1 /** 2 * CANopen Process Data Object protocol. 3 * 4 * @file CO_PDO.h 5 * @ingroup CO_PDO 6 * @author Janez Paternoster 7 * @copyright 2004 - 2020 Janez Paternoster 8 * 9 * This file is part of CANopenNode, an opensource CANopen Stack. 10 * Project home page is <https://github.com/CANopenNode/CANopenNode>. 11 * For more information on CANopen see <http://www.can-cia.org/>. 12 * 13 * Licensed under the Apache License, Version 2.0 (the "License"); 14 * you may not use this file except in compliance with the License. 15 * You may obtain a copy of the License at 16 * 17 * http://www.apache.org/licenses/LICENSE-2.0 18 * 19 * Unless required by applicable law or agreed to in writing, software 20 * distributed under the License is distributed on an "AS IS" BASIS, 21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 * See the License for the specific language governing permissions and 23 * limitations under the License. 24 */ 25 26 27 #ifndef CO_PDO_H 28 #define CO_PDO_H 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 /** 35 * @defgroup CO_PDO PDO 36 * @ingroup CO_CANopen 37 * @{ 38 * 39 * CANopen Process Data Object protocol. 40 * 41 * Process data objects are used for real-time data transfer with no protocol 42 * overhead. 43 * 44 * TPDO with specific identifier is transmitted by one device and recieved by 45 * zero or more devices as RPDO. PDO communication parameters(COB-ID, 46 * transmission type, etc.) are in Object Dictionary at index 0x1400+ and 47 * 0x1800+. PDO mapping parameters (size and contents of the PDO) are in Object 48 * Dictionary at index 0x1600+ and 0x1A00+. 49 * 50 * Features of the PDO as implemented here, in CANopenNode: 51 * - Dynamic PDO mapping. 52 * - Map granularity of one byte. 53 * - After RPDO is received from CAN bus, its data are copied to buffer. 54 * Function CO_RPDO_process() (called by application) copies data to 55 * mapped objects in Object Dictionary. Synchronous RPDOs are processed AFTER 56 * reception of the next SYNC message. 57 * - Function CO_TPDO_process() (called by application) sends TPDO if 58 * necessary. There are possible different transmission types, including 59 * automatic detection of Change of State of specific variable. 60 */ 61 62 63 /** 64 * RPDO communication parameter. The same as record from Object dictionary (index 0x1400+). 65 */ 66 typedef struct{ 67 uint8_t maxSubIndex; /**< Equal to 2 */ 68 /** Communication object identifier for message received. Meaning of the specific bits: 69 - Bit 0-10: COB-ID for PDO, to change it bit 31 must be set. 70 - Bit 11-29: set to 0 for 11 bit COB-ID. 71 - Bit 30: If true, rtr are NOT allowed for PDO. 72 - Bit 31: If true, node does NOT use the PDO. */ 73 uint32_t COB_IDUsedByRPDO; 74 /** Transmission type. Values: 75 - 0-240: Reciving is synchronous, process after next reception of the SYNC object. 76 - 241-253: Not used. 77 - 254: Manufacturer specific. 78 - 255: Asynchronous. */ 79 uint8_t transmissionType; 80 }CO_RPDOCommPar_t; 81 82 83 /** 84 * RPDO mapping parameter. The same as record from Object dictionary (index 0x1600+). 85 */ 86 typedef struct{ 87 /** Actual number of mapped objects from 0 to 8. To change mapped object, 88 this value must be 0. */ 89 uint8_t numberOfMappedObjects; 90 /** Location and size of the mapped object. Bit meanings `0xIIIISSLL`: 91 - Bit 0-7: Data Length in bits. 92 - Bit 8-15: Subindex from object distionary. 93 - Bit 16-31: Index from object distionary. */ 94 uint32_t mappedObject1; 95 uint32_t mappedObject2; /**< Same */ 96 uint32_t mappedObject3; /**< Same */ 97 uint32_t mappedObject4; /**< Same */ 98 uint32_t mappedObject5; /**< Same */ 99 uint32_t mappedObject6; /**< Same */ 100 uint32_t mappedObject7; /**< Same */ 101 uint32_t mappedObject8; /**< Same */ 102 }CO_RPDOMapPar_t; 103 104 105 /** 106 * TPDO communication parameter. The same as record from Object dictionary (index 0x1800+). 107 */ 108 typedef struct{ 109 uint8_t maxSubIndex; /**< Equal to 6 */ 110 /** Communication object identifier for transmitting message. Meaning of the specific bits: 111 - Bit 0-10: COB-ID for PDO, to change it bit 31 must be set. 112 - Bit 11-29: set to 0 for 11 bit COB-ID. 113 - Bit 30: If true, rtr are NOT allowed for PDO. 114 - Bit 31: If true, node does NOT use the PDO. */ 115 uint32_t COB_IDUsedByTPDO; 116 /** Transmission type. Values: 117 - 0: Transmiting is synchronous, specification in device profile. 118 - 1-240: Transmiting is synchronous after every N-th SYNC object. 119 - 241-251: Not used. 120 - 252-253: Transmited only on reception of Remote Transmission Request. 121 - 254: Manufacturer specific. 122 - 255: Asinchronous, specification in device profile. */ 123 uint8_t transmissionType; 124 /** Minimum time between transmissions of the PDO in 100micro seconds. 125 Zero disables functionality. */ 126 uint16_t inhibitTime; 127 /** Not used */ 128 uint8_t compatibilityEntry; 129 /** Time between periodic transmissions of the PDO in milliseconds. 130 Zero disables functionality. */ 131 uint16_t eventTimer; 132 /** Used with numbered SYNC messages. Values: 133 - 0: Counter of the SYNC message shall not be processed. 134 - 1-240: The SYNC message with the counter value equal to this value 135 shall be regarded as the first received SYNC message. */ 136 uint8_t SYNCStartValue; 137 }CO_TPDOCommPar_t; 138 139 140 /** 141 * TPDO mapping parameter. The same as record from Object dictionary (index 0x1A00+). 142 */ 143 typedef struct{ 144 /** Actual number of mapped objects from 0 to 8. To change mapped object, 145 this value must be 0. */ 146 uint8_t numberOfMappedObjects; 147 /** Location and size of the mapped object. Bit meanings `0xIIIISSLL`: 148 - Bit 0-7: Data Length in bits. 149 - Bit 8-15: Subindex from object distionary. 150 - Bit 16-31: Index from object distionary. */ 151 uint32_t mappedObject1; 152 uint32_t mappedObject2; /**< Same */ 153 uint32_t mappedObject3; /**< Same */ 154 uint32_t mappedObject4; /**< Same */ 155 uint32_t mappedObject5; /**< Same */ 156 uint32_t mappedObject6; /**< Same */ 157 uint32_t mappedObject7; /**< Same */ 158 uint32_t mappedObject8; /**< Same */ 159 }CO_TPDOMapPar_t; 160 161 162 /** 163 * RPDO object. 164 */ 165 typedef struct{ 166 CO_EM_t *em; /**< From CO_RPDO_init() */ 167 CO_SDO_t *SDO; /**< From CO_RPDO_init() */ 168 CO_SYNC_t *SYNC; /**< From CO_RPDO_init() */ 169 const CO_RPDOCommPar_t *RPDOCommPar;/**< From CO_RPDO_init() */ 170 const CO_RPDOMapPar_t *RPDOMapPar; /**< From CO_RPDO_init() */ 171 uint8_t *operatingState; /**< From CO_RPDO_init() */ 172 uint8_t nodeId; /**< From CO_RPDO_init() */ 173 uint16_t defaultCOB_ID; /**< From CO_RPDO_init() */ 174 uint8_t restrictionFlags;/**< From CO_RPDO_init() */ 175 /** True, if PDO is enabled and valid */ 176 bool_t valid; 177 /** True, if PDO synchronous (transmissionType <= 240) */ 178 bool_t synchronous; 179 /** Data length of the received PDO message. Calculated from mapping */ 180 uint8_t dataLength; 181 /** Pointers to 8 data objects, where PDO will be copied */ 182 uint8_t *mapPointer[8]; 183 /** Variable indicates, if new PDO message received from CAN bus. */ 184 volatile void *CANrxNew[2]; 185 /** 8 data bytes of the received message. */ 186 uint8_t CANrxData[2][8]; 187 CO_CANmodule_t *CANdevRx; /**< From CO_RPDO_init() */ 188 uint16_t CANdevRxIdx; /**< From CO_RPDO_init() */ 189 }CO_RPDO_t; 190 191 192 /** 193 * TPDO object. 194 */ 195 typedef struct{ 196 CO_EM_t *em; /**< From CO_TPDO_init() */ 197 CO_SDO_t *SDO; /**< From CO_TPDO_init() */ 198 CO_SYNC_t *SYNC; /**< From CO_TPDO_init() */ 199 const CO_TPDOCommPar_t *TPDOCommPar;/**< From CO_TPDO_init() */ 200 const CO_TPDOMapPar_t *TPDOMapPar; /**< From CO_TPDO_init() */ 201 uint8_t *operatingState; /**< From CO_TPDO_init() */ 202 uint8_t nodeId; /**< From CO_TPDO_init() */ 203 uint16_t defaultCOB_ID; /**< From CO_TPDO_init() */ 204 uint8_t restrictionFlags;/**< From CO_TPDO_init() */ 205 bool_t valid; /**< True, if PDO is enabled and valid */ 206 /** Data length of the transmitting PDO message. Calculated from mapping */ 207 uint8_t dataLength; 208 /** If application set this flag, PDO will be later sent by 209 function CO_TPDO_process(). Depends on transmission type. */ 210 uint8_t sendRequest; 211 /** Pointers to 8 data objects, where PDO will be copied */ 212 uint8_t *mapPointer[8]; 213 /** Each flag bit is connected with one mapPointer. If flag bit 214 is true, CO_TPDO_process() functiuon will send PDO if 215 Change of State is detected on value pointed by that mapPointer */ 216 uint8_t sendIfCOSFlags; 217 /** SYNC counter used for PDO sending */ 218 uint8_t syncCounter; 219 /** Inhibit timer used for inhibit PDO sending translated to microseconds */ 220 uint32_t inhibitTimer; 221 /** Event timer used for PDO sending translated to microseconds */ 222 uint32_t eventTimer; 223 CO_CANmodule_t *CANdevTx; /**< From CO_TPDO_init() */ 224 CO_CANtx_t *CANtxBuff; /**< CAN transmit buffer inside CANdev */ 225 uint16_t CANdevTxIdx; /**< From CO_TPDO_init() */ 226 }CO_TPDO_t; 227 228 229 /** 230 * Initialize RPDO object. 231 * 232 * Function must be called in the communication reset section. 233 * 234 * @param RPDO This object will be initialized. 235 * @param em Emergency object. 236 * @param SDO SDO server object. 237 * @param operatingState Pointer to variable indicating CANopen device NMT internal state. 238 * @param nodeId CANopen Node ID of this device. If default COB_ID is used, value will be added. 239 * @param defaultCOB_ID Default COB ID for this PDO (without NodeId). 240 * See #CO_Default_CAN_ID_t 241 * @param restrictionFlags Flag bits indicates, how PDO communication 242 * and mapping parameters are handled: 243 * - Bit1: If true, communication parameters are writeable only in pre-operational NMT state. 244 * - Bit2: If true, mapping parameters are writeable only in pre-operational NMT state. 245 * - Bit3: If true, communication parameters are read-only. 246 * - Bit4: If true, mapping parameters are read-only. 247 * @param RPDOCommPar Pointer to _RPDO communication parameter_ record from Object 248 * dictionary (index 0x1400+). 249 * @param RPDOMapPar Pointer to _RPDO mapping parameter_ record from Object 250 * dictionary (index 0x1600+). 251 * @param idx_RPDOCommPar Index in Object Dictionary. 252 * @param idx_RPDOMapPar Index in Object Dictionary. 253 * @param CANdevRx CAN device for PDO reception. 254 * @param CANdevRxIdx Index of receive buffer in the above CAN device. 255 * 256 * @return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT. 257 */ 258 CO_ReturnError_t CO_RPDO_init( 259 CO_RPDO_t *RPDO, 260 CO_EM_t *em, 261 CO_SDO_t *SDO, 262 CO_SYNC_t *SYNC, 263 uint8_t *operatingState, 264 uint8_t nodeId, 265 uint16_t defaultCOB_ID, 266 uint8_t restrictionFlags, 267 const CO_RPDOCommPar_t *RPDOCommPar, 268 const CO_RPDOMapPar_t *RPDOMapPar, 269 uint16_t idx_RPDOCommPar, 270 uint16_t idx_RPDOMapPar, 271 CO_CANmodule_t *CANdevRx, 272 uint16_t CANdevRxIdx); 273 274 275 /** 276 * Initialize TPDO object. 277 * 278 * Function must be called in the communication reset section. 279 * 280 * @param TPDO This object will be initialized. 281 * @param em Emergency object. 282 * @param SDO SDO object. 283 * @param operatingState Pointer to variable indicating CANopen device NMT internal state. 284 * @param nodeId CANopen Node ID of this device. If default COB_ID is used, value will be added. 285 * @param defaultCOB_ID Default COB ID for this PDO (without NodeId). 286 * See #CO_Default_CAN_ID_t 287 * @param restrictionFlags Flag bits indicates, how PDO communication 288 * and mapping parameters are handled: 289 * - Bit1: If true, communication parameters are writeable only in pre-operational NMT state. 290 * - Bit2: If true, mapping parameters are writeable only in pre-operational NMT state. 291 * - Bit3: If true, communication parameters are read-only. 292 * - Bit4: If true, mapping parameters are read-only. 293 * @param TPDOCommPar Pointer to _TPDO communication parameter_ record from Object 294 * dictionary (index 0x1400+). 295 * @param TPDOMapPar Pointer to _TPDO mapping parameter_ record from Object 296 * dictionary (index 0x1600+). 297 * @param idx_TPDOCommPar Index in Object Dictionary. 298 * @param idx_TPDOMapPar Index in Object Dictionary. 299 * @param CANdevTx CAN device used for PDO transmission. 300 * @param CANdevTxIdx Index of transmit buffer in the above CAN device. 301 * 302 * @return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT. 303 */ 304 CO_ReturnError_t CO_TPDO_init( 305 CO_TPDO_t *TPDO, 306 CO_EM_t *em, 307 CO_SDO_t *SDO, 308 CO_SYNC_t *SYNC, 309 uint8_t *operatingState, 310 uint8_t nodeId, 311 uint16_t defaultCOB_ID, 312 uint8_t restrictionFlags, 313 const CO_TPDOCommPar_t *TPDOCommPar, 314 const CO_TPDOMapPar_t *TPDOMapPar, 315 uint16_t idx_TPDOCommPar, 316 uint16_t idx_TPDOMapPar, 317 CO_CANmodule_t *CANdevTx, 318 uint16_t CANdevTxIdx); 319 320 321 /** 322 * Verify Change of State of the PDO. 323 * 324 * Function verifies if variable mapped to TPDO has changed its value. Verified 325 * are only variables, which has set attribute _CO_ODA_TPDO_DETECT_COS_ in 326 * #CO_SDO_OD_attributes_t. 327 * 328 * Function may be called by application just before CO_TPDO_process() function, 329 * for example: `TPDOx->sendRequest = CO_TPDOisCOS(TPDOx); CO_TPDO_process(TPDOx, ....` 330 * 331 * @param TPDO TPDO object. 332 * 333 * @return True if COS was detected. 334 */ 335 uint8_t CO_TPDOisCOS(CO_TPDO_t *TPDO); 336 337 338 /** 339 * Send TPDO message. 340 * 341 * Function prepares TPDO data from Object Dictionary variables. It should not 342 * be called by application, it is called from CO_TPDO_process(). 343 * 344 * 345 * @param TPDO TPDO object. 346 * 347 * @return Same as CO_CANsend(). 348 */ 349 int16_t CO_TPDOsend(CO_TPDO_t *TPDO); 350 351 352 /** 353 * Process received PDO messages. 354 * 355 * Function must be called cyclically in any NMT state. It copies data from RPDO 356 * to Object Dictionary variables if: new PDO receives and PDO is valid and NMT 357 * operating state is operational. It does not verify _transmission type_. 358 * 359 * @param RPDO This object. 360 * @param syncWas True, if CANopen SYNC message was just received or transmitted. 361 */ 362 void CO_RPDO_process(CO_RPDO_t *RPDO, bool_t syncWas); 363 364 365 /** 366 * Process transmitting PDO messages. 367 * 368 * Function must be called cyclically in any NMT state. It prepares and sends 369 * TPDO if necessary. If Change of State needs to be detected, function 370 * CO_TPDOisCOS() must be called before. 371 * 372 * @param TPDO This object. 373 * @param SYNC SYNC object. Ignored if NULL. 374 * @param syncWas True, if CANopen SYNC message was just received or transmitted. 375 * @param timeDifference_us Time difference from previous function call in [microseconds]. 376 */ 377 void CO_TPDO_process( 378 CO_TPDO_t *TPDO, 379 bool_t syncWas, 380 uint32_t timeDifference_us); 381 382 #ifdef __cplusplus 383 } 384 #endif /*__cplusplus*/ 385 386 /** @} */ 387 #endif 388