AnsweredAssumed Answered

ADC DMA Configuration On STM32F303

Question asked by Palaima.Emmett on Aug 8, 2016
Latest reply on Aug 8, 2016 by Palaima.Emmett
I am trying to set up DMA access for the ADC channels on the STM32F303 Discovery. I have done this successfully on the STM32F4, and have been trying to transfer it over, but unfortunately the names of a lot of things in the libraries are named differently on the two chips, which makes this task somewhat difficult. The main thing I seem to be missing is the following function, which is present in the F4 libraries but not those of the F303:

ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);

My code compiles on the F303, but my DMA memory address always returns 0 in the debugger, regardless of the voltage on the ADC. Is the problem the missing function, and if so what would be the equivalent on the F303? Here is my code, please let me know if you see any problems:

#define ADC3_DR_ADDRESS     ((uint32_t)&ADC3->DR)

__IO uint16_t ADC3ConvertedValue = 0;
__IO uint16_t ADC3ManualConvo = 0;
__IO uint16_t calibration_value = 0;
__IO uint32_t TimingDelay = 0;

static void ADC3_DMAInit(void);
void Delay(__IO uint32_t nTime);

int main(void)
  /*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f30x.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f30x.c file

  while (1)
     //tried manual conversion, also returns 0
      // while(ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC) == RESET);
       //ADC3ManualConvo = ADC_GetConversionValue(ADC3);

static void ADC3_DMAInit(void){
       DMA_InitTypeDef        DMA_InitStructure;
       ADC_InitTypeDef       ADC_InitStructure;
       ADC_CommonInitTypeDef ADC_CommonInitStructure;
       GPIO_InitTypeDef      GPIO_InitStructure;

       // Enable DMA2, GPIOC and ADC34 clock
       RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
       RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
       RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC34, ENABLE);

       DMA_InitStructure.DMA_PeripheralBaseAddr = ADC3_DR_ADDRESS;
       DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC3ConvertedValue;
       DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
       DMA_InitStructure.DMA_BufferSize = 1;
       DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
       DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
       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(DMA2_Channel5, &DMA_InitStructure);

       // Enable DMA2 Channel3
       DMA_Cmd(DMA2_Channel5, ENABLE);

       // Enable GPIO Pins
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
       GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
       GPIO_Init(GPIOB, &GPIO_InitStructure);


       ADC_VoltageRegulatorCmd(ADC3, ENABLE);


       ADC_SelectCalibrationMode(ADC3, ADC_CalibrationMode_Single);

       while(ADC_GetCalibrationStatus(ADC3) != RESET );
       calibration_value = ADC_GetCalibrationValue(ADC3);

       ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
       ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;
       ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
       ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_OneShot;
       ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;
       ADC_CommonInit(ADC3, &ADC_CommonInitStructure);

       ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Enable;
       ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
       ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;
       ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;
       ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
       ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;
       ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;
       ADC_InitStructure.ADC_NbrOfRegChannel = 1;
       ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

       ADC_Init(ADC3, &ADC_InitStructure);

       /* ADC1 regular channel7 configuration */
       ADC_RegularChannelConfig(ADC3, ADC_Channel_1, 1, ADC_SampleTime_7Cycles5);

       //ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);
       //ADC3->CR2 |= (uint32_t)ADC_CR2_DDS;

       /* Enable ADC1 */
       ADC_Cmd(ADC3, ENABLE);

void Delay(__IO uint32_t nTime)
  TimingDelay = nTime;

  while(TimingDelay != 0);