ADC periodic averaging

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

ADC periodic averaging

1,221 Views
benedek_kupper
Contributor III

We want to do periodic averaging of ADC measurements, so e.g. 32 samples are taken in 2ms intervals, averaged and the SW processing starts only after all the 32 measurements are complete. We want to keep the core halted with WFI to reduce power consumption, so we want to avoid interrupts for every conversion.

My initial approach was to configure ADC to hardware average 32 samples, and trigger a conversion with PIT in every 2ms (through ADC_ETC). Attached the MEX configuration for this setup (adc-averaging-1). This isn't working as expected, I get the DONE interrupt in every 2ms, so it seems the hardware averaging is either not working this way, or all 32 conversions are performed when one trigger is received.

Then I tried to find an ADC + DMA example, but there are no prepared examples, only some other platform examples are circulating on the forum. My idea was to transfer the ADC_ETC trigger result register content with DMA with a sizeof(uint32_t) * 32 major count, then calculate the average on the DMA output buffer. Attached the MEX configuration for this setup (adc-averaging-2). This is also not working as expected, I get the DMA transfer complete interrupt in every 2ms (so with every DONE signal), and the whole buffer is filled with the very same register value repeated 32 times.

 

So my question is, how to achieve the desired ADC averaging measurement without CPU intervention for every conversion complete? What's wrong with these two configurations?

Labels (1)
0 Kudos
5 Replies

1,186 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello @benedek_kupper,

I think the hardware average in the ADC module is not the way to achieve this. This function only sets in the register the result of the average, so if you want to obtain each conversion is better to set the hardware average to 1 and link the DMA to move the 32 conversions.

Best Regards,

Alexis Andalon

0 Kudos

1,182 Views
benedek_kupper
Contributor III

Hi Alexis,

Yes, as I mentioned, the hardware averaging didn't work for me, so I tried to transfer with the DMA (approach 2), but the DMA fills up all 32 samples with the same measurement, and I get the DMA complete interrupt for each  conversion, not when 32 conversions are done.

0 Kudos

1,172 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello @benedek_kupper,

Would be possible to share the project to check this behavior? 

Best Regards,

Alexis Andalon

0 Kudos

1,082 Views
benedek_kupper
Contributor III

Any update on this?

0 Kudos

1,162 Views
benedek_kupper
Contributor III

Hi Alexis,

I'm attaching the code that accompanies the generated SDK code made with previously attached adc-averaging-2.

uint16_t g_adc_results[32][2];
edma_transfer_config_t DMA0_ADC_TRANSFER0_config;

void Analog_Init()
{
ADC_InitPins();
XBARA_Init(XBARA);
XBARA_SetSignalsConnection(XBARA, kXBARA1_InputPitTrigger0, kXBARA1_OutputAdcEtcTrig00);

EDMA_SetCallback(&DMA_ADC_Handle, &Analog_DmaCallback, NULL);
EDMA_PrepareTransfer(&DMA0_ADC_TRANSFER0_config,
(void *) &ADC_ETC->TRIG[0].TRIGn_RESULT_1_0,
sizeof(uint32_t),
(void *)&g_adc_results[0][0],
sizeof(g_adc_results[0]),
sizeof(g_adc_results[0]),
sizeof(g_adc_results),
kEDMA_PeripheralToMemory);
EDMA_SubmitTransfer(&DMA_ADC_Handle, &DMA0_ADC_TRANSFER0_config);
EDMA_StartTransfer(&DMA_ADC_Handle);
ADC_InitPeripherals();
}

void Analog_DmaCallback(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds)
{
if (transferDone)
{
// check the results in g_adc_results
}
// start new transfer
EDMA_SubmitTransfer(&DMA_ADC_Handle, &DMA0_ADC_TRANSFER0_config);
EDMA_StartTransfer(&DMA_ADC_Handle);
}

When I get the DMA callback, all of the g_adc_results contain the same 4 bytes repeated, and the DMA callback is triggered with the same frequency as the PIT is triggering the conversions.

0 Kudos