#ifndef _UART_H_
#define _UART_H_

/*_____ I N C L U D E S ____________________________________________________*/
#include <SN8F5754.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

/*** SN8F5754 UART IO Settings ***/
#define _SET_COMBOUART_INPUT_   {P1M &= ~(0x01U<<2); P1UR |= (0x01U<<2);}      /*!< Set P12 to input mode. */
#define _SET_COMBOUART_OUTPUT_  {P12=1; P1M |= (0x01U<<2); P1UR &= ~(0x01U<<2);} 

#define _SET_UART0_RX_INPUT_   	P0M &= ~(0x01U<<2);        
#define _SET_UART0_TX_OUTPUT_ 	P03=1; P0M |= (0x01U<<3); 
#define _SET_UART0_TX_INPUT_ 		P0M &= ~(0x01U<<3); 

#define _SET_UART1_RX_INPUT_   	P3M &= ~(0x01U<<3);        
#define _SET_UART1_TX_OUTPUT_ 	P32=1; P3M |= (0x01U<<2); 
#define _SET_UART1_TX_INPUT_ 		P3M &= ~(0x01U<<2); 

#define _SET_UART1B_RX_INPUT_   P2M &= ~(0x01U<<1);       
#define _SET_UART1B_TX_OUTPUT_  P20=1; P2M |= (0x01U<<0);
#define _SET_UART1B_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,
} UART_BaudRate;

/* UART baud rate configuration defines. (Fcpu = 8MHz) */
#define BD_4800                     0x03E6	//** Accuracy= 0.16%
#define BD_9600                     0x03F3	//** Accuracy= 0.16%
#define BD_19200                    0x03F3	//** Accuracy= 0.16%
#define BD_38400                    0x03F9	//** Accuracy= -6.99% 
#define BD_56000                    0x03FB	//** Accuracy= -10.71% 
#define BD_115200                   0x03FE	//** Accuracy= -8.51% 
#define BD_128000                   0x03FE	//** Accuracy= -8.51%
#define BD_250000                   0x03FF	//** Accuracy= 0%

/*-----------------------------------
| 94H | SMODMX Register 						|	 
------------------------- -----------*/		
#define mskUART1						(0x00U<<2)		//** UART1 TX:P32  URAT1 RX:P33
#define mskUART1B						(0x01U<<2)		//** UART1 TX:P20  URAT1 RX:P21
#define mskUART0						(0x00U<<0)		//** UART0 TX:P03  URAT0 RX:P02
#define mskUART0_COMBO_UTX	(0x02U<<0)		//** UART0 TX:P12
#define mskUART0_COMBO_URX	(0x03U<<0)		//** UART0 RX:P12

/*-----------------------------------
| 95H | SMODCAL 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).

/*-----------------------------------
| 96H | 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