2007-01-30 03:56 AM
The Problem in SSP0+DMA operation
2011-05-17 12:35 AM
The Problem in SSP0+DMA operation
I want to use DMA for both SSP0's RX and TX at the same time I use the DMA Channel1 for SSP0 RX and DMA Channel2 for SSP0 TX, SSP0 is master mode 1. In SSP0 looptest mode, the following code is OK. SSP_LoopBackMode(SSP0,ENABLE); Start_SSPO_RX_DMA(BuRx,20); Start_SSPO_TX_DMA(BuTx,20); Or SSP_LoopBackMode(SSP0,ENABLE); Start_SSPO_RX_DMA(BuRx,20); Start_SSPO_TX_DMA(BuTx,20); 2. Connect MOSI and MISO together, the following code is OK. Start_SSPO_RX_DMA(BuRx,20); Start_SSPO_TX_DMA(BuTx,20); or Start_SSPO_TX_DMA(BuTx,20); Start_SSPO_RX_DMA(BuRx,20); 3. Connect MOSI and MISO to a peripheral, the following code is OK. Start_SSPO_TX_DMA(BuTx,20); Delay_us(10); Start_SSPO_RX_DMA(BuRx,20); 4. Connect MOSI and MISO to a peripheral, the following code is Error. Why ? Start_SSPO_TX_DMA(BuTx,20); Start_SSPO_RX_DMA(BuRx,20); the result are: BuRx[0] is a unknown data; BuRx[1] is the same as BuTx[0]; BuRx[2] is the same as BuTx[1]; ... ... /----------------------------------------------------------------/ #define DMA_Tx DMA_Channel3 #define DMA_Tx_No 3 #define DMA_Tx_ENABLE DMA_Tx->CCNF |= 0x00000001 #define DMA_Tx_DISABLE DMA_Tx->CCNF &= ~0x00000001 #define DMA_Tx_ACTIVE (DMA_Tx->CCNF & 0x00020000) #define DMA_Tx_End (DMA->TCRISR & (1<#define DMA_Tx_WaitEnd while (! DMA_Tx_End) #define DMA_Tx_ClrEnd (DMA->TCICR = (1<#define DMA_Tx_ClrErr (DMA->EICR = (1<#define DMA_Rx DMA_Channel2 #define DMA_Rx_No 2 #define DMA_Rx_ENABLE DMA_Rx->CCNF |= 0x00000001 #define DMA_Rx_DISABLE DMA_Rx->CCNF &= ~0x00000001 #define DMA_Rx_ACTIVE (DMA_Rx->CCNF & 0x00020000) #define DMA_Rx_End (DMA->TCRISR & (1<#define DMA_Rx_WaitEnd while (! DMA_Rx_End) #define DMA_Rx_ClrEnd (DMA->TCICR = (1<#define DMA_Rx_ClrErr (DMA->EICR = (1<u16 BuRx[20]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; u16 BuTx[20]={8,8,8,8,8,8,8,8,8,8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}; void init_DMA() { DMA_InitTypeDef DMA_InitStruct; DMA_Cmd(ENABLE); // Enable the DMA // DMA For SSP0 Tx DMA_Tx_DISABLE; DMA_SyncConfig(DMA_SSP0_TX_Mask, ENABLE); DMA_StructInit(&DMA_InitStruct); DMA_InitStruct.DMA_Channel_LLstItm = 0; DMA_InitStruct.DMA_Channel_DesAdd = (u32)(&SSP0->DR); DMA_InitStruct.DMA_Channel_SrcWidth = DMA_SrcWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesWidth = DMA_DesWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesBstSize= DMA_DesBst_1Data; DMA_InitStruct.DMA_Channel_SrcBstSize= DMA_SrcBst_1Data; DMA_InitStruct.DMA_Channel_FlowCntrl = DMA_FlowCntrl1_DMA; DMA_InitStruct.DMA_Channel_Des = DMA_DES_SSP0_TX; DMA_Init(DMA_Tx,&DMA_InitStruct); SSP_DMACmd(SSP0,SSP_DMA_Transmit,ENABLE); // DMA For SSP0 Rx DMA_Rx_DISABLE; DMA_SyncConfig(DMA_SSP0_RX_Mask, ENABLE); DMA_StructInit(&DMA_InitStruct); DMA_InitStruct.DMA_Channel_LLstItm = 0; DMA_InitStruct.DMA_Channel_SrcAdd = (u32)(&SSP0->DR); DMA_InitStruct.DMA_Channel_SrcWidth = DMA_SrcWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesWidth = DMA_DesWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesBstSize= DMA_DesBst_1Data; DMA_InitStruct.DMA_Channel_SrcBstSize= DMA_SrcBst_1Data; DMA_InitStruct.DMA_Channel_FlowCntrl = DMA_FlowCntrl2_DMA; DMA_InitStruct.DMA_Channel_Src = DMA_SRC_SSP0_RX; DMA_Init(DMA_Rx,&DMA_InitStruct); SSP_DMACmd(SSP0,SSP_DMA_Receive,ENABLE); } /************************************************** Start DMA Tx **************************************************/ void Start_SSPO_TX_DMA(void *Bu, u16 Count) { DMA_Tx_DISABLE; DMA_Tx_ClrEnd; DMA_Tx_ClrErr; DMA_Tx->SRC=(u32)Bu; DMA_Tx->CC = DMA_SrcWidth_HalfWord | DMA_ChannelSRCInc | 0x80000000 | DMA_DesWidth_HalfWord | (Count & 0x0FFF); DMA_Tx_ENABLE; } /************************************************** Start DMA Rx **************************************************/ void Start_SSPO_RX_DMA(void *Bu, u16 Count) { DMA_Rx_DISABLE; DMA_Rx_ClrEnd; DMA_Rx_ClrErr; DMA_Rx->DES=(u32)Bu; DMA_Rx->CC = DMA_SrcWidth_HalfWord | DMA_ChannelDESInc | 0x80000000 | DMA_DesWidth_HalfWord | (Count & 0x0FFF); DMA_Rx_ENABLE; }