Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/wch/ch32v/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub fn build(b: *std.Build) void {
.{ .target = mb.ports.ch32v.boards.ch32v203.lana_tny, .name = "lana_tny_ws2812", .file = "src/ws2812.zig" },
.{ .target = mb.ports.ch32v.boards.ch32v203.lana_tny, .name = "lana_tny_uart_log", .file = "src/uart_log.zig" },
.{ .target = mb.ports.ch32v.boards.ch32v203.lana_tny, .name = "lana_tny_i2c_bus_scan", .file = "src/i2c_bus_scan.zig" },
.{ .target = mb.ports.ch32v.boards.ch32v203.lana_tny, .name = "lana_tny_i2c_eeprom", .file = "src/i2c_eeprom.zig" },
.{ .target = mb.ports.ch32v.boards.ch32v203.lana_tny, .name = "lana_tny_i2c_position_sensor", .file = "src/i2c_position_sensor.zig" },
.{ .target = mb.ports.ch32v.boards.ch32v203.lana_tny, .name = "lana_tny_spi_loopback", .file = "src/spi_loopback.zig" },
.{ .target = mb.ports.ch32v.boards.ch32v203.lana_tny, .name = "lana_tny_spi_flash_w25q", .file = "src/spi_flash_w25q.zig" },
Expand Down
84 changes: 84 additions & 0 deletions examples/wch/ch32v/src/i2c_eeprom.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const std = @import("std");
const microzig = @import("microzig");
const mdf = microzig.drivers;
const hal = microzig.hal;
const gpio = hal.gpio;
const i2c = hal.i2c;

const usart = hal.usart.instance.USART2;
const usart_tx_pin = gpio.Pin.init(0, 2); // PA2

pub const microzig_options = microzig.Options{
.log_level = .debug,
.logFn = hal.usart.log,
};

fn hex_dump(data: []const u8) void {
var offset: usize = 0;
while (offset < data.len) : (offset += 16) {
const end = @min(offset + 16, data.len);
std.log.info("{x:0>4}: {x}", .{ offset, data[offset..end] });
}
}

pub fn main() !void {
// Board brings up clocks and time
microzig.board.init();

// Configure USART2 TX pin (PA2) for alternate function (disable GPIO)
usart_tx_pin.configure_alternate_function(.push_pull, .max_50MHz);

// Initialize USART2 at 115200 baud (uses default pins PA2/PA3)
usart.apply(.{
.baud_rate = 115200,
.remap = .default,
});

hal.usart.init_logger(usart);

// I2C1 is on PB6 (SCL) and PB7 (SDA)
const scl_pin = hal.gpio.Pin.init(1, 6); // GPIOB pin 6
const sda_pin = hal.gpio.Pin.init(1, 7); // GPIOB pin 7

// Configure I2C pins for alternate function (open-drain required for I2C)
scl_pin.configure_alternate_function(.open_drain, .max_50MHz);
sda_pin.configure_alternate_function(.open_drain, .max_50MHz);

// Initialize I2C at 100kHz (uses default pins PB6/PB7)
const instance = i2c.instance.I2C1;
instance.apply(.{});

const eeprom_address: i2c.Address = @enumFromInt(0x50);

// AT24C256 has 32KB (256Kbit), requiring 2-byte addresses
// Read first 256 bytes as a test
var data: [256]u8 = undefined;

// Set address to 0x0000 (2 bytes: high, low)
try instance.write_blocking(eeprom_address, &.{ 0x00, 0x00 }, .from_ms(100));
// Sequential read - address auto-increments
try instance.read_blocking(eeprom_address, &data, .from_ms(100));

std.log.info("Read {d} bytes from EEPROM:", .{data.len});
hex_dump(&data);

// Write value 0x42 at address 0x0005
// Format: [addr_high] [addr_low] [data]
std.log.info("Writing 0x42 at address 0x0005", .{});
try instance.write_blocking(eeprom_address, &.{ 0x00, 0x05, 0x42 }, .from_ms(100));

// Wait for write cycle to complete (~5ms for AT24C256)
hal.time.sleep_ms(10);

// Read back to verify
try instance.write_blocking(eeprom_address, &.{ 0x00, 0x00 }, .from_ms(100));
try instance.read_blocking(eeprom_address, &data, .from_ms(100));

std.log.info("After write:", .{});
hex_dump(&data);

// Infinite loop
while (true) {
hal.time.sleep_ms(1000);
}
}
Loading