Staging: epl: remove CONST
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / epl / EplObd.c
blobf449f4c30a7a6cded6c25158a5fc4e0d0cd3e744
1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
6 Project: openPOWERLINK
8 Description: source file for api function of EplOBD-Module
10 License:
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
14 are met:
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
23 3. Neither the name of SYSTEC electronic GmbH nor the names of its
24 contributors may be used to endorse or promote products derived
25 from this software without prior written permission. For written
26 permission, please contact info@systec-electronic.com.
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 POSSIBILITY OF SUCH DAMAGE.
41 Severability Clause:
43 If a provision of this License is or becomes illegal, invalid or
44 unenforceable in any jurisdiction, that shall not affect:
45 1. the validity or enforceability in that jurisdiction of any other
46 provision of this License; or
47 2. the validity or enforceability in other jurisdictions of that or
48 any other provision of this License.
50 -------------------------------------------------------------------------
52 $RCSfile: EplObd.c,v $
54 $Author: D.Krueger $
56 $Revision: 1.12 $ $Date: 2008/10/17 15:32:32 $
58 $State: Exp $
60 Build Environment:
61 Microsoft VC7
63 -------------------------------------------------------------------------
65 Revision History:
67 2006/06/02 k.t.: start of the implementation, version 1.00
68 ->based on CANopen OBD-Modul
70 ****************************************************************************/
72 #include "EplInc.h"
73 #include "kernel/EplObdk.h" // function prototyps of the EplOBD-Modul
75 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
77 /***************************************************************************/
78 /* */
79 /* */
80 /* G L O B A L D E F I N I T I O N S */
81 /* */
82 /* */
83 /***************************************************************************/
85 //---------------------------------------------------------------------------
86 // const defines
87 //---------------------------------------------------------------------------
89 // float definitions and macros
90 #define _SHIFTED_EXPONENT_MASK_SP 0xff
91 #define _BIAS_SP 126
92 #define T_SP 23
93 #define EXPONENT_DENORM_SP (-_BIAS_SP)
94 #define BASE_TO_THE_T_SP ((float) 8388608.0)
95 #define GET_EXPONENT_SP(x) ((((x) >> T_SP) & _SHIFTED_EXPONENT_MASK_SP) - _BIAS_SP)
97 //---------------------------------------------------------------------------
98 // local types
99 //---------------------------------------------------------------------------
101 // struct for instance table
102 INSTANCE_TYPE_BEGIN EPL_MCO_DECL_INSTANCE_MEMBER()
104 STATIC tEplObdInitParam m_ObdInitParam;
105 STATIC tEplObdStoreLoadObjCallback m_fpStoreLoadObjCallback;
107 INSTANCE_TYPE_END
108 // decomposition of float
109 typedef union {
110 tEplObdReal32 m_flRealPart;
111 int m_nIntegerPart;
113 } tEplObdRealParts;
115 //---------------------------------------------------------------------------
116 // modul globale vars
117 //---------------------------------------------------------------------------
119 // This macro replace the unspecific pointer to an instance through
120 // the modul specific type for the local instance table. This macro
121 // must defined in each modul.
122 //#define tEplPtrInstance tEplInstanceInfo *
124 EPL_MCO_DECL_INSTANCE_VAR()
126 BYTE abEplObdTrashObject_g[8];
128 //---------------------------------------------------------------------------
129 // local function prototypes
130 //---------------------------------------------------------------------------
132 EPL_MCO_DEFINE_INSTANCE_FCT()
134 static tEplKernel EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_
135 tEplObdCallback fpCallback_p,
136 tEplObdCbParam *pCbParam_p);
138 static tEplObdSize EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p);
140 static tEplObdSize EplObdGetStrLen(void *pObjData_p,
141 tEplObdSize ObjLen_p, tEplObdType ObjType_p);
143 #if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
144 static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p,
145 void *pData_p);
146 #endif
148 static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p,
149 tEplObdVarEntry **ppVarEntry_p);
151 static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_
152 unsigned int uiIndex_p,
153 unsigned int uiSubindex_p,
154 tEplObdEntryPtr * ppObdEntry_p,
155 tEplObdSubEntryPtr * ppObdSubEntry_p);
157 static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p);
159 static tEplKernel EplObdGetIndexIntern(tEplObdInitParam *pInitParam_p,
160 unsigned int uiIndex_p,
161 tEplObdEntryPtr * ppObdEntry_p);
163 static tEplKernel EplObdGetSubindexIntern(tEplObdEntryPtr pObdEntry_p,
164 unsigned int uiSubIndex_p,
165 tEplObdSubEntryPtr * ppObdSubEntry_p);
167 static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
168 tEplObdPart CurrentOdPart_p,
169 tEplObdEntryPtr pObdEnty_p,
170 tEplObdDir Direction_p);
172 static void *EplObdGetObjectDefaultPtr(tEplObdSubEntryPtr pSubIndexEntry_p);
173 static void *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p);
175 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
177 static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdCbStoreParam *pCbStoreParam_p);
179 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
181 static void EplObdCopyObjectData(void *pDstData_p,
182 void *pSrcData_p,
183 tEplObdSize ObjSize_p, tEplObdType ObjType_p);
185 void *EplObdGetObjectDataPtrIntern(tEplObdSubEntryPtr pSubindexEntry_p);
187 static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p,
188 BOOL * pfEntryNumerical_p);
190 static tEplKernel EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
191 unsigned int uiSubIndex_p,
192 void *pSrcData_p,
193 void **ppDstData_p,
194 tEplObdSize Size_p,
195 tEplObdEntryPtr *ppObdEntry_p,
196 tEplObdSubEntryPtr *ppSubEntry_p,
197 tEplObdCbParam *pCbParam_p,
198 tEplObdSize *pObdSize_p);
200 static tEplKernel EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p,
201 tEplObdSubEntryPtr pSubEntry_p,
202 tEplObdCbParam *pCbParam_p,
203 void *pSrcData_p,
204 void *pDstData_p,
205 tEplObdSize ObdSize_p);
207 //=========================================================================//
208 // //
209 // P U B L I C F U N C T I O N S //
210 // //
211 //=========================================================================//
213 //---------------------------------------------------------------------------
215 // Function: EplObdInit()
217 // Description: initializes the first instance
219 // Parameters: pInitParam_p = init parameter
221 // Return: tEplKernel = errorcode
223 // State:
225 //---------------------------------------------------------------------------
227 EPLDLLEXPORT tEplKernel EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p)
230 tEplKernel Ret;
231 EPL_MCO_DELETE_INSTANCE_TABLE();
233 if (pInitParam_p == NULL) {
234 Ret = kEplSuccessful;
235 goto Exit;
238 Ret = EplObdAddInstance(EPL_MCO_PTR_INSTANCE_PTR_ pInitParam_p);
240 Exit:
241 return Ret;
245 //---------------------------------------------------------------------------
247 // Function: EplObdAddInstance()
249 // Description: adds a new instance
251 // Parameters: pInitParam_p
253 // Return: tEplKernel
255 // State:
257 //---------------------------------------------------------------------------
259 EPLDLLEXPORT tEplKernel EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p)
262 EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplKernel Ret;
264 // check if pointer to instance pointer valid
265 // get free instance and set the globale instance pointer
266 // set also the instance addr to parameterlist
267 EPL_MCO_CHECK_PTR_INSTANCE_PTR();
268 EPL_MCO_GET_FREE_INSTANCE_PTR();
269 EPL_MCO_SET_PTR_INSTANCE_PTR();
271 // save init parameters
272 EPL_MEMCPY(&EPL_MCO_GLB_VAR(m_ObdInitParam), pInitParam_p,
273 sizeof(tEplObdInitParam));
275 // clear callback function for command LOAD and STORE
276 EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) = NULL;
278 // sign instance as used
279 EPL_MCO_WRITE_INSTANCE_STATE(kStateUsed);
281 // initialize object dictionary
282 // so all all VarEntries will be initialized to trash object and default values will be set to current data
283 Ret = EplObdAccessOdPart(EPL_MCO_INSTANCE_PTR_
284 kEplObdPartAll, kEplObdDirInit);
286 return Ret;
290 //---------------------------------------------------------------------------
292 // Function: EplObdDeleteInstance()
294 // Description: delete instance
296 // Parameters: EPL_MCO_DECL_INSTANCE_PTR
298 // Return: tEplKernel
300 // State:
302 //---------------------------------------------------------------------------
303 #if (EPL_USE_DELETEINST_FUNC != FALSE)
304 EPLDLLEXPORT tEplKernel EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR)
306 // check for all API function if instance is valid
307 EPL_MCO_CHECK_INSTANCE_STATE();
309 // sign instance as unused
310 EPL_MCO_WRITE_INSTANCE_STATE(kStateUnused);
312 return kEplSuccessful;
315 #endif // (EPL_USE_DELETEINST_FUNC != FALSE)
317 //---------------------------------------------------------------------------
319 // Function: EplObdWriteEntry()
321 // Description: Function writes data to an OBD entry. Strings
322 // are stored with added '\0' character.
324 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
325 // uiIndex_p = Index of the OD entry
326 // uiSubIndex_p = Subindex of the OD Entry
327 // pSrcData_p = Pointer to the data to write
328 // Size_p = Size of the data in Byte
330 // Return: tEplKernel = Errorcode
333 // State:
335 //---------------------------------------------------------------------------
337 EPLDLLEXPORT tEplKernel EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
338 unsigned int uiSubIndex_p,
339 void *pSrcData_p,
340 tEplObdSize Size_p)
343 tEplKernel Ret;
344 tEplObdEntryPtr pObdEntry;
345 tEplObdSubEntryPtr pSubEntry;
346 tEplObdCbParam CbParam;
347 void *pDstData;
348 tEplObdSize ObdSize;
350 Ret = EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_
351 uiIndex_p,
352 uiSubIndex_p,
353 pSrcData_p,
354 &pDstData,
355 Size_p,
356 &pObdEntry, &pSubEntry, &CbParam, &ObdSize);
357 if (Ret != kEplSuccessful) {
358 goto Exit;
361 Ret = EplObdWriteEntryPost(EPL_MCO_INSTANCE_PTR_
362 pObdEntry,
363 pSubEntry,
364 &CbParam, pSrcData_p, pDstData, ObdSize);
365 if (Ret != kEplSuccessful) {
366 goto Exit;
369 Exit:
371 return Ret;
375 //---------------------------------------------------------------------------
377 // Function: EplObdReadEntry()
379 // Description: The function reads an object entry. The application
380 // can always read the data even if attrib kEplObdAccRead
381 // is not set. The attrib is only checked up for SDO transfer.
383 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
384 // uiIndex_p = Index oof the OD entry to read
385 // uiSubIndex_p = Subindex to read
386 // pDstData_p = pointer to the buffer for data
387 // Offset_p = offset in data for read access
388 // pSize_p = IN: Size of the buffer
389 // OUT: number of readed Bytes
391 // Return: tEplKernel
393 // State:
395 //---------------------------------------------------------------------------
397 EPLDLLEXPORT tEplKernel EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
398 unsigned int uiSubIndex_p,
399 void *pDstData_p,
400 tEplObdSize *pSize_p)
403 tEplKernel Ret;
404 tEplObdEntryPtr pObdEntry;
405 tEplObdSubEntryPtr pSubEntry;
406 tEplObdCbParam CbParam;
407 void *pSrcData;
408 tEplObdSize ObdSize;
410 // check for all API function if instance is valid
411 EPL_MCO_CHECK_INSTANCE_STATE();
413 ASSERT(pDstData_p != NULL);
414 ASSERT(pSize_p != NULL);
416 // get address of index and subindex entry
417 Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
418 uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry);
419 if (Ret != kEplSuccessful) {
420 goto Exit;
422 // get pointer to object data
423 pSrcData = EplObdGetObjectDataPtrIntern(pSubEntry);
425 // check source pointer
426 if (pSrcData == NULL) {
427 Ret = kEplObdReadViolation;
428 goto Exit;
430 //------------------------------------------------------------------------
431 // address of source data to structure of callback parameters
432 // so callback function can change this data before reading
433 CbParam.m_uiIndex = uiIndex_p;
434 CbParam.m_uiSubIndex = uiSubIndex_p;
435 CbParam.m_pArg = pSrcData;
436 CbParam.m_ObdEvent = kEplObdEvPreRead;
437 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
438 pObdEntry->m_fpCallback, &CbParam);
439 if (Ret != kEplSuccessful) {
440 goto Exit;
442 // get size of data and check if application has reserved enough memory
443 ObdSize = EplObdGetDataSizeIntern(pSubEntry);
444 // check if offset given and calc correct number of bytes to read
445 if (*pSize_p < ObdSize) {
446 Ret = kEplObdValueLengthError;
447 goto Exit;
449 // read value from object
450 EPL_MEMCPY(pDstData_p, pSrcData, ObdSize);
451 *pSize_p = ObdSize;
453 // write address of destination data to structure of callback parameters
454 // so callback function can change this data after reading
455 CbParam.m_pArg = pDstData_p;
456 CbParam.m_ObdEvent = kEplObdEvPostRead;
457 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
458 pObdEntry->m_fpCallback, &CbParam);
460 Exit:
462 return Ret;
466 //---------------------------------------------------------------------------
468 // Function: EplObdAccessOdPart()
470 // Description: restores default values of one part of OD
472 // Parameters: ObdPart_p
473 // Direction_p
475 // Return: tEplKernel
477 // State:
479 //---------------------------------------------------------------------------
481 EPLDLLEXPORT tEplKernel EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdPart ObdPart_p,
482 tEplObdDir Direction_p)
485 tEplKernel Ret = kEplSuccessful;
486 BOOL fPartFount;
487 tEplObdEntryPtr pObdEntry;
489 // check for all API function if instance is valid
490 EPL_MCO_CHECK_INSTANCE_STATE();
492 // part always has to be unequal to NULL
493 pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pPart);
494 ASSERTMSG(pObdEntry != NULL,
495 "EplObdAccessOdPart(): no OD part is defined!\n");
497 // if ObdPart_p is not valid fPartFound keeps FALSE and function returns kEplObdIllegalPart
498 fPartFount = FALSE;
500 // access to part
501 if ((ObdPart_p & kEplObdPartGen) != 0) {
502 fPartFount = TRUE;
504 Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_
505 kEplObdPartGen, pObdEntry,
506 Direction_p);
507 if (Ret != kEplSuccessful) {
508 goto Exit;
511 // access to manufacturer part
512 pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pManufacturerPart);
514 if (((ObdPart_p & kEplObdPartMan) != 0) && (pObdEntry != NULL)) {
515 fPartFount = TRUE;
517 Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_
518 kEplObdPartMan, pObdEntry,
519 Direction_p);
520 if (Ret != kEplSuccessful) {
521 goto Exit;
524 // access to device part
525 pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pDevicePart);
527 if (((ObdPart_p & kEplObdPartDev) != 0) && (pObdEntry != NULL)) {
528 fPartFount = TRUE;
530 Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_
531 kEplObdPartDev, pObdEntry,
532 Direction_p);
533 if (Ret != kEplSuccessful) {
534 goto Exit;
537 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
539 // access to user part
540 pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pUserPart);
542 if (((ObdPart_p & kEplObdPartUsr) != 0) && (pObdEntry != NULL)) {
543 fPartFount = TRUE;
545 Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_
546 kEplObdPartUsr,
547 pObdEntry, Direction_p);
548 if (Ret != kEplSuccessful) {
549 goto Exit;
553 #endif
555 // no access to an OD part was done? illegal OD part was specified!
556 if (fPartFount == FALSE) {
557 Ret = kEplObdIllegalPart;
560 Exit:
562 return Ret;
566 //---------------------------------------------------------------------------
568 // Function: EplObdDefineVar()
570 // Description: defines a variable in OD
572 // Parameters: pEplVarParam_p
574 // Return: tEplKernel
576 // State:
578 //---------------------------------------------------------------------------
580 EPLDLLEXPORT tEplKernel EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_ tEplVarParam *pVarParam_p)
583 tEplKernel Ret;
584 tEplObdVarEntry *pVarEntry;
585 tEplVarParamValid VarValid;
586 tEplObdSubEntryPtr pSubindexEntry;
588 // check for all API function if instance is valid
589 EPL_MCO_CHECK_INSTANCE_STATE();
591 ASSERT(pVarParam_p != NULL); // is not allowed to be NULL
593 // get address of subindex entry
594 Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
595 pVarParam_p->m_uiIndex,
596 pVarParam_p->m_uiSubindex, NULL, &pSubindexEntry);
597 if (Ret != kEplSuccessful) {
598 goto Exit;
600 // get var entry
601 Ret = EplObdGetVarEntry(pSubindexEntry, &pVarEntry);
602 if (Ret != kEplSuccessful) {
603 goto Exit;
606 VarValid = pVarParam_p->m_ValidFlag;
608 // copy only this values, which valid flag is set
609 if ((VarValid & kVarValidSize) != 0) {
610 if (pSubindexEntry->m_Type != kEplObdTypDomain) {
611 tEplObdSize DataSize;
613 // check passed size parameter
614 DataSize = EplObdGetObjectSize(pSubindexEntry);
615 if (DataSize != pVarParam_p->m_Size) { // size of variable does not match
616 Ret = kEplObdValueLengthError;
617 goto Exit;
619 } else { // size can be set only for objects of type DOMAIN
620 pVarEntry->m_Size = pVarParam_p->m_Size;
624 if ((VarValid & kVarValidData) != 0) {
625 pVarEntry->m_pData = pVarParam_p->m_pData;
628 #if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
630 if ((VarValid & kVarValidCallback) != 0)
632 pVarEntry->m_fpCallback = pVarParam_p->m_fpCallback;
635 if ((VarValid & kVarValidArg) != 0)
637 pVarEntry->m_pArg = pVarParam_p->m_pArg;
640 #endif
642 // Ret is already set to kEplSuccessful from ObdGetVarIntern()
644 Exit:
646 return Ret;
650 //---------------------------------------------------------------------------
652 // Function: EplObdGetObjectDataPtr()
654 // Description: It returnes the current data pointer. But if object is an
655 // constant object it returnes the default pointer.
657 // Parameters: uiIndex_p = Index of the entry
658 // uiSubindex_p = Subindex of the entry
660 // Return: void * = pointer to object data
662 // State:
664 //---------------------------------------------------------------------------
666 EPLDLLEXPORT void *EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
667 unsigned int uiSubIndex_p)
669 tEplKernel Ret;
670 void *pData;
671 tEplObdEntryPtr pObdEntry;
672 tEplObdSubEntryPtr pObdSubEntry;
674 // get pointer to index structure
675 Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam),
676 uiIndex_p, &pObdEntry);
677 if (Ret != kEplSuccessful) {
678 pData = NULL;
679 goto Exit;
681 // get pointer to subindex structure
682 Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry);
683 if (Ret != kEplSuccessful) {
684 pData = NULL;
685 goto Exit;
687 // get Datapointer
688 pData = EplObdGetObjectDataPtrIntern(pObdSubEntry);
690 Exit:
691 return pData;
695 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
697 //---------------------------------------------------------------------------
699 // Function: EplObdRegisterUserOd()
701 // Description: function registers the user OD
703 // Parameters: pUserOd_p =pointer to user ODd
705 // Return: tEplKernel = errorcode
707 // State:
709 //---------------------------------------------------------------------------
710 EPLDLLEXPORT tEplKernel EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pUserOd_p)
713 EPL_MCO_CHECK_INSTANCE_STATE();
715 EPL_MCO_GLB_VAR(m_ObdInitParam.m_pUserPart) = pUserOd_p;
717 return kEplSuccessful;
721 #endif
723 //---------------------------------------------------------------------------
725 // Function: EplObdInitVarEntry()
727 // Description: function to initialize VarEntry dependened on object type
729 // Parameters: pVarEntry_p = pointer to var entry structure
730 // Type_p = object type
731 // ObdSize_p = size of object data
733 // Returns: none
735 // State:
737 //---------------------------------------------------------------------------
739 EPLDLLEXPORT void EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdVarEntry *pVarEntry_p,
740 tEplObdType Type_p, tEplObdSize ObdSize_p)
743 #if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
745 // reset pointer to VAR callback and argument
746 pVarEntry_p->m_fpCallback = NULL;
747 pVarEntry_p->m_pArg = NULL;
749 #endif
752 // 10-dec-2004 r.d.: this function will not be used for strings
753 if ((Type_p == kEplObdTypDomain))
754 // (bType_p == kEplObdTypVString) /* ||
755 // (bType_p == kEplObdTypOString) ||
756 // (bType_p == kEplObdTypUString) */ )
758 // variables which are defined as DOMAIN or VSTRING should not point to
759 // trash object, because this trash object contains only 8 bytes. DOMAINS or
760 // STRINGS can be longer.
761 pVarEntry_p->m_pData = NULL;
762 pVarEntry_p->m_Size = 0;
763 } else {
764 // set address to variable data to trash object
765 // This prevents an access violation if user forgets to call EplObdDefineVar()
766 // for this variable but mappes it in a PDO.
767 pVarEntry_p->m_pData = &abEplObdTrashObject_g[0];
768 pVarEntry_p->m_Size = ObdSize_p;
773 //---------------------------------------------------------------------------
775 // Function: EplObdGetDataSize()
777 // Description: function to initialize VarEntry dependened on object type
779 // gets the data size of an object
780 // for string objects it returnes the string length
782 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
783 // uiIndex_p = Index
784 // uiSubIndex_p= Subindex
786 // Return: tEplObdSize
788 // State:
790 //---------------------------------------------------------------------------
791 EPLDLLEXPORT tEplObdSize EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
792 unsigned int uiSubIndex_p)
794 tEplKernel Ret;
795 tEplObdSize ObdSize;
796 tEplObdEntryPtr pObdEntry;
797 tEplObdSubEntryPtr pObdSubEntry;
799 // get pointer to index structure
800 Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam),
801 uiIndex_p, &pObdEntry);
802 if (Ret != kEplSuccessful) {
803 ObdSize = 0;
804 goto Exit;
806 // get pointer to subindex structure
807 Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry);
808 if (Ret != kEplSuccessful) {
809 ObdSize = 0;
810 goto Exit;
812 // get size
813 ObdSize = EplObdGetDataSizeIntern(pObdSubEntry);
814 Exit:
815 return ObdSize;
818 //---------------------------------------------------------------------------
820 // Function: EplObdGetNodeId()
822 // Description: function returns nodeid from entry 0x1F93
825 // Parameters: EPL_MCO_DECL_INSTANCE_PTR = Instancepointer
827 // Return: unsigned int = Node Id
829 // State:
831 //---------------------------------------------------------------------------
832 EPLDLLEXPORT unsigned int EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR)
834 tEplKernel Ret;
835 tEplObdSize ObdSize;
836 BYTE bNodeId;
838 bNodeId = 0;
839 ObdSize = sizeof(bNodeId);
840 Ret = EplObdReadEntry(EPL_MCO_PTR_INSTANCE_PTR_
841 EPL_OBD_NODE_ID_INDEX,
842 EPL_OBD_NODE_ID_SUBINDEX, &bNodeId, &ObdSize);
843 if (Ret != kEplSuccessful) {
844 bNodeId = EPL_C_ADR_INVALID;
845 goto Exit;
848 Exit:
849 return (unsigned int)bNodeId;
853 //---------------------------------------------------------------------------
855 // Function: EplObdSetNodeId()
857 // Description: function sets nodeid in entry 0x1F93
860 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
861 // uiNodeId_p = Node Id to set
862 // NodeIdType_p= Type on which way the Node Id was set
864 // Return: tEplKernel = Errorcode
866 // State:
868 //---------------------------------------------------------------------------
869 EPLDLLEXPORT tEplKernel EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_ unsigned int uiNodeId_p,
870 tEplObdNodeIdType NodeIdType_p)
872 tEplKernel Ret;
873 tEplObdSize ObdSize;
874 BYTE fHwBool;
875 BYTE bNodeId;
877 // check Node Id
878 if (uiNodeId_p == EPL_C_ADR_INVALID) {
879 Ret = kEplInvalidNodeId;
880 goto Exit;
882 bNodeId = (BYTE) uiNodeId_p;
883 ObdSize = sizeof(BYTE);
884 // write NodeId to OD entry
885 Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR_
886 EPL_OBD_NODE_ID_INDEX,
887 EPL_OBD_NODE_ID_SUBINDEX, &bNodeId, ObdSize);
888 if (Ret != kEplSuccessful) {
889 goto Exit;
891 // set HWBOOL-Flag in Subindex EPL_OBD_NODE_ID_HWBOOL_SUBINDEX
892 switch (NodeIdType_p) {
893 // type unknown
894 case kEplObdNodeIdUnknown:
896 fHwBool = OBD_FALSE;
897 break;
900 case kEplObdNodeIdSoftware:
902 fHwBool = OBD_FALSE;
903 break;
906 case kEplObdNodeIdHardware:
908 fHwBool = OBD_TRUE;
909 break;
912 default:
914 fHwBool = OBD_FALSE;
917 } // end of switch (NodeIdType_p)
919 // write flag
920 ObdSize = sizeof(fHwBool);
921 Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR
922 EPL_OBD_NODE_ID_INDEX,
923 EPL_OBD_NODE_ID_HWBOOL_SUBINDEX,
924 &fHwBool, ObdSize);
925 if (Ret != kEplSuccessful) {
926 goto Exit;
929 Exit:
930 return Ret;
933 //---------------------------------------------------------------------------
935 // Function: EplObdIsNumerical()
937 // Description: function checks if a entry is numerical or not
940 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
941 // uiIndex_p = Index
942 // uiSubIndex_p = Subindex
943 // pfEntryNumerical_p = pointer to BOOL for returnvalue
944 // -> TRUE if entry a numerical value
945 // -> FALSE if entry not a numerical value
947 // Return: tEplKernel = Errorcode
949 // State:
951 //---------------------------------------------------------------------------
952 EPLDLLEXPORT tEplKernel EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
953 unsigned int uiSubIndex_p,
954 BOOL *pfEntryNumerical_p)
956 tEplKernel Ret;
957 tEplObdEntryPtr pObdEntry;
958 tEplObdSubEntryPtr pObdSubEntry;
960 // get pointer to index structure
961 Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam),
962 uiIndex_p, &pObdEntry);
963 if (Ret != kEplSuccessful) {
964 goto Exit;
966 // get pointer to subindex structure
967 Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry);
968 if (Ret != kEplSuccessful) {
969 goto Exit;
972 Ret = EplObdIsNumericalIntern(pObdSubEntry, pfEntryNumerical_p);
974 Exit:
975 return Ret;
979 //---------------------------------------------------------------------------
981 // Function: EplObdReadEntryToLe()
983 // Description: The function reads an object entry from the byteoder
984 // of the system to the little endian byteorder for numerical values.
985 // For other types a normal read will be processed. This is usefull for
986 // the PDO and SDO module. The application
987 // can always read the data even if attrib kEplObdAccRead
988 // is not set. The attrib is only checked up for SDO transfer.
990 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
991 // uiIndex_p = Index of the OD entry to read
992 // uiSubIndex_p = Subindex to read
993 // pDstData_p = pointer to the buffer for data
994 // Offset_p = offset in data for read access
995 // pSize_p = IN: Size of the buffer
996 // OUT: number of readed Bytes
998 // Return: tEplKernel
1000 // State:
1002 //---------------------------------------------------------------------------
1003 EPLDLLEXPORT tEplKernel EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
1004 unsigned int uiSubIndex_p,
1005 void *pDstData_p,
1006 tEplObdSize *pSize_p)
1008 tEplKernel Ret;
1009 tEplObdEntryPtr pObdEntry;
1010 tEplObdSubEntryPtr pSubEntry;
1011 tEplObdCbParam CbParam;
1012 void *pSrcData;
1013 tEplObdSize ObdSize;
1015 // check for all API function if instance is valid
1016 EPL_MCO_CHECK_INSTANCE_STATE();
1018 ASSERT(pDstData_p != NULL);
1019 ASSERT(pSize_p != NULL);
1021 // get address of index and subindex entry
1022 Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
1023 uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry);
1024 if (Ret != kEplSuccessful) {
1025 goto Exit;
1027 // get pointer to object data
1028 pSrcData = EplObdGetObjectDataPtrIntern(pSubEntry);
1030 // check source pointer
1031 if (pSrcData == NULL) {
1032 Ret = kEplObdReadViolation;
1033 goto Exit;
1035 //------------------------------------------------------------------------
1036 // address of source data to structure of callback parameters
1037 // so callback function can change this data before reading
1038 CbParam.m_uiIndex = uiIndex_p;
1039 CbParam.m_uiSubIndex = uiSubIndex_p;
1040 CbParam.m_pArg = pSrcData;
1041 CbParam.m_ObdEvent = kEplObdEvPreRead;
1042 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
1043 pObdEntry->m_fpCallback, &CbParam);
1044 if (Ret != kEplSuccessful) {
1045 goto Exit;
1047 // get size of data and check if application has reserved enough memory
1048 ObdSize = EplObdGetDataSizeIntern(pSubEntry);
1049 // check if offset given and calc correct number of bytes to read
1050 if (*pSize_p < ObdSize) {
1051 Ret = kEplObdValueLengthError;
1052 goto Exit;
1054 // check if numerical type
1055 switch (pSubEntry->m_Type) {
1056 //-----------------------------------------------
1057 // types without ami
1058 case kEplObdTypVString:
1059 case kEplObdTypOString:
1060 case kEplObdTypDomain:
1061 default:
1063 // read value from object
1064 EPL_MEMCPY(pDstData_p, pSrcData, ObdSize);
1065 break;
1068 //-----------------------------------------------
1069 // numerical type which needs ami-write
1070 // 8 bit or smaller values
1071 case kEplObdTypBool:
1072 case kEplObdTypInt8:
1073 case kEplObdTypUInt8:
1075 AmiSetByteToLe(pDstData_p, *((BYTE *) pSrcData));
1076 break;
1079 // 16 bit values
1080 case kEplObdTypInt16:
1081 case kEplObdTypUInt16:
1083 AmiSetWordToLe(pDstData_p, *((WORD *) pSrcData));
1084 break;
1087 // 24 bit values
1088 case kEplObdTypInt24:
1089 case kEplObdTypUInt24:
1091 AmiSetDword24ToLe(pDstData_p, *((DWORD *) pSrcData));
1092 break;
1095 // 32 bit values
1096 case kEplObdTypInt32:
1097 case kEplObdTypUInt32:
1098 case kEplObdTypReal32:
1100 AmiSetDwordToLe(pDstData_p, *((DWORD *) pSrcData));
1101 break;
1104 // 40 bit values
1105 case kEplObdTypInt40:
1106 case kEplObdTypUInt40:
1108 AmiSetQword40ToLe(pDstData_p, *((QWORD *) pSrcData));
1109 break;
1112 // 48 bit values
1113 case kEplObdTypInt48:
1114 case kEplObdTypUInt48:
1116 AmiSetQword48ToLe(pDstData_p, *((QWORD *) pSrcData));
1117 break;
1120 // 56 bit values
1121 case kEplObdTypInt56:
1122 case kEplObdTypUInt56:
1124 AmiSetQword56ToLe(pDstData_p, *((QWORD *) pSrcData));
1125 break;
1128 // 64 bit values
1129 case kEplObdTypInt64:
1130 case kEplObdTypUInt64:
1131 case kEplObdTypReal64:
1133 AmiSetQword64ToLe(pDstData_p, *((QWORD *) pSrcData));
1134 break;
1137 // time of day
1138 case kEplObdTypTimeOfDay:
1139 case kEplObdTypTimeDiff:
1141 AmiSetTimeOfDay(pDstData_p, ((tTimeOfDay *) pSrcData));
1142 break;
1145 } // end of switch(pSubEntry->m_Type)
1147 *pSize_p = ObdSize;
1149 // write address of destination data to structure of callback parameters
1150 // so callback function can change this data after reading
1151 CbParam.m_pArg = pDstData_p;
1152 CbParam.m_ObdEvent = kEplObdEvPostRead;
1153 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
1154 pObdEntry->m_fpCallback, &CbParam);
1156 Exit:
1158 return Ret;
1162 //---------------------------------------------------------------------------
1164 // Function: EplObdWriteEntryFromLe()
1166 // Description: Function writes data to an OBD entry from a source with
1167 // little endian byteorder to the od with system specuific
1168 // byteorder. Not numerical values will only by copied. Strings
1169 // are stored with added '\0' character.
1171 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
1172 // uiIndex_p = Index of the OD entry
1173 // uiSubIndex_p = Subindex of the OD Entry
1174 // pSrcData_p = Pointer to the data to write
1175 // Size_p = Size of the data in Byte
1177 // Return: tEplKernel = Errorcode
1180 // State:
1182 //---------------------------------------------------------------------------
1183 EPLDLLEXPORT tEplKernel EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
1184 unsigned int uiSubIndex_p,
1185 void *pSrcData_p,
1186 tEplObdSize Size_p)
1188 tEplKernel Ret;
1189 tEplObdEntryPtr pObdEntry;
1190 tEplObdSubEntryPtr pSubEntry;
1191 tEplObdCbParam CbParam;
1192 void *pDstData;
1193 tEplObdSize ObdSize;
1194 QWORD qwBuffer;
1195 void *pBuffer = &qwBuffer;
1197 Ret = EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_
1198 uiIndex_p,
1199 uiSubIndex_p,
1200 pSrcData_p,
1201 &pDstData,
1202 Size_p,
1203 &pObdEntry, &pSubEntry, &CbParam, &ObdSize);
1204 if (Ret != kEplSuccessful) {
1205 goto Exit;
1208 // check if numerical type
1209 switch (pSubEntry->m_Type) {
1210 //-----------------------------------------------
1211 // types without ami
1212 default:
1213 { // do nothing, i.e. use the given source pointer
1214 pBuffer = pSrcData_p;
1215 break;
1218 //-----------------------------------------------
1219 // numerical type which needs ami-write
1220 // 8 bit or smaller values
1221 case kEplObdTypBool:
1222 case kEplObdTypInt8:
1223 case kEplObdTypUInt8:
1225 *((BYTE *) pBuffer) = AmiGetByteFromLe(pSrcData_p);
1226 break;
1229 // 16 bit values
1230 case kEplObdTypInt16:
1231 case kEplObdTypUInt16:
1233 *((WORD *) pBuffer) = AmiGetWordFromLe(pSrcData_p);
1234 break;
1237 // 24 bit values
1238 case kEplObdTypInt24:
1239 case kEplObdTypUInt24:
1241 *((DWORD *) pBuffer) = AmiGetDword24FromLe(pSrcData_p);
1242 break;
1245 // 32 bit values
1246 case kEplObdTypInt32:
1247 case kEplObdTypUInt32:
1248 case kEplObdTypReal32:
1250 *((DWORD *) pBuffer) = AmiGetDwordFromLe(pSrcData_p);
1251 break;
1254 // 40 bit values
1255 case kEplObdTypInt40:
1256 case kEplObdTypUInt40:
1258 *((QWORD *) pBuffer) = AmiGetQword40FromLe(pSrcData_p);
1259 break;
1262 // 48 bit values
1263 case kEplObdTypInt48:
1264 case kEplObdTypUInt48:
1266 *((QWORD *) pBuffer) = AmiGetQword48FromLe(pSrcData_p);
1267 break;
1270 // 56 bit values
1271 case kEplObdTypInt56:
1272 case kEplObdTypUInt56:
1274 *((QWORD *) pBuffer) = AmiGetQword56FromLe(pSrcData_p);
1275 break;
1278 // 64 bit values
1279 case kEplObdTypInt64:
1280 case kEplObdTypUInt64:
1281 case kEplObdTypReal64:
1283 *((QWORD *) pBuffer) = AmiGetQword64FromLe(pSrcData_p);
1284 break;
1287 // time of day
1288 case kEplObdTypTimeOfDay:
1289 case kEplObdTypTimeDiff:
1291 AmiGetTimeOfDay(pBuffer, ((tTimeOfDay *) pSrcData_p));
1292 break;
1295 } // end of switch(pSubEntry->m_Type)
1297 Ret = EplObdWriteEntryPost(EPL_MCO_INSTANCE_PTR_
1298 pObdEntry,
1299 pSubEntry,
1300 &CbParam, pBuffer, pDstData, ObdSize);
1301 if (Ret != kEplSuccessful) {
1302 goto Exit;
1305 Exit:
1307 return Ret;
1311 //---------------------------------------------------------------------------
1313 // Function: EplObdGetAccessType()
1315 // Description: Function returns accesstype of the entry
1317 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
1318 // uiIndex_p = Index of the OD entry
1319 // uiSubIndex_p = Subindex of the OD Entry
1320 // pAccessTyp_p = pointer to buffer to store accesstype
1322 // Return: tEplKernel = errorcode
1325 // State:
1327 //---------------------------------------------------------------------------
1328 EPLDLLEXPORT tEplKernel EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
1329 unsigned int uiSubIndex_p,
1330 tEplObdAccess *pAccessTyp_p)
1332 tEplKernel Ret;
1333 tEplObdEntryPtr pObdEntry;
1334 tEplObdSubEntryPtr pObdSubEntry;
1336 // get pointer to index structure
1337 Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam),
1338 uiIndex_p, &pObdEntry);
1339 if (Ret != kEplSuccessful) {
1340 goto Exit;
1342 // get pointer to subindex structure
1343 Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry);
1344 if (Ret != kEplSuccessful) {
1345 goto Exit;
1347 // get accessType
1348 *pAccessTyp_p = pObdSubEntry->m_Access;
1350 Exit:
1351 return Ret;
1354 //---------------------------------------------------------------------------
1356 // Function: EplObdSearchVarEntry()
1358 // Description: gets variable from OD
1360 // Parameters: uiIndex_p = index of the var entry to search
1361 // uiSubindex_p = subindex of var entry to search
1362 // ppVarEntry_p = pointer to the pointer to the varentry
1364 // Return: tEplKernel
1366 // State:
1368 //---------------------------------------------------------------------------
1370 tEplKernel EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
1371 unsigned int uiSubindex_p,
1372 tEplObdVarEntry **ppVarEntry_p)
1375 tEplKernel Ret;
1376 tEplObdSubEntryPtr pSubindexEntry;
1378 // check for all API function if instance is valid
1379 EPL_MCO_CHECK_INSTANCE_STATE();
1381 // get address of subindex entry
1382 Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
1383 uiIndex_p, uiSubindex_p, NULL, &pSubindexEntry);
1384 if (Ret == kEplSuccessful) {
1385 // get var entry
1386 Ret = EplObdGetVarEntry(pSubindexEntry, ppVarEntry_p);
1389 return Ret;
1393 //=========================================================================//
1394 // //
1395 // P R I V A T E D E F I N I T I O N S //
1396 // //
1397 //=========================================================================//
1399 EPL_MCO_DECL_INSTANCE_FCT()
1400 //---------------------------------------------------------------------------
1402 // Function: EplObdCallObjectCallback()
1404 // Description: calls callback function of an object or of a variable
1406 // Parameters: fpCallback_p
1407 // pCbParam_p
1409 // Return: tEplKernel
1411 // State:
1413 //---------------------------------------------------------------------------
1414 static tEplKernel EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_
1415 tEplObdCallback fpCallback_p,
1416 tEplObdCbParam *pCbParam_p)
1419 tEplKernel Ret;
1420 tEplObdCallback fpCallback;
1422 // check for all API function if instance is valid
1423 EPL_MCO_CHECK_INSTANCE_STATE();
1425 ASSERT(pCbParam_p != NULL);
1427 Ret = kEplSuccessful;
1429 // check address of callback function before calling it
1430 if (fpCallback_p != NULL) {
1431 // KEIL C51 V6.01 has a bug.
1432 // Therefore the parameter fpCallback_p has to be copied in local variable fpCallback.
1433 fpCallback = fpCallback_p;
1435 // call callback function for this object
1436 Ret = fpCallback(EPL_MCO_INSTANCE_PARAM_IDX_()
1437 pCbParam_p);
1440 return Ret;
1443 //---------------------------------------------------------------------------
1445 // Function: EplObdGetDataSizeIntern()
1447 // Description: gets the data size of an object
1448 // for string objects it returnes the string length
1450 // Parameters: pSubIndexEntry_p
1452 // Return: tEplObdSize
1454 // State:
1456 //---------------------------------------------------------------------------
1458 static tEplObdSize EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p)
1461 tEplObdSize DataSize;
1462 void *pData;
1464 // If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING
1465 // then the current pointer is always NULL. The function
1466 // returns the length of default string.
1467 DataSize = EplObdGetObjectSize(pSubIndexEntry_p);
1469 if (pSubIndexEntry_p->m_Type == kEplObdTypVString) {
1470 // The pointer to current value can be received from EplObdGetObjectCurrentPtr()
1471 pData = ((void *)EplObdGetObjectCurrentPtr(pSubIndexEntry_p));
1472 if (pData != NULL) {
1473 DataSize =
1474 EplObdGetStrLen((void *)pData, DataSize,
1475 pSubIndexEntry_p->m_Type);
1480 return DataSize;
1484 //---------------------------------------------------------------------------
1486 // Function: EplObdGetStrLen()
1488 // Description: The function calculates the length of string. The '\0'
1489 // character is included!!
1491 // Parameters: pObjData_p = pointer to string
1492 // ObjLen_p = max. length of objectr entry
1493 // bObjType_p = object type (VSTRING, ...)
1495 // Returns: string length + 1
1497 // State:
1499 //---------------------------------------------------------------------------
1501 static tEplObdSize EplObdGetStrLen(void *pObjData_p,
1502 tEplObdSize ObjLen_p, tEplObdType ObjType_p)
1505 tEplObdSize StrLen = 0;
1506 BYTE *pbString;
1508 if (pObjData_p == NULL) {
1509 goto Exit;
1511 //----------------------------------------
1512 // Visible String: data format byte
1513 if (ObjType_p == kEplObdTypVString) {
1514 pbString = pObjData_p;
1516 for (StrLen = 0; StrLen < ObjLen_p; StrLen++) {
1517 if (*pbString == '\0') {
1518 StrLen++;
1519 break;
1522 pbString++;
1525 //----------------------------------------
1526 // other string types ...
1528 Exit:
1529 return (StrLen);
1533 #if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
1535 //---------------------------------------------------------------------------
1537 // Function: EplObdCheckObjectRange()
1539 // Description: function to check value range of object data
1541 // NOTICE: The pointer of data (pData_p) must point out to an even address,
1542 // if ObjType is unequal to kEplObdTypInt8 or kEplObdTypUInt8! But it is
1543 // always realiced because pointer m_pDefault points always to an
1544 // array of the SPECIFIED type.
1546 // Parameters: pSubindexEntry_p
1547 // pData_p
1549 // Return: tEplKernel
1551 // State:
1553 //---------------------------------------------------------------------------
1555 static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p,
1556 void *pData_p)
1559 tEplKernel Ret;
1560 void *pRangeData;
1562 ASSERTMSG(pSubindexEntry_p != NULL,
1563 "EplObdCheckObjectRange(): no address to subindex struct!\n");
1565 Ret = kEplSuccessful;
1567 // check if data range has to be checked
1568 if ((pSubindexEntry_p->m_Access & kEplObdAccRange) == 0) {
1569 goto Exit;
1571 // get address of default data
1572 pRangeData = pSubindexEntry_p->m_pDefault;
1574 // jump to called object type
1575 switch ((tEplObdType) pSubindexEntry_p->m_Type) {
1576 // -----------------------------------------------------------------
1577 // ObdType kEplObdTypBool will not be checked because there are only
1578 // two possible values 0 or 1.
1580 // -----------------------------------------------------------------
1581 // ObdTypes which has to be check up because numerical values
1582 case kEplObdTypInt8:
1584 // switch to lower limit
1585 pRangeData = ((tEplObdInteger8 *) pRangeData) + 1;
1587 // check if value is to low
1588 if (*((tEplObdInteger8 *) pData_p) <
1589 *((tEplObdInteger8 *) pRangeData)) {
1590 Ret = kEplObdValueTooLow;
1591 break;
1593 // switch to higher limit
1594 pRangeData = ((tEplObdInteger8 *) pRangeData) + 1;
1596 // check if value is to high
1597 if (*((tEplObdInteger8 *) pData_p) >
1598 *((tEplObdInteger8 *) pRangeData)) {
1599 Ret = kEplObdValueTooHigh;
1602 break;
1604 case kEplObdTypUInt8:
1606 // switch to lower limit
1607 pRangeData = ((tEplObdUnsigned8 *) pRangeData) + 1;
1609 // check if value is to low
1610 if (*((tEplObdUnsigned8 *) pData_p) <
1611 *((tEplObdUnsigned8 *) pRangeData)) {
1612 Ret = kEplObdValueTooLow;
1613 break;
1615 // switch to higher limit
1616 pRangeData = ((tEplObdUnsigned8 *) pRangeData) + 1;
1618 // check if value is to high
1619 if (*((tEplObdUnsigned8 *) pData_p) >
1620 *((tEplObdUnsigned8 *) pRangeData)) {
1621 Ret = kEplObdValueTooHigh;
1624 break;
1626 case kEplObdTypInt16:
1628 // switch to lower limit
1629 pRangeData = ((tEplObdInteger16 *) pRangeData) + 1;
1631 // check if value is to low
1632 if (*((tEplObdInteger16 *) pData_p) <
1633 *((tEplObdInteger16 *) pRangeData)) {
1634 Ret = kEplObdValueTooLow;
1635 break;
1637 // switch to higher limit
1638 pRangeData = ((tEplObdInteger16 *) pRangeData) + 1;
1640 // check if value is to high
1641 if (*((tEplObdInteger16 *) pData_p) >
1642 *((tEplObdInteger16 *) pRangeData)) {
1643 Ret = kEplObdValueTooHigh;
1646 break;
1648 case kEplObdTypUInt16:
1650 // switch to lower limit
1651 pRangeData = ((tEplObdUnsigned16 *) pRangeData) + 1;
1653 // check if value is to low
1654 if (*((tEplObdUnsigned16 *) pData_p) <
1655 *((tEplObdUnsigned16 *) pRangeData)) {
1656 Ret = kEplObdValueTooLow;
1657 break;
1659 // switch to higher limit
1660 pRangeData = ((tEplObdUnsigned16 *) pRangeData) + 1;
1662 // check if value is to high
1663 if (*((tEplObdUnsigned16 *) pData_p) >
1664 *((tEplObdUnsigned16 *) pRangeData)) {
1665 Ret = kEplObdValueTooHigh;
1668 break;
1670 case kEplObdTypInt32:
1672 // switch to lower limit
1673 pRangeData = ((tEplObdInteger32 *) pRangeData) + 1;
1675 // check if value is to low
1676 if (*((tEplObdInteger32 *) pData_p) <
1677 *((tEplObdInteger32 *) pRangeData)) {
1678 Ret = kEplObdValueTooLow;
1679 break;
1681 // switch to higher limit
1682 pRangeData = ((tEplObdInteger32 *) pRangeData) + 1;
1684 // check if value is to high
1685 if (*((tEplObdInteger32 *) pData_p) >
1686 *((tEplObdInteger32 *) pRangeData)) {
1687 Ret = kEplObdValueTooHigh;
1690 break;
1692 case kEplObdTypUInt32:
1694 // switch to lower limit
1695 pRangeData = ((tEplObdUnsigned32 *) pRangeData) + 1;
1697 // check if value is to low
1698 if (*((tEplObdUnsigned32 *) pData_p) <
1699 *((tEplObdUnsigned32 *) pRangeData)) {
1700 Ret = kEplObdValueTooLow;
1701 break;
1703 // switch to higher limit
1704 pRangeData = ((tEplObdUnsigned32 *) pRangeData) + 1;
1706 // check if value is to high
1707 if (*((tEplObdUnsigned32 *) pData_p) >
1708 *((tEplObdUnsigned32 *) pRangeData)) {
1709 Ret = kEplObdValueTooHigh;
1712 break;
1714 case kEplObdTypReal32:
1716 // switch to lower limit
1717 pRangeData = ((tEplObdReal32 *) pRangeData) + 1;
1719 // check if value is to low
1720 if (*((tEplObdReal32 *) pData_p) <
1721 *((tEplObdReal32 *) pRangeData)) {
1722 Ret = kEplObdValueTooLow;
1723 break;
1725 // switch to higher limit
1726 pRangeData = ((tEplObdReal32 *) pRangeData) + 1;
1728 // check if value is to high
1729 if (*((tEplObdReal32 *) pData_p) >
1730 *((tEplObdReal32 *) pRangeData)) {
1731 Ret = kEplObdValueTooHigh;
1734 break;
1736 // -----------------------------------------------------------------
1737 case kEplObdTypInt40:
1738 case kEplObdTypInt48:
1739 case kEplObdTypInt56:
1740 case kEplObdTypInt64:
1742 // switch to lower limit
1743 pRangeData = ((signed QWORD *)pRangeData) + 1;
1745 // check if value is to low
1746 if (*((signed QWORD *)pData_p) < *((signed QWORD *)pRangeData)) {
1747 Ret = kEplObdValueTooLow;
1748 break;
1750 // switch to higher limit
1751 pRangeData = ((signed QWORD *)pRangeData) + 1;
1753 // check if value is to high
1754 if (*((signed QWORD *)pData_p) > *((signed QWORD *)pRangeData)) {
1755 Ret = kEplObdValueTooHigh;
1758 break;
1760 // -----------------------------------------------------------------
1761 case kEplObdTypUInt40:
1762 case kEplObdTypUInt48:
1763 case kEplObdTypUInt56:
1764 case kEplObdTypUInt64:
1766 // switch to lower limit
1767 pRangeData = ((unsigned QWORD *)pRangeData) + 1;
1769 // check if value is to low
1770 if (*((unsigned QWORD *)pData_p) <
1771 *((unsigned QWORD *)pRangeData)) {
1772 Ret = kEplObdValueTooLow;
1773 break;
1775 // switch to higher limit
1776 pRangeData = ((unsigned QWORD *)pRangeData) + 1;
1778 // check if value is to high
1779 if (*((unsigned QWORD *)pData_p) >
1780 *((unsigned QWORD *)pRangeData)) {
1781 Ret = kEplObdValueTooHigh;
1784 break;
1786 // -----------------------------------------------------------------
1787 case kEplObdTypReal64:
1789 // switch to lower limit
1790 pRangeData = ((tEplObdReal64 *) pRangeData) + 1;
1792 // check if value is to low
1793 if (*((tEplObdReal64 *) pData_p) <
1794 *((tEplObdReal64 *) pRangeData)) {
1795 Ret = kEplObdValueTooLow;
1796 break;
1798 // switch to higher limit
1799 pRangeData = ((tEplObdReal64 *) pRangeData) + 1;
1801 // check if value is to high
1802 if (*((tEplObdReal64 *) pData_p) >
1803 *((tEplObdReal64 *) pRangeData)) {
1804 Ret = kEplObdValueTooHigh;
1807 break;
1809 // -----------------------------------------------------------------
1810 case kEplObdTypTimeOfDay:
1811 case kEplObdTypTimeDiff:
1812 break;
1814 // -----------------------------------------------------------------
1815 // ObdTypes kEplObdTypXString and kEplObdTypDomain can not be checkt because
1816 // they have no numerical value.
1817 default:
1819 Ret = kEplObdUnknownObjectType;
1820 break;
1823 Exit:
1825 return Ret;
1828 #endif // (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
1830 //---------------------------------------------------------------------------
1832 // Function: EplObdWriteEntryPre()
1834 // Description: Function prepares write of data to an OBD entry. Strings
1835 // are stored with added '\0' character.
1837 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
1838 // uiIndex_p = Index of the OD entry
1839 // uiSubIndex_p = Subindex of the OD Entry
1840 // pSrcData_p = Pointer to the data to write
1841 // Size_p = Size of the data in Byte
1843 // Return: tEplKernel = Errorcode
1846 // State:
1848 //---------------------------------------------------------------------------
1850 static tEplKernel EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
1851 unsigned int uiSubIndex_p,
1852 void *pSrcData_p,
1853 void **ppDstData_p,
1854 tEplObdSize Size_p,
1855 tEplObdEntryPtr *ppObdEntry_p,
1856 tEplObdSubEntryPtr *ppSubEntry_p,
1857 tEplObdCbParam *pCbParam_p,
1858 tEplObdSize *pObdSize_p)
1861 tEplKernel Ret;
1862 tEplObdEntryPtr pObdEntry;
1863 tEplObdSubEntryPtr pSubEntry;
1864 tEplObdAccess Access;
1865 void *pDstData;
1866 tEplObdSize ObdSize;
1867 BOOL fEntryNumerical;
1869 #if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
1870 tEplObdVStringDomain MemVStringDomain;
1871 void *pCurrData;
1872 #endif
1874 // check for all API function if instance is valid
1875 EPL_MCO_CHECK_INSTANCE_STATE();
1877 ASSERT(pSrcData_p != NULL); // should never be NULL
1879 //------------------------------------------------------------------------
1880 // get address of index and subindex entry
1881 Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
1882 uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry);
1883 if (Ret != kEplSuccessful) {
1884 goto Exit;
1886 // get pointer to object data
1887 pDstData = (void *)EplObdGetObjectDataPtrIntern(pSubEntry);
1889 Access = (tEplObdAccess) pSubEntry->m_Access;
1891 // check access for write
1892 // access violation if adress to current value is NULL
1893 if (((Access & kEplObdAccConst) != 0) || (pDstData == NULL)) {
1894 Ret = kEplObdAccessViolation;
1895 goto Exit;
1897 //------------------------------------------------------------------------
1898 // get size of object
1899 // -as ObdSize = ObdGetObjectSize (pSubEntry);
1901 //------------------------------------------------------------------------
1902 // To use the same callback function for ObdWriteEntry as well as for
1903 // an SDO download call at first (kEplObdEvPre...) the callback function
1904 // with the argument pointer to object size.
1905 pCbParam_p->m_uiIndex = uiIndex_p;
1906 pCbParam_p->m_uiSubIndex = uiSubIndex_p;
1908 // Because object size and object pointer are
1909 // adapted by user callback function, re-read
1910 // this values.
1911 ObdSize = EplObdGetObjectSize(pSubEntry);
1912 pDstData = (void *)EplObdGetObjectDataPtrIntern(pSubEntry);
1914 // 09-dec-2004 r.d.:
1915 // Function EplObdWriteEntry() calls new event kEplObdEvWrStringDomain
1916 // for String or Domain which lets called module directly change
1917 // the data pointer or size. This prevents a recursive call to
1918 // the callback function if it calls EplObdGetEntry().
1919 #if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
1920 if ((pSubEntry->m_Type == kEplObdTypVString) ||
1921 (pSubEntry->m_Type == kEplObdTypDomain) ||
1922 (pSubEntry->m_Type == kEplObdTypOString)) {
1923 if (pSubEntry->m_Type == kEplObdTypVString) {
1924 // reserve one byte for 0-termination
1925 // -as ObdSize -= 1;
1926 Size_p += 1;
1928 // fill out new arg-struct
1929 MemVStringDomain.m_DownloadSize = Size_p;
1930 MemVStringDomain.m_ObjSize = ObdSize;
1931 MemVStringDomain.m_pData = pDstData;
1933 pCbParam_p->m_ObdEvent = kEplObdEvWrStringDomain;
1934 pCbParam_p->m_pArg = &MemVStringDomain;
1935 // call user callback
1936 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
1937 pObdEntry->m_fpCallback,
1938 pCbParam_p);
1939 if (Ret != kEplSuccessful) {
1940 goto Exit;
1942 // write back new settings
1943 pCurrData = pSubEntry->m_pCurrent;
1944 if ((pSubEntry->m_Type == kEplObdTypVString)
1945 || (pSubEntry->m_Type == kEplObdTypOString)) {
1946 ((tEplObdVString *)pCurrData)->m_Size = MemVStringDomain.m_ObjSize;
1947 ((tEplObdVString *)pCurrData)->m_pString = MemVStringDomain.m_pData;
1948 } else // if (pSdosTableEntry_p->m_bObjType == kEplObdTypDomain)
1950 ((tEplObdVarEntry *)pCurrData)->m_Size = MemVStringDomain.m_ObjSize;
1951 ((tEplObdVarEntry *)pCurrData)->m_pData = (void *)MemVStringDomain.m_pData;
1954 // Because object size and object pointer are
1955 // adapted by user callback function, re-read
1956 // this values.
1957 ObdSize = MemVStringDomain.m_ObjSize;
1958 pDstData = (void *)MemVStringDomain.m_pData;
1960 #endif //#if (OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
1962 // 07-dec-2004 r.d.: size from application is needed because callback function can change the object size
1963 // -as 16.11.04 CbParam.m_pArg = &ObdSize;
1964 // 09-dec-2004 r.d.: CbParam.m_pArg = &Size_p;
1965 pCbParam_p->m_pArg = &ObdSize;
1966 pCbParam_p->m_ObdEvent = kEplObdEvInitWrite;
1967 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
1968 pObdEntry->m_fpCallback, pCbParam_p);
1969 if (Ret != kEplSuccessful) {
1970 goto Exit;
1973 if (Size_p > ObdSize) {
1974 Ret = kEplObdValueLengthError;
1975 goto Exit;
1978 if (pSubEntry->m_Type == kEplObdTypVString) {
1979 if (((char *)pSrcData_p)[Size_p - 1] == '\0') { // last byte of source string contains null character
1981 // reserve one byte in destination for 0-termination
1982 Size_p -= 1;
1983 } else if (Size_p >= ObdSize) { // source string is not 0-terminated
1984 // and destination buffer is too short
1985 Ret = kEplObdValueLengthError;
1986 goto Exit;
1990 Ret = EplObdIsNumericalIntern(pSubEntry, &fEntryNumerical);
1991 if (Ret != kEplSuccessful) {
1992 goto Exit;
1995 if ((fEntryNumerical != FALSE)
1996 && (Size_p != ObdSize)) {
1997 // type is numerical, therefor size has to fit, but it does not.
1998 Ret = kEplObdValueLengthError;
1999 goto Exit;
2001 // use given size, because non-numerical objects can be written with shorter values
2002 ObdSize = Size_p;
2004 // set output parameters
2005 *pObdSize_p = ObdSize;
2006 *ppObdEntry_p = pObdEntry;
2007 *ppSubEntry_p = pSubEntry;
2008 *ppDstData_p = pDstData;
2010 // all checks are done
2011 // the caller may now convert the numerial source value to platform byte order in a temporary buffer
2013 Exit:
2015 return Ret;
2019 //---------------------------------------------------------------------------
2021 // Function: EplObdWriteEntryPost()
2023 // Description: Function finishes write of data to an OBD entry. Strings
2024 // are stored with added '\0' character.
2026 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
2027 // uiIndex_p = Index of the OD entry
2028 // uiSubIndex_p = Subindex of the OD Entry
2029 // pSrcData_p = Pointer to the data to write
2030 // Size_p = Size of the data in Byte
2032 // Return: tEplKernel = Errorcode
2035 // State:
2037 //---------------------------------------------------------------------------
2039 static tEplKernel EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p,
2040 tEplObdSubEntryPtr pSubEntry_p,
2041 tEplObdCbParam *pCbParam_p,
2042 void *pSrcData_p,
2043 void *pDstData_p,
2044 tEplObdSize ObdSize_p)
2047 tEplKernel Ret;
2049 // caller converted the source value to platform byte order
2050 // now the range of the value may be checked
2052 #if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
2054 // check data range
2055 Ret = EplObdCheckObjectRange(pSubEntry_p, pSrcData_p);
2056 if (Ret != kEplSuccessful) {
2057 goto Exit;
2060 #endif
2062 // now call user callback function to check value
2063 // write address of source data to structure of callback parameters
2064 // so callback function can check this data
2065 pCbParam_p->m_pArg = pSrcData_p;
2066 pCbParam_p->m_ObdEvent = kEplObdEvPreWrite;
2067 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
2068 pObdEntry_p->m_fpCallback, pCbParam_p);
2069 if (Ret != kEplSuccessful) {
2070 goto Exit;
2072 // copy object data to OBD
2073 EPL_MEMCPY(pDstData_p, pSrcData_p, ObdSize_p);
2075 // terminate string with 0
2076 if (pSubEntry_p->m_Type == kEplObdTypVString) {
2077 ((char *)pDstData_p)[ObdSize_p] = '\0';
2079 // write address of destination to structure of callback parameters
2080 // so callback function can change data subsequently
2081 pCbParam_p->m_pArg = pDstData_p;
2082 pCbParam_p->m_ObdEvent = kEplObdEvPostWrite;
2083 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
2084 pObdEntry_p->m_fpCallback, pCbParam_p);
2086 Exit:
2088 return Ret;
2092 //---------------------------------------------------------------------------
2094 // Function: EplObdGetObjectSize()
2096 // Description: function to get size of object
2097 // The function determines if an object type an fixed data type (BYTE, WORD, ...)
2098 // or non fixed object (string, domain). This information is used to decide
2099 // if download data are stored temporary or not. For objects with fixed data length
2100 // and types a value range checking can process.
2101 // For strings the function returns the whole object size not the
2102 // length of string.
2104 // Parameters: pSubIndexEntry_p
2106 // Return: tEplObdSize
2108 // State:
2110 //---------------------------------------------------------------------------
2112 static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p)
2115 tEplObdSize DataSize = 0;
2116 void *pData;
2118 switch (pSubIndexEntry_p->m_Type) {
2119 // -----------------------------------------------------------------
2120 case kEplObdTypBool:
2122 DataSize = 1;
2123 break;
2125 // -----------------------------------------------------------------
2126 // ObdTypes which has to be check because numerical values
2127 case kEplObdTypInt8:
2128 DataSize = sizeof(tEplObdInteger8);
2129 break;
2131 // -----------------------------------------------------------------
2132 case kEplObdTypUInt8:
2133 DataSize = sizeof(tEplObdUnsigned8);
2134 break;
2136 // -----------------------------------------------------------------
2137 case kEplObdTypInt16:
2138 DataSize = sizeof(tEplObdInteger16);
2139 break;
2141 // -----------------------------------------------------------------
2142 case kEplObdTypUInt16:
2143 DataSize = sizeof(tEplObdUnsigned16);
2144 break;
2146 // -----------------------------------------------------------------
2147 case kEplObdTypInt32:
2148 DataSize = sizeof(tEplObdInteger32);
2149 break;
2151 // -----------------------------------------------------------------
2152 case kEplObdTypUInt32:
2153 DataSize = sizeof(tEplObdUnsigned32);
2154 break;
2156 // -----------------------------------------------------------------
2157 case kEplObdTypReal32:
2158 DataSize = sizeof(tEplObdReal32);
2159 break;
2161 // -----------------------------------------------------------------
2162 // ObdTypes which has to be not checked because not NUM values
2163 case kEplObdTypDomain:
2165 pData = (void *)pSubIndexEntry_p->m_pCurrent;
2166 if ((void *)pData != (void *)NULL) {
2167 DataSize = ((tEplObdVarEntry *) pData)->m_Size;
2169 break;
2171 // -----------------------------------------------------------------
2172 case kEplObdTypVString:
2173 //case kEplObdTypUString:
2175 // If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING
2176 // then the current pointer is always NULL. The function
2177 // returns the length of default string.
2178 pData = (void *)pSubIndexEntry_p->m_pCurrent;
2179 if ((void *)pData != (void *)NULL) {
2180 // The max. size of strings defined by STRING-Macro is stored in
2181 // tEplObdVString of current value.
2182 // (types tEplObdVString, tEplObdOString and tEplObdUString has the same members)
2183 DataSize = ((tEplObdVString *) pData)->m_Size;
2184 } else {
2185 // The current position is not decleared. The string
2186 // is located in ROM, therefor use default pointer.
2187 pData = (void *)pSubIndexEntry_p->m_pDefault;
2188 if ((const void *)pData != (const void *)NULL) {
2189 // The max. size of strings defined by STRING-Macro is stored in
2190 // tEplObdVString of default value.
2191 DataSize = ((const tEplObdVString *)pData)->m_Size;
2195 break;
2197 // -----------------------------------------------------------------
2198 case kEplObdTypOString:
2200 pData = (void *)pSubIndexEntry_p->m_pCurrent;
2201 if ((void *)pData != (void *)NULL) {
2202 // The max. size of strings defined by STRING-Macro is stored in
2203 // tEplObdVString of current value.
2204 // (types tEplObdVString, tEplObdOString and tEplObdUString has the same members)
2205 DataSize = ((tEplObdOString *) pData)->m_Size;
2206 } else {
2207 // The current position is not decleared. The string
2208 // is located in ROM, therefor use default pointer.
2209 pData = (void *)pSubIndexEntry_p->m_pDefault;
2210 if ((const void *)pData != (const void *)NULL) {
2211 // The max. size of strings defined by STRING-Macro is stored in
2212 // tEplObdVString of default value.
2213 DataSize = ((const tEplObdOString *)pData)->m_Size;
2216 break;
2218 // -----------------------------------------------------------------
2219 case kEplObdTypInt24:
2220 case kEplObdTypUInt24:
2222 DataSize = 3;
2223 break;
2225 // -----------------------------------------------------------------
2226 case kEplObdTypInt40:
2227 case kEplObdTypUInt40:
2229 DataSize = 5;
2230 break;
2232 // -----------------------------------------------------------------
2233 case kEplObdTypInt48:
2234 case kEplObdTypUInt48:
2236 DataSize = 6;
2237 break;
2239 // -----------------------------------------------------------------
2240 case kEplObdTypInt56:
2241 case kEplObdTypUInt56:
2243 DataSize = 7;
2244 break;
2246 // -----------------------------------------------------------------
2247 case kEplObdTypInt64:
2248 case kEplObdTypUInt64:
2249 case kEplObdTypReal64:
2251 DataSize = 8;
2252 break;
2254 // -----------------------------------------------------------------
2255 case kEplObdTypTimeOfDay:
2256 case kEplObdTypTimeDiff:
2258 DataSize = 6;
2259 break;
2261 // -----------------------------------------------------------------
2262 default:
2263 break;
2266 return DataSize;
2269 //---------------------------------------------------------------------------
2271 // Function: EplObdGetObjectDefaultPtr()
2273 // Description: function to get the default pointer (type specific)
2275 // Parameters: pSubIndexEntry_p = pointer to subindex structure
2277 // Returns: (void *) = pointer to default value
2279 // State:
2281 //---------------------------------------------------------------------------
2283 static void *EplObdGetObjectDefaultPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
2286 void *pDefault;
2287 tEplObdType Type;
2289 ASSERTMSG(pSubIndexEntry_p != NULL,
2290 "EplObdGetObjectDefaultPtr(): pointer to SubEntry not valid!\n");
2292 // get address to default data from default pointer
2293 pDefault = pSubIndexEntry_p->m_pDefault;
2294 if (pDefault != NULL) {
2295 // there are some special types, whose default pointer always is NULL or has to get from other structure
2296 // get type from subindex structure
2297 Type = pSubIndexEntry_p->m_Type;
2299 // check if object type is a string value
2300 if ((Type == kEplObdTypVString) /* ||
2301 (Type == kEplObdTypUString) */ ) {
2303 // EPL_OBD_SUBINDEX_RAM_VSTRING
2304 // tEplObdSize m_Size; --> size of default string
2305 // char * m_pDefString; --> pointer to default string
2306 // char * m_pString; --> pointer to string in RAM
2308 pDefault =
2309 (void *)((tEplObdVString *) pDefault)->m_pString;
2310 } else if (Type == kEplObdTypOString) {
2311 pDefault =
2312 (void *)((tEplObdOString *) pDefault)->m_pString;
2316 return pDefault;
2320 //---------------------------------------------------------------------------
2322 // Function: EplObdGetVarEntry()
2324 // Description: gets a variable entry of an object
2326 // Parameters: pSubindexEntry_p
2327 // ppVarEntry_p
2329 // Return: tCopKernel
2331 // State:
2333 //---------------------------------------------------------------------------
2335 static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p,
2336 tEplObdVarEntry **ppVarEntry_p)
2339 tEplKernel Ret = kEplObdVarEntryNotExist;
2341 ASSERT(ppVarEntry_p != NULL); // is not allowed to be NULL
2342 ASSERT(pSubindexEntry_p != NULL);
2344 // check VAR-Flag - only this object points to variables
2345 if ((pSubindexEntry_p->m_Access & kEplObdAccVar) != 0) {
2346 // check if object is an array
2347 if ((pSubindexEntry_p->m_Access & kEplObdAccArray) != 0) {
2348 *ppVarEntry_p = &((tEplObdVarEntry *)pSubindexEntry_p->m_pCurrent)[pSubindexEntry_p->m_uiSubIndex - 1];
2349 } else {
2350 *ppVarEntry_p = (tEplObdVarEntry *)pSubindexEntry_p->m_pCurrent;
2353 Ret = kEplSuccessful;
2356 return Ret;
2360 //---------------------------------------------------------------------------
2362 // Function: EplObdGetEntry()
2364 // Description: gets a index entry from OD
2366 // Parameters: uiIndex_p = Index number
2367 // uiSubindex_p = Subindex number
2368 // ppObdEntry_p = pointer to the pointer to the entry
2369 // ppObdSubEntry_p = pointer to the pointer to the subentry
2371 // Return: tEplKernel
2374 // State:
2376 //---------------------------------------------------------------------------
2378 static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_
2379 unsigned int uiIndex_p,
2380 unsigned int uiSubindex_p,
2381 tEplObdEntryPtr * ppObdEntry_p,
2382 tEplObdSubEntryPtr * ppObdSubEntry_p)
2385 tEplObdEntryPtr pObdEntry;
2386 tEplObdCbParam CbParam;
2387 tEplKernel Ret;
2389 // check for all API function if instance is valid
2390 EPL_MCO_CHECK_INSTANCE_STATE();
2392 //------------------------------------------------------------------------
2393 // get address of entry of index
2394 Ret =
2395 EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam), uiIndex_p,
2396 &pObdEntry);
2397 if (Ret != kEplSuccessful) {
2398 goto Exit;
2400 //------------------------------------------------------------------------
2401 // get address of entry of subindex
2402 Ret = EplObdGetSubindexIntern(pObdEntry, uiSubindex_p, ppObdSubEntry_p);
2403 if (Ret != kEplSuccessful) {
2404 goto Exit;
2406 //------------------------------------------------------------------------
2407 // call callback function to inform user/stack that an object will be searched
2408 // if the called module returnes an error then we abort the searching with kEplObdIndexNotExist
2409 CbParam.m_uiIndex = uiIndex_p;
2410 CbParam.m_uiSubIndex = uiSubindex_p;
2411 CbParam.m_pArg = NULL;
2412 CbParam.m_ObdEvent = kEplObdEvCheckExist;
2413 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
2414 pObdEntry->m_fpCallback, &CbParam);
2415 if (Ret != kEplSuccessful) {
2416 Ret = kEplObdIndexNotExist;
2417 goto Exit;
2419 //------------------------------------------------------------------------
2420 // it is allowed to set ppObdEntry_p to NULL
2421 // if so, no address will be written to calling function
2422 if (ppObdEntry_p != NULL) {
2423 *ppObdEntry_p = pObdEntry;
2426 Exit:
2428 return Ret;
2432 //---------------------------------------------------------------------------
2434 // Function: EplObdGetObjectCurrentPtr()
2436 // Description: function to get Current pointer (type specific)
2438 // Parameters: pSubIndexEntry_p
2440 // Return: void *
2442 // State:
2444 //---------------------------------------------------------------------------
2446 static void *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
2449 void *pData;
2450 unsigned int uiArrayIndex;
2451 tEplObdSize Size;
2453 pData = pSubIndexEntry_p->m_pCurrent;
2455 // check if constant object
2456 if (pData != NULL) {
2457 // check if object is an array
2458 if ((pSubIndexEntry_p->m_Access & kEplObdAccArray) != 0) {
2459 // calculate correct data pointer
2460 uiArrayIndex = pSubIndexEntry_p->m_uiSubIndex - 1;
2461 if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0) {
2462 Size = sizeof(tEplObdVarEntry);
2463 } else {
2464 Size = EplObdGetObjectSize(pSubIndexEntry_p);
2466 pData = ((BYTE *) pData) + (Size * uiArrayIndex);
2468 // check if VarEntry
2469 if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0) {
2470 // The data pointer is stored in VarEntry->pData
2471 pData = ((tEplObdVarEntry *) pData)->m_pData;
2473 // the default pointer is stored for strings in tEplObdVString
2474 else if ((pSubIndexEntry_p->m_Type == kEplObdTypVString) /* ||
2475 (pSubIndexEntry_p->m_Type == kEplObdTypUString) */
2477 pData = (void *)((tEplObdVString *)pData)->m_pString;
2478 } else if (pSubIndexEntry_p->m_Type == kEplObdTypOString) {
2479 pData =
2480 (void *)((tEplObdOString *)pData)->m_pString;
2484 return pData;
2488 //---------------------------------------------------------------------------
2490 // Function: EplObdGetIndexIntern()
2492 // Description: gets a index entry from OD
2494 // Parameters: pInitParam_p
2495 // uiIndex_p
2496 // ppObdEntry_p
2498 // Return: tEplKernel
2500 // State:
2502 //---------------------------------------------------------------------------
2504 static tEplKernel EplObdGetIndexIntern(tEplObdInitParam *pInitParam_p,
2505 unsigned int uiIndex_p,
2506 tEplObdEntryPtr * ppObdEntry_p)
2509 tEplObdEntryPtr pObdEntry;
2510 tEplKernel Ret;
2511 unsigned int uiIndex;
2513 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
2515 unsigned int nLoop;
2517 // if user OD is used then objekts also has to be searched in user OD
2518 // there is less code need if we do this in a loop
2519 nLoop = 2;
2521 #endif
2523 ASSERTMSG(ppObdEntry_p != NULL,
2524 "EplObdGetIndexIntern(): pointer to index entry is NULL!\n");
2526 Ret = kEplObdIndexNotExist;
2528 // get start address of OD part
2529 // start address depends on object index because
2530 // object dictionary is divided in 3 parts
2531 if ((uiIndex_p >= 0x1000) && (uiIndex_p < 0x2000)) {
2532 pObdEntry = pInitParam_p->m_pPart;
2533 } else if ((uiIndex_p >= 0x2000) && (uiIndex_p < 0x6000)) {
2534 pObdEntry = pInitParam_p->m_pManufacturerPart;
2536 // index range 0xA000 to 0xFFFF is reserved for DSP-405
2537 // DS-301 defines that range 0x6000 to 0x9FFF (!!!) is stored if "store" was written to 0x1010/3.
2538 // Therefore default configuration is OBD_INCLUDE_A000_TO_DEVICE_PART = FALSE.
2539 // But a CANopen Application which does not implement dynamic OD or user-OD but wants to use static objets 0xA000...
2540 // should set OBD_INCLUDE_A000_TO_DEVICE_PART to TRUE.
2542 #if (EPL_OBD_INCLUDE_A000_TO_DEVICE_PART == FALSE)
2543 else if ((uiIndex_p >= 0x6000) && (uiIndex_p < 0x9FFF))
2544 #else
2545 else if ((uiIndex_p >= 0x6000) && (uiIndex_p < 0xFFFF))
2546 #endif
2548 pObdEntry = pInitParam_p->m_pDevicePart;
2551 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
2553 // if index does not match in static OD then index only has to be searched in user OD
2554 else {
2555 // begin from first entry of user OD part
2556 pObdEntry = pInitParam_p->m_pUserPart;
2558 // no user OD is available
2559 if (pObdEntry == NULL) {
2560 goto Exit;
2562 // loop must only run once
2563 nLoop = 1;
2566 do {
2568 #else
2570 // no user OD is available
2571 // so other object can be found in OD
2572 else {
2573 Ret = kEplObdIllegalPart;
2574 goto Exit;
2577 #endif
2579 // note:
2580 // The end of Index table is marked with m_uiIndex = 0xFFFF.
2581 // If this function will be called with wIndex_p = 0xFFFF, entry
2582 // should not be found. Therefor it is important to use
2583 // while{} instead of do{}while !!!
2585 // get first index of index table
2586 uiIndex = pObdEntry->m_uiIndex;
2588 // search Index in OD part
2589 while (uiIndex != EPL_OBD_TABLE_INDEX_END) {
2590 // go to the end of this function if index is found
2591 if (uiIndex_p == uiIndex) {
2592 // write address of OD entry to calling function
2593 *ppObdEntry_p = pObdEntry;
2594 Ret = kEplSuccessful;
2595 goto Exit;
2597 // objects are sorted in OD
2598 // if the current index in OD is greater than the index which is to search then break loop
2599 // in this case user OD has to be search too
2600 if (uiIndex_p < uiIndex) {
2601 break;
2603 // next entry in index table
2604 pObdEntry++;
2606 // get next index of index table
2607 uiIndex = pObdEntry->m_uiIndex;
2610 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
2612 // begin from first entry of user OD part
2613 pObdEntry = pInitParam_p->m_pUserPart;
2615 // no user OD is available
2616 if (pObdEntry == NULL) {
2617 goto Exit;
2619 // switch next loop for user OD
2620 nLoop--;
2624 while (nLoop > 0) ;
2626 #endif
2628 // in this line Index was not found
2630 Exit:
2632 return Ret;
2636 //---------------------------------------------------------------------------
2638 // Function: EplObdGetSubindexIntern()
2640 // Description: gets a subindex entry from a index entry
2642 // Parameters: pObdEntry_p
2643 // bSubIndex_p
2644 // ppObdSubEntry_p
2646 // Return: tEplKernel
2648 // State:
2650 //---------------------------------------------------------------------------
2652 static tEplKernel EplObdGetSubindexIntern(tEplObdEntryPtr pObdEntry_p,
2653 unsigned int uiSubIndex_p,
2654 tEplObdSubEntryPtr * ppObdSubEntry_p)
2657 tEplObdSubEntryPtr pSubEntry;
2658 unsigned int nSubIndexCount;
2659 tEplKernel Ret;
2661 ASSERTMSG(pObdEntry_p != NULL,
2662 "EplObdGetSubindexIntern(): pointer to index is NULL!\n");
2663 ASSERTMSG(ppObdSubEntry_p != NULL,
2664 "EplObdGetSubindexIntern(): pointer to subindex is NULL!\n");
2666 Ret = kEplObdSubindexNotExist;
2668 // get start address of subindex table and count of subindices
2669 pSubEntry = pObdEntry_p->m_pSubIndex;
2670 nSubIndexCount = pObdEntry_p->m_uiCount;
2671 ASSERTMSG((pSubEntry != NULL) && (nSubIndexCount > 0), "ObdGetSubindexIntern(): invalid subindex table within index table!\n"); // should never be NULL
2673 // search subindex in subindex table
2674 while (nSubIndexCount > 0) {
2675 // check if array is found
2676 if ((pSubEntry->m_Access & kEplObdAccArray) != 0) {
2677 // check if subindex is in range
2678 if (uiSubIndex_p < pObdEntry_p->m_uiCount) {
2679 // update subindex number (subindex entry of an array is always in RAM !!!)
2680 pSubEntry->m_uiSubIndex = uiSubIndex_p;
2681 *ppObdSubEntry_p = pSubEntry;
2682 Ret = kEplSuccessful;
2683 goto Exit;
2686 // go to the end of this function if subindex is found
2687 else if (uiSubIndex_p == pSubEntry->m_uiSubIndex) {
2688 *ppObdSubEntry_p = pSubEntry;
2689 Ret = kEplSuccessful;
2690 goto Exit;
2692 // objects are sorted in OD
2693 // if the current subindex in OD is greater than the subindex which is to search then break loop
2694 // in this case user OD has to be search too
2695 if (uiSubIndex_p < pSubEntry->m_uiSubIndex) {
2696 break;
2699 pSubEntry++;
2700 nSubIndexCount--;
2703 // in this line SubIndex was not fount
2705 Exit:
2707 return Ret;
2711 //---------------------------------------------------------------------------
2713 // Function: EplObdSetStoreLoadObjCallback()
2715 // Description: function set address to callbackfunction for command Store and Load
2717 // Parameters: fpCallback_p
2719 // Return: tEplKernel
2721 // State:
2723 //---------------------------------------------------------------------------
2724 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
2725 EPLDLLEXPORT tEplKernel EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdStoreLoadObjCallback fpCallback_p)
2728 EPL_MCO_CHECK_INSTANCE_STATE();
2730 // set new address of callback function
2731 EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) = fpCallback_p;
2733 return kEplSuccessful;
2736 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
2738 //---------------------------------------------------------------------------
2740 // Function: EplObdAccessOdPartIntern()
2742 // Description: runs through OD and executes a job
2744 // Parameters: CurrentOdPart_p
2745 // pObdEnty_p
2746 // Direction_p = what is to do (load values from flash or EEPROM, store, ...)
2748 // Return: tEplKernel
2750 // State:
2752 //---------------------------------------------------------------------------
2754 static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
2755 tEplObdPart CurrentOdPart_p,
2756 tEplObdEntryPtr pObdEnty_p,
2757 tEplObdDir Direction_p)
2760 tEplObdSubEntryPtr pSubIndex;
2761 unsigned int nSubIndexCount;
2762 tEplObdAccess Access;
2763 void *pDstData;
2764 void *pDefault;
2765 tEplObdSize ObjSize;
2766 tEplKernel Ret;
2767 tEplObdCbStoreParam CbStore;
2768 tEplObdVarEntry *pVarEntry;
2770 ASSERT(pObdEnty_p != NULL);
2772 Ret = kEplSuccessful;
2774 // prepare structure for STORE RESTORE callback function
2775 CbStore.m_bCurrentOdPart = (BYTE) CurrentOdPart_p;
2776 CbStore.m_pData = NULL;
2777 CbStore.m_ObjSize = 0;
2779 // command of first action depends on direction to access
2780 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
2781 if (Direction_p == kEplObdDirLoad) {
2782 CbStore.m_bCommand = (BYTE) kEplObdCommOpenRead;
2784 // call callback function for previous command
2785 Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore);
2786 if (Ret != kEplSuccessful) {
2787 goto Exit;
2789 // set command for index and subindex loop
2790 CbStore.m_bCommand = (BYTE) kEplObdCommReadObj;
2791 } else if (Direction_p == kEplObdDirStore) {
2792 CbStore.m_bCommand = (BYTE) kEplObdCommOpenWrite;
2794 // call callback function for previous command
2795 Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore);
2796 if (Ret != kEplSuccessful) {
2797 goto Exit;
2799 // set command for index and subindex loop
2800 CbStore.m_bCommand = (BYTE) kEplObdCommWriteObj;
2802 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
2804 // we should not restore the OD values here
2805 // the next NMT command "Reset Node" or "Reset Communication" resets the OD data
2806 if (Direction_p != kEplObdDirRestore) {
2807 // walk through OD part till end is found
2808 while (pObdEnty_p->m_uiIndex != EPL_OBD_TABLE_INDEX_END) {
2809 // get address to subindex table and count of subindices
2810 pSubIndex = pObdEnty_p->m_pSubIndex;
2811 nSubIndexCount = pObdEnty_p->m_uiCount;
2812 ASSERT((pSubIndex != NULL) && (nSubIndexCount > 0)); // should never be NULL
2814 // walk through subindex table till all subinices were restored
2815 while (nSubIndexCount != 0) {
2816 Access = (tEplObdAccess) pSubIndex->m_Access;
2818 // get pointer to current and default data
2819 pDefault = EplObdGetObjectDefaultPtr(pSubIndex);
2820 pDstData = EplObdGetObjectCurrentPtr(pSubIndex);
2822 // NOTE (for kEplObdTypVString):
2823 // The function returnes the max. number of bytes for a
2824 // current string.
2825 // r.d.: For stings the default-size will be read in other lines following (kEplObdDirInit).
2826 ObjSize = EplObdGetObjectSize(pSubIndex);
2828 // switch direction of OD access
2829 switch (Direction_p) {
2830 // --------------------------------------------------------------------------
2831 // VarEntry structures has to be initialized
2832 case kEplObdDirInit:
2834 // If VAR-Flag is set, m_pCurrent means not address of data
2835 // but address of tEplObdVarEntry. Address of data has to be get from
2836 // this structure.
2837 if ((Access & kEplObdAccVar) != 0) {
2838 EplObdGetVarEntry(pSubIndex,
2839 &pVarEntry);
2840 EplObdInitVarEntry(pVarEntry,
2841 pSubIndex->
2842 m_Type,
2843 ObjSize);
2845 if ((Access & kEplObdAccArray) == 0)
2847 EplObdInitVarEntry (pSubIndex->m_pCurrent, pSubIndex->m_Type, ObjSize);
2849 else
2851 EplObdInitVarEntry ((tEplObdVarEntry *) (((BYTE *) pSubIndex->m_pCurrent) + (sizeof (tEplObdVarEntry) * pSubIndex->m_uiSubIndex)),
2852 pSubIndex->m_Type, ObjSize);
2855 // at this time no application variable is defined !!!
2856 // therefore data can not be copied.
2857 break;
2858 } else if (pSubIndex->m_Type ==
2859 kEplObdTypVString) {
2860 // If pointer m_pCurrent is not equal to NULL then the
2861 // string was defined with EPL_OBD_SUBINDEX_RAM_VSTRING. The current
2862 // pointer points to struct tEplObdVString located in MEM.
2863 // The element size includes the max. number of
2864 // bytes. The element m_pString includes the pointer
2865 // to string in MEM. The memory location of default string
2866 // must be copied to memory location of current string.
2868 pDstData =
2869 pSubIndex->m_pCurrent;
2870 if (pDstData != NULL) {
2871 // 08-dec-2004: code optimization !!!
2872 // entries ((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_pString
2873 // and ((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_Size were read
2874 // twice. thats not necessary!
2876 // For copying data we have to set the destination pointer to the real RAM string. This
2877 // pointer to RAM string is located in default string info structure. (translated r.d.)
2878 pDstData = (void *)((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_pString;
2879 ObjSize = ((tEplObdVStringDef *)pSubIndex->m_pDefault)->m_Size;
2881 ((tEplObdVString *)pSubIndex->m_pCurrent)->m_pString = pDstData;
2882 ((tEplObdVString *)pSubIndex->m_pCurrent)->m_Size = ObjSize;
2885 } else if (pSubIndex->m_Type ==
2886 kEplObdTypOString) {
2887 pDstData =
2888 pSubIndex->m_pCurrent;
2889 if (pDstData != NULL) {
2890 // 08-dec-2004: code optimization !!!
2891 // entries ((tEplObdOStringDef*) pSubIndex->m_pDefault)->m_pString
2892 // and ((tEplObdOStringDef*) pSubIndex->m_pDefault)->m_Size were read
2893 // twice. thats not necessary!
2895 // For copying data we have to set the destination pointer to the real RAM string. This
2896 // pointer to RAM string is located in default string info structure. (translated r.d.)
2897 pDstData = (void *)((tEplObdOStringDef *) pSubIndex->m_pDefault)->m_pString;
2898 ObjSize = ((tEplObdOStringDef *)pSubIndex->m_pDefault)->m_Size;
2900 ((tEplObdOString *)pSubIndex->m_pCurrent)->m_pString = pDstData;
2901 ((tEplObdOString *)pSubIndex->m_pCurrent)->m_Size = ObjSize;
2906 // no break !! because copy of data has to done too.
2908 // --------------------------------------------------------------------------
2909 // all objects has to be restored with default values
2910 case kEplObdDirRestore:
2912 // 09-dec-2004 r.d.: optimization! the same code for kEplObdDirRestore and kEplObdDirLoad
2913 // is replaced to function ObdCopyObjectData() with a new parameter.
2915 // restore object data for init phase
2916 EplObdCopyObjectData(pDstData, pDefault,
2917 ObjSize,
2918 pSubIndex->m_Type);
2919 break;
2921 // --------------------------------------------------------------------------
2922 // objects with attribute kEplObdAccStore has to be load from EEPROM or from a file
2923 case kEplObdDirLoad:
2925 // restore object data for init phase
2926 EplObdCopyObjectData(pDstData, pDefault,
2927 ObjSize,
2928 pSubIndex->m_Type);
2930 // no break !! because callback function has to be called too.
2932 // --------------------------------------------------------------------------
2933 // objects with attribute kEplObdAccStore has to be stored in EEPROM or in a file
2934 case kEplObdDirStore:
2936 // when attribute kEplObdAccStore is set, then call callback function
2937 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
2938 if ((Access & kEplObdAccStore) != 0) {
2939 // fill out data pointer and size of data
2940 CbStore.m_pData = pDstData;
2941 CbStore.m_ObjSize = ObjSize;
2943 // call callback function for read or write object
2944 Ret =
2945 ObdCallStoreCallback
2946 (EPL_MCO_INSTANCE_PTR_ &
2947 CbStore);
2948 if (Ret != kEplSuccessful) {
2949 goto Exit;
2952 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
2953 break;
2955 // --------------------------------------------------------------------------
2956 // if OD Builder key has to be checked no access to subindex and data should be made
2957 case kEplObdDirOBKCheck:
2959 // no break !! because we want to break the second loop too.
2961 // --------------------------------------------------------------------------
2962 // unknown Direction
2963 default:
2965 // so we can break the second loop earler
2966 nSubIndexCount = 1;
2967 break;
2970 nSubIndexCount--;
2972 // next subindex entry
2973 if ((Access & kEplObdAccArray) == 0) {
2974 pSubIndex++;
2975 if ((nSubIndexCount > 0)
2977 ((pSubIndex->
2978 m_Access & kEplObdAccArray) !=
2979 0)) {
2980 // next subindex points to an array
2981 // reset subindex number
2982 pSubIndex->m_uiSubIndex = 1;
2984 } else {
2985 if (nSubIndexCount > 0) {
2986 // next subindex points to an array
2987 // increment subindex number
2988 pSubIndex->m_uiSubIndex++;
2993 // next index entry
2994 pObdEnty_p++;
2997 // -----------------------------------------------------------------------------------------
2998 // command of last action depends on direction to access
2999 if (Direction_p == kEplObdDirOBKCheck) {
3001 goto Exit;
3003 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
3004 else {
3005 if (Direction_p == kEplObdDirLoad) {
3006 CbStore.m_bCommand = (BYTE) kEplObdCommCloseRead;
3007 } else if (Direction_p == kEplObdDirStore) {
3008 CbStore.m_bCommand = (BYTE) kEplObdCommCloseWrite;
3009 } else if (Direction_p == kEplObdDirRestore) {
3010 CbStore.m_bCommand = (BYTE) kEplObdCommClear;
3011 } else {
3012 goto Exit;
3015 // call callback function for last command
3016 Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore);
3018 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
3020 // goto Exit;
3022 Exit:
3024 return Ret;
3028 // ----------------------------------------------------------------------------
3029 // Function: EplObdCopyObjectData()
3031 // Description: checks pointers to object data and copy them from source to destination
3033 // Parameters: pDstData_p = destination pointer
3034 // pSrcData_p = source pointer
3035 // ObjSize_p = size of object
3036 // ObjType_p =
3038 // Returns: tEplKernel = error code
3039 // ----------------------------------------------------------------------------
3041 static void EplObdCopyObjectData(void *pDstData_p,
3042 void *pSrcData_p,
3043 tEplObdSize ObjSize_p, tEplObdType ObjType_p)
3046 tEplObdSize StrSize = 0;
3048 // it is allowed to set default and current address to NULL (nothing to copy)
3049 if (pDstData_p != NULL) {
3051 if (ObjType_p == kEplObdTypVString) {
3052 // The function calculates the really number of characters of string. The
3053 // object entry size can be bigger as string size of default string.
3054 // The '\0'-termination is included. A string with no characters has a
3055 // size of 1.
3056 StrSize =
3057 EplObdGetStrLen((void *)pSrcData_p, ObjSize_p,
3058 kEplObdTypVString);
3060 // If the string length is greater than or equal to the entry size in OD then only copy
3061 // entry size - 1 and always set the '\0'-termination.
3062 if (StrSize >= ObjSize_p) {
3063 StrSize = ObjSize_p - 1;
3067 if (pSrcData_p != NULL) {
3068 // copy data
3069 EPL_MEMCPY(pDstData_p, pSrcData_p, ObjSize_p);
3071 if (ObjType_p == kEplObdTypVString) {
3072 ((char *)pDstData_p)[StrSize] = '\0';
3079 //---------------------------------------------------------------------------
3081 // Function: EplObdIsNumericalIntern()
3083 // Description: function checks if a entry is numerical or not
3086 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
3087 // uiIndex_p = Index
3088 // uiSubIndex_p = Subindex
3089 // pfEntryNumerical_p = pointer to BOOL for returnvalue
3090 // -> TRUE if entry a numerical value
3091 // -> FALSE if entry not a numerical value
3093 // Return: tEplKernel = Errorcode
3095 // State:
3097 //---------------------------------------------------------------------------
3098 static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p,
3099 BOOL * pfEntryNumerical_p)
3101 tEplKernel Ret = kEplSuccessful;
3103 // get Type
3104 if ((pObdSubEntry_p->m_Type == kEplObdTypVString)
3105 || (pObdSubEntry_p->m_Type == kEplObdTypOString)
3106 || (pObdSubEntry_p->m_Type == kEplObdTypDomain)) { // not numerical types
3107 *pfEntryNumerical_p = FALSE;
3108 } else { // numerical types
3109 *pfEntryNumerical_p = TRUE;
3112 return Ret;
3116 // -------------------------------------------------------------------------
3117 // function to classify object type (fixed/non fixed)
3118 // -------------------------------------------------------------------------
3120 // ----------------------------------------------------------------------------
3121 // Function: EplObdCallStoreCallback()
3123 // Description: checks address to callback function and calles it when unequal
3124 // to NULL
3126 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = (instance pointer)
3127 // pCbStoreParam_p = address to callback parameters
3129 // Returns: tEplKernel = error code
3130 // ----------------------------------------------------------------------------
3131 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
3132 static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_
3133 tEplObdCbStoreParam *
3134 pCbStoreParam_p)
3137 tEplKernel Ret = kEplSuccessful;
3139 ASSERT(pCbStoreParam_p != NULL);
3141 // check if function pointer is NULL - if so, no callback should be called
3142 if (EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) != NULL) {
3143 Ret =
3144 EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback)
3145 (EPL_MCO_INSTANCE_PARAM_IDX_()
3146 pCbStoreParam_p);
3149 return Ret;
3152 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
3153 //---------------------------------------------------------------------------
3155 // Function: EplObdGetObjectDataPtrIntern()
3157 // Description: Function gets the data pointer of an object.
3158 // It returnes the current data pointer. But if object is an
3159 // constant object it returnes the default pointer.
3161 // Parameters: pSubindexEntry_p = pointer to subindex entry
3163 // Return: void * = pointer to object data
3165 // State:
3167 //---------------------------------------------------------------------------
3169 void *EplObdGetObjectDataPtrIntern(tEplObdSubEntryPtr pSubindexEntry_p)
3172 void *pData;
3173 tEplObdAccess Access;
3175 ASSERTMSG(pSubindexEntry_p != NULL,
3176 "EplObdGetObjectDataPtrIntern(): pointer to SubEntry not valid!\n");
3178 // there are are some objects whose data pointer has to get from other structure
3179 // get access type for this object
3180 Access = pSubindexEntry_p->m_Access;
3182 // If object has access type = const,
3183 // for data only exists default values.
3184 if ((Access & kEplObdAccConst) != 0) {
3185 // The pointer to defualt value can be received from ObdGetObjectDefaultPtr()
3186 pData = ((void *)EplObdGetObjectDefaultPtr(pSubindexEntry_p));
3187 } else {
3188 // The pointer to current value can be received from ObdGetObjectCurrentPtr()
3189 pData = ((void *)EplObdGetObjectCurrentPtr(pSubindexEntry_p));
3192 return pData;
3195 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
3196 // EOF