Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 137 additions & 3 deletions cores/lpc8xx/startup_lpc8xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,74 @@ void HardFault_Handler(void) {
}
}

/* NMI gets the same emit + reboot path as HardFault. */
void NMI_Handler(void) __attribute__((alias("HardFault_Handler")));
/* NMI gets the same emit + reboot path as HardFault. Weak so a sketch or
* library can install its own NMI handler (e.g. FastLED routes the WWDT
* warning interrupt to NMI via SYSCON->NMISRC for pre-reset wedge
* backtraces and may want a WDT-specific report). */
void NMI_Handler(void) __attribute__((weak, alias("HardFault_Handler")));
#endif /* !ARDUINOCORE_LPC8XX_NO_FAULT_EMIT */

/* ---------------------------------------------------------------------------
* Named weak chip-level IRQ handlers (issue #38).
*
* Standard CMSIS startup pattern: every chip-level vector slot gets a
* peripheral-named handler, weak-aliased to Default_Handler, so a sketch
* or library can install an ISR by simply defining the strong symbol
* (e.g. `void DMA0_IRQHandler(void)`). Previously all 32 slots pointed
* at Default_Handler directly, which made ISR-driven drivers (DMA chunk
* refill, async UART TX) impossible without a RAM vector table — and the
* Cortex-M0+ has no VTOR, so that would need SYSMEMREMAP plus a reserved
* block at the start of SRAM in every linker script.
*
* Slot names follow each chip's IRQn enum in its vendor CMSIS header
* (variants/<chip>/LPC8xx.h). Reserved slots keep Default_Handler.
* Chips without a per-chip block below keep the legacy all-default
* table — no behavior change until their map is added.
* --------------------------------------------------------------------------- */
#if defined(__LPC845__) || defined(__LPC804__)
void SPI0_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void DAC0_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void USART0_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void USART1_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void I2C1_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void I2C0_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void MRT0_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void CMP_CAPT_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void WDT_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void BOD_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void FLASH_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void WKT_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void CTIMER0_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void PIN_INT0_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void PIN_INT1_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void PIN_INT2_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void PIN_INT3_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void PIN_INT4_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
#endif
#if defined(__LPC845__)
void SPI1_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void USART2_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void SCT0_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void ADC0_SEQA_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void ADC0_SEQB_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void ADC0_THCMP_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void ADC0_OVR_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void DMA0_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void I2C2_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void I2C3_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void PIN_INT5_DAC1_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void PIN_INT6_USART3_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void PIN_INT7_USART4_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
#elif defined(__LPC804__)
void ADC_SEQA_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void ADC_SEQB_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void ADC_THCMP_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void ADC_OVR_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void PIN_INT5_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void PIN_INT6_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
void PIN_INT7_IRQHandler(void) __attribute__((weak, alias("Default_Handler")));
#endif

// External symbols from linker script
extern void _vStackTop(void);
extern void __valid_user_code_checksum(void) __attribute__((weak));
Expand Down Expand Up @@ -142,7 +206,76 @@ void (* const g_pfnVectors[])(void) = {
PendSV_Handler, // PendSV handler
SysTick_Handler, // SysTick handler

// Chip Level - LPC8xx IRQs (32 total)
// Chip Level - LPC8xx IRQs (32 total). Slot names per the chip's
// vendor CMSIS IRQn enum; reserved slots stay on Default_Handler.
#if defined(__LPC845__)
SPI0_IRQHandler, // IRQ0 SPI0
SPI1_IRQHandler, // IRQ1 SPI1
DAC0_IRQHandler, // IRQ2 DAC0
USART0_IRQHandler, // IRQ3 USART0
USART1_IRQHandler, // IRQ4 USART1
USART2_IRQHandler, // IRQ5 USART2
Default_Handler, // IRQ6 reserved
I2C1_IRQHandler, // IRQ7 I2C1
I2C0_IRQHandler, // IRQ8 I2C0
SCT0_IRQHandler, // IRQ9 SCT0
MRT0_IRQHandler, // IRQ10 MRT0
CMP_CAPT_IRQHandler, // IRQ11 analog comparator / captouch
WDT_IRQHandler, // IRQ12 WWDT
BOD_IRQHandler, // IRQ13 BOD
FLASH_IRQHandler, // IRQ14 flash
WKT_IRQHandler, // IRQ15 self-wake-up timer
ADC0_SEQA_IRQHandler, // IRQ16 ADC0 seq A
ADC0_SEQB_IRQHandler, // IRQ17 ADC0 seq B
ADC0_THCMP_IRQHandler, // IRQ18 ADC0 threshold compare
ADC0_OVR_IRQHandler, // IRQ19 ADC0 overrun
DMA0_IRQHandler, // IRQ20 DMA0
I2C2_IRQHandler, // IRQ21 I2C2
I2C3_IRQHandler, // IRQ22 I2C3
CTIMER0_IRQHandler, // IRQ23 CTIMER0
PIN_INT0_IRQHandler, // IRQ24 pin int 0
PIN_INT1_IRQHandler, // IRQ25 pin int 1
PIN_INT2_IRQHandler, // IRQ26 pin int 2
PIN_INT3_IRQHandler, // IRQ27 pin int 3
PIN_INT4_IRQHandler, // IRQ28 pin int 4
PIN_INT5_DAC1_IRQHandler, // IRQ29 pin int 5 / DAC1
PIN_INT6_USART3_IRQHandler, // IRQ30 pin int 6 / USART3
PIN_INT7_USART4_IRQHandler, // IRQ31 pin int 7 / USART4
#elif defined(__LPC804__)
SPI0_IRQHandler, // IRQ0 SPI0
Default_Handler, // IRQ1 reserved
DAC0_IRQHandler, // IRQ2 DAC0
USART0_IRQHandler, // IRQ3 USART0
USART1_IRQHandler, // IRQ4 USART1
Default_Handler, // IRQ5 reserved
Default_Handler, // IRQ6 reserved
I2C1_IRQHandler, // IRQ7 I2C1
I2C0_IRQHandler, // IRQ8 I2C0
Default_Handler, // IRQ9 reserved
MRT0_IRQHandler, // IRQ10 MRT0
CMP_CAPT_IRQHandler, // IRQ11 analog comparator / captouch
WDT_IRQHandler, // IRQ12 WWDT
BOD_IRQHandler, // IRQ13 BOD
FLASH_IRQHandler, // IRQ14 flash
WKT_IRQHandler, // IRQ15 self-wake-up timer
ADC_SEQA_IRQHandler, // IRQ16 ADC seq A
ADC_SEQB_IRQHandler, // IRQ17 ADC seq B
ADC_THCMP_IRQHandler, // IRQ18 ADC threshold compare
ADC_OVR_IRQHandler, // IRQ19 ADC overrun
Default_Handler, // IRQ20 reserved
Default_Handler, // IRQ21 reserved
Default_Handler, // IRQ22 reserved
CTIMER0_IRQHandler, // IRQ23 CTIMER0
PIN_INT0_IRQHandler, // IRQ24 pin int 0
PIN_INT1_IRQHandler, // IRQ25 pin int 1
PIN_INT2_IRQHandler, // IRQ26 pin int 2
PIN_INT3_IRQHandler, // IRQ27 pin int 3
PIN_INT4_IRQHandler, // IRQ28 pin int 4
PIN_INT5_IRQHandler, // IRQ29 pin int 5
PIN_INT6_IRQHandler, // IRQ30 pin int 6
PIN_INT7_IRQHandler, // IRQ31 pin int 7
#else
// Chips without a named map yet keep the legacy all-default table.
Default_Handler, // IRQ0
Default_Handler, // IRQ1
Default_Handler, // IRQ2
Expand Down Expand Up @@ -175,6 +308,7 @@ void (* const g_pfnVectors[])(void) = {
Default_Handler, // IRQ29
Default_Handler, // IRQ30
Default_Handler, // IRQ31
#endif
};

void SystemInit(void) {
Expand Down
Loading