2013-07-30 01:16 AM
Hi all,
I am having problems with configuring DMA for SPI ( SPI is working without DMA).Did anyone use DMA with SPI3 on SMT32F2 ? Pls help me figuring out the issue...here is my DMA code:Problem:It is looping @ while (DMA_GetCmdStatus(DMA1_Stream3) != DISABLE) after Tx. DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure1; DMA_InitTypeDef DMA_InitStructure2; NVIC_InitTypeDef NVIC_InitStructure2; /* Enable DMA clock */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); DMA_DeInit(DMA1_Stream3); while (DMA_GetCmdStatus(DMA1_Stream3) != DISABLE){ } DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & (SPI3->DR); DMA_InitStructure.DMA_Channel = DMA_Channel_3; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)0; DMA_InitStructure.DMA_BufferSize = 1; DMA_Init (DMA1_Stream3, &DMA_InitStructure); DMA_ITConfig(DMA1_Stream3, DMA_IT_TC, ENABLE); SPI_I2S_DMACmd (SPI3, SPI_I2S_DMAReq_Tx, ENABLE); NVIC_InitStructure1.NVIC_IRQChannel = DMA1_Stream3_IRQn; NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 8; NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 8; NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE; NVIC_Init (&NVIC_InitStructure1); DMA_DeInit (DMA1_Stream0); while (DMA_GetCmdStatus (DMA1_Stream0) != DISABLE); DMA_StructInit (&DMA_InitStructure2); DMA_InitStructure2.DMA_PeripheralBaseAddr = (uint32_t) & (SPI3->DR); DMA_InitStructure2.DMA_Channel = DMA_Channel_3; DMA_InitStructure2.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure2.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure2.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure2.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure2.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure2.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure2.DMA_Priority = DMA_Priority_High; DMA_InitStructure2.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure2.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure2.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure2.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_InitStructure2.DMA_Memory0BaseAddr = (uint32_t)0; DMA_InitStructure2.DMA_BufferSize = 1; DMA_Init (DMA1_Stream0, &DMA_InitStructure2); /*Cofigure transfer complete interrupt*/ DMA_ITConfig (DMA1_Stream0, DMA_IT_TC, ENABLE); // Transfer complete interrupt mask NVIC_InitStructure_RX.NVIC_IRQChannel = DMA1_Stream0_IRQn; NVIC_InitStructure_RX.NVIC_IRQChannelPreemptionPriority = 7; NVIC_InitStructure_RX.NVIC_IRQChannelSubPriority = 7; NVIC_InitStructure_RX.NVIC_IRQChannelCmd = ENABLE; NVIC_Init (&NVIC_InitStructure_RX); /* Enable dma rx request. */ SPI_I2S_DMACmd (SPI3, SPI_I2S_DMAReq_Rx, ENABLE); SPI_I2S_DMACmd (SPI3, SPI_I2S_DMAReq_Tx || SPI_I2S_DMAReq_Rx, ENABLE); /* Tx */ unsigned char temp[4]; temp[0] = 0xA0; temp[1] = 0xB1; temp[2] = 0x5C; temp[3] = 0xC3; DMA1_Stream3->PAR = (uint32_t) & (SPI3->DR); DMA1_Stream3->NDTR = (uint32_t) 4; DMA1_Stream3->M0AR = (uint32_t) &(temp[0]); DMA_Cmd (DMA1_Stream3, ENABLE); while (DMA_GetCmdStatus(DMA1_Stream3) != DISABLE) { printf(''success\n''); } /* Rx */ DMA1_Stream0->PAR = (uint32_t) & (SPI3->DR); DMA1_Stream0->NDTR = (uint32_t) 4; DMA1_Stream0->M0AR = (uint32_t) &(temp[0]); DMA_Cmd (DMA1_Stream0, ENABLE); while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) == SET); DMA1_Stream3->PAR = (uint32_t) & (SPI3->DR); DMA1_Stream3->NDTR = (uint32_t) 4; DMA1_Stream3->M0AR = (uint32_t) &(temp[0]) ; DMA_Cmd (DMA1_Stream3, ENABLE); while (DMA_GetCmdStatus(DMA1_Stream3) != DISABLE) { printf(''success\n''); } Thanks in advance.2013-07-30 03:44 AM
You've just ENABLEd the DMA stream, so it is not unreasonable that it != DISABLE...
JW2013-07-30 04:34 AM
hi waclawek.jan,
Thanks for the reply,
According my understanding it should trigger the transfer as soon as the DMA stream is enabled,and hardware disables the DMA stream at the end of the transfer, so I was waiting for it.
I tried even checking for Tx complete interrupt but still same issue.
while(!DMA_GetFlagStatus(DMA1_Stream3, DMA_FLAG_TCIF3));
and observed a weird case i.e., Tx complete interrupt is getting triggered after disabling the DMA.
2013-07-30 05:03 AM
Ah, I see.
--- Why are you trying to use DMA1 Stream3/Channel3 and Stream0/Channel3? According to RM0033 Table 22, those are mapped to I2S2_ext_RX and I2S3_ext_RX respectively. JW2013-07-30 05:51 AM
Hi JW,
Thanks you very much pointing it out. It really helped a lot.I thought we can use any stream/channel for SPI interface.ThanksSagar