www.pudn.com > DeviceNet.zip > conn.c, change:2003-09-19,size:26390b


/***************************************************************************** 
 * 
 * Microchip DeviceNet Stack (Connection Object Source) 
 * 
 ***************************************************************************** 
 * FileName:        conn.c 
 * Dependencies:     
 * Processor:       PIC18F with CAN 
 * Compiler:       	C18 02.20.00 or higher 
 * Linker:          MPLINK 03.40.00 or higher 
 * Company:         Microchip Technology Incorporated 
 * 
 * Software License Agreement 
 * 
 * The software supplied herewith by Microchip Technology Incorporated 
 * (the "Company") is intended and supplied to you, the Company's 
 * customer, for use solely and exclusively with products manufactured 
 * by the Company.  
 * 
 * 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. 
 * 
 * 
 * This file contains the Connection Object managing functions. Based on a  
 * variety of conditions, events are generated for specific instances. Refer 
 * to section 5-4 of Volume 1 of the DeviceNet specification. 
 *  
 * 
 * 
 * Author               Date        Comment 
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
 * Ross Fosler			04/28/03	...	 
 *  
 *****************************************************************************/ 
 
 
 
 
#include	"dnet.def"			// Global definitions file 
#include 	"typedefs.h" 
 
#include	"conn.h"			// Internal definitions 
 
#include	"services.h"		// Service codes 
#include	"errors.h"			// Error codes 
#include	"class.h"			// Class codes 
 
#include	"route.h"			// Global symbols defined by the Router Obj 
#include	"dnet.h"			// Global symbols defined by the DeviceNet Obj 
 
#include	"CAN.h"				// CAN driver 
 
 
 
#define	_CONN_REVISION		0x01 
#define	_ATTRIB_REVISION	1 
 
 
/********************************************************************* 
 * Flag registers for read and write control 
 ********************************************************************/		 
#if USE_ACCESS == TRUE 
#pragma	udata access	_A_CONN_REGISTERS 
#endif 
NEAR FLAGS _rxFlag;			// Receive control and indication 
NEAR FLAGS _txFlag;			// Transmit control and indication 
NEAR FLAGS _txFinFlags;		// Transmit finish control and indication 
NEAR FLAGS _existentFlags;	// Indicates the existance 
NEAR FLAGS _establishFlags;	// Indicates established connections 
NEAR unsigned char _deSer;	// Control register to de-serialize transmissions 
 
 
 
 
 
#pragma	udata 
/********************************************************************* 
 * Function:        void _ConnInit(void) 
 * 
 * PreCondition:    The CAN (or other I/O) driver must be initialized 
 *					prior to calling this function. 
 * 
 * Input:       	none		 
 *                   
 * Output:      	none	 
 * 
 * Side Effects:    none 
 * 
 * Overview:        Initialize the connection object. 
 * 
 * Note:            During this process the Unconnected Explicit  
 *					Messaging and Duplicate ID Messaging connections 
 *					are created. 
 ********************************************************************/ 
void _ConnInit(void) 
{ 
	// Initialize all global connection related variables 
	_txFlag.byte = 0; 
	_rxFlag.byte = 0; 
	_txFinFlags.byte = 0; 
	_existentFlags.byte = 0; 
	_establishFlags.byte = 0; 
	_deSer = 0; 
 
	// Automatically create the duplicate ID and  
	// unconnected explicit messaging connections 
	_Conn6Create(); 
	_Conn7Create(); 
 
	// Initialize all connections to there non-existent state 
	uConn1.attrib.state == _STATE_NON_EXISTENT; 
 
	#if SUPPORT_POLLED || SUPPORT_COS_BOTH_DIR 
	uConn2.attrib.state == _STATE_NON_EXISTENT; 
	#endif 
 
	#if SUPPORT_BIT_STROBED 
	uConn3.attrib.state == _STATE_NON_EXISTENT; 
	#endif 
 
	#if SUPPORT_COS || SUPPORT_CYCLIC  
	uConn4.attrib.state == _STATE_NON_EXISTENT; 
	#endif 
 
	#if SUPPORT_MULTICAST_POLL 
	uConn5.attrib.state == _STATE_NON_EXISTENT; 
	#endif 
} 
 
 
/********************************************************************* 
 * Function:        unsigned char _ConnCreate(enum T_CONTYPE connType) 
 * 
 * PreCondition:     
 * 
 * Input:       		 
 *                   
 * Output:      	 
 * 
 * Side Effects:     
 * 
 * Overview:        Returns a handle to the connection  
 * 
 * Note:            Although a handle is returned, it is not required 
 *					to be stored since this is a static model, where 
 *					the instance numbers are fixed. 
 ********************************************************************/ 
//unsigned char _ConnCreate(CONTYPE connType) 
//{ 
//	switch (connType) 
//	{ 
//		case CONTYPE_EXPLICIT: 		return(_Conn1Create()); // Explicit messaging connection 
//		 
//		#if SUPPORT_POLLED || SUPPORT_COS_BOTH_DIR 
//		case CONTYPE_POLL: 			return(_Conn2Create());	// Poll I/O connection 
//		#endif 
// 
//		#if SUPPORT_BIT_STROBED 
//		case CONTYPE_BIT_STROBE: 	return(_Conn3Create());	// Bit-Strobe I/O connection 
//		#endif 
// 
//		#if SUPPORT_COS || SUPPORT_CYCLIC 
//		case CONTYPE_COS_CYCLIC: 	return(_Conn4Create());	// COS/Cyclic I/O connection 
//		#endif 
// 
//		#if SUPPORT_MULTICAST_POLL 
//		case CONTYPE_MULTICAST: 	return(_Conn5Create());	// Multicast Poll connection 
//		#endif 
// 
//		case CONTYPE_UNC_EXPLICIT: 	return(_Conn6Create());	// Unconnected Explicit messaging connection 
//		case CONTYPE_DUPLICATE_ID: 	return(_Conn7Create());	// Duplicate ID check message 
//		default: return (0); 
//	} 
//} 
 
 
 
 
/********************************************************************* 
 * Function:        void _ConnClose(void) 
 * 
 * PreCondition:     
 * 
 * Input:       		 
 *                   
 * Output:      	 
 * 
 * Side Effects:     
 * 
 * Overview:        Closes the specified connection  
 * 
 * Note:            None 
 ********************************************************************/ 
//void _ConnClose(unsigned char hInstance) 
//{ 
//	switch (hInstance) 
//	{ 
//		case 1:	_Conn1Close(); break; 
//		 
//		#if SUPPORT_POLLED || SUPPORT_COS_BOTH_DIR 
//		case 2:	_Conn2Close(); break; 
//		#endif 
// 
//		#if SUPPORT_BIT_STROBED 
//		case 3:	_Conn3Close(); break; 
//		#endif 
// 
//		#if SUPPORT_COS || SUPPORT_CYCLIC 
//		case 4: _Conn4Close(); break; 
//		#endif 
// 
//		#if SUPPORT_MULTICAST_POLL 
//		case 5: _Conn5Close(); break; 
//		#endif 
// 
//		case 6:	_Conn6Close(); break; 
//		case 7:	_Conn7Close(); break; 
//	} 
//} 
 
 
/********************************************************************* 
 * Function:        unsigned char _ConnReadRdy(unsigned char hInstance) 
 * 
 * PreCondition:     
 * 
 * Input:       	unsigned char handle to the instance 
 *                   
 * Output:      	unsigned char  
 * 
 * Side Effects:    none 
 * 
 * Overview:        Returns true if there is data in the read buffer  
 *					and the connection is established. 
 * 
 * Note:            None 
 ********************************************************************/ 
unsigned char _ConnReadRdy(unsigned char hInstance) 
{ 
	switch (hInstance) 
	{ 
		case 1:	return (_rxFlag.bits.expl && _establishFlags.bits.expl); 
		 
		#if SUPPORT_POLLED || SUPPORT_COS_BOTH_DIR 
		case 2:	return (_rxFlag.bits.poll && _establishFlags.bits.poll); 
		#endif 
 
		#if SUPPORT_BIT_STROBED 
		case 3:	return (_rxFlag.bits.strobe && _establishFlags.bits.strobe); 
		#endif 
 
		#if SUPPORT_COS || SUPPORT_CYCLIC 
		case 4: return (_rxFlag.bits.cos && _establishFlags.bits.cos); 
		#endif 
 
		#if SUPPORT_MULTICAST_POLL 
		case 5: return (_rxFlag.bits.multi && _establishFlags.bits.multi); 
		#endif 
 
		case 6:	return (_rxFlag.bits.uexpl); 
		case 7:	return (_rxFlag.bits.dupid); 
		default: return (0); 
	} 
} 
 
 
 
/********************************************************************* 
 * Function:        unsigned char _ConnWriteRdy(unsigned char hInstance) 
 * 
 * PreCondition:     
 * 
 * Input:       	unsigned char handle to instance 
 *                   
 * Output:      	unsigned char 
 * 
 * Side Effects:     
 * 
 * Overview:        Returns true if the buffer is available.  
 * 
 * Note:            The application must call this function prior to  
 *					loading the buffer. Otherwise any message already 
 *					queued to send will be corrupted. 
 ********************************************************************/ 
unsigned char _ConnWriteRdy(unsigned char hInstance)	 
{ 
	switch (hInstance) 
	{ 
		case 1:	return (!_txFlag.bits.expl && _establishFlags.bits.expl); 
	 
		#if SUPPORT_POLLED || SUPPORT_COS_BOTH_DIR 
		case 2:	return (!_txFlag.bits.poll && _establishFlags.bits.poll); 
		#endif 
 
		#if SUPPORT_BIT_STROBED 
		case 3:	return (!_txFlag.bits.strobe && _establishFlags.bits.strobe); 
		#endif 
 
		#if SUPPORT_COS || SUPPORT_CYCLIC 
		case 4: return (!_txFlag.bits.cos && _establishFlags.bits.cos); 
		#endif 
 
		#if SUPPORT_MULTICAST_POLL 
		case 5: return (!_txFlag.bits.multi && _establishFlags.bits.multi); 
		#endif 
 
		case 6:	return (!_txFlag.bits.uexpl); 
		case 7:	return (!_txFlag.bits.dupid); 
		default: return (0); 
	}	 
} 
 
 
/********************************************************************* 
 * Function:        unsigned char _ConnWriteFin(unsigned char hInstance) 
 * 
 * PreCondition:     
 * 
 * Input:       	unsigned char handle to instance	 
 *                   
 * Output:      	unsigned char 
 * 
 * Side Effects:     
 * 
 * Overview:        Returns true if the buffer has placed data on the bus.  
 * 
 * Note:            None 
 ********************************************************************/ 
unsigned char _ConnWriteFin(unsigned char hInstance)	 
{ 
	unsigned char temp; 
	 
	switch (hInstance) 
	{ 
		case 1:	 
			temp = _txFinFlags.bits.expl; 
			_txFinFlags.bits.expl = 0; 
			return (temp); 
 
		#if SUPPORT_POLLED || SUPPORT_COS_BOTH_DIR 
		case 2:	 
			temp = _txFinFlags.bits.poll; 
			_txFinFlags.bits.poll = 0; 
			return (temp); 
		#endif 
 
		#if SUPPORT_BIT_STROBED 
		case 3:	 
			temp = _txFinFlags.bits.strobe; 
			_txFinFlags.bits.strobe = 0; 
			return (temp); 
		#endif 
 
		#if SUPPORT_COS || SUPPORT_CYCLIC 
		case 4:  
			temp = _txFinFlags.bits.cos; 
			_txFinFlags.bits.cos = 0; 
			return (temp); 
		#endif 
 
		#if SUPPORT_MULTICAST_POLL 
		case 5:  
			temp = _txFinFlags.bits.multi; 
			_txFinFlags.bits.multi = 0; 
			return (temp); 
		#endif 
 
		case 6:	 
			temp = _txFinFlags.bits.uexpl; 
			_txFinFlags.bits.uexpl = 0; 
			return (temp); 
			 
		case 7:	 
			temp = _txFinFlags.bits.dupid; 
			_txFinFlags.bits.dupid = 0; 
			return (temp); 
			 
		default: return (0); 
	}	 
} 
 
/********************************************************************* 
 * Function:        void _ConnRead(unsigned char hInstance) 
 * 
 * PreCondition:  	Function _ConnReadRdy() should be executed prior 
 *					to calling this function to determine if data has 
 *					been received.   
 * 
 * Input:       	unsigned char handle to instance		 
 *                   
 * Output:      	none	 
 * 
 * Side Effects:     
 * 
 * Overview:        Indicates to the Connection Object that the data  
 *					has been read and the buffer is free to take  
 *					another message. 
 * 
 * Note:            The function is only executed successfully if 
 *					the connection is established. 
 ********************************************************************/ 
void _ConnRead(unsigned char hInstance) 
{ 
	switch (hInstance) 
	{ 
		case 1:	if (_establishFlags.bits.expl) _rxFlag.bits.expl = 0; break; 
  
		#if SUPPORT_POLLED || SUPPORT_COS_BOTH_DIR 
		case 2:	if (_establishFlags.bits.poll) _rxFlag.bits.poll = 0; break; 
		#endif 
 
		#if SUPPORT_BIT_STROBED 
		case 3:	if (_establishFlags.bits.strobe) _rxFlag.bits.strobe = 0; break; 
		#endif 
 
		#if SUPPORT_COS || SUPPORT_CYCLIC 
		case 4: if (_establishFlags.bits.cos) _rxFlag.bits.cos = 0; break; 
		#endif 
 
		#if SUPPORT_MULTICAST_POLL 
		case 5: if (_establishFlags.bits.multi) _rxFlag.bits.multi = 0; break; 
		#endif 
 
		case 6:	_rxFlag.bits.uexpl = 0; break; 
		case 7:	_rxFlag.bits.dupid = 0; break; 
	} 
}	 
 
 
 
/********************************************************************* 
 * Function:        void _ConnWrite(unsigned char hInstance) 
 * 
 * PreCondition:	Execute _ConnWriteRdy() to determine if the buffer 
 *					is available before executing this function. Also 
 *					load the buffer prior to sending.      
 * 
 * Input:       	unsigned char handle to instance	 
 *                   
 * Output:      	none 
 * 
 * Side Effects:     
 * 
 * Overview:        Indicates to the Connection object instance that  
 * 					all data has been loaded and the connection 
 *					is free to transmit.  
 * 
 * Note:            The queue bit for the specified connection is set. 
 *					 
 ********************************************************************/ 
void _ConnWrite(unsigned char hInstance)	 
{ 
	switch (hInstance) 
	{ 
		case 1:	if (_establishFlags.bits.expl) _txFlag.bits.expl = 1; break;	 
 
		#if SUPPORT_POLLED || SUPPORT_COS_BOTH_DIR 
		case 2:	if (_establishFlags.bits.poll) _txFlag.bits.poll = 1; break; 
		#endif 
 
		#if SUPPORT_BIT_STROBED 
		case 3:	if (_establishFlags.bits.strobe) _txFlag.bits.strobe = 1; break;	 
		#endif 
 
		#if SUPPORT_COS || SUPPORT_CYCLIC 
		case 4: if (_establishFlags.bits.cos) _txFlag.bits.cos = 1; break; 
		#endif 
 
		#if SUPPORT_MULTICAST_POLL 
		case 5: if (_establishFlags.bits.multi) _txFlag.bits.multi = 1; break;		 
		#endif 
 
		case 6:	_txFlag.bits.uexpl = 1; break; 
		case 7:	_txFlag.bits.dupid = 1; break; 
	} 
} 
 
 
/********************************************************************* 
 * Function:        unsigned char _ConnBusOffErr(void) 
 * 
 * PreCondition:     
 * 
 * Input:       	none	 
 *                   
 * Output:      	unsigned char  
 * 
 * Side Effects:     
 * 
 * Overview:        If a bus-off event has occured then return TRUE 
 * 
 * Note:            None 
 ********************************************************************/ 
unsigned char _ConnBusOffErr(void) 
{ 
	return(uDNet.BusOffCount == 255); 
} 
 
 
 
 
 
/********************************************************************* 
 * Function:        unsigned char _ConnRxManager(void) 
 * 
 * PreCondition:    CAN (or other I/O) driver must be ready 
 * 
 * Input:       	none	 
 *                   
 * Output:      	unsigned char 
 * 
 * Side Effects:     
 * 
 * Overview:        This function handles any received data events 
 *					from the driver and dispaches them to the  
 *					appropriate instance. 
 * 
 * Note:            This function filters through the identifiers. 
 *					Any messages that cannot be processed are ignored. 
 *					This function also returns true if an event was 
 *					generated in an instance. 
 ********************************************************************/ 
unsigned char _ConnRxManager(void) 
{ 
	//NEAR USINT work; 
	UINT work; 
 
	//If there is data in the rx buffer then process 
	if (CANIsRxRdy()) 
	{		    
		// Decode the CID (group 2 only, filtering assumed) 
		work.word = CANGetRxCID() & 0xE0; 
 
		 
		switch(work.bytes.LSB) 
		{ 
			#if SUPPORT_BIT_STROBED 
			case 0x00: 
				if (!_rxFlag.bits.strobe && _establishFlags.bits.strobe) {_Conn3RxEvent(); return(3);} 
				break; 
			#endif 
			#if SUPPORT_MULTICAST_POLL 
			case 0x20: 
			 	if (!_rxFlag.bits.multi && _establishFlags.bits.multi) {_Conn5RxEvent(); return(5);} 
				break; 
			#endif 
			#if SUPPORT_COS || SUPPORT_CYCLIC 
			case 0x40: 
				if (!_rxFlag.bits.cos && _establishFlags.bits.cos) {_Conn4RxEvent(); return(4);}  
				break; 
			#endif 
			case 0x80: 
				if (!_rxFlag.bits.expl && _existentFlags.bits.expl) {_Conn1RxEvent(); return(1);}  
				break; 
			#if SUPPORT_POLLED || SUPPORT_COS_BOTH_DIR 
			case 0xA0: 
				if (!_rxFlag.bits.poll && _establishFlags.bits.poll) {_Conn2RxEvent(); return(2);}  
				break; 
			#endif 
			case 0xC0: 
				if (!_rxFlag.bits.uexpl) _Conn6RxEvent(); return(6); 
			case 0xE0: 
				if (!_rxFlag.bits.dupid) _Conn7RxEvent(); return(7);	 
		} 
 
		CANRead(); 
		return(0); 
	} 
} 
 
 
 
 
/********************************************************************* 
 * Function:        void _ConnTxOpenManager(void) 
 * 
 * PreCondition:   	The connection must be open and available. 
 * 
 * Input:       	none		 
 *                   
 * Output:      	none 
 * 
 * Side Effects:     
 * 
 * Overview:        If a message is queued from any connection and 
 *					the output buffer is available, then this function 
 *					issues an event to the connection instance queued  
 *					to transmit. 
 * 
 * Note:            The queue is deserialized to eliminate software 
 *					imposed priority on the messages. 
 ********************************************************************/ 
void _ConnTxOpenManager(void) 
{	 
	//If the tx buffer is open and one or more connections are requesting 
	//to transmit, then procede to transmit 
	if (_txFlag.byte && CANIsTxRdy()) 
	{ 
		// Set a new entry point into the loop 
		_deSer++; 
 
		// The use of goto in this section is applied to create   
		// multiple entry points into a loop. This has the affect 
		// of removing sequencial priority when supporting multiple 
		// endpoints on an single serial connection. 
		if (_deSer == 1) goto _ConnTxOpenManagerJp1; 
		if (_deSer == 2) goto _ConnTxOpenManagerJp2; 
		if (_deSer == 3) goto _ConnTxOpenManagerJp3; 
		if (_deSer == 4) goto _ConnTxOpenManagerJp4; 
		if (_deSer == 5) goto _ConnTxOpenManagerJp5; 
		if (_deSer == 6) goto _ConnTxOpenManagerJp6; 
		if (_deSer == 7) {_deSer = 0; goto _ConnTxOpenManagerJp7;} 
		_deSer = 0; 
									   
		while (1) 
		{ 
_ConnTxOpenManagerJp1: 
			if (_txFlag.bits.expl) 
			{ 
				if (_establishFlags.bits.expl) _Conn1TxOpenEvent();  
				else _txFlag.bits.expl = 0; 
				return; 
			} 
			else 
 
_ConnTxOpenManagerJp2: 
			#if SUPPORT_POLLED || SUPPORT_COS_BOTH_DIR 
			if (_txFlag.bits.poll) 
			{ 
				if (_establishFlags.bits.poll) _Conn2TxOpenEvent();  
				else _txFlag.bits.poll = 0; 
				return; 
			} 
			else 
			#endif 
 
_ConnTxOpenManagerJp3: 
			#if SUPPORT_BIT_STROBED 
			if (_txFlag.bits.strobe) 
			{ 
				if (_establishFlags.bits.strobe) _Conn3TxOpenEvent();  
				else _txFlag.bits.strobe = 0; 
				return; 
			} 
			else 
			#endif 
 
_ConnTxOpenManagerJp4: 
			#if SUPPORT_COS || SUPPORT_CYCLIC 
			if (_txFlag.bits.cos) 
			{ 
				if (_establishFlags.bits.cos) _Conn4TxOpenEvent();  
				else _txFlag.bits.cos = 0; 
				return; 
			} 
			else 
			#endif 
 
_ConnTxOpenManagerJp5: 
			#if SUPPORT_MULTICAST_POLL 
			if (_txFlag.bits.multi) 
			{ 
				if (_establishFlags.bits.multi) _Conn5TxOpenEvent();  
				else _txFlag.bits.multi = 0; 
				return; 
			} 
			else 
			#endif 
			 
_ConnTxOpenManagerJp6: 
			if (_txFlag.bits.uexpl)  
				{_Conn6TxOpenEvent();  return;} 
			else 
 
_ConnTxOpenManagerJp7: 
			if (_txFlag.bits.dupid)  
				{_Conn7TxOpenEvent(); return;} 
		} 
	} 
} 
 
 
/********************************************************************* 
 * Function:        void _ConnTxManager(void) 
 * 
 * PreCondition:  	This function assumes the connection instance has 
 *					been created (enabled). 	 
 * 
 * Input:       	none	 
 *                   
 * Output:      	none 
 * 
 * Side Effects:     
 * 
 * Overview:        If a message has finished transmitting, then the  
 *					initiator is traced and notified about the  
 *					transmission. 
 * 
 * Note:            None 
 ********************************************************************/ 
void _ConnTxManager(void) 
{ 
	unsigned char instance; 
 
	instance = CANIsMsgSent(); 
 
	// If a message has been transmitted on the bus 
	// then who transmitted 
	if (instance) 
	{ 
		if (instance == 1) {_Conn1TxEvent();} 
		else 
		 
		#if SUPPORT_POLLED || SUPPORT_COS_BOTH_DIR 
		if (instance == 2) {_Conn2TxEvent();} 
		else 
		#endif 
 
		#if SUPPORT_BIT_STROBED 
		if (instance == 3) {_Conn3TxEvent();} 
		else 
		#endif 
 
		#if SUPPORT_COS || SUPPORT_CYCLIC 
		if (instance == 4) {_Conn4TxEvent();} 
		else 
		#endif 
 
		#if SUPPORT_MULTICAST_POLL 
		if (instance == 5) {_Conn5TxEvent();} 
		else 
		#endif 
 
		if (instance == 6) {_Conn6TxEvent();} 
		else 
		if (instance == 7) {_Conn7TxEvent();} 
	} 
} 
 
 
/********************************************************************* 
 * Function:        void _ConnErrorManager(void) 
 * 
 * PreCondition:     
 * 
 * Input:       	none	 
 *                   
 * Output:      	none 
 * 
 * Side Effects:     
 * 
 * Overview:        This function captures any bus-off errors from 
 *					the driver. 
 * 
 * Note:            None 
 ********************************************************************/ 
void _ConnErrorManager(void) 
{ 
	//If there is a bus off error then 
	if (CANIsBusOffError()) 
	{ 
		// Increment the counter up to 255 
		if (uDNet.BusOffCount < 255) uDNet.BusOffCount++; 
	} 
} 
 
 
 
/********************************************************************* 
 * Function:        void _ConnTimeManager(void) 
 * 
 * PreCondition:    This function must be called periodically  
 *					according to the specified tick rate. 
 * 
 * Input:       	none 
 *                   
 * Output:      	none 
 * 
 * Side Effects:     
 * 
 * Overview:        Process timer events.  
 * 
 * Note:            Each connection manages there own timer. 
 ********************************************************************/ 
void _ConnTimeManager(void) 
{ 
	//Process all timer events 
	if (_establishFlags.bits.expl) _Conn1TimerEvent(); 
 
	#if SUPPORT_POLLED || SUPPORT_COS_BOTH_DIR 
	if (_establishFlags.bits.poll) _Conn2TimerEvent(); 
	#endif 
 
	#if SUPPORT_BIT_STROBED 
	if (_establishFlags.bits.strobe) _Conn3TimerEvent(); 
	#endif 
	 
	#if SUPPORT_COS || SUPPORT_CYCLIC 
	if (_establishFlags.bits.cos) _Conn4TimerEvent();	 
	#endif 
	 
	#if SUPPORT_MULTICAST_POLL 
	if (_establishFlags.bits.multi) _Conn5TimerEvent();	 
	#endif 
} 
 
 
 
 
 
 
/********************************************************************* 
 * Function:        void _ConnStateManager(void) 
 * 
 * PreCondition:     
 * 
 * Input:   		none    		 
 *                   
 * Output:      	none 
 * 
 * Side Effects:     
 * 
 * Overview:        Synchronize all connection states. 
 * 
 * Note:            Connection may be deleted. 
 ********************************************************************/ 
void _ConnStateManager(void) 
{ 
	BYTE release; 
 
	if (_existentFlags.bits.expl) 
	{ 
		// Process all stale connections 
		switch (uConn1.attrib.state) 
		{ 
			// if conn 1 is deferred and all I/O connections no not exist  
			// or are timed out then delete all connections 
			case _STATE_DEFERED_DELETE: 
				#if SUPPORT_POLLED || SUPPORT_COS_BOTH_DIR 
				if (_establishFlags.bits.poll) break; 
				#endif 
				#if SUPPORT_BIT_STROBED 
				if (_establishFlags.bits.strobe) break; 
				#endif 
				#if SUPPORT_COS || SUPPORT_CYCLIC 
				if (_establishFlags.bits.cos) break; 
				#endif 
				#if SUPPORT_MULTICAST_POLL 
				if (_establishFlags.bits.multi) break; 
				#endif 
				 
													 
			// If the explicit messaging connection has transisioned to  
			// to non-exixtent then delete all other connections 
			case _STATE_NON_EXISTENT: 
				release.byte = uDNet.AllocInfo.AllocChoice.byte; 
							 
				// Release all allocated connections 
				_DNetCloseConnections(release); 
				 
				// Kill all allocated connections 
				uDNet.AllocInfo.AllocChoice.byte = 0; 
				uDNet.AllocInfo.MasterMACID = 0xFF;		 
		} 
	} 
} 
 
 
 
 
/********************************************************************* 
 * Function:        unsigned char _ConnExplicitEvent() 
 * 
 * PreCondition:    This function is called from the router. 
 * 
 * Input:       	none 
 *                   
 * Output:      	unsigned char 
 * 
 * Side Effects:     
 * 
 * Overview:        Handle explicit messaging.  
 * 
 * Note:            None 
 ********************************************************************/ 
unsigned char _ConnExplMsgHandler(void) 
{ 
	if (mRouteGetInstanceID() == 0) 
	{ 
		switch(mRouteGetServiceID()) 
	   	{ 
	   		case SRVS_GET_ATTRIB_SINGLE: 
	   			return (_ConnInst0GetAttrib()); 
	   		default: 
	   			mRoutePutError(ERR_SERVICE_NOT_SUPPORTED); 
	   			break; 
	   	} 
	} 
	else  
 
	if ((mRouteGetInstanceID() == 1) && _existentFlags.bits.expl) 
		return(_Conn1ExplicitEvent()); 
	else 
 
	#if SUPPORT_POLLED || SUPPORT_COS_BOTH_DIR 
	if ((mRouteGetInstanceID() == 2) && _existentFlags.bits.poll) 
		return(_Conn2ExplicitEvent()); 
	else 
	#endif 
 
	#if SUPPORT_BIT_STROBED 
	if ((mRouteGetInstanceID() == 3) && _existentFlags.bits.strobe) 
		return(_Conn3ExplicitEvent()); 
	else 
	#endif 
 
	#if SUPPORT_COS || SUPPORT_CYCLIC 
	if ((mRouteGetInstanceID() == 4) && _existentFlags.bits.cos) 
		return(_Conn4ExplicitEvent()); 
	else 
	#endif 
 
	#if SUPPORT_MULTICAST_POLL  
	if ((mRouteGetInstanceID() == 5) && _existentFlags.bits.multi) 
		return(_Conn5ExplicitEvent()); 
	else 
	#endif 
 
	{ 
		mRoutePutError(ERR_OBJECT_DOES_NOT_EXIST);	 
	}		 
	return (1); 
} 
 
 
/********************************************************************* 
 * Function:        unsigned char _ConnInst0GetAttrib(void) 
 * 
 * PreCondition:     
 * 
 * Input:       	none 
 *                   
 * Output:      	unsigned char 
 * 
 * Side Effects:     
 * 
 * Overview:        Handle explicit messaging get attribute. 
 * 
 * Note:            None 
 ********************************************************************/ 
unsigned char _ConnInst0GetAttrib(void) 
{	 
	switch (mRouteGetAttributeID()) 
	{ 
		case _ATTRIB_REVISION: 
			mRoutePutByte(_CONN_REVISION & 0xFF); 
			mRoutePutByte((_CONN_REVISION & 0xFF00) >> 8); 
			break; 
				 
		default: 
			mRoutePutError(ERR_ATTRIB_NOT_SUPPORTED); 
			break; 
	} 
  	return (1); 
}