diff --git a/CHANGELOG.md b/CHANGELOG.md index b3b7fb6aa9..b8e4070bda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,41 +1,8 @@ ### New changes -* API: Due to OFW changes API was updated to 14.x, extra pack was updated you can install it separatly or use build with extra pack included -* SubGHz: **Fixed bug in SubGHz HAL, now CC1101 shutdowns properly, (also this fixed unstable TX)** -* SubGHz: **Alutech AT-4N** encoder (support for sending signals) (by @assasinfil | PR #322) -* SubGHz: **KingGates Stylo 4k** encoder (support for sending signals) (by @assasinfil | PR #321) -* SubGHz: Added Debug Pin setting for protocol development and fixed debug (and sound) with internal module -* SubGHz: GUI Fixes -* SubGHz: Removed bugged Detect RAW feature, now its replaced with BinRAW -* Plugins: SubGHz Bruteforcer - Added support for Linear Delta-3 310MHz -* Plugins: Fix CTRL-SHIFT in mousejacker (by @notmarek | PR #316) -* Infrared: Update universal remote assets (by @amec0e) (PR #318) -* NFC: Add Mifare Classic keys (by @Bon-Jorik (scaff.walker) | PR #324) -* Misc: Playing games now affect Flipper's level -* OFW: Fixed typo in nfc_magic_scene_wrong_card.c -* OFW: SubGhz: fix cc1101_read_fifo func -* OFW: feat: add missing `const` qualifiers -* OFW: **SubGhz: add protocol BinRAW (binarization of data quantized by the minimum correlated duration)** -* OFW: Picopass: show elite key used from dictionary -* OFW: Firmware fixes and improvements for flashing via blackmagic -* OFW: fbt: building fap_dist for compact gh build; accessor: fixed for latest ibutton changes -* OFW: Move CSN space to revent overflow -* OFW: **SubGhz: add protocol KingGates Stylo4k** -* OFW: **SubGhz: add protocol Nice One** -* OFW: **SubGhz: add protocol Alutech at-4n** -* OFW: **SubGhz: add DOOYA protocol** -* OFW: **SubGhz: add protocol "Linear Delta-3"** -* OFW: **SubGhz: Fix Raw write, add short duration filter setting** -* OFW: Update Missing SD Card icon from PR 2373 -* OFW: SCons: do not include backup files in build -* OFW: Fix minor UI inconsistencies and bugs -* OFW: Allow use of any suitable pin for 1-Wire devices -* OFW: **SD over SPI improvements** -* OFW: Multitarget support for fbt (includes support for non released yet flipper hardware) -* OFW: Pin Reset -* OFW: nfc: Add mifare classic value block commands -* OFW: battery info temperature shown in C or F based on settings -* OFW: Script that can find programmer and flash firmware via it. -* OFW: **SPI Mem Manager C port** (You can use flipper as programmer to flash supported chips) +* iButton: **Temp Fix of non working emulation on Metakom and Cyfral protocols** +* Archive and FileBrowser: **Sort files and folders alphabetically.** Added a "Internal" tab to the Browser (only in DEBUG mode), other misc changes (by @ClaraCrazy and @Willy-JL | PR #327) +* SubGHz: Custom modulation for lrs pagers and added frequency 467.75 to default list (by @jbohack | PR #328) +* SubGHz: **Small fixes in SubGHz HAL** #### [🎲 Download latest extra apps pack](https://download-directory.github.io/?url=https://github.com/xMasterX/unleashed-extra-pack/tree/main/apps) diff --git a/applications/main/archive/helpers/archive_browser.c b/applications/main/archive/helpers/archive_browser.c index 45c4a414ed..97c68545e1 100644 --- a/applications/main/archive/helpers/archive_browser.c +++ b/applications/main/archive/helpers/archive_browser.c @@ -8,6 +8,7 @@ #include #include #include +#include static void archive_folder_open_cb(void* context, uint32_t item_cnt, int32_t file_idx, bool is_root) { @@ -65,7 +66,13 @@ static void archive_add_file_item(browser, is_folder, furi_string_get_cstr(item_path)); } else { with_view_model( - browser->view, ArchiveBrowserViewModel * model, { model->list_loading = false; }, true); + browser->view, + ArchiveBrowserViewModel * model, + { + files_array_sort(model->files); + model->list_loading = false; + }, + true); } } @@ -140,7 +147,7 @@ void archive_update_focus(ArchiveBrowserView* browser, const char* target) { archive_get_items(browser, furi_string_get_cstr(browser->path)); if(!archive_file_get_array_size(browser) && archive_is_home(browser)) { - archive_switch_tab(browser, TAB_RIGHT); + archive_switch_tab(browser, TAB_LEFT); } else { with_view_model( browser->view, @@ -207,7 +214,7 @@ void archive_file_array_rm_selected(ArchiveBrowserView* browser) { false); if((items_cnt == 0) && (archive_is_home(browser))) { - archive_switch_tab(browser, TAB_RIGHT); + archive_switch_tab(browser, TAB_LEFT); } archive_update_offset(browser); @@ -456,6 +463,13 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) { } else { tab = (tab + 1) % ArchiveTabTotal; } + if(tab == ArchiveTabInternal && !furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + if(key == InputKeyLeft) { + tab = ((tab - 1) + ArchiveTabTotal) % ArchiveTabTotal; + } else { + tab = (tab + 1) % ArchiveTabTotal; + } + } browser->is_root = true; archive_set_tab(browser, tab); diff --git a/applications/main/archive/helpers/archive_browser.h b/applications/main/archive/helpers/archive_browser.h index 09ffea1f9c..43a9a651a4 100644 --- a/applications/main/archive/helpers/archive_browser.h +++ b/applications/main/archive/helpers/archive_browser.h @@ -3,7 +3,7 @@ #include "../archive_i.h" #include -#define TAB_RIGHT InputKeyRight // Default tab switch direction +#define TAB_LEFT InputKeyLeft // Default tab switch direction #define TAB_DEFAULT ArchiveTabFavorites // Start tab #define FILE_LIST_BUF_LEN 50 @@ -17,6 +17,7 @@ static const char* tab_default_paths[] = { [ArchiveTabBadUsb] = ANY_PATH("badusb"), [ArchiveTabU2f] = "/app:u2f", [ArchiveTabApplications] = ANY_PATH("apps"), + [ArchiveTabInternal] = STORAGE_INT_PATH_PREFIX, [ArchiveTabBrowser] = STORAGE_ANY_PATH_PREFIX, }; @@ -44,6 +45,7 @@ static const ArchiveFileTypeEnum known_type[] = { [ArchiveTabBadUsb] = ArchiveFileTypeBadUsb, [ArchiveTabU2f] = ArchiveFileTypeU2f, [ArchiveTabApplications] = ArchiveFileTypeApplication, + [ArchiveTabInternal] = ArchiveFileTypeUnknown, [ArchiveTabBrowser] = ArchiveFileTypeUnknown, }; diff --git a/applications/main/archive/helpers/archive_files.h b/applications/main/archive/helpers/archive_files.h index d2cd93a667..6acdb22136 100644 --- a/applications/main/archive/helpers/archive_files.h +++ b/applications/main/archive/helpers/archive_files.h @@ -2,6 +2,7 @@ #include #include +#include #include #include "toolbox/path.h" @@ -81,13 +82,29 @@ static void ArchiveFile_t_clear(ArchiveFile_t* obj) { furi_string_free(obj->custom_name); } -ARRAY_DEF( - files_array, - ArchiveFile_t, - (INIT(API_2(ArchiveFile_t_init)), - SET(API_6(ArchiveFile_t_set)), - INIT_SET(API_6(ArchiveFile_t_init_set)), - CLEAR(API_2(ArchiveFile_t_clear)))) +static int ArchiveFile_t_cmp(const ArchiveFile_t* a, const ArchiveFile_t* b) { + if(a->type == ArchiveFileTypeFolder && b->type != ArchiveFileTypeFolder) { + return -1; + } + if(a->type != ArchiveFileTypeFolder && b->type == ArchiveFileTypeFolder) { + return 1; + } + + return furi_string_cmpi(a->path, b->path); +} + +#define M_OPL_ArchiveFile_t() \ + (INIT(API_2(ArchiveFile_t_init)), \ + SET(API_6(ArchiveFile_t_set)), \ + INIT_SET(API_6(ArchiveFile_t_init_set)), \ + CLEAR(API_2(ArchiveFile_t_clear)), \ + CMP(API_6(ArchiveFile_t_cmp)), \ + SWAP(M_SWAP_DEFAULT), \ + EQUAL(API_6(M_EQUAL_DEFAULT))) + +ARRAY_DEF(files_array, ArchiveFile_t) + +ALGO_DEF(files_array, ARRAY_OPLIST(files_array, M_OPL_ArchiveFile_t())) void archive_set_file_type(ArchiveFile_t* file, const char* path, bool is_folder, bool is_app); bool archive_get_items(void* context, const char* path); diff --git a/applications/main/archive/views/archive_browser_view.c b/applications/main/archive/views/archive_browser_view.c index dce753fde9..26ed17d75d 100644 --- a/applications/main/archive/views/archive_browser_view.c +++ b/applications/main/archive/views/archive_browser_view.c @@ -19,6 +19,7 @@ static const char* ArchiveTabNames[] = { [ArchiveTabBadUsb] = "Bad USB", [ArchiveTabU2f] = "U2F", [ArchiveTabApplications] = "Apps", + [ArchiveTabInternal] = "Internal", [ArchiveTabBrowser] = "Browser", }; diff --git a/applications/main/archive/views/archive_browser_view.h b/applications/main/archive/views/archive_browser_view.h index 482a675e3c..6e6582405f 100644 --- a/applications/main/archive/views/archive_browser_view.h +++ b/applications/main/archive/views/archive_browser_view.h @@ -2,7 +2,6 @@ #include "../helpers/archive_files.h" #include "../helpers/archive_favorites.h" -#include "../helpers/archive_menu.h" #include #include @@ -10,7 +9,10 @@ #include #include #include -#include +#include "../helpers/archive_files.h" +#include "../helpers/archive_menu.h" +#include "../helpers/archive_favorites.h" +#include "gui/modules/file_browser_worker.h" #define MAX_LEN_PX 110 #define MAX_NAME_LEN 255 @@ -29,6 +31,7 @@ typedef enum { ArchiveTabBadUsb, ArchiveTabU2f, ArchiveTabApplications, + ArchiveTabInternal, ArchiveTabBrowser, ArchiveTabTotal, } ArchiveTabEnum; diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index 39e89e9e95..78295f08ce 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -208,27 +208,38 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { flipper_format_free(temp_fm_preset2); - // # HND - FM presets + // Pagers FlipperFormat* temp_fm_preset3 = flipper_format_string_alloc(); flipper_format_write_string_cstr( temp_fm_preset3, (const char*)"Custom_preset_data", - (const char*)"02 0D 0B 06 08 32 07 04 14 00 13 02 12 04 11 36 10 69 15 32 18 18 19 16 1D 91 1C 00 1B 07 20 FB 22 10 21 56 00 00 C0 00 00 00 00 00 00 00"); + (const char*)"02 0D 07 04 08 32 0B 06 10 64 11 93 12 0C 13 02 14 00 15 15 18 18 19 16 1B 07 1C 00 1D 91 20 FB 21 56 22 10 00 00 C0 00 00 00 00 00 00 00"); flipper_format_rewind(temp_fm_preset3); - subghz_setting_load_custom_preset(subghz->setting, (const char*)"HND_1", temp_fm_preset3); + subghz_setting_load_custom_preset(subghz->setting, (const char*)"Pagers", temp_fm_preset3); flipper_format_free(temp_fm_preset3); + // # HND - FM presets FlipperFormat* temp_fm_preset4 = flipper_format_string_alloc(); flipper_format_write_string_cstr( temp_fm_preset4, (const char*)"Custom_preset_data", - (const char*)"02 0D 0B 06 08 32 07 04 14 00 13 02 12 07 11 36 10 E9 15 32 18 18 19 16 1D 92 1C 40 1B 03 20 FB 22 10 21 56 00 00 C0 00 00 00 00 00 00 00"); + (const char*)"02 0D 0B 06 08 32 07 04 14 00 13 02 12 04 11 36 10 69 15 32 18 18 19 16 1D 91 1C 00 1B 07 20 FB 22 10 21 56 00 00 C0 00 00 00 00 00 00 00"); flipper_format_rewind(temp_fm_preset4); - subghz_setting_load_custom_preset(subghz->setting, (const char*)"HND_2", temp_fm_preset4); + subghz_setting_load_custom_preset(subghz->setting, (const char*)"HND_1", temp_fm_preset4); flipper_format_free(temp_fm_preset4); + FlipperFormat* temp_fm_preset5 = flipper_format_string_alloc(); + flipper_format_write_string_cstr( + temp_fm_preset5, + (const char*)"Custom_preset_data", + (const char*)"02 0D 0B 06 08 32 07 04 14 00 13 02 12 07 11 36 10 E9 15 32 18 18 19 16 1D 92 1C 40 1B 03 20 FB 22 10 21 56 00 00 C0 00 00 00 00 00 00 00"); + flipper_format_rewind(temp_fm_preset5); + subghz_setting_load_custom_preset(subghz->setting, (const char*)"HND_2", temp_fm_preset5); + + flipper_format_free(temp_fm_preset5); + // custom presets loading - end // Load last used values for Read, Read RAW, etc. or default diff --git a/applications/main/subghz/views/subghz_frequency_analyzer.c b/applications/main/subghz/views/subghz_frequency_analyzer.c index 9fa304e908..24f24c39d6 100644 --- a/applications/main/subghz/views/subghz_frequency_analyzer.c +++ b/applications/main/subghz/views/subghz_frequency_analyzer.c @@ -25,7 +25,7 @@ static const uint32_t subghz_frequency_list[] = { 310000000, 312000000, 312100000, 313000000, 313850000, 314000000, 314350000, 314980000, 315000000, 318000000, 330000000, 345000000, 348000000, 350000000, 387000000, 390000000, 418000000, 433075000, 433220000, 433420000, 433657070, 433889000, 433920000, 434075000, - 434176948, 434390000, 434420000, 434775000, 438900000, 440175000, 464000000, 779000000, + 434176948, 434390000, 434420000, 434775000, 438900000, 440175000, 464000000, 467750000, 779000000, 868350000, 868400000, 868800000, 868950000, 906400000, 915000000, 925000000, 928000000}; typedef enum { @@ -645,4 +645,4 @@ SubGHzFrequencyAnalyzerFeedbackLevel subghz_frequency_analyzer_feedback_level( float subghz_frequency_analyzer_get_trigger_level(SubGhzFrequencyAnalyzer* instance) { furi_assert(instance); return subghz_frequency_analyzer_worker_get_trigger_level(instance->worker); -} \ No newline at end of file +} diff --git a/applications/main/subghz/views/subghz_test_carrier.c b/applications/main/subghz/views/subghz_test_carrier.c index 0cc9a29667..2cbde6e323 100644 --- a/applications/main/subghz/views/subghz_test_carrier.c +++ b/applications/main/subghz/views/subghz_test_carrier.c @@ -120,7 +120,10 @@ bool subghz_test_carrier_input(InputEvent* event, void* context) { furi_hal_subghz_rx(); } else { furi_hal_gpio_init( - furi_hal_subghz.cc1101_g0_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_hal_subghz.cc1101_g0_pin, + GpioModeOutputPushPull, + GpioPullNo, + GpioSpeedLow); furi_hal_gpio_write(furi_hal_subghz.cc1101_g0_pin, true); if(!furi_hal_subghz_tx()) { furi_hal_gpio_init( diff --git a/applications/services/gui/modules/file_browser.c b/applications/services/gui/modules/file_browser.c index d12a00ba59..dc3c65eedc 100644 --- a/applications/services/gui/modules/file_browser.c +++ b/applications/services/gui/modules/file_browser.c @@ -11,6 +11,7 @@ #include #include #include +#include "m-algo.h" #include #define LIST_ITEMS 5u @@ -77,13 +78,36 @@ static void BrowserItem_t_clear(BrowserItem_t* obj) { } } -ARRAY_DEF( - items_array, - BrowserItem_t, - (INIT(API_2(BrowserItem_t_init)), - SET(API_6(BrowserItem_t_set)), - INIT_SET(API_6(BrowserItem_t_init_set)), - CLEAR(API_2(BrowserItem_t_clear)))) +static int BrowserItem_t_cmp(const BrowserItem_t* a, const BrowserItem_t* b) { + // Back indicator comes before everything, then folders, then all other files. + if(a->type == BrowserItemTypeBack) { + return -1; + } + if(b->type == BrowserItemTypeBack) { + return 1; + } + if(a->type == BrowserItemTypeFolder && b->type != BrowserItemTypeFolder) { + return -1; + } + if(a->type != BrowserItemTypeFolder && b->type == BrowserItemTypeFolder) { + return 1; + } + + return furi_string_cmpi(a->path, b->path); +} + +#define M_OPL_BrowserItem_t() \ + (INIT(API_2(BrowserItem_t_init)), \ + SET(API_6(BrowserItem_t_set)), \ + INIT_SET(API_6(BrowserItem_t_init_set)), \ + CLEAR(API_2(BrowserItem_t_clear)), \ + CMP(API_6(BrowserItem_t_cmp)), \ + SWAP(M_SWAP_DEFAULT), \ + EQUAL(API_6(M_EQUAL_DEFAULT))) + +ARRAY_DEF(items_array, BrowserItem_t) + +ALGO_DEF(items_array, ARRAY_OPLIST(items_array, M_OPL_BrowserItem_t())) struct FileBrowser { View* view; @@ -438,7 +462,13 @@ static void } } else { with_view_model( - browser->view, FileBrowserModel * model, { model->list_loading = false; }, true); + browser->view, + FileBrowserModel * model, + { + items_array_sort(model->items); + model->list_loading = false; + }, + true); } } @@ -485,19 +515,25 @@ static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) { for(uint32_t i = 0; i < MIN(model->item_cnt, LIST_ITEMS); i++) { int32_t idx = CLAMP((uint32_t)(i + model->list_offset), model->item_cnt, 0u); - BrowserItemType item_type = BrowserItemTypeLoading; + BrowserItemType item_type; uint8_t* custom_icon_data = NULL; if(browser_is_item_in_array(model, idx)) { BrowserItem_t* item = items_array_get( model->items, CLAMP(idx - model->array_offset, (int32_t)(array_size - 1), 0)); item_type = item->type; - furi_string_set(filename, item->display_name); - if(item_type == BrowserItemTypeFile) { - custom_icon_data = item->custom_icon_data; + if(model->list_loading && item_type != BrowserItemTypeBack) { + furi_string_set(filename, "---"); + item_type = BrowserItemTypeLoading; + } else { + furi_string_set(filename, item->display_name); + if(item_type == BrowserItemTypeFile) { + custom_icon_data = item->custom_icon_data; + } } } else { furi_string_set(filename, "---"); + item_type = BrowserItemTypeLoading; } if(item_type == BrowserItemTypeBack) { diff --git a/applications/services/gui/modules/file_browser_worker.c b/applications/services/gui/modules/file_browser_worker.c index 80c4f4c43a..4b7be70a12 100644 --- a/applications/services/gui/modules/file_browser_worker.c +++ b/applications/services/gui/modules/file_browser_worker.c @@ -202,55 +202,58 @@ static bool uint32_t items_cnt = 0; + bool ret = false; do { if(!storage_dir_open(directory, furi_string_get_cstr(path))) { break; } - items_cnt = 0; - while(items_cnt < offset) { - if(!storage_dir_read(directory, &file_info, name_temp, FILE_NAME_LEN_MAX)) { - break; - } - if(storage_file_get_error(directory) == FSE_OK) { - furi_string_set(name_str, name_temp); - if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) { - items_cnt++; - } - } else { - break; - } - } - if(items_cnt != offset) { - break; - } - + // items_cnt = 0; + // while(items_cnt < offset) { + // if(!storage_dir_read(directory, &file_info, name_temp, FILE_NAME_LEN_MAX)) { + // break; + // } + // if(storage_file_get_error(directory) == FSE_OK) { + // furi_string_set(name_str, name_temp); + // if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) { + // items_cnt++; + // } + // } else { + // break; + // } + // } + // if(items_cnt != offset) { + // break; + // } + + // FLIPPER DEVS MOMENT + // this used to load the file list in chunks, and then sort it... + // so while scrolling, it loads more files and sorts them... + // chances are, the new files are higher in the sorted list... + // so the files keep shifting around while scrolling... + // now this does something intelligent and loads all in one go. + // might take a few milliseconds longer, but atleast it works :kekw: + UNUSED(offset); + UNUSED(count); if(browser->list_load_cb) { - browser->list_load_cb(browser->cb_ctx, offset); + browser->list_load_cb(browser->cb_ctx, 0); } - - items_cnt = 0; - while(items_cnt < count) { - if(!storage_dir_read(directory, &file_info, name_temp, FILE_NAME_LEN_MAX)) { - break; - } - if(storage_file_get_error(directory) == FSE_OK) { - furi_string_set(name_str, name_temp); - if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) { - furi_string_printf(name_str, "%s/%s", furi_string_get_cstr(path), name_temp); - if(browser->list_item_cb) { - browser->list_item_cb( - browser->cb_ctx, name_str, (file_info.flags & FSF_DIRECTORY), false); - } - items_cnt++; + while(storage_dir_read(directory, &file_info, name_temp, FILE_NAME_LEN_MAX) && + storage_file_get_error(directory) == FSE_OK) { + furi_string_set(name_str, name_temp); + if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) { + furi_string_printf(name_str, "%s/%s", furi_string_get_cstr(path), name_temp); + if(browser->list_item_cb) { + browser->list_item_cb( + browser->cb_ctx, name_str, (file_info.flags & FSF_DIRECTORY), false); } - } else { - break; + items_cnt++; } } if(browser->list_item_cb) { browser->list_item_cb(browser->cb_ctx, NULL, false, true); } + ret = true; } while(0); furi_string_free(name_str); @@ -260,7 +263,7 @@ static bool furi_record_close(RECORD_STORAGE); - return (items_cnt == count); + return ret; } static int32_t browser_worker(void* context) { diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 3cc1c5c949..8ed3259faf 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1146,13 +1146,23 @@ Function,+,furi_hal_i2c_tx,_Bool,"FuriHalI2cBusHandle*, const uint8_t, const uin Function,+,furi_hal_i2c_write_mem,_Bool,"FuriHalI2cBusHandle*, uint8_t, uint8_t, uint8_t*, uint8_t, uint32_t" Function,+,furi_hal_i2c_write_reg_16,_Bool,"FuriHalI2cBusHandle*, uint8_t, uint8_t, uint16_t, uint32_t" Function,+,furi_hal_i2c_write_reg_8,_Bool,"FuriHalI2cBusHandle*, uint8_t, uint8_t, uint8_t, uint32_t" +Function,+,furi_hal_ibutton_add_interrupt,void,"GpioExtiCallback, void*" Function,+,furi_hal_ibutton_emulate_set_next,void,uint32_t Function,+,furi_hal_ibutton_emulate_start,void,"uint32_t, FuriHalIbuttonEmulateCallback, void*" Function,+,furi_hal_ibutton_emulate_stop,void, Function,-,furi_hal_ibutton_init,void, Function,+,furi_hal_ibutton_pin_configure,void, +Function,+,furi_hal_ibutton_pin_get_level,_Bool, +Function,+,furi_hal_ibutton_pin_high,void, +Function,+,furi_hal_ibutton_pin_low,void, Function,+,furi_hal_ibutton_pin_reset,void, Function,+,furi_hal_ibutton_pin_write,void,const _Bool +Function,+,furi_hal_ibutton_remove_interrupt,void, +Function,+,furi_hal_ibutton_start_drive,void, +Function,+,furi_hal_ibutton_start_drive_in_isr,void, +Function,+,furi_hal_ibutton_start_interrupt,void, +Function,+,furi_hal_ibutton_start_interrupt_in_isr,void, +Function,+,furi_hal_ibutton_stop,void, Function,+,furi_hal_info_get,void,"PropertyValueCallback, char, void*" Function,+,furi_hal_infrared_async_rx_set_capture_isr_callback,void,"FuriHalInfraredRxCaptureCallback, void*" Function,+,furi_hal_infrared_async_rx_set_timeout,void,uint32_t diff --git a/firmware/targets/f7/furi_hal/furi_hal_ibutton.c b/firmware/targets/f7/furi_hal/furi_hal_ibutton.c index c05cd69a82..3afb524182 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_ibutton.c +++ b/firmware/targets/f7/furi_hal/furi_hal_ibutton.c @@ -89,6 +89,51 @@ void furi_hal_ibutton_emulate_stop() { } } +void furi_hal_ibutton_start_drive() { + furi_hal_ibutton_pin_high(); + furi_hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); +} + +void furi_hal_ibutton_start_drive_in_isr() { + furi_hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); + LL_EXTI_ClearFlag_0_31(ibutton_gpio.pin); +} + +void furi_hal_ibutton_start_interrupt() { + furi_hal_ibutton_pin_high(); + furi_hal_gpio_init(&ibutton_gpio, GpioModeInterruptRiseFall, GpioPullNo, GpioSpeedLow); +} + +void furi_hal_ibutton_start_interrupt_in_isr() { + furi_hal_gpio_init(&ibutton_gpio, GpioModeInterruptRiseFall, GpioPullNo, GpioSpeedLow); + LL_EXTI_ClearFlag_0_31(ibutton_gpio.pin); +} + +void furi_hal_ibutton_stop() { + furi_hal_ibutton_pin_high(); + furi_hal_gpio_init(&ibutton_gpio, GpioModeAnalog, GpioPullNo, GpioSpeedLow); +} + +void furi_hal_ibutton_add_interrupt(GpioExtiCallback cb, void* context) { + furi_hal_gpio_add_int_callback(&ibutton_gpio, cb, context); +} + +void furi_hal_ibutton_remove_interrupt() { + furi_hal_gpio_remove_int_callback(&ibutton_gpio); +} + +void furi_hal_ibutton_pin_low() { + furi_hal_gpio_write(&ibutton_gpio, false); +} + +void furi_hal_ibutton_pin_high() { + furi_hal_gpio_write(&ibutton_gpio, true); +} + +bool furi_hal_ibutton_pin_get_level() { + return furi_hal_gpio_read(&ibutton_gpio); +} + void furi_hal_ibutton_pin_configure() { furi_hal_gpio_write(&ibutton_gpio, true); furi_hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); @@ -101,4 +146,4 @@ void furi_hal_ibutton_pin_reset() { void furi_hal_ibutton_pin_write(const bool state) { furi_hal_gpio_write(&ibutton_gpio, state); -} +} \ No newline at end of file diff --git a/firmware/targets/f7/furi_hal/furi_hal_ibutton.h b/firmware/targets/f7/furi_hal/furi_hal_ibutton.h index b723fe1768..c71c216d66 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_ibutton.h +++ b/firmware/targets/f7/furi_hal/furi_hal_ibutton.h @@ -7,6 +7,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -17,27 +18,70 @@ typedef void (*FuriHalIbuttonEmulateCallback)(void* context); /** Initialize */ void furi_hal_ibutton_init(); -/** - * Start emulation timer - * @param period timer period - * @param callback timer callback - * @param context callback context - */ void furi_hal_ibutton_emulate_start( uint32_t period, FuriHalIbuttonEmulateCallback callback, void* context); +void furi_hal_ibutton_emulate_set_next(uint32_t period); + +void furi_hal_ibutton_emulate_stop(); + /** - * Update emulation timer period - * @param period new timer period + * Sets the pin to normal mode (open collector), and sets it to float */ -void furi_hal_ibutton_emulate_set_next(uint32_t period); +void furi_hal_ibutton_start_drive(); /** - * Stop emulation timer + * Sets the pin to normal mode (open collector), and clears pin EXTI interrupt. + * Used in EXTI interrupt context. */ -void furi_hal_ibutton_emulate_stop(); +void furi_hal_ibutton_start_drive_in_isr(); + +/** + * Sets the pin to interrupt mode (EXTI interrupt on rise or fall), and sets it to float + */ +void furi_hal_ibutton_start_interrupt(); + +/** + * Sets the pin to interrupt mode (EXTI interrupt on rise or fall), and clears pin EXTI interrupt. + * Used in EXTI interrupt context. + */ +void furi_hal_ibutton_start_interrupt_in_isr(); + +/** + * Sets the pin to analog mode, and sets it to float + */ +void furi_hal_ibutton_stop(); + +/** + * Attach interrupt callback to iButton pin + * @param cb callback + * @param context context + */ +void furi_hal_ibutton_add_interrupt(GpioExtiCallback cb, void* context); + +/** + * Remove interrupt callback from iButton pin + */ +void furi_hal_ibutton_remove_interrupt(); + +/** + * Sets the pin to low + */ +void furi_hal_ibutton_pin_low(); + +/** + * Sets the pin to high (float in iButton pin modes) + */ +void furi_hal_ibutton_pin_high(); + +/** + * Get pin level + * @return true if level is high + * @return false if level is low + */ +bool furi_hal_ibutton_pin_get_level(); /** * Set the pin to normal mode (open collector), and sets it to float diff --git a/firmware/targets/f7/furi_hal/furi_hal_rfid.c b/firmware/targets/f7/furi_hal/furi_hal_rfid.c index 145e49df2c..b0238f79f2 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_rfid.c +++ b/firmware/targets/f7/furi_hal/furi_hal_rfid.c @@ -77,7 +77,7 @@ void furi_hal_rfid_init() { void furi_hal_rfid_pins_reset() { // ibutton bus disable - furi_hal_ibutton_pin_reset(); + furi_hal_ibutton_stop(); // pulldown rfid antenna furi_hal_gpio_init(&gpio_rfid_carrier_out, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); @@ -94,8 +94,8 @@ void furi_hal_rfid_pins_reset() { void furi_hal_rfid_pins_emulate() { // ibutton low - furi_hal_ibutton_pin_configure(); - furi_hal_ibutton_pin_write(false); + furi_hal_ibutton_start_drive(); + furi_hal_ibutton_pin_low(); // pull pin to timer out furi_hal_gpio_init_ex( @@ -115,8 +115,8 @@ void furi_hal_rfid_pins_emulate() { void furi_hal_rfid_pins_read() { // ibutton low - furi_hal_ibutton_pin_configure(); - furi_hal_ibutton_pin_write(false); + furi_hal_ibutton_start_drive(); + furi_hal_ibutton_pin_low(); // dont pull rfid antenna furi_hal_gpio_init(&gpio_nfc_irq_rfid_pull, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index 27b2845292..688ec4ba41 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -44,13 +44,15 @@ volatile FuriHalSubGhz furi_hal_subghz = { bool furi_hal_subghz_set_radio_type(SubGhzRadioType state) { furi_hal_subghz.radio_type = state; furi_hal_spi_bus_handle_deinit(furi_hal_subghz.spi_bus_handle); - if(state) { - furi_hal_subghz.spi_bus_handle = &furi_hal_spi_bus_handle_subghz_ext; - furi_hal_subghz.cc1101_g0_pin = &gpio_cc1101_g0_ext; - } else { + + if(furi_hal_subghz.radio_type == SubGhzRadioInternal) { furi_hal_subghz.spi_bus_handle = &furi_hal_spi_bus_handle_subghz; furi_hal_subghz.cc1101_g0_pin = &gpio_cc1101_g0; + } else { + furi_hal_subghz.spi_bus_handle = &furi_hal_spi_bus_handle_subghz_ext; + furi_hal_subghz.cc1101_g0_pin = &gpio_cc1101_g0_ext; } + furi_hal_spi_bus_handle_init(furi_hal_subghz.spi_bus_handle); furi_hal_subghz_init_check(); return true; @@ -121,37 +123,26 @@ bool furi_hal_subghz_init_check(void) { // Prepare GD0 for power on self test furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow); - if(furi_hal_subghz.radio_type == SubGhzRadioExternal) { - // GD0 low - cc1101_write_reg(furi_hal_subghz.spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHW); - uint32_t test_start_time = furi_get_tick(); - while(furi_hal_gpio_read(furi_hal_subghz.cc1101_g0_pin) != false && result) { - if(furi_get_tick() - test_start_time > INIT_TIMEOUT) { - result = false; - } - } - // GD0 high - cc1101_write_reg( - furi_hal_subghz.spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); - test_start_time = furi_get_tick(); - while(furi_hal_gpio_read(furi_hal_subghz.cc1101_g0_pin) != true && result) { - if(furi_get_tick() - test_start_time > INIT_TIMEOUT) { - result = false; - } + // GD0 low + cc1101_write_reg(furi_hal_subghz.spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHW); + uint32_t test_start_time = furi_get_tick(); + while(furi_hal_gpio_read(furi_hal_subghz.cc1101_g0_pin) != false && result) { + if(furi_get_tick() - test_start_time > INIT_TIMEOUT) { + result = false; } - } else { - // GD0 low - cc1101_write_reg(furi_hal_subghz.spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHW); - while(furi_hal_gpio_read(&gpio_cc1101_g0) != false) - ; + } - // GD0 high - cc1101_write_reg( - furi_hal_subghz.spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); - while(furi_hal_gpio_read(&gpio_cc1101_g0) != true) - ; + // GD0 high + cc1101_write_reg( + furi_hal_subghz.spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); + test_start_time = furi_get_tick(); + while(furi_hal_gpio_read(furi_hal_subghz.cc1101_g0_pin) != true && result) { + if(furi_get_tick() - test_start_time > INIT_TIMEOUT) { + result = false; + } } + // Reset GD0 to floating state cc1101_write_reg(furi_hal_subghz.spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHighImpedance); furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); @@ -433,8 +424,8 @@ bool furi_hal_subghz_is_tx_allowed(uint32_t value) { flipper_format_free(fff_data_file); furi_record_close(RECORD_STORAGE); - if(!(value >= 299999755 && value <= 350000335) && - !(value >= 386999938 && value <= 464000000) && + if(!(value >= 299999755 && value <= 350000335) && // was increased from 348 to 350 + !(value >= 386999938 && value <= 467750000) && // was increased from 464 to 467.75 !(value >= 778999847 && value <= 928000000) && !(is_extended)) { FURI_LOG_I(TAG, "Frequency blocked - outside default range"); return false; @@ -514,56 +505,55 @@ volatile uint32_t furi_hal_subghz_capture_delta_duration = 0; volatile FuriHalSubGhzCaptureCallback furi_hal_subghz_capture_callback = NULL; volatile void* furi_hal_subghz_capture_callback_context = NULL; -static void furi_hal_subghz_capture_ISR() { - if(furi_hal_subghz.radio_type == SubGhzRadioExternal) { - if(!furi_hal_gpio_read(furi_hal_subghz.cc1101_g0_pin)) { - if(furi_hal_subghz_capture_callback) { - if(furi_hal_subghz.async_mirror_pin != NULL) - furi_hal_gpio_write(furi_hal_subghz.async_mirror_pin, false); +static void furi_hal_subghz_capture_int_ISR() { + // Channel 1 + if(LL_TIM_IsActiveFlag_CC1(TIM2)) { + LL_TIM_ClearFlag_CC1(TIM2); + furi_hal_subghz_capture_delta_duration = LL_TIM_IC_GetCaptureCH1(TIM2); + if(furi_hal_subghz_capture_callback) { + if(furi_hal_subghz.async_mirror_pin != NULL) + furi_hal_gpio_write(furi_hal_subghz.async_mirror_pin, false); + + furi_hal_subghz_capture_callback( + true, + furi_hal_subghz_capture_delta_duration, + (void*)furi_hal_subghz_capture_callback_context); + } + } + // Channel 2 + if(LL_TIM_IsActiveFlag_CC2(TIM2)) { + LL_TIM_ClearFlag_CC2(TIM2); + if(furi_hal_subghz_capture_callback) { + if(furi_hal_subghz.async_mirror_pin != NULL) + furi_hal_gpio_write(furi_hal_subghz.async_mirror_pin, true); + + furi_hal_subghz_capture_callback( + false, + LL_TIM_IC_GetCaptureCH2(TIM2) - furi_hal_subghz_capture_delta_duration, + (void*)furi_hal_subghz_capture_callback_context); + } + } +} - furi_hal_subghz_capture_callback( - true, TIM2->CNT, (void*)furi_hal_subghz_capture_callback_context); - } - } else { - if(furi_hal_subghz_capture_callback) { - if(furi_hal_subghz.async_mirror_pin != NULL) - furi_hal_gpio_write(furi_hal_subghz.async_mirror_pin, true); +static void furi_hal_subghz_capture_ext_ISR() { + if(!furi_hal_gpio_read(furi_hal_subghz.cc1101_g0_pin)) { + if(furi_hal_subghz_capture_callback) { + if(furi_hal_subghz.async_mirror_pin != NULL) + furi_hal_gpio_write(furi_hal_subghz.async_mirror_pin, false); - furi_hal_subghz_capture_callback( - false, TIM2->CNT, (void*)furi_hal_subghz_capture_callback_context); - } + furi_hal_subghz_capture_callback( + true, TIM2->CNT, (void*)furi_hal_subghz_capture_callback_context); } - //Forced correction for improved accuracy - TIM2->CNT = 7; } else { - // Channel 1 - if(LL_TIM_IsActiveFlag_CC1(TIM2)) { - LL_TIM_ClearFlag_CC1(TIM2); - furi_hal_subghz_capture_delta_duration = LL_TIM_IC_GetCaptureCH1(TIM2); - if(furi_hal_subghz_capture_callback) { - if(furi_hal_subghz.async_mirror_pin != NULL) - furi_hal_gpio_write(furi_hal_subghz.async_mirror_pin, false); - - furi_hal_subghz_capture_callback( - true, - furi_hal_subghz_capture_delta_duration, - (void*)furi_hal_subghz_capture_callback_context); - } - } - // Channel 2 - if(LL_TIM_IsActiveFlag_CC2(TIM2)) { - LL_TIM_ClearFlag_CC2(TIM2); - if(furi_hal_subghz_capture_callback) { - if(furi_hal_subghz.async_mirror_pin != NULL) - furi_hal_gpio_write(furi_hal_subghz.async_mirror_pin, true); - - furi_hal_subghz_capture_callback( - false, - LL_TIM_IC_GetCaptureCH2(TIM2) - furi_hal_subghz_capture_delta_duration, - (void*)furi_hal_subghz_capture_callback_context); - } + if(furi_hal_subghz_capture_callback) { + if(furi_hal_subghz.async_mirror_pin != NULL) + furi_hal_gpio_write(furi_hal_subghz.async_mirror_pin, true); + + furi_hal_subghz_capture_callback( + false, TIM2->CNT, (void*)furi_hal_subghz_capture_callback_context); } } + TIM2->CNT = 6; } void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* context) { @@ -573,43 +563,27 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* furi_hal_subghz_capture_callback = callback; furi_hal_subghz_capture_callback_context = context; - if(furi_hal_subghz.radio_type == SubGhzRadioExternal) { - furi_hal_gpio_init( - furi_hal_subghz.cc1101_g0_pin, - GpioModeInterruptRiseFall, - GpioPullUp, - GpioSpeedVeryHigh); - furi_hal_gpio_add_int_callback( - furi_hal_subghz.cc1101_g0_pin, - furi_hal_subghz_capture_ISR, - furi_hal_subghz_capture_callback); - furi_hal_gpio_enable_int_callback(furi_hal_subghz.cc1101_g0_pin); - } else { - furi_hal_gpio_init_ex( - &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); - } - // Timer: base LL_TIM_InitTypeDef TIM_InitStruct = {0}; TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct.Autoreload = 0x7FFFFFFE; - TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV4; // Clock division for capture filter + // Clock division for capture filter (for internal radio) + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV4; LL_TIM_Init(TIM2, &TIM_InitStruct); // Timer: advanced LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); LL_TIM_DisableARRPreload(TIM2); + LL_TIM_DisableDMAReq_TRIG(TIM2); + LL_TIM_DisableIT_TRIG(TIM2); + if(furi_hal_subghz.radio_type == SubGhzRadioInternal) { LL_TIM_SetTriggerInput(TIM2, LL_TIM_TS_TI2FP2); LL_TIM_SetSlaveMode(TIM2, LL_TIM_SLAVEMODE_RESET); LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_RESET); LL_TIM_EnableMasterSlaveMode(TIM2); - } - LL_TIM_DisableDMAReq_TRIG(TIM2); - LL_TIM_DisableIT_TRIG(TIM2); - if(furi_hal_subghz.radio_type == SubGhzRadioInternal) { // Timer: channel 1 indirect LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_INDIRECTTI); LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1); @@ -623,13 +597,31 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV32_N8); // ISR setup - furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_subghz_capture_ISR, NULL); + furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_subghz_capture_int_ISR, NULL); // Interrupts and channels LL_TIM_EnableIT_CC1(TIM2); LL_TIM_EnableIT_CC2(TIM2); LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH1); LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2); + + furi_hal_gpio_init_ex( + furi_hal_subghz.cc1101_g0_pin, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedLow, + GpioAltFn1TIM2); + } else { + furi_hal_gpio_init( + furi_hal_subghz.cc1101_g0_pin, + GpioModeInterruptRiseFall, + GpioPullUp, + GpioSpeedVeryHigh); + furi_hal_gpio_add_int_callback( + furi_hal_subghz.cc1101_g0_pin, + furi_hal_subghz_capture_ext_ISR, + furi_hal_subghz_capture_callback); + furi_hal_gpio_enable_int_callback(furi_hal_subghz.cc1101_g0_pin); } // Start timer @@ -662,6 +654,9 @@ void furi_hal_subghz_stop_async_rx() { FURI_CRITICAL_EXIT(); if(furi_hal_subghz.radio_type == SubGhzRadioInternal) { furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL); + } else { + furi_hal_gpio_disable_int_callback(furi_hal_subghz.cc1101_g0_pin); + furi_hal_gpio_remove_int_callback(furi_hal_subghz.cc1101_g0_pin); } furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); @@ -796,18 +791,18 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* furi_hal_subghz_async_tx.buffer = malloc(API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t)); - if(furi_hal_subghz.radio_type == SubGhzRadioExternal) { - furi_hal_gpio_write(furi_hal_subghz.cc1101_g0_pin, true); - furi_hal_gpio_init( - furi_hal_subghz.cc1101_g0_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - } else { + if(furi_hal_subghz.radio_type == SubGhzRadioInternal) { // Connect CC1101_GD0 to TIM2 as output furi_hal_gpio_init_ex( - &gpio_cc1101_g0, + furi_hal_subghz.cc1101_g0_pin, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn1TIM2); + } else { + furi_hal_gpio_write(furi_hal_subghz.cc1101_g0_pin, true); + furi_hal_gpio_init( + furi_hal_subghz.cc1101_g0_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); } // Configure DMA @@ -882,8 +877,10 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* if(((furi_hal_subghz.async_mirror_pin != NULL) && (furi_hal_subghz.radio_type == SubGhzRadioInternal)) || (furi_hal_subghz.radio_type == SubGhzRadioExternal)) { - furi_hal_subghz_debug_gpio_buff[0] = (uint32_t)gpio->pin << GPIO_NUMBER; - furi_hal_subghz_debug_gpio_buff[1] = gpio->pin; + furi_hal_subghz_debug_gpio_buff[0] = + ((uint32_t)gpio->pin << GPIO_NUMBER) | + ((uint32_t)furi_hal_subghz.async_mirror_pin->pin << GPIO_NUMBER); + furi_hal_subghz_debug_gpio_buff[1] = gpio->pin | furi_hal_subghz.async_mirror_pin->pin; dma_config.MemoryOrM2MDstAddress = (uint32_t)furi_hal_subghz_debug_gpio_buff; dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (gpio->port->BSRR); diff --git a/lib/one_wire/ibutton/ibutton_worker_modes.c b/lib/one_wire/ibutton/ibutton_worker_modes.c index da6b107668..b284940e7f 100644 --- a/lib/one_wire/ibutton/ibutton_worker_modes.c +++ b/lib/one_wire/ibutton/ibutton_worker_modes.c @@ -234,13 +234,16 @@ void ibutton_worker_emulate_timer_cb(void* context) { furi_assert(context); iButtonWorker* worker = context; - const LevelDuration level_duration = + LevelDuration level = protocol_dict_encoder_yield(worker->protocols, worker->protocol_to_encode); - const bool level = level_duration_get_level(level_duration); + furi_hal_ibutton_emulate_set_next(level_duration_get_duration(level)); - furi_hal_ibutton_emulate_set_next(level); - furi_hal_ibutton_pin_write(level); + if(level_duration_get_level(level)) { + furi_hal_ibutton_pin_high(); + } else { + furi_hal_ibutton_pin_low(); + } } void ibutton_worker_emulate_timer_start(iButtonWorker* worker) { @@ -263,7 +266,7 @@ void ibutton_worker_emulate_timer_start(iButtonWorker* worker) { protocol_dict_set_data(worker->protocols, worker->protocol_to_encode, key_id, key_size); protocol_dict_encoder_start(worker->protocols, worker->protocol_to_encode); - furi_hal_ibutton_pin_configure(); + furi_hal_ibutton_start_drive(); furi_hal_ibutton_emulate_start(0, ibutton_worker_emulate_timer_cb, worker); } diff --git a/lib/one_wire/one_wire_host.c b/lib/one_wire/one_wire_host.c index f3d3d3c4dc..f65f4cf7aa 100644 --- a/lib/one_wire/one_wire_host.c +++ b/lib/one_wire/one_wire_host.c @@ -1,5 +1,5 @@ #include - +#include #include "one_wire_host.h" #include "one_wire_host_timing.h" @@ -24,47 +24,49 @@ void onewire_host_free(OneWireHost* host) { } bool onewire_host_reset(OneWireHost* host) { + UNUSED(host); uint8_t r; uint8_t retries = 125; // wait until the gpio is high - furi_hal_gpio_write(host->gpio_pin, true); + furi_hal_ibutton_pin_high(); do { if(--retries == 0) return 0; furi_delay_us(2); - } while(!furi_hal_gpio_read(host->gpio_pin)); + } while(!furi_hal_ibutton_pin_get_level()); // pre delay furi_delay_us(OWH_RESET_DELAY_PRE); // drive low - furi_hal_gpio_write(host->gpio_pin, false); + furi_hal_ibutton_pin_low(); furi_delay_us(OWH_RESET_DRIVE); // release - furi_hal_gpio_write(host->gpio_pin, true); + furi_hal_ibutton_pin_high(); furi_delay_us(OWH_RESET_RELEASE); // read and post delay - r = !furi_hal_gpio_read(host->gpio_pin); + r = !furi_hal_ibutton_pin_get_level(); furi_delay_us(OWH_RESET_DELAY_POST); return r; } bool onewire_host_read_bit(OneWireHost* host) { + UNUSED(host); bool result; // drive low - furi_hal_gpio_write(host->gpio_pin, false); + furi_hal_ibutton_pin_low(); furi_delay_us(OWH_READ_DRIVE); // release - furi_hal_gpio_write(host->gpio_pin, true); + furi_hal_ibutton_pin_high(); furi_delay_us(OWH_READ_RELEASE); // read and post delay - result = furi_hal_gpio_read(host->gpio_pin); + result = furi_hal_ibutton_pin_get_level(); furi_delay_us(OWH_READ_DELAY_POST); return result; @@ -89,21 +91,22 @@ void onewire_host_read_bytes(OneWireHost* host, uint8_t* buffer, uint16_t count) } void onewire_host_write_bit(OneWireHost* host, bool value) { + UNUSED(host); if(value) { // drive low - furi_hal_gpio_write(host->gpio_pin, false); + furi_hal_ibutton_pin_low(); furi_delay_us(OWH_WRITE_1_DRIVE); // release - furi_hal_gpio_write(host->gpio_pin, true); + furi_hal_ibutton_pin_high(); furi_delay_us(OWH_WRITE_1_RELEASE); } else { // drive low - furi_hal_gpio_write(host->gpio_pin, false); + furi_hal_ibutton_pin_low(); furi_delay_us(OWH_WRITE_0_DRIVE); // release - furi_hal_gpio_write(host->gpio_pin, true); + furi_hal_ibutton_pin_high(); furi_delay_us(OWH_WRITE_0_RELEASE); } } @@ -121,13 +124,13 @@ void onewire_host_skip(OneWireHost* host) { } void onewire_host_start(OneWireHost* host) { - furi_hal_gpio_write(host->gpio_pin, true); - furi_hal_gpio_init(host->gpio_pin, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); + UNUSED(host); + furi_hal_ibutton_start_drive(); } void onewire_host_stop(OneWireHost* host) { - furi_hal_gpio_write(host->gpio_pin, true); - furi_hal_gpio_init(host->gpio_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + UNUSED(host); + furi_hal_ibutton_stop(); } void onewire_host_reset_search(OneWireHost* host) { @@ -148,7 +151,7 @@ void onewire_host_target_search(OneWireHost* host, uint8_t family_code) { host->last_device_flag = false; } -uint8_t onewire_host_search(OneWireHost* host, uint8_t* new_addr, OneWireHostSearchMode mode) { +uint8_t onewire_host_search(OneWireHost* host, uint8_t* newAddr, OneWireHostSearchMode mode) { uint8_t id_bit_number; uint8_t last_zero, rom_byte_number, search_result; uint8_t id_bit, cmp_id_bit; @@ -257,7 +260,7 @@ uint8_t onewire_host_search(OneWireHost* host, uint8_t* new_addr, OneWireHostSea host->last_family_discrepancy = 0; search_result = false; } else { - for(int i = 0; i < 8; i++) new_addr[i] = host->saved_rom[i]; + for(int i = 0; i < 8; i++) newAddr[i] = host->saved_rom[i]; } return search_result; diff --git a/lib/one_wire/one_wire_host.h b/lib/one_wire/one_wire_host.h index 9c01abc114..6832351870 100644 --- a/lib/one_wire/one_wire_host.h +++ b/lib/one_wire/one_wire_host.h @@ -22,7 +22,7 @@ typedef struct OneWireHost OneWireHost; /** * Allocate onewire host bus - * @param pin + * @param gpio * @return OneWireHost* */ OneWireHost* onewire_host_alloc(const GpioPin* gpio_pin); @@ -114,7 +114,7 @@ void onewire_host_target_search(OneWireHost* host, uint8_t family_code); * @param mode * @return uint8_t */ -uint8_t onewire_host_search(OneWireHost* host, uint8_t* new_addr, OneWireHostSearchMode mode); +uint8_t onewire_host_search(OneWireHost* host, uint8_t* newAddr, OneWireHostSearchMode mode); #ifdef __cplusplus } diff --git a/lib/one_wire/one_wire_slave.c b/lib/one_wire/one_wire_slave.c index 4b54c4f99f..87ec8adc89 100644 --- a/lib/one_wire/one_wire_slave.c +++ b/lib/one_wire/one_wire_slave.c @@ -36,15 +36,15 @@ struct OneWireSlave { /*********************** PRIVATE ***********************/ -static uint32_t - onewire_slave_wait_while_gpio_is(OneWireSlave* bus, uint32_t time, const bool pin_value) { +uint32_t onewire_slave_wait_while_gpio_is(OneWireSlave* bus, uint32_t time, const bool pin_value) { + UNUSED(bus); uint32_t start = DWT->CYCCNT; uint32_t time_ticks = time * furi_hal_cortex_instructions_per_microsecond(); uint32_t time_captured; do { //-V1044 time_captured = DWT->CYCCNT; - if(furi_hal_gpio_read(bus->gpio_pin) != pin_value) { + if(furi_hal_ibutton_pin_get_level() != pin_value) { uint32_t remaining_time = time_ticks - (time_captured - start); remaining_time /= furi_hal_cortex_instructions_per_microsecond(); return remaining_time; @@ -54,14 +54,14 @@ static uint32_t return 0; } -static bool onewire_slave_show_presence(OneWireSlave* bus) { +bool onewire_slave_show_presence(OneWireSlave* bus) { // wait while master delay presence check onewire_slave_wait_while_gpio_is(bus, OWS_PRESENCE_TIMEOUT, true); // show presence - furi_hal_gpio_write(bus->gpio_pin, false); + furi_hal_ibutton_pin_low(); furi_delay_us(OWS_PRESENCE_MIN); - furi_hal_gpio_write(bus->gpio_pin, true); + furi_hal_ibutton_pin_high(); // somebody also can show presence const uint32_t wait_low_time = OWS_PRESENCE_MAX - OWS_PRESENCE_MIN; @@ -75,7 +75,7 @@ static bool onewire_slave_show_presence(OneWireSlave* bus) { return true; } -static bool onewire_slave_receive_bit(OneWireSlave* bus) { +bool onewire_slave_receive_bit(OneWireSlave* bus) { // wait while bus is low uint32_t time = OWS_SLOT_MAX; time = onewire_slave_wait_while_gpio_is(bus, time, false); @@ -99,7 +99,7 @@ static bool onewire_slave_receive_bit(OneWireSlave* bus) { return (time > 0); } -static bool onewire_slave_send_bit(OneWireSlave* bus, bool value) { +bool onewire_slave_send_bit(OneWireSlave* bus, bool value) { const bool write_zero = !value; // wait while bus is low @@ -120,7 +120,7 @@ static bool onewire_slave_send_bit(OneWireSlave* bus, bool value) { // choose write time if(write_zero) { - furi_hal_gpio_write(bus->gpio_pin, false); + furi_hal_ibutton_pin_low(); time = OWS_WRITE_ZERO; } else { time = OWS_READ_MAX; @@ -128,12 +128,12 @@ static bool onewire_slave_send_bit(OneWireSlave* bus, bool value) { // hold line for ZERO or ONE time furi_delay_us(time); - furi_hal_gpio_write(bus->gpio_pin, true); + furi_hal_ibutton_pin_high(); return true; } -static void onewire_slave_cmd_search_rom(OneWireSlave* bus) { +void onewire_slave_cmd_search_rom(OneWireSlave* bus) { const uint8_t key_bytes = 8; uint8_t* key = onewire_device_get_id_p(bus->device); @@ -152,7 +152,7 @@ static void onewire_slave_cmd_search_rom(OneWireSlave* bus) { } } -static bool onewire_slave_receive_and_process_cmd(OneWireSlave* bus) { +bool onewire_slave_receive_and_process_cmd(OneWireSlave* bus) { uint8_t cmd; onewire_slave_receive(bus, &cmd, 1); @@ -179,14 +179,14 @@ static bool onewire_slave_receive_and_process_cmd(OneWireSlave* bus) { } } -static bool onewire_slave_bus_start(OneWireSlave* bus) { +bool onewire_slave_bus_start(OneWireSlave* bus) { bool result = true; if(bus->device == NULL) { result = false; } else { FURI_CRITICAL_ENTER(); - furi_hal_gpio_init(bus->gpio_pin, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); + furi_hal_ibutton_start_drive_in_isr(); bus->error = NO_ERROR; if(onewire_slave_show_presence(bus)) { @@ -198,7 +198,7 @@ static bool onewire_slave_bus_start(OneWireSlave* bus) { result = false; } - furi_hal_gpio_init(bus->gpio_pin, GpioModeInterruptRiseFall, GpioPullNo, GpioSpeedLow); + furi_hal_ibutton_start_interrupt_in_isr(); FURI_CRITICAL_EXIT(); } @@ -208,7 +208,7 @@ static bool onewire_slave_bus_start(OneWireSlave* bus) { static void exti_cb(void* context) { OneWireSlave* bus = context; - volatile bool input_state = furi_hal_gpio_read(bus->gpio_pin); + volatile bool input_state = furi_hal_ibutton_pin_get_level(); static uint32_t pulse_start = 0; if(input_state) { @@ -251,15 +251,14 @@ void onewire_slave_free(OneWireSlave* bus) { } void onewire_slave_start(OneWireSlave* bus) { - furi_hal_gpio_add_int_callback(bus->gpio_pin, exti_cb, bus); - furi_hal_gpio_write(bus->gpio_pin, true); - furi_hal_gpio_init(bus->gpio_pin, GpioModeInterruptRiseFall, GpioPullNo, GpioSpeedLow); + furi_hal_ibutton_add_interrupt(exti_cb, bus); + furi_hal_ibutton_start_interrupt(); } void onewire_slave_stop(OneWireSlave* bus) { - furi_hal_gpio_write(bus->gpio_pin, true); - furi_hal_gpio_init(bus->gpio_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_remove_int_callback(bus->gpio_pin); + UNUSED(bus); + furi_hal_ibutton_stop(); + furi_hal_ibutton_remove_interrupt(); } void onewire_slave_attach(OneWireSlave* bus, OneWireDevice* device) { @@ -285,7 +284,7 @@ void onewire_slave_set_result_callback( bool onewire_slave_send(OneWireSlave* bus, const uint8_t* address, const uint8_t data_length) { uint8_t bytes_sent = 0; - furi_hal_gpio_write(bus->gpio_pin, true); + furi_hal_ibutton_pin_high(); // bytes loop for(; bytes_sent < data_length; ++bytes_sent) { @@ -307,7 +306,7 @@ bool onewire_slave_send(OneWireSlave* bus, const uint8_t* address, const uint8_t bool onewire_slave_receive(OneWireSlave* bus, uint8_t* data, const uint8_t data_length) { uint8_t bytes_received = 0; - furi_hal_gpio_write(bus->gpio_pin, true); + furi_hal_ibutton_pin_high(); for(; bytes_received < data_length; ++bytes_received) { uint8_t value = 0; diff --git a/lib/one_wire/one_wire_slave.h b/lib/one_wire/one_wire_slave.h index 2e5db3a1c2..319282c5c4 100644 --- a/lib/one_wire/one_wire_slave.h +++ b/lib/one_wire/one_wire_slave.h @@ -19,7 +19,7 @@ typedef void (*OneWireSlaveResultCallback)(void* context); /** * Allocate onewire slave - * @param gpio_pin + * @param pin * @return OneWireSlave* */ OneWireSlave* onewire_slave_alloc(const GpioPin* gpio_pin); diff --git a/lib/subghz/subghz_setting.c b/lib/subghz/subghz_setting.c index 35ba54a8a2..05b6a74ade 100644 --- a/lib/subghz/subghz_setting.c +++ b/lib/subghz/subghz_setting.c @@ -61,6 +61,7 @@ static const uint32_t subghz_frequency_list[] = { 438900000, 440175000, 464000000, + 467750000, /* 779 - 928 */ 779000000,