Ejemplo n.º 1
0
        private void ReadFileToBuffer(string filename)
        {
            var ext = Path.GetExtension(filename);

            this.Title = "GSM AVR Burner - " + Path.GetFileName(filename);
            if (ext == ".hex")
            {
                _flashBuffer = new IntelHex();
                _flashBuffer.Read(filename);
                AppendLog("Flash Buffer loaded..." + _flashBuffer.DataLength + " bytes");
                UpdateFlashBufferDisplay("");
                UpdateFlashBufferDisplay(ByteArrayToHexString(_flashBuffer.RawData));
            }
            else if (ext == ".eep")
            {
                _eepromBuffer = new IntelHex();
                _eepromBuffer.Read(filename);
                AppendLog("EEPROM Buffer loaded..." + _eepromBuffer.DataLength + " bytes");
                UpdateEepromBufferDisplay("");
                UpdateEepromBufferDisplay(ByteArrayToHexString(_eepromBuffer.RawData));
            }
            else if (ext == ".fuse")
            {
                ReadFuseFile(filename);
            }
            else
            {
                PopupError("Format Not Supported!");
            }
        }
Ejemplo n.º 2
0
        private void _ReloadFile()
        {
            StreamReader _sr = null;
            string       _tbv = string.Empty, _tbf = null;
            Color        _tbfb = Color.Black;
            bool         _bte  = false;

            try
            {
                _sr = new StreamReader(_filename); _intelhex = null;
                IntelHex _intelhex_new = new IntelHex(_sr);
                _intelhex_new.BuildData(_pagewidthshift + 1);
                byte[] _firmware_data = _intelhex_new.Data;
                if (_intelhex_new.DataAddressMin == 0 && _intelhex_new.Data[84] == 0x47 && _intelhex_new.Data[85] == 0x57)
                {
                    StringBuilder _sb = new StringBuilder();
                    for (int _i = 86; _i < _intelhex_new.DataAddressMax; _i++)
                    {
                        byte _b = _intelhex_new.Data[_i]; if (_b == 0)
                        {
                            break;
                        }
                        _sb.Append((char)(_b));
                    }

                    _tbv      = _sb.ToString();
                    _intelhex = _intelhex_new; _bte = true;
                }
                else
                {
                    _tbv = "<unrecognized>";
                }
                //for (int _i = 0; _i < _firmware_data.Length; _i += 2) { byte _t = _firmware_data[_i]; _firmware_data[_i] = _firmware_data[_i + 1]; _firmware_data[_i + 1] = _t; }
                _tbfb = SystemColors.Control;
            }
            catch (IOException ex) { _tbv = ex.Message; _tbfb = Color.Red; }
            finally { if (_sr != null)
                      {
                          _sr.Close();
                      }
            }
            Invoke((Action)(() =>
            {
                _tb_version.Text = _tbv; _tb_firmware.BackColor = _tbfb; _btn_program.Enabled = _bte;
                _tb_firmware.Text = _tbf != null ? _tbf : _filename;
            }));
        }
Ejemplo n.º 3
0
        private static void TestIntelHex(string fileName, byte[] data)
        {
            IntelHex     irec = new IntelHex();
            StreamWriter sw   = new StreamWriter(fileName);

            // Create a new type-0 record with data
            IntelHexStructure irecs = irec.NewRecord(0, 0, data, data.Length);

            irec.Write(sw);

            // Create another type-0 record with new data
            irec.NewRecord(0, 8, data, data.Length);
            irec.Write(sw);

            // Create another type-0 record with new data
            irec.NewRecord(0, 16, data, data.Length);
            irec.Write(sw);

            // Create an end of record type-1 record
            irec.NewRecord(1, 0, null, 0);
            irec.Write(sw);
            sw.Close();

            Console.WriteLine("Wrote Intel HEX formatted file: " + fileName);
            Console.WriteLine("Reading back Intel HEX file:");

            // Open up the new file and attempt to read the records and print to the console
            StreamReader sr = new StreamReader(fileName);

            irecs = irec.Read(sr);
            Console.WriteLine((irecs != null) ? irec.Print() : "Could not read record!");
            irecs = irec.Read(sr);
            Console.WriteLine((irecs != null) ? irec.Print() : "Could not read record!");
            irecs = irec.Read(sr);
            Console.WriteLine((irecs != null) ? irec.Print() : "Could not read record!");
            irecs = irec.Read(sr);
            Console.WriteLine((irecs != null) ? irec.Print() : "Could not read record!");
            sr.Close();
        }
Ejemplo n.º 4
0
 public static IntelHex Parse(string line)
 {
     try
     {
         if (string.IsNullOrWhiteSpace(line))
         {
             return(null);
         }
         line = line.Trim();
         if (line[0] != ':')
         {
             throw new AssembleException("需要以“:”作为起始");
         }
         var bytes = new List <byte>();
         for (int i = 1; i < line.Length; i += 2)
         {
             bytes.Add(Convert.ToByte(line.Substring(i, 2), 16));
         }
         var hex   = new IntelHex();
         int index = 0;
         hex.DataSize     = bytes[index++];
         hex.StartAddress = (ushort)(bytes[index++] << 8);
         hex.StartAddress = (ushort)(hex.StartAddress | bytes[index++]);
         hex.RecordType   = bytes[index++];
         hex.Data         = bytes.GetRange(index, hex.DataSize).ToArray();
         index           += hex.DataSize;
         hex.Checksum     = bytes[index++];
         if (index != bytes.Count)
         {
             throw new AssembleException("数据过多");
         }
         return(hex);
     }
     catch (IndexOutOfRangeException)
     {
         throw new AssembleException("数据过少");
     }
 }
Ejemplo n.º 5
0
        static void Main(string[] args)
        {
            string filePath  = null;
            string fileExt   = null;
            bool   help      = false;
            bool   isDfuFile = false;
            // Vendor and Product IDs are required, set them to invalid
            int vid = 0x10000, pid = 0x10000;
            // version is optional, FF means forced update
            int vmajor = 0xFF, vminor = 0xFF;

            // parameter parsing
            OptionSet optionSet = new OptionSet()
                                  .Add("?|help|h",
                                       "Prints out the options.", option => help = option != null)
                                  .Add("i|image=",
                                       "Path of the image file to download. Supported formats are DFU, Intel HEX and Motorola SREC.",
                                       option => filePath = option)
                                  .Add("d|device=",
                                       "USB Device Vendor and Product ID in XXXX:XXXX format. Ignored if the file format is DFU.",
                                       option =>
            {
                var result = UsbIdRegex.Match(option);
                if (!result.Success)
                {
                    help = true;
                }
                else
                {
                    vid = UInt16.Parse(result.Groups["vid"].Value, NumberStyles.HexNumber);
                    pid = UInt16.Parse(result.Groups["pid"].Value, NumberStyles.HexNumber);
                }
            })
                                  .Add("v|version=",
                                       "Firmware version in D.D format. Ignored if the file format is DFU.",
                                       option =>
            {
                var result = VersionRegex.Match(option);
                if (!result.Success)
                {
                    help = true;
                }
                else
                {
                    vmajor = Byte.Parse(result.Groups["major"].Value);
                    vminor = Byte.Parse(result.Groups["minor"].Value);
                }
            });

            try
            {
                // try to get required arguments
                optionSet.Parse(args);
                fileExt   = Path.GetExtension(filePath);
                isDfuFile = Dfu.IsExtensionSupported(fileExt);
                if (!isDfuFile && ((vid > 0xFFFF) || (pid > 0xFFFF)))
                {
                    help = true;
                }
            }
            catch (Exception)
            {
                help = true;
            }

            if (help)
            {
                // print help text and exit
                Console.Error.WriteLine("Usage:");
                optionSet.WriteOptionDescriptions(Console.Error);
                Environment.Exit(-1);
            }

            // DFU device event printers
            int prevCursor = -1;
            EventHandler <ProgressChangedEventArgs> printDownloadProgress = (obj, e) =>
            {
                if (prevCursor == Console.CursorTop)
                {
                    Console.SetCursorPosition(0, Console.CursorTop - 1);
                }
                Console.WriteLine("Download progress: {0}%", e.ProgressPercentage);
                prevCursor = Console.CursorTop;
            };
            EventHandler <ErrorEventArgs> printDevError = (obj, e) =>
            {
                Console.Error.WriteLine("The DFU device reported the following error: {0}", e.GetException().Message);
            };

            Device device = null;

            try
            {
                Version         fileVer     = new Version(vmajor, vminor);
                Dfu.FileContent dfuFileData = null;
                RawMemory       memory      = null;

                // find the matching file parser by extension
                if (isDfuFile)
                {
                    dfuFileData = Dfu.ParseFile(filePath);
                    Console.WriteLine("DFU image parsed successfully.");

                    // DFU file specifies VID, PID and version, so override any arguments
                    vid     = dfuFileData.DeviceInfo.VendorId;
                    pid     = dfuFileData.DeviceInfo.ProductId;
                    fileVer = dfuFileData.DeviceInfo.ProductVersion;
                }
                else if (IntelHex.IsExtensionSupported(fileExt))
                {
                    memory = IntelHex.ParseFile(filePath);
                    Console.WriteLine("Intel HEX image parsed successfully.");
                }
                else if (SRecord.IsExtensionSupported(fileExt))
                {
                    memory = SRecord.ParseFile(filePath);
                    Console.WriteLine("SRecord image parsed successfully.");
                }
                else
                {
                    throw new ArgumentException("Image file format not recognized.");
                }

                // find the DFU device
                device              = Device.OpenFirst(UsbDevice.AllDevices, vid, pid);
                device.DeviceError += printDevError;

                if (isDfuFile)
                {
                    // verify protocol version
                    if (dfuFileData.DeviceInfo.DfuVersion != device.DfuDescriptor.DfuVersion)
                    {
                        throw new InvalidOperationException(String.Format("DFU file version {0} doesn't match device DFU version {1}",
                                                                          dfuFileData.DeviceInfo.DfuVersion,
                                                                          device.DfuDescriptor.DfuVersion));
                    }
                }

                // if the device is in normal application mode, reconfigure it
                if (device.InAppMode())
                {
                    bool skipUpdate = fileVer <= device.Info.ProductVersion;

                    // skip update when it's deemed unnecessary
                    if (skipUpdate)
                    {
                        Console.WriteLine("The device is already up-to-date (version {0}), skipping update (version {1}).",
                                          device.Info.ProductVersion,
                                          fileVer);
                        return;
                    }

                    Console.WriteLine("Device found in application mode, reconfiguring device to DFU mode...");
                    device.Reconfigure();

                    // in case the device detached, we must find the DFU mode device
                    if (!device.IsOpen())
                    {
                        // clean up old device first
                        device.DeviceError -= printDevError;
                        device.Dispose();
                        device = null;

                        device              = Device.OpenFirst(UsbDevice.AllDevices, vid, pid);
                        device.DeviceError += printDevError;
                    }
                }
                else
                {
                    Console.WriteLine("Device found in DFU mode.");
                }

                // perform upgrade
                device.DownloadProgressChanged += printDownloadProgress;
                if (isDfuFile)
                {
                    device.DownloadFirmware(dfuFileData);
                }
                else
                {
                    device.DownloadFirmware(memory);
                }
                device.DownloadProgressChanged -= printDownloadProgress;

                Console.WriteLine("Download successful, manifesting update...");
                device.Manifest();

                // if the device detached, clean up
                if (!device.IsOpen())
                {
                    device.DeviceError -= printDevError;
                    device.Dispose();
                    device = null;
                }

                // TODO find device again to verify new version
                Console.WriteLine("The device has been successfully upgraded.");
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Device Firmware Upgrade failed with exception: {0}.", e.ToString());
                Environment.Exit(-1);
            }
            finally
            {
                if (device != null)
                {
                    device.Dispose();
                }
            }
        }
Ejemplo n.º 6
0
        private void _btn_program_Click(object sender, EventArgs e)
        {
            Thread _thread_program = new Thread(() =>
            {
                IntelHex _ihex = _intelhex;
                if (_ihex != null)
                {
                    uint _amin = _ihex.DataAddressMin, _amax = _ihex.DataAddressMax;
                    unchecked
                    {
                        byte[] _firmware_data = _ihex.Data;
                        Invoke((Action)(() => { _comport.PortName = (string)_cb_port.SelectedItem; }));
                        try
                        {
                            Invoke((Action)(() => { _pb_program.Minimum = (int)_amin; _pb_program.Maximum = (int)_amax; }));
                            _comport.Open();
                            _comport.Write("reset\r");
                            Thread.Sleep(300);
                            _comport.Write(new byte[] { 9 }, 0, 1);
                            Thread.Sleep(100);

                            WGSPResult _res = 0;
                            for (uint _addr = _amin; _addr < _amax; _addr += _pagesize)
                            {
                                Invoke((Action)(() => { _pb_program.Value = (int)_addr + (_pagesize >> 1); }));
                                ushort _page   = (ushort)(_addr >> (_pagewidthshift + 1));
                                ushort _chksum = 0;

                                for (int _i = 0; _i < (1 << _pagewidthshift); _i++)
                                {
                                    ushort _v = (ushort)(_firmware_data[_addr + (_i << 1) + 1] << 8);
                                    _v       |= (ushort)(_firmware_data[_addr + (_i << 1)]);
                                    _chksum   = (ushort)((_chksum ^ _v) * 40503);
                                }

                                string _str = string.Format("flash x{0:X},x{1:X}\r", _page, _chksum);
                                _comport.Write(_str); _comport.ReadTo(_str + "\n");

                                _comport.Write(_firmware_data, (int)_addr, _pagesize);

                                _res = (WGSPResult)_comport.ReadByte();
                                if (_res != 0)
                                {
                                    MessageBox.Show(string.Format("Error '{0}' when writing page {1} {2:X}", _res, _page, _chksum)); break;
                                }
                            }
                            bool _b_wgmode = false;
                            Invoke((Action)(() => { _b_wgmode = _cb_wgmode.Checked; }));
                            if (_b_wgmode)
                            {
                                _comport.ReadTo("bl>\\"); _comport.Write("wg\r");
                            }
                            _comport.Close();
                        }
                        catch (Exception ex) { MessageBox.Show(ex.Message); }
                        finally
                        {
                            Invoke((Action)(() => { _pb_program.Value = 0; _btn_program.Enabled = true; }));
                            if (_comport.IsOpen)
                            {
                                _comport.Close();
                            }
                        }
                    }
                }
            });

            _btn_program.Enabled = false; _thread_program.Start();
        }
Ejemplo n.º 7
0
        static void Main(string[] args)
        {
            AtmelGeneric generic;
            IntelHex     ihex;
            SRecord      srec;
            StreamReader sr = null;

            if (args.Length < 2)
            {
                Console.WriteLine("Usage: TestGIS_RecDump.exe <file format> <file>");
                Console.WriteLine("This program will print the records saved in a generic, Intel HEX, or Motorola\nS-Record formatted file.\n");
                Console.WriteLine("  <file format> can be generic, ihex, or srecord.");
                Console.WriteLine("  <file> is the path to the formatted object file.");
                Environment.Exit(-1);
            }

            try
            {
                sr = new StreamReader(args[1]);
            }
            catch (Exception e)
            {
                Console.WriteLine("Error opening file: " + e.Message);
                Environment.Exit(-1);
            }

            if (string.Compare(args[0], "generic") == 0)
            {
                generic = new AtmelGeneric();
                AtmelGenericStructure gen_s;
                while (true)
                {
                    gen_s = generic.Read(sr);
                    if (gen_s != null)
                    {
                        Console.WriteLine(generic.Print(true));
                    }
                    else
                    {
                        break;
                    }
                }
            }
            else if (string.Compare(args[0], "ihex") == 0)
            {
                ihex = new IntelHex();
                IntelHexStructure ihex_s;
                while (true)
                {
                    ihex_s = ihex.Read(sr);
                    if (ihex_s != null)
                    {
                        Console.WriteLine(ihex.Print(true));
                    }
                    else
                    {
                        break;
                    }
                }
            }
            else if (string.Compare(args[0], "srecord") == 0)
            {
                srec = new SRecord();
                SRecordStructure srec_s;
                while (true)
                {
                    srec_s = srec.Read(sr);
                    if (srec_s != null)
                    {
                        Console.WriteLine(srec.Print(true));
                    }
                    else
                    {
                        break;
                    }
                }
            }
            else
            {
                Console.WriteLine("Unknown file format specified!");
                sr.Close();
                Environment.Exit(-1);
            }

            sr.Close();
        }
Ejemplo n.º 8
0
        private void btnSelectFile_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog openFileDialog = new OpenFileDialog()
                {
                    Filter = "hex files (*.hex)|*.hex"
                };
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    txtSelectFile.Text = openFileDialog.FileName;

                    using (StreamReader reader = new StreamReader(openFileDialog.FileName))
                    {
                        IntelHex     intelHex  = new IntelHex();
                        var          data      = intelHex.GetDataSegment(reader);
                        List <Frame> frameList = new List <Frame>();

                        if (data != null && data.Length > 0)
                        {
                            int count = data.Length / LENGTH_FRAME;
                            if (data.Length % LENGTH_FRAME != 0)
                            {
                                count++;
                            }

                            for (int i = 0; i < count; i++)
                            {
                                Frame frame = new Frame()
                                {
                                    Code = Constants.Hx0A,
                                    Data = new byte[LENGTH_FRAME]
                                };

                                for (int j = 0; j < LENGTH_FRAME; j++)
                                {
                                    int index = (i * LENGTH_FRAME) + j;
                                    if (index < data.Length)
                                    {
                                        frame.Data[j] = data[index];
                                    }
                                    else
                                    {
                                        frame.Data[j] = Constants.HxFF;
                                    }
                                }

                                frameList.Add(frame);
                            }
                        }

                        _frameList = frameList;
                        if (frameList.Count > 0)
                        {
                            btn0x0A.Enabled = true;
                        }
                        else
                        {
                            btn0x0A.Enabled = false;
                        }

                        //rtbLog.Text = intelHex.Print();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Đã xảy ra lỗi trong quá trình xử lý file.", "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
                FileHelper.WriteLogError("", ex.Message + Environment.NewLine + ex.StackTrace);
            }
        }
Ejemplo n.º 9
0
        private void StartOperationThread()
        {
            Task.Run(new Action(() =>
            {
                try
                {
                    if (!ConnectVerifySignature())
                    {
                        DisconnectHardware();
                        return;
                    }

                    if (_operation == Operation.Erase)
                    {
                        AppendLog("Erasing Chip...", false);
                        _programmer.ChipErase();
                        AppendLog("OK");
                    }

                    if (_operation == Operation.Read)
                    {
                        if (_selectedMemory == MemType.Flash || _selectedMemory == MemType.ALL)
                        {
                            UpdateFlashBufferDisplay("");
                            _expectedRWbytes = _selectedChip.FlashSize;
                            AppendLog("Reading Flash...", false);
                            var memBlock = new MemoryBlock
                            {
                                Data = _programmer.ReadMemory(MemSource.Flash, 0, _selectedChip.FlashSize)
                            };
                            _flashBuffer = new IntelHex();
                            _flashBuffer.MemBlocks.Add(memBlock);
                            AppendLog(_flashBuffer.DataLength + " bytes OK");
                            UpdateFlashBufferDisplay(ByteArrayToHexString(_flashBuffer.RawData));
                        }

                        if (_selectedMemory == MemType.EEPROM || _selectedMemory == MemType.ALL)
                        {
                            UpdateEepromBufferDisplay("");
                            _expectedRWbytes = _selectedChip.EepromSize;
                            AppendLog("Reading EEPROM...", false);
                            var memBlock = new MemoryBlock
                            {
                                Data = _programmer.ReadMemory(MemSource.EEPROM, 0, _selectedChip.EepromSize)
                            };
                            _eepromBuffer = new IntelHex();
                            _eepromBuffer.MemBlocks.Add(memBlock);
                            AppendLog(_eepromBuffer.DataLength + " bytes OK");
                            UpdateEepromBufferDisplay(ByteArrayToHexString(_eepromBuffer.RawData));
                        }
                    }

                    if (_operation == Operation.Verify)
                    {
                        if (_selectedMemory == MemType.Flash || _selectedMemory == MemType.ALL)
                        {
                            _expectedRWbytes = _selectedChip.FlashSize;
                            AppendLog("Reading Flash...", false);
                            var verifyBuffer = _programmer.ReadMemory(MemSource.Flash, 0, _selectedChip.FlashSize);
                            AppendLog(verifyBuffer.Length + " bytes OK");

                            AppendLog("Verifying Flash...", false);
                            var failIndex = -1;
                            var flashData = _flashBuffer.RawData;
                            for (int i = 0; i < flashData.Length; i++)
                            {
                                if (flashData[i] != verifyBuffer[i])
                                {
                                    failIndex = i;
                                    break;
                                }
                            }
                            if (failIndex >= 0)
                            {
                                AppendLog("Mismatch at index " + failIndex);
                                PopupError("Flash Verification Mismatch!");
                            }
                            else
                            {
                                AppendLog("OK");
                            }
                        }

                        if (_selectedMemory == MemType.EEPROM || _selectedMemory == MemType.ALL)
                        {
                            _expectedRWbytes = _selectedChip.EepromSize;
                            AppendLog("Reading EEPROM...", false);
                            var verifyBuffer = _programmer.ReadMemory(MemSource.EEPROM, 0, _selectedChip.EepromSize);
                            AppendLog(verifyBuffer.Length + " bytes OK");

                            AppendLog("Verifying EEPROM...", false);
                            var failIndex = -1;
                            var eepData   = _eepromBuffer.RawData;
                            for (int i = 0; i < eepData.Length; i++)
                            {
                                if (eepData[i] != verifyBuffer[i])
                                {
                                    failIndex = i;
                                    break;
                                }
                            }

                            if (failIndex >= 0)
                            {
                                AppendLog("Mismatch at index " + failIndex);
                                PopupError("EEPROM Verification Mismatch!");
                            }
                            else
                            {
                                AppendLog("OK");
                            }
                        }
                    }

                    if (_operation == Operation.Write)
                    {
                        if (_selectedMemory == MemType.Flash || _selectedMemory == MemType.ALL)
                        {
                            if (_programmer is USBasp)
                            {
                                AppendLog("Erasing Chip...", false);
                                _programmer.ChipErase();
                                AppendLog("OK");
                            }

                            var blockNo = 1;
                            AppendLog("Writing Flash...", false);
                            foreach (var item in _flashBuffer.MemBlocks)
                            {
                                if (_flashBuffer.MemBlocks.Count > 0)
                                {
                                    AppendLog("\rWriting MemBlock..." + blockNo++);
                                }
                                _expectedRWbytes = item.Data.Length;
                                _programmer.WriteMemory(MemSource.Flash, item.Start, _selectedChip.PageSize, item.Data);
                            }
                            AppendLog(_flashBuffer.DataLength + " bytes OK");
                        }

                        if (_selectedMemory == MemType.EEPROM || _selectedMemory == MemType.ALL)
                        {
                            var blockNo = 1;
                            AppendLog("Writing EEPROM...", false);
                            foreach (var item in _eepromBuffer.MemBlocks)
                            {
                                if (_flashBuffer.MemBlocks.Count > 0)
                                {
                                    AppendLog("\rWriting MemBlock..." + blockNo++);
                                }
                                _expectedRWbytes = item.Data.Length;
                                _programmer.WriteMemory(MemSource.EEPROM, item.Start, _selectedChip.PageSize, item.Data);
                            }
                            AppendLog(_eepromBuffer.DataLength + " bytes OK");
                        }
                    }

                    DisconnectHardware();
                }
                catch (Exception ex)
                {
                    DisconnectHardware();
                    AppendLog("FAILED");
                    PopupError(ex.Message);
                }
            }));
        }
Ejemplo n.º 10
0
        public static void Flash(string filePath, int BinMemOffset = 0, int vid = 0x0483, int pid = 0xDF11)
        {
            // version is optional, FF means forced update
            int vmajor = 0xFF, vminor = 0xFF;

            var fileExt   = Path.GetExtension(filePath);
            var isDfuFile = Dfu.IsExtensionSupported(fileExt);

            EventHandler <ProgressChangedEventArgs> printDownloadProgress = (obj, e) =>
            {
                Progress(e.ProgressPercentage, "Download progress");
                Console.WriteLine("Download progress: {0}%", e.ProgressPercentage);
            };
            EventHandler <ErrorEventArgs> printDevError = (obj, e) =>
            {
                Progress(-1,
                         String.Format("The DFU device reported the following error: {0}", e.GetException().Message));
                Console.Error.WriteLine("The DFU device reported the following error: {0}", e.GetException().Message);
            };

            LibUsbDfu.Device device = null;
            try
            {
                Version         fileVer     = new Version(vmajor, vminor);
                Dfu.FileContent dfuFileData = null;
                RawMemory       memory      = null;

                // find the matching file parser by extension
                if (isDfuFile)
                {
                    dfuFileData = Dfu.ParseFile(filePath);
                    Console.WriteLine("DFU image parsed successfully.");

                    // DFU file specifies VID, PID and version, so override any arguments
                    vid     = dfuFileData.DeviceInfo.VendorId;
                    pid     = dfuFileData.DeviceInfo.ProductId;
                    fileVer = dfuFileData.DeviceInfo.ProductVersion;
                }
                else if (IntelHex.IsExtensionSupported(fileExt))
                {
                    memory = IntelHex.ParseFile(filePath);
                    Console.WriteLine("Intel HEX image parsed successfully.");
                }
                else if (SRecord.IsExtensionSupported(fileExt))
                {
                    memory = SRecord.ParseFile(filePath);
                    Console.WriteLine("SRecord image parsed successfully.");
                }
                else if (BinMemOffset > 0)
                {
                    memory = new RawMemory();
                    memory.TryAddSegment(new Segment((ulong)BinMemOffset, File.ReadAllBytes(filePath)));
                }
                else
                {
                    throw new ArgumentException("Image file format not recognized.");
                }

                // find the DFU device
                if (vid == 0 && pid == 0)
                {
                    LibUsbDfu.Device.TryOpen(UsbDevice.AllDevices.First(), out device);
                }
                else
                {
                    device = LibUsbDfu.Device.OpenFirst(UsbDevice.AllDevices, vid, pid);
                }

                device.DeviceError += printDevError;

                if (isDfuFile)
                {
                    // verify protocol version
                    if (dfuFileData.DeviceInfo.DfuVersion != device.DfuDescriptor.DfuVersion)
                    {
                        throw new InvalidOperationException(String.Format("DFU file version {0} doesn't match device DFU version {1}",
                                                                          dfuFileData.DeviceInfo.DfuVersion,
                                                                          device.DfuDescriptor.DfuVersion));
                    }
                }

                // if the device is in normal application mode, reconfigure it
                if (device.InAppMode())
                {
                    bool skipUpdate = fileVer <= device.Info.ProductVersion;

                    // skip update when it's deemed unnecessary
                    if (skipUpdate)
                    {
                        Console.WriteLine("The device is already up-to-date (version {0}), skipping update (version {1}).",
                                          device.Info.ProductVersion,
                                          fileVer);
                        return;
                    }

                    Console.WriteLine("Device found in application mode, reconfiguring device to DFU mode...");
                    device.Reconfigure();

                    // in case the device detached, we must find the DFU mode device
                    if (!device.IsOpen())
                    {
                        // clean up old device first
                        device.DeviceError -= printDevError;
                        device.Dispose();
                        device = null;

                        device              = LibUsbDfu.Device.OpenFirst(UsbDevice.AllDevices, vid, pid);
                        device.DeviceError += printDevError;
                    }
                }
                else
                {
                    Console.WriteLine("Device found in DFU mode.");
                }

                // perform upgrade
                device.DownloadProgressChanged += printDownloadProgress;
                if (isDfuFile)
                {
                    device.DownloadFirmware(dfuFileData);
                }
                else
                {
                    device.DownloadFirmware(memory);
                }
                device.DownloadProgressChanged -= printDownloadProgress;

                Console.WriteLine("Download successful, manifesting update...");
                Progress(100, "Download successful, manifesting update...");
                device.Manifest();

                // if the device detached, clean up
                if (!device.IsOpen())
                {
                    device.DeviceError -= printDevError;
                    device.Dispose();
                    device = null;
                }

                // TODO find device again to verify new version
                Console.WriteLine("The device has been successfully upgraded.");
                Progress(100, "The device has been successfully upgraded.");
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Device Firmware Upgrade failed with exception: {0}.", e.ToString());
                //Environment.Exit(-1);
                Progress(-1, String.Format("Device Firmware Upgrade failed with exception: {0}.", e.ToString()));
            }
            finally
            {
                if (device != null)
                {
                    device.Dispose();
                }
            }
        }