2016-04-05 07:52 AM
Hi,
I would like to continously receive data via usart. I have a receive buffer configured to receive 1000 bytes in circular mode. Now I would like to pause the dma, process the received data and resume the dma. How do I know how much bytes were received? Thanks for your help in advance.2016-04-05 08:14 AM
Stoping the DMA is not advised when you want to receive a continuous stream.
Assuming you are using an F4, the best option is to keep circular mode and enable HT and TC interrupts, so you will receive an interrupt every 500 bytes, that you can process while still receiving 500 others. If you can't wait for the interrupt (end of transfer, pause, etc ...) reading the NDTR register of the concerned channel tell you remaining bytes to be received, from which you deduce the number of received bytes.2016-04-06 01:20 AM
Thank you very much.
I will try to read the NDTR register. That's what I was looking for.2016-04-06 02:12 AM
I have figured out how to read the NDTR registers for my dma stream. In my setup I simply want to read the data from USART and process it. For test purposes I just want to output the received charaters. But unfortunately the received data is not (completely) in the buffer. Even when I wait for sometime.
This is my test code:char rx_buf[1000];
HAL_UART_Receive_DMA(&huart5, (uint8_t*) rx_buf, 1000); uint32_t prev_ntdr = 1000; uint32_t rcvd_bytes = 0; uint32_t read_idx = 0; while (1) { // determine number of received bytes HAL_UART_DMAPause(&huart5); rcvd_bytes = prev_ntdr - huart5.hdmarx->Instance->NDTR; prev_ntdr = huart5.hdmarx->Instance->NDTR; HAL_UART_DMAResume(&huart5); HAL_Delay(500); // process received bytes printf(''received %d bytes\n'', rcvd_bytes); for (uint32_t i = 0; i < rcvd_bytes; i++) { printf(''%c'', rx_buf[read_idx]); read_idx++; } printf(''\n''); HAL_Delay(500); } My DMA configuration looks like this:hdma_uart5_rx.Instance = DMA1_Stream0;
hdma_uart5_rx.Init.Channel = DMA_CHANNEL_4; hdma_uart5_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_uart5_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_uart5_rx.Init.MemInc = DMA_MINC_ENABLE; hdma_uart5_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_uart5_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_uart5_rx.Init.Mode = DMA_CIRCULAR; hdma_uart5_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH; hdma_uart5_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE; hdma_uart5_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; hdma_uart5_rx.Init.MemBurst = DMA_MBURST_SINGLE; hdma_uart5_rx.Init.PeriphBurst = DMA_PBURST_SINGLE; HAL_DMA_Init(&hdma_uart5_rx);2016-04-07 01:54 AM
The size of the FIFO and its threshold were too high for my application. After turning of the FIFO all data was available as expected.
Stupid mistake.