/**------------------------------------------------------------------------------------------- // sends a can message // description: // this operation send a canmessage (not CANopen!) to the pci-can board. therefore this // operation has to fill the correct data (corresponding to the values wriiten in the // gui) into the can-message struct. //------------------------------------------------------------------------------------------*/ void CANFestivalGui::sendCan( ) { Message m; unsigned char data[8]; int ID; if( ui->canCountOfByteActiv->isChecked( ) ) { // the user has given a message length ( from 0 up to 8 bytes) m.len = ui->canCountOfByte->text( ).toInt( ); } else { // the length of the value is calculated automatically m.len = getLength( canDataList ); } // converts the data written in the gui to integer values (remember: the gui is able to // handle hex, decimal and binary values for( int i=0; i<m.len; i++ ) { if( ui->canHexFormat->isChecked( ) ) { data[i] = strtol( canDataList.at( i )->text( ).toStdString().c_str(), NULL, 16 ); } else if( ui->canBinFormat->isChecked( ) ) { data[i] = strtol( canDataList.at( i )->text( ).toStdString().c_str(), NULL, 2 ); } else { data[i] = canDataList.at( i )->text( ).toInt( ); } } // converts the can identifier into decimal data if( ui->canHexFormat->isChecked( ) ) { ID = strtol( ui->canIdentifier->text( ).toStdString().c_str(), NULL, 16 ); } else if( ui->canBinFormat->isChecked( ) ) { ID = strtol( ui->canIdentifier->text( ).toStdString().c_str(), NULL, 2 ); } else { ID = ui->canIdentifier->text( ).toInt( ); } m.cob_id.w = ID; // sets the RTR bit (retrieve bit) if( ui->canRTR->isChecked( ) ) { m.rtr = 0x01; } else { m.rtr = 0x00; } // copies the data into the can-message struct (could have be done directly...) memcpy(&(m.data), &(data[0]), m.len); // now send the data onto the bus f_can_send( 0, &m ); }
UNS8 sendPDO(UNS8 bus_id, s_PDO *pdo, UNS8 req) { UNS8 i; if( nodeState == Operational ) { //Message m; /* Message copy for sending */ //m.cob_id = pdo->cob_id &= 0x7FF; // Because the cobId is 11 bytes length if ( req == DONNEES ) { // UNS8 i; //m.rtr = DONNEES; pdo->rtr= DONNEES; // m.len = pdo->len; // for (i = 0 ; i < pdo->len ; i++) // m.data[i] = pdo->data[i]; } else { //m.rtr = REQUETE; //m.len = 0; pdo->len = 0; pdo->rtr = REQUETE; } MSG_WAR(0x3901, "sendPDO cobId :", pdo->cob_id); MSG_WAR(0x3902, " Nb octets : ", pdo->len); //for (i = 0 ; i < m.len ; i++) //{ //MSG_WAR(0x3920," data : ", m->data[i]); //} return f_can_send(bus_id,pdo); } // end if return 0xFF; }
/* Retourne le node-id */ UNS8 proceedNMTerror(UNS8 bus_id, Message* m ) { // UNS16 time, should_time; // UNS8 * pbConsumerHeartbeatCount; // Pointer to HBConsumerTimeArray (Array of expected heartbeat cycle time for each node. // HBConsumerTimeArray is defined in objdict.c * \param CheckAccess if other than 0, do not read if the data is Write Only // UNS32 * pbConsumerHeartbeatEntry;// Index 1016 on 32 bits UNS8 * pdwSize; UNS8 dwSize;//, count, ConsummerHeartBeat_nodeId ; // UNS8 index; // Index to scan the table of heartbeat consumers UNS8 nodeId = (UNS8) GET_NODE_ID((*m)); pdwSize = &dwSize; if((m->rtr == 1) ) /* Notice that only the master can have sent this node guarding request */ { // Receiving a NMT NodeGuarding (request of the state by the master) // only answer to the NMT NodeGuarding request, the master is not checked (not implemented) if (nodeId == bDeviceNodeId ) { Message msg; msg.cob_id = bDeviceNodeId + 0x700; msg.len = (UNS8)0x01; msg.rtr = 0; msg.data[0] = getState(); if (toggle) { msg.data[0] |= 0x80 ; toggle = 0 ; } else toggle = 1 ; // send the nodeguard response. MSG_WAR(0x3130, "Sending NMT Nodeguard to master, state: ", nodeState); f_can_send( bus_id, &msg ); } return 1 ; } if (m->rtr == 0) // Not a request CAN { MSG_WAR(0x3110, "Received NMT nodeId : ", nodeId); /* the slave's state receievd is stored in the NMTable */ // The state is stored on 7 bit // NMTable[bus_id][nodeId] = (e_nodeState) ((*m).data[0] & 0x7F) ; /* Boot-Up frame reception */ // if ( NMTable[bus_id][nodeId] == Initialisation) // { // The device send the boot-up message (Initialisation) // to indicate the master that it is entered in pre_operational mode // Because the device enter automaticaly in pre_operational mode, // the pre_operational mode is stored // NMTable[bus_id][nodeId] = Pre_operational; // MSG_WAR(0x3100, "The NMT is a bootup from node : ", nodeId); // return 1; // } /* if( NMTable[bus_id][nodeId] != Unknown_state ) { if( getODentry( (UNS16)0x1016, (UNS8)0x0, (void * *) &pbConsumerHeartbeatCount, pdwSize, 0 ) == OD_SUCCESSFUL ) { if (*pbConsumerHeartbeatCount > (UNS8)NB_OF_HEARTBEAT_PRODUCERS) count = (UNS8)NB_OF_HEARTBEAT_PRODUCERS ; else count = *pbConsumerHeartbeatCount ; for( index = (UNS8)0x00; index < count; index++ ) { if( getODentry( (UNS16)0x1016, (UNS8)index + 1, (void * *)&pbConsumerHeartbeatEntry, pdwSize, 0 ) == OD_SUCCESSFUL ) { should_time = (UNS16) ( (*pbConsumerHeartbeatEntry) & (UNS32)0x0000FFFF ) ; ConsummerHeartBeat_nodeId = (UNS8)( ((*pbConsumerHeartbeatEntry) & (UNS32)0x00FF0000) >> (UNS8)16 ); if (( should_time )&&( nodeId == ConsummerHeartBeat_nodeId )) { time = getTime16( &(heartBeatTable[index].time) ); MSG_WAR(0x3105, "HeartBeat received from node : ", nodeId ); MSG_WAR(0x3106, " at time : ", time); setTime16( &heartBeatTable[index].time, (UNS8)0x0000 ); if( bErrorOccured == TRUE ) { lifeguardCallback( (UNS8)CONNECTION_OK ); // a little strange return 0 ; } } } } // end for } } //End if( NMTable[bus_id][nodeId] != Unknown_state) */ } // End if (m->rtr == 0) return 1; }
UNS8 sendSDO(UNS8 bus_id, s_SDO sdo) { UNS32 objDict; if( (nodeState == Operational) || (nodeState == Pre_operational )) { Message m; UNS8 i; UNS32 * pwCobId = NULL; UNS8 * pwNodeId = NULL; UNS8 * pSize; UNS8 size; pSize = &size; MSG_WAR(0x3A00, "sendSDO",0); /*get the communication CobId*/ if ( sdo.nodeId == bDeviceNodeId ) /*case server*/ getODentry( 0x1200, (UNS8)2, (void * *)&pwCobId, pSize, 0); else { /*case client*/ UNS16 sdoNum = 0; for( ; sdoNum < dict_cstes.max_count_of_client_SDO; sdoNum++) { MSG_WAR(0x3A52,"Reading index : ", 0x1280 + sdoNum); objDict = getODentry( (UNS16)0x1280 + sdoNum, (UNS8)3, (void * *)&pwNodeId, pSize, 0); MSG_WAR(0x3A53, "Read in dict, nodeId = ", *pwNodeId); if (objDict == OD_SUCCESSFUL) { if(*pwNodeId == sdo.nodeId) { break; } } else { MSG_ERR(0x1A50, "Erreur dans les SDO client, subindex 2, index : ", (UNS16)1280 + sdoNum); return 0xFF; } } if (sdoNum == dict_cstes.max_count_of_client_SDO) { MSG_WAR (0x2A51, "No SDO client corresponds to the mesage sent to node ", sdo.nodeId); return 0xFF; } getODentry( (UNS16)0x1280 + sdoNum, (UNS8)1, (void * *)&pwCobId, pSize, 0); } /* message copy for sending */ m.cob_id = *pwCobId; m.rtr = DONNEES; //the length of SDO must be 8 m.len = 8; //memcpy(&m.data, &sdo.body, m.len); // This Memcpy depends on packing structure. Avoid if (sdo.len > 0) m.data[0] = sdo.body.SCS; for (i = 1 ; i < sdo.len ; i++) { m.data[i] = sdo.body.data[i - 1]; } for (i = sdo.len ; i < 8; i++) m.data[i]=0; return f_can_send(bus_id,&m); } return 0xFF; }