From 25501b7d9240fcd81b5388b61e813b2b5ad29e5c Mon Sep 17 00:00:00 2001 From: Friso Date: Tue, 12 May 2026 16:32:46 +0200 Subject: [PATCH] Add contributor documentation and clean up stale references Add CONTRIBUTING.md and DeveloperDocs/ with architecture, documentation system, peripheral guide, and testing reference. Update README.md to surface these resources and reflect the current peripheral set (SPI, TWI). Remove stale references to the deleted generate_avr_tools_device_file.swift from AGENTS.md and README.md. Rename splitTarget to splitTargetLSB in SUPPLEMENTAL_DOCUMENTATION.md to match the actual field name. --- AGENTS.md | 2 - CONTRIBUTING.md | 94 ++++++++++ DeveloperDocs/ADDING_PERIPHERALS.md | 158 ++++++++++++++++ DeveloperDocs/ARCHITECTURE.md | 82 +++++++++ DeveloperDocs/DOCUMENTATION_SYSTEM.md | 233 ++++++++++++++++++++++++ DeveloperDocs/TESTING_AND_GENERATION.md | 154 ++++++++++++++++ README.md | 26 ++- docs/SUPPLEMENTAL_DOCUMENTATION.md | 6 +- 8 files changed, 746 insertions(+), 9 deletions(-) create mode 100644 CONTRIBUTING.md create mode 100644 DeveloperDocs/ADDING_PERIPHERALS.md create mode 100644 DeveloperDocs/ARCHITECTURE.md create mode 100644 DeveloperDocs/DOCUMENTATION_SYSTEM.md create mode 100644 DeveloperDocs/TESTING_AND_GENERATION.md diff --git a/AGENTS.md b/AGENTS.md index 4c1d13e..2a72ba9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,7 +10,6 @@ Key paths: - `atdf/` - source ATDF device descriptions - `docs/` - supplemental JSON docs (`general.json` plus per-chip files) - `Output/` - generated Swift output -- `Scripts/generate_avr_tools_device_file.swift` - ATDF model regeneration helper Data flow: `atdf/*.atdf` -> `XMLDecoder` -> `AVRToolsDeviceFile` -> `GenerationPipeline` -> peripheral generators -> formatted Swift output in `Output//...` ## Extra Rule Files @@ -95,7 +94,6 @@ Add new tests under `SwiftAVRGeneratorTests/` unless the work is specifically UI - Prefer changing generator code or documentation inputs over hand-editing generated files. - Do not edit `Output/` unless the task is specifically about generated output inspection. - When changing docs behavior, check both `docs/general.json` and `docs/.json`. -- If you need to update the ATDF decode layer, inspect `Scripts/generate_avr_tools_device_file.swift` first. - Keep changes scoped; generator logic is shared across many chips. - Match local style in the file you touch; newer code uses `SwiftSyntaxBuilder`, older files sometimes build strings directly. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..2517be9 --- /dev/null +++ b/CONTRIBUTING.md @@ -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/.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/.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. diff --git a/DeveloperDocs/ADDING_PERIPHERALS.md b/DeveloperDocs/ADDING_PERIPHERALS.md new file mode 100644 index 0000000..3db985e --- /dev/null +++ b/DeveloperDocs/ADDING_PERIPHERALS.md @@ -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//` + +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. diff --git a/DeveloperDocs/ARCHITECTURE.md b/DeveloperDocs/ARCHITECTURE.md new file mode 100644 index 0000000..1f07e19 --- /dev/null +++ b/DeveloperDocs/ARCHITECTURE.md @@ -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//... +``` + +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/.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/.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. diff --git a/DeveloperDocs/DOCUMENTATION_SYSTEM.md b/DeveloperDocs/DOCUMENTATION_SYSTEM.md new file mode 100644 index 0000000..b4987a2 --- /dev/null +++ b/DeveloperDocs/DOCUMENTATION_SYSTEM.md @@ -0,0 +1,233 @@ +# Supplemental Documentation System + +HALGEN does not generate high-quality Swift names from ATDF data alone. ATDF files provide hardware structure, register names, bit masks, captions, and memory data. The supplemental documentation system turns that raw data into stable Swift-facing names, types, access metadata, prose, and board defaults. + +## Mental Model + +```text +ATDF gives raw hardware names and structure. +docs/general.json gives shared semantic names, types, access metadata, and inline preferences. +docs/.json gives chip-specific corrections, prose, split-field mappings, and board defaults. +ChipDocumentationLoader merges these sources. +Missing entries still generate code, but are recorded in logs.json. +``` + +Use this system to improve generated output. Do not hand-edit generated files under `Output/`. + +## Inputs + +| Input | Purpose | +| --- | --- | +| `atdf/*.atdf` | Hardware source of truth from Microchip device packs. | +| `docs/general.json` | Shared aliases and reusable metadata for registers and bitfields that mean the same thing across chips. | +| `docs/.json` | Chip-specific documentation, split-field mappings, board defaults, and corrections. | +| `docs/boilerplate/*.swift.template` | Hand-maintained Swift template code included in generated peripheral modules. | +| `docs/coreavr-package/` | Template files used when exporting CoreAVR package support. | + +## Resolution Order + +For registers and bitfields, HALGEN resolves most naming and metadata fields in this order: + +```text +docs/.json +-> docs/general.json +-> generated ATDF fallback +``` + +Chip JSON wins because some chips have behavior or documentation that should not be generalized. `general.json` comes next because many ATDF aliases represent the same semantic concept across peripheral instances or chip families. ATDF fallback keeps generation working even when supplemental data is incomplete. + +Board metadata is chip-specific. It comes from `docs/.json` first, then ATDF memory or clock data when available, then hardcoded defaults where the generator has a safe fallback. + +For exact field-level behavior, use `docs/SUPPLEMENTAL_DOCUMENTATION.md` as the contract. + +## Choosing The Right File + +Edit `docs/general.json` when the same semantic meaning applies across chips or repeated peripheral instances. + +Good `general.json` candidates: + +- common register aliases such as `UDR0`, `UDR1`, `UBRR0`, and `UBRR1` +- common bitfield aliases such as `RXC0` and `RXC1` +- canonical Swift variable names +- reusable value types +- default values +- access metadata +- inline preferences + +Edit `docs/.json` when the value is specific to one chip. + +Good chip-file candidates: + +- datasheet-specific prose +- split bitfield mappings +- chip-specific access behavior +- board metadata such as RAM, flash, EEPROM, baud, and CPU frequency +- corrections for incomplete ATDF data + +If you are unsure whether something is shared, start in the chip file. Generalize later after another chip needs the same concept. + +## Missing Data And Logs + +Missing supplemental documentation does not stop generation. HALGEN uses generated names and ATDF metadata where it can, then records the missing entries in `logs.json`. + +Each missing register log includes: + +- ATDF register name +- caption +- offset +- suggested Swift variable name + +Each missing bitfield log includes: + +- ATDF bitfield name +- caption +- mask +- suggested Swift variable name + +`GenerationPipeline` sets a peripheral context for each registered generator. That context lets `ChipDocumentationLoader` group missing entries by peripheral in `logs.json`. + +Use `logs.json` after generation to decide what belongs in `general.json` and what belongs in a chip file. + +## Audit And Cleanup Scripts + +After a full generation pass, rebuild the grouped `general.json` audit report with: + +```bash +./generate.sh --all +python3 Scripts/audit_general_json.py --logs Output/logs.json +``` + +This writes `docs/README.md`. That file is generated audit output, not stable contributor guidance. + +Preview stale aliases in `docs/general.json` with: + +```bash +python3 Scripts/prune_general_json_aliases.py --dry-run +``` + +Remove stale aliases with: + +```bash +python3 Scripts/prune_general_json_aliases.py +``` + +## Boilerplate Templates + +Some generated modules need hand-maintained Swift code in addition to register accessors. Those snippets live in `docs/boilerplate/*.swift.template`. + +Generators load templates through `BoilerplateTemplate.load` or `BoilerplateTemplate.render`. Templates should contain stable Swift APIs that are not practical to derive directly from ATDF registers. + +When changing a template: + +- generate at least one representative chip that uses it +- inspect the generated module file +- check `formatting-report.txt` +- add or update focused tests when the generated API shape changes + +## Examples + +### Add A Shared Register Alias + +Use `general.json` when several ATDF aliases represent the same Swift concept: + +```json +{ + "aliases": ["UDR0", "UDR1"], + "variableName": "dataRegister", + "valueType": "UInt8", + "defaultValue": "", + "access": "R/W" +} +``` + +The aliases are ATDF names. `variableName` is the generated Swift name. + +### Add A Shared Bitfield Alias + +Use `general.json` for common bitfields: + +```json +{ + "aliases": ["RXC0", "RXC1"], + "variableName": "receiveComplete", + "valueType": "Bool", + "defaultValue": "", + "access": "R", + "inline": "__always" +} +``` + +Single-bit fields usually use `Bool`. Multi-bit fields usually use an integer type or a generated enum, depending on the generator behavior. + +### Add Chip-Specific Register Documentation + +Use `docs/.json` for prose from a specific datasheet: + +```json +{ + "registers": { + "UDR0": { + "documentation": [ + "The USART data register contains received data when read and transmit data when written." + ] + } + } +} +``` + +Documentation arrays are joined with newlines by the loader. + +### Add A Split Bitfield Mapping + +Use `splitTargetLSB` in the chip file when one logical bitfield is split across registers: + +```json +{ + "bitfields": { + "WGM02": { + "variableName": "waveformGenerationMode", + "valueType": "UInt8", + "splitTargetLSB": "WGM0" + } + } +} +``` + +Set `splitTargetLSB` on the bitfield that should own the generated combined accessor. The value is the ATDF name of the lower-significance companion bitfield. + +### Add Board Metadata + +Use the chip file for chip-specific board defaults or ATDF gaps: + +```json +{ + "chip": "ATmega328P", + "board": { + "ramSize": 2048, + "flashSize": 32768, + "eepromSize": 1024, + "baud": 115200, + "cpuFrequency": 16000000 + } +} +``` + +Do not use EEPROM size as RAM size. They are separate memory areas. + +## Common Mistakes + +- Using a generated Swift name as a JSON key. Register and bitfield keys must be exact ATDF aliases. +- Putting chip-specific prose in `general.json`. Documentation prose currently belongs in chip files. +- Duplicating facts the generator can derive reliably from ATDF. +- Editing `docs/README.md` by hand. It is reserved for generated audit output. +- Using the obsolete shorter split-field key instead of `splitTargetLSB`. The loader model expects `splitTargetLSB`. + +## Contract And Source Files + +Keep this guide aligned with: + +- `docs/SUPPLEMENTAL_DOCUMENTATION.md` +- `SwiftAVRGenerator/Documentation/GeneralDocumentation.swift` +- `SwiftAVRGenerator/Documentation/ChipDocumentation.swift` +- `SwiftAVRGenerator/Documentation/ChipDocumentationLoader.swift` +- `SwiftAVRGenerator/Generators/CoreAVRPackageSupport.swift` diff --git a/DeveloperDocs/TESTING_AND_GENERATION.md b/DeveloperDocs/TESTING_AND_GENERATION.md new file mode 100644 index 0000000..6d472d9 --- /dev/null +++ b/DeveloperDocs/TESTING_AND_GENERATION.md @@ -0,0 +1,154 @@ +# Testing And Generation + +Use this guide when you need exact commands for building, generating, testing, and inspecting HALGEN output. + +## Helper Script + +The preferred workflow is `generate.sh` from the repository root. It builds the CLI in Release and then runs it. + +Generate the default representative chip, currently `ATmega328P`: + +```bash +./generate.sh +``` + +Generate every bundled ATDF file: + +```bash +./generate.sh --all +``` + +Generate into a temporary output directory: + +```bash +./generate.sh --output /tmp/halgen-test +``` + +Generate every bundled chip into a temporary output directory: + +```bash +./generate.sh --all --output /tmp/halgen-test +``` + +Show CLI help: + +```bash +./generate.sh --help +``` + +## Direct CLI Build And Run + +Build the CLI directly: + +```bash +xcodebuild \ + -project SwiftAVRGenerator.xcodeproj \ + -scheme SwiftAVRGeneratorCLI \ + -configuration Release \ + -destination "platform=macOS,arch=arm64" \ + -derivedDataPath .build +``` + +Run the built CLI: + +```bash +.build/Build/Products/Release/SwiftAVRGeneratorCLI [--all] [--output ] +``` + +## App Build + +Build the SwiftUI app target: + +```bash +xcodebuild \ + -project SwiftAVRGenerator.xcodeproj \ + -scheme SwiftAVRGenerator \ + -configuration Debug \ + -destination "platform=macOS,arch=arm64" \ + -derivedDataPath .build +``` + +## Tests + +Run the full test suite: + +```bash +xcodebuild test \ + -project SwiftAVRGenerator.xcodeproj \ + -scheme SwiftAVRGenerator \ + -destination "platform=macOS,arch=arm64" +``` + +Run the focused unit test class: + +```bash +xcodebuild test \ + -project SwiftAVRGenerator.xcodeproj \ + -scheme SwiftAVRGenerator \ + -destination "platform=macOS,arch=arm64" \ + -only-testing:SwiftAVRGeneratorTests/SwiftAVRGeneratorTests +``` + +Run one focused unit test: + +```bash +xcodebuild test \ + -project SwiftAVRGenerator.xcodeproj \ + -scheme SwiftAVRGenerator \ + -destination "platform=macOS,arch=arm64" \ + -only-testing:SwiftAVRGeneratorTests/SwiftAVRGeneratorTests/testExample +``` + +If local signing blocks a test run, append: + +```bash +CODE_SIGNING_ALLOWED=NO CODE_SIGN_IDENTITY="" DEVELOPMENT_TEAM="" +``` + +Example: + +```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="" +``` + +## Inspecting Generated Output + +After generation, inspect the generated files for the affected chip and these reports: + +```text +Output/logs.json +Output/formatting-report.txt +``` + +When using `--output /tmp/halgen-test`, inspect: + +```text +/tmp/halgen-test/logs.json +/tmp/halgen-test/formatting-report.txt +``` + +`logs.json` records missing supplemental documentation grouped by chip and peripheral. Unexpected new missing entries usually mean a generator started looking at new registers or bitfields that need aliases in `docs/general.json` or chip-specific entries in `docs/.json`. + +`formatting-report.txt` records diagnostics from generated Swift formatting. Formatting diagnostics should be reviewed before treating generated output as valid. + +## Which Generation Command To Use + +| Change type | Suggested verification | +| --- | --- | +| One peripheral on a common chip | `./generate.sh --output /tmp/halgen-test` | +| Shared register or bitfield generation | focused tests, then `./generate.sh --output /tmp/halgen-test` | +| Supplemental docs behavior | focused tests, then `./generate.sh --output /tmp/halgen-test` | +| New peripheral generator | focused tests, then `./generate.sh --all --output /tmp/halgen-test` | +| CLI output path handling | `./generate.sh --output /tmp/halgen-test` | +| Broad architecture change | full tests, then `./generate.sh --all --output /tmp/halgen-test` | + +Use `ATmega328P` as the representative chip unless the change targets another device. + +## Generated Output Policy + +Do not fix generated code by editing `Output/`. Fix the source that produced it: generator code, supplemental JSON, boilerplate templates, or ATDF input. diff --git a/README.md b/README.md index d3a8e69..7d75d4c 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,19 @@ generator. The CLI is the primary workflow. Bundled ATDF files originate from: http://packs.download.atmel.com +## Contributing + +Start with `CONTRIBUTING.md` if you are changing generator behavior, adding a +peripheral, updating supplemental documentation, or preparing a contribution for +review. + +The deeper contributor guides live under `DeveloperDocs/`: + +- `DeveloperDocs/ARCHITECTURE.md` explains the generator pipeline and codebase layout. +- `DeveloperDocs/DOCUMENTATION_SYSTEM.md` explains `docs/general.json`, chip JSON files, templates, and missing-data logs. +- `DeveloperDocs/ADDING_PERIPHERALS.md` explains how to add or change peripheral generators. +- `DeveloperDocs/TESTING_AND_GENERATION.md` collects build, generation, and test commands. + ## Requirements - macOS with Xcode installed @@ -69,9 +82,11 @@ xcodebuild \ HALGEN currently generates these peripheral families: -- GPIO - ADC +- GPIO +- SPI - Timers +- TWI - UART Representative output for `ATmega328P`: @@ -82,10 +97,16 @@ Output/ | `-- module/ | |-- AnalogToDigitalConverter.swift | |-- GPIO.swift +| |-- SPI/ +| | |-- SPI.swift +| | `-- SPI0.swift | |-- Timer/ | | |-- Timer0.swift | | |-- Timer1.swift | | `-- Timer2.swift +| |-- TwoWireInterface/ +| | |-- TwoWireInterface.swift +| | `-- TwoWireInterface0.swift | `-- UART/ | |-- UART.swift | `-- UART0.swift @@ -201,9 +222,6 @@ HALGEN/ report. - `Scripts/prune_general_json_aliases.py` removes stale `general.json` aliases that no longer appear in the bundled ATDF files. -- `Scripts/generate_avr_tools_device_file.swift` helps regenerate the ATDF model - layer when needed. - ## Development Build the macOS app target: diff --git a/docs/SUPPLEMENTAL_DOCUMENTATION.md b/docs/SUPPLEMENTAL_DOCUMENTATION.md index 148c296..7ff5334 100644 --- a/docs/SUPPLEMENTAL_DOCUMENTATION.md +++ b/docs/SUPPLEMENTAL_DOCUMENTATION.md @@ -89,7 +89,7 @@ Current behavior: - `access`: chip value, else general value, else ATDF `rw`, else read/write - `inline`: chip value, else general value, else `"__always"` - `documentation`: chip file only -- `splitTarget`: chip file only +- `splitTargetLSB`: chip file only - `overrideGeneratedDocumentation`: chip file only If neither chip nor general docs define a bitfield alias, HALGEN still @@ -150,7 +150,7 @@ Notes: - `aliases` is required and should include every ATDF alias that maps to the same concept. - `variableName` is required in practice and should be the canonical generated Swift name. - `documentation` does not belong in `general.json` today. -- `splitTarget` does not belong in `general.json` today. +- `splitTargetLSB` does not belong in `general.json` today. - Keep entries semantic. Prefer one shared concept with several aliases over many duplicate objects. ## `docs/.json` @@ -191,7 +191,7 @@ Shape: "access": "R", "documentation": ["Chip-specific bitfield documentation paragraph."], "inline": "__always", - "splitTarget": "UCSZ0", + "splitTargetLSB": "UCSZ0", "overrideGeneratedDocumentation": true } }