2008-01-24 12:46 AM
Can't get DMA to work with ADC1
2011-05-17 03:22 AM
I am having difficulty getting DMA to work with ADC1 working on the STM3210B-EVAL board. I believe I have correctly configured the DMA, clocks, and ADC1. The ADC appears to be working OK.
I want to convert channels 10-13, 16, and 17. I am starting conversion by writing the ADON bit. Unfortunately, I can't examine the DMA registers with my probe for some reason. After starting a conversion, I wait for the end of conversion and look at my memory buffer, expecting to see the results of all six conversions. Instead, I see all 0s, although what appears to be a valid result for the temperature sensor is in the ADC_DR register. This is a mystery in itself as the reference voltage should be the last value converted :-). I have examined the DMA examples from the firmware library with no luck. Can anyone see something I am missing in the following code snippets? /********* clock configuration ***************/ CLOCKRCC->RCC_CR = 0x00010000; // PLL off, clock source is HSE CLOCKRCC->RCC_CFGR = 0x04010000; // System clock on MCO output pin, CLOCKRCC->RCC_AHBENR = 0x00000015; // DMA clock enabled CLOCKRCC->RCC_APB2ENR= 0x00005A1D; // USART1, SPI1, TIM1, ADC1, // GPIOC, GPIOB, GPIOA clocks enabled CLOCKRCC->RCC_APB1ENR= 0x12002004; // PWR, CAN, SPI2, TIM4 clocks enabled /******* GPIOC configuration (ADC10-13) ************/ GPIOC->GPIOx_CRL = 0x42440000; GPIOC->GPIOx_CRH = 0x44424442; GPIOC->GPIOx_ODR = PORTC_OUTPUTS; /********************************************************* * Configure DMA channel 1 to transfer from ADC to memory *********************************************************/ DMA->DMA_CPAR1 = ADC1_DR_Address; //ADC1->ADC_DR; // Peripheral base address DMA->DMA_CMAR1 = (u32)&nADRawData[0]; // Memory base address DMA->DMA_CNDTR1 = 6; // 6 data transfers DMA->DMA_CCR1 = DMA_PRIHIGH | DMA_M16BIT | DMA_P16BIT | DMA_MINC; // | DMA_TCIE; DMA->DMA_CCR1 |= DMA_EN; /********************************************************* * Configure ADC1 for scan mode, channels 10-13, 16, 17. *********************************************************/ ADC1->ADC_CR1 = ADC_SCAN; ADC1->ADC_CR2 = ADC_TSVREFE | ADC_DMA | ADC_ADON; // Temp sensor, DMA, ADC on ADC1->ADC_SMPR1 = 0x00FC0FFF; // 239.5 cycles for each scan ADC1->ADC_SQR1 = 0x00500000; // 6 conversions at a time ADC1->ADC_SQR2 = 0x00000000; ADC1->ADC_SQR3 = 0x2306B16A; // Channels 10-13, 16, 17 /********** Later, this code is executed ************/ /********************************************************* * Start conversion and transfer to memory *********************************************************/ DMA->DMA_CPAR1 = ADC1_DR_Address; //ADC1->ADC_DR; // Peripheral base address DMA->DMA_CMAR1 = (u32)&nADRawData[0]; // Memory base address DMA->DMA_CNDTR1 = 6; // 6 data transfers ADC1->ADC_SR &= ~ADC_STRT; // Clear conversion started flag ADC1->ADC_CR2 |= ADC_ADON; // Start group conversion while ((ADC1->ADC_SR & ADC_EOC) == 0);2011-05-17 03:22 AM
Dear FriarTuck,
You should look at ADC Examples instead of DMA one, There are 5 examples to run ADC in different modes & running with DMA. :) May be this will help you to have your application running smoothly . STOne-322011-05-17 03:22 AM
Thanks for the feedback. I finally got my debug probe to allow me to look at DMA registers without crashing, and it showed me that the CNDTRx register was not updating because the DMA channel was enabled. I disabled it before updating the register and now everything works OK.
Thanks again!