I am trying to read a fixed number of bytes (27 bytes in total) from an SPI slave device using DMA. I'm running an STM32F4 chip.
"In order to read from the SPI bus, a clock needs to be generated. So you need to write in order to read." I set up my DMA controller to write a dummy byte (0xFF) in circular mode.
uint8_t tx_buffer[] = {0xFF};
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
DMA_InitStruct.DMA_BufferSize = 1;
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)tx_buffer;
and my Rx dma stream is setup using double buffer mode:
uint8_t rx_buffer0[27];
uint8_t rx_buffer1[27];
DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
DMA_InitStruct.DMA_BufferSize = 27;
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)rx_buffer0;
DMA_DoubleBufferModeConfig(DMA2_Stream0, (uint32_t)rx_buffer1, DMA_Memory_0);
DMA_DoubleBufferModeCmd(DMA2_Stream0, ENABLE);
(I have omitted other irrelevant initialisations.)
After the 27 bytes are received a Transfer Complete interrupt is triggered.
void DMA2_Stream0_IRQHandler(void)
{
if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0) == SET)
{
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
DMA_Cmd(DMA2_Stream1, DISABLE); // disable Tx circular writes
}
}
The problem is as follows: I see correct data in the first buffer. But while the interrupt triggers the Tx circular DMA continues, filling the first few bytes of the second buffer until it is disabled.
I want to avoid reserving 27 bytes for dummy data, so is there any way to stop a circular DMA stream after a fixed amount of cycles?