Skip to content

Commit 7b55957

Browse files
authored
Merge pull request #4 from harp-tech/register-tables
Support for automatic generation of device metadata and register tables
2 parents 3e23379 + 2d500c8 commit 7b55957

9 files changed

Lines changed: 187 additions & 7 deletions

File tree

.config/dotnet-tools.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"version": 1,
3+
"isRoot": true,
4+
"tools": {
5+
"docfx": {
6+
"version": "2.73.1",
7+
"commands": [
8+
"docfx"
9+
]
10+
}
11+
}
12+
}

.github/workflows/build.yml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,25 @@ jobs:
1515
with:
1616
submodules: recursive
1717

18+
- name: Setup .NET Core SDK
19+
uses: actions/setup-dotnet@v3.2.0
20+
with:
21+
dotnet-version: 7.x
22+
23+
- name: Custom Build Steps
24+
run: .\build.ps1
25+
1826
- name: Setup MSBuild
1927
uses: microsoft/setup-msbuild@v1
2028

2129
- name: Restore NuGet Packages
2230
run: msbuild -t:restore src\harp\Bonsai.Harp.sln
2331

2432
- name: Setup DocFX
25-
uses: crazy-max/ghaction-chocolatey@v1
26-
with:
27-
args: install docfx
33+
run: dotnet tool restore
2834

2935
- name: Build Documentation
30-
run: docfx docfx.json
36+
run: dotnet docfx docfx.json
3137

3238
- name: Checkout gh-pages
3339
uses: actions/checkout@v2

apispec/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
###############
2+
# Auto file #
3+
###############
4+
*.md

build.ps1

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
$files = Get-ChildItem .\src\device.*\device.yml
2+
foreach ($file in $files)
3+
{
4+
Write-Output "Generating schema tables for $file..."
5+
dotnet run --project .\src\harp.schemaprocessor $file .\apispec
6+
}

docfx.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@
4444
"files": [
4545
"logo.svg",
4646
"favicon.ico",
47-
"editor/index.html",
47+
"src/device.*/Assets/*.png",
48+
"src/device.*/Assets/*.jpg",
4849
"images/**",
4950
"workflows/**"
5051
]
@@ -53,7 +54,8 @@
5354
"overwrite": [
5455
{
5556
"files": [
56-
"apidoc/**.md"
57+
"apidoc/**.md",
58+
"apispec/**.md"
5759
],
5860
"exclude": [
5961
"obj/**",
@@ -88,7 +90,7 @@
8890
"keepFileLink": false,
8991
"cleanupCacheHistory": false,
9092
"disableGitFeatures": false,
91-
"xrefService": [ "https://xref.docs.microsoft.com/query?uid={uid}" ],
93+
"xrefService": [ "https://learn.microsoft.com/api/xref/query?uid={uid}" ],
9294
"xref": [
9395
"https://bonsai-rx.org/docs/xrefmap.yml",
9496
"https://horizongir.github.io/opencv.net/xrefmap.yml",
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System.Dynamic;
2+
3+
static class ExpandoHelper
4+
{
5+
public static ExpandoObject FromDictionary(Dictionary<object, object> members, params string[] optionalMembers)
6+
{
7+
var result = new ExpandoObject();
8+
foreach (var kvp in members)
9+
{
10+
result.TryAdd((string)kvp.Key, kvp.Value);
11+
}
12+
13+
foreach (var member in optionalMembers)
14+
{
15+
result.TryAdd(member, null);
16+
}
17+
return result;
18+
}
19+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
using System.Dynamic;
2+
using System.Text;
3+
using YamlDotNet.Core;
4+
using YamlDotNet.Serialization;
5+
6+
var fileName = args[0];
7+
var yaml = File.ReadAllText(fileName);
8+
var deserializer = new Deserializer();
9+
var parser = new MergingParser(new Parser(new StringReader(yaml)));
10+
dynamic deviceModel = deserializer.Deserialize<ExpandoObject>(parser);
11+
12+
var builder = new StringBuilder();
13+
builder.AppendLine($@"---
14+
uid: Harp.{deviceModel.device}.Device
15+
---
16+
17+
<table>
18+
<thead>
19+
<tr><th colspan=""2"">{deviceModel.device}</th></tr>
20+
</thead>
21+
<tbody>
22+
<tr><td>whoAmI</td><td>{deviceModel.whoAmI}</td></tr>
23+
<tr><td>firmwareVersion</td><td>{deviceModel.firmwareVersion}</td></tr>
24+
<tr><td>hardwareTargets</td><td>{deviceModel.hardwareTargets}</td></tr>
25+
</tbody>
26+
</table>
27+
28+
### Registers
29+
30+
| name | address | type | length | access | description | range | interfaceType |
31+
|-|-|-|-|-|-|-|-|");
32+
foreach (var item in deviceModel.registers)
33+
{
34+
if (item.Value.TryGetValue("visibility", out object visibility) &&
35+
(string)visibility == "private")
36+
{
37+
continue;
38+
}
39+
40+
var name = item.Key;
41+
var register = ExpandoHelper.FromDictionary(item.Value,
42+
"length",
43+
"description",
44+
"minValue",
45+
"maxValue",
46+
"defaultValue",
47+
"payloadSpec",
48+
"maskType",
49+
"interfaceType");
50+
var interfaceType = register.maskType
51+
?? register.interfaceType
52+
?? (register.payloadSpec != null ? $"{name}Payload" : null);
53+
var interfaceTypeRef = (string)interfaceType == "EnableFlag"
54+
? "Bonsai.Harp.EnableFlag"
55+
: $"Harp.{deviceModel.device}.{interfaceType}";
56+
57+
var access = register.access;
58+
if (access is List<object> accessList)
59+
{
60+
access = string.Join(", ", accessList);
61+
}
62+
63+
var range = "";
64+
if (register.minValue != null || register.maxValue != null)
65+
{
66+
range = $"[{register.minValue}:{register.maxValue}]";
67+
}
68+
if (register.defaultValue != null) range = $"{register.defaultValue} {range}";
69+
70+
builder.AppendLine(
71+
$"| [{name}](xref:Harp.{deviceModel.device}.{name}) " +
72+
$"| {register.address} " +
73+
$"| {register.type} " +
74+
$"| {register.length} " +
75+
$"| {access} " +
76+
$"| {register.description} " +
77+
$"| {range} " +
78+
(interfaceType != null ? $"| [{interfaceType}](xref:{interfaceTypeRef}) |" : "| |"));
79+
}
80+
81+
var output = builder.ToString();
82+
if (args.Length > 1)
83+
{
84+
File.WriteAllText(Path.Combine(args[1], $"Harp_{deviceModel.device}_Device.md"), output);
85+
File.WriteAllText(Path.Combine(args[1], $"Harp_{deviceModel.device}.md"), $@"---
86+
uid: Harp.{deviceModel.device}
87+
---
88+
89+
[!include[README](~/src/device.{deviceModel.device.ToLowerInvariant()}/README.md)]
90+
91+
[!include[RegisterTables](./Harp_{deviceModel.device}_Device.md)]");
92+
}
93+
else Console.WriteLine(output);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net7.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="YamlDotNet" Version="13.7.1" />
11+
</ItemGroup>
12+
13+
</Project>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.5.002.0
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "harp.schemaprocessor", "harp.schemaprocessor.csproj", "{EAD0FB15-A769-45D5-8FBE-9E1495AE59C6}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{EAD0FB15-A769-45D5-8FBE-9E1495AE59C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{EAD0FB15-A769-45D5-8FBE-9E1495AE59C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{EAD0FB15-A769-45D5-8FBE-9E1495AE59C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{EAD0FB15-A769-45D5-8FBE-9E1495AE59C6}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {1C2B33A3-49ED-4B82-AF1B-E2F3FB9E4ACF}
24+
EndGlobalSection
25+
EndGlobal

0 commit comments

Comments
 (0)