예제 #1
0
        /// <summary>
        /// Programs the flash in the ECU by sending a BIN file in pieces to the bootloader running in the ECUs SRAM
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public bool ProgramFlashBin(string filename, ECUType type)
        {
            // if can connection is available, upload the bootloader
            // now upload all the records in the S19 bootloader file

            // if all else fails, revert back to S19 files, so convert the bin to S19 and program that
            // with ProgramFlash function!

            FileInfo fi = new FileInfo(filename);

            using (FileStream fs = File.OpenRead(filename))
            {
                CastInfoEvent("Start upload of new program...", ActivityType.StartFlashing);
                int start = (type == ECUType.T52ECU) ? 0x60000 : 0x40000;
                int bytesread = 0;
                while ((start + bytesread) < 0x80000)
                {
                    // read a section of 0x80 bytes from the BIN file and keep it in a buffer to send to the T5 ECU
                    byte[] bytes = new byte[0x80];
                    // something has gone wrong if we cannot read another 0x80 bytes!!
                    if (fs.Read(bytes, 0,/*bytesread,*/ 0x80) != 0x80) //<GS-22092010> parameter error!
                    {
                        string BytesSoFar = bytesread.ToString("X6");
                        CastInfoEvent("Reading the BIN File Failed after: 0x" + BytesSoFar + " Bytes !!!", ActivityType.UploadingFlash);
                        return false;
                    }
                    // send a bootloader address message
                    byte[] result = sendBootloaderAddressCommand((start + bytesread), 0x80);
                    //DEBUG ONLY
                    //string extraInfo = string.Empty;
                    //foreach (byte b in result)
                    //{
                    //    extraInfo += b.ToString("X2") + " ";
                    //}
                    //CastInfoEvent("send address A5 command: " + extraInfo, ActivityType.UploadingFlash);
                    //DEBUG ONLY
                    bytesread += 0x80;
                    byte[] dataframe = new byte[8];

                    // Construct and send the bootloader frames
                    // NOTE the last frame sent may have less than 7 real data bytes but 7 bytes are always sent. In this case the unnecessary bytes
                    // are repeated from the previous frame. This is OK because the T5 ECU knows how many bytes to expect (because the count of bytes
                    // in the S-Record is sent with the upload address) and ignores any extra bytes in the last frame.
                    for (int i = 0; i < 0x80; i++)
                    {
                        // set the index number
                        if (i % 7 == 0)
                            dataframe.SetValue((byte)(i), 0);
                        // put bytes them in the dataframe!
                        dataframe.SetValue(bytes[i], (i % 7) + 1);
                        // send a bootloader frame whenever 7 bytes or a block of 0x80 bytes have been read from the BIN file
                        if ((i % 7 == 6) || (i == 0x80 - 1))
                        {
                            byte[] result2 = sendBootloaderDataCommand(dataframe, 8);
                            //DEBUG ONLY
                            //string extraInfo = string.Empty;
                            //foreach (byte b in result2)
                            //{
                            //    extraInfo += b.ToString("X2") + " ";
                            //}
                            //CastInfoEvent("send data command: " + extraInfo, ActivityType.UploadingFlash);
                            //DEBUG ONLY
                            if ((byte)result2.GetValue(6) != 0x00)
                            {
                                string BytesSoFar = bytesread.ToString("X6");
                                CastInfoEvent("FLASHing Failed after: 0x" + BytesSoFar + " Bytes !!!", ActivityType.UploadingFlash);
                                return false;
                            }
                        }
                        // show progress information
                    }
                    int prgs = (type == ECUType.T52ECU) ? ((bytesread * 100) / 0x20000) : ((bytesread * 100) / 0x40000);
                    CastProgressWriteEvent(prgs);
                    CastBytesTransmitted(bytesread);
                    //
                    // Rewind to start of file if FLASHing a T5.2 BIN file to A T5.5 ECU
                    // to FLASH 2 copies of the BIN File to T5.5's larger FLASH chips
                    //
                    if ((type != ECUType.T52ECU) && (bytesread == 0x20000) && (fi.Length == 0x20000))
                    {
                        fs.Seek(0, SeekOrigin.Begin);
                    }
                }
                CastInfoEvent("Flash programming finished", ActivityType.FinishedFlashing);
            }
            return true;
        }
예제 #2
0
        private void getECUinfo()
        {
            statusActivity.Text = "getting Footer";
            byte[] footer    = t5can.getECUFooter();
            byte[] chiptypes = t5can.GetChipTypes();
            statusActivity.Text = "IDLE";
            string swversion = t5can.getIdentifierFromFooter(footer, ECUIdentifier.Dataname);
            string romoffset = t5can.getIdentifierFromFooter(footer, ECUIdentifier.ROMoffset);
            string checksum  = t5can.ReturnChecksum();

            statusSWVersion.Text = "SW Version: " + swversion;
            statusChecksum.Text  = "Checksum: " + checksum;
            // identify ECU
            string flashzize = "256 kB";

            switch (chiptypes[0])
            {
            case 0xB8:          // Intel/CSI/OnSemi 28F512
            case 0x25:          // AMD 28F512
                statusFLASHType.Text = "Type: 28F512";
                flashzize            = "128 kB";
                break;

            case 0x5D:          // Atmel 29C512
                statusFLASHType.Text = "Type: 29C512";
                flashzize            = "128 kB";
                break;

            case 0xB4:          // Intel/CSI/OnSemi 28F010
            case 0xA7:          // AMD 28F010
                statusFLASHType.Text = "Type: 28F010";
                break;

            case 0x20:          // AMD/ST 29F010
            case 0xA4:          // AMIC 29F010
                statusFLASHType.Text = "Type: 29F010";
                break;

            case 0xD5:          // Atmel 29C010
                statusFLASHType.Text = "Type: 29C010";
                break;

            case 0xB5:          // SST 39F010
                statusFLASHType.Text = "Type: 39F010";
                break;

            default:
                statusFLASHType.Text = "Type: 0x" + chiptypes[0].ToString("X2") + " - Unknown";
                flashzize            = "Unknown";
                break;
            }
            statusFLASHSize.Text = "Size: " + flashzize;
            switch (chiptypes[1])
            {
            case 0x89:          // Intel
                statusFLASHMake.Text = "Make: Intel";
                break;

            case 0x01:          // AMD
                statusFLASHMake.Text = "Make: AMD/Spansion";
                break;

            case 0x31:          // CSI/OnSemi
                statusFLASHMake.Text = "Make: CSI";
                break;

            case 0x1F:          // Atmel
                statusFLASHMake.Text = "Make: Atmel";
                break;

            case 0xBF:          // SST/Microchip
                statusFLASHMake.Text = "Make: SST/Microchip";
                break;

            case 0x20:          // ST
                statusFLASHMake.Text = "Make: ST Microelectronics";
                break;

            case 0x37:          // AMIC
                statusFLASHMake.Text = "Make: AMIC";
                break;

            default:
                statusFLASHMake.Text = "Make: 0x" + chiptypes[1].ToString("X2") + " - Unknown";
                break;
            }
            switch (flashzize)
            {
            case "128 kB":
                switch (romoffset)
                {
                case "060000":
                    ECU_type       = ECUType.T52ECU;
                    statusECU.Text = "ECU Type: Trionic 5.2";
                    AddToLog("This is a Trionic 5.2 ECU with 128 kB of FLASH");
                    break;

                default:
                    ECU_type       = ECUType.Unknown;
                    statusECU.Text = "ECU Type: Unknown";
                    AddToLog("!!! ERROR !!! This type of ECU is unknown");
                    break;
                }
                break;

            case "256 kB":
                switch (romoffset)
                {
                case "040000":
                    ECU_type       = ECUType.T55ECU;
                    statusECU.Text = "ECU Type: Trionic 5.5";
                    AddToLog("This is a Trionic 5.5 ECU with 256 kB of FLASH");
                    break;

                case "060000":
                    ECU_type       = ECUType.T55AST52;
                    statusECU.Text = "ECU Type: T5.5 as T5.2";
                    AddToLog("This is a Trionic 5.5 ECU with a T5.2 BIN");
                    break;

                default:
                    ECU_type       = ECUType.Unknown;
                    statusECU.Text = "ECU Type: Unknown";
                    AddToLog("!!! ERROR !!! This type of ECU is unknown");
                    break;
                }
                break;

            default:
                ECU_type       = ECUType.Unknown;
                statusECU.Text = "ECU Type: Unknown";
                AddToLog("!!! ERROR !!! This type of ECU is unknown");
                break;
            }
            AddToLog("Part Number: " + t5can.getIdentifierFromFooter(footer, ECUIdentifier.Partnumber));
            AddToLog("Software ID: " + t5can.getIdentifierFromFooter(footer, ECUIdentifier.SoftwareID));
            AddToLog("SW Version: " + swversion);
            AddToLog("Engine Type: " + t5can.getIdentifierFromFooter(footer, ECUIdentifier.EngineType));
            AddToLog("IMMO Code: " + t5can.getIdentifierFromFooter(footer, ECUIdentifier.ImmoCode));
            AddToLog("Other Info: " + t5can.getIdentifierFromFooter(footer, ECUIdentifier.Unknown));
            AddToLog("ROM Start: 0x" + romoffset);
            AddToLog("Code End: 0x" + t5can.getIdentifierFromFooter(footer, ECUIdentifier.CodeEnd));
            AddToLog("ROM End: 0x" + t5can.getIdentifierFromFooter(footer, ECUIdentifier.ROMend));
            AddToLog("Checksum: " + checksum);
        }
예제 #3
0
 /// <summary>
 /// Gets the checksum from the ECU, dumps it to the console and tries to get the ECU out of the bootloader routine
 /// </summary>
 /// <param name="type"></param>
 /// <param name="path"></param>
 public void GetChecksumWithBootloader(ECUType type, string path)
 {
     UploadBootLoader();
     DumpChecksum();
     sendC2Command();
 }
예제 #4
0
        /// <summary>
        /// Programs the flash in the ECU by sending the S19 file in pieces to the bootloader running in the ECUs SRAM
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public bool ProgramFlash(string filename, ECUType type)
        {
            // if can connection is available, upload the bootloader
            // now upload all the records in the S19 bootloader file
            FileInfo fi = new FileInfo(filename);

            using (StreamReader sr = new StreamReader(filename))
            {
                string line = string.Empty;
                int bytestransmitted = 0;
                int bytesread = 0;
                while ((line = sr.ReadLine()) != null)
                {
                    bytesread += line.Length + 2;
                    if (line.StartsWith("S0"))
                    {
                        //if (!BinaryReflection.IsAppDebugMode(Application.ExecutablePath))
                        {
                            // maybe not necessary t5can.sendBootloaderAddressCommand(0, 0);
                        }
                       // AddToLog("Starting upload of new flash");
                        CastInfoEvent("Start upload of new program...", ActivityType.StartFlashing);
                    }
                    else if (line.StartsWith("S2"))
                    {
                        int len = Convert.ToInt32(line.Substring(2, 2), 16);
                        byte[] data = new byte[len - 4]; // substract address (3 bytes) and checksum (1 byte)
                        Int32 address = Convert.ToInt32(line.Substring(4, 6), 16);
                        // add flash start offset address
                        address += ((type == ECUType.T52ECU)) ? 0x60000 : 0x40000;
                        for (int t = 0; t < len - 4; t++)
                        {
                            int bytevalue = Convert.ToInt32(line.Substring((t * 2) + 10, 2), 16);
                            data.SetValue((byte)bytevalue, t);
                        }
                        int framecount = 1 + (len - 4) / 7;
                        int bytessent = 0;
                        sendBootloaderAddressCommand(address, (byte)(len - 4));

                        /** option 1 **/
                        for (int frame = 0; frame < framecount; frame++)
                        {
                            byte[] dataframe = new byte[8];
                            dataframe.SetValue((byte)(frame * 7), 0);
                            for (int bcnt = 0; bcnt < 7; bcnt++)
                            {
                                byte currbyte = 0;
                                if (bytessent < data.Length) currbyte = (byte)data.GetValue(bytessent);
                                bytessent++;
                                dataframe.SetValue(currbyte, bcnt + 1);
                            }
                            sendBootloaderDataCommand(dataframe, 8);
                        }
                        /** end option 1 **/

                        /** option 2 **/
                        /*for (int frame = 0; frame < framecount; frame++)
                        {
                            int dtlen = data.Length - bytessent;
                            if (dtlen > 7) dtlen = 7;
                            t5can.sendBootloaderAddressCommand(address, (byte)dtlen);
                            byte[] dataframe = new byte[8];
                            int bscnt = 0;
                            for (int bcnt = 0; bcnt < 7; bcnt++)
                            {
                                byte currbyte = 0;
                                if (bytessent < data.Length)
                                {
                                    currbyte = (byte)data.GetValue(bytessent);
                                    bscnt++;
                                }
                                bytessent++;
                                dataframe.SetValue(currbyte, bcnt + 1);
                            }
                            dataframe.SetValue((byte)(bscnt), 0);
                            t5can.sendBootloaderDataCommand(dataframe, 8);
                            address += 7; // last one don't care because it will be recalculated
                            //Thread.Sleep(10);
                        }
                        */
                        /** end option 2 **/
                        bytestransmitted += (len - 4);
                        int prgs = (bytesread * 100) / (int)fi.Length;
                        CastProgressWriteEvent(prgs);
                        CastBytesTransmitted(bytestransmitted);

                    }
                    else if (line.StartsWith("S8"))
                    {
                        // terminate session with boot vector address to run SRAM from
                        // S8040060C4D7
                        //int address = Convert.ToInt32(line.Substring(4, 6), 16);
                        // C1 00 00 60 C4 00 00 06
                        //t5can.sendBootVectorAddressSRAM(address);
                        //Thread.Sleep(500);
                        //DumpChecksum();
                        //Thread.Sleep(100);
                        CastInfoEvent("Flash programming finished", ActivityType.FinishedFlashing);
                    }
                    else
                    {
                        //AddToLog("Unknown S record seen: " + line);

                    }
                }
            }
            //progressBar1.Value = 0; // reset
            //sendC2Command(); // reset ECU
            return true;
        }
예제 #5
0
        /// <summary>
        /// Dumps the flash contents of a ECU to a binary file. Be sure to pass the correct ECUType
        /// </summary>
        /// <param name="flashfile"></param>
        /// <param name="type"></param>
        public void DumpECU(string flashfile, ECUType type)
        {
            // set FLASH chip start address and length according to ECUType
            UInt32 start = (type == ECUType.T55ECU) ? (UInt32)0x40000 : (UInt32)0x60000;
            UInt32 length = (type == ECUType.T55ECU) ? (UInt32)0x40000 : (UInt32)0x20000;
            byte[] buffer = new byte[length];

            Console.WriteLine("Start ECU dump");
            string path = Path.GetDirectoryName(flashfile);
            Console.WriteLine("Path = " + path);
            CastInfoEvent("Downloading flash from ECU", ActivityType.StartDownloadingFlash);
            //TODO: hier het aantal keren dat gelezen moet worden nog aanpassen aan het ECUType
            //TODO: specify the times that must be read even adjust the ECUType
            byte[] buffer2 = new byte[6];
            UInt32 address = (start + 5);
            for (int i = 0; i < (length / 6); i++)
            {
                buffer2 = this.sendReadCommand(address);
                address += 6;
                for (int j = 0; j < 6; j++)
                    buffer[(i * 6) + j] = buffer2[j];
                CastProgressWriteEvent((int)((i * 600) / length));
                CastBytesTransmitted((int)(address - (start + 5)));
            }
            // Mop up the last few bytes if not an exact multiple of 6
            // It has to be done this way because the T5 ECU resets if
            // you try to read past the end of the FLASH addresses
            if ((length % 6) > 0)
            {
                buffer2 = this.sendReadCommand(start + length - 1);
                for (int j = (int)(6 - (length % 6)); j < 6; j++)
                    buffer[length - 6 + j] = buffer2[j];
            }
            CastInfoEvent("Finished downloading flash from ECU", ActivityType.FinishedDownloadingFlash);
            CastProgressWriteEvent(100);
            CastBytesTransmitted((int)length);
            //DownloadFlashContent();
            FileStream fs = new FileStream(flashfile, FileMode.Create);
            using (BinaryWriter bw = new BinaryWriter(fs))
            {
                bw.Write(buffer);
            }
            fs.Close();
            fs.Dispose();
        }
예제 #6
0
 public ChecksumResult VerifyECU(ECUType ecutype, string path)
 {
     ChecksumResult result = ChecksumResult.Valid;
     UploadBootLoader();
     //                DumpChecksum();
     if (!VerifyChecksum())
     {
         result = ChecksumResult.Invalid;
     }
     ExitBootloader();
     return result;
 }
예제 #7
0
        /// <summary>
        /// Upgrades the ECU with the given file. Be sure to pass the right ECUType 
        /// </summary>
        /// <param name="flashfile"></param>
        /// <param name="ecutype"></param>
        public UpgradeResult UpgradeECU(string flashfile, ECUType ecutype)
        {
            UpgradeResult result = UpgradeResult.Success;
            string path = Path.GetDirectoryName(flashfile);
            //ecutype = DetermineConnectedECUType(); //<GS-22032011> Does not matter anymore what ECUtype is in the box?
            // hier nog controleren of de lengte van de bin wel past bij het ECUType
            FileInfo fi = new FileInfo(flashfile);
            switch (ecutype)
            {
                case ECUType.T52ECU:
                    if (fi.Length != 0x20000) return UpgradeResult.InvalidFile;
                    break;
                case ECUType.T55ECU:
                case ECUType.T55AST52:
                    if ((fi.Length != 0x20000) && (fi.Length != 0x40000)) return UpgradeResult.InvalidFile;
                    //if (fi.Length != 0x40000) return UpgradeResult.InvalidFile;
                    break;
                default:
                    return UpgradeResult.InvalidFile;
            }
            if (!EraseFlash())
            {
                return UpgradeResult.EraseFailed;
            }
            if (!ProgramFlashBin(flashfile, ecutype))
            {
                return UpgradeResult.ProgrammingFailed;
            }
            if (!VerifyChecksum())
            {
                result = UpgradeResult.ChecksumFailed;
            }
            CastProgressWriteEvent(100);

            return result;
        }
예제 #8
0
        /// <summary>
        /// Upgrades the ECU with the given file. Be sure to pass the right ECUType 
        /// </summary>
        /// <param name="bootloaderfile"></param>
        /// <param name="flashfile"></param>
        /// <param name="filetype"></param>
        /// <param name="ecutype"></param>
        public UpgradeResult UpgradeECU(string flashfile, FileType filetype, ECUType ecutype)
        {
            UpgradeResult result = UpgradeResult.Success;
            string path = Path.GetDirectoryName(flashfile);
            //ecutype = DetermineConnectedECUType(); //<GS-22032011> Does not matter anymore what ECUtype is in the box?
            // hier nog controleren of de lengte van de bin wel past bij het ECUType
            FileInfo fi = new FileInfo(flashfile);
            if (ecutype == ECUType.T52ECU)
            {
                if (fi.Length != 0x20000) return UpgradeResult.InvalidFile;
            }
            else
            {
                if (fi.Length != 0x40000) return UpgradeResult.InvalidFile;
            }
            if (ecutype == ECUType.Autodetect || ecutype == ECUType.Unknown)
            {
                return UpgradeResult.InvalidECUType;
            }

            /*if (isT52ECU())
            {
                ecutype = ECUType.T52ECU;
            }*/
            //CastInfoEvent("Created bootloader: " + bootloader, ActivityType.ConvertingFile);
            UploadBootLoader();
            //DumpChecksum();
            VerifyChecksum();
            if (!EraseFlash())
            {
                return UpgradeResult.EraseFailed;
            }
            if (filetype == FileType.BinaryFile)
            {
                if (!ProgramFlashBin(flashfile, ecutype))
                {
                    return UpgradeResult.ProgrammingFailed;
                }
            }
            else
                ProgramFlash(flashfile, ecutype);

            if (!VerifyChecksum())
            {
                result = UpgradeResult.ChecksumFailed;
            }
            ExitBootloader();
            CastProgressWriteEvent(100);

            return result;
        }
예제 #9
0
 private void getECUinfo()
 {
     statusActivity.Text = "getting Footer";
     byte[] footer = t5can.getECUFooter();
     byte[] chiptypes = t5can.GetChipTypes();
     statusActivity.Text = "IDLE";
     string swversion = t5can.getIdentifierFromFooter(footer, ECUIdentifier.Dataname);
     string romoffset = t5can.getIdentifierFromFooter(footer, ECUIdentifier.ROMoffset);
     string checksum = t5can.ReturnChecksum();
     statusSWVersion.Text = "SW Version: " + swversion;
     statusChecksum.Text = "Checksum: " + checksum;
     // identify ECU
     string flashzize = "256 kB";
     switch (chiptypes[0])
     {
         case 0xB8:      // Intel/CSI/OnSemi 28F512
         case 0x25:      // AMD 28F512
             statusFLASHType.Text = "Type: 28F512";
             flashzize = "128 kB";
             break;
         case 0x5D:      // Atmel 29C512
             statusFLASHType.Text = "Type: 29C512";
             flashzize = "128 kB";
             break;
         case 0xB4:      // Intel/CSI/OnSemi 28F010
         case 0xA7:      // AMD 28F010
             statusFLASHType.Text = "Type: 28F010";
             break;
         case 0x20:      // AMD/ST 29F010
         case 0xA4:      // AMIC 29F010
             statusFLASHType.Text = "Type: 29F010";
             break;
         case 0xD5:      // Atmel 29C010
             statusFLASHType.Text = "Type: 29C010";
             break;
         case 0xB5:      // SST 39F010
             statusFLASHType.Text = "Type: 39F010";
             break;
         default:
             statusFLASHType.Text = "Type: 0x" + chiptypes[0].ToString("X2") + " - Unknown";
             flashzize = "Unknown";
             break;
     }
     statusFLASHSize.Text = "Size: " + flashzize;
     switch (chiptypes[1])
     {
         case 0x89:      // Intel
             statusFLASHMake.Text = "Make: Intel";
             break;
         case 0x01:      // AMD
             statusFLASHMake.Text = "Make: AMD/Spansion";
             break;
         case 0x31:      // CSI/OnSemi
             statusFLASHMake.Text = "Make: CSI";
             break;
         case 0x1F:      // Atmel
             statusFLASHMake.Text = "Make: Atmel";
             break;
         case 0xBF:      // SST/Microchip
             statusFLASHMake.Text = "Make: SST/Microchip";
             break;
         case 0x20:      // ST
             statusFLASHMake.Text = "Make: ST Microelectronics";
             break;
         case 0x37:      // AMIC
             statusFLASHMake.Text = "Make: AMIC";
             break;
         default:
             statusFLASHMake.Text = "Make: 0x" + chiptypes[1].ToString("X2") + " - Unknown";
             break;
     }
     switch (flashzize)
     {
         case "128 kB":
             switch (romoffset)
             {
                 case "060000":
                     ECU_type = ECUType.T52ECU;
                     statusECU.Text = "ECU Type: Trionic 5.2";
                     AddToLog("This is a Trionic 5.2 ECU with 128 kB of FLASH");
                     break;
                 default:
                     ECU_type = ECUType.Unknown;
                     statusECU.Text = "ECU Type: Unknown";
                     AddToLog("!!! ERROR !!! This type of ECU is unknown");
                     break;
             }
             break;
         case "256 kB":
             switch (romoffset)
             {
                 case "040000":
                     ECU_type = ECUType.T55ECU;
                     statusECU.Text = "ECU Type: Trionic 5.5";
                     AddToLog("This is a Trionic 5.5 ECU with 256 kB of FLASH");
                     break;
                 case "060000":
                     ECU_type = ECUType.T55AST52;
                     statusECU.Text = "ECU Type: T5.5 as T5.2";
                     AddToLog("This is a Trionic 5.5 ECU with a T5.2 BIN");
                     break;
                 default:
                     ECU_type = ECUType.Unknown;
                     statusECU.Text = "ECU Type: Unknown";
                     AddToLog("!!! ERROR !!! This type of ECU is unknown");
                     break;
             }
             break;
         default:
             ECU_type = ECUType.Unknown;
             statusECU.Text = "ECU Type: Unknown";
             AddToLog("!!! ERROR !!! This type of ECU is unknown");
             break;
     }
     AddToLog("Part Number: " + t5can.getIdentifierFromFooter(footer, ECUIdentifier.Partnumber));
     AddToLog("Software ID: " + t5can.getIdentifierFromFooter(footer, ECUIdentifier.SoftwareID));
     AddToLog("SW Version: " + swversion);
     AddToLog("Engine Type: " + t5can.getIdentifierFromFooter(footer, ECUIdentifier.EngineType));
     AddToLog("IMMO Code: " + t5can.getIdentifierFromFooter(footer, ECUIdentifier.ImmoCode));
     AddToLog("Other Info: " + t5can.getIdentifierFromFooter(footer, ECUIdentifier.Unknown));
     AddToLog("ROM Start: 0x" + romoffset);
     AddToLog("Code End: 0x" + t5can.getIdentifierFromFooter(footer, ECUIdentifier.CodeEnd));
     AddToLog("ROM End: 0x" + t5can.getIdentifierFromFooter(footer, ECUIdentifier.ROMend));
     AddToLog("Checksum: " + checksum);
 }