diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5bf231fe78c..8ab5cca9a66 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,7 +66,8 @@ jobs: do hex2dfu \ -i bootloader/.obj/${TARGET}/bootloader.hex \ - -o bootloader/.obj/${TARGET}/bootloader.dfu + -o bootloader/.obj/${TARGET}/bootloader.dfu \ + -l "Flipper Zero $(echo $TARGET | tr a-z A-Z)" done - name: 'Build firmware in docker' @@ -86,7 +87,8 @@ jobs: do hex2dfu \ -i firmware/.obj/${TARGET}/firmware.hex \ - -o firmware/.obj/${TARGET}/firmware.dfu + -o firmware/.obj/${TARGET}/firmware.dfu \ + -l "Flipper Zero $(echo $TARGET | tr a-z A-Z)" done - name: 'Generate full hex file' @@ -129,7 +131,8 @@ jobs: do hex2dfu \ -i firmware/.obj/${TARGET}/full.hex \ - -o artifacts/flipper-z-${TARGET}-full-${SUFFIX}.dfu + -o artifacts/flipper-z-${TARGET}-full-${SUFFIX}.dfu \ + -l "Flipper Zero $(echo $TARGET | tr a-z A-Z)" done - name: 'Full flash asssembly: bootloader as base' @@ -157,14 +160,6 @@ jobs: >> artifacts/flipper-z-${TARGET}-full-${SUFFIX}.bin done - - name: 'Publish artifacts' - uses: actions/upload-artifact@v2 - with: - name: artifacts - path: artifacts/* - if-no-files-found: error - retention-days: 7 - - name: 'Upload artifacts to update server' uses: burnett01/rsync-deployments@4.1 with: diff --git a/.github/workflows/lint_c.yml b/.github/workflows/lint_c.yml index f4c0ce5a898..39a7eabe05d 100644 --- a/.github/workflows/lint_c.yml +++ b/.github/workflows/lint_c.yml @@ -1,6 +1,6 @@ name: 'Lint C/C++ with clang-format' -on: push +on: pull_request env: TARGETS: f6 diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml index adff291e88c..4a70d48b000 100644 --- a/.github/workflows/lint_python.yml +++ b/.github/workflows/lint_python.yml @@ -1,10 +1,6 @@ name: 'Python Lint' -on: - push: - paths: - - '**.py' - pull_request: +on: pull_request jobs: lint_python: diff --git a/ReadMe.md b/ReadMe.md index 5b26bd81bed..07e1368928b 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -66,3 +66,67 @@ One liner: `./flash_core1_main.sh` * Project website: [flipperzero.one](https://flipperzero.one) * Kickstarter page: [kickstarter.com](https://www.kickstarter.com/projects/flipper-devices/flipper-zero-tamagochi-for-hackers) * Forum: [forum.flipperzero.one](https://forum.flipperzero.one/) + +# Folders structure + +- applications - application and services + * accessor - Wiegand server + * archive - Archive and file manager + * bt - BLE service and application + * cli - Console service + * debug_tools - different tools that we use on factory and for debug + * dialogs - service for showing GUI dialogs + * dolphin - dolphin service and supplientary apps + * gpio-tester - GPIO control application + * gui - GUI service + * ibutton - ibutton application, onewire keys and more + * input - input service + * irda - irda application, controls your IR devices + * irda_monitor - irda debug tool + * lfrfid - LF RFID application + * lfrfid-debug - LF RFID debug tool + * loader - application loader service + * menu - main menu service + * music-player - music player app (demo) + * nfc - NFC application, HF rfid, EMV and etc + * notification - notification service + * power - power service + * power-observer - power debug tool + * scened-app-example - c++ application example + * storage - storage service, internal + sdcard + * storage-settings - storage settings app + * subghz - subghz application, 433 fobs and etc + * tests - unit tests and etc +- assets - assets used by applications and services + * compiled - compilation results + * icons - source icons images +- bootloader - bootloader for flipper + * src - bootloader sources + * targets - targets' hal and implementation +- core - core libraries: home for furi +- debug - debug helpers, plugins and tools +- docker - docker image sources (used for automated firmware build) +- firmware - firmware for flipper + * targets - targets' hal and implementation +- lib - different libraries and drivers that apps and firmware uses + * ST25RFAL002 - ST253916 driver and NFC hal + * STM32CubeWB - STM32WB hal + * app-scened-template - scened template app library + * app-template - template app library + * callback-connector - callback connector library + * common-api - common api delaration library + * cyfral - cyfral library + * drivers - drivers that we wrote + * fatfs - external storage file system + * fnv1a-hash - fnv1a hash library + * irda - irda library + * littlefs - internal storage file system + * mlib - algorithms and containers + * nfc_protocols - nfc protocols library + * onewire - one wire library + * qrcode - qr code generator library + * subghz - subghz library + * toolbox - toolbox of things that we are using but don't place in core + * u8g2 - graphics library that we use to draw GUI +- make - make helpers +- scripts - supplimentary scripts diff --git a/applications/accessor/accessor-app.cpp b/applications/accessor/accessor-app.cpp index eb430bc3222..f7446b55ee2 100644 --- a/applications/accessor/accessor-app.cpp +++ b/applications/accessor/accessor-app.cpp @@ -1,6 +1,6 @@ #include "accessor-app.h" #include -#include +#include #include void AccessorApp::run(void) { @@ -33,16 +33,16 @@ void AccessorApp::run(void) { AccessorApp::AccessorApp() : onewire_master{&ibutton_gpio} { - api_hal_power_insomnia_enter(); + furi_hal_power_insomnia_enter(); notification = static_cast(furi_record_open("notification")); notify_init(); - api_hal_power_enable_otg(); + furi_hal_power_enable_otg(); } AccessorApp::~AccessorApp() { - api_hal_power_disable_otg(); + furi_hal_power_disable_otg(); furi_record_close("notification"); - api_hal_power_insomnia_exit(); + furi_hal_power_insomnia_exit(); } AccessorAppViewManager* AccessorApp::get_view_manager() { diff --git a/applications/accessor/accessor.cpp b/applications/accessor/accessor.cpp index 252158272b6..8a3d839b470 100644 --- a/applications/accessor/accessor.cpp +++ b/applications/accessor/accessor.cpp @@ -1,7 +1,7 @@ #include "accessor-app.h" // app enter function -extern "C" int32_t app_accessor(void* p) { +extern "C" int32_t accessor_app(void* p) { AccessorApp* app = new AccessorApp(); app->run(); delete app; diff --git a/applications/accessor/helpers/wiegand.cpp b/applications/accessor/helpers/wiegand.cpp index bc618489185..9e92a15d746 100644 --- a/applications/accessor/helpers/wiegand.cpp +++ b/applications/accessor/helpers/wiegand.cpp @@ -1,6 +1,6 @@ #include "wiegand.h" #include -#include +#include volatile unsigned long WIEGAND::_cardTempHigh = 0; volatile unsigned long WIEGAND::_cardTemp = 0; diff --git a/applications/applications.c b/applications/applications.c index d6ea88fa287..a36ac4863b5 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -1,103 +1,107 @@ #include "applications.h" - -// Services and apps decalartion -int32_t application_vertical_screen(void* p); -int32_t irda_monitor_app(void* p); -int32_t flipper_test_app(void* p); -int32_t application_blink(void* p); -int32_t application_uart_write(void* p); -int32_t application_input_dump(void* p); -int32_t u8g2_example(void* p); -int32_t input_task(void* p); -int32_t menu_task(void* p); -int32_t coreglitch_demo_0(void* p); -int32_t u8g2_qrcode(void* p); -int32_t gui_task(void* p); -int32_t irda(void* p); -int32_t loader(void* p); -int32_t nfc_task(void* p); -int32_t dolphin_task(void* p); -int32_t power_task(void* p); -int32_t bt_task(void* p); -int32_t application_vibro(void* p); -int32_t app_gpio_test(void* p); -int32_t app_ibutton(void* p); -int32_t cli_task(void* p); -int32_t music_player(void* p); -int32_t sdnfc(void* p); -int32_t subghz_app(void* p); -int32_t gui_test(void* p); -int32_t keypad_test(void* p); -int32_t scene_app(void* p); -int32_t passport(void* p); -int32_t app_accessor(void* p); -int32_t app_archive(void* p); -int32_t notification_app(void* p); -int32_t scened_app(void* p); -int32_t lfrfid_app(void* p); -int32_t lfrfid_debug_app(void* p); -int32_t storage_app(void* p); -int32_t storage_app_test(void* p); -int32_t dialogs_app(void* p); -int32_t power_observer(void* p); +#include + +// Services +extern int32_t bt_srv(void* p); +extern int32_t cli_srv(void* p); +extern int32_t dialogs_srv(void* p); +extern int32_t dolphin_srv(void* p); +extern int32_t gui_srv(void* p); +extern int32_t input_srv(void* p); +extern int32_t loader_srv(void* p); +extern int32_t menu_srv(void* p); +extern int32_t notification_srv(void* p); +extern int32_t power_observer_srv(void* p); +extern int32_t power_srv(void* p); +extern int32_t storage_srv(void* p); + +// Apps +extern int32_t accessor_app(void* p); +extern int32_t archive_app(void* p); +extern int32_t blink_test_app(void* p); +extern int32_t flipper_test_app(void* p); +extern int32_t gpio_test_app(void* p); +extern int32_t ibutton_app(void* p); +extern int32_t irda_app(void* p); +extern int32_t irda_monitor_app(void* p); +extern int32_t keypad_test_app(void* p); +extern int32_t lfrfid_app(void* p); +extern int32_t lfrfid_debug_app(void* p); +extern int32_t nfc_app(void* p); +extern int32_t passport_app(void* p); +extern int32_t food_minigame_app(void* p); +extern int32_t scene_app(void* p); +extern int32_t scened_app(void* p); +extern int32_t storage_test_app(void* p); +extern int32_t subghz_app(void* p); +extern int32_t vibro_test_app(void* p); + +// Plugins +extern int32_t music_player_app(void* p); // On system start hooks declaration -void irda_cli_init(); -void nfc_cli_init(); -void subghz_cli_init(); -void bt_cli_init(); -void lfrfid_cli_init(); -void ibutton_cli_init(); -void storage_cli_init(); +extern void bt_cli_init(); +extern void ibutton_cli_init(); +extern void irda_cli_init(); +extern void lfrfid_cli_init(); +extern void nfc_cli_init(); +extern void storage_cli_init(); +extern void subghz_cli_init(); // Settings -int32_t notification_app_settings(void* p); -int32_t storage_settings(void* p); +extern int32_t notification_settings_app(void* p); +extern int32_t storage_settings_app(void* p); const FlipperApplication FLIPPER_SERVICES[] = { -#ifdef SRV_CLI - {.app = cli_task, .name = "cli_task", .stack_size = 4096, .icon = &A_Plugins_14}, +/* Services */ +#ifdef SRV_BT + {.app = bt_srv, .name = "BT", .stack_size = 1024, .icon = NULL}, #endif -#ifdef SRV_EXAMPLE_BLINK - {.app = application_blink, .name = "blink", .stack_size = 1024, .icon = &A_Plugins_14}, +#ifdef SRV_CLI + {.app = cli_srv, .name = "Cli", .stack_size = 4096, .icon = NULL}, #endif -#ifdef SRV_INPUT - {.app = input_task, .name = "input_task", .stack_size = 1024, .icon = &A_Plugins_14}, +#ifdef SRV_DIALOGS + {.app = dialogs_srv, .name = "Dialogs", .stack_size = 1024, .icon = NULL}, #endif -#ifdef SRV_EXAMPLE_INPUT_DUMP - {.app = application_input_dump, - .name = "input dump", - .stack_size = 1024, - .icon = &A_Plugins_14}, +#ifdef SRV_DOLPHIN + {.app = dolphin_srv, .name = "Dolphin", .stack_size = 1024, .icon = NULL}, #endif #ifdef SRV_GUI - // TODO: fix stack size when sd api will be in separate thread - {.app = gui_task, .name = "gui_task", .stack_size = 8192, .icon = &A_Plugins_14}, + {.app = gui_srv, .name = "Gui", .stack_size = 8192, .icon = NULL}, +#endif + +#ifdef SRV_INPUT + {.app = input_srv, .name = "Input", .stack_size = 1024, .icon = NULL}, #endif #ifdef SRV_MENU - {.app = menu_task, .name = "menu_task", .stack_size = 1024, .icon = &A_Plugins_14}, - {.app = loader, .name = "loader", .stack_size = 1024, .icon = &A_Plugins_14}, + {.app = menu_srv, .name = "Menu", .stack_size = 1024, .icon = NULL}, + {.app = loader_srv, .name = "Loader", .stack_size = 1024, .icon = NULL}, #endif -#ifdef SRV_DOLPHIN - {.app = dolphin_task, .name = "dolphin_task", .stack_size = 1024, .icon = &A_Plugins_14}, +#ifdef SRV_NOTIFICATION + {.app = notification_srv, .name = "Notification", .stack_size = 1024, .icon = NULL}, #endif #ifdef SRV_POWER - {.app = power_task, .name = "power_task", .stack_size = 1024, .icon = &A_Plugins_14}, + {.app = power_srv, .name = "Power", .stack_size = 1024, .icon = NULL}, #endif #ifdef SRV_POWER_OBSERVER - {.app = power_observer, .name = "power_observer", .stack_size = 1024, .icon = &A_Plugins_14}, + {.app = power_observer_srv, .name = "PowerObserver", .stack_size = 1024, .icon = NULL}, #endif -#ifdef SRV_BT - {.app = bt_task, .name = "bt_task", .stack_size = 1024, .icon = &A_Plugins_14}, +#ifdef SRV_STORAGE + {.app = storage_srv, .name = "Storage", .stack_size = 4096, .icon = NULL}, +#endif + +/* Fake services (autorun) */ +#ifdef SRV_BLINK + {.app = blink_test_app, .name = "Blink", .stack_size = 1024, .icon = &A_Plugins_14}, #endif #ifdef SRV_LF_RFID @@ -105,66 +109,31 @@ const FlipperApplication FLIPPER_SERVICES[] = { #endif #ifdef SRV_IRDA - {.app = irda, .name = "irda", .stack_size = 1024 * 3, .icon = &A_Plugins_14}, -#endif - -#ifdef SRV_EXAMPLE_QRCODE - {.app = u8g2_qrcode, .name = "u8g2_qrcode", .stack_size = 1024, .icon = &A_Plugins_14}, -#endif - -#ifdef SRV_EXAMPLE_DISPLAY - {.app = u8g2_example, .name = "u8g2_example", .stack_size = 1024, .icon = &A_Plugins_14}, -#endif - -#ifdef SRV_SPEAKER_DEMO - {.app = coreglitch_demo_0, - .name = "coreglitch_demo_0", - .stack_size = 1024, - .icon = &A_Plugins_14}, + {.app = irda_app, .name = "Infrared", .stack_size = 1024 * 3, .icon = &A_Plugins_14}, #endif #ifdef SRV_MUSIC_PLAYER - {.app = music_player, .name = "music player", .stack_size = 1024, .icon = &A_Plugins_14}, + {.app = music_player_app, .name = "Music Player", .stack_size = 1024, .icon = &A_Plugins_14}, #endif #ifdef SRV_IBUTTON - {.app = app_ibutton, .name = "ibutton", .stack_size = 2048, .icon = &A_Plugins_14}, -#endif - -#ifdef SRV_GPIO_DEMO - {.app = app_gpio_test, .name = "gpio test", .stack_size = 1024, .icon = &A_Plugins_14}, -#endif - -#ifdef SRV_SDNFC - {.app = sdnfc, .name = "sdnfc", .stack_size = 1024, .icon = &A_Plugins_14}, + {.app = ibutton_app, .name = "iButton", .stack_size = 2048, .icon = &A_Plugins_14}, #endif -#ifdef SRV_GUI_TEST - {.app = gui_test, .name = "gui_test", .stack_size = 1024, .icon = &A_Plugins_14}, +#ifdef SRV_GPIO_TEST + {.app = gpio_test_app, .name = "GPIO Test", .stack_size = 1024, .icon = &A_Plugins_14}, #endif #ifdef SRV_KEYPAD_TEST - {.app = keypad_test, .name = "keypad_test", .stack_size = 1024, .icon = &A_Plugins_14}, + {.app = keypad_test_app, .name = "Keypad Test", .stack_size = 1024, .icon = &A_Plugins_14}, #endif #ifdef SRV_ACCESSOR - {.app = app_accessor, .name = "accessor", .stack_size = 4096, .icon = &A_Plugins_14}, -#endif - -#ifdef SRV_NOTIFICATION - {.app = notification_app, .name = "notification", .stack_size = 1024, .icon = &A_Plugins_14}, -#endif - -#ifdef SRV_STORAGE - {.app = storage_app, .name = "storage", .stack_size = 4096, .icon = &A_Plugins_14}, + {.app = accessor_app, .name = "Accessor", .stack_size = 4096, .icon = &A_Plugins_14}, #endif #ifdef SRV_STORAGE_TEST - {.app = storage_app_test, .name = "storage test", .stack_size = 1024, .icon = &A_Plugins_14}, -#endif - -#ifdef SRV_DIALOGS - {.app = dialogs_app, .name = "dialogs", .stack_size = 1024, .icon = &A_Plugins_14}, + {.app = storage_test_app, .name = "Storage Test", .stack_size = 1024, .icon = &A_Plugins_14}, #endif }; @@ -174,29 +143,27 @@ const size_t FLIPPER_SERVICES_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperA const FlipperApplication FLIPPER_APPS[] = { #ifdef APP_IBUTTON - {.app = app_ibutton, .name = "iButton", .stack_size = 2048, .icon = &A_iButton_14}, + {.app = ibutton_app, .name = "iButton", .stack_size = 2048, .icon = &A_iButton_14}, #endif #ifdef APP_NFC - {.app = nfc_task, .name = "NFC", .stack_size = 4096, .icon = &A_NFC_14}, + {.app = nfc_app, .name = "NFC", .stack_size = 4096, .icon = &A_NFC_14}, #endif #ifdef APP_SUBGHZ - // TODO: decrease stack after SD API refactoring - {.app = subghz_app, .name = "Sub-1 GHz", .stack_size = 4096, .icon = &A_Sub1ghz_14}, + {.app = subghz_app, .name = "Sub-1 GHz", .stack_size = 2048, .icon = &A_Sub1ghz_14}, #endif #ifdef APP_LF_RFID - // TODO: fix stack size when sd api will be in separate thread {.app = lfrfid_app, .name = "125 kHz RFID", .stack_size = 2048, .icon = &A_125khz_14}, #endif #ifdef APP_IRDA - {.app = irda, .name = "Infrared", .stack_size = 1024 * 3, .icon = &A_Infrared_14}, + {.app = irda_app, .name = "Infrared", .stack_size = 1024 * 3, .icon = &A_Infrared_14}, #endif -#ifdef APP_GPIO_DEMO - {.app = app_gpio_test, .name = "GPIO", .stack_size = 1024, .icon = &A_GPIO_14}, +#ifdef APP_GPIO_TEST + {.app = gpio_test_app, .name = "GPIO", .stack_size = 1024, .icon = &A_GPIO_14}, #endif }; @@ -233,51 +200,28 @@ const size_t FLIPPER_ON_SYSTEM_START_COUNT = const FlipperApplication FLIPPER_PLUGINS[] = { #ifdef APP_MUSIC_PLAYER - {.app = music_player, .name = "music player", .stack_size = 1024, .icon = &A_Plugins_14}, + {.app = music_player_app, .name = "Music Player", .stack_size = 1024, .icon = &A_Plugins_14}, #endif - -#ifdef APP_SPEAKER_DEMO - {.app = coreglitch_demo_0, - .name = "coreglitch_demo_0", - .stack_size = 1024, - .icon = &A_Plugins_14}, -#endif - }; const size_t FLIPPER_PLUGINS_COUNT = sizeof(FLIPPER_PLUGINS) / sizeof(FlipperApplication); // Plugin menu const FlipperApplication FLIPPER_DEBUG_APPS[] = { -#ifdef APP_EXAMPLE_BLINK - {.app = application_blink, .name = "blink", .stack_size = 1024, .icon = &A_Plugins_14}, -#endif - -#ifdef APP_EXAMPLE_INPUT_DUMP - {.app = application_input_dump, - .name = "input dump", - .stack_size = 1024, - .icon = &A_Plugins_14}, +#ifdef APP_BLINK + {.app = blink_test_app, .name = "Blink Test", .stack_size = 1024, .icon = &A_Plugins_14}, #endif #ifdef APP_VIBRO_DEMO - {.app = application_vibro, .name = "vibro", .stack_size = 1024, .icon = &A_Plugins_14}, -#endif - -#ifdef APP_SDNFC - {.app = sdnfc, .name = "sdnfc", .stack_size = 1024, .icon = &A_Plugins_14}, -#endif - -#ifdef APP_GUI_TEST - {.app = gui_test, .name = "gui_test", .stack_size = 1024, .icon = &A_Plugins_14}, + {.app = vibro_test_app, .name = "Vibro Test", .stack_size = 1024, .icon = &A_Plugins_14}, #endif #ifdef APP_KEYPAD_TEST - {.app = keypad_test, .name = "keypad_test", .stack_size = 1024, .icon = &A_Plugins_14}, + {.app = keypad_test_app, .name = "Keypad Test", .stack_size = 1024, .icon = &A_Plugins_14}, #endif #ifdef APP_ACCESSOR - {.app = app_accessor, .name = "accessor", .stack_size = 4096, .icon = &A_Plugins_14}, + {.app = accessor_app, .name = "Accessor", .stack_size = 4096, .icon = &A_Plugins_14}, #endif #ifdef APP_UNIT_TESTS @@ -288,13 +232,6 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { {.app = irda_monitor_app, .name = "Irda Monitor", .stack_size = 1024, .icon = &A_Plugins_14}, #endif -#ifdef APP_VERTICAL_SCREEN - {.app = application_vertical_screen, - .name = "Vertical Screen", - .stack_size = 1024, - .icon = &A_Plugins_14}, -#endif - #ifdef APP_SCENED {.app = scened_app, .name = "Templated Scene", .stack_size = 1024, .icon = &A_Plugins_14}, #endif @@ -308,7 +245,7 @@ const size_t FLIPPER_DEBUG_APPS_COUNT = sizeof(FLIPPER_DEBUG_APPS) / sizeof(Flip #ifdef APP_ARCHIVE const FlipperApplication FLIPPER_ARCHIVE = - {.app = app_archive, .name = "Archive", .stack_size = 4096, .icon = &A_FileManager_14}; + {.app = archive_app, .name = "Archive", .stack_size = 4096, .icon = &A_FileManager_14}; #endif #ifdef SRV_DOLPHIN @@ -316,8 +253,8 @@ const FlipperApplication FLIPPER_SCENE = {.app = scene_app, .name = "Scenes", .stack_size = 1024, .icon = &A_Games_14}; const FlipperApplication FLIPPER_SCENE_APPS[] = { - {.app = passport, .name = "Passport", .stack_size = 1024, .icon = &A_Games_14}, - {.app = music_player, .name = "Music player", .stack_size = 1024, .icon = &A_Plugins_14}, + {.app = passport_app, .name = "Passport", .stack_size = 1024, .icon = &A_Games_14}, + {.app = food_minigame_app, .name = "Food minigame", .stack_size = 1024, .icon = &A_Games_14}, }; const size_t FLIPPER_SCENE_APPS_COUNT = sizeof(FLIPPER_SCENE_APPS) / sizeof(FlipperApplication); @@ -327,11 +264,11 @@ const size_t FLIPPER_SCENE_APPS_COUNT = sizeof(FLIPPER_SCENE_APPS) / sizeof(Flip // Settings menu const FlipperApplication FLIPPER_SETTINGS_APPS[] = { #ifdef SRV_NOTIFICATION - {.app = notification_app_settings, .name = "Notification", .stack_size = 1024, .icon = NULL}, + {.app = notification_settings_app, .name = "Notification", .stack_size = 1024, .icon = NULL}, #endif #ifdef SRV_STORAGE - {.app = storage_settings, .name = "Storage", .stack_size = 2048, .icon = NULL}, + {.app = storage_settings_app, .name = "Storage", .stack_size = 2048, .icon = NULL}, #endif }; diff --git a/applications/applications.h b/applications/applications.h index b2e29324b9f..962eaa7726a 100644 --- a/applications/applications.h +++ b/applications/applications.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include typedef struct { const FuriThreadCallback app; diff --git a/applications/applications.mk b/applications/applications.mk index c19015f988b..5e3263a6fba 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -11,40 +11,46 @@ CPP_SOURCES += $(shell find $(APP_DIR) -name *.cpp) APP_RELEASE ?= 1 ifeq ($(APP_RELEASE), 1) -# Main services -SRV_MENU = 1 -SRV_POWER = 1 +# Services SRV_BT = 1 SRV_CLI = 1 +SRV_DIALOGS = 1 SRV_DOLPHIN = 1 +SRV_GUI = 1 +SRV_INPUT = 1 +SRV_MENU = 1 SRV_NOTIFICATION = 1 -SRV_STORAGE = 1 -SRV_DIALOGS = 1 +SRV_POWER = 1 SRV_POWER_OBSERVER = 1 +SRV_STORAGE = 1 -# Main Apps +# Apps +APP_ARCHIVE = 1 +APP_GPIO_TEST = 1 +APP_IBUTTON = 1 APP_IRDA = 1 -APP_SUBGHZ = 1 APP_LF_RFID = 1 APP_NFC = 1 -APP_GPIO_DEMO = 1 +APP_SUBGHZ = 1 + +# Plugins APP_MUSIC_PLAYER = 1 -APP_IBUTTON = 1 -APP_ARCHIVE = 1 -# Debug and misc -APP_GUI_TEST = 1 -APP_KEYPAD_TEST = 1 +# Debug APP_ACCESSOR = 1 +APP_BLINK = 1 +APP_IRDA_MONITOR = 1 +APP_KEYPAD_TEST = 1 APP_SD_TEST = 1 -APP_VIBRO_DEMO = 1 -APP_SPEAKER_DEMO = 1 -APP_EXAMPLE_BLINK = 1 -APP_EXAMPLE_UART_WRITE = 1 -APP_EXAMPLE_INPUT_DUMP = 1 APP_UNIT_TESTS = 0 -APP_IRDA_MONITOR = 1 -APP_VERTICAL_SCREEN = 1 +APP_VIBRO_DEMO = 1 +endif + + +SRV_BT ?= 0 +ifeq ($(SRV_BT), 1) +SRV_CLI = 1 +CFLAGS += -DSRV_BT endif SRV_DOLPHIN ?= 0 @@ -66,12 +72,6 @@ SRV_POWER = 1 CFLAGS += -DSRV_POWER_OBSERVER endif -SRV_BT ?= 0 -ifeq ($(SRV_BT), 1) -SRV_CLI = 1 -CFLAGS += -DSRV_BT -endif - SRV_MENU ?= 0 ifeq ($(SRV_MENU), 1) CFLAGS += -DSRV_MENU @@ -84,11 +84,6 @@ SRV_GUI = 1 CFLAGS += -DAPP_MENU endif -APP_VERTICAL_SCREEN ?= 0 -ifeq ($(APP_VERTICAL_SCREEN), 1) -CFLAGS += -DAPP_VERTICAL_SCREEN -endif - APP_IRDA_MONITOR ?= 0 ifeq ($(APP_IRDA_MONITOR), 1) CFLAGS += -DAPP_IRDA_MONITOR @@ -105,56 +100,35 @@ CFLAGS += -DAPP_ARCHIVE APP_ARCHIVE = 1 endif -SRV_EXAMPLE_BLINK ?= 0 -ifeq ($(SRV_EXAMPLE_BLINK), 1) -CFLAGS += -DSRV_EXAMPLE_BLINK -APP_EXAMPLE_BLINK = 1 +SRV_BLINK ?= 0 +ifeq ($(SRV_BLINK), 1) +CFLAGS += -DSRV_BLINK +APP_BLINK = 1 endif -APP_EXAMPLE_BLINK ?= 0 -ifeq ($(APP_EXAMPLE_BLINK), 1) -CFLAGS += -DAPP_EXAMPLE_BLINK +APP_BLINK ?= 0 +ifeq ($(APP_BLINK), 1) +CFLAGS += -DAPP_BLINK SRV_INPUT = 1 endif -SRV_EXAMPLE_UART_WRITE ?= 0 -ifeq ($(SRV_EXAMPLE_UART_WRITE), 1) -CFLAGS += -DSRV_EXAMPLE_UART_WRITE -APP_EXAMPLE_UART_WRITE = 1 +SRV_UART_WRITE ?= 0 +ifeq ($(SRV_UART_WRITE), 1) +CFLAGS += -DSRV_UART_WRITE +APP_UART_WRITE = 1 endif -APP_EXAMPLE_UART_WRITE ?= 0 -ifeq ($(APP_EXAMPLE_UART_WRITE), 1) -CFLAGS += -DAPP_EXAMPLE_UART_WRITE +APP_UART_WRITE ?= 0 +ifeq ($(APP_UART_WRITE), 1) +CFLAGS += -DAPP_UART_WRITE endif -SRV_EXAMPLE_IPC ?= 0 -ifeq ($(SRV_EXAMPLE_IPC), 1) -CFLAGS += -DSRV_EXAMPLE_IPC -APP_EXAMPLE_IPC = 1 +SRV_IPC ?= 0 +ifeq ($(SRV_IPC), 1) +CFLAGS += -DSRV_IPC +APP_IPC = 1 endif -APP_EXAMPLE_IPC ?= 0 -ifeq ($(APP_EXAMPLE_IPC), 1) -CFLAGS += -DAPP_EXAMPLE_IPC -endif - -SRV_EXAMPLE_INPUT_DUMP ?= 0 -ifeq ($(SRV_EXAMPLE_INPUT_DUMP), 1) -CFLAGS += -DSRV_EXAMPLE_INPUT_DUMP -APP_EXAMPLE_INPUT_DUMP = 1 -endif -APP_EXAMPLE_INPUT_DUMP ?= 0 -ifeq ($(APP_EXAMPLE_INPUT_DUMP), 1) -CFLAGS += -DAPP_EXAMPLE_INPUT_DUMP -SRV_INPUT = 1 -endif - -SRV_EXAMPLE_QRCODE ?= 0 -ifeq ($(SRV_EXAMPLE_QRCODE), 1) -CFLAGS += -DSRV_EXAMPLE_QRCODE -APP_EXAMPLE_QRCODE = 1 -endif -APP_EXAMPLE_QRCODE ?= 0 -ifeq ($(APP_EXAMPLE_QRCODE), 1) -CFLAGS += -DAPP_EXAMPLE_QRCODE +APP_IPC ?= 0 +ifeq ($(APP_IPC), 1) +CFLAGS += -DAPP_IPC endif ifeq ($(APP_SUBGHZ), 1) @@ -196,18 +170,6 @@ SRV_INPUT = 1 SRV_GUI = 1 endif -SRV_SPEAKER_DEMO ?= 0 -ifeq ($(SRV_SPEAKER_DEMO), 1) -CFLAGS += -DSRV_SPEAKER_DEMO -APP_SPEAKER_DEMO = 1 -endif -APP_SPEAKER_DEMO ?= 0 -ifeq ($(APP_SPEAKER_DEMO), 1) -CFLAGS += -DAPP_SPEAKER_DEMO -SRV_INPUT = 1 -SRV_GUI = 1 -endif - APP_VIBRO_DEMO ?= 0 ifeq ($(APP_VIBRO_DEMO), 1) CFLAGS += -DAPP_VIBRO_DEMO @@ -236,14 +198,14 @@ CFLAGS += -DAPP_ACCESSOR APP_ACCESSOR = 1 endif -SRV_GPIO_DEMO ?= 0 -ifeq ($(SRV_GPIO_DEMO), 1) -CFLAGS += -DSRV_GPIO_DEMO -APP_GPIO_DEMO = 1 +SRV_GPIO_TEST ?= 0 +ifeq ($(SRV_GPIO_TEST), 1) +CFLAGS += -DSRV_GPIO_TEST +APP_GPIO_TEST = 1 endif -APP_GPIO_DEMO ?= 0 -ifeq ($(APP_GPIO_DEMO), 1) -CFLAGS += -DAPP_GPIO_DEMO +APP_GPIO_TEST ?= 0 +ifeq ($(APP_GPIO_TEST), 1) +CFLAGS += -DAPP_GPIO_TEST endif SRV_MUSIC_PLAYER ?= 0 @@ -266,17 +228,9 @@ ifeq ($(APP_IBUTTON), 1) CFLAGS += -DAPP_IBUTTON endif -SRV_GUI_TEST ?= 0 -ifeq ($(SRV_GUI_TEST), 1) -CFLAGS += -DSRV_GUI_TEST -APP_GUI_TEST = 1 -endif -APP_GUI_TEST ?= 0 -ifeq ($(APP_GUI_TEST), 1) -CFLAGS += -DAPP_GUI_TEST -endif - -# device drivers +# +# Essential services +# SRV_GUI ?= 0 ifeq ($(SRV_GUI), 1) @@ -307,4 +261,4 @@ endif SRV_DIALOGS ?= 0 ifeq ($(SRV_DIALOGS), 1) CFLAGS += -DSRV_DIALOGS -endif \ No newline at end of file +endif diff --git a/applications/archive/archive.c b/applications/archive/archive.c index f6c0dc1f6c1..265ae02c8b3 100644 --- a/applications/archive/archive.c +++ b/applications/archive/archive.c @@ -629,7 +629,7 @@ ArchiveApp* archive_alloc() { return archive; } -int32_t app_archive(void* p) { +int32_t archive_app(void* p) { ArchiveApp* archive = archive_alloc(); // default tab diff --git a/applications/archive/archive_i.h b/applications/archive/archive_i.h index 38991f7b1a0..006a7bbfea5 100644 --- a/applications/archive/archive_i.h +++ b/applications/archive/archive_i.h @@ -35,7 +35,7 @@ static const char* flipper_app_name[] = { static const char* known_ext[] = { [ArchiveFileTypeIButton] = ".ibtn", [ArchiveFileTypeNFC] = ".nfc", - [ArchiveFileTypeSubOne] = ".sub1", + [ArchiveFileTypeSubOne] = ".sub", [ArchiveFileTypeLFRFID] = ".rfid", [ArchiveFileTypeIrda] = ".ir", }; @@ -44,7 +44,7 @@ static const char* tab_default_paths[] = { [ArchiveTabFavorites] = "/any/favorites", [ArchiveTabIButton] = "/any/ibutton", [ArchiveTabNFC] = "/any/nfc", - [ArchiveTabSubOne] = "/any/subone", + [ArchiveTabSubOne] = "/any/subghz/saved", [ArchiveTabLFRFID] = "/any/lfrfid", [ArchiveTabIrda] = "/any/irda", [ArchiveTabBrowser] = "/any", diff --git a/applications/archive/archive_views.c b/applications/archive/archive_views.c index bd3286f1c95..e2d5224167e 100644 --- a/applications/archive/archive_views.c +++ b/applications/archive/archive_views.c @@ -4,7 +4,7 @@ static const char* ArchiveTabNames[] = { [ArchiveTabFavorites] = "Favorites", [ArchiveTabIButton] = "iButton", [ArchiveTabNFC] = "NFC", - [ArchiveTabSubOne] = "SubOne", + [ArchiveTabSubOne] = "SubGhz", [ArchiveTabLFRFID] = "RFID LF", [ArchiveTabIrda] = "Infrared", [ArchiveTabBrowser] = "Browser"}; diff --git a/applications/bt/bt.c b/applications/bt/bt.c index 5a27b31cf1a..41974f65a3e 100644 --- a/applications/bt/bt.c +++ b/applications/bt/bt.c @@ -148,29 +148,29 @@ void bt_menu_start_app(void* context) { furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); } -int32_t bt_task() { +int32_t bt_srv() { Bt* bt = bt_alloc(); furi_record_create("bt", bt); - api_hal_bt_init(); + furi_hal_bt_init(); BtMessage message; while(1) { furi_check(osMessageQueueGet(bt->message_queue, &message, NULL, osWaitForever) == osOK); if(message.type == BtMessageTypeStartTestCarrier) { // Start carrier test - api_hal_bt_stop_tone_tx(); + furi_hal_bt_stop_tone_tx(); if(bt->state.type == BtStateCarrierTx) { - api_hal_bt_start_tone_tx(message.param.channel, message.param.power); + furi_hal_bt_start_tone_tx(message.param.channel, message.param.power); } else if(bt->state.type == BtStateHoppingTx) { bt->state.param.channel = bt_switch_channel(InputKeyRight, bt->state.param.channel); - api_hal_bt_start_tone_tx(bt->state.param.channel, bt->state.param.power); + furi_hal_bt_start_tone_tx(bt->state.param.channel, bt->state.param.power); } else if(bt->state.type == BtStateCarrierRxStart) { - api_hal_bt_start_packet_rx(bt->state.param.channel, bt->state.param.datarate); + furi_hal_bt_start_packet_rx(bt->state.param.channel, bt->state.param.datarate); bt->state.type = BtStateCarrierRxRunning; } else if(bt->state.type == BtStateCarrierRxRunning) { - bt->state.param.rssi = api_hal_bt_get_rssi(); + bt->state.param.rssi = furi_hal_bt_get_rssi(); } with_view_model( bt->view_test_carrier, (BtViewTestCarrierModel * model) { @@ -183,14 +183,14 @@ int32_t bt_task() { view_dispatcher_switch_to_view(bt->view_dispatcher, BtViewTestCarrier); } else if(message.type == BtMessageTypeStopTestCarrier) { if(bt->state.type == BtStateCarrierRxRunning) { - api_hal_bt_stop_packet_test(); + furi_hal_bt_stop_packet_test(); } else { - api_hal_bt_stop_tone_tx(); + furi_hal_bt_stop_tone_tx(); } bt->state.type = BtStateReady; } else if(message.type == BtMessageTypeSetupTestPacketTx) { // Update packet test setup - api_hal_bt_stop_packet_test(); + furi_hal_bt_stop_packet_test(); with_view_model( bt->view_test_packet_tx, (BtViewTestPacketTxModel * model) { model->type = bt->state.type; @@ -202,10 +202,10 @@ int32_t bt_task() { } else if(message.type == BtMessageTypeStartTestPacketTx) { // Start sending packets if(bt->state.type == BtStatePacketStart) { - api_hal_bt_start_packet_tx(message.param.channel, 1, message.param.datarate); + furi_hal_bt_start_packet_tx(message.param.channel, 1, message.param.datarate); } else if(bt->state.type == BtStatePacketSetup) { - api_hal_bt_stop_packet_test(); - bt->state.param.packets_sent = api_hal_bt_get_transmitted_packets(); + furi_hal_bt_stop_packet_test(); + bt->state.param.packets_sent = furi_hal_bt_get_transmitted_packets(); } with_view_model( bt->view_test_packet_tx, (BtViewTestPacketTxModel * model) { @@ -218,7 +218,7 @@ int32_t bt_task() { view_dispatcher_switch_to_view(bt->view_dispatcher, BtViewTestPacketTx); } else if(message.type == BtMessageTypeSetupTestPacketRx) { // Update packet test setup - api_hal_bt_stop_packet_test(); + furi_hal_bt_stop_packet_test(); with_view_model( bt->view_test_packet_rx, (BtViewTestPacketRxModel * model) { model->type = bt->state.type; @@ -230,12 +230,12 @@ int32_t bt_task() { } else if(message.type == BtMessageTypeStartTestPacketRx) { // Start test rx if(bt->state.type == BtStatePacketStart) { - api_hal_bt_start_packet_rx(message.param.channel, message.param.datarate); + furi_hal_bt_start_packet_rx(message.param.channel, message.param.datarate); bt->state.type = BtStatePacketRunning; } else if(bt->state.type == BtStatePacketRunning) { - bt->state.param.rssi = api_hal_bt_get_rssi(); + bt->state.param.rssi = furi_hal_bt_get_rssi(); } else if(bt->state.type == BtStatePacketSetup) { - bt->state.param.packets_received = api_hal_bt_stop_packet_test(); + bt->state.param.packets_received = furi_hal_bt_stop_packet_test(); } with_view_model( bt->view_test_packet_rx, (BtViewTestPacketRxModel * model) { @@ -249,17 +249,17 @@ int32_t bt_task() { view_dispatcher_switch_to_view(bt->view_dispatcher, BtViewTestPacketRx); } else if(message.type == BtMessageTypeStopTestPacket) { // Stop test packet tx - api_hal_bt_stop_packet_test(); + furi_hal_bt_stop_packet_test(); bt->state.type = BtStateReady; } else if(message.type == BtMessageTypeStartApp) { // Start app view_dispatcher_switch_to_view(bt->view_dispatcher, BtViewStartApp); - if(api_hal_bt_start_app()) { + if(furi_hal_bt_start_app()) { bt->state.type = BtStateStartedApp; } } else if(message.type == BtMessageTypeUpdateStatusbar) { // Update statusbar - view_port_enabled_set(bt->statusbar_view_port, api_hal_bt_is_alive()); + view_port_enabled_set(bt->statusbar_view_port, furi_hal_bt_is_alive()); } } return 0; diff --git a/applications/bt/bt_cli.c b/applications/bt/bt_cli.c index 3c325003265..47a05d067d6 100644 --- a/applications/bt/bt_cli.c +++ b/applications/bt/bt_cli.c @@ -1,6 +1,6 @@ #include "bt_cli.h" #include -#include +#include void bt_cli_init() { Cli* cli = furi_record_open("cli"); @@ -17,7 +17,7 @@ void bt_cli_init() { void bt_cli_command_info(Cli* cli, string_t args, void* context) { string_t buffer; string_init(buffer); - api_hal_bt_dump_state(buffer); + furi_hal_bt_dump_state(buffer); printf(string_get_cstr(buffer)); string_clear(buffer); } @@ -41,12 +41,12 @@ void bt_cli_command_carrier_tx(Cli* cli, string_t args, void* context) { } printf("Transmitting carrier at %hu channel at %hu dB power\r\n", channel, power); printf("Press CTRL+C to stop\r\n"); - api_hal_bt_start_tone_tx(channel, 0x19 + power); + furi_hal_bt_start_tone_tx(channel, 0x19 + power); while(!cli_cmd_interrupt_received(cli)) { osDelay(250); } - api_hal_bt_stop_tone_tx(); + furi_hal_bt_stop_tone_tx(); } void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) { @@ -64,15 +64,15 @@ void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) { printf("Receiving carrier at %hu channel\r\n", channel); printf("Press CTRL+C to stop\r\n"); - api_hal_bt_start_packet_rx(channel, 1); + furi_hal_bt_start_packet_rx(channel, 1); while(!cli_cmd_interrupt_received(cli)) { osDelay(1024 / 4); - printf("RSSI: %6.1f dB\r", api_hal_bt_get_rssi()); + printf("RSSI: %6.1f dB\r", furi_hal_bt_get_rssi()); fflush(stdout); } - api_hal_bt_stop_packet_test(); + furi_hal_bt_stop_packet_test(); } void bt_cli_command_packet_tx(Cli* cli, string_t args, void* context) { @@ -111,13 +111,13 @@ void bt_cli_command_packet_tx(Cli* cli, string_t args, void* context) { channel, datarate); printf("Press CTRL+C to stop\r\n"); - api_hal_bt_start_packet_tx(channel, pattern, datarate); + furi_hal_bt_start_packet_tx(channel, pattern, datarate); while(!cli_cmd_interrupt_received(cli)) { osDelay(250); } - api_hal_bt_stop_packet_test(); - printf("Transmitted %lu packets", api_hal_bt_get_transmitted_packets()); + furi_hal_bt_stop_packet_test(); + printf("Transmitted %lu packets", furi_hal_bt_get_transmitted_packets()); } void bt_cli_command_packet_rx(Cli* cli, string_t args, void* context) { @@ -139,15 +139,15 @@ void bt_cli_command_packet_rx(Cli* cli, string_t args, void* context) { } printf("Receiving packets at %hu channel at %hu M datarate\r\n", channel, datarate); printf("Press CTRL+C to stop\r\n"); - api_hal_bt_start_packet_rx(channel, datarate); + furi_hal_bt_start_packet_rx(channel, datarate); float rssi_raw = 0; while(!cli_cmd_interrupt_received(cli)) { osDelay(250); - rssi_raw = api_hal_bt_get_rssi(); + rssi_raw = furi_hal_bt_get_rssi(); printf("RSSI: %03.1f dB\r", rssi_raw); fflush(stdout); } - uint16_t packets_received = api_hal_bt_stop_packet_test(); + uint16_t packets_received = furi_hal_bt_stop_packet_test(); printf("Received %hu packets", packets_received); } diff --git a/applications/bt/bt_i.h b/applications/bt/bt_i.h index 8d45836b7f3..6a5fe3830da 100644 --- a/applications/bt/bt_i.h +++ b/applications/bt/bt_i.h @@ -5,7 +5,7 @@ #include "bt_types.h" #include -#include +#include #include diff --git a/applications/cli/cli.c b/applications/cli/cli.c index 213bef90a98..11465a9969a 100644 --- a/applications/cli/cli.c +++ b/applications/cli/cli.c @@ -1,7 +1,7 @@ #include "cli_i.h" #include "cli_commands.h" -#include +#include #include Cli* cli_alloc() { @@ -30,33 +30,33 @@ void cli_free(Cli* cli) { } void cli_putc(char c) { - api_hal_vcp_tx((uint8_t*)&c, 1); + furi_hal_vcp_tx((uint8_t*)&c, 1); } char cli_getc(Cli* cli) { furi_assert(cli); char c; - if(api_hal_vcp_rx((uint8_t*)&c, 1) == 0) { + if(furi_hal_vcp_rx((uint8_t*)&c, 1) == 0) { cli_reset(cli); } return c; } void cli_stdout_callback(void* _cookie, const char* data, size_t size) { - api_hal_vcp_tx((const uint8_t*)data, size); + furi_hal_vcp_tx((const uint8_t*)data, size); } void cli_write(Cli* cli, uint8_t* buffer, size_t size) { - return api_hal_vcp_tx(buffer, size); + return furi_hal_vcp_tx(buffer, size); } size_t cli_read(Cli* cli, uint8_t* buffer, size_t size) { - return api_hal_vcp_rx(buffer, size); + return furi_hal_vcp_rx(buffer, size); } bool cli_cmd_interrupt_received(Cli* cli) { char c = '\0'; - if(api_hal_vcp_rx_with_timeout((uint8_t*)&c, 1, 0) == 1) { + if(furi_hal_vcp_rx_with_timeout((uint8_t*)&c, 1, 0) == 1) { return c == CliSymbolAsciiETX; } else { return false; @@ -92,7 +92,7 @@ void cli_motd() { "Read Manual https://docs.flipperzero.one\r\n" "\r\n"); - const Version* firmware_version = api_hal_version_get_firmware_version(); + const Version* firmware_version = furi_hal_version_get_firmware_version(); if(firmware_version) { printf( "Firmware version: %s %s (%s built on %s)\r\n", @@ -143,7 +143,7 @@ static void cli_normalize_line(Cli* cli) { static void cli_execute_command(Cli* cli, CliCommand* command, string_t args) { if(!(command->flags & CliCommandFlagInsomniaSafe)) { - api_hal_power_insomnia_enter(); + furi_hal_power_insomnia_enter(); } // Ensure that we running alone @@ -164,7 +164,7 @@ static void cli_execute_command(Cli* cli, CliCommand* command, string_t args) { } if(!(command->flags & CliCommandFlagInsomniaSafe)) { - api_hal_power_insomnia_exit(); + furi_hal_power_insomnia_exit(); } } @@ -302,12 +302,15 @@ void cli_process_input(Cli* cli) { } else if(c == CliSymbolAsciiSOH) { cli_motd(); cli_prompt(cli); + } else if(c == CliSymbolAsciiETX) { + cli_reset(cli); + cli_prompt(cli); } else if(c == CliSymbolAsciiEOT) { cli_reset(cli); } else if(c == CliSymbolAsciiEsc) { - r = api_hal_vcp_rx((uint8_t*)&c, 1); + r = furi_hal_vcp_rx((uint8_t*)&c, 1); if(r && c == '[') { - api_hal_vcp_rx((uint8_t*)&c, 1); + furi_hal_vcp_rx((uint8_t*)&c, 1); cli_handle_escape(cli, c); } else { cli_putc(CliSymbolAsciiBell); @@ -383,7 +386,7 @@ void cli_delete_command(Cli* cli, const char* name) { string_clear(name_str); } -int32_t cli_task(void* p) { +int32_t cli_srv(void* p) { Cli* cli = cli_alloc(); // Init basic cli commands diff --git a/applications/cli/cli_commands.c b/applications/cli/cli_commands.c index d23a8c59be4..5d1afc1225a 100644 --- a/applications/cli/cli_commands.c +++ b/applications/cli/cli_commands.c @@ -1,6 +1,6 @@ #include "cli_commands.h" -#include -#include +#include +#include #include #include #include @@ -14,33 +14,33 @@ */ void cli_command_device_info(Cli* cli, string_t args, void* context) { // Model name - printf("hardware_model : %s\r\n", api_hal_version_get_model_name()); - const char* name = api_hal_version_get_name_ptr(); + printf("hardware_model : %s\r\n", furi_hal_version_get_model_name()); + const char* name = furi_hal_version_get_name_ptr(); if(name) { printf("hardware_name : %s\r\n", name); } // Unique ID printf("hardware_uid : "); - const uint8_t* uid = api_hal_version_uid(); - for(size_t i = 0; i < api_hal_version_uid_size(); i++) { + const uint8_t* uid = furi_hal_version_uid(); + for(size_t i = 0; i < furi_hal_version_uid_size(); i++) { printf("%02X", uid[i]); } printf("\r\n"); // Board Revision - printf("hardware_ver : %d\r\n", api_hal_version_get_hw_version()); - printf("hardware_target : %d\r\n", api_hal_version_get_hw_target()); - printf("hardware_body : %d\r\n", api_hal_version_get_hw_body()); - printf("hardware_connect : %d\r\n", api_hal_version_get_hw_connect()); - printf("hardware_timestamp : %lu\r\n", api_hal_version_get_hw_timestamp()); + printf("hardware_ver : %d\r\n", furi_hal_version_get_hw_version()); + printf("hardware_target : %d\r\n", furi_hal_version_get_hw_target()); + printf("hardware_body : %d\r\n", furi_hal_version_get_hw_body()); + printf("hardware_connect : %d\r\n", furi_hal_version_get_hw_connect()); + printf("hardware_timestamp : %lu\r\n", furi_hal_version_get_hw_timestamp()); // Color and Region - printf("hardware_color : %d\r\n", api_hal_version_get_hw_color()); - printf("hardware_region : %d\r\n", api_hal_version_get_hw_region()); + printf("hardware_color : %d\r\n", furi_hal_version_get_hw_color()); + printf("hardware_region : %d\r\n", furi_hal_version_get_hw_region()); // Bootloader Version - const Version* boot_version = api_hal_version_get_boot_version(); + const Version* boot_version = furi_hal_version_get_boot_version(); if(boot_version) { printf("boot_version : %s\r\n", version_get_version(boot_version)); printf("boot_commit : %s\r\n", version_get_githash(boot_version)); @@ -49,7 +49,7 @@ void cli_command_device_info(Cli* cli, string_t args, void* context) { } // Firmware version - const Version* firmware_version = api_hal_version_get_firmware_version(); + const Version* firmware_version = furi_hal_version_get_firmware_version(); if(firmware_version) { printf("firmware_version : %s\r\n", version_get_version(firmware_version)); printf("firmware_commit : %s\r\n", version_get_githash(firmware_version)); @@ -58,7 +58,7 @@ void cli_command_device_info(Cli* cli, string_t args, void* context) { } WirelessFwInfo_t pWirelessInfo; - if(api_hal_bt_is_alive() && SHCI_GetWirelessFwInfo(&pWirelessInfo) == SHCI_Success) { + if(furi_hal_bt_is_alive() && SHCI_GetWirelessFwInfo(&pWirelessInfo) == SHCI_Success) { printf("radio_alive : true\r\n"); // FUS Info printf("radio_fus_major : %d\r\n", pWirelessInfo.FusVersionMajor); @@ -80,7 +80,7 @@ void cli_command_device_info(Cli* cli, string_t args, void* context) { printf("radio_stack_flash : %dK\r\n", pWirelessInfo.MemorySizeFlash * 4); // Mac address printf("radio_ble_mac : "); - const uint8_t* ble_mac = api_hal_version_get_ble_mac(); + const uint8_t* ble_mac = furi_hal_version_get_ble_mac(); for(size_t i = 0; i < 6; i++) { printf("%02X", ble_mac[i]); } diff --git a/applications/cli/cli_i.h b/applications/cli/cli_i.h index e60fa45029e..b0ab6384bfc 100755 --- a/applications/cli/cli_i.h +++ b/applications/cli/cli_i.h @@ -3,7 +3,7 @@ #include "cli.h" #include -#include +#include #include #include diff --git a/applications/coreglitch_demo_0/coreglitch_demo_0.c b/applications/coreglitch_demo_0/coreglitch_demo_0.c deleted file mode 100644 index 0bf93d7995f..00000000000 --- a/applications/coreglitch_demo_0/coreglitch_demo_0.c +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include -#include -#include - -#include "u8g2/u8g2.h" - -extern TIM_HandleTypeDef SPEAKER_TIM; - -bool exit_app; - -static void event_cb(const void* value, void* ctx) { - furi_assert(value); - const InputEvent* event = value; - if(event->key == InputKeyBack && event->type == InputTypeShort) { - exit_app = true; - } -} - -void coreglitch_draw_callback(Canvas* canvas, void* ctx) { - canvas_clear(canvas); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 2, 10, "Coreglitch demo application"); -} - -int32_t coreglitch_demo_0(void* p) { - printf("coreglitch demo!\r\n"); - - exit_app = false; - PubSub* event_record = furi_record_open("input_events"); - PubSubItem* event_pubsub = subscribe_pubsub(event_record, event_cb, NULL); - - // Configure view port - ViewPort* view_port = view_port_alloc(); - furi_check(view_port); - view_port_draw_callback_set(view_port, coreglitch_draw_callback, NULL); - - // Register view port in GUI - Gui* gui = furi_record_open("gui"); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - float notes[] = { - 0.0, - 330.0, - 220.0, - 0.0, - 110.0 + 55.0, - 440.0, - 330.0, - 55.0, - }; - - float scales[] = { - 1.0, - 1.5, - 0.75, - 0.8, - }; - - uint8_t cnt = 0; - - while(1) { - for(size_t note_idx = 0; (note_idx < 400) && (!exit_app); note_idx++) { - float scale = scales[((cnt + note_idx) / 16) % 4]; - - float freq = notes[(note_idx + cnt / 2) % 8] * scale; - float width = 0.001 + 0.05 * (note_idx % (cnt / 7 + 5)); - - if(note_idx % 8 == 0) { - freq = 0; - } - - // TODO get sound from FURI - hal_pwm_set(width, freq, &SPEAKER_TIM, SPEAKER_CH); - - // delay(1); - - cnt++; - delay(100); - } - if(exit_app) { - break; - } - } - hal_pwm_stop(&SPEAKER_TIM, SPEAKER_CH); - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - view_port_free(view_port); - unsubscribe_pubsub(event_pubsub); - - return 0; -} diff --git a/applications/examples/blink.c b/applications/debug_tools/blink_test.c similarity index 82% rename from applications/examples/blink.c rename to applications/debug_tools/blink_test.c index f146e49074e..cc41c188d77 100644 --- a/applications/examples/blink.c +++ b/applications/debug_tools/blink_test.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -18,7 +18,7 @@ typedef struct { InputEvent input; } BlinkEvent; -void blink_update(void* ctx) { +static void blink_test_update(void* ctx) { furi_assert(ctx); osMessageQueueId_t event_queue = ctx; @@ -26,13 +26,13 @@ void blink_update(void* ctx) { osMessageQueuePut(event_queue, &event, 0, 0); } -void blink_draw_callback(Canvas* canvas, void* ctx) { +static void blink_test_draw_callback(Canvas* canvas, void* ctx) { canvas_clear(canvas); canvas_set_font(canvas, FontPrimary); canvas_draw_str(canvas, 2, 10, "Blink application"); } -void blink_input_callback(InputEvent* input_event, void* ctx) { +static void blink_test_input_callback(InputEvent* input_event, void* ctx) { furi_assert(ctx); osMessageQueueId_t event_queue = ctx; @@ -40,15 +40,15 @@ void blink_input_callback(InputEvent* input_event, void* ctx) { osMessageQueuePut(event_queue, &event, 0, 0); } -int32_t application_blink(void* p) { +int32_t blink_test_app(void* p) { osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(BlinkEvent), NULL); // Configure view port ViewPort* view_port = view_port_alloc(); furi_check(view_port); - view_port_draw_callback_set(view_port, blink_draw_callback, NULL); - view_port_input_callback_set(view_port, blink_input_callback, event_queue); - osTimerId_t timer = osTimerNew(blink_update, osTimerPeriodic, event_queue, NULL); + view_port_draw_callback_set(view_port, blink_test_draw_callback, NULL); + view_port_input_callback_set(view_port, blink_test_input_callback, event_queue); + osTimerId_t timer = osTimerNew(blink_test_update, osTimerPeriodic, event_queue, NULL); osTimerStart(timer, 1000); // Register view port in GUI diff --git a/applications/debug_tools/keypad_test.c b/applications/debug_tools/keypad_test.c new file mode 100644 index 00000000000..1323e95e23b --- /dev/null +++ b/applications/debug_tools/keypad_test.c @@ -0,0 +1,225 @@ +#include +#include +#include + +typedef struct { + bool press[5]; + uint16_t up; + uint16_t down; + uint16_t left; + uint16_t right; + uint16_t ok; +} KeypadTestState; + +typedef enum { + EventTypeInput, +} EventType; + +typedef struct { + union { + InputEvent input; + }; + EventType type; +} KeypadTestEvent; + +static const char* keypad_test_get_key_name(InputKey key) { + switch(key) { + case InputKeyOk: + return "Ok"; + case InputKeyBack: + return "Back"; + case InputKeyLeft: + return "Left"; + case InputKeyRight: + return "Right"; + case InputKeyUp: + return "Up"; + case InputKeyDown: + return "Down"; + default: + return "Unknown"; + } +} + +static const char* keypad_test_get_type_name(InputType type) { + switch(type) { + case InputTypePress: + return "Press"; + case InputTypeRelease: + return "Release"; + case InputTypeShort: + return "Short"; + case InputTypeLong: + return "Long"; + case InputTypeRepeat: + return "Repeat"; + default: + return "Unknown"; + } +} + +static void keypad_test_reset_state(KeypadTestState* state) { + state->left = 0; + state->right = 0; + state->up = 0; + state->down = 0; + state->ok = 0; +} + +static void keypad_test_render_callback(Canvas* canvas, void* ctx) { + KeypadTestState* state = (KeypadTestState*)acquire_mutex((ValueMutex*)ctx, 25); + canvas_clear(canvas); + char strings[5][20]; + + sprintf(strings[0], "Ok: %d", state->ok); + sprintf(strings[1], "L: %d", state->left); + sprintf(strings[2], "R: %d", state->right); + sprintf(strings[3], "U: %d", state->up); + sprintf(strings[4], "D: %d", state->down); + + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 0, 10, "Keypad test"); + + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 0, 24, strings[1]); + canvas_draw_str(canvas, 35, 24, strings[2]); + canvas_draw_str(canvas, 0, 36, strings[3]); + canvas_draw_str(canvas, 35, 36, strings[4]); + canvas_draw_str(canvas, 0, 48, strings[0]); + canvas_draw_circle(canvas, 100, 26, 25); + + if(state->press[0]) canvas_draw_disc(canvas, 118, 26, 5); + if(state->press[1]) canvas_draw_disc(canvas, 82, 26, 5); + if(state->press[2]) canvas_draw_disc(canvas, 100, 8, 5); + if(state->press[3]) canvas_draw_disc(canvas, 100, 44, 5); + if(state->press[4]) canvas_draw_disc(canvas, 100, 26, 5); + + canvas_draw_str(canvas, 10, 63, "[back] - reset, hold to exit"); + + release_mutex((ValueMutex*)ctx, state); +} + +static void keypad_test_input_callback(InputEvent* input_event, void* ctx) { + osMessageQueueId_t event_queue = ctx; + + KeypadTestEvent event; + event.type = EventTypeInput; + event.input = *input_event; + osMessageQueuePut(event_queue, &event, 0, osWaitForever); +} + +int32_t keypad_test_app(void* p) { + osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(KeypadTestEvent), NULL); + furi_check(event_queue); + + KeypadTestState _state = {{false, false, false, false, false}, 0, 0, 0, 0, 0}; + + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, &_state, sizeof(KeypadTestState))) { + FURI_LOG_E("KeypadTest", "cannot create mutex"); + return 0; + } + + ViewPort* view_port = view_port_alloc(); + + view_port_draw_callback_set(view_port, keypad_test_render_callback, &state_mutex); + view_port_input_callback_set(view_port, keypad_test_input_callback, event_queue); + + // Open GUI and register view_port + Gui* gui = furi_record_open("gui"); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + KeypadTestEvent event; + while(1) { + osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, osWaitForever); + KeypadTestState* state = (KeypadTestState*)acquire_mutex_block(&state_mutex); + + if(event_status == osOK) { + if(event.type == EventTypeInput) { + FURI_LOG_I( + "KeypadTest", + "key: %s type: %s", + keypad_test_get_key_name(event.input.key), + keypad_test_get_type_name(event.input.type)); + + if(event.input.type == InputTypeLong && event.input.key == InputKeyBack) { + release_mutex(&state_mutex, state); + break; + } + + if(event.input.type == InputTypeShort && event.input.key == InputKeyBack) { + keypad_test_reset_state(state); + } + + if(event.input.key == InputKeyRight) { + if(event.input.type == InputTypePress) { + state->press[0] = true; + } else if(event.input.type == InputTypeRelease) { + state->press[0] = false; + } + + if(event.input.type == InputTypeShort) { + ++state->right; + } + } + + if(event.input.key == InputKeyLeft) { + if(event.input.type == InputTypePress) { + state->press[1] = true; + } else if(event.input.type == InputTypeRelease) { + state->press[1] = false; + } + + if(event.input.type == InputTypeShort) { + ++state->left; + } + } + + if(event.input.key == InputKeyUp) { + if(event.input.type == InputTypePress) { + state->press[2] = true; + } else if(event.input.type == InputTypeRelease) { + state->press[2] = false; + } + + if(event.input.type == InputTypeShort) { + ++state->up; + } + } + + if(event.input.key == InputKeyDown) { + if(event.input.type == InputTypePress) { + state->press[3] = true; + } else if(event.input.type == InputTypeRelease) { + state->press[3] = false; + } + + if(event.input.type == InputTypeShort) { + ++state->down; + } + } + + if(event.input.key == InputKeyOk) { + if(event.input.type == InputTypePress) { + state->press[4] = true; + } else if(event.input.type == InputTypeRelease) { + state->press[4] = false; + } + + if(event.input.type == InputTypeShort) { + ++state->ok; + } + } + } + } + view_port_update(view_port); + release_mutex(&state_mutex, state); + } + // remove & free all stuff created by app + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + osMessageQueueDelete(event_queue); + delete_mutex(&state_mutex); + + return 0; +} diff --git a/applications/examples/vibro.c b/applications/debug_tools/vibro_test.c similarity index 86% rename from applications/examples/vibro.c rename to applications/debug_tools/vibro_test.c index 9c4edf30971..b5e9be63b1f 100644 --- a/applications/examples/vibro.c +++ b/applications/debug_tools/vibro_test.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -9,7 +9,7 @@ typedef struct { InputEvent input; } VibroEvent; -void vibro_draw_callback(Canvas* canvas, void* ctx) { +void vibro_test_draw_callback(Canvas* canvas, void* ctx) { canvas_clear(canvas); canvas_set_font(canvas, FontPrimary); canvas_draw_str(canvas, 2, 10, "Vibro application"); @@ -19,7 +19,7 @@ void vibro_draw_callback(Canvas* canvas, void* ctx) { canvas_draw_str(canvas, 2, 34, "Release OK turns off vibro"); } -void vibro_input_callback(InputEvent* input_event, void* ctx) { +void vibro_test_input_callback(InputEvent* input_event, void* ctx) { furi_assert(ctx); osMessageQueueId_t event_queue = ctx; @@ -27,14 +27,14 @@ void vibro_input_callback(InputEvent* input_event, void* ctx) { osMessageQueuePut(event_queue, &event, 0, 0); } -int32_t application_vibro(void* p) { +int32_t vibro_test_app(void* p) { osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(VibroEvent), NULL); // Configure view port ViewPort* view_port = view_port_alloc(); furi_check(view_port); - view_port_draw_callback_set(view_port, vibro_draw_callback, NULL); - view_port_input_callback_set(view_port, vibro_input_callback, event_queue); + view_port_draw_callback_set(view_port, vibro_test_draw_callback, NULL); + view_port_input_callback_set(view_port, vibro_test_input_callback, event_queue); // Register view port in GUI Gui* gui = furi_record_open("gui"); diff --git a/applications/dialogs/dialogs.c b/applications/dialogs/dialogs.c index 41c607da196..8395e8520c4 100644 --- a/applications/dialogs/dialogs.c +++ b/applications/dialogs/dialogs.c @@ -24,7 +24,7 @@ static void dialogs_app_process_message(DialogsApp* app, DialogsAppMessage* mess API_LOCK_UNLOCK(message->semaphore); } -int32_t dialogs_app(void* p) { +int32_t dialogs_srv(void* p) { DialogsApp* app = dialogs_app_alloc(); furi_record_create("dialogs", app); diff --git a/applications/dolphin/dolphin.c b/applications/dolphin/dolphin.c index 3ccbab8260b..705ed80867e 100644 --- a/applications/dolphin/dolphin.c +++ b/applications/dolphin/dolphin.c @@ -393,7 +393,7 @@ void dolphin_deed(Dolphin* dolphin, DolphinDeed deed) { furi_check(osMessageQueuePut(dolphin->event_queue, &event, 0, osWaitForever) == osOK); } -int32_t dolphin_task() { +int32_t dolphin_srv() { Dolphin* dolphin = dolphin_alloc(); if(dolphin_state_load(dolphin->state)) { @@ -411,7 +411,7 @@ int32_t dolphin_task() { furi_record_create("dolphin", dolphin); - if(!api_hal_version_do_i_belong_here()) { + if(!furi_hal_version_do_i_belong_here()) { view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewHwMismatch); } diff --git a/applications/dolphin/dolphin_i.h b/applications/dolphin/dolphin_i.h index ccddf80261f..3f47e2c385c 100644 --- a/applications/dolphin/dolphin_i.h +++ b/applications/dolphin/dolphin_i.h @@ -5,7 +5,7 @@ #include "dolphin_views.h" #include -#include +#include #include #include #include diff --git a/applications/dolphin/dolphin_views.c b/applications/dolphin/dolphin_views.c index 30c15eadc18..8953fe3ad5f 100644 --- a/applications/dolphin/dolphin_views.c +++ b/applications/dolphin/dolphin_views.c @@ -2,8 +2,8 @@ #include #include #include -#include -#include +#include +#include static char* Lockmenu_Items[3] = {"Lock", "Set PIN", "DUMB mode"}; @@ -14,7 +14,7 @@ void dolphin_view_first_start_draw(Canvas* canvas, void* model) { canvas_set_font(canvas, FontSecondary); uint8_t width = canvas_width(canvas); uint8_t height = canvas_height(canvas); - const char* my_name = api_hal_version_get_name_ptr(); + const char* my_name = furi_hal_version_get_name_ptr(); if(m->page == 0) { canvas_draw_icon(canvas, 0, height - 48, &I_DolphinFirstStart0_70x53); elements_multiline_text_framed(canvas, 75, 20, "Hey m8,\npress > to\ncontinue"); @@ -119,20 +119,20 @@ void dolphin_view_idle_down_draw(Canvas* canvas, void* model) { if(m->screen != DolphinViewStatsMeta) { // Hardware version - const char* my_name = api_hal_version_get_name_ptr(); + const char* my_name = furi_hal_version_get_name_ptr(); snprintf( buffer, sizeof(buffer), "HW: %d.F%dB%dC%d %s", - api_hal_version_get_hw_version(), - api_hal_version_get_hw_target(), - api_hal_version_get_hw_body(), - api_hal_version_get_hw_connect(), + furi_hal_version_get_hw_version(), + furi_hal_version_get_hw_target(), + furi_hal_version_get_hw_body(), + furi_hal_version_get_hw_connect(), my_name ? my_name : "Unknown"); canvas_draw_str(canvas, 5, 23, buffer); - ver = m->screen == DolphinViewStatsBoot ? api_hal_version_get_boot_version() : - api_hal_version_get_firmware_version(); + ver = m->screen == DolphinViewStatsBoot ? furi_hal_version_get_boot_version() : + furi_hal_version_get_firmware_version(); if(!ver) { canvas_draw_str(canvas, 5, 33, "No info"); @@ -178,7 +178,7 @@ void dolphin_view_hw_mismatch_draw(Canvas* canvas, void* model) { char buffer[64]; canvas_set_font(canvas, FontSecondary); - snprintf(buffer, 64, "HW target: F%d", api_hal_version_get_hw_target()); + snprintf(buffer, 64, "HW target: F%d", furi_hal_version_get_hw_target()); canvas_draw_str(canvas, 5, 27, buffer); canvas_draw_str(canvas, 5, 38, "FW target: " TARGET); } diff --git a/applications/dolphin/games/food.c b/applications/dolphin/games/food.c new file mode 100644 index 00000000000..ea35b6d87ee --- /dev/null +++ b/applications/dolphin/games/food.c @@ -0,0 +1,321 @@ +#include +#include +#include "dolphin/dolphin_state.h" + +#define MAX_TRIES 3 +#define DISHES_TOTAL 3 +#define LID_POS_MAX 20 +#define TRY_TIMEOUT 10 + +typedef enum { + EventTypeTick, + EventTypeKey, + EventTypeDeed, +} EventType; + +typedef struct { + union { + InputEvent input; + } value; + EventType type; +} AppEvent; + +typedef enum { + PlayerChoiceEvent, + OpenLootEvent, + WinEvent, + LooseEvent, + FinishedEvent, + ExitGameEvent, + GameEventTotal, +} GameEventType; + +typedef enum { + LootSkeleton, + LootFish, + LootShit, + LootTotalNum, +} LootIdEnum; + +typedef struct { + GameEventType current_event; + osMessageQueueId_t event_queue; + LootIdEnum loot_list[DISHES_TOTAL]; + + uint8_t cursor_pos; + uint8_t lid_pos; + uint8_t timeout; + uint8_t try; + + bool selected; + bool deed; + +} GameState; + +typedef struct { + const Icon* f; + const Icon* b; +} LootGfx; + +static const Icon* letters[DISHES_TOTAL] = {&I_letterA_10x10, &I_letterB_10x10, &I_letterC_10x10}; + +static const LootGfx loot[LootTotalNum] = { + [LootSkeleton] = + { + .f = &I_skeleton_25x17, + .b = &I_blackskeleton_25x17, + }, + [LootFish] = + { + .f = &I_fish_25x17, + .b = &I_blackfish_25x17, + }, + [LootShit] = + { + .f = &I_shit_25x17, + .b = &I_blackshit_25x17, + }, +}; + +static void input_callback(InputEvent* input_event, void* ctx) { + osMessageQueueId_t event_queue = ctx; + AppEvent event; + event.type = EventTypeKey; + event.value.input = *input_event; + osMessageQueuePut(event_queue, &event, 0, osWaitForever); +} + +static void draw_dish(Canvas* canvas, GameState* state, uint8_t x, uint8_t y, uint8_t id) { + bool active = state->cursor_pos == id; + bool opened = state->current_event == OpenLootEvent && active; + + canvas_set_bitmap_mode(canvas, true); + canvas_set_color(canvas, ColorBlack); + + if(active) { + canvas_draw_icon(canvas, x, y, &I_active_plate_48x18); + } + + if(opened) { + state->lid_pos = CLAMP(state->lid_pos + 1, LID_POS_MAX, 0); + } + + uint8_t lid_pos = (y - 17) - (opened ? state->lid_pos : 0); + + canvas_draw_icon(canvas, x + 3, y - 6, &I_plate_42x19); + + canvas_set_color(canvas, ColorWhite); + canvas_draw_icon(canvas, x + 11, y - 10, loot[state->loot_list[id]].b); + canvas_set_color(canvas, ColorBlack); + canvas_draw_icon(canvas, x + 11, y - 10, loot[state->loot_list[id]].f); + + canvas_set_color(canvas, ColorWhite); + canvas_draw_icon(canvas, x + 6, lid_pos, &I_blacklid_36x27); + canvas_set_color(canvas, ColorBlack); + canvas_draw_icon(canvas, x + 6, lid_pos, &I_lid_36x27); + canvas_set_bitmap_mode(canvas, false); + + canvas_draw_icon(canvas, x + 19, y + 8, letters[id]); +} + +static void draw_dishes_scene(Canvas* canvas, GameState* state) { + uint8_t tries_left = MAX_TRIES - state->try; + for(size_t i = 0; i < MAX_TRIES; i++) { + if(i < tries_left) { + canvas_draw_disc(canvas, 5 + i * 8, 5, 2); + } else { + canvas_draw_circle(canvas, 5 + i * 8, 5, 2); + } + } + + for(size_t i = 0; i < DISHES_TOTAL; i++) { + draw_dish(canvas, state, i * 40, i % 2 ? 26 : 44, i); + } +} + +static void render_callback(Canvas* canvas, void* ctx) { + GameState* state = (GameState*)acquire_mutex((ValueMutex*)ctx, 25); + canvas_clear(canvas); + + switch(state->current_event) { + case WinEvent: + canvas_draw_str(canvas, 30, 30, "Dolphin_happy.png"); + break; + case LooseEvent: + canvas_draw_str_aligned(canvas, 64, 30, AlignCenter, AlignCenter, "Try again!"); + break; + case ExitGameEvent: + break; + case FinishedEvent: + break; + default: + draw_dishes_scene(canvas, state); + break; + } + + release_mutex((ValueMutex*)ctx, state); +} +static void reset_lid_pos(GameState* state) { + state->selected = false; + state->lid_pos = 0; +} + +void dolphin_food_deed(GameState* state) { + furi_assert(state); + AppEvent event; + event.type = EventTypeDeed; + furi_check(osMessageQueuePut(state->event_queue, &event, 0, osWaitForever) == osOK); +} + +static void reset_loot_array(GameState* state) { + for(size_t i = 0; i < LootTotalNum; i++) { + state->loot_list[i] = i; + } + + for(size_t i = 0; i < LootTotalNum; i++) { + int temp = state->loot_list[i]; + int r_idx = rand() % LootTotalNum; + + state->loot_list[i] = state->loot_list[r_idx]; + state->loot_list[r_idx] = temp; + } +} + +static bool selected_is_food(GameState* state) { + return state->loot_list[state->cursor_pos] == LootFish; +} + +static bool tries_exceed(GameState* state) { + return state->try == MAX_TRIES; +} + +static bool timeout_exceed(GameState* state) { + return state->timeout == TRY_TIMEOUT; +} + +static void gamestate_update(GameState* state, DolphinState* dolphin_state) { + switch(state->current_event) { + case PlayerChoiceEvent: + if(state->selected) { + state->current_event = OpenLootEvent; + } + break; + case OpenLootEvent: + state->timeout = CLAMP(state->timeout + 1, TRY_TIMEOUT, 0); + if(timeout_exceed(state)) { + state->timeout = 0; + state->current_event = selected_is_food(state) ? WinEvent : LooseEvent; + state->deed = selected_is_food(state); + } + break; + case LooseEvent: + state->timeout = CLAMP(state->timeout + 1, TRY_TIMEOUT, 0); + if(timeout_exceed(state)) { + state->timeout = 0; + state->current_event = FinishedEvent; + } + break; + case WinEvent: + if(state->deed) { + dolphin_food_deed(state); + } + break; + case FinishedEvent: + reset_lid_pos(state); + reset_loot_array(state); + + state->try++; + state->current_event = tries_exceed(state) ? ExitGameEvent : PlayerChoiceEvent; + break; + + default: + break; + } +} + +static void food_minigame_controls(GameState* state, AppEvent* event) { + furi_assert(state); + furi_assert(event); + + if(event->value.input.key == InputKeyRight) { + if(state->current_event == PlayerChoiceEvent) { + state->cursor_pos = CLAMP(state->cursor_pos + 1, DISHES_TOTAL - 1, 0); + } + } else if(event->value.input.key == InputKeyLeft) { + if(state->current_event == PlayerChoiceEvent) { + state->cursor_pos = CLAMP(state->cursor_pos - 1, DISHES_TOTAL - 1, 0); + } + } else if(event->value.input.key == InputKeyOk) { + switch(state->current_event) { + case PlayerChoiceEvent: + state->selected = true; + break; + case WinEvent: + state->current_event = FinishedEvent; + break; + default: + break; + } + } +} + +int32_t food_minigame_app(void* p) { + GameState* state = furi_alloc(sizeof(GameState)); + DolphinState* dolphin_state = dolphin_state_alloc(); + dolphin_state_load(dolphin_state); + + ValueMutex state_mutex; + + state->event_queue = osMessageQueueNew(2, sizeof(AppEvent), NULL); + + furi_check(state->event_queue); + + if(!init_mutex(&state_mutex, state, sizeof(GameState*))) { + printf("[Food minigame] cannot create mutex\r\n"); + return 0; + } + + ViewPort* view_port = view_port_alloc(); + + view_port_draw_callback_set(view_port, render_callback, &state_mutex); + view_port_input_callback_set(view_port, input_callback, state->event_queue); + + Gui* gui = furi_record_open("gui"); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + reset_loot_array(state); + + AppEvent event; + while(1) { + osStatus_t event_status = osMessageQueueGet(state->event_queue, &event, NULL, 100); + if(event_status == osOK) { + if(event.type == EventTypeKey && event.value.input.type == InputTypeShort) { + food_minigame_controls(state, &event); + + if(event.value.input.key == InputKeyBack) { + break; + } + } else if(event.type == EventTypeDeed) { + dolphin_state_on_deed(dolphin_state, DolphinDeedIButtonRead); + dolphin_state_save(dolphin_state); + state->deed = false; + } + } + + if(state->current_event == ExitGameEvent) { + break; + } + gamestate_update(state, dolphin_state); + view_port_update(view_port); + } + + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + furi_record_close("gui"); + delete_mutex(&state_mutex); + osMessageQueueDelete(state->event_queue); + dolphin_state_free(dolphin_state); + free(state); + + return 0; +} diff --git a/applications/dolphin/passport/passport.c b/applications/dolphin/passport/passport.c index 53b97ba0a07..de4b1966891 100644 --- a/applications/dolphin/passport/passport.c +++ b/applications/dolphin/passport/passport.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include "dolphin/dolphin.h" #include "dolphin/dolphin_state.h" #include "math.h" @@ -80,7 +80,7 @@ static void render_callback(Canvas* canvas, void* ctx) { canvas_draw_line(canvas, 59, 31, 124, 31); canvas_draw_line(canvas, 59, 44, 124, 44); - const char* my_name = api_hal_version_get_name_ptr(); + const char* my_name = furi_hal_version_get_name_ptr(); canvas_draw_str(canvas, 59, 15, my_name ? my_name : "Unknown"); snprintf(level, 20, "Level: %ld", current_level); @@ -97,7 +97,7 @@ static void render_callback(Canvas* canvas, void* ctx) { release_mutex((ValueMutex*)ctx, state); } -int32_t passport(void* p) { +int32_t passport_app(void* p) { DolphinState* dolphin_state = dolphin_state_alloc(); ValueMutex state_mutex; dolphin_state_load(dolphin_state); diff --git a/applications/dolphin/scenes/assets/items.c b/applications/dolphin/scenes/assets/items.c index d975551bff6..539c01e1d25 100644 --- a/applications/dolphin/scenes/assets/items.c +++ b/applications/dolphin/scenes/assets/items.c @@ -228,6 +228,6 @@ void console_callback(Canvas* canvas, void* s) { furi_assert(s); SceneState* state = s; if(state->use_pending) { - dolphin_scene_start_app(state, &FLIPPER_SCENE_APPS[1]); + dolphin_scene_start_app(state, &FLIPPER_SCENE_APPS[0]); } } \ No newline at end of file diff --git a/applications/dolphin/scenes/scene.c b/applications/dolphin/scenes/scene.c index ed15592a51c..13c0cff0cc4 100644 --- a/applications/dolphin/scenes/scene.c +++ b/applications/dolphin/scenes/scene.c @@ -1,5 +1,5 @@ #include -#include +#include #include "scene.h" static SceneAppGui* scene_app_gui = NULL; @@ -109,7 +109,7 @@ void scene_free() { } int32_t scene_app(void* p) { - api_hal_power_insomnia_enter(); + furi_hal_power_insomnia_enter(); scene_alloc(); osTimerStart(scene_app_gui->timer, 40); @@ -146,6 +146,6 @@ int32_t scene_app(void* p) { osDelay(15); scene_free(); - api_hal_power_insomnia_exit(); + furi_hal_power_insomnia_exit(); return 0; } \ No newline at end of file diff --git a/applications/examples/input_dump.c b/applications/examples/input_dump.c deleted file mode 100644 index 4959ca9f17c..00000000000 --- a/applications/examples/input_dump.c +++ /dev/null @@ -1,100 +0,0 @@ -#include -#include -#include -#include -#include - -typedef struct { - InputEvent input; -} InputDumpEvent; - -void input_dump_draw_callback(Canvas* canvas, void* ctx) { - canvas_clear(canvas); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 2, 10, "Input dump application"); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 2, 22, "Press long back to exit"); -} - -void input_dump_input_callback(InputEvent* input_event, void* ctx) { - furi_assert(ctx); - osMessageQueueId_t event_queue = ctx; - InputDumpEvent event = {.input = *input_event}; - osMessageQueuePut(event_queue, &event, 0, 0); -} - -static const char* input_dump_get_key_name(InputKey key) { - switch(key) { - case InputKeyOk: - return "Ok"; - case InputKeyBack: - return "Back"; - case InputKeyLeft: - return "Left"; - case InputKeyRight: - return "Right"; - case InputKeyUp: - return "Up"; - case InputKeyDown: - return "Down"; - default: - return "Unknown"; - } -} - -static const char* input_dump_get_type_name(InputType type) { - switch(type) { - case InputTypePress: - return "Press"; - case InputTypeRelease: - return "Release"; - case InputTypeShort: - return "Short"; - case InputTypeLong: - return "Long"; - case InputTypeRepeat: - return "Repeat"; - default: - return "Unknown"; - } -} - -int32_t application_input_dump(void* p) { - osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(InputDumpEvent), NULL); - - // Configure view port - ViewPort* view_port = view_port_alloc(); - furi_check(view_port); - view_port_draw_callback_set(view_port, input_dump_draw_callback, NULL); - view_port_input_callback_set(view_port, input_dump_input_callback, event_queue); - - // Register view port in GUI - Gui* gui = furi_record_open("gui"); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - FURI_LOG_I("INPUT DUMP", "waiting for input events"); - InputDumpEvent event; - - while(1) { - furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK); - - FURI_LOG_I( - "INPUT DUMP", - "key: %s type: %s", - input_dump_get_key_name(event.input.key), - input_dump_get_type_name(event.input.type)); - - if(event.input.type == InputTypeLong && event.input.key == InputKeyBack) { - break; - } - } - - FURI_LOG_I("INPUT DUMP", "shutting down, byebye!"); - - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - view_port_free(view_port); - osMessageQueueDelete(event_queue); - - return 0; -} diff --git a/applications/examples/keypad_test.c b/applications/examples/keypad_test.c deleted file mode 100644 index 01fd6070bbb..00000000000 --- a/applications/examples/keypad_test.c +++ /dev/null @@ -1,189 +0,0 @@ -#include -#include -#include - -extern TIM_HandleTypeDef SPEAKER_TIM; - -typedef struct { - bool press[5]; - uint16_t up; - uint16_t down; - uint16_t left; - uint16_t right; - uint16_t ok; -} State; - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - union { - InputEvent input; - } value; - EventType type; -} AppEvent; - -static void reset_state(State* state) { - state->left = 0; - state->right = 0; - state->up = 0; - state->down = 0; - state->ok = 0; -} - -static void render_callback(Canvas* canvas, void* ctx) { - State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25); - canvas_clear(canvas); - char strings[5][20]; - - sprintf(strings[0], "Ok: %d", state->ok); - sprintf(strings[1], "L: %d", state->left); - sprintf(strings[2], "R: %d", state->right); - sprintf(strings[3], "U: %d", state->up); - sprintf(strings[4], "D: %d", state->down); - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 0, 10, "Keypad test"); - - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 0, 24, strings[1]); - canvas_draw_str(canvas, 35, 24, strings[2]); - canvas_draw_str(canvas, 0, 36, strings[3]); - canvas_draw_str(canvas, 35, 36, strings[4]); - canvas_draw_str(canvas, 0, 48, strings[0]); - canvas_draw_circle(canvas, 100, 26, 25); - - if(state->press[0]) canvas_draw_disc(canvas, 118, 26, 5); - if(state->press[1]) canvas_draw_disc(canvas, 82, 26, 5); - if(state->press[2]) canvas_draw_disc(canvas, 100, 8, 5); - if(state->press[3]) canvas_draw_disc(canvas, 100, 44, 5); - if(state->press[4]) canvas_draw_disc(canvas, 100, 26, 5); - - canvas_draw_str(canvas, 10, 63, "[back] - reset, hold to exit"); - - release_mutex((ValueMutex*)ctx, state); -} - -static void input_callback(InputEvent* input_event, void* ctx) { - osMessageQueueId_t event_queue = ctx; - - AppEvent event; - event.type = EventTypeKey; - event.value.input = *input_event; - osMessageQueuePut(event_queue, &event, 0, 0); -} - -int32_t keypad_test(void* p) { - osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(AppEvent), NULL); - furi_check(event_queue); - - State _state = {{false, false, false, false, false}, 0, 0, 0, 0, 0}; - - ValueMutex state_mutex; - if(!init_mutex(&state_mutex, &_state, sizeof(State))) { - printf("[keypad_test] cannot create mutex\r\n"); - return 0; - } - - ViewPort* view_port = view_port_alloc(); - - view_port_draw_callback_set(view_port, render_callback, &state_mutex); - view_port_input_callback_set(view_port, input_callback, event_queue); - - // Open GUI and register view_port - Gui* gui = furi_record_open("gui"); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - AppEvent event; - while(1) { - osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, osWaitForever); - State* state = (State*)acquire_mutex_block(&state_mutex); - - if(event_status == osOK) { - if(event.type == EventTypeKey) { - if(event.value.input.type == InputTypeLong && - event.value.input.key == InputKeyBack) { - printf("[keypad test] bye!\r\n"); - release_mutex(&state_mutex, state); - break; - } - - if(event.value.input.type == InputTypeShort && - event.value.input.key == InputKeyBack) { - reset_state(state); - } - - if(event.value.input.key == InputKeyRight) { - if(event.value.input.type == InputTypePress) { - state->press[0] = true; - } else if(event.value.input.type == InputTypeRelease) { - state->press[0] = false; - } - - if(event.value.input.type == InputTypeShort) { - ++state->right; - } - } - - if(event.value.input.key == InputKeyLeft) { - if(event.value.input.type == InputTypePress) { - state->press[1] = true; - } else if(event.value.input.type == InputTypeRelease) { - state->press[1] = false; - } - - if(event.value.input.type == InputTypeShort) { - ++state->left; - } - } - - if(event.value.input.key == InputKeyUp) { - if(event.value.input.type == InputTypePress) { - state->press[2] = true; - } else if(event.value.input.type == InputTypeRelease) { - state->press[2] = false; - } - - if(event.value.input.type == InputTypeShort) { - ++state->up; - } - } - - if(event.value.input.key == InputKeyDown) { - if(event.value.input.type == InputTypePress) { - state->press[3] = true; - } else if(event.value.input.type == InputTypeRelease) { - state->press[3] = false; - } - - if(event.value.input.type == InputTypeShort) { - ++state->down; - } - } - - if(event.value.input.key == InputKeyOk) { - if(event.value.input.type == InputTypePress) { - state->press[4] = true; - } else if(event.value.input.type == InputTypeRelease) { - state->press[4] = false; - } - - if(event.value.input.type == InputTypeShort) { - ++state->ok; - } - } - } - } - view_port_update(view_port); - release_mutex(&state_mutex, state); - } - // remove & free all stuff created by app - gui_remove_view_port(gui, view_port); - view_port_free(view_port); - osMessageQueueDelete(event_queue); - delete_mutex(&state_mutex); - - return 0; -} \ No newline at end of file diff --git a/applications/examples/u8g2_example.c b/applications/examples/u8g2_example.c deleted file mode 100644 index e5370309f72..00000000000 --- a/applications/examples/u8g2_example.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "u8g2/u8g2.h" -#include - -int32_t u8g2_example(void* p) { - // open record - u8g2_t* fb = furi_record_open("u8g2_fb"); - u8g2_SetFont(fb, u8g2_font_6x10_mf); - u8g2_SetDrawColor(fb, 1); - u8g2_SetFontMode(fb, 1); - u8g2_DrawStr(fb, 2, 12, "hello world!"); - furi_record_close("u8g2_fb"); - - return 0; -} \ No newline at end of file diff --git a/applications/examples/u8g2_qrcode.c b/applications/examples/u8g2_qrcode.c deleted file mode 100644 index f71a0ca349e..00000000000 --- a/applications/examples/u8g2_qrcode.c +++ /dev/null @@ -1,76 +0,0 @@ -#include "u8g2/u8g2.h" -#include "qrcode/qrcode.h" -#include - -/* -TODO: rework with new app api - -void u8g2_DrawPixelSize(u8g2_t* u8g2, uint8_t x, uint8_t y, uint8_t size) { - for(uint8_t px = 0; px < size; px++) { - for(uint8_t py = 0; py < size; py++) { - u8g2_DrawPixel(u8g2, x + px, y + py); - } - } -} - -int32_t u8g2_qrcode(void* p) { - // open record - FuriRecordSubscriber* fb_record = - furi_open_deprecated("u8g2_fb", false, false, NULL, NULL, NULL); - - // Allocate a chunk of memory to store the QR code - // https://github.com/ricmoo/QRCode - // we init version 1, 21x21 px, 16 alphanumeric chars with - // QUARTILE error correction - const uint8_t qr_version = 1; - const uint8_t qr_error_correction = ECC_QUARTILE; - - const uint8_t qr_x = 32; - const uint8_t qr_y = 0; - const uint8_t qr_size = 3; - - // The structure to manage the QR code - QRCode qrcode; - - // QR Code init - uint8_t qrcodeBytes[qrcode_getBufferSize(qr_version)]; - qrcode_initText(&qrcode, qrcodeBytes, qr_version, qr_error_correction, "HELLO FLIPPER"); - - if(fb_record == NULL) { - printf("[view_port] cannot create fb record\r\n"); - return 255; - } - - u8g2_t* fb = furi_take(fb_record); - - // clear display - if(fb != NULL) { - u8g2_ClearBuffer(fb); - } - - while(1) { - if(fb != NULL) { - // draw qr code - for(uint8_t y = 0; y < qrcode.size; y++) { - for(uint8_t x = 0; x < qrcode.size; x++) { - if(qrcode_getModule(&qrcode, x, y)) { - u8g2_SetDrawColor(fb, 1); - u8g2_DrawPixelSize(fb, qr_x + x * qr_size, qr_y + y * qr_size, qr_size); - } else { - u8g2_SetDrawColor(fb, 0); - u8g2_DrawPixelSize(fb, qr_x + x * qr_size, qr_y + y * qr_size, qr_size); - } - } - } - } else { - return 255; - } - - furi_commit(fb_record); - - delay(1); - } - - return 0; -} -*/ \ No newline at end of file diff --git a/applications/examples/uart_write.c b/applications/examples/uart_write.c deleted file mode 100644 index 9c3b339b97f..00000000000 --- a/applications/examples/uart_write.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include -#include - -int32_t application_uart_write(void* p) { - // Red led for showing progress - GpioPin led = {.pin = GPIO_PIN_8, .port = GPIOA}; - // TODO open record - GpioPin* led_record = &led; - - hal_gpio_init(led_record, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); - - // create buffer - const char test_string[] = "test\n"; - printf(test_string); - - // for example, create counter and show its value - uint8_t counter = 0; - - while(1) { - // continously write it to UART - printf("counter: %d\n", counter); - counter++; - - // flash at every send - hal_gpio_write(led_record, false); - delay(50); - hal_gpio_write(led_record, true); - - // delay with overall perion of 1s - delay(950); - } - - return 0; -} \ No newline at end of file diff --git a/applications/examples/vertical_submenu.c b/applications/examples/vertical_submenu.c deleted file mode 100644 index 94e3710d67d..00000000000 --- a/applications/examples/vertical_submenu.c +++ /dev/null @@ -1,103 +0,0 @@ -#include -#include -#include -#include - -static ViewDispatcher* view_dispatcher; -static osMessageQueueId_t event_queue; - -typedef enum { - EventTypeGoAway, - EventTypeGoToMainMenu, - EventTypeSwitchToVertical, - EventTypeSwitchToHorizontal, -} EventType; - -// Nothing dangerous in settings some vars and flags inside callback -static void submenu_callback(void* context, uint32_t index) { - EventType event = EventTypeGoAway; - switch(index) { - case 1: - event = EventTypeSwitchToVertical; - break; - case 2: - event = EventTypeSwitchToHorizontal; - break; - default: - break; - } - - osMessageQueuePut(event_queue, &event, 0, 0); -} - -uint32_t previous_exit_callback(void* context) { - EventType event = EventTypeGoAway; - osMessageQueuePut(event_queue, &event, 0, 0); - return VIEW_IGNORE; -} - -uint32_t previous_callback(void* context) { - EventType event = EventTypeGoToMainMenu; - osMessageQueuePut(event_queue, &event, 0, 0); - return VIEW_IGNORE; -} - -int32_t application_vertical_screen(void* p) { - event_queue = osMessageQueueNew(8, sizeof(EventType), NULL); - - view_dispatcher = view_dispatcher_alloc(); - Gui* gui = furi_record_open("gui"); - view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen); - - Submenu* submenu = submenu_alloc(); - View* submenu_view = submenu_get_view(submenu); - view_set_previous_callback(submenu_view, previous_exit_callback); - view_set_orientation(submenu_view, ViewOrientationVertical); - submenu_add_item(submenu, "VerSubm", 1, submenu_callback, view_dispatcher); - submenu_add_item(submenu, "HorSubm", 2, submenu_callback, view_dispatcher); - view_dispatcher_add_view(view_dispatcher, 1, submenu_view); - - Submenu* submenu_vertical = submenu_alloc(); - View* submenu_vertical_view = submenu_get_view(submenu_vertical); - view_set_previous_callback(submenu_vertical_view, previous_callback); - view_set_orientation(submenu_vertical_view, ViewOrientationVertical); - submenu_add_item(submenu_vertical, "Vert1", 1, NULL, view_dispatcher); - submenu_add_item(submenu_vertical, "Vert2", 2, NULL, view_dispatcher); - view_dispatcher_add_view(view_dispatcher, 2, submenu_vertical_view); - - Submenu* submenu_horizontal = submenu_alloc(); - View* submenu_horizontal_view = submenu_get_view(submenu_horizontal); - view_set_previous_callback(submenu_horizontal_view, previous_callback); - view_set_orientation(submenu_horizontal_view, ViewOrientationHorizontal); - submenu_add_item(submenu_horizontal, "Horiz1", 1, NULL, view_dispatcher); - submenu_add_item(submenu_horizontal, "Horiz2", 2, NULL, view_dispatcher); - view_dispatcher_add_view(view_dispatcher, 3, submenu_horizontal_view); - - view_dispatcher_switch_to_view(view_dispatcher, 1); - - while(1) { - EventType event; - furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK); - if(event == EventTypeGoAway) { - break; - } else if(event == EventTypeGoToMainMenu) { - view_dispatcher_switch_to_view(view_dispatcher, 1); - } else if(event == EventTypeSwitchToVertical) { - view_dispatcher_switch_to_view(view_dispatcher, 2); - } else if(event == EventTypeSwitchToHorizontal) { - view_dispatcher_switch_to_view(view_dispatcher, 3); - } - } - - view_dispatcher_remove_view(view_dispatcher, 1); - view_dispatcher_remove_view(view_dispatcher, 2); - view_dispatcher_remove_view(view_dispatcher, 3); - submenu_free(submenu); - submenu_free(submenu_vertical); - submenu_free(submenu_horizontal); - view_dispatcher_free(view_dispatcher); - osMessageQueueDelete(event_queue); - furi_record_close("gui"); - - return 0; -} diff --git a/applications/gpio-tester/gpio-tester.c b/applications/gpio-tester/gpio-tester.c index a61cc0ce5bb..4d079632cc7 100644 --- a/applications/gpio-tester/gpio-tester.c +++ b/applications/gpio-tester/gpio-tester.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -44,7 +44,7 @@ static void render_callback(Canvas* canvas, void* ctx) { canvas_clear(canvas); canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 2, 10, "GPIO demo"); + canvas_draw_str(canvas, 2, 10, "GPIO Control"); canvas_set_font(canvas, FontSecondary); canvas_draw_str(canvas, 2, 25, GPIO_PINS[state->gpio_index].name); @@ -60,7 +60,7 @@ static void input_callback(InputEvent* input_event, void* ctx) { osMessageQueuePut(event_queue, &event, 0, 0); } -int32_t app_gpio_test(void* p) { +int32_t gpio_test_app(void* p) { osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(AppEvent), NULL); furi_check(event_queue); diff --git a/applications/gui-test/gui-test.c b/applications/gui-test/gui-test.c deleted file mode 100644 index 19addf2f48d..00000000000 --- a/applications/gui-test/gui-test.c +++ /dev/null @@ -1,239 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define GUI_TEST_FLAG_EXIT 0x00000001U - -typedef enum { - GuiTesterViewTextInput = 0, - GuiTesterViewSubmenu, - GuiTesterViewDialog, - GuiTesterViewDialogEx, - GuiTesterViewPopup, - GuiTesterViewByteInput, - GuiTesterViewLast -} GuiTesterView; - -typedef struct { - ViewDispatcher* view_dispatcher; - Dialog* dialog; - DialogEx* dialog_ex; - Submenu* submenu; - TextInput* text_input; - Popup* popup; - ByteInput* byte_input; - GuiTesterView view_index; -} GuiTester; - -static GuiTester* gui_test_alloc(void) { - GuiTester* gui_tester = furi_alloc(sizeof(GuiTester)); - gui_tester->view_dispatcher = view_dispatcher_alloc(); - gui_tester->view_index = GuiTesterViewByteInput; - - gui_tester->dialog = dialog_alloc(); - view_dispatcher_add_view( - gui_tester->view_dispatcher, GuiTesterViewDialog, dialog_get_view(gui_tester->dialog)); - - gui_tester->dialog_ex = dialog_ex_alloc(); - view_dispatcher_add_view( - gui_tester->view_dispatcher, - GuiTesterViewDialogEx, - dialog_ex_get_view(gui_tester->dialog_ex)); - - gui_tester->submenu = submenu_alloc(); - view_dispatcher_add_view( - gui_tester->view_dispatcher, GuiTesterViewSubmenu, submenu_get_view(gui_tester->submenu)); - - gui_tester->text_input = text_input_alloc(); - view_dispatcher_add_view( - gui_tester->view_dispatcher, - GuiTesterViewTextInput, - text_input_get_view(gui_tester->text_input)); - - gui_tester->popup = popup_alloc(); - view_dispatcher_add_view( - gui_tester->view_dispatcher, GuiTesterViewPopup, popup_get_view(gui_tester->popup)); - - gui_tester->byte_input = byte_input_alloc(); - view_dispatcher_add_view( - gui_tester->view_dispatcher, - GuiTesterViewByteInput, - byte_input_get_view(gui_tester->byte_input)); - - return gui_tester; -} - -static void gui_test_free(GuiTester* gui_tester) { - furi_assert(gui_tester); - view_dispatcher_remove_view(gui_tester->view_dispatcher, GuiTesterViewDialog); - dialog_free(gui_tester->dialog); - view_dispatcher_remove_view(gui_tester->view_dispatcher, GuiTesterViewDialogEx); - dialog_ex_free(gui_tester->dialog_ex); - view_dispatcher_remove_view(gui_tester->view_dispatcher, GuiTesterViewSubmenu); - submenu_free(gui_tester->submenu); - view_dispatcher_remove_view(gui_tester->view_dispatcher, GuiTesterViewTextInput); - text_input_free(gui_tester->text_input); - view_dispatcher_remove_view(gui_tester->view_dispatcher, GuiTesterViewPopup); - popup_free(gui_tester->popup); - view_dispatcher_remove_view(gui_tester->view_dispatcher, GuiTesterViewByteInput); - byte_input_free(gui_tester->byte_input); - - view_dispatcher_free(gui_tester->view_dispatcher); - free(gui_tester); -} - -static void next_view(void* context) { - furi_assert(context); - GuiTester* gui_tester = context; - - gui_tester->view_index++; - if(gui_tester->view_index >= GuiTesterViewLast) { - gui_tester->view_index = 0; - } - - view_dispatcher_switch_to_view(gui_tester->view_dispatcher, gui_tester->view_index); -} - -static void popup_callback(void* context) { - next_view(context); -} - -static void submenu_callback(void* context, uint32_t index) { - next_view(context); -} - -static void dialog_callback(DialogResult result, void* context) { - next_view(context); -} - -static void dialog_ex_callback(DialogExResult result, void* context) { - next_view(context); -} - -static void text_input_callback(void* context) { - next_view(context); -} - -static void byte_input_callback(void* context) { - next_view(context); -} - -static void event_cb(const void* value, void* ctx) { - furi_assert(value); - furi_assert(ctx); - const InputEvent* event = value; - if(event->key == InputKeyBack && event->type == InputTypeLong) { - osThreadFlagsSet((osThreadId_t)ctx, GUI_TEST_FLAG_EXIT); - } -} - -int32_t gui_test(void* param) { - (void)param; - PubSub* event_record = furi_record_open("input_events"); - PubSubItem* event_pubsub = subscribe_pubsub(event_record, event_cb, (void*)osThreadGetId()); - GuiTester* gui_tester = gui_test_alloc(); - - Gui* gui = furi_record_open("gui"); - view_dispatcher_attach_to_gui(gui_tester->view_dispatcher, gui, ViewDispatcherTypeFullscreen); - - // Submenu - submenu_add_item(gui_tester->submenu, "Read", 0, submenu_callback, gui_tester); - submenu_add_item(gui_tester->submenu, "Saved", 0, submenu_callback, gui_tester); - submenu_add_item(gui_tester->submenu, "Emulate", 0, submenu_callback, gui_tester); - submenu_add_item(gui_tester->submenu, "Enter manually", 0, submenu_callback, gui_tester); - submenu_add_item(gui_tester->submenu, "Blah blah", 0, submenu_callback, gui_tester); - submenu_add_item(gui_tester->submenu, "Set time", 0, submenu_callback, gui_tester); - submenu_add_item(gui_tester->submenu, "Gender-bender", 0, submenu_callback, gui_tester); - submenu_add_item( - gui_tester->submenu, "Hack American Elections", 0, submenu_callback, gui_tester); - submenu_add_item(gui_tester->submenu, "Hack the White House", 0, submenu_callback, gui_tester); - - // Dialog - dialog_set_result_callback(gui_tester->dialog, dialog_callback); - dialog_set_context(gui_tester->dialog, gui_tester); - dialog_set_header_text(gui_tester->dialog, "Delete Abc123?"); - dialog_set_text(gui_tester->dialog, "ID: F0 00 01 02 03 04\nAre you shure?"); - dialog_set_left_button_text(gui_tester->dialog, "Yes"); - dialog_set_right_button_text(gui_tester->dialog, "No"); - - // Dialog extended - dialog_ex_set_result_callback(gui_tester->dialog_ex, dialog_ex_callback); - dialog_ex_set_context(gui_tester->dialog_ex, gui_tester); - dialog_ex_set_header(gui_tester->dialog_ex, "Dallas", 95, 12, AlignCenter, AlignCenter); - dialog_ex_set_text( - gui_tester->dialog_ex, "F6 E5 D4\nC3 B2 A1", 95, 32, AlignCenter, AlignCenter); - dialog_ex_set_icon(gui_tester->dialog_ex, 0, 1, &I_DolphinExcited_64x63); - dialog_ex_set_left_button_text(gui_tester->dialog_ex, "More"); - dialog_ex_set_right_button_text(gui_tester->dialog_ex, "Save"); - - // Popup - popup_set_callback(gui_tester->popup, popup_callback); - popup_set_context(gui_tester->popup, gui_tester); - popup_set_icon(gui_tester->popup, 0, 2, &I_DolphinMafia_115x62); - popup_set_text(gui_tester->popup, "Deleted", 83, 19, AlignLeft, AlignBottom); - popup_set_timeout(gui_tester->popup, 5000); - popup_enable_timeout(gui_tester->popup); - - // Text input - const uint8_t text_input_text_len = 64; - char* text_input_text = calloc(text_input_text_len + 1, 1); - memcpy(text_input_text, "New_ke", strlen("New_ke")); - - text_input_set_result_callback( - gui_tester->text_input, - text_input_callback, - gui_tester, - text_input_text, - text_input_text_len, - false); - text_input_set_header_text(gui_tester->text_input, "Name the key"); - - const uint8_t byte_input_bytes_len = 16; - uint8_t byte_input_bytes[16] = { - 0x00, - 0x01, - 0x02, - 0x03, - 0x04, - 0x05, - 0x06, - 0x07, - 0x08, - 0x09, - 0x0A, - 0x0B, - 0x0C, - 0x0D, - 0x0E, - 0x0F}; - - byte_input_set_result_callback( - gui_tester->byte_input, - byte_input_callback, - NULL, - gui_tester, - byte_input_bytes, - byte_input_bytes_len); - byte_input_set_header_text(gui_tester->byte_input, "Enter the key"); - - view_dispatcher_switch_to_view(gui_tester->view_dispatcher, gui_tester->view_index); - - while(1) { - if(osThreadFlagsWait(GUI_TEST_FLAG_EXIT, osFlagsWaitAny, osWaitForever)) { - break; - } - } - unsubscribe_pubsub(event_pubsub); - free(text_input_text); - gui_test_free(gui_tester); - - return 0; -} \ No newline at end of file diff --git a/applications/gui/canvas.c b/applications/gui/canvas.c index 3e4d0d85820..1dee2258149 100644 --- a/applications/gui/canvas.c +++ b/applications/gui/canvas.c @@ -3,7 +3,7 @@ #include "icon_animation_i.h" #include -#include +#include uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr); uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr); @@ -11,7 +11,7 @@ uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ Canvas* canvas_init() { Canvas* canvas = furi_alloc(sizeof(Canvas)); - api_hal_power_insomnia_enter(); + furi_hal_power_insomnia_enter(); canvas->orientation = CanvasOrientationHorizontal; u8g2_Setup_st7565_erc12864_alt_f( @@ -21,10 +21,11 @@ Canvas* canvas_init() { u8g2_InitDisplay(&canvas->fb); u8g2_SetContrast(&canvas->fb, 36); // wake up display + u8g2_ClearBuffer(&canvas->fb); u8g2_SetPowerSave(&canvas->fb, 0); u8g2_SendBuffer(&canvas->fb); - api_hal_power_insomnia_exit(); + furi_hal_power_insomnia_exit(); return canvas; } diff --git a/applications/gui/gui.c b/applications/gui/gui.c index efad82ed51c..8ad45499a2c 100644 --- a/applications/gui/gui.c +++ b/applications/gui/gui.c @@ -420,7 +420,7 @@ Gui* gui_alloc() { return gui; } -int32_t gui_task(void* p) { +int32_t gui_srv(void* p) { Gui* gui = gui_alloc(); furi_record_create("gui", gui); diff --git a/applications/gui/modules/button_menu.c b/applications/gui/modules/button_menu.c index f496aebeea6..e342162e00e 100644 --- a/applications/gui/modules/button_menu.c +++ b/applications/gui/modules/button_menu.c @@ -1,6 +1,7 @@ #include "button_menu.h" #include "gui/canvas.h" #include "gui/elements.h" +#include "input/input.h" #include #include #include @@ -23,6 +24,7 @@ ARRAY_DEF(ButtonMenuItemArray, ButtonMenuItem, M_POD_OPLIST); struct ButtonMenu { View* view; + bool freeze_input; }; typedef struct { @@ -158,7 +160,7 @@ static void button_menu_process_down(ButtonMenu* button_menu) { }); } -static void button_menu_process_ok(ButtonMenu* button_menu) { +static void button_menu_process_ok(ButtonMenu* button_menu, InputType type) { furi_assert(button_menu); ButtonMenuItem* item = NULL; @@ -168,11 +170,22 @@ static void button_menu_process_ok(ButtonMenu* button_menu) { if(model->position < (ButtonMenuItemArray_size(model->items))) { item = ButtonMenuItemArray_get(model->items, model->position); } - return true; + return false; }); - if(item && item->callback) { - item->callback(item->callback_context, item->index); + if(item->type == ButtonMenuItemTypeControl) { + if(type == InputTypeShort) { + if(item && item->callback) { + item->callback(item->callback_context, item->index, type); + } + } + } + if(item->type == ButtonMenuItemTypeCommon) { + if((type == InputTypePress) || (type == InputTypeRelease)) { + if(item && item->callback) { + item->callback(item->callback_context, item->index, type); + } + } } } @@ -182,7 +195,19 @@ static bool button_menu_view_input_callback(InputEvent* event, void* context) { ButtonMenu* button_menu = context; bool consumed = false; - if(event->type == InputTypeShort) { + if(event->key == InputKeyOk) { + if((event->type == InputTypeRelease) || (event->type == InputTypePress)) { + consumed = true; + button_menu->freeze_input = (event->type == InputTypePress); + button_menu_process_ok(button_menu, event->type); + } else if(event->type == InputTypeShort) { + consumed = true; + button_menu_process_ok(button_menu, event->type); + } + } + + if(!button_menu->freeze_input && + ((event->type == InputTypeRepeat) || (event->type == InputTypeShort))) { switch(event->key) { case InputKeyUp: consumed = true; @@ -192,10 +217,6 @@ static bool button_menu_view_input_callback(InputEvent* event, void* context) { consumed = true; button_menu_process_down(button_menu); break; - case InputKeyOk: - consumed = true; - button_menu_process_ok(button_menu); - break; default: break; } @@ -272,6 +293,7 @@ ButtonMenu* button_menu_alloc(void) { return true; }); + button_menu->freeze_input = false; return button_menu; } diff --git a/applications/gui/modules/button_menu.h b/applications/gui/modules/button_menu.h index 8228a95fc45..35355d6bf98 100644 --- a/applications/gui/modules/button_menu.h +++ b/applications/gui/modules/button_menu.h @@ -11,7 +11,7 @@ typedef struct ButtonMenu ButtonMenu; typedef struct ButtonMenuItem ButtonMenuItem; /* Callback for any button menu actions */ -typedef void (*ButtonMenuItemCallback)(void* context, int32_t index); +typedef void (*ButtonMenuItemCallback)(void* context, int32_t index, InputType type); /* Type of button. Difference in drawing buttons. */ typedef enum { diff --git a/applications/gui/modules/button_panel.c b/applications/gui/modules/button_panel.c index 7bb5cf05c23..b4cffe05095 100644 --- a/applications/gui/modules/button_panel.c +++ b/applications/gui/modules/button_panel.c @@ -1,5 +1,5 @@ #include "button_panel.h" -#include "api-hal-resources.h" +#include "furi-hal-resources.h" #include "gui/canvas.h" #include #include diff --git a/applications/gui/u8g2_periphery.c b/applications/gui/u8g2_periphery.c index e738ec184fb..6740b82b5e0 100644 --- a/applications/gui/u8g2_periphery.c +++ b/applications/gui/u8g2_periphery.c @@ -1,8 +1,8 @@ #include "u8g2/u8g2.h" -#include +#include #include -static ApiHalSpiDevice* u8g2_periphery_display = NULL; +static FuriHalSpiDevice* u8g2_periphery_display = NULL; uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { switch(msg) { @@ -36,7 +36,7 @@ uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, vo uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { switch(msg) { case U8X8_MSG_BYTE_SEND: - api_hal_spi_bus_tx(u8g2_periphery_display->bus, (uint8_t*)arg_ptr, arg_int, 10000); + furi_hal_spi_bus_tx(u8g2_periphery_display->bus, (uint8_t*)arg_ptr, arg_int, 10000); break; case U8X8_MSG_BYTE_SET_DC: @@ -49,14 +49,14 @@ uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ case U8X8_MSG_BYTE_START_TRANSFER: furi_assert(u8g2_periphery_display == NULL); u8g2_periphery_display = - (ApiHalSpiDevice*)api_hal_spi_device_get(ApiHalSpiDeviceIdDisplay); + (FuriHalSpiDevice*)furi_hal_spi_device_get(FuriHalSpiDeviceIdDisplay); hal_gpio_write(u8g2_periphery_display->chip_select, false); break; case U8X8_MSG_BYTE_END_TRANSFER: furi_assert(u8g2_periphery_display); hal_gpio_write(u8g2_periphery_display->chip_select, true); - api_hal_spi_device_return(u8g2_periphery_display); + furi_hal_spi_device_return(u8g2_periphery_display); u8g2_periphery_display = NULL; break; diff --git a/applications/ibutton/helpers/key-reader.cpp b/applications/ibutton/helpers/key-reader.cpp index f58858708cf..91ada0580a0 100644 --- a/applications/ibutton/helpers/key-reader.cpp +++ b/applications/ibutton/helpers/key-reader.cpp @@ -183,12 +183,12 @@ void KeyReader::switch_mode_if_needed() { } void KeyReader::start() { - api_hal_power_enable_otg(); + furi_hal_power_enable_otg(); switch_to(ReadMode::CYFRAL_METAKOM); } void KeyReader::stop() { - api_hal_power_disable_otg(); + furi_hal_power_disable_otg(); onewire_master->stop(); stop_comaparator(); } diff --git a/applications/ibutton/helpers/key-writer.cpp b/applications/ibutton/helpers/key-writer.cpp index a39a7f7c44d..428be8f12a9 100644 --- a/applications/ibutton/helpers/key-writer.cpp +++ b/applications/ibutton/helpers/key-writer.cpp @@ -14,12 +14,12 @@ KeyWriter::Error KeyWriter::write(iButtonKey* key) { } void KeyWriter::start() { - api_hal_power_enable_otg(); + furi_hal_power_enable_otg(); onewire_master->start(); } void KeyWriter::stop() { - api_hal_power_disable_otg(); + furi_hal_power_disable_otg(); onewire_master->stop(); } diff --git a/applications/ibutton/helpers/pulse-sequencer.cpp b/applications/ibutton/helpers/pulse-sequencer.cpp index c7637b4d41c..21818a3b03a 100644 --- a/applications/ibutton/helpers/pulse-sequencer.cpp +++ b/applications/ibutton/helpers/pulse-sequencer.cpp @@ -1,7 +1,7 @@ #include "pulse-sequencer.h" #include #include -#include +#include void PulseSequencer::set_periods( uint32_t* _periods, diff --git a/applications/ibutton/ibutton-app.cpp b/applications/ibutton/ibutton-app.cpp index 082c267327d..651d754d2c4 100644 --- a/applications/ibutton/ibutton-app.cpp +++ b/applications/ibutton/ibutton-app.cpp @@ -38,7 +38,7 @@ void iButtonApp::run(void* args) { iButtonApp::iButtonApp() : notification{"notification"} { - api_hal_power_insomnia_enter(); + furi_hal_power_insomnia_enter(); key_worker = new KeyWorker(&ibutton_gpio); } @@ -49,7 +49,7 @@ iButtonApp::~iButtonApp() { } delete key_worker; - api_hal_power_insomnia_exit(); + furi_hal_power_insomnia_exit(); } iButtonAppViewManager* iButtonApp::get_view_manager() { diff --git a/applications/ibutton/ibutton-cli.cpp b/applications/ibutton/ibutton-cli.cpp index 7602d46dfbe..f865a26eb10 100644 --- a/applications/ibutton/ibutton-cli.cpp +++ b/applications/ibutton/ibutton-cli.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include diff --git a/applications/ibutton/ibutton.cpp b/applications/ibutton/ibutton.cpp index 806f3ed08b5..f6bc92754b6 100644 --- a/applications/ibutton/ibutton.cpp +++ b/applications/ibutton/ibutton.cpp @@ -1,7 +1,7 @@ #include "ibutton-app.h" // app enter function -extern "C" int32_t app_ibutton(void* p) { +extern "C" int32_t ibutton_app(void* p) { iButtonApp* app = new iButtonApp(); app->run(p); delete app; diff --git a/applications/input/input.c b/applications/input/input.c index 0a4a3990567..32a355979dc 100644 --- a/applications/input/input.c +++ b/applications/input/input.c @@ -91,7 +91,7 @@ void input_cli_send(Cli* cli, string_t args, void* context) { notify_pubsub(&input->event_pubsub, &event); } -int32_t input_task() { +int32_t input_srv() { input = furi_alloc(sizeof(Input)); input->thread = osThreadGetId(); init_pubsub(&input->event_pubsub); diff --git a/applications/input/input.h b/applications/input/input.h index 3e855eec2d6..1ad825557b0 100644 --- a/applications/input/input.h +++ b/applications/input/input.h @@ -1,6 +1,6 @@ #pragma once -#include +#include /* Input Types * Some of them are physical events and some logical diff --git a/applications/input/input_i.h b/applications/input/input_i.h index a3262fc4e13..a0f6cfc36e6 100644 --- a/applications/input/input_i.h +++ b/applications/input/input_i.h @@ -9,7 +9,7 @@ #include #include #include -#include +#include #define INPUT_DEBOUNCE_TICKS_HALF (INPUT_DEBOUNCE_TICKS / 2) #define INPUT_PRESS_TICKS 150 diff --git a/applications/irda/cli/irda-cli.cpp b/applications/irda/cli/irda-cli.cpp index 07aef32788f..6cde9c95d24 100644 --- a/applications/irda/cli/irda-cli.cpp +++ b/applications/irda/cli/irda-cli.cpp @@ -1,11 +1,11 @@ -#include +#include #include #include #include #include #include #include -#include +#include #include #include #include @@ -19,7 +19,7 @@ static void signal_received_callback(void* context, IrdaWorkerSignal* received_s Cli* cli = (Cli*)context; if(irda_worker_signal_is_decoded(received_signal)) { - const IrdaMessage* message = irda_worker_get_decoded_message(received_signal); + const IrdaMessage* message = irda_worker_get_decoded_signal(received_signal); buf_cnt = sniprintf( buf, sizeof(buf), @@ -48,22 +48,21 @@ static void signal_received_callback(void* context, IrdaWorkerSignal* received_s } static void irda_cli_start_ir_rx(Cli* cli, string_t args, void* context) { - if(api_hal_irda_is_busy()) { + if(furi_hal_irda_is_busy()) { printf("IRDA is busy. Exit."); return; } IrdaWorker* worker = irda_worker_alloc(); - irda_worker_set_context(worker, cli); - irda_worker_start(worker); - irda_worker_set_received_signal_callback(worker, signal_received_callback); + irda_worker_rx_start(worker); + irda_worker_rx_set_received_signal_callback(worker, signal_received_callback, cli); printf("Receiving IRDA...\r\nPress Ctrl+C to abort\r\n"); while(!cli_cmd_interrupt_received(cli)) { delay(50); } - irda_worker_stop(worker); + irda_worker_rx_stop(worker); irda_worker_free(worker); } @@ -142,7 +141,7 @@ static bool parse_signal_raw( } static void irda_cli_start_ir_tx(Cli* cli, string_t args, void* context) { - if(api_hal_irda_is_busy()) { + if(furi_hal_irda_is_busy()) { printf("IRDA is busy. Exit."); return; } diff --git a/applications/irda/irda-app-brute-force.cpp b/applications/irda/irda-app-brute-force.cpp index 8709dce6d96..42797d2197e 100644 --- a/applications/irda/irda-app-brute-force.cpp +++ b/applications/irda/irda-app-brute-force.cpp @@ -1,5 +1,5 @@ -#include "irda-app-brute-force.hpp" -#include "irda/irda-app-file-parser.hpp" +#include "irda-app-brute-force.h" +#include "irda/irda-app-file-parser.h" #include "m-string.h" #include #include @@ -47,7 +47,6 @@ void IrdaAppBruteForce::stop_bruteforce() { } } -// TODO: [FL-1418] replace with timer-chained consequence of messages. bool IrdaAppBruteForce::send_next_bruteforce(void) { furi_assert(current_record.size()); furi_assert(file_parser); diff --git a/applications/irda/irda-app-brute-force.hpp b/applications/irda/irda-app-brute-force.h similarity index 85% rename from applications/irda/irda-app-brute-force.hpp rename to applications/irda/irda-app-brute-force.h index ef9ab80dfbd..174f74f54a5 100644 --- a/applications/irda/irda-app-brute-force.hpp +++ b/applications/irda/irda-app-brute-force.h @@ -1,7 +1,7 @@ #pragma once #include "furi/check.h" #include -#include "irda-app-file-parser.hpp" +#include "irda-app-file-parser.h" #include class IrdaAppBruteForce { @@ -28,7 +28,9 @@ class IrdaAppBruteForce { bool start_bruteforce(int index, int& record_amount); void add_record(int index, const char* name); - IrdaAppBruteForce(const char* filename) : universal_db_filename (filename) {} - ~IrdaAppBruteForce() {} + IrdaAppBruteForce(const char* filename) + : universal_db_filename(filename) { + } + ~IrdaAppBruteForce() { + } }; - diff --git a/applications/irda/irda-app-event.hpp b/applications/irda/irda-app-event.h similarity index 89% rename from applications/irda/irda-app-event.hpp rename to applications/irda/irda-app-event.h index eb4848fa9f7..752ce09fb30 100644 --- a/applications/irda/irda-app-event.hpp +++ b/applications/irda/irda-app-event.h @@ -9,6 +9,8 @@ class IrdaAppEvent { Exit, Back, MenuSelected, + MenuSelectedPress, + MenuSelectedRelease, DialogExSelected, NextScene, IrdaMessageReceived, @@ -24,4 +26,3 @@ class IrdaAppEvent { Type type; }; - diff --git a/applications/irda/irda-app-file-parser.cpp b/applications/irda/irda-app-file-parser.cpp index 11fd563e22f..8cd0499b63b 100644 --- a/applications/irda/irda-app-file-parser.cpp +++ b/applications/irda/irda-app-file-parser.cpp @@ -1,6 +1,6 @@ -#include "irda-app-file-parser.hpp" +#include "irda-app-file-parser.h" #include "furi/check.h" -#include "irda-app-remote-manager.hpp" +#include "irda-app-remote-manager.h" #include "irda-app-signal.h" #include "m-string.h" #include diff --git a/applications/irda/irda-app-file-parser.hpp b/applications/irda/irda-app-file-parser.h similarity index 81% rename from applications/irda/irda-app-file-parser.hpp rename to applications/irda/irda-app-file-parser.h index 2ece1a30c1e..f3d42e491d9 100644 --- a/applications/irda/irda-app-file-parser.hpp +++ b/applications/irda/irda-app-file-parser.h @@ -26,8 +26,16 @@ class IrdaAppFileParser { std::string make_name(const std::string& full_name) const; private: - size_t stringify_message(const IrdaAppSignal& signal, const char* name, char* content, size_t content_len); - size_t stringify_raw_signal(const IrdaAppSignal& signal, const char* name, char* content, size_t content_len); + size_t stringify_message( + const IrdaAppSignal& signal, + const char* name, + char* content, + size_t content_len); + size_t stringify_raw_signal( + const IrdaAppSignal& signal, + const char* name, + char* content, + size_t content_len); std::unique_ptr parse_signal(const std::string& str) const; std::unique_ptr parse_signal_raw(const std::string& str) const; std::string make_full_name(const std::string& name) const; @@ -41,4 +49,3 @@ class IrdaAppFileParser { char file_buf[128]; size_t file_buf_cnt = 0; }; - diff --git a/applications/irda/irda-app-remote-manager.cpp b/applications/irda/irda-app-remote-manager.cpp index 4c339e85f89..cd98893e051 100644 --- a/applications/irda/irda-app-remote-manager.cpp +++ b/applications/irda/irda-app-remote-manager.cpp @@ -1,4 +1,4 @@ -#include "irda-app-remote-manager.hpp" +#include "irda-app-remote-manager.h" #include #include "furi.h" #include "furi/check.h" @@ -8,7 +8,7 @@ #include #include #include -#include "irda-app-file-parser.hpp" +#include "irda-app-file-parser.h" static const std::string default_remote_name = "remote"; diff --git a/applications/irda/irda-app-remote-manager.hpp b/applications/irda/irda-app-remote-manager.h similarity index 88% rename from applications/irda/irda-app-remote-manager.hpp rename to applications/irda/irda-app-remote-manager.h index e8e0a48c677..60993b3083b 100644 --- a/applications/irda/irda-app-remote-manager.hpp +++ b/applications/irda/irda-app-remote-manager.h @@ -12,21 +12,27 @@ class IrdaAppRemoteButton { friend class IrdaAppRemoteManager; std::string name; IrdaAppSignal signal; + public: IrdaAppRemoteButton(const char* name, const IrdaAppSignal& signal) - : name(name), signal (signal) {} - ~IrdaAppRemoteButton() {} + : name(name) + , signal(signal) { + } + ~IrdaAppRemoteButton() { + } }; class IrdaAppRemote { friend class IrdaAppRemoteManager; std::vector buttons; std::string name; + public: - IrdaAppRemote(const std::string& name) : name(name) {} + IrdaAppRemote(const std::string& name) + : name(name) { + } - IrdaAppRemote& operator=(std::string& new_name) noexcept - { + IrdaAppRemote& operator=(std::string& new_name) noexcept { name = new_name; buttons.clear(); return *this; @@ -61,4 +67,3 @@ class IrdaAppRemoteManager { bool store(); bool load(const std::string& name); }; - diff --git a/applications/irda/irda-app-view-manager.cpp b/applications/irda/irda-app-view-manager.cpp index cc2371f7355..6c65b00531d 100644 --- a/applications/irda/irda-app-view-manager.cpp +++ b/applications/irda/irda-app-view-manager.cpp @@ -1,7 +1,7 @@ #include "furi.h" #include "gui/modules/button_panel.h" -#include "irda-app.hpp" -#include "irda/irda-app-event.hpp" +#include "irda-app.h" +#include "irda/irda-app-event.h" #include IrdaAppViewManager::IrdaAppViewManager() { @@ -112,8 +112,14 @@ void IrdaAppViewManager::receive_event(IrdaAppEvent* event) { } void IrdaAppViewManager::send_event(IrdaAppEvent* event) { - osStatus_t result = osMessageQueuePut(event_queue, event, 0, 0); - furi_check(result == osOK); + uint32_t timeout = 0; + /* Rapid button hammering on Remote Scene causes queue overflow - ignore it, + * but try to keep button release event - it switches off IRDA DMA sending. */ + if(event->type == IrdaAppEvent::Type::MenuSelectedRelease) { + timeout = 200; + } + osMessageQueuePut(event_queue, event, 0, timeout); + /* furi_check(result == osOK); */ } uint32_t IrdaAppViewManager::previous_view_callback(void* context) { diff --git a/applications/irda/irda-app-view-manager.hpp b/applications/irda/irda-app-view-manager.h similarity index 98% rename from applications/irda/irda-app-view-manager.hpp rename to applications/irda/irda-app-view-manager.h index 4569a104b35..1f38b472951 100644 --- a/applications/irda/irda-app-view-manager.hpp +++ b/applications/irda/irda-app-view-manager.h @@ -6,7 +6,7 @@ #include #include #include -#include "irda-app.hpp" +#include "irda-app.h" #include "view/irda-app-brut-view.h" #include "gui/modules/button_panel.h" @@ -57,4 +57,3 @@ class IrdaAppViewManager { void add_view(ViewType view_type, View* view); }; - diff --git a/applications/irda/irda-app.cpp b/applications/irda/irda-app.cpp index 1e2de687027..5dd7c7b48a3 100644 --- a/applications/irda/irda-app.cpp +++ b/applications/irda/irda-app.cpp @@ -1,5 +1,5 @@ -#include "irda-app.hpp" -#include "irda/irda-app-file-parser.hpp" +#include "irda-app.h" +#include "irda/irda-app-file-parser.h" #include #include #include @@ -222,22 +222,33 @@ void IrdaApp::notify_click() { notification_message_block(notification, &sequence); } -void IrdaApp::notify_click_and_blink() { +void IrdaApp::notify_click_and_green_blink() { static const NotificationSequence sequence = { &message_click, &message_delay_1, &message_sound_off, - &message_red_0, &message_green_255, - &message_blue_0, &message_delay_10, &message_green_0, + &message_do_not_reset, NULL, }; notification_message_block(notification, &sequence); } +void IrdaApp::notify_blink_green() { + static const NotificationSequence sequence = { + &message_green_255, + &message_delay_10, + &message_green_0, + &message_do_not_reset, + NULL, + }; + + notification_message(notification, &sequence); +} + void IrdaApp::notify_double_vibro() { notification_message(notification, &sequence_double_vibro); } diff --git a/applications/irda/irda-app.hpp b/applications/irda/irda-app.h similarity index 90% rename from applications/irda/irda-app.hpp rename to applications/irda/irda-app.h index 0562aefbd12..cc7611a41b6 100644 --- a/applications/irda/irda-app.hpp +++ b/applications/irda/irda-app.h @@ -2,17 +2,16 @@ #include #include #include -#include "scene/irda-app-scene.hpp" -#include "irda-app-event.hpp" -#include "scene/irda-app-scene.hpp" -#include "irda-app-view-manager.hpp" -#include "irda-app-remote-manager.hpp" +#include "scene/irda-app-scene.h" +#include "irda-app-event.h" +#include "scene/irda-app-scene.h" +#include "irda-app-view-manager.h" +#include "irda-app-remote-manager.h" #include #include #include #include - class IrdaApp { public: enum class EditElement : uint8_t { @@ -71,7 +70,7 @@ class IrdaApp { void set_learn_new_remote(bool value); enum : int { - ButtonNA = -1, + ButtonNA = -1, }; int get_current_button(); void set_current_button(int value); @@ -83,7 +82,8 @@ class IrdaApp { void notify_green_on(); void notify_green_off(); void notify_click(); - void notify_click_and_blink(); + void notify_click_and_green_blink(); + void notify_blink_green(); static void text_input_callback(void* context); static void popup_callback(void* context); @@ -95,9 +95,9 @@ class IrdaApp { ~IrdaApp() { irda_worker_free(irda_worker); furi_record_close("notification"); - for (auto &it : scenes) - delete it.second; + for(auto& it : scenes) delete it.second; } + private: static const uint8_t text_store_size = 128; static const uint8_t text_store_max = 2; @@ -120,7 +120,7 @@ class IrdaApp { {Scene::Start, new IrdaAppSceneStart()}, {Scene::Universal, new IrdaAppSceneUniversal()}, {Scene::UniversalTV, new IrdaAppSceneUniversalTV()}, -// {Scene::UniversalAudio, new IrdaAppSceneUniversalAudio()}, + // {Scene::UniversalAudio, new IrdaAppSceneUniversalAudio()}, {Scene::Learn, new IrdaAppSceneLearn()}, {Scene::LearnSuccess, new IrdaAppSceneLearnSuccess()}, {Scene::LearnEnterName, new IrdaAppSceneLearnEnterName()}, diff --git a/applications/irda/irda-runner.cpp b/applications/irda/irda-runner.cpp index 9753466b8f1..cad6fd0a536 100644 --- a/applications/irda/irda-runner.cpp +++ b/applications/irda/irda-runner.cpp @@ -1,6 +1,6 @@ -#include "irda-app.hpp" +#include "irda-app.h" -extern "C" int32_t irda(void* p) { +extern "C" int32_t irda_app(void* p) { IrdaApp* app = new IrdaApp(); int32_t result = app->run(p); delete app; diff --git a/applications/irda/scene/irda-app-scene-edit-delete-done.cpp b/applications/irda/scene/irda-app-scene-edit-delete-done.cpp index fa5422dd2be..ddde3e7bc62 100644 --- a/applications/irda/scene/irda-app-scene-edit-delete-done.cpp +++ b/applications/irda/scene/irda-app-scene-edit-delete-done.cpp @@ -1,4 +1,4 @@ -#include "../irda-app.hpp" +#include "../irda-app.h" void IrdaAppSceneEditDeleteDone::on_enter(IrdaApp* app) { IrdaAppViewManager* view_manager = app->get_view_manager(); diff --git a/applications/irda/scene/irda-app-scene-edit-delete.cpp b/applications/irda/scene/irda-app-scene-edit-delete.cpp index c16ee7f25bb..c5d1cdd7fc9 100644 --- a/applications/irda/scene/irda-app-scene-edit-delete.cpp +++ b/applications/irda/scene/irda-app-scene-edit-delete.cpp @@ -1,6 +1,6 @@ -#include "../irda-app.hpp" +#include "../irda-app.h" #include "irda.h" -#include "irda/scene/irda-app-scene.hpp" +#include "irda/scene/irda-app-scene.h" #include static void dialog_result_callback(DialogExResult result, void* context) { diff --git a/applications/irda/scene/irda-app-scene-edit-key-select.cpp b/applications/irda/scene/irda-app-scene-edit-key-select.cpp index 41956b1d24d..8a6733d8093 100644 --- a/applications/irda/scene/irda-app-scene-edit-key-select.cpp +++ b/applications/irda/scene/irda-app-scene-edit-key-select.cpp @@ -1,4 +1,4 @@ -#include "../irda-app.hpp" +#include "../irda-app.h" #include "gui/modules/submenu.h" static void submenu_callback(void* context, uint32_t index) { diff --git a/applications/irda/scene/irda-app-scene-edit-rename-done.cpp b/applications/irda/scene/irda-app-scene-edit-rename-done.cpp index 8e547f94f77..d3d135c7a07 100644 --- a/applications/irda/scene/irda-app-scene-edit-rename-done.cpp +++ b/applications/irda/scene/irda-app-scene-edit-rename-done.cpp @@ -1,4 +1,4 @@ -#include "../irda-app.hpp" +#include "../irda-app.h" void IrdaAppSceneEditRenameDone::on_enter(IrdaApp* app) { IrdaAppViewManager* view_manager = app->get_view_manager(); diff --git a/applications/irda/scene/irda-app-scene-edit-rename.cpp b/applications/irda/scene/irda-app-scene-edit-rename.cpp index 24b4d0f940a..d821d03fe75 100644 --- a/applications/irda/scene/irda-app-scene-edit-rename.cpp +++ b/applications/irda/scene/irda-app-scene-edit-rename.cpp @@ -1,4 +1,4 @@ -#include "../irda-app.hpp" +#include "../irda-app.h" void IrdaAppSceneEditRename::on_enter(IrdaApp* app) { IrdaAppViewManager* view_manager = app->get_view_manager(); diff --git a/applications/irda/scene/irda-app-scene-edit.cpp b/applications/irda/scene/irda-app-scene-edit.cpp index 0ecb8d9e2c1..1b659313686 100644 --- a/applications/irda/scene/irda-app-scene-edit.cpp +++ b/applications/irda/scene/irda-app-scene-edit.cpp @@ -1,4 +1,4 @@ -#include "../irda-app.hpp" +#include "../irda-app.h" #include "gui/modules/submenu.h" typedef enum { diff --git a/applications/irda/scene/irda-app-scene-learn-done.cpp b/applications/irda/scene/irda-app-scene-learn-done.cpp index a9bd2049ece..5a3bfcc70e8 100644 --- a/applications/irda/scene/irda-app-scene-learn-done.cpp +++ b/applications/irda/scene/irda-app-scene-learn-done.cpp @@ -1,4 +1,4 @@ -#include "../irda-app.hpp" +#include "../irda-app.h" void IrdaAppSceneLearnDone::on_enter(IrdaApp* app) { IrdaAppViewManager* view_manager = app->get_view_manager(); diff --git a/applications/irda/scene/irda-app-scene-learn-enter-name.cpp b/applications/irda/scene/irda-app-scene-learn-enter-name.cpp index a3b403e063d..185e7fbc3c4 100644 --- a/applications/irda/scene/irda-app-scene-learn-enter-name.cpp +++ b/applications/irda/scene/irda-app-scene-learn-enter-name.cpp @@ -1,4 +1,4 @@ -#include "../irda-app.hpp" +#include "../irda-app.h" #include "gui/modules/text_input.h" void IrdaAppSceneLearnEnterName::on_enter(IrdaApp* app) { diff --git a/applications/irda/scene/irda-app-scene-learn-success.cpp b/applications/irda/scene/irda-app-scene-learn-success.cpp index 4ade76df9a6..8fa0c87b6f7 100644 --- a/applications/irda/scene/irda-app-scene-learn-success.cpp +++ b/applications/irda/scene/irda-app-scene-learn-success.cpp @@ -1,6 +1,6 @@ -#include "../irda-app.hpp" +#include "../irda-app.h" #include "irda.h" -#include "../irda-app-file-parser.hpp" +#include "../irda-app-file-parser.h" #include static void dialog_result_callback(DialogExResult result, void* context) { @@ -51,6 +51,10 @@ void IrdaAppSceneLearnSuccess::on_enter(IrdaApp* app) { bool IrdaAppSceneLearnSuccess::on_event(IrdaApp* app, IrdaAppEvent* event) { bool consumed = false; + if(event->type == IrdaAppEvent::Type::Tick) { + /* Send event every tick to suppress any switching off green light */ + app->notify_green_on(); + } if(event->type == IrdaAppEvent::Type::DialogExSelected) { switch(event->payload.dialog_ex_result) { diff --git a/applications/irda/scene/irda-app-scene-learn.cpp b/applications/irda/scene/irda-app-scene-learn.cpp index 7fdd8bf7d0b..cbbbbe7a490 100644 --- a/applications/irda/scene/irda-app-scene-learn.cpp +++ b/applications/irda/scene/irda-app-scene-learn.cpp @@ -1,5 +1,5 @@ -#include "../irda-app.hpp" -#include "../irda-app-event.hpp" +#include "../irda-app.h" +#include "../irda-app-event.h" #include static void signal_received_callback(void* context, IrdaWorkerSignal* received_signal) { @@ -9,7 +9,7 @@ static void signal_received_callback(void* context, IrdaWorkerSignal* received_s IrdaApp* app = static_cast(context); if(irda_worker_signal_is_decoded(received_signal)) { - IrdaAppSignal signal(irda_worker_get_decoded_message(received_signal)); + IrdaAppSignal signal(irda_worker_get_decoded_signal(received_signal)); app->set_received_signal(signal); } else { const uint32_t* timings; @@ -19,7 +19,7 @@ static void signal_received_callback(void* context, IrdaWorkerSignal* received_s app->set_received_signal(signal); } - irda_worker_set_received_signal_callback(app->get_irda_worker(), NULL); + irda_worker_rx_set_received_signal_callback(app->get_irda_worker(), NULL, NULL); IrdaAppEvent event; event.type = IrdaAppEvent::Type::IrdaMessageReceived; auto view_manager = app->get_view_manager(); @@ -31,9 +31,8 @@ void IrdaAppSceneLearn::on_enter(IrdaApp* app) { auto popup = view_manager->get_popup(); auto worker = app->get_irda_worker(); - irda_worker_set_context(worker, app); - irda_worker_set_received_signal_callback(worker, signal_received_callback); - irda_worker_start(worker); + irda_worker_rx_set_received_signal_callback(worker, signal_received_callback, app); + irda_worker_rx_start(worker); popup_set_icon(popup, 0, 32, &I_IrdaLearnShort_128x31); popup_set_text( @@ -58,11 +57,9 @@ bool IrdaAppSceneLearn::on_event(IrdaApp* app, IrdaAppEvent* event) { case IrdaAppEvent::Type::IrdaMessageReceived: app->notify_success(); app->switch_to_next_scene_without_saving(IrdaApp::Scene::LearnSuccess); - irda_worker_stop(app->get_irda_worker()); break; case IrdaAppEvent::Type::Back: consumed = true; - irda_worker_stop(app->get_irda_worker()); app->switch_to_previous_scene(); break; default: @@ -73,4 +70,5 @@ bool IrdaAppSceneLearn::on_event(IrdaApp* app, IrdaAppEvent* event) { } void IrdaAppSceneLearn::on_exit(IrdaApp* app) { + irda_worker_rx_stop(app->get_irda_worker()); } diff --git a/applications/irda/scene/irda-app-scene-remote-list.cpp b/applications/irda/scene/irda-app-scene-remote-list.cpp index d2b56e489b8..b6e8aab1b95 100644 --- a/applications/irda/scene/irda-app-scene-remote-list.cpp +++ b/applications/irda/scene/irda-app-scene-remote-list.cpp @@ -1,5 +1,5 @@ -#include "../irda-app.hpp" -#include "irda/irda-app-event.hpp" +#include "../irda-app.h" +#include "irda/irda-app-event.h" void IrdaAppSceneRemoteList::on_enter(IrdaApp* app) { IrdaAppFileParser file_parser; diff --git a/applications/irda/scene/irda-app-scene-remote.cpp b/applications/irda/scene/irda-app-scene-remote.cpp index 9260babecbd..94cf61ec42e 100644 --- a/applications/irda/scene/irda-app-scene-remote.cpp +++ b/applications/irda/scene/irda-app-scene-remote.cpp @@ -1,5 +1,7 @@ -#include "../irda-app.hpp" +#include "../irda-app.h" #include "gui/modules/button_menu.h" +#include "input/input.h" +#include "irda_worker.h" typedef enum { ButtonIndexPlus = -2, @@ -7,22 +9,41 @@ typedef enum { ButtonIndexNA = 0, } ButtonIndex; -static void button_menu_callback(void* context, int32_t index) { +static void button_menu_callback(void* context, int32_t index, InputType type) { IrdaApp* app = static_cast(context); IrdaAppEvent event; - event.type = IrdaAppEvent::Type::MenuSelected; + if(type == InputTypePress) { + event.type = IrdaAppEvent::Type::MenuSelectedPress; + } else if(type == InputTypeRelease) { + event.type = IrdaAppEvent::Type::MenuSelectedRelease; + } else if(type == InputTypeShort) { + event.type = IrdaAppEvent::Type::MenuSelected; + } else { + furi_assert(0); + } + event.payload.menu_index = index; app->get_view_manager()->send_event(&event); } +static void irda_app_message_sent_callback(void* context) { + IrdaApp* app = static_cast(context); + app->notify_blink_green(); +} + void IrdaAppSceneRemote::on_enter(IrdaApp* app) { IrdaAppViewManager* view_manager = app->get_view_manager(); ButtonMenu* button_menu = view_manager->get_button_menu(); auto remote_manager = app->get_remote_manager(); int i = 0; + button_pressed = false; + irda_worker_tx_set_get_signal_callback( + app->get_irda_worker(), irda_worker_tx_get_signal_steady_callback, app); + irda_worker_tx_set_signal_sent_callback( + app->get_irda_worker(), irda_app_message_sent_callback, app); buttons_names = remote_manager->get_button_list(); i = 0; @@ -48,24 +69,49 @@ void IrdaAppSceneRemote::on_enter(IrdaApp* app) { bool IrdaAppSceneRemote::on_event(IrdaApp* app, IrdaAppEvent* event) { bool consumed = true; - if(event->type == IrdaAppEvent::Type::MenuSelected) { + if((event->type == IrdaAppEvent::Type::MenuSelected) || + (event->type == IrdaAppEvent::Type::MenuSelectedPress) || + (event->type == IrdaAppEvent::Type::MenuSelectedRelease)) { switch(event->payload.menu_index) { case ButtonIndexPlus: + furi_assert(event->type == IrdaAppEvent::Type::MenuSelected); app->notify_click(); buttonmenu_item_selected = event->payload.menu_index; app->set_learn_new_remote(false); app->switch_to_next_scene(IrdaApp::Scene::Learn); break; case ButtonIndexEdit: + furi_assert(event->type == IrdaAppEvent::Type::MenuSelected); app->notify_click(); buttonmenu_item_selected = event->payload.menu_index; app->switch_to_next_scene(IrdaApp::Scene::Edit); break; default: - app->notify_click_and_blink(); - auto remote_manager = app->get_remote_manager(); - auto signal = remote_manager->get_button_data(event->payload.menu_index); - signal.transmit(); + furi_assert(event->type != IrdaAppEvent::Type::MenuSelected); + bool pressed = (event->type == IrdaAppEvent::Type::MenuSelectedPress); + + if(pressed && !button_pressed) { + button_pressed = true; + app->notify_click_and_green_blink(); + + auto button_signal = + app->get_remote_manager()->get_button_data(event->payload.menu_index); + if(button_signal.is_raw()) { + irda_worker_set_raw_signal( + app->get_irda_worker(), + button_signal.get_raw_signal().timings, + button_signal.get_raw_signal().timings_cnt); + } else { + irda_worker_set_decoded_signal( + app->get_irda_worker(), &button_signal.get_message()); + } + + irda_worker_tx_start(app->get_irda_worker()); + } else if(!pressed && button_pressed) { + button_pressed = false; + irda_worker_tx_stop(app->get_irda_worker()); + app->notify_green_off(); + } break; } } else if(event->type == IrdaAppEvent::Type::Back) { @@ -79,6 +125,8 @@ bool IrdaAppSceneRemote::on_event(IrdaApp* app, IrdaAppEvent* event) { } void IrdaAppSceneRemote::on_exit(IrdaApp* app) { + irda_worker_tx_set_get_signal_callback(app->get_irda_worker(), nullptr, nullptr); + irda_worker_tx_set_signal_sent_callback(app->get_irda_worker(), nullptr, nullptr); IrdaAppViewManager* view_manager = app->get_view_manager(); ButtonMenu* button_menu = view_manager->get_button_menu(); diff --git a/applications/irda/scene/irda-app-scene-start.cpp b/applications/irda/scene/irda-app-scene-start.cpp index 6d9e77f82d3..4b6bf13e00d 100644 --- a/applications/irda/scene/irda-app-scene-start.cpp +++ b/applications/irda/scene/irda-app-scene-start.cpp @@ -1,4 +1,4 @@ -#include "../irda-app.hpp" +#include "../irda-app.h" typedef enum { SubmenuIndexUniversalLibrary, diff --git a/applications/irda/scene/irda-app-scene-universal-common.cpp b/applications/irda/scene/irda-app-scene-universal-common.cpp index 88e7cf347ee..8e2e3747e00 100644 --- a/applications/irda/scene/irda-app-scene-universal-common.cpp +++ b/applications/irda/scene/irda-app-scene-universal-common.cpp @@ -1,12 +1,12 @@ -#include "../irda-app.hpp" +#include "../irda-app.h" #include "assets_icons.h" #include "gui/modules/button_menu.h" #include "gui/modules/button_panel.h" #include "../view/irda-app-brut-view.h" #include "gui/view.h" -#include "irda/irda-app-event.hpp" -#include "irda/irda-app-view-manager.hpp" -#include "irda/scene/irda-app-scene.hpp" +#include "irda/irda-app-event.h" +#include "irda/irda-app-view-manager.h" +#include "irda/scene/irda-app-scene.h" void IrdaAppSceneUniversalCommon::irda_app_item_callback(void* context, uint32_t index) { IrdaApp* app = static_cast(context); @@ -49,10 +49,11 @@ void IrdaAppSceneUniversalCommon::show_popup(IrdaApp* app, int record_amount) { button_panel_set_popup_input_callback(button_panel, irda_popup_brut_input_callback, app); } -void IrdaAppSceneUniversalCommon::progress_popup(IrdaApp* app) { - popup_brut_increase_progress(app->get_view_manager()->get_popup_brut()); +bool IrdaAppSceneUniversalCommon::progress_popup(IrdaApp* app) { + bool result = popup_brut_increase_progress(app->get_view_manager()->get_popup_brut()); auto button_panel = app->get_view_manager()->get_button_panel(); with_view_model_cpp(button_panel_get_view(button_panel), void*, model, { return true; }); + return result; } bool IrdaAppSceneUniversalCommon::on_event(IrdaApp* app, IrdaAppEvent* event) { @@ -63,9 +64,11 @@ bool IrdaAppSceneUniversalCommon::on_event(IrdaApp* app, IrdaAppEvent* event) { auto view_manager = app->get_view_manager(); IrdaAppEvent tick_event = {.type = IrdaAppEvent::Type::Tick}; view_manager->send_event(&tick_event); - if(brute_force.send_next_bruteforce()) { - progress_popup(app); - } else { + bool result = brute_force.send_next_bruteforce(); + if(result) { + result = progress_popup(app); + } + if(!result) { brute_force.stop_bruteforce(); brute_force_started = false; remove_popup(app); diff --git a/applications/irda/scene/irda-app-scene-universal-tv.cpp b/applications/irda/scene/irda-app-scene-universal-tv.cpp index 6723990eaf0..92a9ce3766e 100644 --- a/applications/irda/scene/irda-app-scene-universal-tv.cpp +++ b/applications/irda/scene/irda-app-scene-universal-tv.cpp @@ -1,5 +1,5 @@ -#include "irda/scene/irda-app-scene.hpp" -#include "irda/irda-app.hpp" +#include "irda/scene/irda-app-scene.h" +#include "irda/irda-app.h" void IrdaAppSceneUniversalTV::on_enter(IrdaApp* app) { IrdaAppViewManager* view_manager = app->get_view_manager(); diff --git a/applications/irda/scene/irda-app-scene-universal.cpp b/applications/irda/scene/irda-app-scene-universal.cpp index b29adbe71e7..61a61fd26ed 100644 --- a/applications/irda/scene/irda-app-scene-universal.cpp +++ b/applications/irda/scene/irda-app-scene-universal.cpp @@ -1,4 +1,4 @@ -#include "../irda-app.hpp" +#include "../irda-app.h" typedef enum { SubmenuIndexUniversalTV, diff --git a/applications/irda/scene/irda-app-scene.hpp b/applications/irda/scene/irda-app-scene.h similarity index 89% rename from applications/irda/scene/irda-app-scene.hpp rename to applications/irda/scene/irda-app-scene.h index 3b1109018e4..11eb1b38043 100644 --- a/applications/irda/scene/irda-app-scene.hpp +++ b/applications/irda/scene/irda-app-scene.h @@ -1,11 +1,10 @@ #pragma once -#include "../irda-app-event.hpp" -#include +#include "../irda-app-event.h" +#include #include "irda.h" #include #include -#include "../irda-app-brute-force.hpp" - +#include "../irda-app-brute-force.h" class IrdaApp; @@ -24,6 +23,7 @@ class IrdaAppSceneStart : public IrdaAppScene { void on_enter(IrdaApp* app) final; bool on_event(IrdaApp* app, IrdaAppEvent* event) final; void on_exit(IrdaApp* app) final; + private: uint32_t submenu_item_selected = 0; }; @@ -33,6 +33,7 @@ class IrdaAppSceneUniversal : public IrdaAppScene { void on_enter(IrdaApp* app) final; bool on_event(IrdaApp* app, IrdaAppEvent* event) final; void on_exit(IrdaApp* app) final; + private: uint32_t submenu_item_selected = 0; }; @@ -70,9 +71,11 @@ class IrdaAppSceneRemote : public IrdaAppScene { void on_enter(IrdaApp* app) final; bool on_event(IrdaApp* app, IrdaAppEvent* event) final; void on_exit(IrdaApp* app) final; + private: std::vector buttons_names; uint32_t buttonmenu_item_selected = 0; + bool button_pressed = false; }; class IrdaAppSceneRemoteList : public IrdaAppScene { @@ -80,6 +83,7 @@ class IrdaAppSceneRemoteList : public IrdaAppScene { void on_enter(IrdaApp* app) final; bool on_event(IrdaApp* app, IrdaAppEvent* event) final; void on_exit(IrdaApp* app) final; + private: uint32_t submenu_item_selected = 0; std::vector remote_names; @@ -90,6 +94,7 @@ class IrdaAppSceneEdit : public IrdaAppScene { void on_enter(IrdaApp* app) final; bool on_event(IrdaApp* app, IrdaAppEvent* event) final; void on_exit(IrdaApp* app) final; + private: uint32_t submenu_item_selected = 0; }; @@ -99,6 +104,7 @@ class IrdaAppSceneEditKeySelect : public IrdaAppScene { void on_enter(IrdaApp* app) final; bool on_event(IrdaApp* app, IrdaAppEvent* event) final; void on_exit(IrdaApp* app) final; + private: std::vector buttons_names; }; @@ -133,16 +139,20 @@ class IrdaAppSceneEditDeleteDone : public IrdaAppScene { class IrdaAppSceneUniversalCommon : public IrdaAppScene { bool brute_force_started = false; + protected: bool on_event(IrdaApp* app, IrdaAppEvent* event) final; void on_exit(IrdaApp* app) final; IrdaAppBruteForce brute_force; void remove_popup(IrdaApp* app); void show_popup(IrdaApp* app, int record_amount); - void progress_popup(IrdaApp* app); + bool progress_popup(IrdaApp* app); static void irda_app_item_callback(void* context, uint32_t index); - IrdaAppSceneUniversalCommon(const char* filename) : brute_force(filename) {} - ~IrdaAppSceneUniversalCommon() {} + IrdaAppSceneUniversalCommon(const char* filename) + : brute_force(filename) { + } + ~IrdaAppSceneUniversalCommon() { + } }; class IrdaAppSceneUniversalTV : public IrdaAppSceneUniversalCommon { @@ -151,13 +161,16 @@ class IrdaAppSceneUniversalTV : public IrdaAppSceneUniversalCommon { IrdaAppSceneUniversalTV() : IrdaAppSceneUniversalCommon("/ext/irda/universal/tv.ir") { } - ~IrdaAppSceneUniversalTV() {} + ~IrdaAppSceneUniversalTV() { + } }; class IrdaAppSceneUniversalAudio : public IrdaAppSceneUniversalCommon { public: void on_enter(IrdaApp* app) final; - IrdaAppSceneUniversalAudio() : IrdaAppSceneUniversalCommon("/ext/irda/universal/audio.ir") {} - ~IrdaAppSceneUniversalAudio() {} + IrdaAppSceneUniversalAudio() + : IrdaAppSceneUniversalCommon("/ext/irda/universal/audio.ir") { + } + ~IrdaAppSceneUniversalAudio() { + } }; - diff --git a/applications/irda/view/irda-app-brut-view.c b/applications/irda/view/irda-app-brut-view.c index 8d53f90e397..7f502464274 100644 --- a/applications/irda/view/irda-app-brut-view.c +++ b/applications/irda/view/irda-app-brut-view.c @@ -1,4 +1,4 @@ -#include "api-hal-resources.h" +#include "furi-hal-resources.h" #include "assets_icons.h" #include "gui/canvas.h" #include "gui/view.h" @@ -15,13 +15,15 @@ struct IrdaAppPopupBrut { char percents_string_storage[8]; }; -void popup_brut_increase_progress(IrdaAppPopupBrut* popup_brut) { +bool popup_brut_increase_progress(IrdaAppPopupBrut* popup_brut) { furi_assert(popup_brut); if(popup_brut->progress < popup_brut->progress_max) ++popup_brut->progress; else furi_assert(0); + + return popup_brut->progress < popup_brut->progress_max; } void popup_brut_draw_callback(Canvas* canvas, void* context) { diff --git a/applications/irda/view/irda-app-brut-view.h b/applications/irda/view/irda-app-brut-view.h index e9f0ec62800..3f6b973ae84 100644 --- a/applications/irda/view/irda-app-brut-view.h +++ b/applications/irda/view/irda-app-brut-view.h @@ -7,7 +7,7 @@ extern "C" { typedef struct IrdaAppPopupBrut IrdaAppPopupBrut; -void popup_brut_increase_progress(IrdaAppPopupBrut* popup_brut); +bool popup_brut_increase_progress(IrdaAppPopupBrut* popup_brut); IrdaAppPopupBrut* popup_brut_alloc(); void popup_brut_free(IrdaAppPopupBrut* popup_brut); void popup_brut_draw_callback(Canvas* canvas, void* model); diff --git a/applications/irda_monitor/irda_monitor.c b/applications/irda_monitor/irda_monitor.c index 56a81a3f72f..3a0a342af24 100644 --- a/applications/irda_monitor/irda_monitor.c +++ b/applications/irda_monitor/irda_monitor.c @@ -4,8 +4,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -58,7 +58,7 @@ static void signal_received_callback(void* context, IrdaWorkerSignal* received_s IrdaMonitor* irda_monitor = context; if(irda_worker_signal_is_decoded(received_signal)) { - const IrdaMessage* message = irda_worker_get_decoded_message(received_signal); + const IrdaMessage* message = irda_worker_get_decoded_signal(received_signal); snprintf( irda_monitor->display_text, sizeof(irda_monitor->display_text), @@ -112,10 +112,10 @@ int32_t irda_monitor_app(void* p) { gui_add_view_port(gui, irda_monitor->view_port, GuiLayerFullscreen); irda_monitor->worker = irda_worker_alloc(); - irda_worker_set_context(irda_monitor->worker, irda_monitor); - irda_worker_start(irda_monitor->worker); - irda_worker_set_received_signal_callback(irda_monitor->worker, signal_received_callback); - irda_worker_enable_blink_on_receiving(irda_monitor->worker, true); + irda_worker_rx_start(irda_monitor->worker); + irda_worker_rx_set_received_signal_callback( + irda_monitor->worker, signal_received_callback, irda_monitor); + irda_worker_rx_enable_blink_on_receiving(irda_monitor->worker, true); while(1) { InputEvent event; @@ -126,7 +126,7 @@ int32_t irda_monitor_app(void* p) { } } - irda_worker_stop(irda_monitor->worker); + irda_worker_rx_stop(irda_monitor->worker); irda_worker_free(irda_monitor->worker); osMessageQueueDelete(irda_monitor->event_queue); view_port_enabled_set(irda_monitor->view_port, false); diff --git a/applications/lfrfid-debug/lfrfid-debug-app.h b/applications/lfrfid-debug/lfrfid-debug-app.h index fab9fa9aab7..e949471998b 100644 --- a/applications/lfrfid-debug/lfrfid-debug-app.h +++ b/applications/lfrfid-debug/lfrfid-debug-app.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include #include diff --git a/applications/lfrfid-debug/scene/lfrfid-debug-app-scene-tune.cpp b/applications/lfrfid-debug/scene/lfrfid-debug-app-scene-tune.cpp index 1d5c885dec3..fea0e586b7a 100644 --- a/applications/lfrfid-debug/scene/lfrfid-debug-app-scene-tune.cpp +++ b/applications/lfrfid-debug/scene/lfrfid-debug-app-scene-tune.cpp @@ -3,9 +3,9 @@ void LfRfidDebugAppSceneTune::on_enter(LfRfidDebugApp* app, bool need_restore) { app->view_controller.switch_to(); - api_hal_rfid_pins_read(); - api_hal_rfid_tim_read(125000, 0.5); - api_hal_rfid_tim_read_start(); + furi_hal_rfid_pins_read(); + furi_hal_rfid_tim_read(125000, 0.5); + furi_hal_rfid_tim_read_start(); } bool LfRfidDebugAppSceneTune::on_event(LfRfidDebugApp* app, LfRfidDebugApp::Event* event) { @@ -14,15 +14,15 @@ bool LfRfidDebugAppSceneTune::on_event(LfRfidDebugApp* app, LfRfidDebugApp::Even LfRfidViewTuneVM* tune = app->view_controller; if(tune->is_dirty()) { - api_hal_rfid_set_read_period(tune->get_ARR()); - api_hal_rfid_set_read_pulse(tune->get_CCR()); + furi_hal_rfid_set_read_period(tune->get_ARR()); + furi_hal_rfid_set_read_pulse(tune->get_CCR()); } return consumed; } void LfRfidDebugAppSceneTune::on_exit(LfRfidDebugApp* app) { - api_hal_rfid_tim_read_stop(); - api_hal_rfid_tim_reset(); - api_hal_rfid_pins_reset(); + furi_hal_rfid_tim_read_stop(); + furi_hal_rfid_tim_reset(); + furi_hal_rfid_pins_reset(); } \ No newline at end of file diff --git a/applications/lfrfid/helpers/decoder-analyzer.cpp b/applications/lfrfid/helpers/decoder-analyzer.cpp index d3ee90bac60..501f3f8d986 100644 --- a/applications/lfrfid/helpers/decoder-analyzer.cpp +++ b/applications/lfrfid/helpers/decoder-analyzer.cpp @@ -1,6 +1,6 @@ #include "decoder-analyzer.h" #include -#include +#include bool DecoderAnalyzer::read(uint8_t* _data, uint8_t _data_size) { bool result = false; diff --git a/applications/lfrfid/helpers/decoder-emmarine.cpp b/applications/lfrfid/helpers/decoder-emmarin.cpp similarity index 83% rename from applications/lfrfid/helpers/decoder-emmarine.cpp rename to applications/lfrfid/helpers/decoder-emmarin.cpp index 74648980410..3954e22ec7b 100644 --- a/applications/lfrfid/helpers/decoder-emmarine.cpp +++ b/applications/lfrfid/helpers/decoder-emmarin.cpp @@ -1,7 +1,7 @@ -#include "emmarine.h" -#include "decoder-emmarine.h" +#include "emmarin.h" +#include "decoder-emmarin.h" #include -#include +#include constexpr uint32_t clocks_in_us = 64; constexpr uint32_t short_time = 255 * clocks_in_us; @@ -13,19 +13,19 @@ constexpr uint32_t short_time_high = short_time + jitter_time; constexpr uint32_t long_time_low = long_time - jitter_time; constexpr uint32_t long_time_high = long_time + jitter_time; -void DecoderEMMarine::reset_state() { +void DecoderEMMarin::reset_state() { ready = false; readed_data = 0; manchester_advance( manchester_saved_state, ManchesterEventReset, &manchester_saved_state, nullptr); } -bool DecoderEMMarine::read(uint8_t* data, uint8_t data_size) { +bool DecoderEMMarin::read(uint8_t* data, uint8_t data_size) { bool result = false; if(ready) { result = true; - em_marine.decode( + em_marin.decode( reinterpret_cast(&readed_data), sizeof(uint64_t), data, data_size); ready = false; } @@ -33,7 +33,7 @@ bool DecoderEMMarine::read(uint8_t* data, uint8_t data_size) { return result; } -void DecoderEMMarine::process_front(bool polarity, uint32_t time) { +void DecoderEMMarin::process_front(bool polarity, uint32_t time) { if(ready) return; if(time < short_time_low) return; @@ -61,12 +61,12 @@ void DecoderEMMarine::process_front(bool polarity, uint32_t time) { if(data_ok) { readed_data = (readed_data << 1) | data; - ready = em_marine.can_be_decoded( + ready = em_marin.can_be_decoded( reinterpret_cast(&readed_data), sizeof(uint64_t)); } } } -DecoderEMMarine::DecoderEMMarine() { +DecoderEMMarin::DecoderEMMarin() { reset_state(); } diff --git a/applications/lfrfid/helpers/decoder-emmarine.h b/applications/lfrfid/helpers/decoder-emmarin.h similarity index 82% rename from applications/lfrfid/helpers/decoder-emmarine.h rename to applications/lfrfid/helpers/decoder-emmarin.h index 014e3f3e8e0..dd81a944129 100644 --- a/applications/lfrfid/helpers/decoder-emmarine.h +++ b/applications/lfrfid/helpers/decoder-emmarin.h @@ -3,12 +3,12 @@ #include #include "manchester-decoder.h" #include "protocols/protocol-emmarin.h" -class DecoderEMMarine { +class DecoderEMMarin { public: bool read(uint8_t* data, uint8_t data_size); void process_front(bool polarity, uint32_t time); - DecoderEMMarine(); + DecoderEMMarin(); private: void reset_state(); @@ -17,5 +17,5 @@ class DecoderEMMarine { std::atomic ready; ManchesterState manchester_saved_state; - ProtocolEMMarin em_marine; + ProtocolEMMarin em_marin; }; diff --git a/applications/lfrfid/helpers/decoder-gpio-out.cpp b/applications/lfrfid/helpers/decoder-gpio-out.cpp index 50cec34dc96..fc6815fc8e0 100644 --- a/applications/lfrfid/helpers/decoder-gpio-out.cpp +++ b/applications/lfrfid/helpers/decoder-gpio-out.cpp @@ -1,6 +1,6 @@ #include "decoder-gpio-out.h" #include -#include +#include void DecoderGpioOut::process_front(bool polarity, uint32_t time) { hal_gpio_write(&gpio_ext_pa7, polarity); diff --git a/applications/lfrfid/helpers/decoder-hid26.cpp b/applications/lfrfid/helpers/decoder-hid26.cpp index 94f5249306a..d6245e29bef 100644 --- a/applications/lfrfid/helpers/decoder-hid26.cpp +++ b/applications/lfrfid/helpers/decoder-hid26.cpp @@ -1,5 +1,5 @@ #include "decoder-hid26.h" -#include +#include constexpr uint32_t clocks_in_us = 64; diff --git a/applications/lfrfid/helpers/decoder-indala.cpp b/applications/lfrfid/helpers/decoder-indala.cpp index 2103a1809b5..01bff329bb2 100644 --- a/applications/lfrfid/helpers/decoder-indala.cpp +++ b/applications/lfrfid/helpers/decoder-indala.cpp @@ -1,5 +1,5 @@ #include "decoder-indala.h" -#include +#include constexpr uint32_t clocks_in_us = 64; constexpr uint32_t us_per_bit = 255; diff --git a/applications/lfrfid/helpers/emmarine.h b/applications/lfrfid/helpers/emmarin.h similarity index 100% rename from applications/lfrfid/helpers/emmarine.h rename to applications/lfrfid/helpers/emmarin.h diff --git a/applications/lfrfid/helpers/encoder-emmarine.cpp b/applications/lfrfid/helpers/encoder-emmarin.cpp similarity index 95% rename from applications/lfrfid/helpers/encoder-emmarine.cpp rename to applications/lfrfid/helpers/encoder-emmarin.cpp index 44eea5bbe56..f61c9e405d1 100644 --- a/applications/lfrfid/helpers/encoder-emmarine.cpp +++ b/applications/lfrfid/helpers/encoder-emmarin.cpp @@ -1,4 +1,4 @@ -#include "encoder-emmarine.h" +#include "encoder-emmarin.h" #include "protocols/protocol-emmarin.h" #include diff --git a/applications/lfrfid/helpers/encoder-emmarine.h b/applications/lfrfid/helpers/encoder-emmarin.h similarity index 100% rename from applications/lfrfid/helpers/encoder-emmarine.h rename to applications/lfrfid/helpers/encoder-emmarin.h diff --git a/applications/lfrfid/helpers/key-info.cpp b/applications/lfrfid/helpers/key-info.cpp index cd04e1e1583..fe0e31afd1f 100644 --- a/applications/lfrfid/helpers/key-info.cpp +++ b/applications/lfrfid/helpers/key-info.cpp @@ -20,7 +20,7 @@ const char* lfrfid_key_get_type_string(LfrfidKeyType type) { const char* lfrfid_key_get_manufacturer_string(LfrfidKeyType type) { switch(type) { case LfrfidKeyType::KeyEM4100: - return "Em-Marine"; + return "EM-Marin"; break; case LfrfidKeyType::KeyH10301: return "HID"; diff --git a/applications/lfrfid/helpers/rfid-reader.cpp b/applications/lfrfid/helpers/rfid-reader.cpp index dae887d05a7..1af1999e373 100644 --- a/applications/lfrfid/helpers/rfid-reader.cpp +++ b/applications/lfrfid/helpers/rfid-reader.cpp @@ -1,6 +1,6 @@ #include "rfid-reader.h" #include -#include +#include #include #include @@ -20,7 +20,10 @@ void RfidReader::decode(bool polarity) { uint32_t period = current_dwt_value - last_dwt_value; last_dwt_value = current_dwt_value; - //decoder_gpio_out.process_front(polarity, period); +#ifdef RFID_GPIO_DEBUG + decoder_gpio_out.process_front(polarity, period); +#endif + switch(type) { case Type::Normal: decoder_em.process_front(polarity, period); @@ -49,11 +52,11 @@ void RfidReader::switch_mode() { switch(type) { case Type::Normal: type = Type::Indala; - api_hal_rfid_change_read_config(62500.0f, 0.25f); + furi_hal_rfid_change_read_config(62500.0f, 0.25f); break; case Type::Indala: type = Type::Normal; - api_hal_rfid_change_read_config(125000.0f, 0.5f); + furi_hal_rfid_change_read_config(125000.0f, 0.5f); break; } @@ -76,9 +79,9 @@ RfidReader::RfidReader() { void RfidReader::start() { type = Type::Normal; - api_hal_rfid_pins_read(); - api_hal_rfid_tim_read(125000, 0.5); - api_hal_rfid_tim_read_start(); + furi_hal_rfid_pins_read(); + furi_hal_rfid_tim_read(125000, 0.5); + furi_hal_rfid_tim_read_start(); start_comparator(); switch_timer_reset(); @@ -86,27 +89,16 @@ void RfidReader::start() { } void RfidReader::start_forced(RfidReader::Type _type) { - type = _type; - switch(type) { - case Type::Normal: - start(); - break; - case Type::Indala: - api_hal_rfid_pins_read(); - api_hal_rfid_tim_read(62500.0f, 0.25f); - api_hal_rfid_tim_read_start(); - start_comparator(); - - switch_timer_reset(); - last_readed_count = 0; - break; + start(); + if(_type == Type::Indala) { + switch_mode(); } } void RfidReader::stop() { - api_hal_rfid_pins_reset(); - api_hal_rfid_tim_read_stop(); - api_hal_rfid_tim_reset(); + furi_hal_rfid_pins_reset(); + furi_hal_rfid_tim_read_stop(); + furi_hal_rfid_tim_reset(); stop_comparator(); } diff --git a/applications/lfrfid/helpers/rfid-reader.h b/applications/lfrfid/helpers/rfid-reader.h index 3e6acacd89e..e62c4196b1f 100644 --- a/applications/lfrfid/helpers/rfid-reader.h +++ b/applications/lfrfid/helpers/rfid-reader.h @@ -1,11 +1,13 @@ #pragma once //#include "decoder-analyzer.h" #include "decoder-gpio-out.h" -#include "decoder-emmarine.h" +#include "decoder-emmarin.h" #include "decoder-hid26.h" #include "decoder-indala.h" #include "key-info.h" +//#define RFID_GPIO_DEBUG 1 + class RfidReader { public: enum class Type : uint8_t { @@ -26,8 +28,10 @@ class RfidReader { friend struct RfidReaderAccessor; //DecoderAnalyzer decoder_analyzer; - //DecoderGpioOut decoder_gpio_out; - DecoderEMMarine decoder_em; +#ifdef RFID_GPIO_DEBUG + DecoderGpioOut decoder_gpio_out; +#endif + DecoderEMMarin decoder_em; DecoderHID26 decoder_hid26; DecoderIndala decoder_indala; diff --git a/applications/lfrfid/helpers/rfid-timer-emulator.cpp b/applications/lfrfid/helpers/rfid-timer-emulator.cpp index b874767269d..05afb146559 100644 --- a/applications/lfrfid/helpers/rfid-timer-emulator.cpp +++ b/applications/lfrfid/helpers/rfid-timer-emulator.cpp @@ -21,12 +21,12 @@ void RfidTimerEmulator::start(LfrfidKeyType type, const uint8_t* data, uint8_t d if(data_size >= lfrfid_key_get_type_data_count(type)) { current_encoder->init(data, data_size); - api_hal_rfid_tim_emulate(125000); - api_hal_rfid_pins_emulate(); + furi_hal_rfid_tim_emulate(125000); + furi_hal_rfid_pins_emulate(); api_interrupt_add(timer_update_callback, InterruptTypeTimerUpdate, this); - api_hal_rfid_tim_emulate_start(); + furi_hal_rfid_tim_emulate_start(); } } else { // not found @@ -34,18 +34,18 @@ void RfidTimerEmulator::start(LfrfidKeyType type, const uint8_t* data, uint8_t d } void RfidTimerEmulator::stop() { - api_hal_rfid_tim_emulate_stop(); + furi_hal_rfid_tim_emulate_stop(); api_interrupt_remove(timer_update_callback, InterruptTypeTimerUpdate); - api_hal_rfid_tim_reset(); - api_hal_rfid_pins_reset(); + furi_hal_rfid_tim_reset(); + furi_hal_rfid_pins_reset(); } void RfidTimerEmulator::timer_update_callback(void* _hw, void* ctx) { RfidTimerEmulator* _this = static_cast(ctx); TIM_HandleTypeDef* hw = static_cast(_hw); - if(api_hal_rfid_is_tim_emulate(hw)) { + if(furi_hal_rfid_is_tim_emulate(hw)) { bool result; bool polarity; uint16_t period; @@ -58,7 +58,7 @@ void RfidTimerEmulator::timer_update_callback(void* _hw, void* ctx) { _this->pulse_joiner.pop_pulse(&period, &pulse); - api_hal_rfid_set_emulate_period(period - 1); - api_hal_rfid_set_emulate_pulse(pulse); + furi_hal_rfid_set_emulate_period(period - 1); + furi_hal_rfid_set_emulate_pulse(pulse); } } diff --git a/applications/lfrfid/helpers/rfid-timer-emulator.h b/applications/lfrfid/helpers/rfid-timer-emulator.h index 2a4365b596e..b05f5434205 100644 --- a/applications/lfrfid/helpers/rfid-timer-emulator.h +++ b/applications/lfrfid/helpers/rfid-timer-emulator.h @@ -1,8 +1,8 @@ #pragma once -#include +#include #include "key-info.h" #include "encoder-generic.h" -#include "encoder-emmarine.h" +#include "encoder-emmarin.h" #include "encoder-hid-h10301.h" #include "encoder-indala-40134.h" #include "pulse-joiner.h" diff --git a/applications/lfrfid/helpers/rfid-writer.cpp b/applications/lfrfid/helpers/rfid-writer.cpp index 9df81d53248..f983ce35898 100644 --- a/applications/lfrfid/helpers/rfid-writer.cpp +++ b/applications/lfrfid/helpers/rfid-writer.cpp @@ -1,5 +1,5 @@ #include "rfid-writer.h" -#include +#include #include "protocols/protocol-emmarin.h" #include "protocols/protocol-hid-h10301.h" #include "protocols/protocol-indala-40134.h" @@ -34,21 +34,22 @@ RfidWriter::~RfidWriter() { } void RfidWriter::start() { - api_hal_rfid_tim_read(125000, 0.5); - api_hal_rfid_pins_read(); - api_hal_rfid_tim_read_start(); + furi_hal_rfid_tim_read(125000, 0.5); + furi_hal_rfid_pins_read(); + furi_hal_rfid_tim_read_start(); + hal_gpio_write(&gpio_rfid_pull, true); } void RfidWriter::stop() { - api_hal_rfid_tim_read_stop(); - api_hal_rfid_tim_reset(); - api_hal_rfid_pins_reset(); + furi_hal_rfid_tim_read_stop(); + furi_hal_rfid_tim_reset(); + furi_hal_rfid_pins_reset(); } void RfidWriter::write_gap(uint32_t gap_time) { - api_hal_rfid_tim_read_stop(); + furi_hal_rfid_tim_read_stop(); delay_us(gap_time * 8); - api_hal_rfid_tim_read_start(); + furi_hal_rfid_tim_read_start(); } void RfidWriter::write_bit(bool value) { diff --git a/applications/lfrfid/lfrfid-app.cpp b/applications/lfrfid/lfrfid-app.cpp index 1cd59b619df..41cba8d7ae7 100644 --- a/applications/lfrfid/lfrfid-app.cpp +++ b/applications/lfrfid/lfrfid-app.cpp @@ -26,11 +26,11 @@ LfRfidApp::LfRfidApp() : scene_controller{this} , notification{"notification"} , text_store(40) { - api_hal_power_insomnia_enter(); + furi_hal_power_insomnia_enter(); } LfRfidApp::~LfRfidApp() { - api_hal_power_insomnia_exit(); + furi_hal_power_insomnia_exit(); } void LfRfidApp::run(void* _args) { diff --git a/applications/lfrfid/lfrfid-app.h b/applications/lfrfid/lfrfid-app.h index cc126410d7e..b60d6994259 100644 --- a/applications/lfrfid/lfrfid-app.h +++ b/applications/lfrfid/lfrfid-app.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include #include diff --git a/applications/lfrfid/lfrfid-cli.cpp b/applications/lfrfid/lfrfid-cli.cpp index d0ae56da1f6..a039ccc8068 100644 --- a/applications/lfrfid/lfrfid-cli.cpp +++ b/applications/lfrfid/lfrfid-cli.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include diff --git a/applications/loader/loader.c b/applications/loader/loader.c index 856492643ff..50630ac6a8b 100644 --- a/applications/loader/loader.c +++ b/applications/loader/loader.c @@ -15,7 +15,7 @@ static void loader_menu_callback(void* _ctx) { LOADER_LOG_TAG, "Can't start app. %s is running", loader_instance->current_app->name); return; } - api_hal_power_insomnia_enter(); + furi_hal_power_insomnia_enter(); loader_instance->current_app = flipper_app; FURI_LOG_I( @@ -39,7 +39,7 @@ static void loader_cli_callback(Cli* cli, string_t args, void* _ctx) { } loader_instance->lock_semaphore++; - api_hal_power_insomnia_enter(); + furi_hal_power_insomnia_enter(); loader_instance->current_app = flipper_app; printf("Starting furi application %s", loader_instance->current_app->name); furi_thread_set_name(loader_instance->thread, flipper_app->name); @@ -133,7 +133,7 @@ static void loader_thread_state_callback(FuriThreadState thread_state, void* con "Application thread stopped. Heap allocation balance: %d. Thread allocation balance: %d.", heap_diff, furi_thread_get_heap_size(instance->thread)); - api_hal_power_insomnia_exit(); + furi_hal_power_insomnia_exit(); loader_unlock(instance); } } @@ -291,7 +291,7 @@ static void loader_build_menu() { }); } -int32_t loader(void* p) { +int32_t loader_srv(void* p) { FURI_LOG_I(LOADER_LOG_TAG, "Starting"); loader_instance = loader_alloc(); diff --git a/applications/loader/loader_i.h b/applications/loader/loader_i.h index 9a02794e6f4..f5340434ced 100644 --- a/applications/loader/loader_i.h +++ b/applications/loader/loader_i.h @@ -1,7 +1,7 @@ #include "loader.h" #include -#include +#include #include #include #include diff --git a/applications/menu/menu.c b/applications/menu/menu.c index 7fc39aaa61e..ea7157d468e 100644 --- a/applications/menu/menu.c +++ b/applications/menu/menu.c @@ -292,7 +292,7 @@ void menu_exit(Menu* menu) { menu_update(menu); } -int32_t menu_task(void* p) { +int32_t menu_srv(void* p) { ValueMutex* menu_mutex = menu_init(); MenuEvent* menu_event = NULL; diff --git a/applications/music-player/music-player.c b/applications/music-player/music-player.c index 7e065b1fa8a..9fa7708d879 100644 --- a/applications/music-player/music-player.c +++ b/applications/music-player/music-player.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -358,7 +358,7 @@ void music_player_thread(void* p) { } } -int32_t music_player(void* p) { +int32_t music_player_app(void* p) { osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(MusicDemoEvent), NULL); State _state; diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c index 734dade28e7..a1f4a19ef36 100755 --- a/applications/nfc/nfc.c +++ b/applications/nfc/nfc.c @@ -1,5 +1,5 @@ #include "nfc_i.h" -#include "api-hal-nfc.h" +#include "furi-hal-nfc.h" bool nfc_custom_event_callback(void* context, uint32_t event) { furi_assert(context); @@ -136,7 +136,20 @@ void nfc_free(Nfc* nfc) { free(nfc); } -int32_t nfc_task(void* p) { +void nfc_text_store_set(Nfc* nfc, const char* text, ...) { + va_list args; + va_start(args, text); + + vsnprintf(nfc->text_store, sizeof(nfc->text_store), text, args); + + va_end(args); +} + +void nfc_text_store_clear(Nfc* nfc) { + memset(nfc->text_store, 0, sizeof(nfc->text_store)); +} + +int32_t nfc_app(void* p) { Nfc* nfc = nfc_alloc(); // Check argument and run corresponding scene @@ -152,16 +165,3 @@ int32_t nfc_task(void* p) { return 0; } - -void nfc_text_store_set(Nfc* nfc, const char* text, ...) { - va_list args; - va_start(args, text); - - vsnprintf(nfc->text_store, sizeof(nfc->text_store), text, args); - - va_end(args); -} - -void nfc_text_store_clear(Nfc* nfc) { - memset(nfc->text_store, 0, sizeof(nfc->text_store)); -} diff --git a/applications/nfc/nfc_cli.c b/applications/nfc/nfc_cli.c index 6349cde4cb9..8adf5761667 100755 --- a/applications/nfc/nfc_cli.c +++ b/applications/nfc/nfc_cli.c @@ -1,7 +1,7 @@ #include "nfc_cli.h" #include "nfc_types.h" #include -#include +#include void nfc_cli_init() { Cli* cli = furi_record_open("cli"); @@ -12,18 +12,18 @@ void nfc_cli_init() { void nfc_cli_detect(Cli* cli, string_t args, void* context) { // Check if nfc worker is not busy - if(api_hal_nfc_is_busy()) { + if(furi_hal_nfc_is_busy()) { printf("Nfc is busy"); return; } rfalNfcDevice* dev_list; uint8_t dev_cnt = 0; bool cmd_exit = false; - api_hal_nfc_exit_sleep(); + furi_hal_nfc_exit_sleep(); printf("Detecting nfc...\r\nPress Ctrl+C to abort\r\n"); while(!cmd_exit) { cmd_exit |= cli_cmd_interrupt_received(cli); - cmd_exit |= api_hal_nfc_detect(&dev_list, &dev_cnt, 400, true); + cmd_exit |= furi_hal_nfc_detect(&dev_list, &dev_cnt, 400, true); if(dev_cnt > 0) { printf("Found %d devices\r\n", dev_cnt); for(uint8_t i = 0; i < dev_cnt; i++) { @@ -40,17 +40,17 @@ void nfc_cli_detect(Cli* cli, string_t args, void* context) { } osDelay(50); } - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); } void nfc_cli_emulate(Cli* cli, string_t args, void* context) { // Check if nfc worker is not busy - if(api_hal_nfc_is_busy()) { + if(furi_hal_nfc_is_busy()) { printf("Nfc is busy"); return; } - api_hal_nfc_exit_sleep(); + furi_hal_nfc_exit_sleep(); printf("Emulating NFC-A Type: T2T UID: CF72D440 SAK: 20 ATQA: 00/04\r\n"); printf("Press Ctrl+C to abort\r\n"); @@ -64,11 +64,11 @@ void nfc_cli_emulate(Cli* cli, string_t args, void* context) { }; while(!cli_cmd_interrupt_received(cli)) { - if(api_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, 100)) { + if(furi_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, 100)) { printf("Reader detected\r\n"); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); } osDelay(50); } - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); } diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c index 30aecbfd87b..334e6d7bbe0 100755 --- a/applications/nfc/nfc_worker.c +++ b/applications/nfc/nfc_worker.c @@ -1,5 +1,5 @@ #include "nfc_worker_i.h" -#include +#include #include "nfc_protocols/emv_decoder.h" #include "nfc_protocols/mifare_ultralight.h" @@ -15,7 +15,7 @@ NfcWorker* nfc_worker_alloc() { nfc_worker->callback = NULL; nfc_worker->context = NULL; // Initialize rfal - if(!api_hal_nfc_is_busy()) { + if(!furi_hal_nfc_is_busy()) { nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); } else { nfc_worker_change_state(nfc_worker, NfcWorkerStateBroken); @@ -70,8 +70,8 @@ void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state) { void nfc_worker_task(void* context) { NfcWorker* nfc_worker = context; - api_hal_power_insomnia_enter(); - api_hal_nfc_exit_sleep(); + furi_hal_power_insomnia_enter(); + furi_hal_nfc_exit_sleep(); if(nfc_worker->state == NfcWorkerStateDetect) { nfc_worker_detect(nfc_worker); @@ -90,9 +90,9 @@ void nfc_worker_task(void* context) { } else if(nfc_worker->state == NfcWorkerStateField) { nfc_worker_field(nfc_worker); } - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); - api_hal_power_insomnia_exit(); + furi_hal_power_insomnia_exit(); osThreadExit(); } @@ -103,7 +103,7 @@ void nfc_worker_detect(NfcWorker* nfc_worker) { NfcDeviceCommomData* result = &nfc_worker->dev_data->nfc_data; while(nfc_worker->state == NfcWorkerStateDetect) { - if(api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, true)) { + if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 1000, true)) { // Process first found device dev = &dev_list[0]; result->uid_len = dev->nfcidLen; @@ -143,7 +143,7 @@ void nfc_worker_detect(NfcWorker* nfc_worker) { void nfc_worker_emulate(NfcWorker* nfc_worker) { NfcDeviceCommomData* data = &nfc_worker->dev_data->nfc_data; while(nfc_worker->state == NfcWorkerStateEmulate) { - if(api_hal_nfc_listen(data->uid, data->uid_len, data->atqa, data->sak, 100)) { + if(furi_hal_nfc_listen(data->uid, data->uid_len, data->atqa, data->sak, 100)) { FURI_LOG_I(NFC_WORKER_TAG, "Reader detected"); } osDelay(10); @@ -163,7 +163,7 @@ void nfc_worker_read_emv_app(NfcWorker* nfc_worker) { while(nfc_worker->state == NfcWorkerStateReadEMVApp) { memset(&emv_app, 0, sizeof(emv_app)); - if(api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) { + if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) { // Card was found. Check that it supports EMV if(dev_list[0].rfInterface == RFAL_NFC_INTERFACE_ISODEP) { result->nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len; @@ -176,10 +176,10 @@ void nfc_worker_read_emv_app(NfcWorker* nfc_worker) { FURI_LOG_I(NFC_WORKER_TAG, "Send select PPSE command"); tx_len = emv_prepare_select_ppse(tx_buff); - err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); + err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); if(err != ERR_NONE) { FURI_LOG_E(NFC_WORKER_TAG, "Error during selection PPSE request: %d", err); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); continue; } FURI_LOG_I( @@ -195,18 +195,18 @@ void nfc_worker_read_emv_app(NfcWorker* nfc_worker) { break; } else { FURI_LOG_E(NFC_WORKER_TAG, "Can't find pay application"); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); continue; } } else { // Can't find EMV card FURI_LOG_W(NFC_WORKER_TAG, "Card doesn't support EMV"); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); } } else { // Can't find EMV card FURI_LOG_W(NFC_WORKER_TAG, "Can't find any cards"); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); } osDelay(20); } @@ -225,7 +225,7 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { while(nfc_worker->state == NfcWorkerStateReadEMV) { memset(&emv_app, 0, sizeof(emv_app)); - if(api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) { + if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) { // Card was found. Check that it supports EMV if(dev_list[0].rfInterface == RFAL_NFC_INTERFACE_ISODEP) { result->nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len; @@ -238,10 +238,10 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { FURI_LOG_I(NFC_WORKER_TAG, "Send select PPSE command"); tx_len = emv_prepare_select_ppse(tx_buff); - err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); + err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); if(err != ERR_NONE) { FURI_LOG_E(NFC_WORKER_TAG, "Error during selection PPSE request: %d", err); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); continue; } FURI_LOG_I( @@ -250,16 +250,16 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { FURI_LOG_I(NFC_WORKER_TAG, "Select PPSE responce parced"); } else { FURI_LOG_E(NFC_WORKER_TAG, "Can't find pay application"); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); continue; } FURI_LOG_I(NFC_WORKER_TAG, "Starting application ..."); tx_len = emv_prepare_select_app(tx_buff, &emv_app); - err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); + err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); if(err != ERR_NONE) { FURI_LOG_E( NFC_WORKER_TAG, "Error during application selection request: %d", err); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); continue; } FURI_LOG_I( @@ -270,16 +270,16 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { memcpy(result->emv_data.name, emv_app.name, sizeof(emv_app.name)); } else { FURI_LOG_E(NFC_WORKER_TAG, "Can't read card name"); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); continue; } FURI_LOG_I(NFC_WORKER_TAG, "Starting Get Processing Options command ..."); tx_len = emv_prepare_get_proc_opt(tx_buff, &emv_app); - err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); + err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); if(err != ERR_NONE) { FURI_LOG_E( NFC_WORKER_TAG, "Error during Get Processing Options command: %d", err); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); continue; } if(emv_decode_get_proc_opt(rx_buff, *rx_len, &emv_app)) { @@ -303,7 +303,7 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { // Iterate over all records in file for(uint8_t record = record_start; record <= record_end; ++record) { tx_len = emv_prepare_read_sfi_record(tx_buff, sfi, record); - err = api_hal_nfc_data_exchange( + err = furi_hal_nfc_data_exchange( tx_buff, tx_len, &rx_buff, &rx_len, false); if(err != ERR_NONE) { FURI_LOG_E( @@ -336,17 +336,17 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { } else { FURI_LOG_E(NFC_WORKER_TAG, "Can't read card number"); } - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); } } else { // Can't find EMV card FURI_LOG_W(NFC_WORKER_TAG, "Card doesn't support EMV"); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); } } else { // Can't find EMV card FURI_LOG_W(NFC_WORKER_TAG, "Can't find any cards"); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); } osDelay(20); } @@ -406,47 +406,47 @@ void nfc_worker_emulate_apdu(NfcWorker* nfc_worker) { 0x00, 0x00}; while(nfc_worker->state == NfcWorkerStateEmulateApdu) { - if(api_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, 300)) { + if(furi_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, 300)) { FURI_LOG_I(NFC_WORKER_TAG, "POS terminal detected"); // Read data from POS terminal - err = api_hal_nfc_data_exchange(NULL, 0, &rx_buff, &rx_len, false); + err = furi_hal_nfc_data_exchange(NULL, 0, &rx_buff, &rx_len, false); if(err == ERR_NONE) { FURI_LOG_I(NFC_WORKER_TAG, "Received Select PPSE"); } else { FURI_LOG_E(NFC_WORKER_TAG, "Error in 1st data exchange: select PPSE"); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); continue; } FURI_LOG_I(NFC_WORKER_TAG, "Transive SELECT PPSE ANS"); tx_len = emv_select_ppse_ans(tx_buff); - err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); + err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); if(err == ERR_NONE) { FURI_LOG_I(NFC_WORKER_TAG, "Received Select APP"); } else { FURI_LOG_E(NFC_WORKER_TAG, "Error in 2nd data exchange: select APP"); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); continue; } FURI_LOG_I(NFC_WORKER_TAG, "Transive SELECT APP ANS"); tx_len = emv_select_app_ans(tx_buff); - err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); + err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); if(err == ERR_NONE) { FURI_LOG_I(NFC_WORKER_TAG, "Received PDOL"); } else { FURI_LOG_E(NFC_WORKER_TAG, "Error in 3rd data exchange: receive PDOL"); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); continue; } FURI_LOG_I(NFC_WORKER_TAG, "Transive PDOL ANS"); tx_len = emv_get_proc_opt_ans(tx_buff); - err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); + err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); if(err == ERR_NONE) { FURI_LOG_I(NFC_WORKER_TAG, "Transive PDOL ANS"); } else { FURI_LOG_E(NFC_WORKER_TAG, "Error in 4rd data exchange: Transive PDOL ANS"); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); continue; } @@ -455,13 +455,13 @@ void nfc_worker_emulate_apdu(NfcWorker* nfc_worker) { } else { FURI_LOG_I(NFC_WORKER_TAG, "Correct debug message received"); tx_len = sizeof(debug_tx); - err = api_hal_nfc_data_exchange( + err = furi_hal_nfc_data_exchange( (uint8_t*)debug_tx, tx_len, &rx_buff, &rx_len, false); if(err == ERR_NONE) { FURI_LOG_I(NFC_WORKER_TAG, "Transive Debug message"); } } - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); } else { FURI_LOG_W(NFC_WORKER_TAG, "Can't find reader"); } @@ -481,9 +481,9 @@ void nfc_worker_read_mifare_ul(NfcWorker* nfc_worker) { NfcDeviceData* result = nfc_worker->dev_data; while(nfc_worker->state == NfcWorkerStateReadMifareUl) { - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); memset(&mf_ul_read, 0, sizeof(mf_ul_read)); - if(api_hal_nfc_detect(&dev_list, &dev_cnt, 300, false)) { + if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 300, false)) { if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCA && mf_ul_check_card_type( dev_list[0].dev.nfca.sensRes.anticollisionInfo, @@ -492,7 +492,7 @@ void nfc_worker_read_mifare_ul(NfcWorker* nfc_worker) { // Get Mifare Ultralight version FURI_LOG_I(NFC_WORKER_TAG, "Found Mifare Ultralight tag. Reading tag version"); tx_len = mf_ul_prepare_get_version(tx_buff); - err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); + err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); if(err == ERR_NONE) { mf_ul_parse_get_version_response(rx_buff, &mf_ul_read); FURI_LOG_I( @@ -507,8 +507,8 @@ void nfc_worker_read_mifare_ul(NfcWorker* nfc_worker) { err = ERR_NONE; mf_ul_set_default_version(&mf_ul_read); // Reinit device - api_hal_nfc_deactivate(); - if(!api_hal_nfc_detect(&dev_list, &dev_cnt, 300, false)) { + furi_hal_nfc_deactivate(); + if(!furi_hal_nfc_detect(&dev_list, &dev_cnt, 300, false)) { FURI_LOG_E(NFC_WORKER_TAG, "Lost connection. Restarting search"); continue; } @@ -523,7 +523,7 @@ void nfc_worker_read_mifare_ul(NfcWorker* nfc_worker) { if(mf_ul_read.support_fast_read) { FURI_LOG_I(NFC_WORKER_TAG, "Reading pages ..."); tx_len = mf_ul_prepare_fast_read(tx_buff, 0x00, mf_ul_read.pages_to_read - 1); - if(api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) { + if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) { FURI_LOG_E(NFC_WORKER_TAG, "Failed reading pages"); continue; } else { @@ -533,7 +533,7 @@ void nfc_worker_read_mifare_ul(NfcWorker* nfc_worker) { FURI_LOG_I(NFC_WORKER_TAG, "Reading signature ..."); tx_len = mf_ul_prepare_read_signature(tx_buff); - if(api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) { + if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) { FURI_LOG_W(NFC_WORKER_TAG, "Failed reading signature"); memset(mf_ul_read.data.signature, 0, sizeof(mf_ul_read.data.signature)); } else { @@ -543,7 +543,7 @@ void nfc_worker_read_mifare_ul(NfcWorker* nfc_worker) { FURI_LOG_I(NFC_WORKER_TAG, "Reading 3 counters ..."); for(uint8_t i = 0; i < 3; i++) { tx_len = mf_ul_prepare_read_cnt(tx_buff, i); - if(api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) { + if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) { FURI_LOG_W(NFC_WORKER_TAG, "Failed reading Counter %d", i); mf_ul_read.data.counter[i] = 0; } else { @@ -554,7 +554,7 @@ void nfc_worker_read_mifare_ul(NfcWorker* nfc_worker) { FURI_LOG_I(NFC_WORKER_TAG, "Checking tearing flags ..."); for(uint8_t i = 0; i < 3; i++) { tx_len = mf_ul_prepare_check_tearing(tx_buff, i); - if(api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) { + if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) { FURI_LOG_E(NFC_WORKER_TAG, "Error checking tearing flag %d", i); mf_ul_read.data.tearing[i] = MF_UL_TEARING_FLAG_DEFAULT; } else { @@ -566,7 +566,7 @@ void nfc_worker_read_mifare_ul(NfcWorker* nfc_worker) { for(uint8_t page = 0; page < mf_ul_read.pages_to_read; page += 4) { FURI_LOG_I(NFC_WORKER_TAG, "Reading pages %d - %d ...", page, page + 3); tx_len = mf_ul_prepare_read(tx_buff, page); - if(api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) { + if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) { FURI_LOG_E( NFC_WORKER_TAG, "Read pages %d - %d failed", page, page + 3); continue; @@ -610,7 +610,7 @@ void nfc_worker_emulate_mifare_ul(NfcWorker* nfc_worker) { NfcDeviceData* data = nfc_worker->dev_data; while(nfc_worker->state == NfcWorkerStateEmulateMifareUl) { - if(api_hal_nfc_listen( + if(furi_hal_nfc_listen( data->nfc_data.uid, data->nfc_data.uid_len, data->nfc_data.atqa, @@ -620,7 +620,7 @@ void nfc_worker_emulate_mifare_ul(NfcWorker* nfc_worker) { // Prepare version answer tx_len = sizeof(data->mf_ul_data.version); memcpy(tx_buff, &data->mf_ul_data.version, tx_len); - err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); + err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); if(err == ERR_NONE) { FURI_LOG_I(NFC_WORKER_TAG, "Received 1st message:"); for(uint16_t i = 0; i < *rx_len; i++) { @@ -629,7 +629,7 @@ void nfc_worker_emulate_mifare_ul(NfcWorker* nfc_worker) { printf("\r\n"); } else { FURI_LOG_E(NFC_WORKER_TAG, "Error in 1st data exchange: select PPSE"); - api_hal_nfc_deactivate(); + furi_hal_nfc_deactivate(); continue; } } @@ -639,9 +639,9 @@ void nfc_worker_emulate_mifare_ul(NfcWorker* nfc_worker) { } void nfc_worker_field(NfcWorker* nfc_worker) { - api_hal_nfc_field_on(); + furi_hal_nfc_field_on(); while(nfc_worker->state == NfcWorkerStateField) { osDelay(50); } - api_hal_nfc_field_off(); + furi_hal_nfc_field_off(); } diff --git a/applications/notification/notification-app-api.c b/applications/notification/notification-app-api.c index 5905d30a7e4..c14ca5e17f0 100644 --- a/applications/notification/notification-app-api.c +++ b/applications/notification/notification-app-api.c @@ -1,5 +1,5 @@ #include -#include +#include #include "notification.h" #include "notification-messages.h" #include "notification-app.h" diff --git a/applications/notification/notification-app.c b/applications/notification/notification-app.c index ffc9048719f..69ac043d50d 100644 --- a/applications/notification/notification-app.c +++ b/applications/notification/notification-app.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include "notification.h" #include "notification-messages.h" @@ -41,7 +41,7 @@ void notification_apply_internal_led_layer(NotificationLedLayer* layer, uint8_t // apply if current layer is internal if(layer->index == LayerInternal) { - api_hal_light_set(layer->light, layer->value[LayerInternal]); + furi_hal_light_set(layer->light, layer->value[LayerInternal]); } } @@ -71,7 +71,7 @@ void notification_apply_notification_led_layer( // set layer layer->value[LayerNotification] = layer_value; // apply - api_hal_light_set(layer->light, layer->value[LayerNotification]); + furi_hal_light_set(layer->light, layer->value[LayerNotification]); } void notification_reset_notification_led_layer(NotificationLedLayer* layer) { @@ -84,7 +84,7 @@ void notification_reset_notification_led_layer(NotificationLedLayer* layer) { layer->index = LayerInternal; // apply - api_hal_light_set(layer->light, layer->value[LayerInternal]); + furi_hal_light_set(layer->light, layer->value[LayerInternal]); } void notification_reset_notification_layer(NotificationApp* app, uint8_t reset_mask) { @@ -130,11 +130,11 @@ uint32_t notification_settings_display_off_delay_ticks(NotificationApp* app) { // generics void notification_vibro_on() { - api_hal_vibro_on(true); + furi_hal_vibro_on(true); } void notification_vibro_off() { - api_hal_vibro_on(false); + furi_hal_vibro_on(false); } void notification_sound_on(float pwm, float freq) { @@ -434,7 +434,7 @@ static NotificationApp* notification_app_alloc() { }; // App -int32_t notification_app(void* p) { +int32_t notification_srv(void* p) { NotificationApp* app = notification_app_alloc(); if(!notification_load_settings(app)) { diff --git a/applications/notification/notification-app.h b/applications/notification/notification-app.h index a6e5ba84bbc..78c58f6d8a1 100644 --- a/applications/notification/notification-app.h +++ b/applications/notification/notification-app.h @@ -1,5 +1,5 @@ #include -#include +#include #include "notification.h" #include "notification-messages.h" diff --git a/applications/notification/notification-app-settings.c b/applications/notification/notification-settings-app.c similarity index 99% rename from applications/notification/notification-app-settings.c rename to applications/notification/notification-settings-app.c index 3bcf084b1ed..78d7c65e89b 100644 --- a/applications/notification/notification-app-settings.c +++ b/applications/notification/notification-settings-app.c @@ -222,7 +222,7 @@ static void free_settings(NotificationAppSettings* app) { free(app); } -int32_t notification_app_settings(void* p) { +int32_t notification_settings_app(void* p) { NotificationAppSettings* app = alloc_settings(); view_dispatcher_run(app->view_dispatcher); notification_message_save_settings(app->notification); diff --git a/applications/power-observer/power-observer.c b/applications/power-observer/power-observer.c index 5a411eca6ac..7d2388c0da6 100644 --- a/applications/power-observer/power-observer.c +++ b/applications/power-observer/power-observer.c @@ -1,5 +1,5 @@ #include -#include +#include #include const NotificationMessage message_green_110 = { @@ -14,13 +14,13 @@ static const NotificationSequence sequence_overconsumption = { NULL, }; -int32_t power_observer(void* p) { +int32_t power_observer_srv(void* p) { NotificationApp* notifications = furi_record_open("notification"); const float overconsumption_limit = 0.03f; while(true) { - float current = -api_hal_power_get_battery_current(ApiHalPowerICFuelGauge); + float current = -furi_hal_power_get_battery_current(FuriHalPowerICFuelGauge); if(current >= overconsumption_limit) { notification_message_block(notifications, &sequence_overconsumption); diff --git a/applications/power/power.c b/applications/power/power.c index 22bc5db41c6..b083f6eadb2 100644 --- a/applications/power/power.c +++ b/applications/power/power.c @@ -3,7 +3,7 @@ #include "power_views.h" #include -#include +#include #include #include @@ -86,11 +86,11 @@ void power_menu_reset_callback(void* context) { } void power_menu_enable_otg_callback(void* context) { - api_hal_power_enable_otg(); + furi_hal_power_enable_otg(); } void power_menu_disable_otg_callback(void* context) { - api_hal_power_disable_otg(); + furi_hal_power_disable_otg(); } void power_menu_info_callback(void* context) { @@ -157,22 +157,22 @@ void power_free(Power* power) { void power_off(Power* power) { furi_assert(power); - api_hal_power_off(); + furi_hal_power_off(); view_dispatcher_switch_to_view(power->view_dispatcher, PowerViewDisconnect); } void power_reboot(Power* power, PowerBootMode mode) { if(mode == PowerBootModeNormal) { - api_hal_boot_set_mode(ApiHalBootModeNormal); + furi_hal_boot_set_mode(FuriHalBootModeNormal); } else if(mode == PowerBootModeDfu) { - api_hal_boot_set_mode(ApiHalBootModeDFU); + furi_hal_boot_set_mode(FuriHalBootModeDFU); } - api_hal_power_reset(); + furi_hal_power_reset(); } static void power_charging_indication_handler(Power* power, NotificationApp* notifications) { - if(api_hal_power_is_charging()) { - if(api_hal_power_get_pct() == 100) { + if(furi_hal_power_is_charging()) { + if(furi_hal_power_get_pct() == 100) { if(power->state != PowerStateCharged) { notification_internal_message(notifications, &sequence_charged); power->state = PowerStateCharged; @@ -185,7 +185,7 @@ static void power_charging_indication_handler(Power* power, NotificationApp* not } } - if(!api_hal_power_is_charging()) { + if(!furi_hal_power_is_charging()) { if(power->state != PowerStateNotCharging) { notification_internal_message(notifications, &sequence_not_charging); power->state = PowerStateNotCharging; @@ -193,7 +193,7 @@ static void power_charging_indication_handler(Power* power, NotificationApp* not } } -int32_t power_task(void* p) { +int32_t power_srv(void* p) { (void)p; Power* power = power_alloc(); @@ -212,19 +212,19 @@ int32_t power_task(void* p) { with_view_model( power->info_view, (PowerInfoModel * model) { - model->charge = api_hal_power_get_pct(); - model->health = api_hal_power_get_bat_health_pct(); - model->capacity_remaining = api_hal_power_get_battery_remaining_capacity(); - model->capacity_full = api_hal_power_get_battery_full_capacity(); - model->current_charger = api_hal_power_get_battery_current(ApiHalPowerICCharger); - model->current_gauge = api_hal_power_get_battery_current(ApiHalPowerICFuelGauge); - model->voltage_charger = api_hal_power_get_battery_voltage(ApiHalPowerICCharger); - model->voltage_gauge = api_hal_power_get_battery_voltage(ApiHalPowerICFuelGauge); - model->voltage_vbus = api_hal_power_get_usb_voltage(); + model->charge = furi_hal_power_get_pct(); + model->health = furi_hal_power_get_bat_health_pct(); + model->capacity_remaining = furi_hal_power_get_battery_remaining_capacity(); + model->capacity_full = furi_hal_power_get_battery_full_capacity(); + model->current_charger = furi_hal_power_get_battery_current(FuriHalPowerICCharger); + model->current_gauge = furi_hal_power_get_battery_current(FuriHalPowerICFuelGauge); + model->voltage_charger = furi_hal_power_get_battery_voltage(FuriHalPowerICCharger); + model->voltage_gauge = furi_hal_power_get_battery_voltage(FuriHalPowerICFuelGauge); + model->voltage_vbus = furi_hal_power_get_usb_voltage(); model->temperature_charger = - api_hal_power_get_battery_temperature(ApiHalPowerICCharger); + furi_hal_power_get_battery_temperature(FuriHalPowerICCharger); model->temperature_gauge = - api_hal_power_get_battery_temperature(ApiHalPowerICFuelGauge); + furi_hal_power_get_battery_temperature(FuriHalPowerICFuelGauge); if(model->charge == 0 && model->voltage_vbus < 4.0f) { battery_low = true; diff --git a/applications/power/power_cli.c b/applications/power/power_cli.c index e66e82b19d2..c39cafdebad 100644 --- a/applications/power/power_cli.c +++ b/applications/power/power_cli.c @@ -1,5 +1,5 @@ #include "power_cli.h" -#include +#include void power_cli_poweroff(Cli* cli, string_t args, void* context) { Power* power = context; @@ -22,7 +22,7 @@ void power_cli_factory_reset(Cli* cli, string_t args, void* context) { char c = cli_getc(cli); if(c == 'y' || c == 'Y') { printf("Data will be wiped after reboot.\r\n"); - api_hal_boot_set_flags(ApiHalBootFlagFactoryReset); + furi_hal_boot_set_flags(FuriHalBootFlagFactoryReset); power_reboot(power, PowerBootModeNormal); } else { printf("Safe choice.\r\n"); @@ -30,14 +30,14 @@ void power_cli_factory_reset(Cli* cli, string_t args, void* context) { } void power_cli_info(Cli* cli, string_t args, void* context) { - api_hal_power_dump_state(); + furi_hal_power_dump_state(); } void power_cli_otg(Cli* cli, string_t args, void* context) { if(!string_cmp(args, "0")) { - api_hal_power_disable_otg(); + furi_hal_power_disable_otg(); } else if(!string_cmp(args, "1")) { - api_hal_power_enable_otg(); + furi_hal_power_enable_otg(); } else { cli_print_usage("power_otg", "<1|0>", string_get_cstr(args)); } @@ -45,9 +45,9 @@ void power_cli_otg(Cli* cli, string_t args, void* context) { void power_cli_ext(Cli* cli, string_t args, void* context) { if(!string_cmp(args, "0")) { - api_hal_power_disable_external_3_3v(); + furi_hal_power_disable_external_3_3v(); } else if(!string_cmp(args, "1")) { - api_hal_power_enable_external_3_3v(); + furi_hal_power_enable_external_3_3v(); } else { cli_print_usage("power_ext", "<1|0>", string_get_cstr(args)); } diff --git a/applications/scened-app-example/scened-app.h b/applications/scened-app-example/scened-app.h index d45dbf834f3..b5e2bbf1ab3 100644 --- a/applications/scened-app-example/scened-app.h +++ b/applications/scened-app-example/scened-app.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include #include diff --git a/applications/storage-settings/scenes/storage-settings-scene-internal-info.c b/applications/storage-settings/scenes/storage-settings-scene-internal-info.c index 5dff893afd8..389cad0c1c5 100644 --- a/applications/storage-settings/scenes/storage-settings-scene-internal-info.c +++ b/applications/storage-settings/scenes/storage-settings-scene-internal-info.c @@ -1,5 +1,5 @@ #include "../storage-settings.h" -#include +#include static void storage_settings_scene_internal_info_dialog_callback(DialogExResult result, void* context) { @@ -28,7 +28,7 @@ void storage_settings_scene_internal_info_on_enter(void* context) { string_printf( app->text_string, "Label: %s\nType: LittleFS\n%lu KB total\n%lu KB free", - api_hal_version_get_name_ptr(), + furi_hal_version_get_name_ptr() ? furi_hal_version_get_name_ptr() : "Unknown", (uint32_t)(total_space / 1024), (uint32_t)(free_space / 1024)); dialog_ex_set_text( diff --git a/applications/storage-settings/storage-settings.c b/applications/storage-settings/storage-settings.c index 49da39a223a..8e18071b4ab 100644 --- a/applications/storage-settings/storage-settings.c +++ b/applications/storage-settings/storage-settings.c @@ -65,7 +65,7 @@ static void storage_settings_free(StorageSettings* app) { free(app); } -int32_t storage_settings(void* p) { +int32_t storage_settings_app(void* p) { StorageSettings* app = storage_settings_alloc(); view_dispatcher_run(app->view_dispatcher); diff --git a/applications/storage/storage-cli.c b/applications/storage/storage-cli.c index 684e9a8bbcd..a67378a3dac 100644 --- a/applications/storage/storage-cli.c +++ b/applications/storage/storage-cli.c @@ -3,7 +3,7 @@ #include #include #include -#include +#include #define MAX_NAME_LENGTH 255 @@ -64,7 +64,7 @@ void storage_cli_info(Cli* cli, string_t path) { } else { printf( "Label: %s\r\nType: LittleFS\r\n%lu KB total\r\n%lu KB free\r\n", - api_hal_version_get_name_ptr(), + furi_hal_version_get_name_ptr() ? furi_hal_version_get_name_ptr() : "Unknown", (uint32_t)(total_space / 1024), (uint32_t)(free_space / 1024)); } diff --git a/applications/storage/storage-glue.c b/applications/storage/storage-glue.c index 9477712dccd..8f115f53d33 100644 --- a/applications/storage/storage-glue.c +++ b/applications/storage/storage-glue.c @@ -1,5 +1,5 @@ #include "storage-glue.h" -#include +#include /****************** storage file ******************/ @@ -39,12 +39,12 @@ void storage_data_init(StorageData* storage) { } bool storage_data_lock(StorageData* storage) { - api_hal_power_insomnia_enter(); + furi_hal_power_insomnia_enter(); return (osMutexAcquire(storage->mutex, osWaitForever) == osOK); } bool storage_data_unlock(StorageData* storage) { - api_hal_power_insomnia_exit(); + furi_hal_power_insomnia_exit(); return (osMutexRelease(storage->mutex) == osOK); } diff --git a/applications/storage/storage-test-app.c b/applications/storage/storage-test-app.c index bfc8216ff88..022181a587a 100644 --- a/applications/storage/storage-test-app.c +++ b/applications/storage/storage-test-app.c @@ -1,5 +1,5 @@ #include -#include +#include #include #define TAG "storage-test" @@ -315,7 +315,7 @@ static void do_test_end(Storage* api, const char* path) { string_clear(str_path_2); } -int32_t storage_app_test(void* p) { +int32_t storage_test_app(void* p) { Storage* api = furi_record_open("storage"); do_test_start(api, "/int"); do_test_start(api, "/any"); diff --git a/applications/storage/storage.c b/applications/storage/storage.c index 601ac441afd..ef229db0d39 100644 --- a/applications/storage/storage.c +++ b/applications/storage/storage.c @@ -79,7 +79,7 @@ void storage_tick(Storage* app) { } } -int32_t storage_app(void* p) { +int32_t storage_srv(void* p) { Storage* app = storage_app_alloc(); furi_record_create("storage", app); diff --git a/applications/storage/storages/storage-ext.c b/applications/storage/storages/storage-ext.c index 6d0f7b685d8..b29fdf7a6b5 100644 --- a/applications/storage/storages/storage-ext.c +++ b/applications/storage/storages/storage-ext.c @@ -1,9 +1,9 @@ #include "fatfs.h" #include "../filesystem-api-internal.h" #include "storage-ext.h" -#include +#include #include "sd-notify.h" -#include +#include typedef FIL SDFile; typedef DIR SDDir; diff --git a/applications/storage/storages/storage-int.c b/applications/storage/storages/storage-int.c index 625ded6db93..473ac4f5758 100644 --- a/applications/storage/storages/storage-int.c +++ b/applications/storage/storages/storage-int.c @@ -1,6 +1,6 @@ #include "storage-int.h" #include -#include +#include #define TAG "storage-int" #define STORAGE_PATH "/int" @@ -103,7 +103,7 @@ static int storage_int_device_prog( int ret = 0; while(size > 0) { - if(!api_hal_flash_write_dword(address, *(uint64_t*)buffer)) { + if(!furi_hal_flash_write_dword(address, *(uint64_t*)buffer)) { ret = -1; break; } @@ -121,7 +121,7 @@ static int storage_int_device_erase(const struct lfs_config* c, lfs_block_t bloc FURI_LOG_D(TAG, "Device erase: page %d, translated page: %d", block, page); - if(api_hal_flash_erase(page, 1)) { + if(furi_hal_flash_erase(page, 1)) { return 0; } else { return -1; @@ -137,9 +137,9 @@ static LFSData* storage_int_lfs_data_alloc() { LFSData* lfs_data = furi_alloc(sizeof(LFSData)); // Internal storage start address - *(size_t*)(&lfs_data->start_address) = api_hal_flash_get_free_page_start_address(); + *(size_t*)(&lfs_data->start_address) = furi_hal_flash_get_free_page_start_address(); *(size_t*)(&lfs_data->start_page) = - (lfs_data->start_address - api_hal_flash_get_base()) / api_hal_flash_get_page_size(); + (lfs_data->start_address - furi_hal_flash_get_base()) / furi_hal_flash_get_page_size(); // LFS configuration // Glue and context @@ -150,11 +150,11 @@ static LFSData* storage_int_lfs_data_alloc() { lfs_data->config.sync = storage_int_device_sync; // Block device description - lfs_data->config.read_size = api_hal_flash_get_read_block_size(); - lfs_data->config.prog_size = api_hal_flash_get_write_block_size(); - lfs_data->config.block_size = api_hal_flash_get_page_size(); - lfs_data->config.block_count = api_hal_flash_get_free_page_count(); - lfs_data->config.block_cycles = api_hal_flash_get_cycles_count(); + lfs_data->config.read_size = furi_hal_flash_get_read_block_size(); + lfs_data->config.prog_size = furi_hal_flash_get_write_block_size(); + lfs_data->config.block_size = furi_hal_flash_get_page_size(); + lfs_data->config.block_count = furi_hal_flash_get_free_page_count(); + lfs_data->config.block_cycles = furi_hal_flash_get_cycles_count(); lfs_data->config.cache_size = 16; lfs_data->config.lookahead_size = 16; @@ -163,15 +163,15 @@ static LFSData* storage_int_lfs_data_alloc() { static void storage_int_lfs_mount(LFSData* lfs_data, StorageData* storage) { int err; - ApiHalBootFlag boot_flags = api_hal_boot_get_flags(); + FuriHalBootFlag boot_flags = furi_hal_boot_get_flags(); lfs_t* lfs = &lfs_data->lfs; - if(boot_flags & ApiHalBootFlagFactoryReset) { + if(boot_flags & FuriHalBootFlagFactoryReset) { // Factory reset err = lfs_format(lfs, &lfs_data->config); if(err == 0) { FURI_LOG_I(TAG, "Factory reset: Format successful, trying to mount"); - api_hal_boot_set_flags(boot_flags & ~ApiHalBootFlagFactoryReset); + furi_hal_boot_set_flags(boot_flags & ~FuriHalBootFlagFactoryReset); err = lfs_mount(lfs, &lfs_data->config); if(err == 0) { FURI_LOG_I(TAG, "Factory reset: Mounted"); diff --git a/applications/subghz/scenes/subghz_scene.c b/applications/subghz/scenes/subghz_scene.c new file mode 100644 index 00000000000..be84949d67f --- /dev/null +++ b/applications/subghz/scenes/subghz_scene.c @@ -0,0 +1,30 @@ +#include "subghz_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const subghz_on_enter_handlers[])(void*) = { +#include "subghz_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_event handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, +bool (*const subghz_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "subghz_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_exit handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, +void (*const subghz_on_exit_handlers[])(void* context) = { +#include "subghz_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers subghz_scene_handlers = { + .on_enter_handlers = subghz_on_enter_handlers, + .on_event_handlers = subghz_on_event_handlers, + .on_exit_handlers = subghz_on_exit_handlers, + .scene_num = SubGhzSceneNum, +}; diff --git a/applications/subghz/scenes/subghz_scene.h b/applications/subghz/scenes/subghz_scene.h new file mode 100644 index 00000000000..2b667852de6 --- /dev/null +++ b/applications/subghz/scenes/subghz_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) SubGhzScene##id, +typedef enum { +#include "subghz_scene_config.h" + SubGhzSceneNum, +} SubGhzScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers subghz_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "subghz_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_event handlers declaration +#define ADD_SCENE(prefix, name, id) \ + bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); +#include "subghz_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_exit handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); +#include "subghz_scene_config.h" +#undef ADD_SCENE diff --git a/applications/subghz/scenes/subghz_scene_analyze.c b/applications/subghz/scenes/subghz_scene_analyze.c new file mode 100644 index 00000000000..e598589361a --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_analyze.c @@ -0,0 +1,15 @@ +#include "../subghz_i.h" + +const void subghz_scene_analyze_on_enter(void* context) { + SubGhz* subghz = context; + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewAnalyze); +} + +const bool subghz_scene_analyze_on_event(void* context, SceneManagerEvent event) { + // SubGhz* subghz = context; + return false; +} + +const void subghz_scene_analyze_on_exit(void* context) { + // SubGhz* subghz = context; +} diff --git a/applications/subghz/scenes/subghz_scene_config.h b/applications/subghz/scenes/subghz_scene_config.h new file mode 100644 index 00000000000..aa2ddd6adf0 --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_config.h @@ -0,0 +1,12 @@ +ADD_SCENE(subghz, start, Start) +ADD_SCENE(subghz, analyze, Analyze) +ADD_SCENE(subghz, read, Read) +ADD_SCENE(subghz, receiver, Receiver) +ADD_SCENE(subghz, save_name, SaveName) +ADD_SCENE(subghz, save_success, SaveSuccess) +ADD_SCENE(subghz, saved, Saved) +ADD_SCENE(subghz, transmitter, Transmitter) +ADD_SCENE(subghz, static, Static) +ADD_SCENE(subghz, test, Test) +ADD_SCENE(subghz, test_carrier, TestCarrier) +ADD_SCENE(subghz, test_packet, TestPacket) diff --git a/applications/subghz/scenes/subghz_scene_read.c b/applications/subghz/scenes/subghz_scene_read.c new file mode 100644 index 00000000000..02906ff81b2 --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_read.c @@ -0,0 +1,57 @@ +#include "../subghz_i.h" + +#define GUBGHZ_READ_CUSTOM_EVENT (10UL) + +void subghz_read_protocol_callback(SubGhzProtocolCommon* parser, void* context) { + furi_assert(context); + SubGhz* subghz = context; + subghz->protocol_result = parser; + view_dispatcher_send_custom_event(subghz->view_dispatcher, GUBGHZ_READ_CUSTOM_EVENT); +} +void subghz_scene_read_callback(DialogExResult result, void* context) { + SubGhz* subghz = context; + view_dispatcher_send_custom_event(subghz->view_dispatcher, result); +} + +const void subghz_scene_read_on_enter(void* context) { + SubGhz* subghz = context; + + // Setup view + DialogEx* dialog_ex = subghz->dialog_ex; + + dialog_ex_set_header(dialog_ex, "SubGhz 433.92", 36, 6, AlignLeft, AlignCenter); + dialog_ex_set_icon(dialog_ex, 10, 12, &I_RFIDDolphinReceive_97x61); + + //Start CC1101 rx + subghz_begin(FuriHalSubGhzPresetOokAsync); + subghz_rx(433920000); + furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, subghz->worker); + subghz_worker_start(subghz->worker); + subghz_protocol_enable_dump(subghz->protocol, subghz_read_protocol_callback, subghz); + + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewDialogEx); +} + +const bool subghz_scene_read_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GUBGHZ_READ_CUSTOM_EVENT) { + scene_manager_next_scene(subghz->scene_manager, SubGhzViewReceiver); + return true; + } + } + return false; +} + +const void subghz_scene_read_on_exit(void* context) { + SubGhz* subghz = context; + + //Stop CC1101 + subghz_worker_stop(subghz->worker); + furi_hal_subghz_stop_async_rx(); + subghz_end(); + + DialogEx* dialog_ex = subghz->dialog_ex; + dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); + dialog_ex_set_icon(dialog_ex, 0, 0, NULL); +} diff --git a/applications/subghz/scenes/subghz_scene_receiver.c b/applications/subghz/scenes/subghz_scene_receiver.c new file mode 100644 index 00000000000..1fe9a466e5a --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_receiver.c @@ -0,0 +1,37 @@ +#include "../subghz_i.h" +#include "../views/subghz_receiver.h" + +void subghz_scene_receiver_callback(SubghzReceverEvent event, void* context) { + furi_assert(context); + SubGhz* subghz = context; + view_dispatcher_send_custom_event(subghz->view_dispatcher, event); +} + +const void subghz_scene_receiver_on_enter(void* context) { + SubGhz* subghz = context; + SubghzReceiver* subghz_receiver = subghz->subghz_receiver; + + subghz_receiver_set_callback(subghz_receiver, subghz_scene_receiver_callback, subghz); + + subghz_receiver_set_protocol(subghz_receiver, subghz->protocol_result); + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewReceiver); +} + +const bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubghzReceverEventSave) { + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); + return true; + } else if(event.event == SubghzReceverEventBack) { + scene_manager_previous_scene(subghz->scene_manager); + return true; + } + } + return false; +} + +const void subghz_scene_receiver_on_exit(void* context) { + // SubGhz* subghz = context; +} diff --git a/applications/subghz/scenes/subghz_scene_save_name.c b/applications/subghz/scenes/subghz_scene_save_name.c new file mode 100644 index 00000000000..329c6931fed --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_save_name.c @@ -0,0 +1,102 @@ +#include "../subghz_i.h" +#include +#include "file-worker.h" + +#define SCENE_SAVE_NAME_CUSTOM_EVENT (0UL) + +bool subghz_scene_save_data_to_file(void* context, const char* dev_name) { + SubGhz* subghz = context; + FileWorker* file_worker = file_worker_alloc(false); + string_t dev_file_name; + string_init(dev_file_name); + string_t temp_str; + string_init(temp_str); + bool saved = false; + + do { + // Create subghz folder directory if necessary + if(!file_worker_mkdir(file_worker, SUBGHZ_APP_FOLDER)) { + break; + } + // Create saved directory if necessary + if(!file_worker_mkdir(file_worker, SUBGHZ_APP_PATH_FOLDER)) { + break; + } + // First remove subghz device file if it was saved + string_printf( + dev_file_name, "%s/%s%s", SUBGHZ_APP_PATH_FOLDER, dev_name, SUBGHZ_APP_EXTENSION); + if(!file_worker_remove(file_worker, string_get_cstr(dev_file_name))) { + break; + } + // Open file + if(!file_worker_open( + file_worker, string_get_cstr(dev_file_name), FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + break; + } + //Get string save + subghz->protocol_result->to_save_string(subghz->protocol_result, temp_str); + // Prepare and write data to file + if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_size(temp_str))) { + break; + } + saved = true; + } while(0); + + string_clear(temp_str); + string_clear(dev_file_name); + file_worker_close(file_worker); + file_worker_free(file_worker); + + return saved; +} + +void subghz_scene_save_name_text_input_callback(void* context) { + SubGhz* subghz = context; + view_dispatcher_send_custom_event(subghz->view_dispatcher, SCENE_SAVE_NAME_CUSTOM_EVENT); +} + +const void subghz_scene_save_name_on_enter(void* context) { + SubGhz* subghz = context; + + // Setup view + TextInput* text_input = subghz->text_input; + bool dev_name_empty = false; + + set_random_name(subghz->text_store, sizeof(subghz->text_store)); + dev_name_empty = true; + + text_input_set_header_text(text_input, "Name the KEY"); + text_input_set_result_callback( + text_input, + subghz_scene_save_name_text_input_callback, + subghz, + subghz->text_store, + 22, //Max len name + dev_name_empty); + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewTextInput); +} + +const bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SCENE_SAVE_NAME_CUSTOM_EVENT) { + if(subghz_scene_save_data_to_file(subghz, subghz->text_store)) { + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveSuccess); + return true; + } else { + //Error save + return true; + } + } + } + return false; +} + +const void subghz_scene_save_name_on_exit(void* context) { + SubGhz* subghz = context; + + // Clear view + text_input_set_header_text(subghz->text_input, NULL); + text_input_set_result_callback(subghz->text_input, NULL, NULL, NULL, 0, false); +} diff --git a/applications/subghz/scenes/subghz_scene_save_success.c b/applications/subghz/scenes/subghz_scene_save_success.c new file mode 100644 index 00000000000..4cbc9fcd987 --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_save_success.c @@ -0,0 +1,47 @@ +#include "../subghz_i.h" + +#define SCENE_SAVE_SUCCESS_CUSTOM_EVENT (0UL) + +void subghz_scene_save_success_popup_callback(void* context) { + SubGhz* subghz = context; + view_dispatcher_send_custom_event(subghz->view_dispatcher, SCENE_SAVE_SUCCESS_CUSTOM_EVENT); +} + +const void subghz_scene_save_success_on_enter(void* context) { + SubGhz* subghz = context; + + // Setup view + Popup* popup = subghz->popup; + popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); + popup_set_header(popup, "Saved!", 13, 22, AlignLeft, AlignBottom); + popup_set_timeout(popup, 1500); + popup_set_context(popup, subghz); + popup_set_callback(popup, subghz_scene_save_success_popup_callback); + popup_enable_timeout(popup); + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewPopup); +} + +const bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SCENE_SAVE_SUCCESS_CUSTOM_EVENT) { + return scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneStart); + } + } + return false; +} + +const void subghz_scene_save_success_on_exit(void* context) { + SubGhz* subghz = context; + + // Clear view + Popup* popup = subghz->popup; + popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); + popup_set_callback(popup, NULL); + popup_set_context(popup, NULL); + popup_set_timeout(popup, 0); + popup_disable_timeout(popup); +} diff --git a/applications/subghz/scenes/subghz_scene_saved.c b/applications/subghz/scenes/subghz_scene_saved.c new file mode 100644 index 00000000000..d1dd058a7a9 --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_saved.c @@ -0,0 +1,88 @@ +#include "../subghz_i.h" + +bool subghz_scene_saved_file_select(SubGhz* subghz) { + furi_assert(subghz); + + FileWorker* file_worker = file_worker_alloc(false); + string_t protocol_file_name; + string_init(protocol_file_name); + string_t temp_str; + string_init(temp_str); + + // Input events and views are managed by file_select + bool res = file_worker_file_select( + file_worker, + SUBGHZ_APP_PATH_FOLDER, + SUBGHZ_APP_EXTENSION, + subghz->text_store, + sizeof(subghz->text_store), + NULL); + + if(res) { + // Get key file path + string_printf( + protocol_file_name, + "%s/%s%s", + SUBGHZ_APP_PATH_FOLDER, + subghz->text_store, + SUBGHZ_APP_EXTENSION); + } else { + string_clear(temp_str); + string_clear(protocol_file_name); + + file_worker_close(file_worker); + file_worker_free(file_worker); + return res; + } + + do { + if(!file_worker_open( + file_worker, string_get_cstr(protocol_file_name), FSAM_READ, FSOM_OPEN_EXISTING)) { + break; + } + // Read and parse name protocol from 1st line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + // strlen("Protocol: ") = 10 + string_right(temp_str, 10); + subghz->protocol_result = + subghz_protocol_get_by_name(subghz->protocol, string_get_cstr(temp_str)); + if(subghz->protocol_result == NULL) { + file_worker_show_error(file_worker, "Cannot parse\nfile"); + break; + } + if(!subghz->protocol_result->to_load_protocol(file_worker, subghz->protocol_result)) { + file_worker_show_error(file_worker, "Cannot parse\nfile"); + break; + } + res = true; + } while(0); + + string_clear(temp_str); + string_clear(protocol_file_name); + + file_worker_close(file_worker); + file_worker_free(file_worker); + + return res; +} + +const void subghz_scene_saved_on_enter(void* context) { + SubGhz* subghz = context; + + if(subghz_scene_saved_file_select(subghz)) { + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter); + } else { + scene_manager_search_and_switch_to_previous_scene(subghz->scene_manager, SubGhzSceneStart); + } +} + +const bool subghz_scene_saved_on_event(void* context, SceneManagerEvent event) { + // SubGhz* subghz = context; + return false; +} + +const void subghz_scene_saved_on_exit(void* context) { + // SubGhz* subghz = context; +} diff --git a/applications/subghz/scenes/subghz_scene_start.c b/applications/subghz/scenes/subghz_scene_start.c new file mode 100644 index 00000000000..88b69962107 --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_start.c @@ -0,0 +1,77 @@ +#include "../subghz_i.h" + +enum SubmenuIndex { + SubmenuIndexAnalyze, + SubmenuIndexRead, + SubmenuIndexSaved, + SubmenuIndexStatic, + SubmenuIndexTest, +}; + +void subghz_scene_start_submenu_callback(void* context, uint32_t index) { + SubGhz* subghz = context; + view_dispatcher_send_custom_event(subghz->view_dispatcher, index); +} + +const void subghz_scene_start_on_enter(void* context) { + SubGhz* subghz = context; + + submenu_add_item( + subghz->submenu, + "Analyze", + SubmenuIndexAnalyze, + subghz_scene_start_submenu_callback, + subghz); + submenu_add_item( + subghz->submenu, "Read", SubmenuIndexRead, subghz_scene_start_submenu_callback, subghz); + submenu_add_item( + subghz->submenu, "Saved", SubmenuIndexSaved, subghz_scene_start_submenu_callback, subghz); + submenu_add_item( + subghz->submenu, "Static", SubmenuIndexStatic, subghz_scene_start_submenu_callback, subghz); + submenu_add_item( + subghz->submenu, "Test", SubmenuIndexTest, subghz_scene_start_submenu_callback, subghz); + + submenu_set_selected_item( + subghz->submenu, scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneStart)); + + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewMenu); +} + +const bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexAnalyze) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneStart, SubmenuIndexAnalyze); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneAnalyze); + return true; + } else if(event.event == SubmenuIndexRead) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneStart, SubmenuIndexRead); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneRead); + return true; + } else if(event.event == SubmenuIndexSaved) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneStart, SubmenuIndexSaved); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaved); + return true; + } else if(event.event == SubmenuIndexStatic) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneStart, SubmenuIndexStatic); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneStatic); + return true; + } else if(event.event == SubmenuIndexTest) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneStart, SubmenuIndexTest); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTest); + return true; + } + } + return false; +} + +const void subghz_scene_start_on_exit(void* context) { + SubGhz* subghz = context; + submenu_clean(subghz->submenu); +} diff --git a/applications/subghz/scenes/subghz_scene_static.c b/applications/subghz/scenes/subghz_scene_static.c new file mode 100644 index 00000000000..64d593d12bc --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_static.c @@ -0,0 +1,15 @@ +#include "../subghz_i.h" + +const void subghz_scene_static_on_enter(void* context) { + SubGhz* subghz = context; + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewStatic); +} + +const bool subghz_scene_static_on_event(void* context, SceneManagerEvent event) { + // SubGhz* subghz = context; + return false; +} + +const void subghz_scene_static_on_exit(void* context) { + // SubGhz* subghz = context; +} diff --git a/applications/subghz/scenes/subghz_scene_test.c b/applications/subghz/scenes/subghz_scene_test.c new file mode 100644 index 00000000000..69b6c28e857 --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_test.c @@ -0,0 +1,53 @@ +#include "../subghz_i.h" + +enum SubmenuIndex { + SubmenuIndexCarrier, + SubmenuIndexPacket, +}; + +void subghz_scene_test_submenu_callback(void* context, uint32_t index) { + SubGhz* subghz = context; + view_dispatcher_send_custom_event(subghz->view_dispatcher, index); +} + +const void subghz_scene_test_on_enter(void* context) { + SubGhz* subghz = context; + + submenu_add_item( + subghz->submenu, + "Carrier", + SubmenuIndexCarrier, + subghz_scene_test_submenu_callback, + subghz); + submenu_add_item( + subghz->submenu, "Packet", SubmenuIndexPacket, subghz_scene_test_submenu_callback, subghz); + + submenu_set_selected_item( + subghz->submenu, scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneTest)); + + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewMenu); +} + +const bool subghz_scene_test_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexCarrier) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneTest, SubmenuIndexCarrier); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTestCarrier); + return true; + } else if(event.event == SubmenuIndexPacket) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneTest, SubmenuIndexPacket); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTestPacket); + return true; + } + } + return false; +} + +const void subghz_scene_test_on_exit(void* context) { + SubGhz* subghz = context; + submenu_clean(subghz->submenu); +} diff --git a/applications/subghz/scenes/subghz_scene_test_carrier.c b/applications/subghz/scenes/subghz_scene_test_carrier.c new file mode 100644 index 00000000000..ef1fa1fc7be --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_test_carrier.c @@ -0,0 +1,15 @@ +#include "../subghz_i.h" + +const void subghz_scene_test_carrier_on_enter(void* context) { + SubGhz* subghz = context; + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewTestCarrier); +} + +const bool subghz_scene_test_carrier_on_event(void* context, SceneManagerEvent event) { + // SubGhz* subghz = context; + return false; +} + +const void subghz_scene_test_carrier_on_exit(void* context) { + // SubGhz* subghz = context; +} diff --git a/applications/subghz/scenes/subghz_scene_test_packet.c b/applications/subghz/scenes/subghz_scene_test_packet.c new file mode 100644 index 00000000000..7c27581425e --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_test_packet.c @@ -0,0 +1,15 @@ +#include "../subghz_i.h" + +const void subghz_scene_test_packet_on_enter(void* context) { + SubGhz* subghz = context; + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewTestPacket); +} + +const bool subghz_scene_test_packet_on_event(void* context, SceneManagerEvent event) { + // SubGhz* subghz = context; + return false; +} + +const void subghz_scene_test_packet_on_exit(void* context) { + // SubGhz* subghz = context; +} diff --git a/applications/subghz/scenes/subghz_scene_transmitter.c b/applications/subghz/scenes/subghz_scene_transmitter.c new file mode 100644 index 00000000000..c2c9ce511ed --- /dev/null +++ b/applications/subghz/scenes/subghz_scene_transmitter.c @@ -0,0 +1,65 @@ +#include "../subghz_i.h" +#include "../views/subghz_transmitter.h" +#include "lib/subghz/protocols/subghz_protocol_princeton.h" + +void subghz_scene_transmitter_tx(void* context) { + SubGhz* subghz = context; + SubGhzEncoderPrinceton* encoder = subghz_encoder_princeton_alloc(); + + subghz_encoder_princeton_reset(encoder, subghz->protocol_result->code_last_found, 4); + subghz_encoder_princeton_set_te(encoder, subghz->protocol_result); + + subghz_begin(FuriHalSubGhzPresetOokAsync); + subghz_tx(433920000); + + furi_hal_subghz_start_async_tx(subghz_encoder_princeton_yield, encoder); + + while(!furi_hal_subghz_is_async_tx_complete()) { + osDelay(20); + } + + //Stop tx + furi_hal_subghz_stop_async_tx(); + subghz_end(); + subghz_encoder_princeton_free(encoder); +} + +void subghz_scene_transmitter_callback(SubghzTransmitterEvent event, void* context) { + furi_assert(context); + SubGhz* subghz = context; + view_dispatcher_send_custom_event(subghz->view_dispatcher, event); +} + +const void subghz_scene_transmitter_on_enter(void* context) { + SubGhz* subghz = context; + SubghzTransmitter* subghz_transmitter = subghz->subghz_transmitter; + + subghz_transmitter_set_callback(subghz_transmitter, subghz_scene_transmitter_callback, subghz); + + subghz_transmitter_set_protocol(subghz_transmitter, subghz->protocol_result); + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewTransmitter); +} + +const bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubghzTransmitterEventSend) { + //scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); + subghz_scene_transmitter_tx(subghz); + return true; + } else if(event.event == SubghzTransmitterEventBack) { + scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneStart); + return true; + } + } + return false; +} + +const void subghz_scene_transmitter_on_exit(void* context) { + SubGhz* subghz = context; + SubghzTransmitter* subghz_transmitter = subghz->subghz_transmitter; + + subghz_transmitter_set_callback(subghz_transmitter, NULL, subghz); +} diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c index 6190a72bcab..bf45208bf5a 100644 --- a/applications/subghz/subghz.c +++ b/applications/subghz/subghz.c @@ -23,15 +23,22 @@ const uint32_t subghz_frequencies[] = { const uint32_t subghz_frequencies_count = sizeof(subghz_frequencies) / sizeof(uint32_t); const uint32_t subghz_frequencies_433_92 = 5; -void subghz_menu_callback(void* context, uint32_t index) { +bool subghz_custom_event_callback(void* context, uint32_t event) { furi_assert(context); SubGhz* subghz = context; + return scene_manager_handle_custom_event(subghz->scene_manager, event); +} - view_dispatcher_switch_to_view(subghz->view_dispatcher, index); +bool subghz_back_event_callback(void* context) { + furi_assert(context); + SubGhz* subghz = context; + return scene_manager_handle_back_event(subghz->scene_manager); } -uint32_t subghz_exit(void* context) { - return VIEW_NONE; +void subghz_tick_event_callback(void* context) { + furi_assert(context); + SubGhz* subghz = context; + scene_manager_handle_tick_event(subghz->scene_manager); } SubGhz* subghz_alloc() { @@ -46,33 +53,62 @@ SubGhz* subghz_alloc() { view_dispatcher_attach_to_gui( subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen); - // Menu + subghz->scene_manager = scene_manager_alloc(&subghz_scene_handlers, subghz); + view_dispatcher_set_event_callback_context(subghz->view_dispatcher, subghz); + view_dispatcher_set_custom_event_callback( + subghz->view_dispatcher, subghz_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + subghz->view_dispatcher, subghz_back_event_callback); + view_dispatcher_set_tick_event_callback( + subghz->view_dispatcher, subghz_tick_event_callback, 100); + + // SubMenu subghz->submenu = submenu_alloc(); - submenu_add_item(subghz->submenu, "Capture", SubGhzViewCapture, subghz_menu_callback, subghz); - submenu_add_item( - subghz->submenu, "Basic Test", SubGhzViewTestBasic, subghz_menu_callback, subghz); - submenu_add_item( - subghz->submenu, "Packet Test", SubGhzViewTestPacket, subghz_menu_callback, subghz); - submenu_add_item( - subghz->submenu, "Static Code", SubGhzViewStatic, subghz_menu_callback, subghz); - - View* submenu_view = submenu_get_view(subghz->submenu); - view_set_previous_callback(submenu_view, subghz_exit); - view_dispatcher_add_view(subghz->view_dispatcher, SubGhzViewMenu, submenu_view); - - // Capture - subghz->subghz_capture = subghz_capture_alloc(); + view_dispatcher_add_view( + subghz->view_dispatcher, SubGhzViewMenu, submenu_get_view(subghz->submenu)); + + // Analyze + subghz->subghz_analyze = subghz_analyze_alloc(); + view_dispatcher_add_view( + subghz->view_dispatcher, + SubGhzViewAnalyze, + subghz_analyze_get_view(subghz->subghz_analyze)); + + // Receiver + subghz->subghz_receiver = subghz_receiver_alloc(); view_dispatcher_add_view( subghz->view_dispatcher, - SubGhzViewCapture, - subghz_capture_get_view(subghz->subghz_capture)); + SubGhzViewReceiver, + subghz_receiver_get_view(subghz->subghz_receiver)); - // Basic Test Module - subghz->subghz_test_basic = subghz_test_basic_alloc(); + // Dialog + subghz->dialog_ex = dialog_ex_alloc(); + view_dispatcher_add_view( + subghz->view_dispatcher, SubGhzViewDialogEx, dialog_ex_get_view(subghz->dialog_ex)); + + // Popup + subghz->popup = popup_alloc(); + view_dispatcher_add_view( + subghz->view_dispatcher, SubGhzViewPopup, popup_get_view(subghz->popup)); + + // Text Input + subghz->text_input = text_input_alloc(); + view_dispatcher_add_view( + subghz->view_dispatcher, SubGhzViewTextInput, text_input_get_view(subghz->text_input)); + + // Transmitter + subghz->subghz_transmitter = subghz_transmitter_alloc(); view_dispatcher_add_view( subghz->view_dispatcher, - SubGhzViewTestBasic, - subghz_test_basic_get_view(subghz->subghz_test_basic)); + SubGhzViewTransmitter, + subghz_transmitter_get_view(subghz->subghz_transmitter)); + + // Carrier Test Module + subghz->subghz_test_carrier = subghz_test_carrier_alloc(); + view_dispatcher_add_view( + subghz->view_dispatcher, + SubGhzViewTestCarrier, + subghz_test_carrier_get_view(subghz->subghz_test_carrier)); // Packet Test subghz->subghz_test_packet = subghz_test_packet_alloc(); @@ -86,8 +122,19 @@ SubGhz* subghz_alloc() { view_dispatcher_add_view( subghz->view_dispatcher, SubGhzViewStatic, subghz_static_get_view(subghz->subghz_static)); - // Switch to menu - view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewMenu); + //init Worker & Protocol + subghz->worker = subghz_worker_alloc(); + subghz->protocol = subghz_protocol_alloc(); + subghz_worker_set_overrun_callback( + subghz->worker, (SubGhzWorkerOverrunCallback)subghz_protocol_reset); + subghz_worker_set_pair_callback( + subghz->worker, (SubGhzWorkerPairCallback)subghz_protocol_parse); + subghz_worker_set_context(subghz->worker, subghz->protocol); + + subghz_protocol_load_keeloq_file(subghz->protocol, "/ext/assets/subghz/keeloq_mfcodes"); + subghz_protocol_load_nice_flor_s_file(subghz->protocol, "/ext/assets/subghz/nice_floor_s_rx"); + + //subghz_protocol_enable_dump_text(subghz->protocol, subghz_text_callback, subghz); return subghz; } @@ -96,24 +143,47 @@ void subghz_free(SubGhz* subghz) { furi_assert(subghz); // Packet Test + view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewTestPacket); + subghz_test_packet_free(subghz->subghz_test_packet); + + // Carrier Test + view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewTestCarrier); + subghz_test_carrier_free(subghz->subghz_test_carrier); + + // Static view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewStatic); subghz_static_free(subghz->subghz_static); - // Packet Test - view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewTestPacket); - subghz_test_packet_free(subghz->subghz_test_packet); + // Analyze + view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewAnalyze); + subghz_analyze_free(subghz->subghz_analyze); + + // Receiver + view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewReceiver); + subghz_receiver_free(subghz->subghz_receiver); + + // TextInput + view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewTextInput); + text_input_free(subghz->text_input); - // Basic Test - view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewTestBasic); - subghz_test_basic_free(subghz->subghz_test_basic); + // Receiver + view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewTransmitter); + subghz_transmitter_free(subghz->subghz_transmitter); // Submenu view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewMenu); submenu_free(subghz->submenu); - // Capture - view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewCapture); - subghz_capture_free(subghz->subghz_capture); + // DialogEx + view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewDialogEx); + dialog_ex_free(subghz->dialog_ex); + + // Popup + view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewPopup); + popup_free(subghz->popup); + + // Scene manager + scene_manager_free(subghz->scene_manager); // View Dispatcher view_dispatcher_free(subghz->view_dispatcher); @@ -122,13 +192,24 @@ void subghz_free(SubGhz* subghz) { furi_record_close("gui"); subghz->gui = NULL; + //Worker & Protocol + subghz_protocol_free(subghz->protocol); + subghz_worker_free(subghz->worker); + // The rest free(subghz); } -int32_t subghz_app(void* context) { +int32_t subghz_app(void* p) { SubGhz* subghz = subghz_alloc(); + // Check argument and run corresponding scene + if(p && subghz_key_load(subghz, p)) { + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter); + } else { + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneStart); + } + view_dispatcher_run(subghz->view_dispatcher); subghz_free(subghz); diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index a6f4f5f3a9b..9681fdef3c2 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -1,9 +1,10 @@ #include "subghz_cli.h" #include -#include +#include #include #include +#include #define SUBGHZ_FREQUENCY_RANGE_STR \ "299999755...348000000 or 386999938...464000000 or 778999847...928000000" @@ -31,7 +32,7 @@ void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { cli_print_usage("subghz_tx_carrier", "", string_get_cstr(args)); return; } - if(!api_hal_subghz_is_frequency_valid(frequency)) { + if(!furi_hal_subghz_is_frequency_valid(frequency)) { printf( "Frequency must be in " SUBGHZ_FREQUENCY_RANGE_STR " range, not %lu\r\n", frequency); @@ -39,14 +40,14 @@ void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { } } - api_hal_subghz_reset(); - api_hal_subghz_load_preset(ApiHalSubGhzPresetOokAsync); - frequency = api_hal_subghz_set_frequency_and_path(frequency); + furi_hal_subghz_reset(); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync); + frequency = furi_hal_subghz_set_frequency_and_path(frequency); hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); hal_gpio_write(&gpio_cc1101_g0, true); - api_hal_subghz_tx(); + furi_hal_subghz_tx(); printf("Transmitting at frequency %lu Hz\r\n", frequency); printf("Press CTRL+C to stop\r\n"); @@ -54,8 +55,8 @@ void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { osDelay(250); } - api_hal_subghz_set_path(ApiHalSubGhzPathIsolate); - api_hal_subghz_sleep(); + furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); + furi_hal_subghz_sleep(); } void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { @@ -68,7 +69,7 @@ void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { cli_print_usage("subghz_tx_carrier", "", string_get_cstr(args)); return; } - if(!api_hal_subghz_is_frequency_valid(frequency)) { + if(!furi_hal_subghz_is_frequency_valid(frequency)) { printf( "Frequency must be in " SUBGHZ_FREQUENCY_RANGE_STR " range, not %lu\r\n", frequency); @@ -76,32 +77,28 @@ void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { } } - api_hal_subghz_reset(); - api_hal_subghz_load_preset(ApiHalSubGhzPresetOokAsync); - frequency = api_hal_subghz_set_frequency_and_path(frequency); + furi_hal_subghz_reset(); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync); + frequency = furi_hal_subghz_set_frequency_and_path(frequency); printf("Receiving at frequency %lu Hz\r\n", frequency); printf("Press CTRL+C to stop\r\n"); - api_hal_subghz_rx(); + furi_hal_subghz_rx(); while(!cli_cmd_interrupt_received(cli)) { osDelay(250); - printf("RSSI: %03.1fdbm\r", api_hal_subghz_get_rssi()); + printf("RSSI: %03.1fdbm\r", furi_hal_subghz_get_rssi()); fflush(stdout); } - api_hal_subghz_set_path(ApiHalSubGhzPathIsolate); - api_hal_subghz_sleep(); + furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); + furi_hal_subghz_sleep(); } -#define SUBGHZ_PT_SHORT 376 -#define SUBGHZ_PT_LONG (SUBGHZ_PT_SHORT * 3) -#define SUBGHZ_PT_GUARD 10600 - void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { uint32_t frequency = 433920000; - size_t repeat = 10; uint32_t key = 0x0074BADE; + size_t repeat = 10; if(string_size(args)) { int ret = sscanf(string_get_cstr(args), "%lx %lu %u", &key, &frequency, &repeat); @@ -118,7 +115,7 @@ void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { string_get_cstr(args)); return; } - if(!api_hal_subghz_is_frequency_valid(frequency)) { + if(!furi_hal_subghz_is_frequency_valid(frequency)) { printf( "Frequency must be in " SUBGHZ_FREQUENCY_RANGE_STR " range, not %lu\r\n", frequency); @@ -126,41 +123,31 @@ void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { } } - size_t subghz_test_data_size = 25 * 2 * sizeof(uint32_t); - uint32_t* subghz_test_data = furi_alloc(subghz_test_data_size); - - size_t pos = 0; - for(uint8_t i = 0; i < 24; i++) { - uint8_t byte = i / 8; - uint8_t bit = i % 8; - bool value = (((uint8_t*)&key)[2 - byte] >> (7 - bit)) & 1; - if(value) { - subghz_test_data[pos++] = SUBGHZ_PT_SHORT; - subghz_test_data[pos++] = SUBGHZ_PT_LONG; - } else { - subghz_test_data[pos++] = SUBGHZ_PT_LONG; - subghz_test_data[pos++] = SUBGHZ_PT_SHORT; - } - } - subghz_test_data[pos++] = SUBGHZ_PT_SHORT; - subghz_test_data[pos++] = SUBGHZ_PT_SHORT + SUBGHZ_PT_GUARD; - printf( "Transmitting at %lu, key %lx, repeat %u. Press CTRL+C to stop\r\n", frequency, key, repeat); - api_hal_subghz_reset(); - api_hal_subghz_load_preset(ApiHalSubGhzPresetOokAsync); - frequency = api_hal_subghz_set_frequency_and_path(frequency); + SubGhzEncoderPrinceton* encoder = subghz_encoder_princeton_alloc(); + subghz_encoder_princeton_reset(encoder, key, repeat); + + furi_hal_subghz_reset(); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync); + frequency = furi_hal_subghz_set_frequency_and_path(frequency); + + furi_hal_subghz_start_async_tx(subghz_encoder_princeton_yield, encoder); + + while(!furi_hal_subghz_is_async_tx_complete()) { + printf("."); + fflush(stdout); + osDelay(333); + } - api_hal_subghz_start_async_tx(subghz_test_data, subghz_test_data_size, repeat); - api_hal_subghz_wait_async_tx(); - api_hal_subghz_stop_async_tx(); + furi_hal_subghz_stop_async_tx(); - free(subghz_test_data); - api_hal_subghz_sleep(); + furi_hal_subghz_sleep(); + subghz_encoder_princeton_free(encoder); } typedef struct { @@ -200,7 +187,7 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { cli_print_usage("subghz_rx", "", string_get_cstr(args)); return; } - if(!api_hal_subghz_is_frequency_valid(frequency)) { + if(!furi_hal_subghz_is_frequency_valid(frequency)) { printf( "Frequency must be in " SUBGHZ_FREQUENCY_RANGE_STR " range, not %lu\r\n", frequency); @@ -219,14 +206,13 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { subghz_protocol_enable_dump_text(protocol, subghz_cli_command_rx_text_callback, instance); // Configure radio - api_hal_subghz_reset(); - api_hal_subghz_load_preset(ApiHalSubGhzPresetOokAsync); - frequency = api_hal_subghz_set_frequency_and_path(frequency); + furi_hal_subghz_reset(); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync); + frequency = furi_hal_subghz_set_frequency_and_path(frequency); hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); // Prepare and start RX - api_hal_subghz_set_async_rx_callback(subghz_cli_command_rx_callback, instance); - api_hal_subghz_start_async_rx(); + furi_hal_subghz_start_async_rx(subghz_cli_command_rx_callback, instance); // Wait for packets to arrive printf("Listening at %lu. Press CTRL+C to stop\r\n", frequency); @@ -247,8 +233,8 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { } // Shutdown radio - api_hal_subghz_stop_async_rx(); - api_hal_subghz_sleep(); + furi_hal_subghz_stop_async_rx(); + furi_hal_subghz_sleep(); printf("\r\nPackets recieved %u\r\n", instance->packet_count); diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c new file mode 100644 index 00000000000..359b2651d49 --- /dev/null +++ b/applications/subghz/subghz_i.c @@ -0,0 +1,83 @@ +#include "subghz_i.h" + +#include +#include +#include +#include +#include +#include +#include "file-worker.h" + +void subghz_begin(FuriHalSubGhzPreset preset) { + furi_hal_subghz_reset(); + furi_hal_subghz_idle(); + furi_hal_subghz_load_preset(preset); + hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); +} + +void subghz_rx(uint32_t frequency) { + furi_hal_subghz_idle(); + furi_hal_subghz_set_frequency_and_path(frequency); + hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + furi_hal_subghz_flush_rx(); + furi_hal_subghz_rx(); +} + +void subghz_tx(uint32_t frequency) { + furi_hal_subghz_idle(); + furi_hal_subghz_set_frequency_and_path(frequency); + hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + hal_gpio_write(&gpio_cc1101_g0, true); + furi_hal_subghz_tx(); +} + +void subghz_idle(void) { + furi_hal_subghz_idle(); +} + +void subghz_end(void) { + furi_hal_subghz_sleep(); +} + +bool subghz_key_load(SubGhz* subghz, const char* file_path) { + furi_assert(subghz); + furi_assert(file_path); + + FileWorker* file_worker = file_worker_alloc(false); + // Load device data + bool loaded = false; + string_t path; + string_init_set_str(path, file_path); + string_t temp_str; + string_init(temp_str); + + do { + if(!file_worker_open(file_worker, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + break; + } + // Read and parse name protocol from 1st line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + // strlen("Protocol: ") = 10 + string_right(temp_str, 10); + subghz->protocol_result = + subghz_protocol_get_by_name(subghz->protocol, string_get_cstr(temp_str)); + if(subghz->protocol_result == NULL) { + file_worker_show_error(file_worker, "Cannot parse\nfile"); + break; + } + if(!subghz->protocol_result->to_load_protocol(file_worker, subghz->protocol_result)) { + file_worker_show_error(file_worker, "Cannot parse\nfile"); + break; + } + loaded = true; + } while(0); + + string_clear(temp_str); + string_clear(path); + file_worker_close(file_worker); + file_worker_free(file_worker); + + return loaded; +} diff --git a/applications/subghz/subghz_i.h b/applications/subghz/subghz_i.h index ccf41b714a0..a7a86a8ca7a 100644 --- a/applications/subghz/subghz_i.h +++ b/applications/subghz/subghz_i.h @@ -1,16 +1,31 @@ #pragma once #include "subghz.h" -#include "views/subghz_capture.h" -#include "views/subghz_test_basic.h" -#include "views/subghz_test_packet.h" +#include "views/subghz_analyze.h" +#include "views/subghz_receiver.h" +#include "views/subghz_transmitter.h" #include "views/subghz_static.h" +#include "views/subghz_test_carrier.h" +#include "views/subghz_test_packet.h" + #include -#include +#include #include +#include #include #include +#include +#include +#include + +#include + +#include +#include +#include + +#define SUBGHZ_TEXT_STORE_SIZE 128 extern const uint32_t subghz_frequencies[]; extern const uint32_t subghz_frequencies_count; @@ -19,23 +34,47 @@ extern const uint32_t subghz_frequencies_433_92; struct SubGhz { Gui* gui; + SubGhzWorker* worker; + SubGhzProtocol* protocol; + SubGhzProtocolCommon* protocol_result; + + SceneManager* scene_manager; + ViewDispatcher* view_dispatcher; Submenu* submenu; + DialogEx* dialog_ex; + Popup* popup; + TextInput* text_input; + char text_store[SUBGHZ_TEXT_STORE_SIZE + 1]; - SubghzCapture* subghz_capture; - - SubghzTestBasic* subghz_test_basic; + SubghzAnalyze* subghz_analyze; + SubghzReceiver* subghz_receiver; + SubghzTransmitter* subghz_transmitter; + SubghzStatic* subghz_static; + SubghzTestCarrier* subghz_test_carrier; SubghzTestPacket* subghz_test_packet; - - SubghzStatic* subghz_static; }; typedef enum { SubGhzViewMenu, - SubGhzViewCapture, - SubGhzViewTestBasic, - SubGhzViewTestPacket, + + SubGhzViewAnalyze, + SubGhzViewDialogEx, + SubGhzViewReceiver, + SubGhzViewPopup, + SubGhzViewTextInput, + SubGhzViewTransmitter, + SubGhzViewStatic, + SubGhzViewTestCarrier, + SubGhzViewTestPacket, } SubGhzView; + +void subghz_begin(FuriHalSubGhzPreset preset); +void subghz_rx(uint32_t frequency); +void subghz_tx(uint32_t frequency); +void subghz_idle(void); +void subghz_end(void); +bool subghz_key_load(SubGhz* subghz, const char* file_path); \ No newline at end of file diff --git a/applications/subghz/views/subghz_analyze.c b/applications/subghz/views/subghz_analyze.c new file mode 100644 index 00000000000..7380a026690 --- /dev/null +++ b/applications/subghz/views/subghz_analyze.c @@ -0,0 +1,233 @@ +#include "subghz_analyze.h" +#include "../subghz_i.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +struct SubghzAnalyze { + View* view; + SubGhzWorker* worker; + SubGhzProtocol* protocol; +}; + +typedef struct { + uint8_t frequency; + uint32_t real_frequency; + uint32_t counter; + string_t text; + uint16_t scene; + SubGhzProtocolCommon parser; +} SubghzAnalyzeModel; + +static const char subghz_symbols[] = {'-', '\\', '|', '/'}; + +void subghz_analyze_draw(Canvas* canvas, SubghzAnalyzeModel* model) { + char buffer[64]; + + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontPrimary); + + snprintf( + buffer, + sizeof(buffer), + "Analyze: %03ld.%03ldMHz %c", + model->real_frequency / 1000000 % 1000, + model->real_frequency / 1000 % 1000, + subghz_symbols[model->counter % 4]); + canvas_draw_str(canvas, 0, 8, buffer); + + switch(model->scene) { + case 1: + canvas_draw_icon(canvas, 0, 10, &I_RFIDDolphinReceive_97x61); + canvas_invert_color(canvas); + canvas_draw_box(canvas, 80, 12, 20, 20); + canvas_invert_color(canvas); + canvas_draw_icon(canvas, 75, 18, &I_sub1_10px); + elements_multiline_text_aligned( + canvas, 90, 38, AlignCenter, AlignTop, "Detecting\r\nSubGhz"); + break; + + default: + canvas_set_font(canvas, FontSecondary); + elements_multiline_text(canvas, 0, 20, string_get_cstr(model->text)); + break; + } +} + +bool subghz_analyze_input(InputEvent* event, void* context) { + furi_assert(context); + SubghzAnalyze* subghz_analyze = context; + + if(event->type != InputTypeShort) return false; + + if(event->key == InputKeyBack) { + return false; + } + + with_view_model( + subghz_analyze->view, (SubghzAnalyzeModel * model) { + bool model_updated = false; + + if(event->key == InputKeyLeft) { + if(model->frequency > 0) model->frequency--; + model_updated = true; + } else if(event->key == InputKeyRight) { + if(model->frequency < subghz_frequencies_count - 1) model->frequency++; + model_updated = true; + } + + if(model_updated) { + furi_hal_subghz_idle(); + model->real_frequency = + furi_hal_subghz_set_frequency_and_path(subghz_frequencies[model->frequency]); + furi_hal_subghz_rx(); + } + + return model_updated; + }); + + return true; +} + +void subghz_analyze_text_callback(string_t text, void* context) { + furi_assert(context); + SubghzAnalyze* subghz_analyze = context; + + with_view_model( + subghz_analyze->view, (SubghzAnalyzeModel * model) { + model->counter++; + string_set(model->text, text); + model->scene = 0; + return true; + }); +} + +void subghz_analyze_protocol_callback(SubGhzProtocolCommon* parser, void* context) { + furi_assert(context); + SubghzAnalyze* subghz_analyze = context; + char buffer[64]; + snprintf( + buffer, + sizeof(buffer), + "%s\r\n" + "K:%lX%lX\r\n" + "SN:%lX\r\n" + "BTN:%X", + parser->name, + (uint32_t)(parser->code_found >> 32), + (uint32_t)(parser->code_found & 0x00000000FFFFFFFF), + parser->serial, + parser->btn); + + with_view_model( + subghz_analyze->view, (SubghzAnalyzeModel * model) { + model->counter++; + model->parser = *parser; + string_set(model->text, buffer); + model->scene = 0; + return true; + }); +} + +void subghz_analyze_enter(void* context) { + furi_assert(context); + SubghzAnalyze* subghz_analyze = context; + + furi_hal_subghz_reset(); + furi_hal_subghz_idle(); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync); + + with_view_model( + subghz_analyze->view, (SubghzAnalyzeModel * model) { + model->frequency = subghz_frequencies_433_92; + model->real_frequency = + furi_hal_subghz_set_frequency_and_path(subghz_frequencies[model->frequency]); + model->scene = 1; + return true; + }); + + hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + + furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, subghz_analyze->worker); + + subghz_worker_start(subghz_analyze->worker); + + furi_hal_subghz_flush_rx(); + furi_hal_subghz_rx(); +} + +void subghz_analyze_exit(void* context) { + furi_assert(context); + SubghzAnalyze* subghz_analyze = context; + + subghz_worker_stop(subghz_analyze->worker); + + furi_hal_subghz_stop_async_rx(); + furi_hal_subghz_sleep(); +} + +SubghzAnalyze* subghz_analyze_alloc() { + SubghzAnalyze* subghz_analyze = furi_alloc(sizeof(SubghzAnalyze)); + + // View allocation and configuration + subghz_analyze->view = view_alloc(); + view_allocate_model(subghz_analyze->view, ViewModelTypeLocking, sizeof(SubghzAnalyzeModel)); + view_set_context(subghz_analyze->view, subghz_analyze); + view_set_draw_callback(subghz_analyze->view, (ViewDrawCallback)subghz_analyze_draw); + view_set_input_callback(subghz_analyze->view, subghz_analyze_input); + view_set_enter_callback(subghz_analyze->view, subghz_analyze_enter); + view_set_exit_callback(subghz_analyze->view, subghz_analyze_exit); + + with_view_model( + subghz_analyze->view, (SubghzAnalyzeModel * model) { + string_init(model->text); + return true; + }); + + subghz_analyze->worker = subghz_worker_alloc(); + subghz_analyze->protocol = subghz_protocol_alloc(); + + subghz_worker_set_overrun_callback( + subghz_analyze->worker, (SubGhzWorkerOverrunCallback)subghz_protocol_reset); + subghz_worker_set_pair_callback( + subghz_analyze->worker, (SubGhzWorkerPairCallback)subghz_protocol_parse); + subghz_worker_set_context(subghz_analyze->worker, subghz_analyze->protocol); + + subghz_protocol_load_keeloq_file( + subghz_analyze->protocol, "/ext/assets/subghz/keeloq_mfcodes"); + subghz_protocol_load_nice_flor_s_file( + subghz_analyze->protocol, "/ext/assets/subghz/nice_floor_s_rx"); + subghz_protocol_enable_dump_text( + subghz_analyze->protocol, subghz_analyze_text_callback, subghz_analyze); + + return subghz_analyze; +} + +void subghz_analyze_free(SubghzAnalyze* subghz_analyze) { + furi_assert(subghz_analyze); + + subghz_protocol_free(subghz_analyze->protocol); + subghz_worker_free(subghz_analyze->worker); + + with_view_model( + subghz_analyze->view, (SubghzAnalyzeModel * model) { + string_clear(model->text); + return true; + }); + view_free(subghz_analyze->view); + free(subghz_analyze); +} + +View* subghz_analyze_get_view(SubghzAnalyze* subghz_analyze) { + furi_assert(subghz_analyze); + return subghz_analyze->view; +} diff --git a/applications/subghz/views/subghz_analyze.h b/applications/subghz/views/subghz_analyze.h new file mode 100644 index 00000000000..b1a553e6b27 --- /dev/null +++ b/applications/subghz/views/subghz_analyze.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +typedef struct SubghzAnalyze SubghzAnalyze; + +SubghzAnalyze* subghz_analyze_alloc(); + +void subghz_analyze_free(SubghzAnalyze* subghz_analyze); + +View* subghz_analyze_get_view(SubghzAnalyze* subghz_analyze); diff --git a/applications/subghz/views/subghz_capture.c b/applications/subghz/views/subghz_capture.c deleted file mode 100644 index 4df825b9981..00000000000 --- a/applications/subghz/views/subghz_capture.c +++ /dev/null @@ -1,238 +0,0 @@ -#include "subghz_capture.h" -#include "../subghz_i.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -struct SubghzCapture { - View* view; - SubGhzWorker* worker; - SubGhzProtocol* protocol; -}; - -typedef struct { - uint8_t frequency; - uint32_t real_frequency; - uint32_t counter; - string_t text; - uint16_t scene; - SubGhzProtocolCommon parser; -} SubghzCaptureModel; - -static const char subghz_symbols[] = {'-', '\\', '|', '/'}; - -void subghz_capture_draw(Canvas* canvas, SubghzCaptureModel* model) { - char buffer[64]; - - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontPrimary); - - snprintf( - buffer, - sizeof(buffer), - "Capture: %03ld.%03ldMHz %c", - model->real_frequency / 1000000 % 1000, - model->real_frequency / 1000 % 1000, - subghz_symbols[model->counter % 4]); - canvas_draw_str(canvas, 0, 8, buffer); - - switch(model->scene) { - case 1: - canvas_draw_icon(canvas, 0, 10, &I_RFIDDolphinReceive_97x61); - canvas_invert_color(canvas); - canvas_draw_box(canvas, 80, 12, 20, 20); - canvas_invert_color(canvas); - canvas_draw_icon(canvas, 75, 18, &I_sub1_10px); - elements_multiline_text_aligned( - canvas, 90, 38, AlignCenter, AlignTop, "Detecting\r\nSubGhz"); - break; - - default: - canvas_set_font(canvas, FontSecondary); - elements_multiline_text(canvas, 0, 20, string_get_cstr(model->text)); - break; - } -} - -bool subghz_capture_input(InputEvent* event, void* context) { - furi_assert(context); - SubghzCapture* subghz_capture = context; - - if(event->key == InputKeyBack) { - return false; - } - - with_view_model( - subghz_capture->view, (SubghzCaptureModel * model) { - bool reconfigure = false; - if(event->type == InputTypeShort) { - if(event->key == InputKeyLeft) { - if(model->frequency > 0) model->frequency--; - reconfigure = true; - } else if(event->key == InputKeyRight) { - if(model->frequency < subghz_frequencies_count - 1) model->frequency++; - reconfigure = true; - } - } - - if(reconfigure) { - api_hal_subghz_idle(); - model->real_frequency = - api_hal_subghz_set_frequency_and_path(subghz_frequencies[model->frequency]); - api_hal_subghz_rx(); - } - - return reconfigure; - }); - - return true; -} - -void subghz_capture_text_callback(string_t text, void* context) { - furi_assert(context); - SubghzCapture* subghz_capture = context; - - with_view_model( - subghz_capture->view, (SubghzCaptureModel * model) { - model->counter++; - string_set(model->text, text); - model->scene = 0; - return true; - }); -} - -void subghz_capture_protocol_callback(SubGhzProtocolCommon* parser, void* context) { - furi_assert(context); - SubghzCapture* subghz_capture = context; - char buffer[64]; - snprintf( - buffer, - sizeof(buffer), - "%s\r\n" - "K:%lX%lX\r\n" - "SN:%lX\r\n" - "BTN:%X", - parser->name, - (uint32_t)(parser->code_found >> 32), - (uint32_t)(parser->code_found & 0x00000000FFFFFFFF), - parser->serial, - parser->btn); - - with_view_model( - subghz_capture->view, (SubghzCaptureModel * model) { - model->counter++; - model->parser = *parser; - string_set(model->text, buffer); - model->scene = 0; - return true; - }); -} - -void subghz_capture_enter(void* context) { - furi_assert(context); - SubghzCapture* subghz_capture = context; - - api_hal_subghz_reset(); - api_hal_subghz_idle(); - api_hal_subghz_load_preset(ApiHalSubGhzPresetOokAsync); - - with_view_model( - subghz_capture->view, (SubghzCaptureModel * model) { - model->frequency = subghz_frequencies_433_92; - model->real_frequency = - api_hal_subghz_set_frequency_and_path(subghz_frequencies[model->frequency]); - model->scene = 1; - return true; - }); - - hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); - - api_hal_subghz_set_async_rx_callback(subghz_worker_rx_callback, subghz_capture->worker); - api_hal_subghz_start_async_rx(); - - subghz_worker_start(subghz_capture->worker); - - api_hal_subghz_flush_rx(); - api_hal_subghz_rx(); -} - -void subghz_capture_exit(void* context) { - furi_assert(context); - SubghzCapture* subghz_capture = context; - - subghz_worker_stop(subghz_capture->worker); - - api_hal_subghz_stop_async_rx(); - api_hal_subghz_sleep(); -} - -uint32_t subghz_capture_back(void* context) { - return SubGhzViewMenu; -} - -SubghzCapture* subghz_capture_alloc() { - SubghzCapture* subghz_capture = furi_alloc(sizeof(SubghzCapture)); - - // View allocation and configuration - subghz_capture->view = view_alloc(); - view_allocate_model(subghz_capture->view, ViewModelTypeLocking, sizeof(SubghzCaptureModel)); - view_set_context(subghz_capture->view, subghz_capture); - view_set_draw_callback(subghz_capture->view, (ViewDrawCallback)subghz_capture_draw); - view_set_input_callback(subghz_capture->view, subghz_capture_input); - view_set_enter_callback(subghz_capture->view, subghz_capture_enter); - view_set_exit_callback(subghz_capture->view, subghz_capture_exit); - view_set_previous_callback(subghz_capture->view, subghz_capture_back); - - with_view_model( - subghz_capture->view, (SubghzCaptureModel * model) { - string_init(model->text); - return true; - }); - - subghz_capture->worker = subghz_worker_alloc(); - subghz_capture->protocol = subghz_protocol_alloc(); - - subghz_worker_set_overrun_callback( - subghz_capture->worker, (SubGhzWorkerOverrunCallback)subghz_protocol_reset); - subghz_worker_set_pair_callback( - subghz_capture->worker, (SubGhzWorkerPairCallback)subghz_protocol_parse); - subghz_worker_set_context(subghz_capture->worker, subghz_capture->protocol); - - subghz_protocol_load_keeloq_file( - subghz_capture->protocol, "/ext/assets/subghz/keeloq_mfcodes"); - subghz_protocol_load_nice_flor_s_file( - subghz_capture->protocol, "/ext/assets/subghz/nice_floor_s_rx"); - subghz_protocol_enable_dump_text( - subghz_capture->protocol, subghz_capture_text_callback, subghz_capture); - - return subghz_capture; -} - -void subghz_capture_free(SubghzCapture* subghz_capture) { - furi_assert(subghz_capture); - - subghz_protocol_free(subghz_capture->protocol); - subghz_worker_free(subghz_capture->worker); - - with_view_model( - subghz_capture->view, (SubghzCaptureModel * model) { - string_clear(model->text); - return true; - }); - view_free(subghz_capture->view); - free(subghz_capture); -} - -View* subghz_capture_get_view(SubghzCapture* subghz_capture) { - furi_assert(subghz_capture); - return subghz_capture->view; -} diff --git a/applications/subghz/views/subghz_capture.h b/applications/subghz/views/subghz_capture.h deleted file mode 100644 index 84159cf5f05..00000000000 --- a/applications/subghz/views/subghz_capture.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -typedef struct SubghzCapture SubghzCapture; - -SubghzCapture* subghz_capture_alloc(); - -void subghz_capture_free(SubghzCapture* subghz_capture); - -View* subghz_capture_get_view(SubghzCapture* subghz_capture); diff --git a/applications/subghz/views/subghz_receiver.c b/applications/subghz/views/subghz_receiver.c new file mode 100644 index 00000000000..11b030d1f14 --- /dev/null +++ b/applications/subghz/views/subghz_receiver.c @@ -0,0 +1,146 @@ +#include "subghz_receiver.h" +#include "../subghz_i.h" + +#include +#include +#include +#include +#include +#include + +#include + +struct SubghzReceiver { + View* view; + SubghzReceiverCallback callback; + void* context; +}; + +typedef struct { + string_t text; + uint16_t scene; + SubGhzProtocolCommon* protocol; +} SubghzReceiverModel; + +void subghz_receiver_set_callback( + SubghzReceiver* subghz_receiver, + SubghzReceiverCallback callback, + void* context) { + furi_assert(subghz_receiver); + furi_assert(callback); + subghz_receiver->callback = callback; + subghz_receiver->context = context; +} + +void subghz_receiver_set_protocol(SubghzReceiver* subghz_receiver, SubGhzProtocolCommon* protocol) { + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + model->protocol = protocol; + return true; + }); +} + +void subghz_receiver_draw(Canvas* canvas, SubghzReceiverModel* model) { + canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontSecondary); + elements_multiline_text(canvas, 0, 10, string_get_cstr(model->text)); + + elements_button_left(canvas, "Back"); + if(model->protocol && model->protocol->to_save_string) { + elements_button_right(canvas, "Save"); + } +} + +bool subghz_receiver_input(InputEvent* event, void* context) { + furi_assert(context); + SubghzReceiver* subghz_receiver = context; + + if(event->type != InputTypeShort) return false; + + bool can_be_saved = false; + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + can_be_saved = (model->protocol && model->protocol->to_save_string); + return false; + }); + + if(event->key == InputKeyBack) { + return false; + } else if(event->key == InputKeyLeft) { + subghz_receiver->callback(SubghzReceverEventBack, subghz_receiver->context); + } else if(can_be_saved && event->key == InputKeyRight) { + subghz_receiver->callback(SubghzReceverEventSave, subghz_receiver->context); + } + + return true; +} + +void subghz_receiver_text_callback(string_t text, void* context) { + furi_assert(context); + SubghzReceiver* subghz_receiver = context; + + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + string_set(model->text, text); + model->scene = 0; + return true; + }); +} + +void subghz_receiver_enter(void* context) { + furi_assert(context); + SubghzReceiver* subghz_receiver = context; + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + model->protocol->to_string(model->protocol, model->text); + return true; + }); +} + +void subghz_receiver_exit(void* context) { + furi_assert(context); + SubghzReceiver* subghz_receiver = context; + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + string_clean(model->text); + return true; + }); +} + +SubghzReceiver* subghz_receiver_alloc() { + SubghzReceiver* subghz_receiver = furi_alloc(sizeof(SubghzReceiver)); + + // View allocation and configuration + subghz_receiver->view = view_alloc(); + view_allocate_model(subghz_receiver->view, ViewModelTypeLocking, sizeof(SubghzReceiverModel)); + view_set_context(subghz_receiver->view, subghz_receiver); + view_set_draw_callback(subghz_receiver->view, (ViewDrawCallback)subghz_receiver_draw); + view_set_input_callback(subghz_receiver->view, subghz_receiver_input); + view_set_enter_callback(subghz_receiver->view, subghz_receiver_enter); + view_set_exit_callback(subghz_receiver->view, subghz_receiver_exit); + + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + string_init(model->text); + return true; + }); + return subghz_receiver; +} + +void subghz_receiver_free(SubghzReceiver* subghz_receiver) { + furi_assert(subghz_receiver); + + with_view_model( + subghz_receiver->view, (SubghzReceiverModel * model) { + string_clear(model->text); + return true; + }); + view_free(subghz_receiver->view); + free(subghz_receiver); +} + +View* subghz_receiver_get_view(SubghzReceiver* subghz_receiver) { + furi_assert(subghz_receiver); + return subghz_receiver->view; +} diff --git a/applications/subghz/views/subghz_receiver.h b/applications/subghz/views/subghz_receiver.h new file mode 100644 index 00000000000..924f90b8a1a --- /dev/null +++ b/applications/subghz/views/subghz_receiver.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +typedef enum { + SubghzReceverEventSave, + SubghzReceverEventBack, +} SubghzReceverEvent; + +typedef struct SubghzReceiver SubghzReceiver; + +typedef void (*SubghzReceiverCallback)(SubghzReceverEvent event, void* context); + +void subghz_receiver_set_callback( + SubghzReceiver* subghz_receiver, + SubghzReceiverCallback callback, + void* context); + +SubghzReceiver* subghz_receiver_alloc(); + +void subghz_receiver_free(SubghzReceiver* subghz_receiver); + +View* subghz_receiver_get_view(SubghzReceiver* subghz_receiver); + +void subghz_receiver_set_protocol(SubghzReceiver* subghz_receiver, SubGhzProtocolCommon* protocol); diff --git a/applications/subghz/views/subghz_static.c b/applications/subghz/views/subghz_static.c index ad86d4583ae..52bf0ae676f 100644 --- a/applications/subghz/views/subghz_static.c +++ b/applications/subghz/views/subghz_static.c @@ -3,23 +3,21 @@ #include #include -#include +#include #include #include +#include -static const uint8_t subghz_static_keys[][4] = { - {0x74, 0xBA, 0xDE}, - {0x74, 0xBA, 0xDD}, - {0x74, 0xBA, 0xDB}, - {0xE3, 0x4A, 0x4E}, +static const uint32_t subghz_static_keys[] = { + 0x0074BADE, + 0x0074BADD, + 0x0074BADB, + 0x00E34A4E, }; -#define SUBGHZ_PT_SHORT 376 -#define SUBGHZ_PT_LONG (SUBGHZ_PT_SHORT * 3) -#define SUBGHZ_PT_GUARD 10600 - struct SubghzStatic { View* view; + SubGhzEncoderPrinceton* encoder; }; typedef enum { @@ -56,14 +54,14 @@ void subghz_static_draw(Canvas* canvas, SubghzStaticModel* model) { bool subghz_static_input(InputEvent* event, void* context) { furi_assert(context); - SubghzStatic* subghz_static = context; + SubghzStatic* instance = context; if(event->key == InputKeyBack) { return false; } with_view_model( - subghz_static->view, (SubghzStaticModel * model) { + instance->view, (SubghzStaticModel * model) { bool reconfigure = false; if(event->type == InputTypeShort) { if(event->key == InputKeyLeft) { @@ -80,39 +78,24 @@ bool subghz_static_input(InputEvent* event, void* context) { } if(reconfigure) { - api_hal_subghz_idle(); + furi_hal_subghz_idle(); model->real_frequency = - api_hal_subghz_set_frequency_and_path(subghz_frequencies[model->frequency]); - api_hal_subghz_tx(); + furi_hal_subghz_set_frequency_and_path(subghz_frequencies[model->frequency]); + furi_hal_subghz_tx(); } if(event->key == InputKeyOk) { if(event->type == InputTypePress) { - const uint8_t* key = subghz_static_keys[model->button]; - NotificationApp* notification = furi_record_open("notification"); notification_message_block(notification, &sequence_set_red_255); - __disable_irq(); - for(uint8_t r = 0; r < 20; r++) { - //Payload - for(uint8_t i = 0; i < 24; i++) { - uint8_t byte = i / 8; - uint8_t bit = i % 8; - bool value = (key[byte] >> (7 - bit)) & 1; - // Payload send - hal_gpio_write(&gpio_cc1101_g0, true); - delay_us(value ? SUBGHZ_PT_SHORT : SUBGHZ_PT_LONG); - hal_gpio_write(&gpio_cc1101_g0, false); - delay_us(value ? SUBGHZ_PT_LONG : SUBGHZ_PT_SHORT); - } - // Last bit - hal_gpio_write(&gpio_cc1101_g0, true); - delay_us(SUBGHZ_PT_SHORT); - hal_gpio_write(&gpio_cc1101_g0, false); - // Guard time - delay_us(10600); - } - __enable_irq(); + + subghz_encoder_princeton_reset( + instance->encoder, subghz_static_keys[model->button], 20); + furi_hal_subghz_start_async_tx( + subghz_encoder_princeton_yield, instance->encoder); + while(!furi_hal_subghz_is_async_tx_complete()) osDelay(33); + furi_hal_subghz_stop_async_tx(); + notification_message(notification, &sequence_reset_red); furi_record_close("notification"); } @@ -126,61 +109,56 @@ bool subghz_static_input(InputEvent* event, void* context) { void subghz_static_enter(void* context) { furi_assert(context); - SubghzStatic* subghz_static = context; + SubghzStatic* instance = context; - api_hal_subghz_reset(); - api_hal_subghz_load_preset(ApiHalSubGhzPresetOokAsync); + furi_hal_subghz_reset(); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync); hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); hal_gpio_write(&gpio_cc1101_g0, false); with_view_model( - subghz_static->view, (SubghzStaticModel * model) { + instance->view, (SubghzStaticModel * model) { model->frequency = subghz_frequencies_433_92; model->real_frequency = - api_hal_subghz_set_frequency_and_path(subghz_frequencies[model->frequency]); + furi_hal_subghz_set_frequency_and_path(subghz_frequencies[model->frequency]); model->button = 0; return true; }); - api_hal_subghz_tx(); + furi_hal_subghz_tx(); } void subghz_static_exit(void* context) { furi_assert(context); - // SubghzStatic* subghz_static = context; - - // Reinitialize IC to default state - api_hal_subghz_sleep(); -} - -uint32_t subghz_static_back(void* context) { - return SubGhzViewMenu; + furi_hal_subghz_sleep(); } SubghzStatic* subghz_static_alloc() { - SubghzStatic* subghz_static = furi_alloc(sizeof(SubghzStatic)); + SubghzStatic* instance = furi_alloc(sizeof(SubghzStatic)); // View allocation and configuration - subghz_static->view = view_alloc(); - view_allocate_model(subghz_static->view, ViewModelTypeLockFree, sizeof(SubghzStaticModel)); - view_set_context(subghz_static->view, subghz_static); - view_set_draw_callback(subghz_static->view, (ViewDrawCallback)subghz_static_draw); - view_set_input_callback(subghz_static->view, subghz_static_input); - view_set_enter_callback(subghz_static->view, subghz_static_enter); - view_set_exit_callback(subghz_static->view, subghz_static_exit); - view_set_previous_callback(subghz_static->view, subghz_static_back); - - return subghz_static; + instance->view = view_alloc(); + view_allocate_model(instance->view, ViewModelTypeLockFree, sizeof(SubghzStaticModel)); + view_set_context(instance->view, instance); + view_set_draw_callback(instance->view, (ViewDrawCallback)subghz_static_draw); + view_set_input_callback(instance->view, subghz_static_input); + view_set_enter_callback(instance->view, subghz_static_enter); + view_set_exit_callback(instance->view, subghz_static_exit); + + instance->encoder = subghz_encoder_princeton_alloc(); + + return instance; } -void subghz_static_free(SubghzStatic* subghz_static) { - furi_assert(subghz_static); - view_free(subghz_static->view); - free(subghz_static); +void subghz_static_free(SubghzStatic* instance) { + furi_assert(instance); + subghz_encoder_princeton_free(instance->encoder); + view_free(instance->view); + free(instance); } -View* subghz_static_get_view(SubghzStatic* subghz_static) { - furi_assert(subghz_static); - return subghz_static->view; +View* subghz_static_get_view(SubghzStatic* instance) { + furi_assert(instance); + return instance->view; } diff --git a/applications/subghz/views/subghz_test_basic.c b/applications/subghz/views/subghz_test_basic.c deleted file mode 100644 index b3107d5432c..00000000000 --- a/applications/subghz/views/subghz_test_basic.c +++ /dev/null @@ -1,201 +0,0 @@ -#include "subghz_test_basic.h" -#include "../subghz_i.h" - -#include -#include -#include -#include - -struct SubghzTestBasic { - View* view; - osTimerId timer; -}; - -typedef enum { - SubghzTestBasicModelStatusRx, - SubghzTestBasicModelStatusTx, -} SubghzTestBasicModelStatus; - -typedef struct { - uint8_t frequency; - uint32_t real_frequency; - ApiHalSubGhzPath path; - float rssi; - SubghzTestBasicModelStatus status; -} SubghzTestBasicModel; - -void subghz_test_basic_draw(Canvas* canvas, SubghzTestBasicModel* model) { - char buffer[64]; - - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 0, 8, "CC1101 Basic Test"); - - canvas_set_font(canvas, FontSecondary); - // Frequency - snprintf( - buffer, - sizeof(buffer), - "Freq: %03ld.%03ld.%03ld Hz", - model->real_frequency / 1000000 % 1000, - model->real_frequency / 1000 % 1000, - model->real_frequency % 1000); - canvas_draw_str(canvas, 0, 20, buffer); - // Path - char* path_name = "Unknown"; - if(model->path == ApiHalSubGhzPathIsolate) { - path_name = "isolate"; - } else if(model->path == ApiHalSubGhzPath433) { - path_name = "433MHz"; - } else if(model->path == ApiHalSubGhzPath315) { - path_name = "315MHz"; - } else if(model->path == ApiHalSubGhzPath868) { - path_name = "868MHz"; - } - snprintf(buffer, sizeof(buffer), "Path: %d - %s", model->path, path_name); - canvas_draw_str(canvas, 0, 31, buffer); - if(model->status == SubghzTestBasicModelStatusRx) { - snprintf( - buffer, - sizeof(buffer), - "RSSI: %ld.%ld dBm", - (int32_t)(model->rssi), - (int32_t)fabs(model->rssi * 10) % 10); - canvas_draw_str(canvas, 0, 42, buffer); - } else { - canvas_draw_str(canvas, 0, 42, "TX"); - } -} - -bool subghz_test_basic_input(InputEvent* event, void* context) { - furi_assert(context); - SubghzTestBasic* subghz_test_basic = context; - - if(event->key == InputKeyBack) { - return false; - } - - with_view_model( - subghz_test_basic->view, (SubghzTestBasicModel * model) { - osTimerStop(subghz_test_basic->timer); - api_hal_subghz_idle(); - - if(event->type == InputTypeShort) { - if(event->key == InputKeyLeft) { - if(model->frequency > 0) model->frequency--; - } else if(event->key == InputKeyRight) { - if(model->frequency < subghz_frequencies_count - 1) model->frequency++; - } else if(event->key == InputKeyDown) { - if(model->path > 0) model->path--; - } else if(event->key == InputKeyUp) { - if(model->path < ApiHalSubGhzPath868) model->path++; - } else if(event->key == InputKeyOk) { - if(model->status == SubghzTestBasicModelStatusTx) { - model->status = SubghzTestBasicModelStatusRx; - } else { - model->status = SubghzTestBasicModelStatusTx; - } - } - - model->real_frequency = - api_hal_subghz_set_frequency(subghz_frequencies[model->frequency]); - api_hal_subghz_set_path(model->path); - } - - if(model->status == SubghzTestBasicModelStatusRx) { - hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); - api_hal_subghz_rx(); - osTimerStart(subghz_test_basic->timer, 1024 / 4); - } else { - hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_write(&gpio_cc1101_g0, true); - api_hal_subghz_tx(); - } - - return true; - }); - - return true; -} - -void subghz_test_basic_enter(void* context) { - furi_assert(context); - SubghzTestBasic* subghz_test_basic = context; - - api_hal_subghz_reset(); - api_hal_subghz_load_preset(ApiHalSubGhzPresetOokAsync); - - hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); - - with_view_model( - subghz_test_basic->view, (SubghzTestBasicModel * model) { - model->frequency = subghz_frequencies_433_92; // 433 - model->real_frequency = - api_hal_subghz_set_frequency(subghz_frequencies[model->frequency]); - model->path = ApiHalSubGhzPathIsolate; // isolate - model->rssi = 0.0f; - model->status = SubghzTestBasicModelStatusRx; - return true; - }); - - api_hal_subghz_rx(); - - osTimerStart(subghz_test_basic->timer, 1024 / 4); -} - -void subghz_test_basic_exit(void* context) { - furi_assert(context); - SubghzTestBasic* subghz_test_basic = context; - - osTimerStop(subghz_test_basic->timer); - - // Reinitialize IC to default state - api_hal_subghz_sleep(); -} - -void subghz_test_basic_rssi_timer_callback(void* context) { - furi_assert(context); - SubghzTestBasic* subghz_test_basic = context; - - with_view_model( - subghz_test_basic->view, (SubghzTestBasicModel * model) { - model->rssi = api_hal_subghz_get_rssi(); - return true; - }); -} - -uint32_t subghz_test_basic_back(void* context) { - return SubGhzViewMenu; -} - -SubghzTestBasic* subghz_test_basic_alloc() { - SubghzTestBasic* subghz_test_basic = furi_alloc(sizeof(SubghzTestBasic)); - - // View allocation and configuration - subghz_test_basic->view = view_alloc(); - view_allocate_model( - subghz_test_basic->view, ViewModelTypeLockFree, sizeof(SubghzTestBasicModel)); - view_set_context(subghz_test_basic->view, subghz_test_basic); - view_set_draw_callback(subghz_test_basic->view, (ViewDrawCallback)subghz_test_basic_draw); - view_set_input_callback(subghz_test_basic->view, subghz_test_basic_input); - view_set_enter_callback(subghz_test_basic->view, subghz_test_basic_enter); - view_set_exit_callback(subghz_test_basic->view, subghz_test_basic_exit); - view_set_previous_callback(subghz_test_basic->view, subghz_test_basic_back); - - subghz_test_basic->timer = osTimerNew( - subghz_test_basic_rssi_timer_callback, osTimerPeriodic, subghz_test_basic, NULL); - - return subghz_test_basic; -} - -void subghz_test_basic_free(SubghzTestBasic* subghz_test_basic) { - furi_assert(subghz_test_basic); - osTimerDelete(subghz_test_basic->timer); - view_free(subghz_test_basic->view); - free(subghz_test_basic); -} - -View* subghz_test_basic_get_view(SubghzTestBasic* subghz_test_basic) { - furi_assert(subghz_test_basic); - return subghz_test_basic->view; -} diff --git a/applications/subghz/views/subghz_test_basic.h b/applications/subghz/views/subghz_test_basic.h deleted file mode 100644 index 5229c7c6df0..00000000000 --- a/applications/subghz/views/subghz_test_basic.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -typedef struct SubghzTestBasic SubghzTestBasic; - -SubghzTestBasic* subghz_test_basic_alloc(); - -void subghz_test_basic_free(SubghzTestBasic* subghz_test_basic); - -View* subghz_test_basic_get_view(SubghzTestBasic* subghz_test_basic); diff --git a/applications/subghz/views/subghz_test_carrier.c b/applications/subghz/views/subghz_test_carrier.c new file mode 100644 index 00000000000..14fb9daa225 --- /dev/null +++ b/applications/subghz/views/subghz_test_carrier.c @@ -0,0 +1,196 @@ +#include "subghz_test_carrier.h" +#include "../subghz_i.h" + +#include +#include +#include +#include + +struct SubghzTestCarrier { + View* view; + osTimerId timer; +}; + +typedef enum { + SubghzTestCarrierModelStatusRx, + SubghzTestCarrierModelStatusTx, +} SubghzTestCarrierModelStatus; + +typedef struct { + uint8_t frequency; + uint32_t real_frequency; + FuriHalSubGhzPath path; + float rssi; + SubghzTestCarrierModelStatus status; +} SubghzTestCarrierModel; + +void subghz_test_carrier_draw(Canvas* canvas, SubghzTestCarrierModel* model) { + char buffer[64]; + + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 0, 8, "CC1101 Basic Test"); + + canvas_set_font(canvas, FontSecondary); + // Frequency + snprintf( + buffer, + sizeof(buffer), + "Freq: %03ld.%03ld.%03ld Hz", + model->real_frequency / 1000000 % 1000, + model->real_frequency / 1000 % 1000, + model->real_frequency % 1000); + canvas_draw_str(canvas, 0, 20, buffer); + // Path + char* path_name = "Unknown"; + if(model->path == FuriHalSubGhzPathIsolate) { + path_name = "isolate"; + } else if(model->path == FuriHalSubGhzPath433) { + path_name = "433MHz"; + } else if(model->path == FuriHalSubGhzPath315) { + path_name = "315MHz"; + } else if(model->path == FuriHalSubGhzPath868) { + path_name = "868MHz"; + } + snprintf(buffer, sizeof(buffer), "Path: %d - %s", model->path, path_name); + canvas_draw_str(canvas, 0, 31, buffer); + if(model->status == SubghzTestCarrierModelStatusRx) { + snprintf( + buffer, + sizeof(buffer), + "RSSI: %ld.%ld dBm", + (int32_t)(model->rssi), + (int32_t)fabs(model->rssi * 10) % 10); + canvas_draw_str(canvas, 0, 42, buffer); + } else { + canvas_draw_str(canvas, 0, 42, "TX"); + } +} + +bool subghz_test_carrier_input(InputEvent* event, void* context) { + furi_assert(context); + SubghzTestCarrier* subghz_test_carrier = context; + + if(event->key == InputKeyBack) { + return false; + } + + with_view_model( + subghz_test_carrier->view, (SubghzTestCarrierModel * model) { + osTimerStop(subghz_test_carrier->timer); + furi_hal_subghz_idle(); + + if(event->type == InputTypeShort) { + if(event->key == InputKeyLeft) { + if(model->frequency > 0) model->frequency--; + } else if(event->key == InputKeyRight) { + if(model->frequency < subghz_frequencies_count - 1) model->frequency++; + } else if(event->key == InputKeyDown) { + if(model->path > 0) model->path--; + } else if(event->key == InputKeyUp) { + if(model->path < FuriHalSubGhzPath868) model->path++; + } else if(event->key == InputKeyOk) { + if(model->status == SubghzTestCarrierModelStatusTx) { + model->status = SubghzTestCarrierModelStatusRx; + } else { + model->status = SubghzTestCarrierModelStatusTx; + } + } + + model->real_frequency = + furi_hal_subghz_set_frequency(subghz_frequencies[model->frequency]); + furi_hal_subghz_set_path(model->path); + } + + if(model->status == SubghzTestCarrierModelStatusRx) { + hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + furi_hal_subghz_rx(); + osTimerStart(subghz_test_carrier->timer, 1024 / 4); + } else { + hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + hal_gpio_write(&gpio_cc1101_g0, true); + furi_hal_subghz_tx(); + } + + return true; + }); + + return true; +} + +void subghz_test_carrier_enter(void* context) { + furi_assert(context); + SubghzTestCarrier* subghz_test_carrier = context; + + furi_hal_subghz_reset(); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync); + + hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + + with_view_model( + subghz_test_carrier->view, (SubghzTestCarrierModel * model) { + model->frequency = subghz_frequencies_433_92; // 433 + model->real_frequency = + furi_hal_subghz_set_frequency(subghz_frequencies[model->frequency]); + model->path = FuriHalSubGhzPathIsolate; // isolate + model->rssi = 0.0f; + model->status = SubghzTestCarrierModelStatusRx; + return true; + }); + + furi_hal_subghz_rx(); + + osTimerStart(subghz_test_carrier->timer, 1024 / 4); +} + +void subghz_test_carrier_exit(void* context) { + furi_assert(context); + SubghzTestCarrier* subghz_test_carrier = context; + + osTimerStop(subghz_test_carrier->timer); + + // Reinitialize IC to default state + furi_hal_subghz_sleep(); +} + +void subghz_test_carrier_rssi_timer_callback(void* context) { + furi_assert(context); + SubghzTestCarrier* subghz_test_carrier = context; + + with_view_model( + subghz_test_carrier->view, (SubghzTestCarrierModel * model) { + model->rssi = furi_hal_subghz_get_rssi(); + return true; + }); +} + +SubghzTestCarrier* subghz_test_carrier_alloc() { + SubghzTestCarrier* subghz_test_carrier = furi_alloc(sizeof(SubghzTestCarrier)); + + // View allocation and configuration + subghz_test_carrier->view = view_alloc(); + view_allocate_model( + subghz_test_carrier->view, ViewModelTypeLockFree, sizeof(SubghzTestCarrierModel)); + view_set_context(subghz_test_carrier->view, subghz_test_carrier); + view_set_draw_callback(subghz_test_carrier->view, (ViewDrawCallback)subghz_test_carrier_draw); + view_set_input_callback(subghz_test_carrier->view, subghz_test_carrier_input); + view_set_enter_callback(subghz_test_carrier->view, subghz_test_carrier_enter); + view_set_exit_callback(subghz_test_carrier->view, subghz_test_carrier_exit); + + subghz_test_carrier->timer = osTimerNew( + subghz_test_carrier_rssi_timer_callback, osTimerPeriodic, subghz_test_carrier, NULL); + + return subghz_test_carrier; +} + +void subghz_test_carrier_free(SubghzTestCarrier* subghz_test_carrier) { + furi_assert(subghz_test_carrier); + osTimerDelete(subghz_test_carrier->timer); + view_free(subghz_test_carrier->view); + free(subghz_test_carrier); +} + +View* subghz_test_carrier_get_view(SubghzTestCarrier* subghz_test_carrier) { + furi_assert(subghz_test_carrier); + return subghz_test_carrier->view; +} diff --git a/applications/subghz/views/subghz_test_carrier.h b/applications/subghz/views/subghz_test_carrier.h new file mode 100644 index 00000000000..f191f7af8e7 --- /dev/null +++ b/applications/subghz/views/subghz_test_carrier.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +typedef struct SubghzTestCarrier SubghzTestCarrier; + +SubghzTestCarrier* subghz_test_carrier_alloc(); + +void subghz_test_carrier_free(SubghzTestCarrier* subghz_test_carrier); + +View* subghz_test_carrier_get_view(SubghzTestCarrier* subghz_test_carrier); diff --git a/applications/subghz/views/subghz_test_packet.c b/applications/subghz/views/subghz_test_packet.c index 188cbea04f3..44841af2b2c 100644 --- a/applications/subghz/views/subghz_test_packet.c +++ b/applications/subghz/views/subghz_test_packet.c @@ -3,23 +3,19 @@ #include #include -#include +#include #include #include #include #define SUBGHZ_TEST_PACKET_COUNT 1000 -#define SUBGHZ_PT_SHORT 376 -#define SUBGHZ_PT_LONG (SUBGHZ_PT_SHORT * 3) -#define SUBGHZ_PT_GUARD 10600 - struct SubghzTestPacket { View* view; osTimerId timer; - size_t tx_buffer_size; - uint32_t* tx_buffer; - SubGhzProtocolPrinceton* princeton; + + SubGhzDecoderPrinceton* decoder; + SubGhzEncoderPrinceton* encoder; volatile size_t packet_rx; }; @@ -32,7 +28,7 @@ typedef enum { typedef struct { uint8_t frequency; uint32_t real_frequency; - ApiHalSubGhzPath path; + FuriHalSubGhzPath path; float rssi; size_t packets; SubghzTestPacketModelStatus status; @@ -43,7 +39,7 @@ volatile bool subghz_test_packet_overrun = false; static void subghz_test_packet_rx_callback(bool level, uint32_t duration, void* context) { furi_assert(context); SubghzTestPacket* instance = context; - subghz_protocol_princeton_parse(instance->princeton, level, duration); + subghz_decoder_princeton_parse(instance->decoder, level, duration); } static void subghz_test_packet_rx_pt_callback(SubGhzProtocolCommon* parser, void* context) { @@ -59,11 +55,11 @@ static void subghz_test_packet_rssi_timer_callback(void* context) { with_view_model( instance->view, (SubghzTestPacketModel * model) { if(model->status == SubghzTestPacketModelStatusRx) { - model->rssi = api_hal_subghz_get_rssi(); + model->rssi = furi_hal_subghz_get_rssi(); model->packets = instance->packet_rx; } else { - model->packets = - SUBGHZ_TEST_PACKET_COUNT - api_hal_subghz_get_async_tx_repeat_left(); + model->packets = SUBGHZ_TEST_PACKET_COUNT - + subghz_encoder_princeton_get_repeat_left(instance->encoder); } return true; }); @@ -88,13 +84,13 @@ static void subghz_test_packet_draw(Canvas* canvas, SubghzTestPacketModel* model canvas_draw_str(canvas, 0, 20, buffer); // Path char* path_name = "Unknown"; - if(model->path == ApiHalSubGhzPathIsolate) { + if(model->path == FuriHalSubGhzPathIsolate) { path_name = "isolate"; - } else if(model->path == ApiHalSubGhzPath433) { + } else if(model->path == FuriHalSubGhzPath433) { path_name = "433MHz"; - } else if(model->path == ApiHalSubGhzPath315) { + } else if(model->path == FuriHalSubGhzPath315) { path_name = "315MHz"; - } else if(model->path == ApiHalSubGhzPath868) { + } else if(model->path == FuriHalSubGhzPath868) { path_name = "868MHz"; } snprintf(buffer, sizeof(buffer), "Path: %d - %s", model->path, path_name); @@ -127,9 +123,9 @@ static bool subghz_test_packet_input(InputEvent* event, void* context) { with_view_model( instance->view, (SubghzTestPacketModel * model) { if(model->status == SubghzTestPacketModelStatusRx) { - api_hal_subghz_stop_async_rx(); + furi_hal_subghz_stop_async_rx(); } else { - api_hal_subghz_stop_async_tx(); + furi_hal_subghz_stop_async_tx(); } if(event->type == InputTypeShort) { @@ -140,7 +136,7 @@ static bool subghz_test_packet_input(InputEvent* event, void* context) { } else if(event->key == InputKeyDown) { if(model->path > 0) model->path--; } else if(event->key == InputKeyUp) { - if(model->path < ApiHalSubGhzPath868) model->path++; + if(model->path < FuriHalSubGhzPath868) model->path++; } else if(event->key == InputKeyOk) { if(model->status == SubghzTestPacketModelStatusTx) { model->status = SubghzTestPacketModelStatusRx; @@ -150,15 +146,15 @@ static bool subghz_test_packet_input(InputEvent* event, void* context) { } model->real_frequency = - api_hal_subghz_set_frequency(subghz_frequencies[model->frequency]); - api_hal_subghz_set_path(model->path); + furi_hal_subghz_set_frequency(subghz_frequencies[model->frequency]); + furi_hal_subghz_set_path(model->path); } if(model->status == SubghzTestPacketModelStatusRx) { - api_hal_subghz_start_async_rx(); + furi_hal_subghz_start_async_rx(subghz_test_packet_rx_callback, instance); } else { - api_hal_subghz_start_async_tx( - instance->tx_buffer, instance->tx_buffer_size, SUBGHZ_TEST_PACKET_COUNT); + subghz_encoder_princeton_reset(instance->encoder, 0x00AABBCC, 1000); + furi_hal_subghz_start_async_tx(subghz_encoder_princeton_yield, instance->encoder); } return true; @@ -171,43 +167,21 @@ void subghz_test_packet_enter(void* context) { furi_assert(context); SubghzTestPacket* instance = context; - instance->tx_buffer_size = 25 * 2 * sizeof(uint32_t); - instance->tx_buffer = furi_alloc(instance->tx_buffer_size); - - const uint32_t key = 0x00ABCDEF; - - size_t pos = 0; - for(uint8_t i = 0; i < 24; i++) { - uint8_t byte = i / 8; - uint8_t bit = i % 8; - bool value = (((uint8_t*)&key)[2 - byte] >> (7 - bit)) & 1; - if(value) { - instance->tx_buffer[pos++] = SUBGHZ_PT_SHORT; - instance->tx_buffer[pos++] = SUBGHZ_PT_LONG; - } else { - instance->tx_buffer[pos++] = SUBGHZ_PT_LONG; - instance->tx_buffer[pos++] = SUBGHZ_PT_SHORT; - } - } - instance->tx_buffer[pos++] = SUBGHZ_PT_SHORT; - instance->tx_buffer[pos++] = SUBGHZ_PT_SHORT + SUBGHZ_PT_GUARD; - - api_hal_subghz_reset(); - api_hal_subghz_load_preset(ApiHalSubGhzPresetOokAsync); - api_hal_subghz_set_async_rx_callback(subghz_test_packet_rx_callback, instance); + furi_hal_subghz_reset(); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetOokAsync); with_view_model( instance->view, (SubghzTestPacketModel * model) { model->frequency = subghz_frequencies_433_92; model->real_frequency = - api_hal_subghz_set_frequency(subghz_frequencies[model->frequency]); - model->path = ApiHalSubGhzPathIsolate; // isolate + furi_hal_subghz_set_frequency(subghz_frequencies[model->frequency]); + model->path = FuriHalSubGhzPathIsolate; // isolate model->rssi = 0.0f; model->status = SubghzTestPacketModelStatusRx; return true; }); - api_hal_subghz_start_async_rx(); + furi_hal_subghz_start_async_rx(subghz_test_packet_rx_callback, instance); osTimerStart(instance->timer, 1024 / 4); } @@ -222,18 +196,13 @@ void subghz_test_packet_exit(void* context) { with_view_model( instance->view, (SubghzTestPacketModel * model) { if(model->status == SubghzTestPacketModelStatusRx) { - api_hal_subghz_stop_async_rx(); + furi_hal_subghz_stop_async_rx(); } else { - api_hal_subghz_stop_async_tx(); + furi_hal_subghz_stop_async_tx(); } return true; }); - api_hal_subghz_set_async_rx_callback(NULL, NULL); - api_hal_subghz_sleep(); -} - -uint32_t subghz_test_packet_back(void* context) { - return SubGhzViewMenu; + furi_hal_subghz_sleep(); } SubghzTestPacket* subghz_test_packet_alloc() { @@ -247,14 +216,14 @@ SubghzTestPacket* subghz_test_packet_alloc() { view_set_input_callback(instance->view, subghz_test_packet_input); view_set_enter_callback(instance->view, subghz_test_packet_enter); view_set_exit_callback(instance->view, subghz_test_packet_exit); - view_set_previous_callback(instance->view, subghz_test_packet_back); instance->timer = osTimerNew(subghz_test_packet_rssi_timer_callback, osTimerPeriodic, instance, NULL); - instance->princeton = subghz_protocol_princeton_alloc(); + instance->decoder = subghz_decoder_princeton_alloc(); subghz_protocol_common_set_callback( - (SubGhzProtocolCommon*)instance->princeton, subghz_test_packet_rx_pt_callback, instance); + (SubGhzProtocolCommon*)instance->decoder, subghz_test_packet_rx_pt_callback, instance); + instance->encoder = subghz_encoder_princeton_alloc(); return instance; } @@ -262,7 +231,9 @@ SubghzTestPacket* subghz_test_packet_alloc() { void subghz_test_packet_free(SubghzTestPacket* instance) { furi_assert(instance); - subghz_protocol_princeton_free(instance->princeton); + subghz_decoder_princeton_free(instance->decoder); + subghz_encoder_princeton_free(instance->encoder); + osTimerDelete(instance->timer); view_free(instance->view); free(instance); diff --git a/applications/subghz/views/subghz_transmitter.c b/applications/subghz/views/subghz_transmitter.c new file mode 100644 index 00000000000..703d00d894a --- /dev/null +++ b/applications/subghz/views/subghz_transmitter.c @@ -0,0 +1,138 @@ +#include "subghz_transmitter.h" +#include "../subghz_i.h" + +#include +#include +#include +#include +#include +#include + +#include + +struct SubghzTransmitter { + View* view; + SubghzTransmitterCallback callback; + void* context; +}; + +typedef struct { + string_t text; + uint16_t scene; + SubGhzProtocolCommon* protocol; +} SubghzTransmitterModel; + +void subghz_transmitter_set_callback( + SubghzTransmitter* subghz_transmitter, + SubghzTransmitterCallback callback, + void* context) { + furi_assert(subghz_transmitter); + + subghz_transmitter->callback = callback; + subghz_transmitter->context = context; +} + +void subghz_transmitter_set_protocol( + SubghzTransmitter* subghz_transmitter, + SubGhzProtocolCommon* protocol) { + with_view_model( + subghz_transmitter->view, (SubghzTransmitterModel * model) { + model->protocol = protocol; + return true; + }); +} + +void subghz_transmitter_draw(Canvas* canvas, SubghzTransmitterModel* model) { + canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontSecondary); + elements_multiline_text(canvas, 0, 10, string_get_cstr(model->text)); + + elements_button_center(canvas, "Send"); +} + +bool subghz_transmitter_input(InputEvent* event, void* context) { + furi_assert(context); + SubghzTransmitter* subghz_transmitter = context; + + if(event->type != InputTypeShort) return false; + + if(event->key == InputKeyBack) { + return false; + } else if(event->key == InputKeyOk) { + subghz_transmitter->callback(SubghzTransmitterEventSend, subghz_transmitter->context); + return true; + } + + return true; +} + +void subghz_transmitter_text_callback(string_t text, void* context) { + furi_assert(context); + SubghzTransmitter* subghz_transmitter = context; + + with_view_model( + subghz_transmitter->view, (SubghzTransmitterModel * model) { + string_set(model->text, text); + model->scene = 0; + return true; + }); +} + +void subghz_transmitter_enter(void* context) { + furi_assert(context); + SubghzTransmitter* subghz_transmitter = context; + with_view_model( + subghz_transmitter->view, (SubghzTransmitterModel * model) { + model->protocol->to_string(model->protocol, model->text); + return true; + }); +} + +void subghz_transmitter_exit(void* context) { + furi_assert(context); + SubghzTransmitter* subghz_transmitter = context; + with_view_model( + subghz_transmitter->view, (SubghzTransmitterModel * model) { + string_clean(model->text); + return true; + }); +} + +SubghzTransmitter* subghz_transmitter_alloc() { + SubghzTransmitter* subghz_transmitter = furi_alloc(sizeof(SubghzTransmitter)); + + // View allocation and configuration + subghz_transmitter->view = view_alloc(); + view_allocate_model( + subghz_transmitter->view, ViewModelTypeLocking, sizeof(SubghzTransmitterModel)); + view_set_context(subghz_transmitter->view, subghz_transmitter); + view_set_draw_callback(subghz_transmitter->view, (ViewDrawCallback)subghz_transmitter_draw); + view_set_input_callback(subghz_transmitter->view, subghz_transmitter_input); + view_set_enter_callback(subghz_transmitter->view, subghz_transmitter_enter); + view_set_exit_callback(subghz_transmitter->view, subghz_transmitter_exit); + + with_view_model( + subghz_transmitter->view, (SubghzTransmitterModel * model) { + string_init(model->text); + return true; + }); + return subghz_transmitter; +} + +void subghz_transmitter_free(SubghzTransmitter* subghz_transmitter) { + furi_assert(subghz_transmitter); + + with_view_model( + subghz_transmitter->view, (SubghzTransmitterModel * model) { + string_clear(model->text); + return true; + }); + view_free(subghz_transmitter->view); + free(subghz_transmitter); +} + +View* subghz_transmitter_get_view(SubghzTransmitter* subghz_transmitter) { + furi_assert(subghz_transmitter); + return subghz_transmitter->view; +} diff --git a/applications/subghz/views/subghz_transmitter.h b/applications/subghz/views/subghz_transmitter.h new file mode 100644 index 00000000000..ffd2737392e --- /dev/null +++ b/applications/subghz/views/subghz_transmitter.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +typedef enum { + SubghzTransmitterEventSend, + SubghzTransmitterEventBack, +} SubghzTransmitterEvent; + +typedef struct SubghzTransmitter SubghzTransmitter; + +typedef void (*SubghzTransmitterCallback)(SubghzTransmitterEvent event, void* context); + +void subghz_transmitter_set_callback( + SubghzTransmitter* subghz_transmitter, + SubghzTransmitterCallback callback, + void* context); + +SubghzTransmitter* subghz_transmitter_alloc(); + +void subghz_transmitter_free(SubghzTransmitter* subghz_transmitter); + +View* subghz_transmitter_get_view(SubghzTransmitter* subghz_transmitter); + +void subghz_transmitter_set_protocol( + SubghzTransmitter* subghz_transmitter, + SubGhzProtocolCommon* protocol); diff --git a/applications/tests/furi_valuemutex_test.c b/applications/tests/furi_valuemutex_test.c index c0e1755c0d2..43383f94cd8 100644 --- a/applications/tests/furi_valuemutex_test.c +++ b/applications/tests/furi_valuemutex_test.c @@ -1,7 +1,7 @@ #include #include #include -#include "api-hal-delay.h" +#include "furi-hal-delay.h" #include "minunit.h" diff --git a/applications/tests/test_index.c b/applications/tests/test_index.c index f8756dceb10..c0f8919abbc 100644 --- a/applications/tests/test_index.c +++ b/applications/tests/test_index.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include "minunit_vars.h" #include diff --git a/assets/compiled/assets_icons.c b/assets/compiled/assets_icons.c index 83b2dae03e7..f76f05c976d 100644 --- a/assets/compiled/assets_icons.c +++ b/assets/compiled/assets_icons.c @@ -89,6 +89,9 @@ const uint8_t *_I_ButtonLeft_4x7[] = {_I_ButtonLeft_4x7_0}; const uint8_t _I_ButtonLeftSmall_3x5_0[] = {0x04,0x06,0x07,0x06,0x04,}; const uint8_t *_I_ButtonLeftSmall_3x5[] = {_I_ButtonLeftSmall_3x5_0}; +const uint8_t _I_Warning_30x23_0[] = {0x00,0xC0,0x00,0x00,0x00,0xE0,0x01,0x00,0x00,0xF0,0x03,0x00,0x00,0xF0,0x03,0x00,0x00,0xF8,0x07,0x00,0x00,0x3C,0x0F,0x00,0x00,0x3C,0x0F,0x00,0x00,0x3E,0x1F,0x00,0x00,0x3F,0x3F,0x00,0x00,0x3F,0x3F,0x00,0x80,0x3F,0x7F,0x00,0xC0,0x3F,0xFF,0x00,0xC0,0x3F,0xFF,0x00,0xE0,0x3F,0xFF,0x01,0xF0,0x3F,0xFF,0x03,0xF0,0x3F,0xFF,0x03,0xF8,0x3F,0xFF,0x07,0xFC,0xFF,0xFF,0x0F,0xFC,0xFF,0xFF,0x0F,0xFE,0x3F,0xFF,0x1F,0xFF,0x3F,0xFF,0x3F,0xFF,0xFF,0xFF,0x3F,0xFE,0xFF,0xFF,0x1F,}; +const uint8_t *_I_Warning_30x23[] = {_I_Warning_30x23_0}; + const uint8_t _I_ButtonRight_4x7_0[] = {0x01,0x03,0x07,0x0F,0x07,0x03,0x01,}; const uint8_t *_I_ButtonRight_4x7[] = {_I_ButtonRight_4x7_0}; @@ -143,6 +146,45 @@ const uint8_t *_I_FX_Bang_32x6[] = {_I_FX_Bang_32x6_0}; const uint8_t _I_DolphinFirstStart3_57x48_0[] = {0x00,0x00,0x00,0x80,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x04,0x00,0x00,0xF8,0x03,0x01,0x00,0x00,0x08,0x00,0x00,0x04,0xBC,0x00,0x00,0x00,0x10,0x00,0x00,0x02,0xC0,0x00,0x00,0x00,0x20,0x00,0x00,0x02,0x00,0x01,0x00,0x00,0x20,0x00,0x00,0x02,0x00,0x02,0x00,0x38,0x40,0x00,0x00,0x02,0x00,0x04,0x00,0x3E,0x40,0x00,0x00,0xF4,0x03,0x08,0x80,0x07,0x80,0x00,0x00,0x5C,0x0D,0x10,0xE0,0x01,0x80,0x00,0x00,0xA8,0x3A,0x20,0xE0,0x00,0x00,0x01,0x00,0x58,0x55,0x00,0xC0,0x01,0x00,0x01,0x00,0xB0,0xAA,0x00,0x80,0x07,0x00,0x01,0x00,0x60,0x55,0x01,0x00,0x1E,0x00,0x01,0x0E,0xC0,0xAA,0x02,0xE0,0x5C,0x00,0x01,0x11,0x80,0x55,0x05,0x00,0xA9,0x00,0x01,0x21,0x00,0xAB,0x0A,0x00,0x56,0x07,0x01,0x41,0x00,0x56,0x15,0x00,0xEC,0x08,0x01,0x81,0x00,0xBF,0x2A,0x00,0x34,0x08,0x01,0x01,0xF1,0xC0,0x57,0x00,0x0C,0x08,0x01,0x02,0x0A,0x00,0xBE,0x00,0x04,0x08,0x01,0x02,0x06,0x00,0x78,0x83,0x02,0x04,0x01,0x02,0x0C,0x00,0xF0,0x7F,0x01,0x04,0x01,0x02,0xF4,0x01,0xFE,0x81,0x00,0x04,0x01,0x04,0x08,0xFF,0x6B,0x40,0x00,0x02,0x01,0x04,0x88,0x55,0x1D,0x40,0x00,0x02,0x01,0x04,0x50,0xAA,0x06,0x20,0x00,0x02,0x01,0x04,0x30,0xD4,0x01,0x20,0x00,0x01,0x01,0x04,0x10,0x68,0x00,0x10,0x00,0x01,0x01,0x04,0x18,0x18,0x00,0x10,0x00,0x01,0x01,0x08,0x18,0x06,0x80,0x10,0x00,0x01,0x01,0x08,0xE8,0x01,0x60,0x08,0x80,0x00,0x01,0x08,0x08,0x00,0x18,0x08,0x80,0x00,0x00,0x08,0x10,0x00,0x06,0x08,0x80,0x00,0x00,0x08,0x60,0xE0,0x01,0x08,0x80,0x00,0x00,0x08,0x80,0x1F,0x00,0x08,0x80,0x00,0x00,0x08,0x80,0x04,0x00,0x04,0x00,0x01,0x00,0x08,0x80,0x04,0x00,0x04,0x00,0x01,0x00,0x10,0x00,0x03,0x00,0x04,0x00,0x01,0x00,0x10,0x00,0x03,0x00,0x04,0x00,0x01,0x00,0x10,0x00,0x01,0x00,0x04,0x00,0x02,0x00,0x10,0x00,0x01,0x00,0x04,0x00,0x02,0x00,0x10,0x80,0x00,0x00,0x04,0x00,0x02,0x00,0x10,0x80,0x00,0x00,0x04,0x00,0x06,0x00,}; const uint8_t *_I_DolphinFirstStart3_57x48[] = {_I_DolphinFirstStart3_57x48_0}; +const uint8_t _I_blackfish_25x17_0[] = {0x00,0x0E,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x3F,0x80,0x01,0x80,0xFF,0xE0,0x01,0xE0,0xFF,0xF0,0x01,0xF0,0xFF,0xF3,0x01,0xF8,0xFF,0xFF,0x00,0xFC,0xFF,0xFF,0x00,0xFF,0xFF,0x7F,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFE,0xFF,0xFB,0x01,0xF8,0xFF,0xF1,0x01,0xE0,0x7F,0xC0,0x01,0x00,0x3F,0x00,0x00,0x00,0x3C,0x00,0x00,}; +const uint8_t *_I_blackfish_25x17[] = {_I_blackfish_25x17_0}; + +const uint8_t _I_blacklid_36x27_0[] = {0x00,0x80,0x1F,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x80,0x1F,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0xFE,0xFF,0x07,0x00,0x80,0xFF,0xFF,0x1F,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0xE0,0xFF,0xFF,0x7F,0x00,0xF0,0xFF,0xFF,0xFF,0x00,0xF8,0xFF,0xFF,0xFF,0x01,0xFC,0xFF,0xFF,0xFF,0x03,0xFC,0xFF,0xFF,0xFF,0x03,0xFE,0xFF,0xFF,0xFF,0x07,0xFE,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0xFF,0x0F,0xFE,0xFF,0xFF,0xFF,0x07,0xFE,0xFF,0xFF,0xFF,0x07,0xFC,0xFF,0xFF,0xFF,0x03,0xF0,0xFF,0xFF,0xFF,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xFC,0xFF,0x03,0x00,}; +const uint8_t *_I_blacklid_36x27[] = {_I_blacklid_36x27_0}; + +const uint8_t _I_skeleton_25x17_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x10,0x25,0xC0,0x00,0x08,0x49,0xA1,0x00,0x68,0x4A,0x92,0x00,0x64,0x4A,0x52,0x00,0x64,0xFE,0x5F,0x00,0x08,0x4A,0x92,0x00,0x08,0x4A,0xA1,0x00,0x10,0x29,0xC0,0x00,0xE0,0x04,0x00,0x00,}; +const uint8_t *_I_skeleton_25x17[] = {_I_skeleton_25x17_0}; + +const uint8_t _I_letterB_10x10_0[] = {0xFF,0x03,0x01,0x02,0x39,0x02,0x49,0x02,0x39,0x02,0x49,0x02,0x49,0x02,0x39,0x02,0x01,0x02,0xFF,0x03,}; +const uint8_t *_I_letterB_10x10[] = {_I_letterB_10x10_0}; + +const uint8_t _I_shit_25x17_0[] = {0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0xA0,0x00,0x00,0x00,0x30,0x01,0x00,0x00,0x18,0x01,0x00,0x00,0x0F,0x01,0x00,0x80,0x00,0x07,0x00,0x80,0xC0,0x08,0x00,0xC0,0x03,0x08,0x00,0x20,0x06,0x1E,0x00,0x20,0x30,0x13,0x00,0x20,0x00,0x10,0x00,0xC0,0x00,0x18,0x00,0x80,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_shit_25x17[] = {_I_shit_25x17_0}; + +const uint8_t _I_letterC_10x10_0[] = {0xFF,0x03,0x01,0x02,0x31,0x02,0x49,0x02,0x09,0x02,0x09,0x02,0x49,0x02,0x31,0x02,0x01,0x02,0xFF,0x03,}; +const uint8_t *_I_letterC_10x10[] = {_I_letterC_10x10_0}; + +const uint8_t _I_active_plate_48x18_0[] = {0x08,0x00,0x00,0x00,0x00,0x10,0x0C,0x00,0x00,0x00,0x00,0x30,0x06,0x00,0x00,0x00,0x00,0x60,0x06,0x00,0x00,0x00,0x00,0x60,0x07,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0xF0,0x0F,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0xF8,0x3E,0x00,0x00,0x00,0x00,0x7C,0x7E,0x00,0x00,0x00,0x00,0x7E,0xFC,0x01,0x00,0x00,0x80,0x3F,0xF8,0x0F,0x00,0x00,0xF0,0x1F,0xF0,0x7F,0x00,0x00,0xFE,0x0F,0xE0,0xFF,0xFF,0xFF,0xFF,0x07,0x80,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0xFE,0xFF,0xFF,0x7F,0x00,0x00,0xF0,0xFF,0xFF,0x0F,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,}; +const uint8_t *_I_active_plate_48x18[] = {_I_active_plate_48x18_0}; + +const uint8_t _I_fish_25x17_0[] = {0x00,0x0E,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x21,0x80,0x01,0x80,0xCD,0x60,0x01,0x60,0xC0,0x10,0x01,0x10,0x00,0x13,0x01,0x08,0x00,0x8C,0x00,0xC4,0x00,0x88,0x00,0xE3,0x00,0x40,0x00,0xE1,0x00,0x80,0x00,0x03,0x00,0x80,0x00,0x01,0x00,0x0C,0x01,0x0E,0x00,0x1B,0x01,0x38,0xC0,0x71,0x01,0xE0,0x7F,0xC0,0x01,0x00,0x3F,0x00,0x00,0x00,0x3C,0x00,0x00,}; +const uint8_t *_I_fish_25x17[] = {_I_fish_25x17_0}; + +const uint8_t _I_blackshit_25x17_0[] = {0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xF8,0x01,0x00,0x00,0xFF,0x01,0x00,0x80,0xFF,0x07,0x00,0x80,0xFF,0x0F,0x00,0xC0,0xFF,0x0F,0x00,0xE0,0xFF,0x1F,0x00,0xE0,0xFF,0x1F,0x00,0xE0,0xFF,0x1F,0x00,0xC0,0xFF,0x1F,0x00,0x80,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_blackshit_25x17[] = {_I_blackshit_25x17_0}; + +const uint8_t _I_lid_36x27_0[] = {0x00,0x80,0x1F,0x00,0x00,0x00,0x40,0x20,0x00,0x00,0x00,0x40,0x20,0x00,0x00,0x00,0x80,0x1F,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x38,0xCF,0x01,0x00,0x00,0x06,0x00,0x06,0x00,0x80,0x01,0x00,0x18,0x00,0x40,0x00,0x80,0x21,0x00,0x20,0x00,0x00,0x46,0x00,0x10,0x00,0x00,0x8C,0x00,0x08,0x00,0x00,0x18,0x01,0x04,0x00,0x00,0x38,0x02,0x04,0x00,0x00,0x70,0x02,0x02,0x00,0x00,0x70,0x04,0x02,0x00,0x00,0xE0,0x04,0x01,0x00,0x00,0xE0,0x08,0x01,0x00,0x00,0xC0,0x09,0x01,0x00,0x00,0xC0,0x09,0x01,0x00,0x00,0xC0,0x09,0x02,0x00,0x00,0xC0,0x07,0x02,0x00,0x00,0xC0,0x07,0x0C,0x00,0x00,0xE0,0x03,0x30,0x00,0x00,0xF0,0x00,0xC0,0x03,0x00,0x3C,0x00,0x00,0xFC,0xFF,0x03,0x00,}; +const uint8_t *_I_lid_36x27[] = {_I_lid_36x27_0}; + +const uint8_t _I_blackskeleton_25x17_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xF0,0x25,0xC0,0x00,0xF8,0x49,0xE1,0x00,0xF8,0x4B,0xF2,0x00,0xFC,0x4B,0x72,0x00,0xFC,0xFF,0x7F,0x00,0xF8,0x4B,0xF2,0x00,0xF8,0x4B,0xE1,0x00,0xF0,0x29,0xC0,0x00,0xE0,0x04,0x00,0x00,}; +const uint8_t *_I_blackskeleton_25x17[] = {_I_blackskeleton_25x17_0}; + +const uint8_t _I_letterA_10x10_0[] = {0xFF,0x03,0x01,0x02,0x31,0x02,0x49,0x02,0x79,0x02,0x49,0x02,0x49,0x02,0x49,0x02,0x01,0x02,0xFF,0x03,}; +const uint8_t *_I_letterA_10x10[] = {_I_letterA_10x10_0}; + +const uint8_t _I_plate_42x19_0[] = {0x00,0xF0,0xFF,0x3F,0x00,0x00,0x00,0x0E,0x00,0xC0,0x01,0x00,0xC0,0x01,0x00,0x00,0x0E,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x08,0x00,0x00,0x00,0x40,0x00,0x04,0x00,0x00,0x00,0x80,0x00,0x02,0x00,0x00,0x00,0x00,0x01,0x02,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x02,0x01,0x00,0x00,0x00,0x00,0x02,0x01,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x01,0x02,0x00,0x00,0x00,0x00,0x01,0x04,0x00,0x00,0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x40,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0xC0,0x01,0x00,0x00,0x0E,0x00,0x00,0x0E,0x00,0xC0,0x01,0x00,0x00,0xF0,0xFF,0x3F,0x00,0x00,}; +const uint8_t *_I_plate_42x19[] = {_I_plate_42x19_0}; + const uint8_t _I_PassportBottom_128x17_0[] = {0x2C,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8F,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x2C,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0xF2,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8F,0xF9,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0D,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x05,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x05,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x05,0xFA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x09,0x79,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xD5,0x80,0x55,0xD5,0x00,0xF3,0xCC,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x6A,0x00,0xAB,0x6A,0x00,0x06,0x86,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x00,0xFE,0x3F,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; const uint8_t *_I_PassportBottom_128x17[] = {_I_PassportBottom_128x17_0}; @@ -803,6 +845,7 @@ const Icon I_125_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.fram const Icon I_ButtonRightSmall_3x5 = {.width=3,.height=5,.frame_count=1,.frame_rate=0,.frames=_I_ButtonRightSmall_3x5}; const Icon I_ButtonLeft_4x7 = {.width=4,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonLeft_4x7}; const Icon I_ButtonLeftSmall_3x5 = {.width=3,.height=5,.frame_count=1,.frame_rate=0,.frames=_I_ButtonLeftSmall_3x5}; +const Icon I_Warning_30x23 = {.width=30,.height=23,.frame_count=1,.frame_rate=0,.frames=_I_Warning_30x23}; const Icon I_ButtonRight_4x7 = {.width=4,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonRight_4x7}; const Icon I_ButtonCenter_7x7 = {.width=7,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonCenter_7x7}; const Icon I_FX_SittingB_40x27 = {.width=40,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_FX_SittingB_40x27}; @@ -821,6 +864,19 @@ const Icon I_Flipper_young_80x60 = {.width=80,.height=60,.frame_count=1,.frame_r const Icon I_BigBurger_24x24 = {.width=24,.height=24,.frame_count=1,.frame_rate=0,.frames=_I_BigBurger_24x24}; const Icon I_FX_Bang_32x6 = {.width=32,.height=6,.frame_count=1,.frame_rate=0,.frames=_I_FX_Bang_32x6}; const Icon I_DolphinFirstStart3_57x48 = {.width=57,.height=48,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart3_57x48}; +const Icon I_blackfish_25x17 = {.width=25,.height=17,.frame_count=1,.frame_rate=0,.frames=_I_blackfish_25x17}; +const Icon I_blacklid_36x27 = {.width=36,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_blacklid_36x27}; +const Icon I_skeleton_25x17 = {.width=25,.height=17,.frame_count=1,.frame_rate=0,.frames=_I_skeleton_25x17}; +const Icon I_letterB_10x10 = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_letterB_10x10}; +const Icon I_shit_25x17 = {.width=25,.height=17,.frame_count=1,.frame_rate=0,.frames=_I_shit_25x17}; +const Icon I_letterC_10x10 = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_letterC_10x10}; +const Icon I_active_plate_48x18 = {.width=48,.height=18,.frame_count=1,.frame_rate=0,.frames=_I_active_plate_48x18}; +const Icon I_fish_25x17 = {.width=25,.height=17,.frame_count=1,.frame_rate=0,.frames=_I_fish_25x17}; +const Icon I_blackshit_25x17 = {.width=25,.height=17,.frame_count=1,.frame_rate=0,.frames=_I_blackshit_25x17}; +const Icon I_lid_36x27 = {.width=36,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_lid_36x27}; +const Icon I_blackskeleton_25x17 = {.width=25,.height=17,.frame_count=1,.frame_rate=0,.frames=_I_blackskeleton_25x17}; +const Icon I_letterA_10x10 = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_letterA_10x10}; +const Icon I_plate_42x19 = {.width=42,.height=19,.frame_count=1,.frame_rate=0,.frames=_I_plate_42x19}; const Icon I_PassportBottom_128x17 = {.width=128,.height=17,.frame_count=1,.frame_rate=0,.frames=_I_PassportBottom_128x17}; const Icon I_DoorLeft_8x56 = {.width=8,.height=56,.frame_count=1,.frame_rate=0,.frames=_I_DoorLeft_8x56}; const Icon I_DoorLocked_10x56 = {.width=10,.height=56,.frame_count=1,.frame_rate=0,.frames=_I_DoorLocked_10x56}; diff --git a/assets/compiled/assets_icons.h b/assets/compiled/assets_icons.h index 21981ebdadd..5534ca71547 100644 --- a/assets/compiled/assets_icons.h +++ b/assets/compiled/assets_icons.h @@ -21,6 +21,7 @@ extern const Icon I_125_10px; extern const Icon I_ButtonRightSmall_3x5; extern const Icon I_ButtonLeft_4x7; extern const Icon I_ButtonLeftSmall_3x5; +extern const Icon I_Warning_30x23; extern const Icon I_ButtonRight_4x7; extern const Icon I_ButtonCenter_7x7; extern const Icon I_FX_SittingB_40x27; @@ -39,6 +40,19 @@ extern const Icon I_Flipper_young_80x60; extern const Icon I_BigBurger_24x24; extern const Icon I_FX_Bang_32x6; extern const Icon I_DolphinFirstStart3_57x48; +extern const Icon I_blackfish_25x17; +extern const Icon I_blacklid_36x27; +extern const Icon I_skeleton_25x17; +extern const Icon I_letterB_10x10; +extern const Icon I_shit_25x17; +extern const Icon I_letterC_10x10; +extern const Icon I_active_plate_48x18; +extern const Icon I_fish_25x17; +extern const Icon I_blackshit_25x17; +extern const Icon I_lid_36x27; +extern const Icon I_blackskeleton_25x17; +extern const Icon I_letterA_10x10; +extern const Icon I_plate_42x19; extern const Icon I_PassportBottom_128x17; extern const Icon I_DoorLeft_8x56; extern const Icon I_DoorLocked_10x56; diff --git a/assets/icons/Common/Warning_30x23.png b/assets/icons/Common/Warning_30x23.png new file mode 100644 index 00000000000..5f7e02dd857 Binary files /dev/null and b/assets/icons/Common/Warning_30x23.png differ diff --git a/assets/icons/FoodMinigame/active_plate_48x18.png b/assets/icons/FoodMinigame/active_plate_48x18.png new file mode 100644 index 00000000000..f1e2b84c4dd Binary files /dev/null and b/assets/icons/FoodMinigame/active_plate_48x18.png differ diff --git a/assets/icons/FoodMinigame/blackfish_25x17.png b/assets/icons/FoodMinigame/blackfish_25x17.png new file mode 100644 index 00000000000..f8cc252292d Binary files /dev/null and b/assets/icons/FoodMinigame/blackfish_25x17.png differ diff --git a/assets/icons/FoodMinigame/blacklid_36x27.png b/assets/icons/FoodMinigame/blacklid_36x27.png new file mode 100644 index 00000000000..a4407e8d1dd Binary files /dev/null and b/assets/icons/FoodMinigame/blacklid_36x27.png differ diff --git a/assets/icons/FoodMinigame/blackshit_25x17.png b/assets/icons/FoodMinigame/blackshit_25x17.png new file mode 100644 index 00000000000..837c81b5415 Binary files /dev/null and b/assets/icons/FoodMinigame/blackshit_25x17.png differ diff --git a/assets/icons/FoodMinigame/blackskeleton_25x17.png b/assets/icons/FoodMinigame/blackskeleton_25x17.png new file mode 100644 index 00000000000..c55ee79e7c7 Binary files /dev/null and b/assets/icons/FoodMinigame/blackskeleton_25x17.png differ diff --git a/assets/icons/FoodMinigame/fish_25x17.png b/assets/icons/FoodMinigame/fish_25x17.png new file mode 100644 index 00000000000..dcfcba34a59 Binary files /dev/null and b/assets/icons/FoodMinigame/fish_25x17.png differ diff --git a/assets/icons/FoodMinigame/letterA_10x10.png b/assets/icons/FoodMinigame/letterA_10x10.png new file mode 100644 index 00000000000..ccf79edbbe3 Binary files /dev/null and b/assets/icons/FoodMinigame/letterA_10x10.png differ diff --git a/assets/icons/FoodMinigame/letterB_10x10.png b/assets/icons/FoodMinigame/letterB_10x10.png new file mode 100644 index 00000000000..2dee98f56d6 Binary files /dev/null and b/assets/icons/FoodMinigame/letterB_10x10.png differ diff --git a/assets/icons/FoodMinigame/letterC_10x10.png b/assets/icons/FoodMinigame/letterC_10x10.png new file mode 100644 index 00000000000..9d8256e89bc Binary files /dev/null and b/assets/icons/FoodMinigame/letterC_10x10.png differ diff --git a/assets/icons/FoodMinigame/lid_36x27.png b/assets/icons/FoodMinigame/lid_36x27.png new file mode 100644 index 00000000000..c5855b2d7ce Binary files /dev/null and b/assets/icons/FoodMinigame/lid_36x27.png differ diff --git a/assets/icons/FoodMinigame/plate_42x19.png b/assets/icons/FoodMinigame/plate_42x19.png new file mode 100644 index 00000000000..3de05e1bb14 Binary files /dev/null and b/assets/icons/FoodMinigame/plate_42x19.png differ diff --git a/assets/icons/FoodMinigame/shit_25x17.png b/assets/icons/FoodMinigame/shit_25x17.png new file mode 100644 index 00000000000..2323a818158 Binary files /dev/null and b/assets/icons/FoodMinigame/shit_25x17.png differ diff --git a/assets/icons/FoodMinigame/skeleton_25x17.png b/assets/icons/FoodMinigame/skeleton_25x17.png new file mode 100644 index 00000000000..9dcf45bf762 Binary files /dev/null and b/assets/icons/FoodMinigame/skeleton_25x17.png differ diff --git a/bootloader/Makefile b/bootloader/Makefile index c6600a218a6..7207124b834 100644 --- a/bootloader/Makefile +++ b/bootloader/Makefile @@ -3,7 +3,7 @@ PROJECT = bootloader include $(PROJECT_ROOT)/make/base.mk -CFLAGS += -I$(PROJECT_ROOT) -Itargets/api-hal-include +CFLAGS += -I$(PROJECT_ROOT) -Itargets/furi-hal-include ASM_SOURCES += $(wildcard src/*.s) C_SOURCES += $(wildcard src/*.c) CPP_SOURCES += $(wildcard src/*.cpp) @@ -12,6 +12,33 @@ TARGET ?= f6 TARGET_DIR = targets/$(TARGET) include $(TARGET_DIR)/target.mk +LIB_DIR = $(PROJECT_ROOT)/lib + +# U8G2 display library +U8G2_DIR = $(LIB_DIR)/u8g2 +CFLAGS += -I$(U8G2_DIR) +C_SOURCES += $(U8G2_DIR)/u8x8_d_st7565.c +C_SOURCES += $(U8G2_DIR)/u8g2_d_setup.c +C_SOURCES += $(U8G2_DIR)/u8g2_intersection.c +C_SOURCES += $(U8G2_DIR)/u8g2_setup.c +C_SOURCES += $(U8G2_DIR)/u8g2_d_memory.c +C_SOURCES += $(U8G2_DIR)/u8x8_cad.c +C_SOURCES += $(U8G2_DIR)/u8x8_byte.c +C_SOURCES += $(U8G2_DIR)/u8x8_gpio.c +C_SOURCES += $(U8G2_DIR)/u8x8_display.c +C_SOURCES += $(U8G2_DIR)/u8x8_setup.c +C_SOURCES += $(U8G2_DIR)/u8g2_hvline.c +C_SOURCES += $(U8G2_DIR)/u8g2_line.c +C_SOURCES += $(U8G2_DIR)/u8g2_ll_hvline.c +C_SOURCES += $(U8G2_DIR)/u8g2_circle.c +C_SOURCES += $(U8G2_DIR)/u8g2_box.c +C_SOURCES += $(U8G2_DIR)/u8g2_buffer.c +C_SOURCES += $(U8G2_DIR)/u8g2_font.c +C_SOURCES += $(U8G2_DIR)/u8g2_fonts.c +C_SOURCES += $(U8G2_DIR)/u8x8_8x8.c +C_SOURCES += $(U8G2_DIR)/u8g2_bitmap.c + + include $(PROJECT_ROOT)/make/git.mk include $(PROJECT_ROOT)/make/toolchain.mk include $(PROJECT_ROOT)/make/rules.mk diff --git a/bootloader/targets/f6/api-hal/api-hal-resources.h b/bootloader/targets/f6/api-hal/api-hal-resources.h deleted file mode 100644 index 8bf55562229..00000000000 --- a/bootloader/targets/f6/api-hal/api-hal-resources.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define POWER_I2C_SCL_Pin LL_GPIO_PIN_9 -#define POWER_I2C_SCL_GPIO_Port GPIOA -#define POWER_I2C_SDA_Pin LL_GPIO_PIN_10 -#define POWER_I2C_SDA_GPIO_Port GPIOA - -#define POWER_I2C I2C1 -/* Timing register value is computed with the STM32CubeMX Tool, - * Fast Mode @100kHz with I2CCLK = 64 MHz, - * rise time = 0ns, fall time = 0ns - */ -#define POWER_I2C_TIMINGS 0x10707DBC - -/* Input Keys */ -typedef enum { - InputKeyUp, - InputKeyDown, - InputKeyRight, - InputKeyLeft, - InputKeyOk, - InputKeyBack, -} InputKey; - -/* Light */ -typedef enum { - LightRed, - LightGreen, - LightBlue, - LightBacklight, -} Light; - -#ifdef __cplusplus -} -#endif diff --git a/bootloader/targets/f6/api-hal/api-hal.c b/bootloader/targets/f6/api-hal/api-hal.c deleted file mode 100644 index 2d3afc71574..00000000000 --- a/bootloader/targets/f6/api-hal/api-hal.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -void api_hal_init() { - api_hal_i2c_init(); - api_hal_light_init(); -} \ No newline at end of file diff --git a/bootloader/targets/f6/api-hal/api-hal.h b/bootloader/targets/f6/api-hal/api-hal.h deleted file mode 100644 index 9230b28ab39..00000000000 --- a/bootloader/targets/f6/api-hal/api-hal.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include -#include - -void api_hal_init(); \ No newline at end of file diff --git a/bootloader/targets/f6/furi-hal/furi-hal-gpio.c b/bootloader/targets/f6/furi-hal/furi-hal-gpio.c new file mode 100644 index 00000000000..ec926d77c99 --- /dev/null +++ b/bootloader/targets/f6/furi-hal/furi-hal-gpio.c @@ -0,0 +1,189 @@ +#include +#include +#include + +#define GET_SYSCFG_EXTI_PORT(gpio) \ + (((gpio) == (GPIOA)) ? LL_SYSCFG_EXTI_PORTA : \ + ((gpio) == (GPIOB)) ? LL_SYSCFG_EXTI_PORTB : \ + ((gpio) == (GPIOC)) ? LL_SYSCFG_EXTI_PORTC : \ + ((gpio) == (GPIOD)) ? LL_SYSCFG_EXTI_PORTD : \ + ((gpio) == (GPIOE)) ? LL_SYSCFG_EXTI_PORTE : \ + LL_SYSCFG_EXTI_PORTH) + +#define GPIO_PIN_MAP(pin, prefix) \ + (((pin) == (LL_GPIO_PIN_0)) ? prefix##0 : \ + ((pin) == (LL_GPIO_PIN_1)) ? prefix##1 : \ + ((pin) == (LL_GPIO_PIN_2)) ? prefix##2 : \ + ((pin) == (LL_GPIO_PIN_3)) ? prefix##3 : \ + ((pin) == (LL_GPIO_PIN_4)) ? prefix##4 : \ + ((pin) == (LL_GPIO_PIN_5)) ? prefix##5 : \ + ((pin) == (LL_GPIO_PIN_6)) ? prefix##6 : \ + ((pin) == (LL_GPIO_PIN_7)) ? prefix##7 : \ + ((pin) == (LL_GPIO_PIN_8)) ? prefix##8 : \ + ((pin) == (LL_GPIO_PIN_9)) ? prefix##9 : \ + ((pin) == (LL_GPIO_PIN_10)) ? prefix##10 : \ + ((pin) == (LL_GPIO_PIN_11)) ? prefix##11 : \ + ((pin) == (LL_GPIO_PIN_12)) ? prefix##12 : \ + ((pin) == (LL_GPIO_PIN_13)) ? prefix##13 : \ + ((pin) == (LL_GPIO_PIN_14)) ? prefix##14 : \ + prefix##15) + +#define GET_SYSCFG_EXTI_LINE(pin) GPIO_PIN_MAP(pin, LL_SYSCFG_EXTI_LINE) +#define GET_EXTI_LINE(pin) GPIO_PIN_MAP(pin, LL_EXTI_LINE_) + +static volatile GpioInterrupt gpio_interrupt[GPIO_NUMBER]; + +static uint8_t hal_gpio_get_pin_num(const GpioPin* gpio) { + uint8_t pin_num = 0; + for(pin_num = 0; pin_num < GPIO_NUMBER; pin_num++) { + if(gpio->pin & (1 << pin_num)) break; + } + return pin_num; +} + +void hal_gpio_init_simple(const GpioPin* gpio, const GpioMode mode) { + hal_gpio_init(gpio, mode, GpioPullNo, GpioSpeedLow); +} + +void hal_gpio_init( + const GpioPin* gpio, + const GpioMode mode, + const GpioPull pull, + const GpioSpeed speed) { + // we cannot set alternate mode in this function + assert(mode != GpioModeAltFunctionPushPull); + assert(mode != GpioModeAltFunctionOpenDrain); + + hal_gpio_init_ex(gpio, mode, pull, speed, GpioAltFnUnused); +} + +void hal_gpio_init_ex( + const GpioPin* gpio, + const GpioMode mode, + const GpioPull pull, + const GpioSpeed speed, + const GpioAltFn alt_fn) { + uint32_t sys_exti_port = GET_SYSCFG_EXTI_PORT(gpio->port); + uint32_t sys_exti_line = GET_SYSCFG_EXTI_LINE(gpio->pin); + uint32_t exti_line = GET_EXTI_LINE(gpio->pin); + + // Configure gpio with interrupts disabled + __disable_irq(); + // Set gpio speed + if(speed == GpioSpeedLow) { + LL_GPIO_SetPinSpeed(gpio->port, gpio->pin, LL_GPIO_SPEED_FREQ_LOW); + } else if(speed == GpioSpeedMedium) { + LL_GPIO_SetPinSpeed(gpio->port, gpio->pin, LL_GPIO_SPEED_FREQ_MEDIUM); + } else if(speed == GpioSpeedHigh) { + LL_GPIO_SetPinSpeed(gpio->port, gpio->pin, LL_GPIO_SPEED_FREQ_HIGH); + } else { + LL_GPIO_SetPinSpeed(gpio->port, gpio->pin, LL_GPIO_SPEED_FREQ_VERY_HIGH); + } + // Set gpio pull mode + if(pull == GpioPullNo) { + LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_NO); + } else if(pull == GpioPullUp) { + LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_UP); + } else { + LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_DOWN); + } + // Set gpio mode + if(mode >= GpioModeInterruptRise) { + // Set pin in interrupt mode + LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_INPUT); + LL_SYSCFG_SetEXTISource(sys_exti_port, sys_exti_line); + if(mode == GpioModeInterruptRise || mode == GpioModeInterruptRiseFall) { + LL_EXTI_EnableIT_0_31(exti_line); + LL_EXTI_EnableRisingTrig_0_31(exti_line); + } + if(mode == GpioModeInterruptFall || mode == GpioModeInterruptRiseFall) { + LL_EXTI_EnableIT_0_31(exti_line); + LL_EXTI_EnableFallingTrig_0_31(exti_line); + } + if(mode == GpioModeEventRise || mode == GpioModeInterruptRiseFall) { + LL_EXTI_EnableEvent_0_31(exti_line); + LL_EXTI_EnableRisingTrig_0_31(exti_line); + } + if(mode == GpioModeEventFall || mode == GpioModeInterruptRiseFall) { + LL_EXTI_EnableEvent_0_31(exti_line); + LL_EXTI_EnableFallingTrig_0_31(exti_line); + } + } else { + // Disable interrupt if it was set + if(LL_SYSCFG_GetEXTISource(sys_exti_line) == sys_exti_port && + LL_EXTI_IsEnabledIT_0_31(exti_line)) { + LL_EXTI_DisableIT_0_31(exti_line); + LL_EXTI_DisableRisingTrig_0_31(exti_line); + LL_EXTI_DisableFallingTrig_0_31(exti_line); + } + // Set not interrupt pin modes + if(mode == GpioModeInput) { + LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_INPUT); + } else if(mode == GpioModeOutputPushPull || mode == GpioModeAltFunctionPushPull) { + LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_OUTPUT); + LL_GPIO_SetPinOutputType(gpio->port, gpio->pin, LL_GPIO_OUTPUT_PUSHPULL); + } else if(mode == GpioModeOutputOpenDrain || mode == GpioModeAltFunctionOpenDrain) { + LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_OUTPUT); + LL_GPIO_SetPinOutputType(gpio->port, gpio->pin, LL_GPIO_OUTPUT_OPENDRAIN); + } else if(mode == GpioModeAnalog) { + LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_ANALOG); + } + } + + if(mode == GpioModeAltFunctionPushPull || mode == GpioModeAltFunctionOpenDrain) { + // enable alternate mode + LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_ALTERNATE); + + // set alternate function + if(hal_gpio_get_pin_num(gpio) < 8) { + LL_GPIO_SetAFPin_0_7(gpio->port, gpio->pin, alt_fn); + } else { + LL_GPIO_SetAFPin_8_15(gpio->port, gpio->pin, alt_fn); + } + } + + __enable_irq(); +} + +void hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx) { + assert(gpio); + assert(cb); + + __disable_irq(); + uint8_t pin_num = hal_gpio_get_pin_num(gpio); + gpio_interrupt[pin_num].callback = cb; + gpio_interrupt[pin_num].context = ctx; + gpio_interrupt[pin_num].ready = true; + __enable_irq(); +} + +void hal_gpio_enable_int_callback(const GpioPin* gpio) { + assert(gpio); + + __disable_irq(); + uint8_t pin_num = hal_gpio_get_pin_num(gpio); + if(gpio_interrupt[pin_num].callback) { + gpio_interrupt[pin_num].ready = true; + } + __enable_irq(); +} + +void hal_gpio_disable_int_callback(const GpioPin* gpio) { + assert(gpio); + + __disable_irq(); + uint8_t pin_num = hal_gpio_get_pin_num(gpio); + gpio_interrupt[pin_num].ready = false; + __enable_irq(); +} + +void hal_gpio_remove_int_callback(const GpioPin* gpio) { + assert(gpio); + + __disable_irq(); + uint8_t pin_num = hal_gpio_get_pin_num(gpio); + gpio_interrupt[pin_num].callback = NULL; + gpio_interrupt[pin_num].context = NULL; + gpio_interrupt[pin_num].ready = false; + __enable_irq(); +} diff --git a/firmware/targets/f6/api-hal/api-hal-gpio.h b/bootloader/targets/f6/furi-hal/furi-hal-gpio.h similarity index 100% rename from firmware/targets/f6/api-hal/api-hal-gpio.h rename to bootloader/targets/f6/furi-hal/furi-hal-gpio.h diff --git a/bootloader/targets/f6/api-hal/api-hal-i2c.c b/bootloader/targets/f6/furi-hal/furi-hal-i2c.c similarity index 92% rename from bootloader/targets/f6/api-hal/api-hal-i2c.c rename to bootloader/targets/f6/furi-hal/furi-hal-i2c.c index 2ff0b8e987c..c40a70af971 100644 --- a/bootloader/targets/f6/api-hal/api-hal-i2c.c +++ b/bootloader/targets/f6/furi-hal/furi-hal-i2c.c @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -6,7 +6,7 @@ #include #include -void api_hal_i2c_init() { +void furi_hal_i2c_init() { LL_I2C_InitTypeDef I2C_InitStruct = {0}; LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; @@ -38,7 +38,7 @@ void api_hal_i2c_init() { LL_I2C_EnableClockStretching(I2C1); } -bool api_hal_i2c_tx( +bool furi_hal_i2c_tx( I2C_TypeDef* instance, uint8_t address, const uint8_t* data, @@ -79,7 +79,7 @@ bool api_hal_i2c_tx( return ret; } -bool api_hal_i2c_rx( +bool furi_hal_i2c_rx( I2C_TypeDef* instance, uint8_t address, uint8_t* data, @@ -120,7 +120,7 @@ bool api_hal_i2c_rx( return ret; } -bool api_hal_i2c_trx( +bool furi_hal_i2c_trx( I2C_TypeDef* instance, uint8_t address, const uint8_t* tx_data, @@ -128,8 +128,8 @@ bool api_hal_i2c_trx( uint8_t* rx_data, uint8_t rx_size, uint32_t timeout) { - if(api_hal_i2c_tx(instance, address, tx_data, tx_size, timeout) && - api_hal_i2c_rx(instance, address, rx_data, rx_size, timeout)) { + if(furi_hal_i2c_tx(instance, address, tx_data, tx_size, timeout) && + furi_hal_i2c_rx(instance, address, rx_data, rx_size, timeout)) { return true; } else { return false; diff --git a/bootloader/targets/f6/api-hal/api-hal-i2c.h b/bootloader/targets/f6/furi-hal/furi-hal-i2c.h similarity index 78% rename from bootloader/targets/f6/api-hal/api-hal-i2c.h rename to bootloader/targets/f6/furi-hal/furi-hal-i2c.h index 835693a6e6c..5db562e05f9 100644 --- a/bootloader/targets/f6/api-hal/api-hal-i2c.h +++ b/bootloader/targets/f6/furi-hal/furi-hal-i2c.h @@ -2,29 +2,29 @@ #include #include -#include +#include #ifdef __cplusplus extern "C" { #endif -void api_hal_i2c_init(); +void furi_hal_i2c_init(); -bool api_hal_i2c_tx( +bool furi_hal_i2c_tx( I2C_TypeDef* instance, const uint8_t address, const uint8_t* data, const uint8_t size, uint32_t timeout); -bool api_hal_i2c_rx( +bool furi_hal_i2c_rx( I2C_TypeDef* instance, const uint8_t address, uint8_t* data, const uint8_t size, uint32_t timeout); -bool api_hal_i2c_trx( +bool furi_hal_i2c_trx( I2C_TypeDef* instance, const uint8_t address, const uint8_t* tx_data, @@ -33,7 +33,7 @@ bool api_hal_i2c_trx( const uint8_t rx_size, uint32_t timeout); -#define with_api_hal_i2c(type, pointer, function_body) \ +#define with_furi_hal_i2c(type, pointer, function_body) \ { \ *pointer = ({ type __fn__ function_body __fn__; })(); \ } diff --git a/bootloader/targets/f6/api-hal/api-hal-light.c b/bootloader/targets/f6/furi-hal/furi-hal-light.c similarity index 91% rename from bootloader/targets/f6/api-hal/api-hal-light.c rename to bootloader/targets/f6/furi-hal/furi-hal-light.c index 425018a18a4..d5f54f6d112 100644 --- a/bootloader/targets/f6/api-hal/api-hal-light.c +++ b/bootloader/targets/f6/furi-hal/furi-hal-light.c @@ -1,4 +1,4 @@ -#include +#include #include #define LED_CURRENT_RED 50 @@ -6,7 +6,7 @@ #define LED_CURRENT_BLUE 50 #define LED_CURRENT_WHITE 150 -void api_hal_light_init() { +void furi_hal_light_init() { lp5562_reset(); lp5562_set_channel_current(LP5562ChannelRed, LED_CURRENT_RED); @@ -23,7 +23,7 @@ void api_hal_light_init() { lp5562_configure(); } -void api_hal_light_set(Light light, uint8_t value) { +void furi_hal_light_set(Light light, uint8_t value) { switch(light) { case LightRed: lp5562_set_channel_value(LP5562ChannelRed, value); diff --git a/bootloader/targets/f6/api-hal/api-hal-light.h b/bootloader/targets/f6/furi-hal/furi-hal-light.h similarity index 52% rename from bootloader/targets/f6/api-hal/api-hal-light.h rename to bootloader/targets/f6/furi-hal/furi-hal-light.h index 1d571f06f08..de9761033ae 100644 --- a/bootloader/targets/f6/api-hal/api-hal-light.h +++ b/bootloader/targets/f6/furi-hal/furi-hal-light.h @@ -2,15 +2,15 @@ #include #include -#include +#include #ifdef __cplusplus extern "C" { #endif -void api_hal_light_init(); +void furi_hal_light_init(); -void api_hal_light_set(Light light, uint8_t value); +void furi_hal_light_set(Light light, uint8_t value); #ifdef __cplusplus } diff --git a/bootloader/targets/f6/furi-hal/furi-hal-resources.c b/bootloader/targets/f6/furi-hal/furi-hal-resources.c new file mode 100644 index 00000000000..1260a485ab0 --- /dev/null +++ b/bootloader/targets/f6/furi-hal/furi-hal-resources.c @@ -0,0 +1,41 @@ +#include "furi-hal-resources.h" +#include "main.h" + +const GpioPin vibro_gpio = {.port = VIBRO_GPIO_Port, .pin = VIBRO_Pin}; +const GpioPin ibutton_gpio = {.port = iBTN_GPIO_Port, .pin = iBTN_Pin}; + +const GpioPin gpio_cc1101_g0 = {.port = CC1101_G0_GPIO_Port, .pin = CC1101_G0_Pin}; +const GpioPin gpio_rf_sw_0 = {.port = RF_SW_0_GPIO_Port, .pin = RF_SW_0_Pin}; + +const GpioPin gpio_subghz_cs = {.port = CC1101_CS_GPIO_Port, .pin = CC1101_CS_Pin}; +const GpioPin gpio_display_cs = {.port = DISPLAY_CS_GPIO_Port, .pin = DISPLAY_CS_Pin}; +const GpioPin gpio_display_rst = {.port = DISPLAY_RST_GPIO_Port, .pin = DISPLAY_RST_Pin}; +const GpioPin gpio_display_di = {.port = DISPLAY_DI_GPIO_Port, .pin = DISPLAY_DI_Pin}; +const GpioPin gpio_sdcard_cs = {.port = SD_CS_GPIO_Port, .pin = SD_CS_Pin}; +const GpioPin gpio_nfc_cs = {.port = NFC_CS_GPIO_Port, .pin = NFC_CS_Pin}; + +const GpioPin gpio_spi_d_miso = {.port = SPI_D_MISO_GPIO_Port, .pin = SPI_D_MISO_Pin}; +const GpioPin gpio_spi_d_mosi = {.port = SPI_D_MOSI_GPIO_Port, .pin = SPI_D_MOSI_Pin}; +const GpioPin gpio_spi_d_sck = {.port = SPI_D_SCK_GPIO_Port, .pin = SPI_D_SCK_Pin}; +const GpioPin gpio_spi_r_miso = {.port = SPI_R_MISO_GPIO_Port, .pin = SPI_R_MISO_Pin}; +const GpioPin gpio_spi_r_mosi = {.port = SPI_R_MOSI_GPIO_Port, .pin = SPI_R_MOSI_Pin}; +const GpioPin gpio_spi_r_sck = {.port = SPI_R_SCK_GPIO_Port, .pin = SPI_R_SCK_Pin}; + +const GpioPin gpio_ext_pc0 = {.port = GPIOC, .pin = LL_GPIO_PIN_0}; +const GpioPin gpio_ext_pc1 = {.port = GPIOC, .pin = LL_GPIO_PIN_1}; +const GpioPin gpio_ext_pc3 = {.port = GPIOC, .pin = LL_GPIO_PIN_3}; +const GpioPin gpio_ext_pb2 = {.port = GPIOB, .pin = LL_GPIO_PIN_2}; +const GpioPin gpio_ext_pb3 = {.port = GPIOB, .pin = LL_GPIO_PIN_3}; +const GpioPin gpio_ext_pa4 = {.port = GPIOA, .pin = LL_GPIO_PIN_4}; +const GpioPin gpio_ext_pa6 = {.port = GPIOA, .pin = LL_GPIO_PIN_6}; +const GpioPin gpio_ext_pa7 = {.port = GPIOA, .pin = LL_GPIO_PIN_7}; + +const GpioPin gpio_rfid_pull = {.port = RFID_PULL_GPIO_Port, .pin = RFID_PULL_Pin}; +const GpioPin gpio_rfid_carrier_out = {.port = RFID_OUT_GPIO_Port, .pin = RFID_OUT_Pin}; +const GpioPin gpio_rfid_data_in = {.port = RFID_RF_IN_GPIO_Port, .pin = RFID_RF_IN_Pin}; + +const GpioPin gpio_irda_rx = {.port = IR_RX_GPIO_Port, .pin = IR_RX_Pin}; +const GpioPin gpio_irda_tx = {.port = IR_TX_GPIO_Port, .pin = IR_TX_Pin}; + +const GpioPin gpio_usart_tx = {.port = USART1_TX_Port, .pin = USART1_TX_Pin}; +const GpioPin gpio_usart_rx = {.port = USART1_RX_Port, .pin = USART1_RX_Pin}; diff --git a/bootloader/targets/f6/furi-hal/furi-hal-resources.h b/bootloader/targets/f6/furi-hal/furi-hal-resources.h new file mode 100644 index 00000000000..95bb4d0d7fd --- /dev/null +++ b/bootloader/targets/f6/furi-hal/furi-hal-resources.h @@ -0,0 +1,82 @@ +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define POWER_I2C_SCL_Pin LL_GPIO_PIN_9 +#define POWER_I2C_SCL_GPIO_Port GPIOA +#define POWER_I2C_SDA_Pin LL_GPIO_PIN_10 +#define POWER_I2C_SDA_GPIO_Port GPIOA + +#define POWER_I2C I2C1 +/* Timing register value is computed with the STM32CubeMX Tool, + * Fast Mode @100kHz with I2CCLK = 64 MHz, + * rise time = 0ns, fall time = 0ns + */ +#define POWER_I2C_TIMINGS 0x10707DBC + +/* Input Keys */ +typedef enum { + InputKeyUp, + InputKeyDown, + InputKeyRight, + InputKeyLeft, + InputKeyOk, + InputKeyBack, +} InputKey; + +/* Light */ +typedef enum { + LightRed, + LightGreen, + LightBlue, + LightBacklight, +} Light; + +extern const GpioPin vibro_gpio; +extern const GpioPin ibutton_gpio; + +extern const GpioPin gpio_cc1101_g0; +extern const GpioPin gpio_rf_sw_0; + +extern const GpioPin gpio_subghz_cs; +extern const GpioPin gpio_display_cs; +extern const GpioPin gpio_display_rst; +extern const GpioPin gpio_display_di; +extern const GpioPin gpio_sdcard_cs; +extern const GpioPin gpio_nfc_cs; + +extern const GpioPin gpio_spi_d_miso; +extern const GpioPin gpio_spi_d_mosi; +extern const GpioPin gpio_spi_d_sck; +extern const GpioPin gpio_spi_r_miso; +extern const GpioPin gpio_spi_r_mosi; +extern const GpioPin gpio_spi_r_sck; + +extern const GpioPin gpio_ext_pc0; +extern const GpioPin gpio_ext_pc1; +extern const GpioPin gpio_ext_pc3; +extern const GpioPin gpio_ext_pb2; +extern const GpioPin gpio_ext_pb3; +extern const GpioPin gpio_ext_pa4; +extern const GpioPin gpio_ext_pa6; +extern const GpioPin gpio_ext_pa7; + +extern const GpioPin gpio_rfid_pull; +extern const GpioPin gpio_rfid_carrier_out; +extern const GpioPin gpio_rfid_data_in; + +extern const GpioPin gpio_irda_rx; +extern const GpioPin gpio_irda_tx; + +extern const GpioPin gpio_usart_tx; +extern const GpioPin gpio_usart_rx; + +#ifdef __cplusplus +} +#endif diff --git a/bootloader/targets/f6/furi-hal/furi-hal-spi-config.c b/bootloader/targets/f6/furi-hal/furi-hal-spi-config.c new file mode 100644 index 00000000000..00b06a4f925 --- /dev/null +++ b/bootloader/targets/f6/furi-hal/furi-hal-spi-config.c @@ -0,0 +1,114 @@ +#include +#include + +#define SPI_R SPI1 +#define SPI_D SPI2 + +const LL_SPI_InitTypeDef furi_hal_spi_config_nfc = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_2EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +const LL_SPI_InitTypeDef furi_hal_spi_config_subghz = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_1EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +const LL_SPI_InitTypeDef furi_hal_spi_config_display = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_1EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV16, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +/** + * SD Card in fast mode (after init) + */ +const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_1EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +/** + * SD Card in slow mode (before init) + */ +const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_1EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV32, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +const FuriHalSpiBus spi_r = { + .spi = SPI_R, + .miso = &gpio_spi_r_miso, + .mosi = &gpio_spi_r_mosi, + .clk = &gpio_spi_r_sck, +}; + +const FuriHalSpiBus spi_d = { + .spi = SPI_D, + .miso = &gpio_spi_d_miso, + .mosi = &gpio_spi_d_mosi, + .clk = &gpio_spi_d_sck, +}; + +const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax] = { + { + .bus = &spi_r, + .config = &furi_hal_spi_config_subghz, + .chip_select = &gpio_subghz_cs, + }, + { + .bus = &spi_d, + .config = &furi_hal_spi_config_display, + .chip_select = &gpio_display_cs, + }, + { + .bus = &spi_d, + .config = &furi_hal_spi_config_sd_fast, + .chip_select = &gpio_sdcard_cs, + }, + { + .bus = &spi_d, + .config = &furi_hal_spi_config_sd_slow, + .chip_select = &gpio_sdcard_cs, + }, + {.bus = &spi_r, .config = &furi_hal_spi_config_nfc, .chip_select = &gpio_nfc_cs}, +}; diff --git a/bootloader/targets/f6/furi-hal/furi-hal-spi-config.h b/bootloader/targets/f6/furi-hal/furi-hal-spi-config.h new file mode 100644 index 00000000000..dea1cd654e9 --- /dev/null +++ b/bootloader/targets/f6/furi-hal/furi-hal-spi-config.h @@ -0,0 +1,61 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern const LL_SPI_InitTypeDef furi_hal_spi_config_nfc; +extern const LL_SPI_InitTypeDef furi_hal_spi_config_subghz; +extern const LL_SPI_InitTypeDef furi_hal_spi_config_display; +extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast; +extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow; + +/** FURI HAL SPI BUS handler + * Structure content may change at some point + */ +typedef struct { + const SPI_TypeDef* spi; + const GpioPin* miso; + const GpioPin* mosi; + const GpioPin* clk; +} FuriHalSpiBus; + +/** FURI HAL SPI Device handler + * Structure content may change at some point + */ +typedef struct { + const FuriHalSpiBus* bus; + const LL_SPI_InitTypeDef* config; + const GpioPin* chip_select; +} FuriHalSpiDevice; + +/** FURI HAL SPI Standard Device IDs */ +typedef enum { + FuriHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ + FuriHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ + FuriHalSpiDeviceIdSdCardFast, /** SDCARD: fast mode, after initialization */ + FuriHalSpiDeviceIdSdCardSlow, /** SDCARD: slow mode, before initialization */ + FuriHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ + + FuriHalSpiDeviceIdMax, /** Service Value, do not use */ +} FuriHalSpiDeviceId; + +/** Furi Hal Spi Bus R + * CC1101, Nfc + */ +extern const FuriHalSpiBus spi_r; + +/** Furi Hal Spi Bus D + * Display, SdCard + */ +extern const FuriHalSpiBus spi_d; + +/** Furi Hal Spi devices */ +extern const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax]; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/bootloader/targets/f6/furi-hal/furi-hal-spi.c b/bootloader/targets/f6/furi-hal/furi-hal-spi.c new file mode 100644 index 00000000000..e36e9230b39 --- /dev/null +++ b/bootloader/targets/f6/furi-hal/furi-hal-spi.c @@ -0,0 +1,240 @@ +#include "furi-hal-spi.h" +#include "furi-hal-resources.h" + +#include +#include + +#include +#include +#include + +extern void Enable_SPI(SPI_TypeDef* spi); + +void furi_hal_spi_init() { + for(size_t i = 0; i < FuriHalSpiDeviceIdMax; ++i) { + hal_gpio_write(furi_hal_spi_devices[i].chip_select, true); + hal_gpio_init( + furi_hal_spi_devices[i].chip_select, + GpioModeOutputPushPull, + GpioPullNo, + GpioSpeedVeryHigh); + } + + hal_gpio_init_ex( + &gpio_spi_r_miso, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI1); + hal_gpio_init_ex( + &gpio_spi_r_mosi, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI1); + hal_gpio_init_ex( + &gpio_spi_r_sck, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI1); + + hal_gpio_init_ex( + &gpio_spi_d_miso, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn5SPI2); + hal_gpio_init_ex( + &gpio_spi_d_mosi, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn5SPI2); + hal_gpio_init_ex( + &gpio_spi_d_sck, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn5SPI2); +} + +void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus) { + assert(bus); +} + +void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus) { + assert(bus); +} + +void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config) { + assert(bus); + LL_SPI_DeInit((SPI_TypeDef*)bus->spi); + LL_SPI_Init((SPI_TypeDef*)bus->spi, (LL_SPI_InitTypeDef*)config); + LL_SPI_SetRxFIFOThreshold((SPI_TypeDef*)bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable((SPI_TypeDef*)bus->spi); +} + +void furi_hal_spi_bus_end_txrx(const FuriHalSpiBus* bus, uint32_t timeout) { + while(LL_SPI_GetTxFIFOLevel((SPI_TypeDef*)bus->spi) != LL_SPI_TX_FIFO_EMPTY) + ; + while(LL_SPI_IsActiveFlag_BSY((SPI_TypeDef*)bus->spi)) + ; + while(LL_SPI_GetRxFIFOLevel((SPI_TypeDef*)bus->spi) != LL_SPI_RX_FIFO_EMPTY) { + LL_SPI_ReceiveData8((SPI_TypeDef*)bus->spi); + } +} + +bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { + assert(bus); + assert(buffer); + assert(size > 0); + + return furi_hal_spi_bus_trx(bus, buffer, buffer, size, timeout); +} + +bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { + assert(bus); + assert(buffer); + assert(size > 0); + bool ret = true; + + while(size > 0) { + if(LL_SPI_IsActiveFlag_TXE((SPI_TypeDef*)bus->spi)) { + LL_SPI_TransmitData8((SPI_TypeDef*)bus->spi, *buffer); + buffer++; + size--; + } + } + + furi_hal_spi_bus_end_txrx(bus, timeout); + LL_SPI_ClearFlag_OVR((SPI_TypeDef*)bus->spi); + + return ret; +} + +bool furi_hal_spi_bus_trx( + const FuriHalSpiBus* bus, + uint8_t* tx_buffer, + uint8_t* rx_buffer, + size_t size, + uint32_t timeout) { + assert(bus); + assert(tx_buffer); + assert(rx_buffer); + assert(size > 0); + bool ret = true; + size_t tx_size = size; + bool tx_allowed = true; + + while(size > 0) { + if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE((SPI_TypeDef*)bus->spi) && tx_allowed) { + LL_SPI_TransmitData8((SPI_TypeDef*)bus->spi, *tx_buffer); + tx_buffer++; + tx_size--; + tx_allowed = false; + } + + if(LL_SPI_IsActiveFlag_RXNE((SPI_TypeDef*)bus->spi)) { + *rx_buffer = LL_SPI_ReceiveData8((SPI_TypeDef*)bus->spi); + rx_buffer++; + size--; + tx_allowed = true; + } + } + + furi_hal_spi_bus_end_txrx(bus, timeout); + + return ret; +} + +void furi_hal_spi_device_configure(const FuriHalSpiDevice* device) { + assert(device); + assert(device->config); + + furi_hal_spi_bus_configure(device->bus, device->config); +} + +const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id) { + assert(device_id < FuriHalSpiDeviceIdMax); + + const FuriHalSpiDevice* device = &furi_hal_spi_devices[device_id]; + assert(device); + + furi_hal_spi_bus_lock(device->bus); + furi_hal_spi_device_configure(device); + + return device; +} + +void furi_hal_spi_device_return(const FuriHalSpiDevice* device) { + furi_hal_spi_bus_unlock(device->bus); +} + +bool furi_hal_spi_device_rx( + const FuriHalSpiDevice* device, + uint8_t* buffer, + size_t size, + uint32_t timeout) { + assert(device); + assert(buffer); + assert(size > 0); + + if(device->chip_select) { + hal_gpio_write(device->chip_select, false); + } + + bool ret = furi_hal_spi_bus_rx(device->bus, buffer, size, timeout); + + if(device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; +} + +bool furi_hal_spi_device_tx( + const FuriHalSpiDevice* device, + uint8_t* buffer, + size_t size, + uint32_t timeout) { + assert(device); + assert(buffer); + assert(size > 0); + + if(device->chip_select) { + hal_gpio_write(device->chip_select, false); + } + + bool ret = furi_hal_spi_bus_tx(device->bus, buffer, size, timeout); + + if(device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; +} + +bool furi_hal_spi_device_trx( + const FuriHalSpiDevice* device, + uint8_t* tx_buffer, + uint8_t* rx_buffer, + size_t size, + uint32_t timeout) { + assert(device); + assert(tx_buffer); + assert(rx_buffer); + assert(size > 0); + + if(device->chip_select) { + hal_gpio_write(device->chip_select, false); + } + + bool ret = furi_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, timeout); + + if(device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; +} diff --git a/firmware/targets/f6/api-hal/api-hal-spi.h b/bootloader/targets/f6/furi-hal/furi-hal-spi.h similarity index 56% rename from firmware/targets/f6/api-hal/api-hal-spi.h rename to bootloader/targets/f6/furi-hal/furi-hal-spi.h index 849bcf5a44b..8027eb5d7b8 100644 --- a/firmware/targets/f6/api-hal/api-hal-spi.h +++ b/bootloader/targets/f6/furi-hal/furi-hal-spi.h @@ -1,8 +1,12 @@ #pragma once + #include "main.h" -#include "api-hal-spi-config.h" -#include + +#include "furi-hal-spi-config.h" +#include + #include +#include #ifdef __cplusplus extern "C" { @@ -11,32 +15,26 @@ extern "C" { /** * Init SPI API */ -void api_hal_spi_init(); +void furi_hal_spi_init(); /* Bus Level API */ /** Lock SPI bus * Takes bus mutex, if used */ -void api_hal_spi_bus_lock(const ApiHalSpiBus* bus); +void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus); /** Unlock SPI bus * Releases BUS mutex, if used */ -void api_hal_spi_bus_unlock(const ApiHalSpiBus* bus); +void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus); /** * Configure SPI bus * @param bus - spi bus handler * @param config - spi configuration structure */ -void api_hal_spi_bus_configure(const ApiHalSpiBus* bus, const SPI_InitTypeDef* config); - -/** - * Reset SPI bus - * @param bus - spi bus handler - */ -void api_hal_spi_bus_reset(const ApiHalSpiBus* bus); +void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config); /** SPI Receive * @param bus - spi bus handler @@ -44,7 +42,7 @@ void api_hal_spi_bus_reset(const ApiHalSpiBus* bus); * @param size - transaction size * @param timeout - bus operation timeout in ms */ -bool api_hal_spi_bus_rx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); +bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); /** SPI Transmit * @param bus - spi bus handler @@ -52,7 +50,7 @@ bool api_hal_spi_bus_rx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, u * @param size - transaction size * @param timeout - bus operation timeout in ms */ -bool api_hal_spi_bus_tx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); +bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); /** SPI Transmit and Receive * @param bus - spi bus handlere @@ -61,22 +59,32 @@ bool api_hal_spi_bus_tx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, u * @param size - transaction size * @param timeout - bus operation timeout in ms */ -bool api_hal_spi_bus_trx(const ApiHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); +bool furi_hal_spi_bus_trx( + const FuriHalSpiBus* bus, + uint8_t* tx_buffer, + uint8_t* rx_buffer, + size_t size, + uint32_t timeout); /* Device Level API */ +/** Reconfigure SPI bus for device + * @param device - device description + */ +void furi_hal_spi_device_configure(const FuriHalSpiDevice* device); + /** Get Device handle * And lock access to the corresponding SPI BUS * @param device_id - device identifier * @return device handle */ -const ApiHalSpiDevice* api_hal_spi_device_get(ApiHalSpiDeviceId device_id); +const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id); /** Return Device handle * And unlock access to the corresponding SPI BUS * @param device - device handle */ -void api_hal_spi_device_return(const ApiHalSpiDevice* device); +void furi_hal_spi_device_return(const FuriHalSpiDevice* device); /** SPI Recieve * @param device - device handle @@ -84,7 +92,11 @@ void api_hal_spi_device_return(const ApiHalSpiDevice* device); * @param size - transaction size * @param timeout - bus operation timeout in ms */ -bool api_hal_spi_device_rx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout); +bool furi_hal_spi_device_rx( + const FuriHalSpiDevice* device, + uint8_t* buffer, + size_t size, + uint32_t timeout); /** SPI Transmit * @param device - device handle @@ -92,7 +104,11 @@ bool api_hal_spi_device_rx(const ApiHalSpiDevice* device, uint8_t* buffer, size_ * @param size - transaction size * @param timeout - bus operation timeout in ms */ -bool api_hal_spi_device_tx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout); +bool furi_hal_spi_device_tx( + const FuriHalSpiDevice* device, + uint8_t* buffer, + size_t size, + uint32_t timeout); /** SPI Transmit and Receive * @param device - device handle @@ -101,18 +117,12 @@ bool api_hal_spi_device_tx(const ApiHalSpiDevice* device, uint8_t* buffer, size_ * @param size - transaction size * @param timeout - bus operation timeout in ms */ -bool api_hal_spi_device_trx(const ApiHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); - - -/** - * Lock SPI device bus and apply config if needed - */ -void api_hal_spi_lock_device(const SPIDevice* device); - -/** - * Unlock SPI device bus - */ -void api_hal_spi_unlock_device(const SPIDevice* device); +bool furi_hal_spi_device_trx( + const FuriHalSpiDevice* device, + uint8_t* tx_buffer, + uint8_t* rx_buffer, + size_t size, + uint32_t timeout); #ifdef __cplusplus } diff --git a/bootloader/targets/f6/furi-hal/furi-hal.c b/bootloader/targets/f6/furi-hal/furi-hal.c new file mode 100644 index 00000000000..e0521cc9ebb --- /dev/null +++ b/bootloader/targets/f6/furi-hal/furi-hal.c @@ -0,0 +1,7 @@ +#include + +void furi_hal_init() { + furi_hal_i2c_init(); + furi_hal_light_init(); + furi_hal_spi_init(); +} \ No newline at end of file diff --git a/bootloader/targets/f6/furi-hal/furi-hal.h b/bootloader/targets/f6/furi-hal/furi-hal.h new file mode 100644 index 00000000000..9e60092f9a9 --- /dev/null +++ b/bootloader/targets/f6/furi-hal/furi-hal.h @@ -0,0 +1,8 @@ +#pragma once + +#include +#include +#include +#include + +void furi_hal_init(); \ No newline at end of file diff --git a/bootloader/targets/f6/furi-hal/main.h b/bootloader/targets/f6/furi-hal/main.h new file mode 100644 index 00000000000..1c453c5755f --- /dev/null +++ b/bootloader/targets/f6/furi-hal/main.h @@ -0,0 +1,108 @@ +#pragma once + +#include +#include +#include + +#define BUTTON_BACK_GPIO_Port GPIOC +#define BUTTON_BACK_Pin LL_GPIO_PIN_13 +#define BUTTON_DOWN_GPIO_Port GPIOC +#define BUTTON_DOWN_Pin LL_GPIO_PIN_6 +#define BUTTON_LEFT_GPIO_Port GPIOB +#define BUTTON_LEFT_Pin LL_GPIO_PIN_11 +#define BUTTON_OK_GPIO_Port GPIOH +#define BUTTON_OK_Pin LL_GPIO_PIN_3 +#define BUTTON_RIGHT_GPIO_Port GPIOB +#define BUTTON_RIGHT_Pin LL_GPIO_PIN_12 +#define BUTTON_UP_GPIO_Port GPIOB +#define BUTTON_UP_Pin LL_GPIO_PIN_10 + +#define CC1101_CS_GPIO_Port GPIOD +#define CC1101_CS_Pin LL_GPIO_PIN_0 +#define CC1101_G0_GPIO_Port GPIOA +#define CC1101_G0_Pin LL_GPIO_PIN_1 + +#define DISPLAY_CS_GPIO_Port GPIOC +#define DISPLAY_CS_Pin LL_GPIO_PIN_11 +#define DISPLAY_DI_GPIO_Port GPIOB +#define DISPLAY_DI_Pin LL_GPIO_PIN_1 +#define DISPLAY_RST_GPIO_Port GPIOB +#define DISPLAY_RST_Pin LL_GPIO_PIN_0 + +#define IR_RX_GPIO_Port GPIOA +#define IR_RX_Pin LL_GPIO_PIN_0 +#define IR_TX_GPIO_Port GPIOB +#define IR_TX_Pin LL_GPIO_PIN_9 + +#define NFC_CS_GPIO_Port GPIOE +#define NFC_CS_Pin LL_GPIO_PIN_4 + +#define PA4_GPIO_Port GPIOA +#define PA4_Pin LL_GPIO_PIN_4 +#define PA6_GPIO_Port GPIOA +#define PA6_Pin LL_GPIO_PIN_6 +#define PA7_GPIO_Port GPIOA +#define PA7_Pin LL_GPIO_PIN_7 +#define PB2_GPIO_Port GPIOB +#define PB2_Pin LL_GPIO_PIN_2 +#define PB3_GPIO_Port GPIOB +#define PB3_Pin LL_GPIO_PIN_3 +#define PC0_GPIO_Port GPIOC +#define PC0_Pin LL_GPIO_PIN_0 +#define PC1_GPIO_Port GPIOC +#define PC1_Pin LL_GPIO_PIN_1 +#define PC3_GPIO_Port GPIOC +#define PC3_Pin LL_GPIO_PIN_3 + +#define PERIPH_POWER_GPIO_Port GPIOA +#define PERIPH_POWER_Pin LL_GPIO_PIN_3 + +#define QUARTZ_32MHZ_IN_GPIO_Port GPIOC +#define QUARTZ_32MHZ_IN_Pin LL_GPIO_PIN_14 +#define QUARTZ_32MHZ_OUT_GPIO_Port GPIOC +#define QUARTZ_32MHZ_OUT_Pin LL_GPIO_PIN_15 + +#define RFID_OUT_GPIO_Port GPIOB +#define RFID_OUT_Pin LL_GPIO_PIN_13 +#define RFID_PULL_GPIO_Port GPIOA +#define RFID_PULL_Pin LL_GPIO_PIN_2 +#define RFID_RF_IN_GPIO_Port GPIOC +#define RFID_RF_IN_Pin LL_GPIO_PIN_5 +#define RFID_TUNE_GPIO_Port GPIOA +#define RFID_TUNE_Pin LL_GPIO_PIN_8 + +#define RF_SW_0_GPIO_Port GPIOC +#define RF_SW_0_Pin LL_GPIO_PIN_4 + +#define SD_CD_GPIO_Port GPIOC +#define SD_CD_Pin LL_GPIO_PIN_10 +#define SD_CS_GPIO_Port GPIOC +#define SD_CS_Pin LL_GPIO_PIN_12 + +#define SPEAKER_GPIO_Port GPIOB +#define SPEAKER_Pin LL_GPIO_PIN_8 + +#define VIBRO_GPIO_Port GPIOA +#define VIBRO_Pin LL_GPIO_PIN_15 + +#define iBTN_GPIO_Port GPIOB +#define iBTN_Pin LL_GPIO_PIN_14 + +#define USART1_TX_Pin LL_GPIO_PIN_6 +#define USART1_TX_Port GPIOB +#define USART1_RX_Pin LL_GPIO_PIN_7 +#define USART1_RX_Port GPIOB + +#define SPI_D_MISO_GPIO_Port GPIOC +#define SPI_D_MISO_Pin LL_GPIO_PIN_2 +#define SPI_D_MOSI_GPIO_Port GPIOB +#define SPI_D_MOSI_Pin LL_GPIO_PIN_15 +#define SPI_D_SCK_GPIO_Port GPIOD +#define SPI_D_SCK_Pin LL_GPIO_PIN_1 + +#define SPI_R_MISO_GPIO_Port GPIOB +#define SPI_R_MISO_Pin LL_GPIO_PIN_4 +#define SPI_R_MOSI_GPIO_Port GPIOB +#define SPI_R_MOSI_Pin LL_GPIO_PIN_5 +#define SPI_R_SCK_GPIO_Port GPIOA +#define SPI_R_SCK_Pin LL_GPIO_PIN_5 diff --git a/bootloader/targets/f6/furi-hal/u8g2_periphery.c b/bootloader/targets/f6/furi-hal/u8g2_periphery.c new file mode 100644 index 00000000000..a1c153f776a --- /dev/null +++ b/bootloader/targets/f6/furi-hal/u8g2_periphery.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include + +static FuriHalSpiDevice* u8g2_periphery_display = NULL; + +uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { + switch(msg) { + case U8X8_MSG_GPIO_AND_DELAY_INIT: + /* HAL initialization contains all what we need so we can skip this part. */ + break; + + case U8X8_MSG_DELAY_MILLI: + LL_mDelay(arg_int); + break; + + case U8X8_MSG_DELAY_10MICRO: + LL_mDelay(1); + break; + + case U8X8_MSG_DELAY_100NANO: + asm("nop"); + break; + + case U8X8_MSG_GPIO_RESET: + hal_gpio_write(&gpio_display_rst, arg_int); + break; + + default: + return 0; + } + + return 1; +} + +uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { + switch(msg) { + case U8X8_MSG_BYTE_SEND: + furi_hal_spi_bus_tx(u8g2_periphery_display->bus, (uint8_t*)arg_ptr, arg_int, 10000); + break; + + case U8X8_MSG_BYTE_SET_DC: + hal_gpio_write(&gpio_display_di, arg_int); + break; + + case U8X8_MSG_BYTE_INIT: + break; + + case U8X8_MSG_BYTE_START_TRANSFER: + assert(u8g2_periphery_display == NULL); + u8g2_periphery_display = + (FuriHalSpiDevice*)furi_hal_spi_device_get(FuriHalSpiDeviceIdDisplay); + hal_gpio_write(u8g2_periphery_display->chip_select, false); + break; + + case U8X8_MSG_BYTE_END_TRANSFER: + assert(u8g2_periphery_display); + hal_gpio_write(u8g2_periphery_display->chip_select, true); + furi_hal_spi_device_return(u8g2_periphery_display); + u8g2_periphery_display = NULL; + break; + + default: + return 0; + } + + return 1; +} diff --git a/bootloader/targets/f6/target.c b/bootloader/targets/f6/target.c index 761959f3d2b..51dbb672b43 100644 --- a/bootloader/targets/f6/target.c +++ b/bootloader/targets/f6/target.c @@ -10,7 +10,17 @@ #include #include -#include +#include +#include + +const uint8_t I_Warning_30x23_0[] = { + 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xF0, 0x03, 0x00, + 0x00, 0xF8, 0x07, 0x00, 0x00, 0x3C, 0x0F, 0x00, 0x00, 0x3C, 0x0F, 0x00, 0x00, 0x3E, 0x1F, 0x00, + 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x80, 0x3F, 0x7F, 0x00, 0xC0, 0x3F, 0xFF, 0x00, + 0xC0, 0x3F, 0xFF, 0x00, 0xE0, 0x3F, 0xFF, 0x01, 0xF0, 0x3F, 0xFF, 0x03, 0xF0, 0x3F, 0xFF, 0x03, + 0xF8, 0x3F, 0xFF, 0x07, 0xFC, 0xFF, 0xFF, 0x0F, 0xFC, 0xFF, 0xFF, 0x0F, 0xFE, 0x3F, 0xFF, 0x1F, + 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x3F, 0xFE, 0xFF, 0xFF, 0x1F, +}; // Boot request enum #define BOOT_REQUEST_TAINTED 0x00000000 @@ -27,47 +37,57 @@ #define RTC_CLOCK_IS_READY() (LL_RCC_LSE_IsReady() && LL_RCC_LSI1_IsReady()) +uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr); +uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr); + void target_led_control(char* c) { - api_hal_light_set(LightRed, 0x00); - api_hal_light_set(LightGreen, 0x00); - api_hal_light_set(LightBlue, 0x00); + furi_hal_light_set(LightRed, 0x00); + furi_hal_light_set(LightGreen, 0x00); + furi_hal_light_set(LightBlue, 0x00); do { if(*c == 'R') { - api_hal_light_set(LightRed, 0xFF); + furi_hal_light_set(LightRed, 0xFF); } else if(*c == 'G') { - api_hal_light_set(LightGreen, 0xFF); + furi_hal_light_set(LightGreen, 0xFF); } else if(*c == 'B') { - api_hal_light_set(LightBlue, 0xFF); + furi_hal_light_set(LightBlue, 0xFF); } else if(*c == '.') { LL_mDelay(125); - api_hal_light_set(LightRed, 0x00); - api_hal_light_set(LightGreen, 0x00); - api_hal_light_set(LightBlue, 0x00); + furi_hal_light_set(LightRed, 0x00); + furi_hal_light_set(LightGreen, 0x00); + furi_hal_light_set(LightBlue, 0x00); LL_mDelay(125); } else if(*c == '-') { LL_mDelay(250); - api_hal_light_set(LightRed, 0x00); - api_hal_light_set(LightGreen, 0x00); - api_hal_light_set(LightBlue, 0x00); + furi_hal_light_set(LightRed, 0x00); + furi_hal_light_set(LightGreen, 0x00); + furi_hal_light_set(LightBlue, 0x00); LL_mDelay(250); } else if(*c == '|') { - api_hal_light_set(LightRed, 0x00); - api_hal_light_set(LightGreen, 0x00); - api_hal_light_set(LightBlue, 0x00); + furi_hal_light_set(LightRed, 0x00); + furi_hal_light_set(LightGreen, 0x00); + furi_hal_light_set(LightBlue, 0x00); } c++; } while(*c != 0); } -void clock_init() { +void target_clock_init() { LL_Init1msTick(4000000); LL_SetSystemCoreClock(4000000); -} -void gpio_init() { LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOE); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH); + + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); +} + +void target_gpio_init() { // USB D+ LL_GPIO_SetPinMode(BOOT_USB_PORT, BOOT_USB_DP_PIN, LL_GPIO_MODE_OUTPUT); LL_GPIO_SetPinSpeed(BOOT_USB_PORT, BOOT_USB_DP_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH); @@ -81,7 +101,7 @@ void gpio_init() { LL_GPIO_SetPinPull(BOOT_DFU_PORT, BOOT_DFU_PIN, LL_GPIO_PULL_UP); } -void rtc_init() { +void target_rtc_init() { // LSE and RTC LL_PWR_EnableBkUpAccess(); if(!RTC_CLOCK_IS_READY()) { @@ -112,24 +132,46 @@ void rtc_init() { LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB); } -void version_save(void) { +void target_version_save(void) { LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR1, (uint32_t)version_get()); } -void usb_wire_reset() { +void target_usb_wire_reset() { LL_GPIO_ResetOutputPin(BOOT_USB_PORT, BOOT_USB_PIN); LL_mDelay(10); LL_GPIO_SetOutputPin(BOOT_USB_PORT, BOOT_USB_PIN); } +void target_display_init() { + // Prepare gpio + hal_gpio_init_simple(&gpio_display_rst, GpioModeOutputPushPull); + hal_gpio_init_simple(&gpio_display_di, GpioModeOutputPushPull); + // Initialize + u8g2_t fb; + u8g2_Setup_st7565_erc12864_alt_f(&fb, U8G2_R0, u8x8_hw_spi_stm32, u8g2_gpio_and_delay_stm32); + u8g2_InitDisplay(&fb); + u8g2_SetContrast(&fb, 36); + // Create payload + u8g2_ClearBuffer(&fb); + u8g2_SetDrawColor(&fb, 0x01); + u8g2_SetFont(&fb, u8g2_font_helvB08_tf); + u8g2_DrawStr(&fb, 2, 8, "Recovery & Update Mode"); + u8g2_DrawXBM(&fb, 49, 14, 30, 23, I_Warning_30x23_0); + u8g2_DrawStr(&fb, 2, 50, "DFU Bootloader activated"); + u8g2_DrawStr(&fb, 6, 62, "www.flipp.dev/recovery"); + // Send buffer + u8g2_SetPowerSave(&fb, 0); + u8g2_SendBuffer(&fb); +} + void target_init() { - clock_init(); - gpio_init(); - api_hal_init(); + target_clock_init(); + target_gpio_init(); + furi_hal_init(); target_led_control("RGB"); - rtc_init(); - version_save(); - usb_wire_reset(); + target_rtc_init(); + target_version_save(); + target_usb_wire_reset(); // Errata 2.2.9, Flash OPTVERR flag is always set after system reset __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); @@ -164,10 +206,13 @@ void target_switch(void* offset) { void target_switch2dfu() { target_led_control("B"); + furi_hal_light_set(LightBacklight, 0xFF); + target_display_init(); // Mark system as tainted, it will be soon LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_TAINTED); // Remap memory to system bootloader LL_SYSCFG_SetRemapMemory(LL_SYSCFG_REMAP_SYSTEMFLASH); + // Jump target_switch(0x0); } diff --git a/bootloader/targets/f6/target.mk b/bootloader/targets/f6/target.mk index ab0c24b4c39..e6430585467 100644 --- a/bootloader/targets/f6/target.mk +++ b/bootloader/targets/f6/target.mk @@ -21,6 +21,7 @@ C_SOURCES += $(CUBE_DIR)/Drivers/CMSIS/Device/ST/STM32WBxx/Source/Templates/sys C_SOURCES += $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_utils.c C_SOURCES += $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_gpio.c C_SOURCES += $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_i2c.c +C_SOURCES += $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_spi.c CFLAGS += -I$(CUBE_DIR)/Drivers/CMSIS/Include CFLAGS += -I$(CUBE_DIR)/Drivers/CMSIS/Device/ST/STM32WBxx/Include @@ -34,8 +35,8 @@ CFLAGS += -I$(DRIVERS_DIR) C_SOURCES += $(DRIVERS_DIR)/lp5562.c # API-HAL -CFLAGS += -I$(TARGET_DIR)/api-hal -C_SOURCES += $(wildcard $(TARGET_DIR)/api-hal/*.c) +CFLAGS += -I$(TARGET_DIR)/furi-hal +C_SOURCES += $(wildcard $(TARGET_DIR)/furi-hal/*.c) # Version generation C_SOURCES += $(PROJECT_ROOT)/lib/toolbox/version.c diff --git a/bootloader/targets/api-hal-include/target.h b/bootloader/targets/furi-hal-include/target.h similarity index 100% rename from bootloader/targets/api-hal-include/target.h rename to bootloader/targets/furi-hal-include/target.h diff --git a/core/core.mk b/core/core.mk index 5e8fd51e639..4a82434349c 100644 --- a/core/core.mk +++ b/core/core.mk @@ -4,5 +4,5 @@ CFLAGS += -I$(CORE_DIR) -D_GNU_SOURCE ASM_SOURCES += $(wildcard $(CORE_DIR)/*.s) C_SOURCES += $(wildcard $(CORE_DIR)/*.c) C_SOURCES += $(wildcard $(CORE_DIR)/furi/*.c) -C_SOURCES += $(wildcard $(CORE_DIR)/api-hal/*.c) +C_SOURCES += $(wildcard $(CORE_DIR)/furi-hal/*.c) CPP_SOURCES += $(wildcard $(CORE_DIR)/*.cpp) diff --git a/core/flipper.c b/core/flipper.c index ffd44742e3b..785a44635b4 100755 --- a/core/flipper.c +++ b/core/flipper.c @@ -1,7 +1,7 @@ #include "flipper.h" #include #include -#include +#include static void flipper_print_version(const char* target, const Version* version) { if(version) { @@ -25,10 +25,10 @@ static void flipper_print_version(const char* target, const Version* version) { void flipper_init() { const Version* version; - version = (const Version*)api_hal_version_get_boot_version(); + version = (const Version*)furi_hal_version_get_boot_version(); flipper_print_version("Bootloader", version); - version = (const Version*)api_hal_version_get_firmware_version(); + version = (const Version*)furi_hal_version_get_firmware_version(); flipper_print_version("Firmware", version); FURI_LOG_I("FLIPPER", "starting services"); diff --git a/core/api-hal/api-interrupt-mgr.c b/core/furi-hal/api-interrupt-mgr.c similarity index 100% rename from core/api-hal/api-interrupt-mgr.c rename to core/furi-hal/api-interrupt-mgr.c diff --git a/core/api-hal/api-interrupt-mgr.h b/core/furi-hal/api-interrupt-mgr.h similarity index 100% rename from core/api-hal/api-interrupt-mgr.h rename to core/furi-hal/api-interrupt-mgr.h diff --git a/core/api-hal/api-spi.h b/core/furi-hal/api-spi.h similarity index 100% rename from core/api-hal/api-spi.h rename to core/furi-hal/api-spi.h diff --git a/core/furi.h b/core/furi.h index 3ebccc662b7..681855d0631 100644 --- a/core/furi.h +++ b/core/furi.h @@ -13,8 +13,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/core/furi/check.c b/core/furi/check.c index 5bd019ca314..13d176bfc18 100644 --- a/core/furi/check.c +++ b/core/furi/check.c @@ -1,5 +1,5 @@ #include "check.h" -#include "api-hal-task.h" +#include "furi-hal-task.h" #include void __furi_abort(void); diff --git a/core/furi/stdglue.c b/core/furi/stdglue.c index 26d0095ec29..4755c7ab666 100644 --- a/core/furi/stdglue.c +++ b/core/furi/stdglue.c @@ -2,7 +2,7 @@ #include "check.h" #include "memmgr.h" -#include +#include #include DICT_DEF2( @@ -58,7 +58,7 @@ static ssize_t stdout_write(void* _cookie, const char* data, size_t size) { return 0; } // Debug uart - if(!consumed) api_hal_console_tx((const uint8_t*)data, size); + if(!consumed) furi_hal_console_tx((const uint8_t*)data, size); // All data consumed return size; } diff --git a/firmware/Makefile b/firmware/Makefile index ccceb450f06..0b6e6e49434 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -8,7 +8,7 @@ include $(PROJECT_ROOT)/core/core.mk include $(PROJECT_ROOT)/applications/applications.mk include $(PROJECT_ROOT)/lib/lib.mk -CFLAGS += -I$(PROJECT_ROOT) -Itargets/api-hal-include +CFLAGS += -I$(PROJECT_ROOT) -Itargets/furi-hal-include CFLAGS += -Werror -Wno-address-of-packed-member CPPFLAGS += -Werror diff --git a/firmware/ReadMe.md b/firmware/ReadMe.md index a50f0740d78..d3d61b236a5 100644 --- a/firmware/ReadMe.md +++ b/firmware/ReadMe.md @@ -31,7 +31,7 @@ You can find platform code for STM32WB55 version in `f4` folder: ``` ├── Inc # CubeMX generated headers ├── Src # CubeMX generated code -├── api-hal # Our HAL wrappers and platform specifics +├── furi-hal # Our HAL wrappers and platform specifics ├── ble-glue # BLE specific code(Glue for STMWPAN) ├── f4.ioc # CubeMX project file ├── startup_stm32wb55xx_cm4.s # Board startup/initialization assembler code @@ -46,7 +46,7 @@ Working with CubeMX: 3. Do whatever you want to 3. Click `generate code` 4. After regenerating, look at git status, regeneration may brake some files. -5. Check one more time that things that you've changes are not covered in platform api-hal. Because you know... +5. Check one more time that things that you've changes are not covered in platform furi-hal. Because you know... # Flipper Universal Registry Implementation (FURI) diff --git a/firmware/targets/api-hal-include/api-hal-boot.h b/firmware/targets/api-hal-include/api-hal-boot.h deleted file mode 100644 index cd5a7a4e0a2..00000000000 --- a/firmware/targets/api-hal-include/api-hal-boot.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Boot modes */ -typedef enum { - ApiHalBootModeNormal, - ApiHalBootModeDFU -} ApiHalBootMode; - -/** Boot flags */ -typedef enum { - ApiHalBootFlagDefault=0, - ApiHalBootFlagFactoryReset=1, -} ApiHalBootFlag; - -/** Initialize boot subsystem */ -void api_hal_boot_init(); - -/** Set boot mode */ -void api_hal_boot_set_mode(ApiHalBootMode mode); - -/** Set boot flags */ -void api_hal_boot_set_flags(ApiHalBootFlag flags); - -/** Get boot flag */ -ApiHalBootFlag api_hal_boot_get_flags(); - -#ifdef __cplusplus -} -#endif diff --git a/firmware/targets/api-hal-include/api-hal-ibutton.h b/firmware/targets/api-hal-include/api-hal-ibutton.h deleted file mode 100644 index cc19e7e955c..00000000000 --- a/firmware/targets/api-hal-include/api-hal-ibutton.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void api_hal_ibutton_start(); - -void api_hal_ibutton_stop(); - -void api_hal_ibutton_pin_low(); - -void api_hal_ibutton_pin_high(); - -bool api_hal_ibutton_pin_get_level(); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/firmware/targets/api-hal-include/api-hal-irda.h b/firmware/targets/api-hal-include/api-hal-irda.h deleted file mode 100644 index ee3f7106ae3..00000000000 --- a/firmware/targets/api-hal-include/api-hal-irda.h +++ /dev/null @@ -1,121 +0,0 @@ -#pragma once -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - ApiHalIrdaTxGetDataStateError, /* An error occured during transmission */ - ApiHalIrdaTxGetDataStateOk, /* New data obtained */ - ApiHalIrdaTxGetDataStateDone, /* New data obtained, and this is end of package */ - ApiHalIrdaTxGetDataStateLastDone, /* New data obtained, and this is end of package and no more data available */ -} ApiHalIrdaTxGetDataState; - -typedef ApiHalIrdaTxGetDataState (*ApiHalIrdaTxGetDataCallback) (void* context, uint32_t* duration, bool* level); - -/** - * Signature of callback function for receiving continuous IRDA rx signal. - * - * @param ctx[in] - context to pass to callback - * @param level[in] - level of input IRDA rx signal - * @param duration[in] - duration of continuous rx signal level in us - */ -typedef void (*ApiHalIrdaRxCaptureCallback)(void* ctx, bool level, uint32_t duration); - -/** - * Signature of callback function for reaching silence timeout on IRDA port. - * - * @param ctx[in] - context to pass to callback - */ -typedef void (*ApiHalIrdaRxTimeoutCallback)(void* ctx); - -/** - * Initialize IRDA RX timer to receive interrupts. - * It provides interrupts for every RX-signal edge changing - * with its duration. - */ -void api_hal_irda_async_rx_start(void); - -/** - * Deinitialize IRDA RX interrupt. - */ -void api_hal_irda_async_rx_stop(void); - -/** Setup api hal for receiving silence timeout. - * Should be used with 'api_hal_irda_timeout_irq_set_callback()'. - * - * @param[in] timeout_ms - time to wait for silence on IRDA port - * before generating IRQ. - */ -void api_hal_irda_async_rx_set_timeout(uint32_t timeout_ms); - -/** - * Setup callback for previously initialized IRDA RX interrupt. - * - * @param[in] callback - callback to call when RX signal edge changing occurs - * @param[in] ctx - context for callback - */ -void api_hal_irda_async_rx_set_capture_isr_callback(ApiHalIrdaRxCaptureCallback callback, void *ctx); - -/** - * Setup callback for reaching silence timeout on IRDA port. - * Should setup api hal with 'api_hal_irda_setup_rx_timeout_irq()' first. - * - * @param[in] callback - callback for silence timeout - * @param[in] ctx - context to pass to callback - */ -void api_hal_irda_async_rx_set_timeout_isr_callback(ApiHalIrdaRxTimeoutCallback callback, void *ctx); - -/** - * Check if IRDA is in use now. - * @return true - IRDA is busy, false otherwise. - */ -bool api_hal_irda_is_busy(void); - -/** - * Set callback providing new data. This function has to be called - * before api_hal_irda_async_tx_start(). - * - * @param[in] callback - function to provide new data - * @param[in] context - context for callback - */ -void api_hal_irda_async_tx_set_data_isr_callback(ApiHalIrdaTxGetDataCallback callback, void* context); - -/** - * Start IR asynchronous transmission. It can be stopped by 2 reasons: - * 1) implicit call for api_hal_irda_async_tx_stop() - * 2) callback can provide ApiHalIrdaTxGetDataStateLastDone response - * which means no more data available for transmission. - * - * Any func (api_hal_irda_async_tx_stop() or - * api_hal_irda_async_tx_wait_termination()) has to be called to wait - * end of transmission and free resources. - * - * @param[in] freq - frequency for PWM - * @param[in] duty_cycle - duty cycle for PWM - * @return true if transmission successfully started, false otherwise. - * If start failed no need to free resources. - */ -bool api_hal_irda_async_tx_start(uint32_t freq, float duty_cycle); - -/** - * Stop IR asynchronous transmission and free resources. - * Transmission will stop as soon as transmission reaches end of - * package (ApiHalIrdaTxGetDataStateDone or ApiHalIrdaTxGetDataStateLastDone). - */ -void api_hal_irda_async_tx_stop(void); - -/** - * Wait for end of IR asynchronous transmission and free resources. - * Transmission will stop as soon as transmission reaches end of - * transmission (ApiHalIrdaTxGetDataStateLastDone). - */ -void api_hal_irda_async_tx_wait_termination(void); - -#ifdef __cplusplus -} -#endif - diff --git a/firmware/targets/api-hal-include/api-hal-nfc.h b/firmware/targets/api-hal-include/api-hal-nfc.h deleted file mode 100644 index dda13e3bfb7..00000000000 --- a/firmware/targets/api-hal-include/api-hal-nfc.h +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define API_HAL_NFC_UID_MAX_LEN 10 - -/** - * Init nfc - */ -void api_hal_nfc_init(); - -/** - * Check if nfc worker is busy - */ -bool api_hal_nfc_is_busy(); - -/** - * NFC field on - */ -void api_hal_nfc_field_on(); - -/** - * NFC field off - */ -void api_hal_nfc_field_off(); - -/** - * NFC start sleep - */ -void api_hal_nfc_start_sleep(); - -/** - * NFC stop sleep - */ -void api_hal_nfc_exit_sleep(); - -/** - * NFC poll - */ -bool api_hal_nfc_detect(rfalNfcDevice** dev_list, uint8_t* dev_cnt, uint32_t timeout, bool deactivate); - -/** - * NFC listen - */ -bool api_hal_nfc_listen(uint8_t* uid, uint8_t uid_len, uint8_t* atqa, uint8_t sak, uint32_t timeout); - -/** - * NFC data exchange - */ -ReturnCode api_hal_nfc_data_exchange(uint8_t* tx_buff, uint16_t tx_len, uint8_t** rx_buff, uint16_t** rx_len, bool deactivate); - -/** - * NFC deactivate and start sleep - */ -void api_hal_nfc_deactivate(); - -#ifdef __cplusplus -} -#endif diff --git a/firmware/targets/api-hal-include/api-hal-version.h b/firmware/targets/api-hal-include/api-hal-version.h deleted file mode 100644 index edf4d9f0dc0..00000000000 --- a/firmware/targets/api-hal-include/api-hal-version.h +++ /dev/null @@ -1,90 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Device Colors */ -typedef enum { - ApiHalVersionColorUnknown=0x00, - ApiHalVersionColorBlack=0x01, - ApiHalVersionColorWhite=0x02, -} ApiHalVersionColor; - -/** Device Regions */ -typedef enum { - ApiHalVersionRegionUnknown=0x00, - ApiHalVersionRegionEuRu=0x01, - ApiHalVersionRegionUsCaAu=0x02, - ApiHalVersionRegionJp=0x03, -} ApiHalVersionRegion; - -/** Init flipper version */ -void api_hal_version_init(); - -/** Check target firmware version */ -bool api_hal_version_do_i_belong_here(); - -/** Get model name */ -const char* api_hal_version_get_model_name(); - -/** Get hardware version */ -const uint8_t api_hal_version_get_hw_version(); - -/** Get hardware target */ -const uint8_t api_hal_version_get_hw_target(); - -/** Get hardware body */ -const uint8_t api_hal_version_get_hw_body(); - -/** Get hardware body color */ -const ApiHalVersionColor api_hal_version_get_hw_color(); - -/** Get hardware connect */ -const uint8_t api_hal_version_get_hw_connect(); - -/** Get hardware region */ -const ApiHalVersionRegion api_hal_version_get_hw_region(); - -/** Get hardware timestamp */ -const uint32_t api_hal_version_get_hw_timestamp(); - -/** Get pointer to target name */ -const char* api_hal_version_get_name_ptr(); - -/** Get pointer to target device name */ -const char* api_hal_version_get_device_name_ptr(); - -/** Get pointer to target ble local device name */ -const char* api_hal_version_get_ble_local_device_name_ptr(); - -const uint8_t* api_hal_version_get_ble_mac(); - -/** - * Get address of version structure of bootloader, stored in chip flash. - * - * @return Address of boot version structure. - */ -const struct Version* api_hal_version_get_boot_version(void); - -/** - * Get address of version structure of firmware. - * - * @return Address of firmware version structure. - */ -const struct Version* api_hal_version_get_firmware_version(void); - -/** Get platform UID size in bytes */ -size_t api_hal_version_uid_size(); - -/** Get const pointer to UID */ -const uint8_t* api_hal_version_uid(); - -#ifdef __cplusplus -} -#endif diff --git a/firmware/targets/api-hal-include/api-hal.h b/firmware/targets/api-hal-include/api-hal.h deleted file mode 100644 index e6b30db04f1..00000000000 --- a/firmware/targets/api-hal-include/api-hal.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#ifdef __cplusplus -template struct STOP_EXTERNING_ME {}; -#endif - -#include "api-hal-boot.h" -#include "api-hal-clock.h" -#include "api-hal-console.h" -#include "api-hal-os.h" -#include "api-hal-i2c.h" -#include "api-hal-resources.h" -#include "api-hal-gpio.h" -#include "api-hal-light.h" -#include "api-hal-delay.h" -#include "api-hal-pwm.h" -#include "api-hal-task.h" -#include "api-hal-power.h" -#include "api-hal-vcp.h" -#include "api-hal-interrupt.h" -#include "api-hal-version.h" -#include "api-hal-bt.h" -#include "api-hal-spi.h" -#include "api-hal-flash.h" -#include "api-hal-subghz.h" -#include "api-hal-vibro.h" -#include "api-hal-ibutton.h" -#include "api-hal-rfid.h" -#include "api-hal-nfc.h" - -/** Init api-hal */ -void api_hal_init(); diff --git a/firmware/targets/f6/Inc/adc.h b/firmware/targets/f6/Inc/adc.h deleted file mode 100644 index 5f945644c64..00000000000 --- a/firmware/targets/f6/Inc/adc.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - ****************************************************************************** - * @file adc.h - * @brief This file contains all the function prototypes for - * the adc.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __ADC_H__ -#define __ADC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern ADC_HandleTypeDef hadc1; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_ADC1_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ADC_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f6/Inc/crc.h b/firmware/targets/f6/Inc/crc.h deleted file mode 100644 index d1b47518bb1..00000000000 --- a/firmware/targets/f6/Inc/crc.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - ****************************************************************************** - * @file crc.h - * @brief This file contains all the function prototypes for - * the crc.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __CRC_H__ -#define __CRC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern CRC_HandleTypeDef hcrc; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_CRC_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __CRC_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f6/Inc/main.h b/firmware/targets/f6/Inc/main.h index 5b2614dafd5..ff4e635aaac 100644 --- a/firmware/targets/f6/Inc/main.h +++ b/firmware/targets/f6/Inc/main.h @@ -117,10 +117,6 @@ void Error_Handler(void); #define SPI_R_SCK_GPIO_Port GPIOA #define SPI_R_SCK_Pin GPIO_PIN_5 -#define SPI_R hspi1 -#define SPI_D hspi2 -#define SPI_SD_HANDLE SPI_D - extern TIM_HandleTypeDef htim1; extern TIM_HandleTypeDef htim2; extern TIM_HandleTypeDef htim16; diff --git a/firmware/targets/f6/Inc/spi.h b/firmware/targets/f6/Inc/spi.h deleted file mode 100644 index 23beca240a1..00000000000 --- a/firmware/targets/f6/Inc/spi.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - ****************************************************************************** - * @file spi.h - * @brief This file contains all the function prototypes for - * the spi.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __SPI_H__ -#define __SPI_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern SPI_HandleTypeDef hspi1; -extern SPI_HandleTypeDef hspi2; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_SPI1_Init(void); -void MX_SPI2_Init(void); - -/* USER CODE BEGIN Prototypes */ -void NFC_SPI_Reconfigure(); -void SD_SPI_Reconfigure_Slow(); -void SD_SPI_Reconfigure_Fast(); -void CC1101_SPI_Reconfigure(); -void SD_SPI_Bus_To_Down_State(); -void SD_SPI_Bus_To_Normal_State(); -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __SPI_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f6/Inc/stm32wbxx_hal_conf.h b/firmware/targets/f6/Inc/stm32wbxx_hal_conf.h index d7409fe42cd..1c96d8cd49c 100644 --- a/firmware/targets/f6/Inc/stm32wbxx_hal_conf.h +++ b/firmware/targets/f6/Inc/stm32wbxx_hal_conf.h @@ -33,30 +33,30 @@ * @brief This is the list of modules to be used in the HAL driver */ #define HAL_MODULE_ENABLED -#define HAL_ADC_MODULE_ENABLED +/*#define HAL_ADC_MODULE_ENABLED */ #define HAL_CRYP_MODULE_ENABLED #define HAL_COMP_MODULE_ENABLED -#define HAL_CRC_MODULE_ENABLED +/*#define HAL_CRC_MODULE_ENABLED */ #define HAL_HSEM_MODULE_ENABLED -// #define HAL_I2C_MODULE_ENABLED +/*#define HAL_I2C_MODULE_ENABLED */ /*#define HAL_IPCC_MODULE_ENABLED */ /*#define HAL_IRDA_MODULE_ENABLED */ /*#define HAL_IWDG_MODULE_ENABLED */ -/*#define HAL_LCD_MODULE_ENABLED */ -/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_LCD_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ #define HAL_PCD_MODULE_ENABLED #define HAL_PKA_MODULE_ENABLED /*#define HAL_QSPI_MODULE_ENABLED */ #define HAL_RNG_MODULE_ENABLED #define HAL_RTC_MODULE_ENABLED -/*#define HAL_SAI_MODULE_ENABLED */ -/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_SAI_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ /*#define HAL_SMARTCARD_MODULE_ENABLED */ -#define HAL_SPI_MODULE_ENABLED +/*#define HAL_SPI_MODULE_ENABLED */ #define HAL_TIM_MODULE_ENABLED -/*#define HAL_TSC_MODULE_ENABLED */ -#define HAL_UART_MODULE_ENABLED -/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_TSC_MODULE_ENABLED */ +/*#define HAL_UART_MODULE_ENABLED */ +/*#define HAL_USART_MODULE_ENABLED */ /*#define HAL_WWDG_MODULE_ENABLED */ #define HAL_EXTI_MODULE_ENABLED #define HAL_CORTEX_MODULE_ENABLED @@ -172,7 +172,7 @@ * @brief This is the HAL system configuration section */ -#define VDD_VALUE 3300U /*!< Value of VDD in mv */ +#define VDD_VALUE 3300U /*!< Value of VDD in mv */ #define TICK_INT_PRIORITY 0U /*!< tick interrupt priority */ #define USE_RTOS 0U #define PREFETCH_ENABLE 1U diff --git a/firmware/targets/f6/Src/adc.c b/firmware/targets/f6/Src/adc.c deleted file mode 100644 index 1ad43f2f6d6..00000000000 --- a/firmware/targets/f6/Src/adc.c +++ /dev/null @@ -1,128 +0,0 @@ -/** - ****************************************************************************** - * @file adc.c - * @brief This file provides code for the configuration - * of the ADC instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "adc.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -ADC_HandleTypeDef hadc1; - -/* ADC1 init function */ -void MX_ADC1_Init(void) -{ - ADC_ChannelConfTypeDef sConfig = {0}; - - /** Common config - */ - hadc1.Instance = ADC1; - hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; - hadc1.Init.Resolution = ADC_RESOLUTION_12B; - hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; - hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; - hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; - hadc1.Init.LowPowerAutoWait = DISABLE; - hadc1.Init.ContinuousConvMode = DISABLE; - hadc1.Init.NbrOfConversion = 1; - hadc1.Init.DiscontinuousConvMode = DISABLE; - hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; - hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; - hadc1.Init.DMAContinuousRequests = DISABLE; - hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED; - hadc1.Init.OversamplingMode = DISABLE; - if (HAL_ADC_Init(&hadc1) != HAL_OK) - { - Error_Handler(); - } - /** Configure Regular Channel - */ - sConfig.Channel = ADC_CHANNEL_14; - sConfig.Rank = ADC_REGULAR_RANK_1; - sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5; - sConfig.SingleDiff = ADC_SINGLE_ENDED; - sConfig.OffsetNumber = ADC_OFFSET_NONE; - sConfig.Offset = 0; - if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) - { - Error_Handler(); - } - -} - -void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) -{ - - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(adcHandle->Instance==ADC1) - { - /* USER CODE BEGIN ADC1_MspInit 0 */ - - /* USER CODE END ADC1_MspInit 0 */ - /* ADC1 clock enable */ - __HAL_RCC_ADC_CLK_ENABLE(); - - __HAL_RCC_GPIOC_CLK_ENABLE(); - /**ADC1 GPIO Configuration - PC5 ------> ADC1_IN14 - */ - GPIO_InitStruct.Pin = RFID_RF_IN_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(RFID_RF_IN_GPIO_Port, &GPIO_InitStruct); - - /* ADC1 interrupt Init */ - HAL_NVIC_SetPriority(ADC1_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(ADC1_IRQn); - /* USER CODE BEGIN ADC1_MspInit 1 */ - - /* USER CODE END ADC1_MspInit 1 */ - } -} - -void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) -{ - - if(adcHandle->Instance==ADC1) - { - /* USER CODE BEGIN ADC1_MspDeInit 0 */ - - /* USER CODE END ADC1_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_ADC_CLK_DISABLE(); - - /**ADC1 GPIO Configuration - PC5 ------> ADC1_IN14 - */ - HAL_GPIO_DeInit(RFID_RF_IN_GPIO_Port, RFID_RF_IN_Pin); - - /* ADC1 interrupt Deinit */ - HAL_NVIC_DisableIRQ(ADC1_IRQn); - /* USER CODE BEGIN ADC1_MspDeInit 1 */ - - /* USER CODE END ADC1_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f6/Src/crc.c b/firmware/targets/f6/Src/crc.c deleted file mode 100644 index 42b98724543..00000000000 --- a/firmware/targets/f6/Src/crc.c +++ /dev/null @@ -1,82 +0,0 @@ -/** - ****************************************************************************** - * @file crc.c - * @brief This file provides code for the configuration - * of the CRC instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "crc.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -CRC_HandleTypeDef hcrc; - -/* CRC init function */ -void MX_CRC_Init(void) -{ - - hcrc.Instance = CRC; - hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; - hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; - hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; - hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; - hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; - if (HAL_CRC_Init(&hcrc) != HAL_OK) - { - Error_Handler(); - } - -} - -void HAL_CRC_MspInit(CRC_HandleTypeDef* crcHandle) -{ - - if(crcHandle->Instance==CRC) - { - /* USER CODE BEGIN CRC_MspInit 0 */ - - /* USER CODE END CRC_MspInit 0 */ - /* CRC clock enable */ - __HAL_RCC_CRC_CLK_ENABLE(); - /* USER CODE BEGIN CRC_MspInit 1 */ - - /* USER CODE END CRC_MspInit 1 */ - } -} - -void HAL_CRC_MspDeInit(CRC_HandleTypeDef* crcHandle) -{ - - if(crcHandle->Instance==CRC) - { - /* USER CODE BEGIN CRC_MspDeInit 0 */ - - /* USER CODE END CRC_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_CRC_CLK_DISABLE(); - /* USER CODE BEGIN CRC_MspDeInit 1 */ - - /* USER CODE END CRC_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f6/Src/fatfs/spi_sd_hal.c b/firmware/targets/f6/Src/fatfs/spi_sd_hal.c index 386c808120a..70e9bbf1683 100644 --- a/firmware/targets/f6/Src/fatfs/spi_sd_hal.c +++ b/firmware/targets/f6/Src/fatfs/spi_sd_hal.c @@ -1,26 +1,18 @@ #include "main.h" -#include "api-hal-spi.h" +#include +#include #define SD_DUMMY_BYTE 0xFF const uint32_t SpiTimeout = 1000; uint8_t SD_IO_WriteByte(uint8_t Data); -static const ApiHalSpiDevice* sd_spi_dev = &api_hal_spi_devices[ApiHalSpiDeviceIdSdCardFast]; +static const FuriHalSpiDevice* sd_spi_dev = &furi_hal_spi_devices[FuriHalSpiDeviceIdSdCardFast]; /****************************************************************************** BUS OPERATIONS *******************************************************************************/ -/** - * @brief SPI error treatment function - * @retval None - */ -static void SPIx_Error(void) { - /* Re-Initiaize the SPI communication BUS */ - api_hal_spi_bus_reset(sd_spi_dev->bus); -} - /** * @brief SPI Write byte(s) to device * @param DataIn: Pointer to data buffer to write @@ -29,13 +21,7 @@ static void SPIx_Error(void) { * @retval None */ static void SPIx_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t DataLength) { - bool status = api_hal_spi_bus_trx(sd_spi_dev->bus, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout); - - /* Check the communication status */ - if(!status) { - /* Execute user timeout callback */ - SPIx_Error(); - } + furi_check(furi_hal_spi_bus_trx(sd_spi_dev->bus, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout)); } /** @@ -44,15 +30,7 @@ static void SPIx_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t * @retval None */ __attribute__((unused)) static void SPIx_Write(uint8_t Value) { - uint8_t data; - - bool status = api_hal_spi_bus_trx(sd_spi_dev->bus, (uint8_t*)&Value, &data, 1, SpiTimeout); - - /* Check the communication status */ - if(!status) { - /* Execute user timeout callback */ - SPIx_Error(); - } + furi_check(furi_hal_spi_bus_tx(sd_spi_dev->bus, (uint8_t*)&Value, 1, SpiTimeout)); } /****************************************************************************** @@ -70,6 +48,7 @@ void SD_IO_Init(void) { /* SD chip select high */ hal_gpio_write(sd_spi_dev->chip_select, true); + delay_us(10); /* Send dummy byte 0xFF, 10 times with CS high */ /* Rise CS and MOSI for 80 clocks cycles */ @@ -85,10 +64,13 @@ void SD_IO_Init(void) { * @retval None */ void SD_IO_CSState(uint8_t val) { + /* Some SD Cards are prone to fail if CLK-ed too soon after CS transition. Worst case found: 8us */ if(val == 1) { + delay_us(10); // Exit guard time for some SD cards hal_gpio_write(sd_spi_dev->chip_select, true); } else { hal_gpio_write(sd_spi_dev->chip_select, false); + delay_us(10); // Entry guard time for some SD cards } } diff --git a/firmware/targets/f6/Src/fatfs/stm32_adafruit_sd.c b/firmware/targets/f6/Src/fatfs/stm32_adafruit_sd.c index c00ed04aff7..9c328d30ced 100644 --- a/firmware/targets/f6/Src/fatfs/stm32_adafruit_sd.c +++ b/firmware/targets/f6/Src/fatfs/stm32_adafruit_sd.c @@ -91,11 +91,12 @@ #include "stdlib.h" #include "string.h" #include "stdio.h" -#include "spi.h" -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include /** @addtogroup BSP * @{ @@ -282,6 +283,25 @@ static uint8_t SD_ReadData(void); /* Private functions ---------------------------------------------------------*/ +void SD_SPI_Bus_To_Down_State(){ + hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + + hal_gpio_write(&gpio_sdcard_cs, false); + hal_gpio_write(&gpio_spi_d_miso, false); + hal_gpio_write(&gpio_spi_d_mosi, false); + hal_gpio_write(&gpio_spi_d_sck, false); +} + +void SD_SPI_Bus_To_Normal_State(){ + hal_gpio_write(&gpio_sdcard_cs, true); + + hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); +} + /** @defgroup STM32_ADAFRUIT_SD_Private_Functions * @{ */ @@ -295,14 +315,12 @@ static uint8_t SD_ReadData(void); */ uint8_t BSP_SD_Init(bool reset_card) { /* Slow speed init */ - const ApiHalSpiDevice* sd_spi_slow_dev = &api_hal_spi_devices[ApiHalSpiDeviceIdSdCardSlow]; - api_hal_spi_bus_lock(sd_spi_slow_dev->bus); - api_hal_spi_bus_configure(sd_spi_slow_dev->bus, sd_spi_slow_dev->config); + const FuriHalSpiDevice* sd_spi_slow_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardSlow); /* We must reset card in spi_lock context */ if(reset_card) { /* disable power and set low on all bus pins */ - api_hal_power_disable_external_3_3v(); + furi_hal_power_disable_external_3_3v(); SD_SPI_Bus_To_Down_State(); hal_sd_detect_set_low(); delay(250); @@ -310,7 +328,7 @@ uint8_t BSP_SD_Init(bool reset_card) { /* reinit bus and enable power */ SD_SPI_Bus_To_Normal_State(); hal_sd_detect_init(); - api_hal_power_enable_external_3_3v(); + furi_hal_power_enable_external_3_3v(); delay(100); } @@ -326,7 +344,7 @@ uint8_t BSP_SD_Init(bool reset_card) { if(res == BSP_SD_OK) break; } - api_hal_spi_bus_unlock(sd_spi_slow_dev->bus); + furi_hal_spi_device_return(sd_spi_slow_dev); /* SD initialized and set to SPI mode properly */ return res; diff --git a/firmware/targets/f6/Src/fatfs/user_diskio.c b/firmware/targets/f6/Src/fatfs/user_diskio.c index f0f03560303..ca3d60a50f5 100644 --- a/firmware/targets/f6/Src/fatfs/user_diskio.c +++ b/firmware/targets/f6/Src/fatfs/user_diskio.c @@ -35,8 +35,7 @@ /* Includes ------------------------------------------------------------------*/ #include "user_diskio.h" -#include "spi.h" -#include "api-hal-spi.h" +#include "furi-hal-spi.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ @@ -53,7 +52,6 @@ static DSTATUS User_CheckStatus(BYTE lun) { return Stat; } -static const ApiHalSpiDevice* sd_spi_fast_dev = &api_hal_spi_devices[ApiHalSpiDeviceIdSdCardFast]; /* USER CODE END DECL */ /* Private function prototypes -----------------------------------------------*/ @@ -89,12 +87,11 @@ Diskio_drvTypeDef USER_Driver = { DSTATUS USER_initialize(BYTE pdrv) { /* USER CODE BEGIN INIT */ - api_hal_spi_bus_lock(sd_spi_fast_dev->bus); - api_hal_spi_bus_configure(sd_spi_fast_dev->bus, sd_spi_fast_dev->config); + const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); DSTATUS status = User_CheckStatus(pdrv); - api_hal_spi_bus_unlock(sd_spi_fast_dev->bus); + furi_hal_spi_device_return(sd_spi_fast_dev); return status; /* USER CODE END INIT */ @@ -123,8 +120,7 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { /* USER CODE BEGIN READ */ DRESULT res = RES_ERROR; - api_hal_spi_bus_lock(sd_spi_fast_dev->bus); - api_hal_spi_bus_configure(sd_spi_fast_dev->bus, sd_spi_fast_dev->config); + const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); if(BSP_SD_ReadBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) { /* wait until the read operation is finished */ @@ -133,7 +129,7 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { res = RES_OK; } - api_hal_spi_bus_unlock(sd_spi_fast_dev->bus); + furi_hal_spi_device_return(sd_spi_fast_dev); return res; /* USER CODE END READ */ @@ -153,8 +149,7 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { /* USER CODE HERE */ DRESULT res = RES_ERROR; - api_hal_spi_bus_lock(sd_spi_fast_dev->bus); - api_hal_spi_bus_configure(sd_spi_fast_dev->bus, sd_spi_fast_dev->config); + const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); if(BSP_SD_WriteBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) { /* wait until the Write operation is finished */ @@ -163,7 +158,7 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { res = RES_OK; } - api_hal_spi_bus_unlock(sd_spi_fast_dev->bus); + furi_hal_spi_device_return(sd_spi_fast_dev); return res; /* USER CODE END WRITE */ @@ -185,8 +180,7 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { if(Stat & STA_NOINIT) return RES_NOTRDY; - api_hal_spi_bus_lock(sd_spi_fast_dev->bus); - api_hal_spi_bus_configure(sd_spi_fast_dev->bus, sd_spi_fast_dev->config); + const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); switch(cmd) { /* Make sure that no pending write process */ @@ -219,7 +213,7 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { res = RES_PARERR; } - api_hal_spi_bus_unlock(sd_spi_fast_dev->bus); + furi_hal_spi_device_return(sd_spi_fast_dev); return res; /* USER CODE END IOCTL */ diff --git a/firmware/targets/f6/Src/gpio.c b/firmware/targets/f6/Src/gpio.c index c5c26d12c98..8363bc9105a 100644 --- a/firmware/targets/f6/Src/gpio.c +++ b/firmware/targets/f6/Src/gpio.c @@ -67,12 +67,6 @@ void MX_GPIO_Init(void) { GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(RFID_PULL_GPIO_Port, &GPIO_InitStruct); - /*Configure GPIO pin : PtPin */ - GPIO_InitStruct.Pin = CC1101_G0_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; - GPIO_InitStruct.Pull = GPIO_PULLDOWN; - // HAL_GPIO_Init(CC1101_G0_GPIO_Port, &GPIO_InitStruct); - /*Configure GPIO pins : PBPin PBPin PBPin */ GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; @@ -107,22 +101,6 @@ void MX_GPIO_Init(void) { GPIO_InitStruct.Pin = DISPLAY_RST_Pin; HAL_GPIO_Init(DISPLAY_RST_GPIO_Port, &GPIO_InitStruct); - /* NFC_CS */ - HAL_GPIO_WritePin(NFC_CS_GPIO_Port, NFC_CS_Pin, GPIO_PIN_SET); - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Pin = NFC_CS_Pin; - HAL_GPIO_Init(NFC_CS_GPIO_Port, &GPIO_InitStruct); - - /* DISPLAY_CS */ - HAL_GPIO_WritePin(DISPLAY_CS_GPIO_Port, DISPLAY_CS_Pin, GPIO_PIN_SET); - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Pin = DISPLAY_CS_Pin; - HAL_GPIO_Init(DISPLAY_CS_GPIO_Port, &GPIO_InitStruct); - /* DISPLAY_DI */ HAL_GPIO_WritePin(DISPLAY_DI_GPIO_Port, DISPLAY_DI_Pin, GPIO_PIN_RESET); GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; @@ -137,21 +115,6 @@ void MX_GPIO_Init(void) { GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(SD_CD_GPIO_Port, &GPIO_InitStruct); - /* SD_CS */ - GPIO_InitStruct.Pin = SD_CS_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - HAL_GPIO_Init(SD_CS_GPIO_Port, &GPIO_InitStruct); - - /* CC1101_CS */ - HAL_GPIO_WritePin(CC1101_CS_GPIO_Port, CC1101_CS_Pin, GPIO_PIN_SET); - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Pin = CC1101_CS_Pin; - HAL_GPIO_Init(CC1101_CS_GPIO_Port, &GPIO_InitStruct); - /* Enable all NVIC lines related to gpio */ HAL_NVIC_SetPriority(EXTI0_IRQn, 5, 0); HAL_NVIC_EnableIRQ(EXTI0_IRQn); diff --git a/firmware/targets/f6/Src/main.c b/firmware/targets/f6/Src/main.c index 8af59229038..b9deedf28c7 100644 --- a/firmware/targets/f6/Src/main.c +++ b/firmware/targets/f6/Src/main.c @@ -3,7 +3,7 @@ #include "fatfs/fatfs.h" #include -#include +#include #include int main(void) { @@ -13,8 +13,8 @@ int main(void) { // Initialize ST HAL HAL_Init(); - // Flipper API HAL - api_hal_init(); + // Flipper FURI HAL + furi_hal_init(); // 3rd party MX_FATFS_Init(); diff --git a/firmware/targets/f6/Src/spi.c b/firmware/targets/f6/Src/spi.c deleted file mode 100644 index 29c6da7a29f..00000000000 --- a/firmware/targets/f6/Src/spi.c +++ /dev/null @@ -1,374 +0,0 @@ -/** - ****************************************************************************** - * @file spi.c - * @brief This file provides code for the configuration - * of the SPI instances. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "spi.h" -#include - -/* USER CODE BEGIN 0 */ -void Enable_SPI(SPI_HandleTypeDef* spi); -/* USER CODE END 0 */ - -SPI_HandleTypeDef hspi1; -SPI_HandleTypeDef hspi2; - -/* SPI1 init function */ -void MX_SPI1_Init(void) -{ - - hspi1.Instance = SPI1; - hspi1.Init.Mode = SPI_MODE_MASTER; - hspi1.Init.Direction = SPI_DIRECTION_2LINES; - hspi1.Init.DataSize = SPI_DATASIZE_8BIT; - hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; - hspi1.Init.CLKPhase = SPI_PHASE_2EDGE; - hspi1.Init.NSS = SPI_NSS_SOFT; - hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; - hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; - hspi1.Init.TIMode = SPI_TIMODE_DISABLE; - hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - hspi1.Init.CRCPolynomial = 7; - hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; - hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE; - if (HAL_SPI_Init(&hspi1) != HAL_OK) - { - Error_Handler(); - } - -} -/* SPI2 init function */ -void MX_SPI2_Init(void) -{ - - hspi2.Instance = SPI2; - hspi2.Init.Mode = SPI_MODE_MASTER; - hspi2.Init.Direction = SPI_DIRECTION_2LINES; - hspi2.Init.DataSize = SPI_DATASIZE_8BIT; - hspi2.Init.CLKPolarity = SPI_POLARITY_LOW; - hspi2.Init.CLKPhase = SPI_PHASE_1EDGE; - hspi2.Init.NSS = SPI_NSS_SOFT; - hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; - hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; - hspi2.Init.TIMode = SPI_TIMODE_DISABLE; - hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - hspi2.Init.CRCPolynomial = 7; - hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; - hspi2.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; - if (HAL_SPI_Init(&hspi2) != HAL_OK) - { - Error_Handler(); - } - -} - -void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle) -{ - - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(spiHandle->Instance==SPI1) - { - /* USER CODE BEGIN SPI1_MspInit 0 */ - - /* USER CODE END SPI1_MspInit 0 */ - /* SPI1 clock enable */ - __HAL_RCC_SPI1_CLK_ENABLE(); - - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - /**SPI1 GPIO Configuration - PA5 ------> SPI1_SCK - PB4 ------> SPI1_MISO - PB5 ------> SPI1_MOSI - */ - GPIO_InitStruct.Pin = SPI_R_SCK_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; - HAL_GPIO_Init(SPI_R_SCK_GPIO_Port, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = SPI_R_MISO_Pin|SPI_R_MOSI_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - /* USER CODE BEGIN SPI1_MspInit 1 */ - - /* USER CODE END SPI1_MspInit 1 */ - } - else if(spiHandle->Instance==SPI2) - { - /* USER CODE BEGIN SPI2_MspInit 0 */ - - /* USER CODE END SPI2_MspInit 0 */ - /* SPI2 clock enable */ - __HAL_RCC_SPI2_CLK_ENABLE(); - - __HAL_RCC_GPIOC_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - __HAL_RCC_GPIOD_CLK_ENABLE(); - /**SPI2 GPIO Configuration - PC2 ------> SPI2_MISO - PB15 ------> SPI2_MOSI - PD1 ------> SPI2_SCK - */ - GPIO_InitStruct.Pin = GPIO_PIN_2; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; - HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = SPI_D_MOSI_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; - HAL_GPIO_Init(SPI_D_MOSI_GPIO_Port, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = SPI_D_SCK_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; - HAL_GPIO_Init(SPI_D_SCK_GPIO_Port, &GPIO_InitStruct); - - /* USER CODE BEGIN SPI2_MspInit 1 */ - - // SD Card need faster spi gpio - GPIO_InitStruct.Pin = GPIO_PIN_2; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; - HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = SPI_D_MOSI_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; - HAL_GPIO_Init(SPI_D_MOSI_GPIO_Port, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = SPI_D_SCK_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; - HAL_GPIO_Init(SPI_D_SCK_GPIO_Port, &GPIO_InitStruct); - - /* USER CODE END SPI2_MspInit 1 */ - } -} - -void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle) -{ - - if(spiHandle->Instance==SPI1) - { - /* USER CODE BEGIN SPI1_MspDeInit 0 */ - - /* USER CODE END SPI1_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_SPI1_CLK_DISABLE(); - - /**SPI1 GPIO Configuration - PA5 ------> SPI1_SCK - PB4 ------> SPI1_MISO - PB5 ------> SPI1_MOSI - */ - HAL_GPIO_DeInit(SPI_R_SCK_GPIO_Port, SPI_R_SCK_Pin); - - HAL_GPIO_DeInit(GPIOB, SPI_R_MISO_Pin|SPI_R_MOSI_Pin); - - /* USER CODE BEGIN SPI1_MspDeInit 1 */ - - /* USER CODE END SPI1_MspDeInit 1 */ - } - else if(spiHandle->Instance==SPI2) - { - /* USER CODE BEGIN SPI2_MspDeInit 0 */ - - /* USER CODE END SPI2_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_SPI2_CLK_DISABLE(); - - /**SPI2 GPIO Configuration - PC2 ------> SPI2_MISO - PB15 ------> SPI2_MOSI - PD1 ------> SPI2_SCK - */ - HAL_GPIO_DeInit(GPIOC, GPIO_PIN_2); - - HAL_GPIO_DeInit(SPI_D_MOSI_GPIO_Port, SPI_D_MOSI_Pin); - - HAL_GPIO_DeInit(SPI_D_SCK_GPIO_Port, SPI_D_SCK_Pin); - - /* USER CODE BEGIN SPI2_MspDeInit 1 */ - - /* USER CODE END SPI2_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -void NFC_SPI_Reconfigure() { - osKernelLock(); - - SPI_R.Init.Mode = SPI_MODE_MASTER; - SPI_R.Init.Direction = SPI_DIRECTION_2LINES; - SPI_R.Init.DataSize = SPI_DATASIZE_8BIT; - SPI_R.Init.CLKPolarity = SPI_POLARITY_LOW; - SPI_R.Init.CLKPhase = SPI_PHASE_2EDGE; - SPI_R.Init.NSS = SPI_NSS_SOFT; - SPI_R.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; // 8mhz, 10mhz is max - SPI_R.Init.FirstBit = SPI_FIRSTBIT_MSB; - SPI_R.Init.TIMode = SPI_TIMODE_DISABLE; - SPI_R.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - SPI_R.Init.CRCPolynomial = 7; - SPI_R.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; - SPI_R.Init.NSSPMode = SPI_NSS_PULSE_DISABLE; - - if (HAL_SPI_Init(&SPI_R) != HAL_OK) { - Error_Handler(); - } - - Enable_SPI(&SPI_R); - - osKernelUnlock(); -} - -void SD_SPI_Reconfigure_Slow(void) { - osKernelLock(); - - SPI_SD_HANDLE.Init.Mode = SPI_MODE_MASTER; - SPI_SD_HANDLE.Init.Direction = SPI_DIRECTION_2LINES; - SPI_SD_HANDLE.Init.DataSize = SPI_DATASIZE_8BIT; - SPI_SD_HANDLE.Init.CLKPolarity = SPI_POLARITY_LOW; - SPI_SD_HANDLE.Init.CLKPhase = SPI_PHASE_1EDGE; - SPI_SD_HANDLE.Init.NSS = SPI_NSS_SOFT; - SPI_SD_HANDLE.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; - SPI_SD_HANDLE.Init.FirstBit = SPI_FIRSTBIT_MSB; - SPI_SD_HANDLE.Init.TIMode = SPI_TIMODE_DISABLE; - SPI_SD_HANDLE.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - SPI_SD_HANDLE.Init.CRCPolynomial = 7; - SPI_SD_HANDLE.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; - SPI_SD_HANDLE.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; - - if(HAL_SPI_Init(&SPI_SD_HANDLE) != HAL_OK) { - Error_Handler(); - } - - Enable_SPI(&SPI_SD_HANDLE); - - osKernelUnlock(); -} - -void SD_SPI_Reconfigure_Fast(void) { - osKernelLock(); - - SPI_SD_HANDLE.Init.Mode = SPI_MODE_MASTER; - SPI_SD_HANDLE.Init.Direction = SPI_DIRECTION_2LINES; - SPI_SD_HANDLE.Init.DataSize = SPI_DATASIZE_8BIT; - SPI_SD_HANDLE.Init.CLKPolarity = SPI_POLARITY_LOW; - SPI_SD_HANDLE.Init.CLKPhase = SPI_PHASE_1EDGE; - SPI_SD_HANDLE.Init.NSS = SPI_NSS_SOFT; - SPI_SD_HANDLE.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; - SPI_SD_HANDLE.Init.FirstBit = SPI_FIRSTBIT_MSB; - SPI_SD_HANDLE.Init.TIMode = SPI_TIMODE_DISABLE; - SPI_SD_HANDLE.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - SPI_SD_HANDLE.Init.CRCPolynomial = 7; - SPI_SD_HANDLE.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; - SPI_SD_HANDLE.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; - - if(HAL_SPI_Init(&SPI_SD_HANDLE) != HAL_OK) { - Error_Handler(); - } - - Enable_SPI(&SPI_SD_HANDLE); - - osKernelUnlock(); -} - -void CC1101_SPI_Reconfigure(void) { - osKernelLock(); - - SPI_R.Init.Mode = SPI_MODE_MASTER; - SPI_R.Init.Direction = SPI_DIRECTION_2LINES; - SPI_R.Init.DataSize = SPI_DATASIZE_8BIT; - SPI_R.Init.CLKPolarity = SPI_POLARITY_LOW; - SPI_R.Init.CLKPhase = SPI_PHASE_1EDGE; - SPI_R.Init.NSS = SPI_NSS_SOFT; - SPI_R.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; - SPI_R.Init.FirstBit = SPI_FIRSTBIT_MSB; - SPI_R.Init.TIMode = SPI_TIMODE_DISABLE; - SPI_R.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - SPI_R.Init.CRCPolynomial = 7; - SPI_R.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; - SPI_R.Init.NSSPMode = SPI_NSS_PULSE_DISABLE; - - if(HAL_SPI_Init(&SPI_R) != HAL_OK) { - Error_Handler(); - } - - Enable_SPI(&SPI_R); - - osKernelUnlock(); -} - -void Enable_SPI(SPI_HandleTypeDef* spi_instance){ - if((spi_instance->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) { - __HAL_SPI_ENABLE(spi_instance); - } -} - -void SD_SPI_Bus_To_Down_State(){ - GPIO_InitTypeDef GPIO_InitStruct = {0}; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - - GPIO_InitStruct.Pin = GPIO_PIN_2; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = SPI_D_MOSI_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(SPI_D_MOSI_GPIO_Port, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = SPI_D_SCK_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(SPI_D_SCK_GPIO_Port, &GPIO_InitStruct); - - HAL_GPIO_WritePin(SD_CS_GPIO_Port, SD_CS_Pin, GPIO_PIN_RESET); - HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET); - HAL_GPIO_WritePin(SPI_D_MOSI_GPIO_Port, SPI_D_MOSI_Pin, GPIO_PIN_RESET); - HAL_GPIO_WritePin(SPI_D_SCK_GPIO_Port, SPI_D_SCK_Pin, GPIO_PIN_RESET); -} - -void SD_SPI_Bus_To_Normal_State(){ - HAL_GPIO_WritePin(SD_CS_GPIO_Port, SD_CS_Pin, GPIO_PIN_SET); - HAL_SPI_MspInit(&SPI_SD_HANDLE); -} -/* USER CODE END 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f6/Src/stm32wbxx_it.c b/firmware/targets/f6/Src/stm32wbxx_it.c index 5511cfe5f87..01fbdc1d2a9 100644 --- a/firmware/targets/f6/Src/stm32wbxx_it.c +++ b/firmware/targets/f6/Src/stm32wbxx_it.c @@ -4,7 +4,6 @@ #include "task.h" extern PCD_HandleTypeDef hpcd_USB_FS; -extern ADC_HandleTypeDef hadc1; extern COMP_HandleTypeDef hcomp1; extern RTC_HandleTypeDef hrtc; extern TIM_HandleTypeDef htim1; @@ -20,10 +19,6 @@ void SysTick_Handler(void) { HAL_IncTick(); } -void ADC1_IRQHandler(void) { - HAL_ADC_IRQHandler(&hadc1); -} - void USB_LP_IRQHandler(void) { HAL_PCD_IRQHandler(&hpcd_USB_FS); } diff --git a/firmware/targets/f6/Src/usbd_cdc_if.c b/firmware/targets/f6/Src/usbd_cdc_if.c index cd6946c43b9..8a7b5913a5e 100644 --- a/firmware/targets/f6/Src/usbd_cdc_if.c +++ b/firmware/targets/f6/Src/usbd_cdc_if.c @@ -51,11 +51,11 @@ /* USER CODE BEGIN PRIVATE_TYPES */ -extern void _api_hal_vcp_init(); -extern void _api_hal_vcp_deinit(); -extern void _api_hal_vcp_control_line(uint8_t state); -extern void _api_hal_vcp_rx_callback(char* buffer, size_t size); -extern void _api_hal_vcp_tx_complete(size_t size); +extern void _furi_hal_vcp_init(); +extern void _furi_hal_vcp_deinit(); +extern void _furi_hal_vcp_control_line(uint8_t state); +extern void _furi_hal_vcp_rx_callback(char* buffer, size_t size); +extern void _furi_hal_vcp_tx_complete(size_t size); /* USER CODE END PRIVATE_TYPES */ @@ -162,7 +162,7 @@ static int8_t CDC_Init_FS(void) /* Set Application Buffers */ USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0); USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS); - _api_hal_vcp_init(); + _furi_hal_vcp_init(); return (USBD_OK); /* USER CODE END 3 */ } @@ -174,7 +174,7 @@ static int8_t CDC_Init_FS(void) static int8_t CDC_DeInit_FS(void) { /* USER CODE BEGIN 4 */ - _api_hal_vcp_deinit(); + _furi_hal_vcp_deinit(); return (USBD_OK); /* USER CODE END 4 */ } @@ -214,7 +214,7 @@ static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length) /*******************************************************************************/ } else if (cmd == CDC_GET_LINE_CODING) { } else if (cmd == CDC_SET_CONTROL_LINE_STATE) { - _api_hal_vcp_control_line(((USBD_SetupReqTypedef*)pbuf)->wValue); + _furi_hal_vcp_control_line(((USBD_SetupReqTypedef*)pbuf)->wValue); } else if (cmd == CDC_SEND_BREAK) { } else { } @@ -241,7 +241,7 @@ static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length) static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ - _api_hal_vcp_rx_callback((char*)Buf, *Len); + _furi_hal_vcp_rx_callback((char*)Buf, *Len); USBD_CDC_ReceivePacket(&hUsbDeviceFS); return (USBD_OK); /* USER CODE END 6 */ @@ -291,7 +291,7 @@ static int8_t CDC_TransmitCplt_FS(uint8_t *Buf, uint32_t *Len, uint8_t epnum) /* USER CODE BEGIN 13 */ UNUSED(Buf); UNUSED(epnum); - _api_hal_vcp_tx_complete(*Len); + _furi_hal_vcp_tx_complete(*Len); /* USER CODE END 13 */ return result; } diff --git a/firmware/targets/f6/Src/usbd_desc.c b/firmware/targets/f6/Src/usbd_desc.c index 360353ffff9..9e7c548399c 100644 --- a/firmware/targets/f6/Src/usbd_desc.c +++ b/firmware/targets/f6/Src/usbd_desc.c @@ -23,7 +23,7 @@ #include "usbd_core.h" #include "usbd_desc.h" #include "usbd_conf.h" -#include "api-hal-version.h" +#include "furi-hal-version.h" /* USER CODE BEGIN INCLUDE */ /* USER CODE END INCLUDE */ @@ -245,7 +245,7 @@ uint8_t * USBD_CDC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length */ uint8_t * USBD_CDC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) { - USBD_GetString((uint8_t*)api_hal_version_get_device_name_ptr(), USBD_StrDesc, length); + USBD_GetString((uint8_t*)furi_hal_version_get_device_name_ptr(), USBD_StrDesc, length); return USBD_StrDesc; } @@ -275,9 +275,9 @@ uint8_t * USBD_CDC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length /* Update the serial number string descriptor with the data from the unique * ID */ - if(api_hal_version_get_name_ptr()){ + if(furi_hal_version_get_name_ptr()){ char buffer[14] = "flip_"; - strncat(buffer, api_hal_version_get_name_ptr(), 8); + strncat(buffer, furi_hal_version_get_name_ptr(), 8); USBD_GetString((uint8_t*) buffer, USBD_StringSerial, length); } else { Get_SerialNum(); diff --git a/firmware/targets/f6/api-hal/api-hal-clock.h b/firmware/targets/f6/api-hal/api-hal-clock.h deleted file mode 100644 index 077d4f3f708..00000000000 --- a/firmware/targets/f6/api-hal/api-hal-clock.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -/** Initialize clocks */ -void api_hal_clock_init(); - -/** Switch to HSI clock */ -void api_hal_clock_switch_to_hsi(); - -/** Switch to PLL clock */ -void api_hal_clock_switch_to_pll(); diff --git a/firmware/targets/f6/api-hal/api-hal-flash.c b/firmware/targets/f6/api-hal/api-hal-flash.c deleted file mode 100644 index 97a9afa2832..00000000000 --- a/firmware/targets/f6/api-hal/api-hal-flash.c +++ /dev/null @@ -1,88 +0,0 @@ -#include -#include -#include -#include - -/* Free flash space borders, exported by linker */ -extern const void __free_flash_start__; -extern const void __free_flash_end__; - -#define API_HAL_FLASH_READ_BLOCK 8 -#define API_HAL_FLASH_WRITE_BLOCK 8 -#define API_HAL_FLASH_PAGE_SIZE 4096 -#define API_HAL_FLASH_CYCLES_COUNT 10000 - -size_t api_hal_flash_get_base() { - return FLASH_BASE; -} - -size_t api_hal_flash_get_read_block_size() { - return API_HAL_FLASH_READ_BLOCK; -} - -size_t api_hal_flash_get_write_block_size() { - return API_HAL_FLASH_WRITE_BLOCK; -} - -size_t api_hal_flash_get_page_size() { - return API_HAL_FLASH_PAGE_SIZE; -} - -size_t api_hal_flash_get_cycles_count() { - return API_HAL_FLASH_CYCLES_COUNT; -} - -const void* api_hal_flash_get_free_start_address() { - return &__free_flash_start__; -} - -const void* api_hal_flash_get_free_end_address() { - return &__free_flash_end__; -} - -size_t api_hal_flash_get_free_page_start_address() { - size_t start = (size_t)api_hal_flash_get_free_start_address(); - size_t page_start = start - start % API_HAL_FLASH_PAGE_SIZE; - if (page_start != start) { - page_start += API_HAL_FLASH_PAGE_SIZE; - } - return page_start; -} - -size_t api_hal_flash_get_free_page_count() { - size_t end = (size_t)api_hal_flash_get_free_end_address(); - size_t page_start = (size_t)api_hal_flash_get_free_page_start_address(); - return (end-page_start) / API_HAL_FLASH_PAGE_SIZE; -} - -bool api_hal_flash_erase(uint8_t page, uint8_t count) { - if (!api_hal_bt_lock_flash()) { - return false; - } - FLASH_EraseInitTypeDef erase; - erase.TypeErase = FLASH_TYPEERASE_PAGES; - erase.Page = page; - erase.NbPages = count; - uint32_t error; - HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase, &error); - api_hal_bt_unlock_flash(); - return status == HAL_OK; -} - -bool api_hal_flash_write_dword(size_t address, uint64_t data) { - if (!api_hal_bt_lock_flash()) { - return false; - } - HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data); - api_hal_bt_unlock_flash(); - return status == HAL_OK; -} - -bool api_hal_flash_write_dword_from(size_t address, size_t source_address) { - if (!api_hal_bt_lock_flash()) { - return false; - } - HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FAST, address, source_address); - api_hal_bt_unlock_flash(); - return status == HAL_OK; -} diff --git a/firmware/targets/f6/api-hal/api-hal-os-timer.h b/firmware/targets/f6/api-hal/api-hal-os-timer.h deleted file mode 100644 index f700e6b6393..00000000000 --- a/firmware/targets/f6/api-hal/api-hal-os-timer.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include -#include -#include - -// Timer used for system ticks -#define API_HAL_OS_TIMER_MAX 0xFFFF -#define API_HAL_OS_TIMER_REG_LOAD_DLY 0x1 -#define API_HAL_OS_TIMER LPTIM2 -#define API_HAL_OS_TIMER_IRQ LPTIM2_IRQn - -static inline void api_hal_os_timer_init() { - // Configure clock source - LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_LSE); - LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPTIM2); - // Set interrupt priority and enable them - NVIC_SetPriority(API_HAL_OS_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0)); - NVIC_EnableIRQ(API_HAL_OS_TIMER_IRQ); -} - -static inline void api_hal_os_timer_continuous(uint32_t count) { - // Enable timer - LL_LPTIM_Enable(API_HAL_OS_TIMER); - while(!LL_LPTIM_IsEnabled(API_HAL_OS_TIMER)); - - // Enable rutoreload match interrupt - LL_LPTIM_EnableIT_ARRM(API_HAL_OS_TIMER); - - // Set autoreload and start counter - LL_LPTIM_SetAutoReload(API_HAL_OS_TIMER, count); - LL_LPTIM_StartCounter(API_HAL_OS_TIMER, LL_LPTIM_OPERATING_MODE_CONTINUOUS); -} - -static inline void api_hal_os_timer_single(uint32_t count) { - // Enable timer - LL_LPTIM_Enable(API_HAL_OS_TIMER); - while(!LL_LPTIM_IsEnabled(API_HAL_OS_TIMER)); - - // Enable compare match interrupt - LL_LPTIM_EnableIT_CMPM(API_HAL_OS_TIMER); - - // Set compare, autoreload and start counter - // Include some marging to workaround ARRM behaviour - LL_LPTIM_SetCompare(API_HAL_OS_TIMER, count-3); - LL_LPTIM_SetAutoReload(API_HAL_OS_TIMER, count); - LL_LPTIM_StartCounter(API_HAL_OS_TIMER, LL_LPTIM_OPERATING_MODE_ONESHOT); -} - -static inline void api_hal_os_timer_reset() { - // Hard reset timer - // THE ONLY RELIABLEWAY to stop it according to errata - LL_LPTIM_DeInit(API_HAL_OS_TIMER); -} - -static inline uint32_t api_hal_os_timer_get_cnt() { - uint32_t counter = LL_LPTIM_GetCounter(API_HAL_OS_TIMER); - uint32_t counter_shadow = LL_LPTIM_GetCounter(API_HAL_OS_TIMER); - while(counter != counter_shadow) { - counter = counter_shadow; - counter_shadow = LL_LPTIM_GetCounter(API_HAL_OS_TIMER); - } - return counter; -} diff --git a/firmware/targets/f6/api-hal/api-hal-spi-config.c b/firmware/targets/f6/api-hal/api-hal-spi-config.c deleted file mode 100644 index 51a1729e826..00000000000 --- a/firmware/targets/f6/api-hal/api-hal-spi-config.c +++ /dev/null @@ -1,118 +0,0 @@ -#include -#include - -extern SPI_HandleTypeDef SPI_R; -extern SPI_HandleTypeDef SPI_D; - -const SPI_InitTypeDef api_hal_spi_config_nfc = { - .Mode = SPI_MODE_MASTER, - .Direction = SPI_DIRECTION_2LINES, - .DataSize = SPI_DATASIZE_8BIT, - .CLKPolarity = SPI_POLARITY_LOW, - .CLKPhase = SPI_PHASE_2EDGE, - .NSS = SPI_NSS_SOFT, - .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8, - .FirstBit = SPI_FIRSTBIT_MSB, - .TIMode = SPI_TIMODE_DISABLE, - .CRCCalculation = SPI_CRCCALCULATION_DISABLE, - .CRCPolynomial = 7, - .CRCLength = SPI_CRC_LENGTH_DATASIZE, - .NSSPMode = SPI_NSS_PULSE_DISABLE, -}; - -const SPI_InitTypeDef api_hal_spi_config_subghz = { - .Mode = SPI_MODE_MASTER, - .Direction = SPI_DIRECTION_2LINES, - .DataSize = SPI_DATASIZE_8BIT, - .CLKPolarity = SPI_POLARITY_LOW, - .CLKPhase = SPI_PHASE_1EDGE, - .NSS = SPI_NSS_SOFT, - .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8, - .FirstBit = SPI_FIRSTBIT_MSB, - .TIMode = SPI_TIMODE_DISABLE, - .CRCCalculation = SPI_CRCCALCULATION_DISABLE, - .CRCPolynomial = 7, - .CRCLength = SPI_CRC_LENGTH_DATASIZE, - .NSSPMode = SPI_NSS_PULSE_DISABLE, -}; - -const SPI_InitTypeDef api_hal_spi_config_display = { - .Mode = SPI_MODE_MASTER, - .Direction = SPI_DIRECTION_2LINES, - .DataSize = SPI_DATASIZE_8BIT, - .CLKPolarity = SPI_POLARITY_LOW, - .CLKPhase = SPI_PHASE_1EDGE, - .NSS = SPI_NSS_SOFT, - .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16, - .FirstBit = SPI_FIRSTBIT_MSB, - .TIMode = SPI_TIMODE_DISABLE, - .CRCCalculation = SPI_CRCCALCULATION_DISABLE, - .CRCPolynomial = 7, - .CRCLength = SPI_CRC_LENGTH_DATASIZE, - .NSSPMode = SPI_NSS_PULSE_ENABLE, -}; - -/** - * SD Card in fast mode (after init) - */ -const SPI_InitTypeDef api_hal_spi_config_sd_fast = { - .Mode = SPI_MODE_MASTER, - .Direction = SPI_DIRECTION_2LINES, - .DataSize = SPI_DATASIZE_8BIT, - .CLKPolarity = SPI_POLARITY_LOW, - .CLKPhase = SPI_PHASE_1EDGE, - .NSS = SPI_NSS_SOFT, - .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2, - .FirstBit = SPI_FIRSTBIT_MSB, - .TIMode = SPI_TIMODE_DISABLE, - .CRCCalculation = SPI_CRCCALCULATION_DISABLE, - .CRCPolynomial = 7, - .CRCLength = SPI_CRC_LENGTH_DATASIZE, - .NSSPMode = SPI_NSS_PULSE_ENABLE, -}; - -/** - * SD Card in slow mode (before init) - */ -const SPI_InitTypeDef api_hal_spi_config_sd_slow = { - .Mode = SPI_MODE_MASTER, - .Direction = SPI_DIRECTION_2LINES, - .DataSize = SPI_DATASIZE_8BIT, - .CLKPolarity = SPI_POLARITY_LOW, - .CLKPhase = SPI_PHASE_1EDGE, - .NSS = SPI_NSS_SOFT, - .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32, - .FirstBit = SPI_FIRSTBIT_MSB, - .TIMode = SPI_TIMODE_DISABLE, - .CRCCalculation = SPI_CRCCALCULATION_DISABLE, - .CRCPolynomial = 7, - .CRCLength = SPI_CRC_LENGTH_DATASIZE, - .NSSPMode = SPI_NSS_PULSE_ENABLE, -}; - -osMutexId_t spi_mutex_d = NULL; -osMutexId_t spi_mutex_r = NULL; - -const ApiHalSpiBus spi_r = { - .spi=&SPI_R, - .mutex=&spi_mutex_r, - .miso=&gpio_spi_r_miso, - .mosi=&gpio_spi_r_mosi, - .clk=&gpio_spi_r_sck, -}; - -const ApiHalSpiBus spi_d = { - .spi=&SPI_D, - .mutex=&spi_mutex_d, - .miso=&gpio_spi_d_miso, - .mosi=&gpio_spi_d_mosi, - .clk=&gpio_spi_d_sck, -}; - -const ApiHalSpiDevice api_hal_spi_devices[ApiHalSpiDeviceIdMax] = { - { .bus=&spi_r, .config=&api_hal_spi_config_subghz, .chip_select=&gpio_subghz_cs, }, - { .bus=&spi_d, .config=&api_hal_spi_config_display, .chip_select=&gpio_display_cs, }, - { .bus=&spi_d, .config=&api_hal_spi_config_sd_fast, .chip_select=&gpio_sdcard_cs, }, - { .bus=&spi_d, .config=&api_hal_spi_config_sd_slow, .chip_select=&gpio_sdcard_cs, }, - { .bus=&spi_r, .config=&api_hal_spi_config_nfc, .chip_select=&gpio_nfc_cs }, -}; diff --git a/firmware/targets/f6/api-hal/api-hal-spi-config.h b/firmware/targets/f6/api-hal/api-hal-spi-config.h deleted file mode 100644 index c8a3da1b2cc..00000000000 --- a/firmware/targets/f6/api-hal/api-hal-spi-config.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern const SPI_InitTypeDef api_hal_spi_config_nfc; -extern const SPI_InitTypeDef api_hal_spi_config_subghz; -extern const SPI_InitTypeDef api_hal_spi_config_display; -extern const SPI_InitTypeDef api_hal_spi_config_sd_fast; -extern const SPI_InitTypeDef api_hal_spi_config_sd_slow; - -/** API HAL SPI BUS handler - * Structure content may change at some point - */ -typedef struct { - const SPI_HandleTypeDef* spi; - const osMutexId_t* mutex; - const GpioPin* miso; - const GpioPin* mosi; - const GpioPin* clk; -} ApiHalSpiBus; - -/** API HAL SPI Device handler - * Structure content may change at some point - */ -typedef struct { - const ApiHalSpiBus* bus; - const SPI_InitTypeDef* config; - const GpioPin* chip_select; -} ApiHalSpiDevice; - -/** API HAL SPI Standard Device IDs */ -typedef enum { - ApiHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ - ApiHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ - ApiHalSpiDeviceIdSdCardFast, /** SDCARD: fast mode, after initialization */ - ApiHalSpiDeviceIdSdCardSlow, /** SDCARD: slow mode, before initialization */ - ApiHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ - - ApiHalSpiDeviceIdMax, /** Service Value, do not use */ -} ApiHalSpiDeviceId; - -/** Api Hal Spi Bus R - * CC1101, Nfc - */ -extern const ApiHalSpiBus spi_r; - -/** Api Hal Spi Bus D - * Display, SdCard - */ -extern const ApiHalSpiBus spi_d; - -/** Api Hal Spi devices */ -extern const ApiHalSpiDevice api_hal_spi_devices[ApiHalSpiDeviceIdMax]; - -typedef struct { - const ApiHalSpiBus* bus; - const SPI_InitTypeDef config; -} SPIDevice; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/firmware/targets/f6/api-hal/api-hal-spi.c b/firmware/targets/f6/api-hal/api-hal-spi.c deleted file mode 100644 index cffdc59115f..00000000000 --- a/firmware/targets/f6/api-hal/api-hal-spi.c +++ /dev/null @@ -1,168 +0,0 @@ -#include "api-hal-spi.h" -#include -#include -#include -#include -#include - - -extern void Enable_SPI(SPI_HandleTypeDef* spi); - -void api_hal_spi_init() { - // Spi structure is const, but mutex is not - // Need some hell-ish casting to make it work - *(osMutexId_t*)spi_r.mutex = osMutexNew(NULL); - *(osMutexId_t*)spi_d.mutex = osMutexNew(NULL); - // - for (size_t i=0; imutex) { - osMutexAcquire(*bus->mutex, osWaitForever); - } -} - -void api_hal_spi_bus_unlock(const ApiHalSpiBus* bus) { - furi_assert(bus); - if (bus->mutex) { - osMutexRelease(*bus->mutex); - } -} - -void api_hal_spi_bus_configure(const ApiHalSpiBus* bus, const SPI_InitTypeDef* config) { - furi_assert(bus); - - if(memcmp(&bus->spi->Init, config, sizeof(SPI_InitTypeDef))) { - memcpy((SPI_InitTypeDef*)&bus->spi->Init, config, sizeof(SPI_InitTypeDef)); - if(HAL_SPI_Init((SPI_HandleTypeDef*)bus->spi) != HAL_OK) { - Error_Handler(); - } - Enable_SPI((SPI_HandleTypeDef*)bus->spi); - } -} - -void api_hal_spi_bus_reset(const ApiHalSpiBus* bus) { - furi_assert(bus); - - HAL_SPI_DeInit((SPI_HandleTypeDef*)bus->spi); - HAL_SPI_Init((SPI_HandleTypeDef*)bus->spi); - Enable_SPI((SPI_HandleTypeDef*)bus->spi); -} - -bool api_hal_spi_bus_rx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(bus); - furi_assert(buffer); - furi_assert(size > 0); - - HAL_StatusTypeDef ret = HAL_SPI_Receive((SPI_HandleTypeDef *)bus->spi, buffer, size, HAL_MAX_DELAY); - - return ret == HAL_OK; -} - -bool api_hal_spi_bus_tx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(bus); - furi_assert(buffer); - furi_assert(size > 0); - - HAL_StatusTypeDef ret = HAL_SPI_Transmit((SPI_HandleTypeDef *)bus->spi, buffer, size, HAL_MAX_DELAY); - - return ret == HAL_OK; -} - -bool api_hal_spi_bus_trx(const ApiHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { - furi_assert(bus); - furi_assert(tx_buffer); - furi_assert(rx_buffer); - furi_assert(size > 0); - - HAL_StatusTypeDef ret = HAL_SPI_TransmitReceive((SPI_HandleTypeDef *)bus->spi, tx_buffer, rx_buffer, size, HAL_MAX_DELAY); - - return ret == HAL_OK; -} - -const ApiHalSpiDevice* api_hal_spi_device_get(ApiHalSpiDeviceId device_id) { - furi_assert(device_id < ApiHalSpiDeviceIdMax); - - const ApiHalSpiDevice* device = &api_hal_spi_devices[device_id]; - assert(device); - api_hal_spi_bus_lock(device->bus); - - if (device->config) { - memcpy((SPI_InitTypeDef*)&device->bus->spi->Init, device->config, sizeof(SPI_InitTypeDef)); - if(HAL_SPI_Init((SPI_HandleTypeDef *)device->bus->spi) != HAL_OK) { - Error_Handler(); - } - Enable_SPI((SPI_HandleTypeDef *)device->bus->spi); - } - - return device; -} - -void api_hal_spi_device_return(const ApiHalSpiDevice* device) { - api_hal_spi_bus_unlock(device->bus); -} - -bool api_hal_spi_device_rx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(device); - furi_assert(buffer); - furi_assert(size > 0); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = api_hal_spi_bus_rx(device->bus, buffer, size, HAL_MAX_DELAY); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, true); - } - - return ret; -} - -bool api_hal_spi_device_tx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(device); - furi_assert(buffer); - furi_assert(size > 0); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = api_hal_spi_bus_tx(device->bus, buffer, size, HAL_MAX_DELAY); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, true); - } - - return ret; -} - -bool api_hal_spi_device_trx(const ApiHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { - furi_assert(device); - furi_assert(tx_buffer); - furi_assert(rx_buffer); - furi_assert(size > 0); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = api_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, HAL_MAX_DELAY); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, true); - } - - return ret; -} diff --git a/firmware/targets/f6/api-hal/api-hal-vcp.c b/firmware/targets/f6/api-hal/api-hal-vcp.c deleted file mode 100644 index 296ee1e8a90..00000000000 --- a/firmware/targets/f6/api-hal/api-hal-vcp.c +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include -#include -#include - -#define API_HAL_VCP_RX_BUFFER_SIZE 600 - -typedef struct { - StreamBufferHandle_t rx_stream; - osSemaphoreId_t tx_semaphore; - volatile bool alive; - volatile bool underrun; -} ApiHalVcp; - -static ApiHalVcp* api_hal_vcp = NULL; - -static const uint8_t ascii_soh = 0x01; -static const uint8_t ascii_eot = 0x04; - -void _api_hal_vcp_init(); -void _api_hal_vcp_deinit(); -void _api_hal_vcp_control_line(uint8_t state); -void _api_hal_vcp_rx_callback(const uint8_t* buffer, size_t size); -void _api_hal_vcp_tx_complete(size_t size); - -void api_hal_vcp_init() { - api_hal_vcp = furi_alloc(sizeof(ApiHalVcp)); - api_hal_vcp->rx_stream = xStreamBufferCreate(API_HAL_VCP_RX_BUFFER_SIZE, 1); - api_hal_vcp->tx_semaphore = osSemaphoreNew(1, 1, NULL); - api_hal_vcp->alive = false; - api_hal_vcp->underrun = false; - FURI_LOG_I("FuriHalVcp", "Init OK"); -} - -void _api_hal_vcp_init() { - osSemaphoreRelease(api_hal_vcp->tx_semaphore); -} - -void _api_hal_vcp_deinit() { - api_hal_vcp->alive = false; - osSemaphoreRelease(api_hal_vcp->tx_semaphore); -} - -void _api_hal_vcp_control_line(uint8_t state) { - // bit 0: DTR state, bit 1: RTS state - // bool dtr = state & 0b01; - bool dtr = state & 0b1; - - if (dtr) { - if (!api_hal_vcp->alive) { - api_hal_vcp->alive = true; - _api_hal_vcp_rx_callback(&ascii_soh, 1); // SOH - } - } else { - if (api_hal_vcp->alive) { - _api_hal_vcp_rx_callback(&ascii_eot, 1); // EOT - api_hal_vcp->alive = false; - } - } - - osSemaphoreRelease(api_hal_vcp->tx_semaphore); -} - -void _api_hal_vcp_rx_callback(const uint8_t* buffer, size_t size) { - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - size_t ret = xStreamBufferSendFromISR(api_hal_vcp->rx_stream, buffer, size, &xHigherPriorityTaskWoken); - if (ret != size) { - api_hal_vcp->underrun = true; - } - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); -} - -void _api_hal_vcp_tx_complete(size_t size) { - osSemaphoreRelease(api_hal_vcp->tx_semaphore); -} - -size_t api_hal_vcp_rx(uint8_t* buffer, size_t size) { - furi_assert(api_hal_vcp); - return xStreamBufferReceive(api_hal_vcp->rx_stream, buffer, size, portMAX_DELAY); -} - -size_t api_hal_vcp_rx_with_timeout(uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(api_hal_vcp); - return xStreamBufferReceive(api_hal_vcp->rx_stream, buffer, size, timeout); -} - -void api_hal_vcp_tx(const uint8_t* buffer, size_t size) { - furi_assert(api_hal_vcp); - - while (size > 0 && api_hal_vcp->alive) { - furi_check(osSemaphoreAcquire(api_hal_vcp->tx_semaphore, osWaitForever) == osOK); - - size_t batch_size = size; - if (batch_size > APP_TX_DATA_SIZE) { - batch_size = APP_TX_DATA_SIZE; - } - - if (CDC_Transmit_FS((uint8_t*)buffer, batch_size) == USBD_OK) { - size -= batch_size; - buffer += batch_size; - } else { - // Shouldn't be there - osDelay(100); - } - } -} diff --git a/firmware/targets/f6/api-hal/api-hal-version.c b/firmware/targets/f6/api-hal/api-hal-version.c deleted file mode 100644 index 761f57e1692..00000000000 --- a/firmware/targets/f6/api-hal/api-hal-version.c +++ /dev/null @@ -1,242 +0,0 @@ -#include - -#include -#include -#include - -#include -#include "ble.h" - -#define API_HAL_VERSION_OTP_HEADER_MAGIC 0xBABE -#define API_HAL_VERSION_NAME_LENGTH 8 -#define API_HAL_VERSION_ARRAY_NAME_LENGTH (API_HAL_VERSION_NAME_LENGTH + 1) -/** BLE symbol + "Flipper " + name */ -#define API_HAL_VERSION_DEVICE_NAME_LENGTH (1 + 8 + API_HAL_VERSION_ARRAY_NAME_LENGTH) -#define API_HAL_VERSION_OTP_ADDRESS OTP_AREA_BASE - -/** OTP Versions enum */ -typedef enum { - ApiHalVersionOtpVersion0=0x00, - ApiHalVersionOtpVersion1=0x01, - ApiHalVersionOtpVersionEmpty=0xFFFFFFFE, - ApiHalVersionOtpVersionUnknown=0xFFFFFFFF, -} ApiHalVersionOtpVersion; - -/** OTP V0 Structure: prototypes and early EVT */ -typedef struct { - uint8_t board_version; - uint8_t board_target; - uint8_t board_body; - uint8_t board_connect; - uint32_t header_timestamp; - char name[API_HAL_VERSION_NAME_LENGTH]; -} ApiHalVersionOTPv0; - -/** OTP V1 Structure: late EVT, DVT, PVT, Production */ -typedef struct { - /* First 64 bits: header */ - uint16_t header_magic; - uint8_t header_version; - uint8_t header_reserved; - uint32_t header_timestamp; - - /* Second 64 bits: board info */ - uint8_t board_version; /** Board version */ - uint8_t board_target; /** Board target firmware */ - uint8_t board_body; /** Board body */ - uint8_t board_connect; /** Board interconnect */ - uint8_t board_color; /** Board color */ - uint8_t board_region; /** Board region */ - uint16_t board_reserved; /** Reserved for future use, 0x0000 */ - - /* Third 64 bits: Unique Device Name */ - char name[API_HAL_VERSION_NAME_LENGTH]; /** Unique Device Name */ -} ApiHalVersionOTPv1; - -/** Represenation Model: */ -typedef struct { - ApiHalVersionOtpVersion otp_version; - - uint32_t timestamp; - - uint8_t board_version; /** Board version */ - uint8_t board_target; /** Board target firmware */ - uint8_t board_body; /** Board body */ - uint8_t board_connect; /** Board interconnect */ - uint8_t board_color; /** Board color */ - uint8_t board_region; /** Board region */ - - char name[API_HAL_VERSION_ARRAY_NAME_LENGTH]; /** \0 terminated name */ - char device_name[API_HAL_VERSION_DEVICE_NAME_LENGTH]; /** device name for special needs */ - uint8_t ble_mac[6]; -} ApiHalVersion; - -static ApiHalVersion api_hal_version = {0}; - -static ApiHalVersionOtpVersion api_hal_version_get_otp_version() { - if (*(uint64_t*)API_HAL_VERSION_OTP_ADDRESS == 0xFFFFFFFF) { - return ApiHalVersionOtpVersionEmpty; - } else { - if (((ApiHalVersionOTPv1*)API_HAL_VERSION_OTP_ADDRESS)->header_magic == API_HAL_VERSION_OTP_HEADER_MAGIC) { - return ApiHalVersionOtpVersion1; - } else if (((ApiHalVersionOTPv0*)API_HAL_VERSION_OTP_ADDRESS)->board_version <= 10) { - return ApiHalVersionOtpVersion0; - } else { - return ApiHalVersionOtpVersionUnknown; - } - } -} - -static void api_hal_version_set_name(const char* name) { - if(name != NULL) { - strlcpy(api_hal_version.name, name, API_HAL_VERSION_ARRAY_NAME_LENGTH); - snprintf( - api_hal_version.device_name, - API_HAL_VERSION_DEVICE_NAME_LENGTH, - "xFlipper %s", - api_hal_version.name); - } else { - snprintf( - api_hal_version.device_name, - API_HAL_VERSION_DEVICE_NAME_LENGTH, - "xFlipper"); - } - - api_hal_version.device_name[0] = AD_TYPE_COMPLETE_LOCAL_NAME; - - // BLE Mac address - uint32_t udn = LL_FLASH_GetUDN(); - uint32_t company_id = LL_FLASH_GetSTCompanyID(); - uint32_t device_id = LL_FLASH_GetDeviceID(); - api_hal_version.ble_mac[0] = (uint8_t)(udn & 0x000000FF); - api_hal_version.ble_mac[1] = (uint8_t)( (udn & 0x0000FF00) >> 8 ); - api_hal_version.ble_mac[2] = (uint8_t)( (udn & 0x00FF0000) >> 16 ); - api_hal_version.ble_mac[3] = (uint8_t)device_id; - api_hal_version.ble_mac[4] = (uint8_t)(company_id & 0x000000FF); - api_hal_version.ble_mac[5] = (uint8_t)( (company_id & 0x0000FF00) >> 8 ); -} - -static void api_hal_version_load_otp_default() { - api_hal_version_set_name(NULL); -} - -static void api_hal_version_load_otp_v0() { - const ApiHalVersionOTPv0* otp = (ApiHalVersionOTPv0*)API_HAL_VERSION_OTP_ADDRESS; - - api_hal_version.timestamp = otp->header_timestamp; - api_hal_version.board_version = otp->board_version; - api_hal_version.board_target = otp->board_target; - api_hal_version.board_body = otp->board_body; - api_hal_version.board_connect = otp->board_connect; - api_hal_version.board_color = 0; - api_hal_version.board_region = 0; - - api_hal_version_set_name(otp->name); -} - -static void api_hal_version_load_otp_v1() { - const ApiHalVersionOTPv1* otp = (ApiHalVersionOTPv1*)API_HAL_VERSION_OTP_ADDRESS; - - api_hal_version.timestamp = otp->header_timestamp; - api_hal_version.board_version = otp->board_version; - api_hal_version.board_target = otp->board_target; - api_hal_version.board_body = otp->board_body; - api_hal_version.board_connect = otp->board_connect; - api_hal_version.board_color = otp->board_color; - api_hal_version.board_region = otp->board_region; - - api_hal_version_set_name(otp->name); -} - -void api_hal_version_init() { - api_hal_version.otp_version = api_hal_version_get_otp_version(); - switch(api_hal_version.otp_version) { - case ApiHalVersionOtpVersionUnknown: - api_hal_version_load_otp_default(); - break; - case ApiHalVersionOtpVersionEmpty: - api_hal_version_load_otp_default(); - break; - case ApiHalVersionOtpVersion0: - api_hal_version_load_otp_v0(); - break; - case ApiHalVersionOtpVersion1: - api_hal_version_load_otp_v1(); - break; - default: furi_check(0); - } - FURI_LOG_I("FuriHalVersion", "Init OK"); -} - -bool api_hal_version_do_i_belong_here() { - return api_hal_version_get_hw_target() == 6; -} - -const char* api_hal_version_get_model_name() { - return "Flipper Zero"; -} - -const uint8_t api_hal_version_get_hw_version() { - return api_hal_version.board_version; -} - -const uint8_t api_hal_version_get_hw_target() { - return api_hal_version.board_target; -} - -const uint8_t api_hal_version_get_hw_body() { - return api_hal_version.board_body; -} - -const ApiHalVersionColor api_hal_version_get_hw_color() { - return api_hal_version.board_color; -} - -const uint8_t api_hal_version_get_hw_connect() { - return api_hal_version.board_connect; -} - -const ApiHalVersionRegion api_hal_version_get_hw_region() { - return api_hal_version.board_region; -} - -const uint32_t api_hal_version_get_hw_timestamp() { - return api_hal_version.timestamp; -} - -const char* api_hal_version_get_name_ptr() { - return *api_hal_version.name == 0x00 ? NULL : api_hal_version.name; -} - -const char* api_hal_version_get_device_name_ptr() { - return api_hal_version.device_name + 1; -} - -const char* api_hal_version_get_ble_local_device_name_ptr() { - return api_hal_version.device_name; -} - -const uint8_t* api_hal_version_get_ble_mac() { - return api_hal_version.ble_mac; -} - -const struct Version* api_hal_version_get_firmware_version(void) { - return version_get(); -} - -const struct Version* api_hal_version_get_boot_version(void) { -#ifdef NO_BOOTLOADER - return 0; -#else - /* Backup register which points to structure in flash memory */ - return (const struct Version*)LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR1); -#endif -} - -size_t api_hal_version_uid_size() { - return 64/8; -} - -const uint8_t* api_hal_version_uid() { - return (const uint8_t *)UID64_BASE; -} diff --git a/firmware/targets/f6/ble-glue/app_ble.c b/firmware/targets/f6/ble-glue/app_ble.c index 634001c361d..18ca03ae132 100644 --- a/firmware/targets/f6/ble-glue/app_ble.c +++ b/firmware/targets/f6/ble-glue/app_ble.c @@ -14,7 +14,7 @@ #include "dis_app.h" #include "hrs_app.h" -#include +#include typedef struct _tSecurityParams { uint8_t ioCapability; @@ -223,7 +223,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) } /* restart advertising */ Adv_Request(APP_BLE_FAST_ADV); - api_hal_power_insomnia_exit(); + furi_hal_power_insomnia_exit(); } break; /* EVT_DISCONN_COMPLETE */ @@ -272,7 +272,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) break; case EVT_LE_CONN_COMPLETE: { - api_hal_power_insomnia_enter(); + furi_hal_power_insomnia_enter(); hci_le_connection_complete_event_rp0 *connection_complete_event; /** @@ -538,7 +538,7 @@ static void Ble_Hci_Gap_Gatt_Init() { if (role > 0) { - const char *name = api_hal_version_get_device_name_ptr(); + const char *name = furi_hal_version_get_device_name_ptr(); aci_gap_init(role, 0, strlen(name), &gap_service_handle, &gap_dev_name_char_handle, &gap_appearance_char_handle); @@ -640,7 +640,7 @@ static void Adv_Request(APP_BLE_ConnStatus_t New_Status) BleApplicationContext.Device_Connection_Status = New_Status; - const char* name = api_hal_version_get_ble_local_device_name_ptr(); + const char* name = furi_hal_version_get_ble_local_device_name_ptr(); /* Start Fast or Low Power Advertising */ ret = aci_gap_set_discoverable( diff --git a/firmware/targets/f6/ble-glue/app_debug.c b/firmware/targets/f6/ble-glue/app_debug.c index f5b2036d98b..0e09f44fc47 100644 --- a/firmware/targets/f6/ble-glue/app_debug.c +++ b/firmware/targets/f6/ble-glue/app_debug.c @@ -27,7 +27,7 @@ #include "shci.h" #include "tl.h" #include "dbg_trace.h" -#include +#include /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -358,7 +358,7 @@ void DbgOutputInit( void ) void DbgOutputTraces( uint8_t *p_data, uint16_t size, void (*cb)(void) ) { - api_hal_console_tx(p_data, size); + furi_hal_console_tx(p_data, size); cb(); } #endif diff --git a/firmware/targets/f6/ble-glue/app_entry.c b/firmware/targets/f6/ble-glue/app_entry.c index 394669b59cf..2a8e35cc0a0 100644 --- a/firmware/targets/f6/ble-glue/app_entry.c +++ b/firmware/targets/f6/ble-glue/app_entry.c @@ -8,7 +8,7 @@ #include "shci_tl.h" #include "stm32_lpm.h" #include "app_debug.h" -#include +#include extern RTC_HandleTypeDef hrtc; @@ -52,7 +52,7 @@ void APPE_Init() { HW_TS_Init(hw_ts_InitMode_Full, &hrtc); /**< Initialize the TimerServer */ // APPD_Init(); - api_hal_power_insomnia_enter(); + furi_hal_power_insomnia_enter(); appe_Tl_Init(); /* Initialize all transport layers */ @@ -144,7 +144,7 @@ static void APPE_SysUserEvtRx( void * pPayload ) { } else { ble_glue_status = BleGlueStatusBroken; } - api_hal_power_insomnia_exit(); + furi_hal_power_insomnia_exit(); } /************************************************************* diff --git a/firmware/targets/f6/ble-glue/dis_app.c b/firmware/targets/f6/ble-glue/dis_app.c index 45bc4685a10..0bf6d4c0506 100644 --- a/firmware/targets/f6/ble-glue/dis_app.c +++ b/firmware/targets/f6/ble-glue/dis_app.c @@ -1,7 +1,7 @@ #include "app_common.h" #include "ble.h" #include "dis_app.h" -#include +#include #if ((BLE_CFG_DIS_SYSTEM_ID != 0) || (CFG_MENU_DEVICE_INFORMATION != 0)) static const uint8_t system_id[BLE_CFG_DIS_SYSTEM_ID_LEN_MAX] = { @@ -58,7 +58,7 @@ void DISAPP_Init(void) { * @param pPData * @return */ - const char* name = api_hal_version_get_device_name_ptr(); + const char* name = furi_hal_version_get_device_name_ptr(); dis_information_data.pPayload = (uint8_t*)name; dis_information_data.Length = strlen(name) + 1; DIS_UpdateChar(MODEL_NUMBER_UUID, &dis_information_data); diff --git a/firmware/targets/f6/ble-glue/tl_dbg_conf.h b/firmware/targets/f6/ble-glue/tl_dbg_conf.h index 81d924e353f..4c38cfb52c3 100644 --- a/firmware/targets/f6/ble-glue/tl_dbg_conf.h +++ b/firmware/targets/f6/ble-glue/tl_dbg_conf.h @@ -66,7 +66,7 @@ extern "C" { #endif #if (TL_SHCI_CMD_DBG_RAW_EN != 0) -#define TL_SHCI_CMD_DBG_RAW(_PDATA_, _SIZE_) api_hal_console_tx(_PDATA_, _SIZE_) +#define TL_SHCI_CMD_DBG_RAW(_PDATA_, _SIZE_) furi_hal_console_tx(_PDATA_, _SIZE_) #else #define TL_SHCI_CMD_DBG_RAW(...) #endif @@ -80,7 +80,7 @@ extern "C" { #endif #if (TL_SHCI_EVT_DBG_RAW_EN != 0) -#define TL_SHCI_EVT_DBG_RAW(_PDATA_, _SIZE_) api_hal_console_tx(_PDATA_, _SIZE_) +#define TL_SHCI_EVT_DBG_RAW(_PDATA_, _SIZE_) furi_hal_console_tx(_PDATA_, _SIZE_) #else #define TL_SHCI_EVT_DBG_RAW(...) #endif @@ -97,7 +97,7 @@ extern "C" { #endif #if (TL_HCI_CMD_DBG_RAW_EN != 0) -#define TL_HCI_CMD_DBG_RAW(_PDATA_, _SIZE_) api_hal_console_tx(_PDATA_, _SIZE_) +#define TL_HCI_CMD_DBG_RAW(_PDATA_, _SIZE_) furi_hal_console_tx(_PDATA_, _SIZE_) #else #define TL_HCI_CMD_DBG_RAW(...) #endif @@ -111,7 +111,7 @@ extern "C" { #endif #if (TL_HCI_EVT_DBG_RAW_EN != 0) -#define TL_HCI_EVT_DBG_RAW(_PDATA_, _SIZE_) api_hal_console_tx(_PDATA_, _SIZE_) +#define TL_HCI_EVT_DBG_RAW(_PDATA_, _SIZE_) furi_hal_console_tx(_PDATA_, _SIZE_) #else #define TL_HCI_EVT_DBG_RAW(...) #endif diff --git a/firmware/targets/f6/api-hal/api-hal-boot.c b/firmware/targets/f6/furi-hal/furi-hal-boot.c similarity index 67% rename from firmware/targets/f6/api-hal/api-hal-boot.c rename to firmware/targets/f6/furi-hal/furi-hal-boot.c index 5a868a930c4..978711c5aac 100644 --- a/firmware/targets/f6/api-hal/api-hal-boot.c +++ b/firmware/targets/f6/furi-hal/furi-hal-boot.c @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -7,25 +7,25 @@ #define BOOT_REQUEST_CLEAN 0xDADEDADE #define BOOT_REQUEST_DFU 0xDF00B000 -void api_hal_boot_init() { +void furi_hal_boot_init() { #ifndef DEBUG LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_TAINTED); #endif FURI_LOG_I("FuriHalBoot", "Init OK"); } -void api_hal_boot_set_mode(ApiHalBootMode mode) { - if (mode == ApiHalBootModeNormal) { +void furi_hal_boot_set_mode(FuriHalBootMode mode) { + if (mode == FuriHalBootModeNormal) { LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_CLEAN); - } else if (mode == ApiHalBootModeDFU) { + } else if (mode == FuriHalBootModeDFU) { LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_DFU); } } -void api_hal_boot_set_flags(ApiHalBootFlag flags) { +void furi_hal_boot_set_flags(FuriHalBootFlag flags) { LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR2, flags); } -ApiHalBootFlag api_hal_boot_get_flags() { +FuriHalBootFlag furi_hal_boot_get_flags() { return LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR2); } \ No newline at end of file diff --git a/firmware/targets/f6/api-hal/api-hal-bt.c b/firmware/targets/f6/furi-hal/furi-hal-bt.c similarity index 80% rename from firmware/targets/f6/api-hal/api-hal-bt.c rename to firmware/targets/f6/furi-hal/furi-hal-bt.c index bf432530ba8..ec14e85f210 100644 --- a/firmware/targets/f6/api-hal/api-hal-bt.c +++ b/firmware/targets/f6/furi-hal/furi-hal-bt.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -6,18 +6,18 @@ #include #include -void api_hal_bt_init() { +void furi_hal_bt_init() { // Explicitly tell that we are in charge of CLK48 domain HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID); // Start Core2, init HCI and start GAP/GATT APPE_Init(); } -bool api_hal_bt_start_app() { +bool furi_hal_bt_start_app() { return APP_BLE_Start(); } -void api_hal_bt_dump_state(string_t buffer) { +void furi_hal_bt_dump_state(string_t buffer) { BleGlueStatus status = APPE_Status(); if (status == BleGlueStatusStarted) { uint8_t HCI_Version; @@ -39,11 +39,11 @@ void api_hal_bt_dump_state(string_t buffer) { } } -bool api_hal_bt_is_alive() { +bool furi_hal_bt_is_alive() { return APPE_Status() == BleGlueStatusStarted; } -bool api_hal_bt_wait_transition() { +bool furi_hal_bt_wait_transition() { uint8_t counter = 0; while (APPE_Status() == BleGlueStatusStartup) { osDelay(10); @@ -55,8 +55,8 @@ bool api_hal_bt_wait_transition() { return true; } -bool api_hal_bt_lock_flash() { - if (!api_hal_bt_wait_transition()) { +bool furi_hal_bt_lock_flash() { + if (!furi_hal_bt_wait_transition()) { return false; } if (APPE_Status() == BleGlueStatusUninitialized) { @@ -72,7 +72,7 @@ bool api_hal_bt_lock_flash() { return true; } -void api_hal_bt_unlock_flash() { +void furi_hal_bt_unlock_flash() { if (APPE_Status() == BleGlueStatusUninitialized) { HAL_FLASH_Lock(); } else { @@ -82,34 +82,34 @@ void api_hal_bt_unlock_flash() { } } -void api_hal_bt_start_tone_tx(uint8_t channel, uint8_t power) { +void furi_hal_bt_start_tone_tx(uint8_t channel, uint8_t power) { aci_hal_set_tx_power_level(0, power); aci_hal_tone_start(channel, 0); } -void api_hal_bt_stop_tone_tx() { +void furi_hal_bt_stop_tone_tx() { aci_hal_tone_stop(); } -void api_hal_bt_start_packet_tx(uint8_t channel, uint8_t pattern, uint8_t datarate) { +void furi_hal_bt_start_packet_tx(uint8_t channel, uint8_t pattern, uint8_t datarate) { hci_le_enhanced_transmitter_test(channel, 0x25, pattern, datarate); } -void api_hal_bt_start_packet_rx(uint8_t channel, uint8_t datarate) { +void furi_hal_bt_start_packet_rx(uint8_t channel, uint8_t datarate) { hci_le_enhanced_receiver_test(channel, datarate, 0); } -uint16_t api_hal_bt_stop_packet_test() { +uint16_t furi_hal_bt_stop_packet_test() { uint16_t num_of_packets; hci_le_test_end(&num_of_packets); return num_of_packets; } -void api_hal_bt_start_rx(uint8_t channel) { +void furi_hal_bt_start_rx(uint8_t channel) { aci_hal_rx_start(channel); } -float api_hal_bt_get_rssi() { +float furi_hal_bt_get_rssi() { float val; uint8_t rssi_raw[3]; @@ -133,12 +133,12 @@ float api_hal_bt_get_rssi() { return val; } -uint32_t api_hal_bt_get_transmitted_packets() { +uint32_t furi_hal_bt_get_transmitted_packets() { uint32_t packets = 0; aci_hal_le_tx_test_packet_number(&packets); return packets; } -void api_hal_bt_stop_rx() { +void furi_hal_bt_stop_rx() { aci_hal_rx_stop(); } diff --git a/firmware/targets/f6/api-hal/api-hal-clock.c b/firmware/targets/f6/furi-hal/furi-hal-clock.c similarity index 94% rename from firmware/targets/f6/api-hal/api-hal-clock.c rename to firmware/targets/f6/furi-hal/furi-hal-clock.c index 8611a975712..59637ddbb12 100644 --- a/firmware/targets/f6/api-hal/api-hal-clock.c +++ b/firmware/targets/f6/furi-hal/furi-hal-clock.c @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -8,7 +8,7 @@ #define HS_CLOCK_IS_READY() (LL_RCC_HSE_IsReady() && LL_RCC_HSI_IsReady()) #define LS_CLOCK_IS_READY() (LL_RCC_LSE_IsReady() && LL_RCC_LSI1_IsReady()) -void api_hal_clock_init() { +void furi_hal_clock_init() { /* Prepare Flash memory for 64mHz system clock */ LL_FLASH_SetLatency(LL_FLASH_LATENCY_3); while(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_3); @@ -96,6 +96,7 @@ void api_hal_clock_init() { LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMAMUX1); LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1); LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); // AHB2 LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); @@ -104,6 +105,7 @@ void api_hal_clock_init() { LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOE); LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH); + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); // APB1 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB); @@ -113,7 +115,7 @@ void api_hal_clock_init() { LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); } -void api_hal_clock_switch_to_hsi() { +void furi_hal_clock_switch_to_hsi() { LL_RCC_HSI_Enable( ); while(!LL_RCC_HSI_IsReady()); @@ -124,7 +126,7 @@ void api_hal_clock_switch_to_hsi() { while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI); } -void api_hal_clock_switch_to_pll() { +void furi_hal_clock_switch_to_pll() { LL_RCC_HSE_Enable(); LL_RCC_PLL_Enable(); diff --git a/firmware/targets/f6/furi-hal/furi-hal-clock.h b/firmware/targets/f6/furi-hal/furi-hal-clock.h new file mode 100644 index 00000000000..3ec59205113 --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-clock.h @@ -0,0 +1,10 @@ +#pragma once + +/** Initialize clocks */ +void furi_hal_clock_init(); + +/** Switch to HSI clock */ +void furi_hal_clock_switch_to_hsi(); + +/** Switch to PLL clock */ +void furi_hal_clock_switch_to_pll(); diff --git a/firmware/targets/f6/api-hal/api-hal-console.c b/firmware/targets/f6/furi-hal/furi-hal-console.c similarity index 86% rename from firmware/targets/f6/api-hal/api-hal-console.c rename to firmware/targets/f6/furi-hal/furi-hal-console.c index 7fbfa17a016..d34f214a97b 100644 --- a/firmware/targets/f6/api-hal/api-hal-console.c +++ b/firmware/targets/f6/furi-hal/furi-hal-console.c @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -6,9 +6,9 @@ #include -volatile bool api_hal_console_alive = false; +volatile bool furi_hal_console_alive = false; -void api_hal_console_init() { +void furi_hal_console_init() { LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = LL_GPIO_PIN_6|LL_GPIO_PIN_7; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; @@ -35,13 +35,13 @@ void api_hal_console_init() { LL_USART_Enable(USART1); while(!LL_USART_IsActiveFlag_TEACK(USART1)) ; - api_hal_console_alive = true; + furi_hal_console_alive = true; FURI_LOG_I("FuriHalConsole", "Init OK"); } -void api_hal_console_tx(const uint8_t* buffer, size_t buffer_size) { - if (!api_hal_console_alive) +void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size) { + if (!furi_hal_console_alive) return; while(buffer_size > 0) { diff --git a/firmware/targets/f6/api-hal/api-hal-console.h b/firmware/targets/f6/furi-hal/furi-hal-console.h similarity index 55% rename from firmware/targets/f6/api-hal/api-hal-console.h rename to firmware/targets/f6/furi-hal/furi-hal-console.h index b15cf9132ae..1254083f724 100644 --- a/firmware/targets/f6/api-hal/api-hal-console.h +++ b/firmware/targets/f6/furi-hal/furi-hal-console.h @@ -7,9 +7,9 @@ extern "C" { #endif -void api_hal_console_init(); +void furi_hal_console_init(); -void api_hal_console_tx(const uint8_t* buffer, size_t buffer_size); +void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size); #ifdef __cplusplus } diff --git a/firmware/targets/f6/api-hal/api-hal-delay.c b/firmware/targets/f6/furi-hal/furi-hal-delay.c similarity index 92% rename from firmware/targets/f6/api-hal/api-hal-delay.c rename to firmware/targets/f6/furi-hal/furi-hal-delay.c index bb33fb0e3e0..e886e23e764 100644 --- a/firmware/targets/f6/api-hal/api-hal-delay.c +++ b/firmware/targets/f6/furi-hal/furi-hal-delay.c @@ -1,11 +1,11 @@ -#include "api-hal-delay.h" +#include "furi-hal-delay.h" #include #include static uint32_t clk_per_microsecond; -void api_hal_delay_init(void) { +void furi_hal_delay_init(void) { CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; DWT->CYCCNT = 0U; diff --git a/firmware/targets/f6/furi-hal/furi-hal-flash.c b/firmware/targets/f6/furi-hal/furi-hal-flash.c new file mode 100644 index 00000000000..0cd80313c63 --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-flash.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include + +/* Free flash space borders, exported by linker */ +extern const void __free_flash_start__; +extern const void __free_flash_end__; + +#define FURI_HAL_FLASH_READ_BLOCK 8 +#define FURI_HAL_FLASH_WRITE_BLOCK 8 +#define FURI_HAL_FLASH_PAGE_SIZE 4096 +#define FURI_HAL_FLASH_CYCLES_COUNT 10000 + +size_t furi_hal_flash_get_base() { + return FLASH_BASE; +} + +size_t furi_hal_flash_get_read_block_size() { + return FURI_HAL_FLASH_READ_BLOCK; +} + +size_t furi_hal_flash_get_write_block_size() { + return FURI_HAL_FLASH_WRITE_BLOCK; +} + +size_t furi_hal_flash_get_page_size() { + return FURI_HAL_FLASH_PAGE_SIZE; +} + +size_t furi_hal_flash_get_cycles_count() { + return FURI_HAL_FLASH_CYCLES_COUNT; +} + +const void* furi_hal_flash_get_free_start_address() { + return &__free_flash_start__; +} + +const void* furi_hal_flash_get_free_end_address() { + return &__free_flash_end__; +} + +size_t furi_hal_flash_get_free_page_start_address() { + size_t start = (size_t)furi_hal_flash_get_free_start_address(); + size_t page_start = start - start % FURI_HAL_FLASH_PAGE_SIZE; + if (page_start != start) { + page_start += FURI_HAL_FLASH_PAGE_SIZE; + } + return page_start; +} + +size_t furi_hal_flash_get_free_page_count() { + size_t end = (size_t)furi_hal_flash_get_free_end_address(); + size_t page_start = (size_t)furi_hal_flash_get_free_page_start_address(); + return (end-page_start) / FURI_HAL_FLASH_PAGE_SIZE; +} + +bool furi_hal_flash_erase(uint8_t page, uint8_t count) { + if (!furi_hal_bt_lock_flash()) { + return false; + } + FLASH_EraseInitTypeDef erase; + erase.TypeErase = FLASH_TYPEERASE_PAGES; + erase.Page = page; + erase.NbPages = count; + uint32_t error; + HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase, &error); + furi_hal_bt_unlock_flash(); + return status == HAL_OK; +} + +bool furi_hal_flash_write_dword(size_t address, uint64_t data) { + if (!furi_hal_bt_lock_flash()) { + return false; + } + HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data); + furi_hal_bt_unlock_flash(); + return status == HAL_OK; +} + +bool furi_hal_flash_write_dword_from(size_t address, size_t source_address) { + if (!furi_hal_bt_lock_flash()) { + return false; + } + HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FAST, address, source_address); + furi_hal_bt_unlock_flash(); + return status == HAL_OK; +} diff --git a/firmware/targets/f6/api-hal/api-hal-flash.h b/firmware/targets/f6/furi-hal/furi-hal-flash.h similarity index 67% rename from firmware/targets/f6/api-hal/api-hal-flash.h rename to firmware/targets/f6/furi-hal/furi-hal-flash.h index eb7270bef26..3ef9b730079 100644 --- a/firmware/targets/f6/api-hal/api-hal-flash.h +++ b/firmware/targets/f6/furi-hal/furi-hal-flash.h @@ -7,47 +7,47 @@ /** Get flash base address * @return pointer to flash base */ -size_t api_hal_flash_get_base(); +size_t furi_hal_flash_get_base(); /** Get flash read block size * @return size in bytes */ -size_t api_hal_flash_get_read_block_size(); +size_t furi_hal_flash_get_read_block_size(); /** Get flash write block size * @return size in bytes */ -size_t api_hal_flash_get_write_block_size(); +size_t furi_hal_flash_get_write_block_size(); /** Get flash page size * @return size in bytes */ -size_t api_hal_flash_get_page_size(); +size_t furi_hal_flash_get_page_size(); /** Get expected flash cycles count * @return count of erase-write operations */ -size_t api_hal_flash_get_cycles_count(); +size_t furi_hal_flash_get_cycles_count(); /** Get free flash start address * @return pointer to free region start */ -const void* api_hal_flash_get_free_start_address(); +const void* furi_hal_flash_get_free_start_address(); /** Get free flash end address * @return pointer to free region end */ -const void* api_hal_flash_get_free_end_address(); +const void* furi_hal_flash_get_free_end_address(); /** Get first free page start address * @return first free page memory address */ -size_t api_hal_flash_get_free_page_start_address(); +size_t furi_hal_flash_get_free_page_start_address(); /** Get free page count * @return free page count */ -size_t api_hal_flash_get_free_page_count(); +size_t furi_hal_flash_get_free_page_count(); /* * Erase Flash @@ -55,7 +55,7 @@ size_t api_hal_flash_get_free_page_count(); * @param page, page number * @param count, page count to erase */ -bool api_hal_flash_erase(uint8_t page, uint8_t count); +bool furi_hal_flash_erase(uint8_t page, uint8_t count); /* * Write double word (64 bits) @@ -63,7 +63,7 @@ bool api_hal_flash_erase(uint8_t page, uint8_t count); * @param address - destination address, must be double word aligned. * @param data - data to write */ -bool api_hal_flash_write_dword(size_t address, uint64_t data); +bool furi_hal_flash_write_dword(size_t address, uint64_t data); /* * Write double word (64 bits) from address @@ -71,4 +71,4 @@ bool api_hal_flash_write_dword(size_t address, uint64_t data); * @param address - destination address, must be block aligned * @param source_address - source address */ -bool api_hal_flash_write_dword_from(size_t address, size_t source_address); +bool furi_hal_flash_write_dword_from(size_t address, size_t source_address); diff --git a/firmware/targets/f6/api-hal/api-hal-gpio.c b/firmware/targets/f6/furi-hal/furi-hal-gpio.c similarity index 98% rename from firmware/targets/f6/api-hal/api-hal-gpio.c rename to firmware/targets/f6/furi-hal/furi-hal-gpio.c index 338ee00b484..65a8009bb1b 100644 --- a/firmware/targets/f6/api-hal/api-hal-gpio.c +++ b/firmware/targets/f6/furi-hal/furi-hal-gpio.c @@ -1,6 +1,6 @@ #include -#include -#include +#include +#include #define GET_SYSCFG_EXTI_PORT(gpio) \ (((gpio) == (GPIOA)) ? LL_SYSCFG_EXTI_PORTA : \ @@ -284,7 +284,7 @@ extern COMP_HandleTypeDef hcomp1; bool hal_gpio_get_rfid_in_level() { bool value = false; - if(api_hal_version_get_hw_version() > 7) { + if(furi_hal_version_get_hw_version() > 7) { value = (HAL_COMP_GetOutputLevel(&hcomp1) == COMP_OUTPUT_LEVEL_LOW); } else { value = (HAL_COMP_GetOutputLevel(&hcomp1) == COMP_OUTPUT_LEVEL_HIGH); diff --git a/firmware/targets/f6/furi-hal/furi-hal-gpio.h b/firmware/targets/f6/furi-hal/furi-hal-gpio.h new file mode 100644 index 00000000000..a81afb3989a --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-gpio.h @@ -0,0 +1,264 @@ +#pragma once +#include "main.h" +#include "stdbool.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Number of gpio on one port + */ +#define GPIO_NUMBER (16U) + +/** + * Interrupt callback prototype + */ +typedef void (*GpioExtiCallback)(void* ctx); + +/** + * Gpio interrupt type + */ +typedef struct { + GpioExtiCallback callback; + void* context; + volatile bool ready; +} GpioInterrupt; + +/** + * Gpio modes + */ +typedef enum { + GpioModeInput, + GpioModeOutputPushPull, + GpioModeOutputOpenDrain, + GpioModeAltFunctionPushPull, + GpioModeAltFunctionOpenDrain, + GpioModeAnalog, + GpioModeInterruptRise, + GpioModeInterruptFall, + GpioModeInterruptRiseFall, + GpioModeEventRise, + GpioModeEventFall, + GpioModeEventRiseFall, +} GpioMode; + +/** + * Gpio pull modes + */ +typedef enum { + GpioPullNo, + GpioPullUp, + GpioPullDown, +} GpioPull; + +/** + * Gpio speed modes + */ +typedef enum { + GpioSpeedLow, + GpioSpeedMedium, + GpioSpeedHigh, + GpioSpeedVeryHigh, +} GpioSpeed; + +/** + * Gpio alternate functions + */ +typedef enum { + GpioAltFn0MCO = 0, /*!< MCO Alternate Function mapping */ + GpioAltFn0LSCO = 0, /*!< LSCO Alternate Function mapping */ + GpioAltFn0JTMS_SWDIO = 0, /*!< JTMS-SWDIO Alternate Function mapping */ + GpioAltFn0JTCK_SWCLK = 0, /*!< JTCK-SWCLK Alternate Function mapping */ + GpioAltFn0JTDI = 0, /*!< JTDI Alternate Function mapping */ + GpioAltFn0RTC_OUT = 0, /*!< RCT_OUT Alternate Function mapping */ + GpioAltFn0JTD_TRACE = 0, /*!< JTDO-TRACESWO Alternate Function mapping */ + GpioAltFn0NJTRST = 0, /*!< NJTRST Alternate Function mapping */ + GpioAltFn0RTC_REFIN = 0, /*!< RTC_REFIN Alternate Function mapping */ + GpioAltFn0TRACED0 = 0, /*!< TRACED0 Alternate Function mapping */ + GpioAltFn0TRACED1 = 0, /*!< TRACED1 Alternate Function mapping */ + GpioAltFn0TRACED2 = 0, /*!< TRACED2 Alternate Function mapping */ + GpioAltFn0TRACED3 = 0, /*!< TRACED3 Alternate Function mapping */ + GpioAltFn0TRIG_INOUT = 0, /*!< TRIG_INOUT Alternate Function mapping */ + GpioAltFn0TRACECK = 0, /*!< TRACECK Alternate Function mapping */ + GpioAltFn0SYS = 0, /*!< System Function mapping */ + + GpioAltFn1TIM1 = 1, /*!< TIM1 Alternate Function mapping */ + GpioAltFn1TIM2 = 1, /*!< TIM2 Alternate Function mapping */ + GpioAltFn1LPTIM1 = 1, /*!< LPTIM1 Alternate Function mapping */ + + GpioAltFn2TIM2 = 2, /*!< TIM2 Alternate Function mapping */ + GpioAltFn2TIM1 = 2, /*!< TIM1 Alternate Function mapping */ + + GpioAltFn3SAI1 = 3, /*!< SAI1_CK1 Alternate Function mapping */ + GpioAltFn3SPI2 = 3, /*!< SPI2 Alternate Function mapping */ + GpioAltFn3TIM1 = 3, /*!< TIM1 Alternate Function mapping */ + + GpioAltFn4I2C1 = 4, /*!< I2C1 Alternate Function mapping */ + GpioAltFn4I2C3 = 4, /*!< I2C3 Alternate Function mapping */ + + GpioAltFn5SPI1 = 5, /*!< SPI1 Alternate Function mapping */ + GpioAltFn5SPI2 = 5, /*!< SPI2 Alternate Function mapping */ + + GpioAltFn6MCO = 6, /*!< MCO Alternate Function mapping */ + GpioAltFn6LSCO = 6, /*!< LSCO Alternate Function mapping */ + GpioAltFn6RF_DTB0 = 6, /*!< RF_DTB0 Alternate Function mapping */ + GpioAltFn6RF_DTB1 = 6, /*!< RF_DTB1 Alternate Function mapping */ + GpioAltFn6RF_DTB2 = 6, /*!< RF_DTB2 Alternate Function mapping */ + GpioAltFn6RF_DTB3 = 6, /*!< RF_DTB3 Alternate Function mapping */ + GpioAltFn6RF_DTB4 = 6, /*!< RF_DTB4 Alternate Function mapping */ + GpioAltFn6RF_DTB5 = 6, /*!< RF_DTB5 Alternate Function mapping */ + GpioAltFn6RF_DTB6 = 6, /*!< RF_DTB6 Alternate Function mapping */ + GpioAltFn6RF_DTB7 = 6, /*!< RF_DTB7 Alternate Function mapping */ + GpioAltFn6RF_DTB8 = 6, /*!< RF_DTB8 Alternate Function mapping */ + GpioAltFn6RF_DTB9 = 6, /*!< RF_DTB9 Alternate Function mapping */ + GpioAltFn6RF_DTB10 = 6, /*!< RF_DTB10 Alternate Function mapping */ + GpioAltFn6RF_DTB11 = 6, /*!< RF_DTB11 Alternate Function mapping */ + GpioAltFn6RF_DTB12 = 6, /*!< RF_DTB12 Alternate Function mapping */ + GpioAltFn6RF_DTB13 = 6, /*!< RF_DTB13 Alternate Function mapping */ + GpioAltFn6RF_DTB14 = 6, /*!< RF_DTB14 Alternate Function mapping */ + GpioAltFn6RF_DTB15 = 6, /*!< RF_DTB15 Alternate Function mapping */ + GpioAltFn6RF_DTB16 = 6, /*!< RF_DTB16 Alternate Function mapping */ + GpioAltFn6RF_DTB17 = 6, /*!< RF_DTB17 Alternate Function mapping */ + GpioAltFn6RF_DTB18 = 6, /*!< RF_DTB18 Alternate Function mapping */ + GpioAltFn6RF_MISO = 6, /*!< RF_MISO Alternate Function mapping */ + GpioAltFn6RF_MOSI = 6, /*!< RF_MOSI Alternate Function mapping */ + GpioAltFn6RF_SCK = 6, /*!< RF_SCK Alternate Function mapping */ + GpioAltFn6RF_NSS = 6, /*!< RF_NSS Alternate Function mapping */ + + GpioAltFn7USART1 = 7, /*!< USART1 Alternate Function mapping */ + + GpioAltFn8LPUART1 = 8, /*!< LPUART1 Alternate Function mapping */ + GpioAltFn8IR = 8, /*!< IR Alternate Function mapping */ + + GpioAltFn9TSC = 9, /*!< TSC Alternate Function mapping */ + + GpioAltFn10QUADSPI = 10, /*!< QUADSPI Alternate Function mapping */ + GpioAltFn10USB = 10, /*!< USB Alternate Function mapping */ + + GpioAltFn11LCD = 11, /*!< LCD Alternate Function mapping */ + + GpioAltFn12COMP1 = 12, /*!< COMP1 Alternate Function mapping */ + GpioAltFn12COMP2 = 12, /*!< COMP2 Alternate Function mapping */ + GpioAltFn12TIM1 = 12, /*!< TIM1 Alternate Function mapping */ + + GpioAltFn13SAI1 = 13, /*!< SAI1 Alternate Function mapping */ + + GpioAltFn14TIM2 = 14, /*!< TIM2 Alternate Function mapping */ + GpioAltFn14TIM16 = 14, /*!< TIM16 Alternate Function mapping */ + GpioAltFn14TIM17 = 14, /*!< TIM17 Alternate Function mapping */ + GpioAltFn14LPTIM2 = 14, /*!< LPTIM2 Alternate Function mapping */ + + GpioAltFn15EVENTOUT = 15, /*!< EVENTOUT Alternate Function mapping */ + + GpioAltFnUnused = 16, /*!< just dummy value */ +} GpioAltFn; + +/** + * Gpio structure + */ +typedef struct { + GPIO_TypeDef* port; + uint16_t pin; +} GpioPin; + +/** + * GPIO initialization function, simple version + * @param gpio GpioPin + * @param mode GpioMode + */ +void hal_gpio_init_simple(const GpioPin* gpio, const GpioMode mode); + +/** + * GPIO initialization function, normal version + * @param gpio GpioPin + * @param mode GpioMode + * @param pull GpioPull + * @param speed GpioSpeed + */ +void hal_gpio_init( + const GpioPin* gpio, + const GpioMode mode, + const GpioPull pull, + const GpioSpeed speed); + +/** + * GPIO initialization function, extended version + * @param gpio GpioPin + * @param mode GpioMode + * @param pull GpioPull + * @param speed GpioSpeed + * @param alt_fn GpioAltFn + */ +void hal_gpio_init_ex( + const GpioPin* gpio, + const GpioMode mode, + const GpioPull pull, + const GpioSpeed speed, + const GpioAltFn alt_fn); + +/** + * Add and enable interrupt + * @param gpio GpioPin + * @param cb GpioExtiCallback + * @param ctx context for callback + */ +void hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx); + +/** + * Enable interrupt + * @param gpio GpioPin + */ +void hal_gpio_enable_int_callback(const GpioPin* gpio); + +/** + * Disable interrupt + * @param gpio GpioPin + */ +void hal_gpio_disable_int_callback(const GpioPin* gpio); + +/** + * Remove interrupt + * @param gpio GpioPin + */ +void hal_gpio_remove_int_callback(const GpioPin* gpio); + +/** + * GPIO write pin + * @param gpio GpioPin + * @param state true / false + */ +static inline void hal_gpio_write(const GpioPin* gpio, const bool state) { + // writing to BSSR is an atomic operation + if(state == true) { + gpio->port->BSRR = gpio->pin; + } else { + gpio->port->BSRR = (uint32_t)gpio->pin << GPIO_NUMBER; + } +} + +/** + * GPIO read pin + * @param gpio GpioPin + * @return true / false + */ +static inline bool hal_gpio_read(const GpioPin* gpio) { + if((gpio->port->IDR & gpio->pin) != 0x00U) { + return true; + } else { + return false; + } +} + +/** + * Get RFID IN level + * @return false = LOW, true = HIGH + */ +bool hal_gpio_get_rfid_in_level(); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f6/api-hal/api-hal-i2c.c b/firmware/targets/f6/furi-hal/furi-hal-i2c.c similarity index 83% rename from firmware/targets/f6/api-hal/api-hal-i2c.c rename to firmware/targets/f6/furi-hal/furi-hal-i2c.c index 110a5d26abe..196a2a7b764 100644 --- a/firmware/targets/f6/api-hal/api-hal-i2c.c +++ b/firmware/targets/f6/furi-hal/furi-hal-i2c.c @@ -1,16 +1,16 @@ -#include -#include +#include +#include #include #include #include #include -osMutexId_t api_hal_i2c_mutex = NULL; +osMutexId_t furi_hal_i2c_mutex = NULL; -void api_hal_i2c_init() { - api_hal_i2c_mutex = osMutexNew(NULL); - furi_check(api_hal_i2c_mutex); +void furi_hal_i2c_init() { + furi_hal_i2c_mutex = osMutexNew(NULL); + furi_check(furi_hal_i2c_mutex); LL_I2C_InitTypeDef I2C_InitStruct = {0}; LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; @@ -31,7 +31,7 @@ void api_hal_i2c_init() { I2C_InitStruct.OwnAddress1 = 0; I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; - if (api_hal_version_get_hw_version() > 10) { + if (furi_hal_version_get_hw_version() > 10) { I2C_InitStruct.Timing = POWER_I2C_TIMINGS_400; } else { I2C_InitStruct.Timing = POWER_I2C_TIMINGS_100; @@ -45,7 +45,7 @@ void api_hal_i2c_init() { FURI_LOG_I("FuriHalI2C", "Init OK"); } -bool api_hal_i2c_tx( +bool furi_hal_i2c_tx( I2C_TypeDef* instance, uint8_t address, const uint8_t* data, @@ -86,7 +86,7 @@ bool api_hal_i2c_tx( return ret; } -bool api_hal_i2c_rx( +bool furi_hal_i2c_rx( I2C_TypeDef* instance, uint8_t address, uint8_t* data, @@ -127,7 +127,7 @@ bool api_hal_i2c_rx( return ret; } -bool api_hal_i2c_trx( +bool furi_hal_i2c_trx( I2C_TypeDef* instance, uint8_t address, const uint8_t* tx_data, @@ -135,18 +135,18 @@ bool api_hal_i2c_trx( uint8_t* rx_data, uint8_t rx_size, uint32_t timeout) { - if(api_hal_i2c_tx(instance, address, tx_data, tx_size, timeout) && - api_hal_i2c_rx(instance, address, rx_data, rx_size, timeout)) { + if(furi_hal_i2c_tx(instance, address, tx_data, tx_size, timeout) && + furi_hal_i2c_rx(instance, address, rx_data, rx_size, timeout)) { return true; } else { return false; } } -void api_hal_i2c_lock() { - furi_check(osMutexAcquire(api_hal_i2c_mutex, osWaitForever) == osOK); +void furi_hal_i2c_lock() { + furi_check(osMutexAcquire(furi_hal_i2c_mutex, osWaitForever) == osOK); } -void api_hal_i2c_unlock() { - furi_check(osMutexRelease(api_hal_i2c_mutex) == osOK); +void furi_hal_i2c_unlock() { + furi_check(osMutexRelease(furi_hal_i2c_mutex) == osOK); } diff --git a/firmware/targets/f6/api-hal/api-hal-ibutton.c b/firmware/targets/f6/furi-hal/furi-hal-ibutton.c similarity index 50% rename from firmware/targets/f6/api-hal/api-hal-ibutton.c rename to firmware/targets/f6/furi-hal/furi-hal-ibutton.c index 87addbbcfce..6e3c8bee586 100644 --- a/firmware/targets/f6/api-hal/api-hal-ibutton.c +++ b/firmware/targets/f6/furi-hal/furi-hal-ibutton.c @@ -1,24 +1,24 @@ -#include -#include +#include +#include -void api_hal_ibutton_start() { - api_hal_ibutton_pin_high(); +void furi_hal_ibutton_start() { + furi_hal_ibutton_pin_high(); hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioSpeedLow, GpioPullNo); } -void api_hal_ibutton_stop() { - api_hal_ibutton_pin_high(); +void furi_hal_ibutton_stop() { + furi_hal_ibutton_pin_high(); hal_gpio_init(&ibutton_gpio, GpioModeAnalog, GpioSpeedLow, GpioPullNo); } -void api_hal_ibutton_pin_low() { +void furi_hal_ibutton_pin_low() { hal_gpio_write(&ibutton_gpio, false); } -void api_hal_ibutton_pin_high() { +void furi_hal_ibutton_pin_high() { hal_gpio_write(&ibutton_gpio, true); } -bool api_hal_ibutton_pin_get_level() { +bool furi_hal_ibutton_pin_get_level() { return hal_gpio_read(&ibutton_gpio); } diff --git a/firmware/targets/f6/api-hal/api-hal-interrupt.c b/firmware/targets/f6/furi-hal/furi-hal-interrupt.c similarity index 57% rename from firmware/targets/f6/api-hal/api-hal-interrupt.c rename to firmware/targets/f6/furi-hal/furi-hal-interrupt.c index fd5cd2be116..69cdc4b6994 100644 --- a/firmware/targets/f6/api-hal/api-hal-interrupt.c +++ b/firmware/targets/f6/furi-hal/furi-hal-interrupt.c @@ -1,18 +1,18 @@ -#include "api-hal-interrupt.h" +#include "furi-hal-interrupt.h" #include #include #include -volatile ApiHalInterruptISR api_hal_tim_tim2_isr = NULL; -volatile ApiHalInterruptISR api_hal_tim_tim1_isr = NULL; +volatile FuriHalInterruptISR furi_hal_tim_tim2_isr = NULL; +volatile FuriHalInterruptISR furi_hal_tim_tim1_isr = NULL; -#define API_HAL_INTERRUPT_DMA_COUNT 2 -#define API_HAL_INTERRUPT_DMA_CHANNELS_COUNT 8 +#define FURI_HAL_INTERRUPT_DMA_COUNT 2 +#define FURI_HAL_INTERRUPT_DMA_CHANNELS_COUNT 8 -volatile ApiHalInterruptISR api_hal_dma_channel_isr[API_HAL_INTERRUPT_DMA_COUNT][API_HAL_INTERRUPT_DMA_CHANNELS_COUNT] = {0}; +volatile FuriHalInterruptISR furi_hal_dma_channel_isr[FURI_HAL_INTERRUPT_DMA_COUNT][FURI_HAL_INTERRUPT_DMA_CHANNELS_COUNT] = {0}; -void api_hal_interrupt_init() { +void furi_hal_interrupt_init() { NVIC_SetPriority(RCC_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0)); NVIC_EnableIRQ(RCC_IRQn); @@ -25,34 +25,34 @@ void api_hal_interrupt_init() { FURI_LOG_I("FuriHalInterrupt", "Init OK"); } -void api_hal_interrupt_set_timer_isr(TIM_TypeDef* timer, ApiHalInterruptISR isr) { +void furi_hal_interrupt_set_timer_isr(TIM_TypeDef* timer, FuriHalInterruptISR isr) { if (timer == TIM2) { if (isr) { - furi_assert(api_hal_tim_tim2_isr == NULL); + furi_assert(furi_hal_tim_tim2_isr == NULL); } else { - furi_assert(api_hal_tim_tim2_isr != NULL); + furi_assert(furi_hal_tim_tim2_isr != NULL); } - api_hal_tim_tim2_isr = isr; + furi_hal_tim_tim2_isr = isr; } else if (timer == TIM1) { if (isr) { - furi_assert(api_hal_tim_tim1_isr == NULL); + furi_assert(furi_hal_tim_tim1_isr == NULL); } else { - furi_assert(api_hal_tim_tim1_isr != NULL); + furi_assert(furi_hal_tim_tim1_isr != NULL); } - api_hal_tim_tim1_isr = isr; + furi_hal_tim_tim1_isr = isr; } else { furi_check(0); } } -void api_hal_interrupt_set_dma_channel_isr(DMA_TypeDef* dma, uint32_t channel, ApiHalInterruptISR isr) { +void furi_hal_interrupt_set_dma_channel_isr(DMA_TypeDef* dma, uint32_t channel, FuriHalInterruptISR isr) { --channel; // Pascal furi_check(dma); - furi_check(channel < API_HAL_INTERRUPT_DMA_CHANNELS_COUNT); + furi_check(channel < FURI_HAL_INTERRUPT_DMA_CHANNELS_COUNT); if (dma == DMA1) { - api_hal_dma_channel_isr[0][channel] = isr; + furi_hal_dma_channel_isr[0][channel] = isr; } else if (dma == DMA2) { - api_hal_dma_channel_isr[1][channel] = isr; + furi_hal_dma_channel_isr[1][channel] = isr; } else { furi_check(0); } @@ -74,8 +74,8 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) { /* Timer 2 */ void TIM2_IRQHandler(void) { - if (api_hal_tim_tim2_isr) { - api_hal_tim_tim2_isr(); + if (furi_hal_tim_tim2_isr) { + furi_hal_tim_tim2_isr(); } else { HAL_TIM_IRQHandler(&htim2); } @@ -83,8 +83,8 @@ void TIM2_IRQHandler(void) { /* Timer 1 Update */ void TIM1_UP_TIM16_IRQHandler(void) { - if (api_hal_tim_tim1_isr) { - api_hal_tim_tim1_isr(); + if (furi_hal_tim_tim1_isr) { + furi_hal_tim_tim1_isr(); } else { HAL_TIM_IRQHandler(&htim1); } @@ -92,68 +92,68 @@ void TIM1_UP_TIM16_IRQHandler(void) { /* DMA 1 */ void DMA1_Channel1_IRQHandler(void) { - if (api_hal_dma_channel_isr[0][0]) api_hal_dma_channel_isr[0][0](); + if (furi_hal_dma_channel_isr[0][0]) furi_hal_dma_channel_isr[0][0](); } void DMA1_Channel2_IRQHandler(void) { - if (api_hal_dma_channel_isr[0][1]) api_hal_dma_channel_isr[0][1](); + if (furi_hal_dma_channel_isr[0][1]) furi_hal_dma_channel_isr[0][1](); } void DMA1_Channel3_IRQHandler(void) { - if (api_hal_dma_channel_isr[0][2]) api_hal_dma_channel_isr[0][2](); + if (furi_hal_dma_channel_isr[0][2]) furi_hal_dma_channel_isr[0][2](); } void DMA1_Channel4_IRQHandler(void) { - if (api_hal_dma_channel_isr[0][3]) api_hal_dma_channel_isr[0][3](); + if (furi_hal_dma_channel_isr[0][3]) furi_hal_dma_channel_isr[0][3](); } void DMA1_Channel5_IRQHandler(void) { - if (api_hal_dma_channel_isr[0][4]) api_hal_dma_channel_isr[0][4](); + if (furi_hal_dma_channel_isr[0][4]) furi_hal_dma_channel_isr[0][4](); } void DMA1_Channel6_IRQHandler(void) { - if (api_hal_dma_channel_isr[0][5]) api_hal_dma_channel_isr[0][5](); + if (furi_hal_dma_channel_isr[0][5]) furi_hal_dma_channel_isr[0][5](); } void DMA1_Channel7_IRQHandler(void) { - if (api_hal_dma_channel_isr[0][6]) api_hal_dma_channel_isr[0][6](); + if (furi_hal_dma_channel_isr[0][6]) furi_hal_dma_channel_isr[0][6](); } void DMA1_Channel8_IRQHandler(void) { - if (api_hal_dma_channel_isr[0][7]) api_hal_dma_channel_isr[0][7](); + if (furi_hal_dma_channel_isr[0][7]) furi_hal_dma_channel_isr[0][7](); } /* DMA 2 */ void DMA2_Channel1_IRQHandler(void) { - if (api_hal_dma_channel_isr[1][0]) api_hal_dma_channel_isr[1][0](); + if (furi_hal_dma_channel_isr[1][0]) furi_hal_dma_channel_isr[1][0](); } void DMA2_Channel2_IRQHandler(void) { - if (api_hal_dma_channel_isr[1][1]) api_hal_dma_channel_isr[1][1](); + if (furi_hal_dma_channel_isr[1][1]) furi_hal_dma_channel_isr[1][1](); } void DMA2_Channel3_IRQHandler(void) { - if (api_hal_dma_channel_isr[1][2]) api_hal_dma_channel_isr[1][2](); + if (furi_hal_dma_channel_isr[1][2]) furi_hal_dma_channel_isr[1][2](); } void DMA2_Channel4_IRQHandler(void) { - if (api_hal_dma_channel_isr[1][3]) api_hal_dma_channel_isr[1][3](); + if (furi_hal_dma_channel_isr[1][3]) furi_hal_dma_channel_isr[1][3](); } void DMA2_Channel5_IRQHandler(void) { - if (api_hal_dma_channel_isr[1][4]) api_hal_dma_channel_isr[1][4](); + if (furi_hal_dma_channel_isr[1][4]) furi_hal_dma_channel_isr[1][4](); } void DMA2_Channel6_IRQHandler(void) { - if (api_hal_dma_channel_isr[1][5]) api_hal_dma_channel_isr[1][5](); + if (furi_hal_dma_channel_isr[1][5]) furi_hal_dma_channel_isr[1][5](); } void DMA2_Channel7_IRQHandler(void) { - if (api_hal_dma_channel_isr[1][6]) api_hal_dma_channel_isr[1][6](); + if (furi_hal_dma_channel_isr[1][6]) furi_hal_dma_channel_isr[1][6](); } void DMA2_Channel8_IRQHandler(void) { - if (api_hal_dma_channel_isr[1][7]) api_hal_dma_channel_isr[1][7](); + if (furi_hal_dma_channel_isr[1][7]) furi_hal_dma_channel_isr[1][7](); } diff --git a/firmware/targets/f6/api-hal/api-hal-interrupt.h b/firmware/targets/f6/furi-hal/furi-hal-interrupt.h similarity index 71% rename from firmware/targets/f6/api-hal/api-hal-interrupt.h rename to firmware/targets/f6/furi-hal/furi-hal-interrupt.h index eeb0afe9941..693924e6897 100644 --- a/firmware/targets/f6/api-hal/api-hal-interrupt.h +++ b/firmware/targets/f6/furi-hal/furi-hal-interrupt.h @@ -7,10 +7,10 @@ extern "C" { #endif /** Timer ISR */ -typedef void (*ApiHalInterruptISR)(); +typedef void (*FuriHalInterruptISR)(); /** Initialize interrupt subsystem */ -void api_hal_interrupt_init(); +void furi_hal_interrupt_init(); /** Set DMA Channel ISR * We don't clear interrupt flags for you, do it by your self. @@ -18,7 +18,7 @@ void api_hal_interrupt_init(); * @param channel - DMA channel * @param isr - your interrupt service routine or use NULL to clear */ -void api_hal_interrupt_set_dma_channel_isr(DMA_TypeDef* dma, uint32_t channel, ApiHalInterruptISR isr); +void furi_hal_interrupt_set_dma_channel_isr(DMA_TypeDef* dma, uint32_t channel, FuriHalInterruptISR isr); /** Set Timer ISR * By default ISR is serviced by ST HAL. Use this function to override it. @@ -26,7 +26,7 @@ void api_hal_interrupt_set_dma_channel_isr(DMA_TypeDef* dma, uint32_t channel, A * @param timer - timer instance * @param isr - your interrupt service routine or use NULL to clear */ -void api_hal_interrupt_set_timer_isr(TIM_TypeDef *timer, ApiHalInterruptISR isr); +void furi_hal_interrupt_set_timer_isr(TIM_TypeDef *timer, FuriHalInterruptISR isr); #ifdef __cplusplus diff --git a/firmware/targets/f6/api-hal/api-hal-irda.c b/firmware/targets/f6/furi-hal/furi-hal-irda.c similarity index 68% rename from firmware/targets/f6/api-hal/api-hal-irda.c rename to firmware/targets/f6/furi-hal/furi-hal-irda.c index 345f68b5262..16e5b8dd815 100644 --- a/firmware/targets/f6/api-hal/api-hal-irda.c +++ b/firmware/targets/f6/furi-hal/furi-hal-irda.c @@ -1,11 +1,11 @@ -#include "api-hal-irda.h" -#include "api-hal-delay.h" +#include "furi-hal-irda.h" +#include "furi-hal-delay.h" #include "furi/check.h" #include "stm32wbxx_ll_dma.h" #include "sys/_stdint.h" #include -#include -#include +#include +#include #include #include @@ -15,7 +15,7 @@ #include #include #include -#include +#include #define IRDA_TIM_TX_DMA_BUFFER_SIZE 200 #define IRDA_POLARITY_SHIFT 1 @@ -24,9 +24,9 @@ #define IRDA_TX_CCMR_LOW (TIM_CCMR2_OC3PE | LL_TIM_OCMODE_FORCED_INACTIVE) /* Space time - force low */ typedef struct{ - ApiHalIrdaRxCaptureCallback capture_callback; + FuriHalIrdaRxCaptureCallback capture_callback; void *capture_context; - ApiHalIrdaRxTimeoutCallback timeout_callback; + FuriHalIrdaRxTimeoutCallback timeout_callback; void *timeout_context; } IrdaTimRx; @@ -40,14 +40,16 @@ typedef struct{ typedef struct { float cycle_duration; - ApiHalIrdaTxGetDataCallback data_callback; + FuriHalIrdaTxGetDataISRCallback data_callback; + FuriHalIrdaTxSignalSentISRCallback signal_sent_callback; void* data_context; + void* signal_sent_context; IrdaTxBuf buffer[2]; osSemaphoreId_t stop_semaphore; } IrdaTimTx; typedef enum { - IrdaStateIdle, /** Api Hal Irda is ready to start RX or TX */ + IrdaStateIdle, /** Furi Hal Irda is ready to start RX or TX */ IrdaStateAsyncRx, /** Async RX started */ IrdaStateAsyncTx, /** Async TX started, DMA and timer is on */ IrdaStateAsyncTxStopReq, /** Async TX started, async stop request received */ @@ -56,25 +58,25 @@ typedef enum { IrdaStateMAX, } IrdaState; -static volatile IrdaState api_hal_irda_state = IrdaStateIdle; +static volatile IrdaState furi_hal_irda_state = IrdaStateIdle; static IrdaTimTx irda_tim_tx; static IrdaTimRx irda_tim_rx; -static bool api_hal_irda_tx_fill_buffer(uint8_t buf_num, uint8_t polarity_shift); -static void api_hal_irda_async_tx_free_resources(void); -static void api_hal_irda_tx_dma_set_polarity(uint8_t buf_num, uint8_t polarity_shift); -static void api_hal_irda_tx_dma_set_buffer(uint8_t buf_num); -static void api_hal_irda_tx_fill_buffer_last(uint8_t buf_num); -static uint8_t api_hal_irda_get_current_dma_tx_buffer(void); -static void api_hal_irda_tx_dma_polarity_isr(); -static void api_hal_irda_tx_dma_isr(); +static bool furi_hal_irda_tx_fill_buffer(uint8_t buf_num, uint8_t polarity_shift); +static void furi_hal_irda_async_tx_free_resources(void); +static void furi_hal_irda_tx_dma_set_polarity(uint8_t buf_num, uint8_t polarity_shift); +static void furi_hal_irda_tx_dma_set_buffer(uint8_t buf_num); +static void furi_hal_irda_tx_fill_buffer_last(uint8_t buf_num); +static uint8_t furi_hal_irda_get_current_dma_tx_buffer(void); +static void furi_hal_irda_tx_dma_polarity_isr(); +static void furi_hal_irda_tx_dma_isr(); -static void api_hal_irda_tim_rx_isr() { +static void furi_hal_irda_tim_rx_isr() { /* Timeout */ if(LL_TIM_IsActiveFlag_CC3(TIM2)) { LL_TIM_ClearFlag_CC3(TIM2); - furi_assert(api_hal_irda_state == IrdaStateAsyncRx); + furi_assert(furi_hal_irda_state == IrdaStateAsyncRx); /* Timers CNT register starts to counting from 0 to ARR, but it is * reseted when Channel 1 catches interrupt. It is not reseted by @@ -91,7 +93,7 @@ static void api_hal_irda_tim_rx_isr() { /* Rising Edge */ if(LL_TIM_IsActiveFlag_CC1(TIM2)) { LL_TIM_ClearFlag_CC1(TIM2); - furi_assert(api_hal_irda_state == IrdaStateAsyncRx); + furi_assert(furi_hal_irda_state == IrdaStateAsyncRx); if(READ_BIT(TIM2->CCMR1, TIM_CCMR1_CC1S)) { /* Low pin level is a Mark state of IRDA signal. Invert level for further processing. */ @@ -106,7 +108,7 @@ static void api_hal_irda_tim_rx_isr() { /* Falling Edge */ if(LL_TIM_IsActiveFlag_CC2(TIM2)) { LL_TIM_ClearFlag_CC2(TIM2); - furi_assert(api_hal_irda_state == IrdaStateAsyncRx); + furi_assert(furi_hal_irda_state == IrdaStateAsyncRx); if(READ_BIT(TIM2->CCMR1, TIM_CCMR1_CC2S)) { /* High pin level is a Space state of IRDA signal. Invert level for further processing. */ @@ -119,8 +121,8 @@ static void api_hal_irda_tim_rx_isr() { } } -void api_hal_irda_async_rx_start(void) { - furi_assert(api_hal_irda_state == IrdaStateIdle); +void furi_hal_irda_async_rx_start(void) { + furi_assert(furi_hal_irda_state == IrdaStateIdle); LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); @@ -152,8 +154,8 @@ void api_hal_irda_async_rx_start(void) { LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_INDIRECTTI); LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); - api_hal_interrupt_set_timer_isr(TIM2, api_hal_irda_tim_rx_isr); - api_hal_irda_state = IrdaStateAsyncRx; + furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_irda_tim_rx_isr); + furi_hal_irda_state = IrdaStateAsyncRx; LL_TIM_EnableIT_CC1(TIM2); LL_TIM_EnableIT_CC2(TIM2); @@ -167,41 +169,43 @@ void api_hal_irda_async_rx_start(void) { NVIC_EnableIRQ(TIM2_IRQn); } -void api_hal_irda_async_rx_stop(void) { - furi_assert(api_hal_irda_state == IrdaStateAsyncRx); +void furi_hal_irda_async_rx_stop(void) { + furi_assert(furi_hal_irda_state == IrdaStateAsyncRx); LL_TIM_DeInit(TIM2); - api_hal_interrupt_set_timer_isr(TIM2, NULL); + furi_hal_interrupt_set_timer_isr(TIM2, NULL); LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2); - api_hal_irda_state = IrdaStateIdle; + furi_hal_irda_state = IrdaStateIdle; } -void api_hal_irda_async_rx_set_timeout(uint32_t timeout_ms) { - LL_TIM_OC_SetCompareCH3(TIM2, timeout_ms * 1000); +void furi_hal_irda_async_rx_set_timeout(uint32_t timeout_us) { + furi_assert(LL_APB1_GRP1_IsEnabledClock(LL_APB1_GRP1_PERIPH_TIM2)); + + LL_TIM_OC_SetCompareCH3(TIM2, timeout_us); LL_TIM_OC_SetMode(TIM2, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_ACTIVE); LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH3); LL_TIM_EnableIT_CC3(TIM2); } -bool api_hal_irda_is_busy(void) { - return api_hal_irda_state != IrdaStateIdle; +bool furi_hal_irda_is_busy(void) { + return furi_hal_irda_state != IrdaStateIdle; } -void api_hal_irda_async_rx_set_capture_isr_callback(ApiHalIrdaRxCaptureCallback callback, void *ctx) { +void furi_hal_irda_async_rx_set_capture_isr_callback(FuriHalIrdaRxCaptureCallback callback, void *ctx) { irda_tim_rx.capture_callback = callback; irda_tim_rx.capture_context = ctx; } -void api_hal_irda_async_rx_set_timeout_isr_callback(ApiHalIrdaRxTimeoutCallback callback, void *ctx) { +void furi_hal_irda_async_rx_set_timeout_isr_callback(FuriHalIrdaRxTimeoutCallback callback, void *ctx) { irda_tim_rx.timeout_callback = callback; irda_tim_rx.timeout_context = ctx; } -static void api_hal_irda_tx_dma_terminate(void) { +static void furi_hal_irda_tx_dma_terminate(void) { LL_DMA_DisableIT_TC(DMA1, LL_DMA_CHANNEL_1); LL_DMA_DisableIT_HT(DMA1, LL_DMA_CHANNEL_2); LL_DMA_DisableIT_TC(DMA1, LL_DMA_CHANNEL_2); - furi_assert(api_hal_irda_state == IrdaStateAsyncTxStopInProgress); + furi_assert(furi_hal_irda_state == IrdaStateAsyncTxStopInProgress); LL_DMA_DisableIT_TC(DMA1, LL_DMA_CHANNEL_1); LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2); @@ -209,10 +213,10 @@ static void api_hal_irda_tx_dma_terminate(void) { LL_TIM_DisableCounter(TIM1); osStatus_t status = osSemaphoreRelease(irda_tim_tx.stop_semaphore); furi_check(status == osOK); - api_hal_irda_state = IrdaStateAsyncTxStopped; + furi_hal_irda_state = IrdaStateAsyncTxStopped; } -static uint8_t api_hal_irda_get_current_dma_tx_buffer(void) { +static uint8_t furi_hal_irda_get_current_dma_tx_buffer(void) { uint8_t buf_num = 0; uint32_t buffer_adr = LL_DMA_GetMemoryAddress(DMA1, LL_DMA_CHANNEL_2); if (buffer_adr == (uint32_t) irda_tim_tx.buffer[0].data) { @@ -225,7 +229,7 @@ static uint8_t api_hal_irda_get_current_dma_tx_buffer(void) { return buf_num; } -static void api_hal_irda_tx_dma_polarity_isr() { +static void furi_hal_irda_tx_dma_polarity_isr() { if (LL_DMA_IsActiveFlag_TE1(DMA1)) { LL_DMA_ClearFlag_TE1(DMA1); furi_check(0); @@ -233,36 +237,36 @@ static void api_hal_irda_tx_dma_polarity_isr() { if (LL_DMA_IsActiveFlag_TC1(DMA1) && LL_DMA_IsEnabledIT_TC(DMA1, LL_DMA_CHANNEL_1)) { LL_DMA_ClearFlag_TC1(DMA1); - furi_check((api_hal_irda_state == IrdaStateAsyncTx) - || (api_hal_irda_state == IrdaStateAsyncTxStopReq) - || (api_hal_irda_state == IrdaStateAsyncTxStopInProgress)); + furi_check((furi_hal_irda_state == IrdaStateAsyncTx) + || (furi_hal_irda_state == IrdaStateAsyncTxStopReq) + || (furi_hal_irda_state == IrdaStateAsyncTxStopInProgress)); /* actually TC2 is processed and buffer is next buffer */ - uint8_t next_buf_num = api_hal_irda_get_current_dma_tx_buffer(); - api_hal_irda_tx_dma_set_polarity(next_buf_num, 0); + uint8_t next_buf_num = furi_hal_irda_get_current_dma_tx_buffer(); + furi_hal_irda_tx_dma_set_polarity(next_buf_num, 0); } } -static void api_hal_irda_tx_dma_isr() { +static void furi_hal_irda_tx_dma_isr() { if (LL_DMA_IsActiveFlag_TE2(DMA1)) { LL_DMA_ClearFlag_TE2(DMA1); furi_check(0); } if (LL_DMA_IsActiveFlag_HT2(DMA1) && LL_DMA_IsEnabledIT_HT(DMA1, LL_DMA_CHANNEL_2)) { LL_DMA_ClearFlag_HT2(DMA1); - uint8_t buf_num = api_hal_irda_get_current_dma_tx_buffer(); + uint8_t buf_num = furi_hal_irda_get_current_dma_tx_buffer(); uint8_t next_buf_num = !buf_num; if (irda_tim_tx.buffer[buf_num].last_packet_end) { LL_DMA_DisableIT_HT(DMA1, LL_DMA_CHANNEL_2); - } else if (!irda_tim_tx.buffer[buf_num].packet_end || (api_hal_irda_state == IrdaStateAsyncTx)) { - bool result = api_hal_irda_tx_fill_buffer(next_buf_num, 0); + } else if (!irda_tim_tx.buffer[buf_num].packet_end || (furi_hal_irda_state == IrdaStateAsyncTx)) { + bool result = furi_hal_irda_tx_fill_buffer(next_buf_num, 0); if (irda_tim_tx.buffer[next_buf_num].last_packet_end) { LL_DMA_DisableIT_HT(DMA1, LL_DMA_CHANNEL_2); } if (!result) { furi_assert(0); - api_hal_irda_state = IrdaStateAsyncTxStopReq; + furi_hal_irda_state = IrdaStateAsyncTxStopReq; } - } else if (api_hal_irda_state == IrdaStateAsyncTxStopReq) { + } else if (furi_hal_irda_state == IrdaStateAsyncTxStopReq) { /* fallthrough */ } else { furi_check(0); @@ -270,27 +274,30 @@ static void api_hal_irda_tx_dma_isr() { } if (LL_DMA_IsActiveFlag_TC2(DMA1) && LL_DMA_IsEnabledIT_TC(DMA1, LL_DMA_CHANNEL_2)) { LL_DMA_ClearFlag_TC2(DMA1); - furi_check((api_hal_irda_state == IrdaStateAsyncTxStopInProgress) - || (api_hal_irda_state == IrdaStateAsyncTxStopReq) - || (api_hal_irda_state == IrdaStateAsyncTx)); + furi_check((furi_hal_irda_state == IrdaStateAsyncTxStopInProgress) + || (furi_hal_irda_state == IrdaStateAsyncTxStopReq) + || (furi_hal_irda_state == IrdaStateAsyncTx)); - uint8_t buf_num = api_hal_irda_get_current_dma_tx_buffer(); + uint8_t buf_num = furi_hal_irda_get_current_dma_tx_buffer(); uint8_t next_buf_num = !buf_num; - if (api_hal_irda_state == IrdaStateAsyncTxStopInProgress) { - api_hal_irda_tx_dma_terminate(); + if (furi_hal_irda_state == IrdaStateAsyncTxStopInProgress) { + furi_hal_irda_tx_dma_terminate(); } else if (irda_tim_tx.buffer[buf_num].last_packet_end - || (irda_tim_tx.buffer[buf_num].packet_end && (api_hal_irda_state == IrdaStateAsyncTxStopReq))) { - api_hal_irda_state = IrdaStateAsyncTxStopInProgress; - api_hal_irda_tx_fill_buffer_last(next_buf_num); - api_hal_irda_tx_dma_set_buffer(next_buf_num); + || (irda_tim_tx.buffer[buf_num].packet_end && (furi_hal_irda_state == IrdaStateAsyncTxStopReq))) { + furi_hal_irda_state = IrdaStateAsyncTxStopInProgress; + furi_hal_irda_tx_fill_buffer_last(next_buf_num); + furi_hal_irda_tx_dma_set_buffer(next_buf_num); } else { /* if it's not end of the packet - continue receiving */ - api_hal_irda_tx_dma_set_buffer(next_buf_num); + furi_hal_irda_tx_dma_set_buffer(next_buf_num); + } + if (irda_tim_tx.signal_sent_callback) { + irda_tim_tx.signal_sent_callback(irda_tim_tx.signal_sent_context); } } } -static void api_hal_irda_configure_tim_pwm_tx(uint32_t freq, float duty_cycle) +static void furi_hal_irda_configure_tim_pwm_tx(uint32_t freq, float duty_cycle) { LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1); /* LL_DBGMCU_APB2_GRP1_FreezePeriph(LL_DBGMCU_APB2_GRP1_TIM1_STOP); */ @@ -319,7 +326,7 @@ static void api_hal_irda_configure_tim_pwm_tx(uint32_t freq, float duty_cycle) NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn); } -static void api_hal_irda_configure_tim_cmgr2_dma_tx(void) { +static void furi_hal_irda_configure_tim_cmgr2_dma_tx(void) { LL_C2_AHB1_GRP1_EnableClock(LL_C2_AHB1_GRP1_PERIPH_DMA1); LL_DMA_InitTypeDef dma_config = {0}; @@ -336,7 +343,7 @@ static void api_hal_irda_configure_tim_cmgr2_dma_tx(void) { dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP; dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH; LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config); - api_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, api_hal_irda_tx_dma_polarity_isr); + furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, furi_hal_irda_tx_dma_polarity_isr); LL_DMA_ClearFlag_TE1(DMA1); LL_DMA_ClearFlag_TC1(DMA1); LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_1); @@ -346,7 +353,7 @@ static void api_hal_irda_configure_tim_cmgr2_dma_tx(void) { NVIC_EnableIRQ(DMA1_Channel1_IRQn); } -static void api_hal_irda_configure_tim_rcr_dma_tx(void) { +static void furi_hal_irda_configure_tim_rcr_dma_tx(void) { LL_C2_AHB1_GRP1_EnableClock(LL_C2_AHB1_GRP1_PERIPH_DMA1); LL_DMA_InitTypeDef dma_config = {0}; @@ -362,7 +369,7 @@ static void api_hal_irda_configure_tim_rcr_dma_tx(void) { dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP; dma_config.Priority = LL_DMA_PRIORITY_MEDIUM; LL_DMA_Init(DMA1, LL_DMA_CHANNEL_2, &dma_config); - api_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_2, api_hal_irda_tx_dma_isr); + furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_2, furi_hal_irda_tx_dma_isr); LL_DMA_ClearFlag_TC2(DMA1); LL_DMA_ClearFlag_HT2(DMA1); LL_DMA_ClearFlag_TE2(DMA1); @@ -374,10 +381,10 @@ static void api_hal_irda_configure_tim_rcr_dma_tx(void) { NVIC_EnableIRQ(DMA1_Channel2_IRQn); } -static void api_hal_irda_tx_fill_buffer_last(uint8_t buf_num) { +static void furi_hal_irda_tx_fill_buffer_last(uint8_t buf_num) { furi_assert(buf_num < 2); - furi_assert(api_hal_irda_state != IrdaStateAsyncRx); - furi_assert(api_hal_irda_state < IrdaStateMAX); + furi_assert(furi_hal_irda_state != IrdaStateAsyncRx); + furi_assert(furi_hal_irda_state < IrdaStateMAX); furi_assert(irda_tim_tx.data_callback); IrdaTxBuf* buffer = &irda_tim_tx.buffer[buf_num]; furi_assert(buffer->data != NULL); @@ -392,16 +399,16 @@ static void api_hal_irda_tx_fill_buffer_last(uint8_t buf_num) { irda_tim_tx.buffer[buf_num].packet_end = true; } -static bool api_hal_irda_tx_fill_buffer(uint8_t buf_num, uint8_t polarity_shift) { +static bool furi_hal_irda_tx_fill_buffer(uint8_t buf_num, uint8_t polarity_shift) { furi_assert(buf_num < 2); - furi_assert(api_hal_irda_state != IrdaStateAsyncRx); - furi_assert(api_hal_irda_state < IrdaStateMAX); + furi_assert(furi_hal_irda_state != IrdaStateAsyncRx); + furi_assert(furi_hal_irda_state < IrdaStateMAX); furi_assert(irda_tim_tx.data_callback); IrdaTxBuf* buffer = &irda_tim_tx.buffer[buf_num]; furi_assert(buffer->data != NULL); furi_assert(buffer->polarity != NULL); - ApiHalIrdaTxGetDataState status = ApiHalIrdaTxGetDataStateOk; + FuriHalIrdaTxGetDataState status = FuriHalIrdaTxGetDataStateOk; uint32_t duration = 0; bool level = 0; size_t *size = &buffer->size; @@ -410,9 +417,9 @@ static bool api_hal_irda_tx_fill_buffer(uint8_t buf_num, uint8_t polarity_shift) buffer->polarity[polarity_counter++] = IRDA_TX_CCMR_LOW; } - for (*size = 0; (*size < IRDA_TIM_TX_DMA_BUFFER_SIZE) && (status == ApiHalIrdaTxGetDataStateOk); ++(*size), ++polarity_counter) { + for (*size = 0; (*size < IRDA_TIM_TX_DMA_BUFFER_SIZE) && (status == FuriHalIrdaTxGetDataStateOk); ++(*size), ++polarity_counter) { status = irda_tim_tx.data_callback(irda_tim_tx.data_context, &duration, &level); - if (status == ApiHalIrdaTxGetDataStateError) { + if (status == FuriHalIrdaTxGetDataStateError) { furi_assert(0); break; } @@ -421,7 +428,7 @@ static bool api_hal_irda_tx_fill_buffer(uint8_t buf_num, uint8_t polarity_shift) if ((buffer->data[*size] + num_of_impulses - 1) > 0xFFFF) { furi_assert(0); - status = ApiHalIrdaTxGetDataStateError; + status = FuriHalIrdaTxGetDataStateError; break; } @@ -429,15 +436,15 @@ static bool api_hal_irda_tx_fill_buffer(uint8_t buf_num, uint8_t polarity_shift) buffer->data[*size] = num_of_impulses - 1; } - buffer->last_packet_end = (status == ApiHalIrdaTxGetDataStateLastDone); - buffer->packet_end = buffer->last_packet_end || (status == ApiHalIrdaTxGetDataStateDone); + buffer->last_packet_end = (status == FuriHalIrdaTxGetDataStateLastDone); + buffer->packet_end = buffer->last_packet_end || (status == FuriHalIrdaTxGetDataStateDone); - return status != ApiHalIrdaTxGetDataStateError; + return status != FuriHalIrdaTxGetDataStateError; } -static void api_hal_irda_tx_dma_set_polarity(uint8_t buf_num, uint8_t polarity_shift) { +static void furi_hal_irda_tx_dma_set_polarity(uint8_t buf_num, uint8_t polarity_shift) { furi_assert(buf_num < 2); - furi_assert(api_hal_irda_state < IrdaStateMAX); + furi_assert(furi_hal_irda_state < IrdaStateMAX); IrdaTxBuf* buffer = &irda_tim_tx.buffer[buf_num]; furi_assert(buffer->polarity != NULL); @@ -454,9 +461,9 @@ static void api_hal_irda_tx_dma_set_polarity(uint8_t buf_num, uint8_t polarity_s __enable_irq(); } -static void api_hal_irda_tx_dma_set_buffer(uint8_t buf_num) { +static void furi_hal_irda_tx_dma_set_buffer(uint8_t buf_num) { furi_assert(buf_num < 2); - furi_assert(api_hal_irda_state < IrdaStateMAX); + furi_assert(furi_hal_irda_state < IrdaStateMAX); IrdaTxBuf* buffer = &irda_tim_tx.buffer[buf_num]; furi_assert(buffer->data != NULL); @@ -474,13 +481,13 @@ static void api_hal_irda_tx_dma_set_buffer(uint8_t buf_num) { __enable_irq(); } -static void api_hal_irda_async_tx_free_resources(void) { - furi_assert((api_hal_irda_state == IrdaStateIdle) || (api_hal_irda_state == IrdaStateAsyncTxStopped)); +static void furi_hal_irda_async_tx_free_resources(void) { + furi_assert((furi_hal_irda_state == IrdaStateIdle) || (furi_hal_irda_state == IrdaStateAsyncTxStopped)); osStatus_t status; - hal_gpio_init_ex(&gpio_irda_tx, GpioModeOutputOpenDrain, GpioPullDown, GpioSpeedLow, 0); - api_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, NULL); - api_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_2, NULL); + hal_gpio_init(&gpio_irda_tx, GpioModeOutputOpenDrain, GpioPullDown, GpioSpeedLow); + furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, NULL); + furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_2, NULL); LL_TIM_DeInit(TIM1); LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_TIM1); LL_C2_AHB1_GRP1_DisableClock(LL_C2_AHB1_GRP1_PERIPH_DMA1); @@ -498,13 +505,13 @@ static void api_hal_irda_async_tx_free_resources(void) { irda_tim_tx.buffer[1].polarity = NULL; } -bool api_hal_irda_async_tx_start(uint32_t freq, float duty_cycle) { +bool furi_hal_irda_async_tx_start(uint32_t freq, float duty_cycle) { if ((duty_cycle > 1) || (duty_cycle < 0) || (freq > 40000) || (freq < 10000) || (irda_tim_tx.data_callback == NULL)) { furi_assert(0); return false; } - furi_assert(api_hal_irda_state == IrdaStateIdle); + furi_assert(furi_hal_irda_state == IrdaStateIdle); furi_assert(irda_tim_tx.buffer[0].data == NULL); furi_assert(irda_tim_tx.buffer[1].data == NULL); furi_assert(irda_tim_tx.buffer[0].polarity == NULL); @@ -521,16 +528,16 @@ bool api_hal_irda_async_tx_start(uint32_t freq, float duty_cycle) { irda_tim_tx.stop_semaphore = osSemaphoreNew(1, 0, NULL); irda_tim_tx.cycle_duration = 1000000.0 / freq; - bool result = api_hal_irda_tx_fill_buffer(0, IRDA_POLARITY_SHIFT); + bool result = furi_hal_irda_tx_fill_buffer(0, IRDA_POLARITY_SHIFT); if (result) { - api_hal_irda_configure_tim_pwm_tx(freq, duty_cycle); - api_hal_irda_configure_tim_cmgr2_dma_tx(); - api_hal_irda_configure_tim_rcr_dma_tx(); - api_hal_irda_tx_dma_set_polarity(0, IRDA_POLARITY_SHIFT); - api_hal_irda_tx_dma_set_buffer(0); + furi_hal_irda_configure_tim_pwm_tx(freq, duty_cycle); + furi_hal_irda_configure_tim_cmgr2_dma_tx(); + furi_hal_irda_configure_tim_rcr_dma_tx(); + furi_hal_irda_tx_dma_set_polarity(0, IRDA_POLARITY_SHIFT); + furi_hal_irda_tx_dma_set_buffer(0); - api_hal_irda_state = IrdaStateAsyncTx; + furi_hal_irda_state = IrdaStateAsyncTx; LL_TIM_ClearFlag_UPDATE(TIM1); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); @@ -547,38 +554,43 @@ bool api_hal_irda_async_tx_start(uint32_t freq, float duty_cycle) { __enable_irq(); } else { - api_hal_irda_async_tx_free_resources(); + furi_hal_irda_async_tx_free_resources(); } return result; } -void api_hal_irda_async_tx_wait_termination(void) { - furi_assert(api_hal_irda_state >= IrdaStateAsyncTx); - furi_assert(api_hal_irda_state < IrdaStateMAX); +void furi_hal_irda_async_tx_wait_termination(void) { + furi_assert(furi_hal_irda_state >= IrdaStateAsyncTx); + furi_assert(furi_hal_irda_state < IrdaStateMAX); osStatus_t status; status = osSemaphoreAcquire(irda_tim_tx.stop_semaphore, osWaitForever); furi_check(status == osOK); - api_hal_irda_async_tx_free_resources(); - api_hal_irda_state = IrdaStateIdle; + furi_hal_irda_async_tx_free_resources(); + furi_hal_irda_state = IrdaStateIdle; } -void api_hal_irda_async_tx_stop(void) { - furi_assert(api_hal_irda_state >= IrdaStateAsyncTx); - furi_assert(api_hal_irda_state < IrdaStateMAX); +void furi_hal_irda_async_tx_stop(void) { + furi_assert(furi_hal_irda_state >= IrdaStateAsyncTx); + furi_assert(furi_hal_irda_state < IrdaStateMAX); __disable_irq(); - if (api_hal_irda_state == IrdaStateAsyncTx) - api_hal_irda_state = IrdaStateAsyncTxStopReq; + if (furi_hal_irda_state == IrdaStateAsyncTx) + furi_hal_irda_state = IrdaStateAsyncTxStopReq; __enable_irq(); - api_hal_irda_async_tx_wait_termination(); + furi_hal_irda_async_tx_wait_termination(); } -void api_hal_irda_async_tx_set_data_isr_callback(ApiHalIrdaTxGetDataCallback callback, void* context) { - furi_assert(api_hal_irda_state == IrdaStateIdle); +void furi_hal_irda_async_tx_set_data_isr_callback(FuriHalIrdaTxGetDataISRCallback callback, void* context) { + furi_assert(furi_hal_irda_state == IrdaStateIdle); irda_tim_tx.data_callback = callback; irda_tim_tx.data_context = context; } +void furi_hal_irda_async_tx_set_signal_sent_isr_callback(FuriHalIrdaTxSignalSentISRCallback callback, void* context) { + irda_tim_tx.signal_sent_callback = callback; + irda_tim_tx.signal_sent_context = context; +} + diff --git a/firmware/targets/f6/api-hal/api-hal-light.c b/firmware/targets/f6/furi-hal/furi-hal-light.c similarity index 91% rename from firmware/targets/f6/api-hal/api-hal-light.c rename to firmware/targets/f6/furi-hal/furi-hal-light.c index b01a9ab9dd1..fba1bec43b9 100644 --- a/firmware/targets/f6/api-hal/api-hal-light.c +++ b/firmware/targets/f6/furi-hal/furi-hal-light.c @@ -1,4 +1,4 @@ -#include +#include #include #define LED_CURRENT_RED 50 @@ -6,7 +6,7 @@ #define LED_CURRENT_BLUE 50 #define LED_CURRENT_WHITE 150 -void api_hal_light_init() { +void furi_hal_light_init() { lp5562_reset(); lp5562_set_channel_current(LP5562ChannelRed, LED_CURRENT_RED); @@ -24,7 +24,7 @@ void api_hal_light_init() { FURI_LOG_I("FuriHalLight", "Init OK"); } -void api_hal_light_set(Light light, uint8_t value) { +void furi_hal_light_set(Light light, uint8_t value) { switch(light) { case LightRed: lp5562_set_channel_value(LP5562ChannelRed, value); diff --git a/firmware/targets/f6/api-hal/api-hal-nfc.c b/firmware/targets/f6/furi-hal/furi-hal-nfc.c similarity index 86% rename from firmware/targets/f6/api-hal/api-hal-nfc.c rename to firmware/targets/f6/furi-hal/furi-hal-nfc.c index cb75dd26b1b..d64a344ec77 100644 --- a/firmware/targets/f6/api-hal/api-hal-nfc.c +++ b/firmware/targets/f6/furi-hal/furi-hal-nfc.c @@ -1,41 +1,41 @@ -#include "api-hal-nfc.h" +#include "furi-hal-nfc.h" #include static const uint32_t clocks_in_ms = 64 * 1000; -void api_hal_nfc_init() { +void furi_hal_nfc_init() { ReturnCode ret = rfalNfcInitialize(); if(ret == ERR_NONE) { - api_hal_nfc_start_sleep(); + furi_hal_nfc_start_sleep(); FURI_LOG_I("FuriHalNfc", "Init OK"); } else { FURI_LOG_W("FuriHalNfc", "Initialization failed, RFAL returned: %d", ret); } } -bool api_hal_nfc_is_busy() { +bool furi_hal_nfc_is_busy() { return rfalNfcGetState() != RFAL_NFC_STATE_IDLE; } -void api_hal_nfc_field_on() { - api_hal_nfc_exit_sleep(); +void furi_hal_nfc_field_on() { + furi_hal_nfc_exit_sleep(); st25r3916TxRxOn(); } -void api_hal_nfc_field_off() { +void furi_hal_nfc_field_off() { st25r3916TxRxOff(); - api_hal_nfc_start_sleep(); + furi_hal_nfc_start_sleep(); } -void api_hal_nfc_start_sleep() { +void furi_hal_nfc_start_sleep() { rfalLowPowerModeStart(); } -void api_hal_nfc_exit_sleep() { +void furi_hal_nfc_exit_sleep() { rfalLowPowerModeStop(); } -bool api_hal_nfc_detect(rfalNfcDevice **dev_list, uint8_t* dev_cnt, uint32_t timeout, bool deactivate) { +bool furi_hal_nfc_detect(rfalNfcDevice **dev_list, uint8_t* dev_cnt, uint32_t timeout, bool deactivate) { furi_assert(dev_list); furi_assert(dev_cnt); @@ -86,7 +86,7 @@ bool api_hal_nfc_detect(rfalNfcDevice **dev_list, uint8_t* dev_cnt, uint32_t tim return true; } -bool api_hal_nfc_listen(uint8_t* uid, uint8_t uid_len, uint8_t* atqa, uint8_t sak, uint32_t timeout) { +bool furi_hal_nfc_listen(uint8_t* uid, uint8_t uid_len, uint8_t* atqa, uint8_t sak, uint32_t timeout) { rfalNfcState state = rfalNfcGetState(); if(state == RFAL_NFC_STATE_NOTINIT) { @@ -129,7 +129,7 @@ bool api_hal_nfc_listen(uint8_t* uid, uint8_t uid_len, uint8_t* atqa, uint8_t sa return true; } -ReturnCode api_hal_nfc_data_exchange(uint8_t* tx_buff, uint16_t tx_len, uint8_t** rx_buff, uint16_t** rx_len, bool deactivate) { +ReturnCode furi_hal_nfc_data_exchange(uint8_t* tx_buff, uint16_t tx_len, uint8_t** rx_buff, uint16_t** rx_len, bool deactivate) { furi_assert(rx_buff); furi_assert(rx_len); @@ -165,7 +165,7 @@ ReturnCode api_hal_nfc_data_exchange(uint8_t* tx_buff, uint16_t tx_len, uint8_t* return ERR_NONE; } -void api_hal_nfc_deactivate() { +void furi_hal_nfc_deactivate() { rfalNfcDeactivate(false); rfalLowPowerModeStart(); } diff --git a/firmware/targets/f6/furi-hal/furi-hal-os-timer.h b/firmware/targets/f6/furi-hal/furi-hal-os-timer.h new file mode 100644 index 00000000000..f210b539ca7 --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-os-timer.h @@ -0,0 +1,64 @@ +#pragma once + +#include +#include +#include + +// Timer used for system ticks +#define FURI_HAL_OS_TIMER_MAX 0xFFFF +#define FURI_HAL_OS_TIMER_REG_LOAD_DLY 0x1 +#define FURI_HAL_OS_TIMER LPTIM2 +#define FURI_HAL_OS_TIMER_IRQ LPTIM2_IRQn + +static inline void furi_hal_os_timer_init() { + // Configure clock source + LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_LSE); + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPTIM2); + // Set interrupt priority and enable them + NVIC_SetPriority(FURI_HAL_OS_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0)); + NVIC_EnableIRQ(FURI_HAL_OS_TIMER_IRQ); +} + +static inline void furi_hal_os_timer_continuous(uint32_t count) { + // Enable timer + LL_LPTIM_Enable(FURI_HAL_OS_TIMER); + while(!LL_LPTIM_IsEnabled(FURI_HAL_OS_TIMER)); + + // Enable rutoreload match interrupt + LL_LPTIM_EnableIT_ARRM(FURI_HAL_OS_TIMER); + + // Set autoreload and start counter + LL_LPTIM_SetAutoReload(FURI_HAL_OS_TIMER, count); + LL_LPTIM_StartCounter(FURI_HAL_OS_TIMER, LL_LPTIM_OPERATING_MODE_CONTINUOUS); +} + +static inline void furi_hal_os_timer_single(uint32_t count) { + // Enable timer + LL_LPTIM_Enable(FURI_HAL_OS_TIMER); + while(!LL_LPTIM_IsEnabled(FURI_HAL_OS_TIMER)); + + // Enable compare match interrupt + LL_LPTIM_EnableIT_CMPM(FURI_HAL_OS_TIMER); + + // Set compare, autoreload and start counter + // Include some marging to workaround ARRM behaviour + LL_LPTIM_SetCompare(FURI_HAL_OS_TIMER, count-3); + LL_LPTIM_SetAutoReload(FURI_HAL_OS_TIMER, count); + LL_LPTIM_StartCounter(FURI_HAL_OS_TIMER, LL_LPTIM_OPERATING_MODE_ONESHOT); +} + +static inline void furi_hal_os_timer_reset() { + // Hard reset timer + // THE ONLY RELIABLEWAY to stop it according to errata + LL_LPTIM_DeInit(FURI_HAL_OS_TIMER); +} + +static inline uint32_t furi_hal_os_timer_get_cnt() { + uint32_t counter = LL_LPTIM_GetCounter(FURI_HAL_OS_TIMER); + uint32_t counter_shadow = LL_LPTIM_GetCounter(FURI_HAL_OS_TIMER); + while(counter != counter_shadow) { + counter = counter_shadow; + counter_shadow = LL_LPTIM_GetCounter(FURI_HAL_OS_TIMER); + } + return counter; +} diff --git a/firmware/targets/f6/api-hal/api-hal-os.c b/firmware/targets/f6/furi-hal/furi-hal-os.c similarity index 55% rename from firmware/targets/f6/api-hal/api-hal-os.c rename to firmware/targets/f6/furi-hal/furi-hal-os.c index 2f4d83634e2..0e55df53d8d 100644 --- a/firmware/targets/f6/api-hal/api-hal-os.c +++ b/firmware/targets/f6/furi-hal/furi-hal-os.c @@ -1,17 +1,17 @@ -#include -#include -#include +#include +#include +#include #include #include -#define API_HAL_OS_CLK_FREQUENCY 32768 -#define API_HAL_OS_TICK_PER_SECOND 1024 -#define API_HAL_OS_CLK_PER_TICK (API_HAL_OS_CLK_FREQUENCY / API_HAL_OS_TICK_PER_SECOND) -#define API_HAL_OS_TICK_PER_EPOCH (API_HAL_OS_TIMER_MAX / API_HAL_OS_CLK_PER_TICK) -#define API_HAL_OS_MAX_SLEEP (API_HAL_OS_TICK_PER_EPOCH - 1) +#define FURI_HAL_OS_CLK_FREQUENCY 32768 +#define FURI_HAL_OS_TICK_PER_SECOND 1024 +#define FURI_HAL_OS_CLK_PER_TICK (FURI_HAL_OS_CLK_FREQUENCY / FURI_HAL_OS_TICK_PER_SECOND) +#define FURI_HAL_OS_TICK_PER_EPOCH (FURI_HAL_OS_TIMER_MAX / FURI_HAL_OS_CLK_PER_TICK) +#define FURI_HAL_OS_MAX_SLEEP (FURI_HAL_OS_TICK_PER_EPOCH - 1) -#ifdef API_HAL_OS_DEBUG +#ifdef FURI_HAL_OS_DEBUG #include #define LED_SLEEP_PORT GPIOA @@ -21,24 +21,24 @@ #define LED_SECOND_PORT GPIOA #define LED_SECOND_PIN LL_GPIO_PIN_4 -void api_hal_os_timer_callback() { +void furi_hal_os_timer_callback() { LL_GPIO_TogglePin(LED_SECOND_PORT, LED_SECOND_PIN); } #endif -volatile uint32_t api_hal_os_skew = 0; +volatile uint32_t furi_hal_os_skew = 0; -void api_hal_os_init() { +void furi_hal_os_init() { LL_DBGMCU_APB1_GRP2_FreezePeriph(LL_DBGMCU_APB1_GRP2_LPTIM2_STOP); - api_hal_os_timer_init(); - api_hal_os_timer_continuous(API_HAL_OS_CLK_PER_TICK); + furi_hal_os_timer_init(); + furi_hal_os_timer_continuous(FURI_HAL_OS_CLK_PER_TICK); -#ifdef API_HAL_OS_DEBUG +#ifdef FURI_HAL_OS_DEBUG LL_GPIO_SetPinMode(LED_SLEEP_PORT, LED_SLEEP_PIN, LL_GPIO_MODE_OUTPUT); LL_GPIO_SetPinMode(LED_TICK_PORT, LED_TICK_PIN, LL_GPIO_MODE_OUTPUT); LL_GPIO_SetPinMode(LED_SECOND_PORT, LED_SECOND_PIN, LL_GPIO_MODE_OUTPUT); - osTimerId_t second_timer = osTimerNew(api_hal_os_timer_callback, osTimerPeriodic, NULL, NULL); + osTimerId_t second_timer = osTimerNew(furi_hal_os_timer_callback, osTimerPeriodic, NULL, NULL); osTimerStart(second_timer, 1024); #endif @@ -47,67 +47,67 @@ void api_hal_os_init() { void LPTIM2_IRQHandler(void) { // Autoreload - if(LL_LPTIM_IsActiveFlag_ARRM(API_HAL_OS_TIMER)) { - LL_LPTIM_ClearFLAG_ARRM(API_HAL_OS_TIMER); + if(LL_LPTIM_IsActiveFlag_ARRM(FURI_HAL_OS_TIMER)) { + LL_LPTIM_ClearFLAG_ARRM(FURI_HAL_OS_TIMER); if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { - #ifdef API_HAL_OS_DEBUG + #ifdef FURI_HAL_OS_DEBUG LL_GPIO_TogglePin(LED_TICK_PORT, LED_TICK_PIN); #endif xPortSysTickHandler(); } } - if(LL_LPTIM_IsActiveFlag_CMPM(API_HAL_OS_TIMER)) { - LL_LPTIM_ClearFLAG_CMPM(API_HAL_OS_TIMER); + if(LL_LPTIM_IsActiveFlag_CMPM(FURI_HAL_OS_TIMER)) { + LL_LPTIM_ClearFLAG_CMPM(FURI_HAL_OS_TIMER); } } -static inline uint32_t api_hal_os_sleep(TickType_t expected_idle_ticks) { +static inline uint32_t furi_hal_os_sleep(TickType_t expected_idle_ticks) { // Stop ticks - api_hal_os_timer_reset(); + furi_hal_os_timer_reset(); LL_SYSTICK_DisableIT(); // Start wakeup timer - api_hal_os_timer_single(expected_idle_ticks * API_HAL_OS_CLK_PER_TICK); + furi_hal_os_timer_single(expected_idle_ticks * FURI_HAL_OS_CLK_PER_TICK); -#ifdef API_HAL_OS_DEBUG +#ifdef FURI_HAL_OS_DEBUG LL_GPIO_ResetOutputPin(LED_SLEEP_PORT, LED_SLEEP_PIN); #endif // Go to sleep mode - api_hal_power_sleep(); + furi_hal_power_sleep(); -#ifdef API_HAL_OS_DEBUG +#ifdef FURI_HAL_OS_DEBUG LL_GPIO_SetOutputPin(LED_SLEEP_PORT, LED_SLEEP_PIN); #endif // Calculate how much time we spent in the sleep - uint32_t after_cnt = api_hal_os_timer_get_cnt() + api_hal_os_skew; - uint32_t after_tick = after_cnt / API_HAL_OS_CLK_PER_TICK; - api_hal_os_skew = after_cnt % API_HAL_OS_CLK_PER_TICK; + uint32_t after_cnt = furi_hal_os_timer_get_cnt() + furi_hal_os_skew; + uint32_t after_tick = after_cnt / FURI_HAL_OS_CLK_PER_TICK; + furi_hal_os_skew = after_cnt % FURI_HAL_OS_CLK_PER_TICK; - bool cmpm = LL_LPTIM_IsActiveFlag_CMPM(API_HAL_OS_TIMER); - bool arrm = LL_LPTIM_IsActiveFlag_ARRM(API_HAL_OS_TIMER); + bool cmpm = LL_LPTIM_IsActiveFlag_CMPM(FURI_HAL_OS_TIMER); + bool arrm = LL_LPTIM_IsActiveFlag_ARRM(FURI_HAL_OS_TIMER); if (cmpm && arrm) after_tick += expected_idle_ticks; // Prepare tick timer for new round - api_hal_os_timer_reset(); + furi_hal_os_timer_reset(); // Resume ticks LL_SYSTICK_EnableIT(); - api_hal_os_timer_continuous(API_HAL_OS_CLK_PER_TICK); + furi_hal_os_timer_continuous(FURI_HAL_OS_CLK_PER_TICK); return after_tick; } void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { - if(!api_hal_power_sleep_available()) { + if(!furi_hal_power_sleep_available()) { __WFI(); return; } // Limit mount of ticks to maximum that timer can count - if (expected_idle_ticks > API_HAL_OS_MAX_SLEEP) { - expected_idle_ticks = API_HAL_OS_MAX_SLEEP; + if (expected_idle_ticks > FURI_HAL_OS_MAX_SLEEP) { + expected_idle_ticks = FURI_HAL_OS_MAX_SLEEP; } // Stop IRQ handling, no one should disturb us till we finish @@ -120,7 +120,7 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { } // Sleep and track how much ticks we spent sleeping - uint32_t completed_ticks = api_hal_os_sleep(expected_idle_ticks); + uint32_t completed_ticks = furi_hal_os_sleep(expected_idle_ticks); // Reenable IRQ __enable_irq(); diff --git a/firmware/targets/f6/api-hal/api-hal-os.h b/firmware/targets/f6/furi-hal/furi-hal-os.h similarity index 86% rename from firmware/targets/f6/api-hal/api-hal-os.h rename to firmware/targets/f6/furi-hal/furi-hal-os.h index 45666889ca8..72ae74fc6e1 100644 --- a/firmware/targets/f6/api-hal/api-hal-os.h +++ b/firmware/targets/f6/furi-hal/furi-hal-os.h @@ -10,7 +10,7 @@ extern "C" { /* Initialize OS helpers * Configure and start tick timer */ -void api_hal_os_init(); +void furi_hal_os_init(); #ifdef __cplusplus } diff --git a/firmware/targets/f6/api-hal/api-hal-power.c b/firmware/targets/f6/furi-hal/furi-hal-power.c similarity index 73% rename from firmware/targets/f6/api-hal/api-hal-power.c rename to firmware/targets/f6/furi-hal/furi-hal-power.c index 24533e735bf..4dd0127f1dc 100644 --- a/firmware/targets/f6/api-hal/api-hal-power.c +++ b/firmware/targets/f6/furi-hal/furi-hal-power.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #include #include @@ -18,9 +18,9 @@ typedef struct { volatile uint32_t insomnia; volatile uint32_t deep_insomnia; -} ApiHalPower; +} FuriHalPower; -static volatile ApiHalPower api_hal_power = { +static volatile FuriHalPower furi_hal_power = { .insomnia = 0, .deep_insomnia = 1, }; @@ -64,10 +64,10 @@ const ParamCEDV cedv = { void HAL_RCC_CSSCallback(void) { // TODO: notify user about issue with HSE - api_hal_power_reset(); + furi_hal_power_reset(); } -void api_hal_power_init() { +void furi_hal_power_init() { LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); LL_PWR_SMPS_SetMode(LL_PWR_SMPS_STEP_DOWN); bq27220_init(&cedv); @@ -75,31 +75,31 @@ void api_hal_power_init() { FURI_LOG_I("FuriHalPower", "Init OK"); } -uint16_t api_hal_power_insomnia_level() { - return api_hal_power.insomnia; +uint16_t furi_hal_power_insomnia_level() { + return furi_hal_power.insomnia; } -void api_hal_power_insomnia_enter() { - api_hal_power.insomnia++; +void furi_hal_power_insomnia_enter() { + furi_hal_power.insomnia++; } -void api_hal_power_insomnia_exit() { - api_hal_power.insomnia--; +void furi_hal_power_insomnia_exit() { + furi_hal_power.insomnia--; } -bool api_hal_power_sleep_available() { - return api_hal_power.insomnia == 0; +bool furi_hal_power_sleep_available() { + return furi_hal_power.insomnia == 0; } -bool api_hal_power_deep_sleep_available() { - return api_hal_bt_is_alive() && api_hal_power.deep_insomnia == 0; +bool furi_hal_power_deep_sleep_available() { + return furi_hal_bt_is_alive() && furi_hal_power.deep_insomnia == 0; } -void api_hal_power_light_sleep() { +void furi_hal_power_light_sleep() { __WFI(); } -void api_hal_power_deep_sleep() { +void furi_hal_power_deep_sleep() { while( LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)); if (!LL_HSEM_1StepLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID)) { @@ -108,13 +108,13 @@ void api_hal_power_deep_sleep() { LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0); // The switch on HSI before entering Stop Mode is required - api_hal_clock_switch_to_hsi(); + furi_hal_clock_switch_to_hsi(); } } else { /** * The switch on HSI before entering Stop Mode is required */ - api_hal_clock_switch_to_hsi(); + furi_hal_clock_switch_to_hsi(); } /* Release RCC semaphore */ @@ -137,82 +137,82 @@ void api_hal_power_deep_sleep() { while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)); if(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { - api_hal_clock_switch_to_pll(); + furi_hal_clock_switch_to_pll(); } LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); } -void api_hal_power_sleep() { - if(api_hal_power_deep_sleep_available()) { - api_hal_power_deep_sleep(); +void furi_hal_power_sleep() { + if(furi_hal_power_deep_sleep_available()) { + furi_hal_power_deep_sleep(); } else { - api_hal_power_light_sleep(); + furi_hal_power_light_sleep(); } } -uint8_t api_hal_power_get_pct() { +uint8_t furi_hal_power_get_pct() { return bq27220_get_state_of_charge(); } -uint8_t api_hal_power_get_bat_health_pct() { +uint8_t furi_hal_power_get_bat_health_pct() { return bq27220_get_state_of_health(); } -bool api_hal_power_is_charging() { +bool furi_hal_power_is_charging() { return bq25896_is_charging(); } -void api_hal_power_off() { +void furi_hal_power_off() { bq25896_poweroff(); } -void api_hal_power_reset() { +void furi_hal_power_reset() { NVIC_SystemReset(); } -void api_hal_power_enable_otg() { +void furi_hal_power_enable_otg() { bq25896_enable_otg(); } -void api_hal_power_disable_otg() { +void furi_hal_power_disable_otg() { bq25896_disable_otg(); } -uint32_t api_hal_power_get_battery_remaining_capacity() { +uint32_t furi_hal_power_get_battery_remaining_capacity() { return bq27220_get_remaining_capacity(); } -uint32_t api_hal_power_get_battery_full_capacity() { +uint32_t furi_hal_power_get_battery_full_capacity() { return bq27220_get_full_charge_capacity(); } -float api_hal_power_get_battery_voltage(ApiHalPowerIC ic) { - if (ic == ApiHalPowerICCharger) { +float furi_hal_power_get_battery_voltage(FuriHalPowerIC ic) { + if (ic == FuriHalPowerICCharger) { return (float)bq25896_get_vbat_voltage() / 1000.0f; - } else if (ic == ApiHalPowerICFuelGauge) { + } else if (ic == FuriHalPowerICFuelGauge) { return (float)bq27220_get_voltage() / 1000.0f; } else { return 0.0f; } } -float api_hal_power_get_battery_current(ApiHalPowerIC ic) { - if (ic == ApiHalPowerICCharger) { +float furi_hal_power_get_battery_current(FuriHalPowerIC ic) { + if (ic == FuriHalPowerICCharger) { return (float)bq25896_get_vbat_current() / 1000.0f; - } else if (ic == ApiHalPowerICFuelGauge) { + } else if (ic == FuriHalPowerICFuelGauge) { return (float)bq27220_get_current() / 1000.0f; } else { return 0.0f; } } -float api_hal_power_get_battery_temperature(ApiHalPowerIC ic) { - if (ic == ApiHalPowerICCharger) { +float furi_hal_power_get_battery_temperature(FuriHalPowerIC ic) { + if (ic == FuriHalPowerICCharger) { // Linear approximation, +/- 5 C return (71.0f - (float)bq25896_get_ntc_mpct()/1000) / 0.6f; - } else if (ic == ApiHalPowerICFuelGauge) { + } else if (ic == FuriHalPowerICFuelGauge) { return ((float)bq27220_get_temperature() - 2731.0f) / 10.0f; } else { return 0.0f; @@ -220,11 +220,11 @@ float api_hal_power_get_battery_temperature(ApiHalPowerIC ic) { } -float api_hal_power_get_usb_voltage(){ +float furi_hal_power_get_usb_voltage(){ return (float)bq25896_get_vbus_voltage() / 1000.0f; } -void api_hal_power_dump_state() { +void furi_hal_power_dump_state() { BatteryStatus battery_status; OperationStatus operation_status; if (bq27220_get_battery_status(&battery_status) == BQ27220_ERROR @@ -259,7 +259,7 @@ void api_hal_power_dump_state() { ); printf( "bq27220: Voltage: %dmV, Current: %dmA, Temperature: %dC\r\n", - bq27220_get_voltage(), bq27220_get_current(), (int)api_hal_power_get_battery_temperature(ApiHalPowerICFuelGauge) + bq27220_get_voltage(), bq27220_get_current(), (int)furi_hal_power_get_battery_temperature(FuriHalPowerICFuelGauge) ); } @@ -271,10 +271,10 @@ void api_hal_power_dump_state() { ); } -void api_hal_power_enable_external_3_3v(){ +void furi_hal_power_enable_external_3_3v(){ LL_GPIO_SetOutputPin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin); } -void api_hal_power_disable_external_3_3v(){ +void furi_hal_power_disable_external_3_3v(){ LL_GPIO_ResetOutputPin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin); } diff --git a/firmware/targets/f6/api-hal/api-hal-pwm.c b/firmware/targets/f6/furi-hal/furi-hal-pwm.c similarity index 98% rename from firmware/targets/f6/api-hal/api-hal-pwm.c rename to firmware/targets/f6/furi-hal/furi-hal-pwm.c index 7ffdd5661a0..972d28baa3f 100644 --- a/firmware/targets/f6/api-hal/api-hal-pwm.c +++ b/firmware/targets/f6/furi-hal/furi-hal-pwm.c @@ -1,4 +1,4 @@ -#include "api-hal-pwm.h" +#include "furi-hal-pwm.h" void hal_pwm_set(float value, float freq, TIM_HandleTypeDef* tim, uint32_t channel) { tim->Init.CounterMode = TIM_COUNTERMODE_UP; diff --git a/firmware/targets/f6/api-hal/api-hal-pwm.h b/firmware/targets/f6/furi-hal/furi-hal-pwm.h similarity index 100% rename from firmware/targets/f6/api-hal/api-hal-pwm.h rename to firmware/targets/f6/furi-hal/furi-hal-pwm.h diff --git a/firmware/targets/f6/api-hal/api-hal-resources.c b/firmware/targets/f6/furi-hal/furi-hal-resources.c similarity index 98% rename from firmware/targets/f6/api-hal/api-hal-resources.c rename to firmware/targets/f6/furi-hal/furi-hal-resources.c index 29974876925..f1d2003fd76 100644 --- a/firmware/targets/f6/api-hal/api-hal-resources.c +++ b/firmware/targets/f6/furi-hal/furi-hal-resources.c @@ -1,4 +1,4 @@ -#include +#include #include "main.h" #include diff --git a/firmware/targets/f6/api-hal/api-hal-resources.h b/firmware/targets/f6/furi-hal/furi-hal-resources.h similarity index 100% rename from firmware/targets/f6/api-hal/api-hal-resources.h rename to firmware/targets/f6/furi-hal/furi-hal-resources.h diff --git a/firmware/targets/f6/api-hal/api-hal-rfid.c b/firmware/targets/f6/furi-hal/furi-hal-rfid.c similarity index 87% rename from firmware/targets/f6/api-hal/api-hal-rfid.c rename to firmware/targets/f6/furi-hal/furi-hal-rfid.c index be8e3c5f38a..514e5f34435 100644 --- a/firmware/targets/f6/api-hal/api-hal-rfid.c +++ b/firmware/targets/f6/furi-hal/furi-hal-rfid.c @@ -1,15 +1,15 @@ -#include -#include -#include +#include +#include +#include #define LFRFID_READ_TIM htim1 #define LFRFID_READ_CHANNEL TIM_CHANNEL_1 #define LFRFID_EMULATE_TIM htim2 #define LFRFID_EMULATE_CHANNEL TIM_CHANNEL_3 -void api_hal_rfid_pins_reset() { +void furi_hal_rfid_pins_reset() { // ibutton bus disable - api_hal_ibutton_stop(); + furi_hal_ibutton_stop(); // pulldown rfid antenna hal_gpio_init(&gpio_rfid_carrier_out, GpioModeOutputPushPull, GpioSpeedLow, GpioPullNo); @@ -20,24 +20,24 @@ void api_hal_rfid_pins_reset() { hal_gpio_write(&gpio_rfid_pull, true); } -void api_hal_rfid_pins_emulate() { +void furi_hal_rfid_pins_emulate() { // ibutton low - api_hal_ibutton_start(); - api_hal_ibutton_pin_low(); + furi_hal_ibutton_start(); + furi_hal_ibutton_pin_low(); // pull pin to timer out hal_gpio_init_ex( - &gpio_rfid_pull, GpioModeAltFunctionPushPull, GpioSpeedLow, GpioPullNo, GpioAltFn1TIM2); + &gpio_rfid_pull, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); // pull rfid antenna from carrier side hal_gpio_init(&gpio_rfid_carrier_out, GpioModeOutputPushPull, GpioSpeedLow, GpioPullNo); hal_gpio_write(&gpio_rfid_carrier_out, false); } -void api_hal_rfid_pins_read() { +void furi_hal_rfid_pins_read() { // ibutton low - api_hal_ibutton_start(); - api_hal_ibutton_pin_low(); + furi_hal_ibutton_start(); + furi_hal_ibutton_pin_low(); // dont pull rfid antenna hal_gpio_init(&gpio_rfid_pull, GpioModeOutputPushPull, GpioSpeedLow, GpioPullNo); @@ -47,15 +47,15 @@ void api_hal_rfid_pins_read() { hal_gpio_init_ex( &gpio_rfid_carrier_out, GpioModeAltFunctionPushPull, - GpioSpeedLow, GpioPullNo, + GpioSpeedLow, GpioAltFn1TIM1); // comparator in hal_gpio_init(&gpio_rfid_data_in, GpioModeAnalog, GpioSpeedLow, GpioPullNo); } -void api_hal_rfid_tim_read(float freq, float duty_cycle) { +void furi_hal_rfid_tim_read(float freq, float duty_cycle) { // TODO LL init uint32_t period = (uint32_t)((SystemCoreClock) / freq) - 1; @@ -121,15 +121,15 @@ void api_hal_rfid_tim_read(float freq, float duty_cycle) { } } -void api_hal_rfid_tim_read_start() { +void furi_hal_rfid_tim_read_start() { HAL_TIMEx_PWMN_Start(&LFRFID_READ_TIM, LFRFID_READ_CHANNEL); } -void api_hal_rfid_tim_read_stop() { +void furi_hal_rfid_tim_read_stop() { HAL_TIMEx_PWMN_Stop(&LFRFID_READ_TIM, LFRFID_READ_CHANNEL); } -void api_hal_rfid_tim_emulate(float freq) { +void furi_hal_rfid_tim_emulate(float freq) { // TODO LL init uint32_t prescaler = (uint32_t)((SystemCoreClock) / freq) - 1; @@ -196,7 +196,7 @@ void api_hal_rfid_tim_emulate(float freq) { } } -void api_hal_rfid_tim_emulate_start() { +void furi_hal_rfid_tim_emulate_start() { // TODO make api for interrupts priority for(size_t i = WWDG_IRQn; i <= DMAMUX1_OVR_IRQn; i++) { HAL_NVIC_SetPriority(i, 15, 0); @@ -209,25 +209,25 @@ void api_hal_rfid_tim_emulate_start() { HAL_TIM_Base_Start_IT(&LFRFID_EMULATE_TIM); } -void api_hal_rfid_tim_emulate_stop() { +void furi_hal_rfid_tim_emulate_stop() { HAL_TIM_Base_Stop(&LFRFID_EMULATE_TIM); HAL_TIM_PWM_Stop(&LFRFID_EMULATE_TIM, LFRFID_EMULATE_CHANNEL); } -void api_hal_rfid_tim_reset() { +void furi_hal_rfid_tim_reset() { HAL_TIM_Base_DeInit(&LFRFID_READ_TIM); HAL_TIM_Base_DeInit(&LFRFID_EMULATE_TIM); } -bool api_hal_rfid_is_tim_emulate(TIM_HandleTypeDef* hw) { +bool furi_hal_rfid_is_tim_emulate(TIM_HandleTypeDef* hw) { return (hw == &LFRFID_EMULATE_TIM); } -void api_hal_rfid_set_emulate_period(uint32_t period) { +void furi_hal_rfid_set_emulate_period(uint32_t period) { LFRFID_EMULATE_TIM.Instance->ARR = period; } -void api_hal_rfid_set_emulate_pulse(uint32_t pulse) { +void furi_hal_rfid_set_emulate_pulse(uint32_t pulse) { switch(LFRFID_EMULATE_CHANNEL) { case TIM_CHANNEL_1: LFRFID_EMULATE_TIM.Instance->CCR1 = pulse; @@ -247,11 +247,11 @@ void api_hal_rfid_set_emulate_pulse(uint32_t pulse) { } } -void api_hal_rfid_set_read_period(uint32_t period) { +void furi_hal_rfid_set_read_period(uint32_t period) { LFRFID_TIM.Instance->ARR = period; } -void api_hal_rfid_set_read_pulse(uint32_t pulse) { +void furi_hal_rfid_set_read_pulse(uint32_t pulse) { switch(LFRFID_READ_CHANNEL) { case TIM_CHANNEL_1: LFRFID_TIM.Instance->CCR1 = pulse; @@ -271,8 +271,8 @@ void api_hal_rfid_set_read_pulse(uint32_t pulse) { } } -void api_hal_rfid_change_read_config(float freq, float duty_cycle) { +void furi_hal_rfid_change_read_config(float freq, float duty_cycle) { uint32_t period = (uint32_t)((SystemCoreClock) / freq) - 1; - api_hal_rfid_set_read_period(period); - api_hal_rfid_set_read_pulse(period * duty_cycle); + furi_hal_rfid_set_read_period(period); + furi_hal_rfid_set_read_pulse(period * duty_cycle); } \ No newline at end of file diff --git a/firmware/targets/f6/api-hal/api-hal-sd.c b/firmware/targets/f6/furi-hal/furi-hal-sd.c similarity index 96% rename from firmware/targets/f6/api-hal/api-hal-sd.c rename to firmware/targets/f6/furi-hal/furi-hal-sd.c index 14aafd4baa4..01cf9339912 100644 --- a/firmware/targets/f6/api-hal/api-hal-sd.c +++ b/firmware/targets/f6/furi-hal/furi-hal-sd.c @@ -1,4 +1,4 @@ -#include "api-hal-sd.h" +#include "furi-hal-sd.h" #include #include diff --git a/firmware/targets/f6/furi-hal/furi-hal-spi-config.c b/firmware/targets/f6/furi-hal/furi-hal-spi-config.c new file mode 100644 index 00000000000..315d82a235a --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-spi-config.c @@ -0,0 +1,103 @@ +#include +#include + +#define SPI_R SPI1 +#define SPI_D SPI2 + +const LL_SPI_InitTypeDef furi_hal_spi_config_nfc = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_2EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +const LL_SPI_InitTypeDef furi_hal_spi_config_subghz = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_1EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +const LL_SPI_InitTypeDef furi_hal_spi_config_display = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_1EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV16, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +/** + * SD Card in fast mode (after init) + */ +const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_1EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +/** + * SD Card in slow mode (before init) + */ +const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { + .Mode = LL_SPI_MODE_MASTER, + .TransferDirection = LL_SPI_FULL_DUPLEX, + .DataWidth = LL_SPI_DATAWIDTH_8BIT, + .ClockPolarity = LL_SPI_POLARITY_LOW, + .ClockPhase = LL_SPI_PHASE_1EDGE, + .NSS = LL_SPI_NSS_SOFT, + .BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV32, + .BitOrder = LL_SPI_MSB_FIRST, + .CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE, + .CRCPoly = 7, +}; + +osMutexId_t spi_mutex_d = NULL; +osMutexId_t spi_mutex_r = NULL; + +const FuriHalSpiBus spi_r = { + .spi=SPI_R, + .mutex=&spi_mutex_r, + .miso=&gpio_spi_r_miso, + .mosi=&gpio_spi_r_mosi, + .clk=&gpio_spi_r_sck, +}; + +const FuriHalSpiBus spi_d = { + .spi=SPI_D, + .mutex=&spi_mutex_d, + .miso=&gpio_spi_d_miso, + .mosi=&gpio_spi_d_mosi, + .clk=&gpio_spi_d_sck, +}; + +const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax] = { + { .bus=&spi_r, .config=&furi_hal_spi_config_subghz, .chip_select=&gpio_subghz_cs, }, + { .bus=&spi_d, .config=&furi_hal_spi_config_display, .chip_select=&gpio_display_cs, }, + { .bus=&spi_d, .config=&furi_hal_spi_config_sd_fast, .chip_select=&gpio_sdcard_cs, }, + { .bus=&spi_d, .config=&furi_hal_spi_config_sd_slow, .chip_select=&gpio_sdcard_cs, }, + { .bus=&spi_r, .config=&furi_hal_spi_config_nfc, .chip_select=&gpio_nfc_cs }, +}; diff --git a/firmware/targets/f6/furi-hal/furi-hal-spi-config.h b/firmware/targets/f6/furi-hal/furi-hal-spi-config.h new file mode 100644 index 00000000000..3398474af30 --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-spi-config.h @@ -0,0 +1,63 @@ +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern const LL_SPI_InitTypeDef furi_hal_spi_config_nfc; +extern const LL_SPI_InitTypeDef furi_hal_spi_config_subghz; +extern const LL_SPI_InitTypeDef furi_hal_spi_config_display; +extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast; +extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow; + +/** FURI HAL SPI BUS handler + * Structure content may change at some point + */ +typedef struct { + const SPI_TypeDef* spi; + const osMutexId_t* mutex; + const GpioPin* miso; + const GpioPin* mosi; + const GpioPin* clk; +} FuriHalSpiBus; + +/** FURI HAL SPI Device handler + * Structure content may change at some point + */ +typedef struct { + const FuriHalSpiBus* bus; + const LL_SPI_InitTypeDef* config; + const GpioPin* chip_select; +} FuriHalSpiDevice; + +/** FURI HAL SPI Standard Device IDs */ +typedef enum { + FuriHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ + FuriHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ + FuriHalSpiDeviceIdSdCardFast, /** SDCARD: fast mode, after initialization */ + FuriHalSpiDeviceIdSdCardSlow, /** SDCARD: slow mode, before initialization */ + FuriHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ + + FuriHalSpiDeviceIdMax, /** Service Value, do not use */ +} FuriHalSpiDeviceId; + +/** Furi Hal Spi Bus R + * CC1101, Nfc + */ +extern const FuriHalSpiBus spi_r; + +/** Furi Hal Spi Bus D + * Display, SdCard + */ +extern const FuriHalSpiBus spi_d; + +/** Furi Hal Spi devices */ +extern const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax]; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/firmware/targets/f6/furi-hal/furi-hal-spi.c b/firmware/targets/f6/furi-hal/furi-hal-spi.c new file mode 100644 index 00000000000..c925abeed18 --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-spi.c @@ -0,0 +1,200 @@ +#include "furi-hal-spi.h" +#include "furi-hal-resources.h" + +#include +#include +#include + +#include +#include +#include + +void furi_hal_spi_init() { + // Spi structure is const, but mutex is not + // Need some hell-ish casting to make it work + *(osMutexId_t*)spi_r.mutex = osMutexNew(NULL); + *(osMutexId_t*)spi_d.mutex = osMutexNew(NULL); + // + for (size_t i=0; imutex, osWaitForever) == osOK); +} + +void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus) { + furi_assert(bus); + furi_check(osMutexRelease(*bus->mutex) == osOK); +} + +void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config) { + furi_assert(bus); + + LL_SPI_DeInit((SPI_TypeDef*)bus->spi); + LL_SPI_Init((SPI_TypeDef*)bus->spi, (LL_SPI_InitTypeDef*)config); + LL_SPI_SetRxFIFOThreshold((SPI_TypeDef*)bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable((SPI_TypeDef*)bus->spi); +} + +void furi_hal_spi_bus_end_txrx(const FuriHalSpiBus* bus, uint32_t timeout) { + while(LL_SPI_GetTxFIFOLevel((SPI_TypeDef *)bus->spi) != LL_SPI_TX_FIFO_EMPTY); + while(LL_SPI_IsActiveFlag_BSY((SPI_TypeDef *)bus->spi)); + while(LL_SPI_GetRxFIFOLevel((SPI_TypeDef *)bus->spi) != LL_SPI_RX_FIFO_EMPTY) { + LL_SPI_ReceiveData8((SPI_TypeDef *)bus->spi); + } +} + +bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(bus); + furi_assert(buffer); + furi_assert(size > 0); + + return furi_hal_spi_bus_trx(bus, buffer, buffer, size, timeout); +} + +bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(bus); + furi_assert(buffer); + furi_assert(size > 0); + bool ret = true; + + while(size > 0) { + if (LL_SPI_IsActiveFlag_TXE((SPI_TypeDef *)bus->spi)) { + LL_SPI_TransmitData8((SPI_TypeDef *)bus->spi, *buffer); + buffer++; + size--; + } + } + + furi_hal_spi_bus_end_txrx(bus, timeout); + LL_SPI_ClearFlag_OVR((SPI_TypeDef *)bus->spi); + + return ret; +} + +bool furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { + furi_assert(bus); + furi_assert(tx_buffer); + furi_assert(rx_buffer); + furi_assert(size > 0); + + bool ret = true; + size_t tx_size = size; + bool tx_allowed = true; + + while(size > 0) { + if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE((SPI_TypeDef *)bus->spi) && tx_allowed) { + LL_SPI_TransmitData8((SPI_TypeDef *)bus->spi, *tx_buffer); + tx_buffer++; + tx_size--; + tx_allowed = false; + } + + if(LL_SPI_IsActiveFlag_RXNE((SPI_TypeDef *)bus->spi)) { + *rx_buffer = LL_SPI_ReceiveData8((SPI_TypeDef *)bus->spi); + rx_buffer++; + size--; + tx_allowed = true; + } + } + + furi_hal_spi_bus_end_txrx(bus, timeout); + + return ret; +} + +void furi_hal_spi_device_configure(const FuriHalSpiDevice* device) { + furi_assert(device); + furi_assert(device->config); + + furi_hal_spi_bus_configure(device->bus, device->config); +} + +const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id) { + furi_assert(device_id < FuriHalSpiDeviceIdMax); + + const FuriHalSpiDevice* device = &furi_hal_spi_devices[device_id]; + assert(device); + furi_hal_spi_bus_lock(device->bus); + furi_hal_spi_device_configure(device); + + return device; +} + +void furi_hal_spi_device_return(const FuriHalSpiDevice* device) { + furi_hal_spi_bus_unlock(device->bus); +} + +bool furi_hal_spi_device_rx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(device); + furi_assert(buffer); + furi_assert(size > 0); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, false); + } + + bool ret = furi_hal_spi_bus_rx(device->bus, buffer, size, timeout); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; +} + +bool furi_hal_spi_device_tx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(device); + furi_assert(buffer); + furi_assert(size > 0); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, false); + } + + bool ret = furi_hal_spi_bus_tx(device->bus, buffer, size, timeout); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; +} + +bool furi_hal_spi_device_trx(const FuriHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { + furi_assert(device); + furi_assert(tx_buffer); + furi_assert(rx_buffer); + furi_assert(size > 0); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, false); + } + + bool ret = furi_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, timeout); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; +} diff --git a/firmware/targets/f6/furi-hal/furi-hal-spi.h b/firmware/targets/f6/furi-hal/furi-hal-spi.h new file mode 100644 index 00000000000..638e713a5f7 --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-spi.h @@ -0,0 +1,108 @@ +#pragma once +#include "main.h" +#include "furi-hal-spi-config.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Init SPI API + */ +void furi_hal_spi_init(); + +/* Bus Level API */ + +/** Lock SPI bus + * Takes bus mutex, if used + */ +void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus); + +/** Unlock SPI bus + * Releases BUS mutex, if used + */ +void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus); + +/** + * Configure SPI bus + * @param bus - spi bus handler + * @param config - spi configuration structure + */ +void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config); + +/** SPI Receive + * @param bus - spi bus handler + * @param buffer - receive buffer + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); + +/** SPI Transmit + * @param bus - spi bus handler + * @param buffer - transmit buffer + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); + +/** SPI Transmit and Receive + * @param bus - spi bus handlere + * @param tx_buffer - device handle + * @param rx_buffer - device handle + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); + +/* Device Level API */ + +/** Reconfigure SPI bus for device + * @param device - device description + */ +void furi_hal_spi_device_configure(const FuriHalSpiDevice* device); + +/** Get Device handle + * And lock access to the corresponding SPI BUS + * @param device_id - device identifier + * @return device handle + */ +const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id); + +/** Return Device handle + * And unlock access to the corresponding SPI BUS + * @param device - device handle + */ +void furi_hal_spi_device_return(const FuriHalSpiDevice* device); + +/** SPI Recieve + * @param device - device handle + * @param buffer - receive buffer + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool furi_hal_spi_device_rx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout); + +/** SPI Transmit + * @param device - device handle + * @param buffer - transmit buffer + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool furi_hal_spi_device_tx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout); + +/** SPI Transmit and Receive + * @param device - device handle + * @param tx_buffer - device handle + * @param rx_buffer - device handle + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool furi_hal_spi_device_trx(const FuriHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); + + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/firmware/targets/f6/api-hal/api-hal-subghz.c b/firmware/targets/f6/furi-hal/furi-hal-subghz.c similarity index 53% rename from firmware/targets/f6/api-hal/api-hal-subghz.c rename to firmware/targets/f6/furi-hal/furi-hal-subghz.c index d941a406441..62cd2668a57 100644 --- a/firmware/targets/f6/api-hal/api-hal-subghz.c +++ b/firmware/targets/f6/furi-hal/furi-hal-subghz.c @@ -1,17 +1,17 @@ -#include "api-hal-subghz.h" +#include "furi-hal-subghz.h" -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include -static volatile SubGhzState api_hal_subghz_state = SubGhzStateInit; +static volatile SubGhzState furi_hal_subghz_state = SubGhzStateInit; -static const uint8_t api_hal_subghz_preset_ook_async_regs[][2] = { +static const uint8_t furi_hal_subghz_preset_ook_async_regs[][2] = { // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/382066/cc1101---don-t-know-the-correct-registers-configuration /* GPIO GD0 */ @@ -40,8 +40,9 @@ static const uint8_t api_hal_subghz_preset_ook_async_regs[][2] = { { CC1101_FOCCFG, 0x18 }, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off /* Automatic Gain Control */ - { CC1101_AGCTRL1, 0x00 }, // LNA 2 gain is decreased to minimum before decreasing LNA gain - { CC1101_AGCTRL2, 0x07 }, // MAGN_TARGET is 42 dB + { CC1101_AGCTRL0, 0x40 }, // 01 - Low hysteresis, small asymmetric dead zone, medium gain; 00 - 8 samples agc; 00 - Normal AGC, 00 - 4dB boundary + { CC1101_AGCTRL1, 0x00 }, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + { CC1101_AGCTRL2, 0x03 }, // 00 - DVGA all; 000 - MAX LNA+LNA2; 011 - MAIN_TARGET 24 dB /* Wake on radio and timeouts control */ { CC1101_WORCTRL, 0xFB }, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours @@ -65,7 +66,7 @@ static const uint8_t api_hal_subghz_preset_ook_async_regs[][2] = { { 0, 0 }, }; -static const uint8_t api_hal_subghz_preset_ook_async_patable[8] = { +static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = { 0x00, 0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12 0x00, @@ -76,14 +77,14 @@ static const uint8_t api_hal_subghz_preset_ook_async_patable[8] = { 0x00 }; -void api_hal_subghz_init() { - furi_assert(api_hal_subghz_state == SubGhzStateInit); - api_hal_subghz_state = SubGhzStateIdle; +void furi_hal_subghz_init() { + furi_assert(furi_hal_subghz_state == SubGhzStateInit); + furi_hal_subghz_state = SubGhzStateIdle; - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); -#ifdef API_HAL_SUBGHZ_TX_GPIO - hal_gpio_init(&API_HAL_SUBGHZ_TX_GPIO, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); +#ifdef FURI_HAL_SUBGHZ_TX_GPIO + hal_gpio_init(&FURI_HAL_SUBGHZ_TX_GPIO, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); #endif // Reset @@ -113,13 +114,13 @@ void api_hal_subghz_init() { // Go to sleep cc1101_shutdown(device); - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); FURI_LOG_I("FuriHalSubGhz", "Init OK"); } -void api_hal_subghz_sleep() { - furi_assert(api_hal_subghz_state == SubGhzStateIdle); - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); +void furi_hal_subghz_sleep() { + furi_assert(furi_hal_subghz_state == SubGhzStateIdle); + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); cc1101_switch_to_idle(device); @@ -128,110 +129,110 @@ void api_hal_subghz_sleep() { cc1101_shutdown(device); - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); } -void api_hal_subghz_dump_state() { - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); +void furi_hal_subghz_dump_state() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); printf( - "[api_hal_subghz] cc1101 chip %d, version %d\r\n", + "[furi_hal_subghz] cc1101 chip %d, version %d\r\n", cc1101_get_partnumber(device), cc1101_get_version(device) ); - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); } -void api_hal_subghz_load_preset(ApiHalSubGhzPreset preset) { - if(preset == ApiHalSubGhzPresetOokAsync) { - api_hal_subghz_load_registers(api_hal_subghz_preset_ook_async_regs); - api_hal_subghz_load_patable(api_hal_subghz_preset_ook_async_patable); +void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { + if(preset == FuriHalSubGhzPresetOokAsync) { + furi_hal_subghz_load_registers(furi_hal_subghz_preset_ook_async_regs); + furi_hal_subghz_load_patable(furi_hal_subghz_preset_ook_async_patable); } else { furi_check(0); } } -uint8_t api_hal_subghz_get_status() { - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); +uint8_t furi_hal_subghz_get_status() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); CC1101StatusRaw st; st.status = cc1101_get_status(device); - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); return st.status_raw; } -void api_hal_subghz_load_registers(const uint8_t data[][2]) { - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); +void furi_hal_subghz_load_registers(const uint8_t data[][2]) { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); cc1101_reset(device); uint32_t i = 0; while (data[i][0]) { cc1101_write_reg(device, data[i][0], data[i][1]); i++; } - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); } -void api_hal_subghz_load_patable(const uint8_t data[8]) { - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); +void furi_hal_subghz_load_patable(const uint8_t data[8]) { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); cc1101_set_pa_table(device, data); - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); } -void api_hal_subghz_write_packet(const uint8_t* data, uint8_t size) { - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); +void furi_hal_subghz_write_packet(const uint8_t* data, uint8_t size) { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); cc1101_flush_tx(device); cc1101_write_fifo(device, data, size); - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); } -void api_hal_subghz_flush_rx() { - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); +void furi_hal_subghz_flush_rx() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); cc1101_flush_rx(device); - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); } -void api_hal_subghz_read_packet(uint8_t* data, uint8_t* size) { - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); +void furi_hal_subghz_read_packet(uint8_t* data, uint8_t* size) { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); cc1101_read_fifo(device, data, size); - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); } -void api_hal_subghz_shutdown() { - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); +void furi_hal_subghz_shutdown() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); // Reset and shutdown cc1101_shutdown(device); - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); } -void api_hal_subghz_reset() { - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); +void furi_hal_subghz_reset() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); cc1101_switch_to_idle(device); cc1101_reset(device); cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); } -void api_hal_subghz_idle() { - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); +void furi_hal_subghz_idle() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); cc1101_switch_to_idle(device); - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); } -void api_hal_subghz_rx() { - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); +void furi_hal_subghz_rx() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); cc1101_switch_to_rx(device); - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); } -void api_hal_subghz_tx() { - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); +void furi_hal_subghz_tx() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); cc1101_switch_to_tx(device); - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); } -float api_hal_subghz_get_rssi() { - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); +float furi_hal_subghz_get_rssi() { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); int32_t rssi_dec = cc1101_get_rssi(device); - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); float rssi = rssi_dec; if(rssi_dec >= 128) { @@ -243,7 +244,7 @@ float api_hal_subghz_get_rssi() { return rssi; } -bool api_hal_subghz_is_frequency_valid(uint32_t value) { +bool furi_hal_subghz_is_frequency_valid(uint32_t value) { if(!(value >= 299999755 && value <= 348000335) && !(value >= 386999938 && value <= 464000000) && !(value >= 778999847 && value <= 928000000)) { @@ -252,85 +253,84 @@ bool api_hal_subghz_is_frequency_valid(uint32_t value) { return true; } -uint32_t api_hal_subghz_set_frequency_and_path(uint32_t value) { - value = api_hal_subghz_set_frequency(value); +uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value) { + value = furi_hal_subghz_set_frequency(value); if(value >= 299999755 && value <= 348000335) { - api_hal_subghz_set_path(ApiHalSubGhzPath315); + furi_hal_subghz_set_path(FuriHalSubGhzPath315); } else if(value >= 386999938 && value <= 464000000) { - api_hal_subghz_set_path(ApiHalSubGhzPath433); + furi_hal_subghz_set_path(FuriHalSubGhzPath433); } else if(value >= 778999847 && value <= 928000000) { - api_hal_subghz_set_path(ApiHalSubGhzPath868); + furi_hal_subghz_set_path(FuriHalSubGhzPath868); } else { furi_check(0); } return value; } -uint32_t api_hal_subghz_set_frequency(uint32_t value) { - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); +uint32_t furi_hal_subghz_set_frequency(uint32_t value) { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); uint32_t real_frequency = cc1101_set_frequency(device, value); cc1101_calibrate(device); - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); return real_frequency; } -void api_hal_subghz_set_path(ApiHalSubGhzPath path) { - const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); - if (path == ApiHalSubGhzPath433) { +void furi_hal_subghz_set_path(FuriHalSubGhzPath path) { + const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + if (path == FuriHalSubGhzPath433) { hal_gpio_write(&gpio_rf_sw_0, 0); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); - } else if (path == ApiHalSubGhzPath315) { + } else if (path == FuriHalSubGhzPath315) { hal_gpio_write(&gpio_rf_sw_0, 1); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); - } else if (path == ApiHalSubGhzPath868) { + } else if (path == FuriHalSubGhzPath868) { hal_gpio_write(&gpio_rf_sw_0, 1); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); - } else if (path == ApiHalSubGhzPathIsolate) { + } else if (path == FuriHalSubGhzPathIsolate) { hal_gpio_write(&gpio_rf_sw_0, 0); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); } else { furi_check(0); } - api_hal_spi_device_return(device); + furi_hal_spi_device_return(device); } -volatile uint32_t api_hal_subghz_capture_delta_duration = 0; -volatile ApiHalSubGhzCaptureCallback api_hal_subghz_capture_callback = NULL; -volatile void* api_hal_subghz_capture_callback_context = NULL; +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 api_hal_subghz_capture_ISR() { +static void furi_hal_subghz_capture_ISR() { // Channel 1 if(LL_TIM_IsActiveFlag_CC1(TIM2)) { LL_TIM_ClearFlag_CC1(TIM2); - api_hal_subghz_capture_delta_duration = LL_TIM_IC_GetCaptureCH1(TIM2); - if (api_hal_subghz_capture_callback) { - api_hal_subghz_capture_callback(true, api_hal_subghz_capture_delta_duration, - (void*)api_hal_subghz_capture_callback_context + furi_hal_subghz_capture_delta_duration = LL_TIM_IC_GetCaptureCH1(TIM2); + if (furi_hal_subghz_capture_callback) { + 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 (api_hal_subghz_capture_callback) { - api_hal_subghz_capture_callback(false, LL_TIM_IC_GetCaptureCH2(TIM2) - api_hal_subghz_capture_delta_duration, - (void*)api_hal_subghz_capture_callback_context + if (furi_hal_subghz_capture_callback) { + furi_hal_subghz_capture_callback(false, LL_TIM_IC_GetCaptureCH2(TIM2) - furi_hal_subghz_capture_delta_duration, + (void*)furi_hal_subghz_capture_callback_context ); } } } -void api_hal_subghz_set_async_rx_callback(ApiHalSubGhzCaptureCallback callback, void* context) { - api_hal_subghz_capture_callback = callback; - api_hal_subghz_capture_callback_context = context; -} -void api_hal_subghz_start_async_rx() { - furi_assert(api_hal_subghz_state == SubGhzStateIdle); - api_hal_subghz_state = SubGhzStateAsyncRx; +void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* context) { + furi_assert(furi_hal_subghz_state == SubGhzStateIdle); + furi_hal_subghz_state = SubGhzStateAsyncRx; + + furi_hal_subghz_capture_callback = callback; + furi_hal_subghz_capture_callback_context = context; hal_gpio_init_ex(&gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); @@ -366,7 +366,7 @@ void api_hal_subghz_start_async_rx() { LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1); // ISR setup - api_hal_interrupt_set_timer_isr(TIM2, api_hal_subghz_capture_ISR); + furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_capture_ISR); NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); NVIC_EnableIRQ(TIM2_IRQn); @@ -385,50 +385,90 @@ void api_hal_subghz_start_async_rx() { LL_TIM_EnableCounter(TIM2); // Switch to RX - api_hal_subghz_rx(); + furi_hal_subghz_rx(); } -void api_hal_subghz_stop_async_rx() { - furi_assert(api_hal_subghz_state == SubGhzStateAsyncRx); - api_hal_subghz_state = SubGhzStateIdle; +void furi_hal_subghz_stop_async_rx() { + furi_assert(furi_hal_subghz_state == SubGhzStateAsyncRx); + furi_hal_subghz_state = SubGhzStateIdle; // Shutdown radio - api_hal_subghz_idle(); + furi_hal_subghz_idle(); LL_TIM_DeInit(TIM2); LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2); - api_hal_interrupt_set_timer_isr(TIM2, NULL); + furi_hal_interrupt_set_timer_isr(TIM2, NULL); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } -volatile size_t api_hal_subghz_tx_repeat = 0; +#define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL (256) +#define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF (API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL/2) + +typedef struct { + uint32_t* buffer; + bool flip_flop; + FuriHalSubGhzAsyncTxCallback callback; + void* callback_context; +} FuriHalSubGhzAsyncTx; + +static FuriHalSubGhzAsyncTx furi_hal_subghz_async_tx = {0}; + +static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) { + while (samples > 0) { + LevelDuration ld = furi_hal_subghz_async_tx.callback(furi_hal_subghz_async_tx.callback_context); + if (level_duration_is_reset(ld)) { + break; + } else { + uint32_t duration = level_duration_get_duration(ld); + assert(duration > 0); + *buffer = duration; + } + buffer++; + samples--; + } -static void api_hal_subghz_tx_dma_isr() { + memset(buffer, 0, samples * sizeof(uint32_t)); +} + +static void furi_hal_subghz_async_tx_dma_isr() { + furi_assert(furi_hal_subghz_state == SubGhzStateAsyncTx); + if (LL_DMA_IsActiveFlag_HT1(DMA1)) { + LL_DMA_ClearFlag_HT1(DMA1); + furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); + } if (LL_DMA_IsActiveFlag_TC1(DMA1)) { LL_DMA_ClearFlag_TC1(DMA1); - furi_assert(api_hal_subghz_state == SubGhzStateAsyncTx); - if (--api_hal_subghz_tx_repeat == 0) { - api_hal_subghz_state = SubGhzStateAsyncTxLast; - LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1); - } + furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer+API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF); } } -static void api_hal_subghz_tx_timer_isr() { +static void furi_hal_subghz_async_tx_timer_isr() { if(LL_TIM_IsActiveFlag_UPDATE(TIM2)) { LL_TIM_ClearFlag_UPDATE(TIM2); - if (api_hal_subghz_state == SubGhzStateAsyncTxLast) { - LL_TIM_DisableCounter(TIM2); - api_hal_subghz_state = SubGhzStateAsyncTxEnd; + if (LL_TIM_GetAutoReload(TIM2) == 0) { + if (furi_hal_subghz_state == SubGhzStateAsyncTx) { + furi_hal_subghz_state = SubGhzStateAsyncTxLast; + } else { + furi_hal_subghz_state = SubGhzStateAsyncTxEnd; + LL_TIM_DisableCounter(TIM2); + hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullDown, GpioSpeedLow); + } } } } -void api_hal_subghz_start_async_tx(uint32_t* buffer, size_t buffer_size, size_t repeat) { - furi_assert(api_hal_subghz_state == SubGhzStateIdle); - api_hal_subghz_state = SubGhzStateAsyncTx; - api_hal_subghz_tx_repeat = repeat; +void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* context) { + furi_assert(furi_hal_subghz_state == SubGhzStateIdle); + furi_assert(callback); + + furi_hal_subghz_async_tx.callback = callback; + furi_hal_subghz_async_tx.callback_context = context; + + furi_hal_subghz_state = SubGhzStateAsyncTx; + + furi_hal_subghz_async_tx.buffer = furi_alloc(API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t)); + furi_hal_subghz_async_tx_refill(furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL); // Connect CC1101_GD0 to TIM2 as output hal_gpio_init_ex(&gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn1TIM2); @@ -436,19 +476,20 @@ void api_hal_subghz_start_async_tx(uint32_t* buffer, size_t buffer_size, size_t // Configure DMA LL_DMA_InitTypeDef dma_config = {0}; dma_config.PeriphOrM2MSrcAddress = (uint32_t)&(TIM2->ARR); - dma_config.MemoryOrM2MDstAddress = (uint32_t)buffer; + dma_config.MemoryOrM2MDstAddress = (uint32_t)furi_hal_subghz_async_tx.buffer; dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; dma_config.Mode = LL_DMA_MODE_CIRCULAR; dma_config.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; dma_config.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; dma_config.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; dma_config.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; - dma_config.NbData = buffer_size / sizeof(uint32_t); + dma_config.NbData = API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL; dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP; dma_config.Priority = LL_DMA_MODE_NORMAL; LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config); - api_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, api_hal_subghz_tx_dma_isr); + furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, furi_hal_subghz_async_tx_dma_isr); LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1); + LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_1); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); // Configure TIM2 @@ -473,17 +514,17 @@ void api_hal_subghz_start_async_tx(uint32_t* buffer, size_t buffer_size, size_t LL_TIM_OC_DisableFast(TIM2, LL_TIM_CHANNEL_CH2); LL_TIM_DisableMasterSlaveMode(TIM2); - api_hal_interrupt_set_timer_isr(TIM2, api_hal_subghz_tx_timer_isr); + furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_async_tx_timer_isr); LL_TIM_EnableIT_UPDATE(TIM2); LL_TIM_EnableDMAReq_UPDATE(TIM2); LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2); // Start counter LL_TIM_GenerateEvent_UPDATE(TIM2); -#ifdef API_HAL_SUBGHZ_TX_GPIO - hal_gpio_write(&API_HAL_SUBGHZ_TX_GPIO, true); +#ifdef FURI_HAL_SUBGHZ_TX_GPIO + hal_gpio_write(&FURI_HAL_SUBGHZ_TX_GPIO, true); #endif - api_hal_subghz_tx(); + furi_hal_subghz_tx(); // Enable NVIC NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); @@ -493,38 +534,36 @@ void api_hal_subghz_start_async_tx(uint32_t* buffer, size_t buffer_size, size_t LL_TIM_EnableCounter(TIM2); } -size_t api_hal_subghz_get_async_tx_repeat_left() { - return api_hal_subghz_tx_repeat; +bool furi_hal_subghz_is_async_tx_complete() { + return furi_hal_subghz_state == SubGhzStateAsyncTxEnd; } -void api_hal_subghz_wait_async_tx() { - while(api_hal_subghz_state != SubGhzStateAsyncTxEnd) osDelay(1); -} - -void api_hal_subghz_stop_async_tx() { +void furi_hal_subghz_stop_async_tx() { furi_assert( - api_hal_subghz_state == SubGhzStateAsyncTx - || api_hal_subghz_state == SubGhzStateAsyncTxLast - || api_hal_subghz_state == SubGhzStateAsyncTxEnd + furi_hal_subghz_state == SubGhzStateAsyncTx + || furi_hal_subghz_state == SubGhzStateAsyncTxLast + || furi_hal_subghz_state == SubGhzStateAsyncTxEnd ); // Shutdown radio - api_hal_subghz_idle(); -#ifdef API_HAL_SUBGHZ_TX_GPIO - hal_gpio_write(&API_HAL_SUBGHZ_TX_GPIO, false); + furi_hal_subghz_idle(); +#ifdef FURI_HAL_SUBGHZ_TX_GPIO + hal_gpio_write(&FURI_HAL_SUBGHZ_TX_GPIO, false); #endif // Deinitialize Timer LL_TIM_DeInit(TIM2); LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2); - api_hal_interrupt_set_timer_isr(TIM2, NULL); + furi_hal_interrupt_set_timer_isr(TIM2, NULL); // Deinitialize DMA LL_DMA_DeInit(DMA1, LL_DMA_CHANNEL_1); - api_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, NULL); + furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, NULL); // Deinitialize GPIO hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - api_hal_subghz_state = SubGhzStateIdle; + free(furi_hal_subghz_async_tx.buffer); + + furi_hal_subghz_state = SubGhzStateIdle; } diff --git a/firmware/targets/f6/api-hal/api-hal-task.c b/firmware/targets/f6/furi-hal/furi-hal-task.c similarity index 98% rename from firmware/targets/f6/api-hal/api-hal-task.c rename to firmware/targets/f6/furi-hal/furi-hal-task.c index 48df9fa7dd6..aca197a41eb 100644 --- a/firmware/targets/f6/api-hal/api-hal-task.c +++ b/firmware/targets/f6/furi-hal/furi-hal-task.c @@ -1,5 +1,5 @@ #include "cmsis_os.h" -#include "api-hal-task.h" +#include "furi-hal-task.h" //-----------------------------cmsis_os2.c------------------------------- // helpers to get isr context diff --git a/firmware/targets/f6/api-hal/api-hal-task.h b/firmware/targets/f6/furi-hal/furi-hal-task.h similarity index 100% rename from firmware/targets/f6/api-hal/api-hal-task.h rename to firmware/targets/f6/furi-hal/furi-hal-task.h diff --git a/firmware/targets/f6/furi-hal/furi-hal-vcp.c b/firmware/targets/f6/furi-hal/furi-hal-vcp.c new file mode 100644 index 00000000000..9079a5c8a2b --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-vcp.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include + +#define FURI_HAL_VCP_RX_BUFFER_SIZE 600 + +typedef struct { + StreamBufferHandle_t rx_stream; + osSemaphoreId_t tx_semaphore; + volatile bool alive; + volatile bool underrun; +} FuriHalVcp; + +static FuriHalVcp* furi_hal_vcp = NULL; + +static const uint8_t ascii_soh = 0x01; +static const uint8_t ascii_eot = 0x04; + +void _furi_hal_vcp_init(); +void _furi_hal_vcp_deinit(); +void _furi_hal_vcp_control_line(uint8_t state); +void _furi_hal_vcp_rx_callback(const uint8_t* buffer, size_t size); +void _furi_hal_vcp_tx_complete(size_t size); + +void furi_hal_vcp_init() { + furi_hal_vcp = furi_alloc(sizeof(FuriHalVcp)); + furi_hal_vcp->rx_stream = xStreamBufferCreate(FURI_HAL_VCP_RX_BUFFER_SIZE, 1); + furi_hal_vcp->tx_semaphore = osSemaphoreNew(1, 1, NULL); + furi_hal_vcp->alive = false; + furi_hal_vcp->underrun = false; + FURI_LOG_I("FuriHalVcp", "Init OK"); +} + +void _furi_hal_vcp_init() { + osSemaphoreRelease(furi_hal_vcp->tx_semaphore); +} + +void _furi_hal_vcp_deinit() { + furi_hal_vcp->alive = false; + osSemaphoreRelease(furi_hal_vcp->tx_semaphore); +} + +void _furi_hal_vcp_control_line(uint8_t state) { + // bit 0: DTR state, bit 1: RTS state + // bool dtr = state & 0b01; + bool dtr = state & 0b1; + + if (dtr) { + if (!furi_hal_vcp->alive) { + furi_hal_vcp->alive = true; + _furi_hal_vcp_rx_callback(&ascii_soh, 1); // SOH + } + } else { + if (furi_hal_vcp->alive) { + _furi_hal_vcp_rx_callback(&ascii_eot, 1); // EOT + furi_hal_vcp->alive = false; + } + } + + osSemaphoreRelease(furi_hal_vcp->tx_semaphore); +} + +void _furi_hal_vcp_rx_callback(const uint8_t* buffer, size_t size) { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + size_t ret = xStreamBufferSendFromISR(furi_hal_vcp->rx_stream, buffer, size, &xHigherPriorityTaskWoken); + if (ret != size) { + furi_hal_vcp->underrun = true; + } + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +} + +void _furi_hal_vcp_tx_complete(size_t size) { + osSemaphoreRelease(furi_hal_vcp->tx_semaphore); +} + +size_t furi_hal_vcp_rx(uint8_t* buffer, size_t size) { + furi_assert(furi_hal_vcp); + return xStreamBufferReceive(furi_hal_vcp->rx_stream, buffer, size, portMAX_DELAY); +} + +size_t furi_hal_vcp_rx_with_timeout(uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(furi_hal_vcp); + return xStreamBufferReceive(furi_hal_vcp->rx_stream, buffer, size, timeout); +} + +void furi_hal_vcp_tx(const uint8_t* buffer, size_t size) { + furi_assert(furi_hal_vcp); + + while (size > 0 && furi_hal_vcp->alive) { + furi_check(osSemaphoreAcquire(furi_hal_vcp->tx_semaphore, osWaitForever) == osOK); + + size_t batch_size = size; + if (batch_size > APP_TX_DATA_SIZE) { + batch_size = APP_TX_DATA_SIZE; + } + + if (CDC_Transmit_FS((uint8_t*)buffer, batch_size) == USBD_OK) { + size -= batch_size; + buffer += batch_size; + } else { + // Shouldn't be there + osDelay(100); + } + } +} diff --git a/firmware/targets/f6/furi-hal/furi-hal-version.c b/firmware/targets/f6/furi-hal/furi-hal-version.c new file mode 100644 index 00000000000..a58a9d1c50b --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-version.c @@ -0,0 +1,242 @@ +#include + +#include +#include +#include + +#include +#include "ble.h" + +#define FURI_HAL_VERSION_OTP_HEADER_MAGIC 0xBABE +#define FURI_HAL_VERSION_NAME_LENGTH 8 +#define FURI_HAL_VERSION_ARRAY_NAME_LENGTH (FURI_HAL_VERSION_NAME_LENGTH + 1) +/** BLE symbol + "Flipper " + name */ +#define FURI_HAL_VERSION_DEVICE_NAME_LENGTH (1 + 8 + FURI_HAL_VERSION_ARRAY_NAME_LENGTH) +#define FURI_HAL_VERSION_OTP_ADDRESS OTP_AREA_BASE + +/** OTP Versions enum */ +typedef enum { + FuriHalVersionOtpVersion0=0x00, + FuriHalVersionOtpVersion1=0x01, + FuriHalVersionOtpVersionEmpty=0xFFFFFFFE, + FuriHalVersionOtpVersionUnknown=0xFFFFFFFF, +} FuriHalVersionOtpVersion; + +/** OTP V0 Structure: prototypes and early EVT */ +typedef struct { + uint8_t board_version; + uint8_t board_target; + uint8_t board_body; + uint8_t board_connect; + uint32_t header_timestamp; + char name[FURI_HAL_VERSION_NAME_LENGTH]; +} FuriHalVersionOTPv0; + +/** OTP V1 Structure: late EVT, DVT, PVT, Production */ +typedef struct { + /* First 64 bits: header */ + uint16_t header_magic; + uint8_t header_version; + uint8_t header_reserved; + uint32_t header_timestamp; + + /* Second 64 bits: board info */ + uint8_t board_version; /** Board version */ + uint8_t board_target; /** Board target firmware */ + uint8_t board_body; /** Board body */ + uint8_t board_connect; /** Board interconnect */ + uint8_t board_color; /** Board color */ + uint8_t board_region; /** Board region */ + uint16_t board_reserved; /** Reserved for future use, 0x0000 */ + + /* Third 64 bits: Unique Device Name */ + char name[FURI_HAL_VERSION_NAME_LENGTH]; /** Unique Device Name */ +} FuriHalVersionOTPv1; + +/** Represenation Model: */ +typedef struct { + FuriHalVersionOtpVersion otp_version; + + uint32_t timestamp; + + uint8_t board_version; /** Board version */ + uint8_t board_target; /** Board target firmware */ + uint8_t board_body; /** Board body */ + uint8_t board_connect; /** Board interconnect */ + uint8_t board_color; /** Board color */ + uint8_t board_region; /** Board region */ + + char name[FURI_HAL_VERSION_ARRAY_NAME_LENGTH]; /** \0 terminated name */ + char device_name[FURI_HAL_VERSION_DEVICE_NAME_LENGTH]; /** device name for special needs */ + uint8_t ble_mac[6]; +} FuriHalVersion; + +static FuriHalVersion furi_hal_version = {0}; + +static FuriHalVersionOtpVersion furi_hal_version_get_otp_version() { + if (*(uint64_t*)FURI_HAL_VERSION_OTP_ADDRESS == 0xFFFFFFFF) { + return FuriHalVersionOtpVersionEmpty; + } else { + if (((FuriHalVersionOTPv1*)FURI_HAL_VERSION_OTP_ADDRESS)->header_magic == FURI_HAL_VERSION_OTP_HEADER_MAGIC) { + return FuriHalVersionOtpVersion1; + } else if (((FuriHalVersionOTPv0*)FURI_HAL_VERSION_OTP_ADDRESS)->board_version <= 10) { + return FuriHalVersionOtpVersion0; + } else { + return FuriHalVersionOtpVersionUnknown; + } + } +} + +static void furi_hal_version_set_name(const char* name) { + if(name != NULL) { + strlcpy(furi_hal_version.name, name, FURI_HAL_VERSION_ARRAY_NAME_LENGTH); + snprintf( + furi_hal_version.device_name, + FURI_HAL_VERSION_DEVICE_NAME_LENGTH, + "xFlipper %s", + furi_hal_version.name); + } else { + snprintf( + furi_hal_version.device_name, + FURI_HAL_VERSION_DEVICE_NAME_LENGTH, + "xFlipper"); + } + + furi_hal_version.device_name[0] = AD_TYPE_COMPLETE_LOCAL_NAME; + + // BLE Mac address + uint32_t udn = LL_FLASH_GetUDN(); + uint32_t company_id = LL_FLASH_GetSTCompanyID(); + uint32_t device_id = LL_FLASH_GetDeviceID(); + furi_hal_version.ble_mac[0] = (uint8_t)(udn & 0x000000FF); + furi_hal_version.ble_mac[1] = (uint8_t)( (udn & 0x0000FF00) >> 8 ); + furi_hal_version.ble_mac[2] = (uint8_t)( (udn & 0x00FF0000) >> 16 ); + furi_hal_version.ble_mac[3] = (uint8_t)device_id; + furi_hal_version.ble_mac[4] = (uint8_t)(company_id & 0x000000FF); + furi_hal_version.ble_mac[5] = (uint8_t)( (company_id & 0x0000FF00) >> 8 ); +} + +static void furi_hal_version_load_otp_default() { + furi_hal_version_set_name(NULL); +} + +static void furi_hal_version_load_otp_v0() { + const FuriHalVersionOTPv0* otp = (FuriHalVersionOTPv0*)FURI_HAL_VERSION_OTP_ADDRESS; + + furi_hal_version.timestamp = otp->header_timestamp; + furi_hal_version.board_version = otp->board_version; + furi_hal_version.board_target = otp->board_target; + furi_hal_version.board_body = otp->board_body; + furi_hal_version.board_connect = otp->board_connect; + furi_hal_version.board_color = 0; + furi_hal_version.board_region = 0; + + furi_hal_version_set_name(otp->name); +} + +static void furi_hal_version_load_otp_v1() { + const FuriHalVersionOTPv1* otp = (FuriHalVersionOTPv1*)FURI_HAL_VERSION_OTP_ADDRESS; + + furi_hal_version.timestamp = otp->header_timestamp; + furi_hal_version.board_version = otp->board_version; + furi_hal_version.board_target = otp->board_target; + furi_hal_version.board_body = otp->board_body; + furi_hal_version.board_connect = otp->board_connect; + furi_hal_version.board_color = otp->board_color; + furi_hal_version.board_region = otp->board_region; + + furi_hal_version_set_name(otp->name); +} + +void furi_hal_version_init() { + furi_hal_version.otp_version = furi_hal_version_get_otp_version(); + switch(furi_hal_version.otp_version) { + case FuriHalVersionOtpVersionUnknown: + furi_hal_version_load_otp_default(); + break; + case FuriHalVersionOtpVersionEmpty: + furi_hal_version_load_otp_default(); + break; + case FuriHalVersionOtpVersion0: + furi_hal_version_load_otp_v0(); + break; + case FuriHalVersionOtpVersion1: + furi_hal_version_load_otp_v1(); + break; + default: furi_check(0); + } + FURI_LOG_I("FuriHalVersion", "Init OK"); +} + +bool furi_hal_version_do_i_belong_here() { + return furi_hal_version_get_hw_target() == 6; +} + +const char* furi_hal_version_get_model_name() { + return "Flipper Zero"; +} + +const uint8_t furi_hal_version_get_hw_version() { + return furi_hal_version.board_version; +} + +const uint8_t furi_hal_version_get_hw_target() { + return furi_hal_version.board_target; +} + +const uint8_t furi_hal_version_get_hw_body() { + return furi_hal_version.board_body; +} + +const FuriHalVersionColor furi_hal_version_get_hw_color() { + return furi_hal_version.board_color; +} + +const uint8_t furi_hal_version_get_hw_connect() { + return furi_hal_version.board_connect; +} + +const FuriHalVersionRegion furi_hal_version_get_hw_region() { + return furi_hal_version.board_region; +} + +const uint32_t furi_hal_version_get_hw_timestamp() { + return furi_hal_version.timestamp; +} + +const char* furi_hal_version_get_name_ptr() { + return *furi_hal_version.name == 0x00 ? NULL : furi_hal_version.name; +} + +const char* furi_hal_version_get_device_name_ptr() { + return furi_hal_version.device_name + 1; +} + +const char* furi_hal_version_get_ble_local_device_name_ptr() { + return furi_hal_version.device_name; +} + +const uint8_t* furi_hal_version_get_ble_mac() { + return furi_hal_version.ble_mac; +} + +const struct Version* furi_hal_version_get_firmware_version(void) { + return version_get(); +} + +const struct Version* furi_hal_version_get_boot_version(void) { +#ifdef NO_BOOTLOADER + return 0; +#else + /* Backup register which points to structure in flash memory */ + return (const struct Version*)LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR1); +#endif +} + +size_t furi_hal_version_uid_size() { + return 64/8; +} + +const uint8_t* furi_hal_version_uid() { + return (const uint8_t *)UID64_BASE; +} diff --git a/firmware/targets/f6/api-hal/api-hal-vibro.c b/firmware/targets/f6/furi-hal/furi-hal-vibro.c similarity index 63% rename from firmware/targets/f6/api-hal/api-hal-vibro.c rename to firmware/targets/f6/furi-hal/furi-hal-vibro.c index 71102f7fe3b..7dfddd4230c 100644 --- a/firmware/targets/f6/api-hal/api-hal-vibro.c +++ b/firmware/targets/f6/furi-hal/furi-hal-vibro.c @@ -1,13 +1,13 @@ -#include -#include +#include +#include -void api_hal_vibro_init() { +void furi_hal_vibro_init() { hal_gpio_init(&vibro_gpio, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); hal_gpio_write(&vibro_gpio, false); FURI_LOG_I("FuriHalVibro", "Init OK"); } -void api_hal_vibro_on(bool value) { +void furi_hal_vibro_on(bool value) { hal_gpio_write(&vibro_gpio, value); } diff --git a/firmware/targets/f6/api-hal/api-hal.c b/firmware/targets/f6/furi-hal/furi-hal.c similarity index 55% rename from firmware/targets/f6/api-hal/api-hal.c rename to firmware/targets/f6/furi-hal/furi-hal.c index d5edd11f8c7..3dc94a50570 100644 --- a/firmware/targets/f6/api-hal/api-hal.c +++ b/firmware/targets/f6/furi-hal/furi-hal.c @@ -1,40 +1,30 @@ -#include +#include -#include #include #include -#include #include #include #include #include -#include #include #include #include -void api_hal_init() { - api_hal_clock_init(); - api_hal_console_init(); - api_hal_interrupt_init(); - api_hal_delay_init(); +void furi_hal_init() { + furi_hal_clock_init(); + furi_hal_console_init(); + furi_hal_interrupt_init(); + furi_hal_delay_init(); MX_GPIO_Init(); FURI_LOG_I("HAL", "GPIO OK"); MX_RTC_Init(); FURI_LOG_I("HAL", "RTC OK"); - api_hal_boot_init(); - api_hal_version_init(); - - MX_ADC1_Init(); - FURI_LOG_I("HAL", "ADC1 OK"); + furi_hal_boot_init(); + furi_hal_version_init(); - MX_SPI1_Init(); - FURI_LOG_I("HAL", "SPI1 OK"); - MX_SPI2_Init(); - FURI_LOG_I("HAL", "SPI2 OK"); - api_hal_spi_init(); + furi_hal_spi_init(); MX_TIM1_Init(); FURI_LOG_I("HAL", "TIM1 OK"); @@ -54,23 +44,21 @@ void api_hal_init() { FURI_LOG_I("HAL", "AES1 OK"); MX_AES2_Init(); FURI_LOG_I("HAL", "AES2 OK"); - MX_CRC_Init(); - FURI_LOG_I("HAL", "CRC OK"); // VCP + USB - api_hal_vcp_init(); + furi_hal_vcp_init(); MX_USB_Device_Init(); FURI_LOG_I("HAL", "USB OK"); - api_hal_i2c_init(); + furi_hal_i2c_init(); // High Level - api_hal_power_init(); - api_hal_light_init(); - api_hal_vibro_init(); - api_hal_subghz_init(); - api_hal_nfc_init(); + furi_hal_power_init(); + furi_hal_light_init(); + furi_hal_vibro_init(); + furi_hal_subghz_init(); + furi_hal_nfc_init(); // FreeRTOS glue - api_hal_os_init(); + furi_hal_os_init(); } diff --git a/firmware/targets/f6/target.mk b/firmware/targets/f6/target.mk index 44df8fe798b..f26d768d189 100644 --- a/firmware/targets/f6/target.mk +++ b/firmware/targets/f6/target.mk @@ -14,14 +14,14 @@ FLASH_ADDRESS = 0x08000000 CFLAGS += -DNO_BOOTLOADER endif -API_HAL_OS_DEBUG ?= 0 -ifeq ($(API_HAL_OS_DEBUG), 1) -CFLAGS += -DAPI_HAL_OS_DEBUG +FURI_HAL_OS_DEBUG ?= 0 +ifeq ($(FURI_HAL_OS_DEBUG), 1) +CFLAGS += -DFURI_HAL_OS_DEBUG endif -API_HAL_SUBGHZ_TX_GPIO ?= 0 -ifneq ($(API_HAL_SUBGHZ_TX_GPIO), 0) -CFLAGS += -DAPI_HAL_SUBGHZ_TX_GPIO=$(API_HAL_SUBGHZ_TX_GPIO) +FURI_HAL_SUBGHZ_TX_GPIO ?= 0 +ifneq ($(FURI_HAL_SUBGHZ_TX_GPIO), 0) +CFLAGS += -DFURI_HAL_SUBGHZ_TX_GPIO=$(FURI_HAL_SUBGHZ_TX_GPIO) endif ifeq ($(INVERT_RFID_IN), 1) @@ -39,18 +39,14 @@ CPPFLAGS += -fno-rtti -fno-use-cxa-atexit -fno-exceptions LDFLAGS += -Wl,--start-group -lstdc++ -lsupc++ -Wl,--end-group MXPROJECT_DIR = $(TARGET_DIR) -API_HAL_DIR = $(TARGET_DIR) +FURI_HAL_DIR = $(TARGET_DIR) CUBE_DIR = ../lib/STM32CubeWB C_SOURCES += \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_adc.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_adc_ex.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_comp.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cortex.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cryp.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_crc.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_crc_ex.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_exti.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_flash.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_flash_ex.c \ @@ -67,20 +63,19 @@ C_SOURCES += \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rng.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc_ex.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_spi.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_spi_ex.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim_ex.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_adc.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_dma.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_gpio.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_i2c.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_lptim.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_rcc.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_spi.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_tim.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_lptim.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usart.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_utils.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usb.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_utils.c \ $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/croutine.c \ $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c \ $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/list.c \ @@ -96,7 +91,7 @@ C_SOURCES += \ $(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c \ $(wildcard $(MXPROJECT_DIR)/Src/*.c) \ $(wildcard $(MXPROJECT_DIR)/Src/fatfs/*.c) \ - $(wildcard $(API_HAL_DIR)/api-hal/*.c) + $(wildcard $(FURI_HAL_DIR)/furi-hal/*.c) ASM_SOURCES += $(MXPROJECT_DIR)/startup_stm32wb55xx_cm4.s @@ -124,7 +119,7 @@ CFLAGS += \ -I$(CUBE_DIR)/Drivers/CMSIS/Include \ -I$(MXPROJECT_DIR)/Inc \ -I$(MXPROJECT_DIR)/Src/fatfs \ - -I$(API_HAL_DIR)/api-hal \ + -I$(FURI_HAL_DIR)/furi-hal \ # Ble glue CFLAGS += -I$(TARGET_DIR)/ble-glue \ diff --git a/firmware/targets/furi-hal-include/furi-hal-boot.h b/firmware/targets/furi-hal-include/furi-hal-boot.h new file mode 100644 index 00000000000..9731ca1ce16 --- /dev/null +++ b/firmware/targets/furi-hal-include/furi-hal-boot.h @@ -0,0 +1,34 @@ +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Boot modes */ +typedef enum { + FuriHalBootModeNormal, + FuriHalBootModeDFU +} FuriHalBootMode; + +/** Boot flags */ +typedef enum { + FuriHalBootFlagDefault=0, + FuriHalBootFlagFactoryReset=1, +} FuriHalBootFlag; + +/** Initialize boot subsystem */ +void furi_hal_boot_init(); + +/** Set boot mode */ +void furi_hal_boot_set_mode(FuriHalBootMode mode); + +/** Set boot flags */ +void furi_hal_boot_set_flags(FuriHalBootFlag flags); + +/** Get boot flag */ +FuriHalBootFlag furi_hal_boot_get_flags(); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/api-hal-include/api-hal-bt.h b/firmware/targets/furi-hal-include/furi-hal-bt.h similarity index 54% rename from firmware/targets/api-hal-include/api-hal-bt.h rename to firmware/targets/furi-hal-include/furi-hal-bt.h index 312efe09603..d66233a11a4 100644 --- a/firmware/targets/api-hal-include/api-hal-bt.h +++ b/firmware/targets/furi-hal-include/furi-hal-bt.h @@ -8,52 +8,52 @@ extern "C" { #endif /** Initialize */ -void api_hal_bt_init(); +void furi_hal_bt_init(); /** Start BLE app */ -bool api_hal_bt_start_app(); +bool furi_hal_bt_start_app(); /** Get BT/BLE system component state */ -void api_hal_bt_dump_state(string_t buffer); +void furi_hal_bt_dump_state(string_t buffer); /** Get BT/BLE system component state */ -bool api_hal_bt_is_alive(); +bool furi_hal_bt_is_alive(); /** * Lock shared access to flash controller * @return true if lock was successful, false if not */ -bool api_hal_bt_lock_flash(); +bool furi_hal_bt_lock_flash(); /** Unlock shared access to flash controller */ -void api_hal_bt_unlock_flash(); +void furi_hal_bt_unlock_flash(); /** Start ble tone tx at given channel and power */ -void api_hal_bt_start_tone_tx(uint8_t channel, uint8_t power); +void furi_hal_bt_start_tone_tx(uint8_t channel, uint8_t power); /** Stop ble tone tx */ -void api_hal_bt_stop_tone_tx(); +void furi_hal_bt_stop_tone_tx(); /** Start sending ble packets at a given frequency and datarate */ -void api_hal_bt_start_packet_tx(uint8_t channel, uint8_t pattern, uint8_t datarate); +void furi_hal_bt_start_packet_tx(uint8_t channel, uint8_t pattern, uint8_t datarate); /** Stop sending ble packets */ -uint16_t api_hal_bt_stop_packet_test(); +uint16_t furi_hal_bt_stop_packet_test(); /** Start receiving packets */ -void api_hal_bt_start_packet_rx(uint8_t channel, uint8_t datarate); +void furi_hal_bt_start_packet_rx(uint8_t channel, uint8_t datarate); /** Set up the RF to listen to a given RF channel */ -void api_hal_bt_start_rx(uint8_t channel); +void furi_hal_bt_start_rx(uint8_t channel); /** Stop RF listenning */ -void api_hal_bt_stop_rx(); +void furi_hal_bt_stop_rx(); /** Get RSSI */ -float api_hal_bt_get_rssi(); +float furi_hal_bt_get_rssi(); /** Get number of transmitted packets */ -uint32_t api_hal_bt_get_transmitted_packets(); +uint32_t furi_hal_bt_get_transmitted_packets(); #ifdef __cplusplus } diff --git a/firmware/targets/api-hal-include/api-hal-delay.h b/firmware/targets/furi-hal-include/furi-hal-delay.h similarity index 89% rename from firmware/targets/api-hal-include/api-hal-delay.h rename to firmware/targets/furi-hal-include/furi-hal-delay.h index e01321d7d6f..0f6c0a766bf 100644 --- a/firmware/targets/api-hal-include/api-hal-delay.h +++ b/firmware/targets/furi-hal-include/furi-hal-delay.h @@ -6,7 +6,7 @@ extern "C" { #endif /** Init DWT */ -void api_hal_delay_init(void); +void furi_hal_delay_init(void); /** * Delay in milliseconds diff --git a/firmware/targets/api-hal-include/api-hal-i2c.h b/firmware/targets/furi-hal-include/furi-hal-i2c.h similarity index 83% rename from firmware/targets/api-hal-include/api-hal-i2c.h rename to firmware/targets/furi-hal-include/furi-hal-i2c.h index e34b5245290..90908c8d021 100644 --- a/firmware/targets/api-hal-include/api-hal-i2c.h +++ b/firmware/targets/furi-hal-include/furi-hal-i2c.h @@ -2,14 +2,14 @@ #include #include -#include +#include #ifdef __cplusplus extern "C" { #endif /** Init I2C */ -void api_hal_i2c_init(); +void furi_hal_i2c_init(); /** * Perform I2C tx transfer @@ -20,7 +20,7 @@ void api_hal_i2c_init(); * @param timeout timeout in CPU ticks * @return true on successful transfer, false otherwise */ -bool api_hal_i2c_tx( +bool furi_hal_i2c_tx( I2C_TypeDef* instance, const uint8_t address, const uint8_t* data, @@ -36,7 +36,7 @@ bool api_hal_i2c_tx( * @param timeout timeout in CPU ticks * @return true on successful transfer, false otherwise */ -bool api_hal_i2c_rx( +bool furi_hal_i2c_rx( I2C_TypeDef* instance, const uint8_t address, uint8_t* data, @@ -54,7 +54,7 @@ bool api_hal_i2c_rx( * @param timeout timeout in CPU ticks * @return true on successful transfer, false otherwise */ -bool api_hal_i2c_trx( +bool furi_hal_i2c_trx( I2C_TypeDef* instance, const uint8_t address, const uint8_t* tx_data, @@ -64,10 +64,10 @@ bool api_hal_i2c_trx( uint32_t timeout); /** Acquire I2C mutex */ -void api_hal_i2c_lock(); +void furi_hal_i2c_lock(); /** Release I2C mutex */ -void api_hal_i2c_unlock(); +void furi_hal_i2c_unlock(); /** * With clause for I2C peripheral @@ -75,11 +75,11 @@ void api_hal_i2c_unlock(); * @param pointer pointer to return of function_body * @param function_body a (){} lambda declaration, executed with I2C mutex acquired */ -#define with_api_hal_i2c(type, pointer, function_body) \ +#define with_furi_hal_i2c(type, pointer, function_body) \ { \ - api_hal_i2c_lock(); \ + furi_hal_i2c_lock(); \ *pointer = ({ type __fn__ function_body __fn__; })(); \ - api_hal_i2c_unlock(); \ + furi_hal_i2c_unlock(); \ } #ifdef __cplusplus diff --git a/firmware/targets/furi-hal-include/furi-hal-ibutton.h b/firmware/targets/furi-hal-include/furi-hal-ibutton.h new file mode 100644 index 00000000000..e31af7201bf --- /dev/null +++ b/firmware/targets/furi-hal-include/furi-hal-ibutton.h @@ -0,0 +1,20 @@ +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void furi_hal_ibutton_start(); + +void furi_hal_ibutton_stop(); + +void furi_hal_ibutton_pin_low(); + +void furi_hal_ibutton_pin_high(); + +bool furi_hal_ibutton_pin_get_level(); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/firmware/targets/furi-hal-include/furi-hal-irda.h b/firmware/targets/furi-hal-include/furi-hal-irda.h new file mode 100644 index 00000000000..6e490402f37 --- /dev/null +++ b/firmware/targets/furi-hal-include/furi-hal-irda.h @@ -0,0 +1,136 @@ +#pragma once +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + FuriHalIrdaTxGetDataStateError, /* An error occured during transmission */ + FuriHalIrdaTxGetDataStateOk, /* New data obtained */ + FuriHalIrdaTxGetDataStateDone, /* New data obtained, and this is end of package */ + FuriHalIrdaTxGetDataStateLastDone, /* New data obtained, and this is end of package and no more data available */ +} FuriHalIrdaTxGetDataState; + +/* Callback type for providing data to IRDA DMA TX system. It is called every tim */ +typedef FuriHalIrdaTxGetDataState (*FuriHalIrdaTxGetDataISRCallback) (void* context, uint32_t* duration, bool* level); + +/* Callback type called every time signal is sent by DMA to Timer. + * Actually, it means there are 2 timings left to send for this signal, which is almost end. + * Don't use this callback to stop transmission, as far as there are next signal is + * charged for transmission by DMA. + */ +typedef void (*FuriHalIrdaTxSignalSentISRCallback) (void* context); + +/** + * Signature of callback function for receiving continuous IRDA rx signal. + * + * @param ctx[in] - context to pass to callback + * @param level[in] - level of input IRDA rx signal + * @param duration[in] - duration of continuous rx signal level in us + */ +typedef void (*FuriHalIrdaRxCaptureCallback)(void* ctx, bool level, uint32_t duration); + +/** + * Signature of callback function for reaching silence timeout on IRDA port. + * + * @param ctx[in] - context to pass to callback + */ +typedef void (*FuriHalIrdaRxTimeoutCallback)(void* ctx); + +/** + * Initialize IRDA RX timer to receive interrupts. + * It provides interrupts for every RX-signal edge changing + * with its duration. + */ +void furi_hal_irda_async_rx_start(void); + +/** + * Deinitialize IRDA RX interrupt. + */ +void furi_hal_irda_async_rx_stop(void); + +/** Setup hal for receiving silence timeout. + * Should be used with 'furi_hal_irda_timeout_irq_set_callback()'. + * + * @param[in] timeout_us - time to wait for silence on IRDA port + * before generating IRQ. + */ +void furi_hal_irda_async_rx_set_timeout(uint32_t timeout_us); + +/** Setup callback for previously initialized IRDA RX interrupt. + * + * @param[in] callback - callback to call when RX signal edge changing occurs + * @param[in] ctx - context for callback + */ +void furi_hal_irda_async_rx_set_capture_isr_callback(FuriHalIrdaRxCaptureCallback callback, void *ctx); + +/** + * Setup callback for reaching silence timeout on IRDA port. + * Should setup hal with 'furi_hal_irda_setup_rx_timeout_irq()' first. + * + * @param[in] callback - callback for silence timeout + * @param[in] ctx - context to pass to callback + */ +void furi_hal_irda_async_rx_set_timeout_isr_callback(FuriHalIrdaRxTimeoutCallback callback, void *ctx); + +/** + * Check if IRDA is in use now. + * @return true - IRDA is busy, false otherwise. + */ +bool furi_hal_irda_is_busy(void); + +/** + * Set callback providing new data. This function has to be called + * before furi_hal_irda_async_tx_start(). + * + * @param[in] callback - function to provide new data + * @param[in] context - context for callback + */ +void furi_hal_irda_async_tx_set_data_isr_callback(FuriHalIrdaTxGetDataISRCallback callback, void* context); + +/** + * Start IR asynchronous transmission. It can be stopped by 2 reasons: + * 1) implicit call for furi_hal_irda_async_tx_stop() + * 2) callback can provide FuriHalIrdaTxGetDataStateLastDone response + * which means no more data available for transmission. + * + * Any func (furi_hal_irda_async_tx_stop() or + * furi_hal_irda_async_tx_wait_termination()) has to be called to wait + * end of transmission and free resources. + * + * @param[in] freq - frequency for PWM + * @param[in] duty_cycle - duty cycle for PWM + * @return true if transmission successfully started, false otherwise. + * If start failed no need to free resources. + */ +bool furi_hal_irda_async_tx_start(uint32_t freq, float duty_cycle); + +/** + * Stop IR asynchronous transmission and free resources. + * Transmission will stop as soon as transmission reaches end of + * package (FuriHalIrdaTxGetDataStateDone or FuriHalIrdaTxGetDataStateLastDone). + */ +void furi_hal_irda_async_tx_stop(void); + +/** + * Wait for end of IR asynchronous transmission and free resources. + * Transmission will stop as soon as transmission reaches end of + * transmission (FuriHalIrdaTxGetDataStateLastDone). + */ +void furi_hal_irda_async_tx_wait_termination(void); + +/** + * Set callback for end of signal transmission + * + * @param[in] callback - function to call when signal is sent + * @param[in] context - context for callback + */ +void furi_hal_irda_async_tx_set_signal_sent_isr_callback(FuriHalIrdaTxSignalSentISRCallback callback, void* context); + +#ifdef __cplusplus +} +#endif + diff --git a/firmware/targets/api-hal-include/api-hal-light.h b/firmware/targets/furi-hal-include/furi-hal-light.h similarity index 68% rename from firmware/targets/api-hal-include/api-hal-light.h rename to firmware/targets/furi-hal-include/furi-hal-light.h index fd5fa458909..6b69985026b 100644 --- a/firmware/targets/api-hal-include/api-hal-light.h +++ b/firmware/targets/furi-hal-include/furi-hal-light.h @@ -2,21 +2,21 @@ #include #include -#include +#include #ifdef __cplusplus extern "C" { #endif /** Init light driver */ -void api_hal_light_init(); +void furi_hal_light_init(); /** * Set light value * @param light - Light * @param value - light brightness [0-255] */ -void api_hal_light_set(Light light, uint8_t value); +void furi_hal_light_set(Light light, uint8_t value); #ifdef __cplusplus } diff --git a/firmware/targets/furi-hal-include/furi-hal-nfc.h b/firmware/targets/furi-hal-include/furi-hal-nfc.h new file mode 100644 index 00000000000..aaed292434c --- /dev/null +++ b/firmware/targets/furi-hal-include/furi-hal-nfc.h @@ -0,0 +1,66 @@ +#pragma once + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define FURI_HAL_NFC_UID_MAX_LEN 10 + +/** + * Init nfc + */ +void furi_hal_nfc_init(); + +/** + * Check if nfc worker is busy + */ +bool furi_hal_nfc_is_busy(); + +/** + * NFC field on + */ +void furi_hal_nfc_field_on(); + +/** + * NFC field off + */ +void furi_hal_nfc_field_off(); + +/** + * NFC start sleep + */ +void furi_hal_nfc_start_sleep(); + +/** + * NFC stop sleep + */ +void furi_hal_nfc_exit_sleep(); + +/** + * NFC poll + */ +bool furi_hal_nfc_detect(rfalNfcDevice** dev_list, uint8_t* dev_cnt, uint32_t timeout, bool deactivate); + +/** + * NFC listen + */ +bool furi_hal_nfc_listen(uint8_t* uid, uint8_t uid_len, uint8_t* atqa, uint8_t sak, uint32_t timeout); + +/** + * NFC data exchange + */ +ReturnCode furi_hal_nfc_data_exchange(uint8_t* tx_buff, uint16_t tx_len, uint8_t** rx_buff, uint16_t** rx_len, bool deactivate); + +/** + * NFC deactivate and start sleep + */ +void furi_hal_nfc_deactivate(); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/api-hal-include/api-hal-power.h b/firmware/targets/furi-hal-include/furi-hal-power.h similarity index 51% rename from firmware/targets/api-hal-include/api-hal-power.h rename to firmware/targets/furi-hal-include/furi-hal-power.h index 25b20d5e846..aeb6c20194e 100644 --- a/firmware/targets/api-hal-include/api-hal-power.h +++ b/firmware/targets/furi-hal-include/furi-hal-power.h @@ -10,94 +10,94 @@ extern "C" { /** Power IC type */ typedef enum { - ApiHalPowerICCharger, - ApiHalPowerICFuelGauge, -} ApiHalPowerIC; + FuriHalPowerICCharger, + FuriHalPowerICFuelGauge, +} FuriHalPowerIC; /** Initialize drivers */ -void api_hal_power_init(); +void furi_hal_power_init(); /** * Get current insomnia level * @return insomnia level: 0 - no insomnia, >0 - insomnia, bearer count. */ -uint16_t api_hal_power_insomnia_level(); +uint16_t furi_hal_power_insomnia_level(); /** * Enter insomnia mode * Prevents device from going to sleep * @warning Internally increases insomnia level - * Must be paired with api_hal_power_insomnia_exit + * Must be paired with furi_hal_power_insomnia_exit */ -void api_hal_power_insomnia_enter(); +void furi_hal_power_insomnia_enter(); /** * Exit insomnia mode * Allow device to go to sleep * @warning Internally decreases insomnia level. - * Must be paired with api_hal_power_insomnia_enter + * Must be paired with furi_hal_power_insomnia_enter */ -void api_hal_power_insomnia_exit(); +void furi_hal_power_insomnia_exit(); /** Check if sleep availble */ -bool api_hal_power_sleep_available(); +bool furi_hal_power_sleep_available(); /** Check if deep sleep availble */ -bool api_hal_power_deep_sleep_available(); +bool furi_hal_power_deep_sleep_available(); /** Go to sleep */ -void api_hal_power_sleep(); +void furi_hal_power_sleep(); /** Get predicted remaining battery capacity in percents */ -uint8_t api_hal_power_get_pct(); +uint8_t furi_hal_power_get_pct(); /** Get battery health state in percents */ -uint8_t api_hal_power_get_bat_health_pct(); +uint8_t furi_hal_power_get_bat_health_pct(); /** Get charging status */ -bool api_hal_power_is_charging(); +bool furi_hal_power_is_charging(); /** Poweroff device */ -void api_hal_power_off(); +void furi_hal_power_off(); /** Reset device */ -void api_hal_power_reset(); +void furi_hal_power_reset(); /** OTG enable */ -void api_hal_power_enable_otg(); +void furi_hal_power_enable_otg(); /** OTG disable */ -void api_hal_power_disable_otg(); +void furi_hal_power_disable_otg(); /** Get remaining battery battery capacity in mAh */ -uint32_t api_hal_power_get_battery_remaining_capacity(); +uint32_t furi_hal_power_get_battery_remaining_capacity(); /** Get full charge battery capacity in mAh */ -uint32_t api_hal_power_get_battery_full_capacity(); +uint32_t furi_hal_power_get_battery_full_capacity(); /** Get battery voltage in V */ -float api_hal_power_get_battery_voltage(ApiHalPowerIC ic); +float furi_hal_power_get_battery_voltage(FuriHalPowerIC ic); /** Get battery current in A */ -float api_hal_power_get_battery_current(ApiHalPowerIC ic); +float furi_hal_power_get_battery_current(FuriHalPowerIC ic); /** Get temperature in C */ -float api_hal_power_get_battery_temperature(ApiHalPowerIC ic); +float furi_hal_power_get_battery_temperature(FuriHalPowerIC ic); /** Get System voltage in V */ -float api_hal_power_get_system_voltage(); +float furi_hal_power_get_system_voltage(); /** Get USB voltage in V */ -float api_hal_power_get_usb_voltage(); +float furi_hal_power_get_usb_voltage(); /** Get power system component state */ -void api_hal_power_dump_state(); +void furi_hal_power_dump_state(); /** Enable 3.3v on external gpio and sd card */ -void api_hal_power_enable_external_3_3v(); +void furi_hal_power_enable_external_3_3v(); /** Disable 3.3v on external gpio and sd card */ -void api_hal_power_disable_external_3_3v(); +void furi_hal_power_disable_external_3_3v(); #ifdef __cplusplus } diff --git a/firmware/targets/api-hal-include/api-hal-rfid.h b/firmware/targets/furi-hal-include/furi-hal-rfid.h similarity index 64% rename from firmware/targets/api-hal-include/api-hal-rfid.h rename to firmware/targets/furi-hal-include/furi-hal-rfid.h index 7f2870b05fd..d0a6aeaa354 100644 --- a/firmware/targets/api-hal-include/api-hal-rfid.h +++ b/firmware/targets/furi-hal-include/furi-hal-rfid.h @@ -11,19 +11,19 @@ extern "C" { * @brief config rfid pins to reset state * */ -void api_hal_rfid_pins_reset(); +void furi_hal_rfid_pins_reset(); /** * @brief config rfid pins to emulate state * */ -void api_hal_rfid_pins_emulate(); +void furi_hal_rfid_pins_emulate(); /** * @brief config rfid pins to read state * */ -void api_hal_rfid_pins_read(); +void furi_hal_rfid_pins_read(); /** * @brief config rfid timer to read state @@ -31,86 +31,86 @@ void api_hal_rfid_pins_read(); * @param freq timer frequency * @param duty_cycle timer duty cycle, 0.0-1.0 */ -void api_hal_rfid_tim_read(float freq, float duty_cycle); +void furi_hal_rfid_tim_read(float freq, float duty_cycle); /** * @brief start read timer * */ -void api_hal_rfid_tim_read_start(); +void furi_hal_rfid_tim_read_start(); /** * @brief stop read timer * */ -void api_hal_rfid_tim_read_stop(); +void furi_hal_rfid_tim_read_stop(); /** * @brief config rfid timer to emulate state * * @param freq timer frequency */ -void api_hal_rfid_tim_emulate(float freq); +void furi_hal_rfid_tim_emulate(float freq); /** * @brief start emulation timer * */ -void api_hal_rfid_tim_emulate_start(); +void furi_hal_rfid_tim_emulate_start(); /** * @brief stop emulation timer * */ -void api_hal_rfid_tim_emulate_stop(); +void furi_hal_rfid_tim_emulate_stop(); /** * @brief config rfid timers to reset state * */ -void api_hal_rfid_tim_reset(); +void furi_hal_rfid_tim_reset(); /** * @brief check that timer instance is emulation timer * * @param hw timer instance */ -bool api_hal_rfid_is_tim_emulate(TIM_HandleTypeDef* hw); +bool furi_hal_rfid_is_tim_emulate(TIM_HandleTypeDef* hw); /** * @brief set emulation timer period * * @param period overall duration */ -void api_hal_rfid_set_emulate_period(uint32_t period); +void furi_hal_rfid_set_emulate_period(uint32_t period); /** * @brief set emulation timer pulse * * @param pulse duration of high level */ -void api_hal_rfid_set_emulate_pulse(uint32_t pulse); +void furi_hal_rfid_set_emulate_pulse(uint32_t pulse); /** * @brief set read timer period * * @param period overall duration */ -void api_hal_rfid_set_read_period(uint32_t period); +void furi_hal_rfid_set_read_period(uint32_t period); /** * @brief set read timer pulse * * @param pulse duration of high level */ -void api_hal_rfid_set_read_pulse(uint32_t pulse); +void furi_hal_rfid_set_read_pulse(uint32_t pulse); /** * Сhanges the configuration of the RFID timer "on a fly" * @param freq new frequency * @param duty_cycle new duty cycle */ -void api_hal_rfid_change_read_config(float freq, float duty_cycle); +void furi_hal_rfid_change_read_config(float freq, float duty_cycle); #ifdef __cplusplus } diff --git a/firmware/targets/api-hal-include/api-hal-sd.h b/firmware/targets/furi-hal-include/furi-hal-sd.h similarity index 100% rename from firmware/targets/api-hal-include/api-hal-sd.h rename to firmware/targets/furi-hal-include/furi-hal-sd.h diff --git a/firmware/targets/api-hal-include/api-hal-subghz.h b/firmware/targets/furi-hal-include/furi-hal-subghz.h similarity index 53% rename from firmware/targets/api-hal-include/api-hal-subghz.h rename to firmware/targets/furi-hal-include/furi-hal-subghz.h index d6aa1f8b589..bf80d7e19e9 100644 --- a/firmware/targets/api-hal-include/api-hal-subghz.h +++ b/firmware/targets/furi-hal-include/furi-hal-subghz.h @@ -11,16 +11,16 @@ extern "C" { /** Radio Presets */ typedef enum { - ApiHalSubGhzPresetOokAsync, /** OOK, asynchronous */ -} ApiHalSubGhzPreset; + FuriHalSubGhzPresetOokAsync, /** OOK, asynchronous */ +} FuriHalSubGhzPreset; /** Switchable Radio Paths */ typedef enum { - ApiHalSubGhzPathIsolate, /** Isolate Radio from antenna */ - ApiHalSubGhzPath433, /** Center Frquency: 433MHz. Path 1: SW1RF1-SW2RF2, LCLCL */ - ApiHalSubGhzPath315, /** Center Frquency: 315MHz. Path 2: SW1RF2-SW2RF1, LCLCLCL */ - ApiHalSubGhzPath868, /** Center Frquency: 868MHz. Path 3: SW1RF3-SW2RF3, LCLC */ -} ApiHalSubGhzPath; + FuriHalSubGhzPathIsolate, /** Isolate Radio from antenna */ + FuriHalSubGhzPath433, /** Center Frquency: 433MHz. Path 1: SW1RF1-SW2RF2, LCLCL */ + FuriHalSubGhzPath315, /** Center Frquency: 315MHz. Path 2: SW1RF2-SW2RF1, LCLCLCL */ + FuriHalSubGhzPath868, /** Center Frquency: 868MHz. Path 3: SW1RF3-SW2RF3, LCLC */ +} FuriHalSubGhzPath; /** SubGhz state */ typedef enum { @@ -39,133 +39,127 @@ typedef enum { * Used by internal API-HAL initalization routine * Can be used to reinitialize device to safe state and send it to sleep */ -void api_hal_subghz_init(); +void furi_hal_subghz_init(); /** Send device to sleep mode */ -void api_hal_subghz_sleep(); +void furi_hal_subghz_sleep(); /** Dump info to stdout */ -void api_hal_subghz_dump_state(); +void furi_hal_subghz_dump_state(); /** Load registers from preset by preset name * @param preset to load */ -void api_hal_subghz_load_preset(ApiHalSubGhzPreset preset); +void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset); /** Get status */ -uint8_t api_hal_subghz_get_status(); +uint8_t furi_hal_subghz_get_status(); /** Load registers * @param register-value pairs array, terminated with {0,0} */ -void api_hal_subghz_load_registers(const uint8_t data[][2]); +void furi_hal_subghz_load_registers(const uint8_t data[][2]); /** Load PATABLE * @param data, 8 uint8_t values */ -void api_hal_subghz_load_patable(const uint8_t data[8]); +void furi_hal_subghz_load_patable(const uint8_t data[8]); /** Write packet to FIFO * @param data, bytes array * @param size, size */ -void api_hal_subghz_write_packet(const uint8_t* data, uint8_t size); +void furi_hal_subghz_write_packet(const uint8_t* data, uint8_t size); /** Read packet from FIFO * @param data, pointer * @param size, size */ -void api_hal_subghz_read_packet(uint8_t* data, uint8_t* size); +void furi_hal_subghz_read_packet(uint8_t* data, uint8_t* size); /** Flush rx FIFO buffer */ -void api_hal_subghz_flush_rx(); +void furi_hal_subghz_flush_rx(); /** Shutdown * Issue spwd command * @warning registers content will be lost */ -void api_hal_subghz_shutdown(); +void furi_hal_subghz_shutdown(); /** Reset * Issue reset command * @warning registers content will be lost */ -void api_hal_subghz_reset(); +void furi_hal_subghz_reset(); /** Switch to Idle */ -void api_hal_subghz_idle(); +void furi_hal_subghz_idle(); /** Switch to Recieve */ -void api_hal_subghz_rx(); +void furi_hal_subghz_rx(); /** Switch to Transmit */ -void api_hal_subghz_tx(); +void furi_hal_subghz_tx(); /** Get RSSI value in dBm */ -float api_hal_subghz_get_rssi(); +float furi_hal_subghz_get_rssi(); /** Check if frequency is in valid range * @return true if frequncy is valid, otherwise false */ -bool api_hal_subghz_is_frequency_valid(uint32_t value); +bool furi_hal_subghz_is_frequency_valid(uint32_t value); /** Set frequency and path * This function automatically selects antenna matching network * @param frequency in herz * @return real frequency in herz */ -uint32_t api_hal_subghz_set_frequency_and_path(uint32_t value); +uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value); /** Set frequency * @param frequency in herz * @return real frequency in herz */ -uint32_t api_hal_subghz_set_frequency(uint32_t value); +uint32_t furi_hal_subghz_set_frequency(uint32_t value); /** Set path * @param radio path to use */ -void api_hal_subghz_set_path(ApiHalSubGhzPath path); +void furi_hal_subghz_set_path(FuriHalSubGhzPath path); /* High Level API */ /** Signal Timings Capture callback */ -typedef void (*ApiHalSubGhzCaptureCallback)(bool level, uint32_t duration, void* context); - -/** Set signal timings capture callback - * @param callback - your callback for front capture - */ -void api_hal_subghz_set_async_rx_callback(ApiHalSubGhzCaptureCallback callback, void* context); +typedef void (*FuriHalSubGhzCaptureCallback)(bool level, uint32_t duration, void* context); /** Enable signal timings capture * Initializes GPIO and TIM2 for timings capture */ -void api_hal_subghz_start_async_rx(); +void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* context); /** Disable signal timings capture * Resets GPIO and TIM2 */ -void api_hal_subghz_stop_async_rx(); +void furi_hal_subghz_stop_async_rx(); -/** Send buffer - * Initializes GPIO, TIM2 and DMA1 for signal output - * @param buffer - pointer to data buffer - * @param buffer_size - buffer size in bytes +/** Async TX callback type + * @param context - callback context + * @return LevelDuration */ -void api_hal_subghz_start_async_tx(uint32_t* buffer, size_t buffer_size, size_t repeat); +typedef LevelDuration (*FuriHalSubGhzAsyncTxCallback)(void* context); -/** Get repeats left count for async tx - * @return packets left to send +/** Start async TX + * Initializes GPIO, TIM2 and DMA1 for signal output */ -size_t api_hal_subghz_get_async_tx_repeat_left(); +void furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* context); /** Wait for async transmission to complete */ -void api_hal_subghz_wait_async_tx(); +bool furi_hal_subghz_is_async_tx_complete(); /** Stop async transmission and cleanup resources * Resets GPIO, TIM2, and DMA1 */ -void api_hal_subghz_stop_async_tx(); +void furi_hal_subghz_stop_async_tx(); #ifdef __cplusplus } diff --git a/firmware/targets/api-hal-include/api-hal-vcp.h b/firmware/targets/furi-hal-include/furi-hal-vcp.h similarity index 77% rename from firmware/targets/api-hal-include/api-hal-vcp.h rename to firmware/targets/furi-hal-include/furi-hal-vcp.h index 1baad0a0b32..1312b20c40e 100644 --- a/firmware/targets/api-hal-include/api-hal-vcp.h +++ b/firmware/targets/furi-hal-include/furi-hal-vcp.h @@ -12,7 +12,7 @@ extern "C" { * Init VCP HAL * Allocates ring buffer and initializes state */ -void api_hal_vcp_init(); +void furi_hal_vcp_init(); /** * Recieve data from VCP @@ -21,7 +21,7 @@ void api_hal_vcp_init(); * @param size - buffer size * @return items copied in buffer, 0 if channel closed */ -size_t api_hal_vcp_rx(uint8_t* buffer, size_t size); +size_t furi_hal_vcp_rx(uint8_t* buffer, size_t size); /** * Recieve data from VCP with timeout @@ -31,14 +31,14 @@ size_t api_hal_vcp_rx(uint8_t* buffer, size_t size); * @param timeout - rx timeout in ms * @return items copied in buffer, 0 if channel closed or timeout occurs */ -size_t api_hal_vcp_rx_with_timeout(uint8_t* buffer, size_t size, uint32_t timeout); +size_t furi_hal_vcp_rx_with_timeout(uint8_t* buffer, size_t size, uint32_t timeout); /** * Transmit data to VCP * @param buffer - pointer to buffer * @param size - buffer size */ -void api_hal_vcp_tx(const uint8_t* buffer, size_t size); +void furi_hal_vcp_tx(const uint8_t* buffer, size_t size); #ifdef __cplusplus } diff --git a/firmware/targets/furi-hal-include/furi-hal-version.h b/firmware/targets/furi-hal-include/furi-hal-version.h new file mode 100644 index 00000000000..1cd702fc117 --- /dev/null +++ b/firmware/targets/furi-hal-include/furi-hal-version.h @@ -0,0 +1,90 @@ +#pragma once + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Device Colors */ +typedef enum { + FuriHalVersionColorUnknown=0x00, + FuriHalVersionColorBlack=0x01, + FuriHalVersionColorWhite=0x02, +} FuriHalVersionColor; + +/** Device Regions */ +typedef enum { + FuriHalVersionRegionUnknown=0x00, + FuriHalVersionRegionEuRu=0x01, + FuriHalVersionRegionUsCaAu=0x02, + FuriHalVersionRegionJp=0x03, +} FuriHalVersionRegion; + +/** Init flipper version */ +void furi_hal_version_init(); + +/** Check target firmware version */ +bool furi_hal_version_do_i_belong_here(); + +/** Get model name */ +const char* furi_hal_version_get_model_name(); + +/** Get hardware version */ +const uint8_t furi_hal_version_get_hw_version(); + +/** Get hardware target */ +const uint8_t furi_hal_version_get_hw_target(); + +/** Get hardware body */ +const uint8_t furi_hal_version_get_hw_body(); + +/** Get hardware body color */ +const FuriHalVersionColor furi_hal_version_get_hw_color(); + +/** Get hardware connect */ +const uint8_t furi_hal_version_get_hw_connect(); + +/** Get hardware region */ +const FuriHalVersionRegion furi_hal_version_get_hw_region(); + +/** Get hardware timestamp */ +const uint32_t furi_hal_version_get_hw_timestamp(); + +/** Get pointer to target name */ +const char* furi_hal_version_get_name_ptr(); + +/** Get pointer to target device name */ +const char* furi_hal_version_get_device_name_ptr(); + +/** Get pointer to target ble local device name */ +const char* furi_hal_version_get_ble_local_device_name_ptr(); + +const uint8_t* furi_hal_version_get_ble_mac(); + +/** + * Get address of version structure of bootloader, stored in chip flash. + * + * @return Address of boot version structure. + */ +const struct Version* furi_hal_version_get_boot_version(void); + +/** + * Get address of version structure of firmware. + * + * @return Address of firmware version structure. + */ +const struct Version* furi_hal_version_get_firmware_version(void); + +/** Get platform UID size in bytes */ +size_t furi_hal_version_uid_size(); + +/** Get const pointer to UID */ +const uint8_t* furi_hal_version_uid(); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/api-hal-include/api-hal-vibro.h b/firmware/targets/furi-hal-include/furi-hal-vibro.h similarity index 64% rename from firmware/targets/api-hal-include/api-hal-vibro.h rename to firmware/targets/furi-hal-include/furi-hal-vibro.h index 088dbb40a75..6a7c4d366a6 100644 --- a/firmware/targets/api-hal-include/api-hal-vibro.h +++ b/firmware/targets/furi-hal-include/furi-hal-vibro.h @@ -2,17 +2,17 @@ #include #include -#include +#include #ifdef __cplusplus extern "C" { #endif /** Initialize vibro */ -void api_hal_vibro_init(); +void furi_hal_vibro_init(); /** Turn on/off vibro */ -void api_hal_vibro_on(bool value); +void furi_hal_vibro_on(bool value); #ifdef __cplusplus } diff --git a/firmware/targets/furi-hal-include/furi-hal.h b/firmware/targets/furi-hal-include/furi-hal.h new file mode 100644 index 00000000000..dc5162b8a64 --- /dev/null +++ b/firmware/targets/furi-hal-include/furi-hal.h @@ -0,0 +1,32 @@ +#pragma once + +#ifdef __cplusplus +template struct STOP_EXTERNING_ME {}; +#endif + +#include "furi-hal-boot.h" +#include "furi-hal-clock.h" +#include "furi-hal-console.h" +#include "furi-hal-os.h" +#include "furi-hal-i2c.h" +#include "furi-hal-resources.h" +#include "furi-hal-gpio.h" +#include "furi-hal-light.h" +#include "furi-hal-delay.h" +#include "furi-hal-pwm.h" +#include "furi-hal-task.h" +#include "furi-hal-power.h" +#include "furi-hal-vcp.h" +#include "furi-hal-interrupt.h" +#include "furi-hal-version.h" +#include "furi-hal-bt.h" +#include "furi-hal-spi.h" +#include "furi-hal-flash.h" +#include "furi-hal-subghz.h" +#include "furi-hal-vibro.h" +#include "furi-hal-ibutton.h" +#include "furi-hal-rfid.h" +#include "furi-hal-nfc.h" + +/** Init furi-hal */ +void furi_hal_init(); diff --git a/lib/ST25RFAL002/platform.c b/lib/ST25RFAL002/platform.c index c63218ff223..7a011965d7a 100644 --- a/lib/ST25RFAL002/platform.c +++ b/lib/ST25RFAL002/platform.c @@ -2,12 +2,12 @@ #include #include #include -#include +#include static osThreadAttr_t platform_irq_thread_attr; static volatile osThreadId_t platform_irq_thread_id = NULL; static volatile PlatformIrqCallback platform_irq_callback = NULL; -static ApiHalSpiDevice* platform_st25r3916 = NULL; +static FuriHalSpiDevice* platform_st25r3916 = NULL; static const GpioPin pin = {ST25R_INT_PORT, ST25R_INT_PIN}; void nfc_isr(void* _ctx) { @@ -52,11 +52,11 @@ HAL_StatusTypeDef platformSpiTxRx(const uint8_t *txBuf, uint8_t *rxBuf, uint16_t furi_assert(platform_st25r3916); bool ret = false; if (txBuf && rxBuf) { - ret = api_hal_spi_bus_trx(platform_st25r3916->bus, (uint8_t*)txBuf, rxBuf, len, 1000); + ret = furi_hal_spi_bus_trx(platform_st25r3916->bus, (uint8_t*)txBuf, rxBuf, len, 1000); } else if (txBuf) { - ret = api_hal_spi_bus_tx(platform_st25r3916->bus, (uint8_t*)txBuf, len, 1000); + ret = furi_hal_spi_bus_tx(platform_st25r3916->bus, (uint8_t*)txBuf, len, 1000); } else if (rxBuf) { - ret = api_hal_spi_bus_rx(platform_st25r3916->bus, (uint8_t*)rxBuf, len, 1000); + ret = furi_hal_spi_bus_rx(platform_st25r3916->bus, (uint8_t*)rxBuf, len, 1000); } if(!ret) { @@ -68,10 +68,15 @@ HAL_StatusTypeDef platformSpiTxRx(const uint8_t *txBuf, uint8_t *rxBuf, uint16_t } void platformProtectST25RComm() { - platform_st25r3916 = (ApiHalSpiDevice*)api_hal_spi_device_get(ApiHalSpiDeviceIdNfc); + // Don't check platform_st25r3916 since spi device is used simultaneously from nfc worker + // thread and platformIrqWorker thread with the highest priority + + // furi_assert(platform_st25r3916 == NULL); + platform_st25r3916 = (FuriHalSpiDevice*)furi_hal_spi_device_get(FuriHalSpiDeviceIdNfc); } void platformUnprotectST25RComm() { - furi_assert(platform_st25r3916); - api_hal_spi_device_return(platform_st25r3916); + // furi_assert(platform_st25r3916); + furi_hal_spi_device_return(platform_st25r3916); + // platform_st25r3916 = NULL; } diff --git a/lib/ST25RFAL002/platform.h b/lib/ST25RFAL002/platform.h index 4f6705b656b..9629d7ed82f 100644 --- a/lib/ST25RFAL002/platform.h +++ b/lib/ST25RFAL002/platform.h @@ -8,11 +8,10 @@ #include #include "timer.h" #include "math.h" -#include "spi.h" #include "main.h" -#include -#include -#include +#include +#include +#include typedef void (*PlatformIrqCallback)(); void platformSetIrqCallback(PlatformIrqCallback cb); diff --git a/lib/app-template/app-template.h b/lib/app-template/app-template.h index 74c186b3613..27949dd0a08 100644 --- a/lib/app-template/app-template.h +++ b/lib/app-template/app-template.h @@ -2,7 +2,7 @@ #include "callback-connector.h" #include -#include +#include #include #include diff --git a/lib/cyfral/cyfral_emulator.h b/lib/cyfral/cyfral_emulator.h index a8da7668183..2ceaae89a7d 100644 --- a/lib/cyfral/cyfral_emulator.h +++ b/lib/cyfral/cyfral_emulator.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include class CyfralTiming { public: diff --git a/lib/drivers/bq25896.c b/lib/drivers/bq25896.c index c07a710ed20..bcafcb6a1d6 100644 --- a/lib/drivers/bq25896.c +++ b/lib/drivers/bq25896.c @@ -1,7 +1,7 @@ #include "bq25896.h" #include "bq25896_reg.h" -#include +#include #include uint8_t bit_reverse(uint8_t b) { @@ -13,9 +13,9 @@ uint8_t bit_reverse(uint8_t b) { bool bq25896_read(uint8_t address, uint8_t* data, size_t size) { bool ret; - with_api_hal_i2c( + with_furi_hal_i2c( bool, &ret, () { - return api_hal_i2c_trx( + return furi_hal_i2c_trx( POWER_I2C, BQ25896_ADDRESS, &address, 1, data, size, BQ25896_I2C_TIMEOUT); }); return ret; @@ -29,9 +29,9 @@ bool bq25896_read_reg(uint8_t address, uint8_t* data) { bool bq25896_write_reg(uint8_t address, uint8_t* data) { uint8_t buffer[2] = {address, *data}; bool ret; - with_api_hal_i2c( + with_furi_hal_i2c( bool, &ret, () { - return api_hal_i2c_tx(POWER_I2C, BQ25896_ADDRESS, buffer, 2, BQ25896_I2C_TIMEOUT); + return furi_hal_i2c_tx(POWER_I2C, BQ25896_ADDRESS, buffer, 2, BQ25896_I2C_TIMEOUT); }); return ret; } diff --git a/lib/drivers/bq27220.c b/lib/drivers/bq27220.c index 9c62f7a0721..d83cae05618 100644 --- a/lib/drivers/bq27220.c +++ b/lib/drivers/bq27220.c @@ -1,16 +1,16 @@ #include "bq27220.h" #include "bq27220_reg.h" -#include -#include +#include +#include #include uint16_t bq27220_read_word(uint8_t address) { uint8_t buffer[2] = {address}; uint16_t ret; - with_api_hal_i2c( + with_furi_hal_i2c( uint16_t, &ret, () { - if(api_hal_i2c_trx( + if(furi_hal_i2c_trx( POWER_I2C, BQ27220_ADDRESS, buffer, 1, buffer, 2, BQ27220_I2C_TIMEOUT)) { return *(uint16_t*)buffer; } else { @@ -22,13 +22,13 @@ uint16_t bq27220_read_word(uint8_t address) { bool bq27220_control(uint16_t control) { bool ret; - with_api_hal_i2c( + with_furi_hal_i2c( bool, &ret, () { uint8_t buffer[3]; buffer[0] = CommandControl; buffer[1] = control & 0xFF; buffer[2] = (control >> 8) & 0xFF; - return api_hal_i2c_tx(POWER_I2C, BQ27220_ADDRESS, buffer, 3, BQ27220_I2C_TIMEOUT); + return furi_hal_i2c_tx(POWER_I2C, BQ27220_ADDRESS, buffer, 3, BQ27220_I2C_TIMEOUT); }); return ret; } @@ -44,23 +44,23 @@ uint8_t bq27220_get_checksum(uint8_t* data, uint16_t len) { bool bq27220_set_parameter_u16(uint16_t address, uint16_t value) { bool ret; uint8_t buffer[5]; - with_api_hal_i2c( + with_furi_hal_i2c( bool, &ret, () { buffer[0] = CommandSelectSubclass; buffer[1] = address & 0xFF; buffer[2] = (address >> 8) & 0xFF; buffer[3] = (value >> 8) & 0xFF; buffer[4] = value & 0xFF; - return api_hal_i2c_tx(POWER_I2C, BQ27220_ADDRESS, buffer, 5, BQ27220_I2C_TIMEOUT); + return furi_hal_i2c_tx(POWER_I2C, BQ27220_ADDRESS, buffer, 5, BQ27220_I2C_TIMEOUT); }); delay_us(10000); uint8_t checksum = bq27220_get_checksum(&buffer[1], 4); - with_api_hal_i2c( + with_furi_hal_i2c( bool, &ret, () { buffer[0] = CommandMACDataSum; buffer[1] = checksum; buffer[2] = 6; - return api_hal_i2c_tx(POWER_I2C, BQ27220_ADDRESS, buffer, 3, BQ27220_I2C_TIMEOUT); + return furi_hal_i2c_tx(POWER_I2C, BQ27220_ADDRESS, buffer, 3, BQ27220_I2C_TIMEOUT); }); delay_us(10000); return ret; diff --git a/lib/drivers/cc1101.c b/lib/drivers/cc1101.c index c1f2a4d37da..4e020b7041b 100644 --- a/lib/drivers/cc1101.c +++ b/lib/drivers/cc1101.c @@ -1,43 +1,43 @@ #include "cc1101.h" #include -#include +#include #include #include -CC1101Status cc1101_strobe(const ApiHalSpiDevice* device, uint8_t strobe) { +CC1101Status cc1101_strobe(const FuriHalSpiDevice* device, uint8_t strobe) { uint8_t tx[1] = { strobe }; CC1101Status rx[1] = { 0 }; hal_gpio_write(device->chip_select, false); while(hal_gpio_read(device->bus->miso)); - api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 1, CC1101_TIMEOUT); + furi_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 1, CC1101_TIMEOUT); hal_gpio_write(device->chip_select, true); assert(rx[0].CHIP_RDYn == 0); return rx[0]; } -CC1101Status cc1101_write_reg(const ApiHalSpiDevice* device, uint8_t reg, uint8_t data) { +CC1101Status cc1101_write_reg(const FuriHalSpiDevice* device, uint8_t reg, uint8_t data) { uint8_t tx[2] = { reg, data }; CC1101Status rx[2] = { 0 }; hal_gpio_write(device->chip_select, false); while(hal_gpio_read(device->bus->miso)); - api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); + furi_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); hal_gpio_write(device->chip_select, true); assert((rx[0].CHIP_RDYn|rx[1].CHIP_RDYn) == 0); return rx[1]; } -CC1101Status cc1101_read_reg(const ApiHalSpiDevice* device, uint8_t reg, uint8_t* data) { +CC1101Status cc1101_read_reg(const FuriHalSpiDevice* device, uint8_t reg, uint8_t* data) { assert(sizeof(CC1101Status) == 1); uint8_t tx[2] = { reg|CC1101_READ, 0}; CC1101Status rx[2] = { 0 }; hal_gpio_write(device->chip_select, false); while(hal_gpio_read(device->bus->miso)); - api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); + furi_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); hal_gpio_write(device->chip_select, true); assert((rx[0].CHIP_RDYn) == 0); @@ -45,25 +45,25 @@ CC1101Status cc1101_read_reg(const ApiHalSpiDevice* device, uint8_t reg, uint8_t return rx[0]; } -uint8_t cc1101_get_partnumber(const ApiHalSpiDevice* device) { +uint8_t cc1101_get_partnumber(const FuriHalSpiDevice* device) { uint8_t partnumber=0; cc1101_read_reg(device, CC1101_STATUS_PARTNUM|CC1101_BURST, &partnumber); return partnumber; } -uint8_t cc1101_get_version(const ApiHalSpiDevice* device) { +uint8_t cc1101_get_version(const FuriHalSpiDevice* device) { uint8_t version=0; cc1101_read_reg(device, CC1101_STATUS_VERSION|CC1101_BURST, &version); return version; } -uint8_t cc1101_get_rssi(const ApiHalSpiDevice* device) { +uint8_t cc1101_get_rssi(const FuriHalSpiDevice* device) { uint8_t rssi=0; cc1101_read_reg(device, CC1101_STATUS_RSSI|CC1101_BURST, &rssi); return rssi; } -void cc1101_reset(const ApiHalSpiDevice* device) { +void cc1101_reset(const FuriHalSpiDevice* device) { hal_gpio_write(device->chip_select, false); delay_us(1000); hal_gpio_write(device->chip_select, true); @@ -71,39 +71,39 @@ void cc1101_reset(const ApiHalSpiDevice* device) { cc1101_strobe(device, CC1101_STROBE_SRES); } -CC1101Status cc1101_get_status(const ApiHalSpiDevice* device) { +CC1101Status cc1101_get_status(const FuriHalSpiDevice* device) { return cc1101_strobe(device, CC1101_STROBE_SNOP); } -void cc1101_shutdown(const ApiHalSpiDevice* device) { +void cc1101_shutdown(const FuriHalSpiDevice* device) { cc1101_strobe(device, CC1101_STROBE_SPWD); } -void cc1101_calibrate(const ApiHalSpiDevice* device) { +void cc1101_calibrate(const FuriHalSpiDevice* device) { cc1101_strobe(device, CC1101_STROBE_SCAL); } -void cc1101_switch_to_idle(const ApiHalSpiDevice* device) { +void cc1101_switch_to_idle(const FuriHalSpiDevice* device) { cc1101_strobe(device, CC1101_STROBE_SIDLE); } -void cc1101_switch_to_rx(const ApiHalSpiDevice* device) { +void cc1101_switch_to_rx(const FuriHalSpiDevice* device) { cc1101_strobe(device, CC1101_STROBE_SRX); } -void cc1101_switch_to_tx(const ApiHalSpiDevice* device) { +void cc1101_switch_to_tx(const FuriHalSpiDevice* device) { cc1101_strobe(device, CC1101_STROBE_STX); } -void cc1101_flush_rx(const ApiHalSpiDevice* device) { +void cc1101_flush_rx(const FuriHalSpiDevice* device) { cc1101_strobe(device, CC1101_STROBE_SFRX); } -void cc1101_flush_tx(const ApiHalSpiDevice* device) { +void cc1101_flush_tx(const FuriHalSpiDevice* device) { cc1101_strobe(device, CC1101_STROBE_SFTX); } -uint32_t cc1101_set_frequency(const ApiHalSpiDevice* device, uint32_t value) { +uint32_t cc1101_set_frequency(const FuriHalSpiDevice* device, uint32_t value) { uint64_t real_value = (uint64_t)value * CC1101_FDIV / CC1101_QUARTZ; // Sanity check @@ -118,7 +118,7 @@ uint32_t cc1101_set_frequency(const ApiHalSpiDevice* device, uint32_t value) { return (uint32_t)real_frequency; } -uint32_t cc1101_set_intermediate_frequency(const ApiHalSpiDevice* device, uint32_t value) { +uint32_t cc1101_set_intermediate_frequency(const FuriHalSpiDevice* device, uint32_t value) { uint64_t real_value = value * CC1101_IFDIV / CC1101_QUARTZ; assert((real_value & 0xFF) == real_value); @@ -129,7 +129,7 @@ uint32_t cc1101_set_intermediate_frequency(const ApiHalSpiDevice* device, uint32 return (uint32_t)real_frequency; } -void cc1101_set_pa_table(const ApiHalSpiDevice* device, const uint8_t value[8]) { +void cc1101_set_pa_table(const FuriHalSpiDevice* device, const uint8_t value[8]) { uint8_t tx[9] = { CC1101_PATABLE | CC1101_BURST }; CC1101Status rx[9] = { 0 }; @@ -137,13 +137,13 @@ void cc1101_set_pa_table(const ApiHalSpiDevice* device, const uint8_t value[8]) hal_gpio_write(device->chip_select, false); while(hal_gpio_read(device->bus->miso)); - api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, sizeof(rx), CC1101_TIMEOUT); + furi_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, sizeof(rx), CC1101_TIMEOUT); hal_gpio_write(device->chip_select, true); assert((rx[0].CHIP_RDYn|rx[8].CHIP_RDYn) == 0); } -uint8_t cc1101_write_fifo(const ApiHalSpiDevice* device, const uint8_t* data, uint8_t size) { +uint8_t cc1101_write_fifo(const FuriHalSpiDevice* device, const uint8_t* data, uint8_t size) { uint8_t buff_tx[64]; uint8_t buff_rx[64]; buff_tx[0] = CC1101_FIFO | CC1101_BURST; @@ -154,7 +154,7 @@ uint8_t cc1101_write_fifo(const ApiHalSpiDevice* device, const uint8_t* data, ui // Wait IC to become ready while(hal_gpio_read(device->bus->miso)); // Tell IC what we want - api_hal_spi_bus_trx(device->bus, buff_tx, (uint8_t*) buff_rx, size + 1, CC1101_TIMEOUT); + furi_hal_spi_bus_trx(device->bus, buff_tx, (uint8_t*) buff_rx, size + 1, CC1101_TIMEOUT); // Finish transaction hal_gpio_write(device->chip_select, true); @@ -162,7 +162,7 @@ uint8_t cc1101_write_fifo(const ApiHalSpiDevice* device, const uint8_t* data, ui return size; } -uint8_t cc1101_read_fifo(const ApiHalSpiDevice* device, uint8_t* data, uint8_t* size) { +uint8_t cc1101_read_fifo(const FuriHalSpiDevice* device, uint8_t* data, uint8_t* size) { uint8_t buff_tx[64]; buff_tx[0] = CC1101_FIFO | CC1101_READ | CC1101_BURST; uint8_t buff_rx[2]; @@ -173,9 +173,9 @@ uint8_t cc1101_read_fifo(const ApiHalSpiDevice* device, uint8_t* data, uint8_t* while(hal_gpio_read(device->bus->miso)); // First byte - packet length - api_hal_spi_bus_trx(device->bus, buff_tx, buff_rx, 2, CC1101_TIMEOUT); + furi_hal_spi_bus_trx(device->bus, buff_tx, buff_rx, 2, CC1101_TIMEOUT); *size = buff_rx[2]; - api_hal_spi_bus_trx(device->bus, &buff_tx[1], data, *size, CC1101_TIMEOUT); + furi_hal_spi_bus_trx(device->bus, &buff_tx[1], data, *size, CC1101_TIMEOUT); cc1101_flush_rx(device); hal_gpio_write(device->chip_select, true); diff --git a/lib/drivers/cc1101.h b/lib/drivers/cc1101.h index 242ae70f0f3..295e4b6125a 100644 --- a/lib/drivers/cc1101.h +++ b/lib/drivers/cc1101.h @@ -4,7 +4,7 @@ #include #include -#include +#include #ifdef __cplusplus extern "C" { @@ -13,131 +13,131 @@ extern "C" { /* Low level API */ /** Strobe command to the device - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice * @param strobe - command to execute * @return device status */ -CC1101Status cc1101_strobe(const ApiHalSpiDevice* device, uint8_t strobe); +CC1101Status cc1101_strobe(const FuriHalSpiDevice* device, uint8_t strobe); /** Write device register - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice * @param reg - register * @param data - data to write * @return device status */ -CC1101Status cc1101_write_reg(const ApiHalSpiDevice* device, uint8_t reg, uint8_t data); +CC1101Status cc1101_write_reg(const FuriHalSpiDevice* device, uint8_t reg, uint8_t data); /** Read device register - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice * @param reg - register * @param[out] data - pointer to data * @return device status */ -CC1101Status cc1101_read_reg(const ApiHalSpiDevice* device, uint8_t reg, uint8_t* data); +CC1101Status cc1101_read_reg(const FuriHalSpiDevice* device, uint8_t reg, uint8_t* data); /* High level API */ /** Reset - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice */ -void cc1101_reset(const ApiHalSpiDevice* device); +void cc1101_reset(const FuriHalSpiDevice* device); /** Get status - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice */ -CC1101Status cc1101_get_status(const ApiHalSpiDevice* device); +CC1101Status cc1101_get_status(const FuriHalSpiDevice* device); /** Enable shutdown mode - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice */ -void cc1101_shutdown(const ApiHalSpiDevice* device); +void cc1101_shutdown(const FuriHalSpiDevice* device); /** Get Partnumber - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice */ -uint8_t cc1101_get_partnumber(const ApiHalSpiDevice* device); +uint8_t cc1101_get_partnumber(const FuriHalSpiDevice* device); /** Get Version - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice */ -uint8_t cc1101_get_version(const ApiHalSpiDevice* device); +uint8_t cc1101_get_version(const FuriHalSpiDevice* device); /** Get raw RSSI value - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice */ -uint8_t cc1101_get_rssi(const ApiHalSpiDevice* device); +uint8_t cc1101_get_rssi(const FuriHalSpiDevice* device); /** Calibrate oscillator - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice */ -void cc1101_calibrate(const ApiHalSpiDevice* device); +void cc1101_calibrate(const FuriHalSpiDevice* device); /** Switch to idle - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice */ -void cc1101_switch_to_idle(const ApiHalSpiDevice* device); +void cc1101_switch_to_idle(const FuriHalSpiDevice* device); /** Switch to RX - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice */ -void cc1101_switch_to_rx(const ApiHalSpiDevice* device); +void cc1101_switch_to_rx(const FuriHalSpiDevice* device); /** Switch to TX - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice */ -void cc1101_switch_to_tx(const ApiHalSpiDevice* device); +void cc1101_switch_to_tx(const FuriHalSpiDevice* device); /** Flush RX FIFO - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice */ -void cc1101_flush_rx(const ApiHalSpiDevice* device); +void cc1101_flush_rx(const FuriHalSpiDevice* device); /** Flush TX FIFO - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice */ -void cc1101_flush_tx(const ApiHalSpiDevice* device); +void cc1101_flush_tx(const FuriHalSpiDevice* device); /** Set Frequency - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice * @param value - frequency in herz * @return real frequency that were synthesized */ -uint32_t cc1101_set_frequency(const ApiHalSpiDevice* device, uint32_t value); +uint32_t cc1101_set_frequency(const FuriHalSpiDevice* device, uint32_t value); /** Set Intermediate Frequency - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice * @param value - frequency in herz * @return real inermediate frequency that were synthesized */ -uint32_t cc1101_set_intermediate_frequency(const ApiHalSpiDevice* device, uint32_t value); +uint32_t cc1101_set_intermediate_frequency(const FuriHalSpiDevice* device, uint32_t value); /** Set Power Amplifier level table, ramp - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice * @param value - array of power level values */ -void cc1101_set_pa_table(const ApiHalSpiDevice* device, const uint8_t value[8]); +void cc1101_set_pa_table(const FuriHalSpiDevice* device, const uint8_t value[8]); /** Set Power Amplifier level table, ramp - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice * @param value - array of power level values */ -void cc1101_set_pa_table(const ApiHalSpiDevice* device, const uint8_t value[8]); +void cc1101_set_pa_table(const FuriHalSpiDevice* device, const uint8_t value[8]); /** Write FIFO - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice * @param data, pointer to byte array * @param size, write bytes count * @return size, written bytes count */ -uint8_t cc1101_write_fifo(const ApiHalSpiDevice* device, const uint8_t* data, uint8_t size); +uint8_t cc1101_write_fifo(const FuriHalSpiDevice* device, const uint8_t* data, uint8_t size); /** Read FIFO - * @param device - pointer to ApiHalSpiDevice + * @param device - pointer to FuriHalSpiDevice * @param data, pointer to byte array * @param size, bytes to read from fifo * @return size, read bytes count */ -uint8_t cc1101_read_fifo(const ApiHalSpiDevice* device, uint8_t* data, uint8_t* size); +uint8_t cc1101_read_fifo(const FuriHalSpiDevice* device, uint8_t* data, uint8_t* size); #ifdef __cplusplus } diff --git a/lib/drivers/lp5562.c b/lib/drivers/lp5562.c index 1f3f8e8bd61..954fa65e5ef 100644 --- a/lib/drivers/lp5562.c +++ b/lib/drivers/lp5562.c @@ -1,15 +1,15 @@ #include "lp5562.h" #include "lp5562_reg.h" -#include +#include #include bool lp5562_write_reg(uint8_t address, uint8_t* data) { uint8_t buffer[2] = {address, *data}; bool ret; - with_api_hal_i2c( + with_furi_hal_i2c( bool, &ret, () { - return api_hal_i2c_tx(POWER_I2C, LP5562_ADDRESS, buffer, 2, LP5562_I2C_TIMEOUT); + return furi_hal_i2c_tx(POWER_I2C, LP5562_ADDRESS, buffer, 2, LP5562_I2C_TIMEOUT); }); return ret; } diff --git a/lib/irda/encoder_decoder/irda.c b/lib/irda/encoder_decoder/irda.c index da6e17d10ba..6c7866d19c2 100644 --- a/lib/irda/encoder_decoder/irda.c +++ b/lib/irda/encoder_decoder/irda.c @@ -7,7 +7,7 @@ #include #include #include "irda_i.h" -#include +#include struct IrdaDecoderHandler { void** ctx; @@ -34,6 +34,8 @@ typedef struct { IrdaEncoders encoder; uint8_t address_length; uint8_t command_length; + uint32_t frequency; + float duty_cycle; } IrdaProtocolImplementation; struct IrdaEncoderHandler { @@ -58,6 +60,8 @@ static const IrdaProtocolImplementation irda_protocols[] = { .free = irda_encoder_nec_free}, .address_length = 2, .command_length = 2, + .frequency = IRDA_COMMON_CARRIER_FREQUENCY, + .duty_cycle = IRDA_COMMON_DUTY_CYCLE, }, // #1 - have to be after NEC { .protocol = IrdaProtocolNECext, @@ -74,6 +78,8 @@ static const IrdaProtocolImplementation irda_protocols[] = { .free = irda_encoder_nec_free}, .address_length = 4, .command_length = 2, + .frequency = IRDA_COMMON_CARRIER_FREQUENCY, + .duty_cycle = IRDA_COMMON_DUTY_CYCLE, }, // #2 { .protocol = IrdaProtocolSamsung32, @@ -90,6 +96,8 @@ static const IrdaProtocolImplementation irda_protocols[] = { .free = irda_encoder_samsung32_free}, .address_length = 2, .command_length = 2, + .frequency = IRDA_COMMON_CARRIER_FREQUENCY, + .duty_cycle = IRDA_COMMON_DUTY_CYCLE, }, // #3 { .protocol = IrdaProtocolRC6, @@ -106,6 +114,8 @@ static const IrdaProtocolImplementation irda_protocols[] = { .free = irda_encoder_rc6_free}, .address_length = 2, .command_length = 2, + .frequency = IRDA_COMMON_CARRIER_FREQUENCY, + .duty_cycle = IRDA_COMMON_DUTY_CYCLE, }, }; @@ -222,10 +232,12 @@ IrdaProtocol irda_get_protocol_by_name(const char* protocol_name) { if (!strcmp(irda_protocols[i].name, protocol_name)) return i; } + furi_assert(0); return IrdaProtocolUnknown; } const char* irda_get_protocol_name(IrdaProtocol protocol) { + furi_assert(irda_is_protocol_valid(protocol)); if (irda_is_protocol_valid(protocol)) return irda_protocols[protocol].name; else @@ -233,6 +245,7 @@ const char* irda_get_protocol_name(IrdaProtocol protocol) { } uint8_t irda_get_protocol_address_length(IrdaProtocol protocol) { + furi_assert(irda_is_protocol_valid(protocol)); if (irda_is_protocol_valid(protocol)) return irda_protocols[protocol].address_length; else @@ -240,9 +253,26 @@ uint8_t irda_get_protocol_address_length(IrdaProtocol protocol) { } uint8_t irda_get_protocol_command_length(IrdaProtocol protocol) { + furi_assert(irda_is_protocol_valid(protocol)); if (irda_is_protocol_valid(protocol)) return irda_protocols[protocol].command_length; else return 0; } +uint32_t irda_get_protocol_frequency(IrdaProtocol protocol) { + furi_assert(irda_is_protocol_valid(protocol)); + if (irda_is_protocol_valid(protocol)) + return irda_protocols[protocol].frequency; + else + return 0; +} + +float irda_get_protocol_duty_cycle(IrdaProtocol protocol) { + furi_assert(irda_is_protocol_valid(protocol)); + if (irda_is_protocol_valid(protocol)) + return irda_protocols[protocol].duty_cycle; + else + return 0; +} + diff --git a/lib/irda/encoder_decoder/irda.h b/lib/irda/encoder_decoder/irda.h index 2c3a7ac1b3f..954be8183e9 100644 --- a/lib/irda/encoder_decoder/irda.h +++ b/lib/irda/encoder_decoder/irda.h @@ -10,6 +10,12 @@ extern "C" { #define IRDA_COMMON_CARRIER_FREQUENCY 38000 #define IRDA_COMMON_DUTY_CYCLE 0.33 +/* if we want to see splitted raw signals during brutforce, + * we have to have RX raw timing delay less than TX */ +#define IRDA_RAW_RX_TIMING_DELAY_US 150000 +#define IRDA_RAW_TX_TIMING_DELAY_US 180000 + + typedef struct IrdaDecoderHandler IrdaDecoderHandler; typedef struct IrdaEncoderHandler IrdaEncoderHandler; @@ -150,6 +156,24 @@ IrdaStatus irda_encode(IrdaEncoderHandler* handler, uint32_t* duration, bool* le */ void irda_reset_encoder(IrdaEncoderHandler* handler, const IrdaMessage* message); +/** + * Get PWM frequency value for selected protocol + * + * \param[in] protocol - protocol to get from PWM frequency + * + * \return frequency + */ +uint32_t irda_get_protocol_frequency(IrdaProtocol protocol); + +/** + * Get PWM duty cycle value for selected protocol + * + * \param[in] protocol - protocol to get from PWM duty cycle + * + * \return duty cycle + */ +float irda_get_protocol_duty_cycle(IrdaProtocol protocol); + #ifdef __cplusplus } #endif diff --git a/lib/irda/encoder_decoder/irda_protocol_defs_i.h b/lib/irda/encoder_decoder/irda_protocol_defs_i.h index ee2320a4215..9c4e5ae9d8a 100644 --- a/lib/irda/encoder_decoder/irda_protocol_defs_i.h +++ b/lib/irda/encoder_decoder/irda_protocol_defs_i.h @@ -137,7 +137,8 @@ extern const IrdaCommonProtocolSpec protocol_samsung32; #define IRDA_RC6_BIT 444 // half of time-quant for 1 bit #define IRDA_RC6_PREAMBLE_TOLERANCE 0.07 // percents #define IRDA_RC6_BIT_TOLERANCE 120 // us -#define IRDA_RC6_SILENCE 2700 +/* protocol allows 2700 silence, but it is hard to send 1 message without repeat */ +#define IRDA_RC6_SILENCE (2700 * 10) void* irda_decoder_rc6_alloc(void); void irda_decoder_rc6_reset(void* decoder); diff --git a/lib/irda/worker/irda_transmit.c b/lib/irda/worker/irda_transmit.c index d06bf46084e..e87de6ca1f6 100644 --- a/lib/irda/worker/irda_transmit.c +++ b/lib/irda/worker/irda_transmit.c @@ -3,8 +3,8 @@ #include #include #include -#include -#include +#include +#include static uint32_t irda_tx_number_of_transmissions = 0; static uint32_t irda_tx_raw_timings_index = 0; @@ -12,25 +12,25 @@ static uint32_t irda_tx_raw_timings_number = 0; static uint32_t irda_tx_raw_start_from_mark = 0; static bool irda_tx_raw_add_silence = false; -ApiHalIrdaTxGetDataState irda_get_raw_data_callback (void* context, uint32_t* duration, bool* level) { +FuriHalIrdaTxGetDataState irda_get_raw_data_callback (void* context, uint32_t* duration, bool* level) { furi_assert(duration); furi_assert(level); furi_assert(context); - ApiHalIrdaTxGetDataState state = ApiHalIrdaTxGetDataStateOk; + FuriHalIrdaTxGetDataState state = FuriHalIrdaTxGetDataStateOk; const uint32_t* timings = context; if (irda_tx_raw_add_silence && (irda_tx_raw_timings_index == 0)) { irda_tx_raw_add_silence = false; *level = false; - *duration = 180000; // 180 ms delay between raw packets + *duration = IRDA_RAW_TX_TIMING_DELAY_US; } else { *level = irda_tx_raw_start_from_mark ^ (irda_tx_raw_timings_index % 2); *duration = timings[irda_tx_raw_timings_index++]; } if (irda_tx_raw_timings_number == irda_tx_raw_timings_index) { - state = ApiHalIrdaTxGetDataStateLastDone; + state = FuriHalIrdaTxGetDataStateLastDone; } return state; @@ -44,19 +44,19 @@ void irda_send_raw_ext(const uint32_t timings[], uint32_t timings_cnt, bool star irda_tx_raw_timings_index = 0; irda_tx_raw_timings_number = timings_cnt; irda_tx_raw_add_silence = start_from_mark; - api_hal_irda_async_tx_set_data_isr_callback(irda_get_raw_data_callback, (void*) timings); - api_hal_irda_async_tx_start(frequency, duty_cycle); - api_hal_irda_async_tx_wait_termination(); + furi_hal_irda_async_tx_set_data_isr_callback(irda_get_raw_data_callback, (void*) timings); + furi_hal_irda_async_tx_start(frequency, duty_cycle); + furi_hal_irda_async_tx_wait_termination(); - furi_assert(!api_hal_irda_is_busy()); + furi_assert(!furi_hal_irda_is_busy()); } void irda_send_raw(const uint32_t timings[], uint32_t timings_cnt, bool start_from_mark) { irda_send_raw_ext(timings, timings_cnt, start_from_mark, IRDA_COMMON_CARRIER_FREQUENCY, IRDA_COMMON_DUTY_CYCLE); } -ApiHalIrdaTxGetDataState irda_get_data_callback (void* context, uint32_t* duration, bool* level) { - ApiHalIrdaTxGetDataState state = ApiHalIrdaTxGetDataStateError; +FuriHalIrdaTxGetDataState irda_get_data_callback (void* context, uint32_t* duration, bool* level) { + FuriHalIrdaTxGetDataState state = FuriHalIrdaTxGetDataStateError; IrdaEncoderHandler* handler = context; IrdaStatus status = IrdaStatusError; @@ -65,17 +65,17 @@ ApiHalIrdaTxGetDataState irda_get_data_callback (void* context, uint32_t* durati } if (status == IrdaStatusError) { - state = ApiHalIrdaTxGetDataStateError; + state = FuriHalIrdaTxGetDataStateError; } else if (status == IrdaStatusOk) { - state = ApiHalIrdaTxGetDataStateOk; + state = FuriHalIrdaTxGetDataStateOk; } else if (status == IrdaStatusDone) { - state = ApiHalIrdaTxGetDataStateDone; + state = FuriHalIrdaTxGetDataStateDone; if (--irda_tx_number_of_transmissions == 0) { - state = ApiHalIrdaTxGetDataStateLastDone; + state = FuriHalIrdaTxGetDataStateLastDone; } } else { furi_assert(0); - state = ApiHalIrdaTxGetDataStateError; + state = FuriHalIrdaTxGetDataStateError; } return state; @@ -90,12 +90,12 @@ void irda_send(const IrdaMessage* message, int times) { irda_reset_encoder(handler, message); irda_tx_number_of_transmissions = times; - api_hal_irda_async_tx_set_data_isr_callback(irda_get_data_callback, handler); - api_hal_irda_async_tx_start(IRDA_COMMON_CARRIER_FREQUENCY, IRDA_COMMON_DUTY_CYCLE); - api_hal_irda_async_tx_wait_termination(); + furi_hal_irda_async_tx_set_data_isr_callback(irda_get_data_callback, handler); + furi_hal_irda_async_tx_start(IRDA_COMMON_CARRIER_FREQUENCY, IRDA_COMMON_DUTY_CYCLE); + furi_hal_irda_async_tx_wait_termination(); irda_free_encoder(handler); - furi_assert(!api_hal_irda_is_busy()); + furi_assert(!furi_hal_irda_is_busy()); } diff --git a/lib/irda/worker/irda_transmit.h b/lib/irda/worker/irda_transmit.h index 9d56019eba7..1a6edcc3f7a 100644 --- a/lib/irda/worker/irda_transmit.h +++ b/lib/irda/worker/irda_transmit.h @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/lib/irda/worker/irda_worker.c b/lib/irda/worker/irda_worker.c index 45ea7dfc15f..041ea090c6c 100644 --- a/lib/irda/worker/irda_worker.c +++ b/lib/irda/worker/irda_worker.c @@ -1,20 +1,45 @@ +#include "furi/check.h" +#include "furi/common_defines.h" +#include "sys/_stdint.h" #include "irda_worker.h" #include -#include +#include #include #include -#include #include #include +#include + +#define IRDA_WORKER_RX_TIMEOUT IRDA_RAW_RX_TIMING_DELAY_US -#define MAX_TIMINGS_AMOUNT 500 -#define IRDA_WORKER_RX_TIMEOUT 150 // ms #define IRDA_WORKER_RX_RECEIVED 0x01 #define IRDA_WORKER_RX_TIMEOUT_RECEIVED 0x02 #define IRDA_WORKER_OVERRUN 0x04 #define IRDA_WORKER_EXIT 0x08 - -struct IrdaWorkerSignal { +#define IRDA_WORKER_TX_FILL_BUFFER 0x10 +#define IRDA_WORKER_TX_MESSAGE_SENT 0x20 + +#define IRDA_WORKER_ALL_RX_EVENTS (IRDA_WORKER_RX_RECEIVED \ + | IRDA_WORKER_RX_TIMEOUT_RECEIVED \ + | IRDA_WORKER_OVERRUN \ + | IRDA_WORKER_EXIT) + +#define IRDA_WORKER_ALL_TX_EVENTS (IRDA_WORKER_TX_FILL_BUFFER \ + | IRDA_WORKER_TX_MESSAGE_SENT \ + | IRDA_WORKER_EXIT) + +#define IRDA_WORKER_ALL_EVENTS (IRDA_WORKER_ALL_RX_EVENTS | IRDA_WORKER_ALL_TX_EVENTS) + +typedef enum { + IrdaWorkerStateIdle, + IrdaWorkerStateRunRx, + IrdaWorkerStateRunTx, + IrdaWorkerStateWaitTxEnd, + IrdaWorkerStateStopTx, + IrdaWorkerStateStartTx, +} IrdaWorkerState; + +struct IrdaWorkerSignal{ bool decoded; size_t timings_cnt; union { @@ -25,37 +50,67 @@ struct IrdaWorkerSignal { struct IrdaWorker { FuriThread* thread; - IrdaDecoderHandler* irda_decoder; StreamBufferHandle_t stream; + osEventFlagsId_t events; - TaskHandle_t worker_handle; IrdaWorkerSignal signal; - - IrdaWorkerReceivedSignalCallback received_signal_callback; - void* context; - bool blink_enable; - bool overrun; + IrdaWorkerState state; + IrdaEncoderHandler* irda_encoder; + IrdaDecoderHandler* irda_decoder; NotificationApp* notification; + bool blink_enable; + + union { + struct { + IrdaWorkerGetSignalCallback get_signal_callback; + IrdaWorkerMessageSentCallback message_sent_callback; + void* get_signal_context; + void* message_sent_context; + uint32_t frequency; + float duty_cycle; + uint32_t tx_raw_cnt; + bool need_reinitialization; + bool steady_signal_sent; + } tx; + struct { + IrdaWorkerReceivedSignalCallback received_signal_callback; + void* received_signal_context; + bool overrun; + } rx; + }; }; +typedef struct { + uint32_t duration; + bool level; + FuriHalIrdaTxGetDataState state; +} IrdaWorkerTiming; + +static int32_t irda_worker_tx_thread(void* context); +static FuriHalIrdaTxGetDataState irda_worker_furi_hal_data_isr_callback(void* context, uint32_t* duration, bool* level); +static void irda_worker_furi_hal_message_sent_isr_callback(void* context); + + static void irda_worker_rx_timeout_callback(void* context) { IrdaWorker* instance = context; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - xTaskNotifyFromISR(instance->worker_handle, IRDA_WORKER_RX_TIMEOUT_RECEIVED, eSetBits, &xHigherPriorityTaskWoken); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + uint32_t flags_set = osEventFlagsSet(instance->events, IRDA_WORKER_RX_TIMEOUT_RECEIVED); + furi_check(flags_set & IRDA_WORKER_RX_TIMEOUT_RECEIVED); } static void irda_worker_rx_callback(void* context, bool level, uint32_t duration) { IrdaWorker* instance = context; BaseType_t xHigherPriorityTaskWoken = pdFALSE; + furi_assert(duration != 0); LevelDuration level_duration = level_duration_make(level, duration); size_t ret = xStreamBufferSendFromISR(instance->stream, &level_duration, sizeof(LevelDuration), &xHigherPriorityTaskWoken); - uint32_t notify_value = (ret == sizeof(LevelDuration)) ? IRDA_WORKER_RX_RECEIVED : IRDA_WORKER_OVERRUN; - xTaskNotifyFromISR(instance->worker_handle, notify_value, eSetBits, &xHigherPriorityTaskWoken); + uint32_t events = (ret == sizeof(LevelDuration)) ? IRDA_WORKER_RX_RECEIVED : IRDA_WORKER_OVERRUN; portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + + uint32_t flags_set = osEventFlagsSet(instance->events, events); + furi_check(flags_set & events); } static void irda_worker_process_timeout(IrdaWorker* instance) { @@ -63,8 +118,8 @@ static void irda_worker_process_timeout(IrdaWorker* instance) { return; instance->signal.decoded = false; - if (instance->received_signal_callback) - instance->received_signal_callback(instance->context, &instance->signal); + if (instance->rx.received_signal_callback) + instance->rx.received_signal_callback(instance->rx.received_signal_context, &instance->signal); } static void irda_worker_process_timings(IrdaWorker* instance, uint32_t duration, bool level) { @@ -73,8 +128,8 @@ static void irda_worker_process_timings(IrdaWorker* instance, uint32_t duration, instance->signal.data.message = *message_decoded; instance->signal.timings_cnt = 0; instance->signal.decoded = true; - if (instance->received_signal_callback) - instance->received_signal_callback(instance->context, &instance->signal); + if (instance->rx.received_signal_callback) + instance->rx.received_signal_callback(instance->rx.received_signal_context, &instance->signal); } else { /* Skip first timing if it's starts from Space */ if ((instance->signal.timings_cnt == 0) && !level) { @@ -85,50 +140,49 @@ static void irda_worker_process_timings(IrdaWorker* instance, uint32_t duration, instance->signal.data.timings[instance->signal.timings_cnt] = duration; ++instance->signal.timings_cnt; } else { - xTaskNotify(instance->worker_handle, IRDA_WORKER_OVERRUN, eSetBits); - instance->overrun = true; + uint32_t flags_set = osEventFlagsSet(instance->events, IRDA_WORKER_OVERRUN); + furi_check(flags_set & IRDA_WORKER_OVERRUN); + instance->rx.overrun = true; } } } -static int32_t irda_worker_thread_callback(void* context) { - IrdaWorker* instance = context; - uint32_t notify_value = 0; +static int32_t irda_worker_rx_thread(void* thread_context) { + IrdaWorker* instance = thread_context; + uint32_t events = 0; LevelDuration level_duration; TickType_t last_blink_time = 0; while(1) { - BaseType_t result; - result = xTaskNotifyWait(pdFALSE, ULONG_MAX, ¬ify_value, 1000); - if (result != pdPASS) - continue; + events = osEventFlagsWait(instance->events, IRDA_WORKER_ALL_RX_EVENTS, 0, osWaitForever); + furi_check(events & IRDA_WORKER_ALL_RX_EVENTS); /* at least one caught */ - if (notify_value & IRDA_WORKER_RX_RECEIVED) { - if (!instance->overrun && instance->blink_enable && ((xTaskGetTickCount() - last_blink_time) > 80)) { + if (events & IRDA_WORKER_RX_RECEIVED) { + if (!instance->rx.overrun && instance->blink_enable && ((xTaskGetTickCount() - last_blink_time) > 80)) { last_blink_time = xTaskGetTickCount(); notification_message(instance->notification, &sequence_blink_blue_10); } if (instance->signal.timings_cnt == 0) notification_message(instance->notification, &sequence_display_on); while (sizeof(LevelDuration) == xStreamBufferReceive(instance->stream, &level_duration, sizeof(LevelDuration), 0)) { - if (!instance->overrun) { + if (!instance->rx.overrun) { bool level = level_duration_get_level(level_duration); uint32_t duration = level_duration_get_duration(level_duration); irda_worker_process_timings(instance, duration, level); } } } - if (notify_value & IRDA_WORKER_OVERRUN) { + if (events & IRDA_WORKER_OVERRUN) { printf("#"); irda_reset_decoder(instance->irda_decoder); instance->signal.timings_cnt = 0; if (instance->blink_enable) notification_message(instance->notification, &sequence_set_red_255); } - if (notify_value & IRDA_WORKER_RX_TIMEOUT_RECEIVED) { - if (instance->overrun) { + if (events & IRDA_WORKER_RX_TIMEOUT_RECEIVED) { + if (instance->rx.overrun) { printf("\nOVERRUN, max samples: %d\n", MAX_TIMINGS_AMOUNT); - instance->overrun = false; + instance->rx.overrun = false; if (instance->blink_enable) notification_message(instance->notification, &sequence_reset_red); } else { @@ -136,16 +190,17 @@ static int32_t irda_worker_thread_callback(void* context) { } instance->signal.timings_cnt = 0; } - if (notify_value & IRDA_WORKER_EXIT) + if (events & IRDA_WORKER_EXIT) break; } return 0; } -void irda_worker_set_received_signal_callback(IrdaWorker* instance, IrdaWorkerReceivedSignalCallback callback) { +void irda_worker_rx_set_received_signal_callback(IrdaWorker* instance, IrdaWorkerReceivedSignalCallback callback, void* context) { furi_assert(instance); - instance->received_signal_callback = callback; + instance->rx.received_signal_callback = callback; + instance->rx.received_signal_context = context; } IrdaWorker* irda_worker_alloc() { @@ -155,60 +210,67 @@ IrdaWorker* irda_worker_alloc() { furi_thread_set_name(instance->thread, "irda_worker"); furi_thread_set_stack_size(instance->thread, 2048); furi_thread_set_context(instance->thread, instance); - furi_thread_set_callback(instance->thread, irda_worker_thread_callback); - - instance->stream = xStreamBufferCreate(sizeof(LevelDuration) * 512, sizeof(LevelDuration)); + size_t buffer_size = MAX(sizeof(IrdaWorkerTiming) * MAX_TIMINGS_AMOUNT, sizeof(LevelDuration) * MAX_TIMINGS_AMOUNT); + instance->stream = xStreamBufferCreate(buffer_size, sizeof(IrdaWorkerTiming)); instance->irda_decoder = irda_alloc_decoder(); + instance->irda_encoder = irda_alloc_encoder(); instance->blink_enable = false; instance->notification = furi_record_open("notification"); + instance->state = IrdaWorkerStateIdle; + instance->events = osEventFlagsNew(NULL); return instance; } void irda_worker_free(IrdaWorker* instance) { furi_assert(instance); - furi_assert(!instance->worker_handle); + furi_assert(instance->state == IrdaWorkerStateIdle); furi_record_close("notification"); irda_free_decoder(instance->irda_decoder); + irda_free_encoder(instance->irda_encoder); vStreamBufferDelete(instance->stream); furi_thread_free(instance->thread); + osEventFlagsDelete(instance->events); free(instance); } -void irda_worker_set_context(IrdaWorker* instance, void* context) { +void irda_worker_rx_start(IrdaWorker* instance) { furi_assert(instance); - instance->context = context; -} + furi_assert(instance->state == IrdaWorkerStateIdle); -void irda_worker_start(IrdaWorker* instance) { - furi_assert(instance); - furi_assert(!instance->worker_handle); + xStreamBufferSetTriggerLevel(instance->stream, sizeof(LevelDuration)); + osEventFlagsClear(instance->events, IRDA_WORKER_ALL_EVENTS); + furi_thread_set_callback(instance->thread, irda_worker_rx_thread); furi_thread_start(instance->thread); - instance->worker_handle = furi_thread_get_thread_id(instance->thread); - api_hal_irda_async_rx_start(); - api_hal_irda_async_rx_set_timeout(IRDA_WORKER_RX_TIMEOUT); - api_hal_irda_async_rx_set_capture_isr_callback(irda_worker_rx_callback, instance); - api_hal_irda_async_rx_set_timeout_isr_callback(irda_worker_rx_timeout_callback, instance); + furi_hal_irda_async_rx_set_capture_isr_callback(irda_worker_rx_callback, instance); + furi_hal_irda_async_rx_set_timeout_isr_callback(irda_worker_rx_timeout_callback, instance); + furi_hal_irda_async_rx_start(); + furi_hal_irda_async_rx_set_timeout(IRDA_WORKER_RX_TIMEOUT); + + instance->state = IrdaWorkerStateRunRx; } -void irda_worker_stop(IrdaWorker* instance) { +void irda_worker_rx_stop(IrdaWorker* instance) { furi_assert(instance); - furi_assert(instance->worker_handle); + furi_assert(instance->state == IrdaWorkerStateRunRx); - api_hal_irda_async_rx_set_timeout_isr_callback(NULL, NULL); - api_hal_irda_async_rx_set_capture_isr_callback(NULL, NULL); - api_hal_irda_async_rx_stop(); - - xTaskNotify(instance->worker_handle, IRDA_WORKER_EXIT, eSetBits); - - instance->worker_handle = NULL; + furi_hal_irda_async_rx_set_timeout_isr_callback(NULL, NULL); + furi_hal_irda_async_rx_set_capture_isr_callback(NULL, NULL); + furi_hal_irda_async_rx_stop(); + osEventFlagsSet(instance->events, IRDA_WORKER_EXIT); furi_thread_join(instance->thread); + + BaseType_t xReturn = pdFAIL; + xReturn = xStreamBufferReset(instance->stream); + furi_assert(xReturn == pdPASS); + instance->state = IrdaWorkerStateIdle; + instance->state = IrdaWorkerStateIdle; } bool irda_worker_signal_is_decoded(const IrdaWorkerSignal* signal) { @@ -225,13 +287,268 @@ void irda_worker_get_raw_signal(const IrdaWorkerSignal* signal, const uint32_t** *timings_cnt = signal->timings_cnt; } -const IrdaMessage* irda_worker_get_decoded_message(const IrdaWorkerSignal* signal) { +const IrdaMessage* irda_worker_get_decoded_signal(const IrdaWorkerSignal* signal) { furi_assert(signal); return &signal->data.message; } -void irda_worker_enable_blink_on_receiving(IrdaWorker* instance, bool enable) { +void irda_worker_rx_enable_blink_on_receiving(IrdaWorker* instance, bool enable) { furi_assert(instance); instance->blink_enable = enable; } +void irda_worker_tx_start(IrdaWorker* instance) { + furi_assert(instance); + furi_assert(instance->state == IrdaWorkerStateIdle); + + // size have to be greater than api hal irda async tx buffer size + xStreamBufferSetTriggerLevel(instance->stream, sizeof(IrdaWorkerTiming)); + + osEventFlagsClear(instance->events, IRDA_WORKER_ALL_EVENTS); + furi_thread_set_callback(instance->thread, irda_worker_tx_thread); + furi_thread_start(instance->thread); + + instance->tx.steady_signal_sent = false; + instance->tx.need_reinitialization = false; + furi_hal_irda_async_tx_set_data_isr_callback(irda_worker_furi_hal_data_isr_callback, instance); + furi_hal_irda_async_tx_set_signal_sent_isr_callback(irda_worker_furi_hal_message_sent_isr_callback, instance); + + instance->state = IrdaWorkerStateStartTx; +} + +static void irda_worker_furi_hal_message_sent_isr_callback(void* context) { + IrdaWorker* instance = context; + uint32_t flags_set = osEventFlagsSet(instance->events, IRDA_WORKER_TX_MESSAGE_SENT); + furi_check(flags_set & IRDA_WORKER_TX_MESSAGE_SENT); +} + +static FuriHalIrdaTxGetDataState irda_worker_furi_hal_data_isr_callback(void* context, uint32_t* duration, bool* level) { + furi_assert(context); + furi_assert(duration); + furi_assert(level); + + IrdaWorker* instance = context; + IrdaWorkerTiming timing = {.state = FuriHalIrdaTxGetDataStateError} ; + + if (sizeof(IrdaWorkerTiming) == xStreamBufferReceiveFromISR(instance->stream, &timing, sizeof(IrdaWorkerTiming), 0)) { + *level = timing.level; + *duration = timing.duration; + furi_assert(timing.state != FuriHalIrdaTxGetDataStateError); + } else { + furi_assert(0); + timing.state = FuriHalIrdaTxGetDataStateError; + } + + uint32_t flags_set = osEventFlagsSet(instance->events, IRDA_WORKER_TX_FILL_BUFFER); + furi_check(flags_set & IRDA_WORKER_TX_FILL_BUFFER); + + return timing.state; +} + +static bool irda_get_new_signal(IrdaWorker* instance) { + bool new_signal_obtained = false; + + IrdaWorkerGetSignalResponse response = instance->tx.get_signal_callback(instance->tx.get_signal_context, instance); + if (response == IrdaWorkerGetSignalResponseNew) { + uint32_t new_tx_frequency = 0; + float new_tx_duty_cycle = 0; + if (instance->signal.decoded) { + new_tx_frequency = irda_get_protocol_frequency(instance->signal.data.message.protocol); + new_tx_duty_cycle = irda_get_protocol_duty_cycle(instance->signal.data.message.protocol); + } else { + furi_assert(instance->signal.timings_cnt > 1); + new_tx_frequency = IRDA_COMMON_CARRIER_FREQUENCY; + new_tx_duty_cycle = IRDA_COMMON_DUTY_CYCLE; + } + + instance->tx.tx_raw_cnt = 0; + instance->tx.need_reinitialization = (new_tx_frequency != instance->tx.frequency) || (new_tx_duty_cycle != instance->tx.duty_cycle); + instance->tx.frequency = new_tx_frequency; + instance->tx.duty_cycle = new_tx_duty_cycle; + if (instance->signal.decoded) { + irda_reset_encoder(instance->irda_encoder, &instance->signal.data.message); + } + new_signal_obtained = true; + } else if (response == IrdaWorkerGetSignalResponseSame) { + new_signal_obtained = true; + /* no need to reinit */ + } else if (response == IrdaWorkerGetSignalResponseStop) { + new_signal_obtained = false; + } else { + furi_assert(0); + } + + return new_signal_obtained; +} + +static bool irda_worker_tx_fill_buffer(IrdaWorker* instance) { + bool new_data_available = true; + IrdaWorkerTiming timing; + IrdaStatus status = IrdaStatusError; + + while(!xStreamBufferIsFull(instance->stream) && !instance->tx.need_reinitialization && new_data_available) { + if (instance->signal.decoded) { + status = irda_encode(instance->irda_encoder, &timing.duration, &timing.level); + } else { + timing.duration = instance->signal.data.timings[instance->tx.tx_raw_cnt]; +/* raw always starts from Mark, but we fulfill it with space delay at start */ + timing.level = (instance->tx.tx_raw_cnt % 2); + ++instance->tx.tx_raw_cnt; + if (instance->tx.tx_raw_cnt >= instance->signal.timings_cnt) { + instance->tx.tx_raw_cnt = 0; + status = IrdaStatusDone; + } else { + status = IrdaStatusOk; + } + } + + if (status == IrdaStatusError) { + furi_assert(0); + new_data_available = false; + break; + } else if (status == IrdaStatusOk) { + timing.state = FuriHalIrdaTxGetDataStateOk; + } else if (status == IrdaStatusDone) { + timing.state = FuriHalIrdaTxGetDataStateDone; + + new_data_available = irda_get_new_signal(instance); + if (instance->tx.need_reinitialization || !new_data_available) { + timing.state = FuriHalIrdaTxGetDataStateLastDone; + } + } else { + furi_assert(0); + } + uint32_t written_size = xStreamBufferSend(instance->stream, &timing, sizeof(IrdaWorkerTiming), 0); + furi_assert(sizeof(IrdaWorkerTiming) == written_size); + } + + return new_data_available; +} + +static int32_t irda_worker_tx_thread(void* thread_context) { + IrdaWorker* instance = thread_context; + furi_assert(instance->state == IrdaWorkerStateStartTx); + furi_assert(thread_context); + + uint32_t events = 0; + bool new_data_available = true; + bool exit = false; + + exit = !irda_get_new_signal(instance); + furi_assert(!exit); + + while(!exit) { + switch (instance->state) { + case IrdaWorkerStateStartTx: + instance->tx.need_reinitialization = false; + new_data_available = irda_worker_tx_fill_buffer(instance); + furi_hal_irda_async_tx_start(instance->tx.frequency, instance->tx.duty_cycle); + + if (!new_data_available) { + instance->state = IrdaWorkerStateStopTx; + } else if (instance->tx.need_reinitialization) { + instance->state = IrdaWorkerStateWaitTxEnd; + } else { + instance->state = IrdaWorkerStateRunTx; + } + + break; + case IrdaWorkerStateStopTx: + furi_hal_irda_async_tx_stop(); + exit = true; + break; + case IrdaWorkerStateWaitTxEnd: + furi_hal_irda_async_tx_wait_termination(); + instance->state = IrdaWorkerStateStartTx; + + events = osEventFlagsGet(instance->events); + if(events & IRDA_WORKER_EXIT) { + exit = true; + break; + } + + break; + case IrdaWorkerStateRunTx: + events = osEventFlagsWait(instance->events, IRDA_WORKER_ALL_TX_EVENTS, 0, osWaitForever); + furi_check(events & IRDA_WORKER_ALL_TX_EVENTS); /* at least one caught */ + + if (events & IRDA_WORKER_EXIT) { + instance->state = IrdaWorkerStateStopTx; + break; + } + + if (events & IRDA_WORKER_TX_FILL_BUFFER) { + irda_worker_tx_fill_buffer(instance); + + if (instance->tx.need_reinitialization) { + instance->state = IrdaWorkerStateWaitTxEnd; + } + } + + if (events & IRDA_WORKER_TX_MESSAGE_SENT) { + if (instance->tx.message_sent_callback) + instance->tx.message_sent_callback(instance->tx.message_sent_context); + } + break; + default: + furi_assert(0); + break; + } + } + + return 0; +} + +void irda_worker_tx_set_get_signal_callback(IrdaWorker* instance, IrdaWorkerGetSignalCallback callback, void* context) { + furi_assert(instance); + instance->tx.get_signal_callback = callback; + instance->tx.get_signal_context = context; +} + +void irda_worker_tx_set_signal_sent_callback(IrdaWorker* instance, IrdaWorkerMessageSentCallback callback, void* context) { + furi_assert(instance); + instance->tx.message_sent_callback = callback; + instance->tx.message_sent_context = context; +} + +void irda_worker_tx_stop(IrdaWorker* instance) { + furi_assert(instance); + furi_assert(instance->state != IrdaWorkerStateRunRx); + + osEventFlagsSet(instance->events, IRDA_WORKER_EXIT); + furi_thread_join(instance->thread); + furi_hal_irda_async_tx_set_data_isr_callback(NULL, NULL); + furi_hal_irda_async_tx_set_signal_sent_isr_callback(NULL, NULL); + + instance->signal.timings_cnt = 0; + BaseType_t xReturn = pdFAIL; + xReturn = xStreamBufferReset(instance->stream); + furi_assert(xReturn == pdPASS); + instance->state = IrdaWorkerStateIdle; +} + +void irda_worker_set_decoded_signal(IrdaWorker* instance, const IrdaMessage* message) { + furi_assert(instance); + furi_assert(message); + + instance->signal.decoded = true; + instance->signal.data.message = *message; +} + +void irda_worker_set_raw_signal(IrdaWorker* instance, const uint32_t* timings, size_t timings_cnt) { + furi_assert(instance); + furi_assert(timings); + furi_assert(timings_cnt > 2); + + instance->signal.data.timings[0] = IRDA_RAW_TX_TIMING_DELAY_US; + memcpy(&instance->signal.data.timings[1], timings, timings_cnt * sizeof(uint32_t)); + instance->signal.decoded = false; + instance->signal.timings_cnt = timings_cnt + 1; +} + +IrdaWorkerGetSignalResponse irda_worker_tx_get_signal_steady_callback(void* context, IrdaWorker* instance) { + IrdaWorkerGetSignalResponse response = instance->tx.steady_signal_sent ? IrdaWorkerGetSignalResponseSame : IrdaWorkerGetSignalResponseNew; + instance->tx.steady_signal_sent = true; + return response; +} + diff --git a/lib/irda/worker/irda_worker.h b/lib/irda/worker/irda_worker.h index caac873d37f..90452bb3b3c 100644 --- a/lib/irda/worker/irda_worker.h +++ b/lib/irda/worker/irda_worker.h @@ -1,17 +1,34 @@ #pragma once #include -#include +#include #ifdef __cplusplus extern "C" { #endif +#define MAX_TIMINGS_AMOUNT 512 + /** Interface struct of irda worker */ typedef struct IrdaWorker IrdaWorker; /** Interface struct of received signal */ typedef struct IrdaWorkerSignal IrdaWorkerSignal; +typedef enum { + IrdaWorkerGetSignalResponseNew, /** Signal, provided by callback is new and encoder should be reseted */ + IrdaWorkerGetSignalResponseSame, /** Signal, provided by callback is same. No encoder resetting. */ + IrdaWorkerGetSignalResponseStop, /** No more signals available. */ +} IrdaWorkerGetSignalResponse; + +/** Callback type for providing next signal to send. Should be used with + * irda_worker_make_decoded_signal() or irda_worker_make_raw_signal() + */ +typedef IrdaWorkerGetSignalResponse (*IrdaWorkerGetSignalCallback)(void* context, IrdaWorker* instance); + +/** Callback type for 'message is sent' event */ +typedef void (*IrdaWorkerMessageSentCallback)(void* context); + + /** Callback type to call by IrdaWorker thread when new signal is received */ typedef void (*IrdaWorkerReceivedSignalCallback)(void* context, IrdaWorkerSignal* received_signal); @@ -27,31 +44,33 @@ IrdaWorker* irda_worker_alloc(); */ void irda_worker_free(IrdaWorker* instance); -/** Received data callback IrdaWorker +/** Start IrdaWorker thread, initialise furi-hal, prepare all work. * * @param[in] instance - IrdaWorker instance - * @param[in] callback - IrdaWorkerReceivedSignalCallback callback */ -void irda_worker_set_received_signal_callback(IrdaWorker* instance, IrdaWorkerReceivedSignalCallback callback); +void irda_worker_rx_start(IrdaWorker* instance); -/** Context callback IrdaWorker +/** Stop IrdaWorker thread, deinitialize furi-hal. * * @param[in] instance - IrdaWorker instance - * @param[in] context - context to pass to callbacks */ -void irda_worker_set_context(IrdaWorker* instance, void* context); +void irda_worker_rx_stop(IrdaWorker* instance); -/** Start IrdaWorker thread, initialise api-hal, prepare all work. +/** Set received data callback IrdaWorker * * @param[in] instance - IrdaWorker instance + * @param[in] context - context to pass to callbacks + * @param[in] callback - IrdaWorkerReceivedSignalCallback callback */ -void irda_worker_start(IrdaWorker* instance); +void irda_worker_rx_set_received_signal_callback(IrdaWorker* instance, IrdaWorkerReceivedSignalCallback callback, void* context); -/** Stop IrdaWorker thread, deinitialize api-hal. +/** Enable blinking on receiving any signal on IR port. * - * @param[in] instance - IrdaWorker instance + * @param[in] instance - instance of IrdaWorker + * @param[in] enable - true if you want to enable blinking + * false otherwise */ -void irda_worker_stop(IrdaWorker* instance); +void irda_worker_rx_enable_blink_on_receiving(IrdaWorker* instance, bool enable); /** Clarify is received signal either decoded or raw * @@ -60,6 +79,48 @@ void irda_worker_stop(IrdaWorker* instance); */ bool irda_worker_signal_is_decoded(const IrdaWorkerSignal* signal); +/** Start transmitting signal. Callback IrdaWorkerGetSignalCallback should be + * set before this function is called, as it calls for it to fill buffer before + * starting transmission. + * + * @param[in] instance - IrdaWorker instance + */ +void irda_worker_tx_start(IrdaWorker* instance); + +/** Stop transmitting signal. Waits for end of current signal and stops transmission. + * + * @param[in] instance - IrdaWorker instance + */ +void irda_worker_tx_stop(IrdaWorker* instance); + +/** Set callback for providing next signal to send + * + * @param[in] instance - IrdaWorker instance + * @param[in] context - context to pass to callbacks + * @param[in] callback - IrdaWorkerGetSignalCallback callback + */ +void irda_worker_tx_set_get_signal_callback(IrdaWorker* instance, IrdaWorkerGetSignalCallback callback, void* context); + +/** Set callback for end of signal transmitting + * + * @param[in] instance - IrdaWorker instance + * @param[in] context - context to pass to callbacks + * @param[in] callback - IrdaWorkerMessageSentCallback callback + */ +void irda_worker_tx_set_signal_sent_callback(IrdaWorker* instance, IrdaWorkerMessageSentCallback callback, void* context); + +/** Callback to pass to irda_worker_tx_set_get_signal_callback() if signal + * is steady and will not be changed between irda_worker start and stop. + * Before starting transmission, desired steady signal must be set with + * irda_worker_make_decoded_signal() or irda_worker_make_raw_signal(). + * + * This function should not be implicitly called. + * + * @param[in] context - context + * @param[out] instance - IrdaWorker instance + */ +IrdaWorkerGetSignalResponse irda_worker_tx_get_signal_steady_callback(void* context, IrdaWorker* instance); + /** Acquire raw signal from interface struct 'IrdaWorkerSignal'. * First, you have to ensure that signal is raw. * @@ -73,17 +134,24 @@ void irda_worker_get_raw_signal(const IrdaWorkerSignal* signal, const uint32_t** * First, you have to ensure that signal is decoded. * * @param[in] signal - received signal - * @return decoded irda message + * @return decoded IRDA message */ -const IrdaMessage* irda_worker_get_decoded_message(const IrdaWorkerSignal* signal); +const IrdaMessage* irda_worker_get_decoded_signal(const IrdaWorkerSignal* signal); -/** Enable blinking on receiving any signal on IR port. +/** Set current decoded signal for IrdaWorker instance * - * @param[in] instance - instance of IrdaWorker - * @param[in] enable - true if you want to enable blinking - * false otherwise + * @param[out] instance - IrdaWorker instance + * @param[in] message - decoded signal + */ +void irda_worker_set_decoded_signal(IrdaWorker* instance, const IrdaMessage* message); + +/** Set current raw signal for IrdaWorker instance + * + * @param[out] instance - IrdaWorker instance + * @param[in] timings - array of raw timings + * @param[in] timings_cnt - size of array of raw timings */ -void irda_worker_enable_blink_on_receiving(IrdaWorker* instance, bool enable); +void irda_worker_set_raw_signal(IrdaWorker* instance, const uint32_t* timings, size_t timings_cnt); #ifdef __cplusplus } diff --git a/lib/onewire/blanks_writer.cpp b/lib/onewire/blanks_writer.cpp index 651511f8981..bfd3fe92cb2 100644 --- a/lib/onewire/blanks_writer.cpp +++ b/lib/onewire/blanks_writer.cpp @@ -40,7 +40,7 @@ class DS1990 { #include #include #include -#include +#include void BlanksWriter::onewire_release(void) { hal_gpio_write(gpio, true); diff --git a/lib/onewire/one_wire_master.h b/lib/onewire/one_wire_master.h index 3bdc8eaf431..1075de982c3 100644 --- a/lib/onewire/one_wire_master.h +++ b/lib/onewire/one_wire_master.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include "one_wire_timings.h" class OneWireMaster { diff --git a/lib/onewire/one_wire_slave.h b/lib/onewire/one_wire_slave.h index 98d99ed14a3..95a9da572bc 100644 --- a/lib/onewire/one_wire_slave.h +++ b/lib/onewire/one_wire_slave.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include "one_wire_timings.h" class OneWireDevice; diff --git a/lib/subghz/protocols/subghz_protocol.c b/lib/subghz/protocols/subghz_protocol.c index 32e7dc05c6f..f0b930665d2 100644 --- a/lib/subghz/protocols/subghz_protocol.c +++ b/lib/subghz/protocols/subghz_protocol.c @@ -16,19 +16,26 @@ #include #include +typedef enum { + SubGhzProtocolTypeCame, + SubGhzProtocolTypeKeeloq, + SubGhzProtocolTypeNiceFlo, + SubGhzProtocolTypeNiceFlorS, + SubGhzProtocolTypePrinceton, + SubGhzProtocolTypeGateTX, + SubGhzProtocolTypeIDo, + SubGhzProtocolTypeFaacSLH, + SubGhzProtocolTypeNeroSketch, + SubGhzProtocolTypeStarLine, + + SubGhzProtocolTypeMax, +} SubGhzProtocolType; + + struct SubGhzProtocol { SubGhzKeystore* keystore; - SubGhzProtocolCame* came; - SubGhzProtocolKeeloq* keeloq; - SubGhzProtocolNiceFlo* nice_flo; - SubGhzProtocolNiceFlorS* nice_flor_s; - SubGhzProtocolPrinceton* princeton; - SubGhzProtocolGateTX* gate_tx; - SubGhzProtocolIDo* ido; - SubGhzProtocolFaacSLH* faac_slh; - SubGhzProtocolNeroSketch* nero_sketch; - SubGhzProtocolStarLine* star_line; + SubGhzProtocolCommon* protocols[SubGhzProtocolTypeMax]; SubGhzProtocolTextCallback text_callback; void* text_callback_context; @@ -62,16 +69,16 @@ SubGhzProtocol* subghz_protocol_alloc() { instance->keystore = subghz_keystore_alloc(); - instance->came = subghz_protocol_came_alloc(); - instance->keeloq = subghz_protocol_keeloq_alloc(instance->keystore); - instance->princeton = subghz_protocol_princeton_alloc(); - instance->nice_flo = subghz_protocol_nice_flo_alloc(); - instance->nice_flor_s = subghz_protocol_nice_flor_s_alloc(); - instance->gate_tx = subghz_protocol_gate_tx_alloc(); - instance->ido = subghz_protocol_ido_alloc(); - instance->faac_slh = subghz_protocol_faac_slh_alloc(); - instance->nero_sketch = subghz_protocol_nero_sketch_alloc(); - instance->star_line = subghz_protocol_star_line_alloc(instance->keystore); + instance->protocols[SubGhzProtocolTypeCame] =(SubGhzProtocolCommon*)subghz_protocol_came_alloc(); + instance->protocols[SubGhzProtocolTypeKeeloq] = (SubGhzProtocolCommon*)subghz_protocol_keeloq_alloc(instance->keystore); + instance->protocols[SubGhzProtocolTypePrinceton] = (SubGhzProtocolCommon*)subghz_decoder_princeton_alloc(); + instance->protocols[SubGhzProtocolTypeNiceFlo] = (SubGhzProtocolCommon*)subghz_protocol_nice_flo_alloc(); + instance->protocols[SubGhzProtocolTypeNiceFlorS] = (SubGhzProtocolCommon*)subghz_protocol_nice_flor_s_alloc(); + instance->protocols[SubGhzProtocolTypeGateTX] = (SubGhzProtocolCommon*)subghz_protocol_gate_tx_alloc(); + instance->protocols[SubGhzProtocolTypeIDo] = (SubGhzProtocolCommon*)subghz_protocol_ido_alloc(); + instance->protocols[SubGhzProtocolTypeFaacSLH] = (SubGhzProtocolCommon*)subghz_protocol_faac_slh_alloc(); + instance->protocols[SubGhzProtocolTypeNeroSketch] = (SubGhzProtocolCommon*)subghz_protocol_nero_sketch_alloc(); + instance->protocols[SubGhzProtocolTypeStarLine] = (SubGhzProtocolCommon*)subghz_protocol_star_line_alloc(instance->keystore); return instance; } @@ -79,35 +86,41 @@ SubGhzProtocol* subghz_protocol_alloc() { void subghz_protocol_free(SubGhzProtocol* instance) { furi_assert(instance); - subghz_protocol_came_free(instance->came); - subghz_protocol_keeloq_free(instance->keeloq); - subghz_protocol_princeton_free(instance->princeton); - subghz_protocol_nice_flo_free(instance->nice_flo); - subghz_protocol_nice_flor_s_free(instance->nice_flor_s); - subghz_protocol_gate_tx_free(instance->gate_tx); - subghz_protocol_ido_free(instance->ido); - subghz_protocol_faac_slh_free(instance->faac_slh); - subghz_protocol_nero_sketch_free(instance->nero_sketch); - subghz_protocol_star_line_free(instance->star_line); + subghz_protocol_came_free((SubGhzProtocolCame*)instance->protocols[SubGhzProtocolTypeCame]); + subghz_protocol_keeloq_free((SubGhzProtocolKeeloq*)instance->protocols[SubGhzProtocolTypeKeeloq]); + subghz_decoder_princeton_free((SubGhzDecoderPrinceton*)instance->protocols[SubGhzProtocolTypePrinceton]); + subghz_protocol_nice_flo_free((SubGhzProtocolNiceFlo*)instance->protocols[SubGhzProtocolTypeNiceFlo]); + subghz_protocol_nice_flor_s_free((SubGhzProtocolNiceFlorS*)instance->protocols[SubGhzProtocolTypeNiceFlorS]); + subghz_protocol_gate_tx_free((SubGhzProtocolGateTX*)instance->protocols[SubGhzProtocolTypeGateTX]); + subghz_protocol_ido_free((SubGhzProtocolIDo*)instance->protocols[SubGhzProtocolTypeIDo]); + subghz_protocol_faac_slh_free((SubGhzProtocolFaacSLH*)instance->protocols[SubGhzProtocolTypeFaacSLH]); + subghz_protocol_nero_sketch_free((SubGhzProtocolNeroSketch*)instance->protocols[SubGhzProtocolTypeNeroSketch]); + subghz_protocol_star_line_free((SubGhzProtocolStarLine*)instance->protocols[SubGhzProtocolTypeStarLine]); subghz_keystore_free(instance->keystore); free(instance); } +SubGhzProtocolCommon* subghz_protocol_get_by_name(SubGhzProtocol* instance, const char* name) { + SubGhzProtocolCommon* result = NULL; + + for(size_t i = 0; i < SubGhzProtocolTypeMax; i++) { + if(strcmp(instance->protocols[i]->name, name) == 0) { + result = instance->protocols[i]; + break; + } + } + + return result; +} + void subghz_protocol_enable_dump_text(SubGhzProtocol* instance, SubGhzProtocolTextCallback callback, void* context) { furi_assert(instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->came, subghz_protocol_text_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->keeloq, subghz_protocol_text_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->princeton, subghz_protocol_text_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nice_flo, subghz_protocol_text_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nice_flor_s, subghz_protocol_text_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->gate_tx, subghz_protocol_text_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->ido, subghz_protocol_text_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->faac_slh, subghz_protocol_text_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nero_sketch, subghz_protocol_text_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->star_line, subghz_protocol_text_rx_callback, instance); + for(size_t i = 0; i < SubGhzProtocolTypeMax; i++) { + subghz_protocol_common_set_callback(instance->protocols[i], subghz_protocol_text_rx_callback, instance); + } instance->text_callback = callback; instance->text_callback_context = context; @@ -116,24 +129,18 @@ void subghz_protocol_enable_dump_text(SubGhzProtocol* instance, SubGhzProtocolTe void subghz_protocol_enable_dump(SubGhzProtocol* instance, SubGhzProtocolCommonCallbackDump callback, void* context) { furi_assert(instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->came, subghz_protocol_parser_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->keeloq, subghz_protocol_parser_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->princeton, subghz_protocol_parser_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nice_flo, subghz_protocol_parser_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nice_flor_s, subghz_protocol_parser_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->gate_tx, subghz_protocol_parser_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->ido, subghz_protocol_parser_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->faac_slh, subghz_protocol_parser_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nero_sketch, subghz_protocol_parser_rx_callback, instance); - subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->star_line, subghz_protocol_parser_rx_callback, instance); - + for(size_t i = 0; i < SubGhzProtocolTypeMax; i++) { + subghz_protocol_common_set_callback(instance->protocols[i], subghz_protocol_parser_rx_callback, instance); + } + instance->parser_callback = callback; instance->parser_callback_context = context; } void subghz_protocol_load_nice_flor_s_file(SubGhzProtocol* instance, const char* file_name) { - subghz_protocol_nice_flor_s_name_file(instance->nice_flor_s, file_name); + // subghz_protocol_nice_flor_s_name_file(instance->nice_flor_s, file_name); + subghz_protocol_nice_flor_s_name_file((SubGhzProtocolNiceFlorS*) instance->protocols[SubGhzProtocolTypeNiceFlorS], file_name); } void subghz_protocol_load_keeloq_file(SubGhzProtocol* instance, const char* file_name) { @@ -141,27 +148,29 @@ void subghz_protocol_load_keeloq_file(SubGhzProtocol* instance, const char* file } void subghz_protocol_reset(SubGhzProtocol* instance) { - subghz_protocol_came_reset(instance->came); - subghz_protocol_keeloq_reset(instance->keeloq); - subghz_protocol_princeton_reset(instance->princeton); - subghz_protocol_nice_flo_reset(instance->nice_flo); - subghz_protocol_nice_flor_s_reset(instance->nice_flor_s); - subghz_protocol_gate_tx_reset(instance->gate_tx); - subghz_protocol_ido_reset(instance->ido); - subghz_protocol_faac_slh_reset(instance->faac_slh); - subghz_protocol_nero_sketch_reset(instance->nero_sketch); - subghz_protocol_star_line_reset(instance->star_line); + + subghz_protocol_came_reset((SubGhzProtocolCame*)instance->protocols[SubGhzProtocolTypeCame]); + subghz_protocol_keeloq_reset((SubGhzProtocolKeeloq*)instance->protocols[SubGhzProtocolTypeKeeloq]); + subghz_decoder_princeton_reset((SubGhzDecoderPrinceton*)instance->protocols[SubGhzProtocolTypePrinceton]); + subghz_protocol_nice_flo_reset((SubGhzProtocolNiceFlo*)instance->protocols[SubGhzProtocolTypeNiceFlo]); + subghz_protocol_nice_flor_s_reset((SubGhzProtocolNiceFlorS*)instance->protocols[SubGhzProtocolTypeNiceFlorS]); + subghz_protocol_gate_tx_reset((SubGhzProtocolGateTX*)instance->protocols[SubGhzProtocolTypeGateTX]); + subghz_protocol_ido_reset((SubGhzProtocolIDo*)instance->protocols[SubGhzProtocolTypeIDo]); + subghz_protocol_faac_slh_reset((SubGhzProtocolFaacSLH*)instance->protocols[SubGhzProtocolTypeFaacSLH]); + subghz_protocol_nero_sketch_reset((SubGhzProtocolNeroSketch*)instance->protocols[SubGhzProtocolTypeNeroSketch]); + subghz_protocol_star_line_reset((SubGhzProtocolStarLine*)instance->protocols[SubGhzProtocolTypeStarLine]); } void subghz_protocol_parse(SubGhzProtocol* instance, bool level, uint32_t duration) { - subghz_protocol_came_parse(instance->came, level, duration); - subghz_protocol_keeloq_parse(instance->keeloq, level, duration); - subghz_protocol_princeton_parse(instance->princeton, level, duration); - subghz_protocol_nice_flo_parse(instance->nice_flo, level, duration); - subghz_protocol_nice_flor_s_parse(instance->nice_flor_s, level, duration); - subghz_protocol_gate_tx_parse(instance->gate_tx, level, duration); - subghz_protocol_ido_parse(instance->ido, level, duration); - subghz_protocol_faac_slh_parse(instance->faac_slh, level, duration); - subghz_protocol_nero_sketch_parse(instance->nero_sketch, level, duration); - subghz_protocol_star_line_parse(instance->star_line, level, duration); + + subghz_protocol_came_parse((SubGhzProtocolCame*)instance->protocols[SubGhzProtocolTypeCame], level, duration); + subghz_protocol_keeloq_parse((SubGhzProtocolKeeloq*)instance->protocols[SubGhzProtocolTypeKeeloq], level, duration); + subghz_decoder_princeton_parse((SubGhzDecoderPrinceton*)instance->protocols[SubGhzProtocolTypePrinceton], level, duration); + subghz_protocol_nice_flo_parse((SubGhzProtocolNiceFlo*)instance->protocols[SubGhzProtocolTypeNiceFlo], level, duration); + subghz_protocol_nice_flor_s_parse((SubGhzProtocolNiceFlorS*)instance->protocols[SubGhzProtocolTypeNiceFlorS], level, duration); + subghz_protocol_gate_tx_parse((SubGhzProtocolGateTX*)instance->protocols[SubGhzProtocolTypeGateTX], level, duration); + subghz_protocol_ido_parse((SubGhzProtocolIDo*)instance->protocols[SubGhzProtocolTypeIDo], level, duration); + subghz_protocol_faac_slh_parse((SubGhzProtocolFaacSLH*)instance->protocols[SubGhzProtocolTypeFaacSLH], level, duration); + subghz_protocol_nero_sketch_parse((SubGhzProtocolNeroSketch*)instance->protocols[SubGhzProtocolTypeNeroSketch], level, duration); + subghz_protocol_star_line_parse((SubGhzProtocolStarLine*)instance->protocols[SubGhzProtocolTypeStarLine], level, duration); } diff --git a/lib/subghz/protocols/subghz_protocol.h b/lib/subghz/protocols/subghz_protocol.h index 33592854064..3c33b8143e6 100644 --- a/lib/subghz/protocols/subghz_protocol.h +++ b/lib/subghz/protocols/subghz_protocol.h @@ -19,6 +19,14 @@ SubGhzProtocol* subghz_protocol_alloc(); */ void subghz_protocol_free(SubGhzProtocol* instance); +/** Get protocol by name + * + * @param instance - SubGhzProtocol instance + * @param name - name protocol + * @param SubGhzProtocolCommon + */ +SubGhzProtocolCommon* subghz_protocol_get_by_name(SubGhzProtocol* instance, const char* name); + /** Outputting data text from all parsers * * @param instance - SubGhzProtocol instance diff --git a/lib/subghz/protocols/subghz_protocol_came.c b/lib/subghz/protocols/subghz_protocol_came.c index 68f78576393..7af2f6dc5f1 100644 --- a/lib/subghz/protocols/subghz_protocol_came.c +++ b/lib/subghz/protocols/subghz_protocol_came.c @@ -19,6 +19,11 @@ SubGhzProtocolCame* subghz_protocol_came_alloc() { instance->common.te_shot = 320; instance->common.te_long = 640; instance->common.te_delta = 150; + instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_came_to_str; + instance->common.to_save_string = + (SubGhzProtocolCommonGetStrSave)subghz_protocol_came_to_save_str; + instance->common.to_load_protocol= + (SubGhzProtocolCommonLoad)subghz_protocol_came_to_load_protocol; return instance; } @@ -99,6 +104,10 @@ void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32 instance->common.serial = 0x0; instance->common.btn = 0x0; + + instance->common.code_last_found = instance->common.code_found; + instance->common.code_last_count_bit = instance->common.code_count_bit; + if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); @@ -129,3 +138,75 @@ void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32 break; } } + +void subghz_protocol_came_to_str(SubGhzProtocolCame* instance, string_t output) { + uint32_t code_found_hi = instance->common.code_last_found >> 32; + uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff; + + uint64_t code_found_reverse = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); + + uint32_t code_found_reverse_hi = code_found_reverse >> 32; + uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; + + string_cat_printf( + output, + "%s %d Bit\r\n" + " KEY:0x%lX%08lX\r\n" + " YEK:0x%lX%08lX\r\n", + instance->common.name, + instance->common.code_last_count_bit, + code_found_hi, + code_found_lo, + code_found_reverse_hi, + code_found_reverse_lo + ); +} + +void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t output) { + string_printf( + output, + "Protocol: %s\n" + "Bit: %d\n" + "Key: %08lX\n", + instance->common.name, + instance->common.code_last_count_bit, + (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff)); +} + +bool subghz_protocol_came_to_load_protocol(FileWorker* file_worker, SubGhzProtocolCame* instance){ + bool loaded = false; + string_t temp_str; + string_init(temp_str); + int res = 0; + int data = 0; + + do { + // Read and parse bit data from 2nd line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data); + if(res != 1) { + break; + } + instance->common.code_last_count_bit = (uint8_t)data; + + // Read and parse key data from 3nd line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + uint32_t temp_key = 0; + res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key); + if(res != 1) { + break; + } + instance->common.code_last_found = (uint64_t)temp_key; + + loaded = true; + } while(0); + + string_clear(temp_str); + + return loaded; +} diff --git a/lib/subghz/protocols/subghz_protocol_came.h b/lib/subghz/protocols/subghz_protocol_came.h index 7ce1aa09a96..42c1b9a31d0 100644 --- a/lib/subghz/protocols/subghz_protocol_came.h +++ b/lib/subghz/protocols/subghz_protocol_came.h @@ -36,3 +36,13 @@ void subghz_protocol_came_reset(SubGhzProtocolCame* instance); * @param data - LevelDuration level_duration */ void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32_t duration); + +/** Outputting information from the parser + * + * @param instance - SubGhzProtocolCame* instance + * @param output - output string + */ +void subghz_protocol_came_to_str(SubGhzProtocolCame* instance, string_t output); + +void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t output); +bool subghz_protocol_came_to_load_protocol(FileWorker* file_worker, SubGhzProtocolCame* instance); diff --git a/lib/subghz/protocols/subghz_protocol_common.h b/lib/subghz/protocols/subghz_protocol_common.h index cd4c9ec858d..a00b0aba5bf 100644 --- a/lib/subghz/protocols/subghz_protocol_common.h +++ b/lib/subghz/protocols/subghz_protocol_common.h @@ -1,39 +1,52 @@ #pragma once #include -#include +#include #include +#include "file-worker.h" #define bit_read(value, bit) (((value) >> (bit)) & 0x01) #define bit_set(value, bit) ((value) |= (1UL << (bit))) #define bit_clear(value, bit) ((value) &= ~(1UL << (bit))) #define bit_write(value, bit, bitvalue) (bitvalue ? bit_set(value, bit) : bit_clear(value, bit)) -#define SUBGHZ_TX_PIN_HIGTH() -#define SUBGHZ_TX_PIN_LOW() +#define SUBGHZ_TX_PIN_HIGTH() +#define SUBGHZ_TX_PIN_LOW() #define DURATION_DIFF(x, y) ((x < y) ? (y - x) : (x - y)) +//#define SUBGHZ_APP_PATH_FOLDER "/ext/subghz/saved" +#define SUBGHZ_APP_FOLDER "/any/subghz" +#define SUBGHZ_APP_PATH_FOLDER "/any/subghz/saved" +#define SUBGHZ_APP_EXTENSION ".sub" + typedef struct SubGhzProtocolCommon SubGhzProtocolCommon; typedef void (*SubGhzProtocolCommonCallback)(SubGhzProtocolCommon* parser, void* context); typedef void (*SubGhzProtocolCommonToStr)(SubGhzProtocolCommon* instance, string_t output); +//Save +typedef void (*SubGhzProtocolCommonGetStrSave)(SubGhzProtocolCommon* instance, string_t output); + +//Load +typedef bool (*SubGhzProtocolCommonLoad)(FileWorker* file_worker, SubGhzProtocolCommon* instance); + struct SubGhzProtocolCommon { const char* name; - uint16_t te_long; - uint16_t te_shot; - uint16_t te_delta; - uint64_t code_found; - uint64_t code_last_found; - uint8_t code_count_bit; - uint8_t code_min_count_bit_for_found; - uint8_t parser_step; - uint32_t te_last; - uint8_t header_count; - uint16_t cnt; - uint32_t serial; - uint8_t btn; + uint16_t te_long; + uint16_t te_shot; + uint16_t te_delta; + uint8_t code_count_bit; + uint8_t code_last_count_bit; + uint64_t code_found; + uint64_t code_last_found; + uint8_t code_min_count_bit_for_found; + uint8_t parser_step; + uint32_t te_last; + uint8_t header_count; + uint16_t cnt; + uint32_t serial; + uint8_t btn; /* Standard Callback for on rx complete event */ SubGhzProtocolCommonCallback callback; @@ -41,15 +54,18 @@ struct SubGhzProtocolCommon { /* Dump To String */ SubGhzProtocolCommonToStr to_string; + /* Get string to save */ + SubGhzProtocolCommonGetStrSave to_save_string; + /*Load protocol by file*/ + SubGhzProtocolCommonLoad to_load_protocol; }; - /** Add data bit to code_found * * @param common - SubGhzProtocolCommon common * @param bit - add bit */ -void subghz_protocol_common_add_bit(SubGhzProtocolCommon *common, uint8_t bit); +void subghz_protocol_common_add_bit(SubGhzProtocolCommon* common, uint8_t bit); /** Checking that the duration is included in the interval * @@ -58,7 +74,10 @@ void subghz_protocol_common_add_bit(SubGhzProtocolCommon *common, uint8_t bit); * @param duration_check duration checked * @return true on success */ -bool subghz_protocol_common_check_interval(SubGhzProtocolCommon *common, uint32_t duration, uint16_t duration_check); +bool subghz_protocol_common_check_interval( + SubGhzProtocolCommon* common, + uint32_t duration, + uint16_t duration_check); /** Bit-by-bit data mirroring * @@ -68,14 +87,16 @@ bool subghz_protocol_common_check_interval(SubGhzProtocolCommon *common, uint32_ */ uint64_t subghz_protocol_common_reverse_key(uint64_t key, uint8_t count_bit); - /** Callback protocol * * @param instance - SubGhzProtocolCommon* instance * @param callback * @param context */ -void subghz_protocol_common_set_callback(SubGhzProtocolCommon* instance, SubGhzProtocolCommonCallback callback, void* context); +void subghz_protocol_common_set_callback( + SubGhzProtocolCommon* instance, + SubGhzProtocolCommonCallback callback, + void* context); /** outputting information from the parser * @@ -83,4 +104,3 @@ void subghz_protocol_common_set_callback(SubGhzProtocolCommon* instance, SubGhzP * @param output - output string */ void subghz_protocol_common_to_str(SubGhzProtocolCommon* instance, string_t output); - diff --git a/lib/subghz/protocols/subghz_protocol_gate_tx.c b/lib/subghz/protocols/subghz_protocol_gate_tx.c index 90fa0521beb..cfd01db080c 100644 --- a/lib/subghz/protocols/subghz_protocol_gate_tx.c +++ b/lib/subghz/protocols/subghz_protocol_gate_tx.c @@ -14,6 +14,10 @@ SubGhzProtocolGateTX* subghz_protocol_gate_tx_alloc(void) { instance->common.te_long = 700; instance->common.te_delta = 100; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_gate_tx_to_str; + instance->common.to_save_string = + (SubGhzProtocolCommonGetStrSave)subghz_protocol_gate_tx_to_save_str; + instance->common.to_load_protocol= + (SubGhzProtocolCommonLoad)subghz_protocol_gate_tx_to_load_protocol; return instance; } @@ -68,13 +72,10 @@ void subghz_protocol_gate_tx_reset(SubGhzProtocolGateTX* instance) { * @param instance SubGhzProtocolFaacSLH instance */ void subghz_protocol_gate_tx_check_remote_controller(SubGhzProtocolGateTX* instance) { - uint32_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); + uint32_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); instance->common.serial = (code_found_reverse & 0xFF) << 12 | ((code_found_reverse >>8) & 0xFF) << 4 | ((code_found_reverse >>20) & 0x0F) ; instance->common.btn = ((code_found_reverse >> 16) & 0x0F); - - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); - } void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, uint32_t duration) { @@ -103,7 +104,11 @@ void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, u if (duration >= (instance->common.te_shot * 10 + instance->common.te_delta)) { instance->common.parser_step = 1; if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { - subghz_protocol_gate_tx_check_remote_controller(instance); + + instance->common.code_last_found = instance->common.code_found; + instance->common.code_last_count_bit = instance->common.code_count_bit; + + if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); } instance->common.code_found = 0; instance->common.code_count_bit = 0; @@ -135,20 +140,64 @@ void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, u } void subghz_protocol_gate_tx_to_str(SubGhzProtocolGateTX* instance, string_t output) { - - // uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); - // uint32_t code_fix = code_found_reverse & 0xFFFFFFFF; - // uint32_t code_hop = (code_found_reverse >>32) & 0xFFFFFFFF; - - //uint32_t rev_hi = - + subghz_protocol_gate_tx_check_remote_controller(instance); string_cat_printf(output, - "Protocol %s, %d Bit\r\n" + "%s, %d Bit\r\n" " KEY:%06lX\r\n" " SN:%05lX BTN:%lX\r\n", instance->common.name, - instance->common.code_count_bit, - (uint32_t)(instance->common.code_found & 0xFFFFFF), + instance->common.code_last_count_bit, + (uint32_t)(instance->common.code_last_found & 0xFFFFFF), instance->common.serial, - instance->common.btn); -} \ No newline at end of file + instance->common.btn + ); +} + +void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_t output) { + string_printf( + output, + "Protocol: %s\n" + "Bit: %d\n" + "Key: %08lX\n", + instance->common.name, + instance->common.code_last_count_bit, + (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff)); +} + +bool subghz_protocol_gate_tx_to_load_protocol(FileWorker* file_worker, SubGhzProtocolGateTX* instance){ + bool loaded = false; + string_t temp_str; + string_init(temp_str); + int res = 0; + int data = 0; + + do { + // Read and parse bit data from 2nd line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data); + if(res != 1) { + break; + } + instance->common.code_last_count_bit = (uint8_t)data; + + // Read and parse key data from 3nd line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + uint32_t temp_key = 0; + res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key); + if(res != 1) { + break; + } + instance->common.code_last_found = (uint64_t)temp_key; + subghz_protocol_gate_tx_check_remote_controller(instance); + + loaded = true; + } while(0); + + string_clear(temp_str); + + return loaded; +} diff --git a/lib/subghz/protocols/subghz_protocol_gate_tx.h b/lib/subghz/protocols/subghz_protocol_gate_tx.h index 3e73da92562..c02a8c45d18 100644 --- a/lib/subghz/protocols/subghz_protocol_gate_tx.h +++ b/lib/subghz/protocols/subghz_protocol_gate_tx.h @@ -42,4 +42,7 @@ void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, u * @param instance - SubGhzProtocolFaacSLH* instance * @param output - output string */ -void subghz_protocol_gate_tx_to_str(SubGhzProtocolGateTX* instance, string_t output); \ No newline at end of file +void subghz_protocol_gate_tx_to_str(SubGhzProtocolGateTX* instance, string_t output); + +void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_t output); +bool subghz_protocol_gate_tx_to_load_protocol(FileWorker* file_worker, SubGhzProtocolGateTX* instance); diff --git a/lib/subghz/protocols/subghz_protocol_keeloq.c b/lib/subghz/protocols/subghz_protocol_keeloq.c index 28a7a053afc..878e17bc6ad 100644 --- a/lib/subghz/protocols/subghz_protocol_keeloq.c +++ b/lib/subghz/protocols/subghz_protocol_keeloq.c @@ -24,6 +24,10 @@ SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc(SubGhzKeystore* keystore) { instance->common.te_long = 800; instance->common.te_delta = 140; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_keeloq_to_str; + instance->common.to_save_string = + (SubGhzProtocolCommonGetStrSave)subghz_protocol_keeloq_to_save_str; + instance->common.to_load_protocol = + (SubGhzProtocolCommonLoad)subghz_protocol_keeloq_to_load_protocol; return instance; } @@ -40,86 +44,97 @@ void subghz_protocol_keeloq_free(SubGhzProtocolKeeloq* instance) { * @param hop hop encrypted part of the parcel * @return true on successful search */ -uint8_t subghz_protocol_keeloq_check_remote_controller_selector(SubGhzProtocolKeeloq* instance, uint32_t fix , uint32_t hop) { - uint16_t end_serial = (uint16_t)(fix&0x3FF); - uint8_t btn = (uint8_t)(fix>>28); +uint8_t subghz_protocol_keeloq_check_remote_controller_selector( + SubGhzProtocolKeeloq* instance, + uint32_t fix, + uint32_t hop) { + uint16_t end_serial = (uint16_t)(fix & 0x3FF); + uint8_t btn = (uint8_t)(fix >> 28); uint32_t decrypt = 0; uint64_t man_normal_learning; for M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) { - switch (manufacture_code->type){ - case KEELOQ_LEARNING_SIMPLE: - //Simple Learning - decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); - if((decrypt>>28 == btn) && ((((uint16_t)(decrypt>>16)) & 0x3FF) == end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt = decrypt & 0x0000FFFF; - return 1; - } + switch(manufacture_code->type) { + case KEELOQ_LEARNING_SIMPLE: + //Simple Learning + decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); + if((decrypt >> 28 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } break; - case KEELOQ_LEARNING_NORMAL: - // Normal_Learning - // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 - man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - decrypt=subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); - if( (decrypt>>28 ==btn)&& ((((uint16_t)(decrypt>>16))&0x3FF)==end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt = decrypt & 0x0000FFFF; - return 1; - } + case KEELOQ_LEARNING_NORMAL: + // Normal_Learning + // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 + man_normal_learning = + subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); + decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); + if((decrypt >> 28 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } break; - case KEELOQ_LEARNING_UNKNOWN: - // Simple Learning - decrypt=subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); - if( (decrypt>>28 ==btn) && ((((uint16_t)(decrypt>>16))&0x3FF)==end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt = decrypt & 0x0000FFFF; - return 1; - } - // Check for mirrored man - uint64_t man_rev=0; - uint64_t man_rev_byte=0; - for(uint8_t i=0; i<64; i+=8){ - man_rev_byte=(uint8_t)(manufacture_code->key >> i); - man_rev = man_rev | man_rev_byte << (56-i); - } - decrypt=subghz_protocol_keeloq_common_decrypt(hop, man_rev); - if( (decrypt>>28 ==btn) && ((((uint16_t)(decrypt>>16))&0x3FF)==end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt= decrypt&0x0000FFFF; - return 1; - } - //########################### - // Normal_Learning - // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 - man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - decrypt=subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); - if( (decrypt>>28 ==btn)&& ((((uint16_t)(decrypt>>16))&0x3FF)==end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt= decrypt&0x0000FFFF; - return 1; - } - // Check for mirrored man - man_rev=0; - man_rev_byte=0; - for(uint8_t i=0; i<64; i+=8){ - man_rev_byte = (uint8_t)(manufacture_code->key >> i); - man_rev = man_rev | man_rev_byte << (56-i); - } - man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev); - decrypt=subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); - if( (decrypt>>28 ==btn) && ((((uint16_t)(decrypt>>16))&0x3FF)==end_serial)){ - instance->manufacture_name = string_get_cstr(manufacture_code->name); - instance->common.cnt= decrypt&0x0000FFFF; - return 1; - } + case KEELOQ_LEARNING_UNKNOWN: + // Simple Learning + decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); + if((decrypt >> 28 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } + // Check for mirrored man + uint64_t man_rev = 0; + uint64_t man_rev_byte = 0; + for(uint8_t i = 0; i < 64; i += 8) { + man_rev_byte = (uint8_t)(manufacture_code->key >> i); + man_rev = man_rev | man_rev_byte << (56 - i); + } + decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev); + if((decrypt >> 28 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } + //########################### + // Normal_Learning + // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 + man_normal_learning = + subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); + decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); + if((decrypt >> 28 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } + // Check for mirrored man + man_rev = 0; + man_rev_byte = 0; + for(uint8_t i = 0; i < 64; i += 8) { + man_rev_byte = (uint8_t)(manufacture_code->key >> i); + man_rev = man_rev | man_rev_byte << (56 - i); + } + man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev); + decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); + if((decrypt >> 28 == btn) && + ((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial)) { + instance->manufacture_name = string_get_cstr(manufacture_code->name); + instance->common.cnt = decrypt & 0x0000FFFF; + return 1; + } break; } } instance->manufacture_name = "Unknown"; - instance->common.cnt=0; + instance->common.cnt = 0; return 0; } @@ -129,22 +144,23 @@ uint8_t subghz_protocol_keeloq_check_remote_controller_selector(SubGhzProtocolKe * @param instance SubGhzProtocolKeeloq instance */ void subghz_protocol_keeloq_check_remote_controller(SubGhzProtocolKeeloq* instance) { - uint64_t key = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); + uint64_t key = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); uint32_t key_fix = key >> 32; uint32_t key_hop = key & 0x00000000ffffffff; // Check key AN-Motors - if((key_hop >> 24) == ((key_hop>>16)&0x00ff) && (key_fix>>28) ==((key_hop>>12)&0x0f) && (key_hop & 0xFFF ) == 0x404){ + if((key_hop >> 24) == ((key_hop >> 16) & 0x00ff) && + (key_fix >> 28) == ((key_hop >> 12) & 0x0f) && (key_hop & 0xFFF) == 0x404) { instance->manufacture_name = "AN-Motors"; - instance->common.cnt = key_hop>>16; - } else if((key_hop & 0xFFF) == (0x000) && (key_fix>>28) ==((key_hop>>12)&0x0f) ){ + instance->common.cnt = key_hop >> 16; + } else if((key_hop & 0xFFF) == (0x000) && (key_fix >> 28) == ((key_hop >> 12) & 0x0f)) { instance->manufacture_name = "HCS101"; - instance->common.cnt = key_hop>>16; + instance->common.cnt = key_hop >> 16; } else { subghz_protocol_keeloq_check_remote_controller_selector(instance, key_fix, key_hop); } - instance ->common.serial= key_fix&0x0FFFFFFF; + instance->common.serial = key_fix & 0x0FFFFFFF; instance->common.btn = key_fix >> 28; - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); } /** Send bit @@ -153,7 +169,7 @@ void subghz_protocol_keeloq_check_remote_controller(SubGhzProtocolKeeloq* instan * @param bit - bit */ void subghz_protocol_keeloq_send_bit(SubGhzProtocolKeeloq* instance, uint8_t bit) { - if (bit) { + if(bit) { // send bit 1 SUBGHZ_TX_PIN_HIGTH(); delay_us(instance->common.te_shot); @@ -168,10 +184,14 @@ void subghz_protocol_keeloq_send_bit(SubGhzProtocolKeeloq* instance, uint8_t bit } } -void subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, uint64_t key, uint8_t bit, uint8_t repeat) { - while (repeat--) { +void subghz_protocol_keeloq_send_key( + SubGhzProtocolKeeloq* instance, + uint64_t key, + uint8_t bit, + uint8_t repeat) { + while(repeat--) { // Send header - for (uint8_t i = 11; i > 0; i--) { + for(uint8_t i = 11; i > 0; i--) { SUBGHZ_TX_PIN_HIGTH(); delay_us(instance->common.te_shot); SUBGHZ_TX_PIN_LOW(); @@ -179,7 +199,7 @@ void subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, uint64_t ke } delay_us(instance->common.te_shot * 9); //+1 up Send header - for (uint8_t i = bit; i > 0; i--) { + for(uint8_t i = bit; i > 0; i--) { subghz_protocol_keeloq_send_bit(instance, bit_read(key, i - 1)); } // +send 2 status bit @@ -187,7 +207,7 @@ void subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, uint64_t ke subghz_protocol_keeloq_send_bit(instance, 0); // send end subghz_protocol_keeloq_send_bit(instance, 0); - delay_us(instance->common.te_shot * 2); //+2 interval END SEND + delay_us(instance->common.te_shot * 2); //+2 interval END SEND } } @@ -196,9 +216,10 @@ void subghz_protocol_keeloq_reset(SubGhzProtocolKeeloq* instance) { } void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, uint32_t duration) { - switch (instance->common.parser_step) { + switch(instance->common.parser_step) { case 0: - if ((level) && DURATION_DIFF(duration, instance->common.te_shot)< instance->common.te_delta) { + if((level) && + DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta) { instance->common.parser_step = 1; instance->common.header_count++; } else { @@ -207,11 +228,14 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui break; case 1: - if ((!level) && (DURATION_DIFF(duration, instance->common.te_shot ) < instance->common.te_delta)) { + if((!level) && + (DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta)) { instance->common.parser_step = 0; break; } - if ((instance->common.header_count > 2) && ( DURATION_DIFF(duration, instance->common.te_shot * 10)< instance->common.te_delta * 10)) { + if((instance->common.header_count > 2) && + (DURATION_DIFF(duration, instance->common.te_shot * 10) < + instance->common.te_delta * 10)) { // Found header instance->common.parser_step = 2; instance->common.code_found = 0; @@ -222,35 +246,45 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui } break; case 2: - if (level) { + if(level) { instance->common.te_last = duration; instance->common.parser_step = 3; } break; case 3: - if (!level) { - if (duration >= (instance->common.te_shot * 2 + instance->common.te_delta)) { + if(!level) { + if(duration >= (instance->common.te_shot * 2 + instance->common.te_delta)) { // Found end TX instance->common.parser_step = 0; - if (instance->common.code_count_bit >= instance->common.code_min_count_bit_for_found) { - if(instance->common.code_last_found != instance->common.code_found ){ - subghz_protocol_keeloq_check_remote_controller(instance); + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { + if(instance->common.code_last_found != instance->common.code_found) { + instance->common.code_last_found = instance->common.code_found; + instance->common.code_last_count_bit = instance->common.code_count_bit; + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } - instance->common.code_last_found = instance->common.code_found; instance->common.code_found = 0; instance->common.code_count_bit = 0; instance->common.header_count = 0; } break; - } else if ((DURATION_DIFF(instance->common.te_last, instance->common.te_shot) < instance->common.te_delta) - && (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { - if (instance->common.code_count_bit < instance->common.code_min_count_bit_for_found) { + } else if( + (DURATION_DIFF(instance->common.te_last, instance->common.te_shot) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) { + if(instance->common.code_count_bit < + instance->common.code_min_count_bit_for_found) { subghz_protocol_common_add_bit(&instance->common, 1); } instance->common.parser_step = 2; - } else if ((DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta) - && (DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta)) { - if (instance->common.code_count_bit < instance->common.code_min_count_bit_for_found) { + } else if( + (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta)) { + if(instance->common.code_count_bit < + instance->common.code_min_count_bit_for_found) { subghz_protocol_common_add_bit(&instance->common, 0); } instance->common.parser_step = 2; @@ -267,29 +301,152 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui } void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t output) { - uint32_t code_found_hi = instance->common.code_found >> 32; - uint32_t code_found_lo = instance->common.code_found & 0x00000000ffffffff; + subghz_protocol_keeloq_check_remote_controller(instance); + uint32_t code_found_hi = instance->common.code_last_found >> 32; + uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff; - uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); + uint64_t code_found_reverse = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); - uint32_t code_found_reverse_hi = code_found_reverse>>32; - uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff; + uint32_t code_found_reverse_hi = code_found_reverse >> 32; + uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; string_cat_printf( output, - "Protocol %s, %d Bit\r\n" + "%s, %d Bit\r\n" "KEY:0x%lX%lX\r\n" "FIX:%08lX MF:%s \r\n" "HOP:%08lX \r\n" "SN:%07lX CNT:%04X B:%02lX\r\n", instance->common.name, - instance->common.code_count_bit, + instance->common.code_last_count_bit, code_found_hi, code_found_lo, code_found_reverse_hi, instance->manufacture_name, code_found_reverse_lo, instance->common.serial, - instance->common.cnt, - instance->common.btn - ); + instance->common.cnt, + instance->common.btn); +} + +uint64_t subghz_protocol_keeloq_gen_key(SubGhzProtocolKeeloq* instance) { + uint32_t fix = instance->common.btn << 28 | instance->common.serial; + uint32_t decrypt = instance->common.btn << 28 | (instance->common.serial & 0x3FF) << 16 | + instance->common.cnt; + uint32_t hop = 0; + uint64_t man_normal_learning = 0; + int res = 0; + + for + M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) { + res = strcmp(string_get_cstr(manufacture_code->name), instance->manufacture_name); + if(res == 0) { + switch(manufacture_code->type) { + case KEELOQ_LEARNING_SIMPLE: + //Simple Learning + hop = subghz_protocol_keeloq_common_encrypt(decrypt, manufacture_code->key); + break; + case KEELOQ_LEARNING_NORMAL: + //Simple Learning + man_normal_learning = + subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); + hop = subghz_protocol_keeloq_common_encrypt(decrypt, man_normal_learning); + break; + case KEELOQ_LEARNING_UNKNOWN: + hop = 0; //todo + break; + } + break; + } + } + uint64_t yek = (uint64_t)fix << 32 | hop; + return subghz_protocol_common_reverse_key(yek, instance->common.code_last_count_bit); +} + +void subghz_protocol_keeloq_to_save_str(SubGhzProtocolKeeloq* instance, string_t output) { + string_printf( + output, + "Protocol: %s\n" + "Bit: %d\n" + "Manufacture_name: %s\n" + "Serial: %08lX\n" + "Cnt: %04lX\n" + "Btn: %01lX\n", + instance->common.name, + instance->common.code_last_count_bit, + instance->manufacture_name, + instance->common.serial, + instance->common.cnt, + instance->common.btn); +} + +bool subghz_protocol_keeloq_to_load_protocol( + FileWorker* file_worker, + SubGhzProtocolKeeloq* instance) { + bool loaded = false; + string_t temp_str; + string_init(temp_str); + string_t temp_name_man; + string_init(temp_name_man); + int res = 0; + int data = 0; + + do { + // Read and parse bit data from 2nd line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data); + if(res != 1) { + break; + } + instance->common.code_last_count_bit = (uint8_t)data; + + // Read and parse name protocol from 3st line + if(!file_worker_read_until(file_worker, temp_name_man, '\n')) { + break; + } + // strlen("Manufacture_name: ") = 18 + string_right(temp_name_man, 18); + instance->manufacture_name = string_get_cstr(temp_name_man); + + // Read and parse key data from 4nd line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + uint32_t temp_param = 0; + res = sscanf(string_get_cstr(temp_str), "Serial: %08lX\n", &temp_param); + if(res != 1) { + break; + } + instance->common.serial = temp_param; + + // Read and parse key data from 5nd line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + res = sscanf(string_get_cstr(temp_str), "Cnt: %04lX\n", &temp_param); + if(res != 1) { + break; + } + instance->common.cnt = (uint16_t)temp_param; + + // Read and parse key data from 5nd line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + res = sscanf(string_get_cstr(temp_str), "Btn: %01lX\n", &temp_param); + if(res != 1) { + break; + } + instance->common.btn = (uint8_t)temp_param; + + instance->common.code_last_found = subghz_protocol_keeloq_gen_key(instance); + + loaded = true; + } while(0); + string_clear(temp_name_man); + string_clear(temp_str); + + return loaded; } diff --git a/lib/subghz/protocols/subghz_protocol_keeloq.h b/lib/subghz/protocols/subghz_protocol_keeloq.h index 298a6e97b83..4560c725b50 100644 --- a/lib/subghz/protocols/subghz_protocol_keeloq.h +++ b/lib/subghz/protocols/subghz_protocol_keeloq.h @@ -45,3 +45,6 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui * @param output - output string */ void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t output); + +void subghz_protocol_keeloq_to_save_str(SubGhzProtocolKeeloq* instance, string_t output); +bool subghz_protocol_keeloq_to_load_protocol(FileWorker* file_worker, SubGhzProtocolKeeloq* instance); diff --git a/lib/subghz/protocols/subghz_protocol_keeloq_common.h b/lib/subghz/protocols/subghz_protocol_keeloq_common.h index 109df6cdca7..33b9021ebdb 100644 --- a/lib/subghz/protocols/subghz_protocol_keeloq_common.h +++ b/lib/subghz/protocols/subghz_protocol_keeloq_common.h @@ -1,5 +1,7 @@ #pragma once #include "subghz_protocol_common.h" +#include "file-worker.h" + #include diff --git a/lib/subghz/protocols/subghz_protocol_nero_sketch.c b/lib/subghz/protocols/subghz_protocol_nero_sketch.c index 5f9f6a519a8..8e22b0f3c97 100644 --- a/lib/subghz/protocols/subghz_protocol_nero_sketch.c +++ b/lib/subghz/protocols/subghz_protocol_nero_sketch.c @@ -14,6 +14,10 @@ SubGhzProtocolNeroSketch* subghz_protocol_nero_sketch_alloc(void) { instance->common.te_long = 660; instance->common.te_delta = 150; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nero_sketch_to_str; + instance->common.to_save_string = + (SubGhzProtocolCommonGetStrSave)subghz_protocol_nero_sketch_to_save_str; + instance->common.to_load_protocol= + (SubGhzProtocolCommonLoad)subghz_protocol_nero_sketch_to_load_protocol; return instance; } @@ -80,18 +84,18 @@ void subghz_protocol_nero_sketch_reset(SubGhzProtocolNeroSketch* instance) { * * @param instance SubGhzProtocolNeroSketch instance */ -void subghz_protocol_nero_sketch_check_remote_controller(SubGhzProtocolNeroSketch* instance) { - //пока не понятно с серийником, но код статический - // uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); - // uint32_t code_fix = code_found_reverse & 0xFFFFFFFF; - // //uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFF; +// void subghz_protocol_nero_sketch_check_remote_controller(SubGhzProtocolNeroSketch* instance) { +// //пока не понятно с серийником, но код статический +// // uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); +// // uint32_t code_fix = code_found_reverse & 0xFFFFFFFF; +// // //uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFF; - // instance->common.serial = code_fix & 0xFFFFFFF; - // instance->common.btn = (code_fix >> 28) & 0x0F; +// // instance->common.serial = code_fix & 0xFFFFFFF; +// // instance->common.btn = (code_fix >> 28) & 0x0F; - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); +// //if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); -} +// } void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool level, uint32_t duration) { switch (instance->common.parser_step) { @@ -140,7 +144,11 @@ void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool //Found stop bit instance->common.parser_step = 0; if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { - subghz_protocol_nero_sketch_check_remote_controller(instance); + + instance->common.code_last_found = instance->common.code_found; + instance->common.code_last_count_bit = instance->common.code_count_bit; + if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + } instance->common.code_found = 0; instance->common.code_count_bit = 0; @@ -176,25 +184,77 @@ void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool void subghz_protocol_nero_sketch_to_str(SubGhzProtocolNeroSketch* instance, string_t output) { - uint32_t code_found_hi = instance->common.code_found >> 32; - uint32_t code_found_lo = instance->common.code_found & 0x00000000ffffffff; + uint32_t code_found_hi = instance->common.code_last_found >> 32; + uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff; - uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); + uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit); uint32_t code_found_reverse_hi = code_found_reverse>>32; uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff; - //uint32_t rev_hi = - string_cat_printf(output, - "Protocol %s, %d Bit\r\n" + "%s, %d Bit\r\n" " KEY:0x%lX%08lX\r\n" " YEK:0x%lX%08lX\r\n", instance->common.name, - instance->common.code_count_bit, + instance->common.code_last_count_bit, code_found_hi, code_found_lo, code_found_reverse_hi, code_found_reverse_lo ); } + +void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, string_t output) { + uint32_t code_found_hi = instance->common.code_last_found >> 32; + uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff; + + string_printf( + output, + "Protocol: %s\n" + "Bit: %d\n" + "Key: %08lX%08lX\n", + instance->common.name, + instance->common.code_last_count_bit, + code_found_hi, + code_found_lo + ); +} + +bool subghz_protocol_nero_sketch_to_load_protocol(FileWorker* file_worker, SubGhzProtocolNeroSketch* instance){ + bool loaded = false; + string_t temp_str; + string_init(temp_str); + int res = 0; + int data = 0; + + do { + // Read and parse bit data from 2nd line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data); + if(res != 1) { + break; + } + instance->common.code_last_count_bit = (uint8_t)data; + + // Read and parse key data from 3nd line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + uint32_t temp_key_hi = 0; + uint32_t temp_key_lo = 0; + res = sscanf(string_get_cstr(temp_str), "Key: %08lX%08lX\n", &temp_key_hi, &temp_key_lo); + if(res != 2) { + break; + } + instance->common.code_last_found = (uint64_t)temp_key_hi<<32 | temp_key_lo; + + loaded = true; + } while(0); + + string_clear(temp_str); + + return loaded; +} diff --git a/lib/subghz/protocols/subghz_protocol_nero_sketch.h b/lib/subghz/protocols/subghz_protocol_nero_sketch.h index 99d5dbca24e..4fcce1c21d5 100644 --- a/lib/subghz/protocols/subghz_protocol_nero_sketch.h +++ b/lib/subghz/protocols/subghz_protocol_nero_sketch.h @@ -49,3 +49,6 @@ void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool * @param output - output string */ void subghz_protocol_nero_sketch_to_str(SubGhzProtocolNeroSketch* instance, string_t output); + +void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, string_t output); +bool subghz_protocol_nero_sketch_to_load_protocol(FileWorker* file_worker, SubGhzProtocolNeroSketch* instance); diff --git a/lib/subghz/protocols/subghz_protocol_princeton.c b/lib/subghz/protocols/subghz_protocol_princeton.c index c2817e08be5..210f0db023d 100644 --- a/lib/subghz/protocols/subghz_protocol_princeton.c +++ b/lib/subghz/protocols/subghz_protocol_princeton.c @@ -1,39 +1,120 @@ #include "subghz_protocol_princeton.h" - /* * Help * https://phreakerclub.com/447 * */ -struct SubGhzProtocolPrinceton { +#define SUBGHZ_PT_SHORT 450 +#define SUBGHZ_PT_LONG (SUBGHZ_PT_SHORT * 3) +#define SUBGHZ_PT_GUARD (SUBGHZ_PT_SHORT * 30) + +struct SubGhzEncoderPrinceton { + uint32_t key; + uint16_t te; + size_t repeat; + size_t front; +}; + +struct SubGhzDecoderPrinceton { SubGhzProtocolCommon common; + uint16_t te; }; -SubGhzProtocolPrinceton* subghz_protocol_princeton_alloc(void) { - SubGhzProtocolPrinceton* instance = furi_alloc(sizeof(SubGhzProtocolPrinceton)); +SubGhzEncoderPrinceton* subghz_encoder_princeton_alloc() { + SubGhzEncoderPrinceton* instance = furi_alloc(sizeof(SubGhzEncoderPrinceton)); + + + return instance; +} + +void subghz_encoder_princeton_free(SubGhzEncoderPrinceton* instance) { + furi_assert(instance); + free(instance); +} +void subghz_encoder_princeton_set_te(SubGhzEncoderPrinceton* instance, void* decoder){ + SubGhzDecoderPrinceton* pricenton = decoder; + if((pricenton->te) !=0){ + instance->te = pricenton->te; + }else{ + instance->te = SUBGHZ_PT_SHORT; + } +} + + +void subghz_encoder_princeton_reset(SubGhzEncoderPrinceton* instance, uint32_t key, size_t repeat) { + furi_assert(instance); + instance->te = SUBGHZ_PT_SHORT; + instance->key = key; + instance->repeat = repeat; + instance->front = 48; +} + +size_t subghz_encoder_princeton_get_repeat_left(SubGhzEncoderPrinceton* instance) { + furi_assert(instance); + return instance->repeat; +} + +LevelDuration subghz_encoder_princeton_yield(void* context) { + SubGhzEncoderPrinceton* instance = context; + if(instance->repeat == 0) return level_duration_reset(); + + size_t bit = instance->front / 2; + bool level = !(instance->front % 2); + + LevelDuration ret; + if(bit < 24) { + uint8_t byte = bit / 8; + uint8_t bit_in_byte = bit % 8; + bool value = (((uint8_t*)&instance->key)[2 - byte] >> (7 - bit_in_byte)) & 1; + if(value) { + ret = level_duration_make(level, level ? instance->te * 3 : instance->te); + } else { + ret = level_duration_make(level, level ? instance->te : instance->te * 3); + } + } else { + ret = level_duration_make(level, level ? instance->te : instance->te * 30); + } + + instance->front++; + if(instance->front == 50) { + instance->repeat--; + instance->front = 0; + } + + return ret; +} + + +SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc(void) { + SubGhzDecoderPrinceton* instance = furi_alloc(sizeof(SubGhzDecoderPrinceton)); instance->common.name = "Princeton"; instance->common.code_min_count_bit_for_found = 24; - instance->common.te_shot = 450;//150; - instance->common.te_long = 1350;//450; - instance->common.te_delta = 200;//50; + instance->common.te_shot = 450; //150; + instance->common.te_long = 1350; //450; + instance->common.te_delta = 200; //50; + instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_decoder_princeton_to_str; + instance->common.to_save_string = + (SubGhzProtocolCommonGetStrSave)subghz_decoder_princeton_to_save_str; + instance->common.to_load_protocol= + (SubGhzProtocolCommonLoad)subghz_decoder_princeton_to_load_protocol; return instance; } -void subghz_protocol_princeton_free(SubGhzProtocolPrinceton* instance) { +void subghz_decoder_princeton_free(SubGhzDecoderPrinceton* instance) { furi_assert(instance); free(instance); } /** Send bit * - * @param instance - SubGhzProtocolPrinceton instance + * @param instance - SubGhzDecoderPrinceton instance * @param bit - bit */ -void subghz_protocol_princeton_send_bit(SubGhzProtocolPrinceton* instance, uint8_t bit) { - if (bit) { +void subghz_decoder_princeton_send_bit(SubGhzDecoderPrinceton* instance, uint8_t bit) { + if(bit) { //send bit 1 SUBGHZ_TX_PIN_LOW(); delay_us(instance->common.te_long); @@ -48,29 +129,36 @@ void subghz_protocol_princeton_send_bit(SubGhzProtocolPrinceton* instance, uint8 } } -void subghz_protocol_princeton_send_key(SubGhzProtocolPrinceton* instance, uint64_t key, uint8_t bit,uint8_t repeat) { - while (repeat--) { +void subghz_decoder_princeton_send_key( + SubGhzDecoderPrinceton* instance, + uint64_t key, + uint8_t bit, + uint8_t repeat) { + while(repeat--) { SUBGHZ_TX_PIN_LOW(); //Send start bit - subghz_protocol_princeton_send_bit(instance, 1); + subghz_decoder_princeton_send_bit(instance, 1); //Send header delay_us(instance->common.te_shot * 33); //+2 interval v bit 1 //Send key data - for (uint8_t i = bit; i > 0; i--) { - subghz_protocol_princeton_send_bit(instance, bit_read(key, i - 1)); + for(uint8_t i = bit; i > 0; i--) { + subghz_decoder_princeton_send_bit(instance, bit_read(key, i - 1)); } } } -void subghz_protocol_princeton_reset(SubGhzProtocolPrinceton* instance) { +void subghz_decoder_princeton_reset(SubGhzDecoderPrinceton* instance) { instance->common.parser_step = 0; } -void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, bool level, uint32_t duration) { - switch (instance->common.parser_step) { +void subghz_decoder_princeton_parse( + SubGhzDecoderPrinceton* instance, + bool level, + uint32_t duration) { + switch(instance->common.parser_step) { case 0: - if ((!level) - && (DURATION_DIFF(duration,instance->common.te_shot * 36) < instance->common.te_delta * 36)) { + if((!level) && (DURATION_DIFF(duration, instance->common.te_shot * 36) < + instance->common.te_delta * 36)) { //Found Preambula instance->common.parser_step = 1; instance->common.code_found = 0; @@ -81,33 +169,49 @@ void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, bool lev break; case 1: //save duration - if (level) { + if(level) { instance->common.te_last = duration; instance->common.parser_step = 2; } break; case 2: - if (!level) { - if (duration >= (instance->common.te_shot * 10 + instance->common.te_delta)) { + if(!level) { + if(duration >= (instance->common.te_shot * 10 + instance->common.te_delta)) { instance->common.parser_step = 1; - if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { + if(instance->common.code_count_bit >= + instance->common.code_min_count_bit_for_found) { + if(instance->common.code_last_found == instance->common.code_found) { + //instance->te = (instance->te+instance->common.te_last)/2; //Option 1 TE averaging + if(instance->te > instance->common.te_last) + instance->te = instance->common.te_last; //Option 2 TE averaging + } else { + instance->te = instance->common.te_last; + } + instance->common.code_last_found = instance->common.code_found; + instance->common.code_last_count_bit = instance->common.code_count_bit; instance->common.serial = instance->common.code_found >> 4; instance->common.btn = (uint8_t)instance->common.code_found & 0x00000F; - if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + if(instance->common.callback) + instance->common.callback( + (SubGhzProtocolCommon*)instance, instance->common.context); } instance->common.code_found = 0; instance->common.code_count_bit = 0; break; } - if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot)< instance->common.te_delta) - && (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta*3)) { + if((DURATION_DIFF(instance->common.te_last, instance->common.te_shot) < + instance->common.te_delta) && + (DURATION_DIFF(duration, instance->common.te_long) < + instance->common.te_delta * 3)) { subghz_protocol_common_add_bit(&instance->common, 0); instance->common.parser_step = 1; - } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta*3) - && (DURATION_DIFF(duration,instance->common.te_shot)< instance->common.te_delta)) { + } else if( + (DURATION_DIFF(instance->common.te_last, instance->common.te_long) < + instance->common.te_delta * 3) && + (DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta)) { subghz_protocol_common_add_bit(&instance->common, 1); instance->common.parser_step = 1; } else { @@ -119,3 +223,92 @@ void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, bool lev break; } } + +void subghz_decoder_princeton_to_str(SubGhzDecoderPrinceton* instance, string_t output) { + uint32_t code_found_hi = instance->common.code_last_found >> 32; + uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff; + + uint64_t code_found_reverse = subghz_protocol_common_reverse_key( + instance->common.code_last_found, instance->common.code_last_count_bit); + + uint32_t code_found_reverse_hi = code_found_reverse >> 32; + uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; + + string_cat_printf( + output, + "%s %d Bit te %dus\r\n" + " KEY:0x%lX%08lX\r\n" + " YEK:0x%lX%08lX\r\n" + " SN:0x%05lX BTN:%02X\r\n", + instance->common.name, + instance->common.code_last_count_bit, + instance->te, + code_found_hi, + code_found_lo, + code_found_reverse_hi, + code_found_reverse_lo, + instance->common.serial, + instance->common.btn); +} + +void subghz_decoder_princeton_to_save_str(SubGhzDecoderPrinceton* instance, string_t output) { + string_printf( + output, + "Protocol: %s\n" + "Bit: %d\n" + "Te: %d\n" + "Key: %08lX\n", + instance->common.name, + instance->common.code_last_count_bit, + instance->te, + (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff)); +} + +bool subghz_decoder_princeton_to_load_protocol(FileWorker* file_worker, SubGhzDecoderPrinceton* instance){ + bool loaded = false; + string_t temp_str; + string_init(temp_str); + int res = 0; + int data = 0; + + do { + // Read and parse bit data from 2nd line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data); + if(res != 1) { + break; + } + instance->common.code_last_count_bit = (uint8_t)data; + + // Read and parse te data from 3nd line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + res = sscanf(string_get_cstr(temp_str), "Te: %d\n", &data); + if(res != 1) { + break; + } + instance->te = (uint16_t)data; + + // Read and parse key data from 4nd line + if(!file_worker_read_until(file_worker, temp_str, '\n')) { + break; + } + uint32_t temp_key = 0; + res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key); + if(res != 1) { + break; + } + instance->common.code_last_found = (uint64_t)temp_key; + instance->common.serial = instance->common.code_last_found >> 4; + instance->common.btn = (uint8_t)instance->common.code_last_found & 0x00000F; + + loaded = true; + } while(0); + + string_clear(temp_str); + + return loaded; +} diff --git a/lib/subghz/protocols/subghz_protocol_princeton.h b/lib/subghz/protocols/subghz_protocol_princeton.h index 8d260462a54..7feeb978982 100644 --- a/lib/subghz/protocols/subghz_protocol_princeton.h +++ b/lib/subghz/protocols/subghz_protocol_princeton.h @@ -2,38 +2,90 @@ #include "subghz_protocol_common.h" -typedef struct SubGhzProtocolPrinceton SubGhzProtocolPrinceton; -/** Allocate SubGhzProtocolPrinceton +/** SubGhzEncoderPrinceton anonymous type */ +typedef struct SubGhzEncoderPrinceton SubGhzEncoderPrinceton; + +/** Allocate SubGhzEncoderPrinceton + * @return pointer to SubGhzEncoderPrinceton instance + */ +SubGhzEncoderPrinceton* subghz_encoder_princeton_alloc(); + +/** Free SubGhzEncoderPrinceton instance + * @param instance - SubGhzEncoderPrinceton instance + */ +void subghz_encoder_princeton_free(SubGhzEncoderPrinceton* instance); + + +/** Reset encoder with new params + * @param instance - SubGhzEncoderPrinceton instance + * @param key - 24bit key + * @param repeat - how many times to repeat + */ +void subghz_encoder_princeton_reset(SubGhzEncoderPrinceton* instance, uint32_t key, size_t repeat); + +/** Get repeat count left + * @param instance - SubGhzEncoderPrinceton instance + * @return repeat count left + */ +size_t subghz_encoder_princeton_get_repeat_left(SubGhzEncoderPrinceton* instance); + +/** Get level duration + * @param instance - SubGhzEncoderPrinceton instance + * @return level duration + */ +LevelDuration subghz_encoder_princeton_yield(void* context); + + +/** SubGhzDecoderPrinceton anonymous type */ +typedef struct SubGhzDecoderPrinceton SubGhzDecoderPrinceton; + + +void subghz_encoder_princeton_set_te( + SubGhzEncoderPrinceton* instance, + void* decoder); + +/** Allocate SubGhzDecoderPrinceton * - * @return SubGhzProtocolPrinceton* + * @return SubGhzDecoderPrinceton* */ -SubGhzProtocolPrinceton* subghz_protocol_princeton_alloc(); +SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc(); -/** Free SubGhzProtocolPrinceton +/** Free SubGhzDecoderPrinceton * * @param instance */ -void subghz_protocol_princeton_free(SubGhzProtocolPrinceton* instance); +void subghz_decoder_princeton_free(SubGhzDecoderPrinceton* instance); /** Sends the key on the air * - * @param instance - SubGhzProtocolPrinceton instance + * @param instance - SubGhzDecoderPrinceton instance * @param key - key send * @param bit - count bit key * @param repeat - repeat send key */ -void subghz_protocol_princeton_send_key(SubGhzProtocolPrinceton* instance, uint64_t key, uint8_t bit, uint8_t repeat); +void subghz_decoder_princeton_send_key(SubGhzDecoderPrinceton* instance, uint64_t key, uint8_t bit, uint8_t repeat); /** Reset internal state - * @param instance - SubGhzProtocolPrinceton instance + * @param instance - SubGhzDecoderPrinceton instance */ -void subghz_protocol_princeton_reset(SubGhzProtocolPrinceton* instance); +void subghz_decoder_princeton_reset(SubGhzDecoderPrinceton* instance); /** Parse accepted duration * - * @param instance - SubGhzProtocolPrinceton instance + * @param instance - SubGhzDecoderPrinceton instance * @param data - LevelDuration level_duration */ -void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, bool level, uint32_t duration); +void subghz_decoder_princeton_parse(SubGhzDecoderPrinceton* instance, bool level, uint32_t duration); + +/** Outputting information from the parser + * + * @param instance - SubGhzDecoderPrinceton* instance + * @param output - output string + */ +void subghz_decoder_princeton_to_str(SubGhzDecoderPrinceton* instance, string_t output); + +void subghz_decoder_princeton_to_save_str(SubGhzDecoderPrinceton* instance, string_t output); +bool subghz_decoder_princeton_to_load_protocol(FileWorker* file_worker, SubGhzDecoderPrinceton* instance); + diff --git a/lib/subghz/subghz_worker.h b/lib/subghz/subghz_worker.h index 53af3102234..6ef101904bd 100644 --- a/lib/subghz/subghz_worker.h +++ b/lib/subghz/subghz_worker.h @@ -1,6 +1,6 @@ #pragma once -#include +#include typedef struct SubGhzWorker SubGhzWorker;