/* vim: set sw=8 ts=8 si : */ /********************************************* * Author: Guido Socher, Copyright: GPL * Clock frequency : 4,000000 MHz * Copyright: GPL **********************************************/ #include <sig-avr.h> #include <interrupt.h> #include <progmem.h> #include <io.h> #include "avr-util.h" #include "lcd.h" #include "uart.h" #include "hardwarewd.h" static volatile unsigned char wdtimer; static volatile unsigned char timedout; /* the following function will be called when the timer interrupt hits */ SIGNAL(SIG_OVERFLOW1) { wdtimer--; outp(0,TCNT1H); /* set internal interrup timer */ outp(0,TCNT1L); /* set internal interrup timer */ if (wdtimer==0){ outp(0,TCCR1B); // stop timer lcd_clrscr(); /* toggle the relai */ timedout=1; sbi(WDPORT,WD); /* on */ lcd_puts_P("WD reset..."); /* wait */ delay_ms(700); uart_reset(); wdtimer=255; cbi(WDPORT,WD); /* off */ } } /* return 1 on wd on, 0 otherwise */ unsigned char wd_status(void) { if (inp(TCCR1B)){ return(1); }else{ if (timedout==1){ return(2); }else{ return(0); } } } void wd_settime(unsigned char timeout) { wdtimer=timeout; } void wd_gettime(unsigned char *timeout) { *timeout=wdtimer; } void wd_start(void) { /* prescale = 4MHz/1024 */ outp(5,TCCR1B); timedout=0; } void wd_stop(void) { outp(0,TCCR1B); } /* init hardware watchdog. You must enable interrupt with * sei() in the main program */ void wd_init(void) { /* initialize WD/RELAI as output */ sbi(WDDDR,WD); cbi(WDPORT,WD); wdtimer=255; timedout=0; sbi(TIMSK,TOIE1); /* write high byte first */ outp(0x0,TCNT1H); /* set internal interrup timer */ outp(0x0,TCNT1L); /* set internal interrup timer */ /* write high byte first */ outp(0xFF,OCR1H); /* set internal compare register */ outp(0xFF,OCR1L); /* set internal compare register */ outp(0,TCCR1A); /* timer mode */ outp(0,TCCR1B); /* off */ }
mirror server hosted at Truenetwork, Russian Federation.