build: the libavr pin advances over the trait projection
The de-string-2 pass upstream: every peripheral block behind generated instance traits, int-keyed, the string layer gone. The port's share of it is two spellings — the char usart_digit that existed to be pasted into register names becomes the int unit the usart template now takes, and the tsb tiers' one reg<"UBRR0"> is the flat hw::ubrr0 — plus the pbapp harness probing has_usart<0>() instead of instance-name strings. Nine loader codegen families rebuilt green through their full workflows (size matrix and simulator protocol suites included); every image holds its recorded size. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2
libavr
2
libavr
Submodule libavr updated: f5d71225a2...56337f37de
@@ -162,14 +162,14 @@ constexpr std::uint8_t bank_shift = 16 - slot_shift;
|
||||
#define PUREBOOT_TX pb1
|
||||
#endif
|
||||
#if defined(PUREBOOT_USART)
|
||||
constexpr char usart_digit = '0' + PUREBOOT_USART;
|
||||
constexpr int usart_unit = PUREBOOT_USART;
|
||||
#else
|
||||
constexpr char usart_digit = '0';
|
||||
constexpr int usart_unit = 0;
|
||||
#endif
|
||||
|
||||
template <avr::hertz_t C, avr::baud_t B>
|
||||
struct hardware_link {
|
||||
using uart = avr::uart::usart<usart_digit, C, {.baud = B, .max_baud_error = 2.5_pct}>;
|
||||
using uart = avr::uart::usart<usart_unit, C, {.baud = B, .max_baud_error = 2.5_pct}>;
|
||||
|
||||
// The compiled idle poll: lds UCSR0A (2), sbrc skipping the exit (2),
|
||||
// sbiw + sbci + sbci + brne (6).
|
||||
@@ -270,12 +270,12 @@ struct autobaud_link {
|
||||
#if defined(PUREBOOT_AUTOBAUD)
|
||||
using link = autobaud_link;
|
||||
#elif defined(PUREBOOT_USART)
|
||||
static_assert(avr::uart::has_usart<usart_digit>(), "PUREBOOT_USART selects a hardware USART this chip does not have");
|
||||
static_assert(avr::uart::has_usart<usart_unit>(), "PUREBOOT_USART selects a hardware USART this chip does not have");
|
||||
using link = hardware_link<dev::clock, wire_baud>;
|
||||
#elif defined(PUREBOOT_SOFT_SERIAL)
|
||||
using link = software_link<dev::clock, wire_baud>;
|
||||
#else
|
||||
using link = std::conditional_t<avr::uart::has_usart<usart_digit>(), hardware_link<dev::clock, wire_baud>,
|
||||
using link = std::conditional_t<avr::uart::has_usart<usart_unit>(), hardware_link<dev::clock, wire_baud>,
|
||||
software_link<dev::clock, wire_baud>>;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ consteval bool use_hardware()
|
||||
#if defined(PUREBOOT_SOFT_SERIAL)
|
||||
return false;
|
||||
#else
|
||||
return avr::hw::db.has_instance("USART0") || avr::hw::db.has_instance("USART");
|
||||
return avr::uart::has_usart<0>();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ struct link {
|
||||
#else
|
||||
static constexpr avr::baud_t baud{115200};
|
||||
#endif
|
||||
using tx_t = avr::uart::usart<'0' + PUREBOOT_USART, C, {.baud = baud, .max_baud_error = 2.5_pct}>;
|
||||
using tx_t = avr::uart::usart<PUREBOOT_USART, C, {.baud = baud, .max_baud_error = 2.5_pct}>;
|
||||
static void tx(char c)
|
||||
{
|
||||
tx_t::write(static_cast<std::uint8_t>(c));
|
||||
|
||||
@@ -263,7 +263,7 @@ extern "C" [[noreturn]] void tsb_app(); // the application's reset vector: --def
|
||||
// 0, and rx()/tx() raise RXEN0/TXEN0 on first use — only the divisor low
|
||||
// byte and U2X0 need a store. The library still does the datasheet work.
|
||||
static_assert(baud.u2x && baud.ubrr < 256, "lean bring-up writes UBRR0L only, with U2X0");
|
||||
hw::reg<"UBRR0">::write(static_cast<std::uint8_t>(baud.ubrr));
|
||||
hw::ubrr0::write(static_cast<std::uint8_t>(baud.ubrr));
|
||||
hw::ucsr0a::write(hw::ucsr0a::u2x0(1));
|
||||
// General-purpose registers are undefined at power-on (no crt zeroes them);
|
||||
// the direction latch must start "not receiving" so the first rx() enables
|
||||
|
||||
@@ -202,7 +202,7 @@ extern "C" [[noreturn]] void tsb_app(); // the application's reset vector: --def
|
||||
{
|
||||
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<std::uint8_t>(sol.ubrr));
|
||||
avr::hw::ubrr0::write(static_cast<std::uint8_t>(sol.ubrr));
|
||||
avr::hw::ucsr0a::write(avr::hw::ucsr0a::u2x0(1));
|
||||
}
|
||||
|
||||
|
||||
@@ -240,7 +240,7 @@ extern "C" [[noreturn]] void tsb_app(); // the application's reset vector: --def
|
||||
// 0, and rx()/tx() raise RXEN0/TXEN0 on first use — only the divisor low
|
||||
// byte and U2X0 need a store. The library still does the datasheet work.
|
||||
static_assert(baud.u2x && baud.ubrr < 256, "lean bring-up writes UBRR0L only, with U2X0");
|
||||
hw::reg<"UBRR0">::write(static_cast<std::uint8_t>(baud.ubrr));
|
||||
hw::ubrr0::write(static_cast<std::uint8_t>(baud.ubrr));
|
||||
hw::ucsr0a::write(hw::ucsr0a::u2x0(1));
|
||||
// General-purpose registers are undefined at power-on (no crt zeroes them);
|
||||
// the direction latch must start "not receiving" so the first rx() enables
|
||||
|
||||
Reference in New Issue
Block a user