Can_open_slavenode

Dependencies:   mbed

Committer:
sam_grove
Date:
Mon May 30 07:14:41 2011 +0000
Revision:
0:6219434a0cb5
Initial public release of slave node framework port

Who changed what in which revision?

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