diff --git a/lib/silink/JLinkARM.dll b/lib/silink/JLinkARM.dll new file mode 100644 index 0000000..121285f Binary files /dev/null and b/lib/silink/JLinkARM.dll differ diff --git a/lib/silink/Qt5Core.dll b/lib/silink/Qt5Core.dll new file mode 100644 index 0000000..d3649bb Binary files /dev/null and b/lib/silink/Qt5Core.dll differ diff --git a/lib/silink/Qt5Network.dll b/lib/silink/Qt5Network.dll new file mode 100644 index 0000000..a5e3e9e Binary files /dev/null and b/lib/silink/Qt5Network.dll differ diff --git a/lib/silink/emdll0.dll b/lib/silink/emdll0.dll new file mode 100644 index 0000000..d2c8d84 Binary files /dev/null and b/lib/silink/emdll0.dll differ diff --git a/lib/silink/libapack.dll b/lib/silink/libapack.dll new file mode 100644 index 0000000..17aa51b Binary files /dev/null and b/lib/silink/libapack.dll differ diff --git a/lib/silink/libgcc_s_dw2-1.dll b/lib/silink/libgcc_s_dw2-1.dll new file mode 100644 index 0000000..896978e Binary files /dev/null and b/lib/silink/libgcc_s_dw2-1.dll differ diff --git a/lib/silink/libstdc++-6.dll b/lib/silink/libstdc++-6.dll new file mode 100644 index 0000000..0acba06 Binary files /dev/null and b/lib/silink/libstdc++-6.dll differ diff --git a/lib/silink/libwinpthread-1.dll b/lib/silink/libwinpthread-1.dll new file mode 100644 index 0000000..6d088c9 Binary files /dev/null and b/lib/silink/libwinpthread-1.dll differ diff --git a/lib/silink/silink.exe b/lib/silink/silink.exe new file mode 100644 index 0000000..f507d4c Binary files /dev/null and b/lib/silink/silink.exe differ diff --git a/lib/silink/zlib1.dll b/lib/silink/zlib1.dll new file mode 100644 index 0000000..f7099fd Binary files /dev/null and b/lib/silink/zlib1.dll differ diff --git a/nanoFirmwareFlasher/ExitCodes.cs b/nanoFirmwareFlasher/ExitCodes.cs index b12b4cb..f993746 100644 --- a/nanoFirmwareFlasher/ExitCodes.cs +++ b/nanoFirmwareFlasher/ExitCodes.cs @@ -208,6 +208,12 @@ namespace nanoFramework.Tools.FirmwareFlasher [Display(Name = "No J-Link device found. Make sure it's connected.")] E8001 = 8001, + /// + /// Error executing silink command. + /// + [Display(Name = "Error executing silink CLI command.")] + E8002 = 8002, + //////////////////////////////// // Application general Errors // //////////////////////////////// diff --git a/nanoFirmwareFlasher/Program.cs b/nanoFirmwareFlasher/Program.cs index aaa4b1a..8b932a1 100644 --- a/nanoFirmwareFlasher/Program.cs +++ b/nanoFirmwareFlasher/Program.cs @@ -1125,6 +1125,7 @@ namespace nanoFramework.Tools.FirmwareFlasher var connectedJLinkDevices = JLinkDevice.ListDevices(); + if (o.BinFile.Any() && connectedJLinkDevices.Count != 0) { @@ -1147,6 +1148,9 @@ namespace nanoFramework.Tools.FirmwareFlasher Console.WriteLine($"Connected to J-Link device with ID {jlinkDevice.ProbeId}"); } + // set VCP baud rate (if needed) + _ = SilinkCli.SetVcpBaudRate(o.JLinkDeviceId is null ? connectedJLinkDevices.First() : ""); + // set verbosity jlinkDevice.Verbosity = _verbosityLevel; @@ -1196,6 +1200,9 @@ namespace nanoFramework.Tools.FirmwareFlasher operationPerformed = true; + // set VCP baud rate (if needed) + _ = SilinkCli.SetVcpBaudRate(o.JLinkDeviceId is null ? connectedJLinkDevices.First() : ""); + if (_exitCode != ExitCodes.OK) { // done here diff --git a/nanoFirmwareFlasher/SilinkCli.cs b/nanoFirmwareFlasher/SilinkCli.cs new file mode 100644 index 0000000..6a5b658 --- /dev/null +++ b/nanoFirmwareFlasher/SilinkCli.cs @@ -0,0 +1,197 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +using System; +using System.Diagnostics; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Runtime.InteropServices; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; + +namespace nanoFramework.Tools.FirmwareFlasher +{ + internal class SilinkCli + { + private const int SilinkTelnetPort = 49000; + private const int SilinkAdminPort = SilinkTelnetPort + 2; + private const int TargetBaudRate = 921600; + + /// + /// This will set the baud rate of the VCP in a Silabs Jlink board. + /// Before setting the value the devices is queried and the new setting is applied only if needed. + /// + /// Id of the JLink probe to adjust the baud rate. + /// Verbosity level for the operation. will be used if not specified. + /// + /// + /// Currently this operation is only supported in Windows machines. + /// + public static ExitCodes SetVcpBaudRate( + string probeId, + VerbosityLevel verbosity = VerbosityLevel.Quiet) + { + // check that we can run on this platform + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) + || RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Console.WriteLine(""); + Console.ForegroundColor = ConsoleColor.Yellow; + + Console.WriteLine($"Setting VCP baud rate in {OSPlatform.OSX} is not supported."); + + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine(""); + + return ExitCodes.E8002; + } + + // launch silink + var silinkCli = RunSilinkCLI(Path.Combine(probeId)); + + var silinkSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + IPEndPoint silinkEndPoint = new(IPAddress.Parse("127.0.0.1"), SilinkAdminPort); + + try + { + silinkSocket.Connect(silinkEndPoint); + + Thread.Sleep(250); + + // query current config + byte[] buffer = Encoding.Default.GetBytes("serial vcom\r"); + silinkSocket.Send(buffer); + + Thread.Sleep(250); + + buffer = new byte[1024]; + int receiveCount = silinkSocket.Receive(buffer, 0, buffer.Length, 0); + + var currentConfig = Encoding.Default.GetString(buffer, 0, receiveCount); + + if (!string.IsNullOrEmpty(currentConfig)) + { + // interpret reply + const string regexPattern = "(?:Stored port speed : )(?'baudrate'\\d+)"; + + var myRegex1 = new Regex(regexPattern, RegexOptions.Multiline); + var currentBaud = myRegex1.Match(currentConfig); + + if (currentBaud.Success) + { + // verify current setting + if (int.TryParse(currentBaud.Groups["baudrate"].Value, out int baudRate) && baudRate == TargetBaudRate) + { + return ExitCodes.OK; + } + } + + // need to set baud rate because it's different + + if (verbosity >= VerbosityLevel.Normal) + { + Console.Write("Setting VCP baud rate..."); + } + + Thread.Sleep(250); + + // compose command + buffer = Encoding.Default.GetBytes("serial vcom config speed {TargetBaudRate}\r"); + silinkSocket.Send(buffer); + + Thread.Sleep(250); + + buffer = new byte[1024]; + receiveCount = silinkSocket.Receive(buffer, 0, buffer.Length, 0); + + var opResult = Encoding.Default.GetString(buffer, 0, receiveCount); + + if (opResult.Contains("Baudrate set to 921600 bps")) + { + if (verbosity >= VerbosityLevel.Normal) + { + Console.ForegroundColor = ConsoleColor.Green; + Console.WriteLine(" OK"); + + Console.WriteLine(""); + + Console.ForegroundColor = ConsoleColor.White; + } + + return ExitCodes.OK; + } + else + { + if (verbosity >= VerbosityLevel.Normal) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("FAILED!"); + + Console.WriteLine(""); + Console.ForegroundColor = ConsoleColor.Red; + + Console.WriteLine($"{opResult.Replace("PK> ", "")}"); + + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine(""); + } + + return ExitCodes.E8002; + } + } + } + catch (Exception ex) + { + Console.WriteLine(""); + Console.ForegroundColor = ConsoleColor.Red; + + Console.WriteLine($"Error occurred: {ex.Message}"); + + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine(""); + + return ExitCodes.E8002; + } + finally + { + // close socket + silinkSocket?.Close(); + + // kill process tree (to include JLink) + silinkCli.Kill(true); + } + + return ExitCodes.E8002; + } + + internal static Process RunSilinkCLI(string probeId) + { + // prepare the process start of J-Link + string appName = "silink.exe"; + string appDir = Path.Combine(Program.ExecutingPath, "silink"); + + + Process silinkCli = new Process(); + string parameter = $" -sn {probeId} -automap {SilinkTelnetPort}"; + + silinkCli.StartInfo = new ProcessStartInfo(Path.Combine(appDir, appName), parameter) + { + WorkingDirectory = appDir, + UseShellExecute = false, + RedirectStandardError = true, + RedirectStandardOutput = true, + WindowStyle = ProcessWindowStyle.Hidden + }; + + // start siLink CLI and... + silinkCli.Start(); + + // ... return the process + return silinkCli; + } + } +} diff --git a/nanoFirmwareFlasher/nanoFirmwareFlasher.csproj b/nanoFirmwareFlasher/nanoFirmwareFlasher.csproj index 872cc6a..9caaef2 100755 --- a/nanoFirmwareFlasher/nanoFirmwareFlasher.csproj +++ b/nanoFirmwareFlasher/nanoFirmwareFlasher.csproj @@ -103,6 +103,8 @@ + +