AnsweredAssumed Answered

DMA and SSP1

Question asked by termitcz on Nov 25, 2011
I would like to use DMA with SSP1. There is a problem that when flow control is set to peripheral, data are transfered, but I am not able to control how many bytes are transfered. If I change flow control to DMA, nothing happens. Any single transfer doesn't occur, although both single and burst requests are signaled (registers DMA_SSBR and DMA_SBRR).

I can't find where is the error. I believe I did my best according to documentation.


In previous topics there was an example (Example of DMA and SSP, 11/9/2006 2:10 AM), but the attachment is lost and no longer available. Eris, can you post it again?

Tomas


My code:
==============================================================

#define    SPI_SD               SSP1
#define    DMA_CHANNEL_RX       DMA_Channel4
#define    DMA_CHANNEL_TX       DMA_Channel5
#define    DMA_CHANNEL_RX_IDX   Channel4

void str91_dma_transfer_receive( const BYTE *buff, UINT count)
{
    DMA_InitTypeDef         DMA_InitStructure;
    WORD rw_workbyte[] = { 0xffff };

    DMA_DeInit();
    DMA_Cmd(ENABLE);

    // shared DMA configuration values
    DMA_InitStructure.DMA_Channel_LLstItm = 0;
    DMA_InitStructure.DMA_Channel_DesWidth = DMA_DesWidth_Byte;
    DMA_InitStructure.DMA_Channel_SrcWidth = DMA_SrcWidth_Byte;
    DMA_InitStructure.DMA_Channel_DesBstSize = DMA_DesBst_1Data;
    DMA_InitStructure.DMA_Channel_SrcBstSize = DMA_SrcBst_1Data;
    DMA_InitStructure.DMA_Channel_TrsfSize = count;

    // RX - storing data in buffer
    DMA_InitStructure.DMA_Channel_SrcAdd = (DWORD)(&SPI_SD->DR);
    DMA_InitStructure.DMA_Channel_DesAdd = (DWORD)buff;
//        DMA_InitStructure.DMA_Channel_FlowCntrl = DMA_FlowCntrl2_DMA;  // peripheral_to_memory / DMA
    DMA_InitStructure.DMA_Channel_FlowCntrl = DMA_FlowCntrl_Perip2;  // peripheral_to_memory / SSP
    DMA_InitStructure.DMA_Channel_Src = DMA_SRC_SSP1_RX;
    DMA_InitStructure.DMA_Channel_Des = 0;
    DMA_Init(DMA_CHANNEL_RX, &DMA_InitStructure);
    DMA_ChannelSRCIncConfig(DMA_CHANNEL_RX, DISABLE);
    DMA_ChannelDESIncConfig(DMA_CHANNEL_RX, ENABLE);
    
    // TX - must send 0xFF
    DMA_InitStructure.DMA_Channel_SrcAdd = (DWORD)rw_workbyte;
    DMA_InitStructure.DMA_Channel_DesAdd = (DWORD)(&SPI_SD->DR);
//        DMA_InitStructure.DMA_Channel_FlowCntrl = DMA_FlowCntrl1_DMA;  // memory_to_peripheral / DMA
    DMA_InitStructure.DMA_Channel_FlowCntrl = DMA_FlowCntrl_Perip1;  // memory_to_peripheral / SSP
    DMA_InitStructure.DMA_Channel_Src = 0;
    DMA_InitStructure.DMA_Channel_Des = DMA_DES_SSP1_TX;
    DMA_Init(DMA_CHANNEL_TX, &DMA_InitStructure);
    DMA_ChannelSRCIncConfig(DMA_CHANNEL_TX, DISABLE);
    DMA_ChannelDESIncConfig(DMA_CHANNEL_TX, DISABLE);       // reusing the same data in memory

    // enable interrupts
    DMA_ITConfig(DMA_CHANNEL_RX, ENABLE);
    DMA_ITConfig(DMA_CHANNEL_TX, ENABLE);

    DMA_ITMaskConfig(DMA_CHANNEL_RX, DMA_ITMask_ITC, ENABLE);
    DMA_ITMaskConfig(DMA_CHANNEL_TX, DMA_ITMask_ITC, ENABLE);

    // Enable  TX/RX request in SSP controller
    SSP_DMACmd(SPI_SD, SSP_DMA_Receive, ENABLE);
    SSP_DMACmd(SPI_SD, SSP_DMA_Transmit, ENABLE);
    
    // Enable DMA channels
    DMA_ChannelCmd(DMA_CHANNEL_RX, ENABLE);
    DMA_ChannelCmd(DMA_CHANNEL_TX, ENABLE);

    // wait for end of transfer
    while (DMA_GetITStatus(DMA_CHANNEL_RX_IDX, DMA_TCRS) == RESET);


    // Disable DMA channels
    DMA_ChannelCmd(DMA_CHANNEL_RX, DISABLE);
    DMA_ChannelCmd(DMA_CHANNEL_TX, DISABLE);

    // Disable  TX/RX request in SSP controller
    SSP_DMACmd(SPI_SD, SSP_DMA_Transmit, DISABLE);
    SSP_DMACmd(SPI_SD, SSP_DMA_Receive, DISABLE);

    DMA_Cmd(DISABLE);
}  // str91_dma_transfer_receive

Outcomes