From a57f814875d32261597cf308341a8c734ff35bfb Mon Sep 17 00:00:00 2001 From: Vasily Davydov Date: Wed, 26 Apr 2023 18:19:42 +0300 Subject: [PATCH] digitalio: add interrupt support and append to rotary --- source/shoh/src/peripherals/DigitalIoPin.cpp | 55 +++++++++++++++++++- source/shoh/src/peripherals/DigitalIoPin.h | 4 +- source/shoh/src/threads/rotary/Rotary.cpp | 30 ++++++++++- source/shoh/src/threads/rotary/Rotary.h | 4 ++ 4 files changed, 89 insertions(+), 4 deletions(-) diff --git a/source/shoh/src/peripherals/DigitalIoPin.cpp b/source/shoh/src/peripherals/DigitalIoPin.cpp index 8255644..b56c1e0 100644 --- a/source/shoh/src/peripherals/DigitalIoPin.cpp +++ b/source/shoh/src/peripherals/DigitalIoPin.cpp @@ -8,7 +8,7 @@ #include "DigitalIoPin.h" DigitalIoPin::DigitalIoPin (int port, int pin, bool input, bool pullup, - bool invert) + bool invert, bool isr, IRQn_Type isr_index) { assert ((port <= UINT8_MAX_VALUE) && (pin <= UINT8_MAX_VALUE)); _io._port = (uint8_t)port; @@ -18,7 +18,12 @@ DigitalIoPin::DigitalIoPin (int port, int pin, bool input, bool pullup, _io._invert = invert; _io.IOCON_mode = IOCON_MODE_INACT; _io.IOCON_inv = IOCON_FUNC0; - setIoPin (); + if (isr){ + _io.isr_i = isr_index; + setIsr(); + } else { + setIoPin (); + } } DigitalIoPin::~DigitalIoPin () @@ -48,6 +53,52 @@ DigitalIoPin::setIoPin () Chip_GPIO_SetPinDIR (LPC_GPIO, _io._port, _io._pin, direction); } +void +DigitalIoPin::setIsr () +{ + bool direction = true; + if (_io._input) + { + direction = false; + _io.IOCON_mode = IOCON_MODE_PULLUP; + if (!_io._pullup) + { + _io.IOCON_mode = IOCON_MODE_PULLDOWN; + } + if (_io._invert) + { + _io.IOCON_inv = IOCON_INV_EN; + } + } + /* We'll use an optional IOCON filter (0) with a divider of 64 for the + input pin to be used for PININT */ + Chip_Clock_SetIOCONFiltClockDiv(0, 64); + + Chip_IOCON_PinMuxSet (LPC_IOCON, _io._port, _io._pin, + (_io.IOCON_mode | _io.DigitalEn + | _io.IOCON_inv | IOCON_CLKDIV(0) + | IOCON_S_MODE(3))); + /** False direction equals input */ + Chip_GPIO_SetPinDIR (LPC_GPIO, _io._port, _io._pin, direction); + + /* Enable PININT clock if it was not enabled before */ + if ((LPC_SYSCTL->SYSAHBCLKCTRL & (1 << SYSCTL_CLOCK_PINT)) == 0) + { + Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_PINT); + } + /* Configure interrupt channel for the GPIO pin in SysCon block */ + Chip_SYSCTL_SetPinInterrupt(_io.isr_i, _io._port, _io._pin); + + /* Configure channel interrupt as edge sensitive and falling edge interrupt */ + Chip_PININT_ClearIntStatus(LPC_PININT, PININTCH(_io.isr_i)); + Chip_PININT_SetPinModeEdge(LPC_PININT, PININTCH(_io.isr_i)); + Chip_PININT_EnableIntLow(LPC_PININT, PININTCH(_io.isr_i)); + + /* Enable interrupt in the NVIC */ + NVIC_ClearPendingIRQ(_io.isr_i); + NVIC_EnableIRQ(_io.isr_i); +} + bool DigitalIoPin::read () { diff --git a/source/shoh/src/peripherals/DigitalIoPin.h b/source/shoh/src/peripherals/DigitalIoPin.h index de004af..19c6c7b 100644 --- a/source/shoh/src/peripherals/DigitalIoPin.h +++ b/source/shoh/src/peripherals/DigitalIoPin.h @@ -23,13 +23,14 @@ typedef struct DigitalIOConfigStruct uint32_t IOCON_mode; uint32_t IOCON_inv; uint32_t DigitalEn; + IRQn_Type isr_i; } DigitalIOConfigStruct; class DigitalIoPin { public: DigitalIoPin (int port, int pin, bool input = true, bool pullup = true, - bool invert = false); + bool invert = false, bool isr = false, IRQn_Type isr_index = PIN_INT0_IRQn); DigitalIoPin (const DigitalIoPin &) = delete; virtual ~DigitalIoPin (); bool read (); @@ -38,6 +39,7 @@ public: private: DigitalIOConfigStruct _io = { 0, 0, false, false, false, 0, 0, IOCON_DIGMODE_EN}; void setIoPin (); + void setIsr(); }; #endif /* DIGITALIOPIN_H_ */ diff --git a/source/shoh/src/threads/rotary/Rotary.cpp b/source/shoh/src/threads/rotary/Rotary.cpp index 9d5e952..9e5d12b 100644 --- a/source/shoh/src/threads/rotary/Rotary.cpp +++ b/source/shoh/src/threads/rotary/Rotary.cpp @@ -6,8 +6,36 @@ */ #include "Rotary.h" +#include "board.h" -Rotary::Rotary(ThreadCommon::QueueManager* qm) : _qm(qm) {} +extern "C" +{ + void + PIN_INT0_IRQHandler (void) + { + //portEND_SWITCHING_ISR (); + } + + void + PIN_INT1_IRQHandler (void) + { + //portEND_SWITCHING_ISR (); + } + + void + PIN_INT2_IRQHandler (void) + { + //portEND_SWITCHING_ISR (); + } +} +// For example +#define GPIO_PININT_PIN 1 /* GPIO pin number mapped to PININT */ +#define GPIO_PININT_PORT 0 /* GPIO port number mapped to PININT */ + +Rotary::Rotary(ThreadCommon::QueueManager* qm) : _qm(qm) +{ + +} Rotary::~Rotary() {} diff --git a/source/shoh/src/threads/rotary/Rotary.h b/source/shoh/src/threads/rotary/Rotary.h index 4c97f41..d67bd4a 100644 --- a/source/shoh/src/threads/rotary/Rotary.h +++ b/source/shoh/src/threads/rotary/Rotary.h @@ -10,6 +10,7 @@ #include "Event.h" #include "ThreadCommon.h" +#include "DigitalIoPin.h" class Rotary { public: @@ -19,6 +20,9 @@ public: private: Event* message; ThreadCommon::QueueManager* _qm; + DigitalIoPin signal[3] = { { 0, 6, true, false, false, true, PIN_INT0_IRQn}, + { 0, 5, true, false, false, true, PIN_INT1_IRQn}, + { 1, 8, true, false, false, true, PIN_INT2_IRQn} }; }; void rotary_thread(void* pvParams);