2015-02-13 07:45 AM
I am using stm32f427 chip with external SDRAM. I tried to implement ADC triple mode but I found the raw data transferred to external memory by DMA is duplicated or corrupted.
#define SDRAM_BANK1_1MB_ADDR (0xC0100000)void SetupADC_Receive(void){ ADC_InitTypeDef ADC_InitStructure; DMA_Cmd(DMA2_Stream0, DISABLE); // Disable the sampling ADC's ADC_Cmd(ADC1, DISABLE); ADC_Cmd(ADC2, DISABLE); ADC_Cmd(ADC3, DISABLE); // Disable the ADC's DMA interface ADC_DMACmd(ADC1, DISABLE); ADC_DMACmd(ADC2, DISABLE); ADC_DMACmd(ADC3, DISABLE); // Configure the DMA for the sampling (also enables the DMA). SetupDMA(); SetupADC_common(); ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T5_CC1; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = 3; { ADC_Init(ADC1, &ADC_InitStructure); ADC_DiscModeChannelCountConfig(ADC1, 3); ADC_DiscModeCmd(ADC1, ENABLE); // ADC Regular Channel Configuration ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 3, ADC_SampleTime_3Cycles); } { ADC_Init(ADC2, &ADC_InitStructure); // ADC Regular Channel Configuration ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(ADC2, ADC_Channel_14, 2, ADC_SampleTime_3Cycles); // NOT USED -- for interleaving alignment ADC_RegularChannelConfig(ADC2, ADC_Channel_2, 3, ADC_SampleTime_3Cycles); } { ADC_Init(ADC3, &ADC_InitStructure); // ADC Regular Channel Configuration ADC_RegularChannelConfig(ADC3, ADC_Channel_4, 1, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(ADC3, ADC_Channel_5, 2, ADC_SampleTime_3Cycles); // NOT USED -- for interleaving alignment ADC_RegularChannelConfig(ADC3, ADC_Channel_8, 3, ADC_SampleTime_3Cycles); } ADC_DMACmd(ADC1, ENABLE); // Enable the sampling ADC's ADC_Cmd(ADC2, ENABLE); ADC_Cmd(ADC3, ENABLE); ADC_Cmd(ADC1, ENABLE);}void SetupDMA(void){ DMA_InitTypeDef DMA_InitStructure; DMA_DeInit(DMA2_Stream0); ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE); DMA_Cmd(DMA2_Stream0, DISABLE); DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_PeripheralBaseAddr = ((uint32_t)(&ADC->CDR)); DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)SDRAM_BANK1_1MB_ADDR; DMA_InitStructure.DMA_BufferSize = 0x1800 * 3; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA_Mode_Circular;// DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream0, &DMA_InitStructure); // Enable DMA stream. DMA_Cmd(DMA2_Stream0, ENABLE);}void SetupADC_common(void){ // Initialize the ADC common registers. ADC_CommonInitTypeDef ADC_CommonInitStructure; ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_RegSimult; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; ADC_CommonInit(&ADC_CommonInitStructure);}Here is the dump. From C01000000, we can see the duplicated data.What confused me is that I did ADC_Mode_Independent ADC_DMAAccessMode_Disabled only to transfer ADC1 data and the data is totally correct. From my point of view, it should be some part related to ADC common where I set it wrong. Can somebody help me find out this?2015-02-13 08:25 AM
Try one of the example of this that I've posted and confirm if that does, or does not, function correctly with a SDRAM destination. I don't really have the time/patience to keep fixing everyone's broken code. Start with something that works, then push that till it breaks.
2015-02-16 09:13 AM
ok The problem is fixed. It needs to put the code below.
ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);Thanks anyway.