CO_LSSmaster.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. /**
  2. * CANopen Layer Setting Service - master protocol.
  3. *
  4. * @file CO_LSSmaster.h
  5. * @ingroup CO_LSS
  6. * @author Martin Wagner
  7. * @copyright 2017 - 2020 Neuberger Gebaeudeautomation GmbH
  8. *
  9. *
  10. * This file is part of CANopenNode, an opensource CANopen Stack.
  11. * Project home page is <https://github.com/CANopenNode/CANopenNode>.
  12. * For more information on CANopen see <http://www.can-cia.org/>.
  13. *
  14. * Licensed under the Apache License, Version 2.0 (the "License");
  15. * you may not use this file except in compliance with the License.
  16. * You may obtain a copy of the License at
  17. *
  18. * http://www.apache.org/licenses/LICENSE-2.0
  19. *
  20. * Unless required by applicable law or agreed to in writing, software
  21. * distributed under the License is distributed on an "AS IS" BASIS,
  22. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  23. * See the License for the specific language governing permissions and
  24. * limitations under the License.
  25. */
  26. #ifndef CO_LSSmaster_H
  27. #define CO_LSSmaster_H
  28. #include "305/CO_LSS.h"
  29. #if ((CO_CONFIG_LSS) & CO_CONFIG_LSS_MASTER) || defined CO_DOXYGEN
  30. #ifdef __cplusplus
  31. extern "C" {
  32. #endif
  33. /**
  34. * @defgroup CO_LSSmaster LSS Master
  35. * @ingroup CO_CANopen_305
  36. * @{
  37. *
  38. * CANopen Layer Setting Service - master protocol.
  39. *
  40. * The client/master can use the following services
  41. * - node selection via LSS address
  42. * - node selection via LSS fastscan
  43. * - Inquire LSS address of currently selected node
  44. * - Inquire node ID
  45. * - Configure bit timing
  46. * - Configure node ID
  47. * - Activate bit timing parameters
  48. * - Store configuration
  49. *
  50. * The LSS master is initalized during the CANopenNode initialization process.
  51. * Except for enabling the LSS master in the configurator, no further
  52. * run-time configuration is needed for basic operation.
  53. * The LSS master does basic checking of commands and command sequence.
  54. *
  55. * ###Usage
  56. *
  57. * Usage of the CANopen LSS master is demonstrated in CANopenSocket application,
  58. * see CO_LSS_master.c / CO_LSS_master.h files.
  59. *
  60. * It essentially is always as following:
  61. * - select node(s)
  62. * - call master command(s)
  63. * - evaluate return value
  64. * - deselect nodes
  65. *
  66. * All commands need to be run cyclically, e.g. like this
  67. * \code{.c}
  68. interval = 0;
  69. do {
  70. ret = CO_LSSmaster_InquireNodeId(LSSmaster, interval, &outval);
  71. interval = 1; ms
  72. sleep(interval);
  73. } while (ret == CO_LSSmaster_WAIT_SLAVE);
  74. * \endcode
  75. *
  76. * A more advanced implementation can make use of the callback function to
  77. * shorten waiting times.
  78. */
  79. /**
  80. * Return values of LSS master functions.
  81. */
  82. typedef enum {
  83. CO_LSSmaster_SCAN_FINISHED = 2, /**< Scanning finished successful */
  84. CO_LSSmaster_WAIT_SLAVE = 1, /**< No response arrived from slave yet */
  85. CO_LSSmaster_OK = 0, /**< Success, end of communication */
  86. CO_LSSmaster_TIMEOUT = -1, /**< No reply received */
  87. CO_LSSmaster_ILLEGAL_ARGUMENT = -2, /**< Invalid argument */
  88. CO_LSSmaster_INVALID_STATE = -3, /**< State machine not ready or already processing a request */
  89. CO_LSSmaster_SCAN_NOACK = -4, /**< No node found that matches scan request */
  90. CO_LSSmaster_SCAN_FAILED = -5, /**< An error occurred while scanning. Try again */
  91. CO_LSSmaster_OK_ILLEGAL_ARGUMENT = -101, /**< LSS success, node rejected argument because of non-supported value */
  92. CO_LSSmaster_OK_MANUFACTURER = -102, /**< LSS success, node rejected argument with manufacturer error code */
  93. } CO_LSSmaster_return_t;
  94. /**
  95. * LSS master object.
  96. */
  97. typedef struct{
  98. uint32_t timeout_us; /**< LSS response timeout in us */
  99. uint8_t state; /**< Node is currently selected */
  100. uint8_t command; /**< Active command */
  101. uint32_t timeoutTimer; /**< Timeout timer for LSS communication */
  102. uint8_t fsState; /**< Current state of fastscan master state machine */
  103. uint8_t fsLssSub; /**< Current state of node state machine */
  104. uint8_t fsBitChecked; /**< Current scan bit position */
  105. uint32_t fsIdNumber; /**< Current scan result */
  106. volatile void *CANrxNew; /**< Indication if new LSS message is received from CAN bus. It needs to be cleared when received message is completely processed. */
  107. uint8_t CANrxData[8]; /**< 8 data bytes of the received message */
  108. #if ((CO_CONFIG_LSS) & CO_CONFIG_FLAG_CALLBACK_PRE) || defined CO_DOXYGEN
  109. void (*pFunctSignal)(void *object); /**< From CO_LSSmaster_initCallbackPre() or NULL */
  110. void *functSignalObject;/**< Pointer to object */
  111. #endif
  112. CO_CANmodule_t *CANdevTx; /**< From CO_LSSmaster_init() */
  113. CO_CANtx_t *TXbuff; /**< CAN transmit buffer */
  114. }CO_LSSmaster_t;
  115. /**
  116. * Default timeout for LSS slave in ms. This is the same as for SDO. For more
  117. * info about LSS timeout see #CO_LSSmaster_changeTimeout()
  118. */
  119. #ifndef CO_LSSmaster_DEFAULT_TIMEOUT
  120. #define CO_LSSmaster_DEFAULT_TIMEOUT 1000U /* ms */
  121. #endif
  122. /**
  123. * Initialize LSS object.
  124. *
  125. * Function must be called in the communication reset section.
  126. *
  127. * @param LSSmaster This object will be initialized.
  128. * @param timeout_ms slave response timeout in ms, for more detail see
  129. * #CO_LSSmaster_changeTimeout()
  130. * @param CANdevRx CAN device for LSS master reception.
  131. * @param CANdevRxIdx Index of receive buffer in the above CAN device.
  132. * @param CANidLssSlave COB ID for reception.
  133. * @param CANdevTx CAN device for LSS master transmission.
  134. * @param CANdevTxIdx Index of transmit buffer in the above CAN device.
  135. * @param CANidLssMaster COB ID for transmission.
  136. * @return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT.
  137. */
  138. CO_ReturnError_t CO_LSSmaster_init(
  139. CO_LSSmaster_t *LSSmaster,
  140. uint16_t timeout_ms,
  141. CO_CANmodule_t *CANdevRx,
  142. uint16_t CANdevRxIdx,
  143. uint32_t CANidLssSlave,
  144. CO_CANmodule_t *CANdevTx,
  145. uint16_t CANdevTxIdx,
  146. uint32_t CANidLssMaster);
  147. /**
  148. * Change LSS master timeout
  149. *
  150. * On LSS, a "negative ack" is signaled by the slave not answering. Because of
  151. * that, a low timeout value can significantly increase protocol speed in some
  152. * cases (e.g. fastscan). However, as soon as there is activity on the bus,
  153. * LSS messages can be delayed because of their low CAN network priority (see
  154. * #CO_Default_CAN_ID_t).
  155. *
  156. * @remark Be aware that a "late response" will seriously mess up LSS, so this
  157. * value must be selected "as high as necessary and as low as possible". CiA does
  158. * neither specify nor recommend a value.
  159. *
  160. * @remark This timeout is per-transfer. If a command internally needs multiple
  161. * transfers to complete, this timeout is applied on each transfer.
  162. *
  163. * @param LSSmaster This object.
  164. * @param timeout_ms timeout value in ms
  165. */
  166. void CO_LSSmaster_changeTimeout(
  167. CO_LSSmaster_t *LSSmaster,
  168. uint16_t timeout_ms);
  169. #if ((CO_CONFIG_LSS) & CO_CONFIG_FLAG_CALLBACK_PRE) || defined CO_DOXYGEN
  170. /**
  171. * Initialize LSSmasterRx callback function.
  172. *
  173. * Function initializes optional callback function, which should immediately
  174. * start further LSS processing. Callback is called after LSS message is
  175. * received from the CAN bus. It should signal the RTOS to resume corresponding
  176. * task.
  177. *
  178. * @param LSSmaster This object.
  179. * @param object Pointer to object, which will be passed to pFunctSignal(). Can be NULL
  180. * @param pFunctSignal Pointer to the callback function. Not called if NULL.
  181. */
  182. void CO_LSSmaster_initCallbackPre(
  183. CO_LSSmaster_t *LSSmaster,
  184. void *object,
  185. void (*pFunctSignal)(void *object));
  186. #endif
  187. /**
  188. * Request LSS switch state select
  189. *
  190. * This function can select one specific or all nodes.
  191. *
  192. * Function must be called cyclically until it returns != #CO_LSSmaster_WAIT_SLAVE
  193. * Function is non-blocking.
  194. *
  195. * @remark Only one selection can be active at any time.
  196. *
  197. * @param LSSmaster This object.
  198. * @param timeDifference_us Time difference from previous function call in
  199. * [microseconds]. Zero when request is started.
  200. * @param lssAddress LSS target address. If NULL, all nodes are selected
  201. * @return #CO_LSSmaster_ILLEGAL_ARGUMENT, #CO_LSSmaster_INVALID_STATE,
  202. * #CO_LSSmaster_WAIT_SLAVE, #CO_LSSmaster_OK, #CO_LSSmaster_TIMEOUT
  203. */
  204. CO_LSSmaster_return_t CO_LSSmaster_switchStateSelect(
  205. CO_LSSmaster_t *LSSmaster,
  206. uint32_t timeDifference_us,
  207. CO_LSS_address_t *lssAddress);
  208. /**
  209. * Request LSS switch state deselect
  210. *
  211. * This function deselects all nodes, so it doesn't matter if a specific
  212. * node is selected.
  213. *
  214. * This function also resets the LSS master state machine to a clean state
  215. *
  216. * @param LSSmaster This object.
  217. * @return #CO_LSSmaster_ILLEGAL_ARGUMENT, #CO_LSSmaster_INVALID_STATE,
  218. * #CO_LSSmaster_OK
  219. */
  220. CO_LSSmaster_return_t CO_LSSmaster_switchStateDeselect(
  221. CO_LSSmaster_t *LSSmaster);
  222. /**
  223. * Request LSS configure Bit Timing
  224. *
  225. * The new bit rate is set as new pending value.
  226. *
  227. * This function needs one specific node to be selected.
  228. *
  229. * Function must be called cyclically until it returns != #CO_LSSmaster_WAIT_SLAVE.
  230. * Function is non-blocking.
  231. *
  232. * @param LSSmaster This object.
  233. * @param timeDifference_us Time difference from previous function call in
  234. * [microseconds]. Zero when request is started.
  235. * @param bit new bit rate
  236. * @return #CO_LSSmaster_ILLEGAL_ARGUMENT, #CO_LSSmaster_INVALID_STATE,
  237. * #CO_LSSmaster_WAIT_SLAVE, #CO_LSSmaster_OK, #CO_LSSmaster_TIMEOUT,
  238. * #CO_LSSmaster_OK_MANUFACTURER, #CO_LSSmaster_OK_ILLEGAL_ARGUMENT
  239. */
  240. CO_LSSmaster_return_t CO_LSSmaster_configureBitTiming(
  241. CO_LSSmaster_t *LSSmaster,
  242. uint32_t timeDifference_us,
  243. uint16_t bit);
  244. /**
  245. * Request LSS configure node ID
  246. *
  247. * The new node id is set as new pending node ID.
  248. *
  249. * This function needs one specific node to be selected.
  250. *
  251. * Function must be called cyclically until it returns != #CO_LSSmaster_WAIT_SLAVE.
  252. * Function is non-blocking.
  253. *
  254. * @param LSSmaster This object.
  255. * @param timeDifference_us Time difference from previous function call in
  256. * [microseconds]. Zero when request is started.
  257. * @param nodeId new node ID. Special value #CO_LSS_NODE_ID_ASSIGNMENT can be
  258. * used to invalidate node ID.
  259. * @return #CO_LSSmaster_ILLEGAL_ARGUMENT, #CO_LSSmaster_INVALID_STATE,
  260. * #CO_LSSmaster_WAIT_SLAVE, #CO_LSSmaster_OK, #CO_LSSmaster_TIMEOUT,
  261. * #CO_LSSmaster_OK_MANUFACTURER, #CO_LSSmaster_OK_ILLEGAL_ARGUMENT
  262. */
  263. CO_LSSmaster_return_t CO_LSSmaster_configureNodeId(
  264. CO_LSSmaster_t *LSSmaster,
  265. uint32_t timeDifference_us,
  266. uint8_t nodeId);
  267. /**
  268. * Request LSS store configuration
  269. *
  270. * The current "pending" values for bit rate and node ID in LSS slave are
  271. * stored as "permanent" values.
  272. *
  273. * This function needs one specific node to be selected.
  274. *
  275. * Function must be called cyclically until it returns != #CO_LSSmaster_WAIT_SLAVE.
  276. * Function is non-blocking.
  277. *
  278. * @param LSSmaster This object.
  279. * @param timeDifference_us Time difference from previous function call in
  280. * [microseconds]. Zero when request is started.
  281. * @return #CO_LSSmaster_ILLEGAL_ARGUMENT, #CO_LSSmaster_INVALID_STATE,
  282. * #CO_LSSmaster_WAIT_SLAVE, #CO_LSSmaster_OK, #CO_LSSmaster_TIMEOUT,
  283. * #CO_LSSmaster_OK_MANUFACTURER, #CO_LSSmaster_OK_ILLEGAL_ARGUMENT
  284. */
  285. CO_LSSmaster_return_t CO_LSSmaster_configureStore(
  286. CO_LSSmaster_t *LSSmaster,
  287. uint32_t timeDifference_us);
  288. /**
  289. * Request LSS activate bit timing
  290. *
  291. * The current "pending" bit rate in LSS slave is applied.
  292. *
  293. * Be aware that changing the bit rate is a critical step for the network. A
  294. * failure will render the network unusable! Therefore, this function only
  295. * should be called if the following conditions are met:
  296. * - all nodes support changing bit timing
  297. * - new bit timing is successfully set as "pending" in all nodes
  298. * - all nodes have to activate the new bit timing roughly at the same time.
  299. * Therefore this function needs all nodes to be selected.
  300. *
  301. * @param LSSmaster This object.
  302. * @param switchDelay_ms delay that is applied by the slave once before and
  303. * once after switching in ms.
  304. * @return #CO_LSSmaster_ILLEGAL_ARGUMENT, #CO_LSSmaster_INVALID_STATE,
  305. * #CO_LSSmaster_OK
  306. */
  307. CO_LSSmaster_return_t CO_LSSmaster_ActivateBit(
  308. CO_LSSmaster_t *LSSmaster,
  309. uint16_t switchDelay_ms);
  310. /**
  311. * Request LSS inquire LSS address
  312. *
  313. * The LSS address value is read from the node. This is useful when the node
  314. * was selected by fastscan.
  315. *
  316. * This function needs one specific node to be selected.
  317. *
  318. * Function must be called cyclically until it returns != #CO_LSSmaster_WAIT_SLAVE.
  319. * Function is non-blocking.
  320. *
  321. * @param LSSmaster This object.
  322. * @param timeDifference_us Time difference from previous function call in
  323. * [microseconds]. Zero when request is started.
  324. * @param [out] lssAddress read result when function returns successfully
  325. * @return #CO_LSSmaster_ILLEGAL_ARGUMENT, #CO_LSSmaster_INVALID_STATE,
  326. * #CO_LSSmaster_WAIT_SLAVE, #CO_LSSmaster_OK, #CO_LSSmaster_TIMEOUT
  327. */
  328. CO_LSSmaster_return_t CO_LSSmaster_InquireLssAddress(
  329. CO_LSSmaster_t *LSSmaster,
  330. uint32_t timeDifference_us,
  331. CO_LSS_address_t *lssAddress);
  332. /**
  333. * Request LSS inquire node ID or part of LSS address
  334. *
  335. * The node-ID, identity vendor-ID, product-code, revision-number or
  336. * serial-number value is read from the node.
  337. *
  338. * This function needs one specific node to be selected.
  339. *
  340. * Function must be called cyclically until it returns != #CO_LSSmaster_WAIT_SLAVE.
  341. * Function is non-blocking.
  342. *
  343. * @param LSSmaster This object.
  344. * @param timeDifference_us Time difference from previous function call in
  345. * [microseconds]. Zero when request is started.
  346. * @param lssInquireCs One of CO_LSS_INQUIRE_xx commands from #CO_LSS_cs_t.
  347. * @param [out] value read result when function returns successfully
  348. * @return #CO_LSSmaster_ILLEGAL_ARGUMENT, #CO_LSSmaster_INVALID_STATE,
  349. * #CO_LSSmaster_WAIT_SLAVE, #CO_LSSmaster_OK, #CO_LSSmaster_TIMEOUT
  350. */
  351. CO_LSSmaster_return_t CO_LSSmaster_Inquire(
  352. CO_LSSmaster_t *LSSmaster,
  353. uint32_t timeDifference_us,
  354. CO_LSS_cs_t lssInquireCs,
  355. uint32_t *value);
  356. /**
  357. * Scan type for #CO_LSSmaster_fastscan_t scan
  358. */
  359. typedef enum {
  360. CO_LSSmaster_FS_SCAN = 0, /**< Do full 32 bit scan */
  361. CO_LSSmaster_FS_SKIP = 1, /**< Skip this value */
  362. CO_LSSmaster_FS_MATCH = 2, /**< Full 32 bit value is given as argument, just verify */
  363. } CO_LSSmaster_scantype_t;
  364. /**
  365. * Parameters for LSS fastscan #CO_LSSmaster_IdentifyFastscan
  366. */
  367. typedef struct{
  368. CO_LSSmaster_scantype_t scan[4]; /**< Scan type for each part of the LSS address */
  369. CO_LSS_address_t match; /**< Value to match in case of #CO_LSSmaster_FS_MATCH */
  370. CO_LSS_address_t found; /**< Scan result */
  371. } CO_LSSmaster_fastscan_t;
  372. /**
  373. * Select a node by LSS identify fastscan
  374. *
  375. * This initiates searching for a unconfigured node by the means of LSS fastscan
  376. * mechanism. When this function is finished
  377. * - a (more or less) arbitrary node is selected and ready for node ID assingment
  378. * - no node is selected because the given criteria do not match a node
  379. * - no node is selected because all nodes are already configured
  380. *
  381. * There are multiple ways to scan for a node. Depending on those, the scan
  382. * will take different amounts of time:
  383. * - full scan
  384. * - partial scan
  385. * - verification
  386. *
  387. * Most of the time, those are used in combination. Consider the following example:
  388. * - Vendor ID and product code are known
  389. * - Software version doesn't matter
  390. * - Serial number is unknown
  391. *
  392. * In this case, the fastscan structure should be set up as following:
  393. * \code{.c}
  394. CO_LSSmaster_fastscan_t fastscan;
  395. fastscan.scan[CO_LSS_FASTSCAN_VENDOR_ID] = CO_LSSmaster_FS_MATCH;
  396. fastscan.match.vendorID = YOUR_VENDOR_ID;
  397. fastscan.scan[CO_LSS_FASTSCAN_PRODUCT] = CO_LSSmaster_FS_MATCH;
  398. fastscan.match.productCode = YOUR_PRODUCT_CODE;
  399. fastscan.scan[CO_LSS_FASTSCAN_REV] = CO_LSSmaster_FS_SKIP;
  400. fastscan.scan[CO_LSS_FASTSCAN_SERIAL] = CO_LSSmaster_FS_SCAN;
  401. * \endcode
  402. *
  403. * This example will take 2 scan cyles for verifying vendor ID and product code
  404. * and 33 scan cycles to find the serial number.
  405. *
  406. * For scanning, the following limitations apply:
  407. * - No more than two values can be skipped
  408. * - Vendor ID cannot be skipped
  409. *
  410. * @remark When doing partial scans, it is in the responsibility of the user
  411. * that the LSS address is unique.
  412. *
  413. * This function needs that no node is selected when starting the scan process.
  414. *
  415. * Function must be called cyclically until it returns != #CO_LSSmaster_WAIT_SLAVE.
  416. * Function is non-blocking.
  417. *
  418. * @param LSSmaster This object.
  419. * @param timeDifference_us Time difference from previous function call in
  420. * [microseconds]. Zero when request is started.
  421. * @param fastscan struct according to #CO_LSSmaster_fastscan_t.
  422. * @return #CO_LSSmaster_ILLEGAL_ARGUMENT, #CO_LSSmaster_INVALID_STATE,
  423. * #CO_LSSmaster_WAIT_SLAVE, #CO_LSSmaster_SCAN_FINISHED, #CO_LSSmaster_SCAN_NOACK,
  424. * #CO_LSSmaster_SCAN_FAILED
  425. */
  426. CO_LSSmaster_return_t CO_LSSmaster_IdentifyFastscan(
  427. CO_LSSmaster_t *LSSmaster,
  428. uint32_t timeDifference_us,
  429. CO_LSSmaster_fastscan_t *fastscan);
  430. /** @} */ /*@defgroup CO_LSSmaster*/
  431. #ifdef __cplusplus
  432. }
  433. #endif /*__cplusplus*/
  434. #endif /* (CO_CONFIG_LSS) & CO_CONFIG_LSS_MASTER */
  435. #endif /*CO_LSSmaster_H*/