2 /******************************************************************************
\r
4 * alt_watchdog.c - API for the Altera SoC FPGA watchdog timers.
\r
6 ******************************************************************************/
\r
8 /******************************************************************************
\r
10 * Copyright 2013 Altera Corporation. All Rights Reserved.
\r
12 * Redistribution and use in source and binary forms, with or without
\r
13 * modification, are permitted provided that the following conditions are met:
\r
15 * 1. Redistributions of source code must retain the above copyright notice,
\r
16 * this list of conditions and the following disclaimer.
\r
18 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
19 * this list of conditions and the following disclaimer in the documentation
\r
20 * and/or other materials provided with the distribution.
\r
22 * 3. The name of the author may not be used to endorse or promote products
\r
23 * derived from this software without specific prior written permission.
\r
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
\r
26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
27 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
\r
28 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
\r
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
\r
30 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
\r
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
\r
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
\r
33 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
\r
36 ******************************************************************************/
\r
38 /******************************************************************************
\r
40 * The Altera SoC FPGA has six watchdog timers, two are local to the MPU
\r
41 * themselves, and the other four are accessable to either MPU.
\r
43 ******************************************************************************/
\r
46 #include <stdbool.h>
\r
47 #include "socal/hps.h"
\r
48 #include "socal/socal.h"
\r
49 #include "socal/alt_rstmgr.h"
\r
50 #include "socal/alt_l4wd.h"
\r
51 #include "socal/alt_tmr.h"
\r
53 #include "alt_mpu_registers.h"
\r
54 #include "alt_watchdog.h"
\r
55 #include "alt_clock_manager.h"
\r
58 /* Useful constants and utilities */
\r
60 bool cpu_wdog_in_gpt_mode(void)
\r
62 return !(alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) & WDOG_WDT_MODE);
\r
65 static inline bool cpu_wdog_in_wdt_mode(void)
\r
67 return (alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) & WDOG_WDT_MODE);
\r
71 /* This value must be written to the Counter Restart Register of the
\r
72 * peripheral watchdog timers to restart them. */
\r
73 #define WDOG_RESET_KEY 0x00000076
\r
75 #define ALT_WDOG_RST_WIDTH 8 /* 8 or more MPU clock cycles */
\r
78 inline static void alt_wdog_wait(void* reg, uint32_t cnt)
\r
82 (void) alt_read_word(reg);
\r
87 /****************************************************************************************/
\r
88 /* Initialize the watchdog timer module before use */
\r
89 /****************************************************************************************/
\r
91 ALT_STATUS_CODE alt_wdog_init(void)
\r
93 // put watchdog timer modules into system manager reset if not already there
\r
95 // release L4 watchdog timer modules from system reset (w/ four instruction-cycle delay)
\r
96 alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, ALT_RSTMGR_PERMODRST_L4WD0_SET_MSK |
\r
97 ALT_RSTMGR_PERMODRST_L4WD1_SET_MSK);
\r
99 // release *both* ARM watchdog timer modules from system reset (if in reset)
\r
100 // does not put either one into watchdog timer mode
\r
101 alt_clrbits_word(ALT_RSTMGR_MPUMODRST_ADDR, ALT_RSTMGR_MPUMODRST_WDS_SET_MSK);
\r
102 return ALT_E_SUCCESS;
\r
106 /****************************************************************************************/
\r
107 /* Return the local ARM watchdog timer back to general-purpose timer mode */
\r
108 /****************************************************************************************/
\r
110 void alt_ARM_wdog_gpt_mode_set(void)
\r
112 while (alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) & WDOG_WDT_MODE)
\r
114 alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_DISABLE_REG_OFFSET, WDOG_DISABLE_VAL0);
\r
115 alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_DISABLE_REG_OFFSET, WDOG_DISABLE_VAL1);
\r
120 /****************************************************************************************/
\r
121 /* Set the local ARM watchdog timer to watchdog timer mode */
\r
122 /****************************************************************************************/
\r
124 void alt_ARM_wdog_wdog_mode_set(void)
\r
126 alt_setbits_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET, WDOG_WDT_MODE);
\r
130 /****************************************************************************************/
\r
131 /* Uninitialize the watchdog timer module & return to reset state */
\r
132 /****************************************************************************************/
\r
134 ALT_STATUS_CODE alt_wdog_uninit(void)
\r
136 // put L4 watchdog modules into system manager reset
\r
137 alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR,
\r
138 ALT_RSTMGR_PERMODRST_L4WD0_SET_MSK | ALT_RSTMGR_PERMODRST_L4WD1_SET_MSK);
\r
140 // using the system manager bit to reset the ARM watchdog timer
\r
141 // resets *both* ARM watchdog timers, which is often not advisable,
\r
142 // so we reset the local ARM watchdog timer manually:
\r
144 // first, stop the ARM watchdog timer & disable interrupt
\r
145 alt_clrbits_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET, WDOG_TMR_ENABLE | WDOG_INT_EN);
\r
146 // reset load and counter registers
\r
147 alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_LOAD_REG_OFFSET, 0);
\r
148 // clear any pending reset and interrupt status
\r
149 alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_RSTSTAT_REG_OFFSET, WDOG_RST_STAT_BIT);
\r
150 alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_INTSTAT_REG_OFFSET, WDOG_INT_STAT_BIT);
\r
151 // return ARM watchdog timer to (initial) general-purpose timer mode
\r
152 alt_ARM_wdog_gpt_mode_set();
\r
153 // now write zeros to the control register significant bitfields
\r
154 // and then verify that all significant bitfields return zero
\r
155 alt_clrbits_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET,
\r
156 (WDOG_PS_MASK | WDOG_WDT_MODE | WDOG_INT_EN | WDOG_AUTO_RELOAD | WDOG_TMR_ENABLE));
\r
157 if (alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET)
\r
158 & (WDOG_PS_MASK | WDOG_WDT_MODE | WDOG_INT_EN | WDOG_AUTO_RELOAD | WDOG_TMR_ENABLE))
\r
160 return ALT_E_ERROR;
\r
162 return ALT_E_SUCCESS;
\r
167 /****************************************************************************************/
\r
168 /* Stops the specified watchdog timer. */
\r
169 /****************************************************************************************/
\r
171 ALT_STATUS_CODE alt_wdog_stop(ALT_WDOG_TIMER_t tmr_id)
\r
173 ALT_STATUS_CODE ret = ALT_E_BAD_ARG; // return value
\r
174 uint32_t config; // the current configuration
\r
175 uint32_t loadreg; // current restart value
\r
178 if (tmr_id == ALT_WDOG_CPU)
\r
180 alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET,
\r
181 (alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) & ~WDOG_TMR_ENABLE));
\r
182 ret = ALT_E_SUCCESS;
\r
185 // these timers can only be reset by using a system manager reset
\r
186 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))
\r
188 config = alt_read_word(ALT_L4WD0_WDT_CR_ADDR); // read current timer mode
\r
189 loadreg = alt_read_word(ALT_L4WD0_WDT_TORR_ADDR); // read timer restart values
\r
190 alt_write_word(ALT_RSTMGR_PERMODRST_ADDR,
\r
191 alt_read_word(ALT_RSTMGR_PERMODRST_ADDR) | ALT_RSTMGR_PERMODRST_L4WD0_SET_MSK);
\r
192 // assert reset & wait
\r
193 alt_wdog_wait(ALT_RSTMGR_PERMODRST_ADDR, ALT_WDOG_RST_WIDTH);
\r
194 alt_write_word(ALT_RSTMGR_PERMODRST_ADDR,
\r
195 alt_read_word(ALT_RSTMGR_PERMODRST_ADDR) & ALT_RSTMGR_PERMODRST_L4WD0_CLR_MSK);
\r
196 // release peripheral reset signal by clearing bit
\r
197 alt_write_word(ALT_L4WD0_WDT_TORR_ADDR, loadreg); // restore timer restart value
\r
198 alt_write_word(ALT_L4WD0_WDT_CR_ADDR, config & ALT_TMR_TMR1CTLREG_TMR1_EN_CLR_MSK);
\r
199 // restore previous timer mode except timer isn't started
\r
200 ret = ALT_E_SUCCESS;
\r
202 else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))
\r
204 config = alt_read_word(ALT_L4WD1_WDT_CR_ADDR); // read current timer mode
\r
205 loadreg = alt_read_word(ALT_L4WD1_WDT_TORR_ADDR); // read timer restart values
\r
206 alt_write_word(ALT_RSTMGR_PERMODRST_ADDR,
\r
207 alt_read_word(ALT_RSTMGR_PERMODRST_ADDR) | ALT_RSTMGR_PERMODRST_L4WD1_SET_MSK);
\r
208 // assert reset & wait
\r
209 alt_write_word(ALT_RSTMGR_PERMODRST_ADDR,
\r
210 alt_read_word(ALT_RSTMGR_PERMODRST_ADDR) & ALT_RSTMGR_PERMODRST_L4WD1_CLR_MSK);
\r
211 // release peripheral reset signal by clearing bit
\r
212 alt_write_word(ALT_L4WD1_WDT_TORR_ADDR, loadreg); // restore timer restart value
\r
213 alt_write_word(ALT_L4WD1_WDT_CR_ADDR, config & ALT_TMR_TMR1CTLREG_TMR1_EN_CLR_MSK);
\r
214 // restore previous timer mode except timer isn't started
\r
215 ret = ALT_E_SUCCESS;
\r
220 /****************************************************************************************/
\r
221 /* Start the specified watchdog timer. */
\r
222 /****************************************************************************************/
\r
224 ALT_STATUS_CODE alt_wdog_start(ALT_WDOG_TIMER_t tmr_id)
\r
226 ALT_STATUS_CODE ret = ALT_E_BAD_ARG; // return value
\r
227 uint32_t regdata; // data
\r
230 if (tmr_id == ALT_WDOG_CPU)
\r
232 regdata = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET);
\r
233 alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET, regdata | WDOG_TMR_ENABLE);
\r
234 ret = ALT_E_SUCCESS;
\r
236 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))
\r
238 regdata = alt_read_word(ALT_L4WD0_WDT_CR_ADDR);
\r
239 alt_write_word(ALT_L4WD0_WDT_CR_ADDR, regdata | ALT_L4WD_CR_WDT_EN_SET_MSK);
\r
240 ret = ALT_E_SUCCESS;
\r
242 else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))
\r
244 regdata = alt_read_word(ALT_L4WD1_WDT_CR_ADDR);
\r
245 alt_write_word(ALT_L4WD1_WDT_CR_ADDR, regdata | ALT_L4WD_CR_WDT_EN_SET_MSK);
\r
246 ret = ALT_E_SUCCESS;
\r
252 /****************************************************************************************/
\r
253 /* Returns whether the specified watchdog timer is currently running or not. */
\r
254 /****************************************************************************************/
\r
256 bool alt_wdog_tmr_is_enabled(ALT_WDOG_TIMER_t tmr_id)
\r
258 bool ret = false; // return value
\r
261 if (tmr_id == ALT_WDOG_CPU)
\r
263 ret = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) & WDOG_TMR_ENABLE;
\r
265 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))
\r
267 ret = alt_read_word(ALT_L4WD0_WDT_CR_ADDR) & ALT_L4WD_CR_WDT_EN_SET_MSK;
\r
270 else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))
\r
272 ret = alt_read_word(ALT_L4WD1_WDT_CR_ADDR) & ALT_L4WD_CR_WDT_EN_SET_MSK;
\r
278 /****************************************************************************************/
\r
279 /* Reloads the counter countdown value and restarts the watchdog timer. User can reset */
\r
280 /* the timer at any time before timeout. Also known as kicking, petting, feeding, */
\r
281 /* waking, or walking the watchdog. Inherently clears the interrupt as well. */
\r
282 /****************************************************************************************/
\r
284 ALT_STATUS_CODE alt_wdog_reset(ALT_WDOG_TIMER_t tmr_id)
\r
286 uint32_t regdata; // data read
\r
289 if (tmr_id == ALT_WDOG_CPU)
\r
291 regdata = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_LOAD_REG_OFFSET);
\r
292 alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_LOAD_REG_OFFSET, regdata);
\r
293 // verify operation when we have hardware,
\r
294 // the ARM documentation is somewhat vague here
\r
296 if (cpu_wdog_in_wdt_mode())
\r
298 alt_write_word((CPU_WDTGPT_TMR_BASE + WDOG_RSTSTAT_REG_OFFSET), WDOG_RST_STAT_BIT);
\r
299 // depending on current mode, clear the reset bit or...
\r
303 alt_write_word((CPU_WDTGPT_TMR_BASE + WDOG_INTSTAT_REG_OFFSET), WDOG_INT_STAT_BIT);
\r
304 // ...clear the interrupt status bit by writing one to it
\r
307 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))
\r
309 alt_write_word(ALT_L4WD0_WDT_CRR_ADDR, WDOG_RESET_KEY);
\r
310 //restarts the counter, also clears the watchdog timer interrupt
\r
312 else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))
\r
314 alt_write_word(ALT_L4WD1_WDT_CRR_ADDR, WDOG_RESET_KEY);
\r
315 //restarts the counter, also clears the watchdog timer interrupt
\r
317 else {return ALT_E_BAD_ARG; }
\r
318 return ALT_E_SUCCESS;
\r
322 /****************************************************************************************/
\r
323 /* Sets the countdown value of the specified timer. */
\r
324 /****************************************************************************************/
\r
326 ALT_STATUS_CODE alt_wdog_counter_set(ALT_WDOG_TIMER_t tmr_id, uint32_t val)
\r
328 ALT_STATUS_CODE ret = ALT_E_BAD_ARG; // return value
\r
329 uint32_t regdata; // returned data
\r
332 if (tmr_id == ALT_WDOG_CPU)
\r
334 alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_LOAD_REG_OFFSET, val);
\r
335 ret = ALT_E_SUCCESS;
\r
336 // the ARM documentation is somewhat vague here, but it looks like it should be
\r
337 // possible to rewrite this value while counter is running, and that it works in
\r
338 // watchdog mode as well as timer mode. Verify operation when we have hardware.
\r
340 else if (val <= ALT_WDOG_TIMEOUT2G)
\r
342 if (tmr_id == ALT_WDOG0)
\r
344 // set regular timeout value
\r
345 regdata = alt_read_word(ALT_L4WD0_WDT_TORR_ADDR);
\r
346 alt_write_word(ALT_L4WD0_WDT_TORR_ADDR, (regdata & ALT_L4WD_TORR_TOP_CLR_MSK) | val);
\r
347 ret = ALT_E_SUCCESS;
\r
349 else if (tmr_id == ALT_WDOG1)
\r
351 // set regular timeout value
\r
352 regdata = alt_read_word(ALT_L4WD1_WDT_TORR_ADDR);
\r
353 alt_write_word(ALT_L4WD1_WDT_TORR_ADDR, (regdata & ALT_L4WD_TORR_TOP_CLR_MSK) | val);
\r
354 ret = ALT_E_SUCCESS;
\r
356 else if (tmr_id == ALT_WDOG0_INIT)
\r
358 // set initial timeout value
\r
359 regdata = alt_read_word(ALT_L4WD0_WDT_TORR_ADDR);
\r
360 regdata = (regdata & ALT_L4WD_TORR_TOP_INIT_CLR_MSK) |
\r
361 (val << ALT_L4WD_TORR_TOP_INIT_LSB);
\r
362 alt_write_word(ALT_L4WD0_WDT_TORR_ADDR, regdata);
\r
363 ret = ALT_E_SUCCESS;
\r
365 else if (tmr_id == ALT_WDOG1_INIT)
\r
367 // set initial timeout value
\r
368 regdata = alt_read_word(ALT_L4WD1_WDT_TORR_ADDR);
\r
369 regdata = (regdata & ALT_L4WD_TORR_TOP_INIT_CLR_MSK) |
\r
370 (val << ALT_L4WD_TORR_TOP_INIT_LSB);
\r
371 alt_write_word(ALT_L4WD1_WDT_TORR_ADDR, regdata);
\r
372 ret = ALT_E_SUCCESS;
\r
379 /****************************************************************************************/
\r
380 /* Returns the current counter value of the specified timer. */
\r
381 /****************************************************************************************/
\r
383 uint32_t alt_wdog_counter_get_current(ALT_WDOG_TIMER_t tmr_id)
\r
385 uint32_t ret = 0; // return value
\r
387 if (tmr_id == ALT_WDOG_CPU)
\r
389 ret = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CNTR_REG_OFFSET);
\r
391 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))
\r
393 ret = alt_read_word(ALT_L4WD0_WDT_CCVR_ADDR);
\r
395 else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))
\r
397 ret = alt_read_word(ALT_L4WD1_WDT_CCVR_ADDR);
\r
403 /****************************************************************************************/
\r
404 /* Returns the current counter value of the specified timer, as measured in */
\r
405 /* milliseconds. For ALT_CPU_WATCHDOG, this includes the effects of the prescaler */
\r
407 /****************************************************************************************/
\r
409 uint32_t alt_wdog_counter_get_curtime_millisecs(ALT_WDOG_TIMER_t tmr_id)
\r
411 uint32_t time = 0; // return value
\r
412 uint64_t bigtime; // temp for math
\r
413 alt_freq_t freq; // clock frequency
\r
414 ALT_CLK_t clk; // clock ID
\r
416 if (tmr_id == ALT_WDOG_CPU)
\r
418 clk = ALT_CLK_MPU_PERIPH;
\r
420 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG1) ||
\r
421 (tmr_id == ALT_WDOG0_INIT) || (tmr_id == ALT_WDOG1_INIT))
\r
423 clk = ALT_CLK_OSC1;
\r
425 else { return time; }
\r
427 if ((alt_clk_freq_get(clk, &freq) == ALT_E_SUCCESS) && (freq != 0))
\r
428 { // get clock frequency & test
\r
429 time = alt_wdog_counter_get_current(tmr_id); // get current counter value
\r
432 bigtime = (uint64_t) time;
\r
433 // the current time period is not counted, only whole periods are counted
\r
434 if (tmr_id == ALT_WDOG_CPU)
\r
436 bigtime *= (uint64_t) (alt_wdog_core_prescaler_get() + 1);
\r
438 bigtime *= ALT_MILLISECS_IN_A_SEC;
\r
439 bigtime /= freq; // cycles-per-second becomes milliseconds-per-cycle
\r
440 time = (bigtime > (uint64_t) UINT32_MAX) ? 0 : (uint32_t) bigtime;
\r
447 // see the return value range calculations below at alt_wdog_counter_get_inittime_millisecs().
\r
449 /****************************************************************************************/
\r
450 /* Returns the initial counter value of the specified timer as a 32-bit integer */
\r
451 /* value. This is the value that will be reloaded when the timer is reset or restarted. */
\r
452 /* For the timers where this value is set as an encoded powers-of-two between 15 and */
\r
453 /* 31, the value is converted into the equivalent binary value before returning it. For */
\r
454 /* ALT_CPU_WATCHDOG, the returned value does not include the effects of the prescaler */
\r
456 /****************************************************************************************/
\r
458 uint32_t alt_wdog_counter_get_init(ALT_WDOG_TIMER_t tmr_id)
\r
460 uint32_t ret = 0; // value to return
\r
462 if (tmr_id == ALT_WDOG_CPU)
\r
464 ret = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_LOAD_REG_OFFSET);
\r
466 else if (tmr_id == ALT_WDOG0)
\r
468 ret = ALT_L4WD_TORR_TOP_GET(alt_read_word(ALT_L4WD0_WDT_TORR_ADDR));
\r
469 ret = (ret > ALT_L4WD_TORR_TOP_E_TMO2G) ? 0 : ALT_TWO_TO_POW16 << ret;
\r
471 else if (tmr_id == ALT_WDOG1)
\r
473 ret = ALT_L4WD_TORR_TOP_GET(alt_read_word(ALT_L4WD1_WDT_TORR_ADDR));
\r
474 ret = (ret > ALT_L4WD_TORR_TOP_E_TMO2G) ? 0 : ALT_TWO_TO_POW16 << ret;
\r
476 else if (tmr_id == ALT_WDOG0_INIT)
\r
478 ret = ALT_L4WD_TORR_TOP_INIT_GET(alt_read_word(ALT_L4WD0_WDT_TORR_ADDR));
\r
479 ret = (ret > ALT_L4WD_TORR_TOP_INIT_E_TMO2G) ? 0 : ALT_TWO_TO_POW16 << ret;
\r
481 else if (tmr_id == ALT_WDOG1_INIT)
\r
483 ret = ALT_L4WD_TORR_TOP_INIT_GET(alt_read_word(ALT_L4WD1_WDT_TORR_ADDR));
\r
484 ret = (ret > ALT_L4WD_TORR_TOP_INIT_E_TMO2G) ? 0 : ALT_TWO_TO_POW16 << ret;
\r
490 /****************************************************************************************/
\r
491 /* Returns the initial value of the specified timer in nanoseconds. This is the */
\r
492 /* value that will be reloaded when the timer is reset or restarted. For */
\r
493 /* ALT_CPU_WATCHDOG, this includes the effects of the prescaler setting. This call */
\r
494 /* returns a more precise result than alt_wdog_counter_get_inittime_millisecs(), but */
\r
495 /* as an unsigned 64-bit integer. */
\r
496 /****************************************************************************************/
\r
498 uint64_t alt_wdog_counter_get_inittime_nanosecs(ALT_WDOG_TIMER_t tmr_id)
\r
504 if (tmr_id == ALT_WDOG_CPU)
\r
506 clk = ALT_CLK_MPU_PERIPH;
\r
508 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG1) ||
\r
509 (tmr_id == ALT_WDOG0_INIT) || (tmr_id == ALT_WDOG1_INIT))
\r
511 clk = ALT_CLK_OSC1;
\r
513 else { return time; } // zero always indicates an error for an init time
\r
515 if ((alt_clk_freq_get(clk, &freq) == ALT_E_SUCCESS) && (freq != 0))
\r
516 { // get clock frequency & test
\r
517 time = (uint64_t) alt_wdog_counter_get_init(tmr_id); // get reset value
\r
521 if (tmr_id == ALT_WDOG_CPU)
\r
523 time *= (uint64_t) (alt_wdog_core_prescaler_get() + 1);
\r
525 time *= ALT_NANOSECS_IN_A_SEC;
\r
526 time /= freq; // cycles-per-second becomes nanoseconds per cycle
\r
535 * minimum clock divider for ALT_CPU_WATCHDOG is 1
\r
536 * maximum clock divider for ALT_CPU_WATCHDOG is ((0xFFFF FFFF + 1) x (0x0000 0100) = 0x0000 0100 0000 0000)
\r
537 * multiply that by the number of nanoseconds in a second (1,000,000,000)
\r
538 * = 1,099,511,627,776,000,000,000 (0x9ACA 0000 0000 0000)
\r
539 * so the countdown time with the slowest mpu_peripheral clock (2.5 MHz) =
\r
540 * 400 nS to 439,804.6511104 seconds (0x0001 9000 0000 0000 nS)
\r
541 * and with the fastest mpu_peripheral clock (200 MHz) =
\r
542 * 5 nS to 5,497,558,138,880 nanoseconds ( 0x0000 0500 0000 0000 nS)
\r
544 * minimum clock divider for peripheral watchdogs is 2**16 = (65,536 = 0x00010000)
\r
545 * maximum clock divider for peripheral watchdogs is 2**31 = (2,147,483,648 = 0x8000 0000)
\r
546 * multiply that by the number of nanoseconds in a second (1,000,000,000) =
\r
547 * 4,096,000,000,000 (0x0000 03B9 ACA0 0000) to 2,147,483,648,000,000,000 (0x1DCD 6500 0000 0000)
\r
548 * so the countdown time with the slowest l4_sp_clk (625 kHz) =
\r
549 * 6,553,600 nS (0x0064 0000) to 3,435,973,836,800 nS (0x0000 0320 0000 0000 nS)
\r
550 * and with the fastest l4_sp_clk (100 MHz) =
\r
551 * 40,960 ns (0xA000) to 21,474,836,480 nS (0x0000 0005 0000 0000 nS)
\r
554 /****************************************************************************************/
\r
555 /* Returns the initial value of the specified timer in milliseconds. This is the */
\r
556 /* value that will be reloaded when the timer is reset or restarted. For */
\r
557 /* ALT_CPU_WATCHDOG, this includes the effects of the prescaler setting. This call */
\r
558 /* returns a 32-bit unsigned integer, though is less precise than */
\r
559 /* alt_wdog_counter_get_inittime_nanosecs(). */
\r
560 /****************************************************************************************/
\r
562 uint32_t alt_wdog_counter_get_inittime_millisecs(ALT_WDOG_TIMER_t tmr_id)
\r
569 if (tmr_id == ALT_WDOG_CPU)
\r
571 clk = ALT_CLK_MPU_PERIPH;
\r
573 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG1) ||
\r
574 (tmr_id == ALT_WDOG0_INIT) || (tmr_id == ALT_WDOG1_INIT))
\r
576 clk = ALT_CLK_OSC1;
\r
578 else { return time; } // must be an invalid tmr_id
\r
580 if ((alt_clk_freq_get(clk, &freq) == ALT_E_SUCCESS) && (freq != 0))
\r
581 { // get clock frequency & test
\r
582 time = alt_wdog_counter_get_init(tmr_id); // get reset value
\r
585 bigtime = ((uint64_t) time) + 1;
\r
586 if (tmr_id == ALT_WDOG_CPU) // the only watchdog with a prescaler
\r
588 bigtime *= (uint64_t) (alt_wdog_core_prescaler_get() + 1);
\r
590 bigtime *= ALT_MILLISECS_IN_A_SEC; // scale value
\r
591 bigtime /= freq; // cycles-per-second becomes milliseconds per cycle
\r
592 time = (bigtime > (uint64_t) UINT32_MAX) ? 0 : (uint32_t) bigtime;
\r
600 * minimum clock divider for ALT_CPU_WATCHDOG is 1
\r
601 * maximum clock divider for ALT_CPU_WATCHDOG is ((0xFFFF FFFF + 1) x (0x0000 0100) = 0x0000 0100 0000 0000)
\r
602 * multiply that by the number of milliseconds in a second (1,000)
\r
603 * = 1,000 (0x3e8) to 1,099,511,627,776,000 (0x0003 E800 0000 0000)
\r
604 * so the countdown time with the slowest mpu_peripheral clock (2.5 MHz) =
\r
605 * 0 mS to 439,804.6511104 seconds (0x1A36 E2EB mS)
\r
606 * and with the fastest mpu_peripheral clock (200 MHz) =
\r
607 * 0 mS to 5,497.55813888 seconds ( 0x0053 E2D6 mS)
\r
609 * minimum clock divider for peripheral watchdogs is 2**16 = (65,536 = 0x00010000)
\r
610 * maximum clock divider for peripheral watchdogs is 2**31 = (2,147,483,648 = 0x8000 0000)
\r
611 * multiply that by the number of milliseconds in a second (1,000) =
\r
612 * 65,536,000 (0x3E8 0000) to 2,147,483,648,000 (0x01F4 0000 0000)
\r
613 * so the countdown time with the slowest l4_sp_clk (625 kHz) =
\r
614 * 104 mS (0x0068) to 3,435,973 mS (0x0034 6DC5 mS)
\r
615 * and with the fastest l4_sp_clk (100 MHz) = 0 mS to 21,474 mS (0x0000 53E2 mS)
\r
618 /****************************************************************************************/
\r
619 /* Sets the value of the CPU watchdog timer ALT_CPU_WATCHDOG prescaler. */
\r
620 /****************************************************************************************/
\r
622 ALT_STATUS_CODE alt_wdog_core_prescaler_set(uint32_t val)
\r
624 ALT_STATUS_CODE ret = ALT_E_BAD_ARG; // return value
\r
627 if (val <= WDOG_PS_MAX)
\r
629 if (alt_wdog_tmr_is_enabled(ALT_WDOG_CPU))
\r
635 regdata = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET);
\r
636 alt_write_word((CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET),
\r
637 (regdata & ~WDOG_PS_MASK) | (val << WDOG_PS_SHIFT));
\r
638 ret = ALT_E_SUCCESS;
\r
645 /****************************************************************************************/
\r
646 /* Returns the value of the prescaler of the CPU core watchdog timer. */
\r
647 /****************************************************************************************/
\r
649 uint32_t alt_wdog_core_prescaler_get(void)
\r
651 return (alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) &
\r
652 WDOG_PS_MASK) >> WDOG_PS_SHIFT;
\r
656 /****************************************************************************************/
\r
657 /* Returns the maximum possible counter value of the specified timer as a 32-bit value. */
\r
658 /* For the timers where this value is encoded (as powers-of-two between 15 and 31), the */
\r
659 /* encoded value is converted into the equivalent binary value before returning it. */
\r
660 /* This does not include the effects of the prescaler available for ALT_CPU_WATCHDOG. */
\r
661 /****************************************************************************************/
\r
663 uint32_t alt_wdog_counter_get_max(ALT_WDOG_TIMER_t tmr_id)
\r
665 uint32_t ret = 0; // return value
\r
667 if (tmr_id == ALT_WDOG_CPU)
\r
669 ret = WDOG_TMR_MAX;
\r
671 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG1)
\r
672 || (tmr_id == ALT_WDOG0_INIT) || (tmr_id == ALT_WDOG1_INIT))
\r
674 ret = ((uint32_t) ALT_TWO_TO_POW16) << ALT_WDOG_TIMEOUT2G;
\r
681 /****************************************************************************************/
\r
682 /* Returns the maximum possible delay time of the specified timer specified in */
\r
683 /* nanoseconds. For ALT_CPU_WATCHDOG, this includes the prescaler setting. This call */
\r
684 /* returns a more precise reading of the counter than */
\r
685 /* alt_wdog_counter_get_max_millisecs(), though in an unsigned 64-bit integer. */
\r
686 /****************************************************************************************/
\r
688 uint64_t alt_wdog_counter_get_max_nanosecs(ALT_WDOG_TIMER_t tmr_id)
\r
694 if (tmr_id == ALT_WDOG_CPU)
\r
696 clk = ALT_CLK_MPU_PERIPH;
\r
698 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG1) ||
\r
699 (tmr_id == ALT_WDOG0_INIT) || (tmr_id == ALT_WDOG1_INIT))
\r
701 clk = ALT_CLK_OSC1;
\r
703 else { return time; }
\r
705 if ((alt_clk_freq_get(clk, &freq) == ALT_E_SUCCESS) && (freq != 0))
\r
706 { // get clock frequency & test
\r
707 time = (uint64_t) alt_wdog_counter_get_max(tmr_id); // get maximum reset value
\r
711 if (tmr_id == ALT_WDOG_CPU)
\r
713 time *= (WDOG_PS_MAX + 1); // maximum prescaler
\r
715 time *= ALT_NANOSECS_IN_A_SEC;
\r
716 time /= freq; //cycles-per-second becomes nanoseconds-per-cycle
\r
724 /****************************************************************************************/
\r
725 /* Returns the maximum possible delay time of the specified timer specified in */
\r
726 /* milliseconds. For ALT_CPU_WATCHDOG, this includes the prescaler setting. This call */
\r
727 /* returns a 32-bit unsigned integer, though is less precise than */
\r
728 /* alt_wdog_counter_get_max_nanosecs(). */
\r
729 /****************************************************************************************/
\r
731 uint32_t alt_wdog_counter_get_max_millisecs(ALT_WDOG_TIMER_t tmr_id)
\r
738 if (tmr_id == ALT_WDOG_CPU)
\r
740 clk = ALT_CLK_MPU_PERIPH;
\r
742 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG1) ||
\r
743 (tmr_id == ALT_WDOG0_INIT) || (tmr_id == ALT_WDOG1_INIT))
\r
745 clk = ALT_CLK_OSC1;
\r
747 else { return time; }
\r
749 if ((alt_clk_freq_get(clk, &freq) == ALT_E_SUCCESS) && (freq != 0))
\r
750 { // get clock frequency & test
\r
751 time = alt_wdog_counter_get_max(tmr_id); // get reset value
\r
754 bigtime = ((uint64_t) time) + 1;
\r
755 if (tmr_id == ALT_WDOG_CPU)
\r
757 bigtime *= (WDOG_PS_MAX + 1); // maximum prescaler
\r
759 bigtime *= ALT_MILLISECS_IN_A_SEC;
\r
760 bigtime /= freq; //cycles-per-second becomes milliseconds-per-cycle
\r
761 time = (bigtime > (uint64_t) UINT32_MAX) ? 0 : (uint32_t) bigtime;
\r
768 /****************************************************************************************/
\r
769 /* Disables the interrupt of the specified watchdog timer module. If the watchdog timer */
\r
770 /* is one of the watchdog timers that can be used in general-purpose mode, and if the */
\r
771 /* timer is in general-purpose timer mode, disable the interrupt. */
\r
772 /****************************************************************************************/
\r
774 ALT_STATUS_CODE alt_wdog_int_disable(ALT_WDOG_TIMER_t tmr_id)
\r
776 ALT_STATUS_CODE ret = ALT_E_BAD_ARG; // return value
\r
778 if (tmr_id == ALT_WDOG_CPU)
\r
780 if (cpu_wdog_in_wdt_mode())
\r
786 alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET,
\r
787 (alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) & ~WDOG_INT_EN));
\r
788 ret = ALT_E_SUCCESS;
\r
791 // returns an error for the other four watchdog timers
\r
792 // since their interrupts cannot be disabled
\r
793 // (this could change in v13.1)
\r
798 /****************************************************************************************/
\r
799 /* Sets/enables the interrupt of the specified watchdog timer module. If the watchdog */
\r
800 /* timer is one of the watchdog timers that can be used in general-purpose mode, and */
\r
801 /* if the timer is in general-purpose timer mode, enable the interrupt. */
\r
802 /****************************************************************************************/
\r
804 ALT_STATUS_CODE alt_wdog_int_enable(ALT_WDOG_TIMER_t tmr_id)
\r
806 ALT_STATUS_CODE ret = ALT_E_BAD_ARG; // return value
\r
808 if (tmr_id == ALT_WDOG_CPU)
\r
810 if (cpu_wdog_in_wdt_mode())
\r
816 alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET,
\r
817 (alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) | WDOG_INT_EN));
\r
818 ret = ALT_E_SUCCESS;
\r
822 // other watchdog timers always have interrupt enabled if they are running
\r
826 /****************************************************************************************/
\r
827 /* Returns the status of the interrupt of the specified watchdog timer module but does */
\r
828 /* not clear it. Return TRUE if the interrupt of the specified general purpose timer */
\r
829 /* module is pending and FALSE otherwise. */
\r
830 /****************************************************************************************/
\r
832 bool alt_wdog_int_is_pending(ALT_WDOG_TIMER_t tmr_id)
\r
834 bool ret = false; //return value
\r
836 if ((tmr_id == ALT_WDOG_CPU) && cpu_wdog_in_gpt_mode())
\r
838 ret = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_INTSTAT_REG_OFFSET) & WDOG_INT_STAT_BIT;
\r
840 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))
\r
842 ret = alt_read_word(ALT_L4WD0_WDT_STAT_ADDR) & ALT_L4WD_STAT_WDT_STAT_SET_MSK;
\r
844 else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))
\r
846 ret = alt_read_word(ALT_L4WD1_WDT_STAT_ADDR) & ALT_L4WD_STAT_WDT_STAT_SET_MSK;
\r
852 /****************************************************************************************/
\r
853 /* Returns the state of the interrupt of the specified watchdog timer module. If the */
\r
854 /* watchdog timer is one of the watchdog timers that can be used in general-purpose */
\r
855 /* mode, and if the timer is in general-purpose timer mode, returns TRUE if the */
\r
856 /* interrupt of the specified general purpose timer module is enabled and FALSE if */
\r
857 /* disabled. If the timer is not in general-purpose timer mode, returns TRUE, as */
\r
858 /* watchdog interrupts are always enabled. */
\r
859 /****************************************************************************************/
\r
861 bool alt_wdog_int_is_enabled(ALT_WDOG_TIMER_t tmr_id)
\r
863 bool ret = false; //return value
\r
865 if (tmr_id == ALT_WDOG_CPU)
\r
867 ret = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET) &
\r
868 (WDOG_INT_EN | WDOG_WDT_MODE);
\r
869 // if in watchdog mode OR if in general purpose timer mode
\r
870 // AND the interrupt is enabled
\r
872 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))
\r
874 ret = alt_read_word(ALT_L4WD0_WDT_CR_ADDR) & ALT_L4WD_CR_WDT_EN_SET_MSK;
\r
875 // if these timers are running, their interrupt is enabled
\r
877 else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))
\r
879 ret = alt_read_word(ALT_L4WD1_WDT_CR_ADDR) & ALT_L4WD_CR_WDT_EN_SET_MSK;
\r
880 // if these timers are running, their interrupt is enabled
\r
886 /****************************************************************************************/
\r
887 /* Clears the pending status of the interrupt of the specified watchdog timer module. */
\r
888 /****************************************************************************************/
\r
890 ALT_STATUS_CODE alt_wdog_int_clear(ALT_WDOG_TIMER_t tmr_id)
\r
894 if (tmr_id == ALT_WDOG_CPU)
\r
896 alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_INTSTAT_REG_OFFSET, WDOG_INT_STAT_BIT);
\r
897 // clear int by writing to status bit
\r
899 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))
\r
901 (void) alt_read_word(ALT_L4WD0_WDT_EOI_ADDR);
\r
902 // clear int by reading from end-of-interrupt register
\r
903 // adding the void cast tells armcc not to throw a error for this usage
\r
905 else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))
\r
907 (void) alt_read_word(ALT_L4WD1_WDT_EOI_ADDR);
\r
908 // clear int by reading from end-of-interrupt register
\r
910 else {return ALT_E_ERROR; }
\r
911 return ALT_E_SUCCESS;
\r
915 /****************************************************************************************/
\r
916 /* Returns the status of the interrupt of the specified watchdog timer module and also */
\r
917 /* clears it. Return TRUE if the interrupt of the specified general purpose timer */
\r
918 /* module is pending and FALSE otherwise. */
\r
919 /****************************************************************************************/
\r
921 bool alt_wdog_int_if_pending_clear(ALT_WDOG_TIMER_t tmr_id)
\r
923 uint32_t ret = false; // value to return
\r
926 if (tmr_id == ALT_WDOG_CPU)
\r
928 ret = (alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_INTSTAT_REG_OFFSET) & WDOG_INT_STAT_BIT);
\r
931 alt_write_word(CPU_WDTGPT_TMR_BASE + WDOG_INTSTAT_REG_OFFSET, WDOG_INT_STAT_BIT);
\r
932 // clear int by writing to status bit
\r
935 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))
\r
937 ret = alt_read_word(ALT_L4WD0_WDT_STAT_ADDR) & ALT_L4WD_STAT_WDT_STAT_SET_MSK;
\r
940 (void) alt_read_word(ALT_L4WD0_WDT_EOI_ADDR);
\r
941 // clear int by reading from end-of-interrupt register
\r
942 // adding the void cast tells armcc not to throw a error for this usage
\r
946 else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))
\r
948 ret = alt_read_word(ALT_L4WD1_WDT_STAT_ADDR) & ALT_L4WD_STAT_WDT_STAT_SET_MSK;
\r
952 (void) alt_read_word(ALT_L4WD1_WDT_EOI_ADDR);
\r
953 // clear int by reading from end-of-interrupt register
\r
961 /****************************************************************************************/
\r
962 /* Sets the timeout response mode of the specified watchdog timer. For ALT_WATCHDOG0, */
\r
963 /* ALT_WATCHDOG1, \b ALT_WATCHDOG0_INITIAL or \b ALT_WATCHDOG1_INITIAL, the options */
\r
964 /* are to generate a system reset or to generate an interrupt and then generate a */
\r
965 /* system reset if the interrupt is not cleared by the next time the watchdog timer */
\r
966 /* counter rolls over. For ALT_CPU_WATCHDOG, the options are to trigger an interrupt */
\r
967 /* request (with the result set in the interrupt manager) or a reset request (with the */
\r
968 /* result set in the reset manager) plus two more options available when it is used */
\r
969 /* as a general-purpose timer. */
\r
970 /****************************************************************************************/
\r
972 ALT_STATUS_CODE alt_wdog_response_mode_set(ALT_WDOG_TIMER_t tmr_id, ALT_WDOG_RESET_TYPE_t type)
\r
974 ALT_STATUS_CODE ret = ALT_E_BAD_ARG; // return value
\r
975 uint32_t regdata; // register data
\r
978 if (tmr_id == ALT_WDOG_CPU)
\r
980 regdata = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET);
\r
981 if (type == ALT_WDOG_TIMER_MODE_ONESHOT)
\r
983 alt_write_word((CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET), regdata & ~WDOG_AUTO_RELOAD);
\r
984 ret = ALT_E_SUCCESS;
\r
986 else if (type == ALT_WDOG_TIMER_MODE_FREERUN)
\r
988 alt_write_word((CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET), regdata | WDOG_AUTO_RELOAD);
\r
989 ret = ALT_E_SUCCESS;
\r
992 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))
\r
994 regdata = alt_read_word(ALT_L4WD0_WDT_CR_ADDR);
\r
995 if (type == ALT_WDOG_WARM_RESET)
\r
997 alt_write_word(ALT_L4WD0_WDT_CR_ADDR, regdata & ALT_L4WD_CR_RMOD_CLR_MSK);
\r
998 ret = ALT_E_SUCCESS;
\r
1000 else if (type == ALT_WDOG_INT_THEN_RESET)
\r
1002 alt_write_word(ALT_L4WD0_WDT_CR_ADDR, regdata | ALT_L4WD_CR_RMOD_SET_MSK);
\r
1003 ret = ALT_E_SUCCESS;
\r
1006 else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))
\r
1008 regdata = alt_read_word(ALT_L4WD1_WDT_CR_ADDR);
\r
1009 if (type == ALT_WDOG_WARM_RESET)
\r
1011 alt_write_word(ALT_L4WD1_WDT_CR_ADDR, regdata & ALT_L4WD_CR_RMOD_CLR_MSK);
\r
1012 ret = ALT_E_SUCCESS;
\r
1014 else if (type == ALT_WDOG_INT_THEN_RESET)
\r
1016 alt_write_word(ALT_L4WD1_WDT_CR_ADDR, regdata | ALT_L4WD_CR_RMOD_SET_MSK);
\r
1017 ret = ALT_E_SUCCESS;
\r
1020 return ret; // rejects a bad tmr_id argument/type argument combination
\r
1024 /****************************************************************************************/
\r
1025 /* Returns the response mode of the specified timer. */
\r
1026 /****************************************************************************************/
\r
1028 int32_t alt_wdog_response_mode_get(ALT_WDOG_TIMER_t tmr_id)
\r
1030 int32_t ret = ALT_E_BAD_ARG; // return value
\r
1031 uint32_t regdata; // read value
\r
1034 if (tmr_id == ALT_WDOG_CPU)
\r
1036 regdata = alt_read_word(CPU_WDTGPT_TMR_BASE + WDOG_CTRL_REG_OFFSET);
\r
1037 ret = (regdata & WDOG_AUTO_RELOAD) ? ALT_WDOG_TIMER_MODE_FREERUN : ALT_WDOG_TIMER_MODE_ONESHOT;
\r
1039 else if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))
\r
1041 regdata = alt_read_word(ALT_L4WD0_WDT_CR_ADDR);
\r
1042 ret = (regdata & ALT_L4WD_CR_RMOD_SET_MSK) ? ALT_WDOG_INT_THEN_RESET : ALT_WDOG_WARM_RESET;
\r
1044 else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))
\r
1046 regdata = alt_read_word(ALT_L4WD1_WDT_CR_ADDR);
\r
1047 ret = (regdata & ALT_L4WD_CR_RMOD_SET_MSK) ? ALT_WDOG_INT_THEN_RESET : ALT_WDOG_WARM_RESET;
\r
1055 /****************************************************************************************/
\r
1056 /* Returns the component code of the watchdog timer module. Only valid for */
\r
1057 /* ALT_WATCHDOG0, ALT_WATCHDOG1, ALT_WATCHDOG0_INITIAL or ALT_WATCHDOG1_INITIAL. */
\r
1058 /****************************************************************************************/
\r
1060 uint32_t alt_wdog_compcode_get(ALT_WDOG_TIMER_t tmr_id)
\r
1062 uint32_t component = 0; // component code of the module
\r
1064 if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))
\r
1066 component = alt_read_word(ALT_L4WD0_WDT_COMP_TYPE_ADDR);
\r
1068 else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))
\r
1070 component = alt_read_word(ALT_L4WD1_WDT_COMP_TYPE_ADDR);
\r
1077 /****************************************************************************************/
\r
1078 /* Returns the version code of the watchdog timer module. Only valid for ALT_WATCHDOG0, */
\r
1079 /* ALT_WATCHDOG1, ALT_WATCHDOG0_INITIAL or ALT_WATCHDOG1_INITIAL. */
\r
1080 /****************************************************************************************/
\r
1082 uint32_t alt_wdog_ver_get(ALT_WDOG_TIMER_t tmr_id)
\r
1084 uint32_t ver = 0; // revision code of the module
\r
1086 if ((tmr_id == ALT_WDOG0) || (tmr_id == ALT_WDOG0_INIT))
\r
1088 ver = alt_read_word(ALT_L4WD0_WDT_COMP_VER_ADDR);
\r
1090 else if ((tmr_id == ALT_WDOG1) || (tmr_id == ALT_WDOG1_INIT))
\r
1092 ver = alt_read_word(ALT_L4WD1_WDT_COMP_VER_ADDR);
\r
1099 /****************************************************************************************/
\r