-
Notifications
You must be signed in to change notification settings - Fork 1
Add contributor documentation and clean up stale references #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| # Contributing to HALGEN | ||
|
|
||
| HALGEN generates Swift hardware abstraction layers for AVR microcontrollers. The generator reads bundled ATDF XML files, merges supplemental documentation from `docs/`, and writes formatted Swift source into `Output/`. | ||
|
|
||
| The primary development workflow is the command-line generator. The SwiftUI app target exists, but most contributor work should start with the CLI and focused tests. | ||
|
|
||
| ## First Successful Run | ||
|
|
||
| Requirements: | ||
|
|
||
| - macOS with Xcode installed | ||
| - Xcode command line tools pointed at the full Xcode app | ||
|
|
||
| ```bash | ||
| sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer | ||
| ``` | ||
|
|
||
| Generate the default representative chip: | ||
|
|
||
| ```bash | ||
| ./generate.sh | ||
| ``` | ||
|
|
||
| Generate into a temporary directory when you want to inspect output without touching `Output/`: | ||
|
|
||
| ```bash | ||
| ./generate.sh --output /tmp/halgen-test | ||
| ``` | ||
|
|
||
| Run the focused unit test target: | ||
|
|
||
| ```bash | ||
| xcodebuild test \ | ||
| -project SwiftAVRGenerator.xcodeproj \ | ||
| -scheme SwiftAVRGenerator \ | ||
| -destination "platform=macOS,arch=arm64" \ | ||
| -only-testing:SwiftAVRGeneratorTests/SwiftAVRGeneratorTests | ||
| ``` | ||
|
|
||
| If local signing blocks test runs, retry with signing disabled: | ||
|
|
||
| ```bash | ||
| xcodebuild test \ | ||
| -project SwiftAVRGenerator.xcodeproj \ | ||
| -scheme SwiftAVRGenerator \ | ||
| -destination "platform=macOS,arch=arm64" \ | ||
| -only-testing:SwiftAVRGeneratorTests/SwiftAVRGeneratorTests \ | ||
| CODE_SIGNING_ALLOWED=NO CODE_SIGN_IDENTITY="" DEVELOPMENT_TEAM="" | ||
| ``` | ||
|
|
||
| ## Golden Rule | ||
|
|
||
| Change generator code or documentation inputs. Do not hand-edit files under `Output/` unless you are only inspecting generated output. | ||
|
|
||
| Generated files should improve because one of these changed: | ||
|
|
||
| - Swift generator logic under `SwiftAVRGenerator/` | ||
| - supplemental JSON or templates under `docs/` | ||
| - ATDF input data under `atdf/` | ||
|
|
||
| ## Where To Change Things | ||
|
|
||
| | If you are changing... | Start here | | ||
| | --- | --- | | ||
| | CLI arguments or export behavior | `SwiftAVRGenerator/CLI/main.swift` and `SwiftAVRGenerator/Generators/GenerationApi.swift` | | ||
| | ATDF decoding models | `SwiftAVRGenerator/AVRToolsDeviceFile/` | | ||
| | supplemental JSON loading | `SwiftAVRGenerator/Documentation/` | | ||
| | register or bitfield code generation | `SwiftAVRGenerator/CodeGeneration/` | | ||
| | peripheral output | `SwiftAVRGenerator/Generators/Peripherals/` | | ||
| | generator registration | `SwiftAVRGenerator/Generators/GeneratorRegistry.swift` | | ||
| | generated formatting | `SwiftAVRGenerator/CodeGeneration/Linter/` | | ||
| | supplemental docs data | `docs/general.json`, `docs/<Chip>.json`, and `docs/SUPPLEMENTAL_DOCUMENTATION.md` | | ||
| | boilerplate module code | `docs/boilerplate/` | | ||
| | tests | `SwiftAVRGeneratorTests/` | | ||
|
|
||
| ## Common Workflows | ||
|
|
||
| Read `DeveloperDocs/ARCHITECTURE.md` before making broad generator changes. It explains the data flow from ATDF input to generated Swift output. | ||
|
|
||
| Read `DeveloperDocs/DOCUMENTATION_SYSTEM.md` before editing `docs/general.json`, `docs/<Chip>.json`, or boilerplate templates. That guide explains how supplemental data is merged and why missing entries appear in `logs.json`. | ||
|
|
||
| Read `DeveloperDocs/ADDING_PERIPHERALS.md` before adding a new peripheral generator or changing an existing generator's structure. | ||
|
|
||
| Read `DeveloperDocs/TESTING_AND_GENERATION.md` when you need exact build, test, generation, and inspection commands. | ||
|
|
||
| ## Review Checklist | ||
|
|
||
| Before opening a pull request or asking for review: | ||
|
|
||
| - Run focused tests for the area you changed. | ||
| - Run `./generate.sh --output /tmp/halgen-test` for generator or documentation changes. | ||
| - Inspect `logs.json` for unexpected missing supplemental data. | ||
| - Inspect `formatting-report.txt` for generated formatting diagnostics. | ||
| - Update contributor docs when behavior, commands, or documentation fields change. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,158 @@ | ||
| # Adding Or Changing Peripheral Generators | ||
|
|
||
| Peripheral generators turn decoded ATDF modules into Swift HAL files. Add a new generator when a peripheral family needs generated APIs that cannot be handled by an existing generator. | ||
|
|
||
| ## Before You Start | ||
|
|
||
| Check whether the peripheral already has a generator under `SwiftAVRGenerator/Generators/Peripherals/`. | ||
|
|
||
| Existing generators include: | ||
|
|
||
| - `AnalogToDigitalConverter.swift` | ||
| - `GPIO.swift` | ||
| - `SerialPeripheralInterface.swift` | ||
| - `Timers.swift` | ||
| - `TwoWireInterface.swift` | ||
| - `UART.swift` | ||
|
|
||
| If the change is shared register or bitfield behavior, prefer `SwiftAVRGenerator/CodeGeneration/`. If the change is specific to one peripheral family, keep it in that peripheral generator. | ||
|
|
||
| ## Generator Contract | ||
|
|
||
| New generators conform to `PeripheralGenerator`: | ||
|
|
||
| ```swift | ||
| protocol PeripheralGenerator { | ||
| var name: String { get } | ||
| var logName: String { get } | ||
| var subdirectory: String { get } | ||
| func supports(device: AVRToolsDeviceFile) -> Bool | ||
| func generate(device: AVRToolsDeviceFile, documentation: ChipDocumentationLoader) -> [GeneratedCodeFile] | ||
| } | ||
| ``` | ||
|
|
||
| `logName` defaults to `name`. Override it when the generated Swift-facing name differs from the ATDF or log grouping name. `TwoWireInterfaceGenerator` does this by using `name = "TwoWireInterface"` and `logName = "TWI"`. | ||
|
|
||
| ## Minimal Generator Shape | ||
|
|
||
| Use this shape as a starting point: | ||
|
|
||
| ```swift | ||
| struct ExampleGenerator: PeripheralGenerator { | ||
| let name: String = "Example" | ||
| let subdirectory: String = "module/Example" | ||
|
|
||
| func supports(device: AVRToolsDeviceFile) -> Bool { | ||
| device.modules.module.contains { $0.name == "EXAMPLE" } | ||
| } | ||
|
|
||
| func generate(device: AVRToolsDeviceFile, documentation: ChipDocumentationLoader) -> [GeneratedCodeFile] { | ||
| guard let module = device.modules.module.first(where: { $0.name == "EXAMPLE" }) else { | ||
| return [] | ||
| } | ||
|
|
||
| var files: [GeneratedCodeFile] = [] | ||
|
|
||
| for registerGroup in module.registerGroup { | ||
| let structName = "Example\(peripheralInstanceIndex(for: registerGroup.name))" | ||
| var code = buildFileHeader(for: structName) | ||
|
|
||
| // Build declarations from registers and bitfields here. | ||
|
|
||
| files.append( | ||
| GeneratedCodeFile( | ||
| fileName: "\(structName).swift", | ||
| content: code, | ||
| subdirectory: subdirectory | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| return files | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Keep `supports(device:)` conservative. Return `true` only when the required ATDF module or register shape exists. If only some chips have the classic register layout your generator supports, check for that exact shape instead of only checking the module name. | ||
|
|
||
| ## Documentation Context And Logs | ||
|
|
||
| `GenerationPipeline` wraps every registered generator with: | ||
|
|
||
| ```swift | ||
| documentation.withPeripheralContext(named: generator.logName) { | ||
| generator.generate(device: device, documentation: documentation) | ||
| } | ||
| ``` | ||
|
|
||
| This means missing supplemental documentation discovered during `generate(device:documentation:)` is grouped under that generator's log name in `logs.json`. | ||
|
|
||
| Set `name` and `logName` deliberately. Only call `withPeripheralContext(named:)` inside a generator if the generator intentionally needs multiple log groups. | ||
|
|
||
| ## Registering The Generator | ||
|
|
||
| Add the generator to `SwiftAVRGenerator/Generators/GeneratorRegistry.swift`: | ||
|
|
||
| ```swift | ||
| struct GeneratorRegistry { | ||
| static let allGenerators: [PeripheralGenerator] = [ | ||
| UARTGenerator(), | ||
| SPIGenerator(), | ||
| TwoWireInterfaceGenerator(), | ||
| TimerGenerator(), | ||
| ADCGenerator(), | ||
| GPIOGenerator(), | ||
| ExampleGenerator() | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| Keep ordering intentional. If output order matters for generated package layout or review readability, place the new generator where it makes sense with the existing families. | ||
|
|
||
| ## Boilerplate Templates | ||
|
|
||
| If the peripheral needs hand-maintained Swift protocols, convenience APIs, or setup helpers, add a template under `docs/boilerplate/` and load it with `BoilerplateTemplate.load` or `BoilerplateTemplate.render`. | ||
|
|
||
| Use templates for stable API surfaces. Use Swift generator code for declarations that are derived from ATDF registers or bitfields. | ||
|
|
||
| ## Tests And Verification | ||
|
|
||
| Add focused unit tests under `SwiftAVRGeneratorTests/` for the behavior you changed. Good tests assert generated content for a representative chip or a small constructed model. | ||
|
|
||
| Run focused tests first: | ||
|
|
||
| ```bash | ||
| xcodebuild test \ | ||
| -project SwiftAVRGenerator.xcodeproj \ | ||
| -scheme SwiftAVRGenerator \ | ||
| -destination "platform=macOS,arch=arm64" \ | ||
| -only-testing:SwiftAVRGeneratorTests/SwiftAVRGeneratorTests | ||
| ``` | ||
|
|
||
| Then generate a representative chip into a temporary directory: | ||
|
|
||
| ```bash | ||
| ./generate.sh --output /tmp/halgen-test | ||
| ``` | ||
|
|
||
| Inspect: | ||
|
|
||
| - `/tmp/halgen-test/logs.json` | ||
| - `/tmp/halgen-test/formatting-report.txt` | ||
| - the generated peripheral files under `/tmp/halgen-test/<Chip>/` | ||
|
|
||
| For broad generator changes, run all bundled chips: | ||
|
|
||
| ```bash | ||
| ./generate.sh --all --output /tmp/halgen-test | ||
| ``` | ||
|
|
||
| ## Contributor Checklist | ||
|
|
||
| - The generator supports only chips with the expected ATDF shape. | ||
| - New generated files use the existing `GeneratedCodeFile` export path pattern. | ||
| - Register accessors use shared helpers where possible. | ||
| - Bitfield accessors use shared helpers where possible. | ||
| - Missing supplemental docs appear under a useful peripheral name in `logs.json`. | ||
| - Focused tests cover the new behavior. | ||
| - Generated output formats cleanly. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| # HALGEN Architecture | ||
|
|
||
| HALGEN is a source generator. It reads Microchip ATDF device descriptions, combines them with supplemental documentation maintained in this repository, and emits Swift HAL source files. | ||
|
|
||
| ## Data Flow | ||
|
|
||
| ```text | ||
| atdf/*.atdf | ||
| -> XMLDecoder | ||
| -> AVRToolsDeviceFile | ||
| -> ChipDocumentationLoader | ||
| -> GenerationPipeline | ||
| -> PeripheralGenerator | ||
| -> CodeFormatter | ||
| -> Output/<Chip>/... | ||
| ``` | ||
|
|
||
| The ATDF file is the hardware source of truth. Supplemental JSON improves naming, access metadata, generated documentation, split bitfield handling, and board defaults. Peripheral generators transform the decoded device model plus supplemental data into Swift source files. | ||
|
|
||
| ## Main Areas | ||
|
|
||
| | Area | Responsibility | | ||
| | --- | --- | | ||
| | `SwiftAVRGenerator/CLI/` | Command-line entry point and argument handling. | | ||
| | `SwiftAVRGenerator/App/` | SwiftUI macOS app target. The CLI is the primary contributor workflow. | | ||
| | `SwiftAVRGenerator/AVRToolsDeviceFile/` | Codable models for decoded ATDF XML. | | ||
| | `SwiftAVRGenerator/Documentation/` | Models and loader for `docs/general.json`, chip JSON files, board metadata, and missing-data logs. | | ||
| | `SwiftAVRGenerator/Generators/` | Generation pipeline, generator registry, peripheral generators, and CoreAVR package support. | | ||
| | `SwiftAVRGenerator/CodeGeneration/` | Register, bitfield, documentation-comment, formatting, and SwiftSyntax helpers. | | ||
| | `Scripts/` | Maintenance scripts for ATDF models and supplemental documentation audits. | | ||
| | `docs/` | Supplemental JSON data, boilerplate templates, CoreAVR package template files, and contributor docs. | | ||
| | `Output/` | Generated output. Treat this as an artifact, not as source input. | | ||
|
|
||
| ## Generation Lifecycle | ||
|
|
||
| 1. The CLI or app chooses one chip or all bundled ATDF files. | ||
| 2. The selected ATDF XML is decoded into `AVRToolsDeviceFile`. | ||
| 3. `GenerationPipeline.run(device:documentation:)` loads `docs/general.json` and `docs/<Chip>.json`. | ||
| 4. `GeneratorRegistry.allGenerators` is scanned in order. | ||
| 5. Each generator whose `supports(device:)` returns `true` emits one or more `GeneratedCodeFile` values. | ||
| 6. Documentation lookups go through `ChipDocumentationLoader` while the pipeline sets the current peripheral log context. | ||
| 7. Generated Swift is formatted before export. | ||
| 8. Export writes generated files, `logs.json`, and `formatting-report.txt`. | ||
|
|
||
| ## Core Concepts | ||
|
|
||
| ### `AVRToolsDeviceFile` | ||
|
|
||
| `AVRToolsDeviceFile` is the decoded ATDF model. It should describe hardware structure, not HAL naming policy. | ||
|
|
||
| ### `ChipDocumentationLoader` | ||
|
|
||
| `ChipDocumentationLoader` merges shared docs from `docs/general.json`, chip-specific docs from `docs/<Chip>.json`, and generated fallbacks from ATDF data. It also records missing supplemental entries so the export can write actionable `logs.json` output. | ||
|
|
||
| ### `PeripheralGenerator` | ||
|
|
||
| Each peripheral generator owns one generated peripheral family. A generator decides whether it supports a chip, then emits files under its configured output subdirectory. | ||
|
|
||
| ### `GeneratedCodeFile` | ||
|
|
||
| A generated file contains a file name, file content, and output subdirectory. Generators should return generated files instead of writing to disk directly. | ||
|
|
||
| ### `CodeFormatter` | ||
|
|
||
| Generated Swift is normalized during export. Do not assume generated text is final before formatter diagnostics are written to `formatting-report.txt`. | ||
|
|
||
| ## Generator Boundaries | ||
|
|
||
| Keep hardware discovery close to the relevant peripheral generator. Keep shared register and bitfield formatting in `SwiftAVRGenerator/CodeGeneration/`. Keep supplemental metadata behavior in `SwiftAVRGenerator/Documentation/`. | ||
|
|
||
| If a change affects multiple peripheral families, look for a shared helper in `CodeGeneration` before duplicating logic across generators. If a change only affects one peripheral family, keep it in that generator. | ||
|
|
||
| ## Generated Output Policy | ||
|
|
||
| `Output/` is useful for inspection and regression review, but it should not be the place you fix problems. If generated output is wrong, fix the generator, ATDF input, supplemental JSON, or boilerplate template that produced it. | ||
|
|
||
| ## Related Docs | ||
|
|
||
| - `CONTRIBUTING.md` for onboarding and common workflows. | ||
| - `DeveloperDocs/DOCUMENTATION_SYSTEM.md` for supplemental docs behavior. | ||
| - `DeveloperDocs/ADDING_PERIPHERALS.md` for peripheral generator changes. | ||
| - `DeveloperDocs/TESTING_AND_GENERATION.md` for verification commands. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.