cancel
Showing results for 
Search instead for 
Did you mean: 

ADC and DMA timing calculation

machinist
Associate III

Hello,

I am trying to figure out how long an ADC in dual mode and DMA will run to take 24000 samples. I cannot get any proper values.

My init at startup:

bitset(SCB->ConfigCtrl, bit9);											// set STKALIGN in NVIC
	bitset(SCB->AIRCR, (0x5FA<<16)|(3<<8));										// init Priority, 4 Bit Pre-Emption, 4 Bit Subpriority
	bitset(FLASH->ACR, 0x12);												// Flash 1 wait state
	bitout(RCC->CFGR, bit16);												// HSE oscillator clock selected as PLL input clock (8MHz)
 	bitset(RCC->CFGR, (0b0111<<18));											// PLL input clock x 9 (72 MHz HCLK)
	bitout(RCC->CR,0x01010082); 												// enable ext. high frequency OSC and PLL, bit 16: HSE ON, Bit 24: PLL ON
	while(bittst(RCC->CR, bit17));											// wait until the HSE is ready
	while((RCC->CR & (1<<25)) == 0);											// wait until the PLL is ready
	bitset(RCC->CFGR, bit1);													// PLL selected as system clock
	while ((RCC->CFGR & 0x0C) != (2<<2)); 										// wait till SYSCLK is stabilized
	bitset(RCC->CFGR, (0b100<<8)); 											// APB low-speed prescaler (APB1) HCLK divided by 2
	bitset(RCC->CFGR, (0b000<<11));  											// APB high-speed prescaler (APB2) HCLK divided by 1
	bitset(RCC->CFGR, (0b10<<14));											// ADCPRE /6

So the ADC clock should be running at 12 MHz. Is this correct? Crystal is 8 MHz. I checked this with the config tool of the CubeIDE (which I am not using for the project). bitset simply does an x | value and bit out does a x = value.

So then I initialize the ADC and DMA before a sample:

bitset(RCC->AHBENR, bit0);												//enable DMA clock
	bitset(RCC->APB2ENR, bit9);												//enable ADC1 clock
	bitset(RCC->APB2ENR, bit10);												//enable ADC2 clock
 
	bitout(ADC1->CR1, 0);
	bitout(ADC1->CR2, 0);
	bitout(ADC2->CR1, 0);
	bitout(ADC2->CR2, 0);
	bitout(DMA1_Channel1->CCR, 0);
	bitout(DMA1->IFCR, 0xFFFF);
 
	bitset(ADC1->CR1, bit18|bit17|bit8);										//regular simultaneous mode
	bitset(ADC2->CR1, bit18|bit17|bit8);
	bitset(ADC1->CR2, bit20|0b111<<17|bit1);									//SWSTART, continuous
	bitset(ADC2->CR2, bit20|0b111<<17|bit1);
	bitset(ADC1->CR2, bit8);													//set DMA for dual ode
 
	bitset(DMA1_Channel1->CCR, 0b11<<12);										//set DMA1 channel priority to very high
	bitset(DMA1_Channel1->CCR, 0b10<<10);										//set memory size to 32bit
	bitset(DMA1_Channel1->CCR, 0b10<<8);										//set peripheral size to 32bit
	bitset(DMA1_Channel1->CCR, bit7|bit3|bit1);									//enable DMA1 memory increment mode and interrupt (for flags)
	bitset(DMA1_Channel1->CNDTR, buffer_size);									//set amount of reads to size of data buffer (can be changed later)
	bitset(DMA1_Channel1->CPAR, (uint32_t)&ADC1->DR);								//set peripheral address of DMA1 channel1 to ADC1 data register
	bitset(DMA1_Channel1->CMAR, (uint32_t)&data_adc);								//set memory address of DMA1 channel1 to location of data buffer
	bitset(DMA1_Channel1->CCR, bit0);
	vectors_set_priority(11, 15, 15);
	vectors_enable_interrupt(11);
 
	bitout(ADC1->SQR1, 0);													//one channel
	bitout(ADC2->SQR1, 0);
	bitout(ADC1->SQR3, 14);													//ADC1 channel 14 PC4
	bitout(ADC2->SQR3, 15);													//ADC2 channel 15 PC5
	if(adc_sample_time > 7) adc_sample_time &= 0b111;
	bitout(ADC1->SMPR1, adc_sample_time<<12);									//sampletime
	bitout(ADC2->SMPR1, adc_sample_time<<15);
	bitset(ADC1->CR2, bit0);
	bitset(ADC2->CR2, bit0);
	bitset(ADC1->CR2, bit3); 												//reset calibration
	bitset(ADC2->CR2, bit3);
	while(bittst(ADC1->CR2, bit3)); 											//wait for calibration reset
	while(bittst(ADC2->CR2, bit3));
	bitset(ADC1->CR2, bit2); 												//start calibration
	bitset(ADC2->CR2, bit2);
	while(bittst(ADC1->CR2, bit2)); 											//wait for calibration
	while(bittst(ADC2->CR2, bit2));
	bitset(ADC1->CR1, 0b0110<<16);											//ADC1 and ADC2 in dual mode

buffer_size is 24000, adc_sample_time is 0 at first.

So my question is, how do I calculate the time of one sample (and thus the total time) for the all the values of SMP 0 to 7 in the ADC_SMPR1?

It seems 1/12 MHz * the SMP value (1.5, 7.5, 13.5 etc) is not the solution. In the ref.man. it says one conversion at 72 MHz takes 1.17 µs. But how is this connected to the SMP in ADC_SMPR1?

Edit: I foud out about the 12 cycles + SMP. The values still dont match up. It seems the time is of by a factor of 2 as if the ADC clock was 24 MHz... Otherwise its ok.

:weary_face:

Thanks

0 REPLIES 0