Skip to content

Commit

Permalink
Merge branch 'martinwag-neuberger-master'
Browse files Browse the repository at this point in the history
  • Loading branch information
martinwag committed Oct 8, 2019
2 parents d200264 + 0bd08be commit 8b01062
Show file tree
Hide file tree
Showing 37 changed files with 6,472 additions and 261 deletions.
244 changes: 191 additions & 53 deletions CANopen.c

Large diffs are not rendered by default.

83 changes: 76 additions & 7 deletions CANopen.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,18 @@ extern "C" {
#include "CO_SYNC.h"
#include "CO_PDO.h"
#include "CO_HBconsumer.h"
#if CO_NO_SDO_CLIENT == 1
#if CO_NO_SDO_CLIENT != 0
#include "CO_SDOmaster.h"
#endif
#if CO_NO_TRACE > 0
#include "CO_trace.h"
#endif

#if CO_NO_LSS_SERVER == 1
#include "CO_LSSslave.h"
#endif
#if CO_NO_LSS_CLIENT == 1
#include "CO_LSSmaster.h"
#endif

/**
* Default CANopen identifiers.
Expand All @@ -114,7 +119,9 @@ typedef enum{
CO_CAN_ID_RPDO_4 = 0x500, /**< 0x500, Default RPDO5 (+nodeID) */
CO_CAN_ID_TSDO = 0x580, /**< 0x580, SDO response from server (+nodeID) */
CO_CAN_ID_RSDO = 0x600, /**< 0x600, SDO request from client (+nodeID) */
CO_CAN_ID_HEARTBEAT = 0x700 /**< 0x700, Heartbeat message */
CO_CAN_ID_HEARTBEAT = 0x700, /**< 0x700, Heartbeat message */
CO_CAN_ID_LSS_CLI = 0x7E4, /**< 0x7E4, LSS response from server to client */
CO_CAN_ID_LSS_SRV = 0x7E5 /**< 0x7E5, LSS request from client to server */
}CO_Default_CAN_ID_t;


Expand All @@ -131,8 +138,14 @@ typedef struct{
CO_RPDO_t *RPDO[CO_NO_RPDO];/**< RPDO objects */
CO_TPDO_t *TPDO[CO_NO_TPDO];/**< TPDO objects */
CO_HBconsumer_t *HBcons; /**< Heartbeat consumer object*/
#if CO_NO_SDO_CLIENT == 1
CO_SDOclient_t *SDOclient; /**< SDO client object */
#if CO_NO_LSS_SERVER == 1
CO_LSSslave_t *LSSslave; /**< LSS server/slave object */
#endif
#if CO_NO_LSS_CLIENT == 1
CO_LSSmaster_t *LSSmaster; /**< LSS master/client object */
#endif
#if CO_NO_SDO_CLIENT != 0
CO_SDOclient_t *SDOclient[CO_NO_SDO_CLIENT]; /**< SDO client object */
#endif
#if CO_NO_TRACE > 0
CO_trace_t *trace[CO_NO_TRACE]; /**< Trace object for monitoring variables */
Expand All @@ -158,18 +171,72 @@ typedef struct{
* @return other: same as CO_CANsend().
*/
#if CO_NO_NMT_MASTER == 1
uint8_t CO_sendNMTcommand(CO_t *CO, uint8_t command, uint8_t nodeID);
CO_ReturnError_t CO_sendNMTcommand(CO_t *CO, uint8_t command, uint8_t nodeID);
#endif


#if CO_NO_LSS_SERVER == 1
/**
* Allocate and initialize memory for CANopen object
*
* Function must be called in the communication reset section.
*
* @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT,
* CO_ERROR_OUT_OF_MEMORY
*/
CO_ReturnError_t CO_new(void);


/**
* Initialize CAN driver
*
* Function must be called in the communication reset section.
*
* @param CANbaseAddress Address of the CAN module, passed to CO_CANmodule_init().
* @param bitRate CAN bit rate.
* @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT,
* CO_ERROR_ILLEGAL_BAUDRATE, CO_ERROR_OUT_OF_MEMORY
*/
CO_ReturnError_t CO_CANinit(
int32_t CANbaseAddress,
uint16_t bitRate);


/**
* Initialize CANopen LSS slave
*
* Function must be called in the communication reset section.
*
* @param nodeId Node ID of the CANopen device (1 ... 127) or CO_LSS_NODE_ID_ASSIGNMENT
* @param bitRate CAN bit rate.
* @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT
*/
CO_ReturnError_t CO_LSSinit(
uint8_t nodeId,
uint16_t bitRate);


/**
* Initialize CANopen stack.
*
* Function must be called in the communication reset section.
*
* @param nodeId Node ID of the CANopen device (1 ... 127).
* @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT
*/
CO_ReturnError_t CO_CANopenInit(
uint8_t nodeId);


#else /* CO_NO_LSS_SERVER == 1 */
/**
* Initialize CANopen stack.
*
* Function must be called in the communication reset section.
*
* @param CANbaseAddress Address of the CAN module, passed to CO_CANmodule_init().
* @param nodeId Node ID of the CANopen device (1 ... 127).
* @param nodeId CAN bit rate.
* @param bitRate CAN bit rate.
*
* @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT,
* CO_ERROR_OUT_OF_MEMORY, CO_ERROR_ILLEGAL_BAUDRATE
Expand All @@ -179,6 +246,8 @@ CO_ReturnError_t CO_init(
uint8_t nodeId,
uint16_t bitRate);

#endif /* CO_NO_LSS_SERVER == 1 */


/**
* Delete CANopen object and free memory. Must be called at program exit.
Expand Down
2 changes: 1 addition & 1 deletion Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ IDL_PROPERTY_SUPPORT = YES
# all members of a group must be documented explicitly.
# The default value is: NO.

DISTRIBUTE_GROUP_DOC = NO
DISTRIBUTE_GROUP_DOC = YES

# Set the SUBGROUPING tag to YES to allow class member groups of the same type
# (for instance a group of public functions) to be put as a subgroup of that
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ SOURCES = $(STACKDRV_SRC)/CO_driver.c \
$(STACK_SRC)/CO_PDO.c \
$(STACK_SRC)/CO_HBconsumer.c \
$(STACK_SRC)/CO_SDOmaster.c \
$(STACK_SRC)/CO_LSSmaster.c \
$(STACK_SRC)/CO_LSSslave.c \
$(STACK_SRC)/CO_trace.c \
$(CANOPEN_SRC)/CANopen.c \
$(APPL_SRC)/CO_OD.c \
Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ CANopen Features
- Emergency message.
- Sync producer/consumer.
- Non-volatile storage.
- LSS master and slave, LSS fastscan


Usage of the CANopenNode
Expand Down Expand Up @@ -107,6 +108,18 @@ Flowchart of a typical CANopenNode implementation
| from any node in the|
| CANopen network. |
-----------------------
-----------------------
| LSS client (optional) |
| |
| - Can be called by |
| external application|
| - Can do LSS requests |
| - Can request node |
| enumeration |
-----------------------
~~~


Expand All @@ -118,6 +131,9 @@ File structure
- **CO_Emergency.h/.c** - CANopen Emergency object.
- **CO_NMT_Heartbeat.h/.c** - CANopen Network slave and Heartbeat producer object.
- **CO_HBconsumer.h/.c** - CANopen Heartbeat consumer object.
- **CO_LSS.h** - CANopen LSS common. This is common to LSS master and slave.
- **CO_LSSmaster.h/.c** - CANopen LSS master functionality.
- **CO_LSSslave.h/.c** - CANopen LSS slave functionality.
- **CO_SYNC.h/.c** - CANopen SYNC producer and consumer object.
- **CO_SDO.h/.c** - CANopen SDO server object. It serves data from Object dictionary.
- **CO_PDO.h/.c** - CANopen PDO object. It configures, receives and transmits CANopen process data.
Expand Down
3 changes: 2 additions & 1 deletion example/CO_OD.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@
#define CO_NO_TPDO 4 //Associated objects: 1800, 1801, 1802, 1803, 1A00, 1A01, 1A02, 1A03
#define CO_NO_NMT_MASTER 0
#define CO_NO_TRACE 0

#define CO_NO_LSS_SERVER 0
#define CO_NO_LSS_CLIENT 0

/*******************************************************************************
OBJECT DICTIONARY
Expand Down
75 changes: 43 additions & 32 deletions stack/CO_Emergency.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ void CO_EM_process(
CO_EMpr_t *emPr,
bool_t NMTisPreOrOperational,
uint16_t timeDifference_100us,
uint16_t emInhTime)
uint16_t emInhTime,
uint16_t *timerNext_ms)
{

CO_EM_t *em = emPr->em;
Expand Down Expand Up @@ -240,48 +241,58 @@ void CO_EM_process(
/* send Emergency message. */
if( NMTisPreOrOperational &&
!emPr->CANtxBuff->bufferFull &&
emPr->inhibitEmTimer >= emInhTime &&
(em->bufReadPtr != em->bufWritePtr || em->bufFull))
{
uint32_t preDEF; /* preDefinedErrorField */
uint16_t diff;

/* add error register */
em->bufReadPtr[2] = *emPr->errorRegister;
if (emPr->inhibitEmTimer >= emInhTime) {
/* inhibit time elapsed, send message */

/* copy data to CAN emergency message */
CO_memcpy(emPr->CANtxBuff->data, em->bufReadPtr, 8U);
CO_memcpy((uint8_t*)&preDEF, em->bufReadPtr, 4U);
em->bufReadPtr += 8;
/* add error register */
em->bufReadPtr[2] = *emPr->errorRegister;

/* Update read buffer pointer and reset inhibit timer */
if(em->bufReadPtr == em->bufEnd){
em->bufReadPtr = em->buf;
}
emPr->inhibitEmTimer = 0U;
/* copy data to CAN emergency message */
CO_memcpy(emPr->CANtxBuff->data, em->bufReadPtr, 8U);
CO_memcpy((uint8_t*)&preDEF, em->bufReadPtr, 4U);
em->bufReadPtr += 8;

/* verify message buffer overflow, then clear full flag */
if(em->bufFull == 2U){
em->bufFull = 0U; /* will be updated below */
CO_errorReport(em, CO_EM_EMERGENCY_BUFFER_FULL, CO_EMC_GENERIC, 0U);
}
else{
em->bufFull = 0;
CO_errorReset(em, CO_EM_EMERGENCY_BUFFER_FULL, 0);
}
/* Update read buffer pointer and reset inhibit timer */
if(em->bufReadPtr == em->bufEnd){
em->bufReadPtr = em->buf;
}
emPr->inhibitEmTimer = 0U;

/* verify message buffer overflow, then clear full flag */
if(em->bufFull == 2U){
em->bufFull = 0U; /* will be updated below */
CO_errorReport(em, CO_EM_EMERGENCY_BUFFER_FULL, CO_EMC_GENERIC, 0U);
}
else{
em->bufFull = 0;
CO_errorReset(em, CO_EM_EMERGENCY_BUFFER_FULL, 0);
}

/* write to 'pre-defined error field' (object dictionary, index 0x1003) */
if(emPr->preDefErr){
uint8_t i;
/* write to 'pre-defined error field' (object dictionary, index 0x1003) */
if(emPr->preDefErr){
uint8_t i;

if(emPr->preDefErrNoOfErrors < emPr->preDefErrSize)
emPr->preDefErrNoOfErrors++;
for(i=emPr->preDefErrNoOfErrors-1; i>0; i--)
emPr->preDefErr[i] = emPr->preDefErr[i-1];
emPr->preDefErr[0] = preDEF;
if(emPr->preDefErrNoOfErrors < emPr->preDefErrSize)
emPr->preDefErrNoOfErrors++;
for(i=emPr->preDefErrNoOfErrors-1; i>0; i--)
emPr->preDefErr[i] = emPr->preDefErr[i-1];
emPr->preDefErr[0] = preDEF;
}

/* send CAN message */
CO_CANsend(emPr->CANdev, emPr->CANtxBuff);
}

/* send CAN message */
CO_CANsend(emPr->CANdev, emPr->CANtxBuff);
/* check again after inhibit time elapsed */
diff = (emInhTime + 9) / 10; /* time difference in ms, always round up */
if (timerNext_ms != NULL && *timerNext_ms > diff) {
*timerNext_ms = diff;
}
}

return;
Expand Down
4 changes: 3 additions & 1 deletion stack/CO_Emergency.h
Original file line number Diff line number Diff line change
Expand Up @@ -418,12 +418,14 @@ void CO_EM_initCallback(
* @param NMTisPreOrOperational True if this node is NMT_PRE_OPERATIONAL or NMT_OPERATIONAL.
* @param timeDifference_100us Time difference from previous function call in [100 * microseconds].
* @param emInhTime _Inhibit time EMCY_ (object dictionary, index 0x1015).
* @param timerNext_ms Return value - info to OS - see CO_process().
*/
void CO_EM_process(
CO_EMpr_t *emPr,
bool_t NMTisPreOrOperational,
uint16_t timeDifference_100us,
uint16_t emInhTime);
uint16_t emInhTime,
uint16_t *timerNext_ms);


#endif
Expand Down

0 comments on commit 8b01062

Please sign in to comment.