etisserant@0: /* etisserant@0: This file is part of CanFestival, a library implementing CanOpen Stack. etisserant@0: etisserant@0: Copyright (C): Edouard TISSERANT and Francis DUPIN etisserant@0: etisserant@0: See COPYING file for copyrights details. etisserant@0: etisserant@0: This library is free software; you can redistribute it and/or etisserant@0: modify it under the terms of the GNU Lesser General Public etisserant@0: License as published by the Free Software Foundation; either etisserant@0: version 2.1 of the License, or (at your option) any later version. etisserant@0: etisserant@0: This library is distributed in the hope that it will be useful, etisserant@0: but WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU etisserant@0: Lesser General Public License for more details. etisserant@0: etisserant@0: You should have received a copy of the GNU Lesser General Public etisserant@0: License along with this library; if not, write to the Free Software etisserant@0: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA etisserant@0: */ etisserant@0: etisserant@0: #include etisserant@0: #include etisserant@0: #include etisserant@0: #include etisserant@0: #include etisserant@0: #include etisserant@0: etisserant@0: #include etisserant@0: #include etisserant@0: #include etisserant@0: etisserant@0: #include "Master.h" etisserant@0: #include "Slave.h" etisserant@0: #include "TestMasterSlave.h" etisserant@0: etisserant@0: #define MyCase(fc) case fc: eprintf(#fc);break; etisserant@0: void print_message(Message *m) etisserant@0: { etisserant@0: int i; etisserant@0: switch(m->cob_id.w >> 7) etisserant@0: { etisserant@0: MyCase(SYNC) etisserant@0: MyCase(TIME_STAMP) etisserant@0: MyCase(PDO1tx) etisserant@0: MyCase(PDO1rx) etisserant@0: MyCase(PDO2tx) etisserant@0: MyCase(PDO2rx) etisserant@0: MyCase(PDO3tx) etisserant@0: MyCase(PDO3rx) etisserant@0: MyCase(PDO4tx) etisserant@0: MyCase(PDO4rx) etisserant@0: MyCase(SDOtx) etisserant@0: MyCase(SDOrx) etisserant@0: MyCase(NODE_GUARD) etisserant@0: MyCase(NMT) etisserant@0: } etisserant@0: eprintf(" rtr:%d", m->rtr); etisserant@0: eprintf(" len:%d", m->len); etisserant@0: for (i = 0 ; i < m->len ; i++) etisserant@0: eprintf(" %02x", m->data[i]); etisserant@0: eprintf("\n"); etisserant@0: } etisserant@0: etisserant@0: UNS32 OnMasterMap1Update(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex) etisserant@0: { etisserant@0: eprintf("OnSlaveMap1Update:%d\n", SlaveMap1); lbessard@31: return 0; etisserant@0: } etisserant@0: etisserant@0: CAN_HANDLE SlaveCanHandle; etisserant@0: CAN_HANDLE MasterCanHandle; etisserant@0: etisserant@0: // Baudrate values for Peak board : etisserant@0: // CAN_BAUD_1M CAN_BAUD_500K CAN_BAUD_250K CAN_BAUD_125K CAN_BAUD_100K CAN_BAUD_50K etisserant@0: // CAN_BAUD_20K CAN_BAUD_10K CAN_BAUD_5K etisserant@0: etisserant@0: #ifdef CAN_BAUD_500K etisserant@36: int TranslateBaudeRate(char* optarg){ etisserant@36: if(!strcmp( optarg, "1M")) return CAN_BAUD_1M; etisserant@36: if(!strcmp( optarg, "500K")) return CAN_BAUD_500K; etisserant@36: if(!strcmp( optarg, "250K")) return CAN_BAUD_250K; etisserant@36: if(!strcmp( optarg, "125K")) return CAN_BAUD_125K; etisserant@36: if(!strcmp( optarg, "100K")) return CAN_BAUD_100K; etisserant@36: if(!strcmp( optarg, "50K")) return CAN_BAUD_50K; etisserant@36: if(!strcmp( optarg, "20K")) return CAN_BAUD_20K; etisserant@36: if(!strcmp( optarg, "10K")) return CAN_BAUD_10K; etisserant@36: if(!strcmp( optarg, "5K")) return CAN_BAUD_5K; etisserant@36: if(!strcmp( optarg, "none")) return 0; etisserant@36: return 0x0000; etisserant@36: } etisserant@36: s_BOARD SlaveBoard = {"0", CAN_BAUD_500K, &TestSlave_Data}; etisserant@36: s_BOARD MasterBoard = {"1", CAN_BAUD_500K, &TestMaster_Data}; etisserant@0: #else etisserant@36: int TranslateBaudeRate(char* optarg){ etisserant@36: if(!strcmp( optarg, "1M")) return 1000; etisserant@36: if(!strcmp( optarg, "500K")) return 500; etisserant@36: if(!strcmp( optarg, "250K")) return 250; etisserant@36: if(!strcmp( optarg, "125K")) return 125; etisserant@36: if(!strcmp( optarg, "100K")) return 100; etisserant@36: if(!strcmp( optarg, "50K")) return 50; etisserant@36: if(!strcmp( optarg, "20K")) return 20; etisserant@36: if(!strcmp( optarg, "10K")) return 10; etisserant@36: if(!strcmp( optarg, "5K")) return 5; etisserant@36: if(!strcmp( optarg, "none")) return 0; etisserant@36: return 0; etisserant@36: } etisserant@36: s_BOARD SlaveBoard = {"0", 500, &TestSlave_Data}; etisserant@36: s_BOARD MasterBoard = {"1", 500, &TestMaster_Data}; etisserant@0: #endif etisserant@0: etisserant@36: etisserant@0: void catch_signal(int sig) etisserant@0: { etisserant@0: signal(SIGTERM, catch_signal); etisserant@0: signal(SIGINT, catch_signal); etisserant@32: eprintf("Got Signal %d\n",sig); etisserant@32: } etisserant@0: etisserant@0: void help() etisserant@0: { etisserant@0: printf("**************************************************************\n"); etisserant@0: printf("* TestMasterSlave *\n"); etisserant@0: printf("* *\n"); etisserant@0: printf("* A simple example for PC. It does implement 2 CanOpen *\n"); etisserant@0: printf("* nodes in the same process. A master and a slave. Both *\n"); etisserant@36: printf("* communicate together, exchanging periodically NMT, SYNC, *\n"); etisserant@36: printf("* SDO and PDO. *\n"); etisserant@36: printf("* *\n"); etisserant@36: printf("* Usage: *\n"); etisserant@36: printf("* ./TestMasterSlave [OPTIONS] *\n"); etisserant@36: printf("* *\n"); etisserant@36: printf("* OPTIONS: *\n"); etisserant@36: printf("* Slave: *\n"); etisserant@36: printf("* -s : bus name [\"0\"] *\n"); etisserant@36: printf("* -S : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable) *\n"); etisserant@36: printf("* *\n"); etisserant@36: printf("* Master: *\n"); etisserant@36: printf("* -m : bus name [\"1\"] *\n"); etisserant@36: printf("* -M : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable) *\n"); etisserant@0: printf("* *\n"); etisserant@0: printf("**************************************************************\n"); etisserant@0: } etisserant@0: etisserant@36: /*************************** INIT *****************************************/ etisserant@36: void InitNodes(CO_Data* d, UNS32 id) etisserant@36: { etisserant@36: /****************************** INITIALISATION SLAVE *******************************/ etisserant@36: if(SlaveBoard.baudrate) { etisserant@36: /* Defining the node Id */ etisserant@36: setNodeId(&TestSlave_Data, 0x02); etisserant@36: /* init */ etisserant@36: setState(&TestSlave_Data, Initialisation); etisserant@36: } etisserant@36: etisserant@36: /****************************** INITIALISATION MASTER *******************************/ etisserant@36: if(MasterBoard.baudrate){ etisserant@36: RegisterSetODentryCallBack(&TestMaster_Data, 0x2000, 0, &OnMasterMap1Update); etisserant@36: etisserant@36: /* Defining the node Id */ etisserant@36: setNodeId(&TestMaster_Data, 0x01); etisserant@36: etisserant@36: /* init */ etisserant@36: setState(&TestMaster_Data, Initialisation); etisserant@36: etisserant@36: /****************************** START *******************************/ etisserant@36: /* Put the master in operational mode */ etisserant@36: setState(&TestMaster_Data, Operational); etisserant@36: etisserant@36: /* Ask slave node to go in operational mode */ etisserant@36: masterSendNMTstateChange (&TestMaster_Data, 0x02, NMT_Start_Node); etisserant@36: } etisserant@36: } etisserant@36: etisserant@0: /****************************************************************************/ etisserant@0: /*************************** MAIN *****************************************/ etisserant@0: /****************************************************************************/ etisserant@0: int main(int argc,char **argv) etisserant@0: { etisserant@0: etisserant@0: char c; etisserant@0: extern char *optarg; etisserant@0: etisserant@36: while ((c = getopt(argc, argv, "-m:s:M:S:")) != EOF) etisserant@0: { etisserant@0: switch(c) etisserant@0: { etisserant@0: case 's' : etisserant@0: if (optarg[0] == 0) etisserant@0: { etisserant@0: help(); etisserant@0: exit(1); etisserant@0: } etisserant@0: SlaveBoard.busname = optarg; etisserant@0: break; etisserant@0: case 'm' : etisserant@0: if (optarg[0] == 0) etisserant@0: { etisserant@0: help(); etisserant@0: exit(1); etisserant@0: } etisserant@0: MasterBoard.busname = optarg; etisserant@0: break; etisserant@36: case 'S' : etisserant@36: if (optarg[0] == 0) etisserant@36: { etisserant@36: help(); etisserant@36: exit(1); etisserant@36: } etisserant@36: SlaveBoard.baudrate = TranslateBaudeRate(optarg); etisserant@36: break; etisserant@36: case 'M' : etisserant@36: if (optarg[0] == 0) etisserant@36: { etisserant@36: help(); etisserant@36: exit(1); etisserant@36: } etisserant@36: MasterBoard.baudrate = TranslateBaudeRate(optarg); etisserant@36: break; etisserant@0: default: etisserant@0: help(); etisserant@0: exit(1); etisserant@0: } etisserant@0: } etisserant@0: etisserant@0: /* install signal handler for manual break */ etisserant@0: signal(SIGTERM, catch_signal); etisserant@0: signal(SIGINT, catch_signal); etisserant@0: etisserant@0: // Open CAN devices etisserant@36: if(SlaveBoard.baudrate) etisserant@36: if((SlaveCanHandle = canOpen(&SlaveBoard))==NULL) goto fail_slave; etisserant@40: etisserant@36: if(MasterBoard.baudrate) etisserant@36: if((MasterCanHandle = canOpen(&MasterBoard))==NULL) goto fail_master; etisserant@0: etisserant@32: // Start timer thread etisserant@32: StartTimerLoop(&InitNodes); etisserant@32: etisserant@32: // wait Ctrl-C etisserant@32: pause(); etisserant@32: eprintf("Finishing.\n"); etisserant@32: etisserant@32: // Stop timer thread etisserant@32: StopTimerLoop(); etisserant@32: etisserant@32: // Close CAN devices (and can threads) etisserant@36: if(SlaveBoard.baudrate) canClose(SlaveCanHandle); etisserant@36: fail_master: etisserant@36: if(MasterBoard.baudrate) canClose(MasterCanHandle); etisserant@36: fail_slave: etisserant@0: etisserant@0: etisserant@0: return 0; etisserant@0: }