diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..29df842 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "linux-gcc-x64", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu17", + "cppStandard": "gnu++17", + "intelliSenseMode": "linux-gcc-x64", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..8e45d8d --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C/C++ Runner: Debug Session", + "type": "cppdbg", + "request": "launch", + "args": [], + "stopAtEntry": false, + "externalConsole": false, + "cwd": "/home/pedro/projects/naust/CANopenNode", + "program": "/home/pedro/projects/naust/CANopenNode/build/Debug/outDebug", + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..970c545 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,59 @@ +{ + "C_Cpp_Runner.cCompilerPath": "gcc", + "C_Cpp_Runner.cppCompilerPath": "g++", + "C_Cpp_Runner.debuggerPath": "gdb", + "C_Cpp_Runner.cStandard": "gnu17", + "C_Cpp_Runner.cppStandard": "gnu++17", + "C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false +} \ No newline at end of file diff --git a/401/analogInputBlockDiagram.h b/401/analogInputBlockDiagram.h new file mode 100644 index 0000000..52bd4d1 --- /dev/null +++ b/401/analogInputBlockDiagram.h @@ -0,0 +1,43 @@ +#pragma once + +#include "invertValue.h" +#include "stdint.h" + +#include "debug.h" + +template +struct AnalogInputModule { + T val; + T last_val; + + uint16_t od_index; + uint8_t od_subindex; + uint8_t length; + uint8_t channel; + + int32_t offset; + int32_t pre_scaling; + int32_t upper_limit; + int32_t lower_limit; + int32_t delta; + int32_t negative_delta; + int32_t positive_delta; + bool interrupt_enable; +}; + +template +T getAnalogInputFiltered(AnalogInputModule module) { + T filtered_val = module.val + module.offset; + + // Apply pre-scaling + filtered_val = filtered_val * module.pre_scaling; + + const bool upper_limit_triggered = filtered_val >= module.upper_limit; + const bool lower_limit_triggered = filtered_val < module.lower_limit; + const int32_t delta = filtered_val - module.last_val; + const bool delta_triggered = delta > module.delta || delta < module.negative_delta || delta > module.positive_delta; + + const bool condition = (upper_limit_triggered ^ lower_limit_triggered) && delta_triggered; + + return module.interrupt_enable && condition ? filtered_val : module.last_val; +} \ No newline at end of file diff --git a/401/digitalInputBlockDiagram.h b/401/digitalInputBlockDiagram.h new file mode 100644 index 0000000..c3363ab --- /dev/null +++ b/401/digitalInputBlockDiagram.h @@ -0,0 +1,38 @@ +#pragma once + +#include "invertValue.h" +#include "stdint.h" + +template +struct DigitalInputModule { + T val; + uint16_t od_index; + uint8_t od_subindex; + uint8_t length; + uint8_t channel; + bool polarity; + bool filter_constant; + bool any_change; + bool high_to_low; + bool low_to_high; + bool interrupt_enable; +}; + +template +T getDigitalInputFiltered(DigitalInputModule module) { + T val = module.val; + + if (module.filter_constant) { + val = 0; + } + + if (module.polarity) { + val = invertValue(val); + } + + if (!module.interrupt_enable) { + val = 0; + } + + return val; +} \ No newline at end of file diff --git a/401/digitalOutputBlockDiagram.h b/401/digitalOutputBlockDiagram.h new file mode 100644 index 0000000..6a0e9a3 --- /dev/null +++ b/401/digitalOutputBlockDiagram.h @@ -0,0 +1,37 @@ +#pragma once + +#include "invert_value.h" +#include "stdint.h" + +template +struct DigitalOutputModule { + T val; + uint16_t od_index; + uint8_t od_subindex; + uint8_t length; + uint8_t channel; + bool error_mode; + bool error_value; + bool polarity; + bool filter_mask; +}; + +template +T getDigitalOutputFiltered(DigitalOutputModule module, const bool failure = false) { + T val = module.val; + + if (failure) { + if (module.error_mode) { + val = module.error_value; + } + } else { + if (module.polarity) { + val = invertValue(val); + } + + if (!module.filter_mask) { + val = 0; + } + } + return val; +} \ No newline at end of file diff --git a/401/invertValue.h b/401/invertValue.h new file mode 100644 index 0000000..f874ac7 --- /dev/null +++ b/401/invertValue.h @@ -0,0 +1,12 @@ +#pragma once + +template +static T invertValue(T val) { + return ~val; +} + +// Specialization for bool +template <> +bool invertValue(bool val) { + return !val; +} \ No newline at end of file diff --git a/CO_driver_example.cpp b/CO_driver_example.cpp new file mode 100644 index 0000000..ce1a17c --- /dev/null +++ b/CO_driver_example.cpp @@ -0,0 +1,395 @@ +/* + * CAN module object for generic microcontroller. + * + * This file is a template for other microcontrollers. + * + * @file CO_driver.c + * @ingroup CO_driver + * @author Janez Paternoster + * @copyright 2004 - 2020 Janez Paternoster + * + * This file is part of , a CANopen Stack. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +#include "301/CO_driver.h" +#include "301/CO_driver_target.h" + +#include "can_interface.h" +#include "debug.h" + +void CO_CANsetConfigurationMode(void* CANptr) { + /* Put CAN module in configuration mode */ + CanInterface* can = (CanInterface*)CANptr; + if (!can->setMode(CAN_MODE::_MODE_CONFIG)) { + LOG_ERROR("CO_CANsetConfigurationMode: setMode failed\n"); + } else { + LOG_INFO("CO_CANsetConfigurationMode: setMode success\n"); + } +} + +void CO_CANsetNormalMode(CO_CANmodule_t* CANmodule) { + /* Put CAN module in normal mode */ + CanInterface* can = (CanInterface*)CANmodule->CANptr; + if (!can->setMode(CAN_MODE::_MCP_NORMAL)) { + LOG_ERROR("CO_CANsetNormalMode: setMode failed\n"); + } + + CANmodule->CANnormal = true; + LOG_INFO("CO_CANsetNormalMode: setMode success\n"); +} + +CO_ReturnError_t CO_CANmodule_init(CO_CANmodule_t* CANmodule, + void* CANptr, + CO_CANrx_t rxArray[], + uint16_t rxSize, + CO_CANtx_t txArray[], + uint16_t txSize, + uint16_t CANbitRate) { + uint16_t i; + + /* verify arguments */ + if (CANmodule == NULL || rxArray == NULL || txArray == NULL) { + return CO_ERROR_ILLEGAL_ARGUMENT; + } + + /* Configure object variables */ + CANmodule->CANptr = CANptr; + CANmodule->rxArray = rxArray; + CANmodule->rxSize = rxSize; + CANmodule->txArray = txArray; + CANmodule->txSize = txSize; + CANmodule->CANerrorStatus = 0; + CANmodule->CANnormal = false; + CANmodule->useCANrxFilters = (rxSize <= 32U) ? true : false; /* microcontroller dependent */ + CANmodule->bufferInhibitFlag = false; + CANmodule->firstCANtxMessage = true; + CANmodule->CANtxCount = 0U; + CANmodule->errOld = 0U; + + for (i = 0U; i < rxSize; i++) { + rxArray[i].ident = 0U; + rxArray[i].mask = 0xFFFFU; + rxArray[i].object = NULL; + rxArray[i].CANrx_callback = NULL; + } + for (i = 0U; i < txSize; i++) { + txArray[i].bufferFull = false; + } + + /* Configure CAN module registers */ + CanInterface* can = (CanInterface*)CANptr; + const CAN_SPEED speed = getSpeed(CANbitRate); + if (!can->setup(speed)) { + LOG_ERROR("CO_CANmodule_init: setup failed\n"); + return CO_ERROR_ILLEGAL_ARGUMENT; + } + + /* Configure CAN timing */ + + /* Configure CAN module hardware filters */ + if (CANmodule->useCANrxFilters) { + /* CAN module filters are used, they will be configured with */ + /* CO_CANrxBufferInit() functions, called by separate CANopen */ + /* init functions. */ + /* Configure all masks so, that received message must match filter */ + } else { + /* CAN module filters are not used, all messages with standard 11-bit */ + /* identifier will be received */ + /* Configure mask 0 so, that all messages with standard identifier are accepted */ + } + + /* configure CAN interrupt registers */ + + return CO_ERROR_NO; +} + +void CO_CANmodule_disable(CO_CANmodule_t* CANmodule) { + if (CANmodule != NULL) { + /* turn off the module */ + } +} + +CO_ReturnError_t CO_CANrxBufferInit(CO_CANmodule_t* CANmodule, + uint16_t index, + uint16_t ident, + uint16_t mask, + bool_t rtr, + void* object, + void (*CANrx_callback)(void* object, void* message)) { + CO_ReturnError_t ret = CO_ERROR_NO; + LOG_DEBUG("0x%x - 0x%x - 0x%x - 0x%x\n", index, ident, mask, rtr); + + if ((CANmodule != NULL) && (object != NULL) && (CANrx_callback != NULL) && (index < CANmodule->rxSize)) { + /* buffer, which will be configured */ + CO_CANrx_t* buffer = &CANmodule->rxArray[index]; + + /* Configure object variables */ + buffer->object = object; + buffer->CANrx_callback = CANrx_callback; + + /* CAN identifier and CAN mask, bit aligned with CAN module. Different on different microcontrollers. */ + buffer->ident = ident & 0x07FFU; + if (rtr) { + buffer->ident |= 0x0800U; + } + buffer->mask = (mask & 0x07FFU) | 0x0800U; + + LOG_DEBUG("CO_CANrxBufferInit: ident: 0x%x - mask: 0x%x\n", buffer->ident, buffer->mask); + + /* Set CAN hardware module filter and mask. */ + if (CANmodule->useCANrxFilters) { + LOG_DEBUG("CO_CANrxBufferInit: useCANrxFilters\n"); + } + } else { + ret = CO_ERROR_ILLEGAL_ARGUMENT; + LOG_DEBUG("CO_CANrxBufferInit: illegal argument ?\n"); + } + + return ret; +} + +CO_CANtx_t* CO_CANtxBufferInit(CO_CANmodule_t* CANmodule, + uint16_t index, + uint16_t ident, + bool_t rtr, + uint8_t noOfBytes, + bool_t syncFlag) { + CO_CANtx_t* buffer = NULL; + + if ((CANmodule != NULL) && (index < CANmodule->txSize)) { + /* get specific buffer */ + buffer = &CANmodule->txArray[index]; + buffer->ident = (uint32_t)ident & 0x07FFU; + if (rtr) { + buffer->ident |= 0x0800U; + } + buffer->DLC = noOfBytes; + buffer->bufferFull = false; + buffer->syncFlag = syncFlag; + } + + return buffer; +} + +CO_ReturnError_t CO_CANsend(CO_CANmodule_t* CANmodule, CO_CANtx_t* buffer) { + CO_ReturnError_t err = CO_ERROR_NO; + + /* Verify overflow */ + if (buffer->bufferFull) { + LOG_WARNING("CO_CANsend: buffer full\n"); + if (!CANmodule->firstCANtxMessage) { + /* don't set error, if bootup message is still on buffers */ + CANmodule->CANerrorStatus |= CO_CAN_ERRTX_OVERFLOW; + } + err = CO_ERROR_TX_OVERFLOW; + } + + CO_LOCK_CAN_SEND(CANmodule); + /* if CAN TX buffer is free, copy message to it */ + CanInterface* can = (CanInterface*)CANmodule->CANptr; + const CanOpenMsg msg(buffer->ident, buffer->data, buffer->DLC); + // DEBUG("Ident: 0x%x - DLC: %d", buffer->ident, buffer->DLC); + // for (uint8_t i = 0; i < buffer->DLC; i++) { + // DEBUG(" 0x%x", buffer->data[i]); + // } + // DEBUG("\r\n"); + + if (1 && CANmodule->CANtxCount == 0) { + // LOG_DEBUG("CO_CANsend\n"); + if (can->send(msg)) { + LOG_DEBUG("CO_CANsend: sent - NodeID: 0x%x - Fx: 0x%x - Len: 0x%x", msg.getNodeId(), msg.getFunctionCode(), + msg.getLen()); + CANmodule->bufferInhibitFlag = buffer->syncFlag; + } else { + LOG_ERROR("CO_CANsend: failed - CobID: 0x%x NodeID: 0x%x - Fx: 0x%x - Len: 0x%x", msg.getCobId(), + msg.getNodeId(), msg.getFunctionCode(), msg.getLen()); + } + /* copy message and txRequest */ + } + /* if no buffer is free, message will be sent by interrupt */ + else { + LOG_WARNING("CO_CANsend: buffer full\n"); + buffer->bufferFull = true; + CANmodule->CANtxCount++; + // can->send(msg); + } + CO_UNLOCK_CAN_SEND(CANmodule); + + return err; +} + +void CO_CANclearPendingSyncPDOs(CO_CANmodule_t* CANmodule) { + uint32_t tpdoDeleted = 0U; + + CO_LOCK_CAN_SEND(CANmodule); + /* Abort message from CAN module, if there is synchronous TPDO. + * Take special care with this functionality. */ + if (/* messageIsOnCanBuffer && */ CANmodule->bufferInhibitFlag) { + /* clear TXREQ */ + CANmodule->bufferInhibitFlag = false; + tpdoDeleted = 1U; + } + /* delete also pending synchronous TPDOs in TX buffers */ + if (CANmodule->CANtxCount != 0U) { + uint16_t i; + CO_CANtx_t* buffer = &CANmodule->txArray[0]; + for (i = CANmodule->txSize; i > 0U; i--) { + if (buffer->bufferFull) { + if (buffer->syncFlag) { + buffer->bufferFull = false; + CANmodule->CANtxCount--; + tpdoDeleted = 2U; + } + } + buffer++; + } + } + CO_UNLOCK_CAN_SEND(CANmodule); + + if (tpdoDeleted != 0U) { + CANmodule->CANerrorStatus |= CO_CAN_ERRTX_PDO_LATE; + } +} + +/* Get error counters from the module. If necessary, function may use different way to determine errors. */ +static uint16_t rxErrors = 0, txErrors = 0, overflow = 0; + +void CO_CANmodule_process(CO_CANmodule_t* CANmodule) { + uint32_t err; + + err = ((uint32_t)txErrors << 16) | ((uint32_t)rxErrors << 8) | overflow; + + if (CANmodule->errOld != err) { + uint16_t status = CANmodule->CANerrorStatus; + + CANmodule->errOld = err; + + if (txErrors >= 256U) { + /* bus off */ + status |= CO_CAN_ERRTX_BUS_OFF; + } else { + /* recalculate CANerrorStatus, first clear some flags */ + status &= 0xFFFF ^ (CO_CAN_ERRTX_BUS_OFF | CO_CAN_ERRRX_WARNING | CO_CAN_ERRRX_PASSIVE | + CO_CAN_ERRTX_WARNING | CO_CAN_ERRTX_PASSIVE); + + /* rx bus warning or passive */ + if (rxErrors >= 128) { + status |= CO_CAN_ERRRX_WARNING | CO_CAN_ERRRX_PASSIVE; + } else if (rxErrors >= 96) { + status |= CO_CAN_ERRRX_WARNING; + } + + /* tx bus warning or passive */ + if (txErrors >= 128) { + status |= CO_CAN_ERRTX_WARNING | CO_CAN_ERRTX_PASSIVE; + } else if (txErrors >= 96) { + status |= CO_CAN_ERRTX_WARNING; + } + + /* if not tx passive clear also overflow */ + if ((status & CO_CAN_ERRTX_PASSIVE) == 0) { + status &= 0xFFFF ^ CO_CAN_ERRTX_OVERFLOW; + } + } + + if (overflow != 0) { + /* CAN RX bus overflow */ + status |= CO_CAN_ERRRX_OVERFLOW; + } + + CANmodule->CANerrorStatus = status; + } +} + +void CO_CANinterrupt(CO_CANmodule_t* CANmodule) { + /* receive interrupt */ + CanInterface* can = (CanInterface*)CANmodule->CANptr; + if (can->read()) { + CO_CANrxMsg_t rcvMsg; /* pointer to received message in CAN module */ + uint16_t index; /* index of received message */ + uint32_t rcvMsgIdent; /* identifier of the received message */ + CO_CANrx_t* buffer = NULL; /* receive message buffer from CO_CANmodule_t object. */ + bool_t msgMatched = false; + + const CanOpenMsg msg = can->getCanOpenMsg(); + const uint32_t id = msg.getCobId(); + const uint8_t len = msg.getLen(); + rcvMsg.ident = id; + rcvMsg.DLC = len; + // DEBUG("MSG received: id 0x%x - len %d", rcvMsg.ident, rcvMsg.DLC); + for (uint8_t i = 0; i < len; i++) { + rcvMsg.data[i] = msg.getData(i); + // DEBUG(" %d", rcvMsg.data[i]); + } + // DEBUG("\r\n"); + LOG_DEBUG("MSG received: id 0x%x - len %d\n", rcvMsg.ident, rcvMsg.DLC); + rcvMsgIdent = rcvMsg.ident; + + /* CAN module filters are not used, message with any standard 11-bit identifier */ + /* has been received. Search rxArray form CANmodule for the same CAN-ID. */ + buffer = &CANmodule->rxArray[0]; + for (index = 0; index < CANmodule->rxSize; index++) { + // LOG_DEBUG("Buffer: 0x%x - 0x%x - 0x%x\n", buffer->ident, buffer->mask, buffer->object); + if (((rcvMsgIdent ^ buffer->ident) & buffer->mask) == 0U) { + msgMatched = true; + break; + } + buffer++; + } + + /* Call specific function, which will process the message */ + if (msgMatched && (buffer != NULL) && (buffer->CANrx_callback != NULL)) { + LOG_DEBUG("Message: 0x%x - 0x%x - 0x%x\n", rcvMsg.ident, buffer->ident, buffer->mask); + buffer->CANrx_callback(buffer->object, (void*)&rcvMsg); + } + + /* Clear interrupt flag */ + } + + // /* transmit interrupt */ + // else if (0) { + // /* Clear interrupt flag */ + + // /* First CAN message (bootup) was sent successfully */ + // CANmodule->firstCANtxMessage = false; + // /* clear flag from previous message */ + // CANmodule->bufferInhibitFlag = false; + // /* Are there any new messages waiting to be send */ + // if (CANmodule->CANtxCount > 0U) { + // uint16_t i; /* index of transmitting message */ + + // /* first buffer */ + // CO_CANtx_t* buffer = &CANmodule->txArray[0]; + // /* search through whole array of pointers to transmit message buffers. */ + // for (i = CANmodule->txSize; i > 0U; i--) { + // /* if message buffer is full, send it. */ + // if (buffer->bufferFull) { + // buffer->bufferFull = false; + // CANmodule->CANtxCount--; + + // /* Copy message to CAN buffer */ + // CANmodule->bufferInhibitFlag = buffer->syncFlag; + // /* canSend... */ + // break; /* exit for loop */ + // } + // buffer++; + // } /* end of for loop */ + + // /* Clear counter if no more messages */ + // if (i == 0U) { + // CANmodule->CANtxCount = 0U; + // } + // } + // } else { + // /* some other interrupt reason */ + // } +} diff --git a/OD/CO_ident_defs.h b/OD/CO_ident_defs.h new file mode 100644 index 0000000..327d9db --- /dev/null +++ b/OD/CO_ident_defs.h @@ -0,0 +1,23 @@ +/* + * Device identification definitions for CANopenNode. + */ + +/* Initial (newly programmed device) CAN bit rate and CANopen Node Id */ +#define CO_BITRATE_INITIAL 500 +#define CO_NODE_ID_INITIAL 0xff + +/* Manufacturer device name, OD entry 0x1008 */ +#define CO_DEVICE_NAME "CANopenDemoRP2040" +/* Manufacturer hardware version, OD entry 0x1009 */ +#define CO_HW_VERSION "---" +/* Manufacturer software version, OD entry 0x100A, updated on make from git + * version. It has form `"--g[-dirty]"`, where `` is + * name of the last tag, `` is number of commits above the tag, `g` is for + * git, `` is commit ID and `-dirty` shows, if git is not clean. */ +#define CO_SW_VERSION "---" + +/* Identity, OD entry 0x1018 */ +#define CO_IDENTITY_VENDOR_ID 0x00000000 +#define CO_IDENTITY_PRODUCT_CODE 0x00000001 +#define CO_IDENTITY_REVISION_NUMBER 0x00000000 +#define CO_IDENTITY_SERIAL_NUMBER 0x00000003 diff --git a/OD/CO_identificators.c b/OD/CO_identificators.c new file mode 100644 index 0000000..842910d --- /dev/null +++ b/OD/CO_identificators.c @@ -0,0 +1,112 @@ +/* + * Device identificators for CANopenNode. + * + * @file CO_identificators.c + * @author -- + * @copyright 2021 -- + * + * This file is part of CANopenNode, an opensource CANopen Stack. + * Project home page is . + * For more information on CANopen see . + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CO_identificators.h" +#include "301/CO_ODinterface.h" +#include "CO_ident_defs.h" +#include "OD.h" + +/* + * Custom function for reading OD object _Manufacturer device name_ + * + * For more information see file CO_ODinterface.h, OD_IO_t. + */ +static ODR_t OD_read_1008(OD_stream_t* stream, void* buf, OD_size_t count, OD_size_t* countRead) { + if (stream == NULL || buf == NULL || countRead == NULL) { + return ODR_DEV_INCOMPAT; + } + + OD_size_t len = strlen(CO_DEVICE_NAME); + if (len > count) + len = count; + memcpy(buf, CO_DEVICE_NAME, len); + + *countRead = stream->dataLength = len; + return ODR_OK; +} + +/* + * Custom function for reading OD object _Manufacturer hardware version_ + * + * For more information see file CO_ODinterface.h, OD_IO_t. + */ +static ODR_t OD_read_1009(OD_stream_t* stream, void* buf, OD_size_t count, OD_size_t* countRead) { + if (stream == NULL || buf == NULL || countRead == NULL) { + return ODR_DEV_INCOMPAT; + } + + OD_size_t len = strlen(CO_HW_VERSION); + if (len > count) + len = count; + memcpy(buf, CO_HW_VERSION, len); + + *countRead = stream->dataLength = len; + return ODR_OK; +} + +/* + * Custom function for reading OD object _Manufacturer software version_ + * + * For more information see file CO_ODinterface.h, OD_IO_t. + */ +static ODR_t OD_read_100A(OD_stream_t* stream, void* buf, OD_size_t count, OD_size_t* countRead) { + if (stream == NULL || buf == NULL || countRead == NULL) { + return ODR_DEV_INCOMPAT; + } + + OD_size_t len = strlen(CO_SW_VERSION); + if (len > count) + len = count; + memcpy(buf, CO_SW_VERSION, len); + + *countRead = stream->dataLength = len; + return ODR_OK; +} + +/* Extensions for OD objects */ +OD_extension_t OD_1008_extension = {.object = NULL, .read = OD_read_1008, .write = NULL}; +OD_extension_t OD_1009_extension = {.object = NULL, .read = OD_read_1009, .write = NULL}; +OD_extension_t OD_100A_extension = {.object = NULL, .read = OD_read_100A, .write = NULL}; + +/******************************************************************************/ +void CO_identificators_init(uint16_t* bitRate, uint8_t* nodeId) { + /* Set initial CAN bitRate and CANopen nodeId. May be configured by LSS. */ + if (*bitRate == 0) + *bitRate = CO_BITRATE_INITIAL; + if (*nodeId == 0) + *nodeId = CO_NODE_ID_INITIAL; + + /* Initialize OD objects 0x1008, 0x1009 and 0x100A. These are device + * specific strings. Object dictionary has no default value for strings, + * so custom read functions are required for objects to work. */ + OD_extension_init(OD_ENTRY_H1008_manufacturerDeviceName, &OD_1008_extension); + OD_extension_init(OD_ENTRY_H1009_manufacturerHardwareVersion, &OD_1009_extension); + OD_extension_init(OD_ENTRY_H100A_manufacturerSoftwareVersion, &OD_100A_extension); + + /* Write values directly to the Object Dictionary Identity object. */ + OD_PERSIST_COMM.x1018_identity.vendor_ID = CO_IDENTITY_VENDOR_ID; + OD_PERSIST_COMM.x1018_identity.productCode = CO_IDENTITY_PRODUCT_CODE; + OD_PERSIST_COMM.x1018_identity.revisionNumber = CO_IDENTITY_REVISION_NUMBER; + OD_PERSIST_COMM.x1018_identity.serialNumber = CO_IDENTITY_SERIAL_NUMBER; +} diff --git a/OD/CO_identificators.h b/OD/CO_identificators.h new file mode 100644 index 0000000..10b0e41 --- /dev/null +++ b/OD/CO_identificators.h @@ -0,0 +1,50 @@ +/** + * Device identificators for CANopenNode. + * + * @file CO_identificators.h + * @author -- + * @copyright 2021 -- + * + * This file is part of CANopenNode, an opensource CANopen Stack. + * Project home page is . + * For more information on CANopen see . + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CO_IDENTIFICATORS_H +#define CO_IDENTIFICATORS_H + +#include "301/CO_driver.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Function configures default CAN bitRate and CANopen nodeId. Further it + * configures OD objects 0x1008(manufacturerDeviceName), + * 0x1009(manufacturerHardwareVersion), 0x100A(manufacturerSoftwareVersion) and + * 0x1018(identity). It reads definitions from target device specified + * CO_ident_defs.h file. + * + * @param [in,out] bitRate CAN bit rate, set if undefined. + * @param [in,out] nodeId CANopen NodeId, set if undefined. + */ +void CO_identificators_init(uint16_t* bitRate, uint8_t* nodeId); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CO_IDENTIFICATORS_H */ diff --git a/OD/OD.c b/OD/OD.c new file mode 100644 index 0000000..5aba447 --- /dev/null +++ b/OD/OD.c @@ -0,0 +1,1747 @@ +/******************************************************************************* + CANopen Object Dictionary definition for CANopenNode V4 + + This file was automatically generated by CANopenEditor v4.1-1-ga49a51a + + https://github.com/CANopenNode/CANopenNode + https://github.com/CANopenNode/CANopenEditor + + DON'T EDIT THIS FILE MANUALLY, UNLESS YOU KNOW WHAT YOU ARE DOING !!!! +*******************************************************************************/ + +#define OD_DEFINITION +#include "OD.h" +#include "301/CO_ODinterface.h" + +#if CO_VERSION_MAJOR < 4 +#error This Object dictionary is compatible with CANopenNode V4.0 and above! +#endif + +/******************************************************************************* + OD data initialization of all groups +*******************************************************************************/ +OD_ATTR_PERSIST_COMM OD_PERSIST_COMM_t OD_PERSIST_COMM = { + .x1000_deviceType = 0x00238191 /* 0x000F0191 */, + .x1005_COB_ID_SYNCMessage = 0x40000080 /* 0x00000080 */, + .x1006_communicationCyclePeriod = /* 0x00000000 */ 0x005F5E100 /* 0x00001388 */, + .x1007_synchronousWindowLength = 0x00000000, + .x1012_COB_IDTimeStampObject = /* 0x40000100 */ 0x00000100, + .x1014_COB_ID_EMCY = 0x00000080, + .x1015_inhibitTimeEMCY = 0x0000, + .x1016_consumerHeartbeatTime_sub0 = 0x07, + .x1016_consumerHeartbeatTime = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + .x1017_producerHeartbeatTime = 0x03e8, + .x1018_identity = {.highestSub_indexSupported = 0x04, + .vendor_ID = 0x00000000, + .productCode = 0x00000000, + .revisionNumber = 0x00000000, + .serialNumber = 0x00000000}, + .x1019_synchronousCounterOverflowValue = 0xff /* 0x00 */, + .x1280_SDOClientParameter = {.highestSub_indexSupported = 0x03, + .COB_IDClientToServerTx = 0x80000000, + .COB_IDServerToClientRx = 0x80000000, + .node_IDOfTheSDOServer = 0x01}, + .x1400_RPDOCommunicationParameter = {.highestSub_indexSupported = 0x02, + .COB_IDUsedByRPDO = /* 0xC0000200 */ 0x00000200, + .transmissionType = /* 0x00 */ 0xFF}, + .x1401_RPDOCommunicationParameter = {.highestSub_indexSupported = 0x02, + .COB_IDUsedByRPDO = 0xC0000300 /* 0x00000300 */, + .transmissionType = 0x00 /* 0xFF */}, + .x1402_RPDOCommunicationParameter = {.highestSub_indexSupported = 0x02, + .COB_IDUsedByRPDO = 0x80000400 /* 0x00000400 */, + .transmissionType = 0x00 /* 0xFF */}, + .x1403_RPDOCommunicationParameter = {.highestSub_indexSupported = 0x02, + .COB_IDUsedByRPDO = 0x80000500 /* 0x00000500 */, + .transmissionType = 0x00 /* 0xFF */}, + .x1600_RPDOMappingParameter = + {.numberOfMappedApplicationObjectsInPDO = 0x01, + .applicationObject1 = + /* 0x00000000 */ 0x62000140 /* 8bit */ /* 0x62200108 */ /* 1bit */ /* 0x63000130 16bit */, + /* 0x6200 indexs + 0x01 subindex + 0x40 length in bits -> 8 * 8 = 0x40 bytes + */ + .applicationObject2 = 0x00000000 /* 0x62000520 */ /* 0x62200310 */, + .applicationObject3 = 0x00000000 /* 0x62000308 */ /* 0x62200510 */, + .applicationObject4 = 0x00000000 /* 0x62000408 */ /* 0x62200710 */, + .applicationObject5 = 0x00000000 /* 0x62000508 */, + .applicationObject6 = 0x00000000 /* 0x62000608 */, + .applicationObject7 = 0x00000000 /* 0x62000708 */, + .applicationObject8 = 0x00000000 /* 0x62000808 */}, + .x1601_RPDOMappingParameter = {.numberOfMappedApplicationObjectsInPDO = 0x00, + .applicationObject1 = 0x00000000 /* 0x64110140 */, + .applicationObject2 = 0x00000000 /* 0x64110210 */, + .applicationObject3 = 0x00000000 /* 0x64110310 */, + .applicationObject4 = 0x00000000 /* 0x64110410 */, + .applicationObject5 = 0x00000000, + .applicationObject6 = 0x00000000, + .applicationObject7 = 0x00000000, + .applicationObject8 = 0x00000000}, + .x1602_RPDOMappingParameter = {.numberOfMappedApplicationObjectsInPDO = 0x00, + .applicationObject1 = 0x00000000 /* 0x64110510 */, + .applicationObject2 = 0x00000000 /* 0x64110610 */, + .applicationObject3 = 0x00000000 /* 0x64110710 */, + .applicationObject4 = 0x00000000 /* 0x64110810 */, + .applicationObject5 = 0x00000000, + .applicationObject6 = 0x00000000, + .applicationObject7 = 0x00000000, + .applicationObject8 = 0x00000000}, + .x1603_RPDOMappingParameter = {.numberOfMappedApplicationObjectsInPDO = 0x00, + .applicationObject1 = 0x00000000 /* 0x64110910 */, + .applicationObject2 = 0x00000000 /* 0x64110A10 */, + .applicationObject3 = 0x00000000 /* 0x64110B10 */, + .applicationObject4 = 0x00000000 /* 0x64110C10 */, + .applicationObject5 = 0x00000000, + .applicationObject6 = 0x00000000, + .applicationObject7 = 0x00000000, + .applicationObject8 = 0x00000000}, + .x1800_TPDOCommunicationParameter = {.highestSub_indexSupported = 0x06, + .COB_IDUsedByTPDO = 0x00000180 /* 0xC0000180 */, + .transmissionType = 0xFF, + .inhibitTime = 0x0000, + .eventTimer = 0x0000, + .SYNCStartValue = 0x00}, + .x1801_TPDOCommunicationParameter = {.highestSub_indexSupported = 0x06, + .COB_IDUsedByTPDO = 0x00000280 /* 0x80000280 */, + .transmissionType = 0xFF, + .inhibitTime = 0x0000, + .eventTimer = 0x0000, + .SYNCStartValue = 0x00}, + .x1802_TPDOCommunicationParameter = {.highestSub_indexSupported = 0x06, + .COB_IDUsedByTPDO = /* 0x00000380 */ 0x80000380 /* 0x00000000 */, + .transmissionType = /* 0xFF */ 0x00, + .inhibitTime = 0x0000, + .eventTimer = 0x0000, + .SYNCStartValue = 0x00}, + .x1803_TPDOCommunicationParameter = {.highestSub_indexSupported = 0x06, + .COB_IDUsedByTPDO = /* 0x00000480 */ 0x80000480 /* 0x00000000 */, + .transmissionType = /* 0xFF */ 0x00, + .inhibitTime = 0x0000, + .eventTimer = 0x0000, + .SYNCStartValue = 0x00}, + .x1A00_TPDOMappingParameter = {.numberOfMappedApplicationObjectsInPDO = 0x01, + .applicationObject1 = + /* 0x00000000 */ /* 0x60000140 */ /* 8bit */ 0x60200108 /* 1bit */, + .applicationObject2 = 0x00000000 /* 0x60000208 */, + .applicationObject3 = 0x00000000 /* 0x60000308 */, + .applicationObject4 = 0x00000000 /* 0x60000408 */, + .applicationObject5 = 0x00000000 /* 0x60000508 */, + .applicationObject6 = 0x00000000 /* 0x60000608 */, + .applicationObject7 = 0x00000000 /* 0x60000708 */, + .applicationObject8 = 0x00000000 /* 0x60000808 */}, + .x1A01_TPDOMappingParameter = {.numberOfMappedApplicationObjectsInPDO = 0x01, + .applicationObject1 = /* 0x00000000 */ 0x64010140, + .applicationObject2 = 0x00000000 /* 0x64010210 */, + .applicationObject3 = 0x00000000 /* 0x64010310 */, + .applicationObject4 = 0x00000000 /* 0x64010410 */, + .applicationObject5 = 0x00000000 /* 0x00000000 */, + .applicationObject6 = 0x00000000 /* 0x00000000 */, + .applicationObject7 = 0x00000000 /* 0x00000000 */, + .applicationObject8 = 0x00000000 /* 0x00000000 */}, + .x1A02_TPDOMappingParameter = {.numberOfMappedApplicationObjectsInPDO = 0x00, + .applicationObject1 = 0x00000000 /* 0x64010510 */, + .applicationObject2 = 0x00000000 /* 0x64010610 */, + .applicationObject3 = 0x00000000 /* 0x64010710 */, + .applicationObject4 = 0x00000000 /* 0x64010810 */, + .applicationObject5 = 0x00000000 /* 0x00000000 */, + .applicationObject6 = 0x00000000 /* 0x00000000 */, + .applicationObject7 = 0x00000000 /* 0x00000000 */, + .applicationObject8 = 0x00000000 /* 0x00000000 */}, + .x1A03_TPDOMappingParameter = {.numberOfMappedApplicationObjectsInPDO = 0x00, + .applicationObject1 = 0x00000000 /* 0x64010910 */, + .applicationObject2 = 0x00000000 /* 0x64010A10 */, + .applicationObject3 = 0x00000000 /* 0x64010B10 */, + .applicationObject4 = 0x00000000 /* 0x64010C10 */, + .applicationObject5 = 0x00000000 /* 0x00000000 */, + .applicationObject6 = 0x00000000 /* 0x00000000 */, + .applicationObject7 = 0x00000000 /* 0x00000000 */, + .applicationObject8 = 0x00000000 /* 0x00000000 */}}; + +OD_ATTR_RAM OD_RAM_t OD_RAM = { + .x1001_errorRegister = 0x00, + .x1010_storeParameters_sub0 = 0x04, + .x1010_storeParameters = {0x00000003, 0x00000001, 0x00000001, 0x00000003}, + .x1011_restoreDefaultParameters_sub0 = 0x04, + .x1011_restoreDefaultParameters = {0x00000001, 0x00000001, 0x00000001, 0x00000001}, + .x1200_SDOServerParameter = {.highestSub_indexSupported = 0x02, + .COB_IDClientToServerRx = 0x00000600, + .COB_IDServerToClientTx = 0x00000580}, + .x2100_errorStatusBits = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x2110_variableInt32_sub0 = 0x10, + .x2110_variableInt32 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + .x6000_readDigitalInput8_bit_sub0 = 0x08, + .x6000_readDigitalInput8_bit = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6002_polarityDigitalInput8_bit_sub0 = 0x08, + .x6002_polarityDigitalInput8_bit = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6003_digitalFilterEnable8_bit_sub0 = 0x08, + .x6003_digitalFilterEnable8_bit = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6005_globalInterruptEnableDigital8_bit = 0x01, + .x6006_digitalInterruptMaskAnyChange8_bit_sub0 = 0x08, + .x6006_digitalInterruptMaskAnyChange8_bit = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .x6007_digitalInterruptMaskLowToHigh8_bit_sub0 = 0x08, + .x6007_digitalInterruptMaskLowToHigh8_bit = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6008_digitalInterruptMaskHighToLow8_bit_sub0 = 0x08, + .x6008_digitalInterruptMaskHighToLow8_bit = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6020_readDigitalInputBit1To128_sub0 = 0x08, + .x6020_readDigitalInputBit1To128 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6030_polarityDigitalInputBit1To128_sub0 = 0x08, + .x6030_polarityDigitalInputBit1To128 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6038_filterConstantDigitalInputBit1To128_sub0 = 0x08, + .x6038_filterConstantDigitalInputBit1To128 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6050_interruptMaskDigitalInputAnyChange1To128_sub0 = 0x08, + .x6050_interruptMaskDigitalInputAnyChange1To128 = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .x6060_interruptMaskDigitalInputLowToHigh1To128_sub0 = 0x08, + .x6060_interruptMaskDigitalInputLowToHigh1To128 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6070_interruptMaskDigitalInputHighToLow1To128_sub0 = 0x08, + .x6070_interruptMaskDigitalInputHighToLow1To128 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6100_readDigitalInput16_bit_sub0 = 0x08, + .x6100_readDigitalInput16_bit = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + .x6102_polarityDigitalInput16_bit_sub0 = 0x08, + .x6102_polarityDigitalInput16_bit = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + .x6103_digitalFilterEnable16_bit_sub0 = 0x08, + .x6103_digitalFilterEnable16_bit = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + .x6106_interruptMaskDigitalInputAnyChange16_bit_sub0 = 0x08, + .x6106_interruptMaskDigitalInputAnyChange16_bit = {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + .x6107_interruptMaskDigitalInputLowToHigh16_bit_sub0 = 0x08, + .x6107_interruptMaskDigitalInputLowToHigh16_bit = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + .x6108_interruptMaskDigitalInputHighToLow16_bit_sub0 = 0x08, + .x6108_interruptMaskDigitalInputHighToLow16_bit = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + .x6120_readDigitalInput32_bit_sub0 = 0x08, + .x6120_readDigitalInput32_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000}, + .x6122_polarityDigitalInput32_bit_sub0 = 0x08, + .x6122_polarityDigitalInput32_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000}, + .x6123_digitalFilterEnable32_bit_sub0 = 0x08, + .x6123_digitalFilterEnable32_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000}, + .x6126_interruptMaskDigitalInputAnyChange32_bit_sub0 = 0x08, + .x6126_interruptMaskDigitalInputAnyChange32_bit = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff}, + .x6127_interruptMaskDigitalInputLowToHigh32_bit_sub0 = 0x08, + .x6127_interruptMaskDigitalInputLowToHigh32_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, + .x6128_interruptMaskDigitalInputHighToLow32_bit_sub0 = 0x08, + .x6128_interruptMaskDigitalInputHighToLow32_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, + .x6200_writeDigitalOutput8_bit_sub0 = 0x08, + .x6200_writeDigitalOutput8_bit = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6202_changePolarityDigitalOutput8_bit_sub0 = 0x08, + .x6202_changePolarityDigitalOutput8_bit = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6206_errorModeDigitalOutput8_bit_sub0 = 0x08, + .x6206_errorModeDigitalOutput8_bit = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .x6207_errorValueDigitalOutput8_bit_sub0 = 0x08, + .x6207_errorValueDigitalOutput8_bit = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6208_filterMaskDigitalOutput8_bit_sub0 = 0x08, + .x6208_filterMaskDigitalOutput8_bit = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .x6220_writeDigitalOutputBit1To128_sub0 = 0x06, + .x6220_writeDigitalOutputBit1To128 = {0x00}, + .x6240_changePolarityDigitalOutputBit1To128_sub0 = 0x08, + .x6240_changePolarityDigitalOutputBit1To128 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6250_errorModeDigitalOutputLines1To128_sub0 = 0x08, + .x6250_errorModeDigitalOutputLines1To128 = {0x0ff, 0x0ff, 0x0ff, 0x0ff, 0x0ff, 0x0ff, 0x0ff, 0x0ff}, + .x6260_errorValueDigitalOutputBit1To128_sub0 = 0x08, + .x6260_errorValueDigitalOutputBit1To128 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6270_filterMaskDigitalOutputBit1To128_sub0 = 0x08, + .x6270_filterMaskDigitalOutputBit1To128 = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + .x6300_writeDigitalOutput16_bit_sub0 = 0x08, + .x6300_writeDigitalOutput16_bit = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + .x6302_changePolarityDigitalOutput16_bit_sub0 = 0x08, + .x6302_changePolarityDigitalOutput16_bit = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + .x6306_errorModeDigitalOutput16_bit_sub0 = 0x08, + .x6306_errorModeDigitalOutput16_bit = {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + .x6307_errorValueDigitalOutput16_bit_sub0 = 0x08, + .x6307_errorValueDigitalOutput16_bit = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + .x6308_filterMaskDigitalOutput16_bit_sub0 = 0x08, + .x6308_filterMaskDigitalOutput16_bit = {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + .x6320_writeDigitalOutput32_bit_sub0 = 0x08, + .x6320_writeDigitalOutput32_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000}, + .x6322_changePolarityDigitalOutput32_bit_sub0 = 0x08, + .x6322_changePolarityDigitalOutput32_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000}, + .x6326_errorModeDigitalOutput32_bit_sub0 = 0x08, + .x6326_errorModeDigitalOutput32_bit = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff}, + .x6327_errorValueDigitalOutput32_bit_sub0 = 0x08, + .x6327_errorValueDigitalOutput32_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000}, + .x6328_filterMaskDigitalOutput32_bit_sub0 = 0x08, + .x6328_filterMaskDigitalOutput32_bit = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff}, + .x6400_readAnalogInput8_bit_sub0 = 0x08, + .x6400_readAnalogInput8_bit = {0, 0, 0, 0, 0, 0, 0, 0}, + .x6401_readAnalogInput16_bit_sub0 = 0x08, + .x6401_readAnalogInput16_bit = {0, 0, 0, 0, 0, 0, 0, 0}, + .x6402_readAnalogInput32_bit_sub0 = 0x08, + .x6402_readAnalogInput32_bit = {0, 0, 0, 0, 0, 0, 0, 0}, + .x6410_writeAnalogOutput8_bit_sub0 = 0x08, + .x6410_writeAnalogOutput8_bit = {0, 0, 0, 0, 0, 0, 0, 0}, + .x6411_writeAnalogOutput16_bit_sub0 = 0x08, + .x6411_writeAnalogOutput16_bit = {0, 0, 0, 0, 0, 0, 0, 0}, + .x6412_writeAnalogOutput32_bit_sub0 = 0x08, + .x6412_writeAnalogOutput32_bit = {0, 0, 0, 0, 0, 0, 0, 0}, + .x6421_analogInputInterruptTriggerSelection_bit_sub0 = 0x08, + .x6421_analogInputInterruptTriggerSelection_bit = {0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}, + .x6422_analogInputInterruptSource_bit_sub0 = 0x08, + .x6422_analogInputInterruptSource_bit = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + .x6423_analogInputGlobalInterruptEnable = 0x01, + .x6424_analogInputUpperLimitInteger_bit_sub0 = 0x08, + .x6424_analogInputUpperLimitInteger_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000}, + .x6425_analogInputLowerLimitInteger_bit_sub0 = 0x08, + .x6425_analogInputLowerLimitInteger_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000}, + .x6426_analogInputInterruptDeltaUnsigned_bit_sub0 = 0x08, + .x6426_analogInputInterruptDeltaUnsigned_bit = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6427_analogInputInterruptNegativeDeltaUnsigned_bit_sub0 = 0x08, + .x6427_analogInputInterruptNegativeDeltaUnsigned_bit = {0, 0, 0, 0, 0, 0, 0, 0}, + .x6428_analogInputInterruptPositiveDeltaUnsigned_bit_sub0 = 0x08, + .x6428_analogInputInterruptPositiveDeltaUnsigned_bit = {0, 0, 0, 0, 0, 0, 0, 0}, + .x6429_analogInputInterruptUpperLimitFloat_bit_sub0 = 0x08, + .x6429_analogInputInterruptUpperLimitFloat_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, + .x642A_analogInputInterruptLowerLimitFloat_bit_sub0 = 0x08, + .x642A_analogInputInterruptLowerLimitFloat_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, + .x642B_analogInputInterruptDeltaFloat_bit_sub0 = 0x08, + .x642B_analogInputInterruptDeltaFloat_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000}, + .x642C_analogInputInterruptNegativeDeltaFloat_bit_sub0 = 0x04, + .x642C_analogInputInterruptNegativeDeltaFloat_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000}, + .x642D_analogInputInterruptPositiveDeltaFloat_bit_sub0 = 0x08, + .x642D_analogInputInterruptPositiveDeltaFloat_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, + .x642E_analogInputOffsetFloat_bit_sub0 = 0x08, + .x642E_analogInputOffsetFloat_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000}, + .x642F_analogInputPreScalingFloat_bit_sub0 = 0x08, + .x642F_analogInputPreScalingFloat_bit = {0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001}, + .x6430_analogInputSIUnit_bit_sub0 = 0x08, + .x6430_analogInputSIUnit_bit = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .x6431_analogInputOffsetInteger_bit_sub0 = 0x08, + .x6431_analogInputOffsetInteger_bit = {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000}, + .x6432_analogInputPreScalingInteger_bit_sub0 = 0x08, + .x6432_analogInputPreScalingInteger_bit = {0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, + 0x00000001, 0x00000001}, + + .x67FF_deviceType = 0x00238191, +}; + +OD_ATTR_PERSIST_APP_AUTO OD_PERSIST_APP_AUTO_t OD_PERSIST_APP_AUTO = { + .x2106_power_onCounter = 0x00000000, + .x2112_variableNV_Int32AutoSave_sub0 = 0x10, + .x2112_variableNV_Int32AutoSave = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + +OD_ATTR_PERSIST_APP OD_PERSIST_APP_t OD_PERSIST_APP = { + .x2111_variableInt32Save_sub0 = 0x10, + .x2111_variableInt32Save = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + .x2120_demoRecord = {.highestSub_indexSupported = 0x06, + .I64 = -1234567890123456789, + .U64 = 0x1234567890ABCDEF, + .R32 = 12.345, + .R64 = 456.789, + .parameterWithDefaultValue = 0x1234}, + .x2121_demoStrings = { + .highestSub_indexSupported = 0x03, + .stringShort = {'s', 't', 'r', 0}, + .stringLong = + {'E', 'x', 'a', 'm', 'p', 'l', 'e', ' ', 's', 't', 'r', 'i', 'n', 'g', ' ', 'w', + 'i', 't', 'h', ' ', '1', '0', '0', '0', ' ', 'b', 'y', 't', 'e', 's', ' ', 'c', + 'a', 'p', 'a', 'c', 'i', 't', 'y', '.', ' ', 'I', 't', ' ', 'm', 'a', 'y', ' ', + 'c', 'o', 'n', 't', 'a', 'i', 'n', ' ', 'U', 'T', 'F', '-', '8', ' ', 'c', 'h', + 'a', 'r', 'a', 'c', 't', 'e', 'r', 's', ',', ' ', 'l', 'i', 'k', 'e', ' ', '\'', + (char)0xE2, (char)0x82, (char)0xAC, '\'', ',', ' ', 't', 'a', 'b', 's', ' ', '\'', 0x09, '\'', ',', ' ', + 'n', 'e', 'w', 'l', 'i', 'n', 'e', 's', ',', ' ', 'e', 't', 'c', '.', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0}, + .octetString = {0xC8, 0x3D, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}; + +/******************************************************************************* + All OD objects (constant definitions) +*******************************************************************************/ +typedef struct { + OD_obj_var_t o_1000_deviceType; + OD_obj_var_t o_1001_errorRegister; + OD_obj_array_t o_1003_pre_definedErrorField; + OD_obj_var_t o_1005_COB_ID_SYNCMessage; + OD_obj_var_t o_1006_communicationCyclePeriod; + OD_obj_var_t o_1007_synchronousWindowLength; + OD_obj_var_t o_1008_manufacturerDeviceName; + OD_obj_var_t o_1009_manufacturerHardwareVersion; + OD_obj_var_t o_100A_manufacturerSoftwareVersion; + OD_obj_array_t o_1010_storeParameters; + OD_obj_array_t o_1011_restoreDefaultParameters; + OD_obj_var_t o_1012_COB_IDTimeStampObject; + OD_obj_var_t o_1014_COB_ID_EMCY; + OD_obj_var_t o_1015_inhibitTimeEMCY; + OD_obj_array_t o_1016_consumerHeartbeatTime; + OD_obj_var_t o_1017_producerHeartbeatTime; + OD_obj_record_t o_1018_identity[5]; + OD_obj_var_t o_1019_synchronousCounterOverflowValue; + OD_obj_record_t o_1200_SDOServerParameter[3]; + OD_obj_record_t o_1400_RPDOCommunicationParameter[4]; + OD_obj_record_t o_1401_RPDOCommunicationParameter[4]; + OD_obj_record_t o_1402_RPDOCommunicationParameter[4]; + OD_obj_record_t o_1403_RPDOCommunicationParameter[4]; + OD_obj_record_t o_1600_RPDOMappingParameter[9]; + OD_obj_record_t o_1601_RPDOMappingParameter[9]; + OD_obj_record_t o_1602_RPDOMappingParameter[9]; + OD_obj_record_t o_1603_RPDOMappingParameter[9]; + OD_obj_record_t o_1800_TPDOCommunicationParameter[6]; + OD_obj_record_t o_1801_TPDOCommunicationParameter[6]; + OD_obj_record_t o_1802_TPDOCommunicationParameter[6]; + OD_obj_record_t o_1803_TPDOCommunicationParameter[6]; + OD_obj_record_t o_1A00_TPDOMappingParameter[9]; + OD_obj_record_t o_1A01_TPDOMappingParameter[9]; + OD_obj_record_t o_1A02_TPDOMappingParameter[9]; + OD_obj_record_t o_1A03_TPDOMappingParameter[9]; + OD_obj_var_t o_2100_errorStatusBits; + OD_obj_var_t o_2106_power_onCounter; + OD_obj_array_t o_2110_variableInt32; + OD_obj_array_t o_2111_variableInt32Save; + OD_obj_array_t o_2112_variableNV_Int32AutoSave; + OD_obj_record_t o_2120_demoRecord[7]; + OD_obj_record_t o_2121_demoStrings[4]; + OD_obj_var_t o_2122_demoDomain; + OD_obj_array_t o_6000_readDigitalInput8_bit; + OD_obj_array_t o_6002_polarityDigitalInput8_bit; + OD_obj_array_t o_6003_digitalFilterEnable8_bit; + OD_obj_var_t o_6005_globalInterruptEnableDigital8_bit; + OD_obj_array_t o_6006_digitalInterruptMaskAnyChange8_bit; + OD_obj_array_t o_6007_digitalInterruptMaskLowToHigh8_bit; + OD_obj_array_t o_6008_digitalInterruptMaskHighToLow8_bit; + OD_obj_array_t o_6020_readDigitalInputBit1To128; + OD_obj_array_t o_6030_polarityDigitalInputBit1To128; + OD_obj_array_t o_6038_filterConstantDigitalInputBit1To128; + OD_obj_array_t o_6050_interruptMaskDigitalInputAnyChange1To128; + OD_obj_array_t o_6060_interruptMaskDigitalInputLowToHigh1To128; + OD_obj_array_t o_6070_interruptMaskDigitalInputHighToLow1To128; + OD_obj_array_t o_6100_readDigitalInput16_bit; + OD_obj_array_t o_6102_polarityDigitalInput16_bit; + OD_obj_array_t o_6103_digitalFilterEnable16_bit; + OD_obj_array_t o_6106_interruptMaskDigitalInputAnyChange16_bit; + OD_obj_array_t o_6107_interruptMaskDigitalInputLowToHigh16_bit; + OD_obj_array_t o_6108_interruptMaskDigitalInputHighToLow16_bit; + OD_obj_array_t o_6120_readDigitalInput32_bit; + OD_obj_array_t o_6122_polarityDigitalInput32_bit; + OD_obj_array_t o_6123_digitalFilterEnable32_bit; + OD_obj_array_t o_6126_interruptMaskDigitalInputAnyChange32_bit; + OD_obj_array_t o_6127_interruptMaskDigitalInputLowToHigh32_bit; + OD_obj_array_t o_6128_interruptMaskDigitalInputHighToLow32_bit; + OD_obj_array_t o_6200_writeDigitalOutput8_bit; + OD_obj_array_t o_6202_changePolarityDigitalOutput8_bit; + OD_obj_array_t o_6206_errorModeDigitalOutput8_bit; + OD_obj_array_t o_6207_errorValueDigitalOutput8_bit; + OD_obj_array_t o_6208_filterMaskDigitalOutput8_bit; + OD_obj_array_t o_6220_writeDigitalOutputBit1To128; + OD_obj_array_t o_6240_changePolarityDigitalOutputBit1To128; + OD_obj_array_t o_6250_errorModeDigitalOutputLines1To128; + OD_obj_array_t o_6260_errorValueDigitalOutputBit1To128; + OD_obj_array_t o_6270_filterMaskDigitalOutputBit1To128; + OD_obj_array_t o_6300_writeDigitalOutput16_bit; + OD_obj_array_t o_6302_changePolarityDigitalOutput16_bit; + OD_obj_array_t o_6306_errorModeDigitalOutput16_bit; + OD_obj_array_t o_6307_errorValueDigitalOutput16_bit; + OD_obj_array_t o_6308_filterMaskDigitalOutput16_bit; + OD_obj_array_t o_6320_writeDigitalOutput32_bit; + OD_obj_array_t o_6322_changePolarityDigitalOutput32_bit; + OD_obj_array_t o_6326_errorModeDigitalOutput32_bit; + OD_obj_array_t o_6327_errorValueDigitalOutput32_bit; + OD_obj_array_t o_6328_filterMaskDigitalOutput32_bit; + OD_obj_array_t o_6400_readAnalogInput8_bit; + OD_obj_array_t o_6401_readAnalogInput16_bit; + OD_obj_array_t o_6402_readAnalogInput32_bit; + OD_obj_array_t o_6410_writeAnalogOutput8_bit; + OD_obj_array_t o_6411_writeAnalogOutput16_bit; + OD_obj_array_t o_6412_writeAnalogOutput32_bit; + OD_obj_array_t o_6421_analogInputInterruptTriggerSelection_bit; + OD_obj_array_t o_6422_analogInputInterruptSource_bit; + OD_obj_var_t o_6423_analogInputGlobalInterruptEnable; + OD_obj_array_t o_6424_analogInputUpperLimitInteger_bit; + OD_obj_array_t o_6425_analogInputLowerLimitInteger_bit; + OD_obj_array_t o_6426_analogInputInterruptDeltaUnsigned_bit; + OD_obj_array_t o_6427_analogInputInterruptNegativeDeltaUnsigned_bit; + OD_obj_array_t o_6428_analogInputInterruptPositiveDeltaUnsigned_bit; + OD_obj_array_t o_6429_analogInputInterruptUpperLimitFloat_bit; + OD_obj_array_t o_642A_analogInputInterruptLowerLimitFloat_bit; + OD_obj_array_t o_642B_analogInputInterruptDeltaFloat_bit; + OD_obj_array_t o_642C_analogInputInterruptNegativeDeltaFloat_bit; + OD_obj_array_t o_642D_analogInputInterruptPositiveDeltaFloat_bit; + OD_obj_array_t o_642E_analogInputOffsetFloat_bit; + OD_obj_array_t o_642F_analogInputPreScalingFloat_bit; + OD_obj_array_t o_6430_analogInputSIUnit_bit; + OD_obj_array_t o_6431_analogInputOffsetInteger_bit; + OD_obj_array_t o_6432_analogInputPreScalingInteger_bit; + OD_obj_var_t o_67ff_deviceType; + +} ODObjs_t; + +static CO_PROGMEM ODObjs_t ODObjs = { + .o_1000_deviceType = {.dataOrig = &OD_PERSIST_COMM.x1000_deviceType, + .attribute = ODA_SDO_R | ODA_MB, + .dataLength = 4}, + .o_1001_errorRegister = {.dataOrig = &OD_RAM.x1001_errorRegister, + .attribute = ODA_SDO_R | ODA_TPDO, + .dataLength = 1}, + .o_1003_pre_definedErrorField = {.dataOrig0 = NULL, + .dataOrig = NULL, + .attribute0 = ODA_SDO_RW, + .attribute = ODA_SDO_R | ODA_MB, + .dataElementLength = 4, + .dataElementSizeof = sizeof(uint32_t)}, + .o_1005_COB_ID_SYNCMessage = {.dataOrig = &OD_PERSIST_COMM.x1005_COB_ID_SYNCMessage, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + .o_1006_communicationCyclePeriod = {.dataOrig = &OD_PERSIST_COMM.x1006_communicationCyclePeriod, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + .o_1007_synchronousWindowLength = {.dataOrig = &OD_PERSIST_COMM.x1007_synchronousWindowLength, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + .o_1008_manufacturerDeviceName = {.dataOrig = NULL, .attribute = ODA_SDO_R | ODA_STR, .dataLength = 0}, + .o_1009_manufacturerHardwareVersion = {.dataOrig = NULL, .attribute = ODA_SDO_R | ODA_STR, .dataLength = 0}, + .o_100A_manufacturerSoftwareVersion = {.dataOrig = NULL, .attribute = ODA_SDO_R | ODA_STR, .dataLength = 0}, + .o_1010_storeParameters = {.dataOrig0 = &OD_RAM.x1010_storeParameters_sub0, + .dataOrig = &OD_RAM.x1010_storeParameters[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 4, + .dataElementSizeof = sizeof(uint32_t)}, + .o_1011_restoreDefaultParameters = {.dataOrig0 = &OD_RAM.x1011_restoreDefaultParameters_sub0, + .dataOrig = &OD_RAM.x1011_restoreDefaultParameters[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 4, + .dataElementSizeof = sizeof(uint32_t)}, + .o_1012_COB_IDTimeStampObject = {.dataOrig = &OD_PERSIST_COMM.x1012_COB_IDTimeStampObject, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + .o_1014_COB_ID_EMCY = {.dataOrig = &OD_PERSIST_COMM.x1014_COB_ID_EMCY, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + .o_1015_inhibitTimeEMCY = {.dataOrig = &OD_PERSIST_COMM.x1015_inhibitTimeEMCY, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 2}, + .o_1016_consumerHeartbeatTime = {.dataOrig0 = &OD_PERSIST_COMM.x1016_consumerHeartbeatTime_sub0, + .dataOrig = &OD_PERSIST_COMM.x1016_consumerHeartbeatTime[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 4, + .dataElementSizeof = sizeof(uint32_t)}, + .o_1017_producerHeartbeatTime = {.dataOrig = &OD_PERSIST_COMM.x1017_producerHeartbeatTime, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 2}, + .o_1018_identity = {{.dataOrig = &OD_PERSIST_COMM.x1018_identity.highestSub_indexSupported, + .subIndex = 0, + .attribute = ODA_SDO_R, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1018_identity.vendor_ID, + .subIndex = 1, + .attribute = ODA_SDO_R | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1018_identity.productCode, + .subIndex = 2, + .attribute = ODA_SDO_R | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1018_identity.revisionNumber, + .subIndex = 3, + .attribute = ODA_SDO_R | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1018_identity.serialNumber, + .subIndex = 4, + .attribute = ODA_SDO_R | ODA_MB, + .dataLength = 4}}, + .o_1019_synchronousCounterOverflowValue = {.dataOrig = &OD_PERSIST_COMM.x1019_synchronousCounterOverflowValue, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + .o_1200_SDOServerParameter = {{.dataOrig = &OD_RAM.x1200_SDOServerParameter.highestSub_indexSupported, + .subIndex = 0, + .attribute = ODA_SDO_R, + .dataLength = 1}, + {.dataOrig = &OD_RAM.x1200_SDOServerParameter.COB_IDClientToServerRx, + .subIndex = 1, + .attribute = ODA_SDO_R | ODA_TPDO | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_RAM.x1200_SDOServerParameter.COB_IDServerToClientTx, + .subIndex = 2, + .attribute = ODA_SDO_R | ODA_TPDO | ODA_MB, + .dataLength = 4}}, + .o_1400_RPDOCommunicationParameter = + {{.dataOrig = &OD_PERSIST_COMM.x1400_RPDOCommunicationParameter.highestSub_indexSupported, + .subIndex = 0, + .attribute = ODA_SDO_R, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1400_RPDOCommunicationParameter.COB_IDUsedByRPDO, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1400_RPDOCommunicationParameter.transmissionType, + .subIndex = 2, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1400_RPDOCommunicationParameter.eventTimer, + .subIndex = 5, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 2}}, + .o_1401_RPDOCommunicationParameter = + {{.dataOrig = &OD_PERSIST_COMM.x1401_RPDOCommunicationParameter.highestSub_indexSupported, + .subIndex = 0, + .attribute = ODA_SDO_R, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1401_RPDOCommunicationParameter.COB_IDUsedByRPDO, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1401_RPDOCommunicationParameter.transmissionType, + .subIndex = 2, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1401_RPDOCommunicationParameter.eventTimer, + .subIndex = 5, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 2}}, + .o_1402_RPDOCommunicationParameter = + {{.dataOrig = &OD_PERSIST_COMM.x1402_RPDOCommunicationParameter.highestSub_indexSupported, + .subIndex = 0, + .attribute = ODA_SDO_R, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1402_RPDOCommunicationParameter.COB_IDUsedByRPDO, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1402_RPDOCommunicationParameter.transmissionType, + .subIndex = 2, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1402_RPDOCommunicationParameter.eventTimer, + .subIndex = 5, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 2}}, + .o_1403_RPDOCommunicationParameter = + {{.dataOrig = &OD_PERSIST_COMM.x1403_RPDOCommunicationParameter.highestSub_indexSupported, + .subIndex = 0, + .attribute = ODA_SDO_R, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1403_RPDOCommunicationParameter.COB_IDUsedByRPDO, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1403_RPDOCommunicationParameter.transmissionType, + .subIndex = 2, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1403_RPDOCommunicationParameter.eventTimer, + .subIndex = 5, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 2}}, + .o_1600_RPDOMappingParameter = + {{.dataOrig = &OD_PERSIST_COMM.x1600_RPDOMappingParameter.numberOfMappedApplicationObjectsInPDO, + .subIndex = 0, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1600_RPDOMappingParameter.applicationObject1, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1600_RPDOMappingParameter.applicationObject2, + .subIndex = 2, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1600_RPDOMappingParameter.applicationObject3, + .subIndex = 3, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1600_RPDOMappingParameter.applicationObject4, + .subIndex = 4, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1600_RPDOMappingParameter.applicationObject5, + .subIndex = 5, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1600_RPDOMappingParameter.applicationObject6, + .subIndex = 6, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1600_RPDOMappingParameter.applicationObject7, + .subIndex = 7, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1600_RPDOMappingParameter.applicationObject8, + .subIndex = 8, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}}, + .o_1601_RPDOMappingParameter = + {{.dataOrig = &OD_PERSIST_COMM.x1601_RPDOMappingParameter.numberOfMappedApplicationObjectsInPDO, + .subIndex = 0, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1601_RPDOMappingParameter.applicationObject1, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1601_RPDOMappingParameter.applicationObject2, + .subIndex = 2, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1601_RPDOMappingParameter.applicationObject3, + .subIndex = 3, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1601_RPDOMappingParameter.applicationObject4, + .subIndex = 4, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1601_RPDOMappingParameter.applicationObject5, + .subIndex = 5, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1601_RPDOMappingParameter.applicationObject6, + .subIndex = 6, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1601_RPDOMappingParameter.applicationObject7, + .subIndex = 7, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1601_RPDOMappingParameter.applicationObject8, + .subIndex = 8, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}}, + .o_1602_RPDOMappingParameter = + {{.dataOrig = &OD_PERSIST_COMM.x1602_RPDOMappingParameter.numberOfMappedApplicationObjectsInPDO, + .subIndex = 0, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1602_RPDOMappingParameter.applicationObject1, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1602_RPDOMappingParameter.applicationObject2, + .subIndex = 2, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1602_RPDOMappingParameter.applicationObject3, + .subIndex = 3, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1602_RPDOMappingParameter.applicationObject4, + .subIndex = 4, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1602_RPDOMappingParameter.applicationObject5, + .subIndex = 5, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1602_RPDOMappingParameter.applicationObject6, + .subIndex = 6, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1602_RPDOMappingParameter.applicationObject7, + .subIndex = 7, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1602_RPDOMappingParameter.applicationObject8, + .subIndex = 8, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}}, + .o_1603_RPDOMappingParameter = + {{.dataOrig = &OD_PERSIST_COMM.x1603_RPDOMappingParameter.numberOfMappedApplicationObjectsInPDO, + .subIndex = 0, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1603_RPDOMappingParameter.applicationObject1, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1603_RPDOMappingParameter.applicationObject2, + .subIndex = 2, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1603_RPDOMappingParameter.applicationObject3, + .subIndex = 3, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1603_RPDOMappingParameter.applicationObject4, + .subIndex = 4, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1603_RPDOMappingParameter.applicationObject5, + .subIndex = 5, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1603_RPDOMappingParameter.applicationObject6, + .subIndex = 6, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1603_RPDOMappingParameter.applicationObject7, + .subIndex = 7, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1603_RPDOMappingParameter.applicationObject8, + .subIndex = 8, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}}, + .o_1800_TPDOCommunicationParameter = + {{.dataOrig = &OD_PERSIST_COMM.x1800_TPDOCommunicationParameter.highestSub_indexSupported, + .subIndex = 0, + .attribute = ODA_SDO_R, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1800_TPDOCommunicationParameter.COB_IDUsedByTPDO, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1800_TPDOCommunicationParameter.transmissionType, + .subIndex = 2, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1800_TPDOCommunicationParameter.inhibitTime, + .subIndex = 3, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 2}, + {.dataOrig = &OD_PERSIST_COMM.x1800_TPDOCommunicationParameter.eventTimer, + .subIndex = 5, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 2}, + {.dataOrig = &OD_PERSIST_COMM.x1800_TPDOCommunicationParameter.SYNCStartValue, + .subIndex = 6, + .attribute = ODA_SDO_RW, + .dataLength = 1}}, + .o_1801_TPDOCommunicationParameter = + {{.dataOrig = &OD_PERSIST_COMM.x1801_TPDOCommunicationParameter.highestSub_indexSupported, + .subIndex = 0, + .attribute = ODA_SDO_R, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1801_TPDOCommunicationParameter.COB_IDUsedByTPDO, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1801_TPDOCommunicationParameter.transmissionType, + .subIndex = 2, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1801_TPDOCommunicationParameter.inhibitTime, + .subIndex = 3, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 2}, + {.dataOrig = &OD_PERSIST_COMM.x1801_TPDOCommunicationParameter.eventTimer, + .subIndex = 5, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 2}, + {.dataOrig = &OD_PERSIST_COMM.x1801_TPDOCommunicationParameter.SYNCStartValue, + .subIndex = 6, + .attribute = ODA_SDO_RW, + .dataLength = 1}}, + .o_1802_TPDOCommunicationParameter = + {{.dataOrig = &OD_PERSIST_COMM.x1802_TPDOCommunicationParameter.highestSub_indexSupported, + .subIndex = 0, + .attribute = ODA_SDO_R, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1802_TPDOCommunicationParameter.COB_IDUsedByTPDO, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1802_TPDOCommunicationParameter.transmissionType, + .subIndex = 2, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1802_TPDOCommunicationParameter.inhibitTime, + .subIndex = 3, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 2}, + {.dataOrig = &OD_PERSIST_COMM.x1802_TPDOCommunicationParameter.eventTimer, + .subIndex = 5, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 2}, + {.dataOrig = &OD_PERSIST_COMM.x1802_TPDOCommunicationParameter.SYNCStartValue, + .subIndex = 6, + .attribute = ODA_SDO_RW, + .dataLength = 1}}, + .o_1803_TPDOCommunicationParameter = + {{.dataOrig = &OD_PERSIST_COMM.x1803_TPDOCommunicationParameter.highestSub_indexSupported, + .subIndex = 0, + .attribute = ODA_SDO_R, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1803_TPDOCommunicationParameter.COB_IDUsedByTPDO, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1803_TPDOCommunicationParameter.transmissionType, + .subIndex = 2, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1803_TPDOCommunicationParameter.inhibitTime, + .subIndex = 3, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 2}, + {.dataOrig = &OD_PERSIST_COMM.x1803_TPDOCommunicationParameter.eventTimer, + .subIndex = 5, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 2}, + {.dataOrig = &OD_PERSIST_COMM.x1803_TPDOCommunicationParameter.SYNCStartValue, + .subIndex = 6, + .attribute = ODA_SDO_RW, + .dataLength = 1}}, + .o_1A00_TPDOMappingParameter = + {{.dataOrig = &OD_PERSIST_COMM.x1A00_TPDOMappingParameter.numberOfMappedApplicationObjectsInPDO, + .subIndex = 0, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1A00_TPDOMappingParameter.applicationObject1, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A00_TPDOMappingParameter.applicationObject2, + .subIndex = 2, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A00_TPDOMappingParameter.applicationObject3, + .subIndex = 3, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A00_TPDOMappingParameter.applicationObject4, + .subIndex = 4, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A00_TPDOMappingParameter.applicationObject5, + .subIndex = 5, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A00_TPDOMappingParameter.applicationObject6, + .subIndex = 6, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A00_TPDOMappingParameter.applicationObject7, + .subIndex = 7, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A00_TPDOMappingParameter.applicationObject8, + .subIndex = 8, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}}, + .o_1A01_TPDOMappingParameter = + {{.dataOrig = &OD_PERSIST_COMM.x1A01_TPDOMappingParameter.numberOfMappedApplicationObjectsInPDO, + .subIndex = 0, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1A01_TPDOMappingParameter.applicationObject1, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A01_TPDOMappingParameter.applicationObject2, + .subIndex = 2, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A01_TPDOMappingParameter.applicationObject3, + .subIndex = 3, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A01_TPDOMappingParameter.applicationObject4, + .subIndex = 4, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A01_TPDOMappingParameter.applicationObject5, + .subIndex = 5, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A01_TPDOMappingParameter.applicationObject6, + .subIndex = 6, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A01_TPDOMappingParameter.applicationObject7, + .subIndex = 7, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A01_TPDOMappingParameter.applicationObject8, + .subIndex = 8, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}}, + .o_1A02_TPDOMappingParameter = + {{.dataOrig = &OD_PERSIST_COMM.x1A02_TPDOMappingParameter.numberOfMappedApplicationObjectsInPDO, + .subIndex = 0, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1A02_TPDOMappingParameter.applicationObject1, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A02_TPDOMappingParameter.applicationObject2, + .subIndex = 2, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A02_TPDOMappingParameter.applicationObject3, + .subIndex = 3, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A02_TPDOMappingParameter.applicationObject4, + .subIndex = 4, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A02_TPDOMappingParameter.applicationObject5, + .subIndex = 5, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A02_TPDOMappingParameter.applicationObject6, + .subIndex = 6, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A02_TPDOMappingParameter.applicationObject7, + .subIndex = 7, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A02_TPDOMappingParameter.applicationObject8, + .subIndex = 8, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}}, + .o_1A03_TPDOMappingParameter = + {{.dataOrig = &OD_PERSIST_COMM.x1A03_TPDOMappingParameter.numberOfMappedApplicationObjectsInPDO, + .subIndex = 0, + .attribute = ODA_SDO_RW, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_COMM.x1A03_TPDOMappingParameter.applicationObject1, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A03_TPDOMappingParameter.applicationObject2, + .subIndex = 2, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A03_TPDOMappingParameter.applicationObject3, + .subIndex = 3, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A03_TPDOMappingParameter.applicationObject4, + .subIndex = 4, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A03_TPDOMappingParameter.applicationObject5, + .subIndex = 5, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A03_TPDOMappingParameter.applicationObject6, + .subIndex = 6, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A03_TPDOMappingParameter.applicationObject7, + .subIndex = 7, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_COMM.x1A03_TPDOMappingParameter.applicationObject8, + .subIndex = 8, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 4}}, + .o_2100_errorStatusBits = {.dataOrig = &OD_RAM.x2100_errorStatusBits[0], + .attribute = ODA_SDO_R | ODA_TPDO, + .dataLength = 10}, + .o_2106_power_onCounter = {.dataOrig = &OD_PERSIST_APP_AUTO.x2106_power_onCounter, + .attribute = ODA_SDO_R | ODA_MB, + .dataLength = 4}, + .o_2110_variableInt32 = {.dataOrig0 = &OD_RAM.x2110_variableInt32_sub0, + .dataOrig = &OD_RAM.x2110_variableInt32[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_TRPDO | ODA_MB, + .dataElementLength = 4, + .dataElementSizeof = sizeof(int32_t)}, + .o_2111_variableInt32Save = {.dataOrig0 = &OD_PERSIST_APP.x2111_variableInt32Save_sub0, + .dataOrig = &OD_PERSIST_APP.x2111_variableInt32Save[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 4, + .dataElementSizeof = sizeof(int32_t)}, + .o_2112_variableNV_Int32AutoSave = {.dataOrig0 = &OD_PERSIST_APP_AUTO.x2112_variableNV_Int32AutoSave_sub0, + .dataOrig = &OD_PERSIST_APP_AUTO.x2112_variableNV_Int32AutoSave[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 4, + .dataElementSizeof = sizeof(int32_t)}, + .o_2120_demoRecord = + {{.dataOrig = &OD_PERSIST_APP.x2120_demoRecord.highestSub_indexSupported, + .subIndex = 0, + .attribute = ODA_SDO_R, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_APP.x2120_demoRecord.I64, + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_TRPDO | ODA_MB, + .dataLength = 8}, + {.dataOrig = &OD_PERSIST_APP.x2120_demoRecord.U64, + .subIndex = 2, + .attribute = ODA_SDO_RW | ODA_TRPDO | ODA_MB, + .dataLength = 8}, + {.dataOrig = &OD_PERSIST_APP.x2120_demoRecord.R32, + .subIndex = 3, + .attribute = ODA_SDO_RW | ODA_TRPDO | ODA_MB, + .dataLength = 4}, + {.dataOrig = &OD_PERSIST_APP.x2120_demoRecord.R64, + .subIndex = 4, + .attribute = ODA_SDO_RW | ODA_TRPDO | ODA_MB, + .dataLength = 8}, + {.dataOrig = NULL, .subIndex = 5, .attribute = ODA_SDO_R | ODA_TPDO | ODA_MB, .dataLength = 8}, + {.dataOrig = &OD_PERSIST_APP.x2120_demoRecord.parameterWithDefaultValue, + .subIndex = 6, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 2}}, + .o_2121_demoStrings = {{.dataOrig = &OD_PERSIST_APP.x2121_demoStrings.highestSub_indexSupported, + .subIndex = 0, + .attribute = ODA_SDO_R, + .dataLength = 1}, + {.dataOrig = &OD_PERSIST_APP.x2121_demoStrings.stringShort[0], + .subIndex = 1, + .attribute = ODA_SDO_RW | ODA_STR, + .dataLength = 3}, + {.dataOrig = &OD_PERSIST_APP.x2121_demoStrings.stringLong[0], + .subIndex = 2, + .attribute = ODA_SDO_RW | ODA_STR, + .dataLength = 1000}, + {.dataOrig = &OD_PERSIST_APP.x2121_demoStrings.octetString[0], + .subIndex = 3, + .attribute = ODA_SDO_RW, + .dataLength = 10}}, + .o_2122_demoDomain = {.dataOrig = NULL, .attribute = ODA_SDO_RW, .dataLength = 0}, + .o_6000_readDigitalInput8_bit = {.dataOrig0 = &OD_RAM.x6000_readDigitalInput8_bit_sub0, + .dataOrig = &OD_RAM.x6000_readDigitalInput8_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_R | ODA_TPDO, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6002_polarityDigitalInput8_bit = {.dataOrig0 = &OD_RAM.x6002_polarityDigitalInput8_bit_sub0, + .dataOrig = &OD_RAM.x6002_polarityDigitalInput8_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6003_digitalFilterEnable8_bit = {.dataOrig0 = &OD_RAM.x6003_digitalFilterEnable8_bit_sub0, + .dataOrig = &OD_RAM.x6003_digitalFilterEnable8_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6005_globalInterruptEnableDigital8_bit = {.dataOrig = &OD_RAM.x6005_globalInterruptEnableDigital8_bit, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 1}, + .o_6006_digitalInterruptMaskAnyChange8_bit = {.dataOrig0 = &OD_RAM.x6006_digitalInterruptMaskAnyChange8_bit_sub0, + .dataOrig = &OD_RAM.x6006_digitalInterruptMaskAnyChange8_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6007_digitalInterruptMaskLowToHigh8_bit = {.dataOrig0 = &OD_RAM.x6007_digitalInterruptMaskLowToHigh8_bit_sub0, + .dataOrig = &OD_RAM.x6007_digitalInterruptMaskLowToHigh8_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6008_digitalInterruptMaskHighToLow8_bit = {.dataOrig0 = &OD_RAM.x6008_digitalInterruptMaskHighToLow8_bit_sub0, + .dataOrig = &OD_RAM.x6008_digitalInterruptMaskHighToLow8_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6020_readDigitalInputBit1To128 = {.dataOrig0 = &OD_RAM.x6020_readDigitalInputBit1To128_sub0, + .dataOrig = &OD_RAM.x6020_readDigitalInputBit1To128[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_R | ODA_TPDO, + .dataElementLength = 16, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6030_polarityDigitalInputBit1To128 = {.dataOrig0 = &OD_RAM.x6030_polarityDigitalInputBit1To128_sub0, + .dataOrig = &OD_RAM.x6030_polarityDigitalInputBit1To128[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 16, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6038_filterConstantDigitalInputBit1To128 = {.dataOrig0 = &OD_RAM.x6038_filterConstantDigitalInputBit1To128_sub0, + .dataOrig = &OD_RAM.x6038_filterConstantDigitalInputBit1To128[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 16, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6050_interruptMaskDigitalInputAnyChange1To128 = {.dataOrig0 = + &OD_RAM.x6050_interruptMaskDigitalInputAnyChange1To128_sub0, + .dataOrig = + &OD_RAM.x6050_interruptMaskDigitalInputAnyChange1To128[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 16, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6060_interruptMaskDigitalInputLowToHigh1To128 = {.dataOrig0 = + &OD_RAM.x6060_interruptMaskDigitalInputLowToHigh1To128_sub0, + .dataOrig = + &OD_RAM.x6060_interruptMaskDigitalInputLowToHigh1To128[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 16, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6070_interruptMaskDigitalInputHighToLow1To128 = {.dataOrig0 = + &OD_RAM.x6070_interruptMaskDigitalInputHighToLow1To128_sub0, + .dataOrig = + &OD_RAM.x6070_interruptMaskDigitalInputHighToLow1To128[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 16, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6100_readDigitalInput16_bit = {.dataOrig0 = &OD_RAM.x6100_readDigitalInput16_bit_sub0, + .dataOrig = &OD_RAM.x6100_readDigitalInput16_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_R | ODA_TPDO, + .dataElementLength = 16, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6102_polarityDigitalInput16_bit = {.dataOrig0 = &OD_RAM.x6102_polarityDigitalInput16_bit_sub0, + .dataOrig = &OD_RAM.x6102_polarityDigitalInput16_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 16, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6103_digitalFilterEnable16_bit = {.dataOrig0 = &OD_RAM.x6103_digitalFilterEnable16_bit_sub0, + .dataOrig = &OD_RAM.x6103_digitalFilterEnable16_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 16, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6106_interruptMaskDigitalInputAnyChange16_bit = {.dataOrig0 = + &OD_RAM.x6106_interruptMaskDigitalInputAnyChange16_bit_sub0, + .dataOrig = + &OD_RAM.x6106_interruptMaskDigitalInputAnyChange16_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 16, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6107_interruptMaskDigitalInputLowToHigh16_bit = {.dataOrig0 = + &OD_RAM.x6107_interruptMaskDigitalInputLowToHigh16_bit_sub0, + .dataOrig = + &OD_RAM.x6107_interruptMaskDigitalInputLowToHigh16_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 16, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6108_interruptMaskDigitalInputHighToLow16_bit = {.dataOrig0 = + &OD_RAM.x6108_interruptMaskDigitalInputHighToLow16_bit_sub0, + .dataOrig = + &OD_RAM.x6108_interruptMaskDigitalInputHighToLow16_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 16, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6120_readDigitalInput32_bit = {.dataOrig0 = &OD_RAM.x6120_readDigitalInput32_bit_sub0, + .dataOrig = &OD_RAM.x6120_readDigitalInput32_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_R | ODA_TPDO, + .dataElementLength = 32, + .dataElementSizeof = sizeof(uint32_t)}, + .o_6122_polarityDigitalInput32_bit = {.dataOrig0 = &OD_RAM.x6122_polarityDigitalInput32_bit_sub0, + .dataOrig = &OD_RAM.x6122_polarityDigitalInput32_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(uint32_t)}, + .o_6123_digitalFilterEnable32_bit = {.dataOrig0 = &OD_RAM.x6123_digitalFilterEnable32_bit_sub0, + .dataOrig = &OD_RAM.x6123_digitalFilterEnable32_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(uint32_t)}, + .o_6126_interruptMaskDigitalInputAnyChange32_bit = {.dataOrig0 = + &OD_RAM.x6126_interruptMaskDigitalInputAnyChange32_bit_sub0, + .dataOrig = + &OD_RAM.x6126_interruptMaskDigitalInputAnyChange32_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(uint32_t)}, + .o_6127_interruptMaskDigitalInputLowToHigh32_bit = {.dataOrig0 = + &OD_RAM.x6127_interruptMaskDigitalInputLowToHigh32_bit_sub0, + .dataOrig = + &OD_RAM.x6127_interruptMaskDigitalInputLowToHigh32_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(uint32_t)}, + .o_6128_interruptMaskDigitalInputHighToLow32_bit = {.dataOrig0 = + &OD_RAM.x6128_interruptMaskDigitalInputHighToLow32_bit_sub0, + .dataOrig = + &OD_RAM.x6128_interruptMaskDigitalInputHighToLow32_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(uint32_t)}, + .o_6200_writeDigitalOutput8_bit = {.dataOrig0 = &OD_RAM.x6200_writeDigitalOutput8_bit_sub0, + .dataOrig = &OD_RAM.x6200_writeDigitalOutput8_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_TRPDO, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6202_changePolarityDigitalOutput8_bit = {.dataOrig0 = &OD_RAM.x6202_changePolarityDigitalOutput8_bit_sub0, + .dataOrig = &OD_RAM.x6202_changePolarityDigitalOutput8_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6206_errorModeDigitalOutput8_bit = {.dataOrig0 = &OD_RAM.x6206_errorModeDigitalOutput8_bit_sub0, + .dataOrig = &OD_RAM.x6206_errorModeDigitalOutput8_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6207_errorValueDigitalOutput8_bit = {.dataOrig0 = &OD_RAM.x6207_errorValueDigitalOutput8_bit_sub0, + .dataOrig = &OD_RAM.x6207_errorValueDigitalOutput8_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6208_filterMaskDigitalOutput8_bit = {.dataOrig0 = &OD_RAM.x6208_filterMaskDigitalOutput8_bit_sub0, + .dataOrig = &OD_RAM.x6208_filterMaskDigitalOutput8_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6220_writeDigitalOutputBit1To128 = {.dataOrig0 = &OD_RAM.x6220_writeDigitalOutputBit1To128_sub0, + .dataOrig = &OD_RAM.x6220_writeDigitalOutputBit1To128[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_TRPDO, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6240_changePolarityDigitalOutputBit1To128 = {.dataOrig0 = + &OD_RAM.x6240_changePolarityDigitalOutputBit1To128_sub0, + .dataOrig = &OD_RAM.x6240_changePolarityDigitalOutputBit1To128[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6250_errorModeDigitalOutputLines1To128 = {.dataOrig0 = &OD_RAM.x6250_errorModeDigitalOutputLines1To128_sub0, + .dataOrig = &OD_RAM.x6250_errorModeDigitalOutputLines1To128[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6260_errorValueDigitalOutputBit1To128 = {.dataOrig0 = &OD_RAM.x6260_errorValueDigitalOutputBit1To128_sub0, + .dataOrig = &OD_RAM.x6260_errorValueDigitalOutputBit1To128[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6270_filterMaskDigitalOutputBit1To128 = {.dataOrig0 = &OD_RAM.x6270_filterMaskDigitalOutputBit1To128_sub0, + .dataOrig = &OD_RAM.x6270_filterMaskDigitalOutputBit1To128[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6300_writeDigitalOutput16_bit = {.dataOrig0 = &OD_RAM.x6300_writeDigitalOutput16_bit_sub0, + .dataOrig = &OD_RAM.x6300_writeDigitalOutput16_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_TRPDO, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6302_changePolarityDigitalOutput16_bit = {.dataOrig0 = &OD_RAM.x6302_changePolarityDigitalOutput16_bit_sub0, + .dataOrig = &OD_RAM.x6302_changePolarityDigitalOutput16_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6306_errorModeDigitalOutput16_bit = {.dataOrig0 = &OD_RAM.x6306_errorModeDigitalOutput16_bit_sub0, + .dataOrig = &OD_RAM.x6306_errorModeDigitalOutput16_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6307_errorValueDigitalOutput16_bit = {.dataOrig0 = &OD_RAM.x6307_errorValueDigitalOutput16_bit_sub0, + .dataOrig = &OD_RAM.x6307_errorValueDigitalOutput16_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6308_filterMaskDigitalOutput16_bit = {.dataOrig0 = &OD_RAM.x6308_filterMaskDigitalOutput16_bit_sub0, + .dataOrig = &OD_RAM.x6308_filterMaskDigitalOutput16_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint16_t)}, + .o_6320_writeDigitalOutput32_bit = {.dataOrig0 = &OD_RAM.x6320_writeDigitalOutput32_bit_sub0, + .dataOrig = &OD_RAM.x6320_writeDigitalOutput32_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_TRPDO, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint32_t)}, + .o_6322_changePolarityDigitalOutput32_bit = {.dataOrig0 = &OD_RAM.x6322_changePolarityDigitalOutput32_bit_sub0, + .dataOrig = &OD_RAM.x6322_changePolarityDigitalOutput32_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint32_t)}, + .o_6326_errorModeDigitalOutput32_bit = {.dataOrig0 = &OD_RAM.x6326_errorModeDigitalOutput32_bit_sub0, + .dataOrig = &OD_RAM.x6326_errorModeDigitalOutput32_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint32_t)}, + .o_6327_errorValueDigitalOutput32_bit = {.dataOrig0 = &OD_RAM.x6327_errorValueDigitalOutput32_bit_sub0, + .dataOrig = &OD_RAM.x6327_errorValueDigitalOutput32_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint32_t)}, + .o_6328_filterMaskDigitalOutput32_bit = {.dataOrig0 = &OD_RAM.x6328_filterMaskDigitalOutput32_bit_sub0, + .dataOrig = &OD_RAM.x6328_filterMaskDigitalOutput32_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint32_t)}, + + .o_6400_readAnalogInput8_bit = {.dataOrig0 = &OD_RAM.x6400_readAnalogInput8_bit_sub0, + .dataOrig = &OD_RAM.x6400_readAnalogInput8_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_R | ODA_TPDO | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6401_readAnalogInput16_bit = {.dataOrig0 = &OD_RAM.x6401_readAnalogInput16_bit_sub0, + .dataOrig = &OD_RAM.x6401_readAnalogInput16_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_R | ODA_TPDO | ODA_MB, + .dataElementLength = 16, + .dataElementSizeof = sizeof(int16_t)}, + .o_6402_readAnalogInput32_bit = {.dataOrig0 = &OD_RAM.x6402_readAnalogInput32_bit_sub0, + .dataOrig = &OD_RAM.x6402_readAnalogInput32_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_R | ODA_TPDO | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(int32_t)}, + + .o_6410_writeAnalogOutput8_bit = {.dataOrig0 = &OD_RAM.x6410_writeAnalogOutput8_bit_sub0, + .dataOrig = &OD_RAM.x6410_writeAnalogOutput8_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_TRPDO | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t)}, + + .o_6411_writeAnalogOutput16_bit = {.dataOrig0 = &OD_RAM.x6411_writeAnalogOutput16_bit_sub0, + .dataOrig = &OD_RAM.x6411_writeAnalogOutput16_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_TRPDO | ODA_MB, + .dataElementLength = 16, + .dataElementSizeof = sizeof(int16_t)}, + + .o_6412_writeAnalogOutput32_bit = {.dataOrig0 = &OD_RAM.x6412_writeAnalogOutput32_bit_sub0, + .dataOrig = &OD_RAM.x6412_writeAnalogOutput32_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_TRPDO | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(int32_t)}, + .o_6421_analogInputInterruptTriggerSelection_bit = {.dataOrig0 = + &OD_RAM.x6421_analogInputInterruptTriggerSelection_bit_sub0, + .dataOrig = + &OD_RAM.x6421_analogInputInterruptTriggerSelection_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(uint32_t)}, + .o_6422_analogInputInterruptSource_bit = {.dataOrig0 = &OD_RAM.x6422_analogInputInterruptSource_bit_sub0, + .dataOrig = &OD_RAM.x6422_analogInputInterruptSource_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(uint8_t)}, + .o_6423_analogInputGlobalInterruptEnable = {.dataOrig = &OD_RAM.x6423_analogInputGlobalInterruptEnable, + .attribute = ODA_SDO_RW | ODA_MB, + .dataLength = 1}, + .o_6424_analogInputUpperLimitInteger_bit = {.dataOrig0 = &OD_RAM.x6424_analogInputUpperLimitInteger_bit_sub0, + .dataOrig = &OD_RAM.x6424_analogInputUpperLimitInteger_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(uint32_t)}, + .o_6425_analogInputLowerLimitInteger_bit = {.dataOrig0 = &OD_RAM.x6425_analogInputLowerLimitInteger_bit_sub0, + .dataOrig = &OD_RAM.x6425_analogInputLowerLimitInteger_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(uint32_t)}, + .o_6426_analogInputInterruptDeltaUnsigned_bit = {.dataOrig0 = + &OD_RAM.x6426_analogInputInterruptDeltaUnsigned_bit_sub0, + .dataOrig = &OD_RAM.x6426_analogInputInterruptDeltaUnsigned_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(uint32_t)}, + .o_6427_analogInputInterruptNegativeDeltaUnsigned_bit = + {.dataOrig0 = &OD_RAM.x6427_analogInputInterruptNegativeDeltaUnsigned_bit_sub0, + .dataOrig = &OD_RAM.x6427_analogInputInterruptNegativeDeltaUnsigned_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(uint32_t)}, + .o_6428_analogInputInterruptPositiveDeltaUnsigned_bit = + {.dataOrig0 = &OD_RAM.x6428_analogInputInterruptPositiveDeltaUnsigned_bit_sub0, + .dataOrig = &OD_RAM.x6428_analogInputInterruptPositiveDeltaUnsigned_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(uint32_t)}, + .o_6429_analogInputInterruptUpperLimitFloat_bit = + { + .dataOrig0 = &OD_RAM.x6429_analogInputInterruptUpperLimitFloat_bit_sub0, + .dataOrig = &OD_RAM.x6429_analogInputInterruptUpperLimitFloat_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(float), + }, + .o_642A_analogInputInterruptLowerLimitFloat_bit = + { + .dataOrig0 = &OD_RAM.x642A_analogInputInterruptLowerLimitFloat_bit_sub0, + .dataOrig = &OD_RAM.x642A_analogInputInterruptLowerLimitFloat_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(float), + }, + .o_642B_analogInputInterruptDeltaFloat_bit = + { + .dataOrig0 = &OD_RAM.x642B_analogInputInterruptDeltaFloat_bit_sub0, + .dataOrig = &OD_RAM.x642B_analogInputInterruptDeltaFloat_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(float), + }, + .o_642C_analogInputInterruptNegativeDeltaFloat_bit = + { + .dataOrig0 = &OD_RAM.x642C_analogInputInterruptNegativeDeltaFloat_bit_sub0, + .dataOrig = &OD_RAM.x642C_analogInputInterruptNegativeDeltaFloat_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(float), + }, + .o_642D_analogInputInterruptPositiveDeltaFloat_bit = + { + .dataOrig0 = &OD_RAM.x642D_analogInputInterruptPositiveDeltaFloat_bit_sub0, + .dataOrig = &OD_RAM.x642D_analogInputInterruptPositiveDeltaFloat_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(float), + }, + .o_642E_analogInputOffsetFloat_bit = + { + .dataOrig0 = &OD_RAM.x642E_analogInputOffsetFloat_bit_sub0, + .dataOrig = &OD_RAM.x642E_analogInputOffsetFloat_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(float), + }, + .o_642F_analogInputPreScalingFloat_bit = + { + .dataOrig0 = &OD_RAM.x642F_analogInputPreScalingFloat_bit_sub0, + .dataOrig = &OD_RAM.x642F_analogInputPreScalingFloat_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(float), + }, + .o_6430_analogInputSIUnit_bit = + { + .dataOrig0 = &OD_RAM.x6430_analogInputSIUnit_bit_sub0, + .dataOrig = &OD_RAM.x6430_analogInputSIUnit_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 8, + .dataElementSizeof = sizeof(uint8_t), + }, + .o_6431_analogInputOffsetInteger_bit = + { + .dataOrig0 = &OD_RAM.x6431_analogInputOffsetInteger_bit_sub0, + .dataOrig = &OD_RAM.x6431_analogInputOffsetInteger_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(int32_t), + }, + .o_6432_analogInputPreScalingInteger_bit = + { + .dataOrig0 = &OD_RAM.x6432_analogInputPreScalingInteger_bit_sub0, + .dataOrig = &OD_RAM.x6432_analogInputPreScalingInteger_bit[0], + .attribute0 = ODA_SDO_R, + .attribute = ODA_SDO_RW | ODA_MB, + .dataElementLength = 32, + .dataElementSizeof = sizeof(int32_t), + }, + .o_67ff_deviceType = {.dataOrig = &OD_RAM.x67FF_deviceType, .attribute = ODA_SDO_R | ODA_MB, .dataLength = 4}, +}; + +/******************************************************************************* + Object dictionary +*******************************************************************************/ +static OD_ATTR_OD OD_entry_t ODList[] = { + {0x1000, 0x01, ODT_VAR, &ODObjs.o_1000_deviceType, NULL}, + {0x1001, 0x01, ODT_VAR, &ODObjs.o_1001_errorRegister, NULL}, + {0x1003, 0x11, ODT_ARR, &ODObjs.o_1003_pre_definedErrorField, NULL}, + {0x1005, 0x01, ODT_VAR, &ODObjs.o_1005_COB_ID_SYNCMessage, NULL}, + {0x1006, 0x01, ODT_VAR, &ODObjs.o_1006_communicationCyclePeriod, NULL}, + {0x1007, 0x01, ODT_VAR, &ODObjs.o_1007_synchronousWindowLength, NULL}, + {0x1008, 0x01, ODT_VAR, &ODObjs.o_1008_manufacturerDeviceName, NULL}, + {0x1009, 0x01, ODT_VAR, &ODObjs.o_1009_manufacturerHardwareVersion, NULL}, + {0x100A, 0x01, ODT_VAR, &ODObjs.o_100A_manufacturerSoftwareVersion, NULL}, + {0x1010, 0x07, ODT_ARR, &ODObjs.o_1010_storeParameters, NULL}, + {0x1011, 0x07, ODT_ARR, &ODObjs.o_1011_restoreDefaultParameters, NULL}, + {0x1012, 0x01, ODT_VAR, &ODObjs.o_1012_COB_IDTimeStampObject, NULL}, + {0x1014, 0x01, ODT_VAR, &ODObjs.o_1014_COB_ID_EMCY, NULL}, + {0x1015, 0x01, ODT_VAR, &ODObjs.o_1015_inhibitTimeEMCY, NULL}, + {0x1016, 0x09, ODT_ARR, &ODObjs.o_1016_consumerHeartbeatTime, NULL}, + {0x1017, 0x01, ODT_VAR, &ODObjs.o_1017_producerHeartbeatTime, NULL}, + {0x1018, 0x05, ODT_REC, &ODObjs.o_1018_identity, NULL}, + {0x1019, 0x01, ODT_VAR, &ODObjs.o_1019_synchronousCounterOverflowValue, NULL}, + {0x1200, 0x03, ODT_REC, &ODObjs.o_1200_SDOServerParameter, NULL}, + {0x1400, 0x04, ODT_REC, &ODObjs.o_1400_RPDOCommunicationParameter, NULL}, + {0x1401, 0x04, ODT_REC, &ODObjs.o_1401_RPDOCommunicationParameter, NULL}, + {0x1402, 0x04, ODT_REC, &ODObjs.o_1402_RPDOCommunicationParameter, NULL}, + {0x1403, 0x04, ODT_REC, &ODObjs.o_1403_RPDOCommunicationParameter, NULL}, + {0x1600, 0x09, ODT_REC, &ODObjs.o_1600_RPDOMappingParameter, NULL}, + {0x1601, 0x09, ODT_REC, &ODObjs.o_1601_RPDOMappingParameter, NULL}, + {0x1602, 0x09, ODT_REC, &ODObjs.o_1602_RPDOMappingParameter, NULL}, + {0x1603, 0x09, ODT_REC, &ODObjs.o_1603_RPDOMappingParameter, NULL}, + {0x1800, 0x06, ODT_REC, &ODObjs.o_1800_TPDOCommunicationParameter, NULL}, + {0x1801, 0x06, ODT_REC, &ODObjs.o_1801_TPDOCommunicationParameter, NULL}, + {0x1802, 0x06, ODT_REC, &ODObjs.o_1802_TPDOCommunicationParameter, NULL}, + {0x1803, 0x06, ODT_REC, &ODObjs.o_1803_TPDOCommunicationParameter, NULL}, + {0x1A00, 0x09, ODT_REC, &ODObjs.o_1A00_TPDOMappingParameter, NULL}, + {0x1A01, 0x09, ODT_REC, &ODObjs.o_1A01_TPDOMappingParameter, NULL}, + {0x1A02, 0x09, ODT_REC, &ODObjs.o_1A02_TPDOMappingParameter, NULL}, + {0x1A03, 0x09, ODT_REC, &ODObjs.o_1A03_TPDOMappingParameter, NULL}, + {0x2100, 0x0A, ODT_ARR, &ODObjs.o_2100_errorStatusBits, NULL}, + {0x2106, 0x01, ODT_VAR, &ODObjs.o_2106_power_onCounter, NULL}, + {0x2110, 0x11, ODT_ARR, &ODObjs.o_2110_variableInt32, NULL}, + {0x2111, 0x11, ODT_ARR, &ODObjs.o_2111_variableInt32Save, NULL}, + {0x2112, 0x11, ODT_ARR, &ODObjs.o_2112_variableNV_Int32AutoSave, NULL}, + {0x2120, 0x07, ODT_REC, &ODObjs.o_2120_demoRecord, NULL}, + {0x2121, 0x04, ODT_REC, &ODObjs.o_2121_demoStrings, NULL}, + {0x2122, 0x01, ODT_VAR, &ODObjs.o_2122_demoDomain, NULL}, + {0x6000, 0x09, ODT_ARR, &ODObjs.o_6000_readDigitalInput8_bit, NULL}, + {0x6002, 0x09, ODT_ARR, &ODObjs.o_6002_polarityDigitalInput8_bit, NULL}, + {0x6003, 0x09, ODT_ARR, &ODObjs.o_6003_digitalFilterEnable8_bit, NULL}, + {0x6005, 0x01, ODT_VAR, &ODObjs.o_6005_globalInterruptEnableDigital8_bit, NULL}, + {0x6006, 0x09, ODT_ARR, &ODObjs.o_6006_digitalInterruptMaskAnyChange8_bit, NULL}, + {0x6007, 0x09, ODT_ARR, &ODObjs.o_6007_digitalInterruptMaskLowToHigh8_bit, NULL}, + {0x6008, 0x09, ODT_ARR, &ODObjs.o_6008_digitalInterruptMaskHighToLow8_bit, NULL}, + {0x6020, 0x09, ODT_ARR, &ODObjs.o_6020_readDigitalInputBit1To128, NULL}, + {0x6030, 0x09, ODT_ARR, &ODObjs.o_6030_polarityDigitalInputBit1To128, NULL}, + {0x6038, 0x09, ODT_ARR, &ODObjs.o_6038_filterConstantDigitalInputBit1To128, NULL}, + {0x6050, 0x09, ODT_ARR, &ODObjs.o_6050_interruptMaskDigitalInputAnyChange1To128, NULL}, + {0x6060, 0x09, ODT_ARR, &ODObjs.o_6060_interruptMaskDigitalInputLowToHigh1To128, NULL}, + {0x6070, 0x09, ODT_ARR, &ODObjs.o_6070_interruptMaskDigitalInputHighToLow1To128, NULL}, + {0x6100, 0x09, ODT_ARR, &ODObjs.o_6100_readDigitalInput16_bit, NULL}, + {0x6102, 0x09, ODT_ARR, &ODObjs.o_6102_polarityDigitalInput16_bit, NULL}, + {0x6103, 0x09, ODT_ARR, &ODObjs.o_6103_digitalFilterEnable16_bit, NULL}, + {0x6106, 0x09, ODT_ARR, &ODObjs.o_6106_interruptMaskDigitalInputAnyChange16_bit, NULL}, + {0x6107, 0x09, ODT_ARR, &ODObjs.o_6107_interruptMaskDigitalInputLowToHigh16_bit, NULL}, + {0x6108, 0x09, ODT_ARR, &ODObjs.o_6108_interruptMaskDigitalInputHighToLow16_bit, NULL}, + {0x6120, 0x09, ODT_ARR, &ODObjs.o_6120_readDigitalInput32_bit, NULL}, + {0x6122, 0x09, ODT_ARR, &ODObjs.o_6122_polarityDigitalInput32_bit, NULL}, + {0x6123, 0x09, ODT_ARR, &ODObjs.o_6123_digitalFilterEnable32_bit, NULL}, + {0x6126, 0x09, ODT_ARR, &ODObjs.o_6126_interruptMaskDigitalInputAnyChange32_bit, NULL}, + {0x6127, 0x09, ODT_ARR, &ODObjs.o_6127_interruptMaskDigitalInputLowToHigh32_bit, NULL}, + {0x6128, 0x09, ODT_ARR, &ODObjs.o_6128_interruptMaskDigitalInputHighToLow32_bit, NULL}, + {0x6200, 0x09, ODT_ARR, &ODObjs.o_6200_writeDigitalOutput8_bit, NULL}, + {0x6202, 0x09, ODT_ARR, &ODObjs.o_6202_changePolarityDigitalOutput8_bit, NULL}, + {0x6206, 0x09, ODT_ARR, &ODObjs.o_6206_errorModeDigitalOutput8_bit, NULL}, + {0x6207, 0x09, ODT_ARR, &ODObjs.o_6207_errorValueDigitalOutput8_bit, NULL}, + {0x6208, 0x09, ODT_ARR, &ODObjs.o_6208_filterMaskDigitalOutput8_bit, NULL}, + {0x6220, 0x09, ODT_ARR, &ODObjs.o_6220_writeDigitalOutputBit1To128, NULL}, + {0x6240, 0x09, ODT_ARR, &ODObjs.o_6240_changePolarityDigitalOutputBit1To128, NULL}, + {0x6250, 0x09, ODT_ARR, &ODObjs.o_6250_errorModeDigitalOutputLines1To128, NULL}, + {0x6260, 0x09, ODT_ARR, &ODObjs.o_6260_errorValueDigitalOutputBit1To128, NULL}, + {0x6270, 0x09, ODT_ARR, &ODObjs.o_6270_filterMaskDigitalOutputBit1To128, NULL}, + {0x6300, 0x09, ODT_ARR, &ODObjs.o_6300_writeDigitalOutput16_bit, NULL}, + {0x6302, 0x09, ODT_ARR, &ODObjs.o_6302_changePolarityDigitalOutput16_bit, NULL}, + {0x6306, 0x09, ODT_ARR, &ODObjs.o_6306_errorModeDigitalOutput16_bit, NULL}, + {0x6307, 0x09, ODT_ARR, &ODObjs.o_6307_errorValueDigitalOutput16_bit, NULL}, + {0x6308, 0x09, ODT_ARR, &ODObjs.o_6308_filterMaskDigitalOutput16_bit, NULL}, + {0x6320, 0x09, ODT_ARR, &ODObjs.o_6320_writeDigitalOutput32_bit, NULL}, + {0x6322, 0x09, ODT_ARR, &ODObjs.o_6322_changePolarityDigitalOutput32_bit, NULL}, + {0x6326, 0x09, ODT_ARR, &ODObjs.o_6326_errorModeDigitalOutput32_bit, NULL}, + {0x6327, 0x09, ODT_ARR, &ODObjs.o_6327_errorValueDigitalOutput32_bit, NULL}, + {0x6328, 0x09, ODT_ARR, &ODObjs.o_6328_filterMaskDigitalOutput32_bit, NULL}, + {0x6400, 0x09, ODT_ARR, &ODObjs.o_6400_readAnalogInput8_bit, NULL}, + {0x6401, 0x09, ODT_ARR, &ODObjs.o_6401_readAnalogInput16_bit, NULL}, + {0x6402, 0x09, ODT_ARR, &ODObjs.o_6402_readAnalogInput32_bit, NULL}, + {0x6410, 0x09, ODT_ARR, &ODObjs.o_6410_writeAnalogOutput8_bit, NULL}, + {0x6411, 0x09, ODT_ARR, &ODObjs.o_6411_writeAnalogOutput16_bit, NULL}, + {0x6412, 0x09, ODT_ARR, &ODObjs.o_6412_writeAnalogOutput32_bit, NULL}, + {0x6421, 0x09, ODT_ARR, &ODObjs.o_6421_analogInputInterruptTriggerSelection_bit, NULL}, + {0x6422, 0x09, ODT_ARR, &ODObjs.o_6422_analogInputInterruptSource_bit, NULL}, + {0x6423, 0x01, ODT_VAR, &ODObjs.o_6423_analogInputGlobalInterruptEnable, NULL}, + {0x6424, 0x09, ODT_ARR, &ODObjs.o_6424_analogInputUpperLimitInteger_bit, NULL}, + {0x6425, 0x09, ODT_ARR, &ODObjs.o_6425_analogInputLowerLimitInteger_bit, NULL}, + {0x6426, 0x09, ODT_ARR, &ODObjs.o_6426_analogInputInterruptDeltaUnsigned_bit, NULL}, + {0x6427, 0x09, ODT_ARR, &ODObjs.o_6427_analogInputInterruptNegativeDeltaUnsigned_bit, NULL}, + {0x6428, 0x09, ODT_ARR, &ODObjs.o_6428_analogInputInterruptPositiveDeltaUnsigned_bit, NULL}, + {0x6429, 0x09, ODT_ARR, &ODObjs.o_6429_analogInputInterruptUpperLimitFloat_bit, NULL}, + {0x642A, 0x09, ODT_ARR, &ODObjs.o_642A_analogInputInterruptLowerLimitFloat_bit, NULL}, + {0x642B, 0x09, ODT_ARR, &ODObjs.o_642B_analogInputInterruptDeltaFloat_bit, NULL}, + {0x642C, 0x09, ODT_ARR, &ODObjs.o_642C_analogInputInterruptNegativeDeltaFloat_bit, NULL}, + {0x642D, 0x09, ODT_ARR, &ODObjs.o_642D_analogInputInterruptPositiveDeltaFloat_bit, NULL}, + {0x642E, 0x09, ODT_ARR, &ODObjs.o_642E_analogInputOffsetFloat_bit, NULL}, + {0x642F, 0x09, ODT_ARR, &ODObjs.o_642F_analogInputPreScalingFloat_bit, NULL}, + {0x6430, 0x09, ODT_ARR, &ODObjs.o_6430_analogInputSIUnit_bit, NULL}, + {0x6431, 0x09, ODT_ARR, &ODObjs.o_6431_analogInputOffsetInteger_bit, NULL}, + {0x6432, 0x09, ODT_ARR, &ODObjs.o_6432_analogInputPreScalingInteger_bit, NULL}, + {0x67FF, 0x01, ODT_VAR, &ODObjs.o_67ff_deviceType, NULL}, + {0x0000, 0x00, 0, NULL, NULL}}; + +static OD_t _OD = {(sizeof(ODList) / sizeof(ODList[0])) - 1, &ODList[0]}; + +OD_t* OD = &_OD; diff --git a/OD/OD.h b/OD/OD.h new file mode 100644 index 0000000..c7f2dbe --- /dev/null +++ b/OD/OD.h @@ -0,0 +1,1318 @@ +/******************************************************************************* + CANopen Object Dictionary definition for CANopenNode V4 + + This file was automatically generated by CANopenEditor v4.1-1-ga49a51a + + https://github.com/CANopenNode/CANopenNode + https://github.com/CANopenNode/CANopenEditor + + DON'T EDIT THIS FILE MANUALLY !!!! +******************************************************************************** + + File info: + File Names: OD.h; OD.c + Project File: DS301_profile.xpd + File Version: 1 + + Created: 23. 11. 2020 12:00:00 + Created By: + Modified: 17. 03. 2023 02:07:28 + Modified By: + + Device Info: + Vendor Name: + Vendor ID: + Product Name: New Product + Product ID: + + Description: +*******************************************************************************/ + +#ifndef OD_H +#define OD_H + +#include "301/CO_ODinterface.h" + +/******************************************************************************* + Counters of OD objects +*******************************************************************************/ +#define OD_CNT_NMT 1 +#define OD_CNT_EM 1 +#define OD_CNT_SYNC 1 +#define OD_CNT_SYNC_PROD 1 +#define OD_CNT_STORAGE 1 +#define OD_CNT_TIME 1 +#define OD_CNT_EM_PROD 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 + +/******************************************************************************* + Sizes of OD arrays +*******************************************************************************/ +#define OD_CNT_ARR_1003 16 +#define OD_CNT_ARR_1010 4 +#define OD_CNT_ARR_1011 4 +#define OD_CNT_ARR_1016 8 +#define OD_CNT_ARR_2110 16 +#define OD_CNT_ARR_2111 16 +#define OD_CNT_ARR_2112 16 +#define OD_CNT_ARR_6000 8 +#define OD_CNT_ARR_6002 8 +#define OD_CNT_ARR_6003 8 +#define OD_CNT_ARR_6005 8 +#define OD_CNT_ARR_6006 8 +#define OD_CNT_ARR_6007 8 +#define OD_CNT_ARR_6008 8 +#define OD_CNT_ARR_6020 8 +#define OD_CNT_ARR_6030 8 +#define OD_CNT_ARR_6038 8 +#define OD_CNT_ARR_6050 8 +#define OD_CNT_ARR_6060 8 +#define OD_CNT_ARR_6070 8 +#define OD_CNT_ARR_6100 8 +#define OD_CNT_ARR_6102 8 +#define OD_CNT_ARR_6103 8 +#define OD_CNT_ARR_6106 8 +#define OD_CNT_ARR_6107 8 +#define OD_CNT_ARR_6108 8 +#define OD_CNT_ARR_6120 8 +#define OD_CNT_ARR_6122 8 +#define OD_CNT_ARR_6123 8 +#define OD_CNT_ARR_6126 8 +#define OD_CNT_ARR_6127 8 +#define OD_CNT_ARR_6128 8 +#define OD_CNT_ARR_6200 8 +#define OD_CNT_ARR_6202 8 +#define OD_CNT_ARR_6206 8 +#define OD_CNT_ARR_6207 8 +#define OD_CNT_ARR_6208 8 +#define OD_CNT_ARR_6220 128 +#define OD_CNT_ARR_6240 8 +#define OD_CNT_ARR_6250 8 +#define OD_CNT_ARR_6260 8 +#define OD_CNT_ARR_6270 8 +#define OD_CNT_ARR_6300 8 +#define OD_CNT_ARR_6302 8 +#define OD_CNT_ARR_6306 8 +#define OD_CNT_ARR_6307 8 +#define OD_CNT_ARR_6308 8 +#define OD_CNT_ARR_6320 8 +#define OD_CNT_ARR_6322 8 +#define OD_CNT_ARR_6326 8 +#define OD_CNT_ARR_6327 8 +#define OD_CNT_ARR_6328 8 +#define OD_CNT_ARR_6400 16 +#define OD_CNT_ARR_6401 16 +#define OD_CNT_ARR_6402 16 +#define OD_CNT_ARR_6410 8 +#define OD_CNT_ARR_6411 8 +#define OD_CNT_ARR_6412 8 +#define OD_CNT_ARR_6421 16 +#define OD_CNT_ARR_6422 16 +#define OD_CNT_ARR_6424 16 +#define OD_CNT_ARR_6425 16 +#define OD_CNT_ARR_6426 16 +#define OD_CNT_ARR_6427 16 +#define OD_CNT_ARR_6428 16 +#define OD_CNT_ARR_6429 16 +#define OD_CNT_ARR_642A 16 +#define OD_CNT_ARR_642B 16 +#define OD_CNT_ARR_642C 16 +#define OD_CNT_ARR_642D 16 +#define OD_CNT_ARR_642E 16 +#define OD_CNT_ARR_642F 16 +#define OD_CNT_ARR_6430 16 +#define OD_CNT_ARR_6431 16 +#define OD_CNT_ARR_6432 16 + +/******************************************************************************* + OD data declaration of all groups +*******************************************************************************/ +typedef struct { + /* This object describes the type of device and its functionality. For multiple device modules the + additional information field shall contain FFFF h . In this case, the 67FF h object shall be + implemented. Figure 1 shows the value structure as defined in /CiA301/ and specifies the + additional information field. Table 2 specifies the values for the fields I/O functionality and M. + At least one I/O functionality decribed with bit 16 to 19 shall be implemented in the device. + The pre-defined, generic PDO mapping is described in this specification, the Manufacturer - + specific PDO mapping is not in the scope of this specification. In case a joystick module is + implemented, /CiA401-2/ shall be applied for purpose of the implementation. + + 31 Specific functionality 24 + 23 M + 22 I/O functionality 16 + 15 Device profile number 0 + + 31 Additional information 16 + 15 General information 0 + + 31 MSB + 0 LSB + Figure 1 — Value structure + + Table 2 — Value definition for the I/O functionality field and the M field + Field name Definition + + Device profile number 401d + I/O functionality – Bit 16 1b = digital input(s) implemented + 0b = not implemented + I/O functionality – Bit 17 1b = digital output(s) implemented + 0b = not implemented + I/O functionality – Bit 18 1b = analog input(s) implemented + 0b = not implemented + I/O functionality – Bit 19 1b = analog output(s) implemented + 0b = not implemented + I/O functionality – Bit 20 to Bit 21 Reserved (00 b) + I/O functionality – Bit 22 0b + M(apping of PDOs) 1b = Manufacturer-specific PDO mapping is implemented + 0b = Pre-defined, generic PDO mapping is implemented (see 6.2.4 + to 6.2.11) + + + Table 3 — Value definition for the specific functionality field + Value Specific function + 0000 0000 b No specific function + 0000 0001 b to 0000 0111 b Joystick module + 0000 1000 b to 1000 0000 b Reserved + 1000 0001 b to 1111 1111 b Operator environment interface module + */ + uint32_t x1000_deviceType; + uint32_t x1005_COB_ID_SYNCMessage; + uint32_t x1006_communicationCyclePeriod; + uint32_t x1007_synchronousWindowLength; + uint32_t x1012_COB_IDTimeStampObject; + uint32_t x1014_COB_ID_EMCY; + uint16_t x1015_inhibitTimeEMCY; + uint8_t x1016_consumerHeartbeatTime_sub0; + uint32_t x1016_consumerHeartbeatTime[OD_CNT_ARR_1016]; + uint16_t x1017_producerHeartbeatTime; + struct { + uint8_t highestSub_indexSupported; + uint32_t vendor_ID; + uint32_t productCode; + uint32_t revisionNumber; + uint32_t serialNumber; + } x1018_identity; + uint8_t x1019_synchronousCounterOverflowValue; + struct { + uint8_t highestSub_indexSupported; + uint32_t COB_IDClientToServerTx; + uint32_t COB_IDServerToClientRx; + uint8_t node_IDOfTheSDOServer; + } x1280_SDOClientParameter; + struct { + uint8_t highestSub_indexSupported; + uint32_t COB_IDUsedByRPDO; + uint8_t transmissionType; + uint16_t eventTimer; + } x1400_RPDOCommunicationParameter; + struct { + uint8_t highestSub_indexSupported; + uint32_t COB_IDUsedByRPDO; + uint8_t transmissionType; + uint16_t eventTimer; + } x1401_RPDOCommunicationParameter; + struct { + uint8_t highestSub_indexSupported; + uint32_t COB_IDUsedByRPDO; + uint8_t transmissionType; + uint16_t eventTimer; + } x1402_RPDOCommunicationParameter; + struct { + uint8_t highestSub_indexSupported; + uint32_t COB_IDUsedByRPDO; + uint8_t transmissionType; + uint16_t eventTimer; + } x1403_RPDOCommunicationParameter; + struct { + uint8_t numberOfMappedApplicationObjectsInPDO; + uint32_t applicationObject1; + uint32_t applicationObject2; + uint32_t applicationObject3; + uint32_t applicationObject4; + uint32_t applicationObject5; + uint32_t applicationObject6; + uint32_t applicationObject7; + uint32_t applicationObject8; + } x1600_RPDOMappingParameter; + struct { + uint8_t numberOfMappedApplicationObjectsInPDO; + uint32_t applicationObject1; + uint32_t applicationObject2; + uint32_t applicationObject3; + uint32_t applicationObject4; + uint32_t applicationObject5; + uint32_t applicationObject6; + uint32_t applicationObject7; + uint32_t applicationObject8; + } x1601_RPDOMappingParameter; + struct { + uint8_t numberOfMappedApplicationObjectsInPDO; + uint32_t applicationObject1; + uint32_t applicationObject2; + uint32_t applicationObject3; + uint32_t applicationObject4; + uint32_t applicationObject5; + uint32_t applicationObject6; + uint32_t applicationObject7; + uint32_t applicationObject8; + } x1602_RPDOMappingParameter; + struct { + uint8_t numberOfMappedApplicationObjectsInPDO; + uint32_t applicationObject1; + uint32_t applicationObject2; + uint32_t applicationObject3; + uint32_t applicationObject4; + uint32_t applicationObject5; + uint32_t applicationObject6; + uint32_t applicationObject7; + uint32_t applicationObject8; + } x1603_RPDOMappingParameter; + struct { + uint8_t highestSub_indexSupported; + uint32_t COB_IDUsedByTPDO; + uint8_t transmissionType; + uint16_t inhibitTime; + uint16_t eventTimer; + uint8_t SYNCStartValue; + } x1800_TPDOCommunicationParameter; + struct { + uint8_t highestSub_indexSupported; + uint32_t COB_IDUsedByTPDO; + uint8_t transmissionType; + uint16_t inhibitTime; + uint16_t eventTimer; + uint8_t SYNCStartValue; + } x1801_TPDOCommunicationParameter; + struct { + uint8_t highestSub_indexSupported; + uint32_t COB_IDUsedByTPDO; + uint8_t transmissionType; + uint16_t inhibitTime; + uint16_t eventTimer; + uint8_t SYNCStartValue; + } x1802_TPDOCommunicationParameter; + struct { + uint8_t highestSub_indexSupported; + uint32_t COB_IDUsedByTPDO; + uint8_t transmissionType; + uint16_t inhibitTime; + uint16_t eventTimer; + uint8_t SYNCStartValue; + } x1803_TPDOCommunicationParameter; + struct { + uint8_t numberOfMappedApplicationObjectsInPDO; + uint32_t applicationObject1; + uint32_t applicationObject2; + uint32_t applicationObject3; + uint32_t applicationObject4; + uint32_t applicationObject5; + uint32_t applicationObject6; + uint32_t applicationObject7; + uint32_t applicationObject8; + } x1A00_TPDOMappingParameter; + struct { + uint8_t numberOfMappedApplicationObjectsInPDO; + uint32_t applicationObject1; + uint32_t applicationObject2; + uint32_t applicationObject3; + uint32_t applicationObject4; + uint32_t applicationObject5; + uint32_t applicationObject6; + uint32_t applicationObject7; + uint32_t applicationObject8; + } x1A01_TPDOMappingParameter; + struct { + uint8_t numberOfMappedApplicationObjectsInPDO; + uint32_t applicationObject1; + uint32_t applicationObject2; + uint32_t applicationObject3; + uint32_t applicationObject4; + uint32_t applicationObject5; + uint32_t applicationObject6; + uint32_t applicationObject7; + uint32_t applicationObject8; + } x1A02_TPDOMappingParameter; + struct { + uint8_t numberOfMappedApplicationObjectsInPDO; + uint32_t applicationObject1; + uint32_t applicationObject2; + uint32_t applicationObject3; + uint32_t applicationObject4; + uint32_t applicationObject5; + uint32_t applicationObject6; + uint32_t applicationObject7; + uint32_t applicationObject8; + } x1A03_TPDOMappingParameter; +} OD_PERSIST_COMM_t; + +typedef struct { + uint8_t x1001_errorRegister; + uint8_t x1010_storeParameters_sub0; + uint32_t x1010_storeParameters[OD_CNT_ARR_1010]; + uint8_t x1011_restoreDefaultParameters_sub0; + uint32_t x1011_restoreDefaultParameters[OD_CNT_ARR_1011]; + struct { + uint8_t highestSub_indexSupported; + uint32_t COB_IDClientToServerRx; + uint32_t COB_IDServerToClientTx; + } x1200_SDOServerParameter; + uint8_t x2100_errorStatusBits[10]; + uint8_t x2110_variableInt32_sub0; + int32_t x2110_variableInt32[OD_CNT_ARR_2110]; + uint8_t x6000_readDigitalInput8_bit_sub0; + uint8_t x6000_readDigitalInput8_bit[OD_CNT_ARR_6000]; + + /* This object shall indicate the configured polarity of a group of 8 input lines. The input polarity + can be inverted individually. + 1 b = input inverted + 0 b = input not inverted + If the object is not supported the device shall behave according to the default value. + */ + uint8_t x6002_polarityDigitalInput8_bit_sub0; + uint8_t x6002_polarityDigitalInput8_bit[OD_CNT_ARR_6002]; + + /* This object shall enable and disable an additional configurable filter constant. If the object is + not supported, the device shall behave according to the default value. The type of the filter + constant and the configuration of the filter constant are manufacturer -specific. + 1 = enabled + 0 = disabled + */ + uint8_t x6003_digitalFilterEnable8_bit_sub0; + uint8_t x6003_digitalFilterEnable8_bit[OD_CNT_ARR_6003]; + + /* This object shall enable and disable globally the interrupt behavior without changing the + interrupt masks. In event-driven mode the device transmits the input values depending on the + interrupt masks in objects 6006 h , 6007 h , and 6008 h (resp. 6050 h to 6057 h, 6060 h to 6067 h , + 6070 h to 6077 h , or 6106 h , 6107 h , 6108 h , or 6126 h , 6127 h , 6128 h ) and the PDO transmission + type. If the object is not supported, the device shall behave according to the default value. + TRUE = global interrupt enabled + FALSE = global interrupt disabled + */ + uint8_t x6005_globalInterruptEnableDigital8_bit; + /* + This object shall determine, which input port lines shall activate an interrupt by positive or/and + negative edge detection. + If the object is not supported the device shall behave according to the default value. + */ + uint8_t x6006_digitalInterruptMaskAnyChange8_bit_sub0; + uint8_t x6006_digitalInterruptMaskAnyChange8_bit[OD_CNT_ARR_6006]; + + /* This object shall determine, which input port lines shall activate an interrupt by positive edge + detection (logical 0 to 1). This is done for groups of 8 lines. The values shall be in an ”OR” + connection to the values of 6006 h object (Interrupt mask any change 8-bit). If inputs are + inverted by 6002 h object (polarity input 8-bit), the positive logical edge shall correspond to + negative physical edge. + 1 = interrupt enabled + 0 = interrupt disabled + */ + uint8_t x6007_digitalInterruptMaskLowToHigh8_bit_sub0; + uint8_t x6007_digitalInterruptMaskLowToHigh8_bit[OD_CNT_ARR_6007]; + + /* This object shall determine, which input port lines shall activate an interrupt by negative edge + detection (logical 1 to 0). This is done for groups of 8 lines. The values shall be in an ”OR” + connection to the values of 6006 h object (Interrupt mask any change 8-bit). If inputs are + inverted by 6002 h object (polarity input 8-bit), the negative logical edge shall correspond to + positive physical edge. + 1 = interrupt enabled + 0 = interrupt disabled + */ + uint8_t x6008_digitalInterruptMaskHighToLow8_bit_sub0; + uint8_t x6008_digitalInterruptMaskHighToLow8_bit[OD_CNT_ARR_6008]; + + /* + These objects shall read single input lines information. A maximum of 128 input lines are + addressable with one Index. The 6020 h object shall address the input lines 1 to 128, the 6021 h + object shall address the input lines 129 to 256, etc. + */ + uint8_t x6020_readDigitalInputBit1To128_sub0; + uint8_t x6020_readDigitalInputBit1To128[OD_CNT_ARR_6020]; + + /* These objects shall indicate the configured polarity of single input lines. A maximum of 128 + input lines are addressable with one Index. The 6030 h object shall address the input lines 1 to + 128, the 6031 h object shall address the input lines 129 to 256, etc. + TRUE = input inverted + FALSE = input not inverted + If these objects are not supported the device shall behave according to the default value. + */ + uint8_t x6030_polarityDigitalInputBit1To128_sub0; + uint8_t x6030_polarityDigitalInputBit1To128[OD_CNT_ARR_6030]; + + /* These objects shall enable and disable an additional configurable filter constant. If these + objects are not supported, the device shall behave according to the default value. The type of + the filter constant and the configuration of the filter constant are manufacturer -specific. The + 6038 h object shall address the input lines 1 to 128, the 6039 h object shall address the input + lines 129 to 256, etc. + TRUE = enabled + FALSE = disable + */ + uint8_t x6038_filterConstantDigitalInputBit1To128_sub0; + uint8_t x6038_filterConstantDigitalInputBit1To128[OD_CNT_ARR_6038]; + + /* These objects shall set interrupt masks for single input lines. A maximum of 128 bit inputs are + addressable with one Index. The 6050 h object shall address the input lines 1 to 128, the 6051 h + object shall address the input lines 129 to 256, etc. + TRUE = interrupt enabled + FALSE = interrupt disabled + If the object is not supported, the device shall behave according to the default value. + */ + uint8_t x6050_interruptMaskDigitalInputAnyChange1To128_sub0; + uint8_t x6050_interruptMaskDigitalInputAnyChange1To128[OD_CNT_ARR_6050]; + + /* These objects shall set interrupt masks for a single input line. A maximum of 128 bit inputs + are addressable with one Index. The 6060 h object shall address the input lines 1 to 128, the + 6061 h object shall address the input lines 129 to 256, etc. The values shall be in an ”OR” + connection to the values of 6050 h to 6057 h objects (interrupt mask any change). If inputs are + inverted by 6030 h to 6037 h objects (polarity input), the positive logical edge shall correspond + to negative physical edge. + TRUE = interrupt enabled + FALSE = interrupt disabled + If the object is not supported, the device shall behave according to the default value. + */ + uint8_t x6060_interruptMaskDigitalInputLowToHigh1To128_sub0; + uint8_t x6060_interruptMaskDigitalInputLowToHigh1To128[OD_CNT_ARR_6060]; + + /* + These objects shall set interrupt masks for single input lines. A maximum of 128 bit inputs are + addressable with one Index. The 6070 h object shall address the input lines 1 to 128, the 6071 h + object shall address the input lines 129 to 256, etc. The values shall be in an ”OR” connection + to the values of 6050 h to 6057 h objects (interrupt mask any change). If inputs are inverted by + 6030 h to 6037 h objects (polarity input), the negative logical edge shall correspond to positive + physical edge. + TRUE = interrupt enabled + FALSE = interrupt disabled + If the object is not supported, the device shall behave according to the default value. + */ + uint8_t x6070_interruptMaskDigitalInputHighToLow1To128_sub0; + uint8_t x6070_interruptMaskDigitalInputHighToLow1To128[OD_CNT_ARR_6070]; + + /* + The object shall read a group of 16 input lines as 16-bit information. A maximum of 254 x 16- + bit words is addressable (4064 inputs). + */ + uint8_t x6100_readDigitalInput16_bit_sub0; + uint16_t x6100_readDigitalInput16_bit[OD_CNT_ARR_6100]; + + /* This object shall indicate the configured polarity for a group of 16 input lines. The inputs can + be inverted individually. + 1 = input inverted + 0 = input not inverted + If the object is not supported the device shall behave according to the default value. + */ + uint8_t x6102_polarityDigitalInput16_bit_sub0; + uint16_t x6102_polarityDigitalInput16_bit[OD_CNT_ARR_6102]; + + /* This object shall enable and disable an additional configurable filter constant. If the object is + not supported, the device shall behave according to the default value. The type of the filter + constant and the configuration of the filter constant are manufacturer -specific. + 1 = enabled + 0 = disabled + */ + uint8_t x6103_digitalFilterEnable16_bit_sub0; + uint16_t x6103_digitalFilterEnable16_bit[OD_CNT_ARR_6103]; + /* This object shall determine, which input port lines shall activate an interrupt. This is done for + groups of 16 lines and for any change of a digital input line. + 1 = interrupt enabled + 0 = interrupt disabled + */ + uint8_t x6106_interruptMaskDigitalInputAnyChange16_bit_sub0; + uint16_t x6106_interruptMaskDigitalInputAnyChange16_bit[OD_CNT_ARR_6106]; + + /* This object shall determine, which input port lines shall activate an interrupt. This is done for + groups of 16 lines and for a change from low -to-high of a digital input line. The values shall be + in an ”OR” connection to the values of 6106 h object (interrupt mask any change 16-bit). If + inputs are inverted by 6102 h object (polarity input 16-bit), the positive logical edge shall + correspond to negative physical edge. + 1 = interrupt enabled + 0 = interrupt disabled */ + uint8_t x6107_interruptMaskDigitalInputLowToHigh16_bit_sub0; + uint16_t x6107_interruptMaskDigitalInputLowToHigh16_bit[OD_CNT_ARR_6107]; + + /* This object shall determine, which input port lines shall activate an interrupt. This is done for + groups of 16 lines and for a change from high-to-low of a digital input line. The values shall be + in an ”OR” connection to the values of 6106 h object (interrupt mask any change 16-bit). If + inputs are inverted by 6102 h object (polarity input 16-bit), the negative logical edge shall + correspond to positive physical edge. + 1 = interrupt enabled + 0 = interrupt disabled + */ + uint8_t x6108_interruptMaskDigitalInputHighToLow16_bit_sub0; + uint16_t x6108_interruptMaskDigitalInputHighToLow16_bit[OD_CNT_ARR_6108]; + + /* This object shall read a group of 32 input lines as 32-bit information. A maximum of 254 x 32- + */ + uint8_t x6120_readDigitalInput32_bit_sub0; + uint32_t x6120_readDigitalInput32_bit[OD_CNT_ARR_6120]; + + /* This object shall indicate the configured polarity for a group of 32 input lines. Inputs can be + inverted individually. + 1 = input inverted + 0 = input not inverted + If the object is not supported the device shall behave according to the default value. */ + uint8_t x6122_polarityDigitalInput32_bit_sub0; + uint32_t x6122_polarityDigitalInput32_bit[OD_CNT_ARR_6122]; + /* This object shall enable and disable an additional configurable filter constant. If the object is + not supported, the device shall behave according to the default value. The type of the filter + constant and the configuration of the filter constant are manufacturer -specific. + 1 = enabled + 0 = disabled */ + uint8_t x6123_digitalFilterEnable32_bit_sub0; + uint32_t x6123_digitalFilterEnable32_bit[OD_CNT_ARR_6123]; + + /* This object shall determine which input port lines shall activate an interrupt. This is done for + groups of 32 lines and for any change of a digital input line. + 1 = interrupt enabled + 0 = interrupt disabled + If the object is not supported, the device shall behave according to the default value. + */ + uint8_t x6126_interruptMaskDigitalInputAnyChange32_bit_sub0; + uint32_t x6126_interruptMaskDigitalInputAnyChange32_bit[OD_CNT_ARR_6126]; + + /* + This object shall determine, which input port lines shall activate an interrupt. This is done for + groups of 32 lines and for a change from low -to-high of a digital input line. The values shall be + in an ”OR” connection to the values of 6126 h object (interrupt mask any change 32-bit). If + inputs are inverted by 6122 h object (polarity input 32-bit), the positive logical edge shall + correspond to negative physical edge. + 1 = interrupt enabled + 0 = interrupt disabled + */ + uint8_t x6127_interruptMaskDigitalInputLowToHigh32_bit_sub0; + uint32_t x6127_interruptMaskDigitalInputLowToHigh32_bit[OD_CNT_ARR_6127]; + + /* + This object shall determine, which input port lines shall activate an interrupt. This is done for + groups of 32 lines and for a change from high-to-low of a digital input line. The values shall be + in an ”OR” connection to the values of 6126 h object (interrupt mask any change 32-bit). If + inputs are inverted by 6122 h object (polarity input 32-bit), the negative logical edge shall + correspond to positive physical edge. + 1 = interrupt enabled + 0 = interrupt disabled + */ + uint8_t x6128_interruptMaskDigitalInputHighToLow32_bit_sub0; + uint32_t x6128_interruptMaskDigitalInputHighToLow32_bit[OD_CNT_ARR_6128]; + + /* This object shall set a group of 8 output lines as a byte of information. A maximum of 254 x 8 + bit output blocks is addressable. */ + uint8_t x6200_writeDigitalOutput8_bit_sub0; + uint8_t x6200_writeDigitalOutput8_bit[OD_CNT_ARR_6200]; + + /* This object shall indicate the configured polarity of a group of 8 output lines. The output + polarity can be inverted individually. + 1 = output inverted + 0 = output not inverted */ + uint8_t x6202_changePolarityDigitalOutput8_bit_sub0; + uint8_t x6202_changePolarityDigitalOutput8_bit[OD_CNT_ARR_6202]; + + /* This object shall indicate, whether an output is set to a pre-defined error value (see 6207 h + object) in case of an internal device failure or a 'Stop Remote Node' indication. + 1 = output value shall take the pre-defined condition specified in 6207 h object + 0 = output value shall be kept if an error occurs + */ + uint8_t x6206_errorModeDigitalOutput8_bit_sub0; + uint8_t x6206_errorModeDigitalOutput8_bit[OD_CNT_ARR_6206]; + + /* This Object shall indicate to which value the outputs shall be set at device failures (see + chapter 5.2) if the corresponding error mode is active. + 0 = output shall be set to ‘0’ in case of fault, if 6206 h object is enabled + 1 = output shall be set to ‘1’ in case of fault, if 6206 h object is enabled + */ + uint8_t x6207_errorValueDigitalOutput8_bit_sub0; + uint8_t x6207_errorValueDigitalOutput8_bit[OD_CNT_ARR_6207]; + + /* This object shall indicate an additional configurable output filter mask for a group of 8 outputs. + 1 = output shall be set to the received output value + 0 = don’t care, the received output value is neglected for the appropriated output channel, the + old output value shall be kept. + If the object is not supported, the device shall behave according to the default value. */ + uint8_t x6208_filterMaskDigitalOutput8_bit_sub0; + uint8_t x6208_filterMaskDigitalOutput8_bit[OD_CNT_ARR_6208]; + + /* These objects shall set single output line information. A maximum of 128 outputs are + addressable with one Index. The 6220 h object shall address output lines 1 to 128, the 6221 h + object shall address output lines 129 to 256, etc. */ + uint8_t x6220_writeDigitalOutputBit1To128_sub0; + uint8_t x6220_writeDigitalOutputBit1To128[OD_CNT_ARR_6220]; + + /* These objects shall set the polarity of single output lines. A maximum of 128 outputs are + addressable with one Index. The 6240 h object shall address output lines 1 to 128, the 6241 h + object shall address output lines 129 to 256, etc. + TRUE = output inverted + FALSE = output not inverted */ + uint8_t x6240_changePolarityDigitalOutputBit1To128_sub0; + uint8_t x6240_changePolarityDigitalOutputBit1To128[OD_CNT_ARR_6240]; + + /* These objects shall indicate, whether an output is set to a pre -defined error value (see 6260 h + to 6267 h objects) in case of an internal device failure a 'Stop remote node' indication. A + maximum of 128 outputs are addressable with one Index. The 6250 h object shall address + output lines 1 to 128, the 6251 h object shall address output lines 129 to 256, etc. + TRUE = output value shall take the pre-defined condition as specified in 6260 h to 6267 h + objects + FALSE = output value shall be kept if an error occurs + If the object is not supported, the device shall behave according to the default value. */ + uint8_t x6250_errorModeDigitalOutputLines1To128_sub0; + uint8_t x6250_errorModeDigitalOutputLines1To128[OD_CNT_ARR_6250]; + + /* This Object shall indicate to which value the outputs shall be set at device failures (see + chapter 5.2) if the corresponding error mode is active. A maximum of 128 outputs are + addressable with one Index. The 6260 h object shall address output lines 1 to 128, the 6261 h + object shall address output lines 129 to 256, etc. + FALSE = output shall be set to ‘0’ in case of fault, if the corresponding object (6250 h to 6257 h ) + is enabled + TRUE = output shall be set to ‘1’ in case of fault, if the corresponding object (6250 h to 6257 h ) + is enabled + If the object is not supported, the device shall behave according to the default value. */ + uint8_t x6260_errorValueDigitalOutputBit1To128_sub0; + uint8_t x6260_errorValueDigitalOutputBit1To128[OD_CNT_ARR_6260]; + + /* This object shall indicate an additional configurable output filter mask for a single output. + TRUE = output shall set to the received output value + FALSE = don’t care the received output value is neglected for the appropriated output + channel, the old output value shall be kept + A maximum of 128 outputs are addressable with one Index. The 6270 h object shall address + output lines 1 to 128, the 6271 h object shall address output lines 129 to 256, etc. + If the object is not supported, the device shall behave according to the default value. */ + uint8_t x6270_filterMaskDigitalOutputBit1To128_sub0; + uint8_t x6270_filterMaskDigitalOutputBit1To128[OD_CNT_ARR_6270]; + + /* This object shall set a group of 16 output lines as 2 -byte information. A maximum of 255 x 16- + bit words is addressable (4080 outputs). */ + uint8_t x6300_writeDigitalOutput16_bit_sub0; + uint16_t x6300_writeDigitalOutput16_bit[OD_CNT_ARR_6300]; + + /* This object shall indicate the configured polarity for a group of 16 output lines. The output + polarity can be inverted individually. + 1 = enabled + 0 = disabled + If the object is not supported the device shall behave according to the default value. */ + uint8_t x6302_changePolarityDigitalOutput16_bit_sub0; + uint16_t x6302_changePolarityDigitalOutput16_bit[OD_CNT_ARR_6302]; + + /* These objects shall indicate, whether an output is set to a pre -defined error value (see 6307 h + object) in case of an internal device failure a 'Stop Remote Node' indication. + 1 = output value shall take the pre-defined condition as specified in 6307 h object + 0 = output value shall be kept if an error occurs + If the object is not supported, the device shall behave according to the default value. */ + uint8_t x6306_errorModeDigitalOutput16_bit_sub0; + uint16_t x6306_errorModeDigitalOutput16_bit[OD_CNT_ARR_6306]; + + /* This Object shall indicate to which value the outputs shall be set at device failures (see + chapter 5.2) if the corresponding error mode is active. + 0 = output shall be set to ‘0’ in case of fault, if 6306h object is enabled + 1 = output shall be set to ‘1’ in case of fault, if 6306h object is enabled + If the object is not supported, the device shall behave according to the default value. */ + uint8_t x6307_errorValueDigitalOutput16_bit_sub0; + uint16_t x6307_errorValueDigitalOutput16_bit[OD_CNT_ARR_6307]; + + /* This object shall define an additional configurable output filter mask for a group of 16 outputs. + 1 = output is shall set to the received output value + 0 = don’t care, the received output value is neglected for the appropriated output channel, the + old output value shall be kept. + If the object is not supported, the device shall behave according to the default value. */ + uint8_t x6308_filterMaskDigitalOutput16_bit_sub0; + uint16_t x6308_filterMaskDigitalOutput16_bit[OD_CNT_ARR_6308]; + + /* This object shall set a group of 32 output lines as 4 -Byte information. A maximum of 255 x 32- + bit words is addressable (8160 outputs). */ + uint8_t x6320_writeDigitalOutput32_bit_sub0; + uint32_t x6320_writeDigitalOutput32_bit[OD_CNT_ARR_6320]; + + /* This object shall define the polarity for a group of 32 output lines. The output polarity can be + inverted individually. + 1 = enabled + 0 = disabled + If the object is not supported the device shall behave accordingly to the default value. */ + uint8_t x6322_changePolarityDigitalOutput32_bit_sub0; + uint32_t x6322_changePolarityDigitalOutput32_bit[OD_CNT_ARR_6322]; + + /* These objects shall indicate, whether an output is set to a pre -defined error value (see also + 6327 h object) in case of an internal device failure a 'Stop Remote Node' indication. + 1 = output value shall take the pre-defined condition as specified in 6327 h object + 0 = output value shall be kept if an error occurs + If the object is not supported, the device shall behave according to the default value. */ + uint8_t x6326_errorModeDigitalOutput32_bit_sub0; + uint32_t x6326_errorModeDigitalOutput32_bit[OD_CNT_ARR_6326]; + + /* This Object shall indicate to which value the outputs shall be set at device failures (see + chapter 5.2) if the corresponding error mode is active. + 0 = output shall be set to ‘0’ in case of fault, if 6326 h object is enabled + 1 = output shall be set to ‘1’ in case of fault, if 6326 h object is enabled + If the object is not supported, the device shall behave according to the default value. */ + uint8_t x6327_errorValueDigitalOutput32_bit_sub0; + uint32_t x6327_errorValueDigitalOutput32_bit[OD_CNT_ARR_6327]; + + /* This object shall define an additional configurable output filter mask for a group of 32 outputs. + 1 = output shall be set to the received output value + 0 = don’t care the received output value is neglected for the appropriated output channel, the + old output value shall be kept. + If the object is not supported, the device shall behave accordingly to the default value. */ + uint8_t x6328_filterMaskDigitalOutput32_bit_sub0; + uint32_t x6328_filterMaskDigitalOutput32_bit[OD_CNT_ARR_6328]; + + /* This object shall read the value of the input channel 'n'. The value size is 8 -bit or less. The + value shall always be left adjusted. The remaining bits at the right side of the LSB shall be set + to zero. */ + uint8_t x6400_readAnalogInput8_bit_sub0; + uint8_t x6400_readAnalogInput8_bit[OD_CNT_ARR_6400]; + + /* This object shall read the value of the input channel 'n'. The value is 16-bit wide or less. The + value shall always be left adjusted. The remaining bits at the right side of the LSB shall be set + to zero. */ + uint8_t x6401_readAnalogInput16_bit_sub0; + int16_t x6401_readAnalogInput16_bit[OD_CNT_ARR_6401]; + + /* This object shall read the value of the input channel 'n'. The value is 32 -bit wide or less. The + value shall always be left adjusted. The remaining bits at the right side of the LSB shall be set + to zero. */ + uint8_t x6402_readAnalogInput32_bit_sub0; + int32_t x6402_readAnalogInput32_bit[OD_CNT_ARR_6402]; + + /* This object shall write an integer8 value to the output channel 'n'. The value shall always be + left adjusted. */ + uint8_t x6410_writeAnalogOutput8_bit_sub0; + int8_t x6410_writeAnalogOutput8_bit[OD_CNT_ARR_6410]; + + /* This object shall write an integer16 value to the output channel 'n'. The value shall always be + left adjusted. */ + uint8_t x6411_writeAnalogOutput16_bit_sub0; + int16_t x6411_writeAnalogOutput16_bit[OD_CNT_ARR_6411]; + + /* This object shall write an integer32 value to the output channel 'n'. The value shall always be + left adjusted. */ + uint8_t x6412_writeAnalogOutput32_bit_sub0; + int32_t x6412_writeAnalogOutput32_bit[OD_CNT_ARR_6412]; + + /* + This object shall determine, which events shall cause an interrupt for a specific channel. + Any bit set to 1 b shall trigger the corresponding analog input. If the object is not supported, the device + shall behave according to the default value. + bit 0 0b Upper limit not exceeded + bit 0 1b Upper limit exceeded + bit 1 0b Input not below lower limit + bit 1 1b Input below lower limit + bit 2 0b Input not changed by more than delta + bit 2 1b Input changed by more than delta + bit 3 0b Input not reduced by more than negative delta + bit 3 1b Input reduced by more than negative delta + bit 4 0b Input not increased by more than positive delta + bit 4 1b Input increased by more than positive delta + bit 5 0b Reserved for future use + */ + uint8_t x6421_analogInputInterruptTriggerSelection_bit_sub0; + int32_t x6421_analogInputInterruptTriggerSelection_bit[OD_CNT_ARR_6421]; + + /* + This object shall determine, which channel has produced an interrupt. The bits set shall relate + to the number of the channels that have produced interrupts. The bits shall be reset + automatically after read by SDO or transmitted by means of a PDO. + 1 = interrupt produced + 0 = no interrupt produced + If the object is not supported, the device shall behave according to the default value. + */ + uint8_t x6422_analogInputInterruptSource_bit_sub0; + int32_t x6422_analogInputInterruptSource_bit[OD_CNT_ARR_6422]; + /* + This object shall enable and disable globally the interrupt behavior without changing the + interrupt mask. By default, no analog input activates an interrupt. + TRUE = global interrupt enabled + FALSE = global interrupt disabled + */ + uint8_t x6423_analogInputGlobalInterruptEnable; + /* + This object shall trigger an interrupt if enabled (see 6423 h object) and the analog input is + equal to, or rises above the given value. The value shall always be left adjusted. As long as + the trigger condition is met, every change of the analog input data generates a new interrupt, + if there is no additional trigger condition, e.g. an input interrupt delta (6426 h ). + If the object is not supported, the device shall behave according to the default value. + Configuration of the analog input interrupt upper limit float object (6429 h ) shall also cause a + value change in the 6424 h object and vice versa. + */ + uint8_t x6424_analogInputUpperLimitInteger_bit_sub0; + int32_t x6424_analogInputUpperLimitInteger_bit[OD_CNT_ARR_6424]; + /* + This object shall trigger an interrupt if enabled (see 6423 h object) and the analog input falls + below the given value. The value shall always be left adjusted. As long as the trigger + condition is met, every change of the analog input data generates a new interrupt, if there is + no additional trigger condition, e.g. an input interrupt delta (6426 h ). + If the object is not supported, the device shall behave according to the default value. + Configuration of the analog input interrupt lower limit float object (642A h ) shall also cause a + value change in the 6425 h object and vice versa. + */ + uint8_t x6425_analogInputLowerLimitInteger_bit_sub0; + int32_t x6425_analogInputLowerLimitInteger_bit[OD_CNT_ARR_6425]; + /* + This object shall set the delta value (rising or falling above or below the last communicated + value) for interrupt-enabled analog inputs (see 6423 h object). + If the object is not supported, the device shall behave according to the default value. + Configuration of the analog input interrupt delta float object (642B h ) shall also cause a value + change in 6426 h object and vice versa. + */ + uint8_t x6426_analogInputInterruptDeltaUnsigned_bit_sub0; + int32_t x6426_analogInputInterruptDeltaUnsigned_bit[OD_CNT_ARR_6426]; + /* + This object shall set the negative delta value (falling below the last communicated value) for + interrupt-enabled analog inputs (see 6423 h object). + If the object is not supported, the device shall behave according to the default value. + Configuration of the analog input interrupt negative delta float object (642C h ) shall also cause + a value change in the 6427 h object and vice versa. + */ + uint8_t x6427_analogInputInterruptNegativeDeltaUnsigned_bit_sub0; + int32_t x6427_analogInputInterruptNegativeDeltaUnsigned_bit[OD_CNT_ARR_6427]; + /* + This object shall set the positive delta value (rising above the last communicated value) for + interrupt-enabled analog inputs (see 6423 h object). + If the object is not supported, the device shall behave accordingly to the default value. + Configuration of the analog input interrupt positive delta float object (642D h ) shall also cause + a value change in the 6428 h object and vice versa. + */ + uint8_t x6428_analogInputInterruptPositiveDeltaUnsigned_bit_sub0; + int32_t x6428_analogInputInterruptPositiveDeltaUnsigned_bit[OD_CNT_ARR_6428]; + /* + This object shall set the converted upper limits for interrupt-enabled analog inputs (see 6423 h + object). As long as the trigger condition is met, every change of the analog input data + generates a new interrupt, if there is no additional trigger condition, e.g. an input interrupt + delta (642B h ). + If the object is not supported, the device shall behave according to the default value. + Configuration of the analog input interrupt upper limit integer object (6424 h ) shall also cause a + value change in the 6429 h object and vice versa. + */ + uint8_t x6429_analogInputInterruptUpperLimitFloat_bit_sub0; + float32_t x6429_analogInputInterruptUpperLimitFloat_bit[OD_CNT_ARR_6429]; + /* + This object shall set the lower limits for interrupt -enabled analog inputs (see 6423 h object). As + long as the trigger condition is met, every change of the analog input data generates a new + interrupt, if there is no additional trigger condition, e.g. an input interrupt delta (642B h ). + If the object is not supported, the device shall behave accordingly to the default value. + Configuration of the analog input interrupt lower limit integer object (6425 h ) shall also cause a + value change in the 642A h object and vice versa. + */ + uint8_t x642A_analogInputInterruptLowerLimitFloat_bit_sub0; + float32_t x642A_analogInputInterruptLowerLimitFloat_bit[OD_CNT_ARR_642A]; + /* + This object shall set the delta value (rising or falling above or below the last sample) in float + format for interrupt-enabled analog inputs (see 6423 h object). + If the object is not supported, the device shall behave according to the default value. + Configuration of the analog input interrupt delta unsigned object (6426 h) shall also cause a + value change in the 642B h object and vice versa. + */ + uint8_t x642B_analogInputInterruptDeltaFloat_bit_sub0; + float32_t x642B_analogInputInterruptDeltaFloat_bit[OD_CNT_ARR_642B]; + /* + This object shall set the negative delta value (falling below the last sample) in float format for + interrupt-enabled analog inputs (see 6423 h object). + If the object is not supported, the device shall behave according to the default value. + Configuration of the analog input interrupt negative delta unsigned object (6427 h ) shall also + cause a value change in the 642C h object and vice versa. + */ + uint8_t x642C_analogInputInterruptNegativeDeltaFloat_bit_sub0; + float32_t x642C_analogInputInterruptNegativeDeltaFloat_bit[OD_CNT_ARR_642C]; + /* + This object shall set the positive delta value (rising above the last sample) in float format for + interrupt-enabled analog inputs (see 6423 h object). + If the object is not supported, the device shall behave according to the default value. + Configuration of the analog input interrupt positive delta unsigned object (6428 h ) shall also + cause a value change in the 642D h object and vice versa. + */ + uint8_t x642D_analogInputInterruptPositiveDeltaFloat_bit_sub0; + float32_t x642D_analogInputInterruptPositiveDeltaFloat_bit[OD_CNT_ARR_642D]; + /* + This object shall set the offsets in float format for input data (6403 h object) for channel 'n'. + Figure 6 specifies the relationship between the analog input objects for the 16 -bit access. The + analog input offset float value shall be calculated by the formula defined in the sub -clause + 8.4.4. + If the object is not supported, the device shall behave accordingly to 6431 h object, or if that + object is also not supported, the device shall behave accordingly to the default value. + Configuration of the analog input offset integer object (6431 h ) shall also cause a value change + in the 642E h object and vice versa. + */ + uint8_t x642E_analogInputOffsetFloat_bit_sub0; + float32_t x642E_analogInputOffsetFloat_bit[OD_CNT_ARR_642E]; + /* + This object shall set the pre-scaling in float format for input data (6403 h object). Figure 6 + specifies the relationship between the analog input objects for the 16 -bit access. The analog + input pre-scaling float value shall be calculated by the formula defined in the sub -clause 8.4.4. + If the object is not supported, the device shall behave accordingly to 6432 h object, or if that + object is also not supported, the device shall behave accordingly to the default value. + Configuration of the analog input pre-scaling integer object (6432 h ) shall also cause a value + change in the 642F h object and vice versa. + */ + uint8_t x642F_analogInputPreScalingFloat_bit_sub0; + float32_t x642F_analogInputPreScalingFloat_bit[OD_CNT_ARR_642F]; + /* + This object shall assign SI units and prefixes for analog inputs. The value structure is + specified in Figure 9. + 31 Prefix 24 + 23 SI Numerator 16 + 15 SI Denominator 8 + 7 reserved 0 + */ + uint8_t x6430_analogInputSIUnit_bit_sub0; + uint8_t x6430_analogInputSIUnit_bit[OD_CNT_ARR_6430]; + /* + This object shall set the offset in integer format for input data (6403 h object). Figure 6 + specifies the relationship between the analog input objects for the 16 -bit access. The analog + input offset integer value shall be calculated by the formula defined in the sub -clause 8.4.4. + If the object is not supported, the device shall behave according to 642E h object, or if that + object is also not supported, the device shall behave according to the default value. + Configuration of the analog input offset float object (642E h ) shall also cause a value change in + the 6431 h object and vice versa. + */ + uint8_t x6431_analogInputOffsetInteger_bit_sub0; + int32_t x6431_analogInputOffsetInteger_bit[OD_CNT_ARR_6431]; + + /* This object shall set the pre-scaling in integer format or input data (6403 h object). Figure 6 + specifies the relationship between the analog input objects for the 16 -bit access. The analog + input pre-scaling integer value shall be calculated by the formula defined in the sub -clause + 8.4.4. + If the object is not supported, the device shall behave according to 642F h object, or if that + object is also not supported, the device shall behave according to the default value. + Configuration of the analog input pre-scaling float object (642F h ) shall also cause a value + change in the 6432 h object and vice versa. + */ + uint8_t x6432_analogInputPreScalingInteger_bit_sub0; + int32_t x6432_analogInputPreScalingInteger_bit[OD_CNT_ARR_6432]; + + /* This object shall describe the first logical device in a multiple device module according to + /CiA301/. */ + uint32_t x67FF_deviceType; + +} OD_RAM_t; + +typedef struct { + uint32_t x2106_power_onCounter; + uint8_t x2112_variableNV_Int32AutoSave_sub0; + int32_t x2112_variableNV_Int32AutoSave[OD_CNT_ARR_2112]; +} OD_PERSIST_APP_AUTO_t; + +typedef struct { + uint8_t x2111_variableInt32Save_sub0; + int32_t x2111_variableInt32Save[OD_CNT_ARR_2111]; + struct { + uint8_t highestSub_indexSupported; + int64_t I64; + uint64_t U64; + float32_t R32; + float64_t R64; + uint16_t parameterWithDefaultValue; + } x2120_demoRecord; + struct { + uint8_t highestSub_indexSupported; + char stringShort[4]; + char stringLong[1001]; + uint8_t octetString[10]; + } x2121_demoStrings; +} OD_PERSIST_APP_t; + +#ifndef OD_ATTR_PERSIST_COMM +#define OD_ATTR_PERSIST_COMM +#endif +extern OD_ATTR_PERSIST_COMM OD_PERSIST_COMM_t OD_PERSIST_COMM; + +#ifndef OD_ATTR_RAM +#define OD_ATTR_RAM +#endif +extern OD_ATTR_RAM OD_RAM_t OD_RAM; + +#ifndef OD_ATTR_PERSIST_APP_AUTO +#define OD_ATTR_PERSIST_APP_AUTO +#endif +extern OD_ATTR_PERSIST_APP_AUTO OD_PERSIST_APP_AUTO_t OD_PERSIST_APP_AUTO; + +#ifndef OD_ATTR_PERSIST_APP +#define OD_ATTR_PERSIST_APP +#endif +extern OD_ATTR_PERSIST_APP OD_PERSIST_APP_t OD_PERSIST_APP; + +#ifndef OD_ATTR_OD +#define OD_ATTR_OD +#endif +extern OD_ATTR_OD 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_H1008 &OD->list[6] +#define OD_ENTRY_H1009 &OD->list[7] +#define OD_ENTRY_H100A &OD->list[8] +#define OD_ENTRY_H1010 &OD->list[9] +#define OD_ENTRY_H1011 &OD->list[10] +#define OD_ENTRY_H1012 &OD->list[11] +#define OD_ENTRY_H1014 &OD->list[12] +#define OD_ENTRY_H1015 &OD->list[13] +#define OD_ENTRY_H1016 &OD->list[14] +#define OD_ENTRY_H1017 &OD->list[15] +#define OD_ENTRY_H1018 &OD->list[16] +#define OD_ENTRY_H1019 &OD->list[17] +#define OD_ENTRY_H1200 &OD->list[18] +#define OD_ENTRY_H1400 &OD->list[19] +#define OD_ENTRY_H1401 &OD->list[20] +#define OD_ENTRY_H1402 &OD->list[21] +#define OD_ENTRY_H1403 &OD->list[22] +#define OD_ENTRY_H1600 &OD->list[23] +#define OD_ENTRY_H1601 &OD->list[24] +#define OD_ENTRY_H1602 &OD->list[25] +#define OD_ENTRY_H1603 &OD->list[26] +#define OD_ENTRY_H1800 &OD->list[27] +#define OD_ENTRY_H1801 &OD->list[28] +#define OD_ENTRY_H1802 &OD->list[29] +#define OD_ENTRY_H1803 &OD->list[30] +#define OD_ENTRY_H1A00 &OD->list[31] +#define OD_ENTRY_H1A01 &OD->list[32] +#define OD_ENTRY_H1A02 &OD->list[33] +#define OD_ENTRY_H1A03 &OD->list[34] +#define OD_ENTRY_H2100 &OD->list[35] +#define OD_ENTRY_H2106 &OD->list[36] +#define OD_ENTRY_H2110 &OD->list[37] +#define OD_ENTRY_H2111 &OD->list[38] +#define OD_ENTRY_H2112 &OD->list[39] +#define OD_ENTRY_H2120 &OD->list[40] +#define OD_ENTRY_H2121 &OD->list[41] +#define OD_ENTRY_H2122 &OD->list[42] +#define OD_ENTRY_H6000 &OD->list[43] +#define OD_ENTRY_H6002 &OD->list[44] +#define OD_ENTRY_H6003 &OD->list[45] +#define OD_ENTRY_H6005 &OD->list[46] +#define OD_ENTRY_H6006 &OD->list[47] +#define OD_ENTRY_H6007 &OD->list[48] +#define OD_ENTRY_H6008 &OD->list[49] +#define OD_ENTRY_H6020 &OD->list[50] +#define OD_ENTRY_H6030 &OD->list[51] +#define OD_ENTRY_H6038 &OD->list[52] +#define OD_ENTRY_H6050 &OD->list[53] +#define OD_ENTRY_H6060 &OD->list[54] +#define OD_ENTRY_H6070 &OD->list[55] +#define OD_ENTRY_H6100 &OD->list[56] +#define OD_ENTRY_H6102 &OD->list[57] +#define OD_ENTRY_H6103 &OD->list[58] +#define OD_ENTRY_H6106 &OD->list[59] +#define OD_ENTRY_H6107 &OD->list[60] +#define OD_ENTRY_H6108 &OD->list[61] +#define OD_ENTRY_H6120 &OD->list[62] +#define OD_ENTRY_H6122 &OD->list[63] +#define OD_ENTRY_H6123 &OD->list[64] +#define OD_ENTRY_H6126 &OD->list[65] +#define OD_ENTRY_H6127 &OD->list[66] +#define OD_ENTRY_H6128 &OD->list[67] +#define OD_ENTRY_H6200 &OD->list[68] +#define OD_ENTRY_H6202 &OD->list[69] +#define OD_ENTRY_H6206 &OD->list[70] +#define OD_ENTRY_H6207 &OD->list[71] +#define OD_ENTRY_H6208 &OD->list[72] +#define OD_ENTRY_H6220 &OD->list[73] +#define OD_ENTRY_H6240 &OD->list[74] +#define OD_ENTRY_H6250 &OD->list[75] +#define OD_ENTRY_H6260 &OD->list[76] +#define OD_ENTRY_H6270 &OD->list[77] +#define OD_ENTRY_H6300 &OD->list[78] +#define OD_ENTRY_H6302 &OD->list[79] +#define OD_ENTRY_H6306 &OD->list[80] +#define OD_ENTRY_H6307 &OD->list[81] +#define OD_ENTRY_H6308 &OD->list[82] +#define OD_ENTRY_H6320 &OD->list[83] +#define OD_ENTRY_H6322 &OD->list[84] +#define OD_ENTRY_H6326 &OD->list[85] +#define OD_ENTRY_H6327 &OD->list[86] +#define OD_ENTRY_H6328 &OD->list[87] +#define OD_ENTRY_H6400 &OD->list[88] +#define OD_ENTRY_H6401 &OD->list[89] +#define OD_ENTRY_H6402 &OD->list[90] +#define OD_ENTRY_H6410 &OD->list[91] +#define OD_ENTRY_H6411 &OD->list[92] +#define OD_ENTRY_H6412 &OD->list[93] +#define OD_ENTRY_H6421 &OD->list[94] +#define OD_ENTRY_H6422 &OD->list[95] +#define OD_ENTRY_H6423 &OD->list[96] +#define OD_ENTRY_H6424 &OD->list[97] +#define OD_ENTRY_H6425 &OD->list[98] +#define OD_ENTRY_H6426 &OD->list[99] +#define OD_ENTRY_H6427 &OD->list[100] +#define OD_ENTRY_H6428 &OD->list[101] +#define OD_ENTRY_H6429 &OD->list[102] +#define OD_ENTRY_H642A &OD->list[103] +#define OD_ENTRY_H642B &OD->list[104] +#define OD_ENTRY_H642C &OD->list[105] +#define OD_ENTRY_H642D &OD->list[106] +#define OD_ENTRY_H642E &OD->list[107] +#define OD_ENTRY_H642F &OD->list[108] +#define OD_ENTRY_H6430 &OD->list[109] +#define OD_ENTRY_H6431 &OD->list[110] +#define OD_ENTRY_H6432 &OD->list[111] +#define OD_ENTRY_H67FF &OD->list[112] + +/******************************************************************************* + 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_H1008_manufacturerDeviceName &OD->list[6] +#define OD_ENTRY_H1009_manufacturerHardwareVersion &OD->list[7] +#define OD_ENTRY_H100A_manufacturerSoftwareVersion &OD->list[8] +#define OD_ENTRY_H1010_storeParameters &OD->list[9] +#define OD_ENTRY_H1011_restoreDefaultParameters &OD->list[10] +#define OD_ENTRY_H1012_COB_IDTimeStampObject &OD->list[11] +#define OD_ENTRY_H1014_COB_ID_EMCY &OD->list[12] +#define OD_ENTRY_H1015_inhibitTimeEMCY &OD->list[13] +#define OD_ENTRY_H1016_consumerHeartbeatTime &OD->list[14] +#define OD_ENTRY_H1017_producerHeartbeatTime &OD->list[15] +#define OD_ENTRY_H1018_identity &OD->list[16] +#define OD_ENTRY_H1019_synchronousCounterOverflowValue &OD->list[17] +#define OD_ENTRY_H1200_SDOServerParameter &OD->list[18] +#define OD_ENTRY_H1400_RPDOCommunicationParameter &OD->list[19] +#define OD_ENTRY_H1401_RPDOCommunicationParameter &OD->list[20] +#define OD_ENTRY_H1402_RPDOCommunicationParameter &OD->list[21] +#define OD_ENTRY_H1403_RPDOCommunicationParameter &OD->list[22] +#define OD_ENTRY_H1600_RPDOMappingParameter &OD->list[23] +#define OD_ENTRY_H1601_RPDOMappingParameter &OD->list[24] +#define OD_ENTRY_H1602_RPDOMappingParameter &OD->list[25] +#define OD_ENTRY_H1603_RPDOMappingParameter &OD->list[26] +#define OD_ENTRY_H1800_TPDOCommunicationParameter &OD->list[27] +#define OD_ENTRY_H1801_TPDOCommunicationParameter &OD->list[28] +#define OD_ENTRY_H1802_TPDOCommunicationParameter &OD->list[29] +#define OD_ENTRY_H1803_TPDOCommunicationParameter &OD->list[30] +#define OD_ENTRY_H1A00_TPDOMappingParameter &OD->list[31] +#define OD_ENTRY_H1A01_TPDOMappingParameter &OD->list[32] +#define OD_ENTRY_H1A02_TPDOMappingParameter &OD->list[33] +#define OD_ENTRY_H1A03_TPDOMappingParameter &OD->list[34] +#define OD_ENTRY_H2100_errorStatusBits &OD->list[35] +#define OD_ENTRY_H2106_power_onCounter &OD->list[36] +#define OD_ENTRY_H2110_variableInt32 &OD->list[37] +#define OD_ENTRY_H2111_variableInt32Save &OD->list[38] +#define OD_ENTRY_H2112_variableNV_Int32AutoSave &OD->list[39] +#define OD_ENTRY_H2120_demoRecord &OD->list[40] +#define OD_ENTRY_H2121_demoStrings &OD->list[41] +#define OD_ENTRY_H2122_demoDomain &OD->list[42] +#define OD_ENTRY_H6000_readDigitalInput8_bit &OD->list[43] +#define OD_ENTRY_H6002_polarityDigitalInput8_bit &OD->list[44] +#define OD_ENTRY_H6003_digitalFilterEnable8_bit &OD->list[45] +#define OD_ENTRY_H6005_globalInterruptEnableDigital8_bit &OD->list[46] +#define OD_ENTRY_H6006_digitalInterruptMaskAnyChange8_bit &OD->list[47] +#define OD_ENTRY_H6007_digitalInterruptMaskLowToHigh8_bit &OD->list[48] +#define OD_ENTRY_H6008_digitalInterruptMaskHighToLow8_bit &OD->list[49] +#define OD_ENTRY_H6020_readDigitalInputBit1To128 &OD->list[50] +#define OD_ENTRY_H6030_polarityDigitalInputBit1To128 &OD->list[51] +#define OD_ENTRY_H6038_filterConstantDigitalInputBit1To128 &OD->list[52] +#define OD_ENTRY_H6050_interruptMaskDigitalInputAnyChange1To128 &OD->list[53] +#define OD_ENTRY_H6060_interruptMaskDigitalInputLowToHigh1To128 &OD->list[54] +#define OD_ENTRY_H6070_interruptMaskDigitalInputHighToLow1To128 &OD->list[55] +#define OD_ENTRY_H6100_readDigitalInput16_bit &OD->list[56] +#define OD_ENTRY_H6102_polarityDigitalInput16_bit &OD->list[57] +#define OD_ENTRY_H6103_digitalFilterEnable16_bit &OD->list[58] +#define OD_ENTRY_H6106_interruptMaskDigitalInputAnyChange16_bit &OD->list[59] +#define OD_ENTRY_H6107_interruptMaskDigitalInputLowToHigh16_bit &OD->list[60] +#define OD_ENTRY_H6108_interruptMaskDigitalInputHighToLow16_bit &OD->list[61] +#define OD_ENTRY_H6120_readDigitalInput32_bit &OD->list[62] +#define OD_ENTRY_H6122_polarityDigitalInput32_bit &OD->list[63] +#define OD_ENTRY_H6123_digitalFilterEnable32_bit &OD->list[64] +#define OD_ENTRY_H6126_interruptMaskDigitalInputAnyChange32_bit &OD->list[65] +#define OD_ENTRY_H6127_interruptMaskDigitalInputLowToHigh32_bit &OD->list[66] +#define OD_ENTRY_H6128_interruptMaskDigitalInputHighToLow32_bit &OD->list[67] +#define OD_ENTRY_H6200_writeDigitalOutput8_bit &OD->list[68] +#define OD_ENTRY_H6202_changePolarityDigitalOutput8_bit &OD->list[69] +#define OD_ENTRY_H6206_errorModeDigitalOutput8_bit &OD->list[70] +#define OD_ENTRY_H6207_errorValueDigitalOutput8_bit &OD->list[71] +#define OD_ENTRY_H6208_filterMaskDigitalOutput8_bit &OD->list[72] +#define OD_ENTRY_H6220_writeDigitalOutputBit1To128 &OD->list[73] +#define OD_ENTRY_H6240_changePolarityDigitalOutputBit1To128 &OD->list[74] +#define OD_ENTRY_H6250_errorModeDigitalOutputLines1To128 &OD->list[75] +#define OD_ENTRY_H6260_errorValueDigitalOutputBit1To128 &OD->list[76] +#define OD_ENTRY_H6270_filterMaskDigitalOutputBit1To128 &OD->list[77] +#define OD_ENTRY_H6300_writeDigitalOutput16_bit &OD->list[78] +#define OD_ENTRY_H6302_changePolarityDigitalOutput16_bit &OD->list[79] +#define OD_ENTRY_H6306_errorModeDigitalOutput16_bit &OD->list[80] +#define OD_ENTRY_H6307_errorValueDigitalOutput16_bit &OD->list[81] +#define OD_ENTRY_H6308_filterMaskDigitalOutput16_bit &OD->list[82] +#define OD_ENTRY_H6320_writeDigitalOutput32_bit &OD->list[83] +#define OD_ENTRY_H6322_changePolarityDigitalOutput32_bit &OD->list[84] +#define OD_ENTRY_H6326_errorModeDigitalOutput32_bit &OD->list[85] +#define OD_ENTRY_H6327_errorValueDigitalOutput32_bit &OD->list[86] +#define OD_ENTRY_H6328_filterMaskDigitalOutput32_bit &OD->list[87] +#define OD_ENTRY_H6400_readAnalogInput8_bit &OD->list[88] +#define OD_ENTRY_H6401_readAnalogInput16_bit &OD->list[89] +#define OD_ENTRY_H6402_readAnalogInput32_bit &OD->list[90] +#define OD_ENTRY_H6410_writeAnalogOutput8_bit &OD->list[91] +#define OD_ENTRY_H6411_writeAnalogOutput16_bit &OD->list[92] +#define OD_ENTRY_H6412_writeAnalogOutput32_bit &OD->list[93] +#define OD_ENTRY_H6421_analogInputInterruptTriggerSelection_bit &OD->list[94] +#define OD_ENTRY_H6422_analogInputInterruptSource_bit &OD->list[95] +#define OD_ENTRY_H6423_analogInputGlobalInterruptEnable &OD->list[96] +#define OD_ENTRY_H6424_analogInputUpperLimitInteger_bit &OD->list[97] +#define OD_ENTRY_H6425_analogInputLowerLimitInteger_bit &OD->list[98] +#define OD_ENTRY_H6426_analogInputInterruptDeltaUnsigned_bit &OD->list[99] +#define OD_ENTRY_H6427_analogInputInterruptNegativeDeltaUnsigned_bit &OD->list[100] +#define OD_ENTRY_H6428_analogInputInterruptPositiveDeltaUnsigned_bit &OD->list[101] +#define OD_ENTRY_H6429_analogInputInterruptUpperLimitFloat_bit &OD->list[102] +#define OD_ENTRY_H642A_analogInputInterruptLowerLimitFloat_bit &OD->list[103] +#define OD_ENTRY_H642B_analogInputInterruptDeltaFloat_bit &OD->list[104] +#define OD_ENTRY_H642C_analogInputInterruptNegativeDeltaFloat_bit &OD->list[105] +#define OD_ENTRY_H642D_analogInputInterruptPositiveDeltaFloat_bit &OD->list[106] +#define OD_ENTRY_H642E_analogInputOffsetFloat_bit &OD->list[107] +#define OD_ENTRY_H642F_analogInputPreScalingFloat_bit &OD->list[108] +#define OD_ENTRY_H6430_analogInputSIUnit_bit &OD->list[109] +#define OD_ENTRY_H6431_analogInputOffsetInteger_bit &OD->list[110] +#define OD_ENTRY_H6432_analogInputPreScalingInteger_bit &OD->list[111] +#define OD_ENTRY_H67FF_deviceType &OD->list[112] + +/******************************************************************************* + OD config structure +*******************************************************************************/ +#ifdef CO_MULTIPLE_OD +#define OD_INIT_CONFIG(config) \ + { \ + (config).CNT_NMT = OD_CNT_NMT; \ + (config).ENTRY_H1017 = OD_ENTRY_H1017; \ + (config).CNT_HB_CONS = OD_CNT_HB_CONS; \ + (config).CNT_ARR_1016 = OD_CNT_ARR_1016; \ + (config).ENTRY_H1016 = OD_ENTRY_H1016; \ + (config).CNT_EM = OD_CNT_EM; \ + (config).ENTRY_H1001 = OD_ENTRY_H1001; \ + (config).ENTRY_H1014 = OD_ENTRY_H1014; \ + (config).ENTRY_H1015 = OD_ENTRY_H1015; \ + (config).CNT_ARR_1003 = OD_CNT_ARR_1003; \ + (config).ENTRY_H1003 = OD_ENTRY_H1003; \ + (config).CNT_SDO_SRV = OD_CNT_SDO_SRV; \ + (config).ENTRY_H1200 = OD_ENTRY_H1200; \ + (config).CNT_SDO_CLI = OD_CNT_SDO_CLI; \ + (config).ENTRY_H1280 = OD_ENTRY_H1280; \ + (config).CNT_TIME = OD_CNT_TIME; \ + (config).ENTRY_H1012 = OD_ENTRY_H1012; \ + (config).CNT_SYNC = OD_CNT_SYNC; \ + (config).ENTRY_H1005 = OD_ENTRY_H1005; \ + (config).ENTRY_H1006 = OD_ENTRY_H1006; \ + (config).ENTRY_H1007 = OD_ENTRY_H1007; \ + (config).ENTRY_H1019 = OD_ENTRY_H1019; \ + (config).CNT_RPDO = OD_CNT_RPDO; \ + (config).ENTRY_H1400 = OD_ENTRY_H1400; \ + (config).ENTRY_H1600 = OD_ENTRY_H1600; \ + (config).CNT_TPDO = OD_CNT_TPDO; \ + (config).ENTRY_H1800 = OD_ENTRY_H1800; \ + (config).ENTRY_H1A00 = OD_ENTRY_H1A00; \ + (config).CNT_LEDS = 0; \ + (config).CNT_GFC = 0; \ + (config).ENTRY_H1300 = NULL; \ + (config).CNT_SRDO = 0; \ + (config).ENTRY_H1301 = NULL; \ + (config).ENTRY_H1381 = NULL; \ + (config).ENTRY_H13FE = NULL; \ + (config).ENTRY_H13FF = NULL; \ + (config).CNT_LSS_SLV = 0; \ + (config).CNT_LSS_MST = 0; \ + (config).CNT_GTWA = 0; \ + (config).CNT_TRACE = 0; \ + } +#endif + +#endif /* OD_H */ diff --git a/OD/domainDemo.c b/OD/domainDemo.c new file mode 100644 index 0000000..6af0ca0 --- /dev/null +++ b/OD/domainDemo.c @@ -0,0 +1,157 @@ +/** + * Example access to the Object Dictionary variable of type domain. + * + * @file domainDemo.c + * @author -- + * @copyright 2021 -- + * + * This file is part of CANopenNode, an opensource CANopen Stack. + * Project home page is . + * For more information on CANopen see . + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "domainDemo.h" + +#ifndef DOMAIN_DEMO_LENGTH_INDICATE +#define DOMAIN_DEMO_LENGTH_INDICATE 1 +#endif + +/* Global variables are used here for simplicity. */ +/* Data simulation for domain */ +static uint8_t dataSimulated = 0; +/* Index of current data byte transferred. */ +static OD_size_t dataIndex = 0; +/* Size of data to be transferred. It is used when reading domainDemo + * and updated after writing domainDemo. */ +static OD_size_t dataSize = 1024; +/* Extension for OD object OD_domainDemo */ +static OD_extension_t domainDemo_extension; + +/* + * Custom function for reading OD object _domainDemo_ + * + * For more information see file CO_ODinterface.h, OD_IO_t. + */ +static ODR_t OD_read_domainDemo(OD_stream_t* stream, void* buf, OD_size_t count, OD_size_t* countRead) { + if (stream == NULL || buf == NULL || countRead == NULL || stream->subIndex != 0) { + return ODR_DEV_INCOMPAT; + } + + /* Data is simple repeating sequence of values 0..255. Data can be much + * longer than count (available size of the buffer). So + * OD_read_domainDemo() may be called multiple times. */ + if (stream->dataOffset == 0) { + /* Data offset is 0, so this is the first call of this function + * in current (SDO) communication. Initialize variables. */ + dataSimulated = 0; + dataIndex = 0; +#if DOMAIN_DEMO_LENGTH_INDICATE > 0 + /* Indicate dataLength */ + size_t dataLen = dataSize; + stream->dataLength = dataLen <= 0xFFFFFFFF ? dataLen : 0; +#else + /* It is not required to indicate data length in SDO transfer */ + stream->dataLength = 0; +#endif + } + + /* copy application data into buf */ + OD_size_t i; + for (i = 0; i < count; i++) { + uint8_t* bufU8 = (uint8_t*)buf; + if (dataIndex >= dataSize) { + break; + } + bufU8[i] = dataSimulated++; + dataIndex++; + } + *countRead = i; + + /* finished? */ + if (dataIndex >= dataSize) { + stream->dataOffset = 0; + return ODR_OK; + } + + /* indicate partial read, this function will be called again. */ + stream->dataOffset = dataIndex; + return ODR_PARTIAL; +} + +/* + * Custom function for reading OD object _domainDemo_ + * + * For more information see file CO_ODinterface.h, OD_IO_t. + */ +static ODR_t OD_write_domainDemo(OD_stream_t* stream, const void* buf, OD_size_t count, OD_size_t* countWritten) { + if (stream == NULL || buf == NULL || countWritten == NULL || stream->subIndex != 0) { + return ODR_DEV_INCOMPAT; + } + + /* Data will be just verified for correct sequence in this example + * (repeating sequence of values 0..255). Data can be much longer than + * count (current size of data in the buffer). So OD_write_domainDemo() may + * be called multiple times. */ + if (stream->dataOffset == 0) { + /* Data offset is 0, so this is the first call of this function + * in current SDO communication. Initialize variables. */ + dataSimulated = 0; + dataIndex = 0; + } + + /* copy received data into application */ + OD_size_t i; + for (i = 0; i < count; i++) { + uint8_t* bufU8 = (uint8_t*)buf; + /* for simulation just verify, if received data is in sequence */ + if (bufU8[i] != dataSimulated++) { + return ODR_INVALID_VALUE; + } + dataIndex++; + } + *countWritten = i; + stream->dataOffset = dataIndex; + + /* determine, if file write finished or not (dataLength may not yet be + * indicated) */ + if (stream->dataLength > 0 && stream->dataOffset >= stream->dataLength) { + stream->dataOffset = 0; + /* Simulation - set data size to data size currently written. */ + dataSize = dataIndex; + return ODR_OK; + } + + /* indicate partial write, this function will be called again. */ + return ODR_PARTIAL; +} + +/******************************************************************************/ +CO_ReturnError_t domainDemo_init(OD_entry_t* OD_domainDemo, uint32_t* errInfo) { + if (OD_domainDemo == NULL || errInfo == NULL) + return CO_ERROR_ILLEGAL_ARGUMENT; + + /* Initialize custom OD object "domainDemo" */ + domainDemo_extension.object = NULL; + domainDemo_extension.read = OD_read_domainDemo; + domainDemo_extension.write = OD_write_domainDemo; + ODR_t odRet = OD_extension_init(OD_domainDemo, &domainDemo_extension); + + if (odRet != ODR_OK) { + *errInfo = OD_getIndex(OD_domainDemo); + return CO_ERROR_OD_PARAMETERS; + } + + return CO_ERROR_NO; +} diff --git a/OD/domainDemo.h b/OD/domainDemo.h new file mode 100644 index 0000000..d8a58cc --- /dev/null +++ b/OD/domainDemo.h @@ -0,0 +1,48 @@ +/** + * Example access to the Object Dictionary variable of type domain. + * + * @file domainDemo.h + * @author -- + * @copyright 2021 -- + * + * This file is part of CANopenNode, an opensource CANopen Stack. + * Project home page is . + * For more information on CANopen see . + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef domainDemo_H +#define domainDemo_H + +#include "301/CO_ODinterface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Initialize domainDemo object. + * + * @param OD_domainDemo Object Dictionary entry for domainDemo. + * @param [out] errInfo If OD entry is erroneous, errInfo indicates its index. + * + * @return @ref CO_ReturnError_t CO_ERROR_NO in case of success. + */ +CO_ReturnError_t domainDemo_init(OD_entry_t* OD_domainDemo, uint32_t* errInfo); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* domainDemo_H */ diff --git a/OD/objectAccessOD.c b/OD/objectAccessOD.c new file mode 100644 index 0000000..7278b81 --- /dev/null +++ b/OD/objectAccessOD.c @@ -0,0 +1,170 @@ +/* + * Example object oriented access to the Object Dictionary variable. + * + * @file objectAccessOD.c + * @author -- + * @copyright 2021 -- + * + * This file is part of CANopenNode, an opensource CANopen Stack. + * Project home page is . + * For more information on CANopen see . + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "objectAccessOD.h" + +#define SUBIDX_I64 0x01 +#define SUBIDX_U64 0x02 +#define SUBIDX_R32 0x03 +#define SUBIDX_R64 0x04 +#define SUBIDX_AVERAGE 0x05 +#define SUBIDX_PARAMETER 0x06 + +/* + * Custom function for reading OD object _demoRecord_ + * + * For more information see file CO_ODinterface.h, OD_IO_t. + */ +static ODR_t OD_read_demoRecord(OD_stream_t* stream, void* buf, OD_size_t count, OD_size_t* countRead) { + if (stream == NULL || buf == NULL || countRead == NULL) { + return ODR_DEV_INCOMPAT; + } + + /* Object was passed by OD_extensionIO_init, use correct type. */ + objectAccessOD_t* thisObj = (objectAccessOD_t*)stream->object; + + switch (stream->subIndex) { + case SUBIDX_AVERAGE: { + OD_size_t varSize = sizeof(float64_t); + + if (count < varSize || stream->dataLength != varSize) { + return ODR_DEV_INCOMPAT; + } + + float64_t average = (float64_t)*thisObj->i64; + average += (float64_t)*thisObj->u64; + average += (float64_t)*thisObj->r32; + average += *thisObj->r64; + average /= 4; + + memcpy(buf, &average, varSize); + + *countRead = varSize; + return ODR_OK; + } + + case SUBIDX_PARAMETER: { + uint16_t paramU16 = (uint16_t)(thisObj->internalParameter / 1000); + OD_size_t varSize = sizeof(paramU16); + + if (count < varSize || stream->dataLength != varSize) { + return ODR_DEV_INCOMPAT; + } + + CO_setUint16(buf, paramU16); + + *countRead = varSize; + return ODR_OK; + } + + default: { + return OD_readOriginal(stream, buf, count, countRead); + } + } +} + +/* + * Custom function for reading OD object _demoRecord_ + * + * For more information see file CO_ODinterface.h, OD_IO_t. + */ +static ODR_t OD_write_demoRecord(OD_stream_t* stream, const void* buf, OD_size_t count, OD_size_t* countWritten) { + if (stream == NULL || buf == NULL || countWritten == NULL) { + return ODR_DEV_INCOMPAT; + } + + /* Object was passed by OD_extensionIO_init, use correct type. */ + objectAccessOD_t* thisObj = (objectAccessOD_t*)stream->object; + + switch (stream->subIndex) { + case SUBIDX_PARAMETER: { + uint16_t paramU16 = CO_getUint16(buf); + thisObj->internalParameter = (uint32_t)paramU16 * 1000; + + /* write value to the original location in the Object Dictionary */ + return OD_writeOriginal(stream, buf, count, countWritten); + } + + default: { + return OD_writeOriginal(stream, buf, count, countWritten); + } + } +} + +/******************************************************************************/ +CO_ReturnError_t objectAccessOD_init(objectAccessOD_t* thisObj, OD_entry_t* OD_demoRecord, uint32_t* errInfo) { + if (thisObj == NULL || errInfo == NULL || OD_demoRecord == NULL) + return CO_ERROR_ILLEGAL_ARGUMENT; + + CO_ReturnError_t err = CO_ERROR_NO; + ODR_t odRet; + + /* initialize object variables */ + memset(thisObj, 0, sizeof(objectAccessOD_t)); + + /* Initialize custom OD object "demoRecord" */ + thisObj->OD_demoRecord_extension.object = thisObj; + thisObj->OD_demoRecord_extension.read = OD_read_demoRecord; + thisObj->OD_demoRecord_extension.write = OD_write_demoRecord; + odRet = OD_extension_init(OD_demoRecord, &thisObj->OD_demoRecord_extension); + + /* This is strict behavior and will exit the program on error. Error + * checking on all OD functions can also be omitted. In that case program + * will run, but specific OD entry may not be accessible. */ + if (odRet != ODR_OK) { + *errInfo = OD_getIndex(OD_demoRecord); + return CO_ERROR_OD_PARAMETERS; + } + + /* Get variables from Object dictionary, related to "Average" */ + thisObj->i64 = OD_getPtr(OD_demoRecord, SUBIDX_I64, sizeof(int64_t), NULL); + thisObj->u64 = OD_getPtr(OD_demoRecord, SUBIDX_U64, sizeof(uint64_t), NULL); + thisObj->r32 = OD_getPtr(OD_demoRecord, SUBIDX_R32, sizeof(float32_t), NULL); + thisObj->r64 = OD_getPtr(OD_demoRecord, SUBIDX_R64, sizeof(float64_t), NULL); + + if (thisObj->i64 == NULL || thisObj->u64 == NULL || thisObj->r32 == NULL || thisObj->r64 == NULL) { + *errInfo = OD_getIndex(OD_demoRecord); + return CO_ERROR_OD_PARAMETERS; + } + + /* Sub entry SUBIDX_AVERAGE will be read by application via + * OD_read_demoRecord() function. Initialize structure "io_average" here. */ + odRet = OD_getSub(OD_demoRecord, SUBIDX_AVERAGE, &thisObj->io_average, false); + if (odRet != ODR_OK) { + *errInfo = OD_getIndex(OD_demoRecord); + return CO_ERROR_OD_PARAMETERS; + } + + /* Get variable 'Parameter with default value' from Object dictionary */ + uint16_t parameterU16; + odRet = OD_get_u16(OD_demoRecord, SUBIDX_PARAMETER, ¶meterU16, true); + + if (odRet != ODR_OK) { + *errInfo = OD_getIndex(OD_demoRecord); + return CO_ERROR_OD_PARAMETERS; + } + thisObj->internalParameter = (uint32_t)parameterU16 * 1000; + + return err; +} diff --git a/OD/objectAccessOD.h b/OD/objectAccessOD.h new file mode 100644 index 0000000..8a7738c --- /dev/null +++ b/OD/objectAccessOD.h @@ -0,0 +1,91 @@ +/** + * Example object oriented access to the Object Dictionary variable. + * + * @file objectAccessOD.h + * @author -- + * @copyright 2021 -- + * + * This file is part of CANopenNode, an opensource CANopen Stack. + * Project home page is . + * For more information on CANopen see . + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef objectAccessOD_H +#define objectAccessOD_H + +#include "301/CO_ODinterface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Object declaration for objectAccessOD. + */ +typedef struct { + OD_extension_t OD_demoRecord_extension; /**< Extension for OD object */ + OD_IO_t io_average; /**< object for read access to sub-OD variable average*/ + int64_t* i64; /**< Pointer to variable in object dictionary */ + uint64_t* u64; /**< Pointer to variable in object dictionary */ + float32_t* r32; /**< Pointer to variable in object dictionary */ + float64_t* r64; /**< Pointer to variable in object dictionary */ + /** Variable initialised from OD sub-entry 'Parameter with default value' */ + uint32_t internalParameter; +} objectAccessOD_t; + +/** + * Initialize objectAccessOD object. + * + * @param thisObj This object will be initialized. + * @param OD_demoRecord Object Dictionary entry for demoRecord. + * @param [out] errInfo If OD entry is erroneous, errInfo indicates its index. + * + * @return @ref CO_ReturnError_t CO_ERROR_NO in case of success. + */ +CO_ReturnError_t objectAccessOD_init(objectAccessOD_t* thisObj, OD_entry_t* OD_demoRecord, uint32_t* errInfo); + +/** + * Read "average" variable from Object Dictionary + * + * This is a demonstration of extended OD variable. OD variable is not accessed + * from memory location, because it does not exist. Average is calculated from + * internal values, so function access is necessary. "read" function specified + * by OD_extension_init() is called. For "read" function to use, + * "OD_IO_t io_average" structure has been initialized before. If + * objectAccessOD_readAverage() is used from mainline, it has to be protected + * with CO_LOCK_OD / CO_UNLOCK_OD macros as every access to OD variable from + * mainline. + * + * @param thisObj This object contains access information to "average" parameter + * + * @return Value of the parameter. + */ +static inline float64_t objectAccessOD_readAverage(objectAccessOD_t* thisObj) { + float64_t average = 0; + OD_size_t countRd; + + ODR_t odRet = thisObj->io_average.read(&thisObj->io_average.stream, &average, sizeof(average), &countRd); + + (void)odRet; + (void)countRd; /* unused */ + + return average; +} + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* objectAccessOD_H */ diff --git a/drivers/CO_storageBlank.c b/drivers/CO_storageBlank.c new file mode 100644 index 0000000..78c8c5a --- /dev/null +++ b/drivers/CO_storageBlank.c @@ -0,0 +1,112 @@ +/* + * CANopen Object Dictionary storage object (blank example). + * + * @file CO_storageBlank.c + * @author Janez Paternoster + * @copyright 2021 Janez Paternoster + * + * This file is part of , a CANopen Stack. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +#include "CO_storageBlank.h" + +#if (CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE + +/* + * Function for writing data on "Store parameters" command - OD object 1010 + * + * For more information see file CO_storage.h, CO_storage_entry_t. + */ +static ODR_t storeBlank(CO_storage_entry_t* entry, CO_CANmodule_t* CANmodule) { + /* Open a file and write data to it */ + /* file = open(entry->pathToFileOrPointerToMemory); */ + /* write(entry->addr, entry->len, file); */ + + return ODR_OK; +} + +/* + * Function for restoring data on "Restore default parameters" command - OD 1011 + * + * For more information see file CO_storage.h, CO_storage_entry_t. + */ +static ODR_t restoreBlank(CO_storage_entry_t* entry, CO_CANmodule_t* CANmodule) { + /* disable (delete) the file, so default values will stay after startup */ + + return ODR_OK; +} + +CO_ReturnError_t CO_storageBlank_init(CO_storage_t* storage, + CO_CANmodule_t* CANmodule, + OD_entry_t* OD_1010_StoreParameters, + OD_entry_t* OD_1011_RestoreDefaultParam, + CO_storage_entry_t* entries, + uint8_t entriesCount, + uint32_t* storageInitError) { + CO_ReturnError_t ret; + + /* verify arguments */ + if (storage == NULL || entries == NULL || entriesCount == 0 || storageInitError == NULL) { + return CO_ERROR_ILLEGAL_ARGUMENT; + } + + /* initialize storage and OD extensions */ + ret = CO_storage_init(storage, CANmodule, OD_1010_StoreParameters, OD_1011_RestoreDefaultParam, storeBlank, + restoreBlank, entries, entriesCount); + if (ret != CO_ERROR_NO) { + return ret; + } + + /* initialize entries */ + *storageInitError = 0; + for (uint8_t i = 0; i < entriesCount; i++) { + CO_storage_entry_t* entry = &entries[i]; + + /* verify arguments */ + if (entry->addr == NULL || entry->len == 0 || entry->subIndexOD < 2) { + *storageInitError = i; + return CO_ERROR_ILLEGAL_ARGUMENT; + } + + /* Open a file and read data from file to entry->addr */ + /* file = open(entry->pathToFileOrPointerToMemory); */ + /* read(entry->addr, entry->len, file); */ + } + + return ret; +} + +CO_ReturnError_t CO_storageBlank_auto_process(CO_storage_t* storage, bool_t saveAll) { + /* verify arguments */ + if (storage == NULL || !storage->enabled) { + return CO_ERROR_ILLEGAL_ARGUMENT; + } + + /* loop through entries */ + for (uint8_t n = 0; n < storage->entriesCount; n++) { + CO_storage_entry_t* entry = &storage->entries[n]; + + if ((entry->attr & (uint8_t)CO_storage_auto) == 0) { + continue; + } + + if (saveAll) { + /* close the file */ + } else { + /* Open a file and write data to it */ + } + } + + return CO_ERROR_NO; +} + +#endif /* (CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE */ diff --git a/drivers/CO_storageBlank.h b/drivers/CO_storageBlank.h new file mode 100644 index 0000000..f50c9f9 --- /dev/null +++ b/drivers/CO_storageBlank.h @@ -0,0 +1,55 @@ +/* + * CANopen data storage object (blank example) + * + * @file CO_storageBlank.h + * @author Janez Paternoster + * @copyright 2021 Janez Paternoster + * + * This file is part of , a CANopen Stack. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +#ifndef CO_STORAGE_BLANK_H +#define CO_STORAGE_BLANK_H + +#include "storage/CO_storage.h" + +#if ((CO_CONFIG_STORAGE)&CO_CONFIG_STORAGE_ENABLE) || defined CO_DOXYGEN + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This is very basic example of implementing (object dictionary) data storage. Data storage is target specific. + * CO_storageBlank.h and .c files only shows the basic principle, but does nothing. For complete example of storage see: + * - CANopenPIC/PIC32 uses eeprom with CANopenNode/storage/CO_storage.h/.c, CANopenNode/storage/CO_storageEeprom.h/.c, + * CANopenNode/storage/CO_eeprom.h and CANopenPIC/PIC32/CO_eepromPIC32.c files. + * - CANopenLinux uses file system with CANopenNode/storage/CO_storage.h/.c and CANopenLinux/CO_storageLinux.h files. + */ + +CO_ReturnError_t CO_storageBlank_init(CO_storage_t* storage, + CO_CANmodule_t* CANmodule, + OD_entry_t* OD_1010_StoreParameters, + OD_entry_t* OD_1011_RestoreDefaultParam, + CO_storage_entry_t* entries, + uint8_t entriesCount, + uint32_t* storageInitError); + +CO_ReturnError_t CO_storageBlank_auto_process(CO_storage_t* storage, bool_t closeFiles); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* (CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE */ + +#endif /* CO_STORAGE_BLANK_H */ diff --git a/test_performance_example.c b/test_performance_example.c new file mode 100644 index 0000000..3a63f33 --- /dev/null +++ b/test_performance_example.c @@ -0,0 +1,67 @@ +#include "can_controller_factory.h" +#include "canopen_controller_factory.h" +#include "database_factory.h" +#include "debug.h" +#include "rp2040_regs.h" +#include "timer_controller_factory.h" + +int main (){ + CanOpenInterface* canopen = getCanOpenFactory(); + CanInterface* can = getCanFactory(); + TimerInterface* timer = getTimerControllerFactory(); + + TEST_ASSERT_NOT_NULL(canopen); + TEST_ASSERT_NOT_NULL(can); + + TEST_ASSERT_TRUE_MESSAGE(canopen->configure(can, 500, 1), "configure failed"); + CO_ReturnError_t err = canopen->appConfigLoop(); + TEST_ASSERT_EQUAL_MESSAGE(CO_ERROR_NO, err, "appConfigLoop failed"); + + // uint64_t iterations = 1'000; + uint64_t iterations = 1; + const uint64_t start_ms = timer->millis(); + uint8_t statusLed = 0; + uint8_t errorLed = 0; + CO_NMT_reset_cmd_t reset = CO_RESET_COMM; + uint64_t init_us = timer->micros(); + uint64_t total_time_us = 0; + + for (uint64_t i = 0; i < iterations; i++) { + uint64_t iter_start_us = timer->micros(); + + if (reset == CO_RESET_APP) { + canopen->reset(); + canopen->end(); + LOG_ERROR("reset"); + break; + } else if (reset != CO_RESET_NOT) { + timer->delaySec(1); + CO_ReturnError_t err = canopen->appConfigLoop(); + if (err != CO_ERROR_NO) { + LOG_ERROR("appConfigLoop failed"); + // return err; + } + reset = CO_RESET_NOT; + // continue; + } else if (reset == CO_RESET_NOT) { + reset = canopen->appExecLoop(timer->micros(), statusLed, errorLed); + // continue; + } + + uint64_t iter_end_us = timer->micros(); + uint64_t iter_time_us = iter_end_us - iter_start_us; + total_time_us += iter_time_us; + + if (i % 1000000 == 0) { + uint64_t end_us = timer->micros(); + LOG_INFO("Iteration: %lu - %lu us", i, end_us - init_us); + init_us = timer->micros(); + } + } + + const uint64_t end_ms = timer->millis(); + const uint64_t duration_ms = end_ms - start_ms; + LOG_INFO("Duration: %lu ms\n", duration_ms); + LOG_INFO("Average time per iteration: %.2f us\n", static_cast(total_time_us) / iterations); + +} \ No newline at end of file