20
20
#include " Arduino.h"
21
21
#include " wiring_private.h"
22
22
23
+ #define NO_RTS_PIN 255
24
+ #define NO_CTS_PIN 255
25
+ #define RTS_RX_THRESHOLD 10
26
+
23
27
Uart::Uart (SERCOM *_s, uint8_t _pinRX, uint8_t _pinTX, SercomRXPad _padRX, SercomUartTXPad _padTX)
24
28
{
25
29
sercom = _s;
26
30
uc_pinRX = _pinRX;
27
31
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;
30
36
}
31
37
32
38
void Uart::begin (unsigned long baudrate)
@@ -39,6 +45,15 @@ void Uart::begin(unsigned long baudrate, uint16_t config)
39
45
pinPeripheral (uc_pinRX, g_APinDescription[uc_pinRX].ulPinType );
40
46
pinPeripheral (uc_pinTX, g_APinDescription[uc_pinTX].ulPinType );
41
47
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
+
42
57
sercom->initUART (UART_INT_CLOCK, SAMPLE_RATE_x16, baudrate);
43
58
sercom->initFrame (extractCharSize (config), LSB_FIRST, extractParity (config), extractNbStopBit (config));
44
59
sercom->initPads (uc_padTX, uc_padRX);
@@ -48,6 +63,11 @@ void Uart::begin(unsigned long baudrate, uint16_t config)
48
63
49
64
void Uart::end ()
50
65
{
66
+ if (uc_pinRTS != NO_RTS_PIN) {
67
+ digitalWrite (uc_pinRTS, LOW);
68
+ pinMode (uc_pinRTS, INPUT);
69
+ }
70
+
51
71
sercom->resetUART ();
52
72
rxBuffer.clear ();
53
73
txBuffer.clear ();
@@ -64,6 +84,13 @@ void Uart::IrqHandler()
64
84
{
65
85
if (sercom->availableDataUART ()) {
66
86
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
+ }
67
94
}
68
95
69
96
if (sercom->isDataRegisterEmptyUART ()) {
@@ -102,11 +129,30 @@ int Uart::peek()
102
129
103
130
int Uart::read ()
104
131
{
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;
106
142
}
107
143
108
144
size_t Uart::write (const uint8_t data)
109
145
{
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
+
110
156
if (sercom->isDataRegisterEmptyUART () && txBuffer.available () == 0 ) {
111
157
sercom->writeDataUART (data);
112
158
} else {
@@ -168,3 +214,17 @@ SercomParityMode Uart::extractParity(uint16_t config)
168
214
return SERCOM_ODD_PARITY;
169
215
}
170
216
}
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