123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- /* This is from http://www.mtcnet.net/~henryvm/wdt/ */
- #ifndef _AVR_WD_H_
- #define _AVR_WD_H_
-
- #include <avr/io.h>
-
- /*
- Copyright (c) 2009, Curt Van Maanen
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-
- include usage-
- #include "wd.h" //if in same directory as project
- #include <avr/wd.h> //if wd.h is in avr directory
-
- set watchdog modes and prescale
-
- usage-
- WD_SET(mode,[timeout]); //prescale always set
-
- modes-
- WD_OFF disabled
- WD_RST normal reset mode
- WD_IRQ interrupt only mode (if supported)
- WD_RST_IRQ interrupt+reset mode (if supported)
-
- timeout-
- WDTO_15MS default if no timeout provided
- WDTO_30MS
- WDTO_60MS
- WDTO_120MS
- WDTO_250MS
- WDTO_500MS
- WDTO_1S
- WDTO_2S
- WDTO_4S (if supported)
- WDTO_8S (if supported)
-
- examples-
- WD_SET(WD_RST,WDTO_1S); //reset mode, 1s timeout
- WD_SET(WD_OFF); //watchdog disabled (if not fused on)
- WD_SET(WD_RST); //reset mode, 15ms (default timeout)
- WD_SET(WD_IRQ,WDTO_120MS); //interrupt only mode, 120ms timeout
- WD_SET(WD_RST_IRQ,WDTO_2S); //interrupt+reset mode, 2S timeout
-
-
- for enhanced watchdogs, if the watchdog is not being used WDRF should be
- cleared on every power up or reset, along with disabling the watchdog-
- WD_DISABLE(); //clear WDRF, then turn off watchdog
-
- */
-
- //reset registers to the same name (MCUCSR)
- #if !defined(MCUCSR)
- #define MCUCSR MCUSR
- #endif
-
- //watchdog registers to the same name (WDTCSR)
- #if !defined(WDTCSR)
- #define WDTCSR WDTCR
- #endif
-
- //if enhanced watchdog, define irq values, create disable macro
- #if defined(WDIF)
- #define WD_IRQ 0xC0
- #define WD_RST_IRQ 0xC8
- #define WD_DISABLE() do{ \
- MCUCSR &= ~(1<<WDRF); \
- WD_SET(WD_OFF); \
- }while(0)
- #endif
-
- //all watchdogs
- #define WD_RST 8
- #define WD_OFF 0
-
- //prescale values
- #define WDTO_15MS 0
- #define WDTO_30MS 1
- #define WDTO_60MS 2
- #define WDTO_120MS 3
- #define WDTO_250MS 4
- #define WDTO_500MS 5
- #define WDTO_1S 6
- #define WDTO_2S 7
-
- //prescale values for avrs with WDP3
- #if defined(WDP3)
- #define WDTO_4S 0x20
- #define WDTO_8S 0x21
- #endif
-
- //watchdog reset
- #define WDR() __asm__ __volatile__("wdr")
-
- //avr reset using watchdog
- #define WD_AVR_RESET() do{ \
- __asm__ __volatile__("cli"); \
- WD_SET_UNSAFE(WD_RST); \
- while(1); \
- }while(0)
-
- /*set the watchdog-
- 1. save SREG
- 2. turn off irq's
- 3. reset watchdog timer
- 4. enable watchdog change
- 5. write watchdog value
- 6. restore SREG (restoring irq status)
- */
- #define WD_SET(val,...) \
- __asm__ __volatile__( \
- "in __tmp_reg__,__SREG__" "\n\t" \
- "cli" "\n\t" \
- "wdr" "\n\t" \
- "sts %[wdreg],%[wden]" "\n\t" \
- "sts %[wdreg],%[wdval]" "\n\t" \
- "out __SREG__,__tmp_reg__" "\n\t" \
- : \
- : [wdreg] "M" (&WDTCSR), \
- [wden] "r" ((uint8_t)(0x18)), \
- [wdval] "r" ((uint8_t)(val|(__VA_ARGS__+0))) \
- : "r0" \
- )
-
- /*set the watchdog when I bit in SREG known to be clear-
- 1. reset watchdog timer
- 2. enable watchdog change
- 5. write watchdog value
- */
- #define WD_SET_UNSAFE(val,...) \
- __asm__ __volatile__( \
- "wdr" "\n\t" \
- "sts %[wdreg],%[wden]" "\n\t" \
- "sts %[wdreg],%[wdval]" "\n\t" \
- : \
- : [wdreg] "M" (&WDTCSR), \
- [wden] "r" ((uint8_t)(0x18)), \
- [wdval] "r" ((uint8_t)(val|(__VA_ARGS__+0))) \
- )
-
-
- //for compatibility with avr/wdt.h
- #define wdt_enable(val) WD_SET(WD_RST,val)
- #define wdt_disable() WD_SET(WD_OFF)
-
-
- #endif /* _AVR_WD_H_ */
|