diff --git a/.vscode/tasks.json b/.vscode/tasks.json index ecfd878..75679ae 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -6,7 +6,7 @@ // "APPLICATION": "spi", // "APPLICATION": "st7789_lcd", "APPLICATION": "sys_tick", - "${BUILD_CMD}": "eval docker run --env PLATFORM=${PLATFORM} --env APPLICATION=${APPLICATION} -t --rm -v '${workspaceFolder}':/work --user $(id -u):$(id -g) arm-none-eabi.buildenv", + "BUILD_CMD": "eval docker run --env APPLICATION=${APPLICATION} -t --rm -v '${workspaceFolder}':/work --user $(id -u):$(id -g) arm-none-eabi.buildenv", }, }, "presentation": { diff --git a/interfaces/interrupt_interface.h b/interfaces/interrupt_interface.h index f887f1b..78397ab 100644 --- a/interfaces/interrupt_interface.h +++ b/interfaces/interrupt_interface.h @@ -3,7 +3,7 @@ namespace pinetime::interfaces { -class InterruptInterface +class InterruptHandlerInterface { public: virtual void handle() = 0; diff --git a/src/application/blinky/main.cc b/src/application/blinky/main.cc index 7e3aafc..47fec2e 100644 --- a/src/application/blinky/main.cc +++ b/src/application/blinky/main.cc @@ -2,11 +2,14 @@ #include "delay.h" +#include "platform/cm4/InterruptHandler.h" +#include "platform/cm4/InterruptGuardian.h" + #include "platform/nrf52/gpio.h" #include "platform/nrf52/InterruptHandler.h" #include "platform/nrf52/InterruptGuardian.h" -using namespace pinetime::platform::nrf52; +using namespace pinetime::platform; enum { PIN_NUMBER_LED_1 = 17, @@ -15,20 +18,21 @@ enum { PIN_NUMBER_LED_4 = 20 }; -Gpio led_1(PIN_NUMBER_LED_1); -Gpio led_2(PIN_NUMBER_LED_2); -Gpio led_3(PIN_NUMBER_LED_3); -Gpio led_4(PIN_NUMBER_LED_4); +nrf52::Gpio led_1(PIN_NUMBER_LED_1); +nrf52::Gpio led_2(PIN_NUMBER_LED_2); +nrf52::Gpio led_3(PIN_NUMBER_LED_3); +nrf52::Gpio led_4(PIN_NUMBER_LED_4); -std::array leds = {&led_1, &led_2, &led_3, &led_4}; +std::array leds = {&led_1, &led_2, &led_3, &led_4}; -InterruptGuardian InterruptGuardian::instance; +cm4::InterruptGuardian cm4::InterruptGuardian::instance; +nrf52::InterruptGuardian nrf52::InterruptGuardian::instance; int main(void) { while(true) { for(auto it = std::begin(leds); it != std::end(leds); ++it) { - Gpio * tmp = *it; + nrf52::Gpio * tmp = *it; tmp->toggle(); delay_ms(500); } diff --git a/src/application/spi/main.cc b/src/application/spi/main.cc index 31eb0c9..c6fff86 100644 --- a/src/application/spi/main.cc +++ b/src/application/spi/main.cc @@ -1,24 +1,27 @@ #include "delay.h" +#include "platform/cm4/InterruptHandler.h" +#include "platform/cm4/InterruptGuardian.h" + #include "platform/nrf52/gpio.h" #include "platform/nrf52/spi.h" #include "platform/nrf52/InterruptHandler.h" #include "platform/nrf52/InterruptGuardian.h" -using namespace pinetime::platform::nrf52; +using namespace pinetime::platform; const uint8_t buf[] = "Test"; -InterruptGuardian InterruptGuardian::instance; +nrf52::Gpio led_1(17); +nrf52::Gpio lcd_chip_select(25); +nrf52::Spi spi_0(0, 2, 3, 4, lcd_chip_select); + +cm4::InterruptGuardian cm4::InterruptGuardian::instance; +nrf52::InterruptGuardian nrf52::InterruptGuardian::instance; int main(void) { - Gpio led_1(17); - Gpio lcd_chip_select(25); - - Spi spi_0(0, 2, 3, 4, lcd_chip_select); - while(1) { delay_ms(200); spi_0.send(buf, sizeof(buf)); diff --git a/src/application/st7789_lcd/main.cc b/src/application/st7789_lcd/main.cc index 819d395..0b5333d 100644 --- a/src/application/st7789_lcd/main.cc +++ b/src/application/st7789_lcd/main.cc @@ -1,24 +1,28 @@ #include "delay.h" +#include "platform/cm4/InterruptHandler.h" +#include "platform/cm4/InterruptGuardian.h" + #include "platform/nrf52/gpio.h" #include "platform/nrf52/spi.h" #include "platform/nrf52/InterruptHandler.h" #include "platform/nrf52/InterruptGuardian.h" #include "st7789.h" -using namespace pinetime::platform::nrf52; +using namespace pinetime::platform; -Gpio led_1(17); +nrf52::Gpio led_1(17); -Gpio lcd_reset(26); -Gpio lcd_data_command(18); -Gpio lcd_backlight(23); -Gpio lcd_chip_select(25); -Spi lcd_spi(0, 2, 3, 4, lcd_chip_select); +nrf52::Gpio lcd_reset(26); +nrf52::Gpio lcd_data_command(18); +nrf52::Gpio lcd_backlight(23); +nrf52::Gpio lcd_chip_select(25); +nrf52::Spi lcd_spi(0, 2, 3, 4, lcd_chip_select); St7789 lcd(lcd_spi, lcd_reset, lcd_data_command, lcd_backlight); -InterruptGuardian InterruptGuardian::instance; +cm4::InterruptGuardian cm4::InterruptGuardian::instance; +nrf52::InterruptGuardian nrf52::InterruptGuardian::instance; int main(void) { diff --git a/src/application/sys_tick/main.cc b/src/application/sys_tick/main.cc index 21cadbf..75d27a6 100644 --- a/src/application/sys_tick/main.cc +++ b/src/application/sys_tick/main.cc @@ -1,15 +1,14 @@ #include -extern "C" { - #include "nrf52.h" -} +#include "platform/cm4/InterruptHandler.h" +#include "platform/cm4/InterruptGuardian.h" +#include "platform/cm4/SystemTick.h" #include "platform/nrf52/gpio.h" #include "platform/nrf52/InterruptHandler.h" #include "platform/nrf52/InterruptGuardian.h" -#include "platform/cm4/SystemTick.h" -using namespace pinetime::platform::nrf52; +using namespace pinetime::platform; enum { PIN_NUMBER_LED_1 = 17, @@ -18,26 +17,27 @@ enum { PIN_NUMBER_LED_4 = 20 }; -Gpio led_1(PIN_NUMBER_LED_1); -Gpio led_2(PIN_NUMBER_LED_2); -Gpio led_3(PIN_NUMBER_LED_3); -Gpio led_4(PIN_NUMBER_LED_4); +nrf52::Gpio led_1(PIN_NUMBER_LED_1); +nrf52::Gpio led_2(PIN_NUMBER_LED_2); +nrf52::Gpio led_3(PIN_NUMBER_LED_3); +nrf52::Gpio led_4(PIN_NUMBER_LED_4); -std::array leds = {&led_1, &led_2, &led_3, &led_4}; +std::array leds = {&led_1, &led_2, &led_3, &led_4}; -InterruptGuardian InterruptGuardian::instance; +nrf52::InterruptGuardian nrf52::InterruptGuardian::instance; +cm4::InterruptGuardian cm4::InterruptGuardian::instance; -pinetime::platform::cm4::SystemTick ticker; int main(void) { + cm4::SystemTick ticker; ticker.enable(); uint32_t last_tick = 0; while(true) { for(auto it = std::begin(leds); it != std::end(leds); ++it) { uint32_t tick = ticker.tick() / 1000; if(tick != last_tick) { - Gpio * tmp = *it; + nrf52::Gpio * tmp = *it; tmp->toggle(); last_tick = tick; } diff --git a/src/platform/cm4/InterruptGuardian.cc b/src/platform/cm4/InterruptGuardian.cc new file mode 100644 index 0000000..6a4bec9 --- /dev/null +++ b/src/platform/cm4/InterruptGuardian.cc @@ -0,0 +1,13 @@ +#include "platform/cm4/InterruptHandler.h" +#include "platform/cm4/InterruptGuardian.h" + +using namespace pinetime::platform::cm4; + +InterruptGuardian::InterruptGuardian() +{ +} + +void InterruptGuardian::register_handler(Cm4IrqN irq_nr, InterruptHandler &handler) +{ + this->cm4_vector[irq_nr] = &handler; +} diff --git a/src/platform/cm4/InterruptGuardian.h b/src/platform/cm4/InterruptGuardian.h new file mode 100644 index 0000000..edd5047 --- /dev/null +++ b/src/platform/cm4/InterruptGuardian.h @@ -0,0 +1,45 @@ +#ifndef __PINETIME_PLATFORM_CM4_INTERRUPTGUARDIAN_H__ +#define __PINETIME_PLATFORM_CM4_INTERRUPTGUARDIAN_H__ + +#include + +extern "C" { + #include "nrf52.h" +} + +namespace pinetime::platform::cm4 { + +class InterruptGuardian +{ +public: + InterruptGuardian(); + + enum Cm4IrqN { + 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 + }; + +private: + enum { + CM4_HANDLER_COUNT = SYS_TICK_IRQ + 1, + }; + +public: + void register_handler(Cm4IrqN irq_nr, InterruptHandler &); + + static InterruptGuardian instance; + + std::array cm4_vector; +}; + +} + +#endif diff --git a/src/platform/cm4/InterruptHandler.cc b/src/platform/cm4/InterruptHandler.cc new file mode 100644 index 0000000..7e93013 --- /dev/null +++ b/src/platform/cm4/InterruptHandler.cc @@ -0,0 +1,26 @@ +#include + +#include "platform/cm4/InterruptHandler.h" +#include "platform/cm4/InterruptGuardian.h" + +using namespace pinetime::platform::cm4; + +InterruptHandler::InterruptHandler(uint32_t irq_nr) +{ + InterruptGuardian::instance.register_handler(static_cast(irq_nr), *this); +} + +void InterruptHandler::handle() +{ + assert(false); +} + +void InterruptHandler::enable() +{ + assert(false); +} + +void InterruptHandler::disable() +{ + assert(false); +} diff --git a/src/platform/cm4/InterruptHandler.h b/src/platform/cm4/InterruptHandler.h new file mode 100644 index 0000000..c18365b --- /dev/null +++ b/src/platform/cm4/InterruptHandler.h @@ -0,0 +1,22 @@ +#ifndef __PINETIME_PLATFORM_CM4_INTERRUPTHANDLER_H__ +#define __PINETIME_PLATFORM_CM4_INTERRUPTHANDLER_H__ + +#include + +#include "interrupt_interface.h" + +namespace pinetime::platform::cm4 { + +class InterruptHandler : public pinetime::interfaces::InterruptHandlerInterface +{ + public: + InterruptHandler(uint32_t); + + void handle() override; + void enable() override; + void disable() override; +}; + +} + +#endif diff --git a/src/platform/cm4/SystemTick.cc b/src/platform/cm4/SystemTick.cc index be2cc5b..c95adfa 100644 --- a/src/platform/cm4/SystemTick.cc +++ b/src/platform/cm4/SystemTick.cc @@ -2,14 +2,14 @@ extern "C" { #include "nrf52.h" } +#include "platform/cm4/InterruptHandler.h" +#include "platform/cm4/InterruptGuardian.h" #include "platform/cm4/SystemTick.h" -#include "platform/nrf52/InterruptGuardian.h" using namespace pinetime::platform::cm4; -using namespace pinetime::platform::nrf52; SystemTick::SystemTick() - : InterruptHandler(InterruptGuardian::Nrf52IrqN::SYS_TICK_IRQ) + : InterruptHandler(InterruptGuardian::Cm4IrqN::SYS_TICK_IRQ) , sys_tick(0) { } diff --git a/src/platform/cm4/SystemTick.h b/src/platform/cm4/SystemTick.h index 0a52cbf..360383b 100644 --- a/src/platform/cm4/SystemTick.h +++ b/src/platform/cm4/SystemTick.h @@ -1,11 +1,11 @@ #ifndef __PLATFORM_CM4_SYSTEMTICK_H__ #define __PLATFORM_CM4_SYSTEMTICK_H__ -#include "platform/nrf52/InterruptHandler.h" +#include "platform/cm4/InterruptHandler.h" namespace pinetime::platform::cm4 { -class SystemTick : public pinetime::platform::nrf52::InterruptHandler +class SystemTick : public pinetime::platform::cm4::InterruptHandler { public: SystemTick(); diff --git a/src/platform/cm4/low_level_interrupt.cc b/src/platform/cm4/low_level_interrupt.cc new file mode 100644 index 0000000..b5d5949 --- /dev/null +++ b/src/platform/cm4/low_level_interrupt.cc @@ -0,0 +1,28 @@ +#include + +#include "platform/cm4/InterruptHandler.h" +#include "platform/cm4/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); +} + +using namespace pinetime::platform::cm4; + +void SysTick_Handler(void) +{ + uint32_t irq_nr = InterruptGuardian::SYS_TICK_IRQ; + InterruptHandler *h = InterruptGuardian::instance.cm4_vector[irq_nr]; + + assert(h != nullptr); + + h->handle(); +} diff --git a/src/platform/nrf52/InterruptGuardian.h b/src/platform/nrf52/InterruptGuardian.h index e884562..08ead62 100644 --- a/src/platform/nrf52/InterruptGuardian.h +++ b/src/platform/nrf52/InterruptGuardian.h @@ -15,19 +15,6 @@ 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 @@ -66,10 +53,13 @@ public: I2S_IRQn, //!< 37 I2S FPU_IRQn //!< 38 FPU }; + +private: enum { NRF52_HANDLER_COUNT = FPU_IRQn + 1, }; +public: void register_handler(Nrf52IrqN irq_nr, InterruptHandler &); static InterruptGuardian instance; diff --git a/src/platform/nrf52/InterruptHandler.cc b/src/platform/nrf52/InterruptHandler.cc index b700663..7244720 100644 --- a/src/platform/nrf52/InterruptHandler.cc +++ b/src/platform/nrf52/InterruptHandler.cc @@ -12,7 +12,6 @@ InterruptHandler::InterruptHandler(uint32_t irq_nr) void InterruptHandler::handle() { - asm volatile("nop"); assert(false); } diff --git a/src/platform/nrf52/InterruptHandler.h b/src/platform/nrf52/InterruptHandler.h index 1199bde..ddfdd55 100644 --- a/src/platform/nrf52/InterruptHandler.h +++ b/src/platform/nrf52/InterruptHandler.h @@ -7,7 +7,7 @@ namespace pinetime::platform::nrf52 { -class InterruptHandler : public pinetime::interfaces::InterruptInterface +class InterruptHandler : public pinetime::interfaces::InterruptHandlerInterface { public: InterruptHandler(uint32_t); diff --git a/src/platform/nrf52/low_level_interrupt.cc b/src/platform/nrf52/low_level_interrupt.cc index 7bf7ad3..953a8f2 100644 --- a/src/platform/nrf52/low_level_interrupt.cc +++ b/src/platform/nrf52/low_level_interrupt.cc @@ -4,16 +4,6 @@ #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); @@ -54,13 +44,3 @@ extern "C" { } using namespace pinetime::platform::nrf52; - -void SysTick_Handler(void) -{ - uint32_t irq_nr = InterruptGuardian::Nrf52IrqN::SYS_TICK_IRQ; - InterruptHandler *h = InterruptGuardian::instance.nrf52_vector[irq_nr]; - - assert(h != nullptr); - - h->handle(); -}