/*******************************************************
* File�� Uart0.c
* Author:
* Date:
* Version: 1.01
* Desc�� S3C2440 UART-0 test code.
* History:
********************************************************/
#include <string.h>
#include <stdlib.h>
#include "Def.h"
#include "2440addr.h"
#include "2440lib.h"
#include "Uart0.h"
void Uart_Port_Set(void);
void Uart_Port_Return(void);
void __irq Uart0_TxInt(void);
void __irq Uart0_RxIntOrErr(void);
void __irq Uart0_TxDmaDone(void);
void __irq Uart0_RxDmaDone(void);
void __irq Uart0_RxDmaOrErr(void);
void __irq Uart0_TxFifo(void);
void __irq Uart0_RxFifoOrErr(void);
void __irq Uart0_AfcTx(void);
void __irq Uart0_AfcRxOrErr(void);
void __irq Uart0_RxOverrunErr(void);
void __sub_Uart0_RxInt(void);
void __sub_Uart0_RxFifo(void);
void __sub_Uart0_RxAfc(void);
void __sub_Uart0_RxErrInt(void);
void Uart_Fclkn_Dis(void); // for 2440A
volatile U16 rx_dncs;
volatile U32 rx_point,rx_isdone,rx_filesize,rx_checksum;
volatile U32 isDone,isTxInt,isRxInt,tx_cnt,tx_end,rx_cnt,rx_end,afc_err;
volatile U8 *txdataPt;
volatile U8 *txdataFl;
volatile U8 *rxdataPt;
volatile U8 *rxdataCk;
volatile U32 *dbg_data;
U8 temp_exit;
volatile U32 save_rGPHCON,save_rGPHDAT,save_rGPHUP;
volatile U32 save_ULCON0,save_UCON0,save_UFCON0,save_UMCON0,save_UBRDIV0;
volatile U32 save_ULCON1,save_UCON1,save_UFCON1,save_UMCON1,save_UBRDIV1;
volatile U32 save_ULCON2,save_UCON2,save_UFCON2,save_UMCON2,save_UBRDIV2;
volatile static char *uart0TxStr;
volatile static char *uart0RxStr;
extern U32 Fclk, Pclk;
void Uart_Port_Set(void)
{
//Push UART GPIO port configuration
save_rGPHCON=rGPHCON;
save_rGPHDAT=rGPHDAT;
save_rGPHUP=rGPHUP;
//Configure UART port
rGPHCON&=0x3c0000;
rGPHCON|=0x2aaaa; // enable all uart channel
rGPHUP|=0x1ff; //Uart port pull-up disable
rGPGCON|=(0xf<<18); // nRTS1, nCTS1
rGPGUP|=(0x3<<9);
//rINTSUBMSK=0x7ff; //SUBINT ALL MASK
//Push Uart control registers
save_ULCON0=rULCON0;
save_UCON0=rUCON0;
save_UFCON0=rUFCON0;
save_UMCON0=rUMCON0;
save_ULCON1=rULCON1;
save_UCON1 =rUCON1;
save_UFCON1=rUFCON1;
save_UMCON1=rUMCON1;
save_ULCON2=rULCON2;
save_UCON2 =rUCON2;
save_UFCON2=rUFCON2;
save_UMCON2=rUMCON2;
save_UBRDIV0=rUBRDIV0;
save_UBRDIV1=rUBRDIV1;
save_UBRDIV2=rUBRDIV2;
//Initialize UART1,2 port
}
void Uart_Port_Return(void)
{
//Pop UART GPIO port configuration
rGPHCON=save_rGPHCON;
rGPHDAT=save_rGPHDAT;
rGPHUP=save_rGPHUP;
//Pop Uart control registers
rULCON0=save_ULCON0;
rUCON0 =save_UCON0;
rUFCON0=save_UFCON0;
rUMCON0=save_UMCON0;
rULCON1=save_ULCON1;
rUCON1 =save_UCON1;
rUFCON1=save_UFCON1;
rUMCON1=save_UMCON1;
rULCON2=save_ULCON2;
rUCON2 =save_UCON2;
rUFCON2=save_UFCON2;
rUMCON2=save_UMCON2;
rUBRDIV0=save_UBRDIV0;
rUBRDIV1=save_UBRDIV1;
rUBRDIV2=save_UBRDIV2;
Uart_Fclkn_Dis();
}
// 2440X usage enable
void Uart_Uextclk_En(int ch,int baud, int clock)
{
if(ch == 0) {
rUCON0 = rUCON0 & ~(1<<11) |(1<<10); // Select UEXTCLK
rUBRDIV0=( (int)(clock/16./baud) -1 ); //Baud rate divisior register
}
else if(ch==1){
rUCON1 = rUCON1 & ~(1<<11) |(1<<10); // Select UEXTCLK
rUBRDIV1=( (int)(clock/16./baud) -1 ); //Baud rate divisior register
}
else {
rUCON2 = rUCON2 & ~(1<<11) |(1<<10); // Select UEXTCLK
rUBRDIV2=( (int)(clock/16./baud) -1 ); //Baud rate divisior register
}
}
//2440X usage enable
void Uart_Pclk_En(int ch, int baud)
{
if(ch == 0) {
rUCON0 &= ~(3<<10); // Select PCLK
rUBRDIV0=( (int)(Pclk/16./baud+0.5) -1 ); //Baud rate divisior register
}
else if(ch==1){
rUCON1 &= ~(3<<10); // Select PCLK
rUBRDIV1=( (int)(Pclk/16./baud+0.5) -1 ); //Baud rate divisior register
}
else {
rUCON2 &= ~(3<<10); // Select PCLK
rUBRDIV2=( (int)(Pclk/16./baud+0.5) -1 ); //Baud rate divisior register
}
}
void Uart_Fclkn_En(int ch, int baud) // for 2440A
{
int clock = PCLK;//Pclk;
Uart_Printf("Current FCLK is %d\n", Fclk);
#if 1
// input clock divider setting.
if ( (Fclk>290000000) && (Fclk<300000000) ) // for 296MHz
{
rUCON0 = (rUCON0 & ~(0xf<<12)) | (0xe<<12); // FCLK divider 14(n=20), for max 921.6kbps
rUCON1 &= ~(0xf<<12); // 0 setting
rUCON2 &= ~(0xf<<12); // 0 setting
clock = Fclk / 20;
Uart_Printf("1 : %d\n", clock);
}
else if ( (Fclk>395000000) && (Fclk<405000000) ) // for 399MHz
{
rUCON1 = (rUCON1 & ~(0xf<<12)) | (0x6<<12); // FCLK divider 6(n=27), for max 921.6kbps
rUCON0 &= ~(0xf<<12); // 0 setting
rUCON2 &= ~(0xf<<12); // 0 setting
clock = Fclk / 27;
Uart_Printf("2 : %d\n", clock);
}
else if ( (Fclk>525000000) && (Fclk<535000000) ) // for 530MHz
{
rUCON1 |= (0xf<<12); // FCLK divider 15(n=36), for max. 921.6kbps
rUCON0 &= ~(0xf<<12); // 0 setting
rUCON2 &= ~(0xf<<12); // 0 setting
clock = Fclk / 36;
Uart_Printf("3 : %d\n", clock);
}
rUCON2 |= (1<<15); // enable FCLK/n
#else
// In 921.6kbps case of following code, Fclk must be 296352000
rUCON0 = rUCON0 & ~(0xf<<12) | (0xe<<12); // FCLK divider 14(n=20), for max 921.6kbps
rUCON1 &= ~(0xf<<12); // 0 setting
rUCON2 &= ~(0xf<<12); // 0 setting
clock = Fclk / 20;
rUCON2 |= (1<<15); // enable FCLK/n
#endif
// select buadrate.
if(ch == 0) {
rUCON0 |= (3<<10); // Select FCLK/n
rUBRDIV0=( (int)(clock/16./baud+0.5) -1 ); //Baud rate divisior register
}
else if(ch==1){
rUCON1 |= (3<<10); // Select FCLK/n
rUBRDIV1=( (int)(clock/16./baud+0.5) -1 ); //Baud rate divisior register
}
else {
rUCON2 |= (3<<10); // Select FCLK/n
rUBRDIV2=( (int)(clock/16./baud+0.5) -1 ); //Baud rate divisior register
}
// S/W work-around for using FCLK/n
rGPHCON = rGPHCON & ~(3<<16); //GPH8(UEXTCLK) input
Delay(1);
rGPHCON = rGPHCON & ~(3<<16) | (1<<17); //GPH8(UEXTCLK) UEXTCLK
}
void Uart_Fclkn_Dis(void) // for 2440A
{
// S/W work-around for using FCLK/n
rGPHCON = rGPHCON & ~(3<<16); //GPH8(UEXTCLK) input
Delay(1);
rGPHCON = rGPHCON & ~(3<<16) | (1<<17); //GPH8(UEXTCLK) UEXTCLK
}
//---------------------------------------UART0 test function-------------------------------------
void __irq Uart0_TxInt(void)
{
rINTSUBMSK|=(BIT_SUB_RXD0|BIT_SUB_TXD0|BIT_SUB_ERR0); // Just for the safety
if(*uart0TxStr != '\0')
{
WrUTXH0(*uart0TxStr++);
ClearPending(BIT_UART0); // Clear master pending
rSUBSRCPND=(BIT_SUB_TXD0); // Clear Sub int pending
rINTSUBMSK&=~(BIT_SUB_TXD0); // Unmask sub int
}
else
{
isTxInt=0;
ClearPending(BIT_UART0); // Clear master pending
rSUBSRCPND=(BIT_SUB_TXD0); // Clear Sub int pending
rINTMSK|=(BIT_UART0);
}
}
void __irq Uart0_RxIntOrErr(void)
{
rINTSUBMSK|=(BIT_SUB_RXD0|BIT_SUB_TXD0|BIT_SUB_ERR0);
if(rSUBSRCPND&BIT_SUB_RXD0) __sub_Uart0_RxInt();
else __sub_Uart0_RxErrInt();
ClearPending(BIT_UART0);
rSUBSRCPND=(BIT_SUB_RXD0|BIT_SUB_ERR0); // Clear Sub int pending
rINTSUBMSK&=~(BIT_SUB_RXD0|BIT_SUB_ERR0);
}
void __sub_Uart0_RxInt(void)
{
if(RdURXH0()!='\r')
{
Uart_Printf("%c",RdURXH0());
*uart0RxStr++ =(char)RdURXH0();
}
else
{
isRxInt=0;
*uart0RxStr='\0';
Uart_Printf("\n");
}
}
void __sub_Uart0_RxErrInt(void)
{
U32 iStatus;
iStatus = rUERSTAT0;
switch(iStatus)//to clear and check the status of register bits
{
case 1:
Uart_Printf("Overrun error!\n");
break;
case 2:
Uart_Printf("Parity error!\n");
break;
case 4:
Uart_Printf("Frame error!\n");
b