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);
        }
Пример #2
0
 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
            }
        }
Пример #4
0
        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;
            }
        }