Loading...
 

Zephyr project on STM32

   Zephyr Workbench, a VSCode extension to manage Zephyr on STM32.
It enables users to easily create, develop, and debug Zephyr applications.
Main features:
  • Install host dependencies.
  • Import toolchain and SDK.
  • Create, configure, build and manage apps.
  • Debug STM32.
You can directly download it from the VSCode marketplace
For more details, visit the Zephyr Workbench

System Workbench for STM32


UART circular buffer

Hi

I am using the UART on a 32F030 device and want to recieve data continuously. Really I am looking at just implementing a circular buffer. I have looked at the HAL functions but all the UART receive ones seem to need a length of data to be received. These functions seem useless unless you actually know the amount that comes in to the device. So do people just create their own or has anyone used these functions to create a circular buffer?

Thanks

Jon

Hi
My example for UART DMA

  1. define MAX_NUM_CHAR_FOR_MESSAGE 64

  1. ifdef UART_1

extern UART_HandleTypeDef huart1;

  1. define BUFFER_UART1_TX_MAX MAX_NUM_CHAR_FOR_MESSAGE
  2. define CIRCULAR_BUFFER_UART1_RX_MAX 256
  3. ifdef UART_1_DMA

extern DMA_HandleTypeDef hdma_usart1_rx;

  1. endif
  2. endif


HAL_StatusTypeDef InitUart_IT_DMA(BYTE ucCom)
{
HAL_StatusTypeDef ret = HAL_ERROR;

switch (ucCom) {

#ifdef UART_1
case UART_1:
bTx1Running = FALSE;
#ifdef UART_1_DMA
ret = HAL_UART_Receive_DMA(&huart1, (uint8_t *)ucRx1, CIRCULAR_BUFFER_UART1_RX_MAX);
uiIdxWrRx1 = CIRCULAR_BUFFER_UART1_RX_MAX - hdma_usart1_rx.Instance->NDTR;
#else
uiIdxWrRx1 = 0;
ret = HAL_UART_Receive_IT(&huart1, (uint8_t *) &ucRx1uiIdxWrRx1, 1);
#endif
uiIdxRdRx1 = uiIdxWrRx1;
break;
#endif
default:
ret = HAL_ERROR;
break;
}
return ret;
}


You can set up a DMA circular buffer with the MXCube really easily, and just set the receive length to a really large number when you command the DMA receive. For example:

HAL_UART_Receive_DMA(&huart2, gps_circ, 0xFFFFFFFFu); //number of bytes is 2^32, good for about 83 hours continuously at 110kbps

By the way, I figured out tonight that what I wrote was actually bad advice. When I did it with my code, it resulted in hard fault errors. After a little more web research I found what is probably a better way to deal with variable-length UART input: Use the idle line detection interrupt. When the transmission you are receiving string is done, the ISR will activate and then you can deal with the complete transmission and start a new DMA reception. I haven’t implemented it yet, but I wanted to get this out there before someone else tries to use a really long receive length. Seems like a continuous reception into a circular buffer would be an obvious use-case for UART DMA, so I find the HAL disappointing in this area.

 

Newest Forum Posts

  1. Last day: drone bonus by Danielrug, 2025-04-19 16:55
  2. SPI on Nucleo_STMH533RE by higginsa1, 2025-03-25 07:37
  3. SPI on Nucleo_STMH533RE by royjamil, 2025-03-23 11:31
  4. SPI on Nucleo_STMH533RE by higginsa1, 2025-03-23 09:33
  5. Configuring DMA for ADC in SW? by sam.hodgson, 2025-03-04 12:58
  6. Insightful Perspectives on This Subject by davidsycle, 2025-03-04 05:45
  7. Build a project in "release" mode by info@creosrl.it, 2025-02-20 18:12
  8. Build a project in "release" mode by info@creosrl.it, 2025-02-20 17:05
  9. Build a project in "release" mode by tang, 2025-02-20 10:36
  10. Build a project in "release" mode by info@creosrl.it, 2025-02-19 17:35

Last-Modified Blogs