samples: canbus: add CANopen sample
Add sample demonstrating the integration of CANopenNode in Zephyr to support the CANopen protocol. This fixes #15278. Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
parent
308f204952
commit
5ecc6698b9
16 changed files with 4496 additions and 0 deletions
10
samples/subsys/canbus/canbus.rst
Normal file
10
samples/subsys/canbus/canbus.rst
Normal file
|
@ -0,0 +1,10 @@
|
|||
.. _canbus-samples:
|
||||
|
||||
Controller Area Network (CAN) Bus Samples
|
||||
#########################################
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
**/*
|
9
samples/subsys/canbus/canopen/CMakeLists.txt
Normal file
9
samples/subsys/canbus/canopen/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.13.1)
|
||||
|
||||
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
|
||||
project(CANopen)
|
||||
|
||||
target_sources(app PRIVATE src/main.c objdict/CO_OD.c)
|
||||
zephyr_include_directories(objdict)
|
32
samples/subsys/canbus/canopen/Kconfig
Normal file
32
samples/subsys/canbus/canopen/Kconfig
Normal file
|
@ -0,0 +1,32 @@
|
|||
#
|
||||
# Copyright (c) 2019 Vestas Wind Systems A/S
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
choice
|
||||
prompt "CAN interface to use for CANopen"
|
||||
|
||||
config CANOPEN_INTERFACE_CAN_0
|
||||
bool "CAN 0"
|
||||
depends on CAN_0
|
||||
|
||||
config CANOPEN_INTERFACE_CAN_1
|
||||
bool "CAN 1"
|
||||
depends on CAN_1
|
||||
|
||||
endchoice
|
||||
|
||||
config CANOPEN_INTERFACE
|
||||
int
|
||||
default 0 if CANOPEN_INTERFACE_CAN0
|
||||
default 1 if CANOPEN_INTERFACE_CAN1
|
||||
|
||||
config CANOPEN_NODE_ID
|
||||
int "CANopen node ID"
|
||||
default 10
|
||||
range 1 127
|
||||
help
|
||||
7-bit CANopen Node ID
|
||||
|
||||
source "Kconfig.zephyr"
|
353
samples/subsys/canbus/canopen/README.rst
Normal file
353
samples/subsys/canbus/canopen/README.rst
Normal file
|
@ -0,0 +1,353 @@
|
|||
.. _canopen-sample:
|
||||
|
||||
CANopen
|
||||
#######
|
||||
|
||||
Overview
|
||||
********
|
||||
This sample application shows how the `CANopenNode`_ CANopen protocol
|
||||
stack can be used in Zephyr.
|
||||
|
||||
CANopen is an internationally standardized (`EN 50325-4`_, `CiA 301`_)
|
||||
communication protocol and device specification for embedded
|
||||
systems used in automation. CANopenNode is a 3rd party, open-source
|
||||
CANopen protocol stack.
|
||||
|
||||
Apart from the CANopen protocol stack integration, this sample also
|
||||
demonstrates the use of non-volatile storage for the CANopen object
|
||||
dictionary.
|
||||
|
||||
Requirements
|
||||
************
|
||||
|
||||
* A board with CAN bus and flash support
|
||||
* Host PC with CAN bus support
|
||||
|
||||
Building and Running
|
||||
********************
|
||||
|
||||
Building and Running for TWR-KE18F
|
||||
==================================
|
||||
The :ref:`twr_ke18f` board is equipped with an onboard CAN
|
||||
transceiver. This board supports CANopen LED indicators (red and green
|
||||
LEDs). The sample can be built and executed for the TWR-KE18F as
|
||||
follows:
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/subsys/canbus/canopen
|
||||
:board: twr_ke18f
|
||||
:goals: build flash
|
||||
:compact:
|
||||
|
||||
Pressing the button labelled ``SW3`` will increment the button press
|
||||
counter object at index ``0x2102`` in the object dictionary.
|
||||
|
||||
Building and Running for FRDM-K64F
|
||||
==================================
|
||||
The :ref:`frdm_k64f` board does not come with an onboard CAN
|
||||
transceiver. In order to use the CAN bus on the FRDM-K64F board, an
|
||||
external CAN bus tranceiver must be connected to ``PTB18``
|
||||
(``CAN0_TX``) and ``PTB19`` (``CAN0_RX``). This board supports CANopen
|
||||
LED indicators (red and green LEDs)
|
||||
|
||||
The sample can be built and executed for the FRDM-K64F as follows:
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/subsys/canbus/canopen
|
||||
:board: frdm_k64f
|
||||
:goals: build flash
|
||||
:compact:
|
||||
|
||||
Pressing the button labelled ``SW3`` will increment the button press
|
||||
counter object at index ``0x2102`` in the object dictionary.
|
||||
|
||||
Testing CANopen Communication
|
||||
*****************************
|
||||
CANopen communication between the host PC and Zephyr can be
|
||||
established using any CANopen compliant application on the host PC.
|
||||
The examples here uses `CANopen for Python`_ for communicating between
|
||||
the host PC and Zephyr. First, install python-canopen along with the
|
||||
python-can backend as follows:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
pip3 install --user canopen can
|
||||
|
||||
Next, bring up the CAN interface on the test PC. On GNU/Linux, this
|
||||
can be done as follows:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
sudo ip link set can0 type can bitrate 125000 restart-ms 100
|
||||
sudo ip link set up can0
|
||||
|
||||
|
||||
To better understand the communication taking place in the following
|
||||
examples, you can monitor the CAN traffic from the host PC. On
|
||||
GNU/Linux, this can be accomplished using ``candump`` from the
|
||||
`can-utils`_ package as follows:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
candump can0
|
||||
|
||||
NMT State Changes
|
||||
=================
|
||||
Changing the Network Management (NMT) state of the node can be
|
||||
accomplished using the following Python code:
|
||||
|
||||
.. code-block:: py
|
||||
|
||||
import canopen
|
||||
import os
|
||||
import time
|
||||
|
||||
ZEPHYR_BASE = os.environ['ZEPHYR_BASE']
|
||||
EDS = os.path.join(ZEPHYR_BASE, 'samples', 'subsys', 'canbus', 'canopen',
|
||||
'objdict', 'objdict.eds')
|
||||
NODEID = 10
|
||||
|
||||
network = canopen.Network()
|
||||
|
||||
# 'can0' and 'socketcan' is for GNU/Linux, please see the python-can documentation for other platforms:
|
||||
network.connect(channel='can0', bustype='socketcan')
|
||||
|
||||
node = network.add_node(NODEID, EDS)
|
||||
|
||||
# Green indicator LED will flash slowly
|
||||
node.nmt.state = 'STOPPED'
|
||||
time.sleep(5)
|
||||
|
||||
# Green indicator LED will flash faster
|
||||
node.nmt.state = 'PRE-OPERATIONAL'
|
||||
time.sleep(5)
|
||||
|
||||
# Green indicator LED will be steady on
|
||||
node.nmt.state = 'OPERATIONAL'
|
||||
time.sleep(5)
|
||||
|
||||
# Node will reset communication
|
||||
node.nmt.state = 'RESET COMMUNICATION'
|
||||
node.nmt.wait_for_heartbeat()
|
||||
|
||||
# Node will reset
|
||||
node.nmt.state = 'RESET'
|
||||
node.nmt.wait_for_heartbeat()
|
||||
|
||||
network.disconnect()
|
||||
|
||||
Running the above Python code will update the NMT state of the node
|
||||
which is reflected on the indicator LEDs (if present).
|
||||
|
||||
SDO Upload
|
||||
==========
|
||||
Reading a Service Data Object (SDO) at a given index of the CANopen
|
||||
object dictionary (here index ``0x1008``, the manufacturer device
|
||||
name) can be accomplished using the following Python code:
|
||||
|
||||
.. code-block:: py
|
||||
|
||||
import canopen
|
||||
import os
|
||||
|
||||
ZEPHYR_BASE = os.environ['ZEPHYR_BASE']
|
||||
EDS = os.path.join(ZEPHYR_BASE, 'samples', 'subsys', 'canbus', 'canopen',
|
||||
'objdict', 'objdict.eds')
|
||||
NODEID = 10
|
||||
|
||||
network = canopen.Network()
|
||||
|
||||
# 'can0' and 'socketcan' is for GNU/Linux, please see the python-can documentation for other platforms:
|
||||
network.connect(channel='can0', bustype='socketcan')
|
||||
|
||||
node = network.add_node(NODEID, EDS)
|
||||
name = node.sdo['Manufacturer device name']
|
||||
|
||||
print("Device name: '{}'".format(name.raw))
|
||||
|
||||
network.disconnect()
|
||||
|
||||
Running the above Python code should produce the following output:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
Device name: 'Zephyr RTOS/CANopenNode'
|
||||
|
||||
SDO Download
|
||||
============
|
||||
Writing to a Service Data Object (SDO) at a given index of the CANopen
|
||||
object dictionary (here index ``0x1017``, the producer heartbeat time)
|
||||
can be accomplished using the following Python code:
|
||||
|
||||
.. code-block:: py
|
||||
|
||||
import canopen
|
||||
import os
|
||||
|
||||
ZEPHYR_BASE = os.environ['ZEPHYR_BASE']
|
||||
EDS = os.path.join(ZEPHYR_BASE, 'samples', 'subsys', 'canbus', 'canopen',
|
||||
'objdict', 'objdict.eds')
|
||||
NODEID = 10
|
||||
|
||||
network = canopen.Network()
|
||||
|
||||
# 'can0' and 'socketcan' is for GNU/Linux, please see the python-can documentation for other platforms:
|
||||
network.connect(channel='can0', bustype='socketcan')
|
||||
|
||||
node = network.add_node(NODEID, EDS)
|
||||
heartbeat = node.sdo['Producer heartbeat time']
|
||||
reboots = node.sdo['Power-on counter']
|
||||
|
||||
# Set heartbeat interval without saving to non-volatile storage
|
||||
print("Initial heartbeat time: {} ms".format(heartbeat.raw))
|
||||
print("Power-on counter: {}".format(reboots.raw))
|
||||
heartbeat.raw = 5000
|
||||
print("Updated heartbeat time: {} ms".format(heartbeat.raw))
|
||||
|
||||
# Reset and read heartbeat interval again
|
||||
node.nmt.state = 'RESET'
|
||||
node.nmt.wait_for_heartbeat()
|
||||
print("heartbeat time after reset: {} ms".format(heartbeat.raw))
|
||||
print("Power-on counter: {}".format(reboots.raw))
|
||||
|
||||
# Set interval and store it to non-volatile storage
|
||||
heartbeat.raw = 2000
|
||||
print("Updated heartbeat time: {} ms".format(heartbeat.raw))
|
||||
node.store()
|
||||
|
||||
# Reset and read heartbeat interval again
|
||||
node.nmt.state = 'RESET'
|
||||
node.nmt.wait_for_heartbeat()
|
||||
print("heartbeat time after store and reset: {} ms".format(heartbeat.raw))
|
||||
print("Power-on counter: {}".format(reboots.raw))
|
||||
|
||||
# Restore default values, reset and read again
|
||||
node.restore()
|
||||
node.nmt.state = 'RESET'
|
||||
node.nmt.wait_for_heartbeat()
|
||||
print("heartbeat time after restore and reset: {} ms".format(heartbeat.raw))
|
||||
print("Power-on counter: {}".format(reboots.raw))
|
||||
|
||||
network.disconnect()
|
||||
|
||||
Running the above Python code should produce the following output:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
Initial heartbeat time: 1000 ms
|
||||
Power-on counter: 1
|
||||
Updated heartbeat time: 5000 ms
|
||||
heartbeat time after reset: 1000 ms
|
||||
Power-on counter: 2
|
||||
Updated heartbeat time: 2000 ms
|
||||
heartbeat time after store and reset: 2000 ms
|
||||
Power-on counter: 3
|
||||
heartbeat time after restore and reset: 1000 ms
|
||||
Power-on counter: 4
|
||||
|
||||
Note that the power-on counter value may be different.
|
||||
|
||||
PDO Mapping
|
||||
===========
|
||||
Transmit Process Data Object (PDO) mapping for data at a given index
|
||||
of the CANopen object dictionary (here index ``0x2102``, the button
|
||||
press counter) can be accomplished using the following Python code:
|
||||
|
||||
.. code-block:: py
|
||||
|
||||
import canopen
|
||||
import os
|
||||
|
||||
ZEPHYR_BASE = os.environ['ZEPHYR_BASE']
|
||||
EDS = os.path.join(ZEPHYR_BASE, 'samples', 'subsys', 'canbus', 'canopen',
|
||||
'objdict', 'objdict.eds')
|
||||
NODEID = 10
|
||||
|
||||
network = canopen.Network()
|
||||
|
||||
# 'can0' and 'socketcan' is for GNU/Linux, please see the python-can documentation for other platforms:
|
||||
network.connect(channel='can0', bustype='socketcan')
|
||||
|
||||
node = network.add_node(NODEID, EDS)
|
||||
button = node.sdo['Button press counter']
|
||||
|
||||
# Read current TPDO mapping
|
||||
node.tpdo.read()
|
||||
|
||||
# Enter pre-operational state to map TPDO
|
||||
node.nmt.state = 'PRE-OPERATIONAL'
|
||||
|
||||
# Map TPDO 1 to transmit the button press counter on changes
|
||||
node.tpdo[1].clear()
|
||||
node.tpdo[1].add_variable('Button press counter')
|
||||
node.tpdo[1].trans_type = 254
|
||||
node.tpdo[1].enabled = True
|
||||
|
||||
# Save TPDO mapping
|
||||
node.tpdo.save()
|
||||
node.nmt.state = 'OPERATIONAL'
|
||||
|
||||
# Reset button press counter
|
||||
button.raw = 0
|
||||
|
||||
print("Press the button 10 times")
|
||||
while True:
|
||||
node.tpdo[1].wait_for_reception()
|
||||
print("Button press counter: {}".format(node.tpdo['Button press counter'].phys))
|
||||
if node.tpdo['Button press counter'].phys >= 10:
|
||||
break
|
||||
|
||||
network.disconnect()
|
||||
|
||||
Running the above Python code should produce the following output:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
Press the button 10 times
|
||||
Button press counter: 0
|
||||
Button press counter: 1
|
||||
Button press counter: 2
|
||||
Button press counter: 3
|
||||
Button press counter: 4
|
||||
Button press counter: 5
|
||||
Button press counter: 6
|
||||
Button press counter: 7
|
||||
Button press counter: 8
|
||||
Button press counter: 9
|
||||
Button press counter: 10
|
||||
|
||||
Modifying the Object Dictionary
|
||||
*******************************
|
||||
The CANopen object dictionary used in this sample application can be
|
||||
found under :zephyr_file:`samples/subsys/canbus/canopen/objdict` in
|
||||
the Zephyr tree. The object dictionary can be modified using any
|
||||
object dictionary editor supporting CANopenNode object dictionary code
|
||||
generation.
|
||||
|
||||
A popular choice is the EDS editor from the `libedssharp`_
|
||||
project. With that, the
|
||||
:zephyr_file:`samples/subsys/canbus/canopen/objdict/objdicts.xml`
|
||||
project file can be opened and modified, and new implementation files
|
||||
(:zephyr_file:`samples/subsys/canbus/canopen/objdict/CO_OD.h` and
|
||||
:zephyr_file:`samples/subsys/canbus/canopen/objdict/CO_OD.c`) can be
|
||||
generated. The EDS editor can also export an updated Electronic Data
|
||||
Sheet (EDS) file
|
||||
(:zephyr_file:`samples/subsys/canbus/canopen/objdict/objdicts.eds`).
|
||||
|
||||
.. _CANopenNode:
|
||||
https://github.com/CANopenNode/CANopenNode
|
||||
|
||||
.. _EN 50325-4:
|
||||
https://can-cia.org/groups/international-standardization/
|
||||
|
||||
.. _CiA 301:
|
||||
https://can-cia.org/groups/specifications/
|
||||
|
||||
.. _CANopen for Python:
|
||||
https://github.com/christiansandberg/canopen
|
||||
|
||||
.. _can-utils:
|
||||
https://github.com/linux-can/can-utils
|
||||
|
||||
.. _libedssharp:
|
||||
https://github.com/robincornelius/libedssharp
|
2
samples/subsys/canbus/canopen/boards/frdm_k64f.conf
Normal file
2
samples/subsys/canbus/canopen/boards/frdm_k64f.conf
Normal file
|
@ -0,0 +1,2 @@
|
|||
CONFIG_MPU_ALLOW_FLASH_WRITE=y
|
||||
CONFIG_CANOPEN_LEDS_BICOLOR=y
|
1
samples/subsys/canbus/canopen/boards/twr_ke18f.conf
Normal file
1
samples/subsys/canbus/canopen/boards/twr_ke18f.conf
Normal file
|
@ -0,0 +1 @@
|
|||
CONFIG_MPU_ALLOW_FLASH_WRITE=y
|
12
samples/subsys/canbus/canopen/frdm_k64f.overlay
Normal file
12
samples/subsys/canbus/canopen/frdm_k64f.overlay
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Vestas Wind Systems A/S
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
green-led = &green_led;
|
||||
red-led = &red_led;
|
||||
};
|
||||
};
|
321
samples/subsys/canbus/canopen/objdict/CO_OD.c
Normal file
321
samples/subsys/canbus/canopen/objdict/CO_OD.c
Normal file
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Vestas Wind Systems A/S
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
File - CO_OD.c/CO_OD.h
|
||||
CANopen Object Dictionary.
|
||||
|
||||
This file was automatically generated with libedssharp Object
|
||||
Dictionary Editor v0.8-7-g2e53bbc DON'T EDIT THIS FILE MANUALLY !!!!
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#include "CO_driver.h"
|
||||
#include "CO_OD.h"
|
||||
#include "CO_SDO.h"
|
||||
|
||||
/*******************************************************************************
|
||||
DEFINITION AND INITIALIZATION OF OBJECT DICTIONARY VARIABLES
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
/***** Definition for ROM variables ********************************************/
|
||||
struct sCO_OD_ROM CO_OD_ROM = {
|
||||
CO_OD_FIRST_LAST_WORD,
|
||||
|
||||
/*1000*/ 0x0000L,
|
||||
/*1005*/ 0x0080L,
|
||||
/*1006*/ 0x0000L,
|
||||
/*1007*/ 0x0000L,
|
||||
/*1008*/ { 'Z', 'e', 'p', 'h', 'y', 'r', ' ', 'R', 'T', 'O', 'S', '/', 'C', 'A', 'N', 'o', 'p', 'e', 'n', 'N', 'o', 'd', 'e' },
|
||||
/*1009*/ { '3', '.', '0', '0' },
|
||||
/*100a*/ { '3', '.', '0', '0' },
|
||||
/*1012*/ 0x0000L,
|
||||
/*1014*/ 0x0080L,
|
||||
/*1015*/ 0x64,
|
||||
/*1016*/ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
|
||||
/*1017*/ 0x3e8,
|
||||
/*1018*/ { 0x4L, 0x0000L, 0x0000L, 0x0000L, 0x0000L },
|
||||
/*1019*/ 0x0L,
|
||||
/*1029*/ { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 },
|
||||
/*1200*/ { { 0x2L, 0x0600L, 0x0580L } },
|
||||
/*1400*/ { { 0x2L, 0x0200L, 0xfeL },
|
||||
/*1401*/ { 0x2L, 0x0300L, 0xfeL },
|
||||
/*1402*/ { 0x2L, 0x0400L, 0xfeL },
|
||||
/*1403*/ { 0x2L, 0x0500L, 0xfeL } },
|
||||
/*1600*/ { { 0x0L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L },
|
||||
/*1601*/ { 0x0L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L },
|
||||
/*1602*/ { 0x0L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L },
|
||||
/*1603*/ { 0x0L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L } },
|
||||
/*1800*/ { { 0x6L, 0x0180L, 0xfeL, 0x00, 0x0L, 0x00, 0x0L },
|
||||
/*1801*/ { 0x6L, 0x0280L, 0xfeL, 0x00, 0x0L, 0x00, 0x0L },
|
||||
/*1802*/ { 0x6L, 0x0380L, 0xfeL, 0x00, 0x0L, 0x00, 0x0L },
|
||||
/*1803*/ { 0x6L, 0x0480L, 0xfeL, 0x00, 0x0L, 0x00, 0x0L } },
|
||||
/*1a00*/ { { 0x0L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L },
|
||||
/*1a01*/ { 0x0L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L },
|
||||
/*1a02*/ { 0x0L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L },
|
||||
/*1a03*/ { 0x0L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L, 0x0000L } },
|
||||
/*1f80*/ 0x0000L,
|
||||
|
||||
CO_OD_FIRST_LAST_WORD,
|
||||
};
|
||||
|
||||
|
||||
/***** Definition for RAM variables ********************************************/
|
||||
struct sCO_OD_RAM CO_OD_RAM = {
|
||||
CO_OD_FIRST_LAST_WORD,
|
||||
|
||||
/*1001*/ 0x0L,
|
||||
/*1002*/ 0x0000L,
|
||||
/*1003*/ { 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
/*1010*/ { 0x00000003 },
|
||||
/*1011*/ { 0x00000001 },
|
||||
/*2100*/ { 0x0L, 0x0L, 0x0L, 0x0L, 0x0L, 0x0L, 0x0L, 0x0L, 0x0L, 0x0L },
|
||||
/*2102*/ 0x0000L,
|
||||
|
||||
CO_OD_FIRST_LAST_WORD,
|
||||
};
|
||||
|
||||
|
||||
/***** Definition for EEPROM variables ********************************************/
|
||||
struct sCO_OD_EEPROM CO_OD_EEPROM = {
|
||||
CO_OD_FIRST_LAST_WORD,
|
||||
|
||||
/*2101*/ 0x0000L,
|
||||
|
||||
CO_OD_FIRST_LAST_WORD,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
STRUCTURES FOR RECORD TYPE OBJECTS
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
/*0x1018*/ const CO_OD_entryRecord_t OD_record1018[5] = {
|
||||
{ (void *)&CO_OD_ROM.identity.maxSubIndex, 0x05, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.identity.vendorID, 0x85, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.identity.productCode, 0x85, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.identity.revisionNumber, 0x85, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.identity.serialNumber, 0x85, 0x4 },
|
||||
};
|
||||
|
||||
/*0x1200*/ const CO_OD_entryRecord_t OD_record1200[3] = {
|
||||
{ (void *)&CO_OD_ROM.SDOServerParameter[0].maxSubIndex, 0x05, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.SDOServerParameter[0].COB_IDClientToServer, 0x85, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.SDOServerParameter[0].COB_IDServerToClient, 0x85, 0x4 },
|
||||
};
|
||||
|
||||
/*0x1400*/ const CO_OD_entryRecord_t OD_record1400[3] = {
|
||||
{ (void *)&CO_OD_ROM.RPDOCommunicationParameter[0].maxSubIndex, 0x05, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.RPDOCommunicationParameter[0].COB_IDUsedByRPDO, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOCommunicationParameter[0].transmissionType, 0x0d, 0x1 },
|
||||
};
|
||||
|
||||
/*0x1401*/ const CO_OD_entryRecord_t OD_record1401[3] = {
|
||||
{ (void *)&CO_OD_ROM.RPDOCommunicationParameter[1].maxSubIndex, 0x05, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.RPDOCommunicationParameter[1].COB_IDUsedByRPDO, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOCommunicationParameter[1].transmissionType, 0x0d, 0x1 },
|
||||
};
|
||||
|
||||
/*0x1402*/ const CO_OD_entryRecord_t OD_record1402[3] = {
|
||||
{ (void *)&CO_OD_ROM.RPDOCommunicationParameter[2].maxSubIndex, 0x05, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.RPDOCommunicationParameter[2].COB_IDUsedByRPDO, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOCommunicationParameter[2].transmissionType, 0x0d, 0x1 },
|
||||
};
|
||||
|
||||
/*0x1403*/ const CO_OD_entryRecord_t OD_record1403[3] = {
|
||||
{ (void *)&CO_OD_ROM.RPDOCommunicationParameter[3].maxSubIndex, 0x05, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.RPDOCommunicationParameter[3].COB_IDUsedByRPDO, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOCommunicationParameter[3].transmissionType, 0x0d, 0x1 },
|
||||
};
|
||||
|
||||
/*0x1600*/ const CO_OD_entryRecord_t OD_record1600[9] = {
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[0].numberOfMappedObjects, 0x0d, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[0].mappedObject1, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[0].mappedObject2, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[0].mappedObject3, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[0].mappedObject4, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[0].mappedObject5, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[0].mappedObject6, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[0].mappedObject7, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[0].mappedObject8, 0x8d, 0x4 },
|
||||
};
|
||||
|
||||
/*0x1601*/ const CO_OD_entryRecord_t OD_record1601[9] = {
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[1].numberOfMappedObjects, 0x0d, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[1].mappedObject1, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[1].mappedObject2, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[1].mappedObject3, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[1].mappedObject4, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[1].mappedObject5, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[1].mappedObject6, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[1].mappedObject7, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[1].mappedObject8, 0x8d, 0x4 },
|
||||
};
|
||||
|
||||
/*0x1602*/ const CO_OD_entryRecord_t OD_record1602[9] = {
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[2].numberOfMappedObjects, 0x0d, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[2].mappedObject1, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[2].mappedObject2, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[2].mappedObject3, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[2].mappedObject4, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[2].mappedObject5, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[2].mappedObject6, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[2].mappedObject7, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[2].mappedObject8, 0x8d, 0x4 },
|
||||
};
|
||||
|
||||
/*0x1603*/ const CO_OD_entryRecord_t OD_record1603[9] = {
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[3].numberOfMappedObjects, 0x0d, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[3].mappedObject1, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[3].mappedObject2, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[3].mappedObject3, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[3].mappedObject4, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[3].mappedObject5, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[3].mappedObject6, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[3].mappedObject7, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.RPDOMappingParameter[3].mappedObject8, 0x8d, 0x4 },
|
||||
};
|
||||
|
||||
/*0x1800*/ const CO_OD_entryRecord_t OD_record1800[7] = {
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[0].maxSubIndex, 0x05, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[0].COB_IDUsedByTPDO, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[0].transmissionType, 0x0d, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[0].inhibitTime, 0x8d, 0x2 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[0].compatibilityEntry, 0x05, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[0].eventTimer, 0x8d, 0x2 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[0].SYNCStartValue, 0x0d, 0x1 },
|
||||
};
|
||||
|
||||
/*0x1801*/ const CO_OD_entryRecord_t OD_record1801[7] = {
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[1].maxSubIndex, 0x05, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[1].COB_IDUsedByTPDO, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[1].transmissionType, 0x0d, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[1].inhibitTime, 0x8d, 0x2 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[1].compatibilityEntry, 0x05, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[1].eventTimer, 0x8d, 0x2 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[1].SYNCStartValue, 0x0d, 0x1 },
|
||||
};
|
||||
|
||||
/*0x1802*/ const CO_OD_entryRecord_t OD_record1802[7] = {
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[2].maxSubIndex, 0x05, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[2].COB_IDUsedByTPDO, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[2].transmissionType, 0x0d, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[2].inhibitTime, 0x8d, 0x2 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[2].compatibilityEntry, 0x05, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[2].eventTimer, 0x8d, 0x2 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[2].SYNCStartValue, 0x0d, 0x1 },
|
||||
};
|
||||
|
||||
/*0x1803*/ const CO_OD_entryRecord_t OD_record1803[7] = {
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[3].maxSubIndex, 0x05, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[3].COB_IDUsedByTPDO, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[3].transmissionType, 0x0d, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[3].inhibitTime, 0x8d, 0x2 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[3].compatibilityEntry, 0x05, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[3].eventTimer, 0x8d, 0x2 },
|
||||
{ (void *)&CO_OD_ROM.TPDOCommunicationParameter[3].SYNCStartValue, 0x0d, 0x1 },
|
||||
};
|
||||
|
||||
/*0x1a00*/ const CO_OD_entryRecord_t OD_record1a00[9] = {
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[0].numberOfMappedObjects, 0x0d, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[0].mappedObject1, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[0].mappedObject2, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[0].mappedObject3, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[0].mappedObject4, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[0].mappedObject5, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[0].mappedObject6, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[0].mappedObject7, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[0].mappedObject8, 0x8d, 0x4 },
|
||||
};
|
||||
|
||||
/*0x1a01*/ const CO_OD_entryRecord_t OD_record1a01[9] = {
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[1].numberOfMappedObjects, 0x0d, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[1].mappedObject1, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[1].mappedObject2, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[1].mappedObject3, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[1].mappedObject4, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[1].mappedObject5, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[1].mappedObject6, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[1].mappedObject7, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[1].mappedObject8, 0x8d, 0x4 },
|
||||
};
|
||||
|
||||
/*0x1a02*/ const CO_OD_entryRecord_t OD_record1a02[9] = {
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[2].numberOfMappedObjects, 0x0d, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[2].mappedObject1, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[2].mappedObject2, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[2].mappedObject3, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[2].mappedObject4, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[2].mappedObject5, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[2].mappedObject6, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[2].mappedObject7, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[2].mappedObject8, 0x8d, 0x4 },
|
||||
};
|
||||
|
||||
/*0x1a03*/ const CO_OD_entryRecord_t OD_record1a03[9] = {
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[3].numberOfMappedObjects, 0x0d, 0x1 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[3].mappedObject1, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[3].mappedObject2, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[3].mappedObject3, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[3].mappedObject4, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[3].mappedObject5, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[3].mappedObject6, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[3].mappedObject7, 0x8d, 0x4 },
|
||||
{ (void *)&CO_OD_ROM.TPDOMappingParameter[3].mappedObject8, 0x8d, 0x4 },
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
OBJECT DICTIONARY
|
||||
*******************************************************************************/
|
||||
const CO_OD_entry_t CO_OD[41] = {
|
||||
|
||||
{ 0x1000, 0x00, 0x85, 4, (void *)&CO_OD_ROM.deviceType },
|
||||
{ 0x1001, 0x00, 0x26, 1, (void *)&CO_OD_RAM.errorRegister },
|
||||
{ 0x1002, 0x00, 0xa6, 4, (void *)&CO_OD_RAM.manufacturerStatusRegister },
|
||||
{ 0x1003, 0x08, 0x8e, 4, (void *)&CO_OD_RAM.preDefinedErrorField[0] },
|
||||
{ 0x1005, 0x00, 0x8d, 4, (void *)&CO_OD_ROM.COB_ID_SYNCMessage },
|
||||
{ 0x1006, 0x00, 0x8d, 4, (void *)&CO_OD_ROM.communicationCyclePeriod },
|
||||
{ 0x1007, 0x00, 0x8d, 4, (void *)&CO_OD_ROM.synchronousWindowLength },
|
||||
{ 0x1008, 0x00, 0x05, 23, (void *)&CO_OD_ROM.manufacturerDeviceName },
|
||||
{ 0x1009, 0x00, 0x05, 4, (void *)&CO_OD_ROM.manufacturerHardwareVersion },
|
||||
{ 0x100a, 0x00, 0x05, 4, (void *)&CO_OD_ROM.manufacturerSoftwareVersion },
|
||||
{ 0x1010, 0x01, 0x8e, 4, (void *)&CO_OD_RAM.storeParameters[0] },
|
||||
{ 0x1011, 0x01, 0x8e, 4, (void *)&CO_OD_RAM.restoreDefaultParameters[0] },
|
||||
{ 0x1012, 0x00, 0x85, 4, (void *)&CO_OD_ROM.COB_ID_TIME },
|
||||
{ 0x1014, 0x00, 0x85, 4, (void *)&CO_OD_ROM.COB_ID_EMCY },
|
||||
{ 0x1015, 0x00, 0x8d, 2, (void *)&CO_OD_ROM.inhibitTimeEMCY },
|
||||
{ 0x1016, 0x04, 0x8d, 4, (void *)&CO_OD_ROM.consumerHeartbeatTime[0] },
|
||||
{ 0x1017, 0x00, 0x8d, 2, (void *)&CO_OD_ROM.producerHeartbeatTime },
|
||||
{ 0x1018, 0x04, 0x00, 0, (void *)&OD_record1018 },
|
||||
{ 0x1019, 0x00, 0x0d, 1, (void *)&CO_OD_ROM.synchronousCounterOverflowValue },
|
||||
{ 0x1029, 0x06, 0x0d, 1, (void *)&CO_OD_ROM.errorBehavior[0] },
|
||||
{ 0x1200, 0x02, 0x00, 0, (void *)&OD_record1200 },
|
||||
{ 0x1400, 0x02, 0x00, 0, (void *)&OD_record1400 },
|
||||
{ 0x1401, 0x02, 0x00, 0, (void *)&OD_record1401 },
|
||||
{ 0x1402, 0x02, 0x00, 0, (void *)&OD_record1402 },
|
||||
{ 0x1403, 0x02, 0x00, 0, (void *)&OD_record1403 },
|
||||
{ 0x1600, 0x08, 0x00, 0, (void *)&OD_record1600 },
|
||||
{ 0x1601, 0x08, 0x00, 4, (void *)&OD_record1601 },
|
||||
{ 0x1602, 0x08, 0x00, 4, (void *)&OD_record1602 },
|
||||
{ 0x1603, 0x08, 0x00, 4, (void *)&OD_record1603 },
|
||||
{ 0x1800, 0x06, 0x00, 0, (void *)&OD_record1800 },
|
||||
{ 0x1801, 0x06, 0x00, 4, (void *)&OD_record1801 },
|
||||
{ 0x1802, 0x06, 0x00, 4, (void *)&OD_record1802 },
|
||||
{ 0x1803, 0x06, 0x00, 4, (void *)&OD_record1803 },
|
||||
{ 0x1a00, 0x08, 0x00, 0, (void *)&OD_record1a00 },
|
||||
{ 0x1a01, 0x08, 0x00, 4, (void *)&OD_record1a01 },
|
||||
{ 0x1a02, 0x08, 0x00, 0, (void *)&OD_record1a02 },
|
||||
{ 0x1a03, 0x08, 0x00, 0, (void *)&OD_record1a03 },
|
||||
{ 0x1f80, 0x00, 0x8d, 4, (void *)&CO_OD_ROM.NMTStartup },
|
||||
{ 0x2100, 0x00, 0x26, 10, (void *)&CO_OD_RAM.errorStatusBits },
|
||||
{ 0x2101, 0x00, 0xa7, 4, (void *)&CO_OD_EEPROM.powerOnCounter },
|
||||
{ 0x2102, 0x00, 0xfe, 4, (void *)&CO_OD_RAM.buttonPressCounter },
|
||||
};
|
628
samples/subsys/canbus/canopen/objdict/CO_OD.h
Normal file
628
samples/subsys/canbus/canopen/objdict/CO_OD.h
Normal file
|
@ -0,0 +1,628 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Vestas Wind Systems A/S
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
File - CO_OD.c/CO_OD.h
|
||||
CANopen Object Dictionary.
|
||||
|
||||
This file was automatically generated with libedssharp Object
|
||||
Dictionary Editor v0.8-7-g2e53bbc DON'T EDIT THIS FILE MANUALLY !!!!
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#ifndef CO_OD_H_
|
||||
#define CO_OD_H_
|
||||
|
||||
/*******************************************************************************
|
||||
CANopen DATA TYPES
|
||||
*******************************************************************************/
|
||||
typedef bool_t BOOLEAN;
|
||||
typedef uint8_t UNSIGNED8;
|
||||
typedef uint16_t UNSIGNED16;
|
||||
typedef uint32_t UNSIGNED32;
|
||||
typedef uint64_t UNSIGNED64;
|
||||
typedef int8_t INTEGER8;
|
||||
typedef int16_t INTEGER16;
|
||||
typedef int32_t INTEGER32;
|
||||
typedef int64_t INTEGER64;
|
||||
typedef float32_t REAL32;
|
||||
typedef float64_t REAL64;
|
||||
typedef char_t VISIBLE_STRING;
|
||||
typedef oChar_t OCTET_STRING;
|
||||
|
||||
#ifdef DOMAIN
|
||||
#undef DOMAIN
|
||||
#endif
|
||||
|
||||
typedef domain_t DOMAIN;
|
||||
|
||||
#ifndef timeOfDay_t
|
||||
typedef union {
|
||||
unsigned long long ullValue;
|
||||
struct {
|
||||
unsigned long ms : 28;
|
||||
unsigned reserved : 4;
|
||||
unsigned days : 16;
|
||||
unsigned reserved2 : 16;
|
||||
};
|
||||
} timeOfDay_t;
|
||||
#endif
|
||||
|
||||
typedef timeOfDay_t TIME_OF_DAY;
|
||||
typedef timeOfDay_t TIME_DIFFERENCE;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
FILE INFO:
|
||||
FileName: objdict.eds
|
||||
FileVersion: 1
|
||||
CreationTime: 2:52PM
|
||||
CreationDate: 09-18-2019
|
||||
CreatedBy:
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
DEVICE INFO:
|
||||
VendorName:
|
||||
VendorNumber 0
|
||||
ProductName: Zephyr RTOS CANopen sample
|
||||
ProductNumber: 0
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
FEATURES
|
||||
*******************************************************************************/
|
||||
#define CO_NO_SYNC 1 /* Associated objects: 1005-1007 */
|
||||
#define CO_NO_EMERGENCY 1 /* Associated objects: 1014, 1015 */
|
||||
#define CO_NO_TIME 1 /* Associated objects: 1012, 1013 */
|
||||
#define CO_NO_SDO_SERVER 1 /* Associated objects: 1200-127F */
|
||||
#define CO_NO_SDO_CLIENT 0 /* Associated objects: 1280-12FF */
|
||||
#define CO_NO_LSS_SERVER 0 /* LSS Slave */
|
||||
#define CO_NO_LSS_CLIENT 0 /* LSS Master */
|
||||
#define CO_NO_RPDO 4 /* Associated objects: 14xx, 16xx */
|
||||
#define CO_NO_TPDO 4 /* Associated objects: 18xx, 1Axx */
|
||||
#define CO_NO_NMT_MASTER 0
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
OBJECT DICTIONARY
|
||||
*******************************************************************************/
|
||||
#define CO_OD_NoOfElements 41
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
TYPE DEFINITIONS FOR RECORDS
|
||||
*******************************************************************************/
|
||||
/*1018 */ typedef struct {
|
||||
UNSIGNED8 maxSubIndex;
|
||||
UNSIGNED32 vendorID;
|
||||
UNSIGNED32 productCode;
|
||||
UNSIGNED32 revisionNumber;
|
||||
UNSIGNED32 serialNumber;
|
||||
} OD_identity_t;
|
||||
/*1200 */ typedef struct {
|
||||
UNSIGNED8 maxSubIndex;
|
||||
UNSIGNED32 COB_IDClientToServer;
|
||||
UNSIGNED32 COB_IDServerToClient;
|
||||
} OD_SDOServerParameter_t;
|
||||
/*1280 */ typedef struct {
|
||||
UNSIGNED8 maxSubIndex;
|
||||
UNSIGNED32 COB_IDClientToServer;
|
||||
UNSIGNED32 COB_IDServerToClient;
|
||||
UNSIGNED8 nodeIDOfTheSDOServer;
|
||||
} OD_SDOClientParameter_t;
|
||||
/*1400 */ typedef struct {
|
||||
UNSIGNED8 maxSubIndex;
|
||||
UNSIGNED32 COB_IDUsedByRPDO;
|
||||
UNSIGNED8 transmissionType;
|
||||
} OD_RPDOCommunicationParameter_t;
|
||||
/*1600 */ typedef struct {
|
||||
UNSIGNED8 numberOfMappedObjects;
|
||||
UNSIGNED32 mappedObject1;
|
||||
UNSIGNED32 mappedObject2;
|
||||
UNSIGNED32 mappedObject3;
|
||||
UNSIGNED32 mappedObject4;
|
||||
UNSIGNED32 mappedObject5;
|
||||
UNSIGNED32 mappedObject6;
|
||||
UNSIGNED32 mappedObject7;
|
||||
UNSIGNED32 mappedObject8;
|
||||
} OD_RPDOMappingParameter_t;
|
||||
/*1800 */ typedef struct {
|
||||
UNSIGNED8 maxSubIndex;
|
||||
UNSIGNED32 COB_IDUsedByTPDO;
|
||||
UNSIGNED8 transmissionType;
|
||||
UNSIGNED16 inhibitTime;
|
||||
UNSIGNED8 compatibilityEntry;
|
||||
UNSIGNED16 eventTimer;
|
||||
UNSIGNED8 SYNCStartValue;
|
||||
} OD_TPDOCommunicationParameter_t;
|
||||
/*1a00 */ typedef struct {
|
||||
UNSIGNED8 numberOfMappedObjects;
|
||||
UNSIGNED32 mappedObject1;
|
||||
UNSIGNED32 mappedObject2;
|
||||
UNSIGNED32 mappedObject3;
|
||||
UNSIGNED32 mappedObject4;
|
||||
UNSIGNED32 mappedObject5;
|
||||
UNSIGNED32 mappedObject6;
|
||||
UNSIGNED32 mappedObject7;
|
||||
UNSIGNED32 mappedObject8;
|
||||
} OD_TPDOMappingParameter_t;
|
||||
|
||||
/*******************************************************************************
|
||||
TYPE DEFINITIONS FOR OBJECT DICTIONARY INDEXES
|
||||
|
||||
some of those are redundant with CO_SDO.h CO_ObjDicId_t <Common CiA301 object
|
||||
dictionary entries>
|
||||
*******************************************************************************/
|
||||
/*1000 */
|
||||
#define OD_1000_deviceType 0x1000
|
||||
|
||||
/*1001 */
|
||||
#define OD_1001_errorRegister 0x1001
|
||||
|
||||
/*1002 */
|
||||
#define OD_1002_manufacturerStatusRegister 0x1002
|
||||
|
||||
/*1003 */
|
||||
#define OD_1003_preDefinedErrorField 0x1003
|
||||
|
||||
#define OD_1003_0_preDefinedErrorField_maxSubIndex 0
|
||||
#define OD_1003_1_preDefinedErrorField_standardErrorField 1
|
||||
#define OD_1003_2_preDefinedErrorField_standardErrorField 2
|
||||
#define OD_1003_3_preDefinedErrorField_standardErrorField 3
|
||||
#define OD_1003_4_preDefinedErrorField_standardErrorField 4
|
||||
#define OD_1003_5_preDefinedErrorField_standardErrorField 5
|
||||
#define OD_1003_6_preDefinedErrorField_standardErrorField 6
|
||||
#define OD_1003_7_preDefinedErrorField_standardErrorField 7
|
||||
#define OD_1003_8_preDefinedErrorField_standardErrorField 8
|
||||
|
||||
/*1005 */
|
||||
#define OD_1005_COB_ID_SYNCMessage 0x1005
|
||||
|
||||
/*1006 */
|
||||
#define OD_1006_communicationCyclePeriod 0x1006
|
||||
|
||||
/*1007 */
|
||||
#define OD_1007_synchronousWindowLength 0x1007
|
||||
|
||||
/*1008 */
|
||||
#define OD_1008_manufacturerDeviceName 0x1008
|
||||
|
||||
/*1009 */
|
||||
#define OD_1009_manufacturerHardwareVersion 0x1009
|
||||
|
||||
/*100a */
|
||||
#define OD_100a_manufacturerSoftwareVersion 0x100a
|
||||
|
||||
/*1010 */
|
||||
#define OD_1010_storeParameters 0x1010
|
||||
|
||||
#define OD_1010_0_storeParameters_maxSubIndex 0
|
||||
#define OD_1010_1_storeParameters_saveAllParameters 1
|
||||
|
||||
/*1011 */
|
||||
#define OD_1011_restoreDefaultParameters 0x1011
|
||||
|
||||
#define OD_1011_0_restoreDefaultParameters_maxSubIndex 0
|
||||
#define OD_1011_1_restoreDefaultParameters_restoreAllDefaultParameters 1
|
||||
|
||||
/*1012 */
|
||||
#define OD_1012_COB_ID_TIME 0x1012
|
||||
|
||||
/*1014 */
|
||||
#define OD_1014_COB_ID_EMCY 0x1014
|
||||
|
||||
/*1015 */
|
||||
#define OD_1015_inhibitTimeEMCY 0x1015
|
||||
|
||||
/*1016 */
|
||||
#define OD_1016_consumerHeartbeatTime 0x1016
|
||||
|
||||
#define OD_1016_0_consumerHeartbeatTime_maxSubIndex 0
|
||||
#define OD_1016_1_consumerHeartbeatTime_consumerHeartbeatTime 1
|
||||
#define OD_1016_2_consumerHeartbeatTime_consumerHeartbeatTime 2
|
||||
#define OD_1016_3_consumerHeartbeatTime_consumerHeartbeatTime 3
|
||||
#define OD_1016_4_consumerHeartbeatTime_consumerHeartbeatTime 4
|
||||
|
||||
/*1017 */
|
||||
#define OD_1017_producerHeartbeatTime 0x1017
|
||||
|
||||
/*1018 */
|
||||
#define OD_1018_identity 0x1018
|
||||
|
||||
#define OD_1018_0_identity_maxSubIndex 0
|
||||
#define OD_1018_1_identity_vendorID 1
|
||||
#define OD_1018_2_identity_productCode 2
|
||||
#define OD_1018_3_identity_revisionNumber 3
|
||||
#define OD_1018_4_identity_serialNumber 4
|
||||
|
||||
/*1019 */
|
||||
#define OD_1019_synchronousCounterOverflowValue 0x1019
|
||||
|
||||
/*1029 */
|
||||
#define OD_1029_errorBehavior 0x1029
|
||||
|
||||
#define OD_1029_0_errorBehavior_maxSubIndex 0
|
||||
#define OD_1029_1_errorBehavior_communication 1
|
||||
#define OD_1029_2_errorBehavior_communicationOther 2
|
||||
#define OD_1029_3_errorBehavior_communicationPassive 3
|
||||
#define OD_1029_4_errorBehavior_generic 4
|
||||
#define OD_1029_5_errorBehavior_deviceProfile 5
|
||||
#define OD_1029_6_errorBehavior_manufacturerSpecific 6
|
||||
|
||||
/*1200 */
|
||||
#define OD_1200_SDOServerParameter 0x1200
|
||||
|
||||
#define OD_1200_0_SDOServerParameter_maxSubIndex 0
|
||||
#define OD_1200_1_SDOServerParameter_COB_IDClientToServer 1
|
||||
#define OD_1200_2_SDOServerParameter_COB_IDServerToClient 2
|
||||
|
||||
/*1400 */
|
||||
#define OD_1400_RPDOCommunicationParameter 0x1400
|
||||
|
||||
#define OD_1400_0_RPDOCommunicationParameter_maxSubIndex 0
|
||||
#define OD_1400_1_RPDOCommunicationParameter_COB_IDUsedByRPDO 1
|
||||
#define OD_1400_2_RPDOCommunicationParameter_transmissionType 2
|
||||
|
||||
/*1401 */
|
||||
#define OD_1401_RPDOCommunicationParameter 0x1401
|
||||
|
||||
#define OD_1401_0_RPDOCommunicationParameter_maxSubIndex 0
|
||||
#define OD_1401_1_RPDOCommunicationParameter_COB_IDUsedByRPDO 1
|
||||
#define OD_1401_2_RPDOCommunicationParameter_transmissionType 2
|
||||
|
||||
/*1402 */
|
||||
#define OD_1402_RPDOCommunicationParameter 0x1402
|
||||
|
||||
#define OD_1402_0_RPDOCommunicationParameter_maxSubIndex 0
|
||||
#define OD_1402_1_RPDOCommunicationParameter_COB_IDUsedByRPDO 1
|
||||
#define OD_1402_2_RPDOCommunicationParameter_transmissionType 2
|
||||
|
||||
/*1403 */
|
||||
#define OD_1403_RPDOCommunicationParameter 0x1403
|
||||
|
||||
#define OD_1403_0_RPDOCommunicationParameter_maxSubIndex 0
|
||||
#define OD_1403_1_RPDOCommunicationParameter_COB_IDUsedByRPDO 1
|
||||
#define OD_1403_2_RPDOCommunicationParameter_transmissionType 2
|
||||
|
||||
/*1600 */
|
||||
#define OD_1600_RPDOMappingParameter 0x1600
|
||||
|
||||
#define OD_1600_0_RPDOMappingParameter_maxSubIndex 0
|
||||
#define OD_1600_1_RPDOMappingParameter_mappedObject1 1
|
||||
#define OD_1600_2_RPDOMappingParameter_mappedObject2 2
|
||||
#define OD_1600_3_RPDOMappingParameter_mappedObject3 3
|
||||
#define OD_1600_4_RPDOMappingParameter_mappedObject4 4
|
||||
#define OD_1600_5_RPDOMappingParameter_mappedObject5 5
|
||||
#define OD_1600_6_RPDOMappingParameter_mappedObject6 6
|
||||
#define OD_1600_7_RPDOMappingParameter_mappedObject7 7
|
||||
#define OD_1600_8_RPDOMappingParameter_mappedObject8 8
|
||||
|
||||
/*1601 */
|
||||
#define OD_1601_RPDOMappingParameter 0x1601
|
||||
|
||||
#define OD_1601_0_RPDOMappingParameter_maxSubIndex 0
|
||||
#define OD_1601_1_RPDOMappingParameter_mappedObject1 1
|
||||
#define OD_1601_2_RPDOMappingParameter_mappedObject2 2
|
||||
#define OD_1601_3_RPDOMappingParameter_mappedObject3 3
|
||||
#define OD_1601_4_RPDOMappingParameter_mappedObject4 4
|
||||
#define OD_1601_5_RPDOMappingParameter_mappedObject5 5
|
||||
#define OD_1601_6_RPDOMappingParameter_mappedObject6 6
|
||||
#define OD_1601_7_RPDOMappingParameter_mappedObject7 7
|
||||
#define OD_1601_8_RPDOMappingParameter_mappedObject8 8
|
||||
|
||||
/*1602 */
|
||||
#define OD_1602_RPDOMappingParameter 0x1602
|
||||
|
||||
#define OD_1602_0_RPDOMappingParameter_maxSubIndex 0
|
||||
#define OD_1602_1_RPDOMappingParameter_mappedObject1 1
|
||||
#define OD_1602_2_RPDOMappingParameter_mappedObject2 2
|
||||
#define OD_1602_3_RPDOMappingParameter_mappedObject3 3
|
||||
#define OD_1602_4_RPDOMappingParameter_mappedObject4 4
|
||||
#define OD_1602_5_RPDOMappingParameter_mappedObject5 5
|
||||
#define OD_1602_6_RPDOMappingParameter_mappedObject6 6
|
||||
#define OD_1602_7_RPDOMappingParameter_mappedObject7 7
|
||||
#define OD_1602_8_RPDOMappingParameter_mappedObject8 8
|
||||
|
||||
/*1603 */
|
||||
#define OD_1603_RPDOMappingParameter 0x1603
|
||||
|
||||
#define OD_1603_0_RPDOMappingParameter_maxSubIndex 0
|
||||
#define OD_1603_1_RPDOMappingParameter_mappedObject1 1
|
||||
#define OD_1603_2_RPDOMappingParameter_mappedObject2 2
|
||||
#define OD_1603_3_RPDOMappingParameter_mappedObject3 3
|
||||
#define OD_1603_4_RPDOMappingParameter_mappedObject4 4
|
||||
#define OD_1603_5_RPDOMappingParameter_mappedObject5 5
|
||||
#define OD_1603_6_RPDOMappingParameter_mappedObject6 6
|
||||
#define OD_1603_7_RPDOMappingParameter_mappedObject7 7
|
||||
#define OD_1603_8_RPDOMappingParameter_mappedObject8 8
|
||||
|
||||
/*1800 */
|
||||
#define OD_1800_TPDOCommunicationParameter 0x1800
|
||||
|
||||
#define OD_1800_0_TPDOCommunicationParameter_maxSubIndex 0
|
||||
#define OD_1800_1_TPDOCommunicationParameter_COB_IDUsedByTPDO 1
|
||||
#define OD_1800_2_TPDOCommunicationParameter_transmissionType 2
|
||||
#define OD_1800_3_TPDOCommunicationParameter_inhibitTime 3
|
||||
#define OD_1800_4_TPDOCommunicationParameter_compatibilityEntry 4
|
||||
#define OD_1800_5_TPDOCommunicationParameter_eventTimer 5
|
||||
#define OD_1800_6_TPDOCommunicationParameter_SYNCStartValue 6
|
||||
|
||||
/*1801 */
|
||||
#define OD_1801_TPDOCommunicationParameter 0x1801
|
||||
|
||||
#define OD_1801_0_TPDOCommunicationParameter_maxSubIndex 0
|
||||
#define OD_1801_1_TPDOCommunicationParameter_COB_IDUsedByTPDO 1
|
||||
#define OD_1801_2_TPDOCommunicationParameter_transmissionType 2
|
||||
#define OD_1801_3_TPDOCommunicationParameter_inhibitTime 3
|
||||
#define OD_1801_4_TPDOCommunicationParameter_compatibilityEntry 4
|
||||
#define OD_1801_5_TPDOCommunicationParameter_eventTimer 5
|
||||
#define OD_1801_6_TPDOCommunicationParameter_SYNCStartValue 6
|
||||
|
||||
/*1802 */
|
||||
#define OD_1802_TPDOCommunicationParameter 0x1802
|
||||
|
||||
#define OD_1802_0_TPDOCommunicationParameter_maxSubIndex 0
|
||||
#define OD_1802_1_TPDOCommunicationParameter_COB_IDUsedByTPDO 1
|
||||
#define OD_1802_2_TPDOCommunicationParameter_transmissionType 2
|
||||
#define OD_1802_3_TPDOCommunicationParameter_inhibitTime 3
|
||||
#define OD_1802_4_TPDOCommunicationParameter_compatibilityEntry 4
|
||||
#define OD_1802_5_TPDOCommunicationParameter_eventTimer 5
|
||||
#define OD_1802_6_TPDOCommunicationParameter_SYNCStartValue 6
|
||||
|
||||
/*1803 */
|
||||
#define OD_1803_TPDOCommunicationParameter 0x1803
|
||||
|
||||
#define OD_1803_0_TPDOCommunicationParameter_maxSubIndex 0
|
||||
#define OD_1803_1_TPDOCommunicationParameter_COB_IDUsedByTPDO 1
|
||||
#define OD_1803_2_TPDOCommunicationParameter_transmissionType 2
|
||||
#define OD_1803_3_TPDOCommunicationParameter_inhibitTime 3
|
||||
#define OD_1803_4_TPDOCommunicationParameter_compatibilityEntry 4
|
||||
#define OD_1803_5_TPDOCommunicationParameter_eventTimer 5
|
||||
#define OD_1803_6_TPDOCommunicationParameter_SYNCStartValue 6
|
||||
|
||||
/*1a00 */
|
||||
#define OD_1a00_TPDOMappingParameter 0x1a00
|
||||
|
||||
#define OD_1a00_0_TPDOMappingParameter_maxSubIndex 0
|
||||
#define OD_1a00_1_TPDOMappingParameter_mappedObject1 1
|
||||
#define OD_1a00_2_TPDOMappingParameter_mappedObject2 2
|
||||
#define OD_1a00_3_TPDOMappingParameter_mappedObject3 3
|
||||
#define OD_1a00_4_TPDOMappingParameter_mappedObject4 4
|
||||
#define OD_1a00_5_TPDOMappingParameter_mappedObject5 5
|
||||
#define OD_1a00_6_TPDOMappingParameter_mappedObject6 6
|
||||
#define OD_1a00_7_TPDOMappingParameter_mappedObject7 7
|
||||
#define OD_1a00_8_TPDOMappingParameter_mappedObject8 8
|
||||
|
||||
/*1a01 */
|
||||
#define OD_1a01_TPDOMappingParameter 0x1a01
|
||||
|
||||
#define OD_1a01_0_TPDOMappingParameter_maxSubIndex 0
|
||||
#define OD_1a01_1_TPDOMappingParameter_mappedObject1 1
|
||||
#define OD_1a01_2_TPDOMappingParameter_mappedObject2 2
|
||||
#define OD_1a01_3_TPDOMappingParameter_mappedObject3 3
|
||||
#define OD_1a01_4_TPDOMappingParameter_mappedObject4 4
|
||||
#define OD_1a01_5_TPDOMappingParameter_mappedObject5 5
|
||||
#define OD_1a01_6_TPDOMappingParameter_mappedObject6 6
|
||||
#define OD_1a01_7_TPDOMappingParameter_mappedObject7 7
|
||||
#define OD_1a01_8_TPDOMappingParameter_mappedObject8 8
|
||||
|
||||
/*1a02 */
|
||||
#define OD_1a02_TPDOMappingParameter 0x1a02
|
||||
|
||||
#define OD_1a02_0_TPDOMappingParameter_maxSubIndex 0
|
||||
#define OD_1a02_1_TPDOMappingParameter_mappedObject1 1
|
||||
#define OD_1a02_2_TPDOMappingParameter_mappedObject2 2
|
||||
#define OD_1a02_3_TPDOMappingParameter_mappedObject3 3
|
||||
#define OD_1a02_4_TPDOMappingParameter_mappedObject4 4
|
||||
#define OD_1a02_5_TPDOMappingParameter_mappedObject5 5
|
||||
#define OD_1a02_6_TPDOMappingParameter_mappedObject6 6
|
||||
#define OD_1a02_7_TPDOMappingParameter_mappedObject7 7
|
||||
#define OD_1a02_8_TPDOMappingParameter_mappedObject8 8
|
||||
|
||||
/*1a03 */
|
||||
#define OD_1a03_TPDOMappingParameter 0x1a03
|
||||
|
||||
#define OD_1a03_0_TPDOMappingParameter_maxSubIndex 0
|
||||
#define OD_1a03_1_TPDOMappingParameter_mappedObject1 1
|
||||
#define OD_1a03_2_TPDOMappingParameter_mappedObject2 2
|
||||
#define OD_1a03_3_TPDOMappingParameter_mappedObject3 3
|
||||
#define OD_1a03_4_TPDOMappingParameter_mappedObject4 4
|
||||
#define OD_1a03_5_TPDOMappingParameter_mappedObject5 5
|
||||
#define OD_1a03_6_TPDOMappingParameter_mappedObject6 6
|
||||
#define OD_1a03_7_TPDOMappingParameter_mappedObject7 7
|
||||
#define OD_1a03_8_TPDOMappingParameter_mappedObject8 8
|
||||
|
||||
/*1f80 */
|
||||
#define OD_1f80_NMTStartup 0x1f80
|
||||
|
||||
/*2100 */
|
||||
#define OD_2100_errorStatusBits 0x2100
|
||||
|
||||
/*2101 */
|
||||
#define OD_2101_powerOnCounter 0x2101
|
||||
|
||||
/*2102 */
|
||||
#define OD_2102_buttonPressCounter 0x2102
|
||||
|
||||
/*******************************************************************************
|
||||
STRUCTURES FOR VARIABLES IN DIFFERENT MEMORY LOCATIONS
|
||||
*******************************************************************************/
|
||||
#define CO_OD_FIRST_LAST_WORD 0x55 /* Any value from 0x01 to 0xFE. If changed, EEPROM will be reinitialized. */
|
||||
|
||||
/***** Structure for ROM variables ********************************************/
|
||||
struct sCO_OD_ROM {
|
||||
UNSIGNED32 FirstWord;
|
||||
|
||||
/*1000 */ UNSIGNED32 deviceType;
|
||||
/*1005 */ UNSIGNED32 COB_ID_SYNCMessage;
|
||||
/*1006 */ UNSIGNED32 communicationCyclePeriod;
|
||||
/*1007 */ UNSIGNED32 synchronousWindowLength;
|
||||
/*1008 */ VISIBLE_STRING manufacturerDeviceName[23];
|
||||
/*1009 */ VISIBLE_STRING manufacturerHardwareVersion[4];
|
||||
/*100a */ VISIBLE_STRING manufacturerSoftwareVersion[4];
|
||||
/*1012 */ UNSIGNED32 COB_ID_TIME;
|
||||
/*1014 */ UNSIGNED32 COB_ID_EMCY;
|
||||
/*1015 */ UNSIGNED16 inhibitTimeEMCY;
|
||||
/*1016 */ UNSIGNED32 consumerHeartbeatTime[4];
|
||||
/*1017 */ UNSIGNED16 producerHeartbeatTime;
|
||||
/*1018 */ OD_identity_t identity;
|
||||
/*1019 */ UNSIGNED8 synchronousCounterOverflowValue;
|
||||
/*1029 */ UNSIGNED8 errorBehavior[6];
|
||||
/*1200 */ OD_SDOServerParameter_t SDOServerParameter[1];
|
||||
/*1400 */ OD_RPDOCommunicationParameter_t RPDOCommunicationParameter[4];
|
||||
/*1600 */ OD_RPDOMappingParameter_t RPDOMappingParameter[4];
|
||||
/*1800 */ OD_TPDOCommunicationParameter_t TPDOCommunicationParameter[4];
|
||||
/*1a00 */ OD_TPDOMappingParameter_t TPDOMappingParameter[4];
|
||||
/*1f80 */ UNSIGNED32 NMTStartup;
|
||||
|
||||
UNSIGNED32 LastWord;
|
||||
};
|
||||
|
||||
/***** Structure for RAM variables ********************************************/
|
||||
struct sCO_OD_RAM {
|
||||
UNSIGNED32 FirstWord;
|
||||
|
||||
/*1001 */ UNSIGNED8 errorRegister;
|
||||
/*1002 */ UNSIGNED32 manufacturerStatusRegister;
|
||||
/*1003 */ UNSIGNED32 preDefinedErrorField[8];
|
||||
/*1010 */ UNSIGNED32 storeParameters[1];
|
||||
/*1011 */ UNSIGNED32 restoreDefaultParameters[1];
|
||||
/*2100 */ OCTET_STRING errorStatusBits[10];
|
||||
/*2102 */ UNSIGNED32 buttonPressCounter;
|
||||
|
||||
UNSIGNED32 LastWord;
|
||||
};
|
||||
|
||||
/***** Structure for EEPROM variables ********************************************/
|
||||
struct sCO_OD_EEPROM {
|
||||
UNSIGNED32 FirstWord;
|
||||
|
||||
/*2101 */ UNSIGNED32 powerOnCounter;
|
||||
|
||||
UNSIGNED32 LastWord;
|
||||
};
|
||||
|
||||
/***** Declaration of Object Dictionary variables *****************************/
|
||||
extern struct sCO_OD_ROM CO_OD_ROM;
|
||||
|
||||
extern struct sCO_OD_RAM CO_OD_RAM;
|
||||
|
||||
extern struct sCO_OD_EEPROM CO_OD_EEPROM;
|
||||
|
||||
/*******************************************************************************
|
||||
ALIASES FOR OBJECT DICTIONARY VARIABLES
|
||||
*******************************************************************************/
|
||||
/*1000, Data Type: UNSIGNED32 */
|
||||
#define OD_deviceType CO_OD_ROM.deviceType
|
||||
|
||||
/*1001, Data Type: UNSIGNED8 */
|
||||
#define OD_errorRegister CO_OD_RAM.errorRegister
|
||||
|
||||
/*1002, Data Type: UNSIGNED32 */
|
||||
#define OD_manufacturerStatusRegister CO_OD_RAM.manufacturerStatusRegister
|
||||
|
||||
/*1003, Data Type: UNSIGNED32, Array[8] */
|
||||
#define OD_preDefinedErrorField CO_OD_RAM.preDefinedErrorField
|
||||
#define ODL_preDefinedErrorField_arrayLength 8
|
||||
#define ODA_preDefinedErrorField_standardErrorField 0
|
||||
|
||||
/*1005, Data Type: UNSIGNED32 */
|
||||
#define OD_COB_ID_SYNCMessage CO_OD_ROM.COB_ID_SYNCMessage
|
||||
|
||||
/*1006, Data Type: UNSIGNED32 */
|
||||
#define OD_communicationCyclePeriod CO_OD_ROM.communicationCyclePeriod
|
||||
|
||||
/*1007, Data Type: UNSIGNED32 */
|
||||
#define OD_synchronousWindowLength CO_OD_ROM.synchronousWindowLength
|
||||
|
||||
/*1008, Data Type: VISIBLE_STRING */
|
||||
#define OD_manufacturerDeviceName CO_OD_ROM.manufacturerDeviceName
|
||||
#define ODL_manufacturerDeviceName_stringLength 23
|
||||
|
||||
/*1009, Data Type: VISIBLE_STRING */
|
||||
#define OD_manufacturerHardwareVersion CO_OD_ROM.manufacturerHardwareVersion
|
||||
#define ODL_manufacturerHardwareVersion_stringLength 4
|
||||
|
||||
/*100a, Data Type: VISIBLE_STRING */
|
||||
#define OD_manufacturerSoftwareVersion CO_OD_ROM.manufacturerSoftwareVersion
|
||||
#define ODL_manufacturerSoftwareVersion_stringLength 4
|
||||
|
||||
/*1010, Data Type: UNSIGNED32, Array[1] */
|
||||
#define OD_storeParameters CO_OD_RAM.storeParameters
|
||||
#define ODL_storeParameters_arrayLength 1
|
||||
#define ODA_storeParameters_saveAllParameters 0
|
||||
|
||||
/*1011, Data Type: UNSIGNED32, Array[1] */
|
||||
#define OD_restoreDefaultParameters CO_OD_RAM.restoreDefaultParameters
|
||||
#define ODL_restoreDefaultParameters_arrayLength 1
|
||||
#define ODA_restoreDefaultParameters_restoreAllDefaultParameters 0
|
||||
|
||||
/*1012, Data Type: UNSIGNED32 */
|
||||
#define OD_COB_ID_TIME CO_OD_ROM.COB_ID_TIME
|
||||
|
||||
/*1014, Data Type: UNSIGNED32 */
|
||||
#define OD_COB_ID_EMCY CO_OD_ROM.COB_ID_EMCY
|
||||
|
||||
/*1015, Data Type: UNSIGNED16 */
|
||||
#define OD_inhibitTimeEMCY CO_OD_ROM.inhibitTimeEMCY
|
||||
|
||||
/*1016, Data Type: UNSIGNED32, Array[4] */
|
||||
#define OD_consumerHeartbeatTime CO_OD_ROM.consumerHeartbeatTime
|
||||
#define ODL_consumerHeartbeatTime_arrayLength 4
|
||||
#define ODA_consumerHeartbeatTime_consumerHeartbeatTime 0
|
||||
|
||||
/*1017, Data Type: UNSIGNED16 */
|
||||
#define OD_producerHeartbeatTime CO_OD_ROM.producerHeartbeatTime
|
||||
|
||||
/*1018, Data Type: identity_t */
|
||||
#define OD_identity CO_OD_ROM.identity
|
||||
|
||||
/*1019, Data Type: UNSIGNED8 */
|
||||
#define OD_synchronousCounterOverflowValue CO_OD_ROM.synchronousCounterOverflowValue
|
||||
|
||||
/*1029, Data Type: UNSIGNED8, Array[6] */
|
||||
#define OD_errorBehavior CO_OD_ROM.errorBehavior
|
||||
#define ODL_errorBehavior_arrayLength 6
|
||||
#define ODA_errorBehavior_communication 0
|
||||
#define ODA_errorBehavior_communicationOther 1
|
||||
#define ODA_errorBehavior_communicationPassive 2
|
||||
#define ODA_errorBehavior_generic 3
|
||||
#define ODA_errorBehavior_deviceProfile 4
|
||||
#define ODA_errorBehavior_manufacturerSpecific 5
|
||||
|
||||
/*1200, Data Type: SDOServerParameter_t */
|
||||
#define OD_SDOServerParameter CO_OD_ROM.SDOServerParameter
|
||||
|
||||
/*1400, Data Type: RPDOCommunicationParameter_t */
|
||||
#define OD_RPDOCommunicationParameter CO_OD_ROM.RPDOCommunicationParameter
|
||||
|
||||
/*1600, Data Type: RPDOMappingParameter_t */
|
||||
#define OD_RPDOMappingParameter CO_OD_ROM.RPDOMappingParameter
|
||||
|
||||
/*1800, Data Type: TPDOCommunicationParameter_t */
|
||||
#define OD_TPDOCommunicationParameter CO_OD_ROM.TPDOCommunicationParameter
|
||||
|
||||
/*1a00, Data Type: TPDOMappingParameter_t */
|
||||
#define OD_TPDOMappingParameter CO_OD_ROM.TPDOMappingParameter
|
||||
|
||||
/*1f80, Data Type: UNSIGNED32 */
|
||||
#define OD_NMTStartup CO_OD_ROM.NMTStartup
|
||||
|
||||
/*2100, Data Type: OCTET_STRING */
|
||||
#define OD_errorStatusBits CO_OD_RAM.errorStatusBits
|
||||
#define ODL_errorStatusBits_stringLength 10
|
||||
|
||||
/*2101, Data Type: UNSIGNED32 */
|
||||
#define OD_powerOnCounter CO_OD_EEPROM.powerOnCounter
|
||||
|
||||
/*2102, Data Type: UNSIGNED32 */
|
||||
#define OD_buttonPressCounter CO_OD_RAM.buttonPressCounter
|
||||
|
||||
#endif
|
1706
samples/subsys/canbus/canopen/objdict/objdict.eds
Normal file
1706
samples/subsys/canbus/canopen/objdict/objdict.eds
Normal file
File diff suppressed because it is too large
Load diff
1079
samples/subsys/canbus/canopen/objdict/objdict.xml
Normal file
1079
samples/subsys/canbus/canopen/objdict/objdict.xml
Normal file
File diff suppressed because it is too large
Load diff
18
samples/subsys/canbus/canopen/prj.conf
Normal file
18
samples/subsys/canbus/canopen/prj.conf
Normal file
|
@ -0,0 +1,18 @@
|
|||
CONFIG_LOG=y
|
||||
CONFIG_CANOPEN_LOG_LEVEL_DBG=y
|
||||
|
||||
CONFIG_CAN=y
|
||||
CONFIG_CAN_MAX_FILTER=13
|
||||
|
||||
CONFIG_FLASH=y
|
||||
CONFIG_FLASH_MAP=y
|
||||
CONFIG_NVS=y
|
||||
CONFIG_SETTINGS=y
|
||||
CONFIG_SETTINGS_NVS=y
|
||||
|
||||
CONFIG_CANOPEN=y
|
||||
CONFIG_CANOPEN_SYNC_THREAD=y
|
||||
CONFIG_CANOPEN_STORAGE=y
|
||||
CONFIG_CANOPEN_LEDS=y
|
||||
|
||||
CONFIG_REBOOT=y
|
12
samples/subsys/canbus/canopen/sample.yaml
Normal file
12
samples/subsys/canbus/canopen/sample.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
sample:
|
||||
name: CANopen sample
|
||||
tests:
|
||||
sample.subsys.canbus.canopen:
|
||||
tags: CAN
|
||||
depends_on: can
|
||||
platform_whitelist: twr_ke18f frdm_k64f
|
||||
harness: console
|
||||
harness_config:
|
||||
type: one_line
|
||||
regex:
|
||||
- "(.*)CANopen stack initialized"
|
301
samples/subsys/canbus/canopen/src/main.c
Normal file
301
samples/subsys/canbus/canopen/src/main.c
Normal file
|
@ -0,0 +1,301 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Vestas Wind Systems A/S
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <power/reboot.h>
|
||||
#include <settings/settings.h>
|
||||
#include <canbus/canopen.h>
|
||||
|
||||
#define LOG_LEVEL CONFIG_CANOPEN_LOG_LEVEL
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_REGISTER(app);
|
||||
|
||||
#if defined(CONFIG_CANOPEN_INTERFACE_CAN_0)
|
||||
#define CAN_INTERFACE DT_ALIAS_CAN_0_LABEL
|
||||
#define CAN_BITRATE (DT_ALIAS_CAN_0_BUS_SPEED / 1000)
|
||||
#elif defined(CONFIG_CANOPEN_INTERFACE_CAN_1)
|
||||
#define CAN_INTERFACE DT_ALIAS_CAN_1_LABEL
|
||||
#define CAN_BITRATE (DT_ALIAS_CAN_1_BUS_SPEED / 1000)
|
||||
#else
|
||||
#error CANopen CAN interface not set
|
||||
#endif
|
||||
|
||||
#ifdef DT_ALIAS_GREEN_LED_GPIOS_CONTROLLER
|
||||
#define LED_GREEN_PORT DT_ALIAS_GREEN_LED_GPIOS_CONTROLLER
|
||||
#define LED_GREEN_PIN DT_ALIAS_GREEN_LED_GPIOS_PIN
|
||||
#define LED_GREEN_FLAGS DT_ALIAS_GREEN_LED_GPIOS_FLAGS
|
||||
#endif
|
||||
|
||||
#ifdef DT_ALIAS_RED_LED_GPIOS_CONTROLLER
|
||||
#define LED_RED_PORT DT_ALIAS_RED_LED_GPIOS_CONTROLLER
|
||||
#define LED_RED_PIN DT_ALIAS_RED_LED_GPIOS_PIN
|
||||
#define LED_RED_FLAGS DT_ALIAS_RED_LED_GPIOS_FLAGS
|
||||
#endif
|
||||
|
||||
#ifdef DT_ALIAS_SW0_GPIOS_CONTROLLER
|
||||
#define BUTTON_PORT DT_ALIAS_SW0_GPIOS_CONTROLLER
|
||||
#define BUTTON_PIN DT_ALIAS_SW0_GPIOS_PIN
|
||||
#define BUTTON_FLAGS DT_ALIAS_SW0_GPIOS_FLAGS
|
||||
static struct gpio_callback button_callback;
|
||||
#endif
|
||||
|
||||
struct led_indicator {
|
||||
struct device *dev;
|
||||
u32_t pin;
|
||||
u32_t flags;
|
||||
};
|
||||
|
||||
static struct led_indicator led_green;
|
||||
static struct led_indicator led_red;
|
||||
static u32_t counter;
|
||||
|
||||
/**
|
||||
* @brief Callback for setting LED indicator state.
|
||||
*
|
||||
* @param value true if the LED indicator shall be turned on, false otherwise.
|
||||
* @param arg argument that was passed when LEDs were initialized.
|
||||
*/
|
||||
static void led_callback(bool value, void *arg)
|
||||
{
|
||||
struct led_indicator *led = arg;
|
||||
bool drive = value;
|
||||
|
||||
if (!led || !led->dev) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((led->flags & GPIO_INT_ACTIVE_HIGH) == GPIO_INT_ACTIVE_LOW) {
|
||||
drive = !drive;
|
||||
}
|
||||
|
||||
gpio_pin_write(led->dev, led->pin, drive);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure LED indicators pins and callbacks.
|
||||
*
|
||||
* This routine configures the GPIOs for the red and green LEDs (if
|
||||
* available).
|
||||
*
|
||||
* @param nmt CANopenNode NMT object.
|
||||
*/
|
||||
static void config_leds(CO_NMT_t *nmt)
|
||||
{
|
||||
#ifdef LED_GREEN_PORT
|
||||
led_green.dev = device_get_binding(LED_GREEN_PORT);
|
||||
led_green.pin = LED_GREEN_PIN;
|
||||
led_green.flags = LED_GREEN_FLAGS;
|
||||
if (led_green.dev) {
|
||||
gpio_pin_configure(led_green.dev, LED_GREEN_PIN, GPIO_DIR_OUT);
|
||||
}
|
||||
#endif /* LED_GREEN_PORT */
|
||||
#ifdef LED_RED_PORT
|
||||
led_red.dev = device_get_binding(LED_RED_PORT);
|
||||
led_red.pin = LED_RED_PIN;
|
||||
led_red.flags = LED_RED_FLAGS;
|
||||
if (led_red.dev) {
|
||||
gpio_pin_configure(led_red.dev, LED_RED_PIN, GPIO_DIR_OUT);
|
||||
}
|
||||
#endif /* LED_RED_PORT */
|
||||
|
||||
canopen_leds_init(nmt,
|
||||
led_green.dev ? led_callback : NULL, &led_green,
|
||||
led_red.dev ? led_callback : NULL, &led_red);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Button press counter object dictionary handler function.
|
||||
*
|
||||
* This function is called upon SDO access to the button press counter
|
||||
* object (index 0x2102) in the object dictionary.
|
||||
*
|
||||
* @param odf_arg object dictionary function argument.
|
||||
*
|
||||
* @return SDO abort code.
|
||||
*/
|
||||
static CO_SDO_abortCode_t odf_2102(CO_ODF_arg_t *odf_arg)
|
||||
{
|
||||
u32_t value;
|
||||
|
||||
value = CO_getUint32(odf_arg->data);
|
||||
|
||||
if (odf_arg->reading) {
|
||||
return CO_SDO_AB_NONE;
|
||||
}
|
||||
|
||||
if (odf_arg->subIndex != 0U) {
|
||||
return CO_SDO_AB_NONE;
|
||||
}
|
||||
|
||||
if (value != 0) {
|
||||
/* Preserve old value */
|
||||
memcpy(odf_arg->data, odf_arg->ODdataStorage, sizeof(u32_t));
|
||||
return CO_SDO_AB_DATA_TRANSF;
|
||||
}
|
||||
|
||||
LOG_INF("Resetting button press counter");
|
||||
counter = 0;
|
||||
|
||||
return CO_SDO_AB_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Button press interrupt callback.
|
||||
*
|
||||
* @param port GPIO device struct.
|
||||
* @param cb GPIO callback struct.
|
||||
* @param pins GPIO pin mask that triggered the interrupt.
|
||||
*/
|
||||
#ifdef BUTTON_PORT
|
||||
static void button_isr_callback(struct device *port, struct gpio_callback *cb,
|
||||
u32_t pins)
|
||||
{
|
||||
counter++;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Configure button GPIO pin and callback.
|
||||
*
|
||||
* This routine configures the GPIO for the button (if available).
|
||||
*/
|
||||
static void config_button(void)
|
||||
{
|
||||
#ifdef BUTTON_PORT
|
||||
struct device *dev;
|
||||
int err;
|
||||
|
||||
dev = device_get_binding(BUTTON_PORT);
|
||||
if (!dev) {
|
||||
LOG_ERR("failed to get button device");
|
||||
return;
|
||||
}
|
||||
|
||||
err = gpio_pin_configure(dev, BUTTON_PIN, GPIO_DIR_IN |
|
||||
GPIO_INT_DEBOUNCE | GPIO_INT |
|
||||
GPIO_INT_EDGE | BUTTON_FLAGS);
|
||||
|
||||
gpio_init_callback(&button_callback, button_isr_callback,
|
||||
BIT(BUTTON_PIN));
|
||||
|
||||
err = gpio_add_callback(dev, &button_callback);
|
||||
if (err) {
|
||||
LOG_ERR("failed to add button callback");
|
||||
return;
|
||||
}
|
||||
|
||||
err = gpio_pin_enable_callback(dev, BUTTON_PIN);
|
||||
if (err) {
|
||||
LOG_ERR("failed to enable button callback");
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main application entry point.
|
||||
*
|
||||
* The main application thread is responsible for initializing the
|
||||
* CANopen stack and doing the non real-time processing.
|
||||
*/
|
||||
void main(void)
|
||||
{
|
||||
CO_NMT_reset_cmd_t reset = CO_RESET_NOT;
|
||||
CO_ReturnError_t err;
|
||||
struct device *can;
|
||||
u16_t timeout;
|
||||
u32_t elapsed;
|
||||
s64_t timestamp;
|
||||
int ret;
|
||||
|
||||
can = device_get_binding(CAN_INTERFACE);
|
||||
if (!can) {
|
||||
LOG_ERR("CAN interface not found");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = settings_subsys_init();
|
||||
if (ret) {
|
||||
LOG_ERR("failed to initialize settings subsystem (err = %d)",
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = settings_load();
|
||||
if (ret) {
|
||||
LOG_ERR("failed to load settings (err = %d)", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
OD_powerOnCounter++;
|
||||
|
||||
config_button();
|
||||
|
||||
while (reset != CO_RESET_APP) {
|
||||
elapsed = 0U; /* milliseconds */
|
||||
|
||||
err = CO_init(can, CONFIG_CANOPEN_NODE_ID, CAN_BITRATE);
|
||||
if (err != CO_ERROR_NO) {
|
||||
LOG_ERR("CO_init failed (err = %d)", err);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INF("CANopen stack initialized");
|
||||
|
||||
canopen_storage_attach(CO->SDO[0], CO->em);
|
||||
config_leds(CO->NMT);
|
||||
CO_OD_configure(CO->SDO[0], OD_2102_buttonPressCounter,
|
||||
odf_2102, NULL, 0U, 0U);
|
||||
|
||||
CO_CANsetNormalMode(CO->CANmodule[0]);
|
||||
|
||||
while (true) {
|
||||
timeout = 50U; /* default timeout in milliseconds */
|
||||
timestamp = k_uptime_get();
|
||||
reset = CO_process(CO, (uint16_t)elapsed, &timeout);
|
||||
|
||||
if (reset != CO_RESET_NOT) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (timeout > 0) {
|
||||
CO_LOCK_OD();
|
||||
OD_buttonPressCounter = counter;
|
||||
CO_UNLOCK_OD();
|
||||
|
||||
ret = canopen_storage_save(
|
||||
CANOPEN_STORAGE_EEPROM);
|
||||
if (ret) {
|
||||
LOG_ERR("failed to save EEPROM");
|
||||
}
|
||||
/*
|
||||
* Try to sleep for as long as the
|
||||
* stack requested and calculate the
|
||||
* exact time elapsed.
|
||||
*/
|
||||
k_sleep(K_MSEC(timeout));
|
||||
elapsed = k_uptime_delta_32(×tamp);
|
||||
} else {
|
||||
/*
|
||||
* Do not sleep, more processing to be
|
||||
* done by the stack.
|
||||
*/
|
||||
elapsed = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
if (reset == CO_RESET_COMM) {
|
||||
LOG_INF("Resetting communication");
|
||||
}
|
||||
}
|
||||
|
||||
LOG_INF("Resetting device");
|
||||
|
||||
CO_delete(CAN_INTERFACE);
|
||||
sys_reboot(SYS_REBOOT_COLD);
|
||||
}
|
12
samples/subsys/canbus/canopen/twr_ke18f.overlay
Normal file
12
samples/subsys/canbus/canopen/twr_ke18f.overlay
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Vestas Wind Systems A/S
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
green-led = &green_led;
|
||||
red-led = &red_led;
|
||||
};
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue