Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 29 additions & 4 deletions ref_app/src/mcal/am6254_soc/mcal_gpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,38 @@

#include <core_macros.h>

void mcal::gpt::init(const config_type*) { }

mcal::gpt::value_type mcal::gpt::secure::get_time_elapsed()
auto mcal::gpt::secure::get_time_elapsed() -> mcal::gpt::value_type
{
// Get the system tick from the system counter register.
const value_type consistent_microsecond_tick = (value_type) ARM64_READ_SYSREG(CNTPCT_EL0);
const value_type consistent_microsecond_tick = static_cast<value_type>(ARM64_READ_SYSREG(CNTPCT_EL0));

// Convert the consistent tick to microseconds.
return static_cast<value_type>(static_cast<value_type>(consistent_microsecond_tick + UINT64_C(100)) / UINT64_C(200));
}

auto mcal::gpt::secure::get_time_elapsed_core1() -> mcal::gpt::value_type_core1
{
// Get the system tick from the system counter register.
const value_type_core1 consistent_microsecond_tick = static_cast<value_type_core1>(ARM64_READ_SYSREG(CNTPCT_EL0));

// Convert the consistent tick to microseconds.
return static_cast<value_type_core1>(static_cast<value_type_core1>(consistent_microsecond_tick + UINT64_C(100)) / UINT64_C(200));
}

auto mcal::gpt::secure::get_time_elapsed_core2() -> mcal::gpt::value_type_core2
{
// Get the system tick from the system counter register.
const value_type_core2 consistent_microsecond_tick = static_cast<value_type_core2>(ARM64_READ_SYSREG(CNTPCT_EL0));

// Convert the consistent tick to microseconds.
return static_cast<value_type_core2>(static_cast<value_type_core2>(consistent_microsecond_tick + UINT64_C(100)) / UINT64_C(200));
}

auto mcal::gpt::secure::get_time_elapsed_core3() -> mcal::gpt::value_type_core3
{
// Get the system tick from the system counter register.
const value_type_core3 consistent_microsecond_tick = static_cast<value_type_core3>(ARM64_READ_SYSREG(CNTPCT_EL0));

// Convert the consistent tick to microseconds.
return static_cast<value_type_core3>(static_cast<value_type_core3>(consistent_microsecond_tick + UINT64_C(100)) / UINT64_C(200));
}
8 changes: 7 additions & 1 deletion ref_app/src/mcal/am6254_soc/mcal_gpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,18 @@
{
using config_type = void;
using value_type = std::uint64_t;
using value_type_core1 = value_type;
using value_type_core2 = value_type;
using value_type_core3 = value_type;

auto init(const config_type*) -> void;
inline auto init(const config_type*) -> void { }

struct secure final
{
static auto get_time_elapsed() -> value_type;
static auto get_time_elapsed_core1() -> value_type_core1;
static auto get_time_elapsed_core2() -> value_type_core2;
static auto get_time_elapsed_core3() -> value_type_core3;
};
}
}
Expand Down
7 changes: 0 additions & 7 deletions ref_app/src/mcal/nxp_imxrt1062/mcal_gpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,6 @@

#include <mcal/mcal_gpt_arm_sys_tick.h>

// Forward declaration of the util::timer template class.
namespace util
{
template<typename unsigned_tick_type>
class default_timer_backend;
}

namespace mcal
{
namespace gpt
Expand Down
21 changes: 15 additions & 6 deletions ref_app/src/mcal/xtensa_esp32_s3/mcal_cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ namespace local
{
auto main_worker_core1(mcal::led::led_base& my_led) -> void;

template<typename unsigned_tick_type>
template<typename UnsignedTickType>
struct timer_core1_backend
{
using tick_type = unsigned_tick_type;
using tick_type = UnsignedTickType;

constexpr static auto get_now() -> tick_type
{
Expand Down Expand Up @@ -170,13 +170,22 @@ auto local::main_worker_core1(mcal::led::led_base& my_led) -> void
{
my_led.toggle();

using local_timer_type = util::timer<std::uint32_t, local::timer_core1_backend<std::uint32_t>>;
using local_tick_type = typename local_timer_type::tick_type;

constexpr local_tick_type led_time_1sec { local_timer_type::seconds(local_tick_type { UINT8_C(1) }) };

local_timer_type led_timer { led_time_1sec };

for(;;)
{
using local_timer_type = util::timer<std::uint32_t, local::timer_core1_backend<std::uint32_t>>;
using local_tick_type = typename local_timer_type::tick_type;

local_timer_type::blocking_delay(local_timer_type::seconds(local_tick_type { UINT8_C(1) }));
while(!led_timer.timeout())
{
mcal::cpu::nop();
}

my_led.toggle();

led_timer.start_interval(led_time_1sec);
}
}
24 changes: 10 additions & 14 deletions ref_app/src/mcal/xtensa_esp32_s3/mcal_gpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ namespace
{
volatile mcal::gpt::value_type system_tick[std::size_t { UINT8_C(2) }];

template<const std::size_t CoreIndex>
auto get_consistent_tick() -> mcal::gpt::value_type;

template<const std::size_t CoreIndex>
auto get_consistent_tick() -> mcal::gpt::value_type
{
Expand Down Expand Up @@ -58,24 +61,17 @@ namespace

extern "C" void __system_tick_handler()
{
// Reload the private timer1 for the running core.
// Reload the private timer1 for the running core,
// which could be either core0 or core1.
set_cpu_private_timer1(mcal::gpt::detail::timer1_reload());

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

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

if(is_core0)
{
system_tick[std::size_t { UINT8_C(0) }] += mcal::gpt::detail::timer1_max();
}
else
{
system_tick[std::size_t { UINT8_C(1) }] += mcal::gpt::detail::timer1_max();
}
system_tick[core_id] += mcal::gpt::detail::timer1_max();
}

auto mcal::gpt::init(const config_type*) -> void
Expand Down
33 changes: 21 additions & 12 deletions ref_app/src/util/utility/util_time.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,40 +16,49 @@

namespace util
{
template<typename unsigned_tick_type>
template<typename UnsignedTickType>
struct default_timer_backend;

template<typename unsigned_tick_type,
typename BackendType = default_timer_backend<unsigned_tick_type>>
template<typename UnsignedTickType,
typename BackendType = default_timer_backend<UnsignedTickType>>
class timer;

template<typename unsigned_tick_type>
template<typename UnsignedTickType>
struct default_timer_backend
{
using tick_type = unsigned_tick_type;
using tick_type = UnsignedTickType;

constexpr static auto get_now() -> tick_type
{
return static_cast<tick_type>(mcal::gpt::secure::get_time_elapsed());
}
};

template<typename unsigned_tick_type,
template<typename UnsignedTickType,
typename BackendType>
class timer
{
private:
static constexpr auto timer_mask =
static_cast<unsigned_tick_type>
(
(UINTMAX_C(1) << static_cast<unsigned>(std::numeric_limits<unsigned_tick_type>::digits - 1)) - UINTMAX_C(1)
);

using backend_type = BackendType;

public:
using tick_type = typename backend_type::tick_type;

private:
static constexpr auto timer_mask =
static_cast<tick_type>
(
static_cast<std::uintmax_t>
(
static_cast<std::uintmax_t>
(
UINTMAX_C(1) << static_cast<unsigned>(std::numeric_limits<tick_type>::digits - 1)
)
- UINTMAX_C(1)
)
);

public:
template<typename other_tick_type> static constexpr auto microseconds(other_tick_type value_microseconds) noexcept -> tick_type { return static_cast<tick_type>(value_microseconds); }
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); }
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 ); }
Expand Down
92 changes: 74 additions & 18 deletions ref_app/target/micros/am6254_soc/Code/Appli/Core/a53/main_cores.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,92 @@

namespace local
{
template<typename UnsignedTickType, const unsigned CoreId>
struct timer_core_x_backend
{
using tick_type = UnsignedTickType;

constexpr static auto get_now() -> tick_type
{
return static_cast<tick_type>(mcal::gpt::secure::get_time_elapsed());
}
};

template<typename UnsignedTickType>
struct timer_core_x_backend<UnsignedTickType, 1U>
{
using tick_type = UnsignedTickType;

constexpr static auto get_now() -> tick_type
{
return static_cast<tick_type>(mcal::gpt::secure::get_time_elapsed_core1());
}
};

template<typename UnsignedTickType>
struct timer_core_x_backend<UnsignedTickType, 2U>
{
using tick_type = UnsignedTickType;

constexpr static auto get_now() -> tick_type
{
return static_cast<tick_type>(mcal::gpt::secure::get_time_elapsed_core2());
}
};

template<typename UnsignedTickType>
struct timer_core_x_backend<UnsignedTickType, 3U>
{
using tick_type = UnsignedTickType;

constexpr static auto get_now() -> tick_type
{
return static_cast<tick_type>(mcal::gpt::secure::get_time_elapsed_core3());
}
};

template<const unsigned CoreId>
auto main_worker_core_x(mcal::led::led_base& my_led) -> void;

template<const unsigned CoreId>
auto main_worker_core_x(mcal::led::led_base& my_led) -> void
{
my_led.toggle();

using local_timer_backend_type = timer_core_x_backend<std::uint64_t, CoreId>;
using local_tick_type = typename local_timer_backend_type::tick_type;
using local_timer_type = util::timer<local_tick_type, local_timer_backend_type>;

constexpr local_tick_type led_time_1sec { local_timer_type::seconds(local_tick_type { UINT8_C(1) }) };

local_timer_type led_timer { led_time_1sec };

for(;;)
{
while(!led_timer.timeout())
{
mcal::cpu::nop();
}

my_led.toggle();

led_timer.start_interval(led_time_1sec);
}
}
}

extern "C" auto main_core1(void) -> void;
extern "C" auto main_core2(void) -> void;
extern "C" auto main_core3(void) -> void;
extern "C" auto main_core0_init(void) -> void;

extern "C" auto main_core1(void) -> void { local::main_worker_core_x(mcal::led::led1()); }
extern "C" auto main_core2(void) -> void { local::main_worker_core_x(mcal::led::led2()); }
extern "C" auto main_core3(void) -> void { local::main_worker_core_x(mcal::led::led3()); }
extern "C" auto main_core1(void) -> void { local::main_worker_core_x<1U>(mcal::led::led1()); }
extern "C" auto main_core2(void) -> void { local::main_worker_core_x<2U>(mcal::led::led2()); }
extern "C" auto main_core3(void) -> void { local::main_worker_core_x<3U>(mcal::led::led3()); }

extern "C" auto main_core0_init(void) -> void
{
mcal::wdg::init (nullptr);
mcal::port::init(nullptr);
mcal::osc::init (nullptr);
}

auto local::main_worker_core_x(mcal::led::led_base& my_led) -> void
{
my_led.toggle();

for(;;)
{
using local_timer_type = util::timer<std::uint64_t>;
using local_tick_type = typename local_timer_type::tick_type;

local_timer_type::blocking_delay(local_timer_type::seconds(local_tick_type { UINT8_C(1) }));

my_led.toggle();
}
}
Loading