]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/CORTEX_A9_Cyclone_V_SoC_DK/Altera_Code/HardwareLibrary/alt_watchdog.c
Added project for Altera Cyclone V SoC, currently running from internal RAM.
[freertos] / FreeRTOS / Demo / CORTEX_A9_Cyclone_V_SoC_DK / Altera_Code / HardwareLibrary / alt_watchdog.c
diff --git a/FreeRTOS/Demo/CORTEX_A9_Cyclone_V_SoC_DK/Altera_Code/HardwareLibrary/alt_watchdog.c b/FreeRTOS/Demo/CORTEX_A9_Cyclone_V_SoC_DK/Altera_Code/HardwareLibrary/alt_watchdog.c
new file mode 100644 (file)
index 0000000..10c6007
--- /dev/null
@@ -0,0 +1,1101 @@
+\r
+/******************************************************************************\r
+*\r
+* alt_watchdog.c - API for the Altera SoC FPGA watchdog timers.\r
+*\r
+******************************************************************************/\r
+\r
+/******************************************************************************\r
+*\r
+* Copyright 2013 Altera Corporation. All Rights Reserved.\r
+*\r
+* Redistribution and use in source and binary forms, with or without\r
+* modification, are permitted provided that the following conditions are met:\r
+*\r
+* 1. Redistributions of source code must retain the above copyright notice,\r
+* this list of conditions and the following disclaimer.\r
+*\r
+* 2. Redistributions in binary form must reproduce the above copyright notice,\r
+* this list of conditions and the following disclaimer in the documentation\r
+* and/or other materials provided with the distribution.\r
+*\r
+* 3. The name of the author may not be used to endorse or promote products\r
+* derived from this software without specific prior written permission.\r
+*\r
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR\r
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO\r
+* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
+* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
+* OF SUCH DAMAGE.\r
+*\r
+******************************************************************************/\r
+\r
+/******************************************************************************\r
+*\r
+* The Altera SoC FPGA has six watchdog timers, two are local to the MPU\r
+* themselves, and the other four are accessable to either MPU.\r
+*\r
+******************************************************************************/\r
+\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include "socal/hps.h"\r
+#include "socal/socal.h"\r
+#include "socal/alt_rstmgr.h"\r
+#include "socal/alt_l4wd.h"\r
+#include "socal/alt_tmr.h"\r
+#include "hwlib.h"\r
+#include "alt_mpu_registers.h"\r
+#include "alt_watchdog.h"\r
+#include "alt_clock_manager.h"\r
+\r
+\r
+    /* Useful constants and utilities */\r
+\r
+bool cpu_wdog_in_gpt_mode(void)\r
+{\r
+    return !(alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) & WDOG_WDT_MODE);\r
+}\r
+\r
+static inline bool cpu_wdog_in_wdt_mode(void)\r
+{\r
+    return (alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) & WDOG_WDT_MODE);\r
+}\r
+\r
+\r
+/* This value must be written to the Counter Restart Register of the\r
+ * peripheral watchdog timers to restart them. */\r
+#define WDOG_RESET_KEY          0x00000076\r
+\r
+#define ALT_WDOG_RST_WIDTH      8                       /* 8 or more MPU clock cycles */\r
+\r
+\r
+inline static void alt_wdog_wait(void* reg, uint32_t cnt)\r
+{\r
+    for (; cnt ; cnt--)\r
+    {\r
+        (void) alt_read_word(reg);\r
+    }\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Initialize the watchdog timer module before use                                      */\r
+/****************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_wdog_init(void)\r
+{\r
+    // put watchdog timer modules into system manager reset if not already there\r
+    alt_wdog_uninit();\r
+    // release L4 watchdog timer modules from system reset (w/ four instruction-cycle delay)\r
+    alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, ALT_RSTMGR_PERMODRST_L4WD0_SET_MSK |\r
+            ALT_RSTMGR_PERMODRST_L4WD1_SET_MSK);\r
+\r
+    // release *both* ARM watchdog timer modules from system reset (if in reset)\r
+    // does not put either one into watchdog timer mode\r
+    alt_clrbits_word(ALT_RSTMGR_MPUMODRST_ADDR, ALT_RSTMGR_MPUMODRST_WDS_SET_MSK);\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Return the local ARM watchdog timer back to general-purpose timer mode               */\r
+/****************************************************************************************/\r
+\r
+void alt_ARM_wdog_gpt_mode_set(void)\r
+{\r
+    while (alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) & WDOG_WDT_MODE)\r
+    {\r
+        alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_DISABLE_REG_OFFSET, WDOG_DISABLE_VAL0);\r
+        alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_DISABLE_REG_OFFSET, WDOG_DISABLE_VAL1);\r
+    }\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Set the local ARM watchdog timer to watchdog timer mode                              */\r
+/****************************************************************************************/\r
+\r
+void alt_ARM_wdog_wdog_mode_set(void)\r
+{\r
+    alt_setbits_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET, WDOG_WDT_MODE);\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Uninitialize the watchdog timer module & return to reset state                        */\r
+/****************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_wdog_uninit(void)\r
+{\r
+    // put L4 watchdog modules into system manager reset\r
+    alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR,\r
+            ALT_RSTMGR_PERMODRST_L4WD0_SET_MSK | ALT_RSTMGR_PERMODRST_L4WD1_SET_MSK);\r
+\r
+        // using the system manager bit to reset the ARM watchdog timer\r
+        // resets *both* ARM watchdog timers, which is often not advisable,\r
+        // so we reset the local ARM watchdog timer manually:\r
+\r
+        // first, stop the ARM watchdog timer & disable interrupt\r
+    alt_clrbits_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET, WDOG_TMR_ENABLE | WDOG_INT_EN);\r
+        // reset load and counter registers\r
+    alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_LOAD_REG_OFFSET, 0);\r
+        // clear any pending reset and interrupt status\r
+    alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_RSTSTAT_REG_OFFSET, WDOG_RST_STAT_BIT);\r
+    alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_INTSTAT_REG_OFFSET, WDOG_INT_STAT_BIT);\r
+        // return ARM watchdog timer to (initial) general-purpose timer mode\r
+    alt_ARM_wdog_gpt_mode_set();\r
+        // now write zeros to the control register significant bitfields\r
+        // and then verify that all significant bitfields return zero\r
+    alt_clrbits_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET,\r
+            (WDOG_PS_MASK | WDOG_WDT_MODE | WDOG_INT_EN | WDOG_AUTO_RELOAD | WDOG_TMR_ENABLE));\r
+    if (alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET)\r
+            & (WDOG_PS_MASK | WDOG_WDT_MODE | WDOG_INT_EN | WDOG_AUTO_RELOAD | WDOG_TMR_ENABLE))\r
+    {\r
+        return ALT_E_ERROR;\r
+    }\r
+    return ALT_E_SUCCESS;\r
+\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Stops the specified watchdog timer.                                                  */\r
+/****************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_wdog_stop(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    ALT_STATUS_CODE         ret = ALT_E_BAD_ARG;    // return value\r
+    uint32_t                config;                 // the current configuration\r
+    uint32_t                loadreg;                // current restart value\r
+\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET,\r
+                (alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) & ~WDOG_TMR_ENABLE));\r
+        ret = ALT_E_SUCCESS;\r
+    }\r
+\r
+    // these timers can only be reset by using a system manager reset\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))\r
+    {\r
+        config = alt_read_word(ALT_L4WD0_WDT_CR_ADDR);      // read current timer mode\r
+        loadreg = alt_read_word(ALT_L4WD0_WDT_TORR_ADDR);   // read timer restart values\r
+        alt_write_word(ALT_RSTMGR_PERMODRST_ADDR,\r
+                alt_read_word(ALT_RSTMGR_PERMODRST_ADDR) | ALT_RSTMGR_PERMODRST_L4WD0_SET_MSK);\r
+                        // assert reset & wait\r
+        alt_wdog_wait(ALT_RSTMGR_PERMODRST_ADDR, ALT_WDOG_RST_WIDTH);\r
+        alt_write_word(ALT_RSTMGR_PERMODRST_ADDR,\r
+                alt_read_word(ALT_RSTMGR_PERMODRST_ADDR) & ALT_RSTMGR_PERMODRST_L4WD0_CLR_MSK);\r
+                        // release peripheral reset signal by clearing bit\r
+        alt_write_word(ALT_L4WD0_WDT_TORR_ADDR, loadreg);   // restore timer restart value\r
+        alt_write_word(ALT_L4WD0_WDT_CR_ADDR, config & ALT_TMR_TMR1CTLREG_TMR1_EN_CLR_MSK);\r
+                          // restore previous timer mode except timer isn't started\r
+        ret = ALT_E_SUCCESS;\r
+    }\r
+    else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        config = alt_read_word(ALT_L4WD1_WDT_CR_ADDR);      // read current timer mode\r
+        loadreg = alt_read_word(ALT_L4WD1_WDT_TORR_ADDR);   // read timer restart values\r
+        alt_write_word(ALT_RSTMGR_PERMODRST_ADDR,\r
+                alt_read_word(ALT_RSTMGR_PERMODRST_ADDR) | ALT_RSTMGR_PERMODRST_L4WD1_SET_MSK);\r
+                        // assert reset & wait\r
+        alt_write_word(ALT_RSTMGR_PERMODRST_ADDR,\r
+                alt_read_word(ALT_RSTMGR_PERMODRST_ADDR) & ALT_RSTMGR_PERMODRST_L4WD1_CLR_MSK);\r
+                         // release peripheral reset signal by clearing bit\r
+        alt_write_word(ALT_L4WD1_WDT_TORR_ADDR, loadreg);   // restore timer restart value\r
+        alt_write_word(ALT_L4WD1_WDT_CR_ADDR, config & ALT_TMR_TMR1CTLREG_TMR1_EN_CLR_MSK);\r
+                          // restore previous timer mode except timer isn't started\r
+        ret = ALT_E_SUCCESS;\r
+    }\r
+    return  ret;\r
+}\r
+\r
+/****************************************************************************************/\r
+/* Start the specified watchdog timer.                                                  */\r
+/****************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_wdog_start(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    ALT_STATUS_CODE     ret = ALT_E_BAD_ARG;    // return value\r
+    uint32_t            regdata;                // data\r
+\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        regdata = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET);\r
+        alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET, regdata | WDOG_TMR_ENABLE);\r
+        ret = ALT_E_SUCCESS;\r
+    }\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))\r
+    {\r
+        regdata = alt_read_word(ALT_L4WD0_WDT_CR_ADDR);\r
+        alt_write_word(ALT_L4WD0_WDT_CR_ADDR, regdata | ALT_L4WD_CR_WDT_EN_SET_MSK);\r
+        ret = ALT_E_SUCCESS;\r
+    }\r
+    else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        regdata = alt_read_word(ALT_L4WD1_WDT_CR_ADDR);\r
+        alt_write_word(ALT_L4WD1_WDT_CR_ADDR, regdata | ALT_L4WD_CR_WDT_EN_SET_MSK);\r
+        ret = ALT_E_SUCCESS;\r
+    }\r
+    return  ret;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Returns whether the specified watchdog timer is currently running or not.            */\r
+/****************************************************************************************/\r
+\r
+bool alt_wdog_tmr_is_enabled(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    bool      ret = false;          // return value\r
+\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        ret = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) & WDOG_TMR_ENABLE;\r
+    }\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))\r
+    {\r
+        ret = alt_read_word(ALT_L4WD0_WDT_CR_ADDR) & ALT_L4WD_CR_WDT_EN_SET_MSK;\r
+    }\r
+\r
+    else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        ret = alt_read_word(ALT_L4WD1_WDT_CR_ADDR) & ALT_L4WD_CR_WDT_EN_SET_MSK;\r
+    }\r
+    return  ret;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/*  Reloads the counter countdown value and restarts the watchdog timer. User can reset */\r
+/*  the timer at any time before timeout. Also known as kicking, petting, feeding,      */\r
+/* waking, or walking the watchdog. Inherently clears the interrupt as well.            */\r
+/****************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_wdog_reset(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    uint32_t                regdata;        // data read\r
+\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        regdata = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_LOAD_REG_OFFSET);\r
+        alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_LOAD_REG_OFFSET, regdata);\r
+                // verify operation when we have hardware,\r
+                // the ARM documentation is somewhat vague here\r
+\r
+        if (cpu_wdog_in_wdt_mode())\r
+        {\r
+            alt_write_word((CPU_WDTGPT_TMR_BASE + WDOG_RSTSTAT_REG_OFFSET), WDOG_RST_STAT_BIT);\r
+                      // depending on current mode, clear the reset bit or...\r
+        }\r
+        else\r
+        {\r
+            alt_write_word((CPU_WDTGPT_TMR_BASE + WDOG_INTSTAT_REG_OFFSET), WDOG_INT_STAT_BIT);\r
+                      // ...clear the interrupt status bit by writing one to it\r
+        }\r
+    }\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))\r
+    {\r
+        alt_write_word(ALT_L4WD0_WDT_CRR_ADDR, WDOG_RESET_KEY);\r
+            //restarts the counter, also clears the watchdog timer interrupt\r
+    }\r
+    else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        alt_write_word(ALT_L4WD1_WDT_CRR_ADDR, WDOG_RESET_KEY);\r
+            //restarts the counter, also clears the watchdog timer interrupt\r
+    }\r
+    else {return  ALT_E_BAD_ARG; }\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Sets the countdown value of the specified timer.                                     */\r
+/****************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_wdog_counter_set(ALT_WDOG_TIMER_t tmr_id, uint32_t val)\r
+{\r
+    ALT_STATUS_CODE         ret = ALT_E_BAD_ARG;    // return value\r
+    uint32_t                regdata;                // returned data\r
+\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_LOAD_REG_OFFSET, val);\r
+        ret = ALT_E_SUCCESS;\r
+        // the ARM documentation is somewhat vague here, but it looks like it should be\r
+        // possible to rewrite this value while counter is running, and that it works in\r
+        // watchdog mode as well as timer mode. Verify operation when we have hardware.\r
+    }\r
+    else if (val <= ALT_WDOG_TIMEOUT2G)\r
+    {\r
+        if (tmr_id == ALT_WDOG0)\r
+        {\r
+            // set regular timeout value\r
+            regdata = alt_read_word(ALT_L4WD0_WDT_TORR_ADDR);\r
+            alt_write_word(ALT_L4WD0_WDT_TORR_ADDR, (regdata & ALT_L4WD_TORR_TOP_CLR_MSK) | val);\r
+            ret = ALT_E_SUCCESS;\r
+        }\r
+        else if (tmr_id == ALT_WDOG1)\r
+        {\r
+            // set regular timeout value\r
+            regdata = alt_read_word(ALT_L4WD1_WDT_TORR_ADDR);\r
+            alt_write_word(ALT_L4WD1_WDT_TORR_ADDR, (regdata & ALT_L4WD_TORR_TOP_CLR_MSK) | val);\r
+            ret = ALT_E_SUCCESS;\r
+        }\r
+        else if (tmr_id == ALT_WDOG0_INIT)\r
+        {\r
+            // set initial timeout value\r
+            regdata = alt_read_word(ALT_L4WD0_WDT_TORR_ADDR);\r
+            regdata = (regdata & ALT_L4WD_TORR_TOP_INIT_CLR_MSK) |\r
+                    (val << ALT_L4WD_TORR_TOP_INIT_LSB);\r
+            alt_write_word(ALT_L4WD0_WDT_TORR_ADDR, regdata);\r
+            ret = ALT_E_SUCCESS;\r
+        }\r
+        else if (tmr_id == ALT_WDOG1_INIT)\r
+        {\r
+            // set initial timeout value\r
+            regdata = alt_read_word(ALT_L4WD1_WDT_TORR_ADDR);\r
+            regdata = (regdata & ALT_L4WD_TORR_TOP_INIT_CLR_MSK) |\r
+                    (val << ALT_L4WD_TORR_TOP_INIT_LSB);\r
+            alt_write_word(ALT_L4WD1_WDT_TORR_ADDR, regdata);\r
+            ret = ALT_E_SUCCESS;\r
+        }\r
+    }\r
+    return  ret;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Returns the current counter value of the specified timer.                            */\r
+/****************************************************************************************/\r
+\r
+uint32_t alt_wdog_counter_get_current(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    uint32_t     ret = 0;           // return value\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        ret = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CNTR_REG_OFFSET);\r
+    }\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))\r
+    {\r
+        ret = alt_read_word(ALT_L4WD0_WDT_CCVR_ADDR);\r
+    }\r
+    else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        ret = alt_read_word(ALT_L4WD1_WDT_CCVR_ADDR);\r
+    }\r
+    return ret;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Returns the current counter value of the specified timer, as measured in             */\r
+/* milliseconds. For ALT_CPU_WATCHDOG, this includes the effects of the prescaler       */\r
+/* setting.                                                                             */\r
+/****************************************************************************************/\r
+\r
+uint32_t alt_wdog_counter_get_curtime_millisecs(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    uint32_t        time = 0;           // return value\r
+    uint64_t        bigtime;            // temp for math\r
+    alt_freq_t      freq;               // clock frequency\r
+    ALT_CLK_t       clk;                // clock ID\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        clk = ALT_CLK_MPU_PERIPH;\r
+    }\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG1) ||\r
+            (tmr_id == ALT_WDOG0_INIT) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        clk = ALT_CLK_OSC1;\r
+    }\r
+    else { return time; }\r
+\r
+    if ((alt_clk_freq_get(clk, &freq) == ALT_E_SUCCESS) && (freq != 0))\r
+    {                               // get clock frequency & test\r
+        time = alt_wdog_counter_get_current(tmr_id);    // get current counter value\r
+        if (time != 0)\r
+        {\r
+            bigtime = (uint64_t) time;\r
+                  // the current time period is not counted, only whole periods are counted\r
+            if (tmr_id == ALT_WDOG_CPU)\r
+            {\r
+                bigtime *= (uint64_t) (alt_wdog_core_prescaler_get() + 1);\r
+            }\r
+            bigtime *= ALT_MILLISECS_IN_A_SEC;\r
+            bigtime /= freq;          // cycles-per-second becomes milliseconds-per-cycle\r
+            time = (bigtime > (uint64_t) UINT32_MAX) ? 0 : (uint32_t) bigtime;\r
+        }\r
+    }\r
+    return  time;\r
+}\r
+\r
+\r
+// see the return value range calculations below at alt_wdog_counter_get_inittime_millisecs().\r
+\r
+/****************************************************************************************/\r
+/* Returns the initial counter value of the specified timer as a 32-bit integer         */\r
+/* value. This is the value that will be reloaded when the timer is reset or restarted. */\r
+/* For the timers where this value is set as an encoded powers-of-two between 15 and    */\r
+/* 31, the value is converted into the equivalent binary value before returning it. For */\r
+/* ALT_CPU_WATCHDOG, the returned value does not include the effects of the prescaler   */\r
+/* setting                                                                              */\r
+/****************************************************************************************/\r
+\r
+uint32_t alt_wdog_counter_get_init(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    uint32_t                ret = 0;        //    value to return\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        ret = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_LOAD_REG_OFFSET);\r
+    }\r
+    else if (tmr_id == ALT_WDOG0)\r
+    {\r
+        ret = ALT_L4WD_TORR_TOP_GET(alt_read_word(ALT_L4WD0_WDT_TORR_ADDR));\r
+        ret = (ret >  ALT_L4WD_TORR_TOP_E_TMO2G) ? 0 : ALT_TWO_TO_POW16 << ret;\r
+    }\r
+    else if (tmr_id == ALT_WDOG1)\r
+    {\r
+        ret = ALT_L4WD_TORR_TOP_GET(alt_read_word(ALT_L4WD1_WDT_TORR_ADDR));\r
+        ret = (ret >  ALT_L4WD_TORR_TOP_E_TMO2G) ? 0 : ALT_TWO_TO_POW16 << ret;\r
+    }\r
+    else if (tmr_id == ALT_WDOG0_INIT)\r
+    {\r
+        ret = ALT_L4WD_TORR_TOP_INIT_GET(alt_read_word(ALT_L4WD0_WDT_TORR_ADDR));\r
+        ret = (ret >  ALT_L4WD_TORR_TOP_INIT_E_TMO2G) ? 0 : ALT_TWO_TO_POW16 << ret;\r
+    }\r
+    else if (tmr_id == ALT_WDOG1_INIT)\r
+    {\r
+        ret = ALT_L4WD_TORR_TOP_INIT_GET(alt_read_word(ALT_L4WD1_WDT_TORR_ADDR));\r
+        ret = (ret >  ALT_L4WD_TORR_TOP_INIT_E_TMO2G) ? 0 : ALT_TWO_TO_POW16 << ret;\r
+    }\r
+    return  ret;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Returns the initial value of the specified timer in nanoseconds. This is the         */\r
+/* value that will be reloaded when the timer is reset or restarted. For                */\r
+/* ALT_CPU_WATCHDOG, this includes the effects of the prescaler setting.  This call     */\r
+/* returns a more precise result than alt_wdog_counter_get_inittime_millisecs(), but    */\r
+/* as an unsigned 64-bit integer.                                                       */\r
+/****************************************************************************************/\r
+\r
+uint64_t alt_wdog_counter_get_inittime_nanosecs(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    uint64_t    time = 0;\r
+    alt_freq_t  freq;\r
+    ALT_CLK_t   clk;\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        clk = ALT_CLK_MPU_PERIPH;\r
+    }\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG1) ||\r
+            (tmr_id == ALT_WDOG0_INIT) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        clk = ALT_CLK_OSC1;\r
+    }\r
+    else { return time; }            // zero always indicates an error for an init time\r
+\r
+    if ((alt_clk_freq_get(clk, &freq) == ALT_E_SUCCESS) && (freq != 0))\r
+    {                               // get clock frequency & test\r
+        time = (uint64_t) alt_wdog_counter_get_init(tmr_id);     // get reset value\r
+        if (time != 0)\r
+        {\r
+            time += 1;\r
+            if (tmr_id == ALT_WDOG_CPU)\r
+            {\r
+                time *= (uint64_t) (alt_wdog_core_prescaler_get() + 1);\r
+            }\r
+            time *= ALT_NANOSECS_IN_A_SEC;\r
+            time /= freq;              // cycles-per-second becomes nanoseconds per cycle\r
+        }\r
+    }\r
+\r
+    return  time;\r
+}\r
+\r
+\r
+/*  For reviewers:\r
+ * minimum clock divider for ALT_CPU_WATCHDOG is 1\r
+ * maximum clock divider for ALT_CPU_WATCHDOG is ((0xFFFF FFFF + 1) x (0x0000 0100) = 0x0000 0100 0000 0000)\r
+ * multiply that by the number of nanoseconds in a second (1,000,000,000)\r
+ *                              = 1,099,511,627,776,000,000,000 (0x9ACA 0000 0000 0000)\r
+ * so the countdown time with the slowest mpu_peripheral clock (2.5 MHz) =\r
+ *                              400 nS to 439,804.6511104 seconds (0x0001 9000 0000 0000 nS)\r
+ * and with the fastest mpu_peripheral clock (200 MHz) =\r
+ *                              5 nS to 5,497,558,138,880 nanoseconds ( 0x0000 0500 0000 0000 nS)\r
+ *\r
+ * minimum clock divider for peripheral watchdogs is 2**16 = (65,536 = 0x00010000)\r
+ * maximum clock divider for peripheral watchdogs is 2**31 = (2,147,483,648 = 0x8000 0000)\r
+ * multiply that by the number of nanoseconds in a second (1,000,000,000) =\r
+ *              4,096,000,000,000 (0x0000 03B9 ACA0 0000) to 2,147,483,648,000,000,000 (0x1DCD 6500 0000 0000)\r
+ * so the countdown time with the slowest l4_sp_clk (625 kHz) =\r
+ *              6,553,600 nS (0x0064 0000) to 3,435,973,836,800 nS (0x0000 0320 0000 0000 nS)\r
+ * and with the fastest l4_sp_clk (100 MHz) =\r
+ *              40,960 ns (0xA000) to 21,474,836,480 nS (0x0000 0005 0000 0000 nS)\r
+ */\r
+\r
+/****************************************************************************************/\r
+/* Returns the initial value of the specified timer in milliseconds. This is the        */\r
+/* value that will be reloaded when the timer is reset or restarted. For                */\r
+/* ALT_CPU_WATCHDOG, this includes the effects of the prescaler setting. This call      */\r
+/* returns a 32-bit unsigned integer, though is less precise than                       */\r
+/* alt_wdog_counter_get_inittime_nanosecs().                                            */\r
+/****************************************************************************************/\r
+\r
+uint32_t alt_wdog_counter_get_inittime_millisecs(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    uint32_t        time = 0;\r
+    alt_freq_t      freq;\r
+    ALT_CLK_t       clk;\r
+    uint64_t        bigtime;\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        clk = ALT_CLK_MPU_PERIPH;\r
+    }\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG1) ||\r
+            (tmr_id == ALT_WDOG0_INIT) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        clk = ALT_CLK_OSC1;\r
+    }\r
+    else { return time; }                             // must be an invalid tmr_id\r
+\r
+    if ((alt_clk_freq_get(clk, &freq) == ALT_E_SUCCESS) && (freq != 0))\r
+    {                               // get clock frequency & test\r
+        time = alt_wdog_counter_get_init(tmr_id);    // get reset value\r
+        if (time != 0)\r
+        {\r
+            bigtime = ((uint64_t) time) + 1;\r
+            if (tmr_id == ALT_WDOG_CPU)         // the only watchdog with a prescaler\r
+            {\r
+                bigtime *= (uint64_t) (alt_wdog_core_prescaler_get() + 1);\r
+            }\r
+            bigtime *= ALT_MILLISECS_IN_A_SEC;                         // scale value\r
+            bigtime /= freq;              // cycles-per-second becomes milliseconds per cycle\r
+            time = (bigtime > (uint64_t) UINT32_MAX) ? 0 : (uint32_t) bigtime;\r
+        }\r
+    }\r
+    return  time;\r
+}\r
+\r
+\r
+/*  For reviewers:\r
+ * minimum clock divider for ALT_CPU_WATCHDOG is 1\r
+ * maximum clock divider for ALT_CPU_WATCHDOG is ((0xFFFF FFFF + 1) x (0x0000 0100) = 0x0000 0100 0000 0000)\r
+ * multiply that by the number of milliseconds in a second (1,000)\r
+ *                    = 1,000 (0x3e8) to 1,099,511,627,776,000 (0x0003 E800 0000 0000)\r
+ * so the countdown time with the slowest mpu_peripheral clock (2.5 MHz) =\r
+ *                      0 mS to 439,804.6511104 seconds (0x1A36 E2EB mS)\r
+ * and with the fastest mpu_peripheral clock (200 MHz) =\r
+ *                      0 mS to 5,497.55813888 seconds ( 0x0053 E2D6 mS)\r
+ *\r
+ * minimum clock divider for peripheral watchdogs is 2**16 = (65,536 = 0x00010000)\r
+ * maximum clock divider for peripheral watchdogs is 2**31 = (2,147,483,648 = 0x8000 0000)\r
+ * multiply that by the number of milliseconds in a second (1,000) =\r
+ *              65,536,000 (0x3E8 0000) to 2,147,483,648,000 (0x01F4 0000 0000)\r
+ * so the countdown time with the slowest l4_sp_clk (625 kHz) =\r
+ *                  104 mS (0x0068) to 3,435,973 mS (0x0034 6DC5 mS)\r
+ * and with the fastest l4_sp_clk (100 MHz) = 0 mS to 21,474 mS (0x0000 53E2 mS)\r
+ */\r
+\r
+/****************************************************************************************/\r
+/* Sets the value of the CPU watchdog timer ALT_CPU_WATCHDOG prescaler.                 */\r
+/****************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_wdog_core_prescaler_set(uint32_t val)\r
+{\r
+    ALT_STATUS_CODE     ret = ALT_E_BAD_ARG;            // return value\r
+    uint32_t            regdata;\r
+\r
+    if (val <= WDOG_PS_MAX)\r
+    {\r
+        if (alt_wdog_tmr_is_enabled(ALT_WDOG_CPU))\r
+        {\r
+            ret = ALT_E_ERROR;\r
+        }\r
+        else\r
+        {\r
+            regdata = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET);\r
+            alt_write_word((CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET),\r
+                    (regdata & ~WDOG_PS_MASK) | (val << WDOG_PS_SHIFT));\r
+            ret = ALT_E_SUCCESS;\r
+        }\r
+    }\r
+    return  ret;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Returns the value of the prescaler of the CPU core watchdog timer.                   */\r
+/****************************************************************************************/\r
+\r
+uint32_t alt_wdog_core_prescaler_get(void)\r
+{\r
+    return  (alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) &\r
+                    WDOG_PS_MASK) >> WDOG_PS_SHIFT;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Returns the maximum possible counter value of the specified timer as a 32-bit value. */\r
+/* For the timers where this value is encoded (as powers-of-two between 15 and 31), the */\r
+/* encoded value is converted into the equivalent binary value before returning it.     */\r
+/* This does not include the effects of the prescaler available for ALT_CPU_WATCHDOG.   */\r
+/****************************************************************************************/\r
+\r
+uint32_t alt_wdog_counter_get_max(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    uint32_t                ret = 0;        // return value\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        ret = WDOG_TMR_MAX;\r
+    }\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG1)\r
+            || (tmr_id == ALT_WDOG0_INIT) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        ret = ((uint32_t) ALT_TWO_TO_POW16) << ALT_WDOG_TIMEOUT2G;\r
+    }\r
+\r
+    return  ret;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Returns the maximum possible delay time of the specified timer specified in          */\r
+/* nanoseconds. For ALT_CPU_WATCHDOG, this includes the prescaler setting. This call    */\r
+/* returns a more precise reading of the counter than                                   */\r
+/* alt_wdog_counter_get_max_millisecs(), though in an unsigned 64-bit integer.          */\r
+/****************************************************************************************/\r
+\r
+uint64_t alt_wdog_counter_get_max_nanosecs(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    uint64_t    time = 0;\r
+    alt_freq_t  freq;\r
+    ALT_CLK_t   clk;\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        clk = ALT_CLK_MPU_PERIPH;\r
+    }\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG1) ||\r
+            (tmr_id == ALT_WDOG0_INIT) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        clk = ALT_CLK_OSC1;\r
+    }\r
+    else { return time; }\r
+\r
+    if ((alt_clk_freq_get(clk, &freq) == ALT_E_SUCCESS) && (freq != 0))\r
+    {                    // get clock frequency & test\r
+        time = (uint64_t) alt_wdog_counter_get_max(tmr_id);     // get maximum reset value\r
+        if (time != 0)\r
+        {\r
+            time += 1;\r
+            if (tmr_id == ALT_WDOG_CPU)\r
+            {\r
+                time *= (WDOG_PS_MAX + 1);          // maximum prescaler\r
+            }\r
+            time *= ALT_NANOSECS_IN_A_SEC;\r
+            time /= freq;               //cycles-per-second becomes nanoseconds-per-cycle\r
+        }\r
+    }\r
+    return  time;\r
+}\r
+\r
+\r
+\r
+/****************************************************************************************/\r
+/* Returns the maximum possible delay time of the specified timer specified in          */\r
+/* milliseconds. For ALT_CPU_WATCHDOG, this includes the prescaler setting. This call   */\r
+/* returns a 32-bit unsigned integer, though is less precise than                       */\r
+/* alt_wdog_counter_get_max_nanosecs().                                                 */\r
+/****************************************************************************************/\r
+\r
+uint32_t alt_wdog_counter_get_max_millisecs(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    uint32_t        time = 0;\r
+    alt_freq_t      freq;\r
+    ALT_CLK_t       clk;\r
+    uint64_t        bigtime;\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        clk = ALT_CLK_MPU_PERIPH;\r
+    }\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG1) ||\r
+            (tmr_id == ALT_WDOG0_INIT) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        clk = ALT_CLK_OSC1;\r
+    }\r
+    else { return time; }\r
+\r
+    if ((alt_clk_freq_get(clk, &freq) == ALT_E_SUCCESS) && (freq != 0))\r
+    {                   // get clock frequency & test\r
+        time = alt_wdog_counter_get_max(tmr_id);     // get reset value\r
+        if (time != 0)\r
+        {\r
+            bigtime = ((uint64_t) time) + 1;\r
+            if (tmr_id == ALT_WDOG_CPU)\r
+            {\r
+                bigtime *= (WDOG_PS_MAX + 1);           // maximum prescaler\r
+            }\r
+            bigtime *= ALT_MILLISECS_IN_A_SEC;\r
+            bigtime /= freq;              //cycles-per-second becomes milliseconds-per-cycle\r
+            time = (bigtime > (uint64_t) UINT32_MAX) ? 0 : (uint32_t) bigtime;\r
+        }\r
+    }\r
+    return  time;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Disables the interrupt of the specified watchdog timer module. If the watchdog timer */\r
+/* is one of the watchdog timers that can be used in general-purpose mode, and if the   */\r
+/* timer is in general-purpose timer mode, disable the interrupt.                       */\r
+/****************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_wdog_int_disable(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    ALT_STATUS_CODE         ret = ALT_E_BAD_ARG;            // return value\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        if (cpu_wdog_in_wdt_mode())\r
+        {\r
+            ret = ALT_E_ERROR;\r
+        }\r
+        else\r
+        {\r
+            alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET,\r
+                  (alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) & ~WDOG_INT_EN));\r
+            ret = ALT_E_SUCCESS;\r
+        }\r
+    }\r
+            // returns an error for the other four watchdog timers\r
+            // since their interrupts cannot be disabled\r
+            // (this could change in v13.1)\r
+    return  ret;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Sets/enables the interrupt of the specified watchdog timer module. If the watchdog   */\r
+/* timer is one of the watchdog timers that can be used in general-purpose mode, and    */\r
+/* if the timer is in general-purpose timer mode, enable the interrupt.                 */\r
+/****************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_wdog_int_enable(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    ALT_STATUS_CODE         ret = ALT_E_BAD_ARG;            // return value\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        if (cpu_wdog_in_wdt_mode())\r
+        {\r
+            ret = ALT_E_ERROR;\r
+        }\r
+        else\r
+        {\r
+            alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET,\r
+                  (alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) | WDOG_INT_EN));\r
+            ret = ALT_E_SUCCESS;\r
+        }\r
+    }\r
+    return  ret;\r
+                // other watchdog timers always have interrupt enabled if they are running\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Returns the status of the interrupt of the specified watchdog timer module but does  */\r
+/* not clear it. Return TRUE if the interrupt of the specified general purpose timer    */\r
+/* module is pending and FALSE otherwise.                                               */\r
+/****************************************************************************************/\r
+\r
+bool alt_wdog_int_is_pending(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    bool        ret = false;            //return value\r
+\r
+    if ((tmr_id == ALT_WDOG_CPU) && cpu_wdog_in_gpt_mode())\r
+    {\r
+        ret = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_INTSTAT_REG_OFFSET) & WDOG_INT_STAT_BIT;\r
+    }\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))\r
+    {\r
+        ret = alt_read_word(ALT_L4WD0_WDT_STAT_ADDR) & ALT_L4WD_STAT_WDT_STAT_SET_MSK;\r
+    }\r
+    else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        ret = alt_read_word(ALT_L4WD1_WDT_STAT_ADDR) & ALT_L4WD_STAT_WDT_STAT_SET_MSK;\r
+    }\r
+    return ret;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Returns the state of the interrupt of the specified watchdog timer module. If the    */\r
+/* watchdog timer is one of the watchdog timers that can be used in general-purpose     */\r
+/* mode, and if the timer is in general-purpose timer mode, returns TRUE if the         */\r
+/* interrupt of the specified general purpose timer module is enabled and FALSE if      */\r
+/* disabled. If the timer is not in general-purpose timer mode, returns TRUE, as        */\r
+/* watchdog interrupts are always enabled.                                              */\r
+/****************************************************************************************/\r
+\r
+bool alt_wdog_int_is_enabled(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    bool        ret = false;            //return value\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        ret = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) &\r
+                    (WDOG_INT_EN | WDOG_WDT_MODE);\r
+            // if in watchdog mode OR if in general purpose timer mode\r
+            // AND the interrupt is enabled\r
+    }\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))\r
+    {\r
+        ret = alt_read_word(ALT_L4WD0_WDT_CR_ADDR) & ALT_L4WD_CR_WDT_EN_SET_MSK;\r
+        // if these timers are running, their interrupt is enabled\r
+    }\r
+    else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        ret = alt_read_word(ALT_L4WD1_WDT_CR_ADDR) & ALT_L4WD_CR_WDT_EN_SET_MSK;\r
+            // if these timers are running, their interrupt is enabled\r
+    }\r
+    return ret;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Clears the pending status of the interrupt of the specified watchdog timer module.   */\r
+/****************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_wdog_int_clear(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_INTSTAT_REG_OFFSET, WDOG_INT_STAT_BIT);\r
+             // clear int by writing to status bit\r
+    }\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))\r
+    {\r
+        (void) alt_read_word(ALT_L4WD0_WDT_EOI_ADDR);\r
+            // clear int by reading from end-of-interrupt register\r
+            // adding the void cast tells armcc not to throw a error for this usage\r
+    }\r
+    else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        (void) alt_read_word(ALT_L4WD1_WDT_EOI_ADDR);\r
+            // clear int by reading from end-of-interrupt register\r
+    }\r
+    else {return  ALT_E_ERROR; }\r
+    return ALT_E_SUCCESS;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Returns the status of the interrupt of the specified watchdog timer module and also  */\r
+/* clears it. Return TRUE if the interrupt of the specified general purpose timer       */\r
+/* module is pending and FALSE otherwise.                                               */\r
+/****************************************************************************************/\r
+\r
+bool alt_wdog_int_if_pending_clear(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    uint32_t                ret = false;    //    value to return\r
+\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        ret = (alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_INTSTAT_REG_OFFSET) & WDOG_INT_STAT_BIT);\r
+        if (ret)\r
+        {\r
+            alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_INTSTAT_REG_OFFSET, WDOG_INT_STAT_BIT);\r
+            // clear int by writing to status bit\r
+        }\r
+    }\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))\r
+    {\r
+        ret = alt_read_word(ALT_L4WD0_WDT_STAT_ADDR) & ALT_L4WD_STAT_WDT_STAT_SET_MSK;\r
+        if (ret)\r
+        {\r
+            (void) alt_read_word(ALT_L4WD0_WDT_EOI_ADDR);\r
+                // clear int by reading from end-of-interrupt register\r
+                // adding the void cast tells armcc not to throw a error for this usage\r
+\r
+       }\r
+    }\r
+    else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        ret = alt_read_word(ALT_L4WD1_WDT_STAT_ADDR) & ALT_L4WD_STAT_WDT_STAT_SET_MSK;\r
+\r
+        if (ret)\r
+        {\r
+            (void) alt_read_word(ALT_L4WD1_WDT_EOI_ADDR);\r
+                    // clear int by reading from end-of-interrupt register\r
+        }\r
+    }\r
+\r
+    return  ret;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Sets the timeout response mode of the specified watchdog timer. For ALT_WATCHDOG0,   */\r
+/* ALT_WATCHDOG1, \b ALT_WATCHDOG0_INITIAL or \b ALT_WATCHDOG1_INITIAL, the options     */\r
+/* are to generate a system reset or to generate an interrupt and then generate a       */\r
+/* system reset if the interrupt is not cleared by the next time the watchdog timer     */\r
+/* counter rolls over. For ALT_CPU_WATCHDOG, the options are to trigger an interrupt    */\r
+/* request (with the result set in the interrupt manager) or a reset request (with the  */\r
+/* result set in the reset manager) plus two more options available when it is used     */\r
+/* as a general-purpose timer.                                                          */\r
+/****************************************************************************************/\r
+\r
+ALT_STATUS_CODE alt_wdog_response_mode_set(ALT_WDOG_TIMER_t tmr_id, ALT_WDOG_RESET_TYPE_t type)\r
+{\r
+    ALT_STATUS_CODE         ret = ALT_E_BAD_ARG;        // return value\r
+    uint32_t                regdata;                    // register data\r
+\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        regdata = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET);\r
+        if (type == ALT_WDOG_TIMER_MODE_ONESHOT)\r
+        {\r
+            alt_write_word((CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET), regdata & ~WDOG_AUTO_RELOAD);\r
+            ret = ALT_E_SUCCESS;\r
+        }\r
+        else if (type == ALT_WDOG_TIMER_MODE_FREERUN)\r
+        {\r
+            alt_write_word((CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET), regdata | WDOG_AUTO_RELOAD);\r
+            ret = ALT_E_SUCCESS;\r
+        }\r
+    }\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))\r
+    {\r
+        regdata = alt_read_word(ALT_L4WD0_WDT_CR_ADDR);\r
+        if (type == ALT_WDOG_WARM_RESET)\r
+        {\r
+            alt_write_word(ALT_L4WD0_WDT_CR_ADDR, regdata & ALT_L4WD_CR_RMOD_CLR_MSK);\r
+            ret = ALT_E_SUCCESS;\r
+        }\r
+        else if (type == ALT_WDOG_INT_THEN_RESET)\r
+        {\r
+            alt_write_word(ALT_L4WD0_WDT_CR_ADDR, regdata | ALT_L4WD_CR_RMOD_SET_MSK);\r
+            ret = ALT_E_SUCCESS;\r
+        }\r
+    }\r
+    else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        regdata = alt_read_word(ALT_L4WD1_WDT_CR_ADDR);\r
+        if (type == ALT_WDOG_WARM_RESET)\r
+        {\r
+            alt_write_word(ALT_L4WD1_WDT_CR_ADDR, regdata & ALT_L4WD_CR_RMOD_CLR_MSK);\r
+            ret = ALT_E_SUCCESS;\r
+        }\r
+        else if (type == ALT_WDOG_INT_THEN_RESET)\r
+        {\r
+            alt_write_word(ALT_L4WD1_WDT_CR_ADDR, regdata | ALT_L4WD_CR_RMOD_SET_MSK);\r
+            ret = ALT_E_SUCCESS;\r
+        }\r
+    }\r
+    return  ret;            // rejects a bad tmr_id argument/type argument combination\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Returns the response mode of the specified timer.                                    */\r
+/****************************************************************************************/\r
+\r
+int32_t alt_wdog_response_mode_get(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    int32_t             ret = ALT_E_BAD_ARG;     // return value\r
+    uint32_t            regdata;                 // read value\r
+\r
+\r
+    if (tmr_id == ALT_WDOG_CPU)\r
+    {\r
+        regdata = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET);\r
+        ret = (regdata & WDOG_AUTO_RELOAD) ? ALT_WDOG_TIMER_MODE_FREERUN : ALT_WDOG_TIMER_MODE_ONESHOT;\r
+    }\r
+    else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))\r
+    {\r
+        regdata = alt_read_word(ALT_L4WD0_WDT_CR_ADDR);\r
+        ret = (regdata & ALT_L4WD_CR_RMOD_SET_MSK) ? ALT_WDOG_INT_THEN_RESET : ALT_WDOG_WARM_RESET;\r
+    }\r
+    else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        regdata = alt_read_word(ALT_L4WD1_WDT_CR_ADDR);\r
+        ret = (regdata & ALT_L4WD_CR_RMOD_SET_MSK) ? ALT_WDOG_INT_THEN_RESET : ALT_WDOG_WARM_RESET;\r
+    }\r
+\r
+    return  ret;\r
+}\r
+\r
+\r
+\r
+/****************************************************************************************/\r
+/* Returns the component code of the watchdog timer module. Only valid for              */\r
+/* ALT_WATCHDOG0, ALT_WATCHDOG1, ALT_WATCHDOG0_INITIAL or ALT_WATCHDOG1_INITIAL.        */\r
+/****************************************************************************************/\r
+\r
+uint32_t alt_wdog_compcode_get(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    uint32_t    component = 0;                  // component code of the module\r
+\r
+    if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))\r
+    {\r
+        component = alt_read_word(ALT_L4WD0_WDT_COMP_TYPE_ADDR);\r
+    }\r
+    else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        component = alt_read_word(ALT_L4WD1_WDT_COMP_TYPE_ADDR);\r
+\r
+    }\r
+    return  component;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+/* Returns the version code of the watchdog timer module. Only valid for ALT_WATCHDOG0, */\r
+/* ALT_WATCHDOG1, ALT_WATCHDOG0_INITIAL or ALT_WATCHDOG1_INITIAL.                       */\r
+/****************************************************************************************/\r
+\r
+uint32_t alt_wdog_ver_get(ALT_WDOG_TIMER_t tmr_id)\r
+{\r
+    uint32_t    ver = 0;                  // revision code of the module\r
+\r
+    if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))\r
+    {\r
+        ver = alt_read_word(ALT_L4WD0_WDT_COMP_VER_ADDR);\r
+    }\r
+    else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))\r
+    {\r
+        ver = alt_read_word(ALT_L4WD1_WDT_COMP_VER_ADDR);\r
+\r
+    }\r
+    return  ver;\r
+}\r
+\r
+\r
+/****************************************************************************************/\r
+\r
+\r