#ifndef _UART_H_
#define _UART_H_

/*_____ I N C L U D E S ____________________________________________________*/
#include <SN8F5762.h>

/*_____ D E F I N I T I O N S ______________________________________________*/

///* User configurations */
//#define UART0_RECV_FIFO_LENGTH     8
//#define UART1_RECV_FIFO_LENGTH     8

/*** SN8F5762 UART IO Settings ***/
#define _SET_UART0_RX_INPUT_   	P1M &= ~(0x01U<<4);        
#define _SET_UART0_TX_OUTPUT_ 	P15=1; P1M |= (0x01U<<5); 
#define _SET_UART0_TX_INPUT_ 		P1M &= ~(0x01U<<5); 

#define _SET_UART1_RX_INPUT_   	P1M &= ~(0x01U<<0);        
#define _SET_UART1_TX_OUTPUT_ 	P20=1; P2M |= (0x01U<<0); 
#define _SET_UART1_TX_INPUT_ 		P2M &= ~(0x01U<<0); 


/* UART baud rate selections. */
typedef enum UART_BaudRate{
	eBAUD_RATE_TIMER1,
	eBAUD_RATE_FCPU_DIV12,
	eBAUD_RATE_FCPU_DIV32,
	eBAUD_RATE_FCPU_DIV64,
	eBAUD_RATE_4800,
	eBAUD_RATE_9600,
	eBAUD_RATE_19200,
	eBAUD_RATE_38400,
	eBAUD_RATE_56000,
	eBAUD_RATE_115200,
	eBAUD_RATE_128000,
	eBAUD_RATE_250000,
	eBAUD_RATE_500000,	
} UART_BaudRate;

/* UART baud rate configuration defines. (Fcpu = 16MHz) */
#define BD_4800                     0x03CC	//** Accuracy= 0.16%
#define BD_9600                     0x03E6	//** Accuracy= 0.16%
#define BD_19200                    0x03F3	//** Accuracy= 0.16%
#define BD_38400                    0x03F3	//** Accuracy= 0.16%
#define BD_56000                    0x03F7	//** Accuracy= -0.79% 
#define BD_115200                   0x03FC	//** Accuracy= 8.51% 
#define BD_128000                   0x03FC	//** Accuracy= -2.34% 
#define BD_250000                   0x03FE	//** Accuracy= 0%
#define BD_500000                   0x03FF	//** Accuracy= 0%

#define TBD_9600                     0x30		//** Accuracy= 0.16%
#define TBD_19200                    0x98		//** Accuracy= 0.16%
#define TBD_38400                    0xCC		//** Accuracy= 0.16%
#define TBD_56000                    0xDC	  //** Accuracy= -0.80%	
#define TBD_57600                    0xDD		//** Accuracy= -0.80%		
#define TBD_115200                   0xEF		//** Accuracy= 2.08%
#define TBD_128000                   0xF0		//** Accuracy= -2.40%
#define TBD_250000                   0xF8		//** Accuracy= 0%

/*-----------------------------------
| 87H | PCON Register 						|	 
------------------------- -----------*/		
#define SMOD1					(0x01U<<6)  //** Serial Port 1 baud rate select (baud rate doubler).
#define SMOD0					(0x01U<<5) 	//** Serial Port 0 baud rate select (baud rate doubler)

/*-----------------------------------
| 88H | TCON Register 						|	 
------------------------- -----------*/		
#define mskTF1	            (0x01U<<7)		//** Timer 1 overflow flag.
#define mskTR1						  (0x01U<<6)		//** Timer1 Run control.
#define mskTF0					    (0x01U<<5)		//** Timer 0 overflow flag.
#define mskTR0					    (0x01U<<4)		//** Timer 0 Run control.
#define mskIE1					    (0x01U<<3)		//** External interrupt 1 flag.
#define mskIE0				      (0x01U<<1)		//** External interrupt 0 flag.

/*-----------------------------------
| 89H | TMOD Register 						|	 
------------------------- -----------*/		
#define mskT1GATE					  (0x00U<<7)		//** Timer1 gate control
#define mskT1CT						  (0x01U<<6)		//** T1CT = 0 clock source = Fcpu/12, T1CT = 1 clock source = Fosc/N
#define mskT1_Mode0					(0x00U<<6)		//** T1 Mode0
#define mskT1_Mode1					(0x01U<<4)		//** T1 Mode1
#define mskT1_Mode2					(0x01U<<5)		//** T1 Mode2
#define mskT1_Mode3					(0x03U<<4)		//** T1 Mode3
#define mskT0GATE	          (0x00U<<3)		//** Timer0 gate control
#define mskT0CT						  (0x01U<<2)		//** T0CT = 0 clock source = Fcpu/12, T0CT = 1 clock source = Fosc/N
#define mskT0_Mode0					(0x00U<<0)		//** T0 Mode0
#define mskT0_Mode1					(0x01U<<0)		//** T0 Mode1
#define mskT0_Mode2					(0x01U<<1)		//** T0 Mode2
#define mskT0_Mode3					(0x03U<<0)		//** T0 Mode3

/*-----------------------------------
| 8EH | TCON0 Register 						|	 
------------------------- -----------*/		
#define mskT0EXT					  (0x00U<<7)		//** 0=T0OSC, 1=Flosc
#define mskT0Fhosc_128			(0x00U<<6)		//** T0RATE[6:4] 000 = Fhosc/128
#define mskT0Fhosc_64				(0x01U<<4)		//** T0RATE[6:4] 001 = Fhosc/64
#define mskT0Fhosc_32				(0x01U<<5)		//** T0RATE[6:4] 010 = Fhosc/32
#define mskT0Fhosc_16				(0x03U<<4)		//** T0RATE[6:4] 011 = Fhosc/16
#define mskT0Fhosc_8				(0x01U<<6)		//** T0RATE[6:4] 100 = Fhosc/8
#define mskT0Fhosc_4				(0x05U<<4)		//** T0RATE[6:4] 101 = Fhosc/4
#define mskT0Fhosc_2				(0x06U<<4)		//** T0RATE[6:4] 110 = Fhosc/2
#define mskT0Fhosc_1				(0x07U<<4)		//** T0RATE[6:4] 111 = Fhosc/1

#define mskT1Fhosc_128			(0x00U<<0)		//** T1RATE[2:0] 000 = Fhosc/128
#define mskT1Fhosc_64				(0x01U<<0)		//** T1RATE[2:0] 001 = Fhosc/64
#define mskT1Fhosc_32				(0x02U<<0)		//** T1RATE[2:0] 010 = Fhosc/32
#define mskT1Fhosc_16				(0x03U<<0)		//** T1RATE[2:0] 011 = Fhosc/16
#define mskT1Fhosc_8				(0x04U<<0)		//** T1RATE[2:0] 100 = Fhosc/8
#define mskT1Fhosc_4				(0x05U<<0)		//** T1RATE[2:0] 101 = Fhosc/4
#define mskT1Fhosc_2				(0x06U<<0)		//** T1RATE[2:0] 110 = Fhosc/2
#define mskT1Fhosc_1				(0x07U<<0)		//** T1RATE[2:0] 111 = Fhosc/1

/*-----------------------------------
| 94H | SMODMX Register 						|	 
------------------------- -----------*/		
#define mskUART1						(0x00U<<2)		//** UART0 TX:P15  URAT1 RX:P14
#define mskUART0B						(0x01U<<0)		//** UART1 TX:P04  URAT1 RX:P05
#define mskUART0						(0x00U<<0)		//** UART1 TX:P45  URAT0 RX:P44
#define mskUART1_COMBO_UTX	(0x01U<<3)		//** UART0 TX:P37
#define mskUART1_COMBO_URX	(0x03U<<2)		//** UART0 RX:P37
		


/*-----------------------------------
| 9BH | SOCON2 Register 						|	 
------------------------- -----------*/			
#define BD1						(0x01U<<6)  //** Baud rate generator selection (mode1, 3) (0 : Timer1 overflow period,  1 : Controlled by SnREL)
#define BD0						(0x01U<<5) 	//** Baud rate generator selection (mode1, 3) (0 : Timer1 overflow period,  1 : Controlled by SnREL)
#define TEN1					(0x01U<<1)  //** UART1 TX Enable
#define TEN0					(0x01U<<0)  //** UART0 TX Enable

/*-----------------------------------
/*					UART0										*/
/*-----------------------------------
| 97H | SOCON Register 							|	 
------------------------- -----------*/		
#define mskUART_MODE0	(0x00U<<6)	
#define mskUART_MODE1 (0x01U<<6)
#define mskUART_MODE2 (0x02U<<6)
#define mskUART_MODE3 (0x03U<<6)
#define SM20 					(0x01U<<5)
#define REN0 					(0x01U<<4)	//** UART0 RX Enable
#define TB80 					(0x01U<<3)	
#define RB80 					(0x01U<<2)	
#define TI0 					(0x01U<<1)	//** Transmit interrupt flag
#define RI0 					(0x01U<<0)	//** Receive interrupt flag

/*-----------------------------------
| 99H | S0BUF Register 							|	 
------------------------- -----------*/	
/* Writing data to this register sets data in 
serial output buffer and starts the transmission 
through Serial Port 0. Reading from the S0BUF 
reads data from the serial receive buffer.*/

/*-----------------------------------
| 9AH | S0RELL Register 						|	 
------------------------- -----------*/	
/*-----------------------------------
| 9BH | S0RELH Register 						|	 
------------------------- -----------*/	
/* Serial Port 0 Reload Register is used for Serial Port 0 
baud rate generation . Only 10 bits are used. 8 bits from 
the S0RELL as lower bits and 2 bits from the S0RELH 
(S0RELH.1, S0RELH.0) as higher bits */


/*-----------------------------------
/*					UART1										*/
/*-----------------------------------
| 9CH | S1CON Register 							|	 
------------------------- -----------*/		
#define mskUART_MODE0	(0x00U<<6)	
#define mskUART_MODE1 (0x01U<<6)
#define mskUART_MODE2 (0x02U<<6)
#define mskUART_MODE3 (0x03U<<6)
#define S1M20 				(0x01U<<5)
#define REN1 					(0x01U<<4)	//** UART0 RX Enable
#define TB81 					(0x01U<<3)	
#define RB81 					(0x01U<<2)	
#define TI1 					(0x01U<<1)	//** Transmit interrupt flag
#define RI1 					(0x01U<<0)	//** Receive interrupt flag

/*-----------------------------------
| 9DH | S1BUF Register 							|	 
------------------------- -----------*/	
/* Writing data to this register sets data in 
serial output buffer and starts the transmission 
through Serial Port 1. Reading from the S1BUF 
reads data from the serial receive buffer.*/

/*-----------------------------------
| 9EH | S0RELL Register 						|	 
------------------------- -----------*/	
/*-----------------------------------
| 9FH | S0RELH Register 						|	 
------------------------- -----------*/	
/* Serial Port 1 Reload Register is used for Serial Port 1 
baud rate generation . Only 10 bits are used. 8 bits from 
the S1RELL as lower bits and 2 bits from the S1RELH 
(S1RELH.1, S1RELH.0) as higher bits */


/*_____ M A C R O S ________________________________________________________*/
#define UART0_TX_ISR_EN()           EU0TX = 1
#define UART0_RX_ISR_EN()           EU0RX = 1
#define UART0_TX_ISR_DIS()          EU0TX = 0
#define UART0_RX_ISR_DIS()          EU0RX = 0

#define UART1_TX_ISR_EN()           EU1TX = 1
#define UART1_RX_ISR_EN()           EU1RX = 1
#define UART1_TX_ISR_DIS()          EU1TX = 0
#define UART1_RX_ISR_DIS()          EU1RX = 0

/*_____ D E C L A R A T I O N S ____________________________________________*/
typedef struct{
	uint8_t*	bptrRx_StartAdress;
	uint8_t*	bptrRx_EndAdress;	
	uint8_t*	bptrRx_Buf;	
  uint8_t 	fRx_Done:1;	
}UART_Hardware_st;

extern UART_Hardware_st stUART0_Hardware;
extern UART_Hardware_st stUART1_Hardware;

/*_____ F U N C T I O N S __________________________________________________*/
extern void UART0_Init(uint8_t bUartBaudRate, uint8_t* bRxBufAddress, uint8_t bLength);
extern void UART0_TransmitData(uint8_t*, uint8_t);
extern bit 	UART0_ReceivedDone(void);

extern void UART1_Init(uint8_t bUartBaudRate, uint8_t* bRxBufAddress, uint8_t bLength);
extern void UART1_TransmitData(uint8_t*, uint8_t);
extern bit 	UART1_ReceivedDone(void);

#endif