mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-09-14 02:29:29 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a2c4fefe34 | |||
| 121352b149 | |||
| 0ae7768f20 | |||
| 1a0555f9eb | |||
| 6752bf0279 | |||
| 6dc7e3dfc5 | |||
| c992780974 | |||
| 750d592288 | |||
| c77252cca2 |
@@ -1,6 +1,7 @@
|
||||
> [!WARNING]
|
||||
> __IF YOU'VE PAID FOR MAYHEM OR ANY PREPACKAGED PACKAGES, YOU'RE BEING SCAMMED.__
|
||||
> The only legitimate link leading to our repositories is the organization [portapack-mayhem](https://github.com/portapack-mayhem/mayhem-firmware).
|
||||
> __IF YOU'VE PAID FOR MAYHEM OR ANY PREPACKAGED VERSIONS, YOU'RE BEING SCAMMED.__
|
||||
>
|
||||
> The only legitimate link to our repositories is the [portapack-mayhem](https://github.com/portapack-mayhem/mayhem-firmware) organization on GitHub.
|
||||
|
||||
# PortaPack Mayhem
|
||||
|
||||
@@ -16,9 +17,9 @@ This is a fork of the [Havoc](https://github.com/furrtek/portapack-havoc/) firmw
|
||||
|
||||
If you are new to *HackRF+PortaPack+Mayhem*, check these:
|
||||
|
||||
[<img alt="What is the HackRF One Portapack H2+?" src="https://img.youtube.com/vi/alrFbY5vxt4/maxresdefault.jpg" width="512">](https://grabify.link/9UZGEW)
|
||||
[<img alt="It’s TOO Easy to Accidentally Do Illegal Stuff with This" src="https://img.youtube.com/vi/OPckpjBSAOw/maxresdefault.jpg" width="700">](https://grabify.link/X4D5TF)
|
||||
|
||||
[<img alt="Beginner's Guide To The HackRF & Portapak With Mayhem" src="https://img.youtube.com/vi/H-bqdWfbhpg/maxresdefault.jpg" width="254">](https://grabify.link/5MU2VH) [<img alt="HackRF 101 : Everything You Need to Know to Get Started!" src="https://img.youtube.com/vi/xGR_PMD9LeU/maxresdefault.jpg" width="254">](https://grabify.link/C0J6ZR)
|
||||
[<img alt="What is the HackRF One Portapack H2+?" src="https://img.youtube.com/vi/alrFbY5vxt4/maxresdefault.jpg" width="230">](https://grabify.link/9UZGEW) [<img alt="Beginner's Guide To The HackRF & Portapak With Mayhem" src="https://img.youtube.com/vi/H-bqdWfbhpg/maxresdefault.jpg" width="230">](https://grabify.link/5MU2VH) [<img alt="HackRF 101 : Everything You Need to Know to Get Started!" src="https://img.youtube.com/vi/xGR_PMD9LeU/maxresdefault.jpg" width="230">](https://grabify.link/C0J6ZR)
|
||||
|
||||
# Frequently Asked Questions
|
||||
|
||||
@@ -54,13 +55,7 @@ Consider that the hardware and firmware has been created and maintain by a [lot]
|
||||
To support the people behind the hardware, please buy a genuine [HackRF](https://greatscottgadgets.com/hackrf/) and [PortaPack](https://store.sharebrained.com/products/portapack-for-hackrf-one-kit).
|
||||
|
||||
## What if I really want something specific?
|
||||
If what you need can be relevant in general, you can [request a feature](https://github.com/portapack-mayhem/mayhem-firmware/issues/new?labels=enhancement&template=feature_request.md).
|
||||
|
||||
<del>You can create a bounty and invite people to your own bounty. This will incentivize coders to work on a new feature, solving a bug or even writting documentation. Start a bounty by [creating](https://github.com/portapack-mayhem/mayhem-firmware/issues/new/choose) or [choosing](https://github.com/portapack-mayhem/mayhem-firmware/issues/) an existing issue. Then, go to [Bountysource](https://www.bountysource.com/) and post a bounty using the link to that specific [issue](https://www.bountysource.com/teams/portapack-mayhem/issues).</del>
|
||||
|
||||
<del>Promote your bounty over our Discord by clicking the chat badge on [top](#portapack-mayhem).</del>
|
||||
|
||||
Bountysource has not been reliable lately, so until this changes, please **DO NOT** post a bounty there. Go to our Discord by clicking the chat badge on [top](#portapack-mayhem) and discuss there.
|
||||
If what you need can be relevant in general, you can [request a feature](https://github.com/portapack-mayhem/mayhem-firmware/issues/new?labels=enhancement&template=feature_request.md). Alternatively, go to our Discord by clicking the chat badge on [top](#portapack-mayhem) and discuss there.
|
||||
|
||||
## What if I need help?
|
||||
First, check the [documentation](https://github.com/portapack-mayhem/mayhem-firmware/wiki). If you find a bug or you think the problem is related to the current repository, please open an [issue](https://github.com/portapack-mayhem/mayhem-firmware/issues/new/choose).
|
||||
|
||||
@@ -49,6 +49,7 @@ void BattinfoView::update_result() {
|
||||
text_voltage.set("UNKNOWN");
|
||||
text_current.set("-");
|
||||
text_charge.set("-");
|
||||
text_method.set("-");
|
||||
return;
|
||||
}
|
||||
bool uichg = false;
|
||||
@@ -78,6 +79,13 @@ void BattinfoView::update_result() {
|
||||
text_current.hidden(true);
|
||||
text_charge.hidden(true);
|
||||
}
|
||||
if ((valid_mask & battery::BatteryManagement::BATT_VALID_PERCENT) == battery::BatteryManagement::BATT_VALID_PERCENT) {
|
||||
text_method.set("IC");
|
||||
button_mode.set_text("Volt");
|
||||
} else {
|
||||
text_method.set("Voltage");
|
||||
button_mode.set_text("IC");
|
||||
}
|
||||
if (uichg) set_dirty();
|
||||
// to update status bar too, send message in behalf of batt manager
|
||||
BatteryStateMessage msg{valid_mask, percent, current >= 0, voltage};
|
||||
@@ -92,12 +100,24 @@ BattinfoView::BattinfoView(NavigationView& nav)
|
||||
&text_voltage,
|
||||
&text_current,
|
||||
&text_charge,
|
||||
&text_method,
|
||||
&button_mode,
|
||||
&button_exit});
|
||||
|
||||
button_exit.on_select = [this, &nav](Button&) {
|
||||
nav.pop();
|
||||
};
|
||||
|
||||
button_mode.on_select = [this, &nav](Button&) {
|
||||
if (button_mode.text() == "IC") {
|
||||
battery::BatteryManagement::set_calc_override(false);
|
||||
persistent_memory::set_ui_override_batt_calc(false);
|
||||
button_mode.set_text("Volt");
|
||||
} else {
|
||||
battery::BatteryManagement::set_calc_override(true);
|
||||
persistent_memory::set_ui_override_batt_calc(true);
|
||||
button_mode.set_text("IC");
|
||||
}
|
||||
};
|
||||
update_result();
|
||||
if (thread == nullptr) thread = chThdCreateFromHeap(NULL, 1024, NORMALPRIO + 10, BattinfoView::static_fn, this);
|
||||
}
|
||||
|
||||
@@ -53,11 +53,14 @@ class BattinfoView : public View {
|
||||
|
||||
Labels labels{
|
||||
{{2 * 8, 1 * 16}, "Percent:", Theme::getInstance()->fg_light->foreground},
|
||||
{{2 * 8, 2 * 16}, "Voltage:", Theme::getInstance()->fg_light->foreground}};
|
||||
{{2 * 8, 2 * 16}, "Voltage:", Theme::getInstance()->fg_light->foreground},
|
||||
{{2 * 8, 3 * 16}, "Method:", Theme::getInstance()->fg_light->foreground},
|
||||
{{2 * 8, 7 * 16}, "Change method:", Theme::getInstance()->fg_light->foreground},
|
||||
};
|
||||
|
||||
Labels labels_opt{
|
||||
{{2 * 8, 3 * 16}, "Current:", Theme::getInstance()->fg_light->foreground},
|
||||
{{2 * 8, 4 * 16}, "Charge:", Theme::getInstance()->fg_light->foreground}};
|
||||
{{2 * 8, 4 * 16}, "Current:", Theme::getInstance()->fg_light->foreground},
|
||||
{{2 * 8, 5 * 16}, "Charge:", Theme::getInstance()->fg_light->foreground}};
|
||||
|
||||
Text text_percent{
|
||||
{13 * 8, 1 * 16, 10 * 16, 16},
|
||||
@@ -65,12 +68,19 @@ class BattinfoView : public View {
|
||||
Text text_voltage{
|
||||
{13 * 8, 2 * 16, 10 * 16, 16},
|
||||
"-"};
|
||||
Text text_current{
|
||||
Text text_method{
|
||||
{13 * 8, 3 * 16, 10 * 16, 16},
|
||||
"-"};
|
||||
Text text_charge{
|
||||
Text text_current{
|
||||
{13 * 8, 4 * 16, 10 * 16, 16},
|
||||
"-"};
|
||||
Text text_charge{
|
||||
{13 * 8, 5 * 16, 10 * 16, 16},
|
||||
"-"};
|
||||
|
||||
Button button_mode{
|
||||
{2 * 8, 8 * 16 + 5, 5 * 16, 32},
|
||||
"Volt"};
|
||||
|
||||
Button button_exit{
|
||||
{72, 17 * 16, 96, 32},
|
||||
|
||||
@@ -948,6 +948,32 @@ void SetThemeView::focus() {
|
||||
options.focus();
|
||||
}
|
||||
|
||||
/* SetBatteryView ************************************/
|
||||
|
||||
SetBatteryView::SetBatteryView(NavigationView& nav) {
|
||||
add_children({&labels,
|
||||
&button_save,
|
||||
&button_cancel,
|
||||
&checkbox_overridebatt});
|
||||
|
||||
button_save.on_select = [&nav, this](Button&) {
|
||||
pmem::set_ui_override_batt_calc(checkbox_overridebatt.value());
|
||||
battery::BatteryManagement::set_calc_override(checkbox_overridebatt.value());
|
||||
send_system_refresh();
|
||||
nav.pop();
|
||||
};
|
||||
|
||||
checkbox_overridebatt.set_value(pmem::ui_override_batt_calc());
|
||||
|
||||
button_cancel.on_select = [&nav, this](Button&) {
|
||||
nav.pop();
|
||||
};
|
||||
}
|
||||
|
||||
void SetBatteryView::focus() {
|
||||
button_cancel.focus();
|
||||
}
|
||||
|
||||
/* SettingsMenuView **************************************/
|
||||
|
||||
SettingsMenuView::SettingsMenuView(NavigationView& nav)
|
||||
@@ -978,6 +1004,7 @@ void SettingsMenuView::on_populate() {
|
||||
{"Theme", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push<SetThemeView>(); }},
|
||||
{"Autostart", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push<SetAutostartView>(); }},
|
||||
});
|
||||
if (battery::BatteryManagement::isDetected()) add_item({"Battery", ui::Color::dark_cyan(), &bitmap_icon_setup, [this]() { nav_.push<SetBatteryView>(); }});
|
||||
}
|
||||
|
||||
} /* namespace ui */
|
||||
|
||||
@@ -888,6 +888,35 @@ class SetThemeView : public View {
|
||||
};
|
||||
};
|
||||
|
||||
class SetBatteryView : public View {
|
||||
public:
|
||||
SetBatteryView(NavigationView& nav);
|
||||
|
||||
void focus() override;
|
||||
|
||||
std::string title() const override { return "Battery"; };
|
||||
|
||||
private:
|
||||
int32_t selected = 0;
|
||||
Labels labels{
|
||||
{{1 * 8, 1 * 16}, "Override batt calculation", Theme::getInstance()->fg_light->foreground},
|
||||
{{1 * 8, 2 * 16}, "method to voltage based", Theme::getInstance()->fg_light->foreground}};
|
||||
|
||||
Button button_save{
|
||||
{2 * 8, 16 * 16, 12 * 8, 32},
|
||||
"Save"};
|
||||
|
||||
Checkbox checkbox_overridebatt{
|
||||
{2 * 8, 6 * 16},
|
||||
23,
|
||||
"Override"};
|
||||
|
||||
Button button_cancel{
|
||||
{16 * 8, 16 * 16, 12 * 8, 32},
|
||||
"Cancel",
|
||||
};
|
||||
};
|
||||
|
||||
class SettingsMenuView : public BtnGridView {
|
||||
public:
|
||||
SettingsMenuView(NavigationView& nav);
|
||||
|
||||
@@ -281,6 +281,7 @@ void EventDispatcher::emulateTouch(ui::TouchEvent event) {
|
||||
while (injected_touch_event != nullptr) {
|
||||
chThdSleepMilliseconds(5);
|
||||
}
|
||||
injected_touch_event = nullptr; // to clean event_mo.cpp, compile warning error : "storing the address of local variable 'event' in 'this_4(D)->injected_touch_event' [-Wdangling-pointer=]"
|
||||
}
|
||||
|
||||
void EventDispatcher::emulateKeyboard(ui::KeyboardEvent event) {
|
||||
@@ -288,6 +289,7 @@ void EventDispatcher::emulateKeyboard(ui::KeyboardEvent event) {
|
||||
while (injected_keyboard_event != nullptr) {
|
||||
chThdSleepMilliseconds(5);
|
||||
}
|
||||
injected_keyboard_event = nullptr; // to clean event_mo.cpp, compile warning error : "storing the address of local variable 'event' in 'this_4(D)->injected_keyboard_event' [-Wdangling-pointer=]"
|
||||
}
|
||||
|
||||
void EventDispatcher::on_keyboard_event(ui::KeyboardEvent event) {
|
||||
|
||||
@@ -586,7 +586,7 @@ init_status_t init() {
|
||||
chThdSleepMilliseconds(10);
|
||||
|
||||
audio::init(portapack_audio_codec());
|
||||
battery::BatteryManagement::init();
|
||||
battery::BatteryManagement::init(persistent_memory::ui_override_batt_calc());
|
||||
|
||||
if (lcd_fast_setup)
|
||||
draw_splash_screen_icon(4, ui::bitmap_icon_speaker);
|
||||
|
||||
@@ -68,7 +68,7 @@ ThemeYellow::ThemeYellow() {
|
||||
.foreground = Color::black(),
|
||||
};
|
||||
bg_lightest_small = new Style{
|
||||
.font = font::fixed_8x16,
|
||||
.font = font::fixed_5x8,
|
||||
.background = {255, 255, 204},
|
||||
.foreground = Color::black(),
|
||||
};
|
||||
@@ -105,8 +105,8 @@ ThemeYellow::ThemeYellow() {
|
||||
};
|
||||
|
||||
bg_important_small = new Style{
|
||||
.font = ui::font::fixed_5x8,
|
||||
.background = ui::Color::yellow(),
|
||||
.font = font::fixed_5x8,
|
||||
.background = Color::yellow(),
|
||||
.foreground = {31, 31, 0},
|
||||
};
|
||||
|
||||
@@ -201,7 +201,7 @@ ThemeAqua::ThemeAqua() {
|
||||
.foreground = Color::black(),
|
||||
};
|
||||
bg_lightest_small = new Style{
|
||||
.font = font::fixed_8x16,
|
||||
.font = font::fixed_5x8,
|
||||
.background = {204, 255, 255},
|
||||
.foreground = Color::black(),
|
||||
};
|
||||
@@ -238,8 +238,8 @@ ThemeAqua::ThemeAqua() {
|
||||
};
|
||||
|
||||
bg_important_small = new Style{
|
||||
.font = ui::font::fixed_5x8,
|
||||
.background = ui::Color::yellow(),
|
||||
.font = font::fixed_5x8,
|
||||
.background = Color::yellow(),
|
||||
.foreground = {0, 31, 31},
|
||||
};
|
||||
|
||||
@@ -334,7 +334,7 @@ ThemeDefault::ThemeDefault() {
|
||||
.foreground = Color::black(),
|
||||
};
|
||||
bg_lightest_small = new Style{
|
||||
.font = font::fixed_8x16,
|
||||
.font = font::fixed_5x8,
|
||||
.background = Color::white(),
|
||||
.foreground = Color::black(),
|
||||
};
|
||||
@@ -371,9 +371,9 @@ ThemeDefault::ThemeDefault() {
|
||||
};
|
||||
|
||||
bg_important_small = new Style{
|
||||
.font = ui::font::fixed_5x8,
|
||||
.background = ui::Color::yellow(),
|
||||
.foreground = ui::Color::black(),
|
||||
.font = font::fixed_5x8,
|
||||
.background = Color::yellow(),
|
||||
.foreground = Color::black(),
|
||||
};
|
||||
|
||||
error_dark = new Style{
|
||||
@@ -466,7 +466,7 @@ ThemeGreen::ThemeGreen() {
|
||||
.foreground = Color::black(),
|
||||
};
|
||||
bg_lightest_small = new Style{
|
||||
.font = font::fixed_8x16,
|
||||
.font = font::fixed_5x8,
|
||||
.background = {0, 245, 29},
|
||||
.foreground = Color::black(),
|
||||
};
|
||||
@@ -503,8 +503,8 @@ ThemeGreen::ThemeGreen() {
|
||||
};
|
||||
|
||||
bg_important_small = new Style{
|
||||
.font = ui::font::fixed_5x8,
|
||||
.background = ui::Color::yellow(),
|
||||
.font = font::fixed_5x8,
|
||||
.background = Color::yellow(),
|
||||
.foreground = {0, 33, 4},
|
||||
};
|
||||
|
||||
@@ -599,7 +599,7 @@ ThemeRed::ThemeRed() {
|
||||
.foreground = Color::black(),
|
||||
};
|
||||
bg_lightest_small = new Style{
|
||||
.font = font::fixed_8x16,
|
||||
.font = font::fixed_5x8,
|
||||
.background = {245, 29, 0},
|
||||
.foreground = Color::black(),
|
||||
};
|
||||
@@ -636,8 +636,8 @@ ThemeRed::ThemeRed() {
|
||||
};
|
||||
|
||||
bg_important_small = new Style{
|
||||
.font = ui::font::fixed_5x8,
|
||||
.background = ui::Color::yellow(),
|
||||
.font = font::fixed_5x8,
|
||||
.background = Color::yellow(),
|
||||
.foreground = {33, 4, 0},
|
||||
};
|
||||
|
||||
|
||||
@@ -27,9 +27,6 @@
|
||||
namespace battery {
|
||||
namespace ads1110 {
|
||||
|
||||
constexpr uint16_t BATTERY_MIN_VOLTAGE = 3000;
|
||||
constexpr uint16_t BATTERY_MAX_VOLTAGE = 4000;
|
||||
|
||||
void ADS1110::init() {
|
||||
if (!detected_) {
|
||||
detected_ = detect();
|
||||
@@ -118,15 +115,8 @@ uint16_t ADS1110::readVoltage() {
|
||||
return (uint16_t)voltage;
|
||||
}
|
||||
|
||||
void ADS1110::getBatteryInfo(uint8_t& valid_mask, uint8_t& batteryPercentage, uint16_t& voltage) {
|
||||
void ADS1110::getBatteryInfo(uint8_t& valid_mask, uint16_t& voltage) {
|
||||
voltage = readVoltage();
|
||||
|
||||
// Calculate the remaining battery percentage
|
||||
batteryPercentage = (float)(voltage - BATTERY_MIN_VOLTAGE) / (float)(BATTERY_MAX_VOLTAGE - BATTERY_MIN_VOLTAGE) * 100.0;
|
||||
|
||||
// Limit the values to the valid range
|
||||
batteryPercentage = (batteryPercentage > 100) ? 100 : batteryPercentage;
|
||||
// ToDo: if its > 4, then 100%, if < 3 then 0%
|
||||
valid_mask = 1; // BATT_VALID_VOLTAGE
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class ADS1110 {
|
||||
bool isDetected() const { return detected_; }
|
||||
|
||||
uint16_t readVoltage();
|
||||
void getBatteryInfo(uint8_t& valid_mask, uint8_t& batteryPercentage, uint16_t& voltage);
|
||||
void getBatteryInfo(uint8_t& valid_mask, uint16_t& voltage);
|
||||
|
||||
private:
|
||||
I2C& bus;
|
||||
|
||||
@@ -18,6 +18,7 @@ ads1110::ADS1110 battery_ads1110{portapack::i2c0, 0x48};
|
||||
max17055::MAX17055 battery_max17055{portapack::i2c0, 0x36};
|
||||
|
||||
Thread* BatteryManagement::thread = nullptr;
|
||||
bool BatteryManagement::calcOverride = false;
|
||||
|
||||
void BatteryManagement::detect() {
|
||||
// try to detect supported modules
|
||||
@@ -43,22 +44,33 @@ void BatteryManagement::detect() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void BatteryManagement::init() {
|
||||
void BatteryManagement::init(bool override) {
|
||||
calcOverride = override;
|
||||
detect();
|
||||
// sets timer to query and broadcats this info
|
||||
create_thread();
|
||||
}
|
||||
|
||||
// set if the default percentage calculation should be overrided by voltage based one
|
||||
void BatteryManagement::set_calc_override(bool override) {
|
||||
calcOverride = override;
|
||||
}
|
||||
|
||||
// sets the values, it the currend module supports it.
|
||||
void BatteryManagement::getBatteryInfo(uint8_t& valid_mask, uint8_t& batteryPercentage, uint16_t& voltage, int32_t& current) {
|
||||
if (detected_ == BATT_NONE) {
|
||||
valid_mask = BATT_VALID_NONE;
|
||||
return;
|
||||
} else if (detected_ == BATT_ADS1110) {
|
||||
battery_ads1110.getBatteryInfo(valid_mask, batteryPercentage, voltage);
|
||||
battery_ads1110.getBatteryInfo(valid_mask, voltage);
|
||||
batteryPercentage = calc_percent_voltage(voltage);
|
||||
return;
|
||||
} else if (detected_ == BATT_MAX17055) {
|
||||
battery_max17055.getBatteryInfo(valid_mask, batteryPercentage, voltage, current);
|
||||
if (calcOverride) {
|
||||
valid_mask &= ~BATT_VALID_PERCENT; // indicate it is voltage based
|
||||
batteryPercentage = calc_percent_voltage(voltage);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// add new module query here
|
||||
@@ -70,7 +82,7 @@ void BatteryManagement::getBatteryInfo(uint8_t& valid_mask, uint8_t& batteryPerc
|
||||
voltage = rand() % 1000 + 3000; // mV
|
||||
current = rand() % 150; // mA
|
||||
isCharging = rand() % 2;
|
||||
valid_mask = 3;
|
||||
valid_mask = 7;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@@ -100,6 +112,18 @@ uint8_t BatteryManagement::getPercent() {
|
||||
int32_t current = 0;
|
||||
getBatteryInfo(validity, batteryPercentage, voltage, current);
|
||||
if ((validity & BATT_VALID_VOLTAGE) != BATT_VALID_VOLTAGE) return 102;
|
||||
if (calcOverride || ((validity & BATT_VALID_PERCENT) != BATT_VALID_PERCENT)) {
|
||||
validity &= ~BATT_VALID_PERCENT; // indicate it is voltage based
|
||||
batteryPercentage = calc_percent_voltage(voltage);
|
||||
}
|
||||
return batteryPercentage;
|
||||
}
|
||||
|
||||
uint8_t BatteryManagement::calc_percent_voltage(uint16_t voltage) {
|
||||
// Calculate the remaining battery percentage
|
||||
uint8_t batteryPercentage = (float)(voltage - BATTERY_MIN_VOLTAGE) / (float)(BATTERY_MAX_VOLTAGE - BATTERY_MIN_VOLTAGE) * 100.0;
|
||||
// Limit the values to the valid range
|
||||
batteryPercentage = (batteryPercentage > 100) ? 100 : batteryPercentage;
|
||||
return batteryPercentage;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
|
||||
namespace battery {
|
||||
|
||||
#define BATTERY_MIN_VOLTAGE 3000.0
|
||||
#define BATTERY_MAX_VOLTAGE 4170.0
|
||||
#define BATTERY_DESIGN_CAP 2500
|
||||
|
||||
class BatteryManagement {
|
||||
public:
|
||||
enum BatteryModules {
|
||||
@@ -39,8 +43,9 @@ class BatteryManagement {
|
||||
BATT_VALID_NONE = 0,
|
||||
BATT_VALID_VOLTAGE = 1,
|
||||
BATT_VALID_CURRENT = 2,
|
||||
BATT_VALID_PERCENT = 4,
|
||||
};
|
||||
static void init();
|
||||
static void init(bool override = false);
|
||||
static void detect();
|
||||
static bool isDetected() { return detected_ != BATT_NONE; }
|
||||
static BatteryModules detectedModule() { return detected_; }
|
||||
@@ -49,12 +54,15 @@ class BatteryManagement {
|
||||
static uint8_t getPercent();
|
||||
static uint16_t read_register(const uint8_t reg);
|
||||
static bool write_register(const uint8_t reg, const uint16_t value);
|
||||
static void set_calc_override(bool override);
|
||||
static uint8_t calc_percent_voltage(uint16_t); // calculates battery percentage from the voltage
|
||||
|
||||
private:
|
||||
static void create_thread();
|
||||
static msg_t timer_fn(void* arg);
|
||||
static Thread* thread;
|
||||
static BatteryModules detected_; // if there is any batt management system
|
||||
static bool calcOverride; // if set to true, it'll override the battery percent calculation based on current voltage.
|
||||
};
|
||||
}; // namespace battery
|
||||
#endif
|
||||
@@ -166,7 +166,7 @@ void MAX17055::getBatteryInfo(uint8_t& valid_mask, uint8_t& batteryPercentage, u
|
||||
}
|
||||
batteryPercentage = stateOfCharge();
|
||||
current = instantCurrent();
|
||||
valid_mask = 3; // BATT_VALID_VOLTAGE + CURRENT
|
||||
valid_mask = 7; // BATT_VALID_VOLTAGE + CURRENT + PERCENT
|
||||
} else {
|
||||
// let's indicate the data is wrong. ui will handle this by display UNK values.
|
||||
valid_mask = 0;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
#include "battery.hpp"
|
||||
#include "i2c_pp.hpp"
|
||||
|
||||
#define MAX17055_POR 0
|
||||
@@ -47,7 +48,7 @@
|
||||
|
||||
// Define Battery Capacity
|
||||
#ifndef __MAX17055_Design_Capacity__
|
||||
#define __MAX17055_Design_Capacity__ 2500 // Battery Capacity
|
||||
#define __MAX17055_Design_Capacity__ BATTERY_DESIGN_CAP // Battery Capacity
|
||||
#endif
|
||||
|
||||
// Define Gauge Resistor
|
||||
@@ -57,17 +58,17 @@
|
||||
|
||||
// Define Minimum Voltage
|
||||
#ifndef __MAX17055_Min_Voltage__
|
||||
#define __MAX17055_Min_Voltage__ 3.0 // Minimum Voltage
|
||||
#define __MAX17055_Min_Voltage__ BATTERY_MIN_VOLTAGE / 1000.0 // Minimum Voltage
|
||||
#endif
|
||||
|
||||
// Define Maximum Voltage
|
||||
#ifndef __MAX17055_Max_Voltage__
|
||||
#define __MAX17055_Max_Voltage__ 4.17 // Maximum Voltage
|
||||
#define __MAX17055_Max_Voltage__ BATTERY_MAX_VOLTAGE / 1000.0 // Maximum Voltage
|
||||
#endif
|
||||
|
||||
// Define Empty Voltage
|
||||
#ifndef __MAX17055_Empty_Voltage__
|
||||
#define __MAX17055_Empty_Voltage__ 3.0 // Empty Voltage
|
||||
#define __MAX17055_Empty_Voltage__ BATTERY_MIN_VOLTAGE / 1000.0 // Empty Voltage
|
||||
#endif
|
||||
|
||||
// Define Recovery Voltage
|
||||
|
||||
@@ -133,7 +133,7 @@ struct ui_config2_t {
|
||||
bool hide_fake_brightness : 1;
|
||||
bool hide_numeric_battery : 1;
|
||||
bool hide_battery_icon : 1;
|
||||
bool UNUSED_3 : 1;
|
||||
bool override_batt_calc : 1;
|
||||
bool UNUSED_4 : 1;
|
||||
bool UNUSED_5 : 1;
|
||||
bool UNUSED_6 : 1;
|
||||
@@ -965,6 +965,10 @@ uint8_t ui_theme_id() {
|
||||
return data->ui_config2.theme_id;
|
||||
}
|
||||
|
||||
bool ui_override_batt_calc() {
|
||||
return data->ui_config2.override_batt_calc;
|
||||
}
|
||||
|
||||
void set_ui_hide_speaker(bool v) {
|
||||
data->ui_config2.hide_speaker = v;
|
||||
}
|
||||
@@ -1006,6 +1010,9 @@ void set_ui_hide_battery_icon(bool v) {
|
||||
void set_ui_theme_id(uint8_t theme_id) {
|
||||
data->ui_config2.theme_id = theme_id;
|
||||
}
|
||||
void set_ui_override_batt_calc(bool v) {
|
||||
data->ui_config2.override_batt_calc = v;
|
||||
}
|
||||
|
||||
/* Converter */
|
||||
bool config_converter() {
|
||||
|
||||
@@ -339,6 +339,7 @@ bool ui_hide_numeric_battery();
|
||||
bool ui_hide_battery_icon();
|
||||
bool ui_hide_sd_card();
|
||||
uint8_t ui_theme_id();
|
||||
bool ui_override_batt_calc();
|
||||
void set_ui_hide_speaker(bool v);
|
||||
void set_ui_hide_mute(bool v);
|
||||
void set_ui_hide_converter(bool v);
|
||||
@@ -352,6 +353,7 @@ void set_ui_hide_numeric_battery(bool v);
|
||||
void set_ui_hide_battery_icon(bool v);
|
||||
void set_ui_hide_sd_card(bool v);
|
||||
void set_ui_theme_id(uint8_t v);
|
||||
void set_ui_override_batt_calc(bool v);
|
||||
|
||||
// sd persisting settings
|
||||
bool should_use_sdcard_for_pmem();
|
||||
|
||||
@@ -31,7 +31,7 @@ include(CheckCXXCompilerFlag)
|
||||
project(pacman_app)
|
||||
|
||||
# Compiler options here.
|
||||
set(USE_OPT "-Os -g --specs=nano.specs")
|
||||
set(USE_OPT "-Os -g --specs=nano.specs --specs=nosys.specs")
|
||||
|
||||
# C specific options here (added to USE_OPT).
|
||||
set(USE_COPT "-std=gnu99")
|
||||
@@ -120,7 +120,7 @@ set(TCPPSRC)
|
||||
# List ASM source files here
|
||||
set(ASMSRC)
|
||||
|
||||
set(INCDIR
|
||||
set(INCDIR
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${COMMON}
|
||||
${COMMON}/../application
|
||||
|
||||
@@ -55,8 +55,12 @@ def write_image(data, path):
|
||||
|
||||
def patch_image(path, image_data, search_address, replace_address):
|
||||
if (len(image_data) % 4) != 0:
|
||||
print("file size not divideable by 4")
|
||||
sys.exit(-1)
|
||||
#sys.exit(-1)
|
||||
print("\n External App image file:", path, ", size not divideable by 4 :", len(image_data))
|
||||
j=0
|
||||
while (len(image_data) % 4) != 0:
|
||||
image_data += b'\x00' ; j+=1
|
||||
print("file size:", len(image_data)," after padded:",j, "bytes")
|
||||
|
||||
external_application_image = bytearray()
|
||||
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,94 @@
|
||||
f=91200000,m=WFM,bw=200k,d=Radio Slovensko Nitra
|
||||
f=92200000,m=WFM,bw=200k,d=Radio Slovensko Poprad
|
||||
f=96600000,m=WFM,bw=200k,d=Radio Slovensko Bratislava
|
||||
f=96600000,m=WFM,bw=200k,d=Radio Slovensko Kosice
|
||||
f=103500000,m=WFM,bw=200k,d=Radio Slovensko Zilina
|
||||
f=99300000,m=WFM,bw=200k,d=Radio Regina Bratislava
|
||||
f=100100000,m=WFM,bw=200k,d=Radio Regina Zilina
|
||||
f=100300000,m=WFM,bw=200k,d=Radio Regina Kosice
|
||||
f=96200000,m=WFM,bw=200k,d=Radio Devin Kosice
|
||||
f=104400000,m=WFM,bw=200k,d=Radio Devin Bratislava
|
||||
f=106700000,m=WFM,bw=200k,d=Radio Devin Presov
|
||||
f=89300000,m=WFM,bw=200k,d=Radio _FM Bratislava
|
||||
f=94500000,m=WFM,bw=200k,d=Radio _FM Zilina
|
||||
f=101200000,m=WFM,bw=200k,d=Radio _FM Kosice
|
||||
f=101500000,m=WFM,bw=200k,d=Radio _FM Presov
|
||||
f=105400000,m=WFM,bw=200k,d=Radio _FM Banska Bystrica
|
||||
f=98900000,m=WFM,bw=200k,d=Radio Patria Bratislava
|
||||
f=102400000,m=WFM,bw=200k,d=Radio Patria Senec
|
||||
f=98900000,m=WFM,bw=200k,d=Radio Slovakia International Bratislava
|
||||
f=107600000,m=WFM,bw=200k,d=Radio Expres Bratislava
|
||||
f=96500000,m=WFM,bw=200k,d=Radio Expres Zilina
|
||||
f=93100000,m=WFM,bw=200k,d=Radio Expres Martin
|
||||
f=93600000,m=WFM,bw=200k,d=Radio Expres Donovaly
|
||||
f=95100000,m=WFM,bw=200k,d=Radio Expres Banska Stiavnica
|
||||
f=95200000,m=WFM,bw=200k,d=Radio Expres Kosice
|
||||
f=105200000,m=WFM,bw=200k,d=Radio Expres Presov
|
||||
f=99500000,m=WFM,bw=200k,d=Radio Expres Vychodna
|
||||
f=104800000,m=WFM,bw=200k,d=Europa 2 Bratislava
|
||||
f=93500000,m=WFM,bw=200k,d=Europa 2 Martin
|
||||
f=97200000,m=WFM,bw=200k,d=Europa 2 Presov
|
||||
f=102000000,m=WFM,bw=200k,d=Europa 2 Kosice
|
||||
f=106600000,m=WFM,bw=200k,d=Radio Melody Bratislava
|
||||
f=88800000,m=WFM,bw=200k,d=Radio Melody Nitra
|
||||
f=89800000,m=WFM,bw=200k,d=Radio Rock Presov
|
||||
f=97600000,m=WFM,bw=200k,d=Radio Rock Bratislava
|
||||
f=100300000,m=WFM,bw=200k,d=Radio Rock Trencin
|
||||
f=94000000,m=WFM,bw=200k,d=Fun radio Nitra
|
||||
f=94300000,m=WFM,bw=200k,d=Fun radio Bratislava
|
||||
f=102900000,m=WFM,bw=200k,d=Fun radio Kosice
|
||||
f=94800000,m=WFM,bw=200k,d=Radio Vlna Kosice
|
||||
f=96100000,m=WFM,bw=200k,d=Radio Vlna Nitra
|
||||
f=101800000,m=WFM,bw=200k,d=Radio Vlna Bratislava
|
||||
f=104800000,m=WFM,bw=200k,d=Radio Vlna Poprad
|
||||
f=104900000,m=WFM,bw=200k,d=Radio Vlna Martin
|
||||
f=105100000,m=WFM,bw=200k,d=Radio Vlna Banska Stiavnica
|
||||
f=105800000,m=WFM,bw=200k,d=Radio Vlna Presov
|
||||
f=95600000,m=WFM,bw=200k,d=Best FM Bratislava
|
||||
f=93800000,m=WFM,bw=200k,d=Best FM Kosice
|
||||
f=88200000,m=WFM,bw=200k,d=Best FM Nitra
|
||||
f=94000000,m=WFM,bw=200k,d=Best FM Presov
|
||||
f=98900000,m=WFM,bw=200k,d=Best FM Trencin
|
||||
f=93000000,m=WFM,bw=200k,d=Best FM Trnava
|
||||
f=98000000,m=WFM,bw=200k,d=Best FM Zilina
|
||||
f=89400000,m=WFM,bw=200k,d=Radio Lumen Martin
|
||||
f=92900000,m=WFM,bw=200k,d=Radio Lumen Presov
|
||||
f=93800000,m=WFM,bw=200k,d=Radio Lumen Bratislava
|
||||
f=94400000,m=WFM,bw=200k,d=Radio Lumen Kosice
|
||||
f=98100000,m=WFM,bw=200k,d=Radio Lumen Trnava
|
||||
f=91700000,m=WFM,bw=200k,d=Radio 7 Bratislava
|
||||
f=88600000,m=WFM,bw=200k,d=Radio 7 Kosice
|
||||
f=103600000,m=WFM,bw=200k,d=Radio 7 Nitra
|
||||
f=96400000,m=WFM,bw=200k,d=Radio 7 Poprad
|
||||
f=107500000,m=WFM,bw=200k,d=Radio 7 Ruzomberok
|
||||
f=101000000,m=WFM,bw=200k,d=Radio 7 Zilina
|
||||
f=104100000,m=WFM,bw=200k,d=Dobre radio Presov
|
||||
f=104200000,m=WFM,bw=200k,d=Dobre radio Domasa
|
||||
f=104500000,m=WFM,bw=200k,d=Dobre radio Kosice
|
||||
f=107000000,m=WFM,bw=200k,d=Dobre radio Bratislava
|
||||
f=89700000,m=WFM,bw=200k,d=Radio Beta Zvolen
|
||||
f=104300000,m=WFM,bw=200k,d=Radio Beta Trencin
|
||||
f=96200000,m=WFM,bw=200k,d=Radio Frontinus Martin
|
||||
f=104600000,m=WFM,bw=200k,d=Radio Frontinus Zilina
|
||||
f=99600000,m=WFM,bw=200k,d=Radio Rebeca Martin
|
||||
f=88600000,m=WFM,bw=200k,d=Radio Rebeca Zilina
|
||||
f=96000000,m=WFM,bw=200k,d=Radio SiTy Bratislava
|
||||
f=97700000,m=WFM,bw=200k,d=Sky Radio Kosice
|
||||
f=91400000,m=WFM,bw=200k,d=Sky Radio Presov
|
||||
f=106600000,m=WFM,bw=200k,d=Sky Radio Poprad
|
||||
f=106200000,m=WFM,bw=200k,d=Trnavske radio Trnava
|
||||
f=107900000,m=WFM,bw=200k,d=Trnavske radio Piestany
|
||||
f=93300000,m=WFM,bw=200k,d=Radio VIVA Bratislava
|
||||
f=101000000,m=WFM,bw=200k,d=Radio VIVA Trnava
|
||||
f=93600000,m=WFM,bw=200k,d=Radio WOW Nitra
|
||||
f=106700000,m=WFM,bw=200k,d=Radio WOW Trencin
|
||||
f=89200000,m=WFM,bw=200k,d=Zahoracke radio Skalica
|
||||
f=101500000,m=WFM,bw=200k,d=Zahoracke radio Senica
|
||||
f=92400000,m=WFM,bw=200k,d=Radio Goldies Martin
|
||||
f=92800000,m=WFM,bw=200k,d=Radio Goldies Trencin
|
||||
f=104100000,m=WFM,bw=200k,d=Radio Kiss Presov
|
||||
f=90100000,m=WFM,bw=200k,d=Radio Kosice Bratislava
|
||||
f=90400000,m=WFM,bw=200k,d=Radio Kosice Presov
|
||||
f=91700000,m=WFM,bw=200k,d=Radio Kosice Kosice
|
||||
f=106400000,m=WFM,bw=200k,d=Radio Liptov Liptovsky Mikulas
|
||||
f=106100000,m=WFM,bw=200k,d=Radio Modra
|
||||
Reference in New Issue
Block a user