⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 co_sdo1.c

📁 在pic单片机上实现canopen协议通讯
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
 *
 * Microchip CANopen Stack (The Default SDO)
 *
 *****************************************************************************
 * FileName:        CO_SDO1.C
 * Dependencies:    
 * Processor:       PIC18F with CAN
 * Compiler:       	C18 02.30.00 or higher
 * Linker:          MPLINK 03.70.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.
 *
 *
 * 
 * 
 *
 *
 * Author               Date        Comment
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Ross Fosler			11/13/03	...	
 * 
 *****************************************************************************/


#include	"CO_DEFS.DEF"			// Global definitions
#include	"CO_TYPES.H"			// Data types
#include	"CO_ABERR.H"			// Abort types
#include	"CO_CANDRV.H"			// Driver services
#include	"CO_COMM.H"				// Object
#include	"CO_DICT.H"				// Dictionary Object Services
#include	"CO_TOOLS.H"			// COB ID tools









union _SDO_CTL
{
	unsigned char byte;
	struct _SDO_INITIATE_CTL
	{
		unsigned s:1;
		unsigned e:1;
		unsigned n:2;
		unsigned x:1;
		unsigned cmd:3;	
	}ictl;
	struct _SDO_REGULAR_CTL
	{
		unsigned c:1;
		unsigned n:3;
		unsigned t:1;
		unsigned cmd:3;
	}rctl;
	struct _SDO_RESPONSE
	{
		unsigned x:4;
		unsigned t:1;
		unsigned cmd:3;
	}rsp;
};

union _SDO_STATE
{
	unsigned char byte;
	struct _SDO_STATE_BITS
	{
		unsigned :3;
		unsigned ntime:1;
		unsigned tog:1;
		unsigned start:1;
		unsigned dnld:1;	
		unsigned abrt:1;
	}bits;
};


rom unsigned char 	_uSDO1COMMIndx = 3;	// The length of the object

UNSIGNED32 			_uSDO1_CS_COBID;	// COB IDs used by the default SDO
UNSIGNED32 			_uSDO1_SC_COBID;

unsigned char 		_hSDO1;				// Handle to the connection

union _SDO_STATE	_uSDO1State;		// State bitmap for this SDO
REQ_STAT			_uSDO1ACode;		// Abort code
union _SDO_CTL 		_uSDO1Ctl;			// Received control byte buffer
DICT_OBJ			_uSDO1Dict;			// Local dictionary object, loaded during inits
unsigned int	 	_uSDO1Timer;		// Watchdog, defined by the application
UNSIGNED16	 		_uSDO1BytesLeft;	// Bytes to send

/* Buffers used in this design */
unsigned char		_uSDO1RxBuf[CO_SDO1_MAX_RX_BUF];	// Receive space for downloads
unsigned char 		_uSDO1TxBuf[8];		// Transmit space for uploads



/*********************************************************************
 * Function:        void _CO_COMM_SDO1_CS_COBIDAccessEvent(void)
 *
 * PreCondition:    
 *
 * Input:       	none
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        Process any access events to the SDO client to
 *					server COB ID.
 *
 * Note:          	
 ********************************************************************/
// Process access events to the COB ID
void _CO_COMM_SDO1_CS_COBIDAccessEvent(void)
{
	switch (mCO_DictGetCmd())
	{
		case DICT_OBJ_READ: 	// Read the object
			// Translate MCHP COB to CANopen COB
			mTOOLS_MCHP2CO(_uSDO1_CS_COBID.word);

			// Return the COBID
			*(unsigned long *)(uDict.obj->pReqBuf) = mTOOLS_GetCOBID();				
			break;
	}	
}


/*********************************************************************
 * Function:        void _CO_COMM_SDO1_SC_COBIDAccessEvent(void)
 *
 * PreCondition:    
 *
 * Input:       	none
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        Process any access events to the SDO server to
 *					client COB ID.
 *
 * Note:          	
 ********************************************************************/
// Process access events to the COB ID
void _CO_COMM_SDO1_SC_COBIDAccessEvent(void)
{
	switch (mCO_DictGetCmd())
	{
		case DICT_OBJ_READ: 	// Read the object
			// Translate MCHP COB to CANopen COB
			mTOOLS_MCHP2CO(_uSDO1_SC_COBID.word);

			// Return the COBID
			*(unsigned long *)(uDict.obj->pReqBuf) = mTOOLS_GetCOBID();				
			break;
	}
}






/*********************************************************************
 * Function:        void _CO_COMM_SDO1_Open(void)
 *
 * PreCondition:    
 *
 * Input:       	none
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        This function opens the default SDO
 *					communications.
 *
 * Note:          	
 ********************************************************************/
void _CO_COMM_SDO1_Open(void)
{	
	// Set the client to server COB ID and convert it to MCHP
	_uSDO1_CS_COBID.word = 0x600L + _uCO_nodeID.byte;
	mTOOLS_CO2MCHP(_uSDO1_CS_COBID.word);
	_uSDO1_CS_COBID.word = mTOOLS_GetCOBID();

	// Set the server to client COB ID and convert it to MCHP
	_uSDO1_SC_COBID.word = 0x580L + _uCO_nodeID.byte;
	mTOOLS_CO2MCHP(_uSDO1_SC_COBID.word);
	_uSDO1_SC_COBID.word = mTOOLS_GetCOBID();

	// Open a receive message endpoint in the driver
	mCANOpenMessage(COMM_MSGGRP_SDO | COMM_SDO_1, _uSDO1_CS_COBID.word, _hSDO1);
	if (_hSDO1) COMM_SDO_1_EN = 1;
	
	// Reset internal variables
	_uSDO1State.byte = 0;
}


/*********************************************************************
 * Function:        void _CO_COMM_SDO1_Close(void)
 *
 * PreCondition:    
 *
 * Input:       	none
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        This function closes the default SDO
 *					communications.
 *
 * Note:          	
 ********************************************************************/
void _CO_COMM_SDO1_Close(void)
{
	// Call the driver, request to close the receive endpoint
	mCANCloseMessage(_hSDO1);
	COMM_SDO_1_EN = 0;
}











/*********************************************************************
 * Function:        void _CO_COMM_SDO1_LSTimerEvent(void)
 *
 * PreCondition:    
 *
 * Input:       	none
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        This is the low-speed timer event handler for 
 *					the SDO1 endpoint.
 *
 * Note:          	
 ********************************************************************/
void _CO_COMM_SDO1_LSTimerEvent(void)
{
	// Process only if the connection is in the middle of active segmented comm
	if (_uSDO1State.bits.start)
	{		
		// Adjust the time						TODO
		_uSDO1Timer -= CO_TICK_PERIOD;
		
		// Reset SDO1 states if a timeout while receiving
		if ((signed int)_uSDO1Timer <= 0)
		{
			// Reset the states
			_uSDO1State.byte = 0;
			
			// Queue an abort, SDO timeout	
			_uSDO1ACode = E_SDO_TIME;
			COMM_SDO_1_TF = 1;
		}
	}
}




/*********************************************************************
 * Function:        void _CO_COMM_SDO1_TXEvent(void)
 *
 * PreCondition:    
 *
 * Input:       	none
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        This is the SDO1 transmit event handler.
 *
 * Note:          	
 ********************************************************************/
void _CO_COMM_SDO1_TXEvent(void)
{
	// Set the CID
	*(unsigned long *)(mCANGetPtrTxCOB()) = _uSDO1_SC_COBID.word;
	
	// Set the length
	mCANPutDataLen(8);
	
	if (_uSDO1ACode == E_SUCCESS) 
	{
		// Move the data to the transmit buffer
		*(_DATA8 *)(mCANGetPtrTxData()) = *(_DATA8 *)_uSDO1TxBuf;
	}
	else 
	{
		// Set the abort code
		*(mCANGetPtrTxData()) = 0x80;

		// Set the multiplexor
		*(mCANGetPtrTxData() + 1) = ((UNSIGNED16 *)(&(_uSDO1Dict.index)))->bytes.B0.byte;
		*(mCANGetPtrTxData() + 2) = ((UNSIGNED16 *)(&(_uSDO1Dict.index)))->bytes.B1.byte;
		*(mCANGetPtrTxData() + 3) = _uSDO1Dict.subindex;

		switch (_uSDO1ACode)
		{
		
			case E_TOGGLE:						// Toggle not alternated
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x05030000L;
				break;
	
			case E_SDO_TIME:					// SDO protocol timed out
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x05040000L;
				break;
	
			case E_CS_CMD:						// Client/server command specifier not valid or unknown
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x05040001L;
				break;
	
			case E_MEMORY_OUT:					// Out of memory
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x05040005L;
				break;
	
			case E_UNSUPP_ACCESS:				// Unsupported access to an object
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06010000L;
				break;
	
			case E_CANNOT_READ:					// Attempt to read a write only object
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06010001L;
				break;
	
			case E_CANNOT_WRITE:				// Attempt to write a read only object
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06010002L;
				break;
	
			case E_OBJ_NOT_FOUND:				// Object does not exist in the object dictionary
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06020000L;
				break;
	
			case E_OBJ_CANNOT_MAP:				// Object cannot be mapped to the PDO
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06040041L;
				break;
	
			case E_OBJ_MAP_LEN:					// The number and length of the objects to be mapped would exceed PDO length
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06040042L;
				break;
	
			case E_GEN_PARAM_COMP:				// General parameter incompatibility reason
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06040043L;
				break;
	
			case E_GEN_INTERNAL_COMP:			// General internal incompatibility in the device
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06040047L;
				break;
	
			case E_HARDWARE:					// Access failed due to a hardware error
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06060000L;
				break;
	
			case E_LEN_SERVICE:					// Data type does not match, length of service parameter does not match
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06070010L;
				break;
	
			case E_LEN_SERVICE_HIGH:			// Data type does not match, length of service parameter too high
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06070012L;
				break;
	
			case E_LEN_SERVICE_LOW:				// Data type does not match, length of service parameter too low
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06070013L;
				break;
	
			case E_SUBINDEX_NOT_FOUND:			// Sub-index does not exist
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06090011L;
				break;
	
			case E_PARAM_RANGE:					// Value range of parameter exceeded
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06090030L;
				break;
	
			case E_PARAM_HIGH:					// Value of parameter written too high
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06090031L;
				break;
	
			case E_PARAM_LOW:					// Value of parameter written too low
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06090032L;
				break;
	
			case E_MAX_LT_MIN:					// Maximum value is less than minimum value
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x06090036L;
				break;
	
			case E_GENERAL:						// genral error
				*(unsigned long *)(mCANGetPtrTxData() + 4) = 0x08000000L;
				break;
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -