CANopen Master Documentation
Version 6.06.04
Loading...
Searching...
No Matches
com_user.c

//====================================================================================================================//
// File: com_user.c //
// Description: This file holds demo code for callback functions of the CANopen Master Protocol Stack //
// //
// Copyright (C) MicroControl GmbH & Co. KG //
// 53844 Troisdorf - Germany //
// www.microcontrol.net //
// //
//--------------------------------------------------------------------------------------------------------------------//
// The copyright to the computer program(s) herein is the property of MicroControl GmbH & Co. KG, Germany. The //
// program(s) may be used and/or copied only with the written permission of MicroControl GmbH & Co. KG or in //
// accordance with the terms and conditions stipulated in the agreement/contract under which the program(s) have //
// been supplied. //
// //
//====================================================================================================================//
/*--------------------------------------------------------------------------------------------------------------------*\
** IMPORTANT NOTE **
** This file provides a template for all functions that need to be adopted to YOUR hardware. Copy this file to **
** <myfile.c> and make your changes in the new file. **
\*--------------------------------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------------------------------*\
** Include files **
** **
\*--------------------------------------------------------------------------------------------------------------------*/
#include "com_emcy.h"
#include "com_led.h"
#include "com_lss.h"
#include "com_mgr.h"
#include "com_nmt.h"
#include "com_pdo.h"
#include "com_sdo_cln.h"
#include "com_sdo_srv.h"
#include "com_time.h"
#if COM_SAFETY_SUPPORT == 1
#include "com_safety.h"
#endif
#if COM_NRL_SUPPORT > 0
#include "com_nrl.h"
#endif
#include "com_demo.h"
#include "com_demo_app.h"
/*--------------------------------------------------------------------------------------------------------------------*\
** Module variables **
** **
\*--------------------------------------------------------------------------------------------------------------------*/
static CPP_SECTION uint8_t aubLssStateMachineS[COM_NET_MAX];
/*--------------------------------------------------------------------------------------------------------------------*\
** Functions **
** **
\*--------------------------------------------------------------------------------------------------------------------*/
//--------------------------------------------------------------------------------------------------------------------//
// ComDemoLssState() //
// //
//--------------------------------------------------------------------------------------------------------------------//
uint8_t ComDemoLssState(uint8_t ubNetV)
{
uint8_t ubResultT = aubLssStateMachineS[ubNetV];
if (aubLssStateMachineS[ubNetV] > eCOM_LSS_PROT_NONE)
{
aubLssStateMachineS[ubNetV] = eCOM_LSS_PROT_NONE;
}
return (ubResultT);
}
//--------------------------------------------------------------------------------------------------------------------//
// ComEmcyConsEventReceive() //
// //
//--------------------------------------------------------------------------------------------------------------------//
#if COM_EMCY_CONS_SUPPORT >0
void ComEmcyConsEventReceive(uint8_t ubNetV, uint8_t ubNodeIdV)
{
uint16_t uwEmcyConsCountT = 0;
CpCanMsg_ts tsEmcyMessageT;
//---------------------------------------------------------------------------------------------------
// This handler is called upon reception of an EMCY. In this example we read EMCY messages from the
// receive queue until the queue is empty. In this example we do not care for the node-ID of the
// producer.
//
(void) ubNodeIdV;
ComEmcyConsQueueCount(ubNetV, &uwEmcyConsCountT);
while (uwEmcyConsCountT > 0)
{
//-------------------------------------------------------------------------------------------
// Clear CAN frame structure, the frame format does not matter here
//
CpMsgInit(&tsEmcyMessageT, CP_MSG_FORMAT_CBFF);
ComEmcyConsQueueFetch(ubNetV, &tsEmcyMessageT);
uwEmcyConsCountT--;
//-------------------------------------------------------------------------------------------
// Do something with the EMCY using the identifier of 082h.
//
if (CpMsgGetIdentifier(&tsEmcyMessageT) == 0x082)
{
}
}
}
#endif
//--------------------------------------------------------------------------------------------------------------------//
// ComLssEventReceive() //
// Function handler for LSS reception //
//--------------------------------------------------------------------------------------------------------------------//
#if COM_LSS_SUPPORT > 0
void ComLssEventReceive(uint8_t ubNetV, uint8_t ubLssProtocolV)
{
uint8_t ubLssStatusT;
//---------------------------------------------------------------------------------------------------
// read status of last LSS protocol
//
ComLssGetStatus(ubNetV, &ubLssStatusT);
if (ubLssStatusT == eCOM_LSS_STAT_SUCCESS)
{
switch (ubLssProtocolV)
{
//-----------------------------------------------------------------------------------
// A node has been identified which is not configured yet. Start the LSS fast-scan
// next
//
aubLssStateMachineS[ubNetV] = eCOM_LSS_PROT_FASTSCAN;
break;
//-----------------------------------------------------------------------------------
// After successful fast-scan operation, set the new node-ID
//
aubLssStateMachineS[ubNetV] = eCOM_LSS_PROT_CONF_ID;
break;
//-----------------------------------------------------------------------------------
// After successful config node-ID operation, trigger a switch mode global to waiting
//
aubLssStateMachineS[ubNetV] = eCOM_LSS_PROT_SWI_GLB;
break;
default:
break;
}
}
else
{
//-------------------------------------------------------------------------------------------
// error handling, LSS operation failed
//
aubLssStateMachineS[ubNetV] = eCOM_LSS_PROT_NONE;
}
}
#endif
//--------------------------------------------------------------------------------------------------------------------//
// ComMgrEventBus() //
// Handler for Bus events //
//--------------------------------------------------------------------------------------------------------------------//
void ComMgrEventBus(uint8_t ubNetV, CpState_ts * ptsBusStateV)
{
if (ubNetV == eCOM_NET_1)
{
if (ptsBusStateV != 0L)
{
}
}
}
//--------------------------------------------------------------------------------------------------------------------//
// ComMgrGetDataBitrate() //
// //
//--------------------------------------------------------------------------------------------------------------------//
int32_t ComMgrGetDataBitrate(uint8_t ubNetV)
{
//---------------------------------------------------------------------------------------------------
// Return the required data bit-rate when running in CANopen FD mode. If no bit-rate switching
// is necessary the value eCP_BITRATE_NONE must be returned.
//
(void) ubNetV;
return (eCP_BITRATE_2M);
}
//--------------------------------------------------------------------------------------------------------------------//
// ComMgrUserInit() //
// //
//--------------------------------------------------------------------------------------------------------------------//
{
//---------------------------------------------------------------------------------------------------
// initialise state of LSS demo
//
aubLssStateMachineS[ubNetV] = 0;
return (eCOM_ERR_NONE);
}
//--------------------------------------------------------------------------------------------------------------------//
// ComNmtEventActiveMaster() //
// Handler for Active Master detection //
//--------------------------------------------------------------------------------------------------------------------//
void ComNmtEventActiveMaster( uint8_t ubNetV, uint8_t ubPriorityV, uint8_t ubNodeIdV)
{
if (ubNetV == eCOM_NET_1)
{
if (ubPriorityV == 0)
{
//-----------------------------------------------------------------------------------
// report node-id of active master, i.e. 'ubNodeIdV'
//
(void) ubNodeIdV; // avoid compiler warning
}
}
}
//--------------------------------------------------------------------------------------------------------------------//
// ComNmtEventGuarding() //
// Handler for NMT events //
//--------------------------------------------------------------------------------------------------------------------//
#if COM_NMT_GUARDING > 0
void ComNmtEventGuarding(uint8_t ubNetV, uint8_t ubNodeIdV, uint8_t ubReasonV)
{
if(ubNetV == eCOM_NET_1)
{
if(ubNodeIdV == 3)
{
//------------------------------------------------
// Node guarding event failed from node-ID 3
//
}
}
}
#endif
//--------------------------------------------------------------------------------------------------------------------//
// ComNmtEventHeartbeat() //
// Handler for NMT events //
//--------------------------------------------------------------------------------------------------------------------//
void ComNmtEventHeartbeat(uint8_t ubNetV, uint8_t ubNodeIdV)
{
//---------------------------------------------------------------------------------------------------
// Stop Heartbeat consumer for Node
//
ComNmtSetHbConsTime(ubNetV, ubNodeIdV, 0);
ComDemoAppConsoleLog(ComDemoNmtStateString(ubNetV, ubNodeIdV));
//---------------------------------------------------------------------------------------------------
// delete node from structure and send reset-node
//
//ComDemoRemoveDevice(ubNetV, ubNodeIdV);
}
//--------------------------------------------------------------------------------------------------------------------//
// ComNmtEventIdCollision() //
// Handler for identifier collisions //
//--------------------------------------------------------------------------------------------------------------------//
void ComNmtEventIdCollision(uint8_t ubNetV)
{
if (ubNetV == eCOM_NET_1)
{
}
}
//--------------------------------------------------------------------------------------------------------------------//
// ComNmtEventMasterDetection() //
// Handler for NMT master detection events //
//--------------------------------------------------------------------------------------------------------------------//
void ComNmtEventMasterDetection(uint8_t ubNetV, uint8_t ubResultV)
{
//---------------------------------------------------------------------------------------------------
// In case of timeout: we are the active CANopen master
//
if (ubResultV == eCOM_NMT_DETECT_TIMEOUT)
{
ComDemoAppConsoleLog("I am the active master");
//-------------------------------------------------------------------------------------------
// reset all nodes
//
//-------------------------------------------------------------------------------------------
// start the SYNC with configured cycle time
//
#if COM_SYNC_SUPPORT > 0
ComSyncEnable(ubNetV, 1);
#endif
}
}
//--------------------------------------------------------------------------------------------------------------------//
// ComNmtEventResetCommunication() //
// Handler for NMT events //
//--------------------------------------------------------------------------------------------------------------------//
void ComNmtEventResetCommunication(uint8_t ubNetV)
{
//----------------------------------------------------------------
// handle reset communication command
//
if (ubNetV == eCOM_NET_1)
{
}
}
//--------------------------------------------------------------------------------------------------------------------//
// ComNmtEventResetNode() //
// Handler for NMT events //
//--------------------------------------------------------------------------------------------------------------------//
void ComNmtEventResetNode(uint8_t ubNetV)
{
if (ubNetV == eCOM_NET_1)
{
}
}
//--------------------------------------------------------------------------------------------------------------------//
// ComNmtEventStateChange() //
// Handler for NMT events //
//--------------------------------------------------------------------------------------------------------------------//
void ComNmtEventStateChange(uint8_t ubNetV, uint8_t ubNodeIdV, uint8_t ubNmtEventV)
{
if (eCOM_NMT_STATE_UNKNOWN != ubNmtEventV)
{
ComDemoAppConsoleLog(ComDemoNmtStateString(ubNetV, ubNodeIdV));
ComDemoNmtQueueStateChange(ubNetV, ubNodeIdV, ubNmtEventV);
}
}
//--------------------------------------------------------------------------------------------------------------------//
// ComNrlEventHandler() //
// //
//--------------------------------------------------------------------------------------------------------------------//
#if COM_NRL_SUPPORT > 0
void ComNrlEventHandler(uint8_t ubNetV, uint8_t ubNrlStateV)
{
ComDemoAppConsoleLog(ComDemoNrlStateString(ubNetV));
switch (ubNrlStateV)
{
case eCP_NRL_STATE_ACTIVE:
break;
case eCP_NRL_STATE_PASSIVE:
break;
case eCP_NRL_STATE_DISCONNECTED:
break;
default:
break;
}
}
#endif
//--------------------------------------------------------------------------------------------------------------------//
// ComObjectEventProgress() //
// Function handler for SDO / USDO segmented transfer //
//--------------------------------------------------------------------------------------------------------------------//
void ComObjectEventProgress(uint8_t ubNetV, uint8_t ubNodeIdV, CoObject_ts * ptsCoObjV, uint32_t ulByteCntV)
{
(void) ulByteCntV;
if (ubNetV == eCOM_NET_1)
{
if (ubNodeIdV == 1)
{
if( (ptsCoObjV->uwIndex == 0x2000) && (ptsCoObjV->ubSubIndex) == 1 )
{
}
}
}
}
//--------------------------------------------------------------------------------------------------------------------//
// ComObjectEventReady() //
// Function handler for SDO / USDO //
//--------------------------------------------------------------------------------------------------------------------//
void ComObjectEventReady(uint8_t ubNetV, uint8_t ubNodeIdV, CoObject_ts * ptsCoObjV, uint32_t ulAbortV)
{
(void) ulAbortV;
if (ptsCoObjV != (CoObject_ts *) 0L)
{
switch (ptsCoObjV->ubMarker)
{
ComDemoAppConsoleLog(ComDemoNodeInfoString(ubNetV, ubNodeIdV));
ComNodeSetHbProdTime(ubNetV, ubNodeIdV, 500);
ComNmtSetHbConsTime(ubNetV, ubNodeIdV, 1000);
break;
ComDemoNmtConfigurationDone(ubNetV, ubNodeIdV);
break;
default:
break;
}
}
}
//--------------------------------------------------------------------------------------------------------------------//
// ComObjectEventTimeout() //
// Function handler for SDO / USDO time-out //
//--------------------------------------------------------------------------------------------------------------------//
void ComObjectEventTimeout(uint8_t ubNetV, uint8_t ubNodeIdV, CoObject_ts * ptsCoObjV)
{
if (ubNetV == eCOM_NET_1)
{
if (ubNodeIdV == 1)
{
if( (ptsCoObjV->uwIndex == 0x2000) && (ptsCoObjV->ubSubIndex) == 1 )
{
// time-out on this object
}
}
}
ComDemoNmtConfigurationDone(ubNetV, ubNodeIdV);
}
//--------------------------------------------------------------------------------------------------------------------//
// ComPdoEventReceive() //
// Function handler for PDO Receive //
//--------------------------------------------------------------------------------------------------------------------//
#if COM_PDO_RCV_MAX > 0
void ComPdoEventReceive(uint8_t ubNetV, uint16_t uwPdoNumV)
{
uint16_t uwRcvPdoCountT = 0;
CpCanMsg_ts tsPdoMessageT;
//---------------------------------------------------------------------------------------------------
// This handler is called upon reception of a PDO. In this example we read RPDO messages from the
// receive queue until the queue is empty. In this example we do not care for the RPDO number.
//
(void) uwPdoNumV;
ComPdoRcvQueueCount(ubNetV, &uwRcvPdoCountT);
while (uwRcvPdoCountT > 0)
{
//-------------------------------------------------------------------------------------------
// Clear CAN frame structure, the frame format does not matter here
//
CpMsgInit(&tsPdoMessageT, CP_MSG_FORMAT_CBFF);
ComPdoRcvQueueFetch(ubNetV, &tsPdoMessageT);
uwRcvPdoCountT--;
//-------------------------------------------------------------------------------------------
// Do something with the PDO using the identifier of 27Fh.
//
if (CpMsgGetIdentifier(&tsPdoMessageT) == 0x27F)
{
}
}
}
#endif
//--------------------------------------------------------------------------------------------------------------------//
// ComPdoEventTimeout() //
// Function handler for PDO timeout //
//--------------------------------------------------------------------------------------------------------------------//
void ComPdoEventTimeout(uint8_t ubNetV, uint16_t uwPdoNumV)
{
if (ubNetV == eCOM_NET_1)
{
if (uwPdoNumV == 1)
{
// handle time-out for RPDO 1
}
}
}
//--------------------------------------------------------------------------------------------------------------------//
// ComSafetySrdoRcvDataUpdate() //
// Function handler for SRDO //
//--------------------------------------------------------------------------------------------------------------------//
#if COM_SAFETY_SUPPORT == 1
void ComSafetySrdoRcvDataUpdate(uint8_t ubNetV, uint8_t ubNodeIdV, uint8_t ubSrdoNumberV)
{
}
#endif
//--------------------------------------------------------------------------------------------------------------------//
// ComSafetySrdoTrmDataUpdate() //
// Function handler for SRDO //
//--------------------------------------------------------------------------------------------------------------------//
#if COM_SAFETY_SUPPORT == 1
void ComSafetySrdoTrmDataUpdate(uint8_t ubNetV, uint8_t ubNodeIdV, uint8_t ubSrdoNumberV)
{
}
#endif
//--------------------------------------------------------------------------------------------------------------------//
// ComSdoSrvBlkUpObjectSize() //
// Function handler for SDO server block transfer //
//--------------------------------------------------------------------------------------------------------------------//
uint32_t ComSdoSrvBlkUpObjectSize(uint8_t ubNetV, uint16_t uwIndexV, uint8_t ubSubIndexV)
{
uint32_t ulObjSizeT = 0;
if(ubNetV == eCOM_NET_1)
{
//-------------------------------------------------------------
// get object size for index 2000h, sub-index 1
//
if( (uwIndexV == 0x2000) && (ubSubIndexV) == 1 )
{
ulObjSizeT = 100;
}
}
return ulObjSizeT;
}
//--------------------------------------------------------------------------------------------------------------------//
// ComTimeEventConsume() //
// Handler for TIME consumer //
//--------------------------------------------------------------------------------------------------------------------//
void ComTimeEventConsume(uint8_t ubNetV, ComTimeOfDay_ts * ptsTimeStampV)
{
(void) ptsTimeStampV;
if (ubNetV == eCOM_NET_1)
{
}
}
@ eCP_BITRATE_2M
Definition canpie.h:692
#define COM_NET_MAX
Definition com_conf.h:51
@ eCOM_NET_1
Definition com_defs.h:723
@ eCOM_ERR_NONE
Definition com_defs.h:155
int32_t ComStatus_tv
Definition com_defs.h:116
Demo functions for CANopen Master protocol stack services .
Generic demo functions for CANopen Master protocol stack .
void ComDemoAppConsoleLog(const char *szMessageV)
CANopen Master EMCY service .
ComStatus_tv ComEmcyConsQueueCount(uint8_t ubNetV, uint16_t *puwCountV)
ComStatus_tv ComEmcyConsQueueFetch(uint8_t ubNetV, CpCanMsg_ts *ptsCanMsgV)
void ComEmcyConsEventReceive(uint8_t ubNetV, uint8_t ubNodeIdV)
CANopen Master LED Management .
CANopen Master Layer Setting Services (LSS) .
ComStatus_tv ComLssGetStatus(uint8_t ubNetV, uint8_t *pubStatusV)
@ eCOM_LSS_PROT_CONF_ID
Definition com_lss.h:142
@ eCOM_LSS_PROT_SWI_GLB
Definition com_lss.h:99
@ eCOM_LSS_PROT_IDENTIFY
Definition com_lss.h:151
@ eCOM_LSS_PROT_FASTSCAN
Definition com_lss.h:148
@ eCOM_LSS_STAT_SUCCESS
Definition com_lss.h:168
void ComLssEventReceive(uint8_t ubNetV, uint8_t ubLssProtocolV)
CANopen Master management functions .
ComStatus_tv ComMgrUserInit(uint8_t ubNetV)
Change CANopen Master settings.
int32_t ComMgrGetDataBitrate(uint8_t ubNetV)
void ComMgrEventBus(uint8_t ubNetV, CpState_ts *ptsBusStateV)
CANopen Master NMT service .
ComStatus_tv ComNmtSetHbConsTime(uint8_t ubNetV, uint8_t ubNodeIdV, uint16_t uwTimeV)
Set consumer heartbeat time.
void ComNmtEventActiveMaster(uint8_t ubNetV, uint8_t ubPriorityV, uint8_t ubNodeIdV)
void ComNmtEventHeartbeat(uint8_t ubNetV, uint8_t ubNodeIdV)
void ComNmtEventStateChange(uint8_t ubNetV, uint8_t ubNodeIdV, uint8_t ubNmtStateV)
void ComNmtEventGuarding(uint8_t ubNetV, uint8_t ubNodeIdV, uint8_t ubReasonV)
void ComNmtEventResetNode(uint8_t ubNetV)
NMT reset event callback.
@ eCOM_NMT_STATE_RESET_NODE
Definition com_nmt.h:92
@ eCOM_NMT_STATE_UNKNOWN
Definition com_nmt.h:80
@ eCOM_NMT_STATE_RESET_COM
Definition com_nmt.h:95
void ComNmtEventResetCommunication(uint8_t ubNetV)
ComStatus_tv ComNmtSetNodeState(uint8_t ubNetV, uint8_t ubNodeIdV, uint8_t ubStateV)
Set NMT state of CANopen device.
void ComNmtEventIdCollision(uint8_t ubNetV)
void ComNmtEventMasterDetection(uint8_t ubNetV, uint8_t ubResultV)
NMT master detection callback.
ComStatus_tv ComNodeSetHbProdTime(uint8_t ubNetV, uint8_t ubNodeIdV, uint16_t uwHeartbeatV)
void ComObjectEventReady(uint8_t ubNetV, uint8_t ubNodeIdV, CoObject_ts *ptsCoObjV, uint32_t ulAbortV)
void ComObjectEventTimeout(uint8_t ubNetV, uint8_t ubNodeIdV, CoObject_ts *ptsCoObjV)
@ eCOM_OBJECT_MARKER_NODE_GET_INFO
Definition com_object.h:77
@ eCOM_OBJECT_MARKER_NODE_SET_HEARTBEAT
Definition com_object.h:80
void ComObjectEventProgress(uint8_t ubNetV, uint8_t ubNodeIdV, CoObject_ts *ptsCoObjV, uint32_t ulByteCntV)
CANopen Master PDO service .
void ComPdoEventReceive(uint8_t ubNetV, uint16_t uwPdoNumV)
ComStatus_tv ComPdoRcvQueueCount(uint8_t ubNetV, uint16_t *puwCountV)
void ComPdoEventTimeout(uint8_t ubNetV, uint16_t uwPdoNumV)
ComStatus_tv ComPdoRcvQueueFetch(uint8_t ubNetV, CpCanMsg_ts *ptsCanMsgV)
CANopen Master Functional Safety .
void ComSafetySrdoRcvDataUpdate(uint8_t ubNetV, uint8_t ubNodeIdV, uint8_t ubSrdoNumberV)
void ComSafetySrdoTrmDataUpdate(uint8_t ubNetV, uint8_t ubNodeIdV, uint8_t ubSrdoNumberV)
CANopen Master SDO client .
CANopen Master SDO server .
uint32_t ComSdoSrvBlkUpObjectSize(uint8_t ubNetV, uint16_t uwIndexV, uint8_t ubSubIndexV)
ComStatus_tv ComSyncEnable(uint8_t ubNetV, uint8_t ubEnableV)
CANopen Master Stack - TIME service (TIME) .
void ComTimeEventConsume(uint8_t ubNetV, ComTimeOfDay_ts *ptsTimeStampV)
void CpMsgInit(CpCanMsg_ts *ptsCanMsgV, uint8_t ubFormatV)
Initialise message structure.
uint32_t CpMsgGetIdentifier(const CpCanMsg_ts *ptsCanMsgV)
Get Identifier Value.
#define CP_MSG_FORMAT_CBFF
Definition canpie.h:415
#define CPP_SECTION
Definition mc_compiler.h:1187
Object structure.
Definition com_object.h:122
uint16_t uwIndex
Definition com_object.h:125
uint8_t ubMarker
Definition com_object.h:131
uint8_t ubSubIndex
Definition com_object.h:128
Time of day.
Definition com_time.h:109
CAN message structure.
Definition canpie.h:1005
CAN state structure.
Definition canpie.h:1246