public override void Open() { string portName = SerialPortConfig.PortName; int baudRate = SerialPortConfig.BaudRate; Logger?.Info($"Opening serial port {portName} - baudrate {baudRate}"); SerialPort = new SerialPortStream(portName, baudRate) { ReadTimeout = SerialPortConfig.ReadTimeOut, WriteTimeout = SerialPortConfig.WriteTimeOut }; IResetBehavior preOpen = SerialPortConfig.PreOpenResetBehavior; if (preOpen != null) { Logger?.Info($"Executing Pre Open behavior ({preOpen})..."); SerialPort = preOpen.Reset(SerialPort, SerialPortConfig); } try { if (!SerialPort.IsOpen) { SerialPort.Open(); } } catch (ObjectDisposedException ex) { throw new ArduinoUploaderException($"Unable to open serial port {portName} - {ex.Message}."); } catch (InvalidOperationException ex) { throw new ArduinoUploaderException($"Unable to open serial port {portName} - {ex.Message}."); } Logger?.Trace($"Opened serial port {portName} with baud rate {baudRate}!"); IResetBehavior postOpen = SerialPortConfig.PostOpenResetBehavior; if (postOpen != null) { Logger?.Info($"Executing Post Open behavior ({postOpen})..."); SerialPort = postOpen.Reset(SerialPort, SerialPortConfig); } int sleepAfterOpen = SerialPortConfig.SleepAfterOpen; if (SerialPortConfig.SleepAfterOpen <= 0) { return; } Logger?.Trace($"Sleeping for {sleepAfterOpen} ms after open..."); Thread.Sleep(sleepAfterOpen); }
public SerialPortConfig( string portName, int baudRate, IResetBehavior postOpenResetBehavior, IResetBehavior closeResetAction, int sleepAfterOpen = 0, int readTimeout = DefaultTimeout, int writeTimeout = DefaultTimeout) { PortName = portName; BaudRate = baudRate; PostOpenResetBehavior = postOpenResetBehavior; CloseResetAction = closeResetAction; SleepAfterOpen = sleepAfterOpen; ReadTimeOut = readTimeout; WriteTimeOut = writeTimeout; }
public override void Close() { IResetBehavior preClose = SerialPortConfig.CloseResetAction; if (preClose != null) { Logger?.Info("Resetting..."); SerialPort = preClose.Reset(SerialPort, SerialPortConfig); } Logger?.Info("Closing serial port..."); SerialPort.DtrEnable = false; SerialPort.RtsEnable = false; try { SerialPort.Close(); } catch (Exception) { // Ignore } }
public void UploadSketch(IEnumerable <string> hexFileContents) { try { string serialPortName = _options.PortName; string[] allPortNames = SerialPortStream.GetPortNames(); List <string> 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; string model = _options.ArduinoModel.ToString(); Configuration hardwareConfig = ReadConfiguration(); Arduino 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}'!"); } IResetBehavior preOpenResetBehavior = ParseResetBehavior(modelOptions.PreOpenResetBehavior); IResetBehavior postOpenResetBehavior = ParseResetBehavior(modelOptions.PostOpenResetBehavior); IResetBehavior 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 { Logger?.Info("Establishing memory block contents..."); MemoryBlock memoryBlockContents = ReadHexFile(hexFileContents, mcu.Flash.Size); 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(memoryBlockContents, _progress); Logger?.Info("Device programmed."); Logger?.Info("Verifying program..."); programmer.VerifyProgram(memoryBlockContents, _progress); Logger?.Info("Verified program!"); 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; } }