From 88a686091398971850e831047dd08791c9763ad8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Tue, 9 Apr 2024 16:01:55 +0900 Subject: [PATCH 1/4] Update radio stack to v1.19.0 (#3545) * Update radio stack to v1.19.0 * Ble: set max connection interal same as min, kinda speedups everything --- fbt_options.py | 2 +- lib/ble_profile/extra_profiles/hid_profile.c | 4 ++-- lib/stm32wb_copro | 2 +- targets/f7/ble_glue/ble_app.c | 4 ++-- targets/f7/ble_glue/extra_beacon.c | 3 ++- targets/f7/ble_glue/profiles/serial_profile.c | 4 ++-- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/fbt_options.py b/fbt_options.py index 9e4d821a45..c4b8410581 100644 --- a/fbt_options.py +++ b/fbt_options.py @@ -22,7 +22,7 @@ COPRO_OB_DATA = "scripts/ob.data" # Must match lib/stm32wb_copro version -COPRO_CUBE_VERSION = "1.17.3" +COPRO_CUBE_VERSION = "1.19.0" COPRO_CUBE_DIR = "lib/stm32wb_copro" diff --git a/lib/ble_profile/extra_profiles/hid_profile.c b/lib/ble_profile/extra_profiles/hid_profile.c index aaa66d9607..7231fdb195 100644 --- a/lib/ble_profile/extra_profiles/hid_profile.c +++ b/lib/ble_profile/extra_profiles/hid_profile.c @@ -380,8 +380,8 @@ static GapConfig template_config = { .pairing_method = GapPairingPinCodeVerifyYesNo, .conn_param = { - .conn_int_min = 0x18, // 30 ms - .conn_int_max = 0x24, // 45 ms + .conn_int_min = 0x18, // AN5289: 4.7, we need at least 25ms + advertisement, which is 30 ms + .conn_int_max = 0x18, // 30 ms .slave_latency = 0, .supervisor_timeout = 0, }, diff --git a/lib/stm32wb_copro b/lib/stm32wb_copro index d8a6f1feb0..64a060d91f 160000 --- a/lib/stm32wb_copro +++ b/lib/stm32wb_copro @@ -1 +1 @@ -Subproject commit d8a6f1feb0ebb6798c44162c6ae5ea743f90f3df +Subproject commit 64a060d91f5cbf25d765cf23231876add006bcf4 diff --git a/targets/f7/ble_glue/ble_app.c b/targets/f7/ble_glue/ble_app.c index 1f392529de..fd4e64c09c 100644 --- a/targets/f7/ble_glue/ble_app.c +++ b/targets/f7/ble_glue/ble_app.c @@ -54,8 +54,8 @@ static const SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = { .PrWriteListSize = CFG_BLE_PREPARE_WRITE_LIST_SIZE, .MblockCount = CFG_BLE_MBLOCK_COUNT, .AttMtu = CFG_BLE_MAX_ATT_MTU, - .SlaveSca = CFG_BLE_SLAVE_SCA, - .MasterSca = CFG_BLE_MASTER_SCA, + .PeripheralSca = CFG_BLE_SLAVE_SCA, + .CentralSca = CFG_BLE_MASTER_SCA, .LsSource = CFG_BLE_LSE_SOURCE, .MaxConnEventLength = CFG_BLE_MAX_CONN_EVENT_LENGTH, .HsStartupTime = CFG_BLE_HSE_STARTUP_TIME, diff --git a/targets/f7/ble_glue/extra_beacon.c b/targets/f7/ble_glue/extra_beacon.c index 2ef3e056fb..60338cb76b 100644 --- a/targets/f7/ble_glue/extra_beacon.c +++ b/targets/f7/ble_glue/extra_beacon.c @@ -9,7 +9,8 @@ #define GAP_MS_TO_SCAN_INTERVAL(x) ((uint16_t)((x) / 0.625)) // Also used as an indicator of whether the beacon had ever been configured -#define GAP_MIN_ADV_INTERVAL_MS (20) +// AN5289: 4.7, we need at least 25ms + advertisement, which is 30 ms +#define GAP_MIN_ADV_INTERVAL_MS (30u) typedef struct { GapExtraBeaconConfig last_config; diff --git a/targets/f7/ble_glue/profiles/serial_profile.c b/targets/f7/ble_glue/profiles/serial_profile.c index a3949abfc8..165b813307 100644 --- a/targets/f7/ble_glue/profiles/serial_profile.c +++ b/targets/f7/ble_glue/profiles/serial_profile.c @@ -46,8 +46,8 @@ static GapConfig serial_template_config = { .bonding_mode = true, .pairing_method = GapPairingPinCodeShow, .conn_param = { - .conn_int_min = 0x18, // 30 ms - .conn_int_max = 0x24, // 45 ms + .conn_int_min = 0x18, // AN5289: 4.7, we need at least 25ms + advertisement, which is 30 ms + .conn_int_max = 0x18, // 30 ms .slave_latency = 0, .supervisor_timeout = 0, }}; From 58da27fa912422d0a903c24f25549f15f6c20a3c Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Tue, 9 Apr 2024 12:06:37 +0300 Subject: [PATCH 2/4] JS Documentation (#3535) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial JS documentation * Spelling fix Co-authored-by: あく --- documentation/doxygen/index.dox | 1 + documentation/doxygen/js.dox | 18 ++++ documentation/js/js_badusb.md | 144 ++++++++++++++++++++++++++++ documentation/js/js_builtin.md | 56 +++++++++++ documentation/js/js_data_types.md | 13 +++ documentation/js/js_dialog.md | 49 ++++++++++ documentation/js/js_notification.md | 36 +++++++ documentation/js/js_serial.md | 107 +++++++++++++++++++++ 8 files changed, 424 insertions(+) create mode 100644 documentation/doxygen/js.dox create mode 100644 documentation/js/js_badusb.md create mode 100644 documentation/js/js_builtin.md create mode 100644 documentation/js/js_data_types.md create mode 100644 documentation/js/js_dialog.md create mode 100644 documentation/js/js_notification.md create mode 100644 documentation/js/js_serial.md diff --git a/documentation/doxygen/index.dox b/documentation/doxygen/index.dox index 6fb4d5a717..78055caad0 100644 --- a/documentation/doxygen/index.dox +++ b/documentation/doxygen/index.dox @@ -15,6 +15,7 @@ The documentation is divided into several sections, with all of them accessible - @ref dev_tools - Hardware and software tools for all kinds of programming - @ref expansion - Additional modules to expand Flipper's consciousness - @ref misc - Various useful pieces of information +- @ref js - JS-based scripting engine documentation Aside from the manually-written documentation files, there's also a few automatically-generated ones at the bottom of the sidebar: diff --git a/documentation/doxygen/js.dox b/documentation/doxygen/js.dox new file mode 100644 index 0000000000..1c81a08350 --- /dev/null +++ b/documentation/doxygen/js.dox @@ -0,0 +1,18 @@ +/** +@page js JavaScript + +This page contains some information on the Flipper Zero scripting engine, which is based on a modified mJS library + +- [Brief mJS description](https://github.com/cesanta/mjs/blob/master/README.md) +- @subpage js_data_types +- @subpage js_builtin + +JavaScript Modules +JS modules use the Flipper app plugin system. Each module is compiled into a .fal library file and is located on a microSD card. Here is a list of implemented modules: + +- @subpage js_badusb - BadUSB module +- @subpage js_serial - Serial module +- @subpage js_dialog - Dialog module +- @subpage js_notification - Notifications module + +*/ diff --git a/documentation/js/js_badusb.md b/documentation/js/js_badusb.md new file mode 100644 index 0000000000..28372e56a4 --- /dev/null +++ b/documentation/js/js_badusb.md @@ -0,0 +1,144 @@ +# js_badusb {#js_badusb} + +# BadUSB module +```js +let badusb = require("badusb"); +``` +# Methods +## setup +Start USB HID with optional parameters. Should be called before all other methods. + +### Parameters +Configuration object (optional): +- vid, pid (number): VID and PID values, both are mandatory +- mfr_name (string): Manufacturer name (32 ASCII characters max), optional +- prod_name (string): Product name (32 ASCII characters max), optional + +### Examples: +```js +// Start USB HID with default parameters +badusb.setup(); +// Start USB HID with custom vid:pid = AAAA:BBBB, manufacturer and product strings not defined +badusb.setup({ vid: 0xAAAA, pid: 0xBBBB }); +// Start USB HID with custom vid:pid = AAAA:BBBB, manufacturer string = "Flipper Devices", product string = "Flipper Zero" +badusb.setup({ vid: 0xAAAA, pid: 0xBBBB, mfr_name: "Flipper Devices", prod_name: "Flipper Zero" }); +``` + +## isConnected +Returns USB connection state. + +### Example: +```js +if (badusb.isConnected()) { + // Do something +} else { + // Show an error +} +``` + +## press +Press and release a key. + +### Parameters +Key or modifier name, key code. + +See a list of key names below. + +### Examples: +```js +badusb.press("a"); // Press "a" key +badusb.press("A"); // SHIFT + "a" +badusb.press("CTRL", "a"); // CTRL + "a" +badusb.press("CTRL", "SHIFT", "ESC"); // CTRL + SHIFT + ESC combo +badusb.press(98); // Press key with HID code (dec) 98 (Numpad 0 / Insert) +badusb.press(0x47); // Press key with HID code (hex) 0x47 (Scroll lock) +``` + +## hold +Hold a key. Up to 5 keys (excluding modifiers) can be held simultaneously. + +### Parameters +Same as `press` + +### Examples: +```js +badusb.hold("a"); // Press and hold "a" key +badusb.hold("CTRL", "v"); // Press and hold CTRL + "v" combo +``` + +## release +Release a previously hold key. + +### Parameters +Same as `press` + +Release all keys if called without parameters + +### Examples: +```js +badusb.release(); // Release all keys +badusb.release("a"); // Release "a" key +``` + +## print +Print a string. + +### Parameters +- A string to print +- (optional) delay between key presses + +### Examples: +```js +badusb.print("Hello, world!"); // print "Hello, world!" +badusb.print("Hello, world!", 100); // Add 100ms delay between key presses +``` + +## println +Same as `print` but ended with "ENTER" press. + +### Parameters +- A string to print +- (optional) delay between key presses + +### Examples: +```js +badusb.println("Hello, world!"); // print "Hello, world!" and press "ENTER" +``` + +# Key names list + +## Modifier keys + +| Name | +| ------------- | +| CTRL | +| SHIFT | +| ALT | +| GUI | + +## Special keys + +| Name | Notes | +| ------------------ | ---------------- | +| DOWN | Down arrow | +| LEFT | Left arrow | +| RIGHT | Right arrow | +| UP | Up arrow | +| ENTER | | +| DELETE | | +| BACKSPACE | | +| END | | +| HOME | | +| ESC | | +| INSERT | | +| PAGEUP | | +| PAGEDOWN | | +| CAPSLOCK | | +| NUMLOCK | | +| SCROLLLOCK | | +| PRINTSCREEN | | +| PAUSE | Pause/Break key | +| SPACE | | +| TAB | | +| MENU | Context menu key | +| Fx | F1-F24 keys | diff --git a/documentation/js/js_builtin.md b/documentation/js/js_builtin.md new file mode 100644 index 0000000000..3d113807b0 --- /dev/null +++ b/documentation/js/js_builtin.md @@ -0,0 +1,56 @@ +# Built-in methods {#js_builtin} + +## require +Load a module plugin. + +### Parameters +- Module name + +### Examples: +```js +let serial = require("serial"); // Load "serial" module +``` + +## delay +### Parameters +- Delay value in ms + +### Examples: +```js +delay(500); // Delay for 500ms +``` +## print +Print a message on a screen console. + +### Parameters +The following argument types are supported: +- String +- Number +- Bool +- undefined + +### Examples: +```js +print("string1", "string2", 123); +``` + +## console.log +## console.warn +## console.error +## console.debug +Same as `print`, but output to serial console only, with corresponding log level. + +## to_string +Convert a number to string. + +### Examples: +```js +to_string(123) +``` +## to_hex_string +Convert a number to string(hex format). + +### Examples: +```js +to_hex_string(0xFF) +``` diff --git a/documentation/js/js_data_types.md b/documentation/js/js_data_types.md new file mode 100644 index 0000000000..de1c896dce --- /dev/null +++ b/documentation/js/js_data_types.md @@ -0,0 +1,13 @@ +# Data types {#js_data_types} + +Here is a list of common data types used by mJS. +- string - sequence of single byte characters, no UTF8 support +- number +- boolean +- foreign - C function or data pointer +- undefined +- null +- object - a data structure with named fields +- array - special type of object, all items have indexes and equal types +- ArrayBuffer - raw data buffer +- DataView - provides interface for accessing ArrayBuffer contents diff --git a/documentation/js/js_dialog.md b/documentation/js/js_dialog.md new file mode 100644 index 0000000000..5804b075eb --- /dev/null +++ b/documentation/js/js_dialog.md @@ -0,0 +1,49 @@ +# js_dialog {#js_dialog} + +# Dialog module +```js +let dialog = require("dialog"); +``` +# Methods + +## message +Show a simple message dialog with header, text and "OK" button. + +### Parameters +- Dialog header text +- Dialog text + +### Retuns +true if central button was pressed, false if the dialog was closed by back key press + +### Examples: +```js +dialog.message("Dialog demo", "Press OK to start"); +``` + +## custom +More complex dialog with configurable buttons + +### Parameters +Configuration object with the following fileds: +- header: Dialog header text +- text: Dialog text +- button_left: (optional) left button name +- button_right: (optional) right button name +- button_center: (optional) central button name + +### Retuns +Name of pressed button or empty string if the dialog was closed by back key press + +### Examples: +```js +let dialog_params = ({ + header: "Dialog header", + text: "Dialog text", + button_left: "Left", + button_right: "Right", + button_center: "OK" +}); + +dialog.custom(dialog_params); +``` diff --git a/documentation/js/js_notification.md b/documentation/js/js_notification.md new file mode 100644 index 0000000000..100da44146 --- /dev/null +++ b/documentation/js/js_notification.md @@ -0,0 +1,36 @@ +# js_notification {#js_notification} + +# Notification module +```js +let notify = require("notification"); +``` +# Methods + +## success +"Success" flipper notification message + +### Examples: +```js +notify.success(); +``` + +## error +"Error" flipper notification message + +### Examples: +```js +notify.error(); +``` + +## blink +Blink notification LED + +### Parameters +- Blink color (blue/red/green/yellow/cyan/magenta) +- Blink type (short/long) + +### Examples: +```js +notify.blink("red", "short"); // Short blink of red LED +notify.blink("green", "short"); // Long blink of green LED +``` \ No newline at end of file diff --git a/documentation/js/js_serial.md b/documentation/js/js_serial.md new file mode 100644 index 0000000000..cd9993a181 --- /dev/null +++ b/documentation/js/js_serial.md @@ -0,0 +1,107 @@ +# js_serial {#js_serial} + +# Serial module +```js +let serial = require("serial"); +``` +# Methods + +## setup +Configure serial port. Should be called before all other methods. + +### Parameters +- Serial port name (usart, lpuart) +- Baudrate + +### Examples: +```js +// Configure LPUART port with baudrate = 115200 +serial.setup("lpuart", 115200); +``` + +## write +Write data to serial port + +### Parameters +One or more arguments of the following types: +- A string +- Single number, each number is interpreted as a byte +- Array of numbers, each number is interpreted as a byte +- ArrayBuffer or DataView + +### Examples: +```js +serial.write(0x0a); // Write a single byte 0x0A +serial.write("Hello, world!"); // Write a string +serial.write("Hello, world!", [0x0d, 0x0a]); // Write a string followed by two bytes +``` + +## read +Read a fixed number of characters from serial port. + +### Parameters +- Number of bytes to read +- (optional) Timeout value in ms + +### Returns +A sting of received characters or undefined if nothing was received before timeout. + +### Examples: +```js +serial.read(1); // Read a single byte, without timeout +serial.read(10, 5000); // Read 10 bytes, with 5s timeout +``` + +## readln +Read from serial port untill line break character + +### Parameters +(optional) Timeout value in ms + +### Returns +A sting of received characters or undefined if nothing was received before timeout. + +### Examples: +```js +serial.readln(); // Read without timeout +serial.readln(5000); // Read with 5s timeout +``` + +## readBytes +Read from serial port untill line break character + +### Parameters +- Number of bytes to read +- (optional) Timeout value in ms + +### Returns +ArrayBuffer with received data or undefined if nothing was received before timeout. + +### Examples: +```js +serial.readBytes(4); // Read 4 bytes, without timeout + +// Read one byte from receive buffer with zero timeout, returns UNDEFINED if Rx bufer is empty +serial.readBytes(1, 0); +``` + +## expect +Search for a string pattern in received data stream + +### Parameters +- Single argument or array of the following types: + - A string + - Array of numbers, each number is interpreted as a byte +- (optional) Timeout value in ms + +### Returns +Index of matched pattern in input patterns list, undefined if nothing was found. + +### Examples: +```js +// Wait for root shell prompt with 1s timeout, returns 0 if it was received before timeout, undefined if not +serial.expect("# ", 1000); + +// Infinitely wait for one of two strings, should return 0 if the first string got matched, 1 if the second one +serial.expect([": not found", "Usage: "]); +``` \ No newline at end of file From e3ca293eee588c155eac7b389ab7f7e2768d43e0 Mon Sep 17 00:00:00 2001 From: WillyJL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:42:03 +0100 Subject: [PATCH 3/4] Desktop/Loader: Unload animations before loading FAPs (#3573) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Desktop: Unload animations before FAP is loaded * Loader: Add API to start detached (returns instantly, queues event) * Desktop: Fix early animation unload deadlocks * Loader: remove redundant event * Bump api symbols Co-authored-by: あく Co-authored-by: SG --- applications/services/desktop/desktop.c | 6 ++- .../desktop/scenes/desktop_scene_main.c | 17 +++--- applications/services/loader/loader.c | 53 ++++++++++++++----- applications/services/loader/loader.h | 17 ++++-- applications/services/loader/loader_i.h | 1 + targets/f18/api_symbols.csv | 3 +- targets/f7/api_symbols.csv | 3 +- 7 files changed, 69 insertions(+), 31 deletions(-) diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index 49aa04e35e..c5a334a450 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -32,10 +32,12 @@ static void desktop_loader_callback(const void* message, void* context) { Desktop* desktop = context; const LoaderEvent* event = message; - if(event->type == LoaderEventTypeApplicationStarted) { + if(event->type == LoaderEventTypeApplicationBeforeLoad) { view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalBeforeAppStarted); furi_check(furi_semaphore_acquire(desktop->animation_semaphore, 3000) == FuriStatusOk); - } else if(event->type == LoaderEventTypeApplicationStopped) { + } else if( + event->type == LoaderEventTypeApplicationLoadFailed || + event->type == LoaderEventTypeApplicationStopped) { view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalAfterAppFinished); } } diff --git a/applications/services/desktop/scenes/desktop_scene_main.c b/applications/services/desktop/scenes/desktop_scene_main.c index a659ff4e35..41b1c3e751 100644 --- a/applications/services/desktop/scenes/desktop_scene_main.c +++ b/applications/services/desktop/scenes/desktop_scene_main.c @@ -62,23 +62,18 @@ static void #endif static void desktop_scene_main_open_app_or_profile(Desktop* desktop, FavoriteApp* application) { - bool load_ok = false; if(strlen(application->name_or_path) > 0) { - if(loader_start(desktop->loader, application->name_or_path, NULL, NULL) == - LoaderStatusOk) { - load_ok = true; - } - } - if(!load_ok) { - loader_start(desktop->loader, "Passport", NULL, NULL); + loader_start_detached_with_gui_error(desktop->loader, application->name_or_path, NULL); + } else { + loader_start_detached_with_gui_error(desktop->loader, "Passport", NULL); } } static void desktop_scene_main_start_favorite(Desktop* desktop, FavoriteApp* application) { if(strlen(application->name_or_path) > 0) { - loader_start_with_gui_error(desktop->loader, application->name_or_path, NULL); + loader_start_detached_with_gui_error(desktop->loader, application->name_or_path, NULL); } else { - loader_start(desktop->loader, LOADER_APPLICATIONS_NAME, NULL, NULL); + loader_start_detached_with_gui_error(desktop->loader, LOADER_APPLICATIONS_NAME, NULL); } } @@ -141,7 +136,7 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) { break; case DesktopMainEventOpenPowerOff: { - loader_start(desktop->loader, "Power", "off", NULL); + loader_start_detached_with_gui_error(desktop->loader, "Power", "off"); consumed = true; break; } diff --git a/applications/services/loader/loader.c b/applications/services/loader/loader.c index 5daf99d1de..1527807ccc 100644 --- a/applications/services/loader/loader.c +++ b/applications/services/loader/loader.c @@ -47,13 +47,8 @@ LoaderStatus return result.value; } -LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const char* args) { - furi_check(loader); - furi_check(name); - - FuriString* error_message = furi_string_alloc(); - LoaderStatus status = loader_start(loader, name, args, error_message); - +static void + loader_show_gui_error(LoaderStatus status, const char* name, FuriString* error_message) { if(status == LoaderStatusErrorUnknownApp && loader_find_external_application_by_name(name) != NULL) { // Special case for external apps @@ -86,11 +81,31 @@ LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const dialog_message_free(message); furi_record_close(RECORD_DIALOGS); } +} +LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const char* args) { + furi_check(loader); + furi_check(name); + + FuriString* error_message = furi_string_alloc(); + LoaderStatus status = loader_start(loader, name, args, error_message); + loader_show_gui_error(status, name, error_message); furi_string_free(error_message); return status; } +void loader_start_detached_with_gui_error(Loader* loader, const char* name, const char* args) { + furi_check(loader); + furi_check(name); + + LoaderMessage message = { + .type = LoaderMessageTypeStartByNameDetachedWithGuiError, + .start.name = name ? strdup(name) : NULL, + .start.args = args ? strdup(args) : NULL, + }; + furi_message_queue_put(loader->queue, &message, FuriWaitForever); +} + bool loader_lock(Loader* loader) { furi_check(loader); @@ -166,11 +181,7 @@ static void loader_thread_state_callback(FuriThreadState thread_state, void* con Loader* loader = context; - if(thread_state == FuriThreadStateRunning) { - LoaderEvent event; - event.type = LoaderEventTypeApplicationStarted; - furi_pubsub_publish(loader->pubsub, &event); - } else if(thread_state == FuriThreadStateStopped) { + if(thread_state == FuriThreadStateStopped) { LoaderMessage message; message.type = LoaderMessageTypeAppClosed; furi_message_queue_put(loader->queue, &message, FuriWaitForever); @@ -255,6 +266,9 @@ static void loader_start_internal_app( const FlipperInternalApplication* app, const char* args) { FURI_LOG_I(TAG, "Starting %s", app->name); + LoaderEvent event; + event.type = LoaderEventTypeApplicationBeforeLoad; + furi_pubsub_publish(loader->pubsub, &event); // store args furi_assert(loader->app.args == NULL); @@ -309,6 +323,9 @@ static LoaderStatus loader_start_external_app( const char* args, FuriString* error_message) { LoaderStatus status = loader_make_success_status(error_message); + LoaderEvent event; + event.type = LoaderEventTypeApplicationBeforeLoad; + furi_pubsub_publish(loader->pubsub, &event); do { loader->app.fap = flipper_application_alloc(storage, firmware_api_interface); @@ -356,6 +373,8 @@ static LoaderStatus loader_start_external_app( if(status != LoaderStatusOk) { flipper_application_free(loader->app.fap); loader->app.fap = NULL; + event.type = LoaderEventTypeApplicationLoadFailed; + furi_pubsub_publish(loader->pubsub, &event); } return status; @@ -528,6 +547,16 @@ int32_t loader_srv(void* p) { loader, message.start.name, message.start.args, message.start.error_message); api_lock_unlock(message.api_lock); break; + case LoaderMessageTypeStartByNameDetachedWithGuiError: { + FuriString* error_message = furi_string_alloc(); + LoaderStatus status = loader_do_start_by_name( + loader, message.start.name, message.start.args, error_message); + loader_show_gui_error(status, message.start.name, error_message); + if(message.start.name) free((void*)message.start.name); + if(message.start.args) free((void*)message.start.args); + furi_string_free(error_message); + break; + } case LoaderMessageTypeShowMenu: loader_do_menu_show(loader); break; diff --git a/applications/services/loader/loader.h b/applications/services/loader/loader.h index cca65628f8..ae914117d9 100644 --- a/applications/services/loader/loader.h +++ b/applications/services/loader/loader.h @@ -18,7 +18,8 @@ typedef enum { } LoaderStatus; typedef enum { - LoaderEventTypeApplicationStarted, + LoaderEventTypeApplicationBeforeLoad, + LoaderEventTypeApplicationLoadFailed, LoaderEventTypeApplicationStopped } LoaderEventType; @@ -32,7 +33,7 @@ typedef struct { * @param[in] name application name or id * @param[in] args application arguments * @param[out] error_message detailed error message, can be NULL - * @return LoaderStatus + * @return LoaderStatus */ LoaderStatus loader_start(Loader* instance, const char* name, const char* args, FuriString* error_message); @@ -42,11 +43,19 @@ LoaderStatus * @param[in] instance loader instance * @param[in] name application name or id * @param[in] args application arguments - * @return LoaderStatus + * @return LoaderStatus */ LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const char* args); -/** +/** + * @brief Start application detached with GUI error message + * @param[in] instance loader instance + * @param[in] name application name or id + * @param[in] args application arguments + */ +void loader_start_detached_with_gui_error(Loader* loader, const char* name, const char* args); + +/** * @brief Lock application start * @param[in] instance loader instance * @return true on success diff --git a/applications/services/loader/loader_i.h b/applications/services/loader/loader_i.h index 688b8fb665..daa5484d33 100644 --- a/applications/services/loader/loader_i.h +++ b/applications/services/loader/loader_i.h @@ -30,6 +30,7 @@ typedef enum { LoaderMessageTypeLock, LoaderMessageTypeUnlock, LoaderMessageTypeIsLocked, + LoaderMessageTypeStartByNameDetachedWithGuiError, } LoaderMessageType; typedef struct { diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv index 72116ccfdf..7944bc58fa 100644 --- a/targets/f18/api_symbols.csv +++ b/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,60.5,, +Version,+,60.6,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1748,6 +1748,7 @@ Function,+,loader_is_locked,_Bool,Loader* Function,+,loader_lock,_Bool,Loader* Function,+,loader_show_menu,void,Loader* Function,+,loader_start,LoaderStatus,"Loader*, const char*, const char*, FuriString*" +Function,+,loader_start_detached_with_gui_error,void,"Loader*, const char*, const char*" Function,+,loader_start_with_gui_error,LoaderStatus,"Loader*, const char*, const char*" Function,+,loader_unlock,void,Loader* Function,+,loading_alloc,Loading*, diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 4ddff921bc..8fd9f4c9b4 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,60.5,, +Version,+,60.6,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, @@ -2139,6 +2139,7 @@ Function,+,loader_is_locked,_Bool,Loader* Function,+,loader_lock,_Bool,Loader* Function,+,loader_show_menu,void,Loader* Function,+,loader_start,LoaderStatus,"Loader*, const char*, const char*, FuriString*" +Function,+,loader_start_detached_with_gui_error,void,"Loader*, const char*, const char*" Function,+,loader_start_with_gui_error,LoaderStatus,"Loader*, const char*, const char*" Function,+,loader_unlock,void,Loader* Function,+,loading_alloc,Loading*, From db14ca964bd4456f8f86e79a4b1a28469890952e Mon Sep 17 00:00:00 2001 From: Victor Nikitchuk Date: Tue, 9 Apr 2024 18:05:30 +0300 Subject: [PATCH 4/4] Status output !TX/RX on the GDO2 CC1101 pin (#3571) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Status output !TX/RX on the GDO2 CC1101 pin\ * Fix PVS warnings Co-authored-by: あく --- .../drivers/subghz/cc1101_ext/cc1101_ext.c | 20 +++++++++++++++++++ applications/services/loader/loader.c | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c index 8be60088a9..429a4b3a41 100644 --- a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c +++ b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c @@ -177,6 +177,14 @@ static bool subghz_device_cc1101_ext_check_init(void) { furi_hal_gpio_init( subghz_device_cc1101_ext->g0_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + // Reset GDO2 (!TX/RX) to floating state + cc1101_status = cc1101_write_reg( + subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHighImpedance); + if(cc1101_status.CHIP_RDYn != 0) { + //timeout or error + break; + } + // Go to sleep cc1101_status = cc1101_shutdown(subghz_device_cc1101_ext->spi_bus_handle); if(cc1101_status.CHIP_RDYn != 0) { @@ -385,6 +393,9 @@ void subghz_device_cc1101_ext_reset(void) { // Warning: push pull cc1101 clock output on GD0 cc1101_write_reg( subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHighImpedance); + // Reset GDO2 (!TX/RX) to floating state + cc1101_write_reg( + subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHighImpedance); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } @@ -394,6 +405,9 @@ void subghz_device_cc1101_ext_idle(void) { //waiting for the chip to switch to IDLE mode furi_check(cc1101_wait_status_state( subghz_device_cc1101_ext->spi_bus_handle, CC1101StateIDLE, 10000)); + // Reset GDO2 (!TX/RX) to floating state + cc1101_write_reg( + subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHighImpedance); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } @@ -403,6 +417,10 @@ void subghz_device_cc1101_ext_rx(void) { //waiting for the chip to switch to Rx mode furi_check( cc1101_wait_status_state(subghz_device_cc1101_ext->spi_bus_handle, CC1101StateRX, 10000)); + // Go GDO2 (!TX/RX) to high (RX state) + cc1101_write_reg( + subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); } @@ -413,6 +431,8 @@ bool subghz_device_cc1101_ext_tx(void) { //waiting for the chip to switch to Tx mode furi_check( cc1101_wait_status_state(subghz_device_cc1101_ext->spi_bus_handle, CC1101StateTX, 10000)); + // Go GDO2 (!TX/RX) to low (TX state) + cc1101_write_reg(subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHW); furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle); return true; } diff --git a/applications/services/loader/loader.c b/applications/services/loader/loader.c index 1527807ccc..cedc2e83ed 100644 --- a/applications/services/loader/loader.c +++ b/applications/services/loader/loader.c @@ -100,7 +100,7 @@ void loader_start_detached_with_gui_error(Loader* loader, const char* name, cons LoaderMessage message = { .type = LoaderMessageTypeStartByNameDetachedWithGuiError, - .start.name = name ? strdup(name) : NULL, + .start.name = strdup(name), .start.args = args ? strdup(args) : NULL, }; furi_message_queue_put(loader->queue, &message, FuriWaitForever);