HALGEN generates Swift hardware abstraction layers for AVR microcontrollers. It reads bundled ATDF (Atmel Device File) XML descriptions, merges them with supplemental JSON documentation, and emits formatted Swift source for each chip.
atdf/*.atdf + docs/general.json + docs/<Chip>.json
-> GenerationPipeline
-> Output/<Chip>/...
The repository includes both a SwiftUI macOS app target and a command-line generator. The CLI is the primary workflow.
Bundled ATDF files originate from: http://packs.download.atmel.com
- macOS with Xcode installed
- Xcode command line tools pointed at the full Xcode app:
sudo xcode-select --switch /Applications/Xcode.app/Contents/DeveloperUse the helper script at the project root. It builds the CLI in Release and then runs it.
./generate.sh
./generate.sh --all
./generate.sh --output /tmp/halgen-test
./generate.sh --all --output /tmp/halgen-testDefault behavior:
| Invocation | Result |
|---|---|
./generate.sh |
Generate ATmega328P into Output/ |
./generate.sh --all |
Generate every bundled .atdf file in atdf/ |
./generate.sh --output <path> |
Write output to a custom directory |
Show CLI help:
./generate.sh --helpIf you want to build and invoke the binary yourself:
xcodebuild \
-project SwiftAVRGenerator.xcodeproj \
-scheme SwiftAVRGeneratorCLI \
-configuration Release \
-destination "platform=macOS,arch=arm64" \
-derivedDataPath .build
.build/Build/Products/Release/SwiftAVRGeneratorCLI [--all] [--output <path>]HALGEN currently generates these peripheral families:
- GPIO
- ADC
- Timers
- UART
Representative output for ATmega328P:
Output/
|-- ATmega328P/
| `-- module/
| |-- AnalogToDigitalConverter.swift
| |-- GPIO.swift
| |-- Timer/
| | |-- Timer0.swift
| | |-- Timer1.swift
| | `-- Timer2.swift
| `-- UART/
| |-- UART.swift
| `-- UART0.swift
|-- formatting-report.txt
`-- logs.json
logs.json records missing supplemental documentation for each chip. It also
includes top-level exported/skipped chip counts, and any missing items are
grouped by peripheral so follow-up audit tooling can work directly from the log.
formatting-report.txt captures diagnostics from the code formatter that runs on
every generated file.
The files in docs/ add naming, access metadata, and richer documentation on
top of the raw ATDF input:
docs/general.jsoncontains shared aliases and reusable metadata.docs/<Chip>.jsoncontains chip-specific register and bitfield details.docs/SUPPLEMENTAL_DOCUMENTATION.mddocuments the expected shape, precedence, and fallback behavior for these JSON files.- Missing entries fall back to generated names and are reported in
logs.json.
This is the preferred way to improve generated output. Avoid hand-editing files
under Output/ unless you are only inspecting generated results.
Use docs/SUPPLEMENTAL_DOCUMENTATION.md for stable contributor guidance.
docs/README.md is reserved for generated audit output.
Use Scripts/audit_general_json.py to regenerate the grouped audit report in
docs/README.md.
Preferred workflow after a full generation pass:
./generate.sh --all
python3 Scripts/audit_general_json.py --logs Output/logs.jsonWhat it does:
- Uses
logs.jsonas the source of aliases the generator actually reported as missing - Reads the per-peripheral grouping directly from
logs.json - Cleans suggested
variableNamevalues and groups aliases within the same peripheral family - Writes the report to
docs/README.md
If you do not have a fresh logs.json, it can still fall back to a direct scan:
python3 Scripts/audit_general_json.pyNo script edits or extra flags are needed for new peripherals when you use the
logs-based workflow. The script reads whatever peripheral names are present in
logs.json. If you use the direct-scan fallback, it groups entries by ATDF
module name automatically.
Use Scripts/prune_general_json_aliases.py to remove aliases from
docs/general.json that no longer exist in any bundled atdf/*.atdf file.
python3 Scripts/prune_general_json_aliases.py --dry-run
python3 Scripts/prune_general_json_aliases.pyWhat it does:
- Scans every register and bitfield name in
atdf/*.atdf - Compares those names against the aliases in
docs/general.json - Removes only the missing alias when an entry still has other valid aliases
- Removes the whole JSON object when its only alias is stale
- Prints each removal exactly as it happens, for example:
Removed alias: section=registers variableName=outputCompareRegister alias=OCR1
Use --dry-run to preview removals without writing back to docs/general.json.
HALGEN/
|-- generate.sh
|-- atdf/
|-- docs/
|-- Output/
|-- Scripts/
|-- SwiftAVRGenerator/
| |-- App/
| |-- CLI/
| |-- Generators/
| |-- CodeGeneration/
| |-- Documentation/
| `-- AVRToolsDeviceFile/
|-- SwiftAVRGeneratorTests/
`-- SwiftAVRGeneratorUITests/
SwiftAVRGenerator/App/contains the SwiftUI macOS app target.SwiftAVRGenerator/CLI/contains the command-line entry point.SwiftAVRGenerator/Generators/contains the generation pipeline and peripheral generators.SwiftAVRGenerator/Documentation/contains the supplemental doc models and loader.Scripts/audit_general_json.pyrebuilds the missinggeneral.jsonaudit report.Scripts/prune_general_json_aliases.pyremoves stalegeneral.jsonaliases that no longer appear in the bundled ATDF files.Scripts/generate_avr_tools_device_file.swifthelps regenerate the ATDF model layer when needed.
Build the macOS app target:
xcodebuild \
-project SwiftAVRGenerator.xcodeproj \
-scheme SwiftAVRGenerator \
-configuration Debug \
-destination "platform=macOS,arch=arm64" \
-derivedDataPath .buildRun tests:
xcodebuild test \
-project SwiftAVRGenerator.xcodeproj \
-scheme SwiftAVRGenerator \
-destination "platform=macOS,arch=arm64"If local signing blocks test runs, retry with:
xcodebuild test \
-project SwiftAVRGenerator.xcodeproj \
-scheme SwiftAVRGenerator \
-destination "platform=macOS,arch=arm64" \
CODE_SIGNING_ALLOWED=NO CODE_SIGN_IDENTITY="" DEVELOPMENT_TEAM=""