cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 Discovery board SPI, DMA

40802528
Associate II
Posted on December 08, 2011 at 20:04

Hi all,

I am getting some problems with using SPI peripheral.

In the sample code, I see that we have to wait until receiving the ''response'' data after each data transfer.  Why we must do that? I mean when we write data to slave LIS302, we do not need receive the ''response'' data.

And another question is why we must write a ''dummy'' byte before receiving data from slave ? Does it need to keep clock in CLK line ? It is not mentioned in the datasheet.

Does anyone use the DMA with SPI ? Would you help me show steps (transaction) to transmit & receive data from LIS302.

Thank all !

#spi-dma-receive-rx-tx-stm32f4
18 REPLIES 18
Posted on December 08, 2011 at 23:43

The STM32 only generates clocks for data as it sends it. The receive data is read bit-by-bit on the opposite clock edge to the bits being clocked into the slave device.

You wait for the receive to complete to ensure the last bit got to the slave. The transmit buffer goes empty as the byte/word is moved to the the transmit shift register, and consequently clears prior to the first bit actually getting transmitted. Thus TXE is useless at flagging what's going on, you can use it to stuff the next value in which will get sent 8/16 clock cycles in the future.

Dummy bytes/words are sent to generate clocks to shift pending data out of the slaves, otherwise no clocks would be occurring.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
lumley
Associate II
Posted on December 09, 2011 at 03:00

Can you point me to an SPI / DMA example?  The OP implies there is one in the STM32F4Discovery firmware, but I could not find it.

Any example would be fine -- STM32F4, STM32F2, or STM32F1.

Thanks.

40802528
Associate II
Posted on December 09, 2011 at 05:14

Thank clive,

In the transaction, when we write data to slave , slave will not send any data back. So How can the receiver get data and RXNE is set ? I do not understand this point !

I think we can use BSY flag instead of TXE flag to know when the transmission is complete. However, because RXNE was set , so that we must wait to clear it. It is difficult to apply DMA with SPI peripheral :( .

Posted on December 09, 2011 at 05:17

Try the product page, Design Support -> Firmware

''STM32F4DISCOVERY board firmware package, including 22 examples (covering USB Host, audio, MEMS accelerometer and microphone…) and preconfigured projects for 4 different IDEs''

http://www.st.com/internet/evalboard/product/252419.jsp

http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f4discovery_fw.zip

The demonstration code has SPI support

\STM32F4-Discovery_FW_V1.1.0\Project\Demonstration\selftest.c

There are other SPI library examples for prior chips/libraries bundled with Keil or IAR

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on December 09, 2011 at 05:34

In the transaction, when we write data to slave , slave will not send any data back. So How can the receiver get data and RXNE is set ? I do not understand this point !

The STM32 sees it as a symmetrical transaction, it clocks out data on one edge, and samples the data comming back on the other edge. The fact the slave isn't sending anything useable is mostly irrelevant to the STM32.

Think of it as a circular shift register. RXNE is a free side effect.

For sending to SPI via DMA, you'd wait for it to signal TC, then you'd wait for the SPI to complete, if that's what you need to do.

 

 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
lumley
Associate II
Posted on December 09, 2011 at 07:02

I guess I still don't see it.  I am looking for a SPI / DMA full duplex example with two way communication, such as reading an SPI digital gyroscope.  You send data over the Tx, and simultaneously read over the Rx.

I thinik selftest.c has a one way SPI.  When I do search on DMA_Cmd(), I only see one stream initialized.  For duplex DMA / SPI, how do you do it?

Is there a full duplex DMA SPI example that you can point me to?

40802528
Associate II
Posted on December 09, 2011 at 09:51

Thank clive1 again :) !!!

The phrase ''circular shift register'' is very useful. I think I got your idea. And It really works well. I have just applied DMA with SPI to read data from LIS302 sensor and it is ok.

@rjl :I think that the code for SPI/DMA did not include in examples. However, you can try DMA with USART example  in STM32F4xx_DSP_StdPeriph_Lib (not STM32F4_Discovery_FW )  ''STM32F4xx_DSP_StdPeriph_Lib_V1.0.0\Project\STM32F4xx_StdPeriph_Examples\USART\USART_TwoBoards\DataExchangeDMA''  . Then, you apply it to SPI peripheral, the configuration sequence is the same.

For example: I want to read 6 bytes in LIS302 begin at OUT_X register. Firstly, I need configure SPI1 peripheral, DMA enable..etc.Secondly, I want to read data, I will prepare 2 buffers Tx & Rx. The TxBuffer begins with register address and dummy bytes to generate clock to slave. Response data  will be put in RxBuffer

    //prepare TxBuffer to transfer

    spi1TxBuffer[0] = OUT_X_ADDR|READ_INCREMENT_ADDR;

    spi1TxBuffer[1] = DUMMY_BYTE;spi1TxBuffer[2] = DUMMY_BYTE;

    spi1TxBuffer[3] = DUMMY_BYTE;spi1TxBuffer[4] = DUMMY_BYTE;

    spi1TxBuffer[5] = DUMMY_BYTE;spi1TxBuffer[6] = DUMMY_BYTE;

   

    //set up buffer size

    DMA_Spi1TxStruct.DMA_BufferSize = (uint32_t)7;

    DMA_Spi1RxStruct.DMA_BufferSize = (uint32_t)7;

    DMA_Init(DMA2_Stream3, &DMA_Spi1TxStruct);     //Re-configure Tx DMA

    DMA_Init(DMA2_Stream2, &DMA_Spi1RxStruct);    //Re-configure Rx DMA

    

    // Set chip select Low at the start of the transmission ; this bit will be set in    SPI-RX interrupt after receiver end

    GPIO_ResetBits(GPIOE, GPIO_Pin_3);     

    //ENABLE DMA SPI TX-RX

    DMA_Cmd(DMA2_Stream3, ENABLE);         //TX

    DMA_Cmd(DMA2_Stream2, ENABLE);         //RX

lumley
Associate II
Posted on December 09, 2011 at 11:04

Dang, 

Can I ask you to detail your example a bit more?

Do you have the full assignments you made to 

DMA_Spi1TxStruct and DMA_Spi1RXStruct?

And, just for completeness, the place where you issue the two commands for SPI_I2S_DMACmd().  

Thanks.

rjl

Posted on December 09, 2011 at 13:23

Is there a full duplex DMA SPI example that you can point me to?

Within Keil, and presumably IAR, you have V2.0.1 of the firmware library

You have DMA for both Rx, Tx, SPI1 and SPI2

\Keil\ARM\Examples\ST\STM32F10xFWLib\Examples\DMA\SPI_RAM

And a Tx example

\Keil\ARM\Examples\ST\STM32F10xFWLib\Examples\SPI\DMA
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..