2023-04-27 00:47:55 +03:00

115 lines
2.9 KiB
C++

/*
* DigitalIoPin.cpp
*
* Created on: Aug 29, 2022
* Author: Vasily Davydov
*/
#include "DigitalIoPin.h"
DigitalIoPin::DigitalIoPin (int port, int pin, bool input, bool pullup,
bool invert, bool isr, IRQn_Type isr_index)
{
assert ((port <= UINT8_MAX_VALUE) && (pin <= UINT8_MAX_VALUE));
_io._port = (uint8_t)port;
_io._pin = (uint8_t)pin;
_io._input = input;
_io._pullup = pullup;
_io._invert = invert;
_io.IOCON_mode = IOCON_MODE_INACT;
_io.IOCON_inv = IOCON_FUNC0;
if (isr){
_io.isr_i = isr_index;
setIsr();
} else {
setIoPin ();
}
}
DigitalIoPin::~DigitalIoPin ()
{
}
void
DigitalIoPin::setIoPin ()
{
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;
}
}
Chip_IOCON_PinMuxSet (LPC_IOCON, _io._port, _io._pin,
(_io.IOCON_mode | _io.DigitalEn | _io.IOCON_inv));
/** False direction equals input */
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 ()
{
bool state = (Chip_GPIO_GetPinState (LPC_GPIO, _io._port, _io._pin));
return (_io._invert && !_io._input) ? !state : state;
}
void
DigitalIoPin::write (bool value)
{
assert (!(_io._input));
Chip_GPIO_SetPinState (LPC_GPIO, _io._port, _io._pin, ((_io._invert) ? !value : value));
}