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); } }
View more

 

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