From 7fc402f3b5a6f0d320959b86d5a18c425cbc0b3f Mon Sep 17 00:00:00 2001 From: Sandeep Mistry <s.mistry@bcmi-labs.cc> Date: Thu, 31 Aug 2017 14:09:09 -0400 Subject: [PATCH] Leverage SERCOM h/w functionality for RTS and CTS --- cores/arduino/SERCOM.cpp | 10 ++++++++++ cores/arduino/SERCOM.h | 2 ++ cores/arduino/Uart.cpp | 41 ++++++++++++++++++++-------------------- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/cores/arduino/SERCOM.cpp b/cores/arduino/SERCOM.cpp index 42c46d01..d0f50a6b 100644 --- a/cores/arduino/SERCOM.cpp +++ b/cores/arduino/SERCOM.cpp @@ -183,6 +183,16 @@ void SERCOM::disableDataRegisterEmptyInterruptUART() sercom->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_DRE; } +void SERCOM::enableReceiveCompleteInterruptUART() +{ + sercom->USART.INTENSET.reg |= SERCOM_USART_INTENSET_RXC; +} + +void SERCOM::disableReceiveCompleteInterruptUART() +{ + sercom->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_RXC; +} + /* ========================= * ===== Sercom SPI * ========================= diff --git a/cores/arduino/SERCOM.h b/cores/arduino/SERCOM.h index 6b7c703a..77609f87 100644 --- a/cores/arduino/SERCOM.h +++ b/cores/arduino/SERCOM.h @@ -165,6 +165,8 @@ class SERCOM void acknowledgeUARTError() ; void enableDataRegisterEmptyInterruptUART(); void disableDataRegisterEmptyInterruptUART(); + void enableReceiveCompleteInterruptUART(); + void disableReceiveCompleteInterruptUART(); /* ========== SPI ========== */ void initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder) ; diff --git a/cores/arduino/Uart.cpp b/cores/arduino/Uart.cpp index 6ef5338f..2b54787f 100644 --- a/cores/arduino/Uart.cpp +++ b/cores/arduino/Uart.cpp @@ -46,12 +46,11 @@ void Uart::begin(unsigned long baudrate, uint16_t config) pinPeripheral(uc_pinTX, g_APinDescription[uc_pinTX].ulPinType); if (uc_pinRTS != NO_RTS_PIN) { - pinMode(uc_pinRTS, OUTPUT); - digitalWrite(uc_pinRTS, LOW); + pinPeripheral(uc_pinRTS, g_APinDescription[uc_pinRTS].ulPinType); } if (uc_pinCTS != NO_CTS_PIN) { - pinMode(uc_pinCTS, INPUT); + pinPeripheral(uc_pinCTS, g_APinDescription[uc_pinCTS].ulPinType); } sercom->initUART(UART_INT_CLOCK, SAMPLE_RATE_x16, baudrate); @@ -86,9 +85,10 @@ void Uart::IrqHandler() rxBuffer.store_char(sercom->readDataUART()); if (uc_pinRTS != NO_RTS_PIN) { - // if there is NOT enough space in the RX buffer, de-assert RTS + // if there is NOT enough space in the RX buffer, + // diable the receive complete interrupt if (rxBuffer.availableForStore() < RTS_RX_THRESHOLD) { - digitalWrite(uc_pinRTS, HIGH); + sercom->disableReceiveCompleteInterruptUART(); } } } @@ -132,9 +132,10 @@ int Uart::read() int c = rxBuffer.read_char(); if (uc_pinRTS != NO_RTS_PIN) { - // if there is enough space in the RX buffer, assert RTS + // if there is enough space in the RX buffer, + // enable the receive completer interrupt if (rxBuffer.availableForStore() > RTS_RX_THRESHOLD) { - digitalWrite(uc_pinRTS, LOW); + sercom->enableReceiveCompleteInterruptUART(); } } @@ -143,16 +144,6 @@ int Uart::read() size_t Uart::write(const uint8_t data) { - if (uc_pinRTS != NO_RTS_PIN) { - // assert RTS - digitalWrite(uc_pinRTS, LOW); - } - - if (uc_pinCTS != NO_CTS_PIN) { - // wait until CTS is asserted - while (digitalRead(uc_pinCTS) != LOW); - } - if (sercom->isDataRegisterEmptyUART() && txBuffer.available() == 0) { sercom->writeDataUART(data); } else { @@ -217,14 +208,22 @@ SercomParityMode Uart::extractParity(uint16_t config) int Uart::attachRts(uint8_t pin) { - uc_pinRTS = pin; + if (uc_padTX == UART_TX_RTS_CTS_PAD_0_2_3) { + uc_pinRTS = pin; - return 1; + return 1; + } + + return 0; } int Uart::attachCts(uint8_t pin) { - uc_pinCTS = pin; + if (uc_padTX == UART_TX_RTS_CTS_PAD_0_2_3) { + uc_pinCTS = pin; - return 1; + return 1; + } + + return 0; } -- GitLab