/* I-7188XB-512:Use 7188XB to send NMT to control 2054C, (1)Start remote node (2)Stop remote node (3)Enter pre-operational (4)Reset node (5)Reset communication (6)Node guarding (7)Heartbeat I-7188XB-512 + CAN-2054C node ID :0x01 Baud Rate Rotary Switch: 3 (125 kbps) Compiler: TC++ 3.0 Compile mode: large Project: NMT.c 7188xbl.Lib xc100l.Lib Communication: CANBus of 7188XB <==>CANopen<==>CANBus of 2054C Hardware: I-7188XB-512 + CAN-2054C [10,Dec,2011] by Alan */ #include #include "..\..\lib\7188xb.h" #include "..\..\lib\xc100.h" unsigned char MsgData[8]; unsigned int PrintFlag = 1; unsigned long MsgCnt=0; /*Receive CAN message */ void ReceiveCANData(void); /*Send SDO (COB-ID form client to server (RxSDO),COB-ID:600h + node ID)*/ void SendCANSDO(unsigned char cmd,unsigned char index_l,unsigned char index_h,unsigned char sub_index, unsigned char D1,unsigned char D2,unsigned char D3,unsigned char D4); /*send PDO (COB-ID (200h+node ID) used by RxPDO)*/ void SendCANPDO(unsigned char D1); /*Send NMT (COB-ID : 0),Send NMT Error Control(COB-ID:700h + node ID)*/ void SendCANNMT(unsigned char RTR,unsigned char Cmd); /*user define interrupt */ void UserCANInt(char CANInt) { if (CANInt) ; /*avoid complier warning*/ if (CANInt==0x01){ /*for Rx interrupt*/ L3On(); if(PrintFlag) ReceiveCANData(); } else if (CANInt==0x02){ /*for Tx interrupt*/ L2On(); } L2Off(); L3Off(); } void node_guarding(void) { unsigned short _hexValue; unsigned int _time=1; unsigned char _hi_byte,_lo_byte; unsigned short _lifetime; //Set guarding time 100Ch PrintFlag = 0; Print("Input guarding time value (ex:1000):"); Scanf("%d\n\r",&_hexValue); PrintFlag = 1; _lifetime = _hexValue; _hi_byte = (unsigned char)(_hexValue>>8); _lo_byte = (unsigned char)_hexValue; SendCANSDO(0x2B,0x0C,0x10,0x00,_lo_byte,_hi_byte,0x00,0x00); //Set life time factor 100Dh PrintFlag = 0; Print("Input life time factor value (value < 255):"); Scanf("%d\n\r",&_hexValue); PrintFlag = 1; _lifetime *=_hexValue; SendCANSDO(0x2F,0x0D,0x10,0x00,(unsigned char)_hexValue,0x00,0x00,0x00); //Send guarding request //Send NMT to CAN-2054c for node guarding (COB-ID = 1792+node ID) //Default : Send guarding Message ten times /*If the transmission is not available, an error event will be triggered, and an EMCY message for guarding failure will be received.*/ while(_time<=10) { SendCANNMT(1,0x00); DelayMs(_lifetime); _time++; } } void heartbeat(void) { unsigned short _hexValue; unsigned char _hi_byte,_lo_byte; //Set heartbeat time (1017h) /*Default: wait 10 sec,stop heartbeat*/ PrintFlag = 0; Print("Input heartbeat time value (ex:1000):"); Scanf("%d\n\r",&_hexValue); ReceiveCANData(); _hi_byte = (unsigned char)(_hexValue>>8); _lo_byte = (unsigned char)_hexValue; SendCANSDO(0x2B,0x17,0x10,0x00,_lo_byte,_hi_byte,0x00,0x00); DelayMs(10000); //10 sec SendCANSDO(0x2B,0x17,0x10,0x00,0x00,0x00,0x00,0x00); } void main(void) { int ret; unsigned short _quit,_choice; _quit = 1; // if value is 0,exit while loop InitLib(); /********************************************************/ /* Initial all LEDs */ /********************************************************/ L1Off(); L2Off(); L3Off(); /*******************************************************/ /* initialize and configure the CAN controller */ /*******************************************************/ ret=XC100Init(0,3,125000UL,0,0,0x00000000UL,0xffffffffUL); /* XCANInit function Parameter descriptions 1 : for 7186EX(D) model number (7188XB(D) model number is 0) 3 : for Receive and transmission interrupt 125000UL : for CAN baud 0 : for BT0 of user defined baud 0 : for BT1 of user defined baud 0x00000000UL : for AccCode of CAN message filter 0xffffffffUL : for AccMask of CAN message filter */ switch (ret) { /*Check if configuration is OK*/ case CAN_ResetError: Print("Reset Error!\n\r"); return; case CAN_SetACRError: Print("\n\rSet ACR Error!"); return; case CAN_SetAMRError: Print("\n\rSet AMR Error!"); return; case CAN_SetBaudRateError: Print("\n\rSet Baud Rate Error!"); return; case CAN_BaudNotSupport: Print("\n\rBaud Rate Not Support!"); return; case CAN_ConfigError: Print("\n\rConfiguration Failure!"); return; default: if (ret >0){ Print("Default=%d\n\r",ret); return; } } //end switch /********************************************************/ /* Enable Irq */ /********************************************************/ CAN_CreateBuffer(0,1000); //Create RX Buffer CAN_CreateBuffer(1,1000); //Create TX Buffer CAN_InstallIrq();//Set the interrupt function enable L1On(); /*Turn on LED1 for indicating that the demo is starting*/ while(_quit) { DelayMs(500); PrintFlag = 0; Print("mode : (1)Start remote node (2)Stop remote node (3)Enter pre-operational\n\r"); Print(" (4)Reset node (5)Reset communication \n\r"); Print(" (6)Node guarding (7)Heartbeat (0)Exit :"); Scanf("%d\n\r",&_choice); PrintFlag = 0; switch(_choice) { case 1: //Send NMT to start (COB-ID =0,Data=CS+node-ID),CS=1 SendCANNMT(0,0x01); break; case 2: //send NMT to stop (COB-ID =0,Data=CS+node-ID),CS=2 SendCANNMT(0,0x02); break; case 3: //send NMT to enter pre-operational (COB-ID =0,Data=CS+node-ID),CS=128 SendCANNMT(0,0x80); break; case 4: //send NMT to reset node (COB-ID =0,Data=CS+node-ID),CS=129 SendCANNMT(0,0x81); break; case 5: //send NMT to reset communication (COB-ID =0,Data=CS+node-ID),CS=130 SendCANNMT(0,0x82); break; case 6: //send NMT for node guarding (COB-ID = 1792+node ID) node_guarding(); break; case 7: //send NMT for heartbeat (COB-ID = 1792+node ID) heartbeat(); break; case 0: //send NMT to reset node SendCANNMT(0,0x81); _quit=0; break; default : Print("Wrong choice,Please try angain\n\r"); break; }//end switch } L1Off(); L2Off(); L3Off(); CAN_Restore(); //free resource } void ReceiveCANData(void) { unsigned char MsgData[8]; unsigned char MsgMode,MsgRTR,MsgDataLen; unsigned long MsgID,MsgUpperTimeStamp,MsgLowerTimeStamp; int ret,i; /***************************************************************/ /* Receive CAN messages from receive buffer or from CAN bus */ /***************************************************************/ /* *MsgMode :This parameter is used for get the ID type (11-bit or 29-bit ID) of a CAN message *MsgID: This is for obtaining the ID of a CAN message. *RTR: This is for obtaining the RTR of a CAN message. RTR value Meaning 0 This CAN message is not a remote transmit request message. 1 This CAN message is a remote transmit request message. *DataLen: This is for obtaining the data length of a CAN message. *Data: This is for obtaining the Data of a CAN message. The Data buffer size must be 8 bytes. *UpperTime: Get the time stamp of a CAN message. The time stamp unit is us (micro second), This parameter only show the upper part of time stamp. Real time stamp = upper part * 0x1000000UL+lower part *LowerTime: Get the lower part of time stamp of a CAN message. */ ret=GetCANMsg(&MsgMode,&MsgID,&MsgRTR,&MsgDataLen,MsgData,&MsgUpperTimeStamp,&MsgLowerTimeStamp); if (!ret) { MsgCnt++; //Print received information Print("%lu(%lus-%luus):Mode=%d,ID=%lx,RTR=%d,Len=%d",MsgCnt,MsgUpperTimeStamp ,MsgLowerTimeStamp,MsgMode,MsgID,MsgRTR,MsgDataLen); if (MsgDataLen && !MsgRTR) { Print(",Data="); for (i=0;i=0x580) && (MsgID<=0x5FF)) { switch(MsgData[0]) { case 0x4F: Print("Data Value = %02Xh\n\r",MsgData[4]); break; case 0x4B: Print("Data Value = %02X%02Xh\n\r",MsgData[5],MsgData[4]); break; case 0x47: Print("Data Value = %02X%02X%02Xh\n\r",MsgData[6],MsgData[5],MsgData[4]); break; case 0x43: Print("Data Value = %02X%02X%02X%02Xh\n\r",MsgData[7],MsgData[6],MsgData[5],MsgData[4]); break; } } else if ((MsgID>=0x181 && MsgID<=0x18F)||(MsgID>=0x281 && MsgID<=0x28F)||(MsgID>=0x381 && MsgID<=0x38F)||(MsgID>=0x481 && MsgID<=0x48F)) {//For TxPDO Print("Data value = "); for (i=0;i0) {Print("%02Xh,",MsgData[i]); } else {Print("%02Xh",MsgData[i]); } } Print("\n\r"); } else { ; } } } else { switch(ret) { case CAN_DataLengthError: Print("Reception Data Length Error!\n"); break; case CAN_DataOverrun: Print("Software Reception Data Buffer Overrun!\n"); break; case CAN_ReceiveError: Print("Receive data Error!\n"); break; case CAN_ReceiveBufferEmpty: /*No message in receive buffer*/ break; } } } void SendCANSDO(unsigned char cmd,unsigned char index_l,unsigned char index_h,unsigned char sub_index, unsigned char D1,unsigned char D2,unsigned char D3,unsigned char D4) { int ret; MsgData[0]=cmd; //command specifier MsgData[1]=index_l; //index MsgData[2]=index_h; //index MsgData[3]=sub_index; //sub index MsgData[4]=D1;//value MsgData[5]=D2; MsgData[6]=D3; MsgData[7]=D4; ret=SendCANMsg(0,0x601,0,8,MsgData); if (ret) { switch(ret) { case CAN_DataLengthError: Print("Transmission Data Length Error!\n"); break; case CAN_TransmitIncomplete: Print("Transmission is incomplete!\n"); break; case CAN_TransmitBufferLocked: Print("CAN controller transmit Buffer is locked!\n"); break; } } } void SendCANPDO(unsigned char D1) { int ret; //send PDO (COB-ID (200h+node ID) used by RxPDO) MsgData[0]=D1; //Do value MsgData[1]=0x00; MsgData[2]=0x00; MsgData[3]=0x00; MsgData[4]=0x00; MsgData[5]=0x00; MsgData[6]=0x00; MsgData[7]=0x00; ret=SendCANMsg(0,0x201,0,8,MsgData); if (ret) { switch(ret) { case CAN_DataLengthError: Print("Transmission Data Length Error!\n"); break; case CAN_TransmitIncomplete: Print("Transmission is incomplete!\n"); break; case CAN_TransmitBufferLocked: Print("CAN controller transmit Buffer is locked!\n"); break; } //break; } } void SendCANNMT(unsigned char RTR,unsigned char Cmd) { int ret; if(RTR==0) { MsgData[0]=Cmd; //command specifier MsgData[1]=0x01; //node id MsgData[2]=0x00; MsgData[3]=0x00; MsgData[4]=0x00; MsgData[5]=0x00; MsgData[6]=0x00; MsgData[7]=0x00; ret=SendCANMsg(0,0x00,0,8,MsgData); } else { MsgData[0]=0x00; //command specifier MsgData[1]=0x00; //node id MsgData[2]=0x00; MsgData[3]=0x00; MsgData[4]=0x00; MsgData[5]=0x00; MsgData[6]=0x00; MsgData[7]=0x00; ret=SendCANMsg(0,0x701,1,8,MsgData); } if (ret) { switch(ret) { case CAN_DataLengthError: Print("Transmission Data Length Error!\n"); break; case CAN_TransmitIncomplete: Print("Transmission is incomplete!\n"); break; case CAN_TransmitBufferLocked: Print("CAN controller transmit Buffer is locked!\n"); break; } //break; } }