Advice on SPI and DMA for 24bit data on STM32H723
I want to solicit the advice of those more experienced with the STM32 processors. I'm experienced in general with embedded software and peripherals such as SPI but only about 6 months in on the STM32 processors and only in the last few weeks have I been delving into the SPI and DMA. My first dives were into timers and USB. In specific, I'm using a STM32H723.
I'm using a 4 channel SPI based ADC. The TI ADS131M04 in specific. SPI communication is 6 words with a default word size of 24 bits. The word size can be changed to 16 or 32 bits but initial size after reset is 24 bits. It has a data ready line to indicate samples are available.
I realize 24 bits is an awkward size but so many ADC's support it. I would assume there are efficient ways for the STM32 to handle this size of SPI data. While it isn't absolutely mandatory in this application for data to be handled the most efficient way, I have future projects that will need the efficiency. So this is a good time to learn.
What I would like to implement is a totally DMA based data transfer. The DRDY signal would initiate the transfer of the 6 word frame. In that frame are the 4 samples of the specified word size plus 2 words of overhead information. The RX DMA would go into a double buffer with multiple frames per buffer to reduce interrupt frequency. The TX DMA just needs to output 6 words of 0's to create the SPI clocking. I've seen references to a timer capture input being used to trigger a DMA. So I currently have DRDY going into a timer capture input. I haven't figured out the details of this yet. Is this a workable direction? I'm ok with an interrupt to deinterleave the data periodically probably scaling it in the process. I'm using a GPIO for the chip select.
I have basic SPI with DMA working (that was a learning experience). What I ran into the ADC expects the SPI data most significant byte first while the STM32 appears to be little endian. With 24 bit data, I am manually ordering the bytes I put into the transmit buffer so the order is correct. When I tried 32 bit data directly from an int, I realized the byte order was wrong. I know I can manually order the bytes but that seems very inefficient. I made a brief attempt to define a 24bit SPI word size but that messed with the DMA so I had to turn off the FIFO. I got to where 6 words of 24 bits shifted out correctly but the completion interrupt didn't happen and no change to the byte order. I gave up and went back to what works and wrote this message. Since the byte order didn't change, this direction didn't seem useful.
So far I'm using the HAL interface. I expect I will have to get to the register level to realize some of these ambitions but I'm trying to walk before I run.
After setting the context, here are some specific questions.
1) Are their any optimizations for handling 24 bit data words in the SPI and/or DMA controller setup?
2) Any examples of using a timer input to trigger an DMA SPI transfers?
3) Any way other than coding to deal with the byte ordering of SPI data?
4) Would the serial audio interface be better than the SPI for this? This is an SPI based ADC.
I am using a Nucleo board with a prototype IO board I've developed. I can modify this board or do something different for the production board if needed.
Any suggestions and advice will be appreciated.
