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 "Master.h" etisserant@0: #include "Slave.h" etisserant@0: #include "TestMasterSlave.h" etisserant@0: etisserant@0: /*****************************************************************************/ etisserant@0: void TestMaster_heartbeatError(UNS8 heartbeatID) etisserant@0: { etisserant@0: eprintf("TestMaster_heartbeatError %d\n", heartbeatID); etisserant@0: } etisserant@0: etisserant@154: /******************************************************** etisserant@154: * ConfigureSlaveNode is responsible to etisserant@154: * - setup master RPDO 1 to receive TPDO 1 from id 2 etisserant@154: * - setup master RPDO 2 to receive TPDO 2 from id 2 etisserant@154: ********************************************************/ etisserant@0: void TestMaster_initialisation() etisserant@0: { etisserant@154: UNS32 PDO1_COBID = 0x0182; etisserant@154: UNS32 PDO2_COBID = 0x0282; etisserant@154: UNS8 size = sizeof(UNS32); greg@179: etisserant@0: eprintf("TestMaster_initialisation\n"); etisserant@154: etisserant@154: /***************************************** etisserant@154: * Define RPDOs to match slave ID=2 TPDOs* etisserant@154: *****************************************/ etisserant@175: writeLocalDict( &TestMaster_Data, /*CO_Data* d*/ etisserant@154: 0x1400, /*UNS16 index*/ etisserant@154: 0x01, /*UNS8 subind*/ etisserant@154: &PDO1_COBID, /*void * pSourceData,*/ etisserant@154: &size, /* UNS8 * pExpectedSize*/ etisserant@154: RW); /* UNS8 checkAccess */ etisserant@154: etisserant@175: writeLocalDict( &TestMaster_Data, /*CO_Data* d*/ etisserant@154: 0x1401, /*UNS16 index*/ etisserant@154: 0x01, /*UNS8 subind*/ etisserant@154: &PDO2_COBID, /*void * pSourceData,*/ etisserant@154: &size, /* UNS8 * pExpectedSize*/ etisserant@154: RW); /* UNS8 checkAccess */ etisserant@154: } etisserant@154: greg@179: // Step counts number of times ConfigureSlaveNode is called greg@179: static init_step = 0; greg@179: greg@179: /*Froward declaration*/ greg@179: static void ConfigureSlaveNode(CO_Data* d, UNS8 nodeId); greg@179: greg@179: /**/ greg@179: static void CheckSDOAndContinue(CO_Data* d, UNS8 nodeId) greg@179: { greg@179: UNS32 abortCode; greg@179: if(getWriteResultNetworkDict (d, nodeId, &abortCode) != SDO_FINISHED) greg@179: eprintf("Master : Failed in initializing slave %2.2x, step %d, AbortCode :%4.4x \n", nodeId, init_step, abortCode); greg@179: greg@179: /* Finalise last SDO transfer with this node */ greg@179: closeSDOtransfer(&TestMaster_Data, nodeId, SDO_CLIENT); greg@179: greg@179: ConfigureSlaveNode(d, nodeId); greg@179: } greg@179: etisserant@154: /******************************************************** etisserant@154: * ConfigureSlaveNode is responsible to etisserant@154: * - setup slave TPDO 1 transmit time etisserant@154: * - setup slave TPDO 2 transmit time etisserant@154: * - switch to operational mode etisserant@154: * - send NMT to slave etisserant@154: ******************************************************** etisserant@154: * This an example of : etisserant@154: * Network Dictionary Access (SDO) with Callback etisserant@154: * Slave node state change request (NMT) etisserant@154: ******************************************************** etisserant@154: * This is called first by TestMaster_preOperational etisserant@154: * then it called again each time a SDO exchange is etisserant@154: * finished. etisserant@154: ********************************************************/ greg@179: etisserant@154: static void ConfigureSlaveNode(CO_Data* d, UNS8 nodeId) etisserant@154: { greg@179: /* Master configure heartbeat producer time at 1000 ms greg@179: * for slave node-id 0x02 by DCF concise */ greg@179: greg@179: UNS8 Transmission_Type = 0x01; etisserant@154: UNS32 abortCode; etisserant@154: UNS8 res; etisserant@154: eprintf("Master : ConfigureSlaveNode %2.2x\n", nodeId); etisserant@154: greg@179: switch(++init_step){ etisserant@154: case 1: /*First step : setup Slave's TPDO 1 to be transmitted on SYNC*/ etisserant@154: eprintf("Master : set slave %2.2x TPDO 1 transmit type\n", nodeId); etisserant@154: res = writeNetworkDictCallBack (d, /*CO_Data* d*/ greg@179: nodeId, /*UNS8 nodeId*/ etisserant@154: 0x1800, /*UNS16 index*/ etisserant@154: 0x02, /*UNS8 subindex*/ etisserant@154: 1, /*UNS8 count*/ etisserant@154: 0, /*UNS8 dataType*/ etisserant@154: &Transmission_Type,/*void *data*/ greg@179: CheckSDOAndContinue); /*SDOCallback_t Callback*/ greg@179: break; greg@179: etisserant@154: case 2: /*Second step*/ etisserant@154: eprintf("Master : set slave %2.2x TPDO 2 transmit type\n", nodeId); etisserant@154: writeNetworkDictCallBack (d, /*CO_Data* d*/ greg@179: nodeId, /*UNS8 nodeId*/ etisserant@154: 0x1801, /*UNS16 index*/ etisserant@154: 0x02, /*UNS16 index*/ etisserant@154: 1, /*UNS8 count*/ etisserant@154: 0, /*UNS8 dataType*/ etisserant@154: &Transmission_Type,/*void *data*/ greg@179: CheckSDOAndContinue); /*SDOCallback_t Callback*/ greg@179: break; greg@179: case 3: greg@179: greg@179: /****************************** START *******************************/ greg@179: etisserant@154: /* Put the master in operational mode */ etisserant@154: setState(d, Operational); greg@179: etisserant@154: /* Ask slave node to go in operational mode */ etisserant@154: masterSendNMTstateChange (d, nodeId, NMT_Start_Node); greg@179: etisserant@154: } etisserant@0: } etisserant@0: etisserant@343: #ifdef CO_ENABLE_LSS etisserant@343: static void ConfigureLSSNode(CO_Data* d); etisserant@343: UNS8 init_step_LSS=1; etisserant@343: etisserant@343: static void CheckLSSAndContinue(CO_Data* d, UNS8 command) etisserant@343: { etisserant@343: UNS32 dat1; etisserant@343: UNS8 dat2; etisserant@343: printf("CheckLSS->"); etisserant@343: if(getConfigResultNetworkNode (d, command, &dat1, &dat2) != LSS_FINISHED){ etisserant@343: if(command==LSS_IDENT_NON_CONF_SLAVE){ etisserant@343: eprintf("Master : There are not no-configured slaves in the net\n", command); etisserant@343: return; etisserant@343: } etisserant@343: else{ etisserant@343: eprintf("Master : Failed in LSS comand %d. Trying again\n", command); etisserant@343: } etisserant@343: } etisserant@343: else etisserant@343: { etisserant@343: init_step_LSS++; etisserant@343: etisserant@343: switch(command){ etisserant@343: case LSS_CONF_NODE_ID: etisserant@343: switch(dat1){ etisserant@343: case 0: printf("Node ID change succesful\n");break; etisserant@343: case 1: printf("Node ID change error:out of range\n");break; etisserant@343: case 0xFF:printf("Node ID change error:specific error\n");break; etisserant@343: default:break; etisserant@343: } etisserant@343: break; etisserant@343: case LSS_CONF_BIT_TIMING: etisserant@343: switch(dat1){ etisserant@343: case 0: printf("Baud rate change succesful\n");break; etisserant@343: case 1: printf("Baud rate change error: change baud rate not supported\n");break; etisserant@343: case 0xFF:printf("Baud rate change error:specific error\n");break; etisserant@343: default:break; etisserant@343: } etisserant@343: break; etisserant@343: case LSS_CONF_STORE: etisserant@343: switch(dat1){ etisserant@343: case 0: printf("Store configuration succesful\n");break; etisserant@343: case 1: printf("Store configuration error:not supported\n");break; etisserant@343: case 0xFF:printf("Store configuration error:specific error\n");break; etisserant@343: default:break; etisserant@343: } etisserant@343: break; etisserant@343: case LSS_SM_SELECTIVE_RESP: etisserant@343: printf("Slave in CONFIGURATION mode\n"); etisserant@343: break; etisserant@343: case LSS_IDENT_SLAVE: etisserant@343: printf("node identified\n"); etisserant@343: break; etisserant@343: case LSS_IDENT_NON_CONF_SLAVE: etisserant@343: printf("non-configured remote slave in the net\n"); etisserant@343: break; etisserant@343: case LSS_INQ_VENDOR_ID: etisserant@343: printf("Slave VendorID %x\n", dat1); etisserant@343: break; etisserant@343: case LSS_INQ_PRODUCT_CODE: etisserant@343: printf("Slave Product Code %x\n", dat1); etisserant@343: break; etisserant@343: case LSS_INQ_REV_NUMBER: etisserant@343: printf("Slave Revision Number %x\n", dat1); etisserant@343: break; etisserant@343: case LSS_INQ_SERIAL_NUMBER: etisserant@343: printf("Slave Serial Number %x\n", dat1); etisserant@343: break; etisserant@343: case LSS_INQ_NODE_ID: etisserant@343: printf("Slave nodeid %x\n", dat1); etisserant@343: break; etisserant@343: } etisserant@343: } etisserant@343: etisserant@343: printf("\n"); etisserant@343: ConfigureLSSNode(d); etisserant@343: } etisserant@343: etisserant@343: etisserant@343: struct timeval master_prev_time,master_current_time; etisserant@343: static void ConfigureLSSNode(CO_Data* d) etisserant@343: { etisserant@343: UNS32 Vendor_ID=0x12345678; etisserant@343: UNS32 Product_Code=0x90123456; etisserant@343: UNS32 Revision_Number=0x78901234; etisserant@343: UNS32 Serial_Number=0x56789012; etisserant@343: UNS32 Revision_Number_high=0x78901240; etisserant@343: UNS32 Revision_Number_low=0x78901230; etisserant@343: UNS32 Serial_Number_high=0x56789020; etisserant@343: UNS32 Serial_Number_low=0x56789010; etisserant@343: UNS8 NodeID=0x02; etisserant@343: UNS8 Baud_Table=0; etisserant@343: UNS8 Baud_BitTiming=3; etisserant@343: UNS16 Switch_delay=1; etisserant@343: UNS8 LSS_mode=LSS_WAITING_MODE; etisserant@343: UNS8 res; etisserant@343: eprintf("ConfigureLSSNode-> "); etisserant@343: etisserant@343: switch(init_step_LSS){ etisserant@343: case 1: /* LSS=>identify non-configured remote slave */ etisserant@343: eprintf("LSS=>identify non-configured remote slave\n"); etisserant@343: res=configNetworkNodeCallBack(&TestMaster_Data,LSS_IDENT_REMOTE_NON_CONF,0,0,CheckLSSAndContinue); etisserant@343: break; etisserant@343: case 2: /* LSS=>identify node */ etisserant@343: eprintf("LSS=>identify node\n"); etisserant@343: res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_VENDOR,&Vendor_ID,0); etisserant@343: res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_PRODUCT,&Product_Code,0); etisserant@343: res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_REV_LOW,&Revision_Number_low,0); etisserant@343: res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_REV_HIGH,&Revision_Number_high,0); etisserant@343: res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_SERIAL_LOW,&Serial_Number_low,0); etisserant@343: res=configNetworkNodeCallBack(&TestMaster_Data,LSS_IDENT_REMOTE_SERIAL_HIGH,&Serial_Number_high,0,CheckLSSAndContinue); etisserant@343: break; etisserant@343: case 3: /*First step : setup Slave's TPDO 1 to be transmitted on SYNC*/ etisserant@343: eprintf("LSS=>put in configuration mode\n"); etisserant@343: res=configNetworkNode(&TestMaster_Data,LSS_SM_SELECTIVE_VENDOR,&Vendor_ID,0); etisserant@343: res=configNetworkNode(&TestMaster_Data,LSS_SM_SELECTIVE_PRODUCT,&Product_Code,0); etisserant@343: res=configNetworkNode(&TestMaster_Data,LSS_SM_SELECTIVE_REVISION,&Revision_Number,0); etisserant@343: res=configNetworkNodeCallBack(&TestMaster_Data,LSS_SM_SELECTIVE_SERIAL,&Serial_Number,0,CheckLSSAndContinue); etisserant@343: break; etisserant@343: case 4: /* LSS=>inquire nodeID */ etisserant@343: eprintf("LSS=>inquire nodeID\n"); etisserant@343: res=configNetworkNodeCallBack(&TestMaster_Data,LSS_INQ_NODE_ID,0,0,CheckLSSAndContinue); etisserant@343: break; etisserant@343: case 5: /* LSS=>inquire VendorID */ etisserant@343: eprintf("LSS=>inquire VendorID\n"); etisserant@343: res=configNetworkNodeCallBack(&TestMaster_Data,LSS_INQ_VENDOR_ID,0,0,CheckLSSAndContinue); etisserant@343: break; etisserant@343: case 6: /* LSS=>inquire Product code */ etisserant@343: eprintf("LSS=>inquire Product code\n"); etisserant@343: res=configNetworkNodeCallBack(&TestMaster_Data,LSS_INQ_PRODUCT_CODE,0,0,CheckLSSAndContinue); etisserant@343: break; etisserant@343: case 7: /* LSS=>inquire Revision Number */ etisserant@343: eprintf("LSS=>inquire Revision Number\n"); etisserant@343: res=configNetworkNodeCallBack(&TestMaster_Data,LSS_INQ_REV_NUMBER,0,0,CheckLSSAndContinue); etisserant@343: break; etisserant@343: case 8: /* LSS=>inquire Serial Number */ etisserant@343: eprintf("LSS=>inquire Serial Number\n"); etisserant@343: res=configNetworkNodeCallBack(&TestMaster_Data,LSS_INQ_SERIAL_NUMBER,0,0,CheckLSSAndContinue); etisserant@343: break; etisserant@343: case 9: /* LSS=>change the nodeID */ etisserant@343: eprintf("LSS=>change the nodeId\n"); etisserant@343: res=configNetworkNodeCallBack(&TestMaster_Data,LSS_CONF_NODE_ID,&NodeID,0,CheckLSSAndContinue); etisserant@343: break; etisserant@343: case 10: /* LSS=>change the Baud rate */ etisserant@343: eprintf("LSS=>change the Baud rate\n"); etisserant@343: res=configNetworkNodeCallBack(&TestMaster_Data,LSS_CONF_BIT_TIMING,&Baud_Table,&Baud_BitTiming,CheckLSSAndContinue); etisserant@343: break; etisserant@343: case 11: etisserant@343: eprintf("LSS=>Activate Bit Timing\n"); etisserant@343: res=configNetworkNode(&TestMaster_Data,LSS_CONF_ACT_BIT_TIMING,&Switch_delay,0); etisserant@343: /*no break;*/ etisserant@343: init_step_LSS++; etisserant@343: case 12: etisserant@343: /*LSS=>store configuration*/ etisserant@343: /* It will fail the first time (time out) due to the switch delay */ etisserant@343: /* It will fail the second time because it is not implemented in the slave */ etisserant@343: eprintf("LSS=>store configuration\n"); etisserant@343: res=configNetworkNodeCallBack(&TestMaster_Data,LSS_CONF_STORE,0,0,CheckLSSAndContinue); etisserant@343: break; etisserant@343: case 13: /* LSS=>put in operation mod */ etisserant@343: eprintf("LSS=>put in operation mode\n"); etisserant@343: res=configNetworkNode(&TestMaster_Data,LSS_SM_GLOBAL,&LSS_mode,0); etisserant@343: break; etisserant@343: } etisserant@343: } etisserant@343: #endif etisserant@343: etisserant@0: void TestMaster_preOperational() etisserant@0: { etisserant@0: eprintf("TestMaster_preOperational\n"); etisserant@343: #ifdef CO_ENABLE_LSS etisserant@343: /* Ask slave node to go in stop mode */ etisserant@343: masterSendNMTstateChange (&TestMaster_Data, 0, NMT_Stop_Node); etisserant@343: ConfigureLSSNode(&TestMaster_Data); etisserant@343: #endif etisserant@0: } etisserant@0: etisserant@0: void TestMaster_operational() etisserant@0: { etisserant@0: eprintf("TestMaster_operational\n"); etisserant@0: } etisserant@0: etisserant@0: void TestMaster_stopped() etisserant@0: { etisserant@0: eprintf("TestMaster_stopped\n"); etisserant@0: } etisserant@0: etisserant@0: void TestMaster_post_sync() etisserant@0: { etisserant@0: eprintf("TestMaster_post_sync\n"); etisserant@236: eprintf("Master: %d %d %d %d %d %d %d %d %d %x %x %d %d\n", etisserant@236: MasterMap1, etisserant@236: MasterMap2, etisserant@236: MasterMap3, etisserant@236: MasterMap4, etisserant@236: MasterMap5, etisserant@236: MasterMap6, etisserant@236: MasterMap7, etisserant@236: MasterMap8, etisserant@236: MasterMap9, etisserant@236: MasterMap10, etisserant@236: MasterMap11, etisserant@236: MasterMap12, etisserant@236: MasterMap13); etisserant@0: } etisserant@0: luis@284: void TestMaster_post_emcy(UNS8 nodeID, UNS16 errCode, UNS8 errReg) luis@284: { luis@284: eprintf("Master received EMCY message. Node: %2.2x ErrorCode: %4.4x ErrorRegister: %2.2x\n", nodeID, errCode, errReg); luis@284: } luis@284: etisserant@0: char query_result = 0; etisserant@0: char waiting_answer = 0; etisserant@0: etisserant@236: static void CheckSDO(CO_Data* d, UNS8 nodeId) etisserant@236: { etisserant@236: UNS32 abortCode; etisserant@236: if(getWriteResultNetworkDict (d, nodeId, &abortCode) != SDO_FINISHED) etisserant@236: eprintf("Master : Failed in changing Slave's transmit type AbortCode :%4.4x \n", abortCode); etisserant@236: etisserant@236: /* Finalise last SDO transfer with this node */ etisserant@236: closeSDOtransfer(&TestMaster_Data, nodeId, SDO_CLIENT); etisserant@236: } etisserant@236: etisserant@236: etisserant@236: static int MasterSyncCount = 0; etisserant@0: void TestMaster_post_TPDO() etisserant@0: { etisserant@236: eprintf("TestMaster_post_TPDO MasterSyncCount = %d \n", MasterSyncCount); greg@179: // etisserant@0: // { etisserant@0: // char zero = 0; etisserant@0: // if(MasterMap4 > 0x80){ etisserant@0: // writeNetworkDict ( etisserant@0: // &TestMaster_Data, etisserant@0: // TestSlave_Data->bDeviceNodeId, etisserant@0: // 0x2002, etisserant@0: // 0x00, etisserant@0: // 1, etisserant@0: // 0, etisserant@0: // &zero); etisserant@0: // } etisserant@0: // } etisserant@0: etisserant@236: #if 0 etisserant@0: if(waiting_answer){ etisserant@0: UNS32 abortCode; etisserant@0: UNS8 size; etisserant@0: switch(getReadResultNetworkDict ( etisserant@0: &TestMaster_Data, greg@201: 0x02, etisserant@0: &query_result, etisserant@0: &size, etisserant@0: &abortCode)) etisserant@0: { etisserant@0: case SDO_FINISHED: etisserant@0: /* Do something with result here !!*/ etisserant@0: eprintf("Got SDO answer (0x2002, 0x00), %d %d\n",query_result,size); etisserant@0: case SDO_ABORTED_RCV: etisserant@0: case SDO_ABORTED_INTERNAL: etisserant@0: case SDO_RESET: etisserant@0: waiting_answer = 0; etisserant@0: closeSDOtransfer( etisserant@0: &TestMaster_Data, greg@201: 0x02, etisserant@0: SDO_CLIENT); etisserant@0: break; etisserant@0: case SDO_DOWNLOAD_IN_PROGRESS: etisserant@0: case SDO_UPLOAD_IN_PROGRESS: etisserant@0: break; etisserant@0: } etisserant@236: }else if(MasterSyncCount % 10 == 0){ etisserant@0: readNetworkDict ( etisserant@0: &TestMaster_Data, greg@201: 0x02, etisserant@0: 0x2002, etisserant@0: 0x00, etisserant@0: 0); etisserant@0: waiting_answer = 1; etisserant@0: } etisserant@236: #endif etisserant@236: if(MasterSyncCount % 17 == 0){ etisserant@236: eprintf("Master : Ask RTR PDO (0x1402)\n"); etisserant@236: sendPDOrequest(&TestMaster_Data, 0x1402 ); etisserant@236: sendPDOrequest(&TestMaster_Data, 0x1403 ); etisserant@236: } etisserant@236: if(MasterSyncCount % 50 == 0){ etisserant@236: eprintf("Master : Change slave's transmit type to 0xFF\n"); etisserant@236: UNS8 transmitiontype = 0xFF; etisserant@236: writeNetworkDictCallBack (&TestMaster_Data, /*CO_Data* d*/ etisserant@236: 2, /*UNS8 nodeId*/ etisserant@236: 0x1802, /*UNS16 index*/ etisserant@236: 0x02, /*UNS16 index*/ etisserant@236: 1, /*UNS8 count*/ etisserant@236: 0, /*UNS8 dataType*/ etisserant@236: &transmitiontype,/*void *data*/ etisserant@236: CheckSDO); /*SDOCallback_t Callback*/ etisserant@236: } etisserant@236: if(MasterSyncCount % 50 == 25){ etisserant@236: eprintf("Master : Change slave's transmit type to 0x00\n"); etisserant@236: UNS8 transmitiontype = 0x00; etisserant@236: writeNetworkDictCallBack (&TestMaster_Data, /*CO_Data* d*/ etisserant@236: 2, /*UNS8 nodeId*/ etisserant@236: 0x1802, /*UNS16 index*/ etisserant@236: 0x02, /*UNS16 index*/ etisserant@236: 1, /*UNS8 count*/ etisserant@236: 0, /*UNS8 dataType*/ etisserant@236: &transmitiontype,/*void *data*/ etisserant@236: CheckSDO); /*SDOCallback_t Callback*/ etisserant@236: } etisserant@236: MasterSyncCount++; etisserant@236: } etisserant@343: etisserant@343: void TestMaster_post_SlaveBootup(UNS8 nodeid) etisserant@343: { etisserant@343: eprintf("TestMaster_post_SlaveBootup %x\n", nodeid); groke6@349: etisserant@343: ConfigureSlaveNode(&TestMaster_Data, nodeid); groke6@349: groke6@349: } groke6@349: