f211
Fork of OBD21121 by
main.cpp
- Committer:
- takeuz
- Date:
- 2017-04-29
- Revision:
- 9:a3bdc9a71466
- Parent:
- 8:cc3cb620c3bd
- Child:
- 10:fe1b976a3f9c
File content as of revision 9:a3bdc9a71466:
#include "mbed.h" #include "functions.h" #define PID_REQUEST 0x7DF #define PID_REPLY 0x7E8 #define CANSPEED_500 500000 #define CANSPEED_250 250000 #define CANSPEED_125 125000 #define sendDebugMessage 1 #define pushDebugData 1 const int canSpeeds[3]= {CANSPEED_125,CANSPEED_500,CANSPEED_250}; Serial serialPorts[2] = {Serial(P0_11,P0_13),Serial(P0_15,P0_14)}; Serial *kLineUART=NULL; DigitalOut *klineWakeup=new DigitalOut(P0_28); CAN canBus(P0_22, P0_23); Ticker timeCounter; Timer OBDTimer; CANMessage can_MsgRx; char kLineCmd[6]= {'\0','\0','\0','\0','\0','\0'}; void clearOBDCommand(); void flushBuffer(); void sendCommandToVehicle(char *_cmd); void setKLineMsg(char *_cmd); void flushBuffer(); void kLinekeepalive(); char tolower(unsigned char ch); int findStringLength(char *_cmd); int isPoweredupNow=1; int interFace=1; int debug=1; int currentOBDProtocol=0; const int protCan=1; const int protkLine9141=2; const int protkLine14230=3; int canFrequency; int cmd; char can_msg[8]; char *incomingDataInInterFace; const int incomingDataInInterFaceSize=256; int incomingDataInInterFaceCounter=0; char * incomingDataInOBD; const int incomingDataInOBDSize=256; int incomingDataInOBDCounter=0; const int waitTimeForOBDComm=2000; const int sleepTime=25000; const int powerSaveTime=120; int OBDCmdReceived=0; int interfaceCmdReceived=0; int lastOBDCmdRcvdTime=0; int lastInterfaceCmdRcvdTime=0; int KlineReadCount=0; int isVehicleCommandProcessing=0; int kLineCommandCount=0; char kByte=0; void readInterface() { char c; while(serialPorts[interFace].readable()) { lastInterfaceCmdRcvdTime=0; c = serialPorts[interFace].getc(); serialPorts[debug].putc(c); if(incomingDataInInterFaceCounter<incomingDataInInterFaceSize && c!='\r' && c!='\n') { incomingDataInInterFace[incomingDataInInterFaceCounter] = c; } incomingDataInInterFaceCounter++; if(c=='\r') { interfaceCmdReceived=1; serialPorts[debug].puts("nl\r\n"); } } } void canReader() { if (canBus.read(can_MsgRx)) { lastOBDCmdRcvdTime=0; if ((can_MsgRx.id == PID_REPLY)) { OBDCmdReceived=1; for (int i = 0; i < (int)can_MsgRx.len && currentOBDProtocol!=0; i++) { char c[2]; sprintf(c, "%02X",can_MsgRx.data[i]); serialPorts[interFace].puts(c); } } } } void readKLine() { char c; while(kLineUART->readable()) { c=kLineUART->getc(); serialPorts[interFace].printf("%02x",c); } } void timeCounterFunction() { lastInterfaceCmdRcvdTime++; lastOBDCmdRcvdTime++; KlineReadCount++; if(currentOBDProtocol==protkLine14230 && KlineReadCount>=3) { KlineReadCount=0; if(incomingDataInInterFaceCounter) { return; } kLinekeepalive(); } } int main() { serialPorts[interFace].baud(9600); serialPorts[debug].puts("f2119\r\n"); incomingDataInInterFace=(char *)malloc(incomingDataInInterFaceSize*sizeof(char)); incomingDataInOBD=(char *)malloc(incomingDataInOBDSize*sizeof(char)); *klineWakeup=0; clearMemoryLocation(incomingDataInInterFace,incomingDataInInterFaceSize); clearMemoryLocation(incomingDataInOBD,incomingDataInOBDSize); wait_ms(300); timeCounter.attach(&timeCounterFunction, 1.0); serialPorts[interFace].attach(&readInterface); serialPorts[interFace].puts("TU211 v1.0\r\n"); while(1) { if(interfaceCmdReceived && checkForLocalInterfaceCommand()) { serialPorts[debug].puts("Going to clear UART data\r\n"); clearInterfaceCommand(); serialPorts[debug].puts("UART data cleared\r\n"); } if(currentOBDProtocol==0 && isPoweredupNow) { isPoweredupNow=0; #if sendDebugMessage serialPorts[debug].puts("Going to figure protocol\r\n"); #endif serialPorts[debug].puts("Searching...\r\n"); checkCommunicationProtocol(); if(!currentOBDProtocol) { #if sendDebugMessage serialPorts[debug].puts("!Unknownprotocol\r\n"); #endif } else if(currentOBDProtocol==protCan) { #if sendDebugMessage serialPorts[debug].puts("can Protocol\r\n"); #endif serialPorts[interFace].puts("OK\r\n"); } else if(currentOBDProtocol==protkLine14230) { #if sendDebugMessage serialPorts[debug].puts("Kline Protocol\r\n"); #endif } } if(interfaceCmdReceived && checkForLocalInterfaceCommand()) { serialPorts[debug].puts("Going to clear UART data\r\n"); clearInterfaceCommand(); serialPorts[debug].puts("UART data cleared\r\n"); } if(interfaceCmdReceived && currentOBDProtocol) { serialPorts[debug].puts("Going to process user command\r\n"); clearOBDCommand(); if(currentOBDProtocol==protCan) { processUserCommand(); } else if(currentOBDProtocol==protkLine14230) { while(isVehicleCommandProcessing); flushBuffer(); /*kLineUART->attach(NULL); kLineUART->attach(&readKLine);*/ sendCommandToVehicle(incomingDataInInterFace); wait_ms(500); serialPorts[debug].printf("\r\n"); } else { clearInterfaceCommand(); serialPorts[interFace].puts("?\r\n"); #if sendDebugMessage serialPorts[debug].puts("?\r\n"); #endif } } else if(interfaceCmdReceived) { clearInterfaceCommand(); serialPorts[interFace].puts("?\r\n"); #if sendDebugMessage serialPorts[debug].puts("?\r\n"); #endif } sleepProcess(); /*if(lastOBDCmdRcvdTime> powerSaveTime && lastInterfaceCmdRcvdTime> powerSaveTime ) { powerSaveMode(); } else { sleepProcess(); }*/ } } void checkCommunicationProtocol() { /* #if sendDebugMessage serialPorts[debug].puts("check Communication protocal ENT\r\n"); #endif*/ int i=0; do { #if sendDebugMessage serialPorts[debug].puts("CanBusCheck\r\n"); #endif canBus.reset(); canBus.frequency(canSpeeds[i]); canBus.attach(NULL); canBus.attach(&canReader); OBDTimer.reset(); OBDTimer.start(); OBDCmdReceived=0; setCanMessage("010D"); if (canBus.write(CANMessage(PID_REQUEST, can_msg, 8))) { /*#if sendDebugMessage serialPorts[debug].printf("OBDTIMER:%d\r\n",OBDTimer.read_ms()); #endif*/ while(OBDTimer.read_ms() < waitTimeForOBDComm) { if(OBDCmdReceived) { currentOBDProtocol=protCan; canFrequency=i; break; } } } wait_ms(200); i++; } while(i<3 && canFrequency==0); OBDTimer.stop(); canBus.attach(NULL); if(!currentOBDProtocol) { //Kline interface check initializeKLine(); } #if sendDebugMessage serialPorts[debug].puts("check Communication protocal EXT\r\n"); #endif } void clearMemoryLocation( char *base, int _size) { for(int forCount=0; forCount<_size; forCount++) { base[forCount]='\0'; } } void setCanMessage(char* _cmd) { serialPorts[debug].puts("user Command :"); serialPorts[debug].puts(_cmd); serialPorts[debug].puts("\r\n"); int len=findStringLength(_cmd)/2; char _mode[2]=""; for(int i=0; i<2; i++) { _mode[i]=_cmd[i]; } int mode=strtol(_mode,NULL, 16); cmd=strtol((_cmd+2),NULL, 16); can_msg[0] = len; can_msg[1] = mode; can_msg[2] = cmd; can_msg[3] = 0; can_msg[4] = 0; can_msg[5] = 0; can_msg[6] = 0; can_msg[7] = 0; } void processUserCommand() { OBDTimer.reset(); setCanMessage(incomingDataInInterFace); OBDTimer.start(); OBDCmdReceived=0; canBus.attach(NULL); canBus.attach(&canReader); if (canBus.write(CANMessage(PID_REQUEST, can_msg, 8))) { while(OBDTimer.read_ms() < waitTimeForOBDComm) { if(OBDCmdReceived) { clearInterfaceCommand(); break; } } } OBDTimer.stop(); if(!OBDCmdReceived) { clearInterfaceCommand(); serialPorts[interFace].puts("?"); } serialPorts[interFace].puts("\r\n"); } void sleepProcess() { #if pushDebugData serialPorts[debug].puts("SPe\r\n"); #endif OBDTimer.reset(); OBDTimer.start(); while(OBDTimer.read_ms()<sleepTime && !interfaceCmdReceived) { wait_ms(50); } OBDTimer.stop(); } void powerSaveMode() { #if pushDebugData serialPorts[debug].puts("PowerSaveOn\r\n"); #endif wait(20); #if pushDebugData serialPorts[debug].puts("PowerSaveOff\r\n"); #endif } int checkForLocalInterfaceCommand() { serialPorts[debug].puts("CommandDETECTED\r\n"); int i=0; while(incomingDataInInterFace[i]!='\0'){ incomingDataInInterFace[i]=tolower(incomingDataInInterFace[i]); i++; } char temp[2]= {incomingDataInInterFace[0],incomingDataInInterFace[1]}; if(strcmp(temp,"at")!=0) { serialPorts[debug].puts("Not Local Command\r\n"); return 0; } if(strcmp(incomingDataInInterFace,"atz")==0) { LPC_SYSCON->SYSAHBCLKCTRL1 |= (1<<7); LPC_SWM->PINASSIGN0 = 0xffffffffUL; LPC_SWM->PINASSIGN1 = 0xffffffffUL; LPC_SWM->PINASSIGN2 = 0xffffffffUL; LPC_SWM->PINASSIGN3 = 0xffffffffUL; LPC_SWM->PINASSIGN4 = 0xffffffffUL; LPC_SWM->PINASSIGN5 = 0xffffffffUL; LPC_SWM->PINASSIGN8 = 0xffffffffUL; LPC_SYSCON->SYSAHBCLKCTRL1 |= (0<<7); NVIC_SystemReset(); } if(strcmp(incomingDataInInterFace,"atrv")==0) { serialPorts[interFace].puts("12.1V\r\n"); clearMemoryLocation(incomingDataInInterFace,incomingDataInInterFaceSize); return 1; } serialPorts[interFace].puts("?\r\n"); return 2; } void sendResponseToInterface() { serialPorts[interFace].puts(incomingDataInOBD); serialPorts[interFace].puts("\r\n"); } void clearInterfaceCommand() { incomingDataInInterFaceCounter=0; interfaceCmdReceived=0; clearMemoryLocation(incomingDataInInterFace,incomingDataInInterFaceSize); } void clearOBDCommand() { clearMemoryLocation(incomingDataInOBD,incomingDataInOBDSize); incomingDataInOBDCounter=0; OBDCmdReceived=0; } int findStringLength(char *_cmd) { int i=0; for(i=0; _cmd[i]!='\0'; ++i); return i; } int initializeKLine() { #if sendDebugMessage serialPorts[debug].puts("K-Line Check\r\n"); #endif *klineWakeup=1; wait_ms(300); *klineWakeup=0; wait_ms(25); *klineWakeup=1; wait_ms(25); delete klineWakeup; kLineUART=new Serial(P0_28,P0_27); kLineUART->baud(10400); kLineUART->attach(&readKLine); uint8_t crc=0; crc=crc+0xC1; crc=crc+0x33; crc=crc+0xF1; crc=crc+0x81; kLineUART->putc(0xC1); kLineUART->putc(0x33); kLineUART->putc(0xF1); kLineUART->putc(0x81); kLineUART->putc(crc); wait(1); //have to check K-line Response currentOBDProtocol=protkLine14230; // have to remove this line return 0; } void setKLineMsg(char *_cmd) { for(int i=3; i<6; i++) { kLineCmd[i]='\0'; } int len=findStringLength(_cmd)/2; char _mode[2]=""; uint8_t crc=0; if(len==1) { crc=crc+0xC1; kLineCmd[0]=0xC1; crc=crc+0x33; kLineCmd[1]=(0x33); crc=crc+0xF1; kLineCmd[2]=(0xF1); crc=crc+strtol((_cmd),NULL, 16); kLineCmd[3]=(strtol((_cmd),NULL, 16)); kLineCmd[4]=(crc); } else if(len==2) { crc=crc+0xC2; kLineCmd[0]=(0xC2); crc=crc+0x33; kLineCmd[1]=(0x33); crc=crc+0xF1; kLineCmd[2]=(0xF1); for(int i=0; i<2; i++) { _mode[i]=_cmd[i]; } crc=crc+strtol(_mode,NULL, 16); kLineCmd[3]=(strtol(_mode,NULL, 16)); crc=crc+(strtol((_cmd+2),NULL, 16)); kLineCmd[4]=(strtol((_cmd+2),NULL, 16)); kLineCmd[5]=(crc); } } void sendCommandToVehicle(char *_cmd) { isVehicleCommandProcessing=1; setKLineMsg(_cmd); for(kLineCommandCount=0; kLineCommandCount<6; kLineCommandCount++) { if(kLineCmd[kLineCommandCount]=='\0') { break; } kLineUART->putc(kLineCmd[kLineCommandCount]); } wait_ms(500); //have to check given and received commands are same. //if it is same we have to read the response else just fush buffer and send the command again clearInterfaceCommand(); isVehicleCommandProcessing=0; } void flushBuffer() { while(kLineUART->readable()) { kLineUART->getc(); } } void kLinekeepalive() { kLineUART->putc(0xc1); kLineUART->putc(0x33); kLineUART->putc(0xf1); kLineUART->putc(0x3e); kLineUART->putc(0x23); } char tolower(unsigned char ch) { if (ch >= 'A' && ch <= 'Z') ch = 'a' + (ch - 'A'); return ch; }