Skip to content

Commit

Permalink
feat(uart): support UART Tx Rx pin swap function
Browse files Browse the repository at this point in the history
Resolves: stm32duino#2538
  • Loading branch information
fronders committed Nov 5, 2024
1 parent 511ed73 commit 8653cdc
Showing 1 changed file with 43 additions and 12 deletions.
55 changes: 43 additions & 12 deletions libraries/SrcWrapper/src/stm32/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,25 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
USART_TypeDef *uart_rx = pinmap_peripheral(obj->pin_rx, PinMap_UART_RX);
USART_TypeDef *uart_rts = pinmap_peripheral(obj->pin_rts, PinMap_UART_RTS);
USART_TypeDef *uart_cts = pinmap_peripheral(obj->pin_cts, PinMap_UART_CTS);
/* Check if pins are swapped */
#if defined(UART_ADVFEATURE_SWAP_INIT)
USART_TypeDef *uart_tx_swap = pinmap_peripheral(obj->pin_tx, PinMap_UART_RX);
USART_TypeDef *uart_rx_swap = pinmap_peripheral(obj->pin_rx, PinMap_UART_TX);
#else
/* Pin swap not supported */
USART_TypeDef *uart_tx_swap = NP;
USART_TypeDef *uart_rx_swap = NP;
#endif

/* Pin Tx must not be NP */
if (uart_tx == NP) {
if ((uart_tx == NP) && (uart_tx_swap == NP)) {
if (obj != &serial_debug) {
core_debug("ERROR: [U(S)ART] Tx pin has no peripheral!\n");
}
return;
}
/* Pin Rx must not be NP if not half-duplex */
if ((obj->pin_rx != NC) && (uart_rx == NP)) {
if ((obj->pin_rx != NC) && (uart_rx == NP) && (uart_rx_swap == NP)) {
if (obj != &serial_debug) {
core_debug("ERROR: [U(S)ART] Rx pin has no peripheral!\n");
}
Expand All @@ -156,6 +165,10 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
* and assign it to the object
*/
obj->uart = pinmap_merge_peripheral(uart_tx, uart_rx);
if (obj->uart == NP) {
/* Regular pins not matched, check if they can be swapped */
obj->uart = pinmap_merge_peripheral(uart_tx_swap, uart_rx_swap);
}
/* We also merge RTS/CTS and assert all pins belong to the same instance */
obj->uart = pinmap_merge_peripheral(obj->uart, uart_rts);
obj->uart = pinmap_merge_peripheral(obj->uart, uart_cts);
Expand Down Expand Up @@ -328,10 +341,26 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
#endif

/* Configure UART GPIO pins */
pinmap_pinout(obj->pin_tx, PinMap_UART_TX);
if (uart_rx != NP) {
pinmap_pinout(obj->pin_rx, PinMap_UART_RX);
#if defined(UART_ADVFEATURE_SWAP_INIT)
uint32_t pin_swap = UART_ADVFEATURE_SWAP_DISABLE;
#endif
if (uart_tx != NP) {
/* Regular GPIO */
pinmap_pinout(obj->pin_tx, PinMap_UART_TX);
if (uart_rx != NP) {
pinmap_pinout(obj->pin_rx, PinMap_UART_RX);
}
}
#if defined(UART_ADVFEATURE_SWAP_INIT)
else if (uart_tx_swap != NP) {
/* Swapped GPIO */
pinmap_pinout(obj->pin_tx, PinMap_UART_RX);
if (uart_rx_swap != NP) {
pinmap_pinout(obj->pin_rx, PinMap_UART_TX);
}
pin_swap = UART_ADVFEATURE_SWAP_ENABLE;
}
#endif

/* Configure flow control */
uint32_t flow_control = UART_HWCONTROL_NONE;
Expand All @@ -354,8 +383,10 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
huart->Init.Mode = UART_MODE_TX_RX;
huart->Init.HwFlowCtl = flow_control;
huart->Init.OverSampling = UART_OVERSAMPLING_16;
#if !defined(STM32F1xx) && !defined(STM32F2xx) && !defined(STM32F4xx)\
&& !defined(STM32L1xx)
#if defined(UART_ADVFEATURE_SWAP_INIT)
huart->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_SWAP_INIT;
huart->AdvancedInit.Swap = pin_swap;
#elif defined(UART_ADVFEATURE_NO_INIT)
huart->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
#endif
#ifdef UART_ONE_BIT_SAMPLE_DISABLE
Expand Down Expand Up @@ -391,7 +422,7 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
HAL_UARTEx_DisableStopMode(huart);
}
/* Trying default LPUART clock source */
if (uart_rx == NP) {
if ((uart_rx == NP) && (uart_rx_swap == NP)) {
if (HAL_HalfDuplex_Init(huart) == HAL_OK) {
return;
}
Expand All @@ -416,7 +447,7 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
__HAL_RCC_LPUART3_CONFIG(RCC_LPUART3CLKSOURCE_LSE);
}
#endif
if (uart_rx == NP) {
if ((uart_rx == NP) && (uart_rx_swap == NP)) {
if (HAL_HalfDuplex_Init(huart) == HAL_OK) {
return;
}
Expand All @@ -438,7 +469,7 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
__HAL_RCC_LPUART3_CONFIG(RCC_LPUART3CLKSOURCE_HSI);
}
#endif
if (uart_rx == NP) {
if ((uart_rx == NP) && (uart_rx_swap == NP)) {
if (HAL_HalfDuplex_Init(huart) == HAL_OK) {
return;
}
Expand All @@ -465,7 +496,7 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
__HAL_RCC_LPUART3_CONFIG(RCC_LPUART3CLKSOURCE_PCLK1);
}
#endif
if (uart_rx == NP) {
if ((uart_rx == NP) && (uart_rx_swap == NP)) {
if (HAL_HalfDuplex_Init(huart) == HAL_OK) {
return;
}
Expand All @@ -490,7 +521,7 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
}
#endif

if (uart_rx == NP) {
if ((uart_rx == NP) && (uart_rx_swap == NP)) {
if (HAL_HalfDuplex_Init(huart) != HAL_OK) {
return;
}
Expand Down

0 comments on commit 8653cdc

Please sign in to comment.