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 01/13] 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 19bc9f99..4a7015d1 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 df953007..912912b4 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 02/13] [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 f5c7af02..7af5244a 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 7394fd3c..0956cae4 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 cb74d7a8..597710a5 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 1dc5ebd0..90582c1e 100644 --- a/debug/flipperapps.py +++ b/debug/flipperapps.py @@ -135,6 +135,7 @@ class FlipperAppStateHelper: 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 @@ class FlipperAppStateHelper: 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 00000000..8ff77016 --- /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 14d63e9c..23b2e2b5 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 5d5b7bbc..493f5963 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 4a7015d1..6db483db 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 3c4708d1..7d2caab3 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 89984352..3ef57813 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 83562c73..a2f2f1a9 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 cf19451e..d85524ce 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 3b5dfe62..3dc03ea6 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 ee9743e6..3fc1fbea 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 fd601ec7..9a87cef1 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 f36407cc..d3461c4d 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 912912b4..abfd977e 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 f2991730..6e585c51 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 84e7fe39..7bd45c35 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 88397bbb..befbb4f4 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 462e20e4..00182fa2 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 b16b04a6..0d9f46f0 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 910527ce..64f9f72f 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 03a364ab..830bb191 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 1eb6a337..55ab72ba 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 d832a466..2e948662 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 03/13] [#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 174413ba..e671552c 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 c76a8ffa..e6191d5b 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 04/13] [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 d8458854..78e789ac 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 30be3c7c..4fc4d521 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 8ef037d6..cbb2a203 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 1f2b5d6e..2c353f52 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 05/13] [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 329f3b74..167266a8 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 16b60231..2dcea348 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 57a4ec9a..5b09e9b5 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 ec290e08..d11fdc16 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 d14b8eee..f1c139b5 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 0c70702c..9ba20a83 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 zcmaJ@c{r3^8-FYn%91rCV?>K(%%GTzZ7ic~jcrt7jKN@*#$ZO0C8cD`mNlWIhBigA zCHq*SNGLlA4GGE8H{S2<{k}iGzUR80=bUq&`}e!=bKk#nUC&ipYjZ&X836zQ1T9b| zXwJBU^YZcWaK7CA5?TNtfFvN1wiZYvh(aZM68!K0K=04C3&JF=Na_!*;DsHH`{o~~ z`Go^uMJ8Xfh;yFE4FG#dMAWb$Dq6r%Tw-??%Ar1@M*x)_J(_#4+{@@%^r;w!Gdf@8 z2MeEF2xiaCt-W8XoXVP7?_hKahwTtguyf0ziqtFj#bICszU*XjZpx76+R5 z0FUgRdI$i?0N}?6F$M$o1%cV`7W&(OzM`Z-DWETJZxJ65%LSw#G~dr{_!4k)2uG`O z*VX~KOhd3bZ*2)znDcX(Id@pqHXtw#lOSy9285*>tF{3k9c}=*Ppq8>WXY4O(OolK zx0@L5+Fz?DV!VAkY_GuWJ*h_0_O8l(K8Y?U z#cyg(?sHp~>M-PV&6t4lsOiPhRF)W3GP}O-tA%EH%%!OQv)m zBJ6oyVb_Vz0W{#kwK!Z@7gWge`UmWp>sL(Ou3}`Anr zx1T#EOl+3#>?M&pzlekcbBrYhc~5Cpu~f8z&xt?s6146BIO(2EsZy}$YCYW@{x|_+ z##H{QuumaJ>Ffa^G1ny2exa5dyK2nK-;5deo9XZ$G*qS@gIz-e7|F&Mla6dhY#`?L|57`0hu; zZ=JFr<_6kA?5-4vX$52`wP#8qSp{nOJ#R7yUW65I$TY2j|6}An)3i5f-M*i9OixWm zeh=Cucv&#A3FUrJ+E@C#bm5*dX-K-|-ED8v(wpry-os?my>1HMBs*XZFCPw(NNg2N zfu}g8gr-d0w|DS&Fz8|2-)aBALHNO0#|wAO9G=>a74g55e9%)Q=kT)VNJ$4e2pw~AKYKv z?>Lq<`$2VZ^KA*Z&%QSaOXd*^pqAFY}6gotcK$;M`D^%`%^<$+fuDkSC}^)^&J_GOOEfE7QJU?RA-32PJXts zPMNzh;hC)G_lh%%>jN{1L*k?2@rSw(E!mO!p|k6=0<#&j+vjwbvCB%!#N|%8w!NZq zy~k+BLa4NWwm?5h%w&#qPNvw51OoYSj8Y#yjTJzT{)?*`XL;D2^Z^XNC~bKeTSb*1`lHFyY7tr*%H znjX4iJ!kFMPu52KkD3w2H^~L-ZEjqzxF)!&!ezpr^7!(|^QQCO*`d8HcH7JCkX`x` z#=H0ho#m-X88{KQ-EvE%){Aj=S8+HzX2DzPoBU-S(U> zdf41Ax?G+hoi4R{LHy8R*nRacCrj;U=V&Xcz07gvHLt3;h4`ZDFOCiPJf{YFF@5~d zez@7p^04yz<>B-zKTH?WL}_CC`RA^V*Z0*Uu8#S0Px)nNW{qdqr_yjG6N7m#q$a03 zSUEv@&f3liAv#evMbn-bOhkf=Z6SMXCJISba$?^uWk%VUR_Dd$oqSwYeq8UyWVU0< zvd+h27mz=_FWZ;}G-~qOpj8-&(l=fxE?PO7^nPM?emM6*O*c6!IV&G6NJuSJd9P7+ zu*}9&MI}jaoH0pkl})c2Q3;TL7um0yZ3u@#cEgxpi1pWbttUXH3loqDG^ zx5j@0I*` zWL7>o>SXQO6SBl0_V<4}Ue-D{gPJLrAu(5+YaSl2@-gapb9r8{Saux?o`wc#Ur zL?4OWhk{ckGQ-IInR6LI&nTx33)LA-ygD#+H{|@7?dRJauLobZ52ar$TjHBRF;u$Y zH33Yud}1!*b`|^c_55tPvvTIuWxqn%&@o&OWDms^Y~cH^vU8A;EjC7l~nfEA~ zDaOWU%gf6O%2a*x=tvqVd{QXZ*&6Eji!tN>U}|V%bnQeZX1#BI=W0x6O$noDk;;Bh z^bp>p*d$-s!9XnBT`%q!xWF!FR}3{($)_J&H{7&c?D~moDtu$JqCXX~xei&mw73?g ztF)W*S1C<1#n9}?p0pq=6%QDBklpbh3nJDFkH%v?80T8>dH}$4kYJCYVXQ3SI5JTk zyXB)!CsH_Q0MIj_Q?NK+JPqWI_acxGVD`%zFo@uR06S@0X;@K^cy9tKn2NUxwzkIw z`{Hyxzy|stJvy92K*ZCqAUe^H(|^RvS^Oh^Jc*-uDo5Oq1JY`oi?Q9- z(%$sfwXHi+u~ebK8TMP47}?YN-Q7GqJOC~;5nh-=Nc0{P@y3W&D6GyjJR}U@0eB1n 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 493f5963..a37ef02c 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 3ef57813..43ede425 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 06/13] [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 | 37 ++++++++++++----- assets/icons/StatusBar/Muted_8x8.png | Bin 0 -> 3626 bytes .../targets/furi_hal_include/furi_hal_rtc.h | 1 + 10 files changed, 121 insertions(+), 29 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 41470ed3..bdb73009 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 2f3ec9b5..ede6bbcc 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 365fe170..bfaa8a03 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 666d179b..983e8443 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 52570f8c..8b25a890 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 812aa9f9..03ce6fa8 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 2e170f54..f91a73f3 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 d462163a..8efbc5e0 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]); + 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]); + } - 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, "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 zcmaJ^c|26@+dsBKS+a&?jCd-`%vg%a*q2eZ#x^Q3#$Yf@V=yD6q?BygvL=+&kV=_k zON4AuBujP@8cWFjj_3FE{N6v_-t#%<+}C~G*Y|r}*L{EgIOm3~wYdPlG(P|U0v1RU z6no^|d3d?l@5K)5R{+3oj5jv6wJLFmL43BAD;oRFhY&)m~g zzsmqvfx+7-?3^on8^Bx@7BQ%gjN*3`6W^DKbf~-1#gEL28p%1#^fJ5|btc;3oc0g7 z{(={w!K~TY_0Q`SlbMqnZS;1b@O>gm2@|fFC`?2n;+D0A_w#=;&hG+J+4W0*7)9k$F~ z-RcXT11_W+q!rcVMQmQc5Ce-*v6Ic*Mlj;aq{3E1hu)=NUUCsGf?ILT2u2!0ifdB{&NqLBrV^ug=Ug-`DlsZ?!9ls7&U^KZ)7WK zBsnp=ObqrOs?ilT+BFt_fdAh96hkTd8h8))ixMvBoPFuT!liFu+5(e9BIhnolO=b# z?a!{=UvZ6(+pv*W6eACh+UFkI18(D$OpE0PW00D+!}CE?QDUdT^^KH#&O#%f1Q(>j zf+|H!C+3{NT6|w4Nd4x<%?fi^(&cBTxju0Q7`%EYCw=o>j(-PLQ^+MeCD*q@y7V9- z{AF%I$Ej}tR3P+bEH=CYCg^$V3+CLd>!xlu(9%i`64-IHmSdb2Ru+9cP+X=a8^hu~ z#2FnfI>USZs&K8}mH2pbv?bd3q2i1}sYp4m6JNwtSnXfn#D_MeioqhQbu@SQ(|EKQ zL+OY7LHTUO^M477x+WqI2{zpxv*wpqj90hVW8sVJL#pQ6Do8FFb=6uz>t`F&WFZ_x(WQtnOHxO~qH1$Jjr|-AjQ zKZEuPToZ_BK)N56@|C(MRj|KI3X*2|fahasTBAMmv${;0*BzldBnR}-<)b0u3GYRc z;mMB4Vabz^>>d0a^tZUkyO{@6cv2s8AY<0#mkY`;c z5OUGd&e;EvC&M$rGi%~PD~I5_r$ci(Uoua&$+ro#T~y^#)mMGm?Nj7g6jpS+H@LT| z*L{{UD=|CW%L*W88DyzsEx`%!l>ol-W96sIBg^{&+P~|4#7@(v_?F%;2~G`km@g52 z<}FEnXLYkWo%d5^_Q`N6cYb1m`MZ@zc%%#OLM!w>g0dzUBFdFORlT9bU!Jp+ z-)v0Pmx{iPn8^F4ne`{5k3~16^rnO~^Q2g%tT664>N(OKmmEJcEV|E4t4tHRo&0QN zoHF)iz%!a(J}k;8ste2@42q42#U1H9vSdf>h0Sct@Xw^r?3&eC#w;r?6PDX$TMmfG zcAuc02%%5|S_1vZ71Q~{nr{p13g1pSdC7R)^Uqq;l6-I~zF8zSFjdlyP;j$=csIB? zd0hHOdFP9dOL-ZuGy03Z5IzmGAnHROuUn~Q$TYdUMX(Hi&aI$FF0_nh6=W3DF2+wn z&Ig`%KEGah(B^rjQg%0#(AZaZcBr!Xq8nTffm>^v;?jGk$9XsS?)9n%Rp3EHl|oo| zSX$WbjqLRkYt5T+zp97n3lj6zJZ>CsIL0|DFH2v3&gIJ`$DPJ~f43G-4A1LbkiB~1 zMtk`LoaHEqq#DTunN_Stzn4mShxmKmEb%ikYtR-Y%Y)tfVz0IH4hn~n9;{kUwY=nw z8Z!5bV#?vA(j-?y#f}_Rf28*Pbg3Qn0(C{Dn=$6R?o}B(A6Izm)rmfzmy|#+hL0c0 z4?B~=3}-%KUZ!3DWjdcKLKQv4H+y5OuBQ%hW7MB>(l1>jb1dCHg^Dd6@6UZDIWg7N zoE@a=tmPaZq8)ihB=wp8cm&AE7P8-FyntvWE4pwsBhtpSDmNzg^wTotN!{BMS&qre z+5;y-jn}-d*_Z{q)8Ml~Dbo|AZog7kv~o1*{>o_oa^Z`rPEux4W*$lapHiy)8CrI@ z%*In$IZ^tFUSw4G#-8q5V%?m@%Pb%r*3H$O|+v>idC z92R`&{R^?Eh|c@>jg_xBX(ksYH8m59f1Y`T6~`odIIw(DyUsdZIx3m$${;fy7XK}msNdH>g}!`2)ei^7$GZu;wvj@ zrs9P%&B?dYG<1pB`Qyq!oV2@4dG$ot0Mk6kran9F;{A)emrYsIK2(xl|C8$KXM6O5azXl(KTpYFicCYPi|J&BVv`b}6ywga!awohx zfT5a4$U)qzWPQ7pmnC~%*1W20JB$Sz#RfEJ#W`i?WF1D#uZ~?w94+uD$j-9XM|?`_ zr>|IUr1`p>cB%9-ZqL@2r2eohb6sg#{5l!uGFL(V30`sUQ!G1GgeXRshmkjjkx$N& zrg1CHvrf9j)Sp(s9PP1i5ak$`FfoS{tFvo5BwEyGD!OfBNQ|;)Dp1D1%(e2g6^uk37>v7=| zc!NTNTtyolG5=trsI4!Q#blKaHdM-`9o{h5vR&+0!!{IruvyWY4B6U%tXy4O57$xL z$Ns96qMD+qb|g<~5Qc&S3_VEhIFJPaeI*=tS^oVa>se$i3l+3bu}1-_dtN1w5*_3WMiB+9vMu**#%qMV}pIM zIv!wsJ&-O9&L$w>s2C89;79a_(-7dldEsn(#|;64{tlt~BEbJC3T!+BuT-8DQhSQU^uR2>F^vG3!mu;Xxb4LD2(^v?xmC!~0I!cit>|Do-kpHD6`v0?2>^+0fFk}c!4Z73S??5Z7|38#K_&3_0io*T3 z-v5)>-=0p!K~OkGDuxR4F)=F zg~8&9JDwwdL#(Xe7DRt4hKR*km>|Gx5;Z*D1FoS1HPJRTGckc4H-*7WO|+pp+NPS? zn%bs1T2Ny{t>0J^5;lNHBVuSo13}C{;vUc*;?A0 zvd8W1?fYNu4zMjwD$3e!8yGKxo@CFCSeO{v(|T2+oA>}=Z|&{PR5hP@%p4#N Date: Wed, 19 Apr 2023 12:47:01 +0300 Subject: [PATCH 07/13] [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 00000000..5a8cbde6 --- /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 08/13] [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 5f6f50a9..dfeb8d83 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 cecfd124..999111cc 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 7228e2f5..ce7c8b97 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 09/13] [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 a10c64b9..25e84afd 100644 --- a/fbt_options.py +++ b/fbt_options.py @@ -20,7 +20,7 @@ DIST_SUFFIX = "local" 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 a37ef02c..4ee3d863 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 43ede425..a2d70e7f 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 214c85ac..8eaf2308 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 aaa755a3..ee5115cf 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 78e789ac..b443bee2 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 4fc4d521..cc6065b9 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 0e4c8b39..85f734b6 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 a2f2f1a9..c73bbd86 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 1c396281..98a93d71 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 cbb2a203..f0a9ced3 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 fc021d96..d2dbff55 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 9a87cef1..3e4e3f48 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 a9e29b43..06b8133f 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 5276a510..605faccb 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 From 1ef70c0bb4db8c4b7f537b39195fcba419af023b Mon Sep 17 00:00:00 2001 From: hedger Date: Mon, 24 Apr 2023 11:19:36 +0400 Subject: [PATCH 10/13] [FL-3280] cubewb: downgraded to v1.15.0 (#2605) * cubewb: downgraded to v1.15.0 * hal: updated f18 symbols to match LL * hal: flash: use furi_hal_cortex_timer for timeouts * scripts: fixed cube version validation from config file * hal: flash: added 3 seconds timeout when waiting for C2 to unlock flash controller. On timeout, triggers furi_check * nfc: fixed missing interrupt setup on multiple platformSetIrqCallback() invocations * hal: gpio: don't trigger furi_check on furi_hal_gpio_add_int_callback() with same parameters * Reverted NFC fixes - will be in a separate PR * scripts: storage: fixed exception handler for paths --- fbt_options.py | 2 +- firmware/targets/f18/api_symbols.csv | 4 +-- firmware/targets/f7/api_symbols.csv | 4 +-- firmware/targets/f7/ble_glue/ble_app.c | 4 +-- firmware/targets/f7/furi_hal/furi_hal_flash.c | 30 ++++++++++++------- lib/STM32CubeWB | 2 +- scripts/fbt_tools/fbt_dist.py | 4 ++- scripts/flipper/assets/copro.py | 4 +-- scripts/flipper/storage.py | 4 ++- 9 files changed, 35 insertions(+), 23 deletions(-) diff --git a/fbt_options.py b/fbt_options.py index 25e84afd..4fd7ef49 100644 --- a/fbt_options.py +++ b/fbt_options.py @@ -20,7 +20,7 @@ DIST_SUFFIX = "local" COPRO_OB_DATA = "scripts/ob.data" # Must match lib/STM32CubeWB version -COPRO_CUBE_VERSION = "1.16.0" +COPRO_CUBE_VERSION = "1.15.0" COPRO_CUBE_DIR = "lib/STM32CubeWB" diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index 4ee3d863..eb2d6f43 100644 --- a/firmware/targets/f18/api_symbols.csv +++ b/firmware/targets/f18/api_symbols.csv @@ -199,8 +199,8 @@ 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,const I2C_TypeDef* -Function,+,LL_I2C_Init,ErrorStatus,"I2C_TypeDef*, const LL_I2C_InitTypeDef*" +Function,-,LL_I2C_DeInit,ErrorStatus,I2C_TypeDef* +Function,+,LL_I2C_Init,ErrorStatus,"I2C_TypeDef*, LL_I2C_InitTypeDef*" Function,-,LL_I2C_StructInit,void,LL_I2C_InitTypeDef* Function,-,LL_Init1msTick,void,uint32_t Function,+,LL_LPTIM_DeInit,ErrorStatus,LPTIM_TypeDef* diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index a2d70e7f..d0c6b36a 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -231,8 +231,8 @@ 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,const I2C_TypeDef* -Function,+,LL_I2C_Init,ErrorStatus,"I2C_TypeDef*, const LL_I2C_InitTypeDef*" +Function,-,LL_I2C_DeInit,ErrorStatus,I2C_TypeDef* +Function,+,LL_I2C_Init,ErrorStatus,"I2C_TypeDef*, LL_I2C_InitTypeDef*" Function,-,LL_I2C_StructInit,void,LL_I2C_InitTypeDef* Function,-,LL_Init1msTick,void,uint32_t Function,+,LL_LPTIM_DeInit,ErrorStatus,LPTIM_TypeDef* diff --git a/firmware/targets/f7/ble_glue/ble_app.c b/firmware/targets/f7/ble_glue/ble_app.c index cc6065b9..a325830c 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) == 58, - "Ble stack config structure size mismatch (check new config options - last updated for v.1.16.0)"); + sizeof(SHCI_C2_Ble_Init_Cmd_Packet_t) == 57, + "Ble stack config structure size mismatch (check new config options - last updated for v.1.15.0)"); typedef struct { FuriMutex* hci_mtx; diff --git a/firmware/targets/f7/furi_hal/furi_hal_flash.c b/firmware/targets/f7/furi_hal/furi_hal_flash.c index d2dbff55..464d88d9 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_flash.c +++ b/firmware/targets/f7/furi_hal/furi_hal_flash.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -26,6 +27,16 @@ #define FURI_HAL_FLASH_OPT_KEY2 0x4C5D6E7F #define FURI_HAL_FLASH_OB_TOTAL_WORDS (0x80 / (sizeof(uint32_t) * 2)) +/* lib/STM32CubeWB/Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_RfWithFlash/Core/Src/flash_driver.c + * ProcessSingleFlashOperation, quote: + > In most BLE application, the flash should not be blocked by the CPU2 longer than FLASH_TIMEOUT_VALUE (1000ms) + > However, it could be that for some marginal application, this time is longer. + > ... there is no other way than waiting the operation to be completed. + > If for any reason this test is never passed, this means there is a failure in the system and there is no other + > way to recover than applying a device reset. + */ +#define FURI_HAL_FLASH_C2_LOCK_TIMEOUT_MS 3000u /* 3 seconds */ + #define IS_ADDR_ALIGNED_64BITS(__VALUE__) (((__VALUE__)&0x7U) == (0x00UL)) #define IS_FLASH_PROGRAM_ADDRESS(__VALUE__) \ (((__VALUE__) >= FLASH_BASE) && ((__VALUE__) <= (FLASH_BASE + FLASH_SIZE - 8UL)) && \ @@ -131,9 +142,11 @@ static void furi_hal_flash_begin_with_core2(bool erase_flag) { for(volatile uint32_t i = 0; i < 35; i++) ; + FuriHalCortexTimer timer = furi_hal_cortex_timer_get(FURI_HAL_FLASH_C2_LOCK_TIMEOUT_MS * 1000); while(true) { /* Wait till flash controller become usable */ while(LL_FLASH_IsActiveFlag_OperationSuspended()) { + furi_check(!furi_hal_cortex_timer_is_expired(timer)); furi_thread_yield(); }; @@ -143,6 +156,7 @@ static void furi_hal_flash_begin_with_core2(bool erase_flag) { /* Actually we already have mutex for it, but specification is specification */ if(LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID)) { taskEXIT_CRITICAL(); + furi_check(!furi_hal_cortex_timer_is_expired(timer)); furi_thread_yield(); continue; } @@ -150,6 +164,7 @@ static void furi_hal_flash_begin_with_core2(bool erase_flag) { /* Take sempahopre and prevent core2 from anything funky */ if(LL_HSEM_1StepLock(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) != 0) { taskEXIT_CRITICAL(); + furi_check(!furi_hal_cortex_timer_is_expired(timer)); furi_thread_yield(); continue; } @@ -231,17 +246,13 @@ static void furi_hal_flush_cache(void) { bool furi_hal_flash_wait_last_operation(uint32_t timeout) { uint32_t error = 0; - uint32_t countdown = 0; /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset. Even if the FLASH operation fails, the BUSY flag will be reset and an error flag will be set */ - countdown = timeout; + FuriHalCortexTimer timer = furi_hal_cortex_timer_get(timeout * 1000); while(READ_BIT(FLASH->SR, FLASH_SR_BSY)) { - if(LL_SYSTICK_IsActiveCounterFlag()) { - countdown--; - } - if(countdown == 0) { + if(furi_hal_cortex_timer_is_expired(timer)) { return false; } } @@ -264,12 +275,9 @@ bool furi_hal_flash_wait_last_operation(uint32_t timeout) { CLEAR_BIT(FLASH->SR, error); /* Wait for control register to be written */ - countdown = timeout; + timer = furi_hal_cortex_timer_get(timeout * 1000); while(READ_BIT(FLASH->SR, FLASH_SR_CFGBSY)) { - if(LL_SYSTICK_IsActiveCounterFlag()) { - countdown--; - } - if(countdown == 0) { + if(furi_hal_cortex_timer_is_expired(timer)) { return false; } } diff --git a/lib/STM32CubeWB b/lib/STM32CubeWB index 06b8133f..c4cec8ae 160000 --- a/lib/STM32CubeWB +++ b/lib/STM32CubeWB @@ -1 +1 @@ -Subproject commit 06b8133fa295474507b55b1a5695d4b8bf804ed6 +Subproject commit c4cec8ae57a79e949a184cd0b4117a008a0a25a7 diff --git a/scripts/fbt_tools/fbt_dist.py b/scripts/fbt_tools/fbt_dist.py index f0b44348..d2808419 100644 --- a/scripts/fbt_tools/fbt_dist.py +++ b/scripts/fbt_tools/fbt_dist.py @@ -112,6 +112,8 @@ def DistCommand(env, name, source, **kw): def generate(env): + if not env["VERBOSE"]: + env.SetDefault(COPROCOMSTR="\tCOPRO\t${TARGET}") env.AddMethod(AddFwProject) env.AddMethod(DistCommand) env.AddMethod(AddOpenOCDFlashTarget) @@ -147,7 +149,7 @@ def generate(env): '--stack_file="${COPRO_STACK_BIN}" ' "--stack_addr=${COPRO_STACK_ADDR} ", ], - "\tCOPRO\t${TARGET}", + "$COPROCOMSTR", ) ), } diff --git a/scripts/flipper/assets/copro.py b/scripts/flipper/assets/copro.py index b61ac032..e0375b51 100644 --- a/scripts/flipper/assets/copro.py +++ b/scripts/flipper/assets/copro.py @@ -34,7 +34,7 @@ class Copro: self.mcu_copro = None self.logger = logging.getLogger(self.__class__.__name__) - def loadCubeInfo(self, cube_dir, cube_version): + def loadCubeInfo(self, cube_dir, reference_cube_version): if not os.path.isdir(cube_dir): raise Exception(f'"{cube_dir}" doesn\'t exists') self.cube_dir = cube_dir @@ -50,7 +50,7 @@ class Copro: if not cube_version or not cube_version.startswith("FW.WB"): raise Exception(f"Incorrect Cube package or version info") cube_version = cube_version.replace("FW.WB.", "", 1) - if cube_version != cube_version: + if cube_version != reference_cube_version: raise Exception(f"Unsupported cube version") self.version = cube_version diff --git a/scripts/flipper/storage.py b/scripts/flipper/storage.py index 7b56ee0d..cff32ceb 100644 --- a/scripts/flipper/storage.py +++ b/scripts/flipper/storage.py @@ -335,7 +335,9 @@ class FlipperStorage: def _check_no_error(self, response, path=None): if self.has_error(response): - raise FlipperStorageException.from_error_code(self.get_error(response)) + raise FlipperStorageException.from_error_code( + path, self.get_error(response) + ) def size(self, path: str): """file size on Flipper""" From d70ba2b74064e24586adea56231b569ff66d71df Mon Sep 17 00:00:00 2001 From: hedger Date: Tue, 25 Apr 2023 20:33:13 +0400 Subject: [PATCH 11/13] [FL-3286] Don't reboot on crash in debug builds (#2613) * furi: never reboot on furi_crash in debug builds * furi: crash info: added registers * furi: check and assert optimization, split registers and stack info dump * furi: macro uppercase Co-authored-by: SG --- furi/core/check.c | 31 ++++++++++++++++++++++++++++++- furi/core/check.h | 24 ++++++++++++++---------- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/furi/core/check.c b/furi/core/check.c index 64f9f72f..f5390639 100644 --- a/furi/core/check.c +++ b/furi/core/check.c @@ -14,7 +14,7 @@ #include PLACE_IN_SECTION("MB_MEM2") const char* __furi_check_message = NULL; -PLACE_IN_SECTION("MB_MEM2") uint32_t __furi_check_registers[12] = {0}; +PLACE_IN_SECTION("MB_MEM2") uint32_t __furi_check_registers[13] = {0}; /** Load r12 value to __furi_check_message and store registers to __furi_check_registers */ #define GET_MESSAGE_AND_STORE_REGISTERS() \ @@ -22,6 +22,7 @@ PLACE_IN_SECTION("MB_MEM2") uint32_t __furi_check_registers[12] = {0}; "str r12, [r11] \n" \ "ldr r12, =__furi_check_registers \n" \ "stm r12, {r0-r11} \n" \ + "str lr, [r12, #48] \n" \ : \ : \ : "memory"); @@ -62,6 +63,25 @@ static void __furi_put_uint32_as_text(uint32_t data) { furi_hal_console_puts(tmp_str); } +static void __furi_put_uint32_as_hex(uint32_t data) { + char tmp_str[] = "0xFFFFFFFF"; + itoa(data, tmp_str, 16); + furi_hal_console_puts(tmp_str); +} + +static void __furi_print_register_info() { + // Print registers + for(uint8_t i = 0; i < 12; i++) { + furi_hal_console_puts("\r\n\tr"); + __furi_put_uint32_as_text(i); + furi_hal_console_puts(" : "); + __furi_put_uint32_as_hex(__furi_check_registers[i]); + } + + furi_hal_console_puts("\r\n\tlr : "); + __furi_put_uint32_as_hex(__furi_check_registers[12]); +} + static void __furi_print_stack_info() { furi_hal_console_puts("\r\n\tstack watermark: "); __furi_put_uint32_as_text(uxTaskGetStackHighWaterMark(NULL) * 4); @@ -101,32 +121,41 @@ FURI_NORETURN void __furi_crash() { if(__furi_check_message == NULL) { __furi_check_message = "Fatal Error"; + } else if(__furi_check_message == (void*)__FURI_ASSERT_MESSAGE_FLAG) { + __furi_check_message = "furi_assert failed"; + } else if(__furi_check_message == (void*)__FURI_CHECK_MESSAGE_FLAG) { + __furi_check_message = "furi_check failed"; } furi_hal_console_puts("\r\n\033[0;31m[CRASH]"); __furi_print_name(isr); furi_hal_console_puts(__furi_check_message); + __furi_print_register_info(); if(!isr) { __furi_print_stack_info(); } __furi_print_heap_info(); +#ifndef FURI_DEBUG // Check if debug enabled by DAP // https://developer.arm.com/documentation/ddi0403/d/Debug-Architecture/ARMv7-M-Debug/Debug-register-support-in-the-SCS/Debug-Halting-Control-and-Status-Register--DHCSR?lang=en bool debug = CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk; if(debug) { +#endif 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); +#ifndef FURI_DEBUG } else { furi_hal_rtc_set_fault_data((uint32_t)__furi_check_message); furi_hal_console_puts("\r\nRebooting system.\r\n"); furi_hal_console_puts("\033[0m\r\n"); furi_hal_power_reset(); } +#endif __builtin_unreachable(); } diff --git a/furi/core/check.h b/furi/core/check.h index 192c5260..a507fc1e 100644 --- a/furi/core/check.h +++ b/furi/core/check.h @@ -21,6 +21,10 @@ extern "C" { #define FURI_NORETURN noreturn #endif +// Flags instead of pointers will save ~4 bytes on furi_assert and furi_check calls. +#define __FURI_ASSERT_MESSAGE_FLAG (0x01) +#define __FURI_CHECK_MESSAGE_FLAG (0x02) + /** Crash system */ FURI_NORETURN void __furi_crash(); @@ -44,20 +48,20 @@ FURI_NORETURN void __furi_halt(); } while(0) /** Check condition and crash if check failed */ -#define furi_check(__e) \ - do { \ - if(!(__e)) { \ - furi_crash("furi_check failed\r\n"); \ - } \ +#define furi_check(__e) \ + do { \ + if(!(__e)) { \ + furi_crash(__FURI_ASSERT_MESSAGE_FLAG); \ + } \ } while(0) /** Only in debug build: Assert condition and crash if assert failed */ #ifdef FURI_DEBUG -#define furi_assert(__e) \ - do { \ - if(!(__e)) { \ - furi_crash("furi_assert failed\r\n"); \ - } \ +#define furi_assert(__e) \ + do { \ + if(!(__e)) { \ + furi_crash(__FURI_CHECK_MESSAGE_FLAG); \ + } \ } while(0) #else #define furi_assert(__e) \ From 0ec8fc4c55178e9ad7daa014a9268dcfbb8da573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Wed, 26 Apr 2023 05:11:42 +0900 Subject: [PATCH 12/13] FuriHal: use proper divider for core2 when transition to sleep, remove extra stop mode transition checks, cleanup code. Furi: proper assert and check messages. (#2615) --- firmware/targets/f7/ble_glue/ble_app.c | 2 +- firmware/targets/f7/furi_hal/furi_hal_bt.c | 8 ++----- firmware/targets/f7/furi_hal/furi_hal_clock.c | 10 ++++++++- firmware/targets/f7/furi_hal/furi_hal_power.c | 21 ++----------------- furi/core/check.h | 20 +++++++++--------- 5 files changed, 24 insertions(+), 37 deletions(-) diff --git a/firmware/targets/f7/ble_glue/ble_app.c b/firmware/targets/f7/ble_glue/ble_app.c index a325830c..37d8f7cd 100644 --- a/firmware/targets/f7/ble_glue/ble_app.c +++ b/firmware/targets/f7/ble_glue/ble_app.c @@ -88,7 +88,7 @@ bool ble_app_init() { .min_tx_power = 0, .max_tx_power = 0, .rx_model_config = 1, - /* New stack (13.3->16.0)*/ + /* New stack (13.3->15.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 diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index 0857fe4e..b08c9ea2 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -84,9 +84,7 @@ void furi_hal_bt_init() { } // Explicitly tell that we are in charge of CLK48 domain - if(!LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_CLK48_CONFIG_SEMID)) { - furi_check(LL_HSEM_1StepLock(HSEM, CFG_HW_CLK48_CONFIG_SEMID) == 0); - } + furi_check(LL_HSEM_1StepLock(HSEM, CFG_HW_CLK48_CONFIG_SEMID) == 0); // Start Core2 ble_glue_init(); @@ -129,9 +127,7 @@ bool furi_hal_bt_start_radio_stack() { furi_mutex_acquire(furi_hal_bt_core2_mtx, FuriWaitForever); // Explicitly tell that we are in charge of CLK48 domain - if(!LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_CLK48_CONFIG_SEMID)) { - furi_check(LL_HSEM_1StepLock(HSEM, CFG_HW_CLK48_CONFIG_SEMID) == 0); - } + furi_check(LL_HSEM_1StepLock(HSEM, CFG_HW_CLK48_CONFIG_SEMID) == 0); do { // Wait until C2 is started or timeout diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index d85524ce..a4df4877 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -213,7 +213,11 @@ void furi_hal_clock_switch_to_hsi() { while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) ; - LL_FLASH_SetLatency(LL_FLASH_LATENCY_1); + LL_C2_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + + LL_FLASH_SetLatency(LL_FLASH_LATENCY_0); + while(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_0) + ; } void furi_hal_clock_switch_to_pll() { @@ -228,7 +232,11 @@ void furi_hal_clock_switch_to_pll() { while(!LL_RCC_PLLSAI1_IsReady()) ; + LL_C2_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2); + LL_FLASH_SetLatency(LL_FLASH_LATENCY_3); + while(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_3) + ; LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSE); diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 3e4e3f48..7d9334c2 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -29,10 +29,6 @@ #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 @@ -92,10 +88,8 @@ 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); @@ -158,9 +152,7 @@ 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() && !LL_PWR_IsActiveFlag_CRPE() && - !LL_PWR_IsActiveFlag_CRP() && !LL_PWR_IsActiveFlag_BLEA() && - !LL_PWR_IsActiveFlag_BLEWU(); + !furi_hal_debug_is_gdb_session_active(); } static inline void furi_hal_power_light_sleep() { @@ -211,16 +203,7 @@ static inline void furi_hal_power_deep_sleep() { __force_stores(); #endif - 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(); - } + __WFI(); LL_LPM_EnableSleep(); diff --git a/furi/core/check.h b/furi/core/check.h index a507fc1e..ea83f221 100644 --- a/furi/core/check.h +++ b/furi/core/check.h @@ -48,21 +48,21 @@ FURI_NORETURN void __furi_halt(); } while(0) /** Check condition and crash if check failed */ -#define furi_check(__e) \ - do { \ - if(!(__e)) { \ - furi_crash(__FURI_ASSERT_MESSAGE_FLAG); \ - } \ - } while(0) - -/** Only in debug build: Assert condition and crash if assert failed */ -#ifdef FURI_DEBUG -#define furi_assert(__e) \ +#define furi_check(__e) \ do { \ if(!(__e)) { \ furi_crash(__FURI_CHECK_MESSAGE_FLAG); \ } \ } while(0) + +/** Only in debug build: Assert condition and crash if assert failed */ +#ifdef FURI_DEBUG +#define furi_assert(__e) \ + do { \ + if(!(__e)) { \ + furi_crash(__FURI_ASSERT_MESSAGE_FLAG); \ + } \ + } while(0) #else #define furi_assert(__e) \ do { \ From 408edb3e99751b5374571340c9517027845a65fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Thu, 27 Apr 2023 23:01:13 +0900 Subject: [PATCH 13/13] Keep HSI16 working in stop mode. (#2621) --- firmware/targets/f7/furi_hal/furi_hal_clock.c | 3 ++- firmware/targets/f7/furi_hal/furi_hal_power.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index a4df4877..a76fbfbc 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -144,6 +144,7 @@ void furi_hal_clock_init() { LL_RCC_SetRNGClockSource(LL_RCC_RNG_CLKSOURCE_CLK48); LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLLSAI1); LL_RCC_SetCLK48ClockSource(LL_RCC_CLK48_CLKSOURCE_PLLSAI1); + LL_RCC_HSI_EnableInStopMode(); // Ensure that MR is capable of work in STOP0 LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSE); LL_RCC_SetSMPSPrescaler(LL_RCC_SMPS_DIV_1); LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE); @@ -207,8 +208,8 @@ void furi_hal_clock_switch_to_hsi() { while(!LL_RCC_HSI_IsReady()) ; - LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI); LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSI); + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI); while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) ; diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 7d9334c2..e380de7f 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -94,6 +94,7 @@ void furi_hal_power_init() { LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); LL_PWR_SMPS_SetMode(LL_PWR_SMPS_STEP_DOWN); + LL_PWR_SetPowerMode(FURI_HAL_POWER_STOP_MODE); LL_C2_PWR_SetPowerMode(FURI_HAL_POWER_STOP_MODE);