Skip to main content
Graduate
July 17, 2024
Solved

STM32F103C8T6 does not transmit or receive on UART2 in half duplex

  • July 17, 2024
  • 2 replies
  • 3621 views

We are using two STM32 platforms, one is running STM32H735RGV6 and the other is running STM32F103C8T6, they are connected by a single wire and connecting as UART Half Duplex.

Note that we did make it work in a UART in full duplex mode for STM32F103C8T6 previously without any problem using another platform. 

The STM32H735RGV6 is transmitting messages as expected, we do not know it by seeing bytes using a logic analyzer, and we do not know if it can receive yet, and it is configured as this:

 

=======

 huart7.Instance = UART7;
 huart7.Init.BaudRate = 19200;
 huart7.Init.WordLength = UART_WORDLENGTH_8B;
 huart7.Init.StopBits = UART_STOPBITS_1;
 huart7.Init.Parity = UART_PARITY_NONE;
 huart7.Init.Mode = UART_MODE_TX_RX;
 huart7.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart7.Init.OverSampling = UART_OVERSAMPLING_16;
 huart7.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 huart7.Init.ClockPrescaler = UART_PRESCALER_DIV1;
 huart7.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 if (HAL_HalfDuplex_Init(&huart7) != HAL_OK)
 {
 error_handler();
 }
 if (HAL_UARTEx_SetTxFifoThreshold(&huart7, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
 {
 error_handler();
 }
 if (HAL_UARTEx_SetRxFifoThreshold(&huart7, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
 {
 error_handler();
 }
 if (HAL_UARTEx_DisableFifoMode(&huart7) != HAL_OK)
 {
 error_handler();
 }
 if (HAL_HalfDuplex_EnableReceiver(&huart7) != HAL_OK)
 {
 error_handler();
 }

=======

if(huart->Instance==UART7)
 {
 /* USER CODE BEGIN UART7_MspInit 0 */

 /* USER CODE END UART7_MspInit 0 */

 /** Initializes the peripherals clock
 */
 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_UART7;
 PeriphClkInitStruct.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1;
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
 {
 error_handler();
 }

 /* Peripheral clock enable */
 __HAL_RCC_UART7_CLK_ENABLE();

 __HAL_RCC_GPIOA_CLK_ENABLE();
 /**UART7 GPIO Configuration
 PA15(JTDI) ------> UART7_TX
 */
 GPIO_InitStruct.Pin = UART7_HD_TO_FOX_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF11_UART7;
 HAL_GPIO_Init(UART7_HD_TO_FOX_GPIO_Port, &GPIO_InitStruct);

 /* UART7 DMA Init */
 /* UART7_RX Init */
 hdma_uart7_rx.Instance = DMA1_Stream7;
 hdma_uart7_rx.Init.Request = DMA_REQUEST_UART7_RX;
 hdma_uart7_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
 hdma_uart7_rx.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma_uart7_rx.Init.MemInc = DMA_MINC_ENABLE;
 hdma_uart7_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 hdma_uart7_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 hdma_uart7_rx.Init.Mode = DMA_NORMAL;
 hdma_uart7_rx.Init.Priority = DMA_PRIORITY_LOW;
 hdma_uart7_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
 if (HAL_DMA_Init(&hdma_uart7_rx) != HAL_OK)
 {
 error_handler();
 }

 __HAL_LINKDMA(huart,hdmarx,hdma_uart7_rx);

 /* UART7_TX Init */
 hdma_uart7_tx.Instance = DMA2_Stream0;
 hdma_uart7_tx.Init.Request = DMA_REQUEST_UART7_TX;
 hdma_uart7_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
 hdma_uart7_tx.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma_uart7_tx.Init.MemInc = DMA_MINC_ENABLE;
 hdma_uart7_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 hdma_uart7_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 hdma_uart7_tx.Init.Mode = DMA_NORMAL;
 hdma_uart7_tx.Init.Priority = DMA_PRIORITY_LOW;
 hdma_uart7_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
 if (HAL_DMA_Init(&hdma_uart7_tx) != HAL_OK)
 {
 error_handler();
 }

 __HAL_LINKDMA(huart,hdmatx,hdma_uart7_tx);

 /* UART7 interrupt Init */
 HAL_NVIC_SetPriority(UART7_IRQn, 5, 0);
 HAL_NVIC_EnableIRQ(UART7_IRQn);
 /* USER CODE BEGIN UART7_MspInit 1 */

 /* USER CODE END UART7_MspInit 1 */
 }

=======

Sending like this:

 if (HAL_HalfDuplex_EnableTransmitter(&huart7) != HAL_OK)
 {
 error_handler();
 }
 HAL_StatusTypeDef ret = HAL_UART_Transmit_DMA(&huart7, pData, size);

 

 

The STM32F103C8T6 is not receiving or transmitting messages, we tried a few variation of the configuration, but we cannot get it to work and only getting into worst condition. So, here is the best configuration according to us:

 

 

 huart2.Instance = USART2;
 huart2.Init.BaudRate = 19200;
 huart2.Init.WordLength = UART_WORDLENGTH_8B;
 huart2.Init.StopBits = UART_STOPBITS_1;
 huart2.Init.Parity = UART_PARITY_NONE;
 huart2.Init.Mode = UART_MODE_TX_RX;
 huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart2.Init.OverSampling = UART_OVERSAMPLING_16;
 if (HAL_HalfDuplex_Init(&huart2) != HAL_OK)
 {
 error_handler();
 }
 if (HAL_HalfDuplex_EnableReceiver(&huart2) != HAL_OK)
 {
 error_handler();
 }

=======

 if(uartHandle->Instance==USART2)
 {
 /* USER CODE BEGIN USART2_MspInit 0 */

 /* USER CODE END USART2_MspInit 0 */
 /* USART2 clock enable */
 __HAL_RCC_USART2_CLK_ENABLE();

 __HAL_RCC_GPIOA_CLK_ENABLE();
 /**USART2 GPIO Configuration
 PA2 ------> USART2_TX
 PA3 ------> USART2_RX
 */
 GPIO_InitStruct.Pin = USART2_HF_TO_PA_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 HAL_GPIO_Init(USART2_HF_TO_PA_GPIO_Port, &GPIO_InitStruct);

 GPIO_InitStruct.Pin = USART2_HF_TO_PA_Pin2;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 HAL_GPIO_Init(USART2_HF_TO_PA_GPIO_Port2, &GPIO_InitStruct);

 /* USART2 DMA Init */
 /* USART2_RX Init */
 hdma_usart2_rx.Instance = DMA1_Channel6;
 hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
 hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
 hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 hdma_usart2_rx.Init.Mode = DMA_NORMAL;
 hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
 if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
 {
 error_handler();
 }

 __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx);

 /* USART2_TX Init */
 hdma_usart2_tx.Instance = DMA1_Channel7;
 hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
 hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
 hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 hdma_usart2_tx.Init.Mode = DMA_NORMAL;
 hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
 if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK)
 {
 error_handler();
 }

 __HAL_LINKDMA(uartHandle,hdmatx,hdma_usart2_tx);

 /* USART2 interrupt Init */
 HAL_NVIC_SetPriority(USART2_IRQn, 5, 0);
 HAL_NVIC_EnableIRQ(USART2_IRQn);
 /* USER CODE BEGIN USART2_MspInit 1 */

=======

Same code for TX

=======

 if (HAL_HalfDuplex_EnableReceiver(&huart2) != HAL_OK) 
 { 
 error_handler(); 
 } 
 HAL_StatusTypeDef ret = HAL_UARTEx_ReceiveToIdle_DMA(&huart2, 
 &(gRxDataBuffer[gRxDataBufferIndex][0]), 
 UART_BUFFER_SIZE); 
======

HAL_UARTEx_RxEventCallback(), HAL_UART_RxCpltCallback() or HAL_UART_ErrorCallback() are never called.

 

We would like to know what is wrong into our configuration, on either side?

We noticed that there are no call to HAL_RCCEx_PeriphCLKConfig() for STM32F103C8T6 nor that the field GPIO_InitStruct.Alternate is set when compared to STM32H735RGV6.

We did use STM32CubeIDE, Version: 1.16.0, Build: 21983_20240628_1741 (UTC) to generate both code.

    This topic has been closed for replies.
    Best answer by SylvainQuaze

    Thanks all,

    We have found the problem, we were trying to use PIN3 of GPIOA for Half Duplex as it was the RX pin for the Full Duplex, but we need to use the TX pin aka PIN2 of GPIOA in Half Duplex.

    On the hardware, for Half Duplex, we need to plug the TX Pin of the STM32F103C8T6 to the TX Pin STM32H735RGV6 rather than, as for Full Duplex, the TX Pin to the RX Pin and the RX Pin to the TX Pin.

    Regards

    2 replies

    Technical Moderator
    July 19, 2024

    Hello @SylvainQuaze ,

     

    The following configurations are taken from the example UART_TwoBoards_ComDMA.

    Could you please update your code to be aligned with these setting:

     

     /*##-2- Configure peripheral GPIO ##########################################*/ 
     /* UART TX GPIO pin configuration */
     GPIO_InitStruct.Pin = USARTx_TX_PIN;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_PULLUP;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    
     HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);
    
     /* UART RX GPIO pin configuration */
     GPIO_InitStruct.Pin = USARTx_RX_PIN;
     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    
     HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);

     

    Please refer to the example for more details. 

     

    Graduate
    July 19, 2024

    Unfortunately, the example you are referring is a full duplex example using HAL_UART_Init() and we have no problem in full duplex mode. We have problem when using half duplex (HAL_HalfDuplex_Init()).

    Technical Moderator
    July 19, 2024

    Hello @SylvainQuaze,

    Could you try with this code attached. I tested it in my side it sent data without issue. 

     

     

    SylvainQuazeAuthorAnswer
    Graduate
    July 22, 2024

    Thanks all,

    We have found the problem, we were trying to use PIN3 of GPIOA for Half Duplex as it was the RX pin for the Full Duplex, but we need to use the TX pin aka PIN2 of GPIOA in Half Duplex.

    On the hardware, for Half Duplex, we need to plug the TX Pin of the STM32F103C8T6 to the TX Pin STM32H735RGV6 rather than, as for Full Duplex, the TX Pin to the RX Pin and the RX Pin to the TX Pin.

    Regards