Skip to content

Commit 83b65ba

Browse files
authored
I2C device manager (#2282)
* message on dev list change * dc detect * added sht3x sensor. * separete environment data from light * max17055 moved to i2c dev * sht fix, goterror detection fix * fix ext sensor app display for a lot of devices. * added bh1750 driver * autoscan on main view * added devlist mutex * better timing * fix h2 sw8 on poweron by usb
1 parent d4edb5f commit 83b65ba

35 files changed

+1456
-469
lines changed

firmware/application/CMakeLists.txt

+6-3
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ set(CSRC
125125
${CHIBIOS}/os/various/chprintf.c
126126
)
127127

128+
#look for all i2cdev_ files
129+
file(GLOB I2CDEV_SOURCES ${COMMON}/i2cdev_*.cpp)
130+
128131
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
129132
# setting.
130133
set(CPPSRC
@@ -176,8 +179,8 @@ set(CPPSRC
176179
${COMMON}/ui_language.cpp
177180
${COMMON}/utility.cpp
178181
${COMMON}/wm8731.cpp
179-
${COMMON}/ads1110.cpp
180-
${COMMON}/max17055.cpp
182+
${COMMON}/i2cdevmanager.cpp
183+
${I2CDEV_SOURCES}
181184
${COMMON}/battery.cpp
182185
${COMMON}/performance_counter.cpp
183186
${COMMON}/bmpfile.cpp
@@ -292,7 +295,7 @@ set(CPPSRC
292295
apps/ui_btle_rx.cpp
293296
# apps/ui_coasterp.cpp
294297
apps/ui_debug.cpp
295-
apps/ui_debug_battery.cpp
298+
apps/ui_debug_max17055.cpp
296299
apps/ui_dfu_menu.cpp
297300
apps/ui_encoders.cpp
298301
apps/ui_fileman.cpp

firmware/application/apps/ui_battinfo.cpp

+87-64
Original file line numberDiff line numberDiff line change
@@ -43,87 +43,86 @@ void BattinfoView::on_timer() {
4343
}
4444
}
4545

46-
void BattinfoView::update_result() {
47-
if (!battery::BatteryManagement::isDetected()) {
46+
void BattinfoView::update_results_ads1110(i2cdev::I2cDev_ADS1110* dev) {
47+
bool uichg = false;
48+
auto voltage = dev->readVoltage();
49+
auto percent = battery::BatteryManagement::calc_percent_voltage(voltage);
50+
if (percent <= 100)
51+
text_percent.set(to_string_dec_uint(percent) + " %");
52+
else
4853
text_percent.set("UNKNOWN");
54+
if (voltage > 1) {
55+
text_voltage.set(to_string_decimal(voltage / 1000.0, 3) + " V");
56+
} else {
4957
text_voltage.set("UNKNOWN");
50-
text_current.set("-");
51-
text_charge.set("-");
52-
text_cycles.set("-");
53-
text_ttef.set("-");
54-
text_method.set("-");
55-
text_warn.set("");
56-
return;
5758
}
59+
60+
// ui hide:
61+
if (!labels_opt.hidden()) uichg = true;
62+
labels_opt.hidden(true);
63+
text_current.hidden(true);
64+
text_charge.hidden(true);
65+
labels_opt.hidden(true);
66+
text_ttef.hidden(true);
67+
text_cycles.hidden(true);
68+
text_warn.set("");
69+
text_ttef.hidden(true);
70+
text_method.set("Voltage");
71+
button_mode.set_text("Voltage");
72+
if (uichg) set_dirty();
73+
BatteryStateMessage msg{1, percent, false, voltage};
74+
EventDispatcher::send_message(msg);
75+
}
76+
77+
void BattinfoView::update_results_max17055(i2cdev::I2cDev_MAX17055* dev) {
5878
bool uichg = false;
5979
uint8_t valid_mask = 0;
60-
battery::BatteryManagement::getBatteryInfo(valid_mask, percent, voltage, current);
80+
dev->getBatteryInfo(valid_mask, percent, voltage, current);
6181
// update text fields
62-
if (percent <= 100 && (valid_mask & battery::BatteryManagement::BATT_VALID_VOLTAGE) == battery::BatteryManagement::BATT_VALID_VOLTAGE)
82+
if (percent <= 100)
6383
text_percent.set(to_string_dec_uint(percent) + " %");
6484
else
6585
text_percent.set("UNKNOWN");
66-
if (voltage > 1 && (valid_mask & battery::BatteryManagement::BATT_VALID_VOLTAGE) == battery::BatteryManagement::BATT_VALID_VOLTAGE) {
86+
if (voltage > 1) {
6787
text_voltage.set(to_string_decimal(voltage / 1000.0, 3) + " V");
6888
} else {
6989
text_voltage.set("UNKNOWN");
7090
}
71-
if ((valid_mask & battery::BatteryManagement::BATT_VALID_CURRENT) == battery::BatteryManagement::BATT_VALID_CURRENT) {
72-
if (labels_opt.hidden()) uichg = true;
73-
labels_opt.hidden(false);
74-
text_current.hidden(false);
75-
text_charge.hidden(false);
76-
text_current.set(to_string_dec_int(current) + " mA");
77-
text_charge.set(current >= 0 ? "Charging" : "Discharging");
78-
labels_opt.hidden(false);
79-
80-
text_ttef.hidden(false);
81-
} else {
82-
if (!labels_opt.hidden()) uichg = true;
83-
labels_opt.hidden(true);
84-
text_current.hidden(true);
85-
text_charge.hidden(true);
86-
text_cycles.hidden(true);
87-
text_ttef.hidden(true);
91+
if (labels_opt.hidden()) uichg = true;
92+
labels_opt.hidden(false);
93+
text_current.hidden(false);
94+
text_charge.hidden(false);
95+
text_current.set(to_string_dec_int(current) + " mA");
96+
text_charge.set(current >= 0 ? "Charging" : "Discharging");
97+
labels_opt.hidden(false);
98+
text_ttef.hidden(false);
99+
// cycles
100+
text_cycles.hidden(false);
101+
uint16_t cycles = (uint16_t)dev->getValue("Cycles");
102+
if (cycles < 2)
103+
text_warn.set("SoC improves after 2 cycles");
104+
else
88105
text_warn.set("");
89-
}
90-
if ((valid_mask & battery::BatteryManagement::BATT_VALID_CYCLES) == battery::BatteryManagement::BATT_VALID_CYCLES) {
91-
text_cycles.hidden(false);
92-
uint16_t cycles = battery::BatteryManagement::get_cycles();
93-
if (cycles < 2)
94-
text_warn.set("SoC improves after 2 cycles");
95-
else
96-
text_warn.set("");
97-
text_cycles.set(to_string_dec_uint(cycles));
106+
text_cycles.set(to_string_dec_uint(cycles));
107+
// ttef
108+
text_ttef.hidden(false);
109+
float ttef = 0;
110+
if (current <= 0) {
111+
ttef = dev->getValue("TTE");
98112
} else {
99-
text_cycles.hidden(true);
100-
text_warn.set("");
113+
ttef = dev->getValue("TTF");
101114
}
102-
if ((valid_mask & battery::BatteryManagement::BATT_VALID_TTEF) == battery::BatteryManagement::BATT_VALID_TTEF) {
103-
text_ttef.hidden(false);
104-
float ttef = 0;
105-
if (current <= 0) {
106-
ttef = battery::BatteryManagement::get_tte();
107-
} else {
108-
ttef = battery::BatteryManagement::get_ttf();
109-
}
110-
111-
// Convert ttef to hours and minutes
112-
uint8_t hours = static_cast<uint8_t>(ttef);
113-
uint8_t minutes = static_cast<uint8_t>((ttef - hours) * 60 + 0.5); // +0.5 for rounding
114-
115-
// Create the formatted string
116-
std::string formatted_time;
117-
if (hours > 0) {
118-
formatted_time += to_string_dec_uint(hours) + "h ";
119-
}
120-
formatted_time += to_string_dec_uint(minutes) + "m";
121-
122-
text_ttef.set(formatted_time);
123-
} else {
124-
text_ttef.hidden(true);
115+
// Convert ttef to hours and minutes
116+
uint8_t hours = static_cast<uint8_t>(ttef);
117+
uint8_t minutes = static_cast<uint8_t>((ttef - hours) * 60 + 0.5); // +0.5 for rounding
118+
// Create the formatted string
119+
std::string formatted_time;
120+
if (hours > 0) {
121+
formatted_time += to_string_dec_uint(hours) + "h ";
125122
}
126-
if ((valid_mask & battery::BatteryManagement::BATT_VALID_PERCENT) == battery::BatteryManagement::BATT_VALID_PERCENT) {
123+
formatted_time += to_string_dec_uint(minutes) + "m";
124+
text_ttef.set(formatted_time);
125+
if (!battery::BatteryManagement::calcOverride) {
127126
text_method.set("IC");
128127
button_mode.set_text("Volt");
129128
} else {
@@ -136,6 +135,30 @@ void BattinfoView::update_result() {
136135
EventDispatcher::send_message(msg);
137136
}
138137

138+
void BattinfoView::update_result() {
139+
auto dev = i2cdev::I2CDevManager::get_dev_by_model(I2CDEVMDL_MAX17055);
140+
if (dev) {
141+
update_results_max17055((i2cdev::I2cDev_MAX17055*)dev);
142+
return;
143+
}
144+
145+
dev = i2cdev::I2CDevManager::get_dev_by_model(I2CDEVMDL_ADS1110);
146+
if (dev) {
147+
update_results_ads1110((i2cdev::I2cDev_ADS1110*)dev);
148+
return;
149+
}
150+
151+
// no dev found
152+
text_percent.set("UNKNOWN");
153+
text_voltage.set("UNKNOWN");
154+
text_current.set("-");
155+
text_charge.set("-");
156+
text_cycles.set("-");
157+
text_ttef.set("-");
158+
text_method.set("-");
159+
text_warn.set("");
160+
}
161+
139162
BattinfoView::BattinfoView(NavigationView& nav)
140163
: nav_{nav} {
141164
add_children({&labels,

firmware/application/apps/ui_battinfo.hpp

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
#include "ui_widget.hpp"
2828
#include "ui_navigation.hpp"
2929
#include "string_format.hpp"
30+
#include "i2cdevmanager.hpp"
31+
#include "i2cdev_max17055.hpp"
32+
#include "i2cdev_ads1110.hpp"
3033

3134
namespace ui {
3235
class BattinfoView : public View {
@@ -43,6 +46,8 @@ class BattinfoView : public View {
4346

4447
private:
4548
void update_result();
49+
void update_results_max17055(i2cdev::I2cDev_MAX17055* dev);
50+
void update_results_ads1110(i2cdev::I2cDev_ADS1110* dev);
4651
void on_timer();
4752
NavigationView& nav_;
4853
uint16_t timer_period = 60;

firmware/application/apps/ui_debug.cpp

+12-8
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
#include "ui_font_fixed_8x16.hpp"
3737
#include "ui_painter.hpp"
3838
#include "ui_external_items_menu_loader.hpp"
39-
#include "ui_debug_battery.hpp"
39+
#include "ui_debug_max17055.hpp"
4040

4141
#include "portapack.hpp"
4242
#include "portapack_persistent_memory.hpp"
@@ -226,8 +226,10 @@ uint32_t RegistersWidget::reg_read(const uint32_t register_number) {
226226
return radio::debug::second_if::register_read(register_number);
227227
case CT_SI5351:
228228
return portapack::clock_generator.read_register(register_number);
229-
case CT_BATTERY:
230-
return battery::BatteryManagement::read_register(register_number);
229+
case CT_MAX17055: {
230+
i2cdev::I2cDev_MAX17055* dev = (i2cdev::I2cDev_MAX17055*)i2cdev::I2CDevManager::get_dev_by_model(I2C_DEVMDL::I2CDEVMDL_MAX17055);
231+
return dev->read_register(register_number);
232+
}
231233
case CT_AUDIO:
232234
return audio::debug::reg_read(register_number);
233235
}
@@ -249,9 +251,11 @@ void RegistersWidget::reg_write(const uint32_t register_number, const uint32_t v
249251
case CT_SI5351:
250252
portapack::clock_generator.write_register(register_number, value);
251253
break;
252-
case CT_BATTERY:
253-
battery::BatteryManagement::write_register(register_number, value);
254+
case CT_MAX17055: {
255+
i2cdev::I2cDev_MAX17055* dev = (i2cdev::I2cDev_MAX17055*)i2cdev::I2CDevManager::get_dev_by_model(I2C_DEVMDL::I2CDEVMDL_MAX17055);
256+
dev->write_register(register_number, value);
254257
break;
258+
}
255259
case CT_AUDIO:
256260
audio::debug::reg_write(register_number, value);
257261
break;
@@ -465,9 +469,9 @@ void DebugPeripheralsMenuView::on_populate() {
465469
{si5351x, Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_peripherals_details, [this, si5351x]() { nav_.push<RegistersView>(si5351x, RegistersWidgetConfig{CT_SI5351, 188, 96, 8}); }},
466470
{audio::debug::codec_name(), Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_peripherals_details, [this]() { nav_.push<RegistersView>(audio::debug::codec_name(), RegistersWidgetConfig{CT_AUDIO, audio::debug::reg_count(), audio::debug::reg_count(), audio::debug::reg_bits()}); }},
467471
});
468-
if (battery::BatteryManagement::detectedModule() == battery::BatteryManagement::BatteryModules::BATT_MAX17055) {
472+
if (i2cdev::I2CDevManager::get_dev_by_model(I2C_DEVMDL::I2CDEVMDL_MAX17055)) {
469473
add_item(
470-
{"MAX17055", Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_peripherals_details, [this]() { nav_.push<RegistersView>("MAX17055", RegistersWidgetConfig{CT_BATTERY, 256, 16, 16}); }});
474+
{"MAX17055", Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_peripherals_details, [this]() { nav_.push<RegistersView>("MAX17055", RegistersWidgetConfig{CT_MAX17055, 256, 16, 16}); }});
471475
}
472476
set_max_rows(2); // allow wider buttons
473477
}
@@ -512,7 +516,7 @@ void DebugMenuView::on_populate() {
512516
{"Reboot", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_setup, [this]() { nav_.push<DebugReboot>(); }},
513517
});
514518

515-
if (battery::BatteryManagement::detectedModule() == battery::BatteryManagement::BatteryModules::BATT_MAX17055) {
519+
if (i2cdev::I2CDevManager::get_dev_by_model(I2C_DEVMDL::I2CDEVMDL_MAX17055)) {
516520
add_item(
517521
{"Battery", ui::Theme::getInstance()->fg_darkcyan->foreground, &bitmap_icon_batt_icon, [this]() { nav_.push<BatteryCapacityView>(); }});
518522
}

firmware/application/apps/ui_debug.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ typedef enum {
139139
CT_MAX283X,
140140
CT_SI5351,
141141
CT_AUDIO,
142-
CT_BATTERY,
142+
CT_MAX17055,
143143
} chip_type_t;
144144

145145
struct RegistersWidgetConfig {

firmware/application/apps/ui_debug_battery.cpp firmware/application/apps/ui_debug_max17055.cpp

+15-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
#include "ui_debug_battery.hpp"
1+
#include "ui_debug_max17055.hpp"
22
#include "string_format.hpp"
33

44
namespace ui {
55

66
BatteryCapacityView::RegisterEntry BatteryCapacityView::get_entry(size_t index) {
7-
if (index < battery::max17055::MAX17055::entries_count) {
8-
return battery::max17055::MAX17055::entries[index];
7+
if (index < i2cdev::I2cDev_MAX17055::entries_count) {
8+
return i2cdev::I2cDev_MAX17055::entries[index];
99
}
1010
return {"", 0, "", 0, false, "", false, 0, false, false, false, 0, false};
1111
}
@@ -27,6 +27,12 @@ BatteryCapacityView::BatteryCapacityView(NavigationView& nav) {
2727

2828
button_done.on_select = [&nav](Button&) { nav.pop(); };
2929

30+
auto dev = (i2cdev::I2cDev_MAX17055*)i2cdev::I2CDevManager::get_dev_by_model(I2C_DEVMDL::I2CDEVMDL_MAX17055);
31+
if (!dev) { // dev not found
32+
nav.pop();
33+
return;
34+
}
35+
3036
populate_page(0);
3137
update_page_text();
3238
}
@@ -37,7 +43,7 @@ void BatteryCapacityView::focus() {
3743

3844
bool BatteryCapacityView::on_encoder(const EncoderEvent delta) {
3945
int32_t new_page = current_page + delta;
40-
if (new_page >= 0 && new_page < ((int32_t)battery::max17055::MAX17055::entries_count + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE) {
46+
if (new_page >= 0 && new_page < ((int32_t)i2cdev::I2cDev_MAX17055::entries_count + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE) {
4147
current_page = new_page;
4248
populate_page(current_page * ENTRIES_PER_PAGE);
4349
update_page_text();
@@ -46,11 +52,12 @@ bool BatteryCapacityView::on_encoder(const EncoderEvent delta) {
4652
}
4753

4854
void BatteryCapacityView::update_values() {
55+
i2cdev::I2cDev_MAX17055* dev = (i2cdev::I2cDev_MAX17055*)i2cdev::I2CDevManager::get_dev_by_model(I2C_DEVMDL::I2CDEVMDL_MAX17055);
4956
for (size_t i = 0; i < ENTRIES_PER_PAGE; ++i) {
5057
size_t entry_index = current_page * ENTRIES_PER_PAGE + i;
51-
if (entry_index < battery::max17055::MAX17055::entries_count) {
58+
if (entry_index < i2cdev::I2cDev_MAX17055::entries_count) {
5259
const auto entry = get_entry(entry_index);
53-
uint16_t raw_value = battery::BatteryManagement::read_register(entry.address);
60+
uint16_t raw_value = dev->read_register(entry.address);
5461

5562
hex_texts[i].set("0x" + to_string_hex(raw_value, 4));
5663

@@ -78,7 +85,7 @@ void BatteryCapacityView::update_values() {
7885
void BatteryCapacityView::populate_page(int start_index) {
7986
for (size_t i = 0; i < ENTRIES_PER_PAGE; ++i) {
8087
size_t entry_index = start_index + i;
81-
if (entry_index < battery::max17055::MAX17055::entries_count) {
88+
if (entry_index < i2cdev::I2cDev_MAX17055::entries_count) {
8289
const auto entry = get_entry(entry_index);
8390
name_texts[i].set(entry.name);
8491
addr_texts[i].set("0x" + to_string_hex(entry.address, 2));
@@ -97,7 +104,7 @@ void BatteryCapacityView::populate_page(int start_index) {
97104
}
98105

99106
void BatteryCapacityView::update_page_text() {
100-
int total_pages = (battery::max17055::MAX17055::entries_count + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE;
107+
int total_pages = (i2cdev::I2cDev_MAX17055::entries_count + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE;
101108
page_text.set("Page " + to_string_dec_uint(current_page + 1) + "/" + to_string_dec_uint(total_pages));
102109
}
103110

firmware/application/apps/ui_debug_battery.hpp firmware/application/apps/ui_debug_max17055.hpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,20 @@
55
#include "ui_widget.hpp"
66
#include "ui_navigation.hpp"
77
#include "battery.hpp"
8-
#include "max17055.hpp"
8+
#include "i2cdevmanager.hpp"
9+
#include "i2cdev_max17055.hpp"
910

1011
namespace ui {
1112

1213
class BatteryCapacityView : public View {
1314
public:
1415
BatteryCapacityView(NavigationView& nav);
1516
void focus() override;
16-
std::string title() const override { return "Battery Registers"; }
17+
std::string title() const override { return "MAX17055 Registers"; }
1718

1819
bool on_encoder(const EncoderEvent delta) override;
1920

20-
using RegisterEntry = battery::max17055::RegisterEntry;
21+
using RegisterEntry = i2cdev::I2cDev_MAX17055::RegisterEntry;
2122

2223
private:
2324
static RegisterEntry get_entry(size_t index);

0 commit comments

Comments
 (0)