Skip to content

Commit 48cd6dd

Browse files
committed
Refactor device drivers to use I2c base class
Replace ad-hoc i2c usage across multiple sensor drivers with a unified I2c base class: add i2c.h includes, inherit classes from I2c, and migrate initialization and read/write logic into headers. Consolidated register definitions into reg namespaces, standardized constant names (k-prefix), added device I2C addresses and read delays, and moved many small .cpp implementations inline (deleting corresponding .cpp files). Adjusted SC16IS740 to use the new I2c API and updated calls to ReadRegister/WriteRegister with the new signatures. Minor housekeeping: updated copyright years in affected headers. These changes centralize I2C handling, remove duplicated setup code, and simplify driver initialization and data access.
1 parent a214919 commit 48cd6dd

18 files changed

Lines changed: 464 additions & 554 deletions

File tree

lib-device/include/bh1750.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,46 @@
2828

2929
#include <cstdint>
3030

31+
#include "i2c.h"
32+
3133
namespace sensor {
3234
namespace bh1750 {
35+
static constexpr uint8_t kI2CAddress = 0x23;
3336
inline constexpr char kDescription[] = "Ambient Light";
3437
inline constexpr auto kRangeMin = 0;
3538
inline constexpr auto kRangeMax = 65535;
39+
namespace reg {
40+
// static constexpr uint8_t POWER_DOWN = 0x00;
41+
static constexpr uint8_t kPowerOn = 0x01;
42+
// static constexpr uint8_t RESET = 0x07;
43+
static constexpr uint8_t kContinuousHighResMode = 0x10;
44+
// static constexpr uint8_t CONTINUOUS_HIGH_RES_MODE_2 = 0x11;
45+
// static constexpr uint8_t CONTINUOUS_LOW_RES_MODE = 0x13;
46+
// static constexpr uint8_t ONE_TIME_HIGH_RES_MODE = 0x20;
47+
// static constexpr uint8_t ONE_TIME_HIGH_RES_MODE_2 = 0x21;
48+
// static constexpr uint8_t ONE_TIME_LOW_RES_MODE = 0x23;
49+
} // namespace reg
3650
} // namespace bh1750
3751

38-
class BH1750 {
52+
class BH1750 : I2c {
3953
public:
40-
explicit BH1750(uint8_t address = 0);
54+
explicit BH1750(uint8_t address = 0) : I2c(address == 0 ? sensor::bh1750::kI2CAddress : address) {
55+
initialized_ = IsConnected();
56+
57+
if (initialized_) {
58+
Write(sensor::bh1750::reg::kPowerOn, true);
59+
Write(sensor::bh1750::reg::kContinuousHighResMode, false);
60+
}
61+
}
4162

4263
bool Initialize() { return initialized_; }
4364

44-
uint16_t Get();
65+
uint16_t Get() {
66+
const auto kLevel = static_cast<uint16_t>(static_cast<float>(Read16(true)) / 1.2f);
67+
return kLevel;
68+
}
4569

4670
private:
47-
uint8_t address_{0};
4871
bool initialized_{false};
4972
};
5073
} // namespace sensor

lib-device/include/htu21d.h

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@
2828

2929
#include <cstdint>
3030

31+
#include "i2c.h"
32+
3133
namespace sensor {
3234
namespace htu21d {
35+
inline constexpr uint8_t kI2CAddress = 0x40;
3336
namespace temperature {
3437
inline constexpr char kDescription[] = "Ambient Temperature";
3538
inline constexpr int16_t kRangeMin = -40;
@@ -40,25 +43,58 @@ inline constexpr char kDescription[] = "Relative Humidity";
4043
inline constexpr int16_t kRangeMin = 0;
4144
inline constexpr int16_t kRangeMax = 100;
4245
} // namespace humidity
46+
namespace reg {
47+
// static constexpr uint8_t TRIGGER_TEMP_MEASURE_HOLD = 0xE3;
48+
// static constexpr uint8_t TRIGGER_HUMD_MEASURE_HOLD = 0xE5;
49+
inline constexpr uint8_t kTriggerTempMeasureNohold = 0xF3;
50+
inline constexpr uint8_t kTriggerHumdMeasureNohold = 0xF5;
51+
// static constexpr uint8_t WRITE_USER_REG = 0xE6;
52+
// static constexpr uint8_t READ_USER_REG = 0xE7;
53+
// static constexpr uint8_t SOFT_RESET = 0xFE;
54+
} // namespace reg
4355
} // namespace htu21d
4456

45-
class HTU21D {
57+
class HTU21D: I2c {
4658
public:
47-
explicit HTU21D(uint8_t address = 0);
59+
explicit HTU21D(uint8_t address = 0) : I2c(address == 0 ? sensor::htu21d::kI2CAddress : address) {
60+
initialized_ = IsConnected();
61+
}
4862

49-
bool Initialize() { return initialized_; }
63+
float GetTemperature() {
64+
const auto kTemp = static_cast<float>(ReadRaw(sensor::htu21d::reg::kTriggerTempMeasureNohold)) / 65536.0f;
65+
return -46.85f + (175.72f * kTemp);
66+
}
5067

51-
float GetTemperature();
52-
float GetHumidity();
68+
float GetHumidity() {
69+
const auto kHumd = static_cast<float>(ReadRaw(sensor::htu21d::reg::kTriggerHumdMeasureNohold)) / 65536.0f;
70+
return -6.0f + (125.0f * kHumd);
71+
}
72+
73+
bool Initialize() { return initialized_; }
5374

5475
private:
55-
uint16_t ReadRaw(uint8_t cmd);
76+
uint16_t ReadRaw(uint8_t cmd) {
77+
Write(cmd, true);
78+
79+
char buf[3] = {0};
80+
81+
for (uint32_t i = 0; i < 8; ++i) {
82+
timing::DelayUs(10000);
83+
Read(buf, 3, false);
84+
85+
if ((buf[0] & 0x3) == 2) {
86+
break;
87+
}
88+
}
89+
90+
const auto kRawValue = static_cast<uint16_t>((buf[0] << 8) | buf[1]);
91+
92+
return kRawValue & 0xFFFC;
93+
}
5694

5795
private:
58-
uint8_t address_{0};
59-
bool initialized_{false};
96+
bool initialized_{false};
6097
};
61-
6298
} // namespace sensor
6399

64100
#endif // HTU21D_H_

lib-device/include/ina219.h

Lines changed: 123 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,35 @@
2828

2929
#include <cstdint>
3030

31+
#include "i2c.h"
32+
#include "firmware/debug/debug_debug.h"
33+
3134
namespace sensor {
3235
namespace ina219 {
33-
inline constexpr uint16_t RANGE_16V = 0x0000; ///< 0-16V Range
34-
inline constexpr uint16_t RANGE_32V = 0x2000; ///< 0-32V Range
36+
inline constexpr uint8_t kI2CAddress = 0x40;
37+
namespace reg {
38+
inline constexpr uint8_t kConfig = 0x00;
39+
// static constexpr uint8_t SHUNTVOLTAGE = 0x01;
40+
inline constexpr uint8_t kBusvoltage = 0x02;
41+
inline constexpr uint8_t kPower = 0x03;
42+
inline constexpr uint8_t kCurrent = 0x04;
43+
inline constexpr uint8_t kCalibration = 0x05;
44+
namespace value {
45+
inline constexpr auto kReadDelayUs = 800;
46+
} // namespace value
47+
} // namespace reg
48+
inline constexpr uint16_t kRange16V = 0x0000; ///< 0-16V Range
49+
inline constexpr uint16_t kRange32V = 0x2000; ///< 0-32V Range
3550

3651
inline constexpr uint16_t GAIN_40MV = 0x0000; ///< Gain 1, 40mV Range
3752
inline constexpr uint16_t GAIN_80MV = 0x0800; ///< Gain 2, 80mV Range
3853
inline constexpr uint16_t GAIN_160MV = 0x1000; ///< Gain 4, 160mV Range
3954
inline constexpr uint16_t GAIN_320MV = 0x1800; ///< Gain 8, 320mV Range
4055

41-
inline constexpr uint16_t BUS_RES_9BIT = 0x0080; ///< 9-bit bus res = 0..511
42-
inline constexpr uint16_t BUS_RES_10BIT = 0x0100; ///< 10-bit bus res = 0..1023
43-
inline constexpr uint16_t BUS_RES_11BIT = 0x0200; ///< 11-bit bus res = 0..2047
44-
inline constexpr uint16_t BUS_RES_12BIT = 0x0400; ///< 12-bit bus res = 0..4097
56+
inline constexpr uint16_t kBusRes9Bit = 0x0080; ///< 9-bit bus res = 0..511
57+
inline constexpr uint16_t kBusRes10Bit = 0x0100; ///< 10-bit bus res = 0..1023
58+
inline constexpr uint16_t kBusRes11Bit = 0x0200; ///< 11-bit bus res = 0..2047
59+
inline constexpr uint16_t kBusRes12Bit = 0x0400; ///< 12-bit bus res = 0..4097
4560

4661
inline constexpr uint16_t SHUNT_RES_9BIT_1S = 0x0000; ///< 1 x 9-bit shunt sample
4762
inline constexpr uint16_t SHUNT_RES_10BIT_1S = 0x0008; ///< 1 x 10-bit shunt sample
@@ -53,23 +68,23 @@ inline constexpr uint16_t SHUNT_RES_12BIT_8S = 0x0058; ///< 8 x 12-bit shunt s
5368
inline constexpr uint16_t SHUNT_RES_12BIT_16S = 0x0060; ///< 16 x 12-bit shunt samples averaged together
5469
inline constexpr uint16_t SHUNT_RES_12BIT_32S = 0x0068; ///< 32 x 12-bit shunt samples averaged together
5570
inline constexpr uint16_t SHUNT_RES_12BIT_64S = 0x0070; ///< 64 x 12-bit shunt samples averaged together
56-
inline constexpr uint16_t SHUNT_RES_12BIT_128S = 0x0078; ///< 128 x 12-bit shunt samples averaged together
71+
inline constexpr uint16_t kShuntRes12Bit128S = 0x0078; ///< 128 x 12-bit shunt samples averaged together
5772

58-
inline constexpr uint16_t MODE_POWER_DOWN = 0x0000;
59-
inline constexpr uint16_t MODE_SHUNT_TRIG = 0x0001;
60-
inline constexpr uint16_t MODE_BUS_TRIG = 0x0002;
61-
inline constexpr uint16_t MODE_SHUNT_BUS_TRIG = 0x0003;
62-
inline constexpr uint16_t MODE_ADC_OFF = 0x0004;
63-
inline constexpr uint16_t MODE_SHUNT_CONT = 0x0005;
64-
inline constexpr uint16_t MODE_BUS_CONT = 0x0006;
65-
inline constexpr uint16_t MODE_SHUNT_BUS_CONT = 0x0007;
73+
inline constexpr uint16_t kModePowerDown = 0x0000;
74+
inline constexpr uint16_t kModeShuntTrig = 0x0001;
75+
inline constexpr uint16_t kModeBusTrig = 0x0002;
76+
inline constexpr uint16_t kModeShuntBusTrig = 0x0003;
77+
inline constexpr uint16_t kModeAdcOff = 0x0004;
78+
inline constexpr uint16_t kModeShuntCont = 0x0005;
79+
inline constexpr uint16_t kModeBusCont = 0x0006;
80+
inline constexpr uint16_t kModeShuntBusCont = 0x0007;
6681

6782
struct Config {
68-
uint16_t range = RANGE_32V;
83+
uint16_t range = kRange32V;
6984
uint16_t gain = GAIN_320MV;
70-
uint16_t bus_res = BUS_RES_12BIT;
85+
uint16_t bus_res = kBusRes12Bit;
7186
uint16_t shunt_res = SHUNT_RES_12BIT_1S;
72-
uint16_t mode = MODE_SHUNT_BUS_CONT;
87+
uint16_t mode = kModeShuntBusCont;
7388
};
7489

7590
namespace current {
@@ -89,25 +104,102 @@ inline constexpr int16_t kRangeMax = 64; // W
89104
} // namespace power
90105
} // namespace ina219
91106

92-
class INA219 {
107+
class INA219 : I2c {
93108
public:
94-
explicit INA219(uint8_t address = 0);
95-
96-
void Configure(ina219::Config& config);
97-
void Calibrate(float r_shunt_value = 0.1f, float i_max_expected = 2.0f);
109+
explicit INA219(uint8_t address) : I2c(address == 0 ? sensor::ina219::kI2CAddress : address) {
110+
initialized_ = IsConnected();
111+
112+
if (initialized_) {
113+
sensor::ina219::Config config;
114+
Configure(config);
115+
Calibrate(0.1f, 2.0f);
116+
}
117+
}
118+
119+
void Configure(sensor::ina219::Config& config) {
120+
switch (config.range) {
121+
case sensor::ina219::kRange32V:
122+
info_.v_bus_max = 32.0f;
123+
break;
124+
case sensor::ina219::kRange16V:
125+
info_.v_bus_max = 16.0f;
126+
break;
127+
}
128+
129+
switch (config.gain) {
130+
case sensor::ina219::GAIN_320MV:
131+
info_.v_shunt_max = 0.32f;
132+
break;
133+
case sensor::ina219::GAIN_160MV:
134+
info_.v_shunt_max = 0.16f;
135+
break;
136+
case sensor::ina219::GAIN_80MV:
137+
info_.v_shunt_max = 0.08f;
138+
break;
139+
case sensor::ina219::GAIN_40MV:
140+
info_.v_shunt_max = 0.04f;
141+
break;
142+
}
143+
144+
const uint16_t kConfig = config.range | config.gain | config.bus_res | config.shunt_res | config.mode;
145+
146+
DEBUG_PRINTF("kConfig=%x", kConfig);
147+
148+
i2c::WriteReg(sensor::ina219::reg::kConfig, kConfig);
149+
}
150+
151+
void Calibrate(float r_shunt_value, float i_max_expected) {
152+
const float kMinimumLsb = i_max_expected / 32767;
153+
154+
info_.r_shunt = r_shunt_value;
155+
156+
info_.current_lsb = (static_cast<uint16_t>(kMinimumLsb * 100000000));
157+
info_.current_lsb /= 100000000;
158+
info_.current_lsb /= 0.0001f;
159+
info_.current_lsb = CeilingPos(info_.current_lsb);
160+
info_.current_lsb *= 0.0001f;
161+
162+
info_.power_lsb = info_.current_lsb * 20;
163+
164+
const auto kCalibrationValue = static_cast<uint16_t>((0.04096f / (info_.current_lsb * info_.r_shunt)));
165+
166+
DEBUG_PRINTF("kCalibrationValue=%x", kCalibrationValue);
167+
168+
i2c::WriteReg(sensor::ina219::reg::kCalibration, kCalibrationValue);
169+
}
170+
171+
float GetShuntCurrent() {
172+
const float kValue = ReadRegister16DelayUs(sensor::ina219::reg::kCurrent, sensor::ina219::reg::value::kReadDelayUs) * info_.current_lsb;
173+
return kValue;
174+
}
175+
176+
float GetBusVoltage() { return GetBusVoltageRaw() * 0.001f; }
177+
178+
float GetBusPower() {
179+
const float kValue = ReadRegister16DelayUs(sensor::ina219::reg::kPower, sensor::ina219::reg::value::kReadDelayUs) * info_.power_lsb;
180+
return kValue;
181+
}
182+
183+
bool Initialize() { return initialized_; }
98184

99-
bool Initialize() { return initialized_; }
185+
private:
186+
int16_t GetBusVoltageRaw() {
187+
auto voltage = ReadRegister16DelayUs(sensor::ina219::reg::kBusvoltage, sensor::ina219::reg::value::kReadDelayUs);
188+
voltage = static_cast<uint16_t>(voltage >> 3);
100189

101-
float GetShuntCurrent();
102-
float GetBusVoltage();
103-
float GetBusPower();
190+
return static_cast<int16_t>(voltage * 4);
191+
}
104192

105-
private:
106-
int16_t GetBusVoltageRaw();
193+
float CeilingPos(float f) {
194+
const auto kI = static_cast<int>(f);
195+
if (f == static_cast<float>(kI)) {
196+
return static_cast<float>(kI);
197+
}
198+
return static_cast<float>(kI + 1);
199+
}
107200

108201
private:
109-
uint8_t address_{0};
110-
bool initialized_{false};
202+
bool initialized_{false};
111203

112204
struct Info {
113205
float current_lsb;

lib-device/include/mcp3424.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
#include <cstdint>
3030

31+
#include "i2c.h"
32+
3133
namespace adc::mcp3424 {
3234
enum class Gain {
3335
kPgaX1, ///< Default
@@ -49,7 +51,7 @@ enum class Conversion {
4951
};
5052
} // namespace adc::mcp3424
5153

52-
class MCP3424 {
54+
class MCP3424 : I2c {
5355
public:
5456
explicit MCP3424(uint8_t address = 0);
5557

@@ -68,7 +70,6 @@ class MCP3424 {
6870
double GetVoltage(uint32_t channel);
6971

7072
private:
71-
uint8_t address_{0};
7273
bool is_connected_{false};
7374
uint8_t config_;
7475
double lsb_;

0 commit comments

Comments
 (0)