2014-09-17 05:05 PM
I want to change polling SPI to DMA SPI. Now I get stuck and have looked up lots of material. None of them is working for me.
The original polling SPI code works fine. I implemented the following code for the DMA. Something weird happened here. It seems there is no problem for TX but the RX DMA gets transfer error. SxNDT register still 0x78. I don't know the reason.1. Should the amount of RX data be the same as TX? But Rx doesn't receive anything.2. The TX source is from external memory by FMC. Does it matter?void SPI1_DMA_Configuration(){ DMA_InitTypeDef DMA_InitStructure; DMA_Cmd(DMA2_Stream3, DISABLE); DMA_Cmd(DMA2_Stream2, DISABLE); DMA_ClearITPendingBit(DMA2_Stream3,DMA_IT_TCIF3); DMA_ClearITPendingBit(DMA2_Stream2,DMA_IT_TCIF2); DMA_DeInit(DMA2_Stream3); while (DMA_GetCmdStatus (DMA2_Stream3) != DISABLE); DMA_StructInit(&DMA_InitStructure); // TX DMA_InitStructure.DMA_Channel = DMA_Channel_3; DMA_InitStructure.DMA_PeripheralBaseAddr = ((uint32_t)(&SPI1->DR)); DMA_InitStructure.DMA_BufferSize = 10000; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) HEADER_ADDR; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream3, &DMA_InitStructure); // RX DMA_DeInit(DMA2_Stream2); while (DMA_GetCmdStatus (DMA2_Stream2) != DISABLE); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_Channel = DMA_Channel_3; DMA_InitStructure.DMA_PeripheralBaseAddr = ((uint32_t)(&SPI1->DR)); DMA_InitStructure.DMA_BufferSize = 120; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &SPIReceiveBuffer[0]; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream2, &DMA_InitStructure); SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Tx, ENABLE); SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Rx, ENABLE); while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); // wait for empty TX buffer DMA_Cmd(DMA2_Stream2, ENABLE); DMA_Cmd(DMA2_Stream3, ENABLE); while ( DMA_GetCmdStatus(DMA2_Stream3) != ENABLE ); while ( DMA_GetCmdStatus(DMA2_Stream2) != ENABLE ); SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, DISABLE); SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, DISABLE);}This is my first time to ask questions. Thank you for your help.2014-09-18 08:13 AM
http://www.vocabulary.com/dictionary/symmetrical
, ie NOT 10000 vs 200 Last time I cleaned up an SPI1 DMA Tx/Rx example2014-09-18 08:16 AM
JW, thank you for this. I got stuck on this for a while. Never thought about this.
How can I make sure the parameters I declared NOT using CCM?