Skip to content

Commit b97879c

Browse files
committed
feat(uart): support UART Tx Rx pin swap function
Resolves: stm32duino#2538 (cherry-picked from 8653cdc)
1 parent 8a0b65e commit b97879c

File tree

1 file changed

+43
-12
lines changed
  • libraries/SrcWrapper/src/stm32

1 file changed

+43
-12
lines changed

libraries/SrcWrapper/src/stm32/uart.c

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -118,16 +118,25 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
118118
USART_TypeDef *uart_rx = pinmap_peripheral(obj->pin_rx, PinMap_UART_RX);
119119
USART_TypeDef *uart_rts = pinmap_peripheral(obj->pin_rts, PinMap_UART_RTS);
120120
USART_TypeDef *uart_cts = pinmap_peripheral(obj->pin_cts, PinMap_UART_CTS);
121+
/* Check if pins are swapped */
122+
#if defined(UART_ADVFEATURE_SWAP_INIT)
123+
USART_TypeDef *uart_tx_swap = pinmap_peripheral(obj->pin_tx, PinMap_UART_RX);
124+
USART_TypeDef *uart_rx_swap = pinmap_peripheral(obj->pin_rx, PinMap_UART_TX);
125+
#else
126+
/* Pin swap not supported */
127+
USART_TypeDef *uart_tx_swap = NP;
128+
USART_TypeDef *uart_rx_swap = NP;
129+
#endif
121130

122131
/* Pin Tx must not be NP */
123-
if (uart_tx == NP) {
132+
if ((uart_tx == NP) && (uart_tx_swap == NP)) {
124133
if (obj != &serial_debug) {
125134
core_debug("ERROR: [U(S)ART] Tx pin has no peripheral!\n");
126135
}
127136
return;
128137
}
129138
/* Pin Rx must not be NP if not half-duplex */
130-
if ((obj->pin_rx != NC) && (uart_rx == NP)) {
139+
if ((obj->pin_rx != NC) && (uart_rx == NP) && (uart_rx_swap == NP)) {
131140
if (obj != &serial_debug) {
132141
core_debug("ERROR: [U(S)ART] Rx pin has no peripheral!\n");
133142
}
@@ -153,6 +162,10 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
153162
* and assign it to the object
154163
*/
155164
obj->uart = pinmap_merge_peripheral(uart_tx, uart_rx);
165+
if (obj->uart == NP) {
166+
/* Regular pins not matched, check if they can be swapped */
167+
obj->uart = pinmap_merge_peripheral(uart_tx_swap, uart_rx_swap);
168+
}
156169
/* We also merge RTS/CTS and assert all pins belong to the same instance */
157170
obj->uart = pinmap_merge_peripheral(obj->uart, uart_rts);
158171
obj->uart = pinmap_merge_peripheral(obj->uart, uart_cts);
@@ -316,10 +329,26 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
316329
#endif
317330

318331
/* Configure UART GPIO pins */
319-
pinmap_pinout(obj->pin_tx, PinMap_UART_TX);
320-
if (uart_rx != NP) {
321-
pinmap_pinout(obj->pin_rx, PinMap_UART_RX);
332+
#if defined(UART_ADVFEATURE_SWAP_INIT)
333+
uint32_t pin_swap = UART_ADVFEATURE_SWAP_DISABLE;
334+
#endif
335+
if (uart_tx != NP) {
336+
/* Regular GPIO */
337+
pinmap_pinout(obj->pin_tx, PinMap_UART_TX);
338+
if (uart_rx != NP) {
339+
pinmap_pinout(obj->pin_rx, PinMap_UART_RX);
340+
}
341+
}
342+
#if defined(UART_ADVFEATURE_SWAP_INIT)
343+
else if (uart_tx_swap != NP) {
344+
/* Swapped GPIO */
345+
pinmap_pinout(obj->pin_tx, PinMap_UART_RX);
346+
if (uart_rx_swap != NP) {
347+
pinmap_pinout(obj->pin_rx, PinMap_UART_TX);
348+
}
349+
pin_swap = UART_ADVFEATURE_SWAP_ENABLE;
322350
}
351+
#endif
323352

324353
/* Configure flow control */
325354
uint32_t flow_control = UART_HWCONTROL_NONE;
@@ -342,8 +371,10 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
342371
huart->Init.Mode = UART_MODE_TX_RX;
343372
huart->Init.HwFlowCtl = flow_control;
344373
huart->Init.OverSampling = UART_OVERSAMPLING_16;
345-
#if !defined(STM32F1xx) && !defined(STM32F2xx) && !defined(STM32F4xx)\
346-
&& !defined(STM32L1xx)
374+
#if defined(UART_ADVFEATURE_SWAP_INIT)
375+
huart->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_SWAP_INIT;
376+
huart->AdvancedInit.Swap = pin_swap;
377+
#elif defined(UART_ADVFEATURE_NO_INIT)
347378
huart->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
348379
#endif
349380
#ifdef UART_ONE_BIT_SAMPLE_DISABLE
@@ -376,7 +407,7 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
376407
HAL_UARTEx_DisableStopMode(huart);
377408
}
378409
/* Trying default LPUART clock source */
379-
if (uart_rx == NP) {
410+
if ((uart_rx == NP) && (uart_rx_swap == NP)) {
380411
if (HAL_HalfDuplex_Init(huart) == HAL_OK) {
381412
return;
382413
}
@@ -396,7 +427,7 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
396427
__HAL_RCC_LPUART2_CONFIG(RCC_LPUART2CLKSOURCE_LSE);
397428
}
398429
#endif
399-
if (uart_rx == NP) {
430+
if ((uart_rx == NP) && (uart_rx_swap == NP)) {
400431
if (HAL_HalfDuplex_Init(huart) == HAL_OK) {
401432
return;
402433
}
@@ -413,7 +444,7 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
413444
__HAL_RCC_LPUART2_CONFIG(RCC_LPUART2CLKSOURCE_HSI);
414445
}
415446
#endif
416-
if (uart_rx == NP) {
447+
if ((uart_rx == NP) && (uart_rx_swap == NP)) {
417448
if (HAL_HalfDuplex_Init(huart) == HAL_OK) {
418449
return;
419450
}
@@ -435,7 +466,7 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
435466
__HAL_RCC_LPUART2_CONFIG(RCC_LPUART2CLKSOURCE_PCLK1);
436467
}
437468
#endif
438-
if (uart_rx == NP) {
469+
if ((uart_rx == NP) && (uart_rx_swap == NP)) {
439470
if (HAL_HalfDuplex_Init(huart) == HAL_OK) {
440471
return;
441472
}
@@ -455,7 +486,7 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
455486
}
456487
#endif
457488

458-
if (uart_rx == NP) {
489+
if ((uart_rx == NP) && (uart_rx_swap == NP)) {
459490
if (HAL_HalfDuplex_Init(huart) != HAL_OK) {
460491
return;
461492
}

0 commit comments

Comments
 (0)