@@ -71,19 +71,26 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
71
71
uint8_t rx_pad = 255 ; // Unset pad
72
72
uint32_t tx_pinmux = 0 ;
73
73
uint8_t tx_pad = 255 ; // Unset pad
74
+ uint32_t rts_pinmux = 0 ;
75
+ uint32_t cts_pinmux = 0 ;
74
76
75
77
// Set state so the object is deinited to start.
76
78
self -> rx_pin = NO_PIN ;
77
79
self -> tx_pin = NO_PIN ;
80
+ self -> rts_pin = NO_PIN ;
81
+ self -> cts_pin = NO_PIN ;
78
82
79
- if ((rts != NULL ) || ( cts != NULL ) || ( rs485_dir != NULL ) || (rs485_invert )) {
83
+ if ((rs485_dir != NULL ) || (rs485_invert )) {
80
84
mp_raise_NotImplementedError (translate ("RS485" ));
81
85
}
82
86
83
87
mp_arg_validate_int_max (bits , 8 , MP_QSTR_bits );
84
88
85
89
bool have_tx = tx != NULL ;
86
90
bool have_rx = rx != NULL ;
91
+ bool have_rts = rts != NULL ;
92
+ bool have_cts = cts != NULL ;
93
+
87
94
if (!have_tx && !have_rx ) {
88
95
mp_raise_ValueError (translate ("tx and rx cannot both be None" ));
89
96
}
@@ -122,6 +129,9 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
122
129
#endif
123
130
tx_pinmux = PINMUX (tx -> number , (i == 0 ) ? MUX_C : MUX_D );
124
131
tx_pad = tx -> sercom [i ].pad ;
132
+ if (have_rts ) {
133
+ rts_pinmux = PINMUX (rts -> number , (i == 0 ) ? MUX_C : MUX_D );
134
+ }
125
135
if (rx == NULL ) {
126
136
sercom = potential_sercom ;
127
137
break ;
@@ -134,6 +144,9 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
134
144
rx -> sercom [j ].pad != tx_pad ) {
135
145
rx_pinmux = PINMUX (rx -> number , (j == 0 ) ? MUX_C : MUX_D );
136
146
rx_pad = rx -> sercom [j ].pad ;
147
+ if (have_cts ) {
148
+ cts_pinmux = PINMUX (cts -> number , (j == 0 ) ? MUX_C : MUX_D );
149
+ }
137
150
sercom = sercom_insts [rx -> sercom [j ].index ];
138
151
sercom_index = rx -> sercom [j ].index ;
139
152
break ;
@@ -190,24 +203,35 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
190
203
// which don't necessarily match what we need. After calling it, set the values
191
204
// specific to this instantiation of UART.
192
205
193
- // Set pads computed for this SERCOM.
206
+ // Set pads computed for this SERCOM. Refer to the datasheet for details on pads.
194
207
// TXPO:
195
208
// 0x0: TX pad 0; no RTS/CTS
196
- // 0x1: TX pad 2; no RTS/CTS
197
- // 0x2: TX pad 0; RTS: pad 2, CTS: pad 3 (not used by us right now)
198
- // So divide by 2 to map pad to value.
209
+ // 0x1: reserved
210
+ // 0x2: TX pad 0; RTS: pad 2, CTS: pad 3
211
+ // 0x3: TX pad 0; RTS: pad 2; no CTS
199
212
// RXPO:
200
213
// 0x0: RX pad 0
201
214
// 0x1: RX pad 1
202
215
// 0x2: RX pad 2
203
216
// 0x3: RX pad 3
204
217
218
+ // Default to TXPO with no RTS/CTS
219
+ uint8_t computed_txpo = 0 ;
220
+ // If we have both CTS (with or without RTS), use second pinout
221
+ if (have_cts ) {
222
+ computed_txpo = 2 ;
223
+ }
224
+ // If we have RTS only, use the third pinout
225
+ if (have_rts && !have_cts ) {
226
+ computed_txpo = 3 ;
227
+ }
228
+
205
229
// Doing a group mask and set of the registers saves 60 bytes over setting the bitfields individually.
206
230
207
231
sercom -> USART .CTRLA .reg &= ~(SERCOM_USART_CTRLA_TXPO_Msk |
208
232
SERCOM_USART_CTRLA_RXPO_Msk |
209
233
SERCOM_USART_CTRLA_FORM_Msk );
210
- sercom -> USART .CTRLA .reg |= SERCOM_USART_CTRLA_TXPO (tx_pad / 2 ) |
234
+ sercom -> USART .CTRLA .reg |= SERCOM_USART_CTRLA_TXPO (computed_txpo ) |
211
235
SERCOM_USART_CTRLA_RXPO (rx_pad ) |
212
236
(parity == BUSIO_UART_PARITY_NONE ? 0 : SERCOM_USART_CTRLA_FORM (1 ));
213
237
@@ -257,6 +281,26 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
257
281
self -> rx_pin = NO_PIN ;
258
282
}
259
283
284
+ if (have_rts ) {
285
+ gpio_set_pin_direction (rts -> number , GPIO_DIRECTION_OUT );
286
+ gpio_set_pin_pull_mode (rts -> number , GPIO_PULL_OFF );
287
+ gpio_set_pin_function (rts -> number , rts_pinmux );
288
+ self -> rts_pin = rts -> number ;
289
+ claim_pin (rts );
290
+ } else {
291
+ self -> rts_pin = NO_PIN ;
292
+ }
293
+
294
+ if (have_cts ) {
295
+ gpio_set_pin_direction (cts -> number , GPIO_DIRECTION_IN );
296
+ gpio_set_pin_pull_mode (cts -> number , GPIO_PULL_OFF );
297
+ gpio_set_pin_function (cts -> number , cts_pinmux );
298
+ self -> cts_pin = cts -> number ;
299
+ claim_pin (cts );
300
+ } else {
301
+ self -> cts_pin = NO_PIN ;
302
+ }
303
+
260
304
usart_async_enable (usart_desc_p );
261
305
}
262
306
@@ -270,6 +314,8 @@ void common_hal_busio_uart_never_reset(busio_uart_obj_t *self) {
270
314
never_reset_sercom (hw );
271
315
never_reset_pin_number (self -> rx_pin );
272
316
never_reset_pin_number (self -> tx_pin );
317
+ never_reset_pin_number (self -> rts_pin );
318
+ never_reset_pin_number (self -> cts_pin );
273
319
}
274
320
}
275
321
return ;
@@ -289,8 +335,12 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
289
335
usart_async_deinit (usart_desc_p );
290
336
reset_pin_number (self -> rx_pin );
291
337
reset_pin_number (self -> tx_pin );
338
+ reset_pin_number (self -> rts_pin );
339
+ reset_pin_number (self -> cts_pin );
292
340
self -> rx_pin = NO_PIN ;
293
341
self -> tx_pin = NO_PIN ;
342
+ self -> rts_pin = NO_PIN ;
343
+ self -> cts_pin = NO_PIN ;
294
344
}
295
345
296
346
// Read characters.
0 commit comments