1
votes

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?

1

1 Answers

1
votes

Enable DMA in normal mode and set number of elements to 27.

Later, disable memory increase for memory and for peripheral and your approach will work.