Hi
Here is a reference from the uTasker project.
1. The user can choose to have a user interrupt callback on low of power warning by defining SUPPORT_LOW_VOLTAGE_DETECTION
2. When this is defined the user supplies a callback handler (default is the following):
extern __callback_interrupt int fnPowerFailureWarning(void)
{
fnDebugMsg("Power failing!!\r\n");
return 0;
}
3. The user also chooses the threshold voltage (typical values are - 1.8V, 1.9V, 2.1V, 2.1V, 2.7V, 2.8V, 2.9V or 3.0V) by defining it with
#define LOW_VOLTAGE_DETECTION_VOLTAGE_mV 2900 // 2.9V warning threshold
and the closest reset thresholds and warning thresholds are set using
#if !defined LOW_VOLTAGE_DETECTION_VOLTAGE_mV
#define LOW_VOLTAGE_DETECTION_VOLTAGE_mV 2100
#endif
fnEnterInterrupt(irq_LOW_VOLTAGE_ID, 0, _low_voltage_irq);
#if LOW_VOLTAGE_DETECTION_VOLTAGE_mV > 2400
PMC_LVDSC1 = (PMC_LVDSC1_LVDV | PMC_LVDSC1_LVDRE | PMC_LVDSC1_LVDACK);
#if LOW_VOLTAGE_DETECTION_VOLTAGE_mV >= 3000
PMC_LVDSC2 = (PMC_LVDSC2_LVWV_HIGH | PMC_LVDSC2_LVWIE | PMC_LVDSC2_LVWACK);
#elif LOW_VOLTAGE_DETECTION_VOLTAGE_mV >= 2950
PMC_LVDSC2 = (PMC_LVDSC2_LVWV_MID2 | PMC_LVDSC2_LVWIE | PMC_LVDSC2_LVWACK);
#elif LOW_VOLTAGE_DETECTION_VOLTAGE_mV >= 2850
PMC_LVDSC2 = (PMC_LVDSC2_LVWV_MID1 | PMC_LVDSC2_LVWIE | PMC_LVDSC2_LVWACK);
#else
PMC_LVDSC2 = (PMC_LVDSC2_LVWV_LOW | PMC_LVDSC2_LVWIE | PMC_LVDSC2_LVWACK);
#endif
#else
PMC_LVDSC1 = (PMC_LVDSC1_LVDRE | PMC_LVDSC1_LVDACK);
#if LOW_VOLTAGE_DETECTION_VOLTAGE_mV > 2050
PMC_LVDSC2 = (PMC_LVDSC2_LVWV_HIGH | PMC_LVDSC2_LVWIE | PMC_LVDSC2_LVWACK);
#elif LOW_VOLTAGE_DETECTION_VOLTAGE_mV >= 1950
PMC_LVDSC2 = (PMC_LVDSC2_LVWV_MID2 | PMC_LVDSC2_LVWIE | PMC_LVDSC2_LVWACK);
#elif LOW_VOLTAGE_DETECTION_VOLTAGE_mV >= 1850
PMC_LVDSC2 = (PMC_LVDSC2_LVWV_MID1 | PMC_LVDSC2_LVWIE | PMC_LVDSC2_LVWACK);
#else
PMC_LVDSC2 = (PMC_LVDSC2_LVWV_LOW | PMC_LVDSC2_LVWIE | PMC_LVDSC2_LVWACK);
#endif
#endif
4. The general interrupt performs
static __interrupt void _low_voltage_irq(void)
{
PMC_LVDSC2 &= ~(PMC_LVDSC2_LVWIE);
if (fnPowerFailureWarning() != 0) {
OR_ONE_TO_CLEAR(PMC_LVDSC2, (PMC_LVDSC2_LVWACK));
PMC_LVDSC2 |= (PMC_LVDSC2);
}
}
The commenting in the code should explain all technical details.
Regards
Mark
uTasker - for more performance and faster, cheaper product development