mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 04:34:43 +04:00
[FL-3774] Fix 5V on GPIO (#4103)
* Move OTG controls to the power service * Accessor: add missing power service import * Power: add is_otg_enabled to info and properly handle OTG enable with VBUS voltage present * Power: method naming * Power: add backward compatibility with old-style use of furi_hal_power * Scripts: lower MIN_GAP_PAGES to 1 * SubGhz: fix incorrect logging tag * SubGhz: delegate OTG management to power service * Power: fix condition race, various improvements Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <furi_hal.h>
|
#include <furi_hal.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <power/power_service/power.h>
|
||||||
|
|
||||||
void AccessorApp::run(void) {
|
void AccessorApp::run(void) {
|
||||||
AccessorEvent event;
|
AccessorEvent event;
|
||||||
@@ -35,16 +36,18 @@ AccessorApp::AccessorApp()
|
|||||||
: text_store{0} {
|
: text_store{0} {
|
||||||
notification = static_cast<NotificationApp*>(furi_record_open(RECORD_NOTIFICATION));
|
notification = static_cast<NotificationApp*>(furi_record_open(RECORD_NOTIFICATION));
|
||||||
expansion = static_cast<Expansion*>(furi_record_open(RECORD_EXPANSION));
|
expansion = static_cast<Expansion*>(furi_record_open(RECORD_EXPANSION));
|
||||||
|
power = static_cast<Power*>(furi_record_open(RECORD_POWER));
|
||||||
onewire_host = onewire_host_alloc(&gpio_ibutton);
|
onewire_host = onewire_host_alloc(&gpio_ibutton);
|
||||||
expansion_disable(expansion);
|
expansion_disable(expansion);
|
||||||
furi_hal_power_enable_otg();
|
power_enable_otg(power, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessorApp::~AccessorApp() {
|
AccessorApp::~AccessorApp() {
|
||||||
furi_hal_power_disable_otg();
|
power_enable_otg(power, false);
|
||||||
expansion_enable(expansion);
|
expansion_enable(expansion);
|
||||||
furi_record_close(RECORD_EXPANSION);
|
furi_record_close(RECORD_EXPANSION);
|
||||||
furi_record_close(RECORD_NOTIFICATION);
|
furi_record_close(RECORD_NOTIFICATION);
|
||||||
|
furi_record_close(RECORD_POWER);
|
||||||
onewire_host_free(onewire_host);
|
onewire_host_free(onewire_host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <one_wire/one_wire_host.h>
|
#include <one_wire/one_wire_host.h>
|
||||||
#include <notification/notification_messages.h>
|
#include <notification/notification_messages.h>
|
||||||
#include <expansion/expansion.h>
|
#include <expansion/expansion.h>
|
||||||
|
#include <power/power_service/power.h>
|
||||||
|
|
||||||
class AccessorApp {
|
class AccessorApp {
|
||||||
public:
|
public:
|
||||||
@@ -53,4 +54,5 @@ private:
|
|||||||
|
|
||||||
NotificationApp* notification;
|
NotificationApp* notification;
|
||||||
Expansion* expansion;
|
Expansion* expansion;
|
||||||
|
Power* power;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#include <one_wire/maxim_crc.h>
|
#include <one_wire/maxim_crc.h>
|
||||||
#include <one_wire/one_wire_host.h>
|
#include <one_wire/one_wire_host.h>
|
||||||
|
|
||||||
#include <furi_hal_power.h>
|
#include <power/power_service/power.h>
|
||||||
|
|
||||||
#define UPDATE_PERIOD_MS 1000UL
|
#define UPDATE_PERIOD_MS 1000UL
|
||||||
#define TEXT_STORE_SIZE 64U
|
#define TEXT_STORE_SIZE 64U
|
||||||
@@ -76,6 +76,7 @@ typedef struct {
|
|||||||
FuriThread* reader_thread;
|
FuriThread* reader_thread;
|
||||||
FuriMessageQueue* event_queue;
|
FuriMessageQueue* event_queue;
|
||||||
OneWireHost* onewire;
|
OneWireHost* onewire;
|
||||||
|
Power* power;
|
||||||
float temp_celsius;
|
float temp_celsius;
|
||||||
bool has_device;
|
bool has_device;
|
||||||
} ExampleThermoContext;
|
} ExampleThermoContext;
|
||||||
@@ -273,7 +274,7 @@ static void example_thermo_input_callback(InputEvent* event, void* ctx) {
|
|||||||
/* Starts the reader thread and handles the input */
|
/* Starts the reader thread and handles the input */
|
||||||
static void example_thermo_run(ExampleThermoContext* context) {
|
static void example_thermo_run(ExampleThermoContext* context) {
|
||||||
/* Enable power on external pins */
|
/* Enable power on external pins */
|
||||||
furi_hal_power_enable_otg();
|
power_enable_otg(context->power, true);
|
||||||
|
|
||||||
/* Configure the hardware in host mode */
|
/* Configure the hardware in host mode */
|
||||||
onewire_host_start(context->onewire);
|
onewire_host_start(context->onewire);
|
||||||
@@ -309,7 +310,7 @@ static void example_thermo_run(ExampleThermoContext* context) {
|
|||||||
onewire_host_stop(context->onewire);
|
onewire_host_stop(context->onewire);
|
||||||
|
|
||||||
/* Disable power on external pins */
|
/* Disable power on external pins */
|
||||||
furi_hal_power_disable_otg();
|
power_enable_otg(context->power, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************** Initialisation & startup *****************************/
|
/******************** Initialisation & startup *****************************/
|
||||||
@@ -334,6 +335,8 @@ static ExampleThermoContext* example_thermo_context_alloc(void) {
|
|||||||
|
|
||||||
context->onewire = onewire_host_alloc(&THERMO_GPIO_PIN);
|
context->onewire = onewire_host_alloc(&THERMO_GPIO_PIN);
|
||||||
|
|
||||||
|
context->power = furi_record_open(RECORD_POWER);
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,6 +351,7 @@ static void example_thermo_context_free(ExampleThermoContext* context) {
|
|||||||
view_port_free(context->view_port);
|
view_port_free(context->view_port);
|
||||||
|
|
||||||
furi_record_close(RECORD_GUI);
|
furi_record_close(RECORD_GUI);
|
||||||
|
furi_record_close(RECORD_POWER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The application's entry point. Execution starts from here. */
|
/* The application's entry point. Execution starts from here. */
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ GpioApp* gpio_app_alloc(void) {
|
|||||||
app->gui = furi_record_open(RECORD_GUI);
|
app->gui = furi_record_open(RECORD_GUI);
|
||||||
app->gpio_items = gpio_items_alloc();
|
app->gpio_items = gpio_items_alloc();
|
||||||
|
|
||||||
|
app->power = furi_record_open(RECORD_POWER);
|
||||||
|
|
||||||
app->view_dispatcher = view_dispatcher_alloc();
|
app->view_dispatcher = view_dispatcher_alloc();
|
||||||
app->scene_manager = scene_manager_alloc(&gpio_scene_handlers, app);
|
app->scene_manager = scene_manager_alloc(&gpio_scene_handlers, app);
|
||||||
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
|
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
|
||||||
@@ -100,6 +102,7 @@ void gpio_app_free(GpioApp* app) {
|
|||||||
// Close records
|
// Close records
|
||||||
furi_record_close(RECORD_GUI);
|
furi_record_close(RECORD_GUI);
|
||||||
furi_record_close(RECORD_NOTIFICATION);
|
furi_record_close(RECORD_NOTIFICATION);
|
||||||
|
furi_record_close(RECORD_POWER);
|
||||||
|
|
||||||
expansion_enable(app->expansion);
|
expansion_enable(app->expansion);
|
||||||
furi_record_close(RECORD_EXPANSION);
|
furi_record_close(RECORD_EXPANSION);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "scenes/gpio_scene.h"
|
#include "scenes/gpio_scene.h"
|
||||||
#include "gpio_custom_event.h"
|
#include "gpio_custom_event.h"
|
||||||
#include "usb_uart_bridge.h"
|
#include "usb_uart_bridge.h"
|
||||||
|
#include <power/power_service/power.h>
|
||||||
|
|
||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
#include <gui/view_dispatcher.h>
|
#include <gui/view_dispatcher.h>
|
||||||
@@ -27,6 +28,7 @@ struct GpioApp {
|
|||||||
SceneManager* scene_manager;
|
SceneManager* scene_manager;
|
||||||
Widget* widget;
|
Widget* widget;
|
||||||
DialogEx* dialog;
|
DialogEx* dialog;
|
||||||
|
Power* power;
|
||||||
|
|
||||||
VariableItemList* var_item_list;
|
VariableItemList* var_item_list;
|
||||||
VariableItem* var_item_flow;
|
VariableItem* var_item_flow;
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ void gpio_scene_start_on_enter(void* context) {
|
|||||||
GpioOtgSettingsNum,
|
GpioOtgSettingsNum,
|
||||||
gpio_scene_start_var_list_change_callback,
|
gpio_scene_start_var_list_change_callback,
|
||||||
app);
|
app);
|
||||||
if(furi_hal_power_is_otg_enabled()) {
|
if(power_is_otg_enabled(app->power)) {
|
||||||
variable_item_set_current_value_index(item, GpioOtgOn);
|
variable_item_set_current_value_index(item, GpioOtgOn);
|
||||||
variable_item_set_current_value_text(item, gpio_otg_text[GpioOtgOn]);
|
variable_item_set_current_value_text(item, gpio_otg_text[GpioOtgOn]);
|
||||||
} else {
|
} else {
|
||||||
@@ -80,9 +80,9 @@ bool gpio_scene_start_on_event(void* context, SceneManagerEvent event) {
|
|||||||
|
|
||||||
if(event.type == SceneManagerEventTypeCustom) {
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
if(event.event == GpioStartEventOtgOn) {
|
if(event.event == GpioStartEventOtgOn) {
|
||||||
furi_hal_power_enable_otg();
|
power_enable_otg(app->power, true);
|
||||||
} else if(event.event == GpioStartEventOtgOff) {
|
} else if(event.event == GpioStartEventOtgOff) {
|
||||||
furi_hal_power_disable_otg();
|
power_enable_otg(app->power, false);
|
||||||
} else if(event.event == GpioStartEventManualControl) {
|
} else if(event.event == GpioStartEventManualControl) {
|
||||||
scene_manager_set_scene_state(app->scene_manager, GpioSceneStart, GpioItemTest);
|
scene_manager_set_scene_state(app->scene_manager, GpioSceneStart, GpioItemTest);
|
||||||
scene_manager_next_scene(app->scene_manager, GpioSceneTest);
|
scene_manager_next_scene(app->scene_manager, GpioSceneTest);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "infrared_app_i.h"
|
#include "infrared_app_i.h"
|
||||||
|
|
||||||
#include <furi_hal_power.h>
|
#include <power/power_service/power.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <toolbox/path.h>
|
#include <toolbox/path.h>
|
||||||
@@ -501,12 +501,12 @@ void infrared_set_tx_pin(InfraredApp* infrared, FuriHalInfraredTxPin tx_pin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void infrared_enable_otg(InfraredApp* infrared, bool enable) {
|
void infrared_enable_otg(InfraredApp* infrared, bool enable) {
|
||||||
if(enable) {
|
Power* power = furi_record_open(RECORD_POWER);
|
||||||
furi_hal_power_enable_otg();
|
|
||||||
} else {
|
power_enable_otg(power, enable);
|
||||||
furi_hal_power_disable_otg();
|
|
||||||
}
|
|
||||||
infrared->app_state.is_otg_enabled = enable;
|
infrared->app_state.is_otg_enabled = enable;
|
||||||
|
|
||||||
|
furi_record_close(RECORD_POWER);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void infrared_load_settings(InfraredApp* infrared) {
|
static void infrared_load_settings(InfraredApp* infrared) {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <furi_hal.h>
|
#include <furi_hal.h>
|
||||||
|
|
||||||
|
#include <power/power_service/power.h>
|
||||||
|
|
||||||
#include <cli/cli.h>
|
#include <cli/cli.h>
|
||||||
#include <toolbox/args.h>
|
#include <toolbox/args.h>
|
||||||
|
|
||||||
@@ -26,13 +28,14 @@ static void onewire_cli_print_usage(void) {
|
|||||||
static void onewire_cli_search(Cli* cli) {
|
static void onewire_cli_search(Cli* cli) {
|
||||||
UNUSED(cli);
|
UNUSED(cli);
|
||||||
OneWireHost* onewire = onewire_host_alloc(&gpio_ibutton);
|
OneWireHost* onewire = onewire_host_alloc(&gpio_ibutton);
|
||||||
|
Power* power = furi_record_open(RECORD_POWER);
|
||||||
uint8_t address[8];
|
uint8_t address[8];
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
printf("Search started\r\n");
|
printf("Search started\r\n");
|
||||||
|
|
||||||
onewire_host_start(onewire);
|
onewire_host_start(onewire);
|
||||||
furi_hal_power_enable_otg();
|
power_enable_otg(power, true);
|
||||||
|
|
||||||
while(!done) {
|
while(!done) {
|
||||||
if(onewire_host_search(onewire, address, OneWireHostSearchModeNormal) != 1) {
|
if(onewire_host_search(onewire, address, OneWireHostSearchModeNormal) != 1) {
|
||||||
@@ -49,8 +52,10 @@ static void onewire_cli_search(Cli* cli) {
|
|||||||
furi_delay_ms(100);
|
furi_delay_ms(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
furi_hal_power_disable_otg();
|
power_enable_otg(power, false);
|
||||||
|
|
||||||
onewire_host_free(onewire);
|
onewire_host_free(onewire);
|
||||||
|
furi_record_close(RECORD_POWER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onewire_cli(Cli* cli, FuriString* args, void* context) {
|
void onewire_cli(Cli* cli, FuriString* args, void* context) {
|
||||||
|
|||||||
@@ -4,27 +4,22 @@
|
|||||||
#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
|
#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
|
||||||
#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
|
#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
|
||||||
|
|
||||||
|
#include <power/power_service/power.h>
|
||||||
|
|
||||||
#define TAG "SubGhz"
|
#define TAG "SubGhz"
|
||||||
|
|
||||||
static void subghz_txrx_radio_device_power_on(SubGhzTxRx* instance) {
|
static void subghz_txrx_radio_device_power_on(SubGhzTxRx* instance) {
|
||||||
UNUSED(instance);
|
UNUSED(instance);
|
||||||
uint8_t attempts = 5;
|
Power* power = furi_record_open(RECORD_POWER);
|
||||||
while(--attempts > 0) {
|
power_enable_otg(power, true);
|
||||||
if(furi_hal_power_enable_otg()) break;
|
furi_record_close(RECORD_POWER);
|
||||||
}
|
|
||||||
if(attempts == 0) {
|
|
||||||
if(furi_hal_power_get_usb_voltage() < 4.5f) {
|
|
||||||
FURI_LOG_E(
|
|
||||||
TAG,
|
|
||||||
"Error power otg enable. BQ2589 check otg fault = %d",
|
|
||||||
furi_hal_power_check_otg_fault() ? 1 : 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subghz_txrx_radio_device_power_off(SubGhzTxRx* instance) {
|
static void subghz_txrx_radio_device_power_off(SubGhzTxRx* instance) {
|
||||||
UNUSED(instance);
|
UNUSED(instance);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
SubGhzTxRx* subghz_txrx_alloc(void) {
|
SubGhzTxRx* subghz_txrx_alloc(void) {
|
||||||
|
|||||||
@@ -28,22 +28,15 @@
|
|||||||
#define TAG "SubGhzCli"
|
#define TAG "SubGhzCli"
|
||||||
|
|
||||||
static void subghz_cli_radio_device_power_on(void) {
|
static void subghz_cli_radio_device_power_on(void) {
|
||||||
uint8_t attempts = 5;
|
Power* power = furi_record_open(RECORD_POWER);
|
||||||
while(--attempts > 0) {
|
power_enable_otg(power, true);
|
||||||
if(furi_hal_power_enable_otg()) break;
|
furi_record_close(RECORD_POWER);
|
||||||
}
|
|
||||||
if(attempts == 0) {
|
|
||||||
if(furi_hal_power_get_usb_voltage() < 4.5f) {
|
|
||||||
FURI_LOG_E(
|
|
||||||
"TAG",
|
|
||||||
"Error power otg enable. BQ2589 check otg fault = %d",
|
|
||||||
furi_hal_power_check_otg_fault() ? 1 : 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subghz_cli_radio_device_power_off(void) {
|
static void subghz_cli_radio_device_power_off(void) {
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SubGhzEnvironment* subghz_cli_environment_init(void) {
|
static SubGhzEnvironment* subghz_cli_environment_init(void) {
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
#include "rpc/rpc_app.h"
|
#include "rpc/rpc_app.h"
|
||||||
|
|
||||||
|
#include <power/power_service/power.h>
|
||||||
|
|
||||||
#include "helpers/subghz_threshold_rssi.h"
|
#include "helpers/subghz_threshold_rssi.h"
|
||||||
|
|
||||||
#include "helpers/subghz_txrx.h"
|
#include "helpers/subghz_txrx.h"
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include "expansion_worker.h"
|
#include "expansion_worker.h"
|
||||||
|
|
||||||
|
#include <power/power_service/power.h>
|
||||||
#include <furi_hal_power.h>
|
#include <furi_hal_power.h>
|
||||||
|
|
||||||
#include <furi_hal_serial.h>
|
#include <furi_hal_serial.h>
|
||||||
#include <furi_hal_serial_control.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;
|
if(!expansion_worker_rpc_session_open(instance)) break;
|
||||||
instance->state = ExpansionWorkerStateRpcActive;
|
instance->state = ExpansionWorkerStateRpcActive;
|
||||||
} else if(command == ExpansionFrameControlCommandEnableOtg) {
|
} else if(command == ExpansionFrameControlCommandEnableOtg) {
|
||||||
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) {
|
} else if(command == ExpansionFrameControlCommandDisableOtg) {
|
||||||
furi_hal_power_disable_otg();
|
Power* power = furi_record_open(RECORD_POWER);
|
||||||
|
power_enable_otg(power, false);
|
||||||
|
furi_record_close(RECORD_POWER);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,13 +30,16 @@ void power_cli_reboot2dfu(Cli* cli, FuriString* args) {
|
|||||||
|
|
||||||
void power_cli_5v(Cli* cli, FuriString* args) {
|
void power_cli_5v(Cli* cli, FuriString* args) {
|
||||||
UNUSED(cli);
|
UNUSED(cli);
|
||||||
|
Power* power = furi_record_open(RECORD_POWER);
|
||||||
if(!furi_string_cmp(args, "0")) {
|
if(!furi_string_cmp(args, "0")) {
|
||||||
furi_hal_power_disable_otg();
|
power_enable_otg(power, false);
|
||||||
} else if(!furi_string_cmp(args, "1")) {
|
} else if(!furi_string_cmp(args, "1")) {
|
||||||
furi_hal_power_enable_otg();
|
power_enable_otg(power, true);
|
||||||
} else {
|
} else {
|
||||||
cli_print_usage("power_otg", "<1|0>", furi_string_get_cstr(args));
|
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) {
|
void power_cli_3v3(Cli* cli, FuriString* args) {
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ static bool power_update_info(Power* power) {
|
|||||||
.is_charging = furi_hal_power_is_charging(),
|
.is_charging = furi_hal_power_is_charging(),
|
||||||
.gauge_is_ok = furi_hal_power_gauge_is_ok(),
|
.gauge_is_ok = furi_hal_power_gauge_is_ok(),
|
||||||
.is_shutdown_requested = furi_hal_power_is_shutdown_requested(),
|
.is_shutdown_requested = furi_hal_power_is_shutdown_requested(),
|
||||||
|
.is_otg_enabled = furi_hal_power_is_otg_enabled(),
|
||||||
.charge = furi_hal_power_get_pct(),
|
.charge = furi_hal_power_get_pct(),
|
||||||
.health = furi_hal_power_get_bat_health_pct(),
|
.health = furi_hal_power_get_bat_health_pct(),
|
||||||
.capacity_remaining = furi_hal_power_get_battery_remaining_capacity(),
|
.capacity_remaining = furi_hal_power_get_battery_remaining_capacity(),
|
||||||
@@ -216,6 +217,30 @@ static void power_message_callback(FuriEventLoopObject* object, void* context) {
|
|||||||
case PowerMessageTypeShowBatteryLowWarning:
|
case PowerMessageTypeShowBatteryLowWarning:
|
||||||
power->show_battery_low_warning = *msg.bool_param;
|
power->show_battery_low_warning = *msg.bool_param;
|
||||||
break;
|
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:
|
default:
|
||||||
furi_crash();
|
furi_crash();
|
||||||
}
|
}
|
||||||
@@ -241,9 +266,18 @@ static void power_tick_callback(void* context) {
|
|||||||
if(need_refresh) {
|
if(need_refresh) {
|
||||||
view_port_update(power->battery_view_port);
|
view_port_update(power->battery_view_port);
|
||||||
}
|
}
|
||||||
// Check OTG status and disable it in case of fault
|
// Check OTG status, disable in case of a fault
|
||||||
if(furi_hal_power_is_otg_enabled()) {
|
if(furi_hal_power_check_otg_fault()) {
|
||||||
furi_hal_power_check_otg_status();
|
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 gauge_is_ok;
|
||||||
bool is_charging;
|
bool is_charging;
|
||||||
bool is_shutdown_requested;
|
bool is_shutdown_requested;
|
||||||
|
bool is_otg_enabled;
|
||||||
|
|
||||||
float current_charger;
|
float current_charger;
|
||||||
float current_gauge;
|
float current_gauge;
|
||||||
@@ -96,6 +97,19 @@ bool power_is_battery_healthy(Power* power);
|
|||||||
*/
|
*/
|
||||||
void power_enable_low_battery_level_notification(Power* power, bool enable);
|
void power_enable_low_battery_level_notification(Power* power, bool enable);
|
||||||
|
|
||||||
|
/** 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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -70,3 +70,22 @@ void power_enable_low_battery_level_notification(Power* power, bool enable) {
|
|||||||
furi_check(
|
furi_check(
|
||||||
furi_message_queue_put(power->message_queue, &msg, FuriWaitForever) == FuriStatusOk);
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ struct Power {
|
|||||||
|
|
||||||
bool battery_low;
|
bool battery_low;
|
||||||
bool show_battery_low_warning;
|
bool show_battery_low_warning;
|
||||||
|
bool is_otg_requested;
|
||||||
uint8_t battery_level;
|
uint8_t battery_level;
|
||||||
uint8_t power_off_timeout;
|
uint8_t power_off_timeout;
|
||||||
};
|
};
|
||||||
@@ -48,6 +49,7 @@ typedef enum {
|
|||||||
PowerMessageTypeGetInfo,
|
PowerMessageTypeGetInfo,
|
||||||
PowerMessageTypeIsBatteryHealthy,
|
PowerMessageTypeIsBatteryHealthy,
|
||||||
PowerMessageTypeShowBatteryLowWarning,
|
PowerMessageTypeShowBatteryLowWarning,
|
||||||
|
PowerMessageTypeSwitchOTG,
|
||||||
} PowerMessageType;
|
} PowerMessageType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <furi_hal_gpio.h>
|
#include <furi_hal_gpio.h>
|
||||||
#include <furi_hal_power.h>
|
#include <furi_hal_power.h>
|
||||||
#include <furi_hal_resources.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) {
|
static const GpioPin* rpc_pin_to_hal_pin(PB_Gpio_GpioPin rpc_pin) {
|
||||||
switch(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;
|
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(mode == PB_Gpio_GpioOtgMode_OFF) {
|
||||||
furi_hal_power_disable_otg();
|
power_enable_otg(power, false);
|
||||||
} else {
|
} else {
|
||||||
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);
|
rpc_send_and_release_empty(session, request->command_id, PB_CommandStatus_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
#include "ibutton_worker_i.h"
|
#include "ibutton_worker_i.h"
|
||||||
|
|
||||||
#include <core/check.h>
|
#include <core/check.h>
|
||||||
|
#include <core/record.h>
|
||||||
|
|
||||||
#include <furi_hal_rfid.h>
|
#include <furi_hal_rfid.h>
|
||||||
#include <furi_hal_power.h>
|
#include <power/power_service/power.h>
|
||||||
|
|
||||||
#include "ibutton_protocols.h"
|
#include "ibutton_protocols.h"
|
||||||
|
|
||||||
@@ -75,7 +76,9 @@ void ibutton_worker_mode_idle_stop(iButtonWorker* worker) {
|
|||||||
|
|
||||||
void ibutton_worker_mode_read_start(iButtonWorker* worker) {
|
void ibutton_worker_mode_read_start(iButtonWorker* worker) {
|
||||||
UNUSED(worker);
|
UNUSED(worker);
|
||||||
furi_hal_power_enable_otg();
|
Power* power = furi_record_open(RECORD_POWER);
|
||||||
|
power_enable_otg(power, true);
|
||||||
|
furi_record_close(RECORD_POWER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ibutton_worker_mode_read_tick(iButtonWorker* worker) {
|
void ibutton_worker_mode_read_tick(iButtonWorker* worker) {
|
||||||
@@ -90,7 +93,9 @@ void ibutton_worker_mode_read_tick(iButtonWorker* worker) {
|
|||||||
|
|
||||||
void ibutton_worker_mode_read_stop(iButtonWorker* worker) {
|
void ibutton_worker_mode_read_stop(iButtonWorker* worker) {
|
||||||
UNUSED(worker);
|
UNUSED(worker);
|
||||||
furi_hal_power_disable_otg();
|
Power* power = furi_record_open(RECORD_POWER);
|
||||||
|
power_enable_otg(power, false);
|
||||||
|
furi_record_close(RECORD_POWER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************** EMULATE ***********************/
|
/*********************** EMULATE ***********************/
|
||||||
@@ -120,7 +125,9 @@ void ibutton_worker_mode_emulate_stop(iButtonWorker* worker) {
|
|||||||
|
|
||||||
void ibutton_worker_mode_write_common_start(iButtonWorker* worker) { //-V524
|
void ibutton_worker_mode_write_common_start(iButtonWorker* worker) { //-V524
|
||||||
UNUSED(worker);
|
UNUSED(worker);
|
||||||
furi_hal_power_enable_otg();
|
Power* power = furi_record_open(RECORD_POWER);
|
||||||
|
power_enable_otg(power, true);
|
||||||
|
furi_record_close(RECORD_POWER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ibutton_worker_mode_write_id_tick(iButtonWorker* worker) {
|
void ibutton_worker_mode_write_id_tick(iButtonWorker* worker) {
|
||||||
@@ -149,5 +156,7 @@ void ibutton_worker_mode_write_copy_tick(iButtonWorker* worker) {
|
|||||||
|
|
||||||
void ibutton_worker_mode_write_common_stop(iButtonWorker* worker) { //-V524
|
void ibutton_worker_mode_write_common_stop(iButtonWorker* worker) { //-V524
|
||||||
UNUSED(worker);
|
UNUSED(worker);
|
||||||
furi_hal_power_disable_otg();
|
Power* power = furi_record_open(RECORD_POWER);
|
||||||
|
power_enable_otg(power, false);
|
||||||
|
furi_record_close(RECORD_POWER);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ static bool subghz_protocol_secplus_v1_encode(SubGhzProtocolEncoderSecPlus_v1* i
|
|||||||
rolling = 0xE6000000;
|
rolling = 0xE6000000;
|
||||||
}
|
}
|
||||||
if(fixed > 0xCFD41B90) {
|
if(fixed > 0xCFD41B90) {
|
||||||
FURI_LOG_E("TAG", "Encode wrong fixed data");
|
FURI_LOG_E(TAG, "Encode wrong fixed data");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class Main(App):
|
|||||||
|
|
||||||
FLASH_BASE = 0x8000000
|
FLASH_BASE = 0x8000000
|
||||||
FLASH_PAGE_SIZE = 4 * 1024
|
FLASH_PAGE_SIZE = 4 * 1024
|
||||||
MIN_GAP_PAGES = 2
|
MIN_GAP_PAGES = 1
|
||||||
|
|
||||||
# Update stage file larger than that is not loadable without fix
|
# Update stage file larger than that is not loadable without fix
|
||||||
# https://github.com/flipperdevices/flipperzero-firmware/pull/3676
|
# https://github.com/flipperdevices/flipperzero-firmware/pull/3676
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,80.2,,
|
Version,+,80.3,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
||||||
Header,+,applications/services/cli/cli.h,,
|
Header,+,applications/services/cli/cli.h,,
|
||||||
@@ -2362,8 +2362,10 @@ Function,+,power_enable_low_battery_level_notification,void,"Power*, _Bool"
|
|||||||
Function,+,power_get_info,void,"Power*, PowerInfo*"
|
Function,+,power_get_info,void,"Power*, PowerInfo*"
|
||||||
Function,+,power_get_pubsub,FuriPubSub*,Power*
|
Function,+,power_get_pubsub,FuriPubSub*,Power*
|
||||||
Function,+,power_is_battery_healthy,_Bool,Power*
|
Function,+,power_is_battery_healthy,_Bool,Power*
|
||||||
|
Function,+,power_is_otg_enabled,_Bool,Power*
|
||||||
Function,+,power_off,void,Power*
|
Function,+,power_off,void,Power*
|
||||||
Function,+,power_reboot,void,"Power*, PowerBootMode"
|
Function,+,power_reboot,void,"Power*, PowerBootMode"
|
||||||
|
Function,+,power_enable_otg,void,"Power*, _Bool"
|
||||||
Function,+,powf,float,"float, float"
|
Function,+,powf,float,"float, float"
|
||||||
Function,-,powl,long double,"long double, long double"
|
Function,-,powl,long double,"long double, long double"
|
||||||
Function,+,pretty_format_bytes_hex_canonical,void,"FuriString*, size_t, const char*, const uint8_t*, size_t"
|
Function,+,pretty_format_bytes_hex_canonical,void,"FuriString*, size_t, const char*, const uint8_t*, size_t"
|
||||||
|
|||||||
|
@@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,80.2,,
|
Version,+,80.3,,
|
||||||
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
|
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
||||||
@@ -2999,8 +2999,10 @@ Function,+,power_enable_low_battery_level_notification,void,"Power*, _Bool"
|
|||||||
Function,+,power_get_info,void,"Power*, PowerInfo*"
|
Function,+,power_get_info,void,"Power*, PowerInfo*"
|
||||||
Function,+,power_get_pubsub,FuriPubSub*,Power*
|
Function,+,power_get_pubsub,FuriPubSub*,Power*
|
||||||
Function,+,power_is_battery_healthy,_Bool,Power*
|
Function,+,power_is_battery_healthy,_Bool,Power*
|
||||||
|
Function,+,power_is_otg_enabled,_Bool,Power*
|
||||||
Function,+,power_off,void,Power*
|
Function,+,power_off,void,Power*
|
||||||
Function,+,power_reboot,void,"Power*, PowerBootMode"
|
Function,+,power_reboot,void,"Power*, PowerBootMode"
|
||||||
|
Function,+,power_enable_otg,void,"Power*, _Bool"
|
||||||
Function,+,powf,float,"float, float"
|
Function,+,powf,float,"float, float"
|
||||||
Function,-,powl,long double,"long double, long double"
|
Function,-,powl,long double,"long double, long double"
|
||||||
Function,+,pretty_format_bytes_hex_canonical,void,"FuriString*, size_t, const char*, const uint8_t*, size_t"
|
Function,+,pretty_format_bytes_hex_canonical,void,"FuriString*, size_t, const char*, const uint8_t*, size_t"
|
||||||
|
|||||||
|
@@ -105,10 +105,14 @@ void furi_hal_power_off(void);
|
|||||||
FURI_NORETURN void furi_hal_power_reset(void);
|
FURI_NORETURN void furi_hal_power_reset(void);
|
||||||
|
|
||||||
/** OTG enable
|
/** OTG enable
|
||||||
|
*
|
||||||
|
* @warning this is low level control, use power service instead
|
||||||
*/
|
*/
|
||||||
bool furi_hal_power_enable_otg(void);
|
bool furi_hal_power_enable_otg(void);
|
||||||
|
|
||||||
/** OTG disable
|
/** OTG disable
|
||||||
|
*
|
||||||
|
* @warning this is low level control, use power service instead
|
||||||
*/
|
*/
|
||||||
void furi_hal_power_disable_otg(void);
|
void furi_hal_power_disable_otg(void);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user