build: the libavr pin advances over the drain and delay contracts
The hand-over drains move to the explicit drain_unbounded() — both link adapters drain only after their own write, so the frame is in flight by construction and the bounded default's countdown would be dead bytes; the images stay byte-identical. window_polls() states its arithmetic through dev::cycles_for with the whole window converted before the per-poll division — one truncation instead of one per second, same instructions, only the countdown's immediate moves. Every size in the matrix is unchanged; the full gate is green on all 37 chips. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2
libavr
2
libavr
Submodule libavr updated: 56337f37de...c21ed3171e
@@ -10,6 +10,8 @@
|
|||||||
// is what makes a copy one slot below able to rewrite the resident one, and
|
// is what makes a copy one slot below able to rewrite the resident one, and
|
||||||
// every change here has to keep it (test/check_pi.py).
|
// every change here has to keep it (test/check_pi.py).
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
#include <libavr/libavr.hpp>
|
#include <libavr/libavr.hpp>
|
||||||
|
|
||||||
using namespace avr::literals;
|
using namespace avr::literals;
|
||||||
@@ -209,7 +211,10 @@ struct hardware_link {
|
|||||||
|
|
||||||
static void drain()
|
static void drain()
|
||||||
{
|
{
|
||||||
uart::drain();
|
// A drain here always follows this link's own write — the frame is
|
||||||
|
// in flight by construction, so the completion the wait needs is
|
||||||
|
// guaranteed and the bounded default's countdown would be dead bytes.
|
||||||
|
uart::drain_unbounded();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -277,7 +282,10 @@ struct autobaud_link {
|
|||||||
|
|
||||||
static void drain()
|
static void drain()
|
||||||
{
|
{
|
||||||
uart::drain();
|
// A drain here always follows this link's own write — the frame is
|
||||||
|
// in flight by construction, so the completion the wait needs is
|
||||||
|
// guaranteed and the bounded default's countdown would be dead bytes.
|
||||||
|
uart::drain_unbounded();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -340,7 +348,10 @@ void await_host()
|
|||||||
// cost stays wide, so the choice cannot oscillate on the boundary.
|
// cost stays wide, so the choice cannot oscillate on the boundary.
|
||||||
consteval std::uint32_t polls_at(std::uint32_t per_poll)
|
consteval std::uint32_t polls_at(std::uint32_t per_poll)
|
||||||
{
|
{
|
||||||
return timeout_seconds * (dev::clock.hz / per_poll);
|
// Whole-window cycles first, then the per-poll division: one truncation
|
||||||
|
// instead of one per second. Same instructions either way — only the
|
||||||
|
// countdown's immediate moves.
|
||||||
|
return static_cast<std::uint32_t>(dev::cycles_for<std::chrono::seconds{timeout_seconds}>() / per_poll);
|
||||||
}
|
}
|
||||||
|
|
||||||
consteval bool narrow_window()
|
consteval bool narrow_window()
|
||||||
|
|||||||
Reference in New Issue
Block a user