From c4980f435704a0f70f258d6a2639a73f2cdb92bb Mon Sep 17 00:00:00 2001 From: Graziano Misuraca Date: Sat, 25 Jul 2026 09:55:01 -0400 Subject: [PATCH] wip: board-specific uart and other config This is an attempt to make examples more generic, but putting more of the board-specific config (e.g. which pins are easy to use for uart) in a board file, while still providing an easy way for it to be overridden. --- examples/wch/ch32v/src/uart_log.zig | 32 ++++------------------ port/wch/ch32v/src/boards/LANA_TNY.zig | 6 ++++ port/wch/ch32v/src/boards/nanoCH32V203.zig | 3 ++ port/wch/ch32v/src/hals/usart.zig | 20 ++++++++++++++ 4 files changed, 34 insertions(+), 27 deletions(-) diff --git a/examples/wch/ch32v/src/uart_log.zig b/examples/wch/ch32v/src/uart_log.zig index cb2bc7dc8..3d5328ac9 100644 --- a/examples/wch/ch32v/src/uart_log.zig +++ b/examples/wch/ch32v/src/uart_log.zig @@ -1,14 +1,10 @@ const std = @import("std"); const microzig = @import("microzig"); const hal = microzig.hal; +const board = microzig.board; const time = hal.time; -const gpio = hal.gpio; -const RCC = microzig.chip.peripherals.RCC; -const AFIO = microzig.chip.peripherals.AFIO; - -const usart = hal.usart.instance.USART2; -const usart_tx_pin = gpio.Pin.init(0, 2); // PA2 +const uart_cfg: hal.usart.UartConfig = if (@hasDecl(board, "uart_config")) board.uart_config else .{}; pub const panic = microzig.panic; @@ -22,28 +18,10 @@ comptime { } pub fn main() !void { - // Board brings up clocks and time - microzig.board.init(); - - // Enable peripheral clocks for USART2 and GPIOA - RCC.APB2PCENR.modify(.{ - .IOPAEN = 1, // Enable GPIOA clock - .AFIOEN = 1, // Enable AFIO clock - }); - RCC.APB1PCENR.modify(.{ - .USART2EN = 1, // Enable USART2 clock - }); - - // Ensure USART2 is NOT remapped (default PA2/PA3, not PD5/PD6) - AFIO.PCFR1.modify(.{ .USART2_RM = 0 }); - - // Configure PA2 as alternate function push-pull for USART2 TX - usart_tx_pin.set_output_mode(.alternate_function_push_pull, .max_50MHz); - - // Initialize USART2 at 115200 baud - usart.apply(.{ .baud_rate = 115200 }); + board.init(); - hal.usart.init_logger(usart); + hal.usart.setup_uart(uart_cfg); + hal.usart.init_logger(uart_cfg.instance); var i: u32 = 0; while (true) : (i += 1) { diff --git a/port/wch/ch32v/src/boards/LANA_TNY.zig b/port/wch/ch32v/src/boards/LANA_TNY.zig index c4c744018..832767d1e 100644 --- a/port/wch/ch32v/src/boards/LANA_TNY.zig +++ b/port/wch/ch32v/src/boards/LANA_TNY.zig @@ -20,6 +20,12 @@ pub fn init() void { ch32v.time.init(); } +/// Default UART: USART2 on PA2 (exposed on the board header) +pub const uart_config: ch32v.usart.UartConfig = .{ + .instance = .USART2, + .tx_pin = ch32v.gpio.Pin.init(0, 2), // PA2 +}; + pub const pin_config = ch32v.pins.GlobalConfiguration{ .GPIOD = .{ .PIN0 = .{ diff --git a/port/wch/ch32v/src/boards/nanoCH32V203.zig b/port/wch/ch32v/src/boards/nanoCH32V203.zig index 79a2815da..c69aa5481 100644 --- a/port/wch/ch32v/src/boards/nanoCH32V203.zig +++ b/port/wch/ch32v/src/boards/nanoCH32V203.zig @@ -24,6 +24,9 @@ pub fn init() void { ch32v.clocks.enable_usbfs_clock(); } +/// Default UART: USART1 on PA9 +pub const uart_config: ch32v.usart.UartConfig = .{}; + pub const pin_config = ch32v.pins.GlobalConfiguration{ .GPIOA = .{ .PIN15 = .{ diff --git a/port/wch/ch32v/src/hals/usart.zig b/port/wch/ch32v/src/hals/usart.zig index a6fc86c1d..bb15b97ea 100644 --- a/port/wch/ch32v/src/hals/usart.zig +++ b/port/wch/ch32v/src/hals/usart.zig @@ -90,6 +90,26 @@ pub const ReceiveError = error{ Timeout, }; +const gpio = hal.gpio; + +/// Configuration for board-level UART defaults. +/// Boards export a `uart_config` const of this type with their preferred +/// USART instance, TX pin, and serial settings. Examples can use these +/// defaults directly or construct their own `UartConfig`. +pub const UartConfig = struct { + instance: USART = .USART1, + tx_pin: gpio.Pin = gpio.Pin.init(0, 9), // PA9 (USART1 default TX) + config: Config = .{ .baud_rate = 115200 }, +}; + +/// Configure a UART from a `UartConfig`: sets up the TX pin as alternate +/// function push-pull, then applies the USART peripheral configuration +/// (clock enable, AFIO remap, baud rate, etc.). +pub fn setup_uart(comptime cfg: UartConfig) void { + cfg.tx_pin.configure_alternate_function(.push_pull, .max_50MHz); + cfg.instance.apply(cfg.config); +} + pub const instance = struct { pub const USART1: USART = .USART1; pub const USART2: USART = .USART2;