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+
2327Uart::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
3238void 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
4964void 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
103130int 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
108144size_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+ }
0 commit comments