cancel
Showing results for 
Search instead for 
Did you mean: 

UART RX/TX inversion using UART_ADVFEATURE_SWAP_ENABLE doesn't work without UART_ADVFEATURE_TXINV_ENABLE

HRosz.2
Associate

Hello!

I'm working with a STM32 F777IIT6 (F7xx) MCU, and need to invert one of the UART RX/TX pins. Per the driver's instructions (stm32f7xx_hal_uart.h), I added statements to initialize the UART_HandleTypeDef structure's AdvancedInit with the UART_ADVFEATURE_SWAP_INIT and UART_ADVFEATURE_SWAP_ENABLE macros. See the code below:

void MX_UART5_ConfigurePins(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
 
    GPIO_InitStruct.Pin = U5_PROTO_USB_SYSTEM_TX_Pin|U5_PROTO_USB_SYSTEM_RX_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(U5_PROTO_USB_SYSTEM_RX_GPIO_Port, &GPIO_InitStruct);
}
 
void MX_UART5_Init(void)
{
    huart5.Instance = UART5;
 
    huart5.Init.BaudRate = 115200;
 
    huart5.Init.WordLength = UART_WORDLENGTH_8B;
    huart5.Init.StopBits = UART_STOPBITS_1;
    huart5.Init.Parity = UART_PARITY_NONE;
    huart5.Init.Mode = UART_MODE_TX_RX;
    huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart5.Init.OverSampling = UART_OVERSAMPLING_16;
    huart5.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    //huart5.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    huart5.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_SWAP_INIT | UART_ADVFEATURE_TXINVERT_INIT | UART_ADVFEATURE_RXINVERT_INIT | UART_ADVFEATURE_DATAINVERT_INIT;
    huart5.AdvancedInit.TxPinLevelInvert = UART_ADVFEATURE_TXINV_DISABLE;
    huart5.AdvancedInit.RxPinLevelInvert = UART_ADVFEATURE_RXINV_DISABLE;
    huart5.AdvancedInit.DataInvert = UART_ADVFEATURE_DATAINV_DISABLE;
    huart5.AdvancedInit.Swap = UART_ADVFEATURE_SWAP_ENABLE;
 
    if (HAL_UART_Init(&huart5) != HAL_OK)
    {
    Error_Handler();
    }
}

In a testing environment with manually swapped wires, and without the UART_ADVFEATURE_SWAP_ENABLE macro, we are able to communicate with the device. However, with our production setup we cannot manually swap wires and must use UART_ADVFEATURE_SWAP_ENABLE. With this flag enabled, we observe with a digital oscilloscope that all communication stops working. IE, no data is transmitted on the swapped TX pin or on the original TX pin. However, we did notice that if we use the UART_ADVFEATURE_TXINV_ENABLE macro, the MCU does transmit data on the swapped TX pin. The problem with this is that the node we're communicating with requires un-inverted UART.

Is there a pre-requisite to using UART_ADVFEATURE_SWAP_ENABLE?

Thanks,

Hayden

1 REPLY 1
gbm
Lead III

Use the debugger to check the values of control register - this way you will see if it's a problem with HAL (as usual), or with the chip's UART module undocumented behavior.

Also, check if the UART you use supports the feature. Some UARTs are more equal than the others. 😉

Just think, you could initialize all these features of UART without HAL in just 3-4 llines of simple C code. 😉