📄 co_sdo1.c
字号:
/*****************************************************************************
*
* 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 + -