/// <summary> /// Waits for a Maple DFU device to be added or removed. /// </summary> /// <param name="timeout">Timeout in milliseconds.</param> /// <param name="removed">Set to true to wait for DFU device to be removed.</param> /// <returns>Boolean indicating whether or not a DFU device appeared or disappeared within the timeout.</returns> public static bool WaitForDFU(int timeout = 500, bool removed = false) { DateTime start = DateTime.Now; bool dfuCheck = MapleDevice.FindMaple().DfuMode; double elapsedMs = (DateTime.Now - start).TotalMilliseconds; while (dfuCheck == removed && elapsedMs < timeout) { Thread.Sleep(50); dfuCheck = MapleDevice.FindMaple().DfuMode; elapsedMs = (DateTime.Now - start).TotalMilliseconds; } Debug.WriteLine($"Elapsed time: {elapsedMs}"); if (elapsedMs < timeout) { return(true); } else { return(false); } }
/// <summary> /// Selects a firmware file to flash. /// </summary> private void ButtonBrowse_Click(object sender, EventArgs e) { // Create the file open dialog using (OpenFileDialog openFileDialog = new OpenFileDialog()) { // Title for the dialog openFileDialog.Title = "Choose file to flash"; // Filter for .bin files openFileDialog.Filter = ".bin File|*.bin"; if (openFileDialog.ShowDialog() == DialogResult.OK) { // Set the text box to the selected file name this.textFileName.Text = openFileDialog.FileName; } } // Check if there is a Maple device bool mapleCheck = MapleDevice.FindMaple().DeviceFound; // Check the file name and pre-set the Write Bootloader option if (this.textFileName.Text.IndexOf("_FTDI_") > -1 && !mapleCheck) { this.writeBootloader_No.Checked = true; } else if (this.textFileName.Text.IndexOf("_TXFLASH_") > -1 && !mapleCheck) { this.writeBootloader_Yes.Checked = true; } // Check if the Upload button should be enabled yet this.CheckControls(); }
/// <summary> /// Populates the list of COM ports. /// </summary> private void PopulateComPorts() { // Don't refresh if the control is not enabled if (!this.comPortSelector.Enabled) { return; } // Get the current list from the combobox so we can auto-select the new device var oldPortList = this.comPortSelector.Items; // Cache the selected item so we can try to re-select it later object selectedValue = null; selectedValue = this.GetSelectedPort(); // Enumerate the COM ports and bind the COM port selector List <ComPort> comPorts = new List <ComPort>(); comPorts = ComPort.EnumeratePortList(); // Check if we have a Maple device MapleDevice mapleCheck = MapleDevice.FindMaple(); // Populate the COM port selector this.PopulatePortSelector(comPorts); // If we had an old list, compare it to the new one and pick the first item which is new if (oldPortList.Count > 0) { foreach (ComPort newPort in comPorts) { bool found = false; foreach (ComPort oldPort in oldPortList) { if (newPort.Name == oldPort.Name) { found = true; } } if (found == false) { Debug.WriteLine($"{newPort.Name} was added."); selectedValue = newPort.Name; } } } // Re-select the previously selected item this.SelectPort(selectedValue); // Set the width of the dropdown // this.comPortSelector.DropDownWidth = comPorts.Select(c => c.DisplayName).ToList().Max(x => TextRenderer.MeasureText(x, this.comPortSelector.Font).Width); // Make sure the Update button is disabled if there is no port selected this.CheckControls(); }
/// <summary> /// Main method where all the action happens. /// Called by the Upload button. /// </summary> private async void ButtonUpload_Click(object sender, EventArgs e) { // Disable the buttons until this flash attempt is complete Debug.WriteLine("Disabling the controls..."); this.EnableControls(false); // Clear the output box Debug.WriteLine("Clearing the output textboxes..."); this.textActivity.Clear(); this.textVerbose.Clear(); this.progressBar1.Value = 0; // Check if the file exists if (!File.Exists(this.textFileName.Text)) { this.AppendLog(string.Format("File {0} does not exist", this.textFileName.Text)); MessageBox.Show("Firmware file does not exist.", "Write Firmware", MessageBoxButtons.OK, MessageBoxIcon.Error); this.EnableControls(true); return; } // Check the file size if (!this.CheckFirmwareFileSize()) { this.EnableControls(true); return; } // Determine if we should use Maple or serial interface MapleDevice mapleResult = MapleDevice.FindMaple(); // Determine if the selected file contains USB / bootloader support bool firmwareSupportsUsb = this.CheckForUsbSupport(); // Error if flashing non-USB firmware via native USB port if (mapleResult.DeviceFound && !firmwareSupportsUsb) { string msgBoxMessage = "The selected firmware file was compiled without USB support.\r\n\r\nFlashing this firmware would prevent the Multiprotocol module from functioning correctly.\r\n\r\nPlease select a different firmware file."; MessageBox.Show(msgBoxMessage, "Incompatible Firmware", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // Get the selected COM port string comPort = this.comPortSelector.SelectedValue.ToString(); // Do the selected flash using the appropriate method if (mapleResult.DeviceFound == true) { Debug.WriteLine($"Maple device found in {mapleResult.Mode} mode\r\n"); await MapleDevice.WriteFlash(this, this.textFileName.Text, comPort); } else { await SerialDevice.WriteFlash(this, this.textFileName.Text, comPort, firmwareSupportsUsb); } }
/// <summary> /// Prompts the user to unplug / replug the module to get it into recovery mode. /// </summary> /// <param name="sender">Event sender.</param> /// <param name="e">Event arguments.</param> private async void DfuRecoveryDialog_Shown(object sender, EventArgs e) { bool dfuCheck = MapleDevice.FindMaple().DfuMode; if (dfuCheck) { this.flashMulti.AppendLog("Waiting up to 30s for DFU device to disappear ..."); // Wait 30s for the DFU device to disappear await Task.Run(() => { dfuCheck = MapleDevice.WaitForDFU(30000, true); }); if (dfuCheck) { // The module was unplugged this.flashMulti.AppendLog(" gone.\r\n"); } else { // The module wasn't unplugged when the timer expired. this.flashMulti.AppendLog(" timed out!\r\n"); MessageBox.Show("DFU device was not unplugged in time.", "Firmware Update", MessageBoxButtons.OK, MessageBoxIcon.Error); this.DialogResult = DialogResult.Cancel; this.Close(); return; } } this.flashMulti.AppendLog("Waiting up to 30s for DFU device to appear ..."); // Reset the progress bar this.timerProgressBar.Value = 0; // Wait for the DFU device to appear await Task.Run(() => { dfuCheck = MapleDevice.WaitForDFU(30000); }); if (dfuCheck) { // The module was plugged in this.flashMulti.AppendLog(" got it.\r\n"); this.DialogResult = DialogResult.OK; this.Close(); return; } else { // The module wasn't plugged in when the timer expired this.flashMulti.AppendLog(" timed out!\r\n"); MessageBox.Show("DFU device was not plugged in in time.", "Firmware Update", MessageBoxButtons.OK, MessageBoxIcon.Error); this.DialogResult = DialogResult.Cancel; this.Close(); return; } }
/// <summary> /// Enumerates the available COM ports using WMI, including the device description. /// </summary> /// <returns>Returns an ordered list of ports <see cref="ComPort"/>.</returns> public static List <ComPort> EnumeratePortList2() { List <ComPort> comPorts = new List <ComPort>(); // Get all the COM ports using WMI using (ManagementObjectSearcher searcher = new ManagementObjectSearcher( "root\\cimv2", "SELECT * FROM Win32_PnPEntity WHERE ClassGuid=\"{4d36e978-e325-11ce-bfc1-08002be10318}\"")) { // Add all available ports to the list foreach (ManagementObject queryObj in searcher.Get()) { string portCaption = queryObj["Caption"].ToString(); if (portCaption.Contains("(COM")) { // Get the index number where "(COM" starts in the string int indexOfCom = portCaption.IndexOf("(COM"); string portName = portCaption.Substring(indexOfCom + 1, portCaption.Length - indexOfCom - 2); string portDescription = portCaption.Substring(0, indexOfCom - 1); ComPort thisPort = new ComPort { Name = portName, Description = portDescription, DisplayName = $"{portName} ({portDescription})", }; comPorts.Add(thisPort); } } } // Sort the list of ports comPorts = comPorts.OrderBy(c => c.Name.Length).ThenBy(c => c.Name).ToList(); // Check if we there's a Maple device in DFU mode plugged in if (MapleDevice.FindMaple().DfuMode) { ComPort dfuPort = new ComPort { Name = "DFU Device", Description = "Maple DFU Device", DisplayName = "DFU Device", }; comPorts.Add(dfuPort); } // Return a list of COM ports return(comPorts); }
/// <summary> /// Enumerates the available COM ports without using WMI. /// </summary> /// <returns>Returns an ordered list of ports <see cref="ComPort"/>.</returns> public static List <ComPort> EnumeratePortList() { // Get the start time so we can write how long this takes to the debug window DateTime start = DateTime.Now; Debug.WriteLine("Enumerating COM ports"); // Create a list to store the COM port names List <ComPort> comPorts = new List <ComPort>(); // Get all the COM port names string[] comPortNames = SerialPort.GetPortNames().Distinct().ToArray(); // Add all the COM ports to the list foreach (string portName in comPortNames) { // We only know the port name, so write that to all three properties ComPort thisPort = new ComPort { Name = portName, Description = portName, DisplayName = portName, }; comPorts.Add(thisPort); } // Sort the list of ports by name comPorts = comPorts.OrderBy(c => c.Name.Length).ThenBy(c => c.Name).ToList(); // Check if we there's a Maple DFU device plugged in and add it to the list if (MapleDevice.FindMaple().DfuMode) { ComPort dfuPort = new ComPort { Name = "DFU Device", Description = "DFU Device", DisplayName = "DFU Device", }; comPorts.Add(dfuPort); } // Get the time now and write how long that took DateTime end = DateTime.Now; Debug.WriteLine($"COM ports enumerated in {end - start}."); // Return the list of COM ports return(comPorts); }
/// <summary> /// Enable or disable the controls. /// </summary> /// <param name="arg">True to enable, False to disable.</param> public void EnableControls(bool arg) { // Enable the buttons if (arg) { Debug.WriteLine("Re-enabling the controls..."); } else { Debug.WriteLine("Disabling the controls..."); } if (arg) { // Populate the COM ports this.PopulateComPortsAsync(); } // Check if there is a Maple device attached MapleDevice mapleCheck = MapleDevice.FindMaple(); // Toggle the controls this.buttonUpload.Enabled = arg; this.buttonBrowse.Enabled = arg; this.buttonRefresh.Enabled = arg; this.textFileName.Enabled = arg; this.comPortSelector.Enabled = arg; // Keep the Write Bootloader controls disabled if a Maple device is plugged in. if (mapleCheck.DeviceFound) { this.writeBootloader_Yes.Checked = true; this.writeBootloader_Yes.Enabled = false; this.writeBootloader_No.Enabled = false; } else { this.writeBootloader_Yes.Enabled = arg; this.writeBootloader_No.Enabled = arg; } // Check a couple of things if we're re-enabling if (arg) { // Check if the Upload button can be enabled this.CheckControls(); } }
/// <summary> /// Enumerates the available COM ports. /// </summary> /// <returns>Returns an ordered array of COM port names.</returns> public static string[] EnumeratePorts() { // Get the list of COM port names List <string> comPorts = SerialPort.GetPortNames().ToList(); // Sort the list of ports comPorts = comPorts.OrderBy(c => c.Length).ThenBy(c => c).ToList(); // Check if we there's a Maple device plugged in if (MapleDevice.FindMaple().DeviceFound) { comPorts.Add("DFU Device"); } // Return an array of COM port names return(comPorts.ToArray()); }
/// <summary> /// Enumerates the available COM ports without using WMI. /// </summary> /// <returns>Returns an ordered list of ports <see cref="ComPort"/>.</returns> public static List <ComPort> EnumeratePortList() { DateTime start = DateTime.Now; Debug.WriteLine("Enumerating COM ports"); List <ComPort> comPorts = new List <ComPort>(); // Get all the COM ports string[] comPortNames = SerialPort.GetPortNames(); // Add all available to the list foreach (string portName in comPortNames) { ComPort thisPort = new ComPort { Name = portName, Description = portName, DisplayName = portName, }; comPorts.Add(thisPort); } // Sort the list of ports comPorts = comPorts.OrderBy(c => c.Name.Length).ThenBy(c => c.Name).ToList(); // Check if we there's a Maple device in DFU mode plugged in if (MapleDevice.FindMaple().DfuMode) { ComPort dfuPort = new ComPort { Name = "DFU Device", Description = "DFU Device", DisplayName = "DFU Device", }; comPorts.Add(dfuPort); } DateTime end = DateTime.Now; Debug.WriteLine($"COM ports enumerated in {end - start}."); // Return a list of COM ports return(comPorts); }
/// <summary> /// Enable or disable the controls. /// </summary> /// <param name="arg">True to enable, False to disable.</param> public void EnableControls(bool arg) { // Enable the buttons if (arg) { Debug.WriteLine("Re-enabling the controls..."); } else { Debug.WriteLine("Disabling the controls..."); } if (arg) { // Populate the COM ports _ = this.PopulateComPortsAsync(); } // Check if there is a Maple device attached MapleDevice mapleCheck = MapleDevice.FindMaple(); // Toggle the controls this.buttonUpload.Enabled = arg; this.buttonBrowse.Enabled = arg; this.buttonRefresh.Enabled = arg; this.buttonSerialMonitor.Enabled = arg; this.textFileName.Enabled = arg; this.comPortSelector.Enabled = arg; // Check a couple of things if we're re-enabling if (arg) { // Check if the Upload button can be enabled this.CheckControls(); } }
/// <summary> /// Writes the firmware to a Maple serial or DFU device. /// </summary> /// <param name="flashMulti">An instance of the <see cref="FlashMulti"/> class.</param> /// <param name="fileName">The path of the file to flash.</param> /// <param name="comPort">The COM port where the Maple USB device can be found.</param> public static async void WriteFlash(FlashMulti flashMulti, string fileName, string comPort) { string command; string commandArgs; int returnCode = -1; flashMulti.AppendLog("Starting Multimodule update\r\n"); string mapleMode = MapleDevice.FindMaple().Mode; if (mapleMode == "USB") { flashMulti.AppendLog("Switching Multimodule into DFU mode ..."); command = ".\\tools\\maple-reset.exe"; commandArgs = comPort; await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode != 0) { flashMulti.EnableControls(true); flashMulti.AppendLog(" failed!"); MessageBox.Show("Failed to get module to DFU mode.", "Firmware Update", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } flashMulti.AppendLog(" done\r\n"); // Check for a Maple DFU device flashMulti.AppendLog("Waiting for DFU device ..."); bool dfuCheck = false; await Task.Run(() => { dfuCheck = WaitForDFU(2000); }); if (dfuCheck) { flashMulti.AppendLog(" got it\r\n"); } else { flashMulti.AppendLog(" failed!\r\n"); flashMulti.AppendLog("Attempting DFU Recovery Mode.\r\n"); // Show the recovery mode dialog DfuRecoveryDialog recoveryDialog = new DfuRecoveryDialog(flashMulti); var recoveryResult = recoveryDialog.ShowDialog(); // Error out if we didn't made it into recovery mode if (recoveryResult != DialogResult.OK) { flashMulti.AppendLog("DFU Recovery Mode failed."); flashMulti.EnableControls(true); return; } } } // First attempt to flash the firmware flashMulti.AppendLog("Writing firmware to Multimodule ..."); command = ".\\tools\\dfu-util.exe"; commandArgs = string.Format("-R -a 2 -d 1EAF:0003 -D \"{0}\"", fileName, comPort); await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode != 0) { // First attempt failed so we need to try bootloader recovery flashMulti.AppendLog(" failed!\r\n"); flashMulti.AppendLog("Attempting DFU Recovery Mode.\r\n"); // Show the recovery mode dialog DfuRecoveryDialog recoveryDialog = new DfuRecoveryDialog(flashMulti); var recoveryResult = recoveryDialog.ShowDialog(); // If we made it into recovyer mode, flash the module if (recoveryResult == DialogResult.OK) { // Run the recovery flash command flashMulti.AppendLog("Writing firmware to Multimodule ..."); await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode != 0) { flashMulti.EnableControls(true); flashMulti.AppendLog(" failed!\r\n"); MessageBox.Show("Failed to write the firmware.", "Firmware Update", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else { flashMulti.AppendLog("DFU Recovery Mode failed."); flashMulti.EnableControls(true); return; } } flashMulti.AppendLog(" done\r\n"); flashMulti.AppendLog("\r\nMultimodule updated sucessfully"); MessageBox.Show("Multimodule updated sucessfully.", "Firmware Update", MessageBoxButtons.OK, MessageBoxIcon.Information); flashMulti.EnableControls(true); }
/// <summary> /// Writes the firmware to a Maple serial or DFU device. /// </summary> /// <param name="flashMulti">An instance of the <see cref="FlashMulti"/> class.</param> /// <param name="fileName">The path of the file to flash.</param> /// <param name="comPort">The COM port where the Maple USB device can be found.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public static async Task WriteFlash(FlashMulti flashMulti, string fileName, string comPort) { string command; string commandArgs; int returnCode = -1; flashMulti.AppendLog("Starting Multimodule update via native USB\r\n"); // Stop the serial monitor if it's active SerialMonitor serialMonitor = null; bool reconnectSerialMonitor = false; if (Application.OpenForms.OfType <SerialMonitor>().Any()) { Debug.WriteLine("Serial monitor window is open"); serialMonitor = Application.OpenForms.OfType <SerialMonitor>().First(); if (serialMonitor != null && serialMonitor.SerialPort != null && serialMonitor.SerialPort.IsOpen) { reconnectSerialMonitor = true; Debug.WriteLine($"Serial monitor is connected to {serialMonitor.SerialPort.PortName}"); Debug.WriteLine($"Closing serial monitor connection to {serialMonitor.SerialPort.PortName}"); serialMonitor.SerialDisconnect(); } } else { Debug.WriteLine("Serial monitor is not open"); } // Check if the port can be opened if (!ComPort.CheckPort(comPort)) { flashMulti.AppendLog(string.Format("Couldn't open port {0}", comPort)); MessageBox.Show(string.Format("Couldn't open port {0}", comPort), "Write Firmware", MessageBoxButtons.OK, MessageBoxIcon.Error); flashMulti.EnableControls(true); return; } string mapleMode = MapleDevice.FindMaple().Mode; if (mapleMode == "USB") { flashMulti.AppendLog("Switching Multimodule into DFU mode ..."); command = ".\\tools\\maple-reset.exe"; commandArgs = comPort; await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode != 0) { flashMulti.EnableControls(true); flashMulti.AppendLog(" failed!"); MessageBox.Show("Failed to get module to DFU mode.", "Firmware Update", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } flashMulti.AppendLog(" done\r\n"); // Check for a Maple DFU device flashMulti.AppendLog("Waiting for DFU device ..."); bool dfuCheck = false; await Task.Run(() => { dfuCheck = WaitForDFU(2000); }); if (dfuCheck) { flashMulti.AppendLog(" got it\r\n"); } else { flashMulti.AppendLog(" failed!\r\n"); flashMulti.AppendLog("Attempting DFU Recovery Mode.\r\n"); // Show the recovery mode dialog DfuRecoveryDialog recoveryDialog = new DfuRecoveryDialog(flashMulti); var recoveryResult = recoveryDialog.ShowDialog(); // Stop if we didn't made it into recovery mode if (recoveryResult == DialogResult.Cancel) { flashMulti.AppendLog("DFU Recovery cancelled."); flashMulti.EnableControls(true); return; } else if (recoveryResult == DialogResult.Abort) { flashMulti.AppendLog("DFU Recovery failed."); flashMulti.EnableControls(true); return; } } } // First attempt to flash the firmware flashMulti.AppendLog("Writing firmware to Multimodule ..."); command = ".\\tools\\dfu-util.exe"; commandArgs = string.Format("-R -a 2 -d 1EAF:0003 -D \"{0}\"", fileName, comPort); await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode != 0) { // First attempt failed so we need to try bootloader recovery flashMulti.AppendLog(" failed!\r\n"); flashMulti.AppendLog("Attempting DFU Recovery Mode.\r\n"); // Show the recovery mode dialog DfuRecoveryDialog recoveryDialog = new DfuRecoveryDialog(flashMulti); var recoveryResult = recoveryDialog.ShowDialog(); // If we made it into recovery mode, flash the module if (recoveryResult == DialogResult.OK) { // Run the recovery flash command flashMulti.AppendLog("Writing firmware to Multimodule ..."); await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode != 0) { flashMulti.AppendLog(" failed!\r\n"); MessageBox.Show("Failed to write the firmware.", "Firmware Update", MessageBoxButtons.OK, MessageBoxIcon.Error); flashMulti.EnableControls(true); return; } } else if (recoveryResult == DialogResult.Cancel) { flashMulti.AppendLog("DFU Recovery cancelled."); flashMulti.EnableControls(true); return; } else { flashMulti.AppendLog("DFU Recovery failed."); flashMulti.EnableControls(true); return; } } flashMulti.AppendLog(" done\r\n"); flashMulti.AppendLog("\r\nMultimodule updated sucessfully"); // Reconnect the serial monitor if (serialMonitor != null && reconnectSerialMonitor) { Thread.Sleep(1000); serialMonitor.SerialConnect(comPort); } MessageBox.Show("Multimodule updated sucessfully.", "Firmware Update", MessageBoxButtons.OK, MessageBoxIcon.Information); flashMulti.EnableControls(true); }
/// <summary> /// Resets the Maple USB Serial device to DFU mode. /// </summary> /// <param name="flashMulti">An instance of the <see cref="FlashMulti"/> class.</param> /// <param name="comPort">The COM port where the Maple USB device can be found.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public static async Task <bool> ResetToDfuMode(FlashMulti flashMulti, string comPort) { string command; string commandArgs; int returnCode = -1; // Stop the serial monitor if it's active SerialMonitor serialMonitor = null; if (Application.OpenForms.OfType <SerialMonitor>().Any()) { Debug.WriteLine("Serial monitor window is open"); serialMonitor = Application.OpenForms.OfType <SerialMonitor>().First(); if (serialMonitor != null && serialMonitor.SerialPort != null && serialMonitor.SerialPort.IsOpen) { Debug.WriteLine($"Serial monitor is connected to {serialMonitor.SerialPort.PortName}"); Debug.WriteLine($"Closing serial monitor connection to {serialMonitor.SerialPort.PortName}"); serialMonitor.SerialDisconnect(); } } else { Debug.WriteLine("Serial monitor is not open"); } // Check if the port can be opened if (!ComPort.CheckPort(comPort)) { flashMulti.AppendLog($"{Strings.failedToOpenPort} {comPort}"); using (new CenterWinDialog(flashMulti)) { MessageBox.Show($"{Strings.failedToOpenPort} {comPort}", Strings.dialogTitleRead, MessageBoxButtons.OK, MessageBoxIcon.Error); } flashMulti.EnableControls(true); return(false); } string mapleMode = MapleDevice.FindMaple().Mode; if (mapleMode == "USB") { flashMulti.AppendLog($"{Strings.progressSwitchingToDfuMode}"); command = ".\\tools\\maple-reset.exe"; commandArgs = $"{comPort} 2000"; await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode == 0) { flashMulti.AppendLog($" {Strings.done}\r\n"); flashMulti.AppendVerbose(string.Empty); } else { if (MapleDevice.FindMaple().DfuMode == false) { flashMulti.AppendLog($" {Strings.failed}\r\n"); using (new CenterWinDialog(flashMulti)) { MessageBox.Show(Strings.failedToReadModule, Strings.dialogTitleRead, MessageBoxButtons.OK, MessageBoxIcon.Error); } flashMulti.EnableControls(true); return(false); } } } return(true); }
/// <summary> /// Upgrades the bootloader of a Maple serial or DFU device. /// </summary> /// <param name="flashMulti">An instance of the <see cref="FlashMulti"/> class.</param> /// <param name="comPort">The COM port where the Maple USB device can be found.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public static async Task <bool> UpgradeBootloader(FlashMulti flashMulti, string comPort) { string command; string commandArgs; int returnCode = -1; flashMulti.AppendLog($"{Strings.modeBootloaderUpgrade} {Strings.viaNativeUSB}\r\n"); // Stop the serial monitor if it's active SerialMonitor serialMonitor = null; if (Application.OpenForms.OfType <SerialMonitor>().Any()) { Debug.WriteLine("Serial monitor window is open"); serialMonitor = Application.OpenForms.OfType <SerialMonitor>().First(); if (serialMonitor != null && serialMonitor.SerialPort != null && serialMonitor.SerialPort.IsOpen) { Debug.WriteLine($"Serial monitor is connected to {serialMonitor.SerialPort.PortName}"); Debug.WriteLine($"Closing serial monitor connection to {serialMonitor.SerialPort.PortName}"); serialMonitor.SerialDisconnect(); } } else { Debug.WriteLine("Serial monitor is not open"); } // Check if the port can be opened if (!ComPort.CheckPort(comPort)) { flashMulti.AppendLog($"{Strings.failedToOpenPort} {comPort}"); using (new CenterWinDialog(flashMulti)) { MessageBox.Show($"{Strings.failedToOpenPort} {comPort}", Strings.dialogTitleBootloaderUpgrade, MessageBoxButtons.OK, MessageBoxIcon.Error); } flashMulti.EnableControls(true); return(false); } string mapleMode = MapleDevice.FindMaple().Mode; if (mapleMode == "USB") { flashMulti.AppendLog(Strings.progressSwitchingToDfuMode); command = ".\\tools\\maple-reset.exe"; commandArgs = $"{comPort} 2000"; await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode == 0) { flashMulti.AppendLog($" {Strings.done}\r\n"); flashMulti.AppendVerbose(string.Empty); } else { if (MapleDevice.FindMaple().DfuMode == false) { flashMulti.AppendLog($" {Strings.failed}\r\n"); using (new CenterWinDialog(flashMulti)) { MessageBox.Show(Strings.failedToWriteBootReloader, Strings.dialogTitleBootloaderUpgrade, MessageBoxButtons.OK, MessageBoxIcon.Error); } flashMulti.EnableControls(true); return(false); } } } // The bootreloader.bin file string fileName; if (Properties.Settings.Default.ErrorIfNoUSB) { fileName = ".\\tools\\bootreloader_legacy.bin"; } else { fileName = ".\\tools\\bootreloader_stickydfu.bin"; } // Erase the the flash flashMulti.AppendLog(Strings.progressWritingBootReloader); command = ".\\tools\\dfu-util-multi.exe"; commandArgs = string.Format("-a 2 -d 1EAF:0003 -D \"{0}\" -v -R", fileName, comPort); await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode != 0) { // First attempt failed so we need to try bootloader recovery flashMulti.AppendLog($" {Strings.failed}\r\n"); flashMulti.AppendLog($"{Strings.dfuAttemptingRecovery}\r\n"); // Show the recovery mode dialog DfuRecoveryDialog recoveryDialog = new DfuRecoveryDialog(flashMulti); var recoveryResult = recoveryDialog.ShowDialog(); // If we made it into recovery mode, flash the module if (recoveryResult == DialogResult.OK) { // Run the recovery flash command flashMulti.AppendLog(Strings.progressWritingBootReloader); await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode != 0) { flashMulti.AppendLog($" {Strings.failed}!\r\n"); using (new CenterWinDialog(flashMulti)) { MessageBox.Show(Strings.failedToWriteFirmware, Strings.dialogTitleWrite, MessageBoxButtons.OK, MessageBoxIcon.Error); } flashMulti.EnableControls(true); return(false); } } else if (recoveryResult == DialogResult.Cancel) { flashMulti.AppendLog(Strings.dfuRecoveryCancelled); flashMulti.EnableControls(true); return(false); } else { flashMulti.AppendLog(Strings.dfuRecoveryFailed); flashMulti.EnableControls(true); return(false); } } // Write a success message to the log flashMulti.AppendLog($" {Strings.done}\r\n"); flashMulti.AppendLog($"\r\n{Strings.succeededWritingBootReloader}"); // Re-enable the form controls flashMulti.EnableControls(true); return(true); }
/// <summary> /// Writes the firmware to a Maple serial or DFU device. /// </summary> /// <param name="flashMulti">An instance of the <see cref="FlashMulti"/> class.</param> /// <param name="fileName">The path of the file to flash.</param> /// <param name="comPort">The COM port where the Maple USB device can be found.</param> /// <param name="runAfterUpload">Indicates if the firmware should be run when the upload is finished.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public static async Task WriteFlash(FlashMulti flashMulti, string fileName, string comPort, bool runAfterUpload) { string command; string commandArgs; int returnCode = -1; flashMulti.AppendLog($"{Strings.modeWriting} {Strings.viaNativeUSB}\r\n"); // Stop the serial monitor if it's active SerialMonitor serialMonitor = null; bool reconnectSerialMonitor = false; if (Application.OpenForms.OfType <SerialMonitor>().Any()) { Debug.WriteLine("Serial monitor window is open"); serialMonitor = Application.OpenForms.OfType <SerialMonitor>().First(); if (serialMonitor != null && serialMonitor.SerialPort != null && serialMonitor.SerialPort.IsOpen) { reconnectSerialMonitor = true; Debug.WriteLine($"Serial monitor is connected to {serialMonitor.SerialPort.PortName}"); Debug.WriteLine($"Closing serial monitor connection to {serialMonitor.SerialPort.PortName}"); serialMonitor.SerialDisconnect(); } } else { Debug.WriteLine("Serial monitor is not open"); } // Check if the port can be opened if (!ComPort.CheckPort(comPort)) { flashMulti.AppendLog($"{Strings.failedToOpenPort} {comPort}"); using (new CenterWinDialog(flashMulti)) { MessageBox.Show($"{Strings.failedToOpenPort} {comPort}", Strings.dialogTitleWrite, MessageBoxButtons.OK, MessageBoxIcon.Error); } flashMulti.EnableControls(true); return; } string mapleMode = MapleDevice.FindMaple().Mode; if (mapleMode == "USB") { flashMulti.AppendLog(Strings.progressSwitchingToDfuMode); command = ".\\tools\\maple-reset.exe"; commandArgs = $"{comPort} 2000"; await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode == 0) { flashMulti.AppendLog($" {Strings.done}\r\n"); flashMulti.AppendVerbose(string.Empty); } else { if (MapleDevice.FindMaple().DfuMode == false) { flashMulti.AppendLog($" {Strings.failed}\r\n"); flashMulti.AppendLog($"{Strings.dfuAttemptingRecovery}\r\n"); // Show the recovery mode dialog DfuRecoveryDialog recoveryDialog = new DfuRecoveryDialog(flashMulti); var recoveryResult = recoveryDialog.ShowDialog(); // Stop if we didn't make it into recovery mode if (recoveryResult == DialogResult.Cancel) { flashMulti.AppendLog(Strings.dfuRecoveryCancelled); flashMulti.EnableControls(true); return; } else if (recoveryResult == DialogResult.Abort) { flashMulti.AppendLog(Strings.dfuRecoveryFailed); flashMulti.EnableControls(true); return; } } else { flashMulti.AppendLog($" {Strings.done}\r\n"); flashMulti.AppendVerbose(string.Empty); } } } if (!Properties.Settings.Default.DisableFlashVerification) { // Check that the STM32 MCU supports 128KB flashMulti.AppendLog($"{Strings.progressCheckingFlashSize}"); // Create a temporary file name to read into string tempFileName = Path.GetTempFileName(); // Read the flash memory into a temp file command = ".\\tools\\dfu-util-multi.exe"; commandArgs = string.Format("-a 2 -d 1EAF:0003 -U \"{0}\" -v", tempFileName, comPort); await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); // If we failed we need to try DFU Recovery Mode if (returnCode != 0) { // First attempt failed so we need to try bootloader recovery flashMulti.AppendLog($" {Strings.failed}\r\n"); flashMulti.AppendLog($"{Strings.dfuAttemptingRecovery}\r\n"); // Show the recovery mode dialog DfuRecoveryDialog recoveryDialog = new DfuRecoveryDialog(flashMulti); var recoveryResult = recoveryDialog.ShowDialog(); // If we made it into recovery mode, flash the module if (recoveryResult == DialogResult.OK) { // Run the recovery flash command flashMulti.AppendLog(Strings.progressCheckingFlashSize); await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode != 0) { flashMulti.AppendLog($" {Strings.failed}!\r\n"); using (new CenterWinDialog(flashMulti)) { MessageBox.Show(Strings.failedToWriteFirmware, Strings.dialogTitleWrite, MessageBoxButtons.OK, MessageBoxIcon.Error); } flashMulti.EnableControls(true); return; } } else if (recoveryResult == DialogResult.Cancel) { flashMulti.AppendLog(Strings.dfuRecoveryCancelled); flashMulti.EnableControls(true); return; } else { flashMulti.AppendLog(Strings.dfuRecoveryFailed); flashMulti.EnableControls(true); return; } } flashMulti.AppendLog($" {Strings.done}\r\n"); // Get the file size long length = new FileInfo(tempFileName).Length; // Compare the size of the data we read to the size we expect if (length < 122880) { // Throw a message and stop flashMulti.EnableControls(true); using (new CenterWinDialog(flashMulti)) { MessageBox.Show(Strings.failedToVerifyMcuFlash, Strings.dialogTitleWrite, MessageBoxButtons.OK, MessageBoxIcon.Error); } return; } } // First attempt to flash the firmware flashMulti.AppendLog(Strings.progressWritingFirmware); command = ".\\tools\\dfu-util-multi.exe"; commandArgs = string.Format("-a 2 -d 1EAF:0003 -D \"{0}\" -v", fileName, comPort); if (runAfterUpload) { commandArgs += " -R"; } await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode != 0) { // First attempt failed so we need to try bootloader recovery flashMulti.AppendLog($" {Strings.failed}\r\n"); flashMulti.AppendLog($"{Strings.dfuAttemptingRecovery}\r\n"); // Show the recovery mode dialog DfuRecoveryDialog recoveryDialog = new DfuRecoveryDialog(flashMulti); var recoveryResult = recoveryDialog.ShowDialog(); // If we made it into recovery mode, flash the module if (recoveryResult == DialogResult.OK) { // Run the recovery flash command flashMulti.AppendLog(Strings.progressWritingFirmware); await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode != 0) { flashMulti.AppendLog($" {Strings.failed}!\r\n"); using (new CenterWinDialog(flashMulti)) { MessageBox.Show(Strings.failedToWriteFirmware, Strings.dialogTitleWrite, MessageBoxButtons.OK, MessageBoxIcon.Error); } flashMulti.EnableControls(true); return; } } else if (recoveryResult == DialogResult.Cancel) { flashMulti.AppendLog(Strings.dfuRecoveryCancelled); flashMulti.EnableControls(true); return; } else { flashMulti.AppendLog(Strings.dfuRecoveryFailed); flashMulti.EnableControls(true); return; } } flashMulti.AppendLog($" {Strings.done}\r\n"); flashMulti.AppendLog($"\r\n{Strings.succeededWritingFirmware}"); // Reconnect the serial monitor if (serialMonitor != null && reconnectSerialMonitor) { Thread.Sleep(1000); serialMonitor.SerialConnect(comPort); } // Re-enable the form controls flashMulti.EnableControls(true); // Show a success message box using (new CenterWinDialog(flashMulti)) { MessageBox.Show(Strings.succeededWritingFirmware, Strings.dialogTitleWrite, MessageBoxButtons.OK, MessageBoxIcon.Information); } }
/// <summary> /// Reads the flash memory of a Maple USB device. /// </summary> /// <param name="flashMulti">An instance of the <see cref="FlashMulti"/> class.</param> /// <param name="fileName">The path of the file to write to.</param> /// <param name="comPort">The COM port where the Maple USB device can be found.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public static async Task <bool> ReadFlash(FlashMulti flashMulti, string fileName, string comPort) { string command; string commandArgs; int returnCode = -1; flashMulti.AppendLog($"{Strings.modeReading} {Strings.viaNativeUSB}\r\n"); // Stop the serial monitor if it's active SerialMonitor serialMonitor = null; bool reconnectSerialMonitor = false; if (Application.OpenForms.OfType <SerialMonitor>().Any()) { Debug.WriteLine("Serial monitor window is open"); serialMonitor = Application.OpenForms.OfType <SerialMonitor>().First(); if (serialMonitor != null && serialMonitor.SerialPort != null && serialMonitor.SerialPort.IsOpen) { reconnectSerialMonitor = true; Debug.WriteLine($"Serial monitor is connected to {serialMonitor.SerialPort.PortName}"); Debug.WriteLine($"Closing serial monitor connection to {serialMonitor.SerialPort.PortName}"); serialMonitor.SerialDisconnect(); } } else { Debug.WriteLine("Serial monitor is not open"); } // Check if the port can be opened if (!ComPort.CheckPort(comPort)) { flashMulti.AppendLog($"{Strings.failedToOpenPort} {comPort}"); using (new CenterWinDialog(flashMulti)) { MessageBox.Show($"{Strings.failedToOpenPort} {comPort}", Strings.dialogTitleRead, MessageBoxButtons.OK, MessageBoxIcon.Error); } flashMulti.EnableControls(true); return(false); } string mapleMode = MapleDevice.FindMaple().Mode; if (mapleMode == "USB") { flashMulti.AppendLog($"{Strings.progressSwitchingToDfuMode}"); command = ".\\tools\\maple-reset.exe"; commandArgs = $"{comPort} 2000"; await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode == 0) { flashMulti.AppendLog($" {Strings.done}\r\n"); flashMulti.AppendVerbose(string.Empty); } else { if (MapleDevice.FindMaple().DfuMode == false) { flashMulti.AppendLog($" {Strings.failed}\r\n"); using (new CenterWinDialog(flashMulti)) { MessageBox.Show(Strings.failedToReadModule, Strings.dialogTitleRead, MessageBoxButtons.OK, MessageBoxIcon.Error); } flashMulti.EnableControls(true); return(false); } } } // Read the flash memory flashMulti.AppendLog(Strings.progressReadingFlash); command = ".\\tools\\dfu-util-multi.exe"; commandArgs = string.Format("-a 2 -d 1EAF:0003 -U \"{0}\" -v", fileName, comPort); await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode != 0) { flashMulti.AppendLog($" {Strings.failed}\r\n"); using (new CenterWinDialog(flashMulti)) { MessageBox.Show(Strings.failedToReadModule, Strings.dialogTitleRead, MessageBoxButtons.OK, MessageBoxIcon.Error); } flashMulti.EnableControls(true); return(false); } // Write a success message to the log flashMulti.AppendLog($" {Strings.done}\r\n\r\n"); // Reconnect the serial monitor if (serialMonitor != null && reconnectSerialMonitor) { Thread.Sleep(1000); serialMonitor.SerialConnect(comPort); } // Re-enable the form controls flashMulti.EnableControls(true); return(true); }
/// <summary> /// Erases the flash memory of a Maple USB device. /// </summary> /// <param name="flashMulti">An instance of the <see cref="FlashMulti"/> class.</param> /// <param name="comPort">The COM port where the Maple USB device can be found.</param> /// <param name="eraseEeprom">Flag indicating if the EEPROM should be erased.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public static async Task <bool> EraseFlash(FlashMulti flashMulti, string comPort, bool eraseEeprom) { string command; string commandArgs; int returnCode = -1; flashMulti.AppendLog($"{Strings.modeErasing} {Strings.viaNativeUSB}\r\n"); // Stop the serial monitor if it's active SerialMonitor serialMonitor = null; if (Application.OpenForms.OfType <SerialMonitor>().Any()) { Debug.WriteLine("Serial monitor window is open"); serialMonitor = Application.OpenForms.OfType <SerialMonitor>().First(); if (serialMonitor != null && serialMonitor.SerialPort != null && serialMonitor.SerialPort.IsOpen) { Debug.WriteLine($"Serial monitor is connected to {serialMonitor.SerialPort.PortName}"); Debug.WriteLine($"Closing serial monitor connection to {serialMonitor.SerialPort.PortName}"); serialMonitor.SerialDisconnect(); } } else { Debug.WriteLine("Serial monitor is not open"); } // Check if the port can be opened if (!ComPort.CheckPort(comPort)) { flashMulti.AppendLog($"{Strings.failedToOpenPort} {comPort}"); using (new CenterWinDialog(flashMulti)) { MessageBox.Show($"{Strings.failedToOpenPort} {comPort}", Strings.dialogTitleErase, MessageBoxButtons.OK, MessageBoxIcon.Error); } flashMulti.EnableControls(true); return(false); } string mapleMode = MapleDevice.FindMaple().Mode; if (mapleMode == "USB") { flashMulti.AppendLog(Strings.progressSwitchingToDfuMode); command = ".\\tools\\maple-reset.exe"; commandArgs = $"{comPort} 2000"; await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode == 0) { flashMulti.AppendLog($" {Strings.done}\r\n"); flashMulti.AppendVerbose(string.Empty); } else { if (MapleDevice.FindMaple().DfuMode == false) { flashMulti.AppendLog($" {Strings.failed}\r\n"); using (new CenterWinDialog(flashMulti)) { MessageBox.Show(Strings.failedtoEraseModule, Strings.dialogTitleErase, MessageBoxButtons.OK, MessageBoxIcon.Error); } flashMulti.EnableControls(true); return(false); } } } // It's not actually possible to erase a device with dfu-util so we write a file full of FF bytes. string fileName = string.Empty; if (eraseEeprom) { // 120KB file overwrites the EEPROM fileName = ".\\tools\\erase120.bin"; } else { // 118KB file preserves the EEPROM fileName = ".\\tools\\erase118.bin"; } // Erase the the flash flashMulti.AppendLog(Strings.progressErasingFlash); command = ".\\tools\\dfu-util-multi.exe"; commandArgs = string.Format("-a 2 -d 1EAF:0003 -D \"{0}\" -v", fileName, comPort); await Task.Run(() => { returnCode = RunCommand.Run(flashMulti, command, commandArgs); }); if (returnCode != 0) { flashMulti.AppendLog($" {Strings.failed}\r\n"); using (new CenterWinDialog(flashMulti)) { MessageBox.Show(Strings.failedtoEraseModule, Strings.dialogTitleErase, MessageBoxButtons.OK, MessageBoxIcon.Error); } flashMulti.EnableControls(true); return(false); } // Write a success message to the log flashMulti.AppendLog($" {Strings.done}\r\n"); flashMulti.AppendLog($"\r\n{Strings.succeededErasing}"); // Re-enable the form controls flashMulti.EnableControls(true); return(true); }
/// <summary> /// Prompts the user to unplug / replug the module to get it into recovery mode. /// </summary> /// <param name="sender">Event sender.</param> /// <param name="e">Event arguments.</param> private async void DfuRecoveryDialog_Shown(object sender, EventArgs e) { // Check if we have a DFU device we need to see unplugged bool dfuCheck = MapleDevice.FindMaple().DfuMode; if (dfuCheck) { this.flashMulti.AppendLog("Waiting for DFU device to disappear ..."); // Wait 30s for the DFU device to disappear and reappear await Task.Run(() => { dfuCheck = MapleDevice.WaitForDFU(30000, true); }); // Handle user cancelling DFU recovery if (this.DialogResult == DialogResult.Cancel) { return; } if (dfuCheck) { // Wait 30s for the DFU device to disappear await Task.Run(() => { dfuCheck = MapleDevice.WaitForDFU(30000, true); }); if (dfuCheck) { // The module was unplugged this.flashMulti.AppendLog(" gone.\r\n"); } else { // The module wasn't unplugged when the timer expired. this.flashMulti.AppendLog(" timed out!\r\n"); using (new CenterWinDialog(this.flashMulti)) { MessageBox.Show("DFU device was not unplugged in time.", "Firmware Update", MessageBoxButtons.OK, MessageBoxIcon.Error); } this.DialogResult = DialogResult.Cancel; this.Close(); return; } } } this.flashMulti.AppendLog("Waiting for DFU device to appear ..."); // Wait for the DFU device to appear await Task.Run(() => { dfuCheck = MapleDevice.WaitForDFU(30000 - (this.timerProgressBar.Value * 1000)); }); // Handle user cancelling DFU recovery if (this.DialogResult == DialogResult.Cancel) { return; } if (dfuCheck) { // The module was plugged in this.flashMulti.AppendLog(" got it.\r\n"); this.DialogResult = DialogResult.OK; this.Close(); return; } else { // The module wasn't plugged in when the timer expired this.flashMulti.AppendLog(" timed out!\r\n"); using (new CenterWinDialog(this)) { MessageBox.Show("DFU device was not plugged in in time.", "Firmware Update", MessageBoxButtons.OK, MessageBoxIcon.Error); } this.DialogResult = DialogResult.Abort; this.Close(); return; } }
/// <summary> /// Populates the list of COM ports. /// </summary> private void PopulateComPorts() { if (this.InvokeRequired) { this.Invoke(new Action(this.PopulateComPorts)); return; } // Don't refresh if the control is not enabled if (!this.comPortSelector.Enabled) { return; } // Get the current list from the combobox so we can auto-select the new device var oldPortList = this.comPortSelector.Items; // Cache the selected item so we can try to re-select it later object selectedValue = null; selectedValue = this.comPortSelector.SelectedValue; // Enumerate the COM ports and bind the COM port selector List <ComPort> comPorts = new List <ComPort>(); comPorts = ComPort.EnumeratePortList(); // Check if we have a Maple device MapleDevice mapleCheck = MapleDevice.FindMaple(); this.comPortSelector.DataSource = comPorts; this.comPortSelector.DisplayMember = "Name"; this.comPortSelector.ValueMember = "Name"; // If we had an old list, compare it to the new one and pick the first item which is new if (oldPortList.Count > 0) { foreach (ComPort newPort in comPorts) { bool found = false; foreach (ComPort oldPort in oldPortList) { if (newPort.Name == oldPort.Name) { found = true; } } if (found == false) { Debug.WriteLine($"{newPort.Name} was added."); selectedValue = newPort.Name; } } } // Re-select the previously selected item if (selectedValue != null) { this.comPortSelector.SelectedValue = selectedValue; } else { this.comPortSelector.SelectedItem = null; } // Check if we there's a Maple device plugged in if (mapleCheck.DeviceFound) { // Set the Write Bootloader radio button and disable the controls if a Maple device is present // Required so that the firmware size is calculated correctly this.writeBootloader_Yes.Checked = true; this.writeBootloader_Yes.Enabled = false; this.writeBootloader_No.Enabled = false; } else { this.writeBootloader_Yes.Enabled = true; this.writeBootloader_No.Enabled = true; } // Set the width of the dropdown // this.comPortSelector.DropDownWidth = comPorts.Select(c => c.DisplayName).ToList().Max(x => TextRenderer.MeasureText(x, this.comPortSelector.Font).Width); // Make sure the Update button is disabled if there is no port selected this.CheckControls(); }
/// <summary> /// Main method where all the action happens. /// Called by the Upload button. /// </summary> private void ButtonUpload_Click(object sender, EventArgs e) { // Clear the output box Debug.WriteLine("Clearing the output textboxes..."); this.textActivity.Clear(); this.textVerbose.Clear(); this.progressBar1.Value = 0; // Check if the file exists if (!File.Exists(this.textFileName.Text)) { this.AppendLog(string.Format("File {0} does not exist", this.textFileName.Text)); MessageBox.Show("Firmware file does not exist.", "Write Firmware", MessageBoxButtons.OK, MessageBoxIcon.Error); this.EnableControls(true); return; } // Check that the file size is OK // Max size is 120,832B (118KB) with bootloader, 129,024B (126KB) without int maxFileSize = 129024; if (this.writeBootloader_Yes.Checked) { maxFileSize = 120832; } long length = new System.IO.FileInfo(this.textFileName.Text).Length; if (length > maxFileSize) { this.AppendLog(string.Format("Firmware file is too large.\r\nFile is {1:n0} KB, maximum size is {2:n0} KB.", this.textFileName.Text, length / 1024, maxFileSize / 1024)); MessageBox.Show("Firmware file is too large.", "Write Firmware", MessageBoxButtons.OK, MessageBoxIcon.Error); this.EnableControls(true); return; } // Get the selected COM port string comPort = this.comPortSelector.SelectedValue.ToString(); // Check if the port can be opened if (!ComPort.CheckPort(comPort)) { this.AppendLog(string.Format("Couldn't open port {0}", comPort)); MessageBox.Show(string.Format("Couldn't open port {0}", comPort), "Write Firmware", MessageBoxButtons.OK, MessageBoxIcon.Error); this.EnableControls(true); return; } // Disable the buttons until this flash attempt is complete Debug.WriteLine("Disabling the controls..."); this.EnableControls(false); // Determine if we should use Maple or serial interface MapleDevice mapleResult = MapleDevice.FindMaple(); if (mapleResult.DeviceFound == true) { this.AppendLog(string.Format("Maple device found in {0} mode\r\n", mapleResult.Mode)); } // Do the selected flash using the appropriate method if (mapleResult.DeviceFound == true) { // MapleFlashWrite(textFileName.Text, comPort); MapleDevice.WriteFlash(this, this.textFileName.Text, comPort); } else { SerialDevice.WriteFlash(this, this.textFileName.Text, comPort); } }