Skip to content

Commit bd1bd60

Browse files
sandeepmistrycmaglie
authored andcommitted
Add optional RTS + CTS support to UART
1 parent e6df241 commit bd1bd60

File tree

2 files changed

+68
-3
lines changed

2 files changed

+68
-3
lines changed

cores/arduino/Uart.cpp

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,19 @@
2020
#include "Arduino.h"
2121
#include "wiring_private.h"
2222

23+
#define NO_RTS_PIN 255
24+
#define NO_CTS_PIN 255
25+
#define RTS_RX_THRESHOLD 10
26+
2327
Uart::Uart(SERCOM *_s, uint8_t _pinRX, uint8_t _pinTX, SercomRXPad _padRX, SercomUartTXPad _padTX)
2428
{
2529
sercom = _s;
2630
uc_pinRX = _pinRX;
2731
uc_pinTX = _pinTX;
28-
uc_padRX=_padRX ;
29-
uc_padTX=_padTX;
32+
uc_padRX = _padRX ;
33+
uc_padTX = _padTX;
34+
uc_pinRTS = NO_RTS_PIN;
35+
uc_pinCTS = NO_CTS_PIN;
3036
}
3137

3238
void Uart::begin(unsigned long baudrate)
@@ -39,6 +45,15 @@ void Uart::begin(unsigned long baudrate, uint16_t config)
3945
pinPeripheral(uc_pinRX, g_APinDescription[uc_pinRX].ulPinType);
4046
pinPeripheral(uc_pinTX, g_APinDescription[uc_pinTX].ulPinType);
4147

48+
if (uc_pinRTS != NO_RTS_PIN) {
49+
pinMode(uc_pinRTS, OUTPUT);
50+
digitalWrite(uc_pinRTS, LOW);
51+
}
52+
53+
if (uc_pinCTS != NO_CTS_PIN) {
54+
pinMode(uc_pinCTS, INPUT);
55+
}
56+
4257
sercom->initUART(UART_INT_CLOCK, SAMPLE_RATE_x16, baudrate);
4358
sercom->initFrame(extractCharSize(config), LSB_FIRST, extractParity(config), extractNbStopBit(config));
4459
sercom->initPads(uc_padTX, uc_padRX);
@@ -48,6 +63,11 @@ void Uart::begin(unsigned long baudrate, uint16_t config)
4863

4964
void Uart::end()
5065
{
66+
if (uc_pinRTS != NO_RTS_PIN) {
67+
digitalWrite(uc_pinRTS, LOW);
68+
pinMode(uc_pinRTS, INPUT);
69+
}
70+
5171
sercom->resetUART();
5272
rxBuffer.clear();
5373
txBuffer.clear();
@@ -64,6 +84,13 @@ void Uart::IrqHandler()
6484
{
6585
if (sercom->availableDataUART()) {
6686
rxBuffer.store_char(sercom->readDataUART());
87+
88+
if (uc_pinRTS != NO_RTS_PIN) {
89+
// if there is NOT enough space in the RX buffer, de-assert RTS
90+
if (rxBuffer.availableForStore() < RTS_RX_THRESHOLD) {
91+
digitalWrite(uc_pinRTS, HIGH);
92+
}
93+
}
6794
}
6895

6996
if (sercom->isDataRegisterEmptyUART()) {
@@ -102,11 +129,30 @@ int Uart::peek()
102129

103130
int Uart::read()
104131
{
105-
return rxBuffer.read_char();
132+
int c = rxBuffer.read_char();
133+
134+
if (uc_pinRTS != NO_RTS_PIN) {
135+
// if there is enough space in the RX buffer, assert RTS
136+
if (rxBuffer.availableForStore() > RTS_RX_THRESHOLD) {
137+
digitalWrite(uc_pinRTS, LOW);
138+
}
139+
}
140+
141+
return c;
106142
}
107143

108144
size_t Uart::write(const uint8_t data)
109145
{
146+
if (uc_pinRTS != NO_RTS_PIN) {
147+
// assert RTS
148+
digitalWrite(uc_pinRTS, LOW);
149+
}
150+
151+
if (uc_pinCTS != NO_CTS_PIN) {
152+
// wait until CTS is asserted
153+
while (digitalRead(uc_pinCTS) != LOW);
154+
}
155+
110156
if (sercom->isDataRegisterEmptyUART() && txBuffer.available() == 0) {
111157
sercom->writeDataUART(data);
112158
} else {
@@ -168,3 +214,17 @@ SercomParityMode Uart::extractParity(uint16_t config)
168214
return SERCOM_ODD_PARITY;
169215
}
170216
}
217+
218+
int Uart::attachRts(uint8_t pin)
219+
{
220+
uc_pinRTS = pin;
221+
222+
return 1;
223+
}
224+
225+
int Uart::attachCts(uint8_t pin)
226+
{
227+
uc_pinCTS = pin;
228+
229+
return 1;
230+
}

cores/arduino/Uart.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ class Uart : public HardwareSerial
4343

4444
operator bool() { return true; }
4545

46+
int attachRts(uint8_t pin);
47+
int attachCts(uint8_t pin);
48+
4649
private:
4750
SERCOM *sercom;
4851
RingBuffer rxBuffer;
@@ -52,6 +55,8 @@ class Uart : public HardwareSerial
5255
uint8_t uc_pinTX;
5356
SercomRXPad uc_padRX;
5457
SercomUartTXPad uc_padTX;
58+
uint8_t uc_pinRTS;
59+
uint8_t uc_pinCTS;
5560

5661
SercomNumberStopBit extractNbStopBit(uint16_t config);
5762
SercomUartCharSize extractCharSize(uint16_t config);

0 commit comments

Comments
 (0)