Initial bare-metal foundation for nRF52840 PTT-FHSS
- Fully open toolchain: arm-none-eabi-gcc inside Podman/Docker container - Platform-agnostic build via justfile (auto-detects podman vs docker) - CMake + Ninja build system with arm-none-eabi toolchain file - nRF52840 linker script and startup with full 64-entry vector table - Register access via typed bitfield unions (include/regs.h) - FHSS channel sequencer: AES-128-ECB PRNG over 40 channels (2402-2480 MHz) - Low-power sleep via SYSTEM_ON WFI + GPIOTE wakeup on button press - Vendor deps as shallow git submodules: nrfx, CMSIS_5, tiny-AES-c
This commit is contained in:
168
src/startup.c
Normal file
168
src/startup.c
Normal file
@@ -0,0 +1,168 @@
|
||||
#include <stdint.h>
|
||||
|
||||
/* linker script symbols */
|
||||
extern uint32_t _sidata; /* load address of .data in Flash */
|
||||
extern uint32_t _sdata; /* start of .data in RAM */
|
||||
extern uint32_t _edata; /* end of .data in RAM */
|
||||
extern uint32_t _sbss;
|
||||
extern uint32_t _ebss;
|
||||
extern uint32_t _estack; /* address equals initial SP value */
|
||||
|
||||
extern int main(void);
|
||||
|
||||
void Reset_Handler(void);
|
||||
|
||||
static void __attribute__((used)) Default_Handler(void)
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
|
||||
/* ARM Cortex-M4 core exceptions */
|
||||
void NMI_Handler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void HardFault_Handler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void MemManage_Handler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void BusFault_Handler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void UsageFault_Handler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void SVC_Handler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void DebugMon_Handler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void PendSV_Handler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void SysTick_Handler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
|
||||
/* nRF52840 peripheral IRQs (IRQ0–IRQ47) */
|
||||
void POWER_CLOCK_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void RADIO_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void UARTE0_UART0_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void NFCT_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void GPIOTE_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void SAADC_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void TIMER0_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void TIMER1_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void TIMER2_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void RTC0_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void TEMP_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void RNG_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void ECB_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void CCM_AAR_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void WDT_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void RTC1_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void QDEC_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void COMP_LPCOMP_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void SWI0_EGU0_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void SWI1_EGU1_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void SWI2_EGU2_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void SWI3_EGU3_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void SWI4_EGU4_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void SWI5_EGU5_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void TIMER3_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void TIMER4_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void PWM0_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void PDM_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void MWU_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void PWM1_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void PWM2_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void SPIM2_SPIS2_SPI2_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void RTC2_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void I2S_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void FPU_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void USBD_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void UARTE1_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void QSPI_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void CRYPTOCELL_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void PWM3_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
void SPIM3_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
|
||||
|
||||
/* ── vector table: 64 entries (16 core + 48 IRQs) ───────────────────────── */
|
||||
|
||||
typedef void (*vector_fn)(void);
|
||||
|
||||
__attribute__((section(".isr_vector"), used))
|
||||
const vector_fn vectors[64] = {
|
||||
/* 0 */ (vector_fn)&_estack,
|
||||
/* 1 */ Reset_Handler,
|
||||
/* 2 */ NMI_Handler,
|
||||
/* 3 */ HardFault_Handler,
|
||||
/* 4 */ MemManage_Handler,
|
||||
/* 5 */ BusFault_Handler,
|
||||
/* 6 */ UsageFault_Handler,
|
||||
/* 7 */ 0,
|
||||
/* 8 */ 0,
|
||||
/* 9 */ 0,
|
||||
/* 10 */ 0,
|
||||
/* 11 */ SVC_Handler,
|
||||
/* 12 */ DebugMon_Handler,
|
||||
/* 13 */ 0,
|
||||
/* 14 */ PendSV_Handler,
|
||||
/* 15 */ SysTick_Handler,
|
||||
|
||||
/* IRQ0 */ POWER_CLOCK_IRQHandler,
|
||||
/* IRQ1 */ RADIO_IRQHandler,
|
||||
/* IRQ2 */ UARTE0_UART0_IRQHandler,
|
||||
/* IRQ3 */ SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler,
|
||||
/* IRQ4 */ SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler,
|
||||
/* IRQ5 */ NFCT_IRQHandler,
|
||||
/* IRQ6 */ GPIOTE_IRQHandler,
|
||||
/* IRQ7 */ SAADC_IRQHandler,
|
||||
/* IRQ8 */ TIMER0_IRQHandler,
|
||||
/* IRQ9 */ TIMER1_IRQHandler,
|
||||
/* IRQ10 */ TIMER2_IRQHandler,
|
||||
/* IRQ11 */ RTC0_IRQHandler,
|
||||
/* IRQ12 */ TEMP_IRQHandler,
|
||||
/* IRQ13 */ RNG_IRQHandler,
|
||||
/* IRQ14 */ ECB_IRQHandler,
|
||||
/* IRQ15 */ CCM_AAR_IRQHandler,
|
||||
/* IRQ16 */ WDT_IRQHandler,
|
||||
/* IRQ17 */ RTC1_IRQHandler,
|
||||
/* IRQ18 */ QDEC_IRQHandler,
|
||||
/* IRQ19 */ COMP_LPCOMP_IRQHandler,
|
||||
/* IRQ20 */ SWI0_EGU0_IRQHandler,
|
||||
/* IRQ21 */ SWI1_EGU1_IRQHandler,
|
||||
/* IRQ22 */ SWI2_EGU2_IRQHandler,
|
||||
/* IRQ23 */ SWI3_EGU3_IRQHandler,
|
||||
/* IRQ24 */ SWI4_EGU4_IRQHandler,
|
||||
/* IRQ25 */ SWI5_EGU5_IRQHandler,
|
||||
/* IRQ26 */ TIMER3_IRQHandler,
|
||||
/* IRQ27 */ TIMER4_IRQHandler,
|
||||
/* IRQ28 */ PWM0_IRQHandler,
|
||||
/* IRQ29 */ PDM_IRQHandler,
|
||||
/* IRQ30 */ 0, /* reserved */
|
||||
/* IRQ31 */ 0, /* reserved */
|
||||
/* IRQ32 */ MWU_IRQHandler,
|
||||
/* IRQ33 */ PWM1_IRQHandler,
|
||||
/* IRQ34 */ PWM2_IRQHandler,
|
||||
/* IRQ35 */ SPIM2_SPIS2_SPI2_IRQHandler,
|
||||
/* IRQ36 */ RTC2_IRQHandler,
|
||||
/* IRQ37 */ I2S_IRQHandler,
|
||||
/* IRQ38 */ FPU_IRQHandler,
|
||||
/* IRQ39 */ USBD_IRQHandler,
|
||||
/* IRQ40 */ UARTE1_IRQHandler,
|
||||
/* IRQ41 */ QSPI_IRQHandler,
|
||||
/* IRQ42 */ CRYPTOCELL_IRQHandler,
|
||||
/* IRQ43 */ 0, /* reserved */
|
||||
/* IRQ44 */ 0, /* reserved */
|
||||
/* IRQ45 */ PWM3_IRQHandler,
|
||||
/* IRQ46 */ 0, /* reserved */
|
||||
/* IRQ47 */ SPIM3_IRQHandler,
|
||||
};
|
||||
|
||||
/* ── Reset_Handler ───────────────────────────────────────────────────────── */
|
||||
|
||||
void Reset_Handler(void)
|
||||
{
|
||||
/* copy .data initializers from Flash to RAM */
|
||||
uint32_t *src = &_sidata;
|
||||
uint32_t *dst = &_sdata;
|
||||
while (dst < &_edata) {
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
/* zero .bss */
|
||||
dst = &_sbss;
|
||||
while (dst < &_ebss) {
|
||||
*dst++ = 0u;
|
||||
}
|
||||
|
||||
main();
|
||||
while (1);
|
||||
}
|
||||
Reference in New Issue
Block a user