You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					160 lines
				
				5.4 KiB
			
		
		
			
		
	
	
					160 lines
				
				5.4 KiB
			|   
											14 years ago
										 | /* 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_ */
 |