/*******************************************************************************
 *
 * Copyright (C) 2005, FREESCALE INC.   All Rights Reserved
 *
 *  FILE NAME    : MX31_UART_config.c
 *  DATE CREATED : 7/3/2001
 *
 *  DESCRIPTION:
 *  This module contains code initializing and configuring the
 *  internal UART on the MX31 - converted from the DBMX1 code.
 *
 *  REVISION HISTORY:
 *  Release 0.1 - initial release
 *	Release 0.2 - changed and updated for DBMX1 (i.e. interrupt enable bits)
 *	Release 0.3 - changed and updated for MX31 
 *
 *******************************************************************************/

// include files
#include <stdio.h> // to allow printing to a console window e.g. printf("text %d", int);
#include "MX31_uart_config.h"
//#include "DBMX1_AITC.h"
#include "common.h"
#include "tortola_memory_map_defines.h"

// define
//static int gBIR[16] = {BIR_300,BIR_600,BIR_1200,BIR_2400,BIR_4800,BIR_9600,BIR_14400,BIR_19200,BIR_28800,BIR_38400,BIR_57600,BIR_115200,BIR_230400,BIR_460800,BIR_812500,BIR_920000};
//static int gBMR[16] = {BMR_300,BMR_600,BMR_1200,BMR_2400,BMR_4800,BMR_9600,BMR_14400,BMR_19200,BMR_28800,BMR_38400,BMR_57600,BMR_115200,BMR_230400,BMR_460800,BMR_812500,BMR_920000};

uint32_t GetUARTbaseOffset (int uartPort)
{
	uint32_t offset;
	// define address offsets for UART registers from UART1 base address
	if (uartPort == 1)
	{
		offset = 0;
		return (offset);
	}		
	else if (uartPort == 2)
	{
		offset = 0x4000;
		return (offset);		
	}		
	else if (uartPort == 3)
	{
		offset = 0x0C07C000;
		return (offset);		
	}
	else if (uartPort == 4)
	{
		offset = 0x00020000;
		return (offset);		
	}
	else if (uartPort == 5)
	{
		offset = 0x00024000;
		return (offset);		
	}
	
	return(0);
	
}

// InitInternalUART
void InitInternalUART (int uartPort, int ignoreRTS, int wordSize, int parityType, int stopBits)
{
	uint32_t offset;
	offset = GetUARTbaseOffset(uartPort);
	
	*(p_uint32_t)(UART1_UCR2_1 + offset) = 0x2006;			// UCR2 = CTSC,TXEN,RXEN=1,reset
	*(p_uint32_t)(UART1_UCR1_1 + offset) = 0x0001; 			// UARTEN = 1,enable the clock
	*(p_uint32_t)(UART1_UCR2_1 + offset) |= ignoreRTS<<14;	// configure IRTS bit
	*(p_uint32_t)(UART1_UCR2_1 + offset) |= wordSize<<5;
	*(p_uint32_t)(UART1_UCR2_1 + offset) |= stopBits<<6;
	*(p_uint32_t)(UART1_UCR3_1 + offset) |= 0x00000004;		// set RXD_MUX_SEL bit
	
	if (parityType == EVEN)
	{
		// enable parity, set PREN bit 8
		*(p_uint32_t)(UART1_UCR2_1 + offset) |= 1<<8; 
		// even parity, clear PROE bit 7
		*(p_uint32_t)(UART1_UCR2_1 + offset) &= ~(0x00000080);
	}
	else if (parityType == ODD)
	{
		// enable parity, set PREN bit 8
		*(p_uint32_t)(UART1_UCR2_1 + offset) |= 1<<8; 
		// odd parity, set PROE bit 7
		*(p_uint32_t)(UART1_UCR2_1 + offset) |= 1<<7;
	}
	else
	{
		// disable parity
		*(p_uint32_t)(UART1_UCR2_1 + offset) &= ~(0x00000100);			
	}
	
}

/*----------------------------------------------------------------------------*\
   Setting the baud rate to one of the specific values
   NOTE:
    The values in this file are dependent on the clock rates for Tortola, and
    are based on the assumption that ipg_perclk is set to 66MHz (15.15 ns)
    and the RFDIV setting in UFCR is 5 (divide by 1).
   FORMULA: (UBMR + 1) / (UBIR + 1) = ipg_perclk / (baudrate * 16)           
\*----------------------------------------------------------------------------*/

void SetRFDIV_to_div_by_1(int uartPort)
{
	int tmp, offset;
	offset = GetUARTbaseOffset(uartPort);
	
	tmp = *(p_uint32_t)(UART1_UFCR_1 + offset);	// save UFCR to default value
	*(p_uint32_t)(UART1_UFCR_1 + offset) = 5<<7;   // set RFDIV to div-by-1 or b101 
	*(p_uint32_t)(UART1_UFCR_1 + offset) |= tmp;	// set other UFCR bits back to default			
}

void BAUDRATE_920Kbps(int uartPort)
{
	int offset;
	offset = GetUARTbaseOffset(uartPort);
	SetRFDIV_to_div_by_1(uartPort);
	
	*(p_uint32_t)(UART1_UBIR_1 + offset) = 0x11fb;
	*(p_uint32_t)(UART1_UBMR_1 + offset) = 0x50a4;
}


void BAUDRATE_812_5Kbps( int uartPort )
{
	int offset;
	offset = GetUARTbaseOffset(uartPort);
	SetRFDIV_to_div_by_1(uartPort);
	
	*(p_uint32_t)(UART1_UBIR_1 + offset) = 0x08e0;
	*(p_uint32_t)(UART1_UBMR_1 + offset) = 0x2d14;
}

void BAUDRATE_460Kbps( int uartPort )
{
	int offset;
	offset = GetUARTbaseOffset(uartPort);
	SetRFDIV_to_div_by_1(uartPort);
	
	*(p_uint32_t)(UART1_UBIR_1 + offset) = 0x08fd;
	*(p_uint32_t)(UART1_UBMR_1 + offset) = 0x50a4;
}

void BAUDRATE_230Kbps( int uartPort )
{
	int offset;
	offset = GetUARTbaseOffset(uartPort);
	SetRFDIV_to_div_by_1(uartPort);
	
	*(p_uint32_t)(UART1_UBIR_1 + offset) = 0x047e;
	*(p_uint32_t)(UART1_UBMR_1 + offset) = 0x50a4;
}

void BAUDRATE_115_2Kbps( int uartPort ) // 115.2 Kbps @ 66 MHz
{
	int offset;
	offset = GetUARTbaseOffset(uartPort);
	SetRFDIV_to_div_by_1(uartPort);
	
	*(p_uint32_t)(UART1_UBIR_1 + offset) = 0x01a6;
	*(p_uint32_t)(UART1_UBMR_1 + offset) = 0x3b2b;
}

void BAUDRATE_57_6Kbps( int uartPort ) // 57.6 Kbps @ 66 MHz
{
	int offset;
	offset = GetUARTbaseOffset(uartPort);
	SetRFDIV_to_div_by_1(uartPort);
	
	*(p_uint32_t)(UART1_UBIR_1 + offset) = 0x047e;
	*(p_uint32_t)(UART1_UBMR_1 + offset) = 0x50a4;
}

void BAUDRATE_28_8Kbps( int uartPort ) // 28.8 Kbps @ 66 MHz
{
	int offset;
	offset = GetUARTbaseOffset(uartPort);
	SetRFDIV_to_div_by_1(uartPort);
	
	*(p_uint32_t)(UART1_UBIR_1 + offset) = 0x0133;
	*(p_uint32_t)(UART1_UBMR_1 + offset) = 0xac56;
}

void BAUDRATE_19_2Kbps( int uartPort ) // 19.2 Kbps @ 66 MHz
{
	int offset;
	offset = GetUARTbaseOffset(uartPort);
	SetRFDIV_to_div_by_1(uartPort);
	
	*(p_uint32_t)(UART1_UBIR_1 + offset) = 0x8c;
	*(p_uint32_t)(UART1_UBMR_1 + offset) = 0x7657;
}

void BAUDRATE_14_4Kbps( int uartPort ) // 14.4 Kbps @ 66 MHz
{
	int offset;
	offset = GetUARTbaseOffset(uartPort);
	SetRFDIV_to_div_by_1(uartPort);
	
	*(p_uint32_t)(UART1_UBIR_1 + offset) = 0x99;
	*(p_uint32_t)(UART1_UBMR_1 + offset) = 0xac56;
}

void BAUDRATE_9600bps( int uartPort ) // 9600 bps @ 66 MHz
{
	int offset;
	offset = GetUARTbaseOffset(uartPort);
	SetRFDIV_to_div_by_1(uartPort);
	
	*(p_uint32_t)(UART1_UBIR_1 + offset) = 0x72;
	*(p_uint32_t)(UART1_UBMR_1 + offset) = 0xc10a;
}

void BAUDRATE_4800bps( int uartPort ) // 4800 bps @ 66 MHz
{
	int offset;
	offset = GetUARTbaseOffset(uartPort);
	SetRFDIV_to_div_by_1(uartPort);
	
	*(p_uint32_t)(UART1_UBIR_1 + offset) = 0xc;
	*(p_uint32_t)(UART1_UBMR_1 + offset) = 0x2ba4;
}

void BAUDRATE_2400bps( int uartPort ) // 2400 bps @ 66 MHz
{
	int offset;
	offset = GetUARTbaseOffset(uartPort);
	SetRFDIV_to_div_by_1(uartPort);
	
	*(p_uint32_t)(UART1_UBIR_1 + offset) = 0xc;
	*(p_uint32_t)(UART1_UBMR_1 + offset) = 0x5749;
}

void BAUDRATE_1200bps( int uartPort ) // 1200 bps @ 66 MHz
{
	int offset;
	offset = GetUARTbaseOffset(uartPort);
	SetRFDIV_to_div_by_1(uartPort);
	
	*(p_uint32_t)(UART1_UBIR_1 + offset) = 0x038c;
	*(p_uint32_t)(UART1_UBMR_1 + offset) = 0x0c34;
}

void BAUDRATE_600bps( int uartPort ) // 600 bps @ 66 MHz
{
	int offset;
	offset = GetUARTbaseOffset(uartPort);
	SetRFDIV_to_div_by_1(uartPort);
	
	*(p_uint32_t)(UART1_UBIR_1 + offset) = 0x02;
	*(p_uint32_t)(UART1_UBMR_1 + offset) = 0x5092;
}

void uart_setup_ccm(void)
{
//f 0
   uint32_t upctl, ccmr, pdr0;

   // Configure CCM to generate 240MHz USB clock by setting USB PLL Control Register UPCTL
   // Fref (PLL reference clock) = 32kHz * 1024
   // PD = 4     -> PD-field = 3
   // MFD = 1024 -> MFD-field = 1023
   // MFI = 14   -> MFI-field = 14
   // MFN = 664  -> MFN-field = 664
   // MFN/MFD = 0.64844 -> BRM-bit = 0
   upctl = 0x0000 | (0 << 31)    // BRM bit
                  | (3 << 26)    // PD field
                  | (1023 << 16) // MFD field
                  | (14   << 10) // MFI field
                  | 664;         // MFN field


   // Configure UART Baud clock: select USB clock as basis for UART Baud clock
   // UPE = 1 (USB PLL enabled - default)
   // PERCS = 0 (USB clock used as source for ipg_per_clk)
   // FPMF = 1 (pre-multiplier = 1024
   ccmr = 	*(p_uint32_t)(CCM_CCMR);
   ccmr = ccmr & 0xfeffffff;

   // CCM.PDR0: Divide USB clock by 8 to get 30MHz baud clock
   // PER_PODF = 8 -> PER_PODF-field = 7
   pdr0 = 	*(p_uint32_t)(CCM_PDR0);
   pdr0 = pdr0 & (7 << 16);

	*(p_uint32_t)(CCM_UPCTL) = upctl;
   	*(p_uint32_t)(CCM_CCMR) = ccmr;
   	*(p_uint32_t)(CCM_PDR0) = pdr0;
}


// IsCharReady
int IsCharReady (int uartPort)
{
	int tmp, offset;
	offset = GetUARTbaseOffset(uartPort);
	// look for the RDR bit to set in USR2
	tmp = ((*(p_uint32_t)(UART1_USR2_1 + offset)) & 0x00000001);
	return (tmp);

}

// IsRxFifoReady
int IsRxFifoReady (int uartPort)
{
	uint32_t offset;
	offset = GetUARTbaseOffset(uartPort);
	// look for the RRDY bit to set (USR1), will set when RX FIFO hits threshold limit
	return ((*(p_uint32_t)(UART1_USR1_1 + offset)) & 0x00000200);	
}

// MODIFY THESE LATER FOR MX31
/*
// IsTxFifoReady
int IsTxFifoReady (int uartPort)
{
	if (uartPort == UARTA) return (USR1_1.bits.TRDY);
	else return (USR1_2.bits.TRDY);
}

*/
// IsTxFifoEmpty
int IsTxFifoEmpty (int uartPort)
{
	uint32_t tmp, offset;
	offset = GetUARTbaseOffset(uartPort);
	
	tmp = ((*(p_uint32_t)(UART1_USR2_1 + offset)) & 0x00004000);	
	return (tmp);
}


// IsTxComplete
int IsTxComplete (int uartPort)
{
	uint32_t tmp, offset;
	offset = GetUARTbaseOffset(uartPort);
	
	tmp = ((*(p_uint32_t)(UART1_USR2_1 + offset)) & 0x00000008);
	return (tmp);	
}

/*
// IsTxFifoFull
int IsTxFifoFull (int uartPort)
{
	if (uartPort == UARTA) return (UTS_1.bits.TXFULL);
	else return (UTS_2.bits.TXFULL);
}


*/

// GetCharFromFIFO
unsigned char GetCharFromFIFO (int uartPort)
{
	uint32_t offset;
	offset = GetUARTbaseOffset(uartPort);
	
	return ((*(p_uint32_t)(UART1_URXD_1 +offset)) & 0xFF);

}


// GetCharWithFlagsFromFIFO
unsigned short GetCharWithFlagsFromFIFO (int uartPort)
{
	uint32_t offset;
	offset = GetUARTbaseOffset(uartPort);
	
	return (*(p_uint32_t)(UART1_URXD_1 + offset));
}


// PutCharInFIFO
void PutCharInFIFO (int uartPort, unsigned char c)
{
	uint32_t offset;
	offset = GetUARTbaseOffset(uartPort);
	
	*(p_uint32_t)(UART1_UTXD_1 + offset) = c;
}


// SetRxFifoLevel
void SetRxFifoLevel (int uartPort, int level)
{
	uint32_t offset;
	offset = GetUARTbaseOffset(uartPort);
		
	*(p_uint32_t)(UART1_UFCR_1 + offset) &= ~(0x0000003F);
	*(p_uint32_t)(UART1_UFCR_1 + offset) |= level;	
}

// MODIFY LATER FOR MX31
#ifdef DEBUGMX31

// SetTxFifoLevel
void SetTxFifoLevel (int uartPort, int level)
{
	if (uartPort == UARTA) UFCR_1.bits.TXTL = level;
	else UFCR_2.bits.TXTL = level;
}


// SetCTSlevel
void SetCTSlevel (int uartPort, int level)
{
	if (uartPort == UARTA) UCR4_1.bits.CTSTL = level;
	else UCR4_2.bits.CTSTL = level;
}


// SendBreak
void SendBreak (int uartPort)
{
	if (uartPort == UARTA) UCR1_1.bits.SNDBRK = 1;
	else UCR1_2.bits.SNDBRK = 1;
}


// ClearBreak
void ClearBreak (int uartPort)
{
	if (uartPort == UARTA) UCR1_1.bits.SNDBRK = 0;
	else UCR1_2.bits.SNDBRK = 0;
}


// EnableTxReadyInterrupts
void EnableTxReadyInterrupts (int uartPort)
{
	if (uartPort == UARTA) UCR1_1.bits.TRDYEN = 1;
	else UCR1_2.bits.TRDYEN = 1;
}


// DisableTxReadyInterrupts
void DisableTxReadyInterrupts (int uartPort)
{
	if (uartPort == UARTA) UCR1_1.bits.TRDYEN = 0;
	else UCR1_2.bits.TRDYEN = 0;
}




// ConfigureReceiveInterrupts
void ConfigureReceiveInterrupts (int uartPort, int sourceEn, int rxReadyEn, int idleEn, int rxDataReadyEn, int rxStatusEn)
{
	// clear idle status
	ClearIdleStatus (uartPort);
	
	if (uartPort == UARTA) 
	{
		if (sourceEn == 1)
		{
			INTENABLEL   |= 0x40000000;
		}
		else
		{
			INTENABLEL   &= 0xBFFFFFFF;
		}


		UCR1_1.bits.RRDYEN = rxReadyEn;
		UCR1_1.bits.IDEN = idleEn;
		UCR4_1.bits.DREN = rxDataReadyEn;
		UCR3_1.bits.RXDSEN = rxStatusEn;
	}
	else 
	{
		if (sourceEn == 1)
		{
			INTENABLEL   |= 0x01000000;  //Enable interrupt source bit 24
		}
		else
		{
			INTENABLEL   &= 0xFEFFFFFF;
		}


		UCR1_2.bits.RRDYEN = rxReadyEn;
		UCR1_2.bits.IDEN = idleEn;
		UCR4_2.bits.DREN = rxDataReadyEn;
		UCR3_2.bits.RXDSEN = rxStatusEn;
	}

}


// ConfigureTransmitInterrupts
void ConfigureTransmitInterrupts (int uartPort, int sourceEn, int txEmptyEn, int txReadyEn, int txCompleteEn)
{
	if (uartPort == UARTA) 
	{ 

		if (sourceEn == 1)
		{
			INTENABLEL   |= 0x20000000;
		}
		else
		{
			INTENABLEL   &= 0xDFFFFFFF;
		}

		UCR1_1.bits.TXMPTYEN = txEmptyEn;
		UCR1_1.bits.TRDYEN = txReadyEn;
		UCR4_1.bits.TCEN = txCompleteEn;
	}
	
	else 
	{
		if (sourceEn == 1)
		{
			INTENABLEL   |= 0x00800000;
		}
		else
		{
			INTENABLEL   &= 0xFF7FFFFF;
		}
		
		UCR1_2.bits.TXMPTYEN = txEmptyEn;
		UCR1_2.bits.TRDYEN = txReadyEn;
		UCR4_2.bits.TCEN = txCompleteEn;
	}
}


// ConfigureRTSInterrupts
void ConfigureRTSInterrupts (int uartPort, int sourceEn, int rtsDeltaEn, int rtsEn, int edgeCtrl)
{
	// clear RTS status bits
	ClearRTSstatus (uartPort);
	
	if (uartPort == UARTA) 
	{ 

		if (sourceEn == 1)
		{
		INTENABLEL   |= 0x04000000;
		}
		else 
		{
		INTENABLEL   &= 0xFBFFFFFF;
		}
		
		UCR2_1.bits.RTEC = edgeCtrl;
		UCR1_1.bits.RTSDEN = rtsDeltaEn;
		UCR2_1.bits.RTSEN = rtsEn;
	}
	else 
	{

		if (sourceEn == 1)
		{
		INTENABLEL   |= 0x00100000;
		}
		else 
		{
		INTENABLEL   &= 0xFFEFFFFF;
		}
		
		UCR2_2.bits.RTEC = edgeCtrl;
		UCR1_2.bits.RTSDEN = rtsDeltaEn;
		UCR2_2.bits.RTSEN = rtsEn;
	}
}



// ConfigureDTRInterrupts
void ConfigureDTRInterrupts (int uartPort, int sourceEn, int dtrEn, int edgeCtrl)
{
	// clear DTR status bit
	ClearDTRstatus (uartPort);
	
	if (uartPort == UARTA) 
	{
	
		if (sourceEn == 1)
		{
			INTENABLEL |= 0x08000000;
		}
		else
		{
			INTENABLEL &= 0xF7FFFFFF;
		}
	
		UCR3_1.bits.DPEC = edgeCtrl;
		UCR3_1.bits.DTREN = dtrEn;
	}
	else 
	{
	
		if (sourceEn == 1)
		{
			INTENABLEL |= 0x00200000;
		}
		else
		{
			INTENABLEL &= 0xFFDFFFFF;
		}
	

		UCR3_2.bits.DPEC = edgeCtrl;
		UCR3_2.bits.DTREN = dtrEn;
	}
}


// ConfigureCommonInterrupts
void ConfigureCommonInterrupts (int uartPort, int sourceEn, int overRunEn, int breakEn, int wakeEn, int autoBaudEn, int escEn, int irdaEn, int asyncIrEn, int asyncWakeEn)
{
	if (uartPort == UARTA) 
	{ 
		
		if (sourceEn == 1)
		{
			INTENABLEL   |= 0x10000000;
		}
		else
		{
			INTENABLEL   &= 0xEFFFFFFF;
		}
		UCR4_1.bits.OREN = overRunEn;
		UCR4_1.bits.BKEN = breakEn;
		UCR4_1.bits.WKEN = wakeEn;
		UCR1_1.bits.ADEN = autoBaudEn;
		UCR2_1.bits.ESCI = escEn;
		UCR4_1.bits.ENIRI = irdaEn;
		UCR3_1.bits.AIRINTEN = asyncIrEn;
		UCR3_1.bits.AWAKEN = asyncWakeEn;
	}
	else 
	{
		if (sourceEn == 1)
		{
			INTENABLEL |= 0x00400000;
		}
		else
		{
			INTENABLEL   &= 0xFFBFFFFF;
		}

		UCR4_2.bits.OREN = overRunEn;
		UCR4_2.bits.BKEN = breakEn;
		UCR4_2.bits.WKEN = wakeEn;
		UCR1_2.bits.ADEN = autoBaudEn;
		UCR2_2.bits.ESCI = escEn;
		UCR4_2.bits.ENIRI = irdaEn;
		UCR3_2.bits.AIRINTEN = asyncIrEn;
		UCR3_2.bits.AWAKEN = asyncWakeEn;
	}
}

// EnableRxReadyInterrupts
void EnableRxReadyInterrupts (int uartPort)
{
	if (uartPort == UARTA) UCR1_1.bits.RRDYEN = 1;
	else UCR1_2.bits.RRDYEN = 1;
}

void DisableRxReadyInterrupts (int uartPort)
{
	if (uartPort == UARTA) UCR1_1.bits.RRDYEN = 0;
	else UCR1_2.bits.RRDYEN = 0;
}

void EnableAutoBaudDetection (int uartPort)
{
	if (uartPort == UARTA)
	{
		// enable autobaud detection
		UCR1_1.bits.ADBR = 1;
		
		// clear ADET status bit
		ClearAutoBaudStatus (uartPort);
	}
	else 
	{
		// enable autobaud detection
		UCR1_2.bits.ADBR = 1;
		
		// clear ADET status bit
		ClearAutoBaudStatus (uartPort);
	}
}


// DisableAutoBaudDetection
void DisableAutoBaudDetection (int uartPort)
{
	if (uartPort == UARTA)
	{
		UCR1_1.bits.ADBR = 0;
	}
	else 
	{
		UCR1_2.bits.ADBR = 0;
	}
}


// GetAutoBaudStatus
int GetAutoBaudStatus (int uartPort)
{
	if (uartPort == UARTA)
	{
		return USR2_1.bits.ADET;
	}
	else 
	{
		return USR2_2.bits.ADET;
	}
}


// ClearAutoBaudStatus
void ClearAutoBaudStatus (int uartPort)
{
	if (uartPort == UARTA) 
	{
		// write 1 to clear ADET flag
//		USR2_1.all &= USR2_ADET;
		USR2_1.all |= USR2_ADET;
	}
	else
	{
		/* write 1 to clear ADET flag */
//		USR2_2.all &= USR2_ADET;
		USR2_2.all |= USR2_ADET;
	}
}


// EnableIrDA
void EnableIrDA (int uartPort)
{
	if (uartPort == UARTA) UCR1_1.bits.IREN = 1;
	else UCR1_2.bits.IREN = 1;
}


// DisableIrDA
void DisableIrDA (int uartPort)
{
	if (uartPort == UARTA) UCR1_1.bits.IREN = 0;
	else UCR1_2.bits.IREN = 0;
}


// EnableDozeMode
void EnableDozeMode (int uartPort)
{
	if (uartPort == UARTA) UCR1_1.bits.DOZE = 1;
	else UCR1_2.bits.DOZE = 1;
}


// DisableDozeMode
void DisableDozeMode (int uartPort)
{
	if (uartPort == UARTA) UCR1_1.bits.DOZE = 0;
	else UCR1_2.bits.DOZE = 0;
}


// IsReceiverIdle
int IsReceiverIdle (int uartPort)
{
	if (uartPort == UARTA) return USR1_1.bits.RXDS;
	else return USR1_2.bits.RXDS;
}


// ForceCTSlow
void ForceCTSlow (int uartPort)
{
	if (uartPort == UARTA) 
	{
		UCR2_1.bits.CTSC = 0;
		UCR2_1.bits.CTS = 1;
	}
	else
	{
		UCR2_2.bits.CTSC = 0;
		UCR2_2.bits.CTS = 1;
	}
}


// ForceCTShigh
void ForceCTShigh (int uartPort)
{
	if (uartPort == UARTA) 
	{
		UCR2_1.bits.CTSC = 0;
		UCR2_1.bits.CTS = 0;
	}
	else
	{
		UCR2_2.bits.CTSC = 0;
		UCR2_2.bits.CTS = 0;
	}
}


// ClearWakeStatus
void ClearWakeStatus (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// clear wake status bits
//		USR2_1.all &= USR2_WAKE;
//		USR1_1.all &= USR1_AIRINT;
//		USR1_1.all &= USR1_AWAKE;
		USR2_1.all |= USR2_WAKE;
		USR1_1.all |= USR1_AIRINT;
		USR1_1.all |= USR1_AWAKE;

	}
	else 
	{
		// clear wake status bits
//		USR2_2.all &= USR2_WAKE;
//		USR1_2.all &= USR1_AIRINT;
//		USR1_2.all &= USR1_AWAKE;
		USR2_2.all |= USR2_WAKE;
		USR1_2.all |= USR1_AIRINT;
		USR1_2.all |= USR1_AWAKE;

	}
}

// Get AWAKE status
int GetAwakeStatus (int uartPort)
{
	if (uartPort == UARTA) return USR1_1.bits.AWAKE;
	else return USR1_2.bits.AWAKE;
}

// IsStartBitFound
int IsStartBitFound (int uartPort)
{
	if (uartPort == UARTA) return USR2_1.bits.WAKE;
	else return USR2_2.bits.WAKE;
}


// ClearDTRstatus
void ClearDTRstatus (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// clear DTR status bit
//		USR2_1.all &= USR2_DTRF;
		USR2_1.all |= USR2_DTRF;
	}
	else 
	{
		// clear DTR status bit
//		USR2_2.all &= USR2_DTRF;
		USR2_2.all |= USR2_DTRF;
	}
}


// ClearRTSstatus
void ClearRTSstatus (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// clear RTS status bits
//		USR1_1.all &= USR1_RTSD;
//		USR2_1.all &= USR2_RTSF;
		USR1_1.all |= USR1_RTSD;
		USR2_1.all |= USR2_RTSF;

	}
	else 
	{
		// clear RTS status bits
//		USR1_2.all &= USR1_RTSD;
//		USR2_2.all &= USR2_RTSF;
		USR1_2.all |= USR1_RTSD;
		USR2_2.all |= USR2_RTSF;

	}
}


// EnableForceParityError
void EnableForceParityError (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// set force parity error bit
		UTS_1.bits.FRCPERR = 1;
	}
	else 
	{
		// set force parity error bit
		UTS_2.bits.FRCPERR = 1;
	}
}


// DisableForceParityError
void DisableForceParityError (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// clear force parity error bit
		UTS_1.bits.FRCPERR = 0;
	}
	else 
	{
		// clear force parity error bit
		UTS_2.bits.FRCPERR = 0;
	}
}


// EnableLoopBack
void EnableLoopBack (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// set loopback bit
		UTS_1.bits.LOOP = 1;
	}
	else 
	{
		// set loopback bit
		UTS_2.bits.LOOP = 1;
	}
}


// DisableLoopBack
void DisableLoopBack (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// clear loopback bit
		UTS_1.bits.LOOP = 0;
	}
	else 
	{
		// clear loopback bit
		UTS_2.bits.LOOP = 0;
	}
}


// GetRTSstatus
int GetRTSstatus (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// return RTS pin status
		return USR1_1.bits.RTSS;
	}
	else 
	{
		// return RTS pin status
		return USR1_2.bits.RTSS;
	}
}


// GetRTSFstatus
int GetRTSFstatus (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// return RTS flag status
		return USR2_1.bits.RTSF;
	}
	else 
	{
		// return RTS flag status
		return USR2_2.bits.RTSF;
	}
}


// GetRTSDstatus
int GetRTSDstatus (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// return RTS delta flag status
		return USR1_1.bits.RTSD;
	}
	else 
	{
		// return RTS delta flag status
		return USR1_2.bits.RTSD;
	}
}


// GetDTRstatus 
int GetDTRstatus (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// return RTS pin status
		return USR2_1.bits.DTRF;
	}
	else 
	{
		// return RTS pin status
		return USR2_2.bits.DTRF;
	}
}


// ForceDSRlow
void ForceDSRlow (int uartPort)
{
	if (uartPort == UARTA) 
	{
		UCR3_1.bits.DSR = 0;
	}
	else
	{
		UCR3_2.bits.DSR = 0;
	}
}


// ForceDSRhigh
void ForceDSRhigh (int uartPort)
{
	if (uartPort == UARTA) 
	{
		UCR3_1.bits.DSR = 1;
	}
	else
	{
		UCR3_2.bits.DSR = 1;
	}
}


// ForceDCDlow
void ForceDCDlow (int uartPort)
{
	if (uartPort == UARTA) 
	{
		UCR3_1.bits.DCD = 0;
	}
	else
	{
		UCR3_2.bits.DCD = 0;
	}
}


// ForceDCDhigh
void ForceDCDhigh (int uartPort)
{
	if (uartPort == UARTA) 
	{
		UCR3_1.bits.DCD = 1;
	}
	else
	{
		UCR3_2.bits.DCD = 1;
	}
}


// ForceRIlow
void ForceRIlow (int uartPort)
{
	if (uartPort == UARTA) 
	{
		UCR3_1.bits.RI = 0;
	}
	else
	{
		UCR3_2.bits.RI = 0;
	}
}


// ForceRIhigh
void ForceRIhigh (int uartPort)
{
	if (uartPort == UARTA) 
	{
		UCR3_1.bits.RI = 1;
	}
	else
	{
		UCR3_2.bits.RI = 1;
	}
}


// EnableEscDetect
void EnableEscDetect (int uartPort)
{
	if (uartPort == UARTA) 
	{
		// enable escape sequence detection logic
		UCR2_1.bits.ESCEN = 1;
	}
	else
	{
		// enable escape sequence detection logic
		UCR2_2.bits.ESCEN = 1;
	}
}


// DisableEscDetect
void DisableEscDetect (int uartPort)
{
	if (uartPort == UARTA) 
	{
		// disable escape sequence detection logic
		UCR2_1.bits.ESCEN = 0;
	}
	else
	{
		// disable escape sequence detection logic
		UCR2_2.bits.ESCEN = 0;
	}
}


// SetEscChar
void SetEscChar (int uartPort, unsigned char c)
{
	if (uartPort == UARTA) 
	{
		UESC_1.bits.ESC_CHAR = c;
	}
	else
	{
		UESC_2.bits.ESC_CHAR = c;
	}
}


// GetEscStatus
int GetEscStatus (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// return escape sequence detect status
		return USR1_1.bits.ESCF;
	}
	else 
	{
		// return escape sequence detect status
		return USR1_2.bits.ESCF;
	}
}


// ClearEscStatus
void ClearEscStatus (int uartPort)
{
	if (uartPort == UARTA) 
	{
		// write 1 to clear ESC flag
//		USR1_1.all &= USR1_ESCF;
		USR1_1.all |= USR1_ESCF;
	}
	else
	{
		// write 1 to clear ESC flag
//		USR1_2.all &= USR1_ESCF;
		USR1_2.all |= USR1_ESCF;
	}
}


// SetEscInterval
void SetEscInterval (int uartPort, unsigned short interval)
{
	if (uartPort == UARTA) 
	{
		UTIM_1.bits.TIM = interval;
	}
	else
	{
		UTIM_2.bits.TIM = interval;
	}
}


// SetRefFreq
void SetRefFreq (int uartPort, int refFreq)
{
	if (uartPort == UARTA) 
	{
		switch (refFreq)
		{
			case REF_FREQ_16:
				UCR4_1.bits.REF16 = 1;
				UCR3_1.bits.REF25 = 0;				
				UCR3_1.bits.REF30 = 0;
				break;
			
			case REF_FREQ_25:
				UCR4_1.bits.REF16 = 0;
				UCR3_1.bits.REF25 = 1;
				UCR3_1.bits.REF30 = 0;
				break;
				
			case REF_FREQ_30:
				UCR4_1.bits.REF16 = 0;
				UCR3_1.bits.REF25 = 0;
				UCR3_1.bits.REF30 = 1;
				break;
			
			default:
				UCR4_1.bits.REF16 = 0;
				UCR3_1.bits.REF25 = 0;
				UCR3_1.bits.REF30 = 0;
				break;
		}				
	}
	else
	{
		switch (refFreq)
		{
			case REF_FREQ_16:
				UCR4_2.bits.REF16 = 1;
				UCR3_2.bits.REF25 = 0;
				UCR3_2.bits.REF30 = 0;
				break;
			
			case REF_FREQ_25:
				UCR4_2.bits.REF16 = 0;
				UCR3_2.bits.REF25 = 1;
				UCR3_2.bits.REF30 = 0;
				break;
				
			case REF_FREQ_30:
				UCR4_2.bits.REF16 = 0;
				UCR3_2.bits.REF25 = 0;
				UCR3_2.bits.REF30 = 1;
				break;
			
			default:
				UCR4_2.bits.REF16 = 0;
				UCR3_2.bits.REF25 = 0;
				UCR3_2.bits.REF30 = 0;
				break;
		}				
	}
}


// SetIdleFrameCount
void SetIdleFrameCount (int uartPort, unsigned idleFrames)
{
	if (uartPort == UARTA) 
	{
		UCR1_1.bits.ICD = idleFrames;
	}
	else
	{
		UCR1_2.bits.ICD = idleFrames;
	}
}


// GetIdleStatus
int GetIdleStatus (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// return idle status
		return USR2_1.bits.IDLE;
	}
	else 
	{
		// return idle status
		return USR2_2.bits.IDLE;
	}
}


// ClearIdleStatus
void ClearIdleStatus (int uartPort)
{
	if (uartPort == UARTA) 
	{
		// write 1 to clear IDLE flag
//		USR2_1.all &= USR2_IDLE;
		USR2_1.all |= USR2_IDLE;
	}
	else
	{
		// write 1 to clear IDLE flag
//		USR2_2.all &= USR2_IDLE;
		USR2_2.all |= USR2_IDLE;
	}
}


// GetBreakStatus
int GetBreakStatus (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// return break status
		return USR2_1.bits.BRCD;
	}
	else 
	{
		// return break status
		return USR2_2.bits.BRCD;
	}
}


// ClearBreakStatus
void ClearBreakStatus (int uartPort)
{
	if (uartPort == UARTA) 
	{
		// write 1 to clear BRCD flag
//		USR2_1.all &= USR2_BRCD;
		USR2_1.all |= USR2_BRCD;
	}
	else
	{
		// write 1 to clear BRCD flag
//		USR2_2.all &= USR2_BRCD;
		USR2_2.all |= USR2_BRCD;
	}
}


// GetOverrunStatus
int GetOverrunStatus (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// return overrun status
		return USR2_1.bits.ORE;
	}
	else 
	{
		// return overrun status
		return USR2_2.bits.ORE;
	}
}


// ClearOverrunStatus
void ClearOverrunStatus (int uartPort)
{
	if (uartPort == UARTA) 
	{
		// write 1 to clear ORE flag
//		USR2_1.all &= USR2_ORE;
		USR2_1.all |= USR2_ORE;
	}
	else
	{
		// write 1 to clear ORE flag
//		USR2_2.all &= USR2_ORE;
		USR2_2.all |= USR2_ORE;
	}
}


// GetIrdaStatus
int GetIrdaStatus (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// return IrDA status
		return USR2_1.bits.IRINT;
	}
	else 
	{
		// return IrDA status
		return USR2_2.bits.IRINT;
	}
}


// ClearIrdaStatus
void ClearIrdaStatus (int uartPort)
{
	if (uartPort == UARTA) 
	{
		// write 1 to clear IRINT flag
//		USR2_1.all &= USR2_IRINT;
		USR2_1.all |= USR2_IRINT;
	}
	else
	{
		// write 1 to clear IRINT flag
//		USR2_2.all &= USR2_IRINT;
		USR2_2.all |= USR2_IRINT;
	}
}


// GetIrdaWakeStatus
int GetIrdaWakeStatus (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// return IrDA wake status
		return USR1_1.bits.AIRINT;
	}
	else 
	{
		// return IrDA wake status
		return USR1_2.bits.AIRINT;
	}
}



// EnableTxDMA 
void EnableTxDMA (int uartPort)
{
	if (uartPort == UARTA)
	{
		// set TxDMA bit
		UCR1_1.bits.TDMAEN = 1;
	}
	else
	{
		// set TxDMA bit
		UCR1_2.bits.TDMAEN = 1;
	}
}



// EnableRxDMA
void EnableRxDMA (int uartPort)
{
	if (uartPort == UARTA)
	{
		// set RxDMA bit
		UCR1_1.bits.RDMAEN = 1;
	}
	else
	{
		// set TxDMA bit
		UCR1_2.bits.RDMAEN = 1;
	}
}

// DisableTxDMA 
void DisableTxDMA (int uartPort)
{
	if (uartPort == UARTA)
	{
		// clear TxDMA bit
		UCR1_1.bits.TDMAEN = 0;
	}
	else
	{
		// clear TxDMA bit
		UCR1_2.bits.TDMAEN = 0;
	}
}



// DisableRxDMA
void DisableRxDMA (int uartPort)
{
	if (uartPort == UARTA)
	{
		// clear RxDMA bit
		UCR1_1.bits.RDMAEN = 0;
	}
	else
	{
		// clear TxDMA bit
		UCR1_2.bits.RDMAEN = 0;
	}
}

void DisableUartTx(int uartPort)
{
	if (uartPort == UARTA)
	{
		// clear TXEN
		UCR2_1.bits.TXEN = 0;
	}
	else
	{
		// clear TXEN
		UCR2_2.bits.TXEN = 0;
	}

}

void EnableUartTx(int uartPort)
{
	if (uartPort == UARTA)
	{
		// set TXEN
		UCR2_1.bits.TXEN = 1;
	}
	else
	{
		// set TXEN
		UCR2_2.bits.TXEN = 1;
	}

}

int GetTimeoutStatus(int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// return Timeout status
		return USR1_1.bits.TIMEOUT;
	}
	else 
	{
		// return ITimeout status
		return USR1_2.bits.TIMEOUT;
	}
}

void IrDADetect(int state, int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// set Inverted Infared Reception bit
		UCR4_1.bits.INVR = state;
	}
	else 
	{
		// set Inverted Infared Reception bit
		UCR4_2.bits.INVR = state;
	}

}

void IrDATransmit (int state, int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// set Inverted Infared Transmission bit
		UCR3_1.bits.INVT = state;
	}
	else 
	{
		// set Inverted Infared Transmission bit
		UCR3_2.bits.INVT = state;
	}

}

void SetIrDASpecialCase (int uartPort)
{
	if (uartPort == UARTA) 
	{ 
		// set IrDA Special Case to Reference Clock
		UCR4_1.bits.IRSC = 1;
	}
	else 
	{
		// set IrDA Special Case to Reference Clock
		UCR4_2.bits.IRSC = 1;
	}

}






// WAIT
void WAIT (int msec)
{
	int value;
	
	/* need to set first before S/W reset??? */
	TCTL1.bits.TEN = 1;
	
	/* software reset the module */
	TCTL1.bits.SWR = 1;
	
	/* initalize the TIMER module */
	TCTL1.bits.TEN = 0;			// disable timer1
	TCTL1.bits.CLKSOURCE = 0x7;	// select 32kHz clock
	TCTL1.bits.IRQEN = 0;		// disable IRQ
		
	/* program the timer compare register */
	// if using a 32.768kHz crystal use this calculation
//	value = msec * 32.768;
	// else if using a 32kHz crystal, use this calculation
	value = msec * 32;
	
	TCMP1.all = value;
	
	/* enable the timer */
	TCTL1.bits.TEN = 1;
	
	/* wait until compare flag (COMP) is set (read TSTAT) */
	while (!(TSTAT1.bits.COMP == 1));
	
	/* clear the COMP flag */
	TSTAT1.bits.COMP = 0;
	
	/* disable the timer */
	TCTL1.bits.TEN = 0;
}

#endif
