/// <summary> /// Creates an empty text record parser context. /// </summary> public TextRecordParser() { CurrentLine = 0; AddressOffset = 0; SegmentStartAddress = (~0u) - 1u; SegmentEndAddress = (~0u) - 1u; MemoryBlocks = new List <byte[]>(); Memory = new RawMemory(); }
/// <summary> /// Map the raw memory to alternate settings of the DFUSE device. /// </summary> /// <param name="memory">Raw memory image</param> /// <returns>Memory mapped to alternate settings</returns> private Dictionary <byte, NamedMemory> SortMemoryByAltSetting(RawMemory memory) { Dictionary <byte, NamedMemory> sortedMemory = new Dictionary <byte, NamedMemory>(); byte altSel; int segNo = 0; while (segNo < memory.Segments.Count) { // go through the available memories (each of which is an alternate setting) for (altSel = 0; altSel < NumberOfAlternateSettings; altSel++) { string ml = GetString(iAlternateSetting(altSel)); var layout = ParseLayout(ml); int segCount = 0; var newMem = new NamedMemory(layout.Name); // add segments which fit into this layout for (int i = segNo; (i < memory.Segments.Count) && (memory.Segments[i].StartAddress >= layout.StartAddress) && (memory.Segments[i].EndAddress <= layout.EndAddress); i++) { newMem.TryAddSegment(memory.Segments[i]); segCount++; } // no matching segments, continue searching fitting alternate setting if (segCount == 0) { continue; } sortedMemory.Add(altSel, newMem); // advance with the segments segNo += segCount; break; } // loop terminated without break if (altSel == NumberOfAlternateSettings) { throw new ArgumentOutOfRangeException("memory", memory, "The provided memory has segments that cannot be found on the target device."); } } return(sortedMemory); }
/// <summary> /// Download the firmware image to the reconfigured DFU device. /// </summary> /// <param name="memory">Raw memory image to download</param> public void DownloadFirmware(RawMemory memory) { ResetToIdle(); if (DfuDescriptor.DfuVersion <= Protocol.LatestVersion) { // only raw data can be downloaded Download(memory.Segments[0].Data); } else if (DfuDescriptor.DfuVersion == Protocol.SeVersion) { // parse memory layout of device and sort memory Download(SortMemoryByAltSetting(memory)); } else { throw new ArgumentException("The selected dfu file has unsupported DFU specification version."); } }
void OnRefresh(object sender, EventArgs e) { // NOOOOOOO!!!!! I don't want to go through linq to get the array :( var memory = RawMemory?.ToArray(); if (memory != null && memory.Length >= screen + 0x1800) { // The layout of MSX graphics memory is a bit weird for (var s = 0; s < 3; ++s) { for (var cl = 0; cl < 8; ++cl) { for (var l = 0; l < 8; ++l) { var memOffset = screen + (s << 11) + (cl << 8) + (l << 5); for (var cx = 0; cx < 32; ++cx) { var c = memory[memOffset + cx]; var bitmapOffset = stride * (((s << 11) + (l << 8) + (cl << 5) + cx) << 3); for (int x = 0, strideX = 0; x < 8; ++x, strideX += stride) { var b = 0x1 & (c >> (7 - x)); // TODO: Add support for attribute area if (b != 0) { _screenPixels[bitmapOffset + strideX + 0] = 0xFF; _screenPixels[bitmapOffset + strideX + 1] = 0xFF; _screenPixels[bitmapOffset + strideX + 2] = 0xFF; } else { _screenPixels[bitmapOffset + strideX + 0] = 0x00; _screenPixels[bitmapOffset + strideX + 1] = 0x00; _screenPixels[bitmapOffset + strideX + 2] = 0x00; } } } } } } } _screenBitmap.WritePixels(new Int32Rect(0, 0, width, height), _screenPixels, width * stride, 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(); } } }
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(); } } }