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);
- The behaviour if I trigger the ADC via software trigger is:
I can see the ADC sampling 3 values on each trigger as expected (by watching the FIFO level register) - On the first 2 triggers no data is transfered as expected since the FIFO level is still below the threshold
- On the 3rd trigger data is transfered via the DMA but only 3 uint32_t values instead of the expected 9
- As a consequnence, the FIFO level is only lowered by 3 and not down to zero as expected and a a consequence of that on every further trigger 3 more values are transfered and the FIFO level always bonces up and down but the FIFO never gets emptied.
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.