etisserant@246: /* etisserant@246: This file is part of CanFestival, a library implementing CanOpen Stack. etisserant@246: etisserant@246: Copyright (C): Edouard TISSERANT and Francis DUPIN etisserant@246: etisserant@246: See COPYING file for copyrights details. etisserant@246: etisserant@246: This library is free software; you can redistribute it and/or etisserant@246: modify it under the terms of the GNU Lesser General Public etisserant@246: License as published by the Free Software Foundation; either etisserant@246: version 2.1 of the License, or (at your option) any later version. etisserant@246: etisserant@246: This library is distributed in the hope that it will be useful, etisserant@246: but WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@246: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU etisserant@246: Lesser General Public License for more details. etisserant@246: etisserant@246: You should have received a copy of the GNU Lesser General Public etisserant@246: License along with this library; if not, write to the Free Software etisserant@246: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA etisserant@246: */ etisserant@246: etisserant@246: #if defined(WIN32) && !defined(__CYGWIN__) etisserant@246: #include etisserant@246: #include "getopt.h" etisserant@246: void pause(void) etisserant@246: { etisserant@246: system("PAUSE"); etisserant@246: } etisserant@246: #else etisserant@246: #include etisserant@246: #include etisserant@246: #include etisserant@246: #include etisserant@246: #include etisserant@246: #endif etisserant@246: etisserant@246: #include "canfestival.h" etisserant@246: #include "TestMasterMicroMod.h" etisserant@246: #include "TestMaster.h" etisserant@540: unsigned int slavenodeid; etisserant@246: etisserant@246: etisserant@246: /*****************************************************************************/ etisserant@378: void TestMaster_heartbeatError(CO_Data* d, UNS8 heartbeatID) etisserant@246: { etisserant@246: eprintf("TestMaster_heartbeatError %d\n", heartbeatID); etisserant@246: } etisserant@246: etisserant@246: /******************************************************** etisserant@246: * ConfigureSlaveNode is responsible to etisserant@246: * - setup master RPDO 1 to receive TPDO 1 from id 0x40 etisserant@246: * - setup master TPDO 1 to send RPDO 1 to id 0x40 etisserant@246: ********************************************************/ etisserant@378: void TestMaster_initialisation(CO_Data* d) etisserant@246: { etisserant@246: UNS32 PDO1_COBID = 0x0180 + slavenodeid; etisserant@246: UNS32 PDO2_COBID = 0x0200 + slavenodeid; etisserant@540: UNS32 size = sizeof(UNS32); etisserant@246: etisserant@246: eprintf("TestMaster_initialisation\n"); etisserant@246: etisserant@246: /***************************************** etisserant@246: * Define RPDOs to match slave ID=0x40 TPDOs* etisserant@246: *****************************************/ etisserant@246: writeLocalDict( &TestMaster_Data, /*CO_Data* d*/ etisserant@246: 0x1400, /*UNS16 index*/ etisserant@246: 0x01, /*UNS8 subind*/ etisserant@246: &PDO1_COBID, /*void * pSourceData,*/ etisserant@246: &size, /* UNS8 * pExpectedSize*/ etisserant@246: RW); /* UNS8 checkAccess */ etisserant@246: etisserant@246: etisserant@246: /***************************************** etisserant@246: * Define TPDOs to match slave ID=0x40 RPDOs* etisserant@246: *****************************************/ etisserant@246: writeLocalDict( &TestMaster_Data, /*CO_Data* d*/ etisserant@246: 0x1800, /*UNS16 index*/ etisserant@246: 0x01, /*UNS8 subind*/ etisserant@246: &PDO2_COBID, /*void * pSourceData,*/ etisserant@246: &size, /* UNS8 * pExpectedSize*/ etisserant@246: RW); /* UNS8 checkAccess */ etisserant@246: } etisserant@246: greg@454: static int init_step = 0; etisserant@246: etisserant@246: /*Froward declaration*/ etisserant@246: static void ConfigureSlaveNode(CO_Data* d, UNS8 nodeId); etisserant@246: etisserant@246: /**/ etisserant@246: static void CheckSDOAndContinue(CO_Data* d, UNS8 nodeId) etisserant@246: { etisserant@246: UNS32 abortCode; etisserant@246: etisserant@246: if(getWriteResultNetworkDict (d, nodeId, &abortCode) != SDO_FINISHED) etisserant@246: eprintf("Master : Failed in initializing slave %2.2x, step %d, AbortCode :%4.4x \n", nodeId, init_step, abortCode); etisserant@246: etisserant@246: /* Finalise last SDO transfer with this node */ etisserant@246: closeSDOtransfer(&TestMaster_Data, nodeId, SDO_CLIENT); etisserant@246: etisserant@246: ConfigureSlaveNode(d, nodeId); etisserant@246: } etisserant@246: etisserant@246: /******************************************************** etisserant@246: * ConfigureSlaveNode is responsible to etisserant@246: * - setup slave TPDO 1 transmit time etisserant@246: * - setup slave TPDO 2 transmit time etisserant@246: * - setup slave Heartbeat Producer time etisserant@246: * - switch to operational mode etisserant@246: * - send NMT to slave etisserant@246: ******************************************************** etisserant@246: * This an example of : etisserant@246: * Network Dictionary Access (SDO) with Callback etisserant@246: * Slave node state change request (NMT) etisserant@246: ******************************************************** etisserant@246: * This is called first by TestMaster_preOperational etisserant@246: * then it called again each time a SDO exchange is etisserant@246: * finished. etisserant@246: ********************************************************/ etisserant@246: static void ConfigureSlaveNode(CO_Data* d, UNS8 nodeId) etisserant@246: { etisserant@246: UNS8 res; etisserant@246: eprintf("Master : ConfigureSlaveNode %2.2x\n", nodeId); etisserant@246: printf("nodeid slave=%x\n",nodeId); etisserant@246: switch(++init_step){ etisserant@246: case 1: etisserant@246: { /*disable Slave's TPDO 1 */ etisserant@246: UNS32 TPDO_COBId = 0x80000180 + nodeId; etisserant@246: etisserant@246: eprintf("Master : disable slave %2.2x TPDO 1 \n", nodeId); etisserant@246: res = writeNetworkDictCallBack (d, /*CO_Data* d*/ etisserant@246: /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/ etisserant@246: nodeId, /*UNS8 nodeId*/ etisserant@246: 0x1800, /*UNS16 index*/ etisserant@246: 0x01, /*UNS8 subindex*/ etisserant@246: 4, /*UNS8 count*/ etisserant@246: 0, /*UNS8 dataType*/ etisserant@246: &TPDO_COBId,/*void *data*/ etisserant@246: CheckSDOAndContinue); /*SDOCallback_t Callback*/ etisserant@246: } etisserant@246: break; etisserant@246: etisserant@246: case 2: etisserant@246: { /*setup Slave's TPDO 1 to be transmitted on SYNC*/ etisserant@246: UNS8 Transmission_Type = 0x01; etisserant@246: etisserant@246: eprintf("Master : set slave %2.2x TPDO 1 transmit type\n", nodeId); etisserant@246: res = writeNetworkDictCallBack (d, /*CO_Data* d*/ etisserant@246: /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/ etisserant@246: nodeId, /*UNS8 nodeId*/ etisserant@246: 0x1800, /*UNS16 index*/ etisserant@246: 0x02, /*UNS8 subindex*/ etisserant@246: 1, /*UNS8 count*/ etisserant@246: 0, /*UNS8 dataType*/ etisserant@246: &Transmission_Type,/*void *data*/ etisserant@246: CheckSDOAndContinue); /*SDOCallback_t Callback*/ etisserant@246: } etisserant@246: break; etisserant@246: etisserant@246: case 3: etisserant@246: { /*re-enable Slave's TPDO 1 */ etisserant@246: UNS32 TPDO_COBId = 0x00000180 + nodeId; etisserant@246: etisserant@246: eprintf("Master : re-enable slave %2.2x TPDO 1\n", nodeId); etisserant@246: res = writeNetworkDictCallBack (d, /*CO_Data* d*/ etisserant@246: /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/ etisserant@246: nodeId, /*UNS8 nodeId*/ etisserant@246: 0x1800, /*UNS16 index*/ etisserant@246: 0x01, /*UNS8 subindex*/ etisserant@246: 4, /*UNS8 count*/ etisserant@246: 0, /*UNS8 dataType*/ etisserant@246: &TPDO_COBId,/*void *data*/ etisserant@246: CheckSDOAndContinue); /*SDOCallback_t Callback*/ etisserant@246: } etisserant@246: break; etisserant@246: etisserant@246: case 4: etisserant@246: { /*disable Slave's TPDO 2 */ etisserant@246: UNS32 TPDO_COBId = 0x80000200 + nodeId; etisserant@246: etisserant@246: eprintf("Master : disable slave %2.2x RPDO 1\n", nodeId); etisserant@246: res = writeNetworkDictCallBack (d, /*CO_Data* d*/ etisserant@246: /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/ etisserant@246: nodeId, /*UNS8 nodeId*/ etisserant@246: 0x1400, /*UNS16 index*/ etisserant@246: 0x01, /*UNS8 subindex*/ etisserant@246: 4, /*UNS8 count*/ etisserant@246: 0, /*UNS8 dataType*/ etisserant@246: &TPDO_COBId,/*void *data*/ etisserant@246: CheckSDOAndContinue); /*SDOCallback_t Callback*/ etisserant@246: } etisserant@246: break; etisserant@246: etisserant@246: etisserant@246: case 5: etisserant@246: { etisserant@246: UNS8 Transmission_Type = 0x01; etisserant@246: etisserant@246: eprintf("Master : set slave %2.2x RPDO 1 receive type\n", nodeId); etisserant@246: res = writeNetworkDictCallBack (d, /*CO_Data* d*/ etisserant@246: /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/ etisserant@246: nodeId, /*UNS8 nodeId*/ etisserant@246: 0x1400, /*UNS16 index*/ etisserant@246: 0x02, /*UNS8 subindex*/ etisserant@246: 1, /*UNS8 count*/ etisserant@246: 0, /*UNS8 dataType*/ etisserant@246: &Transmission_Type,/*void *data*/ etisserant@246: CheckSDOAndContinue); /*SDOCallback_t Callback*/ etisserant@246: } etisserant@246: break; etisserant@246: etisserant@246: case 6: etisserant@246: { /*re-enable Slave's TPDO 1 */ etisserant@246: UNS32 TPDO_COBId = 0x00000200 + nodeId; etisserant@246: etisserant@246: eprintf("Master : re-enable %2.2x RPDO 1\n", nodeId); etisserant@246: res = writeNetworkDictCallBack (d, /*CO_Data* d*/ etisserant@246: /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/ etisserant@246: nodeId, /*UNS8 nodeId*/ etisserant@246: 0x1400, /*UNS16 index*/ etisserant@246: 0x01, /*UNS8 subindex*/ etisserant@246: 4, /*UNS8 count*/ etisserant@246: 0, /*UNS8 dataType*/ etisserant@246: &TPDO_COBId,/*void *data*/ etisserant@246: CheckSDOAndContinue); /*SDOCallback_t Callback*/ etisserant@246: } etisserant@246: break; etisserant@246: etisserant@246: case 7: etisserant@246: { etisserant@246: UNS16 Heartbeat_Producer_Time = 0x03E8; etisserant@246: eprintf("Master : set slave %2.2x heartbeat producer time \n", nodeId); etisserant@246: res = writeNetworkDictCallBack (d, /*CO_Data* d*/ etisserant@246: /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/ etisserant@246: nodeId, /*UNS8 nodeId*/ etisserant@246: 0x1017, /*UNS16 index*/ etisserant@246: 0x00, /*UNS8 subindex*/ etisserant@246: 2, /*UNS8 count*/ etisserant@246: 0, /*UNS8 dataType*/ etisserant@246: &Heartbeat_Producer_Time,/*void *data*/ etisserant@246: CheckSDOAndContinue); /*SDOCallback_t Callback*/ etisserant@246: } etisserant@246: break; etisserant@246: etisserant@246: case 8: etisserant@246: { /*disable Slave's TPDO 2 */ etisserant@246: UNS32 TPDO_COBId = 0x80000280 + nodeId; etisserant@246: etisserant@246: eprintf("Master : disable slave %2.2x TPDO 2 \n", nodeId); etisserant@246: res = writeNetworkDictCallBack (d, /*CO_Data* d*/ etisserant@246: /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/ etisserant@246: nodeId, /*UNS8 nodeId*/ etisserant@246: 0x1801, /*UNS16 index*/ etisserant@246: 0x01, /*UNS8 subindex*/ etisserant@246: 4, /*UNS8 count*/ etisserant@246: 0, /*UNS8 dataType*/ etisserant@246: &TPDO_COBId,/*void *data*/ etisserant@246: CheckSDOAndContinue); /*SDOCallback_t Callback*/ etisserant@246: } etisserant@246: break; etisserant@246: etisserant@246: case 9: etisserant@246: { /*disable Slave's TPDO 3 */ etisserant@246: UNS32 TPDO_COBId = 0x80000380 + nodeId; etisserant@246: etisserant@246: eprintf("Master : disable slave %2.2x TPDO 3 \n", nodeId); etisserant@246: res = writeNetworkDictCallBack (d, /*CO_Data* d*/ etisserant@246: /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/ etisserant@246: nodeId, /*UNS8 nodeId*/ etisserant@246: 0x1802, /*UNS16 index*/ etisserant@246: 0x01, /*UNS8 subindex*/ etisserant@246: 4, /*UNS8 count*/ etisserant@246: 0, /*UNS8 dataType*/ etisserant@246: &TPDO_COBId,/*void *data*/ etisserant@246: CheckSDOAndContinue); /*SDOCallback_t Callback*/ etisserant@246: } etisserant@246: break; etisserant@246: etisserant@246: case 10: etisserant@246: { /*disable Slave's TPDO 2 */ etisserant@246: UNS32 TPDO_COBId = 0x80000480 + nodeId; etisserant@246: etisserant@246: eprintf("Master : disable slave %2.2x TPDO 4 \n", nodeId); etisserant@246: res = writeNetworkDictCallBack (d, /*CO_Data* d*/ etisserant@246: /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/ etisserant@246: nodeId, /*UNS8 nodeId*/ etisserant@246: 0x1803, /*UNS16 index*/ etisserant@246: 0x01, /*UNS8 subindex*/ etisserant@246: 4, /*UNS8 count*/ etisserant@246: 0, /*UNS8 dataType*/ etisserant@246: &TPDO_COBId,/*void *data*/ etisserant@246: CheckSDOAndContinue); /*SDOCallback_t Callback*/ etisserant@246: } etisserant@246: break; etisserant@246: etisserant@246: case 11: etisserant@246: /* Put the master in operational mode */ etisserant@246: setState(d, Operational); etisserant@246: etisserant@246: /* Ask slave node to go in operational mode */ etisserant@246: masterSendNMTstateChange (d, nodeId, NMT_Start_Node); etisserant@246: } etisserant@246: etisserant@246: } etisserant@246: etisserant@378: void TestMaster_preOperational(CO_Data* d) etisserant@246: { etisserant@246: etisserant@246: eprintf("TestMaster_preOperational\n"); etisserant@246: ConfigureSlaveNode(&TestMaster_Data, slavenodeid); etisserant@246: etisserant@246: } etisserant@246: etisserant@378: void TestMaster_operational(CO_Data* d) etisserant@246: { etisserant@246: eprintf("TestMaster_operational\n"); etisserant@246: } etisserant@246: etisserant@378: void TestMaster_stopped(CO_Data* d) etisserant@246: { etisserant@246: eprintf("TestMaster_stopped\n"); etisserant@246: } etisserant@246: etisserant@378: void TestMaster_post_sync(CO_Data* d) etisserant@246: { etisserant@246: DO++; etisserant@246: etisserant@246: AO1 = AI1 / 2; etisserant@246: AO2 = AI2 / 2; etisserant@246: AO3 = AI3 / 2; etisserant@246: AO4 = AI4 / 2; etisserant@246: eprintf("MicroMod Digital Out: %2.2x\n",DO); etisserant@246: eprintf("MicroMod Analogue Out1: %d\n",AO1); etisserant@246: eprintf("MicroMod Analogue Out2: %d\n",AO2); etisserant@246: eprintf("MicroMod Analogue Out3: %d\n",AO3); etisserant@246: eprintf("MicroMod Analogue Out4: %d\n",AO4); etisserant@246: eprintf("MicroMod Digital In (by bit): DI1: %2.2x DI2: %2.2x DI3: %2.2x DI4: %2.2x DI5: %2.2x DI6: %2.2x DI7: %2.2x DI8: %2.2x\n",DI1,DI2,DI3,DI4,DI5,DI6,DI7,DI8); etisserant@246: eprintf("MicroMod Analogue In1: %d\n", AI1); etisserant@246: eprintf("MicroMod Analogue In2: %d\n", AI2); etisserant@246: eprintf("MicroMod Analogue In3: %d\n", AI3); etisserant@246: eprintf("MicroMod Analogue In4: %d\n", AI4); etisserant@246: eprintf("MicroMod Analogue In5: %d\n", AI5); etisserant@246: eprintf("MicroMod Analogue In6: %d\n", AI6); etisserant@246: eprintf("MicroMod Analogue In7: %d\n", AI7); etisserant@246: eprintf("MicroMod Analogue In8: %d\n", AI8); etisserant@246: } etisserant@246: etisserant@378: void TestMaster_post_TPDO(CO_Data* d) etisserant@246: { etisserant@246: // eprintf("TestMaster_post_TPDO\n"); etisserant@246: } etisserant@246: etisserant@246: //s_BOARD SlaveBoard = {"0", "500K"}; etisserant@246: s_BOARD MasterBoard = {"32", "125K"}; etisserant@246: etisserant@246: #if !defined(WIN32) || defined(__CYGWIN__) etisserant@246: void catch_signal(int sig) etisserant@246: { etisserant@246: signal(SIGTERM, catch_signal); etisserant@246: signal(SIGINT, catch_signal); etisserant@246: etisserant@246: eprintf("Got Signal %d\n",sig); etisserant@246: } etisserant@246: #endif etisserant@246: greg@454: void help(void) etisserant@246: { etisserant@246: printf("**************************************************************\n"); etisserant@246: printf("* TestMasterMicroMod *\n"); etisserant@246: printf("* *\n"); etisserant@246: printf("* A simple example for PC. *\n"); etisserant@246: printf("* A CanOpen master that control a MicroMod module: *\n"); etisserant@246: printf("* - setup module TPDO 1 transmit type *\n"); etisserant@246: printf("* - setup module RPDO 1 transmit type *\n"); etisserant@246: printf("* - setup module hearbeatbeat period *\n"); etisserant@246: printf("* - disable others TPDOs *\n"); etisserant@246: printf("* - set state to operational *\n"); etisserant@246: printf("* - send periodic SYNC *\n"); etisserant@246: printf("* - send periodic RPDO 1 to Micromod (digital output) *\n"); etisserant@246: printf("* - listen Micromod's TPDO 1 (digital input) *\n"); etisserant@246: printf("* - Mapping RPDO 1 bit per bit (digital input) *\n"); etisserant@246: printf("* *\n"); etisserant@246: printf("* Usage: *\n"); etisserant@246: printf("* ./TestMasterMicroMod [OPTIONS] *\n"); etisserant@246: printf("* *\n"); etisserant@246: printf("* OPTIONS: *\n"); etisserant@246: printf("* -l : Can library [\"libcanfestival_can_virtual.so\"] *\n"); etisserant@246: printf("* *\n"); etisserant@246: printf("* Slave: *\n"); etisserant@246: printf("* -i : Slave Node id format [0x01 , 0x7F] *\n"); etisserant@246: printf("* *\n"); etisserant@246: printf("* Master: *\n"); etisserant@246: printf("* -m : bus name [\"1\"] *\n"); etisserant@246: printf("* -M : 1M,500K,250K,125K,100K,50K,20K,10K *\n"); etisserant@246: printf("* *\n"); etisserant@246: printf("**************************************************************\n"); etisserant@246: } etisserant@246: etisserant@246: /*************************** INIT *****************************************/ etisserant@246: void InitNodes(CO_Data* d, UNS32 id) etisserant@246: { etisserant@246: /****************************** INITIALISATION MASTER *******************************/ etisserant@246: if(MasterBoard.baudrate){ etisserant@246: /* Defining the node Id */ etisserant@246: //setNodeId(&TestMaster_Data, 0x01); etisserant@246: etisserant@246: /* init */ etisserant@246: setState(&TestMaster_Data, Initialisation); etisserant@246: } etisserant@246: } etisserant@246: greg@454: /*************************** EXIT *****************************************/ greg@454: void Exit(CO_Data* d, UNS32 id) greg@454: { greg@454: masterSendNMTstateChange(&TestMaster_Data, 0x02, NMT_Reset_Node); greg@454: greg@454: //Stop master greg@454: setState(&TestMaster_Data, Stopped); greg@454: } greg@454: etisserant@246: /****************************************************************************/ etisserant@246: /*************************** MAIN *****************************************/ etisserant@246: /****************************************************************************/ etisserant@246: int main(int argc,char **argv) etisserant@246: { etisserant@246: etisserant@246: int c; etisserant@246: extern char *optarg; etisserant@246: char* LibraryPath="libcanfestival_can_virtual.so"; etisserant@246: char *snodeid; etisserant@246: while ((c = getopt(argc, argv, "-m:s:M:S:l:i:")) != EOF) etisserant@246: { etisserant@246: switch(c) etisserant@246: { etisserant@246: case 'm' : etisserant@246: if (optarg[0] == 0) etisserant@246: { etisserant@246: help(); etisserant@246: exit(1); etisserant@246: } etisserant@246: MasterBoard.busname = optarg; etisserant@246: break; etisserant@246: case 'M' : etisserant@246: if (optarg[0] == 0) etisserant@246: { etisserant@246: help(); etisserant@246: exit(1); etisserant@246: } etisserant@246: MasterBoard.baudrate = optarg; etisserant@246: break; etisserant@246: case 'l' : etisserant@246: if (optarg[0] == 0) etisserant@246: { etisserant@246: help(); etisserant@246: exit(1); etisserant@246: } etisserant@246: LibraryPath = optarg; etisserant@246: break; etisserant@246: case 'i' : etisserant@246: if (optarg[0] == 0) etisserant@246: { etisserant@246: help(); etisserant@246: exit(1); etisserant@246: } etisserant@246: snodeid = optarg; etisserant@246: sscanf(snodeid,"%x",&slavenodeid); etisserant@246: break; etisserant@246: default: etisserant@246: help(); etisserant@246: exit(1); etisserant@246: } etisserant@246: } etisserant@246: etisserant@246: #if !defined(WIN32) || defined(__CYGWIN__) etisserant@246: /* install signal handler for manual break */ etisserant@246: signal(SIGTERM, catch_signal); etisserant@246: signal(SIGINT, catch_signal); greg@454: TimerInit(); etisserant@246: #endif etisserant@246: etisserant@246: #ifndef NOT_USE_DYNAMIC_LOADING etisserant@246: LoadCanDriver(LibraryPath); etisserant@246: #endif etisserant@246: etisserant@246: TestMaster_Data.heartbeatError = TestMaster_heartbeatError; etisserant@246: TestMaster_Data.initialisation = TestMaster_initialisation; etisserant@246: TestMaster_Data.preOperational = TestMaster_preOperational; etisserant@246: TestMaster_Data.operational = TestMaster_operational; etisserant@246: TestMaster_Data.stopped = TestMaster_stopped; etisserant@246: TestMaster_Data.post_sync = TestMaster_post_sync; etisserant@246: TestMaster_Data.post_TPDO = TestMaster_post_TPDO; etisserant@246: etisserant@246: if(!canOpen(&MasterBoard,&TestMaster_Data)){ etisserant@246: eprintf("Cannot open Master Board\n"); etisserant@246: goto fail_master; etisserant@246: } etisserant@246: etisserant@246: // Start timer thread etisserant@246: StartTimerLoop(&InitNodes); etisserant@246: etisserant@246: // wait Ctrl-C etisserant@246: pause(); etisserant@246: eprintf("Finishing.\n"); etisserant@246: etisserant@246: // Reset the slave node for next use (will stop emitting heartbeat) etisserant@246: masterSendNMTstateChange (&TestMaster_Data, slavenodeid, NMT_Reset_Node); etisserant@246: etisserant@246: // Stop master etisserant@246: setState(&TestMaster_Data, Stopped); etisserant@246: etisserant@246: // Stop timer thread greg@454: StopTimerLoop(&Exit); etisserant@246: etisserant@246: fail_master: etisserant@246: if(MasterBoard.baudrate) canClose(&TestMaster_Data); etisserant@246: greg@454: TimerCleanup(); greg@454: return 0; greg@454: } greg@454: greg@454: