-
-
Notifications
You must be signed in to change notification settings - Fork 666
/
CO_PDO.h
387 lines (357 loc) · 15.6 KB
/
CO_PDO.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
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
/**
* CANopen Process Data Object protocol.
*
* @file CO_PDO.h
* @ingroup CO_PDO
* @author Janez Paternoster
* @copyright 2004 - 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 CO_PDO_H
#define CO_PDO_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup CO_PDO PDO
* @ingroup CO_CANopen
* @{
*
* CANopen Process Data Object protocol.
*
* Process data objects are used for real-time data transfer with no protocol
* overhead.
*
* TPDO with specific identifier is transmitted by one device and recieved by
* zero or more devices as RPDO. PDO communication parameters(COB-ID,
* transmission type, etc.) are in Object Dictionary at index 0x1400+ and
* 0x1800+. PDO mapping parameters (size and contents of the PDO) are in Object
* Dictionary at index 0x1600+ and 0x1A00+.
*
* Features of the PDO as implemented here, in CANopenNode:
* - Dynamic PDO mapping.
* - Map granularity of one byte.
* - After RPDO is received from CAN bus, its data are copied to buffer.
* Function CO_RPDO_process() (called by application) copies data to
* mapped objects in Object Dictionary. Synchronous RPDOs are processed AFTER
* reception of the next SYNC message.
* - Function CO_TPDO_process() (called by application) sends TPDO if
* necessary. There are possible different transmission types, including
* automatic detection of Change of State of specific variable.
*/
/**
* RPDO communication parameter. The same as record from Object dictionary (index 0x1400+).
*/
typedef struct{
uint8_t maxSubIndex; /**< Equal to 2 */
/** Communication object identifier for message received. Meaning of the specific bits:
- Bit 0-10: COB-ID for PDO, to change it bit 31 must be set.
- Bit 11-29: set to 0 for 11 bit COB-ID.
- Bit 30: If true, rtr are NOT allowed for PDO.
- Bit 31: If true, node does NOT use the PDO. */
uint32_t COB_IDUsedByRPDO;
/** Transmission type. Values:
- 0-240: Reciving is synchronous, process after next reception of the SYNC object.
- 241-253: Not used.
- 254: Manufacturer specific.
- 255: Asynchronous. */
uint8_t transmissionType;
}CO_RPDOCommPar_t;
/**
* RPDO mapping parameter. The same as record from Object dictionary (index 0x1600+).
*/
typedef struct{
/** Actual number of mapped objects from 0 to 8. To change mapped object,
this value must be 0. */
uint8_t numberOfMappedObjects;
/** Location and size of the mapped object. Bit meanings `0xIIIISSLL`:
- Bit 0-7: Data Length in bits.
- Bit 8-15: Subindex from object distionary.
- Bit 16-31: Index from object distionary. */
uint32_t mappedObject1;
uint32_t mappedObject2; /**< Same */
uint32_t mappedObject3; /**< Same */
uint32_t mappedObject4; /**< Same */
uint32_t mappedObject5; /**< Same */
uint32_t mappedObject6; /**< Same */
uint32_t mappedObject7; /**< Same */
uint32_t mappedObject8; /**< Same */
}CO_RPDOMapPar_t;
/**
* TPDO communication parameter. The same as record from Object dictionary (index 0x1800+).
*/
typedef struct{
uint8_t maxSubIndex; /**< Equal to 6 */
/** Communication object identifier for transmitting message. Meaning of the specific bits:
- Bit 0-10: COB-ID for PDO, to change it bit 31 must be set.
- Bit 11-29: set to 0 for 11 bit COB-ID.
- Bit 30: If true, rtr are NOT allowed for PDO.
- Bit 31: If true, node does NOT use the PDO. */
uint32_t COB_IDUsedByTPDO;
/** Transmission type. Values:
- 0: Transmiting is synchronous, specification in device profile.
- 1-240: Transmiting is synchronous after every N-th SYNC object.
- 241-251: Not used.
- 252-253: Transmited only on reception of Remote Transmission Request.
- 254: Manufacturer specific.
- 255: Asinchronous, specification in device profile. */
uint8_t transmissionType;
/** Minimum time between transmissions of the PDO in 100micro seconds.
Zero disables functionality. */
uint16_t inhibitTime;
/** Not used */
uint8_t compatibilityEntry;
/** Time between periodic transmissions of the PDO in milliseconds.
Zero disables functionality. */
uint16_t eventTimer;
/** Used with numbered SYNC messages. Values:
- 0: Counter of the SYNC message shall not be processed.
- 1-240: The SYNC message with the counter value equal to this value
shall be regarded as the first received SYNC message. */
uint8_t SYNCStartValue;
}CO_TPDOCommPar_t;
/**
* TPDO mapping parameter. The same as record from Object dictionary (index 0x1A00+).
*/
typedef struct{
/** Actual number of mapped objects from 0 to 8. To change mapped object,
this value must be 0. */
uint8_t numberOfMappedObjects;
/** Location and size of the mapped object. Bit meanings `0xIIIISSLL`:
- Bit 0-7: Data Length in bits.
- Bit 8-15: Subindex from object distionary.
- Bit 16-31: Index from object distionary. */
uint32_t mappedObject1;
uint32_t mappedObject2; /**< Same */
uint32_t mappedObject3; /**< Same */
uint32_t mappedObject4; /**< Same */
uint32_t mappedObject5; /**< Same */
uint32_t mappedObject6; /**< Same */
uint32_t mappedObject7; /**< Same */
uint32_t mappedObject8; /**< Same */
}CO_TPDOMapPar_t;
/**
* RPDO object.
*/
typedef struct{
CO_EM_t *em; /**< From CO_RPDO_init() */
CO_SDO_t *SDO; /**< From CO_RPDO_init() */
CO_SYNC_t *SYNC; /**< From CO_RPDO_init() */
const CO_RPDOCommPar_t *RPDOCommPar;/**< From CO_RPDO_init() */
const CO_RPDOMapPar_t *RPDOMapPar; /**< From CO_RPDO_init() */
uint8_t *operatingState; /**< From CO_RPDO_init() */
uint8_t nodeId; /**< From CO_RPDO_init() */
uint16_t defaultCOB_ID; /**< From CO_RPDO_init() */
uint8_t restrictionFlags;/**< From CO_RPDO_init() */
/** True, if PDO is enabled and valid */
bool_t valid;
/** True, if PDO synchronous (transmissionType <= 240) */
bool_t synchronous;
/** Data length of the received PDO message. Calculated from mapping */
uint8_t dataLength;
/** Pointers to 8 data objects, where PDO will be copied */
uint8_t *mapPointer[8];
/** Variable indicates, if new PDO message received from CAN bus. */
volatile void *CANrxNew[2];
/** 8 data bytes of the received message. */
uint8_t CANrxData[2][8];
CO_CANmodule_t *CANdevRx; /**< From CO_RPDO_init() */
uint16_t CANdevRxIdx; /**< From CO_RPDO_init() */
}CO_RPDO_t;
/**
* TPDO object.
*/
typedef struct{
CO_EM_t *em; /**< From CO_TPDO_init() */
CO_SDO_t *SDO; /**< From CO_TPDO_init() */
CO_SYNC_t *SYNC; /**< From CO_TPDO_init() */
const CO_TPDOCommPar_t *TPDOCommPar;/**< From CO_TPDO_init() */
const CO_TPDOMapPar_t *TPDOMapPar; /**< From CO_TPDO_init() */
uint8_t *operatingState; /**< From CO_TPDO_init() */
uint8_t nodeId; /**< From CO_TPDO_init() */
uint16_t defaultCOB_ID; /**< From CO_TPDO_init() */
uint8_t restrictionFlags;/**< From CO_TPDO_init() */
bool_t valid; /**< True, if PDO is enabled and valid */
/** Data length of the transmitting PDO message. Calculated from mapping */
uint8_t dataLength;
/** If application set this flag, PDO will be later sent by
function CO_TPDO_process(). Depends on transmission type. */
uint8_t sendRequest;
/** Pointers to 8 data objects, where PDO will be copied */
uint8_t *mapPointer[8];
/** Each flag bit is connected with one mapPointer. If flag bit
is true, CO_TPDO_process() functiuon will send PDO if
Change of State is detected on value pointed by that mapPointer */
uint8_t sendIfCOSFlags;
/** SYNC counter used for PDO sending */
uint8_t syncCounter;
/** Inhibit timer used for inhibit PDO sending translated to microseconds */
uint32_t inhibitTimer;
/** Event timer used for PDO sending translated to microseconds */
uint32_t eventTimer;
CO_CANmodule_t *CANdevTx; /**< From CO_TPDO_init() */
CO_CANtx_t *CANtxBuff; /**< CAN transmit buffer inside CANdev */
uint16_t CANdevTxIdx; /**< From CO_TPDO_init() */
}CO_TPDO_t;
/**
* Initialize RPDO object.
*
* Function must be called in the communication reset section.
*
* @param RPDO This object will be initialized.
* @param em Emergency object.
* @param SDO SDO server object.
* @param operatingState Pointer to variable indicating CANopen device NMT internal state.
* @param nodeId CANopen Node ID of this device. If default COB_ID is used, value will be added.
* @param defaultCOB_ID Default COB ID for this PDO (without NodeId).
* See #CO_Default_CAN_ID_t
* @param restrictionFlags Flag bits indicates, how PDO communication
* and mapping parameters are handled:
* - Bit1: If true, communication parameters are writeable only in pre-operational NMT state.
* - Bit2: If true, mapping parameters are writeable only in pre-operational NMT state.
* - Bit3: If true, communication parameters are read-only.
* - Bit4: If true, mapping parameters are read-only.
* @param RPDOCommPar Pointer to _RPDO communication parameter_ record from Object
* dictionary (index 0x1400+).
* @param RPDOMapPar Pointer to _RPDO mapping parameter_ record from Object
* dictionary (index 0x1600+).
* @param idx_RPDOCommPar Index in Object Dictionary.
* @param idx_RPDOMapPar Index in Object Dictionary.
* @param CANdevRx CAN device for PDO reception.
* @param CANdevRxIdx Index of receive buffer in the above CAN device.
*
* @return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT.
*/
CO_ReturnError_t CO_RPDO_init(
CO_RPDO_t *RPDO,
CO_EM_t *em,
CO_SDO_t *SDO,
CO_SYNC_t *SYNC,
uint8_t *operatingState,
uint8_t nodeId,
uint16_t defaultCOB_ID,
uint8_t restrictionFlags,
const CO_RPDOCommPar_t *RPDOCommPar,
const CO_RPDOMapPar_t *RPDOMapPar,
uint16_t idx_RPDOCommPar,
uint16_t idx_RPDOMapPar,
CO_CANmodule_t *CANdevRx,
uint16_t CANdevRxIdx);
/**
* Initialize TPDO object.
*
* Function must be called in the communication reset section.
*
* @param TPDO This object will be initialized.
* @param em Emergency object.
* @param SDO SDO object.
* @param operatingState Pointer to variable indicating CANopen device NMT internal state.
* @param nodeId CANopen Node ID of this device. If default COB_ID is used, value will be added.
* @param defaultCOB_ID Default COB ID for this PDO (without NodeId).
* See #CO_Default_CAN_ID_t
* @param restrictionFlags Flag bits indicates, how PDO communication
* and mapping parameters are handled:
* - Bit1: If true, communication parameters are writeable only in pre-operational NMT state.
* - Bit2: If true, mapping parameters are writeable only in pre-operational NMT state.
* - Bit3: If true, communication parameters are read-only.
* - Bit4: If true, mapping parameters are read-only.
* @param TPDOCommPar Pointer to _TPDO communication parameter_ record from Object
* dictionary (index 0x1400+).
* @param TPDOMapPar Pointer to _TPDO mapping parameter_ record from Object
* dictionary (index 0x1600+).
* @param idx_TPDOCommPar Index in Object Dictionary.
* @param idx_TPDOMapPar Index in Object Dictionary.
* @param CANdevTx CAN device used for PDO transmission.
* @param CANdevTxIdx Index of transmit buffer in the above CAN device.
*
* @return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT.
*/
CO_ReturnError_t CO_TPDO_init(
CO_TPDO_t *TPDO,
CO_EM_t *em,
CO_SDO_t *SDO,
CO_SYNC_t *SYNC,
uint8_t *operatingState,
uint8_t nodeId,
uint16_t defaultCOB_ID,
uint8_t restrictionFlags,
const CO_TPDOCommPar_t *TPDOCommPar,
const CO_TPDOMapPar_t *TPDOMapPar,
uint16_t idx_TPDOCommPar,
uint16_t idx_TPDOMapPar,
CO_CANmodule_t *CANdevTx,
uint16_t CANdevTxIdx);
/**
* Verify Change of State of the PDO.
*
* Function verifies if variable mapped to TPDO has changed its value. Verified
* are only variables, which has set attribute _CO_ODA_TPDO_DETECT_COS_ in
* #CO_SDO_OD_attributes_t.
*
* Function may be called by application just before CO_TPDO_process() function,
* for example: `TPDOx->sendRequest = CO_TPDOisCOS(TPDOx); CO_TPDO_process(TPDOx, ....`
*
* @param TPDO TPDO object.
*
* @return True if COS was detected.
*/
uint8_t CO_TPDOisCOS(CO_TPDO_t *TPDO);
/**
* Send TPDO message.
*
* Function prepares TPDO data from Object Dictionary variables. It should not
* be called by application, it is called from CO_TPDO_process().
*
*
* @param TPDO TPDO object.
*
* @return Same as CO_CANsend().
*/
int16_t CO_TPDOsend(CO_TPDO_t *TPDO);
/**
* Process received PDO messages.
*
* Function must be called cyclically in any NMT state. It copies data from RPDO
* to Object Dictionary variables if: new PDO receives and PDO is valid and NMT
* operating state is operational. It does not verify _transmission type_.
*
* @param RPDO This object.
* @param syncWas True, if CANopen SYNC message was just received or transmitted.
*/
void CO_RPDO_process(CO_RPDO_t *RPDO, bool_t syncWas);
/**
* Process transmitting PDO messages.
*
* Function must be called cyclically in any NMT state. It prepares and sends
* TPDO if necessary. If Change of State needs to be detected, function
* CO_TPDOisCOS() must be called before.
*
* @param TPDO This object.
* @param SYNC SYNC object. Ignored if NULL.
* @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_TPDO_process(
CO_TPDO_t *TPDO,
bool_t syncWas,
uint32_t timeDifference_us);
#ifdef __cplusplus
}
#endif /*__cplusplus*/
/** @} */
#endif