Hello,
I have an application with the LPC5536 where I have to sample 3 ADC channels in rapid succession at 3 very distinct points of time. The idea is to trigger them with a SCT channel, collect the 9 (3 x 3) values in the FIFO of the ADC and transfer them off to memory using the DMA when the conversion has finished. However I have run into a problem I don't understand.
I have removed the triggering of the ADC via the SCT for now for easier debugging control. I have set up 3 ADC channels as a sequence with the FIFO watermark set to 8 so that the DMA request happens after the 9th byte
lpadc_conv_command_config_t ADCCommand1 = {kLPADC_SampleChannelSingleEndSideA, 1U, 2, false, 0UL, kLPADC_HardwareAverageCount1, kLPADC_SampleTimeADCK3, kLPADC_HardwareCompareDisabled, 0UL, 0UL, kLPADC_ConversionResolutionStandard, false};
lpadc_conv_command_config_t ADCCommand2 = {kLPADC_SampleChannelSingleEndSideA, 3U, 3, false, 0UL, kLPADC_HardwareAverageCount1, kLPADC_SampleTimeADCK3, kLPADC_HardwareCompareDisabled, 0UL, 0UL, kLPADC_ConversionResolutionStandard, false};
lpadc_conv_command_config_t ADCCommand3 = {kLPADC_SampleChannelSingleEndSideA, 8U, 0, false, 0UL, kLPADC_HardwareAverageCount1, kLPADC_SampleTimeADCK3, kLPADC_HardwareCompareDisabled, 0UL, 0UL, kLPADC_ConversionResolutionStandard, false};
LPADC_SetConvCommandConfig(ADC0, 1, &ADCCommand1);
LPADC_SetConvCommandConfig(ADC0, 2, &ADCCommand2);
LPADC_SetConvCommandConfig(ADC0, 3, &ADCCommand3);
const lpadc_config_t ADC_Config = {true, kLPADC_ConversionAverage1, true, 0x80UL, kLPADC_ReferenceVoltageAlt3, kLPADC_PowerLevelAlt1, kLPADC_TriggerPriorityPreemptImmediately, false, 0UL, 8UL, 0UL};
LPADC_Init(ADC0, &ADC_Config);
LPADC_EnableFIFO0WatermarkDMA(ADC0, true);
I have also set up a DMA channel to transfer the data:
g_XferConfig = DMA_CHANNEL_XFER(false, true, false, false, sizeof(uint32_t), kDMA_AddressInterleave0xWidth, kDMA_AddressInterleave1xWidth, 9 * sizeof(uint32_t));
DMA_PrepareChannelTransfer(&DMAChannelConfigStruct, (void*)(&(BSP_SENSOR_ADC->RESFIFO[0])), (void *)Sensor_ADC_Buffer, g_XferConfig, kDMA_PeripheralToMemory, NULL, NULL);
(void)DMA_SubmitChannelTransfer(&ADC_DMA_Handle, &DMAChannelConfigStruct);
Why does the DMA transfer only a third of the bytes configured? The "9 * sizeof(uint32_t)" bytes in the xfer config look correct to me and they are correctly converted into 9 transfers (leading to the XFERCOUNT field in the XFERCFG register set to 8).
Up front, I am not allowed to upload my project and it is on a custom hardware and not on an evaluation board anyway.
EDIT: I have noticed that I did not have the DMA_SetupDescriptor() call like in the lpadc_dma example and have added that but the behaviour did not change. I still wonder what the descriptors do because the SRAMBASE register mentioned in the RM always points to the s_dma_descriptor_table0 table in the library.
Hi,
I have the same issue. For one request I get 3 reads. Could you share the solution?
Thanks a lot.
Hello @orange_chris
How many time reads RESFIFO for one DMA trigger?
The FIFO can be emptied by successive reads of RESFIFO.
BR
Alice
Hello Alice,
it seems that the RESFIFO is read 3 times per DMA trigger despite being configured to be read 9 times with
g_XferConfig = DMA_CHANNEL_XFER(false, true, true, false, sizeof(uint32_t), kDMA_AddressInterleave0xWidth, kDMA_AddressInterleave1xWidth, 9 * sizeof(uint32_t));
There is data left in the RESFIFO, I have checked that using manual reads after the DMA was triggered
I can scale the reads down to 1 and 2 replacing the 9 in the config above by 1 and 2 but starting at 4, the DMA only reads 3 times.
Is there a hidden limit on how many bytes can be transfered per DMA trigger?
Hello @orange_chris
How about first change and tested base on adc_dma demo under SDK, if still can't work as your requirements, send the project to me , I help to check on LPCxpresso5536-evk board, I think it is easy to find problem by debugging.
BR
Alice
Hello Alice,
I have found out that it is trivial to reproduce. Just open the lpadc_demo project from the SDK and increase DEMO_CADC_SAMPLE_COUNT to anything above 3. You will see that the ADC indeed samples additional sample but they are never transfered into RAM despite the transfer being configured to be DEMO_CADC_SAMPLE_COUNT * sizeof(uint32_t) bytes.
BR,
Christian
Hello @orange_chris
Sorry to reply you late, I came back from public holiday yesterday, and I know Guenter is helping you about this case, he will tell you the answer .ASAP.
BR
Alice