Question
STM32F4 DMA large block transfer
Posted on January 21, 2014 at 09:41
Hello to all,
I am writing application which uses peripheral to memory DMA transfer. When transfers aresmaller than 65535 items written in NDTR register everything is working fine.To be able to support large piece of data transfer I have modified DMA interrupt handler like this:void DMA2_Stream1_IRQHandler(void){ /* DMA Transfer Complete Interrupt */ if(DMA_GetITStatus(DMA2_Stream1, DMA_IT_TCIF1)) { DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1); if(pic_frame_size > 0) { DMA_Cmd(DMA2_Stream1, DISABLE); while((DMA_GetCmdStatus(DMA2_Stream1)) != DISABLE); if(pic_frame_size <= 65532) DMA_InitStructure.DMA_BufferSize = pic_frame_size; else DMA_InitStructure.DMA_BufferSize = 65532; pic_frame_size_proc = DMA_InitStructure.DMA_BufferSize; pic_frame_size -= pic_frame_size_proc; g_dma_cycle++; DMA_InitStructure.DMA_Memory0BaseAddr = (buffer + (SDRAM_DMA_ADDR_BLOCK * g_dma_cycle)); DMA_Init(DMA2_Stream1, &DMA_InitStructure); DMA_Cmd(DMA2_Stream1, ENABLE); while((DMA_GetCmdStatus(DMA2_Stream1)) != ENABLE); }else tx_ready = 1; }else if (DMA_GetITStatus(DMA2_Stream1, DMA_IT_HTIF1)) { DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_HTIF1); }else if (DMA_GetITStatus(DMA2_Stream1, DMA_IT_TEIF1)) { DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TEIF1); }else if (DMA_GetITStatus(DMA2_Stream1, DMA_IT_DMEIF1)) { DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_DMEIF1); }else if (DMA_GetITStatus(DMA2_Stream1, DMA_IT_FEIF1)) { DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_FEIF1); }}Data are transferred to the external 16 bit wide SDRAM, while peripheral is 32 bit wide.The problem I am experiencing is, that DMA_IT_TCIF1 is set even NDTR register is not 0,what is stated in data sheets and also observed when number of items are less then 65535. The second interrupt which happens is DMA_IT_HTIF1, which should not happen. I done DMA setup like this: DMA_InitStructure.DMA_Channel = DMA_Channel_1; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; pic_frame_size = FRAME_BUFFER_SIZE/4; if(pic_frame_size <= 65532) DMA_InitStructure.DMA_BufferSize = pic_frame_size; else DMA_InitStructure.DMA_BufferSize = 65532; pic_frame_size_proc = DMA_InitStructure.DMA_BufferSize; pic_frame_size -= pic_frame_size_proc; DMA_InitStructure.DMA_Memory0BaseAddr = buffer; DMA_InitStructure.DMA_PeripheralBaseAddr = DCMI_DR_ADDR; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream1, &DMA_InitStructure);Could be something wrong with DMA setup?I will appreciate any help.