CO_SRDO.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. /**
  2. * CANopen Safety Related Data Object protocol.
  3. *
  4. * @file CO_SRDO.h
  5. * @ingroup CO_SRDO
  6. * @author Robert Grüning
  7. * @copyright 2020 - 2020 Robert Grüning
  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_SRDO_H
  26. #define CO_SRDO_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. /* default configuration, see CO_config.h */
  32. #ifndef CO_CONFIG_SRDO
  33. #define CO_CONFIG_SRDO (0)
  34. #endif
  35. #ifndef CO_CONFIG_SRDO_MINIMUM_DELAY
  36. #define CO_CONFIG_SRDO_MINIMUM_DELAY 0
  37. #endif
  38. #if ((CO_CONFIG_SRDO) & CO_CONFIG_SRDO_ENABLE) || defined CO_DOXYGEN
  39. #ifdef __cplusplus
  40. extern "C" {
  41. #endif
  42. /**
  43. * @defgroup CO_SRDO SRDO
  44. * @ingroup CO_CANopen_304
  45. * @{
  46. *
  47. * CANopen Safety Related Data Object protocol.
  48. *
  49. * The functionality is very similar to that of the PDOs.
  50. * The main differences is every message is send and received twice.
  51. * The second message must be bitwise inverted. The delay between the two messages and between each message pair is monitored.
  52. * The distinction between sending and receiving SRDO is made at runtime (for PDO it is compile time).
  53. * If the security protocol is used, at least one SRDO is mandatory.
  54. */
  55. /**
  56. * SRDO communication parameter. The same as record from Object dictionary (index 0x1301-0x1340).
  57. */
  58. typedef struct{
  59. uint8_t maxSubIndex; /**< Equal to 6 */
  60. /** Direction of the SRDO. Values:
  61. - 0: SRDO is invalid (deleted)
  62. - 1: SRDO is transmiting data
  63. - 2: SRDO is receive data */
  64. uint8_t informationDirection;
  65. /** Refresh-time / SCT
  66. - in tx mode (Refresh-time): transmission interval
  67. - in rx mode (SCT): receive timeout between two SRDO */
  68. uint16_t safetyCycleTime;
  69. /** SRVT
  70. - in tx mode: unsed
  71. - in rx mode: receive timeout between first and second SRDO message */
  72. uint8_t safetyRelatedValidationTime;
  73. /** Transmission type. Values:
  74. - 254: Manufacturer specific.*/
  75. uint8_t transmissionType;
  76. /** Communication object identifier for message received. Meaning of the specific bits:
  77. - Bit 0-10: COB-ID for SRDO
  78. - Bit 11-31: set to 0 for 11 bit COB-ID. */
  79. uint32_t COB_ID1_normal;
  80. /** Communication object identifier for message received. Meaning of the specific bits:
  81. - Bit 0-10: COB-ID for SRDO
  82. - Bit 11-31: set to 0 for 11 bit COB-ID. */
  83. uint32_t COB_ID2_inverted;
  84. }CO_SRDOCommPar_t;
  85. typedef struct{
  86. /** Actual number of mapped objects from 0 to 16. Only even numbers are allowed. To change mapped object,
  87. this value must be 0. */
  88. uint8_t numberOfMappedObjects;
  89. /** Location and size of the mapped object.
  90. Even index is the normal object. Odd index is the inverted 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 mappedObjects[16];
  95. }CO_SRDOMapPar_t;
  96. /**
  97. * Gurad Object for SRDO
  98. * monitors:
  99. * - access to CRC objects
  100. * - access configuration valid flag
  101. * - change in operation state
  102. */
  103. typedef struct{
  104. CO_NMT_internalState_t *operatingState; /**< pointer to current operation state */
  105. CO_NMT_internalState_t operatingStatePrev; /**< last operation state */
  106. uint8_t *configurationValid; /**< pointer to the configuration valid flag in OD */
  107. uint8_t checkCRC; /**< specifies whether a CRC check should be performed */
  108. }CO_SRDOGuard_t;
  109. /**
  110. * SRDO object.
  111. */
  112. typedef struct{
  113. CO_EM_t *em; /**< From CO_SRDO_init() */
  114. CO_SDO_t *SDO; /**< From CO_SRDO_init() */
  115. CO_SRDOGuard_t *SRDOGuard; /**< From CO_SRDO_init() */
  116. /** Pointers to 2*8 data objects, where SRDO will be copied */
  117. uint8_t *mapPointer[2][8];
  118. /** Data length of the received SRDO message. Calculated from mapping */
  119. uint8_t dataLength;
  120. uint8_t nodeId; /**< From CO_SRDO_init() */
  121. uint16_t defaultCOB_ID[2]; /**< From CO_SRDO_init() */
  122. /** 0 - invalid, 1 - tx, 2 - rx */
  123. uint8_t valid;
  124. const CO_SRDOCommPar_t *SRDOCommPar; /**< From CO_SRDO_init() */
  125. const CO_SRDOMapPar_t *SRDOMapPar; /**< From CO_SRDO_init() */
  126. const uint16_t *checksum; /**< From CO_SRDO_init() */
  127. CO_CANmodule_t *CANdevRx; /**< From CO_SRDO_init() */
  128. CO_CANmodule_t *CANdevTx; /**< From CO_SRDO_init() */
  129. CO_CANtx_t *CANtxBuff[2]; /**< CAN transmit buffer inside CANdevTx */
  130. uint16_t CANdevRxIdx[2]; /**< From CO_SRDO_init() */
  131. uint16_t CANdevTxIdx[2]; /**< From CO_SRDO_init() */
  132. uint8_t toogle; /**< defines the current state */
  133. uint32_t timer; /**< transmit timer and receive timeout */
  134. /** Variable indicates, if new SRDO message received from CAN bus. */
  135. volatile void *CANrxNew[2];
  136. /** 2*8 data bytes of the received message. */
  137. uint8_t CANrxData[2][8];
  138. /** From CO_SRDO_initCallbackEnterSafeState() or NULL */
  139. void (*pFunctSignalSafe)(void *object);
  140. /** From CO_SRDO_initCallbackEnterSafeState() or NULL */
  141. void *functSignalObjectSafe;
  142. #if ((CO_CONFIG_SRDO) & CO_CONFIG_FLAG_CALLBACK_PRE) || defined CO_DOXYGEN
  143. /** From CO_SRDO_initCallbackPre() or NULL */
  144. void (*pFunctSignalPre)(void *object);
  145. /** From CO_SRDO_initCallbackPre() or NULL */
  146. void *functSignalObjectPre;
  147. #endif
  148. }CO_SRDO_t;
  149. /**
  150. * Initialize SRDOGuard object.
  151. *
  152. * Function must be called in the communication reset section.
  153. *
  154. * @param SRDOGuard This object will be initialized.
  155. * @param SDO SDO object.
  156. * @param operatingState Pointer to variable indicating CANopen device NMT internal state.
  157. * @param configurationValid Pointer to variable with the SR valid flag
  158. * @param idx_SRDOvalid Index in Object Dictionary
  159. * @param idx_SRDOcrc Index in Object Dictionary
  160. *
  161. * @return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT.
  162. */
  163. CO_ReturnError_t CO_SRDOGuard_init(
  164. CO_SRDOGuard_t *SRDOGuard,
  165. CO_SDO_t *SDO,
  166. CO_NMT_internalState_t *operatingState,
  167. uint8_t *configurationValid,
  168. uint16_t idx_SRDOvalid,
  169. uint16_t idx_SRDOcrc);
  170. /**
  171. * Process operation and valid state changes.
  172. *
  173. * @param SRDOGuard This object.
  174. * @return uint8_t command for CO_SRDO_process().
  175. * - bit 0 entered operational
  176. * - bit 1 validate checksum
  177. */
  178. uint8_t CO_SRDOGuard_process(
  179. CO_SRDOGuard_t *SRDOGuard);
  180. /**
  181. * Initialize SRDO object.
  182. *
  183. * Function must be called in the communication reset section.
  184. *
  185. * @param SRDO This object will be initialized.
  186. * @param SRDOGuard SRDOGuard object.
  187. * @param em Emergency object.
  188. * @param SDO SDO object.
  189. * @param nodeId CANopen Node ID of this device. If default COB_ID is used, value will be added.
  190. * @param defaultCOB_ID Default COB ID for this SRDO (without NodeId).
  191. * @param SRDOCommPar Pointer to _SRDO communication parameter_ record from Object
  192. * dictionary (index 0x1301+).
  193. * @param SRDOMapPar Pointer to _SRDO mapping parameter_ record from Object
  194. * dictionary (index 0x1381+).
  195. * @param checksum
  196. * @param idx_SRDOCommPar Index in Object Dictionary
  197. * @param idx_SRDOMapPar Index in Object Dictionary
  198. * @param CANdevRx CAN device used for SRDO reception.
  199. * @param CANdevRxIdxNormal Index of receive buffer in the above CAN device.
  200. * @param CANdevRxIdxInverted Index of receive buffer in the above CAN device.
  201. * @param CANdevTx CAN device used for SRDO transmission.
  202. * @param CANdevTxIdxNormal Index of transmit buffer in the above CAN device.
  203. * @param CANdevTxIdxInverted Index of transmit buffer in the above CAN device.
  204. *
  205. * @return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT.
  206. */
  207. CO_ReturnError_t CO_SRDO_init(
  208. CO_SRDO_t *SRDO,
  209. CO_SRDOGuard_t *SRDOGuard,
  210. CO_EM_t *em,
  211. CO_SDO_t *SDO,
  212. uint8_t nodeId,
  213. uint16_t defaultCOB_ID,
  214. const CO_SRDOCommPar_t *SRDOCommPar,
  215. const CO_SRDOMapPar_t *SRDOMapPar,
  216. const uint16_t *checksum,
  217. uint16_t idx_SRDOCommPar,
  218. uint16_t idx_SRDOMapPar,
  219. CO_CANmodule_t *CANdevRx,
  220. uint16_t CANdevRxIdxNormal,
  221. uint16_t CANdevRxIdxInverted,
  222. CO_CANmodule_t *CANdevTx,
  223. uint16_t CANdevTxIdxNormal,
  224. uint16_t CANdevTxIdxInverted);
  225. #if ((CO_CONFIG_SRDO) & CO_CONFIG_FLAG_CALLBACK_PRE) || defined CO_DOXYGEN
  226. /**
  227. * Initialize SRDO callback function.
  228. *
  229. * Function initializes optional callback function, which should immediately
  230. * start processing of CO_SRDO_process() function.
  231. * Callback is called after SRDO message is received from the CAN bus.
  232. *
  233. * @param SRDO This object.
  234. * @param object Pointer to object, which will be passed to pFunctSignalPre(). Can be NULL
  235. * @param pFunctSignalPre Pointer to the callback function. Not called if NULL.
  236. */
  237. void CO_SRDO_initCallbackPre(
  238. CO_SRDO_t *SRDO,
  239. void *object,
  240. void (*pFunctSignalPre)(void *object));
  241. #endif
  242. /**
  243. * Initialize SRDO callback function.
  244. *
  245. * Function initializes optional callback function, that is called when SRDO enters a safe state.
  246. * This happens when a timeout is reached or the data is inconsistent. The safe state itself is not further defined.
  247. * One measure, for example, would be to go back to the pre-operational state
  248. * Callback is called from CO_SRDO_process().
  249. *
  250. * @param SRDO This object.
  251. * @param object Pointer to object, which will be passed to pFunctSignalSafe(). Can be NULL
  252. * @param pFunctSignalSafe Pointer to the callback function. Not called if NULL.
  253. */
  254. void CO_SRDO_initCallbackEnterSafeState(
  255. CO_SRDO_t *SRDO,
  256. void *object,
  257. void (*pFunctSignalSafe)(void *object));
  258. /**
  259. * Send SRDO on event
  260. *
  261. * Sends SRDO before the next refresh timer tiggers. The message itself is send in CO_SRDO_process().
  262. * After the transmission the timer is reset to the full refresh time.
  263. *
  264. * @param SRDO This object.
  265. * @return CO_ReturnError_t CO_ERROR_NO if request is granted
  266. */
  267. CO_ReturnError_t CO_SRDO_requestSend(
  268. CO_SRDO_t *SRDO);
  269. /**
  270. * Process transmitting/receiving SRDO messages.
  271. *
  272. * This function verifies the checksum on demand.
  273. * This function also configures the SRDO on operation state change to operational
  274. *
  275. * @param SRDO This object.
  276. * @param commands result from CO_SRDOGuard_process().
  277. * @param timeDifference_us Time difference from previous function call in [microseconds].
  278. * @param [out] timerNext_us info to OS.
  279. */
  280. void CO_SRDO_process(
  281. CO_SRDO_t *SRDO,
  282. uint8_t commands,
  283. uint32_t timeDifference_us,
  284. uint32_t *timerNext_us);
  285. /** @} */ /* CO_SRDO */
  286. #ifdef __cplusplus
  287. }
  288. #endif /*__cplusplus*/
  289. #endif /* (CO_CONFIG_SRDO) & CO_CONFIG_SRDO_ENABLE */
  290. #endif /* CO_SRDO_H */