cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Master RX DMA non functioning.

daniel8
Associate II
Posted on September 04, 2009 at 19:18

SPI Master RX DMA non functioning.

4 REPLIES 4
daniel8
Associate II
Posted on May 17, 2011 at 09:59

I am trying to setup the SSP in master mode to do a DMA RX , and its not working. I have the SSP_DMA_Receive Enabled

I have tried different DMA setups (as far as flow control), but I cannot get the SSP to generate the clocks to receive the data. Here is my setup:

DMA_StructInit(&DMA_InitStruct);

DMA_InitStruct.DMA_Channel_LLstItm=0;

DMA_InitStruct.DMA_Channel_SrcAdd=(unsigned int)(&SSP0->DR);

DMA_InitStruct.DMA_Channel_DesAdd=(unsigned int)((&buffer[0]));

DMA_InitStruct.DMA_Channel_SrcWidth= DMA_SrcWidth_Byte;

DMA_InitStruct.DMA_Channel_DesWidth= DMA_DesWidth_Byte;

DMA_InitStruct.DMA_Channel_FlowCntrl= DMA_FlowCntrl2_DMA;

DMA_InitStruct.DMA_Channel_SrcBstSize=DMA_SrcBst_1Data;

DMA_InitStruct.DMA_Channel_DesBstSize=DMA_DesBst_1Data;

DMA_InitStruct.DMA_Channel_Src = DMA_SRC_SSP0_RX;

DMA_InitStruct.DMA_Channel_TrsfSize =512;

DMA_ChannelSRCIncConfig(DMA_Channel4, DISABLE);

DMA_ChannelDESIncConfig(DMA_Channel4, ENABLE);

DMA_Init(DMA_Channel4,&DMA_InitStruct);

DMA_ChannelCmd(DMA_Channel4,ENABLE);//Enable the DMA channel

Any ideas why the clocks are not generated? The SSP peripheral is configured properly as I can issue regular reads to it. I have the Write DMA working on it, but I cannot get the system to properly initialize a read DMA when the SSP is setup as a master. Thanks

rich2
Associate II
Posted on May 17, 2011 at 09:59

Yes, I think I know what's going on. A DMA channel cannot request an SSP read operation, it can only respond to one that has already taken place as a result of a previous write.

When in SSP (SPI) master mode, in order to read something from a slave you must first write something to it. The clocks you are expecting to see will not occur unless you write something out first. This is the way SPI works (sorry, I don't mean to tell you something you may already know, I just want to be thorough here).

In order to do DMA reads from SPI RX, you need to set up a second DMA channel that does writes to the same SSP peripheral. Make this new, second channel, have a DMA source request line according to your needs (a timer peripheral, for example, or an external INT line). When that second DMA channel generates a request it will write something to your SPI slave and after that write, the SPI RX peripheral will generate a DMA request. You seem to have that part set up properly already, so you just need to add the new channel.

It sounds convoluted, but makes sense given how SPI works (when a master, you need to write in order to read).

HTH,

Rich

[ This message was edited by: rich2 on 03-09-2009 02:51 ]

daniel8
Associate II
Posted on May 17, 2011 at 09:59

Yeah, right after posting I figured id look at it on the scope, and setup a second dma channel to transmit dummy data (the amount of bytes id like to receive). I still have a problem where the data that I receive is not quite right (I am trying to figure out exactly what is wrong).

The current setup is as follows:

RX DMA CHANNEL

DMA_StructInit(&DMA_InitStruct);

DMA_InitStruct.DMA_Channel_LLstItm=0;

DMA_InitStruct.DMA_Channel_SrcAdd=(unsigned int)(&SSP0->DR);

DMA_InitStruct.DMA_Channel_DesAdd=(unsigned int)((buff));

DMA_InitStruct.DMA_Channel_SrcWidth= DMA_SrcWidth_Byte;

DMA_InitStruct.DMA_Channel_DesWidth= DMA_DesWidth_Byte;

//Peripheral to memory transfer.

DMA_InitStruct.DMA_Channel_FlowCntrl= DMA_FlowCntrl_Perip2;

DMA_InitStruct.DMA_Channel_SrcBstSize=DMA_SrcBst_1Data;

DMA_InitStruct.DMA_Channel_DesBstSize=DMA_DesBst_1Data;

DMA_InitStruct.DMA_Channel_Src = DMA_SRC_SSP0_RX;

DMA_InitStruct.DMA_Channel_TrsfSize =btr;

DMA_ChannelSRCIncConfig(DMA_Channel5, DISABLE);

DMA_ChannelDESIncConfig(DMA_Channel5, ENABLE);

TX DMA CHANNEL

//SETUP TX Portion

value=0xFF;

DMA_StructInit(&DMA_InitStruct);

DMA_InitStruct.DMA_Channel_LLstItm=0;

DMA_InitStruct.DMA_Channel_SrcAdd=(unsigned int)((&value));

DMA_InitStruct.DMA_Channel_DesAdd=(unsigned int)(&SSP0->DR);

DMA_InitStruct.DMA_Channel_SrcWidth= DMA_SrcWidth_Byte;

DMA_InitStruct.DMA_Channel_DesWidth= DMA_DesWidth_Byte;

DMA_InitStruct.DMA_Channel_FlowCntrl= DMA_FlowCntrl1_DMA;

DMA_InitStruct.DMA_Channel_DesBstSize=DMA_DesBst_1Data;

DMA_InitStruct.DMA_Channel_Des = DMA_DES_SSP0_TX;

DMA_InitStruct.DMA_Channel_TrsfSize =btr;

DMA_ChannelSRCIncConfig(DMA_Channel4, DISABLE);

DMA_ChannelDESIncConfig(DMA_Channel4, DISABLE);

DMA_Init(DMA_Channel4,&DMA_InitStruct);

DMA_ChannelCmd(DMA_Channel4,ENABLE);//Enable the DMA channel

while(DMA_GetChannelActiveStatus(DMA_Channel5)); //Wait for reception

Cheers

rich2
Associate II
Posted on May 17, 2011 at 09:59

If the data you're receiving is 'not quite right' (some data bits are wrong) it's most likely that the SPI mode you are using isn't set properly for your slave device. Verify your CLK_PHA and CLK_POL settings in your SSP setup.

If you're not getting any data bits correctly, you might want to check the values you are using for the DMA Src peripheral (DMA_SRC_SSP0_RX in your code). These values are incorrect in some ST library versions.

Good luck.

Rich