Updated schematics, new applications

This commit is contained in:
Agustín Gimenez 2022-07-13 17:07:56 +02:00
parent 36c7e79744
commit f33e8ab042
27 changed files with 1278 additions and 104 deletions

5
.gitignore vendored
View File

@ -360,4 +360,7 @@ MigrationBackup/
.ionide/ .ionide/
# Fody - auto-generated XML schema # Fody - auto-generated XML schema
FodyWeavers.xsd FodyWeavers.xsd
#Releases folder
Releases/

View File

@ -1730,10 +1730,10 @@
(property "Reference" "C12" (id 0) (at 78.105 162.56 0) (property "Reference" "C12" (id 0) (at 78.105 162.56 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Value" "C" (id 1) (at 78.105 167.64 0) (property "Value" "" (id 1) (at 71.12 170.18 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Footprint" "Capacitor_SMD:C_0603_1608Metric" (id 2) (at 78.4352 168.91 0) (property "Footprint" "" (id 2) (at 78.4352 168.91 0)
(effects (font (size 1.27 1.27)) hide) (effects (font (size 1.27 1.27)) hide)
) )
(property "Datasheet" "~" (id 3) (at 77.47 165.1 0) (property "Datasheet" "~" (id 3) (at 77.47 165.1 0)
@ -1749,10 +1749,10 @@
(property "Reference" "C8" (id 0) (at 65.405 162.56 0) (property "Reference" "C8" (id 0) (at 65.405 162.56 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Value" "C" (id 1) (at 65.405 167.64 0) (property "Value" "" (id 1) (at 58.42 170.18 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Footprint" "Capacitor_SMD:C_0603_1608Metric" (id 2) (at 65.7352 168.91 0) (property "Footprint" "" (id 2) (at 65.7352 168.91 0)
(effects (font (size 1.27 1.27)) hide) (effects (font (size 1.27 1.27)) hide)
) )
(property "Datasheet" "~" (id 3) (at 64.77 165.1 0) (property "Datasheet" "~" (id 3) (at 64.77 165.1 0)
@ -1799,10 +1799,10 @@
(property "Reference" "C11" (id 0) (at 78.105 147.32 0) (property "Reference" "C11" (id 0) (at 78.105 147.32 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Value" "C" (id 1) (at 78.105 152.4 0) (property "Value" "" (id 1) (at 71.12 154.94 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Footprint" "Capacitor_SMD:C_0603_1608Metric" (id 2) (at 78.4352 153.67 0) (property "Footprint" "" (id 2) (at 78.4352 153.67 0)
(effects (font (size 1.27 1.27)) hide) (effects (font (size 1.27 1.27)) hide)
) )
(property "Datasheet" "~" (id 3) (at 77.47 149.86 0) (property "Datasheet" "~" (id 3) (at 77.47 149.86 0)
@ -1818,10 +1818,10 @@
(property "Reference" "C4" (id 0) (at 52.705 162.56 0) (property "Reference" "C4" (id 0) (at 52.705 162.56 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Value" "C" (id 1) (at 52.705 167.64 0) (property "Value" "" (id 1) (at 45.72 170.18 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Footprint" "Capacitor_SMD:C_0603_1608Metric" (id 2) (at 53.0352 168.91 0) (property "Footprint" "" (id 2) (at 53.0352 168.91 0)
(effects (font (size 1.27 1.27)) hide) (effects (font (size 1.27 1.27)) hide)
) )
(property "Datasheet" "~" (id 3) (at 52.07 165.1 0) (property "Datasheet" "~" (id 3) (at 52.07 165.1 0)
@ -1837,10 +1837,10 @@
(property "Reference" "C6" (id 0) (at 59.055 162.56 0) (property "Reference" "C6" (id 0) (at 59.055 162.56 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Value" "C" (id 1) (at 59.055 167.64 0) (property "Value" "" (id 1) (at 52.07 167.64 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Footprint" "Capacitor_SMD:C_0603_1608Metric" (id 2) (at 59.3852 168.91 0) (property "Footprint" "" (id 2) (at 59.3852 168.91 0)
(effects (font (size 1.27 1.27)) hide) (effects (font (size 1.27 1.27)) hide)
) )
(property "Datasheet" "~" (id 3) (at 58.42 165.1 0) (property "Datasheet" "~" (id 3) (at 58.42 165.1 0)
@ -1856,10 +1856,10 @@
(property "Reference" "C1" (id 0) (at 46.355 147.32 0) (property "Reference" "C1" (id 0) (at 46.355 147.32 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Value" "C" (id 1) (at 46.355 152.4 0) (property "Value" "" (id 1) (at 39.37 152.4 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Footprint" "Capacitor_SMD:C_0603_1608Metric" (id 2) (at 46.6852 153.67 0) (property "Footprint" "" (id 2) (at 46.6852 153.67 0)
(effects (font (size 1.27 1.27)) hide) (effects (font (size 1.27 1.27)) hide)
) )
(property "Datasheet" "~" (id 3) (at 45.72 149.86 0) (property "Datasheet" "~" (id 3) (at 45.72 149.86 0)
@ -1904,8 +1904,8 @@
(in_bom yes) (on_board yes) (fields_autoplaced) (in_bom yes) (on_board yes) (fields_autoplaced)
(uuid 6cac8c39-815f-4cff-9d09-f222b31d9be6) (uuid 6cac8c39-815f-4cff-9d09-f222b31d9be6)
(property "Reference" "J2" (id 0) (at 214.63 73.66 0)) (property "Reference" "J2" (id 0) (at 214.63 73.66 0))
(property "Value" "" (id 1) (at 214.63 76.2 0)) (property "Value" "Conn_02x15_Odd_Even" (id 1) (at 214.63 76.2 0))
(property "Footprint" "" (id 2) (at 213.36 97.79 0) (property "Footprint" "Connector_PinHeader_2.54mm:PinHeader_2x15_P2.54mm_Horizontal" (id 2) (at 213.36 97.79 0)
(effects (font (size 1.27 1.27)) hide) (effects (font (size 1.27 1.27)) hide)
) )
(property "Datasheet" "~" (id 3) (at 213.36 97.79 0) (property "Datasheet" "~" (id 3) (at 213.36 97.79 0)
@ -1949,10 +1949,10 @@
(property "Reference" "C7" (id 0) (at 65.405 147.32 0) (property "Reference" "C7" (id 0) (at 65.405 147.32 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Value" "C" (id 1) (at 65.405 152.4 0) (property "Value" "" (id 1) (at 58.42 154.94 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Footprint" "Capacitor_SMD:C_0603_1608Metric" (id 2) (at 65.7352 153.67 0) (property "Footprint" "" (id 2) (at 65.7352 153.67 0)
(effects (font (size 1.27 1.27)) hide) (effects (font (size 1.27 1.27)) hide)
) )
(property "Datasheet" "~" (id 3) (at 64.77 149.86 0) (property "Datasheet" "~" (id 3) (at 64.77 149.86 0)
@ -1968,10 +1968,10 @@
(property "Reference" "C5" (id 0) (at 59.055 147.32 0) (property "Reference" "C5" (id 0) (at 59.055 147.32 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Value" "C" (id 1) (at 59.055 152.4 0) (property "Value" "" (id 1) (at 52.07 152.4 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Footprint" "Capacitor_SMD:C_0603_1608Metric" (id 2) (at 59.3852 153.67 0) (property "Footprint" "" (id 2) (at 59.3852 153.67 0)
(effects (font (size 1.27 1.27)) hide) (effects (font (size 1.27 1.27)) hide)
) )
(property "Datasheet" "~" (id 3) (at 58.42 149.86 0) (property "Datasheet" "~" (id 3) (at 58.42 149.86 0)
@ -1987,10 +1987,10 @@
(property "Reference" "C3" (id 0) (at 52.705 147.32 0) (property "Reference" "C3" (id 0) (at 52.705 147.32 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Value" "C" (id 1) (at 52.705 152.4 0) (property "Value" "" (id 1) (at 45.72 154.94 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Footprint" "Capacitor_SMD:C_0603_1608Metric" (id 2) (at 53.0352 153.67 0) (property "Footprint" "" (id 2) (at 53.0352 153.67 0)
(effects (font (size 1.27 1.27)) hide) (effects (font (size 1.27 1.27)) hide)
) )
(property "Datasheet" "~" (id 3) (at 52.07 149.86 0) (property "Datasheet" "~" (id 3) (at 52.07 149.86 0)
@ -2130,10 +2130,10 @@
(property "Reference" "C9" (id 0) (at 71.755 147.32 0) (property "Reference" "C9" (id 0) (at 71.755 147.32 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Value" "C" (id 1) (at 71.755 152.4 0) (property "Value" "" (id 1) (at 64.77 152.4 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Footprint" "Capacitor_SMD:C_0603_1608Metric" (id 2) (at 72.0852 153.67 0) (property "Footprint" "" (id 2) (at 72.0852 153.67 0)
(effects (font (size 1.27 1.27)) hide) (effects (font (size 1.27 1.27)) hide)
) )
(property "Datasheet" "~" (id 3) (at 71.12 149.86 0) (property "Datasheet" "~" (id 3) (at 71.12 149.86 0)
@ -2149,10 +2149,10 @@
(property "Reference" "C2" (id 0) (at 46.355 162.56 0) (property "Reference" "C2" (id 0) (at 46.355 162.56 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Value" "C" (id 1) (at 46.355 167.64 0) (property "Value" "" (id 1) (at 39.37 167.64 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Footprint" "Capacitor_SMD:C_0603_1608Metric" (id 2) (at 46.6852 168.91 0) (property "Footprint" "" (id 2) (at 46.6852 168.91 0)
(effects (font (size 1.27 1.27)) hide) (effects (font (size 1.27 1.27)) hide)
) )
(property "Datasheet" "~" (id 3) (at 45.72 165.1 0) (property "Datasheet" "~" (id 3) (at 45.72 165.1 0)
@ -2168,10 +2168,10 @@
(property "Reference" "C10" (id 0) (at 71.755 162.56 0) (property "Reference" "C10" (id 0) (at 71.755 162.56 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Value" "C" (id 1) (at 71.755 167.64 0) (property "Value" "" (id 1) (at 64.77 167.64 0)
(effects (font (size 1.27 1.27)) (justify left)) (effects (font (size 1.27 1.27)) (justify left))
) )
(property "Footprint" "Capacitor_SMD:C_0603_1608Metric" (id 2) (at 72.0852 168.91 0) (property "Footprint" "" (id 2) (at 72.0852 168.91 0)
(effects (font (size 1.27 1.27)) hide) (effects (font (size 1.27 1.27)) hide)
) )
(property "Datasheet" "~" (id 3) (at 71.12 165.1 0) (property "Datasheet" "~" (id 3) (at 71.12 165.1 0)
@ -2185,8 +2185,8 @@
(in_bom yes) (on_board yes) (fields_autoplaced) (in_bom yes) (on_board yes) (fields_autoplaced)
(uuid fd7a9d01-6879-446c-ae2d-79a9c89ce315) (uuid fd7a9d01-6879-446c-ae2d-79a9c89ce315)
(property "Reference" "J1" (id 0) (at 214.63 22.86 0)) (property "Reference" "J1" (id 0) (at 214.63 22.86 0))
(property "Value" "" (id 1) (at 214.63 25.4 0)) (property "Value" "Conn_02x15_Odd_Even" (id 1) (at 214.63 25.4 0))
(property "Footprint" "" (id 2) (at 213.36 46.99 0) (property "Footprint" "Connector_PinSocket_2.54mm:PinSocket_2x15_P2.54mm_Horizontal" (id 2) (at 213.36 46.99 0)
(effects (font (size 1.27 1.27)) hide) (effects (font (size 1.27 1.27)) hide)
) )
(property "Datasheet" "~" (id 3) (at 213.36 46.99 0) (property "Datasheet" "~" (id 3) (at 213.36 46.99 0)
@ -2230,40 +2230,40 @@
(symbol_instances (symbol_instances
(path "/64a70fbb-9737-4a9e-a1ce-8b5215897e72" (path "/64a70fbb-9737-4a9e-a1ce-8b5215897e72"
(reference "C1") (unit 1) (value "C") (footprint "Capacitor_SMD:C_0603_1608Metric") (reference "C1") (unit 1) (value "100nf 16v") (footprint "Capacitor_SMD:C_0603_1608Metric")
) )
(path "/e0e76faf-8022-4b52-bc87-2867eed80d5a" (path "/e0e76faf-8022-4b52-bc87-2867eed80d5a"
(reference "C2") (unit 1) (value "C") (footprint "Capacitor_SMD:C_0603_1608Metric") (reference "C2") (unit 1) (value "100nf 16v") (footprint "Capacitor_SMD:C_0603_1608Metric")
) )
(path "/aef37177-f63f-4fa4-a49c-920b1eedfc74" (path "/aef37177-f63f-4fa4-a49c-920b1eedfc74"
(reference "C3") (unit 1) (value "C") (footprint "Capacitor_SMD:C_0603_1608Metric") (reference "C3") (unit 1) (value "100nf 16v") (footprint "Capacitor_SMD:C_0603_1608Metric")
) )
(path "/51686eed-d06e-40b4-867d-060618c735af" (path "/51686eed-d06e-40b4-867d-060618c735af"
(reference "C4") (unit 1) (value "C") (footprint "Capacitor_SMD:C_0603_1608Metric") (reference "C4") (unit 1) (value "100nf 16v") (footprint "Capacitor_SMD:C_0603_1608Metric")
) )
(path "/8c5249bf-6898-4f48-87c8-9e04fb1996c5" (path "/8c5249bf-6898-4f48-87c8-9e04fb1996c5"
(reference "C5") (unit 1) (value "C") (footprint "Capacitor_SMD:C_0603_1608Metric") (reference "C5") (unit 1) (value "100nf 16v") (footprint "Capacitor_SMD:C_0603_1608Metric")
) )
(path "/5efc62cb-051d-4992-9f32-0a92869698a9" (path "/5efc62cb-051d-4992-9f32-0a92869698a9"
(reference "C6") (unit 1) (value "C") (footprint "Capacitor_SMD:C_0603_1608Metric") (reference "C6") (unit 1) (value "100nf 16v") (footprint "Capacitor_SMD:C_0603_1608Metric")
) )
(path "/7c3c6d00-6412-4938-b80a-e13de4921c7f" (path "/7c3c6d00-6412-4938-b80a-e13de4921c7f"
(reference "C7") (unit 1) (value "C") (footprint "Capacitor_SMD:C_0603_1608Metric") (reference "C7") (unit 1) (value "100nf 16v") (footprint "Capacitor_SMD:C_0603_1608Metric")
) )
(path "/375174a7-7815-4e69-bf06-fe0dff3f2fe6" (path "/375174a7-7815-4e69-bf06-fe0dff3f2fe6"
(reference "C8") (unit 1) (value "C") (footprint "Capacitor_SMD:C_0603_1608Metric") (reference "C8") (unit 1) (value "100nf 16v") (footprint "Capacitor_SMD:C_0603_1608Metric")
) )
(path "/d48f5449-e275-4df2-84bc-f40d43fc6ffe" (path "/d48f5449-e275-4df2-84bc-f40d43fc6ffe"
(reference "C9") (unit 1) (value "C") (footprint "Capacitor_SMD:C_0603_1608Metric") (reference "C9") (unit 1) (value "100nf 16v") (footprint "Capacitor_SMD:C_0603_1608Metric")
) )
(path "/f9fc8b9f-a8d8-4e68-be4b-36a54206d91b" (path "/f9fc8b9f-a8d8-4e68-be4b-36a54206d91b"
(reference "C10") (unit 1) (value "C") (footprint "Capacitor_SMD:C_0603_1608Metric") (reference "C10") (unit 1) (value "100nf 16v") (footprint "Capacitor_SMD:C_0603_1608Metric")
) )
(path "/4bc45da6-b375-42ac-ba9e-262a4323f1b0" (path "/4bc45da6-b375-42ac-ba9e-262a4323f1b0"
(reference "C11") (unit 1) (value "C") (footprint "Capacitor_SMD:C_0603_1608Metric") (reference "C11") (unit 1) (value "100nf 16v") (footprint "Capacitor_SMD:C_0603_1608Metric")
) )
(path "/040e7661-85a0-483b-ae6c-7b6f489c582f" (path "/040e7661-85a0-483b-ae6c-7b6f489c582f"
(reference "C12") (unit 1) (value "C") (footprint "Capacitor_SMD:C_0603_1608Metric") (reference "C12") (unit 1) (value "100nf 16v") (footprint "Capacitor_SMD:C_0603_1608Metric")
) )
(path "/fd7a9d01-6879-446c-ae2d-79a9c89ce315" (path "/fd7a9d01-6879-446c-ae2d-79a9c89ce315"
(reference "J1") (unit 1) (value "Conn_02x15_Odd_Even") (footprint "Connector_PinSocket_2.54mm:PinSocket_2x15_P2.54mm_Horizontal") (reference "J1") (unit 1) (value "Conn_02x15_Odd_Even") (footprint "Connector_PinSocket_2.54mm:PinSocket_2x15_P2.54mm_Horizontal")

View File

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.9.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SharedDriver\SharedDriver.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CommandLine;
namespace CLCapture
{
public class CLCaptureCommandLineOptions
{
[Value(0, Required = true, HelpText = "Device's serial port.")]
public string? SerialPort { get; set; }
[Value(1, Required = true, HelpText = "Desired sampling frequency.")]
public int SamplingFrequency { get; set; }
[Value(2, Required = true, HelpText = "List of channels to capture (channels sepparated by comma).")]
public string? Channels { get; set; }
[Value(3, Required = true, HelpText = "Number of samples to capture before the trigger.")]
public int PreSamples { get; set; }
[Value(4, Required = true, HelpText = "Number of samples to capture after the trigger.")]
public int PostSamples { get; set; }
[Value(5, Required = true, HelpText = "Trigger definition in the form of \"TriggerType:(Edge, Fast or Complex),Channel:(base trigger channel),Value:(string containing 1's and 0's indicating each trigger chanel state)\".")]
public CLTrigger? Trigger { get; set; }
[Value(6, Required = true, HelpText = "Name of the output file.")]
public string? OutputFile { get; set; }
}
public class CLTrigger
{
public CLTrigger(string Data)
{
string[] parts = Data.Split(",", StringSplitOptions.RemoveEmptyEntries);
if (parts == null || parts.Length != 3)
throw new ArgumentException("Invalid trigger parameters.");
foreach (var part in parts)
{
string[] components = part.Split(":", StringSplitOptions.RemoveEmptyEntries);
if(components == null || components.Length != 2)
throw new ArgumentException("Invalid trigger parameters.");
switch (components[0].ToLower())
{
case "triggertype":
CLTriggerType type;
var typeParsed = Enum.TryParse<CLTriggerType>(components[1], true, out type);
if (!typeParsed)
throw new ArgumentException($"Unknown trigger type: {type}.");
TriggerType = type;
break;
case "channel":
int channel;
if(!int.TryParse(components[1], out channel))
throw new ArgumentException($"Invalid value for trigger channel.");
Channel = channel;
break;
case "value":
if(components[1].Any(v => v != '0' && v != '1'))
throw new ArgumentException($"Trigger values can only be composed of '0's or '1's.");
Value = components[1];
break;
default:
throw new ArgumentException($"Unknown trigger parameter: {components[0]}");
}
}
}
public CLTriggerType TriggerType { get; set; }
public int Channel { get; set; }
public string Value { get; set; }
}
public enum CLTriggerType
{
Edge,
Fast,
Complex
}
}

View File

@ -0,0 +1,199 @@
using CLCapture;
using CommandLine;
using SharedDriver;
using System.IO.Ports;
using System.Linq;
using System.Text;
TaskCompletionSource<CaptureEventArgs> captureCompletedTask;
return await Parser.Default.ParseArguments<CLCaptureCommandLineOptions>(args)
.MapResult(async (CLCaptureCommandLineOptions opts) =>
{
if (string.IsNullOrWhiteSpace(opts.OutputFile))
{
Console.WriteLine("Missing serial port.");
return -1;
}
if (opts.SerialPort == null)
{
Console.WriteLine("Missing serial port.");
return -1;
}
var ports = SerialPort.GetPortNames();
if (!ports.Any(p => p.ToLower() == opts.SerialPort.ToLower()))
{
Console.WriteLine("Cannot find specified serial port.");
return -1;
}
if (opts.SamplingFrequency > 100000000 || opts.SamplingFrequency < 3100)
{
Console.WriteLine("Requested sampling frequency out of range (3100-100000000).");
return -1;
}
int[]? channels = opts.Channels?.Split(",", StringSplitOptions.RemoveEmptyEntries).Select(c => int.Parse(c)).ToArray();
if (channels == null || channels.Any(c => c < 1 || c > 24))
{
Console.WriteLine("Specified capture channels out of range.");
return -1;
}
if (opts.PreSamples + opts.PostSamples > 32767)
{
Console.WriteLine("Total samples exceed the supported maximum (32767).");
return -1;
}
if (opts.Trigger == null)
{
Console.WriteLine("Invalid trigger definition.");
return -1;
}
if (opts.Trigger.Value == null)
{
Console.WriteLine("Invalid trigger value.");
return -1;
}
switch (opts.Trigger.TriggerType)
{
case CLTriggerType.Edge:
if (opts.Trigger.Channel < 1 || opts.Trigger.Channel > 24)
{
Console.WriteLine("Trigger channel out of range.");
return -1;
}
break;
case CLTriggerType.Fast:
if (opts.Trigger.Value.Length > 5)
{
Console.WriteLine("Fast trigger only supports up to 5 channels.");
return -1;
}
if (opts.Trigger.Value.Length + opts.Trigger.Channel > 17)
{
Console.WriteLine("Fast trigger can only be used with the first 16 channels.");
return -1;
}
break;
case CLTriggerType.Complex:
if (opts.Trigger.Value.Length > 16)
{
Console.WriteLine("Complex trigger only supports up to 16 channels.");
return -1;
}
if (opts.Trigger.Value.Length + opts.Trigger.Channel > 17)
{
Console.WriteLine("Complex trigger can only be used with the first 16 channels.");
return -1;
}
break;
}
LogicAnalyzerDriver driver;
Console.WriteLine($"Opening logic analyzer in port {opts.SerialPort}...");
try
{
driver = new LogicAnalyzerDriver(opts.SerialPort, 115200);
}
catch
{
Console.WriteLine($"Error detecting Logic Analyzer in port {opts.SerialPort}");
return -1;
}
Console.WriteLine($"Conneced to device {driver.DeviceVersion} in port {opts.SerialPort}");
captureCompletedTask = new TaskCompletionSource<CaptureEventArgs>();
channels = opts.Channels.Split(",", StringSplitOptions.RemoveEmptyEntries).Select(c => int.Parse(c) - 1).ToArray();
if (opts.Trigger.TriggerType == CLTriggerType.Edge)
{
Console.WriteLine("Starting edge triggered capture...");
driver.StartCapture(opts.SamplingFrequency, opts.PreSamples, opts.PostSamples,
channels, opts.Trigger.Channel - 1, opts.Trigger.Value == "0", CaptureFinished);
Console.WriteLine("Capture running...");
}
else
{
if (opts.Trigger.TriggerType == CLTriggerType.Fast)
Console.WriteLine("Starting fast pattern triggered capture");
else
Console.WriteLine("Starting complex pattern triggered capture");
int bitCount = opts.Trigger.Value.Length;
ushort triggerPattern = 0;
for (int buc = 0; buc < opts.Trigger.Value.Length; buc++)
{
if (opts.Trigger.Value[buc] == '1')
triggerPattern |= (UInt16)(1 << buc);
}
driver.StartPatternCapture(opts.SamplingFrequency, opts.PreSamples, opts.PostSamples,
channels, opts.Trigger.Channel - 1, bitCount, triggerPattern, opts.Trigger.TriggerType == CLTriggerType.Fast, CaptureFinished);
Console.WriteLine("Capture running...");
}
var result = await captureCompletedTask.Task;
Console.WriteLine("Capture complete, writting output file...");
var file = File.Create(opts.OutputFile);
StreamWriter sw = new StreamWriter(file);
sw.WriteLine(String.Join(',', channels.Select(c => $"Channel {c+1}").ToArray()));
StringBuilder sb = new StringBuilder();
for (int sample = 0; sample < result.Samples.Length; sample++)
{
sb.Clear();
for (int buc = 0; buc < opts.Channels.Length; buc++)
{
if((result.Samples[sample] & (1 << buc)) == 0)
sb.Append("0,");
else
sb.Append("1,");
}
sw.WriteLine(sb.ToString());
}
sw.Close();
sw.Dispose();
file.Close();
file.Dispose();
Console.WriteLine("Done.");
return 1;
},
errs => Task.FromResult(-1));
void CaptureFinished(CaptureEventArgs e)
{
captureCompletedTask.SetResult(e);
}

View File

@ -0,0 +1,8 @@
{
"profiles": {
"CLCapture": {
"commandName": "Project",
"commandLineArgs": "COM12 10000 1,2,3,4 512 1024 TriggerType:Edge,Channel:1,Value:1 Capture.csv"
}
}
}

View File

@ -7,6 +7,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LogicAnalyzer", "LogicAnaly
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SPIProtocolAnalyzer", "SPIProtocolAnalyzer\SPIProtocolAnalyzer.csproj", "{C2166CC8-3BD1-4563-BB9F-0001632B449A}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SPIProtocolAnalyzer", "SPIProtocolAnalyzer\SPIProtocolAnalyzer.csproj", "{C2166CC8-3BD1-4563-BB9F-0001632B449A}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LogicAnalyzerMultiplatform", "LogicAnalyzerMultiplatform\LogicAnalyzerMultiplatform.csproj", "{713605B4-A2B7-4254-91C3-FC2A4F5653D8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedDriver", "SharedDriver\SharedDriver.csproj", "{544DB7FA-C828-48A1-922D-F63E2BD479F9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CLCapture", "CLCapture\CLCapture.csproj", "{AA68B9F9-ABFC-443C-9304-E06F264840F6}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -21,6 +27,18 @@ Global
{C2166CC8-3BD1-4563-BB9F-0001632B449A}.Debug|Any CPU.Build.0 = Debug|Any CPU {C2166CC8-3BD1-4563-BB9F-0001632B449A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C2166CC8-3BD1-4563-BB9F-0001632B449A}.Release|Any CPU.ActiveCfg = Release|Any CPU {C2166CC8-3BD1-4563-BB9F-0001632B449A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C2166CC8-3BD1-4563-BB9F-0001632B449A}.Release|Any CPU.Build.0 = Release|Any CPU {C2166CC8-3BD1-4563-BB9F-0001632B449A}.Release|Any CPU.Build.0 = Release|Any CPU
{713605B4-A2B7-4254-91C3-FC2A4F5653D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{713605B4-A2B7-4254-91C3-FC2A4F5653D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{713605B4-A2B7-4254-91C3-FC2A4F5653D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{713605B4-A2B7-4254-91C3-FC2A4F5653D8}.Release|Any CPU.Build.0 = Release|Any CPU
{544DB7FA-C828-48A1-922D-F63E2BD479F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{544DB7FA-C828-48A1-922D-F63E2BD479F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{544DB7FA-C828-48A1-922D-F63E2BD479F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{544DB7FA-C828-48A1-922D-F63E2BD479F9}.Release|Any CPU.Build.0 = Release|Any CPU
{AA68B9F9-ABFC-443C-9304-E06F264840F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA68B9F9-ABFC-443C-9304-E06F264840F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA68B9F9-ABFC-443C-9304-E06F264840F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA68B9F9-ABFC-443C-9304-E06F264840F6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -1,4 +1,5 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using SharedDriver;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View File

@ -1,4 +1,5 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using SharedDriver;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
@ -194,7 +195,7 @@ namespace LogicAnalyzer
if (trigger == -1) if (trigger == -1)
{ {
MessageBox.Show("Yo must select a trigger channel. How the heck did you managed to deselect all? ¬¬"); MessageBox.Show("You must select a trigger channel. How the heck did you managed to deselect all? ¬¬");
return; return;
} }

View File

@ -15,6 +15,10 @@
<PackageReference Include="System.IO.Ports" Version="6.0.0" /> <PackageReference Include="System.IO.Ports" Version="6.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SharedDriver\SharedDriver.csproj" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Update="Properties\Resources.Designer.cs"> <Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>

View File

@ -1,5 +1,6 @@
using LogicAnalyzer.Protocols; using LogicAnalyzer.Protocols;
using Newtonsoft.Json; using Newtonsoft.Json;
using SharedDriver;
using System.IO.Ports; using System.IO.Ports;
namespace LogicAnalyzer namespace LogicAnalyzer

View File

@ -4,6 +4,6 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
--> -->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<History>True|2022-07-08T14:55:29.2331928Z;True|2022-07-03T16:20:52.1046389+02:00;</History> <History>False|2022-07-13T14:45:35.3720563Z;True|2022-07-13T16:45:17.3874110+02:00;True|2022-07-08T18:00:09.3470232+02:00;True|2022-07-08T16:55:29.2331928+02:00;True|2022-07-03T16:20:52.1046389+02:00;</History>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@ -0,0 +1,454 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# Tye
.tye/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
##
## Visual studio for Mac
##
# globs
Makefile.in
*.userprefs
*.usertasks
config.make
config.status
aclocal.m4
install-sh
autom4te.cache/
*.tar.gz
tarballs/
test-results/
# Mac bundle stuff
*.dmg
*.app
# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# JetBrains Rider
.idea/
*.sln.iml
##
## Visual Studio Code
##
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

View File

@ -0,0 +1,7 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="LogicAnalyzerMultiplatform.App">
<Application.Styles>
<FluentTheme Mode="Dark"/>
</Application.Styles>
</Application>

View File

@ -0,0 +1,24 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
namespace LogicAnalyzerMultiplatform
{
public partial class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow();
}
base.OnFrameworkInitializationCompleted();
}
}
}

View File

@ -0,0 +1,53 @@
using Avalonia.Media;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LogicAnalyzerMultiplatform.Classes
{
public static class AnalyzerColors
{
public static Color[] BgChannelColors => new Color[]
{
Color.FromRgb(32,32,32),
Color.FromRgb(64,64, 64),
};
public static Color[] FgChannelColors => new Color[]
{
Color.FromRgb(254, 0, 0),
Color.FromRgb(128, 255, 0),
Color.FromRgb(1, 255, 255),
Color.FromRgb(127, 0, 255),
Color.FromRgb(255, 64, 1),
Color.FromRgb(64, 255, 1),
Color.FromRgb(0, 192, 255),
Color.FromRgb(191, 0, 254),
Color.FromRgb(255, 127, 0),
Color.FromRgb(0, 255, 1),
Color.FromRgb(0, 128, 255),
Color.FromRgb(255, 0, 254),
Color.FromRgb(255, 192, 0),
Color.FromRgb(0, 255, 65),
Color.FromRgb(0, 65, 255),
Color.FromRgb(255, 0, 192),
Color.FromRgb(255, 255, 1),
Color.FromRgb(0, 254, 129),
Color.FromRgb(0, 0, 254),
Color.FromRgb(255, 0, 128),
Color.FromRgb(192, 255, 0),
Color.FromRgb(1, 255, 193),
Color.FromRgb(63, 0, 255),
Color.FromRgb(255, 1, 65),
};
public static Color TxtColor => Colors.White;
}
}

View File

@ -0,0 +1,9 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="140" d:DesignHeight="450"
x:Class="LogicAnalyzerMultiplatform.Controls.ChannelViewer">
<Grid Name="ChannelGrid"></Grid>
</UserControl>

View File

@ -0,0 +1,107 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using LogicAnalyzerMultiplatform.Classes;
using System;
using System.Collections.Generic;
namespace LogicAnalyzerMultiplatform.Controls
{
public partial class ChannelViewer : UserControl
{
TextBox[] boxes;
int[] channels;
public int[] Channels
{
get { return channels; }
set
{
channels = value;
CreateControls();
}
}
private void CreateControls()
{
ChannelGrid.Children.Clear();
if (channels == null || channels.Length == 0)
return;
ChannelGrid.RowDefinitions.Clear();
List<TextBox> newBoxes = new List<TextBox>();
ChannelGrid.BeginBatchUpdate();
for (int buc = 0; buc < channels.Length; buc++)
{
//Create new row
ChannelGrid.RowDefinitions.Add(new RowDefinition(GridLength.Star));
//Create channel grid
var newChannelGrid = new Grid();
newChannelGrid.SetValue(Grid.RowProperty, buc);
newChannelGrid.VerticalAlignment = Avalonia.Layout.VerticalAlignment.Stretch;
newChannelGrid.HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Stretch;
newChannelGrid.RowDefinitions = new RowDefinitions("*,*");
newChannelGrid.Background = new SolidColorBrush(AnalyzerColors.BgChannelColors[buc % 2], 0.8f);
ChannelGrid.Children.Add(newChannelGrid);
//Create label
var newChannelLabel = new TextBlock();
newChannelLabel.SetValue(Grid.RowProperty, 0);
newChannelLabel.VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center;
newChannelLabel.HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center;
newChannelLabel.Text = $"Channel {channels[buc] + 1}";
newChannelLabel.Foreground = new SolidColorBrush(AnalyzerColors.FgChannelColors[buc]);
newChannelGrid.Children.Add(newChannelLabel);
//Create textbox
var newChannelTextbox = new TextBox();
newBoxes.Add(newChannelTextbox);
newChannelTextbox.SetValue(Grid.RowProperty, 1);
newChannelTextbox.VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center;
newChannelTextbox.HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Stretch;
newChannelTextbox.Margin = new Thickness(5, 0, 5, 0);
newChannelTextbox.Background = new SolidColorBrush(AnalyzerColors.BgChannelColors[1 - (buc % 2)], 0.8f);
newChannelTextbox.Foreground = new SolidColorBrush(AnalyzerColors.TxtColor, 1);
newChannelTextbox.MinHeight = newChannelTextbox.MaxHeight = newChannelTextbox.Height = 18;
newChannelTextbox.Padding = new Thickness(2);
newChannelTextbox.BorderThickness = new Thickness(0);
newChannelTextbox.FontSize = 10;
newChannelTextbox.TextAlignment = TextAlignment.Center;
newChannelGrid.Children.Add(newChannelTextbox);
}
boxes = newBoxes.ToArray();
ChannelGrid.EndBatchUpdate();
}
public ChannelViewer()
{
InitializeComponent();
Channels = new int[] { 1, 3, 5 };
}
}
}

View File

@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<!--Avalonia doesen't support TrimMode=link currently,but we are working on that https://github.com/AvaloniaUI/Avalonia/issues/6892 -->
<TrimMode>copyused</TrimMode>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
</PropertyGroup>
<ItemGroup>
<None Remove=".gitignore" />
</ItemGroup>
<ItemGroup>
<!--This helps with theme dll-s trimming.
If you will publish your application in self-contained mode with p:PublishTrimmed=true and it will use Fluent theme Default theme will be trimmed from the output and vice versa.
https://github.com/AvaloniaUI/Avalonia/issues/5593 -->
<TrimmableAssembly Include="Avalonia.Themes.Fluent" />
<TrimmableAssembly Include="Avalonia.Themes.Default" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.10.14" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.14" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="0.10.14" />
<PackageReference Include="XamlNameReferenceGenerator" Version="1.3.4" />
</ItemGroup>
<ItemGroup>
<Folder Include="Styles\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,135 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:LogicAnalyzerMultiplatform.Controls"
mc:Ignorable="d" d:DesignWidth="1024" d:DesignHeight="800"
x:Class="LogicAnalyzerMultiplatform.MainWindow"
Title="LogicAnalyzer - Multiplatform version"
TransparencyLevelHint="AcrylicBlur"
Background="Transparent" MinWidth="1024" MinHeight="800" Width="1024" Height="800">
<DockPanel VerticalAlignment="Stretch">
<ExperimentalAcrylicBorder IsHitTestVisible="False">
<ExperimentalAcrylicBorder.Material>
<ExperimentalAcrylicMaterial
BackgroundSource="Digger"
TintColor="Black"
TintOpacity="1"
MaterialOpacity="0.65" />
</ExperimentalAcrylicBorder.Material>
</ExperimentalAcrylicBorder>
<Menu DockPanel.Dock="Top" Background="#f0202020">
<MenuItem Header="_File">
<MenuItem Header="_Open..." Name="mnuOpen"/>
<MenuItem Header="_Save..." Name="mnuSave"/>
<MenuItem Header="E_xport..." Name="mnuExport"/>
<Separator/>
<MenuItem Header="_Exit" Name="mnuExit"/>
</MenuItem>
<MenuItem Header="_Protocol analyzers" Name="mnuProtocols">
<MenuItem Header="None"/>
</MenuItem>
</Menu>
<Grid DockPanel.Dock="Top" Height="48" ColumnDefinitions="*,*" Background="#80303030">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Stretch" Grid.Column="0" Margin="10,0,0,0">
<Button Name="btnRefresh">Refresh</Button>
<ComboBox VerticalAlignment="Center" Margin="10,0,10,0" Name="cbSerialPorts">
</ComboBox>
<Button Name="btnOpen">Open device</Button>
<TextBlock VerticalAlignment="Center" Margin="10,0,10,0">Open device:</TextBlock>
<TextBlock VerticalAlignment="Center" Name="lblDevice">&lt; None &gt;</TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Stretch" Grid.Column="1" Margin="0,0,10,0">
<Button Name="btnRepeate">Repeat last capture</Button>
<Button Name="btnCapture">Capture</Button>
</StackPanel>
</Grid>
<ScrollBar VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Orientation="Horizontal" DockPanel.Dock="Bottom" Name="scbPosition"></ScrollBar>
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch" ColumnDefinitions="140,10*,240" DockPanel.Dock="Bottom">
<controls:ChannelViewer Name="chViewer" Grid.Row="0" Grid.Column="0" />
<TextBlock Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center">
CONTENT
</TextBlock>
<DockPanel Grid.Column="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="#80303030">
<Grid DockPanel.Dock="Top" RowDefinitions="*,*,2*,*,2*" ColumnDefinitions="*,6*,*" HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="5,0,5,5" Background="#80404040">
<TextBlock Grid.ColumnSpan="2" Margin="10">
Adjustments
</TextBlock>
<TextBlock Grid.Row="1" Margin="10">
10
</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="1" Margin="10" HorizontalAlignment="Center">
Samples in screen
</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="2" Margin="10">
200
</TextBlock>
<Slider Grid.Row="2" Grid.ColumnSpan="3" Margin="10,0,10,0" TickFrequency="10" TickPlacement="BottomRight" Minimum="10" Maximum="200" Value="100" Name="sldSamples"></Slider>
</Grid>
<StackPanel DockPanel.Dock="Bottom" VerticalAlignment="Bottom" Margin="5,0,5,5" Background="#80404040" >
<TextBlock Margin="5">
Information
</TextBlock>
<Panel>
<TextBlock Margin="2" HorizontalAlignment="Left">
- Frequency:
</TextBlock>
<TextBlock Margin="2" HorizontalAlignment="Right" Name="lblFreq">
100000000
</TextBlock>
</Panel>
<Panel>
<TextBlock Margin="2" HorizontalAlignment="Left">
- Total samples:
</TextBlock>
<TextBlock Margin="2" HorizontalAlignment="Right" Name="lblSamples">
1536
</TextBlock>
</Panel>
<Panel>
<TextBlock Margin="2" HorizontalAlignment="Left">
- Pre samples:
</TextBlock>
<TextBlock Margin="2" HorizontalAlignment="Right" Name="lblPreSamples">
512
</TextBlock>
</Panel>
<Panel>
<TextBlock Margin="2" HorizontalAlignment="Left">
- Post samples:
</TextBlock>
<TextBlock Margin="2" HorizontalAlignment="Right" Name="lblPostSamples">
1024
</TextBlock>
</Panel>
<Panel>
<TextBlock Margin="2" HorizontalAlignment="Left">
- Channels:
</TextBlock>
<TextBlock Margin="2" HorizontalAlignment="Right" Name="lblChannels">
4
</TextBlock>
</Panel>
<Panel>
<TextBlock Margin="2" HorizontalAlignment="Left">
- Trigger:
</TextBlock>
<TextBlock Margin="2" HorizontalAlignment="Right" Name="lblTrigger">
Simple, Channel 1
</TextBlock>
</Panel>
<Panel>
<TextBlock Margin="2" HorizontalAlignment="Left">
- Value:
</TextBlock>
<TextBlock Margin="2" HorizontalAlignment="Right" Name="lblValue">
"10010"
</TextBlock>
</Panel>
</StackPanel>
</DockPanel>
</Grid>
</DockPanel>
</Window>

View File

@ -0,0 +1,12 @@
using Avalonia.Controls;
namespace LogicAnalyzerMultiplatform
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,23 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using System;
namespace LogicAnalyzerMultiplatform
{
internal class Program
{
// Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.LogToTrace();
}
}

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace LogicAnalyzer namespace SharedDriver
{ {
public class CaptureSettings public class CaptureSettings
{ {

View File

@ -1,12 +1,8 @@
using System; using System.IO.Ports;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace LogicAnalyzer namespace SharedDriver
{ {
public class LogicAnalyzerDriver : IDisposable public class LogicAnalyzerDriver : IDisposable
{ {
@ -16,12 +12,13 @@ namespace LogicAnalyzer
SerialPort sp; SerialPort sp;
public string? DeviceVersion { get; set; } public string? DeviceVersion { get; set; }
public event EventHandler<CaptureEventArgs> CaptureCompleted; public event EventHandler<CaptureEventArgs>? CaptureCompleted;
bool capturing = false; bool capturing = false;
private int channelCount; private int channelCount;
private int triggerChannel; private int triggerChannel;
private int preSamples; private int preSamples;
private Action<CaptureEventArgs>? currentCaptureHandler;
public LogicAnalyzerDriver(string SerialPort, int Bauds) public LogicAnalyzerDriver(string SerialPort, int Bauds)
{ {
@ -46,36 +43,19 @@ namespace LogicAnalyzer
baseStream.ReadTimeout = Timeout.Infinite; baseStream.ReadTimeout = Timeout.Infinite;
} }
public bool StartCapture(int Frequency, int PreSamples, int PostSamples, int[] Channels, int TriggerChannel, bool TriggerInverted) public bool StartCapture(int Frequency, int PreSamples, int PostSamples, int[] Channels, int TriggerChannel, bool TriggerInverted, Action<CaptureEventArgs>? CaptureCompletedHandler = null)
{ {
if (capturing) if (capturing)
return false; return false;
if (Channels == null || Channels.Length == 0 || PreSamples < 2 || PreSamples > (16 * 1024) || (PreSamples + PostSamples) >= (32 * 1024) || Frequency > 100000000) if (Channels == null || Channels.Length == 0 || PreSamples < 2 || PreSamples > (16 * 1024) || (PreSamples + PostSamples) >= (32 * 1024) || Frequency > 100000000)
return false; return false;
/*
bool oneFound = false;
for (int bitCount = 0; bitCount < 32; bitCount++)
{
if (((PreSamples * 4) & (1 << bitCount)) != 0)
{
if (oneFound)
return false;
oneFound = true;
}
}
if (!oneFound)
return false;
*/
channelCount = Channels.Length; channelCount = Channels.Length;
triggerChannel = Array.IndexOf(Channels, TriggerChannel); triggerChannel = Array.IndexOf(Channels, TriggerChannel);
preSamples = PreSamples; preSamples = PreSamples;
currentCaptureHandler = CaptureCompletedHandler;
CaptureRequest request = new CaptureRequest CaptureRequest request = new CaptureRequest
{ {
@ -89,7 +69,7 @@ namespace LogicAnalyzer
postSamples = (uint)PostSamples postSamples = (uint)PostSamples
}; };
for(int buc = 0; buc < Channels.Length; buc++) for (int buc = 0; buc < Channels.Length; buc++)
request.channels[buc] = (byte)Channels[buc]; request.channels[buc] = (byte)Channels[buc];
OutputPacket pack = new OutputPacket(); OutputPacket pack = new OutputPacket();
@ -111,7 +91,7 @@ namespace LogicAnalyzer
} }
return false; return false;
} }
public bool StartPatternCapture(int Frequency, int PreSamples, int PostSamples, int[] Channels, int TriggerChannel, int TriggerBitCount, UInt16 TriggerPattern, bool Fast) public bool StartPatternCapture(int Frequency, int PreSamples, int PostSamples, int[] Channels, int TriggerChannel, int TriggerBitCount, UInt16 TriggerPattern, bool Fast, Action<CaptureEventArgs>? CaptureCompletedHandler = null)
{ {
if (capturing) if (capturing)
@ -120,27 +100,10 @@ namespace LogicAnalyzer
if (Channels == null || Channels.Length == 0 || PreSamples < 2 || PreSamples > (16 * 1024) || (PreSamples + PostSamples) >= (32 * 1024) || Frequency > 100000000) if (Channels == null || Channels.Length == 0 || PreSamples < 2 || PreSamples > (16 * 1024) || (PreSamples + PostSamples) >= (32 * 1024) || Frequency > 100000000)
return false; return false;
/*
bool oneFound = false;
for (int bitCount = 0; bitCount < 32; bitCount++)
{
if (((PreSamples * 4) & (1 << bitCount)) != 0)
{
if (oneFound)
return false;
oneFound = true;
}
}
if (!oneFound)
return false;
*/
channelCount = Channels.Length; channelCount = Channels.Length;
triggerChannel = Array.IndexOf(Channels, TriggerChannel); triggerChannel = Array.IndexOf(Channels, TriggerChannel);
preSamples = PreSamples; preSamples = PreSamples;
currentCaptureHandler = CaptureCompletedHandler;
CaptureRequest request = new CaptureRequest CaptureRequest request = new CaptureRequest
{ {
@ -177,7 +140,6 @@ namespace LogicAnalyzer
} }
return false; return false;
} }
public void Dispose() public void Dispose()
{ {
try try
@ -187,20 +149,20 @@ namespace LogicAnalyzer
} }
catch { } catch { }
try try
{ {
baseStream.Close(); baseStream.Close();
baseStream.Dispose(); baseStream.Dispose();
} }
catch { } catch { }
try try
{ {
readData.Close(); readData.Close();
readData.Dispose(); readData.Dispose();
} }
catch { } catch { }
try try
{ {
readResponse.Close(); readResponse.Close();
@ -216,22 +178,22 @@ namespace LogicAnalyzer
DeviceVersion = null; DeviceVersion = null;
CaptureCompleted = null; CaptureCompleted = null;
} }
void ReadCapture() void ReadCapture()
{ {
uint length = readData.ReadUInt32(); uint length = readData.ReadUInt32();
uint[] samples = new uint[length]; uint[] samples = new uint[length];
for(int buc = 0; buc < length; buc++) for (int buc = 0; buc < length; buc++)
samples[buc] = readData.ReadUInt32(); samples[buc] = readData.ReadUInt32();
if (CaptureCompleted != null) if (currentCaptureHandler != null)
currentCaptureHandler(new CaptureEventArgs { Samples = samples, ChannelCount = channelCount, TriggerChannel = triggerChannel, PreSamples = preSamples });
else if (CaptureCompleted != null)
CaptureCompleted(this, new CaptureEventArgs { Samples = samples, ChannelCount = channelCount, TriggerChannel = triggerChannel, PreSamples = preSamples }); CaptureCompleted(this, new CaptureEventArgs { Samples = samples, ChannelCount = channelCount, TriggerChannel = triggerChannel, PreSamples = preSamples });
capturing = false; capturing = false;
} }
class OutputPacket class OutputPacket
{ {
List<byte> dataBuffer = new List<byte>(); List<byte> dataBuffer = new List<byte>();
@ -273,7 +235,7 @@ namespace LogicAnalyzer
finalData.Add(0x55); finalData.Add(0x55);
finalData.Add(0xAA); finalData.Add(0xAA);
for(int buc = 0; buc < dataBuffer.Count; buc++) for (int buc = 0; buc < dataBuffer.Count; buc++)
{ {
if (dataBuffer[buc] == 0xAA || dataBuffer[buc] == 0x55 || dataBuffer[buc] == 0xF0) if (dataBuffer[buc] == 0xAA || dataBuffer[buc] == 0x55 || dataBuffer[buc] == 0xF0)
{ {
@ -283,13 +245,13 @@ namespace LogicAnalyzer
else else
finalData.Add(dataBuffer[buc]); finalData.Add(dataBuffer[buc]);
} }
finalData.Add(0xAA); finalData.Add(0xAA);
finalData.Add(0x55); finalData.Add(0x55);
return finalData.ToArray(); return finalData.ToArray();
} }
} }
@ -317,4 +279,4 @@ namespace LogicAnalyzer
public int PreSamples { get; set; } public int PreSamples { get; set; }
public uint[] Samples { get; set; } public uint[] Samples { get; set; }
} }
} }

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.IO.Ports" Version="6.0.0" />
</ItemGroup>
</Project>