mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 04:34:43 +04:00
Merge branch 'dev' into niceflors
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
diff --git a/applications/services/notification/notification_app.c b/applications/services/notification/notification_app.c
|
||||
index 2f947fe..03c4c76 100644
|
||||
index 5769ced..c5d3088 100644
|
||||
--- a/applications/services/notification/notification_app.c
|
||||
+++ b/applications/services/notification/notification_app.c
|
||||
@@ -9,6 +9,7 @@
|
||||
@@ -10,7 +10,7 @@ index 2f947fe..03c4c76 100644
|
||||
|
||||
#define TAG "NotificationSrv"
|
||||
|
||||
@@ -579,6 +580,7 @@ int32_t notification_srv(void* p) {
|
||||
@@ -589,6 +590,7 @@ int32_t notification_srv(void* p) {
|
||||
break;
|
||||
case SaveSettingsMessage:
|
||||
notification_save_settings(app);
|
||||
@@ -19,7 +19,7 @@ index 2f947fe..03c4c76 100644
|
||||
}
|
||||
|
||||
diff --git a/applications/settings/notification_settings/notification_settings_app.c b/applications/settings/notification_settings/notification_settings_app.c
|
||||
index 565d4f1..bae9299 100644
|
||||
index 1955012..19d953d 100644
|
||||
--- a/applications/settings/notification_settings/notification_settings_app.c
|
||||
+++ b/applications/settings/notification_settings/notification_settings_app.c
|
||||
@@ -3,6 +3,7 @@
|
||||
@@ -30,10 +30,20 @@ index 565d4f1..bae9299 100644
|
||||
|
||||
#define MAX_NOTIFICATION_SETTINGS 4
|
||||
|
||||
@@ -162,6 +163,14 @@ static void vibro_changed(VariableItem* item) {
|
||||
@@ -20,6 +21,8 @@ static const NotificationSequence sequence_note_c = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
+static VariableItem* temp_item;
|
||||
+
|
||||
#define CONTRAST_COUNT 11
|
||||
const char* const contrast_text[CONTRAST_COUNT] = {
|
||||
"-5",
|
||||
@@ -156,6 +159,59 @@ static void vibro_changed(VariableItem* item) {
|
||||
notification_message(app->notification, &sequence_single_vibro);
|
||||
}
|
||||
|
||||
+// Set RGB backlight color
|
||||
+static void color_changed(VariableItem* item) {
|
||||
+ NotificationAppSettings* app = variable_item_get_context(item);
|
||||
+ uint8_t index = variable_item_get_current_value_index(item);
|
||||
@@ -41,31 +51,102 @@ index 565d4f1..bae9299 100644
|
||||
+ variable_item_set_current_value_text(item, rgb_backlight_get_color_text(index));
|
||||
+ notification_message(app->notification, &sequence_display_backlight_on);
|
||||
+}
|
||||
+
|
||||
+// TODO: refactor and fix this
|
||||
+static void color_set_custom_red(VariableItem* item) {
|
||||
+ NotificationAppSettings* app = variable_item_get_context(item);
|
||||
+ uint8_t index = variable_item_get_current_value_index(item);
|
||||
+ rgb_backlight_set_custom_color(index, 0);
|
||||
+ char valtext[4] = {};
|
||||
+ snprintf(valtext, sizeof(valtext), "%d", index);
|
||||
+ variable_item_set_current_value_text(item, valtext);
|
||||
+ rgb_backlight_set_color(13);
|
||||
+ rgb_backlight_update(app->notification->settings.display_brightness * 0xFF, true);
|
||||
+ // Set to custom color explicitly
|
||||
+ variable_item_set_current_value_index(temp_item, 13);
|
||||
+ variable_item_set_current_value_text(temp_item, rgb_backlight_get_color_text(13));
|
||||
+ notification_message(app->notification, &sequence_display_backlight_on);
|
||||
+}
|
||||
+static void color_set_custom_green(VariableItem* item) {
|
||||
+ NotificationAppSettings* app = variable_item_get_context(item);
|
||||
+ uint8_t index = variable_item_get_current_value_index(item);
|
||||
+ rgb_backlight_set_custom_color(index, 1);
|
||||
+ char valtext[4] = {};
|
||||
+ snprintf(valtext, sizeof(valtext), "%d", index);
|
||||
+ variable_item_set_current_value_text(item, valtext);
|
||||
+ rgb_backlight_set_color(13);
|
||||
+ rgb_backlight_update(app->notification->settings.display_brightness * 0xFF, true);
|
||||
+ // Set to custom color explicitly
|
||||
+ variable_item_set_current_value_index(temp_item, 13);
|
||||
+ variable_item_set_current_value_text(temp_item, rgb_backlight_get_color_text(13));
|
||||
+ notification_message(app->notification, &sequence_display_backlight_on);
|
||||
+}
|
||||
+static void color_set_custom_blue(VariableItem* item) {
|
||||
+ NotificationAppSettings* app = variable_item_get_context(item);
|
||||
+ uint8_t index = variable_item_get_current_value_index(item);
|
||||
+ rgb_backlight_set_custom_color(index, 2);
|
||||
+ char valtext[4] = {};
|
||||
+ snprintf(valtext, sizeof(valtext), "%d", index);
|
||||
+ variable_item_set_current_value_text(item, valtext);
|
||||
+ rgb_backlight_set_color(13);
|
||||
+ rgb_backlight_update(app->notification->settings.display_brightness * 0xFF, true);
|
||||
+ // Set to custom color explicitly
|
||||
+ variable_item_set_current_value_index(temp_item, 13);
|
||||
+ variable_item_set_current_value_text(temp_item, rgb_backlight_get_color_text(13));
|
||||
+ notification_message(app->notification, &sequence_display_backlight_on);
|
||||
+}
|
||||
+
|
||||
static uint32_t notification_app_settings_exit(void* context) {
|
||||
UNUSED(context);
|
||||
return VIEW_NONE;
|
||||
@@ -187,7 +196,13 @@ static NotificationAppSettings* alloc_settings() {
|
||||
@@ -180,8 +236,40 @@ static NotificationAppSettings* alloc_settings() {
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, contrast_text[value_index]);
|
||||
|
||||
item = variable_item_list_add(
|
||||
- app->variable_item_list, "LCD Backlight", BACKLIGHT_COUNT, backlight_changed, app);
|
||||
+ // RGB Colors
|
||||
+ item = variable_item_list_add(
|
||||
+ app->variable_item_list, "LCD Color", rgb_backlight_get_color_count(), color_changed, app);
|
||||
+ value_index = rgb_backlight_get_settings()->display_color_index;
|
||||
+ variable_item_set_current_value_index(item, value_index);
|
||||
+ variable_item_set_current_value_text(item, rgb_backlight_get_color_text(value_index));
|
||||
+ temp_item = item;
|
||||
+
|
||||
+ // Custom Color - REFACTOR THIS
|
||||
+ item = variable_item_list_add(
|
||||
+ app->variable_item_list, "Custom Red", 255, color_set_custom_red, app);
|
||||
+ value_index = rgb_backlight_get_settings()->custom_r;
|
||||
+ variable_item_set_current_value_index(item, value_index);
|
||||
+ char valtext[4] = {};
|
||||
+ snprintf(valtext, sizeof(valtext), "%d", value_index);
|
||||
+ variable_item_set_current_value_text(item, valtext);
|
||||
+
|
||||
+ item = variable_item_list_add(
|
||||
+ app->variable_item_list, "Custom Green", 255, color_set_custom_green, app);
|
||||
+ value_index = rgb_backlight_get_settings()->custom_g;
|
||||
+ variable_item_set_current_value_index(item, value_index);
|
||||
+ snprintf(valtext, sizeof(valtext), "%d", value_index);
|
||||
+ variable_item_set_current_value_text(item, valtext);
|
||||
+
|
||||
+ item = variable_item_list_add(
|
||||
+ app->variable_item_list, "Custom Blue", 255, color_set_custom_blue, app);
|
||||
+ value_index = rgb_backlight_get_settings()->custom_b;
|
||||
+ variable_item_set_current_value_index(item, value_index);
|
||||
+ snprintf(valtext, sizeof(valtext), "%d", value_index);
|
||||
+ variable_item_set_current_value_text(item, valtext);
|
||||
+ // End of RGB
|
||||
+
|
||||
item = variable_item_list_add(
|
||||
- app->variable_item_list, "LCD Backlight", BACKLIGHT_COUNT, backlight_changed, app);
|
||||
+ app->variable_item_list, "LCD Brightness", BACKLIGHT_COUNT, backlight_changed, app);
|
||||
value_index = value_index_float(
|
||||
app->notification->settings.display_brightness, backlight_value, BACKLIGHT_COUNT);
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
diff --git a/applications/settings/notification_settings/rgb_backlight.c b/applications/settings/notification_settings/rgb_backlight.c
|
||||
new file mode 100644
|
||||
index 0000000..269b544
|
||||
index 0000000..98f0d3a
|
||||
--- /dev/null
|
||||
+++ b/applications/settings/notification_settings/rgb_backlight.c
|
||||
@@ -0,0 +1,171 @@
|
||||
@@ -0,0 +1,217 @@
|
||||
+/*
|
||||
+ RGB backlight FlipperZero driver
|
||||
+ Copyright (C) 2022-2023 Victor Nikitchuk (https://github.com/quen0n)
|
||||
@@ -88,9 +169,9 @@ index 0000000..269b544
|
||||
+#include <furi_hal.h>
|
||||
+#include <storage/storage.h>
|
||||
+
|
||||
+#define RGB_BACKLIGHT_SETTINGS_VERSION 5
|
||||
+#define RGB_BACKLIGHT_SETTINGS_VERSION 6
|
||||
+#define RGB_BACKLIGHT_SETTINGS_FILE_NAME ".rgb_backlight.settings"
|
||||
+#define RGB_BACKLIGHT_SETTINGS_PATH EXT_PATH(RGB_BACKLIGHT_SETTINGS_FILE_NAME)
|
||||
+#define RGB_BACKLIGHT_SETTINGS_PATH INT_PATH(RGB_BACKLIGHT_SETTINGS_FILE_NAME)
|
||||
+
|
||||
+#define COLOR_COUNT (sizeof(colors) / sizeof(RGBBacklightColor))
|
||||
+
|
||||
@@ -99,11 +180,14 @@ index 0000000..269b544
|
||||
+static RGBBacklightSettings rgb_settings = {
|
||||
+ .version = RGB_BACKLIGHT_SETTINGS_VERSION,
|
||||
+ .display_color_index = 0,
|
||||
+ .custom_r = 254,
|
||||
+ .custom_g = 254,
|
||||
+ .custom_b = 254,
|
||||
+ .settings_is_loaded = false};
|
||||
+
|
||||
+static const RGBBacklightColor colors[] = {
|
||||
+ {"Orange", 255, 60, 0},
|
||||
+ {"Yellow", 255, 150, 0},
|
||||
+ {"Yellow", 255, 144, 0},
|
||||
+ {"Spring", 167, 255, 0},
|
||||
+ {"Lime", 0, 255, 0},
|
||||
+ {"Aqua", 0, 255, 127},
|
||||
@@ -114,7 +198,8 @@ index 0000000..269b544
|
||||
+ {"Magenta", 210, 0, 210},
|
||||
+ {"Pink", 255, 0, 127},
|
||||
+ {"Red", 255, 0, 0},
|
||||
+ {"White", 150, 150, 110},
|
||||
+ {"White", 254, 210, 200},
|
||||
+ {"Custom", 0, 0, 0},
|
||||
+};
|
||||
+
|
||||
+uint8_t rgb_backlight_get_color_count(void) {
|
||||
@@ -126,18 +211,28 @@ index 0000000..269b544
|
||||
+}
|
||||
+
|
||||
+void rgb_backlight_load_settings(void) {
|
||||
+ //Не загружать данные из внутренней памяти при загрузке в режиме DFU
|
||||
+ FuriHalRtcBootMode bm = furi_hal_rtc_get_boot_mode();
|
||||
+ if(bm == FuriHalRtcBootModeDfu) {
|
||||
+ // Do not load settings if we are in other boot modes than normal
|
||||
+ if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) {
|
||||
+ rgb_settings.settings_is_loaded = true;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // Wait for all required services to start and create their records
|
||||
+ uint8_t timeout = 0;
|
||||
+ while(!furi_record_exists(RECORD_STORAGE)) {
|
||||
+ timeout++;
|
||||
+ if(timeout > 150) {
|
||||
+ rgb_settings.settings_is_loaded = true;
|
||||
+ return;
|
||||
+ }
|
||||
+ furi_delay_ms(5);
|
||||
+ }
|
||||
+
|
||||
+ RGBBacklightSettings settings;
|
||||
+ File* file = storage_file_alloc(furi_record_open(RECORD_STORAGE));
|
||||
+ const size_t settings_size = sizeof(RGBBacklightSettings);
|
||||
+
|
||||
+ FURI_LOG_I(TAG, "loading settings from \"%s\"", RGB_BACKLIGHT_SETTINGS_PATH);
|
||||
+ FURI_LOG_D(TAG, "loading settings from \"%s\"", RGB_BACKLIGHT_SETTINGS_PATH);
|
||||
+ bool fs_result =
|
||||
+ storage_file_open(file, RGB_BACKLIGHT_SETTINGS_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
|
||||
+
|
||||
@@ -150,7 +245,7 @@ index 0000000..269b544
|
||||
+ }
|
||||
+
|
||||
+ if(fs_result) {
|
||||
+ FURI_LOG_I(TAG, "load success");
|
||||
+ FURI_LOG_D(TAG, "load success");
|
||||
+ if(settings.version != RGB_BACKLIGHT_SETTINGS_VERSION) {
|
||||
+ FURI_LOG_E(
|
||||
+ TAG,
|
||||
@@ -175,7 +270,7 @@ index 0000000..269b544
|
||||
+ File* file = storage_file_alloc(furi_record_open(RECORD_STORAGE));
|
||||
+ const size_t settings_size = sizeof(RGBBacklightSettings);
|
||||
+
|
||||
+ FURI_LOG_I(TAG, "saving settings to \"%s\"", RGB_BACKLIGHT_SETTINGS_PATH);
|
||||
+ FURI_LOG_D(TAG, "saving settings to \"%s\"", RGB_BACKLIGHT_SETTINGS_PATH);
|
||||
+
|
||||
+ memcpy(&settings, &rgb_settings, settings_size);
|
||||
+
|
||||
@@ -191,7 +286,7 @@ index 0000000..269b544
|
||||
+ }
|
||||
+
|
||||
+ if(fs_result) {
|
||||
+ FURI_LOG_I(TAG, "save success");
|
||||
+ FURI_LOG_D(TAG, "save success");
|
||||
+ } else {
|
||||
+ FURI_LOG_E(TAG, "save failed, %s", storage_file_get_error_desc(file));
|
||||
+ }
|
||||
@@ -213,36 +308,68 @@ index 0000000..269b544
|
||||
+ rgb_settings.display_color_index = color_index;
|
||||
+}
|
||||
+
|
||||
+void rgb_backlight_update(uint8_t brightness) {
|
||||
+void rgb_backlight_set_custom_color(uint8_t color, uint8_t index) {
|
||||
+ if(index > 2) return;
|
||||
+ if(index == 0) {
|
||||
+ rgb_settings.custom_r = color;
|
||||
+ } else if(index == 1) {
|
||||
+ rgb_settings.custom_g = color;
|
||||
+ } else if(index == 2) {
|
||||
+ rgb_settings.custom_b = color;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void rgb_backlight_update(uint8_t brightness, bool bypass) {
|
||||
+ if(!rgb_settings.settings_is_loaded) {
|
||||
+ rgb_backlight_load_settings();
|
||||
+ }
|
||||
+
|
||||
+ if(!bypass) {
|
||||
+ static uint8_t last_color_index = 255;
|
||||
+ static uint8_t last_brightness = 123;
|
||||
+
|
||||
+ if(last_brightness == brightness && last_color_index == rgb_settings.display_color_index)
|
||||
+ if(last_brightness == brightness && last_color_index == rgb_settings.display_color_index) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ last_brightness = brightness;
|
||||
+ last_color_index = rgb_settings.display_color_index;
|
||||
+ }
|
||||
+
|
||||
+ for(uint8_t i = 0; i < SK6805_get_led_count(); i++) {
|
||||
+ if(rgb_settings.display_color_index == 13) {
|
||||
+ uint8_t r = rgb_settings.custom_r * (brightness / 255.0f);
|
||||
+ uint8_t g = rgb_settings.custom_g * (brightness / 255.0f);
|
||||
+ uint8_t b = rgb_settings.custom_b * (brightness / 255.0f);
|
||||
+
|
||||
+ SK6805_set_led_color(i, r, g, b);
|
||||
+ } else {
|
||||
+ if((colors[rgb_settings.display_color_index].red == 0) &&
|
||||
+ (colors[rgb_settings.display_color_index].green == 0) &&
|
||||
+ (colors[rgb_settings.display_color_index].blue == 0)) {
|
||||
+ uint8_t r = colors[0].red * (brightness / 255.0f);
|
||||
+ uint8_t g = colors[0].green * (brightness / 255.0f);
|
||||
+ uint8_t b = colors[0].blue * (brightness / 255.0f);
|
||||
+
|
||||
+ SK6805_set_led_color(i, r, g, b);
|
||||
+ } else {
|
||||
+ uint8_t r = colors[rgb_settings.display_color_index].red * (brightness / 255.0f);
|
||||
+ uint8_t g = colors[rgb_settings.display_color_index].green * (brightness / 255.0f);
|
||||
+ uint8_t b = colors[rgb_settings.display_color_index].blue * (brightness / 255.0f);
|
||||
+
|
||||
+ SK6805_set_led_color(i, r, g, b);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ SK6805_update();
|
||||
+}
|
||||
diff --git a/applications/settings/notification_settings/rgb_backlight.h b/applications/settings/notification_settings/rgb_backlight.h
|
||||
new file mode 100644
|
||||
index 0000000..b63d223
|
||||
index 0000000..68dacda
|
||||
--- /dev/null
|
||||
+++ b/applications/settings/notification_settings/rgb_backlight.h
|
||||
@@ -0,0 +1,79 @@
|
||||
@@ -0,0 +1,91 @@
|
||||
+/*
|
||||
+ RGB backlight FlipperZero driver
|
||||
+ Copyright (C) 2022-2023 Victor Nikitchuk (https://github.com/quen0n)
|
||||
@@ -274,6 +401,9 @@ index 0000000..b63d223
|
||||
+typedef struct {
|
||||
+ uint8_t version;
|
||||
+ uint8_t display_color_index;
|
||||
+ uint8_t custom_r;
|
||||
+ uint8_t custom_g;
|
||||
+ uint8_t custom_b;
|
||||
+ bool settings_is_loaded;
|
||||
+} RGBBacklightSettings;
|
||||
+
|
||||
@@ -298,8 +428,9 @@ index 0000000..b63d223
|
||||
+ * @brief Применить текущие настройки RGB-подсветки
|
||||
+ *
|
||||
+ * @param brightness Яркость свечения (0-255)
|
||||
+ * @param bypass Применить настройки принудительно
|
||||
+ */
|
||||
+void rgb_backlight_update(uint8_t brightness);
|
||||
+void rgb_backlight_update(uint8_t brightness, bool bypass);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Установить цвет RGB-подсветки
|
||||
@@ -309,6 +440,14 @@ index 0000000..b63d223
|
||||
+void rgb_backlight_set_color(uint8_t color_index);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Set custom color values by index - 0=R 1=G 2=B
|
||||
+ *
|
||||
+ * @param color - color value (0-255)
|
||||
+ * @param index - color index (0-2) 0=R 1=G 2=B
|
||||
+ */
|
||||
+void rgb_backlight_set_custom_color(uint8_t color, uint8_t index);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Получить количество доступных цветов
|
||||
+ *
|
||||
+ * @return Число доступных вариантов цвета
|
||||
@@ -324,7 +463,7 @@ index 0000000..b63d223
|
||||
+const char* rgb_backlight_get_color_text(uint8_t index);
|
||||
\ No newline at end of file
|
||||
diff --git a/firmware/targets/f7/furi_hal/furi_hal_light.c b/firmware/targets/f7/furi_hal/furi_hal_light.c
|
||||
index 83e1603..cad5b86 100644
|
||||
index 83e1603..45798ca 100644
|
||||
--- a/firmware/targets/f7/furi_hal/furi_hal_light.c
|
||||
+++ b/firmware/targets/f7/furi_hal/furi_hal_light.c
|
||||
@@ -3,6 +3,7 @@
|
||||
@@ -353,7 +492,7 @@ index 83e1603..cad5b86 100644
|
||||
- uint8_t prev = lp5562_get_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite);
|
||||
- lp5562_execute_ramp(
|
||||
- &furi_hal_i2c_handle_power, LP5562Engine1, LP5562ChannelWhite, prev, value, 100);
|
||||
+ rgb_backlight_update(value);
|
||||
+ rgb_backlight_update(value, false);
|
||||
+ } else {
|
||||
+ furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
|
||||
+ if(light & LightRed) {
|
||||
|
||||
54
CHANGELOG.md
54
CHANGELOG.md
@@ -1,50 +1,12 @@
|
||||
## New changes
|
||||
* **Apple BLE Spam app** (by @Willy-JL | Plus research from ECTO-1A, xMasterX and techryptic) -> (app can be found in builds ` `, `e`, `n`, `r`)
|
||||
* Plugins -> Note for new users: **PicoPass emulation is available** in (Apps -> NFC -> PicoPass) + Latest PicoPass emulation fixes (by nvx) -> (app can be found in builds ` `, `e`, `n`, `r`)
|
||||
* SubGHz: **FAAC SLH - Programming mode** (by @xMasterX & @Eng1n33r (full research and PoC by @Skorpionm)| PR #585) -> [How to use](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md)
|
||||
* SubGHz: FAAC SLH -> Add manually new options
|
||||
* SubGHz: **Ignore Princeton** option
|
||||
* SubGHz: **Save all settings, option to reset config to default** (by @derskythe | PR #590)
|
||||
* SubGHz: Fix 0xFFFF counter value being skipped
|
||||
* SubGHz: Fix path reset on save name scene exit
|
||||
* SubGHz: Various fixes
|
||||
* SubGHz Remote: New design (by @Svaarich) - Implemented by @gid9798
|
||||
* SubGHz Remote: Fix Sub-GHz Remote folder name (by @OperKH | PR #583)
|
||||
* SubGHz Remote: submodule (by @gid9798 | PR #592)
|
||||
* Infrared: Updated universal assets (by @amec0e | PR #594)
|
||||
* Infrared: Remake custom universal remotes to use new design (New icons by @Svaarich)
|
||||
* UI: Keyboard ok to toggle select all in cursor mode (by @Willy-JL)
|
||||
* CI/CD: CodeQL for internal usage
|
||||
* CI/CD: Fixed regular builds having `c` in version name in the device info while not being actual `c` build
|
||||
* Docs: New FAAC SLH instructions
|
||||
* Docs: Readme & Changelog fixes (by @gid9798 | PR #586 #600)
|
||||
* OFW: Sub-GHz: fix incorrect key parsing crash
|
||||
* OFW: fbt: added FW_CFG_name with build configuration
|
||||
* OFW: SD-Card: proper HAL -> **Breaking API change, API 37.x -> API 38.x** - **Update your apps!**
|
||||
* OFW: Various Fixes and Improvements -> **Breaking API change, API 36.x -> API 37.x** - **Update your apps!**
|
||||
* OFW: iButton: Return to the file selection if file is corrupted
|
||||
* OFW: Account for the "-" in line carry-over
|
||||
* OFW: github: workflow improvements
|
||||
* OFW: Storage: force mount
|
||||
* OFW: Add File Naming setting for more detailed naming -> **Breaking API change, API 35.x -> API 36.x** - **Update your apps!**
|
||||
* OFW: Disconnect from BLE on protobuf error
|
||||
* OFW: Add support for Mifare Classic 4k SAK 0x38 ATQA 0x02, 0x04, 0x08
|
||||
* OFW: Undo some TODO
|
||||
* OFW: Check the filetype of the update manifest
|
||||
* OFW: StorageListRequest: size filter
|
||||
* OFW: SubGhz: heap overflow text error
|
||||
* OFW: nfc: add rfal wrong state error handling
|
||||
* OFW: Rfid: fix crash on broken key launch from archive (fix was already done in UL in similar way)
|
||||
* OFW: AC OFF button
|
||||
* OFW: New IR universal remote graphics
|
||||
* OFW: Intelligent probing with warnings for fwflash.py
|
||||
* OFW: FuriHal: explicitly pull display pins at early init stage, move PUPD config to early stage
|
||||
* OFW: Fix display last symbol in multiline text
|
||||
* OFW: Properly reset the NFC device data
|
||||
* OFW: fbt: various improvements and bug fixes
|
||||
* OFW: Littlefs updated to v2.7.0
|
||||
* OFW: loader: restored support for debug apps
|
||||
* OFW: Removed explicit dependency on scons for external scripting
|
||||
* SubGHz: Add 4 more systems to Add Manually (untested!)
|
||||
* SubGHz: Add Manually fixes
|
||||
* Misc code cleanup
|
||||
* RGB: Fix white color on reboot, move settings, add custom color option
|
||||
* **BLE Spam app** updated to latest version (Android, Windows support) (by @Willy-JL) -> (app can be found in builds ` `, `e`, `n`, `r`)
|
||||
* OFW: Fix double arrows and add proper indication
|
||||
* OFW: SubGHz: add manually fix 12-bits is 0xFFF (or 0xFF0) CAME/NICE 12-bit
|
||||
* OFW: Fix various crashes if debug libraries used
|
||||
|
||||
----
|
||||
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
|
||||
<br>
|
||||
|
||||
## FAQ (frequently asked questions)
|
||||
[Follow this link to find answers to most asked questions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/FAQ.md)
|
||||
|
||||
## Dev builds (unstable)
|
||||
- https://dev.unleashedflip.com/
|
||||
- https://t.me/kotnehleb
|
||||
|
||||
@@ -39,15 +39,25 @@ void icc_power_on_callback(uint8_t* atrBuffer, uint32_t* atrlen, void* context)
|
||||
iso7816_answer_to_reset(atrBuffer, atrlen);
|
||||
}
|
||||
|
||||
void xfr_datablock_callback(uint8_t* dataBlock, uint32_t* dataBlockLen, void* context) {
|
||||
//dataBlock points to the buffer
|
||||
//dataBlockLen tells reader how nany bytes should be read
|
||||
void xfr_datablock_callback(
|
||||
const uint8_t* dataBlock,
|
||||
uint32_t dataBlockLen,
|
||||
uint8_t* responseDataBlock,
|
||||
uint32_t* responseDataBlockLen,
|
||||
void* context) {
|
||||
UNUSED(context);
|
||||
|
||||
struct ISO7816_Command_APDU commandAPDU;
|
||||
iso7816_read_command_apdu(&commandAPDU, dataBlock, dataBlockLen);
|
||||
|
||||
struct ISO7816_Response_APDU responseAPDU;
|
||||
//class not supported
|
||||
responseAPDU.SW1 = 0x6E;
|
||||
responseAPDU.SW2 = 0x00;
|
||||
|
||||
iso7816_write_response_apdu(&responseAPDU, dataBlock, dataBlockLen);
|
||||
iso7816_write_response_apdu(&responseAPDU, responseDataBlock, responseDataBlockLen);
|
||||
}
|
||||
|
||||
static const CcidCallbacks ccid_cb = {
|
||||
@@ -66,7 +76,7 @@ static void ccid_test_app_render_callback(Canvas* canvas, void* ctx) {
|
||||
canvas_draw_str(canvas, 0, 63, "Hold [back] to exit");
|
||||
}
|
||||
|
||||
static void ccid_test_app__input_callback(InputEvent* input_event, void* ctx) {
|
||||
static void ccid_test_app_input_callback(InputEvent* input_event, void* ctx) {
|
||||
FuriMessageQueue* event_queue = ctx;
|
||||
|
||||
CcidTestAppEvent event;
|
||||
@@ -94,7 +104,7 @@ CcidTestApp* ccid_test_app_alloc() {
|
||||
//message queue
|
||||
app->event_queue = furi_message_queue_alloc(8, sizeof(CcidTestAppEvent));
|
||||
furi_check(app->event_queue);
|
||||
view_port_input_callback_set(app->view_port, ccid_test_app__input_callback, app->event_queue);
|
||||
view_port_input_callback_set(app->view_port, ccid_test_app_input_callback, app->event_queue);
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <furi.h>
|
||||
#include "iso7816_t0_apdu.h"
|
||||
|
||||
void iso7816_answer_to_reset(uint8_t* atrBuffer, uint32_t* atrlen) {
|
||||
void iso7816_answer_to_reset(uint8_t* dataBuffer, uint32_t* atrlen) {
|
||||
//minimum valid ATR: https://smartcard-atr.apdu.fr/parse?ATR=3B+00
|
||||
uint8_t AtrBuffer[2] = {
|
||||
0x3B, //TS (direct convention)
|
||||
@@ -12,18 +12,19 @@ void iso7816_answer_to_reset(uint8_t* atrBuffer, uint32_t* atrlen) {
|
||||
};
|
||||
*atrlen = 2;
|
||||
|
||||
memcpy(atrBuffer, AtrBuffer, sizeof(uint8_t) * (*atrlen));
|
||||
memcpy(dataBuffer, AtrBuffer, sizeof(uint8_t) * (*atrlen));
|
||||
}
|
||||
|
||||
void iso7816_read_command_apdu(
|
||||
struct ISO7816_Command_APDU* command,
|
||||
const uint8_t* dataBuffer,
|
||||
uint32_t dataLen) {
|
||||
furi_assert(dataLen <= 4);
|
||||
UNUSED(dataLen);
|
||||
command->CLA = dataBuffer[0];
|
||||
command->INS = dataBuffer[1];
|
||||
command->P1 = dataBuffer[2];
|
||||
command->P2 = dataBuffer[3];
|
||||
command->Lc = dataBuffer[4];
|
||||
}
|
||||
|
||||
void iso7816_write_response_apdu(
|
||||
|
||||
@@ -6,18 +6,18 @@
|
||||
struct ISO7816_Command_APDU {
|
||||
//header
|
||||
uint8_t CLA;
|
||||
uint32_t INS;
|
||||
uint8_t INS;
|
||||
uint8_t P1;
|
||||
uint8_t P2;
|
||||
|
||||
//body
|
||||
uint8_t Nc;
|
||||
uint8_t Ne;
|
||||
uint8_t Lc;
|
||||
uint8_t Le;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct ISO7816_Response_APDU {
|
||||
uint8_t SW1;
|
||||
uint32_t SW2;
|
||||
uint8_t SW2;
|
||||
} __attribute__((packed));
|
||||
|
||||
void iso7816_answer_to_reset(uint8_t* atrBuffer, uint32_t* atrlen);
|
||||
|
||||
@@ -19,7 +19,7 @@ We recommend to use the `APP_ASSETS_PATH` macro to get the path to the Apps Asse
|
||||
|
||||
## What is the difference between the Apps Assets folder and the Apps Data folder?
|
||||
|
||||
The Apps Assets folder is used to store the data <u>provided</u> with the application. For example, if you want to create a game, you can store game levels (contant data) in the Apps Assets folder.
|
||||
The Apps Assets folder is used to store the data <u>provided</u> with the application. For example, if you want to create a game, you can store game levels (content data) in the Apps Assets folder.
|
||||
|
||||
The Apps Data folder is used to store data <u>generated</u> by the application. For example, if you want to create a game, you can save the progress of the game (user-generated data) in the Apps Data folder.
|
||||
|
||||
|
||||
@@ -19,6 +19,6 @@ We recommend to use the `APP_DATA_PATH` macro to get the path to the Apps Data f
|
||||
|
||||
## What is the difference between the Apps Assets folder and the Apps Data folder?
|
||||
|
||||
The Apps Assets folder is used to store the data <u>provided</u> with the application. For example, if you want to create a game, you can store game levels (contant data) in the Apps Assets folder.
|
||||
The Apps Assets folder is used to store the data <u>provided</u> with the application. For example, if you want to create a game, you can store game levels (content data) in the Apps Assets folder.
|
||||
|
||||
The Apps Data folder is used to store data <u>generated</u> by the application. For example, if you want to create a game, you can save the progress of the game (user-generated data) in the Apps Data folder.
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
/* Common interface between a plugin and host applicaion */
|
||||
/* Common interface between a plugin and host application */
|
||||
|
||||
#define PLUGIN_APP_ID "example_plugins"
|
||||
#define PLUGIN_API_VERSION 1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
/* Common interface between a plugin and host applicaion */
|
||||
/* Common interface between a plugin and host application */
|
||||
|
||||
#define PLUGIN_APP_ID "example_plugins_advanced"
|
||||
#define PLUGIN_API_VERSION 1
|
||||
|
||||
@@ -90,7 +90,7 @@ static void example_thermo_request_temperature(ExampleThermoContext* context) {
|
||||
bool success = false;
|
||||
do {
|
||||
/* Each communication with a 1-wire device starts by a reset.
|
||||
The functon will return true if a device responded with a presence pulse. */
|
||||
The function will return true if a device responded with a presence pulse. */
|
||||
if(!onewire_host_reset(onewire)) break;
|
||||
/* After the reset, a ROM operation must follow.
|
||||
If there is only one device connected, the "Skip ROM" command is most appropriate
|
||||
@@ -130,7 +130,7 @@ static void example_thermo_read_temperature(ExampleThermoContext* context) {
|
||||
size_t attempts_left = 10;
|
||||
do {
|
||||
/* Each communication with a 1-wire device starts by a reset.
|
||||
The functon will return true if a device responded with a presence pulse. */
|
||||
The function will return true if a device responded with a presence pulse. */
|
||||
if(!onewire_host_reset(onewire)) continue;
|
||||
|
||||
/* After the reset, a ROM operation must follow.
|
||||
@@ -221,8 +221,7 @@ static void example_thermo_draw_callback(Canvas* canvas, void* ctx) {
|
||||
canvas_draw_line(canvas, 0, 16, 128, 16);
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, middle_x, 30, AlignCenter, AlignBottom, "Connnect thermometer");
|
||||
canvas_draw_str_aligned(canvas, middle_x, 30, AlignCenter, AlignBottom, "Connect thermometer");
|
||||
|
||||
snprintf(
|
||||
text_store,
|
||||
@@ -237,7 +236,7 @@ static void example_thermo_draw_callback(Canvas* canvas, void* ctx) {
|
||||
float temp;
|
||||
char temp_units;
|
||||
|
||||
/* The applicaton is locale-aware.
|
||||
/* The application is locale-aware.
|
||||
Change Settings->System->Units to check it out. */
|
||||
switch(locale_get_measurement_unit()) {
|
||||
case LocaleMeasurementUnitsMetric:
|
||||
@@ -355,7 +354,7 @@ int32_t example_thermo_main(void* p) {
|
||||
/* Allocate all of the necessary structures */
|
||||
ExampleThermoContext* context = example_thermo_context_alloc();
|
||||
|
||||
/* Start the applicaton's main loop. It won't return until the application was requested to exit. */
|
||||
/* Start the application's main loop. It won't return until the application was requested to exit. */
|
||||
example_thermo_run(context);
|
||||
|
||||
/* Release all unneeded resources */
|
||||
|
||||
@@ -294,7 +294,7 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil
|
||||
return delay_val;
|
||||
} else if(delay_val < 0) { // Script error
|
||||
bad_usb->st.error_line = bad_usb->st.line_cur - 1;
|
||||
FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_usb->st.line_cur - 1U);
|
||||
FURI_LOG_E(WORKER_TAG, "Unknown command at line %zu", bad_usb->st.line_cur - 1U);
|
||||
return SCRIPT_STATE_ERROR;
|
||||
} else {
|
||||
return (delay_val + bad_usb->defdelay);
|
||||
@@ -333,7 +333,7 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil
|
||||
return delay_val;
|
||||
} else if(delay_val < 0) {
|
||||
bad_usb->st.error_line = bad_usb->st.line_cur;
|
||||
FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_usb->st.line_cur);
|
||||
FURI_LOG_E(WORKER_TAG, "Unknown command at line %zu", bad_usb->st.line_cur);
|
||||
return SCRIPT_STATE_ERROR;
|
||||
} else {
|
||||
return (delay_val + bad_usb->defdelay);
|
||||
|
||||
@@ -24,10 +24,10 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
BadUsbWorkerState state;
|
||||
uint16_t line_cur;
|
||||
uint16_t line_nb;
|
||||
size_t line_cur;
|
||||
size_t line_nb;
|
||||
uint32_t delay_remain;
|
||||
uint16_t error_line;
|
||||
size_t error_line;
|
||||
char error[64];
|
||||
} BadUsbState;
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ static int32_t ducky_fnc_string(BadUsbScript* bad_usb, const char* line, int32_t
|
||||
furi_string_cat(bad_usb->string_print, "\n");
|
||||
}
|
||||
|
||||
if(bad_usb->stringdelay == 0) { // stringdelay not set - run command immidiately
|
||||
if(bad_usb->stringdelay == 0) { // stringdelay not set - run command immediately
|
||||
bool state = ducky_string(bad_usb, furi_string_get_cstr(bad_usb->string_print));
|
||||
if(!state) {
|
||||
return ducky_error(bad_usb, "Invalid string %s", line);
|
||||
|
||||
@@ -82,7 +82,7 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(canvas, 127, 33, AlignRight, AlignBottom, "ERROR:");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
furi_string_printf(disp_str, "line %u", model->state.error_line);
|
||||
furi_string_printf(disp_str, "line %zu", model->state.error_line);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 127, 46, AlignRight, AlignBottom, furi_string_get_cstr(disp_str));
|
||||
furi_string_reset(disp_str);
|
||||
@@ -105,7 +105,7 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
|
||||
}
|
||||
canvas_set_font(canvas, FontBigNumbers);
|
||||
furi_string_printf(
|
||||
disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb);
|
||||
disp_str, "%zu", ((model->state.line_cur - 1) * 100) / model->state.line_nb);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 114, 40, AlignRight, AlignBottom, furi_string_get_cstr(disp_str));
|
||||
furi_string_reset(disp_str);
|
||||
@@ -124,7 +124,7 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
|
||||
}
|
||||
canvas_set_font(canvas, FontBigNumbers);
|
||||
furi_string_printf(
|
||||
disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb);
|
||||
disp_str, "%zu", ((model->state.line_cur - 1) * 100) / model->state.line_nb);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 114, 40, AlignRight, AlignBottom, furi_string_get_cstr(disp_str));
|
||||
furi_string_reset(disp_str);
|
||||
@@ -142,7 +142,7 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
|
||||
}
|
||||
canvas_set_font(canvas, FontBigNumbers);
|
||||
furi_string_printf(
|
||||
disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb);
|
||||
disp_str, "%zu", ((model->state.line_cur - 1) * 100) / model->state.line_nb);
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 114, 40, AlignRight, AlignBottom, furi_string_get_cstr(disp_str));
|
||||
furi_string_reset(disp_str);
|
||||
|
||||
@@ -25,8 +25,12 @@ typedef enum {
|
||||
SubmenuIndexStilmatic,
|
||||
SubmenuIndexDTMNeo433,
|
||||
SubmenuIndexGibidi433,
|
||||
SubmenuIndexNiceMHouse_433_92,
|
||||
SubmenuIndexJCM_433_92,
|
||||
SubmenuIndexNormstahl_433_92,
|
||||
SubmenuIndexGSN,
|
||||
SubmenuIndexAprimatic,
|
||||
SubmenuIndexHCS101_433_92,
|
||||
SubmenuIndexANMotorsAT4,
|
||||
SubmenuIndexAlutechAT4N,
|
||||
SubmenuIndexNiceFlo12bit,
|
||||
@@ -51,9 +55,9 @@ typedef enum {
|
||||
SubmenuIndexGateTX,
|
||||
SubmenuIndexDoorHan_315_00,
|
||||
SubmenuIndexDoorHan_433_92,
|
||||
SubmenuIndexLiftMaster_315_00,
|
||||
SubmenuIndexLiftMaster_390_00,
|
||||
SubmenuIndexLiftMaster_433_00,
|
||||
SubmenuIndexSecPlus_v1_315_00,
|
||||
SubmenuIndexSecPlus_v1_390_00,
|
||||
SubmenuIndexSecPlus_v1_433_00,
|
||||
SubmenuIndexSecPlus_v2_310_00,
|
||||
SubmenuIndexSecPlus_v2_315_00,
|
||||
SubmenuIndexSecPlus_v2_390_00,
|
||||
|
||||
@@ -67,6 +67,12 @@ void subghz_scene_set_type_on_enter(void* context) {
|
||||
SubmenuIndexAlutechAT4N,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"KL: HCS101 433MHz",
|
||||
SubmenuIndexHCS101_433_92,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"KL: DoorHan 315MHz",
|
||||
@@ -163,6 +169,24 @@ void subghz_scene_set_type_on_enter(void* context) {
|
||||
SubmenuIndexElmesElectronic,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"KL: Normstahl 433MHz",
|
||||
SubmenuIndexNormstahl_433_92,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"KL: JCM Tech 433MHz",
|
||||
SubmenuIndexJCM_433_92,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"KL: Nice Mhouse 433MHz",
|
||||
SubmenuIndexNiceMHouse_433_92,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"KL: Nice Smilo 433MHz",
|
||||
@@ -278,19 +302,19 @@ void subghz_scene_set_type_on_enter(void* context) {
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"Security+1.0 315MHz",
|
||||
SubmenuIndexLiftMaster_315_00,
|
||||
SubmenuIndexSecPlus_v1_315_00,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"Security+1.0 390MHz",
|
||||
SubmenuIndexLiftMaster_390_00,
|
||||
SubmenuIndexSecPlus_v1_390_00,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"Security+1.0 433MHz",
|
||||
SubmenuIndexLiftMaster_433_00,
|
||||
SubmenuIndexSecPlus_v1_433_00,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
@@ -351,7 +375,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
|
||||
subghz->txrx, "AM650", 315000000, SUBGHZ_PROTOCOL_PRINCETON_NAME, key, 24, 400);
|
||||
break;
|
||||
case SubmenuIndexNiceFlo12bit:
|
||||
key = (key & 0x0000FFF0) | 0x1; //btn 0x1, 0x2, 0x4
|
||||
key = (key & 0x00000FF0) | 0x1; //btn 0x1, 0x2, 0x4
|
||||
generated_protocol = subghz_txrx_gen_data_protocol(
|
||||
subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_NICE_FLO_NAME, key, 12);
|
||||
break;
|
||||
@@ -361,7 +385,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
|
||||
subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_NICE_FLO_NAME, key, 24);
|
||||
break;
|
||||
case SubmenuIndexCAME12bit:
|
||||
key = (key & 0x0000FFF0) | 0x1; //btn 0x1, 0x2, 0x4
|
||||
key = (key & 0x00000FF0) | 0x1; //btn 0x1, 0x2, 0x4
|
||||
generated_protocol = subghz_txrx_gen_data_protocol(
|
||||
subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_CAME_NAME, key, 12);
|
||||
break;
|
||||
@@ -371,7 +395,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
|
||||
subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_CAME_NAME, key, 24);
|
||||
break;
|
||||
case SubmenuIndexCAME12bit868:
|
||||
key = (key & 0x0000FFF0) | 0x1; //btn 0x1, 0x2, 0x4
|
||||
key = (key & 0x00000FF0) | 0x1; //btn 0x1, 0x2, 0x4
|
||||
generated_protocol = subghz_txrx_gen_data_protocol(
|
||||
subghz->txrx, "AM650", 868350000, SUBGHZ_PROTOCOL_CAME_NAME, key, 12);
|
||||
break;
|
||||
@@ -702,31 +726,71 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
|
||||
}
|
||||
break;
|
||||
case SubmenuIndexLiftMaster_315_00:
|
||||
case SubmenuIndexNiceMHouse_433_92:
|
||||
generated_protocol = subghz_txrx_gen_keeloq_protocol(
|
||||
subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "NICE_MHOUSE");
|
||||
if(!generated_protocol) {
|
||||
furi_string_set(
|
||||
subghz->error_str, "Function requires\nan SD card with\nfresh databases.");
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
|
||||
}
|
||||
break;
|
||||
case SubmenuIndexJCM_433_92:
|
||||
generated_protocol = subghz_txrx_gen_keeloq_protocol(
|
||||
subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "JCM_Tech");
|
||||
if(!generated_protocol) {
|
||||
furi_string_set(
|
||||
subghz->error_str, "Function requires\nan SD card with\nfresh databases.");
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
|
||||
}
|
||||
break;
|
||||
case SubmenuIndexNormstahl_433_92:
|
||||
generated_protocol = subghz_txrx_gen_keeloq_protocol(
|
||||
subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "Normstahl");
|
||||
if(!generated_protocol) {
|
||||
furi_string_set(
|
||||
subghz->error_str, "Function requires\nan SD card with\nfresh databases.");
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
|
||||
}
|
||||
break;
|
||||
case SubmenuIndexHCS101_433_92:
|
||||
generated_protocol = subghz_txrx_gen_keeloq_protocol(
|
||||
subghz->txrx, "AM650", 433920000, key & 0x000FFFFF, 0x2, 0x0003, "HCS101");
|
||||
if(!generated_protocol) {
|
||||
furi_string_set(
|
||||
subghz->error_str, "Function requires\nan SD card with\nfresh databases.");
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
|
||||
}
|
||||
break;
|
||||
case SubmenuIndexSecPlus_v1_315_00:
|
||||
generated_protocol =
|
||||
subghz_txrx_gen_secplus_v1_protocol(subghz->txrx, "AM650", 315000000);
|
||||
break;
|
||||
case SubmenuIndexLiftMaster_390_00:
|
||||
case SubmenuIndexSecPlus_v1_390_00:
|
||||
generated_protocol =
|
||||
subghz_txrx_gen_secplus_v1_protocol(subghz->txrx, "AM650", 390000000);
|
||||
break;
|
||||
case SubmenuIndexLiftMaster_433_00:
|
||||
case SubmenuIndexSecPlus_v1_433_00:
|
||||
generated_protocol =
|
||||
subghz_txrx_gen_secplus_v1_protocol(subghz->txrx, "AM650", 433920000);
|
||||
break;
|
||||
case SubmenuIndexSecPlus_v2_310_00:
|
||||
key = (key & 0x7FFFF3FC); // 850LM pairing
|
||||
generated_protocol = subghz_txrx_gen_secplus_v2_protocol(
|
||||
subghz->txrx, "AM650", 310000000, key, 0x68, 0xE500000);
|
||||
break;
|
||||
case SubmenuIndexSecPlus_v2_315_00:
|
||||
key = (key & 0x7FFFF3FC); // 850LM pairing
|
||||
generated_protocol = subghz_txrx_gen_secplus_v2_protocol(
|
||||
subghz->txrx, "AM650", 315000000, key, 0x68, 0xE500000);
|
||||
break;
|
||||
case SubmenuIndexSecPlus_v2_390_00:
|
||||
key = (key & 0x7FFFF3FC); // 850LM pairing
|
||||
generated_protocol = subghz_txrx_gen_secplus_v2_protocol(
|
||||
subghz->txrx, "AM650", 390000000, key, 0x68, 0xE500000);
|
||||
break;
|
||||
case SubmenuIndexSecPlus_v2_433_00:
|
||||
key = (key & 0x7FFFF3FC); // 850LM pairing
|
||||
generated_protocol = subghz_txrx_gen_secplus_v2_protocol(
|
||||
subghz->txrx, "AM650", 433920000, key, 0x68, 0xE500000);
|
||||
break;
|
||||
|
||||
@@ -558,7 +558,7 @@ void subghz_cli_command_decode_raw(Cli* cli, FuriString* args, void* context) {
|
||||
}
|
||||
}
|
||||
|
||||
printf("\r\nPackets received \033[0;32m%u\033[0m\r\n", instance->packet_count);
|
||||
printf("\r\nPackets received \033[0;32m%zu\033[0m\r\n", instance->packet_count);
|
||||
|
||||
// Cleanup
|
||||
subghz_receiver_free(receiver);
|
||||
|
||||
@@ -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(
|
||||
@@ -219,20 +225,38 @@ static void byte_input_draw_input(Canvas* canvas, ByteInputModel* model) {
|
||||
byte_input_get_nibble_text(model->bytes[i], false));
|
||||
canvas_invert_color(canvas);
|
||||
}
|
||||
} else {
|
||||
if(model->first_visible_byte > 0 && i == model->first_visible_byte) {
|
||||
canvas_draw_icon(
|
||||
canvas,
|
||||
text_x + 2 + byte_position * 14,
|
||||
text_y - 7,
|
||||
&I_More_data_placeholder_5x7);
|
||||
} else {
|
||||
canvas_draw_glyph(
|
||||
canvas,
|
||||
text_x + 2 + byte_position * 14,
|
||||
text_y,
|
||||
byte_input_get_nibble_text(model->bytes[i], true));
|
||||
}
|
||||
if(model->bytes_count - model->first_visible_byte > max_drawable_bytes &&
|
||||
i == model->first_visible_byte + MIN(model->bytes_count, max_drawable_bytes) - 1) {
|
||||
canvas_draw_icon(
|
||||
canvas,
|
||||
text_x + 8 + byte_position * 14,
|
||||
text_y - 7,
|
||||
&I_More_data_placeholder_5x7);
|
||||
} else {
|
||||
canvas_draw_glyph(
|
||||
canvas,
|
||||
text_x + 8 + byte_position * 14,
|
||||
text_y,
|
||||
byte_input_get_nibble_text(model->bytes[i], false));
|
||||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
|
||||
@@ -253,14 +277,6 @@ static void byte_input_draw_input(Canvas* canvas, ByteInputModel* model) {
|
||||
snprintf(str, 20, "%u", (model->selected_byte + 1));
|
||||
canvas_draw_str(canvas, text_x + 75, text_y2, str);
|
||||
}
|
||||
|
||||
if(model->bytes_count - model->first_visible_byte > max_drawable_bytes) {
|
||||
canvas_draw_icon(canvas, 123, 21, &I_ButtonRightSmall_3x5);
|
||||
}
|
||||
|
||||
if(model->first_visible_byte > 0) {
|
||||
canvas_draw_icon(canvas, 1, 21, &I_ButtonLeftSmall_3x5);
|
||||
}
|
||||
}
|
||||
|
||||
/** Draw input box (selected view)
|
||||
@@ -298,12 +314,28 @@ static void byte_input_draw_input_selected(Canvas* canvas, ByteInputModel* model
|
||||
text_y,
|
||||
byte_input_get_nibble_text(model->bytes[i], false));
|
||||
canvas_invert_color(canvas);
|
||||
} else {
|
||||
if(model->first_visible_byte > 0 && i == model->first_visible_byte) {
|
||||
canvas_draw_icon(
|
||||
canvas,
|
||||
text_x + 2 + byte_position * 14,
|
||||
text_y - 7,
|
||||
&I_More_data_placeholder_5x7);
|
||||
} else {
|
||||
canvas_draw_glyph(
|
||||
canvas,
|
||||
text_x + 2 + byte_position * 14,
|
||||
text_y,
|
||||
byte_input_get_nibble_text(model->bytes[i], true));
|
||||
}
|
||||
if(model->bytes_count - model->first_visible_byte > max_drawable_bytes &&
|
||||
i == model->first_visible_byte + MIN(model->bytes_count, max_drawable_bytes) - 1) {
|
||||
canvas_draw_icon(
|
||||
canvas,
|
||||
text_x + 8 + byte_position * 14,
|
||||
text_y - 7,
|
||||
&I_More_data_placeholder_5x7);
|
||||
} else {
|
||||
canvas_draw_glyph(
|
||||
canvas,
|
||||
text_x + 8 + byte_position * 14,
|
||||
@@ -311,13 +343,6 @@ static void byte_input_draw_input_selected(Canvas* canvas, ByteInputModel* model
|
||||
byte_input_get_nibble_text(model->bytes[i], false));
|
||||
}
|
||||
}
|
||||
|
||||
if(model->bytes_count - model->first_visible_byte > max_drawable_bytes) {
|
||||
canvas_draw_icon(canvas, 123, 21, &I_ButtonRightSmall_3x5);
|
||||
}
|
||||
|
||||
if(model->first_visible_byte > 0) {
|
||||
canvas_draw_icon(canvas, 1, 21, &I_ButtonLeftSmall_3x5);
|
||||
}
|
||||
|
||||
canvas_invert_color(canvas);
|
||||
@@ -600,9 +625,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 +635,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);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BROWSER_SORT_THRESHOLD 400
|
||||
#define BROWSER_SORT_THRESHOLD 220
|
||||
|
||||
typedef struct BrowserWorker BrowserWorker;
|
||||
typedef void (*BrowserWorkerFolderOpenCallback)(
|
||||
|
||||
@@ -228,7 +228,7 @@ static void notification_process_notification_message(
|
||||
}
|
||||
break;
|
||||
case NotificationMessageTypeLedDisplayBacklightEnforceOn:
|
||||
furi_assert(app->display_led_lock < UINT8_MAX);
|
||||
furi_check(app->display_led_lock < UINT8_MAX);
|
||||
app->display_led_lock++;
|
||||
if(app->display_led_lock == 1) {
|
||||
notification_apply_internal_led_layer(
|
||||
@@ -237,13 +237,16 @@ static void notification_process_notification_message(
|
||||
}
|
||||
break;
|
||||
case NotificationMessageTypeLedDisplayBacklightEnforceAuto:
|
||||
furi_assert(app->display_led_lock > 0);
|
||||
if(app->display_led_lock > 0) {
|
||||
app->display_led_lock--;
|
||||
if(app->display_led_lock == 0) {
|
||||
notification_apply_internal_led_layer(
|
||||
&app->display,
|
||||
notification_message->data.led.value * display_brightness_setting);
|
||||
}
|
||||
} else {
|
||||
FURI_LOG_E(TAG, "Incorrect BacklightEnforce use");
|
||||
}
|
||||
break;
|
||||
case NotificationMessageTypeLedRed:
|
||||
// store and send on delay or after seq
|
||||
|
||||
@@ -869,7 +869,7 @@ bool storage_simply_remove_recursive(Storage* storage, const char* path) {
|
||||
|
||||
while(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) {
|
||||
if(file_info_is_dir(&fileinfo)) {
|
||||
furi_string_cat_printf(cur_dir, "/%s", name);
|
||||
furi_string_cat_printf(cur_dir, "/%s", name); //-V576
|
||||
go_deeper = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -28,14 +28,6 @@ static void storage_move_to_sd_remove_region() {
|
||||
if(storage_common_exists(storage, INT_PATH(".region_data"))) {
|
||||
storage_common_remove(storage, INT_PATH(".region_data"));
|
||||
}
|
||||
if(storage_common_exists(storage, EXT_PATH("apps/Misc/totp.conf"))) {
|
||||
storage_common_rename(
|
||||
storage, EXT_PATH("apps/Misc/totp.conf"), EXT_PATH("authenticator/totp.conf"));
|
||||
}
|
||||
if(storage_common_exists(storage, EXT_PATH("apps/Misc/barcodegen.save"))) {
|
||||
storage_common_remove(storage, EXT_PATH("apps/Misc/barcodegen.save"));
|
||||
storage_common_remove(storage, EXT_PATH("apps/Misc"));
|
||||
}
|
||||
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ static const struct {
|
||||
.stage = UpdateTaskStageRadioBusy,
|
||||
.percent_min = 11,
|
||||
.percent_max = 20,
|
||||
.descr = "C2 FUS swich failed",
|
||||
.descr = "C2 FUS switch failed",
|
||||
},
|
||||
{
|
||||
.stage = UpdateTaskStageRadioBusy,
|
||||
|
||||
BIN
assets/icons/Common/Hashmark_7x7.png
Normal file
BIN
assets/icons/Common/Hashmark_7x7.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 957 B |
BIN
assets/icons/Common/More_data_placeholder_5x7.png
Normal file
BIN
assets/icons/Common/More_data_placeholder_5x7.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 92 B |
BIN
assets/icons/Common/arrow_nano_down.png
Normal file
BIN
assets/icons/Common/arrow_nano_down.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
BIN
assets/icons/Common/arrow_nano_up.png
Normal file
BIN
assets/icons/Common/arrow_nano_up.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 949 B |
@@ -14,7 +14,7 @@ To build your application as a FAP, create a folder with your app's source code
|
||||
|
||||
- To build your application, run `./fbt fap_{APPID}`, where APPID is your application's ID in its manifest.
|
||||
- To build your app and upload it over USB to run on Flipper, use `./fbt launch APPSRC=applications_user/path/to/app`. This command is configured in the default [VS Code profile](../.vscode/ReadMe.md) as a "Launch App on Flipper" build action (Ctrl+Shift+B menu).
|
||||
- To build an app without uploading it to Flipper, use `./fbt build APPSRC=applications_user/path/to/app`. This command is also availabe in VSCode configuration as "Build App".
|
||||
- To build an app without uploading it to Flipper, use `./fbt build APPSRC=applications_user/path/to/app`. This command is also available in VSCode configuration as "Build App".
|
||||
- To build all FAPs, run `./fbt faps` or `./fbt fap_dist`.
|
||||
|
||||
## FAP assets
|
||||
|
||||
323
documentation/FAQ.md
Normal file
323
documentation/FAQ.md
Normal file
@@ -0,0 +1,323 @@
|
||||
# FAQ
|
||||
|
||||
## I bought Flipper Zero and I don't know what I can do with it, pls help
|
||||
- Start with reading official main page: https://flipperzero.one/
|
||||
- Then check out official docs where you can find answers to most questions: https://docs.flipper.net/
|
||||
|
||||
## How do I install Unleashed firmware?
|
||||
https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/HowToInstall.md
|
||||
### What version I should install? What do letters `e`, `r`, `c`... mean?
|
||||
Follow this link for details:<br>
|
||||
https://github.com/DarkFlippers/unleashed-firmware/blob/dev/CHANGELOG.md#recommended-update-option---web-updater
|
||||
|
||||
|
||||
**INSTALLED UNLEASHED AND NOW BACKLIGHT DOESNT WORK?** <br>
|
||||
You’ve installed a version made for custom RGB modded flippers. The version ending in `“r”` is specifically for “RGB” modded flippers. <br>
|
||||
Please do not use that version if your flipper isn’t modded!
|
||||
|
||||
## What apps (plugins) are included with Unleashed FW?
|
||||
See default pack and extra pack (for `e` build) list here:<br>
|
||||
https://github.com/xMasterX/all-the-plugins/tree/dev
|
||||
|
||||
## Where I can find differences between original (official) firmware and Unleashed firmware?
|
||||
Right here:<br>
|
||||
https://github.com/DarkFlippers/unleashed-firmware#whats-changed
|
||||
|
||||
## How to use SubGHz Remote app?
|
||||
1. Open app, press Back button, select New map file
|
||||
2. Configure signal files and their names for every button (also you can add only one signal and make other buttons empty - just don't select any files for them in config)
|
||||
3. Save new map file
|
||||
4. Open map file and select your previously created file
|
||||
5. Use buttons to send subghz signal files that you selected in map config at step 2
|
||||
|
||||
|
||||
## How to build (compile) firmware?
|
||||
Follow this link:<br>
|
||||
https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/HowToBuild.md#how-to-build-by-yourself
|
||||
|
||||
## I installed Unleashed firmware and now my mobile app doesn't connect to flipper ( OR I changed flipper device name and my mobile app now doesn't connect to flipper )
|
||||
1. Click Forget flipper in mobile app
|
||||
2. Open your phone settings - bluetooth, find flipper - if it present here - open its options and click forget device
|
||||
3. On flipper itself open Settings -> Bluetooth -> Forget all devices -> and confirm
|
||||
4. Make sure your flipper has bluetooth ON and open Mobile app and pair it to flipper
|
||||
5. Done
|
||||
|
||||
## My desktop (pin, favourites, etc..) (or other) settings was reset to default after update, what to do?
|
||||
Just configure that settings again, all is fine, and make sure you seen changelogs for the releases that came out after your previous version, when settings struct is changed, settings file are reset after update, this happens only when struct changes is required, so don't assume that settings will be reset in every release, this will happen only in specific ones
|
||||
|
||||
## Why is flipper not connecting to chrome?
|
||||
The most common cause of the flipper not connecting to google chrome is having qFlipper open while trying to connect your flipper. Or having second flipper lab page open at same time.<br>
|
||||
|
||||
You must close qFlipper (or other flipper lab web pages) before attempting to connect your flipper to chrome.
|
||||
|
||||
## Flipper doesn't work! How to restore firmware???
|
||||
|
||||
Follow this guide:<br>
|
||||
https://docs.flipper.net/basics/firmware-update/firmware-recovery
|
||||
|
||||
|
||||
## Useful links and files
|
||||
Flipper Awesome - place where you can find almost all links that you might need:<br>
|
||||
https://github.com/djsime1/awesome-flipperzero
|
||||
|
||||
Dict files for iButton Fuzzer and RFID Fuzzer:<br>
|
||||
https://t.me/flipperzero_unofficial_ru/37058 <br>
|
||||
https://t.me/flipperzero_unofficial_ru/37072
|
||||
|
||||
UL Releases in Telegram:<br>
|
||||
https://t.me/unleashed_fw <br>
|
||||
UL Dev Builds in Telegram:<br>
|
||||
https://t.me/kotnehleb <br>
|
||||
|
||||
Our Discord: <br>
|
||||
https://discord.unleashedflip.com
|
||||
|
||||
## How to change flipper name?
|
||||
All is simple:
|
||||
1. Open Settings -> Desktop -> Change Flipper Name
|
||||
2. Enter new name and click Save
|
||||
3. Exit from settings - Flipper will automatically reboot
|
||||
4. Done, you have custom name which will stay until you reset it to default or replace with new one
|
||||
|
||||
How to reset name to default:
|
||||
1. Open Settings -> Desktop -> Change Flipper Name
|
||||
2. Do not enter anything, just click Save
|
||||
3. Exit from settings - Flipper will automatically reboot
|
||||
4. Done, name is reset to original one.
|
||||
|
||||
## How do I copy files from Github to my Flipper Zero?
|
||||
Follow this detailed guide: <br>
|
||||
https://github.com/wrenchathome/flipperfiles/blob/main/_Guides/How2Flipper.pdf
|
||||
|
||||
|
||||
## Where can I find “This file” or “That file” for my flipper?
|
||||
|
||||
These 2 repos will cover most(99.9%) of your needs:<br>
|
||||
https://github.com/UberGuidoZ/Flipper/tree/main
|
||||
<br>
|
||||
https://github.com/UberGuidoZ/Flipper-IRDB/tree/main
|
||||
|
||||
## How can I support Unleashed firmware project?
|
||||
https://github.com/DarkFlippers/unleashed-firmware#please-support-development-of-the-project
|
||||
|
||||
## What are the dev builds? Where I can get latest build for dev branch?
|
||||
This is an automatic assembly of the latest commits from the repository that have not yet been released, the previous build is deleted when a new one is uploaded and old remains only as file in the telegram channel <br>
|
||||
Be aware that this is not release ready builds! They may have bugs and issues, if you are using dev build and found issue, report it! In github issues
|
||||
<br>
|
||||
|
||||
Dev builds is available in Discord, in channel - `unleashed-development` <br>
|
||||
Builds also can be found here - https://t.me/kotnehleb <br>
|
||||
And here - https://dev.unleashedflip.com/ <br>
|
||||
|
||||
## What is the update server?
|
||||
We have our own update server https://up.unleashedflip.com/directory.json <br>
|
||||
It is identical to the official one, it is impossible to change it in applications without rebuilding the application, it is hardcoded there <br>
|
||||
If you want to use it, you need to patch or build your own build of the application you are interested in <br>
|
||||
|
||||
Also you can use it with uFBT to build apps for UL SDK, uFBT will accept that link as one of args<br>
|
||||
|
||||
The server will remain active and will be automatically updated
|
||||
|
||||
## External Radio: How to connect CC1101 module
|
||||
https://github.com/quen0n/flipperzero-ext-cc1101
|
||||
|
||||
## How to add extra Sub-GHz frequencies
|
||||
https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzSettings.md
|
||||
|
||||
## How to use Flipper as new remote (Nice FlorS, BFT Mitto, Somfy Telis, Aprimatic, AN-Motors, etc..)
|
||||
https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md
|
||||
|
||||
## How Can I Unlock/Remove SubGHz restriction?
|
||||
If you are using Unleashed firmware - **all region locks are removed by default**!
|
||||
|
||||
Also there is a way to go outside of frequencies stated in CC1101 datasheet, but transmission on those frequencies may cause chip damage, make sure you know what you are doing! Do not edit this settings to bypass region lock since there is no region locks in unleashed, all chip supported frequencies will work without any extra steps.<br>
|
||||
But, if you know that you need to bypass subghz chip safety restriction you can unlock the safety restriction which will allow you to go outside the chips supported frequency. <br>
|
||||
This covers how to do it and information regarding the risks of damage to the flipper by doing so <br>
|
||||
https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/DangerousSettings.md
|
||||
|
||||
## Can I clone a car key fob for my own car to use flipper as a key?
|
||||
No, and trying to do so with Read RAW will lead to key desync or unpair with blacklist which means re-pair is very hard and requires service tools
|
||||
|
||||
## Will Unleashed FW support car keyfobs decoding, cloning, emulating?
|
||||
No, never
|
||||
|
||||
## Where can I find jamming files?
|
||||
Nowhere, this is illegal in almost every country in the world
|
||||
|
||||
## I saw something on tiktok and want to ask how to do it, I just wanna be like real hacker
|
||||
And you might be banned for that in our communities, since 99% of that content is fake, or showing illegal actions, and we don't like tiktok related questions
|
||||
|
||||
## I was banned in Unleashed Discord/Telegram/etc.. How to remove ban? I created github issue and it was removed too!
|
||||
Not possible, rules is rules, read them before sending messages in our communities
|
||||
|
||||
## How to clean .DS_Store and other dot files left from macOS
|
||||
`sudo dot_clean -mn /Volumes/Flipper\ SD` -> `Flipper\ SD` may be named differently for you, replace with your microSD card name
|
||||
|
||||
## How to sort files on flipper microSD on macOS/Linux
|
||||
`will make sorting faster, and will work for OFW`
|
||||
1. `brew install fatsort` -> Install fatsort using brew.sh (only on macOS)
|
||||
2. `diskutil list` -> Find your disk name for flipper microSD
|
||||
3. `diskutil unmount /Volumes/Flipper\ SD`
|
||||
4. `sudo fatsort -n /dev/disk4s1` -> Replace `disk4s1` with your microSD id found on step 2
|
||||
|
||||
|
||||
## Your Flipper feels slow and unresponsive?
|
||||
1. Make sure you using good microSD card from known brand, flipper works with microSD via SPI that means not any microSD will work good even if it works ok with other devices
|
||||
2. Go into **Settings -> System** and make sure that you have
|
||||
`Log Level = None`
|
||||
`Debug = OFF`
|
||||
`Heap Trace = None`
|
||||
If some of that settings is set to something different - change it to `None` / `OFF`
|
||||
3. Make sure your battery is charged, that can affect performance too
|
||||
|
||||
## Flipper crashed, stuck, frozen ?
|
||||
Reboot it by holding Left + Back buttons
|
||||
|
||||

|
||||
|
||||
|
||||
## How to reset forgotten Flipper pin code?
|
||||
|
||||
**Disconnect USB Cable if it was connected**
|
||||
1. Turn off the device - hold back button -> Turn Off
|
||||
**If you can't turn it off, try next step but hold buttons for 30-40 seconds)**
|
||||
2. Hold Up + Back for ~5 sec -> You will see reset screen -> Hold Right to reset (and down arrow to exit if you don't want to reset pin code)
|
||||
3. Done, internal memory (dolphin level, settings, pin code, is erased to default settings)
|
||||
|
||||
## What are the differences between x, y and z firmware?
|
||||
If you just got your flipper and not sure what will work better for you, start with original official firmware, if you think you need more features or want to remove subghz region locks then<br>
|
||||
Try installing Unleashed firmware, which is fork of official firmware with many new features and preinstalled plugins (check out `e` build)<br>
|
||||
In other case If you want to experiment more with UI and other things look for existing forks of Unleashed firmware<br>
|
||||
Or create your own fork with your own customisations<br>
|
||||
Also before reporting any found issue make sure you are in correct repo, if you are using not Unleashed but different fork or original firmware, do not report issue in Unleashed firmware repo or UL communities (telegram, discord, etc..)
|
||||
|
||||
|
||||
## Is there a correct way to capturing Infrared signals?
|
||||
|
||||
There is indeed especially with AC units, a new documentation has been released with some notes and steps on capturing infrared signals correctly along with some example data so you are able to understand the difference visually between the two.
|
||||
|
||||
https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/InfraredCaptures.md
|
||||
|
||||
|
||||
# NFC/RFID FAQ
|
||||
From our good friend `@Equip` and `@np0` <br>
|
||||
**------------------------------------------------------**
|
||||
|
||||
### MIFARE Ultralight
|
||||
|
||||
- Scan the card, hold the Flipper Zero up to the reader to get the password to unlock the rest of the sectors, then scan the card again.
|
||||
|
||||
### MIFARE DESFire/MIFARE Ultralight C
|
||||
|
||||
- The Flipper Zero has no available attacks for this card currently.
|
||||
|
||||
### Bank cards
|
||||
|
||||
- You cannot clone bank cards
|
||||
- The Flipper Zero cannot emulate bank cards
|
||||
- The Flipper Zero cannot pretend to be a point of sale machine
|
||||
|
||||
### Amiibos
|
||||
|
||||
- NTAG215. that's it. It's not going on a MIFARE Classic.
|
||||
- Currently, you cannot write Amiibos to new physical tags. yet.
|
||||
|
||||
### HID/iClass
|
||||
|
||||
- Picopass iClass can be read using the Picopass reader plugin
|
||||
- 26bit Picopass can be downgraded to H10301 RFID credentials (note, it is not guaranteed to work if the reader is not configured to read low frequency)
|
||||
- Readers will need to be configured and have an LF RFID antenna in order to be read. Certain iClass readers are HF only, and do not have the ability to have LF configured
|
||||
- **Emulation for Picopass** was added on July 26th, and the updated version can be found in latest releases of Unleashed firmware with apps preinstalled, or in official Apps Hub via Flipper Mobile app
|
||||
- Write support for personalization mode cards is doable with app
|
||||
- The Seader app and a SAM expansion board < https://www.redteamtools.com/nard-sam-expansion-board-for-flipper-zero-with-hid-seos-iclass-sam/ > will allow reading more secure HID cards, which may be helpful in downgrade attacks
|
||||
|
||||
### LF-RFID
|
||||
|
||||
If you're wanting to make clones of low frequency RFID chips you need to write to T5577's. "Blanks" do not exist. All of the chips the Flipper Zero can interact with are read-only and cannot be overwritten or purchased blank.
|
||||
T5577s are multiemulator chips that the Flipper Zero can program to be other tags
|
||||
|
||||
### Unknown Card/Fob
|
||||
|
||||
If you have exhausted all options of scanning via NFC/RFID/PICOPASS then take a photo of:
|
||||
|
||||
- The front and back of your credential
|
||||
- The reader you use with the credential
|
||||
- If your credential is a card, hold it up to a very bright light source e.g. a lightbulb and take a photo of the exposed antenna. This is useful for identification, post it for us to identify!
|
||||
|
||||
**------------------------------------------------------**
|
||||
|
||||
## How do I access the CLI/Logs?
|
||||
<blockquote>
|
||||
To access the Serial CLI, click one of the following based on your platform.
|
||||
<details>
|
||||
<summary>Desktop web browser*</summary>
|
||||
<em>*Chromium browsers only, such as: Google Chrome, Microsoft Edge, Opera/Opera GX, Brave, and Vivaldi.</em>
|
||||
<ul>
|
||||
<li>Connect your Flipper via USB.</li>
|
||||
<li>Ensure qFlipper and any other serial terminals are closed.</li>
|
||||
<li>Open <a href="https://my.flipp.dev/">my.flipp.dev</a> in one of the aforementioned browsers.</li>
|
||||
<li>Click <kbd>CONNECT</kbd> and select "USB Serial Device" from the list.</li>
|
||||
<li>Wait until you can see your device details on screen.</li>
|
||||
<li>Select the 💻 CLI item from the left sidebar.</li>
|
||||
<li><strong>Done!</strong></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Windows</summary>
|
||||
<ul>
|
||||
<li>Install <a href="https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html">PuTTY</a> if it isn't already.</li>
|
||||
<li>Connect your Flipper via USB.</li>
|
||||
<li>Open qFlipper and look for the COM port next to the Flipper's name. <em>(Should say COM followed by a number, like COM1)</em></li>
|
||||
<li>Take note of the COM port number.</li>
|
||||
<li><strong>CLOSE qFlipper</strong>, otherwise the next steps won't work.</li>
|
||||
<li>Open PuTTY and ensure you're on the Session screen.</li>
|
||||
<li>Select "Serial" under connection type.</li>
|
||||
<li>Set serial line to the COM port. <em>(Just COM followed by the number, like COM1)</em></li>
|
||||
<li>Set speed to <code>115200</code></li>
|
||||
<li><em>Optional: Save the session settings for easy connection later.</em></li>
|
||||
<li>Finally, click <kbd>Open</kbd> to enter the CLI.</li>
|
||||
<li><strong>Done!</strong></li>
|
||||
<li>If you get an "Access Denied" error, make sure qFlipper isn't running!</li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>MacOS/Linux</summary>
|
||||
<em>Note: I'm a filthy Windows user without any way to verify this procedure. Let me know if it's wrong!</em>
|
||||
<ul>
|
||||
<li>Install <a href="https://www.gnu.org/software/screen/">GNU Screen</a> if it isn't already.</li>
|
||||
<li>Connect your Flipper via USB.</li>
|
||||
<li>Open qFlipper and look for the device path next to the Flipper's name. <em>(Starts with /dev/tty)</em></li>
|
||||
<li><em>Alternatively: Run <code>ls /dev/tty.*</code> in a terminal.</em></li>
|
||||
<li>Take note of the full device path.</li>
|
||||
<li><strong>CLOSE qFlipper</strong>, otherwise the next steps won't work.</li>
|
||||
<li>Open a terminal.</li>
|
||||
<li>Run <code>screen PATH 115200</code>, replacing PATH with the device path from earlier.</li>
|
||||
<li><strong>Done!</strong></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Android</summary>
|
||||
<ul>
|
||||
<li>Install <a href="https://play.google.com/store/apps/details?id=de.kai_morich.serial_usb_terminal">Serial USB Terminal</a> if it isn't already.</li>
|
||||
<li>Open the app and go to the Connections screen in the hamburger menu <em>(3 bars icon)</em></li>
|
||||
<li>Connect your Flipper via USB.</li>
|
||||
<li>Click the refresh icon if it doesn't automatically show up.</li>
|
||||
<li>Allow Serial USB Terminal to access Flipper if prompted.</li>
|
||||
<li>If it doesn't automatically connect, click the connect icon in the upper right. <em>(2 plugs icon)</em></li>
|
||||
<li><strong>Done!</strong></li>
|
||||
<li><em>Note: To exit log mode, you'll have to disconnect and reconnect using the icon.</em></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>iPhone</summary>
|
||||
Unfortunately, iOS is incapable of accessing a serial terminal over USB; try one of the other methods.
|
||||
</details>
|
||||
On the Flipper, open the settings, go to System, and set Log Level to Debug. <em>(You can keep Debug set to off unless someone asks you to turn it on)</em>
|
||||
Once you have the CLI open, type <code>log</code> and press enter to start watching logs. Press <code>Ctrl-C</code> or <code>Cmd-C</code> to exit log mode.
|
||||
</blockquote>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
**CLI FAQ Source + Check out this FAQ for more info:**
|
||||
https://github.com/djsime1/awesome-flipperzero/blob/main/FAQ.md
|
||||
@@ -4,7 +4,7 @@ BadUsb app uses extended Duckyscript syntax. It is compatible with classic USB R
|
||||
|
||||
# Script file format
|
||||
|
||||
BadUsb app can execute only text scrips from `.txt` files, no compilation is required. Both `\n` and `\r\n` line endings are supported. Empty lines are allowed. You can use spaces or tabs for line indentation.
|
||||
BadUsb app can execute only text scripts from `.txt` files, no compilation is required. Both `\n` and `\r\n` line endings are supported. Empty lines are allowed. You can use spaces or tabs for line indentation.
|
||||
|
||||
# Command set
|
||||
|
||||
@@ -73,8 +73,8 @@ Can be combined with a special key command or a single character.
|
||||
|
||||
Up to 5 keys can be hold simultaneously.
|
||||
| Command | Parameters | Notes |
|
||||
| ------- | ------------------------------- | ----------------------------------------- |
|
||||
| HOLD | Special key or single character | Press and hold key untill RELEASE command |
|
||||
| ------- | ------------------------------- | ---------------------------------------- |
|
||||
| HOLD | Special key or single character | Press and hold key until RELEASE command |
|
||||
| RELEASE | Special key or single character | Release key |
|
||||
|
||||
## Wait for button press
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -22,7 +22,7 @@ DIST_SUFFIX = "local"
|
||||
COPRO_OB_DATA = "scripts/ob.data"
|
||||
|
||||
# Must match lib/stm32wb_copro version
|
||||
COPRO_CUBE_VERSION = "1.17.2"
|
||||
COPRO_CUBE_VERSION = "1.17.3"
|
||||
|
||||
COPRO_CUBE_DIR = "lib/stm32wb_copro"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,39.1,,
|
||||
Version,+,39.2,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/cli/cli.h,,
|
||||
Header,+,applications/services/cli/cli_vcp.h,,
|
||||
@@ -2006,7 +2006,7 @@ Function,+,storage_file_open,_Bool,"File*, const char*, FS_AccessMode, FS_OpenMo
|
||||
Function,+,storage_file_read,uint16_t,"File*, void*, uint16_t"
|
||||
Function,+,storage_file_seek,_Bool,"File*, uint32_t, _Bool"
|
||||
Function,+,storage_file_size,uint64_t,File*
|
||||
Function,-,storage_file_sync,_Bool,File*
|
||||
Function,+,storage_file_sync,_Bool,File*
|
||||
Function,+,storage_file_tell,uint64_t,File*
|
||||
Function,+,storage_file_truncate,_Bool,File*
|
||||
Function,+,storage_file_write,uint16_t,"File*, const void*, uint16_t"
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,39.1,,
|
||||
Version,+,39.2,,
|
||||
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/cli/cli.h,,
|
||||
@@ -2658,7 +2658,7 @@ Function,+,storage_file_open,_Bool,"File*, const char*, FS_AccessMode, FS_OpenMo
|
||||
Function,+,storage_file_read,uint16_t,"File*, void*, uint16_t"
|
||||
Function,+,storage_file_seek,_Bool,"File*, uint32_t, _Bool"
|
||||
Function,+,storage_file_size,uint64_t,File*
|
||||
Function,-,storage_file_sync,_Bool,File*
|
||||
Function,+,storage_file_sync,_Bool,File*
|
||||
Function,+,storage_file_tell,uint64_t,File*
|
||||
Function,+,storage_file_truncate,_Bool,File*
|
||||
Function,+,storage_file_write,uint16_t,"File*, const void*, uint16_t"
|
||||
|
||||
|
@@ -19,7 +19,7 @@ PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint32_t ble_app_nvm[BLE_NVM_SRAM_SI
|
||||
|
||||
_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.17.2)");
|
||||
"Ble stack config structure size mismatch (check new config options - last updated for v.1.17.3)");
|
||||
|
||||
typedef struct {
|
||||
FuriMutex* hci_mtx;
|
||||
|
||||
@@ -39,7 +39,7 @@ static bool dev_info_char_firmware_rev_callback(
|
||||
const uint8_t** data,
|
||||
uint16_t* data_len) {
|
||||
const DevInfoSvc* dev_info_svc = *(DevInfoSvc**)context;
|
||||
*data_len = sizeof(dev_info_svc->hardware_revision);
|
||||
*data_len = strlen(dev_info_svc->hardware_revision);
|
||||
if(data) {
|
||||
*data = (const uint8_t*)&dev_info_svc->hardware_revision;
|
||||
}
|
||||
@@ -155,17 +155,19 @@ void dev_info_svc_start() {
|
||||
void dev_info_svc_stop() {
|
||||
tBleStatus status;
|
||||
if(dev_info_svc) {
|
||||
furi_string_free(dev_info_svc->version_string);
|
||||
// Delete service characteristics
|
||||
for(size_t i = 0; i < DevInfoSvcGattCharacteristicCount; i++) {
|
||||
flipper_gatt_characteristic_delete(
|
||||
dev_info_svc->service_handle, &dev_info_svc->characteristics[i]);
|
||||
}
|
||||
|
||||
// Delete service
|
||||
status = aci_gatt_del_service(dev_info_svc->service_handle);
|
||||
if(status) {
|
||||
FURI_LOG_E(TAG, "Failed to delete device info service: %d", status);
|
||||
}
|
||||
|
||||
furi_string_free(dev_info_svc->version_string);
|
||||
free(dev_info_svc);
|
||||
dev_info_svc = NULL;
|
||||
}
|
||||
|
||||
@@ -118,7 +118,6 @@ void furi_hal_clock_init() {
|
||||
NVIC_EnableIRQ(SysTick_IRQn);
|
||||
|
||||
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_HSI);
|
||||
LL_RCC_SetSMPSPrescaler(LL_RCC_SMPS_DIV_1);
|
||||
LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE);
|
||||
@@ -133,7 +132,7 @@ void furi_hal_clock_switch_hse2hsi() {
|
||||
;
|
||||
|
||||
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
|
||||
furi_assert(LL_RCC_GetSMPSClockSource() == LL_RCC_SMPS_CLKSOURCE_HSI);
|
||||
furi_assert(LL_RCC_GetSMPSClockSelection() == LL_RCC_SMPS_CLKSOURCE_HSI);
|
||||
|
||||
while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI)
|
||||
;
|
||||
|
||||
@@ -65,6 +65,10 @@ void furi_hal_power_init() {
|
||||
LL_PWR_SetPowerMode(FURI_HAL_POWER_STOP_MODE);
|
||||
LL_C2_PWR_SetPowerMode(FURI_HAL_POWER_STOP_MODE);
|
||||
|
||||
#if FURI_HAL_POWER_STOP_MODE == LL_PWR_MODE_STOP0
|
||||
LL_RCC_HSI_EnableInStopMode(); // Ensure that MR is capable of work in STOP0
|
||||
#endif
|
||||
|
||||
furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
|
||||
// Find and init gauge
|
||||
if(bq27220_init(&furi_hal_i2c_handle_power)) {
|
||||
@@ -206,8 +210,11 @@ static inline void furi_hal_power_deep_sleep() {
|
||||
while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID))
|
||||
;
|
||||
|
||||
if(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE) {
|
||||
if(LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {
|
||||
furi_hal_clock_switch_hsi2hse();
|
||||
} else {
|
||||
// Ensure that we are already on HSE
|
||||
furi_check(LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_HSE);
|
||||
}
|
||||
|
||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0);
|
||||
|
||||
@@ -250,76 +250,134 @@ static void ccid_on_suspend(usbd_device* dev) {
|
||||
connected = false;
|
||||
}
|
||||
|
||||
struct ccid_bulk_message_header {
|
||||
typedef struct ccid_bulk_message_header {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
} __attribute__((packed));
|
||||
} __attribute__((packed)) ccid_bulk_message_header_t;
|
||||
|
||||
static struct rdr_to_pc_slot_status responseSlotStatus;
|
||||
static struct rdr_to_pc_data_block responseDataBlock;
|
||||
static struct rdr_to_pc_parameters_t0 responseParameters;
|
||||
uint8_t SendDataBlock[CCID_DATABLOCK_SIZE];
|
||||
uint8_t SendBuffer[sizeof(ccid_bulk_message_header_t) + CCID_DATABLOCK_SIZE];
|
||||
|
||||
uint8_t CALLBACK_CCID_GetSlotStatus(uint8_t slot, uint8_t* error) {
|
||||
if(slot == CCID_SLOT_INDEX) {
|
||||
*error = CCID_ERROR_NOERROR;
|
||||
if(smartcard_inserted) {
|
||||
return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_PRESENTANDACTIVE;
|
||||
} else {
|
||||
return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_NOICCPRESENT;
|
||||
}
|
||||
} else {
|
||||
*error = CCID_ERROR_SLOTNOTFOUND;
|
||||
return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
|
||||
}
|
||||
}
|
||||
//stores the data p
|
||||
uint8_t ReceiveBuffer[sizeof(ccid_bulk_message_header_t) + CCID_DATABLOCK_SIZE];
|
||||
|
||||
uint8_t
|
||||
CALLBACK_CCID_IccPowerOn(uint8_t slot, uint8_t* atrBuffer, uint32_t* atrlen, uint8_t* error) {
|
||||
if(slot == CCID_SLOT_INDEX) {
|
||||
*error = CCID_ERROR_NOERROR;
|
||||
if(smartcard_inserted) {
|
||||
if(callbacks[CCID_SLOT_INDEX] != NULL) {
|
||||
callbacks[CCID_SLOT_INDEX]->icc_power_on_callback(atrBuffer, atrlen, NULL);
|
||||
} else {
|
||||
return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||
CCID_ICCSTATUS_PRESENTANDINACTIVE;
|
||||
}
|
||||
|
||||
return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_PRESENTANDACTIVE;
|
||||
} else {
|
||||
return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_NOICCPRESENT;
|
||||
}
|
||||
} else {
|
||||
*error = CCID_ERROR_SLOTNOTFOUND;
|
||||
return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t CALLBACK_CCID_XfrBlock(
|
||||
void CALLBACK_CCID_GetSlotStatus(
|
||||
uint8_t slot,
|
||||
uint8_t* dataBlock,
|
||||
uint32_t* dataBlockLen,
|
||||
uint8_t* error) {
|
||||
if(slot == CCID_SLOT_INDEX) {
|
||||
*error = CCID_ERROR_NOERROR;
|
||||
uint8_t seq,
|
||||
struct rdr_to_pc_slot_status* responseSlotStatus) {
|
||||
responseSlotStatus->bMessageType = RDR_TO_PC_SLOTSTATUS;
|
||||
|
||||
responseSlotStatus->bSlot = slot;
|
||||
responseSlotStatus->bSeq = seq;
|
||||
responseSlotStatus->bClockStatus = 0;
|
||||
|
||||
responseSlotStatus->dwLength = 0;
|
||||
|
||||
if(responseSlotStatus->bSlot == CCID_SLOT_INDEX) {
|
||||
responseSlotStatus->bError = CCID_ERROR_NOERROR;
|
||||
if(smartcard_inserted) {
|
||||
if(callbacks[CCID_SLOT_INDEX] != NULL) {
|
||||
callbacks[CCID_SLOT_INDEX]->xfr_datablock_callback(dataBlock, dataBlockLen, NULL);
|
||||
responseSlotStatus->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||
CCID_ICCSTATUS_PRESENTANDACTIVE;
|
||||
} else {
|
||||
return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||
CCID_ICCSTATUS_PRESENTANDINACTIVE;
|
||||
responseSlotStatus->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||
CCID_ICCSTATUS_NOICCPRESENT;
|
||||
}
|
||||
} else {
|
||||
responseSlotStatus->bError = CCID_ERROR_SLOTNOTFOUND;
|
||||
responseSlotStatus->bStatus = CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
|
||||
}
|
||||
}
|
||||
|
||||
return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_PRESENTANDACTIVE;
|
||||
void CALLBACK_CCID_SetParametersT0(
|
||||
struct pc_to_rdr_set_parameters_t0* requestSetParametersT0,
|
||||
struct rdr_to_pc_parameters_t0* responseSetParametersT0) {
|
||||
furi_assert(requestSetParametersT0->bProtocolNum == 0x00); //T0
|
||||
responseSetParametersT0->bMessageType = RDR_TO_PC_PARAMETERS;
|
||||
responseSetParametersT0->bSlot = requestSetParametersT0->bSlot;
|
||||
responseSetParametersT0->bSeq = requestSetParametersT0->bSeq;
|
||||
|
||||
responseSetParametersT0->dwLength =
|
||||
sizeof(struct pc_to_rdr_set_parameters_t0) - sizeof(ccid_bulk_message_header_t);
|
||||
|
||||
if(responseSetParametersT0->bSlot == CCID_SLOT_INDEX) {
|
||||
responseSetParametersT0->bError = CCID_ERROR_NOERROR;
|
||||
if(smartcard_inserted) {
|
||||
responseSetParametersT0->bProtocolNum = requestSetParametersT0->bProtocolNum;
|
||||
responseSetParametersT0->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||
CCID_ICCSTATUS_PRESENTANDACTIVE;
|
||||
} else {
|
||||
return CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR | CCID_ICCSTATUS_NOICCPRESENT;
|
||||
responseSetParametersT0->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||
CCID_ICCSTATUS_NOICCPRESENT;
|
||||
}
|
||||
} else {
|
||||
*error = CCID_ERROR_SLOTNOTFOUND;
|
||||
return CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
|
||||
responseSetParametersT0->bError = CCID_ERROR_SLOTNOTFOUND;
|
||||
responseSetParametersT0->bStatus = CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
|
||||
}
|
||||
}
|
||||
|
||||
void CALLBACK_CCID_IccPowerOn(
|
||||
uint8_t slot,
|
||||
uint8_t seq,
|
||||
struct rdr_to_pc_data_block* responseDataBlock) {
|
||||
responseDataBlock->bMessageType = RDR_TO_PC_DATABLOCK;
|
||||
responseDataBlock->dwLength = 0;
|
||||
responseDataBlock->bSlot = slot;
|
||||
responseDataBlock->bSeq = seq;
|
||||
|
||||
if(responseDataBlock->bSlot == CCID_SLOT_INDEX) {
|
||||
responseDataBlock->bError = CCID_ERROR_NOERROR;
|
||||
if(smartcard_inserted) {
|
||||
if(callbacks[CCID_SLOT_INDEX] != NULL) {
|
||||
callbacks[CCID_SLOT_INDEX]->icc_power_on_callback(
|
||||
responseDataBlock->abData, &responseDataBlock->dwLength, NULL);
|
||||
responseDataBlock->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||
CCID_ICCSTATUS_PRESENTANDACTIVE;
|
||||
} else {
|
||||
responseDataBlock->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||
CCID_ICCSTATUS_PRESENTANDINACTIVE;
|
||||
}
|
||||
} else {
|
||||
responseDataBlock->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||
CCID_ICCSTATUS_NOICCPRESENT;
|
||||
}
|
||||
} else {
|
||||
responseDataBlock->bError = CCID_ERROR_SLOTNOTFOUND;
|
||||
responseDataBlock->bStatus = CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
|
||||
}
|
||||
}
|
||||
|
||||
void CALLBACK_CCID_XfrBlock(
|
||||
struct pc_to_rdr_xfr_block* receivedXfrBlock,
|
||||
struct rdr_to_pc_data_block* responseDataBlock) {
|
||||
responseDataBlock->bMessageType = RDR_TO_PC_DATABLOCK;
|
||||
responseDataBlock->bSlot = receivedXfrBlock->bSlot;
|
||||
responseDataBlock->bSeq = receivedXfrBlock->bSeq;
|
||||
responseDataBlock->bChainParameter = 0;
|
||||
|
||||
if(responseDataBlock->bSlot == CCID_SLOT_INDEX) {
|
||||
responseDataBlock->bError = CCID_ERROR_NOERROR;
|
||||
if(smartcard_inserted) {
|
||||
if(callbacks[CCID_SLOT_INDEX] != NULL) {
|
||||
callbacks[CCID_SLOT_INDEX]->xfr_datablock_callback(
|
||||
(const uint8_t*)receivedXfrBlock->abData,
|
||||
receivedXfrBlock->dwLength,
|
||||
responseDataBlock->abData,
|
||||
&responseDataBlock->dwLength,
|
||||
NULL);
|
||||
responseDataBlock->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||
CCID_ICCSTATUS_PRESENTANDACTIVE;
|
||||
} else {
|
||||
responseDataBlock->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||
CCID_ICCSTATUS_PRESENTANDINACTIVE;
|
||||
}
|
||||
} else {
|
||||
responseDataBlock->bStatus = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR |
|
||||
CCID_ICCSTATUS_NOICCPRESENT;
|
||||
}
|
||||
} else {
|
||||
responseDataBlock->bError = CCID_ERROR_SLOTNOTFOUND;
|
||||
responseDataBlock->bStatus = CCID_COMMANDSTATUS_FAILED | CCID_ICCSTATUS_NOICCPRESENT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,109 +405,89 @@ static void ccid_tx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) {
|
||||
if(event == usbd_evt_eprx) {
|
||||
if(connected == false) return;
|
||||
|
||||
struct ccid_bulk_message_header message;
|
||||
usbd_ep_read(usb_dev, ep, &message, sizeof(message));
|
||||
//read initial CCID message header
|
||||
|
||||
uint8_t Status;
|
||||
uint8_t Error = CCID_ERROR_NOERROR;
|
||||
int32_t bytes_read = usbd_ep_read(
|
||||
usb_dev, ep, &ReceiveBuffer, sizeof(ccid_bulk_message_header_t) + CCID_DATABLOCK_SIZE);
|
||||
//minimum request size is header size
|
||||
furi_assert((uint16_t)bytes_read >= sizeof(ccid_bulk_message_header_t));
|
||||
ccid_bulk_message_header_t* message = (ccid_bulk_message_header_t*)&ReceiveBuffer; //-V641
|
||||
|
||||
uint32_t dataBlockLen = 0;
|
||||
uint8_t* dataBlockBuffer = NULL;
|
||||
if(message->bMessageType == PC_TO_RDR_ICCPOWERON) {
|
||||
struct pc_to_rdr_icc_power_on* requestDataBlock =
|
||||
(struct pc_to_rdr_icc_power_on*)message; //-V641
|
||||
struct rdr_to_pc_data_block* responseDataBlock =
|
||||
(struct rdr_to_pc_data_block*)&SendBuffer;
|
||||
|
||||
if(message.bMessageType == PC_TO_RDR_GETSLOTSTATUS) {
|
||||
responseSlotStatus.bMessageType = RDR_TO_PC_SLOTSTATUS;
|
||||
responseSlotStatus.dwLength = 0;
|
||||
responseSlotStatus.bSlot = message.bSlot;
|
||||
responseSlotStatus.bSeq = message.bSeq;
|
||||
CALLBACK_CCID_IccPowerOn(
|
||||
requestDataBlock->bSlot, requestDataBlock->bSeq, responseDataBlock);
|
||||
|
||||
responseSlotStatus.bClockStatus = 0;
|
||||
|
||||
Status = CALLBACK_CCID_GetSlotStatus(message.bSlot, &Error);
|
||||
|
||||
responseSlotStatus.bStatus = Status;
|
||||
responseSlotStatus.bError = Error;
|
||||
|
||||
usbd_ep_write(
|
||||
usb_dev, CCID_IN_EPADDR, &responseSlotStatus, sizeof(responseSlotStatus));
|
||||
} else if(message.bMessageType == PC_TO_RDR_ICCPOWERON) {
|
||||
responseDataBlock.bMessageType = RDR_TO_PC_DATABLOCK;
|
||||
responseDataBlock.bSlot = message.bSlot;
|
||||
responseDataBlock.bSeq = message.bSeq;
|
||||
responseDataBlock.bChainParameter = 0;
|
||||
|
||||
dataBlockLen = 0;
|
||||
dataBlockBuffer = (uint8_t*)SendDataBlock;
|
||||
Status = CALLBACK_CCID_IccPowerOn(
|
||||
message.bSlot, (uint8_t*)dataBlockBuffer, &dataBlockLen, &Error);
|
||||
|
||||
furi_assert(dataBlockLen < CCID_DATABLOCK_SIZE);
|
||||
responseDataBlock.dwLength = dataBlockLen;
|
||||
|
||||
responseSlotStatus.bStatus = Status;
|
||||
responseSlotStatus.bError = Error;
|
||||
|
||||
memcpy(responseDataBlock.abData, SendDataBlock, dataBlockLen);
|
||||
usbd_ep_write(
|
||||
usb_dev,
|
||||
CCID_IN_EPADDR,
|
||||
&responseDataBlock,
|
||||
sizeof(struct rdr_to_pc_data_block) + (sizeof(uint8_t) * dataBlockLen));
|
||||
} else if(message.bMessageType == PC_TO_RDR_ICCPOWEROFF) {
|
||||
responseSlotStatus.bMessageType = RDR_TO_PC_SLOTSTATUS;
|
||||
responseSlotStatus.dwLength = 0;
|
||||
responseSlotStatus.bSlot = message.bSlot;
|
||||
responseSlotStatus.bSeq = message.bSeq;
|
||||
responseDataBlock,
|
||||
sizeof(struct rdr_to_pc_data_block) +
|
||||
(sizeof(uint8_t) * responseDataBlock->dwLength));
|
||||
} else if(message->bMessageType == PC_TO_RDR_ICCPOWEROFF) {
|
||||
struct pc_to_rdr_icc_power_off* requestIccPowerOff =
|
||||
(struct pc_to_rdr_icc_power_off*)message; //-V641
|
||||
struct rdr_to_pc_slot_status* responseSlotStatus =
|
||||
(struct rdr_to_pc_slot_status*)&SendBuffer; //-V641
|
||||
|
||||
responseSlotStatus.bClockStatus = 0;
|
||||
|
||||
uint8_t Status;
|
||||
uint8_t Error = CCID_ERROR_NOERROR;
|
||||
Status = CALLBACK_CCID_GetSlotStatus(message.bSlot, &Error);
|
||||
|
||||
responseSlotStatus.bStatus = Status;
|
||||
responseSlotStatus.bError = Error;
|
||||
CALLBACK_CCID_GetSlotStatus(
|
||||
requestIccPowerOff->bSlot, requestIccPowerOff->bSeq, responseSlotStatus);
|
||||
|
||||
usbd_ep_write(
|
||||
usb_dev, CCID_IN_EPADDR, &responseSlotStatus, sizeof(responseSlotStatus));
|
||||
} else if(message.bMessageType == PC_TO_RDR_SETPARAMETERS) {
|
||||
responseParameters.bMessageType = RDR_TO_PC_PARAMETERS;
|
||||
responseParameters.bSlot = message.bSlot;
|
||||
responseParameters.bSeq = message.bSeq;
|
||||
responseParameters.bProtocolNum = 0; //T0
|
||||
usb_dev, CCID_IN_EPADDR, responseSlotStatus, sizeof(struct rdr_to_pc_slot_status));
|
||||
} else if(message->bMessageType == PC_TO_RDR_GETSLOTSTATUS) {
|
||||
struct pc_to_rdr_get_slot_status* requestSlotStatus =
|
||||
(struct pc_to_rdr_get_slot_status*)message; //-V641
|
||||
struct rdr_to_pc_slot_status* responseSlotStatus =
|
||||
(struct rdr_to_pc_slot_status*)&SendBuffer; //-V641
|
||||
|
||||
uint8_t Status = CCID_COMMANDSTATUS_PROCESSEDWITHOUTERROR;
|
||||
uint8_t Error = CCID_ERROR_NOERROR;
|
||||
|
||||
responseParameters.bStatus = Status;
|
||||
responseParameters.bError = Error;
|
||||
|
||||
responseParameters.dwLength = sizeof(struct rdr_to_pc_parameters_t0);
|
||||
CALLBACK_CCID_GetSlotStatus(
|
||||
requestSlotStatus->bSlot, requestSlotStatus->bSeq, responseSlotStatus);
|
||||
|
||||
usbd_ep_write(
|
||||
usb_dev, CCID_IN_EPADDR, &responseParameters, sizeof(responseParameters));
|
||||
} else if(message.bMessageType == PC_TO_RDR_XFRBLOCK) {
|
||||
responseDataBlock.bMessageType = RDR_TO_PC_DATABLOCK;
|
||||
responseDataBlock.bSlot = message.bSlot;
|
||||
responseDataBlock.bSeq = message.bSeq;
|
||||
responseDataBlock.bChainParameter = 0;
|
||||
usb_dev, CCID_IN_EPADDR, responseSlotStatus, sizeof(struct rdr_to_pc_slot_status));
|
||||
} else if(message->bMessageType == PC_TO_RDR_XFRBLOCK) {
|
||||
struct pc_to_rdr_xfr_block* receivedXfrBlock = (struct pc_to_rdr_xfr_block*)message;
|
||||
struct rdr_to_pc_data_block* responseDataBlock =
|
||||
(struct rdr_to_pc_data_block*)&SendBuffer;
|
||||
|
||||
dataBlockLen = 0;
|
||||
dataBlockBuffer = (uint8_t*)SendDataBlock;
|
||||
Status = CALLBACK_CCID_XfrBlock(
|
||||
message.bSlot, (uint8_t*)dataBlockBuffer, &dataBlockLen, &Error);
|
||||
furi_assert(receivedXfrBlock->dwLength <= CCID_DATABLOCK_SIZE);
|
||||
furi_assert(
|
||||
(uint16_t)bytes_read >=
|
||||
sizeof(ccid_bulk_message_header_t) + receivedXfrBlock->dwLength);
|
||||
|
||||
furi_assert(dataBlockLen < CCID_DATABLOCK_SIZE);
|
||||
responseDataBlock.dwLength = dataBlockLen;
|
||||
CALLBACK_CCID_XfrBlock(receivedXfrBlock, responseDataBlock);
|
||||
|
||||
responseSlotStatus.bStatus = Status;
|
||||
responseSlotStatus.bError = Error;
|
||||
furi_assert(responseDataBlock->dwLength <= CCID_DATABLOCK_SIZE);
|
||||
|
||||
memcpy(responseDataBlock.abData, SendDataBlock, dataBlockLen);
|
||||
usbd_ep_write(
|
||||
usb_dev,
|
||||
CCID_IN_EPADDR,
|
||||
&responseDataBlock,
|
||||
sizeof(struct rdr_to_pc_data_block) + (sizeof(uint8_t) * dataBlockLen));
|
||||
responseDataBlock,
|
||||
sizeof(struct rdr_to_pc_data_block) +
|
||||
(sizeof(uint8_t) * responseDataBlock->dwLength));
|
||||
} else if(message->bMessageType == PC_TO_RDR_SETPARAMETERS) {
|
||||
struct pc_to_rdr_set_parameters_t0* requestSetParametersT0 =
|
||||
(struct pc_to_rdr_set_parameters_t0*)message; //-V641
|
||||
struct rdr_to_pc_parameters_t0* responseSetParametersT0 =
|
||||
(struct rdr_to_pc_parameters_t0*)&SendBuffer; //-V641
|
||||
|
||||
furi_assert(requestSetParametersT0->dwLength <= CCID_DATABLOCK_SIZE);
|
||||
furi_assert(
|
||||
(uint16_t)bytes_read >=
|
||||
sizeof(ccid_bulk_message_header_t) + requestSetParametersT0->dwLength);
|
||||
|
||||
CALLBACK_CCID_SetParametersT0(requestSetParametersT0, responseSetParametersT0);
|
||||
|
||||
usbd_ep_write(
|
||||
usb_dev,
|
||||
CCID_IN_EPADDR,
|
||||
responseSetParametersT0,
|
||||
sizeof(struct rdr_to_pc_parameters_t0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ extern uint32_t SystemCoreClock;
|
||||
|
||||
/* Heap size determined automatically by linker */
|
||||
// #define configTOTAL_HEAP_SIZE ((size_t)0)
|
||||
#define configMAX_TASK_NAME_LEN (16)
|
||||
#define configMAX_TASK_NAME_LEN (32)
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
#define configUSE_TRACE_FACILITY 1
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
|
||||
@@ -70,7 +70,8 @@ static bool flipper_update_load_stage(const FuriString* work_dir, UpdateManifest
|
||||
|
||||
if((f_stat(furi_string_get_cstr(loader_img_path), &stat) != FR_OK) ||
|
||||
(f_open(&file, furi_string_get_cstr(loader_img_path), FA_OPEN_EXISTING | FA_READ) !=
|
||||
FR_OK)) {
|
||||
FR_OK) ||
|
||||
(stat.fsize == 0)) {
|
||||
furi_string_free(loader_img_path);
|
||||
return false;
|
||||
}
|
||||
@@ -83,7 +84,7 @@ static bool flipper_update_load_stage(const FuriString* work_dir, UpdateManifest
|
||||
uint32_t crc = 0;
|
||||
do {
|
||||
uint16_t size_read = 0;
|
||||
if(f_read(&file, img + bytes_read, MAX_READ, &size_read) != FR_OK) {
|
||||
if(f_read(&file, img + bytes_read, MAX_READ, &size_read) != FR_OK) { //-V769
|
||||
break;
|
||||
}
|
||||
crc = crc32_calc_buffer(crc, img + bytes_read, size_read);
|
||||
|
||||
@@ -18,7 +18,12 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
void (*icc_power_on_callback)(uint8_t* dataBlock, uint32_t* dataBlockLen, void* context);
|
||||
void (*xfr_datablock_callback)(uint8_t* dataBlock, uint32_t* dataBlockLen, void* context);
|
||||
void (*xfr_datablock_callback)(
|
||||
const uint8_t* dataBlock,
|
||||
uint32_t dataBlockLen,
|
||||
uint8_t* responseDataBlock,
|
||||
uint32_t* responseDataBlockLen,
|
||||
void* context);
|
||||
} CcidCallbacks;
|
||||
|
||||
void furi_hal_ccid_set_callbacks(CcidCallbacks* cb);
|
||||
|
||||
@@ -153,18 +153,18 @@ FURI_NORETURN void __furi_crash() {
|
||||
__furi_print_heap_info();
|
||||
__furi_print_bt_stack_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;
|
||||
#ifdef FURI_NDEBUG
|
||||
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
|
||||
RESTORE_REGISTERS_AND_HALT_MCU(debug);
|
||||
#ifdef FURI_NDEBUG
|
||||
} else {
|
||||
uint32_t ptr = (uint32_t)__furi_check_message;
|
||||
if(ptr < FLASH_BASE || ptr > (FLASH_BASE + FLASH_SIZE)) {
|
||||
|
||||
@@ -115,8 +115,9 @@ static size_t xBlockAllocatedBit = 0;
|
||||
#include <m-dict.h>
|
||||
|
||||
/* Allocation tracking types */
|
||||
DICT_DEF2(MemmgrHeapAllocDict, uint32_t, uint32_t)
|
||||
DICT_DEF2(
|
||||
DICT_DEF2(MemmgrHeapAllocDict, uint32_t, uint32_t) //-V1048
|
||||
|
||||
DICT_DEF2( //-V1048
|
||||
MemmgrHeapThreadDict,
|
||||
uint32_t,
|
||||
M_DEFAULT_OPLIST,
|
||||
|
||||
@@ -199,7 +199,7 @@ The RFAL encapsulates the different RF ICs (ST25R3911, ST25R3916, ST25R95 and fu
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">Extended support for specific features of ST's ISO15693 Tags. New ST25Dx module added<span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">Interrupt handling changed and further protection added <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">RFAL feature switches have been modified and features are now disabled if omitted <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">ST25R3916 AAT (Automatic Antenna Tunning) module added <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">ST25R3916 AAT (Automatic Antenna Tuning) module added <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">RFAL NFC Higher layer added <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">Several driver improvements <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
</ul>
|
||||
@@ -286,12 +286,12 @@ The RFAL encapsulates the different RF ICs (ST25R3911, ST25R3916, ST25R95 and fu
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">Introduced a new IRQ status handling to read the registers only once <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">Several changes for supporting Linux platform <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">SPI Select/Deselect moved to platform.h <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">Aditional protection of the IRQ status reading, new macros available: platformProtectST25R391xIrqStatus / platformUnprotectST25R391xIrqStatus<span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">Additional protection of the IRQ status reading, new macros available: platformProtectST25R391xIrqStatus / platformUnprotectST25R391xIrqStatus<span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">Renamed the IRQ Enable/Disable macros to platformProtectST25R391xComm / platformUnprotectST25R391xComm <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">Renamed SPI pins from chip specific to ST25R391X <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">Introduced a new option ST25R391X_COM_SINGLETXRX which executes SPI in one single exchange (additional buffer required) <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">Updated and added errata handlings to latest ST25R3911 Errata version <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">Fixed inconsitency on Analog settings for NFC-V <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">Fixed inconsistency on Analog settings for NFC-V <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">Fixed issue on NFC-V 1of256 decoding <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">Changed the default NFC-A FDT Listen to be more strict <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">Added Wake-Up mode support <span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
@@ -318,7 +318,7 @@ The RFAL encapsulates the different RF ICs (ST25R3911, ST25R3916, ST25R95 and fu
|
||||
<p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"><b style=""><u><span style="font-size: 10pt; font-family: Verdana; color: black;">Provided with ST25R3911B Disco v1.1.12<o:p></o:p></span></u></b></p>
|
||||
<p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"><b style=""><u><span style="font-size: 10pt; font-family: Verdana; color: black;">Main Changes<o:p></o:p></span></u></b></p>
|
||||
<ul style="margin-top: 0cm;" type="square">
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">EMD supression enabled for ST25R3911B<span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
<li class="MsoNormal"><span style="font-size: 10pt; font-family: Verdana;">EMD suppression enabled for ST25R3911B<span style="font-weight: bold; font-style: italic;"></span></span></li>
|
||||
</ul>
|
||||
<span style="font-size: 10pt; font-family: Verdana;"></span>
|
||||
<br>
|
||||
|
||||
@@ -237,7 +237,7 @@ the variables length has been consequently set to a dedicated value (cf 'namelen
|
||||
<ul>STM32</ul><br>
|
||||
<li>Parent repository:</li>
|
||||
<ul>ST25R3916_nucleo</ul><br>
|
||||
<li>RFAL informations:</li>
|
||||
<li>RFAL information:</li>
|
||||
<ul>Path: .../ST25R3916_nucleo/rfal</ul>
|
||||
<ul>Version: v2.1.2</ul>
|
||||
<br> <li>Project repositories SHA1:</li>
|
||||
@@ -8087,7 +8087,7 @@ This section targets to provide an overview of Deviation Records.
|
||||
</tr>
|
||||
</table></center>
|
||||
</td>
|
||||
<td width=45%>MISRA 10.5 - Layout of enum rfalIsoDepFSxI is guaranteed whithin 4bit range</td>
|
||||
<td width=45%>MISRA 10.5 - Layout of enum rfalIsoDepFSxI is guaranteed within 4bit range</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width=4%>2526-2526</td>
|
||||
|
||||
@@ -337,7 +337,7 @@ ReturnCode rfalAnalogConfigListWriteRaw(const uint8_t* configTbl, uint16_t confi
|
||||
*
|
||||
* \param[in] more: 0x00 indicates it is last Configuration ID settings;
|
||||
* 0x01 indicates more Configuration ID setting(s) are coming.
|
||||
* \param[in] *config: reference to the configuration list of current Configuraiton ID.
|
||||
* \param[in] *config: reference to the configuration list of current Configuration ID.
|
||||
*
|
||||
* \return ERR_PARAM : if Configuration ID or parameter is invalid
|
||||
* \return ERR_NOMEM : if LUT is full
|
||||
|
||||
@@ -81,7 +81,7 @@ typedef struct {
|
||||
uint8_t dec; /*!< Threshold for decrementing the output power */
|
||||
} rfalDpoEntry;
|
||||
|
||||
/*! Function pointer to methode doing the reference measurement */
|
||||
/*! Function pointer to method doing the reference measurement */
|
||||
typedef ReturnCode (*rfalDpoMeasureFunc)(uint8_t*);
|
||||
|
||||
/*
|
||||
@@ -103,7 +103,7 @@ void rfalDpoInitialize(void);
|
||||
|
||||
/*!
|
||||
*****************************************************************************
|
||||
* \brief Set the measurement methode
|
||||
* \brief Set the measurement method
|
||||
*
|
||||
* This function sets the measurement method used for reference measurement.
|
||||
* Based on the measurement the power will then be adjusted
|
||||
|
||||
@@ -186,8 +186,8 @@ extern ReturnCode iso15693VCDCode(
|
||||
* \param[in] ignoreBits : number of bits in the beginning where collisions will be ignored
|
||||
* \param[in] picopassMode : if set to true, the decoding will be according to Picopass
|
||||
*
|
||||
* \return ERR_COLLISION : collision occured, data uncorrect
|
||||
* \return ERR_CRC : CRC error, data uncorrect
|
||||
* \return ERR_COLLISION : collision occurred, data incorrect
|
||||
* \return ERR_CRC : CRC error, data incorrect
|
||||
* \return ERR_TIMEOUT : timeout waiting for data.
|
||||
* \return ERR_NONE : No error.
|
||||
*
|
||||
|
||||
@@ -616,7 +616,7 @@ bool rfalIsoDepIsAttrib(const uint8_t* buf, uint8_t bufLen);
|
||||
* \param[in] atsParam : reference to ATS parameters
|
||||
* \param[in] attribResParam : reference to ATTRIB_RES parameters
|
||||
* \param[in] buf : reference to buffer containing RATS or ATTRIB
|
||||
* \param[in] bufLen : length in bytes of the given bufffer
|
||||
* \param[in] bufLen : length in bytes of the given buffer
|
||||
* \param[in] actParam : reference to incoming reception information will be placed
|
||||
*
|
||||
*
|
||||
@@ -940,7 +940,7 @@ ReturnCode rfalIsoDepPollBHandleActivation(
|
||||
*****************************************************************************
|
||||
* \brief ISO-DEP Poller Handle S(Parameters)
|
||||
*
|
||||
* This checks if PICC supports S(PARAMETERS), retieves PICC's
|
||||
* This checks if PICC supports S(PARAMETERS), retrieves PICC's
|
||||
* capabilities and sets the Bit Rate at the highest supported by both
|
||||
* devices
|
||||
*
|
||||
|
||||
@@ -189,7 +189,7 @@ typedef struct {
|
||||
|
||||
/*! Discovery parameters */
|
||||
typedef struct {
|
||||
rfalComplianceMode compMode; /*!< Compliancy mode to be used */
|
||||
rfalComplianceMode compMode; /*!< Compliance mode to be used */
|
||||
uint16_t techs2Find; /*!< Technologies to search for */
|
||||
uint16_t totalDuration; /*!< Duration of a whole Poll + Listen cycle */
|
||||
uint8_t devLimit; /*!< Max number of devices */
|
||||
@@ -211,7 +211,7 @@ typedef struct {
|
||||
bool wakeupConfigDefault; /*!< Wake-Up mode default configuration */
|
||||
rfalWakeUpConfig wakeupConfig; /*!< Wake-Up mode configuration */
|
||||
|
||||
bool activate_after_sak; // Set device to Active mode after SAK responce
|
||||
bool activate_after_sak; // Set device to Active mode after SAK response
|
||||
} rfalNfcDiscoverParam;
|
||||
|
||||
/*! Buffer union, only one interface is used at a time */
|
||||
@@ -323,7 +323,7 @@ ReturnCode rfalNfcGetActiveDevice(rfalNfcDevice** dev);
|
||||
*
|
||||
* It selects the device to be activated.
|
||||
* It shall be called when more than one device has been identified to
|
||||
* indiacte which device shall be actived
|
||||
* indiacte which device shall be active
|
||||
*
|
||||
* \param[in] devIdx : device index to be activated
|
||||
*
|
||||
|
||||
@@ -282,7 +282,7 @@ enum {
|
||||
RFAL_NFCDEP_Bx_64_6780 = 0x08 /*!< Peer also supports 6780 */
|
||||
};
|
||||
|
||||
/*! Enumeration of NFC-DEP bit rate Dividor in PSL Digital 1.0 Table 100 */
|
||||
/*! Enumeration of NFC-DEP bit rate Divider in PSL Digital 1.0 Table 100 */
|
||||
enum {
|
||||
RFAL_NFCDEP_Dx_01_106 = RFAL_BR_106, /*!< Divisor D = 1 : bit rate = 106 */
|
||||
RFAL_NFCDEP_Dx_02_212 = RFAL_BR_212, /*!< Divisor D = 2 : bit rate = 212 */
|
||||
@@ -655,7 +655,7 @@ ReturnCode rfalNfcDepInitiatorHandleActivation(
|
||||
*
|
||||
* \param[in] buf : buffer holding Initiator's received request
|
||||
* \param[in] bufLen : size of the msg contained on the buf in Bytes
|
||||
* \param[out] nfcid3 : pointer to where the NFCID3 may be outputed,
|
||||
* \param[out] nfcid3 : pointer to where the NFCID3 may be outputted,
|
||||
* nfcid3 has NFCF_SENSF_NFCID3_LEN as length
|
||||
* Pass NULL if output parameter not desired
|
||||
*
|
||||
|
||||
@@ -332,7 +332,7 @@ ReturnCode
|
||||
* This method executes anti collision loop and select the device with higher NFCID1
|
||||
*
|
||||
* When devLimit = 0 it is configured to perform collision detection only. Once a collision
|
||||
* is detected the collision resolution is aborted immidiatly. If only one device is found
|
||||
* is detected the collision resolution is aborted immediately. If only one device is found
|
||||
* with no collisions, it will properly resolved.
|
||||
*
|
||||
* \param[in] devLimit : device limit value (CON_DEVICES_LIMIT)
|
||||
@@ -374,7 +374,7 @@ ReturnCode rfalNfcaPollerSingleCollisionResolution(
|
||||
*
|
||||
*
|
||||
* When devLimit = 0 it is configured to perform collision detection only. Once a collision
|
||||
* is detected the collision resolution is aborted immidiatly. If only one device is found
|
||||
* is detected the collision resolution is aborted immediately. If only one device is found
|
||||
* with no collisions, it will properly resolved.
|
||||
*
|
||||
*
|
||||
@@ -436,7 +436,7 @@ ReturnCode rfalNfcaPollerSleepFullCollisionResolution(
|
||||
*
|
||||
*
|
||||
* When devLimit = 0 it is configured to perform collision detection only. Once a collision
|
||||
* is detected the collision resolution is aborted immidiatly. If only one device is found
|
||||
* is detected the collision resolution is aborted immediately. If only one device is found
|
||||
* with no collisions, it will properly resolved.
|
||||
*
|
||||
*
|
||||
|
||||
@@ -81,8 +81,8 @@
|
||||
#define RFAL_NFCF_SENSF_PARAMS_TSN_POS 3U /*!< Time Slot Number position in the SENSF_REQ */
|
||||
#define RFAL_NFCF_POLL_MAXCARDS 16U /*!< Max number slots/cards 16 */
|
||||
|
||||
#define RFAL_NFCF_CMD_POS 0U /*!< Command/Responce code length */
|
||||
#define RFAL_NFCF_CMD_LEN 1U /*!< Command/Responce code length */
|
||||
#define RFAL_NFCF_CMD_POS 0U /*!< Command/Response code length */
|
||||
#define RFAL_NFCF_CMD_LEN 1U /*!< Command/Response code length */
|
||||
#define RFAL_NFCF_LENGTH_LEN 1U /*!< LEN field length */
|
||||
#define RFAL_NFCF_HEADER_LEN (RFAL_NFCF_LENGTH_LEN + RFAL_NFCF_CMD_LEN) /*!< Header length*/
|
||||
|
||||
@@ -315,8 +315,8 @@ ReturnCode rfalNfcfPollerCollisionResolution(
|
||||
*****************************************************************************
|
||||
* \brief NFC-F Poller Check/Read
|
||||
*
|
||||
* It computes a Check / Read command accoring to T3T 1.0 and JIS X6319-4 and
|
||||
* sends it to PICC. If sucessfully, the rxBuf will contain the the number of
|
||||
* It computes a Check / Read command according to T3T 1.0 and JIS X6319-4 and
|
||||
* sends it to PICC. If successfully, the rxBuf will contain the the number of
|
||||
* blocks in the first byte followed by the blocks data.
|
||||
*
|
||||
* \param[in] nfcid2 : nfcid2 of the device
|
||||
@@ -344,7 +344,7 @@ ReturnCode rfalNfcfPollerCheck(
|
||||
*****************************************************************************
|
||||
* \brief NFC-F Poller Update/Write
|
||||
*
|
||||
* It computes a Update / Write command accoring to T3T 1.0 and JIS X6319-4 and
|
||||
* It computes a Update / Write command according to T3T 1.0 and JIS X6319-4 and
|
||||
* sends it to PICC.
|
||||
*
|
||||
* \param[in] nfcid2 : nfcid2 of the device
|
||||
@@ -381,7 +381,7 @@ ReturnCode rfalNfcfPollerUpdate(
|
||||
*
|
||||
* \param[in] buf : buffer holding Initiator's received command
|
||||
* \param[in] bufLen : length of received command in bytes
|
||||
* \param[out] nfcid2 : pointer to where the NFCID2 may be outputed,
|
||||
* \param[out] nfcid2 : pointer to where the NFCID2 may be outputted,
|
||||
* nfcid2 has NFCF_SENSF_NFCID2_LEN as length
|
||||
* Pass NULL if output parameter not desired
|
||||
*
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
#define RFAL_T4T_ISO7816_P1_SELECT_BY_FILEID \
|
||||
0x00U /*!< P1 value for Select by file identifier */
|
||||
#define RFAL_T4T_ISO7816_P2_SELECT_FIRST_OR_ONLY_OCCURENCE \
|
||||
0x00U /*!< b2b1 P2 value for First or only occurence */
|
||||
0x00U /*!< b2b1 P2 value for First or only occurrence */
|
||||
#define RFAL_T4T_ISO7816_P2_SELECT_RETURN_FCI_TEMPLATE \
|
||||
0x00U /*!< b4b3 P2 value for Return FCI template */
|
||||
#define RFAL_T4T_ISO7816_P2_SELECT_NO_RESPONSE_DATA \
|
||||
@@ -177,7 +177,7 @@ ReturnCode rfalT4TPollerComposeCAPDU(const rfalT4tCApduParam* apduParam);
|
||||
* \brief T4T Parse R-APDU
|
||||
*
|
||||
* This method parses a R-APDU according to NFC Forum T4T and ISO7816-4.
|
||||
* It will extract the data length and check if the Satus word is expected.
|
||||
* It will extract the data length and check if the Status word is expected.
|
||||
*
|
||||
* \param[in,out] apduParam : APDU parameters
|
||||
* apduParam.rApduBodyLen will contain the data length
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
*
|
||||
* \author bkam
|
||||
*
|
||||
* \brief Funcitons to manage and set analog settings.
|
||||
* \brief Functions to manage and set analog settings.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -434,7 +434,7 @@
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*! Internal structure to be used in handling of S(PARAMETRS) only */
|
||||
/*! Internal structure to be used in handling of S(PARAMETERS) only */
|
||||
typedef struct {
|
||||
uint8_t pcb; /*!< PCB byte */
|
||||
rfalIsoDepSParameter sParam; /*!< S(PARAMETERS) */
|
||||
@@ -1053,7 +1053,7 @@ static ReturnCode isoDepDataExchangePCD(uint16_t* outActRxLen, bool* outIsChaini
|
||||
}
|
||||
return ERR_TIMEOUT; /* NFC Forum mandates timeout or transmission error depending on previous errors */
|
||||
}
|
||||
} else /* Unexcpected R-Block */
|
||||
} else /* Unexpected R-Block */
|
||||
{
|
||||
return ERR_PROTO;
|
||||
}
|
||||
@@ -1899,7 +1899,7 @@ static ReturnCode isoDepDataExchangePICC(void) {
|
||||
return ERR_BUSY;
|
||||
}
|
||||
|
||||
/* Rule E - R(ACK) with not current bn -> toogle bn */
|
||||
/* Rule E - R(ACK) with not current bn -> toggle bn */
|
||||
isoDep_ToggleBN(gIsoDep.blockNumber);
|
||||
|
||||
/* This block has been transmitted and acknowledged, perform WTX until next data is provided */
|
||||
@@ -2336,7 +2336,7 @@ ReturnCode rfalIsoDepPollAGetActivationStatus(void) {
|
||||
rfalSetGT(rfalGetFDTPoll());
|
||||
rfalFieldOnAndStartGT();
|
||||
|
||||
/* Send RATS retransmission */ /* PRQA S 4342 1 # MISRA 10.5 - Layout of enum rfalIsoDepFSxI is guaranteed whithin 4bit range */
|
||||
/* Send RATS retransmission */ /* PRQA S 4342 1 # MISRA 10.5 - Layout of enum rfalIsoDepFSxI is guaranteed within 4bit range */
|
||||
EXIT_ON_ERR(
|
||||
ret,
|
||||
rfalIsoDepStartRATS(
|
||||
|
||||
@@ -90,14 +90,14 @@ typedef struct {
|
||||
rfalNfcDevice* activeDev; /* Active device pointer */
|
||||
rfalNfcDiscoverParam disc; /* Discovery parameters */
|
||||
rfalNfcDevice devList[RFAL_NFC_MAX_DEVICES]; /*!< Location of device list */
|
||||
uint8_t devCnt; /* Decices found counter */
|
||||
uint8_t devCnt; /* Devices found counter */
|
||||
uint32_t discTmr; /* Discovery Total duration timer */
|
||||
ReturnCode dataExErr; /* Last Data Exchange error */
|
||||
bool discRestart; /* Restart discover after deactivation flag */
|
||||
bool isRxChaining; /* Flag indicating Other device is chaining */
|
||||
uint32_t lmMask; /* Listen Mode mask */
|
||||
bool isTechInit; /* Flag indicating technology has been set */
|
||||
bool isOperOngoing; /* Flag indicating opration is ongoing */
|
||||
bool isOperOngoing; /* Flag indicating operation is ongoing */
|
||||
|
||||
rfalNfcBuffer txBuf; /* Tx buffer for Data Exchange */
|
||||
rfalNfcBuffer rxBuf; /* Rx buffer for Data Exchange */
|
||||
@@ -674,7 +674,7 @@ ReturnCode rfalNfcDataExchangeStart(
|
||||
break;
|
||||
}
|
||||
|
||||
/* If a transceive has succesfully started flag Data Exchange as ongoing */
|
||||
/* If a transceive has successfuly started flag Data Exchange as ongoing */
|
||||
if(err == ERR_NONE) {
|
||||
gNfcDev.dataExErr = ERR_BUSY;
|
||||
gNfcDev.state = RFAL_NFC_STATE_DATAEXCHANGE;
|
||||
@@ -814,7 +814,7 @@ ReturnCode rfalNfcDataExchangeCustomStart(
|
||||
break;
|
||||
}
|
||||
|
||||
/* If a transceive has succesfully started flag Data Exchange as ongoing */
|
||||
/* If a transceive has successfuly started flag Data Exchange as ongoing */
|
||||
if(err == ERR_NONE) {
|
||||
gNfcDev.dataExErr = ERR_BUSY;
|
||||
gNfcDev.state = RFAL_NFC_STATE_DATAEXCHANGE;
|
||||
@@ -897,7 +897,7 @@ ReturnCode rfalNfcDataExchangeGetStatus(void) {
|
||||
sizeof(gNfcDev.rxBuf.rfBuf),
|
||||
&gNfcDev.rxLen));
|
||||
|
||||
/* If set Sleep was succesfull keep restore the Sleep request signal */
|
||||
/* If set Sleep was successful keep restore the Sleep request signal */
|
||||
gNfcDev.dataExErr = ERR_SLEEP_REQ;
|
||||
}
|
||||
#endif /* RFAL_FEATURE_LISTEN_MODE */
|
||||
@@ -924,7 +924,7 @@ static ReturnCode rfalNfcPollTechDetetection(void) {
|
||||
|
||||
err = ERR_NONE;
|
||||
|
||||
/* Supress warning when specific RFAL features have been disabled */
|
||||
/* Suppress warning when specific RFAL features have been disabled */
|
||||
NO_WARNING(err);
|
||||
|
||||
/*******************************************************************************/
|
||||
@@ -1154,7 +1154,7 @@ static ReturnCode rfalNfcPollCollResolution(void) {
|
||||
err = ERR_NONE;
|
||||
i = 0;
|
||||
|
||||
/* Supress warning when specific RFAL features have been disabled */
|
||||
/* Suppress warning when specific RFAL features have been disabled */
|
||||
NO_WARNING(err);
|
||||
NO_WARNING(devCnt);
|
||||
NO_WARNING(i);
|
||||
@@ -1415,7 +1415,7 @@ static ReturnCode rfalNfcPollActivation(uint8_t devIt) {
|
||||
|
||||
err = ERR_NONE;
|
||||
|
||||
/* Supress warning when specific RFAL features have been disabled */
|
||||
/* Suppress warning when specific RFAL features have been disabled */
|
||||
NO_WARNING(err);
|
||||
|
||||
if(devIt > gNfcDev.devCnt) {
|
||||
@@ -1428,7 +1428,7 @@ static ReturnCode rfalNfcPollActivation(uint8_t devIt) {
|
||||
/*******************************************************************************/
|
||||
#if RFAL_FEATURE_NFC_DEP
|
||||
case RFAL_NFC_LISTEN_TYPE_AP2P:
|
||||
/* Activation has already been perfomed (ATR_REQ) */
|
||||
/* Activation has already been performed (ATR_REQ) */
|
||||
|
||||
gNfcDev.devList[devIt].nfcid =
|
||||
gNfcDev.devList[devIt].proto.nfcDep.activation.Target.ATR_RES.NFCID3;
|
||||
@@ -1971,7 +1971,7 @@ static ReturnCode rfalNfcNfcDepActivate(
|
||||
uint16_t atrReqLen) {
|
||||
rfalNfcDepAtrParam initParam;
|
||||
|
||||
/* Supress warnings if Listen mode is disabled */
|
||||
/* Suppress warnings if Listen mode is disabled */
|
||||
NO_WARNING(atrReq);
|
||||
NO_WARNING(atrReqLen);
|
||||
|
||||
|
||||
@@ -509,7 +509,7 @@ ReturnCode rfalSt25tbPollerWriteBlock(uint8_t blockAddress, const rfalSt25tbBloc
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If a transmission error occurred (maybe noise while commiting data) wait maximum programming time and verify data afterwards */
|
||||
/* If a transmission error occurred (maybe noise while committing data) wait maximum programming time and verify data afterwards */
|
||||
rfalSetGT((RFAL_ST25TB_FWT + RFAL_ST25TB_TW));
|
||||
rfalFieldOnAndStartGT();
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ ReturnCode rfalT4TPollerComposeCAPDU(const rfalT4tCApduParam* apduParam) {
|
||||
/* Check if Data is present */
|
||||
if(apduParam->LcFlag) {
|
||||
if(apduParam->Lc == 0U) {
|
||||
/* Extented field coding not supported */
|
||||
/* Extended field coding not supported */
|
||||
return ERR_PARAM;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* ENABLE SWITCHS
|
||||
* ENABLE SWITCHES
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -137,7 +137,7 @@ typedef struct {
|
||||
/*! Struct that holds counters to control the FIFO on Tx and Rx */
|
||||
typedef struct {
|
||||
uint16_t
|
||||
expWL; /*!< The amount of bytes expected to be Tx when a WL interrupt occours */
|
||||
expWL; /*!< The amount of bytes expected to be Tx when a WL interrupt occurs */
|
||||
uint16_t
|
||||
bytesTotal; /*!< Total bytes to be transmitted OR the total bytes received */
|
||||
uint16_t
|
||||
@@ -398,7 +398,7 @@ typedef union { /* PRQA S 0750 # MISRA 19.2 - Both members are of the same type
|
||||
* ISO15693 2000 8.4 t1 MIN = 4192/fc
|
||||
* ISO15693 2009 9.1 t1 MIN = 4320/fc
|
||||
* Digital 2.1 B.5 FDTV,LISTEN,MIN = 4310/fc
|
||||
* Set FDT Listen one step earlier than on the more recent spec versions for greater interoprability
|
||||
* Set FDT Listen one step earlier than on the more recent spec versions for greater interoperability
|
||||
*/
|
||||
#define RFAL_FDT_LISTEN_V_ADJUSTMENT 64U
|
||||
|
||||
@@ -1958,7 +1958,7 @@ static void rfalPrepareTransceive(void) {
|
||||
ST25R3916_IRQ_MASK_WU_F); /* Enable external Field interrupts to detect Link Loss and SENF_REQ auto responses */
|
||||
}
|
||||
|
||||
/* In Active comms enable also External Field interrupts and set RF Collsion Avoindance */
|
||||
/* In Active comms enable also External Field interrupts and set RF Collision Avoindance */
|
||||
if(rfalIsModeActiveComm(gRFAL.mode)) {
|
||||
maskInterrupts |=
|
||||
(ST25R3916_IRQ_MASK_EOF | ST25R3916_IRQ_MASK_EON | ST25R3916_IRQ_MASK_PPON2 |
|
||||
@@ -1990,7 +1990,7 @@ static void rfalTransceiveTx(void) {
|
||||
uint16_t tmp;
|
||||
ReturnCode ret;
|
||||
|
||||
/* Supress warning in case NFC-V feature is disabled */
|
||||
/* Suppress warning in case NFC-V feature is disabled */
|
||||
ret = ERR_NONE;
|
||||
NO_WARNING(ret);
|
||||
|
||||
@@ -2370,7 +2370,7 @@ static void rfalTransceiveRx(void) {
|
||||
}
|
||||
|
||||
if((irqs & ST25R3916_IRQ_MASK_RX_REST) != 0U) {
|
||||
/* RX_REST indicates that Receiver has been reseted due to EMD, therefore a RXS + RXE should *
|
||||
/* RX_REST indicates that Receiver has been reset due to EMD, therefore a RXS + RXE should *
|
||||
* follow if a good reception is followed within the valid initial timeout */
|
||||
|
||||
/* Check whether NRT has expired already, if so signal a timeout */
|
||||
@@ -2917,7 +2917,7 @@ ReturnCode rfalISO14443ATransceiveAnticollisionFrame(
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Set speficic Analog Config for Anticolission if needed */
|
||||
/* Set specific Analog Config for Anticolission if needed */
|
||||
rfalSetAnalogConfig(
|
||||
(RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA |
|
||||
RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_ANTICOL));
|
||||
@@ -3030,7 +3030,7 @@ ReturnCode rfalISO15693TransceiveAnticollisionFrame(
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Set speficic Analog Config for Anticolission if needed */
|
||||
/* Set specific Analog Config for Anticolission if needed */
|
||||
rfalSetAnalogConfig(
|
||||
(RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCV |
|
||||
RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_ANTICOL));
|
||||
@@ -4053,7 +4053,7 @@ ReturnCode rfalListenSetState(rfalLmState newSt) {
|
||||
ST25R3916_REG_AUX_DISPLAY,
|
||||
ST25R3916_REG_AUX_DISPLAY_osc_ok,
|
||||
ST25R3916_REG_AUX_DISPLAY_osc_ok)) {
|
||||
/* Wait for Oscilator ready */
|
||||
/* Wait for Oscillator ready */
|
||||
if(st25r3916WaitForInterruptsTimed(
|
||||
ST25R3916_IRQ_MASK_OSC, ST25R3916_TOUT_OSC_STABLE) == 0U) {
|
||||
ret = ERR_IO;
|
||||
@@ -4074,7 +4074,7 @@ ReturnCode rfalListenSetState(rfalLmState newSt) {
|
||||
* Ensure that when upper layer calls SetState(IDLE), it restores initial
|
||||
* configuration and that check whether an external Field is still present */
|
||||
if((gRFAL.Lm.mdMask & RFAL_LM_MASK_ACTIVE_P2P) != 0U) {
|
||||
/* Ensure nfc_ar is reseted and back to only after Rx */
|
||||
/* Ensure nfc_ar is reset and back to only after Rx */
|
||||
st25r3916ExecuteCommand(ST25R3916_CMD_STOP);
|
||||
st25r3916ChangeRegisterBits(
|
||||
ST25R3916_REG_MODE,
|
||||
@@ -4443,7 +4443,7 @@ static uint16_t rfalWakeUpModeFilter(uint16_t curRef, uint16_t curVal, uint8_t w
|
||||
|
||||
/* Perform the averaging|filter as describded in ST25R3916 DS */
|
||||
|
||||
/* Avoid signed arithmetics by spliting in two cases */
|
||||
/* Avoid signed arithmetics by splitting in two cases */
|
||||
if(curVal > curRef) {
|
||||
newRef = curRef + ((curVal - curRef) / weight);
|
||||
|
||||
|
||||
@@ -274,7 +274,7 @@ ReturnCode st25r3916Initialize(void) {
|
||||
void st25r3916Deinitialize(void) {
|
||||
st25r3916DisableInterrupts(ST25R3916_IRQ_MASK_ALL);
|
||||
|
||||
/* Disabe Tx and Rx, Keep OSC On */
|
||||
/* Disable Tx and Rx, Keep OSC On */
|
||||
st25r3916TxRxOff();
|
||||
|
||||
return;
|
||||
@@ -418,7 +418,7 @@ ReturnCode st25r3916CalibrateCapacitiveSensor(uint8_t* result) {
|
||||
ST25R3916_TOUT_CALIBRATE_CAP_SENSOR,
|
||||
&res);
|
||||
|
||||
/* Check wether the calibration was successull */
|
||||
/* Check whether the calibration was successull */
|
||||
if(((res & ST25R3916_REG_CAP_SENSOR_RESULT_cs_cal_end) !=
|
||||
ST25R3916_REG_CAP_SENSOR_RESULT_cs_cal_end) ||
|
||||
((res & ST25R3916_REG_CAP_SENSOR_RESULT_cs_cal_err) ==
|
||||
|
||||
@@ -117,7 +117,7 @@ struct st25r3916StreamConfig {
|
||||
#define ST25R3916_CMD_AM_MOD_STATE_CHANGE \
|
||||
0xD2U /*!< AM Modulation state change */
|
||||
#define ST25R3916_CMD_MEASURE_AMPLITUDE \
|
||||
0xD3U /*!< Measure singal amplitude on RFI inputs */
|
||||
0xD3U /*!< Measure signal amplitude on RFI inputs */
|
||||
#define ST25R3916_CMD_RESET_RXGAIN \
|
||||
0xD5U /*!< Reset RX Gain */
|
||||
#define ST25R3916_CMD_ADJUST_REGULATORS \
|
||||
@@ -299,7 +299,7 @@ ReturnCode st25r3916SetBitrate(uint8_t txrate, uint8_t rxrate);
|
||||
*
|
||||
* This function the power level is measured in maximum load conditions and
|
||||
* the regulated voltage reference is set to 250mV below this level.
|
||||
* Execution of this function lasts arround 5ms.
|
||||
* Execution of this function lasts around 5ms.
|
||||
*
|
||||
* The regulated voltages will be set to the result of Adjust Regulators
|
||||
*
|
||||
|
||||
@@ -1053,7 +1053,7 @@ ReturnCode st25r3916ReadRegister(uint8_t reg, uint8_t* val);
|
||||
* auto-increment feature. That is, after each read the address pointer
|
||||
* inside the ST25R3916 gets incremented automatically.
|
||||
*
|
||||
* \param[in] reg: Address of the frist register to read from.
|
||||
* \param[in] reg: Address of the first register to read from.
|
||||
* \param[in] values: pointer to a buffer where the result shall be written to.
|
||||
* \param[in] length: Number of registers to be read out.
|
||||
*
|
||||
@@ -1088,7 +1088,7 @@ ReturnCode st25r3916WriteRegister(uint8_t reg, uint8_t val);
|
||||
* auto-increment feature. That is, after each write the address pointer
|
||||
* inside the ST25R3916 gets incremented automatically.
|
||||
*
|
||||
* \param[in] reg: Address of the frist register to write.
|
||||
* \param[in] reg: Address of the first register to write.
|
||||
* \param[in] values: pointer to a buffer containing the values to be written.
|
||||
* \param[in] length: Number of values to be written.
|
||||
*
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
* \param[in] tmo : time in milliseconds until timeout occurs. If set to 0
|
||||
* the functions waits forever.
|
||||
*
|
||||
* \return : 0 if timeout occured otherwise a mask indicating the cleared
|
||||
* \return : 0 if timeout occurred otherwise a mask indicating the cleared
|
||||
* interrupts.
|
||||
*
|
||||
*****************************************************************************
|
||||
@@ -173,7 +173,7 @@ uint32_t st25r3916WaitForInterruptsTimed(uint32_t mask, uint16_t tmo);
|
||||
* \brief Get status for the given interrupt
|
||||
*
|
||||
* This function is used to check whether the interrupt given by \a mask
|
||||
* has occured. If yes the interrupt gets cleared. This function returns
|
||||
* has occurred. If yes the interrupt gets cleared. This function returns
|
||||
* only status bits which are inside \a mask.
|
||||
*
|
||||
* \param[in] mask : mask indicating the interrupt to check for.
|
||||
@@ -189,7 +189,7 @@ uint32_t st25r3916GetInterrupt(uint32_t mask);
|
||||
* \brief Init the 3916 interrupt
|
||||
*
|
||||
* This function is used to check whether the interrupt given by \a mask
|
||||
* has occured.
|
||||
* has occurred.
|
||||
*
|
||||
*****************************************************************************
|
||||
*/
|
||||
@@ -220,7 +220,7 @@ void st25r3916CheckForReceivedInterrupts(void);
|
||||
*****************************************************************************
|
||||
* \brief ISR Service routine
|
||||
*
|
||||
* This function modiefies the interupt
|
||||
* This function modiefies the interrupt
|
||||
*****************************************************************************
|
||||
*/
|
||||
void st25r3916Isr(void);
|
||||
|
||||
@@ -1927,7 +1927,7 @@ DWORD xsum32 (
|
||||
|
||||
static
|
||||
void get_xdir_info (
|
||||
BYTE* dirb, /* Pointer to the direcotry entry block 85+C0+C1s */
|
||||
BYTE* dirb, /* Pointer to the directory entry block 85+C0+C1s */
|
||||
FILINFO* fno /* Buffer to store the extracted file information */
|
||||
)
|
||||
{
|
||||
@@ -1971,17 +1971,17 @@ void get_xdir_info (
|
||||
|
||||
|
||||
/*-----------------------------------*/
|
||||
/* exFAT: Get a directry entry block */
|
||||
/* exFAT: Get a directory entry block */
|
||||
/*-----------------------------------*/
|
||||
|
||||
static
|
||||
FRESULT load_xdir ( /* FR_INT_ERR: invalid entry block */
|
||||
DIR* dp /* Pointer to the reading direcotry object pointing the 85 entry */
|
||||
DIR* dp /* Pointer to the reading directory object pointing the 85 entry */
|
||||
)
|
||||
{
|
||||
FRESULT res;
|
||||
UINT i, sz_ent;
|
||||
BYTE* dirb = dp->obj.fs->dirbuf; /* Pointer to the on-memory direcotry entry block 85+C0+C1s */
|
||||
BYTE* dirb = dp->obj.fs->dirbuf; /* Pointer to the on-memory directory entry block 85+C0+C1s */
|
||||
|
||||
|
||||
/* Load 85 entry */
|
||||
@@ -2026,7 +2026,7 @@ FRESULT load_xdir ( /* FR_INT_ERR: invalid entry block */
|
||||
/*------------------------------------------------*/
|
||||
static
|
||||
FRESULT load_obj_dir (
|
||||
DIR* dp, /* Blank directory object to be used to access containing direcotry */
|
||||
DIR* dp, /* Blank directory object to be used to access containing directory */
|
||||
const _FDID* obj /* Object with its containing directory information */
|
||||
)
|
||||
{
|
||||
@@ -2054,12 +2054,12 @@ FRESULT load_obj_dir (
|
||||
/*-----------------------------------------------*/
|
||||
static
|
||||
FRESULT store_xdir (
|
||||
DIR* dp /* Pointer to the direcotry object */
|
||||
DIR* dp /* Pointer to the directory object */
|
||||
)
|
||||
{
|
||||
FRESULT res;
|
||||
UINT nent;
|
||||
BYTE* dirb = dp->obj.fs->dirbuf; /* Pointer to the direcotry entry block 85+C0+C1s */
|
||||
BYTE* dirb = dp->obj.fs->dirbuf; /* Pointer to the directory entry block 85+C0+C1s */
|
||||
|
||||
/* Create set sum */
|
||||
st_word(dirb + XDIR_SetSum, xdir_sum(dirb));
|
||||
@@ -2087,7 +2087,7 @@ FRESULT store_xdir (
|
||||
|
||||
static
|
||||
void create_xdir (
|
||||
BYTE* dirb, /* Pointer to the direcotry entry block buffer */
|
||||
BYTE* dirb, /* Pointer to the directory entry block buffer */
|
||||
const WCHAR* lfn /* Pointer to the nul terminated file name */
|
||||
)
|
||||
{
|
||||
|
||||
@@ -853,7 +853,7 @@ ElfProcessSectionResult elf_process_section(
|
||||
if(process_section(elf->fd, section_header.sh_offset, section_header.sh_size, context)) {
|
||||
result = ElfProcessSectionResultSuccess;
|
||||
} else {
|
||||
result = ElfProcessSectionResultCannotProcess;
|
||||
result = ElfProcessSectionResultCannotProcess; //-V1048
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
DICT_DEF2(AddressCache, int, M_DEFAULT_OPLIST, Elf32_Addr, M_DEFAULT_OPLIST)
|
||||
DICT_DEF2(AddressCache, int, M_DEFAULT_OPLIST, Elf32_Addr, M_DEFAULT_OPLIST) //-V1048
|
||||
|
||||
/**
|
||||
* Callable elf entry type
|
||||
|
||||
@@ -118,7 +118,6 @@ void lfrfid_worker_start_thread(LFRFIDWorker* worker) {
|
||||
}
|
||||
|
||||
void lfrfid_worker_stop_thread(LFRFIDWorker* worker) {
|
||||
furi_assert(worker->mode_index == LFRFIDWorkerIdle);
|
||||
furi_thread_flags_set(furi_thread_get_id(worker->thread), LFRFIDEventStopThread);
|
||||
furi_thread_join(worker->thread);
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ ReturnCode slix_get_random(NfcVData* data) {
|
||||
}
|
||||
|
||||
ReturnCode slix_unlock(NfcVData* data, uint32_t password_id) {
|
||||
furi_assert(rand);
|
||||
furi_assert(data);
|
||||
|
||||
uint16_t received = 0;
|
||||
uint8_t rxBuf[32];
|
||||
|
||||
Submodule lib/stm32wb_copro updated: bbccbefae2...d8a6f1feb0
@@ -2,8 +2,8 @@
|
||||
|
||||
#include <furi_hal.h>
|
||||
|
||||
#define CONTRAST_ERC 31
|
||||
#define CONTRAST_MGG 27
|
||||
#define CONTRAST_ERC 32
|
||||
#define CONTRAST_MGG 28
|
||||
|
||||
uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) {
|
||||
UNUSED(u8x8);
|
||||
|
||||
@@ -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")),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -48,7 +48,6 @@ def generate(env):
|
||||
"@.pvsoptions",
|
||||
"-j${PVSNCORES}",
|
||||
# "--incremental", # kinda broken on PVS side
|
||||
"--disableLicenseExpirationCheck",
|
||||
],
|
||||
PVSCONVOPTIONS=[
|
||||
"-a",
|
||||
|
||||
@@ -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,6 +10,8 @@ def GlobRecursive(env, pattern, node=".", exclude=[]):
|
||||
results = []
|
||||
if isinstance(node, str):
|
||||
node = env.Dir(node)
|
||||
# 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)
|
||||
@@ -17,6 +20,10 @@ def GlobRecursive(env, pattern, node=".", exclude=[]):
|
||||
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
|
||||
|
||||
|
||||
@@ -267,7 +267,7 @@ class DolphinManifest:
|
||||
# Load animation data
|
||||
while True:
|
||||
try:
|
||||
# Read animation spcification
|
||||
# Read animation specification
|
||||
name = file.readKey("Name")
|
||||
min_butthurt = file.readKeyInt("Min butthurt")
|
||||
max_butthurt = file.readKeyInt("Max butthurt")
|
||||
|
||||
@@ -462,7 +462,7 @@ class Main(App):
|
||||
available_interfaces = self._search_interface(network_flash_interfaces)
|
||||
|
||||
if not available_interfaces:
|
||||
self.logger.error("No availiable interfaces")
|
||||
self.logger.error("No available interfaces")
|
||||
return 1
|
||||
elif len(available_interfaces) > 1:
|
||||
self.logger.error("Multiple interfaces found:")
|
||||
|
||||
@@ -72,10 +72,10 @@ def get_details(event, args):
|
||||
|
||||
|
||||
def add_env(name, value, file):
|
||||
delimeter = id_gen()
|
||||
print(f"{name}<<{delimeter}", file=file)
|
||||
delimiter = id_gen()
|
||||
print(f"{name}<<{delimiter}", file=file)
|
||||
print(f"{value}", file=file)
|
||||
print(f"{delimeter}", file=file)
|
||||
print(f"{delimiter}", file=file)
|
||||
|
||||
|
||||
def add_set_output_var(name, value, file):
|
||||
|
||||
@@ -89,7 +89,7 @@ fbtenv_check_sourced()
|
||||
setopt +o nomatch; # disabling 'no match found' warning in zsh
|
||||
return 0;;
|
||||
esac
|
||||
if [ ${0##*/} = "fbtenv.sh" ]; then # exluding script itself
|
||||
if [ ${0##*/} = "fbtenv.sh" ]; then # excluding script itself
|
||||
fbtenv_show_usage;
|
||||
return 1;
|
||||
fi
|
||||
@@ -173,7 +173,7 @@ fbtenv_check_rosetta()
|
||||
if [ "$ARCH_TYPE" = "arm64" ]; then
|
||||
if ! pgrep -q oahd; then
|
||||
echo "Flipper Zero Toolchain needs Rosetta2 to run under Apple Silicon";
|
||||
echo "Please instal it by typing 'softwareupdate --install-rosetta --agree-to-license'";
|
||||
echo "Please install it by typing 'softwareupdate --install-rosetta --agree-to-license'";
|
||||
return 1;
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -5,7 +5,7 @@ name: "FAP: Build for multiple SDK sources"
|
||||
|
||||
on:
|
||||
push:
|
||||
## put your main branch name under "braches"
|
||||
## put your main branch name under "branches"
|
||||
#branches:
|
||||
# - master
|
||||
pull_request:
|
||||
|
||||
Reference in New Issue
Block a user