Skip to content

Commit

Permalink
[FL-3226] Deep Sleep Idle (#2569)
Browse files Browse the repository at this point in the history
* Improve RNG error handling
* Sync RTC shadow registers on Stop mode exit
* Implement working STOP2 mode
* Fix formatting
* FuriHal: disable SWD pins if debug is disabled
* Power: cleanup battery info view, handle zero current report from gauge
* Fbt: add command line argument for extra global defines
* FuriHal: cleanup debug defines in power and os, drop deep_insomnia counter.
* Add a setting to disable deep sleep
* Clean up furi_hal_power
* FuriHal,FapLoader,Debug: implement debug in stop mode, workaround resume in stop
* FuriHal: document OS and power subsystems debugging
* Furi: enable debug interface on crash

---------

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
  • Loading branch information
gsurkov and skotopes authored Apr 13, 2023
1 parent 5d7bdca commit 37fb330
Show file tree
Hide file tree
Showing 26 changed files with 246 additions and 120 deletions.
5 changes: 2 additions & 3 deletions applications/main/fap_loader/fap_loader_app.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "fap_loader_app.h"

#include <furi.h>
#include <furi_hal_debug.h>

#include <assets_icons.h>
#include <gui/gui.h>
Expand All @@ -23,8 +24,6 @@ struct FapLoader {
Loading* loading;
};

volatile bool fap_loader_debug_active = false;

bool fap_loader_load_name_and_icon(
FuriString* path,
Storage* storage,
Expand Down Expand Up @@ -111,7 +110,7 @@ static bool fap_loader_run_selected_app(FapLoader* loader) {
FuriThread* thread = flipper_application_spawn(loader->app, NULL);

/* This flag is set by the debugger - to break on app start */
if(fap_loader_debug_active) {
if(furi_hal_debug_is_gdb_session_active()) {
FURI_LOG_W(TAG, "Triggering BP for debugger");
/* After hitting this, you can set breakpoints in your .fap's code
* Note that you have to toggle breakpoints that were set before */
Expand Down
51 changes: 26 additions & 25 deletions applications/settings/power_settings_app/views/battery_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
#include <assets_icons.h>
#include <locale/locale.h>

#define LOW_CHARGE_THRESHOLD 10
#define HIGH_DRAIN_CURRENT_THRESHOLD 100
#define LOW_CHARGE_THRESHOLD (10)
#define HIGH_DRAIN_CURRENT_THRESHOLD (-100)

struct BatteryInfo {
View* view;
Expand All @@ -25,14 +25,13 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) {
char header[20] = {};
char value[20] = {};

int32_t drain_current = data->gauge_current * (-1000);
uint32_t charge_current = data->gauge_current * 1000;
int32_t current = 1000.0f * data->gauge_current;

// Draw battery
canvas_draw_icon(canvas, x, y, &I_BatteryBody_52x28);
if(charge_current > 0) {
if(current > 0) {
canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceCharging_29x14);
} else if(drain_current > HIGH_DRAIN_CURRENT_THRESHOLD) {
} else if(current < HIGH_DRAIN_CURRENT_THRESHOLD) {
canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceConfused_29x14);
} else if(data->charge < LOW_CHARGE_THRESHOLD) {
canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceNopower_29x14);
Expand All @@ -44,7 +43,7 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) {
elements_bubble(canvas, 53, 0, 71, 39);

// Set text
if(charge_current > 0) {
if(current > 0) {
snprintf(emote, sizeof(emote), "%s", "Yummy!");
snprintf(header, sizeof(header), "%s", "Charging at");
snprintf(
Expand All @@ -53,34 +52,36 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) {
"%lu.%luV %lumA",
(uint32_t)(data->vbus_voltage),
(uint32_t)(data->vbus_voltage * 10) % 10,
charge_current);
} else if(drain_current > 0) {
current);
} else if(current < 0) {
snprintf(
emote,
sizeof(emote),
"%s",
drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "Oh no!" : "Om-nom-nom!");
current < HIGH_DRAIN_CURRENT_THRESHOLD ? "Oh no!" : "Om-nom-nom!");
snprintf(header, sizeof(header), "%s", "Consumption is");
snprintf(
value,
sizeof(value),
"%ld %s",
drain_current,
drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA");
} else if(drain_current != 0) {
snprintf(header, 20, "...");
} else if(data->charge_voltage_limit < 4.2) {
// Non-default battery charging limit, mention it
snprintf(emote, sizeof(emote), "Charged!");
snprintf(header, sizeof(header), "Limited to");
snprintf(
value,
sizeof(value),
"%lu.%luV",
(uint32_t)(data->charge_voltage_limit),
(uint32_t)(data->charge_voltage_limit * 10) % 10);
ABS(current),
current < HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA");
} else if(data->vbus_voltage > 0) {
if(data->charge_voltage_limit < 4.2) {
// Non-default battery charging limit, mention it
snprintf(emote, sizeof(emote), "Charged!");
snprintf(header, sizeof(header), "Limited to");
snprintf(
value,
sizeof(value),
"%lu.%luV",
(uint32_t)(data->charge_voltage_limit),
(uint32_t)(data->charge_voltage_limit * 10) % 10);
} else {
snprintf(header, sizeof(header), "Charged!");
}
} else {
snprintf(header, sizeof(header), "Charged!");
snprintf(header, sizeof(header), "Napping...");
}

canvas_draw_str_aligned(canvas, 92, y + 3, AlignCenter, AlignCenter, emote);
Expand Down
21 changes: 21 additions & 0 deletions applications/settings/system/system_settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,21 @@ static void hand_orient_changed(VariableItem* item) {
loader_update_menu();
}

const char* const sleep_method[] = {
"Default",
"Legacy",
};

static void sleep_method_changed(VariableItem* item) {
uint8_t index = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, sleep_method[index]);
if(index) {
furi_hal_rtc_set_flag(FuriHalRtcFlagLegacySleep);
} else {
furi_hal_rtc_reset_flag(FuriHalRtcFlagLegacySleep);
}
}

static uint32_t system_settings_exit(void* context) {
UNUSED(context);
return VIEW_NONE;
Expand Down Expand Up @@ -218,6 +233,12 @@ SystemSettings* system_settings_alloc() {
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, heap_trace_mode_text[value_index]);

item = variable_item_list_add(
app->var_item_list, "Sleep Method", COUNT_OF(sleep_method), sleep_method_changed, app);
value_index = furi_hal_rtc_is_flag_set(FuriHalRtcFlagLegacySleep) ? 1 : 0;
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, sleep_method[value_index]);

view_set_previous_callback(
variable_item_list_get_view(app->var_item_list), system_settings_exit);
view_dispatcher_add_view(
Expand Down
3 changes: 2 additions & 1 deletion debug/flipperapps.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ def __init__(self):
self.app_list_ptr = None
self.app_list_entry_type = None
self._current_apps: list[AppState] = []
self.set_debug_mode(True)

def _walk_app_list(self, list_head):
while list_head:
Expand Down Expand Up @@ -195,7 +196,7 @@ def handle_exit(self, event) -> None:
self.set_debug_mode(False)

def set_debug_mode(self, mode: bool) -> None:
gdb.execute(f"set variable fap_loader_debug_active = {int(mode)}")
gdb.execute(f"set variable furi_hal_debug_gdb_session_active = {int(mode)}")


# Init additional 'fap-set-debug-elf-root' command and set up hooks
Expand Down
26 changes: 26 additions & 0 deletions documentation/FuriHalDebuging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Furi HAL Debugging

Some Furi subsystem got additional debugging features that can be enabled by adding additional defines to firmware compilation.
Usually they are used for low level tracing and profiling or signal redirection/duplication.


## FuriHalOs

`--extra-define=FURI_HAL_OS_DEBUG` enables tick, tick suppression, idle and time flow.

There are 3 signals that will be exposed to external GPIO pins:

- `AWAKE` - `PA7` - High when system is busy with computations, low when sleeping. Can be used to track transitions to sleep mode.
- `TICK` - `PA6` - Flipped on system tick, only flips when no tick suppression in progress. Can be used to track tick skew and abnormal task scheduling.
- `SECOND` - `PA4` - Flipped each second. Can be used for tracing RT issue: time flow disturbance means system doesn't conforms Hard RT.



## FuriHalPower

`--extra-define=FURI_HAL_POWER_DEBUG` enables power subsystem mode transitions tracing.

There are 2 signals that will be exposed to external GPIO pins:

- `WFI` - `PB2` - Light sleep (wait for interrupt) used. Basically this is lightest and most non-breaking things power save mode. All function and debug should work correctly in this mode.
- `STOP` - `PC3` - STOP mode used. Platform deep sleep mode. Extremely fragile mode where most of the silicon is disabled or in unusable state. Debugging MCU in this mode is nearly impossible.
1 change: 1 addition & 0 deletions documentation/fbt.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ To run cleanup (think of `make clean`) for specified targets, add the `-c` optio
- `--options optionfile.py` (default value `fbt_options.py`) - load a file with multiple configuration values
- `--extra-int-apps=app1,app2,appN` - force listed apps to be built as internal with the `firmware` target
- `--extra-ext-apps=app1,app2,appN` - force listed apps to be built as external with the `firmware_extapps` target
- `--extra-define=A --extra-define=B=C ` - extra global defines that will be passed to the C/C++ compiler, can be specified multiple times
- `--proxy-env=VAR1,VAR2` - additional environment variables to expose to subprocesses spawned by `fbt`. By default, `fbt` sanitizes the execution environment and doesn't forward all inherited environment variables. You can find the list of variables that are always forwarded in the `environ.scons` file.

## Configuration
Expand Down
13 changes: 8 additions & 5 deletions firmware/targets/f18/api_symbols.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,21.0,,
Version,+,22.0,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,,
Expand Down Expand Up @@ -901,6 +901,7 @@ Function,+,furi_hal_crypto_verify_enclave,_Bool,"uint8_t*, uint8_t*"
Function,+,furi_hal_crypto_verify_key,_Bool,uint8_t
Function,+,furi_hal_debug_disable,void,
Function,+,furi_hal_debug_enable,void,
Function,+,furi_hal_debug_is_gdb_session_active,_Bool,
Function,-,furi_hal_deinit_early,void,
Function,-,furi_hal_flash_erase,void,uint8_t
Function,-,furi_hal_flash_get_base,size_t,
Expand Down Expand Up @@ -983,7 +984,6 @@ Function,-,furi_hal_os_init,void,
Function,+,furi_hal_os_tick,void,
Function,+,furi_hal_power_check_otg_status,void,
Function,+,furi_hal_power_debug_get,void,"PropertyValueCallback, void*"
Function,+,furi_hal_power_deep_sleep_available,_Bool,
Function,+,furi_hal_power_disable_external_3_3v,void,
Function,+,furi_hal_power_disable_otg,void,
Function,+,furi_hal_power_enable_external_3_3v,void,
Expand Down Expand Up @@ -1059,6 +1059,7 @@ Function,+,furi_hal_rtc_set_locale_units,void,FuriHalRtcLocaleUnits
Function,+,furi_hal_rtc_set_log_level,void,uint8_t
Function,+,furi_hal_rtc_set_pin_fails,void,uint32_t
Function,+,furi_hal_rtc_set_register,void,"FuriHalRtcRegister, uint32_t"
Function,+,furi_hal_rtc_sync_shadow,void,
Function,+,furi_hal_rtc_validate_datetime,_Bool,FuriHalRtcDateTime*
Function,+,furi_hal_speaker_acquire,_Bool,uint32_t
Function,-,furi_hal_speaker_deinit,void,
Expand Down Expand Up @@ -2149,6 +2150,8 @@ Variable,+,gpio_ext_pd0,const GpioPin,
Variable,+,gpio_ext_pe4,const GpioPin,
Variable,+,gpio_i2c_power_scl,const GpioPin,
Variable,+,gpio_i2c_power_sda,const GpioPin,
Variable,+,gpio_ibutton,const GpioPin,
Variable,+,gpio_periph_power,const GpioPin,
Variable,+,gpio_pins,const GpioPinRecord[],
Variable,+,gpio_pins_count,const size_t,
Variable,+,gpio_sdcard_cd,const GpioPin,
Expand All @@ -2157,11 +2160,13 @@ Variable,+,gpio_speaker,const GpioPin,
Variable,+,gpio_spi_d_miso,const GpioPin,
Variable,+,gpio_spi_d_mosi,const GpioPin,
Variable,+,gpio_spi_d_sck,const GpioPin,
Variable,+,gpio_swclk,const GpioPin,
Variable,+,gpio_swdio,const GpioPin,
Variable,+,gpio_usart_rx,const GpioPin,
Variable,+,gpio_usart_tx,const GpioPin,
Variable,+,gpio_usb_dm,const GpioPin,
Variable,+,gpio_usb_dp,const GpioPin,
Variable,+,gpio_ibutton,const GpioPin,
Variable,+,gpio_vibro,const GpioPin,
Variable,+,input_pins,const InputPin[],
Variable,+,input_pins_count,const size_t,
Variable,+,message_blink_set_color_blue,const NotificationMessage,
Expand Down Expand Up @@ -2309,7 +2314,6 @@ Variable,+,message_red_255,const NotificationMessage,
Variable,+,message_sound_off,const NotificationMessage,
Variable,+,message_vibro_off,const NotificationMessage,
Variable,+,message_vibro_on,const NotificationMessage,
Variable,+,gpio_periph_power,const GpioPin,
Variable,+,sequence_audiovisual_alert,const NotificationSequence,
Variable,+,sequence_blink_blue_10,const NotificationSequence,
Variable,+,sequence_blink_blue_100,const NotificationSequence,
Expand Down Expand Up @@ -2364,4 +2368,3 @@ Variable,+,usb_cdc_single,FuriHalUsbInterface,
Variable,+,usb_hid,FuriHalUsbInterface,
Variable,+,usb_hid_u2f,FuriHalUsbInterface,
Variable,+,usbd_devfs,const usbd_driver,
Variable,+,gpio_vibro,const GpioPin,
3 changes: 3 additions & 0 deletions firmware/targets/f18/furi_hal/furi_hal_resources.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

#define TAG "FuriHalResources"

const GpioPin gpio_swdio = {.port = GPIOA, .pin = LL_GPIO_PIN_13};
const GpioPin gpio_swclk = {.port = GPIOA, .pin = LL_GPIO_PIN_14};

const GpioPin gpio_vibro = {.port = GPIOA, .pin = LL_GPIO_PIN_8};
const GpioPin gpio_ibutton = {.port = GPIOB, .pin = LL_GPIO_PIN_14};

Expand Down
3 changes: 3 additions & 0 deletions firmware/targets/f18/furi_hal/furi_hal_resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ extern const size_t input_pins_count;
extern const GpioPinRecord gpio_pins[];
extern const size_t gpio_pins_count;

extern const GpioPin gpio_swdio;
extern const GpioPin gpio_swclk;

extern const GpioPin gpio_vibro;
extern const GpioPin gpio_ibutton;

Expand Down
13 changes: 8 additions & 5 deletions firmware/targets/f7/api_symbols.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,21.0,,
Version,+,22.0,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,,
Expand Down Expand Up @@ -1082,6 +1082,7 @@ Function,+,furi_hal_crypto_verify_enclave,_Bool,"uint8_t*, uint8_t*"
Function,+,furi_hal_crypto_verify_key,_Bool,uint8_t
Function,+,furi_hal_debug_disable,void,
Function,+,furi_hal_debug_enable,void,
Function,+,furi_hal_debug_is_gdb_session_active,_Bool,
Function,-,furi_hal_deinit_early,void,
Function,-,furi_hal_flash_erase,void,uint8_t
Function,-,furi_hal_flash_get_base,size_t,
Expand Down Expand Up @@ -1212,7 +1213,6 @@ Function,-,furi_hal_os_init,void,
Function,+,furi_hal_os_tick,void,
Function,+,furi_hal_power_check_otg_status,void,
Function,+,furi_hal_power_debug_get,void,"PropertyValueCallback, void*"
Function,+,furi_hal_power_deep_sleep_available,_Bool,
Function,+,furi_hal_power_disable_external_3_3v,void,
Function,+,furi_hal_power_disable_otg,void,
Function,+,furi_hal_power_enable_external_3_3v,void,
Expand Down Expand Up @@ -1313,6 +1313,7 @@ Function,+,furi_hal_rtc_set_locale_units,void,FuriHalRtcLocaleUnits
Function,+,furi_hal_rtc_set_log_level,void,uint8_t
Function,+,furi_hal_rtc_set_pin_fails,void,uint32_t
Function,+,furi_hal_rtc_set_register,void,"FuriHalRtcRegister, uint32_t"
Function,+,furi_hal_rtc_sync_shadow,void,
Function,+,furi_hal_rtc_validate_datetime,_Bool,FuriHalRtcDateTime*
Function,+,furi_hal_speaker_acquire,_Bool,uint32_t
Function,-,furi_hal_speaker_deinit,void,
Expand Down Expand Up @@ -3076,10 +3077,12 @@ Variable,+,gpio_ext_pc1,const GpioPin,
Variable,+,gpio_ext_pc3,const GpioPin,
Variable,+,gpio_i2c_power_scl,const GpioPin,
Variable,+,gpio_i2c_power_sda,const GpioPin,
Variable,+,gpio_ibutton,const GpioPin,
Variable,+,gpio_infrared_rx,const GpioPin,
Variable,+,gpio_infrared_tx,const GpioPin,
Variable,+,gpio_nfc_cs,const GpioPin,
Variable,+,gpio_nfc_irq_rfid_pull,const GpioPin,
Variable,+,gpio_periph_power,const GpioPin,
Variable,+,gpio_pins,const GpioPinRecord[],
Variable,+,gpio_pins_count,const size_t,
Variable,+,gpio_rf_sw_0,const GpioPin,
Expand All @@ -3096,11 +3099,13 @@ Variable,+,gpio_spi_r_miso,const GpioPin,
Variable,+,gpio_spi_r_mosi,const GpioPin,
Variable,+,gpio_spi_r_sck,const GpioPin,
Variable,+,gpio_subghz_cs,const GpioPin,
Variable,+,gpio_swclk,const GpioPin,
Variable,+,gpio_swdio,const GpioPin,
Variable,+,gpio_usart_rx,const GpioPin,
Variable,+,gpio_usart_tx,const GpioPin,
Variable,+,gpio_usb_dm,const GpioPin,
Variable,+,gpio_usb_dp,const GpioPin,
Variable,+,gpio_ibutton,const GpioPin,
Variable,+,gpio_vibro,const GpioPin,
Variable,+,input_pins,const InputPin[],
Variable,+,input_pins_count,const size_t,
Variable,+,lfrfid_protocols,const ProtocolBase*[],
Expand Down Expand Up @@ -3249,7 +3254,6 @@ Variable,+,message_red_255,const NotificationMessage,
Variable,+,message_sound_off,const NotificationMessage,
Variable,+,message_vibro_off,const NotificationMessage,
Variable,+,message_vibro_on,const NotificationMessage,
Variable,+,gpio_periph_power,const GpioPin,
Variable,+,sequence_audiovisual_alert,const NotificationSequence,
Variable,+,sequence_blink_blue_10,const NotificationSequence,
Variable,+,sequence_blink_blue_100,const NotificationSequence,
Expand Down Expand Up @@ -3307,4 +3311,3 @@ Variable,+,usb_cdc_single,FuriHalUsbInterface,
Variable,+,usb_hid,FuriHalUsbInterface,
Variable,+,usb_hid_u2f,FuriHalUsbInterface,
Variable,+,usbd_devfs,const usbd_driver,
Variable,+,gpio_vibro,const GpioPin,
6 changes: 0 additions & 6 deletions firmware/targets/f7/ble_glue/ble_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,6 @@ void ble_glue_init() {
ble_glue = malloc(sizeof(BleGlue));
ble_glue->status = BleGlueStatusStartup;

// Configure the system Power Mode
// Select HSI as system clock source after Wake Up from Stop mode
LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI);
/* Initialize the CPU2 reset value before starting CPU2 with C2BOOT */
LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);

#ifdef BLE_GLUE_DEBUG
APPD_Init();
#endif
Expand Down
Loading

0 comments on commit 37fb330

Please sign in to comment.