Files
nRF52840_PTT/src/startup.c
Krzysztof Cieślik f654df0e78 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
2026-05-21 18:40:02 +02:00

169 lines
8.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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 (IRQ0IRQ47) */
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);
}