build: the libavr pin advances past the audit sweep, and the numbers get names

The pin crosses libavr's phase-6 close and the guideline sweep behind it;
the image is byte-identical in both modes at 8206 bytes.

The port's own sweep, against the same rules. Every mutable `static inline`
takes `m_` - uptime's counter, the sampler's window, the controller's five,
the statistics histogram and the terminal's line state (rule 46; a private
`static constexpr` is a constant rather than state and keeps its bare name).
The command table is `std::to_array` and the serial config breaks one member
per line (rules 36, 40). And three numbers get the name they already had
somewhere: duty goes through `percent_t::of()` rather than a hand-built
basis-point count, the ADC's top count is `thermistor::adc_full_scale`
instead of 1023 in four places, and the two `0xffffffff` are `open_circuit`
- which was already declared five lines away - and `never_written`, which
replaces a comment explaining the literal (rules 5, 6, 41).

Measured, not assumed: rendering `adc_full_scale` into the `show` line
instead of leaving it in the message string cost 6 bytes, so the display
text stays text.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-12 14:40:33 +02:00
parent 1489f4c3a0
commit 837b832bc7
7 changed files with 102 additions and 90 deletions

View File

@@ -13,24 +13,24 @@ using dev = avr::device<{.clock = 16_MHz}>;
// Millisecond uptime from timer2 CTC (the fan owns timer0).
class uptime {
static inline volatile std::uint64_t ms = 0;
static inline volatile std::uint64_t m_ms = 0;
public:
using ticker = dev::timer2<{.frequency = 1_kHz, .on_compare = [] { ms = ms + 1; }}>;
using ticker = dev::timer2<{.frequency = 1_kHz, .on_compare = [] { m_ms = m_ms + 1; }}>;
static std::uint64_t millis()
{
avr::irq::interrupt_guard lock;
return ms;
return m_ms;
}
};
// 1000-sample averaging window fed by the conversion interrupt.
class sampler {
static inline volatile std::uint32_t sum = 0;
static inline volatile std::uint16_t count = 0;
static inline volatile std::uint16_t window = 0;
static inline volatile bool ready = false;
static inline volatile std::uint32_t m_sum = 0;
static inline volatile std::uint16_t m_count = 0;
static inline volatile std::uint16_t m_window = 0;
static inline volatile bool m_ready = false;
static constexpr std::uint16_t samples = 1000;
@@ -38,13 +38,13 @@ class sampler {
using input = dev::adc<{.trigger = avr::adc::trigger::free_running,
.on_conversion =
[](std::uint16_t value) {
sum = sum + value;
count = count + 1;
if (count >= samples) {
window = static_cast<std::uint16_t>(sum / samples);
sum = 0;
count = 0;
ready = true;
m_sum = m_sum + value;
m_count = m_count + 1;
if (m_count >= samples) {
m_window = static_cast<std::uint16_t>(m_sum / samples);
m_sum = 0;
m_count = 0;
m_ready = true;
}
}},
avr::adc::input<avr::adc::input_pin(0)>>;
@@ -55,11 +55,11 @@ class sampler {
static bool take(std::uint16_t &value)
{
avr::irq::interrupt_guard lock;
if (!ready) {
if (!m_ready) {
return false;
}
value = window;
ready = false;
value = m_window;
m_ready = false;
return true;
}
};
@@ -69,7 +69,11 @@ using fan = dev::pwm<avr::pd5, {.frequency = 50_kHz}>;
// 115200 at 16 MHz lands +2.1 % off, past the receiver-tolerance table the
// solver holds rates to - the rate this board has always spoken, so the
// override states that it is meant.
using serial_t = dev::uart0<{.baud = 115200_Bd, .rx_buffer = 32, .allow_baud_error = true}>;
using serial_t = dev::uart0<{
.baud = 115200_Bd,
.rx_buffer = 32,
.allow_baud_error = true,
}>;
inline constexpr serial_t serial{};
} // namespace app