# HG changeset patch # User groke6 # Date 1202139644 -3600 # Node ID 854c43cdc24a1245bf313b973d172e28de9c1fc5 # Parent fe47568b82817254c4d995a29128732005b646ae added TestMasterSlaveLSS. LSS protocol revised. diff -r fe47568b8281 -r 854c43cdc24a configure --- a/configure Mon Feb 04 12:06:20 2008 +0100 +++ b/configure Mon Feb 04 16:40:44 2008 +0100 @@ -672,7 +672,8 @@ if [ "$SUB_TARGET" = "unix" ]; then MAKEFILES=$MAKEFILES\ -\ examples/TestMasterSlave/Makefile.in +\ examples/TestMasterSlave/Makefile.in\ +\ examples/TestMasterSlaveLSS/Makefile.in fi if [ "$SUB_TARGET" = "unix" ]; then @@ -683,6 +684,7 @@ if [ "$SUB_TARGET" = "win32" ]; then MAKEFILES=$MAKEFILES\ \ examples/TestMasterSlave/Makefile.in\ +\ examples/TestMasterSlaveLSS/Makefile.in\ \ examples/TestMasterMicroMod/Makefile.in fi diff -r fe47568b8281 -r 854c43cdc24a examples/Makefile.in --- a/examples/Makefile.in Mon Feb 04 12:06:20 2008 +0100 +++ b/examples/Makefile.in Mon Feb 04 16:40:44 2008 +0100 @@ -23,6 +23,7 @@ TARGET = SUB_TARGET WX = SUB_WX +ENABLE_LSS = SUB_ENABLE_LSS ifeq ($(TARGET),win32) BLD_TEST=1 @@ -39,12 +40,21 @@ endif ifdef BLD_TEST +ifeq ($(ENABLE_LSS),1) +define build_command_seq + $(MAKE) -C TestMasterSlave $@ + $(MAKE) -C TestMasterSlaveLSS $@ + $(MAKE) -C TestMasterMicroMod $@ + $(build_command_seq_wx) +endef +else define build_command_seq $(MAKE) -C TestMasterSlave $@ $(MAKE) -C TestMasterMicroMod $@ $(build_command_seq_wx) endef endif +endif ifeq ($(TARGET),hc12) define build_command_seq diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlave/Master.c --- a/examples/TestMasterSlave/Master.c Mon Feb 04 12:06:20 2008 +0100 +++ b/examples/TestMasterSlave/Master.c Mon Feb 04 16:40:44 2008 +0100 @@ -24,6 +24,7 @@ #include "Slave.h" #include "TestMasterSlave.h" +extern s_BOARD MasterBoard; /*****************************************************************************/ void TestMaster_heartbeatError(CO_Data* d, UNS8 heartbeatID) { @@ -61,7 +62,7 @@ &PDO2_COBID, /*void * pSourceData,*/ &size, /* UNS8 * pExpectedSize*/ RW); /* UNS8 checkAccess */ - + } // Step counts number of times ConfigureSlaveNode is called @@ -85,8 +86,8 @@ /******************************************************** * ConfigureSlaveNode is responsible to - * - setup slave TPDO 1 transmit time - * - setup slave TPDO 2 transmit time + * - setup slave TPDO 1 transmit type + * - setup slave TPDO 2 transmit type * - switch to operational mode * - send NMT to slave ******************************************************** @@ -94,7 +95,7 @@ * Network Dictionary Access (SDO) with Callback * Slave node state change request (NMT) ******************************************************** - * This is called first by TestMaster_preOperational + * This is called first by TestMaster_post_SlaveBootup * then it called again each time a SDO exchange is * finished. ********************************************************/ @@ -146,212 +147,10 @@ } } -#ifdef CO_ENABLE_LSS -static void ConfigureLSSNode(CO_Data* d); -// Step counts number of times ConfigureLSSNode is called -UNS8 init_step_LSS=1; - -static void CheckLSSAndContinue(CO_Data* d, UNS8 command) -{ - UNS32 dat1; - UNS8 dat2; - printf("CheckLSS->"); - if(getConfigResultNetworkNode (d, command, &dat1, &dat2) != LSS_FINISHED){ - if(command==LSS_IDENT_REMOTE_NON_CONF){ - eprintf("Master : There are not no-configured slaves in the net\n", command); - return; - } - else{ - 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_SM_SELECTIVE_SERIAL: - printf("Slave in CONFIGURATION mode\n"); - break; - case LSS_IDENT_REMOTE_SERIAL_HIGH: - printf("node identified\n"); - break; - case LSS_IDENT_REMOTE_NON_CONF: - printf("non-configured remote slave in the net\n"); - 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); -} - - -/* First ask if there is a node with an invalid nodeID. - * If FastScan is activated it is used to put the node in the state “configurationâ€?. - * If FastScan is not activated, identification services are used to identify the node. - * Then switch mode service is used to put it in configuration state. - * Next all the inquire and configuration services are used. - * Finally, the node LSS state is restored to “waitingâ€? and all the process is repeated - * again until there isn't any node with a invalid nodeID. - * */ -static void ConfigureLSSNode(CO_Data* d) -{ - UNS32 Vendor_ID=0x12345678; - UNS32 Product_Code=0x90123456; - UNS32 Revision_Number=0x78901234; - UNS32 Serial_Number=0x56789012; - UNS32 Revision_Number_high=0x78901240; - UNS32 Revision_Number_low=0x78901230; - UNS32 Serial_Number_high=0x56789020; - UNS32 Serial_Number_low=0x56789010; - UNS8 NodeID=0x02; - UNS8 Baud_Table=0; - UNS8 Baud_BitTiming=3; - UNS16 Switch_delay=1; - UNS8 LSS_mode=LSS_WAITING_MODE; - UNS8 res; - eprintf("ConfigureLSSNode -> ",0); - - switch(init_step_LSS){ - case 1: /* LSS=>identify non-configured remote slave */ - eprintf("LSS=>identify non-configured remote slave\n"); - res=configNetworkNodeCallBack(&TestMaster_Data,LSS_IDENT_REMOTE_NON_CONF,0,0,CheckLSSAndContinue); - break; -#ifdef CO_ENABLE_LSS_FS - case 2: /* LSS=>FastScan */ - eprintf("LSS=>FastScan\n"); - res=configNetworkNodeCallBack(&TestMaster_Data,LSS_IDENT_FASTSCAN,0,0,CheckLSSAndContinue); - break; -#else - case 2: /* LSS=>identify node */ - eprintf("LSS=>identify node\n"); - res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_VENDOR,&Vendor_ID,0); - res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_PRODUCT,&Product_Code,0); - res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_REV_LOW,&Revision_Number_low,0); - res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_REV_HIGH,&Revision_Number_high,0); - res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_SERIAL_LOW,&Serial_Number_low,0); - res=configNetworkNodeCallBack(&TestMaster_Data,LSS_IDENT_REMOTE_SERIAL_HIGH,&Serial_Number_high,0,CheckLSSAndContinue); - break; - case 3: /*LSS=>put in configuration mode*/ - eprintf("LSS=>put in configuration mode\n"); - res=configNetworkNode(&TestMaster_Data,LSS_SM_SELECTIVE_VENDOR,&Vendor_ID,0); - res=configNetworkNode(&TestMaster_Data,LSS_SM_SELECTIVE_PRODUCT,&Product_Code,0); - res=configNetworkNode(&TestMaster_Data,LSS_SM_SELECTIVE_REVISION,&Revision_Number,0); - res=configNetworkNodeCallBack(&TestMaster_Data,LSS_SM_SELECTIVE_SERIAL,&Serial_Number,0,CheckLSSAndContinue); - break; -#endif - case 4: /* LSS=>inquire nodeID */ - eprintf("LSS=>inquire nodeID\n"); - res=configNetworkNodeCallBack(&TestMaster_Data,LSS_INQ_NODE_ID,0,0,CheckLSSAndContinue); - break; - case 5: /* LSS=>inquire VendorID */ - eprintf("LSS=>inquire VendorID\n"); - res=configNetworkNodeCallBack(&TestMaster_Data,LSS_INQ_VENDOR_ID,0,0,CheckLSSAndContinue); - break; - case 6: /* LSS=>inquire Product code */ - eprintf("LSS=>inquire Product code\n"); - res=configNetworkNodeCallBack(&TestMaster_Data,LSS_INQ_PRODUCT_CODE,0,0,CheckLSSAndContinue); - break; - case 7: /* LSS=>inquire Revision Number */ - eprintf("LSS=>inquire Revision Number\n"); - res=configNetworkNodeCallBack(&TestMaster_Data,LSS_INQ_REV_NUMBER,0,0,CheckLSSAndContinue); - break; - case 8: /* LSS=>inquire Serial Number */ - eprintf("LSS=>inquire Serial Number\n"); - res=configNetworkNodeCallBack(&TestMaster_Data,LSS_INQ_SERIAL_NUMBER,0,0,CheckLSSAndContinue); - break; - case 9: /* LSS=>change the nodeID */ - eprintf("LSS=>change the nodeId\n"); - res=configNetworkNodeCallBack(&TestMaster_Data,LSS_CONF_NODE_ID,&NodeID,0,CheckLSSAndContinue); - break; - case 10: /* LSS=>change the Baud rate */ - eprintf("LSS=>change the Baud rate\n"); - res=configNetworkNodeCallBack(&TestMaster_Data,LSS_CONF_BIT_TIMING,&Baud_Table,&Baud_BitTiming,CheckLSSAndContinue); - break; - case 11: - eprintf("LSS=>Activate Bit Timing\n"); - res=configNetworkNode(&TestMaster_Data,LSS_CONF_ACT_BIT_TIMING,&Switch_delay,0); - /*no break;*/ - init_step_LSS++; - case 12: - /*LSS=>store configuration*/ - /* It will fail the first time (time out) due to the switch delay */ - /* It will fail the second time because it is not implemented in the slave */ - eprintf("LSS=>store configuration\n"); - res=configNetworkNodeCallBack(&TestMaster_Data,LSS_CONF_STORE,0,0,CheckLSSAndContinue); - break; - case 13: /* LSS=>put in operation mod */ - eprintf("LSS=>put in operation mode\n"); - res=configNetworkNode(&TestMaster_Data,LSS_SM_GLOBAL,&LSS_mode,0); - /* Search again for not-configured slaves*/ - eprintf("LSS=>identify not-configured remote slave\n"); - res=configNetworkNodeCallBack(&TestMaster_Data,LSS_IDENT_REMOTE_NON_CONF,0,0,CheckLSSAndContinue); - init_step_LSS=1; - break; - } -} -#endif void TestMaster_preOperational(CO_Data* d) { eprintf("TestMaster_preOperational\n"); -#ifdef CO_ENABLE_LSS - /* Ask slave node to go in stop mode */ - masterSendNMTstateChange (&TestMaster_Data, 0, NMT_Stop_Node); - ConfigureLSSNode(&TestMaster_Data); -#endif } void TestMaster_operational(CO_Data* d) @@ -494,6 +293,5 @@ { eprintf("TestMaster_post_SlaveBootup %x\n", nodeid); - ConfigureSlaveNode(&TestMaster_Data, nodeid); -} - + ConfigureSlaveNode(d, nodeid); +} diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlave/Slave.c --- a/examples/TestMasterSlave/Slave.c Mon Feb 04 12:06:20 2008 +0100 +++ b/examples/TestMasterSlave/Slave.c Mon Feb 04 16:40:44 2008 +0100 @@ -114,15 +114,3 @@ { eprintf("Slave received EMCY message. Node: %2.2x ErrorCode: %4.4x ErrorRegister: %2.2x\n", nodeID, errCode, errReg); } - -void TestSlave_StoreConfiguration(UNS8 *error, UNS8 *spec_error) -{ - printf("TestSlave_StoreConfiguration\n"); -} - -void TestSlave_ChangeBaudRate(char *baudrate) -{ - eprintf("TestSlave_ChangeBaudRate from %s to %s\n", SlaveBoard.baudrate, baudrate); - SlaveBoard.baudrate=baudrate; - /* something to do with the new baudrate */ -} diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlave/Slave.h --- a/examples/TestMasterSlave/Slave.h Mon Feb 04 12:06:20 2008 +0100 +++ b/examples/TestMasterSlave/Slave.h Mon Feb 04 16:40:44 2008 +0100 @@ -13,5 +13,3 @@ void TestSlave_post_TPDO(CO_Data* d); void TestSlave_storeODSubIndex(CO_Data* d, UNS16 wIndex, UNS8 bSubindex); void TestSlave_post_emcy(CO_Data* d, UNS8 nodeID, UNS16 errCode, UNS8 errReg); -void TestSlave_StoreConfiguration(UNS8 *error, UNS8 *spec_error); -void TestSlave_ChangeBaudRate(char *baudrate); diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlave/TestMasterSlave.c --- a/examples/TestMasterSlave/TestMasterSlave.c Mon Feb 04 12:06:20 2008 +0100 +++ b/examples/TestMasterSlave/TestMasterSlave.c Mon Feb 04 16:40:44 2008 +0100 @@ -94,13 +94,7 @@ { /****************************** INITIALISATION SLAVE *******************************/ if(strcmp(SlaveBoard.baudrate, "none")) { - -#ifdef CO_ENABLE_LSS - /* Set an invalid nodeID */ - setNodeId(&TestSlave_Data, 0xFF); -#else setNodeId(&TestSlave_Data, 0x02); -#endif /* init */ setState(&TestSlave_Data, Initialisation); @@ -202,11 +196,6 @@ TestSlave_Data.post_TPDO = TestSlave_post_TPDO; TestSlave_Data.storeODSubIndex = TestSlave_storeODSubIndex; TestSlave_Data.post_emcy = TestSlave_post_emcy; -#ifdef CO_ENABLE_LSS - /* in this example the slave doesn't support Store configuration*/ - //TestSlave_Data.lss_StoreConfiguration = TestSlave_StoreConfiguration; - TestSlave_Data.lss_ChangeBaudRate=TestSlave_ChangeBaudRate; -#endif if(!canOpen(&SlaveBoard,&TestSlave_Data)){ eprintf("Cannot open Slave Board (%s,%s)\n",SlaveBoard.busname, SlaveBoard.baudrate); diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlaveLSS/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlaveLSS/.cvsignore Mon Feb 04 16:40:44 2008 +0100 @@ -0,0 +1,6 @@ +Makefile +TestMasterSlaveLSS +result.txt +TestMasterSlaveLSS.exe +TestMasterSalve.vcproj.KONG.edouard.user +Release diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlaveLSS/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlaveLSS/Makefile.in Mon Feb 04 16:40:44 2008 +0100 @@ -0,0 +1,97 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +CC = SUB_CC +CXX = SUB_CXX +LD = SUB_LD +OPT_CFLAGS = -O2 +CFLAGS = SUB_OPT_CFLAGS +PROG_CFLAGS = SUB_PROG_CFLAGS +EXE_CFLAGS = SUB_EXE_CFLAGS +OS_NAME = SUB_OS_NAME +ARCH_NAME = SUB_ARCH_NAME +PREFIX = SUB_PREFIX +TARGET = SUB_TARGET +CAN_DRIVER = SUB_CAN_DRIVER +TIMERS_DRIVER = SUB_TIMERS_DRIVER +TESTMASTERSLAVELSS = "TestMasterSlaveLSS" + +INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER) -I../../include/$(TIMERS_DRIVER) + +MASTER_OBJS = TestSlaveA.o TestSlaveB.o TestMaster.o TestMasterSlaveLSS.o SlaveA.o SlaveB.o Master.o + +OBJS = $(MASTER_OBJS) ../../src/libcanfestival.a ../../drivers/$(TARGET)/libcanfestival_$(TARGET).a + +ifeq ($(TARGET),win32) + TESTMASTERSLAVELSS = "TestMasterSlaveLSS.exe" +endif + +ifeq ($(TIMERS_DRIVER),timers_win32) + EXE_CFLAGS = +endif + +ifeq ($(TIMERS_DRIVER),timers_xeno) + PROGDEFINES = -DUSE_XENO +endif + +all: $(TESTMASTERSLAVELSS) +../../drivers/$(TARGET)/libcanfestival_$(TARGET).a: + $(MAKE) -C ../../drivers/$(TARGET) libcanfestival_$(TARGET).a + + +$(TESTMASTERSLAVELSS): $(OBJS) + $(LD) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ $(OBJS) $(EXE_CFLAGS) + +TestSlaveA.c: TestSlaveA.od + $(MAKE) -C ../../objdictgen gnosis + python ../../objdictgen/objdictgen.py TestSlaveA.od TestSlaveA.c + +TestSlaveB.c: TestSlaveB.od + $(MAKE) -C ../../objdictgen gnosis + python ../../objdictgen/objdictgen.py TestSlaveB.od TestSlaveB.c + +TestMaster.c: TestMaster.od + $(MAKE) -C ../../objdictgen gnosis + python ../../objdictgen/objdictgen.py TestMaster.od TestMaster.c + +%o: %c + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $< + +clean: + rm -f $(MASTER_OBJS) + rm -f $(TESTMASTERSLAVELSS) + +mrproper: clean + rm -f TestSlaveA.c + rm -f TestSlaveB.c + rm -f TestMaster.c + +install: TestMasterSlaveLSS + mkdir -p $(PREFIX)/bin/ + cp $< $(PREFIX)/bin/ + +uninstall: + rm -f $(PREFIX)/bin/TestMasterSlaveLSS + + + diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlaveLSS/Master.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlaveLSS/Master.c Mon Feb 04 16:40:44 2008 +0100 @@ -0,0 +1,458 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT , Francis DUPIN and Jorge BERZOSA + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "Master.h" +#include "SlaveA.h" +#include "SlaveB.h" +#include "TestMasterSlaveLSS.h" + +extern s_BOARD MasterBoard; + +/*****************************************************************************/ +void TestMaster_heartbeatError(CO_Data* d, UNS8 heartbeatID) +{ + eprintf("TestMaster_heartbeatError %d\n", heartbeatID); +} + +/******************************************************** + * TestMaster_initialisation is responsible to + * - setup master RPDO 1 to receive TPDO 1 from id 2 + * - setup master RPDO 2 to receive TPDO 1 from id 3 + ********************************************************/ +void TestMaster_initialisation(CO_Data* d) +{ + UNS32 PDO1_COBID = 0x0182; + UNS32 PDO2_COBID = 0x0183; + UNS8 size = sizeof(UNS32); + + eprintf("TestMaster_initialisation\n"); + + /***************************************** + * Define RPDO to match slave ID=2 TPDO1* + *****************************************/ + writeLocalDict( &TestMaster_Data, /*CO_Data* d*/ + 0x1400, /*UNS16 index*/ + 0x01, /*UNS8 subind*/ + &PDO1_COBID, /*void * pSourceData,*/ + &size, /* UNS8 * pExpectedSize*/ + RW); /* UNS8 checkAccess */ + + /***************************************** + * Define RPDO to match slave ID=3 TPDO1* + *****************************************/ + writeLocalDict( &TestMaster_Data, /*CO_Data* d*/ + 0x1401, /*UNS16 index*/ + 0x01, /*UNS8 subind*/ + &PDO2_COBID, /*void * pSourceData,*/ + &size, /* UNS8 * pExpectedSize*/ + RW); /* UNS8 checkAccess */ + +} + +// Step counts number of times ConfigureSlaveNode is called +// There is one per each slave +static init_step[] ={0,0}; + +/*Forward declaration*/ +static void ConfigureSlaveNode(CO_Data* d, UNS8 nodeId); + +static void CheckSDOAndContinue(CO_Data* d, UNS8 nodeId) +{ + UNS32 abortCode; + if(getWriteResultNetworkDict (d, nodeId, &abortCode) != SDO_FINISHED) + eprintf("Master : Failed in initializing slave %2.2x, step %d, AbortCode :%4.4x \n", nodeId, init_step, abortCode); + + /* Finalise last SDO transfer with this node */ + closeSDOtransfer(&TestMaster_Data, nodeId, SDO_CLIENT); + + ConfigureSlaveNode(d, nodeId); +} + +/******************************************************** + * ConfigureSlaveNode is responsible to + * - setup slave 'n' TPDO 1 transmit type + * - setup slave 'n' Producer Hertbeat Time + * - setup the Consumer Heartbeat Time for slave 'n' + * - 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_post_SlaveBootup + * after the LSS configuration has been done + * then it called again each time a SDO exchange is + * finished. + ********************************************************/ + +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*/ + 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); + UNS8 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*/ + 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); + } +} + +static void ConfigureLSSNode(CO_Data* d); +// Step counts number of times ConfigureLSSNode is called +UNS8 init_step_LSS=1; + +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 + UNS8 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. */ + + printf("Master : Switch Delay period finished. Switching to LSS WAITING state\n"); + configNetworkNode(&TestMaster_Data,LSS_SM_GLOBAL,&LSS_mode,0,NULL); + + printf("Master : Restarting all the slaves\n"); + masterSendNMTstateChange (&TestMaster_Data, 0x00, NMT_Reset_Node); + + printf("Master : Starting the SYNC producer\n"); + writeLocalDict( &TestMaster_Data, /*CO_Data* d*/ + 0x1006, /*UNS16 index*/ + 0x00, /*UNS8 subind*/ + &SINC_cicle, /*void * pSourceData,*/ + &size, /* UNS8 * pExpectedSize*/ + RW); /* UNS8 checkAccess */ + + return; + } + else{ + printf("Master : unable to activate bit timing. trying again\n"); + init_step_LSS--; + } + 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", command); + eprintf("Switching all the nodes to LSS CONFIGURATION state\n"); + configNetworkNode(&TestMaster_Data,LSS_SM_GLOBAL,&LSS_mode,0,NULL); + eprintf("LSS=>Activate Bit Timing\n"); + configNetworkNode(&TestMaster_Data,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); +} + +/* Initial nodeID and VendorID. They are incremented by one for each slave*/ +UNS8 NodeID=0x02; +UNS32 Vendor_ID=0x12345678; + +/* Configuration of the nodeID and baudrate with LSS services: + * --First ask if there is a node with an invalid nodeID. + * --If FastScan is activated it is used to put the slave in the state “configuration”. + * --If FastScan is not activated, identification services are used to identify the slave. Then + * switch mode service is used to put it in configuration state. + * --Next, all the inquire services are used (only for example) and a valid nodeId and a + * new baudrate are assigned to the slave. + * --Finally, the slave's LSS state is restored to “waiting” and all the process is repeated + * again until there isn't any node with an invalid nodeID. + * --After the configuration of all the slaves finished the LSS state of all of them is switched + * again to "configuration" and the Activate Bit Timing service is requested. On sucessfull, the + * LSS state is restored to "waiting" and NMT state is changed to reset (by means of the NMT services). + * */ +static void ConfigureLSSNode(CO_Data* d) +{ + UNS32 Product_Code=0x90123456; + UNS32 Revision_Number=0x78901234; + UNS32 Serial_Number=0x56789012; + UNS32 Revision_Number_high=0x78901240; + UNS32 Revision_Number_low=0x78901230; + UNS32 Serial_Number_high=0x56789020; + UNS32 Serial_Number_low=0x56789010; + UNS8 LSS_mode=LSS_WAITING_MODE; + UNS8 Baud_Table=0; + UNS8 Baud_BitTiming=3; + UNS8 res; + eprintf("ConfigureLSSNode step %d -> ",init_step_LSS); + + switch(init_step_LSS){ + case 1: /* LSS=>identify non-configured remote slave */ + eprintf("LSS=>identify no-configured remote slave(s)\n"); + res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_NON_CONF,0,0,CheckLSSAndContinue); + break; +#ifdef CO_ENABLE_LSS_FS + case 2: /* LSS=>FastScan */ + eprintf("LSS=>FastScan\n"); + res=configNetworkNode(&TestMaster_Data,LSS_IDENT_FASTSCAN,0,0,CheckLSSAndContinue); + break; +#else + case 2: /* LSS=>identify node */ + eprintf("LSS=>identify node\n"); + res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_VENDOR,&Vendor_ID,0,NULL); + res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_PRODUCT,&Product_Code,0,NULL); + res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_REV_LOW,&Revision_Number_low,0,NULL); + res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_REV_HIGH,&Revision_Number_high,0,NULL); + res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_SERIAL_LOW,&Serial_Number_low,0,NULL); + res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_SERIAL_HIGH,&Serial_Number_high,0,CheckLSSAndContinue); + break; + case 3: /*LSS=>put in configuration mode*/ + eprintf("LSS=>put in configuration mode\n"); + res=configNetworkNode(&TestMaster_Data,LSS_SM_SELECTIVE_VENDOR,&Vendor_ID,0,NULL); + res=configNetworkNode(&TestMaster_Data,LSS_SM_SELECTIVE_PRODUCT,&Product_Code,0,NULL); + res=configNetworkNode(&TestMaster_Data,LSS_SM_SELECTIVE_REVISION,&Revision_Number,0,NULL); + res=configNetworkNode(&TestMaster_Data,LSS_SM_SELECTIVE_SERIAL,&Serial_Number,0,CheckLSSAndContinue); + Vendor_ID++; + break; +#endif + case 4: /* LSS=>inquire nodeID */ + eprintf("LSS=>inquire nodeID\n"); + res=configNetworkNode(&TestMaster_Data,LSS_INQ_NODE_ID,0,0,CheckLSSAndContinue); + break; + case 5: /* LSS=>inquire VendorID */ + eprintf("LSS=>inquire VendorID\n"); + res=configNetworkNode(&TestMaster_Data,LSS_INQ_VENDOR_ID,0,0,CheckLSSAndContinue); + break; + case 6: /* LSS=>inquire Product code */ + eprintf("LSS=>inquire Product code\n"); + res=configNetworkNode(&TestMaster_Data,LSS_INQ_PRODUCT_CODE,0,0,CheckLSSAndContinue); + break; + case 7: /* LSS=>inquire Revision Number */ + eprintf("LSS=>inquire Revision Number\n"); + res=configNetworkNode(&TestMaster_Data,LSS_INQ_REV_NUMBER,0,0,CheckLSSAndContinue); + break; + case 8: /* LSS=>inquire Serial Number */ + eprintf("LSS=>inquire Serial Number\n"); + res=configNetworkNode(&TestMaster_Data,LSS_INQ_SERIAL_NUMBER,0,0,CheckLSSAndContinue); + break; + case 9: /* LSS=>change the nodeID */ + eprintf("LSS=>change the nodeId\n"); + res=configNetworkNode(&TestMaster_Data,LSS_CONF_NODE_ID,&NodeID,0,CheckLSSAndContinue); + NodeID++; + break; + case 10: /* LSS=>change the Baud rate */ + eprintf("LSS=>change the Baud rate\n"); + res=configNetworkNode(&TestMaster_Data,LSS_CONF_BIT_TIMING,&Baud_Table,&Baud_BitTiming,CheckLSSAndContinue); + break; + case 11: + /*LSS=>store configuration*/ + eprintf("LSS=>store configuration\n"); + res=configNetworkNode(&TestMaster_Data,LSS_CONF_STORE,0,0,CheckLSSAndContinue); + break; + case 12: /* LSS=>put in waiting mode */ + eprintf("LSS=>put in waiting mode\n"); + res=configNetworkNode(&TestMaster_Data,LSS_SM_GLOBAL,&LSS_mode,0,NULL); + /* Search again for no-configured slaves*/ + eprintf("LSS=>identify no-configured remote slave(s)\n"); + res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_NON_CONF,0,0,CheckLSSAndContinue); + init_step_LSS=1; + break; + } +} + +void TestMaster_preOperational(CO_Data* d) +{ + eprintf("TestMaster_preOperational\n"); + + /* Ask slaves to go in stop mode */ + masterSendNMTstateChange (d, 0, NMT_Stop_Node); + ConfigureLSSNode(&TestMaster_Data); +} + +void TestMaster_operational(CO_Data* d) +{ + eprintf("TestMaster_operational\n"); +} + +void TestMaster_stopped(CO_Data* d) +{ + eprintf("TestMaster_stopped\n"); +} + +void TestMaster_post_sync(CO_Data* d) +{ + eprintf("TestMaster_post_sync\n"); + eprintf("Master: %d %d %d\n", + MasterMap1, + MasterMap2, + MasterMap3); +} + +void TestMaster_post_emcy(CO_Data* d, UNS8 nodeID, UNS16 errCode, UNS8 errReg) +{ + eprintf("Master received EMCY message. Node: %2.2x ErrorCode: %4.4x ErrorRegister: %2.2x\n", nodeID, errCode, errReg); +} + +void TestMaster_post_TPDO(CO_Data* d) +{ + eprintf("TestMaster_post_TPDO\n"); +} + +void TestMaster_post_SlaveBootup(CO_Data* d, UNS8 nodeid) +{ + eprintf("TestMaster_post_SlaveBootup %x\n", nodeid); + /* Wait until the new baud rate is stored before configure the slaves*/ + if(MasterBoard.baudrate=="250K") + ConfigureSlaveNode(d, nodeid); +} + +void TestMaster_ChangeBaudRate(CO_Data* d, char *baudrate) +{ + eprintf("TestMaster_ChangeBaudRate from %s to %s\n", MasterBoard.baudrate, baudrate); + MasterBoard.baudrate=baudrate; + /* something to do with the new baudrate */ +} diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlaveLSS/Master.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlaveLSS/Master.h Mon Feb 04 16:40:44 2008 +0100 @@ -0,0 +1,16 @@ +#include "TestMaster.h" + +void TestMaster_heartbeatError(CO_Data* d, UNS8); + +UNS8 TestMaster_canSend(Message *); + +void TestMaster_initialisation(CO_Data* d); +void TestMaster_preOperational(CO_Data* d); +void TestMaster_operational(CO_Data* d); +void TestMaster_stopped(CO_Data* d); + +void TestMaster_post_sync(CO_Data* d); +void TestMaster_post_TPDO(CO_Data* d); +void TestMaster_post_emcy(CO_Data* d, UNS8 nodeID, UNS16 errCode, UNS8 errReg); +void TestMaster_post_SlaveBootup(CO_Data* d, UNS8 nodeid); +void TestMaster_ChangeBaudRate(CO_Data* d,char *baudrate); diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlaveLSS/SlaveA.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlaveLSS/SlaveA.c Mon Feb 04 16:40:44 2008 +0100 @@ -0,0 +1,95 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "SlaveA.h" +#include "Master.h" +#include "TestMasterSlaveLSS.h" + +extern s_BOARD SlaveBoardA; +/*****************************************************************************/ +void TestSlaveA_heartbeatError(CO_Data* d, UNS8 heartbeatID) +{ + eprintf("TestSlaveA_heartbeatError %d\n", heartbeatID); +} + +void TestSlaveA_initialisation(CO_Data* d) +{ + eprintf("TestSlaveA_initialisation\n"); +} + +void TestSlaveA_preOperational(CO_Data* d) +{ + eprintf("TestSlaveA_preOperational\n"); +} + +void TestSlaveA_operational(CO_Data* d) +{ + eprintf("TestSlaveA_operational\n"); +} + +void TestSlaveA_stopped(CO_Data* d) +{ + eprintf("TestSlaveA_stopped\n"); +} + +void TestSlaveA_post_sync(CO_Data* d) +{ + eprintf("TestSlaveA_post_sync\n"); +} + +void TestSlaveA_post_TPDO(CO_Data* d) +{ + eprintf("TestSlaveA_post_TPDO\n"); + SlaveAMap1++; + SlaveAMap2+=2; +} + +void TestSlaveA_storeODSubIndex(CO_Data* d, UNS16 wIndex, UNS8 bSubindex) +{ + /*TODO : + * - call getODEntry for index and subindex, + * - save content to file, database, flash, nvram, ... + * + * To ease flash organisation, index of variable to store + * can be established by scanning d->objdict[d->ObjdictSize] + * for variables to store. + * + * */ + eprintf("TestSlaveA_storeODSubIndex : %4.4x %2.2x\n", wIndex, bSubindex); +} + +void TestSlaveA_post_emcy(CO_Data* d, UNS8 nodeID, UNS16 errCode, UNS8 errReg) +{ + eprintf("SlaveA received EMCY message. Node: %2.2x ErrorCode: %4.4x ErrorRegister: %2.2x\n", nodeID, errCode, errReg); +} + +void TestSlaveA_StoreConfiguration(CO_Data* d, UNS8 *error, UNS8 *spec_error) +{ + printf("TestSlaveA_StoreConfiguration\n"); +} + +void TestSlaveA_ChangeBaudRate(CO_Data* d, char *baudrate) +{ + eprintf("TestSlaveA_ChangeBaudRate from %s to %s\n", SlaveBoardA.baudrate, baudrate); + SlaveBoardA.baudrate=baudrate; + /* something to do with the new baudrate */ +} diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlaveLSS/SlaveA.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlaveLSS/SlaveA.h Mon Feb 04 16:40:44 2008 +0100 @@ -0,0 +1,17 @@ +#include "TestSlaveA.h" + +void TestSlaveA_heartbeatError(CO_Data* d, UNS8); + +UNS8 TestSlaveA_canSend(Message *); + +void TestSlaveA_initialisation(CO_Data* d); +void TestSlaveA_preOperational(CO_Data* d); +void TestSlaveA_operational(CO_Data* d); +void TestSlaveA_stopped(CO_Data* d); + +void TestSlaveA_post_sync(CO_Data* d); +void TestSlaveA_post_TPDO(CO_Data* d); +void TestSlaveA_storeODSubIndex(CO_Data* d, UNS16 wIndex, UNS8 bSubindex); +void TestSlaveA_post_emcy(CO_Data* d, UNS8 nodeID, UNS16 errCode, UNS8 errReg); +void TestSlaveA_StoreConfiguration(CO_Data* d, UNS8 *error, UNS8 *spec_error); +void TestSlaveA_ChangeBaudRate(CO_Data* d, char *baudrate); diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlaveLSS/SlaveB.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlaveLSS/SlaveB.c Mon Feb 04 16:40:44 2008 +0100 @@ -0,0 +1,94 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "SlaveB.h" +#include "Master.h" +#include "TestMasterSlaveLSS.h" + +extern s_BOARD SlaveBoardB; +/*****************************************************************************/ +void TestSlaveB_heartbeatError(CO_Data* d, UNS8 heartbeatID) +{ + eprintf("TestSlaveB_heartbeatError %d\n", heartbeatID); +} + +void TestSlaveB_initialisation(CO_Data* d) +{ + eprintf("TestSlaveB_initialisation\n"); +} + +void TestSlaveB_preOperational(CO_Data* d) +{ + eprintf("TestSlaveB_preOperational\n"); +} + +void TestSlaveB_operational(CO_Data* d) +{ + eprintf("TestSlaveB_operational\n"); +} + +void TestSlaveB_stopped(CO_Data* d) +{ + eprintf("TestSlaveB_stopped\n"); +} + +void TestSlaveB_post_sync(CO_Data* d) +{ + eprintf("TestSlaveB_post_sync\n"); +} + +void TestSlaveB_post_TPDO(CO_Data* d) +{ + eprintf("TestSlaveB_post_TPDO\n"); + SlaveBMap1+=16; +} + +void TestSlaveB_storeODSubIndex(CO_Data* d, UNS16 wIndex, UNS8 bSubindex) +{ + /*TODO : + * - call getODEntry for index and subindex, + * - save content to file, database, flash, nvram, ... + * + * To ease flash organisation, index of variable to store + * can be established by scanning d->objdict[d->ObjdictSize] + * for variables to store. + * + * */ + eprintf("TestSlaveB_storeODSubIndex : %4.4x %2.2x\n", wIndex, bSubindex); +} + +void TestSlaveB_post_emcy(CO_Data* d, UNS8 nodeID, UNS16 errCode, UNS8 errReg) +{ + eprintf("SlaveB received EMCY message. Node: %2.2x ErrorCode: %4.4x ErrorRegister: %2.2x\n", nodeID, errCode, errReg); +} + +void TestSlaveB_StoreConfiguration(CO_Data* d, UNS8 *error, UNS8 *spec_error) +{ + printf("TestSlaveB_StoreConfiguration\n"); +} + +void TestSlaveB_ChangeBaudRate(CO_Data* d, char *baudrate) +{ + eprintf("TestSlave2_ChangeBaudRate from %s to %s\n", SlaveBoardB.baudrate, baudrate); + SlaveBoardB.baudrate=baudrate; + /* something to do with the new baudrate */ +} diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlaveLSS/SlaveB.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlaveLSS/SlaveB.h Mon Feb 04 16:40:44 2008 +0100 @@ -0,0 +1,17 @@ +#include "TestSlaveB.h" + +void TestSlaveB_heartbeatError(CO_Data* d, UNS8); + +UNS8 TestSlaveB_canSend(Message *); + +void TestSlaveB_initialisation(CO_Data* d); +void TestSlaveB_preOperational(CO_Data* d); +void TestSlaveB_operational(CO_Data* d); +void TestSlaveB_stopped(CO_Data* d); + +void TestSlaveB_post_sync(CO_Data* d); +void TestSlaveB_post_TPDO(CO_Data* d); +void TestSlaveB_storeODSubIndex(CO_Data* d, UNS16 wIndex, UNS8 bSubindex); +void TestSlaveB_post_emcy(CO_Data* d, UNS8 nodeID, UNS16 errCode, UNS8 errReg); +void TestSlaveB_StoreConfiguration(CO_Data* d, UNS8 *error, UNS8 *spec_error); +void TestSlaveB_ChangeBaudRate(CO_Data* d, char *baudrate); diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlaveLSS/TestMaster.od --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlaveLSS/TestMaster.od Mon Feb 04 16:40:44 2008 +0100 @@ -0,0 +1,5475 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MasterMap1 + + + + + + + MasterMap1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MasterMap2 + + + + + + + MasterMap2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MasterMap3 + + + + + + + MasterMap3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +DS-401 +master + +TestMaster + diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlaveLSS/TestMasterSlaveLSS.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlaveLSS/TestMasterSlaveLSS.c Mon Feb 04 16:40:44 2008 +0100 @@ -0,0 +1,283 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#if defined(WIN32) && !defined(__CYGWIN__) +#include +#include "getopt.h" +void pause(void) +{ + system("PAUSE"); +} +#else +#include +#include +#include +#include +#include +#endif + +#include "canfestival.h" +//#include +//#include + +#include "Master.h" +#include "SlaveA.h" +#include "SlaveB.h" +#include "TestMasterSlaveLSS.h" + +s_BOARD SlaveBoardA = {"0", "125K"}; +s_BOARD SlaveBoardB = {"1", "125K"}; +s_BOARD MasterBoard = {"2", "125K"}; + +#if !defined(WIN32) || defined(__CYGWIN__) +void catch_signal(int sig) +{ + signal(SIGTERM, catch_signal); + signal(SIGINT, catch_signal); + eprintf("Got Signal %d\n",sig); +} +#endif + +void help() +{ + printf("**************************************************************\n"); + printf("* TestMasterSlaveLSS *\n"); + printf("* *\n"); + printf("* A LSS example for PC. It does implement 3 CanOpen *\n"); + printf("* nodes in the same process. A master and 2 slaves. Both *\n"); + printf("* communicate together, exchanging periodically NMT, SYNC, *\n"); + printf("* SDO and PDO. Master configure heartbeat producer time *\n"); + printf("* at 1000 ms for slave node-id 0x02 by concise DCF. *\n"); + printf("* *\n"); + printf("* Usage: *\n"); + printf("* ./TestMasterSlaveLSS [OPTIONS] *\n"); + printf("* *\n"); + printf("* OPTIONS: *\n"); + printf("* -l : Can library [\"libcanfestival_can_virtual.so\"] *\n"); + printf("* *\n"); + printf("* SlaveA: *\n"); + printf("* -s : bus name [\"0\"] *\n"); + printf("* -S : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable) *\n"); + printf("* *\n"); + printf("* Master: *\n"); + printf("* -m : bus name [\"1\"] *\n"); + printf("* -M : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable) *\n"); + printf("* *\n"); + printf("**************************************************************\n"); +} + +/*************************** INIT *****************************************/ +void InitNodes(CO_Data* d, UNS32 id) +{ + /****************************** INITIALISATION SLAVE_A *******************************/ + if(strcmp(SlaveBoardA.baudrate, "none")) { + /* Set an invalid nodeID */ + setNodeId(&TestSlaveA_Data, 0xFF); + + /* init */ + setState(&TestSlaveA_Data, Initialisation); + } + + /****************************** INITIALISATION SLAVE_B *******************************/ + if(strcmp(SlaveBoardB.baudrate, "none")) { + + /* Set an invalid nodeID */ + setNodeId(&TestSlaveB_Data, 0xFF); + + /* init */ + setState(&TestSlaveB_Data, Initialisation); + } + + /****************************** INITIALISATION MASTER *******************************/ + if(strcmp(MasterBoard.baudrate, "none")){ + + /* Defining the node Id */ + setNodeId(&TestMaster_Data, 0x01); + + /* init */ + setState(&TestMaster_Data, Initialisation); + } +} + +/****************************************************************************/ +/*************************** MAIN *****************************************/ +/****************************************************************************/ +int main(int argc,char **argv) +{ + + int c; + extern char *optarg; + char* LibraryPath="../../drivers/can_virtual/libcanfestival_can_virtual.so"; + + while ((c = getopt(argc, argv, "-m:s:M:S:l:")) != EOF) + { + switch(c) + { + case 's' : + if (optarg[0] == 0) + { + help(); + exit(1); + } + SlaveBoardA.busname = optarg; + break; + case 'm' : + if (optarg[0] == 0) + { + help(); + exit(1); + } + MasterBoard.busname = optarg; + break; + case 'S' : + if (optarg[0] == 0) + { + help(); + exit(1); + } + SlaveBoardA.baudrate = 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; + default: + help(); + exit(1); + } + } + +#if !defined(WIN32) || defined(__CYGWIN__) + /* install signal handler for manual break */ + signal(SIGTERM, catch_signal); + signal(SIGINT, catch_signal); +#endif + +#ifndef NOT_USE_DYNAMIC_LOADING + if (LoadCanDriver(LibraryPath) == NULL) + printf("Unable to load library: %s\n",LibraryPath); +#endif + // Open CAN devices + + if(strcmp(SlaveBoardA.baudrate, "none")){ + + TestSlaveA_Data.heartbeatError = TestSlaveA_heartbeatError; + TestSlaveA_Data.initialisation = TestSlaveA_initialisation; + TestSlaveA_Data.preOperational = TestSlaveA_preOperational; + TestSlaveA_Data.operational = TestSlaveA_operational; + TestSlaveA_Data.stopped = TestSlaveA_stopped; + TestSlaveA_Data.post_sync = TestSlaveA_post_sync; + TestSlaveA_Data.post_TPDO = TestSlaveA_post_TPDO; + TestSlaveA_Data.storeODSubIndex = TestSlaveA_storeODSubIndex; + TestSlaveA_Data.post_emcy = TestSlaveA_post_emcy; + /* in this example the slave doesn't support Store configuration*/ + TestSlaveA_Data.lss_StoreConfiguration = TestSlaveA_StoreConfiguration; + TestSlaveA_Data.lss_ChangeBaudRate=TestSlaveA_ChangeBaudRate; + + if(!canOpen(&SlaveBoardA,&TestSlaveA_Data)){ + eprintf("Cannot open SlaveA Board (%s,%s)\n",SlaveBoardA.busname, SlaveBoardA.baudrate); + goto fail_slaveA; + } + } + + if(strcmp(SlaveBoardB.baudrate, "none")){ + + TestSlaveB_Data.heartbeatError = TestSlaveB_heartbeatError; + TestSlaveB_Data.initialisation = TestSlaveB_initialisation; + TestSlaveB_Data.preOperational = TestSlaveB_preOperational; + TestSlaveB_Data.operational = TestSlaveB_operational; + TestSlaveB_Data.stopped = TestSlaveB_stopped; + TestSlaveB_Data.post_sync = TestSlaveB_post_sync; + TestSlaveB_Data.post_TPDO = TestSlaveB_post_TPDO; + TestSlaveB_Data.storeODSubIndex = TestSlaveB_storeODSubIndex; + TestSlaveB_Data.post_emcy = TestSlaveB_post_emcy; + TestSlaveB_Data.lss_StoreConfiguration = TestSlaveB_StoreConfiguration; + TestSlaveB_Data.lss_ChangeBaudRate=TestSlaveB_ChangeBaudRate; + + + if(!canOpen(&SlaveBoardB,&TestSlaveB_Data)){ + eprintf("Cannot open SlaveB Board (%s,%s)\n",SlaveBoardB.busname, SlaveBoardB.baudrate); + goto fail_slaveB; + } + } + + if(strcmp(MasterBoard.baudrate, "none")){ + + 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; + TestMaster_Data.post_emcy = TestMaster_post_emcy; + TestMaster_Data.post_SlaveBootup=TestMaster_post_SlaveBootup; + TestMaster_Data.lss_ChangeBaudRate=TestMaster_ChangeBaudRate; + + if(!canOpen(&MasterBoard,&TestMaster_Data)){ + eprintf("Cannot open Master Board (%s,%s)\n",MasterBoard.busname, MasterBoard.baudrate); + goto fail_master; + } + } + + // Start timer thread + StartTimerLoop(&InitNodes); + + // wait Ctrl-C + + pause(); + + eprintf("Finishing.\n"); + EnterMutex(); + masterSendNMTstateChange (&TestMaster_Data, 0x00, NMT_Stop_Node); + LeaveMutex(); + + eprintf("reset\n"); + // Stop master + EnterMutex(); + setState(&TestMaster_Data, Stopped); + LeaveMutex(); + + // Stop timer thread + StopTimerLoop(); + + // Close CAN devices (and can threads) + if(strcmp(MasterBoard.baudrate, "none")) canClose(&TestMaster_Data); +fail_master: + if(strcmp(SlaveBoardB.baudrate, "none")) canClose(&TestSlaveB_Data); +fail_slaveB: + if(strcmp(SlaveBoardA.baudrate, "none")) canClose(&TestSlaveA_Data); +fail_slaveA: + return 0; +} diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlaveLSS/TestMasterSlaveLSS.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlaveLSS/TestMasterSlaveLSS.h Mon Feb 04 16:40:44 2008 +0100 @@ -0,0 +1,59 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifdef USE_XENO +//#define eprintf(...) if(0){} +#define eprintf(...) +#else +#define eprintf(...) printf (__VA_ARGS__) +#endif + +/*UNS8 canSend(CAN_HANDLE fd0, Message *m);*/ + +#include "canfestival.h" + +/* +#define CAN_FIFO_LENGTH 100 + +#define DECLARE_A_CAN_FIFO \ +static Message FIFO[CAN_FIFO_LENGTH];\ +static int FIFO_First = 0;\ +static int FIFO_Last = 0;\ +\ +static void PutInFIFO(Message *m)\ +{\ + FIFO[FIFO_Last++] = *m;\ + FIFO_Last %= CAN_FIFO_LENGTH;\ +}\ +\ +static void GetFromFIFO(Message *m)\ +{\ + *m = FIFO[FIFO_First++];\ + FIFO_First %= CAN_FIFO_LENGTH;\ +}\ +\ +static void TransmitMessage(CO_Data* d, UNS32 id)\ +{\ + Message m;\ + GetFromFIFO(&m);\ + canDispatch(d, &m);\ +} +*/ diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlaveLSS/TestMasterSlaveLSS.vcproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlaveLSS/TestMasterSlaveLSS.vcproj Mon Feb 04 16:40:44 2008 +0100 @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlaveLSS/TestSlaveA.od --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlaveLSS/TestSlaveA.od Mon Feb 04 16:40:44 2008 +0100 @@ -0,0 +1,334 @@ + + + + + +TestSlaveA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + EVENT + + + + + + + + + 5000*100 µC = 500 ms + + + + + + + + + + + + + + + + + + 1000 ms + + + + + + + + + + + + + + RTR_SYNC + + + + + + + + + + + + + + RTR + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SlaveAMap1 + + + + + + + SlaveAMap1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SlaveAMap2 + + + + + + + SlaveAMap2 + + + + + + + + + + + +slave + + + diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlaveLSS/TestSlaveB.od --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlaveLSS/TestSlaveB.od Mon Feb 04 16:40:44 2008 +0100 @@ -0,0 +1,280 @@ + + + + + +TestSlaveB + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + EVENT + + + + + + + + + 5000*100 µC = 500 ms + + + + + + + + + + + + + + + + + + 1000 ms + + + + + + + + + + + + + + RTR_SYNC + + + + + + + + + + + + + + RTR + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SlaveBMap1 + + + + + + + SlaveBMap1 + + + + + + + + + + + +slave + + + diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlaveLSS/getopt.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlaveLSS/getopt.c Mon Feb 04 16:40:44 2008 +0100 @@ -0,0 +1,1260 @@ +/* from http://www.pwilson.net/getopt.html */ + +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to drepper@gnu.org + before changing it! + Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include +# include +#endif /* GNU C library. */ + +#ifdef VMS +# include +# if HAVE_STRING_H - 0 +# include +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. */ +# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC +# include +# ifndef _ +# define _(msgid) gettext (msgid) +# endif +# else +# define _(msgid) (msgid) +# endif +# if defined _LIBC && defined USE_IN_LIBIO +# include +# endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +# include +# define my_index strchr +#else + +# if HAVE_STRING_H || WIN32 /* Pete Wilson mod 7/28/02 */ +# include +# else +# include +# endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv (); +#endif + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +# if (!defined __STDC__ || !__STDC__) && !defined strlen +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +# endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Stored original parameters. + XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ +extern int __libc_argc; +extern char **__libc_argv; + +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +# ifdef USE_NONOPTION_FLAGS +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; +# endif + +# ifdef USE_NONOPTION_FLAGS +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +# else +# define SWAP_FLAGS(ch1, ch2) +# endif +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +#if defined __STDC__ && __STDC__ +static void exchange (char **); +#endif + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined __STDC__ && __STDC__ +static const char *_getopt_initialize (int, char *const *, const char *); +#endif +static const char * +_getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + if (posixly_correct == NULL + && argc == __libc_argc && argv == __libc_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + int print_errors = opterr; + if (optstring[0] == ':') + print_errors = 0; + + if (argc < 1) + return -1; + + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#if defined _LIBC && defined USE_NONOPTION_FLAGS +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT and LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else if (long_only + || pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + __asprintf (&buf, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); +#else + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); +#endif + } + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; +#endif + + if (argv[optind - 1][1] == '-') + { + /* --option */ +#if defined _LIBC && defined USE_IN_LIBIO + __asprintf (&buf, _("\ +%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); +#else + fprintf (stderr, _("\ +%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); +#endif + } + else + { + /* +option or -option */ +#if defined _LIBC && defined USE_IN_LIBIO + __asprintf (&buf, _("\ +%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], + pfound->name); +#else + fprintf (stderr, _("\ +%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); +#endif + } + +#if defined _LIBC && defined USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); +#endif + } + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + __asprintf (&buf, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); +#else + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); +#endif + } + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; +#endif + + if (argv[optind][1] == '-') + { + /* --option */ +#if defined _LIBC && defined USE_IN_LIBIO + __asprintf (&buf, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); +#else + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); +#endif + } + else + { + /* +option or -option */ +#if defined _LIBC && defined USE_IN_LIBIO + __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); +#else + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); +#endif + } + +#if defined _LIBC && defined USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); +#endif + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; +#endif + + if (posixly_correct) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + __asprintf (&buf, _("%s: illegal option -- %c\n"), + argv[0], c); +#else + fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); +#endif + } + else + { +#if defined _LIBC && defined USE_IN_LIBIO + __asprintf (&buf, _("%s: invalid option -- %c\n"), + argv[0], c); +#else + fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); +#endif + } + +#if defined _LIBC && defined USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); +#endif + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + __asprintf (&buf, _("%s: option requires an argument -- %c\n"), + argv[0], c); + + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); +#else + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); +#endif + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + __asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); +#else + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); +#endif + } + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + __asprintf (&buf, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); +#else + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); +#endif + } + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + __asprintf (&buf, _("\ +%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); +#else + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); +#endif + } + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + __asprintf (&buf, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s", buf); + else + fputs (buf, stderr); + + free (buf); +#else + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); +#endif + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +/* #define TEST */ /* Pete Wilson mod 7/28/02 */ +#ifdef TEST + +#ifndef exit /* Pete Wilson mod 7/28/02 */ + int exit(int); /* Pete Wilson mod 7/28/02 */ +#endif /* Pete Wilson mod 7/28/02 */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff -r fe47568b8281 -r 854c43cdc24a examples/TestMasterSlaveLSS/getopt.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlaveLSS/getopt.h Mon Feb 04 16:40:44 2008 +0100 @@ -0,0 +1,191 @@ +/* from http://www.pwilson.net/getopt.html */ + +/* getopt.h */ +/* Declarations for getopt. + Copyright (C) 1989-1994, 1996-1999, 2001 Free Software + Foundation, Inc. This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute + it and/or modify it under the terms of the GNU Lesser + General Public License as published by the Free Software + Foundation; either version 2.1 of the License, or + (at your option) any later version. + + The GNU C Library is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A + PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with the GNU C Library; if not, write + to the Free Software Foundation, Inc., 59 Temple Place, + Suite 330, Boston, MA 02111-1307 USA. */ + + + + + +#ifndef _GETOPT_H + +#ifndef __need_getopt +# define _GETOPT_H 1 +#endif + +/* If __GNU_LIBRARY__ is not already defined, either we are being used + standalone, or this is the first header included in the source file. + If we are being used with glibc, we need to include , but + that does not exist if we are standalone. So: if __GNU_LIBRARY__ is + not defined, include , which will pull in for us + if it's from glibc. (Why ctype.h? It's guaranteed to exist and it + doesn't flood the namespace with stuff the way some other headers do.) */ +#if !defined __GNU_LIBRARY__ +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +#ifndef __need_getopt +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +# if (defined __STDC__ && __STDC__) || defined __cplusplus + const char *name; +# else + char *name; +# endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +# define no_argument 0 +# define required_argument 1 +# define optional_argument 2 +#endif /* need getopt */ + + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, `optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU `getopt'. + + The argument `--' causes premature termination of argument + scanning, explicitly telling `getopt' that there are no more + options. + + If OPTS begins with `--', then non-option arguments are treated as + arguments to the option '\0'. This behavior is specific to the GNU + `getopt'. */ + +#if (defined __STDC__ && __STDC__) || defined __cplusplus +# ifdef __GNU_LIBRARY__ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int ___argc, char *const *___argv, const char *__shortopts); +# else /* not __GNU_LIBRARY__ */ +extern int getopt (); +# endif /* __GNU_LIBRARY__ */ + +# ifndef __need_getopt +extern int getopt_long (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind); +extern int getopt_long_only (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only); +# endif +#else /* not __STDC__ */ +extern int getopt (); +# ifndef __need_getopt +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +# endif +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +/* Make sure we later can get all the definitions and declarations. */ +#undef __need_getopt + +#endif /* getopt.h */ + diff -r fe47568b8281 -r 854c43cdc24a include/can_driver.h --- a/include/can_driver.h Mon Feb 04 12:06:20 2008 +0100 +++ b/include/can_driver.h Mon Feb 04 16:40:44 2008 +0100 @@ -68,6 +68,14 @@ else printf("EMCY "); break; +#ifdef CO_ENABLE_LSS + case LSS: + if(m->cob_id == 0x7E5) + printf("MLSS "); + else + printf("SLSS "); + break; +#endif _P(TIME_STAMP) _P(PDO1tx) _P(PDO1rx) diff -r fe47568b8281 -r 854c43cdc24a include/data.h --- a/include/data.h Mon Feb 04 12:06:20 2008 +0100 +++ b/include/data.h Mon Feb 04 16:40:44 2008 +0100 @@ -146,28 +146,38 @@ }, #ifdef CO_ENABLE_LSS + +#ifdef CO_ENABLE_LSS_FS +#define lss_fs_Initializer \ + ,0, /* IDNumber */\ + 128, /* BitChecked */\ + 0, /* LSSSub */\ + 0, /* LSSNext */\ + 0, /* LSSPos */\ + LSS_FS_RESET, /* FastScan_SM */\ + -1 /* timerFS */ +#else +#define lss_fs_Initializer +#endif + #define lss_Initializer {\ LSS_RESET, /* state */\ 0, /* command */\ LSS_WAITING_MODE, /* mode */\ 0, /* dat1 */\ 0, /* dat2 */\ - Unknown_state, /* currentState */\ 0, /* NodeID */\ 0, /* addr_sel_match */\ 0, /* addr_ident_match */\ "none", /* BaudRate */\ 0, /* SwitchDelay */\ SDELAY_OFF, /* SwitchDelayState */\ - {-1,-1,-1}, /* Timers[3] */\ + NULL, /* canHandle_t */\ + -1, /* TimerMSG */\ + -1, /* TimerSDELAY */\ NULL, /* Callback */\ - 0, /* LSSanswer */\ - 0, /* IDNumber */\ - 128, /* BitChecked */\ - 0, /* LSSSub */\ - 0, /* LSSNext */\ - 0, /* LSSPos */\ - LSS_FS_RESET /* FastScan_SM */\ + 0 /* LSSanswer */\ + lss_fs_Initializer /*FastScan service initialization */\ },\ NULL, /* _lss_StoreConfiguration*/\ NULL /* _lss_ChangeBaudRate */ @@ -203,7 +213,8 @@ 0, /* csEmergency */\ 0, /* csSYNC */\ 0, /* csHeartbeat */\ - 0 /* csPDO */\ + 0, /* csPDO */\ + 0 /* csLSS */\ },\ _initialisation, /* initialisation */\ _preOperational, /* preOperational */\ diff -r fe47568b8281 -r 854c43cdc24a include/lss.h --- a/include/lss.h Mon Feb 04 12:06:20 2008 +0100 +++ b/include/lss.h Mon Feb 04 16:40:44 2008 +0100 @@ -26,10 +26,6 @@ #define SLSS_ADRESS 0x7E4 #define MLSS_ADRESS 0x7E5 -#define LSS_MSG_TIMER 0 -#define LSS_SWITCH_DELAY_TIMER 1 -#define LSS_FS_TIMER 2 - #define SDELAY_OFF 0 #define SDELAY_FIRST 1 #define SDELAY_SECOND 2 @@ -75,10 +71,10 @@ typedef void (*LSSCallback_t)(CO_Data* d, UNS8 command); -typedef void (*lss_StoreConfiguration_t)(UNS8*,UNS8*); +typedef void (*lss_StoreConfiguration_t)(CO_Data* d,UNS8*,UNS8*); //void _lss_StoreConfiguration(UNS8 *error, UNS8 *spec_error); -typedef void (*lss_ChangeBaudRate_t)(char*); +typedef void (*lss_ChangeBaudRate_t)(CO_Data* d,char*); //void _lss_ChangeBaudRate(char *BaudRate); @@ -98,7 +94,6 @@ UNS32 dat1; /* the data from the last msg received */ UNS8 dat2; - e_nodeState currentState; /* the state of the node before switching to LSSTimingDelay*/ UNS8 nodeID; /* the new nodeid stored to update the nodeid when switching to LSS operational*/ UNS8 addr_sel_match; /* the matching mask for the LSS Switch Mode Selective service */ UNS8 addr_ident_match; /* the matching mask for the LSS Identify Remote Slaves service*/ @@ -107,19 +102,24 @@ * Timing Parameters is received*/ UNS16 switchDelay; /* the period of the two delay */ UNS8 switchDelayState; /* the state machine for the switchDelay */ - - TIMER_HANDLE timers[3]; /* Time counters to implement a timeout in milliseconds. - * LSS_MSG_TIMER (index 0) is automatically incremented whenever + CAN_HANDLE canHandle_t; + + /* Time counters to implement a timeout in milliseconds.*/ + TIMER_HANDLE timerMSG; /* timerMSG is automatically incremented whenever * the lss state is in LSS_TRANS_IN_PROGRESS, and reseted to 0 * when the response LSS have been received. - * LSS_SWITCH_DELAY_TIMER (index 1) is automatically incremented whenever + */ + + TIMER_HANDLE timerSDELAY; /* timerSDELAY is automatically incremented whenever * the lss switchDelayState is in SDELAY_FIRST or SDELAY_SECOND, and reseted to 0 * when the two periods have been expired. */ + LSSCallback_t Callback; /* The user callback func to be called at LSS transaction end */ UNS8 LSSanswer; /* stores if a message has been received during a timer period */ - + +#ifdef CO_ENABLE_LSS_FS UNS32 IDNumber; /* in the master, the LSS address parameter which it currently tries to identify. * in the slave, the LSS address parameter which is being checked (LSS-ID[sub]). */ UNS8 BitChecked; /* bits of the current IDNumber that are currently checked */ @@ -127,6 +127,10 @@ UNS8 LSSNext; /* which LSSSub value will be used in the next request */ UNS8 LSSPos; /* in the slave, which part of the LSS-ID is currently processed*/ UNS8 FastScan_SM; /* the state machine for the FastScan protocol */ + TIMER_HANDLE timerFS; /* timerFS is automatically incremented when the FastScan service + * has been requested and reseted to 0 when the protocol ends. + */ +#endif }; #ifdef CO_ENABLE_LSS @@ -141,7 +145,6 @@ /** transmit a LSS message - * Checks if the msg can be transmited (i.e. we are not in LssTimingDelay state) * command is the LSS command specifier * dat1 and dat2 are pointers to optional data (depend on command) * return sendLSSMessage(d,command,dat1,dat2) @@ -175,7 +178,7 @@ * dat1 and dat2: pointers to optional data (depend on command). * return sendLSS(d,command,dat1,dat2) */ -UNS8 configNetworkNode(CO_Data* d, UNS8 command, void *dat1, void* dat2); +//UNS8 configNetworkNode(CO_Data* d, UNS8 command, void *dat1, void* dat2); /** Used by the Master application to send a LSS command, WITH response, to the slave. * The function Callback, which must be defined in the user code, is called at the @@ -183,7 +186,7 @@ * The LSS_MSG_TIMER timer is started to control the timeout * return sendLSS(d,command,dat1,dat2) */ -UNS8 configNetworkNodeCallBack (CO_Data* d, UNS8 command, void *dat1, void* dat2, LSSCallback_t Callback); +UNS8 configNetworkNode (CO_Data* d, UNS8 command, void *dat1, void* dat2, LSSCallback_t Callback); /** Use this function after a configNetworkNode or configNetworkNodeCallBack to get the result. Returns : LSS_RESET // Transmission not started. Init state. diff -r fe47568b8281 -r 854c43cdc24a include/states.h --- a/include/states.h Mon Feb 04 12:06:20 2008 +0100 +++ b/include/states.h Mon Feb 04 16:40:44 2008 +0100 @@ -41,9 +41,6 @@ Operational = 0x05, Pre_operational = 0x7F, Unknown_state = 0x0F -#ifdef CO_ENABLE_LSS - ,LssTimingDelay = 0x10 -#endif }; typedef enum enum_nodeState e_nodeState; diff -r fe47568b8281 -r 854c43cdc24a src/lss.c --- a/src/lss.c Mon Feb 04 12:06:20 2008 +0100 +++ b/src/lss.c Mon Feb 04 16:40:44 2008 +0100 @@ -62,183 +62,215 @@ #define getLSSNext(msg) msg->data[7] /* Prototypes for internals functions */ -void LssAlarm(CO_Data* d, UNS32 id); - -#define StopLSS_TIMER(id){\ - MSG_WAR(0x3D01, "StopLSS_TIMER for timer : ", id);\ - d->lss_transfer.timers[id] = DelAlarm(d->lss_transfer.timers[id]);} +UNS8 sendMasterLSSMessage(CO_Data* d, UNS8 command,void *dat1,void *dat2); +void LssAlarmMSG(CO_Data* d, UNS32 id); +void LssAlarmSDELAY(CO_Data* d, UNS32 id); + + +#define StopLSS_MSG_TIMER(){\ + MSG_WAR(0x3D01, "StopLSS_MSG_TIMER", 0);\ + d->lss_transfer.timerMSG = DelAlarm(d->lss_transfer.timerMSG);} #define StartLSS_MSG_TIMER(){\ - MSG_WAR(0x3D02, "StartLSS_TIMER for MSG_TIMER",0);\ - d->lss_transfer.timers[LSS_MSG_TIMER] = SetAlarm(d,LSS_MSG_TIMER,&LssAlarm,MS_TO_TIMEVAL(LSS_TIMEOUT_MS),0);} + MSG_WAR(0x3D02, "StartLSS_MSG_TIMER",0);\ + d->lss_transfer.timerMSG = SetAlarm(d,0,&LssAlarmMSG,MS_TO_TIMEVAL(LSS_TIMEOUT_MS),0);} + +#define StopLSS_SDELAY_TIMER(){\ + MSG_WAR(0x3D03, "StopLSS_SDELAY_TIMER", 0);\ + d->lss_transfer.timerSDELAY = DelAlarm(d->lss_transfer.timerSDELAY);} #define StartLSS_SDELAY_TIMER(){\ - MSG_WAR(0x3D03, "StartLSS_TIMER for SDELAY_TIMER",0);\ - d->lss_transfer.timers[LSS_SWITCH_DELAY_TIMER] = SetAlarm(d,LSS_SWITCH_DELAY_TIMER,&LssAlarm,MS_TO_TIMEVAL(d->lss_transfer.switchDelay),MS_TO_TIMEVAL(d->lss_transfer.switchDelay));} + MSG_WAR(0x3D04, "StartLSS_SDELAY_TIMER",0);\ + d->lss_transfer.timerSDELAY= SetAlarm(d,0,&LssAlarmSDELAY,MS_TO_TIMEVAL(d->lss_transfer.switchDelay),MS_TO_TIMEVAL(d->lss_transfer.switchDelay));} + + +#ifdef CO_ENABLE_LSS_FS +/* Prototypes for internals functions */ +void LssAlarmFS(CO_Data* d, UNS32 id); + +#define StopLSS_FS_TIMER(){\ + MSG_WAR(0x3D05, "StopLSS_FS_TIMER", id);\ + d->lss_transfer.timerFS = DelAlarm(d->lss_transfer.timerFS);} #define StartLSS_FS_TIMER(){\ - MSG_WAR(0x3D04, "StartLSS_TIMER for FS_TIMER",0);\ - d->lss_transfer.timers[LSS_FS_TIMER] = SetAlarm(d,LSS_FS_TIMER,&LssAlarm,MS_TO_TIMEVAL(LSS_FS_TIMEOUT_MS),0);} - -UNS8 sendMasterLSSMessage(CO_Data* d, UNS8 command,void *dat1,void *dat2); - + MSG_WAR(0x3D06, "StartLSS_FS_TIMER",0);\ + d->lss_transfer.timerFS = SetAlarm(d,0,&LssAlarmFS,MS_TO_TIMEVAL(LSS_FS_TIMEOUT_MS),0);} +#endif + + +void LssAlarmMSG(CO_Data* d, UNS32 id) +{ + StopLSS_MSG_TIMER(); +#ifdef CO_ENABLE_LSS_FS + if(d->lss_transfer.command==LSS_IDENT_FASTSCAN){ + if(d->lss_transfer.FastScan_SM==LSS_FS_RESET){ + /* if at least one node had answered before the timer expired, start the FastScan protocol*/ + if(d->lss_transfer.LSSanswer!=0){ + d->lss_transfer.LSSanswer=0; + d->lss_transfer.BitChecked=31; + d->lss_transfer.IDNumber=0; + d->lss_transfer.FastScan_SM=LSS_FS_PROCESSING; + StartLSS_FS_TIMER(); + sendMasterLSSMessage(d,LSS_IDENT_FASTSCAN,0,0); + return; + } + else{ + + d->lss_transfer.state = LSS_FINISHED; + /* Inform the application that there aren't not configured nodes in the net */ + d->lss_transfer.dat1=1; + } + } + else{ + /* This should not happen, an error ocurred*/ + MSG_ERR(0x1D07, "LSS FastScan timeout. FastScan_SM inconsisten state.", d->lss_transfer.FastScan_SM); + } + } + else +#endif + if(d->lss_transfer.command==LSS_IDENT_REMOTE_NON_CONF){ + MSG_WAR(0x2D08, "LSS timeout. There are not no-configured slaves in the net", 0); + d->lss_transfer.state = LSS_FINISHED; + d->lss_transfer.dat1=1; + } + else{ + MSG_ERR(0x1D09, "LSS timeout. LSS response not received.", 0); + MSG_WAR(0x2D0A, "LSS timeout command specifier : ", d->lss_transfer.command); + /* Set aborted state */ + d->lss_transfer.state = LSS_ABORTED_INTERNAL; + } + + /* Call the user function to inform of the problem.*/ + if(d->lss_transfer.Callback){ + /*If there is a callback, it is responsible of the error*/ + (*d->lss_transfer.Callback)(d,d->lss_transfer.command); + } +} + + /*! ** ** ** @param d ** @param id **/ -//struct timeval current_time,init_time; -void LssAlarm(CO_Data* d, UNS32 id) +void LssAlarmSDELAY(CO_Data* d, UNS32 id) { - /*unsigned long time_period; - - gettimeofday(¤t_time,NULL); - time_period=(current_time.tv_sec - init_time.tv_sec)* 1000000 + current_time.tv_usec - init_time.tv_usec; - printf("%3ld.%3ld.%3ld --",time_period/1000000,(time_period%1000000)/1000,time_period%1000);*/ - - switch(id){ - case LSS_MSG_TIMER: - StopLSS_TIMER(LSS_MSG_TIMER); + + /* The first switch_delay period expired. Store the node state, change it + * so no CAN messages will be sent or received, call the ChangeBaudRate function*/ + if(d->lss_transfer.switchDelayState==SDELAY_FIRST){ + MSG_WAR(0x3D0B, "LSS switch delay first period expired",0); + d->lss_transfer.switchDelayState=SDELAY_SECOND; + (*d->lss_ChangeBaudRate)(d,d->lss_transfer.baudRate); + } + else{ /* d->lss_transfer.switchDelayState==SDELAY_SECOND */ + MSG_WAR(0x3D0C, "LSS switch delay second period expired",0); + d->lss_transfer.switchDelayState=SDELAY_OFF; + StopLSS_SDELAY_TIMER(); + + if (*(d->iam_a_slave)) + d->canHandle=d->lss_transfer.canHandle_t; + else{ + d->lss_transfer.dat1=0; + d->lss_transfer.state=LSS_FINISHED; + /* Call the user function */ + if(d->lss_transfer.Callback){ + (*d->lss_transfer.Callback)(d,d->lss_transfer.command); + } + } + } +} + #ifdef CO_ENABLE_LSS_FS - if(d->lss_transfer.command==LSS_IDENT_FASTSCAN){ - if(d->lss_transfer.FastScan_SM==LSS_FS_RESET){ - /* if at least one node had answered before the timer expired, start the FastScan protocol*/ - if(d->lss_transfer.LSSanswer!=0){ - d->lss_transfer.LSSanswer=0; - d->lss_transfer.BitChecked=31; - d->lss_transfer.IDNumber=0; - d->lss_transfer.FastScan_SM=LSS_FS_PROCESSING; - StartLSS_FS_TIMER(); - sendMasterLSSMessage(d,LSS_IDENT_FASTSCAN,0,0); - return; - } - else{ - - d->lss_transfer.state = LSS_FINISHED; - /* Inform the application that there aren't not configured nodes in the net */ - d->lss_transfer.dat1=1; - } - } - else{ - /* This should not happen, an error ocurred*/ - MSG_ERR(0x1D05, "LSS FastScan timeout. FastScan_SM inconsisten state.", d->lss_transfer.FastScan_SM); - } - } - else +/*! +** +** +** @param d +** @param id +**/ +void LssAlarmFS(CO_Data* d, UNS32 id) +{ + StopLSS_FS_TIMER(); + + switch(d->lss_transfer.FastScan_SM){ + case LSS_FS_RESET: + { + /* This should not happen, an error ocurred*/ + MSG_ERR(0x1D0D, "LSS FastScan timeout. FastScan_SM inconsisten state.", d->lss_transfer.FastScan_SM); + } + break; + case LSS_FS_PROCESSING: + { + /* If there isn't any answer, set the bit */ + if(d->lss_transfer.LSSanswer==0){ + UNS32 Mask=0x1; + Mask<<=d->lss_transfer.BitChecked; + d->lss_transfer.IDNumber|=Mask; + } + + if(d->lss_transfer.BitChecked==0){ + /* We finished with the current LSS-ID[sub], confirm it */ + d->lss_transfer.FastScan_SM=LSS_FS_CONFIRMATION; + if(d->lss_transfer.LSSNext<3)d->lss_transfer.LSSNext++; + } + else{ + d->lss_transfer.BitChecked--; + } + + d->lss_transfer.LSSanswer=0; + StartLSS_FS_TIMER(); + sendMasterLSSMessage(d,LSS_IDENT_FASTSCAN,0,0); + return; + } + break; + case LSS_FS_CONFIRMATION: + { + if(d->lss_transfer.LSSanswer!=0){ + d->lss_transfer.LSSanswer=0; + + if(d->lss_transfer.LSSSub==3){ + /* The LSS FastScan protocol finished correctly. Restore the parameters */ + d->lss_transfer.BitChecked=128; + d->lss_transfer.FastScan_SM=LSS_FS_RESET; + d->lss_transfer.LSSSub=0; + d->lss_transfer.LSSNext=0; + d->lss_transfer.IDNumber=0; + + /* Inform the application that the FastScan finished correctly */ + d->lss_transfer.state = LSS_FINISHED; + d->lss_transfer.dat1=0; + } + else{ + /* Start with the next LSS-ID[sub] */ + d->lss_transfer.LSSSub++; + d->lss_transfer.BitChecked=31; + d->lss_transfer.IDNumber=0; + d->lss_transfer.FastScan_SM=LSS_FS_PROCESSING; + StartLSS_FS_TIMER(); + sendMasterLSSMessage(d,LSS_IDENT_FASTSCAN,0,0); + return; + } + } + else{ + /* This should not happen, an error ocurred*/ + MSG_ERR(0x1D0E, "LSS FastScan timeout. FastScan response not received.", 0); + /* Set aborted state */ + d->lss_transfer.state = LSS_ABORTED_INTERNAL; + } + } + break; + } + + /* Call the user function to inform of the problem.*/ + if(d->lss_transfer.Callback){ + /*If there is a callback, it is responsible of the error*/ + (*d->lss_transfer.Callback)(d,d->lss_transfer.command); + } +} #endif - { - MSG_ERR(0x1D06, "LSS timeout. LSS response not received.", 0); - MSG_WAR(0x2D07, "LSS timeout command specifier : ", d->lss_transfer.command); - /* Set aborted state */ - d->lss_transfer.state = LSS_ABORTED_INTERNAL; - } - - /* Call the user function to inform of the problem.*/ - if(d->lss_transfer.Callback){ - /*If there is a callback, it is responsible of the error*/ - (*d->lss_transfer.Callback)(d,d->lss_transfer.command); - } - break; - case LSS_SWITCH_DELAY_TIMER: - /* The first switch_delay period expired. Store the node state, change it - * so no CAN messages will be sent or received, call the ChangeBaudRate function*/ - if(d->lss_transfer.switchDelayState==SDELAY_FIRST){ - MSG_WAR(0x3D08, "LSS switch delay first period expired",0); - d->lss_transfer.switchDelayState=SDELAY_SECOND; - (*d->lss_ChangeBaudRate)(d->lss_transfer.baudRate); - } - else{ /* d->lss_transfer.switchDelayState==SDELAY_SECOND */ - MSG_WAR(0x3D09, "LSS switch delay second period expired",0); - d->lss_transfer.switchDelayState=SDELAY_OFF; - StopLSS_TIMER(LSS_SWITCH_DELAY_TIMER); - - setState(d, d->lss_transfer.currentState); - } - break; -#ifdef CO_ENABLE_LSS_FS - case LSS_FS_TIMER: - StopLSS_TIMER(LSS_FS_TIMER); - - switch(d->lss_transfer.FastScan_SM){ - case LSS_FS_RESET: - { - /* This should not happen, an error ocurred*/ - MSG_ERR(0x1D0A, "LSS FastScan timeout. FastScan_SM inconsisten state.", d->lss_transfer.FastScan_SM); - } - break; - case LSS_FS_PROCESSING: - { - /* If there isn't any answer, set the bit */ - if(d->lss_transfer.LSSanswer==0){ - UNS32 Mask=0x1; - Mask<<=d->lss_transfer.BitChecked; - d->lss_transfer.IDNumber|=Mask; - } - - if(d->lss_transfer.BitChecked==0){ - /* We finished with the current LSS-ID[sub], confirm it */ - d->lss_transfer.FastScan_SM=LSS_FS_CONFIRMATION; - if(d->lss_transfer.LSSNext<3)d->lss_transfer.LSSNext++; - } - else{ - d->lss_transfer.BitChecked--; - } - - d->lss_transfer.LSSanswer=0; - StartLSS_FS_TIMER(); - sendMasterLSSMessage(d,LSS_IDENT_FASTSCAN,0,0); - return; - } - break; - case LSS_FS_CONFIRMATION: - { - if(d->lss_transfer.LSSanswer!=0){ - d->lss_transfer.LSSanswer=0; - - if(d->lss_transfer.LSSSub==3){ - /* The LSS FastScan protocol finished correctly. Restore the parameters */ - d->lss_transfer.BitChecked=128; - d->lss_transfer.FastScan_SM=LSS_FS_RESET; - d->lss_transfer.LSSSub=0; - d->lss_transfer.LSSNext=0; - d->lss_transfer.IDNumber=0; - - /* Inform the application that the FastScan finished correctly */ - d->lss_transfer.state = LSS_FINISHED; - d->lss_transfer.dat1=0; - } - else{ - /* Start with the next LSS-ID[sub] */ - d->lss_transfer.LSSSub++; - d->lss_transfer.BitChecked=31; - d->lss_transfer.IDNumber=0; - d->lss_transfer.FastScan_SM=LSS_FS_PROCESSING; - StartLSS_FS_TIMER(); - sendMasterLSSMessage(d,LSS_IDENT_FASTSCAN,0,0); - return; - } - } - else{ - /* This should not happen, an error ocurred*/ - MSG_ERR(0x1D0B, "LSS FastScan timeout. FastScan response not received.", 0); - /* Set aborted state */ - d->lss_transfer.state = LSS_ABORTED_INTERNAL; - } - } - break; - } - - /* Call the user function to inform of the problem.*/ - if(d->lss_transfer.Callback){ - /*If there is a callback, it is responsible of the error*/ - (*d->lss_transfer.Callback)(d,d->lss_transfer.command); - } - break; -#endif - } -} - + + /*! ** ** @@ -273,7 +305,7 @@ UNS8 i; if (!d->CurrentCommunicationState.csLSS){ - MSG_WAR(0x2D0C, "unable to send the LSS message, not in the proper state =>", d->nodeState); + MSG_WAR(0x2D17, "unable to send the LSS message, not in the proper state =>", d->nodeState); return 0xFF; } @@ -308,7 +340,7 @@ case LSS_IDENT_NON_CONF_SLAVE: /* LSS identify non-configured remote slave */ break; default: - MSG_ERR(0x1D0D, "send Slave LSS command not implemented", command); + MSG_ERR(0x1D18, "send Slave LSS command not implemented", command); return 0xFF; } @@ -327,7 +359,9 @@ { Message m; UNS8 i; - + UNS8 res; + UNS8 hasResponse=0; + for(i=1;i<8;i++)m.data[i]=0; m.len = 8; m.rtr = NOT_A_REQUEST; @@ -336,34 +370,87 @@ /* Tha data sent with the msg depends on the command */ switch(command){ + case LSS_CONF_NODE_ID: /* Configure Node-ID */ + hasResponse=1; case LSS_SM_GLOBAL: /* Switch Mode Global */ - d->lss_transfer.state=LSS_FINISHED; - case LSS_CONF_NODE_ID: /* Configure Node-ID */ m.data[1]=*(UNS8 *)dat1; break; case LSS_CONF_BIT_TIMING: /* Configure Bit Timing Parameters */ m.data[1]=*(UNS8 *)dat1; m.data[2]=*(UNS8 *)dat2; + if(d->lss_ChangeBaudRate){ + /* If a baud rate is not supported just comment the line. */ + switch(m.data[2]){ + case 0x00:d->lss_transfer.baudRate="1M";break; + case 0x01:d->lss_transfer.baudRate="800K";break; + case 0x02:d->lss_transfer.baudRate="500K";break; + case 0x03:d->lss_transfer.baudRate="250K";break; + case 0x04:d->lss_transfer.baudRate="125K";break; + case 0x05:d->lss_transfer.baudRate="100K";break; + case 0x06:d->lss_transfer.baudRate="50K";break; + case 0x07:d->lss_transfer.baudRate="20K";break; + case 0x08:d->lss_transfer.baudRate="10K";break; + default: + MSG_ERR(0x1D19, "Master-> Baud rate not supported",0); + d->lss_transfer.dat1=0xFF; + goto ErrorBitRateMaster; + break; + } + hasResponse=1; + break; + } + else{ + MSG_ERR(0x1D1A, "Master-> Bit timing not supported",0); + d->lss_transfer.dat1=0x01; + } + +ErrorBitRateMaster: + d->lss_transfer.dat2=0; + /* If there is a callback, it is responsible of the error */ + if(d->lss_transfer.Callback) + (*d->lss_transfer.Callback)(d,d->lss_transfer.command); + return 0xFF; break; case LSS_CONF_ACT_BIT_TIMING: /* Activate Bit Timing Parameters */ m.data[1]=(UNS8)(*(UNS32*)dat1 & 0xFF); m.data[2]=(UNS8)(*(UNS32*)dat1>>8 & 0xFF); + if(d->lss_transfer.baudRate!="none"){ + d->lss_transfer.switchDelay=(UNS16)(*(UNS32*)dat1 & 0xFFFF); + d->lss_transfer.switchDelayState=SDELAY_FIRST; + res=canSend(d->canHandle,&m); + if(res==0){ + StartLSS_SDELAY_TIMER(); + d->lss_transfer.state=LSS_TRANS_IN_PROGRESS; + } + return res; + } + else{ + MSG_ERR(0x1D1B, "Master-> Baud rate not specified",0); + d->lss_transfer.dat1=1; + /* If there is a callback, it is responsible of the error */ + if(d->lss_transfer.Callback){ + (*d->lss_transfer.Callback)(d,d->lss_transfer.command); + } + return 0xFF; + } break; + case LSS_SM_SELECTIVE_SERIAL: + case LSS_IDENT_REMOTE_SERIAL_HIGH: + hasResponse=1; case LSS_SM_SELECTIVE_VENDOR: /* Switch Mode Selective */ case LSS_SM_SELECTIVE_PRODUCT: case LSS_SM_SELECTIVE_REVISION: - case LSS_SM_SELECTIVE_SERIAL: case LSS_IDENT_REMOTE_VENDOR: /* LSS Identify Remote Slaves */ case LSS_IDENT_REMOTE_PRODUCT: case LSS_IDENT_REMOTE_REV_LOW: case LSS_IDENT_REMOTE_REV_HIGH: case LSS_IDENT_REMOTE_SERIAL_LOW: - case LSS_IDENT_REMOTE_SERIAL_HIGH: m.data[1]=(UNS8)(*(UNS32*)dat1 & 0xFF); m.data[2]=(UNS8)(*(UNS32*)dat1>>8 & 0xFF); m.data[3]=(UNS8)(*(UNS32*)dat1>>16 & 0xFF); m.data[4]=(UNS8)(*(UNS32*)dat1>>24 & 0xFF); break; + case LSS_CONF_STORE: /* Store Configured Parameters */ case LSS_IDENT_REMOTE_NON_CONF: /* LSS identify non-configured remote slave */ case LSS_INQ_VENDOR_ID: /* Inquire Identity Vendor-ID */ @@ -371,6 +458,7 @@ case LSS_INQ_REV_NUMBER: /* Inquire Identity Revision-Number */ case LSS_INQ_SERIAL_NUMBER: /* Inquire Identity Serial-Number */ case LSS_INQ_NODE_ID: /* Inquire Node-ID */ + hasResponse=1; break; #ifdef CO_ENABLE_LSS_FS case LSS_IDENT_FASTSCAN: @@ -381,14 +469,21 @@ m.data[5]=d->lss_transfer.BitChecked; m.data[6]=d->lss_transfer.LSSSub; m.data[7]=d->lss_transfer.LSSNext; + /* it will generate a response only if it is the start of the FastScan protocol*/ + if(d->lss_transfer.FastScan_SM==LSS_FS_RESET)hasResponse=1; break; #endif default: - MSG_ERR(0x1D0E, "send Master LSS command not implemented", command); + MSG_ERR(0x1D1C, "send Master LSS command not implemented", command); return 0xFF; } - return canSend(d->canHandle,&m); + res=canSend(d->canHandle,&m); + if(res==0 && hasResponse==1){ + StartLSS_MSG_TIMER(); + d->lss_transfer.state=LSS_TRANS_IN_PROGRESS; + } + return res; } /*! @@ -435,16 +530,7 @@ goto ErrorProcessMaster; } - //#ifdef CO_ENABLE_LSS_FS - /* The FastScan protocol doesn't stops the timers when a message has been received */ - /*if(d->lss_transfer.command!=LSS_IDENT_FASTSCAN) -#endif - { - StopLSS_TIMER(LSS_MSG_TIMER); - d->lss_transfer.state = LSS_FINISHED; - }*/ - - MSG_WAR(0x3D0F, "MasterLSS proceedLSS; command ", m->data[0]); + MSG_WAR(0x3D1E, "MasterLSS proceedLSS; command ", m->data[0]); switch(msg_cs=m->data[0]){ case LSS_INQ_NODE_ID: /* Inquire Node-ID */ @@ -493,11 +579,11 @@ if(d->lss_transfer.command!=LSS_IDENT_REMOTE_NON_CONF)goto ErrorProcessMaster; break; default: - MSG_ERR(0x1D10, "Master LSS command not implemented", msg_cs); + MSG_ERR(0x1D1F, "Master LSS command not implemented", msg_cs); return 0xFF; } - StopLSS_TIMER(LSS_MSG_TIMER); + StopLSS_MSG_TIMER(); d->lss_transfer.state = LSS_FINISHED; d->lss_transfer.dat1=Dat1; @@ -509,7 +595,7 @@ return 0; ErrorProcessMaster: - MSG_WAR(0x3D11, "MasterLSS proceedLSS; unexpected message arrived;command ", m->data[0]); + MSG_WAR(0x3D20, "MasterLSS proceedLSS; unexpected message arrived;command ", m->data[0]); return 0xFF; } @@ -526,32 +612,35 @@ { UNS8 msg_cs; - MSG_WAR(0x3D12, "SlaveLSS proceedLSS; command ", m->data[0]); + MSG_WAR(0x3D21, "SlaveLSS proceedLSS; command ", m->data[0]); switch(msg_cs=m->data[0]){ case LSS_SM_GLOBAL: /* Switch Mode Global */ /* if there is not a mode change break*/ if(m->data[1] == d->lss_transfer.mode){ - MSG_WAR(0x3D13, "SlaveLSS already in the mode ", m->data[1]); + MSG_WAR(0x3D22, "SlaveLSS already in the mode ", m->data[1]); break; } if(m->data[1]==LSS_CONFIGURATION_MODE) { - MSG_WAR(0x3D14, "SlaveLSS switching to configuration mode ", 0); + MSG_WAR(0x3D23, "SlaveLSS switching to configuration mode ", 0); /* Store the NodeId in case it will be changed */ - d->lss_transfer.nodeID=getNodeId(d); + //d->lss_transfer.nodeID=getNodeId(d); d->lss_transfer.mode=LSS_CONFIGURATION_MODE; } else if(m->data[1]==LSS_WAITING_MODE){ - MSG_WAR(0x3D15, "SlaveLSS switching to operational mode ", 0); + MSG_WAR(0x3D24, "SlaveLSS switching to operational mode ", 0); - if(d->lss_transfer.switchDelayState==SDELAY_OFF){ - /* If the nodeID has changed update it and put the node state to Initialisation. */ - if(d->lss_transfer.nodeID!=getNodeId(d)){ - MSG_WAR(0x3D16, "The node Id has changed. Reseting to Initialisation state",0); + /* If the nodeID has changed update it and put the node state to Initialisation. */ + if(d->lss_transfer.nodeID!=getNodeId(d)){ + if(getNodeId(d)==0xFF){/* The nodeID was 0xFF; initialize the application*/ + MSG_WAR(0x3D25, "The node Id has changed. Reseting to Initialisation state",0); setNodeId(d, d->lss_transfer.nodeID); setState(d, Initialisation); } + else{/* The nodeID will be changed on NMT_Reset Request*/ + setNodeId(d, d->lss_transfer.nodeID); + } } d->lss_transfer.mode=LSS_WAITING_MODE; } @@ -563,7 +652,7 @@ if(d->lss_transfer.mode==LSS_CONFIGURATION_MODE){ if(m->data[1]>127 && m->data[1]!=0xFF){ - MSG_ERR(0x1D17, "NodeID out of range",0); + MSG_ERR(0x1D26, "NodeID out of range",0); error_code=1; /* NodeID out of range */ } else{ @@ -571,7 +660,7 @@ } } else{ - MSG_WAR(0x3D18, "SlaveLSS not in configuration mode",0); + MSG_WAR(0x3D27, "SlaveLSS not in configuration mode",0); //error_code=0xFF; break; } @@ -600,19 +689,19 @@ case 0x07:d->lss_transfer.baudRate="20K";break; case 0x08:d->lss_transfer.baudRate="10K";break; default: - MSG_ERR(0x1D19, "Baud rate not supported",0); + MSG_ERR(0x1D28, "Baud rate not supported",0); error_code=0xFF; /* Baud rate not supported*/ break; } } else { - MSG_ERR(0x1D1A, "Bit timing not supported",0); + MSG_ERR(0x1D29, "Bit timing not supported",0); error_code=0x01; /* bit timing not supported */ } } else{ - MSG_WAR(0x3D1B, "SlaveLSS not in configuration mode",0); + MSG_WAR(0x3D2A, "SlaveLSS not in configuration mode",0); //error_code=0xFF; break; } @@ -623,16 +712,18 @@ case LSS_CONF_ACT_BIT_TIMING: /* Activate Bit Timing Parameters */ if(d->lss_transfer.mode!=LSS_CONFIGURATION_MODE){ - MSG_ERR(0x3D1C, "SlaveLSS not in configuration mode",0); + MSG_ERR(0x3D2B, "SlaveLSS not in configuration mode",0); break; } if(d->lss_transfer.baudRate!="none"){ d->lss_transfer.switchDelay=getLSSDelay(m); - MSG_WAR(0x3D1D, "Slave Switch Delay set to: ",d->lss_transfer.switchDelay); + MSG_WAR(0x3D2C, "Slave Switch Delay set to: ",d->lss_transfer.switchDelay); d->lss_transfer.switchDelayState=SDELAY_FIRST; - d->lss_transfer.currentState=getState(d); - setState(d, LssTimingDelay); + //d->lss_transfer.currentState=getState(d); + //setState(d, LssTimingDelay); + d->lss_transfer.canHandle_t=d->canHandle; + d->canHandle=NULL; StartLSS_SDELAY_TIMER(); } break; @@ -644,15 +735,15 @@ if(d->lss_transfer.mode==LSS_CONFIGURATION_MODE){ if(d->lss_StoreConfiguration){ /* call lss_StoreConfiguration with NodeId */ - (*d->lss_StoreConfiguration)(&error_code,&spec_error); + (*d->lss_StoreConfiguration)(d,&error_code,&spec_error); } else{ - MSG_ERR(0x1D1E, "Store configuration not supported",0); + MSG_ERR(0x1D2E, "Store configuration not supported",0); error_code=1; /* store configuration is not supported */ } } else{ - MSG_WAR(0x3D1F, "SlaveLSS not in configuration mode",0); + MSG_WAR(0x3D2F, "SlaveLSS not in configuration mode",0); //error_code=0xFF; break; } @@ -671,7 +762,7 @@ if(d->lss_transfer.mode==LSS_CONFIGURATION_MODE) { - MSG_ERR(0x1D20, "Switch Mode Selective only supported in operational mode",0); + MSG_ERR(0x1D30, "Switch Mode Selective only supported in operational mode",0); break; } @@ -684,7 +775,7 @@ /* If all the fields has been set */ if(d->lss_transfer.addr_sel_match==0x0F){ - MSG_WAR(0x3D21, "SlaveLSS switching to configuration mode ", 0); + MSG_WAR(0x3D31, "SlaveLSS switching to configuration mode ", 0); d->lss_transfer.addr_sel_match=0; d->lss_transfer.nodeID=getNodeId(d); d->lss_transfer.mode=LSS_CONFIGURATION_MODE; @@ -693,7 +784,7 @@ } } else { - MSG_WAR(0x3D22, "LSS identity field doesn't match ", _SpecificNodeInfo); + MSG_WAR(0x3D32, "LSS identity field doesn't match ", _SpecificNodeInfo); d->lss_transfer.addr_sel_match=0; } } @@ -725,23 +816,23 @@ } /* If all the fields has been set.. */ if(d->lss_transfer.addr_ident_match==0x3F){ - MSG_WAR(0x3D23, "SlaveLSS identified ", 0); + MSG_WAR(0x3D33, "SlaveLSS identified ", 0); d->lss_transfer.addr_ident_match=0; sendSlaveLSSMessage(d,LSS_IDENT_SLAVE,0,0); } else if(d->lss_transfer.addr_ident_match==0){ - MSG_WAR(0x3D24, "LSS identify field doesn't match ", _SpecificNodeInfo); + MSG_WAR(0x3D34, "LSS identify field doesn't match ", _SpecificNodeInfo); } } break; case LSS_IDENT_REMOTE_NON_CONF: /* LSS identify non-configured remote slave */ { if(getNodeId(d)==0xFF){ - MSG_WAR(0x3D25, "SlaveLSS non-configured ", 0); + MSG_WAR(0x3D35, "SlaveLSS non-configured ", 0); sendSlaveLSSMessage(d,LSS_IDENT_NON_CONF_SLAVE,0,0); } else{ - MSG_WAR(0x3D26, "SlaveLSS already configured ", 0); + MSG_WAR(0x3D36, "SlaveLSS already configured ", 0); } } break; @@ -759,7 +850,7 @@ ptrTable = (*d->scanIndexOD)(0x1018, &errorCode, &Callback); _SpecificNodeInfo=*(UNS32*)ptrTable->pSubindex[msg_cs-(LSS_INQ_VENDOR_ID-1)].pObject; - MSG_WAR(0x3D27, "SlaveLSS identity field inquired ", _SpecificNodeInfo); + MSG_WAR(0x3D37, "SlaveLSS identity field inquired ", _SpecificNodeInfo); sendSlaveLSSMessage(d,msg_cs,&_SpecificNodeInfo,0); } @@ -770,11 +861,11 @@ UNS8 NodeID; NodeID=getNodeId(d); - MSG_WAR(0x3D28, "SlaveLSS Node ID inquired ", NodeID); + MSG_WAR(0x3D38, "SlaveLSS Node ID inquired ", NodeID); sendSlaveLSSMessage(d,msg_cs,&NodeID,0); } else{ - MSG_WAR(0x3D29, "SlaveLSS not in configuration mode",0); + MSG_WAR(0x3D39, "SlaveLSS not in configuration mode",0); } break; #ifdef CO_ENABLE_LSS_FS @@ -791,7 +882,7 @@ const indextable *ptrTable; ODCallback_t *Callback; - MSG_WAR(0x3D2A, "SlaveLSS Reseting LSSPos", 0); + MSG_WAR(0x3D3A, "SlaveLSS Reseting LSSPos", 0); d->lss_transfer.LSSPos=0; d->lss_transfer.FastScan_SM=LSS_FS_PROCESSING; @@ -806,9 +897,9 @@ { UNS32 Mask=0xFFFFFFFF<lss_transfer.IDNumber); + MSG_WAR(0x3D3B, "SlaveLSS FastScan IDNumber", getLSSIdent(m)); + MSG_WAR(0x3D3C, "SlaveLSS FastScan BitMask ", Mask); + MSG_WAR(0x3D3D, "SlaveLSS FastScan LSS-ID ", d->lss_transfer.IDNumber); if((getLSSIdent(m) & Mask)==(d->lss_transfer.IDNumber & Mask)) { @@ -827,11 +918,11 @@ if(getLSSIdent(m)==d->lss_transfer.IDNumber) { /* Current LSS-ID[sub] confirmed correctly */ - MSG_WAR(0x3D2E, "SlaveLSS FastScan IDNumber and LSS-ID match=>", d->lss_transfer.IDNumber); + MSG_WAR(0x3D3E, "SlaveLSS FastScan IDNumber and LSS-ID match=>", d->lss_transfer.IDNumber); if(d->lss_transfer.LSSPos==3) { /* All LSS-ID[sub] identified correctly, switching to configuration mode */ - MSG_WAR(0x3D2F, "SlaveLSS switching to configuration mode ", 0); + MSG_WAR(0x3D3F, "SlaveLSS switching to configuration mode ", 0); d->lss_transfer.nodeID=getNodeId(d); d->lss_transfer.mode=LSS_CONFIGURATION_MODE; d->lss_transfer.FastScan_SM=LSS_FS_RESET; @@ -858,26 +949,26 @@ break; #endif default: - MSG_ERR(0x1D30, "SlaveLSS command not implemented", msg_cs); + MSG_ERR(0x1D40, "SlaveLSS command not implemented", msg_cs); return 0xFF; } return 0; } -UNS8 configNetworkNode(CO_Data* d, UNS8 command, void *dat1, void* dat2) +/*UNS8 configNetworkNode(CO_Data* d, UNS8 command, void *dat1, void* dat2) { return sendMasterLSSMessage(d,command,dat1,dat2); -} - -UNS8 configNetworkNodeCallBack (CO_Data* d, UNS8 command, void *dat1, void* dat2, LSSCallback_t Callback) +}*/ + +UNS8 configNetworkNode (CO_Data* d, UNS8 command, void *dat1, void* dat2, LSSCallback_t Callback) { - d->lss_transfer.state=LSS_TRANS_IN_PROGRESS; + //d->lss_transfer.state=LSS_TRANS_IN_PROGRESS; d->lss_transfer.Callback=Callback; d->lss_transfer.command=command; - StopLSS_TIMER(LSS_MSG_TIMER); - StartLSS_MSG_TIMER(); + StopLSS_MSG_TIMER(); + //StartLSS_MSG_TIMER(); return sendMasterLSSMessage(d,command,dat1,dat2); } diff -r fe47568b8281 -r 854c43cdc24a src/nmtSlave.c --- a/src/nmtSlave.c Mon Feb 04 12:06:20 2008 +0100 +++ b/src/nmtSlave.c Mon Feb 04 16:40:44 2008 +0100 @@ -73,10 +73,18 @@ break; case NMT_Reset_Node: +#ifdef CO_ENABLE_LSS + if(getNodeId(d)!=d->lss_transfer.nodeID) + setNodeId(d, d->lss_transfer.nodeID); +#endif setState(d,Initialisation); break; case NMT_Reset_Comunication: +#ifdef CO_ENABLE_LSS + if(getNodeId(d)!=d->lss_transfer.nodeID && getNodeId(d)>0 && getNodeId(d)<=127) + setNodeId(d, d->lss_transfer.nodeID); +#endif setState(d,Initialisation); break; diff -r fe47568b8281 -r 854c43cdc24a src/states.c --- a/src/states.c Mon Feb 04 12:06:20 2008 +0100 +++ b/src/states.c Mon Feb 04 16:40:44 2008 +0100 @@ -136,15 +136,15 @@ **/ void switchCommunicationState(CO_Data* d, s_state_communication *newCommunicationState) { +#ifdef CO_ENABLE_LSS + StartOrStop(csLSS, startLSS(d), stopLSS(d)) +#endif StartOrStop(csSDO, None, resetSDO(d)) StartOrStop(csSYNC, startSYNC(d), stopSYNC(d)) StartOrStop(csHeartbeat, heartbeatInit(d), heartbeatStop(d)) StartOrStop(csEmergency, emergencyInit(d), emergencyStop(d)) StartOrStop(csPDO, PDOInit(d), PDOStop(d)) StartOrStop(csBoot_Up, None, slaveSendBootUp(d)) -#ifdef CO_ENABLE_LSS - StartOrStop(csLSS, startLSS(d), stopLSS(d)) -#endif } /*! @@ -209,16 +209,9 @@ (*d->stopped)(d); } break; -#ifdef CO_ENABLE_LSS - case LssTimingDelay: - { - s_state_communication newCommunicationState = {0, 0, 0, 0, 0, 0, 0}; - d->nodeState = LssTimingDelay; - newState = LssTimingDelay; - switchCommunicationState(d, &newCommunicationState); - } - break; -#endif + default: + return 0xFF; + }/* end switch case */ } @@ -250,6 +243,7 @@ UNS16 offset = d->firstIndex->SDO_SVR; #ifdef CO_ENABLE_LSS + d->lss_transfer.nodeID=nodeId; if(nodeId==0xFF) { *d->bDeviceNodeId = nodeId;