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 \