OD interface simplified #162
OD_extension is now configurable by application only.
This commit is contained in:
parent
7b5de9f383
commit
51d64df860
19 changed files with 893 additions and 1270 deletions
|
|
@ -349,18 +349,18 @@ static void CO_EM_receive(void *object, void *msg) {
|
|||
CO_ReturnError_t CO_EM_init(CO_EM_t *em,
|
||||
const OD_entry_t *OD_1001_errReg,
|
||||
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER
|
||||
const OD_entry_t *OD_1014_cobIdEm,
|
||||
OD_entry_t *OD_1014_cobIdEm,
|
||||
CO_CANmodule_t *CANdevTx,
|
||||
uint16_t CANdevTxIdx,
|
||||
#if (CO_CONFIG_EM) & CO_CONFIG_EM_PROD_INHIBIT
|
||||
const OD_entry_t *OD_1015_InhTime,
|
||||
OD_entry_t *OD_1015_InhTime,
|
||||
#endif
|
||||
#endif
|
||||
#if (CO_CONFIG_EM) & CO_CONFIG_EM_HISTORY
|
||||
const OD_entry_t *OD_1003_preDefErr,
|
||||
OD_entry_t *OD_1003_preDefErr,
|
||||
#endif
|
||||
#if (CO_CONFIG_EM) & CO_CONFIG_EM_STATUS_BITS
|
||||
const OD_entry_t *OD_statusBits,
|
||||
OD_entry_t *OD_statusBits,
|
||||
#endif
|
||||
#if (CO_CONFIG_EM) & CO_CONFIG_EM_CONSUMER
|
||||
CO_CANmodule_t *CANdevRx,
|
||||
|
|
@ -410,10 +410,12 @@ CO_ReturnError_t CO_EM_init(CO_EM_t *em,
|
|||
uint16_t producerCanId = (uint16_t)(COB_IDEmergency32 & 0x7FF);
|
||||
em->producerEnabled = (COB_IDEmergency32 & 0x80000000) == 0
|
||||
&& producerCanId != 0;
|
||||
ODR_t odRetE = OD_extensionIO_init(OD_1014_cobIdEm,
|
||||
(void *) em,
|
||||
OD_read_1014,
|
||||
OD_write_1014);
|
||||
|
||||
em->OD_1014_extension.object = em;
|
||||
em->OD_1014_extension.read = OD_read_1014;
|
||||
em->OD_1014_extension.write = OD_write_1014;
|
||||
ODR_t odRetE = OD_extension_init(OD_1014_cobIdEm,
|
||||
&em->OD_1014_extension);
|
||||
if (odRetE != ODR_OK) {
|
||||
CO_errinfo(CANdevTx, OD_getIndex(OD_1014_cobIdEm));
|
||||
return CO_ERROR_OD_PARAMETERS;
|
||||
|
|
@ -428,10 +430,12 @@ CO_ReturnError_t CO_EM_init(CO_EM_t *em,
|
|||
#else
|
||||
uint16_t producerCanId = CO_CAN_ID_EMERGENCY + nodeId;
|
||||
em->producerEnabled = (COB_IDEmergency32 & 0x80000000) == 0;
|
||||
ODR_t odRetE = OD_extensionIO_init(OD_1014_cobIdEm,
|
||||
(void *) em,
|
||||
OD_read_1014_default,
|
||||
OD_writeOriginal);
|
||||
|
||||
em->OD_1014_extension.object = em;
|
||||
em->OD_1014_extension.read = OD_read_1014_default;
|
||||
em->OD_1014_extension.write = OD_writeOriginal;
|
||||
ODR_t odRetE = OD_extension_init(OD_1014_cobIdEm,
|
||||
&em->OD_1014_extension);
|
||||
if (odRetE != ODR_OK) {
|
||||
CO_errinfo(CANdevTx, OD_getIndex(OD_1014_cobIdEm));
|
||||
return CO_ERROR_OD_PARAMETERS;
|
||||
|
|
@ -462,10 +466,12 @@ CO_ReturnError_t CO_EM_init(CO_EM_t *em,
|
|||
ODR_t odRet1 = OD_get_u16(OD_1015_InhTime, 0, &inhibitTime_100us, true);
|
||||
if (odRet1 == ODR_OK) {
|
||||
em->inhibitEmTime_us = (uint32_t)inhibitTime_100us * 100;
|
||||
OD_extensionIO_init(OD_1015_InhTime,
|
||||
(void *) em,
|
||||
OD_readOriginal,
|
||||
OD_write_1015);
|
||||
|
||||
em->OD_1015_extension.object = em;
|
||||
em->OD_1015_extension.read = OD_readOriginal;
|
||||
em->OD_1015_extension.write = OD_write_1015;
|
||||
OD_extension_init(OD_1015_InhTime,
|
||||
&em->OD_1015_extension);
|
||||
}
|
||||
#endif /* (CO_CONFIG_EM) & CO_CONFIG_EM_PROD_INHIBIT */
|
||||
#endif /* (CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER */
|
||||
|
|
@ -473,19 +479,21 @@ CO_ReturnError_t CO_EM_init(CO_EM_t *em,
|
|||
|
||||
#if (CO_CONFIG_EM) & CO_CONFIG_EM_HISTORY
|
||||
/* If OD entry available, make access to em->preDefErr */
|
||||
OD_extensionIO_init(OD_1003_preDefErr,
|
||||
(void *) em,
|
||||
OD_read_1003,
|
||||
OD_write_1003);
|
||||
em->OD_1003_extension.object = em;
|
||||
em->OD_1003_extension.read = OD_read_1003;
|
||||
em->OD_1003_extension.write = OD_write_1003;
|
||||
OD_extension_init(OD_1003_preDefErr,
|
||||
&em->OD_1003_extension);
|
||||
#endif /* (CO_CONFIG_EM) & CO_CONFIG_EM_HISTORY */
|
||||
|
||||
|
||||
#if (CO_CONFIG_EM) & CO_CONFIG_EM_STATUS_BITS
|
||||
/* If OD entry available, make access to em->errorStatusBits */
|
||||
OD_extensionIO_init(OD_statusBits,
|
||||
(void *) em,
|
||||
OD_read_statusBits,
|
||||
OD_write_statusBits);
|
||||
em->OD_statusBits_extension.object = em;
|
||||
em->OD_statusBits_extension.read = OD_read_statusBits;
|
||||
em->OD_statusBits_extension.write = OD_write_statusBits;
|
||||
OD_extension_init(OD_statusBits,
|
||||
&em->OD_statusBits_extension);
|
||||
#endif /* (CO_CONFIG_EM) & CO_CONFIG_EM_STATUS_BITS */
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -380,11 +380,11 @@ typedef struct {
|
|||
* messages. Messages are added by @ref CO_error() function. All messages
|
||||
* are later post-processed by @ref CO_EM_process() function. Fifo is also
|
||||
* used for error history - OD object 0x1003, "Pre-defined error field". */
|
||||
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER) || defined CO_DOXYGEN
|
||||
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER) || defined CO_DOXYGEN
|
||||
uint32_t fifo[CO_CONFIG_EM_BUFFER_SIZE + 1][2];
|
||||
#else
|
||||
#else
|
||||
uint32_t fifo[CO_CONFIG_EM_BUFFER_SIZE + 1][1];
|
||||
#endif
|
||||
#endif
|
||||
/** Pointer for the fifo buffer, where next emergency message will be
|
||||
* written by @ref CO_error() function. */
|
||||
uint8_t fifoWrPtr;
|
||||
|
|
@ -407,20 +407,34 @@ typedef struct {
|
|||
CO_CANmodule_t *CANdevTx;
|
||||
/** CAN transmit buffer */
|
||||
CO_CANtx_t *CANtxBuff;
|
||||
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_PROD_CONFIGURABLE) || defined CO_DOXYGEN
|
||||
/** Extension for OD object */
|
||||
OD_extension_t OD_1014_extension;
|
||||
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_PROD_CONFIGURABLE) || defined CO_DOXYGEN
|
||||
/** COB ID of emergency message, from Object dictionary */
|
||||
uint16_t producerCanId;
|
||||
/** From CO_EM_init() */
|
||||
uint16_t CANdevTxIdx;
|
||||
#endif
|
||||
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_PROD_INHIBIT) || defined CO_DOXYGEN
|
||||
#endif
|
||||
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_PROD_INHIBIT) || defined CO_DOXYGEN
|
||||
/** Inhibit time for emergency message, from Object dictionary */
|
||||
uint32_t inhibitEmTime_us;
|
||||
/**< Internal timer for inhibit time */
|
||||
uint32_t inhibitEmTimer;
|
||||
#endif
|
||||
/** Extension for OD object */
|
||||
OD_extension_t OD_1015_extension;
|
||||
#endif
|
||||
#endif /* (CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER */
|
||||
|
||||
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_HISTORY) || defined CO_DOXYGEN
|
||||
/** Extension for OD object */
|
||||
OD_extension_t OD_1003_extension;
|
||||
#endif
|
||||
|
||||
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_STATUS_BITS) || defined CO_DOXYGEN
|
||||
/** Extension for OD object */
|
||||
OD_extension_t OD_statusBits_extension;
|
||||
#endif
|
||||
|
||||
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_CONSUMER) || defined CO_DOXYGEN
|
||||
/** From CO_EM_initCallbackRx() or NULL */
|
||||
void (*pFunctSignalRx)(const uint16_t ident,
|
||||
|
|
@ -470,18 +484,18 @@ typedef struct {
|
|||
CO_ReturnError_t CO_EM_init(CO_EM_t *em,
|
||||
const OD_entry_t *OD_1001_errReg,
|
||||
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_PRODUCER) || defined CO_DOXYGEN
|
||||
const OD_entry_t *OD_1014_cobIdEm,
|
||||
OD_entry_t *OD_1014_cobIdEm,
|
||||
CO_CANmodule_t *CANdevTx,
|
||||
uint16_t CANdevTxIdx,
|
||||
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_PROD_INHIBIT) || defined CO_DOXYGEN
|
||||
const OD_entry_t *OD_1015_InhTime,
|
||||
OD_entry_t *OD_1015_InhTime,
|
||||
#endif
|
||||
#endif
|
||||
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_HISTORY) || defined CO_DOXYGEN
|
||||
const OD_entry_t *OD_1003_preDefErr,
|
||||
OD_entry_t *OD_1003_preDefErr,
|
||||
#endif
|
||||
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_STATUS_BITS) || defined CO_DOXYGEN
|
||||
const OD_entry_t *OD_statusBits,
|
||||
OD_entry_t *OD_statusBits,
|
||||
#endif
|
||||
#if ((CO_CONFIG_EM) & CO_CONFIG_EM_CONSUMER) || defined CO_DOXYGEN
|
||||
CO_CANmodule_t *CANdevRx,
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ static OD_size_t OD_write_1017(OD_stream_t *stream, uint8_t subIndex,
|
|||
|
||||
/******************************************************************************/
|
||||
CO_ReturnError_t CO_NMT_init(CO_NMT_t *NMT,
|
||||
const OD_entry_t *OD_1017_ProducerHbTime,
|
||||
OD_entry_t *OD_1017_ProducerHbTime,
|
||||
CO_EM_t *em,
|
||||
uint8_t nodeId,
|
||||
CO_NMT_control_t NMTcontrol,
|
||||
|
|
@ -132,10 +132,11 @@ CO_ReturnError_t CO_NMT_init(CO_NMT_t *NMT,
|
|||
}
|
||||
NMT->HBproducerTime_us = (uint32_t)HBprodTime_ms * 1000;
|
||||
|
||||
odRet = OD_extensionIO_init(OD_1017_ProducerHbTime,
|
||||
(void *) NMT,
|
||||
OD_readOriginal,
|
||||
OD_write_1017);
|
||||
NMT->OD_1017_extension.object = NMT;
|
||||
NMT->OD_1017_extension.read = OD_readOriginal;
|
||||
NMT->OD_1017_extension.write = OD_write_1017;
|
||||
odRet = OD_extension_init(OD_1017_ProducerHbTime,
|
||||
&NMT->OD_1017_extension);
|
||||
if (odRet != ODR_OK) {
|
||||
CO_errinfo(HB_CANdevTx, OD_getIndex(OD_1017_ProducerHbTime));
|
||||
return CO_ERROR_OD_PARAMETERS;
|
||||
|
|
|
|||
|
|
@ -175,6 +175,8 @@ typedef struct {
|
|||
uint32_t HBproducerTime_us;
|
||||
/** Internal timer for HB producer */
|
||||
uint32_t HBproducerTimer;
|
||||
/** Extension for OD object */
|
||||
OD_extension_t OD_1017_extension;
|
||||
/** From CO_NMT_init() */
|
||||
CO_EM_t *em;
|
||||
#if ((CO_CONFIG_NMT) & CO_CONFIG_NMT_MASTER) || defined CO_DOXYGEN
|
||||
|
|
@ -229,7 +231,7 @@ typedef struct {
|
|||
* @return #CO_ReturnError_t CO_ERROR_NO on success.
|
||||
*/
|
||||
CO_ReturnError_t CO_NMT_init(CO_NMT_t *NMT,
|
||||
const OD_entry_t *OD_1017_ProducerHbTime,
|
||||
OD_entry_t *OD_1017_ProducerHbTime,
|
||||
CO_EM_t *em,
|
||||
uint8_t nodeId,
|
||||
CO_NMT_control_t NMTcontrol,
|
||||
|
|
|
|||
|
|
@ -39,9 +39,9 @@ OD_size_t OD_readOriginal(OD_stream_t *stream, uint8_t subIndex,
|
|||
}
|
||||
|
||||
OD_size_t dataLenToCopy = stream->dataLength; /* length of OD variable */
|
||||
const uint8_t *odData = stream->dataObjectOriginal;
|
||||
const uint8_t *dataOrig = stream->dataOrig;
|
||||
|
||||
if (odData == NULL) {
|
||||
if (dataOrig == NULL) {
|
||||
*returnCode = ODR_SUB_NOT_EXIST;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -57,7 +57,7 @@ OD_size_t OD_readOriginal(OD_stream_t *stream, uint8_t subIndex,
|
|||
}
|
||||
/* Reduce for already copied data */
|
||||
dataLenToCopy -= stream->dataOffset;
|
||||
odData += stream->dataOffset;
|
||||
dataOrig += stream->dataOffset;
|
||||
|
||||
if (dataLenToCopy > count) {
|
||||
/* Not enough space in destination buffer */
|
||||
|
|
@ -71,7 +71,7 @@ OD_size_t OD_readOriginal(OD_stream_t *stream, uint8_t subIndex,
|
|||
}
|
||||
|
||||
CO_LOCK_OD();
|
||||
memcpy(buf, odData, dataLenToCopy);
|
||||
memcpy(buf, dataOrig, dataLenToCopy);
|
||||
CO_UNLOCK_OD();
|
||||
return dataLenToCopy;
|
||||
}
|
||||
|
|
@ -88,9 +88,9 @@ OD_size_t OD_writeOriginal(OD_stream_t *stream, uint8_t subIndex,
|
|||
}
|
||||
|
||||
OD_size_t dataLenToCopy = stream->dataLength; /* length of OD variable */
|
||||
uint8_t *odData = stream->dataObjectOriginal;
|
||||
uint8_t *dataOrig = stream->dataOrig;
|
||||
|
||||
if (odData == NULL) {
|
||||
if (dataOrig == NULL) {
|
||||
*returnCode = ODR_SUB_NOT_EXIST;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -107,7 +107,7 @@ OD_size_t OD_writeOriginal(OD_stream_t *stream, uint8_t subIndex,
|
|||
}
|
||||
/* reduce for already copied data */
|
||||
dataLenToCopy -= stream->dataOffset;
|
||||
odData += stream->dataOffset;
|
||||
dataOrig += stream->dataOffset;
|
||||
|
||||
if (dataLenToCopy > count) {
|
||||
/* Remaining data space in OD variable is larger than current count
|
||||
|
|
@ -128,7 +128,7 @@ OD_size_t OD_writeOriginal(OD_stream_t *stream, uint8_t subIndex,
|
|||
}
|
||||
|
||||
CO_LOCK_OD();
|
||||
memcpy(odData, buf, dataLenToCopy);
|
||||
memcpy(dataOrig, buf, dataLenToCopy);
|
||||
CO_UNLOCK_OD();
|
||||
return dataLenToCopy;
|
||||
}
|
||||
|
|
@ -157,7 +157,7 @@ static OD_size_t OD_writeDisabled(OD_stream_t *stream, uint8_t subIndex,
|
|||
|
||||
|
||||
/******************************************************************************/
|
||||
const OD_entry_t *OD_find(const OD_t *od, uint16_t index) {
|
||||
OD_entry_t *OD_find(OD_t *od, uint16_t index) {
|
||||
if (od == NULL || od->size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -172,7 +172,7 @@ const OD_entry_t *OD_find(const OD_t *od, uint16_t index) {
|
|||
while (min < max) {
|
||||
/* get entry between min and max */
|
||||
cur = (min + max) >> 1;
|
||||
const OD_entry_t* entry = &od->list[cur];
|
||||
OD_entry_t* entry = &od->list[cur];
|
||||
|
||||
if (index == entry->index) {
|
||||
return entry;
|
||||
|
|
@ -187,7 +187,7 @@ const OD_entry_t *OD_find(const OD_t *od, uint16_t index) {
|
|||
}
|
||||
|
||||
if (min == max) {
|
||||
const OD_entry_t* entry = &od->list[min];
|
||||
OD_entry_t* entry = &od->list[min];
|
||||
if (index == entry->index) {
|
||||
return entry;
|
||||
}
|
||||
|
|
@ -198,58 +198,47 @@ const OD_entry_t *OD_find(const OD_t *od, uint16_t index) {
|
|||
|
||||
/******************************************************************************/
|
||||
ODR_t OD_getSub(const OD_entry_t *entry, uint8_t subIndex,
|
||||
OD_subEntry_t *subEntry, OD_IO_t *io, bool_t odOrig)
|
||||
OD_IO_t *io, bool_t odOrig)
|
||||
{
|
||||
if (entry == NULL || entry->odObject == NULL) return ODR_IDX_NOT_EXIST;
|
||||
else if (io == NULL) return ODR_DEV_INCOMPAT;
|
||||
if (io == NULL) return ODR_DEV_INCOMPAT;
|
||||
|
||||
const void *odObjectOrig = entry->odObject;
|
||||
const OD_obj_extended_t *odObjectExt = NULL;
|
||||
uint8_t odBasicType = entry->odObjectType & ODT_TYPE_MASK;
|
||||
OD_attr_t attr = 0;
|
||||
OD_stream_t *stream = &io->stream;
|
||||
|
||||
/* Is object type extended? */
|
||||
if ((entry->odObjectType & ODT_EXTENSION_MASK) != 0) {
|
||||
odObjectExt = (const OD_obj_extended_t *)odObjectOrig;
|
||||
odObjectOrig = odObjectExt->odObjectOriginal;
|
||||
if (odObjectOrig == NULL) return ODR_DEV_INCOMPAT;
|
||||
}
|
||||
|
||||
/* attribute, dataObjectOriginal and dataLength, depends on object type */
|
||||
if (odBasicType == ODT_VAR) {
|
||||
/* attribute, dataOrig and dataLength, depends on object type */
|
||||
switch (entry->odObjectType & ODT_TYPE_MASK) {
|
||||
case ODT_VAR: {
|
||||
if (subIndex > 0) return ODR_SUB_NOT_EXIST;
|
||||
const OD_obj_var_t *odo = (const OD_obj_var_t *)odObjectOrig;
|
||||
CO_PROGMEM OD_obj_var_t *odo = entry->odObject;
|
||||
|
||||
attr = odo->attribute;
|
||||
io->stream.dataObjectOriginal = odo->data;
|
||||
io->stream.dataLength = odo->dataLength;
|
||||
|
||||
stream->attribute = odo->attribute;
|
||||
stream->dataOrig = odo->dataOrig;
|
||||
stream->dataLength = odo->dataLength;
|
||||
break;
|
||||
}
|
||||
else if (odBasicType == ODT_ARR) {
|
||||
case ODT_ARR: {
|
||||
if (subIndex >= entry->subEntriesCount) return ODR_SUB_NOT_EXIST;
|
||||
const OD_obj_array_t *odo = (const OD_obj_array_t *)odObjectOrig;
|
||||
CO_PROGMEM OD_obj_array_t *odo = entry->odObject;
|
||||
|
||||
if (subIndex == 0) {
|
||||
attr = odo->attribute0;
|
||||
io->stream.dataObjectOriginal = odo->data0;
|
||||
io->stream.dataLength = 1;
|
||||
stream->attribute = odo->attribute0;
|
||||
stream->dataOrig = odo->dataOrig0;
|
||||
stream->dataLength = 1;
|
||||
}
|
||||
else {
|
||||
attr = odo->attribute;
|
||||
if (odo->data == NULL) {
|
||||
io->stream.dataObjectOriginal = NULL;
|
||||
}
|
||||
else {
|
||||
uint8_t *data = odo->data;
|
||||
int i = subIndex - 1;
|
||||
io->stream.dataObjectOriginal = data + odo->dataElementSizeof * i;
|
||||
}
|
||||
io->stream.dataLength = odo->dataElementLength;
|
||||
stream->attribute = odo->attribute;
|
||||
uint8_t *ptr = odo->dataOrig;
|
||||
stream->dataOrig = ptr == NULL ? ptr
|
||||
: ptr + odo->dataElementSizeof * (subIndex - 1);
|
||||
stream->dataLength = odo->dataElementLength;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (odBasicType == ODT_REC) {
|
||||
const OD_obj_record_t *odoArr = (const OD_obj_record_t *)odObjectOrig;
|
||||
const OD_obj_record_t *odo = NULL;
|
||||
for (int i = 0; i< entry->subEntriesCount; i++) {
|
||||
case ODT_REC: {
|
||||
CO_PROGMEM OD_obj_record_t *odoArr = entry->odObject;
|
||||
CO_PROGMEM OD_obj_record_t *odo = NULL;
|
||||
for (uint8_t i = 0; i < entry->subEntriesCount; i++) {
|
||||
if (odoArr[i].subIndex == subIndex) {
|
||||
odo = &odoArr[i];
|
||||
break;
|
||||
|
|
@ -257,38 +246,33 @@ ODR_t OD_getSub(const OD_entry_t *entry, uint8_t subIndex,
|
|||
}
|
||||
if (odo == NULL) return ODR_SUB_NOT_EXIST;
|
||||
|
||||
attr = odo->attribute;
|
||||
io->stream.dataObjectOriginal = odo->data;
|
||||
io->stream.dataLength = odo->dataLength;
|
||||
stream->attribute = odo->attribute;
|
||||
stream->dataOrig = odo->dataOrig;
|
||||
stream->dataLength = odo->dataLength;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
default: {
|
||||
return ODR_DEV_INCOMPAT;
|
||||
}
|
||||
}
|
||||
|
||||
/* read, write and dataObject, direct or with IO extension */
|
||||
if (odObjectExt == NULL || odObjectExt->extIO == NULL || odOrig) {
|
||||
/* Access data from the original OD location */
|
||||
if (entry->extension == NULL || odOrig) {
|
||||
io->read = OD_readOriginal;
|
||||
io->write = OD_writeOriginal;
|
||||
io->stream.object = NULL;
|
||||
stream->object = NULL;
|
||||
}
|
||||
/* Access data from extension specified by application */
|
||||
else {
|
||||
io->read = odObjectExt->extIO->read != NULL ?
|
||||
odObjectExt->extIO->read : OD_readDisabled;
|
||||
io->write = odObjectExt->extIO->write != NULL ?
|
||||
odObjectExt->extIO->write : OD_writeDisabled;
|
||||
io->stream.object = odObjectExt->extIO->object;
|
||||
io->read = entry->extension->read != NULL ?
|
||||
entry->extension->read : OD_readDisabled;
|
||||
io->write = entry->extension->write != NULL ?
|
||||
entry->extension->write : OD_writeDisabled;
|
||||
stream->object = entry->extension->object;
|
||||
}
|
||||
|
||||
/* common properties */
|
||||
if (subEntry != NULL) {
|
||||
subEntry->index = entry->index;
|
||||
subEntry->subIndex = subIndex;
|
||||
subEntry->subEntriesCount = entry->subEntriesCount;
|
||||
subEntry->attribute = attr;
|
||||
subEntry->flagsPDO = odObjectExt != NULL ?
|
||||
odObjectExt->flagsPDO : NULL;
|
||||
}
|
||||
io->stream.dataOffset = 0;
|
||||
/* Reset stream data offset */
|
||||
stream->dataOffset = 0;
|
||||
|
||||
return ODR_OK;
|
||||
}
|
||||
|
|
@ -328,44 +312,13 @@ uint32_t OD_getSDOabCode(ODR_t returnCode) {
|
|||
abortCodes[ODR_DEV_INCOMPAT] : abortCodes[returnCode];
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
ODR_t OD_extensionIO_init(const OD_entry_t *entry,
|
||||
void *object,
|
||||
OD_size_t (*read)(OD_stream_t *stream,
|
||||
uint8_t subIndex,
|
||||
void *buf,
|
||||
OD_size_t count,
|
||||
ODR_t *returnCode),
|
||||
OD_size_t (*write)(OD_stream_t *stream,
|
||||
uint8_t subIndex,
|
||||
const void *buf,
|
||||
OD_size_t count,
|
||||
ODR_t *returnCode))
|
||||
{
|
||||
if (entry == NULL) {
|
||||
return ODR_IDX_NOT_EXIST;
|
||||
}
|
||||
|
||||
const OD_obj_extended_t *odo = (const OD_obj_extended_t *) entry->odObject;
|
||||
|
||||
if ((entry->odObjectType & ODT_EXTENSION_MASK) == 0 || odo->extIO == NULL) {
|
||||
return ODR_PAR_INCOMPAT;
|
||||
}
|
||||
|
||||
odo->extIO->object = object;
|
||||
odo->extIO->read = read;
|
||||
odo->extIO->write = write;
|
||||
|
||||
return ODR_OK;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
ODR_t OD_get_i8(const OD_entry_t *entry, uint8_t subIndex,
|
||||
int8_t *val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -377,7 +330,7 @@ ODR_t OD_get_i16(const OD_entry_t *entry, uint8_t subIndex,
|
|||
int16_t *val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -389,7 +342,7 @@ ODR_t OD_get_i32(const OD_entry_t *entry, uint8_t subIndex,
|
|||
int32_t *val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -401,7 +354,7 @@ ODR_t OD_get_i64(const OD_entry_t *entry, uint8_t subIndex,
|
|||
int64_t *val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -413,7 +366,7 @@ ODR_t OD_get_u8(const OD_entry_t *entry, uint8_t subIndex,
|
|||
uint8_t *val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -425,7 +378,7 @@ ODR_t OD_get_u16(const OD_entry_t *entry, uint8_t subIndex,
|
|||
uint16_t *val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -437,7 +390,7 @@ ODR_t OD_get_u32(const OD_entry_t *entry, uint8_t subIndex,
|
|||
uint32_t *val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -449,7 +402,7 @@ ODR_t OD_get_u64(const OD_entry_t *entry, uint8_t subIndex,
|
|||
uint64_t *val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -461,7 +414,7 @@ ODR_t OD_get_r32(const OD_entry_t *entry, uint8_t subIndex,
|
|||
float32_t *val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -473,7 +426,7 @@ ODR_t OD_get_r64(const OD_entry_t *entry, uint8_t subIndex,
|
|||
float64_t *val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(*val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -486,7 +439,7 @@ ODR_t OD_set_i8(const OD_entry_t *entry, uint8_t subIndex,
|
|||
int8_t val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -498,7 +451,7 @@ ODR_t OD_set_i16(const OD_entry_t *entry, uint8_t subIndex,
|
|||
int16_t val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -510,7 +463,7 @@ ODR_t OD_set_i32(const OD_entry_t *entry, uint8_t subIndex,
|
|||
int32_t val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -522,7 +475,7 @@ ODR_t OD_set_i64(const OD_entry_t *entry, uint8_t subIndex,
|
|||
int64_t val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -534,7 +487,7 @@ ODR_t OD_set_u8(const OD_entry_t *entry, uint8_t subIndex,
|
|||
uint8_t val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -546,7 +499,7 @@ ODR_t OD_set_u16(const OD_entry_t *entry, uint8_t subIndex,
|
|||
uint16_t val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -558,7 +511,7 @@ ODR_t OD_set_u32(const OD_entry_t *entry, uint8_t subIndex,
|
|||
uint32_t val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -570,7 +523,7 @@ ODR_t OD_set_u64(const OD_entry_t *entry, uint8_t subIndex,
|
|||
uint64_t val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -582,7 +535,7 @@ ODR_t OD_set_r32(const OD_entry_t *entry, uint8_t subIndex,
|
|||
float32_t val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -594,7 +547,7 @@ ODR_t OD_set_r64(const OD_entry_t *entry, uint8_t subIndex,
|
|||
float64_t val, bool_t odOrig)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, odOrig);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, odOrig);
|
||||
|
||||
if (ret == ODR_OK && io.stream.dataLength != sizeof(val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
|
|
@ -605,131 +558,131 @@ ODR_t OD_set_r64(const OD_entry_t *entry, uint8_t subIndex,
|
|||
/******************************************************************************/
|
||||
ODR_t OD_getPtr_i8(const OD_entry_t *entry, uint8_t subIndex, int8_t **val) {
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, true);
|
||||
|
||||
if (val == NULL || io.stream.dataObjectOriginal == NULL)
|
||||
if (val == NULL || io.stream.dataOrig == NULL)
|
||||
ret = ODR_DEV_INCOMPAT;
|
||||
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
else if (ret == ODR_OK)
|
||||
*val = (int8_t *)io.stream.dataObjectOriginal;
|
||||
*val = (int8_t *)io.stream.dataOrig;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ODR_t OD_getPtr_i16(const OD_entry_t *entry, uint8_t subIndex, int16_t **val) {
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, true);
|
||||
|
||||
if (val == NULL || io.stream.dataObjectOriginal == NULL)
|
||||
if (val == NULL || io.stream.dataOrig == NULL)
|
||||
ret = ODR_DEV_INCOMPAT;
|
||||
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
else if (ret == ODR_OK)
|
||||
*val = (int16_t *)io.stream.dataObjectOriginal;
|
||||
*val = (int16_t *)io.stream.dataOrig;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ODR_t OD_getPtr_i32(const OD_entry_t *entry, uint8_t subIndex, int32_t **val) {
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, true);
|
||||
|
||||
if (val == NULL || io.stream.dataObjectOriginal == NULL)
|
||||
if (val == NULL || io.stream.dataOrig == NULL)
|
||||
ret = ODR_DEV_INCOMPAT;
|
||||
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
else if (ret == ODR_OK)
|
||||
*val = (int32_t *)io.stream.dataObjectOriginal;
|
||||
*val = (int32_t *)io.stream.dataOrig;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ODR_t OD_getPtr_i64(const OD_entry_t *entry, uint8_t subIndex, int64_t **val) {
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, true);
|
||||
|
||||
if (val == NULL || io.stream.dataObjectOriginal == NULL)
|
||||
if (val == NULL || io.stream.dataOrig == NULL)
|
||||
ret = ODR_DEV_INCOMPAT;
|
||||
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
else if (ret == ODR_OK)
|
||||
*val = (int64_t *)io.stream.dataObjectOriginal;
|
||||
*val = (int64_t *)io.stream.dataOrig;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ODR_t OD_getPtr_u8(const OD_entry_t *entry, uint8_t subIndex, uint8_t **val) {
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, true);
|
||||
|
||||
if (val == NULL || io.stream.dataObjectOriginal == NULL)
|
||||
if (val == NULL || io.stream.dataOrig == NULL)
|
||||
ret = ODR_DEV_INCOMPAT;
|
||||
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
else if (ret == ODR_OK)
|
||||
*val = (uint8_t *)io.stream.dataObjectOriginal;
|
||||
*val = (uint8_t *)io.stream.dataOrig;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ODR_t OD_getPtr_u16(const OD_entry_t *entry, uint8_t subIndex, uint16_t **val) {
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, true);
|
||||
|
||||
if (val == NULL || io.stream.dataObjectOriginal == NULL)
|
||||
if (val == NULL || io.stream.dataOrig == NULL)
|
||||
ret = ODR_DEV_INCOMPAT;
|
||||
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
else if (ret == ODR_OK)
|
||||
*val = (uint16_t *)io.stream.dataObjectOriginal;
|
||||
*val = (uint16_t *)io.stream.dataOrig;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ODR_t OD_getPtr_u32(const OD_entry_t *entry, uint8_t subIndex, uint32_t **val) {
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, true);
|
||||
|
||||
if (val == NULL || io.stream.dataObjectOriginal == NULL)
|
||||
if (val == NULL || io.stream.dataOrig == NULL)
|
||||
ret = ODR_DEV_INCOMPAT;
|
||||
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
else if (ret == ODR_OK)
|
||||
*val = (uint32_t *)io.stream.dataObjectOriginal;
|
||||
*val = (uint32_t *)io.stream.dataOrig;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ODR_t OD_getPtr_u64(const OD_entry_t *entry, uint8_t subIndex, uint64_t **val) {
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, true);
|
||||
|
||||
if (val == NULL || io.stream.dataObjectOriginal == NULL)
|
||||
if (val == NULL || io.stream.dataOrig == NULL)
|
||||
ret = ODR_DEV_INCOMPAT;
|
||||
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
else if (ret == ODR_OK)
|
||||
*val = (uint64_t *)io.stream.dataObjectOriginal;
|
||||
*val = (uint64_t *)io.stream.dataOrig;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ODR_t OD_getPtr_r32(const OD_entry_t *entry, uint8_t subIndex, float32_t **val){
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, true);
|
||||
|
||||
if (val == NULL || io.stream.dataObjectOriginal == NULL)
|
||||
if (val == NULL || io.stream.dataOrig == NULL)
|
||||
ret = ODR_DEV_INCOMPAT;
|
||||
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
else if (ret == ODR_OK)
|
||||
*val = (float32_t *)io.stream.dataObjectOriginal;
|
||||
*val = (float32_t *)io.stream.dataOrig;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ODR_t OD_getPtr_r64(const OD_entry_t *entry, uint8_t subIndex, float64_t **val){
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, true);
|
||||
|
||||
if (val == NULL || io.stream.dataObjectOriginal == NULL)
|
||||
if (val == NULL || io.stream.dataOrig == NULL)
|
||||
ret = ODR_DEV_INCOMPAT;
|
||||
else if (ret == ODR_OK && io.stream.dataLength != sizeof(**val))
|
||||
ret = ODR_TYPE_MISMATCH;
|
||||
else if (ret == ODR_OK)
|
||||
*val = (float64_t *)io.stream.dataObjectOriginal;
|
||||
*val = (float64_t *)io.stream.dataOrig;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -737,15 +690,15 @@ ODR_t OD_getPtr_vs(const OD_entry_t *entry, uint8_t subIndex,
|
|||
char **val, OD_size_t *dataLength)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, true);
|
||||
|
||||
if (val == NULL || io.stream.dataObjectOriginal == NULL
|
||||
if (val == NULL || io.stream.dataOrig == NULL
|
||||
|| io.stream.dataLength == 0)
|
||||
{
|
||||
ret = ODR_DEV_INCOMPAT;
|
||||
}
|
||||
else if (ret == ODR_OK) {
|
||||
*val = (char *)io.stream.dataObjectOriginal;
|
||||
*val = (char *)io.stream.dataOrig;
|
||||
if (dataLength != NULL) *dataLength = io.stream.dataLength;
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -755,15 +708,15 @@ ODR_t OD_getPtr_os(const OD_entry_t *entry, uint8_t subIndex,
|
|||
uint8_t **val, OD_size_t *dataLength)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, true);
|
||||
|
||||
if (val == NULL || io.stream.dataObjectOriginal == NULL
|
||||
if (val == NULL || io.stream.dataOrig == NULL
|
||||
|| io.stream.dataLength == 0)
|
||||
{
|
||||
ret = ODR_DEV_INCOMPAT;
|
||||
}
|
||||
else if (ret == ODR_OK) {
|
||||
*val = (uint8_t *)io.stream.dataObjectOriginal;
|
||||
*val = (uint8_t *)io.stream.dataOrig;
|
||||
if (dataLength != NULL) *dataLength = io.stream.dataLength;
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -773,15 +726,15 @@ ODR_t OD_getPtr_us(const OD_entry_t *entry, uint8_t subIndex,
|
|||
uint16_t **val, OD_size_t *dataLength)
|
||||
{
|
||||
OD_IO_t io;
|
||||
ODR_t ret = OD_getSub(entry, subIndex, NULL, &io, true);
|
||||
ODR_t ret = OD_getSub(entry, subIndex, &io, true);
|
||||
|
||||
if (val == NULL || io.stream.dataObjectOriginal == NULL
|
||||
if (val == NULL || io.stream.dataOrig == NULL
|
||||
|| io.stream.dataLength == 0)
|
||||
{
|
||||
ret = ODR_DEV_INCOMPAT;
|
||||
}
|
||||
else if (ret == ODR_OK) {
|
||||
*val = (uint16_t *)io.stream.dataObjectOriginal;
|
||||
*val = (uint16_t *)io.stream.dataOrig;
|
||||
if (dataLength != NULL) *dataLength = io.stream.dataLength;
|
||||
}
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -39,15 +39,20 @@ extern "C" {
|
|||
* See @ref doc/objectDictionary.md
|
||||
*/
|
||||
|
||||
#ifndef OD_size_t
|
||||
#ifndef CO_OD_OWN_TYPES
|
||||
/** Variable of type OD_size_t contains data length in bytes of OD variable */
|
||||
#define OD_size_t uint32_t
|
||||
/** Type of flagsPDO variable from OD_subEntry_t */
|
||||
#define OD_flagsPDO_t uint32_t
|
||||
typedef uint32_t OD_size_t;
|
||||
/** Type (and size) of Object Dictionary attribute */
|
||||
typedef uint8_t OD_attr_t;
|
||||
/** Size of of flagsPDO variable inside OD_extension_t, from 1 to 64 */
|
||||
#define OD_FLAGS_PDO_SIZE 4
|
||||
#endif
|
||||
|
||||
/** Size of Object Dictionary attribute */
|
||||
#define OD_attr_t uint8_t
|
||||
#ifndef CO_PROGMEM
|
||||
/** Modifier for OD objects. This is large amount of data and is specified in
|
||||
* Object Dictionary (OD.c file usually) */
|
||||
#define CO_PROGMEM const
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -192,47 +197,6 @@ typedef enum {
|
|||
} ODR_t;
|
||||
|
||||
|
||||
/**
|
||||
* Structure describing properties of a variable, located in specific index and
|
||||
* sub-index inside the Object Dictionary.
|
||||
*
|
||||
* Structure is initialized with @ref OD_getSub() function.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Object Dictionary index */
|
||||
uint16_t index;
|
||||
/** Object Dictionary sub-index */
|
||||
uint8_t subIndex;
|
||||
/** Number of sub-entries in OD object. For VAR is 1, for ARRAY is
|
||||
* maxSubIndex + 1, for RECORD maxSubIndex may be larger, if there is a gap
|
||||
* between sub-indexes. */
|
||||
uint8_t subEntriesCount;
|
||||
/** Attribute bit-field of the OD sub-object, see @ref OD_attributes_t */
|
||||
OD_attr_t attribute;
|
||||
/**
|
||||
* Pointer to PDO flags bit-field. This is optional extension of OD object.
|
||||
* If OD object has enabled this extension, then each sub-element is coupled
|
||||
* with own flagsPDO variable of size 8 to 64 bits (size is configurable
|
||||
* by @ref OD_flagsPDO_t). Flag is useful, when variable is mapped to RPDO
|
||||
* or TPDO.
|
||||
*
|
||||
* If sub-element is mapped to RPDO, then bit0 is set to 1 each time, when
|
||||
* any RPDO writes new data into variable. Application may clear bit0.
|
||||
*
|
||||
* If sub-element is mapped to TPDO, then TPDO will set one bit on the time,
|
||||
* it is sent. First TPDO will set bit1, second TPDO will set bit2, etc. Up
|
||||
* to 63 TPDOs can use flagsPDO.
|
||||
*
|
||||
* Another functionality is with asynchronous TPDOs, to which variable may
|
||||
* be mapped. If corresponding bit is 0, TPDO will be sent. This means, that
|
||||
* if application sets variable pointed by flagsPDO to zero, it will trigger
|
||||
* sending all asynchronous TPDOs (up to first 63), to which variable is
|
||||
* mapped.
|
||||
*/
|
||||
OD_flagsPDO_t *flagsPDO;
|
||||
} OD_subEntry_t;
|
||||
|
||||
|
||||
/**
|
||||
* IO stream structure, used for read/write access to OD variable, part of
|
||||
* @ref OD_IO_t.
|
||||
|
|
@ -240,10 +204,10 @@ typedef struct {
|
|||
typedef struct {
|
||||
/** Pointer to original data object, defined by Object Dictionary. Default
|
||||
* read/write functions operate on it. If memory for data object is not
|
||||
* specified by Object Dictionary, then dataObjectOriginal is NULL.
|
||||
* specified by Object Dictionary, then dataOrig is NULL.
|
||||
*/
|
||||
void *dataObjectOriginal;
|
||||
/** Pointer to object, passed by @ref OD_extensionIO_init(). Can be used
|
||||
void *dataOrig;
|
||||
/** Pointer to object, passed by @ref OD_extension_init(). Can be used
|
||||
* inside read / write functions from IO extension.
|
||||
*/
|
||||
void *object;
|
||||
|
|
@ -252,6 +216,8 @@ typedef struct {
|
|||
/** In case of large data, dataOffset indicates position of already
|
||||
* transferred data */
|
||||
OD_size_t dataOffset;
|
||||
/** Attribute bit-field of the OD sub-object, see @ref OD_attributes_t */
|
||||
OD_attr_t attribute;
|
||||
} OD_stream_t;
|
||||
|
||||
|
||||
|
|
@ -277,9 +243,8 @@ typedef struct {
|
|||
* data from Object Dictionary variable. Application can bind its own "read"
|
||||
* function for specific object. In that case application is able to
|
||||
* calculate data for reading from own internal state at the moment of
|
||||
* "read" function call. For this functionality OD object must have IO
|
||||
* extension enabled. OD object must also be initialized with
|
||||
* @ref OD_extensionIO_init() function call.
|
||||
* "read" function call. Own "read" function on OD object can be initialized
|
||||
* with @ref OD_extension_init() function.
|
||||
*
|
||||
* "read" function must always copy all own data to buf, except if "buf" is
|
||||
* not large enough. ("*returnCode" must not return 'ODR_PARTIAL', if there
|
||||
|
|
@ -326,12 +291,51 @@ typedef struct {
|
|||
} OD_IO_t;
|
||||
|
||||
|
||||
/**
|
||||
* Extension of OD object, which can optionally be specified by application in
|
||||
* initialization phase with @ref OD_extension_init() function.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Object on which read and write will operate, part of @ref OD_stream_t */
|
||||
void *object;
|
||||
/** Application specified read function pointer. If NULL, then read will be
|
||||
* disabled. @ref OD_readOriginal can be used here to keep the original read
|
||||
* function. For function description see @ref OD_IO_t. */
|
||||
OD_size_t (*read)(OD_stream_t *stream, uint8_t subIndex,
|
||||
void *buf, OD_size_t count, ODR_t *returnCode);
|
||||
/** Application specified write function pointer. If NULL, then write will
|
||||
* be disabled. @ref OD_writeOriginal can be used here to keep the original
|
||||
* write function. For function description see @ref OD_IO_t. */
|
||||
OD_size_t (*write)(OD_stream_t *stream, uint8_t subIndex,
|
||||
const void *buf, OD_size_t count, ODR_t *returnCode);
|
||||
/**
|
||||
* PDO flags bit-field. If available, then each sub-element is coupled
|
||||
* with own flagsPDO variable of size 8 to 512 bits (size is configurable
|
||||
* by @ref OD_FLAGS_PDO_SIZE). Flag is useful, when variable is mapped to
|
||||
* RPDO or TPDO.
|
||||
*
|
||||
* If sub-element is mapped to RPDO, then bit0 is set to 1 each time, when
|
||||
* any RPDO writes new data into variable. Application may clear bit0.
|
||||
*
|
||||
* If sub-element is mapped to TPDO, then TPDO will set one bit on the time,
|
||||
* it is sent. First TPDO will set bit1, second TPDO will set bit2, etc.
|
||||
*
|
||||
* Another functionality is with asynchronous TPDOs, to which variable may
|
||||
* be mapped. If corresponding bit is 0, TPDO will be sent. This means, that
|
||||
* if application sets variable pointed by flagsPDO to zero, it will trigger
|
||||
* sending all asynchronous TPDOs, to which variable is mapped.
|
||||
*/
|
||||
uint8_t flagsPDO[OD_FLAGS_PDO_SIZE];
|
||||
} OD_extension_t;
|
||||
|
||||
|
||||
/**
|
||||
* Object Dictionary entry for one OD object.
|
||||
*
|
||||
* OD entries are collected inside OD_t as array (list). Each OD entry contains
|
||||
* basic information about OD object (index and subEntriesCount) and
|
||||
* access function together with a pointer to other details of the OD object.
|
||||
* basic information about OD object (index and subEntriesCount), pointer to
|
||||
* odObject with additional information about var, array or record entry and
|
||||
* pointer to extension, configurable by application.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Object Dictionary index */
|
||||
|
|
@ -342,7 +346,9 @@ typedef struct {
|
|||
uint8_t odObjectType;
|
||||
/** OD object of type indicated by odObjectType, from which @ref OD_getSub()
|
||||
* fetches the information */
|
||||
const void *odObject;
|
||||
CO_PROGMEM void *odObject;
|
||||
/** Extension to OD, specified by application */
|
||||
OD_extension_t *extension;
|
||||
} OD_entry_t;
|
||||
|
||||
|
||||
|
|
@ -353,7 +359,7 @@ typedef struct {
|
|||
/** Number of elements in the list, without last element, which is blank */
|
||||
uint16_t size;
|
||||
/** List OD entries (table of contents), ordered by index */
|
||||
const OD_entry_t *list;
|
||||
OD_entry_t *list;
|
||||
} OD_t;
|
||||
|
||||
|
||||
|
|
@ -361,7 +367,7 @@ typedef struct {
|
|||
* Read value from original OD location
|
||||
*
|
||||
* This function can be used inside read / write functions, specified by
|
||||
* @ref OD_extensionIO_init(). It reads data directly from memory location
|
||||
* @ref OD_extension_init(). It reads data directly from memory location
|
||||
* specified by Object dictionary. If no IO extension is used on OD entry, then
|
||||
* io->read returned by @ref OD_getSub() equals to this function. See
|
||||
* also @ref OD_IO_t.
|
||||
|
|
@ -374,7 +380,7 @@ OD_size_t OD_readOriginal(OD_stream_t *stream, uint8_t subIndex,
|
|||
* Write value to original OD location
|
||||
*
|
||||
* This function can be used inside read / write functions, specified by
|
||||
* @ref OD_extensionIO_init(). It writes data directly to memory location
|
||||
* @ref OD_extension_init(). It writes data directly to memory location
|
||||
* specified by Object dictionary. If no IO extension is used on OD entry, then
|
||||
* io->write returned by @ref OD_getSub() equals to this function. See
|
||||
* also @ref OD_IO_t.
|
||||
|
|
@ -391,16 +397,15 @@ OD_size_t OD_writeOriginal(OD_stream_t *stream, uint8_t subIndex,
|
|||
*
|
||||
* @return Pointer to OD entry or NULL if not found
|
||||
*/
|
||||
const OD_entry_t *OD_find(const OD_t *od, uint16_t index);
|
||||
OD_entry_t *OD_find(OD_t *od, uint16_t index);
|
||||
|
||||
|
||||
/**
|
||||
* Find sub-object with specified sub-index on OD entry returned by OD_find.
|
||||
* Function populates subEntry and io structures with sub-object data.
|
||||
* Function populates io structure with sub-object data.
|
||||
*
|
||||
* @param entry OD entry returned by @ref OD_find().
|
||||
* @param subIndex Sub-index of the variable from the OD object.
|
||||
* @param [out] subEntry Structure will be populated on success, may be NULL.
|
||||
* @param [out] io Structure will be populated on success.
|
||||
* @param odOrig If true, then potential IO extension on entry will be
|
||||
* ignored and access to data entry in the original OD location will be returned
|
||||
|
|
@ -408,7 +413,7 @@ const OD_entry_t *OD_find(const OD_t *od, uint16_t index);
|
|||
* @return Value from @ref ODR_t, "ODR_OK" in case of success.
|
||||
*/
|
||||
ODR_t OD_getSub(const OD_entry_t *entry, uint8_t subIndex,
|
||||
OD_subEntry_t *subEntry, OD_IO_t *io, bool_t odOrig);
|
||||
OD_IO_t *io, bool_t odOrig);
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -448,16 +453,20 @@ uint32_t OD_getSDOabCode(ODR_t returnCode);
|
|||
|
||||
|
||||
/**
|
||||
* Initialize extended OD object with own read/write functions
|
||||
* Extend OD object with own read/write functions and/or flagsPDO
|
||||
*
|
||||
* This function works on OD object, which has IO extension enabled. It gives
|
||||
* application very powerful tool: definition of own IO access on own OD
|
||||
* object. Structure and attributes are the same as defined in original OD
|
||||
* object, but data are read directly from (or written directly to) application
|
||||
* specified object via custom function calls.
|
||||
* This function gives application very powerful tool: definition of own IO
|
||||
* access on OD object. Structure and attributes are the same as defined in
|
||||
* original OD object, but data are read directly from (or written directly to)
|
||||
* application specified object via custom function calls.
|
||||
*
|
||||
* If this function is not called yet, then normal access ("odOrig" argument is
|
||||
* false) to OD entry is disabled.
|
||||
* Before this function specifies extension, OD variables are accessed from
|
||||
* original OD location. After this function specifies extension OD variables
|
||||
* are accessed from read/write functions specified by extension. (Except when
|
||||
* "odOrig" argument to @ref OD_getSub() is set to true.)
|
||||
*
|
||||
* This function must also be used, when flagsPDO needs to be enabled for
|
||||
* specific entry.
|
||||
*
|
||||
* @warning
|
||||
* Object dictionary storage works only directly on OD variables. It does not
|
||||
|
|
@ -471,29 +480,18 @@ uint32_t OD_getSDOabCode(ODR_t returnCode);
|
|||
* @ref CO_UNLOCK_OD().
|
||||
*
|
||||
* @param entry OD entry returned by @ref OD_find().
|
||||
* @param object Object, which will be passed to read or write function.
|
||||
* @param read Read function pointer. If NULL, then read will be disabled.
|
||||
* @ref OD_readOriginal can be used here to keep original read function.
|
||||
* For function description see @ref OD_IO_t.
|
||||
* @param write Write function pointer. If NULL, then write will be disabled.
|
||||
* @ref OD_writeOriginal can be used here to keep original write function.
|
||||
* For function description see @ref OD_IO_t.
|
||||
* @param extension Extension object, which must be initialized externally.
|
||||
* Extension object must exist permanently. If NULL, extension will be removed.
|
||||
*
|
||||
* @return "ODR_OK" on success, "ODR_IDX_NOT_EXIST" if OD object doesn't exist,
|
||||
* "ODR_PAR_INCOMPAT" if OD object is not extended.
|
||||
* @return "ODR_OK" on success, "ODR_IDX_NOT_EXIST" if OD object doesn't exist.
|
||||
*/
|
||||
ODR_t OD_extensionIO_init(const OD_entry_t *entry,
|
||||
void *object,
|
||||
OD_size_t (*read)(OD_stream_t *stream,
|
||||
uint8_t subIndex,
|
||||
void *buf,
|
||||
OD_size_t count,
|
||||
ODR_t *returnCode),
|
||||
OD_size_t (*write)(OD_stream_t *stream,
|
||||
uint8_t subIndex,
|
||||
const void *buf,
|
||||
OD_size_t count,
|
||||
ODR_t *returnCode));
|
||||
static inline ODR_t OD_extension_init(OD_entry_t *entry,
|
||||
OD_extension_t *extension)
|
||||
{
|
||||
if (entry == NULL) return ODR_IDX_NOT_EXIST;
|
||||
entry->extension = extension;
|
||||
return ODR_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -592,7 +590,7 @@ ODR_t OD_set_r64(const OD_entry_t *entry, uint8_t subIndex,
|
|||
/**
|
||||
* Get pointer to int8_t variable from Object Dictionary
|
||||
*
|
||||
* Function always returns "dataObjectOriginal" pointer, which points to data
|
||||
* Function always returns "dataOrig" pointer, which points to data
|
||||
* in the original OD location. Take care, if IO extension is enabled on OD
|
||||
* entry.
|
||||
*
|
||||
|
|
@ -626,7 +624,7 @@ ODR_t OD_getPtr_r64(const OD_entry_t *entry, uint8_t subIndex, float64_t **val);
|
|||
/**
|
||||
* Get pointer to "visible string" variable from Object Dictionary
|
||||
*
|
||||
* Function always returns "dataObjectOriginal" pointer, which points to data
|
||||
* Function always returns "dataOrig" pointer, which points to data
|
||||
* in the original OD location. Take care, if IO extension is enabled on OD
|
||||
* entry.
|
||||
*
|
||||
|
|
@ -680,26 +678,15 @@ typedef enum {
|
|||
* @ref OD_obj_var_t. Variable at sub-index 0 is of type uint8_t and usually
|
||||
* represents number of sub-elements in the structure. */
|
||||
ODT_REC = 0x03,
|
||||
|
||||
/** Same as ODT_VAR, but extended with OD_obj_extended_t type. It includes
|
||||
* additional pointer to IO extension and PDO flags */
|
||||
ODT_EVAR = 0x11,
|
||||
/** Same as ODT_ARR, but extended with OD_obj_extended_t type */
|
||||
ODT_EARR = 0x12,
|
||||
/** Same as ODT_REC, but extended with OD_obj_extended_t type */
|
||||
ODT_EREC = 0x13,
|
||||
|
||||
/** Mask for basic type */
|
||||
ODT_TYPE_MASK = 0x0F,
|
||||
/** Mask for extension */
|
||||
ODT_EXTENSION_MASK = 0x10
|
||||
} OD_objectTypes_t;
|
||||
|
||||
/**
|
||||
* Object for single OD variable, used for "VAR" type OD objects
|
||||
*/
|
||||
typedef struct {
|
||||
void *data; /**< Pointer to data */
|
||||
void *dataOrig; /**< Pointer to data */
|
||||
OD_attr_t attribute; /**< Attribute bitfield, see @ref OD_attributes_t */
|
||||
OD_size_t dataLength; /**< Data length in bytes */
|
||||
} OD_obj_var_t;
|
||||
|
|
@ -708,8 +695,8 @@ typedef struct {
|
|||
* Object for OD array of variables, used for "ARRAY" type OD objects
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t *data0; /**< Pointer to data for sub-index 0 */
|
||||
void *data; /**< Pointer to array of data */
|
||||
uint8_t *dataOrig0; /**< Pointer to data for sub-index 0 */
|
||||
void *dataOrig; /**< Pointer to array of data */
|
||||
OD_attr_t attribute0; /**< Attribute bitfield for sub-index 0, see
|
||||
@ref OD_attributes_t */
|
||||
OD_attr_t attribute; /**< Attribute bitfield for array elements */
|
||||
|
|
@ -721,40 +708,12 @@ typedef struct {
|
|||
* Object for OD sub-elements, used in "RECORD" type OD objects
|
||||
*/
|
||||
typedef struct {
|
||||
void *data; /**< Pointer to data */
|
||||
void *dataOrig; /**< Pointer to data */
|
||||
uint8_t subIndex; /**< Sub index of element. */
|
||||
OD_attr_t attribute; /**< Attribute bitfield, see @ref OD_attributes_t */
|
||||
OD_size_t dataLength; /**< Data length in bytes */
|
||||
} OD_obj_record_t;
|
||||
|
||||
/**
|
||||
* Object pointed by @ref OD_obj_extended_t contains application specified
|
||||
* parameters for extended OD object
|
||||
*/
|
||||
typedef struct {
|
||||
/** Object on which read and write will operate */
|
||||
void *object;
|
||||
/** Application specified function pointer, see @ref OD_IO_t. */
|
||||
OD_size_t (*read)(OD_stream_t *stream, uint8_t subIndex,
|
||||
void *buf, OD_size_t count, ODR_t *returnCode);
|
||||
/** Application specified function pointer, see @ref OD_IO_t. */
|
||||
OD_size_t (*write)(OD_stream_t *stream, uint8_t subIndex,
|
||||
const void *buf, OD_size_t count, ODR_t *returnCode);
|
||||
} OD_extensionIO_t;
|
||||
|
||||
/**
|
||||
* Object for extended type of OD variable, configurable by
|
||||
* @ref OD_extensionIO_init() function
|
||||
*/
|
||||
typedef struct {
|
||||
/** Pointer to application specified IO extension, may be NULL. */
|
||||
OD_extensionIO_t *extIO;
|
||||
/** Pointer to PDO flags bit-field, see @ref OD_subEntry_t, may be NULL. */
|
||||
OD_flagsPDO_t *flagsPDO;
|
||||
/** Pointer to original odObject, see @ref OD_entry_t. */
|
||||
const void *odObjectOriginal;
|
||||
} OD_obj_extended_t;
|
||||
|
||||
/** @} */ /* CO_ODdefinition */
|
||||
|
||||
#endif /* defined OD_DEFINITION */
|
||||
|
|
|
|||
|
|
@ -249,8 +249,8 @@ static OD_size_t OD_write_1280(OD_stream_t *stream, uint8_t subIndex,
|
|||
|
||||
/******************************************************************************/
|
||||
CO_ReturnError_t CO_SDOclient_init(CO_SDOclient_t *SDO_C,
|
||||
const OD_t *OD,
|
||||
const OD_entry_t *OD_1280_SDOcliPar,
|
||||
OD_t *OD,
|
||||
OD_entry_t *OD_1280_SDOcliPar,
|
||||
uint8_t nodeId,
|
||||
CO_CANmodule_t *CANdevRx,
|
||||
uint16_t CANdevRxIdx,
|
||||
|
|
@ -300,10 +300,11 @@ CO_ReturnError_t CO_SDOclient_init(CO_SDOclient_t *SDO_C,
|
|||
}
|
||||
|
||||
#if (CO_CONFIG_SDO_CLI) & CO_CONFIG_FLAG_OD_DYNAMIC
|
||||
ODR_t odRetE = OD_extensionIO_init(OD_1280_SDOcliPar,
|
||||
(void *)SDO_C,
|
||||
OD_readOriginal,
|
||||
OD_write_1280);
|
||||
SDO_C->OD_1280_extension.object = SDO_C;
|
||||
SDO_C->OD_1280_extension.read = OD_readOriginal;
|
||||
SDO_C->OD_1280_extension.write = OD_write_1280;
|
||||
ODR_t odRetE = OD_extension_init(OD_1280_SDOcliPar,
|
||||
&SDO_C->OD_1280_extension);
|
||||
if (odRetE != ODR_OK) {
|
||||
CO_errinfo(CANdevTx, OD_getIndex(OD_1280_SDOcliPar));
|
||||
return CO_ERROR_OD_PARAMETERS;
|
||||
|
|
@ -535,22 +536,19 @@ CO_SDO_return_t CO_SDOclientDownload(CO_SDOclient_t *SDO_C,
|
|||
/* search object dictionary in first pass */
|
||||
if (SDO_C->OD_IO.write == NULL) {
|
||||
ODR_t odRet;
|
||||
OD_subEntry_t subEntry;
|
||||
|
||||
odRet = OD_getSub(OD_find(SDO_C->OD, SDO_C->index), SDO_C->subIndex,
|
||||
&subEntry, &SDO_C->OD_IO, false);
|
||||
|
||||
SDO_C->attribute = subEntry.attribute;
|
||||
&SDO_C->OD_IO, false);
|
||||
|
||||
if (odRet != ODR_OK) {
|
||||
abortCode = (CO_SDO_abortCode_t)OD_getSDOabCode(odRet);
|
||||
ret = CO_SDO_RT_endedWithClientAbort;
|
||||
}
|
||||
else if ((SDO_C->attribute & ODA_SDO_RW) == 0) {
|
||||
else if ((SDO_C->OD_IO.stream.attribute & ODA_SDO_RW) == 0) {
|
||||
abortCode = CO_SDO_AB_UNSUPPORTED_ACCESS;
|
||||
ret = CO_SDO_RT_endedWithClientAbort;
|
||||
}
|
||||
else if ((SDO_C->attribute & ODA_SDO_W) == 0) {
|
||||
else if ((SDO_C->OD_IO.stream.attribute & ODA_SDO_W) == 0) {
|
||||
abortCode = CO_SDO_AB_READONLY;
|
||||
ret = CO_SDO_RT_endedWithClientAbort;
|
||||
}
|
||||
|
|
@ -589,7 +587,7 @@ CO_SDO_return_t CO_SDOclientDownload(CO_SDOclient_t *SDO_C,
|
|||
else if (!bufferPartial) {
|
||||
#ifdef CO_BIG_ENDIAN
|
||||
/* swap int16_t .. uint64_t data if necessary */
|
||||
if ((SDO_C->attribute & ODA_MB) != 0) {
|
||||
if ((SDO_C->OD_IO.stream.attribute & ODA_MB) != 0) {
|
||||
reverseBytes(buf, count);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -599,7 +597,7 @@ CO_SDO_return_t CO_SDOclientDownload(CO_SDOclient_t *SDO_C,
|
|||
* shorter than size of OD data buffer. If so, add two zero
|
||||
* bytes to terminate (unicode) string. Shorten also OD data
|
||||
* size, (temporary, send info about EOF into OD_IO.write) */
|
||||
if ((SDO_C->attribute & ODA_STR) != 0
|
||||
if ((SDO_C->OD_IO.stream.attribute & ODA_STR) != 0
|
||||
&& (sizeInOd == 0 || SDO_C->sizeTran < sizeInOd)
|
||||
) {
|
||||
buf[count++] = 0;
|
||||
|
|
@ -1175,22 +1173,19 @@ CO_SDO_return_t CO_SDOclientUpload(CO_SDOclient_t *SDO_C,
|
|||
/* search object dictionary in first pass */
|
||||
if (SDO_C->OD_IO.read == NULL) {
|
||||
ODR_t odRet;
|
||||
OD_subEntry_t subEntry;
|
||||
|
||||
odRet = OD_getSub(OD_find(SDO_C->OD, SDO_C->index), SDO_C->subIndex,
|
||||
&subEntry, &SDO_C->OD_IO, false);
|
||||
|
||||
SDO_C->attribute = subEntry.attribute;
|
||||
&SDO_C->OD_IO, false);
|
||||
|
||||
if (odRet != ODR_OK) {
|
||||
abortCode = (CO_SDO_abortCode_t)OD_getSDOabCode(odRet);
|
||||
ret = CO_SDO_RT_endedWithClientAbort;
|
||||
}
|
||||
else if ((SDO_C->attribute & ODA_SDO_RW) == 0) {
|
||||
else if ((SDO_C->OD_IO.stream.attribute & ODA_SDO_RW) == 0) {
|
||||
abortCode = CO_SDO_AB_UNSUPPORTED_ACCESS;
|
||||
ret = CO_SDO_RT_endedWithClientAbort;
|
||||
}
|
||||
else if ((SDO_C->attribute & ODA_SDO_R) == 0) {
|
||||
else if ((SDO_C->OD_IO.stream.attribute & ODA_SDO_R) == 0) {
|
||||
abortCode = CO_SDO_AB_WRITEONLY;
|
||||
ret = CO_SDO_RT_endedWithClientAbort;
|
||||
}
|
||||
|
|
@ -1227,10 +1222,12 @@ CO_SDO_return_t CO_SDOclientUpload(CO_SDOclient_t *SDO_C,
|
|||
}
|
||||
else {
|
||||
/* if data is string, send only data up to null termination */
|
||||
if (countRd > 0 && (SDO_C->attribute & ODA_STR) != 0) {
|
||||
if (countRd > 0
|
||||
&& (SDO_C->OD_IO.stream.attribute & ODA_STR) != 0
|
||||
) {
|
||||
buf[countRd] = 0; /* (buf is one byte larger) */
|
||||
OD_size_t countStr = strlen((char *)buf);
|
||||
if (countStr == 0) countStr = 1; /* ne zero length */
|
||||
if (countStr == 0) countStr = 1; /* no zero length */
|
||||
if (countStr < countRd) {
|
||||
/* string terminator found, finish read, shorten data */
|
||||
countRd = countStr;
|
||||
|
|
|
|||
|
|
@ -67,13 +67,11 @@ extern "C" {
|
|||
typedef struct {
|
||||
#if ((CO_CONFIG_SDO_CLI) & CO_CONFIG_SDO_CLI_LOCAL) || defined CO_DOXYGEN
|
||||
/** From CO_SDOclient_init() */
|
||||
const OD_t *OD;
|
||||
OD_t *OD;
|
||||
/** From CO_SDOclient_init() */
|
||||
uint8_t nodeId;
|
||||
/** Object dictionary interface for locally transferred object */
|
||||
OD_IO_t OD_IO;
|
||||
/** Attribute for locally transferred OD sub-object, see OD_attributes_t */
|
||||
OD_attr_t attribute;
|
||||
#endif
|
||||
/** From CO_SDOclient_init() */
|
||||
CO_CANmodule_t *CANdevRx;
|
||||
|
|
@ -93,6 +91,8 @@ typedef struct {
|
|||
uint32_t COB_IDClientToServer;
|
||||
/** Copy of CANopen COB_ID Server -> Client, similar as above */
|
||||
uint32_t COB_IDServerToClient;
|
||||
/** Extension for OD object */
|
||||
OD_extension_t OD_1280_extension;
|
||||
#endif
|
||||
/** Node-ID of the SDO server */
|
||||
uint8_t nodeIDOfTheSDOServer;
|
||||
|
|
@ -177,8 +177,8 @@ typedef struct {
|
|||
* @return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT.
|
||||
*/
|
||||
CO_ReturnError_t CO_SDOclient_init(CO_SDOclient_t *SDO_C,
|
||||
const OD_t *OD,
|
||||
const OD_entry_t *OD_1280_SDOcliPar,
|
||||
OD_t *OD,
|
||||
OD_entry_t *OD_1280_SDOcliPar,
|
||||
uint8_t nodeId,
|
||||
CO_CANmodule_t *CANdevRx,
|
||||
uint16_t CANdevRxIdx,
|
||||
|
|
|
|||
|
|
@ -163,46 +163,6 @@ static void CO_SDO_receive(void *object, void *msg) {
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Custom function for reading OD variable _SDO server parameter_, default
|
||||
* channel
|
||||
*
|
||||
* For more information see file CO_ODinterface.h, OD_IO_t.
|
||||
*/
|
||||
static OD_size_t OD_read_1200_default(OD_stream_t *stream, uint8_t subIndex,
|
||||
void *buf, OD_size_t count,
|
||||
ODR_t *returnCode)
|
||||
{
|
||||
if (stream == NULL || buf == NULL || returnCode == NULL
|
||||
|| count < 1 || (count < 4 && subIndex > 0)
|
||||
) {
|
||||
if (returnCode != NULL) *returnCode = ODR_DEV_INCOMPAT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
CO_SDOserver_t *SDO = (CO_SDOserver_t *)stream->object;
|
||||
*returnCode = ODR_OK;
|
||||
|
||||
switch (subIndex) {
|
||||
case 0: /* Highest sub-index supported */
|
||||
CO_setUint8(buf, 2);
|
||||
return stream->dataLength = sizeof(uint8_t);
|
||||
|
||||
case 1: /* COB-ID client -> server */
|
||||
CO_setUint32(buf, CO_CAN_ID_SDO_CLI + SDO->nodeId);
|
||||
return stream->dataLength = sizeof(uint32_t);
|
||||
|
||||
case 2: /* COB-ID server -> client */
|
||||
CO_setUint32(buf, CO_CAN_ID_SDO_SRV + SDO->nodeId);
|
||||
return stream->dataLength = sizeof(uint32_t);
|
||||
|
||||
default:
|
||||
*returnCode = ODR_SUB_NOT_EXIST;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* helper for configuring CANrx and CANtx *************************************/
|
||||
static CO_ReturnError_t CO_SDOserver_init_canRxTx(CO_SDOserver_t *SDO,
|
||||
CO_CANmodule_t *CANdevRx,
|
||||
|
|
@ -355,8 +315,8 @@ static OD_size_t OD_write_1201_additional(OD_stream_t *stream, uint8_t subIndex,
|
|||
|
||||
/******************************************************************************/
|
||||
CO_ReturnError_t CO_SDOserver_init(CO_SDOserver_t *SDO,
|
||||
const OD_t *OD,
|
||||
const OD_entry_t *OD_1200_SDOsrvPar,
|
||||
OD_t *OD,
|
||||
OD_entry_t *OD_1200_SDOsrvPar,
|
||||
uint8_t nodeId,
|
||||
uint16_t SDOtimeoutTime_ms,
|
||||
CO_CANmodule_t *CANdevRx,
|
||||
|
|
@ -385,6 +345,7 @@ CO_ReturnError_t CO_SDOserver_init(CO_SDOserver_t *SDO,
|
|||
|
||||
/* configure CAN identifiers and SDO server parameters if available */
|
||||
uint16_t CanId_ClientToServer, CanId_ServerToClient;
|
||||
uint16_t OD_SDOsrvParIdx = OD_getIndex(OD_1200_SDOsrvPar);
|
||||
|
||||
if (OD_1200_SDOsrvPar == NULL) {
|
||||
/* configure default SDO channel */
|
||||
|
|
@ -394,24 +355,19 @@ CO_ReturnError_t CO_SDOserver_init(CO_SDOserver_t *SDO,
|
|||
CanId_ServerToClient = CO_CAN_ID_SDO_SRV + nodeId;
|
||||
SDO->valid = true;
|
||||
}
|
||||
else if (OD_getIndex(OD_1200_SDOsrvPar) == OD_H1200_SDO_SERVER_1_PARAM) {
|
||||
else if (OD_SDOsrvParIdx == OD_H1200_SDO_SERVER_1_PARAM) {
|
||||
/* configure default SDO channel and SDO server parameters for it */
|
||||
if (nodeId < 1 || nodeId > 127) return CO_ERROR_ILLEGAL_ARGUMENT;
|
||||
|
||||
CanId_ClientToServer = CO_CAN_ID_SDO_CLI + nodeId;
|
||||
CanId_ServerToClient = CO_CAN_ID_SDO_SRV + nodeId;
|
||||
SDO->valid = true;
|
||||
ODR_t odRetE = OD_extensionIO_init(OD_1200_SDOsrvPar,
|
||||
(void *) SDO,
|
||||
OD_read_1200_default,
|
||||
NULL);
|
||||
if (odRetE != ODR_OK) {
|
||||
CO_errinfo(CANdevTx, OD_getIndex(OD_1200_SDOsrvPar));
|
||||
return CO_ERROR_OD_PARAMETERS;
|
||||
}
|
||||
|
||||
OD_set_u32(OD_1200_SDOsrvPar, 1, CanId_ClientToServer, true);
|
||||
OD_set_u32(OD_1200_SDOsrvPar, 2, CanId_ServerToClient, true);
|
||||
}
|
||||
else if (OD_getIndex(OD_1200_SDOsrvPar) > OD_H1200_SDO_SERVER_1_PARAM
|
||||
&& OD_getIndex(OD_1200_SDOsrvPar) <= (OD_H1200_SDO_SERVER_1_PARAM+0x7F)
|
||||
else if (OD_SDOsrvParIdx > OD_H1200_SDO_SERVER_1_PARAM
|
||||
&& OD_SDOsrvParIdx <= (OD_H1200_SDO_SERVER_1_PARAM + 0x7F)
|
||||
) {
|
||||
/* configure additional SDO channel and SDO server parameters for it */
|
||||
uint8_t maxSubIndex;
|
||||
|
|
@ -427,7 +383,7 @@ CO_ReturnError_t CO_SDOserver_init(CO_SDOserver_t *SDO,
|
|||
if (odRet0 != ODR_OK || (maxSubIndex != 2 && maxSubIndex != 3)
|
||||
|| odRet1 != ODR_OK || odRet2 != ODR_OK
|
||||
) {
|
||||
CO_errinfo(CANdevTx, OD_getIndex(OD_1200_SDOsrvPar));
|
||||
CO_errinfo(CANdevTx, OD_SDOsrvParIdx);
|
||||
return CO_ERROR_OD_PARAMETERS;
|
||||
}
|
||||
|
||||
|
|
@ -438,12 +394,13 @@ CO_ReturnError_t CO_SDOserver_init(CO_SDOserver_t *SDO,
|
|||
? (uint16_t)(COB_IDServerToClient32 & 0x7FF) : 0;
|
||||
|
||||
#if (CO_CONFIG_SDO_SRV) & CO_CONFIG_FLAG_OD_DYNAMIC
|
||||
ODR_t odRetE = OD_extensionIO_init(OD_1200_SDOsrvPar,
|
||||
(void *) SDO,
|
||||
OD_readOriginal,
|
||||
OD_write_1201_additional);
|
||||
SDO->OD_1200_extension.object = SDO;
|
||||
SDO->OD_1200_extension.read = OD_readOriginal;
|
||||
SDO->OD_1200_extension.write = OD_write_1201_additional;
|
||||
ODR_t odRetE = OD_extension_init(OD_1200_SDOsrvPar,
|
||||
&SDO->OD_1200_extension);
|
||||
if (odRetE != ODR_OK) {
|
||||
CO_errinfo(CANdevTx, OD_getIndex(OD_1200_SDOsrvPar));
|
||||
CO_errinfo(CANdevTx, OD_SDOsrvParIdx);
|
||||
return CO_ERROR_OD_PARAMETERS;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -532,7 +489,7 @@ static bool_t validateAndWriteToOD(CO_SDOserver_t *SDO,
|
|||
|
||||
#ifdef CO_BIG_ENDIAN
|
||||
/* swap int16_t .. uint64_t data if necessary */
|
||||
if ((SDO->attribute & ODA_MB) != 0) {
|
||||
if ((SDO->OD_IO.stream.attribute & ODA_MB) != 0) {
|
||||
reverseBytes(SDO->buf, SDO->bufOffsetWr);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -543,7 +500,7 @@ static bool_t validateAndWriteToOD(CO_SDOserver_t *SDO,
|
|||
* shorter than size of OD data buffer. If so, add two zero bytes
|
||||
* to terminate (unicode) string. Shorten also OD data size,
|
||||
* (temporary, send information about EOF into OD_IO.write) */
|
||||
if ((SDO->attribute & ODA_STR) != 0
|
||||
if ((SDO->OD_IO.stream.attribute & ODA_STR) != 0
|
||||
&& (sizeInOd == 0 || SDO->sizeTran < sizeInOd)
|
||||
&& (SDO->bufOffsetWr + 2) <= CO_CONFIG_SDO_SRV_BUFFER_SIZE
|
||||
) {
|
||||
|
|
@ -661,7 +618,7 @@ static bool_t readFromOd(CO_SDOserver_t *SDO,
|
|||
}
|
||||
|
||||
/* if data is string, send only data up to null termination */
|
||||
if (countRd > 0 && (SDO->attribute & ODA_STR) != 0) {
|
||||
if (countRd > 0 && (SDO->OD_IO.stream.attribute & ODA_STR) != 0) {
|
||||
bufShifted[countRd] = 0; /* (SDO->buf is one byte larger) */
|
||||
OD_size_t countStr = strlen((char *)bufShifted);
|
||||
if (countStr == 0) countStr = 1; /* zero length is not allowed */
|
||||
|
|
@ -689,7 +646,7 @@ static bool_t readFromOd(CO_SDOserver_t *SDO,
|
|||
|
||||
#ifdef CO_BIG_ENDIAN
|
||||
/* swap data if necessary */
|
||||
if ((SDO->attribute & ODA_MB) != 0) {
|
||||
if ((SDO->OD_IO.stream.attribute & ODA_MB) != 0) {
|
||||
if (SDO->finished) {
|
||||
/* int16_t .. uint64_t */
|
||||
reverseBytes(bufShifted, countRd);
|
||||
|
|
@ -771,30 +728,30 @@ CO_SDO_return_t CO_SDOserver_process(CO_SDOserver_t *SDO,
|
|||
/* if no error search object dictionary for new SDO request */
|
||||
if (abortCode == CO_SDO_AB_NONE) {
|
||||
ODR_t odRet;
|
||||
OD_subEntry_t subEntry;
|
||||
|
||||
SDO->index = ((uint16_t)SDO->CANrxData[2]) << 8
|
||||
| SDO->CANrxData[1];
|
||||
SDO->subIndex = SDO->CANrxData[3];
|
||||
odRet = OD_getSub(OD_find(SDO->OD, SDO->index), SDO->subIndex,
|
||||
&subEntry, &SDO->OD_IO, false);
|
||||
&SDO->OD_IO, false);
|
||||
if (odRet != ODR_OK) {
|
||||
abortCode = (CO_SDO_abortCode_t)OD_getSDOabCode(odRet);
|
||||
SDO->state = CO_SDO_ST_ABORT;
|
||||
}
|
||||
else {
|
||||
SDO->attribute = subEntry.attribute;
|
||||
|
||||
/* verify read/write attributes */
|
||||
if ((SDO->attribute & ODA_SDO_RW) == 0) {
|
||||
if ((SDO->OD_IO.stream.attribute & ODA_SDO_RW) == 0) {
|
||||
abortCode = CO_SDO_AB_UNSUPPORTED_ACCESS;
|
||||
SDO->state = CO_SDO_ST_ABORT;
|
||||
}
|
||||
else if (upload && (SDO->attribute & ODA_SDO_R) == 0) {
|
||||
else if (upload
|
||||
&& (SDO->OD_IO.stream.attribute & ODA_SDO_R) == 0
|
||||
) {
|
||||
abortCode = CO_SDO_AB_WRITEONLY;
|
||||
SDO->state = CO_SDO_ST_ABORT;
|
||||
}
|
||||
else if (!upload && (SDO->attribute & ODA_SDO_W) == 0) {
|
||||
else if (!upload
|
||||
&& (SDO->OD_IO.stream.attribute & ODA_SDO_W) == 0
|
||||
) {
|
||||
abortCode = CO_SDO_AB_READONLY;
|
||||
SDO->state = CO_SDO_ST_ABORT;
|
||||
}
|
||||
|
|
@ -825,7 +782,7 @@ CO_SDO_return_t CO_SDOserver_process(CO_SDOserver_t *SDO,
|
|||
}
|
||||
else {
|
||||
/* If data type is string, size is not known */
|
||||
SDO->sizeInd = (SDO->attribute & ODA_STR) == 0
|
||||
SDO->sizeInd = (SDO->OD_IO.stream.attribute&ODA_STR)==0
|
||||
? SDO->OD_IO.stream.dataLength
|
||||
: 0;
|
||||
}
|
||||
|
|
@ -854,7 +811,7 @@ CO_SDO_return_t CO_SDOserver_process(CO_SDOserver_t *SDO,
|
|||
uint8_t buf[6] = {0};
|
||||
memcpy(buf, &SDO->CANrxData[4], dataSizeToWrite);
|
||||
#ifdef CO_BIG_ENDIAN
|
||||
if ((SDO->attribute & ODA_MB) != 0) {
|
||||
if ((SDO->OD_IO.stream.attribute & ODA_MB) != 0) {
|
||||
reverseBytes(buf, dataSizeToWrite);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -863,7 +820,7 @@ CO_SDO_return_t CO_SDOserver_process(CO_SDOserver_t *SDO,
|
|||
* shorter as size of OD data buffer. If so, add two zero bytes
|
||||
* to terminate (unicode) string. Shorten also OD data size,
|
||||
* (temporary, send information about EOF into OD_IO.write) */
|
||||
if ((SDO->attribute & ODA_STR) != 0
|
||||
if ((SDO->OD_IO.stream.attribute & ODA_STR) != 0
|
||||
&& (sizeInOd == 0 || dataSizeToWrite < sizeInOd)
|
||||
) {
|
||||
OD_size_t delta = sizeInOd - dataSizeToWrite;
|
||||
|
|
@ -916,7 +873,7 @@ CO_SDO_return_t CO_SDOserver_process(CO_SDOserver_t *SDO,
|
|||
}
|
||||
/* strings are allowed to be shorter */
|
||||
else if (SDO->sizeInd < sizeInOd
|
||||
&& (SDO->attribute & ODA_STR) == 0
|
||||
&& (SDO->OD_IO.stream.attribute & ODA_STR) == 0
|
||||
) {
|
||||
abortCode = CO_SDO_AB_DATA_SHORT;
|
||||
SDO->state = CO_SDO_ST_ABORT;
|
||||
|
|
@ -1029,7 +986,7 @@ CO_SDO_return_t CO_SDOserver_process(CO_SDOserver_t *SDO,
|
|||
}
|
||||
/* strings are allowed to be shorter */
|
||||
else if (SDO->sizeInd < sizeInOd
|
||||
&& (SDO->attribute & ODA_STR) == 0
|
||||
&& (SDO->OD_IO.stream.attribute & ODA_STR) == 0
|
||||
) {
|
||||
abortCode = CO_SDO_AB_DATA_SHORT;
|
||||
SDO->state = CO_SDO_ST_ABORT;
|
||||
|
|
@ -1324,7 +1281,9 @@ CO_SDO_return_t CO_SDOserver_process(CO_SDOserver_t *SDO,
|
|||
&odRet);
|
||||
|
||||
/* strings are allowed to be shorter */
|
||||
if (odRet == ODR_PARTIAL && (SDO->attribute & ODA_STR) != 0) {
|
||||
if (odRet == ODR_PARTIAL
|
||||
&& (SDO->OD_IO.stream.attribute & ODA_STR) != 0
|
||||
) {
|
||||
odRet = ODR_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1337,7 +1296,7 @@ CO_SDO_return_t CO_SDOserver_process(CO_SDOserver_t *SDO,
|
|||
|
||||
#ifdef CO_BIG_ENDIAN
|
||||
/* swap data if necessary */
|
||||
if ((SDO->attribute & ODA_MB) != 0) {
|
||||
if ((SDO->OD_IO.stream.attribute & ODA_MB) != 0) {
|
||||
reverseBytes(buf, dataSizeToWrite);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -442,7 +442,7 @@ typedef struct {
|
|||
/** CAN transmit buffer inside CANdevTx for CAN tx message */
|
||||
CO_CANtx_t *CANtxBuff;
|
||||
/** From CO_SDOserver_init() */
|
||||
const OD_t *OD;
|
||||
OD_t *OD;
|
||||
/** From CO_SDOserver_init() */
|
||||
uint8_t nodeId;
|
||||
/* If true, SDO channel is valid */
|
||||
|
|
@ -455,8 +455,6 @@ typedef struct {
|
|||
uint16_t index;
|
||||
/** Subindex of the current object in Object Dictionary */
|
||||
uint8_t subIndex;
|
||||
/** Attribute bit-field of the current OD sub-object, see OD_attributes_t */
|
||||
OD_attr_t attribute;
|
||||
/** Indicates, if new SDO message received from CAN bus. It is not cleared,
|
||||
* until received message is completely processed. */
|
||||
volatile void *CANrxNew;
|
||||
|
|
@ -476,6 +474,8 @@ typedef struct {
|
|||
uint32_t COB_IDClientToServer;
|
||||
/** Copy of CANopen COB_ID Server -> Client, similar as above */
|
||||
uint32_t COB_IDServerToClient;
|
||||
/** Extension for OD object */
|
||||
OD_extension_t OD_1200_extension;
|
||||
#endif
|
||||
#if ((CO_CONFIG_SDO_SRV) & CO_CONFIG_SDO_SRV_SEGMENTED) || defined CO_DOXYGEN
|
||||
/** Size of data, which will be transferred. It is optionally indicated by
|
||||
|
|
@ -546,8 +546,8 @@ typedef struct {
|
|||
* @return @ref CO_ReturnError_t CO_ERROR_NO in case of success.
|
||||
*/
|
||||
CO_ReturnError_t CO_SDOserver_init(CO_SDOserver_t *SDO,
|
||||
const OD_t *OD,
|
||||
const OD_entry_t *OD_1200_SDOsrvPar,
|
||||
OD_t *OD,
|
||||
OD_entry_t *OD_1200_SDOsrvPar,
|
||||
uint8_t nodeId,
|
||||
uint16_t SDOtimeoutTime_ms,
|
||||
CO_CANmodule_t *CANdevRx,
|
||||
|
|
|
|||
20
CANopen.c
20
CANopen.c
|
|
@ -906,8 +906,8 @@ CO_ReturnError_t CO_LSSinit(CO_t *co,
|
|||
CO_ReturnError_t CO_CANopenInit(CO_t *co,
|
||||
CO_NMT_t *NMT,
|
||||
CO_EM_t *em,
|
||||
const OD_t *od,
|
||||
const OD_entry_t *OD_statusBits,
|
||||
OD_t *od,
|
||||
OD_entry_t *OD_statusBits,
|
||||
CO_NMT_control_t NMTcontrol,
|
||||
uint16_t firstHBTime_ms,
|
||||
uint16_t SDOserverTimeoutTime_ms,
|
||||
|
|
@ -1020,7 +1020,7 @@ CO_ReturnError_t CO_CANopenInit(CO_t *co,
|
|||
|
||||
/* SDOserver */
|
||||
if (CO_GET_CNT(SDO_SRV) > 0) {
|
||||
const OD_entry_t *SDOsrvPar = OD_GET(H1200,OD_H1200_SDO_SERVER_1_PARAM);
|
||||
OD_entry_t *SDOsrvPar = OD_GET(H1200,OD_H1200_SDO_SERVER_1_PARAM);
|
||||
for (int16_t i = 0; i < CO_GET_CNT(SDO_SRV); i++) {
|
||||
err = CO_SDOserver_init(&co->SDOserver[i],
|
||||
od,
|
||||
|
|
@ -1037,7 +1037,7 @@ CO_ReturnError_t CO_CANopenInit(CO_t *co,
|
|||
|
||||
#if (CO_CONFIG_SDO_CLI) & CO_CONFIG_SDO_CLI_ENABLE
|
||||
if (CO_GET_CNT(SDO_CLI) > 0) {
|
||||
const OD_entry_t *SDOcliPar = OD_GET(H1280,OD_H1280_SDO_CLIENT_1_PARAM);
|
||||
OD_entry_t *SDOcliPar = OD_GET(H1280,OD_H1280_SDO_CLIENT_1_PARAM);
|
||||
for (int16_t i = 0; i < CO_GET_CNT(SDO_CLI); i++) {
|
||||
err = CO_SDOclient_init(&co->SDOclient[i],
|
||||
od,
|
||||
|
|
@ -1087,8 +1087,8 @@ CO_ReturnError_t CO_CANopenInit(CO_t *co,
|
|||
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_RPDO_ENABLE
|
||||
if (CO_GET_CNT(RPDO) > 0) {
|
||||
const OD_entry_t *RPDOcomm = OD_GET(H1400, OD_H1400_RXPDO_1_PARAM);
|
||||
const OD_entry_t *RPDOmap = OD_GET(H1600, OD_H1600_RXPDO_1_MAPPING);
|
||||
OD_entry_t *RPDOcomm = OD_GET(H1400, OD_H1400_RXPDO_1_PARAM);
|
||||
OD_entry_t *RPDOmap = OD_GET(H1600, OD_H1600_RXPDO_1_MAPPING);
|
||||
for (int16_t i = 0; i < CO_GET_CNT(RPDO); i++) {
|
||||
err = CO_RPDO_init(co->RPDO[i],
|
||||
em,
|
||||
|
|
@ -1113,8 +1113,8 @@ CO_ReturnError_t CO_CANopenInit(CO_t *co,
|
|||
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_TPDO_ENABLE
|
||||
if (CO_GET_CNT(TPDO) > 0) {
|
||||
const OD_entry_t *TPDOcomm = OD_GET(H1800, OD_H1800_TXPDO_1_PARAM);
|
||||
const OD_entry_t *TPDOmap = OD_GET(H1A00, OD_H1A00_TXPDO_1_MAPPING);
|
||||
OD_entry_t *TPDOcomm = OD_GET(H1800, OD_H1800_TXPDO_1_PARAM);
|
||||
OD_entry_t *TPDOmap = OD_GET(H1A00, OD_H1A00_TXPDO_1_MAPPING);
|
||||
for (int16_t i = 0; i < CO_GET_CNT(TPDO); i++) {
|
||||
err = CO_TPDO_init(co->TPDO[i],
|
||||
em,
|
||||
|
|
@ -1161,8 +1161,8 @@ CO_ReturnError_t CO_CANopenInit(CO_t *co,
|
|||
OD_H13FF_SRDO_CHECKSUM);
|
||||
if (err) return err;
|
||||
|
||||
const OD_entry_t *SRDOcomm = OD_GET(H1301, OD_H1301_SRDO_1_PARAM);
|
||||
const OD_entry_t *SRDOmap = OD_GET(H1318, OD_H1381_SRDO_1_MAPPING);
|
||||
OD_entry_t *SRDOcomm = OD_GET(H1301, OD_H1301_SRDO_1_PARAM);
|
||||
OD_entry_t *SRDOmap = OD_GET(H1318, OD_H1381_SRDO_1_MAPPING);
|
||||
for (int16_t i = 0; i < CO_GET_CNT(SRDO); i++) {
|
||||
uint16_t CANdevRxIdx = CO_GET_CO(RX_IDX_SRDO) + 2 * i;
|
||||
uint16_t CANdevTxIdx = CO_GET_CO(TX_IDX_SRDO) + 2 * i;
|
||||
|
|
|
|||
46
CANopen.h
46
CANopen.h
|
|
@ -230,57 +230,57 @@ typedef struct {
|
|||
* @ref CO_CONFIG_NMT. Start indexes inside CANrx and CANtx are always 0.
|
||||
* There must be one NMT object in the device. */
|
||||
uint8_t CNT_NMT;
|
||||
const OD_entry_t *ENTRY_H1017; /**< OD entry for @ref CO_NMT_init() */
|
||||
OD_entry_t *ENTRY_H1017; /**< OD entry for @ref CO_NMT_init() */
|
||||
/** Number of Heartbeat consumer objects, 0 or 1: object uses from 1 to 127
|
||||
* internal consumers (CANrx), as specified by @ref CO_CONFIG_HB_CONS_SIZE.
|
||||
*/
|
||||
uint8_t CNT_HB_CONS;
|
||||
const OD_entry_t *ENTRY_H1016; /**< OD entry for @ref CO_HBconsumer_init()*/
|
||||
OD_entry_t *ENTRY_H1016; /**< OD entry for @ref CO_HBconsumer_init()*/
|
||||
/** Number of Emergency objects, 0 or 1: optional producer (CANtx) +
|
||||
* optional consumer (CANrx), configurable by @ref CO_CONFIG_EM.
|
||||
* There must be one Emergency object in the device. */
|
||||
uint8_t CNT_EM;
|
||||
const OD_entry_t *ENTRY_H1001; /**< OD entry for @ref CO_EM_init() */
|
||||
const OD_entry_t *ENTRY_H1014; /**< OD entry for @ref CO_EM_init() */
|
||||
const OD_entry_t *ENTRY_H1015; /**< OD entry for @ref CO_EM_init() */
|
||||
const OD_entry_t *ENTRY_H1003; /**< OD entry for @ref CO_EM_init() */
|
||||
OD_entry_t *ENTRY_H1014; /**< OD entry for @ref CO_EM_init() */
|
||||
OD_entry_t *ENTRY_H1015; /**< OD entry for @ref CO_EM_init() */
|
||||
OD_entry_t *ENTRY_H1003; /**< OD entry for @ref CO_EM_init() */
|
||||
/** Number of SDO server objects, from 0 to 128 (CANrx + CANtx). There must
|
||||
* be at least one SDO server object in the device. */
|
||||
uint8_t CNT_SDO_SRV;
|
||||
const OD_entry_t *ENTRY_H1200; /**< OD entry for @ref CO_SDOserver_init()*/
|
||||
OD_entry_t *ENTRY_H1200; /**< OD entry for @ref CO_SDOserver_init()*/
|
||||
/** Number of SDO client objects, from 0 to 128 (CANrx + CANtx). */
|
||||
uint8_t CNT_SDO_CLI;
|
||||
const OD_entry_t *ENTRY_H1280; /**< OD entry for @ref CO_SDOclient_init()*/
|
||||
OD_entry_t *ENTRY_H1280; /**< OD entry for @ref CO_SDOclient_init()*/
|
||||
/** Number of TIME objects, 0 or 1: consumer (CANrx) + optional producer
|
||||
* (CANtx), configurable by @ref CO_CONFIG_TIME. */
|
||||
uint8_t CNT_TIME;
|
||||
const OD_entry_t *ENTRY_H1012; /**< OD entry for @ref CO_TIME_init() */
|
||||
OD_entry_t *ENTRY_H1012; /**< OD entry for @ref CO_TIME_init() */
|
||||
/** Number of SYNC objects, 0 or 1: consumer (CANrx) + optional producer
|
||||
* (CANtx), configurable by @ref CO_CONFIG_SYNC. */
|
||||
uint8_t CNT_SYNC;
|
||||
const OD_entry_t *ENTRY_H1005; /**< OD entry for @ref CO_SYNC_init() */
|
||||
const OD_entry_t *ENTRY_H1006; /**< OD entry for @ref CO_SYNC_init() */
|
||||
const OD_entry_t *ENTRY_H1007; /**< OD entry for @ref CO_SYNC_init() */
|
||||
const OD_entry_t *ENTRY_H1019; /**< OD entry for @ref CO_SYNC_init() */
|
||||
OD_entry_t *ENTRY_H1005; /**< OD entry for @ref CO_SYNC_init() */
|
||||
OD_entry_t *ENTRY_H1006; /**< OD entry for @ref CO_SYNC_init() */
|
||||
OD_entry_t *ENTRY_H1007; /**< OD entry for @ref CO_SYNC_init() */
|
||||
OD_entry_t *ENTRY_H1019; /**< OD entry for @ref CO_SYNC_init() */
|
||||
/** Number of RPDO objects, from 0 to 512 consumers (CANrx) */
|
||||
uint16_t CNT_RPDO;
|
||||
const OD_entry_t *ENTRY_H1400; /**< OD entry for @ref CO_RPDO_init() */
|
||||
const OD_entry_t *ENTRY_H1600; /**< OD entry for @ref CO_RPDO_init() */
|
||||
OD_entry_t *ENTRY_H1400; /**< OD entry for @ref CO_RPDO_init() */
|
||||
OD_entry_t *ENTRY_H1600; /**< OD entry for @ref CO_RPDO_init() */
|
||||
/** Number of TPDO objects, from 0 to 512 producers (CANtx) */
|
||||
uint16_t CNT_TPDO;
|
||||
const OD_entry_t *ENTRY_H1800; /**< OD entry for @ref CO_TPDO_init() */
|
||||
const OD_entry_t *ENTRY_H1A00; /**< OD entry for @ref CO_TPDO_init() */
|
||||
OD_entry_t *ENTRY_H1800; /**< OD entry for @ref CO_TPDO_init() */
|
||||
OD_entry_t *ENTRY_H1A00; /**< OD entry for @ref CO_TPDO_init() */
|
||||
/** Number of LEDs objects, 0 or 1. */
|
||||
uint8_t CNT_LEDS;
|
||||
/** Number of GFC objects, 0 or 1 (CANrx + CANtx). */
|
||||
uint8_t CNT_GFC;
|
||||
const OD_entry_t *ENTRY_H1300; /**< OD entry for @ref CO_GFC_init() */
|
||||
OD_entry_t *ENTRY_H1300; /**< OD entry for @ref CO_GFC_init() */
|
||||
/** Number of SRDO objects, from 0 to 64 (2*CANrx + 2*CANtx). */
|
||||
uint8_t CNT_SRDO;
|
||||
const OD_entry_t *ENTRY_H1301; /**< OD entry for @ref CO_SRDO_init() */
|
||||
const OD_entry_t *ENTRY_H1381; /**< OD entry for @ref CO_SRDO_init() */
|
||||
const OD_entry_t *ENTRY_H13FE; /**< OD entry for @ref CO_SRDOGuard_init() */
|
||||
const OD_entry_t *ENTRY_H13FF; /**< OD entry for @ref CO_SRDOGuard_init() */
|
||||
OD_entry_t *ENTRY_H1301; /**< OD entry for @ref CO_SRDO_init() */
|
||||
OD_entry_t *ENTRY_H1381; /**< OD entry for @ref CO_SRDO_init() */
|
||||
OD_entry_t *ENTRY_H13FE; /**< OD entry for @ref CO_SRDOGuard_init() */
|
||||
OD_entry_t *ENTRY_H13FF; /**< OD entry for @ref CO_SRDOGuard_init() */
|
||||
/** Number of LSSslave objects, 0 or 1 (CANrx + CANtx). */
|
||||
uint8_t CNT_LSS_SLV;
|
||||
/** Number of LSSmaster objects, 0 or 1 (CANrx + CANtx). */
|
||||
|
|
@ -534,8 +534,8 @@ CO_ReturnError_t CO_LSSinit(CO_t *co,
|
|||
CO_ReturnError_t CO_CANopenInit(CO_t *co,
|
||||
CO_NMT_t *NMT,
|
||||
CO_EM_t *em,
|
||||
const OD_t *od,
|
||||
const OD_entry_t *OD_statusBits,
|
||||
OD_t *od,
|
||||
OD_entry_t *OD_statusBits,
|
||||
CO_NMT_control_t NMTcontrol,
|
||||
uint16_t firstHBTime_ms,
|
||||
uint16_t SDOserverTimeoutTime_ms,
|
||||
|
|
|
|||
|
|
@ -21,21 +21,15 @@ The term **OD variable** is basic variable of specified type. For example: int8_
|
|||
The term **OD entry** means structure element, which contains some basic properties of the OD object, indication of type of OD object and pointer to all necessary data for the OD object. An array of OD entries together with information about total number of OD entries represents object dictionary as defined inside CANopenNode. See @ref OD_entry_t and @ref OD_t.
|
||||
|
||||
### Access
|
||||
Application and the stack have access to OD objects via universal @ref OD_t object and @ref OD_find() function. No direct access to custom structures, which define object dictionary, is required. Properties for specific OD variable is fetched with @ref OD_getSub() function. Access to actual variable is via **read** and **write** functions. Pointer to those two functions is fetched by @ref OD_getSub(). See @ref OD_stream_t and @ref OD_subEntry_t. See also shortcuts: @ref CO_ODgetSetters, for access to data of different type.
|
||||
|
||||
### Optional extensions
|
||||
There are some optional extensions to the object dictionary:
|
||||
* **PDO flags** informs application, if specific OD variable was received or sent by PDO. And also gives the application ability to request a TPDO, to which variable is possibly mapped.
|
||||
* **IO extension** gives the application ability to take full control over the OD object. Application can specify own **read** and **write** functions and own object, on which they operate.
|
||||
Application and the stack have access to OD objects via universal @ref OD_t object and @ref OD_find() function. No direct access to custom structures, which define object dictionary, is required. Properties for specific OD variable is fetched with @ref OD_getSub() function. Access to actual variable is via **read** and **write** functions. Pointer to those two functions is fetched by @ref OD_getSub(). See @ref OD_stream_t. See also shortcuts: @ref CO_ODgetSetters, for access to data of different type.
|
||||
|
||||
### Example usage
|
||||
```c
|
||||
extern const OD_t ODxyz;
|
||||
extern OD_t *ODxyz;
|
||||
|
||||
void myFunc(const OD_t *od) {
|
||||
void myFunc(OD_t *od) {
|
||||
ODR_t ret;
|
||||
const OD_entry_t *entry;
|
||||
OD_subEntry_t subEntry;
|
||||
OD_entry_t *entry;
|
||||
OD_IO_t io1008;
|
||||
char buf[50];
|
||||
OD_size_t bytesRd;
|
||||
|
|
@ -43,7 +37,7 @@ void myFunc(const OD_t *od) {
|
|||
|
||||
/* Init IO for "Manufacturer device name" at index 0x1008, sub-index 0x00 */
|
||||
entry = OD_find(od, 0x1008);
|
||||
ret = OD_getSub(entry, 0x00, &subEntry, &io1008, false);
|
||||
ret = OD_getSub(entry, 0x00, &io1008, false);
|
||||
/* Read with io1008, subindex = 0x00 */
|
||||
if (ret == ODR_OK)
|
||||
bytesRd = io1008.read(&io1008.stream, 0x00, &buf[0], sizeof(buf), &ret);
|
||||
|
|
@ -64,14 +58,14 @@ If access to the same variable is very frequent, it is better to use first examp
|
|||
Some simple user applications can also access some OD variables directly via globals.
|
||||
|
||||
@warning
|
||||
If OD object has IO extension enabled, then direct access to its OD variables must not be used. Only valid access is via read or write or helper functions.
|
||||
If OD object has OD extension enabled, then direct access to its OD variables must not be used. Only valid access is via read or write or helper functions.
|
||||
|
||||
```c
|
||||
#include ODxyz.h
|
||||
|
||||
void myFuncGlob(void) {
|
||||
//Direct address instead of OD_find()
|
||||
const OD_entry_t *entry_errReg = ODxyz_1001_errorRegister;
|
||||
OD_entry_t *entry_errReg = ODxyz_1001_errorRegister;
|
||||
|
||||
//Direct access to OD variable
|
||||
uint32_t devType = ODxyz_0.x1000_deviceType;
|
||||
|
|
@ -117,18 +111,18 @@ typedef struct {
|
|||
|
||||
extern ODxyz_PERSIST_COMM_t ODxyz_PERSIST_COMM;
|
||||
extern ODxyz_RAM_t ODxyz_RAM;
|
||||
extern const OD_t ODxyz;
|
||||
extern OD_t *ODxyz;
|
||||
|
||||
/* Object dictionary entries - shortcuts **************************************/
|
||||
#define ODxyz_ENTRY_H1000 &ODxyz.list[0]
|
||||
#define ODxyz_ENTRY_H1001 &ODxyz.list[1]
|
||||
#define ODxyz_ENTRY_H1003 &ODxyz.list[2]
|
||||
#define ODxyz_ENTRY_H1018 &ODxyz.list[3]
|
||||
#define ODxyz_ENTRY_H1000 &ODxyz->list[0]
|
||||
#define ODxyz_ENTRY_H1001 &ODxyz->list[1]
|
||||
#define ODxyz_ENTRY_H1003 &ODxyz->list[2]
|
||||
#define ODxyz_ENTRY_H1018 &ODxyz->list[3]
|
||||
|
||||
#define ODxyz_ENTRY_H1000_deviceType &ODxyz.list[0]
|
||||
#define ODxyz_ENTRY_H1001_errorRegister &ODxyz.list[1]
|
||||
#define ODxyz_ENTRY_H1003_preDefinedErrorField &ODxyz.list[2]
|
||||
#define ODxyz_ENTRY_H1018_identity &ODxyz.list[3]
|
||||
#define ODxyz_ENTRY_H1000_deviceType &ODxyz->list[0]
|
||||
#define ODxyz_ENTRY_H1001_errorRegister &ODxyz->list[1]
|
||||
#define ODxyz_ENTRY_H1003_preDefinedErrorField &ODxyz->list[2]
|
||||
#define ODxyz_ENTRY_H1018_identity &ODxyz->list[3]
|
||||
```
|
||||
|
||||
### Example ODxyz.c file
|
||||
|
|
@ -139,13 +133,13 @@ extern const OD_t ODxyz;
|
|||
|
||||
/* OD data initialization of all groups ***************************************/
|
||||
ODxyz_PERSIST_COMM_t ODxyz_PERSIST_COMM = {
|
||||
.x1000_deviceType = 0L,
|
||||
.x1000_deviceType = 0,
|
||||
.x1018_identity = {
|
||||
.maxSubIndex = 4,
|
||||
.vendorID = 0L,
|
||||
.productCode = 0L,
|
||||
.revisionNumber = 0L,
|
||||
.serialNumber = 0L
|
||||
.vendorID = 0,
|
||||
.productCode = 0,
|
||||
.revisionNumber = 0,
|
||||
.serialNumber = 0
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -155,46 +149,33 @@ ODxyz_RAM_t ODxyz_RAM = {
|
|||
.x1003_preDefinedErrorField = {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* IO extensions and flagsPDO (configurable by application) *******************/
|
||||
typedef struct {
|
||||
OD_extensionIO_t xio_1003_preDefinedErrorField;
|
||||
} ODxyzExts_t;
|
||||
|
||||
static ODxyzExts_t ODxyzExts = {0};
|
||||
|
||||
/* All OD objects (constant) **************************************************/
|
||||
typedef struct {
|
||||
OD_obj_var_t o_1000_deviceType;
|
||||
OD_obj_var_t o_1001_errorRegister;
|
||||
OD_obj_array_t o_1003_preDefinedErrorField;
|
||||
OD_obj_extended_t oE_1003_preDefinedErrorField;
|
||||
OD_obj_record_t o_1018_identity[5];
|
||||
} ODxyzObjs_t;
|
||||
|
||||
static const ODxyzObjs_t ODxyzObjs = {
|
||||
static CO_PROGMEM ODxyzObjs_t ODxyzObjs = {
|
||||
.o_1000_deviceType = {
|
||||
.data = &ODxyz_PERSIST_COMM.x1000_deviceType,
|
||||
.dataOrig = &ODxyz_PERSIST_COMM.x1000_deviceType,
|
||||
.attribute = ODA_SDO_R | ODA_MB,
|
||||
.dataLength = 4
|
||||
},
|
||||
.o_1001_errorRegister = {
|
||||
.data = &ODxyz_RAM.x1001_errorRegister,
|
||||
.dataOrig = &ODxyz_RAM.x1001_errorRegister,
|
||||
.attribute = ODA_SDO_R,
|
||||
.dataLength = 1
|
||||
},
|
||||
.o_1003_preDefinedErrorField = {
|
||||
.data0 = &ODxyz_RAM.x1003_preDefinedErrorField_sub0,
|
||||
.data = &ODxyz_RAM.x1003_preDefinedErrorField[0],
|
||||
.dataOrig0 = &ODxyz_RAM.x1003_preDefinedErrorField_sub0,
|
||||
.dataOrig = &ODxyz_RAM.x1003_preDefinedErrorField[0],
|
||||
.attribute0 = ODA_SDO_RW,
|
||||
.attribute = ODA_SDO_R | ODA_MB,
|
||||
.dataElementLength = 4,
|
||||
.dataElementSizeof = sizeof(uint32_t)
|
||||
},
|
||||
.oE_1003_preDefinedErrorField = {
|
||||
.extIO = &ODxyzExts.xio_1003_preDefinedErrorField,
|
||||
.flagsPDO = NULL,
|
||||
.odObjectOriginal = &ODxyzObjs.o_1003_preDefinedErrorField
|
||||
},
|
||||
.o_1018_identity = {
|
||||
{
|
||||
.data = &ODxyz_PERSIST_COMM.x1018_identity.maxSubIndex,
|
||||
|
|
@ -230,18 +211,20 @@ static const ODxyzObjs_t ODxyzObjs = {
|
|||
};
|
||||
|
||||
/* Object dictionary **********************************************************/
|
||||
static const OD_entry_t ODxyzList[] = {
|
||||
{0x1000, 1, ODT_VAR, &ODxyzObjs.o_1000_deviceType},
|
||||
{0x1001, 1, ODT_VAR, &ODxyzObjs.o_1001_errorRegister},
|
||||
{0x1003, 9, ODT_EVAR, &ODxyzObjs.oE_1003_preDefinedErrorField},
|
||||
{0x1018, 5, ODT_REC, &ODxyzObjs.o_1018_identity},
|
||||
{0x0000, 0, 0, NULL}
|
||||
static OD_entry_t ODxyzList[] = {
|
||||
{0x1000, 0x01, ODT_VAR, &ODxyzObjs.o_1000_deviceType, NULL},
|
||||
{0x1001, 0x01, ODT_VAR, &ODxyzObjs.o_1001_errorRegister, NULL},
|
||||
{0x1003, 0x09, ODT_VAR, &ODxyzObjs.o_1003_preDefinedErrorField, NULL},
|
||||
{0x1018, 0x05, ODT_REC, &ODxyzObjs.o_1018_identity, NULL},
|
||||
{0x0000, 0x00, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
const OD_t ODxyz = {
|
||||
OD_t _ODxyz = {
|
||||
(sizeof(ODxyzList) / sizeof(ODxyzList[0])) - 1,
|
||||
&ODxyzList[0]
|
||||
};
|
||||
|
||||
OD_t *ODxyz = &_ODxyz;
|
||||
```
|
||||
|
||||
|
||||
|
|
@ -289,7 +272,6 @@ There are also device configuration files with "XDC" extension. They are describ
|
|||
<BYTE/>
|
||||
<defaultValue value="0" />
|
||||
<property name="CO_storageGroup" value="RAM">
|
||||
<property name="CO_extensionIO" value="true">
|
||||
</parameter>
|
||||
<parameter uniqueID="UID_PARAM_1018">
|
||||
<label lang="en">Identity</label>
|
||||
|
|
@ -407,13 +389,11 @@ If "uniqueIDRef" attribute is not specified and "objectType" is 7(VAR), then "CA
|
|||
* "noAccess" - object will be in object dictionary, but no access.
|
||||
* <**label** lang="en">, <**description** lang="en"> (required) - several elements in multiple languages possible
|
||||
* <**INT and similar**/> (required) - Basic or complex data type. Basic data type (for VAR) is specified in IEC 61131-3 (see below). If data type is complex (ARRAY or RECORD), then **<dataTypeIDRef>** must be specified and entry must be added in the **<dataTypeList>**. Such definition of complex data types is required by the standard, but it is not required by CANopenNode.
|
||||
* <**defaultValue**> (optional for VAR) - Default value for the variable. If it is empty string, then data is not stored inside object dictionary. Application should provide own data via IO extension.
|
||||
* <**defaultValue**> (optional for VAR) - Default value for the variable. If it is empty string, then data is not stored inside object dictionary. Application should provide own data via OD extension.
|
||||
* <**property** name="..." value="..."> (optional) - Multiple elements may contain additional custom properties. CANopenNode uses custom properties with following names:
|
||||
* "**CO_disabled**" (used for base OD entry) - Valid value is "false" (default) or "true". if OD entry is disabled, then it will not be present in generated Object Dictionary .h and .c files.
|
||||
* "**CO_countLabel**" (used for base OD entry) - Valid value is any string without spaces. OD exporter will generate a macro for each different string. For example, if four OD objects have "CO_countLabel" set to "TPDO", then macro "#define ODxyz_CNT_TPDO 4" will be generated by OD exporter. "CO_countLabel" is not required for configuration with multiple object dictionaries (CO_MULTIPLE_OD), although may be useful. Default is "".
|
||||
* "**CO_storageGroup**" (used for base OD entry) - group name (string) into which the C variable will belong. Variables from specific storage group may then be stored into non-volatile memory, automatically or by SDO command. Default is "RAM". Please note: if <defaultValue> is empty string at specific subindex, then no storage group will be used for that variable.
|
||||
* "**CO_extensionIO**" (used for base OD entry) - Valid value is "false" (default) or "true", if IO extension is enabled.
|
||||
* "**CO_flagsPDO**" (used for base OD entry) - Valid value is "false" (default) or "true", if PDO flags are enabled.
|
||||
* "**CO_accessSRDO**" (used for each "VAR") - Valid values are: "tx", "rx", "trx", "no"(default).
|
||||
* "**CO_stringLengthMin**" (used for each "VAR") - Minimum length of the string. Used with "VISIBLE_STRING" and "UNICODE_STRING". If CO_stringLengthMin is smaller than length of the string in <defaultValue>, then it is ignored. Byte length of unicode string is 2 * CO_stringLengthMin. If <defaultValue> is empty and CO_stringLengthMin is 0, then data is not stored inside object dictionary. Default is 0.
|
||||
|
||||
|
|
@ -462,62 +442,56 @@ Other elements listed in the above XML example are required by the standard. The
|
|||
Object Dictionary Requirements By CANopenNode {#object-dictionary-requirements-by-canopennode}
|
||||
----------------------------------------------------------------------------------------------
|
||||
* **Used by** column indicates CANopenNode object or its part, which uses the OD object. It also indicates, if OD object is required or optional for actual configuration. For the configuration of the CANopenNode objects see [Stack configuration](301/CO_config.h). If CANopenNode object or its part is disabled in stack configuration, then OD object is not used. Note that OD objects: 1000, 1001 and 1017 and 1018 are mandatory for CANopen.
|
||||
* **CO_extensionIO** column indicates, if OD object must have property "CO_extensionIO" set to true:
|
||||
* "no" - no IO extension used
|
||||
* "optional" - If IO extension is enabled, then writing to the OD parameter will reflect in CANopen run time, otherwise reset communication is required for changes to take effect.
|
||||
* "required" - IO extension is required on OD object and init function will return error if not enabled.
|
||||
* "req if DYNAMIC" - IO extension is required on OD object if CO_CONFIG_FLAG_OD_DYNAMIC is set.
|
||||
* "yes, own data" - OD object don't need own data and IO extension is necessary for OD object to work. Init function will not return error, if OD object does not exist or doesn't have IO extension enabled.
|
||||
* **CO_countLabel** column indicates, which value must have property "CO_countLabel" inside OD object.
|
||||
|
||||
| index | Description | Used by | CO_extensionIO | CO_countLabel |
|
||||
| ----- | ----------------------------- | ---------------------| -------------- | ------------- |
|
||||
| 1000 | Device type | CANopen, req | no | NMT |
|
||||
| 1001 | Error register | CANopen, EM, req | no | EM |
|
||||
| 1002 | Manufacturer status register | | | |
|
||||
| 1003 | Pre-defined error field | EM_HISTORY, opt | yes, own data | |
|
||||
| 1005 | COB-ID SYNC message | SYNC, req | req if DYNAMIC | SYNC |
|
||||
| 1006 | Communication cycle period | SYNC_PRODUCER, req | opt | SYNC_PROD |
|
||||
| 1007 | Synchronous window length | SYNC, opt | opt | |
|
||||
| 1008 | Manufacturer device name | | | |
|
||||
| 1009 | Manufacturer hardware version | | | |
|
||||
| 100A | Manufacturer software version | | | |
|
||||
| 100C | Guard time | | | |
|
||||
| 100D | Life time factor | | | |
|
||||
| 1010 | Store parameters | | | |
|
||||
| 1011 | Restore default parameters | | | |
|
||||
| 1012 | COB-ID time stamp object | TIME, req | required | TIME |
|
||||
| 1013 | High resolution time stamp | | | |
|
||||
| 1014 | COB-ID EMCY | EM_PRODUCER, req | required | EM_PROD |
|
||||
| 1015 | Inhibit time EMCY | EM_PROD_INHIBIT, opt | optional | |
|
||||
| 1016 | Consumer heartbeat time | HB_CONS, req | optional | HB_CONS |
|
||||
| 1017 | Producer heartbeat time | CANopen, NMT, req | required | HB_PROD |
|
||||
| 1018 | Identity object | CANopen, LSS_SL, req | no | |
|
||||
| 1019 | Synch. counter overflow value | SYNC, opt | no | |
|
||||
| 1020 | Verify configuration | | | |
|
||||
| 1021 | Store EDS | | | |
|
||||
| 1022 | Store format | | | |
|
||||
| 1023 | OS command | | | |
|
||||
| 1024 | OS command mode | | | |
|
||||
| 1025 | OS debugger interface | | | |
|
||||
| 1026 | OS prompt | | | |
|
||||
| 1027 | Module list | | | |
|
||||
| 1028 | Emergency consumer object | | | |
|
||||
| 1029 | Error behavior object | | | |
|
||||
| 1200 | SDO server parameter (first) | SDO optional | required | SDO_SRV |
|
||||
| 1201+ | SDO server parameter | SDO+, req | req if DYNAMIC | SDO_SRV |
|
||||
| 1280+ | SDO client parameter | SDO_CLI, req | req if DYNAMIC | SDO_CLI |
|
||||
| 1300 | Global fail-safe command par | GFC, req | | GFC |
|
||||
| 1301+ | SRDO communication parameter | SRDO, req | | SRDO |
|
||||
| 1381+ | SRDO mapping parameter | SRDO, req | | |
|
||||
| 13FE | Configuration valid | SRDO, req | | |
|
||||
| 13FF | Safety configuration checksum | SRDO, req | | |
|
||||
| 1400+ | RPDO communication parameter | RPDO, req | req if DYNAMIC | RPDO |
|
||||
| 1600+ | RPDO mapping parameter | RPDO, req | req if DYNAMIC | |
|
||||
| 1800+ | TPDO communication parameter | TPDO, req | req if DYNAMIC | TPDO |
|
||||
| 1A00+ | TPDO mapping parameter | TPDO, req | req if DYNAMIC | |
|
||||
| 1FA0+ | Object scanner list | | | |
|
||||
| 1FD0+ | Object dispatching list | | | |
|
||||
| | Custom objects | | | |
|
||||
| any | Error status bits | EM_STATUS_BITS, opt | yes, own data | |
|
||||
| any+ | Trace | TRACE, req | yes, own data | TRACE |
|
||||
| index | Description | Used by | CO_countLabel |
|
||||
| ----- | ----------------------------- | ---------------------| ------------- |
|
||||
| 1000 | Device type | CANopen, req | NMT |
|
||||
| 1001 | Error register | CANopen, EM, req | EM |
|
||||
| 1002 | Manufacturer status register | | |
|
||||
| 1003 | Pre-defined error field | EM_HISTORY, opt | |
|
||||
| 1005 | COB-ID SYNC message | SYNC, req | SYNC |
|
||||
| 1006 | Communication cycle period | SYNC_PRODUCER, req | SYNC_PROD |
|
||||
| 1007 | Synchronous window length | SYNC, opt | |
|
||||
| 1008 | Manufacturer device name | | |
|
||||
| 1009 | Manufacturer hardware version | | |
|
||||
| 100A | Manufacturer software version | | |
|
||||
| 100C | Guard time | | |
|
||||
| 100D | Life time factor | | |
|
||||
| 1010 | Store parameters | | |
|
||||
| 1011 | Restore default parameters | | |
|
||||
| 1012 | COB-ID time stamp object | TIME, req | TIME |
|
||||
| 1013 | High resolution time stamp | | |
|
||||
| 1014 | COB-ID EMCY | EM_PRODUCER, req | EM_PROD |
|
||||
| 1015 | Inhibit time EMCY | EM_PROD_INHIBIT, opt | |
|
||||
| 1016 | Consumer heartbeat time | HB_CONS, req | HB_CONS |
|
||||
| 1017 | Producer heartbeat time | CANopen, NMT, req | HB_PROD |
|
||||
| 1018 | Identity object | CANopen, LSS_SL, req | |
|
||||
| 1019 | Synch. counter overflow value | SYNC, opt | |
|
||||
| 1020 | Verify configuration | | |
|
||||
| 1021 | Store EDS | | |
|
||||
| 1022 | Store format | | |
|
||||
| 1023 | OS command | | |
|
||||
| 1024 | OS command mode | | |
|
||||
| 1025 | OS debugger interface | | |
|
||||
| 1026 | OS prompt | | |
|
||||
| 1027 | Module list | | |
|
||||
| 1028 | Emergency consumer object | | |
|
||||
| 1029 | Error behavior object | | |
|
||||
| 1200 | SDO server parameter (first) | SDO optional | SDO_SRV |
|
||||
| 1201+ | SDO server parameter | SDO+, req | SDO_SRV |
|
||||
| 1280+ | SDO client parameter | SDO_CLI, req | SDO_CLI |
|
||||
| 1300 | Global fail-safe command par | GFC, req | GFC |
|
||||
| 1301+ | SRDO communication parameter | SRDO, req | SRDO |
|
||||
| 1381+ | SRDO mapping parameter | SRDO, req | |
|
||||
| 13FE | Configuration valid | SRDO, req | |
|
||||
| 13FF | Safety configuration checksum | SRDO, req | |
|
||||
| 1400+ | RPDO communication parameter | RPDO, req | RPDO |
|
||||
| 1600+ | RPDO mapping parameter | RPDO, req | |
|
||||
| 1800+ | TPDO communication parameter | TPDO, req | TPDO |
|
||||
| 1A00+ | TPDO mapping parameter | TPDO, req | |
|
||||
| 1FA0+ | Object scanner list | | |
|
||||
| 1FD0+ | Object dispatching list | | |
|
||||
| | Custom objects | | |
|
||||
| any | Error status bits | EM_STATUS_BITS, opt | |
|
||||
| any+ | Trace | TRACE, req | TRACE |
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ Description=
|
|||
CreationTime=12:00PM
|
||||
CreationDate=11-23-2020
|
||||
CreatedBy=
|
||||
ModificationTime=1:31PM
|
||||
ModificationDate=11-24-2020
|
||||
ModificationTime=4:21PM
|
||||
ModificationDate=01-06-2021
|
||||
ModifiedBy=
|
||||
|
||||
[DeviceInfo]
|
||||
|
|
|
|||
|
|
@ -4,32 +4,37 @@ CANopen documentation
|
|||
|
||||
|
||||
|
||||
| | |
|
||||
| ------------ | ------------------------------ |
|
||||
| | |
|
||||
| ------------ | ------------------------------ |
|
||||
| Project File | DS301_profile.xpd |
|
||||
| File Version | 1 |
|
||||
| Created | 23. 11. 2020 12:00:00 |
|
||||
| Created By | |
|
||||
| Modified | 24. 11. 2020 13:31:53 |
|
||||
| Modified | 6. 01. 2021 16:21:52 |
|
||||
| Modified By | |
|
||||
|
||||
This file was automatically generated with [libedssharp](https://github.com/robincornelius/libedssharp) Object Dictionary Editor v0.8-99-g0425f94
|
||||
This file was automatically generated with [libedssharp](https://github.com/robincornelius/libedssharp) Object Dictionary Editor v0.8-116-g2e8a14a
|
||||
|
||||
* [Device Information](#device-information)
|
||||
* [PDO Mapping](#pdo-mapping)
|
||||
* [Communication Specific Parameters](#communication-specific-parameters)
|
||||
* [Manufacturer Specific Parameters](#manufacturer-specific-parameters)
|
||||
* [Device Profile Specific Parameters](#device-profile-specific-parameters)
|
||||
|
||||
|
||||
* [Device Information](#device-information)
* [PDO Mapping](#pdo-mapping)
* [Communication Specific Parameters](#communication-specific-parameters)
* [Manufacturer Specific Parameters](#manufacturer-specific-parameters)
* [Device Profile Specific Parameters](#device-profile-specific-parameters)
|
||||
|
||||
Device Information {#device-information}
|
||||
----------------------------------------
|
||||
| | |
|
||||
| ------------ | ------------------------------ |
|
||||
| | |
|
||||
| ------------ | ------------------------------ |
|
||||
| Vendor Name | |
|
||||
| Vendor ID | |
|
||||
| Product Name | New Product |
|
||||
| Product ID | |
|
||||
| Granularity | 8 |
|
||||
| RPDO count | 4 |
|
||||
| TPDO count | 4 |
|
||||
| LSS Slave | True |
|
||||
| LSS Master | False |
|
||||
| Granularity | 8 |
|
||||
| RPDO count | 4 |
|
||||
| TPDO count | 4 |
|
||||
| LSS Slave | True |
|
||||
| LSS Master | False |
|
||||
|
||||
#### Supported Baud rates
|
||||
* [x] 10 kBit/s
|
||||
|
|
@ -50,24 +55,24 @@ Communication Specific Parameters {#communication-specific-parameters}
|
|||
----------------------------------------------------------------------
|
||||
|
||||
### 0x1000 - Device type
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| VAR | NMT | PERSIST_COMM | False | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| VAR | NMT | PERSIST_COMM |
|
||||
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| UNSIGNED32 | ro | no | no | 0x00000000 |
|
||||
|
||||
* bit 16-31: Additional information
|
||||
* bit 0-15: Device profile number
|
||||
|
||||
### 0x1001 - Error register
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| VAR | EM | RAM | False | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| VAR | EM | RAM |
|
||||
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| UNSIGNED8 | ro | tr | no | 0x00 |
|
||||
|
||||
* bit 7: manufacturer specific
|
||||
|
|
@ -80,11 +85,11 @@ Communication Specific Parameters {#communication-specific-parameters}
|
|||
* bit 0: generic error
|
||||
|
||||
### 0x1003 - Pre-defined error field
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| ARRAY | | RAM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| ARRAY | | RAM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Number of errors | UNSIGNED8 | rw | no | no | 0 |
|
||||
| 0x01 | Standard error field | UNSIGNED32 | ro | no | no | 0x00000000 |
|
||||
|
|
@ -102,12 +107,12 @@ Communication Specific Parameters {#communication-specific-parameters}
|
|||
* bit 0-15: Error code as transmited in the Emergency object
|
||||
|
||||
### 0x1005 - COB-ID SYNC message
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| VAR | SYNC | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| VAR | SYNC | PERSIST_COMM |
|
||||
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| UNSIGNED32 | rw | no | no | 0x00000080 |
|
||||
|
||||
* bit 31: set to 0
|
||||
|
|
@ -116,33 +121,33 @@ Communication Specific Parameters {#communication-specific-parameters}
|
|||
* bit 0-10: 11-bit CAN-ID
|
||||
|
||||
### 0x1006 - Communication cycle period
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| VAR | SYNC_PROD | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| VAR | SYNC_PROD | PERSIST_COMM |
|
||||
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| UNSIGNED32 | rw | no | no | 0 |
|
||||
|
||||
Period of SYNC transmission in µs (0 = transmission disabled).
|
||||
|
||||
### 0x1007 - Synchronous window length
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| VAR | | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| VAR | | PERSIST_COMM |
|
||||
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| UNSIGNED32 | rw | no | no | 0 |
|
||||
|
||||
Synchronous window leghth in µs (0 = not used). All synchronous PDOs must be transmitted within this time window.
|
||||
|
||||
### 0x1010 - Store parameters
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| ARRAY | | RAM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| ARRAY | | RAM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Highest sub-index supported| UNSIGNED8 | ro | no | no | 0x04 |
|
||||
| 0x01 | Save all parameters | UNSIGNED32 | rw | no | no | 0x00000001 |
|
||||
|
|
@ -157,11 +162,11 @@ Sub-indexes 1 and above:
|
|||
* Writing value 0x65766173 ('s','a','v','e' from LSB to MSB) stores corresponding data.
|
||||
|
||||
### 0x1011 - Restore default parameters
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| ARRAY | | RAM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| ARRAY | | RAM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Highest sub-index supported| UNSIGNED8 | ro | no | no | 0x04 |
|
||||
| 0x01 | Restore all default parameters| UNSIGNED32 | rw | no | no | 0x00000001 |
|
||||
|
|
@ -175,12 +180,12 @@ Sub-indexes 1 and above:
|
|||
* Writing value 0x64616F6C ('l','o','a','d' from LSB to MSB) restores corresponding data.
|
||||
|
||||
### 0x1012 - COB-ID time stamp object
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| VAR | TIME | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| VAR | TIME | PERSIST_COMM |
|
||||
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| UNSIGNED32 | rw | no | no | 0x00000100 |
|
||||
|
||||
* bit 31: If set, CANopen device consumes TIME message
|
||||
|
|
@ -189,12 +194,12 @@ Sub-indexes 1 and above:
|
|||
* bit 0-10: 11-bit CAN-ID
|
||||
|
||||
### 0x1014 - COB-ID EMCY
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| VAR | EM_PROD | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| VAR | EM_PROD | PERSIST_COMM |
|
||||
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| UNSIGNED32 | rw | no | no | 0x80+$NODEID |
|
||||
|
||||
* bit 31: If set, EMCY does NOT exist / is NOT valid
|
||||
|
|
@ -202,22 +207,22 @@ Sub-indexes 1 and above:
|
|||
* bit 0-10: 11-bit CAN-ID
|
||||
|
||||
### 0x1015 - Inhibit time EMCY
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| VAR | | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| VAR | | PERSIST_COMM |
|
||||
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| UNSIGNED16 | rw | no | no | 0 |
|
||||
|
||||
Inhibit time of emergency message in multiples of 100µs. The value 0 disables the inhibit time.
|
||||
|
||||
### 0x1016 - Consumer heartbeat time
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| ARRAY | HB_CONS | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| ARRAY | HB_CONS | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Highest sub-index supported| UNSIGNED8 | ro | no | no | 0x08 |
|
||||
| 0x01 | Consumer heartbeat time| UNSIGNED32 | rw | no | no | 0x00000000 |
|
||||
|
|
@ -235,22 +240,22 @@ Consumer Heartbeat Time:
|
|||
* bit 0-15: Heartbeat time in ms (if 0, sub-intry is not used). Value should be higher than the corresponding producer heartbeat time.
|
||||
|
||||
### 0x1017 - Producer heartbeat time
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| VAR | HB_PROD | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| VAR | HB_PROD | PERSIST_COMM |
|
||||
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| UNSIGNED16 | rw | no | no | 0 |
|
||||
|
||||
Heartbeat producer time in ms (0 = disable transmission).
|
||||
|
||||
### 0x1018 - Identity
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | | PERSIST_COMM | False | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Highest sub-index supported| UNSIGNED8 | ro | no | no | 0x04 |
|
||||
| 0x01 | Vendor-ID | UNSIGNED32 | ro | no | no | 0x00000000 |
|
||||
|
|
@ -266,12 +271,12 @@ Heartbeat producer time in ms (0 = disable transmission).
|
|||
* Serial number, manufacturer specific
|
||||
|
||||
### 0x1019 - Synchronous counter overflow value
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| VAR | | PERSIST_COMM | False | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| VAR | | PERSIST_COMM |
|
||||
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ----------------------- | --- | --- | ---- | ------------------------------- |
|
||||
| UNSIGNED8 | rw | no | no | 0 |
|
||||
|
||||
* Value 0: SYNC message is transmitted with data length 0.
|
||||
|
|
@ -280,11 +285,11 @@ Heartbeat producer time in ms (0 = disable transmission).
|
|||
* Value 241-255: reserved.
|
||||
|
||||
### 0x1200 - SDO server parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | SDO_SRV | RAM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | SDO_SRV | RAM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Highest sub-index supported| UNSIGNED8 | ro | no | no | 2 |
|
||||
| 0x01 | COB-ID client to server (rx)| UNSIGNED32 | ro | t | no | 0x600+$NODEID |
|
||||
|
|
@ -295,11 +300,11 @@ Sub-indexes 1 and 2:
|
|||
* bit 0-10: 11-bit CAN-ID
|
||||
|
||||
### 0x1280 - SDO client parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | SDO_CLI | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | SDO_CLI | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Highest sub-index supported| UNSIGNED8 | ro | no | no | 0x03 |
|
||||
| 0x01 | COB-ID client to server (tx)| UNSIGNED32 | rw | tr | no | 0x80000000 |
|
||||
|
|
@ -314,11 +319,11 @@ Sub-indexes 1 and 2:
|
|||
* Node-ID of the SDO server, 0x01 to 0x7F
|
||||
|
||||
### 0x1400 - RPDO communication parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | RPDO | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | RPDO | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Highest sub-index supported| UNSIGNED8 | ro | no | no | 0x05 |
|
||||
| 0x01 | COB-ID used by RPDO | UNSIGNED32 | rw | no | no | 0x80000200+$NODEID|
|
||||
|
|
@ -337,11 +342,11 @@ Sub-indexes 1 and 2:
|
|||
* Event timer in ms (0 = disabled) for deadline monitoring.
|
||||
|
||||
### 0x1401 - RPDO communication parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | RPDO | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | RPDO | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Highest sub-index supported| UNSIGNED8 | ro | no | no | 0x05 |
|
||||
| 0x01 | COB-ID used by RPDO | UNSIGNED32 | rw | no | no | 0x80000300+$NODEID|
|
||||
|
|
@ -360,11 +365,11 @@ Sub-indexes 1 and 2:
|
|||
* Event timer in ms (0 = disabled) for deadline monitoring.
|
||||
|
||||
### 0x1402 - RPDO communication parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | RPDO | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | RPDO | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Highest sub-index supported| UNSIGNED8 | ro | no | no | 0x05 |
|
||||
| 0x01 | COB-ID used by RPDO | UNSIGNED32 | rw | no | no | 0x80000400+$NODEID|
|
||||
|
|
@ -383,11 +388,11 @@ Sub-indexes 1 and 2:
|
|||
* Event timer in ms (0 = disabled) for deadline monitoring.
|
||||
|
||||
### 0x1403 - RPDO communication parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | RPDO | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | RPDO | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Highest sub-index supported| UNSIGNED8 | ro | no | no | 0x05 |
|
||||
| 0x01 | COB-ID used by RPDO | UNSIGNED32 | rw | no | no | 0x80000500+$NODEID|
|
||||
|
|
@ -406,11 +411,11 @@ Sub-indexes 1 and 2:
|
|||
* Event timer in ms (0 = disabled) for deadline monitoring.
|
||||
|
||||
### 0x1600 - RPDO mapping parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Number of mapped application objects in PDO| UNSIGNED8 | rw | no | no | 0 |
|
||||
| 0x01 | Application object 1 | UNSIGNED32 | rw | no | no | 0x00000000 |
|
||||
|
|
@ -432,11 +437,11 @@ Sub-indexes 1 and 2:
|
|||
* bit 0-7: data length in bits
|
||||
|
||||
### 0x1601 - RPDO mapping parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Number of mapped application objects in PDO| UNSIGNED8 | rw | no | no | 0 |
|
||||
| 0x01 | Application object 1 | UNSIGNED32 | rw | no | no | 0x00000000 |
|
||||
|
|
@ -458,11 +463,11 @@ Sub-indexes 1 and 2:
|
|||
* bit 0-7: data length in bits
|
||||
|
||||
### 0x1602 - RPDO mapping parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Number of mapped application objects in PDO| UNSIGNED8 | rw | no | no | 0 |
|
||||
| 0x01 | Application object 1 | UNSIGNED32 | rw | no | no | 0x00000000 |
|
||||
|
|
@ -484,11 +489,11 @@ Sub-indexes 1 and 2:
|
|||
* bit 0-7: data length in bits
|
||||
|
||||
### 0x1603 - RPDO mapping parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Number of mapped application objects in PDO| UNSIGNED8 | rw | no | no | 0 |
|
||||
| 0x01 | Application object 1 | UNSIGNED32 | rw | no | no | 0x00000000 |
|
||||
|
|
@ -510,11 +515,11 @@ Sub-indexes 1 and 2:
|
|||
* bit 0-7: data length in bits
|
||||
|
||||
### 0x1800 - TPDO communication parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | TPDO | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | TPDO | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Highest sub-index supported| UNSIGNED8 | ro | no | no | 0x06 |
|
||||
| 0x01 | COB-ID used by TPDO | UNSIGNED32 | rw | no | no | 0xC0000180+$NODEID|
|
||||
|
|
@ -541,11 +546,11 @@ Sub-indexes 1 and 2:
|
|||
* Value 1-240: The SYNC message with the counter value equal to this value shall be regarded as the first received SYNC message.
|
||||
|
||||
### 0x1801 - TPDO communication parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | TPDO | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | TPDO | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Highest sub-index supported| UNSIGNED8 | ro | no | no | 0x06 |
|
||||
| 0x01 | COB-ID used by TPDO | UNSIGNED32 | rw | no | no | 0xC0000280+$NODEID|
|
||||
|
|
@ -572,11 +577,11 @@ Sub-indexes 1 and 2:
|
|||
* Value 1-240: The SYNC message with the counter value equal to this value shall be regarded as the first received SYNC message.
|
||||
|
||||
### 0x1802 - TPDO communication parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | TPDO | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | TPDO | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Highest sub-index supported| UNSIGNED8 | ro | no | no | 0x06 |
|
||||
| 0x01 | COB-ID used by TPDO | UNSIGNED32 | rw | no | no | 0xC0000380+$NODEID|
|
||||
|
|
@ -603,11 +608,11 @@ Sub-indexes 1 and 2:
|
|||
* Value 1-240: The SYNC message with the counter value equal to this value shall be regarded as the first received SYNC message.
|
||||
|
||||
### 0x1803 - TPDO communication parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | TPDO | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | TPDO | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Highest sub-index supported| UNSIGNED8 | ro | no | no | 0x06 |
|
||||
| 0x01 | COB-ID used by TPDO | UNSIGNED32 | rw | no | no | 0xC0000480+$NODEID|
|
||||
|
|
@ -634,11 +639,11 @@ Sub-indexes 1 and 2:
|
|||
* Value 1-240: The SYNC message with the counter value equal to this value shall be regarded as the first received SYNC message.
|
||||
|
||||
### 0x1A00 - TPDO mapping parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Number of mapped application objects in PDO| UNSIGNED8 | rw | no | no | 0 |
|
||||
| 0x01 | Application object 1 | UNSIGNED32 | rw | no | no | 0x00000000 |
|
||||
|
|
@ -660,11 +665,11 @@ Sub-indexes 1 and 2:
|
|||
* bit 0-7: data length in bits
|
||||
|
||||
### 0x1A01 - TPDO mapping parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Number of mapped application objects in PDO| UNSIGNED8 | rw | no | no | 0 |
|
||||
| 0x01 | Application object 1 | UNSIGNED32 | rw | no | no | 0x00000000 |
|
||||
|
|
@ -686,11 +691,11 @@ Sub-indexes 1 and 2:
|
|||
* bit 0-7: data length in bits
|
||||
|
||||
### 0x1A02 - TPDO mapping parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Number of mapped application objects in PDO| UNSIGNED8 | rw | no | no | 0 |
|
||||
| 0x01 | Application object 1 | UNSIGNED32 | rw | no | no | 0x00000000 |
|
||||
|
|
@ -712,11 +717,11 @@ Sub-indexes 1 and 2:
|
|||
* bit 0-7: data length in bits
|
||||
|
||||
### 0x1A03 - TPDO mapping parameter
|
||||
| Object Type | Count Label | Storage Group | IO extension | PDO flags |
|
||||
| ----------- | -------------- | -------------- | ------------- | ------------ |
|
||||
| RECORD | | PERSIST_COMM | True | False |
|
||||
| Object Type | Count Label | Storage Group |
|
||||
| ----------- | -------------- | -------------- |
|
||||
| RECORD | | PERSIST_COMM |
|
||||
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| Sub | Name | Data Type | SDO | PDO | SRDO | Default Value |
|
||||
| ---- | --------------------- | ---------- | --- | --- | ---- | ------------- |
|
||||
| 0x00 | Number of mapped application objects in PDO| UNSIGNED8 | rw | no | no | 0 |
|
||||
| 0x01 | Application object 1 | UNSIGNED32 | rw | no | no | 0x00000000 |
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--File is generated with libedssharp Object Dictionary Editor v0.8-96-g365f604-dirty, URL: https://github.com/robincornelius/libedssharp-->
|
||||
<!--File is generated with libedssharp Object Dictionary Editor v0.8-116-g2e8a14a, URL: https://github.com/robincornelius/libedssharp-->
|
||||
<!--File includes additional custom properties for CANopenNode, CANopen protocol stack, URL: https://github.com/CANopenNode/CANopenNode-->
|
||||
<ISO15745ProfileContainer xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.canopen.org/xml/1.1">
|
||||
<ISO15745Profile>
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
<ProfileTechnology>CANopen</ProfileTechnology>
|
||||
</ISO15745Reference>
|
||||
</ProfileHeader>
|
||||
<ProfileBody xmlns:q1="http://www.canopen.org/xml/1.1" xsi:type="q1:ProfileBody_Device_CANopen" formatName="CANopen" formatVersion="1.0" fileName="DS301_profile.xpd" fileCreator="" fileCreationDate="2020-11-23" fileCreationTime="12:00:00.0000000+01:00" fileModifiedBy="" fileModificationDate="2020-11-24" fileModificationTime="13:31:53.0637770+01:00" fileVersion="1" supportedLanguages="en" xmlns="">
|
||||
<ProfileBody xmlns:q1="http://www.canopen.org/xml/1.1" xsi:type="q1:ProfileBody_Device_CANopen" formatName="CANopen" formatVersion="1.0" fileName="DS301_profile.xpd" fileCreator="" fileCreationDate="2020-11-23" fileCreationTime="12:00:00.0000000+01:00" fileModifiedBy="" fileModificationDate="2021-01-06" fileModificationTime="16:21:52.3514396+01:00" fileVersion="1" supportedLanguages="en" xmlns="">
|
||||
<q1:DeviceIdentity>
|
||||
<q1:vendorName></q1:vendorName>
|
||||
<q1:vendorID></q1:vendorID>
|
||||
|
|
@ -659,7 +659,6 @@
|
|||
* bit 16-31: Manufacturer specific additional information
|
||||
* bit 0-15: Error code as transmited in the Emergency object</description>
|
||||
<q1:dataTypeIDRef uniqueIDRef="UID_ARR_1003" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_100300" access="readWrite">
|
||||
<label lang="en">Number of errors</label>
|
||||
|
|
@ -715,7 +714,6 @@
|
|||
<q1:defaultValue value="0x00000080" />
|
||||
<q1:property name="CO_countLabel" value="SYNC" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_OBJ_1006" access="readWrite">
|
||||
<description lang="en">Period of SYNC transmission in µs (0 = transmission disabled).</description>
|
||||
|
|
@ -723,14 +721,12 @@
|
|||
<q1:defaultValue value="0" />
|
||||
<q1:property name="CO_countLabel" value="SYNC_PROD" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_OBJ_1007" access="readWrite">
|
||||
<description lang="en">Synchronous window leghth in µs (0 = not used). All synchronous PDOs must be transmitted within this time window.</description>
|
||||
<UDINT />
|
||||
<q1:defaultValue value="0" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_OBJ_1008">
|
||||
<label lang="en">Manufacturer device name</label>
|
||||
|
|
@ -757,7 +753,6 @@
|
|||
* bit 0: If set, CANopen device saves parameters on command
|
||||
* Writing value 0x65766173 ('s','a','v','e' from LSB to MSB) stores corresponding data.</description>
|
||||
<q1:dataTypeIDRef uniqueIDRef="UID_ARR_1010" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_101000">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -790,7 +785,6 @@
|
|||
* bit 0: If set, CANopen device restores parameters
|
||||
* Writing value 0x64616F6C ('l','o','a','d' from LSB to MSB) restores corresponding data.</description>
|
||||
<q1:dataTypeIDRef uniqueIDRef="UID_ARR_1011" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_101100">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -826,14 +820,12 @@
|
|||
<q1:defaultValue value="0x00000100" />
|
||||
<q1:property name="CO_countLabel" value="TIME" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_OBJ_1013" access="readWrite">
|
||||
<label lang="en">High resolution time stamp</label>
|
||||
<UDINT />
|
||||
<q1:defaultValue value="0" />
|
||||
<q1:property name="CO_disabled" value="true" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_OBJ_1014" access="readWrite">
|
||||
<description lang="en">* bit 31: If set, EMCY does NOT exist / is NOT valid
|
||||
|
|
@ -843,14 +835,12 @@
|
|||
<q1:defaultValue value="0x80+$NODEID" />
|
||||
<q1:property name="CO_countLabel" value="EM_PROD" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_OBJ_1015" access="readWrite">
|
||||
<description lang="en">Inhibit time of emergency message in multiples of 100µs. The value 0 disables the inhibit time.</description>
|
||||
<UINT />
|
||||
<q1:defaultValue value="0" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_OBJ_1016">
|
||||
<description lang="en">Consumer Heartbeat Time:
|
||||
|
|
@ -860,7 +850,6 @@
|
|||
<q1:dataTypeIDRef uniqueIDRef="UID_ARR_1016" />
|
||||
<q1:property name="CO_countLabel" value="HB_CONS" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_101600">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -913,7 +902,6 @@
|
|||
<q1:defaultValue value="0" />
|
||||
<q1:property name="CO_countLabel" value="HB_PROD" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_OBJ_1018">
|
||||
<description lang="en">* Vendor-ID, assigned by CiA
|
||||
|
|
@ -984,7 +972,6 @@
|
|||
<label lang="en">Store EDS</label>
|
||||
<BITSTRING />
|
||||
<q1:property name="CO_disabled" value="true" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_OBJ_1022">
|
||||
<label lang="en">Store format</label>
|
||||
|
|
@ -997,7 +984,6 @@
|
|||
<label lang="en">OS command</label>
|
||||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1023" />
|
||||
<q1:property name="CO_disabled" value="true" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_102300">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1027,7 +1013,6 @@
|
|||
<label lang="en">OS debugger interface</label>
|
||||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1025" />
|
||||
<q1:property name="CO_disabled" value="true" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_102500">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1050,7 +1035,6 @@
|
|||
<label lang="en">OS prompt</label>
|
||||
<q1:dataTypeIDRef uniqueIDRef="UID_ARR_1026" />
|
||||
<q1:property name="CO_disabled" value="true" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_102600">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1093,7 +1077,6 @@
|
|||
<q1:dataTypeIDRef uniqueIDRef="UID_ARR_1028" />
|
||||
<q1:property name="CO_disabled" value="true" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_102800">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1170,7 +1153,6 @@
|
|||
* bit 0-10: 11-bit CAN-ID</description>
|
||||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1200" />
|
||||
<q1:property name="CO_countLabel" value="SDO_SRV" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_120000">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1198,7 +1180,6 @@
|
|||
<q1:property name="CO_disabled" value="true" />
|
||||
<q1:property name="CO_countLabel" value="SDO_SRV" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_120100">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1230,7 +1211,6 @@
|
|||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1280" />
|
||||
<q1:property name="CO_countLabel" value="SDO_CLI" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_128000">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1266,7 +1246,6 @@
|
|||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1400" />
|
||||
<q1:property name="CO_countLabel" value="RPDO" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_140000">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1302,7 +1281,6 @@
|
|||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1401" />
|
||||
<q1:property name="CO_countLabel" value="RPDO" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_140100">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1338,7 +1316,6 @@
|
|||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1402" />
|
||||
<q1:property name="CO_countLabel" value="RPDO" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_140200">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1374,7 +1351,6 @@
|
|||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1403" />
|
||||
<q1:property name="CO_countLabel" value="RPDO" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_140300">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1411,7 +1387,6 @@
|
|||
<q1:property name="CO_disabled" value="true" />
|
||||
<q1:property name="CO_countLabel" value="RPDO" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_140400">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1444,7 +1419,6 @@
|
|||
* bit 0-7: data length in bits</description>
|
||||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1600" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_160000" access="readWrite">
|
||||
<label lang="en">Number of mapped application objects in PDO</label>
|
||||
|
|
@ -1502,7 +1476,6 @@
|
|||
* bit 0-7: data length in bits</description>
|
||||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1601" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_160100" access="readWrite">
|
||||
<label lang="en">Number of mapped application objects in PDO</label>
|
||||
|
|
@ -1560,7 +1533,6 @@
|
|||
* bit 0-7: data length in bits</description>
|
||||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1602" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_160200" access="readWrite">
|
||||
<label lang="en">Number of mapped application objects in PDO</label>
|
||||
|
|
@ -1618,7 +1590,6 @@
|
|||
* bit 0-7: data length in bits</description>
|
||||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1603" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_160300" access="readWrite">
|
||||
<label lang="en">Number of mapped application objects in PDO</label>
|
||||
|
|
@ -1677,7 +1648,6 @@
|
|||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1604" />
|
||||
<q1:property name="CO_disabled" value="true" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_160400" access="readWrite">
|
||||
<label lang="en">Number of mapped application objects in PDO</label>
|
||||
|
|
@ -1744,7 +1714,6 @@
|
|||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1800" />
|
||||
<q1:property name="CO_countLabel" value="TPDO" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_180000">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1796,7 +1765,6 @@
|
|||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1801" />
|
||||
<q1:property name="CO_countLabel" value="TPDO" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_180100">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1848,7 +1816,6 @@
|
|||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1802" />
|
||||
<q1:property name="CO_countLabel" value="TPDO" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_180200">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1900,7 +1867,6 @@
|
|||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1803" />
|
||||
<q1:property name="CO_countLabel" value="TPDO" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_180300">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1953,7 +1919,6 @@
|
|||
<q1:property name="CO_disabled" value="true" />
|
||||
<q1:property name="CO_countLabel" value="TPDO" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_180400">
|
||||
<label lang="en">Highest sub-index supported</label>
|
||||
|
|
@ -1996,7 +1961,6 @@
|
|||
* bit 0-7: data length in bits</description>
|
||||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1A00" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_1A0000" access="readWrite">
|
||||
<label lang="en">Number of mapped application objects in PDO</label>
|
||||
|
|
@ -2054,7 +2018,6 @@
|
|||
* bit 0-7: data length in bits</description>
|
||||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1A01" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_1A0100" access="readWrite">
|
||||
<label lang="en">Number of mapped application objects in PDO</label>
|
||||
|
|
@ -2112,7 +2075,6 @@
|
|||
* bit 0-7: data length in bits</description>
|
||||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1A02" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_1A0200" access="readWrite">
|
||||
<label lang="en">Number of mapped application objects in PDO</label>
|
||||
|
|
@ -2170,7 +2132,6 @@
|
|||
* bit 0-7: data length in bits</description>
|
||||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1A03" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_1A0300" access="readWrite">
|
||||
<label lang="en">Number of mapped application objects in PDO</label>
|
||||
|
|
@ -2229,7 +2190,6 @@
|
|||
<q1:dataTypeIDRef uniqueIDRef="UID_REC_1A04" />
|
||||
<q1:property name="CO_disabled" value="true" />
|
||||
<q1:property name="CO_storageGroup" value="PERSIST_COMM" />
|
||||
<q1:property name="CO_extensionIO" value="true" />
|
||||
</q1:parameter>
|
||||
<q1:parameter uniqueID="UID_SUB_1A0400" access="readWrite">
|
||||
<label lang="en">Number of mapped application objects in PDO</label>
|
||||
|
|
@ -2293,7 +2253,7 @@
|
|||
<ProfileTechnology>CANopen</ProfileTechnology>
|
||||
</ISO15745Reference>
|
||||
</ProfileHeader>
|
||||
<ProfileBody xmlns:q2="http://www.canopen.org/xml/1.1" xsi:type="q2:ProfileBody_CommunicationNetwork_CANopen" formatName="CANopen" formatVersion="1.0" fileName="DS301_profile.xpd" fileCreator="" fileCreationDate="2020-11-23" fileCreationTime="12:00:00.0000000+01:00" fileModificationDate="2020-11-24" fileModificationTime="13:31:53.0637770+01:00" fileVersion="1" supportedLanguages="en" xmlns="">
|
||||
<ProfileBody xmlns:q2="http://www.canopen.org/xml/1.1" xsi:type="q2:ProfileBody_CommunicationNetwork_CANopen" formatName="CANopen" formatVersion="1.0" fileName="DS301_profile.xpd" fileCreator="" fileCreationDate="2020-11-23" fileCreationTime="12:00:00.0000000+01:00" fileModificationDate="2021-01-06" fileModificationTime="16:21:52.3514396+01:00" fileVersion="1" supportedLanguages="en" xmlns="">
|
||||
<ApplicationLayers>
|
||||
<q2:CANopenObjectList>
|
||||
<CANopenObject index="1000" name="Device type" objectType="7" PDOmapping="no" uniqueIDRef="UID_OBJ_1000" />
|
||||
|
|
@ -2628,4 +2588,4 @@
|
|||
</NetworkManagement>
|
||||
</ProfileBody>
|
||||
</ISO15745Profile>
|
||||
</ISO15745ProfileContainer>
|
||||
</ISO15745ProfileContainer>
|
||||
575
example/OD.c
575
example/OD.c
File diff suppressed because it is too large
Load diff
162
example/OD.h
162
example/OD.h
|
|
@ -2,7 +2,7 @@
|
|||
CANopen Object Dictionary definition for CANopenNode V4
|
||||
|
||||
This file was automatically generated with
|
||||
libedssharp Object Dictionary Editor v0.8-99-g0425f94
|
||||
libedssharp Object Dictionary Editor v0.8-116-g2e8a14a
|
||||
|
||||
https://github.com/CANopenNode/CANopenNode
|
||||
https://github.com/robincornelius/libedssharp
|
||||
|
|
@ -16,17 +16,17 @@
|
|||
File Version: 1
|
||||
|
||||
Created: 23. 11. 2020 12:00:00
|
||||
Created By:
|
||||
Modified: 24. 11. 2020 13:31:53
|
||||
Modified By:
|
||||
Created By:
|
||||
Modified: 6. 01. 2021 16:21:52
|
||||
Modified By:
|
||||
|
||||
Device Info:
|
||||
Vendor Name:
|
||||
Vendor ID:
|
||||
Vendor Name:
|
||||
Vendor ID:
|
||||
Product Name: New Product
|
||||
Product ID:
|
||||
Product ID:
|
||||
|
||||
Description:
|
||||
Description:
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef OD_H
|
||||
|
|
@ -36,16 +36,16 @@
|
|||
*******************************************************************************/
|
||||
#define OD_CNT_NMT 1
|
||||
#define OD_CNT_EM 1
|
||||
//#define OD_CNT_SYNC 1
|
||||
//#define OD_CNT_SYNC_PROD 1
|
||||
//#define OD_CNT_TIME 1
|
||||
#define OD_CNT_SYNC 1
|
||||
#define OD_CNT_SYNC_PROD 1
|
||||
#define OD_CNT_TIME 1
|
||||
#define OD_CNT_EM_PROD 1
|
||||
//#define OD_CNT_HB_CONS 1
|
||||
#define OD_CNT_HB_CONS 1
|
||||
#define OD_CNT_HB_PROD 1
|
||||
#define OD_CNT_SDO_SRV 1
|
||||
#define OD_CNT_SDO_CLI 1
|
||||
//#define OD_CNT_RPDO 4
|
||||
//#define OD_CNT_TPDO 4
|
||||
#define OD_CNT_RPDO 4
|
||||
#define OD_CNT_TPDO 4
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
@ -239,82 +239,82 @@ typedef struct {
|
|||
|
||||
extern OD_PERSIST_COMM_t OD_PERSIST_COMM;
|
||||
extern OD_RAM_t OD_RAM;
|
||||
extern const OD_t OD;
|
||||
extern OD_t *OD;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
Object dictionary entries - shortcuts
|
||||
*******************************************************************************/
|
||||
#define OD_ENTRY_H1000 &OD.list[0]
|
||||
#define OD_ENTRY_H1001 &OD.list[1]
|
||||
#define OD_ENTRY_H1003 &OD.list[2]
|
||||
#define OD_ENTRY_H1005 &OD.list[3]
|
||||
#define OD_ENTRY_H1006 &OD.list[4]
|
||||
#define OD_ENTRY_H1007 &OD.list[5]
|
||||
#define OD_ENTRY_H1010 &OD.list[6]
|
||||
#define OD_ENTRY_H1011 &OD.list[7]
|
||||
#define OD_ENTRY_H1012 &OD.list[8]
|
||||
#define OD_ENTRY_H1014 &OD.list[9]
|
||||
#define OD_ENTRY_H1015 &OD.list[10]
|
||||
#define OD_ENTRY_H1016 &OD.list[11]
|
||||
#define OD_ENTRY_H1017 &OD.list[12]
|
||||
#define OD_ENTRY_H1018 &OD.list[13]
|
||||
#define OD_ENTRY_H1019 &OD.list[14]
|
||||
#define OD_ENTRY_H1200 &OD.list[15]
|
||||
#define OD_ENTRY_H1280 &OD.list[16]
|
||||
#define OD_ENTRY_H1400 &OD.list[17]
|
||||
#define OD_ENTRY_H1401 &OD.list[18]
|
||||
#define OD_ENTRY_H1402 &OD.list[19]
|
||||
#define OD_ENTRY_H1403 &OD.list[20]
|
||||
#define OD_ENTRY_H1600 &OD.list[21]
|
||||
#define OD_ENTRY_H1601 &OD.list[22]
|
||||
#define OD_ENTRY_H1602 &OD.list[23]
|
||||
#define OD_ENTRY_H1603 &OD.list[24]
|
||||
#define OD_ENTRY_H1800 &OD.list[25]
|
||||
#define OD_ENTRY_H1801 &OD.list[26]
|
||||
#define OD_ENTRY_H1802 &OD.list[27]
|
||||
#define OD_ENTRY_H1803 &OD.list[28]
|
||||
#define OD_ENTRY_H1A00 &OD.list[29]
|
||||
#define OD_ENTRY_H1A01 &OD.list[30]
|
||||
#define OD_ENTRY_H1A02 &OD.list[31]
|
||||
#define OD_ENTRY_H1A03 &OD.list[32]
|
||||
#define OD_ENTRY_H1000 &OD->list[0]
|
||||
#define OD_ENTRY_H1001 &OD->list[1]
|
||||
#define OD_ENTRY_H1003 &OD->list[2]
|
||||
#define OD_ENTRY_H1005 &OD->list[3]
|
||||
#define OD_ENTRY_H1006 &OD->list[4]
|
||||
#define OD_ENTRY_H1007 &OD->list[5]
|
||||
#define OD_ENTRY_H1010 &OD->list[6]
|
||||
#define OD_ENTRY_H1011 &OD->list[7]
|
||||
#define OD_ENTRY_H1012 &OD->list[8]
|
||||
#define OD_ENTRY_H1014 &OD->list[9]
|
||||
#define OD_ENTRY_H1015 &OD->list[10]
|
||||
#define OD_ENTRY_H1016 &OD->list[11]
|
||||
#define OD_ENTRY_H1017 &OD->list[12]
|
||||
#define OD_ENTRY_H1018 &OD->list[13]
|
||||
#define OD_ENTRY_H1019 &OD->list[14]
|
||||
#define OD_ENTRY_H1200 &OD->list[15]
|
||||
#define OD_ENTRY_H1280 &OD->list[16]
|
||||
#define OD_ENTRY_H1400 &OD->list[17]
|
||||
#define OD_ENTRY_H1401 &OD->list[18]
|
||||
#define OD_ENTRY_H1402 &OD->list[19]
|
||||
#define OD_ENTRY_H1403 &OD->list[20]
|
||||
#define OD_ENTRY_H1600 &OD->list[21]
|
||||
#define OD_ENTRY_H1601 &OD->list[22]
|
||||
#define OD_ENTRY_H1602 &OD->list[23]
|
||||
#define OD_ENTRY_H1603 &OD->list[24]
|
||||
#define OD_ENTRY_H1800 &OD->list[25]
|
||||
#define OD_ENTRY_H1801 &OD->list[26]
|
||||
#define OD_ENTRY_H1802 &OD->list[27]
|
||||
#define OD_ENTRY_H1803 &OD->list[28]
|
||||
#define OD_ENTRY_H1A00 &OD->list[29]
|
||||
#define OD_ENTRY_H1A01 &OD->list[30]
|
||||
#define OD_ENTRY_H1A02 &OD->list[31]
|
||||
#define OD_ENTRY_H1A03 &OD->list[32]
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
Object dictionary entries - shortcuts with names
|
||||
*******************************************************************************/
|
||||
#define OD_ENTRY_H1000_deviceType &OD.list[0]
|
||||
#define OD_ENTRY_H1001_errorRegister &OD.list[1]
|
||||
#define OD_ENTRY_H1003_pre_definedErrorField &OD.list[2]
|
||||
#define OD_ENTRY_H1005_COB_ID_SYNCMessage &OD.list[3]
|
||||
#define OD_ENTRY_H1006_communicationCyclePeriod &OD.list[4]
|
||||
#define OD_ENTRY_H1007_synchronousWindowLength &OD.list[5]
|
||||
#define OD_ENTRY_H1010_storeParameters &OD.list[6]
|
||||
#define OD_ENTRY_H1011_restoreDefaultParameters &OD.list[7]
|
||||
#define OD_ENTRY_H1012_COB_IDTimeStampObject &OD.list[8]
|
||||
#define OD_ENTRY_H1014_COB_ID_EMCY &OD.list[9]
|
||||
#define OD_ENTRY_H1015_inhibitTimeEMCY &OD.list[10]
|
||||
#define OD_ENTRY_H1016_consumerHeartbeatTime &OD.list[11]
|
||||
#define OD_ENTRY_H1017_producerHeartbeatTime &OD.list[12]
|
||||
#define OD_ENTRY_H1018_identity &OD.list[13]
|
||||
#define OD_ENTRY_H1019_synchronousCounterOverflowValue &OD.list[14]
|
||||
#define OD_ENTRY_H1200_SDOServerParameter &OD.list[15]
|
||||
#define OD_ENTRY_H1280_SDOClientParameter &OD.list[16]
|
||||
#define OD_ENTRY_H1400_RPDOCommunicationParameter &OD.list[17]
|
||||
#define OD_ENTRY_H1401_RPDOCommunicationParameter &OD.list[18]
|
||||
#define OD_ENTRY_H1402_RPDOCommunicationParameter &OD.list[19]
|
||||
#define OD_ENTRY_H1403_RPDOCommunicationParameter &OD.list[20]
|
||||
#define OD_ENTRY_H1600_RPDOMappingParameter &OD.list[21]
|
||||
#define OD_ENTRY_H1601_RPDOMappingParameter &OD.list[22]
|
||||
#define OD_ENTRY_H1602_RPDOMappingParameter &OD.list[23]
|
||||
#define OD_ENTRY_H1603_RPDOMappingParameter &OD.list[24]
|
||||
#define OD_ENTRY_H1800_TPDOCommunicationParameter &OD.list[25]
|
||||
#define OD_ENTRY_H1801_TPDOCommunicationParameter &OD.list[26]
|
||||
#define OD_ENTRY_H1802_TPDOCommunicationParameter &OD.list[27]
|
||||
#define OD_ENTRY_H1803_TPDOCommunicationParameter &OD.list[28]
|
||||
#define OD_ENTRY_H1A00_TPDOMappingParameter &OD.list[29]
|
||||
#define OD_ENTRY_H1A01_TPDOMappingParameter &OD.list[30]
|
||||
#define OD_ENTRY_H1A02_TPDOMappingParameter &OD.list[31]
|
||||
#define OD_ENTRY_H1A03_TPDOMappingParameter &OD.list[32]
|
||||
#define OD_ENTRY_H1000_deviceType &OD->list[0]
|
||||
#define OD_ENTRY_H1001_errorRegister &OD->list[1]
|
||||
#define OD_ENTRY_H1003_pre_definedErrorField &OD->list[2]
|
||||
#define OD_ENTRY_H1005_COB_ID_SYNCMessage &OD->list[3]
|
||||
#define OD_ENTRY_H1006_communicationCyclePeriod &OD->list[4]
|
||||
#define OD_ENTRY_H1007_synchronousWindowLength &OD->list[5]
|
||||
#define OD_ENTRY_H1010_storeParameters &OD->list[6]
|
||||
#define OD_ENTRY_H1011_restoreDefaultParameters &OD->list[7]
|
||||
#define OD_ENTRY_H1012_COB_IDTimeStampObject &OD->list[8]
|
||||
#define OD_ENTRY_H1014_COB_ID_EMCY &OD->list[9]
|
||||
#define OD_ENTRY_H1015_inhibitTimeEMCY &OD->list[10]
|
||||
#define OD_ENTRY_H1016_consumerHeartbeatTime &OD->list[11]
|
||||
#define OD_ENTRY_H1017_producerHeartbeatTime &OD->list[12]
|
||||
#define OD_ENTRY_H1018_identity &OD->list[13]
|
||||
#define OD_ENTRY_H1019_synchronousCounterOverflowValue &OD->list[14]
|
||||
#define OD_ENTRY_H1200_SDOServerParameter &OD->list[15]
|
||||
#define OD_ENTRY_H1280_SDOClientParameter &OD->list[16]
|
||||
#define OD_ENTRY_H1400_RPDOCommunicationParameter &OD->list[17]
|
||||
#define OD_ENTRY_H1401_RPDOCommunicationParameter &OD->list[18]
|
||||
#define OD_ENTRY_H1402_RPDOCommunicationParameter &OD->list[19]
|
||||
#define OD_ENTRY_H1403_RPDOCommunicationParameter &OD->list[20]
|
||||
#define OD_ENTRY_H1600_RPDOMappingParameter &OD->list[21]
|
||||
#define OD_ENTRY_H1601_RPDOMappingParameter &OD->list[22]
|
||||
#define OD_ENTRY_H1602_RPDOMappingParameter &OD->list[23]
|
||||
#define OD_ENTRY_H1603_RPDOMappingParameter &OD->list[24]
|
||||
#define OD_ENTRY_H1800_TPDOCommunicationParameter &OD->list[25]
|
||||
#define OD_ENTRY_H1801_TPDOCommunicationParameter &OD->list[26]
|
||||
#define OD_ENTRY_H1802_TPDOCommunicationParameter &OD->list[27]
|
||||
#define OD_ENTRY_H1803_TPDOCommunicationParameter &OD->list[28]
|
||||
#define OD_ENTRY_H1A00_TPDOMappingParameter &OD->list[29]
|
||||
#define OD_ENTRY_H1A01_TPDOMappingParameter &OD->list[30]
|
||||
#define OD_ENTRY_H1A02_TPDOMappingParameter &OD->list[31]
|
||||
#define OD_ENTRY_H1A03_TPDOMappingParameter &OD->list[32]
|
||||
|
||||
#endif /* OD_H */
|
||||
|
|
|
|||
|
|
@ -514,7 +514,7 @@ int main (int argc, char *argv[]) {
|
|||
err = CO_CANopenInit(CO, /* CANopen object */
|
||||
NULL, /* alternate NMT */
|
||||
NULL, /* alternate em */
|
||||
&OD, /* Object dictionary */
|
||||
OD, /* Object dictionary */
|
||||
OD_STATUS_BITS, /* Optional OD_statusBits */
|
||||
NMT_CONTROL, /* CO_NMT_control_t */
|
||||
FIRST_HB_TIME, /* firstHBTime_ms */
|
||||
|
|
|
|||
Loading…
Reference in a new issue