cancel
Showing results for 
Search instead for 
Did you mean: 

SPI and DMA on STM32F2xx

carl2399
Associate II
Posted on November 23, 2011 at 02:23

Is there a simple example of this?

I've written some code based on a working non-DMA version of my SPI object. So far I have the following:

void SPI2_StartDMA(u16 NumBytes)

{

// Disable both DMA channels

DMA1_Stream3->CR   &= ~1;

DMA1_Stream4->CR   &= ~1;

// Disable the SPI port

SPI2->CR1          &= ~0x40;

// Clear any outstanding DMA interrupts

DMA1->LIFCR         = 0x0F400000;

DMA1->HIFCR         = 0x0000003D;

// Configure the receiver

DMA1_Stream3->CR    = (DMA1_Stream3->CR & 0xF0100000) | 0x00012C20;

DMA1_Stream3->NDTR  = NumBytes;

DMA1_Stream3->PAR   = (uint32_t)&(SPI2->DR);

DMA1_Stream3->M0AR  = (uint32_t)&(SPI2RxBuf[0]);

// Configure the transmitter

DMA1_Stream4->CR    = (DMA1_Stream4->CR & 0xF0100000) | 0x00012C60;

DMA1_Stream4->NDTR  = NumBytes;

DMA1_Stream4->PAR   = (uint32_t)&(SPI2->DR);

DMA1_Stream4->M0AR  = (uint32_t)&(SPI2TxBuf[0]);

// Flush the SPI receiver

(void)SPI2->DR;

// Enable the DMA mode in the SPI

SPI2->CR2          |= 3;

// Enable the DMA devices    

DMA1_Stream3->CR   |= 1;

DMA1_Stream4->CR   |= 1;

// Enable the SPI Port - to start the transfer

SPI2->CR1          |= 0x40;

}

I call the previous function with something like:

SPI2TxBuf[0] = 10;

SPI2TxBuf[1] = 0;

SPI2TxBuf[2] = 55;

SPI2_StartDMA(3); // Tx/Rx 3 bytes // Wait for the received response

printf(''Wait.'');

while ((DMA1->LISR & 0x0B400000) == 0) ;

printf(''Success.'');

I get ''Wait.'', but no ''Success.''. It's like the process hasn't started.

Any ideas as to what I might be doing wrong?

3 REPLIES 3
loeffel2
Associate III
Posted on November 23, 2011 at 08:13

Hi

Did you setup your SPI to support DMA for transmitting and receiving? Is the receiver FIFO setup correct?

Regards Raphael

 

carl2399
Associate II
Posted on November 23, 2011 at 08:41

Hi Raphael,

In answer to your questions, the code I attached includes:

// Enable the DMA mode in the SPI

SPI2->CR2          |= 3;

and

DMA1_Stream3->M0AR  = (uint32_t)&(SPI2RxBuf[0]);

...

DMA1_Stream4->M0AR  = (uint32_t)&(SPI2TxBuf[0]);

Which I believe answers both your questions.

SPI2RxBuf[0] and 

SPI2TxBuf[0] are defined as simple arrays.

I know the SPI port works, because my port-bashed non-DMA version of the driver works fine.

 
carl2399
Associate II
Posted on November 23, 2011 at 12:08

Solved.

In the end it was a simple misunderstanding of the role of peripheral control versus DMA control of the flow controller. The solution was to change the following lines:

DMA1_Stream3->CR    = (DMA1_Stream3->CR & 0xF0100000) | 0x00012C00;

...

DMA1_Stream4->CR    = (DMA1_Stream4->CR & 0xF0100000) | 0x00012C40;

Blink and you'll miss the change. But making this change resulted in the DMA jumping into life!

This processor is so cool - even if a bit mind-numbing at times.