?? watchdog.c
字號:
/*======================================================================
Project Name : S3C2443 verification project
Copyright 2006 by Samsung Electronics, Inc.
All rights reserved.
Project Description :
This software is only for verifying functions of the S3C2443.
Anybody can use this code without our permission.
File Name : watchdog.c
Description : S3C2443 WDT module code
Author : Junon Jeon
Dept : AP
Created Date : 2006.06.02
Version : 0.0
History
R0.0 (2006.06.02): Junon draft
- This code is derived from S3C2413A watchdog test code.
=======================================================================*/
#include <stdio.h>
#include "option.h"
#include "2443addr.h"
#include "watchdog.h"
#include "system.h"
#include "console.h"
volatile int isWdtInt;
void __irq ISR_Watchdog(void);
void WDT_ManualTest(void);
void WDT_AutoTest(void);
void WDT_Open(void);
void WDT_Close(void);
unsigned int WDT_ResetFunc(void);
unsigned int GetWDTdivider(unsigned int sel);
void * func_wdt_test[][2]=
{
// "123456789012345678901"
(void *)WDT_ManualTest, "Manual Reset Test ",
(void *)WDT_AutoTest, "Automatic Test ",
0,0
};
void Test_Watchdog(void)
{
int i;
while(1)
{
i=0;
printf("\n\n=============== Watchdog Function Test ===============\n\n");
while(1)
{ //display menu
printf("%2d:%s",i,func_wdt_test[i][1]);
i++;
if((int)(func_wdt_test[i][0])==0)
{
printf("\n");
break;
}
if((i%4)==0)
printf("\n");
}
printf("\n======================================================\n");
printf("Select #Item or Press Enter key to exit : ");
i = GetIntNum();
if(i==-1) break; // return.
if(i>=0 && (i<((sizeof(func_wdt_test)-1)/8)) ) // select and execute...
( (void (*)(void)) (func_wdt_test[i][0]) )();
}
}
////////////////////////////// Library function /////////////////////////////
void __irq ISR_Watchdog(void) // for interrupt test
{
if(rSUBSRCPND & BIT_SUB_WDT)
{
rSUBSRCPND = BIT_SUB_WDT;
printf("%d ",++isWdtInt);
}
ClearPending(BIT_WDT_AC97);
}
unsigned int GetWDTdivider(unsigned int sel)
{
unsigned int ret;
switch(sel)
{
case 0 :
ret = 16;
break;
case 1 :
ret = 32;
break;
case 2 :
ret = 64;
break;
case 3 :
ret = 128;
break;
default :
ret = 16;
break;
}
return ret;
}
void WDT_Open(void)
{
rINTSUBMSK &= ~(BIT_SUB_WDT);
rINTMSK &= ~(BIT_WDT_AC97); //Watch dog Interrupt service is available
pISR_WDT_AC97= (unsigned )ISR_Watchdog;
isWdtInt = 0;
rWTCON = 0; // wdt reset & interrupt disable
}
void WDT_Close(void)
{
rINTSUBMSK |= BIT_SUB_WDT;
rINTMSK |= BIT_WDT_AC97; //WDT Interrupt Mask
}
unsigned int WDT_ResetFunc(void)
{
// Reset function test
rWTCON &= ~(1<<5); // WDT disable
printf("\n Do you want to test WDT Reset function? 'y' or 'n'\n");
if (getchar()=='y')
{
printf(" System would be reset....\n");
rWTCON |= (1<<5)|1; // WDT enable & reset enable
return 1;
}
else
{
rWTCON |= (1<<5); // WDT enable only
return 0;
}
}
////////////////////////////// Test Function /////////////////////////////
void WDT_ManualTest(void)
{
unsigned int pres_val, clk_div, wt_count, s_factor;
unsigned int temp_num;
WDT_Open();
// Timer function test
printf(" Select Prescaler value [0(D)~255] : ");
pres_val = (unsigned int)GetIntNum();
if (pres_val > 255)
{
printf(" Typed number is over 255! Be set as 0!\n");
pres_val = 0;
}
printf(" Select Clock division factor [0:16(D), 1:32, 2:64, 3:128] : ");
clk_div = (unsigned int)GetIntNum();
if (clk_div > 3)
{
printf(" Typed number is over 3! Be set as 0!\n");
clk_div = 0;
}
rWTCON = (pres_val<<8) | (clk_div<<3) | (1<<2); //Prescaler,Clock division,Interrupt enable
temp_num = GetWDTdivider(clk_div);
wt_count = PCLK/(pres_val+1)/temp_num; // count as 1 second
s_factor = (unsigned int)(wt_count/0xffff) + 1;
if(wt_count > 0xffff)
{
printf(" Count down interval changed from 0x%x to 0xffff \n",wt_count);
wt_count = 0xffff;
}
rWTDAT = wt_count; // about 1 sec. or under : interval of interrupt
rWTCNT = wt_count;
if (WDT_ResetFunc())
printf(" WDT Reset after 1 period time. \n");
else
{
printf(" WDT only timer function check for 3 seconds! \n");
printf(" Interrupt count!!\n ");
while(isWdtInt < 3*s_factor) // about 3 seconds or over
if (Uart_GetKey()) break;
}
WDT_Close();
}
void WDT_AutoTest(void) // timer function
{
unsigned int pres_val, clk_div, wt_count, s_factor;
unsigned int temp_num, end_flag = 0;
WDT_Open();
// Timer function test
printf(" Watchdog timer function test \n");
for (pres_val=0;pres_val<256;pres_val++)
{
for(clk_div=0;clk_div<4;clk_div++)
{
rWTCON = (pres_val<<8)|(1<<5)|(clk_div<<3)|(1<<2); //Prescaler=0x2a(42),Clock division 128,Interrupt enable
temp_num = GetWDTdivider(clk_div);
wt_count = PCLK/(pres_val+1)/temp_num; // count as 1 second
s_factor = (unsigned int)(wt_count/0xffff) + 1;
if(wt_count > 0xffff)
{
printf(" Count down interval changed from 0x%x to 0xffff \n",wt_count);
wt_count = 0xffff;
}
rWTDAT = wt_count; // for 1 sec. interval
rWTCNT = wt_count;
rWTCON = rWTCON | (1<<5); //Watch-dog timer enable
printf(" WDT input clock changed after wdt interrupt happened 1 time.\n");
while(isWdtInt < s_factor) // about 1 seconds
if (Uart_GetKey())
{
end_flag = 1;
break;
}
printf(" Prescaler : %d, Clock divider : %d Test OK!!\n", pres_val, clk_div);
isWdtInt = 0;
}
if (end_flag == 1) break;
}
printf(" Timer function test ok!\n");
rWTCON &= ~(1<<5); // WDT disable
printf(" WDT Reset after about 1 seconds. \n");
rWTCON |= (1<<5)|1; // WDT enable & reset enable
WDT_Close();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -