Example #1
0
        //Search GM e38/e67 DTC codes
        public string SearchDtcE38(PcmFile PCM)
        {
            try
            {
                if (PCM.OSSegment == -1)
                {
                    return("DTC search: No OS segment??");
                }
                if (PCM.diagSegment == -1)
                {
                    return("DTC search: No Diagnostic segment??");
                }

                //Get codes from OS segment:
                string searchStr  = "3D 80 * * 39 8C * * 7D 7B DA 14 7C 8C 5A 2E 80 BD";
                uint   opCodeAddr = uint.MaxValue;
                uint   tableStart = 0;
                for (int b = 0; b < PCM.segmentAddressDatas[PCM.OSSegment].SegmentBlocks.Count; b++)
                {
                    opCodeAddr = searchBytes(PCM, searchStr, PCM.segmentAddressDatas[PCM.OSSegment].SegmentBlocks[b].Start, PCM.segmentAddressDatas[PCM.OSSegment].SegmentBlocks[b].End);
                    if (opCodeAddr < uint.MaxValue)
                    {
                        ushort highBytes = BEToUint16(PCM.buf, (uint)(opCodeAddr + 2));
                        ushort lowBytes  = BEToUint16(PCM.buf, (uint)(opCodeAddr + 6));
                        tableStart = (uint)(highBytes << 16 | lowBytes);
                        ushort tmp = (ushort)(opCodeAddr & 0xffff);
                        if (tmp > 0x5000)
                        {
                            tableStart -= 0x10000;               //Some kind of address offset
                        }
                        bool dCodes = false;
                        for (uint addr = tableStart; addr < PCM.fsize; addr += 2)
                        {
                            dtcCode dtc = new dtcCode();
                            dtc.codeAddrInt = addr;
                            dtc.CodeAddr    = addr.ToString("X8");
                            dtc.codeInt     = BEToUint16(PCM.buf, addr);

                            string codeTmp = dtc.codeInt.ToString("X4");
                            if (dCodes && !codeTmp.StartsWith("D"))
                            {
                                break;
                            }
                            if (codeTmp.StartsWith("D"))
                            {
                                dCodes = true;
                            }
                            dtc.Code        = decodeDTC(codeTmp);
                            dtc.Description = getDtcDescription(dtc.Code);
                            PCM.dtcCodes.Add(dtc);
                        }
                        break;
                    }
                }

                int dtcCount = PCM.dtcCodes.Count;

                //Search by opcode:
                opCodeAddr = searchBytes(PCM, "3C A0 * * 38 A5 * * 7D 85 50", 0, PCM.fsize);
                if (opCodeAddr < uint.MaxValue)
                {
                    ushort highBytes = BEToUint16(PCM.buf, (uint)(opCodeAddr + 2));
                    ushort lowBytes  = BEToUint16(PCM.buf, (uint)(opCodeAddr + 6));
                    tableStart = (uint)(highBytes << 16 | lowBytes);
                }

                if (tableStart > 0)
                {
                    int dtcNr = 0;
                    for (uint addr2 = tableStart; addr2 < tableStart + dtcCount; addr2++)
                    {
                        if (PCM.buf[addr2] == 0xFF)
                        {
                            return("");
                        }
                        dtcCode dtc = PCM.dtcCodes[dtcNr];
                        dtc.statusAddrInt = addr2;
                        //dtc.StatusAddr = addr2.ToString("X8");
                        //dtc.Status = PCM.buf[addr2];
                        byte statusByte = PCM.buf[addr2];
                        if (statusByte > 3)
                        {
                            dtc.MilStatus = 1;
                        }
                        else
                        {
                            dtc.MilStatus = 0;
                        }
                        dtc.Status    = statusByte;
                        dtc.StatusTxt = dtcStatusCombined[dtc.Status];

                        PCM.dtcCodes.RemoveAt(dtcNr);
                        PCM.dtcCodes.Insert(dtcNr, dtc);
                        dtcNr++;
                    }
                }
            }
            catch (Exception ex)
            {
                var st = new StackTrace(ex, true);
                // Get the top stack frame
                var frame = st.GetFrame(st.FrameCount - 1);
                // Get the line number from the stack frame
                var line = frame.GetFileLineNumber();
                return("DTC search, line " + line + ": " + ex.Message);
            }
            return("");
        }
Example #2
0
        public void importDTC(PcmFile PCM, ref List <TableData> tdList)
        {
            if (PCM.dtcCodes.Count == 0)
            {
                DtcSearch DS = new DtcSearch();
                Logger(DS.searchDtc(PCM));
            }
            if (PCM.dtcCodes.Count == 0)
            {
                return;
            }
            TableData dtcTd = new TableData();
            dtcCode   dtc   = PCM.dtcCodes[0];

            dtcTd.Origin   = "seek";
            dtcTd.addrInt  = dtc.statusAddrInt;
            dtcTd.Category = "DTC";
            dtcTd.Columns  = 1;
            //td.Floating = false;
            dtcTd.OutputType = OutDataType.Int;
            dtcTd.Decimals   = 0;
            dtcTd.DataType   = InDataType.UBYTE;
            dtcTd.Math       = "X";
            dtcTd.OS         = PCM.OS;
            for (int i = 0; i < PCM.dtcCodes.Count; i++)
            {
                dtcTd.RowHeaders += PCM.dtcCodes[i].Code + ",";
            }
            dtcTd.RowHeaders = dtcTd.RowHeaders.Trim(',');
            dtcTd.Rows       = (ushort)PCM.dtcCodes.Count;
            //dtcTd.SavingMath = "X";
            if (PCM.dtcCombined)
            {
                //td.TableDescription = "00 MIL and reporting off, 01 type A/no mil, 02 type B/no mil, 03 type C/no mil, 04 not reported/mil, 05 type A/mil, 06 type B/mil, 07 type c/mil";
                dtcTd.Values    = "Enum: 00:MIL and reporting off,01:type A/no mil,02:type B/no mil,03:type C/no mil,04:not reported/mil,05:type A/mil,06:type B/mil,07:type c/mil";
                dtcTd.TableName = "DTC";
            }
            else
            {
                //td.TableDescription = "0 = 1 Trip, Emissions Related (MIL will illuminate IMMEDIATELY), 1 = 2 Trips, Emissions Related (MIL will illuminate if the DTC is active for two consecutive drive cycles), 2 = Non Emssions (MIL will NOT be illuminated, but the PCM will store the DTC), 3 = Not Reported (the DTC test/algorithm is NOT functional, i.e. the DTC is Disabled)";
                dtcTd.Values    = "Enum: 0:1 Trip (MIL IMMEDIATELY),1:2 Trips (MIL if DTC active two drive cycles),2:(No MIL store DTC),3:Not Reported (DTC Disabled)";
                dtcTd.TableName = "DTC.Codes";
            }

            tdList.Insert(0, dtcTd);

            if (!PCM.dtcCombined)
            {
                dtcTd           = new TableData();
                dtcTd.TableName = "DTC.MIL_Enable";
                dtcTd.addrInt   = dtc.milAddrInt;
                dtcTd.Category  = "DTC";
                dtcTd.Origin    = "seek";
                //td.ColumnHeaders = "MIL";
                dtcTd.Columns    = 1;
                dtcTd.OutputType = OutDataType.Flag;
                dtcTd.Decimals   = 0;
                dtcTd.DataType   = InDataType.UBYTE;
                dtcTd.Math       = "X";
                dtcTd.OS         = PCM.OS;
                for (int i = 0; i < PCM.dtcCodes.Count; i++)
                {
                    dtcTd.RowHeaders += PCM.dtcCodes[i].Code + ",";
                }
                dtcTd.RowHeaders = dtcTd.RowHeaders.Trim(',');
                dtcTd.Rows       = (ushort)PCM.dtcCodes.Count;
                //dtcTd.SavingMath = "X";
                //td.Signed = false;
                dtcTd.TableDescription = "0 = No MIL (Lamp always off) 1 = MIL (Lamp may be commanded on by PCM)";
                //td.Values = "Enum: 0:No MIL (Lamp always off),1:MIL (Lamp may be commanded on by PCM)";
                tdList.Insert(1, dtcTd);
            }
            if (!PCM.tableCategories.Contains("DTC"))
            {
                PCM.tableCategories.Add("DTC");
            }
        }
Example #3
0
        public string searchDtc(PcmFile PCM)
        {
            try
            {
                loadOBD2Codes();
                //Search DTC codes:
                uint   codeAddr = uint.MaxValue;
                string searchStr;
                int    configIndex = 0;
                uint   startAddr   = 0;
                PCM.dtcCombined = false;
                bool condOffset = false;
                uint statusAddr = uint.MaxValue;
                uint milAddr    = uint.MaxValue;

                for (configIndex = 0; configIndex < dtcSearchConfigs.Count; configIndex++)
                {
                    if (PCM.configFile == dtcSearchConfigs[configIndex].XMLFile.ToLower())
                    {
                        searchStr  = dtcSearchConfigs[configIndex].CodeSearch;
                        startAddr  = 0;
                        condOffset = false;
                        if (dtcSearchConfigs[configIndex].ConditionalOffset.Contains("code"))
                        {
                            condOffset = true;
                        }
                        codeAddr = getAddrbySearchString(PCM, searchStr, ref startAddr, PCM.fsize, condOffset).Addr;
                        //Check if we found status table, too:
                        startAddr  = 0;
                        condOffset = false;
                        if (dtcSearchConfigs[configIndex].ConditionalOffset.Contains("status"))
                        {
                            condOffset = true;
                        }
                        statusAddr = getAddrbySearchString(PCM, dtcSearchConfigs[configIndex].StatusSearch, ref startAddr, PCM.fsize, condOffset).Addr;
                        if (codeAddr < PCM.fsize && statusAddr < PCM.fsize)
                        {
                            Debug.WriteLine("Code search string: " + searchStr);
                            Debug.WriteLine("DTC code table address: " + codeAddr.ToString("X"));
                            codeAddr = (uint)(codeAddr + dtcSearchConfigs[configIndex].CodeOffset);
                            if (PCM.buf[codeAddr] > 0x10 && dtcSearchConfigs[configIndex].ConditionalOffset.Contains("code"))
                            {
                                codeAddr += 0x10000; //HACK: Don't know when should use -0x10000 offset, check if first PID is < 0x10
                            }
                            statusAddr = (uint)(statusAddr + dtcSearchConfigs[configIndex].StatusOffset);
                            Debug.WriteLine("DTC status table address: " + statusAddr.ToString("X"));
                            break;
                        }
                        else
                        {
                            codeAddr = 0;
                        }
                    }
                }

                if (codeAddr == uint.MaxValue)
                {
                    if (PCM.configFile == "e38" || PCM.configFile == "e67")
                    {
                        PCM.dtcCombined = true;
                        string retval = SearchDtcE38(PCM);
                        return(retval);
                    }
                    return("DTC search: can't find DTC code table");
                }

                //Read codes:
                bool dCodes = false;
                for (uint addr = codeAddr; addr < PCM.fsize; addr += (uint)dtcSearchConfigs[configIndex].CodeSteps)
                {
                    dtcCode dtc = new dtcCode();
                    dtc.codeAddrInt = addr;
                    dtc.CodeAddr    = addr.ToString("X8");
                    dtc.codeInt     = BEToUint16(PCM.buf, addr);

                    string codeTmp = dtc.codeInt.ToString("X");
                    if (dCodes && !codeTmp.StartsWith("D") || (dtc.codeInt < 10 && PCM.dtcCodes.Count > 10))
                    {
                        break;
                    }
                    codeTmp  = dtc.codeInt.ToString("X4");
                    dtc.Code = decodeDTC(codeTmp);
                    if (codeTmp.StartsWith("D"))
                    {
                        dCodes = true;
                    }
                    //Find description for code:
                    dtc.Description = getDtcDescription(dtc.Code);
                    PCM.dtcCodes.Add(dtc);
                }

                List <uint> milAddrList = new List <uint>();

                if (dtcSearchConfigs[configIndex].MilTable == "afterstatus")
                {
                    milAddr = (uint)(statusAddr + PCM.dtcCodes.Count + (uint)dtcSearchConfigs[configIndex].MilOffset);
                    if (PCM.configFile == "p01-p59" && PCM.buf[milAddr - 1] == 0xFF)
                    {
                        milAddr++;                                                              //P59 hack: If there is FF before first byte, skip first byte
                    }
                    milAddrList.Add(milAddr);
                }
                else if (dtcSearchConfigs[configIndex].MilTable == "combined")
                {
                    //Do nothing for now
                    milAddr = 0;
                    milAddrList.Add(milAddr);
                    PCM.dtcCombined = true;
                }
                else
                {
                    //Search MIL table
                    startAddr = 0;
                    for (int i = 0; i < 30; i++)
                    {
                        condOffset = false;
                        if (dtcSearchConfigs[configIndex].ConditionalOffset.Contains("mil"))
                        {
                            condOffset = true;
                        }
                        milAddr = getAddrbySearchString(PCM, dtcSearchConfigs[configIndex].MilSearch, ref startAddr, PCM.fsize, condOffset).Addr;
                        if (milAddr < uint.MaxValue)
                        {
                            milAddr += (uint)dtcSearchConfigs[configIndex].MilOffset;
                            if (milAddr < PCM.fsize) //Hit
                            {
                                milAddrList.Add(milAddr);
                                //break;
                            }
                        }
                        else
                        {
                            //Not found
                            break;
                        }
                    }
                }


                if (milAddrList.Count > 1)
                {
                    //IF have multiple hits for search, use table which starts after FF, ends before FF
                    for (int m = 0; m < milAddrList.Count; m++)
                    {
                        Debug.WriteLine("MIL Start: " + (milAddrList[m] - 1).ToString("X"));
                        Debug.WriteLine("MIL End: " + (milAddrList[m] + PCM.dtcCodes.Count).ToString("X"));
                        if (PCM.buf[milAddrList[m] - 2] == 0xFF && PCM.buf[milAddrList[m] + PCM.dtcCodes.Count] == 0xFF)
                        {
                            milAddr = milAddrList[m];
                            break;
                        }
                    }
                    if (milAddr == uint.MaxValue)
                    {
                        //We didn't found it, use first from list
                        milAddr = milAddrList[0];
                    }
                }
                else
                {
                    milAddr = milAddrList[0];
                }
                Debug.WriteLine("MIL: " + milAddr.ToString("X"));
                if (milAddr >= PCM.fsize)
                {
                    return("DTC search: MIL table address out of address range:" + milAddr.ToString("X8"));
                }

                //Read DTC status bytes:
                int  dtcNr = 0;
                uint addr3 = milAddr;
                for (uint addr2 = statusAddr; dtcNr < PCM.dtcCodes.Count; addr2 += (uint)dtcSearchConfigs[configIndex].StatusSteps, addr3 += (uint)dtcSearchConfigs[configIndex].MilSteps)
                {
                    if (PCM.buf[addr2] > 7)
                    {
                        break;
                    }
                    if (!PCM.dtcCombined && PCM.buf[addr2] > 3) //DTC = 0-3
                    {
                        break;
                    }
                    dtcCode dtc = PCM.dtcCodes[dtcNr];
                    dtc.statusAddrInt = addr2;
                    //dtc.StatusAddr = addr2.ToString("X8");
                    byte statusByte = PCM.buf[addr2];
                    dtc.Status = statusByte;

                    if (PCM.dtcCombined)
                    {
                        dtc.StatusTxt = dtcStatusCombined[dtc.Status];
                        if (statusByte > 4)
                        {
                            dtc.MilStatus = 1;
                        }
                        else
                        {
                            dtc.MilStatus = 0;
                        }
                    }
                    else
                    {
                        dtc.StatusTxt = dtcStatus[dtc.Status];
                        //Read MIL bytes:
                        dtc.milAddrInt = addr3;
                        dtc.MilAddr    = addr3.ToString("X8");
                        dtc.MilStatus  = PCM.buf[addr3];
                    }
                    PCM.dtcCodes.RemoveAt(dtcNr);
                    PCM.dtcCodes.Insert(dtcNr, dtc);
                    dtcNr++;
                }
            }
            catch (Exception ex)
            {
                var st = new StackTrace(ex, true);
                // Get the top stack frame
                var frame = st.GetFrame(st.FrameCount - 1);
                // Get the line number from the stack frame
                var line = frame.GetFileLineNumber();
                return("DTC search, line " + line + ": " + ex.Message);
            }
            return("");
        }