2009-12-22 07:42 PM
SPI-DMA slave receive problem
2011-05-17 04:35 AM
Hi,
i configured the SPI3 of an STM32F103 as a Slave to receive data from another controller via DMA transfer (not an STM32). The configuration of the DMA is like this:Code:
DMA_DeInit(DMA2_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SPI3_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SPI3_Buffer_Rx; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 8192; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA2_Channel1, &DMA_InitStructure); DMA_ITConfig(DMA2_Channel1, DMA_IT_TC, ENABLE); The received data are blocks of 8k size. So after receiving the Transfer Complete Interrupt I would expect that the first element would be placed as the first element in the receive bufer. But this only works in very rare cases. Instedd of this, most of the times the received data will be start anywhere in the receive buffer. I also tried to set the DMA_Mode = DMA_Mode_Normal and to releoad the counter manually like this, but without success:Code:
DMA_Cmd(DMA2_Channel1, DISABLE); DMA2_Channel1->CNDTR = 8192; DMA_Cmd(DMA2_Channel1, ENABLE); How can i get the recieved data starting from 0 in the receive buffer? Best regards Tom2011-05-17 04:35 AM
Hi ralf1303,
Normally your SPI useful data will be transferred only upon DMA request.Hence are you sure, you are enabling the SPI3 peripheral request using SPI_I2S_DMACmd()function? Cheers.2011-05-17 04:35 AM
Hi armmcu.engineer,
no i don't forgot to call SPI_I2S_DMACmd(). The SPI works. In the meantime I modified the settings. I set DMA_InitStructure.DMA_Mode to DMA_Mode_Normal. Previous setting was DMA_Mode_Circular. I also increased the DMA buffer. At the end of the DMA Interrupt handler I reset the buffer:Code:
DMA_Cmd(DMA2_Channel1, DISABLE); DMA2_Channel1->CNDTR = 15000; DMA_Cmd(DMA2_Channel1, ENABLE); With these modifications the incoming data are starting a 0 in most cases. Sometimes it happens that the data starting only at position 1. In this case I filter the valid packet out of the buffer. So now it seems to work much better than before. Best regards