cancel
Showing results for 
Search instead for 
Did you mean: 

Missing or unaligned sample in buffer when using ADC and DMA

RMoli.3
Associate III

I am using a STM32F767BITx LQFP208. I have to measure 12 channels. 6 channels measure the voltage and 6 other channels measure the intensity. Samples from voltage and insitensities shall be done as simultaneously as possible.

I am using ADC1(voltage) and ADC2 (current) in dual regular simultaneos mode only triggered by timer 2 and transfering the data to the buffer using DMA.

ADC 1

ADC1.PNG

ADC 2

ADC2.PNG

 

Both use identical DMA  configuration but with differente DMA stream:

RMoli3_0-1700488802068.png

 

My code is:

 

#define ADC_VOLTAGE &hadc1
#define ADC_CURRENT &hadc2
#define NUM_PHASES 3
#define NUM_NETWORKS 2
#define ADC_BURST_SAMPLE 64

uint16_t voltage_measurements[NUM_NETWORKS*NUM_PHASES*ADC_BURST_SAMPLE];
uint16_t intensity_measurements[NUM_NETWORKS*NUM_PHASES*ADC_BURST_SAMPLE];
bool voltage_read = false;
bool intensity_read = false;

/* Called once at boot */
void AC_Init()
{
	HAL_TIM_Base_Start_IT(&htim2);
	HAL_ADC_Start_DMA(ADC_VOLTAGE, (uint32_t*)&voltage_measurements, NUM_NETWORKS*NUM_PHASES*ADC_BURST_SAMPLE);
	HAL_ADC_Start_DMA(ADC_CURRENT, (uint32_t*)&intensity_measurements, NUM_NETWORKS*NUM_PHASES*ADC_BURST_SAMPLE);
}

/* IRQ from DMA */
void AdcManager_ReadComplete_IRQ(ADC_HandleTypeDef* AdcHandle)
{
	HAL_ADC_Stop_DMA(AdcHandle);
	
	if (AdcHandle == ADC_VOLTAGE) {
        voltage_read = true;
    } else if (AdcHandle == ADC_CURRENT){
        intensity_read = true;
    }
	
	/* Stop the measuring process if everything has finished */
    if ((voltage_read == true) && (intensity_read == true)) {
       HAL_TIM_Base_Stop_IT(&htim2);
    }
}

/* Periodic task called every 100ms (sampling time is much smaller than 100ms) */
void Task_AdcManager_100ms(void)
{
    if ((voltage_read == true) && (intensity_read == true)){
        voltage_read = false;
        intensity_read = false;
		
		/* Store the data in another buffer */
		memcpy(voltage_measurements_stable,voltage_measurements,sizeof(voltage_measurements));
        memcpy(intensity_measurements_stable,intensity_measurements,sizeof(intensity_measurements));
		
		/* Resetart samples */
        HAL_TIM_Base_Start_IT(&htim2);
		
        HAL_ADC_Start_DMA(ADC_VOLTAGE, (uint32_t*)&voltage_measurements, NUM_NETWORKS*NUM_PHASES*ADC_BURST_SAMPLE);
        HAL_ADC_Start_DMA(ADC_CURRENT, (uint32_t*)&intensity_measurements, NUM_NETWORKS*NUM_PHASES*ADC_BURST_SAMPLE);
     
    }
}

 

I would expect that samples are stored in the buffer always with the same order, thus when i de-interleave the samples I always get the same channel:

 

voltage_measurements[0] => channel 1 sample 0
voltage_measurements[1] => channel 2 sample 0
voltage_measurements[2] => channel 3 sample 0
voltage_measurements[3] => channel 4 sample 0
voltage_measurements[4] => channel 5 sample 0
voltage_measurements[5] => channel 6 sample 0
voltage_measurements[6] => channel 1 sample 1
voltage_measurements[7] => channel 2 sample 1
... an so on

 

But sporadically (maybe 1/500 time ) the sampels are not in the correct order (Note that it may be shifted 1 or various registers) 

 

voltage_measurements[0] = channel ? sample ?
voltage_measurements[1] = channel 1 sample 0
voltage_measurements[2] = channel 2 sample 0
voltage_measurements[3] = channel 3 sample 0
voltage_measurements[4] = channel 4 sample 0
voltage_measurements[5] = channel 5 sample 0
voltage_measurements[6] = channel 6 sample 0
voltage_measurements[7] = channel 1 sample 1
voltage_measurements[8] = channel 2 sample 1
....

 

 

Any idea of what could be causing this issues?

0 REPLIES 0