From: Nathael Pajani Date: Tue, 26 Apr 2016 23:00:00 +0000 (+0200) Subject: Improvements to watchdog support X-Git-Url: http://git.techno-innov.fr/?a=commitdiff_plain;h=74574d0cc5075c0b6691278cf5817aa63dfaba53;p=soft%2Flpc122x%2Fcore Improvements to watchdog support --- diff --git a/core/watchdog.c b/core/watchdog.c index a9d0974..e3731e3 100644 --- a/core/watchdog.c +++ b/core/watchdog.c @@ -38,17 +38,23 @@ void watchdog_feed(void) { struct lpc_watchdog* wdt = LPC_WDT; + subsystem_power(LPC_SYS_ABH_CLK_CTRL_Watchdog, 1); lpc_disable_irq(); wdt->feed_seqence = 0xAA; wdt->feed_seqence = 0x55; lpc_enable_irq(); } +static void (*wdt_callback)(void) = NULL; + void WDT_Handler(void) { - /* Nothing to do, we are only waking up the vehicule by generating an interrupt */ struct lpc_watchdog* wdt = LPC_WDT; wdt->mode |= LPC_WDT_INTR_FLAG; + /* Call user callback if the user registered one */ + if (wdt_callback != NULL) { + wdt_callback(); + } } /* Lock the watchdog clock source. Once the clock is locked, the configuration is @@ -143,14 +149,16 @@ void watchdog_config(const struct wdt_config* wd_conf) NVIC_DisableIRQ(WDT_IRQ); /* Power wadchdog block before changing it's configuration */ subsystem_power(LPC_SYS_ABH_CLK_CTRL_Watchdog, 1); - /* Configure watchdog timeout for normal operation */ - wdt->timer_const = ((wd_conf->nb_clk >> 2) & LPC_WDT_TIMER_MAX); /* If intr_mode_only is set, a watchdog timeout will trigger an interrupt instead of a reset */ if (wd_conf->intr_mode_only == 1) { wdt->mode = LPC_WDT_EN; } else { wdt->mode = LPC_WDT_EN | LPC_WDT_RESET_ON_TIMEOUT; } + /* Register the callback for the interrupt */ + wdt_callback = wd_conf->callback; + /* Configure watchdog timeout for normal operation */ + wdt->timer_const = ((wd_conf->nb_clk >> 2) & LPC_WDT_TIMER_MAX); /* Watchdog clock select */ if (wd_conf->clk_sel == LPC_WDT_CLK_IRC) { sys_ctrl->powerdown_run_cfg &= ~(LPC_POWER_DOWN_IRC); @@ -163,8 +171,6 @@ void watchdog_config(const struct wdt_config* wd_conf) /* Use the windows functionnality ? */ if (wd_conf->wdt_window > 0x100) { wdt->window_compare = (wd_conf->wdt_window & LPC_WDT_TIMER_MAX); - } else { - wdt->window_compare = LPC_WDT_TIMER_MAX; } /* Warning interrupt ? */ if (wd_conf->wdt_warn != 0) { @@ -274,7 +280,7 @@ void startup_watchdog_disable(void) struct lpc_watchdog* wdt = LPC_WDT; /* Power wadchdog block before changing it's configuration */ - sys_ctrl->sys_AHB_clk_ctrl |= LPC_SYS_ABH_CLK_CTRL_Watchdog; + subsystem_power(LPC_SYS_ABH_CLK_CTRL_Watchdog, 1); /* Stop watchdog */ wdt->mode = 0; watchdog_feed(); diff --git a/include/core/watchdog.h b/include/core/watchdog.h index 54b40c5..c14b8c0 100644 --- a/include/core/watchdog.h +++ b/include/core/watchdog.h @@ -44,6 +44,7 @@ struct wdt_config { /* clk_sel is either 0 (IRC) or 1 (WDTCLK). The corresponding clock source will be powered on. */ int clk_sel; int intr_mode_only; /* If set to 1, a watchdog timeout will trigger an interrupt instead of a reset */ + void (*callback)(void); uint32_t locks; /* Bitfield from WDT_*_LOCK defined in watchdog.h */ /* Number of clk_src clocks before the watchdog timer times out. Will be divided by 4 to give * the watchdog reload value */