The submodule replaces FetchContent and the unpinned forge fallback; LIBAVR_ROOT stays as the tandem-development override, the presets take the toolchain file from the submodule, and the Studio project's include path anchors there — correct by construction. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
59 lines
2.5 KiB
Markdown
59 lines
2.5 KiB
Markdown
# fantemp
|
||
|
||
Temperature-controlled fan firmware (ATmega328P, 16 MHz), rewritten on
|
||
[libavr](https://git.blackmark.me/avr/libavr): thermistor on ADC0 sampled
|
||
free-running and averaged over 1000 conversions, fan on OC0B at 50 kHz,
|
||
115200 Bd serial console (`help` lists the commands), temperature
|
||
histogram persisted to EEPROM, watchdog-reset path into a boot-section
|
||
bootloader.
|
||
|
||
The Steinhart–Hart math of the legacy firmware (runtime doubles + libm
|
||
log) is gone: the Beta equation and the cubic fan curve are evaluated
|
||
consteval into flash tables — the firmware itself never touches floating
|
||
point.
|
||
|
||
libavr rides as the `libavr/` submodule, pinned to the commit this firmware
|
||
builds against; `LIBAVR_ROOT` (cache or environment) overrides it for
|
||
development against a working tree:
|
||
|
||
```sh
|
||
git submodule update --init libavr
|
||
cmake --preset atmega328p-generated
|
||
cmake --build --preset atmega328p-generated
|
||
```
|
||
|
||
## Atmel Studio
|
||
|
||
`master` carries a Studio solution, so this branch does too: `ide/fantemp.atsln`
|
||
builds the same firmware — byte-identical `.text` and `.data` to the CMake
|
||
build — from the same sources, with the flags mirrored by hand.
|
||
|
||
Studio finds libavr in the **submodule**, at
|
||
`$(MSBuildProjectDirectory)\..\libavr\include` — correct by construction, and
|
||
anchored to the project rather than written relative to the generated makefile,
|
||
which runs from the configuration's output directory and would need a different
|
||
number of `..`. Unlike the CMake build there is no `LIBAVR_ROOT` to point
|
||
elsewhere: an environment variable set in a shell is not visible to Studio
|
||
launched from the Start menu — which is what the submodule answers.
|
||
|
||
It also needs a GCC 16.1 toolchain registered as flavour `avr-g++-16.1.0`;
|
||
nothing older can compile `-std=c++26`.
|
||
|
||
One generated file is required before the project will load, and one command
|
||
checks the flags have not drifted (both from libavr's `tools/atmelstudio/`):
|
||
|
||
```sh
|
||
python ../libavr/tools/atmelstudio/componentinfo.py \
|
||
ide/fantemp.componentinfo.xml --device ATmega328P
|
||
python ../libavr/tools/atmelstudio/check-flags.py --solution ide/fantemp.atsln \
|
||
--compile-commands build/atmega328p-generated/compile_commands.json \
|
||
--log build/atmelstudio.log
|
||
```
|
||
|
||
CMake remains the build system; the solution is there so the project opens in
|
||
Studio as its predecessor did. Only the Release configuration is gated against
|
||
CMake — the presets define no debug build — and Debug carries the `-Og
|
||
-gdwarf-4` pair libavr's own debug preset uses.
|
||
|
||
Legacy (yazoalfa submodules) stays on `master`.
|