diff --git a/interfaces/interrupt_interface.h b/interfaces/interrupt_interface.h new file mode 100644 index 0000000..f887f1b --- /dev/null +++ b/interfaces/interrupt_interface.h @@ -0,0 +1,16 @@ +#ifndef __INTERFACES_INTERRUPT_INTERFACE_H__ +#define __INTERFACES_INTERRUPT_INTERFACE_H__ + +namespace pinetime::interfaces { + +class InterruptInterface +{ + public: + virtual void handle() = 0; + virtual void enable() = 0; + virtual void disable() = 0; +}; + +} + +#endif diff --git a/src/platform/nrf52/InterruptGuardian.cc b/src/platform/nrf52/InterruptGuardian.cc new file mode 100644 index 0000000..fd9762d --- /dev/null +++ b/src/platform/nrf52/InterruptGuardian.cc @@ -0,0 +1,13 @@ +#include "platform/nrf52/InterruptHandler.h" +#include "platform/nrf52/InterruptGuardian.h" + +using namespace pinetime::platform::nrf52; + +InterruptGuardian::InterruptGuardian() +{ +} + +void InterruptGuardian::register_handler(Nrf52IrqN irq_nr, InterruptHandler &handler) +{ + this->nrf52_vector[irq_nr] = &handler; +} diff --git a/src/platform/nrf52/InterruptGuardian.h b/src/platform/nrf52/InterruptGuardian.h new file mode 100644 index 0000000..e884562 --- /dev/null +++ b/src/platform/nrf52/InterruptGuardian.h @@ -0,0 +1,82 @@ +#ifndef __PINETIME_PLATFORM_NRF52_INTERRUPTGUARDIAN_H__ +#define __PINETIME_PLATFORM_NRF52_INTERRUPTGUARDIAN_H__ + +#include + +extern "C" { + #include "nrf52.h" +} + +namespace pinetime::platform::nrf52 { + +class InterruptGuardian +{ +public: + InterruptGuardian(); + + enum Nrf52IrqN { + // CM4 interrupts + RESET_IRQ = 0, //!< -15 Reset Vector, invoked on Power up and warm reset + NON_MASKABLE_INT_IRQ, //!< -14 Non maskable Interrupt, cannot be stopped or preempted + HARD_FAULT_IRQ, //!< -13 Hard Fault, all classes of Fault + MEMORY_MANAGEMENT_IRQ, //!< -12 Memory Management, MPU mismatch, including Access Violation and No Match + BUS_FAULT_IRQ, //!< -11 Bus Fault, Pre-Fetch-, Memory Access Fault, other address/memory related Fault + USAGE_FAULT_IRQ, //!< -10 Usage Fault, i.e. Undef Instruction, Illegal State Transition + SV_CALL_IRQ, //!< -5 System Service Call via SVC instruction + DEBUG_MONITOR_IRQ, //!< -4 Debug Monitor + PEND_SV_IRQ, //!< -2 Pendable request for system service + SYS_TICK_IRQ, //!< -1 System Tick Timer + + // nrf52 interrupts + POWER_CLOCK_IRQn, //!< 0 POWER_CLOCK + RADIO_IRQn, //!< 1 RADIO + UARTE0_UART0_IRQn, //!< 2 UARTE0_UART0 + SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQn, //!< 3 SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 + SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQn, //!< 4 SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1 + NFCT_IRQn, //!< 5 NFCT + GPIOTE_IRQn, //!< 6 GPIOTE + SAADC_IRQn, //!< 7 SAADC + TIMER0_IRQn, //!< 8 TIMER0 + TIMER1_IRQn, //!< 9 TIMER1 + TIMER2_IRQn, //!< 10 TIMER2 + RTC0_IRQn, //!< 11 RTC0 + TEMP_IRQn, //!< 12 TEMP + RNG_IRQn, //!< 13 RNG + ECB_IRQn, //!< 14 ECB + CCM_AAR_IRQn, //!< 15 CCM_AAR + WDT_IRQn, //!< 16 WDT + RTC1_IRQn, //!< 17 RTC1 + QDEC_IRQn, //!< 18 QDEC + COMP_LPCOMP_IRQn, //!< 19 COMP_LPCOMP + SWI0_EGU0_IRQn, //!< 20 SWI0_EGU0 + SWI1_EGU1_IRQn, //!< 21 SWI1_EGU1 + SWI2_EGU2_IRQn, //!< 22 SWI2_EGU2 + SWI3_EGU3_IRQn, //!< 23 SWI3_EGU3 + SWI4_EGU4_IRQn, //!< 24 SWI4_EGU4 + SWI5_EGU5_IRQn, //!< 25 SWI5_EGU5 + TIMER3_IRQn, //!< 26 TIMER3 + TIMER4_IRQn, //!< 27 TIMER4 + PWM0_IRQn, //!< 28 PWM0 + PDM_IRQn, //!< 29 PDM + MWU_IRQn, //!< 32 MWU + PWM1_IRQn, //!< 33 PWM1 + PWM2_IRQn, //!< 34 PWM2 + SPIM2_SPIS2_SPI2_IRQn, //!< 35 SPIM2_SPIS2_SPI2 + RTC2_IRQn, //!< 36 RTC2 + I2S_IRQn, //!< 37 I2S + FPU_IRQn //!< 38 FPU + }; + enum { + NRF52_HANDLER_COUNT = FPU_IRQn + 1, + }; + + void register_handler(Nrf52IrqN irq_nr, InterruptHandler &); + + static InterruptGuardian instance; + + std::array nrf52_vector; +}; + +} + +#endif diff --git a/src/platform/nrf52/InterruptHandler.cc b/src/platform/nrf52/InterruptHandler.cc new file mode 100644 index 0000000..b700663 --- /dev/null +++ b/src/platform/nrf52/InterruptHandler.cc @@ -0,0 +1,27 @@ +#include + +#include "platform/nrf52/InterruptHandler.h" +#include "platform/nrf52/InterruptGuardian.h" + +using namespace pinetime::platform::nrf52; + +InterruptHandler::InterruptHandler(uint32_t irq_nr) +{ + InterruptGuardian::instance.register_handler(static_cast(irq_nr), *this); +} + +void InterruptHandler::handle() +{ + asm volatile("nop"); + assert(false); +} + +void InterruptHandler::enable() +{ + assert(false); +} + +void InterruptHandler::disable() +{ + assert(false); +} diff --git a/src/platform/nrf52/InterruptHandler.h b/src/platform/nrf52/InterruptHandler.h new file mode 100644 index 0000000..1199bde --- /dev/null +++ b/src/platform/nrf52/InterruptHandler.h @@ -0,0 +1,22 @@ +#ifndef __PINETIME_PLATFORM_NRF52_INTERRUPTHANDLER_H__ +#define __PINETIME_PLATFORM_NRF52_INTERRUPTHANDLER_H__ + +#include + +#include "interrupt_interface.h" + +namespace pinetime::platform::nrf52 { + +class InterruptHandler : public pinetime::interfaces::InterruptInterface +{ + public: + InterruptHandler(uint32_t); + + void handle() override; + void enable() override; + void disable() override; +}; + +} + +#endif diff --git a/src/platform/nrf52/low_level_interrupt.cc b/src/platform/nrf52/low_level_interrupt.cc new file mode 100644 index 0000000..9ee8323 --- /dev/null +++ b/src/platform/nrf52/low_level_interrupt.cc @@ -0,0 +1,60 @@ +#include "platform/nrf52/InterruptHandler.h" +#include "platform/nrf52/InterruptGuardian.h" + +extern "C" { + void NMI_Handler(void); + void HardFault_Handler(void); + void MemoryManagement_Handler(void); + void BusFault_Handler(void); + void UsageFault_Handler(void); + void SVC_Handler(void); + void DebugMon_Handler(void); + void PendSV_Handler(void); + void SysTick_Handler(void); + + void POWER_CLOCK_IRQHandler(void); + void RADIO_IRQHandler(void); + void UARTE0_UART0_IRQHandler(void); + void SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler(void); + void SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler(void); + void NFCT_IRQHandler(void); + void GPIOTE_IRQHandler(void); + void SAADC_IRQHandler(void); + void TIMER0_IRQHandler(void); + void TIMER1_IRQHandler(void); + void TIMER2_IRQHandler(void); + void RTC0_IRQHandler(void); + void TEMP_IRQHandler(void); + void RNG_IRQHandler(void); + void ECB_IRQHandler(void); + void CCM_AAR_IRQHandler(void); + void WDT_IRQHandler(void); + void RTC1_IRQHandler(void); + void QDEC_IRQHandler(void); + void COMP_LPCOMP_IRQHandler(void); + void SWI0_EGU0_IRQHandler(void); + void SWI1_EGU1_IRQHandler(void); + void SWI2_EGU2_IRQHandler(void); + void SWI3_EGU3_IRQHandler(void); + void SWI4_EGU4_IRQHandler(void); + void SWI5_EGU5_IRQHandler(void); + void TIMER3_IRQHandler(void); + void TIMER4_IRQHandler(void); + void PWM0_IRQHandler(void); + void PDM_IRQHandler(void); + void MWU_IRQHandler(void); + void PWM1_IRQHandler(void); + void PWM2_IRQHandler(void); + void SPIM2_SPIS2_SPI2_IRQHandler(void); + void RTC2_IRQHandler(void); + void I2S_IRQHandler(void); + void FPU_IRQHandler(void); +} + +using namespace pinetime::platform::nrf52; + +void SysTick_Handler(void) +{ + InterruptHandler *h = InterruptGuardian::instance.nrf52_vector[InterruptGuardian::Nrf52IrqN::SYS_TICK_IRQ]; + h->handle(); +}