Exemplo n.º 1
0
        /// <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);
            }
        }
Exemplo n.º 2
0
        /// <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();
        }
Exemplo n.º 3
0
        /// <summary>
        /// Finds a Maple device in either USB or DFU mode.
        /// </summary>
        /// <returns>Returns a <see cref="MapleDevice"/>.</returns>
        public static MapleDevice FindMaple()
        {
            MapleDevice result = new MapleDevice(false);

            var usbDevices = UsbDeviceInfo.GetUSBDevices();

            foreach (var usbDevice in usbDevices)
            {
                switch (usbDevice.PnpDeviceID.Substring(0, 21))
                {
                case "USB\\VID_1EAF&PID_0003":
                    result = new MapleDevice(true, "USB\\VID_1EAF&PID_0003", true, false, "DFU");
                    break;

                case "USB\\VID_1EAF&PID_0004":
                    result = new MapleDevice(true, "USB\\VID_1EAF&PID_0004", false, true, "USB");
                    break;

                default:
                    break;
                }
            }

            return(result);
        }
Exemplo n.º 4
0
        /// <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();
        }
Exemplo n.º 5
0
        /// <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);
            }
        }
Exemplo n.º 6
0
        /// <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;
            }
        }
Exemplo n.º 7
0
        /// <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);
        }
Exemplo n.º 8
0
        /// <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);
        }
Exemplo n.º 9
0
        /// <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();
            }
        }
Exemplo n.º 10
0
        /// <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());
        }
Exemplo n.º 11
0
        /// <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);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Gets the name of the Maple Device COM port.
        /// </summary>
        /// <returns>A string containing the COM port name.</returns>
        public static string GetMapleComPort()
        {
            string portName = null;

            MapleDevice device = FindMaple();

            if (device.DeviceFound)
            {
                _ = new List <ComPort>();
                List <ComPort> comPorts = ComPort.EnumeratePortList();

                foreach (ComPort port in comPorts)
                {
                    if (device.DeviceName.Contains(port.Name))
                    {
                        portName = port.Name;
                    }
                }
            }

            return(portName);
        }
Exemplo n.º 13
0
        /// <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();
            }
        }
Exemplo n.º 14
0
        /// <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);
        }
Exemplo n.º 15
0
        /// <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);
        }
Exemplo n.º 16
0
        /// <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);
        }
Exemplo n.º 17
0
        /// <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);
            }
        }
Exemplo n.º 18
0
        /// <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);
        }
Exemplo n.º 19
0
        /// <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();
        }
Exemplo n.º 20
0
        /// <summary>
        /// Async method to find a Maple device in either USB or DFU mode.
        /// </summary>
        /// <returns>Returns a <see cref="MapleDevice"/>.</returns>
        public static async Task <MapleDevice> FindMapleAsync()
        {
            MapleDevice mapleDevice = await Task.Run(() => FindMaple());

            return(mapleDevice);
        }
Exemplo n.º 21
0
        /// <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;
            }
        }
Exemplo n.º 22
0
        /// <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);
        }
Exemplo n.º 23
0
        /// <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);
        }
Exemplo n.º 24
0
        /// <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);
            }
        }