os: ucosiii + LWIP
hardware:K64
PIT0 -> DMA0
DMA0->ADC0 DMA0 transfer command change adc channel and trigger adc conver.
ADC0->DMA8 transfer the result to buffer.
set DMA0 priority to 0;
set DMA8 priority to 8;
ADC convert rate:25kps/per channel.
adc convert data send to PC by ethernet.
some times adc sample data is abnormal, have glitch, sometimes is normal, how to solve this problem?
@Daniel Chen ,Can check my adc code for me ?
volatile int16_t adc0_0_acqusition_buffer[ACCELERATION_DATA_LENGTH * NUMBER_OF_ADC0MEASUREMENT * 2];
volatile int16_t adc1_1_acqusition_buffer[ACCELERATION_DATA_LENGTH * NUMBER_OF_ADC1MEASUREMENT * 2];
edma_handle_t EDMA_ADC0_setchannel_handle;
/* for transfer ADC0 result to memory */
edma_handle_t EDMA_ADC0_transfer_handle;
/* for transfer switch channel command to sc1 register */
edma_handle_t EDMA_ADC1_setchannel_handle;
/* for transfer ADC1 result to memory */
edma_handle_t EDMA_ADC1_transfer_handle;
/* define transfer type */
edma_transfer_config_t ADC0_setchannel_config;
edma_transfer_config_t ADC0_transfer_config;
edma_transfer_config_t ADC1_setchannel_config;
edma_transfer_config_t ADC1_transfer_config;
const uint8_t ADC0_channels_cmd[] = 
{
 ADC_SC1_ADCH(0),
 ADC_SC1_ADCH(1),
 ADC_SC1_ADCH(21),
 ADC_SC1_ADCH(22),
 ADC_SC1_ADCH(26) /* reserved */
};
const uint8_t ADC1_channels_cmd[] = 
{
 ADC_SC1_ADCH(0),
 ADC_SC1_ADCH(1),
 ADC_SC1_ADCH(18),
 ADC_SC1_ADCH(14),
 ADC_SC1_ADCH(23) /* reserved */
};
static void eDMA_ADC0_callback(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds);
static void eDMA_ADC1_callback(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds);
void DMAMUX_configuration(void)
{
 /* Configure DMAMUX */
 DMAMUX_Init(DMAMUX0);
/* Map ADC0 set sc1 register to channel 0 */
 DMAMUX_SetSource(DMAMUX0, DMA_ADC0_SETCHANNEL, DMA_ADC0_ALWAYSENABLED);
 DMAMUX_EnablePeriodTrigger(DMAMUX0, DMA_ADC0_SETCHANNEL);
 DMAMUX_EnableChannel(DMAMUX0, DMA_ADC0_SETCHANNEL);
/* Map ADC0 result to channel 1 */
 DMAMUX_SetSource(DMAMUX0, DMA_ADC0_TRANSFER, DMA_ADC0_RESULT);
 DMAMUX_EnableChannel(DMAMUX0, DMA_ADC0_TRANSFER);
 
 /* Map ADC1 set sc1 register to channel 2 */
 DMAMUX_SetSource(DMAMUX0, DMA_ADC1_SETCHANNEL, DMA_ADC1_ALWAYSENABLED);
 DMAMUX_EnablePeriodTrigger(DMAMUX0, DMA_ADC1_SETCHANNEL);
 DMAMUX_EnableChannel(DMAMUX0, DMA_ADC1_SETCHANNEL);
/* Map ADC0 result to channel 3 */
 DMAMUX_SetSource(DMAMUX0, DMA_ADC1_TRANSFER, DMA_ADC1_RESULT);
 DMAMUX_EnableChannel(DMAMUX0, DMA_ADC1_TRANSFER);
}
#define ENABLE_DMA_PREEMPTION 1
/*****************************************************************************
** Funcation : eDMA_configuration
** Description: inital dma and create handles for adc0 and adc1 .
** Arguments : void
** Return : void
*****************************************************************************/
void eDMA_ADC0_configuration(void)
{
 edma_config_t userConfig;
 status_t status;
const edma_channel_Preemption_config_t adc0_setchl_config = 
 {
 .enableChannelPreemption = true,
 .enablePreemptAbility = true,
 .channelPriority = DMA_ADC0_SETCHANNEL, //low priority
 };
 
 const edma_channel_Preemption_config_t adc0_transfer_config = 
 {
 .enableChannelPreemption = true,
 .enablePreemptAbility = true,
 .channelPriority = DMA_ADC0_TRANSFER, //high priority
 };
 
 EDMA_GetDefaultConfig(&userConfig);
 userConfig.enableContinuousLinkMode = true;
 EDMA_Init(DMA0, &userConfig);
 
 EDMA_ResetChannel(DMA0, DMA_ADC0_SETCHANNEL);
 
 #if ENABLE_DMA_PREEMPTION
 EDMA_SetChannelPreemptionConfig(DMA0, DMA_ADC0_SETCHANNEL, &adc0_setchl_config);
 #endif
 
 /* init dma channel 0 for set ADC0 channel */
 EDMA_CreateHandle(&EDMA_ADC0_setchannel_handle, DMA0, DMA_ADC0_SETCHANNEL);
 //EDMA_SetCallback(&EDMA_ADC0_setchannel_handle, eDMA_ADC0_callback, NULL);
 EDMA_PrepareTransfer(&ADC0_setchannel_config, (void *)ADC0_channels_cmd, sizeof(ADC0_channels_cmd[0]),
 (void *)ADC0_SC1_REG_ADDR, sizeof(uint8_t), sizeof(ADC0_channels_cmd[0]),
 sizeof(ADC0_channels_cmd), kEDMA_MemoryToPeripheral);
 status = EDMA_SubmitTransfer(&EDMA_ADC0_setchannel_handle, &ADC0_setchannel_config);
 
/* never stop when major loop finished */
 //DMA0->TCD[DMA_ADC0_SETCHANNEL].CSR &= ~DMA_CSR_DREQ_MASK;
 EDMA_EnableAutoStopRequest(DMA0, DMA_ADC0_SETCHANNEL, false);
 
 
 DMA0->TCD[DMA_ADC0_SETCHANNEL].SLAST = -1 * (int32_t)(sizeof(ADC0_channels_cmd));
 EDMA_DisableChannelInterrupts(DMA0, DMA_ADC0_SETCHANNEL, kEDMA_MajorInterruptEnable
 | kEDMA_ErrorInterruptEnable
 | kEDMA_HalfInterruptEnable);
 
 /* Enable transfer. */
 EDMA_StartTransfer(&EDMA_ADC0_setchannel_handle);
EDMA_ResetChannel(DMA0, DMA_ADC0_TRANSFER);
 
 #if ENABLE_DMA_PREEMPTION
 EDMA_SetChannelPreemptionConfig(DMA0, DMA_ADC0_TRANSFER, &adc0_transfer_config);
 #endif
 
 /* init dma channel 1 for result transfer */
 EDMA_CreateHandle(&EDMA_ADC0_transfer_handle, DMA0, DMA_ADC0_TRANSFER);
 EDMA_SetCallback(&EDMA_ADC0_transfer_handle, eDMA_ADC0_callback, NULL);
 EDMA_PrepareTransfer(&ADC0_transfer_config, (void *)ADC0_RESULT_REG_ADDR, sizeof(uint16_t),
 (void *)adc0_0_acqusition_buffer, sizeof(uint16_t), sizeof(uint16_t),
 sizeof(adc0_0_acqusition_buffer), kEDMA_PeripheralToMemory);
 status = EDMA_SubmitTransfer(&EDMA_ADC0_transfer_handle, &ADC0_transfer_config);
 
 
 /* never stop when major loop finished */
 //DMA0->TCD[DMA_ADC0_TRANSFER].CSR &= ~DMA_CSR_DREQ_MASK;
EDMA_EnableAutoStopRequest(DMA0, DMA_ADC0_TRANSFER, false);
 DMA0->TCD[DMA_ADC0_TRANSFER].DLAST_SGA = -1 * (int32_t)(sizeof(adc0_0_acqusition_buffer));
 
 EDMA_EnableChannelInterrupts(DMA0, DMA_ADC0_TRANSFER, kEDMA_MajorInterruptEnable
 | kEDMA_ErrorInterruptEnable
 | kEDMA_HalfInterruptEnable);
 /* Enable transfer. */
 EDMA_StartTransfer(&EDMA_ADC0_transfer_handle);
 
}
void eDMA_ADC1_configuration(void)
{
const edma_channel_Preemption_config_t adc1_setchl_config = 
 {
 .enableChannelPreemption = true,
 .enablePreemptAbility = true,
 .channelPriority = DMA_ADC1_SETCHANNEL, //low priority
 };
 
 const edma_channel_Preemption_config_t adc1_transfer_config = 
 {
 .enableChannelPreemption = true,
 .enablePreemptAbility = true,
 .channelPriority = DMA_ADC1_TRANSFER, //high priority
 };
 
 EDMA_ResetChannel(DMA0, DMA_ADC1_SETCHANNEL);
 #if ENABLE_DMA_PREEMPTION
 EDMA_SetChannelPreemptionConfig(DMA0, DMA_ADC1_SETCHANNEL, &adc1_setchl_config); 
 #endif
 
 /* init dma channel 0 for set ADC0 channel */
 EDMA_CreateHandle(&EDMA_ADC1_setchannel_handle, DMA0, DMA_ADC1_SETCHANNEL);
 //EDMA_SetCallback(&EDMA_ADC1_setchannel_handle, eDMA_ADC1_callback, NULL);
 EDMA_PrepareTransfer(&ADC1_setchannel_config, (void *)ADC1_channels_cmd, sizeof(ADC1_channels_cmd[0]),
 (void *)ADC1_SC1_REG_ADDR, sizeof(uint8_t), sizeof(ADC1_channels_cmd[0]),
 sizeof(ADC1_channels_cmd), kEDMA_MemoryToPeripheral);
 EDMA_SubmitTransfer(&EDMA_ADC1_setchannel_handle, &ADC1_setchannel_config);
 /* never stop when major loop finished */
 //DMA0->TCD[DMA_ADC1_SETCHANNEL].CSR &= ~DMA_CSR_DREQ_MASK;
 EDMA_EnableAutoStopRequest(DMA0, DMA_ADC1_SETCHANNEL, false);
 
 DMA0->TCD[DMA_ADC1_SETCHANNEL].SLAST = -1 * (int32_t)(sizeof(ADC1_channels_cmd));
 
 EDMA_DisableChannelInterrupts(DMA0, DMA_ADC1_SETCHANNEL, kEDMA_MajorInterruptEnable
 | kEDMA_ErrorInterruptEnable
 | kEDMA_HalfInterruptEnable);
 
 /* Enable transfer. */
 EDMA_StartTransfer(&EDMA_ADC1_setchannel_handle);
 
 EDMA_ResetChannel(DMA0, DMA_ADC1_TRANSFER);
 
 #if ENABLE_DMA_PREEMPTION 
 EDMA_SetChannelPreemptionConfig(DMA0, DMA_ADC1_TRANSFER, &adc1_transfer_config); 
 #endif 
 
 EDMA_CreateHandle(&EDMA_ADC1_transfer_handle, DMA0, DMA_ADC1_TRANSFER);
 EDMA_SetCallback(&EDMA_ADC1_transfer_handle, eDMA_ADC1_callback, NULL);
 EDMA_PrepareTransfer(&ADC1_transfer_config, (void *)ADC1_RESULT_REG_ADDR, sizeof(uint16_t),
 (void *)adc1_1_acqusition_buffer, sizeof(uint16_t), sizeof(uint16_t),
 sizeof(adc1_1_acqusition_buffer), kEDMA_PeripheralToMemory);
 EDMA_SubmitTransfer(&EDMA_ADC1_transfer_handle, &ADC1_transfer_config);
 
 
 
 /* never stop when major loop finished */
 //DMA0->TCD[DMA_ADC1_TRANSFER].CSR &= ~DMA_CSR_DREQ_MASK; 
 EDMA_EnableAutoStopRequest(DMA0, DMA_ADC1_TRANSFER, false);
 
 DMA0->TCD[DMA_ADC1_TRANSFER].DLAST_SGA = -1 * (int32_t)(sizeof(adc1_1_acqusition_buffer));
 //DMA0->TCD[DMA_ADC0_TRANSFER].CSR &= ~DMA_CSR_DREQ_MASK;
 //DMA0->TCD[DMA_ADC0_TRANSFER].SLAST = -1 * (int16_t)(sizeof(adc0_0_acqusition_buffer));
 /* Enable interrupt when transfer is done. */
 EDMA_EnableChannelInterrupts(DMA0, DMA_ADC1_TRANSFER, kEDMA_MajorInterruptEnable
 | kEDMA_HalfInterruptEnable);
/* Enable transfer. */
 EDMA_StartTransfer(&EDMA_ADC1_transfer_handle); 
 
}
static void eDMA_ADC0_callback(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds)
{
OS_ERR os_err;
 OSIntEnter();
 /* Clear Edma interrupt flag. */
 EDMA_ClearChannelStatusFlags(DMA0, DMA_ADC0_TRANSFER, kEDMA_InterruptFlag | kEDMA_DoneFlag | kEDMA_ErrorFlag);
 __DSB();
 OSIntExit();
}
static void eDMA_ADC1_callback(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds)
{
 OS_ERR os_err;
 OSIntEnter();
 /* Clear Edma interrupt flag. */
 EDMA_ClearChannelStatusFlags(DMA0, DMA_ADC1_TRANSFER, kEDMA_InterruptFlag | kEDMA_DoneFlag | kEDMA_ErrorFlag);
 __DSB();
 OSIntExit();
 
 //PRINTF("line:%d,OSTimeGet:%d \r\n", __LINE__, OSTimeGet( &os_err));
}
void ADC_init(ADC_Type *base)
{
 adc16_config_t adc16ConfigStruct;
ADC16_GetDefaultConfig(&adc16ConfigStruct);
 adc16ConfigStruct.enableLowPower = false;
 /* Bus clock */
 adc16ConfigStruct.clockSource = kADC16_ClockSourceAlt3;
 /* divider 1 */
 adc16ConfigStruct.clockDivider = kADC16_ClockDivider1;
 adc16ConfigStruct.resolution = kADC16_ResolutionSE16Bit; 
 adc16ConfigStruct.referenceVoltageSource = kADC16_ReferenceVoltageSourceVref;
 adc16ConfigStruct.enableAsynchronousClock = false;
 adc16ConfigStruct.enableHighSpeed = true;
 adc16ConfigStruct.longSampleMode = kADC16_LongSampleCycle24;
/* continue convertion for dma */
 adc16ConfigStruct.enableContinuousConversion = false;
ADC16_Init(base, &adc16ConfigStruct);
 
 /* Make sure the software trigger is used. */
 ADC16_EnableHardwareTrigger(base, false);
/* Configure hardware average mode */
 ADC16_SetHardwareAverage(base, kADC16_HardwareAverageDisabled);
/* Configure channel multiplexing mode */
 ADC16_SetChannelMuxMode(base, kADC16_ChannelMuxA);
 
 if (kStatus_Success != ADC16_DoAutoCalibration(base))
 {
 APP_TRACE_DBG(("ADC16_DoAutoCalibration(ADC) failed.\r\n"));
 }else{
 APP_TRACE_DBG(("ADC16_DoAutoCalibration(ADC) done.\r\n"));
 }
/* allow dma */
 ADC16_EnableDMA(base, true);
}
#define DMA_ADC0_SETCHANNEL 0U
#define DMA_ADC0_ALWAYSENABLED 58U /* fixed */
#define DMA_ADC0_TRANSFER 2U
#define DMA_ADC0_RESULT 40U /* fixed */
#define DMA_ADC1_SETCHANNEL 1U
#define DMA_ADC1_ALWAYSENABLED 59U /* fixed */
#define DMA_ADC1_TRANSFER 3U
#define DMA_ADC1_RESULT 41U /* fixed */
 
					
				
		
 danielchen
		
			danielchen
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		Hi Zh
I would suggest you check with your power, could you please test your app with a stable power? we should first rule out the power issue.
Please also refer to below AN4373, Cookbook for SAR ADC Measurements
https://www.nxp.com/docs/en/application-note/AN4373.pdf
Regards
Daniel
Can check my adc code for me ?
