diff --git a/src/main/drivers/serial_uart_hal.c b/src/main/drivers/serial_uart_hal.c index 3e640c11b89..4800f2a33dc 100644 --- a/src/main/drivers/serial_uart_hal.c +++ b/src/main/drivers/serial_uart_hal.c @@ -64,6 +64,34 @@ static void usartConfigurePinInversion(uartPort_t *uartPort) { } } +static uartDevice_t *uartFindDevice(uartPort_t *uartPort) +{ + for (uint32_t i = 0; i < UARTDEV_COUNT_MAX; i++) { + uartDevice_t *candidate = uartDevmap[i]; + + if (&candidate->port == uartPort) { + return candidate; + } + } + return NULL; +} + +static void uartConfigurePinSwap(uartPort_t *uartPort) +{ +#if (defined(STM32F1) || defined(STM32F4)) + // Older CPUs don't support pin swap. + UNUSED(uartPart); +#else + uartDevice_t *uartDevice = uartFindDevice(uartPort); + if (!uartDevice) return NULL; + + if (uartDevice->pinSwap) { + uartDevice->port.Handle.AdvancedInit.AdvFeatureInit |= UART_ADVFEATURE_SWAP_INIT; + uartDevice->port.Handle.AdvancedInit.Swap = UART_ADVFEATURE_SWAP_ENABLE; + } +#endif +} + // XXX uartReconfigure does not handle resource management properly. void uartReconfigure(uartPort_t *uartPort) @@ -91,6 +119,7 @@ void uartReconfigure(uartPort_t *uartPort) usartConfigurePinInversion(uartPort); + uartConfigurePinSwap(uartPort); #ifdef TARGET_USART_CONFIG void usartTargetConfigure(uartPort_t *); diff --git a/src/main/drivers/serial_uart_impl.h b/src/main/drivers/serial_uart_impl.h index 1f26e5e8b88..da12bb47145 100644 --- a/src/main/drivers/serial_uart_impl.h +++ b/src/main/drivers/serial_uart_impl.h @@ -222,6 +222,9 @@ typedef struct uartDevice_s { uartPinDef_t tx; volatile uint8_t *rxBuffer; volatile uint8_t *txBuffer; +#if !(defined(STM32F1) || defined(STM32F4)) // Older CPUs don't support pin swap. + bool pinSwap; +#endif } uartDevice_t; extern uartDevice_t *uartDevmap[]; diff --git a/src/main/drivers/serial_uart_pinconfig.c b/src/main/drivers/serial_uart_pinconfig.c index ffa0999583b..4ddc39bc35c 100644 --- a/src/main/drivers/serial_uart_pinconfig.c +++ b/src/main/drivers/serial_uart_pinconfig.c @@ -53,14 +53,31 @@ void uartPinConfigure(const serialPinConfig_t *pSerialPinConfig) const uartHardware_t *hardware = &uartHardware[hindex]; const UARTDevice_e device = hardware->device; +#if !(defined(STM32F1) || defined(STM32F4)) // Older CPUs don't support pin swap. + uartdev->pinSwap = false; +#endif for (int pindex = 0 ; pindex < UARTHARDWARE_MAX_PINS ; pindex++) { - if (hardware->rxPins[pindex].pin == pSerialPinConfig->ioTagRx[device]) { + if (pSerialPinConfig->ioTagRx[device] == hardware->rxPins[pindex].pin) { uartdev->rx = hardware->rxPins[pindex]; } - if (hardware->txPins[pindex].pin == pSerialPinConfig->ioTagTx[device]) { + if (pSerialPinConfig->ioTagTx[device] == hardware->txPins[pindex].pin) { uartdev->tx = hardware->txPins[pindex]; } + + +#if !(defined(STM32F1) || defined(STM32F4)) + // Check for swapped pins + if (pSerialPinConfig->ioTagTx[device] == hardware->rxPins[pindex].pin) { + uartdev->tx = hardware->rxPins[pindex]; + uartdev->pinSwap = true; + } + + if (pSerialPinConfig->ioTagRx[device] == hardware->txPins[pindex].pin) { + uartdev->rx = hardware->txPins[pindex]; + uartdev->pinSwap = true; + } +#endif } if (uartdev->rx.pin || uartdev->tx.pin) {