www.pudn.com > dsPIC33EP512MU810.zip > RTDM.c, change:2011-03-28,size:63523b


/******************************************************************************/ 
// 
//							 Software License Agreement 
// 
// The software supplied herewith by Microchip Technology Incorporated  
// (the “Company”) for its PICmicro® Microcontroller is intended and  
// supplied to you, the Company’s customer, for use solely and  
// exclusively on Microchip PICmicro Microcontroller products. The  
// software is owned by the Company and/or its supplier, and is  
// protected under applicable copyright laws. All rights are reserved.  
//  Any use in violation of the foregoing restrictions may subject the  
// user to criminal sanctions under applicable laws, as well as to  
// civil liability for the breach of the terms and conditions of this  
// license. 
// 
// THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,  
// WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED  
// TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A  
// PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,  
// IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR  
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 
// 
/*****************************************************************************/ 
//	File:		RTDM.c 
// 
// This program along with MPLAB DMCI ( MPLAB 8.10 or higher) create an alternative link  
//between Host PC and target device for debugging applications in real-time.  
//It is required to include the RTDM.C file and RTDM.h into the application project  
//in order to send/receive data through the UART to/from the host PC running under  
//MPLAB (release 8.10 or higher) DMCI environment.  
// NOTE:DMCI included in MPLAB 8.10 or higher is ready and enabled to support data exchange  
//between the host PC and target device. Previous versions of DMCI do not support this feature.  
// NOTE: RTDM is currently supported by PIC24H, dsPIC30F,dsPIC33F and dsPIC33E processors 
// 
// 
//	Written By:		M.Ellis, D. Torres, 
//				Microchip Technology Inc 
//						 
//  
// The following files should be included in the MPLAB project: 
// 
//		RTDM.c			-- RTDM source code file 
//		RTDM.h			-- RTDM header file 
//		RTDMUSER.h		-- RTDM user definitions file 
//		libpXXXX-coff.a		-- Your dsPIC/PIC24 Peripheral Library		 
//		pXXXXXXX.gld		-- your dsPIC/PIC24 Linker script file 
//				 
// 
/*****************************************************************************/ 
// 
// Revision History 
// 
// 4/7/08  -- First Version Release 
/****************************************************************************/ 
// 
// Revision History 
// 
// 4/12/10  -- Added support for dsPIC33E and PIC24E (supports UART3 and UART4) 
/****************************************************************************/ 
 
#include "RTDM.h" 
 
/*+++++++++++++++++++++++++++++++ RTDM Variables ++++++++++++++++++++++++++++++++++++++++*/ 
/* Received data is stored in array RTDMRxBuffer  */ 
unsigned char RTDMRxBuffer[RTDM_RXBUFFERSIZE]; 
unsigned char * RTDMRxBufferLoLimit = RTDMRxBuffer; 
unsigned char * RTDMRxBufferHiLimit = RTDMRxBuffer + RTDM_RXBUFFERSIZE - 1; 
unsigned char * RTDMRxBufferIndex = RTDMRxBuffer; 
unsigned char * RTDMRxBufferStartMsgPointer; 
unsigned char * RTDMRxBufferEndMsgPointer; 
 
/* Data to be transmitted using UART communication module */ 
const unsigned char RTDMTxdata[] = {'R','T','D','M','\0'}; 
const unsigned char RTDMSanityCheckOK[] = {'+','$','R','T','D','M','#',0x1B,0x86,'\0'};  
const unsigned char RTDMWriteMemoryOK[] = {'+','$','O','K','#',0x4C,0x08,'\0'}; 
const unsigned char RTDMErrorIllegalFunction[] = {'-','$','E',0x01,'#',0xD3,0x6A,'\0'}; 
unsigned char RTDMErrorFrame[] = {'-','$','E',0,'#',0,0,'\0'}; 
 
/* Temp variables used to calculate the CRC16*/ 
unsigned int RTDMcrcTemp,RTDMcrcTempH,RTDMcrcTempL; 
 
/*Structure enclosing the RTDM flags*/ 
struct { 
			unsigned MessageReceived  :		1; 
			unsigned TransmitNow	  :		1; 
			unsigned unused :		14;      
		}	RTDMFlags;  
 
 
/* UART Configuration data */ 
/* Holds the value of uart config reg */ 
unsigned int RTDM_UART_MODE_VALUE; 
/* Holds the information regarding uart	TX & RX interrupt modes */    	 
unsigned int RTDM_UART_STA_VALUE;  
 
#if (RTDM_UART == 1) 
/****************************************************************************** 
* Function:     RTDM_Start() 
* 
* Output:		return 0 if no errors 
* 
* Overview:	Here is where the RTDM code initilizes the UART to be used to 
*			exchange data wiht the host PC 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
#if defined (RTDM_UART_V2) 
int RTDM_Start() 
{ 
 
	/********************** UART CONFIGURATIION ***************************/ 
	/* Turn off UART1 module */	 
	CloseUART1(); 
	/* Configure UART2 receive and transmit interrupt */ 
	ConfigIntUART1(UART_RX_INT_EN & (UART_RX_INT_PR0+RTDM_UART_PRIORITY) & UART_TX_INT_DIS & UART_TX_INT_PR2); 
	/* Configure UART1 module to transmit 8 bit data with one stopbit.  */  
	RTDM_UART_MODE_VALUE = UART_EN & UART_IDLE_CON & UART_IrDA_DISABLE & 
				UART_MODE_FLOW & UART_UEN_00 & UART_DIS_WAKE &  
				UART_DIS_LOOPBACK & UART_DIS_ABAUD & UART_UXRX_IDLE_ONE &  
				UART_BRGH_SIXTEEN & UART_NO_PAR_8BIT & UART_1STOPBIT; 
 
 
 
	 
	RTDM_UART_STA_VALUE  = UART_INT_TX_BUF_EMPTY  & UART_IrDA_POL_INV_ZERO &                   
	            UART_SYNC_BREAK_DISABLED & UART_TX_ENABLE & UART_INT_RX_CHAR &  
	            UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR; 
	 
	 
	OpenUART1(RTDM_UART_MODE_VALUE, RTDM_UART_STA_VALUE, RTDM_BRG); 
	 
	/************* RTDM Flags Configuration & Initial Values *****************/ 
	RTDMFlags.MessageReceived = 0; 
	RTDMFlags.MessageReceived = 0; 
	RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	RTDMRxBufferStartMsgPointer = 	RTDMRxBufferLoLimit;		 
	RTDMRxBufferEndMsgPointer = RTDMRxBufferLoLimit; 
 
    return 0; 
} 
#elif defined (RTDM_UART_V1) 
int RTDM_Start() 
{ 
 
	/********************** UART CONFIGURATIION ***************************/ 
	/* Turn off UART1 module */	 
	CloseUART1(); 
	/* Configure UART2 receive and transmit interrupt */ 
	ConfigIntUART1(UART_RX_INT_EN & (UART_RX_INT_PR0+RTDM_UART_PRIORITY) & UART_TX_INT_DIS & UART_TX_INT_PR2); 
	/* Configure UART1 module to transmit 8 bit data with one stopbit.  */  
	RTDM_UART_MODE_VALUE = UART_EN & UART_IDLE_CON &  
                         UART_DIS_WAKE & UART_DIS_LOOPBACK &  
                         UART_DIS_ABAUD & UART_NO_PAR_8BIT &  
                         UART_1STOPBIT; 
	 
	RTDM_UART_STA_VALUE  = UART_INT_TX_BUF_EMPTY & UART_TX_PIN_NORMAL &  
                         UART_TX_ENABLE & UART_INT_RX_CHAR &  
	                       UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR; 
	 
	 
	OpenUART1(RTDM_UART_MODE_VALUE, RTDM_UART_STA_VALUE, RTDM_BRG); 
	 
	/************* RTDM Flags Configuration & Initial Values *****************/ 
	RTDMFlags.MessageReceived = 0; 
	RTDMFlags.MessageReceived = 0; 
	RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	RTDMRxBufferStartMsgPointer = 	RTDMRxBufferLoLimit;		 
	RTDMRxBufferEndMsgPointer = RTDMRxBufferLoLimit; 
 
    return 0; 
} 
#endif 
 
/****************************************************************************** 
* Function:     	CloseRTDM() 
* 
* Output:		return 0 if no errors 
* 
* Overview:	Here is where the RTDM code closes the UART used to 
*			exchange data wiht the host PC 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
int CloseRTDM() 
{ 
	int nRet = 0; 
	CloseUART1(); 
	return nRet; 
		 
} 
 
/****************************************************************************** 
* Function:     	RTDM_ProcessMsgs() 
* 
* Output:		return 0 if no errors 
* 
* Overview:	Here is where the RTDM code process the message received and then  
*			executes the required task. These tasks are reading an specified memory 
*			location, writing an specified memory location, receive a communication 
*			link sanity check command, or being asked for the size of the bufffers. 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
int RTDM_ProcessMsgs() 
{ 
	 
	//Local pointer management variables 
	unsigned long int * RTDMpu32AddressTemp; 
	unsigned char     * RTDMpucWrData; 
    unsigned char     * RTDMpucRdData; 
    unsigned char     * RTDMpucWrAddr;	 
    unsigned short      RTDMNumBytes; 
    unsigned char       RTDMPacketBuf[16]; 
     
	unsigned int        RTDMProcessMsgsTemp1, RTDMProcessMsgsTemp2; 
	unsigned int        N; 
 
    if (!RTDMFlags.MessageReceived) 
	{ 
		return -1; 
	} 
 
 
	RTDMcrcTemp =  
		RTDM_CumulativeCrc16 
			(RTDMRxBufferStartMsgPointer,  
			(unsigned int)(RTDMRxBufferEndMsgPointer-RTDMRxBufferStartMsgPointer)+1,  
			0xFFFF); 
			 
	RTDMcrcTempH = (RTDMcrcTemp & 0xFF00)>>8; 
	RTDMcrcTempL = RTDMcrcTemp & 0x00FF; 
	RTDMProcessMsgsTemp1 = (unsigned int)*((RTDMRxBufferEndMsgPointer)+2); 
	RTDMProcessMsgsTemp2 = (unsigned int)*((RTDMRxBufferEndMsgPointer)+1); 
 
 
 
	RTDMRxBufferStartMsgPointer +=2; 
	if((RTDMProcessMsgsTemp1 == (unsigned)RTDMcrcTempH) && (RTDMProcessMsgsTemp2 == RTDMcrcTempL)) 
	  { 
 
		switch(*((RTDMRxBufferLoLimit)+1)) 
		  { 
		  case 'm': 
			/*************** Extract Address **************/ 
			//Capture address as 32 bit quantity to match protocol definition.  
			RTDMpu32AddressTemp = ((unsigned long *) RTDMRxBufferStartMsgPointer); 
			 
			//Increment receive buffer pointer to length field. 
			RTDMRxBufferStartMsgPointer += sizeof(unsigned long); 
			  
			//Init a byte oriented data pointer   
			RTDMpucRdData = (unsigned char *) ((unsigned int) *RTDMpu32AddressTemp); 
 
			/********* Extract Number of Bytes ************/			 
			//Capture address as 16 bit quantity to match protocol definition.  
			RTDMNumBytes = *((unsigned short *) RTDMRxBufferStartMsgPointer); 
			 
			//Increment receive buffer pointer to start of data payload. 
			RTDMRxBufferStartMsgPointer += sizeof(unsigned short); 
			 
            //Init the CRC seed for the cumulative checksum calculation. 					 
			RTDMcrcTemp = 0xffff; 
			 
			//Add packet header prefix 
			RTDMPacketBuf[0] = '+'; 
			RTDMPacketBuf[1] = '$'; 
			//Add null terminator for putsUARTx function... 
			RTDMPacketBuf[2] = 0;  
			 
			//Calc header prefix checksum piece 
			RTDMcrcTemp = RTDM_CumulativeCrc16(RTDMPacketBuf, 2, RTDMcrcTemp);	 
			//Calc data payload checksum 
			RTDMcrcTemp = RTDM_CumulativeCrc16(RTDMpucRdData, RTDMNumBytes, RTDMcrcTemp);			 
			 
			//Send packet header. Use string function to save code space...  
			putsUART1((unsigned int *)RTDMPacketBuf); 
			while(BusyUART1());  
			 
			//Send data portion of message...  
			while(RTDMNumBytes--) 
			 { 
				WriteUART1(*RTDMpucRdData++); 
				while(BusyUART1());  
			 } 
			 
			//Add packet trailer    
		    RTDMPacketBuf[0] = '#'; 
		    RTDMcrcTemp = RTDM_CumulativeCrc16(RTDMPacketBuf, 1, RTDMcrcTemp);			 
		     
		    //Add checksum bytes to packet 
			RTDMPacketBuf[1] = RTDMcrcTemp & 0x00FF; 
			RTDMPacketBuf[2] = (RTDMcrcTemp & 0xFF00) >> 8; 
			 
			//Send packet trailer and checksum. 			 
			for (N=0; N < 3; N++) 
			{ 
				WriteUART1(RTDMPacketBuf[N]);  
				while(BusyUART1());  
			}	 
		  break; 
		   
		  case 'M': 
			{ 
			/*************** Extract Address **************/						 
		    //Capture address as 32 bit quantity to match protocol definition.  
		    RTDMpu32AddressTemp = (unsigned long *) RTDMRxBufferStartMsgPointer; 
		     
		    //Increment receive buffer pointer to length field. 
		    RTDMRxBufferStartMsgPointer += sizeof(unsigned long); 
		    		     
			// Init a byte oriented address pointer for use in incrementing  
			//through the address range properly as we write each byte of data 
			//in the range (length) of this write request.    
			RTDMpucWrAddr = (unsigned char *) ((unsigned int) *RTDMpu32AddressTemp); 
 
			/********* Extract Number of Bytes ************/ 
			//MEllis Capture length as 16 bit quantity to match protocol definition. 
			RTDMNumBytes = *((unsigned short *) RTDMRxBufferStartMsgPointer); 
			 
			//MEllis Increment receive buffer pointer to start of data payload. 
			RTDMRxBufferStartMsgPointer += sizeof(unsigned short); 
			 
			/********** Extract Data ************/ 
			 
			//Init a byte oriented data pointer so that we can increment a byte at at  
			//time for as many bytes as are in the range for this write.  
			RTDMpucWrData = RTDMRxBufferStartMsgPointer; 
			 
			//*** Write Data in specified RAM location *****			 
			//Important to increment through address range using byte oriented address and data 
			//pointers. Otherwise, single byte or odd byte ranges do not get written correctly.  
			while(RTDMNumBytes--) 
			  { 
    			*RTDMpucWrAddr++ = *RTDMpucWrData++; 
    		  } 
			  			 
			//Transmit OK message 
			putsUART1((unsigned int *)RTDMWriteMemoryOK); 
			/* Wait for  transmission to complete */ 
			while(BusyUART1());  
			break; 
			} 
		  case 's': 
			{ 
			/* Load transmit buffer and transmit the same till null character is encountered */ 
			//Transmit OK message 
			putsUART1((unsigned int *)RTDMSanityCheckOK); 
			/* Wait for  transmission to complete */ 
			while(BusyUART1());  
		    break; 
			} 
		   
		  case 'L': 
		    RTDMcrcTemp = 0xffff; //Init the CRC seed. 
			 
			RTDMPacketBuf[0] = '+'; 
			RTDMPacketBuf[1] = '$'; 
			//Size of the RTDM Receive buffer. 
			RTDMPacketBuf[2] = (sizeof(RTDMRxBuffer) & 0x00FF); 
			RTDMPacketBuf[3] = (sizeof(RTDMRxBuffer) & 0xFF00) >> 8; 
			//Note: We dod not utilize a transmit buffer since any data memory source is  
			//essentially already buffered. So the transmit limit is now just a way to  
			//limit the total message length that a client make with any single read request. 
			RTDMPacketBuf[4] = (RTDM_MAX_XMIT_LEN & 0x00FF); 
			RTDMPacketBuf[5] = (RTDM_MAX_XMIT_LEN & 0xFF00) >> 8; 
			RTDMPacketBuf[6] = '#';		 
			RTDMcrcTemp = RTDM_CumulativeCrc16(RTDMPacketBuf, 7, RTDMcrcTemp);			 
			RTDMPacketBuf[7] = (RTDMcrcTemp & 0x00FF); 
			RTDMPacketBuf[8] = (RTDMcrcTemp & 0xFF00) >> 8; 
 
			//Send completed message which is 9 bytes in length. 
			for (N=0; N < 9; N++) 
			{ 
				WriteUART1(RTDMPacketBuf[N]); 
				while(BusyUART1());  
			}	 
			break; 
		   
		  default: 
			// ---> COMMAND SUPPORTED?? IF NOT ERROR HANDLER 
			//Transmit ERROR message 1 
			putsUART1 ((unsigned int *)RTDMErrorIllegalFunction); 
			/* Wait for  transmission to complete */ 
			while(BusyUART1());  
			break; 
		  } 
				    
	  } 
 
	  memset(&RTDMRxBuffer, 0, sizeof(RTDMRxBuffer)); 
	   
	  RTDMFlags.MessageReceived = 0; 
	  RTDMRxBufferIndex             = RTDMRxBufferLoLimit; 
	  RTDMRxBufferStartMsgPointer   = RTDMRxBufferLoLimit;		 
	  RTDMRxBufferEndMsgPointer     = RTDMRxBufferLoLimit; 
	   
	  return 0; 
}	 
 
/****************************************************************************** 
* Function:     	_U1RXInterrupt(void) 
* 
* Output:		void 
* 
* Overview:	Here is where the RTDM receives the messages using the UART receiver  
*			interrupt, If polling method is selected in the RTDMUSER.h file then 
*			the user application should call the RTDM_ProcessMsgs routine in order  
*			to precess up comming messages. If polling method is disabled then the  
*			RTDM_ProcessMsgs routine is called in the UART received interrupt 
*			routine. 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
#if (RTDM_POLLING == YES) 
/* This is UART1 receive ISR Polling RTDM Messages*/  
void __attribute__((__interrupt__, no_auto_psv)) _U1RXInterrupt(void)  
{ 
     
    _U1RXIF = 0; 
     
	/* Read the receive buffer until at least one or more character can be read */   
    while(DataRdyUART1()) 
      *(RTDMRxBufferIndex++) = ReadUART1();		 
 
	RTDMRxBufferEndMsgPointer = RTDMRxBufferIndex-3; 
	if(RTDMRxBufferIndex > (RTDMRxBufferHiLimit-1)) 
	  { 
	  RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	  RTDMRxBufferEndMsgPointer = RTDMRxBufferHiLimit-1; 
	  } 
	 
	if(*(RTDMRxBufferStartMsgPointer) == '$') 
	{ 
	  if(*(RTDMRxBufferEndMsgPointer) == '#') 
	  { 
      	RTDMFlags.MessageReceived = 1; 
      } 
    }   
	else 
	{ 
		RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	} 
	 
}   
 
/****************************************************************************** 
* Function:     	_U1RXInterrupt(void) 
* 
* Output:		void 
* 
* Overview:	Here is where the RTDM receives the messages using the UART receiver  
*			interrupt, If polling method is selected in the RTDMUSER.h file then 
*			the user application should call the RTDM_ProcessMsgs routine in order  
*			to precess up comming messages. If polling method is disabled then the  
*			RTDM_ProcessMsgs routine is called in the UART received interrupt 
*			routine. 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
#else 
/* This is UART1 receive ISR without polling RTDM Messages */  
void __attribute__((__interrupt__, no_auto_psv)) _U1RXInterrupt(void)  
{ 
     
    _U1RXIF = 0; 
     
	/* Read the receive buffer until at least one or more character can be read */   
    while(DataRdyUART1()) 
      *(RTDMRxBufferIndex++) = ReadUART1();		 
 
	RTDMRxBufferEndMsgPointer = RTDMRxBufferIndex-3; 
	if(RTDMRxBufferIndex > (RTDMRxBufferHiLimit-1)) 
	  { 
	  RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	  RTDMRxBufferEndMsgPointer = RTDMRxBufferHiLimit-1; 
	  } 
	 
	if(*(RTDMRxBufferStartMsgPointer) == '$') 
	{ 
	  if(*(RTDMRxBufferEndMsgPointer) == '#') 
	  { 
      	RTDMFlags.MessageReceived = 1; 
      	RTDM_ProcessMsgs(); 
      } 
    }   
	else 
	{ 
		RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	} 
	 
}   
#endif 
 
#elif (RTDM_UART == 2) 
/****************************************************************************** 
* Function:    	 RTDM_Start() 
* 
* Output:		return 0 if no errors 
* 
* Overview:	Here is where the RTDM code initilizes the UART to be used to 
*			exchange data wiht the host PC 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
#if defined (RTDM_UART_V2) 
int RTDM_Start() 
{ 
 
	/********************** UART CONFIGURATIION ******************************/ 
	/* Turn off UART2 module */	 
	CloseUART2(); 
	 
	/* Configure UART2 receive and transmit interrupt */ 
	ConfigIntUART2(UART_RX_INT_EN & (UART_RX_INT_PR0+RTDM_UART_PRIORITY)& UART_TX_INT_DIS & UART_TX_INT_PR2); 
	 
	/* Configure UART2 module to transmit 8 bit data with one stopbit.  */  
	RTDM_UART_MODE_VALUE = UART_EN & UART_IDLE_CON & UART_IrDA_DISABLE & 
				UART_MODE_FLOW & UART_UEN_00 & UART_DIS_WAKE &  
				UART_DIS_LOOPBACK & UART_DIS_ABAUD & UART_UXRX_IDLE_ONE &  
				UART_BRGH_SIXTEEN & UART_NO_PAR_8BIT & UART_1STOPBIT; 
 
 
 
	 
	RTDM_UART_STA_VALUE  = UART_INT_TX_BUF_EMPTY  & UART_IrDA_POL_INV_ZERO &                   
	            UART_SYNC_BREAK_DISABLED & UART_TX_ENABLE & UART_INT_RX_CHAR &  
	            UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR; 
	 
	 
	OpenUART2(RTDM_UART_MODE_VALUE, RTDM_UART_STA_VALUE, RTDM_BRG); 
	 
	 
	/************* RTDM Flags Configuration & Initial Values *****************/ 
	RTDMFlags.MessageReceived = 0; 
	RTDMFlags.MessageReceived = 0; 
	RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	RTDMRxBufferStartMsgPointer = 	RTDMRxBufferLoLimit;		 
	RTDMRxBufferEndMsgPointer = RTDMRxBufferLoLimit; 
 
    return 0; 
} 
	#elif defined (RTDM_UART_V1) 
int RTDM_Start() 
{ 
 
	/********************** UART CONFIGURATIION ******************************/ 
	/* Turn off UART2 module */	 
	CloseUART2(); 
	 
	/* Configure UART2 receive and transmit interrupt */ 
	ConfigIntUART2(UART_RX_INT_EN & (UART_RX_INT_PR0+RTDM_UART_PRIORITY)& UART_TX_INT_DIS & UART_TX_INT_PR2); 
	 
	/* Configure UART2 module to transmit 8 bit data with one stopbit.  */  
	RTDM_UART_MODE_VALUE = UART_EN & UART_IDLE_CON &  
                       UART_DIS_WAKE & UART_DIS_LOOPBACK &  
                       UART_DIS_ABAUD & UART_NO_PAR_8BIT &  
                       UART_1STOPBIT; 
	 
	RTDM_UART_STA_VALUE  = UART_INT_TX_BUF_EMPTY & UART_TX_PIN_NORMAL &  
                       UART_TX_ENABLE & UART_INT_RX_CHAR &  
                       UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR; 
	 
	 
	OpenUART2(RTDM_UART_MODE_VALUE, RTDM_UART_STA_VALUE, RTDM_BRG); 
	 
	 
	/************* RTDM Flags Configuration & Initial Values *****************/ 
	RTDMFlags.MessageReceived = 0; 
	RTDMFlags.MessageReceived = 0; 
	RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	RTDMRxBufferStartMsgPointer = 	RTDMRxBufferLoLimit;		 
	RTDMRxBufferEndMsgPointer = RTDMRxBufferLoLimit; 
 
    return 0; 
} 
#endif 
/****************************************************************************** 
* Function:     	CloseRTDM() 
* 
* Output:		return 0 if no errors 
* 
* Overview:	Here is where the RTDM code closes the UART used to 
*			exchange data wiht the host PC 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
int CloseRTDM() 
{ 
	int nRet = 0; 
	CloseUART2();	 
	return nRet; 
} 
 
/****************************************************************************** 
* Function:     	RTDM_ProcessMsgs() 
* 
* Output:		return 0 if no errors 
* 
* Overview:	Here is where the RTDM code process the message received and then  
*			executes the required task. These tasks are reading an specified memory 
*			location, writing an specified memory location, receive a communication 
*			link sanity check command, or being asked for the size of the bufffers. 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
int RTDM_ProcessMsgs() 
{ 
	 
	//Local pointer management variables 
	unsigned long int * RTDMpu32AddressTemp; 
	unsigned char     * RTDMpucWrData; 
    unsigned char     * RTDMpucRdData; 
    unsigned char     * RTDMpucWrAddr;	 
    unsigned short      RTDMNumBytes; 
    unsigned char       RTDMPacketBuf[16]; 
     
	unsigned int        RTDMProcessMsgsTemp1, RTDMProcessMsgsTemp2; 
	unsigned int        N; 
 
    if (!RTDMFlags.MessageReceived) 
	{ 
		return -1; 
	} 
 
 
	RTDMcrcTemp =  
		RTDM_CumulativeCrc16 
		(RTDMRxBufferStartMsgPointer,  
		(unsigned int)(RTDMRxBufferEndMsgPointer-RTDMRxBufferStartMsgPointer)+1,  
		0xFFFF); 
		 
	RTDMcrcTempH = (RTDMcrcTemp & 0xFF00)>>8; 
	RTDMcrcTempL = RTDMcrcTemp & 0x00FF; 
	RTDMProcessMsgsTemp1 = (unsigned int)*((RTDMRxBufferEndMsgPointer)+2); 
	RTDMProcessMsgsTemp2 = (unsigned int)*((RTDMRxBufferEndMsgPointer)+1); 
 
	RTDMRxBufferStartMsgPointer +=2; 
	if((RTDMProcessMsgsTemp1 == (unsigned)RTDMcrcTempH) && (RTDMProcessMsgsTemp2 == RTDMcrcTempL)) 
	  { 
 
		switch(*((RTDMRxBufferLoLimit)+1)) 
		  { 
		  case 'm': 
			/*************** Extract Address **************/ 
			//Capture address as 32 bit quantity to match protocol definition.  
			RTDMpu32AddressTemp = ((unsigned long *) RTDMRxBufferStartMsgPointer); 
			 
			//Increment receive buffer pointer to length field. 
			RTDMRxBufferStartMsgPointer += sizeof(unsigned long); 
			  
			//Init a byte oriented data pointer   
			RTDMpucRdData = (unsigned char *) ((unsigned int) *RTDMpu32AddressTemp); 
 
			/********* Extract Number of Bytes ***********/			 
			//Capture address as 16 bit quantity to match protocol definition.  
			RTDMNumBytes = *((unsigned short *) RTDMRxBufferStartMsgPointer); 
			 
			//Increment receive buffer pointer to start of data payload. 
			RTDMRxBufferStartMsgPointer += sizeof(unsigned short); 
			 
            //Init the CRC seed for the cumulative checksum calculation. 					 
			RTDMcrcTemp = 0xffff; 
			 
			//Add packet header prefix 
			RTDMPacketBuf[0] = '+'; 
			RTDMPacketBuf[1] = '$'; 
			//Add null terminator for putsUARTx function... 
			RTDMPacketBuf[2] = 0;  
			 
			//Calc header prefix checksum piece 
			RTDMcrcTemp = RTDM_CumulativeCrc16(RTDMPacketBuf, 2, RTDMcrcTemp);	 
			//Calc data payload checksum 
			RTDMcrcTemp = RTDM_CumulativeCrc16(RTDMpucRdData, RTDMNumBytes, RTDMcrcTemp);			 
			 
			//Send packet header. Use string function to save code space...  
			putsUART2 ((unsigned int *)RTDMPacketBuf); 
			while(BusyUART2());  
			 
			//Send data portion of message...  
			while(RTDMNumBytes--) 
			 { 
				WriteUART2(*RTDMpucRdData++); 
				while(BusyUART2());  
			 } 
			 
			//Add packet trailer    
		    RTDMPacketBuf[0] = '#'; 
		    RTDMcrcTemp = RTDM_CumulativeCrc16(RTDMPacketBuf, 1, RTDMcrcTemp);			 
		     
		    //Add checksum bytes to packet 
			RTDMPacketBuf[1] = RTDMcrcTemp & 0x00FF; 
			RTDMPacketBuf[2] = (RTDMcrcTemp & 0xFF00) >> 8; 
			 
			//Send packet trailer and checksum. 			 
			for (N=0; N < 3; N++) 
			{ 
				WriteUART2(RTDMPacketBuf[N]);  
				while(BusyUART2());  
			}	 
		  break; 
		   
		  case 'M': 
			{ 
			/*************** Extract Address **************/						 
		    //Capture address as 32 bit quantity to match protocol definition.  
		    RTDMpu32AddressTemp = (unsigned long *) RTDMRxBufferStartMsgPointer; 
		     
		    //Increment receive buffer pointer to length field. 
		    RTDMRxBufferStartMsgPointer += sizeof(unsigned long); 
		    		     
			//Init a byte oriented address pointer for use in incrementing  
			//through the address range properly as we write each byte of data 
			//in the range (length) of this write request.    
			RTDMpucWrAddr = (unsigned char *) ((unsigned int) *RTDMpu32AddressTemp); 
 
			/********* Extract Number of Bytes ************/ 
			//Capture length as 16 bit quantity to match protocol definition. 
			RTDMNumBytes = *((unsigned short *) RTDMRxBufferStartMsgPointer); 
			 
			//Increment receive buffer pointer to start of data payload. 
			RTDMRxBufferStartMsgPointer += sizeof(unsigned short); 
			 
			/********** Extract Data ************/			 
			//Init a byte oriented data pointer so that we can increment a byte at at  
			//time for as many bytes as are in the range for this write.  
			RTDMpucWrData = RTDMRxBufferStartMsgPointer; 
			 
			//*** Write Data in specified RAM location *****			 
			//Important to increment through address range using byte oriented address and data 
			//pointers. Otherwise, single byte or odd byte ranges do not get written correctly.  
			while(RTDMNumBytes--) 
			  { 
    			*RTDMpucWrAddr++ = *RTDMpucWrData++; 
    		  } 
			  			 
			//Transmit OK message 
			putsUART2((unsigned int *)RTDMWriteMemoryOK); 
			/* Wait for  transmission to complete */ 
			while(BusyUART2());  
			break; 
			} 
		  case 's': 
			{ 
			/* Load transmit buffer and transmit the same till null character is encountered */ 
			//Transmit OK message 
			putsUART2((unsigned int *)RTDMSanityCheckOK); 
			/* Wait for  transmission to complete */ 
			while(BusyUART2());  
		    break; 
			} 
		   
		  case 'L': 
		    RTDMcrcTemp = 0xffff; //Init the CRC seed. 
			 
			RTDMPacketBuf[0] = '+'; 
			RTDMPacketBuf[1] = '$'; 
			//Size of the RTDM Receive buffer. 
			RTDMPacketBuf[2] = (sizeof(RTDMRxBuffer) & 0x00FF); 
			RTDMPacketBuf[3] = (sizeof(RTDMRxBuffer) & 0xFF00) >> 8; 
			//Note: We dod not utilize a transmit buffer since any data memory source is  
			//essentially already buffered. So the transmit limit is now just a way to  
			//limit the total message length that a client make with any single read request. 
			RTDMPacketBuf[4] = (RTDM_MAX_XMIT_LEN & 0x00FF); 
			RTDMPacketBuf[5] = (RTDM_MAX_XMIT_LEN & 0xFF00) >> 8; 
			RTDMPacketBuf[6] = '#';		 
			RTDMcrcTemp = RTDM_CumulativeCrc16(RTDMPacketBuf, 7, RTDMcrcTemp);			 
			RTDMPacketBuf[7] = (RTDMcrcTemp & 0x00FF); 
			RTDMPacketBuf[8] = (RTDMcrcTemp & 0xFF00) >> 8; 
 
			//Send completed message which is 9 bytes in length. 
			for (N=0; N < 9; N++) 
			{ 
				WriteUART2(RTDMPacketBuf[N]); 
				while(BusyUART2());  
			}	 
			break; 
 
		  default: 
			// ---> COMMAND SUPPORTED?? IF NOT ERROR HANDLER 
			//Transmit ERROR message 1 
			putsUART2 ((unsigned int *)RTDMErrorIllegalFunction); 
			/* Wait for  transmission to complete */ 
			while(BusyUART2());  
			break; 
		  } 
				    
	  } 
 
	  memset(&RTDMRxBuffer, 0, sizeof(RTDMRxBuffer)); 
	   
	  RTDMFlags.MessageReceived = 0; 
	  RTDMRxBufferIndex             = RTDMRxBufferLoLimit; 
	  RTDMRxBufferStartMsgPointer   = RTDMRxBufferLoLimit;		 
	  RTDMRxBufferEndMsgPointer     = RTDMRxBufferLoLimit; 
	   
	  return 0; 
}	 
 
/****************************************************************************** 
* Function:     	_U2RXInterrupt(void) 
* 
* Output:		void 
* 
* Overview:	Here is where the RTDM receives the messages using the UART receiver  
*			interrupt, If polling method is selected in the RTDMUSER.h file then 
*			the user application should call the RTDM_ProcessMsgs routine in order  
*			to precess up comming messages. If polling method is disabled then the  
*			RTDM_ProcessMsgs routine is called in the UART received interrupt 
*			routine. 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
#if (RTDM_POLLING == YES) 
/* This is UART2 receive ISR Polling RTDM Messages*/  
void __attribute__((__interrupt__, no_auto_psv)) _U2RXInterrupt(void)  
{ 
     
    _U2RXIF = 0; 
     
	/* Read the receive buffer until at least one or more character can be read */   
    while(DataRdyUART2()) 
      *(RTDMRxBufferIndex++) = ReadUART2();		 
 
	RTDMRxBufferEndMsgPointer = RTDMRxBufferIndex-3; 
	if(RTDMRxBufferIndex > (RTDMRxBufferHiLimit-1)) 
	  { 
	  RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	  RTDMRxBufferEndMsgPointer = RTDMRxBufferHiLimit-1; 
	  } 
	 
	if(*(RTDMRxBufferStartMsgPointer) == '$') 
	{ 
	  if(*(RTDMRxBufferEndMsgPointer) == '#') 
	  { 
      	RTDMFlags.MessageReceived = 1; 
      } 
    }   
	else 
	{ 
		RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	} 
	 
}   
 
/****************************************************************************** 
* Function:     	_U2RXInterrupt(void) 
* 
* Output:		void 
* 
* Overview:	Here is where the RTDM receives the messages using the UART receiver  
*			interrupt, If polling method is selected in the RTDMUSER.h file then 
*			the user application should call the RTDM_ProcessMsgs routine in order  
*			to precess up comming messages. If polling method is disabled then the  
*			RTDM_ProcessMsgs routine is called in the UART received interrupt 
*			routine. 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
#else 
/* This is UART2 receive ISR without polling RTDM Messages */  
void __attribute__((__interrupt__, no_auto_psv)) _U2RXInterrupt(void)  
{ 
     
    _U2RXIF = 0; 
     
	/* Read the receive buffer until at least one or more character can be read */   
    while(DataRdyUART2()) 
      *(RTDMRxBufferIndex++) = ReadUART2();		 
 
	RTDMRxBufferEndMsgPointer = RTDMRxBufferIndex-3; 
	if(RTDMRxBufferIndex > (RTDMRxBufferHiLimit-1)) 
	  { 
	  RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	  RTDMRxBufferEndMsgPointer = RTDMRxBufferHiLimit-1; 
	  } 
	 
	if(*(RTDMRxBufferStartMsgPointer) == '$') 
	{ 
	  if(*(RTDMRxBufferEndMsgPointer) == '#') 
	  { 
      	RTDMFlags.MessageReceived = 1; 
      	RTDM_ProcessMsgs(); 
      } 
    }   
	else 
	{ 
		RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	} 
	 
}   
#endif 
 
#elif (RTDM_UART == 3) 
	 
	#if (defined (RTDM_UART_V2) && (defined(__dsPIC33E__) || defined(__PIC24E__)) ) 
		 
/****************************************************************************** 
* Function:    	 RTDM_Start() 
* 
* Output:		return 0 if no errors 
* 
* Overview:	Here is where the RTDM code initilizes the UART to be used to 
*			exchange data wiht the host PC 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
int RTDM_Start() 
{ 
 
	/********************** UART CONFIGURATIION ******************************/ 
	/* Turn off UART3 module */	 
	CloseUART3(); 
	 
	/* Configure UART3 receive and transmit interrupt */ 
	ConfigIntUART3(UART_RX_INT_EN & (UART_RX_INT_PR0+RTDM_UART_PRIORITY)& UART_TX_INT_DIS & UART_TX_INT_PR2); 
	 
	/* Configure UART3 module to transmit 8 bit data with one stopbit.  */  
	RTDM_UART_MODE_VALUE = UART_EN & UART_IDLE_CON & UART_IrDA_DISABLE & 
				UART_MODE_FLOW & UART_UEN_00 & UART_DIS_WAKE &  
				UART_DIS_LOOPBACK & UART_DIS_ABAUD & UART_UXRX_IDLE_ONE &  
				UART_BRGH_SIXTEEN & UART_NO_PAR_8BIT & UART_1STOPBIT; 
 
 
 
	 
	RTDM_UART_STA_VALUE  = UART_INT_TX_BUF_EMPTY  & UART_IrDA_POL_INV_ZERO &                   
	            UART_SYNC_BREAK_DISABLED & UART_TX_ENABLE & UART_INT_RX_CHAR &  
	            UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR; 
	 
	 
	OpenUART3(RTDM_UART_MODE_VALUE, RTDM_UART_STA_VALUE, RTDM_BRG); 
	 
	 
	/************* RTDM Flags Configuration & Initial Values *****************/ 
	RTDMFlags.MessageReceived = 0; 
	RTDMFlags.MessageReceived = 0; 
	RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	RTDMRxBufferStartMsgPointer = 	RTDMRxBufferLoLimit;		 
	RTDMRxBufferEndMsgPointer = RTDMRxBufferLoLimit; 
 
    return 0; 
} 
 
/****************************************************************************** 
* Function:     	CloseRTDM() 
* 
* Output:		return 0 if no errors 
* 
* Overview:	Here is where the RTDM code closes the UART used to 
*			exchange data wiht the host PC 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
int CloseRTDM() 
{ 
	int nRet = 0; 
	CloseUART3();	 
	return nRet; 
} 
 
/****************************************************************************** 
* Function:     	RTDM_ProcessMsgs() 
* 
* Output:		return 0 if no errors 
* 
* Overview:	Here is where the RTDM code process the message received and then  
*			executes the required task. These tasks are reading an specified memory 
*			location, writing an specified memory location, receive a communication 
*			link sanity check command, or being asked for the size of the bufffers. 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
int RTDM_ProcessMsgs() 
{ 
	 
	//Local pointer management variables 
	unsigned long int * RTDMpu32AddressTemp; 
	unsigned char     * RTDMpucWrData; 
    unsigned char     * RTDMpucRdData; 
    unsigned char     * RTDMpucWrAddr;	 
    unsigned short      RTDMNumBytes; 
    unsigned char       RTDMPacketBuf[16]; 
     
	unsigned int        RTDMProcessMsgsTemp1, RTDMProcessMsgsTemp2; 
	unsigned int        N; 
 
    if (!RTDMFlags.MessageReceived) 
	{ 
		return -1; 
	} 
 
 
	RTDMcrcTemp =  
		RTDM_CumulativeCrc16 
		(RTDMRxBufferStartMsgPointer,  
		(unsigned int)(RTDMRxBufferEndMsgPointer-RTDMRxBufferStartMsgPointer)+1,  
		0xFFFF); 
		 
	RTDMcrcTempH = (RTDMcrcTemp & 0xFF00)>>8; 
	RTDMcrcTempL = RTDMcrcTemp & 0x00FF; 
	RTDMProcessMsgsTemp1 = (unsigned int)*((RTDMRxBufferEndMsgPointer)+2); 
	RTDMProcessMsgsTemp2 = (unsigned int)*((RTDMRxBufferEndMsgPointer)+1); 
 
	RTDMRxBufferStartMsgPointer +=2; 
	if((RTDMProcessMsgsTemp1 == (unsigned)RTDMcrcTempH) && (RTDMProcessMsgsTemp2 == RTDMcrcTempL)) 
	  { 
 
		switch(*((RTDMRxBufferLoLimit)+1)) 
		  { 
		  case 'm': 
			/*************** Extract Address **************/ 
			//Capture address as 32 bit quantity to match protocol definition.  
			RTDMpu32AddressTemp = ((unsigned long *) RTDMRxBufferStartMsgPointer); 
			 
			//Increment receive buffer pointer to length field. 
			RTDMRxBufferStartMsgPointer += sizeof(unsigned long); 
			  
			//Init a byte oriented data pointer   
			RTDMpucRdData = (unsigned char *) ((unsigned int) *RTDMpu32AddressTemp); 
 
			/********* Extract Number of Bytes ***********/			 
			//Capture address as 16 bit quantity to match protocol definition.  
			RTDMNumBytes = *((unsigned short *) RTDMRxBufferStartMsgPointer); 
			 
			//Increment receive buffer pointer to start of data payload. 
			RTDMRxBufferStartMsgPointer += sizeof(unsigned short); 
			 
            //Init the CRC seed for the cumulative checksum calculation. 					 
			RTDMcrcTemp = 0xffff; 
			 
			//Add packet header prefix 
			RTDMPacketBuf[0] = '+'; 
			RTDMPacketBuf[1] = '$'; 
			//Add null terminator for putsUARTx function... 
			RTDMPacketBuf[2] = 0;  
			 
			//Calc header prefix checksum piece 
			RTDMcrcTemp = RTDM_CumulativeCrc16(RTDMPacketBuf, 2, RTDMcrcTemp);	 
			//Calc data payload checksum 
			RTDMcrcTemp = RTDM_CumulativeCrc16(RTDMpucRdData, RTDMNumBytes, RTDMcrcTemp);			 
			 
			//Send packet header. Use string function to save code space...  
			putsUART3 ((unsigned int *)RTDMPacketBuf); 
			while(BusyUART3());  
			 
			//Send data portion of message...  
			while(RTDMNumBytes--) 
			 { 
				WriteUART3(*RTDMpucRdData++); 
				while(BusyUART3());  
			 } 
			 
			//Add packet trailer    
		    RTDMPacketBuf[0] = '#'; 
		    RTDMcrcTemp = RTDM_CumulativeCrc16(RTDMPacketBuf, 1, RTDMcrcTemp);			 
		     
		    //Add checksum bytes to packet 
			RTDMPacketBuf[1] = RTDMcrcTemp & 0x00FF; 
			RTDMPacketBuf[2] = (RTDMcrcTemp & 0xFF00) >> 8; 
			 
			//Send packet trailer and checksum. 			 
			for (N=0; N < 3; N++) 
			{ 
				WriteUART3(RTDMPacketBuf[N]);  
				while(BusyUART3());  
			}	 
		  break; 
		   
		  case 'M': 
			{ 
			/*************** Extract Address **************/						 
		    //Capture address as 32 bit quantity to match protocol definition.  
		    RTDMpu32AddressTemp = (unsigned long *) RTDMRxBufferStartMsgPointer; 
		     
		    //Increment receive buffer pointer to length field. 
		    RTDMRxBufferStartMsgPointer += sizeof(unsigned long); 
		    		     
			//Init a byte oriented address pointer for use in incrementing  
			//through the address range properly as we write each byte of data 
			//in the range (length) of this write request.    
			RTDMpucWrAddr = (unsigned char *) ((unsigned int) *RTDMpu32AddressTemp); 
 
			/********* Extract Number of Bytes ************/ 
			//Capture length as 16 bit quantity to match protocol definition. 
			RTDMNumBytes = *((unsigned short *) RTDMRxBufferStartMsgPointer); 
			 
			//Increment receive buffer pointer to start of data payload. 
			RTDMRxBufferStartMsgPointer += sizeof(unsigned short); 
			 
			/********** Extract Data ************/			 
			//Init a byte oriented data pointer so that we can increment a byte at at  
			//time for as many bytes as are in the range for this write.  
			RTDMpucWrData = RTDMRxBufferStartMsgPointer; 
			 
			//*** Write Data in specified RAM location *****			 
			//Important to increment through address range using byte oriented address and data 
			//pointers. Otherwise, single byte or odd byte ranges do not get written correctly.  
			while(RTDMNumBytes--) 
			  { 
    			*RTDMpucWrAddr++ = *RTDMpucWrData++; 
    		  } 
			  			 
			//Transmit OK message 
			putsUART3((unsigned int *)RTDMWriteMemoryOK); 
			/* Wait for  transmission to complete */ 
			while(BusyUART3());  
			break; 
			} 
		  case 's': 
			{ 
			/* Load transmit buffer and transmit the same till null character is encountered */ 
			//Transmit OK message 
			putsUART3((unsigned int *)RTDMSanityCheckOK); 
			/* Wait for  transmission to complete */ 
			while(BusyUART3());  
		    break; 
			} 
		   
		  case 'L': 
		    RTDMcrcTemp = 0xffff; //Init the CRC seed. 
			 
			RTDMPacketBuf[0] = '+'; 
			RTDMPacketBuf[1] = '$'; 
			//Size of the RTDM Receive buffer. 
			RTDMPacketBuf[2] = (sizeof(RTDMRxBuffer) & 0x00FF); 
			RTDMPacketBuf[3] = (sizeof(RTDMRxBuffer) & 0xFF00) >> 8; 
			//Note: We dod not utilize a transmit buffer since any data memory source is  
			//essentially already buffered. So the transmit limit is now just a way to  
			//limit the total message length that a client make with any single read request. 
			RTDMPacketBuf[4] = (RTDM_MAX_XMIT_LEN & 0x00FF); 
			RTDMPacketBuf[5] = (RTDM_MAX_XMIT_LEN & 0xFF00) >> 8; 
			RTDMPacketBuf[6] = '#';		 
			RTDMcrcTemp = RTDM_CumulativeCrc16(RTDMPacketBuf, 7, RTDMcrcTemp);			 
			RTDMPacketBuf[7] = (RTDMcrcTemp & 0x00FF); 
			RTDMPacketBuf[8] = (RTDMcrcTemp & 0xFF00) >> 8; 
 
			//Send completed message which is 9 bytes in length. 
			for (N=0; N < 9; N++) 
			{ 
				WriteUART3(RTDMPacketBuf[N]); 
				while(BusyUART3());  
			}	 
			break; 
 
		  default: 
			// ---> COMMAND SUPPORTED?? IF NOT ERROR HANDLER 
			//Transmit ERROR message 1 
			putsUART3 ((unsigned int *)RTDMErrorIllegalFunction); 
			/* Wait for  transmission to complete */ 
			while(BusyUART3());  
			break; 
		  } 
				    
	  } 
 
	  memset(&RTDMRxBuffer, 0, sizeof(RTDMRxBuffer)); 
	   
	  RTDMFlags.MessageReceived = 0; 
	  RTDMRxBufferIndex             = RTDMRxBufferLoLimit; 
	  RTDMRxBufferStartMsgPointer   = RTDMRxBufferLoLimit;		 
	  RTDMRxBufferEndMsgPointer     = RTDMRxBufferLoLimit; 
	   
	  return 0; 
}	 
 
/****************************************************************************** 
* Function:     	_U3RXInterrupt(void) 
* 
* Output:		void 
* 
* Overview:	Here is where the RTDM receives the messages using the UART receiver  
*			interrupt, If polling method is selected in the RTDMUSER.h file then 
*			the user application should call the RTDM_ProcessMsgs routine in order  
*			to precess up comming messages. If polling method is disabled then the  
*			RTDM_ProcessMsgs routine is called in the UART received interrupt 
*			routine. 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
#if (RTDM_POLLING == YES) 
/* This is UART3 receive ISR Polling RTDM Messages*/  
void __attribute__((__interrupt__, no_auto_psv)) _U3RXInterrupt(void)  
{ 
     
    _U3RXIF = 0; 
     
	/* Read the receive buffer until at least one or more character can be read */   
    while(DataRdyUART3()) 
      *(RTDMRxBufferIndex++) = ReadUART3();		 
 
	RTDMRxBufferEndMsgPointer = RTDMRxBufferIndex-3; 
	if(RTDMRxBufferIndex > (RTDMRxBufferHiLimit-1)) 
	  { 
	  RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	  RTDMRxBufferEndMsgPointer = RTDMRxBufferHiLimit-1; 
	  } 
	 
	if(*(RTDMRxBufferStartMsgPointer) == '$') 
	{ 
	  if(*(RTDMRxBufferEndMsgPointer) == '#') 
	  { 
      	RTDMFlags.MessageReceived = 1; 
      } 
    }   
	else 
	{ 
		RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	} 
	 
}   
 
/****************************************************************************** 
* Function:     	_U3RXInterrupt(void) 
* 
* Output:		void 
* 
* Overview:	Here is where the RTDM receives the messages using the UART receiver  
*			interrupt, If polling method is selected in the RTDMUSER.h file then 
*			the user application should call the RTDM_ProcessMsgs routine in order  
*			to precess up comming messages. If polling method is disabled then the  
*			RTDM_ProcessMsgs routine is called in the UART received interrupt 
*			routine. 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
#else 
/* This is UART3 receive ISR without polling RTDM Messages */  
void __attribute__((__interrupt__, no_auto_psv)) _U3RXInterrupt(void)  
{ 
     
    _U3RXIF = 0; 
     
	/* Read the receive buffer until at least one or more character can be read */   
    while(DataRdyUART3()) 
      *(RTDMRxBufferIndex++) = ReadUART3();		 
 
	RTDMRxBufferEndMsgPointer = RTDMRxBufferIndex-3; 
	if(RTDMRxBufferIndex > (RTDMRxBufferHiLimit-1)) 
	  { 
	  RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	  RTDMRxBufferEndMsgPointer = RTDMRxBufferHiLimit-1; 
	  } 
	 
	if(*(RTDMRxBufferStartMsgPointer) == '$') 
	{ 
	  if(*(RTDMRxBufferEndMsgPointer) == '#') 
	  { 
      	RTDMFlags.MessageReceived = 1; 
      	RTDM_ProcessMsgs(); 
      } 
    }   
	else 
	{ 
		RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	} 
	 
}   
#endif 
 
#else  
	#error UART3 not avaialable on the current device 
 
#endif 
 
#elif (RTDM_UART == 4) 
	 
	#if (defined (RTDM_UART_V2) && (defined(__dsPIC33E__) || defined(__PIC24E__)) ) 
		 
/****************************************************************************** 
* Function:    	 RTDM_Start() 
* 
* Output:		return 0 if no errors 
* 
* Overview:	Here is where the RTDM code initilizes the UART to be used to 
*			exchange data wiht the host PC 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
int RTDM_Start() 
{ 
 
	/********************** UART CONFIGURATIION ******************************/ 
	/* Turn off UART4 module */	 
	CloseUART4(); 
	 
	/* Configure UART4 receive and transmit interrupt */ 
	ConfigIntUART4(UART_RX_INT_EN & (UART_RX_INT_PR0+RTDM_UART_PRIORITY)& UART_TX_INT_DIS & UART_TX_INT_PR2); 
	 
	/* Configure UART4 module to transmit 8 bit data with one stopbit.  */  
	RTDM_UART_MODE_VALUE = UART_EN & UART_IDLE_CON & UART_IrDA_DISABLE & 
				UART_MODE_FLOW & UART_UEN_00 & UART_DIS_WAKE &  
				UART_DIS_LOOPBACK & UART_DIS_ABAUD & UART_UXRX_IDLE_ONE &  
				UART_BRGH_SIXTEEN & UART_NO_PAR_8BIT & UART_1STOPBIT; 
 
 
 
	 
	RTDM_UART_STA_VALUE  = UART_INT_TX_BUF_EMPTY  & UART_IrDA_POL_INV_ZERO &                   
	            UART_SYNC_BREAK_DISABLED & UART_TX_ENABLE & UART_INT_RX_CHAR &  
	            UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR; 
	 
	 
	OpenUART4(RTDM_UART_MODE_VALUE, RTDM_UART_STA_VALUE, RTDM_BRG); 
	 
	 
	/************* RTDM Flags Configuration & Initial Values *****************/ 
	RTDMFlags.MessageReceived = 0; 
	RTDMFlags.MessageReceived = 0; 
	RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	RTDMRxBufferStartMsgPointer = 	RTDMRxBufferLoLimit;		 
	RTDMRxBufferEndMsgPointer = RTDMRxBufferLoLimit; 
 
    return 0; 
} 
 
/****************************************************************************** 
* Function:     	CloseRTDM() 
* 
* Output:		return 0 if no errors 
* 
* Overview:	Here is where the RTDM code closes the UART used to 
*			exchange data wiht the host PC 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
int CloseRTDM() 
{ 
	int nRet = 0; 
	CloseUART4();	 
	return nRet; 
} 
 
/****************************************************************************** 
* Function:     	RTDM_ProcessMsgs() 
* 
* Output:		return 0 if no errors 
* 
* Overview:	Here is where the RTDM code process the message received and then  
*			executes the required task. These tasks are reading an specified memory 
*			location, writing an specified memory location, receive a communication 
*			link sanity check command, or being asked for the size of the bufffers. 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
int RTDM_ProcessMsgs() 
{ 
	 
	//Local pointer management variables 
	unsigned long int * RTDMpu32AddressTemp; 
	unsigned char     * RTDMpucWrData; 
    unsigned char     * RTDMpucRdData; 
    unsigned char     * RTDMpucWrAddr;	 
    unsigned short      RTDMNumBytes; 
    unsigned char       RTDMPacketBuf[16]; 
     
	unsigned int        RTDMProcessMsgsTemp1, RTDMProcessMsgsTemp2; 
	unsigned int        N; 
 
    if (!RTDMFlags.MessageReceived) 
	{ 
		return -1; 
	} 
 
 
	RTDMcrcTemp =  
		RTDM_CumulativeCrc16 
		(RTDMRxBufferStartMsgPointer,  
		(unsigned int)(RTDMRxBufferEndMsgPointer-RTDMRxBufferStartMsgPointer)+1,  
		0xFFFF); 
		 
	RTDMcrcTempH = (RTDMcrcTemp & 0xFF00)>>8; 
	RTDMcrcTempL = RTDMcrcTemp & 0x00FF; 
	RTDMProcessMsgsTemp1 = (unsigned int)*((RTDMRxBufferEndMsgPointer)+2); 
	RTDMProcessMsgsTemp2 = (unsigned int)*((RTDMRxBufferEndMsgPointer)+1); 
 
	RTDMRxBufferStartMsgPointer +=2; 
	if((RTDMProcessMsgsTemp1 == (unsigned)RTDMcrcTempH) && (RTDMProcessMsgsTemp2 == RTDMcrcTempL)) 
	  { 
 
		switch(*((RTDMRxBufferLoLimit)+1)) 
		  { 
		  case 'm': 
			/*************** Extract Address **************/ 
			//Capture address as 32 bit quantity to match protocol definition.  
			RTDMpu32AddressTemp = ((unsigned long *) RTDMRxBufferStartMsgPointer); 
			 
			//Increment receive buffer pointer to length field. 
			RTDMRxBufferStartMsgPointer += sizeof(unsigned long); 
			  
			//Init a byte oriented data pointer   
			RTDMpucRdData = (unsigned char *) ((unsigned int) *RTDMpu32AddressTemp); 
 
			/********* Extract Number of Bytes ***********/			 
			//Capture address as 16 bit quantity to match protocol definition.  
			RTDMNumBytes = *((unsigned short *) RTDMRxBufferStartMsgPointer); 
			 
			//Increment receive buffer pointer to start of data payload. 
			RTDMRxBufferStartMsgPointer += sizeof(unsigned short); 
			 
            //Init the CRC seed for the cumulative checksum calculation. 					 
			RTDMcrcTemp = 0xffff; 
			 
			//Add packet header prefix 
			RTDMPacketBuf[0] = '+'; 
			RTDMPacketBuf[1] = '$'; 
			//Add null terminator for putsUARTx function... 
			RTDMPacketBuf[2] = 0;  
			 
			//Calc header prefix checksum piece 
			RTDMcrcTemp = RTDM_CumulativeCrc16(RTDMPacketBuf, 2, RTDMcrcTemp);	 
			//Calc data payload checksum 
			RTDMcrcTemp = RTDM_CumulativeCrc16(RTDMpucRdData, RTDMNumBytes, RTDMcrcTemp);			 
			 
			//Send packet header. Use string function to save code space...  
			putsUART4 ((unsigned int *)RTDMPacketBuf); 
			while(BusyUART4());  
			 
			//Send data portion of message...  
			while(RTDMNumBytes--) 
			 { 
				WriteUART4(*RTDMpucRdData++); 
				while(BusyUART4());  
			 } 
			 
			//Add packet trailer    
		    RTDMPacketBuf[0] = '#'; 
		    RTDMcrcTemp = RTDM_CumulativeCrc16(RTDMPacketBuf, 1, RTDMcrcTemp);			 
		     
		    //Add checksum bytes to packet 
			RTDMPacketBuf[1] = RTDMcrcTemp & 0x00FF; 
			RTDMPacketBuf[2] = (RTDMcrcTemp & 0xFF00) >> 8; 
			 
			//Send packet trailer and checksum. 			 
			for (N=0; N < 3; N++) 
			{ 
				WriteUART4(RTDMPacketBuf[N]);  
				while(BusyUART4());  
			}	 
		  break; 
		   
		  case 'M': 
			{ 
			/*************** Extract Address **************/						 
		    //Capture address as 32 bit quantity to match protocol definition.  
		    RTDMpu32AddressTemp = (unsigned long *) RTDMRxBufferStartMsgPointer; 
		     
		    //Increment receive buffer pointer to length field. 
		    RTDMRxBufferStartMsgPointer += sizeof(unsigned long); 
		    		     
			//Init a byte oriented address pointer for use in incrementing  
			//through the address range properly as we write each byte of data 
			//in the range (length) of this write request.    
			RTDMpucWrAddr = (unsigned char *) ((unsigned int) *RTDMpu32AddressTemp); 
 
			/********* Extract Number of Bytes ************/ 
			//Capture length as 16 bit quantity to match protocol definition. 
			RTDMNumBytes = *((unsigned short *) RTDMRxBufferStartMsgPointer); 
			 
			//Increment receive buffer pointer to start of data payload. 
			RTDMRxBufferStartMsgPointer += sizeof(unsigned short); 
			 
			/********** Extract Data ************/			 
			//Init a byte oriented data pointer so that we can increment a byte at at  
			//time for as many bytes as are in the range for this write.  
			RTDMpucWrData = RTDMRxBufferStartMsgPointer; 
			 
			//*** Write Data in specified RAM location *****			 
			//Important to increment through address range using byte oriented address and data 
			//pointers. Otherwise, single byte or odd byte ranges do not get written correctly.  
			while(RTDMNumBytes--) 
			  { 
    			*RTDMpucWrAddr++ = *RTDMpucWrData++; 
    		  } 
			  			 
			//Transmit OK message 
			putsUART4((unsigned int *)RTDMWriteMemoryOK); 
			/* Wait for  transmission to complete */ 
			while(BusyUART4());  
			break; 
			} 
		  case 's': 
			{ 
			/* Load transmit buffer and transmit the same till null character is encountered */ 
			//Transmit OK message 
			putsUART4((unsigned int *)RTDMSanityCheckOK); 
			/* Wait for  transmission to complete */ 
			while(BusyUART4());  
		    break; 
			} 
		   
		  case 'L': 
		    RTDMcrcTemp = 0xffff; //Init the CRC seed. 
			 
			RTDMPacketBuf[0] = '+'; 
			RTDMPacketBuf[1] = '$'; 
			//Size of the RTDM Receive buffer. 
			RTDMPacketBuf[2] = (sizeof(RTDMRxBuffer) & 0x00FF); 
			RTDMPacketBuf[3] = (sizeof(RTDMRxBuffer) & 0xFF00) >> 8; 
			//Note: We dod not utilize a transmit buffer since any data memory source is  
			//essentially already buffered. So the transmit limit is now just a way to  
			//limit the total message length that a client make with any single read request. 
			RTDMPacketBuf[4] = (RTDM_MAX_XMIT_LEN & 0x00FF); 
			RTDMPacketBuf[5] = (RTDM_MAX_XMIT_LEN & 0xFF00) >> 8; 
			RTDMPacketBuf[6] = '#';		 
			RTDMcrcTemp = RTDM_CumulativeCrc16(RTDMPacketBuf, 7, RTDMcrcTemp);			 
			RTDMPacketBuf[7] = (RTDMcrcTemp & 0x00FF); 
			RTDMPacketBuf[8] = (RTDMcrcTemp & 0xFF00) >> 8; 
 
			//Send completed message which is 9 bytes in length. 
			for (N=0; N < 9; N++) 
			{ 
				WriteUART4(RTDMPacketBuf[N]); 
				while(BusyUART4());  
			}	 
			break; 
 
		  default: 
			// ---> COMMAND SUPPORTED?? IF NOT ERROR HANDLER 
			//Transmit ERROR message 1 
			putsUART4 ((unsigned int *)RTDMErrorIllegalFunction); 
			/* Wait for  transmission to complete */ 
			while(BusyUART4());  
			break; 
		  } 
				    
	  } 
 
	  memset(&RTDMRxBuffer, 0, sizeof(RTDMRxBuffer)); 
	   
	  RTDMFlags.MessageReceived = 0; 
	  RTDMRxBufferIndex             = RTDMRxBufferLoLimit; 
	  RTDMRxBufferStartMsgPointer   = RTDMRxBufferLoLimit;		 
	  RTDMRxBufferEndMsgPointer     = RTDMRxBufferLoLimit; 
	   
	  return 0; 
}	 
 
/****************************************************************************** 
* Function:     	_U4RXInterrupt(void) 
* 
* Output:		void 
* 
* Overview:	Here is where the RTDM receives the messages using the UART receiver  
*			interrupt, If polling method is selected in the RTDMUSER.h file then 
*			the user application should call the RTDM_ProcessMsgs routine in order  
*			to precess up comming messages. If polling method is disabled then the  
*			RTDM_ProcessMsgs routine is called in the UART received interrupt 
*			routine. 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
#if (RTDM_POLLING == YES) 
/* This is UART4 receive ISR Polling RTDM Messages*/  
void __attribute__((__interrupt__, no_auto_psv)) _U4RXInterrupt(void)  
{ 
     
    _U4RXIF = 0; 
     
	/* Read the receive buffer until at least one or more character can be read */   
    while(DataRdyUART4()) 
      *(RTDMRxBufferIndex++) = ReadUART4();		 
 
	RTDMRxBufferEndMsgPointer = RTDMRxBufferIndex-3; 
	if(RTDMRxBufferIndex > (RTDMRxBufferHiLimit-1)) 
	  { 
	  RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	  RTDMRxBufferEndMsgPointer = RTDMRxBufferHiLimit-1; 
	  } 
	 
	if(*(RTDMRxBufferStartMsgPointer) == '$') 
	{ 
	  if(*(RTDMRxBufferEndMsgPointer) == '#') 
	  { 
      	RTDMFlags.MessageReceived = 1; 
      } 
    }   
	else 
	{ 
		RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	} 
	 
}   
 
/****************************************************************************** 
* Function:     	_U4RXInterrupt(void) 
* 
* Output:		void 
* 
* Overview:	Here is where the RTDM receives the messages using the UART receiver  
*			interrupt, If polling method is selected in the RTDMUSER.h file then 
*			the user application should call the RTDM_ProcessMsgs routine in order  
*			to precess up comming messages. If polling method is disabled then the  
*			RTDM_ProcessMsgs routine is called in the UART received interrupt 
*			routine. 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
#else 
/* This is UART4 receive ISR without polling RTDM Messages */  
void __attribute__((__interrupt__, no_auto_psv)) _U4RXInterrupt(void)  
{ 
     
    _U4RXIF = 0; 
     
	/* Read the receive buffer until at least one or more character can be read */   
    while(DataRdyUART4()) 
      *(RTDMRxBufferIndex++) = ReadUART4();		 
 
	RTDMRxBufferEndMsgPointer = RTDMRxBufferIndex-3; 
	if(RTDMRxBufferIndex > (RTDMRxBufferHiLimit-1)) 
	  { 
	  RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	  RTDMRxBufferEndMsgPointer = RTDMRxBufferHiLimit-1; 
	  } 
	 
	if(*(RTDMRxBufferStartMsgPointer) == '$') 
	{ 
	  if(*(RTDMRxBufferEndMsgPointer) == '#') 
	  { 
      	RTDMFlags.MessageReceived = 1; 
      	RTDM_ProcessMsgs(); 
      } 
    }   
	else 
	{ 
		RTDMRxBufferIndex = RTDMRxBufferLoLimit; 
	} 
	 
}   
#endif 
 
#else  
	#error UART4 not avaialable on the current device 
 
#endif 
 
#else 
	#error Please define the UART to be used by RTDM in RTDMuserdef.h file 
#endif 
 
//Conditionally compile for speed performance or minimum code size. 
#if (RTDM_MIN_CODE_SIZE == NO) 
 
//When RTDM_MIN_CODE_SIZE is not defined we employ a table driven crc  
//calculation with pre-calculated polyniomial values to speed-up  
//checksum calculation time.  
 
const unsigned int crc_16_tab[] = { 
  0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 
  0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 
  0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 
  0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 
  0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, 
  0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, 
  0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, 
  0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, 
  0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, 
  0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 
  0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 
  0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 
  0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 
  0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, 
  0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, 
  0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, 
  0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, 
  0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, 
  0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 
  0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 
  0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 
  0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 
  0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, 
  0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, 
  0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, 
  0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, 
  0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, 
  0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 
  0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 
  0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 
  0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 
  0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040 
}; 
 
/****************************************************************************** 
* Function:     	RTDM_CumulativeCrc16  
				(unsigned char *buf,  
				unsigned int u16Length,  
				unsigned int u16CRC) 
* 
* Output:		return CRC16 
* 
* Overview:	This routine calculates the polynomial for the checksum byte using 
*			a coefficients table.  
*			This approach has a faster performance but consumes a higher amount of  
*			program memory 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
unsigned int RTDM_CumulativeCrc16(unsigned char *buf, unsigned int bsize, unsigned int crcSeed) 
{ 
   unsigned char * pData = buf; 
 
   while (bsize--) 
    { 
   		crcSeed = (unsigned int)(crcSeed >> 8) ^ crc_16_tab[(crcSeed ^ *pData++) & 0xff]; 
    }		 
    
  return crcSeed; 
 
} 
 
#else //This is when the _RTDM_CODE_FOOTPRINT = RTDM_MIN_SIZE 
 
 
 
/****************************************************************************** 
* Function:     	RTDM_CumulativeCrc16  
				(unsigned char *buf,  
				unsigned int u16Length,  
				unsigned int u16CRC) 
* 
* Output:		return CRC16 
* 
* Overview:	This routine calculates the polynomial for the checksum byte on the fly 
*			every time. Saves code space because no const table is required.  
*			This approach saves code space but yields slower throughput  
*			performance. 
* 
* Note:		Some processors may have more UART modules, that is why it is required to 
*			specify wich UART module is going to be used by RTDM	 
*******************************************************************************/ 
 
int wcopy; 
unsigned int RTDM_CumulativeCrc16 (unsigned char *buf, unsigned int u16Length, unsigned int u16CRC) 
{ 
	unsigned int u16Poly16   = 0xA001; // Bits 15, 13 and 0  
	unsigned int DATA_BITS   = 8;      // Number of data bits  
	unsigned int u16BitIdx; 
	unsigned int u16MsgIdx; 
	unsigned int u16MsgByte; 
 
    for ( u16MsgIdx = 0; u16MsgIdx < u16Length; u16MsgIdx++) 
	{ 
		asm("mov.w w14,_wcopy"); 
		u16MsgByte = 0x00FF & *buf++; 
		for( u16BitIdx = 0; u16BitIdx < DATA_BITS; u16BitIdx++) 
		{ 
			if ( (u16CRC ^ u16MsgByte) & 0x0001 ) 
			 { 
				 u16CRC = ( u16CRC >> 1 ) ^ u16Poly16; 
			 } 
			else 
			 { 
				u16CRC = u16CRC >> 1; 
			 } 
			 
			u16MsgByte >>= 1; // Right shift one to get to next bit  
		} 
	} 
 
	return u16CRC; 
} 
 
#endif /* End of #ifndef compilation condition. */