From 9898a5d0dd1c239e0b3ca428fbba7e17a381df09 Mon Sep 17 00:00:00 2001 From: Max Andreev Date: Mon, 2 Oct 2023 12:51:41 +0300 Subject: [PATCH 1/4] Enable PVS Studio license check (#3122) --- scripts/fbt_tools/pvsstudio.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/fbt_tools/pvsstudio.py b/scripts/fbt_tools/pvsstudio.py index b2592eca6..211f46aee 100644 --- a/scripts/fbt_tools/pvsstudio.py +++ b/scripts/fbt_tools/pvsstudio.py @@ -48,7 +48,6 @@ def generate(env): "@.pvsoptions", "-j${PVSNCORES}", # "--incremental", # kinda broken on PVS side - "--disableLicenseExpirationCheck", ], PVSCONVOPTIONS=[ "-a", From 699078d5a5840065f3741cf3b053e583aaa6ca02 Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Fri, 6 Oct 2023 09:15:26 +0300 Subject: [PATCH 2/4] [FL-3576] HEX input UI improvements (#3112) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- .../services/gui/modules/byte_input.c | 24 ++++++++++++++---- assets/icons/Common/Hashmark_7x7.png | Bin 0 -> 957 bytes assets/icons/Common/arrow_nano_down.png | Bin 0 -> 2311 bytes assets/icons/Common/arrow_nano_up.png | Bin 0 -> 949 bytes 4 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 assets/icons/Common/Hashmark_7x7.png create mode 100644 assets/icons/Common/arrow_nano_down.png create mode 100644 assets/icons/Common/arrow_nano_up.png diff --git a/applications/services/gui/modules/byte_input.c b/applications/services/gui/modules/byte_input.c index 3bca8fc74..e0cbbb779 100644 --- a/applications/services/gui/modules/byte_input.c +++ b/applications/services/gui/modules/byte_input.c @@ -177,6 +177,12 @@ static void byte_input_draw_input(Canvas* canvas, ByteInputModel* model) { if(i == model->selected_byte) { canvas_draw_frame(canvas, text_x + byte_position * 14, text_y - 9, 15, 11); + if(model->selected_row == -2) { + canvas_draw_icon( + canvas, text_x + 6 + byte_position * 14, text_y - 14, &I_arrow_nano_up); + canvas_draw_icon( + canvas, text_x + 6 + byte_position * 14, text_y + 5, &I_arrow_nano_down); + } if(model->selected_high_nibble) { canvas_draw_glyph( @@ -233,6 +239,7 @@ static void byte_input_draw_input(Canvas* canvas, ByteInputModel* model) { } if(draw_index_line) { + canvas_draw_icon(canvas, 1, text_y + 8, &I_Hashmark_7x7); canvas_draw_glyph( canvas, text_x + 2 + byte_position * 14, text_y2, num_to_char[(i + 1) / 10]); @@ -600,9 +607,6 @@ static void byte_input_view_draw_callback(Canvas* canvas, void* _model) { canvas_clear(canvas); canvas_set_color(canvas, ColorBlack); - - canvas_draw_str(canvas, 2, 9, model->header); - canvas_set_font(canvas, FontKeyboard); if(model->selected_row == -1) { @@ -613,9 +617,19 @@ static void byte_input_view_draw_callback(Canvas* canvas, void* _model) { if(model->selected_row == -2) { canvas_set_font(canvas, FontSecondary); - canvas_draw_icon(canvas, 3, 52, &I_Pin_back_arrow_10x8); - canvas_draw_str_aligned(canvas, 16, 60, AlignLeft, AlignBottom, "back to keyboard"); + canvas_draw_icon(canvas, 3, 1, &I_Pin_back_arrow_10x8); + canvas_draw_str_aligned(canvas, 16, 9, AlignLeft, AlignBottom, "back to keyboard"); + elements_button_center(canvas, "Save"); } else { + // Draw the header + canvas_set_font(canvas, FontSecondary); + if(model->selected_row == -1) { + canvas_draw_str(canvas, 10, 9, "Move up for alternate input"); + canvas_draw_icon(canvas, 3, 4, &I_SmallArrowUp_3x5); + } else { + canvas_draw_str(canvas, 2, 9, model->header); + } + canvas_set_font(canvas, FontKeyboard); // Draw keyboard for(uint8_t row = 0; row < keyboard_row_count; row++) { const uint8_t column_count = byte_input_get_row_size(row); diff --git a/assets/icons/Common/Hashmark_7x7.png b/assets/icons/Common/Hashmark_7x7.png new file mode 100644 index 0000000000000000000000000000000000000000..93fb147be235c2030fb85ba55859cfc66d32b1fa GIT binary patch literal 957 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 literal 0 HcmV?d00001 diff --git a/assets/icons/Common/arrow_nano_up.png b/assets/icons/Common/arrow_nano_up.png new file mode 100644 index 0000000000000000000000000000000000000000..4a1d5be85cf83a3a1767d3b422054285f978c9eb GIT binary patch literal 949 zcmaJ=J#W)M7`9pos!AP@SYSH2OOS}qpGj=RR3VqPk?JT)Es-%7`;u6xea5~JClg|W zAHd4Q(gBH?ftjCBBz^;b04bdFRfYsh_Ir1JpXYt<-sj%8TNfwCPmcvbIB8y@4v&ZY zJvhq0x3?b)JUn5IF1w}!HpK}MYCi1~&3AHzo}9$uNj)@%OjyA_#n2d}TPY6W7ToxSS{Cdfsxq`Pegk@$3btW)>$1 z3Bw=@Z=%%7Y;nnJ@o~NkMX*d^V_RH_>N;&urwIY3q!c|_RzTU5aK+clhNhd(fhwyS zlr^YoMMbk@!_p0~eneg{@ds81ov+LBnJtbOi!BJJ)2TGoB$^DNVwxtDRj8^(o>5F^ z5yM$AN>4Woh@@T;#4Ml@$Qf~;PM9rnv8!E#@s>79*C)l#3}!fniX`W|+9W#8|5L+o zo1L-_x!1dsICW<+fgO_4N#gO|4Nmh?u~kn9W;Agrz1bXOdqf#cM>GbiE|oyR!CnyM zE6PsIp-wrJABN8Wp6-sAAM~T{ktPsT(Y!-XtUu z+hF~BY-ukxH$)io%7`Sv8{(fQGz80CTfq)3nyQ Date: Fri, 6 Oct 2023 10:11:02 +0300 Subject: [PATCH 3/4] fbt: glob improvements (#3117) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fbt: glob improvements, now treats entries with no special glob chars as files by default, not calling scons' globbing for them * fbt: further fixes for glob * fbt: less strict existence checks * fbt: fixed frame_rate collection; typo fixes & comments Co-authored-by: あく --- scripts/fbt_tools/fbt_assets.py | 2 +- scripts/fbt_tools/fbt_extapps.py | 8 +++++++- scripts/fbt_tools/sconsrecursiveglob.py | 23 +++++++++++++++-------- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/scripts/fbt_tools/fbt_assets.py b/scripts/fbt_tools/fbt_assets.py index 4f4d3bffd..d923c328f 100644 --- a/scripts/fbt_tools/fbt_assets.py +++ b/scripts/fbt_tools/fbt_assets.py @@ -9,7 +9,7 @@ from SCons.Errors import StopError def icons_emitter(target, source, env): icons_src = env.GlobRecursive("*.png", env["ICON_SRC_DIR"]) - icons_src += env.GlobRecursive("frame_rate", env["ICON_SRC_DIR"]) + icons_src += env.GlobRecursive("**/frame_rate", env["ICON_SRC_DIR"]) target = [ target[0].File(env.subst("${ICON_FILE_NAME}.c")), diff --git a/scripts/fbt_tools/fbt_extapps.py b/scripts/fbt_tools/fbt_extapps.py index aa6354c9e..bc8f9d5df 100644 --- a/scripts/fbt_tools/fbt_extapps.py +++ b/scripts/fbt_tools/fbt_extapps.py @@ -157,6 +157,11 @@ class AppBuilder: for source_type in self.app.sources ) ) + if not app_sources: + raise UserError(f"No source files found for {self.app.appid}") + + ## Uncomment for debug + # print(f"App sources for {self.app.appid}: {list(f.path for f in app_sources)}") app_artifacts = FlipperExternalAppInfo(self.app) app_artifacts.debug = self.app_env.Program( @@ -239,9 +244,10 @@ class AppBuilder: # Add dependencies on file assets for assets_dir in self.app._assets_dirs: + glob_res = self.app_env.GlobRecursive("*", assets_dir) self.app_env.Depends( app_artifacts.compact, - (assets_dir, self.app_env.GlobRecursive("*", assets_dir)), + (*glob_res, assets_dir), ) # Always run the validator for the app's binary when building the app diff --git a/scripts/fbt_tools/sconsrecursiveglob.py b/scripts/fbt_tools/sconsrecursiveglob.py index 7dbde531b..38aa9a839 100644 --- a/scripts/fbt_tools/sconsrecursiveglob.py +++ b/scripts/fbt_tools/sconsrecursiveglob.py @@ -1,6 +1,7 @@ import SCons from fbt.util import GLOB_FILE_EXCLUSION from SCons.Script import Flatten +from SCons.Node.FS import has_glob_magic def GlobRecursive(env, pattern, node=".", exclude=[]): @@ -9,14 +10,20 @@ def GlobRecursive(env, pattern, node=".", exclude=[]): results = [] if isinstance(node, str): node = env.Dir(node) - for f in node.glob("*", source=True, exclude=exclude): - if isinstance(f, SCons.Node.FS.Dir): - results += env.GlobRecursive(pattern, f, exclude) - results += node.glob( - pattern, - source=True, - exclude=exclude, - ) + # Only initiate actual recursion if special symbols can be found in 'pattern' + if has_glob_magic(pattern): + for f in node.glob("*", source=True, exclude=exclude): + if isinstance(f, SCons.Node.FS.Dir): + results += env.GlobRecursive(pattern, f, exclude) + results += node.glob( + pattern, + source=True, + exclude=exclude, + ) + # Otherwise, just check if that's an existing file path + # NB: still creates "virtual" nodes as part of existence check + elif (file_node := node.File(pattern)).exists() or file_node.rexists(): + results.append(file_node) # print(f"Glob result for {pattern} from {node}: {results}") return results From 62a4c0dd039fd32955e9d2b4d002f1ddf4c3dc75 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Fri, 6 Oct 2023 11:20:32 +0400 Subject: [PATCH 4/4] [Documentation]: add documentation SubGhz Bin_RAW file format (#3133) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Documentation]: add documentation SubGhz Bin_RAW file format * [Documentation]: fix error Co-authored-by: あく --- .../file_formats/SubGhzFileFormats.md | 55 ++++++++++++++++--- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/documentation/file_formats/SubGhzFileFormats.md b/documentation/file_formats/SubGhzFileFormats.md index 26863f564..c22f97f8d 100644 --- a/documentation/file_formats/SubGhzFileFormats.md +++ b/documentation/file_formats/SubGhzFileFormats.md @@ -6,9 +6,9 @@ Flipper uses `.sub` files to store SubGhz transmissions. These are text files in A `.sub` files consist of 3 parts: -- **header**: contains file type, version, and frequency -- **preset information**: preset type and, in case of a custom preset, transceiver configuration data -- **protocol and its data**: contains protocol name and its specific data, such as key, bit length, etc., or RAW data +- **header**, contains file type, version, and frequency +- **preset information**, preset type and, in case of a custom preset, transceiver configuration data +- **protocol and its data**, contains protocol name and its specific data, such as key, bit length, etc., or RAW data Flipper's SubGhz subsystem uses presets to configure the radio transceiver. Presets are used to configure modulation, bandwidth, filters, etc. There are several presets available in stock firmware, and there is a way to create custom presets. See [SubGhz Presets](#adding-a-custom-preset) for more details. @@ -45,10 +45,10 @@ Built-in presets: Transceiver configuration data is a string of bytes, encoded in hex format, separated by spaces. For CC1101 data structure is: `XX YY XX YY .. 00 00 ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ`, where: -- XX holds register address, -- YY contains register value, -- 00 00: marks register block end, -- `ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ`: 8 byte PA table (Power amplifier ramp table). +- **XX**, holds register address, +- **YY**, contains register value, +- **00 00**, marks register block end, +- **ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ**, 8 byte PA table (Power amplifier ramp table). You can find more details in the [CC1101 datasheet](https://www.ti.com/lit/ds/symlink/cc1101.pdf) and `furi_hal_subghz` code. @@ -87,8 +87,8 @@ RAW `.sub` files contain raw signal data that is not processed through protocol- For RAW files, 2 fields are required: -- `Protocol`, must be `RAW` -- `RAW_Data`, contains an array of timings, specified in microseconds Values must be non-zero, start with a positive number, and interleaved (change sign with each value). Up to 512 values per line. Can be specified multiple times to store multiple lines of data. +- **Protocol**, must be `RAW` +- **RAW_Data**, contains an array of timings, specified in microseconds Values must be non-zero, start with a positive number, and interleaved (change sign with each value). Up to 512 values per line. Can be specified multiple times to store multiple lines of data. Example of RAW data: @@ -97,6 +97,43 @@ Example of RAW data: Long payload not fitting into internal memory buffer and consisting of short duration timings (< 10us) may not be read fast enough from the SD card. That might cause the signal transmission to stop before reaching the end of the payload. Ensure that your SD Card has good performance before transmitting long or complex RAW payloads. +### BIN_RAW Files + +BinRAW `.sub` files and `RAW` files both contain data that has not been decoded by any protocol. However, unlike `RAW`, `BinRAW` files only record a useful repeating sequence of durations with a restored byte transfer rate and without broadcast noise. These files can emulate nearly all static protocols, whether Flipper knows them or not. + +- Usually, you have to receive the signal a little longer so that Flipper accumulates sufficient data for correct analysis. + +For `BinRAW` files, the following parameters are required and must be aligned to the left: + +- **Protocol**, must be `BinRAW`. +- **Bit**, is the length of the payload of the entire file, in bits (max 4096). +- **TE**, is the quantization interval, in us. +- **Bit_RAW**, is the length of the payload in the next Data_RAW parameter, in bits. +- **Data_RAW**, is an encoded sequence of durations, where each bit in the sequence encodes one TE interval: 1 - high level (there is a carrier), 0 - low (no carrier). + For example, TE=100, Bit_RAW=8, Data_RAW=0x37 => 0b00110111, that is, `-200 200 -100 300` will be transmitted. + When sending uploads, `Bit_RAW` and `Data_RAW` form a repeating block. Several such blocks are necessary if you want to send different sequences sequentially. However, usually, there will be only one block. + +Example data from a `BinRAW` file: + +``` +... +Protocol: BinRAW +Bit: 1572 +TE: 597 +Bit_RAW: 260 +Data_RAW: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0F 4A B5 55 4C B3 52 AC D5 2D 53 52 AD 4A D5 35 00 +Bit_RAW: 263 +Data_RAW: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 04 D5 32 D2 AB 2B 33 32 CB 2C CC B3 52 D3 00 +Bit_RAW: 259 +Data_RAW: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 4A AB 55 34 D5 2D 4C CD 33 4A CD 55 4C D2 B3 00 +Bit_RAW: 263 +Data_RAW: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0F 7F 4A AA D5 2A CC B2 B4 CB 34 CC AA AB 4D 53 53 00 +Bit_RAW: 264 +Data_RAW: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FC 00 00 15 2C CB 34 D3 35 35 4D 4B 32 B2 D3 33 00 +Bit_RAW: 263 +Data_RAW: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 DE 02 D3 54 D5 4C D2 CC AD 4B 2C B2 B5 54 CC AB 00 +``` + ## File examples ### Key file, standard preset