CO_SDOserver.h 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165
  1. /**
  2. * CANopen Service Data Object - server protocol.
  3. *
  4. * @file CO_SDOserver.h
  5. * @ingroup CO_SDOserver
  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_SDO_SERVER_H
  26. #define CO_SDO_SERVER_H
  27. #include <string.h>
  28. #include "301/CO_driver.h"
  29. /* default configuration, see CO_config.h */
  30. #ifndef CO_CONFIG_SDO_SRV
  31. #define CO_CONFIG_SDO_SRV (CO_CONFIG_SDO_SRV_SEGMENTED)
  32. #endif
  33. #ifndef CO_CONFIG_SDO_SRV_BUFFER_SIZE
  34. #define CO_CONFIG_SDO_SRV_BUFFER_SIZE 32
  35. #endif
  36. #define CO_CONFIG_SDO CO_CONFIG_SDO_SRV
  37. #define CO_CONFIG_SDO_BUFFER_SIZE CO_CONFIG_SDO_SRV_BUFFER_SIZE
  38. #ifdef __cplusplus
  39. extern "C" {
  40. #endif
  41. /**
  42. * @defgroup CO_SDOserver SDO server
  43. * @ingroup CO_CANopen_301
  44. * @{
  45. *
  46. * CANopen Service Data Object - server protocol.
  47. *
  48. * Service data objects (SDOs) allow the access to any entry of the CANopen
  49. * Object dictionary. An SDO establishes a peer-to-peer communication channel
  50. * between two devices. In addition, the SDO protocol enables to transfer any
  51. * amount of data in a segmented way. Therefore the SDO protocol is mainly used
  52. * in order to communicate configuration data.
  53. *
  54. * All CANopen devices must have implemented SDO server and first SDO server
  55. * channel. Servers serves data from Object dictionary. Object dictionary
  56. * is a collection of variables, arrays or records (structures), which can be
  57. * used by the stack or by the application. This file (CO_SDOserver.h)
  58. * implements SDO server.
  59. *
  60. * SDO client can be (optionally) implemented on one (or multiple, if multiple
  61. * SDO channels are used) device in CANopen network. Usually this is master
  62. * device and provides also some kind of user interface, so configuration of
  63. * the network is possible. Code for the SDO client is in file CO_SDOclient.h.
  64. *
  65. * SDO communication cycle is initiated by the client. Client can upload (read)
  66. * data from device or can download (write) data to device. If data size is less
  67. * or equal to 4 bytes, communication is finished by one server response
  68. * (expedited transfer). If data size is longer, data are split into multiple
  69. * segments of request/response pairs (normal or segmented transfer). For longer
  70. * data there is also a block transfer protocol, which transfers larger block of
  71. * data in secure way with little protocol overhead. If error occurs during SDO
  72. * transfer #CO_SDO_abortCode_t is send by client or server and transfer is
  73. * terminated. For more details see #CO_SDO_state_t.
  74. */
  75. /**
  76. * Internal state flags indicate type of transfer
  77. *
  78. * These flags correspond to the upper nibble of the SDO state machine states
  79. * and can be used to determine the type of state an SDO object is in.
  80. */
  81. #define CO_SDO_ST_FLAG_DOWNLOAD 0x10U
  82. #define CO_SDO_ST_FLAG_UPLOAD 0x20U
  83. #define CO_SDO_ST_FLAG_BLOCK 0x40U
  84. /**
  85. * Internal states of the SDO state machine.
  86. *
  87. * Upper nibble of byte indicates type of state:
  88. * 0x10: Download
  89. * 0x20: Upload
  90. * 0x40: Block Mode
  91. *
  92. * Note: CANopen has little endian byte order.
  93. */
  94. typedef enum {
  95. /**
  96. * - SDO client may start new download to or upload from specified node,
  97. * specified index and specified subindex. It can start normal or block
  98. * communication.
  99. * - SDO server is waiting for client request. */
  100. CO_SDO_ST_IDLE = 0x00U,
  101. /**
  102. * - SDO client or server may send SDO abort message in case of error:
  103. * - byte 0: @b 10000000 binary.
  104. * - byte 1..3: Object index and subIndex.
  105. * - byte 4..7: #CO_SDO_abortCode_t. */
  106. CO_SDO_ST_ABORT = 0x01U,
  107. /**
  108. * - SDO client: Node-ID of the SDO server is the same as node-ID of this node,
  109. * SDO client is the same device as SDO server. Transfer data directly without
  110. * communication on CAN.
  111. * - SDO server does not use this state. */
  112. CO_SDO_ST_DOWNLOAD_LOCAL_TRANSFER = 0x10U,
  113. /**
  114. * - SDO client initiates SDO download:
  115. * - byte 0: @b 0010nnes binary: (nn: if e=s=1, number of data bytes, that do
  116. * @b not contain data; e=1 for expedited transfer; s=1 if data size is
  117. * indicated.)
  118. * - byte 1..3: Object index and subIndex.
  119. * - byte 4..7: If e=1, expedited data are here. If e=0 s=1, size of data for
  120. * segmented transfer is indicated here.
  121. * - SDO server is in #CO_SDO_ST_IDLE state and waits for client request. */
  122. CO_SDO_ST_DOWNLOAD_INITIATE_REQ = 0x11U,
  123. /**
  124. * - SDO client waits for response.
  125. * - SDO server responses:
  126. * - byte 0: @b 01100000 binary.
  127. * - byte 1..3: Object index and subIndex.
  128. * - byte 4..7: Reserved.
  129. * - In case of expedited transfer communication ends here. */
  130. CO_SDO_ST_DOWNLOAD_INITIATE_RSP = 0x12U,
  131. /**
  132. * - SDO client sends SDO segment:
  133. * - byte 0: @b 000tnnnc binary: (t: toggle bit, set to 0 in first segment;
  134. * nnn: number of data bytes, that do @b not contain data; c=1 if this is the
  135. * last segment).
  136. * - byte 1..7: Data segment.
  137. * - SDO server waits for segment. */
  138. CO_SDO_ST_DOWNLOAD_SEGMENT_REQ = 0x13U,
  139. /**
  140. * - SDO client waits for response.
  141. * - SDO server responses:
  142. * - byte 0: @b 001t0000 binary: (t: toggle bit, set to 0 in first segment).
  143. * - byte 1..7: Reserved.
  144. * - If c was set to 1, then communication ends here. */
  145. CO_SDO_ST_DOWNLOAD_SEGMENT_RSP = 0x14U,
  146. /**
  147. * - SDO client: Node-ID of the SDO server is the same as node-ID of this node,
  148. * SDO client is the same device as SDO server. Transfer data directly without
  149. * communication on CAN.
  150. * - SDO server does not use this state. */
  151. CO_SDO_ST_UPLOAD_LOCAL_TRANSFER = 0x20U,
  152. /**
  153. * - SDO client initiates SDO upload:
  154. * - byte 0: @b 01000000 binary.
  155. * - byte 1..3: Object index and subIndex.
  156. * - byte 4..7: Reserved.
  157. * - SDO server is in #CO_SDO_ST_IDLE state and waits for client request. */
  158. CO_SDO_ST_UPLOAD_INITIATE_REQ = 0x21U,
  159. /**
  160. * - SDO client waits for response.
  161. * - SDO server responses:
  162. * - byte 0: @b 0100nnes binary: (nn: if e=s=1, number of data bytes, that do
  163. * @b not contain data; e=1 for expedited transfer; s=1 if data size is
  164. * indicated).
  165. * - byte 1..3: Object index and subIndex.
  166. * - byte 4..7: If e=1, expedited data are here. If e=0 s=1, size of data for
  167. * segmented transfer is indicated here.
  168. * - In case of expedited transfer communication ends here. */
  169. CO_SDO_ST_UPLOAD_INITIATE_RSP = 0x22U,
  170. /**
  171. * - SDO client requests SDO segment:
  172. * - byte 0: @b 011t0000 binary: (t: toggle bit, set to 0 in first segment).
  173. * - byte 1..7: Reserved.
  174. * - SDO server waits for segment request. */
  175. CO_SDO_ST_UPLOAD_SEGMENT_REQ = 0x23U,
  176. /**
  177. * - SDO client waits for response.
  178. * - SDO server responses with data:
  179. * - byte 0: @b 000tnnnc binary: (t: toggle bit, set to 0 in first segment;
  180. * nnn: number of data bytes, that do @b not contain data; c=1 if this is the
  181. * last segment).
  182. * - byte 1..7: Data segment.
  183. * - If c is set to 1, then communication ends here. */
  184. CO_SDO_ST_UPLOAD_SEGMENT_RSP = 0x24U,
  185. /**
  186. * - SDO client initiates SDO block download:
  187. * - byte 0: @b 11000rs0 binary: (r=1 if client supports generating CRC on
  188. * data; s=1 if data size is indicated.)
  189. * - byte 1..3: Object index and subIndex.
  190. * - byte 4..7: If s=1, then size of data for block download is indicated here.
  191. * - SDO server is in #CO_SDO_ST_IDLE state and waits for client request. */
  192. CO_SDO_ST_DOWNLOAD_BLK_INITIATE_REQ = 0x51U,
  193. /**
  194. * - SDO client waits for response.
  195. * - SDO server responses:
  196. * - byte 0: @b 10100r00 binary: (r=1 if server supports generating CRC on
  197. * data.)
  198. * - byte 1..3: Object index and subIndex.
  199. * - byte 4: blksize: Number of segments per block that shall be used by the
  200. * client for the following block download with 0 < blksize < 128.
  201. * - byte 5..7: Reserved. */
  202. CO_SDO_ST_DOWNLOAD_BLK_INITIATE_RSP = 0x52U,
  203. /**
  204. * - SDO client sends 'blksize' segments of data in sequence:
  205. * - byte 0: @b cnnnnnnn binary: (c=1 if no more segments to be downloaded,
  206. * enter SDO block download end phase; nnnnnnn is sequence number of segment,
  207. * 1..127.
  208. * - byte 1..7: At most 7 bytes of segment data to be downloaded.
  209. * - SDO server reads sequence of 'blksize' blocks. */
  210. CO_SDO_ST_DOWNLOAD_BLK_SUBBLOCK_REQ = 0x53U,
  211. /**
  212. * - SDO client waits for response.
  213. * - SDO server responses:
  214. * - byte 0: @b 10100010 binary.
  215. * - byte 1: ackseq: sequence number of last segment that was received
  216. * successfully during the last block download. If ackseq is set to 0 the
  217. * server indicates the client that the segment with the sequence number 1
  218. * was not received correctly and all segments shall be retransmitted by the
  219. * client.
  220. * - byte 2: Number of segments per block that shall be used by the client for
  221. * the following block download with 0 < blksize < 128.
  222. * - byte 3..7: Reserved.
  223. * - If c was set to 1, then communication enters SDO block download end phase.
  224. */
  225. CO_SDO_ST_DOWNLOAD_BLK_SUBBLOCK_RSP = 0x54U,
  226. /**
  227. * - SDO client sends SDO block download end:
  228. * - byte 0: @b 110nnn01 binary: (nnn: number of data bytes, that do @b not
  229. * contain data)
  230. * - byte 1..2: 16 bit CRC for the data set, if enabled by client and server.
  231. * - byte 3..7: Reserved.
  232. * - SDO server waits for client request. */
  233. CO_SDO_ST_DOWNLOAD_BLK_END_REQ = 0x55U,
  234. /**
  235. * - SDO client waits for response.
  236. * - SDO server responses:
  237. * - byte 0: @b 10100001 binary.
  238. * - byte 1..7: Reserved.
  239. * - Block download successfully ends here.
  240. */
  241. CO_SDO_ST_DOWNLOAD_BLK_END_RSP = 0x56U,
  242. /**
  243. * - SDO client initiates SDO block upload:
  244. * - byte 0: @b 10100r00 binary: (r=1 if client supports generating CRC on
  245. * data.)
  246. * - byte 1..3: Object index and subIndex.
  247. * - byte 4: blksize: Number of segments per block with 0 < blksize < 128.
  248. * - byte 5: pst - protocol switch threshold. If pst > 0 and size of the data
  249. * in bytes is less or equal pst, then the server may switch to the SDO
  250. * upload protocol #CO_SDO_ST_UPLOAD_INITIATE_RSP.
  251. * - byte 6..7: Reserved.
  252. * - SDO server is in #CO_SDO_ST_IDLE state and waits for client request. */
  253. CO_SDO_ST_UPLOAD_BLK_INITIATE_REQ = 0x61U,
  254. /**
  255. * - SDO client waits for response.
  256. * - SDO server responses:
  257. * - byte 0: @b 11000rs0 binary: (r=1 if server supports generating CRC on
  258. * data; s=1 if data size is indicated. )
  259. * - byte 1..3: Object index and subIndex.
  260. * - byte 4..7: If s=1, then size of data for block upload is indicated here.
  261. * - If enabled by pst, then server may alternatively response with
  262. * #CO_SDO_ST_UPLOAD_INITIATE_RSP */
  263. CO_SDO_ST_UPLOAD_BLK_INITIATE_RSP = 0x62U,
  264. /**
  265. * - SDO client sends second initiate for SDO block upload:
  266. * - byte 0: @b 10100011 binary.
  267. * - byte 1..7: Reserved.
  268. * - SDO server waits for client request. */
  269. CO_SDO_ST_UPLOAD_BLK_INITIATE_REQ2 = 0x63U,
  270. /**
  271. * - SDO client reads sequence of 'blksize' blocks.
  272. * - SDO server sends 'blksize' segments of data in sequence:
  273. * - byte 0: @b cnnnnnnn binary: (c=1 if no more segments to be uploaded,
  274. * enter SDO block upload end phase; nnnnnnn is sequence number of segment,
  275. * 1..127.
  276. * - byte 1..7: At most 7 bytes of segment data to be uploaded. */
  277. CO_SDO_ST_UPLOAD_BLK_SUBBLOCK_SREQ = 0x64U,
  278. /**
  279. * - SDO client responses:
  280. * - byte 0: @b 10100010 binary.
  281. * - byte 1: ackseq: sequence number of last segment that was received
  282. * successfully during the last block upload. If ackseq is set to 0 the
  283. * client indicates the server that the segment with the sequence number 1
  284. * was not received correctly and all segments shall be retransmitted by the
  285. * server.
  286. * - byte 2: Number of segments per block that shall be used by the server for
  287. * the following block upload with 0 < blksize < 128.
  288. * - byte 3..7: Reserved.
  289. * - SDO server waits for response.
  290. * - If c was set to 1, then communication enters SDO block upload end phase. */
  291. CO_SDO_ST_UPLOAD_BLK_SUBBLOCK_CRSP = 0x65U,
  292. /**
  293. * - SDO client waits for server request.
  294. * - SDO server sends SDO block upload end:
  295. * - byte 0: @b 110nnn01 binary: (nnn: number of data bytes, that do @b not
  296. * contain data)
  297. * - byte 1..2: 16 bit CRC for the data set, if enabled by client and server.
  298. * - byte 3..7: Reserved. */
  299. CO_SDO_ST_UPLOAD_BLK_END_SREQ = 0x66U,
  300. /**
  301. * - SDO client responses:
  302. * - byte 0: @b 10100001 binary.
  303. * - byte 1..7: Reserved.
  304. * - SDO server waits for response.
  305. * - Block download successfully ends here. Note that this communication ends
  306. * with client response. Client may then start next SDO communication
  307. * immediately.
  308. */
  309. CO_SDO_ST_UPLOAD_BLK_END_CRSP = 0x67U,
  310. /* old state names, will be removed */
  311. CO_SDO_ST_DOWNLOAD_INITIATE = 0xA1U,
  312. CO_SDO_ST_DOWNLOAD_SEGMENTED = 0xA2U,
  313. CO_SDO_ST_DOWNLOAD_BL_INITIATE = 0xA4U,
  314. CO_SDO_ST_DOWNLOAD_BL_SUBBLOCK = 0xA5U,
  315. CO_SDO_ST_DOWNLOAD_BL_SUB_RESP = 0xA6U,
  316. CO_SDO_ST_DOWNLOAD_BL_SUB_RESP_2 = 0xA7U,
  317. CO_SDO_ST_DOWNLOAD_BL_END = 0xA8U,
  318. CO_SDO_ST_UPLOAD_INITIATE = 0xB1U,
  319. CO_SDO_ST_UPLOAD_SEGMENTED = 0xB2U,
  320. CO_SDO_ST_UPLOAD_BL_INITIATE = 0xB4U,
  321. CO_SDO_ST_UPLOAD_BL_INITIATE_2 = 0xB5U,
  322. CO_SDO_ST_UPLOAD_BL_SUBBLOCK = 0xB6U,
  323. CO_SDO_ST_UPLOAD_BL_END = 0xB7U
  324. } CO_SDO_state_t;
  325. /**
  326. * SDO abort codes.
  327. *
  328. * Send with Abort SDO transfer message.
  329. *
  330. * The abort codes not listed here are reserved.
  331. */
  332. typedef enum{
  333. CO_SDO_AB_NONE = 0x00000000UL, /**< 0x00000000, No abort */
  334. CO_SDO_AB_TOGGLE_BIT = 0x05030000UL, /**< 0x05030000, Toggle bit not altered */
  335. CO_SDO_AB_TIMEOUT = 0x05040000UL, /**< 0x05040000, SDO protocol timed out */
  336. CO_SDO_AB_CMD = 0x05040001UL, /**< 0x05040001, Command specifier not valid or unknown */
  337. CO_SDO_AB_BLOCK_SIZE = 0x05040002UL, /**< 0x05040002, Invalid block size in block mode */
  338. CO_SDO_AB_SEQ_NUM = 0x05040003UL, /**< 0x05040003, Invalid sequence number in block mode */
  339. CO_SDO_AB_CRC = 0x05040004UL, /**< 0x05040004, CRC error (block mode only) */
  340. CO_SDO_AB_OUT_OF_MEM = 0x05040005UL, /**< 0x05040005, Out of memory */
  341. CO_SDO_AB_UNSUPPORTED_ACCESS = 0x06010000UL, /**< 0x06010000, Unsupported access to an object */
  342. CO_SDO_AB_WRITEONLY = 0x06010001UL, /**< 0x06010001, Attempt to read a write only object */
  343. CO_SDO_AB_READONLY = 0x06010002UL, /**< 0x06010002, Attempt to write a read only object */
  344. CO_SDO_AB_NOT_EXIST = 0x06020000UL, /**< 0x06020000, Object does not exist in the object dictionary */
  345. CO_SDO_AB_NO_MAP = 0x06040041UL, /**< 0x06040041, Object cannot be mapped to the PDO */
  346. CO_SDO_AB_MAP_LEN = 0x06040042UL, /**< 0x06040042, Number and length of object to be mapped exceeds PDO length */
  347. CO_SDO_AB_PRAM_INCOMPAT = 0x06040043UL, /**< 0x06040043, General parameter incompatibility reasons */
  348. CO_SDO_AB_DEVICE_INCOMPAT = 0x06040047UL, /**< 0x06040047, General internal incompatibility in device */
  349. CO_SDO_AB_HW = 0x06060000UL, /**< 0x06060000, Access failed due to hardware error */
  350. CO_SDO_AB_TYPE_MISMATCH = 0x06070010UL, /**< 0x06070010, Data type does not match, length of service parameter does not match */
  351. CO_SDO_AB_DATA_LONG = 0x06070012UL, /**< 0x06070012, Data type does not match, length of service parameter too high */
  352. CO_SDO_AB_DATA_SHORT = 0x06070013UL, /**< 0x06070013, Data type does not match, length of service parameter too short */
  353. CO_SDO_AB_SUB_UNKNOWN = 0x06090011UL, /**< 0x06090011, Sub index does not exist */
  354. CO_SDO_AB_INVALID_VALUE = 0x06090030UL, /**< 0x06090030, Invalid value for parameter (download only). */
  355. CO_SDO_AB_VALUE_HIGH = 0x06090031UL, /**< 0x06090031, Value range of parameter written too high */
  356. CO_SDO_AB_VALUE_LOW = 0x06090032UL, /**< 0x06090032, Value range of parameter written too low */
  357. CO_SDO_AB_MAX_LESS_MIN = 0x06090036UL, /**< 0x06090036, Maximum value is less than minimum value. */
  358. CO_SDO_AB_NO_RESOURCE = 0x060A0023UL, /**< 0x060A0023, Resource not available: SDO connection */
  359. CO_SDO_AB_GENERAL = 0x08000000UL, /**< 0x08000000, General error */
  360. CO_SDO_AB_DATA_TRANSF = 0x08000020UL, /**< 0x08000020, Data cannot be transferred or stored to application */
  361. CO_SDO_AB_DATA_LOC_CTRL = 0x08000021UL, /**< 0x08000021, Data cannot be transferred or stored to application because of local control */
  362. CO_SDO_AB_DATA_DEV_STATE = 0x08000022UL, /**< 0x08000022, Data cannot be transferred or stored to application because of present device state */
  363. CO_SDO_AB_DATA_OD = 0x08000023UL, /**< 0x08000023, Object dictionary not present or dynamic generation fails */
  364. CO_SDO_AB_NO_DATA = 0x08000024UL /**< 0x08000024, No data available */
  365. }CO_SDO_abortCode_t;
  366. /**
  367. * @defgroup CO_SDO_objectDictionary Object dictionary
  368. *
  369. * CANopen Object dictionary implementation in CANopenNode.
  370. *
  371. * CANopen Object dictionary is a collection of different data items, which can
  372. * be used by the stack or by the application.
  373. *
  374. * Each Object dictionary entry is located under 16-bit index, as specified
  375. * by the CANopen:
  376. * - 0x0001..0x025F: Data type definitions.
  377. * - 0x1000..0x1FFF: Communication profile area.
  378. * - 0x2000..0x5FFF: Manufacturer-specific profile area.
  379. * - 0x6000..0x9FFF: Standardized device profile area for eight logical devices.
  380. * - 0xA000..0xAFFF: Standardized network variable area.
  381. * - 0xB000..0xBFFF: Standardized system variable area.
  382. * - Other: Reserved.
  383. *
  384. * If Object dictionary entry has complex data type (array or structure),
  385. * then 8-bit subIndex specifies the sub-member of the entry. In that case
  386. * subIndex 0x00 is encoded as uint8_t and specifies the highest available
  387. * subIndex with that entry. Subindex 0xFF has special meaning in the standard
  388. * and is not supported by CANopenNode.
  389. *
  390. * ####Object type of one Object dictionary entry
  391. * - NULL: Not used by CANopenNode.
  392. * - DOMAIN: Block of data of variable length. Data and length are
  393. * under control of the application.
  394. * - DEFTYPE: Definition of CANopen basic data type, for example
  395. * INTEGER16.
  396. * - DEFSTRUCT: Definition of complex data type - structure, which is
  397. * used with RECORD.
  398. * - VAR: Variable of CANopen basic data type. Subindex is 0.
  399. * - ARRAY: Array of multiple variables of the same CANopen basic
  400. * data type. Subindex 1..arrayLength specifies sub-member.
  401. * - RECORD: Record or structure of multiple variables of different
  402. * CANopen basic data type. Subindex specifies sub-member.
  403. *
  404. *
  405. * ####Implementation in CANopenNode
  406. * Object dictionary in CANopenNode is implemented in CO_OD.h and CO_OD.c files.
  407. * These files are application specific and must be generated by Object
  408. * dictionary editor (application is included by the stack).
  409. *
  410. * CO_OD.h and CO_OD.c files include:
  411. * - Structure definitions for records.
  412. * - Global declaration and initialization of all variables, arrays and records
  413. * mapped to Object dictionary. Variables are distributed in multiple objects,
  414. * depending on memory location. This eases storage to different memories in
  415. * microcontroller, like eeprom or flash.
  416. * - Constant array of multiple Object dictionary entries of type
  417. * CO_OD_entry_t. If object type is record, then entry includes additional
  418. * constant array with members of type CO_OD_entryRecord_t. Each OD entry
  419. * includes information: index, maxSubIndex, #CO_SDO_OD_attributes_t, data size and
  420. * pointer to variable.
  421. *
  422. *
  423. * Function CO_SDO_init() initializes object CO_SDO_t, which includes SDO
  424. * server and Object dictionary.
  425. *
  426. * Application doesn't need to know anything about the Object dictionary. It can
  427. * use variables specified in CO_OD.h file directly. If it needs more control
  428. * over the CANopen communication with the variables, it can configure additional
  429. * functionality with function CO_OD_configure(). Additional functionality
  430. * include: @ref CO_SDO_OD_function and #CO_SDO_OD_flags_t.
  431. *
  432. * Interface to Object dictionary is provided by following functions: CO_OD_find()
  433. * finds OD entry by index, CO_OD_getLength() returns length of variable,
  434. * CO_OD_getAttribute returns attribute and CO_OD_getDataPointer() returns pointer
  435. * to data. These functions are used by SDO server and by PDO configuration. They
  436. * can also be used to access the OD by index like this.
  437. *
  438. * \code{.c}
  439. * index = CO_OD_find(CO->SDO[0], OD_H1001_ERR_REG);
  440. * if (index == 0xffff) {
  441. * return;
  442. * }
  443. * length = CO_OD_getLength(CO->SDO[0], index, 1);
  444. * if (length != sizeof(new_data)) {
  445. * return;
  446. * }
  447. *
  448. * p = CO_OD_getDataPointer(CO->SDO[0], index, 1);
  449. * if (p == NULL) {
  450. * return;
  451. * }
  452. * CO_LOCK_OD();
  453. * *p = new_data;
  454. * CO_UNLOCK_OD();
  455. * \endcode
  456. *
  457. * Be aware that accessing the OD directly using CO_OD.h files is more CPU
  458. * efficient as CO_OD_find() has to do a search everytime it is called.
  459. *
  460. */
  461. /**
  462. * @defgroup CO_SDO_OD_function Object Dictionary function
  463. *
  464. * Optional application specific function, which may manipulate data downloaded
  465. * or uploaded via SDO.
  466. *
  467. * Object dictionary function is external function defined by application or
  468. * by other stack files. It may be registered for specific Object dictionary
  469. * entry (with specific index). If it is registered, it is called (through
  470. * function pointer) from SDO server. It may verify and manipulate data during
  471. * SDO transfer. Object dictionary function can be registered by function
  472. * CO_OD_configure().
  473. *
  474. * ####SDO download (writing to Object dictionary)
  475. * After SDO client transfers data to the server, data are stored in internal
  476. * buffer. If data contains multibyte variable and processor is big endian,
  477. * then data bytes are swapped. Object dictionary function is called if
  478. * registered. Data may be verified and manipulated inside that function. After
  479. * function exits, data are copied to location as specified in CO_OD_entry_t.
  480. *
  481. * ####SDO upload (reading from Object dictionary)
  482. * Before start of SDO upload, data are read from Object dictionary into
  483. * internal buffer. If necessary, bytes are swapped.
  484. * Object dictionary function is called if registered. Data may be
  485. * manipulated inside that function. After function exits, data are
  486. * transferred via SDO server.
  487. *
  488. * ####Domain data type
  489. * If data type is domain, then length is not specified by Object dictionary.
  490. * In that case Object dictionary function must be used. In case of
  491. * download it must store the data in own location. In case of upload it must
  492. * write the data (maximum size is specified by length) into data buffer and
  493. * specify actual length. With domain data type it is possible to transfer
  494. * data, which are longer than #CO_CONFIG_SDO_BUFFER_SIZE. In that case
  495. * Object dictionary function is called multiple times between SDO transfer.
  496. *
  497. * ####Parameter to function:
  498. * ODF_arg - Pointer to CO_ODF_arg_t object filled before function call.
  499. *
  500. * ####Return from function:
  501. * - 0: Data transfer is successful
  502. * - Different than 0: Failure. See #CO_SDO_abortCode_t.
  503. */
  504. /**
  505. * Size of fifo queue for SDO received messages.
  506. *
  507. * If block transfers are used size of fifo queue should be more that 1 message
  508. * to avoid possible drops in consecutive SDO block upload transfers.
  509. * To increase performance, value can be set to 1 if block transfers are not used
  510. *
  511. * Min value is 1.
  512. */
  513. #ifndef CO_SDO_RX_DATA_SIZE
  514. #define CO_SDO_RX_DATA_SIZE 2
  515. #endif
  516. /**
  517. * Object Dictionary attributes. Bit masks for attribute in CO_OD_entry_t.
  518. */
  519. typedef enum{
  520. CO_ODA_MEM_ROM = 0x0001U, /**< Variable is located in ROM memory */
  521. CO_ODA_MEM_RAM = 0x0002U, /**< Variable is located in RAM memory */
  522. CO_ODA_MEM_EEPROM = 0x0003U, /**< Variable is located in EEPROM memory */
  523. CO_ODA_READABLE = 0x0004U, /**< SDO server may read from the variable */
  524. CO_ODA_WRITEABLE = 0x0008U, /**< SDO server may write to the variable */
  525. CO_ODA_RPDO_MAPABLE = 0x0010U, /**< Variable is mappable for RPDO */
  526. CO_ODA_TPDO_MAPABLE = 0x0020U, /**< Variable is mappable for TPDO */
  527. CO_ODA_TPDO_DETECT_COS = 0x0040U, /**< If variable is mapped to any PDO, then
  528. PDO is automatically send, if variable
  529. changes its value */
  530. CO_ODA_MB_VALUE = 0x0080U /**< True when variable is a multibyte value */
  531. }CO_SDO_OD_attributes_t;
  532. /**
  533. * Common DS301 object dictionary entries.
  534. */
  535. typedef enum{
  536. OD_H1000_DEV_TYPE = 0x1000U,/**< Device type */
  537. OD_H1001_ERR_REG = 0x1001U,/**< Error register */
  538. OD_H1002_MANUF_STATUS_REG = 0x1002U,/**< Manufacturer status register */
  539. OD_H1003_PREDEF_ERR_FIELD = 0x1003U,/**< Predefined error field */
  540. OD_H1004_RSV = 0x1004U,/**< Reserved */
  541. OD_H1005_COBID_SYNC = 0x1005U,/**< Sync message cob-id */
  542. OD_H1006_COMM_CYCL_PERIOD = 0x1006U,/**< Communication cycle period */
  543. OD_H1007_SYNC_WINDOW_LEN = 0x1007U,/**< Sync windows length */
  544. OD_H1008_MANUF_DEV_NAME = 0x1008U,/**< Manufacturer device name */
  545. OD_H1009_MANUF_HW_VERSION = 0x1009U,/**< Manufacturer hardware version */
  546. OD_H100A_MANUF_SW_VERSION = 0x100AU,/**< Manufacturer software version */
  547. OD_H100B_RSV = 0x100BU,/**< Reserved */
  548. OD_H100C_GUARD_TIME = 0x100CU,/**< Guard time */
  549. OD_H100D_LIFETIME_FACTOR = 0x100DU,/**< Life time factor */
  550. OD_H100E_RSV = 0x100EU,/**< Reserved */
  551. OD_H100F_RSV = 0x100FU,/**< Reserved */
  552. OD_H1010_STORE_PARAM_FUNC = 0x1010U,/**< Store parameter in persistent memory function */
  553. OD_H1011_REST_PARAM_FUNC = 0x1011U,/**< Restore default parameter function */
  554. OD_H1012_COBID_TIME = 0x1012U,/**< Timestamp message cob-id */
  555. OD_H1013_HIGH_RES_TIMESTAMP = 0x1013U,/**< High resolution timestamp */
  556. OD_H1014_COBID_EMERGENCY = 0x1014U,/**< Emergency message cob-id */
  557. OD_H1015_INHIBIT_TIME_MSG = 0x1015U,/**< Inhibit time message */
  558. OD_H1016_CONSUMER_HB_TIME = 0x1016U,/**< Consumer heartbeat time */
  559. OD_H1017_PRODUCER_HB_TIME = 0x1017U,/**< Producer heartbeat time */
  560. OD_H1018_IDENTITY_OBJECT = 0x1018U,/**< Identity object */
  561. OD_H1019_SYNC_CNT_OVERFLOW = 0x1019U,/**< Sync counter overflow value */
  562. OD_H1020_VERIFY_CONFIG = 0x1020U,/**< Verify configuration */
  563. OD_H1021_STORE_EDS = 0x1021U,/**< Store EDS */
  564. OD_H1022_STORE_FORMAT = 0x1022U,/**< Store format */
  565. OD_H1023_OS_CMD = 0x1023U,/**< OS command */
  566. OD_H1024_OS_CMD_MODE = 0x1024U,/**< OS command mode */
  567. OD_H1025_OS_DBG_INTERFACE = 0x1025U,/**< OS debug interface */
  568. OD_H1026_OS_PROMPT = 0x1026U,/**< OS prompt */
  569. OD_H1027_MODULE_LIST = 0x1027U,/**< Module list */
  570. OD_H1028_EMCY_CONSUMER = 0x1028U,/**< Emergency consumer object */
  571. OD_H1029_ERR_BEHAVIOR = 0x1029U,/**< Error behaviour */
  572. OD_H1200_SDO_SERVER_PARAM = 0x1200U,/**< SDO server parameters */
  573. OD_H1280_SDO_CLIENT_PARAM = 0x1280U,/**< SDO client parameters */
  574. OD_H1300_GFC_PARAM = 0x1300U,/**< GFC parameter */
  575. OD_H1301_SRDO_1_PARAM = 0x1301U,/**< SRDO communication parameters */
  576. OD_H1381_SRDO_1_MAPPING = 0x1381U,/**< SRDO mapping parameters */
  577. OD_H13FE_SRDO_VALID = 0x13FEU,/**< SRDO valid flag */
  578. OD_H13FF_SRDO_CHECKSUM = 0x13FFU,/**< SRDO checksum */
  579. OD_H1400_RXPDO_1_PARAM = 0x1400U,/**< RXPDO communication parameter */
  580. OD_H1401_RXPDO_2_PARAM = 0x1401U,/**< RXPDO communication parameter */
  581. OD_H1402_RXPDO_3_PARAM = 0x1402U,/**< RXPDO communication parameter */
  582. OD_H1403_RXPDO_4_PARAM = 0x1403U,/**< RXPDO communication parameter */
  583. OD_H1600_RXPDO_1_MAPPING = 0x1600U,/**< RXPDO mapping parameters */
  584. OD_H1601_RXPDO_2_MAPPING = 0x1601U,/**< RXPDO mapping parameters */
  585. OD_H1602_RXPDO_3_MAPPING = 0x1602U,/**< RXPDO mapping parameters */
  586. OD_H1603_RXPDO_4_MAPPING = 0x1603U,/**< RXPDO mapping parameters */
  587. OD_H1800_TXPDO_1_PARAM = 0x1800U,/**< TXPDO communication parameter */
  588. OD_H1801_TXPDO_2_PARAM = 0x1801U,/**< TXPDO communication parameter */
  589. OD_H1802_TXPDO_3_PARAM = 0x1802U,/**< TXPDO communication parameter */
  590. OD_H1803_TXPDO_4_PARAM = 0x1803U,/**< TXPDO communication parameter */
  591. OD_H1A00_TXPDO_1_MAPPING = 0x1A00U,/**< TXPDO mapping parameters */
  592. OD_H1A01_TXPDO_2_MAPPING = 0x1A01U,/**< TXPDO mapping parameters */
  593. OD_H1A02_TXPDO_3_MAPPING = 0x1A02U,/**< TXPDO mapping parameters */
  594. OD_H1A03_TXPDO_4_MAPPING = 0x1A03U /**< TXPDO mapping parameters */
  595. }CO_ObjDicId_t;
  596. /**
  597. * Bit masks for flags associated with variable from @ref CO_SDO_objectDictionary.
  598. *
  599. * This additional functionality of any variable in @ref CO_SDO_objectDictionary can be
  600. * enabled by function CO_OD_configure(). Location of the flag byte can be
  601. * get from function CO_OD_getFlagsPointer().
  602. */
  603. typedef enum{
  604. /** Variable was written by RPDO. Flag can be cleared by application */
  605. CO_ODFL_RPDO_WRITTEN = 0x01U,
  606. /** Variable is mapped to TPDO */
  607. CO_ODFL_TPDO_MAPPED = 0x02U,
  608. /** Change of state bit, initially copy of attribute from CO_OD_entry_t.
  609. If set and variable is mapped to TPDO, TPDO will be automatically send,
  610. if variable changed */
  611. CO_ODFL_TPDO_COS_ENABLE = 0x04U,
  612. /** PDO send bit, can be set by application. If variable is mapped into
  613. TPDO, TPDO will be send and bit will be cleared. */
  614. CO_ODFL_TPDO_SEND = 0x08U,
  615. /** Variable was accessed by SDO download */
  616. CO_ODFL_SDO_DOWNLOADED = 0x10U,
  617. /** Variable was accessed by SDO upload */
  618. CO_ODFL_SDO_UPLOADED = 0x20U,
  619. /** Reserved */
  620. CO_ODFL_BIT_6 = 0x40U,
  621. /** Reserved */
  622. CO_ODFL_BIT_7 = 0x80U
  623. }CO_SDO_OD_flags_t;
  624. /**
  625. * Return values from SDO server or client functions.
  626. */
  627. typedef enum {
  628. /** Data buffer is full.
  629. * SDO client: data must be read before next upload cycle begins. */
  630. CO_SDO_RT_uploadDataBufferFull = 5,
  631. /** CAN transmit buffer is full. Waiting. */
  632. CO_SDO_RT_transmittBufferFull = 4,
  633. /** Block download is in progress. Sending train of messages. */
  634. CO_SDO_RT_blockDownldInProgress = 3,
  635. /** Block upload is in progress. Receiving train of messages.
  636. * SDO client: Data must not be read in this state. */
  637. CO_SDO_RT_blockUploadInProgress = 2,
  638. /** Waiting server or client response */
  639. CO_SDO_RT_waitingResponse = 1,
  640. /** Success, end of communication. SDO client: uploaded data must be read.*/
  641. CO_SDO_RT_ok_communicationEnd = 0,
  642. /** Error in arguments */
  643. CO_SDO_RT_wrongArguments = -2,
  644. /** Communication ended with client abort */
  645. CO_SDO_RT_endedWithClientAbort = -9,
  646. /** Communication ended with server abort */
  647. CO_SDO_RT_endedWithServerAbort = -10,
  648. } CO_SDO_return_t;
  649. /**
  650. * Object for one entry with specific index in @ref CO_SDO_objectDictionary.
  651. */
  652. typedef struct {
  653. /** The index of Object from 0x1000 to 0xFFFF */
  654. uint16_t index;
  655. /** Number of (sub-objects - 1). If Object Type is variable, then
  656. maxSubIndex is 0, otherwise maxSubIndex is equal or greater than 1. */
  657. uint8_t maxSubIndex;
  658. /** If Object Type is record, attribute is set to zero. Attribute for
  659. each member is then set in special array with members of type
  660. CO_OD_entryRecord_t. If Object Type is Array, attribute is common for
  661. all array members. See #CO_SDO_OD_attributes_t. */
  662. uint16_t attribute;
  663. /** If Object Type is Variable, length is the length of variable in bytes.
  664. If Object Type is Array, length is the length of one array member.
  665. If Object Type is Record, length is zero. Length for each member is
  666. set in special array with members of type CO_OD_entryRecord_t.
  667. If Object Type is Domain, length is zero. Length is specified
  668. by application in @ref CO_SDO_OD_function. */
  669. uint16_t length;
  670. /** If Object Type is Variable, pData is pointer to data.
  671. If Object Type is Array, pData is pointer to data. Data doesn't
  672. include Sub-Object 0.
  673. If object type is Record, pData is pointer to special array
  674. with members of type CO_OD_entryRecord_t.
  675. If object type is Domain, pData is null. */
  676. void *pData;
  677. }CO_OD_entry_t;
  678. /**
  679. * Object for record type entry in @ref CO_SDO_objectDictionary.
  680. *
  681. * See CO_OD_entry_t.
  682. */
  683. typedef struct{
  684. /** Pointer to data. If object type is Domain, pData is null */
  685. void *pData;
  686. /** See #CO_SDO_OD_attributes_t */
  687. uint16_t attribute;
  688. /** Length of variable in bytes. If object type is Domain, length is zero */
  689. uint16_t length;
  690. }CO_OD_entryRecord_t;
  691. /**
  692. * Object contains all information about the object being transferred by SDO server.
  693. *
  694. * Object is used as an argument to @ref CO_SDO_OD_function. It is also
  695. * part of the CO_SDO_t object.
  696. */
  697. typedef struct{
  698. /** Informative parameter. It may point to object, which is connected
  699. with this OD entry. It can be used inside @ref CO_SDO_OD_function, ONLY
  700. if it was registered by CO_OD_configure() function before. */
  701. void *object;
  702. /** SDO data buffer contains data, which are exchanged in SDO transfer.
  703. @ref CO_SDO_OD_function may verify or manipulate that data before (after)
  704. they are written to (read from) Object dictionary. Data have the same
  705. endianes as processor. Pointer must NOT be changed. (Data up to length
  706. can be changed.) */
  707. uint8_t *data;
  708. /** Pointer to location in object dictionary, where data are stored.
  709. (informative reference to old data, read only). Data have the same
  710. endianes as processor. If data type is Domain, this variable is null. */
  711. const void *ODdataStorage;
  712. /** Length of data in the above buffer. Read only, except for domain. If
  713. data type is domain see @ref CO_SDO_OD_function for special rules by upload. */
  714. uint16_t dataLength;
  715. /** Attribute of object in Object dictionary (informative, must NOT be changed). */
  716. uint16_t attribute;
  717. /** Pointer to the #CO_SDO_OD_flags_t byte. */
  718. uint8_t *pFlags;
  719. /** Index of object in Object dictionary (informative, must NOT be changed). */
  720. uint16_t index;
  721. /** Subindex of object in Object dictionary (informative, must NOT be changed). */
  722. uint8_t subIndex;
  723. /** True, if SDO upload is in progress, false if SDO download is in progress. */
  724. bool_t reading;
  725. /** Used by domain data type. Indicates the first segment. Variable is informative. */
  726. bool_t firstSegment;
  727. /** Used by domain data type. If false by download, then application will
  728. receive more segments during SDO communication cycle. If uploading,
  729. application may set variable to false, so SDO server will call
  730. @ref CO_SDO_OD_function again for filling the next data. */
  731. bool_t lastSegment;
  732. /** Used by domain data type. By upload @ref CO_SDO_OD_function may write total
  733. data length, so this information will be send in SDO upload initiate phase. It
  734. is not necessary to specify this variable. By download this variable contains
  735. total data size, if size is indicated in SDO download initiate phase */
  736. uint32_t dataLengthTotal;
  737. /** Used by domain data type. In case of multiple segments, this indicates the offset
  738. into the buffer this segment starts at. */
  739. uint32_t offset;
  740. }CO_ODF_arg_t;
  741. /**
  742. * Object is used as array inside CO_SDO_t, parallel to @ref CO_SDO_objectDictionary.
  743. *
  744. * Object is generated by function CO_OD_configure(). It is then used as
  745. * extension to Object dictionary entry at specific index.
  746. */
  747. typedef struct{
  748. /** Pointer to @ref CO_SDO_OD_function */
  749. CO_SDO_abortCode_t (*pODFunc)(CO_ODF_arg_t *ODF_arg);
  750. /** Pointer to object, which will be passed to @ref CO_SDO_OD_function */
  751. void *object;
  752. /** Pointer to #CO_SDO_OD_flags_t. If object type is array or record, this
  753. variable points to array with length equal to number of subindexes. */
  754. uint8_t *flags;
  755. }CO_OD_extension_t;
  756. /**
  757. * SDO server object.
  758. */
  759. typedef struct{
  760. /** FIFO queue of the received message 8 data bytes each */
  761. uint8_t CANrxData[CO_SDO_RX_DATA_SIZE][8];
  762. /** SDO data buffer of size #CO_CONFIG_SDO_BUFFER_SIZE. */
  763. uint8_t databuffer[CO_CONFIG_SDO_BUFFER_SIZE];
  764. /** Internal flag indicates, that this object has own OD */
  765. bool_t ownOD;
  766. /** Pointer to the @ref CO_SDO_objectDictionary (array) */
  767. const CO_OD_entry_t *OD;
  768. /** Size of the @ref CO_SDO_objectDictionary */
  769. uint16_t ODSize;
  770. /** Pointer to array of CO_OD_extension_t objects. Size of the array is
  771. equal to ODSize. */
  772. CO_OD_extension_t *ODExtensions;
  773. /** Offset in buffer of next data segment being read/written */
  774. uint16_t bufferOffset;
  775. /** Sequence number of OD entry as returned from CO_OD_find() */
  776. uint16_t entryNo;
  777. /** CO_ODF_arg_t object with additional variables. Reference to this object
  778. is passed to @ref CO_SDO_OD_function */
  779. CO_ODF_arg_t ODF_arg;
  780. /** From CO_SDO_init() */
  781. uint8_t nodeId;
  782. /** Current internal state of the SDO server state machine #CO_SDO_state_t */
  783. CO_SDO_state_t state;
  784. /** Toggle bit in segmented transfer or block sequence in block transfer */
  785. uint8_t sequence;
  786. /** Maximum timeout time between request and response in microseconds. */
  787. uint32_t SDOtimeoutTime_us;
  788. /** Timeout timer for SDO communication */
  789. uint32_t timeoutTimer;
  790. /** Number of segments per block with 1 <= blksize <= 127 */
  791. uint8_t blksize;
  792. /** True, if CRC calculation by block transfer is enabled */
  793. bool_t crcEnabled;
  794. /** Calculated CRC code */
  795. uint16_t crc;
  796. /** Length of data in the last segment in block upload */
  797. uint8_t lastLen;
  798. /** Indication timeout in sub-block transfer */
  799. bool_t timeoutSubblockDownolad;
  800. /** Indication end of block transfer */
  801. bool_t endOfTransfer;
  802. /** Variables indicates, if new SDO message received from CAN bus */
  803. volatile void *CANrxNew[CO_SDO_RX_DATA_SIZE];
  804. /** Index of CANrxData for new received SDO message */
  805. uint8_t CANrxRcv;
  806. /** Index of CANrxData SDO message to processed */
  807. uint8_t CANrxProc;
  808. /** Number of new SDO messages in CANrxData to process */
  809. uint8_t CANrxSize;
  810. #if ((CO_CONFIG_SDO) & CO_CONFIG_FLAG_CALLBACK_PRE) || defined CO_DOXYGEN
  811. /** From CO_SDO_initCallbackPre() or NULL */
  812. void (*pFunctSignalPre)(void *object);
  813. /** From CO_SDO_initCallbackPre() or NULL */
  814. void *functSignalObjectPre;
  815. #endif
  816. /** From CO_SDO_init() */
  817. CO_CANmodule_t *CANdevTx;
  818. /** CAN transmit buffer inside CANdev for CAN tx message */
  819. CO_CANtx_t *CANtxBuff;
  820. }CO_SDO_t;
  821. /**
  822. * Copy 2 data bytes from source to destination. Swap bytes if
  823. * microcontroller is big-endian.
  824. *
  825. * @param dest Destination location.
  826. * @param src Source location.
  827. */
  828. #ifdef CO_LITTLE_ENDIAN
  829. #define CO_memcpySwap2(dest, src) memcpy(dest, src, 2)
  830. #endif
  831. #if defined CO_BIG_ENDIAN || defined CO_DOXYGEN
  832. static inline void CO_memcpySwap2(void* dest, const void* src){
  833. char *cdest;
  834. char *csrc;
  835. cdest = (char *) dest;
  836. csrc = (char *) src;
  837. cdest[0] = csrc[1];
  838. cdest[1] = csrc[0];
  839. }
  840. #endif
  841. /**
  842. * Copy 4 data bytes from source to destination. Swap bytes if
  843. * microcontroller is big-endian.
  844. *
  845. * @param dest Destination location.
  846. * @param src Source location.
  847. */
  848. #ifdef CO_LITTLE_ENDIAN
  849. #define CO_memcpySwap4(dest, src) memcpy(dest, src, 4)
  850. #endif
  851. #if defined CO_BIG_ENDIAN || defined CO_DOXYGEN
  852. static inline void CO_memcpySwap4(void* dest, const void* src){
  853. char *cdest;
  854. char *csrc;
  855. cdest = (char *) dest;
  856. csrc = (char *) src;
  857. cdest[0] = csrc[3];
  858. cdest[1] = csrc[2];
  859. cdest[2] = csrc[1];
  860. cdest[3] = csrc[0];
  861. }
  862. #endif
  863. /**
  864. * Copy 8 data bytes from source to destination. Swap bytes if
  865. * microcontroller is big-endian.
  866. *
  867. * @param dest Destination location.
  868. * @param src Source location.
  869. */
  870. #ifdef CO_LITTLE_ENDIAN
  871. #define CO_memcpySwap8(dest, src) memcpy(dest, src, 8)
  872. #endif
  873. #if defined CO_BIG_ENDIAN || defined CO_DOXYGEN
  874. static inline void CO_memcpySwap8(void* dest, const void* src){
  875. char *cdest;
  876. char *csrc;
  877. cdest = (char *) dest;
  878. csrc = (char *) src;
  879. cdest[0] = csrc[7];
  880. cdest[1] = csrc[6];
  881. cdest[2] = csrc[5];
  882. cdest[3] = csrc[4];
  883. cdest[4] = csrc[3];
  884. cdest[5] = csrc[2];
  885. cdest[6] = csrc[1];
  886. cdest[7] = csrc[0];
  887. }
  888. #endif
  889. /**
  890. * Initialize SDO object.
  891. *
  892. * Function must be called in the communication reset section.
  893. *
  894. * @param SDO This object will be initialized.
  895. * @param COB_IDClientToServer COB ID for client to server for this SDO object.
  896. * @param COB_IDServerToClient COB ID for server to client for this SDO object.
  897. * @param ObjDictIndex_SDOServerParameter Index in Object dictionary.
  898. * @param parentSDO Pointer to SDO object, which contains object dictionary and
  899. * its extension. For first (default) SDO object this argument must be NULL.
  900. * If this argument is specified, then OD, ODSize and ODExtensions arguments
  901. * are ignored.
  902. * @param OD Pointer to @ref CO_SDO_objectDictionary array defined externally.
  903. * @param ODSize Size of the above array.
  904. * @param ODExtensions Pointer to the externally defined array of the same size
  905. * as ODSize.
  906. * @param nodeId CANopen Node ID of this device.
  907. * @param SDOtimeoutTime_ms Timeout time for SDO communication in milliseconds.
  908. * @param CANdevRx CAN device for SDO server reception.
  909. * @param CANdevRxIdx Index of receive buffer in the above CAN device.
  910. * @param CANdevTx CAN device for SDO server transmission.
  911. * @param CANdevTxIdx Index of transmit buffer in the above CAN device.
  912. *
  913. * @return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT.
  914. */
  915. CO_ReturnError_t CO_SDO_init(
  916. CO_SDO_t *SDO,
  917. uint32_t COB_IDClientToServer,
  918. uint32_t COB_IDServerToClient,
  919. uint16_t ObjDictIndex_SDOServerParameter,
  920. CO_SDO_t *parentSDO,
  921. const CO_OD_entry_t OD[],
  922. uint16_t ODSize,
  923. CO_OD_extension_t ODExtensions[],
  924. uint8_t nodeId,
  925. uint16_t SDOtimeoutTime_ms,
  926. CO_CANmodule_t *CANdevRx,
  927. uint16_t CANdevRxIdx,
  928. CO_CANmodule_t *CANdevTx,
  929. uint16_t CANdevTxIdx);
  930. #if ((CO_CONFIG_SDO) & CO_CONFIG_FLAG_CALLBACK_PRE) || defined CO_DOXYGEN
  931. /**
  932. * Initialize SDOrx callback function.
  933. *
  934. * Function initializes optional callback function, which should immediately
  935. * start processing of CO_SDO_process() function.
  936. * Callback is called after SDOserver message is received from the CAN bus or
  937. * when new call without delay is necessary (SDO block transfer is in progress).
  938. *
  939. * @param SDO This object.
  940. * @param object Pointer to object, which will be passed to pFunctSignalPre(). Can be NULL
  941. * @param pFunctSignalPre Pointer to the callback function. Not called if NULL.
  942. */
  943. void CO_SDO_initCallbackPre(
  944. CO_SDO_t *SDO,
  945. void *object,
  946. void (*pFunctSignalPre)(void *object));
  947. #endif
  948. /**
  949. * Process SDO communication.
  950. *
  951. * Function must be called cyclically.
  952. *
  953. * @param SDO This object.
  954. * @param NMTisPreOrOperational Different than zero, if #CO_NMT_internalState_t is
  955. * NMT_PRE_OPERATIONAL or NMT_OPERATIONAL.
  956. * @param timeDifference_us Time difference from previous function call in [microseconds].
  957. * @param [out] timerNext_us info to OS - see CO_process().
  958. *
  959. * @return 0: SDO server is idle.
  960. * @return 1: SDO server is in transfer state.
  961. * @return -1: SDO abort just occurred.
  962. */
  963. int8_t CO_SDO_process(
  964. CO_SDO_t *SDO,
  965. bool_t NMTisPreOrOperational,
  966. uint32_t timeDifference_us,
  967. uint32_t *timerNext_us);
  968. /**
  969. * Configure additional functionality to one @ref CO_SDO_objectDictionary entry.
  970. *
  971. * Additional functionality include: @ref CO_SDO_OD_function and
  972. * #CO_SDO_OD_flags_t. It is optional feature and can be used on any object in
  973. * Object dictionary. If OD entry does not exist, function returns silently.
  974. *
  975. * @param SDO This object.
  976. * @param index Index of object in the Object dictionary.
  977. * @param pODFunc Pointer to @ref CO_SDO_OD_function, specified by application.
  978. * If NULL, @ref CO_SDO_OD_function will not be used on this object.
  979. * @param object Pointer to object, which will be passed to @ref CO_SDO_OD_function.
  980. * @param flags Pointer to array of #CO_SDO_OD_flags_t defined externally. If
  981. * zero, #CO_SDO_OD_flags_t will not be used on this OD entry.
  982. * @param flagsSize Size of the above array. It must be equal to number
  983. * of sub-objects in object dictionary entry. Otherwise #CO_SDO_OD_flags_t will
  984. * not be used on this OD entry.
  985. */
  986. void CO_OD_configure(
  987. CO_SDO_t *SDO,
  988. uint16_t index,
  989. CO_SDO_abortCode_t (*pODFunc)(CO_ODF_arg_t *ODF_arg),
  990. void *object,
  991. uint8_t *flags,
  992. uint8_t flagsSize);
  993. /**
  994. * Find object with specific index in Object dictionary.
  995. *
  996. * @param SDO This object.
  997. * @param index Index of the object in Object dictionary.
  998. *
  999. * @return Sequence number of the @ref CO_SDO_objectDictionary entry, 0xFFFF if not found.
  1000. */
  1001. uint16_t CO_OD_find(CO_SDO_t *SDO, uint16_t index);
  1002. /**
  1003. * Get length of the given object with specific subIndex.
  1004. *
  1005. * @param SDO This object.
  1006. * @param entryNo Sequence number of OD entry as returned from CO_OD_find().
  1007. * @param subIndex Sub-index of the object in Object dictionary.
  1008. *
  1009. * @return Data length of the variable.
  1010. */
  1011. uint16_t CO_OD_getLength(CO_SDO_t *SDO, uint16_t entryNo, uint8_t subIndex);
  1012. /**
  1013. * Get attribute of the given object with specific subIndex. See #CO_SDO_OD_attributes_t.
  1014. *
  1015. * If Object Type is array and subIndex is zero, function always returns
  1016. * 'read-only' attribute. An exception to this rule is ID1003 (Error field).
  1017. * However, this is supposed to be only written by network.
  1018. *
  1019. * @param SDO This object.
  1020. * @param entryNo Sequence number of OD entry as returned from CO_OD_find().
  1021. * @param subIndex Sub-index of the object in Object dictionary.
  1022. *
  1023. * @return Attribute of the variable.
  1024. */
  1025. uint16_t CO_OD_getAttribute(CO_SDO_t *SDO, uint16_t entryNo, uint8_t subIndex);
  1026. /**
  1027. * Get pointer to data of the given object with specific subIndex.
  1028. *
  1029. * If Object Type is array and subIndex is zero, function returns pointer to
  1030. * object->maxSubIndex variable.
  1031. *
  1032. * @param SDO This object.
  1033. * @param entryNo Sequence number of OD entry as returned from CO_OD_find().
  1034. * @param subIndex Sub-index of the object in Object dictionary.
  1035. *
  1036. * @return Pointer to the variable in @ref CO_SDO_objectDictionary.
  1037. */
  1038. void* CO_OD_getDataPointer(CO_SDO_t *SDO, uint16_t entryNo, uint8_t subIndex);
  1039. /**
  1040. * Get pointer to the #CO_SDO_OD_flags_t byte of the given object with
  1041. * specific subIndex.
  1042. *
  1043. * @param SDO This object.
  1044. * @param entryNo Sequence number of OD entry as returned from CO_OD_find().
  1045. * @param subIndex Sub-index of the object in Object dictionary.
  1046. *
  1047. * @return Pointer to the #CO_SDO_OD_flags_t of the variable.
  1048. */
  1049. uint8_t* CO_OD_getFlagsPointer(CO_SDO_t *SDO, uint16_t entryNo, uint8_t subIndex);
  1050. /**
  1051. * Initialize SDO transfer.
  1052. *
  1053. * Find object in OD, verify, fill ODF_arg s.
  1054. *
  1055. * @param SDO This object.
  1056. * @param index Index of the object in Object dictionary.
  1057. * @param subIndex subIndex of the object in Object dictionary.
  1058. *
  1059. * @return 0 on success, otherwise #CO_SDO_abortCode_t.
  1060. */
  1061. uint32_t CO_SDO_initTransfer(CO_SDO_t *SDO, uint16_t index, uint8_t subIndex);
  1062. /**
  1063. * Read data from @ref CO_SDO_objectDictionary to internal buffer.
  1064. *
  1065. * ODF_arg s must be initialized before with CO_SDO_initTransfer().
  1066. * @ref CO_SDO_OD_function is called if configured.
  1067. *
  1068. * @param SDO This object.
  1069. * @param SDOBufferSize Total size of the SDO buffer.
  1070. *
  1071. * @return 0 on success, otherwise #CO_SDO_abortCode_t.
  1072. */
  1073. uint32_t CO_SDO_readOD(CO_SDO_t *SDO, uint16_t SDOBufferSize);
  1074. /**
  1075. * Write data from internal buffer to @ref CO_SDO_objectDictionary.
  1076. *
  1077. * ODF_arg s must be initialized before with CO_SDO_initTransfer().
  1078. * @ref CO_SDO_OD_function is called if configured.
  1079. *
  1080. * @param SDO This object.
  1081. * @param length Length of data (received from network) to write.
  1082. *
  1083. * @return 0 on success, otherwise #CO_SDO_abortCode_t.
  1084. */
  1085. uint32_t CO_SDO_writeOD(CO_SDO_t *SDO, uint16_t length);
  1086. #ifdef __cplusplus
  1087. }
  1088. #endif /*__cplusplus*/
  1089. /** @} */
  1090. #endif