CO_driver.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. /**
  2. * Interface between CAN hardware and CANopenNode.
  3. *
  4. * @file CO_driver.h
  5. * @ingroup CO_driver
  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_DRIVER_H
  26. #define CO_DRIVER_H
  27. #include <string.h>
  28. #include "CO_config.h"
  29. #include "CO_driver_target.h"
  30. #ifdef __cplusplus
  31. extern "C" {
  32. #endif
  33. #ifdef CO_DEBUG_COMMON
  34. #if (CO_CONFIG_DEBUG) & CO_CONFIG_DEBUG_SDO_CLIENT
  35. #define CO_DEBUG_SDO_CLIENT(msg) CO_DEBUG_COMMON(msg)
  36. #endif
  37. #if (CO_CONFIG_DEBUG) & CO_CONFIG_DEBUG_SDO_SERVER
  38. #define CO_DEBUG_SDO_SERVER(msg) CO_DEBUG_COMMON(msg)
  39. #endif
  40. #endif
  41. /**
  42. * @defgroup CO_driver Driver
  43. * @ingroup CO_CANopen_301
  44. * @{
  45. *
  46. * Interface between CAN hardware and CANopenNode.
  47. *
  48. * CANopenNode is designed for speed and portability. It runs efficiently on
  49. * devices from simple 16-bit microcontrollers to PC computers. It can run in
  50. * multiple threads. Reception of CAN messages is pre-processed with very fast
  51. * functions. Time critical objects, such as PDO or SYNC are processed in
  52. * real-time thread and other objects are processed in normal thread. See
  53. * Flowchart in [README.md](index.html) for more information.
  54. *
  55. * @anchor CO_obj
  56. * #### CANopenNode Object
  57. * CANopenNode is implemented as a collection of different objects, for example
  58. * SDO, SYNC, Emergency, PDO, NMT, Heartbeat, etc. Code is written in C language
  59. * and tries to be object oriented. So each CANopenNode Object is implemented in
  60. * a pair of .h/.c files. It basically contains a structure with all necessary
  61. * variables and some functions which operates on it. CANopenNode Object is
  62. * usually connected with one or more CAN receive or transmit Message Objects.
  63. * (CAN message Object is a CAN message with specific 11-bit CAN identifier
  64. * (usually one fixed or a range).)
  65. *
  66. * #### Hardware interface of CANopenNode
  67. * It consists of minimum three files:
  68. * - **CO_driver.h** file declares common functions. This file is part of the
  69. * CANopenNode. It is included from each .c file from CANopenNode.
  70. * - **CO_driver_target.h** file declares microcontroller specific type
  71. * declarations and defines some macros, which are necessary for CANopenNode.
  72. * This file is included from CO_driver.h.
  73. * - **CO_driver.c** file defines functions declared in CO_driver.h.
  74. *
  75. * **CO_driver_target.h** and **CO_driver.c** files are specific for each
  76. * different microcontroller and are not part of CANopenNode. There are separate
  77. * projects for different microcontrollers, which usually include CANopenNode as
  78. * a git submodule. CANopenNode only includes those two files in the `example`
  79. * directory and they are basically empty. It should be possible to compile the
  80. * `CANopenNode/example` on any system, however compiled program is not usable.
  81. * CO_driver.h contains documentation for all necessary macros, types and
  82. * functions.
  83. *
  84. * See [CANopenNode/Wiki](https://github.com/CANopenNode/CANopenNode/wiki) for a
  85. * known list of available implementations of CANopenNode on different systems
  86. * and microcontrollers. Everybody is welcome to extend the list with a link to
  87. * his own implementation.
  88. *
  89. * Implementation of the hardware interface for specific microcontroller is not
  90. * always an easy task. For reliable and efficient operation it is necessary to
  91. * know some parts of the target microcontroller in detail (for example threads
  92. * (or interrupts), CAN module, etc.).
  93. */
  94. /** Major version number of CANopenNode */
  95. #define CO_VERSION_MAJOR 2
  96. /** Minor version number of CANopenNode */
  97. #define CO_VERSION_MINOR 0
  98. /* Macros and declarations in following part are only used for documentation. */
  99. #ifdef CO_DOXYGEN
  100. /**
  101. * @defgroup CO_dataTypes Basic definitions
  102. * @{
  103. *
  104. * Target specific basic definitions and data types according to Misra C
  105. * specification.
  106. *
  107. * Must be defined in the **CO_driver_target.h** file.
  108. *
  109. * Depending on processor or compiler architecture, one of the two macros must
  110. * be defined: CO_LITTLE_ENDIAN or CO_BIG_ENDIAN. CANopen itself is little
  111. * endian.
  112. *
  113. * Basic data types may be specified differently on different architectures.
  114. * Usually `true` and `false` are defined in `<stdbool.h>`, `NULL` is defined in
  115. * `<stddef.h>`, `int8_t` to `uint64_t` are defined in `<stdint.h>`.
  116. */
  117. /** CO_LITTLE_ENDIAN or CO_BIG_ENDIAN must be defined */
  118. #define CO_LITTLE_ENDIAN
  119. /** Macro must swap bytes, if CO_BIG_ENDIAN is defined */
  120. #define CO_SWAP_16(x) x
  121. /** Macro must swap bytes, if CO_BIG_ENDIAN is defined */
  122. #define CO_SWAP_32(x) x
  123. /** Macro must swap bytes, if CO_BIG_ENDIAN is defined */
  124. #define CO_SWAP_64(x) x
  125. /** NULL, for general usage */
  126. #define NULL (0)
  127. /** Logical true, for general use */
  128. #define true 1
  129. /** Logical false, for general use */
  130. #define false 0
  131. /** Boolean data type for general use */
  132. typedef unsigned char bool_t;
  133. /** INTEGER8 in CANopen (0002h), 8-bit signed integer */
  134. typedef signed char int8_t;
  135. /** INTEGER16 in CANopen (0003h), 16-bit signed integer */
  136. typedef signed int int16_t;
  137. /** INTEGER32 in CANopen (0004h), 32-bit signed integer */
  138. typedef signed long int int32_t;
  139. /** INTEGER64 in CANopen (0015h), 64-bit signed integer */
  140. typedef signed long long int int64_t;
  141. /** UNSIGNED8 in CANopen (0005h), 8-bit unsigned integer */
  142. typedef unsigned char uint8_t;
  143. /** UNSIGNED16 in CANopen (0006h), 16-bit unsigned integer */
  144. typedef unsigned int uint16_t;
  145. /** UNSIGNED32 in CANopen (0007h), 32-bit unsigned integer */
  146. typedef unsigned long int uint32_t;
  147. /** UNSIGNED64 in CANopen (001Bh), 64-bit unsigned integer */
  148. typedef unsigned long long int uint64_t;
  149. /** REAL32 in CANopen (0008h), single precision floating point value, 32-bit */
  150. typedef float float32_t;
  151. /** REAL64 in CANopen (0011h), double precision floating point value, 64-bit */
  152. typedef double float64_t;
  153. /** VISIBLE_STRING in CANopen (0009h), string of signed 8-bit values */
  154. typedef char char_t;
  155. /** OCTET_STRING in CANopen (000Ah), string of unsigned 8-bit values */
  156. typedef unsigned char oChar_t;
  157. /** DOMAIN in CANopen (000Fh), used to transfer a large block of data */
  158. typedef unsigned char domain_t;
  159. /** @} */
  160. /**
  161. * @defgroup CO_CAN_Message_reception Reception of CAN messages
  162. * @{
  163. *
  164. * Target specific definitions and description of CAN message reception
  165. *
  166. * CAN messages in CANopenNode are usually received by its own thread or higher
  167. * priority interrupt. Received CAN messages are first filtered by hardware or
  168. * by software. Thread then examines its 11-bit CAN-id and mask and determines,
  169. * to which \ref CO_obj "CANopenNode Object" it belongs to. After that it calls
  170. * predefined CANrx_callback() function, which quickly pre-processes the message
  171. * and fetches the relevant data. CANrx_callback() function is defined by each
  172. * \ref CO_obj "CANopenNode Object" separately. Pre-processed fetched data are
  173. * later processed in another thread.
  174. *
  175. * If \ref CO_obj "CANopenNode Object" reception of specific CAN message, it
  176. * must first configure its own CO_CANrx_t object with the CO_CANrxBufferInit()
  177. * function.
  178. */
  179. /**
  180. * CAN receive callback function which pre-processes received CAN message
  181. *
  182. * It is called by fast CAN receive thread. Each \ref CO_obj "CANopenNode
  183. * Object" defines its own and registers it with CO_CANrxBufferInit(), by
  184. * passing function pointer.
  185. *
  186. * @param object pointer to specific \ref CO_obj "CANopenNode Object",
  187. * registered with CO_CANrxBufferInit()
  188. * @param rxMsg pointer to received CAN message
  189. */
  190. void CANrx_callback(void *object, void *rxMsg);
  191. /**
  192. * CANrx_callback() can read CAN identifier from received CAN message
  193. *
  194. * Must be defined in the **CO_driver_target.h** file.
  195. *
  196. * This is target specific function and is specific for specific
  197. * microcontroller. It is best to implement it by using inline function or
  198. * macro. `rxMsg` parameter should cast to a pointer to structure. For best
  199. * efficiency structure may have the same alignment as CAN registers inside CAN
  200. * module.
  201. *
  202. * @param rxMsg Pointer to received message
  203. * @return 11-bit CAN standard identifier.
  204. */
  205. static inline uint16_t CO_CANrxMsg_readIdent(void *rxMsg) {
  206. return 0;
  207. }
  208. /**
  209. * CANrx_callback() can read Data Length Code from received CAN message
  210. *
  211. * See also CO_CANrxMsg_readIdent():
  212. *
  213. * @param rxMsg Pointer to received message
  214. * @return data length in bytes (0 to 8)
  215. */
  216. static inline uint8_t CO_CANrxMsg_readDLC(void *rxMsg) {
  217. return 0;
  218. }
  219. /**
  220. * CANrx_callback() can read pointer to data from received CAN message
  221. *
  222. * See also CO_CANrxMsg_readIdent():
  223. *
  224. * @param rxMsg Pointer to received message
  225. * @return pointer to data buffer
  226. */
  227. static inline uint8_t *CO_CANrxMsg_readData(void *rxMsg) {
  228. return NULL;
  229. }
  230. /**
  231. * Configuration object for CAN received message for specific \ref CO_obj
  232. * "CANopenNode Object".
  233. *
  234. * Must be defined in the **CO_driver_target.h** file.
  235. *
  236. * Data fields of this structure are used exclusively by the driver. Usually it
  237. * has the following data fields, but they may differ for different
  238. * microcontrollers. Array of multiple CO_CANrx_t objects is included inside
  239. * CO_CANmodule_t.
  240. */
  241. typedef struct {
  242. uint16_t ident; /**< Standard CAN Identifier (bits 0..10) + RTR (bit 11) */
  243. uint16_t mask; /**< Standard CAN Identifier mask with the same alignment as
  244. ident */
  245. void *object; /**< \ref CO_obj "CANopenNode Object" initialized in from
  246. CO_CANrxBufferInit() */
  247. void (*pCANrx_callback)(
  248. void *object, void *message); /**< Pointer to CANrx_callback()
  249. initialized in CO_CANrxBufferInit() */
  250. } CO_CANrx_t;
  251. /** @} */
  252. /**
  253. * @defgroup CO_CAN_Message_transmission Transmission of CAN messages
  254. * @{
  255. *
  256. * Target specific definitions and description of CAN message transmission
  257. *
  258. * If \ref CO_obj "CANopenNode Object" needs transmitting CAN message, it must
  259. * first configure its own CO_CANtx_t object with the CO_CANtxBufferInit()
  260. * function. CAN message can then be sent with CO_CANsend() function. If at that
  261. * moment CAN transmit buffer inside microcontroller's CAN module is free,
  262. * message is copied directly to the CAN module. Otherwise CO_CANsend() function
  263. * sets _bufferFull_ flag to true. Message will be then sent by CAN TX interrupt
  264. * as soon as CAN module is freed. Until message is not copied to CAN module,
  265. * its contents must not change. If there are multiple CO_CANtx_t objects with
  266. * _bufferFull_ flag set to true, then CO_CANtx_t with lower index will be sent
  267. * first.
  268. */
  269. /**
  270. * Configuration object for CAN transmit message for specific \ref CO_obj
  271. * "CANopenNode Object".
  272. *
  273. * Must be defined in the **CO_driver_target.h** file.
  274. *
  275. * Data fields of this structure are used exclusively by the driver. Usually it
  276. * has the following data fields, but they may differ for different
  277. * microcontrollers. Array of multiple CO_CANtx_t objects is included inside
  278. * CO_CANmodule_t.
  279. */
  280. typedef struct {
  281. uint32_t ident; /**< CAN identifier as aligned in CAN module */
  282. uint8_t DLC; /**< Length of CAN message */
  283. uint8_t data[8]; /**< 8 data bytes */
  284. volatile bool_t bufferFull; /**< True if previous message is still in the
  285. buffer */
  286. volatile bool_t syncFlag; /**< Synchronous PDO messages has this flag set.
  287. It prevents them to be sent outside the synchronous window */
  288. } CO_CANtx_t;
  289. /** @} */
  290. /**
  291. * Complete CAN module object.
  292. *
  293. * Must be defined in the **CO_driver_target.h** file.
  294. *
  295. * Usually it has the following data fields, but they may differ for different
  296. * microcontrollers.
  297. */
  298. typedef struct {
  299. void *CANptr; /**< From CO_CANmodule_init() */
  300. CO_CANrx_t *rxArray; /**< From CO_CANmodule_init() */
  301. uint16_t rxSize; /**< From CO_CANmodule_init() */
  302. CO_CANtx_t *txArray; /**< From CO_CANmodule_init() */
  303. uint16_t txSize; /**< From CO_CANmodule_init() */
  304. uint16_t CANerrorStatus; /**< CAN error status bitfield,
  305. see @ref CO_CAN_ERR_status_t */
  306. volatile bool_t CANnormal; /**< CAN module is in normal mode */
  307. volatile bool_t useCANrxFilters; /**< Value different than zero indicates,
  308. that CAN module hardware filters are used for CAN reception. If
  309. there is not enough hardware filters, they won't be used. In this
  310. case will be *all* received CAN messages processed by software. */
  311. volatile bool_t bufferInhibitFlag; /**< If flag is true, then message in
  312. transmit buffer is synchronous PDO message, which will be aborted,
  313. if CO_clearPendingSyncPDOs() function will be called by application.
  314. This may be necessary if Synchronous window time was expired. */
  315. volatile bool_t firstCANtxMessage; /**< Equal to 1, when the first
  316. transmitted message (bootup message) is in CAN TX buffers */
  317. volatile uint16_t CANtxCount; /**< Number of messages in transmit
  318. buffer, which are waiting to be copied to the CAN module */
  319. uint32_t errOld; /**< Previous state of CAN errors */
  320. int32_t errinfo; /**< For use with @ref CO_errinfo() */
  321. } CO_CANmodule_t;
  322. /**
  323. * @defgroup CO_critical_sections Critical sections
  324. * @{
  325. * CANopenNode is designed to run in different threads, as described in
  326. * [README.md](index.html). Threads are implemented differently in different
  327. * systems. In microcontrollers threads are interrupts with different
  328. * priorities, for example. It is necessary to protect sections, where different
  329. * threads access to the same resource. In simple systems interrupts or
  330. * scheduler may be temporary disabled between access to the shared resource.
  331. * Otherwise mutexes or semaphores can be used.
  332. *
  333. * #### Reentrant functions
  334. * Functions CO_CANsend() from C_driver.h, CO_errorReport() from CO_Emergency.h
  335. * and CO_errorReset() from CO_Emergency.h may be called from different threads.
  336. * Critical sections must be protected. Either by disabling scheduler or
  337. * interrupts or by mutexes or semaphores.
  338. *
  339. * #### Object Dictionary variables
  340. * In general, there are two threads, which accesses OD variables: mainline and
  341. * timer. CANopenNode initialization and SDO server runs in mainline. PDOs runs
  342. * in faster timer thread. Processing of PDOs must not be interrupted by
  343. * mainline. Mainline thread must protect sections, which accesses the same OD
  344. * variables as timer thread. This care must also take the application. Note
  345. * that not all variables are allowed to be mapped to PDOs, so they may not need
  346. * to be protected. SDO server protects sections with access to OD variables.
  347. *
  348. * #### Synchronization functions for CAN receive
  349. * After CAN message is received, it is pre-processed in CANrx_callback(), which
  350. * copies some data into appropriate object and at the end sets **new_message**
  351. * flag. This flag is then pooled in another thread, which further processes the
  352. * message. The problem is, that compiler optimization may shuffle memory
  353. * operations, so it is necessary to ensure, that **new_message** flag is surely
  354. * set at the end. It is necessary to use [Memory
  355. * barrier](https://en.wikipedia.org/wiki/Memory_barrier).
  356. *
  357. * If receive function runs inside IRQ, no further synchronization is needed.
  358. * Otherwise, some kind of synchronization has to be included. The following
  359. * example uses GCC builtin memory barrier `__sync_synchronize()`. More
  360. * information can be found
  361. * [here](https://stackoverflow.com/questions/982129/what-does-sync-synchronize-do#982179).
  362. */
  363. /** Lock critical section in CO_CANsend() */
  364. #define CO_LOCK_CAN_SEND()
  365. /** Unlock critical section in CO_CANsend() */
  366. #define CO_UNLOCK_CAN_SEND()
  367. /** Lock critical section in CO_errorReport() or CO_errorReset() */
  368. #define CO_LOCK_EMCY()
  369. /** Unlock critical section in CO_errorReport() or CO_errorReset() */
  370. #define CO_UNLOCK_EMCY()
  371. /** Lock critical section when accessing Object Dictionary */
  372. #define CO_LOCK_OD()
  373. /** Unock critical section when accessing Object Dictionary */
  374. #define CO_UNLOCK_OD()
  375. /** Check if new message has arrived */
  376. #define CO_FLAG_READ(rxNew) ((rxNew) != NULL)
  377. /** Set new message flag */
  378. #define CO_FLAG_SET(rxNew) { __sync_synchronize(); rxNew = (void *)1L; }
  379. /** Clear new message flag */
  380. #define CO_FLAG_CLEAR(rxNew) { __sync_synchronize(); rxNew = NULL; }
  381. /** @} */
  382. #endif /* CO_DOXYGEN */
  383. /** Macro for passing additional information about error.
  384. *
  385. * This macro is called from several CANopen init functions, which returns
  386. * @ref CO_ReturnError_t.
  387. *
  388. * CO_driver_target.h may implement this macro. Usually macro only sets
  389. * CANmodule->errinfo to err. Application may then use CANmodule->errinfo to
  390. * determine the reason of failure. errinfo must be type of int32_t. By default
  391. * macro does not record anything.
  392. *
  393. * CO_errinfo is called in following @ref CO_ReturnError_t reasons:
  394. * - 'CO_ERROR_OD_PARAMETERS' - Index of erroneous OD parameter.
  395. */
  396. #ifndef CO_errinfo
  397. #define CO_errinfo(CANmodule, err) CANmodule->errinfo = err
  398. #endif
  399. /**
  400. * Default CANopen identifiers.
  401. *
  402. * Default CANopen identifiers for CANopen communication objects. Same as
  403. * 11-bit addresses of CAN messages. These are default identifiers and
  404. * can be changed in CANopen. Especially PDO identifiers are configured
  405. * in PDO linking phase of the CANopen network configuration.
  406. */
  407. typedef enum {
  408. CO_CAN_ID_NMT_SERVICE = 0x000, /**< 0x000, Network management */
  409. CO_CAN_ID_GFC = 0x001, /**< 0x001, Global fail-safe command */
  410. CO_CAN_ID_SYNC = 0x080, /**< 0x080, Synchronous message */
  411. CO_CAN_ID_EMERGENCY = 0x080, /**< 0x080, Emergency messages (+nodeID) */
  412. CO_CAN_ID_TIME = 0x100, /**< 0x100, Time message */
  413. CO_CAN_ID_SRDO_1 = 0x0FF, /**< 0x0FF, Default SRDO1 (+2*nodeID) */
  414. CO_CAN_ID_TPDO_1 = 0x180, /**< 0x180, Default TPDO1 (+nodeID) */
  415. CO_CAN_ID_RPDO_1 = 0x200, /**< 0x200, Default RPDO1 (+nodeID) */
  416. CO_CAN_ID_TPDO_2 = 0x280, /**< 0x280, Default TPDO2 (+nodeID) */
  417. CO_CAN_ID_RPDO_2 = 0x300, /**< 0x300, Default RPDO2 (+nodeID) */
  418. CO_CAN_ID_TPDO_3 = 0x380, /**< 0x380, Default TPDO3 (+nodeID) */
  419. CO_CAN_ID_RPDO_3 = 0x400, /**< 0x400, Default RPDO3 (+nodeID) */
  420. CO_CAN_ID_TPDO_4 = 0x480, /**< 0x480, Default TPDO4 (+nodeID) */
  421. CO_CAN_ID_RPDO_4 = 0x500, /**< 0x500, Default RPDO5 (+nodeID) */
  422. CO_CAN_ID_SDO_SRV = 0x580, /**< 0x580, SDO response from server (+nodeID) */
  423. CO_CAN_ID_SDO_CLI = 0x600, /**< 0x600, SDO request from client (+nodeID) */
  424. CO_CAN_ID_HEARTBEAT = 0x700, /**< 0x700, Heartbeat message */
  425. CO_CAN_ID_LSS_SLV = 0x7E4, /**< 0x7E4, LSS response from slave */
  426. CO_CAN_ID_LSS_MST = 0x7E5 /**< 0x7E5, LSS request from master */
  427. } CO_Default_CAN_ID_t;
  428. /**
  429. * CAN error status bitmasks.
  430. *
  431. * CAN warning level is reached, if CAN transmit or receive error counter is
  432. * more or equal to 96. CAN passive level is reached, if counters are more or
  433. * equal to 128. Transmitter goes in error state 'bus off' if transmit error
  434. * counter is more or equal to 256.
  435. */
  436. typedef enum {
  437. CO_CAN_ERRTX_WARNING = 0x0001, /**< 0x0001, CAN transmitter warning */
  438. CO_CAN_ERRTX_PASSIVE = 0x0002, /**< 0x0002, CAN transmitter passive */
  439. CO_CAN_ERRTX_BUS_OFF = 0x0004, /**< 0x0004, CAN transmitter bus off */
  440. CO_CAN_ERRTX_OVERFLOW = 0x0008, /**< 0x0008, CAN transmitter overflow */
  441. CO_CAN_ERRTX_PDO_LATE = 0x0080, /**< 0x0080, TPDO is outside sync window */
  442. CO_CAN_ERRRX_WARNING = 0x0100, /**< 0x0100, CAN receiver warning */
  443. CO_CAN_ERRRX_PASSIVE = 0x0200, /**< 0x0200, CAN receiver passive */
  444. CO_CAN_ERRRX_OVERFLOW = 0x0800, /**< 0x0800, CAN receiver overflow */
  445. CO_CAN_ERR_WARN_PASSIVE = 0x0303/**< 0x0303, combination */
  446. } CO_CAN_ERR_status_t;
  447. /**
  448. * Return values of some CANopen functions. If function was executed
  449. * successfully it returns 0 otherwise it returns <0.
  450. */
  451. typedef enum {
  452. CO_ERROR_NO = 0, /**< Operation completed successfully */
  453. CO_ERROR_ILLEGAL_ARGUMENT = -1, /**< Error in function arguments */
  454. CO_ERROR_OUT_OF_MEMORY = -2, /**< Memory allocation failed */
  455. CO_ERROR_TIMEOUT = -3, /**< Function timeout */
  456. CO_ERROR_ILLEGAL_BAUDRATE = -4, /**< Illegal baudrate passed to function
  457. CO_CANmodule_init() */
  458. CO_ERROR_RX_OVERFLOW = -5, /**< Previous message was not processed
  459. yet */
  460. CO_ERROR_RX_PDO_OVERFLOW = -6, /**< previous PDO was not processed yet */
  461. CO_ERROR_RX_MSG_LENGTH = -7, /**< Wrong receive message length */
  462. CO_ERROR_RX_PDO_LENGTH = -8, /**< Wrong receive PDO length */
  463. CO_ERROR_TX_OVERFLOW = -9, /**< Previous message is still waiting,
  464. buffer full */
  465. CO_ERROR_TX_PDO_WINDOW = -10, /**< Synchronous TPDO is outside window */
  466. CO_ERROR_TX_UNCONFIGURED = -11, /**< Transmit buffer was not configured
  467. properly */
  468. CO_ERROR_OD_PARAMETERS = -12, /**< Error in Object Dictionary parameters*/
  469. CO_ERROR_DATA_CORRUPT = -13, /**< Stored data are corrupt */
  470. CO_ERROR_CRC = -14, /**< CRC does not match */
  471. CO_ERROR_TX_BUSY = -15, /**< Sending rejected because driver is
  472. busy. Try again */
  473. CO_ERROR_WRONG_NMT_STATE = -16, /**< Command can't be processed in current
  474. state */
  475. CO_ERROR_SYSCALL = -17, /**< Syscall failed */
  476. CO_ERROR_INVALID_STATE = -18, /**< Driver not ready */
  477. CO_ERROR_NODE_ID_UNCONFIGURED_LSS = -19 /**< Node-id is in LSS unconfigured
  478. state. If objects are handled properly,
  479. this may not be an error. */
  480. } CO_ReturnError_t;
  481. #define CLAMP(x, min, max) (((x) < (min)) ? (min) : ((x) > (max)) ? (max) : (x))
  482. #define IN_RANGE(val, min, max) ((val) >= (min) && (val) <= (max))
  483. uint16_t CO_CANrxMsg_readIdent(CO_CANrxMsg_t *rxMsg);
  484. uint8_t CO_CANrxMsg_readDLC(CO_CANrxMsg_t *rxMsg);
  485. uint8_t *CO_CANrxMsg_readData(CO_CANrxMsg_t *rxMsg);
  486. /**
  487. * Request CAN configuration (stopped) mode and *wait* until it is set.
  488. *
  489. * @param CANptr Pointer to CAN device
  490. */
  491. void CO_CANsetConfigurationMode(void *CANptr);
  492. /**
  493. * Request CAN normal (operational) mode and *wait* until it is set.
  494. *
  495. * @param CANmodule CO_CANmodule_t object.
  496. */
  497. void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule);
  498. /**
  499. * Initialize CAN module object.
  500. *
  501. * Function must be called in the communication reset section. CAN module must
  502. * be in Configuration Mode before.
  503. *
  504. * @param CANmodule This object will be initialized.
  505. * @param CANptr Pointer to CAN device.
  506. * @param rxArray Array for handling received CAN messages
  507. * @param rxSize Size of the above array. Must be equal to number of receiving
  508. * CAN objects.
  509. * @param txArray Array for handling transmitting CAN messages
  510. * @param txSize Size of the above array. Must be equal to number of
  511. * transmitting CAN objects.
  512. * @param CANbitRate Valid values are (in kbps): 10, 20, 50, 125, 250, 500, 800,
  513. * 1000. If value is illegal, bitrate defaults to 125.
  514. *
  515. * Return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT.
  516. */
  517. CO_ReturnError_t CO_CANmodule_init(CO_CANmodule_t *CANmodule,
  518. void *CANptr,
  519. CO_CANrx_t rxArray[],
  520. uint16_t rxSize,
  521. CO_CANtx_t txArray[],
  522. uint16_t txSize,
  523. uint16_t CANbitRate);
  524. /**
  525. * Switch off CANmodule. Call at program exit.
  526. *
  527. * @param CANmodule CAN module object.
  528. */
  529. void CO_CANmodule_disable(CO_CANmodule_t *CANmodule);
  530. /**
  531. * Configure CAN message receive buffer.
  532. *
  533. * Function configures specific CAN receive buffer. It sets CAN identifier
  534. * and connects buffer with specific object. Function must be called for each
  535. * member in _rxArray_ from CO_CANmodule_t.
  536. *
  537. * @param CANmodule This object.
  538. * @param index Index of the specific buffer in _rxArray_.
  539. * @param ident 11-bit standard CAN Identifier. If two or more CANrx buffers
  540. * have the same _ident_, then buffer with lowest _index_ has precedence and
  541. * other CANrx buffers will be ignored.
  542. * @param mask 11-bit mask for identifier. Most usually set to 0x7FF.
  543. * Received message (rcvMsg) will be accepted if the following
  544. * condition is true: (((rcvMsgId ^ ident) & mask) == 0).
  545. * @param rtr If true, 'Remote Transmit Request' messages will be accepted.
  546. * @param object CANopen object, to which buffer is connected. It will be used
  547. * as an argument to CANrx_callback. Its type is (void), CANrx_callback will
  548. * change its type back to the correct object type.
  549. * @param CANrx_callback Pointer to function, which will be called, if received
  550. * CAN message matches the identifier. It must be fast function.
  551. *
  552. * Return #CO_ReturnError_t: CO_ERROR_NO CO_ERROR_ILLEGAL_ARGUMENT or
  553. * CO_ERROR_OUT_OF_MEMORY (not enough masks for configuration).
  554. */
  555. CO_ReturnError_t CO_CANrxBufferInit(CO_CANmodule_t *CANmodule,
  556. uint16_t index,
  557. uint16_t ident,
  558. uint16_t mask,
  559. bool_t rtr,
  560. void *object,
  561. void (*CANrx_callback)(void *object,
  562. void *message));
  563. /**
  564. * Configure CAN message transmit buffer.
  565. *
  566. * Function configures specific CAN transmit buffer. Function must be called for
  567. * each member in _txArray_ from CO_CANmodule_t.
  568. *
  569. * @param CANmodule This object.
  570. * @param index Index of the specific buffer in _txArray_.
  571. * @param ident 11-bit standard CAN Identifier.
  572. * @param rtr If true, 'Remote Transmit Request' messages will be transmitted.
  573. * @param noOfBytes Length of CAN message in bytes (0 to 8 bytes).
  574. * @param syncFlag This flag bit is used for synchronous TPDO messages. If it is
  575. * set, message will not be sent, if current time is outside synchronous window.
  576. *
  577. * @return Pointer to CAN transmit message buffer. 8 bytes data array inside
  578. * buffer should be written, before CO_CANsend() function is called.
  579. * Zero is returned in case of wrong arguments.
  580. */
  581. CO_CANtx_t *CO_CANtxBufferInit(CO_CANmodule_t *CANmodule,
  582. uint16_t index,
  583. uint16_t ident,
  584. bool_t rtr,
  585. uint8_t noOfBytes,
  586. bool_t syncFlag);
  587. /**
  588. * Send CAN message.
  589. *
  590. * @param CANmodule This object.
  591. * @param buffer Pointer to transmit buffer, returned by CO_CANtxBufferInit().
  592. * Data bytes must be written in buffer before function call.
  593. *
  594. * @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_TX_OVERFLOW or
  595. * CO_ERROR_TX_PDO_WINDOW (Synchronous TPDO is outside window).
  596. */
  597. CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
  598. /**
  599. * Clear all synchronous TPDOs from CAN module transmit buffers.
  600. *
  601. * CANopen allows synchronous PDO communication only inside time between SYNC
  602. * message and SYNC Window. If time is outside this window, new synchronous PDOs
  603. * must not be sent and all pending sync TPDOs, which may be on CAN TX buffers,
  604. * may optionally be cleared.
  605. *
  606. * This function checks (and aborts transmission if necessary) CAN TX buffers
  607. * when it is called. Function should be called by the stack in the moment,
  608. * when SYNC time was just passed out of synchronous window.
  609. *
  610. * @param CANmodule This object.
  611. */
  612. void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule);
  613. /**
  614. * Process can module - verify CAN errors
  615. *
  616. * Function must be called cyclically. It should calculate CANerrorStatus
  617. * bitfield for CAN errors defined in @ref CO_CAN_ERR_status_t.
  618. *
  619. * @param CANmodule This object.
  620. */
  621. void CO_CANmodule_process(CO_CANmodule_t *CANmodule);
  622. /**
  623. * Get uint8_t value from memory buffer
  624. *
  625. * @param buf Memory buffer to get value from.
  626. *
  627. * @return Value
  628. */
  629. static inline uint8_t CO_getUint8(const void *buf) {
  630. uint8_t value; memmove(&value, buf, sizeof(value)); return value;
  631. }
  632. /** Get uint16_t value from memory buffer, see @ref CO_getUint8 */
  633. static inline uint16_t CO_getUint16(const void *buf) {
  634. uint16_t value; memmove(&value, buf, sizeof(value)); return value;
  635. }
  636. /** Get uint32_t value from memory buffer, see @ref CO_getUint8 */
  637. static inline uint32_t CO_getUint32(const void *buf) {
  638. uint32_t value; memmove(&value, buf, sizeof(value)); return value;
  639. }
  640. /**
  641. * Write uint8_t value into memory buffer
  642. *
  643. * @param buf Memory buffer.
  644. * @param value Value to be written into buf.
  645. *
  646. * @return number of bytes written.
  647. */
  648. static inline uint8_t CO_setUint8(void *buf, uint8_t value) {
  649. memmove(buf, &value, sizeof(value)); return sizeof(value);
  650. }
  651. /** Write uint16_t value into memory buffer, see @ref CO_setUint8 */
  652. static inline uint8_t CO_setUint16(void *buf, uint16_t value) {
  653. memmove(buf, &value, sizeof(value)); return sizeof(value);
  654. }
  655. /** Write uint32_t value into memory buffer, see @ref CO_setUint8 */
  656. static inline uint8_t CO_setUint32(void *buf, uint32_t value) {
  657. memmove(buf, &value, sizeof(value)); return sizeof(value);
  658. }
  659. /** @} */ /* CO_driver */
  660. #ifdef __cplusplus
  661. }
  662. #endif /* __cplusplus */
  663. #endif /* CO_DRIVER_H */