aboutsummaryrefslogtreecommitdiffstats
path: root/arduino/cores/nRF5/Uart.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'arduino/cores/nRF5/Uart.cpp')
-rwxr-xr-xarduino/cores/nRF5/Uart.cpp220
1 files changed, 220 insertions, 0 deletions
diff --git a/arduino/cores/nRF5/Uart.cpp b/arduino/cores/nRF5/Uart.cpp
new file mode 100755
index 0000000..6eb5efd
--- /dev/null
+++ b/arduino/cores/nRF5/Uart.cpp
@@ -0,0 +1,220 @@
+/*
+ Copyright (c) 2015 Arduino LLC. All right reserved.
+ Copyright (c) 2016 Sandeep Mistry All right reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "Uart.h"
+#include "Arduino.h"
+#include "wiring_private.h"
+
+
+void serialEventRun(void)
+{
+ if (serialEvent && Serial.available() ) serialEvent();
+}
+
+Uart::Uart(NRF_UART_Type *_nrfUart, IRQn_Type _IRQn, uint8_t _pinRX, uint8_t _pinTX)
+{
+ nrfUart = _nrfUart;
+ IRQn = _IRQn;
+ uc_pinRX = g_ADigitalPinMap[_pinRX];
+ uc_pinTX = g_ADigitalPinMap[_pinTX];
+ uc_hwFlow = 0;
+
+ _mutex = NULL;
+ _begun = false;
+}
+
+Uart::Uart(NRF_UART_Type *_nrfUart, IRQn_Type _IRQn, uint8_t _pinRX, uint8_t _pinTX, uint8_t _pinCTS, uint8_t _pinRTS)
+{
+ nrfUart = _nrfUart;
+ IRQn = _IRQn;
+ uc_pinRX = g_ADigitalPinMap[_pinRX];
+ uc_pinTX = g_ADigitalPinMap[_pinTX];
+ uc_pinCTS = g_ADigitalPinMap[_pinCTS];
+ uc_pinRTS = g_ADigitalPinMap[_pinRTS];
+ uc_hwFlow = 1;
+
+ _mutex = NULL;
+ _begun = false;
+}
+
+void Uart::setPins(uint8_t pin_rx, uint8_t pin_tx)
+{
+ uc_pinRX = pin_rx;
+ uc_pinTX = pin_tx;
+}
+
+void Uart::begin(unsigned long baudrate)
+{
+ begin(baudrate, (uint8_t)SERIAL_8N1);
+}
+
+void Uart::begin(unsigned long baudrate, uint16_t /*config*/)
+{
+ // skip if already begun
+ if ( _begun ) return;
+
+ nrfUart->PSELTXD = uc_pinTX;
+ nrfUart->PSELRXD = uc_pinRX;
+
+ if (uc_hwFlow == 1) {
+ nrfUart->PSELCTS = uc_pinCTS;
+ nrfUart->PSELRTS = uc_pinRTS;
+ nrfUart->CONFIG = (UART_CONFIG_PARITY_Excluded << UART_CONFIG_PARITY_Pos) | UART_CONFIG_HWFC_Enabled;
+ } else {
+ nrfUart->CONFIG = (UART_CONFIG_PARITY_Excluded << UART_CONFIG_PARITY_Pos) | UART_CONFIG_HWFC_Disabled;
+ }
+
+ uint32_t nrfBaudRate;
+
+ if (baudrate <= 1200) {
+ nrfBaudRate = UARTE_BAUDRATE_BAUDRATE_Baud1200;
+ } else if (baudrate <= 2400) {
+ nrfBaudRate = UARTE_BAUDRATE_BAUDRATE_Baud2400;
+ } else if (baudrate <= 4800) {
+ nrfBaudRate = UARTE_BAUDRATE_BAUDRATE_Baud4800;
+ } else if (baudrate <= 9600) {
+ nrfBaudRate = UARTE_BAUDRATE_BAUDRATE_Baud9600;
+ } else if (baudrate <= 14400) {
+ nrfBaudRate = UARTE_BAUDRATE_BAUDRATE_Baud14400;
+ } else if (baudrate <= 19200) {
+ nrfBaudRate = UARTE_BAUDRATE_BAUDRATE_Baud19200;
+ } else if (baudrate <= 28800) {
+ nrfBaudRate = UARTE_BAUDRATE_BAUDRATE_Baud28800;
+ } else if (baudrate <= 38400) {
+ nrfBaudRate = UARTE_BAUDRATE_BAUDRATE_Baud38400;
+ } else if (baudrate <= 57600) {
+ nrfBaudRate = UARTE_BAUDRATE_BAUDRATE_Baud57600;
+ } else if (baudrate <= 76800) {
+ nrfBaudRate = UARTE_BAUDRATE_BAUDRATE_Baud76800;
+ } else if (baudrate <= 115200) {
+ nrfBaudRate = UARTE_BAUDRATE_BAUDRATE_Baud115200;
+ } else if (baudrate <= 230400) {
+ nrfBaudRate = UARTE_BAUDRATE_BAUDRATE_Baud230400;
+ } else if (baudrate <= 250000) {
+ nrfBaudRate = UARTE_BAUDRATE_BAUDRATE_Baud250000;
+ } else if (baudrate <= 460800) {
+ nrfBaudRate = UARTE_BAUDRATE_BAUDRATE_Baud460800;
+ } else if (baudrate <= 921600) {
+ nrfBaudRate = UARTE_BAUDRATE_BAUDRATE_Baud921600;
+ } else {
+ nrfBaudRate = UARTE_BAUDRATE_BAUDRATE_Baud1M;
+ }
+
+ nrfUart->BAUDRATE = nrfBaudRate;
+
+ nrfUart->ENABLE = UART_ENABLE_ENABLE_Enabled;
+
+ nrfUart->EVENTS_RXDRDY = 0x0UL;
+ nrfUart->EVENTS_TXDRDY = 0x0UL;
+
+ nrfUart->TASKS_STARTRX = 0x1UL;
+ nrfUart->TASKS_STARTTX = 0x1UL;
+
+ nrfUart->INTENSET = UART_INTENSET_RXDRDY_Msk;
+
+ NVIC_ClearPendingIRQ(IRQn);
+ NVIC_SetPriority(IRQn, 3);
+ NVIC_EnableIRQ(IRQn);
+
+ _mutex = xSemaphoreCreateMutex();
+ _begun = true;
+}
+
+void Uart::end()
+{
+ NVIC_DisableIRQ(IRQn);
+
+ nrfUart->INTENCLR = UART_INTENCLR_RXDRDY_Msk;
+
+ nrfUart->TASKS_STOPRX = 0x1UL;
+ nrfUart->TASKS_STOPTX = 0x1UL;
+
+ nrfUart->ENABLE = UART_ENABLE_ENABLE_Disabled;
+
+ nrfUart->PSELTXD = 0xFFFFFFFF;
+ nrfUart->PSELRXD = 0xFFFFFFFF;
+
+ nrfUart->PSELRTS = 0xFFFFFFFF;
+ nrfUart->PSELCTS = 0xFFFFFFFF;
+
+ rxBuffer.clear();
+
+ vSemaphoreDelete(_mutex);
+ _mutex = NULL;
+ _begun = false;
+}
+
+void Uart::flush()
+{
+ rxBuffer.clear();
+}
+
+void Uart::IrqHandler()
+{
+ if (nrfUart->EVENTS_RXDRDY)
+ {
+ nrfUart->EVENTS_RXDRDY = 0x0UL;
+ rxBuffer.store_char(nrfUart->RXD);
+ }
+}
+
+int Uart::available()
+{
+ return rxBuffer.available();
+}
+
+int Uart::peek()
+{
+ return rxBuffer.peek();
+}
+
+int Uart::read()
+{
+ return rxBuffer.read_char();
+}
+
+size_t Uart::write(const uint8_t data)
+{
+ xSemaphoreTake(_mutex, portMAX_DELAY);
+
+ nrfUart->TXD = data;
+
+ while(!nrfUart->EVENTS_TXDRDY);
+
+ nrfUart->EVENTS_TXDRDY = 0x0UL;
+
+ xSemaphoreGive(_mutex);
+
+ return 1;
+}
+
+Uart SERIAL_PORT_HARDWARE( NRF_UART0, UARTE0_UART0_IRQn, PIN_SERIAL_RX, PIN_SERIAL_TX );
+
+#ifdef HAVE_HWSERIAL2
+// TODO UART1 is UARTE only, need update class Uart to work
+Uart Serial2( NRF_UARTE1, UARTE1_IRQn, PIN_SERIAL2_RX, PIN_SERIAL2_TX );
+#endif
+
+extern "C"
+{
+ void UARTE0_UART0_IRQHandler()
+ {
+ SERIAL_PORT_HARDWARE.IrqHandler();
+ }
+}