Hi,
I have used a DMA channel (Channel 0) to trigger ADC in software trigger mode and another DMA channel (channel 1) to store the result of ADC. I want to sample 12 ADC channels back to back using the above process.
The attached code samples all the 12 channels properly but there are few observations I am not able to understand:
1) My ADC result buffer shows shifted results. E.g. I have stored ADC channel 8, channel 9 & channel 15 respectively in ADC trigger buffer but the result buffer shows output as channel 15, channel 8 & channel 9 respectively.
2) I am getiing two DMA channel 1 interrupts then one DMA channel 1 interrupt. Ideally I should get only 1 interrupt each DMA channel.
DMA source and destination address seems fine.
I have attached code for reference.
Development board used: FRDM K22F
Please help in resolving the issue.
Thanks and best regards,
Prasanna
Hi Prasanna,
For what I could see in your code ,you need to enable the channels need it to use.
void ADC_Configuration()
{
EnableIRQ(ADC0_IRQn);
adc16_config_t adc16ConfigStruct;
adc16_channel_config_t adc16ChannelConfigStruct;
ADC16_GetDefaultConfig(&adc16ConfigStruct);
adc16ConfigStruct.clockSource = kADC16_ClockSourceAlt0;/*Bus clock 40 Mhz*/
adc16ConfigStruct.clockDivider = kADC16_ClockDivider2;/*Divided by 2*/
ADC16_Init( ADC0, &adc16ConfigStruct);
ADC16_DoAutoCalibration( ADC0 );
ADC16_EnableHardwareTrigger(ADC0, false); /* Make sure the software trigger is used. */
//ADC16_EnableHardwareTrigger( ADC0, true);
ADC16_EnableDMA( ADC0, true);
adc16ChannelConfigStruct.channelNumber = g_ADC_mux[0];
adc16ChannelConfigStruct.enableInterruptOnConversionCompleted = true;
adc16ChannelConfigStruct.enableDifferentialConversion = false;
ADC16_SetChannelConfig( ADC0, 0, &adc16ChannelConfigStruct);
adc16ChannelConfigStruct.channelNumber = g_ADC_mux[1];
adc16ChannelConfigStruct.enableInterruptOnConversionCompleted = false;
adc16ChannelConfigStruct.enableDifferentialConversion = false;
ADC16_SetChannelConfig( ADC0, 0, &adc16ChannelConfigStruct);
adc16ChannelConfigStruct.channelNumber = g_ADC_mux[2];
adc16ChannelConfigStruct.enableInterruptOnConversionCompleted = false;
adc16ChannelConfigStruct.enableDifferentialConversion = false;
ADC16_SetChannelConfig( ADC0, 0, &adc16ChannelConfigStruct);
}
And in the interruption you only need to start a single transfer, this is the reason the interruption is trigger twice:
void BOARD_FTM_HANDLER(void)
{
/* Clear interrupt flag.*/
FTM_ClearStatusFlags(BOARD_FTM_BASEADDR, kFTM_TimeOverflowFlag);
/* If transfer will continue it will need to adjust last source and destination */
EDMA_StartTransfer(&g_EDMA_Handle_1);
//GPIO_PinWrite(TEST_PIN_PORT, TEST_PIN_NUMBER, 1);
GPIO_PortToggle(TEST_PIN_PORT, 1u << TEST_PIN_NUMBER);
__DSB();
}
For the shift in the register, I'm still looking for this.
Best Regards,
Alexis Andalon
Hi,
Thank you for your response.
I tried enabling the channels as you mentioned but it did not solve the problem. I am still getting the interrupt of DMA channel 0 twice. Also starting only one transfer in the timer interrupt causes no output.
I tried another approach- without enabling the channels and explicitly starting the DMA channel 0 transfer by writing TCD[0].CSR register along with EDMA_StartTransfer(&g_EDMA_Handle_1) in the timer interrupt . With this approach, I am getting each interrupt only once and there is no shift in the registers as well. So this seems to solve the problem.
Please let me know if you find some ambiguity in this approach.
Thanks and Best Regards,
Prasanna