Solved! Go to Solution.
Hi,
I have checked that ADC0->FLAGS[SEQA_INT] can not be set, I do not know why either, maybe it is only used in interrupt or DMA mode.
Any, pls use the code as you have done, I just modify it based on your architecture. Now it works fine. Note that the DATA VALID bit for DAT[0:11] register can only be read once. Reading the register will clear the bit.
DATA
VALID
This bit is set to 1 at the end of each conversion when a new result is loaded into the RESULT
field. It is cleared whenever this register is read.
This bit will cause a conversion-complete interrupt for the corresponding sequence if the MODE
bit (in SEQB_CTRL) for that sequence is set to 0 (and if the interrupt is enabled).
Hope it can help you
BR
XiangJun Rong
int main(void)
{
/* Initialize board hardware. */
/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
BOARD_InitPins();
BOARD_BootClockPLL180M();
BOARD_InitDebugConsole();
/* Reset DMA since core reset in IDE will not reset DMA */
RESET_SetPeripheralReset(kDMA_RST_SHIFT_RSTn);
/* Enable the power and clock for ADC. */
ADC_ClockPower_Configuration();
PRINTF("ADC basic example.\r\n");
#if !(defined(FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC) && FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC)
uint32_t frequency = 0U;
/* Calibration after power up. */
#if defined(FSL_FEATURE_ADC_HAS_CALIB_REG) && FSL_FEATURE_ADC_HAS_CALIB_REG
DEMO_ADC_BASE->CTRL |= ADC_CTRL_BYPASSCAL_MASK;
frequency = CLOCK_GetFreq(kCLOCK_BusClk);
if (true == ADC_DoOffsetCalibration(DEMO_ADC_BASE, frequency))
#else
#if defined(SYSCON_ADCCLKDIV_DIV_MASK)
frequency = CLOCK_GetFreq(DEMO_ADC_CLOCK_SOURCE) / CLOCK_GetClkDivider(kCLOCK_DivAdcClk);
#else
frequency = CLOCK_GetFreq(DEMO_ADC_CLOCK_SOURCE);
#endif /* SYSCON_ADCCLKDIV_DIV_MASK */
if (true == ADC_DoSelfCalibration(DEMO_ADC_BASE, frequency))
#endif /* FSL_FEATURE_ADC_HAS_CALIB_REG */
{
PRINTF("ADC Calibration Done.\r\n");
}
else
{
PRINTF("ADC Calibration Failed.\r\n");
}
#endif /* FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC */
/* Configure the converter and work mode. */
ADC_Configuration();
PRINTF("Configuration Done.\r\n");
#if defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) & FSL_FEATURE_ADC_HAS_CTRL_RESOL
PRINTF("ADC Full Range: %d\r\n", g_Adc_12bitFullRange);
#endif /* FSL_FEATURE_ADC_HAS_CTRL_RESOL */
while (1)
{
/* Get the input from terminal and trigger the converter by software. */
GETCHAR();
ADC_DoSoftwareTriggerConvSeqA(DEMO_ADC_BASE);
//ADC_DoSoftwareTriggerConvSeqB(DEMO_ADC_BASE);
#if 1 //Rong wrote: it appears the lines is incorrect
while(!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER4, &adcResultInfoStruct)) {}
ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER4, &adcResultInfoStruct);
while(!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER5, &adcResultInfoStruct5)) {}
ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER5, &adcResultInfoStruct5);
while(!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER6, &adcResultInfoStruct6)) {}
ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER6, &adcResultInfoStruct6);
#endif
#if 0
/* Wait for the converter to be done. */
while(!(ADC0->FLAGS& 0x10000000)) //test the ADC0->FLAGS[SEQA_INT], bit 28
{
//PRINTF("In loop.\r\n");
}
ADC0->FLAGS|=0x10000000;
#endif
ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER4, &adcResultInfoStruct);
ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER5, &adcResultInfoStruct5);
ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER6, &adcResultInfoStruct6);
PRINTF("adcResultInfoStruct.result = %d\r\n", adcResultInfoStruct.result);
PRINTF("adcResultInfoStruct.channelNumber = %d\r\n", adcResultInfoStruct.channelNumber);
PRINTF("adcResultInfoStruct.overrunFlag = %d\r\n", adcResultInfoStruct.overrunFlag ? 1U : 0U);
PRINTF("\r\n");
PRINTF("adcResultInfoStruct5.result = %d\r\n", adcResultInfoStruct5.result);
PRINTF("adcResultInfoStruct5.channelNumber = %d\r\n", adcResultInfoStruct5.channelNumber);
PRINTF("adcResultInfoStruct5.overrunFlag = %d\r\n", adcResultInfoStruct5.overrunFlag ? 1U : 0U);
PRINTF("\r\n");
PRINTF("adcResultInfoStruct6.result = %d\r\n", adcResultInfoStruct6.result);
PRINTF("adcResultInfoStruct6.channelNumber = %d\r\n", adcResultInfoStruct6.channelNumber);
PRINTF("adcResultInfoStruct6.overrunFlag = %d\r\n", adcResultInfoStruct6.overrunFlag ? 1U : 0U);
PRINTF("\r\n");
}
}
Hi, Ahmed,
Regarding your question, I do not think there is big difference for the ADC[0:5] fast channels and ADC[6:11] slow channel except for the ADC fast/slow channel pin input impedance.
Regarding your issue, I think your ADC code has issue, pls post your ADC code so that we can have a review.
BR
Xiangjun Rong
Thanks for your help. I believe I know the reason. On my evaluation board, the ADC input for channel 6 is shorted to ground.
Thanks for your help.
Hi,
Pls try to test the code.
Hope it can help you
BR
XiangJun Rong
int main(void)
{
/* Initialize board hardware. */
/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
BOARD_InitPins();
BOARD_BootClockPLL180M();
BOARD_InitDebugConsole();
/* Reset DMA since core reset in IDE will not reset DMA */
RESET_SetPeripheralReset(kDMA_RST_SHIFT_RSTn);
/* Enable the power and clock for ADC. */
ADC_ClockPower_Configuration();
PRINTF("ADC basic example.\r\n");
#if !(defined(FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC) && FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC)
uint32_t frequency = 0U;
/* Calibration after power up. */
#if defined(FSL_FEATURE_ADC_HAS_CALIB_REG) && FSL_FEATURE_ADC_HAS_CALIB_REG
DEMO_ADC_BASE->CTRL |= ADC_CTRL_BYPASSCAL_MASK;
frequency = CLOCK_GetFreq(kCLOCK_BusClk);
if (true == ADC_DoOffsetCalibration(DEMO_ADC_BASE, frequency))
#else
#if defined(SYSCON_ADCCLKDIV_DIV_MASK)
frequency = CLOCK_GetFreq(DEMO_ADC_CLOCK_SOURCE) / CLOCK_GetClkDivider(kCLOCK_DivAdcClk);
#else
frequency = CLOCK_GetFreq(DEMO_ADC_CLOCK_SOURCE);
#endif /* SYSCON_ADCCLKDIV_DIV_MASK */
if (true == ADC_DoSelfCalibration(DEMO_ADC_BASE, frequency))
#endif /* FSL_FEATURE_ADC_HAS_CALIB_REG */
{
PRINTF("ADC Calibration Done.\r\n");
}
else
{
PRINTF("ADC Calibration Failed.\r\n");
}
#endif /* FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC */
/* Configure the converter and work mode. */
ADC_Configuration();
PRINTF("Configuration Done.\r\n");
#if defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) & FSL_FEATURE_ADC_HAS_CTRL_RESOL
PRINTF("ADC Full Range: %d\r\n", g_Adc_12bitFullRange);
#endif /* FSL_FEATURE_ADC_HAS_CTRL_RESOL */
while (1)
{
/* Get the input from terminal and trigger the converter by software. */
GETCHAR();
ADC_DoSoftwareTriggerConvSeqA(DEMO_ADC_BASE);
//ADC_DoSoftwareTriggerConvSeqB(DEMO_ADC_BASE);
/////////////////////////////////////////////////////////////////////////////////////////////////////////
///////Rong modified code beginning
/* Wait for the converter to be done. */
#if 0 //Rong wrote: it appears the lines is incorrect
while ((!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER4, &adcResultInfoStruct))
&& (!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER5, &adcResultInfoStruct5))
&& (!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER6, &adcResultInfoStruct6)))
#endif
while(!(ADC0->FLAGS&0x10000000)) //test the ADC0->FLAGS[SEQA_INT], bit 28
{
}
ADC0->FLAGS|=0x10000000;
ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER4, &adcResultInfoStruct);
ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER5, &adcResultInfoStruct5);
ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER6, &adcResultInfoStruct6);
///////Rong modified code end
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
PRINTF("adcResultInfoStruct.result = %d\r\n", adcResultInfoStruct.result);
PRINTF("adcResultInfoStruct.channelNumber = %d\r\n", adcResultInfoStruct.channelNumber);
PRINTF("adcResultInfoStruct.overrunFlag = %d\r\n", adcResultInfoStruct.overrunFlag ? 1U : 0U);
PRINTF("\r\n");
PRINTF("adcResultInfoStruct5.result = %d\r\n", adcResultInfoStruct5.result);
PRINTF("adcResultInfoStruct5.channelNumber = %d\r\n", adcResultInfoStruct5.channelNumber);
PRINTF("adcResultInfoStruct5.overrunFlag = %d\r\n", adcResultInfoStruct5.overrunFlag ? 1U : 0U);
PRINTF("\r\n");
PRINTF("adcResultInfoStruct6.result = %d\r\n", adcResultInfoStruct6.result);
PRINTF("adcResultInfoStruct6.channelNumber = %d\r\n", adcResultInfoStruct6.channelNumber);
PRINTF("adcResultInfoStruct6.overrunFlag = %d\r\n", adcResultInfoStruct6.overrunFlag ? 1U : 0U);
PRINTF("\r\n");
}
/*
GETCHAR();
ADC_DoSoftwareTriggerConvSeqB(DEMO_ADC_BASE);
/* Wait for the converter to be done. *./
while ((!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER4, &adcResultInfoStruct6)))
{
}
PRINTF("adcResultInfoStruct6.result = %d\r\n", adcResultInfoStruct6.result);
PRINTF("adcResultInfoStruct6.channelNumber = %d\r\n", adcResultInfoStruct6.channelNumber);
PRINTF("adcResultInfoStruct6.overrunFlag = %d\r\n", adcResultInfoStruct6.overrunFlag ? 1U : 0U);
PRINTF("\r\n");*/
}
Hi,
I have checked that ADC0->FLAGS[SEQA_INT] can not be set, I do not know why either, maybe it is only used in interrupt or DMA mode.
Any, pls use the code as you have done, I just modify it based on your architecture. Now it works fine. Note that the DATA VALID bit for DAT[0:11] register can only be read once. Reading the register will clear the bit.
DATA
VALID
This bit is set to 1 at the end of each conversion when a new result is loaded into the RESULT
field. It is cleared whenever this register is read.
This bit will cause a conversion-complete interrupt for the corresponding sequence if the MODE
bit (in SEQB_CTRL) for that sequence is set to 0 (and if the interrupt is enabled).
Hope it can help you
BR
XiangJun Rong
int main(void)
{
/* Initialize board hardware. */
/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
BOARD_InitPins();
BOARD_BootClockPLL180M();
BOARD_InitDebugConsole();
/* Reset DMA since core reset in IDE will not reset DMA */
RESET_SetPeripheralReset(kDMA_RST_SHIFT_RSTn);
/* Enable the power and clock for ADC. */
ADC_ClockPower_Configuration();
PRINTF("ADC basic example.\r\n");
#if !(defined(FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC) && FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC)
uint32_t frequency = 0U;
/* Calibration after power up. */
#if defined(FSL_FEATURE_ADC_HAS_CALIB_REG) && FSL_FEATURE_ADC_HAS_CALIB_REG
DEMO_ADC_BASE->CTRL |= ADC_CTRL_BYPASSCAL_MASK;
frequency = CLOCK_GetFreq(kCLOCK_BusClk);
if (true == ADC_DoOffsetCalibration(DEMO_ADC_BASE, frequency))
#else
#if defined(SYSCON_ADCCLKDIV_DIV_MASK)
frequency = CLOCK_GetFreq(DEMO_ADC_CLOCK_SOURCE) / CLOCK_GetClkDivider(kCLOCK_DivAdcClk);
#else
frequency = CLOCK_GetFreq(DEMO_ADC_CLOCK_SOURCE);
#endif /* SYSCON_ADCCLKDIV_DIV_MASK */
if (true == ADC_DoSelfCalibration(DEMO_ADC_BASE, frequency))
#endif /* FSL_FEATURE_ADC_HAS_CALIB_REG */
{
PRINTF("ADC Calibration Done.\r\n");
}
else
{
PRINTF("ADC Calibration Failed.\r\n");
}
#endif /* FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC */
/* Configure the converter and work mode. */
ADC_Configuration();
PRINTF("Configuration Done.\r\n");
#if defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) & FSL_FEATURE_ADC_HAS_CTRL_RESOL
PRINTF("ADC Full Range: %d\r\n", g_Adc_12bitFullRange);
#endif /* FSL_FEATURE_ADC_HAS_CTRL_RESOL */
while (1)
{
/* Get the input from terminal and trigger the converter by software. */
GETCHAR();
ADC_DoSoftwareTriggerConvSeqA(DEMO_ADC_BASE);
//ADC_DoSoftwareTriggerConvSeqB(DEMO_ADC_BASE);
#if 1 //Rong wrote: it appears the lines is incorrect
while(!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER4, &adcResultInfoStruct)) {}
ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER4, &adcResultInfoStruct);
while(!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER5, &adcResultInfoStruct5)) {}
ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER5, &adcResultInfoStruct5);
while(!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER6, &adcResultInfoStruct6)) {}
ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER6, &adcResultInfoStruct6);
#endif
#if 0
/* Wait for the converter to be done. */
while(!(ADC0->FLAGS& 0x10000000)) //test the ADC0->FLAGS[SEQA_INT], bit 28
{
//PRINTF("In loop.\r\n");
}
ADC0->FLAGS|=0x10000000;
#endif
ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER4, &adcResultInfoStruct);
ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER5, &adcResultInfoStruct5);
ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER6, &adcResultInfoStruct6);
PRINTF("adcResultInfoStruct.result = %d\r\n", adcResultInfoStruct.result);
PRINTF("adcResultInfoStruct.channelNumber = %d\r\n", adcResultInfoStruct.channelNumber);
PRINTF("adcResultInfoStruct.overrunFlag = %d\r\n", adcResultInfoStruct.overrunFlag ? 1U : 0U);
PRINTF("\r\n");
PRINTF("adcResultInfoStruct5.result = %d\r\n", adcResultInfoStruct5.result);
PRINTF("adcResultInfoStruct5.channelNumber = %d\r\n", adcResultInfoStruct5.channelNumber);
PRINTF("adcResultInfoStruct5.overrunFlag = %d\r\n", adcResultInfoStruct5.overrunFlag ? 1U : 0U);
PRINTF("\r\n");
PRINTF("adcResultInfoStruct6.result = %d\r\n", adcResultInfoStruct6.result);
PRINTF("adcResultInfoStruct6.channelNumber = %d\r\n", adcResultInfoStruct6.channelNumber);
PRINTF("adcResultInfoStruct6.overrunFlag = %d\r\n", adcResultInfoStruct6.overrunFlag ? 1U : 0U);
PRINTF("\r\n");
}
}
Hello,
I have used the code that you recommended, but I'm still not able to read accurate information for ADC0IN6. All I can read is 4092 every time I try to read, even though the result should be different (i'm measuring 1.6V on the pin so it should be ~2040 or so. Channels 4 and 5 are functioning correctly. Please review my main file and let me know what I am doing wrong.
Am I configuring the ADC wrong?
Thanks