f211
Fork of OBD21121 by
Diff: main.cpp
- Revision:
- 7:42cb4b01909c
- Parent:
- 6:741524d110fe
- Child:
- 8:cc3cb620c3bd
--- a/main.cpp Mon Feb 27 10:46:09 2017 +0000 +++ b/main.cpp Fri Mar 24 14:16:24 2017 +0000 @@ -1,9 +1,8 @@ #include "mbed.h" #include "functions.h" -#include <string.h> -#define ENGINE_RPM 0x0C -#define VEHICLE_SPEED 0x0D +#define ENGINE_RPM 0x0D +#define VEHICLE_SPEED 13/*0x0D*/ #define PID_REQUEST 0x7DF #define PID_REPLY 0x7E8 @@ -14,33 +13,58 @@ #define sendDebugMessage 1 #define pushDebugData 1 -const int canSpeeds[3]= {CANSPEED_125,CANSPEED_250,CANSPEED_500}; +const int kLineW1=300; +const int kLineW2=20; +const int kLineW3=20; +const int kLineW4=34; +const int kLineP1=20; +const int kLineP2=50; +const int kLineP3=5000; +const int kLineP4=14; +const int canSpeeds[3]= {CANSPEED_125,CANSPEED_500,CANSPEED_250}; +char kLineCmd[6]={'\0','\0','\0','\0','\0','\0'}; +int kLineCommandCount=0; + DigitalOut myled(LED2); -DigitalOut canDriverPowerSave(P0_4); +DigitalOut canDriverPowerSave(LED1); InterruptIn canActivity(P0_5); -RawSerial serialPorts[3] = {RawSerial(P0_26,P0_6),RawSerial(P0_22,P0_23),RawSerial(USBTX,USBRX)}; +RawSerial serialPorts[2] = {RawSerial(P0_22,P0_23),RawSerial(P0_15,P0_14)}; +RawSerial *kLineUART=NULL;//(P0_26,P0_6), +DigitalOut *klineWakeup=new DigitalOut(P0_26); +Ticker timeCounter; +uint8_t calculateChecksum(char *data,int len); +void sendCommandToVehicle(char *_cmd); +int findStringLength(char *_cmd); +void clearOBDCommand(); +int isVehicleCommandProcessing=0; +void flushBuffer(); +int KlineReadCount=0; //Serial pc(P0_9,P0_29); -CAN canBus(P0_24, P0_25); -AnalogIn batteryVoltage(P0_6); +CAN canBus(P0_24, P0_27); + +//AnalogIn batteryVoltage(P0_6); //DigitalOut indicatorLEDs[3] = {P0_22,P0_23,P0_6}; - +DigitalOut kline(P0_1); //UART Counters int kLine=0; int interFace=1; -int debug=2; +int debug=1; int currentOBDProtocol=0; -const int protkLine=2; + const int protCan=1; +const int protkLine9141=2; +const int protkLine14230=3; int canFrequency; +int cmd; //LED Counters -Ticker timeCounter; +Ticker timeCounter2; char can_msg[8]; Timer OBDTimer; @@ -54,6 +78,10 @@ const int incomingDataInOBDSize=256; CANMessage can_MsgRx; int incomingDataInOBDCounter=0; +int emergencyRestart=0; + +char *kLineMessage; +const int kLineMessageSize=8; //OBD Command data @@ -62,6 +90,9 @@ int pid; int ID; +char kLine9141[] = {0x68, 0x6a, 0xf1, 0x00, 0x00,0x00}; +char kLine14230[] = {0xc2, 0x33, 0xf1, 0x00, 0x00,0x00}; +char fastKLine14230[] = {0xC1, 0x33, 0xF1, 0x81, 0x66}; //Wait Duration for OBD comm @@ -80,56 +111,79 @@ int lastOBDCmdRcvdTime=0; int lastInterfaceCmdRcvdTime=0; -void activityOnCan() -{ + +void timeCounterFunction2() { + } void readInterface() { char c; + serialPorts[debug].puts("iS:"); 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=='\n') { + if(c=='\r') { interfaceCmdReceived=1; + serialPorts[debug].puts("nl\r\n"); + // emergencyRestart=0; } + /*if(c=='!') { + emergencyRestart++; + if(emergencyRestart>3) { + NVIC_SystemReset(); + } + }*/ } } void readKLine() { - char c; + /*char c; while(serialPorts[kLine].readable()) { - lastOBDCmdRcvdTime=0; c = serialPorts[kLine].getc(); - if(incomingDataInOBDCounter<incomingDataInOBDSize) { + if(incomingDataInOBDCounter<incomingDataInOBDSize && c!='\r' && c!='\n') { incomingDataInOBD[incomingDataInOBDCounter]=c; + incomingDataInOBDCounter++; } - incomingDataInOBDCounter++; if(c=='\n') { - OBDCmdReceived=1; + OBDCmdReceived++; } + }*/ + char c; + while(kLineUART->readable()) { + c = kLineUART->getc(); + if(incomingDataInOBDCounter<incomingDataInOBDSize && c!='\r' && c!='\n') { + incomingDataInOBD[incomingDataInOBDCounter]=c; + incomingDataInOBDCounter++; + serialPorts[debug].putc(c); + } + } } - - void canReader() { if (canBus.read(can_MsgRx)) { //Setting lastOBDCmdRcvdTime=0; - - if ((can_MsgRx.id == PID_REPLY) && (can_MsgRx.data[2] == ENGINE_RPM)) { + //serialPorts[debug].puts("HRHK2"); + if ((can_MsgRx.id == PID_REPLY) && (can_MsgRx.data[2] == cmd)) { serialPorts[debug].puts("HRHK"); + OBDCmdReceived=1; for (int i = 0; i < (int)can_MsgRx.len; i++) { serialPorts[debug].printf("%d:%x , ", i, can_MsgRx.data[i]); + incomingDataInOBD[incomingDataInOBDCounter]=can_MsgRx.data[i]; + incomingDataInOBDCounter++; } } } @@ -139,16 +193,21 @@ { lastInterfaceCmdRcvdTime++; lastOBDCmdRcvdTime++; + KlineReadCount++; + if(currentOBDProtocol==protkLine14230 && KlineReadCount>=3){ + KlineReadCount=0; + if(incomingDataInInterFaceCounter){ + return; + } + sendCommandToVehicle("010D"); + } //IF timout is over certain amount just shutdown - - } int main() { - serialPorts[debug].puts("f2117\r\n"); - + serialPorts[debug].puts("f2119\r\n"); //Initialization incomingDataInInterFace=(char *)malloc(incomingDataInInterFaceSize*sizeof(char)); incomingDataInOBD=(char *)malloc(incomingDataInOBDSize*sizeof(char)); @@ -157,76 +216,98 @@ clearMemoryLocation(incomingDataInOBD,incomingDataInOBDSize); - canDriverPowerSave=0; - timeCounter.attach(&timeCounterFunction, 1.0); serialPorts[interFace].attach(&readInterface); + serialPorts[interFace].puts("TU211 v1.0\r\n"); + //checkCommunicationProtocol(); - serialPorts[interFace].puts("ELM327 v1.0\r\n"); while(1) { - if(!currentOBDProtocol) { +// canDriverPowerSave=1; + if(interfaceCmdReceived && checkForLocalInterfaceCommand()) { + clearInterfaceCommand(); + } + + if(currentOBDProtocol==0 && interfaceCmdReceived) { #if sendDebugMessage serialPorts[debug].puts("Going to figure protocol\r\n"); #endif - serialPorts[kLine].attach(NULL); canBus.attach(NULL); serialPorts[interFace].puts("Searching...\r\n"); serialPorts[debug].puts("Searching...\r\n"); checkCommunicationProtocol(); - if(currentOBDProtocol==protkLine) { - serialPorts[kLine].attach(&readKLine); - } - if(currentOBDProtocol==protCan) { - canBus.attach(&canReader); - } - //??Shall we do somehitng when receive a specific commnad - - //?? Do this !Unknown only once. if(!currentOBDProtocol) { - serialPorts[interFace].puts("!UnknownProtocol\r\n"); #if sendDebugMessage serialPorts[debug].puts("!Unknownprotocol\r\n"); #endif //Goto Sleep? + } else if(currentOBDProtocol==protCan) { +#if sendDebugMessage + serialPorts[debug].puts("can Protocol\r\n"); +#endif + serialPorts[interFace].puts("OK\r\n"); + canBus.attach(&canReader); + } else if(currentOBDProtocol==protkLine14230){ + //serialPorts[interFace].puts("OK\r\n"); + //serialPorts[kLine].attach(&readKLine); +#if sendDebugMessage + serialPorts[debug].puts("Kline Protocol\r\n"); +#endif + timeCounter2.attach(&timeCounterFunction2, 3.0); } } - - if(interfaceCmdReceived) { - checkForLocalInterfaceCommand(); + if(interfaceCmdReceived && checkForLocalInterfaceCommand()) { + serialPorts[debug].puts("Going to clear UART data\r\n"); + clearInterfaceCommand(); + serialPorts[debug].puts("UART data cleared\r\n"); } - if(interfaceCmdReceived) { - OBDTimer.reset(); - OBDCmdReceived=0; - sendCommand(); - OBDTimer.start(); - while(OBDTimer.read_ms() < waitTimeForOBDComm) { - if(OBDCmdReceived) { - sendResponseToInterface(); - break; - } + if(interfaceCmdReceived && currentOBDProtocol) { + serialPorts[debug].puts("Going to process user command\r\n"); + clearOBDCommand(); + if(currentOBDProtocol==protCan){ + processUserCommand(); + }else if(currentOBDProtocol==protkLine14230){ + serialPorts[debug].printf("Command Received\r\n"); + wait_ms(200); + while(isVehicleCommandProcessing); + flushBuffer(); + kLineUART->attach(&readKLine); + sendCommandToVehicle(incomingDataInInterFace); + wait_ms(500); + serialPorts[debug].printf("\r\n"); + kLineUART->attach(NULL); } - OBDTimer.stop(); - if(!OBDCmdReceived) { - serialPorts[interFace].puts("?\r\n"); - } - OBDCmdReceived=0; - interfaceCmdReceived=0; - - //issueRegularCommands(); + } else { + clearInterfaceCommand(); + serialPorts[interFace].puts("?\r\n"); +#if sendDebugMessage + serialPorts[debug].puts("?\r\n"); +#endif } myled=0; - sleepProcess(); if(lastOBDCmdRcvdTime> powerSaveTime && lastInterfaceCmdRcvdTime> powerSaveTime ) { powerSaveMode(); + } else { + ///???? suren changes + sleepProcess(); } + //???? suren changes + /*if(interfaceCmdReceived && checkForLocalInterfaceCommand()) { + clearInterfaceCommand(); + }*/ myled=1; } } void checkCommunicationProtocol() { + + /*canBus.frequency(canSpeeds[2]); + setCanMessage("010D"); + if (canBus.write(CANMessage(PID_REQUEST, can_msg, 8))) { + serialPorts[debug].printf("done\r\n"); + }*/ #if sendDebugMessage serialPorts[debug].puts("check Communication protocal ENT\r\n"); #endif @@ -235,12 +316,13 @@ #if sendDebugMessage serialPorts[debug].puts("CanBusCheck\r\n"); #endif + canBus.frequency(canSpeeds[i]); + canBus.attach(&canReader); canBus.reset(); - clearCanMessage(); - canBus.frequency(canSpeeds[i]); 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()); @@ -250,6 +332,8 @@ currentOBDProtocol=protCan; canFrequency=i; #if sendDebugMessage + serialPorts[debug].puts("OBD ResPonse is : "); + serialPorts[debug].puts(incomingDataInOBD); serialPorts[debug].puts("check Communication protocal SET\r\n"); #endif return; @@ -258,8 +342,14 @@ } wait_ms(200); i++; + canBus.attach(NULL); } while(i<3); OBDTimer.stop(); + if(!currentOBDProtocol){ + //Kline interface check + initializeKLine(); + } + #if sendDebugMessage serialPorts[debug].puts("check Communication protocal EXT\r\n"); #endif @@ -271,11 +361,17 @@ base[forCount]='\0'; } } -void clearCanMessage() +void setCanMessage(char* _cmd) { + 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] = 0x02; - can_msg[1] = 0x01; - can_msg[2] = 0; + can_msg[1] = mode; + can_msg[2] = cmd; can_msg[3] = 0; can_msg[4] = 0; can_msg[5] = 0; @@ -283,9 +379,32 @@ can_msg[7] = 0; } -void sendCommand() +void processUserCommand() { - + OBDTimer.reset(); + setCanMessage(incomingDataInInterFace); + OBDTimer.start(); + OBDCmdReceived=0; + if (canBus.write(CANMessage(PID_REQUEST, can_msg, 8))) { + while(OBDTimer.read_ms() < waitTimeForOBDComm) { + if(OBDCmdReceived) { + sendResponseToInterface(); +#if sendDebugMessage + serialPorts[debug].puts("OBD ResPonse is : "); + serialPorts[debug].puts(incomingDataInOBD); + serialPorts[debug].puts("check Communication protocal SET\r\n"); +#endif + clearInterfaceCommand(); + break; + } + } + } + OBDTimer.stop(); + if(!OBDCmdReceived) { + clearInterfaceCommand(); + serialPorts[interFace].puts("?\r\n"); + } + interfaceCmdReceived=0; } @@ -301,48 +420,58 @@ wait_ms(50); } OBDTimer.stop(); - } void powerSaveMode() { - //Putting CAn Driver on low power - //Detect can Activity - if(currentOBDProtocol==protCan) { - canDriverPowerSave=1; - } - + //???? suren changes begin #if pushDebugData serialPorts[debug].puts("PowerSaveOn\r\n"); #endif - //Remove pin allocaitons - - //Detect can Activity On Acnbus - if(currentOBDProtocol==protCan) { - canActivity.rise(&activityOnCan); - canActivity.fall(&activityOnCan); - } - - + canDriverPowerSave=0; wait(20); - if(currentOBDProtocol==protCan) { - canDriverPowerSave=0; - } - - //Make pin allocaitons - - //Detect can Activity On Acnbus - if(currentOBDProtocol==protCan) { - canActivity.rise(NULL); - canActivity.fall(NULL); - } - - lastOBDCmdRcvdTime=0; - lastInterfaceCmdRcvdTime=0; - #if pushDebugData serialPorts[debug].puts("PowerSaveOff\r\n"); #endif +//???? suren changes end + //Putting CAn Driver on low power + //Detect can Activity + /* if(currentOBDProtocol==protCan) { + canDriverPowerSave=1; + } + + #if pushDebugData + serialPorts[debug].puts("PowerSaveOn\r\n"); + #endif + //Remove pin allocaitons + + //Detect can Activity On Acnbus + if(currentOBDProtocol==protCan) { + canActivity.rise(&activityOnCan); + canActivity.fall(&activityOnCan); + } + + + wait(20); + if(currentOBDProtocol==protCan) { + canDriverPowerSave=0; + } + + //Make pin allocaitons + + //Detect can Activity On Acnbus + if(currentOBDProtocol==protCan) { + canActivity.rise(NULL); + canActivity.fall(NULL); + } + + lastOBDCmdRcvdTime=0; + lastInterfaceCmdRcvdTime=0; + + #if pushDebugData + serialPorts[debug].puts("PowerSaveOff\r\n"); + #endif + */ } @@ -368,25 +497,278 @@ return; } -void checkForLocalInterfaceCommand() +int checkForLocalInterfaceCommand() { - - char temp[2]={incomingDataInInterFace[0],incomingDataInInterFace[1]}; - if(strcmp(temp,"AT")!=0){ + serialPorts[debug].puts("CommandDETECTED\r\n"); + char temp[2]= {incomingDataInInterFace[0],incomingDataInInterFace[1]}; + serialPorts[debug].puts(temp); + serialPorts[debug].puts(incomingDataInInterFace); + if(strcmp(temp,"AT")!=0) { serialPorts[debug].puts("Not Local Command\r\n"); - return; + return 0; } - if(strcmp(incomingDataInInterFace,"ATZ")==0){ + if(strcmp(incomingDataInInterFace,"ATZ")==0) { NVIC_SystemReset(); } - if(strcmp(incomingDataInInterFace,"ATRV")==0){ - serialPorts[interFace].puts("Gointoreport bat vol\r\n"); - interfaceCmdReceived=0; - return; + if(strcmp(incomingDataInInterFace,"ATRV")==0) { + serialPorts[debug].puts("Gointoreport bat vol\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); + incomingDataInInterFaceCounter=0; + interfaceCmdReceived=0; +} + +int initializeKLine(){ + *klineWakeup=0; + wait_ms(25); + *klineWakeup=1; + wait_ms(25); + delete klineWakeup; + kLineUART=new RawSerial(P0_26,P0_6); + kLineUART->attach(&readKLine); + kLineUART->baud(10400); + 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 remove below line + kLineUART->attach(NULL); + currentOBDProtocol=protkLine14230; + return 0; + serialPorts[kLine].baud(5); + serialPorts[kLine].attach(NULL); + kline=0; wait_ms(200); // start + kline=1; wait_ms(400); // first two bits + kline=0; wait_ms(400); // second pair + kline=1; wait_ms(400); // third pair + kline=0; wait_ms(400); // last pair + clearMemoryLocation(incomingDataInOBD,incomingDataInOBDSize); + lastOBDCmdRcvdTime=0; + OBDCmdReceived++; + serialPorts[kLine].attach(&readKLine); // just attached listener before complete the the first step + kline=1; wait_ms(200); // stop b + //Use PINMUX to move to serial port + //start time count to recevice vehicel data + serialPorts[kLine].attach(NULL); + /*if (incomingDataInOBD==0x55){ + serialPorts[kLine].baud(10400); + clearMemoryLocation(incomingDataInOBD,incomingDataInOBDSize); + lastOBDCmdRcvdTime=0; + OBDCmdReceived++; + serialPorts[kLine].attach(&readKLine); + //start time count to recevice vehicel data + //serialPorts[kLine].attach(NULL); //dont want detach it. But we have to reset the variables. + lastOBDCmdRcvdTime=0; + OBDCmdReceived++; + if (incomingDataInOBD==0x08 || incomingDataInOBD==0x94){ + int firstData=incomingDataInOBD; + clearMemoryLocation(incomingDataInOBD,incomingDataInOBDSize); + //start time count to recevice vehicel data + if (incomingDataInOBD==firstData){ + + } + }*/ + OBDTimer.reset(); + OBDTimer.start(); + char c; + while(OBDTimer.read_ms() < kLineW1){ + if(serialPorts[kLine].readable()) { + c=serialPorts[kLine].getc(); + } + } + if(c!=0x55){ + return 0; + } + int dataReceived=0; + OBDTimer.reset(); + OBDTimer.start(); + + while(OBDTimer.read_ms() < kLineW2){ + if(serialPorts[kLine].readable()) { + c=serialPorts[kLine].getc(); + dataReceived=1; + break; + + } + } + if(!dataReceived){ + return 0; + } + dataReceived=0; + char d; + OBDTimer.reset(); + OBDTimer.start(); + + while(OBDTimer.read_ms() < kLineW3){ + if(serialPorts[kLine].readable()) { + d=serialPorts[kLine].getc(); + dataReceived++; + break; + } + } + OBDTimer.stop(); + if(!dataReceived){ + return 0; + } + // these two should be identical according to the spec. + if(c!=d){ + return 0; + } + + // we obtained w1 and w2, now invert and send it back. + // tester waits w4 between 25 and 50 ms: + wait_ms(kLineW4); + serialPorts[kLine].putc(~c); + + OBDTimer.reset(); + OBDTimer.start(); + + while(OBDTimer.read_ms() < kLineW4){ + if(serialPorts[kLine].readable()) { + d=serialPorts[kLine].getc(); + dataReceived++; + break; + } + } + OBDTimer.stop(); + if(!dataReceived){ + return 0; + } + if(c!=0xCC){ + return 0; + } + //Detectig ISO9141 protocol + if(c==0x08 || c== 0x96){ + currentOBDProtocol=protkLine9141; + + } + //Detectig ISO14230 protocol + if(c==0xef || c== 0x8f){ + currentOBDProtocol=protkLine14230; + } + + return 1; } + +/*int fastInitializeKLine(){ + + +}*/ +void writeToKLine(){ + wait_ms(kLineP4); +} + +int fastInitializeKLine(){ + kline=0; wait_ms(25); // start + kline=1; wait_ms(25); // start + serialPorts[kLine].baud(10400); + + for(int k =0;sizeof(fastKLine14230);k++){ + serialPorts[kLine].putc(fastKLine14230[k]); + } + return 1; +} +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; + //kLineUART->putc(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){//kLineUART + isVehicleCommandProcessing=1; +// clearMemoryLocation(incomingDataInInterFace,incomingDataInInterFaceSize); + setKLineMsg(_cmd); + for(kLineCommandCount=0;kLineCommandCount<6;kLineCommandCount++){ + if(kLineCmd[kLineCommandCount]=='\0'){ + break; + } + kLineUART->putc(kLineCmd[kLineCommandCount]); + wait_ms(5); + } + //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 + ///??? suren code begin + wait_ms(500); + + ///??? suren code end + clearMemoryLocation(incomingDataInInterFace,incomingDataInInterFaceSize); + interfaceCmdReceived=0; + incomingDataInInterFaceCounter=0; +// isUserPortAvailable=1; + isVehicleCommandProcessing=0; +} + + +int findStringLength(char *_cmd){ + int i=0; + for(i=0;_cmd[i]!='\0';++i); + return i; +} +void flushBuffer(){ + while(kLineUART->readable()){ + kLineUART->getc(); + } +} +//byte iso_checksum(byte *data, byte len){ +// byte crc=0; +// for(byte i=0; i<len; i++) +// crc=crc+data[i]; +// return crc; +//}