digitalio: add interrupt support and append to rotary

This commit is contained in:
Vasily Davydov 2023-04-26 18:19:42 +03:00
parent 809358b341
commit a57f814875
4 changed files with 89 additions and 4 deletions

View File

@ -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 ()
{

View File

@ -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_ */

View File

@ -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() {}

View File

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