diff --git a/ref_app/ref_app.vcxproj b/ref_app/ref_app.vcxproj index 2727cd3e1..fd054ccc9 100644 --- a/ref_app/ref_app.vcxproj +++ b/ref_app/ref_app.vcxproj @@ -261,6 +261,10 @@ true true + + true + true + true true @@ -1512,10 +1516,6 @@ true true - - true - true - true true @@ -1528,6 +1528,10 @@ true true + + true + true + true true diff --git a/ref_app/ref_app.vcxproj.filters b/ref_app/ref_app.vcxproj.filters index 627eca46b..2ecb1f276 100644 --- a/ref_app/ref_app.vcxproj.filters +++ b/ref_app/ref_app.vcxproj.filters @@ -1276,6 +1276,9 @@ src\mcal\am6254_soc + + src\mcal\am6254_soc + @@ -2892,9 +2895,6 @@ src\mcal\am6254_soc - - src\mcal\am6254_soc - src\mcal\am6254_soc @@ -2919,6 +2919,9 @@ src\mcal\am6254_soc + + src\mcal\am6254_soc + diff --git a/ref_app/src/mcal/am6254_soc/mcal_benchmark.h b/ref_app/src/mcal/am6254_soc/mcal_benchmark.h index e8ef4a1cb..b86102407 100644 --- a/ref_app/src/mcal/am6254_soc/mcal_benchmark.h +++ b/ref_app/src/mcal/am6254_soc/mcal_benchmark.h @@ -8,14 +8,16 @@ #ifndef MCAL_BENCHMARK_2014_04_16_H #define MCAL_BENCHMARK_2014_04_16_H - #include #include + #include + + #include namespace mcal { namespace benchmark { - typedef mcal::port::port_pin<2U> benchmark_port_type; + typedef mcal::port::port_pin benchmark_port_type; } } diff --git a/ref_app/src/mcal/am6254_soc/mcal_cpu.h b/ref_app/src/mcal/am6254_soc/mcal_cpu.h index 0c8cb16c9..ec6fe8c38 100644 --- a/ref_app/src/mcal/am6254_soc/mcal_cpu.h +++ b/ref_app/src/mcal/am6254_soc/mcal_cpu.h @@ -10,6 +10,9 @@ #include + extern "C" auto hw_acquire_spin_lock(volatile std::uint32_t*) noexcept -> void; + extern "C" auto hw_release_spin_lock(volatile std::uint32_t*) noexcept -> void; + namespace mcal { namespace cpu @@ -19,6 +22,9 @@ inline auto post_init() -> void { } inline auto nop() noexcept -> void { asm volatile("nop"); } + + inline auto acquire_spin_lock(volatile std::uint32_t* p_sync) noexcept -> void { hw_acquire_spin_lock(p_sync); } + inline auto release_spin_lock(volatile std::uint32_t* p_sync) noexcept -> void { hw_release_spin_lock(p_sync); } } } diff --git a/ref_app/src/mcal/am6254_soc/mcal_cpu_secure.s b/ref_app/src/mcal/am6254_soc/mcal_cpu_secure.s new file mode 100644 index 000000000..6f972ada3 --- /dev/null +++ b/ref_app/src/mcal/am6254_soc/mcal_cpu_secure.s @@ -0,0 +1,48 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2025. +// Distributed under the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Originally from: + +// *************************************************************************************** +// Filename : boot.s +// +// Core : ARM Cortex-A53 +// +// Author : Chalandi Amine +// +// Owner : Chalandi Amine +// +// Date : 16.05.2025 +// +// Description : multicore ARM Cortex-A53 (ARMv8-A) startup code +// +// *************************************************************************************** + +.section .text +.type hw_acquire_spin_lock,@function +.align 3 +.globl hw_acquire_spin_lock + +hw_acquire_spin_lock: + mov w1, #1 + .L_loop: + ldaxr w2, [x0] + cbnz w2, .L_loop + stxr w2, w1, [x0] + cbnz w2, .L_loop + dmb ish + ret + +.section .text +.type hw_release_spin_lock,@function +.align 3 +.globl hw_release_spin_lock + +hw_release_spin_lock: + dmb ish + stlr wzr, [x0] + ret diff --git a/ref_app/src/mcal/am6254_soc/mcal_led.cpp b/ref_app/src/mcal/am6254_soc/mcal_led.cpp index 9977e54a9..012fa1cbc 100644 --- a/ref_app/src/mcal/am6254_soc/mcal_led.cpp +++ b/ref_app/src/mcal/am6254_soc/mcal_led.cpp @@ -6,13 +6,50 @@ // #include -#include +#include +#include +#include auto mcal::led::led0() -> mcal::led::led_base& { - using led0_led_type = led_am6254_soc; + using local_led_port_type = mcal::port::port_pin; - static led0_led_type l0; + using local_led_type = led_port; - return l0; + static local_led_type led_instance; + + return led_instance; +} + +auto mcal::led::led1() -> mcal::led::led_base& +{ + using local_led_port_type = mcal::port::port_pin; + + using local_led_type = led_port; + + static local_led_type led_instance; + + return led_instance; +} + +auto mcal::led::led2() -> mcal::led::led_base& +{ + using local_led_port_type = mcal::port::port_pin; + + using local_led_type = led_port; + + static local_led_type led_instance; + + return led_instance; +} + +auto mcal::led::led3() -> mcal::led::led_base& +{ + using local_led_port_type = mcal::port::port_pin; + + using local_led_type = led_port; + + static local_led_type led_instance; + + return led_instance; } diff --git a/ref_app/src/mcal/am6254_soc/mcal_led.h b/ref_app/src/mcal/am6254_soc/mcal_led.h index 6d939fec3..34d0eff68 100644 --- a/ref_app/src/mcal/am6254_soc/mcal_led.h +++ b/ref_app/src/mcal/am6254_soc/mcal_led.h @@ -10,11 +10,21 @@ #include + #include + namespace mcal { namespace led { + constexpr unsigned LED_ID_1 { UINT8_C(6) }; + constexpr unsigned LED_ID_2 { UINT8_C(5) }; + constexpr unsigned LED_ID_3 { UINT8_C(4) }; + constexpr unsigned LED_ID_4 { UINT8_C(3) }; + auto led0() -> led_base&; + auto led1() -> led_base&; + auto led2() -> led_base&; + auto led3() -> led_base&; } } diff --git a/ref_app/src/mcal/am6254_soc/mcal_led_am6254_soc.h b/ref_app/src/mcal/am6254_soc/mcal_led_am6254_soc.h deleted file mode 100644 index 2d5d28111..000000000 --- a/ref_app/src/mcal/am6254_soc/mcal_led_am6254_soc.h +++ /dev/null @@ -1,132 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2025. -// Distributed under the Boost Software License, -// Version 1.0. (See accompanying file LICENSE_1_0.txt -// or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -// Parts of this file originate from the file Mcal/Gpio/led.h in: -// https://github.com/Chalandi/Baremetal_TI_AM6254_multicore_nosdk - -#ifndef MCAL_LED_AM6254_SOC_2025_08_04_H - #define MCAL_LED_AM6254_SOC_2025_08_04_H - - #include - - #include - - #include - #include - - namespace mcal - { - namespace led - { - constexpr unsigned LED_1 { UINT8_C(6) }; - constexpr unsigned LED_2 { UINT8_C(5) }; - constexpr unsigned LED_3 { UINT8_C(4) }; - constexpr unsigned LED_4 { UINT8_C(3) }; - - template - class led_am6254_soc_base : public mcal::led::led_boolean_state_base - { - public: - ~led_am6254_soc_base() override = default; - - protected: - led_am6254_soc_base() noexcept = default; - - auto toggle() -> void override - { - using base_class_type = led_boolean_state_base; - - base_class_type::toggle(); - } - - static constexpr std::uint32_t PADCFG_CTRL0_CFG0_PADCONFIG3 { UINT32_C(0x000F400C) }; - static constexpr std::uint32_t PADCFG_CTRL0_CFG0_PADCONFIG4 { UINT32_C(0x000F4010) }; - static constexpr std::uint32_t PADCFG_CTRL0_CFG0_PADCONFIG5 { UINT32_C(0x000F4014) }; - static constexpr std::uint32_t PADCFG_CTRL0_CFG0_PADCONFIG6 { UINT32_C(0x000F4018) }; - - static constexpr std::uint32_t GPIO_DIR01 { UINT32_C(0x00600010) }; - static constexpr std::uint32_t GPIO_OUT_DATA01 { UINT32_C(0x00600014) }; - static constexpr std::uint32_t GPIO_SET_DATA01 { UINT32_C(0x00600018) }; - static constexpr std::uint32_t GPIO_CLR_DATA01 { UINT32_C(0x0060001C) }; - - private: - static const volatile bool is_init; - - using local_void_class = VoidClass; - - static_assert(std::is_same::value, "Error: The template parameter must be of type void."); - - #if defined(__GNUC__) - __attribute__((noinline,used)) - #endif - static auto LED_INIT() -> bool - { - *reinterpret_cast(PADCFG_CTRL0_CFG0_PADCONFIG3) &= static_cast(~(UINT32_C(1) << 21U)); - *reinterpret_cast(PADCFG_CTRL0_CFG0_PADCONFIG4) &= static_cast(~(UINT32_C(1) << 21U)); - *reinterpret_cast(PADCFG_CTRL0_CFG0_PADCONFIG5) &= static_cast(~(UINT32_C(1) << 21U)); - *reinterpret_cast(PADCFG_CTRL0_CFG0_PADCONFIG6) &= static_cast(~(UINT32_C(1) << 21U)); - *reinterpret_cast(GPIO_CLR_DATA01) |= UINT32_C(0x78); - *reinterpret_cast(GPIO_OUT_DATA01) &= static_cast(~(UINT32_C(0x78))); - *reinterpret_cast(GPIO_DIR01) &= static_cast(~(UINT32_C(0x78))); - - return true; - } - }; - - template - const volatile bool led_am6254_soc_base::is_init { LED_INIT() }; - - template - class led_am6254_soc final : public mcal::led::led_am6254_soc_base - { - private: - using base_class_type = led_am6254_soc_base; - - static constexpr auto local_led_id() noexcept -> unsigned { return LED_ID; } - - public: - led_am6254_soc() noexcept = default; - - ~led_am6254_soc() override = default; - - auto toggle() -> void override - { - ((base_class_type::state_is_on()) ? LED_OFF() : LED_ON()); - - base_class_type::toggle(); - } - - static auto main_core_worker() -> void - { - using local_timer_type = util::timer; - using local_tick_type = typename local_timer_type::tick_type; - using local_led_type = led_am6254_soc; - - local_led_type my_led { }; - - local_timer_type led_timer(local_timer_type::seconds(local_tick_type { UINT8_C(1) })); - - my_led.toggle(); - - for(;;) - { - while(!led_timer.timeout()) { asm volatile("nop"); } - - my_led.toggle(); - - led_timer.start_interval(local_timer_type::seconds(local_tick_type { UINT8_C(1) })); - } - } - - private: - auto LED_ON () noexcept -> void { *reinterpret_cast(base_class_type::GPIO_SET_DATA01) |= static_cast(UINT32_C(1) << local_led_id()); *reinterpret_cast(base_class_type::GPIO_OUT_DATA01) |= static_cast(UINT32_C(1) << local_led_id()); } - auto LED_OFF() noexcept -> void { *reinterpret_cast(base_class_type::GPIO_CLR_DATA01) |= static_cast(UINT32_C(1) << local_led_id()); *reinterpret_cast(base_class_type::GPIO_OUT_DATA01) &= static_cast(~static_cast(UINT32_C(1) << local_led_id())); } - }; - } // namespace led - } // namespace mcal - -#endif // MCAL_LED_AM6254_SOC_2025_08_04_H diff --git a/ref_app/src/mcal/am6254_soc/mcal_port.h b/ref_app/src/mcal/am6254_soc/mcal_port.h index 46d8321a7..51c770e4d 100644 --- a/ref_app/src/mcal/am6254_soc/mcal_port.h +++ b/ref_app/src/mcal/am6254_soc/mcal_port.h @@ -8,6 +8,12 @@ #ifndef MCAL_PORT_2014_01_10_H_ #define MCAL_PORT_2014_01_10_H_ + #include + #include + + #include + #include + namespace mcal { namespace port @@ -16,35 +22,98 @@ inline void init(const config_type*) { } - template + template class port_pin { + private: + static constexpr std::uintptr_t instance_base { InstanceBase }; + static constexpr unsigned pin { PIN_ID }; + public: - static void set_direction_output() + static auto set_direction_output() -> void { + mcal::cpu::acquire_spin_lock(&sync_object); + GPIO_CONFIG_AS_OUTPUT(); + mcal::cpu::release_spin_lock(&sync_object); } - static void set_direction_input() + static auto set_direction_input() -> void { + // Not yet implemented. } - static void set_pin_high() + static auto set_pin_high() -> void { + mcal::cpu::acquire_spin_lock(&sync_object); + output_is_high = true; + OUTPUT_HIGH(); + mcal::cpu::release_spin_lock(&sync_object); } - static void set_pin_low() + static auto set_pin_low() -> void { + mcal::cpu::acquire_spin_lock(&sync_object); + output_is_high = false; + OUTPUT_LOW(); + mcal::cpu::release_spin_lock(&sync_object); } - static bool read_input_value() + static auto read_input_value() -> bool { + // Not yet implemented. return false; } - static void toggle_pin() + static auto toggle_pin() -> void + { + mcal::cpu::acquire_spin_lock(&sync_object); + (output_is_high ? OUTPUT_LOW() : OUTPUT_HIGH()); + output_is_high = (!output_is_high); + mcal::cpu::release_spin_lock(&sync_object); + } + + private: + static volatile std::uint32_t sync_object; + static bool output_is_high; + + static auto GPIO_CONFIG_AS_OUTPUT() -> void { + if(instance_base == mcal::reg::gpio0) + { + *(volatile uint32_t*)(uintptr_t)(0x000F4000 + (pin * 4)) /* PADCFG_CTRL0_CFG0_PADCONFIG */ = 0x08014007ul; + } + else if(instance_base == mcal::reg::mcu_gpio0) + { + *(volatile uint32_t*)(uintptr_t)(0x4084000 + (pin * 4)) /* MCU_PADCFG_CTRL0_CFG0_PADCONFIG */ = 0x08014007ul; + } + else + { + /* GPIO1 has no pad configuration */ + } + + *(volatile uint32_t*)(instance_base + (uintptr_t)((pin/32) * 0x28) + (uintptr_t)0x0C /* GPIO_CLR_DATA */) |= (1ul << (pin % 32)); + *(volatile uint32_t*)(instance_base + (uintptr_t)((pin/32) * 0x28) + (uintptr_t)0x04 /* GPIO_OUT_DATA */) &= ~((uint32_t)(1ul << (pin % 32))); + *(volatile uint32_t*)(instance_base + (uintptr_t)((pin/32) * 0x28) + (uintptr_t)0x00 /* GPIO_DIR */) &= ~((uint32_t)(1ul << (pin % 32))); } + + static auto OUTPUT_HIGH() -> void { *(volatile uint32_t*)(instance_base + (uintptr_t)((pin/32) * 0x28) + (uintptr_t)0x08 /* GPIO_SET_DATA */) = (1ul << (pin % 32)); } + static auto OUTPUT_LOW () -> void { *(volatile uint32_t*)(instance_base + (uintptr_t)((pin/32) * 0x28) + (uintptr_t)0x0C /* GPIO_CLR_DATA */) = (1ul << (pin % 32)); } + + #if 0 + // Notes on gpio registers. + instance_base + (uintptr_t)((pin/32) * 0x28) + (uintptr_t)0x00 /* GPIO_DIR */ + instance_base + (uintptr_t)((pin/32) * 0x28) + (uintptr_t)0x04 /* GPIO_OUT_DATA */ + instance_base + (uintptr_t)((pin/32) * 0x28) + (uintptr_t)0x08 /* GPIO_SET_DATA */ + instance_base + (uintptr_t)((pin/32) * 0x28) + (uintptr_t)0x0C /* GPIO_CLR_DATA */ + instance_base + (uintptr_t)((pin/32) * 0x28) + (uintptr_t)0x10 /* GPIO_IN_DATA */ + #endif }; + + template + volatile std::uint32_t port_pin::sync_object { }; + + template + bool port_pin::output_is_high { }; } } diff --git a/ref_app/src/mcal/am6254_soc/mcal_reg.h b/ref_app/src/mcal/am6254_soc/mcal_reg.h new file mode 100644 index 000000000..29a9d56ec --- /dev/null +++ b/ref_app/src/mcal/am6254_soc/mcal_reg.h @@ -0,0 +1,27 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2024. +// Distributed under the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef MCAL_REG_2010_04_10_H + #define MCAL_REG_2010_04_10_H + + #include + + namespace mcal + { + namespace reg + { + // Port (gpio) registers. + constexpr std::uintptr_t gpio0 { UINT32_C(0x00600010) }; + constexpr std::uintptr_t gpio1 { UINT32_C(0x00601010) }; + constexpr std::uintptr_t mcu_gpio0 { UINT32_C(0x04201010) }; + } + } + + #include + #include + +#endif // MCAL_REG_2010_04_10_H diff --git a/ref_app/target/micros/am6254_soc/Code/Appli/Core/a53/main_cores.cpp b/ref_app/target/micros/am6254_soc/Code/Appli/Core/a53/main_cores.cpp index 8a867739e..d0bacfd76 100644 --- a/ref_app/target/micros/am6254_soc/Code/Appli/Core/a53/main_cores.cpp +++ b/ref_app/target/micros/am6254_soc/Code/Appli/Core/a53/main_cores.cpp @@ -5,17 +5,38 @@ // or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include -#include +#include +#include #include #include -extern "C" void main_core1(void); -extern "C" void main_core2(void); -extern "C" void main_core3(void); +static auto main_core_worker(mcal::led::led_base& my_led) -> void; -extern "C" void main_core1(void) { using namespace mcal::led; led_am6254_soc::main_core_worker(); } -extern "C" void main_core2(void) { using namespace mcal::led; led_am6254_soc::main_core_worker(); } -extern "C" void main_core3(void) { using namespace mcal::led; led_am6254_soc::main_core_worker(); } +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_core1(void) -> void { main_core_worker(mcal::led::led1()); } +extern "C" auto main_core2(void) -> void { main_core_worker(mcal::led::led2()); } +extern "C" auto main_core3(void) -> void { main_core_worker(mcal::led::led3()); } + +static auto main_core_worker(mcal::led::led_base& my_led) -> void +{ + using local_timer_type = util::timer; + using local_tick_type = typename local_timer_type::tick_type; + + local_timer_type led_timer(local_timer_type::seconds(local_tick_type { UINT8_C(1) })); + + my_led.toggle(); + + for(;;) + { + while(!led_timer.timeout()) { asm volatile("nop"); } + + my_led.toggle(); + + led_timer.start_interval(local_timer_type::seconds(local_tick_type { UINT8_C(1) })); + } +} diff --git a/ref_app/target/micros/am6254_soc/make/am6254_soc_files.gmk b/ref_app/target/micros/am6254_soc/make/am6254_soc_files.gmk index 3a7ccf969..f525d6535 100644 --- a/ref_app/target/micros/am6254_soc/make/am6254_soc_files.gmk +++ b/ref_app/target/micros/am6254_soc/make/am6254_soc_files.gmk @@ -33,6 +33,7 @@ FILES_CPP := $(PATH_APP)/app/benchmark/app_benchmark $(PATH_APP)/app/benchmark/app_benchmark_wide_decimal \ $(PATH_APP)/app/benchmark/app_benchmark_wide_integer \ $(PATH_APP)/app/led/app_led \ + $(PATH_APP)/mcal/$(TGT)/mcal_cpu_secure \ $(PATH_APP)/mcal/$(TGT)/mcal_gpt \ $(PATH_APP)/mcal/$(TGT)/mcal_led \ $(PATH_APP)/mcal/mcal \