Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added lib/silink/JLinkARM.dll
Binary file not shown.
Binary file added lib/silink/Qt5Core.dll
Binary file not shown.
Binary file added lib/silink/Qt5Network.dll
Binary file not shown.
Binary file added lib/silink/emdll0.dll
Binary file not shown.
Binary file added lib/silink/libapack.dll
Binary file not shown.
Binary file added lib/silink/libgcc_s_dw2-1.dll
Binary file not shown.
Binary file added lib/silink/libstdc++-6.dll
Binary file not shown.
Binary file added lib/silink/libwinpthread-1.dll
Binary file not shown.
Binary file added lib/silink/silink.exe
Binary file not shown.
Binary file added lib/silink/zlib1.dll
Binary file not shown.
6 changes: 6 additions & 0 deletions nanoFirmwareFlasher/ExitCodes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,12 @@ public enum ExitCodes
[Display(Name = "No J-Link device found. Make sure it's connected.")]
E8001 = 8001,

/// <summary>
/// Error executing silink command.
/// </summary>
[Display(Name = "Error executing silink CLI command.")]
E8002 = 8002,

////////////////////////////////
// Application general Errors //
////////////////////////////////
Expand Down
7 changes: 7 additions & 0 deletions nanoFirmwareFlasher/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1125,6 +1125,7 @@ static async Task RunOptionsAndReturnExitCodeAsync(Options o)

var connectedJLinkDevices = JLinkDevice.ListDevices();


if (o.BinFile.Any()
&& connectedJLinkDevices.Count != 0)
{
Expand All @@ -1147,6 +1148,9 @@ static async Task RunOptionsAndReturnExitCodeAsync(Options o)
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;

Expand Down Expand Up @@ -1196,6 +1200,9 @@ static async Task RunOptionsAndReturnExitCodeAsync(Options o)

operationPerformed = true;

// set VCP baud rate (if needed)
_ = SilinkCli.SetVcpBaudRate(o.JLinkDeviceId is null ? connectedJLinkDevices.First() : "");

if (_exitCode != ExitCodes.OK)
{
// done here
Expand Down
197 changes: 197 additions & 0 deletions nanoFirmwareFlasher/SilinkCli.cs
Original file line number Diff line number Diff line change
@@ -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;

/// <summary>
/// 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.
/// </summary>
/// <param name="probeId">Id of the JLink probe to adjust the baud rate.</param>
/// <param name="verbosity">Verbosity level for the operation. <see cref="VerbosityLevel.Quiet"/> will be used if not specified.</param>
/// <returns></returns>
/// <remarks>
/// Currently this operation is only supported in Windows machines.
/// </remarks>
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;
}
}
}
2 changes: 2 additions & 0 deletions nanoFirmwareFlasher/nanoFirmwareFlasher.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@
</None>
<None Include="..\lib\jlinkLinux\**" Link="jlinkLinux\%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="Always">
</None>
<None Include="..\lib\silink\**" Link="silink\%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="Always">
</None>
</ItemGroup>
<ItemGroup>
<None Include="..\lib\uniflash\**" Link="uniflash\%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="Always">
Expand Down