public void UploadSketch(IEnumerable <string> hexFileContents) { try { var serialPortName = _options.PortName; var allPortNames = SerialPortStream.GetPortNames(); var distinctPorts = allPortNames.Distinct().ToList(); // If we don't specify a COM port, automagically select one if there is only a single match. if (string.IsNullOrWhiteSpace(serialPortName) && distinctPorts.SingleOrDefault() != null) { Logger?.Info($"Port autoselected: {serialPortName}."); serialPortName = distinctPorts.Single(); } // Or else, check that we have an unambiguous match. Throw an exception otherwise. else if (!allPortNames.Any() || distinctPorts.SingleOrDefault( x => x.Equals(serialPortName, StringComparison.OrdinalIgnoreCase)) == null) { throw new ArduinoUploaderException( $"Specified COM port name '{serialPortName}' is not valid."); } Logger?.Trace($"Creating serial port '{serialPortName}'..."); ArduinoBootloaderProgrammer programmer; IMcu mcu; var model = _options.ArduinoModel.ToString(); var hardwareConfig = ReadConfiguration(); var modelOptions = hardwareConfig.Arduinos.SingleOrDefault( x => x.Model.Equals(model, StringComparison.OrdinalIgnoreCase)); if (modelOptions == null) { throw new ArduinoUploaderException($"Unable to find configuration for '{model}'!"); } switch (modelOptions.Mcu) { case McuIdentifier.AtMega1284: mcu = new AtMega1284(); break; case McuIdentifier.AtMega2560: mcu = new AtMega2560(); break; case McuIdentifier.AtMega32U4: mcu = new AtMega32U4(); break; case McuIdentifier.AtMega328P: mcu = new AtMega328P(); break; case McuIdentifier.AtMega168: mcu = new AtMega168(); break; default: throw new ArduinoUploaderException( $"Unrecognized MCU: '{modelOptions.Mcu}'!"); } var preOpenResetBehavior = ParseResetBehavior(modelOptions.PreOpenResetBehavior); var postOpenResetBehavior = ParseResetBehavior(modelOptions.PostOpenResetBehavior); var closeResetBehavior = ParseResetBehavior(modelOptions.CloseResetBehavior); var serialPortConfig = new SerialPortConfig(serialPortName, modelOptions.BaudRate, preOpenResetBehavior, postOpenResetBehavior, closeResetBehavior, modelOptions.SleepAfterOpen, modelOptions.ReadTimeout, modelOptions.WriteTimeout); switch (modelOptions.Protocol) { case Protocol.Avr109: programmer = new Avr109BootloaderProgrammer(serialPortConfig, mcu); break; case Protocol.Stk500v1: programmer = new Stk500V1BootloaderProgrammer(serialPortConfig, mcu); break; case Protocol.Stk500v2: programmer = new Stk500V2BootloaderProgrammer(serialPortConfig, mcu); break; default: throw new ArduinoUploaderException( $"Unrecognized protocol: '{modelOptions.Protocol}'!"); } try { programmer.Open(); Logger?.Info("Establishing sync..."); //programmer.EstablishSync(); Logger?.Info("Sync established."); Logger?.Info("Checking device signature..."); programmer.CheckDeviceSignature(); Logger?.Info("Device signature checked."); Logger?.Info("Initializing device..."); programmer.InitializeDevice(); Logger?.Info("Device initialized."); Logger?.Info("Enabling programming mode on the device..."); programmer.EnableProgrammingMode(); Logger?.Info("Programming mode enabled."); Logger?.Info("Programming device..."); programmer.ProgramDevice(ReadHexFile(hexFileContents, mcu.Flash.Size), _progress); Logger?.Info("Device programmed."); Logger?.Info("Leaving programming mode..."); programmer.LeaveProgrammingMode(); Logger?.Info("Left programming mode!"); } finally { programmer.Close(); } Logger?.Info("All done, shutting down!"); } catch (Exception ex) { Logger?.Error(ex.Message, ex); throw; } }
public void UploadSketch(IEnumerable <string> hexFileContents) { try { var serialPortName = _options.PortName; var allPortNames = SerialPortStream.GetPortNames(); var distinctPorts = allPortNames.Distinct().ToList(); // If we don't specify a COM port, automagically select one if there is only a single match. if (string.IsNullOrWhiteSpace(serialPortName) && distinctPorts.SingleOrDefault() != null) { Logger?.Info($"Port autoselected: {serialPortName}."); serialPortName = distinctPorts.Single(); } // Or else, check that we have an unambiguous match. Throw an exception otherwise. else if (!allPortNames.Any() || distinctPorts.SingleOrDefault( x => x.Equals(serialPortName, StringComparison.OrdinalIgnoreCase)) == null) { throw new ArduinoUploaderException( $"Specified COM port name '{serialPortName}' is not valid."); } Logger?.Trace($"Creating serial port '{serialPortName}'..."); ArduinoBootloaderProgrammer programmer; IMcu mcu; SerialPortConfig serialPortConfig; switch (_options.ArduinoModel) { case ArduinoModel.Mega1284: { mcu = new AtMega1284(); serialPortConfig = new SerialPortConfig(serialPortName, 115200, new ResetThroughEnablingDtrBehavior(), new ResetThroughTogglingDtrRtsBehavior(250, 50), 250); programmer = new Stk500V1BootloaderProgrammer(serialPortConfig, mcu); break; } case ArduinoModel.Mega2560: { mcu = new AtMega2560(); serialPortConfig = new SerialPortConfig(serialPortName, 115200, new ResetThroughEnablingDtrBehavior(), new ResetThroughTogglingDtrRtsBehavior(50, 50, true), 50); programmer = new Stk500V2BootloaderProgrammer(serialPortConfig, mcu); break; } case ArduinoModel.Leonardo: case ArduinoModel.Micro: { mcu = new AtMega32U4(); serialPortConfig = new SerialPortConfig(serialPortName, 57600, new ResetThrough1200BpsBehavior(), null); programmer = new Avr109BootloaderProgrammer(serialPortConfig, mcu); break; } case ArduinoModel.NanoR2: { mcu = new AtMega168(); serialPortConfig = new SerialPortConfig(serialPortName, 19200, new ResetThroughEnablingDtrBehavior(), new ResetThroughTogglingDtrRtsBehavior(250, 50), 250); programmer = new Stk500V1BootloaderProgrammer(serialPortConfig, mcu); break; } case ArduinoModel.NanoR3: { mcu = new AtMega328P(); serialPortConfig = new SerialPortConfig(serialPortName, 57600, new ResetThroughEnablingDtrBehavior(), new ResetThroughTogglingDtrRtsBehavior(250, 50), 250); programmer = new Stk500V1BootloaderProgrammer(serialPortConfig, mcu); break; } case ArduinoModel.UnoR3: { mcu = new AtMega328P(); serialPortConfig = new SerialPortConfig(serialPortName, 115200, new ResetThroughEnablingDtrBehavior(), new ResetThroughTogglingDtrRtsBehavior(250, 50), 250); programmer = new Stk500V1BootloaderProgrammer(serialPortConfig, mcu); break; } default: { throw new ArduinoUploaderException($"Unsupported model: {_options.ArduinoModel}!"); } } try { programmer.Open(); Logger?.Info("Establishing sync..."); programmer.EstablishSync(); Logger?.Info("Sync established."); Logger?.Info("Checking device signature..."); programmer.CheckDeviceSignature(); Logger?.Info("Device signature checked."); Logger?.Info("Initializing device..."); programmer.InitializeDevice(); Logger?.Info("Device initialized."); Logger?.Info("Enabling programming mode on the device..."); programmer.EnableProgrammingMode(); Logger?.Info("Programming mode enabled."); Logger?.Info("Programming device..."); programmer.ProgramDevice(ReadHexFile(hexFileContents, mcu.Flash.Size), _progress); Logger?.Info("Device programmed."); Logger?.Info("Leaving programming mode..."); programmer.LeaveProgrammingMode(); Logger?.Info("Left programming mode!"); } finally { programmer.Close(); } Logger?.Info("All done, shutting down!"); } catch (Exception ex) { Logger?.Error(ex.Message, ex); throw; } }