/* Copyright (C) Trampas Stern name of author This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "obdii.h" #include "codes.h" UBYTE connect=UNKNOWN; UBYTE obdError=0; UBYTE pidSupported[32]={0}; //allow up to 256 PIDS UBYTE pid13; UBYTE pid1D; UBYTE MIL_ON=0; UBYTE obdII_clear_codes() { OBDII data[MAX_RESP]; UBYTE cmd,ret,i; cmd=0x04; ret=obdII_send(&cmd,1,data,MAX_RESP); if (ret==0) { printf("No response to clear codes\n\r"); return 0; } for (i=0; i>3],(pid & 0x07)); } UBYTE getNextPid(UBYTE pid) { while(pid<0x4E) { pid++; if(isPidSupported(pid) && pid!=0x13 && pid!=0x1d ) return pid; } return 0; } UBYTE PidInit() { OBDII data[MAX_RESP]; UBYTE cmd[2],ret,i,j; UBYTE mask,dataByte; UBYTE offset; static UBYTE numPids=0; static UBYTE ncount=0; if (ncount==0 || ncount>50) { numPids=0; offset=0; ncount=0; do { //first find supported PIDs cmd[0]=0x01; cmd[1]=offset; ret=obdII_send(cmd,2,data,MAX_RESP); if(ret==0) { printf("No response from ECM for PID number\n\r"); return 0; } if (ret>1) { //or the data bytes together printf("Num ECMs %d\n\r",ret); for(j=0; j>3],(i & 0x07)); if (i!=0x01) { numPids++; } } i++; mask=mask>>1; if (mask==0) { dataByte++; mask=0x80; } } offset=offset + 0x20; //now handle the configuration PIDS if (isPidSupported(0x13)) { cmd[0]=0x01; cmd[1]=0x13; ret=obdII_send(cmd,2,data,MAX_RESP); if (ret) { pid13=data[0].data[2]; } } if (isPidSupported(0x1D)) { cmd[0]=0x01; cmd[1]=0x1D; ret=obdII_send(cmd,2,data,MAX_RESP); if (ret) { pid1D=data[0].data[2]; } } }while(data[0].data[5] & 0x01); } ncount++; /* printf("Supported pids: "); for (i=0; i<8; i++) { printf("%X ",pidSupported[i]); } printf("\n\r"); */ return numPids; } //gets PID from ECM and returns string. The // value returned from function is number of lines // stored in string UBYTE obdII_read_PID(UBYTE PID, UBYTE *str, UBYTE nStr,UBYTE *str2, UBYTE nStr2) { OBDII data[MAX_RESP]; UBYTE cmd[2],ret,i; cmd[0]=0x01; cmd[1]=PID; ret=obdII_send(cmd,2,data,MAX_RESP); if (ret==0) { return 0; } for(i=0; i1) { //or the data bytes together printf("Num ECMs %d\n\r",ret); for(j=0; j>1; if (mask==0) { dataByte++; mask=0x80; } } offset=offset + 0x20; }while(data[0].data[5] & 0x01); return 0; } //reads PIDs from ECM UBYTE obdII_pid_test() { OBDII data[MAX_RESP]; UBYTE cmd[2],ret,i,j; UBYTE str[50]; UBYTE mask,dataByte; UBYTE offset; offset=0; do { //first find supported PIDs cmd[0]=0x01; cmd[1]=offset; ret=obdII_send(cmd,2,data,MAX_RESP); if(ret==0) { printf("No response from ECM for PID support\n\r"); return 0; } if (ret>1) { //or the data bytes together printf("Num ECMs %d\n\r",ret); for(j=0; j>1; if (mask==0) { dataByte++; mask=0x80; } } offset=offset + 0x20; }while(data[0].data[5] & 0x01); return 0; } */ UBYTE obdII_leds_off() { LED_CAT(0); LED_HEATED_CAT(0); LED_DTC(0); LED_EVAP(0); LED_AIR(0); LED_O2(0); LED_HEATED_O2(0); LED_EGR(0); LED_MISFIRE(0); LED_AC(0); LED_FUEL(0); LED_COMP(0); return 0; } UBYTE obdII_leds(OBDII *data_in,UBYTE nResp) { UBYTE i,j; OBDII data[1]; //Logically or multiple ECM responses for Status for (i=0; i50 || ncount==0) { ncount=0; //first find number of codes cmd[0]=0x01; cmd[1]=0x01; ret=obdII_send(cmd,2,data,MAX_RESP); if (ret==0 || ret>MAX_RESP) { printf("No response for number of codes %d\n\r",ret); return 0; } obdII_leds(data,ret); //process data nCodes=0; for (i=0; inCodes) //Opps someone passed bad parameters { return 0; } cmd[0]=0x03; ret=obdII_send(cmd,1,data,MAX_RESP); if (ret==0 || ret>MAX_RESP) { printf("No response for codes %d\n\r",ret); return 0; } //process codes if(index<1) return 0; l=0; for (i=0; i>6)*10000; code=code+(UWORD)((data[i].data[1+(j*2)] & 0x30)>>4)*(UWORD)1000; code=code+ (UWORD)((data[i].data[1+(j*2)] & 0x0F))*(UWORD)100; code=code+ (UWORD)((data[i].data[2+(j*2)] & 0xF0)>>4)*(UWORD)10; code=code+ (UWORD)((data[i].data[2+(j*2)] & 0x0F)); //printf("code is %lu\n\r",code); j++; if (code>0) { l++; if (l==index) { return code; } } k=k+2; }else { k=data[i].n; } }//while } return 0; } //we need a function to read codes UBYTE obdII_codes() { UBYTE i; UBYTE nCodes; //first find number of codes nCodes=obdII_get_num_codes(0); printf("Found %d codes\n\r",nCodes); for (i=0; iNUM_STATUS_LINES) { sprintf(str, "STATUS ERROR"); return 0; } //read the status bits if (count==0 || count>50) { cmd[0]=0x01; cmd[1]=0x01; ret=obdII_send(cmd,2,data,MAX_RESP); if (ret==0 || ret>MAX_RESP) { printf("No response for status %d\n\r",ret); count=0; return 0; } //Logically or multiple ECM responses for Status for (i=0; i(INT)(nCodes+NUM_STATUS_LINES+nPids)) { line=nCodes+NUM_STATUS_LINES+nPids; } if (line<=0) { line=0; sprintf(str,"NumCodes %u",nCodes); LCD_print1(str,0); sprintf(str,"Scroll to view"); LCD_print2(str,0); return 0; } temp=line; if (temp<=nCodes) { UWORD code; //get the code code=obdII_get_code(temp,nCodes); //since the code is scrolling we can not update every loop //so let's update when code changes... //printf("code %lu %u\n\r",code,temp); if (lastcode!=code && code!=0) { //printf("printing code %lu %u\n\r",code,temp); PcodePrint(code); lastcode=code; } //printf("printing code done\n\r"); //PcodePrint(temp+100); return 0; }else { lastcode=0; } //Now lets handle the status monitors temp=line-nCodes; if (temp0) pid=temp2; } //printf("PID is %u\n\r",pid); //get the labels for the PIDs pidLabels(pid,str,20,str2,20); temp2=0; if (str2[0]==0) { //printf("reading next pid\n\r"); temp2=getNextPid(pid); //printf("next pid is %u\n\r",temp2); if (temp2!=0) { pidLabels(temp2,str2,20,str5,20); } } ////printf("Temp2 is %u\n\r",temp2); if (pid!=lastPid) { LCD_print1(str,0); LCD_print2(str2,0); lastPid=pid; } obdII_read_PID(pid,str3,20,str4,20); //printf("str4 is %s\n\r",str4); if(temp2!=0) { //printf("reading second pid value %u\n\r",temp2); obdII_read_PID(temp2,str4,20,str5,20); } str5[0]=0; sprintf(str5,"%s%s",str,str3); str[0]=0; sprintf(str,"%s%s",str2,str4); //printf("str is %s\n\r",str); LCD_print1(str5,0); LCD_print2(str,0); /* if (temp<=nPids) { obdII_pid_get(str, temp) ; LCD_print1(str,0); obdII_pid_get(str,temp+1); LCD_print2(str,0); } */ return 0; } //does CRC calculations UBYTE crc(UBYTE *data, UBYTE len) { UBYTE result; UBYTE i; UBYTE mask; UBYTE j; UBYTE temp; UBYTE poly; result=0xFF; for(i=0; i>1; } } return ~result; } UBYTE checksum(UBYTE *data, UBYTE len) { UBYTE i; UBYTE sum; sum=0; for(i=0; inum_resp || i>=num_data) { return n; } // j=(num_data+1); } } } } i++; if ((i+3)>=num_data) { done=1; } } /* if (n==0) { printf("Malformed data: "); for(i=0; i