Skip to content

Commit 0c5a2f0

Browse files
authored
Merge pull request #670 from ckormanyos/more_multichan_gpt
Use more multi-channel GPT also on am6254
2 parents 430ec1c + c945414 commit 0c5a2f0

7 files changed

Lines changed: 156 additions & 62 deletions

File tree

ref_app/src/mcal/am6254_soc/mcal_gpt.cpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,38 @@
99

1010
#include <core_macros.h>
1111

12-
void mcal::gpt::init(const config_type*) { }
13-
14-
mcal::gpt::value_type mcal::gpt::secure::get_time_elapsed()
12+
auto mcal::gpt::secure::get_time_elapsed() -> mcal::gpt::value_type
1513
{
1614
// Get the system tick from the system counter register.
17-
const value_type consistent_microsecond_tick = (value_type) ARM64_READ_SYSREG(CNTPCT_EL0);
15+
const value_type consistent_microsecond_tick = static_cast<value_type>(ARM64_READ_SYSREG(CNTPCT_EL0));
1816

1917
// Convert the consistent tick to microseconds.
2018
return static_cast<value_type>(static_cast<value_type>(consistent_microsecond_tick + UINT64_C(100)) / UINT64_C(200));
2119
}
20+
21+
auto mcal::gpt::secure::get_time_elapsed_core1() -> mcal::gpt::value_type_core1
22+
{
23+
// Get the system tick from the system counter register.
24+
const value_type_core1 consistent_microsecond_tick = static_cast<value_type_core1>(ARM64_READ_SYSREG(CNTPCT_EL0));
25+
26+
// Convert the consistent tick to microseconds.
27+
return static_cast<value_type_core1>(static_cast<value_type_core1>(consistent_microsecond_tick + UINT64_C(100)) / UINT64_C(200));
28+
}
29+
30+
auto mcal::gpt::secure::get_time_elapsed_core2() -> mcal::gpt::value_type_core2
31+
{
32+
// Get the system tick from the system counter register.
33+
const value_type_core2 consistent_microsecond_tick = static_cast<value_type_core2>(ARM64_READ_SYSREG(CNTPCT_EL0));
34+
35+
// Convert the consistent tick to microseconds.
36+
return static_cast<value_type_core2>(static_cast<value_type_core2>(consistent_microsecond_tick + UINT64_C(100)) / UINT64_C(200));
37+
}
38+
39+
auto mcal::gpt::secure::get_time_elapsed_core3() -> mcal::gpt::value_type_core3
40+
{
41+
// Get the system tick from the system counter register.
42+
const value_type_core3 consistent_microsecond_tick = static_cast<value_type_core3>(ARM64_READ_SYSREG(CNTPCT_EL0));
43+
44+
// Convert the consistent tick to microseconds.
45+
return static_cast<value_type_core3>(static_cast<value_type_core3>(consistent_microsecond_tick + UINT64_C(100)) / UINT64_C(200));
46+
}

ref_app/src/mcal/am6254_soc/mcal_gpt.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,18 @@
1616
{
1717
using config_type = void;
1818
using value_type = std::uint64_t;
19+
using value_type_core1 = value_type;
20+
using value_type_core2 = value_type;
21+
using value_type_core3 = value_type;
1922

20-
auto init(const config_type*) -> void;
23+
inline auto init(const config_type*) -> void { }
2124

2225
struct secure final
2326
{
2427
static auto get_time_elapsed() -> value_type;
28+
static auto get_time_elapsed_core1() -> value_type_core1;
29+
static auto get_time_elapsed_core2() -> value_type_core2;
30+
static auto get_time_elapsed_core3() -> value_type_core3;
2531
};
2632
}
2733
}

ref_app/src/mcal/nxp_imxrt1062/mcal_gpt.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,6 @@
1212

1313
#include <mcal/mcal_gpt_arm_sys_tick.h>
1414

15-
// Forward declaration of the util::timer template class.
16-
namespace util
17-
{
18-
template<typename unsigned_tick_type>
19-
class default_timer_backend;
20-
}
21-
2215
namespace mcal
2316
{
2417
namespace gpt

ref_app/src/mcal/xtensa_esp32_s3/mcal_cpu.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ namespace local
3030
{
3131
auto main_worker_core1(mcal::led::led_base& my_led) -> void;
3232

33-
template<typename unsigned_tick_type>
33+
template<typename UnsignedTickType>
3434
struct timer_core1_backend
3535
{
36-
using tick_type = unsigned_tick_type;
36+
using tick_type = UnsignedTickType;
3737

3838
constexpr static auto get_now() -> tick_type
3939
{
@@ -170,13 +170,22 @@ auto local::main_worker_core1(mcal::led::led_base& my_led) -> void
170170
{
171171
my_led.toggle();
172172

173+
using local_timer_type = util::timer<std::uint32_t, local::timer_core1_backend<std::uint32_t>>;
174+
using local_tick_type = typename local_timer_type::tick_type;
175+
176+
constexpr local_tick_type led_time_1sec { local_timer_type::seconds(local_tick_type { UINT8_C(1) }) };
177+
178+
local_timer_type led_timer { led_time_1sec };
179+
173180
for(;;)
174181
{
175-
using local_timer_type = util::timer<std::uint32_t, local::timer_core1_backend<std::uint32_t>>;
176-
using local_tick_type = typename local_timer_type::tick_type;
177-
178-
local_timer_type::blocking_delay(local_timer_type::seconds(local_tick_type { UINT8_C(1) }));
182+
while(!led_timer.timeout())
183+
{
184+
mcal::cpu::nop();
185+
}
179186

180187
my_led.toggle();
188+
189+
led_timer.start_interval(led_time_1sec);
181190
}
182191
}

ref_app/src/mcal/xtensa_esp32_s3/mcal_gpt.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ namespace
2323
{
2424
volatile mcal::gpt::value_type system_tick[std::size_t { UINT8_C(2) }];
2525

26+
template<const std::size_t CoreIndex>
27+
auto get_consistent_tick() -> mcal::gpt::value_type;
28+
2629
template<const std::size_t CoreIndex>
2730
auto get_consistent_tick() -> mcal::gpt::value_type
2831
{
@@ -58,24 +61,17 @@ namespace
5861

5962
extern "C" void __system_tick_handler()
6063
{
61-
// Reload the private timer1 for the running core.
64+
// Reload the private timer1 for the running core,
65+
// which could be either core0 or core1.
6266
set_cpu_private_timer1(mcal::gpt::detail::timer1_reload());
6367

64-
const bool is_core0 { (get_core_id() == std::uint32_t { UINT8_C(0) }) };
68+
const std::size_t core_id { static_cast<std::size_t>(get_core_id()) };
6569

66-
// Increment the 64-bit system tick (on core0). Here, we
67-
// service the system tick for core0 only. This is because
68-
// there is only one tick but it is used in the timer
69-
// facility by both cores.
70+
// Increment the 64-bit system tick (on the appropriate core).
71+
// Here, we service the system tick for either core0 or core1,
72+
// depending on the running core.
7073

71-
if(is_core0)
72-
{
73-
system_tick[std::size_t { UINT8_C(0) }] += mcal::gpt::detail::timer1_max();
74-
}
75-
else
76-
{
77-
system_tick[std::size_t { UINT8_C(1) }] += mcal::gpt::detail::timer1_max();
78-
}
74+
system_tick[core_id] += mcal::gpt::detail::timer1_max();
7975
}
8076

8177
auto mcal::gpt::init(const config_type*) -> void

ref_app/src/util/utility/util_time.h

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,40 +16,49 @@
1616

1717
namespace util
1818
{
19-
template<typename unsigned_tick_type>
19+
template<typename UnsignedTickType>
2020
struct default_timer_backend;
2121

22-
template<typename unsigned_tick_type,
23-
typename BackendType = default_timer_backend<unsigned_tick_type>>
22+
template<typename UnsignedTickType,
23+
typename BackendType = default_timer_backend<UnsignedTickType>>
2424
class timer;
2525

26-
template<typename unsigned_tick_type>
26+
template<typename UnsignedTickType>
2727
struct default_timer_backend
2828
{
29-
using tick_type = unsigned_tick_type;
29+
using tick_type = UnsignedTickType;
3030

3131
constexpr static auto get_now() -> tick_type
3232
{
3333
return static_cast<tick_type>(mcal::gpt::secure::get_time_elapsed());
3434
}
3535
};
3636

37-
template<typename unsigned_tick_type,
37+
template<typename UnsignedTickType,
3838
typename BackendType>
3939
class timer
4040
{
4141
private:
42-
static constexpr auto timer_mask =
43-
static_cast<unsigned_tick_type>
44-
(
45-
(UINTMAX_C(1) << static_cast<unsigned>(std::numeric_limits<unsigned_tick_type>::digits - 1)) - UINTMAX_C(1)
46-
);
47-
4842
using backend_type = BackendType;
4943

5044
public:
5145
using tick_type = typename backend_type::tick_type;
5246

47+
private:
48+
static constexpr auto timer_mask =
49+
static_cast<tick_type>
50+
(
51+
static_cast<std::uintmax_t>
52+
(
53+
static_cast<std::uintmax_t>
54+
(
55+
UINTMAX_C(1) << static_cast<unsigned>(std::numeric_limits<tick_type>::digits - 1)
56+
)
57+
- UINTMAX_C(1)
58+
)
59+
);
60+
61+
public:
5362
template<typename other_tick_type> static constexpr auto microseconds(other_tick_type value_microseconds) noexcept -> tick_type { return static_cast<tick_type>(value_microseconds); }
5463
template<typename other_tick_type> static constexpr auto milliseconds(other_tick_type value_milliseconds) noexcept -> tick_type { return static_cast<tick_type>(UINT16_C(1000)) * microseconds(value_milliseconds); }
5564
template<typename other_tick_type> static constexpr auto seconds (other_tick_type value_seconds) noexcept -> tick_type { return static_cast<tick_type>(UINT16_C(1000)) * milliseconds(value_seconds ); }

ref_app/target/micros/am6254_soc/Code/Appli/Core/a53/main_cores.cpp

Lines changed: 74 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,36 +17,92 @@
1717

1818
namespace local
1919
{
20+
template<typename UnsignedTickType, const unsigned CoreId>
21+
struct timer_core_x_backend
22+
{
23+
using tick_type = UnsignedTickType;
24+
25+
constexpr static auto get_now() -> tick_type
26+
{
27+
return static_cast<tick_type>(mcal::gpt::secure::get_time_elapsed());
28+
}
29+
};
30+
31+
template<typename UnsignedTickType>
32+
struct timer_core_x_backend<UnsignedTickType, 1U>
33+
{
34+
using tick_type = UnsignedTickType;
35+
36+
constexpr static auto get_now() -> tick_type
37+
{
38+
return static_cast<tick_type>(mcal::gpt::secure::get_time_elapsed_core1());
39+
}
40+
};
41+
42+
template<typename UnsignedTickType>
43+
struct timer_core_x_backend<UnsignedTickType, 2U>
44+
{
45+
using tick_type = UnsignedTickType;
46+
47+
constexpr static auto get_now() -> tick_type
48+
{
49+
return static_cast<tick_type>(mcal::gpt::secure::get_time_elapsed_core2());
50+
}
51+
};
52+
53+
template<typename UnsignedTickType>
54+
struct timer_core_x_backend<UnsignedTickType, 3U>
55+
{
56+
using tick_type = UnsignedTickType;
57+
58+
constexpr static auto get_now() -> tick_type
59+
{
60+
return static_cast<tick_type>(mcal::gpt::secure::get_time_elapsed_core3());
61+
}
62+
};
63+
64+
template<const unsigned CoreId>
2065
auto main_worker_core_x(mcal::led::led_base& my_led) -> void;
66+
67+
template<const unsigned CoreId>
68+
auto main_worker_core_x(mcal::led::led_base& my_led) -> void
69+
{
70+
my_led.toggle();
71+
72+
using local_timer_backend_type = timer_core_x_backend<std::uint64_t, CoreId>;
73+
using local_tick_type = typename local_timer_backend_type::tick_type;
74+
using local_timer_type = util::timer<local_tick_type, local_timer_backend_type>;
75+
76+
constexpr local_tick_type led_time_1sec { local_timer_type::seconds(local_tick_type { UINT8_C(1) }) };
77+
78+
local_timer_type led_timer { led_time_1sec };
79+
80+
for(;;)
81+
{
82+
while(!led_timer.timeout())
83+
{
84+
mcal::cpu::nop();
85+
}
86+
87+
my_led.toggle();
88+
89+
led_timer.start_interval(led_time_1sec);
90+
}
91+
}
2192
}
2293

2394
extern "C" auto main_core1(void) -> void;
2495
extern "C" auto main_core2(void) -> void;
2596
extern "C" auto main_core3(void) -> void;
2697
extern "C" auto main_core0_init(void) -> void;
2798

28-
extern "C" auto main_core1(void) -> void { local::main_worker_core_x(mcal::led::led1()); }
29-
extern "C" auto main_core2(void) -> void { local::main_worker_core_x(mcal::led::led2()); }
30-
extern "C" auto main_core3(void) -> void { local::main_worker_core_x(mcal::led::led3()); }
99+
extern "C" auto main_core1(void) -> void { local::main_worker_core_x<1U>(mcal::led::led1()); }
100+
extern "C" auto main_core2(void) -> void { local::main_worker_core_x<2U>(mcal::led::led2()); }
101+
extern "C" auto main_core3(void) -> void { local::main_worker_core_x<3U>(mcal::led::led3()); }
31102

32103
extern "C" auto main_core0_init(void) -> void
33104
{
34105
mcal::wdg::init (nullptr);
35106
mcal::port::init(nullptr);
36107
mcal::osc::init (nullptr);
37108
}
38-
39-
auto local::main_worker_core_x(mcal::led::led_base& my_led) -> void
40-
{
41-
my_led.toggle();
42-
43-
for(;;)
44-
{
45-
using local_timer_type = util::timer<std::uint64_t>;
46-
using local_tick_type = typename local_timer_type::tick_type;
47-
48-
local_timer_type::blocking_delay(local_timer_type::seconds(local_tick_type { UINT8_C(1) }));
49-
50-
my_led.toggle();
51-
}
52-
}

0 commit comments

Comments
 (0)