Question
SPI DMA receive problem
Posted on November 18, 2013 at 14:03
Hi,
I am using SPI with DMA in STM32F427 for full duplex communication with another processor. My configuration for SPI and DMA is follows; SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2); // SCK GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2); // MISO GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2); // MOSI //Configure the pins used for SPI GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_Init(GPIOB, &GPIO_InitStructure); SPI_I2S_DeInit(SPI2); SPI_StructInit(&SPI_InitStructure); // SPI configuration SPI_InitStructure.SPI_Mode = SPI_Mode_Slave; SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI2, &SPI_InitStructure); SPI_Cmd(SPI2, ENABLE); /*********************************************************************************************/ // DMA for Tx DMA_DeInit(DMA1_Stream4); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & (SPI2->DR); DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t) &Tx_Buffer_to_AP1; DMA_InitStructure.DMA_BufferSize = 8; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralInc = DMA_MemoryInc_Disable; DMA_DoubleBufferModeConfig (DMA1_Stream4 ,(uint32_t) &Tx_Buffer_to_AP2, DMA_Memory_0); DMA_DoubleBufferModeCmd(DMA1_Stream4 , ENABLE); DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4; DMA_InitStructure.DMA_PeripheralBurst = DMA_MemoryBurst_INC4; DMA_Init(DMA1_Stream4 , &DMA_InitStructure); /************************************************************************************/ // DMA for Rx DMA_DeInit(DMA1_Stream3); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & (SPI2->DR); DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &Rx_Buffer_from_AP; DMA_InitStructure.DMA_BufferSize = 40968; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralInc = DMA_MemoryInc_Disable; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4; DMA_InitStructure.DMA_PeripheralBurst = DMA_MemoryBurst_INC4; DMA_Init(DMA1_Stream3 , &DMA_InitStructure); /***************************************************************************************/ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); DMA_ITConfig(DMA1_Stream3, DMA_IT_TC, ENABLE); DMA_ITConfig(DMA1_Stream4, DMA_IT_TC, ENABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);In the DMA interrupts, I clear the TCIF3 and TCIF4 flags and DMA is enabled in the main part of the code. There is no problem regarding the Tx part of the SPI, it works fine, but it only receives the data at first access of the master device and as a result, it goes into receive interrupt only once. I spent hours trying to figure out why this happens, but so far I have got no result. Can anybody can help me out on this? Thanks,Ali