2012-01-27 12:48 AM
Update:
Ok quick update I have now edited my code to only use DMA with the ADC and software trigger (DAC_SoftwareTriggerCmd) the DAC and it works fine. Therefore it seems to be a DMA issue. The new implementation I now have works but this is only test code yet and I was hoping to use DMA with both ADC and DAC when I get onto the full project.Is there a know issue with DMA or things I should watch out for?
I have not tested using ADC2 instead or ADC1 I think I read somewhere there is an issue with ADC1 and DMA is this correct?
Any pointers or links you know of would be a big help.
P.S. I'm using the STM32F107 on the STM3210C-Eval board but on the main project I will be using the STM32F417Original post:
Does anyone know of an issue with using both DAC and ADC together with DMA. In the code below if i program it as is the DAC will work, if I add in just the 7 lines of ''ADC_InitStructure'' and the ''ADC_Init'' call the DAC will not work. /* RCC configuration */ RCC_Configuration(); /* GPIO configuration */ GPIO_Configuration(); /* TIM2 Configuration */ /* Time base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 0x19; TIM_TimeBaseStructure.TIM_Prescaler = 0x0; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* TIM2 TRGO selection */ TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); /* DAC channel1 Configuration */ DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO; DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; DAC_Init(DAC_Channel_1, &DAC_InitStructure); /* DAC channel2 Configuration */ DAC_Init(DAC_Channel_2, &DAC_InitStructure); /* Fill Sine32bit table * for (Idx = 0; Idx < 32; Idx++) { DualSine12bit[Idx] = (Sine12bit[Idx] << 16) + (Sine12bit[Idx]); } */ DualSine12bit = (Sine12bit << 16) + (Sine12bit); mDELAY(2000); DMA_Configuration(); /* Enable DAC Channel1: Once the DAC channel1 is enabled, PA.04 is automatically connected to the DAC converter. */ DAC_Cmd(DAC_Channel_1, ENABLE); /* Enable DAC Channel2: Once the DAC channel2 is enabled, PA.05 is automatically connected to the DAC converter. */ DAC_Cmd(DAC_Channel_2, ENABLE); /* Enable DMA for DAC Channel2 */ DAC_DMACmd(DAC_Channel_2, ENABLE); /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); /* ADC1 configuration ------------------------------------------------------* ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; //2; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channel7&8 configuration */* ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 2, ADC_SampleTime_239Cycles5);*/ /* ADC1 regular channel14 configuration */ // ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_239Cycles5); /* Enable ADC1 DMA * ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 * ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibaration register * ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register * while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibaration * ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration * while(ADC_GetCalibrationStatus(ADC1)); /* Start ADC1 Software Conversion * ADC_SoftwareStartConvCmd(ADC1, ENABLE);*/while(1) ... etc void DMA_Configuration(void){ DMA_InitTypeDef DMA_InitStructure; /* DMA1 channel1 configuration ----------------------------------------------*/ //ADC Configuration DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADCConvertedValue; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 128; 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_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable DMA1 Channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); /* DMA2 channel4 configuration */ //DAC Configuration DMA_DeInit(DMA2_Channel4); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)DAC_DHR12RD_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&DualSine12bit; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA2_Channel4, &DMA_InitStructure); /* Enable DMA2 Channel4 */ DMA_Cmd(DMA2_Channel4, ENABLE);}2012-01-28 08:23 AM
See the DAC, ADC and DMA sections of the reference manual for your device for constraints on DMA usage. When you use ADC2, DMA mode is available only in dual ADC1 & 2 mode, where ADC1 is the master.
When you port to the F4, the DMA design is different, so the code will require change. Your sample code uses ADC in circular mode, running continuously, while the DAC is triggered by a timer. DMA1 has priority over DMA2. And we don't see any NVIC initialization. Perhaps the continuous ADC is preventing DAC operation due to priorities. For your application, I recommend that the ADC continuous conversion be disabled. Enable and disable conversion for each group of channels sample, which could be on a timer. Cheers, Hal2012-06-12 10:34 PM