diff --git a/applications/debug/file_browser_test/file_browser_app.c b/applications/debug/file_browser_test/file_browser_app.c index 6cb50d385..996cb2bd2 100644 --- a/applications/debug/file_browser_test/file_browser_app.c +++ b/applications/debug/file_browser_test/file_browser_app.c @@ -48,7 +48,7 @@ FileBrowserApp* file_browser_app_alloc(char* arg) { app->file_path = furi_string_alloc(); app->file_browser = file_browser_alloc(app->file_path); - file_browser_configure(app->file_browser, "*", true, &I_badusb_10px, true); + file_browser_configure(app->file_browser, "*", NULL, true, &I_badusb_10px, true); view_dispatcher_add_view( app->view_dispatcher, FileBrowserAppViewStart, widget_get_view(app->widget)); diff --git a/applications/debug/uart_echo/uart_echo.c b/applications/debug/uart_echo/uart_echo.c index 16996ba8c..dc1327529 100644 --- a/applications/debug/uart_echo/uart_echo.c +++ b/applications/debug/uart_echo/uart_echo.c @@ -215,26 +215,26 @@ static UartEchoApp* uart_echo_app_alloc() { view_dispatcher_add_view(app->view_dispatcher, 0, app->view); view_dispatcher_switch_to_view(app->view_dispatcher, 0); + app->worker_thread = furi_thread_alloc_ex("UsbUartWorker", 1024, uart_echo_worker, app); + furi_thread_start(app->worker_thread); + // Enable uart listener furi_hal_console_disable(); furi_hal_uart_set_br(FuriHalUartIdUSART1, 115200); furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, uart_echo_on_irq_cb, app); - app->worker_thread = furi_thread_alloc_ex("UsbUartWorker", 1024, uart_echo_worker, app); - furi_thread_start(app->worker_thread); - return app; } static void uart_echo_app_free(UartEchoApp* app) { furi_assert(app); + furi_hal_console_enable(); // this will also clear IRQ callback so thread is no longer referenced + furi_thread_flags_set(furi_thread_get_id(app->worker_thread), WorkerEventStop); furi_thread_join(app->worker_thread); furi_thread_free(app->worker_thread); - furi_hal_console_enable(); - // Free views view_dispatcher_remove_view(app->view_dispatcher, 0); diff --git a/applications/debug/unit_tests/furi_hal/furi_hal_tests.c b/applications/debug/unit_tests/furi_hal/furi_hal_tests.c new file mode 100644 index 000000000..e942c5933 --- /dev/null +++ b/applications/debug/unit_tests/furi_hal/furi_hal_tests.c @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include "../minunit.h" + +#define DATA_SIZE 4 + +static void furi_hal_i2c_int_setup() { + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); +} + +static void furi_hal_i2c_int_teardown() { + furi_hal_i2c_release(&furi_hal_i2c_handle_power); +} + +MU_TEST(furi_hal_i2c_int_1b) { + bool ret = false; + uint8_t data_one = 0; + + // 1 byte: read, write, read + ret = furi_hal_i2c_read_reg_8( + &furi_hal_i2c_handle_power, + LP5562_ADDRESS, + LP5562_CHANNEL_BLUE_CURRENT_REGISTER, + &data_one, + LP5562_I2C_TIMEOUT); + mu_assert(ret, "0 read_reg_8 failed"); + mu_assert(data_one != 0, "0 invalid data"); + ret = furi_hal_i2c_write_reg_8( + &furi_hal_i2c_handle_power, + LP5562_ADDRESS, + LP5562_CHANNEL_BLUE_CURRENT_REGISTER, + data_one, + LP5562_I2C_TIMEOUT); + mu_assert(ret, "1 write_reg_8 failed"); + ret = furi_hal_i2c_read_reg_8( + &furi_hal_i2c_handle_power, + LP5562_ADDRESS, + LP5562_CHANNEL_BLUE_CURRENT_REGISTER, + &data_one, + LP5562_I2C_TIMEOUT); + mu_assert(ret, "2 read_reg_8 failed"); + mu_assert(data_one != 0, "2 invalid data"); +} + +MU_TEST(furi_hal_i2c_int_3b) { + bool ret = false; + uint8_t data_many[DATA_SIZE] = {0}; + + // 3 byte: read, write, read + data_many[0] = LP5562_CHANNEL_BLUE_CURRENT_REGISTER; + ret = furi_hal_i2c_tx( + &furi_hal_i2c_handle_power, LP5562_ADDRESS, data_many, 1, LP5562_I2C_TIMEOUT); + mu_assert(ret, "3 tx failed"); + ret = furi_hal_i2c_rx( + &furi_hal_i2c_handle_power, + LP5562_ADDRESS, + data_many + 1, + DATA_SIZE - 1, + LP5562_I2C_TIMEOUT); + mu_assert(ret, "4 rx failed"); + for(size_t i = 0; i < DATA_SIZE; i++) mu_assert(data_many[i] != 0, "4 invalid data_many"); + + ret = furi_hal_i2c_tx( + &furi_hal_i2c_handle_power, LP5562_ADDRESS, data_many, DATA_SIZE, LP5562_I2C_TIMEOUT); + mu_assert(ret, "5 tx failed"); + + ret = furi_hal_i2c_tx( + &furi_hal_i2c_handle_power, LP5562_ADDRESS, data_many, 1, LP5562_I2C_TIMEOUT); + mu_assert(ret, "6 tx failed"); + ret = furi_hal_i2c_rx( + &furi_hal_i2c_handle_power, + LP5562_ADDRESS, + data_many + 1, + DATA_SIZE - 1, + LP5562_I2C_TIMEOUT); + mu_assert(ret, "7 rx failed"); + for(size_t i = 0; i < DATA_SIZE; i++) mu_assert(data_many[i] != 0, "7 invalid data_many"); +} + +MU_TEST(furi_hal_i2c_int_1b_fail) { + bool ret = false; + uint8_t data_one = 0; + + // 1 byte: fail, read, fail, write, fail, read + data_one = 0; + ret = furi_hal_i2c_read_reg_8( + &furi_hal_i2c_handle_power, + LP5562_ADDRESS + 0x10, + LP5562_CHANNEL_BLUE_CURRENT_REGISTER, + &data_one, + LP5562_I2C_TIMEOUT); + mu_assert(!ret, "8 read_reg_8 failed"); + mu_assert(data_one == 0, "8 invalid data"); + ret = furi_hal_i2c_read_reg_8( + &furi_hal_i2c_handle_power, + LP5562_ADDRESS, + LP5562_CHANNEL_BLUE_CURRENT_REGISTER, + &data_one, + LP5562_I2C_TIMEOUT); + mu_assert(ret, "9 read_reg_8 failed"); + mu_assert(data_one != 0, "9 invalid data"); +} + +MU_TEST_SUITE(furi_hal_i2c_int_suite) { + MU_SUITE_CONFIGURE(&furi_hal_i2c_int_setup, &furi_hal_i2c_int_teardown); + MU_RUN_TEST(furi_hal_i2c_int_1b); + MU_RUN_TEST(furi_hal_i2c_int_3b); + MU_RUN_TEST(furi_hal_i2c_int_1b_fail); +} + +int run_minunit_test_furi_hal() { + MU_RUN_SUITE(furi_hal_i2c_int_suite); + return MU_EXIT_CODE; +} diff --git a/applications/debug/unit_tests/test_index.c b/applications/debug/unit_tests/test_index.c index 2009d4a5b..b8760b1f0 100644 --- a/applications/debug/unit_tests/test_index.c +++ b/applications/debug/unit_tests/test_index.c @@ -9,6 +9,7 @@ #define TAG "UnitTests" int run_minunit_test_furi(); +int run_minunit_test_furi_hal(); int run_minunit_test_furi_string(); int run_minunit_test_infrared(); int run_minunit_test_rpc(); @@ -32,6 +33,7 @@ typedef struct { const UnitTest unit_tests[] = { {.name = "furi", .entry = run_minunit_test_furi}, + {.name = "furi_hal", .entry = run_minunit_test_furi_hal}, {.name = "furi_string", .entry = run_minunit_test_furi_string}, {.name = "storage", .entry = run_minunit_test_storage}, {.name = "stream", .entry = run_minunit_test_stream}, diff --git a/applications/main/archive/helpers/archive_browser.c b/applications/main/archive/helpers/archive_browser.c index b379c75c0..9ff7e49ce 100644 --- a/applications/main/archive/helpers/archive_browser.c +++ b/applications/main/archive/helpers/archive_browser.c @@ -90,7 +90,8 @@ static void archive_file_browser_set_path( bool hide_dot_files) { furi_assert(browser); if(!browser->worker_running) { - browser->worker = file_browser_worker_alloc(path, filter_ext, skip_assets, hide_dot_files); + browser->worker = + file_browser_worker_alloc(path, NULL, filter_ext, skip_assets, hide_dot_files); file_browser_worker_set_callback_context(browser->worker, browser); file_browser_worker_set_folder_callback(browser->worker, archive_folder_open_cb); file_browser_worker_set_list_callback(browser->worker, archive_list_load_cb); @@ -481,6 +482,8 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) { tab = archive_get_tab(browser); if(archive_is_dir_exists(browser->path)) { bool skip_assets = (strcmp(archive_get_tab_ext(tab), "*") == 0) ? false : true; + // Hide dot files everywhere except Browser + bool hide_dot_files = (strcmp(archive_get_tab_ext(tab), "*") == 0) ? false : true; archive_file_browser_set_path( browser, browser->path, archive_get_tab_ext(tab), skip_assets, false); tab_empty = false; // Empty check will be performed later diff --git a/applications/main/bad_usb/scenes/bad_usb_scene_file_select.c b/applications/main/bad_usb/scenes/bad_usb_scene_file_select.c index 782d42948..e67a45c53 100644 --- a/applications/main/bad_usb/scenes/bad_usb_scene_file_select.c +++ b/applications/main/bad_usb/scenes/bad_usb_scene_file_select.c @@ -1,14 +1,15 @@ #include "../bad_usb_app_i.h" #include "furi_hal_power.h" #include "furi_hal_usb.h" +#include static bool bad_usb_file_select(BadUsbApp* bad_usb) { furi_assert(bad_usb); DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options( - &browser_options, BAD_USB_APP_SCRIPT_EXTENSION, &I_badusb_10px); + dialog_file_browser_set_basic_options(&browser_options, BAD_USB_APP_EXTENSION, &I_badusb_10px); browser_options.skip_assets = true; + browser_options.base_path = BAD_USB_APP_PATH_FOLDER; // Input events and views are managed by file_browser bool res = dialog_file_browser_show( diff --git a/applications/main/fap_loader/fap_loader_app.c b/applications/main/fap_loader/fap_loader_app.c index 71d10341f..e46762a6a 100644 --- a/applications/main/fap_loader/fap_loader_app.c +++ b/applications/main/fap_loader/fap_loader_app.c @@ -161,6 +161,7 @@ static bool fap_loader_select_app(FapLoader* loader) { .hide_ext = true, .item_loader_callback = fap_loader_item_callback, .item_loader_context = loader, + .base_path = EXT_PATH("apps"), }; return dialog_file_browser_show( diff --git a/applications/main/ibutton/ibutton.c b/applications/main/ibutton/ibutton.c index 2762d68e1..d1cb78b4e 100644 --- a/applications/main/ibutton/ibutton.c +++ b/applications/main/ibutton/ibutton.c @@ -217,6 +217,7 @@ void ibutton_free(iButton* ibutton) { bool ibutton_file_select(iButton* ibutton) { DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options(&browser_options, IBUTTON_APP_EXTENSION, &I_ibutt_10px); + browser_options.base_path = IBUTTON_APP_FOLDER; bool success = dialog_file_browser_show( ibutton->dialogs, ibutton->file_path, ibutton->file_path, &browser_options); diff --git a/applications/main/infrared/scenes/infrared_scene_remote_list.c b/applications/main/infrared/scenes/infrared_scene_remote_list.c index 1667352d1..55f14416b 100644 --- a/applications/main/infrared/scenes/infrared_scene_remote_list.c +++ b/applications/main/infrared/scenes/infrared_scene_remote_list.c @@ -7,6 +7,7 @@ void infrared_scene_remote_list_on_enter(void* context) { DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options(&browser_options, INFRARED_APP_EXTENSION, &I_ir_10px); + browser_options.base_path = INFRARED_APP_FOLDER; bool success = dialog_file_browser_show( infrared->dialogs, infrared->file_path, infrared->file_path, &browser_options); diff --git a/applications/main/lfrfid/lfrfid.c b/applications/main/lfrfid/lfrfid.c index d391c5e89..2207e7e07 100644 --- a/applications/main/lfrfid/lfrfid.c +++ b/applications/main/lfrfid/lfrfid.c @@ -230,6 +230,7 @@ bool lfrfid_load_key_from_file_select(LfRfid* app) { DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options(&browser_options, LFRFID_APP_EXTENSION, &I_125_10px); + browser_options.base_path = LFRFID_APP_FOLDER; // Input events and views are managed by file_browser bool result = diff --git a/applications/main/nfc/scenes/nfc_scene_emulate_uid.c b/applications/main/nfc/scenes/nfc_scene_emulate_uid.c index 5ddb60992..f90197679 100644 --- a/applications/main/nfc/scenes/nfc_scene_emulate_uid.c +++ b/applications/main/nfc/scenes/nfc_scene_emulate_uid.c @@ -37,8 +37,8 @@ static void nfc_scene_emulate_uid_widget_config(Nfc* nfc, bool data_received) { FuriString* info_str; info_str = furi_string_alloc(); - widget_add_icon_element(widget, 0, 3, &I_RFIDDolphinSend_97x61); - widget_add_string_element(widget, 89, 32, AlignCenter, AlignTop, FontPrimary, "Emulating UID"); + widget_add_icon_element(widget, 0, 3, &I_NFC_dolphin_emulation_47x61); + widget_add_string_element(widget, 57, 13, AlignLeft, AlignTop, FontPrimary, "Emulating UID"); if(strcmp(nfc->dev->dev_name, "")) { furi_string_printf(info_str, "%s", nfc->dev->dev_name); } else { @@ -48,7 +48,7 @@ static void nfc_scene_emulate_uid_widget_config(Nfc* nfc, bool data_received) { } furi_string_trim(info_str); widget_add_text_box_element( - widget, 56, 43, 70, 21, AlignCenter, AlignTop, furi_string_get_cstr(info_str), true); + widget, 57, 28, 67, 25, AlignCenter, AlignTop, furi_string_get_cstr(info_str), true); furi_string_free(info_str); if(data_received) { widget_add_button_element( diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c index 68eda7040..1bd9a85a8 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c @@ -17,13 +17,14 @@ void nfc_scene_mf_classic_emulate_on_enter(void* context) { // Setup view Popup* popup = nfc->popup; + popup_set_header(popup, "Emulating", 67, 13, AlignLeft, AlignTop); if(strcmp(nfc->dev->dev_name, "")) { - nfc_text_store_set(nfc, "Emulating\n%s", nfc->dev->dev_name); + nfc_text_store_set(nfc, "%s", nfc->dev->dev_name); } else { - nfc_text_store_set(nfc, "Emulating\nMf Classic", nfc->dev->dev_name); + nfc_text_store_set(nfc, "MIFARE\nClassic"); } - popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61); - popup_set_header(popup, nfc->text_store, 56, 31, AlignLeft, AlignTop); + popup_set_icon(popup, 0, 3, &I_NFC_dolphin_emulation_47x61); + popup_set_text(popup, nfc->text_store, 90, 28, AlignCenter, AlignTop); // Setup and start worker view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); diff --git a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c index 1505064a4..b823eb313 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c @@ -98,6 +98,21 @@ void nfc_scene_mf_ultralight_emulate_on_enter(void* context) { text_box_set_font(text_box, TextBoxFontHex); text_box_set_focus(text_box, TextBoxFocusEnd); furi_string_reset(nfc->text_box_store); + // Setup view + MfUltralightType type = nfc->dev->dev_data.mf_ul_data.type; + bool is_ultralight = (type == MfUltralightTypeUL11) || (type == MfUltralightTypeUL21) || + (type == MfUltralightTypeUnknown); + Popup* popup = nfc->popup; + popup_set_header(popup, "Emulating", 67, 13, AlignLeft, AlignTop); + if(strcmp(nfc->dev->dev_name, "")) { + nfc_text_store_set(nfc, "%s", nfc->dev->dev_name); + } else if(is_ultralight) { + nfc_text_store_set(nfc, "MIFARE\nUltralight"); + } else { + nfc_text_store_set(nfc, "MIFARE\nNTAG"); + } + popup_set_icon(popup, 0, 3, &I_NFC_dolphin_emulation_47x61); + popup_set_text(popup, nfc->text_store, 90, 28, AlignCenter, AlignTop); // Set Widget state and view state = (state & ~NfcSceneMfUltralightEmulateStateMax) | diff --git a/applications/main/nfc/scenes/nfc_scene_rpc.c b/applications/main/nfc/scenes/nfc_scene_rpc.c index 1c0e4fa85..d06ee7564 100644 --- a/applications/main/nfc/scenes/nfc_scene_rpc.c +++ b/applications/main/nfc/scenes/nfc_scene_rpc.c @@ -7,7 +7,7 @@ void nfc_scene_rpc_on_enter(void* context) { popup_set_header(popup, "NFC", 89, 42, AlignCenter, AlignBottom); popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61); + popup_set_icon(popup, 0, 12, &I_NFC_dolphin_emulation_47x61); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); diff --git a/applications/main/subghz/subghz_i.c b/applications/main/subghz/subghz_i.c index 9660fa1aa..c423d5037 100644 --- a/applications/main/subghz/subghz_i.c +++ b/applications/main/subghz/subghz_i.c @@ -461,6 +461,7 @@ bool subghz_load_protocol_from_file(SubGhz* subghz) { DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options(&browser_options, SUBGHZ_APP_EXTENSION, &I_sub1_10px); + browser_options.base_path = SUBGHZ_APP_FOLDER; // Input events and views are managed by file_select bool res = dialog_file_browser_show( diff --git a/applications/plugins/music_player/music_player.c b/applications/plugins/music_player/music_player.c index 24e2d0fbc..2f9839c10 100644 --- a/applications/plugins/music_player/music_player.c +++ b/applications/plugins/music_player/music_player.c @@ -313,6 +313,7 @@ int32_t music_player_app(void* p) { dialog_file_browser_set_basic_options( &browser_options, MUSIC_PLAYER_APP_EXTENSION, &I_music_10px); browser_options.hide_ext = false; + browser_options.base_path = MUSIC_PLAYER_APP_PATH_FOLDER; DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); bool res = dialog_file_browser_show(dialogs, file_path, file_path, &browser_options); diff --git a/applications/plugins/picopass/picopass_device.c b/applications/plugins/picopass/picopass_device.c index 6403da922..de01834bc 100644 --- a/applications/plugins/picopass/picopass_device.c +++ b/applications/plugins/picopass/picopass_device.c @@ -231,6 +231,7 @@ bool picopass_file_select(PicopassDevice* dev) { DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options(&browser_options, PICOPASS_APP_EXTENSION, &I_Nfc_10px); + browser_options.base_path = PICOPASS_APP_FOLDER; bool res = dialog_file_browser_show( dev->dialogs, dev->load_path, picopass_app_folder, &browser_options); diff --git a/applications/services/dialogs/dialogs.c b/applications/services/dialogs/dialogs.c index 3c6588889..3908ca31b 100644 --- a/applications/services/dialogs/dialogs.c +++ b/applications/services/dialogs/dialogs.c @@ -14,6 +14,7 @@ void dialog_file_browser_set_basic_options( options->hide_ext = true; options->item_loader_callback = NULL; options->item_loader_context = NULL; + options->base_path = NULL; } static DialogsApp* dialogs_app_alloc() { diff --git a/applications/services/dialogs/dialogs.h b/applications/services/dialogs/dialogs.h index 97783eb0d..4c1b675a6 100644 --- a/applications/services/dialogs/dialogs.h +++ b/applications/services/dialogs/dialogs.h @@ -18,6 +18,7 @@ typedef struct DialogsApp DialogsApp; /** * File browser dialog extra options * @param extension file extension to be offered for selection + * @param base_path root folder path for navigation with back key * @param skip_assets true - do not show assets folders * @param hide_dot_files true - hide dot files * @param icon file icon pointer, NULL for default icon @@ -27,6 +28,7 @@ typedef struct DialogsApp DialogsApp; */ typedef struct { const char* extension; + const char* base_path; bool skip_assets; bool hide_dot_files; const Icon* icon; diff --git a/applications/services/dialogs/dialogs_api.c b/applications/services/dialogs/dialogs_api.c index 91b3a1d04..5e2b0683e 100644 --- a/applications/services/dialogs/dialogs_api.c +++ b/applications/services/dialogs/dialogs_api.c @@ -24,6 +24,7 @@ bool dialog_file_browser_show( .preselected_filename = path, .item_callback = options ? options->item_loader_callback : NULL, .item_callback_context = options ? options->item_loader_context : NULL, + .base_path = options ? options->base_path : NULL, }}; DialogsAppReturn return_data; diff --git a/applications/services/dialogs/dialogs_message.h b/applications/services/dialogs/dialogs_message.h index 45d36ba17..1c8c4fb50 100644 --- a/applications/services/dialogs/dialogs_message.h +++ b/applications/services/dialogs/dialogs_message.h @@ -17,6 +17,7 @@ typedef struct { FuriString* preselected_filename; FileBrowserLoadItemCallback item_callback; void* item_callback_context; + const char* base_path; } DialogsAppMessageDataFileBrowser; typedef struct { diff --git a/applications/services/dialogs/dialogs_module_file_browser.c b/applications/services/dialogs/dialogs_module_file_browser.c index e03434cf5..8d486dbaf 100644 --- a/applications/services/dialogs/dialogs_module_file_browser.c +++ b/applications/services/dialogs/dialogs_module_file_browser.c @@ -40,6 +40,7 @@ bool dialogs_app_process_module_file_browser(const DialogsAppMessageDataFileBrow file_browser_configure( file_browser, data->extension, + data->base_path, data->skip_assets, data->hide_dot_files, data->file_icon, diff --git a/applications/services/gui/modules/file_browser.c b/applications/services/gui/modules/file_browser.c index 60d77a971..522d7d591 100644 --- a/applications/services/gui/modules/file_browser.c +++ b/applications/services/gui/modules/file_browser.c @@ -101,6 +101,7 @@ struct FileBrowser { View* view; BrowserWorker* worker; const char* ext_filter; + const char* base_path; bool skip_assets; bool hide_dot_files; bool hide_ext; @@ -181,6 +182,7 @@ View* file_browser_get_view(FileBrowser* browser) { void file_browser_configure( FileBrowser* browser, const char* extension, + const char* base_path, bool skip_assets, bool hide_dot_files, const Icon* file_icon, @@ -190,6 +192,7 @@ void file_browser_configure( browser->ext_filter = extension; browser->skip_assets = skip_assets; browser->hide_ext = hide_ext; + browser->base_path = base_path; browser->hide_dot_files = hide_dot_files; with_view_model( @@ -205,7 +208,11 @@ void file_browser_configure( void file_browser_start(FileBrowser* browser, FuriString* path) { furi_assert(browser); browser->worker = file_browser_worker_alloc( - path, browser->ext_filter, browser->skip_assets, browser->hide_dot_files); + path, + browser->base_path, + browser->ext_filter, + browser->skip_assets, + browser->hide_dot_files); file_browser_worker_set_callback_context(browser->worker, browser); file_browser_worker_set_folder_callback(browser->worker, browser_folder_open_cb); file_browser_worker_set_list_callback(browser->worker, browser_list_load_cb); diff --git a/applications/services/gui/modules/file_browser.h b/applications/services/gui/modules/file_browser.h index 377d4d9bc..879d62c4e 100644 --- a/applications/services/gui/modules/file_browser.h +++ b/applications/services/gui/modules/file_browser.h @@ -29,6 +29,7 @@ View* file_browser_get_view(FileBrowser* browser); void file_browser_configure( FileBrowser* browser, const char* extension, + const char* base_path, bool skip_assets, bool hide_dot_files, const Icon* file_icon, diff --git a/applications/services/gui/modules/file_browser_worker.c b/applications/services/gui/modules/file_browser_worker.c index 83fe5697d..9e772fd5c 100644 --- a/applications/services/gui/modules/file_browser_worker.c +++ b/applications/services/gui/modules/file_browser_worker.c @@ -375,6 +375,7 @@ static int32_t browser_worker(void* context) { BrowserWorker* file_browser_worker_alloc( FuriString* path, + const char* base_path, const char* filter_ext, bool skip_assets, bool hide_dot_files) { @@ -386,11 +387,13 @@ BrowserWorker* file_browser_worker_alloc( browser->skip_assets = skip_assets; browser->hide_dot_files = hide_dot_files; browser->path_start = furi_string_alloc_set(path); + browser->path_current = furi_string_alloc_set(path); browser->path_next = furi_string_alloc_set(path); - if(browser_path_is_file(browser->path_start)) { - browser_path_trim(browser->path_start); + browser->path_start = furi_string_alloc(); + if(base_path) { + furi_string_set_str(browser->path_start, base_path); } browser->thread = furi_thread_alloc_ex("BrowserWorker", 2048, browser_worker, browser); diff --git a/applications/services/gui/modules/file_browser_worker.h b/applications/services/gui/modules/file_browser_worker.h index ca143d660..3b4be6aa7 100644 --- a/applications/services/gui/modules/file_browser_worker.h +++ b/applications/services/gui/modules/file_browser_worker.h @@ -23,6 +23,7 @@ typedef void (*BrowserWorkerLongLoadCallback)(void* context); BrowserWorker* file_browser_worker_alloc( FuriString* path, + const char* base_path, const char* filter_ext, bool skip_assets, bool hide_dot_files); diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c index bdd9589ed..cf474c546 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c @@ -106,6 +106,7 @@ bool desktop_settings_scene_favorite_on_event(void* context, SceneManagerEvent e .hide_ext = true, .item_loader_callback = favorite_fap_selector_item_callback, .item_loader_context = app, + .base_path = EXT_PATH("apps"), }; if(primary_favorite) { // Select favorite fap in file browser diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_0.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_0.png new file mode 100644 index 000000000..912090032 Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_0.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_1.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_1.png new file mode 100644 index 000000000..0b99a32ff Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_1.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_10.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_10.png new file mode 100644 index 000000000..9da72ac1d Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_10.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_11.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_11.png new file mode 100644 index 000000000..8d54da6c6 Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_11.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_12.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_12.png new file mode 100644 index 000000000..84046a46c Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_12.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_13.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_13.png new file mode 100644 index 000000000..3e1c9c329 Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_13.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_14.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_14.png new file mode 100644 index 000000000..f4f6ccd66 Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_14.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_15.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_15.png new file mode 100644 index 000000000..5dc1a6525 Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_15.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_16.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_16.png new file mode 100644 index 000000000..bec472921 Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_16.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_17.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_17.png new file mode 100644 index 000000000..82e5176c8 Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_17.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_18.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_18.png new file mode 100644 index 000000000..3b5e60dfd Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_18.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_19.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_19.png new file mode 100644 index 000000000..5f76c7d23 Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_19.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_2.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_2.png new file mode 100644 index 000000000..84d6aaf35 Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_2.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_20.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_20.png new file mode 100644 index 000000000..2f8394fd5 Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_20.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_3.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_3.png new file mode 100644 index 000000000..48adde113 Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_3.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_4.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_4.png new file mode 100644 index 000000000..5889835b7 Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_4.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_5.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_5.png new file mode 100644 index 000000000..7f980f57f Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_5.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_6.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_6.png new file mode 100644 index 000000000..497136000 Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_6.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_7.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_7.png new file mode 100644 index 000000000..03d67134a Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_7.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_8.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_8.png new file mode 100644 index 000000000..9f523cace Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_8.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/frame_9.png b/assets/dolphin/external/L2_Wake_up_128x64/frame_9.png new file mode 100644 index 000000000..5a565b1af Binary files /dev/null and b/assets/dolphin/external/L2_Wake_up_128x64/frame_9.png differ diff --git a/assets/dolphin/external/L2_Wake_up_128x64/meta.txt b/assets/dolphin/external/L2_Wake_up_128x64/meta.txt new file mode 100644 index 000000000..06c710f03 --- /dev/null +++ b/assets/dolphin/external/L2_Wake_up_128x64/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 10 +Active frames: 18 +Frames order: 0 1 0 1 0 1 0 2 3 4 0 5 6 7 8 9 10 11 10 12 13 14 15 16 17 18 19 20 +Active cycles: 1 +Frame rate: 2 +Duration: 3600 +Active cooldown: 7 + +Bubble slots: 0 \ No newline at end of file diff --git a/assets/dolphin/external/manifest.txt b/assets/dolphin/external/manifest.txt index 57480b211..0e6943cf4 100644 --- a/assets/dolphin/external/manifest.txt +++ b/assets/dolphin/external/manifest.txt @@ -85,6 +85,13 @@ Min level: 1 Max level: 30 Weight: 7 +Name: L2_Wake_up_128x64 +Min butthurt: 0 +Max butthurt: 14 +Min level: 1 +Max level: 30 +Weight: 5 + Name: L1_Halloween_128x64 Min butthurt: 0 Max butthurt: 14 diff --git a/assets/icons/NFC/NFC_dolphin_emulation_47x61.png b/assets/icons/NFC/NFC_dolphin_emulation_47x61.png new file mode 100644 index 000000000..178353128 Binary files /dev/null and b/assets/icons/NFC/NFC_dolphin_emulation_47x61.png differ diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index ff502ef78..490b785b8 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,9.0,, +Version,+,10.1,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -833,14 +833,14 @@ Function,-,fgetpos,int,"FILE*, fpos_t*" Function,-,fgets,char*,"char*, int, FILE*" Function,-,fgets_unlocked,char*,"char*, int, FILE*" Function,+,file_browser_alloc,FileBrowser*,FuriString* -Function,+,file_browser_configure,void,"FileBrowser*, const char*, _Bool, _Bool, const Icon*, _Bool" +Function,+,file_browser_configure,void,"FileBrowser*, const char*, const char*, _Bool, _Bool, const Icon*, _Bool" Function,+,file_browser_free,void,FileBrowser* Function,+,file_browser_get_view,View*,FileBrowser* Function,+,file_browser_set_callback,void,"FileBrowser*, FileBrowserCallback, void*" Function,+,file_browser_set_item_callback,void,"FileBrowser*, FileBrowserLoadItemCallback, void*" Function,+,file_browser_start,void,"FileBrowser*, FuriString*" Function,+,file_browser_stop,void,FileBrowser* -Function,+,file_browser_worker_alloc,BrowserWorker*,"FuriString*, const char*, _Bool, _Bool" +Function,+,file_browser_worker_alloc,BrowserWorker*,"FuriString*, const char*, const char*, _Bool, _Bool" Function,+,file_browser_worker_folder_enter,void,"BrowserWorker*, FuriString*, int32_t" Function,+,file_browser_worker_folder_exit,void,BrowserWorker* Function,+,file_browser_worker_folder_refresh,void,"BrowserWorker*, int32_t" diff --git a/lib/nfc/nfc_device.c b/lib/nfc/nfc_device.c index a3f89b283..a6e213a52 100644 --- a/lib/nfc/nfc_device.c +++ b/lib/nfc/nfc_device.c @@ -1533,6 +1533,7 @@ bool nfc_file_select(NfcDevice* dev) { .hide_ext = true, .item_loader_callback = NULL, .item_loader_context = NULL, + .base_path = NFC_APP_FOLDER, }; bool res =