Пример #1
0
/* Ask a slave node to go in operational mode */
void StartNode(UNS8 nodeid)
{
	masterSendNMTstateChange(CANOpenShellOD_Data, nodeid, NMT_Start_Node);
}
Пример #2
0
static void CheckLSSAndContinue(CO_Data* d, UNS8 command)
{
	UNS32 dat1;
	UNS8 dat2;
	
	printf("CheckLSS->");
	if(getConfigResultNetworkNode (d, command, &dat1, &dat2) != LSS_FINISHED){
			eprintf("Master : Failed in LSS comand %d.  Trying again\n", command);
	}
	else
	{
		init_step_LSS++;
	
		switch(command){
		case LSS_CONF_NODE_ID:
   			switch(dat1){
   				case 0: printf("Node ID change succesful\n");break;
   				case 1: printf("Node ID change error:out of range\n");break;
   				case 0xFF:printf("Node ID change error:specific error\n");break;
   				default:break;
   			}
   			break;
   		case LSS_CONF_BIT_TIMING:
   			switch(dat1){
   				case 0: printf("Baud rate change succesful\n");break;
   				case 1: printf("Baud rate change error: change baud rate not supported\n");break;
   				case 0xFF:printf("Baud rate change error:specific error\n");break;
   				default:break;
   			}
   			break;
   		case LSS_CONF_STORE:
   			switch(dat1){
   				case 0: printf("Store configuration succesful\n");break;
   				case 1: printf("Store configuration error:not supported\n");break;
   				case 0xFF:printf("Store configuration error:specific error\n");break;
   				default:break;
   			}
   			break;
   		case LSS_CONF_ACT_BIT_TIMING:
   			if(dat1==0){
   				UNS8 LSS_mode=LSS_WAITING_MODE;
				UNS32 SINC_cicle=50000;// us
				UNS32 size = sizeof(UNS32); 
	
				/* The slaves are now configured (nodeId and Baudrate) via the LSS services.
   			 	* Switch the LSS state to WAITING and restart the slaves. */
				
				/*TODO: change the baud rate of the master!!*/
   			 	MasterBoard.baudrate="250K";
   			 	
   			 	
	   			printf("Master : Switch Delay period finished. Switching to LSS WAITING state\n");
   				configNetworkNode(d,LSS_SM_GLOBAL,&LSS_mode,0,NULL);
	   			
   				printf("Master : Restarting all the slaves\n");
   				masterSendNMTstateChange (d, 0x00, NMT_Reset_Comunication);
	   			
   				printf("Master : Starting the SYNC producer\n");
   				writeLocalDict( d, /*CO_Data* d*/
					0x1006, /*UNS16 index*/
					0x00, /*UNS8 subind*/ 
					&SINC_cicle, /*void * pSourceData,*/ 
					&size, /* UNS8 * pExpectedSize*/
					RW);  /* UNS8 checkAccess */
					
				return;
			}
   			else{
   				UNS16 Switch_delay=1;
				UNS8 LSS_mode=LSS_CONFIGURATION_MODE;
				
	   			eprintf("Master : unable to activate bit timing. trying again\n");
				configNetworkNode(d,LSS_CONF_ACT_BIT_TIMING,&Switch_delay,0,CheckLSSAndContinue);
				return;
   			}
   			break;	
		case LSS_SM_SELECTIVE_SERIAL:
   			printf("Slave in LSS CONFIGURATION state\n");
   			break;
   		case LSS_IDENT_REMOTE_SERIAL_HIGH:
   			printf("node identified\n");
   			break;
   		case LSS_IDENT_REMOTE_NON_CONF:
   			if(dat1==0)
   				eprintf("There are no-configured remote slave(s) in the net\n");
   			else
   			{
   				UNS16 Switch_delay=1;
				UNS8 LSS_mode=LSS_CONFIGURATION_MODE;
			
				/*The configuration of the slaves' nodeId ended.
				 * Start the configuration of the baud rate. */
				eprintf("Master : There are not no-configured slaves in the net\n");
				eprintf("Switching all the nodes to LSS CONFIGURATION state\n");
				configNetworkNode(d,LSS_SM_GLOBAL,&LSS_mode,0,NULL);
				eprintf("LSS=>Activate Bit Timing\n");
				configNetworkNode(d,LSS_CONF_ACT_BIT_TIMING,&Switch_delay,0,CheckLSSAndContinue);
				return;
   			}
   			break;
   		case LSS_INQ_VENDOR_ID:
   			printf("Slave VendorID %x\n", dat1);
   			break;
   		case LSS_INQ_PRODUCT_CODE:
   			printf("Slave Product Code %x\n", dat1);
   			break;
   		case LSS_INQ_REV_NUMBER:
   			printf("Slave Revision Number %x\n", dat1);
   			break;
   		case LSS_INQ_SERIAL_NUMBER:
   			printf("Slave Serial Number %x\n", dat1);
   			break;
   		case LSS_INQ_NODE_ID:
   			printf("Slave nodeid %x\n", dat1);
   			break;
#ifdef CO_ENABLE_LSS_FS
   		case LSS_IDENT_FASTSCAN:
   			if(dat1==0)
   				printf("Slave node identified with FastScan\n");
   			else
   			{
   				printf("There is not unconfigured node in the net\n");
   				return;
   			}	
   			init_step_LSS++;
   			break;
#endif	
	
		}
	}

	printf("\n");
	ConfigureLSSNode(d);
}
Пример #3
0
__inline void start_node(CO_Data* d, UNS8 nodeId){
    /* Ask slave node to go in operational mode */
    masterSendNMTstateChange (d, nodeId, NMT_Start_Node);
    d->NMTable[nodeId] = Operational;
}
Пример #4
0
/*!
**
**
** @param d
** @param newState
**
** @return
**/
UNS8 setState(CO_Data* d, e_nodeState newState)
{
	if (newState != d->nodeState) {
		switch ( newState ) {
		case Initialisation: {
			s_state_communication newCommunicationState = {1, 0, 0, 0, 0, 0, 0};
			d->nodeState = Initialisation;
			switchCommunicationState(d, &newCommunicationState);
			/* call user app init callback now. */
			/* d->initialisation MUST NOT CALL SetState */
			(*d->initialisation)(d);
		}

		/* Automatic transition - No break statement ! */
		/* Transition from Initialisation to Pre_operational */
		/* is automatic as defined in DS301. */
		/* App don't have to call SetState(d, Pre_operational) */

		case Pre_operational: {

			s_state_communication newCommunicationState = {0, 1, 1, 1, 1, 0, 1};
			d->nodeState = Pre_operational;
			switchCommunicationState(d, &newCommunicationState);
			if (!(*(d->iam_a_slave))) {
				masterSendNMTstateChange (d, 0, NMT_Reset_Node);
			}
			(*d->preOperational)(d);
		}
		break;

		case Operational:
			if (d->nodeState == Initialisation) return 0xFF;
			{
				s_state_communication newCommunicationState = {0, 1, 1, 1, 1, 1, 0};
				d->nodeState = Operational;
				newState = Operational;
				switchCommunicationState(d, &newCommunicationState);
				(*d->operational)(d);
			}
			break;

		case Stopped:
			if (d->nodeState == Initialisation) return 0xFF;
			{
				s_state_communication newCommunicationState = {0, 0, 0, 0, 1, 0, 1};
				d->nodeState = Stopped;
				newState = Stopped;
				switchCommunicationState(d, &newCommunicationState);
				(*d->stopped)(d);
			}
			break;
		default:
			return 0xFF;

		}/* end switch case */

	}
	/* d->nodeState contains the final state */
	/* may not be the requested state */
	return d->nodeState;
}
Пример #5
0
static void ConfigureSlaveNode(CO_Data* d, UNS8 nodeId)
{
	/* Master configure heartbeat producer time at 0 ms 
	 * for slaves node-id 0x02 and 0x03 by DCF concise */
	 
	UNS8 Transmission_Type = 0x01;
	UNS16 Slave_Prod_Heartbeat_T=1000;//ms
	UNS32 Master_Cons_Heartbeat_Base=0x05DC; //1500ms
	UNS32 abortCode;
	UNS8 res;
	eprintf("Master : ConfigureSlaveNode %2.2x\n", nodeId);

	switch(++init_step[nodeId-2]){
		case 1: /*First step : setup Slave's TPDO 1 to be transmitted on SYNC*/
			eprintf("Master : set slave %2.2x TPDO 1 transmit type\n", nodeId);
			res = writeNetworkDictCallBack (d, /*CO_Data* d*/
					nodeId, /*UNS8 nodeId*/
					0x1800, /*UNS16 index*/
					0x02, /*UNS8 subindex*/
					1, /*UNS8 count*/
					0, /*UNS8 dataType*/
					&Transmission_Type,/*void *data*/
					CheckSDOAndContinue, /*SDOCallback_t Callback*/
                    0); /*UNS8 useBlockMode*/
					break;
		case 2: /* Second step : Set the new heartbeat producer time in the slave */
		{
			UNS32 Master_Cons_Heartbeat_T=Master_Cons_Heartbeat_Base + (nodeId * 0x10000);
			UNS32 size = sizeof(UNS32); 
			
			eprintf("Master : set slave %2.2x Producer Heartbeat Time = %d\n", nodeId,Slave_Prod_Heartbeat_T);
			res = writeNetworkDictCallBack (d, /*CO_Data* d*/
					nodeId, /*UNS8 nodeId*/
					0x1017, /*UNS16 index*/
					0x00, /*UNS8 subindex*/
					2, /*UNS8 count*/
					0, /*UNS8 dataType*/
					&Slave_Prod_Heartbeat_T,/*void *data*/
					CheckSDOAndContinue, /*SDOCallback_t Callback*/
                    0); /*UNS8 useBlockMode*/
					break;
					
			/* Set the new heartbeat consumer time in the master*/
			eprintf("Master : set Consumer Heartbeat Time for slave %2.2x = %d\n", nodeId,Master_Cons_Heartbeat_T);
			writeLocalDict( &TestMaster_Data, /*CO_Data* d*/
				0x1016, /*UNS16 index*/
				nodeId-1, /*UNS8 subind*/ 
				&Master_Cons_Heartbeat_T, /*void * pSourceData,*/ 
				&size, /* UNS8 * pExpectedSize*/
				RW);  /* UNS8 checkAccess */
		}		
		break;
		case 3: 
		
		/****************************** START *******************************/
		
			/* Put the master in operational mode */
			setState(d, Operational);
		 
			/* Ask slave node to go in operational mode */
			masterSendNMTstateChange (d, nodeId, NMT_Start_Node);
	}
}
Пример #6
0
int main(int argc,char **argv)
{

  int c;
  extern char *optarg;
  char* LibraryPath="libcanfestival_can_virtual.so";
  char *snodeid;
  while ((c = getopt(argc, argv, "-m:s:M:S:l:i:")) != EOF)
  {
    switch(c)
    {
      case 'm' :
        if (optarg[0] == 0)
        {
          help();
          exit(1);
        }
        MasterBoard.busname = optarg;
        break;
      case 'M' :
        if (optarg[0] == 0)
        {
          help();
          exit(1);
        }
        MasterBoard.baudrate = optarg;
        break;
      case 'l' :
        if (optarg[0] == 0)
        {
          help();
          exit(1);
        }
        LibraryPath = optarg;
        break;
      case 'i' :
        if (optarg[0] == 0)
        {
          help();
          exit(1);
        }
        snodeid = optarg;
		sscanf(snodeid,"%x",&slavenodeid);
        break;
      default:
        help();
        exit(1);
    }
  }

#if !defined(WIN32) || defined(__CYGWIN__)
  /* install signal handler for manual break */
	signal(SIGTERM, catch_signal);
	signal(SIGINT, catch_signal);
	TimerInit();
#endif

#ifndef NOT_USE_DYNAMIC_LOADING
	LoadCanDriver(LibraryPath);
#endif		

	TestMaster_Data.heartbeatError = TestMaster_heartbeatError;
	TestMaster_Data.initialisation = TestMaster_initialisation;
	TestMaster_Data.preOperational = TestMaster_preOperational;
	TestMaster_Data.operational = TestMaster_operational;
	TestMaster_Data.stopped = TestMaster_stopped;
	TestMaster_Data.post_sync = TestMaster_post_sync;
	TestMaster_Data.post_TPDO = TestMaster_post_TPDO;
	
	if(!canOpen(&MasterBoard,&TestMaster_Data)){
		eprintf("Cannot open Master Board\n");
		goto fail_master;
	}
	
	// Start timer thread
	StartTimerLoop(&InitNodes);

	// wait Ctrl-C
	pause();
	eprintf("Finishing.\n");
	
	// Reset the slave node for next use (will stop emitting heartbeat)
	masterSendNMTstateChange (&TestMaster_Data, slavenodeid, NMT_Reset_Node);
	
	// Stop master
	setState(&TestMaster_Data, Stopped);
	
	// Stop timer thread
	StopTimerLoop(&Exit);
	
fail_master:
	if(MasterBoard.baudrate) canClose(&TestMaster_Data);	

	TimerCleanup();
  	return 0;
}
Пример #7
0
/********************************************************
 * ConfigureSlaveNode is responsible to
 *  - setup slave TPDO 1 transmit time
 *  - setup slave TPDO 2 transmit time
 *  - setup slave Heartbeat Producer time
 *  - switch to operational mode
 *  - send NMT to slave
 ********************************************************
 * This an example of :
 * Network Dictionary Access (SDO) with Callback 
 * Slave node state change request (NMT) 
 ********************************************************
 * This is called first by TestMaster_preOperational
 * then it called again each time a SDO exchange is
 * finished.
 ********************************************************/
static void ConfigureSlaveNode(CO_Data* d, UNS8 nodeId)
{
	UNS8 res;
	eprintf("Master : ConfigureSlaveNode %2.2x\n", nodeId);
	printf("nodeid slave=%x\n",nodeId);
	switch(++init_step){
		case 1: 
		{	/*disable Slave's TPDO 1 */
			UNS32 TPDO_COBId = 0x80000180 + nodeId;
			
			eprintf("Master : disable slave %2.2x TPDO 1 \n", nodeId);
			res = writeNetworkDictCallBack (d, /*CO_Data* d*/
					/**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
					nodeId, /*UNS8 nodeId*/
					0x1800, /*UNS16 index*/
					0x01, /*UNS8 subindex*/
					4, /*UNS8 count*/
					0, /*UNS8 dataType*/
					&TPDO_COBId,/*void *data*/
					CheckSDOAndContinue, /*SDOCallback_t Callback*/
                    0); /* use block mode */
        }			
		break;

		case 2: 
		{	/*setup Slave's TPDO 1 to be transmitted on SYNC*/
			UNS8 Transmission_Type = 0x01;
			
			eprintf("Master : set slave %2.2x TPDO 1 transmit type\n", nodeId);
			res = writeNetworkDictCallBack (d, /*CO_Data* d*/
					/**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
					nodeId, /*UNS8 nodeId*/
					0x1800, /*UNS16 index*/
					0x02, /*UNS8 subindex*/
					1, /*UNS8 count*/
					0, /*UNS8 dataType*/
					&Transmission_Type,/*void *data*/
					CheckSDOAndContinue, /*SDOCallback_t Callback*/
                    0); /* use block mode */
		}			
		break;

		case 3: 
		{	/*re-enable Slave's TPDO 1 */
			UNS32 TPDO_COBId = 0x00000180 + nodeId;
			
			eprintf("Master : re-enable slave %2.2x TPDO 1\n", nodeId);
			res = writeNetworkDictCallBack (d, /*CO_Data* d*/
					/**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
					nodeId, /*UNS8 nodeId*/
					0x1800, /*UNS16 index*/
					0x01, /*UNS8 subindex*/
					4, /*UNS8 count*/
					0, /*UNS8 dataType*/
					&TPDO_COBId,/*void *data*/
					CheckSDOAndContinue, /*SDOCallback_t Callback*/
                    0); /* use block mode */
		}			
		break;
					
		case 4: 
		{	/*disable Slave's TPDO 2 */
			UNS32 TPDO_COBId = 0x80000200 + nodeId;
			
			eprintf("Master : disable slave %2.2x RPDO 1\n", nodeId);
			res = writeNetworkDictCallBack (d, /*CO_Data* d*/
					/**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
					nodeId, /*UNS8 nodeId*/
					0x1400, /*UNS16 index*/
					0x01, /*UNS8 subindex*/
					4, /*UNS8 count*/
					0, /*UNS8 dataType*/
					&TPDO_COBId,/*void *data*/
					CheckSDOAndContinue, /*SDOCallback_t Callback*/
                    0); /* use block mode */
		}			
		break;

					
		case 5:
		{	
			UNS8 Transmission_Type = 0x01;
			
			eprintf("Master : set slave %2.2x RPDO 1 receive type\n", nodeId);
			res = writeNetworkDictCallBack (d, /*CO_Data* d*/
					/**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
					nodeId, /*UNS8 nodeId*/
					0x1400, /*UNS16 index*/
					0x02, /*UNS8 subindex*/
					1, /*UNS8 count*/
					0, /*UNS8 dataType*/
					&Transmission_Type,/*void *data*/
					CheckSDOAndContinue, /*SDOCallback_t Callback*/
                    0); /* use block mode */
		}	
		break;

		case 6: 
		{	/*re-enable Slave's TPDO 1 */
			UNS32 TPDO_COBId = 0x00000200 + nodeId;
			
			eprintf("Master : re-enable %2.2x RPDO 1\n", nodeId);
			res = writeNetworkDictCallBack (d, /*CO_Data* d*/
					/**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
					nodeId, /*UNS8 nodeId*/
					0x1400, /*UNS16 index*/
					0x01, /*UNS8 subindex*/
					4, /*UNS8 count*/
					0, /*UNS8 dataType*/
					&TPDO_COBId,/*void *data*/
					CheckSDOAndContinue, /*SDOCallback_t Callback*/
                    0); /* use block mode */
		}			
		break;
		
		case 7:	
		{
			UNS16 Heartbeat_Producer_Time = 0x03E8; 
			eprintf("Master : set slave %2.2x heartbeat producer time \n", nodeId);
			res = writeNetworkDictCallBack (d, /*CO_Data* d*/
					/**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
					nodeId, /*UNS8 nodeId*/
					0x1017, /*UNS16 index*/
					0x00, /*UNS8 subindex*/
					2, /*UNS8 count*/
					0, /*UNS8 dataType*/
					&Heartbeat_Producer_Time,/*void *data*/
					CheckSDOAndContinue, /*SDOCallback_t Callback*/
                    0); /* use block mode */
		}			
		break;

		case 8: 
		{	/*disable Slave's TPDO 2 */
			UNS32 TPDO_COBId = 0x80000280 + nodeId;
			
			eprintf("Master : disable slave %2.2x TPDO 2 \n", nodeId);
			res = writeNetworkDictCallBack (d, /*CO_Data* d*/
					/**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
					nodeId, /*UNS8 nodeId*/
					0x1801, /*UNS16 index*/
					0x01, /*UNS8 subindex*/
					4, /*UNS8 count*/
					0, /*UNS8 dataType*/
					&TPDO_COBId,/*void *data*/
					CheckSDOAndContinue, /*SDOCallback_t Callback*/
                    0); /* use block mode */
		}			
		break;

		case 9: 
		{	/*disable Slave's TPDO 3 */
			UNS32 TPDO_COBId = 0x80000380 + nodeId;
			
			eprintf("Master : disable slave %2.2x TPDO 3 \n", nodeId);
			res = writeNetworkDictCallBack (d, /*CO_Data* d*/
					/**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
					nodeId, /*UNS8 nodeId*/
					0x1802, /*UNS16 index*/
					0x01, /*UNS8 subindex*/
					4, /*UNS8 count*/
					0, /*UNS8 dataType*/
					&TPDO_COBId,/*void *data*/
					CheckSDOAndContinue, /*SDOCallback_t Callback*/
                    0); /* use block mode */
		}
		break;			

		case 10: 
		{	/*disable Slave's TPDO 2 */
			UNS32 TPDO_COBId = 0x80000480 + nodeId;
			
			eprintf("Master : disable slave %2.2x TPDO 4 \n", nodeId);
			res = writeNetworkDictCallBack (d, /*CO_Data* d*/
					/**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
					nodeId, /*UNS8 nodeId*/
					0x1803, /*UNS16 index*/
					0x01, /*UNS8 subindex*/
					4, /*UNS8 count*/
					0, /*UNS8 dataType*/
					&TPDO_COBId,/*void *data*/
					CheckSDOAndContinue, /*SDOCallback_t Callback*/
                    0); /* use block mode */
		}			
		break;			
		
		case 11:
			/* Put the master in operational mode */
			setState(d, Operational);
			  
			/* Ask slave node to go in operational mode */
			masterSendNMTstateChange (d, nodeId, NMT_Start_Node);
	}
			
}
Пример #8
0
void CANUi::on_pushButton_setNodeState_clicked()
{
    UNS8 id = ui->spinBox_NMTnodeID->value();
    UNS8 state = ui->comboBox_nodeState->currentData().value<UNS8>();
    masterSendNMTstateChange(&master_Data, id, state);
}
Пример #9
0
void can_start_node(uint8_t nodeId)
{
    masterSendNMTstateChange(&Sensor_Board_Data, nodeId, NMT_Start_Node);
}
Пример #10
0
int main(int argc, char *argv[])
  {
   UNS8 node_id = 0;
   s_BOARD MasterBoard = {"1", "125K"};
   char* dll_file_name;

   /* process command line arguments */
   if (argc < 2)
      {
      printf("USAGE: win32test <node_id> [can driver dll filename [baud rate]]\n");
      return 1;
      }

   node_id = atoi(argv[1]);
   if (node_id < 2 || node_id > 127)
      {
      printf("ERROR: node_id shoule be >=2 and <= 127\n");
      return 1;
      }

   if (argc > 2)
      dll_file_name = argv[2];
   else
      dll_file_name = "can_uvccm_win32.dll";

   if (argc > 3)
      MasterBoard.baudrate = argv[3];

   // load can driver
   if (!LoadCanDriver(dll_file_name))
      {
      printf("ERROR: could not load diver %s\n", dll_file_name);
      return 1;
      }
   
   if (canOpen(&MasterBoard,&win32test_Data))
      {
      /* Defining the node Id */
      setNodeId(&win32test_Data, 0x01);

      /* init */
      setState(&win32test_Data, Initialisation);

      /****************************** START *******************************/
      /* Put the master in operational mode */
      setState(&win32test_Data, Operational);

      /* Ask slave node to go in operational mode */
      masterSendNMTstateChange (&win32test_Data, 0, NMT_Start_Node);

      printf("\nStarting node %d (%xh) ...\n",(int)node_id,(int)node_id);
      
      /* wait untill mode will switch to operational state*/
      if (GetChangeStateResults(node_id, Operational, 3000) != 0xFF)
         {
         /* modify Client SDO 1 Parameter */
         UNS32 COB_ID_Client_to_Server_Transmit_SDO = 0x600 + node_id;
         UNS32 COB_ID_Server_to_Client_Receive_SDO  = 0x580 + node_id;
         UNS32 Node_ID_of_the_SDO_Server = node_id;
         UNS8 ExpectedSize = sizeof (UNS32);

         if (OD_SUCCESSFUL ==  writeLocalDict(&win32test_Data, 0x1280, 1, &COB_ID_Client_to_Server_Transmit_SDO, &ExpectedSize, RW) 
              && OD_SUCCESSFUL ==  writeLocalDict(&win32test_Data, 0x1280, 2, &COB_ID_Server_to_Client_Receive_SDO, &ExpectedSize, RW) 
              && OD_SUCCESSFUL ==  writeLocalDict(&win32test_Data, 0x1280, 3, &Node_ID_of_the_SDO_Server, &ExpectedSize, RW))
            {
            UNS32 dev_type = 0;
            char device_name[64]="";
            char hw_ver[64]="";
            char sw_ver[64]="";   
            UNS32 vendor_id = 0;            
            UNS32 prod_code = 0;
            UNS32 ser_num = 0;
            UNS8 size;
            UNS8 res;

            printf("\nnode_id: %d (%xh) info\n",(int)node_id,(int)node_id);
            printf("********************************************\n");

            size = sizeof (dev_type);
            res = ReadSDO(node_id, 0x1000, 0, uint32, &dev_type, &size);
            printf("device type: %d\n",dev_type & 0xFFFF);
           
            size = sizeof (device_name);
            res = ReadSDO(node_id, 0x1008, 0, visible_string, device_name, &size);
            printf("device name: %s\n",device_name);

            size = sizeof (hw_ver);
            res = ReadSDO(node_id, 0x1009, 0, visible_string, hw_ver, &size);
            printf("HW version: %s\n",hw_ver);

            size = sizeof (sw_ver);
            res = ReadSDO(node_id, 0x100A, 0, visible_string, sw_ver, &size);
            printf("SW version: %s\n",sw_ver);            
            
            size = sizeof (vendor_id);
            res = ReadSDO(node_id, 0x1018, 1, uint32, &vendor_id, &size);
            printf("vendor id: %d\n",vendor_id);

            size = sizeof (prod_code);
            res = ReadSDO(node_id, 0x1018, 2, uint32, &prod_code, &size);
            printf("product code: %d\n",prod_code);

            size = sizeof (ser_num);
            res = ReadSDO(node_id, 0x1018, 4, uint32, &ser_num, &size);
            printf("serial number: %d\n",ser_num);
            
            printf("********************************************\n");
            } 
         else
            {
            printf("ERROR: Object dictionary access failed\n");
            }
         }
      else
         {
         printf("ERROR: node_id %d (%xh) is not responding\n",(int)node_id,(int)node_id);
         }
         
      masterSendNMTstateChange (&win32test_Data, 0x02, NMT_Stop_Node);

      setState(&win32test_Data, Stopped);
      
      canClose(&win32test_Data);
      }
   return 0;
  }