cancel
Showing results for 
Search instead for 
Did you mean: 

STM32f4 ADC DMA Discontinuities

BastelBaus
Associate II

I have a problem and currently no clue how to further debug. Maybe one coudl help me.

 

I use STM32f4 to capture with ADC1 3 signals with 1Mhz (so 333kHz per channel) triggered by a timer and transfered via DMA. I have a DMA buffer of 3*2*100 (so 100 samples per channel per half DMA). When DMA is Half/Full filed, I store the data in a second buffer with 10 times 100 samples. Using a test sin signal ~23kHz, I get discontinuities at each 100 sample border.

 

I check the code several times but could not find an error and it seams like ADC sampling is kind of pausing at each DMA Half/Full callback call (which seams not plausible)

BR, BastelBaus

 

The faulty output with discontinuities each 100 samples:

BastelBaus_0-1759491791658.png

 

Timer configuration (96Mhz clock)

BastelBaus_1-1759491864289.png

ADC configuration

BastelBaus_2-1759491888224.pngBastelBaus_3-1759491900824.png

 

Init the ADC and callbacks

void ADC_init(void) {
    HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); // ADC trigger
    HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&adc_samples,ADC_N ); 
} // void ADC_init(void) {
// Called when first half of buffer is filled
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) {
    if (new_data != NULL) buffer_overrun = true;
    new_data = first_half_adc_buffer;    
} // void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) {

// Called when buffer is completely filled
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
    if (new_data != NULL) buffer_overrun = true;
    new_data = second_half_adc_buffer;
} // void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {

 

Buffereing 10 frames and transmitting over UART

bool transmitting_data = false;
#define ADC_SAMPLE_PATCHES 10
uint16_t adc_patch_buffer[ADC_SAMPLE_PATCHES][ADC_N/2];
int patch_i = 0;

void ADC_clb_process_adc_data(volatile uint16_t* source_adr, size_t samples) {
	//print_debug("ADC_clb_process_adc_data: samples=%d\n",samples);

	if (transmitting_data) return;

	memcpy(adc_patch_buffer[patch_i],source_adr,samples*sizeof(uint16_t));
	patch_i = (patch_i+1)%ADC_SAMPLE_PATCHES;


	return;
} // void CLB_process_adc_data(void) {



void print_adc_raw_data(CHANNEL_t channel, PARAMETER_t par) {
    transmitting_data = true;
    uint8_t channels[3] = {CHANNEL_X,CHANNEL_Y,CHANNEL_Z};

    // output each channel
    for(uint8_t k=0;k<3;k++)
        if (channel == channels[k] || channel == CHANNEL_ALL) { 
                print_adc("");
                for(uint8_t a=0;a<ADC_SAMPLE_PATCHES-1;a++) {
                    uint8_t b = (a+patch_i+1)%ADC_SAMPLE_PATCHES;
                    for(int i=0;i<ADC_N/3/2;i++) printf("%d;",adc_patch_buffer[b][i*3+k]);                    
                }
                printf("\n"); 
                fflush(stdout); 
                HAL_Delay(100); // TODO: check this, nbeeded to have it stable ???
            }
        }

    fflush(stdout);    
    transmitting_data = false;

} // void print_adc_raw_data(CHANNEL_t channel, PARAMETER_t par) {

 

 

 

 

0 REPLIES 0