www.pudn.com > s3c2443_test_code.zip > Uart.c


//Description :  The description of Function Pointer sholud be under 15 characters 
 
 
#include "system.h" 
#include "Uart.h" 
 
 
 
#define UART0_REG ( UART_REGS *)UART_REG_BASE  // Uart 0 register base address 
#define UART1_REG ( UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET) 
#define UART2_REG ( UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*2)  
#define UART3_REG ( UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*3)  
#define UART_BUF (_NONCACHE_STARTADDRESS + 0x10000) 
#define FIFO_DEBUG_BUF (_NONCACHE_STARTADDRESS + 0x11000) 
 
#define TX_FIFO_RESET	(1<<2) 
#define RX_FIFO_RESET	(1<<1) 
#define TX_INT_TYPE(Bit)		((Bit)<<9) // 0:pulse 1:level 
#define RX_INT_TYPE(Bit)		((Bit)<<8) // 0:pulse 1:level 
 
 
#define RX_TIMEOUT_EN	(0<<7) // 0:disable 1:enable, disable for FIFO test 
#define RX_ERR_INT_EN	(1<<6) // 0:disable 1:enable 
#define RTS_ACTIVE		(1) // In normal mode, nRTS signal  0:low, 1:High 
 
//2460 -> 2443 porting 
#define BIT_UART_ERROR		(1<<2) 
#define BIT_UART_TXD		(1<<1) 
#define BIT_UART_RXD		(1) 
#define BIT_UART			(1<>(32-uLenOfBit) ) << uShiftWidth)) | (uVal <>28], BitTable[((a) & 0xF000000)>>24],BitTable[((a) & 0xF00000)>>20],\ 
										BitTable[((a) & 0xF0000)>>16],BitTable[((a) & 0xF000)>>12],BitTable[((a) & 0xF00)>>8],\ 
										BitTable[((a) & 0xF0)>>4],	BitTable[((a) & 0xF)]) 
 
char BitTable[16][10] = {    
						"0000  ", 
						"0001  ", 
						"0010  ", 
						"0011  ", 
						"0100  ", 
						"0101  ", 
						"0110  ", 
						"0111  ", 
						"1000  ", 
						"1001  ", 
						"1010  ", 
						"1011  ", 
						"1100  ", 
						"1101  ", 
						"1110  ", 
						"1111  " 
					   }; 
//-->Debugging Only					    
					    
					    
#define		TRUE		1 
#define		FALSE		0 
#define		BOOL		unsigned int 
BOOL		g_bIsLevelInt = TRUE; //TRUE : Level Type , FALSE : Pulse Type 
 
 
 
 
 
typedef struct tag_UART_CON 
{ 
	unsigned int iBaudrate; 
	unsigned char fSelUartIrda; // Uart mode 
	unsigned char fLoopTest;  // UCON[5]  (0 : normal, 1 : LoopBack) 
	unsigned char fAfc; 
	unsigned char fEnableFifo; 
	unsigned char cOpClock; 	// 0,2:PCLK, 1:UEXTCLK, 2:EPLL 
	unsigned char cDataBit; 	// 0:5bit, 1:6bit, 2:7bit, 3:8bit 
	unsigned char cParityBit; 	// 0:no parity, 1:odd, 2:even, 3:forced 1, 4:forced 0 
	unsigned char cStopBit; 	// 0:one stopbit, 1:two stopbit 
	unsigned char cTxMode; 	// 0:disable, 1:interrupt or polling, 2:DMA0, 3:DMA1 
	unsigned char cTxTrig; 	// 0:empty, 1:16, 2:32, 3:48 (byte) 
	unsigned char cRxMode; 	// 0:disable, 1:interrupt or polling, 2:DMA0, 3:DMA1 
	unsigned char cRxTrig; 	// 0:1, 1:8, 2:16, 3:32 (byte) 
	unsigned char cRtsTrig; 	// 0:63, 1:56, 2:48, ... , 7:8 (byte) 
	unsigned char cSendBreakSignal;  // ULCON[4]  (0 : normal, 1 : Send Break Signal) 
} UART_CON; 
 
 
void SetUartPort(void); 
void ReturnUartPort(void); 
void CalcBaudrate( UART_REGS *, UART_CON *); 
int InitializeUart( UART_REGS *, UART_CON *);  // initialize with current setting 
void UartSubIsr(unsigned char ); 
void __irq UartIsr0(void); 
void __irq UartIsr1(void); 
void __irq UartIsr2(void); 
void __irq UartIsr3(void); 
 
void __irq DmaIsr(void); 
 
unsigned char SetBaudrate(unsigned char ch, unsigned int Baudrate); 
unsigned char SetOpClock(unsigned char ch, unsigned int OpClock); 
unsigned char SetLineCon(unsigned char ch, unsigned char DataBit, unsigned char StopBit, unsigned char ParityBit); 
unsigned char SetDbgUart(unsigned char ch);  // set registers with debug setting 
unsigned char UartOpen(unsigned char ch, unsigned int SetIRQ); 
unsigned char UartClose(unsigned char ch); 
 
 
void TestUart(void); 
void UartTx(void); 
void UartRx(void); 
 
 
static unsigned int	save_rGPHCON;//, save_rGPHPU, save_rSPCON;  // for setting Uart Port  
static UART_CON	UartCon[5] = {{115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0} 
									, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0} 
									, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0} 
									, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0} 
									, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0}};  
									// control property per each channel. 4th data is defualt value for initialize 
 
const unsigned int nSlotTable[16] = {0x0000, 0x0080, 0x0808, 0x0888, 0x2222, 0x4924, 0x4a52, 0x54aa, 
				     		0x5555, 0xd555, 0xd5d5, 0xddd5, 0xdddd, 0xdfdd, 0xdfdf, 0xffdf}; 
				     		 
U32 SRCPNDOFFSET;		 
U32 SUBINTOFFSET; 
 
volatile unsigned int UextClk = 12000000; 
volatile unsigned int EpllClk = 12000000; 
static volatile unsigned char isTxDone[4] = {0, 0, 0, 0}; 
static volatile unsigned char isRxDone[4] = {0, 0, 0, 0}; 
char *pUartTxStr[4], *pUartRxStr[4]; 
 
// buffer for test 
char TestString[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890->UART Tx interrupt test is good!!!!\r"; 
//char TestString[]="UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU!!!!\r"; //Test string for Toggling Value on the oscilloscope 
 
volatile unsigned int *pFifoDebug  = (unsigned int *)FIFO_DEBUG_BUF; //temporary for fifo count test 
volatile unsigned int fcnt = 0; 
 
 
void * func_uart_test[][2]= 
{	 
	(void *)TestUart, 		"UART Test	",	 
	0,0 
}; 
 
void Test_UART(void) 
{ 
	int i; 
	 
	printf("\n======  UART Test program start ======\n"); 
		 
	while(1) 
	{ 
		i=0; 
		printf("\n\n"); 
		while(1) 
		{   //display menu 
			printf("%2d:%s",i,func_uart_test[i][1]); 
			i++; 
			if((int)(func_uart_test[i][0])==0) 
			{ 
				printf("\n"); 
				break; 
			} 
			if((i%4)==0) 
			printf("\n"); 
		} 
 
		printf("\nPress Enter key to exit : "); 
 
		i = GetIntNum(); 
		if(i==-1) break;		// return. 
		if(i>=0 && (i<((sizeof(func_uart_test)-1)/8)) )	// select and execute... 
			( (void (*)(void)) (func_uart_test[i][0]) )(); 
	}	 
	printf("\n====== UART Test program end ======\n"); 
} 
 
///////////////////////// Test functions //////////////////////// 
 
unsigned char UartConfig(void) 
{ 
	unsigned char ch; 
	int iNum = 0; 
//	volatile UART_REGS *pUartRegs; 
	volatile UART_CON *pUartCon; 
	 
	 
 
	// Select Channel 
	printf("Note : [D] mark means default value. If you press ENTER key, default value is selected.\n"); 
	printf("Select Channel(0~3) [D=0] : "); 
 
	ch = (unsigned char)GetIntNum(); 
	if ( ch>3 )	ch = 0; // default uart 0 
		 
	pUartCon = &UartCon[ch];	 
 
	printf("\n\nConnect PC[COM1 or COM2] and UART%d of SMDK2443 with a serial cable for test!!! \n", ch); 
	 
	 
	//Set Other Options 
	printf("\nSelect Other Options\n 0. Nothing[D]  1.Send Break Signal  2. Loop Back Mode  \n Choose : "); 
	switch(GetIntNum()) 
	{		 
		default : 	{ 
						pUartCon->cSendBreakSignal = 0; 
						pUartCon->fLoopTest = 0; 
						break; 
					} 
		case 1 :		pUartCon->cSendBreakSignal = 1;	return ch; 
		case 2 : 	pUartCon->fLoopTest = 1;		break;		 
	}		 
	 
	 
	//Set Parity mode 
	printf("\nSelect Parity Mode\n 1. No parity[D] 2. Odd 3. Even 4. Forced as '1' 5. Forced as '0' \n Choose : "); 
	switch(GetIntNum()) 
	{		 
		default : 	pUartCon->cParityBit = 0;		break; 
		case 2 : 	pUartCon->cParityBit = 4;		break; 
		case 3 :		pUartCon->cParityBit = 5;		break; 
		case 4 :		pUartCon->cParityBit = 6;		break; 
		case 5 :		pUartCon->cParityBit = 7;		break; 
	} 
	//Set the number of stop bit	 
	printf("\n\nSelect Number of Stop Bit\n 1. One stop bit per frame[D] 2. Two stop bit per frame"); 
	switch(GetIntNum()) 
	{ 
		default : 	pUartCon->cStopBit = 0;		break; 
		case 2 : 	pUartCon->cStopBit = 1;		break;		 
	} 
	//Set Word Length	 
	printf("\n\nSelect Word Length\n 1. 5bits 2. 6bits 3. 7bits 4. 8bits \n Choose : "); 
	switch(GetIntNum()) 
	{		 
		case 1 :		pUartCon->cDataBit = 0;		break; 
		case 2 :		pUartCon->cDataBit = 1;		break; 
		case 3 :		pUartCon->cDataBit = 2;		break;	 
		default :		pUartCon->cDataBit = 3;		break; 
	} 
	 
	 
	// Set Operation clock 
	printf("\n\nSelect Operating Clock\n 1. PCLK[D]	2. UEXTCLK	3. EPLL \n Choose : "); 
	switch (GetIntNum()) 
	{ 
	case 2 : 
		pUartCon->cOpClock = 1; 
		// connect CLKOUT and UEXTCLK 
		rGPHCON = rGPHCON & ~(3<<24) | (1<<25);// Uextclk using			 
		UextClk = PCLK; 		 
		break; 
 
	case 3 : 
		pUartCon->cOpClock = 3; 
		SetEPLL(42, 1, 2); // Epll output - 96MHz, pll input - 12MHz 
		 // use EPLL output clock 
		rCLKSRC = rCLKSRC & ~(1<<6)|(1<<6); // epll output select 
		EpllClk = 50000000; 		 
		break; 
 
	default : 
		pUartCon->cOpClock = 0; // PCLK		 
		break; 
	} 
 
	// Select UART or IrDA 1.0 
	printf("\n\nSelect External Interface Type\n 1. UART[D]   2. IrDA mode\n Choose : "); 
	if (GetIntNum() == 2)		pUartCon->fSelUartIrda = 1; // IrDA mode 
	else					pUartCon->fSelUartIrda = 0; // IrDA mode 
 
	// Set Baudrate 
	printf("\n\nType the baudrate and then change the same baudrate of host, too.\n"); 
	printf(" Baudrate (ex 9600, 115200[D], 921600) : "); 
	pUartCon->iBaudrate = GetIntNum(); 
	if ((int)pUartCon->iBaudrate == -1) pUartCon->iBaudrate = 115200; 
 
	// Select UART operating mode 
	printf("\n\nSelect Operating Mode\n 1. Interrupt[D]	2. DMA\n Choose : "); 
	if (GetIntNum() == 2) 
	{ 
		pUartCon->cTxMode = 2; // DMA0 mode 
		pUartCon->cRxMode = 3; // DMA1 mode 
	} 
	else 
	{	 
		pUartCon->cTxMode = 1; // Int mode 
		pUartCon->cRxMode = 1; // Int mode 
	} 
 
	// Select UART FIFO mode 
	printf("\n\nSelect FIFO Mode (Tx/Rx[byte])\n 1. no FIFO[D]  2. Empty/1  3. 16/8   4. 32/16  5. 48/32 \n Choose : "); 
	iNum = GetIntNum(); 
	if ( (iNum>1)&&(iNum<6) ) 
	{ 
		pUartCon->fEnableFifo = 1; 
		pUartCon->cTxTrig = iNum -2; 
		pUartCon->cRxTrig = iNum -2; 
	} 
	else  
	{ 
		pUartCon->fEnableFifo = 0; 
	} 
 
	// Select AFC mode enable/disable 
	printf("\n\nSelect AFC Mode\n 1. Disable[D]	2. Enable\n Choose : "); 
	if (GetIntNum() == 2) 
	{ 
		pUartCon->fAfc = 1; // AFC mode enable 
		printf("Select nRTS trigger level(byte)\n 1. 63[D]   2. 56   3. 48   4. 40   5. 32   6. 24   7. 16   8. 8\n Choose : "); 
		iNum = GetIntNum(); 
		if ( (iNum>1)&&(iNum<9) )	pUartCon->cRtsTrig = iNum -1; 
		else						pUartCon->cRtsTrig = 0; // default 63 byte 
	} 
	else 
	{ 
		pUartCon->fAfc = 0; // AFC mode disable 
	} 
	return ch; 
} 
 
 
void TxString(unsigned char ch, char *str)  // The last character of 'str' should be NULL 
{ 
	volatile UART_REGS *pUartRegs; 
	volatile UART_CON *pUartCon; 
	int iTemp; 
 
	pUartRegs = (volatile UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch); 
	pUartCon = &UartCon[ch];	 
 
	isTxDone[ch] = 0; 
	pUartTxStr[ch] = str; 
 
	pFifoDebug = (unsigned int *)FIFO_DEBUG_BUF; 
	fcnt = 0; 
 
	 
	if(ch == 1){	SUBINTOFFSET = 3;	SRCPNDOFFSET = 23;} 
	else if(ch == 2){	SUBINTOFFSET = 6;		SRCPNDOFFSET = 15;} 
	else if(ch == 3){	SUBINTOFFSET = 24;	SRCPNDOFFSET = 18;} 
	else {	SUBINTOFFSET = 0;	SRCPNDOFFSET = 28;}// CH 0 default		 
	 
		 
	iTemp = pUartCon->cTxMode & 3;	 
	 
	if ( iTemp == 1 ) // interrupt mode 
	{		 
		rINTMSK &= ~(BIT_UART);		 
		rINTSUBMSK &= ~(BIT_UART_TXD << SUBINTOFFSET);					 
	} 
	else if ( (iTemp==2) || (iTemp==3) ) // dma mode 
	{ 
		rDISRC0 = (unsigned int)str;	// Start address 
		rDISRCC0 = (0<<1)|(0);		// AHB,Increment 
		rDIDST0 = (unsigned int)(&pUartRegs->rUtxh); 	// Memory buffer Address 
		rDIDSTC0 = (1<<1)|(1);		// APB,Fixed 
		rDCON0 = (1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(1<<22)|(0<<20)|strlen(str); 
		//handshake, sync PCLK, TC int, single tx, single service,auto-reload off, Byte size Tx, Tx count value 
		rDMAREQSEL0 = ((19+ch*2)<<1)|1; 
 
		// Clear Int Pending and Unmask     
		rSUBSRCPND = BIT_SUB_DMA0; 
		ClearPending(BIT_DMA); 
		rINTMSK &= ~(BIT_DMA); 
		rINTSUBMSK &= ~(BIT_SUB_DMA0); 
		rDMASKTRIG0 = (0<<2)|(1<<1)|(0);    //no-stop, DMA0 channel on, no-SW trigger  
	}	 
	 
	 
	 
	while(!isTxDone[ch]); 
	 
	 
	rINTMSK |= (BIT_UART); 
	//rINTMSK |= (BIT_DMA); 
	rINTSUBMSK |= (BIT_UART_TXD<cRxMode & 3; 
	if ( iTemp == 1 ) // interrupt mode 
	{			 
		rINTMSK &= ~(BIT_UART); 
		rINTSUBMSK &= ~ ((BIT_UART_ERROR << SUBINTOFFSET)|(BIT_UART_RXD << SUBINTOFFSET));	 
		 
	} 
	else if ( (iTemp == 2) || (iTemp == 3) ) // dma mode 
	{ 
		printf("\nIn DMA rxstring mode");	 
		rDISRC1=(unsigned int)(&pUartRegs->rUrxh);	// Start address 
		rDISRCC1=(1<<1)|(1);		// APB,Fixed 
		rDIDST1=(unsigned int)(UART_BUF);	        // Memory buffer Address 
		rDIDSTC1= (0<<1)|(0);		// AHB,Increment 
		rDCON1=(1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(1<<22)|(0<<20)|(DMA_BUF_LEN);				 
		//handshake, sync PCLK, TC int, single tx, single service,auto-reload off, Byte size Tx, Tx count value 
		rDMAREQSEL1 = ((20+ch*2)<<1)|1; 
 
		// Clear Int Pending and Unmask    		 
		rINTMSK &= ~(BIT_DMA); 
		rINTSUBMSK &= ~(BIT_SUB_DMA1);		 
		rDMASKTRIG1 = (0<<2)|(1<<1)|(0);    //no-stop, DMA1 channel on, no-SW trigger 		 
	}	 
	while(!isRxDone[ch]); 
 
	pUartRxStr[ch] = ( char *)(UART_BUF+DMA_BUF_LEN); 
	return pUartRxStr[ch]; 
} 
 
	 
 
void TestUart(void) 
{ 
	unsigned char ch; 
	ch = UartConfig();	 
	if( UartOpen(ch,1) == SENDBREAK )  
	{ 
		printf("\n\nSend Break Signal has been transfered"); 
		return; 	 
	} 	 
	// UART Tx test with interrupt	 
	printf("\n[Uart channel %d Tx Test]\n",ch);	 
	TxString(ch, TestString);	 
	printf("\nTx Done~ \n");	 
		 
 
	// UART Rx test with interrupt  
	printf("\n[Uart channel %d Rx Test]\n",ch); 
	printf("Case 1 : Interrupt mode. After typing characters and pressing ENTER key.\n"); 
	printf("Case 2 : Interrupt FIFO mode & DMA mode. After typing characters and pressing ENTER key until FIFO level trigger.\n");	 
	printf(" Then, you will see those characters.\n"); 
	printf("\nRx : %s \n",RxString(ch)); 
	printf("\nRx Done~ \n"); 
 
	// Test End 
	printf("\nComplete UART test!!! \n"); 
	UartClose(ch); 
	SetDbgUart(1); // change channel setting for debug port set 
} 
 
 
void UartTx(void) 
{ 
	unsigned char ch; 
	char str[128]; 
 
	ch = UartConfig(); 
	UartOpen(ch,1);  
 
	printf("\n[Uart%1d Tx String]\n",ch); 
	printf("\nIf you want to exit, press 'ESC' key at first. The character instead of 'ESC' is ignored.\n"); 
	while (getchar() != 0x1b) 
	{ 
		gets(str); 
//		printf("Tx : "); 
		TxString(ch, str); 
		printf("\nIf you want to exit, press 'ESC' key at first. The character instead of 'ESC' is ignored.\n"); 
	}	 
 
	UartClose(ch); 
	SetDbgUart(0); // change channel setting for debug port set 
} 
 
 
void UartRx(void) 
{ 
	unsigned char ch; 
 
	ch = UartConfig(); 
	UartOpen(ch,1);  
 
	printf("\n[Uart%1d Rx String]\n",ch); 
	printf("\nIf you want to exit, press 'ESC' key at first. The character instead of 'ESC' is ignored.\n"); 
	while (getchar() != 0x1b) 
	{ 
		printf("Rx : %s ", RxString(ch));		 
		printf("\nIf you want to exit, press 'ESC' key at first. The character instead of 'ESC' is ignored.\n"); 
	}	 
 
	UartClose(ch); 
	SetDbgUart(0); // change channel setting for debug port set 
} 
 
 
 
 
void SetUartPort(void) 
{	//Push UART GPIO port configuration 
	save_rGPHCON = rGPHCON;  
 
	//Configure UART port 
	rGPHCON	&= ~((0xf<<20)|(0xf<<16)|(0xf<<12)|(0xf<<8)|(0xf<<4)|(0xf<<0)); 
	rGPHCON	|=  ((0xa<<20)|(0xa<<16)|(0xa<<12)|(0xa<<8)|(0xa<<4)|(0xa<<0)); 
  
}        
 
void ReturnUartPort(void) 
{    //Pop UART GPIO port configuration 
	rGPHCON = save_rGPHCON; 
} 
 
void CalcBaudrate( UART_REGS *pUartRegs, UART_CON *pUartCon) 
{ 
	float tempDiv; 
	unsigned int nOpClock; 
	unsigned int nSlot; 
	 
	switch(pUartCon->cOpClock) 
	{ 
		case 1 : 			nOpClock = UextClk;			break;// Uextclk 
		case 3 : 			nOpClock = EpllClk;			break;// Epll 
		case 0 : 
		case 2 : // Pclk 
		default : 			nOpClock = PCLK;			break; 
	} 
 
	tempDiv = (nOpClock/(16.*pUartCon->iBaudrate)) - 1; 
	nSlot = (int)((tempDiv - (int)tempDiv) * 16); 
	pUartRegs->rUbrDiv = (int)(tempDiv); 
	pUartRegs->rUdivSlot = nSlotTable[nSlot];	 
} 
 
int InitializeUart( UART_REGS *pUartRegs, UART_CON *pUartCon) // Initialize register set with current control set 
{ 
	#if 1 
	rGPHCON = ((rGPHCON  & ~(0x03 << 26)) | (0x02 << 26));	 
	rMISCCR = ((rMISCCR  & ~(0x07 << 4)) | (0x04 << 4));	 
	#endif  
	 
	CalcBaudrate(pUartRegs, pUartCon); 
	 
	pUartRegs->rUlCon = (pUartCon->fSelUartIrda<<6)|(pUartCon->cParityBit<<3)|(pUartCon->cStopBit<<2) 
						|(pUartCon->cDataBit); 
	pUartRegs->rUCon = (pUartCon->cOpClock<<10)|TX_INT_TYPE(g_bIsLevelInt)|RX_INT_TYPE(g_bIsLevelInt)|RX_ERR_INT_EN|RX_TIMEOUT_EN 
						|(pUartCon->fLoopTest<<5)| (pUartCon->cSendBreakSignal<<4) |(pUartCon->cTxMode<<2)|(pUartCon->cRxMode);		 
	if(pUartCon->cSendBreakSignal) 
		return SENDBREAK; 
	pUartRegs->rUfCon = (pUartCon->cTxTrig<<6)|(pUartCon->cRxTrig<<4)|TX_FIFO_RESET|RX_FIFO_RESET 
						|(pUartCon->fEnableFifo); 
	pUartRegs->rUmCon = (pUartCon->cRtsTrig<<5)|(pUartCon->fAfc<<4)|RTS_ACTIVE;	 
	return 0; 
	 
} 
 
//ARM disables IFQ in CPSR  When it enters ISR, There is no need to masking SUBMASK or MASK registers 
void __irq UartIsr0(void) 
{		 
	UartSubIsr(0);	 
}		 
 
void __irq UartIsr1(void) 
{	 
	UartSubIsr(1); 
} 
 
void __irq UartIsr2(void) 
{	 
	UartSubIsr(2); 
} 
 
void __irq UartIsr3(void) 
{	 
	UartSubIsr(3); 
}	 
 
 
 
void UartSubIsr(unsigned char ch) 
{ 
	unsigned int ErrorStatus = 0;	 
	char ReadChar; 
	unsigned int uSubSrcPnd; 
	volatile UART_REGS *pUartRegs;			 
	 
	uSubSrcPnd = rSUBSRCPND;	 
	pUartRegs = ( UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch); 
	 
	if(ch == 1)		{		SUBINTOFFSET = 3;		SRCPNDOFFSET = 23;	} 
	else if(ch == 2)	{		SUBINTOFFSET = 6;		SRCPNDOFFSET = 15;	} 
	else if(ch == 3)	{		SUBINTOFFSET = 24;		SRCPNDOFFSET = 18;	} 
	else 			{		SUBINTOFFSET = 0;		SRCPNDOFFSET = 28;	}// default : CH 0		 
	 
	if(!g_bIsLevelInt)		rSUBSRCPND = (BIT_UART_ERROR<rUerStat; 
		switch(ErrorStatus)//to clear and check the status of register bits 
		{ 
			case 1:				printf("Overrun error!\n");					break;  
			case 2:				printf("Parity error!\n");						break; 
			case 4:				printf("Frame error!\n");						break; 
			case 6:				printf("Parity, Frame error!\n");				break; 
			case 8:				printf("Breake detect\n");					break; 
			case 0xa:			printf("Parity error & Break detect!\n");		break; 
			case 0xc:			printf("Frame error & Breake detect\n");		break; 
			case 0xe:			printf("Parity, Frame error & Break detect!\n");	break; 
			default :				printf("Unknown error : 0x%x\n", ErrorStatus); break; 
		} 
		isRxDone[ch] = 1;	 
		rINTSUBMSK |= (BIT_UART_RXD<rUfCon & 1) // 1 : fifo enable  
		{		 
			while (!(pUartRegs->rUfStat & (1<<14)) && (*pUartTxStr[ch] != TX_END_CHAR)) 	//until tx fifo full or end of string			 
				pUartRegs->rUtxh = *pUartTxStr[ch]++;					 
			if(   !( *pUartTxStr[ch])) // if there is no character in the pUartTxStr[ch], Tx is done 
			{		rINTSUBMSK |= (BIT_UART_TXD<rUtxh = *pUartTxStr[ch]++;	// if there is no character in the pUartTxStr[ch], Tx is done	 
			else 
			{	rINTSUBMSK |= (BIT_UART_TXD<rUfCon & 1) // 1 : fifo enable  
		{	 
			while (pUartRegs->rUfStat & 0x3f) 	//until rx fifo count 0			 
				*pUartRxStr[ch]++ = (unsigned char)(pUartRegs->rUrxh);	 
				 
			if(*(pUartRxStr[ch]-1) == RX_END_CHAR)  
			{			 
				*pUartRxStr[ch] = NULL;				isRxDone[ch] = 1; 
				rINTSUBMSK |= (BIT_UART_RXD<rUrxh); 
			if (ReadChar != RX_END_CHAR)		*pUartRxStr[ch]++ = ReadChar; 
			else  
			{ 
				*pUartRxStr[ch] = NULL;			    	printf("\n");				 
				isRxDone[ch] = 1;		 
				rINTSUBMSK |= (BIT_UART_RXD<>1) -19)/2; 
		isTxDone[ch] = 1; 
		 
		rINTSUBMSK |= (BIT_SUB_DMA0);		 
		rSUBSRCPND = BIT_SUB_DMA0; 
		ClearPending(BIT_DMA); 
	} 
 
	if (rSUBSRCPND&BIT_SUB_DMA1) 
	{	//printf("\n [RX]IN DMA "); 
		rDMASKTRIG1=0;	// Stop Dma1 
		pBuf = (unsigned char*)UART_BUF; 
		ch = ((rDMAREQSEL1>>1) -19)/2; 
 
		for (i=0; i 2) return FALSE; 
	 
	pUartCon = &UartCon[ch];	 
	pUartRegs = (UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch); 
 
	pUartCon->iBaudrate = Baudrate; 
	CalcBaudrate(pUartRegs, pUartCon); 
 
	return TRUE; 
} 
 
unsigned char SetOpClock(unsigned char ch, unsigned int OpClock) 
{ 
	volatile UART_REGS *pUartRegs; 
	volatile UART_CON *pUartCon; 
 
	if (ch > 2) return FALSE; 
 
	pUartCon = &UartCon[ch];	 
	pUartRegs = (volatile UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch); 
 
	pUartCon->cOpClock = OpClock; 
	pUartRegs->rUCon &= ~(3<<10); 
	pUartRegs->rUCon |= (pUartCon->cOpClock<<10); 
 
	return TRUE; 
} 
 
//DataBit    	0:5bit, 1:6bit, 2:7bit, 3:8bit 
//ParityBit  	0,1,2,3:no parity, 4:odd, 5:even, 6:forced 1, 7:forced 0 
//StopBit 	0:one stopbit, 1:two stopbit 
unsigned char SetLineCon(unsigned char ch, unsigned char DataBit, unsigned char ParityBit, unsigned char StopBit) 
{ 
	volatile UART_REGS *pUartRegs; 
	volatile UART_CON *pUartCon; 
 
	if (ch > 2) return FALSE; 
 
	pUartCon = &UartCon[ch];	 
	pUartRegs = (volatile UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch); 
 
	pUartCon->cDataBit = DataBit; 
	pUartCon->cParityBit = ParityBit; 
	pUartCon->cStopBit = StopBit; 
	pUartRegs->rUlCon = pUartRegs->rUlCon&(~0x3f) | (pUartCon->cParityBit<<3)|(pUartCon->cStopBit<<2)|(pUartCon->cDataBit); 
 
	return TRUE; 
} 
 
unsigned char SetDbgUart(unsigned char ch) 
{ 
	if (ch > 3) return FALSE; 
 
	memcpy(&UartCon[ch], &UartCon[4], sizeof(UART_CON)); 
	UartOpen(ch,1); 
	 
	return TRUE; 
} 
 
 
unsigned char UartOpen(unsigned char ch, unsigned int SetIRQ) // setting H/W & initializing regiter 
{ 
	if(SetIRQ) 
	{ 
		pISR_UART0 = (unsigned)UartIsr0; 
		pISR_UART1 = (unsigned)UartIsr1; 
		pISR_UART2 = (unsigned)UartIsr2; 
		pISR_UART3 = (unsigned)UartIsr3; 
		pISR_DMA = (unsigned)DmaIsr; 
	} 
 
	switch(ch) 
	{ 
		case 0 : 
			rGPHCON &= ~(0xf000f); // GPH0,1,8,9 
			rGPHCON |= 0xa000a; // Uart 0 Rx, Tx, Rts, Cts			 
			if(InitializeUart(UART0_REG, &UartCon[0])  == SENDBREAK) 
				return SENDBREAK; // Initialize register set for Uart 0 
			break; 
		case 1 : 
			rGPHCON &= ~(0xf000f<<4); // GPH2,3,10,11 
			rGPHCON |= (0xa000a<<4); // Uart 1 Rx, Tx, Rts, Cts 
			if(InitializeUart(UART1_REG, &UartCon[1]) == SENDBREAK) 
				return SENDBREAK; 
			break; 
		case 2 : 
			rGPHCON &= ~(0xf<<6); // GPH4,5 
			rGPHCON |= (0xa<<6); // Uart 2 Rx, Tx 
			if(InitializeUart(UART2_REG, &UartCon[2]) == SENDBREAK) 
				return SENDBREAK; 
			break; 
		case 3 : 
			rGPHCON &= ~(0xf<<12); // GPH6,7 
			rGPHCON |= (0xa<<12); // Uart 3 Rx, Tx 
			if(InitializeUart(UART3_REG, &UartCon[3]) == SENDBREAK) 
				return SENDBREAK; 
			break; 
		default : 
			printf("Can't open UARTx!! Select 0,1, or 2!!"); 
			return FALSE; 
	} 
	return TRUE; 
} 
 
 
unsigned char UartClose(unsigned char ch)  // return to reset value 
{ 
	if (ch > 3) return FALSE; 
	rINTMSK |= (BIT_UART); 
	rINTSUBMSK |=  (BIT_UART_ERROR<