Staging: epl: remove NEAR
[wandboard.git] / drivers / staging / epl / EplObd.c
bloba853a02601a6a43556b3cb7a2354ccb2a6766308
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 INST_FAR 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 MEM*
124 EPL_MCO_DECL_INSTANCE_VAR()
126 BYTE MEM 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 MEM * 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 MEM ** 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 MEM * 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 MEM *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p);
175 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
177 static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_
178 tEplObdCbStoreParam MEM *
179 pCbStoreParam_p);
181 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
183 static void EplObdCopyObjectData(void MEM * pDstData_p,
184 void *pSrcData_p,
185 tEplObdSize ObjSize_p, tEplObdType ObjType_p);
187 void *EplObdGetObjectDataPtrIntern(tEplObdSubEntryPtr pSubindexEntry_p);
189 static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p,
190 BOOL * pfEntryNumerical_p);
192 static tEplKernel EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
193 unsigned int uiSubIndex_p,
194 void *pSrcData_p,
195 void **ppDstData_p,
196 tEplObdSize Size_p,
197 tEplObdEntryPtr *ppObdEntry_p,
198 tEplObdSubEntryPtr *ppSubEntry_p,
199 tEplObdCbParam MEM *pCbParam_p,
200 tEplObdSize *pObdSize_p);
202 static tEplKernel EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p,
203 tEplObdSubEntryPtr pSubEntry_p,
204 tEplObdCbParam MEM *pCbParam_p,
205 void *pSrcData_p,
206 void *pDstData_p,
207 tEplObdSize ObdSize_p);
209 //=========================================================================//
210 // //
211 // P U B L I C F U N C T I O N S //
212 // //
213 //=========================================================================//
215 //---------------------------------------------------------------------------
217 // Function: EplObdInit()
219 // Description: initializes the first instance
221 // Parameters: pInitParam_p = init parameter
223 // Return: tEplKernel = errorcode
225 // State:
227 //---------------------------------------------------------------------------
229 EPLDLLEXPORT tEplKernel EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam MEM *pInitParam_p)
232 tEplKernel Ret;
233 EPL_MCO_DELETE_INSTANCE_TABLE();
235 if (pInitParam_p == NULL) {
236 Ret = kEplSuccessful;
237 goto Exit;
240 Ret = EplObdAddInstance(EPL_MCO_PTR_INSTANCE_PTR_ pInitParam_p);
242 Exit:
243 return Ret;
247 //---------------------------------------------------------------------------
249 // Function: EplObdAddInstance()
251 // Description: adds a new instance
253 // Parameters: pInitParam_p
255 // Return: tEplKernel
257 // State:
259 //---------------------------------------------------------------------------
261 EPLDLLEXPORT tEplKernel EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam MEM *pInitParam_p)
264 EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplKernel Ret;
266 // check if pointer to instance pointer valid
267 // get free instance and set the globale instance pointer
268 // set also the instance addr to parameterlist
269 EPL_MCO_CHECK_PTR_INSTANCE_PTR();
270 EPL_MCO_GET_FREE_INSTANCE_PTR();
271 EPL_MCO_SET_PTR_INSTANCE_PTR();
273 // save init parameters
274 EPL_MEMCPY(&EPL_MCO_GLB_VAR(m_ObdInitParam), pInitParam_p,
275 sizeof(tEplObdInitParam));
277 // clear callback function for command LOAD and STORE
278 EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) = NULL;
280 // sign instance as used
281 EPL_MCO_WRITE_INSTANCE_STATE(kStateUsed);
283 // initialize object dictionary
284 // so all all VarEntries will be initialized to trash object and default values will be set to current data
285 Ret = EplObdAccessOdPart(EPL_MCO_INSTANCE_PTR_
286 kEplObdPartAll, kEplObdDirInit);
288 return Ret;
292 //---------------------------------------------------------------------------
294 // Function: EplObdDeleteInstance()
296 // Description: delete instance
298 // Parameters: EPL_MCO_DECL_INSTANCE_PTR
300 // Return: tEplKernel
302 // State:
304 //---------------------------------------------------------------------------
305 #if (EPL_USE_DELETEINST_FUNC != FALSE)
306 EPLDLLEXPORT tEplKernel EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR)
308 // check for all API function if instance is valid
309 EPL_MCO_CHECK_INSTANCE_STATE();
311 // sign instance as unused
312 EPL_MCO_WRITE_INSTANCE_STATE(kStateUnused);
314 return kEplSuccessful;
317 #endif // (EPL_USE_DELETEINST_FUNC != FALSE)
319 //---------------------------------------------------------------------------
321 // Function: EplObdWriteEntry()
323 // Description: Function writes data to an OBD entry. Strings
324 // are stored with added '\0' character.
326 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
327 // uiIndex_p = Index of the OD entry
328 // uiSubIndex_p = Subindex of the OD Entry
329 // pSrcData_p = Pointer to the data to write
330 // Size_p = Size of the data in Byte
332 // Return: tEplKernel = Errorcode
335 // State:
337 //---------------------------------------------------------------------------
339 EPLDLLEXPORT tEplKernel EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
340 unsigned int uiSubIndex_p,
341 void *pSrcData_p,
342 tEplObdSize Size_p)
345 tEplKernel Ret;
346 tEplObdEntryPtr pObdEntry;
347 tEplObdSubEntryPtr pSubEntry;
348 tEplObdCbParam MEM CbParam;
349 void MEM *pDstData;
350 tEplObdSize ObdSize;
352 Ret = EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_
353 uiIndex_p,
354 uiSubIndex_p,
355 pSrcData_p,
356 &pDstData,
357 Size_p,
358 &pObdEntry, &pSubEntry, &CbParam, &ObdSize);
359 if (Ret != kEplSuccessful) {
360 goto Exit;
363 Ret = EplObdWriteEntryPost(EPL_MCO_INSTANCE_PTR_
364 pObdEntry,
365 pSubEntry,
366 &CbParam, pSrcData_p, pDstData, ObdSize);
367 if (Ret != kEplSuccessful) {
368 goto Exit;
371 Exit:
373 return Ret;
377 //---------------------------------------------------------------------------
379 // Function: EplObdReadEntry()
381 // Description: The function reads an object entry. The application
382 // can always read the data even if attrib kEplObdAccRead
383 // is not set. The attrib is only checked up for SDO transfer.
385 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
386 // uiIndex_p = Index oof the OD entry to read
387 // uiSubIndex_p = Subindex to read
388 // pDstData_p = pointer to the buffer for data
389 // Offset_p = offset in data for read access
390 // pSize_p = IN: Size of the buffer
391 // OUT: number of readed Bytes
393 // Return: tEplKernel
395 // State:
397 //---------------------------------------------------------------------------
399 EPLDLLEXPORT tEplKernel EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
400 unsigned int uiSubIndex_p,
401 void *pDstData_p,
402 tEplObdSize *pSize_p)
405 tEplKernel Ret;
406 tEplObdEntryPtr pObdEntry;
407 tEplObdSubEntryPtr pSubEntry;
408 tEplObdCbParam MEM CbParam;
409 void *pSrcData;
410 tEplObdSize ObdSize;
412 // check for all API function if instance is valid
413 EPL_MCO_CHECK_INSTANCE_STATE();
415 ASSERT(pDstData_p != NULL);
416 ASSERT(pSize_p != NULL);
418 // get address of index and subindex entry
419 Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
420 uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry);
421 if (Ret != kEplSuccessful) {
422 goto Exit;
424 // get pointer to object data
425 pSrcData = EplObdGetObjectDataPtrIntern(pSubEntry);
427 // check source pointer
428 if (pSrcData == NULL) {
429 Ret = kEplObdReadViolation;
430 goto Exit;
432 //------------------------------------------------------------------------
433 // address of source data to structure of callback parameters
434 // so callback function can change this data before reading
435 CbParam.m_uiIndex = uiIndex_p;
436 CbParam.m_uiSubIndex = uiSubIndex_p;
437 CbParam.m_pArg = pSrcData;
438 CbParam.m_ObdEvent = kEplObdEvPreRead;
439 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
440 pObdEntry->m_fpCallback, &CbParam);
441 if (Ret != kEplSuccessful) {
442 goto Exit;
444 // get size of data and check if application has reserved enough memory
445 ObdSize = EplObdGetDataSizeIntern(pSubEntry);
446 // check if offset given and calc correct number of bytes to read
447 if (*pSize_p < ObdSize) {
448 Ret = kEplObdValueLengthError;
449 goto Exit;
451 // read value from object
452 EPL_MEMCPY(pDstData_p, pSrcData, ObdSize);
453 *pSize_p = ObdSize;
455 // write address of destination data to structure of callback parameters
456 // so callback function can change this data after reading
457 CbParam.m_pArg = pDstData_p;
458 CbParam.m_ObdEvent = kEplObdEvPostRead;
459 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
460 pObdEntry->m_fpCallback, &CbParam);
462 Exit:
464 return Ret;
468 //---------------------------------------------------------------------------
470 // Function: EplObdAccessOdPart()
472 // Description: restores default values of one part of OD
474 // Parameters: ObdPart_p
475 // Direction_p
477 // Return: tEplKernel
479 // State:
481 //---------------------------------------------------------------------------
483 EPLDLLEXPORT tEplKernel EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdPart ObdPart_p,
484 tEplObdDir Direction_p)
487 tEplKernel Ret = kEplSuccessful;
488 BOOL fPartFount;
489 tEplObdEntryPtr pObdEntry;
491 // check for all API function if instance is valid
492 EPL_MCO_CHECK_INSTANCE_STATE();
494 // part always has to be unequal to NULL
495 pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pPart);
496 ASSERTMSG(pObdEntry != NULL,
497 "EplObdAccessOdPart(): no OD part is defined!\n");
499 // if ObdPart_p is not valid fPartFound keeps FALSE and function returns kEplObdIllegalPart
500 fPartFount = FALSE;
502 // access to part
503 if ((ObdPart_p & kEplObdPartGen) != 0) {
504 fPartFount = TRUE;
506 Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_
507 kEplObdPartGen, pObdEntry,
508 Direction_p);
509 if (Ret != kEplSuccessful) {
510 goto Exit;
513 // access to manufacturer part
514 pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pManufacturerPart);
516 if (((ObdPart_p & kEplObdPartMan) != 0) && (pObdEntry != NULL)) {
517 fPartFount = TRUE;
519 Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_
520 kEplObdPartMan, pObdEntry,
521 Direction_p);
522 if (Ret != kEplSuccessful) {
523 goto Exit;
526 // access to device part
527 pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pDevicePart);
529 if (((ObdPart_p & kEplObdPartDev) != 0) && (pObdEntry != NULL)) {
530 fPartFount = TRUE;
532 Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_
533 kEplObdPartDev, pObdEntry,
534 Direction_p);
535 if (Ret != kEplSuccessful) {
536 goto Exit;
539 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
541 // access to user part
542 pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pUserPart);
544 if (((ObdPart_p & kEplObdPartUsr) != 0) && (pObdEntry != NULL)) {
545 fPartFount = TRUE;
547 Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_
548 kEplObdPartUsr,
549 pObdEntry, Direction_p);
550 if (Ret != kEplSuccessful) {
551 goto Exit;
555 #endif
557 // no access to an OD part was done? illegal OD part was specified!
558 if (fPartFount == FALSE) {
559 Ret = kEplObdIllegalPart;
562 Exit:
564 return Ret;
568 //---------------------------------------------------------------------------
570 // Function: EplObdDefineVar()
572 // Description: defines a variable in OD
574 // Parameters: pEplVarParam_p
576 // Return: tEplKernel
578 // State:
580 //---------------------------------------------------------------------------
582 EPLDLLEXPORT tEplKernel EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_ tEplVarParam MEM *pVarParam_p)
585 tEplKernel Ret;
586 tEplObdVarEntry MEM *pVarEntry;
587 tEplVarParamValid VarValid;
588 tEplObdSubEntryPtr pSubindexEntry;
590 // check for all API function if instance is valid
591 EPL_MCO_CHECK_INSTANCE_STATE();
593 ASSERT(pVarParam_p != NULL); // is not allowed to be NULL
595 // get address of subindex entry
596 Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
597 pVarParam_p->m_uiIndex,
598 pVarParam_p->m_uiSubindex, NULL, &pSubindexEntry);
599 if (Ret != kEplSuccessful) {
600 goto Exit;
602 // get var entry
603 Ret = EplObdGetVarEntry(pSubindexEntry, &pVarEntry);
604 if (Ret != kEplSuccessful) {
605 goto Exit;
608 VarValid = pVarParam_p->m_ValidFlag;
610 // copy only this values, which valid flag is set
611 if ((VarValid & kVarValidSize) != 0) {
612 if (pSubindexEntry->m_Type != kEplObdTypDomain) {
613 tEplObdSize DataSize;
615 // check passed size parameter
616 DataSize = EplObdGetObjectSize(pSubindexEntry);
617 if (DataSize != pVarParam_p->m_Size) { // size of variable does not match
618 Ret = kEplObdValueLengthError;
619 goto Exit;
621 } else { // size can be set only for objects of type DOMAIN
622 pVarEntry->m_Size = pVarParam_p->m_Size;
626 if ((VarValid & kVarValidData) != 0) {
627 pVarEntry->m_pData = pVarParam_p->m_pData;
630 #if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
632 if ((VarValid & kVarValidCallback) != 0)
634 pVarEntry->m_fpCallback = pVarParam_p->m_fpCallback;
637 if ((VarValid & kVarValidArg) != 0)
639 pVarEntry->m_pArg = pVarParam_p->m_pArg;
642 #endif
644 // Ret is already set to kEplSuccessful from ObdGetVarIntern()
646 Exit:
648 return Ret;
652 //---------------------------------------------------------------------------
654 // Function: EplObdGetObjectDataPtr()
656 // Description: It returnes the current data pointer. But if object is an
657 // constant object it returnes the default pointer.
659 // Parameters: uiIndex_p = Index of the entry
660 // uiSubindex_p = Subindex of the entry
662 // Return: void * = pointer to object data
664 // State:
666 //---------------------------------------------------------------------------
668 EPLDLLEXPORT void *EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
669 unsigned int uiSubIndex_p)
671 tEplKernel Ret;
672 void *pData;
673 tEplObdEntryPtr pObdEntry;
674 tEplObdSubEntryPtr pObdSubEntry;
676 // get pointer to index structure
677 Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam),
678 uiIndex_p, &pObdEntry);
679 if (Ret != kEplSuccessful) {
680 pData = NULL;
681 goto Exit;
683 // get pointer to subindex structure
684 Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry);
685 if (Ret != kEplSuccessful) {
686 pData = NULL;
687 goto Exit;
689 // get Datapointer
690 pData = EplObdGetObjectDataPtrIntern(pObdSubEntry);
692 Exit:
693 return pData;
697 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
699 //---------------------------------------------------------------------------
701 // Function: EplObdRegisterUserOd()
703 // Description: function registers the user OD
705 // Parameters: pUserOd_p =pointer to user ODd
707 // Return: tEplKernel = errorcode
709 // State:
711 //---------------------------------------------------------------------------
712 EPLDLLEXPORT tEplKernel EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pUserOd_p)
715 EPL_MCO_CHECK_INSTANCE_STATE();
717 EPL_MCO_GLB_VAR(m_ObdInitParam.m_pUserPart) = pUserOd_p;
719 return kEplSuccessful;
723 #endif
725 //---------------------------------------------------------------------------
727 // Function: EplObdInitVarEntry()
729 // Description: function to initialize VarEntry dependened on object type
731 // Parameters: pVarEntry_p = pointer to var entry structure
732 // Type_p = object type
733 // ObdSize_p = size of object data
735 // Returns: none
737 // State:
739 //---------------------------------------------------------------------------
741 EPLDLLEXPORT void EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdVarEntry MEM *pVarEntry_p,
742 tEplObdType Type_p, tEplObdSize ObdSize_p)
745 #if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
747 // reset pointer to VAR callback and argument
748 pVarEntry_p->m_fpCallback = NULL;
749 pVarEntry_p->m_pArg = NULL;
751 #endif
754 // 10-dec-2004 r.d.: this function will not be used for strings
755 if ((Type_p == kEplObdTypDomain))
756 // (bType_p == kEplObdTypVString) /* ||
757 // (bType_p == kEplObdTypOString) ||
758 // (bType_p == kEplObdTypUString) */ )
760 // variables which are defined as DOMAIN or VSTRING should not point to
761 // trash object, because this trash object contains only 8 bytes. DOMAINS or
762 // STRINGS can be longer.
763 pVarEntry_p->m_pData = NULL;
764 pVarEntry_p->m_Size = 0;
765 } else {
766 // set address to variable data to trash object
767 // This prevents an access violation if user forgets to call EplObdDefineVar()
768 // for this variable but mappes it in a PDO.
769 pVarEntry_p->m_pData = &abEplObdTrashObject_g[0];
770 pVarEntry_p->m_Size = ObdSize_p;
775 //---------------------------------------------------------------------------
777 // Function: EplObdGetDataSize()
779 // Description: function to initialize VarEntry dependened on object type
781 // gets the data size of an object
782 // for string objects it returnes the string length
784 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
785 // uiIndex_p = Index
786 // uiSubIndex_p= Subindex
788 // Return: tEplObdSize
790 // State:
792 //---------------------------------------------------------------------------
793 EPLDLLEXPORT tEplObdSize EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
794 unsigned int uiSubIndex_p)
796 tEplKernel Ret;
797 tEplObdSize ObdSize;
798 tEplObdEntryPtr pObdEntry;
799 tEplObdSubEntryPtr pObdSubEntry;
801 // get pointer to index structure
802 Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam),
803 uiIndex_p, &pObdEntry);
804 if (Ret != kEplSuccessful) {
805 ObdSize = 0;
806 goto Exit;
808 // get pointer to subindex structure
809 Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry);
810 if (Ret != kEplSuccessful) {
811 ObdSize = 0;
812 goto Exit;
814 // get size
815 ObdSize = EplObdGetDataSizeIntern(pObdSubEntry);
816 Exit:
817 return ObdSize;
820 //---------------------------------------------------------------------------
822 // Function: EplObdGetNodeId()
824 // Description: function returns nodeid from entry 0x1F93
827 // Parameters: EPL_MCO_DECL_INSTANCE_PTR = Instancepointer
829 // Return: unsigned int = Node Id
831 // State:
833 //---------------------------------------------------------------------------
834 EPLDLLEXPORT unsigned int EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR)
836 tEplKernel Ret;
837 tEplObdSize ObdSize;
838 BYTE bNodeId;
840 bNodeId = 0;
841 ObdSize = sizeof(bNodeId);
842 Ret = EplObdReadEntry(EPL_MCO_PTR_INSTANCE_PTR_
843 EPL_OBD_NODE_ID_INDEX,
844 EPL_OBD_NODE_ID_SUBINDEX, &bNodeId, &ObdSize);
845 if (Ret != kEplSuccessful) {
846 bNodeId = EPL_C_ADR_INVALID;
847 goto Exit;
850 Exit:
851 return (unsigned int)bNodeId;
855 //---------------------------------------------------------------------------
857 // Function: EplObdSetNodeId()
859 // Description: function sets nodeid in entry 0x1F93
862 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
863 // uiNodeId_p = Node Id to set
864 // NodeIdType_p= Type on which way the Node Id was set
866 // Return: tEplKernel = Errorcode
868 // State:
870 //---------------------------------------------------------------------------
871 EPLDLLEXPORT tEplKernel EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_ unsigned int uiNodeId_p,
872 tEplObdNodeIdType NodeIdType_p)
874 tEplKernel Ret;
875 tEplObdSize ObdSize;
876 BYTE fHwBool;
877 BYTE bNodeId;
879 // check Node Id
880 if (uiNodeId_p == EPL_C_ADR_INVALID) {
881 Ret = kEplInvalidNodeId;
882 goto Exit;
884 bNodeId = (BYTE) uiNodeId_p;
885 ObdSize = sizeof(BYTE);
886 // write NodeId to OD entry
887 Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR_
888 EPL_OBD_NODE_ID_INDEX,
889 EPL_OBD_NODE_ID_SUBINDEX, &bNodeId, ObdSize);
890 if (Ret != kEplSuccessful) {
891 goto Exit;
893 // set HWBOOL-Flag in Subindex EPL_OBD_NODE_ID_HWBOOL_SUBINDEX
894 switch (NodeIdType_p) {
895 // type unknown
896 case kEplObdNodeIdUnknown:
898 fHwBool = OBD_FALSE;
899 break;
902 case kEplObdNodeIdSoftware:
904 fHwBool = OBD_FALSE;
905 break;
908 case kEplObdNodeIdHardware:
910 fHwBool = OBD_TRUE;
911 break;
914 default:
916 fHwBool = OBD_FALSE;
919 } // end of switch (NodeIdType_p)
921 // write flag
922 ObdSize = sizeof(fHwBool);
923 Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR
924 EPL_OBD_NODE_ID_INDEX,
925 EPL_OBD_NODE_ID_HWBOOL_SUBINDEX,
926 &fHwBool, ObdSize);
927 if (Ret != kEplSuccessful) {
928 goto Exit;
931 Exit:
932 return Ret;
935 //---------------------------------------------------------------------------
937 // Function: EplObdIsNumerical()
939 // Description: function checks if a entry is numerical or not
942 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
943 // uiIndex_p = Index
944 // uiSubIndex_p = Subindex
945 // pfEntryNumerical_p = pointer to BOOL for returnvalue
946 // -> TRUE if entry a numerical value
947 // -> FALSE if entry not a numerical value
949 // Return: tEplKernel = Errorcode
951 // State:
953 //---------------------------------------------------------------------------
954 EPLDLLEXPORT tEplKernel EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
955 unsigned int uiSubIndex_p,
956 BOOL *pfEntryNumerical_p)
958 tEplKernel Ret;
959 tEplObdEntryPtr pObdEntry;
960 tEplObdSubEntryPtr pObdSubEntry;
962 // get pointer to index structure
963 Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam),
964 uiIndex_p, &pObdEntry);
965 if (Ret != kEplSuccessful) {
966 goto Exit;
968 // get pointer to subindex structure
969 Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry);
970 if (Ret != kEplSuccessful) {
971 goto Exit;
974 Ret = EplObdIsNumericalIntern(pObdSubEntry, pfEntryNumerical_p);
976 Exit:
977 return Ret;
981 //---------------------------------------------------------------------------
983 // Function: EplObdReadEntryToLe()
985 // Description: The function reads an object entry from the byteoder
986 // of the system to the little endian byteorder for numerical values.
987 // For other types a normal read will be processed. This is usefull for
988 // the PDO and SDO module. The application
989 // can always read the data even if attrib kEplObdAccRead
990 // is not set. The attrib is only checked up for SDO transfer.
992 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
993 // uiIndex_p = Index of the OD entry to read
994 // uiSubIndex_p = Subindex to read
995 // pDstData_p = pointer to the buffer for data
996 // Offset_p = offset in data for read access
997 // pSize_p = IN: Size of the buffer
998 // OUT: number of readed Bytes
1000 // Return: tEplKernel
1002 // State:
1004 //---------------------------------------------------------------------------
1005 EPLDLLEXPORT tEplKernel EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
1006 unsigned int uiSubIndex_p,
1007 void *pDstData_p,
1008 tEplObdSize *pSize_p)
1010 tEplKernel Ret;
1011 tEplObdEntryPtr pObdEntry;
1012 tEplObdSubEntryPtr pSubEntry;
1013 tEplObdCbParam MEM CbParam;
1014 void *pSrcData;
1015 tEplObdSize ObdSize;
1017 // check for all API function if instance is valid
1018 EPL_MCO_CHECK_INSTANCE_STATE();
1020 ASSERT(pDstData_p != NULL);
1021 ASSERT(pSize_p != NULL);
1023 // get address of index and subindex entry
1024 Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
1025 uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry);
1026 if (Ret != kEplSuccessful) {
1027 goto Exit;
1029 // get pointer to object data
1030 pSrcData = EplObdGetObjectDataPtrIntern(pSubEntry);
1032 // check source pointer
1033 if (pSrcData == NULL) {
1034 Ret = kEplObdReadViolation;
1035 goto Exit;
1037 //------------------------------------------------------------------------
1038 // address of source data to structure of callback parameters
1039 // so callback function can change this data before reading
1040 CbParam.m_uiIndex = uiIndex_p;
1041 CbParam.m_uiSubIndex = uiSubIndex_p;
1042 CbParam.m_pArg = pSrcData;
1043 CbParam.m_ObdEvent = kEplObdEvPreRead;
1044 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
1045 pObdEntry->m_fpCallback, &CbParam);
1046 if (Ret != kEplSuccessful) {
1047 goto Exit;
1049 // get size of data and check if application has reserved enough memory
1050 ObdSize = EplObdGetDataSizeIntern(pSubEntry);
1051 // check if offset given and calc correct number of bytes to read
1052 if (*pSize_p < ObdSize) {
1053 Ret = kEplObdValueLengthError;
1054 goto Exit;
1056 // check if numerical type
1057 switch (pSubEntry->m_Type) {
1058 //-----------------------------------------------
1059 // types without ami
1060 case kEplObdTypVString:
1061 case kEplObdTypOString:
1062 case kEplObdTypDomain:
1063 default:
1065 // read value from object
1066 EPL_MEMCPY(pDstData_p, pSrcData, ObdSize);
1067 break;
1070 //-----------------------------------------------
1071 // numerical type which needs ami-write
1072 // 8 bit or smaller values
1073 case kEplObdTypBool:
1074 case kEplObdTypInt8:
1075 case kEplObdTypUInt8:
1077 AmiSetByteToLe(pDstData_p, *((BYTE *) pSrcData));
1078 break;
1081 // 16 bit values
1082 case kEplObdTypInt16:
1083 case kEplObdTypUInt16:
1085 AmiSetWordToLe(pDstData_p, *((WORD *) pSrcData));
1086 break;
1089 // 24 bit values
1090 case kEplObdTypInt24:
1091 case kEplObdTypUInt24:
1093 AmiSetDword24ToLe(pDstData_p, *((DWORD *) pSrcData));
1094 break;
1097 // 32 bit values
1098 case kEplObdTypInt32:
1099 case kEplObdTypUInt32:
1100 case kEplObdTypReal32:
1102 AmiSetDwordToLe(pDstData_p, *((DWORD *) pSrcData));
1103 break;
1106 // 40 bit values
1107 case kEplObdTypInt40:
1108 case kEplObdTypUInt40:
1110 AmiSetQword40ToLe(pDstData_p, *((QWORD *) pSrcData));
1111 break;
1114 // 48 bit values
1115 case kEplObdTypInt48:
1116 case kEplObdTypUInt48:
1118 AmiSetQword48ToLe(pDstData_p, *((QWORD *) pSrcData));
1119 break;
1122 // 56 bit values
1123 case kEplObdTypInt56:
1124 case kEplObdTypUInt56:
1126 AmiSetQword56ToLe(pDstData_p, *((QWORD *) pSrcData));
1127 break;
1130 // 64 bit values
1131 case kEplObdTypInt64:
1132 case kEplObdTypUInt64:
1133 case kEplObdTypReal64:
1135 AmiSetQword64ToLe(pDstData_p, *((QWORD *) pSrcData));
1136 break;
1139 // time of day
1140 case kEplObdTypTimeOfDay:
1141 case kEplObdTypTimeDiff:
1143 AmiSetTimeOfDay(pDstData_p, ((tTimeOfDay *) pSrcData));
1144 break;
1147 } // end of switch(pSubEntry->m_Type)
1149 *pSize_p = ObdSize;
1151 // write address of destination data to structure of callback parameters
1152 // so callback function can change this data after reading
1153 CbParam.m_pArg = pDstData_p;
1154 CbParam.m_ObdEvent = kEplObdEvPostRead;
1155 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
1156 pObdEntry->m_fpCallback, &CbParam);
1158 Exit:
1160 return Ret;
1164 //---------------------------------------------------------------------------
1166 // Function: EplObdWriteEntryFromLe()
1168 // Description: Function writes data to an OBD entry from a source with
1169 // little endian byteorder to the od with system specuific
1170 // byteorder. Not numerical values will only by copied. Strings
1171 // are stored with added '\0' character.
1173 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
1174 // uiIndex_p = Index of the OD entry
1175 // uiSubIndex_p = Subindex of the OD Entry
1176 // pSrcData_p = Pointer to the data to write
1177 // Size_p = Size of the data in Byte
1179 // Return: tEplKernel = Errorcode
1182 // State:
1184 //---------------------------------------------------------------------------
1185 EPLDLLEXPORT tEplKernel EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
1186 unsigned int uiSubIndex_p,
1187 void *pSrcData_p,
1188 tEplObdSize Size_p)
1190 tEplKernel Ret;
1191 tEplObdEntryPtr pObdEntry;
1192 tEplObdSubEntryPtr pSubEntry;
1193 tEplObdCbParam MEM CbParam;
1194 void MEM *pDstData;
1195 tEplObdSize ObdSize;
1196 QWORD qwBuffer;
1197 void *pBuffer = &qwBuffer;
1199 Ret = EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_
1200 uiIndex_p,
1201 uiSubIndex_p,
1202 pSrcData_p,
1203 &pDstData,
1204 Size_p,
1205 &pObdEntry, &pSubEntry, &CbParam, &ObdSize);
1206 if (Ret != kEplSuccessful) {
1207 goto Exit;
1210 // check if numerical type
1211 switch (pSubEntry->m_Type) {
1212 //-----------------------------------------------
1213 // types without ami
1214 default:
1215 { // do nothing, i.e. use the given source pointer
1216 pBuffer = pSrcData_p;
1217 break;
1220 //-----------------------------------------------
1221 // numerical type which needs ami-write
1222 // 8 bit or smaller values
1223 case kEplObdTypBool:
1224 case kEplObdTypInt8:
1225 case kEplObdTypUInt8:
1227 *((BYTE *) pBuffer) = AmiGetByteFromLe(pSrcData_p);
1228 break;
1231 // 16 bit values
1232 case kEplObdTypInt16:
1233 case kEplObdTypUInt16:
1235 *((WORD *) pBuffer) = AmiGetWordFromLe(pSrcData_p);
1236 break;
1239 // 24 bit values
1240 case kEplObdTypInt24:
1241 case kEplObdTypUInt24:
1243 *((DWORD *) pBuffer) = AmiGetDword24FromLe(pSrcData_p);
1244 break;
1247 // 32 bit values
1248 case kEplObdTypInt32:
1249 case kEplObdTypUInt32:
1250 case kEplObdTypReal32:
1252 *((DWORD *) pBuffer) = AmiGetDwordFromLe(pSrcData_p);
1253 break;
1256 // 40 bit values
1257 case kEplObdTypInt40:
1258 case kEplObdTypUInt40:
1260 *((QWORD *) pBuffer) = AmiGetQword40FromLe(pSrcData_p);
1261 break;
1264 // 48 bit values
1265 case kEplObdTypInt48:
1266 case kEplObdTypUInt48:
1268 *((QWORD *) pBuffer) = AmiGetQword48FromLe(pSrcData_p);
1269 break;
1272 // 56 bit values
1273 case kEplObdTypInt56:
1274 case kEplObdTypUInt56:
1276 *((QWORD *) pBuffer) = AmiGetQword56FromLe(pSrcData_p);
1277 break;
1280 // 64 bit values
1281 case kEplObdTypInt64:
1282 case kEplObdTypUInt64:
1283 case kEplObdTypReal64:
1285 *((QWORD *) pBuffer) = AmiGetQword64FromLe(pSrcData_p);
1286 break;
1289 // time of day
1290 case kEplObdTypTimeOfDay:
1291 case kEplObdTypTimeDiff:
1293 AmiGetTimeOfDay(pBuffer, ((tTimeOfDay *) pSrcData_p));
1294 break;
1297 } // end of switch(pSubEntry->m_Type)
1299 Ret = EplObdWriteEntryPost(EPL_MCO_INSTANCE_PTR_
1300 pObdEntry,
1301 pSubEntry,
1302 &CbParam, pBuffer, pDstData, ObdSize);
1303 if (Ret != kEplSuccessful) {
1304 goto Exit;
1307 Exit:
1309 return Ret;
1313 //---------------------------------------------------------------------------
1315 // Function: EplObdGetAccessType()
1317 // Description: Function returns accesstype of the entry
1319 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
1320 // uiIndex_p = Index of the OD entry
1321 // uiSubIndex_p = Subindex of the OD Entry
1322 // pAccessTyp_p = pointer to buffer to store accesstype
1324 // Return: tEplKernel = errorcode
1327 // State:
1329 //---------------------------------------------------------------------------
1330 EPLDLLEXPORT tEplKernel EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
1331 unsigned int uiSubIndex_p,
1332 tEplObdAccess *pAccessTyp_p)
1334 tEplKernel Ret;
1335 tEplObdEntryPtr pObdEntry;
1336 tEplObdSubEntryPtr pObdSubEntry;
1338 // get pointer to index structure
1339 Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam),
1340 uiIndex_p, &pObdEntry);
1341 if (Ret != kEplSuccessful) {
1342 goto Exit;
1344 // get pointer to subindex structure
1345 Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry);
1346 if (Ret != kEplSuccessful) {
1347 goto Exit;
1349 // get accessType
1350 *pAccessTyp_p = pObdSubEntry->m_Access;
1352 Exit:
1353 return Ret;
1356 //---------------------------------------------------------------------------
1358 // Function: EplObdSearchVarEntry()
1360 // Description: gets variable from OD
1362 // Parameters: uiIndex_p = index of the var entry to search
1363 // uiSubindex_p = subindex of var entry to search
1364 // ppVarEntry_p = pointer to the pointer to the varentry
1366 // Return: tEplKernel
1368 // State:
1370 //---------------------------------------------------------------------------
1372 tEplKernel EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
1373 unsigned int uiSubindex_p,
1374 tEplObdVarEntry MEM **ppVarEntry_p)
1377 tEplKernel Ret;
1378 tEplObdSubEntryPtr pSubindexEntry;
1380 // check for all API function if instance is valid
1381 EPL_MCO_CHECK_INSTANCE_STATE();
1383 // get address of subindex entry
1384 Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
1385 uiIndex_p, uiSubindex_p, NULL, &pSubindexEntry);
1386 if (Ret == kEplSuccessful) {
1387 // get var entry
1388 Ret = EplObdGetVarEntry(pSubindexEntry, ppVarEntry_p);
1391 return Ret;
1395 //=========================================================================//
1396 // //
1397 // P R I V A T E D E F I N I T I O N S //
1398 // //
1399 //=========================================================================//
1401 EPL_MCO_DECL_INSTANCE_FCT()
1402 //---------------------------------------------------------------------------
1404 // Function: EplObdCallObjectCallback()
1406 // Description: calls callback function of an object or of a variable
1408 // Parameters: fpCallback_p
1409 // pCbParam_p
1411 // Return: tEplKernel
1413 // State:
1415 //---------------------------------------------------------------------------
1416 static tEplKernel EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_
1417 tEplObdCallback fpCallback_p,
1418 tEplObdCbParam MEM * pCbParam_p)
1421 tEplKernel Ret;
1422 tEplObdCallback MEM fpCallback;
1424 // check for all API function if instance is valid
1425 EPL_MCO_CHECK_INSTANCE_STATE();
1427 ASSERT(pCbParam_p != NULL);
1429 Ret = kEplSuccessful;
1431 // check address of callback function before calling it
1432 if (fpCallback_p != NULL) {
1433 // KEIL C51 V6.01 has a bug.
1434 // Therefore the parameter fpCallback_p has to be copied in local variable fpCallback.
1435 fpCallback = fpCallback_p;
1437 // call callback function for this object
1438 Ret = fpCallback(EPL_MCO_INSTANCE_PARAM_IDX_()
1439 pCbParam_p);
1442 return Ret;
1445 //---------------------------------------------------------------------------
1447 // Function: EplObdGetDataSizeIntern()
1449 // Description: gets the data size of an object
1450 // for string objects it returnes the string length
1452 // Parameters: pSubIndexEntry_p
1454 // Return: tEplObdSize
1456 // State:
1458 //---------------------------------------------------------------------------
1460 static tEplObdSize EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p)
1463 tEplObdSize DataSize;
1464 void MEM *pData;
1466 // If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING
1467 // then the current pointer is always NULL. The function
1468 // returns the length of default string.
1469 DataSize = EplObdGetObjectSize(pSubIndexEntry_p);
1471 if (pSubIndexEntry_p->m_Type == kEplObdTypVString) {
1472 // The pointer to current value can be received from EplObdGetObjectCurrentPtr()
1473 pData =
1474 ((void MEM *)EplObdGetObjectCurrentPtr(pSubIndexEntry_p));
1475 if (pData != NULL) {
1476 DataSize =
1477 EplObdGetStrLen((void *)pData, DataSize,
1478 pSubIndexEntry_p->m_Type);
1483 return DataSize;
1487 //---------------------------------------------------------------------------
1489 // Function: EplObdGetStrLen()
1491 // Description: The function calculates the length of string. The '\0'
1492 // character is included!!
1494 // Parameters: pObjData_p = pointer to string
1495 // ObjLen_p = max. length of objectr entry
1496 // bObjType_p = object type (VSTRING, ...)
1498 // Returns: string length + 1
1500 // State:
1502 //---------------------------------------------------------------------------
1504 static tEplObdSize EplObdGetStrLen(void *pObjData_p,
1505 tEplObdSize ObjLen_p, tEplObdType ObjType_p)
1508 tEplObdSize StrLen = 0;
1509 BYTE *pbString;
1511 if (pObjData_p == NULL) {
1512 goto Exit;
1514 //----------------------------------------
1515 // Visible String: data format byte
1516 if (ObjType_p == kEplObdTypVString) {
1517 pbString = pObjData_p;
1519 for (StrLen = 0; StrLen < ObjLen_p; StrLen++) {
1520 if (*pbString == '\0') {
1521 StrLen++;
1522 break;
1525 pbString++;
1528 //----------------------------------------
1529 // other string types ...
1531 Exit:
1532 return (StrLen);
1536 #if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
1538 //---------------------------------------------------------------------------
1540 // Function: EplObdCheckObjectRange()
1542 // Description: function to check value range of object data
1544 // NOTICE: The pointer of data (pData_p) must point out to an even address,
1545 // if ObjType is unequal to kEplObdTypInt8 or kEplObdTypUInt8! But it is
1546 // always realiced because pointer m_pDefault points always to an
1547 // array of the SPECIFIED type.
1549 // Parameters: pSubindexEntry_p
1550 // pData_p
1552 // Return: tEplKernel
1554 // State:
1556 //---------------------------------------------------------------------------
1558 static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p,
1559 void *pData_p)
1562 tEplKernel Ret;
1563 void *pRangeData;
1565 ASSERTMSG(pSubindexEntry_p != NULL,
1566 "EplObdCheckObjectRange(): no address to subindex struct!\n");
1568 Ret = kEplSuccessful;
1570 // check if data range has to be checked
1571 if ((pSubindexEntry_p->m_Access & kEplObdAccRange) == 0) {
1572 goto Exit;
1574 // get address of default data
1575 pRangeData = pSubindexEntry_p->m_pDefault;
1577 // jump to called object type
1578 switch ((tEplObdType) pSubindexEntry_p->m_Type) {
1579 // -----------------------------------------------------------------
1580 // ObdType kEplObdTypBool will not be checked because there are only
1581 // two possible values 0 or 1.
1583 // -----------------------------------------------------------------
1584 // ObdTypes which has to be check up because numerical values
1585 case kEplObdTypInt8:
1587 // switch to lower limit
1588 pRangeData = ((tEplObdInteger8 *) pRangeData) + 1;
1590 // check if value is to low
1591 if (*((tEplObdInteger8 *) pData_p) <
1592 *((tEplObdInteger8 *) pRangeData)) {
1593 Ret = kEplObdValueTooLow;
1594 break;
1596 // switch to higher limit
1597 pRangeData = ((tEplObdInteger8 *) pRangeData) + 1;
1599 // check if value is to high
1600 if (*((tEplObdInteger8 *) pData_p) >
1601 *((tEplObdInteger8 *) pRangeData)) {
1602 Ret = kEplObdValueTooHigh;
1605 break;
1607 case kEplObdTypUInt8:
1609 // switch to lower limit
1610 pRangeData = ((tEplObdUnsigned8 *) pRangeData) + 1;
1612 // check if value is to low
1613 if (*((tEplObdUnsigned8 *) pData_p) <
1614 *((tEplObdUnsigned8 *) pRangeData)) {
1615 Ret = kEplObdValueTooLow;
1616 break;
1618 // switch to higher limit
1619 pRangeData = ((tEplObdUnsigned8 *) pRangeData) + 1;
1621 // check if value is to high
1622 if (*((tEplObdUnsigned8 *) pData_p) >
1623 *((tEplObdUnsigned8 *) pRangeData)) {
1624 Ret = kEplObdValueTooHigh;
1627 break;
1629 case kEplObdTypInt16:
1631 // switch to lower limit
1632 pRangeData = ((tEplObdInteger16 *) pRangeData) + 1;
1634 // check if value is to low
1635 if (*((tEplObdInteger16 *) pData_p) <
1636 *((tEplObdInteger16 *) pRangeData)) {
1637 Ret = kEplObdValueTooLow;
1638 break;
1640 // switch to higher limit
1641 pRangeData = ((tEplObdInteger16 *) pRangeData) + 1;
1643 // check if value is to high
1644 if (*((tEplObdInteger16 *) pData_p) >
1645 *((tEplObdInteger16 *) pRangeData)) {
1646 Ret = kEplObdValueTooHigh;
1649 break;
1651 case kEplObdTypUInt16:
1653 // switch to lower limit
1654 pRangeData = ((tEplObdUnsigned16 *) pRangeData) + 1;
1656 // check if value is to low
1657 if (*((tEplObdUnsigned16 *) pData_p) <
1658 *((tEplObdUnsigned16 *) pRangeData)) {
1659 Ret = kEplObdValueTooLow;
1660 break;
1662 // switch to higher limit
1663 pRangeData = ((tEplObdUnsigned16 *) pRangeData) + 1;
1665 // check if value is to high
1666 if (*((tEplObdUnsigned16 *) pData_p) >
1667 *((tEplObdUnsigned16 *) pRangeData)) {
1668 Ret = kEplObdValueTooHigh;
1671 break;
1673 case kEplObdTypInt32:
1675 // switch to lower limit
1676 pRangeData = ((tEplObdInteger32 *) pRangeData) + 1;
1678 // check if value is to low
1679 if (*((tEplObdInteger32 *) pData_p) <
1680 *((tEplObdInteger32 *) pRangeData)) {
1681 Ret = kEplObdValueTooLow;
1682 break;
1684 // switch to higher limit
1685 pRangeData = ((tEplObdInteger32 *) pRangeData) + 1;
1687 // check if value is to high
1688 if (*((tEplObdInteger32 *) pData_p) >
1689 *((tEplObdInteger32 *) pRangeData)) {
1690 Ret = kEplObdValueTooHigh;
1693 break;
1695 case kEplObdTypUInt32:
1697 // switch to lower limit
1698 pRangeData = ((tEplObdUnsigned32 *) pRangeData) + 1;
1700 // check if value is to low
1701 if (*((tEplObdUnsigned32 *) pData_p) <
1702 *((tEplObdUnsigned32 *) pRangeData)) {
1703 Ret = kEplObdValueTooLow;
1704 break;
1706 // switch to higher limit
1707 pRangeData = ((tEplObdUnsigned32 *) pRangeData) + 1;
1709 // check if value is to high
1710 if (*((tEplObdUnsigned32 *) pData_p) >
1711 *((tEplObdUnsigned32 *) pRangeData)) {
1712 Ret = kEplObdValueTooHigh;
1715 break;
1717 case kEplObdTypReal32:
1719 // switch to lower limit
1720 pRangeData = ((tEplObdReal32 *) pRangeData) + 1;
1722 // check if value is to low
1723 if (*((tEplObdReal32 *) pData_p) <
1724 *((tEplObdReal32 *) pRangeData)) {
1725 Ret = kEplObdValueTooLow;
1726 break;
1728 // switch to higher limit
1729 pRangeData = ((tEplObdReal32 *) pRangeData) + 1;
1731 // check if value is to high
1732 if (*((tEplObdReal32 *) pData_p) >
1733 *((tEplObdReal32 *) pRangeData)) {
1734 Ret = kEplObdValueTooHigh;
1737 break;
1739 // -----------------------------------------------------------------
1740 case kEplObdTypInt40:
1741 case kEplObdTypInt48:
1742 case kEplObdTypInt56:
1743 case kEplObdTypInt64:
1745 // switch to lower limit
1746 pRangeData = ((signed QWORD *)pRangeData) + 1;
1748 // check if value is to low
1749 if (*((signed QWORD *)pData_p) < *((signed QWORD *)pRangeData)) {
1750 Ret = kEplObdValueTooLow;
1751 break;
1753 // switch to higher limit
1754 pRangeData = ((signed QWORD *)pRangeData) + 1;
1756 // check if value is to high
1757 if (*((signed QWORD *)pData_p) > *((signed QWORD *)pRangeData)) {
1758 Ret = kEplObdValueTooHigh;
1761 break;
1763 // -----------------------------------------------------------------
1764 case kEplObdTypUInt40:
1765 case kEplObdTypUInt48:
1766 case kEplObdTypUInt56:
1767 case kEplObdTypUInt64:
1769 // switch to lower limit
1770 pRangeData = ((unsigned QWORD *)pRangeData) + 1;
1772 // check if value is to low
1773 if (*((unsigned QWORD *)pData_p) <
1774 *((unsigned QWORD *)pRangeData)) {
1775 Ret = kEplObdValueTooLow;
1776 break;
1778 // switch to higher limit
1779 pRangeData = ((unsigned QWORD *)pRangeData) + 1;
1781 // check if value is to high
1782 if (*((unsigned QWORD *)pData_p) >
1783 *((unsigned QWORD *)pRangeData)) {
1784 Ret = kEplObdValueTooHigh;
1787 break;
1789 // -----------------------------------------------------------------
1790 case kEplObdTypReal64:
1792 // switch to lower limit
1793 pRangeData = ((tEplObdReal64 *) pRangeData) + 1;
1795 // check if value is to low
1796 if (*((tEplObdReal64 *) pData_p) <
1797 *((tEplObdReal64 *) pRangeData)) {
1798 Ret = kEplObdValueTooLow;
1799 break;
1801 // switch to higher limit
1802 pRangeData = ((tEplObdReal64 *) pRangeData) + 1;
1804 // check if value is to high
1805 if (*((tEplObdReal64 *) pData_p) >
1806 *((tEplObdReal64 *) pRangeData)) {
1807 Ret = kEplObdValueTooHigh;
1810 break;
1812 // -----------------------------------------------------------------
1813 case kEplObdTypTimeOfDay:
1814 case kEplObdTypTimeDiff:
1815 break;
1817 // -----------------------------------------------------------------
1818 // ObdTypes kEplObdTypXString and kEplObdTypDomain can not be checkt because
1819 // they have no numerical value.
1820 default:
1822 Ret = kEplObdUnknownObjectType;
1823 break;
1826 Exit:
1828 return Ret;
1831 #endif // (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
1833 //---------------------------------------------------------------------------
1835 // Function: EplObdWriteEntryPre()
1837 // Description: Function prepares write of data to an OBD entry. Strings
1838 // are stored with added '\0' character.
1840 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
1841 // uiIndex_p = Index of the OD entry
1842 // uiSubIndex_p = Subindex of the OD Entry
1843 // pSrcData_p = Pointer to the data to write
1844 // Size_p = Size of the data in Byte
1846 // Return: tEplKernel = Errorcode
1849 // State:
1851 //---------------------------------------------------------------------------
1853 static tEplKernel EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
1854 unsigned int uiSubIndex_p,
1855 void *pSrcData_p,
1856 void **ppDstData_p,
1857 tEplObdSize Size_p,
1858 tEplObdEntryPtr *ppObdEntry_p,
1859 tEplObdSubEntryPtr *ppSubEntry_p,
1860 tEplObdCbParam MEM *pCbParam_p,
1861 tEplObdSize *pObdSize_p)
1864 tEplKernel Ret;
1865 tEplObdEntryPtr pObdEntry;
1866 tEplObdSubEntryPtr pSubEntry;
1867 tEplObdAccess Access;
1868 void MEM *pDstData;
1869 tEplObdSize ObdSize;
1870 BOOL fEntryNumerical;
1872 #if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
1873 tEplObdVStringDomain MEM MemVStringDomain;
1874 void MEM *pCurrData;
1875 #endif
1877 // check for all API function if instance is valid
1878 EPL_MCO_CHECK_INSTANCE_STATE();
1880 ASSERT(pSrcData_p != NULL); // should never be NULL
1882 //------------------------------------------------------------------------
1883 // get address of index and subindex entry
1884 Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
1885 uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry);
1886 if (Ret != kEplSuccessful) {
1887 goto Exit;
1889 // get pointer to object data
1890 pDstData = (void MEM *)EplObdGetObjectDataPtrIntern(pSubEntry);
1892 Access = (tEplObdAccess) pSubEntry->m_Access;
1894 // check access for write
1895 // access violation if adress to current value is NULL
1896 if (((Access & kEplObdAccConst) != 0) || (pDstData == NULL)) {
1897 Ret = kEplObdAccessViolation;
1898 goto Exit;
1900 //------------------------------------------------------------------------
1901 // get size of object
1902 // -as ObdSize = ObdGetObjectSize (pSubEntry);
1904 //------------------------------------------------------------------------
1905 // To use the same callback function for ObdWriteEntry as well as for
1906 // an SDO download call at first (kEplObdEvPre...) the callback function
1907 // with the argument pointer to object size.
1908 pCbParam_p->m_uiIndex = uiIndex_p;
1909 pCbParam_p->m_uiSubIndex = uiSubIndex_p;
1911 // Because object size and object pointer are
1912 // adapted by user callback function, re-read
1913 // this values.
1914 ObdSize = EplObdGetObjectSize(pSubEntry);
1915 pDstData = (void MEM *)EplObdGetObjectDataPtrIntern(pSubEntry);
1917 // 09-dec-2004 r.d.:
1918 // Function EplObdWriteEntry() calls new event kEplObdEvWrStringDomain
1919 // for String or Domain which lets called module directly change
1920 // the data pointer or size. This prevents a recursive call to
1921 // the callback function if it calls EplObdGetEntry().
1922 #if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
1923 if ((pSubEntry->m_Type == kEplObdTypVString) ||
1924 (pSubEntry->m_Type == kEplObdTypDomain) ||
1925 (pSubEntry->m_Type == kEplObdTypOString)) {
1926 if (pSubEntry->m_Type == kEplObdTypVString) {
1927 // reserve one byte for 0-termination
1928 // -as ObdSize -= 1;
1929 Size_p += 1;
1931 // fill out new arg-struct
1932 MemVStringDomain.m_DownloadSize = Size_p;
1933 MemVStringDomain.m_ObjSize = ObdSize;
1934 MemVStringDomain.m_pData = pDstData;
1936 pCbParam_p->m_ObdEvent = kEplObdEvWrStringDomain;
1937 pCbParam_p->m_pArg = &MemVStringDomain;
1938 // call user callback
1939 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
1940 pObdEntry->m_fpCallback,
1941 pCbParam_p);
1942 if (Ret != kEplSuccessful) {
1943 goto Exit;
1945 // write back new settings
1946 pCurrData = pSubEntry->m_pCurrent;
1947 if ((pSubEntry->m_Type == kEplObdTypVString)
1948 || (pSubEntry->m_Type == kEplObdTypOString)) {
1949 ((tEplObdVString MEM *) pCurrData)->m_Size =
1950 MemVStringDomain.m_ObjSize;
1951 ((tEplObdVString MEM *) pCurrData)->m_pString =
1952 MemVStringDomain.m_pData;
1953 } else // if (pSdosTableEntry_p->m_bObjType == kEplObdTypDomain)
1955 ((tEplObdVarEntry MEM *) pCurrData)->m_Size =
1956 MemVStringDomain.m_ObjSize;
1957 ((tEplObdVarEntry MEM *) pCurrData)->m_pData =
1958 (void MEM *)MemVStringDomain.m_pData;
1961 // Because object size and object pointer are
1962 // adapted by user callback function, re-read
1963 // this values.
1964 ObdSize = MemVStringDomain.m_ObjSize;
1965 pDstData = (void MEM *)MemVStringDomain.m_pData;
1967 #endif //#if (OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
1969 // 07-dec-2004 r.d.: size from application is needed because callback function can change the object size
1970 // -as 16.11.04 CbParam.m_pArg = &ObdSize;
1971 // 09-dec-2004 r.d.: CbParam.m_pArg = &Size_p;
1972 pCbParam_p->m_pArg = &ObdSize;
1973 pCbParam_p->m_ObdEvent = kEplObdEvInitWrite;
1974 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
1975 pObdEntry->m_fpCallback, pCbParam_p);
1976 if (Ret != kEplSuccessful) {
1977 goto Exit;
1980 if (Size_p > ObdSize) {
1981 Ret = kEplObdValueLengthError;
1982 goto Exit;
1985 if (pSubEntry->m_Type == kEplObdTypVString) {
1986 if (((char MEM *)pSrcData_p)[Size_p - 1] == '\0') { // last byte of source string contains null character
1988 // reserve one byte in destination for 0-termination
1989 Size_p -= 1;
1990 } else if (Size_p >= ObdSize) { // source string is not 0-terminated
1991 // and destination buffer is too short
1992 Ret = kEplObdValueLengthError;
1993 goto Exit;
1997 Ret = EplObdIsNumericalIntern(pSubEntry, &fEntryNumerical);
1998 if (Ret != kEplSuccessful) {
1999 goto Exit;
2002 if ((fEntryNumerical != FALSE)
2003 && (Size_p != ObdSize)) {
2004 // type is numerical, therefor size has to fit, but it does not.
2005 Ret = kEplObdValueLengthError;
2006 goto Exit;
2008 // use given size, because non-numerical objects can be written with shorter values
2009 ObdSize = Size_p;
2011 // set output parameters
2012 *pObdSize_p = ObdSize;
2013 *ppObdEntry_p = pObdEntry;
2014 *ppSubEntry_p = pSubEntry;
2015 *ppDstData_p = pDstData;
2017 // all checks are done
2018 // the caller may now convert the numerial source value to platform byte order in a temporary buffer
2020 Exit:
2022 return Ret;
2026 //---------------------------------------------------------------------------
2028 // Function: EplObdWriteEntryPost()
2030 // Description: Function finishes write of data to an OBD entry. Strings
2031 // are stored with added '\0' character.
2033 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
2034 // uiIndex_p = Index of the OD entry
2035 // uiSubIndex_p = Subindex of the OD Entry
2036 // pSrcData_p = Pointer to the data to write
2037 // Size_p = Size of the data in Byte
2039 // Return: tEplKernel = Errorcode
2042 // State:
2044 //---------------------------------------------------------------------------
2046 static tEplKernel EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p,
2047 tEplObdSubEntryPtr pSubEntry_p,
2048 tEplObdCbParam MEM *pCbParam_p,
2049 void *pSrcData_p,
2050 void *pDstData_p,
2051 tEplObdSize ObdSize_p)
2054 tEplKernel Ret;
2056 // caller converted the source value to platform byte order
2057 // now the range of the value may be checked
2059 #if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
2061 // check data range
2062 Ret = EplObdCheckObjectRange(pSubEntry_p, pSrcData_p);
2063 if (Ret != kEplSuccessful) {
2064 goto Exit;
2067 #endif
2069 // now call user callback function to check value
2070 // write address of source data to structure of callback parameters
2071 // so callback function can check this data
2072 pCbParam_p->m_pArg = pSrcData_p;
2073 pCbParam_p->m_ObdEvent = kEplObdEvPreWrite;
2074 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
2075 pObdEntry_p->m_fpCallback, pCbParam_p);
2076 if (Ret != kEplSuccessful) {
2077 goto Exit;
2079 // copy object data to OBD
2080 EPL_MEMCPY(pDstData_p, pSrcData_p, ObdSize_p);
2082 // terminate string with 0
2083 if (pSubEntry_p->m_Type == kEplObdTypVString) {
2084 ((char MEM *)pDstData_p)[ObdSize_p] = '\0';
2086 // write address of destination to structure of callback parameters
2087 // so callback function can change data subsequently
2088 pCbParam_p->m_pArg = pDstData_p;
2089 pCbParam_p->m_ObdEvent = kEplObdEvPostWrite;
2090 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
2091 pObdEntry_p->m_fpCallback, pCbParam_p);
2093 Exit:
2095 return Ret;
2099 //---------------------------------------------------------------------------
2101 // Function: EplObdGetObjectSize()
2103 // Description: function to get size of object
2104 // The function determines if an object type an fixed data type (BYTE, WORD, ...)
2105 // or non fixed object (string, domain). This information is used to decide
2106 // if download data are stored temporary or not. For objects with fixed data length
2107 // and types a value range checking can process.
2108 // For strings the function returns the whole object size not the
2109 // length of string.
2111 // Parameters: pSubIndexEntry_p
2113 // Return: tEplObdSize
2115 // State:
2117 //---------------------------------------------------------------------------
2119 static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p)
2122 tEplObdSize DataSize = 0;
2123 void *pData;
2125 switch (pSubIndexEntry_p->m_Type) {
2126 // -----------------------------------------------------------------
2127 case kEplObdTypBool:
2129 DataSize = 1;
2130 break;
2132 // -----------------------------------------------------------------
2133 // ObdTypes which has to be check because numerical values
2134 case kEplObdTypInt8:
2135 DataSize = sizeof(tEplObdInteger8);
2136 break;
2138 // -----------------------------------------------------------------
2139 case kEplObdTypUInt8:
2140 DataSize = sizeof(tEplObdUnsigned8);
2141 break;
2143 // -----------------------------------------------------------------
2144 case kEplObdTypInt16:
2145 DataSize = sizeof(tEplObdInteger16);
2146 break;
2148 // -----------------------------------------------------------------
2149 case kEplObdTypUInt16:
2150 DataSize = sizeof(tEplObdUnsigned16);
2151 break;
2153 // -----------------------------------------------------------------
2154 case kEplObdTypInt32:
2155 DataSize = sizeof(tEplObdInteger32);
2156 break;
2158 // -----------------------------------------------------------------
2159 case kEplObdTypUInt32:
2160 DataSize = sizeof(tEplObdUnsigned32);
2161 break;
2163 // -----------------------------------------------------------------
2164 case kEplObdTypReal32:
2165 DataSize = sizeof(tEplObdReal32);
2166 break;
2168 // -----------------------------------------------------------------
2169 // ObdTypes which has to be not checked because not NUM values
2170 case kEplObdTypDomain:
2172 pData = (void *)pSubIndexEntry_p->m_pCurrent;
2173 if ((void MEM *)pData != (void MEM *)NULL) {
2174 DataSize = ((tEplObdVarEntry MEM *) pData)->m_Size;
2176 break;
2178 // -----------------------------------------------------------------
2179 case kEplObdTypVString:
2180 //case kEplObdTypUString:
2182 // If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING
2183 // then the current pointer is always NULL. The function
2184 // returns the length of default string.
2185 pData = (void *)pSubIndexEntry_p->m_pCurrent;
2186 if ((void MEM *)pData != (void MEM *)NULL) {
2187 // The max. size of strings defined by STRING-Macro is stored in
2188 // tEplObdVString of current value.
2189 // (types tEplObdVString, tEplObdOString and tEplObdUString has the same members)
2190 DataSize = ((tEplObdVString MEM *) pData)->m_Size;
2191 } else {
2192 // The current position is not decleared. The string
2193 // is located in ROM, therefor use default pointer.
2194 pData = (void *)pSubIndexEntry_p->m_pDefault;
2195 if ((CONST void ROM *)pData != (CONST void ROM *)NULL) {
2196 // The max. size of strings defined by STRING-Macro is stored in
2197 // tEplObdVString of default value.
2198 DataSize =
2199 ((CONST tEplObdVString ROM *) pData)->
2200 m_Size;
2204 break;
2206 // -----------------------------------------------------------------
2207 case kEplObdTypOString:
2209 pData = (void *)pSubIndexEntry_p->m_pCurrent;
2210 if ((void MEM *)pData != (void MEM *)NULL) {
2211 // The max. size of strings defined by STRING-Macro is stored in
2212 // tEplObdVString of current value.
2213 // (types tEplObdVString, tEplObdOString and tEplObdUString has the same members)
2214 DataSize = ((tEplObdOString MEM *) pData)->m_Size;
2215 } else {
2216 // The current position is not decleared. The string
2217 // is located in ROM, therefor use default pointer.
2218 pData = (void *)pSubIndexEntry_p->m_pDefault;
2219 if ((CONST void ROM *)pData != (CONST void ROM *)NULL) {
2220 // The max. size of strings defined by STRING-Macro is stored in
2221 // tEplObdVString of default value.
2222 DataSize =
2223 ((CONST tEplObdOString ROM *) pData)->
2224 m_Size;
2227 break;
2229 // -----------------------------------------------------------------
2230 case kEplObdTypInt24:
2231 case kEplObdTypUInt24:
2233 DataSize = 3;
2234 break;
2236 // -----------------------------------------------------------------
2237 case kEplObdTypInt40:
2238 case kEplObdTypUInt40:
2240 DataSize = 5;
2241 break;
2243 // -----------------------------------------------------------------
2244 case kEplObdTypInt48:
2245 case kEplObdTypUInt48:
2247 DataSize = 6;
2248 break;
2250 // -----------------------------------------------------------------
2251 case kEplObdTypInt56:
2252 case kEplObdTypUInt56:
2254 DataSize = 7;
2255 break;
2257 // -----------------------------------------------------------------
2258 case kEplObdTypInt64:
2259 case kEplObdTypUInt64:
2260 case kEplObdTypReal64:
2262 DataSize = 8;
2263 break;
2265 // -----------------------------------------------------------------
2266 case kEplObdTypTimeOfDay:
2267 case kEplObdTypTimeDiff:
2269 DataSize = 6;
2270 break;
2272 // -----------------------------------------------------------------
2273 default:
2274 break;
2277 return DataSize;
2280 //---------------------------------------------------------------------------
2282 // Function: EplObdGetObjectDefaultPtr()
2284 // Description: function to get the default pointer (type specific)
2286 // Parameters: pSubIndexEntry_p = pointer to subindex structure
2288 // Returns: (void *) = pointer to default value
2290 // State:
2292 //---------------------------------------------------------------------------
2294 static void *EplObdGetObjectDefaultPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
2297 void *pDefault;
2298 tEplObdType Type;
2300 ASSERTMSG(pSubIndexEntry_p != NULL,
2301 "EplObdGetObjectDefaultPtr(): pointer to SubEntry not valid!\n");
2303 // get address to default data from default pointer
2304 pDefault = pSubIndexEntry_p->m_pDefault;
2305 if (pDefault != NULL) {
2306 // there are some special types, whose default pointer always is NULL or has to get from other structure
2307 // get type from subindex structure
2308 Type = pSubIndexEntry_p->m_Type;
2310 // check if object type is a string value
2311 if ((Type == kEplObdTypVString) /* ||
2312 (Type == kEplObdTypUString) */ ) {
2314 // EPL_OBD_SUBINDEX_RAM_VSTRING
2315 // tEplObdSize m_Size; --> size of default string
2316 // char * m_pDefString; --> pointer to default string
2317 // char * m_pString; --> pointer to string in RAM
2319 pDefault =
2320 (void *)((tEplObdVString *) pDefault)->m_pString;
2321 } else if (Type == kEplObdTypOString) {
2322 pDefault =
2323 (void *)((tEplObdOString *) pDefault)->m_pString;
2327 return pDefault;
2331 //---------------------------------------------------------------------------
2333 // Function: EplObdGetVarEntry()
2335 // Description: gets a variable entry of an object
2337 // Parameters: pSubindexEntry_p
2338 // ppVarEntry_p
2340 // Return: tCopKernel
2342 // State:
2344 //---------------------------------------------------------------------------
2346 static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p,
2347 tEplObdVarEntry MEM ** ppVarEntry_p)
2350 tEplKernel Ret = kEplObdVarEntryNotExist;
2352 ASSERT(ppVarEntry_p != NULL); // is not allowed to be NULL
2353 ASSERT(pSubindexEntry_p != NULL);
2355 // check VAR-Flag - only this object points to variables
2356 if ((pSubindexEntry_p->m_Access & kEplObdAccVar) != 0) {
2357 // check if object is an array
2358 if ((pSubindexEntry_p->m_Access & kEplObdAccArray) != 0) {
2359 *ppVarEntry_p =
2360 &((tEplObdVarEntry MEM *) pSubindexEntry_p->
2361 m_pCurrent)[pSubindexEntry_p->m_uiSubIndex - 1];
2362 } else {
2363 *ppVarEntry_p =
2364 (tEplObdVarEntry MEM *) pSubindexEntry_p->
2365 m_pCurrent;
2368 Ret = kEplSuccessful;
2371 return Ret;
2375 //---------------------------------------------------------------------------
2377 // Function: EplObdGetEntry()
2379 // Description: gets a index entry from OD
2381 // Parameters: uiIndex_p = Index number
2382 // uiSubindex_p = Subindex number
2383 // ppObdEntry_p = pointer to the pointer to the entry
2384 // ppObdSubEntry_p = pointer to the pointer to the subentry
2386 // Return: tEplKernel
2389 // State:
2391 //---------------------------------------------------------------------------
2393 static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_
2394 unsigned int uiIndex_p,
2395 unsigned int uiSubindex_p,
2396 tEplObdEntryPtr * ppObdEntry_p,
2397 tEplObdSubEntryPtr * ppObdSubEntry_p)
2400 tEplObdEntryPtr pObdEntry;
2401 tEplObdCbParam MEM CbParam;
2402 tEplKernel Ret;
2404 // check for all API function if instance is valid
2405 EPL_MCO_CHECK_INSTANCE_STATE();
2407 //------------------------------------------------------------------------
2408 // get address of entry of index
2409 Ret =
2410 EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam), uiIndex_p,
2411 &pObdEntry);
2412 if (Ret != kEplSuccessful) {
2413 goto Exit;
2415 //------------------------------------------------------------------------
2416 // get address of entry of subindex
2417 Ret = EplObdGetSubindexIntern(pObdEntry, uiSubindex_p, ppObdSubEntry_p);
2418 if (Ret != kEplSuccessful) {
2419 goto Exit;
2421 //------------------------------------------------------------------------
2422 // call callback function to inform user/stack that an object will be searched
2423 // if the called module returnes an error then we abort the searching with kEplObdIndexNotExist
2424 CbParam.m_uiIndex = uiIndex_p;
2425 CbParam.m_uiSubIndex = uiSubindex_p;
2426 CbParam.m_pArg = NULL;
2427 CbParam.m_ObdEvent = kEplObdEvCheckExist;
2428 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
2429 pObdEntry->m_fpCallback, &CbParam);
2430 if (Ret != kEplSuccessful) {
2431 Ret = kEplObdIndexNotExist;
2432 goto Exit;
2434 //------------------------------------------------------------------------
2435 // it is allowed to set ppObdEntry_p to NULL
2436 // if so, no address will be written to calling function
2437 if (ppObdEntry_p != NULL) {
2438 *ppObdEntry_p = pObdEntry;
2441 Exit:
2443 return Ret;
2447 //---------------------------------------------------------------------------
2449 // Function: EplObdGetObjectCurrentPtr()
2451 // Description: function to get Current pointer (type specific)
2453 // Parameters: pSubIndexEntry_p
2455 // Return: void MEM*
2457 // State:
2459 //---------------------------------------------------------------------------
2461 static void MEM *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
2464 void MEM *pData;
2465 unsigned int uiArrayIndex;
2466 tEplObdSize Size;
2468 pData = pSubIndexEntry_p->m_pCurrent;
2470 // check if constant object
2471 if (pData != NULL) {
2472 // check if object is an array
2473 if ((pSubIndexEntry_p->m_Access & kEplObdAccArray) != 0) {
2474 // calculate correct data pointer
2475 uiArrayIndex = pSubIndexEntry_p->m_uiSubIndex - 1;
2476 if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0) {
2477 Size = sizeof(tEplObdVarEntry);
2478 } else {
2479 Size = EplObdGetObjectSize(pSubIndexEntry_p);
2481 pData = ((BYTE MEM *) pData) + (Size * uiArrayIndex);
2483 // check if VarEntry
2484 if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0) {
2485 // The data pointer is stored in VarEntry->pData
2486 pData = ((tEplObdVarEntry MEM *) pData)->m_pData;
2488 // the default pointer is stored for strings in tEplObdVString
2489 else if ((pSubIndexEntry_p->m_Type == kEplObdTypVString) /* ||
2490 (pSubIndexEntry_p->m_Type == kEplObdTypUString) */
2492 pData =
2493 (void MEM *)((tEplObdVString MEM *) pData)->
2494 m_pString;
2495 } else if (pSubIndexEntry_p->m_Type == kEplObdTypOString) {
2496 pData =
2497 (void MEM *)((tEplObdOString MEM *) pData)->
2498 m_pString;
2502 return pData;
2506 //---------------------------------------------------------------------------
2508 // Function: EplObdGetIndexIntern()
2510 // Description: gets a index entry from OD
2512 // Parameters: pInitParam_p
2513 // uiIndex_p
2514 // ppObdEntry_p
2516 // Return: tEplKernel
2518 // State:
2520 //---------------------------------------------------------------------------
2522 static tEplKernel EplObdGetIndexIntern(tEplObdInitParam MEM * pInitParam_p,
2523 unsigned int uiIndex_p,
2524 tEplObdEntryPtr * ppObdEntry_p)
2527 tEplObdEntryPtr pObdEntry;
2528 tEplKernel Ret;
2529 unsigned int uiIndex;
2531 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
2533 unsigned int nLoop;
2535 // if user OD is used then objekts also has to be searched in user OD
2536 // there is less code need if we do this in a loop
2537 nLoop = 2;
2539 #endif
2541 ASSERTMSG(ppObdEntry_p != NULL,
2542 "EplObdGetIndexIntern(): pointer to index entry is NULL!\n");
2544 Ret = kEplObdIndexNotExist;
2546 // get start address of OD part
2547 // start address depends on object index because
2548 // object dictionary is divided in 3 parts
2549 if ((uiIndex_p >= 0x1000) && (uiIndex_p < 0x2000)) {
2550 pObdEntry = pInitParam_p->m_pPart;
2551 } else if ((uiIndex_p >= 0x2000) && (uiIndex_p < 0x6000)) {
2552 pObdEntry = pInitParam_p->m_pManufacturerPart;
2554 // index range 0xA000 to 0xFFFF is reserved for DSP-405
2555 // DS-301 defines that range 0x6000 to 0x9FFF (!!!) is stored if "store" was written to 0x1010/3.
2556 // Therefore default configuration is OBD_INCLUDE_A000_TO_DEVICE_PART = FALSE.
2557 // But a CANopen Application which does not implement dynamic OD or user-OD but wants to use static objets 0xA000...
2558 // should set OBD_INCLUDE_A000_TO_DEVICE_PART to TRUE.
2560 #if (EPL_OBD_INCLUDE_A000_TO_DEVICE_PART == FALSE)
2561 else if ((uiIndex_p >= 0x6000) && (uiIndex_p < 0x9FFF))
2562 #else
2563 else if ((uiIndex_p >= 0x6000) && (uiIndex_p < 0xFFFF))
2564 #endif
2566 pObdEntry = pInitParam_p->m_pDevicePart;
2569 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
2571 // if index does not match in static OD then index only has to be searched in user OD
2572 else {
2573 // begin from first entry of user OD part
2574 pObdEntry = pInitParam_p->m_pUserPart;
2576 // no user OD is available
2577 if (pObdEntry == NULL) {
2578 goto Exit;
2580 // loop must only run once
2581 nLoop = 1;
2584 do {
2586 #else
2588 // no user OD is available
2589 // so other object can be found in OD
2590 else {
2591 Ret = kEplObdIllegalPart;
2592 goto Exit;
2595 #endif
2597 // note:
2598 // The end of Index table is marked with m_uiIndex = 0xFFFF.
2599 // If this function will be called with wIndex_p = 0xFFFF, entry
2600 // should not be found. Therefor it is important to use
2601 // while{} instead of do{}while !!!
2603 // get first index of index table
2604 uiIndex = pObdEntry->m_uiIndex;
2606 // search Index in OD part
2607 while (uiIndex != EPL_OBD_TABLE_INDEX_END) {
2608 // go to the end of this function if index is found
2609 if (uiIndex_p == uiIndex) {
2610 // write address of OD entry to calling function
2611 *ppObdEntry_p = pObdEntry;
2612 Ret = kEplSuccessful;
2613 goto Exit;
2615 // objects are sorted in OD
2616 // if the current index in OD is greater than the index which is to search then break loop
2617 // in this case user OD has to be search too
2618 if (uiIndex_p < uiIndex) {
2619 break;
2621 // next entry in index table
2622 pObdEntry++;
2624 // get next index of index table
2625 uiIndex = pObdEntry->m_uiIndex;
2628 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
2630 // begin from first entry of user OD part
2631 pObdEntry = pInitParam_p->m_pUserPart;
2633 // no user OD is available
2634 if (pObdEntry == NULL) {
2635 goto Exit;
2637 // switch next loop for user OD
2638 nLoop--;
2642 while (nLoop > 0) ;
2644 #endif
2646 // in this line Index was not found
2648 Exit:
2650 return Ret;
2654 //---------------------------------------------------------------------------
2656 // Function: EplObdGetSubindexIntern()
2658 // Description: gets a subindex entry from a index entry
2660 // Parameters: pObdEntry_p
2661 // bSubIndex_p
2662 // ppObdSubEntry_p
2664 // Return: tEplKernel
2666 // State:
2668 //---------------------------------------------------------------------------
2670 static tEplKernel EplObdGetSubindexIntern(tEplObdEntryPtr pObdEntry_p,
2671 unsigned int uiSubIndex_p,
2672 tEplObdSubEntryPtr * ppObdSubEntry_p)
2675 tEplObdSubEntryPtr pSubEntry;
2676 unsigned int nSubIndexCount;
2677 tEplKernel Ret;
2679 ASSERTMSG(pObdEntry_p != NULL,
2680 "EplObdGetSubindexIntern(): pointer to index is NULL!\n");
2681 ASSERTMSG(ppObdSubEntry_p != NULL,
2682 "EplObdGetSubindexIntern(): pointer to subindex is NULL!\n");
2684 Ret = kEplObdSubindexNotExist;
2686 // get start address of subindex table and count of subindices
2687 pSubEntry = pObdEntry_p->m_pSubIndex;
2688 nSubIndexCount = pObdEntry_p->m_uiCount;
2689 ASSERTMSG((pSubEntry != NULL) && (nSubIndexCount > 0), "ObdGetSubindexIntern(): invalid subindex table within index table!\n"); // should never be NULL
2691 // search subindex in subindex table
2692 while (nSubIndexCount > 0) {
2693 // check if array is found
2694 if ((pSubEntry->m_Access & kEplObdAccArray) != 0) {
2695 // check if subindex is in range
2696 if (uiSubIndex_p < pObdEntry_p->m_uiCount) {
2697 // update subindex number (subindex entry of an array is always in RAM !!!)
2698 pSubEntry->m_uiSubIndex = uiSubIndex_p;
2699 *ppObdSubEntry_p = pSubEntry;
2700 Ret = kEplSuccessful;
2701 goto Exit;
2704 // go to the end of this function if subindex is found
2705 else if (uiSubIndex_p == pSubEntry->m_uiSubIndex) {
2706 *ppObdSubEntry_p = pSubEntry;
2707 Ret = kEplSuccessful;
2708 goto Exit;
2710 // objects are sorted in OD
2711 // if the current subindex in OD is greater than the subindex which is to search then break loop
2712 // in this case user OD has to be search too
2713 if (uiSubIndex_p < pSubEntry->m_uiSubIndex) {
2714 break;
2717 pSubEntry++;
2718 nSubIndexCount--;
2721 // in this line SubIndex was not fount
2723 Exit:
2725 return Ret;
2729 //---------------------------------------------------------------------------
2731 // Function: EplObdSetStoreLoadObjCallback()
2733 // Description: function set address to callbackfunction for command Store and Load
2735 // Parameters: fpCallback_p
2737 // Return: tEplKernel
2739 // State:
2741 //---------------------------------------------------------------------------
2742 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
2743 EPLDLLEXPORT tEplKernel EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdStoreLoadObjCallback fpCallback_p)
2746 EPL_MCO_CHECK_INSTANCE_STATE();
2748 // set new address of callback function
2749 EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) = fpCallback_p;
2751 return kEplSuccessful;
2754 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
2756 //---------------------------------------------------------------------------
2758 // Function: EplObdAccessOdPartIntern()
2760 // Description: runs through OD and executes a job
2762 // Parameters: CurrentOdPart_p
2763 // pObdEnty_p
2764 // Direction_p = what is to do (load values from flash or EEPROM, store, ...)
2766 // Return: tEplKernel
2768 // State:
2770 //---------------------------------------------------------------------------
2772 static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
2773 tEplObdPart CurrentOdPart_p,
2774 tEplObdEntryPtr pObdEnty_p,
2775 tEplObdDir Direction_p)
2778 tEplObdSubEntryPtr pSubIndex;
2779 unsigned int nSubIndexCount;
2780 tEplObdAccess Access;
2781 void MEM *pDstData;
2782 void *pDefault;
2783 tEplObdSize ObjSize;
2784 tEplKernel Ret;
2785 tEplObdCbStoreParam MEM CbStore;
2786 tEplObdVarEntry MEM *pVarEntry;
2788 ASSERT(pObdEnty_p != NULL);
2790 Ret = kEplSuccessful;
2792 // prepare structure for STORE RESTORE callback function
2793 CbStore.m_bCurrentOdPart = (BYTE) CurrentOdPart_p;
2794 CbStore.m_pData = NULL;
2795 CbStore.m_ObjSize = 0;
2797 // command of first action depends on direction to access
2798 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
2799 if (Direction_p == kEplObdDirLoad) {
2800 CbStore.m_bCommand = (BYTE) kEplObdCommOpenRead;
2802 // call callback function for previous command
2803 Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore);
2804 if (Ret != kEplSuccessful) {
2805 goto Exit;
2807 // set command for index and subindex loop
2808 CbStore.m_bCommand = (BYTE) kEplObdCommReadObj;
2809 } else if (Direction_p == kEplObdDirStore) {
2810 CbStore.m_bCommand = (BYTE) kEplObdCommOpenWrite;
2812 // call callback function for previous command
2813 Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore);
2814 if (Ret != kEplSuccessful) {
2815 goto Exit;
2817 // set command for index and subindex loop
2818 CbStore.m_bCommand = (BYTE) kEplObdCommWriteObj;
2820 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
2822 // we should not restore the OD values here
2823 // the next NMT command "Reset Node" or "Reset Communication" resets the OD data
2824 if (Direction_p != kEplObdDirRestore) {
2825 // walk through OD part till end is found
2826 while (pObdEnty_p->m_uiIndex != EPL_OBD_TABLE_INDEX_END) {
2827 // get address to subindex table and count of subindices
2828 pSubIndex = pObdEnty_p->m_pSubIndex;
2829 nSubIndexCount = pObdEnty_p->m_uiCount;
2830 ASSERT((pSubIndex != NULL) && (nSubIndexCount > 0)); // should never be NULL
2832 // walk through subindex table till all subinices were restored
2833 while (nSubIndexCount != 0) {
2834 Access = (tEplObdAccess) pSubIndex->m_Access;
2836 // get pointer to current and default data
2837 pDefault = EplObdGetObjectDefaultPtr(pSubIndex);
2838 pDstData = EplObdGetObjectCurrentPtr(pSubIndex);
2840 // NOTE (for kEplObdTypVString):
2841 // The function returnes the max. number of bytes for a
2842 // current string.
2843 // r.d.: For stings the default-size will be read in other lines following (kEplObdDirInit).
2844 ObjSize = EplObdGetObjectSize(pSubIndex);
2846 // switch direction of OD access
2847 switch (Direction_p) {
2848 // --------------------------------------------------------------------------
2849 // VarEntry structures has to be initialized
2850 case kEplObdDirInit:
2852 // If VAR-Flag is set, m_pCurrent means not address of data
2853 // but address of tEplObdVarEntry. Address of data has to be get from
2854 // this structure.
2855 if ((Access & kEplObdAccVar) != 0) {
2856 EplObdGetVarEntry(pSubIndex,
2857 &pVarEntry);
2858 EplObdInitVarEntry(pVarEntry,
2859 pSubIndex->
2860 m_Type,
2861 ObjSize);
2863 if ((Access & kEplObdAccArray) == 0)
2865 EplObdInitVarEntry (pSubIndex->m_pCurrent, pSubIndex->m_Type, ObjSize);
2867 else
2869 EplObdInitVarEntry ((tEplObdVarEntry MEM*) (((BYTE MEM*) pSubIndex->m_pCurrent) + (sizeof (tEplObdVarEntry) * pSubIndex->m_uiSubIndex)),
2870 pSubIndex->m_Type, ObjSize);
2873 // at this time no application variable is defined !!!
2874 // therefore data can not be copied.
2875 break;
2876 } else if (pSubIndex->m_Type ==
2877 kEplObdTypVString) {
2878 // If pointer m_pCurrent is not equal to NULL then the
2879 // string was defined with EPL_OBD_SUBINDEX_RAM_VSTRING. The current
2880 // pointer points to struct tEplObdVString located in MEM.
2881 // The element size includes the max. number of
2882 // bytes. The element m_pString includes the pointer
2883 // to string in MEM. The memory location of default string
2884 // must be copied to memory location of current string.
2886 pDstData =
2887 pSubIndex->m_pCurrent;
2888 if (pDstData != NULL) {
2889 // 08-dec-2004: code optimization !!!
2890 // entries ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_pString
2891 // and ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_Size were read
2892 // twice. thats not necessary!
2894 // For copying data we have to set the destination pointer to the real RAM string. This
2895 // pointer to RAM string is located in default string info structure. (translated r.d.)
2896 pDstData =
2897 (void MEM
2898 *)((tEplObdVStringDef ROM *) pSubIndex->m_pDefault)->m_pString;
2899 ObjSize =
2900 ((tEplObdVStringDef
2901 ROM *) pSubIndex->
2902 m_pDefault)->
2903 m_Size;
2905 ((tEplObdVString MEM *)
2906 pSubIndex->
2907 m_pCurrent)->
2908 m_pString = pDstData;
2909 ((tEplObdVString MEM *)
2910 pSubIndex->
2911 m_pCurrent)->m_Size =
2912 ObjSize;
2915 } else if (pSubIndex->m_Type ==
2916 kEplObdTypOString) {
2917 pDstData =
2918 pSubIndex->m_pCurrent;
2919 if (pDstData != NULL) {
2920 // 08-dec-2004: code optimization !!!
2921 // entries ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_pString
2922 // and ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_Size were read
2923 // twice. thats not necessary!
2925 // For copying data we have to set the destination pointer to the real RAM string. This
2926 // pointer to RAM string is located in default string info structure. (translated r.d.)
2927 pDstData =
2928 (void MEM
2929 *)((tEplObdOStringDef ROM *) pSubIndex->m_pDefault)->m_pString;
2930 ObjSize =
2931 ((tEplObdOStringDef
2932 ROM *) pSubIndex->
2933 m_pDefault)->
2934 m_Size;
2936 ((tEplObdOString MEM *)
2937 pSubIndex->
2938 m_pCurrent)->
2939 m_pString = pDstData;
2940 ((tEplObdOString MEM *)
2941 pSubIndex->
2942 m_pCurrent)->m_Size =
2943 ObjSize;
2948 // no break !! because copy of data has to done too.
2950 // --------------------------------------------------------------------------
2951 // all objects has to be restored with default values
2952 case kEplObdDirRestore:
2954 // 09-dec-2004 r.d.: optimization! the same code for kEplObdDirRestore and kEplObdDirLoad
2955 // is replaced to function ObdCopyObjectData() with a new parameter.
2957 // restore object data for init phase
2958 EplObdCopyObjectData(pDstData, pDefault,
2959 ObjSize,
2960 pSubIndex->m_Type);
2961 break;
2963 // --------------------------------------------------------------------------
2964 // objects with attribute kEplObdAccStore has to be load from EEPROM or from a file
2965 case kEplObdDirLoad:
2967 // restore object data for init phase
2968 EplObdCopyObjectData(pDstData, pDefault,
2969 ObjSize,
2970 pSubIndex->m_Type);
2972 // no break !! because callback function has to be called too.
2974 // --------------------------------------------------------------------------
2975 // objects with attribute kEplObdAccStore has to be stored in EEPROM or in a file
2976 case kEplObdDirStore:
2978 // when attribute kEplObdAccStore is set, then call callback function
2979 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
2980 if ((Access & kEplObdAccStore) != 0) {
2981 // fill out data pointer and size of data
2982 CbStore.m_pData = pDstData;
2983 CbStore.m_ObjSize = ObjSize;
2985 // call callback function for read or write object
2986 Ret =
2987 ObdCallStoreCallback
2988 (EPL_MCO_INSTANCE_PTR_ &
2989 CbStore);
2990 if (Ret != kEplSuccessful) {
2991 goto Exit;
2994 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
2995 break;
2997 // --------------------------------------------------------------------------
2998 // if OD Builder key has to be checked no access to subindex and data should be made
2999 case kEplObdDirOBKCheck:
3001 // no break !! because we want to break the second loop too.
3003 // --------------------------------------------------------------------------
3004 // unknown Direction
3005 default:
3007 // so we can break the second loop earler
3008 nSubIndexCount = 1;
3009 break;
3012 nSubIndexCount--;
3014 // next subindex entry
3015 if ((Access & kEplObdAccArray) == 0) {
3016 pSubIndex++;
3017 if ((nSubIndexCount > 0)
3019 ((pSubIndex->
3020 m_Access & kEplObdAccArray) !=
3021 0)) {
3022 // next subindex points to an array
3023 // reset subindex number
3024 pSubIndex->m_uiSubIndex = 1;
3026 } else {
3027 if (nSubIndexCount > 0) {
3028 // next subindex points to an array
3029 // increment subindex number
3030 pSubIndex->m_uiSubIndex++;
3035 // next index entry
3036 pObdEnty_p++;
3039 // -----------------------------------------------------------------------------------------
3040 // command of last action depends on direction to access
3041 if (Direction_p == kEplObdDirOBKCheck) {
3043 goto Exit;
3045 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
3046 else {
3047 if (Direction_p == kEplObdDirLoad) {
3048 CbStore.m_bCommand = (BYTE) kEplObdCommCloseRead;
3049 } else if (Direction_p == kEplObdDirStore) {
3050 CbStore.m_bCommand = (BYTE) kEplObdCommCloseWrite;
3051 } else if (Direction_p == kEplObdDirRestore) {
3052 CbStore.m_bCommand = (BYTE) kEplObdCommClear;
3053 } else {
3054 goto Exit;
3057 // call callback function for last command
3058 Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore);
3060 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
3062 // goto Exit;
3064 Exit:
3066 return Ret;
3070 // ----------------------------------------------------------------------------
3071 // Function: EplObdCopyObjectData()
3073 // Description: checks pointers to object data and copy them from source to destination
3075 // Parameters: pDstData_p = destination pointer
3076 // pSrcData_p = source pointer
3077 // ObjSize_p = size of object
3078 // ObjType_p =
3080 // Returns: tEplKernel = error code
3081 // ----------------------------------------------------------------------------
3083 static void EplObdCopyObjectData(void MEM * pDstData_p,
3084 void *pSrcData_p,
3085 tEplObdSize ObjSize_p, tEplObdType ObjType_p)
3088 tEplObdSize StrSize = 0;
3090 // it is allowed to set default and current address to NULL (nothing to copy)
3091 if (pDstData_p != NULL) {
3093 if (ObjType_p == kEplObdTypVString) {
3094 // The function calculates the really number of characters of string. The
3095 // object entry size can be bigger as string size of default string.
3096 // The '\0'-termination is included. A string with no characters has a
3097 // size of 1.
3098 StrSize =
3099 EplObdGetStrLen((void *)pSrcData_p, ObjSize_p,
3100 kEplObdTypVString);
3102 // If the string length is greater than or equal to the entry size in OD then only copy
3103 // entry size - 1 and always set the '\0'-termination.
3104 if (StrSize >= ObjSize_p) {
3105 StrSize = ObjSize_p - 1;
3109 if (pSrcData_p != NULL) {
3110 // copy data
3111 EPL_MEMCPY(pDstData_p, pSrcData_p, ObjSize_p);
3113 if (ObjType_p == kEplObdTypVString) {
3114 ((char MEM *)pDstData_p)[StrSize] = '\0';
3121 //---------------------------------------------------------------------------
3123 // Function: EplObdIsNumericalIntern()
3125 // Description: function checks if a entry is numerical or not
3128 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
3129 // uiIndex_p = Index
3130 // uiSubIndex_p = Subindex
3131 // pfEntryNumerical_p = pointer to BOOL for returnvalue
3132 // -> TRUE if entry a numerical value
3133 // -> FALSE if entry not a numerical value
3135 // Return: tEplKernel = Errorcode
3137 // State:
3139 //---------------------------------------------------------------------------
3140 static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p,
3141 BOOL * pfEntryNumerical_p)
3143 tEplKernel Ret = kEplSuccessful;
3145 // get Type
3146 if ((pObdSubEntry_p->m_Type == kEplObdTypVString)
3147 || (pObdSubEntry_p->m_Type == kEplObdTypOString)
3148 || (pObdSubEntry_p->m_Type == kEplObdTypDomain)) { // not numerical types
3149 *pfEntryNumerical_p = FALSE;
3150 } else { // numerical types
3151 *pfEntryNumerical_p = TRUE;
3154 return Ret;
3158 // -------------------------------------------------------------------------
3159 // function to classify object type (fixed/non fixed)
3160 // -------------------------------------------------------------------------
3162 // ----------------------------------------------------------------------------
3163 // Function: EplObdCallStoreCallback()
3165 // Description: checks address to callback function and calles it when unequal
3166 // to NULL
3168 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = (instance pointer)
3169 // pCbStoreParam_p = address to callback parameters
3171 // Returns: tEplKernel = error code
3172 // ----------------------------------------------------------------------------
3173 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
3174 static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_
3175 tEplObdCbStoreParam MEM *
3176 pCbStoreParam_p)
3179 tEplKernel Ret = kEplSuccessful;
3181 ASSERT(pCbStoreParam_p != NULL);
3183 // check if function pointer is NULL - if so, no callback should be called
3184 if (EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) != NULL) {
3185 Ret =
3186 EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback)
3187 (EPL_MCO_INSTANCE_PARAM_IDX_()
3188 pCbStoreParam_p);
3191 return Ret;
3194 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
3195 //---------------------------------------------------------------------------
3197 // Function: EplObdGetObjectDataPtrIntern()
3199 // Description: Function gets the data pointer of an object.
3200 // It returnes the current data pointer. But if object is an
3201 // constant object it returnes the default pointer.
3203 // Parameters: pSubindexEntry_p = pointer to subindex entry
3205 // Return: void * = pointer to object data
3207 // State:
3209 //---------------------------------------------------------------------------
3211 void *EplObdGetObjectDataPtrIntern(tEplObdSubEntryPtr pSubindexEntry_p)
3214 void *pData;
3215 tEplObdAccess Access;
3217 ASSERTMSG(pSubindexEntry_p != NULL,
3218 "EplObdGetObjectDataPtrIntern(): pointer to SubEntry not valid!\n");
3220 // there are are some objects whose data pointer has to get from other structure
3221 // get access type for this object
3222 Access = pSubindexEntry_p->m_Access;
3224 // If object has access type = const,
3225 // for data only exists default values.
3226 if ((Access & kEplObdAccConst) != 0) {
3227 // The pointer to defualt value can be received from ObdGetObjectDefaultPtr()
3228 pData = ((void *)EplObdGetObjectDefaultPtr(pSubindexEntry_p));
3229 } else {
3230 // The pointer to current value can be received from ObdGetObjectCurrentPtr()
3231 pData = ((void *)EplObdGetObjectCurrentPtr(pSubindexEntry_p));
3234 return pData;
3237 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
3238 // EOF