@@ -111,9 +111,9 @@ const OperationType = enum(u1) {
111111};
112112
113113pub 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;
124124const 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