diff --git a/engine/HAL/ZEPHYR/luos_hal.c b/engine/HAL/ZEPHYR/luos_hal.c new file mode 100644 index 000000000..f55fc8b84 --- /dev/null +++ b/engine/HAL/ZEPHYR/luos_hal.c @@ -0,0 +1,40 @@ +/****************************************************************************** + * @file luosHAL + * @brief Luos Hardware Abstraction Layer for Zephyr (Cortex-M). + ******************************************************************************/ +#include "luos_hal.h" +#include +#include + +void LuosHAL_Init(void) +{ + /* Zephyr owns the system tick and cycle counter; nothing to start. */ +} + +/* Mask all interrupts (including the radio IRQ) so the engine can guard its RX + * ring against Serial_ReceptionWrite running from the radio ISR. Paired + * (false then true) by the engine; not nested. */ +void LuosHAL_SetIrqState(bool Enable) +{ + if (Enable) + { + __enable_irq(); + } + else + { + __disable_irq(); + } +} + +uint32_t LuosHAL_GetSystick(void) +{ + return k_uptime_get_32(); /* milliseconds */ +} + +uint64_t LuosHAL_GetTimestamp(void) +{ + return k_cyc_to_ns_floor64(k_cycle_get_64()); /* nanoseconds */ +} + +void LuosHAL_StartTimestamp(void) {} +void LuosHAL_StopTimestamp(void) {} diff --git a/engine/HAL/ZEPHYR/luos_hal.h b/engine/HAL/ZEPHYR/luos_hal.h new file mode 100644 index 000000000..574e9dfc7 --- /dev/null +++ b/engine/HAL/ZEPHYR/luos_hal.h @@ -0,0 +1,35 @@ +/****************************************************************************** + * @file luosHAL + * @brief Luos Hardware Abstraction Layer for Zephyr (Cortex-M). + * @MCU Family Zephyr / nRF54L15 + ******************************************************************************/ +#ifndef _LUOSHAL_H_ +#define _LUOSHAL_H_ + +#include +#include +#include "luos_hal_config.h" + +#define _CRITICAL + +#define BOOT_MODE_MASK 0x000000FF +#define BOOT_MODE_OFFSET 0 +#define NODE_ID_MASK 0x00FFFF00 +#define NODE_ID_OFFSET 8 + +typedef struct ll_timestamp +{ + uint32_t lower_timestamp; + uint64_t higher_timestamp; + uint32_t start_offset; +} ll_timestamp_t; + +void LuosHAL_Init(void); +void LuosHAL_SetIrqState(bool Enable); +uint32_t LuosHAL_GetSystick(void); + +uint64_t LuosHAL_GetTimestamp(void); +void LuosHAL_StartTimestamp(void); +void LuosHAL_StopTimestamp(void); + +#endif /* _LUOSHAL_H_ */ diff --git a/engine/HAL/ZEPHYR/luos_hal_config.h b/engine/HAL/ZEPHYR/luos_hal_config.h new file mode 100644 index 000000000..11247af17 --- /dev/null +++ b/engine/HAL/ZEPHYR/luos_hal_config.h @@ -0,0 +1,31 @@ +/****************************************************************************** + * @file luos_hal_config + * @brief Luos HAL config for Zephyr. No bus peripheral is reserved here; the + * serial network's radio HAL owns the physical layer. + ******************************************************************************/ +#ifndef _LUOSHAL_CONFIG_H_ +#define _LUOSHAL_CONFIG_H_ + +#ifndef MCUFREQ + #define MCUFREQ 128000000 /* nRF54L15 application core max */ +#endif + +/******************************************************************************* + * DEFINE THREAD MUTEX LOCKING AND UNLOCKING FUNCTIONS + * Engine runs in a single cooperative loop here; no-op like the bare-metal HALs. + ******************************************************************************/ +#ifndef MSGALLOC_MUTEX_LOCK + #define MSGALLOC_MUTEX_LOCK +#endif +#ifndef MSGALLOC_MUTEX_UNLOCK + #define MSGALLOC_MUTEX_UNLOCK +#endif + +#ifndef LUOS_MUTEX_LOCK + #define LUOS_MUTEX_LOCK +#endif +#ifndef LUOS_MUTEX_UNLOCK + #define LUOS_MUTEX_UNLOCK +#endif + +#endif /* _LUOSHAL_CONFIG_H_ */ diff --git a/network/serial_network/HAL/ZEPHYR/serial_network_hal.c b/network/serial_network/HAL/ZEPHYR/serial_network_hal.c new file mode 100644 index 000000000..9323ece66 --- /dev/null +++ b/network/serial_network/HAL/ZEPHYR/serial_network_hal.c @@ -0,0 +1,65 @@ +/****************************************************************************** + * @file serial_network_hal (ZEPHYR / radio) + * @brief The radio is a best-effort byte pipe; the serial network handles all + * framing (0x7E/size/0x81) and reassembles from the engine RX ring. + * One Luos frame (<=139 B) fits one radio packet (<=255 B): SerialHAL_Send + * issues exactly one radio_send(). + * + * TX completion is SYNCHRONOUS: serial_network.c busy-waits on its + * `sending` flag in places that never pump this HAL (notably the + * `while (sending == true);` spin at the top of Serial_RunTopology), and + * every other Luos serial HAL clears `sending` from the TX-complete IRQ. + * So SerialHAL_Send must leave `sending` cleared on return: it transmits, + * waits for the radio TX-done IRQ, then calls Serial_TransmissionEnd() + * from this (caller) context. It must NOT be called from the radio ISR, + * which would re-enter radio_send and corrupt the radio state machine. + ******************************************************************************/ +#include "serial_network_hal.h" +#include "_serial_network.h" +#include "radio.h" + +static volatile bool tx_done; + +/* Radio IRQ context: push received bytes straight into the engine RX ring. */ +static void on_radio_rx(const uint8_t *data, uint8_t len) +{ + Serial_ReceptionWrite((uint8_t *)data, (uint32_t)len); +} + +/* Radio IRQ context: a transmit has completed. */ +static void on_radio_tx_done(void) +{ + tx_done = true; +} + +void SerialHAL_Init(uint8_t *rx_buffer, uint32_t buffer_size) +{ + (void)rx_buffer; /* the engine owns the ring; bytes arrive via Serial_ReceptionWrite */ + (void)buffer_size; + tx_done = false; + radio_init(on_radio_rx, on_radio_tx_done); +} + +void SerialHAL_Loop(void) +{ + /* TX completion is handled synchronously in SerialHAL_Send. */ +} + +void SerialHAL_Send(uint8_t *data, uint16_t size) +{ + tx_done = false; + while (!radio_send(data, (uint8_t)size)) + { + /* a previous transmit is still draining; wait for the radio to free up */ + } + while (!tx_done) + { + /* wait for this transmit to complete (tx_done set in the radio IRQ) */ + } + Serial_TransmissionEnd(); +} + +uint8_t SerialHAL_GetPort(void) +{ + return 0; +} diff --git a/network/serial_network/HAL/ZEPHYR/serial_network_hal.h b/network/serial_network/HAL/ZEPHYR/serial_network_hal.h new file mode 100644 index 000000000..7603d270e --- /dev/null +++ b/network/serial_network/HAL/ZEPHYR/serial_network_hal.h @@ -0,0 +1,15 @@ +/****************************************************************************** + * @file serial_network_hal (ZEPHYR / radio) + * @brief Binds the Luos serial network to the 2.4 GHz radio byte PHY. + ******************************************************************************/ +#ifndef _SERIAL_NETWORK_HAL_H_ +#define _SERIAL_NETWORK_HAL_H_ + +#include + +void SerialHAL_Init(uint8_t *rx_buffer, uint32_t buffer_size); +void SerialHAL_Loop(void); +void SerialHAL_Send(uint8_t *data, uint16_t size); +uint8_t SerialHAL_GetPort(void); + +#endif /* _SERIAL_NETWORK_HAL_H_ */