K64 ADC sample  abnormal?

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

K64 ADC sample  abnormal?

969 Views
xxwl0406
Contributor I

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?

Labels (1)
0 Kudos
4 Replies

750 Views
xxwl0406
Contributor I

@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);
}

0 Kudos

750 Views
xxwl0406
Contributor I

#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 */

0 Kudos

750 Views
danielchen
NXP TechSupport
NXP TechSupport

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

0 Kudos

750 Views
xxwl0406
Contributor I

Can check my adc code for me ?

0 Kudos