AnsweredAssumed Answered

STM32F205 & DMA for UART

Question asked by Peden.Fabrice on Mar 14, 2017
Latest reply on Mar 21, 2017 by Peden.Fabrice

Hi Everybody,

I'm using a STM32f205RG on a personnal electronic board. I would like to communicate with an external equipment using modbus RTU on RS485 link. So, I'm trying to implement USART 1 with DMA.

 

For the moment, I have set everything (DMA, UART...). My board is the slave. So, I can see frames from the master (read holding registers). These frame have only 8 bytes.

 

So, at the first frame, the 8 bytes are located in my array from 0 to 7. When I receive the second frame, this one is located from 8 to 15.

 

So when I calculate the size of my frame, I found 16 instead of 8, and then my checksum is wrong, and the frame is not validated.

 

So, I'm looking for a solution to "reset" this array.

 

Please find my code :

 

--------------------INITIALIZATION---------------------------

 

/* USER CODE END USART1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART1_CLK_ENABLE();

/**USART1 GPIO Configuration
PB6 ------> USART1_TX
PB7 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* Peripheral DMA init*/

hdma_usart1_rx.Instance = DMA2_Stream5;
hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4;
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;
hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
{
Error_Handler();
}

__HAL_LINKDMA(huart,hdmarx,hdma_usart1_rx);

hdma_usart1_tx.Instance = DMA2_Stream7;
hdma_usart1_tx.Init.Channel = DMA_CHANNEL_4;
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;
//hdma_usart1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
{
Error_Handler();
}

__HAL_LINKDMA(huart,hdmatx,hdma_usart1_tx);

HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);

 

-----------------------------IT--------------------------------------------

/**
* @brief This function handles DMA2 Stream7 global interrupt.
*/
void DMA2_Stream7_IRQHandler(void)
{
HAL_DMA_IRQHandler(&hdma_usart1_tx);


if((HAL_DMA_GetState(&hdma_usart1_tx) == HAL_DMA_STATE_READY) || (HAL_DMA_GetState(&hdma_usart1_tx) == HAL_DMA_STATE_ERROR))
{
Modbus_IT_Transmit(&modbusNET1);
}
}

/**
* @brief This function handles USART6 global interrupt.
*/
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart1);

if((__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&huart1, UART_IT_IDLE) != RESET))
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
__HAL_UART_DISABLE_IT(&huart1, UART_IT_IDLE);

Modbus_IT_Receive_Data(&modbusNET1);
}
}

 

If you have any idea, I  would be very happy.

 

Regards,

 

Fabrice Péden

Attachments

Outcomes