#include "com_port.h"

#if UART_MODE == Soft_uart
volatile unsigned char	USART_BUF @0x20;
volatile bit D0			@ ((unsigned)&USART_BUF*8)+0;
volatile bit D1			@ ((unsigned)&USART_BUF*8)+1;
volatile bit D2			@ ((unsigned)&USART_BUF*8)+2;
volatile bit D3			@ ((unsigned)&USART_BUF*8)+3;
volatile bit D4			@ ((unsigned)&USART_BUF*8)+4;
volatile bit D5			@ ((unsigned)&USART_BUF*8)+5;
volatile bit D6			@ ((unsigned)&USART_BUF*8)+6;
volatile bit D7			@ ((unsigned)&USART_BUF*8)+7;
#endif

volatile unsigned char UART_Read_FLAG = 0;
volatile unsigned char RcvDat[20];

void usart_init(void)
{
#if UART_MODE == Hard_uart
	//TX_PAx_RX_PAx@9600
	UART0CLKEN = 1;
    TX0_MAP    = MAP_PB0;
	TRISB0     = 0;
	UARTCON    = 0x00;
	SPBRG      = 0x1A;
	RCSTA      = 0x90;
	TXSTA      = 0x20;
#elif UART_MODE == Soft_uart
	TX_DIR     = 0;
	TX_PIN     = 1;

	RX_DIR     = 1;
#endif
}

void putch(unsigned char tmp)
{
#if UART_MODE == Hard_uart
	while(!TXIF)continue;
	TXREG = tmp;
#elif UART_MODE == Soft_uart
	USART_BUF = tmp;
	unsigned char i=0;
	TX_PIN = 1;
	TX_PIN = 0;
	__delay_us(104);
	for(i=0;i<8;i++)
	{
		TX_PIN=tmp&0X01;
		__delay_us(100);
		tmp=tmp>>1;
	}
	TX_PIN = 1;
	__delay_us(104);
	__delay_us(104);
#endif
}

unsigned char getch(void)
{
    unsigned short Time_out = 35000;

#if UART_MODE == Hard_uart
	while(!RCIF)
	{
		Time_out--;
	    if(Time_out == 0)return 0;
	}
	RCIF = 1;
	return RCREG;
#elif UART_MODE == Soft_uart
	unsigned char  tmp      = 0;
    while(RX_PIN ==1 )
	{
       Time_out--;
	   if(Time_out == 0)return 0;
	}

	__delay_us(104);
	__delay_us(52);
	if (RX_PIN==1)
		tmp = tmp | 0x01;
	__delay_us(104);

	if (RX_PIN==1)
		tmp = tmp | 0x02;
	__delay_us(104);

	if (RX_PIN==1)
		tmp = tmp | 0x04;
	__delay_us(104);

	if (RX_PIN==1)
		tmp = tmp | 0x08;
	__delay_us(104);

	if (RX_PIN==1)
		tmp = tmp | 0x10;
	__delay_us(104);

	if (RX_PIN==1)
		tmp = tmp | 0x20;
	__delay_us(104);

	if (RX_PIN==1)
		tmp = tmp | 0x40;
	__delay_us(104);

	if (RX_PIN==1)
		tmp = tmp | 0x80;
	__delay_us(104);

	if (RX_PIN==1)
		return tmp;
	else
		return 0;
#endif
}

void Tx_Rx_Init(unsigned char UaRt_MoDe)
{
	switch(UaRt_MoDe)
	{
	    case Tx_Init:
	    {
	        Tx_RX_r_Pin_TRIS = 0;
			Tx_RX_r_Pin_PUPD = 0;
			Tx_RX_t_Pin      = 0;
	    }break;
	    case Rx_Init:
	    {
	        Tx_RX_r_Pin_TRIS = 1;
	    }break;
	    default:
		{
			Tx_RX_r_Pin_TRIS = 1;
		}break;
	}
}

unsigned char get_dat()
{
    unsigned char Temp       = 0;
    unsigned char i          = 0;
    unsigned char HIGH_LEVEL = 0;
    unsigned char LOW_LEVEL  = 0;
    unsigned int  Time_out   = 0;

    Tx_Rx_Init(Rx_Init);

    if(Tx_RX_r_Pin == 0)
	{
	    Time_out = 0;
		while(Tx_RX_r_Pin == 0)
		{
			Time_out ++;
			if(Time_out > 2500){return 0;}
        }

		for(i = 0;i < 8;i++)
		{
		    Temp = Temp << 1;
			Time_out = 0;while(Tx_RX_r_Pin != 0){Time_out ++;if(Time_out > 2500){return 0;}}HIGH_LEVEL = Time_out;
			Time_out = 0;while(Tx_RX_r_Pin != 1){Time_out ++;if(Time_out > 2500){return 0;}}LOW_LEVEL  = Time_out;
			if(HIGH_LEVEL < LOW_LEVEL)Temp |= 0x01;
		}
		return Temp;
	}else Time_out = 0;
	return 0;
}

void Send_ch(unsigned char Temp)
{
    unsigned char i = 0;

    Tx_Rx_Init(Tx_Init);

	__delay_us(1000);
	Tx_RX_t_Pin = 1;
	for(i = 0;i < 8;i++)
	{
	   if(Temp & 0x80)
	   {
	       Tx_RX_t_Pin = 1;
		   __delay_us(100);
		   Tx_RX_t_Pin = 0;
		   __delay_us(400);
	   }else {
	       Tx_RX_t_Pin = 1;
		   __delay_us(400);
		   Tx_RX_t_Pin = 0;
		   __delay_us(100);
	   }
	   Temp = Temp << 1;
	}
	Tx_RX_t_Pin = 1;
	__delay_us(5000);
	Tx_Rx_Init(Rx_Init);
}

void Send_Data_Temp(unsigned char Dat_Tmp)
{
	unsigned char  radix_minus_one1 = ((~(Dat_Tmp & 0x0F)) & 0x0F);
	unsigned char  radix_minus_one2 = ((~((Dat_Tmp & 0xF0) >> 4)) & 0x0F);
	unsigned char  Send_Data_4B1 = ((Dat_Tmp & 0x0F) << 4);
	unsigned char  Send_Data_4B2 = (Dat_Tmp & 0xF0);
	unsigned char  Send_Dat1 = Send_Data_4B1 | radix_minus_one1;
	unsigned char  Send_Dat2 = Send_Data_4B2 | radix_minus_one2;

	Send_ch(Send_Dat1);
	Send_ch(Send_Dat2);
}

void Send_CMD(unsigned char Addr,unsigned char Dat)
{
	Send_Data_Temp(0xAA);
	Send_Data_Temp(IC_ID);
	Send_Data_Temp(0x03);
	Send_Data_Temp(Addr);
	Send_Data_Temp(Dat);
	Send_Data_Temp(0xBB);
	Send_Data_Temp(0xCC);
}

