etisserant@0: /*
etisserant@0: This file is part of CanFestival, a library implementing CanOpen Stack. 
etisserant@0: 
etisserant@0: Copyright (C): Edouard TISSERANT and Francis DUPIN
etisserant@0: 
etisserant@0: See COPYING file for copyrights details.
etisserant@0: 
etisserant@0: This library is free software; you can redistribute it and/or
etisserant@0: modify it under the terms of the GNU Lesser General Public
etisserant@0: License as published by the Free Software Foundation; either
etisserant@0: version 2.1 of the License, or (at your option) any later version.
etisserant@0: 
etisserant@0: This library is distributed in the hope that it will be useful,
etisserant@0: but WITHOUT ANY WARRANTY; without even the implied warranty of
etisserant@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
etisserant@0: Lesser General Public License for more details.
etisserant@0: 
etisserant@0: You should have received a copy of the GNU Lesser General Public
etisserant@0: License along with this library; if not, write to the Free Software
etisserant@0: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
etisserant@0: */
etisserant@0: 
etisserant@0: #ifndef __data_h__
etisserant@0: #define __data_h__
etisserant@0: 
etisserant@251: #ifdef __cplusplus
etisserant@251: extern "C" {
etisserant@251: #endif
etisserant@251: 
frdupin@71: /* declaration of CO_Data type let us include all necessary headers
frdupin@71:  struct struct_CO_Data can then be defined later
frdupin@71:  */
etisserant@0: typedef struct struct_CO_Data CO_Data;
etisserant@0: 
etisserant@145: #include "applicfg.h"
etisserant@0: #include "def.h"
etisserant@0: #include "can.h"
etisserant@0: #include "objdictdef.h"
etisserant@0: #include "objacces.h"
etisserant@0: #include "sdo.h"
etisserant@0: #include "pdo.h"
etisserant@0: #include "states.h"
etisserant@0: #include "lifegrd.h"
etisserant@0: #include "sync.h"
etisserant@383: #include "nmtSlave.h"
etisserant@0: #include "nmtMaster.h"
luis@284: #include "emcy.h"
etisserant@343: #ifdef CO_ENABLE_LSS
etisserant@343: #include "lss.h"
etisserant@343: #endif
etisserant@0: 
greg@528: /**
greg@528:  * @ingroup od
greg@561:  * @brief This structure contains all necessary informations to define a CANOpen node 
greg@528:  */
etisserant@0: struct struct_CO_Data {
frdupin@71: 	/* Object dictionary */
etisserant@0: 	UNS8 *bDeviceNodeId;
etisserant@0: 	const indextable *objdict;
etisserant@235: 	s_PDO_status *PDO_status;
Mongo@670: 	TIMER_HANDLE *RxPDO_EventTimers;
Mongo@670: 	void (*RxPDO_EventTimers_Handler)(CO_Data*, UNS32);
etisserant@475: 	const quick_index *firstIndex;
etisserant@475: 	const quick_index *lastIndex;
etisserant@475: 	const UNS16 *ObjdictSize;
etisserant@0: 	const UNS8 *iam_a_slave;
etisserant@0: 	valueRangeTest_t valueRangeTest;
etisserant@0: 	
frdupin@71: 	/* SDO */
etisserant@0: 	s_transfer transfers[SDO_MAX_SIMULTANEOUS_TRANSFERTS];
frdupin@71: 	/* s_sdo_parameter *sdo_parameters; */
etisserant@0: 
frdupin@71: 	/* State machine */
etisserant@0: 	e_nodeState nodeState;
etisserant@0: 	s_state_communication CurrentCommunicationState;
etisserant@0: 	initialisation_t initialisation;
etisserant@0: 	preOperational_t preOperational;
etisserant@0: 	operational_t operational;
etisserant@0: 	stopped_t stopped;
etisserant@475:      void (*NMT_Slave_Node_Reset_Callback)(CO_Data*);
etisserant@475:      void (*NMT_Slave_Communications_Reset_Callback)(CO_Data*);
etisserant@475:      
frdupin@71: 	/* NMT-heartbeat */
etisserant@0: 	UNS8 *ConsumerHeartbeatCount;
etisserant@0: 	UNS32 *ConsumerHeartbeatEntries;
etisserant@0: 	TIMER_HANDLE *ConsumerHeartBeatTimers;
etisserant@0: 	UNS16 *ProducerHeartBeatTime;
etisserant@0: 	TIMER_HANDLE ProducerHeartBeatTimer;
etisserant@0: 	heartbeatError_t heartbeatError;
etisserant@0: 	e_nodeState NMTable[NMT_MAX_NODE_ID]; 
etisserant@0: 
frdupin@71: 	/* SYNC */
etisserant@0: 	TIMER_HANDLE syncTimer;
etisserant@0: 	UNS32 *COB_ID_Sync;
etisserant@0: 	UNS32 *Sync_Cycle_Period;
frdupin@71: 	/*UNS32 *Sync_window_length;;*/
etisserant@0: 	post_sync_t post_sync;
etisserant@0: 	post_TPDO_t post_TPDO;
etisserant@343: 	post_SlaveBootup_t post_SlaveBootup;
fbeaulier@664:     post_SlaveStateChange_t post_SlaveStateChange;
etisserant@0: 	
frdupin@71: 	/* General */
etisserant@0: 	UNS8 toggle;
etisserant@405: 	CAN_PORT canHandle;	
etisserant@0: 	scanIndexOD_t scanIndexOD;
etisserant@161: 	storeODSubIndex_t storeODSubIndex; 
greg@178: 	
greg@178: 	/* DCF concise */
etisserant@322:     const indextable* dcf_odentry;
etisserant@204: 	UNS8* dcf_cursor;
etisserant@320: 	UNS32 dcf_entries_count;
Mongo@669: 	UNS8 dcf_status;
Mongo@669:     UNS32 dcf_size;
Mongo@669:     UNS8* dcf_data;
greg@178: 	
luis@284: 	/* EMCY */
luis@284: 	e_errorState error_state;
luis@284: 	UNS8 error_history_size;
luis@284: 	UNS8* error_number;
luis@284: 	UNS32* error_first_element;
luis@284: 	UNS8* error_register;
etisserant@314:     UNS32* error_cobid;
luis@284: 	s_errors error_data[EMCY_MAX_ERRORS];
luis@284: 	post_emcy_t post_emcy;
luis@284: 	
etisserant@343: #ifdef CO_ENABLE_LSS
etisserant@343: 	/* LSS */
etisserant@343: 	lss_transfer_t lss_transfer;
etisserant@343: 	lss_StoreConfiguration_t lss_StoreConfiguration;
etisserant@343: #endif	
etisserant@0: };
etisserant@0: 
etisserant@91: #define NMTable_Initializer Unknown_state,
etisserant@91: 
Christian@636: #ifdef SDO_DYNAMIC_BUFFER_ALLOCATION
Christian@636: #define s_transfer_Initializer {\
fbeaulier@664: 		0,          /* CliServNbr */\
Christian@636: 		0,          /* wohami */\
Christian@636: 		SDO_RESET,  /* state */\
Christian@636: 		0,          /* toggle */\
Christian@636: 		0,          /* abortCode */\
Christian@636: 		0,          /* index */\
Christian@636: 		0,          /* subIndex */\
Christian@636: 		0,          /* count */\
Christian@636: 		0,          /* offset */\
Christian@636: 		{0},        /* data (static use, so that all the table is initialize at 0)*/\
Christian@636:     NULL,       /* dynamicData */ \
Christian@636:     0,          /* dynamicDataSize */ \
fbeaulier@664: 		0,          /* peerCRCsupport */\
fbeaulier@664: 		0,          /* blksize */\
fbeaulier@664: 		0,          /* ackseq */\
fbeaulier@664: 		0,          /* objsize */\
fbeaulier@664: 		0,          /* lastblockoffset */\
fbeaulier@664: 		0,          /* seqno */\
fbeaulier@664: 		0,          /* endfield */\
fbeaulier@664: 		RXSTEP_INIT,/* rxstep */\
fbeaulier@664: 		{0},        /* tmpData */\
Christian@636: 		0,          /* dataType */\
Christian@636: 		-1,         /* timer */\
Christian@636: 		NULL        /* Callback */\
Christian@636: 	  },
Christian@636: #else
etisserant@91: #define s_transfer_Initializer {\
etisserant@91: 		0,          /* nodeId */\
etisserant@91: 		0,          /* wohami */\
etisserant@91: 		SDO_RESET,  /* state */\
etisserant@91: 		0,          /* toggle */\
etisserant@91: 		0,          /* abortCode */\
etisserant@91: 		0,          /* index */\
etisserant@91: 		0,          /* subIndex */\
etisserant@91: 		0,          /* count */\
etisserant@91: 		0,          /* offset */\
etisserant@91: 		{0},        /* data (static use, so that all the table is initialize at 0)*/\
fbeaulier@664: 		0,          /* peerCRCsupport */\
fbeaulier@664: 		0,          /* blksize */\
fbeaulier@664: 		0,          /* ackseq */\
fbeaulier@664: 		0,          /* objsize */\
fbeaulier@664: 		0,          /* lastblockoffset */\
fbeaulier@664: 		0,          /* seqno */\
fbeaulier@664: 		0,          /* endfield */\
fbeaulier@664: 		RXSTEP_INIT,/* rxstep */\
fbeaulier@664: 		{0},        /* tmpData */\
fbeaulier@664: 		0,          /*  */\
fbeaulier@664: 		-1,         /*  */\
fbeaulier@664: 		NULL        /*  */\
etisserant@91: 	  },
Christian@636: #endif //SDO_DYNAMIC_BUFFER_ALLOCATION
etisserant@91: 
luis@284: #define ERROR_DATA_INITIALIZER \
luis@284: 	{\
luis@284: 	0, /* errCode */\
luis@284: 	0, /* errRegMask */\
luis@284: 	0 /* active */\
luis@284: 	},
etisserant@343: 	
etisserant@343: #ifdef CO_ENABLE_LSS
groke6@381: 
groke6@381: #ifdef CO_ENABLE_LSS_FS	
groke6@381: #define lss_fs_Initializer \
groke6@381: 		,0,						/* IDNumber */\
groke6@381:   		128, 					/* BitChecked */\
groke6@381:   		0,						/* LSSSub */\
groke6@381:   		0, 						/* LSSNext */\
groke6@381:   		0, 						/* LSSPos */\
groke6@381:   		LSS_FS_RESET,			/* FastScan_SM */\
groke6@517:   		-1,						/* timerFS */\
groke6@517:   		{{0,0,0,0},{0,0,0,0}}   /* lss_fs_transfer */
groke6@381: #else
groke6@381: #define lss_fs_Initializer
groke6@381: #endif		
groke6@381: 
etisserant@343: #define lss_Initializer {\
etisserant@343: 		LSS_RESET,  			/* state */\
etisserant@343: 		0,						/* command */\
etisserant@343: 		LSS_WAITING_MODE, 		/* mode */\
etisserant@343: 		0,						/* dat1 */\
etisserant@343: 		0,						/* dat2 */\
etisserant@343: 		0,          			/* NodeID */\
etisserant@343: 		0,          			/* addr_sel_match */\
etisserant@343: 		0,          			/* addr_ident_match */\
etisserant@343: 		"none",         		/* BaudRate */\
etisserant@343: 		0,          			/* SwitchDelay */\
etisserant@343: 		SDELAY_OFF,   			/* SwitchDelayState */\
groke6@381: 		NULL,					/* canHandle_t */\
groke6@381: 		-1,						/* TimerMSG */\
groke6@381: 		-1,          			/* TimerSDELAY */\
etisserant@343: 		NULL,        			/* Callback */\
groke6@381: 		0						/* LSSanswer */\
groke6@381: 		lss_fs_Initializer		/*FastScan service initialization */\
etisserant@343: 	  },\
groke6@384: 	  NULL 	/* _lss_StoreConfiguration*/
etisserant@343: #else
etisserant@343: #define lss_Initializer
etisserant@343: #endif
etisserant@343: 
luis@284: 
frdupin@71: /* A macro to initialize the data in client app.*/
frdupin@78: /* CO_Data structure */
etisserant@0: #define CANOPEN_NODE_DATA_INITIALIZER(NODE_PREFIX) {\
etisserant@0: 	/* Object dictionary*/\
frdupin@78: 	& NODE_PREFIX ## _bDeviceNodeId,     /* bDeviceNodeId */\
frdupin@78: 	NODE_PREFIX ## _objdict,             /* objdict  */\
etisserant@235: 	NODE_PREFIX ## _PDO_status,          /* PDO_status */\
Mongo@670: 	NULL,                                /* RxPDO_EventTimers */\
Mongo@670: 	_RxPDO_EventTimers_Handler,          /* RxPDO_EventTimers_Handler */\
frdupin@78: 	& NODE_PREFIX ## _firstIndex,        /* firstIndex */\
frdupin@78: 	& NODE_PREFIX ## _lastIndex,         /* lastIndex */\
frdupin@78: 	& NODE_PREFIX ## _ObjdictSize,       /* ObjdictSize */\
frdupin@78: 	& NODE_PREFIX ## _iam_a_slave,       /* iam_a_slave */\
frdupin@78: 	NODE_PREFIX ## _valueRangeTest,      /* valueRangeTest */\
etisserant@0: 	\
frdupin@78: 	/* SDO, structure s_transfer */\
etisserant@91: 	{\
etisserant@91:           REPEAT_SDO_MAX_SIMULTANEOUS_TRANSFERTS_TIMES(s_transfer_Initializer)\
frdupin@78: 	},\
etisserant@0: 	\
frdupin@78: 	/* State machine*/\
frdupin@78: 	Unknown_state,      /* nodeState */\
frdupin@78: 	/* structure s_state_communication */\
frdupin@78: 	{\
frdupin@78: 		0,          /* csBoot_Up */\
frdupin@78: 		0,          /* csSDO */\
frdupin@78: 		0,          /* csEmergency */\
frdupin@78: 		0,          /* csSYNC */\
frdupin@78: 		0,          /* csHeartbeat */\
groke6@381: 		0,           /* csPDO */\
groke6@381: 		0           /* csLSS */\
frdupin@78: 	},\
etisserant@167: 	_initialisation,     /* initialisation */\
etisserant@167: 	_preOperational,     /* preOperational */\
etisserant@167: 	_operational,        /* operational */\
etisserant@167: 	_stopped,            /* stopped */\
etisserant@475: 	NULL,                /* NMT node reset callback */\
etisserant@475: 	NULL,                /* NMT communications reset callback */\
etisserant@0: 	\
etisserant@0: 	/* NMT-heartbeat */\
frdupin@78: 	& NODE_PREFIX ## _highestSubIndex_obj1016, /* ConsumerHeartbeatCount */\
frdupin@78: 	NODE_PREFIX ## _obj1016,                   /* ConsumerHeartbeatEntries */\
frdupin@78: 	NODE_PREFIX ## _heartBeatTimers,           /* ConsumerHeartBeatTimers  */\
frdupin@78: 	& NODE_PREFIX ## _obj1017,                 /* ProducerHeartBeatTime */\
frdupin@78: 	TIMER_NONE,                                /* ProducerHeartBeatTimer */\
etisserant@167: 	_heartbeatError,           /* heartbeatError */\
frdupin@78: 	\
etisserant@91: 	{REPEAT_NMT_MAX_NODE_ID_TIMES(NMTable_Initializer)},\
frdupin@78:                                                    /* is  well initialized at "Unknown_state". Is it ok ? (FD)*/\
etisserant@0: 	\
etisserant@0: 	/* SYNC */\
frdupin@78: 	TIMER_NONE,                                /* syncTimer */\
frdupin@78: 	& NODE_PREFIX ## _obj1005,                 /* COB_ID_Sync */\
frdupin@78: 	& NODE_PREFIX ## _obj1006,                 /* Sync_Cycle_Period */\
frdupin@78: 	/*& NODE_PREFIX ## _obj1007, */            /* Sync_window_length */\
etisserant@167: 	_post_sync,                 /* post_sync */\
etisserant@167: 	_post_TPDO,                 /* post_TPDO */\
etisserant@343: 	_post_SlaveBootup,			/* post_SlaveBootup */\
Christian@635:   _post_SlaveStateChange,			/* post_SlaveStateChange */\
etisserant@0: 	\
etisserant@0: 	/* General */\
frdupin@78: 	0,                                         /* toggle */\
etisserant@167: 	NULL,                   /* canSend */\
etisserant@161: 	NODE_PREFIX ## _scanIndexOD,                /* scanIndexOD */\
greg@178: 	_storeODSubIndex,                /* storeODSubIndex */\
etisserant@320:     /* DCF concise */\
etisserant@320:     NULL,       /*dcf_odentry*/\
greg@178: 	NULL,		/*dcf_cursor*/\
etisserant@320: 	1,		/*dcf_entries_count*/\
Mongo@669: 	0,		/* dcf_status*/\
Mongo@669:     0,      /* dcf_size */\
Mongo@669:     NULL,   /* dcf_data */\
luis@284: 	\
luis@284: 	/* EMCY */\
luis@284: 	Error_free,                      /* error_state */\
luis@284: 	sizeof(NODE_PREFIX ## _obj1003) / sizeof(NODE_PREFIX ## _obj1003[0]),      /* error_history_size */\
luis@284: 	& NODE_PREFIX ## _highestSubIndex_obj1003,    /* error_number */\
luis@284: 	& NODE_PREFIX ## _obj1003[0],    /* error_first_element */\
luis@284: 	& NODE_PREFIX ## _obj1001,       /* error_register */\
etisserant@314:     & NODE_PREFIX ## _obj1014,       /* error_cobid */\
luis@284: 	/* error_data: structure s_errors */\
luis@284: 	{\
luis@284: 	REPEAT_EMCY_MAX_ERRORS_TIMES(ERROR_DATA_INITIALIZER)\
luis@284: 	},\
etisserant@343: 	_post_emcy,              /* post_emcy */\
etisserant@343: 	/* LSS */\
etisserant@343: 	lss_Initializer\
etisserant@0: }
etisserant@0: 
etisserant@251: #ifdef __cplusplus
etisserant@251: };
etisserant@251: #endif
etisserant@251: 
frdupin@71: #endif /* __data_h__ */
etisserant@0: 
etisserant@0: