105 lines
2.6 KiB
C++
105 lines
2.6 KiB
C++
// Be careful to use a platform-specific conditional include to only make the
|
|
// code visible for the appropriate platform. Arduino will try to compile and
|
|
// link all .cpp files regardless of platform.
|
|
#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
|
|
|
|
#include <kinetis.h>
|
|
#include "WatchdogKinetisK.h"
|
|
|
|
static void one_bus_cycle(void) __attribute__((always_inline));
|
|
static void watchdog_config(int cfg, int val);
|
|
|
|
// Enable the watchdog timer to reset the machine after a period of time
|
|
// without any calls to reset(). The passed in period (in milliseconds) is
|
|
// just a suggestion and a lower value might be picked if the hardware does
|
|
// not support the exact desired value.
|
|
//
|
|
// The actual period (in milliseconds) before a watchdog timer reset is
|
|
// returned.
|
|
int WatchdogKinetisKseries::enable(int maxPeriodMS)
|
|
{
|
|
if (maxPeriodMS < 4) {
|
|
maxPeriodMS = 8000; // default is 8 seconds
|
|
}
|
|
if (setting != maxPeriodMS) {
|
|
watchdog_config(WDOG_STCTRLH_WDOGEN, maxPeriodMS);
|
|
setting = maxPeriodMS;
|
|
}
|
|
return maxPeriodMS;
|
|
}
|
|
|
|
// Reset or 'kick' the watchdog timer to prevent a reset of the device.
|
|
void WatchdogKinetisKseries::reset()
|
|
{
|
|
__disable_irq();
|
|
WDOG_REFRESH = 0xA602;
|
|
WDOG_REFRESH = 0xB480;
|
|
__enable_irq();
|
|
}
|
|
|
|
// Completely disable the watchdog timer.
|
|
void WatchdogKinetisKseries::disable()
|
|
{
|
|
if (setting > 0) {
|
|
watchdog_config(0, 4);
|
|
setting = 0;
|
|
}
|
|
}
|
|
|
|
// Enter the lowest power sleep mode for the desired period of time. The
|
|
// passed in period (in milliseconds) is just a suggestion and a lower value
|
|
// might be picked if the hardware does not support the exact desired value
|
|
//
|
|
// The actual period (in milliseconds) that the hardware was asleep will be
|
|
// returned.
|
|
int WatchdogKinetisKseries::sleep(int maxPeriodMS)
|
|
{
|
|
if (maxPeriodMS <= 0) return 0;
|
|
// TODO....
|
|
return 0;
|
|
}
|
|
|
|
static void watchdog_config(int cfg, int val)
|
|
{
|
|
__disable_irq();
|
|
WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;
|
|
WDOG_UNLOCK = WDOG_UNLOCK_SEQ2;
|
|
one_bus_cycle();
|
|
WDOG_STCTRLH = cfg | WDOG_STCTRLH_ALLOWUPDATE;
|
|
WDOG_TOVALH = val >> 16;
|
|
WDOG_TOVALL = val;
|
|
WDOG_PRESC = 0;
|
|
__enable_irq();
|
|
for (int i=0; i < 256; i++) {
|
|
one_bus_cycle();
|
|
}
|
|
}
|
|
|
|
static void one_bus_cycle(void)
|
|
{
|
|
__asm__ volatile ("nop");
|
|
#if (F_CPU / F_BUS) > 1
|
|
__asm__ volatile ("nop");
|
|
#endif
|
|
#if (F_CPU / F_BUS) > 2
|
|
__asm__ volatile ("nop");
|
|
#endif
|
|
#if (F_CPU / F_BUS) > 3
|
|
__asm__ volatile ("nop");
|
|
#endif
|
|
#if (F_CPU / F_BUS) > 4
|
|
__asm__ volatile ("nop");
|
|
#endif
|
|
#if (F_CPU / F_BUS) > 5
|
|
__asm__ volatile ("nop");
|
|
#endif
|
|
#if (F_CPU / F_BUS) > 6
|
|
__asm__ volatile ("nop");
|
|
#endif
|
|
#if (F_CPU / F_BUS) > 7
|
|
__asm__ volatile ("nop");
|
|
#endif
|
|
}
|
|
|
|
#endif
|