|
7 | 7 | //! |
8 | 8 | const std = @import("std"); |
9 | 9 | const mdf_base = @import("../framework.zig").base; |
| 10 | +const InterfaceError = mdf_base.I2C_Device.InterfaceError; |
10 | 11 |
|
11 | 12 | const assert = std.debug.assert; |
12 | 13 |
|
@@ -67,7 +68,7 @@ pub const HTS221 = struct { |
67 | 68 | T_OUT = 0x2A, |
68 | 69 | STATUS_REG = 0x27, |
69 | 70 |
|
70 | | - // Callibration register |
| 71 | + // Calibration register |
71 | 72 | T0_DEGC_X8 = 0x32, |
72 | 73 | T1_DEGC_X8 = 0x33, |
73 | 74 | T01_DEGC_MSB_x8 = 0x35, |
@@ -131,83 +132,96 @@ pub const HTS221 = struct { |
131 | 132 | reserved0: u2, |
132 | 133 | }); |
133 | 134 |
|
| 135 | + const T01_DEGC_MSB = Reg(packed struct(u8) { |
| 136 | + T0MSB: i2, |
| 137 | + T1MSB: i2, |
| 138 | + reserved0: u4, |
| 139 | + }); |
| 140 | + |
134 | 141 | dev: *mdf_base.I2C_Device, |
135 | 142 |
|
136 | | - // Needs to be initialize with calibration value. |
| 143 | + // Needs to be initialized with calibration value. |
137 | 144 | t_slop: f32 = 0.0, |
138 | 145 | t_b0: f32 = 0.0, |
139 | 146 |
|
140 | 147 | // internal read buffer |
141 | | - read_buffer: [2]u8 = [2]u8{ 0, 0 }, |
| 148 | + read_buffer: [2]u8 = .{ 0, 0 }, |
| 149 | + |
| 150 | + fn read_one_byte(self: *@This(), register: RegsAddr) InterfaceError!u8 { |
| 151 | + try self.dev.write_then_read(address, &[_]u8{register.v()}, self.read_buffer[0..1]); |
| 152 | + return self.read_buffer[0]; |
| 153 | + } |
| 154 | + |
| 155 | + // LSB is always read first. |
| 156 | + fn read_two_byte(self: *@This(), register: RegsAddr) InterfaceError!u16 { |
| 157 | + try self.dev.write_then_read(address, &[_]u8{register.auto_v()}, &self.read_buffer); |
| 158 | + return @as(u16, @intCast(self.read_buffer[0])) | (@as(u16, @intCast(self.read_buffer[1])) << 8); |
| 159 | + } |
142 | 160 |
|
143 | | - fn init_temp_callibration(self: *@This()) !void { |
| 161 | + fn init_temp_calibration(self: *@This()) InterfaceError!void { |
144 | 162 | // Get the MSB of degC calibration value. |
145 | | - try self.dev.write_then_read(address, &[_]u8{RegsAddr.T01_DEGC_MSB_x8.v()}, self.read_buffer[0..1]); |
146 | | - const t0msb = @as(i10, @intCast(@as(i2, @bitCast(@as(u2, @truncate(self.read_buffer[0])))))) << 8; |
147 | | - const t1msb = @as(i10, @intCast(@as(i2, @bitCast(@as(u2, @truncate(self.read_buffer[0] >> 2)))))) << 8; |
| 163 | + const t01_msb_reg = T01_DEGC_MSB.from(try self.read_one_byte(RegsAddr.T01_DEGC_MSB_x8)); |
| 164 | + const t0msb = @as(i10, @intCast(t01_msb_reg.read().T0MSB)) << 8; |
| 165 | + const t1msb = @as(i10, @intCast(t01_msb_reg.read().T1MSB)) << 8; |
148 | 166 |
|
149 | | - try self.dev.write_then_read(address, &[_]u8{RegsAddr.T0_DEGC_X8.v()}, self.read_buffer[0..1]); |
150 | | - const t0_deg = @as(f32, @floatFromInt(@as(i10, @bitCast(@as(u10, @intCast(self.read_buffer[0])))) | t0msb)) / 8.0; |
| 167 | + const t0_degc_lsb = @as(u10, @intCast(try self.read_one_byte(RegsAddr.T0_DEGC_X8))); |
| 168 | + const t0_deg = @as(f32, @floatFromInt(@as(i10, @bitCast(t0_degc_lsb)) | t0msb)) / 8.0; |
151 | 169 |
|
152 | | - try self.dev.write_then_read(address, &[_]u8{RegsAddr.T1_DEGC_X8.v()}, self.read_buffer[0..1]); |
153 | | - const t1_deg = @as(f32, @floatFromInt(@as(i10, @bitCast(@as(u10, @intCast(self.read_buffer[0])))) | t1msb)) / 8.0; |
| 170 | + const t1_degc_lsb = @as(u10, @intCast(try self.read_one_byte(RegsAddr.T1_DEGC_X8))); |
| 171 | + const t1_deg = @as(f32, @floatFromInt(@as(i10, @bitCast(t1_degc_lsb)) | t1msb)) / 8.0; |
154 | 172 |
|
155 | | - try self.dev.write_then_read(address, &[_]u8{RegsAddr.T0_OUT.auto_v()}, &self.read_buffer); |
156 | | - const T0 = @as(f32, @floatFromInt(@as(i16, @intCast(self.read_buffer[0])) | (@as(i16, @intCast(self.read_buffer[1])) << 8))); |
| 173 | + const t0_raw = try self.read_two_byte(RegsAddr.T0_OUT); |
| 174 | + const T0 = @as(f32, @floatFromInt(@as(i16, @bitCast(t0_raw)))); |
157 | 175 |
|
158 | | - try self.dev.write_then_read(address, &[_]u8{RegsAddr.T1_OUT.auto_v()}, &self.read_buffer); |
159 | | - const T1 = @as(f32, @floatFromInt(@as(i16, @intCast(self.read_buffer[0])) | (@as(i16, @intCast(self.read_buffer[1])) << 8))); |
| 176 | + const t1_raw = try self.read_two_byte(RegsAddr.T1_OUT); |
| 177 | + const T1 = @as(f32, @floatFromInt(@as(i16, @bitCast(t1_raw)))); |
160 | 178 |
|
161 | 179 | self.t_slop = ((t1_deg - t0_deg) / (T1 - T0)); |
162 | 180 | self.t_b0 = t0_deg - T0 * self.t_slop; |
163 | 181 | } |
164 | 182 |
|
165 | | - fn setup_output_rate(self: *@This(), rate: ODR) !void { |
166 | | - try self.dev.write_then_read(address, &[_]u8{RegsAddr.CTRL_REG1.v()}, self.read_buffer[0..1]); |
167 | | - var reg = CTRL_REG1.from(self.read_buffer[0]); |
| 183 | + fn setup_output_rate(self: *@This(), rate: ODR) InterfaceError!void { |
| 184 | + var reg = CTRL_REG1.from(try self.read_one_byte(RegsAddr.CTRL_REG1)); |
168 | 185 | reg.modify(.{ .ODR = rate }); |
169 | 186 | try self.dev.write(address, &[_]u8{ RegsAddr.CTRL_REG1.v(), reg.raw }); |
170 | 187 | } |
171 | 188 |
|
172 | | - fn setup_average(self: *@This(), avgt: AVGT, avgh: AVGH) !void { |
173 | | - try self.dev.write_then_read(address, &[_]u8{RegsAddr.AV_CONF.v()}, self.read_buffer[0..1]); |
174 | | - var reg = AV_CONF.from(self.read_buffer[0]); |
| 189 | + fn setup_average(self: *@This(), avgt: AVGT, avgh: AVGH) InterfaceError!void { |
| 190 | + var reg = AV_CONF.from(try self.read_one_byte(RegsAddr.AV_CONF)); |
175 | 191 | reg.modify(.{ |
176 | 192 | .AVGH = avgh, |
177 | 193 | .AVGT = avgt, |
178 | 194 | }); |
179 | 195 | try self.dev.write(address, &[_]u8{ RegsAddr.AV_CONF.v(), reg.raw }); |
180 | 196 | } |
181 | 197 |
|
182 | | - pub fn turn_on(self: *@This()) !void { |
183 | | - try self.dev.write_then_read(address, &[_]u8{RegsAddr.CTRL_REG1.v()}, self.read_buffer[0..1]); |
184 | | - var reg = CTRL_REG1.from(self.read_buffer[0]); |
| 198 | + pub fn turn_on(self: *@This()) InterfaceError!void { |
| 199 | + var reg = CTRL_REG1.from(try self.read_one_byte(RegsAddr.CTRL_REG1)); |
185 | 200 | reg.modify(.{ .PD = 1 }); |
186 | 201 | try self.dev.write(address, &[_]u8{ RegsAddr.CTRL_REG1.v(), reg.raw }); |
187 | 202 | } |
188 | 203 |
|
189 | | - pub fn turn_off(self: *@This()) !void { |
190 | | - try self.dev.write_then_read(address, &[_]u8{RegsAddr.CTRL_REG1.v()}, self.read_buffer[0..1]); |
191 | | - var reg = CTRL_REG1.from(self.read_buffer[0]); |
| 204 | + pub fn turn_off(self: *@This()) InterfaceError!void { |
| 205 | + var reg = CTRL_REG1.from(try self.read_one_byte(RegsAddr.CTRL_REG1)); |
192 | 206 | reg.modify(.{ .PD = 0 }); |
193 | 207 | try self.dev.write(address, &[_]u8{ RegsAddr.CTRL_REG1.v(), reg.raw }); |
194 | 208 | } |
195 | 209 |
|
196 | | - pub fn configure(self: *@This(), config: Config) !void { |
197 | | - try self.init_temp_callibration(); |
| 210 | + pub fn configure(self: *@This(), config: Config) InterfaceError!void { |
| 211 | + try self.init_temp_calibration(); |
198 | 212 | try self.setup_output_rate(config.outputDataRate); |
199 | 213 | try self.setup_average(config.temperatureAverageSample, config.humidityAverageSample); |
200 | 214 | } |
201 | 215 |
|
202 | | - pub fn temperature_ready(self: *@This()) !bool { |
203 | | - try self.dev.write_then_read(address, &[_]u8{RegsAddr.STATUS_REG.v()}, self.read_buffer[0..1]); |
204 | | - const status = STATUS_REG.from(self.read_buffer[0]); |
| 216 | + pub fn temperature_ready(self: *@This()) InterfaceError!bool { |
| 217 | + const raw_status = try self.read_one_byte(RegsAddr.STATUS_REG); |
| 218 | + const status = STATUS_REG.from(raw_status); |
205 | 219 | return status.read().T_DA == 1; |
206 | 220 | } |
207 | 221 |
|
208 | | - pub fn read_temperature(self: *@This()) !f32 { |
209 | | - try self.dev.write_then_read(address, &[_]u8{RegsAddr.T_OUT.auto_v()}, &self.read_buffer); |
210 | | - const inter = @as(f32, @floatFromInt(@as(i16, @intCast(self.read_buffer[0])) | (@as(i16, @intCast(self.read_buffer[1])) << 8))); |
| 222 | + pub fn read_temperature(self: *@This()) InterfaceError!f32 { |
| 223 | + const raw_t = try self.read_two_byte(RegsAddr.T_OUT); |
| 224 | + const inter = @as(f32, @floatFromInt(@as(i16, @bitCast(raw_t)))); |
211 | 225 | return self.t_b0 + inter * self.t_slop; |
212 | 226 | } |
213 | 227 |
|
|
0 commit comments