Skip to content

Commit dea3bc4

Browse files
committed
esp: make I2C a struct to store configuration
This is done because if we have an error we have to reset the peripheral and reconfigure it.
1 parent 8737550 commit dea3bc4

File tree

1 file changed

+17
-13
lines changed

1 file changed

+17
-13
lines changed

port/espressif/esp/src/hal/i2c.zig

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,9 @@ const OperationType = enum(u1) {
111111
};
112112

113113
pub const instance = struct {
114-
pub const I2C0: I2C = @as(I2C, @enumFromInt(0));
115114
pub fn num(n: u1) I2C {
116-
return @as(I2C, @enumFromInt(n));
115+
if (n != 0) @compileError("Only I2C0 is present");
116+
return .{ .regs = I2C0 };
117117
}
118118
};
119119

@@ -124,15 +124,20 @@ const I2C_FIFO_SIZE: usize = 32;
124124
const I2C_CHUNK_SIZE: usize = I2C_FIFO_SIZE - 1;
125125

126126
/// I2C Master peripheral driver
127-
pub const I2C = enum(u1) {
128-
_,
127+
pub const I2C = struct {
128+
regs: *volatile I2cRegs,
129+
frequency: u32 = 100_000,
129130

130-
inline fn get_regs(i2c: I2C) *volatile I2cRegs {
131-
_ = i2c;
132-
return I2C0;
131+
inline fn get_regs(self: I2C) *volatile I2cRegs {
132+
return self.regs;
133133
}
134134

135-
pub fn apply(self: I2C, frequency: u32) ConfigError!void {
135+
pub fn apply(self: *I2C, frequency: u32) ConfigError!void {
136+
self.frequency = frequency;
137+
try self.init();
138+
}
139+
140+
pub fn init(self: I2C) ConfigError!void {
136141
const regs = self.get_regs();
137142

138143
// Enable I2C peripheral clock and take it out of reset
@@ -163,7 +168,7 @@ pub const I2C = enum(u1) {
163168

164169
// Configure frequency
165170
// TODO: Take timeout as extra arg and handle saturation?
166-
try self.set_frequency(SOURCE_CLK_FREQ, frequency);
171+
try self.set_frequency(SOURCE_CLK_FREQ, self.frequency);
167172

168173
// Propagate configuration changes
169174
self.update_config();
@@ -297,18 +302,17 @@ pub const I2C = enum(u1) {
297302
});
298303
}
299304

300-
fn reset_fsm(self: I2C) void {
305+
fn reset_fsm(self: I2C) !void {
301306
// Even though C2 and C3 have a FSM reset bit, esp-idf does not
302307
// define SOC_I2C_SUPPORT_HW_FSM_RST for them, so include them in the fallback impl.
303308
microzig.hal.system.peripheral_reset(.{ .i2c_ext0 = true });
304309

305-
// FIXME: store the configuration and apply the correct frequency
306-
self.apply(400_000) catch {};
310+
try self.init();
307311
}
308312

309313
fn check_errors(self: I2C) !void {
310314
// Reset the peripheral in case of error
311-
errdefer self.reset_fsm();
315+
errdefer self.reset_fsm() catch {};
312316

313317
const interrupts = self.get_regs().INT_RAW.read();
314318
if (interrupts.TIME_OUT_INT_RAW == 1) {

0 commit comments

Comments
 (0)