diff --git a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c index 56273d63e..f77842a3a 100644 --- a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c +++ b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c @@ -448,6 +448,7 @@ void subghz_device_cc1101_ext_rx(void) { // 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); if(subghz_device_cc1101_ext->power_amp) { furi_hal_gpio_write(SUBGHZ_DEVICE_CC1101_EXT_E07_AMP_GPIO, 0); diff --git a/applications/services/loader/loader.c b/applications/services/loader/loader.c index 87d077de4..8c8a46589 100644 --- a/applications/services/loader/loader.c +++ b/applications/services/loader/loader.c @@ -101,7 +101,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); @@ -182,11 +182,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); diff --git a/applications/services/loader/loader.h b/applications/services/loader/loader.h index 36722ae10..ad6a46532 100644 --- a/applications/services/loader/loader.h +++ b/applications/services/loader/loader.h @@ -22,7 +22,6 @@ typedef enum { typedef enum { LoaderEventTypeApplicationBeforeLoad, LoaderEventTypeApplicationLoadFailed, - LoaderEventTypeApplicationStarted, LoaderEventTypeApplicationStopped } LoaderEventType; @@ -36,7 +35,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); @@ -46,7 +45,7 @@ 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); diff --git a/documentation/js/js_badusb.md b/documentation/js/js_badusb.md new file mode 100644 index 000000000..28372e56a --- /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 000000000..3d113807b --- /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 000000000..de1c896dc --- /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 000000000..5804b075e --- /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 000000000..100da4414 --- /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 000000000..cd9993a18 --- /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 diff --git a/fbt_options.py b/fbt_options.py index 2367caf9a..e1cece7f5 100644 --- a/fbt_options.py +++ b/fbt_options.py @@ -22,7 +22,7 @@ DIST_SUFFIX = "local" 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 aaa66d960..7231fdb19 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 d8a6f1feb..64a060d91 160000 --- a/lib/stm32wb_copro +++ b/lib/stm32wb_copro @@ -1 +1 @@ -Subproject commit d8a6f1feb0ebb6798c44162c6ae5ea743f90f3df +Subproject commit 64a060d91f5cbf25d765cf23231876add006bcf4 diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv index 72116ccfd..7944bc58f 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 2cb22dde7..0dfc280a7 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,, diff --git a/targets/f7/ble_glue/ble_app.c b/targets/f7/ble_glue/ble_app.c index 1f392529d..fd4e64c09 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 2ef3e056f..60338cb76 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 a3949abfc..165b81330 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, }};