Skip to content

Commit 9fd5320

Browse files
committed
[hdsc] HC32L110 i2c master read and write
1 parent d1543c8 commit 9fd5320

File tree

7 files changed

+463
-6
lines changed

7 files changed

+463
-6
lines changed

examples/hdsc/hc32l110/build.zig

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ pub fn build(b: *std.Build) void {
1212
const mz_dep = b.dependency("microzig", .{});
1313
const mb = MicroBuild.init(b, mz_dep) orelse return;
1414

15+
const rtt = b.dependency("rtt", .{});
16+
1517
const examples: []const Example = &.{
1618
.{ .name = "blinky", .file = "src/blinky.zig" },
1719
.{ .name = "crc16", .file = "src/crc16.zig" },
20+
.{ .name = "i2c_ssd1306", .file = "src/i2c_ssd1306.zig" },
1821
};
1922

2023
for (examples) |example| {
@@ -24,10 +27,11 @@ pub fn build(b: *std.Build) void {
2427

2528
const firmware = mb.add_firmware(.{
2629
.name = example.name,
27-
.target = mb.ports.hc32l110.chips.hc32l110x4,
30+
.target = mb.ports.hc32l110.chips.hc32l110x6,
2831
.optimize = optimize,
2932
.root_source_file = b.path(example.file),
3033
});
34+
firmware.add_app_import("rtt", rtt.module("rtt"), .{});
3135

3236
mb.install_firmware(firmware, .{});
3337
mb.install_firmware(firmware, .{ .format = .elf });

examples/hdsc/hc32l110/build.zig.zon

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
.version = "0.0.0",
55
.dependencies = .{
66
.microzig = .{ .path = "../../.." },
7+
.rtt = .{
8+
.url = "git+https://github.com/haydenridd/zig-rtt#b21fa1b54176e9aa5d17aefe4a7c4e0d9a89a09e",
9+
.hash = "rtt-0.0.0-s7auv1V5AAAtPzKYj-8Kbj7dD1JPkDJBsVxrKGfnIwqj",
10+
},
711
},
812
.paths = .{
913
"README.md",
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
const std = @import("std");
2+
const microzig = @import("microzig");
3+
4+
const hal = microzig.hal;
5+
const time = microzig.time;
6+
const i2c = hal.i2c;
7+
const gpio = hal.gpio;
8+
const clocks = hal.clocks;
9+
const peripherals = microzig.chip.peripherals;
10+
11+
const drivers = microzig.drivers;
12+
const display = drivers.display;
13+
const ssd1306 = display.ssd1306;
14+
15+
const i2c0 = i2c.instance.num(0);
16+
17+
const sda_pin = gpio.num(0, 1);
18+
const scl_pin = gpio.num(0, 2);
19+
20+
var framebuffer: drivers.display.ssd1306.Framebuffer = .init(.black);
21+
22+
pub fn main() !void {
23+
clocks.gate.enable(.Gpio);
24+
clocks.gate.enable(.I2c);
25+
26+
inline for (&.{ scl_pin, sda_pin }) |pin| {
27+
pin.set_direction(.out);
28+
pin.set_pull(.disabled);
29+
pin.set_open_drain(.enabled);
30+
pin.set_drive_strength(.normal);
31+
pin.set_analog(.disabled);
32+
}
33+
// TODO:
34+
sda_pin.set_function(2);
35+
scl_pin.set_function(2);
36+
37+
try i2c0.apply(.{ .baud = 32 });
38+
i2c0.enable();
39+
40+
const i2c_device = i2c0.device(.new(0x3c));
41+
const disp = ssd1306.init(.i2c, i2c_device, null) catch |err|
42+
switch (err) {
43+
error.Timeout => while (true) {},
44+
else => return err,
45+
};
46+
47+
var color: display.colors.BlackWhite = .white;
48+
49+
while (true) {
50+
framebuffer.clear(color);
51+
color = if (color == .black) .white else .black;
52+
53+
try disp.write_full_display(framebuffer.bit_stream());
54+
hal.time.sleep_ms(100);
55+
}
56+
}

port/hdsc/hc32l110/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ HAL and register definitions for the HC32L110 family of microcontrollers
99
- [x] crc
1010
- [ ] flash
1111
- [x] gpio
12-
- [ ] i2c
13-
- [ ] master
12+
- [-] i2c
13+
- [x] master
1414
- [ ] slave
1515
- [ ] irq
1616
- [ ] lpm - Low Power Management

port/hdsc/hc32l110/src/hal.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const chip = microzig.chip;
55

66
pub const time = @import("hal/time.zig");
77
pub const gpio = @import("hal/gpio.zig");
8-
pub const clock = @import("hal/clocks.zig");
8+
pub const clocks = @import("hal/clocks.zig");
99
pub const crc16 = @import("hal/crc16.zig");
1010
pub const spi = @import("hal/spi.zig");
1111
pub const uart = @import("hal/uart.zig");
@@ -14,8 +14,8 @@ pub const drivers = @import("hal/drivers.zig");
1414

1515
pub inline fn init() void {
1616
const CLOCK = chip.peripherals.CLOCK;
17-
clock.set_rch_frequency(.@"4MHz");
18-
clock.enable(.InternalHighSpeed, true);
17+
clocks.set_rch_frequency(.@"24MHz");
18+
clocks.enable(.InternalHighSpeed, true);
1919
// TODO: hide pins on 20-pin mcu
2020

2121
// TODO: move this to seprate function
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
const std = @import("std");
2+
const microzig = @import("microzig");
3+
const hal = @import("../hal.zig");
4+
5+
const drivers = microzig.drivers.base;
6+
const time = microzig.drivers.time;
7+
8+
const Datagram_Device = drivers.Datagram_Device;
9+
10+
///
11+
/// A datagram device attached to an I²C bus.
12+
///
13+
pub const I2C_Device = struct {
14+
pub const ConnectError = Datagram_Device.ConnectError;
15+
pub const WriteError = Datagram_Device.WriteError;
16+
pub const ReadError = Datagram_Device.ReadError;
17+
18+
/// Selects I²C bus should be used.
19+
bus: hal.i2c.I2C,
20+
21+
/// The address of our I²C device.
22+
address: hal.i2c.Address,
23+
24+
pub fn init(bus: hal.i2c.I2C, address: hal.i2c.Address) I2C_Device {
25+
return .{
26+
.bus = bus,
27+
.address = address,
28+
};
29+
}
30+
31+
pub fn datagram_device(dev: *I2C_Device) Datagram_Device {
32+
return .{
33+
.ptr = dev,
34+
.vtable = &vtable,
35+
};
36+
}
37+
38+
pub fn connect(dev: I2C_Device) ConnectError!void {
39+
_ = dev;
40+
}
41+
42+
pub fn disconnect(dev: I2C_Device) void {
43+
_ = dev;
44+
}
45+
46+
pub fn write(dev: I2C_Device, datagram: []const u8) !void {
47+
try dev.bus.write_blocking(dev.address, datagram, null);
48+
}
49+
50+
pub fn writev(dev: I2C_Device, datagrams: []const []const u8) !void {
51+
try dev.bus.writev_blocking(dev.address, datagrams, null);
52+
}
53+
54+
pub fn read(dev: I2C_Device, datagram: []u8) !usize {
55+
try dev.bus.read_blocking(dev.address, datagram, null);
56+
return datagram.len;
57+
}
58+
59+
pub fn readv(dev: I2C_Device, datagrams: []const []u8) !usize {
60+
try dev.bus.readv_blocking(dev.address, datagrams, null);
61+
return microzig.utilities.Slice_Vector([]u8).init(datagrams).size();
62+
}
63+
64+
const vtable = Datagram_Device.VTable{
65+
.connect_fn = null,
66+
.disconnect_fn = null,
67+
.writev_fn = writev_fn,
68+
.readv_fn = readv_fn,
69+
};
70+
71+
fn writev_fn(dd: *anyopaque, chunks: []const []const u8) WriteError!void {
72+
const dev: *I2C_Device = @ptrCast(@alignCast(dd));
73+
return dev.writev(chunks) catch |err| switch (err) {
74+
error.DeviceNotPresent,
75+
error.NoAcknowledge,
76+
error.TargetAddressReserved,
77+
=> return error.Unsupported,
78+
79+
error.UnknownAbort,
80+
error.TxFifoFlushed,
81+
=> return error.IoError,
82+
83+
error.Timeout => return error.Timeout,
84+
error.NoData => {},
85+
};
86+
}
87+
88+
fn readv_fn(dd: *anyopaque, chunks: []const []u8) ReadError!usize {
89+
const dev: *I2C_Device = @ptrCast(@alignCast(dd));
90+
return dev.readv(chunks) catch |err| switch (err) {
91+
error.DeviceNotPresent,
92+
error.NoAcknowledge,
93+
error.TargetAddressReserved,
94+
=> return error.Unsupported,
95+
96+
error.UnknownAbort,
97+
error.TxFifoFlushed,
98+
=> return error.IoError,
99+
100+
error.Timeout => return error.Timeout,
101+
error.NoData => return 0,
102+
};
103+
}
104+
};

0 commit comments

Comments
 (0)