Use libavr flash_table and __builtin_log

The thermistor Beta curve and the fan cubic move onto avr::flash_table
instead of hand-rolled [[gnu::progmem]] arrays with raw pgm_read, and
the compile-time logarithm uses __builtin_log (which constant-folds on
the AVR backend) instead of a hand-rolled series. Same 11284 B, still
byte-identical across libavr modes.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-18 08:03:42 +02:00
parent ab78d94872
commit f17ebd17e5
2 changed files with 29 additions and 58 deletions

View File

@@ -3,11 +3,11 @@
#include <array>
#include <cstdint>
#include <avr/pgmspace.h>
#include <libavr/flash.hpp>
// The auto-mode fan curve, tabulated at compile time: the legacy cubic
// (0.002246·x³ 0.09·x² + 0.91·x, zero below 20 °C) becomes a flash
// lookup of duty percent per °C.
// (0.002246·x³ 0.09·x² + 0.91·x, zero below 20 °C) becomes a libavr
// flash_table of duty percent per °C.
namespace app::curve {
namespace detail {
@@ -25,14 +25,13 @@ consteval std::uint8_t duty_entry(int celsius)
return static_cast<std::uint8_t>(duty + 0.5);
}
struct table {
[[gnu::progmem]] static constexpr std::array<std::uint8_t, 100> data = [] {
std::array<std::uint8_t, 100> out{};
for (int t = 0; t < 100; ++t)
out[static_cast<std::size_t>(t)] = duty_entry(t);
return out;
}();
};
inline constexpr avr::flash_table<[] {
std::array<std::uint8_t, 100> out{};
for (int t = 0; t < 100; ++t)
out[static_cast<std::size_t>(t)] = duty_entry(t);
return out;
}()>
table;
} // namespace detail
@@ -43,7 +42,7 @@ inline std::uint8_t duty(std::int8_t celsius)
celsius = 0;
if (celsius > 99)
celsius = 99;
return pgm_read_byte(&detail::table::data[static_cast<std::uint8_t>(celsius)]);
return detail::table[static_cast<std::uint8_t>(celsius)];
}
} // namespace app::curve