2011-01-01 01:58 PM
When I use DMA to trasfer data from memory to SPI2 everything works well util I try do another trasfer, then I reload NDTR register I try enable DMA, but nothing happens, there are no errors in setatus register, just cant set EN bit for stream. When I do deinitialization of DMA stream, and initialize again, it works well.
Siple code where problem occurs: SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI2, &SPI_InitStructure); SPI_Cmd(SPI2, ENABLE); DMA_DeInit(DMA1_Stream4); DMA_Cmd(DMA1_Stream4, DISABLE); DMA_InitTypeDef DMA_InitStructure; DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) (&(SPI2->DR)); DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) (&buuf); DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_BufferSize = (uint32_t) 10; 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_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA1_Stream4, &DMA_InitStructure); DMA_Cmd(DMA1_Stream4, ENABLE); //THIS TRANSATION WORK WELL SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); while (DMA_GetCurrDataCounter(DMA1_Stream4)); DMA_Cmd(DMA1_Stream4,DISABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, DISABLE); while (DMA1_Stream4->CR & 0x01 == 1); DMA1_Stream4->NDTR=17; DMA_Cmd(DMA1_Stream4,ENABLE); //THIS WILL NOT ENABLE STREAM EN=0 SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); //HANG HERE while (DMA_GetCurrDataCounter(DMA1_Stream4)); DMA_Cmd(DMA1_Stream4,DISABLE); while (DMA1_Stream4->CR & 0x01 == 1); DMA1_Stream4->M0AR = (uint32_t) (&buuf); DMA1_Stream4->NDTR=27; DMA_Cmd(DMA1_Stream4,ENABLE); #dma-spi2011-01-01 02:43 PM
The DMA mode is Normal, not Circular. I believe you have to reset the address pointer (MOAR) each time.
Happy New Year, Hal2012-01-02 09:09 AM
I solved problem, to start new DMA transation I have to reset ''DMA Transfer complete interrupt flag'' TCIF, I'm not using interrupts and I have no idea why I should reset this flag, especialy there is no a single word about it in Reference Manual DM00031020