Can_open_masternode

Dependencies:   mbed

Committer:
sam_grove
Date:
Wed Sep 26 05:48:14 2012 +0000
Revision:
7:537bae5a6fc6
Parent:
0:9dd7c6129683
Pushing the project into the new repo

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sam_grove 0:9dd7c6129683 1 /*
sam_grove 0:9dd7c6129683 2 This file is part of CanFestival, a library implementing CanOpen Stack.
sam_grove 0:9dd7c6129683 3
sam_grove 0:9dd7c6129683 4 Copyright (C): Edouard TISSERANT and Francis DUPIN
sam_grove 0:9dd7c6129683 5
sam_grove 0:9dd7c6129683 6 See COPYING file for copyrights details.
sam_grove 0:9dd7c6129683 7
sam_grove 0:9dd7c6129683 8 This library is free software; you can redistribute it and/or
sam_grove 0:9dd7c6129683 9 modify it under the terms of the GNU Lesser General Public
sam_grove 0:9dd7c6129683 10 License as published by the Free Software Foundation; either
sam_grove 0:9dd7c6129683 11 version 2.1 of the License, or (at your option) any later version.
sam_grove 0:9dd7c6129683 12
sam_grove 0:9dd7c6129683 13 This library is distributed in the hope that it will be useful,
sam_grove 0:9dd7c6129683 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
sam_grove 0:9dd7c6129683 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
sam_grove 0:9dd7c6129683 16 Lesser General Public License for more details.
sam_grove 0:9dd7c6129683 17
sam_grove 0:9dd7c6129683 18 You should have received a copy of the GNU Lesser General Public
sam_grove 0:9dd7c6129683 19 License along with this library; if not, write to the Free Software
sam_grove 0:9dd7c6129683 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
sam_grove 0:9dd7c6129683 21 */
sam_grove 0:9dd7c6129683 22 /*!
sam_grove 0:9dd7c6129683 23 ** @file sdo.c
sam_grove 0:9dd7c6129683 24 ** @author Edouard TISSERANT and Francis DUPIN
sam_grove 0:9dd7c6129683 25 ** @date Tue Jun 5 09:32:32 2007
sam_grove 0:9dd7c6129683 26 **
sam_grove 0:9dd7c6129683 27 ** @brief
sam_grove 0:9dd7c6129683 28 **
sam_grove 0:9dd7c6129683 29 **
sam_grove 0:9dd7c6129683 30 */
sam_grove 0:9dd7c6129683 31
sam_grove 0:9dd7c6129683 32 /* #define DEBUG_WAR_CONSOLE_ON */
sam_grove 0:9dd7c6129683 33 /* #define DEBUG_ERR_CONSOLE_ON */
sam_grove 0:9dd7c6129683 34
sam_grove 0:9dd7c6129683 35 #include "canfestival.h"
sam_grove 0:9dd7c6129683 36 #include "sysdep.h"
sam_grove 0:9dd7c6129683 37
sam_grove 0:9dd7c6129683 38 /* Uncomment if your compiler does not support inline functions */
sam_grove 0:9dd7c6129683 39 #define NO_INLINE
sam_grove 0:9dd7c6129683 40
sam_grove 0:9dd7c6129683 41 #ifdef NO_INLINE
sam_grove 0:9dd7c6129683 42 #define INLINE
sam_grove 0:9dd7c6129683 43 #else
sam_grove 0:9dd7c6129683 44 #define INLINE inline
sam_grove 0:9dd7c6129683 45 #endif
sam_grove 0:9dd7c6129683 46
sam_grove 0:9dd7c6129683 47 /*Internals prototypes*/
sam_grove 0:9dd7c6129683 48
sam_grove 0:9dd7c6129683 49 /*!
sam_grove 0:9dd7c6129683 50 ** Called by writeNetworkDict
sam_grove 0:9dd7c6129683 51 **
sam_grove 0:9dd7c6129683 52 ** @param d
sam_grove 0:9dd7c6129683 53 ** @param nodeId
sam_grove 0:9dd7c6129683 54 ** @param index
sam_grove 0:9dd7c6129683 55 ** @param subIndex
sam_grove 0:9dd7c6129683 56 ** @param count
sam_grove 0:9dd7c6129683 57 ** @param dataType
sam_grove 0:9dd7c6129683 58 ** @param data
sam_grove 0:9dd7c6129683 59 ** @param Callback
sam_grove 0:9dd7c6129683 60 ** @param endianize
sam_grove 0:9dd7c6129683 61 **
sam_grove 0:9dd7c6129683 62 ** @return
sam_grove 0:9dd7c6129683 63 **/
sam_grove 0:9dd7c6129683 64 INLINE UNS8 _writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
sam_grove 0:9dd7c6129683 65 UNS8 subIndex, UNS32 count, UNS8 dataType, void *data, SDOCallback_t Callback, UNS8 endianize);
sam_grove 0:9dd7c6129683 66
sam_grove 0:9dd7c6129683 67 /*!
sam_grove 0:9dd7c6129683 68 ** Called by readNetworkDict
sam_grove 0:9dd7c6129683 69 **
sam_grove 0:9dd7c6129683 70 ** @param d
sam_grove 0:9dd7c6129683 71 ** @param nodeId
sam_grove 0:9dd7c6129683 72 ** @param index
sam_grove 0:9dd7c6129683 73 ** @param subIndex
sam_grove 0:9dd7c6129683 74 ** @param dataType
sam_grove 0:9dd7c6129683 75 ** @param Callback
sam_grove 0:9dd7c6129683 76 **
sam_grove 0:9dd7c6129683 77 ** @return
sam_grove 0:9dd7c6129683 78 **/
sam_grove 0:9dd7c6129683 79 INLINE UNS8 _readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex,
sam_grove 0:9dd7c6129683 80 UNS8 dataType, SDOCallback_t Callback);
sam_grove 0:9dd7c6129683 81
sam_grove 0:9dd7c6129683 82
sam_grove 0:9dd7c6129683 83 /***************************************************************************/
sam_grove 0:9dd7c6129683 84 /* SDO (un)packing macros */
sam_grove 0:9dd7c6129683 85
sam_grove 0:9dd7c6129683 86 /** Returns the command specifier (cs, ccs, scs) from the first byte of the SDO
sam_grove 0:9dd7c6129683 87 */
sam_grove 0:9dd7c6129683 88 #define getSDOcs(byte) (byte >> 5)
sam_grove 0:9dd7c6129683 89
sam_grove 0:9dd7c6129683 90 /** Returns the number of bytes without data from the first byte of the SDO. Coded in 2 bits
sam_grove 0:9dd7c6129683 91 */
sam_grove 0:9dd7c6129683 92 #define getSDOn2(byte) ((byte >> 2) & 3)
sam_grove 0:9dd7c6129683 93
sam_grove 0:9dd7c6129683 94 /** Returns the number of bytes without data from the first byte of the SDO. Coded in 3 bits
sam_grove 0:9dd7c6129683 95 */
sam_grove 0:9dd7c6129683 96 #define getSDOn3(byte) ((byte >> 1) & 7)
sam_grove 0:9dd7c6129683 97
sam_grove 0:9dd7c6129683 98 /** Returns the transfer type from the first byte of the SDO
sam_grove 0:9dd7c6129683 99 */
sam_grove 0:9dd7c6129683 100 #define getSDOe(byte) ((byte >> 1) & 1)
sam_grove 0:9dd7c6129683 101
sam_grove 0:9dd7c6129683 102 /** Returns the size indicator from the first byte of the SDO
sam_grove 0:9dd7c6129683 103 */
sam_grove 0:9dd7c6129683 104 #define getSDOs(byte) (byte & 1)
sam_grove 0:9dd7c6129683 105
sam_grove 0:9dd7c6129683 106 /** Returns the indicator of end transmission from the first byte of the SDO
sam_grove 0:9dd7c6129683 107 */
sam_grove 0:9dd7c6129683 108 #define getSDOc(byte) (byte & 1)
sam_grove 0:9dd7c6129683 109
sam_grove 0:9dd7c6129683 110 /** Returns the toggle from the first byte of the SDO
sam_grove 0:9dd7c6129683 111 */
sam_grove 0:9dd7c6129683 112 #define getSDOt(byte) ((byte >> 4) & 1)
sam_grove 0:9dd7c6129683 113
sam_grove 0:9dd7c6129683 114 /** Returns the index from the bytes 1 and 2 of the SDO
sam_grove 0:9dd7c6129683 115 */
sam_grove 0:9dd7c6129683 116 #define getSDOindex(byte1, byte2) (((UNS16)byte2 << 8) | ((UNS16)byte1))
sam_grove 0:9dd7c6129683 117
sam_grove 0:9dd7c6129683 118 /** Returns the subIndex from the byte 3 of the SDO
sam_grove 0:9dd7c6129683 119 */
sam_grove 0:9dd7c6129683 120 #define getSDOsubIndex(byte3) (byte3)
sam_grove 0:9dd7c6129683 121
sam_grove 0:9dd7c6129683 122 /*!
sam_grove 0:9dd7c6129683 123 **
sam_grove 0:9dd7c6129683 124 **
sam_grove 0:9dd7c6129683 125 ** @param d
sam_grove 0:9dd7c6129683 126 ** @param id
sam_grove 0:9dd7c6129683 127 **/
sam_grove 0:9dd7c6129683 128 void SDOTimeoutAlarm(CO_Data* d, UNS32 id)
sam_grove 0:9dd7c6129683 129 {
sam_grove 0:9dd7c6129683 130 MSG_ERR(0x1A01, "SDO timeout. SDO response not received.", 0);
sam_grove 0:9dd7c6129683 131 MSG_WAR(0x2A02, "server node : ", d->transfers[id].nodeId);
sam_grove 0:9dd7c6129683 132 MSG_WAR(0x2A02, " index : ", d->transfers[id].index);
sam_grove 0:9dd7c6129683 133 MSG_WAR(0x2A02, " subIndex : ", d->transfers[id].subIndex);
sam_grove 0:9dd7c6129683 134 /* Reset timer handler */
sam_grove 0:9dd7c6129683 135 d->transfers[id].timer = TIMER_NONE;
sam_grove 0:9dd7c6129683 136 /*Set aborted state*/
sam_grove 0:9dd7c6129683 137 d->transfers[id].state = SDO_ABORTED_INTERNAL;
sam_grove 0:9dd7c6129683 138 /* Sending a SDO abort */
sam_grove 0:9dd7c6129683 139 sendSDOabort(d, d->transfers[id].whoami, d->transfers[id].nodeId,
sam_grove 0:9dd7c6129683 140 d->transfers[id].index, d->transfers[id].subIndex, SDOABT_TIMED_OUT);
sam_grove 0:9dd7c6129683 141 d->transfers[id].abortCode = SDOABT_TIMED_OUT;
sam_grove 0:9dd7c6129683 142 /* Call the user function to inform of the problem.*/
sam_grove 0:9dd7c6129683 143 if(d->transfers[id].Callback)
sam_grove 0:9dd7c6129683 144 /*If ther is a callback, it is responsible to close SDO transfer (client)*/
sam_grove 0:9dd7c6129683 145 (*d->transfers[id].Callback)(d,d->transfers[id].nodeId);
sam_grove 0:9dd7c6129683 146
sam_grove 0:9dd7c6129683 147 /*Reset the line if (whoami == SDO_SERVER) or the callback did not close the line.
sam_grove 0:9dd7c6129683 148 Otherwise this sdo transfer would never be closed. */
sam_grove 0:9dd7c6129683 149 resetSDOline(d, (UNS8)id);
sam_grove 0:9dd7c6129683 150 }
sam_grove 0:9dd7c6129683 151
sam_grove 0:9dd7c6129683 152 #define StopSDO_TIMER(id) \
sam_grove 0:9dd7c6129683 153 MSG_WAR(0x3A05, "StopSDO_TIMER for line : ", line);\
sam_grove 0:9dd7c6129683 154 d->transfers[id].timer = DelAlarm(d->transfers[id].timer);
sam_grove 0:9dd7c6129683 155
sam_grove 0:9dd7c6129683 156 #define StartSDO_TIMER(id) \
sam_grove 0:9dd7c6129683 157 MSG_WAR(0x3A06, "StartSDO_TIMER for line : ", line);\
sam_grove 0:9dd7c6129683 158 d->transfers[id].timer = SetAlarm(d,id,&SDOTimeoutAlarm,MS_TO_TIMEVAL(SDO_TIMEOUT_MS),0);
sam_grove 0:9dd7c6129683 159
sam_grove 0:9dd7c6129683 160 #define RestartSDO_TIMER(id) \
sam_grove 0:9dd7c6129683 161 MSG_WAR(0x3A07, "restartSDO_TIMER for line : ", line);\
sam_grove 0:9dd7c6129683 162 if(d->transfers[id].timer != TIMER_NONE) { StopSDO_TIMER(id) StartSDO_TIMER(id) }
sam_grove 0:9dd7c6129683 163
sam_grove 0:9dd7c6129683 164 /*!
sam_grove 0:9dd7c6129683 165 ** Reset all sdo buffers
sam_grove 0:9dd7c6129683 166 **
sam_grove 0:9dd7c6129683 167 ** @param d
sam_grove 0:9dd7c6129683 168 **/
sam_grove 0:9dd7c6129683 169 void resetSDO (CO_Data* d)
sam_grove 0:9dd7c6129683 170 {
sam_grove 0:9dd7c6129683 171 UNS8 j;
sam_grove 0:9dd7c6129683 172
sam_grove 0:9dd7c6129683 173 /* transfer structure initialization */
sam_grove 0:9dd7c6129683 174 for (j = 0 ; j < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; j++)
sam_grove 0:9dd7c6129683 175 resetSDOline(d, j);
sam_grove 0:9dd7c6129683 176 }
sam_grove 0:9dd7c6129683 177
sam_grove 0:9dd7c6129683 178 /*!
sam_grove 0:9dd7c6129683 179 **
sam_grove 0:9dd7c6129683 180 **
sam_grove 0:9dd7c6129683 181 ** @param d
sam_grove 0:9dd7c6129683 182 ** @param line
sam_grove 0:9dd7c6129683 183 **
sam_grove 0:9dd7c6129683 184 ** @return
sam_grove 0:9dd7c6129683 185 **/
sam_grove 0:9dd7c6129683 186 UNS32 SDOlineToObjdict (CO_Data* d, UNS8 line)
sam_grove 0:9dd7c6129683 187 {
sam_grove 0:9dd7c6129683 188 UNS32 size;
sam_grove 0:9dd7c6129683 189 UNS32 errorCode;
sam_grove 0:9dd7c6129683 190 MSG_WAR(0x3A08, "Enter in SDOlineToObjdict ", line);
sam_grove 0:9dd7c6129683 191 /* if SDO initiated with e=0 and s=0 count is null, offset carry effective size*/
sam_grove 0:9dd7c6129683 192 if( d->transfers[line].count == 0)
sam_grove 0:9dd7c6129683 193 d->transfers[line].count = d->transfers[line].offset;
sam_grove 0:9dd7c6129683 194 size = d->transfers[line].count;
sam_grove 0:9dd7c6129683 195
sam_grove 0:9dd7c6129683 196 #ifdef SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 197 if (size > SDO_MAX_LENGTH_TRANSFERT)
sam_grove 0:9dd7c6129683 198 {
sam_grove 0:9dd7c6129683 199 errorCode = setODentry(d, d->transfers[line].index, d->transfers[line].subIndex,
sam_grove 0:9dd7c6129683 200 (void *) d->transfers[line].dynamicData, &size, 1);
sam_grove 0:9dd7c6129683 201 }
sam_grove 0:9dd7c6129683 202 else
sam_grove 0:9dd7c6129683 203 {
sam_grove 0:9dd7c6129683 204 errorCode = setODentry(d, d->transfers[line].index, d->transfers[line].subIndex,
sam_grove 0:9dd7c6129683 205 (void *) d->transfers[line].data, &size, 1);
sam_grove 0:9dd7c6129683 206 }
sam_grove 0:9dd7c6129683 207 #else //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 208 errorCode = setODentry(d, d->transfers[line].index, d->transfers[line].subIndex,
sam_grove 0:9dd7c6129683 209 (void *) d->transfers[line].data, &size, 1);
sam_grove 0:9dd7c6129683 210 #endif //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 211
sam_grove 0:9dd7c6129683 212 if (errorCode != OD_SUCCESSFUL)
sam_grove 0:9dd7c6129683 213 return errorCode;
sam_grove 0:9dd7c6129683 214 MSG_WAR(0x3A08, "exit of SDOlineToObjdict ", line);
sam_grove 0:9dd7c6129683 215 return 0;
sam_grove 0:9dd7c6129683 216
sam_grove 0:9dd7c6129683 217 }
sam_grove 0:9dd7c6129683 218
sam_grove 0:9dd7c6129683 219 /*!
sam_grove 0:9dd7c6129683 220 **
sam_grove 0:9dd7c6129683 221 **
sam_grove 0:9dd7c6129683 222 ** @param d
sam_grove 0:9dd7c6129683 223 ** @param line
sam_grove 0:9dd7c6129683 224 **
sam_grove 0:9dd7c6129683 225 ** @return
sam_grove 0:9dd7c6129683 226 **/
sam_grove 0:9dd7c6129683 227 UNS32 objdictToSDOline (CO_Data* d, UNS8 line)
sam_grove 0:9dd7c6129683 228 {
sam_grove 0:9dd7c6129683 229 UNS32 size = 0;
sam_grove 0:9dd7c6129683 230 UNS8 dataType;
sam_grove 0:9dd7c6129683 231 UNS32 errorCode;
sam_grove 0:9dd7c6129683 232
sam_grove 0:9dd7c6129683 233 MSG_WAR(0x3A05, "objdict->line index : ", d->transfers[line].index);
sam_grove 0:9dd7c6129683 234 MSG_WAR(0x3A06, " subIndex : ", d->transfers[line].subIndex);
sam_grove 0:9dd7c6129683 235
sam_grove 0:9dd7c6129683 236 #ifdef SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 237 //TODO: Read the size of the object. Depending o it put data into data or dynamicData
sam_grove 0:9dd7c6129683 238 errorCode = getODentry(d, d->transfers[line].index,
sam_grove 0:9dd7c6129683 239 d->transfers[line].subIndex,
sam_grove 0:9dd7c6129683 240 (void *)d->transfers[line].data,
sam_grove 0:9dd7c6129683 241 &size, &dataType, 1);
sam_grove 0:9dd7c6129683 242 #else //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 243 errorCode = getODentry(d, d->transfers[line].index,
sam_grove 0:9dd7c6129683 244 d->transfers[line].subIndex,
sam_grove 0:9dd7c6129683 245 (void *)d->transfers[line].data,
sam_grove 0:9dd7c6129683 246 &size, &dataType, 1);
sam_grove 0:9dd7c6129683 247 #endif //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 248
sam_grove 0:9dd7c6129683 249 if (errorCode != OD_SUCCESSFUL)
sam_grove 0:9dd7c6129683 250 return errorCode;
sam_grove 0:9dd7c6129683 251
sam_grove 0:9dd7c6129683 252 d->transfers[line].count = size;
sam_grove 0:9dd7c6129683 253 d->transfers[line].offset = 0;
sam_grove 0:9dd7c6129683 254
sam_grove 0:9dd7c6129683 255 return 0;
sam_grove 0:9dd7c6129683 256 }
sam_grove 0:9dd7c6129683 257
sam_grove 0:9dd7c6129683 258 /*!
sam_grove 0:9dd7c6129683 259 **
sam_grove 0:9dd7c6129683 260 **
sam_grove 0:9dd7c6129683 261 ** @param d
sam_grove 0:9dd7c6129683 262 ** @param line
sam_grove 0:9dd7c6129683 263 ** @param nbBytes
sam_grove 0:9dd7c6129683 264 ** @param data
sam_grove 0:9dd7c6129683 265 **
sam_grove 0:9dd7c6129683 266 ** @return
sam_grove 0:9dd7c6129683 267 **/
sam_grove 0:9dd7c6129683 268 UNS8 lineToSDO (CO_Data* d, UNS8 line, UNS32 nbBytes, UNS8* data) {
sam_grove 0:9dd7c6129683 269 UNS8 i;
sam_grove 0:9dd7c6129683 270 UNS32 offset;
sam_grove 0:9dd7c6129683 271
sam_grove 0:9dd7c6129683 272 #ifndef SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 273 if ((d->transfers[line].offset + nbBytes) > SDO_MAX_LENGTH_TRANSFERT) {
sam_grove 0:9dd7c6129683 274 MSG_ERR(0x1A10,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes);
sam_grove 0:9dd7c6129683 275 return 0xFF;
sam_grove 0:9dd7c6129683 276 }
sam_grove 0:9dd7c6129683 277 #endif //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 278
sam_grove 0:9dd7c6129683 279 if ((d->transfers[line].offset + nbBytes) > d->transfers[line].count) {
sam_grove 0:9dd7c6129683 280 MSG_ERR(0x1A11,"SDO Size of data too large. Exceed count", nbBytes);
sam_grove 0:9dd7c6129683 281 return 0xFF;
sam_grove 0:9dd7c6129683 282 }
sam_grove 0:9dd7c6129683 283 offset = d->transfers[line].offset;
sam_grove 0:9dd7c6129683 284 #ifdef SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 285 if (d->transfers[line].count <= SDO_MAX_LENGTH_TRANSFERT)
sam_grove 0:9dd7c6129683 286 {
sam_grove 0:9dd7c6129683 287 for (i = 0 ; i < nbBytes ; i++)
sam_grove 0:9dd7c6129683 288 * (data + i) = d->transfers[line].data[offset + i];
sam_grove 0:9dd7c6129683 289 }
sam_grove 0:9dd7c6129683 290 else
sam_grove 0:9dd7c6129683 291 {
sam_grove 0:9dd7c6129683 292 if (d->transfers[line].dynamicData == NULL)
sam_grove 0:9dd7c6129683 293 {
sam_grove 0:9dd7c6129683 294 MSG_ERR(0x1A11,"SDO's dynamic buffer not allocated. Line", line);
sam_grove 0:9dd7c6129683 295 return 0xFF;
sam_grove 0:9dd7c6129683 296 }
sam_grove 0:9dd7c6129683 297 for (i = 0 ; i < nbBytes ; i++)
sam_grove 0:9dd7c6129683 298 * (data + i) = d->transfers[line].dynamicData[offset + i];
sam_grove 0:9dd7c6129683 299 }
sam_grove 0:9dd7c6129683 300 #else //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 301 for (i = 0 ; i < nbBytes ; i++)
sam_grove 0:9dd7c6129683 302 * (data + i) = d->transfers[line].data[offset + i];
sam_grove 0:9dd7c6129683 303 #endif //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 304 d->transfers[line].offset = d->transfers[line].offset + nbBytes;
sam_grove 0:9dd7c6129683 305 return 0;
sam_grove 0:9dd7c6129683 306 }
sam_grove 0:9dd7c6129683 307
sam_grove 0:9dd7c6129683 308 /*!
sam_grove 0:9dd7c6129683 309 **
sam_grove 0:9dd7c6129683 310 **
sam_grove 0:9dd7c6129683 311 ** @param d
sam_grove 0:9dd7c6129683 312 ** @param line
sam_grove 0:9dd7c6129683 313 ** @param nbBytes
sam_grove 0:9dd7c6129683 314 ** @param data
sam_grove 0:9dd7c6129683 315 **
sam_grove 0:9dd7c6129683 316 ** @return
sam_grove 0:9dd7c6129683 317 **/
sam_grove 0:9dd7c6129683 318 UNS8 SDOtoLine (CO_Data* d, UNS8 line, UNS32 nbBytes, UNS8* data)
sam_grove 0:9dd7c6129683 319 {
sam_grove 0:9dd7c6129683 320 UNS8 i;
sam_grove 0:9dd7c6129683 321 UNS32 offset;
sam_grove 0:9dd7c6129683 322 #ifndef SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 323 if ((d->transfers[line].offset + nbBytes) > SDO_MAX_LENGTH_TRANSFERT) {
sam_grove 0:9dd7c6129683 324 MSG_ERR(0x1A15,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes);
sam_grove 0:9dd7c6129683 325 return 0xFF;
sam_grove 0:9dd7c6129683 326 }
sam_grove 0:9dd7c6129683 327 #endif //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 328
sam_grove 0:9dd7c6129683 329 offset = d->transfers[line].offset;
sam_grove 0:9dd7c6129683 330 #ifdef SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 331 {
sam_grove 0:9dd7c6129683 332 UNS8* lineData = d->transfers[line].data;
sam_grove 0:9dd7c6129683 333 if ((d->transfers[line].offset + nbBytes) > SDO_MAX_LENGTH_TRANSFERT) {
sam_grove 0:9dd7c6129683 334 if (d->transfers[line].dynamicData == NULL) {
sam_grove 0:9dd7c6129683 335 d->transfers[line].dynamicData = (UNS8*) malloc(SDO_DYNAMIC_BUFFER_ALLOCATION_SIZE);
sam_grove 0:9dd7c6129683 336 d->transfers[line].dynamicDataSize = SDO_DYNAMIC_BUFFER_ALLOCATION_SIZE;
sam_grove 0:9dd7c6129683 337
sam_grove 0:9dd7c6129683 338 if (d->transfers[line].dynamicData == NULL) {
sam_grove 0:9dd7c6129683 339 MSG_ERR(0x1A15,"SDO allocating dynamic buffer failed, size", SDO_DYNAMIC_BUFFER_ALLOCATION_SIZE);
sam_grove 0:9dd7c6129683 340 return 0xFF;
sam_grove 0:9dd7c6129683 341 }
sam_grove 0:9dd7c6129683 342 //Copy present data
sam_grove 0:9dd7c6129683 343 memcpy(d->transfers[line].dynamicData, d->transfers[line].data, offset);
sam_grove 0:9dd7c6129683 344 }
sam_grove 0:9dd7c6129683 345 else if ((d->transfers[line].offset + nbBytes) > d->transfers[line].dynamicDataSize)
sam_grove 0:9dd7c6129683 346 {
sam_grove 0:9dd7c6129683 347 UNS8* newDynamicBuffer = (UNS8*) realloc(d->transfers[line].dynamicData, d->transfers[line].dynamicDataSize + SDO_DYNAMIC_BUFFER_ALLOCATION_SIZE);
sam_grove 0:9dd7c6129683 348 if (newDynamicBuffer == NULL) {
sam_grove 0:9dd7c6129683 349 MSG_ERR(0x1A15,"SDO reallocating dynamic buffer failed, size", d->transfers[line].dynamicDataSize + SDO_DYNAMIC_BUFFER_ALLOCATION_SIZE);
sam_grove 0:9dd7c6129683 350 return 0xFF;
sam_grove 0:9dd7c6129683 351 }
sam_grove 0:9dd7c6129683 352 d->transfers[line].dynamicData = newDynamicBuffer;
sam_grove 0:9dd7c6129683 353 d->transfers[line].dynamicDataSize += SDO_DYNAMIC_BUFFER_ALLOCATION_SIZE;
sam_grove 0:9dd7c6129683 354 }
sam_grove 0:9dd7c6129683 355 lineData = d->transfers[line].dynamicData;
sam_grove 0:9dd7c6129683 356 }
sam_grove 0:9dd7c6129683 357
sam_grove 0:9dd7c6129683 358 for (i = 0 ; i < nbBytes ; i++)
sam_grove 0:9dd7c6129683 359 lineData[offset + i] = * (data + i);
sam_grove 0:9dd7c6129683 360 }
sam_grove 0:9dd7c6129683 361 #else //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 362 for (i = 0 ; i < nbBytes ; i++)
sam_grove 0:9dd7c6129683 363 d->transfers[line].data[offset + i] = * (data + i);
sam_grove 0:9dd7c6129683 364 #endif //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 365
sam_grove 0:9dd7c6129683 366 d->transfers[line].offset = d->transfers[line].offset + nbBytes;
sam_grove 0:9dd7c6129683 367 return 0;
sam_grove 0:9dd7c6129683 368 }
sam_grove 0:9dd7c6129683 369
sam_grove 0:9dd7c6129683 370 /*!
sam_grove 0:9dd7c6129683 371 **
sam_grove 0:9dd7c6129683 372 **
sam_grove 0:9dd7c6129683 373 ** @param d
sam_grove 0:9dd7c6129683 374 ** @param nodeId
sam_grove 0:9dd7c6129683 375 ** @param whoami
sam_grove 0:9dd7c6129683 376 ** @param index
sam_grove 0:9dd7c6129683 377 ** @param subIndex
sam_grove 0:9dd7c6129683 378 ** @param abortCode
sam_grove 0:9dd7c6129683 379 **
sam_grove 0:9dd7c6129683 380 ** @return
sam_grove 0:9dd7c6129683 381 **/
sam_grove 0:9dd7c6129683 382 UNS8 failedSDO (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS16 index,
sam_grove 0:9dd7c6129683 383 UNS8 subIndex, UNS32 abortCode)
sam_grove 0:9dd7c6129683 384 {
sam_grove 0:9dd7c6129683 385 UNS8 err;
sam_grove 0:9dd7c6129683 386 UNS8 line;
sam_grove 0:9dd7c6129683 387 err = getSDOlineOnUse( d, nodeId, whoami, &line );
sam_grove 0:9dd7c6129683 388 if (!err) /* If a line on use have been found.*/
sam_grove 0:9dd7c6129683 389 MSG_WAR(0x3A20, "FailedSDO : line found : ", line);
sam_grove 0:9dd7c6129683 390 if ((! err) && (whoami == SDO_SERVER)) {
sam_grove 0:9dd7c6129683 391 resetSDOline( d, line );
sam_grove 0:9dd7c6129683 392 MSG_WAR(0x3A21, "FailedSDO : line released : ", line);
sam_grove 0:9dd7c6129683 393 }
sam_grove 0:9dd7c6129683 394 if ((! err) && (whoami == SDO_CLIENT)) {
sam_grove 0:9dd7c6129683 395 StopSDO_TIMER(line);
sam_grove 0:9dd7c6129683 396 d->transfers[line].state = SDO_ABORTED_INTERNAL;
sam_grove 0:9dd7c6129683 397 }
sam_grove 0:9dd7c6129683 398 MSG_WAR(0x3A22, "Sending SDO abort ", 0);
sam_grove 0:9dd7c6129683 399 err = sendSDOabort(d, whoami, nodeId, index, subIndex, abortCode);
sam_grove 0:9dd7c6129683 400 if (err) {
sam_grove 0:9dd7c6129683 401 MSG_WAR(0x3A23, "Unable to send the SDO abort", 0);
sam_grove 0:9dd7c6129683 402 return 0xFF;
sam_grove 0:9dd7c6129683 403 }
sam_grove 0:9dd7c6129683 404 return 0;
sam_grove 0:9dd7c6129683 405 }
sam_grove 0:9dd7c6129683 406
sam_grove 0:9dd7c6129683 407 /*!
sam_grove 0:9dd7c6129683 408 **
sam_grove 0:9dd7c6129683 409 **
sam_grove 0:9dd7c6129683 410 ** @param d
sam_grove 0:9dd7c6129683 411 ** @param line
sam_grove 0:9dd7c6129683 412 **/
sam_grove 0:9dd7c6129683 413 void resetSDOline ( CO_Data* d, UNS8 line )
sam_grove 0:9dd7c6129683 414 {
sam_grove 0:9dd7c6129683 415 UNS32 i;
sam_grove 0:9dd7c6129683 416 MSG_WAR(0x3A25, "reset SDO line nb : ", line);
sam_grove 0:9dd7c6129683 417 initSDOline(d, line, 0, 0, 0, SDO_RESET);
sam_grove 0:9dd7c6129683 418 for (i = 0 ; i < SDO_MAX_LENGTH_TRANSFERT ; i++)
sam_grove 0:9dd7c6129683 419 d->transfers[line].data[i] = 0;
sam_grove 0:9dd7c6129683 420 d->transfers[line].whoami = 0;
sam_grove 0:9dd7c6129683 421 d->transfers[line].abortCode = 0;
sam_grove 0:9dd7c6129683 422 #ifdef SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 423 free(d->transfers[line].dynamicData);
sam_grove 0:9dd7c6129683 424 d->transfers[line].dynamicData = 0;
sam_grove 0:9dd7c6129683 425 d->transfers[line].dynamicDataSize = 0;
sam_grove 0:9dd7c6129683 426 #endif //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 427 }
sam_grove 0:9dd7c6129683 428
sam_grove 0:9dd7c6129683 429 /*!
sam_grove 0:9dd7c6129683 430 **
sam_grove 0:9dd7c6129683 431 **
sam_grove 0:9dd7c6129683 432 ** @param d
sam_grove 0:9dd7c6129683 433 ** @param line
sam_grove 0:9dd7c6129683 434 ** @param nodeId
sam_grove 0:9dd7c6129683 435 ** @param index
sam_grove 0:9dd7c6129683 436 ** @param subIndex
sam_grove 0:9dd7c6129683 437 ** @param state
sam_grove 0:9dd7c6129683 438 **
sam_grove 0:9dd7c6129683 439 ** @return
sam_grove 0:9dd7c6129683 440 **/
sam_grove 0:9dd7c6129683 441 UNS8 initSDOline (CO_Data* d, UNS8 line, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 state)
sam_grove 0:9dd7c6129683 442 {
sam_grove 0:9dd7c6129683 443 MSG_WAR(0x3A25, "init SDO line nb : ", line);
sam_grove 0:9dd7c6129683 444 if (state == SDO_DOWNLOAD_IN_PROGRESS || state == SDO_UPLOAD_IN_PROGRESS){
sam_grove 0:9dd7c6129683 445 StartSDO_TIMER(line)
sam_grove 0:9dd7c6129683 446 }else{
sam_grove 0:9dd7c6129683 447 StopSDO_TIMER(line)
sam_grove 0:9dd7c6129683 448 }
sam_grove 0:9dd7c6129683 449 d->transfers[line].nodeId = nodeId;
sam_grove 0:9dd7c6129683 450 d->transfers[line].index = index;
sam_grove 0:9dd7c6129683 451 d->transfers[line].subIndex = subIndex;
sam_grove 0:9dd7c6129683 452 d->transfers[line].state = state;
sam_grove 0:9dd7c6129683 453 d->transfers[line].toggle = 0;
sam_grove 0:9dd7c6129683 454 d->transfers[line].count = 0;
sam_grove 0:9dd7c6129683 455 d->transfers[line].offset = 0;
sam_grove 0:9dd7c6129683 456 d->transfers[line].dataType = 0;
sam_grove 0:9dd7c6129683 457 d->transfers[line].Callback = NULL;
sam_grove 0:9dd7c6129683 458 #ifdef SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 459 free(d->transfers[line].dynamicData);
sam_grove 0:9dd7c6129683 460 d->transfers[line].dynamicData = 0;
sam_grove 0:9dd7c6129683 461 d->transfers[line].dynamicDataSize = 0;
sam_grove 0:9dd7c6129683 462 #endif //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 463 return 0;
sam_grove 0:9dd7c6129683 464 }
sam_grove 0:9dd7c6129683 465
sam_grove 0:9dd7c6129683 466 /*!
sam_grove 0:9dd7c6129683 467 **
sam_grove 0:9dd7c6129683 468 **
sam_grove 0:9dd7c6129683 469 ** @param d
sam_grove 0:9dd7c6129683 470 ** @param whoami
sam_grove 0:9dd7c6129683 471 ** @param line
sam_grove 0:9dd7c6129683 472 **
sam_grove 0:9dd7c6129683 473 ** @return
sam_grove 0:9dd7c6129683 474 **/
sam_grove 0:9dd7c6129683 475 UNS8 getSDOfreeLine ( CO_Data* d, UNS8 whoami, UNS8 *line )
sam_grove 0:9dd7c6129683 476 {
sam_grove 0:9dd7c6129683 477
sam_grove 0:9dd7c6129683 478 UNS8 i;
sam_grove 0:9dd7c6129683 479
sam_grove 0:9dd7c6129683 480 for (i = 0 ; i < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; i++){
sam_grove 0:9dd7c6129683 481 if ( d->transfers[i].state == SDO_RESET ) {
sam_grove 0:9dd7c6129683 482 *line = i;
sam_grove 0:9dd7c6129683 483 d->transfers[i].whoami = whoami;
sam_grove 0:9dd7c6129683 484 return 0;
sam_grove 0:9dd7c6129683 485 } /* end if */
sam_grove 0:9dd7c6129683 486 } /* end for */
sam_grove 0:9dd7c6129683 487 MSG_ERR(0x1A25, "Too many SDO in progress. Aborted.", i);
sam_grove 0:9dd7c6129683 488 return 0xFF;
sam_grove 0:9dd7c6129683 489 }
sam_grove 0:9dd7c6129683 490
sam_grove 0:9dd7c6129683 491 /*!
sam_grove 0:9dd7c6129683 492 **
sam_grove 0:9dd7c6129683 493 **
sam_grove 0:9dd7c6129683 494 ** @param d
sam_grove 0:9dd7c6129683 495 ** @param nodeId
sam_grove 0:9dd7c6129683 496 ** @param whoami
sam_grove 0:9dd7c6129683 497 ** @param line
sam_grove 0:9dd7c6129683 498 **
sam_grove 0:9dd7c6129683 499 ** @return
sam_grove 0:9dd7c6129683 500 **/
sam_grove 0:9dd7c6129683 501 UNS8 getSDOlineOnUse (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS8 *line)
sam_grove 0:9dd7c6129683 502 {
sam_grove 0:9dd7c6129683 503
sam_grove 0:9dd7c6129683 504 UNS8 i;
sam_grove 0:9dd7c6129683 505
sam_grove 0:9dd7c6129683 506 for (i = 0 ; i < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; i++){
sam_grove 0:9dd7c6129683 507 if ( (d->transfers[i].state != SDO_RESET) &&
sam_grove 0:9dd7c6129683 508 (d->transfers[i].state != SDO_ABORTED_INTERNAL) &&
sam_grove 0:9dd7c6129683 509 (d->transfers[i].nodeId == nodeId) &&
sam_grove 0:9dd7c6129683 510 (d->transfers[i].whoami == whoami) ) {
sam_grove 0:9dd7c6129683 511 if (line) *line = i;
sam_grove 0:9dd7c6129683 512 return 0;
sam_grove 0:9dd7c6129683 513 }
sam_grove 0:9dd7c6129683 514 }
sam_grove 0:9dd7c6129683 515 return 0xFF;
sam_grove 0:9dd7c6129683 516 }
sam_grove 0:9dd7c6129683 517
sam_grove 0:9dd7c6129683 518 /*!
sam_grove 0:9dd7c6129683 519 **
sam_grove 0:9dd7c6129683 520 **
sam_grove 0:9dd7c6129683 521 ** @param d
sam_grove 0:9dd7c6129683 522 ** @param nodeId
sam_grove 0:9dd7c6129683 523 ** @param whoami
sam_grove 0:9dd7c6129683 524 ** @param line
sam_grove 0:9dd7c6129683 525 **
sam_grove 0:9dd7c6129683 526 ** @return
sam_grove 0:9dd7c6129683 527 **/
sam_grove 0:9dd7c6129683 528 UNS8 getSDOlineToClose (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS8 *line)
sam_grove 0:9dd7c6129683 529 {
sam_grove 0:9dd7c6129683 530
sam_grove 0:9dd7c6129683 531 UNS8 i;
sam_grove 0:9dd7c6129683 532
sam_grove 0:9dd7c6129683 533 for (i = 0 ; i < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; i++){
sam_grove 0:9dd7c6129683 534 if ( (d->transfers[i].state != SDO_RESET) &&
sam_grove 0:9dd7c6129683 535 (d->transfers[i].nodeId == nodeId) &&
sam_grove 0:9dd7c6129683 536 (d->transfers[i].whoami == whoami) ) {
sam_grove 0:9dd7c6129683 537 if (line) *line = i;
sam_grove 0:9dd7c6129683 538 return 0;
sam_grove 0:9dd7c6129683 539 }
sam_grove 0:9dd7c6129683 540 }
sam_grove 0:9dd7c6129683 541 return 0xFF;
sam_grove 0:9dd7c6129683 542 }
sam_grove 0:9dd7c6129683 543
sam_grove 0:9dd7c6129683 544
sam_grove 0:9dd7c6129683 545 /*!
sam_grove 0:9dd7c6129683 546 **
sam_grove 0:9dd7c6129683 547 **
sam_grove 0:9dd7c6129683 548 ** @param d
sam_grove 0:9dd7c6129683 549 ** @param nodeId
sam_grove 0:9dd7c6129683 550 ** @param whoami
sam_grove 0:9dd7c6129683 551 **
sam_grove 0:9dd7c6129683 552 ** @return
sam_grove 0:9dd7c6129683 553 **/
sam_grove 0:9dd7c6129683 554 UNS8 closeSDOtransfer (CO_Data* d, UNS8 nodeId, UNS8 whoami)
sam_grove 0:9dd7c6129683 555 {
sam_grove 0:9dd7c6129683 556 UNS8 err;
sam_grove 0:9dd7c6129683 557 UNS8 line;
sam_grove 0:9dd7c6129683 558 err = getSDOlineToClose(d, nodeId, whoami, &line);
sam_grove 0:9dd7c6129683 559 if (err) {
sam_grove 0:9dd7c6129683 560 MSG_WAR(0x2A30, "No SDO communication to close for node : ", nodeId);
sam_grove 0:9dd7c6129683 561 return 0xFF;
sam_grove 0:9dd7c6129683 562 }
sam_grove 0:9dd7c6129683 563 resetSDOline(d, line);
sam_grove 0:9dd7c6129683 564 return 0;
sam_grove 0:9dd7c6129683 565 }
sam_grove 0:9dd7c6129683 566
sam_grove 0:9dd7c6129683 567 /*!
sam_grove 0:9dd7c6129683 568 **
sam_grove 0:9dd7c6129683 569 **
sam_grove 0:9dd7c6129683 570 ** @param d
sam_grove 0:9dd7c6129683 571 ** @param line
sam_grove 0:9dd7c6129683 572 ** @param nbBytes
sam_grove 0:9dd7c6129683 573 **
sam_grove 0:9dd7c6129683 574 ** @return
sam_grove 0:9dd7c6129683 575 **/
sam_grove 0:9dd7c6129683 576 UNS8 getSDOlineRestBytes (CO_Data* d, UNS8 line, UNS32 * nbBytes)
sam_grove 0:9dd7c6129683 577 {
sam_grove 0:9dd7c6129683 578 /* SDO initiated with e=0 and s=0 have count set to null */
sam_grove 0:9dd7c6129683 579 if (d->transfers[line].count == 0)
sam_grove 0:9dd7c6129683 580 * nbBytes = 0;
sam_grove 0:9dd7c6129683 581 else
sam_grove 0:9dd7c6129683 582 * nbBytes = d->transfers[line].count - d->transfers[line].offset;
sam_grove 0:9dd7c6129683 583 return 0;
sam_grove 0:9dd7c6129683 584 }
sam_grove 0:9dd7c6129683 585
sam_grove 0:9dd7c6129683 586 /*!
sam_grove 0:9dd7c6129683 587 **
sam_grove 0:9dd7c6129683 588 **
sam_grove 0:9dd7c6129683 589 ** @param d
sam_grove 0:9dd7c6129683 590 ** @param line
sam_grove 0:9dd7c6129683 591 ** @param nbBytes
sam_grove 0:9dd7c6129683 592 **
sam_grove 0:9dd7c6129683 593 ** @return
sam_grove 0:9dd7c6129683 594 **/
sam_grove 0:9dd7c6129683 595 UNS8 setSDOlineRestBytes (CO_Data* d, UNS8 line, UNS32 nbBytes)
sam_grove 0:9dd7c6129683 596 {
sam_grove 0:9dd7c6129683 597 #ifndef SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 598 if (nbBytes > SDO_MAX_LENGTH_TRANSFERT) {
sam_grove 0:9dd7c6129683 599 MSG_ERR(0x1A35,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes);
sam_grove 0:9dd7c6129683 600 return 0xFF;
sam_grove 0:9dd7c6129683 601 }
sam_grove 0:9dd7c6129683 602 #endif //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 603
sam_grove 0:9dd7c6129683 604 d->transfers[line].count = nbBytes;
sam_grove 0:9dd7c6129683 605 return 0;
sam_grove 0:9dd7c6129683 606 }
sam_grove 0:9dd7c6129683 607
sam_grove 0:9dd7c6129683 608 /*!
sam_grove 0:9dd7c6129683 609 **
sam_grove 0:9dd7c6129683 610 **
sam_grove 0:9dd7c6129683 611 ** @param d
sam_grove 0:9dd7c6129683 612 ** @param whoami
sam_grove 0:9dd7c6129683 613 ** @param sdo
sam_grove 0:9dd7c6129683 614 **
sam_grove 0:9dd7c6129683 615 ** @return
sam_grove 0:9dd7c6129683 616 **/
sam_grove 0:9dd7c6129683 617 UNS8 sendSDO (CO_Data* d, UNS8 whoami, s_SDO sdo)
sam_grove 0:9dd7c6129683 618 {
sam_grove 0:9dd7c6129683 619 UNS16 offset;
sam_grove 0:9dd7c6129683 620 UNS16 lastIndex;
sam_grove 0:9dd7c6129683 621 UNS8 found = 0;
sam_grove 0:9dd7c6129683 622 Message m;
sam_grove 0:9dd7c6129683 623 UNS8 i;
sam_grove 0:9dd7c6129683 624 UNS32 * pwCobId = NULL;
sam_grove 0:9dd7c6129683 625 UNS8 * pwNodeId = NULL;
sam_grove 0:9dd7c6129683 626
sam_grove 0:9dd7c6129683 627 MSG_WAR(0x3A38, "sendSDO",0);
sam_grove 0:9dd7c6129683 628 if( !((d->nodeState == Operational) || (d->nodeState == Pre_operational ))) {
sam_grove 0:9dd7c6129683 629 MSG_WAR(0x2A39, "unable to send the SDO (not in op or pre-op mode", d->nodeState);
sam_grove 0:9dd7c6129683 630 return 0xFF;
sam_grove 0:9dd7c6129683 631 }
sam_grove 0:9dd7c6129683 632
sam_grove 0:9dd7c6129683 633 /*get the server->client cobid*/
sam_grove 0:9dd7c6129683 634 if ( whoami == SDO_SERVER ) {/*case server. only one SDO server*/
sam_grove 0:9dd7c6129683 635 offset = d->firstIndex->SDO_SVR;
sam_grove 0:9dd7c6129683 636 if (offset == 0) {
sam_grove 0:9dd7c6129683 637 MSG_ERR(0x1A42, "SendSDO : No SDO server found", 0);
sam_grove 0:9dd7c6129683 638 return 0xFF;
sam_grove 0:9dd7c6129683 639 }
sam_grove 0:9dd7c6129683 640 pwCobId = (UNS32*) d->objdict[offset].pSubindex[2].pObject;
sam_grove 0:9dd7c6129683 641 MSG_WAR(0x3A41, "I am server. cobId : ", *pwCobId);
sam_grove 0:9dd7c6129683 642 }
sam_grove 0:9dd7c6129683 643 else { /*case client*/
sam_grove 0:9dd7c6129683 644 /* Get the client->server cobid.*/
sam_grove 0:9dd7c6129683 645 UNS16 sdoNum = 0;
sam_grove 0:9dd7c6129683 646 offset = d->firstIndex->SDO_CLT;
sam_grove 0:9dd7c6129683 647 lastIndex = d->lastIndex->SDO_CLT;
sam_grove 0:9dd7c6129683 648 if (offset == 0) {
sam_grove 0:9dd7c6129683 649 MSG_ERR(0x1A42, "SendSDO : No SDO client index found", 0);
sam_grove 0:9dd7c6129683 650 return 0xFF;
sam_grove 0:9dd7c6129683 651 }
sam_grove 0:9dd7c6129683 652 /* find index for communication server node */
sam_grove 0:9dd7c6129683 653 while (offset <= lastIndex){
sam_grove 0:9dd7c6129683 654 MSG_WAR(0x3A43,"Reading index : ", 0x1280 + sdoNum);
sam_grove 0:9dd7c6129683 655 if (d->objdict[offset].bSubCount <= 3) {
sam_grove 0:9dd7c6129683 656 MSG_ERR(0x1A28, "Subindex 3 not found at index ", 0x1280 + sdoNum);
sam_grove 0:9dd7c6129683 657 return 0xFF;
sam_grove 0:9dd7c6129683 658 }
sam_grove 0:9dd7c6129683 659 pwNodeId = (UNS8*) d->objdict[offset].pSubindex[3].pObject;
sam_grove 0:9dd7c6129683 660 MSG_WAR(0x3A44, "Found nodeId server = ", *pwNodeId);
sam_grove 0:9dd7c6129683 661 if(*pwNodeId == sdo.nodeId) {
sam_grove 0:9dd7c6129683 662 found = 1;
sam_grove 0:9dd7c6129683 663 break;
sam_grove 0:9dd7c6129683 664 }
sam_grove 0:9dd7c6129683 665 offset ++;
sam_grove 0:9dd7c6129683 666 sdoNum ++;
sam_grove 0:9dd7c6129683 667 }
sam_grove 0:9dd7c6129683 668 if (! found){
sam_grove 0:9dd7c6129683 669 MSG_WAR (0x2A45, "No SDO client corresponds to the mesage to send to node ", sdo.nodeId);
sam_grove 0:9dd7c6129683 670 return 0xFF;
sam_grove 0:9dd7c6129683 671 }
sam_grove 0:9dd7c6129683 672 /* read the client->server cobid */
sam_grove 0:9dd7c6129683 673 pwCobId = (UNS32*) d->objdict[offset].pSubindex[1].pObject;
sam_grove 0:9dd7c6129683 674 }
sam_grove 0:9dd7c6129683 675 /* message copy for sending */
sam_grove 0:9dd7c6129683 676 m.cob_id = (UNS16)UNS16_LE(*pwCobId);
sam_grove 0:9dd7c6129683 677 m.rtr = NOT_A_REQUEST;
sam_grove 0:9dd7c6129683 678 /* the length of SDO must be 8 */
sam_grove 0:9dd7c6129683 679 m.len = 8;
sam_grove 0:9dd7c6129683 680 for (i = 0 ; i < 8 ; i++) {
sam_grove 0:9dd7c6129683 681 m.data[i] = sdo.body.data[i];
sam_grove 0:9dd7c6129683 682 }
sam_grove 0:9dd7c6129683 683 return canSend(d->canHandle,&m);
sam_grove 0:9dd7c6129683 684 }
sam_grove 0:9dd7c6129683 685
sam_grove 0:9dd7c6129683 686 /*!
sam_grove 0:9dd7c6129683 687 **
sam_grove 0:9dd7c6129683 688 **
sam_grove 0:9dd7c6129683 689 ** @param d
sam_grove 0:9dd7c6129683 690 ** @param whoami
sam_grove 0:9dd7c6129683 691 ** @param index
sam_grove 0:9dd7c6129683 692 ** @param subIndex
sam_grove 0:9dd7c6129683 693 ** @param abortCode
sam_grove 0:9dd7c6129683 694 **
sam_grove 0:9dd7c6129683 695 ** @return
sam_grove 0:9dd7c6129683 696 **/
sam_grove 0:9dd7c6129683 697 UNS8 sendSDOabort (CO_Data* d, UNS8 whoami, UNS8 nodeID, UNS16 index, UNS8 subIndex, UNS32 abortCode)
sam_grove 0:9dd7c6129683 698 {
sam_grove 0:9dd7c6129683 699 s_SDO sdo;
sam_grove 0:9dd7c6129683 700 UNS8 ret;
sam_grove 0:9dd7c6129683 701
sam_grove 0:9dd7c6129683 702 MSG_WAR(0x2A50,"Sending SDO abort ", abortCode);
sam_grove 0:9dd7c6129683 703 if(whoami == SDO_SERVER)
sam_grove 0:9dd7c6129683 704 {
sam_grove 0:9dd7c6129683 705 sdo.nodeId = *d->bDeviceNodeId;
sam_grove 0:9dd7c6129683 706 }
sam_grove 0:9dd7c6129683 707 else
sam_grove 0:9dd7c6129683 708 {
sam_grove 0:9dd7c6129683 709 sdo.nodeId = nodeID;
sam_grove 0:9dd7c6129683 710 }
sam_grove 0:9dd7c6129683 711 sdo.body.data[0] = 0x80;
sam_grove 0:9dd7c6129683 712 /* Index */
sam_grove 0:9dd7c6129683 713 sdo.body.data[1] = index & 0xFF; /* LSB */
sam_grove 0:9dd7c6129683 714 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
sam_grove 0:9dd7c6129683 715 /* Subindex */
sam_grove 0:9dd7c6129683 716 sdo.body.data[3] = subIndex;
sam_grove 0:9dd7c6129683 717 /* Data */
sam_grove 0:9dd7c6129683 718 sdo.body.data[4] = (UNS8)(abortCode & 0xFF);
sam_grove 0:9dd7c6129683 719 sdo.body.data[5] = (UNS8)((abortCode >> 8) & 0xFF);
sam_grove 0:9dd7c6129683 720 sdo.body.data[6] = (UNS8)((abortCode >> 16) & 0xFF);
sam_grove 0:9dd7c6129683 721 sdo.body.data[7] = (UNS8)((abortCode >> 24) & 0xFF);
sam_grove 0:9dd7c6129683 722 ret = sendSDO(d, whoami, sdo);
sam_grove 0:9dd7c6129683 723
sam_grove 0:9dd7c6129683 724 return ret;
sam_grove 0:9dd7c6129683 725 }
sam_grove 0:9dd7c6129683 726
sam_grove 0:9dd7c6129683 727 /*!
sam_grove 0:9dd7c6129683 728 **
sam_grove 0:9dd7c6129683 729 **
sam_grove 0:9dd7c6129683 730 ** @param d
sam_grove 0:9dd7c6129683 731 ** @param m
sam_grove 0:9dd7c6129683 732 **
sam_grove 0:9dd7c6129683 733 ** @return
sam_grove 0:9dd7c6129683 734 **/
sam_grove 0:9dd7c6129683 735 UNS8 proceedSDO (CO_Data* d, Message *m)
sam_grove 0:9dd7c6129683 736 {
sam_grove 0:9dd7c6129683 737 UNS8 err;
sam_grove 0:9dd7c6129683 738 UNS8 line;
sam_grove 0:9dd7c6129683 739 UNS32 nbBytes; /* received or to be transmited. */
sam_grove 0:9dd7c6129683 740 UNS8 nodeId = 0; /* The node from which the SDO is received */
sam_grove 0:9dd7c6129683 741 UNS8 *pNodeId = NULL;
sam_grove 0:9dd7c6129683 742 UNS8 whoami = SDO_UNKNOWN; /* SDO_SERVER or SDO_CLIENT.*/
sam_grove 0:9dd7c6129683 743 UNS32 errorCode; /* while reading or writing in the local object dictionary.*/
sam_grove 0:9dd7c6129683 744 s_SDO sdo; /* SDO to transmit */
sam_grove 0:9dd7c6129683 745 UNS16 index;
sam_grove 0:9dd7c6129683 746 UNS8 subIndex;
sam_grove 0:9dd7c6129683 747 UNS32 abortCode;
sam_grove 0:9dd7c6129683 748 UNS32 i;
sam_grove 0:9dd7c6129683 749 UNS8 j;
sam_grove 0:9dd7c6129683 750 UNS32 *pCobId = NULL;
sam_grove 0:9dd7c6129683 751 UNS16 offset;
sam_grove 0:9dd7c6129683 752 UNS16 lastIndex;
sam_grove 0:9dd7c6129683 753
sam_grove 0:9dd7c6129683 754 MSG_WAR(0x3A60, "proceedSDO ", 0);
sam_grove 0:9dd7c6129683 755 whoami = SDO_UNKNOWN;
sam_grove 0:9dd7c6129683 756 /* Looking for the cobId in the object dictionary. */
sam_grove 0:9dd7c6129683 757 /* Am-I a server ? */
sam_grove 0:9dd7c6129683 758 offset = d->firstIndex->SDO_SVR;
sam_grove 0:9dd7c6129683 759 lastIndex = d->lastIndex->SDO_SVR;
sam_grove 0:9dd7c6129683 760 j = 0;
sam_grove 0:9dd7c6129683 761 if(offset) while (offset <= lastIndex) {
sam_grove 0:9dd7c6129683 762 if (d->objdict[offset].bSubCount <= 1) {
sam_grove 0:9dd7c6129683 763 MSG_ERR(0x1A61, "Subindex 1 not found at index ", 0x1200 + j);
sam_grove 0:9dd7c6129683 764 return 0xFF;
sam_grove 0:9dd7c6129683 765 }
sam_grove 0:9dd7c6129683 766 pCobId = (UNS32*) d->objdict[offset].pSubindex[1].pObject;
sam_grove 0:9dd7c6129683 767 if ( *pCobId == UNS16_LE(m->cob_id) ) {
sam_grove 0:9dd7c6129683 768 whoami = SDO_SERVER;
sam_grove 0:9dd7c6129683 769 MSG_WAR(0x3A62, "proceedSDO. I am server. index : ", 0x1200 + j);
sam_grove 0:9dd7c6129683 770 /* In case of server, the node id of the client may be unknown. So we put the index minus offset */
sam_grove 0:9dd7c6129683 771 /* 0x1200 where the cobid received is defined. */
sam_grove 0:9dd7c6129683 772 nodeId = j;
sam_grove 0:9dd7c6129683 773 break;
sam_grove 0:9dd7c6129683 774 }
sam_grove 0:9dd7c6129683 775 j++;
sam_grove 0:9dd7c6129683 776 offset++;
sam_grove 0:9dd7c6129683 777 } /* end while */
sam_grove 0:9dd7c6129683 778 if (whoami == SDO_UNKNOWN) {
sam_grove 0:9dd7c6129683 779 /* Am-I client ? */
sam_grove 0:9dd7c6129683 780 offset = d->firstIndex->SDO_CLT;
sam_grove 0:9dd7c6129683 781 lastIndex = d->lastIndex->SDO_CLT;
sam_grove 0:9dd7c6129683 782 j = 0;
sam_grove 0:9dd7c6129683 783 if(offset) while (offset <= lastIndex) {
sam_grove 0:9dd7c6129683 784 if (d->objdict[offset].bSubCount <= 3) {
sam_grove 0:9dd7c6129683 785 MSG_ERR(0x1A63, "Subindex 3 not found at index ", 0x1280 + j);
sam_grove 0:9dd7c6129683 786 return 0xFF;
sam_grove 0:9dd7c6129683 787 }
sam_grove 0:9dd7c6129683 788 /* a) Looking for the cobid received. */
sam_grove 0:9dd7c6129683 789 pCobId = (UNS32*) d->objdict[offset].pSubindex[2].pObject;
sam_grove 0:9dd7c6129683 790 if (*pCobId == UNS16_LE(m->cob_id) ) {
sam_grove 0:9dd7c6129683 791 /* b) cobid found, so reading the node id of the server. */
sam_grove 0:9dd7c6129683 792 pNodeId = (UNS8*) d->objdict[offset].pSubindex[3].pObject;
sam_grove 0:9dd7c6129683 793 whoami = SDO_CLIENT;
sam_grove 0:9dd7c6129683 794 nodeId = *pNodeId;
sam_grove 0:9dd7c6129683 795 MSG_WAR(0x3A64, "proceedSDO. I am server. index : ", 0x1280 + j);
sam_grove 0:9dd7c6129683 796 MSG_WAR(0x3A65, " Server nodeId : ", nodeId);
sam_grove 0:9dd7c6129683 797 break;
sam_grove 0:9dd7c6129683 798 }
sam_grove 0:9dd7c6129683 799 j++;
sam_grove 0:9dd7c6129683 800 offset++;
sam_grove 0:9dd7c6129683 801 } /* end while */
sam_grove 0:9dd7c6129683 802 }
sam_grove 0:9dd7c6129683 803 if (whoami == SDO_UNKNOWN) {
sam_grove 0:9dd7c6129683 804 return 0xFF;/* This SDO was not for us ! */
sam_grove 0:9dd7c6129683 805 }
sam_grove 0:9dd7c6129683 806
sam_grove 0:9dd7c6129683 807 /* Test if the size of the SDO is ok */
sam_grove 0:9dd7c6129683 808 if ( (*m).len != 8) {
sam_grove 0:9dd7c6129683 809 MSG_ERR(0x1A67, "Error size SDO. CobId : ", UNS16_LE(m->cob_id));
sam_grove 0:9dd7c6129683 810 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_GENERAL_ERROR);
sam_grove 0:9dd7c6129683 811 return 0xFF;
sam_grove 0:9dd7c6129683 812 }
sam_grove 0:9dd7c6129683 813
sam_grove 0:9dd7c6129683 814 if (whoami == SDO_CLIENT) {
sam_grove 0:9dd7c6129683 815 MSG_WAR(0x3A68, "I am CLIENT. Received SDO from nodeId : ", nodeId);
sam_grove 0:9dd7c6129683 816 }
sam_grove 0:9dd7c6129683 817 else {
sam_grove 0:9dd7c6129683 818 MSG_WAR(0x3A69, "I am SERVER. Received SDO cobId : ", UNS16_LE(m->cob_id));
sam_grove 0:9dd7c6129683 819 }
sam_grove 0:9dd7c6129683 820
sam_grove 0:9dd7c6129683 821 /* Testing the command specifier */
sam_grove 0:9dd7c6129683 822 /* Allowed : cs = 0, 1, 2, 3, 4. (= all except those for block tranfert). */
sam_grove 0:9dd7c6129683 823 /* cs = other : Not allowed -> abort. */
sam_grove 0:9dd7c6129683 824 switch (getSDOcs(m->data[0])) {
sam_grove 0:9dd7c6129683 825
sam_grove 0:9dd7c6129683 826 case 0:
sam_grove 0:9dd7c6129683 827 /* I am SERVER */
sam_grove 0:9dd7c6129683 828 if (whoami == SDO_SERVER) {
sam_grove 0:9dd7c6129683 829 /* Receiving a download segment data. */
sam_grove 0:9dd7c6129683 830 /* A SDO transfert should have been yet initiated. */
sam_grove 0:9dd7c6129683 831 err = getSDOlineOnUse( d, nodeId, whoami, &line );
sam_grove 0:9dd7c6129683 832 if (!err)
sam_grove 0:9dd7c6129683 833 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
sam_grove 0:9dd7c6129683 834 if (err) {
sam_grove 0:9dd7c6129683 835 MSG_ERR(0x1A70, "SDO error : Received download segment for unstarted trans. index 0x1200 + ",
sam_grove 0:9dd7c6129683 836 nodeId);
sam_grove 0:9dd7c6129683 837 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
sam_grove 0:9dd7c6129683 838 return 0xFF;
sam_grove 0:9dd7c6129683 839 }
sam_grove 0:9dd7c6129683 840 /* Reset the wathdog */
sam_grove 0:9dd7c6129683 841 RestartSDO_TIMER(line)
sam_grove 0:9dd7c6129683 842 MSG_WAR(0x3A71, "Received SDO download segment defined at index 0x1200 + ", nodeId);
sam_grove 0:9dd7c6129683 843 index = d->transfers[line].index;
sam_grove 0:9dd7c6129683 844 subIndex = d->transfers[line].subIndex;
sam_grove 0:9dd7c6129683 845 /* Toggle test. */
sam_grove 0:9dd7c6129683 846 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
sam_grove 0:9dd7c6129683 847 MSG_ERR(0x1A72, "SDO error : Toggle error : ", getSDOt(m->data[0]));
sam_grove 0:9dd7c6129683 848 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
sam_grove 0:9dd7c6129683 849 return 0xFF;
sam_grove 0:9dd7c6129683 850 }
sam_grove 0:9dd7c6129683 851 /* Nb of data to be downloaded */
sam_grove 0:9dd7c6129683 852 nbBytes = 7 - getSDOn3(m->data[0]);
sam_grove 0:9dd7c6129683 853 /* Store the data in the transfert structure. */
sam_grove 0:9dd7c6129683 854 err = SDOtoLine(d, line, nbBytes, (*m).data + 1);
sam_grove 0:9dd7c6129683 855 if (err) {
sam_grove 0:9dd7c6129683 856 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
sam_grove 0:9dd7c6129683 857 return 0xFF;
sam_grove 0:9dd7c6129683 858 }
sam_grove 0:9dd7c6129683 859 /* Sending the SDO response, CS = 1 */
sam_grove 0:9dd7c6129683 860 sdo.nodeId = *d->bDeviceNodeId; /* The node id of the server, (here it is the sender). */
sam_grove 0:9dd7c6129683 861 sdo.body.data[0] = (1 << 5) | (d->transfers[line].toggle << 4);
sam_grove 0:9dd7c6129683 862 for (i = 1 ; i < 8 ; i++)
sam_grove 0:9dd7c6129683 863 sdo.body.data[i] = 0;
sam_grove 0:9dd7c6129683 864 MSG_WAR(0x3A73, "SDO. Send response to download request defined at index 0x1200 + ", nodeId);
sam_grove 0:9dd7c6129683 865 sendSDO(d, whoami, sdo);
sam_grove 0:9dd7c6129683 866 /* Inverting the toggle for the next segment. */
sam_grove 0:9dd7c6129683 867 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
sam_grove 0:9dd7c6129683 868 /* If it was the last segment, */
sam_grove 0:9dd7c6129683 869 if (getSDOc(m->data[0])) {
sam_grove 0:9dd7c6129683 870 /* Transfering line data to object dictionary. */
sam_grove 0:9dd7c6129683 871 /* The code does not use the "d" of initiate frame. So it is safe if e=s=0 */
sam_grove 0:9dd7c6129683 872 errorCode = SDOlineToObjdict(d, line);
sam_grove 0:9dd7c6129683 873 if (errorCode) {
sam_grove 0:9dd7c6129683 874 MSG_ERR(0x1A54, "SDO error : Unable to copy the data in the object dictionary", 0);
sam_grove 0:9dd7c6129683 875 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
sam_grove 0:9dd7c6129683 876 return 0xFF;
sam_grove 0:9dd7c6129683 877 }
sam_grove 0:9dd7c6129683 878 /* Release of the line */
sam_grove 0:9dd7c6129683 879 resetSDOline(d, line);
sam_grove 0:9dd7c6129683 880 MSG_WAR(0x3A74, "SDO. End of download defined at index 0x1200 + ", nodeId);
sam_grove 0:9dd7c6129683 881 }
sam_grove 0:9dd7c6129683 882 } /* end if SERVER */
sam_grove 0:9dd7c6129683 883 else { /* if CLIENT */
sam_grove 0:9dd7c6129683 884 /* I am CLIENT */
sam_grove 0:9dd7c6129683 885 /* It is a request for a previous upload segment. We should find a line opened for this.*/
sam_grove 0:9dd7c6129683 886 err = getSDOlineOnUse( d, nodeId, whoami, &line);
sam_grove 0:9dd7c6129683 887 if (!err)
sam_grove 0:9dd7c6129683 888 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
sam_grove 0:9dd7c6129683 889 if (err) {
sam_grove 0:9dd7c6129683 890 MSG_ERR(0x1A75, "SDO error : Received segment response for unknown trans. from nodeId", nodeId);
sam_grove 0:9dd7c6129683 891 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
sam_grove 0:9dd7c6129683 892 return 0xFF;
sam_grove 0:9dd7c6129683 893 }
sam_grove 0:9dd7c6129683 894 /* Reset the wathdog */
sam_grove 0:9dd7c6129683 895 RestartSDO_TIMER(line)
sam_grove 0:9dd7c6129683 896 index = d->transfers[line].index;
sam_grove 0:9dd7c6129683 897 subIndex = d->transfers[line].subIndex;
sam_grove 0:9dd7c6129683 898 /* test of the toggle; */
sam_grove 0:9dd7c6129683 899 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
sam_grove 0:9dd7c6129683 900 MSG_ERR(0x1A76, "SDO error : Received segment response Toggle error. from nodeId", nodeId);
sam_grove 0:9dd7c6129683 901 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
sam_grove 0:9dd7c6129683 902 return 0xFF;
sam_grove 0:9dd7c6129683 903 }
sam_grove 0:9dd7c6129683 904 /* nb of data to be uploaded */
sam_grove 0:9dd7c6129683 905 nbBytes = 7 - getSDOn3(m->data[0]);
sam_grove 0:9dd7c6129683 906 /* Storing the data in the line structure. */
sam_grove 0:9dd7c6129683 907 err = SDOtoLine(d, line, nbBytes, (*m).data + 1);
sam_grove 0:9dd7c6129683 908 if (err) {
sam_grove 0:9dd7c6129683 909 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
sam_grove 0:9dd7c6129683 910 return 0xFF;
sam_grove 0:9dd7c6129683 911 }
sam_grove 0:9dd7c6129683 912 /* Inverting the toggle for the next segment. */
sam_grove 0:9dd7c6129683 913 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
sam_grove 0:9dd7c6129683 914 /* If it was the last segment,*/
sam_grove 0:9dd7c6129683 915 if ( getSDOc(m->data[0])) {
sam_grove 0:9dd7c6129683 916 /* Put in state finished */
sam_grove 0:9dd7c6129683 917 /* The code is safe for the case e=s=0 in initiate frame. */
sam_grove 0:9dd7c6129683 918 StopSDO_TIMER(line)
sam_grove 0:9dd7c6129683 919 d->transfers[line].state = SDO_FINISHED;
sam_grove 0:9dd7c6129683 920 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
sam_grove 0:9dd7c6129683 921
sam_grove 0:9dd7c6129683 922 MSG_WAR(0x3A77, "SDO. End of upload from node : ", nodeId);
sam_grove 0:9dd7c6129683 923 }
sam_grove 0:9dd7c6129683 924 else { /* more segments to receive */
sam_grove 0:9dd7c6129683 925 /* Sending the request for the next segment. */
sam_grove 0:9dd7c6129683 926 sdo.nodeId = nodeId;
sam_grove 0:9dd7c6129683 927 sdo.body.data[0] = (3 << 5) | (d->transfers[line].toggle << 4);
sam_grove 0:9dd7c6129683 928 for (i = 1 ; i < 8 ; i++)
sam_grove 0:9dd7c6129683 929 sdo.body.data[i] = 0;
sam_grove 0:9dd7c6129683 930 sendSDO(d, whoami, sdo);
sam_grove 0:9dd7c6129683 931 MSG_WAR(0x3A78, "SDO send upload segment request to nodeId", nodeId);
sam_grove 0:9dd7c6129683 932 }
sam_grove 0:9dd7c6129683 933 } /* End if CLIENT */
sam_grove 0:9dd7c6129683 934 break;
sam_grove 0:9dd7c6129683 935
sam_grove 0:9dd7c6129683 936 case 1:
sam_grove 0:9dd7c6129683 937 /* I am SERVER */
sam_grove 0:9dd7c6129683 938 /* Receive of an initiate download */
sam_grove 0:9dd7c6129683 939 if (whoami == SDO_SERVER) {
sam_grove 0:9dd7c6129683 940 index = getSDOindex(m->data[1],m->data[2]);
sam_grove 0:9dd7c6129683 941 subIndex = getSDOsubIndex(m->data[3]);
sam_grove 0:9dd7c6129683 942 MSG_WAR(0x3A79, "Received SDO Initiate Download (to store data) defined at index 0x1200 + ",
sam_grove 0:9dd7c6129683 943 nodeId);
sam_grove 0:9dd7c6129683 944 MSG_WAR(0x3A80, "Writing at index : ", index);
sam_grove 0:9dd7c6129683 945 MSG_WAR(0x3A80, "Writing at subIndex : ", subIndex);
sam_grove 0:9dd7c6129683 946
sam_grove 0:9dd7c6129683 947 /* Search if a SDO transfert have been yet initiated */
sam_grove 0:9dd7c6129683 948 err = getSDOlineOnUse( d, nodeId, whoami, &line );
sam_grove 0:9dd7c6129683 949 if (! err) {
sam_grove 0:9dd7c6129683 950 MSG_ERR(0x1A81, "SDO error : Transmission yet started.", 0);
sam_grove 0:9dd7c6129683 951 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
sam_grove 0:9dd7c6129683 952 return 0xFF;
sam_grove 0:9dd7c6129683 953 }
sam_grove 0:9dd7c6129683 954 /* No line on use. Great ! */
sam_grove 0:9dd7c6129683 955 /* Try to open a new line. */
sam_grove 0:9dd7c6129683 956 err = getSDOfreeLine( d, whoami, &line );
sam_grove 0:9dd7c6129683 957 if (err) {
sam_grove 0:9dd7c6129683 958 MSG_ERR(0x1A82, "SDO error : No line free, too many SDO in progress. Aborted.", 0);
sam_grove 0:9dd7c6129683 959 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
sam_grove 0:9dd7c6129683 960 return 0xFF;
sam_grove 0:9dd7c6129683 961 }
sam_grove 0:9dd7c6129683 962 initSDOline(d, line, nodeId, index, subIndex, SDO_DOWNLOAD_IN_PROGRESS);
sam_grove 0:9dd7c6129683 963
sam_grove 0:9dd7c6129683 964 if (getSDOe(m->data[0])) { /* If SDO expedited */
sam_grove 0:9dd7c6129683 965 /* nb of data to be downloaded */
sam_grove 0:9dd7c6129683 966 nbBytes = 4 - getSDOn2(m->data[0]);
sam_grove 0:9dd7c6129683 967 /* Storing the data in the line structure. */
sam_grove 0:9dd7c6129683 968 d->transfers[line].count = nbBytes;
sam_grove 0:9dd7c6129683 969 err = SDOtoLine(d, line, nbBytes, (*m).data + 4);
sam_grove 0:9dd7c6129683 970
sam_grove 0:9dd7c6129683 971 if (err) {
sam_grove 0:9dd7c6129683 972 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
sam_grove 0:9dd7c6129683 973 return 0xFF;
sam_grove 0:9dd7c6129683 974 }
sam_grove 0:9dd7c6129683 975
sam_grove 0:9dd7c6129683 976 /* SDO expedited -> transfert finished. Data can be stored in the dictionary. */
sam_grove 0:9dd7c6129683 977 /*The line will be reseted when it is downloading in the dictionary. */
sam_grove 0:9dd7c6129683 978 MSG_WAR(0x3A83, "SDO Initiate Download is an expedited transfert. Finished.: ", nodeId);
sam_grove 0:9dd7c6129683 979 /* Transfering line data to object dictionary. */
sam_grove 0:9dd7c6129683 980 errorCode = SDOlineToObjdict(d, line);
sam_grove 0:9dd7c6129683 981 if (errorCode) {
sam_grove 0:9dd7c6129683 982 MSG_ERR(0x1A84, "SDO error : Unable to copy the data in the object dictionary", 0);
sam_grove 0:9dd7c6129683 983 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
sam_grove 0:9dd7c6129683 984 return 0xFF;
sam_grove 0:9dd7c6129683 985 }
sam_grove 0:9dd7c6129683 986 /* Release of the line. */
sam_grove 0:9dd7c6129683 987 resetSDOline(d, line);
sam_grove 0:9dd7c6129683 988 }
sam_grove 0:9dd7c6129683 989 else {/* So, if it is not an expedited transfert */
sam_grove 0:9dd7c6129683 990 if (getSDOs(m->data[0])) {
sam_grove 0:9dd7c6129683 991 nbBytes = (m->data[4]) + ((UNS32)(m->data[5])<<8) + ((UNS32)(m->data[6])<<16) + ((UNS32)(m->data[7])<<24);
sam_grove 0:9dd7c6129683 992 err = setSDOlineRestBytes(d, nodeId, nbBytes);
sam_grove 0:9dd7c6129683 993 if (err) {
sam_grove 0:9dd7c6129683 994 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
sam_grove 0:9dd7c6129683 995 return 0xFF;
sam_grove 0:9dd7c6129683 996 }
sam_grove 0:9dd7c6129683 997 }
sam_grove 0:9dd7c6129683 998 }
sam_grove 0:9dd7c6129683 999 /*Sending a SDO, cs=3*/
sam_grove 0:9dd7c6129683 1000 sdo.nodeId = *d->bDeviceNodeId; /* The node id of the server, (here it is the sender).*/
sam_grove 0:9dd7c6129683 1001 sdo.body.data[0] = 3 << 5;
sam_grove 0:9dd7c6129683 1002 sdo.body.data[1] = index & 0xFF; /* LSB */
sam_grove 0:9dd7c6129683 1003 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
sam_grove 0:9dd7c6129683 1004 sdo.body.data[3] = subIndex;
sam_grove 0:9dd7c6129683 1005 for (i = 4 ; i < 8 ; i++)
sam_grove 0:9dd7c6129683 1006 sdo.body.data[i] = 0;
sam_grove 0:9dd7c6129683 1007 sendSDO(d, whoami, sdo);
sam_grove 0:9dd7c6129683 1008 } /* end if I am SERVER */
sam_grove 0:9dd7c6129683 1009 else {
sam_grove 0:9dd7c6129683 1010 /* I am CLIENT */
sam_grove 0:9dd7c6129683 1011 /* It is a response for a previous download segment. We should find a line opened for this. */
sam_grove 0:9dd7c6129683 1012 err = getSDOlineOnUse( d, nodeId, whoami, &line);
sam_grove 0:9dd7c6129683 1013 if (!err)
sam_grove 0:9dd7c6129683 1014 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
sam_grove 0:9dd7c6129683 1015 if (err) {
sam_grove 0:9dd7c6129683 1016 MSG_ERR(0x1A85, "SDO error : Received segment response for unknown trans. from nodeId", nodeId);
sam_grove 0:9dd7c6129683 1017 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
sam_grove 0:9dd7c6129683 1018 return 0xFF;
sam_grove 0:9dd7c6129683 1019 }
sam_grove 0:9dd7c6129683 1020 /* Reset the wathdog */
sam_grove 0:9dd7c6129683 1021 RestartSDO_TIMER(line)
sam_grove 0:9dd7c6129683 1022 index = d->transfers[line].index;
sam_grove 0:9dd7c6129683 1023 subIndex = d->transfers[line].subIndex;
sam_grove 0:9dd7c6129683 1024 /* test of the toggle; */
sam_grove 0:9dd7c6129683 1025 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
sam_grove 0:9dd7c6129683 1026 MSG_ERR(0x1A86, "SDO error : Received segment response Toggle error. from nodeId", nodeId);
sam_grove 0:9dd7c6129683 1027 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
sam_grove 0:9dd7c6129683 1028 return 0xFF;
sam_grove 0:9dd7c6129683 1029 }
sam_grove 0:9dd7c6129683 1030
sam_grove 0:9dd7c6129683 1031 /* End transmission or downloading next segment. We need to know if it will be the last one. */
sam_grove 0:9dd7c6129683 1032 getSDOlineRestBytes(d, line, &nbBytes);
sam_grove 0:9dd7c6129683 1033 if (nbBytes == 0) {
sam_grove 0:9dd7c6129683 1034 MSG_WAR(0x3A87, "SDO End download. segment response received. OK. from nodeId", nodeId);
sam_grove 0:9dd7c6129683 1035 StopSDO_TIMER(line)
sam_grove 0:9dd7c6129683 1036 d->transfers[line].state = SDO_FINISHED;
sam_grove 0:9dd7c6129683 1037 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
sam_grove 0:9dd7c6129683 1038 return 0x00;
sam_grove 0:9dd7c6129683 1039 }
sam_grove 0:9dd7c6129683 1040 /* At least one transfer to send. */
sam_grove 0:9dd7c6129683 1041 if (nbBytes > 7) {
sam_grove 0:9dd7c6129683 1042 /* several segments to download.*/
sam_grove 0:9dd7c6129683 1043 /* code to send the next segment. (cs = 0; c = 0) */
sam_grove 0:9dd7c6129683 1044 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
sam_grove 0:9dd7c6129683 1045 sdo.nodeId = nodeId; /* The server node Id; */
sam_grove 0:9dd7c6129683 1046 sdo.body.data[0] = (d->transfers[line].toggle << 4);
sam_grove 0:9dd7c6129683 1047 err = lineToSDO(d, line, 7, sdo.body.data + 1);
sam_grove 0:9dd7c6129683 1048 if (err) {
sam_grove 0:9dd7c6129683 1049 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
sam_grove 0:9dd7c6129683 1050 return 0xFF;
sam_grove 0:9dd7c6129683 1051 }
sam_grove 0:9dd7c6129683 1052 }
sam_grove 0:9dd7c6129683 1053 else {
sam_grove 0:9dd7c6129683 1054 /* Last segment. */
sam_grove 0:9dd7c6129683 1055 /* code to send the last segment. (cs = 0; c = 1)*/
sam_grove 0:9dd7c6129683 1056 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
sam_grove 0:9dd7c6129683 1057 sdo.nodeId = nodeId; /* The server node Id; */
sam_grove 0:9dd7c6129683 1058 sdo.body.data[0] = (UNS8)((d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1);
sam_grove 0:9dd7c6129683 1059 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
sam_grove 0:9dd7c6129683 1060 if (err) {
sam_grove 0:9dd7c6129683 1061 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
sam_grove 0:9dd7c6129683 1062 return 0xFF;
sam_grove 0:9dd7c6129683 1063 }
sam_grove 0:9dd7c6129683 1064 for (i = nbBytes + 1 ; i < 8 ; i++)
sam_grove 0:9dd7c6129683 1065 sdo.body.data[i] = 0;
sam_grove 0:9dd7c6129683 1066 }
sam_grove 0:9dd7c6129683 1067 MSG_WAR(0x3A88, "SDO sending download segment to nodeId", nodeId);
sam_grove 0:9dd7c6129683 1068 sendSDO(d, whoami, sdo);
sam_grove 0:9dd7c6129683 1069 } /* end if I am a CLIENT */
sam_grove 0:9dd7c6129683 1070 break;
sam_grove 0:9dd7c6129683 1071
sam_grove 0:9dd7c6129683 1072 case 2:
sam_grove 0:9dd7c6129683 1073 /* I am SERVER */
sam_grove 0:9dd7c6129683 1074 /* Receive of an initiate upload.*/
sam_grove 0:9dd7c6129683 1075 if (whoami == SDO_SERVER) {
sam_grove 0:9dd7c6129683 1076 index = getSDOindex(m->data[1],m->data[2]);
sam_grove 0:9dd7c6129683 1077 subIndex = getSDOsubIndex(m->data[3]);
sam_grove 0:9dd7c6129683 1078 MSG_WAR(0x3A89, "Received SDO Initiate upload (to send data) defined at index 0x1200 + ",
sam_grove 0:9dd7c6129683 1079 nodeId);
sam_grove 0:9dd7c6129683 1080 MSG_WAR(0x3A90, "Reading at index : ", index);
sam_grove 0:9dd7c6129683 1081 MSG_WAR(0x3A91, "Reading at subIndex : ", subIndex);
sam_grove 0:9dd7c6129683 1082 /* Search if a SDO transfert have been yet initiated*/
sam_grove 0:9dd7c6129683 1083 err = getSDOlineOnUse( d, nodeId, whoami, &line );
sam_grove 0:9dd7c6129683 1084 if (! err) {
sam_grove 0:9dd7c6129683 1085 MSG_ERR(0x1A92, "SDO error : Transmission yet started at line : ", line);
sam_grove 0:9dd7c6129683 1086 MSG_WAR(0x3A93, "nodeId = ", nodeId);
sam_grove 0:9dd7c6129683 1087 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
sam_grove 0:9dd7c6129683 1088 return 0xFF;
sam_grove 0:9dd7c6129683 1089 }
sam_grove 0:9dd7c6129683 1090 /* No line on use. Great !*/
sam_grove 0:9dd7c6129683 1091 /* Try to open a new line.*/
sam_grove 0:9dd7c6129683 1092 err = getSDOfreeLine( d, whoami, &line );
sam_grove 0:9dd7c6129683 1093 if (err) {
sam_grove 0:9dd7c6129683 1094 MSG_ERR(0x1A71, "SDO error : No line free, too many SDO in progress. Aborted.", 0);
sam_grove 0:9dd7c6129683 1095 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
sam_grove 0:9dd7c6129683 1096 return 0xFF;
sam_grove 0:9dd7c6129683 1097 }
sam_grove 0:9dd7c6129683 1098 initSDOline(d, line, nodeId, index, subIndex, SDO_UPLOAD_IN_PROGRESS);
sam_grove 0:9dd7c6129683 1099 /* Transfer data from dictionary to the line structure. */
sam_grove 0:9dd7c6129683 1100 errorCode = objdictToSDOline(d, line);
sam_grove 0:9dd7c6129683 1101
sam_grove 0:9dd7c6129683 1102 if (errorCode) {
sam_grove 0:9dd7c6129683 1103 MSG_ERR(0x1A94, "SDO error : Unable to copy the data from object dictionary. Err code : ",
sam_grove 0:9dd7c6129683 1104 errorCode);
sam_grove 0:9dd7c6129683 1105 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
sam_grove 0:9dd7c6129683 1106 return 0xFF;
sam_grove 0:9dd7c6129683 1107 }
sam_grove 0:9dd7c6129683 1108 /* Preparing the response.*/
sam_grove 0:9dd7c6129683 1109 getSDOlineRestBytes(d, line, &nbBytes); /* Nb bytes to transfer ? */
sam_grove 0:9dd7c6129683 1110 sdo.nodeId = nodeId; /* The server node Id; */
sam_grove 0:9dd7c6129683 1111 if (nbBytes > 4) {
sam_grove 0:9dd7c6129683 1112 /* normal transfert. (segmented). */
sam_grove 0:9dd7c6129683 1113 /* code to send the initiate upload response. (cs = 2) */
sam_grove 0:9dd7c6129683 1114 sdo.body.data[0] = (2 << 5) | 1;
sam_grove 0:9dd7c6129683 1115 sdo.body.data[1] = index & 0xFF; /* LSB */
sam_grove 0:9dd7c6129683 1116 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
sam_grove 0:9dd7c6129683 1117 sdo.body.data[3] = subIndex;
sam_grove 0:9dd7c6129683 1118 sdo.body.data[4] = (UNS8)nbBytes; /* Limitation of canfestival2 : Max tranfert is 256 bytes.*/
sam_grove 0:9dd7c6129683 1119 /* It takes too much memory to upgrate to 2^32 because the size of data is also coded */
sam_grove 0:9dd7c6129683 1120 /* in the object dictionary, at every index and subindex. */
sam_grove 0:9dd7c6129683 1121 for (i = 5 ; i < 8 ; i++)
sam_grove 0:9dd7c6129683 1122 sdo.body.data[i] = 0;
sam_grove 0:9dd7c6129683 1123 MSG_WAR(0x3A95, "SDO. Sending normal upload initiate response defined at index 0x1200 + ", nodeId);
sam_grove 0:9dd7c6129683 1124 sendSDO(d, whoami, sdo);
sam_grove 0:9dd7c6129683 1125 }
sam_grove 0:9dd7c6129683 1126 else {
sam_grove 0:9dd7c6129683 1127 /* Expedited upload. (cs = 2 ; e = 1) */
sam_grove 0:9dd7c6129683 1128 sdo.body.data[0] = (UNS8)((2 << 5) | ((4 - nbBytes) << 2) | 3);
sam_grove 0:9dd7c6129683 1129 sdo.body.data[1] = index & 0xFF; /* LSB */
sam_grove 0:9dd7c6129683 1130 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
sam_grove 0:9dd7c6129683 1131 sdo.body.data[3] = subIndex;
sam_grove 0:9dd7c6129683 1132 err = lineToSDO(d, line, nbBytes, sdo.body.data + 4);
sam_grove 0:9dd7c6129683 1133 if (err) {
sam_grove 0:9dd7c6129683 1134 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
sam_grove 0:9dd7c6129683 1135 return 0xFF;
sam_grove 0:9dd7c6129683 1136 }
sam_grove 0:9dd7c6129683 1137 for (i = 4 + nbBytes ; i < 8 ; i++)
sam_grove 0:9dd7c6129683 1138 sdo.body.data[i] = 0;
sam_grove 0:9dd7c6129683 1139 MSG_WAR(0x3A96, "SDO. Sending expedited upload initiate response defined at index 0x1200 + ",
sam_grove 0:9dd7c6129683 1140 nodeId);
sam_grove 0:9dd7c6129683 1141 sendSDO(d, whoami, sdo);
sam_grove 0:9dd7c6129683 1142 /* Release the line.*/
sam_grove 0:9dd7c6129683 1143 resetSDOline(d, line);
sam_grove 0:9dd7c6129683 1144 }
sam_grove 0:9dd7c6129683 1145 } /* end if I am SERVER*/
sam_grove 0:9dd7c6129683 1146 else {
sam_grove 0:9dd7c6129683 1147 /* I am CLIENT */
sam_grove 0:9dd7c6129683 1148 /* It is the response for the previous initiate upload request.*/
sam_grove 0:9dd7c6129683 1149 /* We should find a line opened for this. */
sam_grove 0:9dd7c6129683 1150 err = getSDOlineOnUse( d, nodeId, whoami, &line);
sam_grove 0:9dd7c6129683 1151 if (!err)
sam_grove 0:9dd7c6129683 1152 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
sam_grove 0:9dd7c6129683 1153 if (err) {
sam_grove 0:9dd7c6129683 1154 MSG_ERR(0x1A97, "SDO error : Received response for unknown upload request from nodeId", nodeId);
sam_grove 0:9dd7c6129683 1155 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
sam_grove 0:9dd7c6129683 1156 return 0xFF;
sam_grove 0:9dd7c6129683 1157 }
sam_grove 0:9dd7c6129683 1158 /* Reset the wathdog */
sam_grove 0:9dd7c6129683 1159 RestartSDO_TIMER(line)
sam_grove 0:9dd7c6129683 1160 index = d->transfers[line].index;
sam_grove 0:9dd7c6129683 1161 subIndex = d->transfers[line].subIndex;
sam_grove 0:9dd7c6129683 1162
sam_grove 0:9dd7c6129683 1163 if (getSDOe(m->data[0])) { /* If SDO expedited */
sam_grove 0:9dd7c6129683 1164 /* nb of data to be uploaded */
sam_grove 0:9dd7c6129683 1165 nbBytes = 4 - getSDOn2(m->data[0]);
sam_grove 0:9dd7c6129683 1166 /* Storing the data in the line structure. */
sam_grove 0:9dd7c6129683 1167 err = SDOtoLine(d, line, nbBytes, (*m).data + 4);
sam_grove 0:9dd7c6129683 1168 if (err) {
sam_grove 0:9dd7c6129683 1169 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
sam_grove 0:9dd7c6129683 1170 return 0xFF;
sam_grove 0:9dd7c6129683 1171 }
sam_grove 0:9dd7c6129683 1172 /* SDO expedited -> transfert finished. data are available via getReadResultNetworkDict(). */
sam_grove 0:9dd7c6129683 1173 MSG_WAR(0x3A98, "SDO expedited upload finished. Response received from node : ", nodeId);
sam_grove 0:9dd7c6129683 1174 StopSDO_TIMER(line)
sam_grove 0:9dd7c6129683 1175 d->transfers[line].count = nbBytes;
sam_grove 0:9dd7c6129683 1176 d->transfers[line].state = SDO_FINISHED;
sam_grove 0:9dd7c6129683 1177 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
sam_grove 0:9dd7c6129683 1178 return 0;
sam_grove 0:9dd7c6129683 1179 }
sam_grove 0:9dd7c6129683 1180 else { /* So, if it is not an expedited transfert */
sam_grove 0:9dd7c6129683 1181 /* Storing the nb of data to receive. */
sam_grove 0:9dd7c6129683 1182 if (getSDOs(m->data[0])) {
sam_grove 0:9dd7c6129683 1183 nbBytes = m->data[4] + ((UNS32)(m->data[5])<<8) + ((UNS32)(m->data[6])<<16) + ((UNS32)(m->data[7])<<24);
sam_grove 0:9dd7c6129683 1184 err = setSDOlineRestBytes(d, line, nbBytes);
sam_grove 0:9dd7c6129683 1185 if (err) {
sam_grove 0:9dd7c6129683 1186 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
sam_grove 0:9dd7c6129683 1187 return 0xFF;
sam_grove 0:9dd7c6129683 1188 }
sam_grove 0:9dd7c6129683 1189 }
sam_grove 0:9dd7c6129683 1190 /* Requesting next segment. (cs = 3) */
sam_grove 0:9dd7c6129683 1191 sdo.nodeId = nodeId;
sam_grove 0:9dd7c6129683 1192 sdo.body.data[0] = 3 << 5;
sam_grove 0:9dd7c6129683 1193 for (i = 1 ; i < 8 ; i++)
sam_grove 0:9dd7c6129683 1194 sdo.body.data[i] = 0;
sam_grove 0:9dd7c6129683 1195 MSG_WAR(0x3A99, "SDO. Sending upload segment request to node : ", nodeId);
sam_grove 0:9dd7c6129683 1196 sendSDO(d, whoami, sdo);
sam_grove 0:9dd7c6129683 1197 }
sam_grove 0:9dd7c6129683 1198 } /* End if CLIENT */
sam_grove 0:9dd7c6129683 1199 break;
sam_grove 0:9dd7c6129683 1200
sam_grove 0:9dd7c6129683 1201 case 3:
sam_grove 0:9dd7c6129683 1202 /* I am SERVER */
sam_grove 0:9dd7c6129683 1203 if (whoami == SDO_SERVER) {
sam_grove 0:9dd7c6129683 1204 /* Receiving a upload segment. */
sam_grove 0:9dd7c6129683 1205 /* A SDO transfert should have been yet initiated. */
sam_grove 0:9dd7c6129683 1206 err = getSDOlineOnUse( d, nodeId, whoami, &line );
sam_grove 0:9dd7c6129683 1207 if (!err)
sam_grove 0:9dd7c6129683 1208 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
sam_grove 0:9dd7c6129683 1209 if (err) {
sam_grove 0:9dd7c6129683 1210 MSG_ERR(0x1AA0, "SDO error : Received upload segment for unstarted trans. index 0x1200 + ",
sam_grove 0:9dd7c6129683 1211 nodeId);
sam_grove 0:9dd7c6129683 1212 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
sam_grove 0:9dd7c6129683 1213 return 0xFF;
sam_grove 0:9dd7c6129683 1214 }
sam_grove 0:9dd7c6129683 1215 /* Reset the wathdog */
sam_grove 0:9dd7c6129683 1216 RestartSDO_TIMER(line)
sam_grove 0:9dd7c6129683 1217 MSG_WAR(0x3AA1, "Received SDO upload segment defined at index 0x1200 + ", nodeId);
sam_grove 0:9dd7c6129683 1218 index = d->transfers[line].index;
sam_grove 0:9dd7c6129683 1219 subIndex = d->transfers[line].subIndex;
sam_grove 0:9dd7c6129683 1220 /* Toggle test.*/
sam_grove 0:9dd7c6129683 1221 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
sam_grove 0:9dd7c6129683 1222 MSG_ERR(0x1AA2, "SDO error : Toggle error : ", getSDOt(m->data[0]));
sam_grove 0:9dd7c6129683 1223 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
sam_grove 0:9dd7c6129683 1224 return 0xFF;
sam_grove 0:9dd7c6129683 1225 }
sam_grove 0:9dd7c6129683 1226 /* Uploading next segment. We need to know if it will be the last one. */
sam_grove 0:9dd7c6129683 1227 getSDOlineRestBytes(d, line, &nbBytes);
sam_grove 0:9dd7c6129683 1228 if (nbBytes > 7) {
sam_grove 0:9dd7c6129683 1229 /* The segment to transfer is not the last one.*/
sam_grove 0:9dd7c6129683 1230 /* code to send the next segment. (cs = 0; c = 0) */
sam_grove 0:9dd7c6129683 1231 sdo.nodeId = nodeId; /* The server node Id; */
sam_grove 0:9dd7c6129683 1232 sdo.body.data[0] = (d->transfers[line].toggle << 4);
sam_grove 0:9dd7c6129683 1233 err = lineToSDO(d, line, 7, sdo.body.data + 1);
sam_grove 0:9dd7c6129683 1234 if (err) {
sam_grove 0:9dd7c6129683 1235 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
sam_grove 0:9dd7c6129683 1236 return 0xFF;
sam_grove 0:9dd7c6129683 1237 }
sam_grove 0:9dd7c6129683 1238 /* Inverting the toggle for the next tranfert. */
sam_grove 0:9dd7c6129683 1239 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
sam_grove 0:9dd7c6129683 1240 MSG_WAR(0x3AA3, "SDO. Sending upload segment defined at index 0x1200 + ", nodeId);
sam_grove 0:9dd7c6129683 1241 sendSDO(d, whoami, sdo);
sam_grove 0:9dd7c6129683 1242 }
sam_grove 0:9dd7c6129683 1243 else {
sam_grove 0:9dd7c6129683 1244 /* Last segment. */
sam_grove 0:9dd7c6129683 1245 /* code to send the last segment. (cs = 0; c = 1) */
sam_grove 0:9dd7c6129683 1246 sdo.nodeId = nodeId; /** The server node Id; */
sam_grove 0:9dd7c6129683 1247 sdo.body.data[0] = (UNS8)((d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1);
sam_grove 0:9dd7c6129683 1248 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
sam_grove 0:9dd7c6129683 1249 if (err) {
sam_grove 0:9dd7c6129683 1250 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
sam_grove 0:9dd7c6129683 1251 return 0xFF;
sam_grove 0:9dd7c6129683 1252 }
sam_grove 0:9dd7c6129683 1253 for (i = nbBytes + 1 ; i < 8 ; i++)
sam_grove 0:9dd7c6129683 1254 sdo.body.data[i] = 0;
sam_grove 0:9dd7c6129683 1255 MSG_WAR(0x3AA4, "SDO. Sending last upload segment defined at index 0x1200 + ", nodeId);
sam_grove 0:9dd7c6129683 1256 sendSDO(d, whoami, sdo);
sam_grove 0:9dd7c6129683 1257 /* Release the line */
sam_grove 0:9dd7c6129683 1258 resetSDOline(d, line);
sam_grove 0:9dd7c6129683 1259 }
sam_grove 0:9dd7c6129683 1260 } /* end if SERVER*/
sam_grove 0:9dd7c6129683 1261 else {
sam_grove 0:9dd7c6129683 1262 /* I am CLIENT */
sam_grove 0:9dd7c6129683 1263 /* It is the response for the previous initiate download request. */
sam_grove 0:9dd7c6129683 1264 /* We should find a line opened for this. */
sam_grove 0:9dd7c6129683 1265 err = getSDOlineOnUse( d, nodeId, whoami, &line);
sam_grove 0:9dd7c6129683 1266 if (!err)
sam_grove 0:9dd7c6129683 1267 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
sam_grove 0:9dd7c6129683 1268 if (err) {
sam_grove 0:9dd7c6129683 1269 MSG_ERR(0x1AA5, "SDO error : Received response for unknown download request from nodeId", nodeId);
sam_grove 0:9dd7c6129683 1270 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
sam_grove 0:9dd7c6129683 1271 return 0xFF;
sam_grove 0:9dd7c6129683 1272 }
sam_grove 0:9dd7c6129683 1273 /* Reset the watchdog */
sam_grove 0:9dd7c6129683 1274 RestartSDO_TIMER(line)
sam_grove 0:9dd7c6129683 1275 index = d->transfers[line].index;
sam_grove 0:9dd7c6129683 1276 subIndex = d->transfers[line].subIndex;
sam_grove 0:9dd7c6129683 1277 /* End transmission or requesting next segment. */
sam_grove 0:9dd7c6129683 1278 getSDOlineRestBytes(d, line, &nbBytes);
sam_grove 0:9dd7c6129683 1279 if (nbBytes == 0) {
sam_grove 0:9dd7c6129683 1280 MSG_WAR(0x3AA6, "SDO End download expedited. Response received. from nodeId", nodeId);
sam_grove 0:9dd7c6129683 1281 StopSDO_TIMER(line)
sam_grove 0:9dd7c6129683 1282 d->transfers[line].state = SDO_FINISHED;
sam_grove 0:9dd7c6129683 1283 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
sam_grove 0:9dd7c6129683 1284 return 0x00;
sam_grove 0:9dd7c6129683 1285 }
sam_grove 0:9dd7c6129683 1286 if (nbBytes > 7) {
sam_grove 0:9dd7c6129683 1287 /* more than one request to send */
sam_grove 0:9dd7c6129683 1288 /* code to send the next segment. (cs = 0; c = 0) */
sam_grove 0:9dd7c6129683 1289 sdo.nodeId = nodeId; /** The server node Id; */
sam_grove 0:9dd7c6129683 1290 sdo.body.data[0] = (d->transfers[line].toggle << 4);
sam_grove 0:9dd7c6129683 1291 err = lineToSDO(d, line, 7, sdo.body.data + 1);
sam_grove 0:9dd7c6129683 1292 if (err) {
sam_grove 0:9dd7c6129683 1293 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
sam_grove 0:9dd7c6129683 1294 return 0xFF;
sam_grove 0:9dd7c6129683 1295 }
sam_grove 0:9dd7c6129683 1296 }
sam_grove 0:9dd7c6129683 1297 else {
sam_grove 0:9dd7c6129683 1298 /* Last segment.*/
sam_grove 0:9dd7c6129683 1299 /* code to send the last segment. (cs = 0; c = 1) */
sam_grove 0:9dd7c6129683 1300 sdo.nodeId = nodeId; /* The server node Id; */
sam_grove 0:9dd7c6129683 1301 sdo.body.data[0] = (UNS8)((d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1);
sam_grove 0:9dd7c6129683 1302 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
sam_grove 0:9dd7c6129683 1303 if (err) {
sam_grove 0:9dd7c6129683 1304 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
sam_grove 0:9dd7c6129683 1305 return 0xFF;
sam_grove 0:9dd7c6129683 1306 }
sam_grove 0:9dd7c6129683 1307 for (i = nbBytes + 1 ; i < 8 ; i++)
sam_grove 0:9dd7c6129683 1308 sdo.body.data[i] = 0;
sam_grove 0:9dd7c6129683 1309 }
sam_grove 0:9dd7c6129683 1310 MSG_WAR(0x3AA7, "SDO sending download segment to nodeId", nodeId);
sam_grove 0:9dd7c6129683 1311 sendSDO(d, whoami, sdo);
sam_grove 0:9dd7c6129683 1312
sam_grove 0:9dd7c6129683 1313 } /* end if I am a CLIENT */
sam_grove 0:9dd7c6129683 1314 break;
sam_grove 0:9dd7c6129683 1315
sam_grove 0:9dd7c6129683 1316 case 4:
sam_grove 0:9dd7c6129683 1317 abortCode =
sam_grove 0:9dd7c6129683 1318 (UNS32)m->data[4] |
sam_grove 0:9dd7c6129683 1319 ((UNS32)m->data[5] << 8) |
sam_grove 0:9dd7c6129683 1320 ((UNS32)m->data[6] << 16) |
sam_grove 0:9dd7c6129683 1321 ((UNS32)m->data[7] << 24);
sam_grove 0:9dd7c6129683 1322 /* Received SDO abort. */
sam_grove 0:9dd7c6129683 1323 /* Looking for the line concerned. */
sam_grove 0:9dd7c6129683 1324 if (whoami == SDO_SERVER) {
sam_grove 0:9dd7c6129683 1325 err = getSDOlineOnUse( d, nodeId, whoami, &line );
sam_grove 0:9dd7c6129683 1326 if (!err) {
sam_grove 0:9dd7c6129683 1327 resetSDOline( d, line );
sam_grove 0:9dd7c6129683 1328 MSG_WAR(0x3AA8, "SD0. Received SDO abort. Line released. Code : ", abortCode);
sam_grove 0:9dd7c6129683 1329 }
sam_grove 0:9dd7c6129683 1330 else
sam_grove 0:9dd7c6129683 1331 MSG_WAR(0x3AA9, "SD0. Received SDO abort. No line found. Code : ", abortCode);
sam_grove 0:9dd7c6129683 1332 /* Tips : The end user has no way to know that the server node has received an abort SDO. */
sam_grove 0:9dd7c6129683 1333 /* Its is ok, I think.*/
sam_grove 0:9dd7c6129683 1334 }
sam_grove 0:9dd7c6129683 1335 else { /* If I am CLIENT */
sam_grove 0:9dd7c6129683 1336 err = getSDOlineOnUse( d, nodeId, whoami, &line );
sam_grove 0:9dd7c6129683 1337 if (!err) {
sam_grove 0:9dd7c6129683 1338 /* The line *must* be released by the core program. */
sam_grove 0:9dd7c6129683 1339 StopSDO_TIMER(line)
sam_grove 0:9dd7c6129683 1340 d->transfers[line].state = SDO_ABORTED_RCV;
sam_grove 0:9dd7c6129683 1341 d->transfers[line].abortCode = abortCode;
sam_grove 0:9dd7c6129683 1342 MSG_WAR(0x3AB0, "SD0. Received SDO abort. Line state ABORTED. Code : ", abortCode);
sam_grove 0:9dd7c6129683 1343 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
sam_grove 0:9dd7c6129683 1344 }
sam_grove 0:9dd7c6129683 1345 else
sam_grove 0:9dd7c6129683 1346 MSG_WAR(0x3AB1, "SD0. Received SDO abort. No line found. Code : ", abortCode);
sam_grove 0:9dd7c6129683 1347 }
sam_grove 0:9dd7c6129683 1348 break;
sam_grove 0:9dd7c6129683 1349 default:
sam_grove 0:9dd7c6129683 1350 /* Error : Unknown cs */
sam_grove 0:9dd7c6129683 1351 MSG_ERR(0x1AB2, "SDO. Received unknown command specifier : ", getSDOcs(m->data[0]));
sam_grove 0:9dd7c6129683 1352 return 0xFF;
sam_grove 0:9dd7c6129683 1353
sam_grove 0:9dd7c6129683 1354 } /* End switch */
sam_grove 0:9dd7c6129683 1355 return 0;
sam_grove 0:9dd7c6129683 1356 }
sam_grove 0:9dd7c6129683 1357
sam_grove 0:9dd7c6129683 1358 /*!
sam_grove 0:9dd7c6129683 1359 **
sam_grove 0:9dd7c6129683 1360 **
sam_grove 0:9dd7c6129683 1361 ** @param d
sam_grove 0:9dd7c6129683 1362 ** @param nodeId
sam_grove 0:9dd7c6129683 1363 ** @param index
sam_grove 0:9dd7c6129683 1364 ** @param subIndex
sam_grove 0:9dd7c6129683 1365 ** @param count
sam_grove 0:9dd7c6129683 1366 ** @param dataType
sam_grove 0:9dd7c6129683 1367 ** @param data
sam_grove 0:9dd7c6129683 1368 ** @param Callback
sam_grove 0:9dd7c6129683 1369 ** @param endianize
sam_grove 0:9dd7c6129683 1370 **
sam_grove 0:9dd7c6129683 1371 ** @return
sam_grove 0:9dd7c6129683 1372 **/
sam_grove 0:9dd7c6129683 1373 INLINE UNS8 _writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
sam_grove 0:9dd7c6129683 1374 UNS8 subIndex, UNS32 count, UNS8 dataType, void *data, SDOCallback_t Callback, UNS8 endianize)
sam_grove 0:9dd7c6129683 1375 {
sam_grove 0:9dd7c6129683 1376 UNS8 err;
sam_grove 0:9dd7c6129683 1377 UNS8 SDOfound = 0;
sam_grove 0:9dd7c6129683 1378 UNS8 line;
sam_grove 0:9dd7c6129683 1379 s_SDO sdo; /* SDO to transmit */
sam_grove 0:9dd7c6129683 1380 UNS8 i;
sam_grove 0:9dd7c6129683 1381 UNS32 j;
sam_grove 0:9dd7c6129683 1382 UNS16 lastIndex;
sam_grove 0:9dd7c6129683 1383 UNS16 offset;
sam_grove 0:9dd7c6129683 1384 UNS8 *pNodeIdServer;
sam_grove 0:9dd7c6129683 1385 UNS8 nodeIdServer;
sam_grove 0:9dd7c6129683 1386
sam_grove 0:9dd7c6129683 1387 MSG_WAR(0x3AC0, "Send SDO to write in the dictionary of node : ", nodeId);
sam_grove 0:9dd7c6129683 1388 MSG_WAR(0x3AC1, " At index : ", index);
sam_grove 0:9dd7c6129683 1389 MSG_WAR(0x3AC2, " subIndex : ", subIndex);
sam_grove 0:9dd7c6129683 1390 MSG_WAR(0x3AC3, " nb bytes : ", count);
sam_grove 0:9dd7c6129683 1391
sam_grove 0:9dd7c6129683 1392 /* Verify that there is no SDO communication yet. */
sam_grove 0:9dd7c6129683 1393 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
sam_grove 0:9dd7c6129683 1394 if (!err) {
sam_grove 0:9dd7c6129683 1395 MSG_ERR(0x1AC4, "SDO error : Communication yet established. with node : ", nodeId);
sam_grove 0:9dd7c6129683 1396 return 0xFF;
sam_grove 0:9dd7c6129683 1397 }
sam_grove 0:9dd7c6129683 1398 /* Taking the line ... */
sam_grove 0:9dd7c6129683 1399 err = getSDOfreeLine( d, SDO_CLIENT, &line );
sam_grove 0:9dd7c6129683 1400 if (err) {
sam_grove 0:9dd7c6129683 1401 MSG_ERR(0x1AC5, "SDO error : No line free, too many SDO in progress. Aborted for node : ", nodeId);
sam_grove 0:9dd7c6129683 1402 return (0xFF);
sam_grove 0:9dd7c6129683 1403 }
sam_grove 0:9dd7c6129683 1404 /* Check which SDO to use to communicate with the node */
sam_grove 0:9dd7c6129683 1405 offset = d->firstIndex->SDO_CLT;
sam_grove 0:9dd7c6129683 1406 lastIndex = d->lastIndex->SDO_CLT;
sam_grove 0:9dd7c6129683 1407 if (offset == 0) {
sam_grove 0:9dd7c6129683 1408 MSG_ERR(0x1AC6, "writeNetworkDict : No SDO client index found", 0);
sam_grove 0:9dd7c6129683 1409 return 0xFF;
sam_grove 0:9dd7c6129683 1410 }
sam_grove 0:9dd7c6129683 1411 i = 0;
sam_grove 0:9dd7c6129683 1412 while (offset <= lastIndex) {
sam_grove 0:9dd7c6129683 1413 if (d->objdict[offset].bSubCount <= 3) {
sam_grove 0:9dd7c6129683 1414 MSG_ERR(0x1AC8, "Subindex 3 not found at index ", 0x1280 + i);
sam_grove 0:9dd7c6129683 1415 return 0xFF;
sam_grove 0:9dd7c6129683 1416 }
sam_grove 0:9dd7c6129683 1417 /* looking for the nodeId server */
sam_grove 0:9dd7c6129683 1418 pNodeIdServer = (UNS8*) d->objdict[offset].pSubindex[3].pObject;
sam_grove 0:9dd7c6129683 1419 nodeIdServer = *pNodeIdServer;
sam_grove 0:9dd7c6129683 1420 MSG_WAR(0x1AD2, "index : ", 0x1280 + i);
sam_grove 0:9dd7c6129683 1421 MSG_WAR(0x1AD3, "nodeIdServer : ", nodeIdServer);
sam_grove 0:9dd7c6129683 1422
sam_grove 0:9dd7c6129683 1423 if(nodeIdServer == nodeId) {
sam_grove 0:9dd7c6129683 1424 SDOfound = 1;
sam_grove 0:9dd7c6129683 1425 break;
sam_grove 0:9dd7c6129683 1426 }
sam_grove 0:9dd7c6129683 1427 offset++;
sam_grove 0:9dd7c6129683 1428 i++;
sam_grove 0:9dd7c6129683 1429 } /* end while */
sam_grove 0:9dd7c6129683 1430 if (!SDOfound) {
sam_grove 0:9dd7c6129683 1431 MSG_ERR(0x1AC9, "SDO. Error. No client found to communicate with node : ", nodeId);
sam_grove 0:9dd7c6129683 1432 return 0xFE;
sam_grove 0:9dd7c6129683 1433 }
sam_grove 0:9dd7c6129683 1434 MSG_WAR(0x3AD0," SDO client defined at index : ", 0x1280 + i);
sam_grove 0:9dd7c6129683 1435 initSDOline(d, line, nodeId, index, subIndex, SDO_DOWNLOAD_IN_PROGRESS);
sam_grove 0:9dd7c6129683 1436 d->transfers[line].count = count;
sam_grove 0:9dd7c6129683 1437 d->transfers[line].dataType = dataType;
sam_grove 0:9dd7c6129683 1438
sam_grove 0:9dd7c6129683 1439 #ifdef SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 1440 {
sam_grove 0:9dd7c6129683 1441 UNS8* lineData = d->transfers[line].data;
sam_grove 0:9dd7c6129683 1442 if (count > SDO_MAX_LENGTH_TRANSFERT)
sam_grove 0:9dd7c6129683 1443 {
sam_grove 0:9dd7c6129683 1444 d->transfers[line].dynamicData = (UNS8*) malloc(count);
sam_grove 0:9dd7c6129683 1445 d->transfers[line].dynamicDataSize = count;
sam_grove 0:9dd7c6129683 1446 if (d->transfers[line].dynamicData == NULL)
sam_grove 0:9dd7c6129683 1447 {
sam_grove 0:9dd7c6129683 1448 MSG_ERR(0x1AC9, "SDO. Error. Could not allocate enough bytes : ", count);
sam_grove 0:9dd7c6129683 1449 return 0xFE;
sam_grove 0:9dd7c6129683 1450 }
sam_grove 0:9dd7c6129683 1451 lineData = d->transfers[line].dynamicData;
sam_grove 0:9dd7c6129683 1452 }
sam_grove 0:9dd7c6129683 1453 #endif //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 1454
sam_grove 0:9dd7c6129683 1455 /* Copy data to transfers structure. */
sam_grove 0:9dd7c6129683 1456 for (j = 0 ; j < count ; j++) {
sam_grove 0:9dd7c6129683 1457 #ifdef SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 1458 # ifdef CANOPEN_BIG_ENDIAN
sam_grove 0:9dd7c6129683 1459 if (dataType == 0 && endianize)
sam_grove 0:9dd7c6129683 1460 lineData[count - 1 - j] = ((char *)data)[j];
sam_grove 0:9dd7c6129683 1461 else /* String of bytes. */
sam_grove 0:9dd7c6129683 1462 lineData[j] = ((char *)data)[j];
sam_grove 0:9dd7c6129683 1463 # else
sam_grove 0:9dd7c6129683 1464 lineData[j] = ((char *)data)[j];
sam_grove 0:9dd7c6129683 1465 # endif
sam_grove 0:9dd7c6129683 1466 }
sam_grove 0:9dd7c6129683 1467 #else //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 1468 # ifdef CANOPEN_BIG_ENDIAN
sam_grove 0:9dd7c6129683 1469 if (dataType == 0 && endianize)
sam_grove 0:9dd7c6129683 1470 d->transfers[line].data[count - 1 - j] = ((char *)data)[j];
sam_grove 0:9dd7c6129683 1471 else /* String of bytes. */
sam_grove 0:9dd7c6129683 1472 d->transfers[line].data[j] = ((char *)data)[j];
sam_grove 0:9dd7c6129683 1473 # else
sam_grove 0:9dd7c6129683 1474 d->transfers[line].data[j] = ((char *)data)[j];
sam_grove 0:9dd7c6129683 1475 # endif
sam_grove 0:9dd7c6129683 1476 #endif //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 1477 }
sam_grove 0:9dd7c6129683 1478 /* Send the SDO to the server. Initiate download, cs=1. */
sam_grove 0:9dd7c6129683 1479 sdo.nodeId = nodeId;
sam_grove 0:9dd7c6129683 1480 if (count <= 4) { /* Expedited transfert */
sam_grove 0:9dd7c6129683 1481 sdo.body.data[0] = (UNS8)((1 << 5) | ((4 - count) << 2) | 3);
sam_grove 0:9dd7c6129683 1482 for (i = 4 ; i < 8 ; i++)
sam_grove 0:9dd7c6129683 1483 sdo.body.data[i] = d->transfers[line].data[i - 4];
sam_grove 0:9dd7c6129683 1484 d->transfers[line].offset = count;
sam_grove 0:9dd7c6129683 1485 }
sam_grove 0:9dd7c6129683 1486 else { /** Normal transfert */
sam_grove 0:9dd7c6129683 1487 sdo.body.data[0] = (1 << 5) | 1;
sam_grove 0:9dd7c6129683 1488 for (i = 0 ; i < 4 ; i++)
sam_grove 0:9dd7c6129683 1489 sdo.body.data[i+4] = (UNS8)((count >> (i<<3))); /* i*8 */
sam_grove 0:9dd7c6129683 1490 }
sam_grove 0:9dd7c6129683 1491 sdo.body.data[1] = index & 0xFF; /* LSB */
sam_grove 0:9dd7c6129683 1492 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
sam_grove 0:9dd7c6129683 1493 sdo.body.data[3] = subIndex;
sam_grove 0:9dd7c6129683 1494
sam_grove 0:9dd7c6129683 1495 d->transfers[line].Callback = Callback;
sam_grove 0:9dd7c6129683 1496
sam_grove 0:9dd7c6129683 1497 err = sendSDO(d, SDO_CLIENT, sdo);
sam_grove 0:9dd7c6129683 1498 if (err) {
sam_grove 0:9dd7c6129683 1499 MSG_ERR(0x1AD1, "SDO. Error while sending SDO to node : ", nodeId);
sam_grove 0:9dd7c6129683 1500 /* release the line */
sam_grove 0:9dd7c6129683 1501 resetSDOline(d, line);
sam_grove 0:9dd7c6129683 1502 return 0xFF;
sam_grove 0:9dd7c6129683 1503 }
sam_grove 0:9dd7c6129683 1504
sam_grove 0:9dd7c6129683 1505
sam_grove 0:9dd7c6129683 1506 return 0;
sam_grove 0:9dd7c6129683 1507 }
sam_grove 0:9dd7c6129683 1508
sam_grove 0:9dd7c6129683 1509 /*!
sam_grove 0:9dd7c6129683 1510 **
sam_grove 0:9dd7c6129683 1511 **
sam_grove 0:9dd7c6129683 1512 ** @param d
sam_grove 0:9dd7c6129683 1513 ** @param nodeId
sam_grove 0:9dd7c6129683 1514 ** @param index
sam_grove 0:9dd7c6129683 1515 ** @param subIndex
sam_grove 0:9dd7c6129683 1516 ** @param count
sam_grove 0:9dd7c6129683 1517 ** @param dataType
sam_grove 0:9dd7c6129683 1518 ** @param data
sam_grove 0:9dd7c6129683 1519 **
sam_grove 0:9dd7c6129683 1520 ** @return
sam_grove 0:9dd7c6129683 1521 **/
sam_grove 0:9dd7c6129683 1522 UNS8 writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
sam_grove 0:9dd7c6129683 1523 UNS8 subIndex, UNS32 count, UNS8 dataType, void *data)
sam_grove 0:9dd7c6129683 1524 {
sam_grove 0:9dd7c6129683 1525 return _writeNetworkDict (d, nodeId, index, subIndex, count, dataType, data, NULL, 1);
sam_grove 0:9dd7c6129683 1526 }
sam_grove 0:9dd7c6129683 1527
sam_grove 0:9dd7c6129683 1528 /*!
sam_grove 0:9dd7c6129683 1529 **
sam_grove 0:9dd7c6129683 1530 **
sam_grove 0:9dd7c6129683 1531 ** @param d
sam_grove 0:9dd7c6129683 1532 ** @param nodeId
sam_grove 0:9dd7c6129683 1533 ** @param index
sam_grove 0:9dd7c6129683 1534 ** @param subIndex
sam_grove 0:9dd7c6129683 1535 ** @param count
sam_grove 0:9dd7c6129683 1536 ** @param dataType
sam_grove 0:9dd7c6129683 1537 ** @param data
sam_grove 0:9dd7c6129683 1538 ** @param Callback
sam_grove 0:9dd7c6129683 1539 **
sam_grove 0:9dd7c6129683 1540 ** @return
sam_grove 0:9dd7c6129683 1541 **/
sam_grove 0:9dd7c6129683 1542 UNS8 writeNetworkDictCallBack (CO_Data* d, UNS8 nodeId, UNS16 index,
sam_grove 0:9dd7c6129683 1543 UNS8 subIndex, UNS32 count, UNS8 dataType, void *data, SDOCallback_t Callback)
sam_grove 0:9dd7c6129683 1544 {
sam_grove 0:9dd7c6129683 1545 return _writeNetworkDict (d, nodeId, index, subIndex, count, dataType, data, Callback, 1);
sam_grove 0:9dd7c6129683 1546 }
sam_grove 0:9dd7c6129683 1547
sam_grove 0:9dd7c6129683 1548 UNS8 writeNetworkDictCallBackAI (CO_Data* d, UNS8 nodeId, UNS16 index,
sam_grove 0:9dd7c6129683 1549 UNS8 subIndex, UNS32 count, UNS8 dataType, void *data, SDOCallback_t Callback, UNS8 endianize)
sam_grove 0:9dd7c6129683 1550 {
sam_grove 0:9dd7c6129683 1551 UNS8 ret;
sam_grove 0:9dd7c6129683 1552 UNS16 lastIndex;
sam_grove 0:9dd7c6129683 1553 UNS16 offset;
sam_grove 0:9dd7c6129683 1554 UNS8 nodeIdServer;
sam_grove 0:9dd7c6129683 1555 UNS8 i;
sam_grove 0:9dd7c6129683 1556
sam_grove 0:9dd7c6129683 1557 ret = _writeNetworkDict (d, nodeId, index, subIndex, count, dataType, data, Callback, endianize);
sam_grove 0:9dd7c6129683 1558 if(ret == 0xFE)
sam_grove 0:9dd7c6129683 1559 {
sam_grove 0:9dd7c6129683 1560 offset = d->firstIndex->SDO_CLT;
sam_grove 0:9dd7c6129683 1561 lastIndex = d->lastIndex->SDO_CLT;
sam_grove 0:9dd7c6129683 1562 if (offset == 0)
sam_grove 0:9dd7c6129683 1563 {
sam_grove 0:9dd7c6129683 1564 MSG_ERR(0x1AC6, "writeNetworkDict : No SDO client index found", 0);
sam_grove 0:9dd7c6129683 1565 return 0xFF;
sam_grove 0:9dd7c6129683 1566 }
sam_grove 0:9dd7c6129683 1567 i = 0;
sam_grove 0:9dd7c6129683 1568 while (offset <= lastIndex)
sam_grove 0:9dd7c6129683 1569 {
sam_grove 0:9dd7c6129683 1570 if (d->objdict[offset].bSubCount <= 3)
sam_grove 0:9dd7c6129683 1571 {
sam_grove 0:9dd7c6129683 1572 MSG_ERR(0x1AC8, "Subindex 3 not found at index ", 0x1280 + i);
sam_grove 0:9dd7c6129683 1573 return 0xFF;
sam_grove 0:9dd7c6129683 1574 }
sam_grove 0:9dd7c6129683 1575 nodeIdServer = *(UNS8*) d->objdict[offset].pSubindex[3].pObject;
sam_grove 0:9dd7c6129683 1576 if(nodeIdServer == 0)
sam_grove 0:9dd7c6129683 1577 {
sam_grove 0:9dd7c6129683 1578 *(UNS32*)d->objdict[offset].pSubindex[1].pObject = (UNS32)(0x600 + nodeId);
sam_grove 0:9dd7c6129683 1579 *(UNS32*)d->objdict[offset].pSubindex[2].pObject = (UNS32)(0x580 + nodeId);
sam_grove 0:9dd7c6129683 1580 *(UNS8*) d->objdict[offset].pSubindex[3].pObject = nodeId;
sam_grove 0:9dd7c6129683 1581 return _writeNetworkDict (d, nodeId, index, subIndex, count, dataType, data, Callback, 1);
sam_grove 0:9dd7c6129683 1582 }
sam_grove 0:9dd7c6129683 1583 offset++;
sam_grove 0:9dd7c6129683 1584 }
sam_grove 0:9dd7c6129683 1585 return 0xFF;
sam_grove 0:9dd7c6129683 1586 }
sam_grove 0:9dd7c6129683 1587 else if(ret == 0)
sam_grove 0:9dd7c6129683 1588 {
sam_grove 0:9dd7c6129683 1589 return 0;
sam_grove 0:9dd7c6129683 1590 }
sam_grove 0:9dd7c6129683 1591 else
sam_grove 0:9dd7c6129683 1592 {
sam_grove 0:9dd7c6129683 1593 return 0xFF;
sam_grove 0:9dd7c6129683 1594 }
sam_grove 0:9dd7c6129683 1595 }
sam_grove 0:9dd7c6129683 1596
sam_grove 0:9dd7c6129683 1597 /*!
sam_grove 0:9dd7c6129683 1598 **
sam_grove 0:9dd7c6129683 1599 **
sam_grove 0:9dd7c6129683 1600 ** @param d
sam_grove 0:9dd7c6129683 1601 ** @param nodeId
sam_grove 0:9dd7c6129683 1602 ** @param index
sam_grove 0:9dd7c6129683 1603 ** @param subIndex
sam_grove 0:9dd7c6129683 1604 ** @param dataType
sam_grove 0:9dd7c6129683 1605 ** @param Callback
sam_grove 0:9dd7c6129683 1606 **
sam_grove 0:9dd7c6129683 1607 ** @return
sam_grove 0:9dd7c6129683 1608 **/
sam_grove 0:9dd7c6129683 1609 INLINE UNS8 _readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback)
sam_grove 0:9dd7c6129683 1610 {
sam_grove 0:9dd7c6129683 1611 UNS8 err;
sam_grove 0:9dd7c6129683 1612 UNS8 SDOfound = 0;
sam_grove 0:9dd7c6129683 1613 UNS8 i;
sam_grove 0:9dd7c6129683 1614 UNS8 line;
sam_grove 0:9dd7c6129683 1615 s_SDO sdo; /* SDO to transmit */
sam_grove 0:9dd7c6129683 1616 UNS8 *pNodeIdServer;
sam_grove 0:9dd7c6129683 1617 UNS8 nodeIdServer;
sam_grove 0:9dd7c6129683 1618 UNS16 offset;
sam_grove 0:9dd7c6129683 1619 UNS16 lastIndex;
sam_grove 0:9dd7c6129683 1620 MSG_WAR(0x3AD5, "Send SDO to read in the dictionary of node : ", nodeId);
sam_grove 0:9dd7c6129683 1621 MSG_WAR(0x3AD6, " At index : ", index);
sam_grove 0:9dd7c6129683 1622 MSG_WAR(0x3AD7, " subIndex : ", subIndex);
sam_grove 0:9dd7c6129683 1623
sam_grove 0:9dd7c6129683 1624
sam_grove 0:9dd7c6129683 1625 /* Verify that there is no SDO communication yet. */
sam_grove 0:9dd7c6129683 1626 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
sam_grove 0:9dd7c6129683 1627 if (!err) {
sam_grove 0:9dd7c6129683 1628 MSG_ERR(0x1AD8, "SDO error : Communication yet established. with node : ", nodeId);
sam_grove 0:9dd7c6129683 1629 return 0xFF;
sam_grove 0:9dd7c6129683 1630 }
sam_grove 0:9dd7c6129683 1631 /* Taking the line ... */
sam_grove 0:9dd7c6129683 1632 err = getSDOfreeLine( d, SDO_CLIENT, &line );
sam_grove 0:9dd7c6129683 1633 if (err) {
sam_grove 0:9dd7c6129683 1634 MSG_ERR(0x1AD9, "SDO error : No line free, too many SDO in progress. Aborted for node : ", nodeId);
sam_grove 0:9dd7c6129683 1635 return (0xFF);
sam_grove 0:9dd7c6129683 1636 }
sam_grove 0:9dd7c6129683 1637 else
sam_grove 0:9dd7c6129683 1638 MSG_WAR(0x3AE0, "Transmission on line : ", line);
sam_grove 0:9dd7c6129683 1639
sam_grove 0:9dd7c6129683 1640 /* Check which SDO to use to communicate with the node */
sam_grove 0:9dd7c6129683 1641 offset = d->firstIndex->SDO_CLT;
sam_grove 0:9dd7c6129683 1642 lastIndex = d->lastIndex->SDO_CLT;
sam_grove 0:9dd7c6129683 1643 if (offset == 0) {
sam_grove 0:9dd7c6129683 1644 MSG_ERR(0x1AE1, "writeNetworkDict : No SDO client index found", 0);
sam_grove 0:9dd7c6129683 1645 return 0xFF;
sam_grove 0:9dd7c6129683 1646 }
sam_grove 0:9dd7c6129683 1647 i = 0;
sam_grove 0:9dd7c6129683 1648 while (offset <= lastIndex) {
sam_grove 0:9dd7c6129683 1649 if (d->objdict[offset].bSubCount <= 3) {
sam_grove 0:9dd7c6129683 1650 MSG_ERR(0x1AE2, "Subindex 3 not found at index ", 0x1280 + i);
sam_grove 0:9dd7c6129683 1651 return 0xFF;
sam_grove 0:9dd7c6129683 1652 }
sam_grove 0:9dd7c6129683 1653 /* looking for the nodeId server */
sam_grove 0:9dd7c6129683 1654 pNodeIdServer = (UNS8*) d->objdict[offset].pSubindex[3].pObject;
sam_grove 0:9dd7c6129683 1655 nodeIdServer = *pNodeIdServer;
sam_grove 0:9dd7c6129683 1656
sam_grove 0:9dd7c6129683 1657 if(nodeIdServer == nodeId) {
sam_grove 0:9dd7c6129683 1658 SDOfound = 1;
sam_grove 0:9dd7c6129683 1659 break;
sam_grove 0:9dd7c6129683 1660 }
sam_grove 0:9dd7c6129683 1661 offset++;
sam_grove 0:9dd7c6129683 1662 i++;
sam_grove 0:9dd7c6129683 1663 } /* end while */
sam_grove 0:9dd7c6129683 1664 if (!SDOfound) {
sam_grove 0:9dd7c6129683 1665 MSG_ERR(0x1AE3, "SDO. Error. No client found to communicate with node : ", nodeId);
sam_grove 0:9dd7c6129683 1666 return 0xFE;
sam_grove 0:9dd7c6129683 1667 }
sam_grove 0:9dd7c6129683 1668 MSG_WAR(0x3AE4," SDO client defined at index : ", 0x1280 + i);
sam_grove 0:9dd7c6129683 1669 initSDOline(d, line, nodeId, index, subIndex, SDO_UPLOAD_IN_PROGRESS);
sam_grove 0:9dd7c6129683 1670 getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
sam_grove 0:9dd7c6129683 1671 sdo.nodeId = nodeId;
sam_grove 0:9dd7c6129683 1672 /* Send the SDO to the server. Initiate upload, cs=2. */
sam_grove 0:9dd7c6129683 1673 d->transfers[line].dataType = dataType;
sam_grove 0:9dd7c6129683 1674 sdo.body.data[0] = (2 << 5);
sam_grove 0:9dd7c6129683 1675 sdo.body.data[1] = index & 0xFF; /* LSB */
sam_grove 0:9dd7c6129683 1676 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
sam_grove 0:9dd7c6129683 1677 sdo.body.data[3] = subIndex;
sam_grove 0:9dd7c6129683 1678 for (i = 4 ; i < 8 ; i++)
sam_grove 0:9dd7c6129683 1679 sdo.body.data[i] = 0;
sam_grove 0:9dd7c6129683 1680 d->transfers[line].Callback = Callback;
sam_grove 0:9dd7c6129683 1681 err = sendSDO(d, SDO_CLIENT, sdo);
sam_grove 0:9dd7c6129683 1682 if (err) {
sam_grove 0:9dd7c6129683 1683 MSG_ERR(0x1AE5, "SDO. Error while sending SDO to node : ", nodeId);
sam_grove 0:9dd7c6129683 1684 /* release the line */
sam_grove 0:9dd7c6129683 1685 resetSDOline(d, line);
sam_grove 0:9dd7c6129683 1686 return 0xFF;
sam_grove 0:9dd7c6129683 1687 }
sam_grove 0:9dd7c6129683 1688 return 0;
sam_grove 0:9dd7c6129683 1689 }
sam_grove 0:9dd7c6129683 1690
sam_grove 0:9dd7c6129683 1691 /*!
sam_grove 0:9dd7c6129683 1692 **
sam_grove 0:9dd7c6129683 1693 **
sam_grove 0:9dd7c6129683 1694 ** @param d
sam_grove 0:9dd7c6129683 1695 ** @param nodeId
sam_grove 0:9dd7c6129683 1696 ** @param index
sam_grove 0:9dd7c6129683 1697 ** @param subIndex
sam_grove 0:9dd7c6129683 1698 ** @param dataType
sam_grove 0:9dd7c6129683 1699 **
sam_grove 0:9dd7c6129683 1700 ** @return
sam_grove 0:9dd7c6129683 1701 **/
sam_grove 0:9dd7c6129683 1702 UNS8 readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType)
sam_grove 0:9dd7c6129683 1703 {
sam_grove 0:9dd7c6129683 1704 return _readNetworkDict (d, nodeId, index, subIndex, dataType, NULL);
sam_grove 0:9dd7c6129683 1705 }
sam_grove 0:9dd7c6129683 1706
sam_grove 0:9dd7c6129683 1707 /*!
sam_grove 0:9dd7c6129683 1708 **
sam_grove 0:9dd7c6129683 1709 **
sam_grove 0:9dd7c6129683 1710 ** @param d
sam_grove 0:9dd7c6129683 1711 ** @param nodeId
sam_grove 0:9dd7c6129683 1712 ** @param index
sam_grove 0:9dd7c6129683 1713 ** @param subIndex
sam_grove 0:9dd7c6129683 1714 ** @param dataType
sam_grove 0:9dd7c6129683 1715 ** @param Callback
sam_grove 0:9dd7c6129683 1716 **
sam_grove 0:9dd7c6129683 1717 ** @return
sam_grove 0:9dd7c6129683 1718 **/
sam_grove 0:9dd7c6129683 1719 UNS8 readNetworkDictCallback (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback)
sam_grove 0:9dd7c6129683 1720 {
sam_grove 0:9dd7c6129683 1721 return _readNetworkDict (d, nodeId, index, subIndex, dataType, Callback);
sam_grove 0:9dd7c6129683 1722 }
sam_grove 0:9dd7c6129683 1723
sam_grove 0:9dd7c6129683 1724 UNS8 readNetworkDictCallbackAI (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback)
sam_grove 0:9dd7c6129683 1725 {
sam_grove 0:9dd7c6129683 1726 UNS8 ret;
sam_grove 0:9dd7c6129683 1727 UNS16 lastIndex;
sam_grove 0:9dd7c6129683 1728 UNS16 offset;
sam_grove 0:9dd7c6129683 1729 UNS8 nodeIdServer;
sam_grove 0:9dd7c6129683 1730 UNS8 i;
sam_grove 0:9dd7c6129683 1731
sam_grove 0:9dd7c6129683 1732 ret = _readNetworkDict (d, nodeId, index, subIndex, dataType, Callback);
sam_grove 0:9dd7c6129683 1733 if(ret == 0xFE)
sam_grove 0:9dd7c6129683 1734 {
sam_grove 0:9dd7c6129683 1735 offset = d->firstIndex->SDO_CLT;
sam_grove 0:9dd7c6129683 1736 lastIndex = d->lastIndex->SDO_CLT;
sam_grove 0:9dd7c6129683 1737 if (offset == 0)
sam_grove 0:9dd7c6129683 1738 {
sam_grove 0:9dd7c6129683 1739 MSG_ERR(0x1AC6, "writeNetworkDict : No SDO client index found", 0);
sam_grove 0:9dd7c6129683 1740 return 0xFF;
sam_grove 0:9dd7c6129683 1741 }
sam_grove 0:9dd7c6129683 1742 i = 0;
sam_grove 0:9dd7c6129683 1743 while (offset <= lastIndex)
sam_grove 0:9dd7c6129683 1744 {
sam_grove 0:9dd7c6129683 1745 if (d->objdict[offset].bSubCount <= 3)
sam_grove 0:9dd7c6129683 1746 {
sam_grove 0:9dd7c6129683 1747 MSG_ERR(0x1AC8, "Subindex 3 not found at index ", 0x1280 + i);
sam_grove 0:9dd7c6129683 1748 return 0xFF;
sam_grove 0:9dd7c6129683 1749 }
sam_grove 0:9dd7c6129683 1750 nodeIdServer = *(UNS8*) d->objdict[offset].pSubindex[3].pObject;
sam_grove 0:9dd7c6129683 1751 if(nodeIdServer == 0)
sam_grove 0:9dd7c6129683 1752 {
sam_grove 0:9dd7c6129683 1753 *(UNS32*)d->objdict[offset].pSubindex[1].pObject = (UNS32)(0x600 + nodeId);
sam_grove 0:9dd7c6129683 1754 *(UNS32*)d->objdict[offset].pSubindex[2].pObject = (UNS32)(0x580 + nodeId);
sam_grove 0:9dd7c6129683 1755 *(UNS8*) d->objdict[offset].pSubindex[3].pObject = nodeId;
sam_grove 0:9dd7c6129683 1756 return _readNetworkDict (d, nodeId, index, subIndex, dataType, Callback);
sam_grove 0:9dd7c6129683 1757 }
sam_grove 0:9dd7c6129683 1758 offset++;
sam_grove 0:9dd7c6129683 1759 }
sam_grove 0:9dd7c6129683 1760 return 0xFF;
sam_grove 0:9dd7c6129683 1761 }
sam_grove 0:9dd7c6129683 1762 else if(ret == 0)
sam_grove 0:9dd7c6129683 1763 {
sam_grove 0:9dd7c6129683 1764 return 0;
sam_grove 0:9dd7c6129683 1765 }
sam_grove 0:9dd7c6129683 1766 else
sam_grove 0:9dd7c6129683 1767 {
sam_grove 0:9dd7c6129683 1768 return 0xFF;
sam_grove 0:9dd7c6129683 1769 }
sam_grove 0:9dd7c6129683 1770 }
sam_grove 0:9dd7c6129683 1771
sam_grove 0:9dd7c6129683 1772 /*!
sam_grove 0:9dd7c6129683 1773 **
sam_grove 0:9dd7c6129683 1774 **
sam_grove 0:9dd7c6129683 1775 ** @param d
sam_grove 0:9dd7c6129683 1776 ** @param nodeId
sam_grove 0:9dd7c6129683 1777 ** @param data
sam_grove 0:9dd7c6129683 1778 ** @param size pointer to expected size, changed into returned size. Expected size will be truncated to transfered data size
sam_grove 0:9dd7c6129683 1779 ** @param abortCode
sam_grove 0:9dd7c6129683 1780 **
sam_grove 0:9dd7c6129683 1781 ** @return
sam_grove 0:9dd7c6129683 1782 **/
sam_grove 0:9dd7c6129683 1783 UNS8 getReadResultNetworkDict (CO_Data* d, UNS8 nodeId, void* data, UNS32 *size,
sam_grove 0:9dd7c6129683 1784 UNS32 * abortCode)
sam_grove 0:9dd7c6129683 1785 {
sam_grove 0:9dd7c6129683 1786 UNS32 i;
sam_grove 0:9dd7c6129683 1787 UNS8 err;
sam_grove 0:9dd7c6129683 1788 UNS8 line;
sam_grove 0:9dd7c6129683 1789 * abortCode = 0;
sam_grove 0:9dd7c6129683 1790
sam_grove 0:9dd7c6129683 1791 /* Looking for the line tranfert. */
sam_grove 0:9dd7c6129683 1792 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
sam_grove 0:9dd7c6129683 1793 if (err) {
sam_grove 0:9dd7c6129683 1794 MSG_ERR(0x1AF0, "SDO error : No line found for communication with node : ", nodeId);
sam_grove 0:9dd7c6129683 1795 return SDO_ABORTED_INTERNAL;
sam_grove 0:9dd7c6129683 1796 }
sam_grove 0:9dd7c6129683 1797 * abortCode = d->transfers[line].abortCode;
sam_grove 0:9dd7c6129683 1798 if (d->transfers[line].state != SDO_FINISHED)
sam_grove 0:9dd7c6129683 1799 return d->transfers[line].state;
sam_grove 0:9dd7c6129683 1800
sam_grove 0:9dd7c6129683 1801 /* if SDO initiated with e=0 and s=0 count is null, offset carry effective size*/
sam_grove 0:9dd7c6129683 1802 if( d->transfers[line].count == 0)
sam_grove 0:9dd7c6129683 1803 d->transfers[line].count = d->transfers[line].offset;
sam_grove 0:9dd7c6129683 1804 /* use transfers[line].count as max size */
sam_grove 0:9dd7c6129683 1805 if( d->transfers[line].count < *size )
sam_grove 0:9dd7c6129683 1806 *size = d->transfers[line].count;
sam_grove 0:9dd7c6129683 1807
sam_grove 0:9dd7c6129683 1808 /* Copy payload to data pointer */
sam_grove 0:9dd7c6129683 1809 #ifdef SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 1810 {
sam_grove 0:9dd7c6129683 1811 UNS8 *lineData = d->transfers[line].data;
sam_grove 0:9dd7c6129683 1812
sam_grove 0:9dd7c6129683 1813 if (d->transfers[line].dynamicData && d->transfers[line].dynamicDataSize)
sam_grove 0:9dd7c6129683 1814 {
sam_grove 0:9dd7c6129683 1815 lineData = d->transfers[line].dynamicData;
sam_grove 0:9dd7c6129683 1816 }
sam_grove 0:9dd7c6129683 1817 for ( i = 0 ; i < *size ; i++) {
sam_grove 0:9dd7c6129683 1818 # ifdef CANOPEN_BIG_ENDIAN
sam_grove 0:9dd7c6129683 1819 if (d->transfers[line].dataType != visible_string)
sam_grove 0:9dd7c6129683 1820 ( (char *) data)[*size - 1 - i] = lineData[i];
sam_grove 0:9dd7c6129683 1821 else /* String of bytes. */
sam_grove 0:9dd7c6129683 1822 ( (char *) data)[i] = lineData[i];
sam_grove 0:9dd7c6129683 1823 # else
sam_grove 0:9dd7c6129683 1824 ( (char *) data)[i] = lineData[i];
sam_grove 0:9dd7c6129683 1825 # endif
sam_grove 0:9dd7c6129683 1826 }
sam_grove 0:9dd7c6129683 1827 }
sam_grove 0:9dd7c6129683 1828 #else //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 1829 for ( i = 0 ; i < *size ; i++) {
sam_grove 0:9dd7c6129683 1830 # ifdef CANOPEN_BIG_ENDIAN
sam_grove 0:9dd7c6129683 1831 if (d->transfers[line].dataType != visible_string)
sam_grove 0:9dd7c6129683 1832 ( (char *) data)[*size - 1 - i] = d->transfers[line].data[i];
sam_grove 0:9dd7c6129683 1833 else /* String of bytes. */
sam_grove 0:9dd7c6129683 1834 ( (char *) data)[i] = d->transfers[line].data[i];
sam_grove 0:9dd7c6129683 1835 # else
sam_grove 0:9dd7c6129683 1836 ( (char *) data)[i] = d->transfers[line].data[i];
sam_grove 0:9dd7c6129683 1837 # endif
sam_grove 0:9dd7c6129683 1838 }
sam_grove 0:9dd7c6129683 1839 #endif //SDO_DYNAMIC_BUFFER_ALLOCATION
sam_grove 0:9dd7c6129683 1840 return SDO_FINISHED;
sam_grove 0:9dd7c6129683 1841 }
sam_grove 0:9dd7c6129683 1842
sam_grove 0:9dd7c6129683 1843 /*!
sam_grove 0:9dd7c6129683 1844 **
sam_grove 0:9dd7c6129683 1845 **
sam_grove 0:9dd7c6129683 1846 ** @param d
sam_grove 0:9dd7c6129683 1847 ** @param nodeId
sam_grove 0:9dd7c6129683 1848 ** @param abortCode
sam_grove 0:9dd7c6129683 1849 **
sam_grove 0:9dd7c6129683 1850 ** @return
sam_grove 0:9dd7c6129683 1851 **/
sam_grove 0:9dd7c6129683 1852 UNS8 getWriteResultNetworkDict (CO_Data* d, UNS8 nodeId, UNS32 * abortCode)
sam_grove 0:9dd7c6129683 1853 {
sam_grove 0:9dd7c6129683 1854 UNS8 line = 0;
sam_grove 0:9dd7c6129683 1855 UNS8 err;
sam_grove 0:9dd7c6129683 1856
sam_grove 0:9dd7c6129683 1857 * abortCode = 0;
sam_grove 0:9dd7c6129683 1858 /* Looking for the line tranfert. */
sam_grove 0:9dd7c6129683 1859 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
sam_grove 0:9dd7c6129683 1860 if (err) {
sam_grove 0:9dd7c6129683 1861 MSG_ERR(0x1AF1, "SDO error : No line found for communication with node : ", nodeId);
sam_grove 0:9dd7c6129683 1862 return SDO_ABORTED_INTERNAL;
sam_grove 0:9dd7c6129683 1863 }
sam_grove 0:9dd7c6129683 1864 * abortCode = d->transfers[line].abortCode;
sam_grove 0:9dd7c6129683 1865 return d->transfers[line].state;
sam_grove 0:9dd7c6129683 1866 }