I am using SDK 2.5.0 and ADC driver version 2.2.0, and trying to read ADC data continuously.
After sometime it gets stuck in while condition during ADC read condition.
bool ADC_GetChannelConversionResult(ADC_Type *base, uint32_t channel, adc_result_info_t *info)
{
assert(info != NULL);
assert(channel < ADC_DAT_COUNT);
uint32_t tmp32 = base->DAT[channel]; /* Read to clear the status. */
if (0U == (ADC_DAT_DATAVALID_MASK & tmp32))
{
return false;
}
info->result = (tmp32 & ADC_DAT_RESULT_MASK) >> ADC_DAT_RESULT_SHIFT;
info->thresholdCompareStatus =
(adc_threshold_compare_status_t)((tmp32 & ADC_DAT_THCMPRANGE_MASK) >> ADC_DAT_THCMPRANGE_SHIFT);
info->thresholdCorssingStatus =
(adc_threshold_crossing_status_t)((tmp32 & ADC_DAT_THCMPCROSS_MASK) >> ADC_DAT_THCMPCROSS_SHIFT);
info->channelNumber = (tmp32 & ADC_DAT_CHANNEL_MASK) >> ADC_DAT_CHANNEL_SHIFT;
info->overrunFlag = ((tmp32 & ADC_DAT_OVERRUN_MASK) == ADC_DAT_OVERRUN_MASK);
return true;
}
It returns false from
if (0U == (ADC_DAT_DATAVALID_MASK & tmp32))
{
return false;
}
Even if i skip this once it is false, it then keeps on giving false every time.
Solved! Go to Solution.
@Omar_Anguiano @frank_m We did power down for :
PDEN_VD2_ANA,
PDEN_ADC0,
PDEN_VDDA,
PDEN_VREFP.
Then powered them ON. Then did re-init ADC.
This resolved the issue.
It's been a while since your post. Have you learned anything new about the cause if this issue? We are seeing the same thing on the LPC54605. Where the ADC get's stuck and never finishes a conversion. We strongly believe this is happening due to large static build up and eventually it causes the ADC to lockup. The ADC also seems very susceptible to EMI and can cause this lockup as well.
I wanted to see if you learned anything new about what is causing the lockup or how to prevent it. From our testing, overvoltage events on an ADC pin does not cause the ADC to lock up, it causes a full MCU reset. Unfortunately for us, power down and re-initializing the ADC is not an option in firmware, as that would take time to do and if it happens in a critical parts of our ADC sampling it will throw off sampling rates, etc.
Thanks for sharing.
follow up in case any one has the same comes here to read tis post. I used the following code to power cycle the adc and was able to overcome stuck problem. I check if the data valid bit is not becoming 1 and reset the adc after waiting for a certain amount of time
CLOCK_DisableClock(kCLOCK_Adc0);
POWER_EnablePD(kPDRUNCFG_PD_VDDA); /* Power off VDDA. */
POWER_EnablePD(kPDRUNCFG_PD_ADC0); /* Power off the ADC converter. */
//POWER_EnablePD(kPDRUNCFG_PD_VD2_ANA); /* Power off the analog power supply.DO NOT do that if you use usb, it will disable usb */
POWER_EnablePD(kPDRUNCFG_PD_VREFP); /* Power off the reference voltage source. */
POWER_EnablePD(kPDRUNCFG_PD_TS); /* Power off the temperature sensor. */
Delayus(150);
POWER_DisablePD(kPDRUNCFG_PD_VDDA); /* Power on VDDA. */
POWER_DisablePD(kPDRUNCFG_PD_ADC0); /* Power on the ADC converter. */
POWER_DisablePD(kPDRUNCFG_PD_VD2_ANA); /* Power on the analog power supply (just in case). */
POWER_DisablePD(kPDRUNCFG_PD_VREFP); /* Power on the reference voltage source. */
POWER_DisablePD(kPDRUNCFG_PD_TS); /* Power on the temperature sensor. */
Delayus(500);
CLOCK_SetClkDiv(kCLOCK_DivAdcAsyncClk, 0U, true); /*!< Reset ADCCLKDIV divider counter and halt it */
CLOCK_SetClkDiv(kCLOCK_DivAdcAsyncClk, 4U, false); /*!< Set ADCCLKDIV divider to value 2 */
CLOCK_AttachClk(kFRO_HF_to_ADC_CLK); /*!< Switch ADC_CLK (ADCCLKSEL) to FRO_HF */
CLOCK_EnableClock(kCLOCK_Adc0); /* SYSCON->AHBCLKCTRL[0] |= SYSCON_AHBCLKCTRL_ADC0_MASK; */
Delayus(5000);//give time so adc is powered on
@Omar_Anguiano @frank_m We did power down for :
PDEN_VD2_ANA,
PDEN_ADC0,
PDEN_VDDA,
PDEN_VREFP.
Then powered them ON. Then did re-init ADC.
This resolved the issue.
We're trying to find why it happens, but simultaneously we need to find what to do if it happens. So if it gets stuck in adc conversion, is there any way to recover ADC from stuck mode without resetting the controller.
it works fine on desk, but at site, it runs normally for sometime and then gets stuck due to noise or unknown factor.
in case it gets stuck, it is found that the ADC is not able to convert the data, and hence triggered watchdog.
When the ADC gets stuck because of invalid data, we tried to deinit ADC, change GPIO to digital, change GPIO to analog, and init ADC.
But it still remains stuck in invalid data
We tried to power down ADC module using PDEN_ADC0 too, but still ADC does not recover.
Even the ADC example from SDK face the same issue.
The ADC is basically a simple sequential machine, there is hardly anything that can "get stuck".
In my experience, there are 3 issues that might cause the observed behavior.
1. Overvoltage at the inputs. Check that you never ever exceed the maximum allowed input voltage in analog mode, perhaps clamp the inputs if necessary. I had been observing very strange behavior in such cases on a wide variety of devices over the years.
2. Unhandled interrupts. Check that all enabled interrupt events are handled, including overflow and threshold compare. If set, always clear this flags in the handler.
3. Time overrun in the ADC/DMA handler. Avoid too much code in interrupt context, especially code that relies on other interrupts. Especially, never call printf (semihosting) functions in interrupt context. Use flags to do core-intensive operations in normal user context.
I suspect issue 3 most likely applies to your case.
Interrupts are not the issue here.
But the first point MIGHT be the issue. It could be that somehow the ADC pin gets high voltage spike.
In that case, while reading the ADC data, it'll give INVALID data.
But even after the voltage spike is passed, the ADC continues to give INVALID data.
The DATA VALID bit remains ZERO thereafter. This is the state I am referring as stuck.
> But even after the voltage spike is passed, the ADC continues to give INVALID data.
> The DATA VALID bit remains ZERO thereafter. This is the state I am referring as stuck.
I am just a "user" like you, and have no special inside into the silicon, and design. But this sounds plausible. Perhaps a NXP engineer can confirm.
I once had such an experience with the PCF8591 (a 5V I2C-driven device), which played dead if one of the analog inputs rose slightly about 5V. Only power-cycling helped.
Hello
Hope you are well. Another suggestion I have is update to the most recent version of the SDK. As Frank suggested you can refer to the examples of the SDK to check if it is working as expected.
Let me know if this is helpful, if you have more questions do not hesitate to ask me.
Best regards,
Omar
when we provide more then 10V at input ds_p, a spike of >4V and <1us is observed at ds_ain.
After that the DATA VALID bit remains ZERO, and does not set even if when the spike passed away and ADC pin is getting normal voltage.
After CPU reset it works fine!
The scenario doesn't change even if we use interrupt based ADC instead of polling.
Signal levels on analog input pins must not be above the level of VDDA at any time. Otherwise, ADC readings will be invalid.
As Frank suggested adding a zener diode with a capacitor could help to soften these spikes.
In the Vdd pins we suggest adding some coupling capacitors to avoid spikes and variations in the supply voltage, this also can be helpful.
If you have more questions do not hesitate to ask me.
Best regards,
Omar
Any solution other than power cycle?
Hello
Another way to recover your module without resetting the whole MCU is clearing all flags and de initialize the module.
I suggest you to minimize the spikes since we do not recommend that the signal is above the VDDA value. This might cause invalid readings or even can damage your device.
If you have more questions do not hesitate to ask me.
Best regards,
Omar
We have provided diodes and are maintaining the permissible range of ADC input.
At the site, we are facing the issue of ADC getting stuck at INVALID data.
We're not sure, how it happens. but we know the issue id due to ADC getting stuck at INVALID data.
We'll enhance the ADC input protection circuit once it is confirmed that it is due to spike/over voltage.
But adding diode is protection, not the cure. What if it happened due to some other reason?
What steps should be taken to recover ADC from INVALID data loop?
> Otherwise, ADC readings will be invalid.
I think the point is, the readings will be invalid (and the ADC remains dysfunctional) until a power cycle. This behavior is a bit unexpected, and remains to be explained.
I suppose there is not much you can do - except filtering out such spikes. I would try a zener diode with an Uz of about 3,5V, but better ask a hardware designer.
I assume NXP staff and engineers have more insight in design details, and can explain this effect.
please have a look at this. (above conversation)
There are things missing in your post that are required for the ADC to work correctly, like the GPIO and ADC initialisation.
Build and run an ADC example from the SDK, and check it with a debugger.
I am using the OM13098 (LPCXpresso54628), and this example worked fine.