Programming the WatchDog Timer The onboard watchdog timer uses a 8-bit counter, so it has 256 resolution and the time range is from 32 seconds to 254 minutes with a resolution of 1 minute. When the timer is setting and time-out occur, it will trigger the hardware reset signal, a system reset will happen. The onboard watchdog timer function is carried by the I/O chip Winbond W83977EF. If you want to use this function in your program, you have to know how to read/write the W83977EF configuration register. The onboard W83977EF I/O chip decode address is 3F0h, it is index port and data port is 3F1h. The read/write register methods are write register number to index port ,then read/write data from/to data port. About how to program the W83977EF register and the procedure of using watchdog function are describe as follow. Program W83977EF register : 1. Unlock W83977EF I/O chip and enter configuration mode. 2. Select Logical Device. 3. Select register number. 4. Read/Write data from/to register. 5. Lock W83977EF I/O chip and exit from configuration mode. To Unlock/Lock the W83977EF and Enter/exit configuration mode is to write a specific value to I/O Port 3f0h. Unlock W83977EF : write value 87h to I/O port 3f0h twice. Lock W83977EF : write value aah to I/O port 3f0h. program watchdog procedure : 1. Unlock W83977EF I/O chip and enter configuration mode. write twice unlock value(87h) to port 3f0h ex: outportb(0x3f0, 0x87); outportb(0x3f0, 0x87); 2. Set register 30h of logical device 8 to 1 to activate the timer. Logical Device 8: Register number 30h (CR30) 00h : timer inactive 01h : timer active write value 7 to port 3f0 /* register 7(logical device switch register)*/ write value 8 to port 3f1 /* write value 8 to enter logical device 8 */ write value 30 to port 3f0 write value 01 to port 3f1 ex: outportb(0x3f0, 0x07); outportb(0x3f1, 0x08); outportb(0x3f0, 0x30); outportb(0x3f1, 0x01); 3. write time-out value(01h ~ FFh) to timer register (F2h). Logical Device 8: Register number F2h (CRF2) 00h : Time-out Disable 01h : Time-out occurs after 32 seconds 02h : Time-out occurs after 1 minute 32 seconds 03h : Time-out occurs after 2 minute 32 seconds 04h : Time-out occurs after 3 minute 32 seconds 05h : Time-out occurs after 4 minutes 32 seconds . . FFh : Time-out occurs after 127 minutes 16 seconds write register number F2h to port 3f0h write time-out value to port 3f1h ex: outportb(0x3f0, 0xF2); /* register F2 (Watchdog Timer) */ outportb(0x3f1, 0x01); /* time-out value 01 == 32 seconds */ 4. Lock W83977EF I/O chip, exit configuration mode write lock value (AAh) to port 3f0h ex: outportb(0x3f0, 0xAA); Followings show two examples of programming the watchdog timer with 16 seconds time interval in both Micro-assembly and C language. Demo Porgram 1 (assember language): ;;============================================================== ;; Title : WatchDog Timer Demo Program (32 seconds) ;; Date : 11/02/2000 ;;============================================================== .model small .code W83977_IO_PORT DW 3F0H UNLOCK_ID DB 087h LOCK_ID DB 0AAH ;;--------------------------------------------------- ;; Main Program start ;;--------------------------------------------------- WatchDog PROC ;; Set Logic Device 8 Active mov bl, 8 ;; Logic Device 8 mov al, 30h ;; Register 30h mov ah, 01h ;; Active --> 01h, InActive --> 00h call W977_Register_Set ;; Set watchdog time-out value = 1 (16 seconds) mov bl, 8 ;; Logic Device 8 mov al, 0F2h ;; Register F2h mov ah, 01h ;; 01h ~ FFh == 0:32 ~ 254:32 call W977_Register_Set mov ah,4ch ;; Retuen to DOS int 21h ret WatchDog ENDP ;;--------------------------------------------------- ;;--------------------------------------------------- ;; unlock W83977 register program mode ;;--------------------------------------------------- Unlock_977 proc cli push ax push dx mov al, UNLOCK_ID mov dx, cs:W83977_IO_PORT out dx, al ;; write Unlock_ID to w83977 twice out dx, al jmp $+2 jmp $+2 pop dx pop ax ret Unlock_977 endp ;;--------------------------------------------------- ;;--------------------------------------------------- ;; lock w83977 register program mode ;;--------------------------------------------------- Lock_977 proc push ax push dx mov dx, cs:W83977_IO_PORT mov al, LOCK_ID out dx, al pop dx pop ax ret Lock_977 endp ;;--------------------------------------------------- ;;--------------------------------------------------- ;; Select W83977 I/O chip Logic Device ;; bl : Device Number ;;--------------------------------------------------- Set_Device proc push ax push dx mov dx, cs:W83977_IO_PORT mov al, 07h out dx, al inc dx mov al, bl out dx, al pop dx pop ax ret Set_Device endp ;;--------------------------------------------------- ;;--------------------------------------------------- ;; Write data to W83977 Register ;; al : register number ;; ah : data ;; bl : device number ;;--------------------------------------------------- W977_Register_Set PROC push dx call Unlock_977 call Set_Device mov dx, cs: W83977_IO_PORT out dx, al mov al, ah inc dx out dx, al call Lock_977 pop dx ret W977_Register_Set ENDP ;;--------------------------------------------------- end WatchDog Demo program 2 (C language): //============================================================== // Title : WatchDog Timer Test Utility // Programer: Winston Kang // Version : 1.0 // Date : 04/20/2001 // Compiler : Borland C ++ //============================================================== #include #include #include #define IO_INDEX_PORT 0x3F0 #define IO_DATA_PORT 0x3F1 #define UNLOCK_DATA 0x87 #define LOCK_DATA 0xAA #define DEVICE_REGISTER 0x07 void EnterConfigMode() { outportb(IO_INDEX_PORT, UNLOCK_DATA); outportb(IO_INDEX_PORT, UNLOCK_DATA); } void ExitConfigMode() { outportb(IO_INDEX_PORT, LOCK_DATA); } void SelectDevice(unsigned char device) { outportb(IO_INDEX_PORT, DEVICE_REGISTER); outportb(IO_DATA_PORT, device); } unsigned char ReadAData(short int reg) { outportb(IO_INDEX_PORT, reg); return (inportb(IO_DATA_PORT)); } void WriteAData(unsigned char reg, unsigned char data) { outportb(IO_INDEX_PORT, reg); outportb(IO_DATA_PORT, data); } void SetWatchDogTime(unsigned char time_val) { EnterConfigMode(); SelectDevice(8); //Set Register F2 //Set Watch-Dog Timer 1~ 255 minutes WriteAData(0xF2, time_val); //Set Register 30 //Set Device 8 Function enable WriteAData(0x30, 0x01); ExitConfigMode(); } void main(int argc, char* argv[]) { int time_value=0; char *ptr; printf("WinBond 83977EF WatchDog Timer Test Utility Version 1.0 \n"); if (argc == 1) { printf("\n Syntax: WD_TEST [step] \n"); printf(" step range : 1 ~ 255 steps \n"); printf(" timer range: 0:32 ~ 255:32 (min:sec) \n"); return ; } if (argc > 1) { ptr = argv[1]; time_value = atoi(ptr); } if (time_value > 0 && time_value < 256) { SetWatchDogTime((unsigned char) time_value); printf("Watch Dog reset Timer set up : %02d:%02d ",(time_value-1), 32); } }