2 This file is part of CanFestival, a library implementing CanOpen Stack.
4 Copyright (C): Edouard TISSERANT and Francis DUPIN
6 See COPYING file for copyrights details.
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 //#define DEBUG_WAR_CONSOLE_ON
24 //#define DEBUG_ERR_CONSOLE_ON
28 #ifdef DEBUG_WAR_CONSOLE_ON
29 UNS8 accessDictionaryError(UNS16 index, UNS8 subIndex,
30 UNS8 sizeDataDict, UNS8 sizeDataGiven, UNS32 code)
32 MSG_WAR(0x2B09,"Dictionary index : ", index);
33 MSG_WAR(0X2B10," subindex : ", subIndex);
35 case OD_NO_SUCH_OBJECT:
36 MSG_WAR(0x2B11,"Index not found ", index);
38 case OD_NO_SUCH_SUBINDEX :
39 MSG_WAR(0x2B12,"SubIndex not found ", subIndex);
41 case OD_WRITE_NOT_ALLOWED :
42 MSG_WAR(0x2B13,"Write not allowed, data is read only ", index);
44 case OD_LENGTH_DATA_INVALID :
45 MSG_WAR(0x2B14,"Conflict size data. Should be (bytes) : ", sizeDataDict);
46 MSG_WAR(0x2B15,"But you have given the size : ", sizeDataGiven);
48 case OD_NOT_MAPPABLE :
49 MSG_WAR(0x2B16,"Not mappable data in a PDO at index : ", index);
51 case OD_VALUE_TOO_LOW :
52 MSG_WAR(0x2B17,"Value range error : value too low. SDOabort : ", code);
54 case OD_VALUE_TOO_HIGH :
55 MSG_WAR(0x2B18,"Value range error : value too high. SDOabort : ", code);
58 MSG_WAR(0x2B20, "Unknown error code : ", code);
64 UNS32 getODentry( CO_Data* d,
71 { // DO NOT USE MSG_ERR because the macro may send a PDO -> infinite loop if it fails.
74 const indextable *ptrTable;
75 ODCallback_t *Callback;
77 ptrTable = (*d->scanIndexOD)(wIndex, &errorCode, &Callback);
79 if (errorCode != OD_SUCCESSFUL)
81 if( ptrTable->bSubCount <= bSubindex ) {
83 accessDictionaryError(wIndex, bSubindex, 0, 0, OD_NO_SUCH_SUBINDEX);
84 return OD_NO_SUCH_SUBINDEX;
87 if (checkAccess && !(ptrTable->pSubindex[bSubindex].bAccessType & WO)) {
88 MSG_WAR(0x2B30, "Access Type : ", ptrTable->pSubindex[bSubindex].bAccessType);
89 accessDictionaryError(wIndex, bSubindex, 0, 0, OD_WRITE_NOT_ALLOWED);
90 return OD_READ_NOT_ALLOWED;
93 *pDataType = ptrTable->pSubindex[bSubindex].bDataType;
94 szData = ptrTable->pSubindex[bSubindex].size;
96 if( *pExpectedSize == 0 ||
97 *pExpectedSize == szData ||
98 (*pDataType == visible_string && *pExpectedSize > szData)) // We allow to fetch a shorter string than expected
100 #ifdef CANOPEN_BIG_ENDIAN
102 // data must be transmited with low byte first
104 for ( i = ptrTable->pSubindex[bSubindex].size ; i > 0 ; i--) {
105 ((char*)pDestData)[j++] = ((char*)ptrTable->pSubindex[bSubindex].pObject)[i-1];
109 memcpy(pDestData, ptrTable->pSubindex[bSubindex].pObject,*pExpectedSize);
111 *pExpectedSize = szData;
112 return OD_SUCCESSFUL;
114 *pExpectedSize = szData;
115 accessDictionaryError(wIndex, bSubindex, szData, *pExpectedSize, OD_LENGTH_DATA_INVALID);
116 return OD_LENGTH_DATA_INVALID;
120 UNS32 setODentry( CO_Data* d,
124 UNS8 * pExpectedSize,
130 const indextable *ptrTable;
131 ODCallback_t *Callback;
133 ptrTable =(*d->scanIndexOD)(wIndex, &errorCode, &Callback);
134 if (errorCode != OD_SUCCESSFUL)
137 if( ptrTable->bSubCount <= bSubindex ) {
138 // Subindex not found
139 accessDictionaryError(wIndex, bSubindex, 0, *pExpectedSize, OD_NO_SUCH_SUBINDEX);
140 return OD_NO_SUCH_SUBINDEX;
142 if (checkAccess && (ptrTable->pSubindex[bSubindex].bAccessType == RO)) {
143 MSG_WAR(0x2B25, "Access Type : ", ptrTable->pSubindex[bSubindex].bAccessType);
144 accessDictionaryError(wIndex, bSubindex, 0, *pExpectedSize, OD_WRITE_NOT_ALLOWED);
145 return OD_WRITE_NOT_ALLOWED;
149 dataType = ptrTable->pSubindex[bSubindex].bDataType;
150 szData = ptrTable->pSubindex[bSubindex].size;
152 if( *pExpectedSize == 0 ||
153 *pExpectedSize == szData ||
154 (dataType == visible_string && *pExpectedSize < szData)) // We allow to store a shorter string than entry size
156 errorCode = (*d->valueRangeTest)(dataType, pSourceData);
158 accessDictionaryError(wIndex, bSubindex, szData, *pExpectedSize, errorCode);
161 #ifdef CANOPEN_BIG_ENDIAN
163 // data must be transmited with low byte first
165 for ( i = ptrTable->pSubindex[bSubindex].size ; i > 0 ; i--) {
166 ((char*)ptrTable->pSubindex[bSubindex].pObject)[i - 1] = ((char*)pSourceData)[j++];
170 memcpy(ptrTable->pSubindex[bSubindex].pObject,pSourceData, *pExpectedSize);
172 *pExpectedSize = szData;
175 if(Callback && Callback[bSubindex]){
176 (*Callback[bSubindex])(d, ptrTable, bSubindex);
179 // TODO : Store dans NVRAM
180 // if (ptrTable->pSubindex[bSubindex].bAccessType & TO_BE_SAVED)
181 return OD_SUCCESSFUL;
183 *pExpectedSize = szData;
184 accessDictionaryError(wIndex, bSubindex, szData, *pExpectedSize, OD_LENGTH_DATA_INVALID);
185 return OD_LENGTH_DATA_INVALID;
190 const indextable * scanIndexOD (CO_Data* d, UNS16 wIndex, UNS32 *errorCode, ODCallback_t **Callback)
192 return (*d->scanIndexOD)(wIndex, errorCode, Callback);
195 UNS32 RegisterSetODentryCallBack(CO_Data* d, UNS16 wIndex, UNS8 bSubindex, ODCallback_t Callback)
198 ODCallback_t *CallbackList;
200 scanIndexOD (d, wIndex, &errorCode, &CallbackList);
201 if(errorCode == OD_SUCCESSFUL && CallbackList)
202 CallbackList[bSubindex] = Callback;