/*
 * MICETEK International Inc., (shanghai) 
 * 	By Qinwei , 2003.05.28 (CopyRight)
 * 
 *  Version 0.1
 */
#include <stdio.h>
#include "uart_ev44b0.h"


static unsigned int uart_base;
// static unsigned int SYS_CLK;
static int CurrBaud;
static int delayLoopCount=400;

//init clock
int clock_init()
{
	*((unsigned int *)PLLCON) = 0x48032; //set clock to be 40M
	return 1; 
}

//init port
int port_init(int ch)
{
	if(ch) {                    //if channel 1,init port F group
		rPCONF=0x242aa; 
		//PF0,PF1,PF2,PF3,PF4,PF5,PF6:TXD1,PF7:RXD1,PF8
		rPUPF=0x0;
        } 
   	else {			 //if channel 0,init port E group							
		rPCONE=0x2552b;	 
		//PE0:FOUT, PE1:TxD0, PE2:RxD0, PE3, PE4, PE5,PE6,PE7,PE8: CODECLK  
    		rPUPE=0x0;	
    		rPDATE=0x60;	
	}
	return 1;	
}

//dev_uart_init returns non-negative number on  succuess, 0 on failing.
int dev_uart_init (int sys_clock,  int reg_base, int ch)
{
        int i;
        
        if (reg_base == 0)
                reg_base = 0x01D00000;
        if (sys_clock == 0)
                sys_clock = MCLK;
        if (ch) /* If is channel 1*/
                uart_base = reg_base + 0x4000;
        else
                uart_base = reg_base + 0x0;
	
        *((unsigned int *)(uart_base+ULCON)) =  0x00000003 |0x00000000| 0x00000000 |0x00000000;
        //	WordLength | Parity | StopBit | IRDA_mode, and now 8N1 mode
	
        *((unsigned int *)(uart_base+UBRDIV)) = B115200; // Now set to 115200, and can change later

        // Start channel
        /* Enable the UART in UCON and Unmask the RX interrupt!         */
        *((unsigned int *)(uart_base+UCON))  = (0x4 | 0x1|0x40|0x200) ;
        // Transmit Mode | Receive Mode| Rx error status | Tx interrupt type 
	*((unsigned int *)(uart_base+UFCON)) = 0x0;
	*((unsigned int *)(uart_base+UMCON)) = 0x0;
		
        CurrBaud = 115200;
        for(i=0;i<100;i++);
        
        return 1;
}


//crtio returns the old baud rate on success, 0 on failing.
int crtio (int baud)
{
        int bbaud, ret ;
	
        ret = CurrBaud;
        switch (baud) {
        case 9600:
                bbaud = B9600;		
                CurrBaud  = 9600;
                break;
        case 19200:
                bbaud = B19200;	
                CurrBaud  = 19200;	
                break;
        case 38400:
                bbaud = B38400;	
                CurrBaud  = 38400;	
                break;
        case 57600:
                bbaud = B57600;	
                CurrBaud  = 57600;	
                break;
        case 115200:
                bbaud = B115200;
                CurrBaud  = 115200;
                break;
        default:
                bbaud = B115200;
                CurrBaud  = 115200;
                break;
        }
        *((unsigned int *)(uart_base+UBRDIV)) = bbaud; // Now change the baudrate

        return ret;
}


void Delay(int time)
// time=0: adjust the Delay function by WatchDog timer.
// time>0: the number of loop time
// 100us resolution.
{
    int i,adjust=0;
    if(time==0)
    {
	time=200;
	adjust=1;
	delayLoopCount=400;
	rWTCON=((MCLK/1000000-1)<<8)|(2<<3);  // 1M/64,Watch-dog,nRESET,interrupt disable
	rWTDAT=0xffff;
	rWTCNT=0xffff;	 
	rWTCON=((MCLK/1000000-1)<<8)|(2<<3)|(1<<5); // 1M/64,Watch-dog enable,nRESET,interrupt disable 
    }
    for(;time>0;time--)
	for(i=0;i<delayLoopCount;i++);
    if(adjust==1)
    {
	rWTCON=((MCLK/1000000-1)<<8)|(2<<3);
	i=0xffff-rWTCNT;   //  1count/16us?????????
	delayLoopCount=8000000/(i*64);	//400*100/(i*64/200)   
    }
}
/*
//outbyte returns the written char on success or EOF on failing.
int outbyte (int ch)
{
        volatile unsigned int uart_status;

        while (1) {
                uart_status = (*((unsigned int *)(uart_base+UTRSTAT)) )& 0xf;
                if (uart_status & (TH_empty ))
                        break;
        }

	Delay(10);
        *((unsigned int *)(uart_base+UTXH))  = ch; //Send the char
	
        return ch;
} 
*/
void outbyte(int data)
{
	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(10);
	WrUTXH0(data);
}

//inbyte returns the byte it reads on success or EOF on failing.
int inbyte (void)
{
        unsigned int uart_status = (*((unsigned int *)(uart_base+UTRSTAT)) )& 0xf;
	
        if (uart_status & RDV ) {
                unsigned int ch = (*((unsigned int *)(uart_base+URXH)) )& 0xFF;    /* get the data byte */
                return ch;
        }
	
        return EOF;
}





