/* * ======== switchToWatchdogTimer ======== * * Use 250ms watchdog timer interrupt to drive the Clock tick * Stop the default Timer_A then start the watchdog timer. */ static void switchToWatchdogTimer() { Clock_TimerProxy_Handle clockTimer; static Hwi_Handle wdtHwi = NULL; /* Stop Timer_A currrently being used by Clock */ clockTimer = Clock_getTimerHandle(); Clock_TimerProxy_stop(clockTimer); MAP_WDT_A_holdTimer(); if (wdtHwi == NULL) { /* Create watchdog Timer Hwi */ wdtHwi = Hwi_create(19, clockTickFxn, NULL, NULL); /* set WDT to use 32KHz input, 250ms period */ MAP_WDT_A_initIntervalTimer(WDT_A_CLOCKSOURCE_XCLK, WDT_A_CLOCKITERATIONS_8192); } /* don't allow deeper than DEEPSLEEP1 */ Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_1); /* Start watchdog Timer */ MAP_WDT_A_clearTimer(); MAP_WDT_A_startTimer(); /* hence, Clock_tick() will be called from 250ms watchdog timer interrupt */ }
/* * ======== WatchdogMSP432_open ======== */ Watchdog_Handle WatchdogMSP432_open(Watchdog_Handle handle, Watchdog_Params *params) { uintptr_t key; HwiP_Params hwiParams; WatchdogMSP432_Object *object = handle->object; WatchdogMSP432_HWAttrs const *hwAttrs = handle->hwAttrs; /* If params are NULL use defaults. */ if (params == NULL) { params = (Watchdog_Params *) &Watchdog_defaultParams; } /* Ensure a callbackFxn is specified if using watchdog in interval mode */ DebugP_assert((params->resetMode == Watchdog_RESET_ON) || (params->callbackFxn != NULL)); /* Don't allow preemption */ key = HwiP_disable(); /* Check if the Watchdog is open already with the HWAttrs */ if (object->isOpen) { HwiP_restore(key); DebugP_log1("Watchdog: Handle %x already in use.", (uintptr_t) handle); return (NULL); } object->isOpen = true; HwiP_restore(key); /* * Add power management support - Disable performance transitions while * opening the driver. */ Power_setConstraint(PowerMSP432_DISALLOW_PERF_CHANGES); if (params->resetMode == Watchdog_RESET_ON || hwAttrs->clockSource == WDT_A_CLOCKSOURCE_SMCLK || hwAttrs->clockSource == WDT_A_CLOCKSOURCE_ACLK) { /* * Do not support power modes lower than LPM0 if in watchdog mode or * in interval mode and using SMCLK or ACLK as clock sources. * Additionally, LPM3.5 cannot be reached. */ Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0); Power_setConstraint(PowerMSP432_DISALLOW_SHUTDOWN_0); } else { /* * Interval mode and not using SMCLK and ACLK as clock sources. Can * be configured as a LPM3.5 wake up source, so we do not set the * SHUTDOWN_0 constraint. */ Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_1); } /* SHUTDOWN_1 (LPM4.5) not supported while driver is open */ Power_setConstraint(PowerMSP432_DISALLOW_SHUTDOWN_1); /* Construct Hwi object for watchdog */ if (params->callbackFxn) { HwiP_Params_init(&hwiParams); hwiParams.arg = (uintptr_t) handle; hwiParams.priority = hwAttrs->intPriority; object->hwiHandle = HwiP_create(hwAttrs->intNum, params->callbackFxn, &hwiParams); if (!object->hwiHandle) { DebugP_log0("Watchdog: HwiP_create() failed"); Power_releaseConstraint(PowerMSP432_DISALLOW_PERF_CHANGES); WatchdogMSP432_close(handle); return (NULL); } } /* Configure and initialize WDT */ object->resetMode = params->resetMode; if (object->resetMode == Watchdog_RESET_ON) { MAP_WDT_A_initWatchdogTimer(hwAttrs->clockSource, hwAttrs->clockDivider); } else { MAP_WDT_A_initIntervalTimer(hwAttrs->clockSource, hwAttrs->clockDivider); } MAP_WDT_A_startTimer(); /* Allow performance level changes */ Power_releaseConstraint(PowerMSP432_DISALLOW_PERF_CHANGES); DebugP_log1("Watchdog: (0x%x) opened and enabled.", (uintptr_t) handle); /* Return handle of the Watchdog object */ return (handle); }