I'm reading samples at a fairly high bitrate (820kbps) from an external ADC over SPI. I need to add a CRC byte and then forward each sample to USART.
As a consequence of my inexperience, within the DMA (SPI) transfer complete ISR where I have a frame of received samples in a memory buffer I attempted to (in a loop over each sample) add CRC and send each byte to USART. This was too slow and delayed setting up the next SPI transfer such that samples were getting dropped.
I believe I need to move the CRC and USART transfer code out of the ISR and into the main loop however I don't think then I can then read from the same memory buffer that SPI is writing to since I can't control when it might change (due to SPI DMA being autonomous and continuous).
One solution I imagined is to have the DMA (SPI) target alternating memory buffers (A and B). SPI would write to buffer A while USART reads from B, then swap. I'd need to ensure
- the main loop only reads from the buffer that's currently not targeted.
- The main loop sets a lock flag on the buffer it's reading from and the DMA ISR is prevented from setting up a new transfer to that buffer while the lock is set
What is common practice for this type of situation?
Latency isn't a concern.
The ADC is 24bit but an extra 8 bits is appended (for a total of 32bit) which is static and represents the configured downsampling factor. I am overwriting the final 8 bits received in each sample with an 8bit CRC of the 24bits representing the sample.
The USART is set to a baud of 1.7Mbps. I've done an echo test and confirmed no data corruption is happening.
The STM32 model is STM32U5.
The USART output is purely for diagnostics during development. It will be disabled under normal operation.