mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-10 05:59:08 -07:00
Merge remote-tracking branch 'OFW/dev' into dev
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
#include "expansion_worker.h"
|
||||
|
||||
#include <power/power_service/power.h>
|
||||
#include <furi_hal_power.h>
|
||||
|
||||
#include <furi_hal_serial.h>
|
||||
#include <furi_hal_serial_control.h>
|
||||
|
||||
@@ -250,9 +252,13 @@ static bool expansion_worker_handle_state_connected(
|
||||
if(!expansion_worker_rpc_session_open(instance)) break;
|
||||
instance->state = ExpansionWorkerStateRpcActive;
|
||||
} else if(command == ExpansionFrameControlCommandEnableOtg) {
|
||||
if(!furi_hal_power_is_otg_enabled()) furi_hal_power_enable_otg();
|
||||
Power* power = furi_record_open(RECORD_POWER);
|
||||
power_enable_otg(power, true);
|
||||
furi_record_close(RECORD_POWER);
|
||||
} else if(command == ExpansionFrameControlCommandDisableOtg) {
|
||||
if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg();
|
||||
Power* power = furi_record_open(RECORD_POWER);
|
||||
power_enable_otg(power, false);
|
||||
furi_record_close(RECORD_POWER);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -30,13 +30,16 @@ void power_cli_reboot2dfu(Cli* cli, FuriString* args) {
|
||||
|
||||
void power_cli_5v(Cli* cli, FuriString* args) {
|
||||
UNUSED(cli);
|
||||
Power* power = furi_record_open(RECORD_POWER);
|
||||
if(!furi_string_cmp(args, "0")) {
|
||||
furi_hal_power_disable_otg();
|
||||
power_enable_otg(power, false);
|
||||
} else if(!furi_string_cmp(args, "1")) {
|
||||
furi_hal_power_enable_otg();
|
||||
power_enable_otg(power, true);
|
||||
} else {
|
||||
cli_print_usage("power_otg", "<1|0>", furi_string_get_cstr(args));
|
||||
}
|
||||
|
||||
furi_record_close(RECORD_POWER);
|
||||
}
|
||||
|
||||
void power_cli_3v3(Cli* cli, FuriString* args) {
|
||||
|
||||
@@ -247,6 +247,7 @@ static bool power_update_info(Power* power) {
|
||||
.is_charging = furi_hal_power_is_charging(),
|
||||
.gauge_is_ok = furi_hal_power_gauge_is_ok(),
|
||||
.is_shutdown_requested = furi_hal_power_is_shutdown_requested(),
|
||||
.is_otg_enabled = furi_hal_power_is_otg_enabled(),
|
||||
.charge = furi_hal_power_get_pct(),
|
||||
.health = furi_hal_power_get_bat_health_pct(),
|
||||
.capacity_remaining = furi_hal_power_get_battery_remaining_capacity(),
|
||||
@@ -539,6 +540,30 @@ static void power_message_callback(FuriEventLoopObject* object, void* context) {
|
||||
power_settings_load(&power->settings);
|
||||
power_settings_apply(power);
|
||||
break;
|
||||
case PowerMessageTypeSwitchOTG:
|
||||
power->is_otg_requested = *msg.bool_param;
|
||||
if(power->is_otg_requested) {
|
||||
// Only try to enable if VBUS voltage is low, otherwise charger will refuse
|
||||
if(power->info.voltage_vbus < 4.5f) {
|
||||
size_t retries = 5;
|
||||
while(retries-- > 0) {
|
||||
if(furi_hal_power_enable_otg()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!retries) {
|
||||
FURI_LOG_W(TAG, "Failed to enable OTG, will try later");
|
||||
}
|
||||
} else {
|
||||
FURI_LOG_W(
|
||||
TAG,
|
||||
"Postponing OTG enable: VBUS(%0.1f) >= 4.5v",
|
||||
(double)power->info.voltage_vbus);
|
||||
}
|
||||
} else {
|
||||
furi_hal_power_disable_otg();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
furi_crash();
|
||||
}
|
||||
@@ -584,9 +609,18 @@ static void power_tick_callback(void* context) {
|
||||
if(need_refresh) {
|
||||
view_port_update(power->battery_view_port);
|
||||
}
|
||||
// Check OTG status and disable it in case of fault
|
||||
if(furi_hal_power_is_otg_enabled()) {
|
||||
furi_hal_power_check_otg_status();
|
||||
// Check OTG status, disable in case of a fault
|
||||
if(furi_hal_power_check_otg_fault()) {
|
||||
FURI_LOG_E(TAG, "OTG fault detected, disabling OTG");
|
||||
furi_hal_power_disable_otg();
|
||||
power->is_otg_requested = false;
|
||||
}
|
||||
|
||||
// Change OTG state if needed (i.e. after disconnecting USB power)
|
||||
if(power->is_otg_requested &&
|
||||
(!power->info.is_otg_enabled && power->info.voltage_vbus < 4.5f)) {
|
||||
FURI_LOG_D(TAG, "OTG requested but not enabled, enabling OTG");
|
||||
furi_hal_power_enable_otg();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ typedef struct {
|
||||
bool gauge_is_ok;
|
||||
bool is_charging;
|
||||
bool is_shutdown_requested;
|
||||
bool is_otg_enabled;
|
||||
|
||||
float current_charger;
|
||||
float current_gauge;
|
||||
@@ -108,6 +109,19 @@ void power_api_get_settings(Power* instance, PowerSettings* settings);
|
||||
// set settings from app to service
|
||||
void power_api_set_settings(Power* instance, const PowerSettings* settings);
|
||||
|
||||
/** Enable or disable OTG
|
||||
*
|
||||
* @param power Power instance
|
||||
* @param enable true - enable, false - disable
|
||||
*/
|
||||
void power_enable_otg(Power* power, bool enable);
|
||||
|
||||
/** Check OTG status
|
||||
*
|
||||
* @return true if OTG is requested
|
||||
*/
|
||||
bool power_is_otg_enabled(Power* power);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -70,3 +70,22 @@ void power_enable_low_battery_level_notification(Power* power, bool enable) {
|
||||
furi_check(
|
||||
furi_message_queue_put(power->message_queue, &msg, FuriWaitForever) == FuriStatusOk);
|
||||
}
|
||||
|
||||
void power_enable_otg(Power* power, bool enable) {
|
||||
furi_check(power);
|
||||
|
||||
PowerMessage msg = {
|
||||
.type = PowerMessageTypeSwitchOTG,
|
||||
.bool_param = &enable,
|
||||
.lock = api_lock_alloc_locked(),
|
||||
};
|
||||
|
||||
furi_check(
|
||||
furi_message_queue_put(power->message_queue, &msg, FuriWaitForever) == FuriStatusOk);
|
||||
api_lock_wait_unlock_and_free(msg.lock);
|
||||
}
|
||||
|
||||
bool power_is_otg_enabled(Power* power) {
|
||||
furi_check(power);
|
||||
return power->is_otg_requested;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ struct Power {
|
||||
bool battery_low;
|
||||
bool show_battery_low_warning;
|
||||
uint8_t displayBatteryPercentage;
|
||||
bool is_otg_requested;
|
||||
uint8_t battery_level;
|
||||
uint8_t power_off_timeout;
|
||||
PowerSettings settings;
|
||||
@@ -58,6 +59,7 @@ typedef enum {
|
||||
PowerMessageTypeGetSettings,
|
||||
PowerMessageTypeSetSettings,
|
||||
PowerMessageTypeReloadSettings,
|
||||
PowerMessageTypeSwitchOTG,
|
||||
} PowerMessageType;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <furi_hal_gpio.h>
|
||||
#include <furi_hal_power.h>
|
||||
#include <furi_hal_resources.h>
|
||||
#include <power/power_service/power.h>
|
||||
|
||||
static const GpioPin* rpc_pin_to_hal_pin(PB_Gpio_GpioPin rpc_pin) {
|
||||
switch(rpc_pin) {
|
||||
@@ -218,12 +219,16 @@ void rpc_system_gpio_set_otg_mode(const PB_Main* request, void* context) {
|
||||
|
||||
const PB_Gpio_GpioOtgMode mode = request->content.gpio_set_otg_mode.mode;
|
||||
|
||||
Power* power = furi_record_open(RECORD_POWER);
|
||||
|
||||
if(mode == PB_Gpio_GpioOtgMode_OFF) {
|
||||
if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg();
|
||||
power_enable_otg(power, false);
|
||||
} else {
|
||||
if(!furi_hal_power_is_otg_enabled()) furi_hal_power_enable_otg();
|
||||
power_enable_otg(power, true);
|
||||
}
|
||||
|
||||
furi_record_close(RECORD_POWER);
|
||||
|
||||
rpc_send_and_release_empty(session, request->command_id, PB_CommandStatus_OK);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user