CO_PDO.h 18 KB

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