cancel
Showing results for 
Search instead for 
Did you mean: 

I am using STM32F3xx_HAL_Driver with my STM32F303VD MCU. When I am erasing 1-3 pages of flash memory with HAL_ERR_TYPE HAL_FLASHEx_Erase (&eInit, &status) subroutine, my USART2 seems to overflow.

JKlec
Associate II

I have the USART2 setup for RTS/CTS flow-control and Rx DMA for one byte transfers into a ringbuffer. The problem isn't that the ringbuffer is overflowing, it appears that the DMA process is stalled during the erase flash pages operation and the UART receive buffer overflows. If the DMA is stalled, why doesn't the USART2 peripheral de-assert the RTS signal and prevent this overflow?

Here is my USART setup:

/* USART2 init function */

static void MX_USART2_UART_Init(void)

{

  huart2.Instance = USART2;

  huart2.Init.BaudRate = 115200;

 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_RTS_CTS;

 huart2.Init.OverSampling = UART_OVERSAMPLING_16;

 huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;

 huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT|UART_ADVFEATURE_DMADISABLEONERROR_INIT;

 huart2.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;

  huart2.AdvancedInit.DMADisableonRxError = UART_ADVFEATURE_DMA_DISABLEONRXERROR;

  if (HAL_UART_Init(&huart2) != HAL_OK)

 {

   _Error_Handler(__FILE__, __LINE__);

  }

}

Here is my Rx DMA setup:

static void MX_DMA_Init(void) 

{

 /* DMA controller clock enable */

  __HAL_RCC_DMA1_CLK_ENABLE();

  __HAL_RCC_DMA2_CLK_ENABLE();

 /* DMA interrupt init */

 /* DMA1_Channel1_IRQn interrupt configuration */

  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

 /* DMA1_Channel4_IRQn interrupt configuration */

  HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);

  /* DMA1_Channel6_IRQn interrupt configuration */

 HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 0, 0);

 HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);

 /* DMA2_Channel1_IRQn interrupt configuration */

  HAL_NVIC_SetPriority(DMA2_Channel1_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(DMA2_Channel1_IRQn);

 /* DMA2_Channel2_IRQn interrupt configuration */

  HAL_NVIC_SetPriority(DMA2_Channel2_IRQn, 0, 0);

 HAL_NVIC_EnableIRQ(DMA2_Channel2_IRQn);

  /* DMA2_Channel5_IRQn interrupt configuration */

 HAL_NVIC_SetPriority(DMA2_Channel5_IRQn, 0, 0);

 HAL_NVIC_EnableIRQ(DMA2_Channel5_IRQn);

}

Here is where I erase flash memory:

FLASH_EraseInitTypeDef eInit;;

eInit.TypeErase = FLASH_TYPEERASE_PAGES;

eInit.PageAddress = 253;

eInit.NbPages = 3;

HAL_ERR_TYPE HAL_FLASHEx_Erase(&eInit, &status);

assert_param(err==HAL_OK);

Here is how I enable the USART2's Rx DMA:

void initSerial (void)

{ HAL_ERR;

switch (l->is.baudRate) {

case BAUD_9600: USART_HW->Init.BaudRate = 9600; break;

case BAUD_19200:  USART_HW->Init.BaudRate = 19200; break;

case BAUD_38400: USART_HW->Init.BaudRate = 38400; break;

case BAUD_57600: USART_HW->Init.BaudRate = 57600; break;

default: USART_HW->Init.BaudRate = 115200;

}

HAL_ERR_TYPE HAL_UART_Init(USART_HW);

assert_param(err==HAL_OK);

HAL_ERR_TYPE HAL_UART_Receive_DMA (USART_HW, (uint8_t *)&uart_c, 1);

assert_param(err==HAL_OK);

}// End of initSerial routine

Here is my UART_RxCpltCallback() routine:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)

{ HAL_ERR;

ringBuffer[wrPtr++] = uart_c; // Store character in

wrPtr %= RINGLENGTH; //

RxDMAcplt++; // Increment RxDMAcplt counter

if ((wrPtr-rdPtr)%RINGLENGTH<RINGLENGTH-(RINGLENGTH>>3)) {

if (USART_HW->RxState==HAL_UART_STATE_READY) {

HAL_ERR_TYPE HAL_UART_Receive_DMA (USART_HW, (uint8_t *)&uart_c, 1);

assert_param(err==HAL_OK);// Restart Rx transmission if room left in ringBuffer

}

} //Endif

}//end

I enable DMA transfers of only 1 character at a time so I can immediately see if XON/XOFF is being sent or to force harware flow-control to keep USART2's internal Rx buffer from overflowing if DMA has been suspended or stalled due to lack of MCU resources, especially during flash page erase and write cycles. This however doesn't appear to work properly. I don't even see the RTS signal being deasserted to inform my desktop computer to wait. Even if it does I'm not sure if my USB-to-RS232 bridge (FT320X) knows how to stop its transmission upon receipt of HIGH CTS signal.

Is there any supported serial drivers that support hardware and/or software flow-control on USART2?

0 REPLIES 0