/*******************************************************************************
*                                                                              *
* Copyright 2010 Rheinmetall Canada Inc.                                  	   *
*                                                                              *
* No part of this document may be reproduced, stored in                        *
* a retrieval system, or transmitted, in any form or by any means,             *
* electronic, mechanical, photocopying, recording, or otherwise,               *
* without the prior written permission of Rheinmetall Canada Inc.              *
*                                                                              *
*******************************************************************************/
/*
	Description:
	This is a template file for standard C code file.

*/

/* ************************************************************************** */
/* ¤Revision:
000 20100616 JFM,
	Original version.

### YYYYMMDD Initial, Bug Identification
	Change description.
 */

/* ************************************************************************** */
/* Includes */
#include "define.h"
#include "BoardCfg.h"
#include "InternalUart.h"
#include "uart.h"
#include "BootloaderProtocol.h"
//#include <stdio.h>

/* ************************************************************************** */
/* Local variables */
//char IntUartTxBuff[MAX_INTERNAL_UART_PORT][INTERNAL_UART_BUFFER_DEPTH];		//Tx Buffers
//char acIntUartRxBuff[INTERNAL_UART_BUFFER_DEPTH];		//Rx Buffers
stInternalUartData astInternalUartData;		//port management data

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void InternalUartInit(void)
{	
	
	
#ifdef USE_SERIAL_PORT_1	
	//Setup port 1A 
	//
	U1STA = 0;
	U1STAbits.UTXEN = 1;		//enable transmitter
	IPC6bits.U1IP = 5;			//priority 5	//NOT USED
	IPC6bits.U1IS = 2;			//sub-priority 2	//NOT USED
	U1STAbits.UTXSEL = 0b01;	//interrupt when all characters are transmitted
	IFS0bits.U1TXIF = 0;		//clear interrupt flag
	IEC0bits.U1TXIE = 0;		//disable tx interrupt
	U1STAbits.URXISEL = 0b00;	//interrupt for each character received
	IFS0bits.U1RXIF = 0;
	IEC0bits.U1RXIE = 0;		//disable rx interrupts
	U1STAbits.URXEN = 1;		//enable receiver
	U1MODEbits.ON = 0;			//disable module
		
#endif
#ifdef USE_SERIAL_PORT_2	
	//Setup port 1B
	//
	U2STA = 0;
	U2STAbits.UTXEN = 1;		//enable transmitter
	IPC8bits.U2IP = 5;			//priority 5	//NOT USED
	IPC8bits.U2IS = 2;			//sub-priority 2	//NOT USED
	U2STAbits.UTXSEL = 0b01;	//interrupt when all characters are transmitted
	IFS1bits.U2TXIF = 0;		//clear interrupt flag
	IEC1bits.U2TXIE = 0;		//disable tx interrupt
	U2STAbits.URXISEL = 0b00;	//interrupt for each character received
	IFS1bits.U2RXIF = 0;
	IEC1bits.U2RXIE = 0;		//disable rx interrupts
	U2STAbits.URXEN = 1;		//enable receiver
	U2MODEbits.ON = 0;			//disable module
#endif
	
	
//
//#ifdef USE_SERIAL_PORT_1A	
//	//Setup port 1A 
//	//
//	U1ASTA = 0;
//	U1ASTAbits.UTXEN = 1;		//enable transmitter
//	IPC6bits.U1AIP = 5;		//priority 5
//	IPC6bits.U1AIS = 2;		//sub-priority 2
//	U1ASTAbits.UTXSEL = 0b01;	//interrupt when all characters are transmitted
//	IFS0bits.U1ATXIF = 0;		//clear interrupt flag
//	IEC0bits.U1ATXIE = 0;		//disable tx interrupt
//	U1ASTAbits.URXISEL = 0b00;	//interrupt for each character received
//	IFS0bits.U1ARXIF = 0;
//	IEC0bits.U1ARXIE = 0;		//disable rx interrupts
//	U1ASTAbits.URXEN = 1;		//enable receiver
//	U1AMODEbits.ON = 0;			//disable module
//		
//#endif
//#ifdef USE_SERIAL_PORT_1B	
//	//Setup port 1B
//	//
//	U1BSTA = 0;
//	U1BSTAbits.UTXEN = 1;		//enable transmitter
//	IPC12bits.U1BIP = 5;		//priority 5
//	IPC12bits.U1BIS = 2;		//sub-priority 2
//	U1BSTAbits.UTXSEL = 0b01;	//interrupt when all characters are transmitted
//	IFS2bits.U1BTXIF = 0;		//clear interrupt flag
//	IEC2bits.U1BTXIE = 0;		//disable tx interrupt
//	U1BSTAbits.URXISEL = 0b00;	//interrupt for each character received
//	IFS2bits.U1BRXIF = 0;
//	IEC2bits.U1BRXIE = 0;		//disable rx interrupts
//	U1BSTAbits.URXEN = 1;		//enable receiver
//	U1BMODEbits.ON = 0;			//disable module
//#endif	
//	
//#ifdef USE_SERIAL_PORT_2A
//	//Setup port 2A
//	//
//	U2ASTA = 0;
//	U2ASTAbits.UTXEN = 1;		//enable transmitter
//	IPC7bits.U2AIP = 5;		//priority 5
//	IPC7bits.U2AIS = 2;		//sub-priority 2
//	U2ASTAbits.UTXSEL = 0b01;	//interrupt when all characters are transmitted
//	IFS1bits.U2ATXIF = 0;		//clear interrupt flag
//	IEC1bits.U2ATXIE = 0;		//disable tx interrupt
//	U2ASTAbits.URXISEL = 0b00;	//interrupt for each character received
//	IFS1bits.U2ARXIF = 0;
//	IEC1bits.U2ARXIE = 0;		//disable rx interrupts
//	U2ASTAbits.URXEN = 1;		//enable receiver
//	U2AMODEbits.ON = 0;			//disable module		
//#endif
//
//#ifdef USE_SERIAL_PORT_2B
//
//	//Setup port 2B
//	//
//	U2BSTA = 0;
//	U2BSTAbits.UTXEN = 1;		//enable transmitter
//	IPC12bits.U2BIP = 5;		//priority 5
//	IPC12bits.U2BIS = 2;		//sub-priority 2
//	U2BSTAbits.UTXSEL = 0b01;	//interrupt when all characters are transmitted
//	IFS2bits.U2BTXIF = 0;		//clear interrupt flag
//	IEC2bits.U2BTXIE = 0;		//disable tx interrupt
//	U2BSTAbits.URXISEL = 0b00;	//interrupt for each character received
//	IFS2bits.U2BRXIF = 0;
//	IEC2bits.U2BRXIE = 0;		//disable rx interrupts
//	U2BSTAbits.URXEN = 1;		//enable receiver
//	U2BMODEbits.ON = 0;			//disable module	
//#endif
//
//#ifdef USE_SERIAL_PORT_3A
//	
//	//Setup port 3A
//	//
//	U3ASTA = 0;
//	U3ASTAbits.UTXEN = 1;		//enable transmitter
//	IPC8bits.U3AIP = 5;			//priority 5
//	IPC8bits.U3AIS = 2;			//sub-priority 2
//	U3ASTAbits.UTXSEL = 0b01;	//interrupt when all characters are transmitted
//	IFS1bits.U3ATXIF = 0;		//clear interrupt flag
//	IEC1bits.U3ATXIE = 0;		//disable tx interrupt
//	U3ASTAbits.URXISEL = 0b00;	//interrupt for each character received
//	IFS1bits.U3ARXIF = 0;		//clear interrupt flag
//	IEC1bits.U3ARXIE = 0;		//disable tx interrupt	
//	U3ASTAbits.URXEN = 1;		//enable receiver
//	U3AMODEbits.ON = 0;			//disable module
//#endif
//
//#ifdef USE_SERIAL_PORT_3B	
//	//Setup port 3B
//	//
//	U3BSTA = 0;
//	U3BSTAbits.UTXEN = 1;		//enable transmitter
//	IPC12bits.U3BIP = 5;		//priority 5
//	IPC12bits.U3BIS = 2;		//sub-priority 2
//	U3BSTAbits.UTXSEL = 0b01;	//interrupt when all characters are transmitted
//	IFS2bits.U3BTXIF = 0;		//clear interrupt flag
//	IEC2bits.U3BTXIE = 0;		//disable tx interrupt
//	U3BSTAbits.URXISEL = 0b00;	//interrupt for each character received
//	IFS2bits.U3BRXIF = 0;		//clear interrupt flag
//	IEC2bits.U3BRXIE = 0;		//disable rx interrupt	
//	U3BSTAbits.URXEN = 1;		//enable receiver
//	U3BMODEbits.ON = 0;			//disable module
//#endif
//	

	astInternalUartData.pcTxDataPtr = 0;
	astInternalUartData.pcTxCircBufferTail = 0;
	astInternalUartData.pcTxCircBufferHead = 0;
	astInternalUartData.iTxDataSize = 0;
	astInternalUartData.iTxDataCounter = 0;
	astInternalUartData.iIsBusy = 0;
	astInternalUartData.iIsOpened = 0;
	astInternalUartData.iUartHandle = 0;
}


/*
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int SetIntalUartInterrupts(int p_iUartPort, int p_iRxInterrupt,int p_iTxInterrupt)
{
	if(p_iUartPort > MAX_INTERNAL_UART_PORT)
		return UART_INVALID_PORT;
		
		
		
	switch(p_iUartPort)
	{
		case INTERNAL_UART_PORT_1A:
		{
			if(p_iTxInterrupt)
			{
				IFS0bits.U1ATXIF = 0;		//clear interrupt flag
				IEC0bits.U1ATXIE = 1;		//enable tx interrupt
			}
			else
			{
				IEC0bits.U1ATXIE = 0;		//disable tx interrupt
				U1ASTAbits.UTXEN = 1;		//This bit must be set when working without interrupts
			}
			if(p_iRxInterrupt)
			{
				IFS0bits.U1ARXIF = 0;
				IEC0bits.U1ARXIE = 1;		//enable rx interrupt
			}
			else
			{
				IEC0bits.U1ARXIE = 0;		//disable rx interrupt
			}		
			break;
		}	
		case INTERNAL_UART_PORT_1B:
		{
			if(p_iTxInterrupt)
			{
				IFS2bits.U1BTXIF = 0;		//clear interrupt flag
				IEC2bits.U1BTXIE = 1;		//enable tx interrupt
			}
			else
			{
				IEC2bits.U1BTXIE = 0;		//disable tx interrupt
				U1BSTAbits.UTXEN = 1;		//This bit must be set when working without interrupts
			}
			if(p_iRxInterrupt)
			{
				IFS2bits.U1BRXIF = 0;
				IEC2bits.U1BRXIE = 1;		//enable rx interrupt
			}
			else
			{
				IEC2bits.U1BRXIE = 0;		//disable rx interrupt
			}		
			break;
		}
		case INTERNAL_UART_PORT_2A:
		{	
			if(p_iTxInterrupt)
			{
				IFS1bits.U2ATXIF = 0;		//clear interrupt flag
				IEC1bits.U2ATXIE = 1;		//enable tx interrupt
			}
			else
			{
				IEC1bits.U2ATXIE = 0;		//disable tx interrupt
				U2ASTAbits.UTXEN = 1;		//This bit must be set when working without interrupts
			}
			if(p_iRxInterrupt)
			{
				IFS1bits.U2ARXIF = 0;
				IEC1bits.U2ARXIE = 1;		//enable rx interrupt
			}
			else
			{
				IEC1bits.U2ARXIE = 0;		//disable rx interrupt
			}		
			break;
		}	
		case INTERNAL_UART_PORT_2B:
		{
			if(p_iTxInterrupt)
			{
				IFS2bits.U2BTXIF = 0;		//clear interrupt flag
				IEC2bits.U2BTXIE = 1;		//enable tx interrupt
			}
			else
			{
				IEC2bits.U2BTXIE = 0;		//disable tx interrupt
				U2ASTAbits.UTXEN = 1;		//This bit must be set when working without interrupts
			}
			if(p_iRxInterrupt)
			{
				IFS2bits.U2BRXIF = 0;
				IEC2bits.U2BRXIE = 1;		//enable rx interrupt
			}
			else
			{
				IEC2bits.U2BRXIE = 0;		//disable rx interrupt
			}		
			break;
		}	
	
		
		case INTERNAL_UART_PORT_3A:
		{
			if(p_iTxInterrupt)
			{
				IFS1bits.U3ATXIF = 0;		//clear interrupt flag
				IEC1bits.U3ATXIE = 1;		//enable tx interrupt
			}
			else
			{
				IEC1bits.U3ATXIE = 0;		//disable tx interrupt
				U3ASTAbits.UTXEN = 1;		//This bit must be set when working without interrupts
			}
			if(p_iRxInterrupt)
			{
				IFS1bits.U3ARXIF = 0;		//clear interrupt flag
				IEC1bits.U3ARXIE = 1;		//enable tx interrupt
			}
			else
			{
				IEC1bits.U3ARXIE = 0;		//disable rx interrupt
			}
			break;
		}
		case INTERNAL_UART_PORT_3B:
		{
			if(p_iTxInterrupt)
			{
				IFS2bits.U3BTXIF = 0;		//clear interrupt flag
				IEC2bits.U3BTXIE = 1;		//enable tx interrupt
			}
			else
			{
				IEC2bits.U3BTXIE = 0;		//disable tx interrupt
				U3BSTAbits.UTXEN = 1;		//This bit must be set when working without interrupts
			}
			if(p_iRxInterrupt)
			{
				IFS2bits.U3BRXIF = 0;		//clear interrupt flag
				IEC2bits.U3BRXIE = 1;		//enable tx interrupt
			}
			else
			{
				IEC2bits.U3BRXIE = 0;		//disable rx interrupt
			}
			break;
		}
		default:
		{
			return UART_INVALID_PORT;
		}	
	}	
	return UART_OK;
}	*/

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------	
int OpenInternalPort(char *p_pcHeadPtr, char *p_pcTailPtr, int p_iBaudRate, int p_iNbStopBits, int p_iParityEnable)
{
	int iBRG = (PERIPHERAL_FREQ/(4*p_iBaudRate)) - 1;
	int iMask = 0;
	
	switch(p_iNbStopBits)
	{
		case INT_UART_ONE_STOP_BIT:
		{
			break;
		}
		case INT_UART_TWO_STOP_BITS:
		{
			iMask |= 0x00000001;
			break;
		}	
	}
	
//	astInternalUartData.iUartHandle = p_iUartHandle;
	astInternalUartData.pcTxCircBufferTail = p_pcTailPtr;
	astInternalUartData.pcTxCircBufferHead = p_pcHeadPtr;	
	
	switch(p_iParityEnable)
	{
		case INT_UART_NO_PARITY:
		{
			break;
		}
		case INT_UART_EVEN_PARITY:
		{
			iMask |= 0x00000002;
			break;
		}
		case INT_UART_ODD_PARITY:
		{
			iMask |= 0x00000004;
			break;
		}	
	}
	
#ifdef USE_SERIAL_PORT_1		
		{
			U1MODE = iMask;
			U1MODEbits.BRGH = 1;
			U1BRG = iBRG;
			U1MODEbits.ON = 1;			//enable module
		}
#endif
#ifdef USE_SERIAL_PORT_2	
		{
			U2MODE = iMask;
			U2MODEbits.BRGH = 1;
			U2BRG = iBRG;
			U2MODEbits.ON = 1;			//enable module
		}
#endif


	

//#ifdef USE_SERIAL_PORT_1A		
//		{
//			U1AMODE = iMask;
//			U1AMODEbits.BRGH = 1;
//			U1ABRG = iBRG;
//			U1AMODEbits.ON = 1;			//enable module
//		}
//#endif
//#ifdef USE_SERIAL_PORT_1B		
//		{
//			U1BMODE = iMask;
//			U1BMODEbits.BRGH = 1;
//			U1BBRG = iBRG;
//			U1BMODEbits.ON = 1;			//enable module
//		}
//#endif
//#ifdef USE_SERIAL_PORT_2A		
//		{
//			U2AMODE = iMask;
//			U2AMODEbits.BRGH = 1;
//			U2ABRG = iBRG;
//			U2AMODEbits.ON = 1;			//enable module
//		}
//#endif
//#ifdef USE_SERIAL_PORT_2B
//		{	
//			U2BMODE = iMask;
//			U2BMODEbits.BRGH = 1;
//			U2BBRG = iBRG;
//			U2BMODEbits.ON = 1;			//enable module
//		}	
//#endif
//#ifdef USE_SERIAL_PORT_3A
//		{
//			U3AMODE = iMask;
//			U3AMODEbits.BRGH = 1;
//			U3ABRG = iBRG;
//			U3AMODEbits.ON = 1;			//enable module
//		}
//#endif
//#ifdef USE_SERIAL_PORT_3B
//		{
//			U3BMODE = iMask;
//			U3BMODEbits.BRGH = 1;
//			U3BBRG = iBRG;
//			U3BMODEbits.ON = 1;			//enable module
//		}	
//#endif
	
	astInternalUartData.iIsOpened = 1;

	return UART_OK;
}

//-----------------------------------------------------------------------------




//-----------------------------------------------------------------------------
int SendInternalUartData(char *p_pcDataBuf, int p_iDataSize)
{
	int i;
	if(astInternalUartData.iIsOpened == 0)
		return UART_PORT_NOT_OPENED;
	
	if(astInternalUartData.iIsBusy)
		return UART_PORT_BUSY;
	

	astInternalUartData.pcTxDataPtr = p_pcDataBuf;
	astInternalUartData.iTxDataSize = p_iDataSize;
	astInternalUartData.iTxDataCounter = 0;
	astInternalUartData.iIsBusy = 0;
	
	for(i = 0; i < p_iDataSize; i++)
	{
		#ifdef USE_SERIAL_PORT_1
			U1TXREG = *p_pcDataBuf++;
			while(U1STAbits.TRMT == 0);
		#endif
		#ifdef USE_SERIAL_PORT_2
			U2TXREG = *p_pcDataBuf++;
			while(U2STAbits.TRMT == 0);
            Nop();
		#endif		
		
		
		
		
//		#ifdef USE_SERIAL_PORT_1A
//			U1ATXREG = *p_pcDataBuf++;
//			while(U1ASTAbits.TRMT == 0);
//		#endif
//		#ifdef USE_SERIAL_PORT_1B
//			U1BTXREG = *p_pcDataBuf++;
//			while(U1BSTAbits.TRMT == 0);
//		#endif
//		#ifdef USE_SERIAL_PORT_2A
//			U2ATXREG = *p_pcDataBuf++;
//			while(U2ASTAbits.TRMT == 0);
//		#endif
//		#ifdef USE_SERIAL_PORT_2B
//			U2BTXREG = *p_pcDataBuf++;
//			while(U2BSTAbits.TRMT == 0);
//		#endif
//		#ifdef USE_SERIAL_PORT_3A
//			U3ATXREG = *p_pcDataBuf++;
//			while(U3ASTAbits.TRMT == 0);
//		#endif
//		#ifdef USE_SERIAL_PORT_3B		
//			U3BTXREG = *p_pcDataBuf++;
//			while(U3BSTAbits.TRMT == 0);
//		#endif
		
	}
	
	return UART_OK;
}

int ReadInternalUart(void)
{
	int count = 0;
	char byte;

		#ifdef USE_SERIAL_PORT_1
			while(U1STAbits.URXDA == 1)
			{
				byte = U1RXREG;
				ProtocolRxData(byte);
				count++;
			}
		#endif
		#ifdef USE_SERIAL_PORT_2
			while(U2STAbits.URXDA == 1)
			{
				byte = U2RXREG;
//				ProtocolRxData(byte);
				count++;
			}
		#endif


//		#ifdef USE_SERIAL_PORT_1A
//			while(U1ASTAbits.URXDA == 1)
//			{
//				byte = U1ARXREG;
//				ProtocolRxData(byte);
//				count++;
//			}
//		#endif
//		#ifdef USE_SERIAL_PORT_1B
//			while(U1BSTAbits.URXDA == 1)
//			{
//				byte = U1BRXREG;
//				ProtocolRxData(byte);
//				count++;
//			}
//		#endif
//		#ifdef USE_SERIAL_PORT_2A
//			while(U2ASTAbits.URXDA == 1)
//			{
//				byte = U2ARXREG;
//				ProtocolRxData(byte);
//				count++;
//			}
//		#endif
//		#ifdef USE_SERIAL_PORT_2B
//			while(U2BSTAbits.URXDA == 1)
//			{
//				byte = U2BRXREG;
//				ProtocolRxData(byte);
//				count++;
//			}
//		#endif
//		#ifdef USE_SERIAL_PORT_3A
//			while(U3ASTAbits.URXDA == 1)
//			{
//				byte = U3ARXREG;
//				ProtocolRxData(byte);
//				count++;
//			}
//		#endif
//		#ifdef USE_SERIAL_PORT_3B		
//			while(U3BSTAbits.URXDA == 1)
//			{
//				byte = U3BRXREG;
//				ProtocolRxData(byte);
//				count++;
//			}
//		#endif
		
	return count;
		
}

void CloseInternalUart(void)
{
	#ifdef USE_SERIAL_PORT_1
		U1MODEbits.ON = 0;			//disable module
		U1STA = 0;
	#endif
	#ifdef USE_SERIAL_PORT_2
		U2MODEbits.ON = 0;			//disable module
		U2STA = 0;
	#endif	
	
	
	
//	#ifdef USE_SERIAL_PORT_1A
//		U1AMODEbits.ON = 0;			//disable module
//		U1ASTA = 0;
//	#endif
//	#ifdef USE_SERIAL_PORT_1B
//		U1BMODEbits.ON = 0;			//disable module
//		U1BSTA = 0;
//	#endif
//	#ifdef USE_SERIAL_PORT_2A
//		U2AMODEbits.ON = 0;			//disable module
//		U2ASTA = 0;
//	#endif
//	#ifdef USE_SERIAL_PORT_2B
//		U2BMODEbits.ON = 0;			//disable module
//		U2BSTA = 0;
//	#endif
//	#ifdef USE_SERIAL_PORT_3A
//		U3AMODEbits.ON = 0;			//disable module
//		U3ASTA = 0;
//	#endif
//	#ifdef USE_SERIAL_PORT_3B		
//		U3BMODEbits.ON = 0;			//disable module
//		U3BSTA = 0;
//	#endif	
}	


//EOF

