From a3ea0991056639ef79ba432787547b00c4f7434f Mon Sep 17 00:00:00 2001 From: BlackMark Date: Tue, 28 Jul 2026 16:12:35 +0200 Subject: [PATCH] pureboot: the detail reaches become the library's own API The three things this repo took from under libavr's counter are now over it, and the local copies fold away. The USART release on a software link's pins is the library's init contract (its guard here becomes a deletion, byte-identical images held by the gate); the WDRF routing test is power::peek_reset_cause().watchdog instead of a hand lookup of the flag's register; the tsb tiers' baud arithmetic is the public solver. libavr pin advances over those three additions. Co-Authored-By: Claude Fable 5 --- libavr | 2 +- pureboot/pureboot.cpp | 32 +------------------------------- tsb/tsb_asm.cpp | 2 +- tsb/tsb_policy.cpp | 2 +- tsb/tsb_tricks.cpp | 2 +- 5 files changed, 5 insertions(+), 35 deletions(-) diff --git a/libavr b/libavr index 26b80e2..911a875 160000 --- a/libavr +++ b/libavr @@ -1 +1 @@ -Subproject commit 26b80e262dcf475fdb3c647e43ade1e2ef85d04c +Subproject commit 911a87538f2dc99a22ac0b2faa9434ad6e438362 diff --git a/pureboot/pureboot.cpp b/pureboot/pureboot.cpp index 964d8ea..4665b19 100644 --- a/pureboot/pureboot.cpp +++ b/pureboot/pureboot.cpp @@ -38,13 +38,6 @@ using dev = avr::device<{.clock = avr::hertz_t{PUREBOOT_CLOCK_HZ}}>; constexpr avr::baud_t wire_baud{PUREBOOT_BAUD}; #endif -// The watchdog reset flag's home: MCUSR, or the classic megas' MCUCSR. -consteval std::int16_t wdrf_field() -{ - auto reg = std::string_view{avr::hw::db.regs[static_cast(avr::power::detail::reset_reg())].name}; - return avr::hw::db.field_index(reg, "WDRF"); -} - // The loader owns the top 512 bytes; a staging copy goes in the slot below. // Chips without a hardware boot section — the tinies and the m48s, whose SPM // runs from anywhere (Atmel-8271 §26) — keep the application's relocated @@ -174,27 +167,6 @@ constexpr char usart_digit = '0' + PUREBOOT_USART; constexpr char usart_digit = '0'; #endif -// Release a hardware USART the application may have left enabled onto a -// bit-banged link's pins. A software transmitter drives its TX pin through the -// port register, but while that USART's TXEN is set the USART owns the pin and -// the port write does nothing — the loader would receive and obey yet never -// answer. Writing UCSRnB zero hands the pin back to the port. Guarded on the -// pin actually being a USART's TXD, so a link on non-USART pins emits nothing. -template -[[gnu::always_inline]] inline void release_usart_on() -{ - if constexpr (avr::uart::has_usart()) - if constexpr (avr::uart::detail::usart_pin("TXD") == Tx) - avr::hw::reg_impl()>::write(0); -} - -template -[[gnu::always_inline]] inline void release_usarts_on() -{ - release_usart_on<'0', Tx>(); - release_usart_on<'1', Tx>(); -} - template struct hardware_link { using uart = avr::uart::usart; @@ -241,7 +213,6 @@ struct software_link { static void init() { avr::init(); - release_usarts_on(); } static bool pending() @@ -275,7 +246,6 @@ struct autobaud_link { static void init() { avr::init(); - release_usarts_on(); } static std::uint8_t rx() @@ -498,7 +468,7 @@ void fill_page(std::uint8_t bank, std::uint16_t at) #endif // A watchdog reset belongs to the application, whose watchdog stays forced // on until it clears WDRF — no activation window in its way. - if (avr::hw::field_impl::test()) + if (avr::power::peek_reset_cause().watchdog) run_app(); link::init(); diff --git a/tsb/tsb_asm.cpp b/tsb/tsb_asm.cpp index 7cf105c..1594939 100644 --- a/tsb/tsb_asm.cpp +++ b/tsb/tsb_asm.cpp @@ -65,7 +65,7 @@ constexpr std::uint8_t comm_window = 200; constexpr std::uint16_t build_date = 26 * 512 + 7 * 32 + 20; // Fixed 115200 8N1; the library solves UBRR + U2X from clock and baud. -constexpr auto baud = avr::uart::detail::solve_baud(16_MHz, 115200_Bd); +constexpr auto baud = avr::uart::solve_baud(16_MHz, 115200_Bd); // The 16-byte device-info block, streamed out on activation. // clang-format off diff --git a/tsb/tsb_policy.cpp b/tsb/tsb_policy.cpp index fb061c9..f5cedf2 100644 --- a/tsb/tsb_policy.cpp +++ b/tsb/tsb_policy.cpp @@ -200,7 +200,7 @@ extern "C" [[noreturn]] void tsb_app(); // the application's reset vector: --def // only the divisor low byte and U2X0 need a store. The solver still does // the datasheet work; the asserts pin the reset-state assumptions. { - constexpr auto sol = avr::uart::detail::solve_baud(dev::clock, 115200_Bd); + constexpr auto sol = avr::uart::solve_baud(dev::clock, 115200_Bd); static_assert(sol.u2x && sol.ubrr < 256, "lean bring-up writes UBRR0L only, with U2X0"); avr::hw::reg<"UBRR0">::write(static_cast(sol.ubrr)); avr::hw::ucsr0a::write(avr::hw::ucsr0a::u2x0(1)); diff --git a/tsb/tsb_tricks.cpp b/tsb/tsb_tricks.cpp index 53b0dcc..84d4684 100644 --- a/tsb/tsb_tricks.cpp +++ b/tsb/tsb_tricks.cpp @@ -65,7 +65,7 @@ constexpr std::uint8_t comm_window = 200; constexpr std::uint16_t build_date = 26 * 512 + 7 * 32 + 20; // Fixed 115200 8N1; the library solves UBRR + U2X from clock and baud. -constexpr auto baud = avr::uart::detail::solve_baud(16_MHz, 115200_Bd); +constexpr auto baud = avr::uart::solve_baud(16_MHz, 115200_Bd); // The 16-byte device-info block, streamed out on activation. // clang-format off