2 This file is part of CanFestival, a library implementing CanOpen
5 Copyright (C): Edouard TISSERANT and Francis DUPIN
7 See COPYING file for copyrights details.
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26 ** @author Edouard TISSERANT and Francis DUPIN
27 ** @date Tue Jun 5 08:55:23 2007
37 /* #define DEBUG_WAR_CONSOLE_ON */
38 /* #define DEBUG_ERR_CONSOLE_ON */
49 ** @param sizeDataDict
50 ** @param sizeDataGiven
55 UNS8 accessDictionaryError(UNS16 index, UNS8 subIndex,
56 UNS8 sizeDataDict, UNS8 sizeDataGiven, UNS32 code)
58 #ifdef DEBUG_WAR_CONSOLE_ON
59 MSG_WAR(0x2B09,"Dictionary index : ", index);
60 MSG_WAR(0X2B10," subindex : ", subIndex);
62 case OD_NO_SUCH_OBJECT:
63 MSG_WAR(0x2B11,"Index not found ", index);
65 case OD_NO_SUCH_SUBINDEX :
66 MSG_WAR(0x2B12,"SubIndex not found ", subIndex);
68 case OD_WRITE_NOT_ALLOWED :
69 MSG_WAR(0x2B13,"Write not allowed, data is read only ", index);
71 case OD_LENGTH_DATA_INVALID :
72 MSG_WAR(0x2B14,"Conflict size data. Should be (bytes) : ", sizeDataDict);
73 MSG_WAR(0x2B15,"But you have given the size : ", sizeDataGiven);
75 case OD_NOT_MAPPABLE :
76 MSG_WAR(0x2B16,"Not mappable data in a PDO at index : ", index);
78 case OD_VALUE_TOO_LOW :
79 MSG_WAR(0x2B17,"Value range error : value too low. SDOabort : ", code);
81 case OD_VALUE_TOO_HIGH :
82 MSG_WAR(0x2B18,"Value range error : value too high. SDOabort : ", code);
85 MSG_WAR(0x2B20, "Unknown error code : ", code);
98 ** @param pExpectedSize
100 ** @param checkAccess
105 UNS32 _getODentry( CO_Data* d,
109 UNS8 * pExpectedSize,
113 { /* DO NOT USE MSG_ERR because the macro may send a PDO -> infinite
117 const indextable *ptrTable;
118 ODCallback_t *Callback;
120 ptrTable = (*d->scanIndexOD)(wIndex, &errorCode, &Callback);
122 if (errorCode != OD_SUCCESSFUL)
124 if( ptrTable->bSubCount <= bSubindex ) {
125 /* Subindex not found */
126 accessDictionaryError(wIndex, bSubindex, 0, 0, OD_NO_SUCH_SUBINDEX);
127 return OD_NO_SUCH_SUBINDEX;
130 if (checkAccess && !(ptrTable->pSubindex[bSubindex].bAccessType & WO)) {
131 MSG_WAR(0x2B30, "Access Type : ", ptrTable->pSubindex[bSubindex].bAccessType);
132 accessDictionaryError(wIndex, bSubindex, 0, 0, OD_WRITE_NOT_ALLOWED);
133 return OD_READ_NOT_ALLOWED;
136 *pDataType = ptrTable->pSubindex[bSubindex].bDataType;
137 szData = ptrTable->pSubindex[bSubindex].size;
139 if(*pExpectedSize == 0 ||
140 *pExpectedSize == szData ||
141 (*pDataType == visible_string && *pExpectedSize < szData)) {
143 allow to fetch a shorter string than expected */
145 # ifdef CANOPEN_BIG_ENDIAN
146 if(endianize && *pDataType > boolean && *pDataType < visible_string) {
147 /* data must be transmited with low byte first */
149 MSG_WAR(boolean, "data type ", *pDataType);
150 MSG_WAR(visible_string, "data type ", *pDataType);
151 for ( i = szData ; i > 0 ; i--) {
153 ((UNS8*)pDestData)[j++] =
154 ((UNS8*)ptrTable->pSubindex[bSubindex].pObject)[i-1];
157 else /* It it is a visible string no endianisation to perform */
158 memcpy(pDestData, ptrTable->pSubindex[bSubindex].pObject,szData);
160 memcpy(pDestData, ptrTable->pSubindex[bSubindex].pObject,szData);
163 *pExpectedSize = szData;
165 /* Me laisser a, please ! (FD) */
168 for (i = 0 ; i < 10 ; i++) {
169 MSG_WAR(*pExpectedSize, "dic data= ",
170 *(UNS8 *)(ptrTable->pSubindex[bSubindex].pObject + i));
175 return OD_SUCCESSFUL;
178 *pExpectedSize = szData;
179 accessDictionaryError(wIndex, bSubindex, szData,
180 *pExpectedSize, OD_LENGTH_DATA_INVALID);
181 return OD_LENGTH_DATA_INVALID;
192 ** @param pExpectedSize
194 ** @param checkAccess
198 UNS32 getODentry( CO_Data* d,
202 UNS8 * pExpectedSize,
206 return _getODentry( d,
223 ** @param pExpectedSize
225 ** @param checkAccess
229 UNS32 readLocalDict( CO_Data* d,
233 UNS8 * pExpectedSize,
237 return _getODentry( d,
244 0);//do not endianize
253 ** @param pSourceData
254 ** @param pExpectedSize
255 ** @param checkAccess
260 UNS32 _setODentry( CO_Data* d,
264 UNS8 * pExpectedSize,
271 const indextable *ptrTable;
272 ODCallback_t *Callback;
274 ptrTable =(*d->scanIndexOD)(wIndex, &errorCode, &Callback);
275 if (errorCode != OD_SUCCESSFUL)
278 if( ptrTable->bSubCount <= bSubindex ) {
279 /* Subindex not found */
280 accessDictionaryError(wIndex, bSubindex, 0, *pExpectedSize, OD_NO_SUCH_SUBINDEX);
281 return OD_NO_SUCH_SUBINDEX;
283 if (checkAccess && (ptrTable->pSubindex[bSubindex].bAccessType == RO)) {
284 MSG_WAR(0x2B25, "Access Type : ", ptrTable->pSubindex[bSubindex].bAccessType);
285 accessDictionaryError(wIndex, bSubindex, 0, *pExpectedSize, OD_WRITE_NOT_ALLOWED);
286 return OD_WRITE_NOT_ALLOWED;
290 dataType = ptrTable->pSubindex[bSubindex].bDataType;
291 szData = ptrTable->pSubindex[bSubindex].size;
293 if( *pExpectedSize == 0 ||
294 *pExpectedSize == szData ||
295 (dataType == visible_string && *pExpectedSize < szData)) /* We
296 allow to store a shorter string than entry size */
298 #ifdef CANOPEN_BIG_ENDIAN
299 if(endianize && dataType > boolean && dataType < visible_string)
301 /* we invert the data source directly. This let us do range
303 /* additional temp variable */
305 for ( i = 0 ; i < ( ptrTable->pSubindex[bSubindex].size >> 1) ; i++)
307 UNS8 tmp =((UNS8 *)pSourceData) [(ptrTable->pSubindex[bSubindex].size - 1) - i];
308 ((UNS8 *)pSourceData) [(ptrTable->pSubindex[bSubindex].size - 1) - i] = ((UNS8 *)pSourceData)[i];
309 ((UNS8 *)pSourceData)[i] = tmp;
313 errorCode = (*d->valueRangeTest)(dataType, pSourceData);
315 accessDictionaryError(wIndex, bSubindex, szData, *pExpectedSize, errorCode);
318 memcpy(ptrTable->pSubindex[bSubindex].pObject,pSourceData, *pExpectedSize);
319 *pExpectedSize = szData;
322 if(Callback && Callback[bSubindex]){
323 (*Callback[bSubindex])(d, ptrTable, bSubindex);
326 /* TODO : Store dans NVRAM */
327 if (ptrTable->pSubindex[bSubindex].bAccessType & TO_BE_SAVE){
328 (*d->storeODSubIndex)(wIndex, bSubindex);
330 return OD_SUCCESSFUL;
332 *pExpectedSize = szData;
333 accessDictionaryError(wIndex, bSubindex, szData, *pExpectedSize, OD_LENGTH_DATA_INVALID);
334 return OD_LENGTH_DATA_INVALID;
344 ** @param pSourceData
345 ** @param pExpectedSize
346 ** @param checkAccess
350 UNS32 setODentry( CO_Data* d,
354 UNS8 * pExpectedSize,
357 return _setODentry( d,
372 ** @param pSourceData
373 ** @param pExpectedSize
374 ** @param checkAccess
378 UNS32 writeLocalDict( CO_Data* d,
382 UNS8 * pExpectedSize,
385 return _setODentry( d,
391 0);//do not endianize
404 const indextable * scanIndexOD (CO_Data* d, UNS16 wIndex, UNS32 *errorCode, ODCallback_t **Callback)
406 return (*d->scanIndexOD)(wIndex, errorCode, Callback);
419 UNS32 RegisterSetODentryCallBack(CO_Data* d, UNS16 wIndex, UNS8 bSubindex, ODCallback_t Callback)
422 ODCallback_t *CallbackList;
424 scanIndexOD (d, wIndex, &errorCode, &CallbackList);
425 if(errorCode == OD_SUCCESSFUL && CallbackList)
426 CallbackList[bSubindex] = Callback;
436 void _storeODSubIndex (UNS16 wIndex, UNS8 bSubindex){}