AnsweredAssumed Answered

STM32F030 UART HalfDuplex config

Question asked by Lukasz Przenioslo on Nov 15, 2016
Hello there,
I am trying to configure uart in half duplex mode on STM32F030 device (usage with RS485 later on). I am having difficulties in making the program work properly using the HAL library. This is basically the important part of code:

Uart parameters initialization (uart module)
void MX_USART1_UART_Init(void)
{
 
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 9600;
  huart1.Init.WordLength = UART_WORDLENGTH_9B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_EVEN;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_RS485Ex_Init(&huart1, UART_DE_POLARITY_HIGH, 16, 16) != HAL_OK)
  {
    Error_Handler();
  }
 
}

DMA module:
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
 
  GPIO_InitTypeDef GPIO_InitStruct;
  if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspInit 0 */
 
  /* USER CODE END USART1_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();
   
    /**USART1 GPIO Configuration   
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX
    PA12     ------> USART1_DE
    */
    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF1_USART1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF1_USART1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
    /* Peripheral DMA init*/
   
    hdma_usart1_rx.Instance = DMA1_Channel3;
    hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart1_rx.Init.Mode = DMA_NORMAL;
    hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
    {
      Error_Handler();
    }
 
    __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);
 
    hdma_usart1_tx.Instance = DMA1_Channel2;
    hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart1_tx.Init.Mode = DMA_NORMAL;
    hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
    {
      Error_Handler();
    }
 
    __HAL_LINKDMA(uartHandle,hdmatx,hdma_usart1_tx);
 
    /* Peripheral interrupt init */
    HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART1_IRQn);
  /* USER CODE BEGIN USART1_MspInit 1 */
 
  /* USER CODE END USART1_MspInit 1 */
  }
}


Now I am trying to receive just 1 byte in halfduplex DMA mode here:
retVal += HAL_HalfDuplex_Init(mbs_uartHandle); 
retVal += HAL_HalfDuplex_EnableReceiver(mbs_uartHandle); // should toggle DE?
retVal += HAL_UART_Receive_DMA(mbs_uartHandle, mbs_rawRxDataStream, len);

I place a breakpoint in the ISR routine and wait for interrupt to come after sending one byte, but nothing happens. If I comment out the 1st line (retVal += HAL_HalfDuplex_Init(mbs_uartHandle);  ) I will get an infite number of interrupt in the ISR, but the code doesnt match any function that the HAL lib checks inside (returns from HAL_UART_IRQHandler(&huart1); without hitting any flag... Infitie times.

I was wondering what is wrong with my config? Do I need to perform any additional steps? Also, after I enabled the RS485 functionality (DE line handling), will it automatically work when using send/ receive functions? Or do I need to implement some more myself because the library is not complete?
I would appreciate all help regarding this.

Outcomes