From 5d7bdca835e83c6925d7802774ac1ffe03766368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Wed, 12 Apr 2023 19:45:13 +0800 Subject: [PATCH 1/9] FuriHal: pwr pulls for some pins (#2579) --- firmware/targets/f18/furi_hal/furi_hal_resources.c | 5 +++-- firmware/targets/f7/furi_hal/furi_hal_resources.c | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/firmware/targets/f18/furi_hal/furi_hal_resources.c b/firmware/targets/f18/furi_hal/furi_hal_resources.c index 19bc9f99840..4a7015d139a 100644 --- a/firmware/targets/f18/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f18/furi_hal/furi_hal_resources.c @@ -166,8 +166,9 @@ void furi_hal_resources_init() { furi_hal_resources_init_input_pins(GpioModeInterruptRiseFall); // Explicit pulls pins - furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullDown, GpioSpeedLow); - furi_hal_gpio_init(&gpio_vibro, GpioModeAnalog, GpioPullDown, GpioSpeedLow); + LL_PWR_EnablePUPDCfg(); + LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_B, LL_PWR_GPIO_BIT_8); // gpio_speaker + LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_A, LL_PWR_GPIO_BIT_8); // gpio_vibro // Display pins furi_hal_gpio_init(&gpio_display_rst_n, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.c b/firmware/targets/f7/furi_hal/furi_hal_resources.c index df9530079c6..912912b4a4a 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c @@ -153,10 +153,11 @@ void furi_hal_resources_init() { // Button pins furi_hal_resources_init_input_pins(GpioModeInterruptRiseFall); - // Explicit pulls pins - furi_hal_gpio_init(&gpio_infrared_tx, GpioModeAnalog, GpioPullDown, GpioSpeedLow); - furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullDown, GpioSpeedLow); - furi_hal_gpio_init(&gpio_vibro, GpioModeAnalog, GpioPullDown, GpioSpeedLow); + // Explicit, surviving reset, pulls + LL_PWR_EnablePUPDCfg(); + LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_B, LL_PWR_GPIO_BIT_9); // gpio_infrared_tx + LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_B, LL_PWR_GPIO_BIT_8); // gpio_speaker + LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_A, LL_PWR_GPIO_BIT_8); // gpio_vibro // Display pins furi_hal_gpio_init(&gpio_display_rst_n, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); From 37fb330b362dba3b01b7c6ca6a200564211dc1b7 Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Thu, 13 Apr 2023 17:47:38 +0300 Subject: [PATCH 2/9] [FL-3226] Deep Sleep Idle (#2569) * 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 --- applications/main/fap_loader/fap_loader_app.c | 5 +- .../power_settings_app/views/battery_info.c | 51 +++++++------- .../settings/system/system_settings.c | 21 ++++++ debug/flipperapps.py | 3 +- documentation/FuriHalDebuging.md | 26 +++++++ documentation/fbt.md | 1 + firmware/targets/f18/api_symbols.csv | 13 ++-- .../targets/f18/furi_hal/furi_hal_resources.c | 3 + .../targets/f18/furi_hal/furi_hal_resources.h | 3 + firmware/targets/f7/api_symbols.csv | 13 ++-- firmware/targets/f7/ble_glue/ble_glue.c | 6 -- firmware/targets/f7/furi_hal/furi_hal_clock.c | 9 ++- firmware/targets/f7/furi_hal/furi_hal_debug.c | 21 ++++++ firmware/targets/f7/furi_hal/furi_hal_os.c | 30 ++++++-- firmware/targets/f7/furi_hal/furi_hal_power.c | 69 +++++++++---------- .../targets/f7/furi_hal/furi_hal_random.c | 42 ++++++----- .../targets/f7/furi_hal/furi_hal_resources.c | 3 + .../targets/f7/furi_hal/furi_hal_resources.h | 3 + firmware/targets/f7/furi_hal/furi_hal_rtc.c | 15 ++-- .../targets/furi_hal_include/furi_hal_debug.h | 3 + .../targets/furi_hal_include/furi_hal_power.h | 6 -- .../targets/furi_hal_include/furi_hal_rtc.h | 4 ++ furi/core/check.c | 3 + furi/core/core_defines.h | 4 ++ site_scons/cc.scons | 1 + site_scons/commandline.scons | 8 +++ 26 files changed, 246 insertions(+), 120 deletions(-) create mode 100644 documentation/FuriHalDebuging.md diff --git a/applications/main/fap_loader/fap_loader_app.c b/applications/main/fap_loader/fap_loader_app.c index f5c7af02488..7af5244ae49 100644 --- a/applications/main/fap_loader/fap_loader_app.c +++ b/applications/main/fap_loader/fap_loader_app.c @@ -1,6 +1,7 @@ #include "fap_loader_app.h" #include +#include #include #include @@ -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, @@ -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 */ diff --git a/applications/settings/power_settings_app/views/battery_info.c b/applications/settings/power_settings_app/views/battery_info.c index 7394fd3c5a6..0956cae4f5a 100644 --- a/applications/settings/power_settings_app/views/battery_info.c +++ b/applications/settings/power_settings_app/views/battery_info.c @@ -4,8 +4,8 @@ #include #include -#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; @@ -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); @@ -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( @@ -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); diff --git a/applications/settings/system/system_settings.c b/applications/settings/system/system_settings.c index cb74d7a8353..597710a53f0 100644 --- a/applications/settings/system/system_settings.c +++ b/applications/settings/system/system_settings.c @@ -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; @@ -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( diff --git a/debug/flipperapps.py b/debug/flipperapps.py index 1dc5ebd04bb..90582c1e44a 100644 --- a/debug/flipperapps.py +++ b/debug/flipperapps.py @@ -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: @@ -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 diff --git a/documentation/FuriHalDebuging.md b/documentation/FuriHalDebuging.md new file mode 100644 index 00000000000..8ff770163b2 --- /dev/null +++ b/documentation/FuriHalDebuging.md @@ -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. \ No newline at end of file diff --git a/documentation/fbt.md b/documentation/fbt.md index 14d63e9cea8..23b2e2b55f1 100644 --- a/documentation/fbt.md +++ b/documentation/fbt.md @@ -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 diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index 5d5b7bbcf2c..493f5963474 100644 --- a/firmware/targets/f18/api_symbols.csv +++ b/firmware/targets/f18/api_symbols.csv @@ -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,, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, diff --git a/firmware/targets/f18/furi_hal/furi_hal_resources.c b/firmware/targets/f18/furi_hal/furi_hal_resources.c index 4a7015d139a..6db483dbcbb 100644 --- a/firmware/targets/f18/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f18/furi_hal/furi_hal_resources.c @@ -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}; diff --git a/firmware/targets/f18/furi_hal/furi_hal_resources.h b/firmware/targets/f18/furi_hal/furi_hal_resources.h index 3c4708d15f9..7d2caab3682 100644 --- a/firmware/targets/f18/furi_hal/furi_hal_resources.h +++ b/firmware/targets/f18/furi_hal/furi_hal_resources.h @@ -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; diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 89984352a2d..3ef57813b4a 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -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,, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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*[], @@ -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, @@ -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, diff --git a/firmware/targets/f7/ble_glue/ble_glue.c b/firmware/targets/f7/ble_glue/ble_glue.c index 83562c73eef..a2f2f1a94b0 100644 --- a/firmware/targets/f7/ble_glue/ble_glue.c +++ b/firmware/targets/f7/ble_glue/ble_glue.c @@ -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 diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index cf19451ec7b..d85524ce44e 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -63,6 +63,10 @@ void furi_hal_clock_init() { LL_RCC_HSI_Enable(); while(!HS_CLOCK_IS_READY()) ; + /* Select HSI as system clock source after Wake Up from Stop mode + * Must be set before enabling CSS */ + LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI); + LL_RCC_HSE_EnableCSS(); /* LSE and LSI1 configuration and activation */ @@ -215,11 +219,14 @@ void furi_hal_clock_switch_to_hsi() { void furi_hal_clock_switch_to_pll() { LL_RCC_HSE_Enable(); LL_RCC_PLL_Enable(); + LL_RCC_PLLSAI1_Enable(); while(!LL_RCC_HSE_IsReady()) ; while(!LL_RCC_PLL_IsReady()) ; + while(!LL_RCC_PLLSAI1_IsReady()) + ; LL_FLASH_SetLatency(LL_FLASH_LATENCY_3); @@ -296,4 +303,4 @@ void furi_hal_clock_mco_disable() { LL_RCC_MSI_Disable(); while(LL_RCC_MSI_IsReady() != 0) ; -} \ No newline at end of file +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_debug.c b/firmware/targets/f7/furi_hal/furi_hal_debug.c index 3b5dfe622e0..3dc03ea69d7 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_debug.c +++ b/firmware/targets/f7/furi_hal/furi_hal_debug.c @@ -3,12 +3,26 @@ #include #include +#include +#include + +volatile bool furi_hal_debug_gdb_session_active = false; + void furi_hal_debug_enable() { // Low power mode debug LL_DBGMCU_EnableDBGSleepMode(); LL_DBGMCU_EnableDBGStopMode(); LL_DBGMCU_EnableDBGStandbyMode(); LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); + // SWD GPIO + furi_hal_gpio_init_ex( + &gpio_swdio, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn0JTMS_SWDIO); + furi_hal_gpio_init_ex( + &gpio_swclk, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn0JTCK_SWCLK); } void furi_hal_debug_disable() { @@ -17,4 +31,11 @@ void furi_hal_debug_disable() { LL_DBGMCU_DisableDBGStopMode(); LL_DBGMCU_DisableDBGStandbyMode(); LL_EXTI_DisableIT_32_63(LL_EXTI_LINE_48); + // SWD GPIO + furi_hal_gpio_init_simple(&gpio_swdio, GpioModeAnalog); + furi_hal_gpio_init_simple(&gpio_swclk, GpioModeAnalog); } + +bool furi_hal_debug_is_gdb_session_active() { + return furi_hal_debug_gdb_session_active; +} \ No newline at end of file diff --git a/firmware/targets/f7/furi_hal/furi_hal_os.c b/firmware/targets/f7/furi_hal/furi_hal_os.c index ee9743e62c6..3fc1fbea848 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_os.c +++ b/firmware/targets/f7/furi_hal/furi_hal_os.c @@ -28,11 +28,24 @@ // Arbitrary (but small) number for better tick consistency #define FURI_HAL_OS_EXTRA_CNT 3 +#ifndef FURI_HAL_OS_DEBUG_AWAKE_GPIO +#define FURI_HAL_OS_DEBUG_AWAKE_GPIO (&gpio_ext_pa7) +#endif + +#ifndef FURI_HAL_OS_DEBUG_TICK_GPIO +#define FURI_HAL_OS_DEBUG_TICK_GPIO (&gpio_ext_pa6) +#endif + +#ifndef FURI_HAL_OS_DEBUG_SECOND_GPIO +#define FURI_HAL_OS_DEBUG_SECOND_GPIO (&gpio_ext_pa4) +#endif + #ifdef FURI_HAL_OS_DEBUG #include void furi_hal_os_timer_callback() { - furi_hal_gpio_write(&gpio_ext_pa4, !furi_hal_gpio_read(&gpio_ext_pa4)); + furi_hal_gpio_write( + FURI_HAL_OS_DEBUG_SECOND_GPIO, !furi_hal_gpio_read(FURI_HAL_OS_DEBUG_SECOND_GPIO)); } #endif @@ -44,9 +57,11 @@ void furi_hal_os_init() { furi_hal_idle_timer_init(); #ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull); - furi_hal_gpio_init_simple(&gpio_ext_pa6, GpioModeOutputPushPull); - furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(FURI_HAL_OS_DEBUG_AWAKE_GPIO, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(FURI_HAL_OS_DEBUG_TICK_GPIO, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(FURI_HAL_OS_DEBUG_SECOND_GPIO, GpioModeOutputPushPull); + furi_hal_gpio_write(FURI_HAL_OS_DEBUG_AWAKE_GPIO, 1); + FuriTimer* second_timer = furi_timer_alloc(furi_hal_os_timer_callback, FuriTimerTypePeriodic, NULL); furi_timer_start(second_timer, FURI_HAL_OS_TICK_HZ); @@ -58,7 +73,8 @@ void furi_hal_os_init() { void furi_hal_os_tick() { if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { #ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_write(&gpio_ext_pa6, !furi_hal_gpio_read(&gpio_ext_pa6)); + furi_hal_gpio_write( + FURI_HAL_OS_DEBUG_TICK_GPIO, !furi_hal_gpio_read(FURI_HAL_OS_DEBUG_TICK_GPIO)); #endif xPortSysTickHandler(); } @@ -121,14 +137,14 @@ static inline uint32_t furi_hal_os_sleep(TickType_t expected_idle_ticks) { furi_hal_idle_timer_start(FURI_HAL_OS_TICKS_TO_IDLE_CNT(expected_idle_ticks)); #ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_write(&gpio_ext_pa7, 0); + furi_hal_gpio_write(FURI_HAL_OS_DEBUG_AWAKE_GPIO, 0); #endif // Go to sleep mode furi_hal_power_sleep(); #ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_write(&gpio_ext_pa7, 1); + furi_hal_gpio_write(FURI_HAL_OS_DEBUG_AWAKE_GPIO, 1); #endif // Calculate how much time we spent in the sleep diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index fd601ec7ec8..9a87cef15c3 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include @@ -19,15 +21,16 @@ #define TAG "FuriHalPower" -#ifdef FURI_HAL_POWER_DEEP_SLEEP_ENABLED -#define FURI_HAL_POWER_DEEP_INSOMNIA 0 -#else -#define FURI_HAL_POWER_DEEP_INSOMNIA 1 +#ifndef FURI_HAL_POWER_DEBUG_WFI_GPIO +#define FURI_HAL_POWER_DEBUG_WFI_GPIO (&gpio_ext_pb2) +#endif + +#ifndef FURI_HAL_POWER_DEBUG_STOP_GPIO +#define FURI_HAL_POWER_DEBUG_STOP_GPIO (&gpio_ext_pc3) #endif typedef struct { volatile uint8_t insomnia; - volatile uint8_t deep_insomnia; volatile uint8_t suppress_charge; uint8_t gauge_initialized; @@ -36,7 +39,6 @@ typedef struct { static volatile FuriHalPower furi_hal_power = { .insomnia = 0, - .deep_insomnia = FURI_HAL_POWER_DEEP_INSOMNIA, .suppress_charge = 0, }; @@ -79,19 +81,23 @@ const ParamCEDV cedv = { }; void furi_hal_power_init() { +#ifdef FURI_HAL_POWER_DEBUG + furi_hal_gpio_init_simple(FURI_HAL_POWER_DEBUG_WFI_GPIO, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(FURI_HAL_POWER_DEBUG_STOP_GPIO, GpioModeOutputPushPull); + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 0); + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 0); +#endif + LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); LL_PWR_SMPS_SetMode(LL_PWR_SMPS_STEP_DOWN); + LL_PWR_SetPowerMode(LL_PWR_MODE_STOP2); + LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STOP2); furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); bq27220_init(&furi_hal_i2c_handle_power, &cedv); bq25896_init(&furi_hal_i2c_handle_power); furi_hal_i2c_release(&furi_hal_i2c_handle_power); -#ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_init_simple(&gpio_ext_pb2, GpioModeOutputPushPull); - furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull); -#endif - FURI_LOG_I(TAG, "Init OK"); } @@ -140,11 +146,12 @@ bool furi_hal_power_sleep_available() { return furi_hal_power.insomnia == 0; } -bool furi_hal_power_deep_sleep_available() { - return furi_hal_bt_is_alive() && furi_hal_power.deep_insomnia == 0; +static inline bool furi_hal_power_deep_sleep_available() { + return furi_hal_bt_is_alive() && !furi_hal_rtc_is_flag_set(FuriHalRtcFlagLegacySleep) && + !furi_hal_debug_is_gdb_session_active(); } -void furi_hal_power_light_sleep() { +static inline void furi_hal_power_light_sleep() { __WFI(); } @@ -152,17 +159,15 @@ static inline void furi_hal_power_suspend_aux_periphs() { // Disable USART furi_hal_uart_suspend(FuriHalUartIdUSART1); furi_hal_uart_suspend(FuriHalUartIdLPUART1); - // TODO: Disable USB } static inline void furi_hal_power_resume_aux_periphs() { // Re-enable USART furi_hal_uart_resume(FuriHalUartIdUSART1); furi_hal_uart_resume(FuriHalUartIdLPUART1); - // TODO: Re-enable USB } -void furi_hal_power_deep_sleep() { +static inline void furi_hal_power_deep_sleep() { furi_hal_power_suspend_aux_periphs(); while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) @@ -187,8 +192,6 @@ void furi_hal_power_deep_sleep() { LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); // Prepare deep sleep - LL_PWR_SetPowerMode(LL_PWR_MODE_STOP2); - LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STOP2); LL_LPM_EnableDeepSleep(); #if defined(__CC_ARM) @@ -200,13 +203,6 @@ void furi_hal_power_deep_sleep() { LL_LPM_EnableSleep(); - // Make sure that values differ to prevent disaster on wfi - LL_PWR_SetPowerMode(LL_PWR_MODE_STOP0); - LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN); - - LL_PWR_ClearFlag_C1STOP_C1STB(); - LL_PWR_ClearFlag_C2STOP_C2STB(); - /* Release ENTRY_STOP_MODE semaphore */ LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0); @@ -220,28 +216,25 @@ void furi_hal_power_deep_sleep() { LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); furi_hal_power_resume_aux_periphs(); + furi_hal_rtc_sync_shadow(); } void furi_hal_power_sleep() { if(furi_hal_power_deep_sleep_available()) { -#ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_write(&gpio_ext_pc3, 1); +#ifdef FURI_HAL_POWER_DEBUG + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 1); #endif - furi_hal_power_deep_sleep(); - -#ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_write(&gpio_ext_pc3, 0); +#ifdef FURI_HAL_POWER_DEBUG + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 0); #endif } else { -#ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_write(&gpio_ext_pb2, 1); +#ifdef FURI_HAL_POWER_DEBUG + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 1); #endif - furi_hal_power_light_sleep(); - -#ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_write(&gpio_ext_pb2, 0); +#ifdef FURI_HAL_POWER_DEBUG + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 0); #endif } } diff --git a/firmware/targets/f7/furi_hal/furi_hal_random.c b/firmware/targets/f7/furi_hal/furi_hal_random.c index f36407cc16a..d3461c4d12e 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_random.c +++ b/firmware/targets/f7/furi_hal/furi_hal_random.c @@ -9,19 +9,35 @@ #define TAG "FuriHalRandom" +static uint32_t furi_hal_random_read_rng() { + while(LL_RNG_IsActiveFlag_CECS(RNG) && LL_RNG_IsActiveFlag_SECS(RNG) && + !LL_RNG_IsActiveFlag_DRDY(RNG)) { + /* Error handling as described in RM0434, pg. 582-583 */ + if(LL_RNG_IsActiveFlag_CECS(RNG)) { + /* Clock error occurred */ + LL_RNG_ClearFlag_CEIS(RNG); + } + + if(LL_RNG_IsActiveFlag_SECS(RNG)) { + /* Noise source error occurred */ + LL_RNG_ClearFlag_SEIS(RNG); + + for(uint32_t i = 0; i < 12; ++i) { + const volatile uint32_t discard = LL_RNG_ReadRandData32(RNG); + UNUSED(discard); + } + } + } + + return LL_RNG_ReadRandData32(RNG); +} + uint32_t furi_hal_random_get() { while(LL_HSEM_1StepLock(HSEM, CFG_HW_RNG_SEMID)) ; LL_RNG_Enable(RNG); - while(!LL_RNG_IsActiveFlag_DRDY(RNG)) - ; - - if((LL_RNG_IsActiveFlag_CECS(RNG)) || (LL_RNG_IsActiveFlag_SECS(RNG))) { - furi_crash("TRNG error"); - } - - uint32_t random_val = LL_RNG_ReadRandData32(RNG); + const uint32_t random_val = furi_hal_random_read_rng(); LL_RNG_Disable(RNG); LL_HSEM_ReleaseLock(HSEM, CFG_HW_RNG_SEMID, 0); @@ -35,15 +51,7 @@ void furi_hal_random_fill_buf(uint8_t* buf, uint32_t len) { LL_RNG_Enable(RNG); for(uint32_t i = 0; i < len; i += 4) { - while(!LL_RNG_IsActiveFlag_DRDY(RNG)) - ; - - if((LL_RNG_IsActiveFlag_CECS(RNG)) || (LL_RNG_IsActiveFlag_SECS(RNG))) { - furi_crash("TRNG error"); - } - - uint32_t random_val = LL_RNG_ReadRandData32(RNG); - + const uint32_t random_val = furi_hal_random_read_rng(); uint8_t len_cur = ((i + 4) < len) ? (4) : (len - i); memcpy(&buf[i], &random_val, len_cur); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.c b/firmware/targets/f7/furi_hal/furi_hal_resources.c index 912912b4a4a..abfd977e52c 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c @@ -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 = VIBRO_GPIO_Port, .pin = VIBRO_Pin}; const GpioPin gpio_ibutton = {.port = iBTN_GPIO_Port, .pin = iBTN_Pin}; diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.h b/firmware/targets/f7/furi_hal/furi_hal_resources.h index f2991730010..6e585c51822 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.h +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.h @@ -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; diff --git a/firmware/targets/f7/furi_hal/furi_hal_rtc.c b/firmware/targets/f7/furi_hal/furi_hal_rtc.c index 84e7fe3959c..7bd45c35d71 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_rtc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_rtc.c @@ -165,6 +165,14 @@ void furi_hal_rtc_init() { FURI_LOG_I(TAG, "Init OK"); } +void furi_hal_rtc_sync_shadow() { + if(!LL_RTC_IsShadowRegBypassEnabled(RTC)) { + LL_RTC_ClearFlag_RS(RTC); + while(!LL_RTC_IsActiveFlag_RS(RTC)) { + }; + } +} + uint32_t furi_hal_rtc_get_register(FuriHalRtcRegister reg) { return LL_RTC_BAK_GetRegister(RTC, reg); } @@ -312,12 +320,7 @@ void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime) { /* Exit Initialization mode */ LL_RTC_DisableInitMode(RTC); - /* If RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */ - if(!LL_RTC_IsShadowRegBypassEnabled(RTC)) { - LL_RTC_ClearFlag_RS(RTC); - while(!LL_RTC_IsActiveFlag_RS(RTC)) { - }; - } + furi_hal_rtc_sync_shadow(); /* Enable write protection */ LL_RTC_EnableWriteProtection(RTC); diff --git a/firmware/targets/furi_hal_include/furi_hal_debug.h b/firmware/targets/furi_hal_include/furi_hal_debug.h index 88397bbbafb..befbb4f40cb 100644 --- a/firmware/targets/furi_hal_include/furi_hal_debug.h +++ b/firmware/targets/furi_hal_include/furi_hal_debug.h @@ -18,6 +18,9 @@ void furi_hal_debug_enable(); /** Disable MCU debug */ void furi_hal_debug_disable(); +/** Check if GDB debug session is active */ +bool furi_hal_debug_is_gdb_session_active(); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/furi_hal_include/furi_hal_power.h b/firmware/targets/furi_hal_include/furi_hal_power.h index 462e20e41db..00182fa2861 100644 --- a/firmware/targets/furi_hal_include/furi_hal_power.h +++ b/firmware/targets/furi_hal_include/furi_hal_power.h @@ -58,12 +58,6 @@ void furi_hal_power_insomnia_exit(); */ bool furi_hal_power_sleep_available(); -/** Check if deep sleep availble - * - * @return true if available - */ -bool furi_hal_power_deep_sleep_available(); - /** Go to sleep */ void furi_hal_power_sleep(); diff --git a/firmware/targets/furi_hal_include/furi_hal_rtc.h b/firmware/targets/furi_hal_include/furi_hal_rtc.h index b16b04a6849..0d9f46f01ba 100644 --- a/firmware/targets/furi_hal_include/furi_hal_rtc.h +++ b/firmware/targets/furi_hal_include/furi_hal_rtc.h @@ -30,6 +30,7 @@ typedef enum { FuriHalRtcFlagLock = (1 << 2), FuriHalRtcFlagC2Update = (1 << 3), FuriHalRtcFlagHandOrient = (1 << 4), + FuriHalRtcFlagLegacySleep = (1 << 5), } FuriHalRtcFlag; typedef enum { @@ -85,6 +86,9 @@ void furi_hal_rtc_deinit_early(); /** Initialize RTC subsystem */ void furi_hal_rtc_init(); +/** Force sync shadow registers */ +void furi_hal_rtc_sync_shadow(); + /** Get RTC register content * * @param[in] reg The register identifier diff --git a/furi/core/check.c b/furi/core/check.c index 910527ceed8..64f9f72f1b9 100644 --- a/furi/core/check.c +++ b/furi/core/check.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -117,6 +118,8 @@ FURI_NORETURN void __furi_crash() { if(debug) { furi_hal_console_puts("\r\nSystem halted. Connect debugger for more info\r\n"); furi_hal_console_puts("\033[0m\r\n"); + furi_hal_debug_enable(); + RESTORE_REGISTERS_AND_HALT_MCU(true); } else { furi_hal_rtc_set_fault_data((uint32_t)__furi_check_message); diff --git a/furi/core/core_defines.h b/furi/core/core_defines.h index 03a364abd0f..830bb191c2e 100644 --- a/furi/core/core_defines.h +++ b/furi/core/core_defines.h @@ -24,6 +24,10 @@ extern "C" { }) #endif +#ifndef ABS +#define ABS(a) ({ (a) < 0 ? -(a) : (a); }) +#endif + #ifndef ROUND_UP_TO #define ROUND_UP_TO(a, b) \ ({ \ diff --git a/site_scons/cc.scons b/site_scons/cc.scons index 1eb6a33768e..55ab72ba654 100644 --- a/site_scons/cc.scons +++ b/site_scons/cc.scons @@ -36,6 +36,7 @@ ENV.AppendUnique( ], CPPDEFINES=[ "_GNU_SOURCE", + *GetOption("extra_defines"), ], LINKFLAGS=[ "-mcpu=cortex-m4", diff --git a/site_scons/commandline.scons b/site_scons/commandline.scons index d832a466e37..2e948662738 100644 --- a/site_scons/commandline.scons +++ b/site_scons/commandline.scons @@ -26,6 +26,14 @@ AddOption( help="List of applications to add to firmware's built-ins. Also see FIRMWARE_APP_SET and FIRMWARE_APPS", ) +AddOption( + "--extra-define", + action="append", + dest="extra_defines", + default=[], + help="Extra global define that will be passed to C/C++ compiler, can be specified multiple times", +) + AddOption( "--extra-ext-apps", action="store", From de02a0a25ad1d9b2637bf16bdb78b97b2a38f6ab Mon Sep 17 00:00:00 2001 From: Eric Betts Date: Sun, 16 Apr 2023 22:36:15 -0700 Subject: [PATCH 3/9] [#2589] Correctly aborts when correct key is found (#2590) --- applications/external/picopass/picopass_worker.c | 5 ++++- .../picopass/scenes/picopass_scene_elite_dict_attack.c | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/applications/external/picopass/picopass_worker.c b/applications/external/picopass/picopass_worker.c index 174413bae36..e671552c5cb 100644 --- a/applications/external/picopass/picopass_worker.c +++ b/applications/external/picopass/picopass_worker.c @@ -570,7 +570,7 @@ void picopass_worker_elite_dict_attack(PicopassWorker* picopass_worker) { picopass_worker->callback(PicopassWorkerEventFail, picopass_worker->context); break; } - picopass_worker->callback(PicopassWorkerEventSuccess, picopass_worker->context); + picopass_worker->callback(PicopassWorkerEventAborted, picopass_worker->context); break; } @@ -596,6 +596,9 @@ int32_t picopass_worker_task(void* context) { picopass_worker_write_key(picopass_worker); } else if(picopass_worker->state == PicopassWorkerStateEliteDictAttack) { picopass_worker_elite_dict_attack(picopass_worker); + } else if(picopass_worker->state == PicopassWorkerStateStop) { + FURI_LOG_D(TAG, "Worker state stop"); + // no-op } else { FURI_LOG_W(TAG, "Unknown state %d", picopass_worker->state); } diff --git a/applications/external/picopass/scenes/picopass_scene_elite_dict_attack.c b/applications/external/picopass/scenes/picopass_scene_elite_dict_attack.c index c76a8ffae59..e6191d5baf4 100644 --- a/applications/external/picopass/scenes/picopass_scene_elite_dict_attack.c +++ b/applications/external/picopass/scenes/picopass_scene_elite_dict_attack.c @@ -116,8 +116,7 @@ bool picopass_scene_elite_dict_attack_on_event(void* context, SceneManagerEvent uint32_t state = scene_manager_get_scene_state(picopass->scene_manager, PicopassSceneEliteDictAttack); if(event.type == SceneManagerEventTypeCustom) { - if(event.event == PicopassWorkerEventSuccess || - event.event == PicopassWorkerEventAborted) { + if(event.event == PicopassWorkerEventSuccess) { if(state == DictAttackStateUserDictInProgress || state == DictAttackStateStandardDictInProgress) { picopass_worker_stop(picopass->worker); @@ -127,6 +126,9 @@ bool picopass_scene_elite_dict_attack_on_event(void* context, SceneManagerEvent scene_manager_next_scene(picopass->scene_manager, PicopassSceneReadCardSuccess); consumed = true; } + } else if(event.event == PicopassWorkerEventAborted) { + scene_manager_next_scene(picopass->scene_manager, PicopassSceneReadCardSuccess); + consumed = true; } else if(event.event == PicopassWorkerEventCardDetected) { dict_attack_set_card_detected(picopass->dict_attack); consumed = true; From f68c3b2a653a2f5fc35c3bc90c8447f3d5d97398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Tue, 18 Apr 2023 20:38:35 +0900 Subject: [PATCH 4/9] [FL-3264] Various stop mode fixes (#2584) * BleGlue: log hci_cmd_resp invocation * BleGlue: increase BleHciDriver stack size * ble hid app: increase stack * ble: comment unnecessary hci reset * BleGlue: stricter checks in communication with core2, cleanup code * Furi: enter insomnia when executing from RAM --------- Co-authored-by: gornekich --- firmware/targets/f7/ble_glue/app_debug.c | 2 +- firmware/targets/f7/ble_glue/ble_app.c | 33 ++++++++++-------------- firmware/targets/f7/ble_glue/gap.c | 2 -- firmware/targets/f7/src/main.c | 3 +++ 4 files changed, 18 insertions(+), 22 deletions(-) diff --git a/firmware/targets/f7/ble_glue/app_debug.c b/firmware/targets/f7/ble_glue/app_debug.c index d84588540a0..78e789ac307 100644 --- a/firmware/targets/f7/ble_glue/app_debug.c +++ b/firmware/targets/f7/ble_glue/app_debug.c @@ -68,7 +68,7 @@ static const APPD_GpioConfig_t aGpioConfigList[GPIO_CFG_NBR_OF_FEATURES] = { {GPIOA, LL_GPIO_PIN_0, 0, 0}, /* END_OF_CONNECTION_EVENT - Set on Entry / Reset on Exit */ {GPIOA, LL_GPIO_PIN_0, 0, 0}, /* TIMER_SERVER_CALLBACK - Toggle on Entry */ {GPIOA, LL_GPIO_PIN_4, 1, 0}, /* PES_ACTIVITY - Set on Entry / Reset on Exit */ - {GPIOB, LL_GPIO_PIN_2, 1, 0}, /* MB_BLE_SEND_EVT - Set on Entry / Reset on Exit */ + {GPIOC, LL_GPIO_PIN_0, 1, 0}, /* MB_BLE_SEND_EVT - Set on Entry / Reset on Exit */ /* From v1.3.0 */ {GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_NO_DELAY - Set on Entry / Reset on Exit */ {GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_STACK_STORE_NVM_CB - Set on Entry / Reset on Exit */ diff --git a/firmware/targets/f7/ble_glue/ble_app.c b/firmware/targets/f7/ble_glue/ble_app.c index 30be3c7ceca..4fc4d521be1 100644 --- a/firmware/targets/f7/ble_glue/ble_app.c +++ b/firmware/targets/f7/ble_glue/ble_app.c @@ -137,38 +137,33 @@ static int32_t ble_app_hci_thread(void* arg) { // Called by WPAN lib void hci_notify_asynch_evt(void* pdata) { UNUSED(pdata); - if(ble_app) { - FuriThreadId thread_id = furi_thread_get_id(ble_app->thread); - furi_assert(thread_id); - furi_thread_flags_set(thread_id, BLE_APP_FLAG_HCI_EVENT); - } + furi_check(ble_app); + FuriThreadId thread_id = furi_thread_get_id(ble_app->thread); + furi_assert(thread_id); + furi_thread_flags_set(thread_id, BLE_APP_FLAG_HCI_EVENT); } void hci_cmd_resp_release(uint32_t flag) { UNUSED(flag); - if(ble_app) { - furi_semaphore_release(ble_app->hci_sem); - } + furi_check(ble_app); + furi_check(furi_semaphore_release(ble_app->hci_sem) == FuriStatusOk); } void hci_cmd_resp_wait(uint32_t timeout) { - UNUSED(timeout); - if(ble_app) { - furi_semaphore_acquire(ble_app->hci_sem, FuriWaitForever); - } + furi_check(ble_app); + furi_check(furi_semaphore_acquire(ble_app->hci_sem, timeout) == FuriStatusOk); } static void ble_app_hci_event_handler(void* pPayload) { SVCCTL_UserEvtFlowStatus_t svctl_return_status; tHCI_UserEvtRxParam* pParam = (tHCI_UserEvtRxParam*)pPayload; - if(ble_app) { - svctl_return_status = SVCCTL_UserEvtRx((void*)&(pParam->pckt->evtserial)); - if(svctl_return_status != SVCCTL_UserEvtFlowDisable) { - pParam->status = HCI_TL_UserEventFlow_Enable; - } else { - pParam->status = HCI_TL_UserEventFlow_Disable; - } + furi_check(ble_app); + svctl_return_status = SVCCTL_UserEvtRx((void*)&(pParam->pckt->evtserial)); + if(svctl_return_status != SVCCTL_UserEvtFlowDisable) { + pParam->status = HCI_TL_UserEventFlow_Enable; + } else { + pParam->status = HCI_TL_UserEventFlow_Disable; } } diff --git a/firmware/targets/f7/ble_glue/gap.c b/firmware/targets/f7/ble_glue/gap.c index 8ef037d6b72..cbb2a203bd1 100644 --- a/firmware/targets/f7/ble_glue/gap.c +++ b/firmware/targets/f7/ble_glue/gap.c @@ -289,8 +289,6 @@ static void gap_init_svc(Gap* gap) { tBleStatus status; uint32_t srd_bd_addr[2]; - // HCI Reset to synchronise BLE Stack - hci_reset(); // Configure mac address aci_hal_write_config_data( CONFIG_DATA_PUBADDR_OFFSET, CONFIG_DATA_PUBADDR_LEN, gap->config->mac_address); diff --git a/firmware/targets/f7/src/main.c b/firmware/targets/f7/src/main.c index 1f2b5d6e42a..2c353f52b20 100644 --- a/firmware/targets/f7/src/main.c +++ b/firmware/targets/f7/src/main.c @@ -29,6 +29,8 @@ int main() { FuriThread* main_thread = furi_thread_alloc_ex("Init", 4096, init_task, NULL); #ifdef FURI_RAM_EXEC + // Prevent entering sleep mode when executed from RAM + furi_hal_power_insomnia_enter(); furi_thread_start(main_thread); #else furi_hal_light_sequence("RGB"); @@ -44,6 +46,7 @@ int main() { furi_hal_power_reset(); } else if(boot_mode == FuriHalRtcBootModeUpdate) { furi_hal_light_sequence("rgb BR"); + // Do update flipper_boot_update_exec(); // if things go nice, we shouldn't reach this point. // But if we do, abandon to avoid bootloops From 2c7eb53caceea63999aed09d691271a3d1ee58bc Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Wed, 19 Apr 2023 11:30:26 +0300 Subject: [PATCH 5/9] [FL-2505] Active RPC session icon (#2583) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Active RPC session icon * Add RpcOwner, don't show the RPC icon when the session was started from BLE * Fix rpc_test and f18 api * Bump API version Co-authored-by: あく --- applications/debug/unit_tests/rpc/rpc_test.c | 4 +-- applications/services/bt/bt_service/bt.c | 2 +- applications/services/rpc/rpc.c | 9 ++++++- applications/services/rpc/rpc.h | 18 ++++++++++++- applications/services/rpc/rpc_cli.c | 2 +- applications/services/rpc/rpc_gui.c | 26 ++++++++++++++++++- assets/icons/StatusBar/Rpc_active_7x8.png | Bin 0 -> 3607 bytes firmware/targets/f18/api_symbols.csv | 5 ++-- firmware/targets/f7/api_symbols.csv | 5 ++-- 9 files changed, 60 insertions(+), 11 deletions(-) create mode 100644 assets/icons/StatusBar/Rpc_active_7x8.png diff --git a/applications/debug/unit_tests/rpc/rpc_test.c b/applications/debug/unit_tests/rpc/rpc_test.c index 329f3b7412e..167266a8433 100644 --- a/applications/debug/unit_tests/rpc/rpc_test.c +++ b/applications/debug/unit_tests/rpc/rpc_test.c @@ -84,7 +84,7 @@ static void test_rpc_setup(void) { rpc = furi_record_open(RECORD_RPC); for(int i = 0; !(rpc_session[0].session) && (i < 10000); ++i) { - rpc_session[0].session = rpc_session_open(rpc); + rpc_session[0].session = rpc_session_open(rpc, RpcOwnerUnknown); furi_delay_tick(1); } furi_check(rpc_session[0].session); @@ -104,7 +104,7 @@ static void test_rpc_setup_second_session(void) { furi_check(!(rpc_session[1].session)); for(int i = 0; !(rpc_session[1].session) && (i < 10000); ++i) { - rpc_session[1].session = rpc_session_open(rpc); + rpc_session[1].session = rpc_session_open(rpc, RpcOwnerUnknown); furi_delay_tick(1); } furi_check(rpc_session[1].session); diff --git a/applications/services/bt/bt_service/bt.c b/applications/services/bt/bt_service/bt.c index 16b60231b24..2dcea34856c 100644 --- a/applications/services/bt/bt_service/bt.c +++ b/applications/services/bt/bt_service/bt.c @@ -225,7 +225,7 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) { furi_event_flag_clear(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED); if(bt->profile == BtProfileSerial) { // Open RPC session - bt->rpc_session = rpc_session_open(bt->rpc); + bt->rpc_session = rpc_session_open(bt->rpc, RpcOwnerBle); if(bt->rpc_session) { FURI_LOG_I(TAG, "Open RPC connection"); rpc_session_set_send_bytes_callback(bt->rpc_session, bt_rpc_send_bytes_callback); diff --git a/applications/services/rpc/rpc.c b/applications/services/rpc/rpc.c index 57a4ec9aa2d..5b09e9b5178 100644 --- a/applications/services/rpc/rpc.c +++ b/applications/services/rpc/rpc.c @@ -76,6 +76,7 @@ struct RpcSession { RpcBufferIsEmptyCallback buffer_is_empty_callback; RpcSessionClosedCallback closed_callback; RpcSessionTerminatedCallback terminated_callback; + RpcOwner owner; void* context; }; @@ -83,6 +84,11 @@ struct Rpc { FuriMutex* busy_mutex; }; +RpcOwner rpc_session_get_owner(RpcSession* session) { + furi_assert(session); + return session->owner; +} + static void rpc_close_session_process(const PB_Main* request, void* context) { furi_assert(request); furi_assert(context); @@ -348,7 +354,7 @@ static void rpc_session_free_callback(FuriThreadState thread_state, void* contex } } -RpcSession* rpc_session_open(Rpc* rpc) { +RpcSession* rpc_session_open(Rpc* rpc, RpcOwner owner) { furi_assert(rpc); RpcSession* session = malloc(sizeof(RpcSession)); @@ -357,6 +363,7 @@ RpcSession* rpc_session_open(Rpc* rpc) { session->rpc = rpc; session->terminate = false; session->decode_error = false; + session->owner = owner; RpcHandlerDict_init(session->handlers); session->decoded_message = malloc(sizeof(PB_Main)); diff --git a/applications/services/rpc/rpc.h b/applications/services/rpc/rpc.h index ec290e083af..d11fdc16244 100644 --- a/applications/services/rpc/rpc.h +++ b/applications/services/rpc/rpc.h @@ -30,6 +30,21 @@ typedef void (*RpcSessionClosedCallback)(void* context); * and all operations were finished */ typedef void (*RpcSessionTerminatedCallback)(void* context); +/** RPC owner */ +typedef enum { + RpcOwnerUnknown = 0, + RpcOwnerBle, + RpcOwnerUsb, + RpcOwnerCount, +} RpcOwner; + +/** Get RPC session owner + * + * @param session pointer to RpcSession descriptor + * @return session owner + */ +RpcOwner rpc_session_get_owner(RpcSession* session); + /** Open RPC session * * USAGE: @@ -44,10 +59,11 @@ typedef void (*RpcSessionTerminatedCallback)(void* context); * * * @param rpc instance + * @param owner owner of session * @return pointer to RpcSession descriptor, or * NULL if RPC is busy and can't open session now */ -RpcSession* rpc_session_open(Rpc* rpc); +RpcSession* rpc_session_open(Rpc* rpc, RpcOwner owner); /** Close RPC session * It is guaranteed that no callbacks will be called diff --git a/applications/services/rpc/rpc_cli.c b/applications/services/rpc/rpc_cli.c index d14b8eee2fa..f1c139b5f93 100644 --- a/applications/services/rpc/rpc_cli.c +++ b/applications/services/rpc/rpc_cli.c @@ -47,7 +47,7 @@ void rpc_cli_command_start_session(Cli* cli, FuriString* args, void* context) { FURI_LOG_D(TAG, "Free memory %lu", mem_before); furi_hal_usb_lock(); - RpcSession* rpc_session = rpc_session_open(rpc); + RpcSession* rpc_session = rpc_session_open(rpc, RpcOwnerUsb); if(rpc_session == NULL) { printf("Session start error\r\n"); furi_hal_usb_unlock(); diff --git a/applications/services/rpc/rpc_gui.c b/applications/services/rpc/rpc_gui.c index 0c70702cf4e..9ba20a83208 100644 --- a/applications/services/rpc/rpc_gui.c +++ b/applications/services/rpc/rpc_gui.c @@ -2,6 +2,7 @@ #include "rpc_i.h" #include "gui.pb.h" #include +#include #define TAG "RpcGui" @@ -31,6 +32,8 @@ typedef struct { uint32_t input_key_counter[InputKeyMAX]; uint32_t input_counter; + + ViewPort* rpc_session_active_viewport; } RpcGuiSystem; static const PB_Gui_ScreenOrientation rpc_system_gui_screen_orientation_map[] = { @@ -352,6 +355,12 @@ static void rpc_system_gui_virtual_display_frame_process(const PB_Main* request, (void)session; } +static void rpc_active_session_icon_draw_callback(Canvas* canvas, void* context) { + UNUSED(context); + furi_assert(canvas); + canvas_draw_icon(canvas, 0, 0, &I_Rpc_active_7x8); +} + void* rpc_system_gui_alloc(RpcSession* session) { furi_assert(session); @@ -359,6 +368,18 @@ void* rpc_system_gui_alloc(RpcSession* session) { rpc_gui->gui = furi_record_open(RECORD_GUI); rpc_gui->session = session; + // Active session icon + rpc_gui->rpc_session_active_viewport = view_port_alloc(); + view_port_set_width(rpc_gui->rpc_session_active_viewport, icon_get_width(&I_Rpc_active_7x8)); + view_port_draw_callback_set( + rpc_gui->rpc_session_active_viewport, rpc_active_session_icon_draw_callback, session); + if(rpc_session_get_owner(rpc_gui->session) != RpcOwnerBle) { + view_port_enabled_set(rpc_gui->rpc_session_active_viewport, true); + } else { + view_port_enabled_set(rpc_gui->rpc_session_active_viewport, false); + } + gui_add_view_port(rpc_gui->gui, rpc_gui->rpc_session_active_viewport, GuiLayerStatusBarLeft); + RpcHandler rpc_handler = { .message_handler = NULL, .decode_submessage = NULL, @@ -399,6 +420,9 @@ void rpc_system_gui_free(void* context) { rpc_gui->virtual_display_not_empty = false; } + gui_remove_view_port(rpc_gui->gui, rpc_gui->rpc_session_active_viewport); + view_port_free(rpc_gui->rpc_session_active_viewport); + if(rpc_gui->is_streaming) { rpc_gui->is_streaming = false; // Remove GUI framebuffer callback @@ -415,4 +439,4 @@ void rpc_system_gui_free(void* context) { } furi_record_close(RECORD_GUI); free(rpc_gui); -} +} \ No newline at end of file diff --git a/assets/icons/StatusBar/Rpc_active_7x8.png b/assets/icons/StatusBar/Rpc_active_7x8.png new file mode 100644 index 0000000000000000000000000000000000000000..f643a82aa1d2efab26d7e8976bce73124c5c64d2 GIT binary patch literal 3607 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 TX-MlFYYS&#YHd=yAa5I#)A literal 0 HcmV?d00001 diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index 493f5963474..a37ef02cc60 100644 --- a/firmware/targets/f18/api_symbols.csv +++ b/firmware/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,22.0,, +Version,+,23.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1596,7 +1596,8 @@ Function,-,rindex,char*,"const char*, int" Function,+,rpc_session_close,void,RpcSession* Function,+,rpc_session_feed,size_t,"RpcSession*, uint8_t*, size_t, TickType_t" Function,+,rpc_session_get_available_size,size_t,RpcSession* -Function,+,rpc_session_open,RpcSession*,Rpc* +Function,+,rpc_session_get_owner,RpcOwner,RpcSession* +Function,+,rpc_session_open,RpcSession*,"Rpc*, RpcOwner" Function,+,rpc_session_set_buffer_is_empty_callback,void,"RpcSession*, RpcBufferIsEmptyCallback" Function,+,rpc_session_set_close_callback,void,"RpcSession*, RpcSessionClosedCallback" Function,+,rpc_session_set_context,void,"RpcSession*, void*" diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 3ef57813b4a..43ede425e12 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,22.0,, +Version,+,23.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -2373,7 +2373,8 @@ Function,-,roundl,long double,long double Function,+,rpc_session_close,void,RpcSession* Function,+,rpc_session_feed,size_t,"RpcSession*, uint8_t*, size_t, TickType_t" Function,+,rpc_session_get_available_size,size_t,RpcSession* -Function,+,rpc_session_open,RpcSession*,Rpc* +Function,+,rpc_session_get_owner,RpcOwner,RpcSession* +Function,+,rpc_session_open,RpcSession*,"Rpc*, RpcOwner" Function,+,rpc_session_set_buffer_is_empty_callback,void,"RpcSession*, RpcBufferIsEmptyCallback" Function,+,rpc_session_set_close_callback,void,"RpcSession*, RpcSessionClosedCallback" Function,+,rpc_session_set_context,void,"RpcSession*, void*" From 74fe003f8bd6e69230979d02a90853f0ea9f9750 Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Wed, 19 Apr 2023 12:33:23 +0300 Subject: [PATCH 6/9] [FL-3171] Introduce stealth mode and auto-selective lock (#2576) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Introduce stealth mode and auto-selective lock * Stealth mode status bar icon * Review fixes * Fix icon disappearing after reboot * Support overriding stealth mode * FuriHal: correct reserved space size in RTC SystemReg Co-authored-by: あく --- applications/services/desktop/desktop.c | 29 +++++++++++++ applications/services/desktop/desktop_i.h | 2 + .../desktop/scenes/desktop_scene_lock_menu.c | 12 ++++++ .../services/desktop/views/desktop_events.h | 2 + .../desktop/views/desktop_view_lock_menu.c | 38 +++++++++++++---- .../desktop/views/desktop_view_lock_menu.h | 2 + .../services/notification/notification_app.c | 27 ++++++++---- .../notification_settings_app.c | 39 ++++++++++++------ assets/icons/StatusBar/Muted_8x8.png | Bin 0 -> 3626 bytes .../targets/furi_hal_include/furi_hal_rtc.h | 1 + 10 files changed, 122 insertions(+), 30 deletions(-) create mode 100644 assets/icons/StatusBar/Muted_8x8.png diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index 41470ed3a17..bdb73009952 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -46,6 +46,12 @@ static void desktop_dummy_mode_icon_draw_callback(Canvas* canvas, void* context) canvas_draw_icon(canvas, 0, 0, &I_GameMode_11x8); } +static void desktop_stealth_mode_icon_draw_callback(Canvas* canvas, void* context) { + UNUSED(context); + furi_assert(canvas); + canvas_draw_icon(canvas, 0, 0, &I_Muted_8x8); +} + static bool desktop_custom_event_callback(void* context, uint32_t event) { furi_assert(context); Desktop* desktop = (Desktop*)context; @@ -153,6 +159,17 @@ void desktop_set_dummy_mode_state(Desktop* desktop, bool enabled) { desktop->in_transition = false; } +void desktop_set_stealth_mode_state(Desktop* desktop, bool enabled) { + desktop->in_transition = true; + if(enabled) { + furi_hal_rtc_set_flag(FuriHalRtcFlagStealthMode); + } else { + furi_hal_rtc_reset_flag(FuriHalRtcFlagStealthMode); + } + view_port_enabled_set(desktop->stealth_mode_icon_viewport, enabled); + desktop->in_transition = false; +} + Desktop* desktop_alloc() { Desktop* desktop = malloc(sizeof(Desktop)); @@ -244,6 +261,18 @@ Desktop* desktop_alloc() { view_port_enabled_set(desktop->dummy_mode_icon_viewport, false); gui_add_view_port(desktop->gui, desktop->dummy_mode_icon_viewport, GuiLayerStatusBarLeft); + // Stealth mode icon + desktop->stealth_mode_icon_viewport = view_port_alloc(); + view_port_set_width(desktop->stealth_mode_icon_viewport, icon_get_width(&I_Muted_8x8)); + view_port_draw_callback_set( + desktop->stealth_mode_icon_viewport, desktop_stealth_mode_icon_draw_callback, desktop); + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode)) { + view_port_enabled_set(desktop->stealth_mode_icon_viewport, true); + } else { + view_port_enabled_set(desktop->stealth_mode_icon_viewport, false); + } + gui_add_view_port(desktop->gui, desktop->stealth_mode_icon_viewport, GuiLayerStatusBarLeft); + // Special case: autostart application is already running desktop->loader = furi_record_open(RECORD_LOADER); if(loader_is_locked(desktop->loader) && diff --git a/applications/services/desktop/desktop_i.h b/applications/services/desktop/desktop_i.h index 2f3ec9b517d..ede6bbcc31c 100644 --- a/applications/services/desktop/desktop_i.h +++ b/applications/services/desktop/desktop_i.h @@ -59,6 +59,7 @@ struct Desktop { ViewPort* lock_icon_viewport; ViewPort* dummy_mode_icon_viewport; + ViewPort* stealth_mode_icon_viewport; AnimationManager* animation_manager; @@ -79,3 +80,4 @@ void desktop_free(Desktop* desktop); void desktop_lock(Desktop* desktop); void desktop_unlock(Desktop* desktop); void desktop_set_dummy_mode_state(Desktop* desktop, bool enabled); +void desktop_set_stealth_mode_state(Desktop* desktop, bool enabled); diff --git a/applications/services/desktop/scenes/desktop_scene_lock_menu.c b/applications/services/desktop/scenes/desktop_scene_lock_menu.c index 365fe17023c..bfaa8a036a6 100644 --- a/applications/services/desktop/scenes/desktop_scene_lock_menu.c +++ b/applications/services/desktop/scenes/desktop_scene_lock_menu.c @@ -27,6 +27,8 @@ void desktop_scene_lock_menu_on_enter(void* context) { desktop_lock_menu_set_callback(desktop->lock_menu, desktop_scene_lock_menu_callback, desktop); desktop_lock_menu_set_pin_state(desktop->lock_menu, desktop->settings.pin_code.length > 0); desktop_lock_menu_set_dummy_mode_state(desktop->lock_menu, desktop->settings.dummy_mode); + desktop_lock_menu_set_stealth_mode_state( + desktop->lock_menu, furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode)); desktop_lock_menu_set_idx(desktop->lock_menu, 0); view_dispatcher_switch_to_view(desktop->view_dispatcher, DesktopViewIdLockMenu); @@ -78,6 +80,16 @@ bool desktop_scene_lock_menu_on_event(void* context, SceneManagerEvent event) { scene_manager_search_and_switch_to_previous_scene( desktop->scene_manager, DesktopSceneMain); break; + case DesktopLockMenuEventStealthModeOn: + desktop_set_stealth_mode_state(desktop, true); + scene_manager_search_and_switch_to_previous_scene( + desktop->scene_manager, DesktopSceneMain); + break; + case DesktopLockMenuEventStealthModeOff: + desktop_set_stealth_mode_state(desktop, false); + scene_manager_search_and_switch_to_previous_scene( + desktop->scene_manager, DesktopSceneMain); + break; default: break; } diff --git a/applications/services/desktop/views/desktop_events.h b/applications/services/desktop/views/desktop_events.h index 666d179b83d..983e8443853 100644 --- a/applications/services/desktop/views/desktop_events.h +++ b/applications/services/desktop/views/desktop_events.h @@ -34,6 +34,8 @@ typedef enum { DesktopLockMenuEventPinLock, DesktopLockMenuEventDummyModeOn, DesktopLockMenuEventDummyModeOff, + DesktopLockMenuEventStealthModeOn, + DesktopLockMenuEventStealthModeOff, DesktopAnimationEventCheckAnimation, DesktopAnimationEventNewIdleAnimation, diff --git a/applications/services/desktop/views/desktop_view_lock_menu.c b/applications/services/desktop/views/desktop_view_lock_menu.c index 52570f8ca2b..8b25a890f16 100644 --- a/applications/services/desktop/views/desktop_view_lock_menu.c +++ b/applications/services/desktop/views/desktop_view_lock_menu.c @@ -7,7 +7,7 @@ typedef enum { DesktopLockMenuIndexLock, - DesktopLockMenuIndexPinLock, + DesktopLockMenuIndexStealth, DesktopLockMenuIndexDummy, DesktopLockMenuIndexTotalCount @@ -39,6 +39,14 @@ void desktop_lock_menu_set_dummy_mode_state(DesktopLockMenuView* lock_menu, bool true); } +void desktop_lock_menu_set_stealth_mode_state(DesktopLockMenuView* lock_menu, bool stealth_mode) { + with_view_model( + lock_menu->view, + DesktopLockMenuViewModel * model, + { model->stealth_mode = stealth_mode; }, + true); +} + void desktop_lock_menu_set_idx(DesktopLockMenuView* lock_menu, uint8_t idx) { furi_assert(idx < DesktopLockMenuIndexTotalCount); with_view_model( @@ -58,11 +66,11 @@ void desktop_lock_menu_draw_callback(Canvas* canvas, void* model) { if(i == DesktopLockMenuIndexLock) { str = "Lock"; - } else if(i == DesktopLockMenuIndexPinLock) { - if(m->pin_is_set) { - str = "Lock with PIN"; + } else if(i == DesktopLockMenuIndexStealth) { + if(m->stealth_mode) { + str = "Sound Mode"; } else { - str = "Set PIN"; + str = "Stealth Mode"; } } else if(i == DesktopLockMenuIndexDummy) { //-V547 if(m->dummy_mode) { @@ -93,6 +101,8 @@ bool desktop_lock_menu_input_callback(InputEvent* event, void* context) { uint8_t idx = 0; bool consumed = false; bool dummy_mode = false; + bool stealth_mode = false; + bool pin_is_set = false; bool update = false; with_view_model( @@ -120,14 +130,24 @@ bool desktop_lock_menu_input_callback(InputEvent* event, void* context) { } idx = model->idx; dummy_mode = model->dummy_mode; + stealth_mode = model->stealth_mode; + pin_is_set = model->pin_is_set; }, update); if(event->key == InputKeyOk) { - if((idx == DesktopLockMenuIndexLock) && (event->type == InputTypeShort)) { - lock_menu->callback(DesktopLockMenuEventLock, lock_menu->context); - } else if((idx == DesktopLockMenuIndexPinLock) && (event->type == InputTypeShort)) { - lock_menu->callback(DesktopLockMenuEventPinLock, lock_menu->context); + if((idx == DesktopLockMenuIndexLock)) { + if((pin_is_set) && (event->type == InputTypeShort)) { + lock_menu->callback(DesktopLockMenuEventPinLock, lock_menu->context); + } else if((pin_is_set == false) && (event->type == InputTypeShort)) { + lock_menu->callback(DesktopLockMenuEventLock, lock_menu->context); + } + } else if(idx == DesktopLockMenuIndexStealth) { + if((stealth_mode == false) && (event->type == InputTypeShort)) { + lock_menu->callback(DesktopLockMenuEventStealthModeOn, lock_menu->context); + } else if((stealth_mode == true) && (event->type == InputTypeShort)) { + lock_menu->callback(DesktopLockMenuEventStealthModeOff, lock_menu->context); + } } else if(idx == DesktopLockMenuIndexDummy) { if((dummy_mode == false) && (event->type == InputTypeShort)) { lock_menu->callback(DesktopLockMenuEventDummyModeOn, lock_menu->context); diff --git a/applications/services/desktop/views/desktop_view_lock_menu.h b/applications/services/desktop/views/desktop_view_lock_menu.h index 812aa9f99e8..03ce6fa8084 100644 --- a/applications/services/desktop/views/desktop_view_lock_menu.h +++ b/applications/services/desktop/views/desktop_view_lock_menu.h @@ -19,6 +19,7 @@ typedef struct { uint8_t idx; bool pin_is_set; bool dummy_mode; + bool stealth_mode; } DesktopLockMenuViewModel; void desktop_lock_menu_set_callback( @@ -29,6 +30,7 @@ void desktop_lock_menu_set_callback( View* desktop_lock_menu_get_view(DesktopLockMenuView* lock_menu); void desktop_lock_menu_set_pin_state(DesktopLockMenuView* lock_menu, bool pin_is_set); void desktop_lock_menu_set_dummy_mode_state(DesktopLockMenuView* lock_menu, bool dummy_mode); +void desktop_lock_menu_set_stealth_mode_state(DesktopLockMenuView* lock_menu, bool stealth_mode); void desktop_lock_menu_set_idx(DesktopLockMenuView* lock_menu, uint8_t idx); DesktopLockMenuView* desktop_lock_menu_alloc(); void desktop_lock_menu_free(DesktopLockMenuView* lock_menu); diff --git a/applications/services/notification/notification_app.c b/applications/services/notification/notification_app.c index 2e170f54766..f91a73f321d 100644 --- a/applications/services/notification/notification_app.c +++ b/applications/services/notification/notification_app.c @@ -20,9 +20,9 @@ static const uint8_t reset_sound_mask = 1 << 4; static const uint8_t reset_display_mask = 1 << 5; static const uint8_t reset_blink_mask = 1 << 6; -void notification_vibro_on(); +void notification_vibro_on(bool force); void notification_vibro_off(); -void notification_sound_on(float freq, float volume); +void notification_sound_on(float freq, float volume, bool force); void notification_sound_off(); uint8_t notification_settings_get_display_brightness(NotificationApp* app, uint8_t value); @@ -141,17 +141,21 @@ uint32_t notification_settings_display_off_delay_ticks(NotificationApp* app) { } // generics -void notification_vibro_on() { - furi_hal_vibro_on(true); +void notification_vibro_on(bool force) { + if(!furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode) || force) { + furi_hal_vibro_on(true); + } } void notification_vibro_off() { furi_hal_vibro_on(false); } -void notification_sound_on(float freq, float volume) { - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) { - furi_hal_speaker_start(freq, volume); +void notification_sound_on(float freq, float volume, bool force) { + if(!furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode) || force) { + if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) { + furi_hal_speaker_start(freq, volume); + } } } @@ -174,6 +178,8 @@ void notification_process_notification_message( NotificationApp* app, NotificationAppMessage* message) { uint32_t notification_message_index = 0; + bool force_volume = false; + bool force_vibro = false; const NotificationMessage* notification_message; notification_message = (*message->sequence)[notification_message_index]; @@ -269,7 +275,7 @@ void notification_process_notification_message( break; case NotificationMessageTypeVibro: if(notification_message->data.vibro.on) { - if(vibro_setting) notification_vibro_on(); + if(vibro_setting) notification_vibro_on(force_vibro); } else { notification_vibro_off(); } @@ -278,7 +284,8 @@ void notification_process_notification_message( case NotificationMessageTypeSoundOn: notification_sound_on( notification_message->data.sound.frequency, - notification_message->data.sound.volume * speaker_volume_setting); + notification_message->data.sound.volume * speaker_volume_setting, + force_volume); reset_mask |= reset_sound_mask; break; case NotificationMessageTypeSoundOff: @@ -307,9 +314,11 @@ void notification_process_notification_message( break; case NotificationMessageTypeForceSpeakerVolumeSetting: speaker_volume_setting = notification_message->data.forced_settings.speaker_volume; + force_volume = true; break; case NotificationMessageTypeForceVibroSetting: vibro_setting = notification_message->data.forced_settings.vibro; + force_vibro = true; break; case NotificationMessageTypeForceDisplayBrightnessSetting: display_brightness_setting = diff --git a/applications/settings/notification_settings/notification_settings_app.c b/applications/settings/notification_settings/notification_settings_app.c index d462163ad7e..8efbc5e0844 100644 --- a/applications/settings/notification_settings/notification_settings_app.c +++ b/applications/settings/notification_settings/notification_settings_app.c @@ -157,18 +157,33 @@ static NotificationAppSettings* alloc_settings() { variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, backlight_text[value_index]); - item = variable_item_list_add( - app->variable_item_list, "Volume", VOLUME_COUNT, volume_changed, app); - value_index = - value_index_float(app->notification->settings.speaker_volume, volume_value, VOLUME_COUNT); - variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, volume_text[value_index]); - - item = - variable_item_list_add(app->variable_item_list, "Vibro", VIBRO_COUNT, vibro_changed, app); - value_index = value_index_bool(app->notification->settings.vibro_on, vibro_value, VIBRO_COUNT); - variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, vibro_text[value_index]); + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode)) { + item = variable_item_list_add(app->variable_item_list, "Volume", 1, NULL, app); + value_index = 0; + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, "Stealth"); + } else { + item = variable_item_list_add( + app->variable_item_list, "Volume", VOLUME_COUNT, volume_changed, app); + value_index = value_index_float( + app->notification->settings.speaker_volume, volume_value, VOLUME_COUNT); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, volume_text[value_index]); + } + + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode)) { + item = variable_item_list_add(app->variable_item_list, "Vibro", 1, NULL, app); + value_index = 0; + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, "Stealth"); + } else { + item = variable_item_list_add( + app->variable_item_list, "Vibro", VIBRO_COUNT, vibro_changed, app); + value_index = + value_index_bool(app->notification->settings.vibro_on, vibro_value, VIBRO_COUNT); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, vibro_text[value_index]); + } app->view_dispatcher = view_dispatcher_alloc(); view_dispatcher_enable_queue(app->view_dispatcher); diff --git a/assets/icons/StatusBar/Muted_8x8.png b/assets/icons/StatusBar/Muted_8x8.png new file mode 100644 index 0000000000000000000000000000000000000000..fee4e09f5e68ce3fd468d2aae8ffea79a1fcd74a GIT binary patch literal 3626 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 Date: Wed, 19 Apr 2023 12:47:01 +0300 Subject: [PATCH 7/9] [FL-3089] Raw RFID documentation (#2592) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- documentation/LFRFIDRaw.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 documentation/LFRFIDRaw.md diff --git a/documentation/LFRFIDRaw.md b/documentation/LFRFIDRaw.md new file mode 100644 index 00000000000..5a8cbde60d7 --- /dev/null +++ b/documentation/LFRFIDRaw.md @@ -0,0 +1,23 @@ +# Reading RAW RFID data + +Flipper Zero has the option to read RAW data from 125 kHz cards that allows you to record the card's data and save it, similar to how a dictaphone records sound. + +To use this function, you need to activate the Debug mode on your Flipper Zero by doing the following: + +1. Go to **Main Menu** → **Settings** → **System**. + +2. Set **Debug** to **ON**. + +Once the Debug mode is activated on your Flipper Zero, you can read RAW data from 125 kHz RFID cards: + +1. Go to **Main Menu** → **125 kHz RFID** → **Extra Actions**. + +2. Select **RAW RFID** data and name the raw file. + +3. Read instructions and press **OK**. + +4. Apply the card to Flipper Zero's back. + +5. Once the reading is finished, press **OK**. + +Two files with data (with ASK and PSK modulations) will be saved in the `lfrfid` folder on the microSD card. Now, you can share it and the card's photo with developers by creating an issue on GitHub. From 39325036607d16effddfb5016cb7ffbd5b38ac49 Mon Sep 17 00:00:00 2001 From: hedger Date: Wed, 19 Apr 2023 15:08:13 +0400 Subject: [PATCH 8/9] [FL-3243] github: testing SDK with ufbt action (#2581) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * github: testing SDK with ufbt action * github: also build apps with ufbt * github: fixed dir lookup for ufbt * ufbt: checks for compatibility on app discovery * github: Conditional app skip for ufbt * github: fixed app build flow with ufbt * extra debug * github: lint: message capture * github: testing different output capture method for linters * shorter version of status check * github: updated comment actions to suppress warnings * Reverted formatting changes Co-authored-by: あく --- .github/workflows/build.yml | 44 ++++++++++++++++--- .../workflows/lint_and_submodule_check.yml | 34 +++++++++++--- scripts/ufbt/SConstruct | 14 ++++++ 3 files changed, 82 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5f6f50a9d0d..dfeb8d83f28 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -139,7 +139,7 @@ jobs: - name: 'Find Previous Comment' if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request }} - uses: peter-evans/find-comment@v1 + uses: peter-evans/find-comment@v2 id: fc with: issue-number: ${{ github.event.pull_request.number }} @@ -148,7 +148,7 @@ jobs: - name: 'Create or update comment' if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request}} - uses: peter-evans/create-or-update-comment@v1 + uses: peter-evans/create-or-update-comment@v3 with: comment-id: ${{ steps.fc.outputs.comment-id }} issue-number: ${{ github.event.pull_request.number }} @@ -162,6 +162,9 @@ jobs: compact: if: ${{ !startsWith(github.ref, 'refs/tags') }} runs-on: [self-hosted,FlipperZeroShell] + strategy: + matrix: + target: [f7, f18] steps: - name: 'Wipe workspace' run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; @@ -185,9 +188,40 @@ jobs: python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE" || cat "${{ github.event_path }}" - name: 'Build the firmware' + id: build-fw run: | set -e - for TARGET in ${TARGETS}; do - TARGET="$(echo "${TARGET}" | sed 's/f//')"; \ - ./fbt TARGET_HW=$TARGET DEBUG=0 COMPACT=1 fap_dist updater_package + TARGET="$(echo '${{ matrix.target }}' | sed 's/f//')"; \ + ./fbt TARGET_HW=$TARGET DEBUG=0 COMPACT=1 fap_dist updater_package + echo "sdk-file=$(ls dist/${{ matrix.target }}-*/flipper-z-${{ matrix.target }}-sdk-*.zip)" >> $GITHUB_OUTPUT + + - name: Deploy uFBT with SDK + uses: flipperdevices/flipperzero-ufbt-action@v0.1.0 + with: + task: setup + sdk-file: ${{ steps.build-fw.outputs.sdk-file }} + + - name: Build test app with SDK + run: | + mkdir testapp + cd testapp + ufbt create APPID=testapp + ufbt + + - name: Build example & external apps with uFBT + run: | + for appdir in 'applications/external' 'applications/examples'; do + for app in $(find "$appdir" -maxdepth 1 -mindepth 1 -type d); do + pushd $app + TARGETS_FAM=$(grep "targets" application.fam || echo "${{ matrix.target }}") + if ! grep -q "${{ matrix.target }}" <<< $TARGETS_FAM ; then + echo Skipping unsupported app: $app + popd + continue + fi + echo Building $app + ufbt + popd + done done + diff --git a/.github/workflows/lint_and_submodule_check.yml b/.github/workflows/lint_and_submodule_check.yml index cecfd12481e..999111cc95c 100644 --- a/.github/workflows/lint_and_submodule_check.yml +++ b/.github/workflows/lint_and_submodule_check.yml @@ -40,7 +40,7 @@ jobs: COMMITS_IN_BRANCH="$(git rev-list --count dev)"; if [ $COMMITS_IN_BRANCH -lt $SUB_COMMITS_MIN ]; then echo "name=fails::error" >> $GITHUB_OUTPUT; - echo "::error::Error: Too low commits in $SUB_BRANCH of submodule $SUB_PATH: $COMMITS_IN_BRANCH(expected $SUB_COMMITS_MIN+)"; + echo "::error::Error: Too few commits in $SUB_BRANCH of submodule $SUB_PATH: $COMMITS_IN_BRANCH(expected $SUB_COMMITS_MIN+)"; exit 1; fi if ! grep -q "/$SUB_BRANCH" <<< "$BRANCHES"; then @@ -51,12 +51,36 @@ jobs: - name: 'Check Python code formatting' id: syntax_check_py - run: ./fbt lint_py 2>&1 >/dev/null || echo "errors=1" >> $GITHUB_OUTPUT - + run: | + set +e; + ./fbt -s lint_py 2>&1 | tee lint-py.log; + if [ "${PIPESTATUS[0]}" -ne 0 ]; then + # Save multiline output + echo "errors=1" >> $GITHUB_OUTPUT; + printf "Python Lint errors:\n\`\`\`\n" >> $GITHUB_STEP_SUMMARY; + echo "$(cat lint-py.log)" >> $GITHUB_STEP_SUMMARY; + printf "\n\`\`\`\n" >> $GITHUB_STEP_SUMMARY; + exit 1; + else + echo "Python Lint: all good ✨" >> $GITHUB_STEP_SUMMARY; + fi + - name: 'Check C++ code formatting' - if: always() id: syntax_check_cpp - run: ./fbt lint 2>&1 >/dev/null || echo "errors=1" >> $GITHUB_OUTPUT + if: always() + run: | + set +e; + ./fbt -s lint 2>&1 | tee lint-cpp.log; + if [ "${PIPESTATUS[0]}" -ne 0 ]; then + # Save multiline output + echo "errors=1" >> $GITHUB_OUTPUT; + printf "C Lint errors:\n\`\`\`\n" >> $GITHUB_STEP_SUMMARY; + echo "$(cat lint-cpp.log)" >> $GITHUB_STEP_SUMMARY; + printf "\n\`\`\`\n" >> $GITHUB_STEP_SUMMARY; + exit 1; + else + echo "C Lint: all good ✨" >> $GITHUB_STEP_SUMMARY; + fi - name: Report code formatting errors if: ( steps.syntax_check_py.outputs.errors || steps.syntax_check_cpp.outputs.errors ) && github.event.pull_request diff --git a/scripts/ufbt/SConstruct b/scripts/ufbt/SConstruct index 7228e2f510c..ce7c8b9780a 100644 --- a/scripts/ufbt/SConstruct +++ b/scripts/ufbt/SConstruct @@ -1,6 +1,8 @@ from SCons.Platform import TempFileMunge from SCons.Node import FS from SCons.Errors import UserError +from SCons.Warnings import warn, WarningOnByDefault + import os import multiprocessing @@ -246,7 +248,12 @@ known_extapps = [ for apptype in apps_to_build_as_faps for app in appenv["APPBUILD"].get_apps_of_type(apptype, True) ] +incompatible_apps = [] for app in known_extapps: + if not app.supports_hardware_target(appenv.subst("f${TARGET_HW}")): + incompatible_apps.append(app) + continue + app_artifacts = appenv.BuildAppElf(app) app_src_dir = extract_abs_dir(app_artifacts.app._appdir) app_artifacts.installer = [ @@ -254,6 +261,13 @@ for app in known_extapps: appenv.Install(app_src_dir.Dir("dist").Dir("debug"), app_artifacts.debug), ] +if len(incompatible_apps): + print( + "WARNING: The following apps are not compatible with the current target hardware and will not be built: {}".format( + ", ".join([app.name for app in incompatible_apps]) + ) + ) + if appenv["FORCE"]: appenv.AlwaysBuild([extapp.compact for extapp in apps_artifacts.values()]) From 4d015a1106f2577b47c66c5dd7edcccc58caa2e5 Mon Sep 17 00:00:00 2001 From: hedger Date: Thu, 20 Apr 2023 16:57:51 +0400 Subject: [PATCH 9/9] [FL-3271] cubewb: updated to v1.16.0 (#2595) * cubewb: updated project to v1.16.0 * hal: updated api_symbols for f18 * FuriHal: add missing enterprise sleep and insomnia * FuriHal: slightly more paranoic sleep mode Co-authored-by: Aleksandr Kutuzov --- fbt_options.py | 2 +- firmware/targets/f18/api_symbols.csv | 40 +++++++-------- firmware/targets/f7/api_symbols.csv | 38 +++++++------- firmware/targets/f7/ble_glue/app_common.h | 1 + firmware/targets/f7/ble_glue/app_conf.h | 2 + firmware/targets/f7/ble_glue/app_debug.c | 3 +- firmware/targets/f7/ble_glue/ble_app.c | 10 +++- firmware/targets/f7/ble_glue/ble_const.h | 4 ++ firmware/targets/f7/ble_glue/ble_glue.c | 2 + firmware/targets/f7/ble_glue/compiler.h | 10 +++- firmware/targets/f7/ble_glue/gap.c | 51 +++++++++---------- firmware/targets/f7/furi_hal/furi_hal_flash.c | 3 ++ firmware/targets/f7/furi_hal/furi_hal_power.c | 29 +++++++++-- lib/STM32CubeWB | 2 +- scripts/ob.data | 4 +- 15 files changed, 124 insertions(+), 77 deletions(-) diff --git a/fbt_options.py b/fbt_options.py index a10c64b96ab..25e84afde57 100644 --- a/fbt_options.py +++ b/fbt_options.py @@ -20,7 +20,7 @@ COPRO_OB_DATA = "scripts/ob.data" # Must match lib/STM32CubeWB version -COPRO_CUBE_VERSION = "1.13.3" +COPRO_CUBE_VERSION = "1.16.0" COPRO_CUBE_DIR = "lib/STM32CubeWB" diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index a37ef02cc60..4ee3d8636b3 100644 --- a/firmware/targets/f18/api_symbols.csv +++ b/firmware/targets/f18/api_symbols.csv @@ -176,17 +176,17 @@ Header,+,lib/toolbox/tar/tar_archive.h,, Header,+,lib/toolbox/value_index.h,, Header,+,lib/toolbox/version.h,, Function,-,LL_ADC_CommonDeInit,ErrorStatus,ADC_Common_TypeDef* -Function,-,LL_ADC_CommonInit,ErrorStatus,"ADC_Common_TypeDef*, LL_ADC_CommonInitTypeDef*" +Function,-,LL_ADC_CommonInit,ErrorStatus,"ADC_Common_TypeDef*, const LL_ADC_CommonInitTypeDef*" Function,-,LL_ADC_CommonStructInit,void,LL_ADC_CommonInitTypeDef* Function,-,LL_ADC_DeInit,ErrorStatus,ADC_TypeDef* -Function,-,LL_ADC_INJ_Init,ErrorStatus,"ADC_TypeDef*, LL_ADC_INJ_InitTypeDef*" +Function,-,LL_ADC_INJ_Init,ErrorStatus,"ADC_TypeDef*, const LL_ADC_INJ_InitTypeDef*" Function,-,LL_ADC_INJ_StructInit,void,LL_ADC_INJ_InitTypeDef* -Function,-,LL_ADC_Init,ErrorStatus,"ADC_TypeDef*, LL_ADC_InitTypeDef*" -Function,-,LL_ADC_REG_Init,ErrorStatus,"ADC_TypeDef*, LL_ADC_REG_InitTypeDef*" +Function,-,LL_ADC_Init,ErrorStatus,"ADC_TypeDef*, const LL_ADC_InitTypeDef*" +Function,-,LL_ADC_REG_Init,ErrorStatus,"ADC_TypeDef*, const LL_ADC_REG_InitTypeDef*" Function,-,LL_ADC_REG_StructInit,void,LL_ADC_REG_InitTypeDef* Function,-,LL_ADC_StructInit,void,LL_ADC_InitTypeDef* Function,-,LL_COMP_DeInit,ErrorStatus,COMP_TypeDef* -Function,+,LL_COMP_Init,ErrorStatus,"COMP_TypeDef*, LL_COMP_InitTypeDef*" +Function,+,LL_COMP_Init,ErrorStatus,"COMP_TypeDef*, const LL_COMP_InitTypeDef*" Function,-,LL_COMP_StructInit,void,LL_COMP_InitTypeDef* Function,-,LL_CRC_DeInit,ErrorStatus,CRC_TypeDef* Function,-,LL_CRS_DeInit,ErrorStatus, @@ -199,16 +199,16 @@ Function,-,LL_EXTI_StructInit,void,LL_EXTI_InitTypeDef* Function,-,LL_GPIO_DeInit,ErrorStatus,GPIO_TypeDef* Function,+,LL_GPIO_Init,ErrorStatus,"GPIO_TypeDef*, LL_GPIO_InitTypeDef*" Function,-,LL_GPIO_StructInit,void,LL_GPIO_InitTypeDef* -Function,-,LL_I2C_DeInit,ErrorStatus,I2C_TypeDef* -Function,+,LL_I2C_Init,ErrorStatus,"I2C_TypeDef*, LL_I2C_InitTypeDef*" +Function,-,LL_I2C_DeInit,ErrorStatus,const I2C_TypeDef* +Function,+,LL_I2C_Init,ErrorStatus,"I2C_TypeDef*, const LL_I2C_InitTypeDef*" Function,-,LL_I2C_StructInit,void,LL_I2C_InitTypeDef* Function,-,LL_Init1msTick,void,uint32_t Function,+,LL_LPTIM_DeInit,ErrorStatus,LPTIM_TypeDef* Function,-,LL_LPTIM_Disable,void,LPTIM_TypeDef* -Function,+,LL_LPTIM_Init,ErrorStatus,"LPTIM_TypeDef*, LL_LPTIM_InitTypeDef*" +Function,+,LL_LPTIM_Init,ErrorStatus,"LPTIM_TypeDef*, const LL_LPTIM_InitTypeDef*" Function,-,LL_LPTIM_StructInit,void,LL_LPTIM_InitTypeDef* -Function,-,LL_LPUART_DeInit,ErrorStatus,USART_TypeDef* -Function,+,LL_LPUART_Init,ErrorStatus,"USART_TypeDef*, LL_LPUART_InitTypeDef*" +Function,-,LL_LPUART_DeInit,ErrorStatus,const USART_TypeDef* +Function,+,LL_LPUART_Init,ErrorStatus,"USART_TypeDef*, const LL_LPUART_InitTypeDef*" Function,-,LL_LPUART_StructInit,void,LL_LPUART_InitTypeDef* Function,-,LL_PKA_DeInit,ErrorStatus,PKA_TypeDef* Function,-,LL_PKA_Init,ErrorStatus,"PKA_TypeDef*, LL_PKA_InitTypeDef*" @@ -253,23 +253,23 @@ Function,+,LL_SPI_Init,ErrorStatus,"SPI_TypeDef*, LL_SPI_InitTypeDef*" Function,-,LL_SPI_StructInit,void,LL_SPI_InitTypeDef* Function,-,LL_SetFlashLatency,ErrorStatus,uint32_t Function,+,LL_SetSystemCoreClock,void,uint32_t -Function,-,LL_TIM_BDTR_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_BDTR_InitTypeDef*" +Function,-,LL_TIM_BDTR_Init,ErrorStatus,"TIM_TypeDef*, const LL_TIM_BDTR_InitTypeDef*" Function,-,LL_TIM_BDTR_StructInit,void,LL_TIM_BDTR_InitTypeDef* -Function,+,LL_TIM_DeInit,ErrorStatus,TIM_TypeDef* -Function,-,LL_TIM_ENCODER_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_ENCODER_InitTypeDef*" +Function,-,LL_TIM_DeInit,ErrorStatus,TIM_TypeDef* +Function,-,LL_TIM_ENCODER_Init,ErrorStatus,"TIM_TypeDef*, const LL_TIM_ENCODER_InitTypeDef*" Function,-,LL_TIM_ENCODER_StructInit,void,LL_TIM_ENCODER_InitTypeDef* -Function,-,LL_TIM_HALLSENSOR_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_HALLSENSOR_InitTypeDef*" +Function,-,LL_TIM_HALLSENSOR_Init,ErrorStatus,"TIM_TypeDef*, const LL_TIM_HALLSENSOR_InitTypeDef*" Function,-,LL_TIM_HALLSENSOR_StructInit,void,LL_TIM_HALLSENSOR_InitTypeDef* -Function,-,LL_TIM_IC_Init,ErrorStatus,"TIM_TypeDef*, uint32_t, LL_TIM_IC_InitTypeDef*" +Function,-,LL_TIM_IC_Init,ErrorStatus,"TIM_TypeDef*, uint32_t, const LL_TIM_IC_InitTypeDef*" Function,-,LL_TIM_IC_StructInit,void,LL_TIM_IC_InitTypeDef* -Function,+,LL_TIM_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_InitTypeDef*" -Function,+,LL_TIM_OC_Init,ErrorStatus,"TIM_TypeDef*, uint32_t, LL_TIM_OC_InitTypeDef*" +Function,+,LL_TIM_Init,ErrorStatus,"TIM_TypeDef*, const LL_TIM_InitTypeDef*" +Function,+,LL_TIM_OC_Init,ErrorStatus,"TIM_TypeDef*, uint32_t, const LL_TIM_OC_InitTypeDef*" Function,-,LL_TIM_OC_StructInit,void,LL_TIM_OC_InitTypeDef* Function,-,LL_TIM_StructInit,void,LL_TIM_InitTypeDef* -Function,-,LL_USART_ClockInit,ErrorStatus,"USART_TypeDef*, LL_USART_ClockInitTypeDef*" +Function,-,LL_USART_ClockInit,ErrorStatus,"USART_TypeDef*, const LL_USART_ClockInitTypeDef*" Function,-,LL_USART_ClockStructInit,void,LL_USART_ClockInitTypeDef* -Function,-,LL_USART_DeInit,ErrorStatus,USART_TypeDef* -Function,+,LL_USART_Init,ErrorStatus,"USART_TypeDef*, LL_USART_InitTypeDef*" +Function,-,LL_USART_DeInit,ErrorStatus,const USART_TypeDef* +Function,+,LL_USART_Init,ErrorStatus,"USART_TypeDef*, const LL_USART_InitTypeDef*" Function,-,LL_USART_StructInit,void,LL_USART_InitTypeDef* Function,-,LL_mDelay,void,uint32_t Function,-,SystemCoreClockUpdate,void, diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 43ede425e12..a2d70e7f86e 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -208,17 +208,17 @@ Header,+,lib/toolbox/tar/tar_archive.h,, Header,+,lib/toolbox/value_index.h,, Header,+,lib/toolbox/version.h,, Function,-,LL_ADC_CommonDeInit,ErrorStatus,ADC_Common_TypeDef* -Function,-,LL_ADC_CommonInit,ErrorStatus,"ADC_Common_TypeDef*, LL_ADC_CommonInitTypeDef*" +Function,-,LL_ADC_CommonInit,ErrorStatus,"ADC_Common_TypeDef*, const LL_ADC_CommonInitTypeDef*" Function,-,LL_ADC_CommonStructInit,void,LL_ADC_CommonInitTypeDef* Function,-,LL_ADC_DeInit,ErrorStatus,ADC_TypeDef* -Function,-,LL_ADC_INJ_Init,ErrorStatus,"ADC_TypeDef*, LL_ADC_INJ_InitTypeDef*" +Function,-,LL_ADC_INJ_Init,ErrorStatus,"ADC_TypeDef*, const LL_ADC_INJ_InitTypeDef*" Function,-,LL_ADC_INJ_StructInit,void,LL_ADC_INJ_InitTypeDef* -Function,-,LL_ADC_Init,ErrorStatus,"ADC_TypeDef*, LL_ADC_InitTypeDef*" -Function,-,LL_ADC_REG_Init,ErrorStatus,"ADC_TypeDef*, LL_ADC_REG_InitTypeDef*" +Function,-,LL_ADC_Init,ErrorStatus,"ADC_TypeDef*, const LL_ADC_InitTypeDef*" +Function,-,LL_ADC_REG_Init,ErrorStatus,"ADC_TypeDef*, const LL_ADC_REG_InitTypeDef*" Function,-,LL_ADC_REG_StructInit,void,LL_ADC_REG_InitTypeDef* Function,-,LL_ADC_StructInit,void,LL_ADC_InitTypeDef* Function,-,LL_COMP_DeInit,ErrorStatus,COMP_TypeDef* -Function,+,LL_COMP_Init,ErrorStatus,"COMP_TypeDef*, LL_COMP_InitTypeDef*" +Function,+,LL_COMP_Init,ErrorStatus,"COMP_TypeDef*, const LL_COMP_InitTypeDef*" Function,-,LL_COMP_StructInit,void,LL_COMP_InitTypeDef* Function,-,LL_CRC_DeInit,ErrorStatus,CRC_TypeDef* Function,-,LL_CRS_DeInit,ErrorStatus, @@ -231,16 +231,16 @@ Function,-,LL_EXTI_StructInit,void,LL_EXTI_InitTypeDef* Function,-,LL_GPIO_DeInit,ErrorStatus,GPIO_TypeDef* Function,+,LL_GPIO_Init,ErrorStatus,"GPIO_TypeDef*, LL_GPIO_InitTypeDef*" Function,-,LL_GPIO_StructInit,void,LL_GPIO_InitTypeDef* -Function,-,LL_I2C_DeInit,ErrorStatus,I2C_TypeDef* -Function,+,LL_I2C_Init,ErrorStatus,"I2C_TypeDef*, LL_I2C_InitTypeDef*" +Function,-,LL_I2C_DeInit,ErrorStatus,const I2C_TypeDef* +Function,+,LL_I2C_Init,ErrorStatus,"I2C_TypeDef*, const LL_I2C_InitTypeDef*" Function,-,LL_I2C_StructInit,void,LL_I2C_InitTypeDef* Function,-,LL_Init1msTick,void,uint32_t Function,+,LL_LPTIM_DeInit,ErrorStatus,LPTIM_TypeDef* Function,-,LL_LPTIM_Disable,void,LPTIM_TypeDef* -Function,+,LL_LPTIM_Init,ErrorStatus,"LPTIM_TypeDef*, LL_LPTIM_InitTypeDef*" +Function,+,LL_LPTIM_Init,ErrorStatus,"LPTIM_TypeDef*, const LL_LPTIM_InitTypeDef*" Function,-,LL_LPTIM_StructInit,void,LL_LPTIM_InitTypeDef* -Function,-,LL_LPUART_DeInit,ErrorStatus,USART_TypeDef* -Function,+,LL_LPUART_Init,ErrorStatus,"USART_TypeDef*, LL_LPUART_InitTypeDef*" +Function,-,LL_LPUART_DeInit,ErrorStatus,const USART_TypeDef* +Function,+,LL_LPUART_Init,ErrorStatus,"USART_TypeDef*, const LL_LPUART_InitTypeDef*" Function,-,LL_LPUART_StructInit,void,LL_LPUART_InitTypeDef* Function,-,LL_PKA_DeInit,ErrorStatus,PKA_TypeDef* Function,-,LL_PKA_Init,ErrorStatus,"PKA_TypeDef*, LL_PKA_InitTypeDef*" @@ -285,23 +285,23 @@ Function,+,LL_SPI_Init,ErrorStatus,"SPI_TypeDef*, LL_SPI_InitTypeDef*" Function,-,LL_SPI_StructInit,void,LL_SPI_InitTypeDef* Function,-,LL_SetFlashLatency,ErrorStatus,uint32_t Function,+,LL_SetSystemCoreClock,void,uint32_t -Function,-,LL_TIM_BDTR_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_BDTR_InitTypeDef*" +Function,-,LL_TIM_BDTR_Init,ErrorStatus,"TIM_TypeDef*, const LL_TIM_BDTR_InitTypeDef*" Function,-,LL_TIM_BDTR_StructInit,void,LL_TIM_BDTR_InitTypeDef* Function,+,LL_TIM_DeInit,ErrorStatus,TIM_TypeDef* -Function,-,LL_TIM_ENCODER_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_ENCODER_InitTypeDef*" +Function,-,LL_TIM_ENCODER_Init,ErrorStatus,"TIM_TypeDef*, const LL_TIM_ENCODER_InitTypeDef*" Function,-,LL_TIM_ENCODER_StructInit,void,LL_TIM_ENCODER_InitTypeDef* -Function,-,LL_TIM_HALLSENSOR_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_HALLSENSOR_InitTypeDef*" +Function,-,LL_TIM_HALLSENSOR_Init,ErrorStatus,"TIM_TypeDef*, const LL_TIM_HALLSENSOR_InitTypeDef*" Function,-,LL_TIM_HALLSENSOR_StructInit,void,LL_TIM_HALLSENSOR_InitTypeDef* -Function,-,LL_TIM_IC_Init,ErrorStatus,"TIM_TypeDef*, uint32_t, LL_TIM_IC_InitTypeDef*" +Function,-,LL_TIM_IC_Init,ErrorStatus,"TIM_TypeDef*, uint32_t, const LL_TIM_IC_InitTypeDef*" Function,-,LL_TIM_IC_StructInit,void,LL_TIM_IC_InitTypeDef* -Function,+,LL_TIM_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_InitTypeDef*" -Function,+,LL_TIM_OC_Init,ErrorStatus,"TIM_TypeDef*, uint32_t, LL_TIM_OC_InitTypeDef*" +Function,+,LL_TIM_Init,ErrorStatus,"TIM_TypeDef*, const LL_TIM_InitTypeDef*" +Function,+,LL_TIM_OC_Init,ErrorStatus,"TIM_TypeDef*, uint32_t, const LL_TIM_OC_InitTypeDef*" Function,-,LL_TIM_OC_StructInit,void,LL_TIM_OC_InitTypeDef* Function,-,LL_TIM_StructInit,void,LL_TIM_InitTypeDef* -Function,-,LL_USART_ClockInit,ErrorStatus,"USART_TypeDef*, LL_USART_ClockInitTypeDef*" +Function,-,LL_USART_ClockInit,ErrorStatus,"USART_TypeDef*, const LL_USART_ClockInitTypeDef*" Function,-,LL_USART_ClockStructInit,void,LL_USART_ClockInitTypeDef* -Function,-,LL_USART_DeInit,ErrorStatus,USART_TypeDef* -Function,+,LL_USART_Init,ErrorStatus,"USART_TypeDef*, LL_USART_InitTypeDef*" +Function,-,LL_USART_DeInit,ErrorStatus,const USART_TypeDef* +Function,+,LL_USART_Init,ErrorStatus,"USART_TypeDef*, const LL_USART_InitTypeDef*" Function,-,LL_USART_StructInit,void,LL_USART_InitTypeDef* Function,-,LL_mDelay,void,uint32_t Function,-,SystemCoreClockUpdate,void, diff --git a/firmware/targets/f7/ble_glue/app_common.h b/firmware/targets/f7/ble_glue/app_common.h index 214c85acd23..8eaf2308593 100644 --- a/firmware/targets/f7/ble_glue/app_common.h +++ b/firmware/targets/f7/ble_glue/app_common.h @@ -33,6 +33,7 @@ extern "C" { #include #include +#include #include "app_conf.h" diff --git a/firmware/targets/f7/ble_glue/app_conf.h b/firmware/targets/f7/ble_glue/app_conf.h index aaa755a3622..ee5115cfed3 100644 --- a/firmware/targets/f7/ble_glue/app_conf.h +++ b/firmware/targets/f7/ble_glue/app_conf.h @@ -8,6 +8,8 @@ #define CFG_TX_POWER (0x19) /* +0dBm */ +#define CFG_IDENTITY_ADDRESS GAP_PUBLIC_ADDR + /** * Define Advertising parameters */ diff --git a/firmware/targets/f7/ble_glue/app_debug.c b/firmware/targets/f7/ble_glue/app_debug.c index 78e789ac307..b443bee21f0 100644 --- a/firmware/targets/f7/ble_glue/app_debug.c +++ b/firmware/targets/f7/ble_glue/app_debug.c @@ -33,7 +33,8 @@ PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static SHCI_C2_DEBUG_TracesConfig_t APPD_TracesConfig = {0, 0, 0, 0}; PLACE_IN_SECTION("MB_MEM2") ALIGN(4) -static SHCI_C2_DEBUG_GeneralConfig_t APPD_GeneralConfig = {BLE_DTB_CFG, SYS_DBG_CFG1, {0, 0}}; +static SHCI_C2_DEBUG_GeneralConfig_t APPD_GeneralConfig = + {BLE_DTB_CFG, SYS_DBG_CFG1, {0, 0}, 0, 0, 0, 0, 0}; /** * THE DEBUG ON GPIO FOR CPU2 IS INTENDED TO BE USED ONLY ON REQUEST FROM ST SUPPORT diff --git a/firmware/targets/f7/ble_glue/ble_app.c b/firmware/targets/f7/ble_glue/ble_app.c index 4fc4d521be1..cc6065b9755 100644 --- a/firmware/targets/f7/ble_glue/ble_app.c +++ b/firmware/targets/f7/ble_glue/ble_app.c @@ -18,8 +18,8 @@ PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t ble_app_cmd_buffer; PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint32_t ble_app_nvm[BLE_NVM_SRAM_SIZE]; _Static_assert( - sizeof(SHCI_C2_Ble_Init_Cmd_Packet_t) == 49, - "Ble stack config structure size mismatch"); + sizeof(SHCI_C2_Ble_Init_Cmd_Packet_t) == 58, + "Ble stack config structure size mismatch (check new config options - last updated for v.1.16.0)"); typedef struct { FuriMutex* hci_mtx; @@ -88,6 +88,12 @@ bool ble_app_init() { .min_tx_power = 0, .max_tx_power = 0, .rx_model_config = 1, + /* New stack (13.3->16.0)*/ + .max_adv_set_nbr = 1, // Only used if SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV is set + .max_adv_data_len = 31, // Only used if SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV is set + .tx_path_compens = 0, // RF TX Path Compensation, * 0.1 dB + .rx_path_compens = 0, // RF RX Path Compensation, * 0.1 dB + .ble_core_version = 11, // BLE Core Version: 11(5.2), 12(5.3) }}; status = SHCI_C2_BLE_Init(&ble_init_cmd_packet); if(status) { diff --git a/firmware/targets/f7/ble_glue/ble_const.h b/firmware/targets/f7/ble_glue/ble_const.h index 0e4c8b398d9..85f734b62c2 100644 --- a/firmware/targets/f7/ble_glue/ble_const.h +++ b/firmware/targets/f7/ble_glue/ble_const.h @@ -23,6 +23,7 @@ #include #include #include "osal.h" +#include "compiler.h" /* Default BLE variant */ #ifndef BASIC_FEATURES @@ -34,6 +35,9 @@ #ifndef LL_ONLY #define LL_ONLY 0 #endif +#ifndef LL_ONLY_BASIC +#define LL_ONLY_BASIC 0 +#endif #ifndef BEACON_ONLY #define BEACON_ONLY 0 #endif diff --git a/firmware/targets/f7/ble_glue/ble_glue.c b/firmware/targets/f7/ble_glue/ble_glue.c index a2f2f1a94b0..c73bbd86601 100644 --- a/firmware/targets/f7/ble_glue/ble_glue.c +++ b/firmware/targets/f7/ble_glue/ble_glue.c @@ -403,7 +403,9 @@ void shci_cmd_resp_release(uint32_t flag) { void shci_cmd_resp_wait(uint32_t timeout) { UNUSED(timeout); if(ble_glue) { + furi_hal_power_insomnia_enter(); furi_semaphore_acquire(ble_glue->shci_sem, FuriWaitForever); + furi_hal_power_insomnia_exit(); } } diff --git a/firmware/targets/f7/ble_glue/compiler.h b/firmware/targets/f7/ble_glue/compiler.h index 1c39628197d..98a93d71264 100644 --- a/firmware/targets/f7/ble_glue/compiler.h +++ b/firmware/targets/f7/ble_glue/compiler.h @@ -5,7 +5,7 @@ ***************************************************************************** * @attention * - * Copyright (c) 2018-2022 STMicroelectronics. + * Copyright (c) 2018-2023 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file @@ -18,6 +18,14 @@ #ifndef COMPILER_H__ #define COMPILER_H__ +#ifndef __PACKED_STRUCT +#define __PACKED_STRUCT PACKED(struct) +#endif + +#ifndef __PACKED_UNION +#define __PACKED_UNION PACKED(union) +#endif + /** * @brief This is the section dedicated to IAR toolchain */ diff --git a/firmware/targets/f7/ble_glue/gap.c b/firmware/targets/f7/ble_glue/gap.c index cbb2a203bd1..f0a9ced3cb7 100644 --- a/firmware/targets/f7/ble_glue/gap.c +++ b/firmware/targets/f7/ble_glue/gap.c @@ -1,5 +1,6 @@ #include "gap.h" +#include "app_common.h" #include #include @@ -85,7 +86,7 @@ static void gap_verify_connection_parameters(Gap* gap) { SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { hci_event_pckt* event_pckt; evt_le_meta_event* meta_evt; - evt_blue_aci* blue_evt; + evt_blecore_aci* blue_evt; hci_le_phy_update_complete_event_rp0* evt_le_phy_update_complete; uint8_t tx_phy; uint8_t rx_phy; @@ -97,7 +98,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { furi_mutex_acquire(gap->state_mutex, FuriWaitForever); } switch(event_pckt->evt) { - case EVT_DISCONN_COMPLETE: { + case HCI_DISCONNECTION_COMPLETE_EVT_CODE: { hci_disconnection_complete_event_rp0* disconnection_complete_event = (hci_disconnection_complete_event_rp0*)event_pckt->data; if(disconnection_complete_event->Connection_Handle == gap->service.connection_handle) { @@ -106,6 +107,8 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { FURI_LOG_I( TAG, "Disconnect from client. Reason: %02X", disconnection_complete_event->Reason); } + // Enterprise sleep + furi_delay_us(666 + 666); if(gap->enable_adv) { // Restart advertising gap_advertise_start(GapStateAdvFast); @@ -114,10 +117,10 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { gap->on_event_cb(event, gap->context); } break; - case EVT_LE_META_EVENT: + case HCI_LE_META_EVT_CODE: meta_evt = (evt_le_meta_event*)event_pckt->data; switch(meta_evt->subevent) { - case EVT_LE_CONN_UPDATE_COMPLETE: { + case HCI_LE_CONNECTION_UPDATE_COMPLETE_SUBEVT_CODE: { hci_le_connection_update_complete_event_rp0* event = (hci_le_connection_update_complete_event_rp0*)meta_evt->data; gap->connection_params.conn_interval = event->Conn_Interval; @@ -128,7 +131,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { break; } - case EVT_LE_PHY_UPDATE_COMPLETE: + case HCI_LE_PHY_UPDATE_COMPLETE_SUBEVT_CODE: evt_le_phy_update_complete = (hci_le_phy_update_complete_event_rp0*)meta_evt->data; if(evt_le_phy_update_complete->Status) { FURI_LOG_E( @@ -144,7 +147,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { } break; - case EVT_LE_CONN_COMPLETE: { + case HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE: { hci_le_connection_complete_event_rp0* event = (hci_le_connection_complete_event_rp0*)meta_evt->data; gap->connection_params.conn_interval = event->Conn_Interval; @@ -168,16 +171,16 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { } break; - case EVT_VENDOR: - blue_evt = (evt_blue_aci*)event_pckt->data; + case HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE: + blue_evt = (evt_blecore_aci*)event_pckt->data; switch(blue_evt->ecode) { aci_gap_pairing_complete_event_rp0* pairing_complete; - case EVT_BLUE_GAP_LIMITED_DISCOVERABLE: + case ACI_GAP_LIMITED_DISCOVERABLE_VSEVT_CODE: FURI_LOG_I(TAG, "Limited discoverable event"); break; - case EVT_BLUE_GAP_PASS_KEY_REQUEST: { + case ACI_GAP_PASS_KEY_REQ_VSEVT_CODE: { // Generate random PIN code uint32_t pin = rand() % 999999; //-V1064 aci_gap_pass_key_resp(gap->service.connection_handle, pin); @@ -190,7 +193,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { gap->on_event_cb(event, gap->context); } break; - case EVT_BLUE_ATT_EXCHANGE_MTU_RESP: { + case ACI_ATT_EXCHANGE_MTU_RESP_VSEVT_CODE: { aci_att_exchange_mtu_resp_event_rp0* pr = (void*)blue_evt->data; FURI_LOG_I(TAG, "Rx MTU size: %d", pr->Server_RX_MTU); // Set maximum packet size given header size is 3 bytes @@ -199,32 +202,28 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { gap->on_event_cb(event, gap->context); } break; - case EVT_BLUE_GAP_AUTHORIZATION_REQUEST: + case ACI_GAP_AUTHORIZATION_REQ_VSEVT_CODE: FURI_LOG_D(TAG, "Authorization request event"); break; - case EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED: + case ACI_GAP_SLAVE_SECURITY_INITIATED_VSEVT_CODE: FURI_LOG_D(TAG, "Slave security initiated"); break; - case EVT_BLUE_GAP_BOND_LOST: + case ACI_GAP_BOND_LOST_VSEVT_CODE: FURI_LOG_D(TAG, "Bond lost event. Start rebonding"); aci_gap_allow_rebond(gap->service.connection_handle); break; - case EVT_BLUE_GAP_DEVICE_FOUND: - FURI_LOG_D(TAG, "Device found event"); - break; - - case EVT_BLUE_GAP_ADDR_NOT_RESOLVED: + case ACI_GAP_ADDR_NOT_RESOLVED_VSEVT_CODE: FURI_LOG_D(TAG, "Address not resolved event"); break; - case EVT_BLUE_GAP_KEYPRESS_NOTIFICATION: + case ACI_GAP_KEYPRESS_NOTIFICATION_VSEVT_CODE: FURI_LOG_D(TAG, "Key press notification event"); break; - case EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE: { + case ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE: { uint32_t pin = ((aci_gap_numeric_comparison_value_event_rp0*)(blue_evt->data))->Numeric_Value; FURI_LOG_I(TAG, "Verify numeric comparison: %06lu", pin); @@ -234,7 +233,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { break; } - case EVT_BLUE_GAP_PAIRING_CMPLT: + case ACI_GAP_PAIRING_COMPLETE_VSEVT_CODE: pairing_complete = (aci_gap_pairing_complete_event_rp0*)blue_evt->data; if(pairing_complete->Status) { FURI_LOG_E( @@ -249,11 +248,11 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { } break; - case EVT_BLUE_GAP_PROCEDURE_COMPLETE: + case ACI_L2CAP_CONNECTION_UPDATE_RESP_VSEVT_CODE: FURI_LOG_D(TAG, "Procedure complete event"); break; - case EVT_BLUE_L2CAP_CONNECTION_UPDATE_RESP: { + case ACI_L2CAP_CONNECTION_UPDATE_REQ_VSEVT_CODE: { uint16_t result = ((aci_l2cap_connection_update_resp_event_rp0*)(blue_evt->data))->Result; if(result == 0) { @@ -362,7 +361,7 @@ static void gap_init_svc(Gap* gap) { CFG_ENCRYPTION_KEY_SIZE_MAX, CFG_USED_FIXED_PIN, 0, - PUBLIC_ADDR); + CFG_IDENTITY_ADDRESS); // Configure whitelist aci_gap_configure_whitelist(); } @@ -397,7 +396,7 @@ static void gap_advertise_start(GapState new_state) { ADV_IND, min_interval, max_interval, - PUBLIC_ADDR, + CFG_IDENTITY_ADDRESS, 0, strlen(gap->service.adv_name), (uint8_t*)gap->service.adv_name, diff --git a/firmware/targets/f7/furi_hal/furi_hal_flash.c b/firmware/targets/f7/furi_hal/furi_hal_flash.c index fc021d96921..d2dbff55f30 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_flash.c +++ b/firmware/targets/f7/furi_hal/furi_hal_flash.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -114,6 +115,7 @@ static void furi_hal_flash_lock(void) { } static void furi_hal_flash_begin_with_core2(bool erase_flag) { + furi_hal_power_insomnia_enter(); /* Take flash controller ownership */ while(LL_HSEM_1StepLock(HSEM, CFG_HW_FLASH_SEMID) != 0) { furi_thread_yield(); @@ -188,6 +190,7 @@ static void furi_hal_flash_end_with_core2(bool erase_flag) { /* Release flash controller ownership */ LL_HSEM_ReleaseLock(HSEM, CFG_HW_FLASH_SEMID, 0); + furi_hal_power_insomnia_exit(); } static void furi_hal_flash_end(bool erase_flag) { diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 9a87cef15c3..3e4e3f48b60 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -29,6 +29,14 @@ #define FURI_HAL_POWER_DEBUG_STOP_GPIO (&gpio_ext_pc3) #endif +#ifndef FURI_HAL_POWER_DEBUG_ABNORMAL_GPIO +#define FURI_HAL_POWER_DEBUG_ABNORMAL_GPIO (&gpio_ext_pb3) +#endif + +#ifndef FURI_HAL_POWER_STOP_MODE +#define FURI_HAL_POWER_STOP_MODE (LL_PWR_MODE_STOP2) +#endif + typedef struct { volatile uint8_t insomnia; volatile uint8_t suppress_charge; @@ -84,14 +92,16 @@ void furi_hal_power_init() { #ifdef FURI_HAL_POWER_DEBUG furi_hal_gpio_init_simple(FURI_HAL_POWER_DEBUG_WFI_GPIO, GpioModeOutputPushPull); furi_hal_gpio_init_simple(FURI_HAL_POWER_DEBUG_STOP_GPIO, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(FURI_HAL_POWER_DEBUG_ABNORMAL_GPIO, GpioModeOutputPushPull); furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 0); furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 0); + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_ABNORMAL_GPIO, 0); #endif LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); LL_PWR_SMPS_SetMode(LL_PWR_SMPS_STEP_DOWN); - LL_PWR_SetPowerMode(LL_PWR_MODE_STOP2); - LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STOP2); + LL_PWR_SetPowerMode(FURI_HAL_POWER_STOP_MODE); + LL_C2_PWR_SetPowerMode(FURI_HAL_POWER_STOP_MODE); furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); bq27220_init(&furi_hal_i2c_handle_power, &cedv); @@ -148,7 +158,9 @@ bool furi_hal_power_sleep_available() { static inline bool furi_hal_power_deep_sleep_available() { return furi_hal_bt_is_alive() && !furi_hal_rtc_is_flag_set(FuriHalRtcFlagLegacySleep) && - !furi_hal_debug_is_gdb_session_active(); + !furi_hal_debug_is_gdb_session_active() && !LL_PWR_IsActiveFlag_CRPE() && + !LL_PWR_IsActiveFlag_CRP() && !LL_PWR_IsActiveFlag_BLEA() && + !LL_PWR_IsActiveFlag_BLEWU(); } static inline void furi_hal_power_light_sleep() { @@ -199,7 +211,16 @@ static inline void furi_hal_power_deep_sleep() { __force_stores(); #endif - __WFI(); + bool should_abort_sleep = LL_PWR_IsActiveFlag_CRPE() || LL_PWR_IsActiveFlag_CRP() || + LL_PWR_IsActiveFlag_BLEA() || LL_PWR_IsActiveFlag_BLEWU(); + + if(should_abort_sleep) { +#ifdef FURI_HAL_POWER_DEBUG + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_ABNORMAL_GPIO, 1); +#endif + } else { + __WFI(); + } LL_LPM_EnableSleep(); diff --git a/lib/STM32CubeWB b/lib/STM32CubeWB index a9e29b431f6..06b8133fa29 160000 --- a/lib/STM32CubeWB +++ b/lib/STM32CubeWB @@ -1 +1 @@ -Subproject commit a9e29b431f6dac95b6fc860a717834f35b7f78e5 +Subproject commit 06b8133fa295474507b55b1a5695d4b8bf804ed6 diff --git a/scripts/ob.data b/scripts/ob.data index 5276a5103bf..605faccbfc6 100644 --- a/scripts/ob.data +++ b/scripts/ob.data @@ -14,7 +14,7 @@ IWDGSTOP:0x1:rw IWDGSW:0x1:rw IPCCDBA:0x0:rw ESE:0x1:r -SFSA:0xD7:r +SFSA:0xD5:r FSD:0x0:r DDS:0x1:r C2OPT:0x1:r @@ -22,7 +22,7 @@ NBRSD:0x0:r SNBRSA:0xD:r BRSD:0x0:r SBRSA:0x12:r -SBRV:0x35C00:r +SBRV:0x35400:r PCROP1A_STRT:0x1FF:r PCROP1A_END:0x0:r PCROP_RDP:0x1:rw