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


/***************************************************************************** 
 * 
 * Microchip DeviceNet Stack  
 * (Network Access State Machine management source code) 
 * 
 ***************************************************************************** 
 * FileName:        NASM.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 Network Access State Machine (NASM) managing  
 * functions. All the functions work closely with the Duplicate ID messaging 
 * provided by the connection object. Refer to Chapter 6 of Volume 1 of the  
 * DeviceNet Specification for more information. 
 *  
 * 
 * 
 * Author               Date        Comment 
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
 * Ross Fosler			06/06/03	...	 
 *  
 *****************************************************************************/ 
 
 
#include	"dnet.def"				// Global definitions file 
#include 	"typedefs.h" 
 
#include	"nasm.h"				// Internal definitions 
 
#include	"services.h"			// Service codes 
#include	"errors.h"				// Error codes 
#include	"class.h"				// Class codes 
				 
#include 	"conn.h"				// Connection object  
#include	"dnet.h"				// DeviceNet Object 
#include	"ident.h" 				// Identity Object 
 
 
/********************************************************************* 
 * Common control registers 
 ********************************************************************/ 
#if USE_ACCESS == 1 
#pragma	udata access	_A_GO_DNET_FUNCTIONS 
#endif 
NEAR BYTE _aNASMInternalCtl; 
NEAR USINT _aNASMStates; 
NEAR UINT _aNASMWaitTimer; 
NEAR USINT _aNASMBaud; 
 
 
 
/********************************************************************* 
 * Function:        void _NASMAutoBaudStateManager(void) 
 * 
 * PreCondition:  	none   
 * 
 * Input:       	none			 
 *                   
 * Output:     		none 
 * 	 
 * Side Effects:   	none  
 * 
 * Overview:        This function attempts to determine the baud rate 
 *					by using the Duplicate ID messaging.   
 * 
 * Note:            none 
 ********************************************************************/ 
 #if (0) 
void _NASMAutoBaudStateManager(void) 
{ 
	// If baud rate switch value is not valid  
	if (uDNet.BaudSwValue > 2) 
	{ 
		// If no bus off error 
		if (!_ConnBusOffErr()) 
		{ 
			// If write not yet finished 
			if (!_ConnWriteFin(7)) 
			{ 
				// If the write buffer is available	and not previously locked 
				if (_ConnWriteRdy(7) && !_aNASMInternalCtl.bits.b0)  
				{ 
					// Prevent re-entry 
					_aNASMInternalCtl.bits.b0 = 1; 
 
					// Send duplicate ID		  
					_NASMWriteDuplicateID(0x00); 
					_ConnWrite(7); 
				} 
			} 
 
			// Write to bus successful, baud rate good 
			else 
			{ 
				// Release the internal write lock 
				_aNASMInternalCtl.bits.b0 = 0; 
 
				// Change to the waiting state 
				_aNASMStates = _NASM_WAITING_DID; 
 
				// Notify app of the baud rate for saving	TODO 
			} 
		} 
 
		// bus off error 
		else 
		{ 
			if (_aNASMBaud < 2) 
			{ 
				_aNASMBaud++; 
 
				// Go off bus					TODO 
				// reset the bit rate 
				// Go on bus 
			} 
			else 
			{ 
				// Transfer to FAULT state 
				_aNASMStates = _NASM_COMM_FAULT; 
			} 
		} 
	} 
 
	// Valid baud rate  
	else 
	{ 
		// Go back to the sending state 
		_aNASMStates = _NASM_SENDING_DID; 
	} 
} 
#endif 
 
 
 
/********************************************************************* 
 * Function:        void _NASMSendingDupIDStateManagder(void) 
 * 
 * PreCondition:  	none   
 * 
 * Input:       	none			 
 *                   
 * Output:     		none 
 * 	 
 * Side Effects:   	none  
 * 
 * Overview:        This function manages Duplicate ID messaging while 
 *					in the Sending Duplicate ID state.   
 * 
 * Note:            none 
 ********************************************************************/ 
void _NASMSendingDupIDStateManagder(void) 
{ 
	// If there is no bus off error 
	if (!_ConnBusOffErr()) 
	{ 
		// If there is no data in the read buffer 
		if (!_ConnReadRdy(7)) 
		{ 
			// If no data from this connection has been placed on the bus 
			if (!_ConnWriteFin(7)) 
			{ 
				// If the write buffer is available and not previously locked 
				if (_ConnWriteRdy(7) && !_aNASMInternalCtl.bits.b0) // and internal lock 
				{ 
					// Prevent re-entry 
					_aNASMInternalCtl.bits.b0 = 1; 
				 
					// Send duplicate ID					 
					_NASMWriteDuplicateID(0x00); 
					_ConnWrite(7); 
				} 
			} 
			 
			// Data has been placed on the bus 
			else 
			{ 
				// Release the internal write lock 
				_aNASMInternalCtl.bits.b0 = 0; 
				 
				// Change to the waiting state 
				_aNASMStates = _NASM_WAITING_DID; 
				 
				// Start timer at 1000ms 
				_aNASMWaitTimer.word = 1000; 
			} 
		} 
		 
		// Connection received a Duplicate ID 
		else 
		{ 
			// If rec DID then transfer to FAULT 
			_aNASMStates = _NASM_COMM_FAULT; 
			_ConnRead(7); 
		} 
	} 
	 
	// Bus error, goto fault state 
	else 
	{ 
		_aNASMStates = _NASM_COMM_FAULT; 
	} 
} 
 
 
 
 
/********************************************************************* 
 * Function:        void _NASMWaitingForDupIDStateManager(void) 
 * 
 * PreCondition:  	none   
 * 
 * Input:       	none			 
 *                   
 * Output:     		none 
 * 	 
 * Side Effects:   	none  
 * 
 * Overview:        This function manages Duplicate ID messaging while 
 *					in the Waiting for Duplicate ID state.   
 * 
 * Note:            none 
 ********************************************************************/ 
void _NASMWaitingForDupIDStateManager(void) 
{ 
	// If there is no bus off error 
	if (!_ConnBusOffErr()) 
	{ 
		// If there is no data in the read buffer 
		if (!_ConnReadRdy(7)) 
		{ 
			// If timer expired 
			if (_aNASMInternalCtl.bits.b2) 
			{ 
				// Reset the timer flag 
				_aNASMInternalCtl.bits.b2 = 0; 
			 
				// If this is the second wait sequence then  
				if (_aNASMInternalCtl.bits.b1) 
				{ 
					// Go on-line 
					_aNASMStates = _NASM_ON_LINE; 
					_aNASMInternalCtl.bits.b1 = 0; 
				} 
				 
				// This is the first wait time out 
				else 
				{ 
					// Go back to the sending state 
					_aNASMStates = _NASM_SENDING_DID; 
					_aNASMInternalCtl.bits.b1 = 1; 
				} 
			} 
		} 
		 
		// Connection received a Duplicate ID 
		else 
		{ 
			// If rec DID then transfer to FAULT 
			_aNASMStates = _NASM_COMM_FAULT; 
			_ConnRead(7); 
		} 
	} 
	 
	// Bus error, goto fault state 
	else 
	{ 
		_aNASMStates = _NASM_COMM_FAULT; 
	} 
} 
 
 
 
 
/********************************************************************* 
 * Function:        void _NASMOnLineStateManager(void) 
 * 
 * PreCondition:  	none   
 * 
 * Input:       	none			 
 *                   
 * Output:     		none 
 * 	 
 * Side Effects:   	none  
 * 
 * Overview:        This function manages Duplicate ID messaging while 
 *					in the on-line state.   
 * 
 * Note:            none 
 ********************************************************************/ 
void _NASMOnLineStateManager(void) 
{ 
	// If there is no bus off error 
	if (!_ConnBusOffErr()) 
	{ 
		// If duplicate ID has been received 
		if (_ConnReadRdy(7)) 
		{ 
			// If the duplicate ID is a response 
			if (((BYTE *)uConn7.rx.pMsg)->bits.b7) 
			{ 
				_aNASMStates = _NASM_COMM_FAULT; 
			} 
			 
			// the duplicate ID is a request 
			else 
			{ 
				// If the write buffer is available 
				if (_ConnWriteRdy(7)) 
				{ 
					// Send DID				 
					_NASMWriteDuplicateID(0x80); 
					_ConnWrite(7); 
				} 
			} 
			 
			// Release the buffer to accept more data 
			_ConnRead(7);			 
		} 
	} 
	 
	// Bus off error 
	else 
	{ 
		// Hold in reset 
		if (mDNetGetBOI() == 0) 
		{ 
			// If rec DID then transfer to FAULT 
			_aNASMStates = _NASM_COMM_FAULT; 
		} 
		else 
 
		// Automatic reset 
		if (mDNetGetBOI() == 1) 
		{ 
			// Go back to the sending state 
			_aNASMStates = _NASM_SENDING_DID;		// May need to add code to recover last running mode 
		} 
	} 
} 
 
 
 
 
 
 
/********************************************************************* 
 * Function:        void _NASMWaitTimeManager(void) 
 * 
 * PreCondition:  	none   
 * 
 * Input:       	none			 
 *                   
 * Output:     		none 
 * 	 
 * Side Effects:   	none  
 * 
 * Overview:        This funcion adjusts the Network Access State  
 *					Machine timer.   
 * 
 * Note:            none 
 ********************************************************************/ 
void _NASMWaitTimeManager(void) 
{ 
	// Update the time for network wait to be established 
	if (_aNASMWaitTimer.word) 
	{ 
		// Adjust the time 
		_aNASMWaitTimer.word -= TICK_RESOLUTION; 
	} 
	else 
	{		 
		// Set flag indicating the time has expired 
		_aNASMInternalCtl.bits.b2 = 1; 
	}		 
} 
 
 
 
 
/********************************************************************* 
 * Function:        void _NASMWriteDuplicateID(void) 
 * 
 * PreCondition:     
 * 
 * Input:       			 
 *                   
 * Output:      
 * 	 
 * Side Effects:     
 * 
 * Overview:        Write the Vendor ID and Serial number to the 
 *					transmit buffer.   
 * 
 * Note:            None 
 ********************************************************************/ 
void _NASMWriteDuplicateID(NEAR unsigned char portNoAndReq) 
{ 
	*((unsigned char *)uConn7.tx.pMsg) = portNoAndReq; 
	*((unsigned char *)(uConn7.tx.pMsg + 1)) = mIdentityGetVendorIDL(); 
	*((unsigned char *)(uConn7.tx.pMsg + 2)) = mIdentityGetVendorIDH(); 
	*((unsigned char *)(uConn7.tx.pMsg + 3)) = mIdentityGetSerialL(); 
	*((unsigned char *)(uConn7.tx.pMsg + 4)) = mIdentityGetSerialH(); 
	*((unsigned char *)(uConn7.tx.pMsg + 5)) = mIdentityGetSerialUL(); 
	*((unsigned char *)(uConn7.tx.pMsg + 6)) = mIdentityGetSerialUH(); 
 
	uConn7.tx.len = 7; 
} 
 
 
 
 
 
/********************************************************************* 
 * Function:        void _NASMInit(void) 
 * 
 * PreCondition:     
 * 
 * Input:       			 
 *                   
 * Output:      
 * 	 
 * Side Effects:     
 * 
 * Overview:        Initialize the Network Access State Machine.   
 * 
 * Note:            None 
 ********************************************************************/ 
void _NASMInit(void) 
{ 
	// Reset network access states 
	_aNASMStates = 1; 
	 
	// Reset network access state control bits 
	_aNASMInternalCtl.byte = 0; 
 
	// Reset the autobaud  
	//_aNASMBaud = 0; 
 
}