Skip to content

Commit 4ef67d3

Browse files
committed
stmhal: Implement support for RTS/CTS hardware flow control in UART.
This is experimental support. API is subject to changes. RTS/CTS available on UART(2) and UART(3) only. Use as: uart = pyb.UART(2, 9600, flow=pyb.UART.RTS | pyb.UART.CTS)
1 parent 9a41b32 commit 4ef67d3

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

stmhal/qstrdefsport.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ Q(baudrate)
144144
Q(bits)
145145
Q(stop)
146146
Q(parity)
147+
Q(flow)
147148
Q(read_buf_len)
148149
Q(buf)
149150
Q(len)
@@ -155,6 +156,8 @@ Q(any)
155156
Q(writechar)
156157
Q(readchar)
157158
Q(readinto)
159+
Q(RTS)
160+
Q(CTS)
158161

159162
// for CAN class
160163
Q(CAN)

stmhal/uart.c

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ void uart_deinit(void) {
115115
}
116116

117117
// assumes Init parameters have been set up correctly
118-
bool uart_init2(pyb_uart_obj_t *uart_obj) {
118+
STATIC bool uart_init2(pyb_uart_obj_t *uart_obj) {
119119
USART_TypeDef *UARTx;
120120
IRQn_Type irqn;
121121
uint32_t GPIO_Pin;
@@ -140,7 +140,7 @@ bool uart_init2(pyb_uart_obj_t *uart_obj) {
140140
__USART1_CLK_ENABLE();
141141
break;
142142

143-
// USART2 is on PA2/PA3 (CK on PA4), PD5/PD6 (CK on PD7)
143+
// USART2 is on PA2/PA3 (CTS,RTS,CK on PA0,PA1,PA4), PD5/PD6 (CK on PD7)
144144
case PYB_UART_2:
145145
UARTx = USART2;
146146
irqn = USART2_IRQn;
@@ -149,10 +149,17 @@ bool uart_init2(pyb_uart_obj_t *uart_obj) {
149149
GPIO_Port = GPIOA;
150150
GPIO_Pin = GPIO_PIN_2 | GPIO_PIN_3;
151151

152+
if (uart_obj->uart.Init.HwFlowCtl & UART_HWCONTROL_RTS) {
153+
GPIO_Pin |= GPIO_PIN_1;
154+
}
155+
if (uart_obj->uart.Init.HwFlowCtl & UART_HWCONTROL_CTS) {
156+
GPIO_Pin |= GPIO_PIN_0;
157+
}
158+
152159
__USART2_CLK_ENABLE();
153160
break;
154161

155-
// USART3 is on PB10/PB11 (CK on PB12), PC10/PC11 (CK on PC12), PD8/PD9 (CK on PD10)
162+
// USART3 is on PB10/PB11 (CK,CTS,RTS on PB12,PB13,PB14), PC10/PC11 (CK on PC12), PD8/PD9 (CK on PD10)
156163
case PYB_UART_3:
157164
UARTx = USART3;
158165
irqn = USART3_IRQn;
@@ -161,6 +168,13 @@ bool uart_init2(pyb_uart_obj_t *uart_obj) {
161168
#if defined(PYBV3) || defined(PYBV4) | defined(PYBV10)
162169
GPIO_Port = GPIOB;
163170
GPIO_Pin = GPIO_PIN_10 | GPIO_PIN_11;
171+
172+
if (uart_obj->uart.Init.HwFlowCtl & UART_HWCONTROL_RTS) {
173+
GPIO_Pin |= GPIO_PIN_14;
174+
}
175+
if (uart_obj->uart.Init.HwFlowCtl & UART_HWCONTROL_CTS) {
176+
GPIO_Pin |= GPIO_PIN_13;
177+
}
164178
#else
165179
GPIO_Port = GPIOD;
166180
GPIO_Pin = GPIO_PIN_8 | GPIO_PIN_9;
@@ -357,6 +371,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
357371
{ MP_QSTR_bits, MP_ARG_INT, {.u_int = 8} },
358372
{ MP_QSTR_parity, MP_ARG_OBJ, {.u_obj = mp_const_none} },
359373
{ MP_QSTR_stop, MP_ARG_INT, {.u_int = 1} },
374+
{ MP_QSTR_flow, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = UART_HWCONTROL_NONE} },
360375
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1000} },
361376
{ MP_QSTR_timeout_char, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
362377
{ MP_QSTR_read_buf_len, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} },
@@ -382,7 +397,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
382397
default: init->StopBits = UART_STOPBITS_2; break;
383398
}
384399
init->Mode = UART_MODE_TX_RX;
385-
init->HwFlowCtl = UART_HWCONTROL_NONE;
400+
init->HwFlowCtl = args[4].u_int;
386401
init->OverSampling = UART_OVERSAMPLING_16;
387402

388403
// init UART (if it fails, it's because the port doesn't exist)
@@ -391,8 +406,8 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
391406
}
392407

393408
// set timeouts
394-
self->timeout = args[4].u_int;
395-
self->timeout_char = args[5].u_int;
409+
self->timeout = args[5].u_int;
410+
self->timeout_char = args[6].u_int;
396411

397412
// setup the read buffer
398413
m_del(byte, self->read_buf, self->read_buf_len << self->char_width);
@@ -403,16 +418,16 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
403418
}
404419
self->read_buf_head = 0;
405420
self->read_buf_tail = 0;
406-
if (args[6].u_int <= 0) {
421+
if (args[7].u_int <= 0) {
407422
// no read buffer
408423
self->read_buf_len = 0;
409424
self->read_buf = NULL;
410425
HAL_NVIC_DisableIRQ(self->irqn);
411426
__HAL_UART_DISABLE_IT(&self->uart, UART_IT_RXNE);
412427
} else {
413428
// read buffer using interrupts
414-
self->read_buf_len = args[6].u_int;
415-
self->read_buf = m_new(byte, args[6].u_int << self->char_width);
429+
self->read_buf_len = args[7].u_int;
430+
self->read_buf = m_new(byte, args[7].u_int << self->char_width);
416431
__HAL_UART_ENABLE_IT(&self->uart, UART_IT_RXNE);
417432
HAL_NVIC_SetPriority(self->irqn, 0xd, 0xd); // next-to-next-to lowest priority
418433
HAL_NVIC_EnableIRQ(self->irqn);
@@ -595,6 +610,10 @@ STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = {
595610

596611
{ MP_OBJ_NEW_QSTR(MP_QSTR_writechar), (mp_obj_t)&pyb_uart_writechar_obj },
597612
{ MP_OBJ_NEW_QSTR(MP_QSTR_readchar), (mp_obj_t)&pyb_uart_readchar_obj },
613+
614+
// class constants
615+
{ MP_OBJ_NEW_QSTR(MP_QSTR_RTS), MP_OBJ_NEW_SMALL_INT(UART_HWCONTROL_RTS) },
616+
{ MP_OBJ_NEW_QSTR(MP_QSTR_CTS), MP_OBJ_NEW_SMALL_INT(UART_HWCONTROL_CTS) },
598617
};
599618

600619
STATIC MP_DEFINE_CONST_DICT(pyb_uart_locals_dict, pyb_uart_locals_dict_table);

0 commit comments

Comments
 (0)