/*
* co_odaccess.c - contains routines for object dictionary access
*
* Copyright (c) 2012-2024 emotas embedded communication GmbH
*-------------------------------------------------------------------
* $Id: co_odaccess.c 54952 2024-08-07 06:35:20Z boe $
*
*
*-------------------------------------------------------------------
*
*
*/

/********************************************************************/
/**
* \brief object dictionary access
*
* \file co_odaccess.c
* contains routines for object dictionary access
*
*/

/* header of standard C - libraries
---------------------------------------------------------------------------*/
#include <string.h>

/* header of project specific types
---------------------------------------------------------------------------*/
#include <gen_define.h>
#include <co_datatype.h>
#include <co_memcpy.h>
#include <co_timer.h>
#include <co_drv.h>
#include <co_common.h>
#include <co_odaccess.h>
#include <co_nmt.h>
#include <co_sdo.h>
#ifdef CANOPEN_SUPPORTED
# include <co_pdo.h>
#endif /* CANOPEN_SUPPORTED */
#include "ico_common.h"
#include "ico_cobhandler.h"
#include "ico_queue.h"
#include "ico_event.h"
#include "ico_indication.h"
#include "ico_odaccess.h"
#include "ico_memcpy.h"
#ifdef CO_SDO_SERVER_CNT
# include "ico_sdoserver.h"
#endif /* CO_SDO_SERVER_CNT */
#ifdef CO_SDO_CLIENT_CNT
# include "ico_sdoclient.h"
#endif /* CO_SDO_CLIENT_CNT */
#ifdef CANOPEN_SUPPORTED
# include "ico_pdo.h"
# include "ico_nmt.h"
# include "ico_sync.h"
# include "ico_emcy.h"
# include "ico_time.h"
# include "ico_store.h"
#endif /* CANOPEN_SUPPORTED */
#ifdef CO_SRD_SUPPORTED
#include "ico_srd.h"
#endif /* CO_SRD_SUPPORTED */
#ifdef CO_DYNAMIC_OBJDIC
#include "ico_dynod.h"
#endif /* CO_DYNAMIC_OBJDIC */
#ifdef CO_NETWORK_ROUTING_CNT
# include "ico_network.h"
#endif /* CO_NETWORK_ROUTING_CNT */
#ifdef CO_SRDO_SUPPORTED
# include "co_srdo.h"
# include "ico_srdo.h"
#endif /* CO_SRDO_SUPPORTED */
#ifdef CO_GFC_SUPPORTED
# include "ico_gfc.h"
#endif /* CO_GFC_SUPPORTED */

/* constant definitions
---------------------------------------------------------------------------*/

/* local defined data types
---------------------------------------------------------------------------*/
#ifdef CO_EVENT_OBJECT_CHANGED
typedef struct {
	UNSIGNED16	index;			/* object index */
	UNSIGNED8	subIndex;		/* object subindex (if 255 - valid for all subindex) */
	CO_LINE_TYPE	CO_LINE;	/* line information */
	CO_EVENT_OBJECT_CHANGED_FCT_T pFct;		/* function */
} CO_EVENT_OBJECT_CHANGED_T;
#endif /* CO_EVENT_OBJECT_CHANGED */

#ifdef CO_STORE_SUPPORTED
typedef struct {
	UNSIGNED32	idx;
	UNSIGNED16	assign;
	UNSIGNED8	subIdx;
	UNSIGNED16	odIndex;
	UNSIGNED8	odSubIndex;
} OD_LAST_STORE_T;
#endif /* CO_STORE_SUPPORTED */

/* list of external used functions, if not in headers
---------------------------------------------------------------------------*/

/* list of global defined functions
---------------------------------------------------------------------------*/

/* list of local defined functions
---------------------------------------------------------------------------*/
static RET_T odGetObjDescIdx(CO_LINE_DECL, UNSIGNED16 index, UNSIGNED8 subIndex,
		UNSIGNED16	*pDescIdx);
static UNSIGNED8 *odGetObjAddr(CO_LINE_DECL, const CO_OBJECT_DESC_T	*pDesc,
		UNSIGNED8 subIndex);
static CO_CONST UNSIGNED8 *odGetObjAddr_R(CO_LINE_DECL, const CO_OBJECT_DESC_T *pDesc,
		UNSIGNED8 subIndex);
#ifdef CO_CPU_DSP
static void odCorrectObjOffs(CO_CONST CO_OBJECT_DESC_T *pDesc,
		UNSIGNED32 *pOffset, UNSIGNED32 *pPackOffset, UNSIGNED16 *pAttr);
#endif /* CO_CPU_DSP */
static RET_T odCheckObjLimitsOther(CO_CONST CO_OBJECT_DESC_T *pDesc,
		CO_CONST CO_DATA_TYPE_T	dType, CO_CONST UNSIGNED8 *pData);
static RET_T checkObjLimits_u16(CO_LINE_DECL, CO_CONST CO_OBJECT_DESC_T *pDesc,
		CO_CONST UNSIGNED16	value);

static RET_T checkObjValue_u8(CO_LINE_DECL, CO_CONST CO_OBJECT_DESC_T *pDesc,
		CO_CONST UNSIGNED8	value);
static RET_T checkObjValue_u16(CO_LINE_DECL, CO_CONST CO_OBJECT_DESC_T *pDesc,
		CO_CONST UNSIGNED16	value);
static RET_T checkObjValue_u32(CO_LINE_DECL, CO_CONST CO_OBJECT_DESC_T *pDesc,
		CO_CONST UNSIGNED32	value);


/* external variables
---------------------------------------------------------------------------*/

/* global variables
---------------------------------------------------------------------------*/

/* local defined variables
---------------------------------------------------------------------------*/
#ifdef CO_EVENT_OBJECT_CHANGED_CNT
static CO_EVENT_OBJECT_CHANGED_T objectEventTable[CO_EVENT_OBJECT_CHANGED_CNT];
static UNSIGNED16		objectEventTableCnt = 0u;
#endif /* CO_EVENT_OBJECT_CHANGED_CNT */

static CO_CONST CO_OD_ASSIGN_T		*pOdAssignTable[CO_LINE_ARRAY_DECL];
static UNSIGNED16					odAssignCnt[CO_LINE_ARRAY_DECL];
static CO_CONST CO_OBJECT_DESC_T	*pObjDescTable[CO_LINE_ARRAY_DECL];
/* static UNSIGNED16		objDescCnt; */
static CO_CONST UNSIGNED8		*pOdConst_u8 = NULL;
static CO_CONST UNSIGNED16		*pOdConst_u16 = NULL;
static CO_CONST UNSIGNED32		*pOdConst_u32 = NULL;
static CO_CONST REAL32		        *pOdConst_r32 = NULL;
#ifdef CO_EXTENDED_DATA_TYPES
static CO_CONST UNSIGNED24		*pOdConst_u24 = NULL;
static CO_CONST UNSIGNED40		*pOdConst_u40 = NULL;
static CO_CONST UNSIGNED48		*pOdConst_u48 = NULL;
static CO_CONST UNSIGNED64		*pOdConst_u64 = NULL;
#endif /* CO_EXTENDED_DATA_TYPES */
static UNSIGNED8			*pOdVar_u8 = NULL;
static UNSIGNED16			*pOdVar_u16 = NULL;
static UNSIGNED32			*pOdVar_u32 = NULL;
static REAL32				*pOdVar_r32 = NULL;
#ifdef CO_EXTENDED_DATA_TYPES
static UNSIGNED24			*pOdVar_u24 = NULL;
static UNSIGNED40			*pOdVar_u40 = NULL;
static UNSIGNED48			*pOdVar_u48 = NULL;
static UNSIGNED64			*pOdVar_u64 = NULL;
#endif /* CO_EXTENDED_DATA_TYPES */
static CO_CONST INTEGER8	*pOdConst_i8 = NULL;
static CO_CONST INTEGER16	*pOdConst_i16 = NULL;
static CO_CONST INTEGER32	*pOdConst_i32 = NULL;
static INTEGER8				*pOdVar_i8 = NULL;
static INTEGER16			*pOdVar_i16 = NULL;
static INTEGER32			*pOdVar_i32 = NULL;
static UNSIGNED8	* CO_CONST *pOdPtr_u8 = NULL;
static UNSIGNED16	* CO_CONST *pOdPtr_u16 = NULL;
static UNSIGNED32	* CO_CONST *pOdPtr_u32 = NULL;
#ifdef CO_EXTENDED_DATA_TYPES
static UNSIGNED24	* CO_CONST *pOdPtr_u24 = NULL;
static UNSIGNED40	* CO_CONST *pOdPtr_u40 = NULL;
static UNSIGNED48	* CO_CONST *pOdPtr_u48 = NULL;
static UNSIGNED64	* CO_CONST *pOdPtr_u64 = NULL;
#endif /* CO_EXTENDED_DATA_TYPES */
static INTEGER8		* CO_CONST *pOdPtr_i8 = NULL;
static INTEGER16	* CO_CONST *pOdPtr_i16 = NULL;
static INTEGER32	* CO_CONST *pOdPtr_i32 = NULL;
static REAL32		* CO_CONST *pOdPtr_r32 = NULL;
static CO_CONST VIS_STRING		*pOdConst_VS = NULL;
static CO_CONST UNSIGNED32		*pOdConst_VS_MaxLen = NULL;
static VIS_STRING		*pOdPtr_VS = NULL;
static CO_CONST UNSIGNED32		*pOdPtr_VS_MaxLen = NULL;
static UNSIGNED32		*pOdPtr_VS_ActLen = NULL;
static OCTET_STRING		* CO_CONST *pOdPtr_OS = NULL;
static CO_CONST UNSIGNED32		*pOdPtr_OS_MaxLen =  NULL;
static UNSIGNED32		*pOdPtr_OS_ActLen =  NULL;
static CO_DOMAIN_PTR 	*pOdPtr_Domain = NULL; /*lint !e961 pointer to generic domains */
static UNSIGNED32		*pOdPtr_Domain_MaxLen = NULL;
static UNSIGNED32		*pOdPtr_Domain_ActLen = NULL;
#ifdef CO_EVENT_STORE
static BOOL_T	loadParameterState[CO_LINE_ARRAY_DECL] = { CO_FALSE };
#endif /* CO_EVENT_STORE */
#ifdef CO_STORE_SUPPORTED
static OD_LAST_STORE_T	odLastStore[CO_LINE_ARRAY_DECL];
#endif /* CO_STORE_SUPPORTED */



/***************************************************************************/
/**
* \brief coOdSetCobid - set cob id
*
* This function set the COB-Id for a service indicated by index and subindex.
*
* According to the standard, the COB-ID is disabled first by this function,
* and then the new COB-ID is set.
*
* \return RET_T
*
*/
RET_T coOdSetCobid(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16	index,			/**< index for the cob */
		UNSIGNED8	subIndex,		/**< subIndex for the cob */
		UNSIGNED32	newCobId		/**< new cob-id */
	)
{
RET_T	retVal;

	/* disable cob-id */
	retVal = coOdPutObj_u32(CO_LINE, index, subIndex, CO_COB_INVALID);
	if (retVal == RET_OK)  {
		/* write new cobid */
		retVal = coOdPutObj_u32(CO_LINE, index, subIndex, newCobId);
	}

	return(retVal);
}


/***************************************************************************/
/**
*
* \brief coOdGetObjAddr - get address of a writable object
*
* Get the address of an object from the object dictionary
* for write access
*
* \return pointer to object address, NULL if object not found
*
*/
void *coOdGetObjAddr(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex	/**< subindex of object */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;
UNSIGNED8	*pAddr;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex, &pDesc);
	if (retVal != RET_OK)  {
		return(NULL);
	}
	pAddr = odGetObjAddr(CO_LINE, pDesc, subIndex);

	return(pAddr);
}


/***************************************************************************/
/**
*
* \brief coOdGetObjAddrR - get address of a readable object
*
* Get the address of an object from the object dictionary
* for read access
*
* \return pointer to object address, NULL if object not found
*
*/
CO_CONST void *coOdGetObjAddrR(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex	/**< subindex of object */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;
CO_CONST UNSIGNED8	*pAddr;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex, &pDesc);
	if (retVal != RET_OK)  {
		return(NULL);
	}
	pAddr = odGetObjAddr_R(CO_LINE, pDesc, subIndex);

	return(pAddr);
}


/***************************************************************************/
/**
* \brief coOdGetObj_u8 - get UNSIGNED8 object
*
* Get an object from the object dictionary from type UNSIGNED8.
*
* \return RET_T
*
*/
RET_T coOdGetObj_u8(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex,	/**< subindex of object */
		UNSIGNED8		*pObj		/**< pointer to object */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;


	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_BOOL_CONST:
		case CO_DTYPE_BOOL_VAR:
		case CO_DTYPE_BOOL_PTR:
		case CO_DTYPE_U8_CONST:
		case CO_DTYPE_U8_VAR:
		case CO_DTYPE_U8_PTR:
		case CO_DTYPE_U8_SDO_SERVER:
		case CO_DTYPE_U8_SDO_CLIENT:
		case CO_DTYPE_U8_TPDO:
		case CO_DTYPE_U8_RPDO:
		case CO_DTYPE_U8_TMAP:
		case CO_DTYPE_U8_RMAP:
		case CO_DTYPE_U8_SYNC:
		case CO_DTYPE_U8_EMCY:
		case CO_DTYPE_U8_ERRCTRL:
		case CO_DTYPE_U8_NETWORK:
		case CO_DTYPE_U8_GFC:
		case CO_DTYPE_U8_SRDO:
		case CO_DTYPE_U8_NMT:
			retVal = icoOdGetObj(CO_LINE, pDesc, subIndex, pObj, 0u, 0u, CO_TRUE);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
			break;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdGetObj_u16 - get UNSIGNED16 object
*
* Get an object from the object dictionary from type UNSIGNED16.
*
* \return RET_T
*
*/
RET_T coOdGetObj_u16(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex,	/**< subindex of object */
		UNSIGNED16		*pObj		/**< pointer to object */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_U16_CONST:
		case CO_DTYPE_U16_VAR:
		case CO_DTYPE_U16_PTR:
		case CO_DTYPE_U16_TPDO:
		case CO_DTYPE_U16_RPDO:
		case CO_DTYPE_U16_ERRCTRL:
		case CO_DTYPE_U16_EMCY:
		case CO_DTYPE_U16_NMT:
		case CO_DTYPE_U16_NETWORK:
		case CO_DTYPE_U16_SRDO:
		case CO_DTYPE_U16_FLYMA:
			retVal = icoOdGetObj(CO_LINE, pDesc, subIndex, pObj, 0u, 0u, CO_TRUE);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdGetObj_u32 - get UNSIGNED32 object
*
* Get an object from the object dictionary from type UNSIGNED32.
*
* \return RET_T
*
*/
RET_T coOdGetObj_u32(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex,	/**< subindex of object */
		UNSIGNED32		*pObj		/**< pointer to object */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex, &pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_U32_CONST:
		case CO_DTYPE_U32_VAR:
		case CO_DTYPE_U32_PTR:
		case CO_DTYPE_U32_SDO_SERVER:
		case CO_DTYPE_U32_SDO_CLIENT:
		case CO_DTYPE_U32_TPDO:
		case CO_DTYPE_U32_RPDO:
		case CO_DTYPE_U32_TMAP:
		case CO_DTYPE_U32_RMAP:
		case CO_DTYPE_U32_ERRCTRL:
		case CO_DTYPE_U32_EMCY:
		case CO_DTYPE_U32_SYNC:
		case CO_DTYPE_U32_STORE:
		case CO_DTYPE_U32_SRD:
		case CO_DTYPE_U32_NMT:
		case CO_DTYPE_U32_NETWORK:
		case CO_DTYPE_U32_SRDO:
		case CO_DTYPE_U32_TIME:
			retVal = icoOdGetObj(CO_LINE, pDesc, subIndex, pObj, 0u, 0u, CO_TRUE);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
	}


	return(retVal);
}


#ifdef CO_EXTENDED_DATA_TYPES
/***************************************************************************/
/**
* \brief coOdGetObj_u24 - get UNSIGNED24 object
*
* Get an object from the object dictionary from type UNSIGNED24.
*
* \return RET_T
*
*/
RET_T coOdGetObj_u24(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16	index,		/**< index of object */
		UNSIGNED8	subIndex,	/**< subindex of object */
		UNSIGNED24	*pObj		/**< pointer to object */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_U24_CONST:
		case CO_DTYPE_U24_VAR:
		case CO_DTYPE_U24_PTR:
			retVal = icoOdGetObj(CO_LINE, pDesc, subIndex, pObj, 0u, 0u, CO_TRUE);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
			break;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdGetObj_u40 - get UNSIGNED40 object
*
* Get an object from the object dictionary from type UNSIGNED40
*
* \return RET_T
*
*/
RET_T coOdGetObj_u40(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16	index,		/**< index of object */
		UNSIGNED8	subIndex,	/**< subindex of object */
		UNSIGNED40	*pObj		/**< pointer to object */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_U40_CONST:
		case CO_DTYPE_U40_VAR:
		case CO_DTYPE_U40_PTR:
			retVal = icoOdGetObj(CO_LINE, pDesc, subIndex, pObj, 0u, 0u, CO_TRUE);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
			break;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdGetObj_u48 - get UNSIGNED48 object
*
* Get an object from the object dictionary from type UNSIGNED48
*
* \return RET_T
*
*/
RET_T coOdGetObj_u48(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16	index,		/**< index of object */
		UNSIGNED8	subIndex,	/**< subindex of object */
		UNSIGNED48	*pObj		/**< pointer to object */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_U48_CONST:
		case CO_DTYPE_U48_VAR:
		case CO_DTYPE_U48_PTR:
			retVal = icoOdGetObj(CO_LINE, pDesc, subIndex, pObj, 0u, 0u, CO_TRUE);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
			break;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdGetObj_u64 - get UNSIGNED64 object
*
* Get an object from the object dictionary from type UNSIGNED64
*
* \return RET_T
*
*/
RET_T coOdGetObj_u64(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16	index,		/**< index of object */
		UNSIGNED8	subIndex,	/**< subindex of object */
		UNSIGNED64	*pObj		/**< pointer to object */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_U64_CONST:
		case CO_DTYPE_U64_VAR:
		case CO_DTYPE_U64_PTR:
			retVal = icoOdGetObj(CO_LINE, pDesc, subIndex, pObj, 0u, 0u, CO_TRUE);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
			break;
	}

	return(retVal);
}
#endif /* CO_EXTENDED_DATA_TYPES */


/***************************************************************************/
/**
* \brief coOdGetObj_i8 - get INTEGER8 object
*
* Get an object from the object dictionary from type INTEGER8.
*
* \return RET_T
*
*/
RET_T coOdGetObj_i8(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex,	/**< subindex of object */
		INTEGER8		*pObj		/**< pointer to object */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_I8_VAR:
		case CO_DTYPE_I8_CONST:
		case CO_DTYPE_I8_PTR:
		case CO_DTYPE_U8_SRDO:
			retVal = icoOdGetObj(CO_LINE, pDesc, subIndex, pObj, 0u, 0u, CO_TRUE);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
	}


	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdGetObj_i16 - get INTEGER16 object
*
* Get an object from the object dictionary from type INTEGER16.
*
* \return RET_T
*
*/
RET_T coOdGetObj_i16(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex,	/**< subindex of object */
		INTEGER16		*pObj		/**< pointer to object */
	)
{
RET_T	retVal;
CO_CONST CO_OBJECT_DESC_T *pDesc;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_I16_VAR:
		case CO_DTYPE_I16_PTR:
		case CO_DTYPE_I16_CONST:
		case CO_DTYPE_I16_SRDO:
			retVal = icoOdGetObj(CO_LINE, pDesc, subIndex, pObj, 0u, 0u, CO_TRUE);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdGetObj_i32 - get INTEGER32 object
*
* Get an object from the object dictionary from type INTEGER32.
*
* \return RET_T
*
*/
RET_T coOdGetObj_i32(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex,	/**< subindex of object */
		INTEGER32		*pObj		/**< pointer to object */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_I32_VAR:
		case CO_DTYPE_I32_PTR:
		case CO_DTYPE_I32_CONST:
		case CO_DTYPE_I32_SRDO:
			retVal = icoOdGetObj(CO_LINE, pDesc, subIndex, pObj, 0u, 0u, CO_TRUE);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdGetObj_r32 - get REAL32 object
*
* Get an object from the object dictionary from type REAL32.
*
* \return RET_T
*
*/
RET_T coOdGetObj_r32(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex,	/**< subindex of object */
		REAL32			*pObj		/**< pointer to object */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_R32_VAR:
		case CO_DTYPE_R32_PTR:
		case CO_DTYPE_R32_CONST:
		case CO_DTYPE_R32_SRDO:
			retVal = icoOdGetObj(CO_LINE, pDesc, subIndex, pObj, 0u, 0u, CO_TRUE);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdPutObj_u8 - put UNSIGNED8 value to object
*
* Put value from type UNSIGNED8 to the object dictionary
*
* \return RET_T
*
*/
RET_T coOdPutObj_u8(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex,	/**< subindex of object */
		UNSIGNED8		newVal		/**< new value */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;
BOOL_T	changed = CO_FALSE;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_BOOL_VAR:
		case CO_DTYPE_BOOL_PTR:
		case CO_DTYPE_U8_VAR:
		case CO_DTYPE_U8_PTR:
			retVal = icoOdPutObj(CO_LINE, pDesc, subIndex, &newVal, 0u, 0u, CO_TRUE, &changed);
			break;

		case CO_DTYPE_U8_SDO_SERVER:
		case CO_DTYPE_U8_SDO_CLIENT:
		case CO_DTYPE_U8_TPDO:
		case CO_DTYPE_U8_RPDO:
		case CO_DTYPE_U8_TMAP:
		case CO_DTYPE_U8_RMAP:
		case CO_DTYPE_U8_SYNC:
		case CO_DTYPE_U8_EMCY:
		case CO_DTYPE_U8_ERRCTRL:
		case CO_DTYPE_U8_NETWORK:
		case CO_DTYPE_U8_GFC:
		case CO_DTYPE_U8_SRDO:
			retVal = checkObjValue_u8(CO_LINE, pDesc, newVal);
			if (retVal == RET_OK)  {
				retVal = icoOdPutObj(CO_LINE, pDesc, subIndex, &newVal, 0u, 0u, CO_TRUE, &changed);
			}
			break;
		case CO_DTYPE_U8_NMT:
			retVal = icoOdPutObj(CO_LINE, pDesc, subIndex, &newVal, 0u, 0u, CO_TRUE, &changed);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
	}

	if (retVal == RET_OK)  {
		retVal = icoEventObjectChanged(CO_LINE, pDesc, index, subIndex, changed);
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdPutObj_u16 - put UNSIGNED16 value to object
*
* Put value from type UNSIGNED16 to the object dictionary
*
* \return RET_T
*
*/
RET_T coOdPutObj_u16(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex,	/**< subindex of object */
		UNSIGNED16		newVal		/**< new value */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;
BOOL_T	changed = CO_FALSE;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_U16_VAR:
		case CO_DTYPE_U16_PTR:
			retVal = icoOdPutObj(CO_LINE, pDesc, subIndex, &newVal, 0u, 0u, CO_TRUE, &changed);
			break;

		case CO_DTYPE_U16_TPDO:
		case CO_DTYPE_U16_RPDO:
		case CO_DTYPE_U16_ERRCTRL:
		case CO_DTYPE_U16_EMCY:
		case CO_DTYPE_U16_NMT:
		case CO_DTYPE_U16_NETWORK:
		case CO_DTYPE_U16_SRDO:
		case CO_DTYPE_U16_FLYMA:
			retVal = checkObjValue_u16(CO_LINE, pDesc, newVal);
			if (retVal == RET_OK)  {
				retVal = icoOdPutObj(CO_LINE, pDesc, subIndex, &newVal, 0u, 0u, CO_TRUE, &changed);
			}
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
	}

	if (retVal == RET_OK)  {
		retVal = icoEventObjectChanged(CO_LINE, pDesc, index, subIndex, changed);
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdPutObj_u32 - put UNSIGNED32 value to object
*
* Put value from type UNSIGNED32 to the object dictionary
*
* \return RET_T
*
*/
RET_T coOdPutObj_u32(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex,	/**< subindex of object */
		UNSIGNED32		newVal		/**< new value */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;
BOOL_T	changed = CO_FALSE;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex, &pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_U32_VAR:
		case CO_DTYPE_U32_PTR:
			retVal = icoOdPutObj(CO_LINE, pDesc, subIndex, &newVal, 0u, 0u, CO_TRUE, &changed);
			break;

		case CO_DTYPE_U32_SDO_SERVER:
		case CO_DTYPE_U32_SDO_CLIENT:
		case CO_DTYPE_U32_TPDO:
		case CO_DTYPE_U32_RPDO:
		case CO_DTYPE_U32_TMAP:
		case CO_DTYPE_U32_RMAP:
		case CO_DTYPE_U32_ERRCTRL:
		case CO_DTYPE_U32_EMCY:
		case CO_DTYPE_U32_SYNC:
		case CO_DTYPE_U32_TIME:
		case CO_DTYPE_U32_NETWORK:
		case CO_DTYPE_U32_NMT:
		case CO_DTYPE_U32_SRDO:
		case CO_DTYPE_U32_STORE:
			retVal = checkObjValue_u32(CO_LINE, pDesc, newVal);
			if (retVal == RET_OK)  {
				retVal = icoOdPutObj(CO_LINE, pDesc, subIndex, &newVal, 0u, 0u, CO_TRUE,
					&changed);
			}
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
	}

	if (retVal == RET_OK)  {
		retVal = icoEventObjectChanged(CO_LINE, pDesc, index, subIndex, changed);
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdPutObj_i8 - Put INTEGER8 object
*
* Put value from type INTEGER8 to the object dictionary
*
* \return RET_T
*
*/
RET_T coOdPutObj_i8(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex,	/**< subindex of object */
		INTEGER8		newVal		/**< new value */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;
BOOL_T	changed = CO_FALSE;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_I8_VAR:
		case CO_DTYPE_I8_PTR:
		case CO_DTYPE_I8_SRDO:
			retVal = icoOdPutObj(CO_LINE, pDesc, subIndex, &newVal, 0u, 0u, CO_TRUE, &changed);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
	}

	if (retVal == RET_OK)  {
		retVal = icoEventObjectChanged(CO_LINE, pDesc, index, subIndex, changed);
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdPutObj_i16 - Put INTEGER16 object
*
* Put value from type INTEGER16 to the object dictionary
*
* \return RET_T
*
*/
RET_T coOdPutObj_i16(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex,	/**< subindex of object */
		INTEGER16		newVal		/**< new value */
	)
{
RET_T	retVal;
CO_CONST CO_OBJECT_DESC_T *pDesc;
BOOL_T	changed = CO_FALSE;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_I16_VAR:
		case CO_DTYPE_I16_PTR:
		case CO_DTYPE_I16_SRDO:
			retVal = icoOdPutObj(CO_LINE, pDesc, subIndex, &newVal, 0u, 0u, CO_TRUE, &changed);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
	}

	if (retVal == RET_OK)  {
		retVal = icoEventObjectChanged(CO_LINE, pDesc, index, subIndex, changed);
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdPutObj_i32 - Put INTEGER32 object
*
* Put value from type INTEGER32 to the object dictionary
*
* \return RET_T
*
*/
RET_T coOdPutObj_i32(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex,	/**< subindex of object */
		INTEGER32		newVal		/**< new value */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;
BOOL_T	changed = CO_FALSE;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_I32_VAR:
		case CO_DTYPE_I32_PTR:
		case CO_DTYPE_I32_SRDO:
			retVal = icoOdPutObj(CO_LINE, pDesc, subIndex, &newVal, 0u, 0u, CO_TRUE, &changed);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
			break;
	}

	if (retVal == RET_OK)  {
		retVal = icoEventObjectChanged(CO_LINE, pDesc, index, subIndex, changed);
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdPutObj_r32 - Put REAL32 object
*
* Put value from type REAL32 to the object dictionary
*
* \return RET_T
*
*/
RET_T coOdPutObj_r32(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex,	/**< subindex of object */
		REAL32			newVal		/**< new value */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;
BOOL_T	changed = CO_FALSE;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_R32_VAR:
		case CO_DTYPE_R32_PTR:
		case CO_DTYPE_R32_SRDO:
			retVal = icoOdPutObj(CO_LINE, pDesc, subIndex, &newVal, 0u, 0u, CO_TRUE, &changed);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
			break;
	}

	if (retVal == RET_OK)  {
		retVal = icoEventObjectChanged(CO_LINE, pDesc, index, subIndex, changed);
	}

	return(retVal);
}


#ifdef CO_EXTENDED_DATA_TYPES
/***************************************************************************/
/**
* \brief coOdPutObj_u24 - Put UNSIGNED24 Object
*
* Put value from type UNSIGNED24 to the object dictionary
*
* \return RET_T
*
*/
RET_T coOdPutObj_u24(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16	index,		/**< index of object */
		UNSIGNED8	subIndex,	/**< subindex of object */
		UNSIGNED24	newVal		/**< new value */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;
BOOL_T	changed = CO_FALSE;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_U24_VAR:
		case CO_DTYPE_U24_PTR:
			retVal = icoOdPutObj(CO_LINE, pDesc, subIndex, &newVal, 0u, 0u, CO_TRUE, &changed);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
			break;
	}

	if (retVal == RET_OK)  {
		retVal = icoEventObjectChanged(CO_LINE, pDesc, index, subIndex, changed);
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdPutObj_u40 - Put UNSIGNED40 Object
*
* Put value from type UNSIGNED24 to the object dictionary
*
* \return RET_T
*
*/
RET_T coOdPutObj_u40(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16	index,		/**< index of object */
		UNSIGNED8	subIndex,	/**< subindex of object */
		UNSIGNED40	newVal		/**< new value */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;
BOOL_T	changed = CO_FALSE;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_U40_VAR:
		case CO_DTYPE_U40_PTR:
			retVal = icoOdPutObj(CO_LINE, pDesc, subIndex, &newVal, 0u, 0u, CO_TRUE, &changed);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
			break;
	}

	if (retVal == RET_OK)  {
		retVal = icoEventObjectChanged(CO_LINE, pDesc, index, subIndex, changed);
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdPutObj_u48 - Put UNSIGNED48 Object
*
* Put value from type UNSIGNED24 to the object dictionary
*
* \return RET_T
*
*/
RET_T coOdPutObj_u48(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16	index,		/**< index of object */
		UNSIGNED8	subIndex,	/**< subindex of object */
		UNSIGNED48	newVal		/**< new value */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;
BOOL_T	changed = CO_FALSE;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_U48_VAR:
		case CO_DTYPE_U48_PTR:
			retVal = icoOdPutObj(CO_LINE, pDesc, subIndex, &newVal, 0u, 0u, CO_TRUE, &changed);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
			break;
	}

	if (retVal == RET_OK)  {
		retVal = icoEventObjectChanged(CO_LINE, pDesc, index, subIndex, changed);
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdPutObj_u64 - Put UNSIGNED64 Object
*
* Put value from type UNSIGNED24 to the object dictionary
*
* \return RET_T
*
*/
RET_T coOdPutObj_u64(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16	index,		/**< index of object */
		UNSIGNED8	subIndex,	/**< subindex of object */
		UNSIGNED64	newVal		/**< new value */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;
BOOL_T	changed = CO_FALSE;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_U64_VAR:
		case CO_DTYPE_U64_PTR:
			retVal = icoOdPutObj(CO_LINE, pDesc, subIndex, &newVal, 0u, 0u, CO_TRUE, &changed);
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
			break;
	}

	if (retVal == RET_OK)  {
		retVal = icoEventObjectChanged(CO_LINE, pDesc, index, subIndex, changed);
	}

	return(retVal);
}
#endif /* CO_EXTENDED_DATA_TYPES */


/***************************************************************************/
/**
* \internal
*
* \brief icoOdGetObj - get data from object
*
* copy data from OD to given pointer
*
*
* \return RET_T
*
*/
RET_T icoOdGetObj(
		CO_LINE_TYPE		CO_LINE,	/* can line */
		CO_CONST CO_OBJECT_DESC_T	*pDesc,	/* pointer for description index */
		UNSIGNED8			subIndex,	/* subindex */
		void				*pData,		/* pointer to data */
		UNSIGNED32			offset,		/* offset at object data in bytes */
		UNSIGNED32			maxData,	/* buffer len of pData in bytes */
		BOOL_T				internal	/* data are used internal */
	)
{
CO_CONST UNSIGNED8	*pObjAddr;
UNSIGNED32	size = 0u;
RET_T	retVal = RET_VALUE_NOT_AVAILABLE;
UNSIGNED32	packOffset = 0u;
UNSIGNED16	attr = pDesc->attr;

	pObjAddr = odGetObjAddr_R(CO_LINE, pDesc, subIndex);
	if (pObjAddr != NULL)  {
		/* get object size */
		size = coOdGetObjSize(pDesc);

		/* request data outsize of object return error */
		if (offset >= size)  {
			return(RET_OUT_OF_MEMORY);
		}
		/* return only rest data */
		size -= offset;
		if (maxData != 0u)  {
			if (size > maxData)  {
				size = maxData;
			}
		}

#ifdef CO_CPU_DSP
		odCorrectObjOffs(pDesc, &offset, &packOffset, &attr);
#endif /* CO_CPU_DSP */

		pObjAddr += offset;

		/* lock OD */
		CO_OS_LOCK_OD

		if (internal == CO_TRUE)  {
			(void)coreMemcpy(pData, pObjAddr, size, (attr & CO_ATTR_NUM));

		} else {
			CORE_DATA_TYPE_T dType;
			if ((attr & CO_ATTR_NUM) != 0u)  {
				dType = icoGetNumericDatatype(size);
			} else {
				dType = CORE_DTYPE_NON_NUMERIC;
			}
			coreMemcpyUnpack(pData, pObjAddr, size,
				packOffset, dType, 0u);
		}
		/* unlock OD */
		CO_OS_UNLOCK_OD

		retVal = RET_OK;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \internal
*
* \brief icoOdPutObj - put data to object
*
* copy data to OD from given pointer
*
*
* \return RET_T
*
*/
RET_T icoOdPutObj(
		CO_LINE_TYPE		CO_LINE,	/* can line */
		CO_CONST CO_OBJECT_DESC_T	*pDesc,	/* pointer for description index */
		UNSIGNED8			subIndex,	/* subindex */
		CO_CONST void		*pData,		/* pointer to data */
		UNSIGNED32			offset,		/* offset at object */
		UNSIGNED32			maxData,	/* buffer len of pData */
		BOOL_T				internal,	/* data are used internal */
		BOOL_T				*pChanged	/* object got new value */
	)
{
UNSIGNED8	*pObjAddr = NULL;
UNSIGNED32	size = 0u;
RET_T		retVal = RET_INVALID_PARAMETER;
UNSIGNED32	packOffset = 0u;
UNSIGNED16	attr = pDesc->attr;

	switch (pDesc->dType)  {
		case CO_DTYPE_BOOL_CONST:
		case CO_DTYPE_U8_CONST:
		case CO_DTYPE_U16_CONST:
		case CO_DTYPE_U32_CONST:
		case CO_DTYPE_I8_CONST:
		case CO_DTYPE_I16_CONST:
		case CO_DTYPE_I32_CONST:
		case CO_DTYPE_R32_CONST:
		case CO_DTYPE_VS_CONST:
			pObjAddr = NULL;
			break;
#ifdef CO_EXTENDED_DATA_TYPES
		case CO_DTYPE_U24_CONST:
		case CO_DTYPE_U40_CONST:
		case CO_DTYPE_U64_CONST:
			pObjAddr = NULL;
			break;
#endif /* CO_EXTENDED_DATA_TYPES */
		default:
			pObjAddr = odGetObjAddr(CO_LINE, pDesc, subIndex);
			break;
	}

	if (pObjAddr != NULL)  {
		size = coOdGetObjMaxSize(pDesc);

		if (offset >= size)  {
			return(RET_OUT_OF_MEMORY);
		}
		size -= offset;
		if (maxData != 0u)  {
			if (size > maxData)  {
				size = maxData;
			}
		}

#ifdef CO_CPU_DSP
		odCorrectObjOffs(pDesc, &offset, &packOffset, &attr);
#endif /* CO_CPU_DSP */

		pObjAddr += offset;

		/* lock OD */
		CO_OS_LOCK_OD

		/* check for new data */
		if (internal == CO_TRUE)   {
			*pChanged = coreMemcpy((void *)pObjAddr, pData, size,
				(attr & CO_ATTR_NUM));
		} else {
			CORE_DATA_TYPE_T dType;
			if ((attr & CO_ATTR_NUM) != 0u)  {
				dType = icoGetNumericDatatype(size);
			} else {
				dType = CORE_DTYPE_NON_NUMERIC;
			}
			*pChanged = coreMemcpyPack(pObjAddr, pData, size,
				packOffset,
				dType,
				0u);
		}

		/* unlock OD */
		CO_OS_UNLOCK_OD

		retVal = RET_OK;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \internal
*
* \brief odGetObjAddr_R - get object address for read objects
*
* \return RET_T
*
*/
static CO_CONST UNSIGNED8 *odGetObjAddr_R(
		CO_LINE_TYPE	CO_LINE,			/* can line */
		CO_CONST CO_OBJECT_DESC_T	*pDesc,	/* pointer for description index */
		UNSIGNED8					subIndex	/* sub index */
	)
{
CO_CONST void *pObjAddr = NULL;
UNSIGNED16	offs;

	/* offset depends on attribute CO_ATTR_COMPACT */
	if ((pDesc->attr & CO_ATTR_COMPACT) != 0u)  {
		offs = (pDesc->tableIdx + subIndex) - pDesc->subIndex;
	} else {
		offs = pDesc->tableIdx;
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_BOOL_CONST:
		case CO_DTYPE_U8_CONST:
			if (pOdConst_u8 != NULL)  {
				pObjAddr = &pOdConst_u8[offs];
			}
			break;
		case CO_DTYPE_U16_CONST:
			if (pOdConst_u16 != NULL)  {
				pObjAddr = &pOdConst_u16[offs];
			}
			break;
		case CO_DTYPE_U32_CONST:
			/* table initialized ? */
			if (pOdConst_u32 != NULL)  {
				pObjAddr = &pOdConst_u32[offs];
			}
			break;
		case CO_DTYPE_I8_CONST:
			/* table initialized ? */
			if (pOdConst_i8 != NULL)  {
				pObjAddr = &pOdConst_i8[offs];
			}
			break;
		case CO_DTYPE_I16_CONST:
			/* table initialized ? */
			if (pOdConst_i16 != NULL)  {
				pObjAddr = &pOdConst_i16[offs];
			}
			break;
		case CO_DTYPE_I32_CONST:
			/* table initialized ? */
			if (pOdConst_i32 != NULL)  {
				pObjAddr = &pOdConst_i32[offs];
			}
			break;
		case CO_DTYPE_R32_CONST:
			/* table initialized ? */
			if (pOdConst_r32 != NULL)  {
				pObjAddr = &pOdConst_r32[offs];
			}
			break;

#ifdef CO_PDO_RECEIVE_CNT
		case CO_DTYPE_U8_RMAP:
		case CO_DTYPE_U32_RMAP:
			pObjAddr = icoRecMapGetObjectAddr_R(CO_LINE, pDesc->tableIdx, subIndex);
			break;
#endif /* CO_PDO_RECEIVE_CNT */

#ifdef CO_PDO_TRANSMIT_CNT
		case CO_DTYPE_U8_TMAP:
		case CO_DTYPE_U32_TMAP:
			pObjAddr = icoTrMapGetObjectAddr_R(CO_LINE, pDesc->tableIdx, subIndex);
			break;
#endif /* CO_PDO_TRANSMIT_CNT */

#ifdef CO_EXTENDED_DATA_TYPES
		case CO_DTYPE_U24_CONST:
			if (pOdConst_u24 != NULL)  {
				pObjAddr = &pOdConst_u24[offs];
			}
			break;
		case CO_DTYPE_U40_CONST:
			if (pOdConst_u40 != NULL)  {
				pObjAddr = &pOdConst_u40[offs];
			}
			break;
		case CO_DTYPE_U48_CONST:
			if (pOdConst_u48 != NULL)  {
				pObjAddr = &pOdConst_u48[offs];
			}
			break;
		case CO_DTYPE_U64_CONST:
			if (pOdConst_u64 != NULL)  {
				pObjAddr = &pOdConst_u64[offs];
			}
			break;
#endif /* CO_EXTENDED_DATA_TYPES */

		default:
			pObjAddr = odGetObjAddr(CO_LINE, pDesc, subIndex);
			break;
	}

	return((CO_CONST UNSIGNED8 *)pObjAddr);
}


/***************************************************************************/
/**
* \internal
*
* \brief odGetObjAddr - get object address (read/write)
*
* \return RET_T
*
*/
static UNSIGNED8 *odGetObjAddr(
		CO_LINE_TYPE				CO_LINE,	/* can line */
		CO_CONST CO_OBJECT_DESC_T	*pDesc,		/* pointer for description index */
		UNSIGNED8					subIndex	/* sub index */
	)
{
void *pObjAddr = NULL;
UNSIGNED16	offs;

	/* offset depends on attribute CO_ATTR_COMPACT */
	if ((pDesc->attr & CO_ATTR_COMPACT) != 0u)  {
		offs = pDesc->tableIdx + subIndex;
		offs -= pDesc->subIndex;
	} else {
		offs = pDesc->tableIdx;
	}

#ifdef CO_DYNAMIC_OBJDIC
	if ((pDesc->attr & CO_ATTR_DYNOD) != 0u)  {
		pObjAddr = coDynOdGetObjAddr(CO_LINE, pDesc);
		return((UNSIGNED8 *)pObjAddr);
	}
#endif /* CO_DYNAMIC_OBJDIC */

	switch (pDesc->dType)  {
		case CO_DTYPE_BOOL_VAR:
		case CO_DTYPE_U8_VAR:
			/* table initialized ? */
			if (pOdVar_u8 != NULL)  {
				pObjAddr = &pOdVar_u8[offs];
			}
			break;
		case CO_DTYPE_U16_VAR:
			/* table initialized ? */
			if (pOdVar_u16 != NULL)  {
				pObjAddr = &pOdVar_u16[offs];
			}
			break;
		case CO_DTYPE_U32_VAR:
			/* table initialized ? */
			if (pOdVar_u32 != NULL)  {
				pObjAddr = &pOdVar_u32[offs];
			}
			break;
		case CO_DTYPE_R32_VAR:
			/* table initialized ? */
			if (pOdVar_r32 != NULL)  {
				pObjAddr = &pOdVar_r32[offs];
			}
			break;
		case CO_DTYPE_U8_PTR:
		case CO_DTYPE_BOOL_PTR:
			if (pOdPtr_u8 != NULL)  {
				pObjAddr = pOdPtr_u8[offs];
			}
			break;
		case CO_DTYPE_U16_PTR:
			if (pOdPtr_u16 != NULL)  {
				pObjAddr = pOdPtr_u16[offs];
			}
			break;
		case CO_DTYPE_U32_PTR:
			/* table initialized ? */
			if (pOdPtr_u32 != NULL)  {
				pObjAddr = pOdPtr_u32[offs];
			}
			break;
		case CO_DTYPE_I8_VAR:
			/* table initialized ? */
			if (pOdVar_i8 != NULL)  {
				pObjAddr = &pOdVar_i8[offs];
			}
			break;
		case CO_DTYPE_I16_VAR:
			/* table initialized ? */
			if (pOdVar_i16 != NULL)  {
				pObjAddr = &pOdVar_i16[offs];
			}
			break;
		case CO_DTYPE_I32_VAR:
			/* table initialized ? */
			if (pOdVar_i32 != NULL)  {
				pObjAddr = &pOdVar_i32[offs];
			}
			break;
		case CO_DTYPE_I8_PTR:
			if (pOdPtr_i8 != NULL)  {
				pObjAddr = pOdPtr_i8[offs];
			}
			break;
		case CO_DTYPE_I16_PTR:
			if (pOdPtr_i16 != NULL)  {
				pObjAddr = pOdPtr_i16[offs];
			}
			break;
		case CO_DTYPE_I32_PTR:
			/* table initialized ? */
			if (pOdPtr_i32 != NULL)  {
				pObjAddr = pOdPtr_i32[offs];
			}
			break;
		case CO_DTYPE_R32_PTR:
			/* table initialized ? */
			if (pOdPtr_r32 != NULL)  {
				pObjAddr = pOdPtr_r32[offs];
			}
			break;
		case CO_DTYPE_VS_CONST:
			if (pOdConst_VS != NULL)  {
				pObjAddr = pOdConst_VS[offs];
			}
			break;
		case CO_DTYPE_VS_PTR:
			if (pOdPtr_VS != NULL)  {
				pObjAddr = pOdPtr_VS[offs];
			}
			break;
		case CO_DTYPE_OS_PTR:
			if (pOdPtr_OS != NULL)  {
				pObjAddr = pOdPtr_OS[offs];
			}
			break;
		case CO_DTYPE_DOMAIN:
			if (pOdPtr_Domain != NULL)  {
				pObjAddr = pOdPtr_Domain[offs];
			}
			break;
#ifdef CO_SDO_SERVER_CNT
		case CO_DTYPE_U8_SDO_SERVER:
		case CO_DTYPE_U32_SDO_SERVER:
			pObjAddr = icoSdoGetObjectAddr(CO_LINE, pDesc->tableIdx, pDesc->subIndex);
			break;
#endif /* CO_SDO_SERVER_CNT */
#ifdef CO_SDO_CLIENT_CNT
		case CO_DTYPE_U8_SDO_CLIENT:
		case CO_DTYPE_U32_SDO_CLIENT:
			pObjAddr = icoSdoClientGetObjectAddr(CO_LINE, (UNSIGNED8)pDesc->tableIdx,
					(UNSIGNED8)pDesc->subIndex);
			break;
#endif /* CO_SDO_CLIENT_CNT */

#ifdef CO_PDO_TRANSMIT_CNT
		case CO_DTYPE_U8_TPDO:
		case CO_DTYPE_U16_TPDO:
		case CO_DTYPE_U32_TPDO:
			pObjAddr = icoTrPdoGetObjectAddr(CO_LINE, pDesc->tableIdx, pDesc->subIndex);
			break;

		case CO_DTYPE_U8_TMAP:
		case CO_DTYPE_U32_TMAP:
			pObjAddr = icoTrMapGetObjectAddr(CO_LINE, pDesc->tableIdx, subIndex);
			break;
#endif /* CO_PDO_TRANSMIT_CNT */

#ifdef CO_PDO_RECEIVE_CNT
		case CO_DTYPE_U8_RPDO:
		case CO_DTYPE_U16_RPDO:
		case CO_DTYPE_U32_RPDO:
			pObjAddr = icoRecPdoGetObjectAddr(CO_LINE, pDesc->tableIdx, pDesc->subIndex);
			break;

		case CO_DTYPE_U8_RMAP:
		case CO_DTYPE_U32_RMAP:
			pObjAddr = icoRecMapGetObjectAddr(CO_LINE, pDesc->tableIdx, subIndex);
			break;
#endif /* CO_PDO_RECEIVE_CNT */

#ifdef CANOPEN_SUPPORTED
		case CO_DTYPE_U8_ERRCTRL:
		case CO_DTYPE_U16_ERRCTRL:
		case CO_DTYPE_U32_ERRCTRL:
			pObjAddr = icoErrCtrlGetObjectAddr(CO_LINE, pDesc->tableIdx, pDesc->subIndex);
			break;
#endif /* CANOPEN_SUPPORTED */

#ifdef CO_SYNC_SUPPORTED
		case CO_DTYPE_U8_SYNC:
		case CO_DTYPE_U32_SYNC:
			pObjAddr = icoSyncGetObjectAddr(CO_LINE, pDesc->tableIdx);
			break;
#endif /* CO_SYNC_SUPPORTED */

#if defined(CO_EMCY_PRODUCER) || defined (CO_EMCY_CONSUMER_CNT)
		case CO_DTYPE_U8_EMCY:
		case CO_DTYPE_U16_EMCY:
		case CO_DTYPE_U32_EMCY:
			pObjAddr = icoEmcyGetObjectAddr(CO_LINE, pDesc->tableIdx, pDesc->subIndex);
			break;
#endif /* defined(CO_EMCY_PRODUCER) || defined (CO_EMCY_CONSUMER_CNT) */

#ifdef CO_TIME_SUPPORTED
		case CO_DTYPE_U32_TIME:
			pObjAddr = icoTimeGetObjectAddr(CO_LINE);
			break;
#endif /* CO_TIME_SUPPORTED */

#ifdef CO_STORE_SUPPORTED
		case CO_DTYPE_U32_STORE:
			pObjAddr = icoStoreGetObjectAddr(CO_LINE, pDesc->tableIdx, pDesc->subIndex);
			break;
#endif /* CO_STORE_SUPPORTED */

#if defined(CO_NMT_MASTER) || defined(CO_SELF_STARTING_DEVICE)
		case CO_DTYPE_U8_NMT:
		case CO_DTYPE_U16_NMT:
		case CO_DTYPE_U32_NMT:
			pObjAddr = icoNmtGetObjectAddr(CO_LINE, pDesc->tableIdx, subIndex);
			break;
#endif /* defined(CO_NMT_MASTER) || defined(CO_SELF_STARTING_DEVICE) */

#ifdef CO_SRD_SUPPORTED
		case CO_DTYPE_U32_SRD:
			pObjAddr = icoSrdGetObjectAddr(CO_LINE, pDesc->tableIdx);
			break;
#endif /* CO_SRD_SUPPORTED */

#ifdef CO_FLYING_MASTER_SUPPORTED
		case CO_DTYPE_U16_FLYMA:
			pObjAddr = icoFlymaGetObjectAddr(CO_LINE, pDesc->tableIdx, pDesc->subIndex);
			break;
#endif /* CO_FLYING_MASTER_SUPPORTED */

#ifdef CO_NETWORK_ROUTING_CNT
		case CO_DTYPE_U8_NETWORK:
		case CO_DTYPE_U16_NETWORK:
		case CO_DTYPE_U32_NETWORK:
			pObjAddr = icoNetworkGetObjectAddr(CO_LINE, pDesc->tableIdx, subIndex);
			break;
#endif /*  CO_NETWORK_ROUTING_CNT */

#ifdef CO_SRDO_SUPPORTED
		case CO_DTYPE_U8_SRDO:
		case CO_DTYPE_U16_SRDO:
		case CO_DTYPE_U32_SRDO:
		case CO_DTYPE_I8_SRDO:
		case CO_DTYPE_I16_SRDO:
		case CO_DTYPE_I32_SRDO:
		case CO_DTYPE_R32_SRDO:
			pObjAddr = icoSrdoGetObjectAddr(CO_LINE, pDesc->tableIdx, pDesc->subIndex, pDesc->dType);
			break;
#endif /* CO_SRDO_SUPPORTED */

#ifdef CO_GFC_SUPPORTED
		case CO_DTYPE_U8_GFC:
			pObjAddr = icoGfcGetObjectAddr(CO_LINE);
			break;
#endif /* CO_GFC_SUPPORTED */

#ifdef CO_EXTENDED_DATA_TYPES
		case CO_DTYPE_U24_VAR:
			/* table initialized ? */
			if (pOdVar_u24 != NULL)  {
				pObjAddr = &pOdVar_u24[offs];
			}
			break;
		case CO_DTYPE_U40_VAR:
			/* table initialized ? */
			if (pOdVar_u40 != NULL)  {
				pObjAddr = &pOdVar_u40[offs];
			}
			break;
		case CO_DTYPE_U48_VAR:
			/* table initialized ? */
			if (pOdVar_u48 != NULL)  {
				pObjAddr = &pOdVar_u48[offs];
			}
			break;
		case CO_DTYPE_U64_VAR:
			/* table initialized ? */
			if (pOdVar_u64 != NULL)  {
				pObjAddr = &pOdVar_u64[offs];
			}
			break;

		case CO_DTYPE_U24_PTR:
			if (pOdPtr_u24 != NULL)  {
				pObjAddr = pOdPtr_u24[offs];
			}
			break;
		case CO_DTYPE_U40_PTR:
			if (pOdPtr_u40 != NULL)  {
				pObjAddr = pOdPtr_u40[offs];
			}
			break;
		case CO_DTYPE_U48_PTR:
			if (pOdPtr_u48 != NULL)  {
				pObjAddr = pOdPtr_u48[offs];
			}
			break;
		case CO_DTYPE_U64_PTR:
			if (pOdPtr_u64 != NULL)  {
				pObjAddr = pOdPtr_u64[offs];
			}
			break;
#endif /* CO_EXTENDED_DATA_TYPES */

		default:
			break;
	}

	return((UNSIGNED8 *)pObjAddr);
}


#ifdef CO_CPU_DSP
/***************************************************************************/
/**
* \internal
*
* \brief odCorrectObjOffs - correct object address offset for DSP domains
*
* \return RET_T
*
*/
void odCorrectObjOffs(
		CO_CONST CO_OBJECT_DESC_T	*pDesc,		/* pointer for description index */
		UNSIGNED32			*pOffset,
		UNSIGNED32			*pPackOffset,
		UNSIGNED16			*pAttr
	)
{
	switch (pDesc->dType)  {
		case CO_DTYPE_DOMAIN:
		case CO_DTYPE_OS_PTR:
			*pPackOffset = *pOffset % CO_CPU_DSP_BYTESIZE;
			*pOffset = *pOffset / CO_CPU_DSP_BYTESIZE;
			*pAttr |= CO_ATTR_NUM;
			break;

		default:
			break;
	}
}
#endif /* CO_CPU_DSP */


/***************************************************************************/
/**
* \brief coOdGetObjAttribute - get object attribute
*
* This function returns the attribute of the object from the given
* object description.
*
* \return attribute
*
*/
UNSIGNED16 coOdGetObjAttribute(
		CO_CONST CO_OBJECT_DESC_T	*pObjDesc	/**< pointer to object description */
	)
{
	return(pObjDesc->attr);
}


/***************************************************************************/
/**
* \brief coOdDomainAddrSet - set domain address
*
* This function sets the adress and the size of a domain.<br>
* At the initialization time,
* domains are not initialized at the object dictionary.
* This has to be done by this function.
* 
* \return RET_T
*
*/
RET_T coOdDomainAddrSet(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex,	/**< subindex of object */
		CO_DOMAIN_PTR	pAddr,		/**< pointer to domain */
		UNSIGNED32		size		/**< domain length */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex, &pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	if (pDesc->dType != CO_DTYPE_DOMAIN)  {
		return(RET_SDO_DATA_TYPE_NOT_MATCH);
	}

	pOdPtr_Domain[pDesc->tableIdx] = pAddr;
	pOdPtr_Domain_MaxLen[pDesc->tableIdx] = size;
	pOdPtr_Domain_ActLen[pDesc->tableIdx] = size;

	return(RET_OK);
}


/***************************************************************************/
/**
* \brief coOdVisStringSet - set address and len for visible string
*
* This function change the address and current length if a visible string object.
* It can only be used for non-constant strings,
* defined as user variable.
* Please note, the maximal object len will not be changed.
* 
* \return RET_T
*
*/
RET_T coOdVisStringSet(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16	index,		/**< index of object */
		UNSIGNED8	subIndex,	/**< subindex of object */
		VIS_STRING	pAddr,		/**< pointer to string */
		UNSIGNED32	size		/**< string length */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex, &pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	if (pDesc->dType != CO_DTYPE_VS_PTR)  {
		return(RET_SDO_DATA_TYPE_NOT_MATCH);
	}

	pOdPtr_VS[pDesc->tableIdx] = pAddr;
	pOdPtr_VS_ActLen[pDesc->tableIdx] = size;

	return(RET_OK);
}


/***************************************************************************/
/**
* \brief coOdDomainSetActualSize - set actual domain size
*
* This function change the address and current size if a domain object.
* Please note, the maximal object len will not be changed.
* 
* \return RET_T
*
*/
RET_T coOdDomainSetActualSize(
		CO_LINE_TYPE	CO_LINE,	/**< can line */
		UNSIGNED16		index,		/**< index of object */
		UNSIGNED8		subIndex,	/**< subindex of object */
		CO_DOMAIN_PTR	pAddr,		/**< pointer to domain */
		UNSIGNED32		size		/**< actual domain length */
	)
{
CO_CONST CO_OBJECT_DESC_T *pDesc;
RET_T	retVal;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex, &pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	if (pDesc->dType != CO_DTYPE_DOMAIN)  {
		return(RET_SDO_DATA_TYPE_NOT_MATCH);
	}

	pOdPtr_Domain[pDesc->tableIdx] = pAddr;
	pOdPtr_Domain_ActLen[pDesc->tableIdx] = size;

	return(RET_OK);
}


/***************************************************************************/
/**
* \internal
*
* \brief checkObjValue_u8 - check object limits for u8 value
*
*
* \return RET_T
*
*/
static RET_T checkObjValue_u8(
		CO_LINE_TYPE		CO_LINE,		/* can line */
		CO_CONST CO_OBJECT_DESC_T *pDesc,	/* pointer to object description */
		CO_CONST UNSIGNED8	value			/* value u8 */
	)
{
RET_T	retVal = RET_INVALID_PARAMETER;

#ifdef CO_EVENT_STORE
	/* In init and load there is no limit check */
	if (loadParameterState[CO_LINE] == CO_TRUE) {
		return RET_OK;
	}
#endif /* CO_EVENT_STORE */


	switch (pDesc->dType)  {
#ifdef CO_SDO_SERVER_CNT
		case CO_DTYPE_U8_SDO_SERVER:
			retVal = icoSdoCheckObjLimitNode(CO_LINE, pDesc->tableIdx);
			break;
#endif /* CO_SDO_SERVER_CNT */

#ifdef CO_SDO_CLIENT_CNT
		case CO_DTYPE_U8_SDO_CLIENT:
			retVal = icoSdoClientCheckObjLimitNode(CO_LINE, pDesc->tableIdx);
			break;
#endif /* CO_SDO_CLIENT_CNT */

#ifdef CO_PDO_TRANSMIT_CNT
		case CO_DTYPE_U8_TPDO:
			/* transtype/sync start value */
			retVal = icoTrPdoCheckObjLimit_u8(CO_LINE, 
				pDesc->tableIdx, pDesc->subIndex, value);
			break;
		case CO_DTYPE_U8_TMAP:
			retVal = icoTrMapCheckObjLimitMapTable(CO_LINE, 
				pDesc->tableIdx, pDesc->subIndex, value);
			break;
#endif /* CO_PDO_TRANSMIT_CNT */

#ifdef CO_PDO_RECEIVE_CNT
		case CO_DTYPE_U8_RPDO:
			/* transtype/sync start value */
			retVal = icoRecPdoCheckObjLimit_u8(CO_LINE, 
				pDesc->tableIdx, pDesc->subIndex, value);
			break;
		case CO_DTYPE_U8_RMAP:
			retVal = icoRecMapCheckObjLimitMapTable(CO_LINE, 
				pDesc->tableIdx, pDesc->subIndex, value);
			break;
#endif /* CO_PDO_RECEIVE_CNT */

#ifdef CO_EMCY_PRODUCER
		case CO_DTYPE_U8_EMCY:
			retVal = icoEmcyCheckObjLimitHist(CO_LINE, 
				pDesc->tableIdx, pDesc->subIndex, value);
			break;
#endif /* CO_EMCY_PRODUCER */

#ifdef CO_SYNC_SUPPORTED
		case CO_DTYPE_U8_SYNC:
			retVal = icoSyncCheckObjLimit_u8(CO_LINE, pDesc->tableIdx, value);
			break;
#endif /* CO_SYNC_SUPPORTED */

#ifdef CO_SRDO_SUPPORTED
		case CO_DTYPE_U8_SRDO:
			retVal = icoSrdoCheckObjLimit_u8(CO_LINE, pDesc->tableIdx,
				pDesc->subIndex, pDesc->dType, value);
			break;
#endif /* CO_SRDO_SUPPORTED */

		case CO_DTYPE_U8_ERRCTRL:
		case CO_DTYPE_U8_NETWORK:
			retVal = RET_OK;
			break;

		case CO_DTYPE_BOOL_CONST:
		case CO_DTYPE_BOOL_VAR:
		case CO_DTYPE_BOOL_PTR:
			if (value > 1u)  {
				retVal = RET_SDO_INVALID_VALUE;
			} else {
				retVal = RET_OK;
			}
			break;

		case CO_DTYPE_U8_CONST:
				retVal = RET_OK;
			break;

		case CO_DTYPE_U8_VAR:
		case CO_DTYPE_U8_PTR:
#ifdef CO_CONFIG_LIMIT_CHECK
			/* check only objects with limit check attribut */
			if ((pDesc->attr & CO_ATTR_LIMIT) != 0u)  {
				if (pOdConst_u8 != NULL)  {
					if ((value >= pOdConst_u8[pDesc->limitMinIdx]) 
					 && (value <= pOdConst_u8[pDesc->limitMaxIdx]))  {
						retVal = RET_OK;
					}
				}
			} else
#endif /* CO_CONFIG_LIMIT_CHECK */
			{
				retVal = RET_OK;
			}
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
			break;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \internal
*
* \brief checkObjVal_u16 - check object limits for u16 vars
*
*
* \return RET_T
*
*/
static RET_T checkObjValue_u16(
		CO_LINE_TYPE		CO_LINE,		/* can line */
		CO_CONST CO_OBJECT_DESC_T *pDesc,	/* pointer to object description */
		CO_CONST UNSIGNED16	value			/* u16 */
	)
{
RET_T	retVal = RET_INVALID_PARAMETER;

#ifdef CO_EVENT_STORE
	/* In init and load there is no limit check */
	if (loadParameterState[CO_LINE] == CO_TRUE) {
		return RET_OK;
	}
#endif /* CO_EVENT_STORE */

	switch (pDesc->dType)  {
#ifdef CO_PDO_TRANSMIT_CNT
		case CO_DTYPE_U16_TPDO:
			/* inhibit/event timer */
			retVal = icoTrPdoCheckObjLimit_u16(CO_LINE, pDesc->tableIdx,
				pDesc->subIndex);
			if (retVal == RET_OK)  {
				retVal = checkObjLimits_u16(CO_LINE, pDesc, value);
			}
			break;
#endif /* CO_PDO_TRANSMIT_CNT */

#ifdef CO_PDO_RECEIVE_CNT
		case CO_DTYPE_U16_RPDO:
			/* inhibit/event timer */
			retVal = icoRecPdoCheckObjLimit_u16(CO_LINE, 
				pDesc->tableIdx, pDesc->subIndex);
			if (retVal == RET_OK)  {
				retVal = checkObjLimits_u16(CO_LINE, pDesc, value);
			}
			break;
#endif /* CO_PDO_RECEIVE_CNT */

#ifdef CO_SRDO_SUPPORTED
		case CO_DTYPE_U16_SRDO:
			retVal = icoSrdoCheckObjLimit_u16(CO_LINE, pDesc->tableIdx,
				pDesc->subIndex, pDesc->dType, value);
			break;
#endif /* CO_SRDO_SUPPORTED */

		case CO_DTYPE_U16_EMCY:
		case CO_DTYPE_U16_NMT:
		case CO_DTYPE_U16_NETWORK:
		case CO_DTYPE_U16_ERRCTRL:
		case CO_DTYPE_U16_VAR:
		case CO_DTYPE_U16_PTR:
		case CO_DTYPE_U16_FLYMA:
			retVal = checkObjLimits_u16(CO_LINE, pDesc, value);
			break;

		case CO_DTYPE_U16_CONST:
			retVal = RET_OK;
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
			break;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \internal
*
* \brief checkObjLimits_u16 - check object limit
*
*
* \return RET_T
*
*/
static RET_T checkObjLimits_u16(
		CO_LINE_TYPE		CO_LINE,		/* can line */
		CO_CONST CO_OBJECT_DESC_T *pDesc,	/* pointer to object description */
		CO_CONST UNSIGNED16	value			/* u16 */
	)
{
RET_T	retVal;
(void)value;
(void)pDesc;

#ifdef CO_CONFIG_LIMIT_CHECK
	retVal = RET_INVALID_PARAMETER;

	/* check only objects with limit check attribut */
	if ((pDesc->attr & CO_ATTR_LIMIT) != 0u)  {
		if (pOdConst_u16 != NULL)  {
			if ((value >= pOdConst_u16[pDesc->limitMinIdx]) 
			 && (value <= pOdConst_u16[pDesc->limitMaxIdx]))  {
				retVal = RET_OK;
			}
		}
	} else
#endif /* CO_CONFIG_LIMIT_CHECK */
	{
		retVal = RET_OK;
	}
	(void)CO_LINE;
	return(retVal);
}


/***************************************************************************/
/**
* \internal
*
* \brief checkObjValue_u32 - check object limits for u32 values
*
*
* \return RET_T
*
*/
static RET_T checkObjValue_u32(
		CO_LINE_TYPE		CO_LINE,		/* can line */
		CO_CONST CO_OBJECT_DESC_T *pDesc,	/* pointer to object description */
		CO_CONST UNSIGNED32	value			/* U32 val */
	)
{
RET_T	retVal = RET_INVALID_PARAMETER;

#ifdef CO_EVENT_STORE
	/* In init and load there is no limit check */
	if (loadParameterState[CO_LINE] == CO_TRUE) {
		return RET_OK;
	}
#endif /* CO_EVENT_STORE */

	switch (pDesc->dType)  {
#ifdef CO_SDO_SERVER_CNT
		case CO_DTYPE_U32_SDO_SERVER:
			retVal = icoSdoCheckObjLimitCobId(CO_LINE, 
				pDesc->tableIdx, pDesc->subIndex, value);
			break;
#endif /* CO_SDO_SERVER_CNT */

#ifdef CO_SDO_CLIENT_CNT
		case CO_DTYPE_U32_SDO_CLIENT:
			retVal = icoSdoClientCheckObjLimitCobId(CO_LINE, pDesc->tableIdx,
				pDesc->subIndex, value);
			break;
#endif /* CO_SDO_CLIENT_CNT */

#ifdef CO_PDO_TRANSMIT_CNT
		case CO_DTYPE_U32_TPDO:
			retVal = icoTrPdoCheckObjLimitCobid(CO_LINE, pDesc->tableIdx, value);
			break;
		case CO_DTYPE_U32_TMAP:
			retVal = icoTrMapCheckObjLimitMapEntry(CO_LINE, pDesc->tableIdx, value);
			break;
#endif /* CO_PDO_TRANSMIT_CNT */

#ifdef CO_PDO_RECEIVE_CNT
		case CO_DTYPE_U32_RPDO:
			retVal = icoRecPdoCheckObjLimitCobid(CO_LINE, pDesc->tableIdx, value);
			break;
		case CO_DTYPE_U32_RMAP:
			retVal = icoRecMapCheckObjLimitMapEntry(CO_LINE, pDesc->tableIdx, value);
			break;
#endif /* CO_PDO_RECEIVE_CNT */

#ifdef CO_HB_CONSUMER_CNT
		case CO_DTYPE_U32_ERRCTRL:
			retVal = icoErrCtrlCheckObjLimit(CO_LINE, pDesc->subIndex, value);
			break;
#endif /* CO_HB_CONSUMER_CNT */

#if defined(CO_EMCY_PRODUCER) || defined (CO_EMCY_CONSUMER_CNT)
		case CO_DTYPE_U32_EMCY:
			retVal = icoEmcyCheckObjLimitCobid(CO_LINE, pDesc->tableIdx, pDesc->subIndex, value);
			break;
#endif /* defined(CO_EMCY_PRODUCER) || defined (CO_EMCY_CONSUMER_CNT) */

#ifdef CO_SYNC_SUPPORTED
		case CO_DTYPE_U32_SYNC:
			retVal = icoSyncCheckObjLimit_u32(CO_LINE, pDesc->tableIdx, value);
			break;
#endif /* CO_SYNC_SUPPORTED */

#ifdef CO_TIME_SUPPORTED
		case CO_DTYPE_U32_TIME:
			retVal = icoTimeCheckObjLimit_u32(CO_LINE, value);
			break;
#endif /* CO_TIME_SUPPORTED */

#ifdef CO_STORE_SUPPORTED
		case CO_DTYPE_U32_STORE:
			retVal = icoStoreCheckObjLimit_u32(CO_LINE, pDesc->tableIdx, value);
			break;
#endif /* CO_STORE_SUPPORTED */

#ifdef CO_SRD_SUPPORTED
		case CO_DTYPE_U32_SRD:
			retVal = icoSrdCheckObjLimit_u32(CO_LINE, value);
			break;
#endif /* CO_SRD_SUPPORTED */

#ifdef CO_SRDO_SUPPORTED
		case CO_DTYPE_U32_SRDO:
			retVal = icoSrdoCheckObjLimit_u32(CO_LINE, pDesc->tableIdx,
				pDesc->subIndex, pDesc->dType, value);
			break;
#endif /* CO_SRDO_SUPPORTED */

		case CO_DTYPE_U32_NETWORK:
			retVal = RET_OK;
			break;

		case CO_DTYPE_U32_CONST:
			retVal = RET_OK;
			break;

		case CO_DTYPE_U32_NMT:
			retVal = RET_OK;
			break;

		case CO_DTYPE_U32_VAR:
		case CO_DTYPE_U32_PTR:
#ifdef CO_CONFIG_LIMIT_CHECK
			/* check only objects with limit check attribut */
			if ((pDesc->attr & CO_ATTR_LIMIT) != 0u)  {
				if (pOdConst_u32 != NULL)  {
					if ((value >= pOdConst_u32[pDesc->limitMinIdx]) 
					 && (value <= pOdConst_u32[pDesc->limitMaxIdx]))  {
						retVal = RET_OK;
					}
				}
			} else
#endif /* CO_CONFIG_LIMIT_CHECK */
			{
				retVal = RET_OK;
			}
			break;

		default:
			retVal = RET_OD_ACCESS_ERROR;
			break;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \internal
*
* \brief icoOdCheckObjLimits - check object limits
*
*
* \return RET_T
*
*/
RET_T icoOdCheckObjLimits(
		CO_LINE_TYPE		CO_LINE,		/* can line */
		CO_CONST CO_OBJECT_DESC_T *pDesc,	/* pointer to object description */
		CO_CONST UNSIGNED8	*pData			/* pointer to receive data */
	)
{
RET_T	retVal = RET_INVALID_PARAMETER;
UNSIGNED16	u16;
UNSIGNED32	u32;

	switch (pDesc->dType)  {
		/* no test for const */
		case CO_DTYPE_BOOL_CONST:
		case CO_DTYPE_U8_CONST:
		case CO_DTYPE_U16_CONST:
		case CO_DTYPE_U32_CONST:
		case CO_DTYPE_R32_CONST:
		case CO_DTYPE_VS_CONST:
		case CO_DTYPE_VS_PTR:
		case CO_DTYPE_OS_PTR:
		case CO_DTYPE_DOMAIN:

# ifdef CO_EXTENDED_DATA_TYPES
		case CO_DTYPE_U24_VAR:
		case CO_DTYPE_U40_VAR:
		case CO_DTYPE_U48_VAR:
		case CO_DTYPE_U64_VAR:
		case CO_DTYPE_U24_PTR:
		case CO_DTYPE_U40_PTR:
		case CO_DTYPE_U48_PTR:
		case CO_DTYPE_U64_PTR:
		case CO_DTYPE_U24_CONST:
		case CO_DTYPE_U40_CONST:
		case CO_DTYPE_U48_CONST:
		case CO_DTYPE_U64_CONST:
# endif /* CO_EXTENDED_DATA_TYPES */
			retVal = RET_OK;
			break;

		case CO_DTYPE_U8_SDO_SERVER:
		case CO_DTYPE_U8_ERRCTRL:
		case CO_DTYPE_U8_NETWORK:
		case CO_DTYPE_U8_SDO_CLIENT:
		case CO_DTYPE_U8_TPDO:
		case CO_DTYPE_U8_TMAP:
		case CO_DTYPE_U8_RPDO:
		case CO_DTYPE_U8_RMAP:
		case CO_DTYPE_U8_EMCY:
		case CO_DTYPE_U8_SYNC:
		case CO_DTYPE_U8_SRDO:
		case CO_DTYPE_U8_VAR:
		case CO_DTYPE_U8_PTR:
		case CO_DTYPE_BOOL_VAR:
		case CO_DTYPE_BOOL_PTR:
			retVal = checkObjValue_u8(CO_LINE, pDesc, *pData);
			break;


		case CO_DTYPE_U16_ERRCTRL:
		case CO_DTYPE_U16_EMCY:
		case CO_DTYPE_U16_NMT:
		case CO_DTYPE_U16_NETWORK:
		case CO_DTYPE_U16_TPDO:
		case CO_DTYPE_U16_RPDO:
		case CO_DTYPE_U16_SRDO:
		case CO_DTYPE_U16_VAR:
		case CO_DTYPE_U16_PTR:
			(void)coreMemcpyPack(&u16, pData, 2u, 0u, CORE_DTYPE_U16, 0u);
			retVal = checkObjValue_u16(CO_LINE, pDesc, u16);
			break;


		case CO_DTYPE_U32_SDO_SERVER:
		case CO_DTYPE_U32_NETWORK:
		case CO_DTYPE_U32_SDO_CLIENT:
		case CO_DTYPE_U32_TPDO:
		case CO_DTYPE_U32_TMAP:
		case CO_DTYPE_U32_RPDO:
		case CO_DTYPE_U32_RMAP:
		case CO_DTYPE_U32_ERRCTRL:
		case CO_DTYPE_U32_EMCY:
		case CO_DTYPE_U32_SYNC:
		case CO_DTYPE_U32_TIME:
		case CO_DTYPE_U32_STORE:
		case CO_DTYPE_U32_SRD:
		case CO_DTYPE_U32_SRDO:
		case CO_DTYPE_U32_VAR:
		case CO_DTYPE_U32_PTR:
			(void)coreMemcpyPack(&u32, pData, 4u, 0u, CORE_DTYPE_U32, 0u);
			retVal = checkObjValue_u32(CO_LINE, pDesc, u32);
			break;

		default:
			retVal = odCheckObjLimitsOther(pDesc, pDesc->dType, pData);
			break;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \internal
*
* \brief odCheckObjLimitsOther - check other variable limits
*
*
* \return RET_T
*
*/
static RET_T odCheckObjLimitsOther(
		CO_CONST CO_OBJECT_DESC_T *pDesc,	/* pointer to object description */
		CO_CONST CO_DATA_TYPE_T	  dType,	/* data type */
		CO_CONST UNSIGNED8	*pData			/* pointer to receive data */
	)
{
RET_T	retVal = RET_INVALID_PARAMETER;
#ifdef CO_CONFIG_LIMIT_CHECK
INTEGER8	i8 = 0;
INTEGER16	i16 = 0;
INTEGER32	i32 = 0;
REAL32		r32;
#endif /* CO_CONFIG_LIMIT_CHECK */
(void)pData;

	/* check only objects with limit check attribut */
	if ((pDesc->attr & CO_ATTR_LIMIT) == 0u)  {
		return(RET_OK);
	}

	switch (dType)  {

#ifdef CO_CONFIG_LIMIT_CHECK
		case CO_DTYPE_I8_VAR:
		case CO_DTYPE_I8_PTR:
			if (pOdConst_i8 != NULL)  {
				(void)coreMemcpyPack(&i8, pData, sizeof(i8), 0u, CORE_DTYPE_I8, 0u);
				if ((i8 >= pOdConst_i8[pDesc->limitMinIdx]) 
				 && (i8 <= pOdConst_i8[pDesc->limitMaxIdx]))  {
					retVal = RET_OK;
				}
			}
			break;
		case CO_DTYPE_I16_VAR:
		case CO_DTYPE_I16_PTR:
			if (pOdConst_i16 != NULL)  {
				(void)coreMemcpyPack(&i16, pData, sizeof(i16), 0u, CORE_DTYPE_I16, 0u);
				if ((i16 >= pOdConst_i16[pDesc->limitMinIdx]) 
				 && (i16 <= pOdConst_i16[pDesc->limitMaxIdx]))  {
					retVal = RET_OK;
				}
			}
			break;
		case CO_DTYPE_I32_VAR:
		case CO_DTYPE_I32_PTR:
			if (pOdConst_i32 != NULL)  {
				(void)coreMemcpyPack(&i32, pData, sizeof(i32), 0u, CORE_DTYPE_I32, 0u);
				if ((i32 >= pOdConst_i32[pDesc->limitMinIdx]) 
				 && (i32 <= pOdConst_i32[pDesc->limitMaxIdx]))  {
					retVal = RET_OK;
				}
			}
			break;
		case CO_DTYPE_R32_VAR:
		case CO_DTYPE_R32_PTR:
			if (pOdConst_r32 != NULL)  {
				(void)coreMemcpyPack(&r32, pData, 4u, 0u, CORE_DTYPE_U32, 0u);
				if ((r32 >= pOdConst_r32[pDesc->limitMinIdx])
				 && (r32 <= pOdConst_r32[pDesc->limitMaxIdx]))  {
					retVal = RET_OK;
				}
			}
			break;

#else /* CO_CONFIG_LIMIT_CHECK */
		case CO_DTYPE_R32_VAR:
		case CO_DTYPE_R32_PTR:
		case CO_DTYPE_I8_CONST:
		case CO_DTYPE_I16_CONST:
		case CO_DTYPE_I32_CONST:
		case CO_DTYPE_I8_VAR:
		case CO_DTYPE_I16_VAR:
		case CO_DTYPE_I32_VAR:
		case CO_DTYPE_I8_PTR:
		case CO_DTYPE_I16_PTR:
		case CO_DTYPE_I32_PTR:
			retVal = RET_OK;
			break;
#endif /* CO_CONFIG_LIMIT_CHECK */

		default:
			retVal = RET_OD_ACCESS_ERROR;
	}

	return(retVal);
}


/***************************************************************************/
/**
*
* \brief coOdSetObjSize - set object size
*
* This function set the size of an object (in bytes),
* given by the object description.
*
* Only valid for strings and domains
*
*
*/
RET_T coOdSetObjSize(
		CO_CONST CO_OBJECT_DESC_T	*pDesc,	/**< pointer for description index */
		UNSIGNED32					size	/**< new object size */
	)
{
#ifdef CO_DYNAMIC_OBJDIC
	if ((pDesc->attr & CO_ATTR_DYNOD) != 0u)  {
		return(RET_OK);
	}
#endif /* CO_DYNAMIC_OBJDIC */

	switch (pDesc->dType)  {
		case CO_DTYPE_VS_PTR:
			if (pOdPtr_VS_ActLen != NULL)  {
				pOdPtr_VS_ActLen[pDesc->tableIdx] = size;
			}
			break;
		case CO_DTYPE_OS_PTR:
			if (pOdPtr_OS_ActLen != NULL)  {
				pOdPtr_OS_ActLen[pDesc->tableIdx] = size;
			}
			break;
		case CO_DTYPE_DOMAIN:
			if (pOdPtr_Domain_ActLen != NULL)  {
				pOdPtr_Domain_ActLen[pDesc->tableIdx] = size;
			}
			break;
		default:
			break;
	}

	return(RET_OK);
}


/***************************************************************************/
/**
* \brief coOdGetObjMaxSize - get object maximum size
*
* This function returns the maximum size of an object (in bytes),
* given by the object description.
*
* The maximum size is used for strings and domains and cannot be changed.
*
* \return maximum object size
*
*/
UNSIGNED32 coOdGetObjMaxSize(
		CO_CONST CO_OBJECT_DESC_T	*pDesc	/**< pointer for description index */
	)
{
UNSIGNED32	size = 0u;

#ifdef CO_DYNAMIC_OBJDIC
	if ((pDesc->attr & CO_ATTR_DYNOD) != 0u)  {
		size = coDynOdGetObjMaxSize(pDesc);
		return(size);
	}
#endif /* CO_DYNAMIC_OBJDIC */

	switch (pDesc->dType)  {
		case CO_DTYPE_VS_PTR:
			if (pOdPtr_VS_MaxLen != NULL)  {
				size = pOdPtr_VS_MaxLen[pDesc->tableIdx];
			}
			break;
		case CO_DTYPE_OS_PTR:
			if (pOdPtr_OS_MaxLen != NULL)  {
				size = pOdPtr_OS_MaxLen[pDesc->tableIdx];
			}
			break;
		case CO_DTYPE_DOMAIN:
			if (pOdPtr_Domain_MaxLen != NULL)  {
				size = pOdPtr_Domain_MaxLen[pDesc->tableIdx];
			}
			break;
		default:
			size = coOdGetObjSize(pDesc);
	}

	return(size);
}


/***************************************************************************/
/**
* \brief coOdGetObjSize - get object size
*
* This function returns the size of an object (in bytes),
* given by the object description.
*
*
* \return object size
*
*/
UNSIGNED32 coOdGetObjSize(
		CO_CONST CO_OBJECT_DESC_T	*pDesc	/**< pointer for description index */
	)
{
UNSIGNED32	size = 0u;

#ifdef CO_DYNAMIC_OBJDIC
	if ((pDesc->attr & CO_ATTR_DYNOD) != 0u)  {
		size = coDynOdGetObjSize(pDesc);
		return(size);
	}
#endif /* CO_DYNAMIC_OBJDIC */

	switch (pDesc->dType)  {
		case CO_DTYPE_U8_CONST:
		case CO_DTYPE_BOOL_CONST:
			/* table initialized ? */
			if (pOdConst_u8 != NULL)  {
				size = 1u;
			}
			break;
		case CO_DTYPE_U16_CONST:
			/* table initialized ? */
			if (pOdConst_u16 != NULL)  {
				size = 2u;
			}
			break;
		case CO_DTYPE_U32_CONST:
			/* table initialized ? */
			if (pOdConst_u32 != NULL)  {
				size = 4u;
			}
			break;
		case CO_DTYPE_R32_CONST:
			/* table initialized ? */
			if (pOdConst_r32 != NULL)  {
				size = 4u;
			}
			break;
		case CO_DTYPE_U8_VAR:
		case CO_DTYPE_BOOL_VAR:
			/* table initialized ? */
			if (pOdVar_u8 != NULL)  {
				size = 1u;
			}
			break;
		case CO_DTYPE_U16_VAR:
			/* table initialized ? */
			if (pOdVar_u16 != NULL)  {
				size = 2u;
			}
			break;
		case CO_DTYPE_U32_VAR:
			/* table initialized ? */
			if (pOdVar_u32 != NULL)  {
				size = 4u;
			}
			break;
		case CO_DTYPE_R32_VAR:
			/* table initialized ? */
			if (pOdVar_r32 != NULL)  {
				size = 4u;
			}
			break;
		case CO_DTYPE_U8_PTR:
		case CO_DTYPE_BOOL_PTR:
			/* table initialized ? */
			if (pOdPtr_u8 != NULL)  {
				size = 1u;
			}
			break;
		case CO_DTYPE_U16_PTR:
			/* table initialized ? */
			if (pOdPtr_u16 != NULL)  {
				size = 2u;
			}
			break;
		case CO_DTYPE_U32_PTR:
			/* table initialized ? */
			if (pOdPtr_u32 != NULL)  {
				size = 4u;
			}
			break;
		case CO_DTYPE_I8_CONST:
			/* table initialized ? */
			if (pOdConst_i8 != NULL)  {
				size = 1u;
			}
			break;
		case CO_DTYPE_I16_CONST:
			/* table initialized ? */
			if (pOdConst_i16 != NULL)  {
				size = 2u;
			}
			break;
		case CO_DTYPE_I32_CONST:
			/* table initialized ? */
			if (pOdConst_i32 != NULL)  {
				size = 4u;
			}
			break;
		case CO_DTYPE_I8_VAR:
			/* table initialized ? */
			if (pOdVar_i8 != NULL)  {
				size = 1u;
			}
			break;
		case CO_DTYPE_I16_VAR:
			/* table initialized ? */
			if (pOdVar_i16 != NULL)  {
				size = 2u;
			}
			break;
		case CO_DTYPE_I32_VAR:
			/* table initialized ? */
			if (pOdVar_i32 != NULL)  {
				size = 4u;
			}
			break;
		case CO_DTYPE_I8_PTR:
			/* table initialized ? */
			if (pOdPtr_i8 != NULL)  {
				size = 1u;
			}
			break;
		case CO_DTYPE_I16_PTR:
			/* table initialized ? */
			if (pOdPtr_i16 != NULL)  {
				size = 2u;
			}
			break;
		case CO_DTYPE_I32_PTR:
			/* table initialized ? */
			if (pOdPtr_i32 != NULL)  {
				size = 4u;
			}
			break;
		case CO_DTYPE_R32_PTR:
			/* table initialized ? */
			if (pOdPtr_r32 != NULL)  {
				size = 4u;
			}
			break;
		case CO_DTYPE_VS_PTR:
			if (pOdPtr_VS_ActLen != NULL)  {
				size = pOdPtr_VS_ActLen[pDesc->tableIdx];
			}
			break;
		case CO_DTYPE_VS_CONST:
			if (pOdConst_VS_MaxLen != NULL)  {
				size = pOdConst_VS_MaxLen[pDesc->tableIdx];
			}
			break;
		case CO_DTYPE_OS_PTR:
			if (pOdPtr_OS_ActLen != NULL)  {
				size = pOdPtr_OS_ActLen[pDesc->tableIdx];
			}
			break;
		case CO_DTYPE_DOMAIN:
			if (pOdPtr_Domain_ActLen != NULL)  {
				size = pOdPtr_Domain_ActLen[pDesc->tableIdx];
			}
			break;
		case CO_DTYPE_U8_SDO_SERVER:
		case CO_DTYPE_U8_SDO_CLIENT:
		case CO_DTYPE_U8_TPDO:
		case CO_DTYPE_U8_RPDO:
		case CO_DTYPE_U8_TMAP:
		case CO_DTYPE_U8_RMAP:
		case CO_DTYPE_U8_SYNC:
		case CO_DTYPE_U8_EMCY:
		case CO_DTYPE_U8_ERRCTRL:
		case CO_DTYPE_U8_NETWORK:
		case CO_DTYPE_U8_NMT:
		case CO_DTYPE_U8_SRDO:
		case CO_DTYPE_I8_SRDO:
		case CO_DTYPE_U8_GFC:
			size = 1u;
			break;
		case CO_DTYPE_U16_TPDO:
		case CO_DTYPE_U16_RPDO:
		case CO_DTYPE_U16_ERRCTRL:
		case CO_DTYPE_U16_EMCY:
		case CO_DTYPE_U16_NMT:
		case CO_DTYPE_U16_NETWORK:
		case CO_DTYPE_U16_SRDO:
		case CO_DTYPE_I16_SRDO:
		case CO_DTYPE_U16_FLYMA:
			size = 2u;
			break;
		case CO_DTYPE_U32_SDO_SERVER:
		case CO_DTYPE_U32_SDO_CLIENT:
		case CO_DTYPE_U32_TPDO:
		case CO_DTYPE_U32_TMAP:
		case CO_DTYPE_U32_RPDO:
		case CO_DTYPE_U32_RMAP:
		case CO_DTYPE_U32_ERRCTRL:
		case CO_DTYPE_U32_SYNC:
		case CO_DTYPE_U32_EMCY:
		case CO_DTYPE_U32_TIME:
		case CO_DTYPE_U32_STORE:
		case CO_DTYPE_U32_SRD:
		case CO_DTYPE_U32_NETWORK:
		case CO_DTYPE_U32_NMT:
		case CO_DTYPE_U32_SRDO:
		case CO_DTYPE_I32_SRDO:
		case CO_DTYPE_R32_SRDO:
			size = 4u;
			break;

#ifdef CO_EXTENDED_DATA_TYPES
		case CO_DTYPE_U24_VAR:
			/* table initialized ? */
			if (pOdVar_u24 != NULL)  {
				size = 3u;
			}
			break;
		case CO_DTYPE_U24_PTR:
			/* table initialized ? */
			if (pOdPtr_u24 != NULL)  {
				size = 3u;
			}
			break;
		case CO_DTYPE_U24_CONST:
			/* table initialized ? */
			if (pOdConst_u24 != NULL)  {
				size = 3u;
			}
			break;

		case CO_DTYPE_U40_VAR:
			/* table initialized ? */
			if (pOdVar_u40 != NULL)  {
				size = 5u;
			}
			break;
		case CO_DTYPE_U40_PTR:
			/* table initialized ? */
			if (pOdPtr_u40 != NULL)  {
				size = 5u;
			}
			break;
		case CO_DTYPE_U40_CONST:
			/* table initialized ? */
			if (pOdConst_u40 != NULL)  {
				size = 5u;
			}
			break;

		case CO_DTYPE_U48_VAR:
			/* table initialized ? */
			if (pOdVar_u48 != NULL)  {
				size = 6u;
			}
			break;
		case CO_DTYPE_U48_PTR:
			/* table initialized ? */
			if (pOdPtr_u48 != NULL)  {
				size = 6u;
			}
			break;
		case CO_DTYPE_U48_CONST:
			/* table initialized ? */
			if (pOdConst_u48 != NULL)  {
				size = 6u;
			}
			break;

		case CO_DTYPE_U64_VAR:
			/* table initialized ? */
			if (pOdVar_u64 != NULL)  {
				size = 8u;
			}
			break;
		case CO_DTYPE_U64_PTR:
			/* table initialized ? */
			if (pOdPtr_u64 != NULL)  {
				size = 8u;
			}
			break;
		case CO_DTYPE_U64_CONST:
			/* table initialized ? */
			if (pOdConst_u64 != NULL)  {
				size = 8u;
			}
			break;
#endif /* CO_EXTENDED_DATA_TYPES */

		default:
			size = 0u;
	}

	return(size);
}


#if defined(CO_PDO_RECEIVE_CNT) || defined(CO_SRDO_SUPPORTED)
/***************************************************************************/
/**
* \internal
*
* \brief icoOdGetObjRecMapData - get data of receive mapping entry
*
* This function returns data of mapping entry
* If index is not mapable, returns error
*
* \return RET_T
*
*/
RET_T icoOdGetObjRecMapData(
		CO_LINE_TYPE	CO_LINE,	/* can line */
		UNSIGNED16		index,		/* index of mapped variable */
		UNSIGNED8		subIndex,	/* subindex of mapped variable */
		UNSIGNED8       bitLen,     /* bit length in mapping entry */
		void			**pVar,		/* pointer to mapped variable */
		UNSIGNED8		*pLen,		/* len of mapped variable */
		BOOL_T			*pNumeric	/* numeric sign for mapped variable */
	)
{
CO_CONST CO_OBJECT_DESC_T	*pDesc;
RET_T	retVal;
UNSIGNED16	attr;

	/* check for dummy mapping */
	if (index < 0x20u) {
		*pVar = NULL;
		*pNumeric = CO_TRUE;
		retVal = RET_OK;

		switch (index)  {
			case 1u:				/* bool */
				*pLen = 0x01u;
				break;
			case 2u:				/* 8 bit */
			case 5u:				/* 8 bit */
				*pLen = 0x01u;
				break;
			case 3u:				/* 16 bit */
			case 6u:				/* 16 bit */
				*pLen = 0x02u;
				break;
			case 4u:				/* 32 bit */
			case 7u:				/* 32 bit */
				*pLen = 0x04u;
				break;
			default:
				retVal = RET_MAP_ERROR;
				break;
		}
#ifdef CO_PDO_BIT_MAPPING
		if (index != 1u) { /* bool */
			*pLen = (UNSIGNED8)(*pLen << 3u);
		} 
#endif /* CO_PDO_BIT_MAPPING */
		return(retVal);
	}

	/* get description stucture */
	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex, &pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	attr = coOdGetObjAttribute(pDesc);

	/* check for mapable */
	if ((attr & (CO_ATTR_MAP | CO_ATTR_MAP_REC)) == 0u)  {
		return(RET_MAP_ERROR);
	}

	/* check for writable */
	if ((attr & CO_ATTR_WRITE) == 0u)  {
		return(RET_NO_WRITE_PERM);
	}

	if ((attr & CO_ATTR_NUM) == 0u)  {
		*pNumeric = CO_FALSE;
	} else {
		*pNumeric = CO_TRUE;
	}

	*pVar = odGetObjAddr(CO_LINE, pDesc, subIndex);

#ifdef CO_PDO_BIT_MAPPING
	if ((pDesc->dType == CO_DTYPE_BOOL_CONST)
	 || (pDesc->dType == CO_DTYPE_BOOL_VAR)
	 || (pDesc->dType == CO_DTYPE_BOOL_PTR))  {
		*pLen = 1u;
	} else {
		*pLen = (UNSIGNED8)(coOdGetObjSize(pDesc) << 3u);
        /* allow less bits to be mapped */
        if (bitLen < *pLen)  {
            *pLen = bitLen;
        }
	}
#else /* CO_PDO_BIT_MAPPING */
	*pLen = (UNSIGNED8)coOdGetObjSize(pDesc);
    (void)bitLen;
#endif /* CO_PDO_BIT_MAPPING */

	return(RET_OK);
}
#endif /* defined(CO_PDO_RECEIVE_CNT) || defined(CO_SRDO_SUPPORTED) */


#if defined(CO_PDO_TRANSMIT_CNT) || defined(CO_SRDO_SUPPORTED)
/***************************************************************************/
/**
* \internal
*
* \brief icoOdGetObjTrMapData - get data of transmit mapping entry
*
* This function returns data of mapping entry
* If index is not mapable, returns error
*
* \return RET_T
*
*/
RET_T icoOdGetObjTrMapData(
		CO_LINE_TYPE	CO_LINE,	/* can line */
		UNSIGNED16		index,		/* index of mapped variable */
		UNSIGNED8		subIndex,	/* subindex of mapped variable */
		UNSIGNED8       bitLen,     /* bit length in mapping entry */
		CO_CONST void	**pVar,		/* pointer to mapped variable */
		UNSIGNED8		*pLen,		/* len of mapped variable */
		BOOL_T			*pNumeric	/* numeric sign for mapped variable */
	)
{
CO_CONST CO_OBJECT_DESC_T	*pDesc;
RET_T	retVal;
UNSIGNED16	attr;

	/* check for dummy mapping */
	if (index < 0x20u) {
		return(RET_MAP_ERROR);
	}

	/* get description stucture */
	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex, &pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	attr = coOdGetObjAttribute(pDesc);

	/* check for mapable */
	if ((attr & (CO_ATTR_MAP | CO_ATTR_MAP_TR)) == 0u)  {
		return(RET_MAP_ERROR);
	}
	/* check for redable */
	if ((attr & CO_ATTR_READ) == 0u)  {
		return(RET_NO_READ_PERM);
	}

	if ((attr & CO_ATTR_NUM) == 0u)  {
		*pNumeric = CO_FALSE;
	} else {
		*pNumeric = CO_TRUE;
	}

	*pVar = odGetObjAddr_R(CO_LINE, pDesc, subIndex);

#ifdef CO_PDO_BIT_MAPPING
	if ((pDesc->dType == CO_DTYPE_BOOL_CONST)
	 || (pDesc->dType == CO_DTYPE_BOOL_VAR)
	 || (pDesc->dType == CO_DTYPE_BOOL_PTR))  {
		*pLen = 1u;
	} else {
		*pLen = (UNSIGNED8)(coOdGetObjSize(pDesc) << 3u);
        /* allow less bits to be mapped */
        if (bitLen < *pLen)  {
            *pLen = bitLen;
        }
	}
#else /* CO_PDO_BIT_MAPPING */
	*pLen = (UNSIGNED8)coOdGetObjSize(pDesc);
    (void)bitLen;
#endif /* CO_PDO_BIT_MAPPING */

	return(RET_OK);
}
#endif /* defined(CO_PDO_TRANSMIT_CNT) || defined(CO_SRDO_SUPPORTED) */


/***************************************************************************/
/**
* \internal
*
* \brief icoOdCheckObjAttr - check object for given attributes
*
* This function checks an object for the given attributes
*
* \return RET_T
*
*/
RET_T icoOdCheckObjAttr(
		CO_LINE_TYPE	CO_LINE,	/* can line */
		UNSIGNED16		index,		/* index */
		UNSIGNED8		subIndex,	/* subindex */
		UNSIGNED16		checkAttr	/* attribute to check */
	)
{
CO_CONST CO_OBJECT_DESC_T	*pDesc;
RET_T	retVal;
UNSIGNED16	attr;

	/* generic data types are ok */
	if (index < 0x20u) {
		return(RET_OK);
	}

	/* get description stucture */
	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex, &pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	attr = coOdGetObjAttribute(pDesc);

	/* mask only check attributes */
	attr &= checkAttr;

	/* if not all attr are set, return error */
	if ((attr ^ checkAttr) != 0u)  {
		retVal = RET_MAP_ERROR;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdGetDefaultVal_u8 - get default value for specific object 
*
* This function returns the default value of an UNSIGNED8 object.
*
* \return RET_T
*
*/
RET_T coOdGetDefaultVal_u8(
		CO_LINE_TYPE	CO_LINE,		/**< can line */
		UNSIGNED16		index,			/**< index */
		UNSIGNED8		subIndex,		/**< sub index */
		UNSIGNED8		*pDefVal		/**< pointer to default val */
	)
{
RET_T	retVal;
CO_CONST CO_OBJECT_DESC_T *pDesc;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_BOOL_VAR:
		case CO_DTYPE_BOOL_PTR:
		case CO_DTYPE_U8_VAR:
		case CO_DTYPE_U8_PTR:
		case CO_DTYPE_U8_CONST:
		case CO_DTYPE_U8_SYNC:
		case CO_DTYPE_U8_TPDO:
		case CO_DTYPE_U8_RPDO:
		case CO_DTYPE_U8_TMAP:
		case CO_DTYPE_U8_RMAP:
		case CO_DTYPE_U8_EMCY:
		case CO_DTYPE_U8_SDO_CLIENT:
		case CO_DTYPE_U8_ERRCTRL:
		case CO_DTYPE_U8_NETWORK:
		case CO_DTYPE_U8_SRDO:
			*pDefVal = pOdConst_u8[pDesc->defValIdx];
			break;
		default:
			retVal = RET_SDO_DATA_TYPE_NOT_MATCH;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdGetDefaultVal_u16 - get default value for specific object 
*
* This function returns the default value of an UNSIGNED16 object.
*
* \return RET_T
*
*/
RET_T coOdGetDefaultVal_u16(
		CO_LINE_TYPE	CO_LINE,		/**< can line */
		UNSIGNED16		index,			/**< index */
		UNSIGNED8		subIndex,		/**< sub index */
		UNSIGNED16		*pDefVal		/**< pointer to default val */
	)
{
RET_T	retVal;
CO_CONST CO_OBJECT_DESC_T *pDesc;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_U16_VAR:
		case CO_DTYPE_U16_PTR:
		case CO_DTYPE_U16_CONST:
		case CO_DTYPE_U16_ERRCTRL:
		case CO_DTYPE_U16_TPDO:
		case CO_DTYPE_U16_RPDO:
		case CO_DTYPE_U16_EMCY:
		case CO_DTYPE_U16_NMT:
		case CO_DTYPE_U16_NETWORK:
		case CO_DTYPE_U16_SRDO:
		case CO_DTYPE_U16_FLYMA:
			*pDefVal = pOdConst_u16[pDesc->defValIdx];
			break;
		default:
			retVal = RET_SDO_DATA_TYPE_NOT_MATCH;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdGetDefaultVal_u32 - get default value for specific object 
*
* This function returns the default value of an UNSIGNED32 object.
*
* \return RET_T
*
*/
RET_T coOdGetDefaultVal_u32(
		CO_LINE_TYPE	CO_LINE,		/**< can line */
		UNSIGNED16		index,			/**< index */
		UNSIGNED8		subIndex,		/**< sub index */
		UNSIGNED32		*pDefVal		/**< pointer to default val */
	)
{
RET_T	retVal;
CO_CONST CO_OBJECT_DESC_T *pDesc;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex,	&pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_U32_VAR:
		case CO_DTYPE_U32_PTR:
		case CO_DTYPE_U32_CONST:
		case CO_DTYPE_U32_ERRCTRL:
		case CO_DTYPE_U32_SYNC:
		case CO_DTYPE_U32_EMCY:
		case CO_DTYPE_U32_TMAP:
		case CO_DTYPE_U32_RMAP:
		case CO_DTYPE_U32_TIME:
		case CO_DTYPE_U32_RPDO:
		case CO_DTYPE_U32_TPDO:
		case CO_DTYPE_U32_SDO_SERVER:
		case CO_DTYPE_U32_SDO_CLIENT:
		case CO_DTYPE_U32_NMT:
		case CO_DTYPE_U32_NETWORK:
		case CO_DTYPE_U32_SRDO:
		case CO_DTYPE_U32_STORE:
			*pDefVal = pOdConst_u32[pDesc->defValIdx];
			break;
		default:
			retVal = RET_SDO_DATA_TYPE_NOT_MATCH;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdGetDefaultVal_r32 - get default value for specific object 
*
* This function returns the default value of an REAL32 object.
*
* \return RET_T
*
*/
RET_T coOdGetDefaultVal_r32(
		CO_LINE_TYPE	CO_LINE,		/**< can line */
		UNSIGNED16		index,			/**< index */
		UNSIGNED8		subIndex,		/**< sub index */
		REAL32			*pDefVal		/**< pointer to default val */
	)
{
RET_T	retVal;
CO_CONST CO_OBJECT_DESC_T *pDesc;

	retVal = coOdGetObjDescPtr(CO_LINE, index, subIndex, &pDesc);
	if (retVal != RET_OK)  {
		return(retVal);
	}

	switch (pDesc->dType)  {
		case CO_DTYPE_R32_VAR:
		case CO_DTYPE_R32_PTR:
		case CO_DTYPE_R32_CONST:
			*pDefVal = pOdConst_r32[pDesc->defValIdx];
			break;
		default:
			retVal = RET_SDO_DATA_TYPE_NOT_MATCH;
	}

	return(retVal);
}


/***************************************************************************/
/**
* \brief coOdGetObjDescPtr - get object description pointer
*
* This function returns a pointer to the object description
* of an object of the object dictionary.
*
* \return RET_T
*
*/
RET_T coOdGetObjDescPtr(
		CO_LINE_TYPE	CO_LINE,		/**< can line */
		UNSIGNED16		index,			/**< index */
		UNSIGNED8		subIndex,		/**< sub index */
		CO_CONST CO_OBJECT_DESC_T **pDescPtr /**< pointer for description index */
	)
{
UNSIGNED16	idx = 0u;
RET_T	retVal;


	retVal =  odGetObjDescIdx(CO_LINE, index, subIndex, &idx);
	if (retVal != RET_OK)  {
#ifdef CO_DYNAMIC_OBJDIC
		retVal = coDynOdGetObjDescPtr(CO_LINE, index, subIndex, pDescPtr);
		if (retVal == RET_IDX_NOT_FOUND)  {
		UNSIGNED8 nbrSubs;
			nbrSubs = icoOdGetNumberOfSubs(CO_LINE, index);
			if (nbrSubs != 0u)  {
				retVal = RET_SUBIDX_NOT_FOUND;
			}
		}
#endif /* CO_DYNAMIC_OBJDIC */
		return(retVal);
	}

	*pDescPtr = &pObjDescTable[CO_LINE][idx];


	return(RET_OK);
}


#ifdef CO_STORE_SUPPORTED
/***************************************************************************/
/**
* \brief odGetObjStoreCnt - get number of objects with a store flag set  
*
* This function returns the number of objects which are marked with a store
* flag in the object attributes.
*
* \return UNSIGNED32
*
*/
UNSIGNED32 coOdGetObjStoreFlagCnt(
		CO_LINE_TYPE	CO_LINE		/**< can line */
	)
{
UNSIGNED32	count = 0u;
UNSIGNED32	odIdx;
UNSIGNED16	sub;
UNSIGNED16	attr;
UNSIGNED16	descIdx;
UNSIGNED16	nrOfSubs;
UNSIGNED16	highestSub;

	/* reset all pointer */
	odLastStore[CO_LINE].assign = 0u;
	odLastStore[CO_LINE].subIdx = 0u;
	odLastStore[CO_LINE].idx = 0u;

	/* for all OD objects */
	for (odIdx = 0u; odIdx < odAssignCnt[CO_LINE]; odIdx++) {
		nrOfSubs = pOdAssignTable[CO_LINE][odIdx].numberOfSubs;
		highestSub = pOdAssignTable[CO_LINE][odIdx].highestSub;
		descIdx = pOdAssignTable[CO_LINE][odIdx].odDescIdx;

		/* for all subs of this object */
		for (sub = 0u; sub < nrOfSubs; sub++)  {
			/* get attribute */
			attr = pObjDescTable[CO_LINE][descIdx + sub].attr;
			/* compact desc subindex */
			if ((attr & CO_ATTR_COMPACT) == CO_ATTR_COMPACT) {
				if ((attr & CO_ATTR_STORE) == CO_ATTR_STORE) {
					UNSIGNED16 tmp = (UNSIGNED16)(highestSub - sub) + 1u;
					count += tmp;
				}
			} else {
				if ((attr & CO_ATTR_STORE) == CO_ATTR_STORE) {
					count++;
				}
			}
		}
	}

	return(count);
}
#endif /* CO_STORE_SUPPORTED */


#ifdef CO_STORE_SUPPORTED
/***************************************************************************/
/**
* \brief odGetObjStoreFlag - get index and subindex of store flagged object
*
* This function returns the index and subindex of a store flagged objects. 
*
* \return RET_T
*
*/
RET_T coOdGetObjStoreFlag(
		CO_LINE_TYPE	CO_LINE,		/**< can line */
		UNSIGNED32		idx,			/**< number of the store marked object (starts with 1) */
		UNSIGNED16		*pIndex,		/**< pointer for object index */
		UNSIGNED8		*pSubIndex		/**< pointer for object subindex */
	)
{
UNSIGNED16	u16;
UNSIGNED8	u8 = 0u;
UNSIGNED8	numberOfSubs;
UNSIGNED8	highestSub;
UNSIGNED16	odDescIdx;
CO_CONST CO_OBJECT_DESC_T * pDesc = NULL;

	if ((pIndex == NULL) || (pSubIndex == NULL) || (idx < 1u)) {
		return RET_INVALID_PARAMETER;
	}

	/* for faster access, check start address */
	/* is exact the same since last call */
	if (odLastStore[CO_LINE].idx == idx) {
		*pIndex = odLastStore[CO_LINE].odIndex;
		*pSubIndex = odLastStore[CO_LINE].odSubIndex;
		return(RET_OK);
	}

	if (idx < odLastStore[CO_LINE].idx) {
		odLastStore[CO_LINE].assign = 0u;
		odLastStore[CO_LINE].idx = 0u;
		odLastStore[CO_LINE].subIdx = 0u;
	}

	for (u16 = odLastStore[CO_LINE].assign; u16 < odAssignCnt[CO_LINE]; u16++) {

		numberOfSubs = pOdAssignTable[CO_LINE][u16].numberOfSubs;
		odDescIdx = pOdAssignTable[CO_LINE][u16].odDescIdx;
		highestSub = pOdAssignTable[CO_LINE][u16].highestSub;

		/* normal:
		 * number: 1	highest: 0
		 * gap
		 * number:	5	highest: 6
		 * short array: 
		 * number:	2	highest: 4
		 */
		for (u8 = odLastStore[CO_LINE].subIdx; u8 <= highestSub; u8++) {
			if (u8 >= numberOfSubs)  {
				pDesc = &pObjDescTable[CO_LINE][(odDescIdx + numberOfSubs) - 1u];
				if ((pDesc->attr & CO_ATTR_COMPACT) != CO_ATTR_COMPACT) {
					break;
				}
				odLastStore[CO_LINE].odSubIndex = u8;
			} else {
				pDesc = &pObjDescTable[CO_LINE][odDescIdx + u8];
				odLastStore[CO_LINE].odSubIndex = pDesc->subIndex;
			}
			/* compact desc subindex */
			if ((pDesc->attr & CO_ATTR_STORE) == CO_ATTR_STORE) {
				odLastStore[CO_LINE].idx++;
				/* is it the needed index */
				if (odLastStore[CO_LINE].idx == idx) {
					odLastStore[CO_LINE].idx = idx;
					odLastStore[CO_LINE].assign = u16;
					odLastStore[CO_LINE].subIdx = u8 + 1u;
					odLastStore[CO_LINE].odIndex = pOdAssignTable[CO_LINE][u16].index;
					*pIndex = odLastStore[CO_LINE].odIndex;
					*pSubIndex = odLastStore[CO_LINE].odSubIndex;

					return RET_OK;
				}
			}
		}
		odLastStore[CO_LINE].subIdx = 0u;
	}

	/* reset all values */
	odLastStore[CO_LINE].subIdx = 0u;
	odLastStore[CO_LINE].assign = 0u;
	odLastStore[CO_LINE].idx = 0u;
	
	return RET_IDX_NOT_FOUND;
}
#endif /* CO_STORE_SUPPORTED */


/***************************************************************************/
/**
* \internal
*
* \brief coOdGetObjDescIdx - get object description index
*
*
* \return RET_T
*
*/
static CO_INLINE RET_T odGetObjDescIdx(
		CO_LINE_TYPE	CO_LINE,	/* can line */
		UNSIGNED16		index,		/* index */
		UNSIGNED8		subIndex,	/* sub index */
		UNSIGNED16		*pDescIdx	/* pointer for description index */
	)
{
UNSIGNED16	left = 0u;
UNSIGNED16	right = odAssignCnt[CO_LINE] - 1u;
UNSIGNED16	middle = 0u;
UNSIGNED16  mainIndex = 0u;
BOOL_T		found = CO_FALSE;
BOOL_T		breakLoop = CO_FALSE;
RET_T		retVal;

	if (odAssignCnt[CO_LINE] == 0u)  {
		return(RET_IDX_NOT_FOUND);
	}

	/* binary search index */
	while (left <= right)  {
		/* l + r / 2 */
		middle = (left + right) >> 1;
		if (pOdAssignTable[CO_LINE][middle].index == index)  {
			mainIndex = middle;
			found = CO_TRUE;
			breakLoop = CO_TRUE;	/* break; */
		}
		if (pOdAssignTable[CO_LINE][middle].index > index)  {
			if (middle == 0u)  {
				breakLoop = CO_TRUE;	/* break; */
			}
			right = middle - 1u;
		} else {
			left = middle + 1u;
		}

		/* finish loop ? */
		if (breakLoop == CO_TRUE)  {
			break;
		}
	}

	if (found != CO_TRUE)  {
		return(RET_IDX_NOT_FOUND);
	}

	/* binary search subindex */
	left = pOdAssignTable[CO_LINE][middle].odDescIdx;
	right = (left + (UNSIGNED16)pOdAssignTable[CO_LINE][middle].numberOfSubs) - 1u;
	found = CO_FALSE;

	breakLoop = CO_FALSE;
	while (left <= right)  {
		/* l + r / 2 */
		middle = (left + right) >> 1;
		if (pObjDescTable[CO_LINE][middle].subIndex == subIndex)  {
			found = CO_TRUE;
			breakLoop = CO_TRUE;	/* break; */
		}
		if (pObjDescTable[CO_LINE][middle].subIndex > subIndex)  {
			if (middle == 0u)  {
				breakLoop = CO_TRUE;	/* break; */
			}
			right = middle - 1u;
		} else {
			left = middle + 1u;
		}

		/* finish loop ? */
		if (breakLoop == CO_TRUE)  {
			break;
		}
	}

	if (found == CO_FALSE) {
		retVal = RET_SUBIDX_NOT_FOUND;
        if (pOdAssignTable[CO_LINE][mainIndex].highestSub >= subIndex)  {
			middle = pOdAssignTable[CO_LINE][mainIndex].odDescIdx;
			middle += (UNSIGNED16)pOdAssignTable[CO_LINE][mainIndex].numberOfSubs - 1u;
			if((pObjDescTable[CO_LINE][middle].attr & CO_ATTR_COMPACT) == CO_ATTR_COMPACT)  {
				*pDescIdx = middle;
				retVal = RET_OK;
			}
		}
	} else {
		*pDescIdx = middle;
		retVal = RET_OK;
	}

	return(retVal);
}


#ifdef CO_EVENT_OBJECT_CHANGED_CNT
/***************************************************************************/
/**
* \brief coEventRegister_OBJECT_CHANGED - register object changed function
*
* This function registered a indication function for a given object.
* Each time, this object is changed by PDO, SDO or by coOdPutObj_xx()
* the given function is called.
*
* If the subindex == 255, then the indication is called for each subindex.
*
* \return RET_T
*
*/

RET_T coEventRegister_OBJECT_CHANGED(
		CO_LINE_TYPE	CO_LINE,				/**< can line */
		CO_EVENT_OBJECT_CHANGED_FCT_T	pFunction,	/**< pointer to function */
		UNSIGNED16		index,					/**< index */
		UNSIGNED8		subIndex				/**< subIndex */
    )
{
UNSIGNED16	idx = 255u;
RET_T	retVal;
CO_EVENT_OBJECT_CHANGED_T tObj;
CO_EVENT_OBJECT_CHANGED_FCT_T pFct;
CO_CONST UNSIGNED32	l = sizeof(CO_EVENT_OBJECT_CHANGED_T);
#ifdef CO_DYNAMIC_OBJDIC
CO_CONST CO_OBJECT_DESC_T *pDesc;
#endif /* CO_DYNAMIC_OBJDIC */	

	/* check if object exist */
	if (subIndex == 255u)  {
		if (index != 0xffffu)  {
			retVal = odGetObjDescIdx(CO_LINE, index, 0u, &idx);
		} else {
			/* if all object don't search the object */
			retVal = RET_OK;
		}
	} else {
		retVal = odGetObjDescIdx(CO_LINE, index, subIndex, &idx);
	}
#ifdef CO_DYNAMIC_OBJDIC
	if (retVal != RET_OK)  {
		if (subIndex == 255u)  {
			retVal = coDynOdGetObjDescPtr(CO_LINE, index, 0u, &pDesc);
		} else {
			retVal = coDynOdGetObjDescPtr(CO_LINE, index, subIndex, &pDesc);
		}
	}
#endif /* CO_DYNAMIC_OBJDIC */	
	if (retVal != RET_OK)  {
		return(RET_OD_ACCESS_ERROR);
	}

	/* index/sub already at list, return error */
	pFct = icoEventObjectChangedFunction(CO_LINE, index, subIndex);
	if (pFct != NULL)  {
		return(RET_ALREADY_INITIALIZED);
	}

	/* list full, abort */
	if (objectEventTableCnt == CO_EVENT_OBJECT_CHANGED_CNT)  {
		return(RET_EVENT_NO_RESSOURCE);
	}

	/* sort into last position from list */
	idx = objectEventTableCnt;
	objectEventTableCnt++;
	objectEventTable[idx].index = index;
	objectEventTable[idx].subIndex = subIndex;
	objectEventTable[idx].canLine = CO_LINE;
	objectEventTable[idx].pFct = pFunction;
	while (idx > 0u)  {
		/* if value < predecessor, exchange with him */
		if (objectEventTable[idx].index < objectEventTable[idx - 1u].index)  {
			MEMCPY(&tObj, &objectEventTable[idx], l);
			MEMCPY(&objectEventTable[idx], &objectEventTable[idx - 1u], l);
			MEMCPY(&objectEventTable[idx - 1u], &tObj, l);
		} else {
			if (objectEventTable[idx].index == objectEventTable[idx - 1u].index)  {
				/* subindex = 255 is valid for each subindex */
				if (objectEventTable[idx].subIndex != 255u)  {
					/* check the same with subindex */
					if (objectEventTable[idx].subIndex < objectEventTable[idx - 1u].subIndex)  {
						MEMCPY(&tObj, &objectEventTable[idx], l);
						MEMCPY(&objectEventTable[idx], &objectEventTable[idx - 1u], l);
						MEMCPY(&objectEventTable[idx - 1u], &tObj, l);
					}
				}
			}
		}
		idx--;
	}

	return(RET_OK);
}


/***************************************************************************/
/**
* \internal
*
* \brief icoEventObjectGetIndex - get object event function
*
* \return RET_T
*
*/
CO_EVENT_OBJECT_CHANGED_FCT_T icoEventObjectChangedFunction(
		CO_LINE_TYPE	CO_LINE,	/* can line */
		UNSIGNED16	index,			/* index */
		UNSIGNED8	subIndex		/* subIndex */
	)
{
UNSIGNED16	idx = 0u;

	while (idx < objectEventTableCnt)  {
		if ((objectEventTable[idx].index == index)
		 || (objectEventTable[idx].index == 0xffffu))  {
			if ((objectEventTable[idx].subIndex == subIndex)
		 	 || (objectEventTable[idx].subIndex == 255u))  {
				if (objectEventTable[idx].canLine == CO_LINE)
				{
					return(objectEventTable[idx].pFct);
				}
			}
		}
		idx++;
	}

	return(NULL);
}

#endif /* CO_EVENT_OBJECT_CHANGED_CNT */


/***************************************************************************/
/**
* \internal
*
* \brief coEventObjectChanged - event object changed
*
* \return RET_T
*
*/
RET_T icoEventObjectChanged(
		CO_LINE_TYPE			CO_LINE,	/* can line */
		CO_CONST CO_OBJECT_DESC_T	*pDesc,	/* pointer for description index */
		UNSIGNED16				index,		/* object index */
		UNSIGNED8				subIndex,	/* object subindex */
		BOOL_T					changed		/* object has new value */
	)
{
RET_T		retVal = RET_OK;
#ifdef CO_EVENT_OBJECT_CHANGED
#else /* CO_EVENT_OBJECT_CHANGED */
	(void)index;
	(void)changed;
#endif /* CO_EVENT_OBJECT_CHANGED */

#ifdef CO_EVENT_STORE
	/* don't execute function at load parameter state */
	if (loadParameterState[CO_LINE] == CO_TRUE)  {
#ifdef CO_SRDO_SUPPORTED
		switch (pDesc->dType)  {
		/* special handling for SRDO write back */
		case CO_DTYPE_U8_SRDO:
		case CO_DTYPE_U16_SRDO:
		case CO_DTYPE_U32_SRDO:
		case CO_DTYPE_I8_SRDO:
		case CO_DTYPE_I16_SRDO:
		case CO_DTYPE_I32_SRDO:
		case CO_DTYPE_R32_SRDO:
			retVal = icoSrdoObjChanged(CO_LINE, pDesc->tableIdx, subIndex, pDesc->dType);
			break;
		default:
			break;
		}
#endif /* CO_SRDO_SUPPORTED */
		return(retVal);
	}
#endif /* CO_EVENT_STORE */

	/* first, call objects at 0x1000..0x1fff */
	switch (pDesc->dType)  {
#ifdef CO_SDO_SERVER_CNT
		case CO_DTYPE_U32_SDO_SERVER:
			retVal = icoSdoObjChanged(CO_LINE, pDesc->tableIdx, subIndex);
			break;
#endif /* CO_SDO_SERVER_CNT */

#ifdef CO_SDO_CLIENT_CNT
		case CO_DTYPE_U32_SDO_CLIENT:
			retVal = icoSdoClientObjChanged(CO_LINE, pDesc->tableIdx, subIndex);
			break;
#endif /* CO_SDO_CLIENT_CNT */

#ifdef CO_PDO_TRANSMIT_CNT
		case CO_DTYPE_U8_TPDO:
		case CO_DTYPE_U16_TPDO:
		case CO_DTYPE_U32_TPDO:
			retVal = icoTrPdoObjChanged(CO_LINE, pDesc->tableIdx, subIndex);
			break;

# ifdef CO_TR_PDO_DYN_MAP_ENTRIES
		case CO_DTYPE_U8_TMAP:
			retVal = icoTrPdoMapChanged(CO_LINE, pDesc->tableIdx);
			break;
# endif /* CO_TR_PDO_DYN_MAP_ENTRIES */
#endif /* CO_PDO_TRANSMIT_CNT */

#ifdef CO_PDO_RECEIVE_CNT
		case CO_DTYPE_U8_RPDO:
		case CO_DTYPE_U16_RPDO:
		case CO_DTYPE_U32_RPDO:
			retVal = icoRecPdoObjChanged(CO_LINE, pDesc->tableIdx, subIndex);
			break;

# ifdef CO_REC_PDO_DYN_MAP_ENTRIES
		case CO_DTYPE_U8_RMAP:
			retVal = icoRecPdoMapChanged(CO_LINE, pDesc->tableIdx);
			break;
# endif /* CO_REC_PDO_DYN_MAP_ENTRIES */
#endif /* CO_PDO_RECEIVE_CNT */

#ifdef CANOPEN_SUPPORTED
		case CO_DTYPE_U8_ERRCTRL:
		case CO_DTYPE_U16_ERRCTRL:
		case CO_DTYPE_U32_ERRCTRL:
			retVal = icoErrCtrlObjChanged(CO_LINE, pDesc->tableIdx, subIndex);
			break;
#endif /* CANOPEN_SUPPORTED */

#ifdef CO_SYNC_SUPPORTED
		case CO_DTYPE_U8_SYNC:
		case CO_DTYPE_U32_SYNC:
			retVal = icoSyncObjChanged(CO_LINE, pDesc->tableIdx);
			break;
#endif /* CO_SYNC_SUPPORTED */

		case CO_DTYPE_U8_EMCY:
		case CO_DTYPE_U16_EMCY:
#ifdef CO_EMCY_PRODUCER
			retVal = icoEmcyObjChanged(CO_LINE, pDesc->tableIdx, subIndex);
#endif /* CO_EMCY_PRODUCER */
			break;
		case CO_DTYPE_U32_EMCY:
#if defined(CO_EMCY_PRODUCER) || defined (CO_EMCY_CONSUMER_CNT)
			retVal = icoEmcyObjChanged(CO_LINE, pDesc->tableIdx, subIndex);
#endif /* defined(CO_EMCY_PRODUCER) || defined (CO_EMCY_CONSUMER_CNT) */
			break;

#ifdef CO_TIME_SUPPORTED
		case CO_DTYPE_U32_TIME:
			retVal = icoTimeObjChanged(CO_LINE);
			break;
#endif /* CO_TIME_SUPPORTED */

#ifdef CO_STORE_SUPPORTED
		case CO_DTYPE_U32_STORE:
			retVal = icoStoreObjChanged(CO_LINE, pDesc->tableIdx, subIndex);
			break;
#endif /* CO_STORE_SUPPORTED */

#if defined(CO_NMT_MASTER) || defined(CO_SELF_STARTING_DEVICE)
		case CO_DTYPE_U8_NMT:
		case CO_DTYPE_U16_NMT:
		case CO_DTYPE_U32_NMT:
			retVal = icoNmtObjChanged(CO_LINE, pDesc->tableIdx, subIndex);
			break;
#endif /* defined(CO_NMT_MASTER) || defined(CO_SELF_STARTING_DEVICE) */


#ifdef CO_SRDO_SUPPORTED
		case CO_DTYPE_U8_SRDO:
		case CO_DTYPE_U16_SRDO:
		case CO_DTYPE_U32_SRDO:
		case CO_DTYPE_I8_SRDO:
		case CO_DTYPE_I16_SRDO:
		case CO_DTYPE_I32_SRDO:
		case CO_DTYPE_R32_SRDO:
			retVal = icoSrdoObjChanged(CO_LINE, pDesc->tableIdx, subIndex, pDesc->dType);
			break;
#endif /* CO_SRDO_SUPPORTED */

		default:
			break;
	}

	if (retVal != RET_OK)  {
		return(retVal);
	}

#ifdef CO_EVENT_OBJECT_CHANGED
	if (changed == CO_TRUE)  {
		CO_EVENT_OBJECT_CHANGED_FCT_T pFct;

		pFct = icoEventObjectChangedFunction(CO_LINE, index, subIndex);
		if (pFct != NULL)  {
			retVal = pFct(CO_LINE, index, subIndex);
		}
	}
#endif /* CO_EVENT_OBJECT_CHANGED */

	return(retVal);
}


/***************************************************************************/
/**
* \internal
*
* \brief icoOdGetNumberOfSubs - get number of subindexe
*
*
* \return number of subs
*
*/
UNSIGNED8	icoOdGetNumberOfSubs(
		CO_LINE_TYPE	CO_LINE,	/* can line */
		UNSIGNED16		index		/* index */
	)
{
UNSIGNED16	i;
UNSIGNED16	offs;

	for (i = 0u; i < odAssignCnt[CO_LINE]; i++)  {
		if (pOdAssignTable[CO_LINE][i].index == index)  {
			offs = pOdAssignTable[CO_LINE][i].odDescIdx;
			offs += pOdAssignTable[CO_LINE][i].numberOfSubs;
			offs -= 1u;
			if ((pObjDescTable[CO_LINE][offs].attr & CO_ATTR_COMPACT) != 0u ) {
				return((UNSIGNED8)(pOdAssignTable[CO_LINE][i].highestSub + 1u));
			} else {
				return(pOdAssignTable[CO_LINE][i].numberOfSubs);
			}
		}
	}

	return(0u);
}


#ifdef CO_EVENT_STORE
/***************************************************************************/
/**
* \internal
*
* \brief icoOdSetLoadParaState - sets new load state internally
*
*
* \return none
*
*/
void icoOdSetLoadParaState(
		CO_LINE_TYPE	CO_LINE,		/* can line */
		BOOL_T	newState
	)
{
	loadParameterState[CO_LINE] = newState;
}
#endif /* CO_EVENT_STORE */


/***************************************************************************/
/**
* \internal
*
* \brief icoOdReset - reset obect dictionary variables
*
*
* \return none
*
*/
void icoOdReset(
		CO_LINE_TYPE	CO_LINE,		/* can line */
		UNSIGNED16		startIdx,		/* start index */
		UNSIGNED16		lastIdx			/* last index */
	)
{
UNSIGNED16			i;
UNSIGNED16			sub = 0u;
const CO_OBJECT_DESC_T	*pDesc;
UNSIGNED8	*p_u8;
UNSIGNED16	*p_u16;
UNSIGNED32	*p_u32;
INTEGER8	*p_i8;
INTEGER16	*p_i16;
INTEGER32	*p_i32;
REAL32		*p_r32;

	/* start at index */
	for (i = 0u; i < odAssignCnt[CO_LINE]; i++)  {
		if ((pOdAssignTable[CO_LINE][i].index >= startIdx)
		 && (pOdAssignTable[CO_LINE][i].index <= lastIdx))  {
			/* reset all subs */
			for (sub = 0u; sub < pOdAssignTable[CO_LINE][i].numberOfSubs; sub++)  {
				pDesc = &pObjDescTable[CO_LINE][pOdAssignTable[CO_LINE][i].odDescIdx + sub];

				/* reset only objects with default value */
				if ((pDesc->attr & CO_ATTR_DEFVAL) != 0u)  {
					switch (pDesc->dType)  {
						case CO_DTYPE_U8_VAR:
						case CO_DTYPE_BOOL_VAR:
							CO_OS_LOCK_OD
							pOdVar_u8[pDesc->tableIdx] = pOdConst_u8[pDesc->defValIdx];
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_I8_VAR:
							CO_OS_LOCK_OD
							pOdVar_i8[pDesc->tableIdx] = pOdConst_i8[pDesc->defValIdx];
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_U16_VAR:
							CO_OS_LOCK_OD
							pOdVar_u16[pDesc->tableIdx] = pOdConst_u16[pDesc->defValIdx];
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_I16_VAR:
							CO_OS_LOCK_OD
							pOdVar_i16[pDesc->tableIdx] = pOdConst_i16[pDesc->defValIdx];
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_U32_VAR:
							CO_OS_LOCK_OD
							pOdVar_u32[pDesc->tableIdx] = pOdConst_u32[pDesc->defValIdx];
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_R32_VAR:
							CO_OS_LOCK_OD
							pOdVar_r32[pDesc->tableIdx] = pOdConst_r32[pDesc->defValIdx];
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_I32_VAR:
							CO_OS_LOCK_OD
							pOdVar_i32[pDesc->tableIdx] = pOdConst_i32[pDesc->defValIdx];
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_U8_PTR:
						case CO_DTYPE_BOOL_PTR:
							p_u8 = pOdPtr_u8[pDesc->tableIdx];
							CO_OS_LOCK_OD
							*p_u8 = pOdConst_u8[pDesc->defValIdx];
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_I8_PTR:
							p_i8 = pOdPtr_i8[pDesc->tableIdx];
							CO_OS_LOCK_OD
							*p_i8 = pOdConst_i8[pDesc->defValIdx];
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_U16_PTR:
							p_u16 = pOdPtr_u16[pDesc->tableIdx];
							CO_OS_LOCK_OD
							*p_u16 = pOdConst_u16[pDesc->defValIdx];
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_I16_PTR:
							p_i16 = pOdPtr_i16[pDesc->tableIdx];
							CO_OS_LOCK_OD
							*p_i16 = pOdConst_i16[pDesc->defValIdx];
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_U32_PTR:
							p_u32 = pOdPtr_u32[pDesc->tableIdx];
							CO_OS_LOCK_OD
							*p_u32 = pOdConst_u32[pDesc->defValIdx];
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_I32_PTR:
							p_i32 = pOdPtr_i32[pDesc->tableIdx];
							CO_OS_LOCK_OD
							*p_i32 = pOdConst_i32[pDesc->defValIdx];
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_R32_PTR:
							p_r32 = pOdPtr_r32[pDesc->tableIdx];
							CO_OS_LOCK_OD
							*p_r32 = pOdConst_r32[pDesc->defValIdx];
							CO_OS_UNLOCK_OD
							break;

#ifdef CO_EXTENDED_DATA_TYPES
						case CO_DTYPE_U24_VAR:
							CO_OS_LOCK_OD
							MEMCPY(&pOdVar_u24[pDesc->tableIdx],
								&pOdConst_u24[pDesc->defValIdx], 3u);
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_U24_PTR:
							CO_OS_LOCK_OD
							MEMCPY(pOdPtr_u24[pDesc->tableIdx],
								&pOdConst_u24[pDesc->defValIdx], 3u);
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_U40_VAR:
							CO_OS_LOCK_OD
							MEMCPY(&pOdVar_u40[pDesc->tableIdx],
								&pOdConst_u40[pDesc->defValIdx], 5u);
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_U40_PTR:
							CO_OS_LOCK_OD
							MEMCPY(pOdPtr_u40[pDesc->tableIdx],
								&pOdConst_u40[pDesc->defValIdx], 5u);
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_U48_VAR:
							CO_OS_LOCK_OD
							MEMCPY(&pOdVar_u48[pDesc->tableIdx],
								&pOdConst_u48[pDesc->defValIdx], 6u);
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_U48_PTR:
							CO_OS_LOCK_OD
							MEMCPY(pOdPtr_u48[pDesc->tableIdx],
								&pOdConst_u48[pDesc->defValIdx], 6u);
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_U64_VAR:
							CO_OS_LOCK_OD
							MEMCPY(&pOdVar_u64[pDesc->tableIdx],
								&pOdConst_u64[pDesc->defValIdx], 8u);
							CO_OS_UNLOCK_OD
							break;
						case CO_DTYPE_U64_PTR:
							CO_OS_LOCK_OD
							MEMCPY(pOdPtr_u64[pDesc->tableIdx],
								&pOdConst_u64[pDesc->defValIdx], 8u);
							CO_OS_UNLOCK_OD
							break;
#endif /* CO_EXTENDED_DATA_TYPES */

#ifdef SRDO_OD_ENTRY_U8_CNT
						case CO_DTYPE_U8_SRDO:
							(void)genSrdoDataPut_u8(CO_LINE,
							 	pOdAssignTable[CO_LINE][i].index, sub,
								pOdConst_u8[pDesc->defValIdx]);
							break;
#endif /* SRDO_OD_ENTRY_U8_CNT */
#ifdef SRDO_OD_ENTRY_U16_CNT
						case CO_DTYPE_U16_SRDO:
							(void) genSrdoDataPut_u16(CO_LINE,
							 	pOdAssignTable[CO_LINE][i].index, sub,
								pOdConst_u16[pDesc->defValIdx]);
							break;
#endif /* SRDO_OD_ENTRY_U16_CNT */
#ifdef SRDO_OD_ENTRY_U32_CNT
						case CO_DTYPE_U32_SRDO:
							(void) genSrdoDataPut_u32(CO_LINE,
							 	pOdAssignTable[CO_LINE][i].index, sub,
								pOdConst_u32[pDesc->defValIdx]);
							break;
#endif /* SRDO_OD_ENTRY_U32_CNT */
#ifdef SRDO_OD_ENTRY_I8_CNT
						case CO_DTYPE_I8_SRDO:
							(void) genSrdoDataPut_i8(CO_LINE,
							 	pOdAssignTable[CO_LINE][i].index, sub,
								pOdConst_i8[pDesc->defValIdx]);
							break;
#endif /* SRDO_OD_ENTRY_I8_CNT */
#ifdef SRDO_OD_ENTRY_I16_CNT
						case CO_DTYPE_I16_SRDO:
							(void) genSrdoDataPut_i16(CO_LINE,
							 	pOdAssignTable[CO_LINE][i].index, sub,
								pOdConst_i16[pDesc->defValIdx]);
							break;
#endif /* SRDO_OD_ENTRY_I16_CNT */
#ifdef SRDO_OD_ENTRY_I32_CNT
						case CO_DTYPE_I32_SRDO:
							(void) genSrdoDataPut_i32(CO_LINE,
							 	pOdAssignTable[CO_LINE][i].index, sub,
								pOdConst_i32[pDesc->defValIdx]);
							break;
#endif /* SRDO_OD_ENTRY_I32_CNT */
#ifdef SRDO_OD_ENTRY_R32_CNT
						case CO_DTYPE_R32_SRDO:
							(void) genSrdoDataPut_r32(CO_LINE,
							 	pOdAssignTable[CO_LINE][i].index, sub,
								pOdConst_r32[pDesc->defValIdx]);
							break;
#endif /* SRDO_OD_ENTRY_R32_CNT */
						default:
							break;
					}
				}
			}
		}
	}
}


/***************************************************************************/
/**
* \internal
*
* \brief icoOdVarInit - variable init
*
*
* \return none
*
*/
void icoOdAccessVarInit(
		void
	)
{
# if defined(CO_STORE_SUPPORTED) || defined(CO_EVENT_STORE)
CO_LINE_TYPE	CO_LINE;
# endif /* defined(CO_STORE_SUPPORTED) || defined(CO_EVENT_STORE) */

#ifdef CO_EVENT_OBJECT_CHANGED_CNT
	objectEventTableCnt = 0u;
#endif /* CO_EVENT_OBJECT_CHANGED_CNT */

	pOdConst_u8 = NULL;
	pOdConst_u16 = NULL;
	pOdConst_u32 = NULL;
	pOdConst_r32 = NULL;
	pOdVar_u8 = NULL;
	pOdVar_u16 = NULL;
	pOdVar_u32 = NULL;
	pOdVar_r32 = NULL;
	pOdConst_i8 = NULL;
	pOdConst_i16 = NULL;
	pOdConst_i32 = NULL;
	pOdVar_i8 = NULL;
	pOdVar_i16 = NULL;
	pOdVar_i32 = NULL;
	pOdPtr_u8 = NULL;
	pOdPtr_u16 = NULL;
	pOdPtr_u32 = NULL;
	pOdPtr_i8 = NULL;
	pOdPtr_i16 = NULL;
	pOdPtr_i32 = NULL;
	pOdPtr_r32 = NULL;
	pOdConst_VS = NULL;
	pOdConst_VS_MaxLen = NULL;
	pOdPtr_VS = NULL;
	pOdPtr_VS_MaxLen = NULL;
	pOdPtr_VS_ActLen = NULL;
	pOdPtr_OS = NULL;
	pOdPtr_OS_MaxLen =  NULL;
	pOdPtr_OS_ActLen =  NULL;
	pOdPtr_Domain = NULL;
	pOdPtr_Domain_MaxLen = NULL;
	pOdPtr_Domain_ActLen = NULL;

#ifdef CO_EXTENDED_DATA_TYPES
	pOdConst_u24 = NULL;
	pOdConst_u40 = NULL;
	pOdConst_u48 = NULL;
	pOdConst_u64 = NULL;
	pOdVar_u24 = NULL;
	pOdVar_u40 = NULL;
	pOdVar_u48 = NULL;
	pOdVar_u64 = NULL;
	pOdPtr_u24 = NULL;
	pOdPtr_u40 = NULL;
	pOdPtr_u48 = NULL;
	pOdPtr_u64 = NULL;
#endif /* CO_EXTENDED_DATA_TYPES */

#ifdef CO_EVENT_STORE
	for (CO_LINE = 0u; CO_LINE < CO_MULTI_LINE_CNT; CO_LINE++) 
	{
		loadParameterState[CO_LINE] = CO_FALSE;
	}
#endif /* CO_EVENT_STORE */

#ifdef CO_STORE_SUPPORTED
	for (CO_LINE = 0u; CO_LINE < CO_MULTI_LINE_CNT; CO_LINE++)
	{
		/* reset all pointer */
		odLastStore[CO_LINE].assign = 0u;
		odLastStore[CO_LINE].subIdx = 0u;
		odLastStore[CO_LINE].idx = 0u;
	}
#endif /* CO_STORE_SUPPORTED */

}


/***************************************************************************/
/**
* \brief coOdInitOdPtr - init all object dictionary and variable pointers
*
* This function initializes the object dictionary with all variables.
*
* \return none
*
*/
void coOdInitOdPtr(
		CO_LINE_TYPE			CO_LINE,	/**< can line */
		const CO_OD_ASSIGN_T	*pOdAssign,	/**< pointer to OD assign */
		UNSIGNED16				odCnt,		/**< number of objects */
		const CO_OBJECT_DESC_T	*pObjdesc,	/**< pointer to obj descr */
		UNSIGNED16				descCnt,	/**< number of obj desc */
		CO_EVENT_OBJECT_CHANGED_FCT_T *pEventPtr, /**< pointer to obj events */
		const CO_OD_DATA_VARIABLES_T *pOdVarPointers /**< pointer to variable types */
	)
{
(void)descCnt;
(void)pEventPtr;

	pOdAssignTable[CO_LINE] = pOdAssign;
	odAssignCnt[CO_LINE] = odCnt;
	pObjDescTable[CO_LINE] = pObjdesc;

	pOdConst_u8 = pOdVarPointers->odConst_u8;
	pOdConst_u16 = pOdVarPointers->odConst_u16;
	pOdConst_u32 = pOdVarPointers->odConst_u32;
	pOdConst_r32 = pOdVarPointers->odConst_r32;
#ifdef CO_EXTENDED_DATA_TYPES
	pOdConst_u24 = pOdVarPointers->odConst_u24;
	pOdConst_u40 = pOdVarPointers->odConst_u40;
	pOdConst_u48 = pOdVarPointers->odConst_u48;
	pOdConst_u64 = pOdVarPointers->odConst_u64;
#endif /* CO_EXTENDED_DATA_TYPES */
	pOdVar_u8 = pOdVarPointers->odVar_u8;
	pOdVar_u16 = pOdVarPointers->odVar_u16;
	pOdVar_u32 = pOdVarPointers->odVar_u32;
	pOdVar_r32 = pOdVarPointers->odVar_r32;
#ifdef CO_EXTENDED_DATA_TYPES
	pOdVar_u24 = pOdVarPointers->odVar_u24;
	pOdVar_u40 = pOdVarPointers->odVar_u40;
	pOdVar_u48 = pOdVarPointers->odVar_u48;
	pOdVar_u64 = pOdVarPointers->odVar_u64;
#endif /* CO_EXTENDED_DATA_TYPES */
	pOdPtr_u8 =  pOdVarPointers->odPtr_u8;
	pOdPtr_u16 =  pOdVarPointers->odPtr_u16;
	pOdPtr_u32 =  pOdVarPointers->odPtr_u32;
	pOdPtr_r32 =  pOdVarPointers->odPtr_r32;
#ifdef CO_EXTENDED_DATA_TYPES
	pOdPtr_u24 =  pOdVarPointers->odPtr_u24;
	pOdPtr_u40 =  pOdVarPointers->odPtr_u40;
	pOdPtr_u48 =  pOdVarPointers->odPtr_u48;
	pOdPtr_u64 =  pOdVarPointers->odPtr_u64;
#endif /* CO_EXTENDED_DATA_TYPES */

	pOdConst_i8 = pOdVarPointers->odConst_i8;
	pOdConst_i16 = pOdVarPointers->odConst_i16;
	pOdConst_i32 = pOdVarPointers->odConst_i32;
	pOdVar_i8 = pOdVarPointers->odVar_i8;
	pOdVar_i16 = pOdVarPointers->odVar_i16;
	pOdVar_i32 = pOdVarPointers->odVar_i32;
	pOdPtr_i8 =  pOdVarPointers->odPtr_i8;
	pOdPtr_i16 =  pOdVarPointers->odPtr_i16;
	pOdPtr_i32 =  pOdVarPointers->odPtr_i32;

	pOdConst_VS = pOdVarPointers->odConstVisString;
	pOdConst_VS_MaxLen = pOdVarPointers->odConstVisStringLen;
	pOdPtr_VS = pOdVarPointers->odVisString;
	pOdPtr_VS_MaxLen = pOdVarPointers->odVisStringLen;
	pOdPtr_VS_ActLen = pOdVarPointers->odVisStringActLen;

	pOdPtr_OS = pOdVarPointers->odOctetString;
	pOdPtr_OS_MaxLen = pOdVarPointers->odOctetStringLen;
	pOdPtr_OS_ActLen = pOdVarPointers->odOctetStringActLen;
	pOdPtr_Domain = pOdVarPointers->domainPtr;
	pOdPtr_Domain_MaxLen = pOdVarPointers->domainLen;
	pOdPtr_Domain_ActLen = pOdVarPointers->domainActLen;

	/* reset application variables */
	icoOdReset(CO_LINE, 0x1000u, 0x9fffu);
}

