Separate nrf52/cm4 interrupt handling

This commit is contained in:
Thomas Klaehn 2020-04-10 08:14:36 +02:00
parent a1c89c96d5
commit 3f379122db
17 changed files with 192 additions and 78 deletions

2
.vscode/tasks.json vendored
View File

@ -6,7 +6,7 @@
// "APPLICATION": "spi", // "APPLICATION": "spi",
// "APPLICATION": "st7789_lcd", // "APPLICATION": "st7789_lcd",
"APPLICATION": "sys_tick", "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": { "presentation": {

View File

@ -3,7 +3,7 @@
namespace pinetime::interfaces { namespace pinetime::interfaces {
class InterruptInterface class InterruptHandlerInterface
{ {
public: public:
virtual void handle() = 0; virtual void handle() = 0;

View File

@ -2,11 +2,14 @@
#include "delay.h" #include "delay.h"
#include "platform/cm4/InterruptHandler.h"
#include "platform/cm4/InterruptGuardian.h"
#include "platform/nrf52/gpio.h" #include "platform/nrf52/gpio.h"
#include "platform/nrf52/InterruptHandler.h" #include "platform/nrf52/InterruptHandler.h"
#include "platform/nrf52/InterruptGuardian.h" #include "platform/nrf52/InterruptGuardian.h"
using namespace pinetime::platform::nrf52; using namespace pinetime::platform;
enum { enum {
PIN_NUMBER_LED_1 = 17, PIN_NUMBER_LED_1 = 17,
@ -15,20 +18,21 @@ enum {
PIN_NUMBER_LED_4 = 20 PIN_NUMBER_LED_4 = 20
}; };
Gpio led_1(PIN_NUMBER_LED_1); nrf52::Gpio led_1(PIN_NUMBER_LED_1);
Gpio led_2(PIN_NUMBER_LED_2); nrf52::Gpio led_2(PIN_NUMBER_LED_2);
Gpio led_3(PIN_NUMBER_LED_3); nrf52::Gpio led_3(PIN_NUMBER_LED_3);
Gpio led_4(PIN_NUMBER_LED_4); nrf52::Gpio led_4(PIN_NUMBER_LED_4);
std::array<Gpio *, 4> leds = {&led_1, &led_2, &led_3, &led_4}; std::array<nrf52::Gpio *, 4> 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) int main(void)
{ {
while(true) { while(true) {
for(auto it = std::begin(leds); it != std::end(leds); ++it) { for(auto it = std::begin(leds); it != std::end(leds); ++it) {
Gpio * tmp = *it; nrf52::Gpio * tmp = *it;
tmp->toggle(); tmp->toggle();
delay_ms(500); delay_ms(500);
} }

View File

@ -1,24 +1,27 @@
#include "delay.h" #include "delay.h"
#include "platform/cm4/InterruptHandler.h"
#include "platform/cm4/InterruptGuardian.h"
#include "platform/nrf52/gpio.h" #include "platform/nrf52/gpio.h"
#include "platform/nrf52/spi.h" #include "platform/nrf52/spi.h"
#include "platform/nrf52/InterruptHandler.h" #include "platform/nrf52/InterruptHandler.h"
#include "platform/nrf52/InterruptGuardian.h" #include "platform/nrf52/InterruptGuardian.h"
using namespace pinetime::platform::nrf52; using namespace pinetime::platform;
const uint8_t buf[] = "Test"; 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) int main(void)
{ {
Gpio led_1(17);
Gpio lcd_chip_select(25);
Spi spi_0(0, 2, 3, 4, lcd_chip_select);
while(1) { while(1) {
delay_ms(200); delay_ms(200);
spi_0.send(buf, sizeof(buf)); spi_0.send(buf, sizeof(buf));

View File

@ -1,24 +1,28 @@
#include "delay.h" #include "delay.h"
#include "platform/cm4/InterruptHandler.h"
#include "platform/cm4/InterruptGuardian.h"
#include "platform/nrf52/gpio.h" #include "platform/nrf52/gpio.h"
#include "platform/nrf52/spi.h" #include "platform/nrf52/spi.h"
#include "platform/nrf52/InterruptHandler.h" #include "platform/nrf52/InterruptHandler.h"
#include "platform/nrf52/InterruptGuardian.h" #include "platform/nrf52/InterruptGuardian.h"
#include "st7789.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); nrf52::Gpio lcd_reset(26);
Gpio lcd_data_command(18); nrf52::Gpio lcd_data_command(18);
Gpio lcd_backlight(23); nrf52::Gpio lcd_backlight(23);
Gpio lcd_chip_select(25); nrf52::Gpio lcd_chip_select(25);
Spi lcd_spi(0, 2, 3, 4, lcd_chip_select); nrf52::Spi lcd_spi(0, 2, 3, 4, lcd_chip_select);
St7789 lcd(lcd_spi, lcd_reset, lcd_data_command, lcd_backlight); 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) int main(void)
{ {

View File

@ -1,15 +1,14 @@
#include <array> #include <array>
extern "C" { #include "platform/cm4/InterruptHandler.h"
#include "nrf52.h" #include "platform/cm4/InterruptGuardian.h"
} #include "platform/cm4/SystemTick.h"
#include "platform/nrf52/gpio.h" #include "platform/nrf52/gpio.h"
#include "platform/nrf52/InterruptHandler.h" #include "platform/nrf52/InterruptHandler.h"
#include "platform/nrf52/InterruptGuardian.h" #include "platform/nrf52/InterruptGuardian.h"
#include "platform/cm4/SystemTick.h"
using namespace pinetime::platform::nrf52; using namespace pinetime::platform;
enum { enum {
PIN_NUMBER_LED_1 = 17, PIN_NUMBER_LED_1 = 17,
@ -18,26 +17,27 @@ enum {
PIN_NUMBER_LED_4 = 20 PIN_NUMBER_LED_4 = 20
}; };
Gpio led_1(PIN_NUMBER_LED_1); nrf52::Gpio led_1(PIN_NUMBER_LED_1);
Gpio led_2(PIN_NUMBER_LED_2); nrf52::Gpio led_2(PIN_NUMBER_LED_2);
Gpio led_3(PIN_NUMBER_LED_3); nrf52::Gpio led_3(PIN_NUMBER_LED_3);
Gpio led_4(PIN_NUMBER_LED_4); nrf52::Gpio led_4(PIN_NUMBER_LED_4);
std::array<Gpio *, 4> leds = {&led_1, &led_2, &led_3, &led_4}; std::array<nrf52::Gpio *, 4> 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) int main(void)
{ {
cm4::SystemTick ticker;
ticker.enable(); ticker.enable();
uint32_t last_tick = 0; uint32_t last_tick = 0;
while(true) { while(true) {
for(auto it = std::begin(leds); it != std::end(leds); ++it) { for(auto it = std::begin(leds); it != std::end(leds); ++it) {
uint32_t tick = ticker.tick() / 1000; uint32_t tick = ticker.tick() / 1000;
if(tick != last_tick) { if(tick != last_tick) {
Gpio * tmp = *it; nrf52::Gpio * tmp = *it;
tmp->toggle(); tmp->toggle();
last_tick = tick; last_tick = tick;
} }

View File

@ -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;
}

View File

@ -0,0 +1,45 @@
#ifndef __PINETIME_PLATFORM_CM4_INTERRUPTGUARDIAN_H__
#define __PINETIME_PLATFORM_CM4_INTERRUPTGUARDIAN_H__
#include <array>
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<InterruptHandler *, CM4_HANDLER_COUNT> cm4_vector;
};
}
#endif

View File

@ -0,0 +1,26 @@
#include <assert.h>
#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<InterruptGuardian::Cm4IrqN>(irq_nr), *this);
}
void InterruptHandler::handle()
{
assert(false);
}
void InterruptHandler::enable()
{
assert(false);
}
void InterruptHandler::disable()
{
assert(false);
}

View File

@ -0,0 +1,22 @@
#ifndef __PINETIME_PLATFORM_CM4_INTERRUPTHANDLER_H__
#define __PINETIME_PLATFORM_CM4_INTERRUPTHANDLER_H__
#include <cstdint>
#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

View File

@ -2,14 +2,14 @@ extern "C" {
#include "nrf52.h" #include "nrf52.h"
} }
#include "platform/cm4/InterruptHandler.h"
#include "platform/cm4/InterruptGuardian.h"
#include "platform/cm4/SystemTick.h" #include "platform/cm4/SystemTick.h"
#include "platform/nrf52/InterruptGuardian.h"
using namespace pinetime::platform::cm4; using namespace pinetime::platform::cm4;
using namespace pinetime::platform::nrf52;
SystemTick::SystemTick() SystemTick::SystemTick()
: InterruptHandler(InterruptGuardian::Nrf52IrqN::SYS_TICK_IRQ) : InterruptHandler(InterruptGuardian::Cm4IrqN::SYS_TICK_IRQ)
, sys_tick(0) , sys_tick(0)
{ {
} }

View File

@ -1,11 +1,11 @@
#ifndef __PLATFORM_CM4_SYSTEMTICK_H__ #ifndef __PLATFORM_CM4_SYSTEMTICK_H__
#define __PLATFORM_CM4_SYSTEMTICK_H__ #define __PLATFORM_CM4_SYSTEMTICK_H__
#include "platform/nrf52/InterruptHandler.h" #include "platform/cm4/InterruptHandler.h"
namespace pinetime::platform::cm4 { namespace pinetime::platform::cm4 {
class SystemTick : public pinetime::platform::nrf52::InterruptHandler class SystemTick : public pinetime::platform::cm4::InterruptHandler
{ {
public: public:
SystemTick(); SystemTick();

View File

@ -0,0 +1,28 @@
#include <cassert>
#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();
}

View File

@ -15,19 +15,6 @@ public:
InterruptGuardian(); InterruptGuardian();
enum Nrf52IrqN { 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 POWER_CLOCK_IRQn, //!< 0 POWER_CLOCK
RADIO_IRQn, //!< 1 RADIO RADIO_IRQn, //!< 1 RADIO
UARTE0_UART0_IRQn, //!< 2 UARTE0_UART0 UARTE0_UART0_IRQn, //!< 2 UARTE0_UART0
@ -66,10 +53,13 @@ public:
I2S_IRQn, //!< 37 I2S I2S_IRQn, //!< 37 I2S
FPU_IRQn //!< 38 FPU FPU_IRQn //!< 38 FPU
}; };
private:
enum { enum {
NRF52_HANDLER_COUNT = FPU_IRQn + 1, NRF52_HANDLER_COUNT = FPU_IRQn + 1,
}; };
public:
void register_handler(Nrf52IrqN irq_nr, InterruptHandler &); void register_handler(Nrf52IrqN irq_nr, InterruptHandler &);
static InterruptGuardian instance; static InterruptGuardian instance;

View File

@ -12,7 +12,6 @@ InterruptHandler::InterruptHandler(uint32_t irq_nr)
void InterruptHandler::handle() void InterruptHandler::handle()
{ {
asm volatile("nop");
assert(false); assert(false);
} }

View File

@ -7,7 +7,7 @@
namespace pinetime::platform::nrf52 { namespace pinetime::platform::nrf52 {
class InterruptHandler : public pinetime::interfaces::InterruptInterface class InterruptHandler : public pinetime::interfaces::InterruptHandlerInterface
{ {
public: public:
InterruptHandler(uint32_t); InterruptHandler(uint32_t);

View File

@ -4,16 +4,6 @@
#include "platform/nrf52/InterruptGuardian.h" #include "platform/nrf52/InterruptGuardian.h"
extern "C" { 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 POWER_CLOCK_IRQHandler(void);
void RADIO_IRQHandler(void); void RADIO_IRQHandler(void);
void UARTE0_UART0_IRQHandler(void); void UARTE0_UART0_IRQHandler(void);
@ -54,13 +44,3 @@ extern "C" {
} }
using namespace pinetime::platform::nrf52; 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();
}