cancel
Showing results for 
Search instead for 
Did you mean: 

The signal Produced by DAC has errors

HBesi.1
Associate II

Hello,

I am building and electric field sensor. The driver signal for it is produced via DAC of the STM32F767zi microcontroller. The signal is 4 kHz and is generated at a sampling speed of 80 kHz via DMA and TIM6. As you can see from the picture the signal has errors in it like every 10-20 wavelengths there is 1 corrupted sample.

Best regards 0693W000008wDUqQAM.png

1 ACCEPTED SOLUTION

Accepted Solutions
HBesi.1
Associate II

The solution for the problem was changing the callback functions to:

void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)

{

//first half of adc is full

inbufPtr= &adc_val[0];

outbufPtr= &dac_val[0];

processDSP();

}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

{

inbufPtr= &adc_val[DATASIZE];

outbufPtr= &dac_val[DATASIZE];

processDSP();

}

cant really tell why this solved the problem. Occasionally it still happens that 1 sample is pulled high but it can be tolerated.

View solution in original post

7 REPLIES 7

Hello

seems like interruption from a higher priority interrupt routines causes DMA underruns.

But would underrun result in an unexpected value to be output? Wouldn't it produce a "stretch" rather than a "glitch"?

I don't think this can be solved without seeing substantial portion of the code.

JW

The code is simple I load values of a cosine table into the DMA buffer. My first thought was that the DAC hit its limit regarding speed. 80kHz maybe too fast.

I have done further measurements, the DMA halfbuffer length is 1024. I have 20 samples for one wavelength. 1024/20 results in 51,2 Wave lengths per halfbuffer. When I measure on the oscilloscope the glitch happens exactly at every 51,2 wavelengths. Could it be that the DMA does something strange?

Here is the code for the DMA init:

static void MX_DMA_Init(void)

{

 /* DMA controller clock enable */

 __HAL_RCC_DMA1_CLK_ENABLE();

 __HAL_RCC_DMA2_CLK_ENABLE();

 /* DMA interrupt init */

 /* DMA1_Stream5_IRQn interrupt configuration */

 HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);

 HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);

 /* DMA2_Stream0_IRQn interrupt configuration */

 HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);

 HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);

}

for the DMA callback:

//callback functions

void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)

{

//first half of adc is full

inbufPtr= &adc_val[0];

outbufPtr= &dac_val[DATASIZE];

processDSP();

}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

{

inbufPtr= &adc_val[DATASIZE];

outbufPtr= &dac_val[0];

processDSP();

}

and the DSP function where the DMA is filled:

void processDSP(void)

{

/*update buffers and and NCOs-------------------*/

for(int i=0;i<DATASIZE;i++)

{

//fill output buffer

outbufPtr[i]=(int)(2048+1000*cos_table[nco_f0.index]);

//read input into a buffer

incomming_buffer[i]=(float)inbufPtr[i]*ADC_gain; //ADC_gain=3.3/4095

//update local cosine and sine buffers

local_cosine_buffer[i]=cos_table[nco_f0.index];

local_sine_buffer[i]=-sin_table[nco_f0.index];

local_rect_buffer[i]=rect_table[nco_f0.index];

//update NCO

update_NCO(&nco_f0, COSINE_TABLE_SIZE);

}

I hope you can help

Regards

Piranha
Chief II

Is D-cache turned on? Is it managed properly?

Isn't the first or last value in the calculated array off? Read it out and check.

JW

HBesi.1
Associate II

The solution for the problem was changing the callback functions to:

void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)

{

//first half of adc is full

inbufPtr= &adc_val[0];

outbufPtr= &dac_val[0];

processDSP();

}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

{

inbufPtr= &adc_val[DATASIZE];

outbufPtr= &dac_val[DATASIZE];

processDSP();

}

cant really tell why this solved the problem. Occasionally it still happens that 1 sample is pulled high but it can be tolerated.