2 This file is part of CanFestival, a library implementing CanOpen Stack.
4 Copyright (C): Edouard TISSERANT and Francis DUPIN
6 See COPYING file for copyrights details.
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /** @defgroup comobj Communication Objects
27 /** @defgroup sdo Service Data Object (SDO)
28 * SDOs provide the access to entries in the CANopen Object Dictionary.
29 * An SDO is made up of at least two CAN messages with different identifiers.
30 * SDO s are always confirmed point-to-point communications services.
37 struct struct_s_transfer;
41 typedef void (*SDOCallback_t)(CO_Data* d, UNS8 nodeId);
43 /* The Transfer structure
44 Used to store the different segments of
45 - a SDO received before writing in the dictionary
46 - the reading of the dictionary to put on a SDO to transmit
49 struct struct_s_transfer {
50 UNS8 nodeId; /**<own ID if server, or node ID of the server if client */
52 UNS8 whoami; /**< Takes the values SDO_CLIENT or SDO_SERVER */
53 UNS8 state; /**< state of the transmission : Takes the values SDO_... */
55 UNS32 abortCode; /**< Sent or received */
56 /**< index and subindex of the dictionary where to store */
57 /**< (for a received SDO) or to read (for a transmit SDO) */
60 UNS32 count; /**< Number of data received or to be sent. */
61 UNS32 offset; /**< stack pointer of data[]
62 * Used only to tranfer part of a line to or from a SDO.
63 * offset is always pointing on the next free cell of data[].
64 * WARNING s_transfer.data is subject to ENDIANISATION
65 * (with respect to CANOPEN_BIG_ENDIAN)
67 UNS8 data [SDO_MAX_LENGTH_TRANSFERT];
68 UNS8 dataType; /**< Defined in objdictdef.h Value is visible_string
69 * if it is a string, any other value if it is not a string,
70 * like 0. In fact, it is used only if client.
72 TIMER_HANDLE timer; /**< Time counter to implement a timeout in milliseconds.
73 * It is automatically incremented whenever
74 * the line state is in SDO_DOWNLOAD_IN_PROGRESS or
75 * SDO_UPLOAD_IN_PROGRESS, and reseted to 0
76 * when the response SDO have been received.
78 SDOCallback_t Callback; /**< The user callback func to be called at SDO transaction end */
80 typedef struct struct_s_transfer s_transfer;
87 UNS8 data[8]; /**< The 8 bytes data of the SDO */
90 /* The SDO structure ...*/
92 UNS8 nodeId; /**< In any case, Node ID of the server (case sender or receiver).*/
97 typedef struct struct_s_SDO s_SDO;
100 * @brief Reset of a SDO exchange on timeout.
102 * @param *d Pointer on a CAN object data structure
105 void SDOTimeoutAlarm(CO_Data* d, UNS32 id);
108 * @brief Reset all SDO buffers.
109 * @param *d Pointer on a CAN object data structure
111 void resetSDO (CO_Data* d);
115 * @brief Copy the data received from the SDO line transfert to the object dictionary.
116 * @param *d Pointer on a CAN object data structure
117 * @param line SDO line
118 * @return SDO error code if error. Else, returns 0.
120 UNS32 SDOlineToObjdict (CO_Data* d, UNS8 line);
123 * @brief Copy the data from the object dictionary to the SDO line for a network transfert.
124 * @param *d Pointer on a CAN object data structure
125 * @param line SDO line
126 * @return SDO error code if error. Else, returns 0.
128 UNS32 objdictToSDOline (CO_Data* d, UNS8 line);
131 * @brief Copy data from an existant line in the argument "* data"
132 * @param d Pointer on a CAN object data structure
133 * @param line SDO line
135 * @param *data Pointer on the data
136 * @return 0xFF if error. Else, returns 0.
138 UNS8 lineToSDO (CO_Data* d, UNS8 line, UNS8 nbBytes, UNS8 * data);
141 * @brief Add data to an existant line
142 * @param d Pointer on a CAN object data structure
143 * @param line SDO line
145 * @param *data Pointer on the data
146 * @return 0xFF if error. Else, returns 0.
148 UNS8 SDOtoLine (CO_Data* d, UNS8 line, UNS8 nbBytes, UNS8 * data);
151 * @brief Called when an internal SDO abort occurs.
152 * Release the line * Only if server *
153 * If client, the line must be released manually in the core application.
154 * The reason of that is to permit the program to read the transfers structure before its reset,
155 * because many informations are stored on it : index, subindex, data received or trasmited, ...
156 * In all cases, sends a SDO abort.
157 * @param *d Pointer on a CAN object data structure
165 UNS8 failedSDO (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS16 index, UNS8 subIndex, UNS32 abortCode);
168 * @brief Reset an unused line.
169 * @param *d Pointer on a CAN object data structure
170 * @param line SDO line
172 void resetSDOline (CO_Data* d, UNS8 line);
175 * @brief Initialize some fields of the structure.
176 * @param *d Pointer on a CAN object data structure
184 UNS8 initSDOline (CO_Data* d, UNS8 line, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 state);
187 * @brief Search for an unused line in the transfers array
188 * to store a new SDO.
189 * ie a line which value of the field "state" is "SDO_RESET"
190 * An unused line have the field "state" at the value SDO_RESET
191 * bus_id is hardware dependant
192 * @param *d Pointer on a CAN object data structure
193 * @param whoami Create the line for a SDO_SERVER or SDO_CLIENT.
194 * @param *line Pointer on a SDO line
195 * @return 0xFF if all the lines are on use. Else, return 0.
197 UNS8 getSDOfreeLine (CO_Data* d, UNS8 whoami, UNS8 *line);
200 * @brief Search for the line, in the transfers array, which contains the
201 * beginning of the reception of a fragmented SDO
202 * bus_id is hardware dependant
203 * @param *d Pointer on a CAN object data structure
204 * @param nodeId correspond to the message node-id
205 * @param whoami takes 2 values : look for a line opened as SDO_CLIENT or SDO_SERVER
206 * @param *line Pointer on a SDO line
207 * @return 0xFF if error. Else, return 0
209 UNS8 getSDOlineOnUse (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS8 *line);
212 * @brief Close a transmission.
213 * @param *d Pointer on a CAN object data structure
214 * @param nodeId Node id of the server if both server or client
215 * @param whoami Line opened as SDO_CLIENT or SDO_SERVER
217 UNS8 closeSDOtransfer (CO_Data* d, UNS8 nodeId, UNS8 whoami);
220 * @brief Bytes in the line structure which must be transmited (or received)
221 * bus_id is hardware dependant.
222 * @param *d Pointer on a CAN object data structure
223 * @param line SDO line
224 * @param *nbBytes Pointer on nbBytes
227 UNS8 getSDOlineRestBytes (CO_Data* d, UNS8 line, UNS8 * nbBytes);
230 * @brief Store in the line structure the nb of bytes which must be transmited (or received)
231 * bus_id is hardware dependant.
232 * @param *d Pointer on a CAN object data structure
233 * @param line SDO line
235 * @return 0 if success, 0xFF if error.
237 UNS8 setSDOlineRestBytes (CO_Data* d, UNS8 line, UNS8 nbBytes);
240 * @brief Transmit a SDO frame on the bus bus_id
241 * bus_id is hardware dependant
242 * @param *d Pointer on a CAN object data structure
243 * @param whoami Takes 2 values : SDO_CLIENT or SDO_SERVER
244 * @param sdo SDO Structure which contains the sdo to transmit
245 * @return canSend(bus_id,&m) or 0xFF if error.
247 UNS8 sendSDO (CO_Data* d, UNS8 whoami, s_SDO sdo);
250 * @brief Transmit a SDO error to the client. The reasons may be :
251 * Read/Write to a undefined object
252 * Read/Write to a undefined subindex
253 * Read/write a not valid length object
254 * Write a read only object
255 * @param *d Pointer on a CAN object data structure
256 * @param whoami takes 2 values : SDO_CLIENT or SDO_SERVER
263 UNS8 sendSDOabort (CO_Data* d, UNS8 whoami, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS32 abortCode);
266 * @brief Treat a SDO frame reception
267 * bus_id is hardware dependant
268 * call the function sendSDO
269 * @param *d Pointer on a CAN object data structure
270 * @param *m Pointer on a CAN message structure
273 * - 0x80 if transfert aborted by the server
276 UNS8 proceedSDO (CO_Data* d, Message *m);
280 * @brief Used by the application to send a SDO request frame to write the data *data
281 * at the index and subIndex indicated
282 * bus_id is hardware dependant
283 * @param *d Pointer on a CAN object data structure
284 * @param nodeId In the dictionary of the slave whose node_id is nodeId
285 * @param index At index indicated
286 * @param subIndex At subIndex indicated
287 * @param count number of bytes to write in the dictionnary.
288 * @param dataType (defined in objdictdef.h) : put "visible_string" for strings, 0 for integers or reals or other value.
289 * @param *data Pointer on data
290 * @return 0xFF if error, else return 0
292 UNS8 writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
293 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data);
297 * @brief Used to send a SDO request frame to write in a distant node dictionnary.
298 * The function Callback which must be defined in the user code is called at the
299 * end of the exchange. (on succes or abort).
300 * @param *d Pointer on a CAN object data structure
301 * @param nodeId In the dictionary of the slave whose node_id is nodeId
302 * @param index At index indicated
303 * @param subIndex At subIndex indicated
304 * @param count number of bytes to write in the dictionnary.
305 * @param dataType (defined in objdictdef.h) : put "visible_string" for strings, 0 for integers or reals or other value.
306 * @param *data Pointer on data
307 * @param Callback Callback function
308 * @return 0xFF if error, else return 0
310 UNS8 writeNetworkDictCallBack (CO_Data* d, UNS8 nodeId, UNS16 index,
311 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback);
315 * @brief Used to send a SDO request frame to write in a distant node dictionnary.
316 * The function Callback which must be defined in the user code is called at the
317 * end of the exchange. (on succes or abort). First free SDO client parameter is
318 * automatically initialized for specific node if not already defined.
319 * @param *d Pointer on a CAN object data structure
320 * @param nodeId In the dictionary of the slave whose node_id is nodeId
321 * @param index At index indicated
322 * @param subIndex At subIndex indicated
323 * @param count number of bytes to write in the dictionnary.
324 * @param dataType (defined in objdictdef.h) : put "visible_string" for strings, 0 for integers or reals or other value.
325 * @param *data Pointer on data
326 * @param Callback Callback function
328 * @return 0xFF if error, else return 0
330 UNS8 writeNetworkDictCallBackAI (CO_Data* d, UNS8 nodeId, UNS16 index,
331 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback, UNS8 endianize);
335 * @brief Used by the application to send a SDO request frame to read
336 * @param *d Pointer on a CAN object data structure
337 * @param nodeId In the dictionary of the slave whose node_id is nodeId
338 * @param index At index indicated
339 * @param subIndex At subIndex indicated
340 * @param dataType (defined in objdictdef.h) : put "visible_string" for strings, 0 for integers or reals or other value. * bus_id is hardware dependant
341 * @return 0xFF if error, else return 0
343 UNS8 readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType);
347 * @brief Used to send a SDO request frame to read in a distant node dictionnary.
348 * The function Callback which must be defined in the user code is called at the
349 * end of the exchange. (on succes or abort).
350 * @param *d Pointer on a CAN object data structure
351 * @param nodeId In the dictionary of the slave whose node_id is nodeId
352 * @param index At index indicated
353 * @param subIndex At subIndex indicated
354 * @param dataType (defined in objdictdef.h) : put "visible_string" for strings, 0 for integers or reals or other value.
355 * @param Callback Callback function
356 * @return 0xFF if error, else return 0
358 UNS8 readNetworkDictCallback (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback);
362 * @brief Used to send a SDO request frame to read in a distant node dictionnary.
363 * The function Callback which must be defined in the user code is called at the
364 * end of the exchange. (on succes or abort). First free SDO client parameter is
365 * automatically initialized for specific node if not already defined.
366 * @param *d Pointer on a CAN object data structure
367 * @param nodeId In the dictionary of the slave whose node_id is nodeId
368 * @param index At index indicated
369 * @param subIndex At subIndex indicated
370 * @param dataType (defined in objdictdef.h) : put "visible_string" for strings, 0 for integers or reals or other value.
371 * @param Callback Callback function
372 * @return 0xFF if error, else return 0
374 UNS8 readNetworkDictCallbackAI (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback);
378 * @brief Use this function after a readNetworkDict to get the result.
379 * @param *d Pointer on a CAN object data structure
380 * @param nodeId In the dictionary of the slave whose node_id is nodeId
381 * @param *data Pointer on data
382 * @param *size Pointer on size
383 * @param *abortCode Pointer on the abortcode. 0 = not available. Else : SDO abort code. (received if return SDO_ABORTED_RCV)
387 * - SDO_FINISHED // data is available
388 * - SDO_ABORTED_RCV // Transfert failed. (abort SDO received)
389 * - SDO_ABORTED_INTERNAL // Transfert failed. Internal abort.
390 * - SDO_UPLOAD_IN_PROGRESS // Data not yet available
391 * - SDO_DOWNLOAD_IN_PROGRESS // Should not arrive !
396 * readNetworkDict(0, 0x05, 0x1016, 1, 0) // get the data index 1016 subindex 1 of node 5
397 * while (getReadResultNetworkDict (0, 0x05, &data, &size) != SDO_UPLOAD_IN_PROGRESS);
399 UNS8 getReadResultNetworkDict (CO_Data* d, UNS8 nodeId, void* data, UNS8 *size, UNS32 * abortCode);
402 * @brief Use this function after a writeNetworkDict to get the result of the write
403 * It is mandatory to call this function because it is releasing the line used for the transfer.
404 * @param *d Pointer on a CAN object data structure
405 * @param nodeId In the dictionary of the slave whose node_id is nodeId
406 * @param *abortCode Pointer on the abortcode. 0 = not available. Else : SDO abort code. (received if return SDO_ABORTED_RCV)
409 * - SDO_FINISHED // data is available
410 * - SDO_ABORTED_RCV // Transfert failed. (abort SDO received)
411 * - SDO_ABORTED_INTERNAL // Transfert failed. Internal abort.
412 * - SDO_DOWNLOAD_IN_PROGRESS // Data not yet available
413 * - SDO_UPLOAD_IN_PROGRESS // Should not arrive !
419 * writeNetworkDict(0, 0x05, 0x1016, 1, size, &data) // write the data index 1016 subindex 1 of node 5
420 * while (getWriteResultNetworkDict (0, 0x05, &abortCode) != SDO_DOWNLOAD_IN_PROGRESS);
422 UNS8 getWriteResultNetworkDict (CO_Data* d, UNS8 nodeId, UNS32 * abortCode);