Reputation: 113
I have a known serial stream format that I am capturing via the DMA. It has header and footer bytes. But sometimes the MCU starts capturing in the middle of the stream and then the sync is out because the DMA is looking for a set number of bytes. I have read of people using circular buffers, but I have struggled to grasp this concept.
Instead, I was thinking of disabling the DMA and enabling the a serial interrupt at the start up of the MCU. Then cycle through each byte that is captured by the interrupt to find the start byte. Then, once I have found the start byte, disable the serial interrupt capturing and enable the DMA to take over the capturing of the stream.
Does this sound feasible? Thanks for any input.
I am using STM32 HAL libs with the new STM32 IDE that includes STM32 CubeMX.
Upvotes: 0
Views: 1902
Reputation: 8059
As the protocol has idle gaps between packets, you can use the idle interrupt feature of the UART to synchronize the receiver.
Enable the UART interrupt, simply start receiving with DMA, and set UARTx->CR1 |= USART_CR1_IDLEIE
. Whenever the idle interrupt is triggered, look at the DMA channel, if it's still running, stop the transfer and discard the input buffer (as this means that the receive was started in the middle of the packet) and start receiving the next packet.
Upvotes: 0
Reputation: 665
If I understand your reference to circular buffers correctly, the concept is simple. You have a large buffer with a write pointer and a read pointer. The write function writes data into the buffer from the write pointer onward, taking care that once it reaches the end of the buffer, it wraps around and dumps the data at the beginning of the buffer and onward. Then you need a reader function that reads the data from the read pointer onward, and again, taking care of wrap around at the end of the buffer.
Both the read and write pointers start at the beginning of the buffer. The two conditions that you have to check are: 1) When the read pointer is at the same location as the write pointer, there is nothing (more) to read. 2) When the write pointer increments and runs into the read pointer location, you have a buffer overflow condition. This should never happen, so either you must use a larger buffer, or have the reader task runs more frequently, or you start throwing things out.
So in your scenario, the DMA just dumps data, and your reader task looks for the header bytes and processes the data until it finds the footer bytes.
Upvotes: 0