www.pudn.com > armmousecouter.rar > 44blib.c


/**************************************************************************** 
【文  件  名  称】44blib.c 
【功  能  描  述】三星S3C44B0X通用子函数 
【程  序  版  本】4.0 
【创建人及创建日期】龚俊//2002年11月19日19:26 
【修改人及修改日期】龚俊//2003年3月12日20:24 
****************************************************************************/ 
 
//*************************************************************************** 
#include "..\inc\44b.h" 
#include "..\inc\44blib.h" 
#include "..\inc\def.h" 
#include "..\inc\option.h" 
 
#include  
#include  
#include  
#include  
#include  
 
#define STACKSIZE    0xa00 //SVC satck size(do not use user stack) 
#define HEAPEND     (_ISR_STARTADDRESS-STACKSIZE-0x500) // = 0xc7ff000 
	//SVC Stack Area:0xc(e)7ff000-0xc(e)7ffaff 
 
extern char Image$$RW$$Limit[]; 
 
void *mallocPt=Image$$RW$$Limit; 
 
int MCLK = MCLK_D; 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】通用延时函数,延时time个100us 
time=0: adjust the Delay function by WatchDog timer. 
time>0: the number of loop time 
100us resolution. 
****************************************************************************/ 
static int delayLoopCount=400; 
void Delay(int time) 
{ 
    int i,adjust=0; 
 
    if(time==0) 
    { 
		time=200; 
		adjust=1; 
		delayLoopCount=400; 
		rWTCON=((MCLK/1000000-1)<<8)|(2<<3);    //MCLK/1M,Watch-dog disable,1/64,interrupt disable,reset disable 
		rWTDAT=0xffff;//for first update 
		rWTCNT=0xffff;//resolution=64us	@any MCLK  
		rWTCON=((MCLK/1000000-1)<<8)|(2<<3)|(1<<5); //Watch-dog timer start 
    } 
 
    for(;time>0;time--) 
 
	for(i=0;i64us, 200*400 cycle runtime = 64*i us 
		delayLoopCount=8000000/(i*64);	//200*400:64*i=1*x:100 -> x=80000*100/(64*i)    
    } 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】IO端口功能、方向设定 
****************************************************************************/ 
void Port_Init(void) 
{ 
	// PORT A GROUP 
	/*  BIT 9	8	7	6	5	4	3	2	1	0	*/ 
	/*  A24	  A23	A22	A21	A20	A19	A18	A17	A16	A0	*/	       
	/*  1		1	1	1	1	1	1	1	1	1	*/ 
	rPCONA = 0x3ff;	 
 
	// PORT B GROUP 
	/* BIT 10   9    8       7      6        5     4     3     2     1     0    */ 
	/*     /CS5 /CS4 /CS3    /CS2   /CS1     nWBE3 nWBE2 /SRAS /SCAS SCLS  SCKE	*/ 
	/*     NC   NC   RTL8019 USBD12 NV_Flash NC    NC    Sdram Sdram Sdram Sdram*/ 
	/*     0,   0,   1,      1,     1,       0,    0,    1,    1,    1,    1    */ 
	rPDATB = 0x1cf; 
	rPCONB = 0x1cf; 
     
	//PORT C GROUP 
	//BUSWIDTH=16													*/ 
	/*  PC15		14		13		12		11		10		9		8	*/ 
	/*	o		o		RXD1	TXD1	o		o		o		o	*/ 
	/*	NC		NC		Uart1	Uart1	NC		NC		NC		NC	*/ 
	/*   01		01		11		11		01		01		01		01	*/ 
 
	/*  PC7		6		5		4		3		2		1		0	*/ 
	/*   o		o		o		o		o		o		o		o	*/ 
	/*   NC		NC		NC		NC		NFALE 	NFCLE 	NFCE 	NFRB*/ 
	/*   01		01		01		01		01		01		01		00	*/ 
	rPDATC = 0x0001;	//All IO is low 
	rPCONC = 0x5f555554;	 
	rPUPC  = 0x3000;	//PULL UP RESISTOR should be enabled to I/O 
 
	//PORT D GROUP 
	/*  PORT D GROUP(I/O OR LCD)										*/ 
	/*  BIT7		6		5		4		3		2		1		0	*/ 
	/*      VF		VM		VLINE	VCLK	VD3		VD2		VD1		VD0	*/ 
	/*	   01		01		01		01		01		01		01		01	*/ 
	rPDATD= 0x55; 
	rPCOND= 0xaaaa;	 
	rPUPD = 0x00; 
	//These pins must be set only after CPU's internal LCD controller is enable 
	 
	//PORT E GROUP  
	/*  Bit 8		7		6		5		4		3		2		1		0		*/ 
	/*		ENDLAN	LED3	LED2	LED1	LED0	BEEP	RXD0	TXD0	CLKOUT	*/  
	/*      00		01		01		01		01		01		10		10		01		*/ 
	rPDATE	= 0x357; 
	rPCONE	= 0x556b;	 
	rPUPE	= 0x6; 
	 
	//PORT F GROUP 
	/*  Bit8		7		6		5		 4		3		2		1		0		*/    
	/*  IISCLK	IISDI	IISDO	IISLRCK	Input	Input	Input	IICSDA	IICSCL	*/ 
	/*	100		010		010		001		00		01		01		10		10		*/ 
	rPDATF = 0x0; 
	rPCONF = 0x22445a; 
	rPUPF  = 0x1d3; 
 
	//PORT G GROUP 
	/*  BIT7		6		5		4		3		2		1		0	 */ 
	/*	INT7		INT6		INT5		INT4		INT3		INT2		INT1		INT0	*/ 
	/*    S3		S4		S5		S6		NIC		EXT		IDE		USB	*/ 
	/*      11      11      11      11      11      11      11      11       */ 
	rPDATG = 0xff; 
	rPCONG = 0x0000; 
	rPUPG  = 0x00;	//should be enabled   
 
	rSPUCR=0x7;  //D15-D0 pull-up disable 
 
	/*所有的外部硬件中断为低电平触发*/ 
	rEXTINT=0x0; 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】选择串口通道为COM0或者COM1 
****************************************************************************/ 
static int whichUart=0; 
void Uart_Select(int ch) 
{ 
    whichUart=ch; 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】异步串行口初始化 
****************************************************************************/ 
void Uart_Init(int mclk,int baud) 
{ 
    int i; 
    if(mclk==0) 
	mclk=MCLK; 
    rUFCON0=0x0;     //FIFO disable 
    rUFCON1=0x0; 
    rUMCON0=0x0; 
    rUMCON1=0x0; 
//UART0 
    rULCON0=0x3;     //Normal,No parity,1 stop,8 bit 
//    rULCON0=0x7;     //Normal,No parity,2 stop,8 bit 
    rUCON0=0x245;    //rx=edge,tx=level,disable timeout int.,enable rx error int.,normal,interrupt or polling 
    rUBRDIV0=( (int)(mclk/16./baud + 0.5) -1 ); 
//UART1 
//    rULCON1=0x7;     //Normal,No parity,2 stop,8 bit 
    rULCON1=0x3; 
    rUCON1=0x245; 
    rUBRDIV1=( (int)(mclk/16./baud + 0.5) -1 ); 
 
    for(i=0;i<100;i++); 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】等待直到串口发送缓冲区内部的数据发送完毕 
****************************************************************************/ 
void Uart_TxEmpty(int ch) 
{ 
    if(ch==0) 
	while(!(rUTRSTAT0 & 0x4)); //wait until tx shifter is empty. 
    else 
    	while(!(rUTRSTAT1 & 0x4)); //wait until tx shifter is empty. 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】从串口接收一个字符 
****************************************************************************/ 
char Uart_Getch(void) 
{ 
    if(whichUart==0) 
    {	     
		while(!(rUTRSTAT0 & 0x1)); //Receive data read 
		return RdURXH0(); 
    } 
 
    else 
    { 
		while(!(rUTRSTAT1 & 0x1)); //Receive data ready 
		return	rURXH1; 
    } 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】从串口接收一个字符,如果没有收到数据返回0 
****************************************************************************/ 
char Uart_GetKey(void) 
{ 
    if(whichUart==0) 
    {	     
		if(rUTRSTAT0 & 0x1)    //Receive data ready 
	    	    return RdURXH0(); 
		else 
		    return 0; 
    } 
    else 
    { 
		if(rUTRSTAT1 & 0x1)    //Receive data ready 
		    return rURXH1; 
		else 
		    return 0; 
    } 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】从串口获取一个字符串 
****************************************************************************/ 
void Uart_GetString(char *string) 
{ 
    char *string2=string; 
    char c; 
    while((c=Uart_Getch())!='\r')		//输入字符不等于回车 
    { 
		if(c=='\b')		//输入字符等于退格 
		{ 
		    if(	(int)string2 < (int)string ) 
		    { 
				Uart_Printf("\b \b"); 
				string--; 
		    } 
		} 
		else  
		{ 
		    *string++=c; 
		    Uart_SendByte(c); 
		} 
    } 
    *string='\0';		//内容为空 
    Uart_SendByte('\n');		//换行 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】从串口获取一个整型数 
****************************************************************************/ 
int Uart_GetIntNum(void) 
{ 
    char str[30]; 
    char *string=str; 
    int base=10; 
    int minus=0; 
    int lastIndex; 
    int result=0; 
    int i; 
     
    Uart_GetString(string); 
     
    if(string[0]=='-') 
    { 
        minus=1; 
        string++; 
    } 
     
    if(string[0]=='0' && (string[1]=='x' || string[1]=='X')) 
    { 
	base=16; 
	string+=2; 
    } 
     
    lastIndex=strlen(string)-1; 
    if( string[lastIndex]=='h' || string[lastIndex]=='H' ) 
    { 
	base=16; 
	string[lastIndex]=0; 
	lastIndex--; 
    } 
 
    if(base==10) 
    { 
	result=atoi(string); 
	result=minus ? (-1*result):result; 
    } 
    else 
    { 
	for(i=0;i<=lastIndex;i++) 
	{ 
    	    if(isalpha(string[i])) 
	    { 
		if(isupper(string[i])) 
		    result=(result<<4)+string[i]-'A'+10; 
		else 
		    result=(result<<4)+string[i]-'a'+10; 
	    } 
	    else 
	    { 
		result=(result<<4)+string[i]-'0'; 
	    } 
	} 
	result=minus ? (-1*result):result; 
    } 
    return result; 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】向串口发送一个字节的整型数 
****************************************************************************/ 
void Uart_SendByte(int data) 
{ 
    if(whichUart==0) 
    { 
	if(data=='\n') 
	{ 
	    while(!(rUTRSTAT0 & 0x2)); 
//	    Delay(10);	//because the slow response of hyper_terminal  
	    WrUTXH0('\r'); 
	} 
	while(!(rUTRSTAT0 & 0x2)); //Wait until THR is empty. 
//	Delay(5); 
	WrUTXH0(data); 
    } 
    else 
    { 
	if(data=='\n') 
	{ 
    	    while(!(rUTRSTAT1 & 0x2)); 
//	    Delay(10);	//because the slow response of hyper_terminal  
	    rUTXH1='\r'; 
	} 
	while(!(rUTRSTAT1 & 0x2));  //Wait until THR is empty. 
//	Delay(5); 
	rUTXH1=data; 
    }	 
}		 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】向串口送出一串字符 
****************************************************************************/ 
void Uart_SendString(char *pt) 
{ 
    while(*pt) 
	Uart_SendByte(*pt++); 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】以标准输出格式向串口输出各种信息 
****************************************************************************/ 
//if you don't use vsprintf(), the code size is reduced very much. 
void Uart_Printf(char *fmt,...) 
{ 
    va_list ap; 
    char string[256]; 
 
    va_start(ap,fmt); 
    vsprintf(string,fmt,ap); 
    Uart_SendString(string); 
    va_end(ap); 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】蜂鸣器鸣叫time个100us 
****************************************************************************/ 
void Beep(unsigned int time) 
{ 
	rPDATE = (rPDATE | 0x08); 
	Delay(time);		//延时若干个100us 
	rPDATE = (rPDATE & 0x1f7); 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】检测四个按键,有任何一个按键按下就让蜂鸣器鸣叫,否则不鸣叫 
****************************************************************************/ 
void Key_Speaker(void) 
{ 
	unsigned int m; 
	m = rPDATG; 
	if((m & 0xf8) < 0xf8)	{rPDATE = (rPDATE | 0x08);} 
	else	{rPDATE = (rPDATE & 0x1f7);} 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】四个LED 点亮/熄灭状态设置(LedStatus低四位电平高低对应着四个LED亮/熄) 
****************************************************************************/ 
void Led_Set(int LedStatus) 
{ 
	if((LedStatus&0x01)==0x01)		//PE7状态设置 
		rPDATE=rPDATE&0x17f; 
	else 
		rPDATE=rPDATE|0x80; 
	 
	if((LedStatus&0x02)==0x02)		//PE6状态设置 
		rPDATE=rPDATE&0x1bf; 
	else 
		rPDATE=rPDATE|0x40; 
 
	if((LedStatus&0x04)==0x04)		//PE5状态设置 
		rPDATE=rPDATE&0x1df; 
	else 
		rPDATE=rPDATE|0x20; 
 
	if((LedStatus&0x08)==0x08)		//PE4状态设置 
		rPDATE=rPDATE&0x1ef; 
	else 
		rPDATE=rPDATE|0x10; 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】LED来回闪烁显示  
****************************************************************************/ 
void Led_Disp(void) 
{ 
	Led_Set(0x08);		//LED点亮/熄灭状态设置 
	Delay(500);		//延时若干个100us 
	Led_Set(0x04);		//LED点亮/熄灭状态设置 
	Delay(500);		//延时若干个100us 
	Led_Set(0x02);		//LED点亮/熄灭状态设置 
	Delay(500);		//延时若干个100us 
	Led_Set(0x01);		//LED点亮/熄灭状态设置 
	Delay(500);		//延时若干个100us 
	Led_Set(0x02);		//LED点亮/熄灭状态设置 
	Delay(500);		//延时若干个100us 
	Led_Set(0x04);		//LED点亮/熄灭状态设置 
	Delay(500);		//延时若干个100us 
	Led_Set(0x08);		//LED点亮/熄灭状态设置 
	Delay(500);		//延时若干个100us 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】定时器启动 
****************************************************************************/ 
void Timer_Start(int divider)  //0:16us,1:32us 2:64us 3:128us 
{ 
    rWTCON=((MCLK/1000000-1)<<8)|(divider<<3); 
    rWTDAT=0xffff; 
    rWTCNT=0xffff;    
 
    // 1/16/(65+1),nRESET & interrupt  disable 
    rWTCON=((MCLK/1000000-1)<<8)|(divider<<3)|(1<<5);	 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】定时器停止 
****************************************************************************/ 
int Timer_Stop(void) 
{ 
//    int i; 
    rWTCON=((MCLK/1000000-1)<<8); 
    return (0xffff-rWTCNT); 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】锁相环设置,修改系统主频 
Fout = (8 + M_DIV) * Fin / [ (2+P_DIV) * (2^S_DIV) ] 
****************************************************************************/ 
void ChangePllValue(int mdiv,int pdiv,int sdiv) 
{ 
	int i = 1;	 
	 
    rPLLCON = (mdiv << 12) | (pdiv << 4) | sdiv; 
 
	while(sdiv--) 
		i *= 2;	 
	 
	MCLK = (EXT_OSC_CLK*(mdiv+8))/((pdiv+2)*i);		 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】 
****************************************************************************/ 
void * malloc(unsigned nbyte)  
/*Very simple; Use malloc() & free() like Stack*/ 
//void *mallocPt=Image$$RW$$Limit; 
{ 
    void *returnPt=mallocPt; 
 
    mallocPt= (int *)mallocPt+nbyte/4+((nbyte%4)>0); //to align 4byte 
 
    if( (int)mallocPt > HEAPEND ) 
    { 
	mallocPt=returnPt; 
	return NULL; 
    } 
    return returnPt; 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】 
****************************************************************************/ 
void free(void *pt) 
{ 
    mallocPt=pt; 
} 
//*************************************************************************** 
 
/**************************************************************************** 
【功能说明】 
****************************************************************************/ 
void Cache_Flush(void) 
{ 
    int i,saveSyscfg; 
     
    saveSyscfg=rSYSCFG; 
 
    rSYSCFG=SYSCFG_0KB; 		       
    for(i=0x10004000;i<0x10004800;i+=16)     
    {					    
	*((int *)i)=0x0;		    
    } 
    rSYSCFG=saveSyscfg; 			     
} 
//***************************************************************************