forked from zephyrproject-rtos/canopennode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CANopen.h
324 lines (290 loc) · 11 KB
/
CANopen.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
/**
* Main CANopen stack file.
*
* It combines Object dictionary (CO_OD) and all other CANopen source files.
* Configuration information are read from CO_OD.h file. This file uses one
* CAN module. If multiple CAN modules are to be used, then this file may be
* customized for different CANopen configuration. (One or multiple CANopen
* device on one or multiple CAN modules.)
*
* @file CANopen.h
* @ingroup CO_CANopen
* @author Janez Paternoster
* @author Uwe Kindler
* @copyright 2010 - 2020 Janez Paternoster
*
* This file is part of CANopenNode, an opensource CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
*
* 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 CANopen_H
#define CANopen_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup CO_CANopen CANopen stack
* @{
*
* CANopenNode is free and open source CANopen Stack.
*
* CANopen is the internationally standardized (EN 50325-4) (CiA DS-301)
* CAN-based higher-layer protocol for embedded control system. For more
* information on CANopen see http://www.can-cia.org/
*
* CANopenNode homepage is https://github.com/CANopenNode/CANopenNode
*
* 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_driver.h"
#include "CO_OD.h"
#include "CO_SDO.h"
#include "CO_Emergency.h"
#include "CO_NMT_Heartbeat.h"
#include "CO_SYNC.h"
#include "CO_TIME.h"
#include "CO_PDO.h"
#include "CO_HBconsumer.h"
#if CO_NO_SDO_CLIENT != 0
#include "CO_SDOmaster.h"
#endif
#if CO_NO_TRACE > 0
#include "CO_trace.h"
#endif
#if CO_NO_LSS_SERVER == 1
#include "CO_LSSslave.h"
#endif
#if CO_NO_LSS_CLIENT == 1
#include "CO_LSSmaster.h"
#endif
/**
* Default CANopen identifiers.
*
* Default CANopen identifiers for CANopen communication objects. Same as
* 11-bit addresses of CAN messages. These are default identifiers and
* can be changed in CANopen. Especially PDO identifiers are confgured
* in PDO linking phase of the CANopen network configuration.
*/
typedef enum{
CO_CAN_ID_NMT_SERVICE = 0x000, /**< 0x000, Network management */
CO_CAN_ID_SYNC = 0x080, /**< 0x080, Synchronous message */
CO_CAN_ID_EMERGENCY = 0x080, /**< 0x080, Emergency messages (+nodeID) */
CO_CAN_ID_TIME = 0x100, /**< 0x100, Time message */
CO_CAN_ID_TPDO_1 = 0x180, /**< 0x180, Default TPDO1 (+nodeID) */
CO_CAN_ID_RPDO_1 = 0x200, /**< 0x200, Default RPDO1 (+nodeID) */
CO_CAN_ID_TPDO_2 = 0x280, /**< 0x280, Default TPDO2 (+nodeID) */
CO_CAN_ID_RPDO_2 = 0x300, /**< 0x300, Default RPDO2 (+nodeID) */
CO_CAN_ID_TPDO_3 = 0x380, /**< 0x380, Default TPDO3 (+nodeID) */
CO_CAN_ID_RPDO_3 = 0x400, /**< 0x400, Default RPDO3 (+nodeID) */
CO_CAN_ID_TPDO_4 = 0x480, /**< 0x480, Default TPDO4 (+nodeID) */
CO_CAN_ID_RPDO_4 = 0x500, /**< 0x500, Default RPDO5 (+nodeID) */
CO_CAN_ID_TSDO = 0x580, /**< 0x580, SDO response from server (+nodeID) */
CO_CAN_ID_RSDO = 0x600, /**< 0x600, SDO request from client (+nodeID) */
CO_CAN_ID_HEARTBEAT = 0x700, /**< 0x700, Heartbeat message */
CO_CAN_ID_LSS_CLI = 0x7E4, /**< 0x7E4, LSS response from server to client */
CO_CAN_ID_LSS_SRV = 0x7E5 /**< 0x7E5, LSS request from client to server */
}CO_Default_CAN_ID_t;
/**
* CANopen stack object combines pointers to all CANopen objects.
*/
typedef struct{
CO_CANmodule_t *CANmodule[1]; /**< CAN module objects */
CO_SDO_t *SDO[CO_NO_SDO_SERVER]; /**< SDO object */
CO_EM_t *em; /**< Emergency report object */
CO_EMpr_t *emPr; /**< Emergency process object */
CO_NMT_t *NMT; /**< NMT object */
CO_SYNC_t *SYNC; /**< SYNC object */
CO_TIME_t *TIME; /**< TIME object */
CO_RPDO_t *RPDO[CO_NO_RPDO];/**< RPDO objects */
CO_TPDO_t *TPDO[CO_NO_TPDO];/**< TPDO objects */
CO_HBconsumer_t *HBcons; /**< Heartbeat consumer object*/
#if CO_NO_LSS_SERVER == 1
CO_LSSslave_t *LSSslave; /**< LSS server/slave object */
#endif
#if CO_NO_LSS_CLIENT == 1
CO_LSSmaster_t *LSSmaster; /**< LSS master/client object */
#endif
#if CO_NO_SDO_CLIENT != 0
CO_SDOclient_t *SDOclient[CO_NO_SDO_CLIENT]; /**< SDO client object */
#endif
#if CO_NO_TRACE > 0
CO_trace_t *trace[CO_NO_TRACE]; /**< Trace object for monitoring variables */
#endif
}CO_t;
/** CANopen object */
extern CO_t *CO;
/**
* Function CO_sendNMTcommand() is simple function, which sends CANopen message.
* This part of code is an example of custom definition of simple CANopen
* object. Follow the code in CANopen.c file. If macro CO_NO_NMT_MASTER is 1,
* function CO_sendNMTcommand can be used to send NMT master message.
*
* @param co CANopen object.
* @param command NMT command.
* @param nodeID Node ID.
*
* @return 0: Operation completed successfully.
* @return other: same as CO_CANsend().
*/
#if CO_NO_NMT_MASTER == 1
CO_ReturnError_t CO_sendNMTcommand(CO_t *co, uint8_t command, uint8_t nodeID);
#endif
#if CO_NO_LSS_SERVER == 1
/**
* Allocate and initialize memory for CANopen object
*
* Function must be called in the communication reset section.
*
* @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT,
* CO_ERROR_OUT_OF_MEMORY
*/
CO_ReturnError_t CO_new(void);
/**
* Initialize CAN driver
*
* Function must be called in the communication reset section.
*
* @param CANdriverState Pointer to the CAN module, passed to CO_CANmodule_init().
* @param bitRate CAN bit rate.
* @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT,
* CO_ERROR_ILLEGAL_BAUDRATE, CO_ERROR_OUT_OF_MEMORY
*/
CO_ReturnError_t CO_CANinit(
void *CANdriverState,
uint16_t bitRate);
/**
* Initialize CANopen LSS slave
*
* Function must be called in the communication reset section.
*
* @param nodeId Node ID of the CANopen device (1 ... 127) or CO_LSS_NODE_ID_ASSIGNMENT
* @param bitRate CAN bit rate.
* @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT
*/
CO_ReturnError_t CO_LSSinit(
uint8_t nodeId,
uint16_t bitRate);
/**
* Initialize CANopen stack.
*
* Function must be called in the communication reset section.
*
* @param nodeId Node ID of the CANopen device (1 ... 127).
* @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT
*/
CO_ReturnError_t CO_CANopenInit(
uint8_t nodeId);
#else /* CO_NO_LSS_SERVER == 1 */
/**
* Initialize CANopen stack.
*
* Function must be called in the communication reset section.
*
* @param CANdriverState Pointer to the user-defined CAN base structure, passed to CO_CANmodule_init().
* @param nodeId Node ID of the CANopen device (1 ... 127).
* @param bitRate CAN bit rate.
*
* @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT,
* CO_ERROR_OUT_OF_MEMORY, CO_ERROR_ILLEGAL_BAUDRATE
*/
CO_ReturnError_t CO_init(
void *CANdriverState,
uint8_t nodeId,
uint16_t bitRate);
#endif /* CO_NO_LSS_SERVER == 1 */
/**
* Delete CANopen object and free memory. Must be called at program exit.
*
* @param CANdriverState Pointer to the user-defined CAN base structure, passed to CO_CANmodule_init().
*/
void CO_delete(void *CANdriverState);
/**
* Process CANopen objects.
*
* Function must be called cyclically. It processes all "asynchronous" CANopen
* objects.
*
* @param co CANopen object.
* @param timeDifference_ms Time difference from previous function call in [milliseconds].
* @param timerNext_ms Return value - info to OS - maximum delay after function
* should be called next time in [milliseconds]. Value can be used for OS
* sleep time. Initial value must be set to something, 50ms typically.
* Output will be equal or lower to initial value. If there is new object
* to process, delay should be suspended and this function should be
* called immediately. Parameter is ignored if NULL.
*
* @return #CO_NMT_reset_cmd_t from CO_NMT_process().
*/
CO_NMT_reset_cmd_t CO_process(
CO_t *co,
uint16_t timeDifference_ms,
uint16_t *timerNext_ms);
#if CO_NO_SYNC == 1
/**
* Process CANopen SYNC objects.
*
* Function must be called cyclically from real time thread with constant
* interval (1ms typically). It processes SYNC CANopen objects.
*
* @param co CANopen object.
* @param timeDifference_us Time difference from previous function call in [microseconds].
*
* @return True, if CANopen SYNC message was just received or transmitted.
*/
bool_t CO_process_SYNC(
CO_t *co,
uint32_t timeDifference_us);
#endif
/**
* Process CANopen RPDO objects.
*
* Function must be called cyclically from real time thread with constant.
* interval (1ms typically). It processes receive PDO CANopen objects.
*
* @param co CANopen object.
* @param syncWas True, if CANopen SYNC message was just received or transmitted.
*/
void CO_process_RPDO(
CO_t *co,
bool_t syncWas);
/**
* Process CANopen TPDO objects.
*
* Function must be called cyclically from real time thread with constant.
* interval (1ms typically). It processes transmit PDO CANopen objects.
*
* @param co CANopen object.
* @param syncWas True, if CANopen SYNC message was just received or transmitted.
* @param timeDifference_us Time difference from previous function call in [microseconds].
*/
void CO_process_TPDO(
CO_t *co,
bool_t syncWas,
uint32_t timeDifference_us);
#ifdef __cplusplus
}
#endif /*__cplusplus*/
/** @} */
#endif