fix i2c reading and add bus scan example (#71)

wch-ch32v003
Vlad Panazan 1 year ago committed by GitHub
parent 360655dbe2
commit 35e9757bdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -63,6 +63,7 @@ pub const Examples = struct {
blinky: *microzig.EmbeddedExecutable, blinky: *microzig.EmbeddedExecutable,
blinky_core1: *microzig.EmbeddedExecutable, blinky_core1: *microzig.EmbeddedExecutable,
gpio_clk: *microzig.EmbeddedExecutable, gpio_clk: *microzig.EmbeddedExecutable,
i2c_bus_scan: *microzig.EmbeddedExecutable,
pwm: *microzig.EmbeddedExecutable, pwm: *microzig.EmbeddedExecutable,
spi_master: *microzig.EmbeddedExecutable, spi_master: *microzig.EmbeddedExecutable,
uart: *microzig.EmbeddedExecutable, uart: *microzig.EmbeddedExecutable,

@ -0,0 +1,44 @@
const std = @import("std");
const microzig = @import("microzig");
const rp2040 = microzig.hal;
const i2c = rp2040.i2c;
const gpio = rp2040.gpio;
const peripherals = microzig.chip.peripherals;
pub const std_options = struct {
pub const log_level = .info;
pub const logFn = rp2040.uart.log;
};
const uart = rp2040.uart.num(0);
const i2c0 = i2c.num(0);
pub fn main() !void {
uart.apply(.{
.baud_rate = 115200,
.tx_pin = gpio.num(0),
.rx_pin = gpio.num(1),
.clock_config = rp2040.clock_config,
});
rp2040.uart.init_logger(uart);
_ = i2c0.apply(.{
.clock_config = rp2040.clock_config,
.scl_pin = gpio.num(4),
.sda_pin = gpio.num(5),
});
for (0..std.math.maxInt(u7)) |addr| {
const a: i2c.Address = @enumFromInt(addr);
// Skip over any reserved addresses.
if (a.is_reserved()) continue;
var rx_data: [1]u8 = undefined;
_ = i2c0.read_blocking(a, &rx_data) catch continue;
std.log.info("I2C device found at address {X}.", .{addr});
}
}

@ -243,12 +243,13 @@ pub const I2C = enum(u1) {
_ = tc; _ = tc;
} }
}; };
try i2c.read_blocking_internal(addr, dst, Timeout{}); return i2c.read_blocking_internal(addr, dst, Timeout{});
} }
/// Determine non-blocking write space available. /// Determine non-blocking write space available.
pub inline fn get_write_available(i2c: I2C) u5 { pub inline fn get_write_available(i2c: I2C) u5 {
return i2c.get_regs().IC_TXFLR.read().TXFLR; const IC_TX_BUFFER_DEPTH = 16;
return IC_TX_BUFFER_DEPTH - i2c.get_regs().IC_TXFLR.read().TXFLR;
} }
/// Determine number of bytes received. /// Determine number of bytes received.
@ -378,7 +379,7 @@ pub const I2C = enum(u1) {
for (dst, 0..) |*byte, i| { for (dst, 0..) |*byte, i| {
const first = (i == 0); const first = (i == 0);
const last = (i == dst.len - 1); const last = (i == dst.len - 1);
while (i2c.get_write_available(i2c) == 0) { while (i2c.get_write_available() == 0) {
hw.tight_loop_contents(); hw.tight_loop_contents();
} }
@ -388,11 +389,11 @@ pub const I2C = enum(u1) {
.CMD = .{ .value = .READ }, .CMD = .{ .value = .READ },
.DAT = 0, .DAT = 0,
.FIRST_DATA_BYTE = .{ .value = 0 }, .FIRST_DATA_BYTE = .{ .raw = 0 },
.padding = 0, .padding = 0,
}); });
while (i2c.get_read_available() == 0) { while (true) {
const abort_reason = regs.IC_TX_ABRT_SOURCE.read(); const abort_reason = regs.IC_TX_ABRT_SOURCE.read();
const abort = (regs.IC_CLR_TX_ABRT.read().CLR_TX_ABRT != 0); const abort = (regs.IC_CLR_TX_ABRT.read().CLR_TX_ABRT != 0);
if (abort) { if (abort) {
@ -403,6 +404,8 @@ pub const I2C = enum(u1) {
} }
try timeout_check.perform(); try timeout_check.perform();
if (i2c.get_read_available() != 0) break;
} }
byte.* = regs.IC_DATA_CMD.read().DAT; byte.* = regs.IC_DATA_CMD.read().DAT;

Loading…
Cancel
Save