diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bed54dfa0..6626f9ae2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -22,9 +22,6 @@ /applications/main/subghz/ @skotopes @DrZlo13 @hedger @Skorpionm /applications/main/u2f/ @skotopes @DrZlo13 @hedger @nminaylov -/applications/external/bt_hid_app/ @skotopes @DrZlo13 @hedger @gornekich -/applications/external/picopass/ @skotopes @DrZlo13 @hedger @gornekich - /applications/services/bt/ @skotopes @DrZlo13 @hedger @gornekich /applications/services/cli/ @skotopes @DrZlo13 @hedger @nminaylov /applications/services/crypto/ @skotopes @DrZlo13 @hedger @nminaylov diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9fbcb16eb..b9eb4d709 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -201,7 +201,7 @@ jobs: - name: Build example & external apps with uFBT run: | - for appdir in 'applications/external' 'applications/examples'; do + for appdir in 'applications/examples'; do for app in $(find "$appdir" -maxdepth 1 -mindepth 1 -type d); do pushd $app TARGETS_FAM=$(grep "targets" application.fam || echo "${{ matrix.target }}") diff --git a/.gitmodules b/.gitmodules index 4fba0483e..52cf4a207 100644 --- a/.gitmodules +++ b/.gitmodules @@ -26,9 +26,6 @@ [submodule "lib/cxxheaderparser"] path = lib/cxxheaderparser url = https://github.com/robotpy/cxxheaderparser.git -[submodule "applications/external/dap_link/lib/free-dap"] - path = applications/external/dap_link/lib/free-dap - url = https://github.com/ataradov/free-dap.git [submodule "lib/heatshrink"] path = lib/heatshrink url = https://github.com/flipperdevices/heatshrink.git diff --git a/.pvsoptions b/.pvsoptions index b25d4633e..2e0b2fb8d 100644 --- a/.pvsoptions +++ b/.pvsoptions @@ -1 +1 @@ ---ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/cmsis_core -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/micro-ecc -e lib/microtar -e lib/mlib -e lib/qrcode -e lib/ST25RFAL002 -e lib/stm32wb_cmsis -e lib/stm32wb_copro -e lib/stm32wb_hal -e lib/u8g2 -e lib/nanopb -e */arm-none-eabi/* -e applications/external/dap_link/lib/free-dap +--ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/cmsis_core -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/micro-ecc -e lib/microtar -e lib/mlib -e lib/qrcode -e lib/ST25RFAL002 -e lib/stm32wb_cmsis -e lib/stm32wb_copro -e lib/stm32wb_hal -e lib/u8g2 -e lib/nanopb -e */arm-none-eabi/* diff --git a/applications/ReadMe.md b/applications/ReadMe.md index 10e54ce22..91ef02bbb 100644 --- a/applications/ReadMe.md +++ b/applications/ReadMe.md @@ -33,22 +33,10 @@ Applications for main Flipper menu. - `nfc` - NFC application, HF rfid, EMV and etc - `subghz` - SubGhz application, 433 fobs and etc - `u2f` - U2F Application - - -## External - -External applications deployed to SD Card - - `clock` - Clock application -- `dap_link` - DAP Link OnChip debugger -- `hid_app` - USB/BT Remote controller - `music_player` - Music player app (demo) -- `nfc_magic` - NFC MFC Magic card application -- `picopass` - Picopass reader / writer -- `signal_generator` - Signal generator app: PWM and clock generator - `snake_game` - Snake game application -- `spi_mem_manager` - SPI Memory reader / flasher -- `weather_station` - SubGHz weather station + ## services diff --git a/applications/external/application.fam b/applications/external/application.fam deleted file mode 100644 index 12dc1cc1a..000000000 --- a/applications/external/application.fam +++ /dev/null @@ -1,6 +0,0 @@ -# Placeholder -App( - appid="external_apps", - name="External apps bundle", - apptype=FlipperAppType.METAPACKAGE, -) diff --git a/applications/external/avr_isp_programmer/application.fam b/applications/external/avr_isp_programmer/application.fam deleted file mode 100644 index 19556d03d..000000000 --- a/applications/external/avr_isp_programmer/application.fam +++ /dev/null @@ -1,17 +0,0 @@ -App( - appid="avr_isp", - name="AVR Flasher", - apptype=FlipperAppType.EXTERNAL, - entry_point="avr_isp_app", - requires=["gui"], - stack_size=4 * 1024, - order=20, - fap_icon="avr_app_icon_10x10.png", - fap_category="GPIO", - fap_icon_assets="images", - fap_private_libs=[ - Lib( - name="driver", - ), - ], -) diff --git a/applications/external/avr_isp_programmer/avr_app_icon_10x10.png b/applications/external/avr_isp_programmer/avr_app_icon_10x10.png deleted file mode 100644 index 533787fe3..000000000 Binary files a/applications/external/avr_isp_programmer/avr_app_icon_10x10.png and /dev/null differ diff --git a/applications/external/avr_isp_programmer/avr_isp_app.c b/applications/external/avr_isp_programmer/avr_isp_app.c deleted file mode 100644 index 740dc3610..000000000 --- a/applications/external/avr_isp_programmer/avr_isp_app.c +++ /dev/null @@ -1,179 +0,0 @@ -#include "avr_isp_app_i.h" - -static bool avr_isp_app_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - AvrIspApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool avr_isp_app_back_event_callback(void* context) { - furi_assert(context); - AvrIspApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -static void avr_isp_app_tick_event_callback(void* context) { - furi_assert(context); - AvrIspApp* app = context; - scene_manager_handle_tick_event(app->scene_manager); -} - -AvrIspApp* avr_isp_app_alloc() { - AvrIspApp* app = malloc(sizeof(AvrIspApp)); - - app->file_path = furi_string_alloc(); - furi_string_set(app->file_path, STORAGE_APP_DATA_PATH_PREFIX); - app->error = AvrIspErrorNoError; - - // GUI - app->gui = furi_record_open(RECORD_GUI); - - // View Dispatcher - app->view_dispatcher = view_dispatcher_alloc(); - app->scene_manager = scene_manager_alloc(&avr_isp_scene_handlers, app); - view_dispatcher_enable_queue(app->view_dispatcher); - - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - view_dispatcher_set_custom_event_callback( - app->view_dispatcher, avr_isp_app_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, avr_isp_app_back_event_callback); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, avr_isp_app_tick_event_callback, 100); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - // Open Notification record - app->notifications = furi_record_open(RECORD_NOTIFICATION); - - // SubMenu - app->submenu = submenu_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, AvrIspViewSubmenu, submenu_get_view(app->submenu)); - - // Widget - app->widget = widget_alloc(); - view_dispatcher_add_view(app->view_dispatcher, AvrIspViewWidget, widget_get_view(app->widget)); - - // Text Input - app->text_input = text_input_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, AvrIspViewTextInput, text_input_get_view(app->text_input)); - - // Popup - app->popup = popup_alloc(); - view_dispatcher_add_view(app->view_dispatcher, AvrIspViewPopup, popup_get_view(app->popup)); - - //Dialog - app->dialogs = furi_record_open(RECORD_DIALOGS); - - // Programmer view - app->avr_isp_programmer_view = avr_isp_programmer_view_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - AvrIspViewProgrammer, - avr_isp_programmer_view_get_view(app->avr_isp_programmer_view)); - - // Reader view - app->avr_isp_reader_view = avr_isp_reader_view_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - AvrIspViewReader, - avr_isp_reader_view_get_view(app->avr_isp_reader_view)); - - // Writer view - app->avr_isp_writer_view = avr_isp_writer_view_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - AvrIspViewWriter, - avr_isp_writer_view_get_view(app->avr_isp_writer_view)); - - // Chip detect view - app->avr_isp_chip_detect_view = avr_isp_chip_detect_view_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - AvrIspViewChipDetect, - avr_isp_chip_detect_view_get_view(app->avr_isp_chip_detect_view)); - - // Enable 5v power, multiple attempts to avoid issues with power chip protection false triggering - uint8_t attempts = 0; - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - furi_delay_ms(10); - } - - scene_manager_next_scene(app->scene_manager, AvrIspSceneStart); - - return app; -} //-V773 - -void avr_isp_app_free(AvrIspApp* app) { - furi_assert(app); - - // Disable 5v power - if(furi_hal_power_is_otg_enabled()) { - furi_hal_power_disable_otg(); - } - - // Submenu - view_dispatcher_remove_view(app->view_dispatcher, AvrIspViewSubmenu); - submenu_free(app->submenu); - - // Widget - view_dispatcher_remove_view(app->view_dispatcher, AvrIspViewWidget); - widget_free(app->widget); - - // TextInput - view_dispatcher_remove_view(app->view_dispatcher, AvrIspViewTextInput); - text_input_free(app->text_input); - - // Popup - view_dispatcher_remove_view(app->view_dispatcher, AvrIspViewPopup); - popup_free(app->popup); - - //Dialog - furi_record_close(RECORD_DIALOGS); - - // Programmer view - view_dispatcher_remove_view(app->view_dispatcher, AvrIspViewProgrammer); - avr_isp_programmer_view_free(app->avr_isp_programmer_view); - - // Reader view - view_dispatcher_remove_view(app->view_dispatcher, AvrIspViewReader); - avr_isp_reader_view_free(app->avr_isp_reader_view); - - // Writer view - view_dispatcher_remove_view(app->view_dispatcher, AvrIspViewWriter); - avr_isp_writer_view_free(app->avr_isp_writer_view); - - // Chip detect view - view_dispatcher_remove_view(app->view_dispatcher, AvrIspViewChipDetect); - avr_isp_chip_detect_view_free(app->avr_isp_chip_detect_view); - - // View dispatcher - view_dispatcher_free(app->view_dispatcher); - scene_manager_free(app->scene_manager); - - // Notifications - furi_record_close(RECORD_NOTIFICATION); - app->notifications = NULL; - - // Close records - furi_record_close(RECORD_GUI); - - // Path strings - furi_string_free(app->file_path); - - free(app); -} - -int32_t avr_isp_app(void* p) { - UNUSED(p); - AvrIspApp* avr_isp_app = avr_isp_app_alloc(); - - view_dispatcher_run(avr_isp_app->view_dispatcher); - - avr_isp_app_free(avr_isp_app); - - return 0; -} diff --git a/applications/external/avr_isp_programmer/avr_isp_app_i.c b/applications/external/avr_isp_programmer/avr_isp_app_i.c deleted file mode 100644 index 7a7fa6d7f..000000000 --- a/applications/external/avr_isp_programmer/avr_isp_app_i.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "avr_isp_app_i.h" -#include -#include - -#define TAG "AvrIsp" - -bool avr_isp_load_from_file(AvrIspApp* app) { - furi_assert(app); - - FuriString* file_path = furi_string_alloc(); - FuriString* file_name = furi_string_alloc(); - - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options( - &browser_options, AVR_ISP_APP_EXTENSION, &I_avr_app_icon_10x10); - browser_options.base_path = STORAGE_APP_DATA_PATH_PREFIX; - - // Input events and views are managed by file_select - bool res = dialog_file_browser_show(app->dialogs, file_path, app->file_path, &browser_options); - - if(res) { - path_extract_dirname(furi_string_get_cstr(file_path), app->file_path); - path_extract_filename(file_path, file_name, true); - strncpy(app->file_name_tmp, furi_string_get_cstr(file_name), AVR_ISP_MAX_LEN_NAME); - } - - furi_string_free(file_name); - furi_string_free(file_path); - - return res; -} diff --git a/applications/external/avr_isp_programmer/avr_isp_app_i.h b/applications/external/avr_isp_programmer/avr_isp_app_i.h deleted file mode 100644 index 17c69f8f2..000000000 --- a/applications/external/avr_isp_programmer/avr_isp_app_i.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "helpers/avr_isp_types.h" -#include - -#include "scenes/avr_isp_scene.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "views/avr_isp_view_programmer.h" -#include "views/avr_isp_view_reader.h" -#include "views/avr_isp_view_writer.h" -#include "views/avr_isp_view_chip_detect.h" - -#define AVR_ISP_MAX_LEN_NAME 64 - -typedef struct { - Gui* gui; - ViewDispatcher* view_dispatcher; - SceneManager* scene_manager; - NotificationApp* notifications; - DialogsApp* dialogs; - Popup* popup; - Submenu* submenu; - Widget* widget; - TextInput* text_input; - FuriString* file_path; - char file_name_tmp[AVR_ISP_MAX_LEN_NAME]; - AvrIspProgrammerView* avr_isp_programmer_view; - AvrIspReaderView* avr_isp_reader_view; - AvrIspWriterView* avr_isp_writer_view; - AvrIspChipDetectView* avr_isp_chip_detect_view; - AvrIspError error; -} AvrIspApp; - -bool avr_isp_load_from_file(AvrIspApp* app); \ No newline at end of file diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp.c b/applications/external/avr_isp_programmer/helpers/avr_isp.c deleted file mode 100644 index 283c17bfd..000000000 --- a/applications/external/avr_isp_programmer/helpers/avr_isp.c +++ /dev/null @@ -1,496 +0,0 @@ -#include "avr_isp.h" -#include "../lib/driver/avr_isp_prog_cmd.h" -#include "../lib/driver/avr_isp_spi_sw.h" - -#include - -#define AVR_ISP_PROG_TX_RX_BUF_SIZE 320 -#define TAG "AvrIsp" - -struct AvrIsp { - AvrIspSpiSw* spi; - bool pmode; - AvrIspCallback callback; - void* context; -}; - -AvrIsp* avr_isp_alloc(void) { - AvrIsp* instance = malloc(sizeof(AvrIsp)); - return instance; -} - -void avr_isp_free(AvrIsp* instance) { - furi_assert(instance); - - if(instance->spi) avr_isp_end_pmode(instance); - free(instance); -} - -void avr_isp_set_tx_callback(AvrIsp* instance, AvrIspCallback callback, void* context) { - furi_assert(instance); - furi_assert(context); - - instance->callback = callback; - instance->context = context; -} - -uint8_t avr_isp_spi_transaction( - AvrIsp* instance, - uint8_t cmd, - uint8_t addr_hi, - uint8_t addr_lo, - uint8_t data) { - furi_assert(instance); - - avr_isp_spi_sw_txrx(instance->spi, cmd); - avr_isp_spi_sw_txrx(instance->spi, addr_hi); - avr_isp_spi_sw_txrx(instance->spi, addr_lo); - return avr_isp_spi_sw_txrx(instance->spi, data); -} - -static bool avr_isp_set_pmode(AvrIsp* instance, uint8_t a, uint8_t b, uint8_t c, uint8_t d) { - furi_assert(instance); - - uint8_t res = 0; - avr_isp_spi_sw_txrx(instance->spi, a); - avr_isp_spi_sw_txrx(instance->spi, b); - res = avr_isp_spi_sw_txrx(instance->spi, c); - avr_isp_spi_sw_txrx(instance->spi, d); - return res == 0x53; -} - -void avr_isp_end_pmode(AvrIsp* instance) { - furi_assert(instance); - - if(instance->pmode) { - avr_isp_spi_sw_res_set(instance->spi, true); - // We're about to take the target out of reset - // so configure SPI pins as input - if(instance->spi) avr_isp_spi_sw_free(instance->spi); - instance->spi = NULL; - } - - instance->pmode = false; -} - -static bool avr_isp_start_pmode(AvrIsp* instance, AvrIspSpiSwSpeed spi_speed) { - furi_assert(instance); - - // Reset target before driving PIN_SCK or PIN_MOSI - - // SPI.begin() will configure SS as output, - // so SPI master mode is selected. - // We have defined RESET as pin 10, - // which for many arduino's is not the SS pin. - // So we have to configure RESET as output here, - // (reset_target() first sets the correct level) - if(instance->spi) avr_isp_spi_sw_free(instance->spi); - instance->spi = avr_isp_spi_sw_init(spi_speed); - - avr_isp_spi_sw_res_set(instance->spi, false); - // See avr datasheets, chapter "SERIAL_PRG Programming Algorithm": - - // Pulse RESET after PIN_SCK is low: - avr_isp_spi_sw_sck_set(instance->spi, false); - - // discharge PIN_SCK, value arbitrally chosen - furi_delay_ms(20); - avr_isp_spi_sw_res_set(instance->spi, true); - - // Pulse must be minimum 2 target CPU speed cycles - // so 100 usec is ok for CPU speeds above 20KHz - furi_delay_ms(1); - - avr_isp_spi_sw_res_set(instance->spi, false); - - // Send the enable programming command: - // datasheet: must be > 20 msec - furi_delay_ms(50); - if(avr_isp_set_pmode(instance, AVR_ISP_SET_PMODE)) { - instance->pmode = true; - return true; - } - return false; -} - -bool avr_isp_auto_set_spi_speed_start_pmode(AvrIsp* instance) { - furi_assert(instance); - - AvrIspSpiSwSpeed spi_speed[] = { - AvrIspSpiSwSpeed1Mhz, - AvrIspSpiSwSpeed400Khz, - AvrIspSpiSwSpeed250Khz, - AvrIspSpiSwSpeed125Khz, - AvrIspSpiSwSpeed60Khz, - AvrIspSpiSwSpeed40Khz, - AvrIspSpiSwSpeed20Khz, - AvrIspSpiSwSpeed10Khz, - AvrIspSpiSwSpeed5Khz, - AvrIspSpiSwSpeed1Khz, - }; - for(uint8_t i = 0; i < COUNT_OF(spi_speed); i++) { - if(avr_isp_start_pmode(instance, spi_speed[i])) { - AvrIspSignature sig = avr_isp_read_signature(instance); - AvrIspSignature sig_examination = avr_isp_read_signature(instance); //-V656 - uint8_t y = 0; - while(y < 8) { - if(memcmp((uint8_t*)&sig, (uint8_t*)&sig_examination, sizeof(AvrIspSignature)) != - 0) - break; - sig_examination = avr_isp_read_signature(instance); - y++; - } - if(y == 8) { - if(spi_speed[i] > AvrIspSpiSwSpeed1Mhz) { - if(i < (COUNT_OF(spi_speed) - 1)) { - avr_isp_end_pmode(instance); - i++; - return avr_isp_start_pmode(instance, spi_speed[i]); - } - } - return true; - } - } - } - - if(instance->spi) { - avr_isp_spi_sw_free(instance->spi); - instance->spi = NULL; - } - - return false; -} - -static void avr_isp_commit(AvrIsp* instance, uint16_t addr, uint8_t data) { - furi_assert(instance); - - avr_isp_spi_transaction(instance, AVR_ISP_COMMIT(addr)); - /* polling flash */ - if(data == 0xFF) { - furi_delay_ms(5); - } else { - /* polling flash */ - uint32_t starttime = furi_get_tick(); - while((furi_get_tick() - starttime) < 30) { - if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FLASH_HI(addr)) != 0xFF) { - break; - }; - } - } -} - -static uint16_t avr_isp_current_page(AvrIsp* instance, uint32_t addr, uint16_t page_size) { - furi_assert(instance); - - uint16_t page = 0; - switch(page_size) { - case 32: - page = addr & 0xFFFFFFF0; - break; - case 64: - page = addr & 0xFFFFFFE0; - break; - case 128: - page = addr & 0xFFFFFFC0; - break; - case 256: - page = addr & 0xFFFFFF80; - break; - - default: - page = addr; - break; - } - - return page; -} - -static bool avr_isp_flash_write_pages( - AvrIsp* instance, - uint16_t addr, - uint16_t page_size, - uint8_t* data, - uint32_t data_size) { - furi_assert(instance); - - size_t x = 0; - uint16_t page = avr_isp_current_page(instance, addr, page_size); - - while(x < data_size) { - if(page != avr_isp_current_page(instance, addr, page_size)) { - avr_isp_commit(instance, page, data[x - 1]); - page = avr_isp_current_page(instance, addr, page_size); - } - avr_isp_spi_transaction(instance, AVR_ISP_WRITE_FLASH_LO(addr, data[x++])); - avr_isp_spi_transaction(instance, AVR_ISP_WRITE_FLASH_HI(addr, data[x++])); - addr++; - } - avr_isp_commit(instance, page, data[x - 1]); - return true; -} - -bool avr_isp_erase_chip(AvrIsp* instance) { - furi_assert(instance); - - bool ret = false; - if(!instance->pmode) avr_isp_auto_set_spi_speed_start_pmode(instance); - if(instance->pmode) { - avr_isp_spi_transaction(instance, AVR_ISP_ERASE_CHIP); - furi_delay_ms(100); - avr_isp_end_pmode(instance); - ret = true; - } - return ret; -} - -static bool - avr_isp_eeprom_write(AvrIsp* instance, uint16_t addr, uint8_t* data, uint32_t data_size) { - furi_assert(instance); - - for(uint16_t i = 0; i < data_size; i++) { - avr_isp_spi_transaction(instance, AVR_ISP_WRITE_EEPROM(addr, data[i])); - furi_delay_ms(10); - addr++; - } - return true; -} - -bool avr_isp_write_page( - AvrIsp* instance, - uint32_t mem_type, - uint32_t mem_size, - uint16_t addr, - uint16_t page_size, - uint8_t* data, - uint32_t data_size) { - furi_assert(instance); - - bool ret = false; - switch(mem_type) { - case STK_SET_FLASH_TYPE: - if((addr + data_size / 2) <= mem_size) { - ret = avr_isp_flash_write_pages(instance, addr, page_size, data, data_size); - } - break; - - case STK_SET_EEPROM_TYPE: - if((addr + data_size) <= mem_size) { - ret = avr_isp_eeprom_write(instance, addr, data, data_size); - } - break; - - default: - furi_crash(TAG " Incorrect mem type."); - break; - } - - return ret; -} - -static bool avr_isp_flash_read_page( - AvrIsp* instance, - uint16_t addr, - uint16_t page_size, - uint8_t* data, - uint32_t data_size) { - furi_assert(instance); - - if(page_size > data_size) return false; - for(uint16_t i = 0; i < page_size; i += 2) { - data[i] = avr_isp_spi_transaction(instance, AVR_ISP_READ_FLASH_LO(addr)); - data[i + 1] = avr_isp_spi_transaction(instance, AVR_ISP_READ_FLASH_HI(addr)); - addr++; - } - return true; -} - -static bool avr_isp_eeprom_read_page( - AvrIsp* instance, - uint16_t addr, - uint16_t page_size, - uint8_t* data, - uint32_t data_size) { - furi_assert(instance); - - if(page_size > data_size) return false; - for(uint16_t i = 0; i < page_size; i++) { - data[i] = avr_isp_spi_transaction(instance, AVR_ISP_READ_EEPROM(addr)); - addr++; - } - return true; -} - -bool avr_isp_read_page( - AvrIsp* instance, - uint32_t mem_type, - uint16_t addr, - uint16_t page_size, - uint8_t* data, - uint32_t data_size) { - furi_assert(instance); - - bool res = false; - if(mem_type == STK_SET_FLASH_TYPE) - res = avr_isp_flash_read_page(instance, addr, page_size, data, data_size); - if(mem_type == STK_SET_EEPROM_TYPE) - res = avr_isp_eeprom_read_page(instance, addr, page_size, data, data_size); - - return res; -} - -AvrIspSignature avr_isp_read_signature(AvrIsp* instance) { - furi_assert(instance); - - AvrIspSignature signature; - signature.vendor = avr_isp_spi_transaction(instance, AVR_ISP_READ_VENDOR); - signature.part_family = avr_isp_spi_transaction(instance, AVR_ISP_READ_PART_FAMILY); - signature.part_number = avr_isp_spi_transaction(instance, AVR_ISP_READ_PART_NUMBER); - return signature; -} - -uint8_t avr_isp_read_lock_byte(AvrIsp* instance) { - furi_assert(instance); - - uint8_t data = 0; - uint32_t starttime = furi_get_tick(); - while((furi_get_tick() - starttime) < 300) { - data = avr_isp_spi_transaction(instance, AVR_ISP_READ_LOCK_BYTE); - if(avr_isp_spi_transaction(instance, AVR_ISP_READ_LOCK_BYTE) == data) { - break; - }; - data = 0x00; - } - return data; -} - -bool avr_isp_write_lock_byte(AvrIsp* instance, uint8_t lock) { - furi_assert(instance); - - bool ret = false; - if(avr_isp_read_lock_byte(instance) == lock) { - ret = true; - } else { - avr_isp_spi_transaction(instance, AVR_ISP_WRITE_LOCK_BYTE(lock)); - /* polling lock byte */ - uint32_t starttime = furi_get_tick(); - while((furi_get_tick() - starttime) < 30) { - if(avr_isp_spi_transaction(instance, AVR_ISP_READ_LOCK_BYTE) == lock) { - ret = true; - break; - }; - } - } - return ret; -} - -uint8_t avr_isp_read_fuse_low(AvrIsp* instance) { - furi_assert(instance); - - uint8_t data = 0; - uint32_t starttime = furi_get_tick(); - while((furi_get_tick() - starttime) < 300) { - data = avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_LOW); - if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_LOW) == data) { - break; - }; - data = 0x00; - } - return data; -} - -bool avr_isp_write_fuse_low(AvrIsp* instance, uint8_t lfuse) { - furi_assert(instance); - - bool ret = false; - if(avr_isp_read_fuse_low(instance) == lfuse) { - ret = true; - } else { - avr_isp_spi_transaction(instance, AVR_ISP_WRITE_FUSE_LOW(lfuse)); - /* polling fuse */ - uint32_t starttime = furi_get_tick(); - while((furi_get_tick() - starttime) < 30) { - if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_LOW) == lfuse) { - ret = true; - break; - }; - } - } - return ret; -} - -uint8_t avr_isp_read_fuse_high(AvrIsp* instance) { - furi_assert(instance); - - uint8_t data = 0; - uint32_t starttime = furi_get_tick(); - while((furi_get_tick() - starttime) < 300) { - data = avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_HIGH); - if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_HIGH) == data) { - break; - }; - data = 0x00; - } - return data; -} - -bool avr_isp_write_fuse_high(AvrIsp* instance, uint8_t hfuse) { - furi_assert(instance); - - bool ret = false; - if(avr_isp_read_fuse_high(instance) == hfuse) { - ret = true; - } else { - avr_isp_spi_transaction(instance, AVR_ISP_WRITE_FUSE_HIGH(hfuse)); - /* polling fuse */ - uint32_t starttime = furi_get_tick(); - while((furi_get_tick() - starttime) < 30) { - if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_HIGH) == hfuse) { - ret = true; - break; - }; - } - } - return ret; -} - -uint8_t avr_isp_read_fuse_extended(AvrIsp* instance) { - furi_assert(instance); - - uint8_t data = 0; - uint32_t starttime = furi_get_tick(); - while((furi_get_tick() - starttime) < 300) { - data = avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_EXTENDED); - if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_EXTENDED) == data) { - break; - }; - data = 0x00; - } - return data; -} - -bool avr_isp_write_fuse_extended(AvrIsp* instance, uint8_t efuse) { - furi_assert(instance); - - bool ret = false; - if(avr_isp_read_fuse_extended(instance) == efuse) { - ret = true; - } else { - avr_isp_spi_transaction(instance, AVR_ISP_WRITE_FUSE_EXTENDED(efuse)); - /* polling fuse */ - uint32_t starttime = furi_get_tick(); - while((furi_get_tick() - starttime) < 30) { - if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_EXTENDED) == efuse) { - ret = true; - break; - }; - } - } - return ret; -} - -void avr_isp_write_extended_addr(AvrIsp* instance, uint8_t extended_addr) { - furi_assert(instance); - - avr_isp_spi_transaction(instance, AVR_ISP_EXTENDED_ADDR(extended_addr)); - furi_delay_ms(10); -} \ No newline at end of file diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp.h b/applications/external/avr_isp_programmer/helpers/avr_isp.h deleted file mode 100644 index 476fc3d64..000000000 --- a/applications/external/avr_isp_programmer/helpers/avr_isp.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include - -typedef struct AvrIsp AvrIsp; -typedef void (*AvrIspCallback)(void* context); - -struct AvrIspSignature { - uint8_t vendor; - uint8_t part_family; - uint8_t part_number; -}; - -typedef struct AvrIspSignature AvrIspSignature; - -AvrIsp* avr_isp_alloc(void); - -void avr_isp_free(AvrIsp* instance); - -void avr_isp_set_tx_callback(AvrIsp* instance, AvrIspCallback callback, void* context); - -bool avr_isp_auto_set_spi_speed_start_pmode(AvrIsp* instance); - -AvrIspSignature avr_isp_read_signature(AvrIsp* instance); - -void avr_isp_end_pmode(AvrIsp* instance); - -bool avr_isp_erase_chip(AvrIsp* instance); - -uint8_t avr_isp_spi_transaction( - AvrIsp* instance, - uint8_t cmd, - uint8_t addr_hi, - uint8_t addr_lo, - uint8_t data); - -bool avr_isp_read_page( - AvrIsp* instance, - uint32_t memtype, - uint16_t addr, - uint16_t page_size, - uint8_t* data, - uint32_t data_size); - -bool avr_isp_write_page( - AvrIsp* instance, - uint32_t mem_type, - uint32_t mem_size, - uint16_t addr, - uint16_t page_size, - uint8_t* data, - uint32_t data_size); - -uint8_t avr_isp_read_lock_byte(AvrIsp* instance); - -bool avr_isp_write_lock_byte(AvrIsp* instance, uint8_t lock); - -uint8_t avr_isp_read_fuse_low(AvrIsp* instance); - -bool avr_isp_write_fuse_low(AvrIsp* instance, uint8_t lfuse); - -uint8_t avr_isp_read_fuse_high(AvrIsp* instance); - -bool avr_isp_write_fuse_high(AvrIsp* instance, uint8_t hfuse); - -uint8_t avr_isp_read_fuse_extended(AvrIsp* instance); - -bool avr_isp_write_fuse_extended(AvrIsp* instance, uint8_t efuse); - -void avr_isp_write_extended_addr(AvrIsp* instance, uint8_t extended_addr); \ No newline at end of file diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp_event.h b/applications/external/avr_isp_programmer/helpers/avr_isp_event.h deleted file mode 100644 index c704b5b35..000000000 --- a/applications/external/avr_isp_programmer/helpers/avr_isp_event.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -typedef enum { - //SubmenuIndex - SubmenuIndexAvrIspProgrammer = 10, - SubmenuIndexAvrIspReader, - SubmenuIndexAvrIspWriter, - SubmenuIndexAvrIsWiring, - SubmenuIndexAvrIspAbout, - - //AvrIspCustomEvent - AvrIspCustomEventSceneChipDetectOk = 100, - AvrIspCustomEventSceneReadingOk, - AvrIspCustomEventSceneWritingOk, - AvrIspCustomEventSceneErrorVerification, - AvrIspCustomEventSceneErrorReading, - AvrIspCustomEventSceneErrorWriting, - AvrIspCustomEventSceneErrorWritingFuse, - AvrIspCustomEventSceneInputName, - AvrIspCustomEventSceneSuccess, - AvrIspCustomEventSceneExit, - AvrIspCustomEventSceneExitStartMenu, -} AvrIspCustomEvent; diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp_types.h b/applications/external/avr_isp_programmer/helpers/avr_isp_types.h deleted file mode 100644 index 5e174ec3b..000000000 --- a/applications/external/avr_isp_programmer/helpers/avr_isp_types.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include -#include - -#define AVR_ISP_VERSION_APP "0.1" -#define AVR_ISP_DEVELOPED "SkorP" -#define AVR_ISP_GITHUB "https://github.com/flipperdevices/flipperzero-firmware" - -#define AVR_ISP_APP_FILE_VERSION 1 -#define AVR_ISP_APP_FILE_TYPE "Flipper Dump AVR" -#define AVR_ISP_APP_EXTENSION ".avr" - -typedef enum { - //AvrIspViewVariableItemList, - AvrIspViewSubmenu, - AvrIspViewProgrammer, - AvrIspViewReader, - AvrIspViewWriter, - AvrIspViewWidget, - AvrIspViewPopup, - AvrIspViewTextInput, - AvrIspViewChipDetect, -} AvrIspView; - -typedef enum { - AvrIspErrorNoError, - AvrIspErrorReading, - AvrIspErrorWriting, - AvrIspErrorVerification, - AvrIspErrorWritingFuse, -} AvrIspError; \ No newline at end of file diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp_worker.c b/applications/external/avr_isp_programmer/helpers/avr_isp_worker.c deleted file mode 100644 index dfe1f43c2..000000000 --- a/applications/external/avr_isp_programmer/helpers/avr_isp_worker.c +++ /dev/null @@ -1,266 +0,0 @@ -#include "avr_isp_worker.h" -#include -#include "../lib/driver/avr_isp_prog.h" -#include "../lib/driver/avr_isp_prog_cmd.h" -#include "../lib/driver/avr_isp_chip_arr.h" - -#include - -#define TAG "AvrIspWorker" - -typedef enum { - AvrIspWorkerEvtStop = (1 << 0), - - AvrIspWorkerEvtRx = (1 << 1), - AvrIspWorkerEvtTxCoplete = (1 << 2), - AvrIspWorkerEvtTx = (1 << 3), - AvrIspWorkerEvtState = (1 << 4), - - //AvrIspWorkerEvtCfg = (1 << 5), - -} AvrIspWorkerEvt; - -struct AvrIspWorker { - FuriThread* thread; - volatile bool worker_running; - uint8_t connect_usb; - AvrIspWorkerCallback callback; - void* context; -}; - -#define AVR_ISP_WORKER_PROG_ALL_EVENTS (AvrIspWorkerEvtStop) -#define AVR_ISP_WORKER_ALL_EVENTS \ - (AvrIspWorkerEvtTx | AvrIspWorkerEvtTxCoplete | AvrIspWorkerEvtRx | AvrIspWorkerEvtStop | \ - AvrIspWorkerEvtState) - -//########################/* VCP CDC */############################################# -#include "usb_cdc.h" -#include -#include -#include - -#define AVR_ISP_VCP_CDC_CH 1 -#define AVR_ISP_VCP_CDC_PKT_LEN CDC_DATA_SZ -#define AVR_ISP_VCP_UART_RX_BUF_SIZE (AVR_ISP_VCP_CDC_PKT_LEN * 5) - -static void vcp_on_cdc_tx_complete(void* context); -static void vcp_on_cdc_rx(void* context); -static void vcp_state_callback(void* context, uint8_t state); -static void vcp_on_cdc_control_line(void* context, uint8_t state); -static void vcp_on_line_config(void* context, struct usb_cdc_line_coding* config); - -static const CdcCallbacks cdc_cb = { - vcp_on_cdc_tx_complete, - vcp_on_cdc_rx, - vcp_state_callback, - vcp_on_cdc_control_line, - vcp_on_line_config, -}; - -/* VCP callbacks */ - -static void vcp_on_cdc_tx_complete(void* context) { - furi_assert(context); - AvrIspWorker* instance = context; - furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerEvtTxCoplete); -} - -static void vcp_on_cdc_rx(void* context) { - furi_assert(context); - AvrIspWorker* instance = context; - furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerEvtRx); -} - -static void vcp_state_callback(void* context, uint8_t state) { - UNUSED(context); - - AvrIspWorker* instance = context; - instance->connect_usb = state; - furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerEvtState); -} - -static void vcp_on_cdc_control_line(void* context, uint8_t state) { - UNUSED(context); - UNUSED(state); -} - -static void vcp_on_line_config(void* context, struct usb_cdc_line_coding* config) { - UNUSED(context); - UNUSED(config); -} - -static void avr_isp_worker_vcp_cdc_init(void* context) { - furi_hal_usb_unlock(); - Cli* cli = furi_record_open(RECORD_CLI); - //close cli - cli_session_close(cli); - //disable callbacks VCP_CDC=0 - furi_hal_cdc_set_callbacks(0, NULL, NULL); - //set 2 cdc - furi_check(furi_hal_usb_set_config(&usb_cdc_dual, NULL) == true); - //open cli VCP_CDC=0 - cli_session_open(cli, &cli_vcp); - furi_record_close(RECORD_CLI); - - furi_hal_cdc_set_callbacks(AVR_ISP_VCP_CDC_CH, (CdcCallbacks*)&cdc_cb, context); -} - -static void avr_isp_worker_vcp_cdc_deinit(void) { - //disable callbacks AVR_ISP_VCP_CDC_CH - furi_hal_cdc_set_callbacks(AVR_ISP_VCP_CDC_CH, NULL, NULL); - - Cli* cli = furi_record_open(RECORD_CLI); - //close cli - cli_session_close(cli); - furi_hal_usb_unlock(); - //set 1 cdc - furi_check(furi_hal_usb_set_config(&usb_cdc_single, NULL) == true); - //open cli VCP_CDC=0 - cli_session_open(cli, &cli_vcp); - furi_record_close(RECORD_CLI); -} - -//################################################################################# - -static int32_t avr_isp_worker_prog_thread(void* context) { - AvrIspProg* prog = context; - FURI_LOG_D(TAG, "AvrIspProgWorker Start"); - while(1) { - if(furi_thread_flags_get() & AvrIspWorkerEvtStop) break; - avr_isp_prog_avrisp(prog); - } - FURI_LOG_D(TAG, "AvrIspProgWorker Stop"); - return 0; -} - -static void avr_isp_worker_prog_tx_data(void* context) { - furi_assert(context); - AvrIspWorker* instance = context; - furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerEvtTx); -} - -/** Worker thread - * - * @param context - * @return exit code - */ -static int32_t avr_isp_worker_thread(void* context) { - AvrIspWorker* instance = context; - avr_isp_worker_vcp_cdc_init(instance); - - /* start PWM on &gpio_ext_pa4 */ - furi_hal_pwm_start(FuriHalPwmOutputIdLptim2PA4, 4000000, 50); - - AvrIspProg* prog = avr_isp_prog_init(); - avr_isp_prog_set_tx_callback(prog, avr_isp_worker_prog_tx_data, instance); - - uint8_t buf[AVR_ISP_VCP_UART_RX_BUF_SIZE]; - size_t len = 0; - - FuriThread* prog_thread = - furi_thread_alloc_ex("AvrIspProgWorker", 1024, avr_isp_worker_prog_thread, prog); - furi_thread_start(prog_thread); - - FURI_LOG_D(TAG, "Start"); - - while(instance->worker_running) { - uint32_t events = - furi_thread_flags_wait(AVR_ISP_WORKER_ALL_EVENTS, FuriFlagWaitAny, FuriWaitForever); - - if(events & AvrIspWorkerEvtRx) { - if(avr_isp_prog_spaces_rx(prog) >= AVR_ISP_VCP_CDC_PKT_LEN) { - len = furi_hal_cdc_receive(AVR_ISP_VCP_CDC_CH, buf, AVR_ISP_VCP_CDC_PKT_LEN); - // for(uint8_t i = 0; i < len; i++) { - // FURI_LOG_I(TAG, "--> %X", buf[i]); - // } - avr_isp_prog_rx(prog, buf, len); - } else { - furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerEvtRx); - } - } - - if((events & AvrIspWorkerEvtTxCoplete) || (events & AvrIspWorkerEvtTx)) { - len = avr_isp_prog_tx(prog, buf, AVR_ISP_VCP_CDC_PKT_LEN); - - // for(uint8_t i = 0; i < len; i++) { - // FURI_LOG_I(TAG, "<-- %X", buf[i]); - // } - - if(len > 0) furi_hal_cdc_send(AVR_ISP_VCP_CDC_CH, buf, len); - } - - if(events & AvrIspWorkerEvtStop) { - break; - } - - if(events & AvrIspWorkerEvtState) { - if(instance->callback) - instance->callback(instance->context, (bool)instance->connect_usb); - } - } - - FURI_LOG_D(TAG, "Stop"); - - furi_thread_flags_set(furi_thread_get_id(prog_thread), AvrIspWorkerEvtStop); - avr_isp_prog_exit(prog); - furi_delay_ms(10); - furi_thread_join(prog_thread); - furi_thread_free(prog_thread); - - avr_isp_prog_free(prog); - furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4); - avr_isp_worker_vcp_cdc_deinit(); - return 0; -} - -AvrIspWorker* avr_isp_worker_alloc(void* context) { - furi_assert(context); - UNUSED(context); - AvrIspWorker* instance = malloc(sizeof(AvrIspWorker)); - - instance->thread = furi_thread_alloc_ex("AvrIspWorker", 2048, avr_isp_worker_thread, instance); - return instance; -} - -void avr_isp_worker_free(AvrIspWorker* instance) { - furi_assert(instance); - - furi_check(!instance->worker_running); - furi_thread_free(instance->thread); - free(instance); -} - -void avr_isp_worker_set_callback( - AvrIspWorker* instance, - AvrIspWorkerCallback callback, - void* context) { - furi_assert(instance); - - instance->callback = callback; - instance->context = context; -} - -void avr_isp_worker_start(AvrIspWorker* instance) { - furi_assert(instance); - furi_assert(!instance->worker_running); - - instance->worker_running = true; - - furi_thread_start(instance->thread); -} - -void avr_isp_worker_stop(AvrIspWorker* instance) { - furi_assert(instance); - furi_assert(instance->worker_running); - - instance->worker_running = false; - furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerEvtStop); - - furi_thread_join(instance->thread); -} - -bool avr_isp_worker_is_running(AvrIspWorker* instance) { - furi_assert(instance); - - return instance->worker_running; -} diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp_worker.h b/applications/external/avr_isp_programmer/helpers/avr_isp_worker.h deleted file mode 100644 index cd9897dff..000000000 --- a/applications/external/avr_isp_programmer/helpers/avr_isp_worker.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include - -typedef struct AvrIspWorker AvrIspWorker; - -typedef void (*AvrIspWorkerCallback)(void* context, bool connect_usb); - -/** Allocate AvrIspWorker - * - * @param context AvrIsp* context - * @return AvrIspWorker* - */ -AvrIspWorker* avr_isp_worker_alloc(void* context); - -/** Free AvrIspWorker - * - * @param instance AvrIspWorker instance - */ -void avr_isp_worker_free(AvrIspWorker* instance); - -/** Callback AvrIspWorker - * - * @param instance AvrIspWorker instance - * @param callback AvrIspWorkerOverrunCallback callback - * @param context - */ -void avr_isp_worker_set_callback( - AvrIspWorker* instance, - AvrIspWorkerCallback callback, - void* context); - -/** Start AvrIspWorker - * - * @param instance AvrIspWorker instance - */ -void avr_isp_worker_start(AvrIspWorker* instance); - -/** Stop AvrIspWorker - * - * @param instance AvrIspWorker instance - */ -void avr_isp_worker_stop(AvrIspWorker* instance); - -/** Check if worker is running - * @param instance AvrIspWorker instance - * @return bool - true if running - */ -bool avr_isp_worker_is_running(AvrIspWorker* instance); diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c b/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c deleted file mode 100644 index b4c12cbc3..000000000 --- a/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c +++ /dev/null @@ -1,1157 +0,0 @@ -#include "avr_isp_worker_rw.h" -#include -#include "avr_isp_types.h" -#include "avr_isp.h" -#include "../lib/driver/avr_isp_prog_cmd.h" -#include "../lib/driver/avr_isp_chip_arr.h" - -#include "flipper_i32hex_file.h" -#include - -#include - -#define TAG "AvrIspWorkerRW" - -#define NAME_PATERN_FLASH_FILE "flash.hex" -#define NAME_PATERN_EEPROM_FILE "eeprom.hex" - -struct AvrIspWorkerRW { - AvrIsp* avr_isp; - FuriThread* thread; - volatile bool worker_running; - - uint32_t chip_arr_ind; - bool chip_detect; - uint8_t lfuse; - uint8_t hfuse; - uint8_t efuse; - uint8_t lock; - float progress_flash; - float progress_eeprom; - const char* file_path; - const char* file_name; - AvrIspSignature signature; - AvrIspWorkerRWCallback callback; - void* context; - - AvrIspWorkerRWStatusCallback callback_status; - void* context_status; -}; - -typedef enum { - AvrIspWorkerRWEvtStop = (1 << 0), - - AvrIspWorkerRWEvtReading = (1 << 1), - AvrIspWorkerRWEvtVerification = (1 << 2), - AvrIspWorkerRWEvtWriting = (1 << 3), - AvrIspWorkerRWEvtWritingFuse = (1 << 4), - -} AvrIspWorkerRWEvt; -#define AVR_ISP_WORKER_ALL_EVENTS \ - (AvrIspWorkerRWEvtWritingFuse | AvrIspWorkerRWEvtWriting | AvrIspWorkerRWEvtVerification | \ - AvrIspWorkerRWEvtReading | AvrIspWorkerRWEvtStop) - -/** Worker thread - * - * @param context - * @return exit code - */ -static int32_t avr_isp_worker_rw_thread(void* context) { - AvrIspWorkerRW* instance = context; - - /* start PWM on &gpio_ext_pa4 */ - if(!furi_hal_pwm_is_running(FuriHalPwmOutputIdLptim2PA4)) { - furi_hal_pwm_start(FuriHalPwmOutputIdLptim2PA4, 4000000, 50); - } - - FURI_LOG_D(TAG, "Start"); - - while(1) { - uint32_t events = - furi_thread_flags_wait(AVR_ISP_WORKER_ALL_EVENTS, FuriFlagWaitAny, FuriWaitForever); - - if(events & AvrIspWorkerRWEvtStop) { - break; - } - - if(events & AvrIspWorkerRWEvtWritingFuse) { - if(avr_isp_worker_rw_write_fuse(instance, instance->file_path, instance->file_name)) { - if(instance->callback_status) - instance->callback_status( - instance->context_status, AvrIspWorkerRWStatusEndWritingFuse); - } else { - if(instance->callback_status) - instance->callback_status( - instance->context_status, AvrIspWorkerRWStatusErrorWritingFuse); - } - } - - if(events & AvrIspWorkerRWEvtWriting) { - if(avr_isp_worker_rw_write_dump(instance, instance->file_path, instance->file_name)) { - if(instance->callback_status) - instance->callback_status( - instance->context_status, AvrIspWorkerRWStatusEndWriting); - } else { - if(instance->callback_status) - instance->callback_status( - instance->context_status, AvrIspWorkerRWStatusErrorWriting); - } - } - - if(events & AvrIspWorkerRWEvtVerification) { - if(avr_isp_worker_rw_verification(instance, instance->file_path, instance->file_name)) { - if(instance->callback_status) - instance->callback_status( - instance->context_status, AvrIspWorkerRWStatusEndVerification); - } else { - if(instance->callback_status) - instance->callback_status( - instance->context_status, AvrIspWorkerRWStatusErrorVerification); - } - } - - if(events & AvrIspWorkerRWEvtReading) { - if(avr_isp_worker_rw_read_dump(instance, instance->file_path, instance->file_name)) { - if(instance->callback_status) - instance->callback_status( - instance->context_status, AvrIspWorkerRWStatusEndReading); - } else { - if(instance->callback_status) - instance->callback_status( - instance->context_status, AvrIspWorkerRWStatusErrorReading); - } - } - } - FURI_LOG_D(TAG, "Stop"); - - if(furi_hal_pwm_is_running(FuriHalPwmOutputIdLptim2PA4)) { - furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4); - } - - return 0; -} - -bool avr_isp_worker_rw_detect_chip(AvrIspWorkerRW* instance) { - furi_assert(instance); - - FURI_LOG_D(TAG, "Detecting AVR chip"); - - instance->chip_detect = false; - instance->chip_arr_ind = avr_isp_chip_arr_size + 1; - - /* start PWM on &gpio_ext_pa4 */ - bool was_pwm_enabled = false; - if(!furi_hal_pwm_is_running(FuriHalPwmOutputIdLptim2PA4)) { - furi_hal_pwm_start(FuriHalPwmOutputIdLptim2PA4, 4000000, 50); - } else { - was_pwm_enabled = true; - } - - do { - if(!avr_isp_auto_set_spi_speed_start_pmode(instance->avr_isp)) { - FURI_LOG_E(TAG, "Well, I managed to enter the mod program"); - break; - } - instance->signature = avr_isp_read_signature(instance->avr_isp); - - if(instance->signature.vendor != 0x1E) { - //No detect chip - } else { - for(uint32_t ind = 0; ind < avr_isp_chip_arr_size; ind++) { - if(avr_isp_chip_arr[ind].avrarch != F_AVR8) continue; - if(avr_isp_chip_arr[ind].sigs[1] == instance->signature.part_family) { - if(avr_isp_chip_arr[ind].sigs[2] == instance->signature.part_number) { - FURI_LOG_D(TAG, "Detect AVR chip = \"%s\"", avr_isp_chip_arr[ind].name); - FURI_LOG_D( - TAG, - "Signature = 0x%02X 0x%02X 0x%02X", - instance->signature.vendor, - instance->signature.part_family, - instance->signature.part_number); - - switch(avr_isp_chip_arr[ind].nfuses) { - case 1: - instance->lfuse = avr_isp_read_fuse_low(instance->avr_isp); - FURI_LOG_D(TAG, "Lfuse = %02X", instance->lfuse); - break; - case 2: - instance->lfuse = avr_isp_read_fuse_low(instance->avr_isp); - instance->hfuse = avr_isp_read_fuse_high(instance->avr_isp); - FURI_LOG_D( - TAG, "Lfuse = %02X Hfuse = %02X", instance->lfuse, instance->hfuse); - break; - case 3: - instance->lfuse = avr_isp_read_fuse_low(instance->avr_isp); - instance->hfuse = avr_isp_read_fuse_high(instance->avr_isp); - instance->efuse = avr_isp_read_fuse_extended(instance->avr_isp); - FURI_LOG_D( - TAG, - "Lfuse = %02X Hfuse = %02X Efuse = %02X", - instance->lfuse, - instance->hfuse, - instance->efuse); - break; - default: - break; - } - if(avr_isp_chip_arr[ind].nlocks == 1) { - instance->lock = avr_isp_read_lock_byte(instance->avr_isp); - FURI_LOG_D(TAG, "Lock = %02X", instance->lock); - } - instance->chip_detect = true; - instance->chip_arr_ind = ind; - break; - } - } - } - } - avr_isp_end_pmode(instance->avr_isp); - - } while(0); - - if(furi_hal_pwm_is_running(FuriHalPwmOutputIdLptim2PA4) && !was_pwm_enabled) { - furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4); - } - - if(instance->callback) { - if(instance->chip_arr_ind > avr_isp_chip_arr_size) { - instance->callback(instance->context, "No detect", instance->chip_detect, 0); - } else if(instance->chip_arr_ind < avr_isp_chip_arr_size) { - instance->callback( - instance->context, - avr_isp_chip_arr[instance->chip_arr_ind].name, - instance->chip_detect, - avr_isp_chip_arr[instance->chip_arr_ind].flashsize); - } else { - instance->callback(instance->context, "Unknown", instance->chip_detect, 0); - } - } - - return instance->chip_detect; -} - -AvrIspWorkerRW* avr_isp_worker_rw_alloc(void* context) { - furi_assert(context); - UNUSED(context); - - AvrIspWorkerRW* instance = malloc(sizeof(AvrIspWorkerRW)); - instance->avr_isp = avr_isp_alloc(); - - instance->thread = - furi_thread_alloc_ex("AvrIspWorkerRW", 4096, avr_isp_worker_rw_thread, instance); - - instance->chip_detect = false; - instance->lfuse = 0; - instance->hfuse = 0; - instance->efuse = 0; - instance->lock = 0; - instance->progress_flash = 0.0f; - instance->progress_eeprom = 0.0f; - - return instance; -} - -void avr_isp_worker_rw_free(AvrIspWorkerRW* instance) { - furi_assert(instance); - - avr_isp_free(instance->avr_isp); - - furi_check(!instance->worker_running); - furi_thread_free(instance->thread); - - free(instance); -} - -void avr_isp_worker_rw_start(AvrIspWorkerRW* instance) { - furi_assert(instance); - furi_assert(!instance->worker_running); - - instance->worker_running = true; - - furi_thread_start(instance->thread); -} - -void avr_isp_worker_rw_stop(AvrIspWorkerRW* instance) { - furi_assert(instance); - furi_assert(instance->worker_running); - - instance->worker_running = false; - furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerRWEvtStop); - - furi_thread_join(instance->thread); -} - -bool avr_isp_worker_rw_is_running(AvrIspWorkerRW* instance) { - furi_assert(instance); - - return instance->worker_running; -} - -void avr_isp_worker_rw_set_callback( - AvrIspWorkerRW* instance, - AvrIspWorkerRWCallback callback, - void* context) { - furi_assert(instance); - - instance->callback = callback; - instance->context = context; -} - -void avr_isp_worker_rw_set_callback_status( - AvrIspWorkerRW* instance, - AvrIspWorkerRWStatusCallback callback_status, - void* context_status) { - furi_assert(instance); - - instance->callback_status = callback_status; - instance->context_status = context_status; -} - -float avr_isp_worker_rw_get_progress_flash(AvrIspWorkerRW* instance) { - furi_assert(instance); - - return instance->progress_flash; -} - -float avr_isp_worker_rw_get_progress_eeprom(AvrIspWorkerRW* instance) { - furi_assert(instance); - - return instance->progress_eeprom; -} - -static void avr_isp_worker_rw_get_dump_flash(AvrIspWorkerRW* instance, const char* file_path) { - furi_assert(instance); - furi_check(instance->avr_isp); - - FURI_LOG_D(TAG, "Dump FLASH %s", file_path); - - FlipperI32HexFile* flipper_hex_flash = flipper_i32hex_file_open_write( - file_path, avr_isp_chip_arr[instance->chip_arr_ind].flashoffset); - - uint8_t data[272] = {0}; - bool send_extended_addr = ((avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2) > 0x10000); - uint8_t extended_addr = 0; - - for(int32_t i = avr_isp_chip_arr[instance->chip_arr_ind].flashoffset; - i < avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2; - i += avr_isp_chip_arr[instance->chip_arr_ind].pagesize / 2) { - if(send_extended_addr) { - if(extended_addr <= ((i >> 16) & 0xFF)) { - avr_isp_write_extended_addr(instance->avr_isp, extended_addr); - extended_addr = ((i >> 16) & 0xFF) + 1; - } - } - avr_isp_read_page( - instance->avr_isp, - STK_SET_FLASH_TYPE, - (uint16_t)i, - avr_isp_chip_arr[instance->chip_arr_ind].pagesize, - data, - sizeof(data)); - flipper_i32hex_file_bin_to_i32hex_set_data( - flipper_hex_flash, data, avr_isp_chip_arr[instance->chip_arr_ind].pagesize); - FURI_LOG_D(TAG, "%s", flipper_i32hex_file_get_string(flipper_hex_flash)); - instance->progress_flash = - (float)(i) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2.0f); - } - flipper_i32hex_file_bin_to_i32hex_set_end_line(flipper_hex_flash); - FURI_LOG_D(TAG, "%s", flipper_i32hex_file_get_string(flipper_hex_flash)); - flipper_i32hex_file_close(flipper_hex_flash); - instance->progress_flash = 1.0f; -} - -static void avr_isp_worker_rw_get_dump_eeprom(AvrIspWorkerRW* instance, const char* file_path) { - furi_assert(instance); - furi_check(instance->avr_isp); - - FURI_LOG_D(TAG, "Dump EEPROM %s", file_path); - - FlipperI32HexFile* flipper_hex_eeprom = flipper_i32hex_file_open_write( - file_path, avr_isp_chip_arr[instance->chip_arr_ind].eepromoffset); - - int32_t size_data = 32; - uint8_t data[256] = {0}; - - if(size_data > avr_isp_chip_arr[instance->chip_arr_ind].eepromsize) - size_data = avr_isp_chip_arr[instance->chip_arr_ind].eepromsize; - - for(int32_t i = avr_isp_chip_arr[instance->chip_arr_ind].eepromoffset; - i < avr_isp_chip_arr[instance->chip_arr_ind].eepromsize; - i += size_data) { - avr_isp_read_page( - instance->avr_isp, STK_SET_EEPROM_TYPE, (uint16_t)i, size_data, data, sizeof(data)); - flipper_i32hex_file_bin_to_i32hex_set_data(flipper_hex_eeprom, data, size_data); - FURI_LOG_D(TAG, "%s", flipper_i32hex_file_get_string(flipper_hex_eeprom)); - instance->progress_eeprom = - (float)(i) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].eepromsize); - } - flipper_i32hex_file_bin_to_i32hex_set_end_line(flipper_hex_eeprom); - FURI_LOG_D(TAG, "%s", flipper_i32hex_file_get_string(flipper_hex_eeprom)); - flipper_i32hex_file_close(flipper_hex_eeprom); - instance->progress_eeprom = 1.0f; -} - -bool avr_isp_worker_rw_read_dump( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name) { - furi_assert(instance); - furi_assert(file_path); - furi_assert(file_name); - - FURI_LOG_D(TAG, "Read dump chip"); - - instance->progress_flash = 0.0f; - instance->progress_eeprom = 0.0f; - bool ret = false; - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* flipper_format = flipper_format_file_alloc(storage); - FuriString* file_path_name = furi_string_alloc(); - - if(!avr_isp_worker_rw_detect_chip(instance)) { - FURI_LOG_E(TAG, "No detect AVR chip"); - } else { - do { - furi_string_printf( - file_path_name, "%s/%s%s", file_path, file_name, AVR_ISP_APP_EXTENSION); - if(!flipper_format_file_open_always( - flipper_format, furi_string_get_cstr(file_path_name))) { - FURI_LOG_E(TAG, "flipper_format_file_open_always"); - break; - } - if(!flipper_format_write_header_cstr( - flipper_format, AVR_ISP_APP_FILE_TYPE, AVR_ISP_APP_FILE_VERSION)) { - FURI_LOG_E(TAG, "flipper_format_write_header_cstr"); - break; - } - if(!flipper_format_write_string_cstr( - flipper_format, "Chip name", avr_isp_chip_arr[instance->chip_arr_ind].name)) { - FURI_LOG_E(TAG, "Chip name"); - break; - } - if(!flipper_format_write_hex( - flipper_format, - "Signature", - (uint8_t*)&instance->signature, - sizeof(AvrIspSignature))) { - FURI_LOG_E(TAG, "Unable to add Signature"); - break; - } - if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 0) { - if(!flipper_format_write_hex(flipper_format, "Lfuse", &instance->lfuse, 1)) { - FURI_LOG_E(TAG, "Unable to add Lfuse"); - break; - } - } - if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 1) { - if(!flipper_format_write_hex(flipper_format, "Hfuse", &instance->hfuse, 1)) { - FURI_LOG_E(TAG, "Unable to add Hfuse"); - break; - } - } - if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 2) { - if(!flipper_format_write_hex(flipper_format, "Efuse", &instance->efuse, 1)) { - FURI_LOG_E(TAG, "Unable to add Efuse"); - break; - } - } - if(avr_isp_chip_arr[instance->chip_arr_ind].nlocks == 1) { - if(!flipper_format_write_hex(flipper_format, "Lock", &instance->lock, 1)) { - FURI_LOG_E(TAG, "Unable to add Lock"); - break; - } - } - furi_string_printf(file_path_name, "%s_%s", file_name, NAME_PATERN_FLASH_FILE); - if(!flipper_format_write_string_cstr( - flipper_format, "Dump_flash", furi_string_get_cstr(file_path_name))) { - FURI_LOG_E(TAG, "Unable to add Dump_flash"); - break; - } - - if(avr_isp_chip_arr[instance->chip_arr_ind].eepromsize > 0) { - furi_string_printf(file_path_name, "%s_%s", file_name, NAME_PATERN_EEPROM_FILE); - if(avr_isp_chip_arr[instance->chip_arr_ind].eepromsize > 0) { - if(!flipper_format_write_string_cstr( - flipper_format, "Dump_eeprom", furi_string_get_cstr(file_path_name))) { - FURI_LOG_E(TAG, "Unable to add Dump_eeprom"); - break; - } - } - } - ret = true; - } while(false); - } - - flipper_format_free(flipper_format); - furi_record_close(RECORD_STORAGE); - - if(ret) { - if(avr_isp_auto_set_spi_speed_start_pmode(instance->avr_isp)) { - //Dump flash - furi_string_printf( - file_path_name, "%s/%s_%s", file_path, file_name, NAME_PATERN_FLASH_FILE); - avr_isp_worker_rw_get_dump_flash(instance, furi_string_get_cstr(file_path_name)); - //Dump eeprom - if(avr_isp_chip_arr[instance->chip_arr_ind].eepromsize > 0) { - furi_string_printf( - file_path_name, "%s/%s_%s", file_path, file_name, NAME_PATERN_EEPROM_FILE); - avr_isp_worker_rw_get_dump_eeprom(instance, furi_string_get_cstr(file_path_name)); - } - - avr_isp_end_pmode(instance->avr_isp); - } - } - - furi_string_free(file_path_name); - - return true; -} - -void avr_isp_worker_rw_read_dump_start( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name) { - furi_assert(instance); - - instance->file_path = file_path; - instance->file_name = file_name; - furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerRWEvtReading); -} - -static bool avr_isp_worker_rw_verification_flash(AvrIspWorkerRW* instance, const char* file_path) { - furi_assert(instance); - furi_assert(file_path); - - FURI_LOG_D(TAG, "Verification flash %s", file_path); - - instance->progress_flash = 0.0; - bool ret = true; - - FlipperI32HexFile* flipper_hex_flash = flipper_i32hex_file_open_read(file_path); - - uint8_t data_read_flash[272] = {0}; - uint8_t data_read_hex[272] = {0}; - - uint32_t addr = avr_isp_chip_arr[instance->chip_arr_ind].flashoffset; - bool send_extended_addr = ((avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2) > 0x10000); - uint8_t extended_addr = 0; - - FlipperI32HexFileRet flipper_hex_ret = flipper_i32hex_file_i32hex_to_bin_get_data( - flipper_hex_flash, data_read_hex, sizeof(data_read_hex)); - - while(((flipper_hex_ret.status == FlipperI32HexFileStatusData) || - (flipper_hex_ret.status == FlipperI32HexFileStatusUdateAddr)) && - ret) { - switch(flipper_hex_ret.status) { - case FlipperI32HexFileStatusData: - - if(send_extended_addr) { - if(extended_addr <= ((addr >> 16) & 0xFF)) { - avr_isp_write_extended_addr(instance->avr_isp, extended_addr); - extended_addr = ((addr >> 16) & 0xFF) + 1; - } - } - - avr_isp_read_page( - instance->avr_isp, - STK_SET_FLASH_TYPE, - (uint16_t)addr, - flipper_hex_ret.data_size, - data_read_flash, - sizeof(data_read_flash)); - - if(memcmp(data_read_hex, data_read_flash, flipper_hex_ret.data_size) != 0) { - ret = false; - - FURI_LOG_E(TAG, "Verification flash error"); - FURI_LOG_E(TAG, "Addr: 0x%04lX", addr); - for(uint32_t i = 0; i < flipper_hex_ret.data_size; i++) { - FURI_LOG_RAW_E("%02X ", data_read_hex[i]); - } - FURI_LOG_RAW_E("\r\n"); - for(uint32_t i = 0; i < flipper_hex_ret.data_size; i++) { - FURI_LOG_RAW_E("%02X ", data_read_flash[i]); - } - FURI_LOG_RAW_E("\r\n"); - } - - addr += flipper_hex_ret.data_size / 2; - instance->progress_flash = - (float)(addr) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2.0f); - break; - - case FlipperI32HexFileStatusUdateAddr: - addr = (data_read_hex[0] << 24 | data_read_hex[1] << 16) / 2; - break; - - default: - furi_crash(TAG " Incorrect status."); - break; - } - - flipper_hex_ret = flipper_i32hex_file_i32hex_to_bin_get_data( - flipper_hex_flash, data_read_hex, sizeof(data_read_hex)); - } - - flipper_i32hex_file_close(flipper_hex_flash); - instance->progress_flash = 1.0f; - - return ret; -} - -static bool - avr_isp_worker_rw_verification_eeprom(AvrIspWorkerRW* instance, const char* file_path) { - furi_assert(instance); - furi_assert(file_path); - - FURI_LOG_D(TAG, "Verification eeprom %s", file_path); - - instance->progress_eeprom = 0.0; - bool ret = true; - - FlipperI32HexFile* flipper_hex_eeprom = flipper_i32hex_file_open_read(file_path); - - uint8_t data_read_eeprom[272] = {0}; - uint8_t data_read_hex[272] = {0}; - - uint32_t addr = avr_isp_chip_arr[instance->chip_arr_ind].eepromoffset; - - FlipperI32HexFileRet flipper_hex_ret = flipper_i32hex_file_i32hex_to_bin_get_data( - flipper_hex_eeprom, data_read_hex, sizeof(data_read_hex)); - - while(((flipper_hex_ret.status == FlipperI32HexFileStatusData) || - (flipper_hex_ret.status == FlipperI32HexFileStatusUdateAddr)) && - ret) { - switch(flipper_hex_ret.status) { - case FlipperI32HexFileStatusData: - avr_isp_read_page( - instance->avr_isp, - STK_SET_EEPROM_TYPE, - (uint16_t)addr, - flipper_hex_ret.data_size, - data_read_eeprom, - sizeof(data_read_eeprom)); - - if(memcmp(data_read_hex, data_read_eeprom, flipper_hex_ret.data_size) != 0) { - ret = false; - FURI_LOG_E(TAG, "Verification eeprom error"); - FURI_LOG_E(TAG, "Addr: 0x%04lX", addr); - for(uint32_t i = 0; i < flipper_hex_ret.data_size; i++) { - FURI_LOG_RAW_E("%02X ", data_read_hex[i]); - } - FURI_LOG_RAW_E("\r\n"); - for(uint32_t i = 0; i < flipper_hex_ret.data_size; i++) { - FURI_LOG_RAW_E("%02X ", data_read_eeprom[i]); - } - FURI_LOG_RAW_E("\r\n"); - } - - addr += flipper_hex_ret.data_size; - instance->progress_eeprom = - (float)(addr) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].eepromsize); - break; - - case FlipperI32HexFileStatusUdateAddr: - addr = (data_read_hex[0] << 24 | data_read_hex[1] << 16); - break; - - default: - furi_crash(TAG " Incorrect status."); - break; - } - - flipper_hex_ret = flipper_i32hex_file_i32hex_to_bin_get_data( - flipper_hex_eeprom, data_read_hex, sizeof(data_read_hex)); - } - - flipper_i32hex_file_close(flipper_hex_eeprom); - instance->progress_eeprom = 1.0f; - - return ret; -} - -bool avr_isp_worker_rw_verification( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name) { - furi_assert(instance); - furi_assert(file_path); - furi_assert(file_name); - - FURI_LOG_D(TAG, "Verification chip"); - - instance->progress_flash = 0.0f; - instance->progress_eeprom = 0.0f; - FuriString* file_path_name = furi_string_alloc(); - - bool ret = false; - - if(avr_isp_auto_set_spi_speed_start_pmode(instance->avr_isp)) { - do { - furi_string_printf( - file_path_name, "%s/%s_%s", file_path, file_name, NAME_PATERN_FLASH_FILE); - if(!avr_isp_worker_rw_verification_flash( - instance, furi_string_get_cstr(file_path_name))) - break; - - if(avr_isp_chip_arr[instance->chip_arr_ind].eepromsize > 0) { - furi_string_printf( - file_path_name, "%s/%s_%s", file_path, file_name, NAME_PATERN_EEPROM_FILE); - - if(!avr_isp_worker_rw_verification_eeprom( - instance, furi_string_get_cstr(file_path_name))) - break; - } - ret = true; - } while(false); - avr_isp_end_pmode(instance->avr_isp); - furi_string_free(file_path_name); - } - return ret; -} - -void avr_isp_worker_rw_verification_start( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name) { - furi_assert(instance); - - instance->file_path = file_path; - instance->file_name = file_name; - furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerRWEvtVerification); -} - -static void avr_isp_worker_rw_write_flash(AvrIspWorkerRW* instance, const char* file_path) { - furi_assert(instance); - furi_check(instance->avr_isp); - - instance->progress_flash = 0.0; - - FURI_LOG_D(TAG, "Write Flash %s", file_path); - - uint8_t data[288] = {0}; - - FlipperI32HexFile* flipper_hex_flash = flipper_i32hex_file_open_read(file_path); - - uint32_t addr = avr_isp_chip_arr[instance->chip_arr_ind].flashoffset; - bool send_extended_addr = ((avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2) > 0x10000); - uint8_t extended_addr = 0; - - FlipperI32HexFileRet flipper_hex_ret = - flipper_i32hex_file_i32hex_to_bin_get_data(flipper_hex_flash, data, sizeof(data)); - - while((flipper_hex_ret.status == FlipperI32HexFileStatusData) || - (flipper_hex_ret.status == FlipperI32HexFileStatusUdateAddr)) { - switch(flipper_hex_ret.status) { - case FlipperI32HexFileStatusData: - - if(send_extended_addr) { - if(extended_addr <= ((addr >> 16) & 0xFF)) { - avr_isp_write_extended_addr(instance->avr_isp, extended_addr); - extended_addr = ((addr >> 16) & 0xFF) + 1; - } - } - - if(!avr_isp_write_page( - instance->avr_isp, - STK_SET_FLASH_TYPE, - avr_isp_chip_arr[instance->chip_arr_ind].flashsize, - (uint16_t)addr, - avr_isp_chip_arr[instance->chip_arr_ind].pagesize, - data, - flipper_hex_ret.data_size)) { - break; - } - addr += flipper_hex_ret.data_size / 2; - instance->progress_flash = - (float)(addr) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2.0f); - break; - - case FlipperI32HexFileStatusUdateAddr: - addr = (data[0] << 24 | data[1] << 16) / 2; - break; - - default: - furi_crash(TAG " Incorrect status."); - break; - } - - flipper_hex_ret = - flipper_i32hex_file_i32hex_to_bin_get_data(flipper_hex_flash, data, sizeof(data)); - } - - flipper_i32hex_file_close(flipper_hex_flash); - instance->progress_flash = 1.0f; -} - -static void avr_isp_worker_rw_write_eeprom(AvrIspWorkerRW* instance, const char* file_path) { - furi_assert(instance); - furi_check(instance->avr_isp); - - instance->progress_eeprom = 0.0; - uint8_t data[288] = {0}; - - FURI_LOG_D(TAG, "Write EEPROM %s", file_path); - - FlipperI32HexFile* flipper_hex_eeprom_read = flipper_i32hex_file_open_read(file_path); - - uint32_t addr = avr_isp_chip_arr[instance->chip_arr_ind].eepromoffset; - FlipperI32HexFileRet flipper_hex_ret = - flipper_i32hex_file_i32hex_to_bin_get_data(flipper_hex_eeprom_read, data, sizeof(data)); - - while((flipper_hex_ret.status == FlipperI32HexFileStatusData) || - (flipper_hex_ret.status == FlipperI32HexFileStatusUdateAddr)) { - switch(flipper_hex_ret.status) { - case FlipperI32HexFileStatusData: - if(!avr_isp_write_page( - instance->avr_isp, - STK_SET_EEPROM_TYPE, - avr_isp_chip_arr[instance->chip_arr_ind].eepromsize, - (uint16_t)addr, - avr_isp_chip_arr[instance->chip_arr_ind].eeprompagesize, - data, - flipper_hex_ret.data_size)) { - break; - } - addr += flipper_hex_ret.data_size; - instance->progress_eeprom = - (float)(addr) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].eepromsize); - break; - - case FlipperI32HexFileStatusUdateAddr: - addr = data[0] << 24 | data[1] << 16; - break; - - default: - furi_crash(TAG " Incorrect status."); - break; - } - - flipper_hex_ret = flipper_i32hex_file_i32hex_to_bin_get_data( - flipper_hex_eeprom_read, data, sizeof(data)); - } - - flipper_i32hex_file_close(flipper_hex_eeprom_read); - instance->progress_eeprom = 1.0f; -} - -bool avr_isp_worker_rw_write_dump( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name) { - furi_assert(instance); - furi_assert(file_path); - furi_assert(file_name); - - FURI_LOG_D(TAG, "Write dump chip"); - - instance->progress_flash = 0.0f; - instance->progress_eeprom = 0.0f; - bool ret = false; - - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* flipper_format = flipper_format_file_alloc(storage); - FuriString* file_path_name = furi_string_alloc(); - - FuriString* temp_str_1 = furi_string_alloc(); - FuriString* temp_str_2 = furi_string_alloc(); - uint32_t temp_data32; - - if(!avr_isp_worker_rw_detect_chip(instance)) { - FURI_LOG_E(TAG, "No detect AVR chip"); - } else { - //upload file with description - do { - furi_string_printf( - file_path_name, "%s/%s%s", file_path, file_name, AVR_ISP_APP_EXTENSION); - if(!flipper_format_file_open_existing( - flipper_format, furi_string_get_cstr(file_path_name))) { - FURI_LOG_E(TAG, "Error open file %s", furi_string_get_cstr(file_path_name)); - break; - } - - if(!flipper_format_read_header(flipper_format, temp_str_1, &temp_data32)) { - FURI_LOG_E(TAG, "Missing or incorrect header"); - break; - } - - if((!strcmp(furi_string_get_cstr(temp_str_1), AVR_ISP_APP_FILE_TYPE)) && - temp_data32 == AVR_ISP_APP_FILE_VERSION) { - } else { - FURI_LOG_E(TAG, "Type or version mismatch"); - break; - } - - AvrIspSignature sig_read = {0}; - - if(!flipper_format_read_hex( - flipper_format, "Signature", (uint8_t*)&sig_read, sizeof(AvrIspSignature))) { - FURI_LOG_E(TAG, "Missing Signature"); - break; - } - - if(memcmp( - (uint8_t*)&instance->signature, (uint8_t*)&sig_read, sizeof(AvrIspSignature)) != - 0) { - FURI_LOG_E( - TAG, - "Wrong chip. Connected (%02X %02X %02X), read from file (%02X %02X %02X)", - instance->signature.vendor, - instance->signature.part_family, - instance->signature.part_number, - sig_read.vendor, - sig_read.part_family, - sig_read.part_number); - break; - } - - if(!flipper_format_read_string(flipper_format, "Dump_flash", temp_str_1)) { - FURI_LOG_E(TAG, "Missing Dump_flash"); - break; - } - - //may not be - flipper_format_read_string(flipper_format, "Dump_eeprom", temp_str_2); - ret = true; - } while(false); - } - flipper_format_free(flipper_format); - furi_record_close(RECORD_STORAGE); - - if(ret) { - do { - //checking .hex files for errors - - furi_string_printf( - file_path_name, "%s/%s", file_path, furi_string_get_cstr(temp_str_1)); - - FURI_LOG_D(TAG, "Check flash file"); - FlipperI32HexFile* flipper_hex_flash_read = - flipper_i32hex_file_open_read(furi_string_get_cstr(file_path_name)); - if(flipper_i32hex_file_check(flipper_hex_flash_read)) { - FURI_LOG_D(TAG, "Check flash file: OK"); - } else { - FURI_LOG_E(TAG, "Check flash file: Error"); - ret = false; - } - flipper_i32hex_file_close(flipper_hex_flash_read); - - if(furi_string_size(temp_str_2) > 4) { - furi_string_printf( - file_path_name, "%s/%s", file_path, furi_string_get_cstr(temp_str_2)); - - FURI_LOG_D(TAG, "Check eeprom file"); - FlipperI32HexFile* flipper_hex_eeprom_read = - flipper_i32hex_file_open_read(furi_string_get_cstr(file_path_name)); - if(flipper_i32hex_file_check(flipper_hex_eeprom_read)) { - FURI_LOG_D(TAG, "Check eeprom file: OK"); - } else { - FURI_LOG_E(TAG, "Check eeprom file: Error"); - ret = false; - } - flipper_i32hex_file_close(flipper_hex_eeprom_read); - } - - if(!ret) break; - ret = false; - - //erase chip - FURI_LOG_D(TAG, "Erase chip"); - if(!avr_isp_erase_chip(instance->avr_isp)) { - FURI_LOG_E(TAG, "Erase chip: Error"); - break; - } - - if(!avr_isp_auto_set_spi_speed_start_pmode(instance->avr_isp)) { - FURI_LOG_E(TAG, "Well, I managed to enter the mod program"); - break; - } - - //write flash - furi_string_printf( - file_path_name, "%s/%s", file_path, furi_string_get_cstr(temp_str_1)); - avr_isp_worker_rw_write_flash(instance, furi_string_get_cstr(file_path_name)); - - //write eeprom - if(furi_string_size(temp_str_2) > 4) { - furi_string_printf( - file_path_name, "%s/%s", file_path, furi_string_get_cstr(temp_str_2)); - avr_isp_worker_rw_write_eeprom(instance, furi_string_get_cstr(file_path_name)); - } - ret = true; - avr_isp_end_pmode(instance->avr_isp); - } while(false); - } - - furi_string_free(file_path_name); - furi_string_free(temp_str_1); - furi_string_free(temp_str_2); - - return ret; -} - -void avr_isp_worker_rw_write_dump_start( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name) { - furi_assert(instance); - - instance->file_path = file_path; - instance->file_name = file_name; - furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerRWEvtWriting); -} - -bool avr_isp_worker_rw_write_fuse( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name) { - furi_assert(instance); - furi_assert(file_path); - furi_assert(file_name); - - FURI_LOG_D(TAG, "Write fuse chip"); - - bool ret = false; - uint8_t lfuse; - uint8_t hfuse; - uint8_t efuse; - uint8_t lock; - - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* flipper_format = flipper_format_file_alloc(storage); - FuriString* temp_str = furi_string_alloc(); - - uint32_t temp_data32; - - if(!avr_isp_worker_rw_detect_chip(instance)) { - FURI_LOG_E(TAG, "No detect AVR chip"); - } else { - //upload file with description - do { - furi_string_printf(temp_str, "%s/%s%s", file_path, file_name, AVR_ISP_APP_EXTENSION); - if(!flipper_format_file_open_existing(flipper_format, furi_string_get_cstr(temp_str))) { - FURI_LOG_E(TAG, "Error open file %s", furi_string_get_cstr(temp_str)); - break; - } - - if(!flipper_format_read_header(flipper_format, temp_str, &temp_data32)) { - FURI_LOG_E(TAG, "Missing or incorrect header"); - break; - } - - if((!strcmp(furi_string_get_cstr(temp_str), AVR_ISP_APP_FILE_TYPE)) && - temp_data32 == AVR_ISP_APP_FILE_VERSION) { - } else { - FURI_LOG_E(TAG, "Type or version mismatch"); - break; - } - - AvrIspSignature sig_read = {0}; - - if(!flipper_format_read_hex( - flipper_format, "Signature", (uint8_t*)&sig_read, sizeof(AvrIspSignature))) { - FURI_LOG_E(TAG, "Missing Signature"); - break; - } - - if(memcmp( - (uint8_t*)&instance->signature, (uint8_t*)&sig_read, sizeof(AvrIspSignature)) != - 0) { - FURI_LOG_E( - TAG, - "Wrong chip. Connected (%02X %02X %02X), read from file (%02X %02X %02X)", - instance->signature.vendor, - instance->signature.part_family, - instance->signature.part_number, - sig_read.vendor, - sig_read.part_family, - sig_read.part_number); - break; - } - - if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 0) { - if(!flipper_format_read_hex(flipper_format, "Lfuse", &lfuse, 1)) { - FURI_LOG_E(TAG, "Missing Lfuse"); - break; - } - } - if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 1) { - if(!flipper_format_read_hex(flipper_format, "Hfuse", &hfuse, 1)) { - FURI_LOG_E(TAG, "Missing Hfuse"); - break; - } - } - if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 2) { - if(!flipper_format_read_hex(flipper_format, "Efuse", &efuse, 1)) { - FURI_LOG_E(TAG, "Missing Efuse"); - break; - } - } - if(avr_isp_chip_arr[instance->chip_arr_ind].nlocks == 1) { - if(!flipper_format_read_hex(flipper_format, "Lock", &lock, 1)) { - FURI_LOG_E(TAG, "Missing Lock"); - break; - } - } - - if(!avr_isp_auto_set_spi_speed_start_pmode(instance->avr_isp)) { - FURI_LOG_E(TAG, "Well, I managed to enter the mod program"); - break; - } - - ret = true; - - if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 0) { - if(instance->lfuse != lfuse) { - if(!avr_isp_write_fuse_low(instance->avr_isp, lfuse)) { - FURI_LOG_E(TAG, "Write Lfuse: error"); - ret = false; - } - } - } - if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 1) { - if(instance->hfuse != hfuse) { - if(!avr_isp_write_fuse_high(instance->avr_isp, hfuse)) { - FURI_LOG_E(TAG, "Write Hfuse: error"); - ret = false; - } - } - } - if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 2) { - if(instance->efuse != efuse) { - if(!avr_isp_write_fuse_extended(instance->avr_isp, efuse)) { - FURI_LOG_E(TAG, "Write Efuse: error"); - ret = false; - } - } - } - - if(avr_isp_chip_arr[instance->chip_arr_ind].nlocks == 1) { - FURI_LOG_D(TAG, "Write lock byte"); - if(instance->lock != lock) { - if(!avr_isp_write_lock_byte(instance->avr_isp, lock)) { - FURI_LOG_E(TAG, "Write Lock byte: error"); - ret = false; - } - } - } - avr_isp_end_pmode(instance->avr_isp); - } while(false); - } - - flipper_format_free(flipper_format); - furi_record_close(RECORD_STORAGE); - furi_string_free(temp_str); - return ret; -} - -void avr_isp_worker_rw_write_fuse_start( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name) { - furi_assert(instance); - - instance->file_path = file_path; - instance->file_name = file_name; - furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerRWEvtWritingFuse); -} \ No newline at end of file diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.h b/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.h deleted file mode 100644 index 2c52a8700..000000000 --- a/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -#include - -typedef struct AvrIspWorkerRW AvrIspWorkerRW; - -typedef void (*AvrIspWorkerRWCallback)( - void* context, - const char* name, - bool detect_chip, - uint32_t flash_size); - -typedef enum { - AvrIspWorkerRWStatusILDE = 0, - AvrIspWorkerRWStatusEndReading = 1, - AvrIspWorkerRWStatusEndVerification = 2, - AvrIspWorkerRWStatusEndWriting = 3, - AvrIspWorkerRWStatusEndWritingFuse = 4, - - AvrIspWorkerRWStatusErrorReading = (-1), - AvrIspWorkerRWStatusErrorVerification = (-2), - AvrIspWorkerRWStatusErrorWriting = (-3), - AvrIspWorkerRWStatusErrorWritingFuse = (-4), - - AvrIspWorkerRWStatusReserved = 0x7FFFFFFF, ///< Prevents enum down-size compiler optimization. -} AvrIspWorkerRWStatus; - -typedef void (*AvrIspWorkerRWStatusCallback)(void* context, AvrIspWorkerRWStatus status); - -AvrIspWorkerRW* avr_isp_worker_rw_alloc(void* context); - -void avr_isp_worker_rw_free(AvrIspWorkerRW* instance); - -void avr_isp_worker_rw_start(AvrIspWorkerRW* instance); - -void avr_isp_worker_rw_stop(AvrIspWorkerRW* instance); - -bool avr_isp_worker_rw_is_running(AvrIspWorkerRW* instance); - -void avr_isp_worker_rw_set_callback( - AvrIspWorkerRW* instance, - AvrIspWorkerRWCallback callback, - void* context); - -void avr_isp_worker_rw_set_callback_status( - AvrIspWorkerRW* instance, - AvrIspWorkerRWStatusCallback callback_status, - void* context_status); - -bool avr_isp_worker_rw_detect_chip(AvrIspWorkerRW* instance); - -float avr_isp_worker_rw_get_progress_flash(AvrIspWorkerRW* instance); - -float avr_isp_worker_rw_get_progress_eeprom(AvrIspWorkerRW* instance); - -bool avr_isp_worker_rw_read_dump( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name); - -void avr_isp_worker_rw_read_dump_start( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name); - -bool avr_isp_worker_rw_verification( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name); - -void avr_isp_worker_rw_verification_start( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name); - -bool avr_isp_worker_rw_check_hex( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name); - -bool avr_isp_worker_rw_write_dump( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name); - -void avr_isp_worker_rw_write_dump_start( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name); - -bool avr_isp_worker_rw_write_fuse( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name); - -void avr_isp_worker_rw_write_fuse_start( - AvrIspWorkerRW* instance, - const char* file_path, - const char* file_name); \ No newline at end of file diff --git a/applications/external/avr_isp_programmer/helpers/flipper_i32hex_file.c b/applications/external/avr_isp_programmer/helpers/flipper_i32hex_file.c deleted file mode 100644 index a8c20a0bd..000000000 --- a/applications/external/avr_isp_programmer/helpers/flipper_i32hex_file.c +++ /dev/null @@ -1,321 +0,0 @@ -#include "flipper_i32hex_file.h" -#include -#include -#include -#include -#include - -//https://en.wikipedia.org/wiki/Intel_HEX - -#define TAG "FlipperI32HexFile" - -#define COUNT_BYTE_PAYLOAD 32 //how much payload will be used - -#define I32HEX_TYPE_DATA 0x00 -#define I32HEX_TYPE_END_OF_FILE 0x01 -#define I32HEX_TYPE_EXT_LINEAR_ADDR 0x04 -#define I32HEX_TYPE_START_LINEAR_ADDR 0x05 - -struct FlipperI32HexFile { - uint32_t addr; - uint32_t addr_last; - Storage* storage; - Stream* stream; - FuriString* str_data; - FlipperI32HexFileStatus file_open; -}; - -FlipperI32HexFile* flipper_i32hex_file_open_write(const char* name, uint32_t start_addr) { - furi_assert(name); - - FlipperI32HexFile* instance = malloc(sizeof(FlipperI32HexFile)); - instance->addr = start_addr; - instance->addr_last = 0; - instance->storage = furi_record_open(RECORD_STORAGE); - instance->stream = file_stream_alloc(instance->storage); - - if(file_stream_open(instance->stream, name, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { - instance->file_open = FlipperI32HexFileStatusOpenFileWrite; - FURI_LOG_D(TAG, "Open write file %s", name); - } else { - FURI_LOG_E(TAG, "Failed to open file %s", name); - instance->file_open = FlipperI32HexFileStatusErrorNoOpenFile; - } - instance->str_data = furi_string_alloc(instance->storage); - - return instance; -} - -FlipperI32HexFile* flipper_i32hex_file_open_read(const char* name) { - furi_assert(name); - - FlipperI32HexFile* instance = malloc(sizeof(FlipperI32HexFile)); - instance->addr = 0; - instance->addr_last = 0; - instance->storage = furi_record_open(RECORD_STORAGE); - instance->stream = file_stream_alloc(instance->storage); - - if(file_stream_open(instance->stream, name, FSAM_READ, FSOM_OPEN_EXISTING)) { - instance->file_open = FlipperI32HexFileStatusOpenFileRead; - FURI_LOG_D(TAG, "Open read file %s", name); - } else { - FURI_LOG_E(TAG, "Failed to open file %s", name); - instance->file_open = FlipperI32HexFileStatusErrorNoOpenFile; - } - instance->str_data = furi_string_alloc(instance->storage); - - return instance; -} - -void flipper_i32hex_file_close(FlipperI32HexFile* instance) { - furi_assert(instance); - - furi_string_free(instance->str_data); - file_stream_close(instance->stream); - stream_free(instance->stream); - furi_record_close(RECORD_STORAGE); -} - -FlipperI32HexFileRet flipper_i32hex_file_bin_to_i32hex_set_data( - FlipperI32HexFile* instance, - uint8_t* data, - uint32_t data_size) { - furi_assert(instance); - furi_assert(data); - - FlipperI32HexFileRet ret = {.status = FlipperI32HexFileStatusOK, .data_size = 0}; - if(instance->file_open != FlipperI32HexFileStatusOpenFileWrite) { - ret.status = FlipperI32HexFileStatusErrorFileWrite; - } - uint8_t count_byte = 0; - uint32_t ind = 0; - uint8_t crc = 0; - - furi_string_reset(instance->str_data); - - if((instance->addr_last & 0xFF0000) < (instance->addr & 0xFF0000)) { - crc = 0x02 + 0x04 + ((instance->addr >> 24) & 0xFF) + ((instance->addr >> 16) & 0xFF); - crc = 0x01 + ~crc; - //I32HEX_TYPE_EXT_LINEAR_ADDR - furi_string_cat_printf( - instance->str_data, ":02000004%04lX%02X\r\n", (instance->addr >> 16), crc); - instance->addr_last = instance->addr; - } - - while(ind < data_size) { - if((ind + COUNT_BYTE_PAYLOAD) > data_size) { - count_byte = data_size - ind; - } else { - count_byte = COUNT_BYTE_PAYLOAD; - } - //I32HEX_TYPE_DATA - furi_string_cat_printf( - instance->str_data, ":%02X%04lX00", count_byte, (instance->addr & 0xFFFF)); - crc = count_byte + ((instance->addr >> 8) & 0xFF) + (instance->addr & 0xFF); - - for(uint32_t i = 0; i < count_byte; i++) { - furi_string_cat_printf(instance->str_data, "%02X", *data); - crc += *data++; - } - crc = 0x01 + ~crc; - furi_string_cat_printf(instance->str_data, "%02X\r\n", crc); - - ind += count_byte; - instance->addr += count_byte; - } - if(instance->file_open) stream_write_string(instance->stream, instance->str_data); - return ret; -} - -FlipperI32HexFileRet flipper_i32hex_file_bin_to_i32hex_set_end_line(FlipperI32HexFile* instance) { - furi_assert(instance); - - FlipperI32HexFileRet ret = {.status = FlipperI32HexFileStatusOK, .data_size = 0}; - if(instance->file_open != FlipperI32HexFileStatusOpenFileWrite) { - ret.status = FlipperI32HexFileStatusErrorFileWrite; - } - furi_string_reset(instance->str_data); - //I32HEX_TYPE_END_OF_FILE - furi_string_cat_printf(instance->str_data, ":00000001FF\r\n"); - if(instance->file_open) stream_write_string(instance->stream, instance->str_data); - return ret; -} - -void flipper_i32hex_file_bin_to_i32hex_set_addr(FlipperI32HexFile* instance, uint32_t addr) { - furi_assert(instance); - - instance->addr = addr; -} - -const char* flipper_i32hex_file_get_string(FlipperI32HexFile* instance) { - furi_assert(instance); - - return furi_string_get_cstr(instance->str_data); -} - -static FlipperI32HexFileRet flipper_i32hex_file_parse_line( - FlipperI32HexFile* instance, - const char* str, - uint8_t* data, - uint32_t data_size) { - furi_assert(instance); - furi_assert(data); - - char* str1; - uint32_t data_wrire_ind = 0; - uint32_t data_len = 0; - FlipperI32HexFileRet ret = {.status = FlipperI32HexFileStatusErrorData, .data_size = 0}; - - //Search for start of data I32HEX - str1 = strstr(str, ":"); - do { - if(str1 == NULL) { - ret.status = FlipperI32HexFileStatusErrorData; - break; - } - str1++; - if(!hex_char_to_uint8(*str1, str1[1], data + data_wrire_ind)) { - ret.status = FlipperI32HexFileStatusErrorData; - break; - } - str1++; - if(++data_wrire_ind > data_size) { - ret.status = FlipperI32HexFileStatusErrorOverflow; - break; - } - data_len = 5 + data[0]; // +5 bytes per header and crc - while(data_len > data_wrire_ind) { - str1++; - if(!hex_char_to_uint8(*str1, str1[1], data + data_wrire_ind)) { - ret.status = FlipperI32HexFileStatusErrorData; - break; - } - str1++; - if(++data_wrire_ind > data_size) { - ret.status = FlipperI32HexFileStatusErrorOverflow; - break; - } - } - ret.status = FlipperI32HexFileStatusOK; - ret.data_size = data_wrire_ind; - - } while(0); - return ret; -} - -static bool flipper_i32hex_file_check_data(uint8_t* data, uint32_t data_size) { - furi_assert(data); - - uint8_t crc = 0; - uint32_t data_read_ind = 0; - if(data[0] > data_size) return false; - while(data_read_ind < data_size - 1) { - crc += data[data_read_ind++]; - } - return data[data_size - 1] == ((1 + ~crc) & 0xFF); -} - -static FlipperI32HexFileRet flipper_i32hex_file_parse( - FlipperI32HexFile* instance, - const char* str, - uint8_t* data, - uint32_t data_size) { - furi_assert(instance); - furi_assert(data); - - FlipperI32HexFileRet ret = flipper_i32hex_file_parse_line(instance, str, data, data_size); - - if((ret.status == FlipperI32HexFileStatusOK) && (ret.data_size > 4)) { - switch(data[3]) { - case I32HEX_TYPE_DATA: - if(flipper_i32hex_file_check_data(data, ret.data_size)) { - ret.data_size -= 5; - memcpy(data, data + 4, ret.data_size); - ret.status = FlipperI32HexFileStatusData; - } else { - ret.status = FlipperI32HexFileStatusErrorCrc; - ret.data_size = 0; - } - break; - case I32HEX_TYPE_END_OF_FILE: - if(flipper_i32hex_file_check_data(data, ret.data_size)) { - ret.status = FlipperI32HexFileStatusEofFile; - ret.data_size = 0; - } else { - ret.status = FlipperI32HexFileStatusErrorCrc; - ret.data_size = 0; - } - break; - case I32HEX_TYPE_EXT_LINEAR_ADDR: - if(flipper_i32hex_file_check_data(data, ret.data_size)) { - data[0] = data[4]; - data[1] = data[5]; - data[3] = 0; - data[4] = 0; - ret.status = FlipperI32HexFileStatusUdateAddr; - ret.data_size = 4; - } else { - ret.status = FlipperI32HexFileStatusErrorCrc; - ret.data_size = 0; - } - break; - case I32HEX_TYPE_START_LINEAR_ADDR: - ret.status = FlipperI32HexFileStatusErrorUnsupportedCommand; - ret.data_size = 0; - break; - default: - ret.status = FlipperI32HexFileStatusErrorUnsupportedCommand; - ret.data_size = 0; - break; - } - } else { - ret.status = FlipperI32HexFileStatusErrorData; - ret.data_size = 0; - } - return ret; -} - -bool flipper_i32hex_file_check(FlipperI32HexFile* instance) { - furi_assert(instance); - - uint32_t data_size = 280; - uint8_t data[280] = {0}; - bool ret = true; - - if(instance->file_open != FlipperI32HexFileStatusOpenFileRead) { - FURI_LOG_E(TAG, "File is not open"); - ret = false; - } else { - stream_rewind(instance->stream); - - while(stream_read_line(instance->stream, instance->str_data)) { - FlipperI32HexFileRet parse_ret = flipper_i32hex_file_parse( - instance, furi_string_get_cstr(instance->str_data), data, data_size); - - if(parse_ret.status < 0) { - ret = false; - } - } - stream_rewind(instance->stream); - } - return ret; -} - -FlipperI32HexFileRet flipper_i32hex_file_i32hex_to_bin_get_data( - FlipperI32HexFile* instance, - uint8_t* data, - uint32_t data_size) { - furi_assert(instance); - furi_assert(data); - - FlipperI32HexFileRet ret = {.status = FlipperI32HexFileStatusOK, .data_size = 0}; - if(instance->file_open != FlipperI32HexFileStatusOpenFileRead) { - ret.status = FlipperI32HexFileStatusErrorFileRead; - } else { - stream_read_line(instance->stream, instance->str_data); - ret = flipper_i32hex_file_parse( - instance, furi_string_get_cstr(instance->str_data), data, data_size); - } - - return ret; -} \ No newline at end of file diff --git a/applications/external/avr_isp_programmer/helpers/flipper_i32hex_file.h b/applications/external/avr_isp_programmer/helpers/flipper_i32hex_file.h deleted file mode 100644 index 765b94beb..000000000 --- a/applications/external/avr_isp_programmer/helpers/flipper_i32hex_file.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include - -typedef struct FlipperI32HexFile FlipperI32HexFile; - -typedef enum { - FlipperI32HexFileStatusOK = 0, - FlipperI32HexFileStatusData = 2, - FlipperI32HexFileStatusUdateAddr = 3, - FlipperI32HexFileStatusEofFile = 4, - FlipperI32HexFileStatusOpenFileWrite = 5, - FlipperI32HexFileStatusOpenFileRead = 6, - - // Errors - FlipperI32HexFileStatusErrorCrc = (-1), - FlipperI32HexFileStatusErrorOverflow = (-2), - FlipperI32HexFileStatusErrorData = (-3), - FlipperI32HexFileStatusErrorUnsupportedCommand = (-4), - FlipperI32HexFileStatusErrorNoOpenFile = (-5), - FlipperI32HexFileStatusErrorFileWrite = (-6), - FlipperI32HexFileStatusErrorFileRead = (-7), - - FlipperI32HexFileStatusReserved = - 0x7FFFFFFF, ///< Prevents enum down-size compiler optimization. -} FlipperI32HexFileStatus; - -typedef struct { - FlipperI32HexFileStatus status; - uint32_t data_size; -} FlipperI32HexFileRet; - -FlipperI32HexFile* flipper_i32hex_file_open_write(const char* name, uint32_t start_addr); - -FlipperI32HexFile* flipper_i32hex_file_open_read(const char* name); - -void flipper_i32hex_file_close(FlipperI32HexFile* instance); - -FlipperI32HexFileRet flipper_i32hex_file_bin_to_i32hex_set_data( - FlipperI32HexFile* instance, - uint8_t* data, - uint32_t data_size); - -FlipperI32HexFileRet flipper_i32hex_file_bin_to_i32hex_set_end_line(FlipperI32HexFile* instance); - -const char* flipper_i32hex_file_get_string(FlipperI32HexFile* instance); - -void flipper_i32hex_file_bin_to_i32hex_set_addr(FlipperI32HexFile* instance, uint32_t addr); - -bool flipper_i32hex_file_check(FlipperI32HexFile* instance); - -FlipperI32HexFileRet flipper_i32hex_file_i32hex_to_bin_get_data( - FlipperI32HexFile* instance, - uint8_t* data, - uint32_t data_size); \ No newline at end of file diff --git a/applications/external/avr_isp_programmer/images/avr_app_icon_10x10.png b/applications/external/avr_isp_programmer/images/avr_app_icon_10x10.png deleted file mode 100644 index 533787fe3..000000000 Binary files a/applications/external/avr_isp_programmer/images/avr_app_icon_10x10.png and /dev/null differ diff --git a/applications/external/avr_isp_programmer/images/avr_wiring.png b/applications/external/avr_isp_programmer/images/avr_wiring.png deleted file mode 100644 index 957012405..000000000 Binary files a/applications/external/avr_isp_programmer/images/avr_wiring.png and /dev/null differ diff --git a/applications/external/avr_isp_programmer/images/chif_not_found_83x37.png b/applications/external/avr_isp_programmer/images/chif_not_found_83x37.png deleted file mode 100644 index b03bf3567..000000000 Binary files a/applications/external/avr_isp_programmer/images/chif_not_found_83x37.png and /dev/null differ diff --git a/applications/external/avr_isp_programmer/images/chip_error_70x22.png b/applications/external/avr_isp_programmer/images/chip_error_70x22.png deleted file mode 100644 index 16f81178c..000000000 Binary files a/applications/external/avr_isp_programmer/images/chip_error_70x22.png and /dev/null differ diff --git a/applications/external/avr_isp_programmer/images/chip_long_70x22.png b/applications/external/avr_isp_programmer/images/chip_long_70x22.png deleted file mode 100644 index 3edfff82d..000000000 Binary files a/applications/external/avr_isp_programmer/images/chip_long_70x22.png and /dev/null differ diff --git a/applications/external/avr_isp_programmer/images/chip_not_found_83x37.png b/applications/external/avr_isp_programmer/images/chip_not_found_83x37.png deleted file mode 100644 index 6d56dcfa0..000000000 Binary files a/applications/external/avr_isp_programmer/images/chip_not_found_83x37.png and /dev/null differ diff --git a/applications/external/avr_isp_programmer/images/dolphin_nice_96x59.png b/applications/external/avr_isp_programmer/images/dolphin_nice_96x59.png deleted file mode 100644 index a299d3630..000000000 Binary files a/applications/external/avr_isp_programmer/images/dolphin_nice_96x59.png and /dev/null differ diff --git a/applications/external/avr_isp_programmer/images/isp_active_128x53.png b/applications/external/avr_isp_programmer/images/isp_active_128x53.png deleted file mode 100644 index 843792123..000000000 Binary files a/applications/external/avr_isp_programmer/images/isp_active_128x53.png and /dev/null differ diff --git a/applications/external/avr_isp_programmer/images/link_waiting_77x56.png b/applications/external/avr_isp_programmer/images/link_waiting_77x56.png deleted file mode 100644 index d7d32aed5..000000000 Binary files a/applications/external/avr_isp_programmer/images/link_waiting_77x56.png and /dev/null differ diff --git a/applications/external/avr_isp_programmer/lib/driver/avr_isp_chip_arr.c b/applications/external/avr_isp_programmer/lib/driver/avr_isp_chip_arr.c deleted file mode 100644 index 2be54de6a..000000000 --- a/applications/external/avr_isp_programmer/lib/driver/avr_isp_chip_arr.c +++ /dev/null @@ -1,386 +0,0 @@ -#include "avr_isp_chip_arr.h" - -#include - -//https://github.com/avrdudes/avrdude/blob/master/src/avrintel.c - -const AvrIspChipArr avr_isp_chip_arr[] = { // Value of -1 typically means unknown - //{mcu_name, mcuid, family, {sig, na, ture}, flstart, flsize, pgsiz, nb, bootsz, eestart, eesize, ep, rambeg, ramsiz, nf, nl, ni}, // Source - {"ATtiny4", 0, F_AVR8L, {0x1E, 0x8F, 0x0A}, 0, 0x00200, 0x010, 0, 0, 0, 0, 0, 0x0040, 0x0020, 1, 1, 10}, // atdf, avr-gcc 12.2.0, avrdude, boot size (manual) - {"ATtiny5", 1, F_AVR8L, {0x1E, 0x8F, 0x09}, 0, 0x00200, 0x010, 0, 0, 0, 0, 0, 0x0040, 0x0020, 1, 1, 11}, // atdf, avr-gcc 12.2.0, avrdude, boot size (manual) - {"ATtiny9", 2, F_AVR8L, {0x1E, 0x90, 0x08}, 0, 0x00400, 0x010, 0, 0, 0, 0, 0, 0x0040, 0x0020, 1, 1, 10}, // atdf, avr-gcc 12.2.0, avrdude, boot size (manual) - {"ATtiny10", 3, F_AVR8L, {0x1E, 0x90, 0x03}, 0, 0x00400, 0x010, 0, 0, 0, 0, 0, 0x0040, 0x0020, 1, 1, 11}, // atdf, avr-gcc 12.2.0, avrdude, boot size (manual) - {"ATtiny20", 4, F_AVR8L, {0x1E, 0x91, 0x0F}, 0, 0x00800, 0x020, 0, 0, 0, 0, 0, 0x0040, 0x0080, 1, 1, 17}, // atdf, avr-gcc 12.2.0, avrdude, boot size (manual) - {"ATtiny40", 5, F_AVR8L, {0x1E, 0x92, 0x0E}, 0, 0x01000, 0x040, 0, 0, 0, 0, 0, 0x0040, 0x0100, 1, 1, 18}, // atdf, avr-gcc 12.2.0, avrdude, boot size (manual) - {"ATtiny102", 6, F_AVR8L, {0x1E, 0x90, 0x0C}, 0, 0x00400, 0x010, 0, 0, 0, 0, 0, 0x0040, 0x0020, 1, 1, 16}, // atdf, avrdude, boot size (manual) - {"ATtiny104", 7, F_AVR8L, {0x1E, 0x90, 0x0B}, 0, 0x00400, 0x010, 0, 0, 0, 0, 0, 0x0040, 0x0020, 1, 1, 16}, // atdf, avrdude, boot size (manual) - - {"ATtiny11", 8, F_AVR8, {0x1E, 0x90, 0x04}, 0, 0x00400, 0x001, 0, 0, 0, 0x0040, 1, 0x0060, 0x0020, 1, 1, 5}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny12", 9, F_AVR8, {0x1E, 0x90, 0x05}, 0, 0x00400, 0x001, 0, 0, 0, 0x0040, 2, 0x0060, 0x0020, 1, 1, 6}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny13", 10, F_AVR8, {0x1E, 0x90, 0x07}, 0, 0x00400, 0x020, 0, 0, 0, 0x0040, 4, 0x0060, 0x0040, 2, 1, 10}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny13A", 11, F_AVR8, {0x1E, 0x90, 0x07}, 0, 0x00400, 0x020, 0, 0, 0, 0x0040, 4, 0x0060, 0x0040, 2, 1, 10}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny15", 12, F_AVR8, {0x1E, 0x90, 0x06}, 0, 0x00400, 0x001, 0, 0, 0, 0x0040, 2, 0x0060, 0x0020, 1, 1, 9}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny22", 13, F_AVR8, {0x1E, 0x91, 0x06}, 0, 0x00800, -1, 0, 0, -1, -1, -1, 0x0060, 0x0080, 1, 1, 3}, // avr-gcc 12.2.0, boot size (manual) - {"ATtiny24", 14, F_AVR8, {0x1E, 0x91, 0x0B}, 0, 0x00800, 0x020, 0, 0, 0, 0x0080, 4, 0x0060, 0x0080, 3, 1, 17}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny24A", 15, F_AVR8, {0x1E, 0x91, 0x0B}, 0, 0x00800, 0x020, 0, 0, 0, 0x0080, 4, 0x0060, 0x0080, 3, 1, 17}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny25", 16, F_AVR8, {0x1E, 0x91, 0x08}, 0, 0x00800, 0x020, 0, 0, 0, 0x0080, 4, 0x0060, 0x0080, 3, 1, 15}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny26", 17, F_AVR8, {0x1E, 0x91, 0x09}, 0, 0x00800, 0x020, 0, 0, 0, 0x0080, 4, 0x0060, 0x0080, 2, 1, 12}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny28", 18, F_AVR8, {0x1E, 0x91, 0x07}, 0, 0x00800, 0x002, 0, 0, 0, 0, 0, 0x0060, 0x0020, 1, 1, 6}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny43U", 19, F_AVR8, {0x1E, 0x92, 0x0C}, 0, 0x01000, 0x040, 0, 0, 0, 0x0040, 4, 0x0060, 0x0100, 3, 1, 16}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny44", 20, F_AVR8, {0x1E, 0x92, 0x07}, 0, 0x01000, 0x040, 0, 0, 0, 0x0100, 4, 0x0060, 0x0100, 3, 1, 17}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny44A", 21, F_AVR8, {0x1E, 0x92, 0x07}, 0, 0x01000, 0x040, 0, 0, 0, 0x0100, 4, 0x0060, 0x0100, 3, 1, 17}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny45", 22, F_AVR8, {0x1E, 0x92, 0x06}, 0, 0x01000, 0x040, 0, 0, 0, 0x0100, 4, 0x0060, 0x0100, 3, 1, 15}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny48", 23, F_AVR8, {0x1E, 0x92, 0x09}, 0, 0x01000, 0x040, 0, 0, 0, 0x0040, 4, 0x0100, 0x0100, 3, 1, 20}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny84", 24, F_AVR8, {0x1E, 0x93, 0x0C}, 0, 0x02000, 0x040, 0, 0, 0, 0x0200, 4, 0x0060, 0x0200, 3, 1, 17}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny84A", 25, F_AVR8, {0x1E, 0x93, 0x0C}, 0, 0x02000, 0x040, 0, 0, 0, 0x0200, 4, 0x0060, 0x0200, 3, 1, 17}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny85", 26, F_AVR8, {0x1E, 0x93, 0x0B}, 0, 0x02000, 0x040, 0, 0, 0, 0x0200, 4, 0x0060, 0x0200, 3, 1, 15}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny87", 27, F_AVR8, {0x1E, 0x93, 0x87}, 0, 0x02000, 0x080, 0, 0, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 20}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny88", 28, F_AVR8, {0x1E, 0x93, 0x11}, 0, 0x02000, 0x040, 0, 0, 0, 0x0040, 4, 0x0100, 0x0200, 3, 1, 20}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny167", 29, F_AVR8, {0x1E, 0x94, 0x87}, 0, 0x04000, 0x080, 0, 0, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 20}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny261", 30, F_AVR8, {0x1E, 0x91, 0x0C}, 0, 0x00800, 0x020, 0, 0, 0, 0x0080, 4, 0x0060, 0x0080, 3, 1, 19}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny261A", 31, F_AVR8, {0x1E, 0x91, 0x0C}, 0, 0x00800, 0x020, 0, 0, 0, 0x0080, 4, 0x0060, 0x0080, 3, 1, 19}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny441", 32, F_AVR8, {0x1E, 0x92, 0x15}, 0, 0x01000, 0x010, 0, 0, 0, 0x0100, 4, 0x0100, 0x0100, 3, 1, 30}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny461", 33, F_AVR8, {0x1E, 0x92, 0x08}, 0, 0x01000, 0x040, 0, 0, 0, 0x0100, 4, 0x0060, 0x0100, 3, 1, 19}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny461A", 34, F_AVR8, {0x1E, 0x92, 0x08}, 0, 0x01000, 0x040, 0, 0, 0, 0x0100, 4, 0x0060, 0x0100, 3, 1, 19}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny828", 35, F_AVR8, {0x1E, 0x93, 0x14}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0100, 4, 0x0100, 0x0200, 3, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny828R", 36, F_AVR8, {0x1E, 0x93, 0x14}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0100, 4, 0x0100, 0x0200, 3, 1, 26}, // avrdude, from ATtiny828 - {"ATtiny841", 37, F_AVR8, {0x1E, 0x93, 0x15}, 0, 0x02000, 0x010, 0, 0, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 30}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny861", 38, F_AVR8, {0x1E, 0x93, 0x0D}, 0, 0x02000, 0x040, 0, 0, 0, 0x0200, 4, 0x0060, 0x0200, 3, 1, 19}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny861A", 39, F_AVR8, {0x1E, 0x93, 0x0D}, 0, 0x02000, 0x040, 0, 0, 0, 0x0200, 4, 0x0060, 0x0200, 3, 1, 19}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny1634", 40, F_AVR8, {0x1E, 0x94, 0x12}, 0, 0x04000, 0x020, 0, 0, 0, 0x0100, 4, 0x0100, 0x0400, 3, 1, 28}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny1634R", 41, F_AVR8, {0x1E, 0x94, 0x12}, 0, 0x04000, 0x020, 0, 0, 0, 0x0100, 4, 0x0100, 0x0400, 3, 1, 28}, // avrdude, from ATtiny1634 - {"ATtiny2313", 42, F_AVR8, {0x1E, 0x91, 0x0A}, 0, 0x00800, 0x020, 0, 0, 0, 0x0080, 4, 0x0060, 0x0080, 3, 1, 19}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny2313A", 43, F_AVR8, {0x1E, 0x91, 0x0A}, 0, 0x00800, 0x020, 0, 0, 0, 0x0080, 4, 0x0060, 0x0080, 3, 1, 21}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny4313", 44, F_AVR8, {0x1E, 0x92, 0x0D}, 0, 0x01000, 0x040, 0, 0, 0, 0x0100, 4, 0x0060, 0x0100, 3, 1, 21}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega8", 45, F_AVR8, {0x1E, 0x93, 0x07}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0060, 0x0400, 2, 1, 19}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega8A", 46, F_AVR8, {0x1E, 0x93, 0x07}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0060, 0x0400, 2, 1, 19}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega8HVA", 47, F_AVR8, {0x1E, 0x93, 0x10}, 0, 0x02000, 0x080, 0, 0, 0, 0x0100, 4, 0x0100, 0x0200, 1, 1, 21}, // atdf, avr-gcc 12.2.0 - {"ATmega8U2", 48, F_AVR8, {0x1E, 0x93, 0x89}, 0, 0x02000, 0x080, 4, 0x0200, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 29}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega16", 49, F_AVR8, {0x1E, 0x94, 0x03}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0060, 0x0400, 2, 1, 21}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega16A", 50, F_AVR8, {0x1E, 0x94, 0x03}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0060, 0x0400, 2, 1, 21}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega16HVA", 51, F_AVR8, {0x1E, 0x94, 0x0C}, 0, 0x04000, 0x080, 0, 0, 0, 0x0100, 4, 0x0100, 0x0200, 1, 1, 21}, // atdf, avr-gcc 12.2.0 - {"ATmega16HVB", 52, F_AVR8, {0x1E, 0x94, 0x0D}, 0, 0x04000, 0x080, 4, 0x0200, 0, 0x0200, 4, 0x0100, 0x0400, 2, 1, 29}, // atdf, avr-gcc 12.2.0 - {"ATmega16HVBrevB", 53, F_AVR8, {0x1E, 0x94, 0x0D}, 0, 0x04000, 0x080, 4, 0x0200, 0, 0x0200, 4, 0x0100, 0x0400, 2, 1, 29}, // atdf, avr-gcc 12.2.0 - {"ATmega16M1", 54, F_AVR8, {0x1E, 0x94, 0x84}, 0, 0x04000, 0x080, 4, 0x0200, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 31}, // atdf, avr-gcc 12.2.0 - {"ATmega16HVA2", 55, F_AVR8, {0x1E, 0x94, 0x0E}, 0, 0x04000, 0x080, -1, -1, -1, -1, -1, 0x0100, 0x0400, 2, 1, 22}, // avr-gcc 12.2.0 - {"ATmega16U2", 56, F_AVR8, {0x1E, 0x94, 0x89}, 0, 0x04000, 0x080, 4, 0x0200, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 29}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega16U4", 57, F_AVR8, {0x1E, 0x94, 0x88}, 0, 0x04000, 0x080, 4, 0x0200, 0, 0x0200, 4, 0x0100, 0x0500, 3, 1, 43}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega32", 58, F_AVR8, {0x1E, 0x95, 0x02}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0060, 0x0800, 2, 1, 21}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega32A", 59, F_AVR8, {0x1E, 0x95, 0x02}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0060, 0x0800, 2, 1, 21}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega32HVB", 60, F_AVR8, {0x1E, 0x95, 0x10}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 2, 1, 29}, // atdf, avr-gcc 12.2.0 - {"ATmega32HVBrevB", 61, F_AVR8, {0x1E, 0x95, 0x10}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 2, 1, 29}, // atdf, avr-gcc 12.2.0 - {"ATmega32C1", 62, F_AVR8, {0x1E, 0x95, 0x86}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 31}, // atdf, avr-gcc 12.2.0 - {"ATmega32M1", 63, F_AVR8, {0x1E, 0x95, 0x84}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega32U2", 64, F_AVR8, {0x1E, 0x95, 0x8A}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0400, 3, 1, 29}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega32U4", 65, F_AVR8, {0x1E, 0x95, 0x87}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0a00, 3, 1, 43}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega32U6", 66, F_AVR8, {0x1E, 0x95, 0x88}, 0, 0x08000, 0x080, 4, 0x0200, -1, -1, -1, 0x0100, 0x0a00, 3, 1, 38}, // avr-gcc 12.2.0, boot size (manual) - {"ATmega48", 67, F_AVR8, {0x1E, 0x92, 0x05}, 0, 0x01000, 0x040, 0, 0, 0, 0x0100, 4, 0x0100, 0x0200, 3, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega48A", 68, F_AVR8, {0x1E, 0x92, 0x05}, 0, 0x01000, 0x040, 0, 0, 0, 0x0100, 4, 0x0100, 0x0200, 3, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega48P", 69, F_AVR8, {0x1E, 0x92, 0x0A}, 0, 0x01000, 0x040, 0, 0, 0, 0x0100, 4, 0x0100, 0x0200, 3, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega48PA", 70, F_AVR8, {0x1E, 0x92, 0x0A}, 0, 0x01000, 0x040, 0, 0, 0, 0x0100, 4, 0x0100, 0x0200, 3, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega48PB", 71, F_AVR8, {0x1E, 0x92, 0x10}, 0, 0x01000, 0x040, 0, 0, 0, 0x0100, 4, 0x0100, 0x0200, 3, 1, 27}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega64", 72, F_AVR8, {0x1E, 0x96, 0x02}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 35}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega64A", 73, F_AVR8, {0x1E, 0x96, 0x02}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 35}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega64HVE", 74, F_AVR8, {0x1E, 0x96, 0x10}, 0, 0x10000, 0x080, 4, 0x0400, -1, -1, -1, 0x0100, 0x1000, 2, 1, 25}, // avr-gcc 12.2.0, boot size (manual) - {"ATmega64C1", 75, F_AVR8, {0x1E, 0x96, 0x86}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 31}, // atdf, avr-gcc 12.2.0 - {"ATmega64M1", 76, F_AVR8, {0x1E, 0x96, 0x84}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega64HVE2", 77, F_AVR8, {0x1E, 0x96, 0x10}, 0, 0x10000, 0x080, 4, 0x0400, 0, 0x0400, 4, 0x0100, 0x1000, 2, 1, 25}, // atdf, avr-gcc 12.2.0 - {"ATmega64RFR2", 78, F_AVR8, {0x1E, 0xA6, 0x02}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0200, 0x2000, 3, 1, 77}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega88", 79, F_AVR8, {0x1E, 0x93, 0x0A}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega88A", 80, F_AVR8, {0x1E, 0x93, 0x0A}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega88P", 81, F_AVR8, {0x1E, 0x93, 0x0F}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega88PA", 82, F_AVR8, {0x1E, 0x93, 0x0F}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega88PB", 83, F_AVR8, {0x1E, 0x93, 0x16}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 27}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega103", 84, F_AVR8, {0x1E, 0x97, 0x01}, 0, 0x20000, 0x100, 0, 0, 0, 0x1000, 1, 0x0060, 0x0fa0, 1, 1, 24}, // avr-gcc 12.2.0, avrdude, boot size (manual) - {"ATmega128", 85, F_AVR8, {0x1E, 0x97, 0x02}, 0, 0x20000, 0x100, 4, 0x0400, 0, 0x1000, 8, 0x0100, 0x1000, 3, 1, 35}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega128A", 86, F_AVR8, {0x1E, 0x97, 0x02}, 0, 0x20000, 0x100, 4, 0x0400, 0, 0x1000, 8, 0x0100, 0x1000, 3, 1, 35}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega128RFA1", 87, F_AVR8, {0x1E, 0xA7, 0x01}, 0, 0x20000, 0x100, 4, 0x0400, 0, 0x1000, 8, 0x0200, 0x4000, 3, 1, 72}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega128RFR2", 88, F_AVR8, {0x1E, 0xA7, 0x02}, 0, 0x20000, 0x100, 4, 0x0400, 0, 0x1000, 8, 0x0200, 0x4000, 3, 1, 77}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega161", 89, F_AVR8, {0x1E, 0x94, 0x01}, 0, 0x04000, 0x080, 1, 0x0400, 0, 0x0200, 1, 0x0060, 0x0400, 1, 1, 21}, // avr-gcc 12.2.0, avrdude, boot size (manual) - {"ATmega162", 90, F_AVR8, {0x1E, 0x94, 0x04}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 28}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega163", 91, F_AVR8, {0x1E, 0x94, 0x02}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 1, 0x0060, 0x0400, 2, 1, 18}, // avr-gcc 12.2.0, avrdude, boot size (manual) - {"ATmega164A", 92, F_AVR8, {0x1E, 0x94, 0x0F}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega164P", 93, F_AVR8, {0x1E, 0x94, 0x0A}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega164PA", 94, F_AVR8, {0x1E, 0x94, 0x0A}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega165", 95, F_AVR8, {0x1E, 0x94, 0x10}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 22}, // avr-gcc 12.2.0, avrdude, boot size (manual) - {"ATmega165A", 96, F_AVR8, {0x1E, 0x94, 0x10}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 22}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega165P", 97, F_AVR8, {0x1E, 0x94, 0x07}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 22}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega165PA", 98, F_AVR8, {0x1E, 0x94, 0x07}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 22}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega168", 99, F_AVR8, {0x1E, 0x94, 0x06}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega168A", 100, F_AVR8, {0x1E, 0x94, 0x06}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega168P", 101, F_AVR8, {0x1E, 0x94, 0x0B}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega168PA", 102, F_AVR8, {0x1E, 0x94, 0x0B}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega168PB", 103, F_AVR8, {0x1E, 0x94, 0x15}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 27}, // atdf, avr-gcc 7.3.0, avrdude - {"ATmega169", 104, F_AVR8, {0x1E, 0x94, 0x05}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 23}, // avr-gcc 12.2.0, avrdude, boot size (manual) - {"ATmega169A", 105, F_AVR8, {0x1E, 0x94, 0x11}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 23}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega169P", 106, F_AVR8, {0x1E, 0x94, 0x05}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 23}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega169PA", 107, F_AVR8, {0x1E, 0x94, 0x05}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 23}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega256RFR2", 108, F_AVR8, {0x1E, 0xA8, 0x02}, 0, 0x40000, 0x100, 4, 0x0400, 0, 0x2000, 8, 0x0200, 0x8000, 3, 1, 77}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega323", 109, F_AVR8, {0x1E, 0x95, 0x01}, 0, 0x08000, 0x080, 4, 0x0200, -1, -1, -1, 0x0060, 0x0800, 2, 1, 21}, // avr-gcc 12.2.0, boot size (manual) - {"ATmega324A", 110, F_AVR8, {0x1E, 0x95, 0x15}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega324P", 111, F_AVR8, {0x1E, 0x95, 0x08}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega324PA", 112, F_AVR8, {0x1E, 0x95, 0x11}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega324PB", 113, F_AVR8, {0x1E, 0x95, 0x17}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 51}, // atdf, avrdude - {"ATmega325", 114, F_AVR8, {0x1E, 0x95, 0x05}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 22}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega325A", 115, F_AVR8, {0x1E, 0x95, 0x05}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 22}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega325P", 116, F_AVR8, {0x1E, 0x95, 0x0D}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 22}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega325PA", 117, F_AVR8, {0x1E, 0x95, 0x0D}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 22}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega328", 118, F_AVR8, {0x1E, 0x95, 0x14}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega328P", 119, F_AVR8, {0x1E, 0x95, 0x0F}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega328PB", 120, F_AVR8, {0x1E, 0x95, 0x16}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 45}, // atdf, avr-gcc 7.3.0, avrdude - {"ATmega329", 121, F_AVR8, {0x1E, 0x95, 0x03}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 23}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega329A", 122, F_AVR8, {0x1E, 0x95, 0x03}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 23}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega329P", 123, F_AVR8, {0x1E, 0x95, 0x0B}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 23}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega329PA", 124, F_AVR8, {0x1E, 0x95, 0x0B}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 23}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega406", 125, F_AVR8, {0x1E, 0x95, 0x07}, 0, 0x0a000, 0x080, 4, 0x0200, 0, 0x0200, 4, 0x0100, 0x0800, 2, 1, 23}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega640", 126, F_AVR8, {0x1E, 0x96, 0x08}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x1000, 8, 0x0200, 0x2000, 3, 1, 57}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega644", 127, F_AVR8, {0x1E, 0x96, 0x09}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 28}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega644A", 128, F_AVR8, {0x1E, 0x96, 0x09}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega644P", 129, F_AVR8, {0x1E, 0x96, 0x0A}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega644PA", 130, F_AVR8, {0x1E, 0x96, 0x0A}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega644RFR2", 131, F_AVR8, {0x1E, 0xA6, 0x03}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0200, 0x2000, 3, 1, 77}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega645", 132, F_AVR8, {0x1E, 0x96, 0x05}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 22}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega645A", 133, F_AVR8, {0x1E, 0x96, 0x05}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 22}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega645P", 134, F_AVR8, {0x1E, 0x96, 0x0D}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 22}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega649", 135, F_AVR8, {0x1E, 0x96, 0x03}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 23}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega649A", 136, F_AVR8, {0x1E, 0x96, 0x03}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 23}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega649P", 137, F_AVR8, {0x1E, 0x96, 0x0B}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 23}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega1280", 138, F_AVR8, {0x1E, 0x97, 0x03}, 0, 0x20000, 0x100, 4, 0x0400, 0, 0x1000, 8, 0x0200, 0x2000, 3, 1, 57}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega1281", 139, F_AVR8, {0x1E, 0x97, 0x04}, 0, 0x20000, 0x100, 4, 0x0400, 0, 0x1000, 8, 0x0200, 0x2000, 3, 1, 57}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega1284", 140, F_AVR8, {0x1E, 0x97, 0x06}, 0, 0x20000, 0x100, 4, 0x0400, 0, 0x1000, 8, 0x0100, 0x4000, 3, 1, 35}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega1284P", 141, F_AVR8, {0x1E, 0x97, 0x05}, 0, 0x20000, 0x100, 4, 0x0400, 0, 0x1000, 8, 0x0100, 0x4000, 3, 1, 35}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega1284RFR2", 142, F_AVR8, {0x1E, 0xA7, 0x03}, 0, 0x20000, 0x100, 4, 0x0400, 0, 0x1000, 8, 0x0200, 0x4000, 3, 1, 77}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega2560", 143, F_AVR8, {0x1E, 0x98, 0x01}, 0, 0x40000, 0x100, 4, 0x0400, 0, 0x1000, 8, 0x0200, 0x2000, 3, 1, 57}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega2561", 144, F_AVR8, {0x1E, 0x98, 0x02}, 0, 0x40000, 0x100, 4, 0x0400, 0, 0x1000, 8, 0x0200, 0x2000, 3, 1, 57}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega2564RFR2", 145, F_AVR8, {0x1E, 0xA8, 0x03}, 0, 0x40000, 0x100, 4, 0x0400, 0, 0x2000, 8, 0x0200, 0x8000, 3, 1, 77}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega3250", 146, F_AVR8, {0x1E, 0x95, 0x06}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 25}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega3250A", 147, F_AVR8, {0x1E, 0x95, 0x06}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 25}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega3250P", 148, F_AVR8, {0x1E, 0x95, 0x0E}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 25}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega3250PA", 149, F_AVR8, {0x1E, 0x95, 0x0E}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 25}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega3290", 150, F_AVR8, {0x1E, 0x95, 0x04}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 25}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega3290A", 151, F_AVR8, {0x1E, 0x95, 0x04}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 25}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega3290P", 152, F_AVR8, {0x1E, 0x95, 0x0C}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 25}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega3290PA", 153, F_AVR8, {0x1E, 0x95, 0x0C}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 25}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega6450", 154, F_AVR8, {0x1E, 0x96, 0x06}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 25}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega6450A", 155, F_AVR8, {0x1E, 0x96, 0x06}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 25}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega6450P", 156, F_AVR8, {0x1E, 0x96, 0x0E}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 25}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega6490", 157, F_AVR8, {0x1E, 0x96, 0x04}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 25}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega6490A", 158, F_AVR8, {0x1E, 0x96, 0x04}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 25}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega6490P", 159, F_AVR8, {0x1E, 0x96, 0x0C}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 25}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega8515", 160, F_AVR8, {0x1E, 0x93, 0x06}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0060, 0x0200, 2, 1, 17}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega8535", 161, F_AVR8, {0x1E, 0x93, 0x08}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0060, 0x0200, 2, 1, 21}, // atdf, avr-gcc 12.2.0, avrdude - {"AT43USB320", 162, F_AVR8, {0xff, -1, -1}, 0, 0x10000, -1, -1, -1, -1, -1, -1, 0x0060, 0x0200, -1, -1, 0}, // avr-gcc 12.2.0 - {"AT43USB355", 163, F_AVR8, {0xff, -1, -1}, 0, 0x06000, -1, -1, -1, -1, -1, -1, 0x0060, 0x0400, -1, -1, 0}, // avr-gcc 12.2.0 - {"AT76C711", 164, F_AVR8, {0xff, -1, -1}, 0, 0x04000, -1, -1, -1, -1, -1, -1, 0x0060, 0x07a0, -1, -1, 0}, // avr-gcc 12.2.0 - {"AT86RF401", 165, F_AVR8, {0x1E, 0x91, 0x81}, 0, 0x00800, -1, -1, -1, -1, -1, -1, 0x0060, 0x0080, 0, 1, 3}, // avr-gcc 12.2.0 - {"AT90PWM1", 166, F_AVR8, {0x1E, 0x93, 0x83}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 32}, // atdf, avr-gcc 12.2.0 - {"AT90PWM2", 167, F_AVR8, {0x1E, 0x93, 0x81}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 32}, // avr-gcc 12.2.0, avrdude, boot size (manual) - {"AT90PWM2B", 168, F_AVR8, {0x1E, 0x93, 0x83}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 32}, // atdf, avr-gcc 12.2.0, avrdude - {"AT90PWM3", 169, F_AVR8, {0x1E, 0x93, 0x81}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 32}, // atdf, avr-gcc 12.2.0, avrdude - {"AT90PWM3B", 170, F_AVR8, {0x1E, 0x93, 0x83}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 32}, // atdf, avr-gcc 12.2.0, avrdude - {"AT90CAN32", 171, F_AVR8, {0x1E, 0x95, 0x81}, 0, 0x08000, 0x100, 4, 0x0400, 0, 0x0400, 8, 0x0100, 0x0800, 3, 1, 37}, // atdf, avr-gcc 12.2.0, avrdude - {"AT90CAN64", 172, F_AVR8, {0x1E, 0x96, 0x81}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 37}, // atdf, avr-gcc 12.2.0, avrdude - {"AT90PWM81", 173, F_AVR8, {0x1E, 0x93, 0x88}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0100, 3, 1, 20}, // atdf, avr-gcc 12.2.0 - {"AT90USB82", 174, F_AVR8, {0x1E, 0x93, 0x82}, 0, 0x02000, 0x080, 4, 0x0200, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 29}, // atdf, avr-gcc 12.2.0, avrdude - {"AT90SCR100", 175, F_AVR8, {0x1E, 0x96, 0xC1}, 0, 0x10000, 0x100, 4, 0x0200, -1, -1, -1, 0x0100, 0x1000, 3, 1, 38}, // avr-gcc 12.2.0, boot size (manual) - {"AT90CAN128", 176, F_AVR8, {0x1E, 0x97, 0x81}, 0, 0x20000, 0x100, 4, 0x0400, 0, 0x1000, 8, 0x0100, 0x1000, 3, 1, 37}, // atdf, avr-gcc 12.2.0, avrdude - {"AT90PWM161", 177, F_AVR8, {0x1E, 0x94, 0x8B}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 20}, // atdf, avr-gcc 12.2.0 - {"AT90USB162", 178, F_AVR8, {0x1E, 0x94, 0x82}, 0, 0x04000, 0x080, 4, 0x0200, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 29}, // atdf, avr-gcc 12.2.0, avrdude - {"AT90PWM216", 179, F_AVR8, {0x1E, 0x94, 0x83}, 0, 0x04000, 0x080, 4, 0x0200, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 32}, // atdf, avr-gcc 12.2.0, avrdude - {"AT90PWM316", 180, F_AVR8, {0x1E, 0x94, 0x83}, 0, 0x04000, 0x080, 4, 0x0200, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 32}, // atdf, avr-gcc 12.2.0, avrdude - {"AT90USB646", 181, F_AVR8, {0x1E, 0x96, 0x82}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 38}, // atdf, avr-gcc 12.2.0, avrdude - {"AT90USB647", 182, F_AVR8, {0x1E, 0x96, 0x82}, 0, 0x10000, 0x100, 4, 0x0400, 0, 0x0800, 8, 0x0100, 0x1000, 3, 1, 38}, // atdf, avr-gcc 12.2.0, avrdude - {"AT90S1200", 183, F_AVR8, {0x1E, 0x90, 0x01}, 0, 0x00400, 0x001, 0, 0, 0, 0x0040, 1, 0x0060, 0x0020, 1, 1, 4}, // avr-gcc 12.2.0, avrdude, boot size (manual) - {"AT90USB1286", 184, F_AVR8, {0x1E, 0x97, 0x82}, 0, 0x20000, 0x100, 4, 0x0400, 0, 0x1000, 8, 0x0100, 0x2000, 3, 1, 38}, // atdf, avr-gcc 12.2.0, avrdude - {"AT90USB1287", 185, F_AVR8, {0x1E, 0x97, 0x82}, 0, 0x20000, 0x100, 4, 0x0400, 0, 0x1000, 8, 0x0100, 0x2000, 3, 1, 38}, // atdf, avr-gcc 12.2.0, avrdude - {"AT90S2313", 186, F_AVR8, {0x1E, 0x91, 0x01}, 0, 0x00800, 0x001, 0, 0, 0, 0x0080, 1, 0x0060, 0x0080, 1, 1, 11}, // avr-gcc 12.2.0, avrdude, boot size (manual) - {"AT90S2323", 187, F_AVR8, {0x1E, 0x91, 0x02}, 0, 0x00800, -1, 0, 0, -1, -1, -1, 0x0060, 0x0080, 1, 1, 3}, // avr-gcc 12.2.0, boot size (manual) - {"AT90S2333", 188, F_AVR8, {0x1E, 0x91, 0x05}, 0, 0x00800, 0x001, 0, 0, 0, 0x0080, 1, 0x0060, 0x0080, -1, -1, 14}, // avr-gcc 12.2.0, avrdude, boot size (manual) - {"AT90S2343", 189, F_AVR8, {0x1E, 0x91, 0x03}, 0, 0x00800, 0x001, 0, 0, 0, 0x0080, 1, 0x0060, 0x0080, 1, 1, 3}, // avr-gcc 12.2.0, avrdude, boot size (manual) - {"AT90S4414", 190, F_AVR8, {0x1E, 0x92, 0x01}, 0, 0x01000, 0x001, 0, 0, 0, 0x0100, 1, 0x0060, 0x0100, 1, 1, 13}, // avr-gcc 12.2.0, avrdude, boot size (manual) - {"AT90S4433", 191, F_AVR8, {0x1E, 0x92, 0x03}, 0, 0x01000, 0x001, 0, 0, 0, 0x0100, 1, 0x0060, 0x0080, 1, 1, 14}, // avr-gcc 12.2.0, avrdude, boot size (manual) - {"AT90S4434", 192, F_AVR8, {0x1E, 0x92, 0x02}, 0, 0x01000, 0x001, 0, 0, 0, 0x0100, 1, 0x0060, 0x0100, 1, 1, 17}, // avr-gcc 12.2.0, avrdude, boot size (manual) - {"AT90S8515", 193, F_AVR8, {0x1E, 0x93, 0x01}, 0, 0x02000, 0x001, 0, 0, 0, 0x0200, 1, 0x0060, 0x0200, 1, 1, 13}, // avr-gcc 12.2.0, avrdude, boot size (manual) - {"AT90C8534", 194, F_AVR8, {0xff, -1, -1}, 0, 0x02000, -1, -1, -1, -1, -1, -1, 0x0060, 0x0100, -1, -1, 0}, // avr-gcc 12.2.0 - {"AT90S8535", 195, F_AVR8, {0x1E, 0x93, 0x03}, 0, 0x02000, 0x001, 0, 0, 0, 0x0200, 1, 0x0060, 0x0200, 1, 1, 17}, // avr-gcc 12.2.0, avrdude, boot size (manual) - {"AT94K", 196, F_AVR8, {0xff, -1, -1}, 0, 0x08000, -1, -1, -1, -1, -1, -1, 0x0060, 0x0fa0, -1, -1, 0}, // avr-gcc 12.2.0 - {"ATA5272", 197, F_AVR8, {0x1E, 0x93, 0x87}, 0, 0x02000, 0x080, 0, 0, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 37}, // atdf, avr-gcc 12.2.0 - {"ATA5505", 198, F_AVR8, {0x1E, 0x94, 0x87}, 0, 0x04000, 0x080, 0, 0, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 20}, // atdf, avr-gcc 12.2.0 - {"ATA5700M322", 199, F_AVR8, {0x1E, 0x95, 0x67}, 0x08000, 0x08000, 0x040, 0, 0, 0, 0x0880, 16, 0x0200, 0x0400, 1, 1, 51}, // atdf - {"ATA5702M322", 200, F_AVR8, {0x1E, 0x95, 0x69}, 0x08000, 0x08000, 0x040, 0, 0, 0, 0x0880, 16, 0x0200, 0x0400, 1, 1, 51}, // atdf, avr-gcc 12.2.0 - {"ATA5781", 201, F_AVR8, {0x1E, 0x95, 0x64}, -1, -1, -1, 0, 0, 0, 0x0400, 16, 0x0200, 0x0400, 1, 1, 42}, // atdf - {"ATA5782", 202, F_AVR8, {0x1E, 0x95, 0x65}, 0x08000, 0x05000, 0x040, 1, 0x5000, 0, 0x0400, 16, 0x0200, 0x0400, 1, 1, 42}, // atdf, avr-gcc 12.2.0 - {"ATA5783", 203, F_AVR8, {0x1E, 0x95, 0x66}, -1, -1, -1, 0, 0, 0, 0x0400, 16, 0x0200, 0x0400, 1, 1, 42}, // atdf - {"ATA5787", 204, F_AVR8, {0x1E, 0x94, 0x6C}, 0x08000, 0x05200, 0x040, 0, 0, 0, 0x0400, 16, 0x0200, 0x0800, 1, 1, 44}, // atdf - {"ATA5790", 205, F_AVR8, {0x1E, 0x94, 0x61}, 0, 0x04000, 0x080, 1, 0x0800, 0, 0x0800, 16, 0x0100, 0x0200, 1, 1, 30}, // atdf, avr-gcc 12.2.0 - {"ATA5790N", 206, F_AVR8, {0x1E, 0x94, 0x62}, 0, 0x04000, 0x080, 1, 0x0800, 0, 0x0800, 16, 0x0100, 0x0200, 1, 1, 31}, // atdf, avr-gcc 12.2.0 - {"ATA5791", 207, F_AVR8, {0x1E, 0x94, 0x62}, 0, 0x04000, 0x080, 1, 0x0800, 0, 0x0800, 16, 0x0100, 0x0200, 1, 1, 31}, // atdf, avr-gcc 7.3.0 - {"ATA5795", 208, F_AVR8, {0x1E, 0x93, 0x61}, 0, 0x02000, 0x040, 1, 0x0800, 0, 0x0800, 16, 0x0100, 0x0200, 1, 1, 23}, // atdf, avr-gcc 12.2.0 - {"ATA5831", 209, F_AVR8, {0x1E, 0x95, 0x61}, 0x08000, 0x05000, 0x040, 1, 0x5000, 0, 0x0400, 16, 0x0200, 0x0400, 1, 1, 42}, // atdf, avr-gcc 12.2.0 - {"ATA5832", 210, F_AVR8, {0x1E, 0x95, 0x62}, -1, -1, -1, 0, 0, 0, 0x0400, 16, 0x0200, 0x0400, 1, 1, 42}, // atdf - {"ATA5833", 211, F_AVR8, {0x1E, 0x95, 0x63}, -1, -1, -1, 0, 0, 0, 0x0400, 16, 0x0200, 0x0400, 1, 1, 42}, // atdf - {"ATA5835", 212, F_AVR8, {0x1E, 0x94, 0x6B}, 0x08000, 0x05200, 0x040, 0, 0, 0, 0x0400, 16, 0x0200, 0x0800, 1, 1, 44}, // atdf - {"ATA6285", 213, F_AVR8, {0x1E, 0x93, 0x82}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0140, 4, 0x0100, 0x0200, 2, 1, 27}, // atdf, avr-gcc 12.2.0 - {"ATA6286", 214, F_AVR8, {0x1E, 0x93, 0x82}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0140, 4, 0x0100, 0x0200, 2, 1, 27}, // atdf, avr-gcc 12.2.0 - {"ATA6289", 215, F_AVR8, {0x1E, 0x93, 0x82}, 0, 0x02000, 0x040, 4, 0x0100, -1, -1, -1, 0x0100, 0x0200, 2, 1, 27}, // avr-gcc 12.2.0, boot size (manual) - {"ATA6612C", 216, F_AVR8, {0x1E, 0x93, 0x0A}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 26}, // atdf, avr-gcc 12.2.0 - {"ATA6613C", 217, F_AVR8, {0x1E, 0x94, 0x06}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 26}, // atdf, avr-gcc 12.2.0 - {"ATA6614Q", 218, F_AVR8, {0x1E, 0x95, 0x0F}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 26}, // atdf, avr-gcc 12.2.0 - {"ATA6616C", 219, F_AVR8, {0x1E, 0x93, 0x87}, 0, 0x02000, 0x080, 0, 0, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 20}, // atdf, avr-gcc 12.2.0 - {"ATA6617C", 220, F_AVR8, {0x1E, 0x94, 0x87}, 0, 0x04000, 0x080, 0, 0, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 20}, // atdf, avr-gcc 12.2.0 - {"ATA8210", 221, F_AVR8, {0x1E, 0x95, 0x65}, 0x08000, 0x05000, 0x040, 1, 0x5000, 0, 0x0400, 16, 0x0200, 0x0400, 1, 1, 42}, // atdf, avr-gcc 7.3.0 - {"ATA8215", 222, F_AVR8, {0x1E, 0x95, 0x64}, -1, -1, -1, 0, 0, 0, 0x0400, 16, 0x0200, 0x0400, 1, 1, 42}, // atdf - {"ATA8510", 223, F_AVR8, {0x1E, 0x95, 0x61}, 0x08000, 0x05000, 0x040, 1, 0x5000, 0, 0x0400, 16, 0x0200, 0x0400, 1, 1, 42}, // atdf, avr-gcc 7.3.0 - {"ATA8515", 224, F_AVR8, {0x1E, 0x95, 0x63}, -1, -1, -1, 0, 0, 0, 0x0400, 16, 0x0200, 0x0400, 1, 1, 42}, // atdf - {"ATA664251", 225, F_AVR8, {0x1E, 0x94, 0x87}, 0, 0x04000, 0x080, 0, 0, 0, 0x0200, 4, 0x0100, 0x0200, 3, 1, 20}, // atdf, avr-gcc 12.2.0 - {"M3000", 226, F_AVR8, {0xff, -1, -1}, 0, 0x10000, -1, -1, -1, -1, -1, -1, 0x1000, 0x1000, -1, -1, 0}, // avr-gcc 12.2.0 - {"LGT8F88P", 227, F_AVR8, {0x1E, 0x93, 0x0F}, 0, 0x02000, 0x040, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 26}, // avrdude, from ATmega88 - {"LGT8F168P", 228, F_AVR8, {0x1E, 0x94, 0x0B}, 0, 0x04000, 0x080, 4, 0x0100, 0, 0x0200, 4, 0x0100, 0x0400, 3, 1, 26}, // avrdude, from ATmega168P - {"LGT8F328P", 229, F_AVR8, {0x1E, 0x95, 0x0F}, 0, 0x08000, 0x080, 4, 0x0200, 0, 0x0400, 4, 0x0100, 0x0800, 3, 1, 26}, // avrdude, from ATmega328P - - {"ATxmega8E5", 230, F_XMEGA, {0x1E, 0x93, 0x41}, 0, 0x02800, 0x080, 1, 0x0800, 0, 0x0200, 32, 0x2000, 0x0400, 7, 1, 43}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega16A4", 231, F_XMEGA, {0x1E, 0x94, 0x41}, 0, 0x05000, 0x100, 1, 0x1000, 0, 0x0400, 32, 0x2000, 0x0800, 6, 1, 94}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega16A4U", 232, F_XMEGA, {0x1E, 0x94, 0x41}, 0, 0x05000, 0x100, 1, 0x1000, 0, 0x0400, 32, 0x2000, 0x0800, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega16C4", 233, F_XMEGA, {0x1E, 0x94, 0x43}, 0, 0x05000, 0x100, 1, 0x1000, 0, 0x0400, 32, 0x2000, 0x0800, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega16D4", 234, F_XMEGA, {0x1E, 0x94, 0x42}, 0, 0x05000, 0x100, 1, 0x1000, 0, 0x0400, 32, 0x2000, 0x0800, 6, 1, 91}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega16E5", 235, F_XMEGA, {0x1E, 0x94, 0x45}, 0, 0x05000, 0x080, 1, 0x1000, 0, 0x0200, 32, 0x2000, 0x0800, 7, 1, 43}, // atdf, avr-gcc 7.3.0, avrdude - {"ATxmega32C3", 236, F_XMEGA, {0x1E, 0x95, 0x49}, 0, 0x09000, 0x100, 1, 0x1000, 0, 0x0400, 32, 0x2000, 0x1000, 6, 1, 127}, // atdf, avr-gcc 12.2.0 - {"ATxmega32D3", 237, F_XMEGA, {0x1E, 0x95, 0x4A}, 0, 0x09000, 0x100, 1, 0x1000, 0, 0x0400, 32, 0x2000, 0x1000, 6, 1, 114}, // atdf, avr-gcc 12.2.0 - {"ATxmega32A4", 238, F_XMEGA, {0x1E, 0x95, 0x41}, 0, 0x09000, 0x100, 1, 0x1000, 0, 0x0400, 32, 0x2000, 0x1000, 6, 1, 94}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega32A4U", 239, F_XMEGA, {0x1E, 0x95, 0x41}, 0, 0x09000, 0x100, 1, 0x1000, 0, 0x0400, 32, 0x2000, 0x1000, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega32C4", 240, F_XMEGA, {0x1E, 0x95, 0x44}, 0, 0x09000, 0x100, 1, 0x1000, 0, 0x0400, 32, 0x2000, 0x1000, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega32D4", 241, F_XMEGA, {0x1E, 0x95, 0x42}, 0, 0x09000, 0x100, 1, 0x1000, 0, 0x0400, 32, 0x2000, 0x1000, 6, 1, 91}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega32E5", 242, F_XMEGA, {0x1E, 0x95, 0x4C}, 0, 0x09000, 0x080, 1, 0x1000, 0, 0x0400, 32, 0x2000, 0x1000, 7, 1, 43}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega64A1", 243, F_XMEGA, {0x1E, 0x96, 0x4E}, 0, 0x11000, 0x100, 1, 0x1000, 0, 0x0800, 32, 0x2000, 0x1000, 6, 1, 125}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega64A1U", 244, F_XMEGA, {0x1E, 0x96, 0x4E}, 0, 0x11000, 0x100, 1, 0x1000, 0, 0x0800, 32, 0x2000, 0x1000, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega64B1", 245, F_XMEGA, {0x1E, 0x96, 0x52}, 0, 0x11000, 0x100, 1, 0x1000, 0, 0x0800, 32, 0x2000, 0x1000, 6, 1, 81}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega64A3", 246, F_XMEGA, {0x1E, 0x96, 0x42}, 0, 0x11000, 0x100, 1, 0x1000, 0, 0x0800, 32, 0x2000, 0x1000, 6, 1, 122}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega64A3U", 247, F_XMEGA, {0x1E, 0x96, 0x42}, 0, 0x11000, 0x100, 1, 0x1000, 0, 0x0800, 32, 0x2000, 0x1000, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega64B3", 248, F_XMEGA, {0x1E, 0x96, 0x51}, 0, 0x11000, 0x100, 1, 0x1000, 0, 0x0800, 32, 0x2000, 0x1000, 6, 1, 54}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega64C3", 249, F_XMEGA, {0x1E, 0x96, 0x49}, 0, 0x11000, 0x100, 1, 0x1000, 0, 0x0800, 32, 0x2000, 0x1000, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega64D3", 250, F_XMEGA, {0x1E, 0x96, 0x4A}, 0, 0x11000, 0x100, 1, 0x1000, 0, 0x0800, 32, 0x2000, 0x1000, 6, 1, 114}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega64A4", 251, F_XMEGA, {0x1E, 0x96, 0x46}, 0, 0x11000, 0x100, -1, -1, 0, 0x0800, 32, -1, -1, -1, -1, 0}, // avrdude - {"ATxmega64A4U", 252, F_XMEGA, {0x1E, 0x96, 0x46}, 0, 0x11000, 0x100, 1, 0x1000, 0, 0x0800, 32, 0x2000, 0x1000, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega64D4", 253, F_XMEGA, {0x1E, 0x96, 0x47}, 0, 0x11000, 0x100, 1, 0x1000, 0, 0x0800, 32, 0x2000, 0x1000, 6, 1, 91}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega128A1", 254, F_XMEGA, {0x1E, 0x97, 0x4C}, 0, 0x22000, 0x200, 1, 0x2000, 0, 0x0800, 32, 0x2000, 0x2000, 6, 1, 125}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega128A1revD", 255, F_XMEGA, {0x1E, 0x97, 0x41}, 0, 0x22000, 0x200, -1, -1, 0, 0x0800, 32, -1, -1, -1, -1, 0}, // avrdude - {"ATxmega128A1U", 256, F_XMEGA, {0x1E, 0x97, 0x4C}, 0, 0x22000, 0x200, 1, 0x2000, 0, 0x0800, 32, 0x2000, 0x2000, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega128B1", 257, F_XMEGA, {0x1E, 0x97, 0x4D}, 0, 0x22000, 0x100, 1, 0x2000, 0, 0x0800, 32, 0x2000, 0x2000, 6, 1, 81}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega128A3", 258, F_XMEGA, {0x1E, 0x97, 0x42}, 0, 0x22000, 0x200, 1, 0x2000, 0, 0x0800, 32, 0x2000, 0x2000, 6, 1, 122}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega128A3U", 259, F_XMEGA, {0x1E, 0x97, 0x42}, 0, 0x22000, 0x200, 1, 0x2000, 0, 0x0800, 32, 0x2000, 0x2000, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega128B3", 260, F_XMEGA, {0x1E, 0x97, 0x4B}, 0, 0x22000, 0x100, 1, 0x2000, 0, 0x0800, 32, 0x2000, 0x2000, 6, 1, 54}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega128C3", 261, F_XMEGA, {0x1E, 0x97, 0x52}, 0, 0x22000, 0x200, 1, 0x2000, 0, 0x0800, 32, 0x2000, 0x2000, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega128D3", 262, F_XMEGA, {0x1E, 0x97, 0x48}, 0, 0x22000, 0x200, 1, 0x2000, 0, 0x0800, 32, 0x2000, 0x2000, 6, 1, 114}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega128A4", 263, F_XMEGA, {0x1E, 0x97, 0x46}, 0, 0x22000, 0x200, -1, -1, 0, 0x0800, 32, -1, -1, -1, -1, 0}, // avrdude - {"ATxmega128A4U", 264, F_XMEGA, {0x1E, 0x97, 0x46}, 0, 0x22000, 0x100, 1, 0x2000, 0, 0x0800, 32, 0x2000, 0x2000, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega128D4", 265, F_XMEGA, {0x1E, 0x97, 0x47}, 0, 0x22000, 0x100, 1, 0x2000, 0, 0x0800, 32, 0x2000, 0x2000, 6, 1, 91}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega192A1", 266, F_XMEGA, {0x1E, 0x97, 0x4E}, 0, 0x32000, 0x200, -1, -1, 0, 0x0800, 32, -1, -1, -1, -1, 0}, // avrdude - {"ATxmega192A3", 267, F_XMEGA, {0x1E, 0x97, 0x44}, 0, 0x32000, 0x200, 1, 0x2000, 0, 0x0800, 32, 0x2000, 0x4000, 6, 1, 122}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega192A3U", 268, F_XMEGA, {0x1E, 0x97, 0x44}, 0, 0x32000, 0x200, 1, 0x2000, 0, 0x0800, 32, 0x2000, 0x4000, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega192C3", 269, F_XMEGA, {0x1E, 0x97, 0x51}, 0, 0x32000, 0x200, 1, 0x2000, 0, 0x0800, 32, 0x2000, 0x4000, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega192D3", 270, F_XMEGA, {0x1E, 0x97, 0x49}, 0, 0x32000, 0x200, 1, 0x2000, 0, 0x0800, 32, 0x2000, 0x4000, 6, 1, 114}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega256A1", 271, F_XMEGA, {0x1E, 0x98, 0x46}, 0, 0x42000, 0x200, -1, -1, 0, 0x1000, 32, -1, -1, -1, -1, 0}, // avrdude - {"ATxmega256A3", 272, F_XMEGA, {0x1E, 0x98, 0x42}, 0, 0x42000, 0x200, 1, 0x2000, 0, 0x1000, 32, 0x2000, 0x4000, 6, 1, 122}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega256A3B", 273, F_XMEGA, {0x1E, 0x98, 0x43}, 0, 0x42000, 0x200, 1, 0x2000, 0, 0x1000, 32, 0x2000, 0x4000, 6, 1, 122}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega256A3BU", 274, F_XMEGA, {0x1E, 0x98, 0x43}, 0, 0x42000, 0x200, 1, 0x2000, 0, 0x1000, 32, 0x2000, 0x4000, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega256A3U", 275, F_XMEGA, {0x1E, 0x98, 0x42}, 0, 0x42000, 0x200, 1, 0x2000, 0, 0x1000, 32, 0x2000, 0x4000, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega256C3", 276, F_XMEGA, {0x1E, 0x98, 0x46}, 0, 0x42000, 0x200, 1, 0x2000, 0, 0x1000, 32, 0x2000, 0x4000, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega256D3", 277, F_XMEGA, {0x1E, 0x98, 0x44}, 0, 0x42000, 0x200, 1, 0x2000, 0, 0x1000, 32, 0x2000, 0x4000, 6, 1, 114}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega384C3", 278, F_XMEGA, {0x1E, 0x98, 0x45}, 0, 0x62000, 0x200, 1, 0x2000, 0, 0x1000, 32, 0x2000, 0x8000, 6, 1, 127}, // atdf, avr-gcc 12.2.0, avrdude - {"ATxmega384D3", 279, F_XMEGA, {0x1E, 0x98, 0x47}, 0, 0x62000, 0x200, 1, 0x2000, 0, 0x1000, 32, 0x2000, 0x8000, 6, 1, 114}, // atdf, avr-gcc 12.2.0, avrdude - - {"ATtiny202", 280, F_AVR8X, {0x1E, 0x91, 0x23}, 0, 0x00800, 0x040, 1, 0, 0x01400, 0x0040, 32, 0x3f80, 0x0080, 10, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny204", 281, F_AVR8X, {0x1E, 0x91, 0x22}, 0, 0x00800, 0x040, 1, 0, 0x01400, 0x0040, 32, 0x3f80, 0x0080, 10, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny212", 282, F_AVR8X, {0x1E, 0x91, 0x21}, 0, 0x00800, 0x040, 1, 0, 0x01400, 0x0040, 32, 0x3f80, 0x0080, 10, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny214", 283, F_AVR8X, {0x1E, 0x91, 0x20}, 0, 0x00800, 0x040, 1, 0, 0x01400, 0x0040, 32, 0x3f80, 0x0080, 10, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny402", 284, F_AVR8X, {0x1E, 0x92, 0x27}, 0, 0x01000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3f00, 0x0100, 10, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny404", 285, F_AVR8X, {0x1E, 0x92, 0x26}, 0, 0x01000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3f00, 0x0100, 10, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny406", 286, F_AVR8X, {0x1E, 0x92, 0x25}, 0, 0x01000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3f00, 0x0100, 10, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny412", 287, F_AVR8X, {0x1E, 0x92, 0x23}, 0, 0x01000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3f00, 0x0100, 10, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny414", 288, F_AVR8X, {0x1E, 0x92, 0x22}, 0, 0x01000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3f00, 0x0100, 10, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny416", 289, F_AVR8X, {0x1E, 0x92, 0x21}, 0, 0x01000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3f00, 0x0100, 10, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny416auto", 290, F_AVR8X, {0x1E, 0x92, 0x28}, 0, 0x01000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3f00, 0x0100, 10, 1, 26}, // atdf - {"ATtiny417", 291, F_AVR8X, {0x1E, 0x92, 0x20}, 0, 0x01000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3f00, 0x0100, 10, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny424", 292, F_AVR8X, {0x1E, 0x92, 0x2C}, 0, 0x01000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10, 1, 30}, // atdf, avrdude - {"ATtiny426", 293, F_AVR8X, {0x1E, 0x92, 0x2B}, 0, 0x01000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10, 1, 30}, // atdf, avrdude - {"ATtiny427", 294, F_AVR8X, {0x1E, 0x92, 0x2A}, 0, 0x01000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10, 1, 30}, // atdf, avrdude - {"ATtiny804", 295, F_AVR8X, {0x1E, 0x93, 0x25}, 0, 0x02000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny806", 296, F_AVR8X, {0x1E, 0x93, 0x24}, 0, 0x02000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny807", 297, F_AVR8X, {0x1E, 0x93, 0x23}, 0, 0x02000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny814", 298, F_AVR8X, {0x1E, 0x93, 0x22}, 0, 0x02000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny816", 299, F_AVR8X, {0x1E, 0x93, 0x21}, 0, 0x02000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny817", 300, F_AVR8X, {0x1E, 0x93, 0x20}, 0, 0x02000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10, 1, 26}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny824", 301, F_AVR8X, {0x1E, 0x93, 0x29}, 0, 0x02000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3c00, 0x0400, 10, 1, 30}, // atdf, avrdude - {"ATtiny826", 302, F_AVR8X, {0x1E, 0x93, 0x28}, 0, 0x02000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3c00, 0x0400, 10, 1, 30}, // atdf, avrdude - {"ATtiny827", 303, F_AVR8X, {0x1E, 0x93, 0x27}, 0, 0x02000, 0x040, 1, 0, 0x01400, 0x0080, 32, 0x3c00, 0x0400, 10, 1, 30}, // atdf, avrdude - {"ATtiny1604", 304, F_AVR8X, {0x1E, 0x94, 0x25}, 0, 0x04000, 0x040, 1, 0, 0x01400, 0x0100, 32, 0x3c00, 0x0400, 10, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny1606", 305, F_AVR8X, {0x1E, 0x94, 0x24}, 0, 0x04000, 0x040, 1, 0, 0x01400, 0x0100, 32, 0x3c00, 0x0400, 10, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny1607", 306, F_AVR8X, {0x1E, 0x94, 0x23}, 0, 0x04000, 0x040, 1, 0, 0x01400, 0x0100, 32, 0x3c00, 0x0400, 10, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny1614", 307, F_AVR8X, {0x1E, 0x94, 0x22}, 0, 0x04000, 0x040, 1, 0, 0x01400, 0x0100, 32, 0x3800, 0x0800, 10, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny1616", 308, F_AVR8X, {0x1E, 0x94, 0x21}, 0, 0x04000, 0x040, 1, 0, 0x01400, 0x0100, 32, 0x3800, 0x0800, 10, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny1617", 309, F_AVR8X, {0x1E, 0x94, 0x20}, 0, 0x04000, 0x040, 1, 0, 0x01400, 0x0100, 32, 0x3800, 0x0800, 10, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny1624", 310, F_AVR8X, {0x1E, 0x94, 0x2A}, 0, 0x04000, 0x040, 1, 0, 0x01400, 0x0100, 32, 0x3800, 0x0800, 10, 1, 30}, // atdf, avrdude - {"ATtiny1626", 311, F_AVR8X, {0x1E, 0x94, 0x29}, 0, 0x04000, 0x040, 1, 0, 0x01400, 0x0100, 32, 0x3800, 0x0800, 10, 1, 30}, // atdf, avrdude - {"ATtiny1627", 312, F_AVR8X, {0x1E, 0x94, 0x28}, 0, 0x04000, 0x040, 1, 0, 0x01400, 0x0100, 32, 0x3800, 0x0800, 10, 1, 30}, // atdf, avrdude - {"ATtiny3214", 313, F_AVR8X, {0x1E, 0x95, 0x20}, 0, 0x08000, 0x080, 1, 0, 0x01400, 0x0100, 64, 0x3800, 0x0800, 10, 1, 31}, // avr-gcc 12.2.0 - {"ATtiny3216", 314, F_AVR8X, {0x1E, 0x95, 0x21}, 0, 0x08000, 0x080, 1, 0, 0x01400, 0x0100, 64, 0x3800, 0x0800, 10, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny3217", 315, F_AVR8X, {0x1E, 0x95, 0x22}, 0, 0x08000, 0x080, 1, 0, 0x01400, 0x0100, 64, 0x3800, 0x0800, 10, 1, 31}, // atdf, avr-gcc 12.2.0, avrdude - {"ATtiny3224", 316, F_AVR8X, {0x1E, 0x95, 0x28}, 0, 0x08000, 0x080, 1, 0, 0x01400, 0x0100, 64, 0x3400, 0x0c00, 10, 1, 30}, // atdf, avrdude - {"ATtiny3226", 317, F_AVR8X, {0x1E, 0x95, 0x27}, 0, 0x08000, 0x080, 1, 0, 0x01400, 0x0100, 64, 0x3400, 0x0c00, 10, 1, 30}, // atdf, avrdude - {"ATtiny3227", 318, F_AVR8X, {0x1E, 0x95, 0x26}, 0, 0x08000, 0x080, 1, 0, 0x01400, 0x0100, 64, 0x3400, 0x0c00, 10, 1, 30}, // atdf, avrdude - {"ATmega808", 319, F_AVR8X, {0x1E, 0x93, 0x26}, 0, 0x02000, 0x040, 1, 0, 0x01400, 0x0100, 32, 0x3c00, 0x0400, 10, 1, 36}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega809", 320, F_AVR8X, {0x1E, 0x93, 0x2A}, 0, 0x02000, 0x040, 1, 0, 0x01400, 0x0100, 32, 0x3c00, 0x0400, 10, 1, 40}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega1608", 321, F_AVR8X, {0x1E, 0x94, 0x27}, 0, 0x04000, 0x040, 1, 0, 0x01400, 0x0100, 32, 0x3800, 0x0800, 10, 1, 36}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega1609", 322, F_AVR8X, {0x1E, 0x94, 0x26}, 0, 0x04000, 0x040, 1, 0, 0x01400, 0x0100, 32, 0x3800, 0x0800, 10, 1, 40}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega3208", 323, F_AVR8X, {0x1E, 0x95, 0x30}, 0, 0x08000, 0x080, 1, 0, 0x01400, 0x0100, 64, 0x3000, 0x1000, 10, 1, 36}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega3209", 324, F_AVR8X, {0x1E, 0x95, 0x31}, 0, 0x08000, 0x080, 1, 0, 0x01400, 0x0100, 64, 0x3000, 0x1000, 10, 1, 40}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega4808", 325, F_AVR8X, {0x1E, 0x96, 0x50}, 0, 0x0c000, 0x080, 1, 0, 0x01400, 0x0100, 64, 0x2800, 0x1800, 10, 1, 36}, // atdf, avr-gcc 12.2.0, avrdude - {"ATmega4809", 326, F_AVR8X, {0x1E, 0x96, 0x51}, 0, 0x0c000, 0x080, 1, 0, 0x01400, 0x0100, 64, 0x2800, 0x1800, 10, 1, 40}, // atdf, avr-gcc 12.2.0, avrdude - {"AVR8EA28", 327, F_AVR8X, {0x1E, 0x93, 0x2C}, 0, 0x02000, 0x040, 1, 0, 0x01400, 0x0200, 8, -1, -1, -1, -1, 0}, // avrdude - {"AVR8EA32", 328, F_AVR8X, {0x1E, 0x93, 0x2B}, 0, 0x02000, 0x040, 1, 0, 0x01400, 0x0200, 8, -1, -1, -1, -1, 0}, // avrdude - {"AVR16DD14", 329, F_AVR8X, {0x1E, 0x94, 0x34}, 0, 0x04000, 0x200, 1, 0, 0x01400, 0x0100, 1, 0x7800, 0x0800, 16, 4, 36}, // atdf, avrdude - {"AVR16DD20", 330, F_AVR8X, {0x1E, 0x94, 0x33}, 0, 0x04000, 0x200, 1, 0, 0x01400, 0x0100, 1, 0x7800, 0x0800, 16, 4, 36}, // atdf, avrdude - {"AVR16DD28", 331, F_AVR8X, {0x1E, 0x94, 0x32}, 0, 0x04000, 0x200, 1, 0, 0x01400, 0x0100, 1, 0x7800, 0x0800, 16, 4, 36}, // atdf, avrdude - {"AVR16EA28", 332, F_AVR8X, {0x1E, 0x94, 0x37}, 0, 0x04000, 0x040, 1, 0, 0x01400, 0x0200, 8, -1, -1, -1, -1, 0}, // avrdude - {"AVR16DD32", 333, F_AVR8X, {0x1E, 0x94, 0x31}, 0, 0x04000, 0x200, 1, 0, 0x01400, 0x0100, 1, 0x7800, 0x0800, 16, 4, 36}, // atdf, avrdude - {"AVR16EA32", 334, F_AVR8X, {0x1E, 0x94, 0x36}, 0, 0x04000, 0x040, 1, 0, 0x01400, 0x0200, 8, -1, -1, -1, -1, 0}, // avrdude - {"AVR16EA48", 335, F_AVR8X, {0x1E, 0x94, 0x35}, 0, 0x04000, 0x040, 1, 0, 0x01400, 0x0200, 8, -1, -1, -1, -1, 0}, // avrdude - {"AVR32DD14", 336, F_AVR8X, {0x1E, 0x95, 0x3B}, 0, 0x08000, 0x200, 1, 0, 0x01400, 0x0100, 1, 0x7000, 0x1000, 16, 4, 36}, // atdf, avrdude - {"AVR32DD20", 337, F_AVR8X, {0x1E, 0x95, 0x3A}, 0, 0x08000, 0x200, 1, 0, 0x01400, 0x0100, 1, 0x7000, 0x1000, 16, 4, 36}, // atdf, avrdude - {"AVR32DA28", 338, F_AVR8X, {0x1E, 0x95, 0x34}, 0, 0x08000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x7000, 0x1000, 16, 4, 41}, // atdf, avrdude - {"AVR32DB28", 339, F_AVR8X, {0x1E, 0x95, 0x37}, 0, 0x08000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x7000, 0x1000, 16, 4, 42}, // atdf, avrdude - {"AVR32DD28", 340, F_AVR8X, {0x1E, 0x95, 0x39}, 0, 0x08000, 0x200, 1, 0, 0x01400, 0x0100, 1, 0x7000, 0x1000, 16, 4, 36}, // atdf, avrdude - {"AVR32EA28", 341, F_AVR8X, {0x1E, 0x95, 0x3E}, 0, 0x08000, 0x040, 1, 0, 0x01400, 0x0200, 8, -1, -1, -1, -1, 0}, // avrdude - {"AVR32DA32", 342, F_AVR8X, {0x1E, 0x95, 0x33}, 0, 0x08000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x7000, 0x1000, 16, 4, 44}, // atdf, avrdude - {"AVR32DB32", 343, F_AVR8X, {0x1E, 0x95, 0x36}, 0, 0x08000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x7000, 0x1000, 16, 4, 44}, // atdf, avrdude - {"AVR32DD32", 344, F_AVR8X, {0x1E, 0x95, 0x38}, 0, 0x08000, 0x200, 1, 0, 0x01400, 0x0100, 1, 0x7000, 0x1000, 16, 4, 36}, // atdf, avrdude - {"AVR32EA32", 345, F_AVR8X, {0x1E, 0x95, 0x3D}, 0, 0x08000, 0x040, 1, 0, 0x01400, 0x0200, 8, -1, -1, -1, -1, 0}, // avrdude - {"AVR32DA48", 346, F_AVR8X, {0x1E, 0x95, 0x32}, 0, 0x08000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x7000, 0x1000, 16, 4, 58}, // atdf, avrdude - {"AVR32DB48", 347, F_AVR8X, {0x1E, 0x95, 0x35}, 0, 0x08000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x7000, 0x1000, 16, 4, 61}, // atdf, avrdude - {"AVR32EA48", 348, F_AVR8X, {0x1E, 0x95, 0x3C}, 0, 0x08000, 0x040, 1, 0, 0x01400, 0x0200, 8, -1, -1, -1, -1, 0}, // avrdude - {"AVR64DD14", 349, F_AVR8X, {0x1E, 0x96, 0x1D}, 0, 0x10000, 0x200, 1, 0, 0x01400, 0x0100, 1, 0x6000, 0x2000, 16, 4, 36}, // atdf, avrdude - {"AVR64DD20", 350, F_AVR8X, {0x1E, 0x96, 0x1C}, 0, 0x10000, 0x200, 1, 0, 0x01400, 0x0100, 1, 0x6000, 0x2000, 16, 4, 36}, // atdf, avrdude - {"AVR64DA28", 351, F_AVR8X, {0x1E, 0x96, 0x15}, 0, 0x10000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x6000, 0x2000, 16, 4, 41}, // atdf, avrdude - {"AVR64DB28", 352, F_AVR8X, {0x1E, 0x96, 0x19}, 0, 0x10000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x6000, 0x2000, 16, 4, 42}, // atdf, avrdude - {"AVR64DD28", 353, F_AVR8X, {0x1E, 0x96, 0x1B}, 0, 0x10000, 0x200, 1, 0, 0x01400, 0x0100, 1, 0x6000, 0x2000, 16, 4, 36}, // atdf, avrdude - {"AVR64EA28", 354, F_AVR8X, {0x1E, 0x96, 0x20}, 0, 0x10000, 0x080, 1, 0, 0x01400, 0x0200, 8, 0x6800, 0x1800, 16, 4, 37}, // atdf, avrdude - {"AVR64DA32", 355, F_AVR8X, {0x1E, 0x96, 0x14}, 0, 0x10000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x6000, 0x2000, 16, 4, 44}, // atdf, avrdude - {"AVR64DB32", 356, F_AVR8X, {0x1E, 0x96, 0x18}, 0, 0x10000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x6000, 0x2000, 16, 4, 44}, // atdf, avrdude - {"AVR64DD32", 357, F_AVR8X, {0x1E, 0x96, 0x1A}, 0, 0x10000, 0x200, 1, 0, 0x01400, 0x0100, 1, 0x6000, 0x2000, 16, 4, 36}, // atdf, avrdude - {"AVR64EA32", 358, F_AVR8X, {0x1E, 0x96, 0x1F}, 0, 0x10000, 0x080, 1, 0, 0x01400, 0x0200, 8, 0x6800, 0x1800, 16, 4, 37}, // atdf, avrdude - {"AVR64DA48", 359, F_AVR8X, {0x1E, 0x96, 0x13}, 0, 0x10000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x6000, 0x2000, 16, 4, 58}, // atdf, avrdude - {"AVR64DB48", 360, F_AVR8X, {0x1E, 0x96, 0x17}, 0, 0x10000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x6000, 0x2000, 16, 4, 61}, // atdf, avrdude - {"AVR64EA48", 361, F_AVR8X, {0x1E, 0x96, 0x1E}, 0, 0x10000, 0x080, 1, 0, 0x01400, 0x0200, 8, 0x6800, 0x1800, 16, 4, 45}, // atdf, avrdude - {"AVR64DA64", 362, F_AVR8X, {0x1E, 0x96, 0x12}, 0, 0x10000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x6000, 0x2000, 16, 4, 64}, // atdf, avrdude - {"AVR64DB64", 363, F_AVR8X, {0x1E, 0x96, 0x16}, 0, 0x10000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x6000, 0x2000, 16, 4, 65}, // atdf, avrdude - {"AVR128DA28", 364, F_AVR8X, {0x1E, 0x97, 0x0A}, 0, 0x20000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x4000, 0x4000, 16, 4, 41}, // atdf, avrdude - {"AVR128DB28", 365, F_AVR8X, {0x1E, 0x97, 0x0E}, 0, 0x20000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x4000, 0x4000, 16, 4, 42}, // atdf, avrdude - {"AVR128DA32", 366, F_AVR8X, {0x1E, 0x97, 0x09}, 0, 0x20000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x4000, 0x4000, 16, 4, 44}, // atdf, avrdude - {"AVR128DB32", 367, F_AVR8X, {0x1E, 0x97, 0x0D}, 0, 0x20000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x4000, 0x4000, 16, 4, 44}, // atdf, avrdude - {"AVR128DA48", 368, F_AVR8X, {0x1E, 0x97, 0x08}, 0, 0x20000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x4000, 0x4000, 16, 4, 58}, // atdf, avrdude - {"AVR128DB48", 369, F_AVR8X, {0x1E, 0x97, 0x0C}, 0, 0x20000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x4000, 0x4000, 16, 4, 61}, // atdf, avrdude - {"AVR128DA64", 370, F_AVR8X, {0x1E, 0x97, 0x07}, 0, 0x20000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x4000, 0x4000, 16, 4, 64}, // atdf, avrdude - {"AVR128DB64", 371, F_AVR8X, {0x1E, 0x97, 0x0B}, 0, 0x20000, 0x200, 1, 0, 0x01400, 0x0200, 1, 0x4000, 0x4000, 16, 4, 65}, // atdf, avrdude -}; - -const size_t avr_isp_chip_arr_size = COUNT_OF(avr_isp_chip_arr); \ No newline at end of file diff --git a/applications/external/avr_isp_programmer/lib/driver/avr_isp_chip_arr.h b/applications/external/avr_isp_programmer/lib/driver/avr_isp_chip_arr.h deleted file mode 100644 index 66f16a7b9..000000000 --- a/applications/external/avr_isp_programmer/lib/driver/avr_isp_chip_arr.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include - -#define F_AVR8L 1 // TPI programming, ATtiny(4|5|9|10|20|40|102|104) -#define F_AVR8 2 // ISP programming with SPI, "classic" AVRs -#define F_XMEGA 4 // PDI programming, ATxmega family -#define F_AVR8X 8 // UPDI programming, newer 8-bit MCUs - -struct AvrIspChipArr { // Value of -1 typically means unknown - const char* name; // Name of part - uint16_t mcuid; // ID of MCU in 0..2039 - uint8_t avrarch; // F_AVR8L, F_AVR8, F_XMEGA or F_AVR8X - uint8_t sigs[3]; // Signature bytes - int32_t flashoffset; // Flash offset - int32_t flashsize; // Flash size - int16_t pagesize; // Flash page size - int8_t nboots; // Number of supported boot sectors - int16_t bootsize; // Size of (smallest) boot sector - int32_t eepromoffset; // EEPROM offset - int32_t eepromsize; // EEPROM size - int32_t eeprompagesize; // EEPROM page size - int32_t sramstart; // SRAM offset - int32_t sramsize; // SRAM size - int8_t nfuses; // Number of fuse bytes - int8_t nlocks; // Number of lock bytes - uint8_t ninterrupts; // Number of vectors in interrupt vector table -}; - -typedef struct AvrIspChipArr AvrIspChipArr; - -extern const AvrIspChipArr avr_isp_chip_arr[]; -extern const size_t avr_isp_chip_arr_size; \ No newline at end of file diff --git a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c b/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c deleted file mode 100644 index bbb6d4739..000000000 --- a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c +++ /dev/null @@ -1,639 +0,0 @@ -#include "avr_isp_prog.h" -#include "avr_isp_prog_cmd.h" - -#include - -#define AVR_ISP_PROG_TX_RX_BUF_SIZE 320 -#define TAG "AvrIspProg" - -struct AvrIspProgSignature { - uint8_t vendor; - uint8_t part_family; - uint8_t part_number; -}; - -typedef struct AvrIspProgSignature AvrIspProgSignature; - -struct AvrIspProgCfgDevice { - uint8_t devicecode; - uint8_t revision; - uint8_t progtype; - uint8_t parmode; - uint8_t polling; - uint8_t selftimed; - uint8_t lockbytes; - uint8_t fusebytes; - uint8_t flashpoll; - uint16_t eeprompoll; - uint16_t pagesize; - uint16_t eepromsize; - uint32_t flashsize; -}; - -typedef struct AvrIspProgCfgDevice AvrIspProgCfgDevice; - -struct AvrIspProg { - AvrIspSpiSw* spi; - AvrIspProgCfgDevice* cfg; - FuriStreamBuffer* stream_rx; - FuriStreamBuffer* stream_tx; - - uint16_t error; - uint16_t addr; - bool pmode; - bool exit; - bool rst_active_high; - uint8_t buff[AVR_ISP_PROG_TX_RX_BUF_SIZE]; - - AvrIspProgCallback callback; - void* context; -}; - -static void avr_isp_prog_end_pmode(AvrIspProg* instance); - -AvrIspProg* avr_isp_prog_init(void) { - AvrIspProg* instance = malloc(sizeof(AvrIspProg)); - instance->cfg = malloc(sizeof(AvrIspProgCfgDevice)); - instance->stream_rx = - furi_stream_buffer_alloc(sizeof(int8_t) * AVR_ISP_PROG_TX_RX_BUF_SIZE, sizeof(int8_t)); - instance->stream_tx = - furi_stream_buffer_alloc(sizeof(int8_t) * AVR_ISP_PROG_TX_RX_BUF_SIZE, sizeof(int8_t)); - instance->rst_active_high = false; - instance->exit = false; - return instance; -} - -void avr_isp_prog_free(AvrIspProg* instance) { - furi_assert(instance); - if(instance->spi) avr_isp_prog_end_pmode(instance); - furi_stream_buffer_free(instance->stream_tx); - furi_stream_buffer_free(instance->stream_rx); - free(instance->cfg); - free(instance); -} - -size_t avr_isp_prog_spaces_rx(AvrIspProg* instance) { - return furi_stream_buffer_spaces_available(instance->stream_rx); -} - -bool avr_isp_prog_rx(AvrIspProg* instance, uint8_t* data, size_t len) { - furi_assert(instance); - furi_assert(data); - furi_assert(len != 0); - size_t ret = furi_stream_buffer_send(instance->stream_rx, data, sizeof(uint8_t) * len, 0); - return ret == sizeof(uint8_t) * len; -} - -size_t avr_isp_prog_tx(AvrIspProg* instance, uint8_t* data, size_t max_len) { - furi_assert(instance); - return furi_stream_buffer_receive(instance->stream_tx, data, sizeof(int8_t) * max_len, 0); -} - -void avr_isp_prog_exit(AvrIspProg* instance) { - furi_assert(instance); - instance->exit = true; -} - -void avr_isp_prog_set_tx_callback(AvrIspProg* instance, AvrIspProgCallback callback, void* context) { - furi_assert(instance); - furi_assert(context); - instance->callback = callback; - instance->context = context; -} - -static void avr_isp_prog_tx_ch(AvrIspProg* instance, uint8_t data) { - furi_assert(instance); - furi_stream_buffer_send(instance->stream_tx, &data, sizeof(uint8_t), FuriWaitForever); -} - -static uint8_t avr_isp_prog_getch(AvrIspProg* instance) { - furi_assert(instance); - uint8_t data[1] = {0}; - while(furi_stream_buffer_receive(instance->stream_rx, &data, sizeof(int8_t), 30) == 0) { - if(instance->exit) break; - }; - return data[0]; -} - -static void avr_isp_prog_fill(AvrIspProg* instance, size_t len) { - furi_assert(instance); - for(size_t x = 0; x < len; x++) { - instance->buff[x] = avr_isp_prog_getch(instance); - } -} - -static void avr_isp_prog_reset_target(AvrIspProg* instance, bool reset) { - furi_assert(instance); - avr_isp_spi_sw_res_set(instance->spi, (reset == instance->rst_active_high) ? true : false); -} - -static uint8_t avr_isp_prog_spi_transaction( - AvrIspProg* instance, - uint8_t cmd, - uint8_t addr_hi, - uint8_t addr_lo, - uint8_t data) { - furi_assert(instance); - - avr_isp_spi_sw_txrx(instance->spi, cmd); - avr_isp_spi_sw_txrx(instance->spi, addr_hi); - avr_isp_spi_sw_txrx(instance->spi, addr_lo); - return avr_isp_spi_sw_txrx(instance->spi, data); -} - -static void avr_isp_prog_empty_reply(AvrIspProg* instance) { - furi_assert(instance); - if(avr_isp_prog_getch(instance) == CRC_EOP) { - avr_isp_prog_tx_ch(instance, STK_INSYNC); - avr_isp_prog_tx_ch(instance, STK_OK); - } else { - instance->error++; - avr_isp_prog_tx_ch(instance, STK_NOSYNC); - } -} - -static void avr_isp_prog_breply(AvrIspProg* instance, uint8_t data) { - furi_assert(instance); - if(avr_isp_prog_getch(instance) == CRC_EOP) { - avr_isp_prog_tx_ch(instance, STK_INSYNC); - avr_isp_prog_tx_ch(instance, data); - avr_isp_prog_tx_ch(instance, STK_OK); - } else { - instance->error++; - avr_isp_prog_tx_ch(instance, STK_NOSYNC); - } -} - -static void avr_isp_prog_get_version(AvrIspProg* instance, uint8_t data) { - furi_assert(instance); - switch(data) { - case STK_HW_VER: - avr_isp_prog_breply(instance, AVR_ISP_HWVER); - break; - case STK_SW_MAJOR: - avr_isp_prog_breply(instance, AVR_ISP_SWMAJ); - break; - case STK_SW_MINOR: - avr_isp_prog_breply(instance, AVR_ISP_SWMIN); - break; - case AVP_ISP_CONNECT_TYPE: - avr_isp_prog_breply(instance, AVP_ISP_SERIAL_CONNECT_TYPE); - break; - default: - avr_isp_prog_breply(instance, AVR_ISP_RESP_0); - } -} - -static void avr_isp_prog_set_cfg(AvrIspProg* instance) { - furi_assert(instance); - // call this after reading cfg packet into buff[] - instance->cfg->devicecode = instance->buff[0]; - instance->cfg->revision = instance->buff[1]; - instance->cfg->progtype = instance->buff[2]; - instance->cfg->parmode = instance->buff[3]; - instance->cfg->polling = instance->buff[4]; - instance->cfg->selftimed = instance->buff[5]; - instance->cfg->lockbytes = instance->buff[6]; - instance->cfg->fusebytes = instance->buff[7]; - instance->cfg->flashpoll = instance->buff[8]; - // ignore (instance->buff[9] == instance->buff[8]) //FLASH polling value. Same as “flashpoll” - instance->cfg->eeprompoll = instance->buff[10] << 8 | instance->buff[11]; - instance->cfg->pagesize = instance->buff[12] << 8 | instance->buff[13]; - instance->cfg->eepromsize = instance->buff[14] << 8 | instance->buff[15]; - instance->cfg->flashsize = instance->buff[16] << 24 | instance->buff[17] << 16 | - instance->buff[18] << 8 | instance->buff[19]; - - // avr devices have active low reset, at89sx are active high - instance->rst_active_high = (instance->cfg->devicecode >= 0xe0); -} -static bool - avr_isp_prog_set_pmode(AvrIspProg* instance, uint8_t a, uint8_t b, uint8_t c, uint8_t d) { - furi_assert(instance); - uint8_t res = 0; - avr_isp_spi_sw_txrx(instance->spi, a); - avr_isp_spi_sw_txrx(instance->spi, b); - res = avr_isp_spi_sw_txrx(instance->spi, c); - avr_isp_spi_sw_txrx(instance->spi, d); - return res == 0x53; -} - -static void avr_isp_prog_end_pmode(AvrIspProg* instance) { - furi_assert(instance); - if(instance->pmode) { - avr_isp_prog_reset_target(instance, false); - // We're about to take the target out of reset - // so configure SPI pins as input - - if(instance->spi) avr_isp_spi_sw_free(instance->spi); - instance->spi = NULL; - } - - instance->pmode = false; -} - -static bool avr_isp_prog_start_pmode(AvrIspProg* instance, AvrIspSpiSwSpeed spi_speed) { - furi_assert(instance); - // Reset target before driving PIN_SCK or PIN_MOSI - - // SPI.begin() will configure SS as output, - // so SPI master mode is selected. - // We have defined RESET as pin 10, - // which for many arduino's is not the SS pin. - // So we have to configure RESET as output here, - // (reset_target() first sets the correct level) - if(instance->spi) avr_isp_spi_sw_free(instance->spi); - instance->spi = avr_isp_spi_sw_init(spi_speed); - - avr_isp_prog_reset_target(instance, true); - // See avr datasheets, chapter "SERIAL_PRG Programming Algorithm": - - // Pulse RESET after PIN_SCK is low: - avr_isp_spi_sw_sck_set(instance->spi, false); - - // discharge PIN_SCK, value arbitrally chosen - furi_delay_ms(20); - avr_isp_prog_reset_target(instance, false); - - // Pulse must be minimum 2 target CPU speed cycles - // so 100 usec is ok for CPU speeds above 20KHz - furi_delay_ms(1); - - avr_isp_prog_reset_target(instance, true); - - // Send the enable programming command: - // datasheet: must be > 20 msec - furi_delay_ms(50); - if(avr_isp_prog_set_pmode(instance, AVR_ISP_SET_PMODE)) { - instance->pmode = true; - return true; - } - return false; -} - -static AvrIspProgSignature avr_isp_prog_check_signature(AvrIspProg* instance) { - furi_assert(instance); - AvrIspProgSignature signature; - signature.vendor = avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_VENDOR); - signature.part_family = avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_PART_FAMILY); - signature.part_number = avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_PART_NUMBER); - return signature; -} - -static bool avr_isp_prog_auto_set_spi_speed_start_pmode(AvrIspProg* instance) { - AvrIspSpiSwSpeed spi_speed[] = { - AvrIspSpiSwSpeed1Mhz, - AvrIspSpiSwSpeed400Khz, - AvrIspSpiSwSpeed250Khz, - AvrIspSpiSwSpeed125Khz, - AvrIspSpiSwSpeed60Khz, - AvrIspSpiSwSpeed40Khz, - AvrIspSpiSwSpeed20Khz, - AvrIspSpiSwSpeed10Khz, - AvrIspSpiSwSpeed5Khz, - AvrIspSpiSwSpeed1Khz, - }; - for(uint8_t i = 0; i < COUNT_OF(spi_speed); i++) { - if(avr_isp_prog_start_pmode(instance, spi_speed[i])) { - AvrIspProgSignature sig = avr_isp_prog_check_signature(instance); - AvrIspProgSignature sig_examination = avr_isp_prog_check_signature(instance); //-V656 - uint8_t y = 0; - while(y < 8) { - if(memcmp( - (uint8_t*)&sig, (uint8_t*)&sig_examination, sizeof(AvrIspProgSignature)) != - 0) - break; - sig_examination = avr_isp_prog_check_signature(instance); - y++; - } - if(y == 8) { - if(spi_speed[i] > AvrIspSpiSwSpeed1Mhz) { - if(i < (COUNT_OF(spi_speed) - 1)) { - avr_isp_prog_end_pmode(instance); - i++; - return avr_isp_prog_start_pmode(instance, spi_speed[i]); - } - } - return true; - } - } - } - - if(instance->spi) { - avr_isp_spi_sw_free(instance->spi); - instance->spi = NULL; - } - - return false; -} - -static void avr_isp_prog_universal(AvrIspProg* instance) { - furi_assert(instance); - uint8_t data; - - avr_isp_prog_fill(instance, 4); - data = avr_isp_prog_spi_transaction( - instance, instance->buff[0], instance->buff[1], instance->buff[2], instance->buff[3]); - avr_isp_prog_breply(instance, data); -} - -static void avr_isp_prog_commit(AvrIspProg* instance, uint16_t addr, uint8_t data) { - furi_assert(instance); - avr_isp_prog_spi_transaction(instance, AVR_ISP_COMMIT(addr)); - /* polling flash */ - if(data == 0xFF) { - furi_delay_ms(5); - } else { - /* polling flash */ - uint32_t starttime = furi_get_tick(); - while((furi_get_tick() - starttime) < 30) { - if(avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_FLASH_HI(addr)) != 0xFF) { - break; - }; - } - } -} - -static uint16_t avr_isp_prog_current_page(AvrIspProg* instance) { - furi_assert(instance); - uint16_t page = 0; - switch(instance->cfg->pagesize) { - case 32: - page = instance->addr & 0xFFFFFFF0; - break; - case 64: - page = instance->addr & 0xFFFFFFE0; - break; - case 128: - page = instance->addr & 0xFFFFFFC0; - break; - case 256: - page = instance->addr & 0xFFFFFF80; - break; - - default: - page = instance->addr; - break; - } - - return page; -} - -static uint8_t avr_isp_prog_write_flash_pages(AvrIspProg* instance, size_t length) { - furi_assert(instance); - size_t x = 0; - uint16_t page = avr_isp_prog_current_page(instance); - while(x < length) { - if(page != avr_isp_prog_current_page(instance)) { - --x; - avr_isp_prog_commit(instance, page, instance->buff[x++]); - page = avr_isp_prog_current_page(instance); - } - avr_isp_prog_spi_transaction( - instance, AVR_ISP_WRITE_FLASH_LO(instance->addr, instance->buff[x++])); - - avr_isp_prog_spi_transaction( - instance, AVR_ISP_WRITE_FLASH_HI(instance->addr, instance->buff[x++])); - instance->addr++; - } - - avr_isp_prog_commit(instance, page, instance->buff[--x]); - return STK_OK; -} - -static void avr_isp_prog_write_flash(AvrIspProg* instance, size_t length) { - furi_assert(instance); - avr_isp_prog_fill(instance, length); - if(avr_isp_prog_getch(instance) == CRC_EOP) { - avr_isp_prog_tx_ch(instance, STK_INSYNC); - avr_isp_prog_tx_ch(instance, avr_isp_prog_write_flash_pages(instance, length)); - } else { - instance->error++; - avr_isp_prog_tx_ch(instance, STK_NOSYNC); - } -} - -// write (length) bytes, (start) is a byte address -static uint8_t - avr_isp_prog_write_eeprom_chunk(AvrIspProg* instance, uint16_t start, uint16_t length) { - furi_assert(instance); - // this writes byte-by-byte, - // page writing may be faster (4 bytes at a time) - avr_isp_prog_fill(instance, length); - for(uint16_t x = 0; x < length; x++) { - uint16_t addr = start + x; - avr_isp_prog_spi_transaction(instance, AVR_ISP_WRITE_EEPROM(addr, instance->buff[x])); - furi_delay_ms(10); - } - return STK_OK; -} - -static uint8_t avr_isp_prog_write_eeprom(AvrIspProg* instance, size_t length) { - furi_assert(instance); - // here is a word address, get the byte address - uint16_t start = instance->addr * 2; - uint16_t remaining = length; - if(length > instance->cfg->eepromsize) { - instance->error++; - return STK_FAILED; - } - while(remaining > AVR_ISP_EECHUNK) { - avr_isp_prog_write_eeprom_chunk(instance, start, AVR_ISP_EECHUNK); - start += AVR_ISP_EECHUNK; - remaining -= AVR_ISP_EECHUNK; - } - avr_isp_prog_write_eeprom_chunk(instance, start, remaining); - return STK_OK; -} - -static void avr_isp_prog_program_page(AvrIspProg* instance) { - furi_assert(instance); - uint8_t result = STK_FAILED; - uint16_t length = avr_isp_prog_getch(instance) << 8 | avr_isp_prog_getch(instance); - uint8_t memtype = avr_isp_prog_getch(instance); - // flash memory @addr, (length) bytes - if(memtype == STK_SET_FLASH_TYPE) { - avr_isp_prog_write_flash(instance, length); - return; - } - if(memtype == STK_SET_EEPROM_TYPE) { - result = avr_isp_prog_write_eeprom(instance, length); - if(avr_isp_prog_getch(instance) == CRC_EOP) { - avr_isp_prog_tx_ch(instance, STK_INSYNC); - avr_isp_prog_tx_ch(instance, result); - - } else { - instance->error++; - avr_isp_prog_tx_ch(instance, STK_NOSYNC); - } - return; - } - avr_isp_prog_tx_ch(instance, STK_FAILED); - return; -} - -static uint8_t avr_isp_prog_flash_read_page(AvrIspProg* instance, uint16_t length) { - furi_assert(instance); - for(uint16_t x = 0; x < length; x += 2) { - avr_isp_prog_tx_ch( - instance, - avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_FLASH_LO(instance->addr))); - avr_isp_prog_tx_ch( - instance, - avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_FLASH_HI(instance->addr))); - instance->addr++; - } - return STK_OK; -} - -static uint8_t avr_isp_prog_eeprom_read_page(AvrIspProg* instance, uint16_t length) { - furi_assert(instance); - // here again we have a word address - uint16_t start = instance->addr * 2; - for(uint16_t x = 0; x < length; x++) { - uint16_t addr = start + x; - avr_isp_prog_tx_ch( - instance, avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_EEPROM(addr))); - } - return STK_OK; -} - -static void avr_isp_prog_read_page(AvrIspProg* instance) { - furi_assert(instance); - uint8_t result = STK_FAILED; - uint16_t length = avr_isp_prog_getch(instance) << 8 | avr_isp_prog_getch(instance); - uint8_t memtype = avr_isp_prog_getch(instance); - if(avr_isp_prog_getch(instance) != CRC_EOP) { - instance->error++; - avr_isp_prog_tx_ch(instance, STK_NOSYNC); - return; - } - avr_isp_prog_tx_ch(instance, STK_INSYNC); - if(memtype == STK_SET_FLASH_TYPE) result = avr_isp_prog_flash_read_page(instance, length); - if(memtype == STK_SET_EEPROM_TYPE) result = avr_isp_prog_eeprom_read_page(instance, length); - avr_isp_prog_tx_ch(instance, result); -} - -static void avr_isp_prog_read_signature(AvrIspProg* instance) { - furi_assert(instance); - if(avr_isp_prog_getch(instance) != CRC_EOP) { - instance->error++; - avr_isp_prog_tx_ch(instance, STK_NOSYNC); - return; - } - avr_isp_prog_tx_ch(instance, STK_INSYNC); - - avr_isp_prog_tx_ch(instance, avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_VENDOR)); - avr_isp_prog_tx_ch(instance, avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_PART_FAMILY)); - avr_isp_prog_tx_ch(instance, avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_PART_NUMBER)); - - avr_isp_prog_tx_ch(instance, STK_OK); -} - -void avr_isp_prog_avrisp(AvrIspProg* instance) { - furi_assert(instance); - uint8_t ch = avr_isp_prog_getch(instance); - - switch(ch) { - case STK_GET_SYNC: - FURI_LOG_D(TAG, "cmd STK_GET_SYNC"); - instance->error = 0; - avr_isp_prog_empty_reply(instance); - break; - case STK_GET_SIGN_ON: - FURI_LOG_D(TAG, "cmd STK_GET_SIGN_ON"); - if(avr_isp_prog_getch(instance) == CRC_EOP) { - avr_isp_prog_tx_ch(instance, STK_INSYNC); - - avr_isp_prog_tx_ch(instance, 'A'); - avr_isp_prog_tx_ch(instance, 'V'); - avr_isp_prog_tx_ch(instance, 'R'); - avr_isp_prog_tx_ch(instance, ' '); - avr_isp_prog_tx_ch(instance, 'I'); - avr_isp_prog_tx_ch(instance, 'S'); - avr_isp_prog_tx_ch(instance, 'P'); - - avr_isp_prog_tx_ch(instance, STK_OK); - } else { - instance->error++; - avr_isp_prog_tx_ch(instance, STK_NOSYNC); - } - break; - case STK_GET_PARAMETER: - FURI_LOG_D(TAG, "cmd STK_GET_PARAMETER"); - avr_isp_prog_get_version(instance, avr_isp_prog_getch(instance)); - break; - case STK_SET_DEVICE: - FURI_LOG_D(TAG, "cmd STK_SET_DEVICE"); - avr_isp_prog_fill(instance, 20); - avr_isp_prog_set_cfg(instance); - avr_isp_prog_empty_reply(instance); - break; - case STK_SET_DEVICE_EXT: // ignore for now - FURI_LOG_D(TAG, "cmd STK_SET_DEVICE_EXT"); - avr_isp_prog_fill(instance, 5); - avr_isp_prog_empty_reply(instance); - break; - case STK_ENTER_PROGMODE: - FURI_LOG_D(TAG, "cmd STK_ENTER_PROGMODE"); - if(!instance->pmode) avr_isp_prog_auto_set_spi_speed_start_pmode(instance); - avr_isp_prog_empty_reply(instance); - break; - case STK_LOAD_ADDRESS: - FURI_LOG_D(TAG, "cmd STK_LOAD_ADDRESS"); - instance->addr = avr_isp_prog_getch(instance) | avr_isp_prog_getch(instance) << 8; - avr_isp_prog_empty_reply(instance); - break; - case STK_PROG_FLASH: // ignore for now - FURI_LOG_D(TAG, "cmd STK_PROG_FLASH"); - avr_isp_prog_getch(instance); - avr_isp_prog_getch(instance); - avr_isp_prog_empty_reply(instance); - break; - case STK_PROG_DATA: // ignore for now - FURI_LOG_D(TAG, "cmd STK_PROG_DATA"); - avr_isp_prog_getch(instance); - avr_isp_prog_empty_reply(instance); - break; - case STK_PROG_PAGE: - FURI_LOG_D(TAG, "cmd STK_PROG_PAGE"); - avr_isp_prog_program_page(instance); - break; - case STK_READ_PAGE: - FURI_LOG_D(TAG, "cmd STK_READ_PAGE"); - avr_isp_prog_read_page(instance); - break; - case STK_UNIVERSAL: - FURI_LOG_D(TAG, "cmd STK_UNIVERSAL"); - avr_isp_prog_universal(instance); - break; - case STK_LEAVE_PROGMODE: - FURI_LOG_D(TAG, "cmd STK_LEAVE_PROGMODE"); - instance->error = 0; - if(instance->pmode) avr_isp_prog_end_pmode(instance); - avr_isp_prog_empty_reply(instance); - break; - case STK_READ_SIGN: - FURI_LOG_D(TAG, "cmd STK_READ_SIGN"); - avr_isp_prog_read_signature(instance); - break; - // expecting a command, not CRC_EOP - // this is how we can get back in sync - case CRC_EOP: - FURI_LOG_D(TAG, "cmd CRC_EOP"); - instance->error++; - avr_isp_prog_tx_ch(instance, STK_NOSYNC); - break; - // anything else we will return STK_UNKNOWN - default: - FURI_LOG_D(TAG, "cmd STK_ERROR_CMD"); - instance->error++; - if(avr_isp_prog_getch(instance) == CRC_EOP) - avr_isp_prog_tx_ch(instance, STK_UNKNOWN); - else - avr_isp_prog_tx_ch(instance, STK_NOSYNC); - } - - if(instance->callback) { - instance->callback(instance->context); - } -} diff --git a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.h b/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.h deleted file mode 100644 index 2c15ab066..000000000 --- a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "avr_isp_spi_sw.h" -#include - -typedef struct AvrIspProg AvrIspProg; -typedef void (*AvrIspProgCallback)(void* context); - -AvrIspProg* avr_isp_prog_init(void); -void avr_isp_prog_free(AvrIspProg* instance); -size_t avr_isp_prog_spaces_rx(AvrIspProg* instance) ; -bool avr_isp_prog_rx(AvrIspProg* instance, uint8_t* data, size_t len); -size_t avr_isp_prog_tx(AvrIspProg* instance, uint8_t* data, size_t max_len); -void avr_isp_prog_avrisp(AvrIspProg* instance); -void avr_isp_prog_exit(AvrIspProg* instance); -void avr_isp_prog_set_tx_callback(AvrIspProg* instance, AvrIspProgCallback callback, void* context); diff --git a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog_cmd.h b/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog_cmd.h deleted file mode 100644 index f8b07203e..000000000 --- a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog_cmd.h +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once - -// http://ww1.microchip.com/downloads/en/appnotes/atmel-0943-in-system-programming_applicationnote_avr910.pdf -// AVR ISP Definitions -#define AVR_ISP_HWVER 0X02 -#define AVR_ISP_SWMAJ 0X01 -#define AVR_ISP_SWMIN 0X12 -#define AVP_ISP_SERIAL_CONNECT_TYPE 0X53 -#define AVP_ISP_CONNECT_TYPE 0x93 -#define AVR_ISP_RESP_0 0X00 - -#define AVR_ISP_SET_PMODE 0xAC, 0x53, 0x00, 0x00 -#define AVR_ISP_READ_VENDOR 0x30, 0x00, 0x00, 0x00 -#define AVR_ISP_READ_PART_FAMILY 0x30, 0x00, 0x01, 0x00 -#define AVR_ISP_READ_PART_NUMBER 0x30, 0x00, 0x02, 0x00 -#define AVR_ISP_ERASE_CHIP \ - 0xAC, 0x80, 0x00, 0x00 //Erase Chip, Wait N ms, Release RESET to end the erase. -//The only way to end a Chip Erase cycle is by temporarily releasing the Reset line - -#define AVR_ISP_EXTENDED_ADDR(data) 0x4D, 0x00, data, 0x00 -#define AVR_ISP_WRITE_FLASH_LO(add, data) 0x40, (add >> 8) & 0xFF, add & 0xFF, data -#define AVR_ISP_WRITE_FLASH_HI(add, data) 0x48, (add >> 8) & 0xFF, add & 0xFF, data -#define AVR_ISP_READ_FLASH_LO(add) 0x20, (add >> 8) & 0xFF, add & 0xFF, 0x00 -#define AVR_ISP_READ_FLASH_HI(add) 0x28, (add >> 8) & 0xFF, add & 0xFF, 0x00 - -#define AVR_ISP_WRITE_EEPROM(add, data) \ - 0xC0, (add >> 8) & 0xFF, add & 0xFF, data //Send cmd, Wait N ms -#define AVR_ISP_READ_EEPROM(add) 0xA0, (add >> 8) & 0xFF, add & 0xFF, 0xFF - -#define AVR_ISP_COMMIT(add) \ - 0x4C, (add >> 8) & 0xFF, add & 0xFF, 0x00 //Send cmd, polling read last addr page - -#define AVR_ISP_OSCCAL(add) 0x38, 0x00, add, 0x00 - -#define AVR_ISP_WRITE_LOCK_BYTE(data) 0xAC, 0xE0, 0x00, data //Send cmd, Wait N ms -#define AVR_ISP_READ_LOCK_BYTE 0x58, 0x00, 0x00, 0x00 -#define AVR_ISP_WRITE_FUSE_LOW(data) 0xAC, 0xA0, 0x00, data //Send cmd, Wait N ms -#define AVR_ISP_READ_FUSE_LOW 0x50, 0x00, 0x00, 0x00 -#define AVR_ISP_WRITE_FUSE_HIGH(data) 0xAC, 0xA8, 0x00, data //Send cmd, Wait N ms -#define AVR_ISP_READ_FUSE_HIGH 0x58, 0x08, 0x00, 0x00 -#define AVR_ISP_WRITE_FUSE_EXTENDED(data) 0xAC, 0xA4, 0x00, data //Send cmd, Wait N ms (~write) -#define AVR_ISP_READ_FUSE_EXTENDED 0x50, 0x08, 0x00, 0x00 - -#define AVR_ISP_EECHUNK 0x20 - -// https://www.microchip.com/content/dam/mchp/documents/OTH/ApplicationNotes/ApplicationNotes/doc2525.pdf -// STK Definitions -#define STK_OK 0x10 -#define STK_FAILED 0x11 -#define STK_UNKNOWN 0x12 -#define STK_INSYNC 0x14 -#define STK_NOSYNC 0x15 -#define CRC_EOP 0x20 - -#define STK_GET_SYNC 0x30 -#define STK_GET_SIGN_ON 0x31 -#define STK_SET_PARAMETER 0x40 -#define STK_GET_PARAMETER 0x41 -#define STK_SET_DEVICE 0x42 -#define STK_SET_DEVICE_EXT 0x45 -#define STK_ENTER_PROGMODE 0x50 -#define STK_LEAVE_PROGMODE 0x51 -#define STK_CHIP_ERASE 0x52 -#define STK_CHECK_AUTOINC 0x53 -#define STK_LOAD_ADDRESS 0x55 -#define STK_UNIVERSAL 0x56 -#define STK_UNIVERSAL_MULTI 0x57 -#define STK_PROG_FLASH 0x60 -#define STK_PROG_DATA 0x61 -#define STK_PROG_FUSE 0x62 -#define STK_PROG_FUSE_EXT 0x65 -#define STK_PROG_LOCK 0x63 -#define STK_PROG_PAGE 0x64 -#define STK_READ_FLASH 0x70 -#define STK_READ_DATA 0x71 -#define STK_READ_FUSE 0x72 -#define STK_READ_LOCK 0x73 -#define STK_READ_PAGE 0x74 -#define STK_READ_SIGN 0x75 -#define STK_READ_OSCCAL 0x76 -#define STK_READ_FUSE_EXT 0x77 -#define STK_READ_OSCCAL_EXT 0x78 -#define STK_HW_VER 0x80 -#define STK_SW_MAJOR 0x81 -#define STK_SW_MINOR 0x82 -#define STK_LEDS 0x83 -#define STK_VTARGET 0x84 -#define STK_VADJUST 0x85 -#define STK_OSC_PSCALE 0x86 -#define STK_OSC_CMATCH 0x87 -#define STK_SCK_DURATION 0x89 -#define STK_BUFSIZEL 0x90 -#define STK_BUFSIZEH 0x91 -#define STK_STK500_TOPCARD_DETECT 0x98 - -#define STK_SET_EEPROM_TYPE 0X45 -#define STK_SET_FLASH_TYPE 0X46 diff --git a/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c b/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c deleted file mode 100644 index c6d9d54c8..000000000 --- a/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c +++ /dev/null @@ -1,71 +0,0 @@ -#include "avr_isp_spi_sw.h" - -#include - -#define AVR_ISP_SPI_SW_MISO &gpio_ext_pa6 -#define AVR_ISP_SPI_SW_MOSI &gpio_ext_pa7 -#define AVR_ISP_SPI_SW_SCK &gpio_ext_pb3 -#define AVR_ISP_RESET &gpio_ext_pb2 - -struct AvrIspSpiSw { - AvrIspSpiSwSpeed speed_wait_time; - const GpioPin* miso; - const GpioPin* mosi; - const GpioPin* sck; - const GpioPin* res; -}; - -AvrIspSpiSw* avr_isp_spi_sw_init(AvrIspSpiSwSpeed speed) { - AvrIspSpiSw* instance = malloc(sizeof(AvrIspSpiSw)); - instance->speed_wait_time = speed; - instance->miso = AVR_ISP_SPI_SW_MISO; - instance->mosi = AVR_ISP_SPI_SW_MOSI; - instance->sck = AVR_ISP_SPI_SW_SCK; - instance->res = AVR_ISP_RESET; - - furi_hal_gpio_init(instance->miso, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_write(instance->mosi, false); - furi_hal_gpio_init(instance->mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_write(instance->sck, false); - furi_hal_gpio_init(instance->sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_init(instance->res, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - - return instance; -} - -void avr_isp_spi_sw_free(AvrIspSpiSw* instance) { - furi_assert(instance); - furi_hal_gpio_init(instance->res, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(instance->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(instance->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(instance->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - free(instance); -} - -uint8_t avr_isp_spi_sw_txrx(AvrIspSpiSw* instance, uint8_t data) { - furi_assert(instance); - for(uint8_t i = 0; i < 8; ++i) { - furi_hal_gpio_write(instance->mosi, (data & 0x80) ? true : false); - - furi_hal_gpio_write(instance->sck, true); - if(instance->speed_wait_time != AvrIspSpiSwSpeed1Mhz) - furi_delay_us(instance->speed_wait_time - 1); - - data = (data << 1) | furi_hal_gpio_read(instance->miso); //-V792 - - furi_hal_gpio_write(instance->sck, false); - if(instance->speed_wait_time != AvrIspSpiSwSpeed1Mhz) - furi_delay_us(instance->speed_wait_time - 1); - } - return data; -} - -void avr_isp_spi_sw_res_set(AvrIspSpiSw* instance, bool state) { - furi_assert(instance); - furi_hal_gpio_write(instance->res, state); -} - -void avr_isp_spi_sw_sck_set(AvrIspSpiSw* instance, bool state) { - furi_assert(instance); - furi_hal_gpio_write(instance->sck, state); -} \ No newline at end of file diff --git a/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.h b/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.h deleted file mode 100644 index 44de5ff79..000000000 --- a/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include - -typedef enum { - AvrIspSpiSwSpeed1Mhz = 0, - AvrIspSpiSwSpeed400Khz = 1, - AvrIspSpiSwSpeed250Khz = 2, - AvrIspSpiSwSpeed125Khz = 4, - AvrIspSpiSwSpeed60Khz = 8, - AvrIspSpiSwSpeed40Khz = 12, - AvrIspSpiSwSpeed20Khz = 24, - AvrIspSpiSwSpeed10Khz = 48, - AvrIspSpiSwSpeed5Khz = 96, - AvrIspSpiSwSpeed1Khz = 480, -} AvrIspSpiSwSpeed; - -typedef struct AvrIspSpiSw AvrIspSpiSw; - -AvrIspSpiSw* avr_isp_spi_sw_init(AvrIspSpiSwSpeed speed); -void avr_isp_spi_sw_free(AvrIspSpiSw* instance); -uint8_t avr_isp_spi_sw_txrx(AvrIspSpiSw* instance, uint8_t data); -void avr_isp_spi_sw_res_set(AvrIspSpiSw* instance, bool state); -void avr_isp_spi_sw_sck_set(AvrIspSpiSw* instance, bool state); \ No newline at end of file diff --git a/applications/external/avr_isp_programmer/lib/driver/clock.png b/applications/external/avr_isp_programmer/lib/driver/clock.png deleted file mode 100644 index 93a59fe68..000000000 Binary files a/applications/external/avr_isp_programmer/lib/driver/clock.png and /dev/null differ diff --git a/applications/external/avr_isp_programmer/scenes/avr_isp_scene.c b/applications/external/avr_isp_programmer/scenes/avr_isp_scene.c deleted file mode 100644 index 4af125aee..000000000 --- a/applications/external/avr_isp_programmer/scenes/avr_isp_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "../avr_isp_app_i.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const avr_isp_scene_on_enter_handlers[])(void*) = { -#include "avr_isp_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 avr_isp_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "avr_isp_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 avr_isp_scene_on_exit_handlers[])(void* context) = { -#include "avr_isp_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers avr_isp_scene_handlers = { - .on_enter_handlers = avr_isp_scene_on_enter_handlers, - .on_event_handlers = avr_isp_scene_on_event_handlers, - .on_exit_handlers = avr_isp_scene_on_exit_handlers, - .scene_num = AvrIspSceneNum, -}; diff --git a/applications/external/avr_isp_programmer/scenes/avr_isp_scene.h b/applications/external/avr_isp_programmer/scenes/avr_isp_scene.h deleted file mode 100644 index 658ee7432..000000000 --- a/applications/external/avr_isp_programmer/scenes/avr_isp_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) AvrIspScene##id, -typedef enum { -#include "avr_isp_scene_config.h" - AvrIspSceneNum, -} AvrIspScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers avr_isp_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "avr_isp_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 "avr_isp_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 "avr_isp_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_about.c b/applications/external/avr_isp_programmer/scenes/avr_isp_scene_about.c deleted file mode 100644 index e5f530fec..000000000 --- a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_about.c +++ /dev/null @@ -1,99 +0,0 @@ -#include "../avr_isp_app_i.h" -#include "../helpers/avr_isp_types.h" - -void avr_isp_scene_about_widget_callback(GuiButtonType result, InputType type, void* context) { - furi_assert(context); - - AvrIspApp* app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(app->view_dispatcher, result); - } -} - -void avr_isp_scene_about_on_enter(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - FuriString* temp_str = furi_string_alloc(); - furi_string_printf(temp_str, "\e#%s\n", "Information"); - - furi_string_cat_printf(temp_str, "Version: %s\n", AVR_ISP_VERSION_APP); - furi_string_cat_printf(temp_str, "Developed by: %s\n", AVR_ISP_DEVELOPED); - furi_string_cat_printf(temp_str, "Github: %s\n\n", AVR_ISP_GITHUB); - - furi_string_cat_printf(temp_str, "\e#%s\n", "Description"); - furi_string_cat_printf( - temp_str, - "This application is an AVR in-system programmer based on stk500mk1. It is compatible with AVR-based" - " microcontrollers including Arduino. You can also use it to repair the chip if you accidentally" - " corrupt the bootloader.\n\n"); - - furi_string_cat_printf(temp_str, "\e#%s\n", "What it can do:"); - furi_string_cat_printf(temp_str, "- Create a dump of your chip on an SD card\n"); - furi_string_cat_printf(temp_str, "- Flash your chip firmware from the SD card\n"); - furi_string_cat_printf(temp_str, "- Act as a wired USB ISP using avrdude software\n\n"); - - furi_string_cat_printf(temp_str, "\e#%s\n", "Supported chip series:"); - furi_string_cat_printf( - temp_str, - "Example command for avrdude flashing: avrdude.exe -p m328p -c stk500v1 -P COMxx -U flash:r:" - "X:\\sketch_sample.hex" - ":i\n"); - furi_string_cat_printf( - temp_str, - "Where: " - "-p m328p" - " brand of your chip, " - "-P COMxx" - " com port number in the system when " - "ISP Programmer" - " is enabled\n\n"); - - furi_string_cat_printf(temp_str, "\e#%s\n", "Info"); - furi_string_cat_printf( - temp_str, - "ATtinyXXXX\nATmegaXXXX\nAT43Uxxx\nAT76C711\nAT86RF401\nAT90xxxxx\nAT94K\n" - "ATAxxxxx\nATA664251\nM3000\nLGT8F88P\nLGT8F168P\nLGT8F328P\n"); - - furi_string_cat_printf( - temp_str, "For a more detailed list of supported chips, see AVRDude help\n"); - - widget_add_text_box_element( - app->widget, - 0, - 0, - 128, - 14, - AlignCenter, - AlignBottom, - "\e#\e! \e!\n", - false); - widget_add_text_box_element( - app->widget, - 0, - 2, - 128, - 14, - AlignCenter, - AlignBottom, - "\e#\e! ISP Programmer \e!\n", - false); - widget_add_text_scroll_element(app->widget, 0, 16, 128, 50, furi_string_get_cstr(temp_str)); - furi_string_free(temp_str); - - view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewWidget); -} - -bool avr_isp_scene_about_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void avr_isp_scene_about_on_exit(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - // Clear views - widget_reset(app->widget); -} diff --git a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_chip_detect.c b/applications/external/avr_isp_programmer/scenes/avr_isp_scene_chip_detect.c deleted file mode 100644 index 79c239390..000000000 --- a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_chip_detect.c +++ /dev/null @@ -1,72 +0,0 @@ -#include "../avr_isp_app_i.h" - -void avr_isp_scene_chip_detect_callback(AvrIspCustomEvent event, void* context) { - furi_assert(context); - - AvrIspApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -void avr_isp_scene_chip_detect_on_enter(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - switch(app->error) { - case AvrIspErrorReading: - case AvrIspErrorWriting: - case AvrIspErrorWritingFuse: - avr_isp_chip_detect_set_state( - app->avr_isp_chip_detect_view, AvrIspChipDetectViewStateErrorOccured); - break; - case AvrIspErrorVerification: - avr_isp_chip_detect_set_state( - app->avr_isp_chip_detect_view, AvrIspChipDetectViewStateErrorVerification); - break; - - default: - avr_isp_chip_detect_set_state( - app->avr_isp_chip_detect_view, AvrIspChipDetectViewStateNoDetect); - break; - } - app->error = AvrIspErrorNoError; - avr_isp_chip_detect_view_set_callback( - app->avr_isp_chip_detect_view, avr_isp_scene_chip_detect_callback, app); - - view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewChipDetect); -} - -bool avr_isp_scene_chip_detect_on_event(void* context, SceneManagerEvent event) { - furi_assert(context); - - AvrIspApp* app = context; - bool consumed = false; - if(event.type == SceneManagerEventTypeCustom) { - switch(event.event) { - case AvrIspCustomEventSceneChipDetectOk: - - if(scene_manager_get_scene_state(app->scene_manager, AvrIspSceneChipDetect) == - AvrIspViewProgrammer) { - scene_manager_next_scene(app->scene_manager, AvrIspSceneProgrammer); - } else if( - scene_manager_get_scene_state(app->scene_manager, AvrIspSceneChipDetect) == - AvrIspViewReader) { - scene_manager_next_scene(app->scene_manager, AvrIspSceneInputName); - } else if( - scene_manager_get_scene_state(app->scene_manager, AvrIspSceneChipDetect) == - AvrIspViewWriter) { - scene_manager_next_scene(app->scene_manager, AvrIspSceneLoad); - } - - consumed = true; - break; - default: - break; - } - } else if(event.type == SceneManagerEventTypeTick) { - } - return consumed; -} - -void avr_isp_scene_chip_detect_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_config.h b/applications/external/avr_isp_programmer/scenes/avr_isp_scene_config.h deleted file mode 100644 index 6f22511db..000000000 --- a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_config.h +++ /dev/null @@ -1,10 +0,0 @@ -ADD_SCENE(avr_isp, start, Start) -ADD_SCENE(avr_isp, about, About) -ADD_SCENE(avr_isp, programmer, Programmer) -ADD_SCENE(avr_isp, reader, Reader) -ADD_SCENE(avr_isp, input_name, InputName) -ADD_SCENE(avr_isp, load, Load) -ADD_SCENE(avr_isp, writer, Writer) -ADD_SCENE(avr_isp, wiring, Wiring) -ADD_SCENE(avr_isp, chip_detect, ChipDetect) -ADD_SCENE(avr_isp, success, Success) diff --git a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_input_name.c b/applications/external/avr_isp_programmer/scenes/avr_isp_scene_input_name.c deleted file mode 100644 index 3394f4362..000000000 --- a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_input_name.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "../avr_isp_app_i.h" -#include - -#define MAX_TEXT_INPUT_LEN 22 - -void avr_isp_scene_input_name_text_callback(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, AvrIspCustomEventSceneInputName); -} - -void avr_isp_scene_input_name_get_timefilename(FuriString* name) { - FuriHalRtcDateTime datetime = {0}; - furi_hal_rtc_get_datetime(&datetime); - furi_string_printf( - name, - "AVR_dump-%.4d%.2d%.2d-%.2d%.2d%.2d", - datetime.year, - datetime.month, - datetime.day, - datetime.hour, - datetime.minute, - datetime.second); -} - -void avr_isp_scene_input_name_on_enter(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - // Setup view - TextInput* text_input = app->text_input; - bool dev_name_empty = false; - - FuriString* file_name = furi_string_alloc(); - - avr_isp_scene_input_name_get_timefilename(file_name); - furi_string_set(app->file_path, STORAGE_APP_DATA_PATH_PREFIX); - //highlighting the entire filename by default - dev_name_empty = true; - - strncpy(app->file_name_tmp, furi_string_get_cstr(file_name), AVR_ISP_MAX_LEN_NAME); - text_input_set_header_text(text_input, "Name dump"); - text_input_set_result_callback( - text_input, - avr_isp_scene_input_name_text_callback, - app, - app->file_name_tmp, - MAX_TEXT_INPUT_LEN, // buffer size - dev_name_empty); - - ValidatorIsFile* validator_is_file = - validator_is_file_alloc_init(STORAGE_APP_DATA_PATH_PREFIX, AVR_ISP_APP_EXTENSION, ""); - text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - - furi_string_free(file_name); - - view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewTextInput); -} - -bool avr_isp_scene_input_name_on_event(void* context, SceneManagerEvent event) { - furi_assert(context); - - AvrIspApp* app = context; - if(event.type == SceneManagerEventTypeBack) { - scene_manager_previous_scene(app->scene_manager); - return true; - } else if(event.type == SceneManagerEventTypeCustom) { - if(event.event == AvrIspCustomEventSceneInputName) { - if(strcmp(app->file_name_tmp, "") != 0) { - scene_manager_next_scene(app->scene_manager, AvrIspSceneReader); - } else { - } - } - } - return false; -} - -void avr_isp_scene_input_name_on_exit(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - // Clear validator - void* validator_context = text_input_get_validator_callback_context(app->text_input); - text_input_set_validator(app->text_input, NULL, NULL); - validator_is_file_free(validator_context); - // Clear view - text_input_reset(app->text_input); -} diff --git a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_load.c b/applications/external/avr_isp_programmer/scenes/avr_isp_scene_load.c deleted file mode 100644 index e8890e373..000000000 --- a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_load.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "../avr_isp_app_i.h" - -void avr_isp_scene_load_on_enter(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - if(avr_isp_load_from_file(app)) { - scene_manager_next_scene(app->scene_manager, AvrIspSceneWriter); - } else { - scene_manager_previous_scene(app->scene_manager); - } -} - -bool avr_isp_scene_load_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void avr_isp_scene_load_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_programmer.c b/applications/external/avr_isp_programmer/scenes/avr_isp_scene_programmer.c deleted file mode 100644 index 0915e1e8a..000000000 --- a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_programmer.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "../avr_isp_app_i.h" - -void avr_isp_scene_programmer_callback(AvrIspCustomEvent event, void* context) { - furi_assert(context); - - AvrIspApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -void avr_isp_scene_programmer_on_enter(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - avr_isp_programmer_view_set_callback( - app->avr_isp_programmer_view, avr_isp_scene_programmer_callback, app); - - view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewProgrammer); -} - -bool avr_isp_scene_programmer_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void avr_isp_scene_programmer_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_reader.c b/applications/external/avr_isp_programmer/scenes/avr_isp_scene_reader.c deleted file mode 100644 index 8dcb47597..000000000 --- a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_reader.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "../avr_isp_app_i.h" - -void avr_isp_scene_reader_callback(AvrIspCustomEvent event, void* context) { - furi_assert(context); - - AvrIspApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -void avr_isp_scene_reader_on_enter(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - avr_isp_reader_set_file_path( - app->avr_isp_reader_view, furi_string_get_cstr(app->file_path), app->file_name_tmp); - avr_isp_reader_view_set_callback(app->avr_isp_reader_view, avr_isp_scene_reader_callback, app); - - view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewReader); -} - -bool avr_isp_scene_reader_on_event(void* context, SceneManagerEvent event) { - furi_assert(context); - - AvrIspApp* app = context; - UNUSED(app); - bool consumed = false; - if(event.type == SceneManagerEventTypeBack) { - //do not handle exit on "Back" - consumed = true; - } else if(event.type == SceneManagerEventTypeCustom) { - switch(event.event) { - case AvrIspCustomEventSceneReadingOk: - scene_manager_next_scene(app->scene_manager, AvrIspSceneSuccess); - consumed = true; - break; - case AvrIspCustomEventSceneExit: - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, AvrIspSceneChipDetect); - consumed = true; - break; - case AvrIspCustomEventSceneErrorVerification: - app->error = AvrIspErrorVerification; - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, AvrIspSceneChipDetect); - consumed = true; - break; - case AvrIspCustomEventSceneErrorReading: - app->error = AvrIspErrorReading; - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, AvrIspSceneChipDetect); - consumed = true; - break; - default: - break; - } - } else if(event.type == SceneManagerEventTypeTick) { - avr_isp_reader_update_progress(app->avr_isp_reader_view); - } - return consumed; -} - -void avr_isp_scene_reader_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_start.c b/applications/external/avr_isp_programmer/scenes/avr_isp_scene_start.c deleted file mode 100644 index b00bfefce..000000000 --- a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_start.c +++ /dev/null @@ -1,75 +0,0 @@ -#include "../avr_isp_app_i.h" - -void avr_isp_scene_start_submenu_callback(void* context, uint32_t index) { - furi_assert(context); - AvrIspApp* app = context; - - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void avr_isp_scene_start_on_enter(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - Submenu* submenu = app->submenu; - submenu_add_item( - submenu, "Dump AVR", SubmenuIndexAvrIspReader, avr_isp_scene_start_submenu_callback, app); - submenu_add_item( - submenu, "Flash AVR", SubmenuIndexAvrIspWriter, avr_isp_scene_start_submenu_callback, app); - submenu_add_item( - submenu, - "ISP Programmer", - SubmenuIndexAvrIspProgrammer, - avr_isp_scene_start_submenu_callback, - app); - submenu_add_item( - submenu, "Wiring", SubmenuIndexAvrIsWiring, avr_isp_scene_start_submenu_callback, app); - submenu_add_item( - submenu, "About", SubmenuIndexAvrIspAbout, avr_isp_scene_start_submenu_callback, app); - - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(app->scene_manager, AvrIspSceneStart)); - - view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewSubmenu); -} - -bool avr_isp_scene_start_on_event(void* context, SceneManagerEvent event) { - furi_assert(context); - - AvrIspApp* app = context; - bool consumed = false; - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexAvrIspAbout) { - scene_manager_next_scene(app->scene_manager, AvrIspSceneAbout); - consumed = true; - } else if(event.event == SubmenuIndexAvrIspProgrammer) { - scene_manager_set_scene_state( - app->scene_manager, AvrIspSceneChipDetect, AvrIspViewProgrammer); - scene_manager_next_scene(app->scene_manager, AvrIspSceneChipDetect); - consumed = true; - } else if(event.event == SubmenuIndexAvrIspReader) { - scene_manager_set_scene_state( - app->scene_manager, AvrIspSceneChipDetect, AvrIspViewReader); - scene_manager_next_scene(app->scene_manager, AvrIspSceneChipDetect); - consumed = true; - } else if(event.event == SubmenuIndexAvrIspWriter) { - scene_manager_set_scene_state( - app->scene_manager, AvrIspSceneChipDetect, AvrIspViewWriter); - scene_manager_next_scene(app->scene_manager, AvrIspSceneChipDetect); - consumed = true; - } else if(event.event == SubmenuIndexAvrIsWiring) { - scene_manager_next_scene(app->scene_manager, AvrIspSceneWiring); - consumed = true; - } - scene_manager_set_scene_state(app->scene_manager, AvrIspSceneStart, event.event); - } - - return consumed; -} - -void avr_isp_scene_start_on_exit(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_success.c b/applications/external/avr_isp_programmer/scenes/avr_isp_scene_success.c deleted file mode 100644 index a88ed28aa..000000000 --- a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_success.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "../avr_isp_app_i.h" - -void avr_isp_scene_success_popup_callback(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, AvrIspCustomEventSceneSuccess); -} - -void avr_isp_scene_success_on_enter(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - Popup* popup = app->popup; - popup_set_icon(popup, 32, 5, &I_dolphin_nice_96x59); - popup_set_header(popup, "Success!", 8, 22, AlignLeft, AlignBottom); - popup_set_timeout(popup, 1500); - popup_set_context(popup, app); - popup_set_callback(popup, avr_isp_scene_success_popup_callback); - popup_enable_timeout(popup); - view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewPopup); -} - -bool avr_isp_scene_success_on_event(void* context, SceneManagerEvent event) { - furi_assert(context); - - AvrIspApp* app = context; - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == AvrIspCustomEventSceneSuccess) { - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, AvrIspSceneStart); - return true; - } - } - return false; -} - -void avr_isp_scene_success_on_exit(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - Popup* popup = app->popup; - popup_reset(popup); -} diff --git a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_wiring.c b/applications/external/avr_isp_programmer/scenes/avr_isp_scene_wiring.c deleted file mode 100644 index 787ed5673..000000000 --- a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_wiring.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../avr_isp_app_i.h" - -void avr_isp_scene_wiring_on_enter(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - widget_add_icon_element(app->widget, 0, 0, &I_avr_wiring); - view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewWidget); -} - -bool avr_isp_scene_wiring_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} -void avr_isp_scene_wiring_on_exit(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - widget_reset(app->widget); -} diff --git a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_writer.c b/applications/external/avr_isp_programmer/scenes/avr_isp_scene_writer.c deleted file mode 100644 index 39c944fd5..000000000 --- a/applications/external/avr_isp_programmer/scenes/avr_isp_scene_writer.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "../avr_isp_app_i.h" - -void avr_isp_scene_writer_callback(AvrIspCustomEvent event, void* context) { - furi_assert(context); - - AvrIspApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -void avr_isp_scene_writer_on_enter(void* context) { - furi_assert(context); - - AvrIspApp* app = context; - avr_isp_writer_set_file_path( - app->avr_isp_writer_view, furi_string_get_cstr(app->file_path), app->file_name_tmp); - avr_isp_writer_view_set_callback(app->avr_isp_writer_view, avr_isp_scene_writer_callback, app); - view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewWriter); -} - -bool avr_isp_scene_writer_on_event(void* context, SceneManagerEvent event) { - furi_assert(context); - - AvrIspApp* app = context; - bool consumed = false; - if(event.type == SceneManagerEventTypeBack) { - //do not handle exit on "Back" - consumed = true; - } else if(event.type == SceneManagerEventTypeCustom) { - switch(event.event) { - case AvrIspCustomEventSceneExitStartMenu: - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, AvrIspSceneStart); - consumed = true; - break; - case AvrIspCustomEventSceneExit: - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, AvrIspSceneChipDetect); - consumed = true; - break; - case AvrIspCustomEventSceneErrorVerification: - app->error = AvrIspErrorVerification; - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, AvrIspSceneChipDetect); - consumed = true; - break; - case AvrIspCustomEventSceneErrorWriting: - app->error = AvrIspErrorWriting; - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, AvrIspSceneChipDetect); - consumed = true; - break; - case AvrIspCustomEventSceneErrorWritingFuse: - app->error = AvrIspErrorWritingFuse; - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, AvrIspSceneChipDetect); - consumed = true; - break; - default: - break; - } - } else if(event.type == SceneManagerEventTypeTick) { - avr_isp_writer_update_progress(app->avr_isp_writer_view); - } - return consumed; -} - -void avr_isp_scene_writer_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/avr_isp_programmer/views/avr_isp_view_chip_detect.c b/applications/external/avr_isp_programmer/views/avr_isp_view_chip_detect.c deleted file mode 100644 index fdcf71c36..000000000 --- a/applications/external/avr_isp_programmer/views/avr_isp_view_chip_detect.c +++ /dev/null @@ -1,213 +0,0 @@ -#include "avr_isp_view_chip_detect.h" -#include -#include - -#include "../helpers/avr_isp_worker_rw.h" - -struct AvrIspChipDetectView { - View* view; - AvrIspWorkerRW* avr_isp_worker_rw; - AvrIspChipDetectViewCallback callback; - void* context; -}; - -typedef struct { - uint16_t idx; - const char* name_chip; - uint32_t flash_size; - AvrIspChipDetectViewState state; -} AvrIspChipDetectViewModel; - -void avr_isp_chip_detect_view_set_callback( - AvrIspChipDetectView* instance, - AvrIspChipDetectViewCallback callback, - void* context) { - furi_assert(instance); - furi_assert(callback); - - instance->callback = callback; - instance->context = context; -} - -void avr_isp_chip_detect_set_state(AvrIspChipDetectView* instance, AvrIspChipDetectViewState state) { - furi_assert(instance); - - with_view_model( - instance->view, AvrIspChipDetectViewModel * model, { model->state = state; }, true); -} - -void avr_isp_chip_detect_view_draw(Canvas* canvas, AvrIspChipDetectViewModel* model) { - canvas_clear(canvas); - - char str_buf[64] = {0}; - canvas_set_font(canvas, FontPrimary); - - switch(model->state) { - case AvrIspChipDetectViewStateDetected: - canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "AVR chip detected!"); - canvas_draw_icon(canvas, 29, 14, &I_chip_long_70x22); - canvas_set_font(canvas, FontSecondary); - snprintf(str_buf, sizeof(str_buf), "%ld Kb", model->flash_size / 1024); - canvas_draw_str_aligned(canvas, 64, 25, AlignCenter, AlignCenter, str_buf); - canvas_draw_str_aligned(canvas, 64, 45, AlignCenter, AlignCenter, model->name_chip); - elements_button_right(canvas, "Next"); - break; - case AvrIspChipDetectViewStateErrorOccured: - canvas_draw_str_aligned( - canvas, 64, 5, AlignCenter, AlignCenter, "Error occured, try again!"); - canvas_draw_icon(canvas, 29, 14, &I_chip_error_70x22); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, 64, 45, AlignCenter, AlignCenter, "Check the wiring and retry"); - break; - case AvrIspChipDetectViewStateErrorVerification: - canvas_draw_str_aligned( - canvas, 64, 5, AlignCenter, AlignCenter, "Data verification failed"); - canvas_draw_icon(canvas, 29, 14, &I_chip_error_70x22); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, 64, 45, AlignCenter, AlignCenter, "Try to restart the process"); - break; - - default: - //AvrIspChipDetectViewStateNoDetect - canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "AVR chip not found!"); - canvas_draw_icon(canvas, 29, 12, &I_chif_not_found_83x37); - - break; - } - canvas_set_font(canvas, FontSecondary); - elements_button_left(canvas, "Retry"); -} - -bool avr_isp_chip_detect_view_input(InputEvent* event, void* context) { - furi_assert(context); - - AvrIspChipDetectView* instance = context; - - if(event->type == InputTypeShort) { - if(event->key == InputKeyBack) { - return false; - } else if(event->key == InputKeyRight) { - with_view_model( - instance->view, - AvrIspChipDetectViewModel * model, - { - if(model->state == AvrIspChipDetectViewStateDetected) { - if(instance->callback) - instance->callback( - AvrIspCustomEventSceneChipDetectOk, instance->context); - } - }, - false); - - } else if(event->key == InputKeyLeft) { - bool detect_chip = false; - with_view_model( - instance->view, - AvrIspChipDetectViewModel * model, - { - if(model->state != AvrIspChipDetectViewStateDetecting) { - model->state = AvrIspChipDetectViewStateDetecting; - detect_chip = true; - } - }, - false); - if(detect_chip) avr_isp_worker_rw_detect_chip(instance->avr_isp_worker_rw); - } - } else { - return false; - } - - return true; -} - -static void avr_isp_chip_detect_detect_chip_callback( - void* context, - const char* name, - bool detect_chip, - uint32_t flash_size) { - furi_assert(context); - - AvrIspChipDetectView* instance = context; - with_view_model( - instance->view, - AvrIspChipDetectViewModel * model, - { - model->name_chip = name; - model->flash_size = flash_size; - if(detect_chip) { - model->state = AvrIspChipDetectViewStateDetected; - } else { - model->state = AvrIspChipDetectViewStateNoDetect; - } - }, - true); -} -void avr_isp_chip_detect_view_enter(void* context) { - furi_assert(context); - - AvrIspChipDetectView* instance = context; - bool detect_chip = false; - with_view_model( - instance->view, - AvrIspChipDetectViewModel * model, - { - if(model->state == AvrIspChipDetectViewStateNoDetect || - model->state == AvrIspChipDetectViewStateDetected) { - detect_chip = true; - } - }, - false); - - //Start avr_isp_worker_rw - instance->avr_isp_worker_rw = avr_isp_worker_rw_alloc(instance->context); - - avr_isp_worker_rw_set_callback( - instance->avr_isp_worker_rw, avr_isp_chip_detect_detect_chip_callback, instance); - - if(detect_chip) avr_isp_worker_rw_detect_chip(instance->avr_isp_worker_rw); -} - -void avr_isp_chip_detect_view_exit(void* context) { - furi_assert(context); - - AvrIspChipDetectView* instance = context; - - avr_isp_worker_rw_set_callback(instance->avr_isp_worker_rw, NULL, NULL); - avr_isp_worker_rw_free(instance->avr_isp_worker_rw); -} - -AvrIspChipDetectView* avr_isp_chip_detect_view_alloc() { - AvrIspChipDetectView* instance = malloc(sizeof(AvrIspChipDetectView)); - - // View allocation and configuration - instance->view = view_alloc(); - - view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(AvrIspChipDetectViewModel)); - view_set_context(instance->view, instance); - view_set_draw_callback(instance->view, (ViewDrawCallback)avr_isp_chip_detect_view_draw); - view_set_input_callback(instance->view, avr_isp_chip_detect_view_input); - view_set_enter_callback(instance->view, avr_isp_chip_detect_view_enter); - view_set_exit_callback(instance->view, avr_isp_chip_detect_view_exit); - - with_view_model( - instance->view, - AvrIspChipDetectViewModel * model, - { model->state = AvrIspChipDetectViewStateNoDetect; }, - false); - return instance; -} - -void avr_isp_chip_detect_view_free(AvrIspChipDetectView* instance) { - furi_assert(instance); - - view_free(instance->view); - free(instance); -} - -View* avr_isp_chip_detect_view_get_view(AvrIspChipDetectView* instance) { - furi_assert(instance); - - return instance->view; -} diff --git a/applications/external/avr_isp_programmer/views/avr_isp_view_chip_detect.h b/applications/external/avr_isp_programmer/views/avr_isp_view_chip_detect.h deleted file mode 100644 index 37f2ae233..000000000 --- a/applications/external/avr_isp_programmer/views/avr_isp_view_chip_detect.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include -#include "../helpers/avr_isp_types.h" -#include "../helpers/avr_isp_event.h" - -typedef struct AvrIspChipDetectView AvrIspChipDetectView; - -typedef void (*AvrIspChipDetectViewCallback)(AvrIspCustomEvent event, void* context); - -typedef enum { - AvrIspChipDetectViewStateNoDetect, - AvrIspChipDetectViewStateDetecting, - AvrIspChipDetectViewStateDetected, - AvrIspChipDetectViewStateErrorOccured, - AvrIspChipDetectViewStateErrorVerification, -} AvrIspChipDetectViewState; - -void avr_isp_chip_detect_view_set_callback( - AvrIspChipDetectView* instance, - AvrIspChipDetectViewCallback callback, - void* context); - -void avr_isp_chip_detect_set_state(AvrIspChipDetectView* instance, AvrIspChipDetectViewState state); - -AvrIspChipDetectView* avr_isp_chip_detect_view_alloc(); - -void avr_isp_chip_detect_view_free(AvrIspChipDetectView* instance); - -View* avr_isp_chip_detect_view_get_view(AvrIspChipDetectView* instance); - -void avr_isp_chip_detect_view_exit(void* context); diff --git a/applications/external/avr_isp_programmer/views/avr_isp_view_programmer.c b/applications/external/avr_isp_programmer/views/avr_isp_view_programmer.c deleted file mode 100644 index 34e18770b..000000000 --- a/applications/external/avr_isp_programmer/views/avr_isp_view_programmer.c +++ /dev/null @@ -1,134 +0,0 @@ -#include "avr_isp_view_programmer.h" -#include - -#include "../helpers/avr_isp_worker.h" -#include - -struct AvrIspProgrammerView { - View* view; - AvrIspWorker* worker; - AvrIspProgrammerViewCallback callback; - void* context; -}; - -typedef struct { - AvrIspProgrammerViewStatus status; -} AvrIspProgrammerViewModel; - -void avr_isp_programmer_view_set_callback( - AvrIspProgrammerView* instance, - AvrIspProgrammerViewCallback callback, - void* context) { - furi_assert(instance); - furi_assert(callback); - - instance->callback = callback; - instance->context = context; -} - -void avr_isp_programmer_view_draw(Canvas* canvas, AvrIspProgrammerViewModel* model) { - canvas_clear(canvas); - - if(model->status == AvrIspProgrammerViewStatusUSBConnect) { - canvas_set_font(canvas, FontPrimary); - canvas_draw_icon(canvas, 0, 0, &I_isp_active_128x53); - elements_multiline_text(canvas, 45, 10, "ISP mode active"); - } else { - canvas_set_font(canvas, FontSecondary); - canvas_draw_icon(canvas, 51, 6, &I_link_waiting_77x56); - elements_multiline_text(canvas, 0, 25, "Waiting for\nsoftware\nconnection"); - } -} - -bool avr_isp_programmer_view_input(InputEvent* event, void* context) { - furi_assert(context); - UNUSED(context); - - if(event->key == InputKeyBack || event->type != InputTypeShort) { - return false; - } - - return true; -} - -static void avr_isp_programmer_usb_connect_callback(void* context, bool status_connect) { - furi_assert(context); - AvrIspProgrammerView* instance = context; - - with_view_model( - instance->view, - AvrIspProgrammerViewModel * model, - { - if(status_connect) { - model->status = AvrIspProgrammerViewStatusUSBConnect; - } else { - model->status = AvrIspProgrammerViewStatusNoUSBConnect; - } - }, - true); -} - -void avr_isp_programmer_view_enter(void* context) { - furi_assert(context); - - AvrIspProgrammerView* instance = context; - with_view_model( - instance->view, - AvrIspProgrammerViewModel * model, - { model->status = AvrIspProgrammerViewStatusNoUSBConnect; }, - true); - - //Start worker - instance->worker = avr_isp_worker_alloc(instance->context); - - avr_isp_worker_set_callback( - instance->worker, avr_isp_programmer_usb_connect_callback, instance); - - avr_isp_worker_start(instance->worker); -} - -void avr_isp_programmer_view_exit(void* context) { - furi_assert(context); - - AvrIspProgrammerView* instance = context; - //Stop worker - if(avr_isp_worker_is_running(instance->worker)) { - avr_isp_worker_stop(instance->worker); - } - avr_isp_worker_set_callback(instance->worker, NULL, NULL); - avr_isp_worker_free(instance->worker); -} - -AvrIspProgrammerView* avr_isp_programmer_view_alloc() { - AvrIspProgrammerView* instance = malloc(sizeof(AvrIspProgrammerView)); - - // View allocation and configuration - instance->view = view_alloc(); - - view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(AvrIspProgrammerViewModel)); - view_set_context(instance->view, instance); - view_set_draw_callback(instance->view, (ViewDrawCallback)avr_isp_programmer_view_draw); - view_set_input_callback(instance->view, avr_isp_programmer_view_input); - view_set_enter_callback(instance->view, avr_isp_programmer_view_enter); - view_set_exit_callback(instance->view, avr_isp_programmer_view_exit); - - with_view_model( - instance->view, - AvrIspProgrammerViewModel * model, - { model->status = AvrIspProgrammerViewStatusNoUSBConnect; }, - false); - return instance; -} - -void avr_isp_programmer_view_free(AvrIspProgrammerView* instance) { - furi_assert(instance); - - view_free(instance->view); - free(instance); -} - -View* avr_isp_programmer_view_get_view(AvrIspProgrammerView* instance) { - furi_assert(instance); - - return instance->view; -} diff --git a/applications/external/avr_isp_programmer/views/avr_isp_view_programmer.h b/applications/external/avr_isp_programmer/views/avr_isp_view_programmer.h deleted file mode 100644 index 9f005b026..000000000 --- a/applications/external/avr_isp_programmer/views/avr_isp_view_programmer.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include -#include "../helpers/avr_isp_types.h" -#include "../helpers/avr_isp_event.h" - -typedef struct AvrIspProgrammerView AvrIspProgrammerView; - -typedef void (*AvrIspProgrammerViewCallback)(AvrIspCustomEvent event, void* context); - -typedef enum { - AvrIspProgrammerViewStatusNoUSBConnect, - AvrIspProgrammerViewStatusUSBConnect, -} AvrIspProgrammerViewStatus; - -void avr_isp_programmer_view_set_callback( - AvrIspProgrammerView* instance, - AvrIspProgrammerViewCallback callback, - void* context); - -AvrIspProgrammerView* avr_isp_programmer_view_alloc(); - -void avr_isp_programmer_view_free(AvrIspProgrammerView* instance); - -View* avr_isp_programmer_view_get_view(AvrIspProgrammerView* instance); - -void avr_isp_programmer_view_exit(void* context); diff --git a/applications/external/avr_isp_programmer/views/avr_isp_view_reader.c b/applications/external/avr_isp_programmer/views/avr_isp_view_reader.c deleted file mode 100644 index 92d15bd7f..000000000 --- a/applications/external/avr_isp_programmer/views/avr_isp_view_reader.c +++ /dev/null @@ -1,215 +0,0 @@ -#include "avr_isp_view_reader.h" -#include - -#include "../helpers/avr_isp_worker_rw.h" - -struct AvrIspReaderView { - View* view; - AvrIspWorkerRW* avr_isp_worker_rw; - const char* file_path; - const char* file_name; - AvrIspReaderViewCallback callback; - void* context; -}; - -typedef struct { - AvrIspReaderViewStatus status; - float progress_flash; - float progress_eeprom; -} AvrIspReaderViewModel; - -void avr_isp_reader_update_progress(AvrIspReaderView* instance) { - with_view_model( - instance->view, - AvrIspReaderViewModel * model, - { - model->progress_flash = - avr_isp_worker_rw_get_progress_flash(instance->avr_isp_worker_rw); - model->progress_eeprom = - avr_isp_worker_rw_get_progress_eeprom(instance->avr_isp_worker_rw); - }, - true); -} - -void avr_isp_reader_view_set_callback( - AvrIspReaderView* instance, - AvrIspReaderViewCallback callback, - void* context) { - furi_assert(instance); - furi_assert(callback); - - instance->callback = callback; - instance->context = context; -} - -void avr_isp_reader_set_file_path( - AvrIspReaderView* instance, - const char* file_path, - const char* file_name) { - furi_assert(instance); - - instance->file_path = file_path; - instance->file_name = file_name; -} - -void avr_isp_reader_view_draw(Canvas* canvas, AvrIspReaderViewModel* model) { - canvas_clear(canvas); - char str_buf[64] = {0}; - - canvas_set_font(canvas, FontPrimary); - switch(model->status) { - case AvrIspReaderViewStatusIDLE: - canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Press start to dump"); - canvas_set_font(canvas, FontSecondary); - elements_button_center(canvas, "Start"); - break; - case AvrIspReaderViewStatusReading: - canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Reading dump"); - break; - case AvrIspReaderViewStatusVerification: - canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Verifyng dump"); - break; - - default: - break; - } - - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 0, 27, "Flash"); - snprintf(str_buf, sizeof(str_buf), "%d%%", (uint8_t)(model->progress_flash * 100)); - elements_progress_bar_with_text(canvas, 44, 17, 84, model->progress_flash, str_buf); - canvas_draw_str(canvas, 0, 43, "EEPROM"); - snprintf(str_buf, sizeof(str_buf), "%d%%", (uint8_t)(model->progress_eeprom * 100)); - elements_progress_bar_with_text(canvas, 44, 34, 84, model->progress_eeprom, str_buf); -} - -bool avr_isp_reader_view_input(InputEvent* event, void* context) { - furi_assert(context); - AvrIspReaderView* instance = context; - - bool ret = true; - if(event->key == InputKeyBack && event->type == InputTypeShort) { - with_view_model( - instance->view, - AvrIspReaderViewModel * model, - { - if(model->status == AvrIspReaderViewStatusIDLE) { - if(instance->callback) - instance->callback(AvrIspCustomEventSceneExit, instance->context); - ret = false; - } - }, - false); - } else if(event->key == InputKeyOk && event->type == InputTypeShort) { - with_view_model( - instance->view, - AvrIspReaderViewModel * model, - { - if(model->status == AvrIspReaderViewStatusIDLE) { - model->status = AvrIspReaderViewStatusReading; - avr_isp_worker_rw_read_dump_start( - instance->avr_isp_worker_rw, instance->file_path, instance->file_name); - } - }, - false); - } - return ret; -} - -static void avr_isp_reader_callback_status(void* context, AvrIspWorkerRWStatus status) { - furi_assert(context); - AvrIspReaderView* instance = context; - - with_view_model( - instance->view, - AvrIspReaderViewModel * model, - { - switch(status) { - case AvrIspWorkerRWStatusEndReading: - model->status = AvrIspReaderViewStatusVerification; - avr_isp_worker_rw_verification_start( - instance->avr_isp_worker_rw, instance->file_path, instance->file_name); - model->status = AvrIspReaderViewStatusVerification; - break; - case AvrIspWorkerRWStatusEndVerification: - if(instance->callback) - instance->callback(AvrIspCustomEventSceneReadingOk, instance->context); - break; - case AvrIspWorkerRWStatusErrorVerification: - if(instance->callback) - instance->callback(AvrIspCustomEventSceneErrorVerification, instance->context); - break; - - default: - //AvrIspWorkerRWStatusErrorReading; - if(instance->callback) - instance->callback(AvrIspCustomEventSceneErrorReading, instance->context); - break; - } - }, - true); -} - -void avr_isp_reader_view_enter(void* context) { - furi_assert(context); - AvrIspReaderView* instance = context; - - with_view_model( - instance->view, - AvrIspReaderViewModel * model, - { - model->status = AvrIspReaderViewStatusIDLE; - model->progress_flash = 0.0f; - model->progress_eeprom = 0.0f; - }, - true); - - //Start avr_isp_worker_rw - instance->avr_isp_worker_rw = avr_isp_worker_rw_alloc(instance->context); - - avr_isp_worker_rw_set_callback_status( - instance->avr_isp_worker_rw, avr_isp_reader_callback_status, instance); - - avr_isp_worker_rw_start(instance->avr_isp_worker_rw); -} - -void avr_isp_reader_view_exit(void* context) { - furi_assert(context); - - AvrIspReaderView* instance = context; - //Stop avr_isp_worker_rw - if(avr_isp_worker_rw_is_running(instance->avr_isp_worker_rw)) { - avr_isp_worker_rw_stop(instance->avr_isp_worker_rw); - } - - avr_isp_worker_rw_free(instance->avr_isp_worker_rw); -} - -AvrIspReaderView* avr_isp_reader_view_alloc() { - AvrIspReaderView* instance = malloc(sizeof(AvrIspReaderView)); - - // View allocation and configuration - instance->view = view_alloc(); - - view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(AvrIspReaderViewModel)); - view_set_context(instance->view, instance); - view_set_draw_callback(instance->view, (ViewDrawCallback)avr_isp_reader_view_draw); - view_set_input_callback(instance->view, avr_isp_reader_view_input); - view_set_enter_callback(instance->view, avr_isp_reader_view_enter); - view_set_exit_callback(instance->view, avr_isp_reader_view_exit); - - return instance; -} - -void avr_isp_reader_view_free(AvrIspReaderView* instance) { - furi_assert(instance); - - view_free(instance->view); - free(instance); -} - -View* avr_isp_reader_view_get_view(AvrIspReaderView* instance) { - furi_assert(instance); - - return instance->view; -} diff --git a/applications/external/avr_isp_programmer/views/avr_isp_view_reader.h b/applications/external/avr_isp_programmer/views/avr_isp_view_reader.h deleted file mode 100644 index 44a439948..000000000 --- a/applications/external/avr_isp_programmer/views/avr_isp_view_reader.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include -#include "../helpers/avr_isp_types.h" -#include "../helpers/avr_isp_event.h" - -typedef struct AvrIspReaderView AvrIspReaderView; - -typedef void (*AvrIspReaderViewCallback)(AvrIspCustomEvent event, void* context); - -typedef enum { - AvrIspReaderViewStatusIDLE, - AvrIspReaderViewStatusReading, - AvrIspReaderViewStatusVerification, -} AvrIspReaderViewStatus; - -void avr_isp_reader_update_progress(AvrIspReaderView* instance); - -void avr_isp_reader_set_file_path( - AvrIspReaderView* instance, - const char* file_path, - const char* file_name); - -void avr_isp_reader_view_set_callback( - AvrIspReaderView* instance, - AvrIspReaderViewCallback callback, - void* context); - -AvrIspReaderView* avr_isp_reader_view_alloc(); - -void avr_isp_reader_view_free(AvrIspReaderView* instance); - -View* avr_isp_reader_view_get_view(AvrIspReaderView* instance); - -void avr_isp_reader_view_exit(void* context); diff --git a/applications/external/avr_isp_programmer/views/avr_isp_view_writer.c b/applications/external/avr_isp_programmer/views/avr_isp_view_writer.c deleted file mode 100644 index a06b78535..000000000 --- a/applications/external/avr_isp_programmer/views/avr_isp_view_writer.c +++ /dev/null @@ -1,268 +0,0 @@ -#include "avr_isp_view_writer.h" -#include - -#include "../helpers/avr_isp_worker_rw.h" -#include - -struct AvrIspWriterView { - View* view; - AvrIspWorkerRW* avr_isp_worker_rw; - const char* file_path; - const char* file_name; - AvrIspWriterViewCallback callback; - void* context; -}; - -typedef struct { - AvrIspWriterViewStatus status; - float progress_flash; - float progress_eeprom; -} AvrIspWriterViewModel; - -void avr_isp_writer_update_progress(AvrIspWriterView* instance) { - with_view_model( - instance->view, - AvrIspWriterViewModel * model, - { - model->progress_flash = - avr_isp_worker_rw_get_progress_flash(instance->avr_isp_worker_rw); - model->progress_eeprom = - avr_isp_worker_rw_get_progress_eeprom(instance->avr_isp_worker_rw); - }, - true); -} - -void avr_isp_writer_view_set_callback( - AvrIspWriterView* instance, - AvrIspWriterViewCallback callback, - void* context) { - furi_assert(instance); - furi_assert(callback); - - instance->callback = callback; - instance->context = context; -} - -void avr_isp_writer_set_file_path( - AvrIspWriterView* instance, - const char* file_path, - const char* file_name) { - furi_assert(instance); - - instance->file_path = file_path; - instance->file_name = file_name; -} - -void avr_isp_writer_view_draw(Canvas* canvas, AvrIspWriterViewModel* model) { - canvas_clear(canvas); - char str_flash[32] = {0}; - char str_eeprom[32] = {0}; - - canvas_set_font(canvas, FontPrimary); - - switch(model->status) { - case AvrIspWriterViewStatusIDLE: - canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Press start to write"); - canvas_set_font(canvas, FontSecondary); - elements_button_center(canvas, "Start"); - snprintf(str_flash, sizeof(str_flash), "%d%%", (uint8_t)(model->progress_flash * 100)); - snprintf(str_eeprom, sizeof(str_eeprom), "%d%%", (uint8_t)(model->progress_eeprom * 100)); - break; - case AvrIspWriterViewStatusWriting: - if(float_is_equal(model->progress_flash, 0.f)) { - canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Verifying firmware"); - snprintf(str_flash, sizeof(str_flash), "***"); - snprintf(str_eeprom, sizeof(str_eeprom), "***"); - } else { - canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Writing dump"); - snprintf(str_flash, sizeof(str_flash), "%d%%", (uint8_t)(model->progress_flash * 100)); - snprintf( - str_eeprom, sizeof(str_eeprom), "%d%%", (uint8_t)(model->progress_eeprom * 100)); - } - break; - case AvrIspWriterViewStatusVerification: - canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Verifying dump"); - snprintf(str_flash, sizeof(str_flash), "%d%%", (uint8_t)(model->progress_flash * 100)); - snprintf(str_eeprom, sizeof(str_eeprom), "%d%%", (uint8_t)(model->progress_eeprom * 100)); - break; - case AvrIspWriterViewStatusWritingFuse: - canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Writing fuse"); - snprintf(str_flash, sizeof(str_flash), "%d%%", (uint8_t)(model->progress_flash * 100)); - snprintf(str_eeprom, sizeof(str_eeprom), "%d%%", (uint8_t)(model->progress_eeprom * 100)); - break; - case AvrIspWriterViewStatusWritingFuseOk: - canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Done!"); - snprintf(str_flash, sizeof(str_flash), "%d%%", (uint8_t)(model->progress_flash * 100)); - snprintf(str_eeprom, sizeof(str_eeprom), "%d%%", (uint8_t)(model->progress_eeprom * 100)); - canvas_set_font(canvas, FontSecondary); - elements_button_center(canvas, "Reflash"); - elements_button_right(canvas, "Exit"); - break; - - default: - break; - } - - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 0, 27, "Flash"); - // snprintf(str_buf, sizeof(str_buf), "%d%%", (uint8_t)(model->progress_flash * 100)); - elements_progress_bar_with_text(canvas, 44, 17, 84, model->progress_flash, str_flash); - canvas_draw_str(canvas, 0, 43, "EEPROM"); - // snprintf(str_buf, sizeof(str_buf), "%d%%", (uint8_t)(model->progress_eeprom * 100)); - elements_progress_bar_with_text(canvas, 44, 34, 84, model->progress_eeprom, str_eeprom); -} - -bool avr_isp_writer_view_input(InputEvent* event, void* context) { - furi_assert(context); - AvrIspWriterView* instance = context; - - bool ret = true; - if(event->key == InputKeyBack && event->type == InputTypeShort) { - with_view_model( - instance->view, - AvrIspWriterViewModel * model, - { - if((model->status == AvrIspWriterViewStatusIDLE) || - (model->status == AvrIspWriterViewStatusWritingFuseOk)) { - if(instance->callback) - instance->callback(AvrIspCustomEventSceneExit, instance->context); - ret = false; - } - }, - false); - } else if(event->key == InputKeyOk && event->type == InputTypeShort) { - with_view_model( - instance->view, - AvrIspWriterViewModel * model, - { - if((model->status == AvrIspWriterViewStatusIDLE) || - (model->status == AvrIspWriterViewStatusWritingFuseOk)) { - model->status = AvrIspWriterViewStatusWriting; - - avr_isp_worker_rw_write_dump_start( - instance->avr_isp_worker_rw, instance->file_path, instance->file_name); - } - }, - false); - } else if(event->key == InputKeyRight && event->type == InputTypeShort) { - with_view_model( - instance->view, - AvrIspWriterViewModel * model, - { - if((model->status == AvrIspWriterViewStatusIDLE) || - (model->status == AvrIspWriterViewStatusWritingFuseOk)) { - if(instance->callback) - instance->callback(AvrIspCustomEventSceneExitStartMenu, instance->context); - ret = false; - } - }, - false); - } - return ret; -} - -static void avr_isp_writer_callback_status(void* context, AvrIspWorkerRWStatus status) { - furi_assert(context); - - AvrIspWriterView* instance = context; - with_view_model( - instance->view, - AvrIspWriterViewModel * model, - { - switch(status) { - case AvrIspWorkerRWStatusEndWriting: - model->status = AvrIspWriterViewStatusVerification; - avr_isp_worker_rw_verification_start( - instance->avr_isp_worker_rw, instance->file_path, instance->file_name); - model->status = AvrIspWriterViewStatusVerification; - break; - case AvrIspWorkerRWStatusErrorVerification: - if(instance->callback) - instance->callback(AvrIspCustomEventSceneErrorVerification, instance->context); - break; - case AvrIspWorkerRWStatusEndVerification: - avr_isp_worker_rw_write_fuse_start( - instance->avr_isp_worker_rw, instance->file_path, instance->file_name); - model->status = AvrIspWriterViewStatusWritingFuse; - break; - case AvrIspWorkerRWStatusErrorWritingFuse: - if(instance->callback) - instance->callback(AvrIspCustomEventSceneErrorWritingFuse, instance->context); - break; - case AvrIspWorkerRWStatusEndWritingFuse: - model->status = AvrIspWriterViewStatusWritingFuseOk; - break; - - default: - //AvrIspWorkerRWStatusErrorWriting; - if(instance->callback) - instance->callback(AvrIspCustomEventSceneErrorWriting, instance->context); - break; - } - }, - true); -} - -void avr_isp_writer_view_enter(void* context) { - furi_assert(context); - - AvrIspWriterView* instance = context; - with_view_model( - instance->view, - AvrIspWriterViewModel * model, - { - model->status = AvrIspWriterViewStatusIDLE; - model->progress_flash = 0.0f; - model->progress_eeprom = 0.0f; - }, - true); - - //Start avr_isp_worker_rw - instance->avr_isp_worker_rw = avr_isp_worker_rw_alloc(instance->context); - - avr_isp_worker_rw_set_callback_status( - instance->avr_isp_worker_rw, avr_isp_writer_callback_status, instance); - - avr_isp_worker_rw_start(instance->avr_isp_worker_rw); -} - -void avr_isp_writer_view_exit(void* context) { - furi_assert(context); - AvrIspWriterView* instance = context; - - //Stop avr_isp_worker_rw - if(avr_isp_worker_rw_is_running(instance->avr_isp_worker_rw)) { - avr_isp_worker_rw_stop(instance->avr_isp_worker_rw); - } - - avr_isp_worker_rw_free(instance->avr_isp_worker_rw); -} - -AvrIspWriterView* avr_isp_writer_view_alloc() { - AvrIspWriterView* instance = malloc(sizeof(AvrIspWriterView)); - - // View allocation and configuration - instance->view = view_alloc(); - - view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(AvrIspWriterViewModel)); - view_set_context(instance->view, instance); - view_set_draw_callback(instance->view, (ViewDrawCallback)avr_isp_writer_view_draw); - view_set_input_callback(instance->view, avr_isp_writer_view_input); - view_set_enter_callback(instance->view, avr_isp_writer_view_enter); - view_set_exit_callback(instance->view, avr_isp_writer_view_exit); - - return instance; -} - -void avr_isp_writer_view_free(AvrIspWriterView* instance) { - furi_assert(instance); - - view_free(instance->view); - free(instance); -} - -View* avr_isp_writer_view_get_view(AvrIspWriterView* instance) { - furi_assert(instance); - - return instance->view; -} diff --git a/applications/external/avr_isp_programmer/views/avr_isp_view_writer.h b/applications/external/avr_isp_programmer/views/avr_isp_view_writer.h deleted file mode 100644 index 1ff728387..000000000 --- a/applications/external/avr_isp_programmer/views/avr_isp_view_writer.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include "../helpers/avr_isp_types.h" -#include "../helpers/avr_isp_event.h" - -typedef struct AvrIspWriterView AvrIspWriterView; - -typedef void (*AvrIspWriterViewCallback)(AvrIspCustomEvent event, void* context); - -typedef enum { - AvrIspWriterViewStatusIDLE, - AvrIspWriterViewStatusWriting, - AvrIspWriterViewStatusVerification, - AvrIspWriterViewStatusWritingFuse, - AvrIspWriterViewStatusWritingFuseOk, -} AvrIspWriterViewStatus; - -void avr_isp_writer_update_progress(AvrIspWriterView* instance); - -void avr_isp_writer_set_file_path( - AvrIspWriterView* instance, - const char* file_path, - const char* file_name); - -void avr_isp_writer_view_set_callback( - AvrIspWriterView* instance, - AvrIspWriterViewCallback callback, - void* context); - -AvrIspWriterView* avr_isp_writer_view_alloc(); - -void avr_isp_writer_view_free(AvrIspWriterView* instance); - -View* avr_isp_writer_view_get_view(AvrIspWriterView* instance); - -void avr_isp_writer_view_exit(void* context); diff --git a/applications/external/dap_link/README.md b/applications/external/dap_link/README.md deleted file mode 100644 index aead0a60a..000000000 --- a/applications/external/dap_link/README.md +++ /dev/null @@ -1,105 +0,0 @@ -# Flipper Zero as CMSIS DAP/DAP Link -Flipper Zero as a [Free-DAP](https://github.com/ataradov/free-dap) based SWD\JTAG debugger. Free-DAP is a free and open source firmware implementation of the [CMSIS-DAP](https://www.keil.com/pack/doc/CMSIS_Dev/DAP/html/index.html) debugger. - -## Protocols -SWD, JTAG , CMSIS-DAP v1 (18 KiB/s), CMSIS-DAP v2 (46 KiB/s), VCP (USB-UART). - -WinUSB for driverless installation for Windows 8 and above. - -## Usage - -### VSCode + Cortex-Debug - Set `"device": "cmsis-dap"` - -
- BluePill configuration example - - ```json -{ - "name": "Attach (DAP)", - "cwd": "${workspaceFolder}", - "executable": "./build/firmware.elf", - "request": "attach", - "type": "cortex-debug", - "servertype": "openocd", - "device": "cmsis-dap", - "configFiles": [ - "interface/cmsis-dap.cfg", - "target/stm32f1x.cfg", - ], -}, - ``` -
- -
- Flipper Zero configuration example - - ```json -{ - "name": "Attach (DAP)", - "cwd": "${workspaceFolder}", - "executable": "./build/latest/firmware.elf", - "request": "attach", - "type": "cortex-debug", - "servertype": "openocd", - "device": "cmsis-dap", - "svdFile": "./debug/STM32WB55_CM4.svd", - "rtos": "FreeRTOS", - "configFiles": [ - "interface/cmsis-dap.cfg", - "./debug/stm32wbx.cfg", - ], - "postAttachCommands": [ - "source debug/flipperapps.py", - ], -}, - ``` -
- -### OpenOCD -Use `interface/cmsis-dap.cfg`. You will need OpenOCD v0.11.0. - -Additional commands: -* `cmsis_dap_backend hid` for CMSIS-DAP v1 protocol. -* `cmsis_dap_backend usb_bulk` for CMSIS-DAP v2 protocol. -* `cmsis_dap_serial DAP_Oyevoxo` use DAP-Link running on Flipper named `Oyevoxo`. -* `cmsis-dap cmd 81` - reboot connected DAP-Link. - -
- Flash BluePill - - ``` -openocd -f interface/cmsis-dap.cfg -f target/stm32f1x.cfg -c init -c "program build/firmware.bin reset exit 0x8000000" - ``` -
- -
- Flash Flipper Zero using DAP v2 protocol - - ``` -openocd -f interface/cmsis-dap.cfg -c "cmsis_dap_backend usb_bulk" -f debug/stm32wbx.cfg -c init -c "program build/latest/firmware.bin reset exit 0x8000000" - ``` -
- -
- Reboot connected DAP-Link on Flipper named Oyevoxo - - ``` -openocd -f interface/cmsis-dap.cfg -c "cmsis_dap_serial DAP_Oyevoxo" -c "transport select swd" -c "adapter speed 4000000" -c init -c "cmsis-dap cmd 81" -c "exit" - ``` -
- -### PlatformIO -Use `debug_tool = cmsis-dap` and `upload_protocol = cmsis-dap`. [Documentation](https://docs.platformio.org/en/latest/plus/debug-tools/cmsis-dap.html#debugging-tool-cmsis-dap). Remember that Windows 8 and above do not require drivers. - -
- BluePill platformio.ini example - - ``` -[env:bluepill_f103c8] -platform = ststm32 -board = bluepill_f103c8 -debug_tool = cmsis-dap -upload_protocol = cmsis-dap - ``` -
diff --git a/applications/external/dap_link/application.fam b/applications/external/dap_link/application.fam deleted file mode 100644 index 017143803..000000000 --- a/applications/external/dap_link/application.fam +++ /dev/null @@ -1,24 +0,0 @@ -App( - appid="dap_link", - name="DAP Link", - apptype=FlipperAppType.EXTERNAL, - entry_point="dap_link_app", - requires=[ - "gui", - "dialogs", - ], - stack_size=4 * 1024, - order=20, - fap_icon="dap_link.png", - fap_category="GPIO", - fap_private_libs=[ - Lib( - name="free-dap", - cincludes=["."], - sources=[ - "dap.c", - ], - ), - ], - fap_icon_assets="icons", -) diff --git a/applications/external/dap_link/dap_config.h b/applications/external/dap_link/dap_config.h deleted file mode 100644 index 88b90bd34..000000000 --- a/applications/external/dap_link/dap_config.h +++ /dev/null @@ -1,234 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// Copyright (c) 2022, Alex Taradov . All rights reserved. - -#ifndef _DAP_CONFIG_H_ -#define _DAP_CONFIG_H_ - -/*- Includes ----------------------------------------------------------------*/ -#include - -/*- Definitions -------------------------------------------------------------*/ -#define DAP_CONFIG_ENABLE_JTAG - -#define DAP_CONFIG_DEFAULT_PORT DAP_PORT_SWD -#define DAP_CONFIG_DEFAULT_CLOCK 4200000 // Hz - -#define DAP_CONFIG_PACKET_SIZE 64 -#define DAP_CONFIG_PACKET_COUNT 1 - -#define DAP_CONFIG_JTAG_DEV_COUNT 8 - -// DAP_CONFIG_PRODUCT_STR must contain "CMSIS-DAP" to be compatible with the standard -#define DAP_CONFIG_VENDOR_STR "Flipper Zero" -#define DAP_CONFIG_PRODUCT_STR "Generic CMSIS-DAP Adapter" -#define DAP_CONFIG_SER_NUM_STR usb_serial_number -#define DAP_CONFIG_CMSIS_DAP_VER_STR "2.0.0" - -#define DAP_CONFIG_RESET_TARGET_FN dap_app_target_reset -#define DAP_CONFIG_VENDOR_FN dap_app_vendor_cmd - -// Attribute to use for performance-critical functions -#define DAP_CONFIG_PERFORMANCE_ATTR - -// A value at which dap_clock_test() produces 1 kHz output on the SWCLK pin -// #define DAP_CONFIG_DELAY_CONSTANT 19000 -#define DAP_CONFIG_DELAY_CONSTANT 6290 - -// A threshold for switching to fast clock (no added delays) -// This is the frequency produced by dap_clock_test(1) on the SWCLK pin -#define DAP_CONFIG_FAST_CLOCK 2400000 // Hz - -/*- Prototypes --------------------------------------------------------------*/ -extern char usb_serial_number[16]; - -/*- Implementations ---------------------------------------------------------*/ -extern GpioPin flipper_dap_swclk_pin; -extern GpioPin flipper_dap_swdio_pin; -extern GpioPin flipper_dap_reset_pin; -extern GpioPin flipper_dap_tdo_pin; -extern GpioPin flipper_dap_tdi_pin; - -extern void dap_app_vendor_cmd(uint8_t cmd); -extern void dap_app_target_reset(); -extern void dap_app_disconnect(); -extern void dap_app_connect_swd(); -extern void dap_app_connect_jtag(); - -//----------------------------------------------------------------------------- -static inline void DAP_CONFIG_SWCLK_TCK_write(int value) { - furi_hal_gpio_write(&flipper_dap_swclk_pin, value); -} - -//----------------------------------------------------------------------------- -static inline void DAP_CONFIG_SWDIO_TMS_write(int value) { - furi_hal_gpio_write(&flipper_dap_swdio_pin, value); -} - -//----------------------------------------------------------------------------- -static inline void DAP_CONFIG_TDI_write(int value) { -#ifdef DAP_CONFIG_ENABLE_JTAG - furi_hal_gpio_write(&flipper_dap_tdi_pin, value); -#else - (void)value; -#endif -} - -//----------------------------------------------------------------------------- -static inline void DAP_CONFIG_TDO_write(int value) { -#ifdef DAP_CONFIG_ENABLE_JTAG - furi_hal_gpio_write(&flipper_dap_tdo_pin, value); -#else - (void)value; -#endif -} - -//----------------------------------------------------------------------------- -static inline void DAP_CONFIG_nTRST_write(int value) { - (void)value; -} - -//----------------------------------------------------------------------------- -static inline void DAP_CONFIG_nRESET_write(int value) { - furi_hal_gpio_write(&flipper_dap_reset_pin, value); -} - -//----------------------------------------------------------------------------- -static inline int DAP_CONFIG_SWCLK_TCK_read(void) { - return furi_hal_gpio_read(&flipper_dap_swclk_pin); -} - -//----------------------------------------------------------------------------- -static inline int DAP_CONFIG_SWDIO_TMS_read(void) { - return furi_hal_gpio_read(&flipper_dap_swdio_pin); -} - -//----------------------------------------------------------------------------- -static inline int DAP_CONFIG_TDO_read(void) { -#ifdef DAP_CONFIG_ENABLE_JTAG - return furi_hal_gpio_read(&flipper_dap_tdo_pin); -#else - return 0; -#endif -} - -//----------------------------------------------------------------------------- -static inline int DAP_CONFIG_TDI_read(void) { -#ifdef DAP_CONFIG_ENABLE_JTAG - return furi_hal_gpio_read(&flipper_dap_tdi_pin); -#else - return 0; -#endif -} - -//----------------------------------------------------------------------------- -static inline int DAP_CONFIG_nTRST_read(void) { - return 0; -} - -//----------------------------------------------------------------------------- -static inline int DAP_CONFIG_nRESET_read(void) { - return furi_hal_gpio_read(&flipper_dap_reset_pin); -} - -//----------------------------------------------------------------------------- -static inline void DAP_CONFIG_SWCLK_TCK_set(void) { - LL_GPIO_SetOutputPin(flipper_dap_swclk_pin.port, flipper_dap_swclk_pin.pin); -} - -//----------------------------------------------------------------------------- -static inline void DAP_CONFIG_SWCLK_TCK_clr(void) { - LL_GPIO_ResetOutputPin(flipper_dap_swclk_pin.port, flipper_dap_swclk_pin.pin); -} - -//----------------------------------------------------------------------------- -static inline void DAP_CONFIG_SWDIO_TMS_in(void) { - LL_GPIO_SetPinMode(flipper_dap_swdio_pin.port, flipper_dap_swdio_pin.pin, LL_GPIO_MODE_INPUT); -} - -//----------------------------------------------------------------------------- -static inline void DAP_CONFIG_SWDIO_TMS_out(void) { - LL_GPIO_SetPinMode(flipper_dap_swdio_pin.port, flipper_dap_swdio_pin.pin, LL_GPIO_MODE_OUTPUT); -} - -//----------------------------------------------------------------------------- -static inline void DAP_CONFIG_SETUP(void) { - furi_hal_gpio_init(&flipper_dap_swdio_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_init(&flipper_dap_swclk_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_init(&flipper_dap_reset_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh); -#ifdef DAP_CONFIG_ENABLE_JTAG - furi_hal_gpio_init(&flipper_dap_tdo_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_init(&flipper_dap_tdi_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh); -#endif -} - -//----------------------------------------------------------------------------- -static inline void DAP_CONFIG_DISCONNECT(void) { - furi_hal_gpio_init(&flipper_dap_swdio_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_init(&flipper_dap_swclk_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_init(&flipper_dap_reset_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh); -#ifdef DAP_CONFIG_ENABLE_JTAG - furi_hal_gpio_init(&flipper_dap_tdo_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_init(&flipper_dap_tdi_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh); -#endif - dap_app_disconnect(); -} - -//----------------------------------------------------------------------------- -static inline void DAP_CONFIG_CONNECT_SWD(void) { - furi_hal_gpio_init( - &flipper_dap_swdio_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_write(&flipper_dap_swdio_pin, true); - - furi_hal_gpio_init( - &flipper_dap_swclk_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_write(&flipper_dap_swclk_pin, true); - - furi_hal_gpio_init( - &flipper_dap_reset_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_write(&flipper_dap_reset_pin, true); - -#ifdef DAP_CONFIG_ENABLE_JTAG - furi_hal_gpio_init(&flipper_dap_tdo_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_init(&flipper_dap_tdi_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh); -#endif - dap_app_connect_swd(); -} - -//----------------------------------------------------------------------------- -static inline void DAP_CONFIG_CONNECT_JTAG(void) { - furi_hal_gpio_init( - &flipper_dap_swdio_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_write(&flipper_dap_swdio_pin, true); - - furi_hal_gpio_init( - &flipper_dap_swclk_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_write(&flipper_dap_swclk_pin, true); - - furi_hal_gpio_init( - &flipper_dap_reset_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_write(&flipper_dap_reset_pin, true); - -#ifdef DAP_CONFIG_ENABLE_JTAG - furi_hal_gpio_init(&flipper_dap_tdo_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh); - - furi_hal_gpio_init( - &flipper_dap_tdi_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_write(&flipper_dap_tdi_pin, true); -#endif - dap_app_connect_jtag(); -} - -//----------------------------------------------------------------------------- -static inline void DAP_CONFIG_LED(int index, int state) { - (void)index; - (void)state; -} - -//----------------------------------------------------------------------------- -__attribute__((always_inline)) static inline void DAP_CONFIG_DELAY(uint32_t cycles) { - asm volatile("1: subs %[cycles], %[cycles], #1 \n" - " bne 1b \n" - : [cycles] "+l"(cycles)); -} - -#endif // _DAP_CONFIG_H_ diff --git a/applications/external/dap_link/dap_link.c b/applications/external/dap_link/dap_link.c deleted file mode 100644 index eafb435e7..000000000 --- a/applications/external/dap_link/dap_link.c +++ /dev/null @@ -1,527 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dap_link.h" -#include "dap_config.h" -#include "gui/dap_gui.h" -#include "usb/dap_v2_usb.h" -#include -#include "dap_link_icons.h" - -/***************************************************************************/ -/****************************** DAP COMMON *********************************/ -/***************************************************************************/ - -struct DapApp { - FuriThread* dap_thread; - FuriThread* cdc_thread; - FuriThread* gui_thread; - - DapState state; - DapConfig config; -}; - -void dap_app_get_state(DapApp* app, DapState* state) { - *state = app->state; -} - -#define DAP_PROCESS_THREAD_TICK 500 - -typedef enum { - DapThreadEventStop = (1 << 0), -} DapThreadEvent; - -void dap_thread_send_stop(FuriThread* thread) { - furi_thread_flags_set(furi_thread_get_id(thread), DapThreadEventStop); -} - -GpioPin flipper_dap_swclk_pin; -GpioPin flipper_dap_swdio_pin; -GpioPin flipper_dap_reset_pin; -GpioPin flipper_dap_tdo_pin; -GpioPin flipper_dap_tdi_pin; - -/***************************************************************************/ -/****************************** DAP PROCESS ********************************/ -/***************************************************************************/ - -typedef struct { - uint8_t data[DAP_CONFIG_PACKET_SIZE]; - uint8_t size; -} DapPacket; - -typedef enum { - DAPThreadEventStop = DapThreadEventStop, - DAPThreadEventRxV1 = (1 << 1), - DAPThreadEventRxV2 = (1 << 2), - DAPThreadEventUSBConnect = (1 << 3), - DAPThreadEventUSBDisconnect = (1 << 4), - DAPThreadEventApplyConfig = (1 << 5), - DAPThreadEventAll = DAPThreadEventStop | DAPThreadEventRxV1 | DAPThreadEventRxV2 | - DAPThreadEventUSBConnect | DAPThreadEventUSBDisconnect | - DAPThreadEventApplyConfig, -} DAPThreadEvent; - -#define USB_SERIAL_NUMBER_LEN 16 -char usb_serial_number[USB_SERIAL_NUMBER_LEN] = {0}; - -const char* dap_app_get_serial(DapApp* app) { - UNUSED(app); - return usb_serial_number; -} - -static void dap_app_rx1_callback(void* context) { - furi_assert(context); - FuriThreadId thread_id = (FuriThreadId)context; - furi_thread_flags_set(thread_id, DAPThreadEventRxV1); -} - -static void dap_app_rx2_callback(void* context) { - furi_assert(context); - FuriThreadId thread_id = (FuriThreadId)context; - furi_thread_flags_set(thread_id, DAPThreadEventRxV2); -} - -static void dap_app_usb_state_callback(bool state, void* context) { - furi_assert(context); - FuriThreadId thread_id = (FuriThreadId)context; - if(state) { - furi_thread_flags_set(thread_id, DAPThreadEventUSBConnect); - } else { - furi_thread_flags_set(thread_id, DAPThreadEventUSBDisconnect); - } -} - -static void dap_app_process_v1() { - DapPacket tx_packet; - DapPacket rx_packet; - memset(&tx_packet, 0, sizeof(DapPacket)); - rx_packet.size = dap_v1_usb_rx(rx_packet.data, DAP_CONFIG_PACKET_SIZE); - dap_process_request(rx_packet.data, rx_packet.size, tx_packet.data, DAP_CONFIG_PACKET_SIZE); - dap_v1_usb_tx(tx_packet.data, DAP_CONFIG_PACKET_SIZE); -} - -static void dap_app_process_v2() { - DapPacket tx_packet; - DapPacket rx_packet; - memset(&tx_packet, 0, sizeof(DapPacket)); - rx_packet.size = dap_v2_usb_rx(rx_packet.data, DAP_CONFIG_PACKET_SIZE); - size_t len = dap_process_request( - rx_packet.data, rx_packet.size, tx_packet.data, DAP_CONFIG_PACKET_SIZE); - dap_v2_usb_tx(tx_packet.data, len); -} - -void dap_app_vendor_cmd(uint8_t cmd) { - // openocd -c "cmsis-dap cmd 81" - if(cmd == 0x01) { - furi_hal_power_reset(); - } -} - -void dap_app_target_reset() { - FURI_LOG_I("DAP", "Target reset"); -} - -static void dap_init_gpio(DapSwdPins swd_pins) { - switch(swd_pins) { - case DapSwdPinsPA7PA6: - flipper_dap_swclk_pin = gpio_ext_pa7; - flipper_dap_swdio_pin = gpio_ext_pa6; - break; - case DapSwdPinsPA14PA13: - flipper_dap_swclk_pin = (GpioPin){.port = GPIOA, .pin = LL_GPIO_PIN_14}; - flipper_dap_swdio_pin = (GpioPin){.port = GPIOA, .pin = LL_GPIO_PIN_13}; - break; - } - - flipper_dap_reset_pin = gpio_ext_pa4; - flipper_dap_tdo_pin = gpio_ext_pb3; - flipper_dap_tdi_pin = gpio_ext_pb2; -} - -static void dap_deinit_gpio(DapSwdPins swd_pins) { - // setup gpio pins to default state - furi_hal_gpio_init(&flipper_dap_reset_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(&flipper_dap_tdo_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(&flipper_dap_tdi_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - - if(DapSwdPinsPA14PA13 == swd_pins) { - // PA14 and PA13 are used by SWD - furi_hal_gpio_init_ex( - &flipper_dap_swclk_pin, - GpioModeAltFunctionPushPull, - GpioPullDown, - GpioSpeedLow, - GpioAltFn0JTCK_SWCLK); - furi_hal_gpio_init_ex( - &flipper_dap_swdio_pin, - GpioModeAltFunctionPushPull, - GpioPullUp, - GpioSpeedVeryHigh, - GpioAltFn0JTMS_SWDIO); - } else { - furi_hal_gpio_init(&flipper_dap_swclk_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(&flipper_dap_swdio_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - } -} - -static int32_t dap_process(void* p) { - DapApp* app = p; - DapState* dap_state = &(app->state); - - // allocate resources - FuriHalUsbInterface* usb_config_prev; - app->config.swd_pins = DapSwdPinsPA7PA6; - DapSwdPins swd_pins_prev = app->config.swd_pins; - - // init pins - dap_init_gpio(swd_pins_prev); - - // init dap - dap_init(); - - // get name - const char* name = furi_hal_version_get_name_ptr(); - if(!name) { - name = "Flipper"; - } - snprintf(usb_serial_number, USB_SERIAL_NUMBER_LEN, "DAP_%s", name); - - // init usb - usb_config_prev = furi_hal_usb_get_config(); - dap_common_usb_alloc_name(usb_serial_number); - dap_common_usb_set_context(furi_thread_get_id(furi_thread_get_current())); - dap_v1_usb_set_rx_callback(dap_app_rx1_callback); - dap_v2_usb_set_rx_callback(dap_app_rx2_callback); - dap_common_usb_set_state_callback(dap_app_usb_state_callback); - furi_hal_usb_set_config(&dap_v2_usb_hid, NULL); - - // work - uint32_t events; - while(1) { - events = furi_thread_flags_wait(DAPThreadEventAll, FuriFlagWaitAny, FuriWaitForever); - - if(!(events & FuriFlagError)) { - if(events & DAPThreadEventRxV1) { - dap_app_process_v1(); - dap_state->dap_counter++; - dap_state->dap_version = DapVersionV1; - } - - if(events & DAPThreadEventRxV2) { - dap_app_process_v2(); - dap_state->dap_counter++; - dap_state->dap_version = DapVersionV2; - } - - if(events & DAPThreadEventUSBConnect) { - dap_state->usb_connected = true; - } - - if(events & DAPThreadEventUSBDisconnect) { - dap_state->usb_connected = false; - dap_state->dap_version = DapVersionUnknown; - } - - if(events & DAPThreadEventApplyConfig) { - if(swd_pins_prev != app->config.swd_pins) { - dap_deinit_gpio(swd_pins_prev); - swd_pins_prev = app->config.swd_pins; - dap_init_gpio(swd_pins_prev); - } - } - - if(events & DAPThreadEventStop) { - break; - } - } - } - - // deinit usb - furi_hal_usb_set_config(usb_config_prev, NULL); - dap_common_usb_free_name(); - dap_deinit_gpio(swd_pins_prev); - return 0; -} - -/***************************************************************************/ -/****************************** CDC PROCESS ********************************/ -/***************************************************************************/ - -typedef enum { - CDCThreadEventStop = DapThreadEventStop, - CDCThreadEventUARTRx = (1 << 1), - CDCThreadEventCDCRx = (1 << 2), - CDCThreadEventCDCConfig = (1 << 3), - CDCThreadEventApplyConfig = (1 << 4), - CDCThreadEventAll = CDCThreadEventStop | CDCThreadEventUARTRx | CDCThreadEventCDCRx | - CDCThreadEventCDCConfig | CDCThreadEventApplyConfig, -} CDCThreadEvent; - -typedef struct { - FuriStreamBuffer* rx_stream; - FuriThreadId thread_id; - FuriHalUartId uart_id; - struct usb_cdc_line_coding line_coding; -} CDCProcess; - -static void cdc_uart_irq_cb(UartIrqEvent ev, uint8_t data, void* ctx) { - CDCProcess* app = ctx; - - if(ev == UartIrqEventRXNE) { - furi_stream_buffer_send(app->rx_stream, &data, 1, 0); - furi_thread_flags_set(app->thread_id, CDCThreadEventUARTRx); - } -} - -static void cdc_usb_rx_callback(void* context) { - CDCProcess* app = context; - furi_thread_flags_set(app->thread_id, CDCThreadEventCDCRx); -} - -static void cdc_usb_control_line_callback(uint8_t state, void* context) { - UNUSED(context); - UNUSED(state); -} - -static void cdc_usb_config_callback(struct usb_cdc_line_coding* config, void* context) { - CDCProcess* app = context; - app->line_coding = *config; - furi_thread_flags_set(app->thread_id, CDCThreadEventCDCConfig); -} - -static FuriHalUartId cdc_init_uart( - DapUartType type, - DapUartTXRX swap, - uint32_t baudrate, - void (*cb)(UartIrqEvent ev, uint8_t data, void* ctx), - void* ctx) { - FuriHalUartId uart_id = FuriHalUartIdUSART1; - if(baudrate == 0) baudrate = 115200; - - switch(type) { - case DapUartTypeUSART1: - uart_id = FuriHalUartIdUSART1; - furi_hal_console_disable(); - furi_hal_uart_deinit(uart_id); - if(swap == DapUartTXRXSwap) { - LL_USART_SetTXRXSwap(USART1, LL_USART_TXRX_SWAPPED); - } else { - LL_USART_SetTXRXSwap(USART1, LL_USART_TXRX_STANDARD); - } - furi_hal_uart_init(uart_id, baudrate); - furi_hal_uart_set_irq_cb(uart_id, cb, ctx); - break; - case DapUartTypeLPUART1: - uart_id = FuriHalUartIdLPUART1; - furi_hal_uart_deinit(uart_id); - if(swap == DapUartTXRXSwap) { - LL_LPUART_SetTXRXSwap(LPUART1, LL_LPUART_TXRX_SWAPPED); - } else { - LL_LPUART_SetTXRXSwap(LPUART1, LL_LPUART_TXRX_STANDARD); - } - furi_hal_uart_init(uart_id, baudrate); - furi_hal_uart_set_irq_cb(uart_id, cb, ctx); - break; - } - - return uart_id; -} - -static void cdc_deinit_uart(DapUartType type) { - switch(type) { - case DapUartTypeUSART1: - furi_hal_uart_deinit(FuriHalUartIdUSART1); - LL_USART_SetTXRXSwap(USART1, LL_USART_TXRX_STANDARD); - furi_hal_console_init(); - break; - case DapUartTypeLPUART1: - furi_hal_uart_deinit(FuriHalUartIdLPUART1); - LL_LPUART_SetTXRXSwap(LPUART1, LL_LPUART_TXRX_STANDARD); - break; - } -} - -static int32_t cdc_process(void* p) { - DapApp* dap_app = p; - DapState* dap_state = &(dap_app->state); - - dap_app->config.uart_pins = DapUartTypeLPUART1; - dap_app->config.uart_swap = DapUartTXRXNormal; - - DapUartType uart_pins_prev = dap_app->config.uart_pins; - DapUartTXRX uart_swap_prev = dap_app->config.uart_swap; - - CDCProcess* app = malloc(sizeof(CDCProcess)); - app->thread_id = furi_thread_get_id(furi_thread_get_current()); - app->rx_stream = furi_stream_buffer_alloc(512, 1); - - const uint8_t rx_buffer_size = 64; - uint8_t* rx_buffer = malloc(rx_buffer_size); - - app->uart_id = cdc_init_uart( - uart_pins_prev, uart_swap_prev, dap_state->cdc_baudrate, cdc_uart_irq_cb, app); - - dap_cdc_usb_set_context(app); - dap_cdc_usb_set_rx_callback(cdc_usb_rx_callback); - dap_cdc_usb_set_control_line_callback(cdc_usb_control_line_callback); - dap_cdc_usb_set_config_callback(cdc_usb_config_callback); - - uint32_t events; - while(1) { - events = furi_thread_flags_wait(CDCThreadEventAll, FuriFlagWaitAny, FuriWaitForever); - - if(!(events & FuriFlagError)) { - if(events & CDCThreadEventCDCConfig) { - if(dap_state->cdc_baudrate != app->line_coding.dwDTERate) { - dap_state->cdc_baudrate = app->line_coding.dwDTERate; - if(dap_state->cdc_baudrate > 0) { - furi_hal_uart_set_br(app->uart_id, dap_state->cdc_baudrate); - } - } - } - - if(events & CDCThreadEventUARTRx) { - size_t len = - furi_stream_buffer_receive(app->rx_stream, rx_buffer, rx_buffer_size, 0); - - if(len > 0) { - dap_cdc_usb_tx(rx_buffer, len); - } - dap_state->cdc_rx_counter += len; - } - - if(events & CDCThreadEventCDCRx) { - size_t len = dap_cdc_usb_rx(rx_buffer, rx_buffer_size); - if(len > 0) { - furi_hal_uart_tx(app->uart_id, rx_buffer, len); - } - dap_state->cdc_tx_counter += len; - } - - if(events & CDCThreadEventApplyConfig) { - if(uart_pins_prev != dap_app->config.uart_pins || - uart_swap_prev != dap_app->config.uart_swap) { - cdc_deinit_uart(uart_pins_prev); - uart_pins_prev = dap_app->config.uart_pins; - uart_swap_prev = dap_app->config.uart_swap; - app->uart_id = cdc_init_uart( - uart_pins_prev, - uart_swap_prev, - dap_state->cdc_baudrate, - cdc_uart_irq_cb, - app); - } - } - - if(events & CDCThreadEventStop) { - break; - } - } - } - - cdc_deinit_uart(uart_pins_prev); - free(rx_buffer); - furi_stream_buffer_free(app->rx_stream); - free(app); - - return 0; -} - -/***************************************************************************/ -/******************************* MAIN APP **********************************/ -/***************************************************************************/ - -static DapApp* dap_app_alloc() { - DapApp* dap_app = malloc(sizeof(DapApp)); - dap_app->dap_thread = furi_thread_alloc_ex("DAP Process", 1024, dap_process, dap_app); - dap_app->cdc_thread = furi_thread_alloc_ex("DAP CDC", 1024, cdc_process, dap_app); - dap_app->gui_thread = furi_thread_alloc_ex("DAP GUI", 1024, dap_gui_thread, dap_app); - return dap_app; -} - -static void dap_app_free(DapApp* dap_app) { - furi_assert(dap_app); - furi_thread_free(dap_app->dap_thread); - furi_thread_free(dap_app->cdc_thread); - furi_thread_free(dap_app->gui_thread); - free(dap_app); -} - -static DapApp* app_handle = NULL; - -void dap_app_disconnect() { - app_handle->state.dap_mode = DapModeDisconnected; -} - -void dap_app_connect_swd() { - app_handle->state.dap_mode = DapModeSWD; -} - -void dap_app_connect_jtag() { - app_handle->state.dap_mode = DapModeJTAG; -} - -void dap_app_set_config(DapApp* app, DapConfig* config) { - app->config = *config; - furi_thread_flags_set(furi_thread_get_id(app->dap_thread), DAPThreadEventApplyConfig); - furi_thread_flags_set(furi_thread_get_id(app->cdc_thread), CDCThreadEventApplyConfig); -} - -DapConfig* dap_app_get_config(DapApp* app) { - return &app->config; -} - -int32_t dap_link_app(void* p) { - UNUSED(p); - - if(furi_hal_usb_is_locked()) { - DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); - DialogMessage* message = dialog_message_alloc(); - dialog_message_set_header(message, "Connection\nis active!", 3, 2, AlignLeft, AlignTop); - dialog_message_set_text( - message, - "Disconnect from\nPC or phone to\nuse this function.", - 3, - 30, - AlignLeft, - AlignTop); - dialog_message_set_icon(message, &I_ActiveConnection_50x64, 78, 0); - dialog_message_show(dialogs, message); - dialog_message_free(message); - furi_record_close(RECORD_DIALOGS); - return -1; - } - - // alloc app - DapApp* app = dap_app_alloc(); - app_handle = app; - - furi_thread_start(app->dap_thread); - furi_thread_start(app->cdc_thread); - furi_thread_start(app->gui_thread); - - // wait until gui thread is finished - furi_thread_join(app->gui_thread); - - // send stop event to threads - dap_thread_send_stop(app->dap_thread); - dap_thread_send_stop(app->cdc_thread); - - // wait for threads to stop - furi_thread_join(app->dap_thread); - furi_thread_join(app->cdc_thread); - - // free app - dap_app_free(app); - - return 0; -} \ No newline at end of file diff --git a/applications/external/dap_link/dap_link.h b/applications/external/dap_link/dap_link.h deleted file mode 100644 index d51726c45..000000000 --- a/applications/external/dap_link/dap_link.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once -#include - -typedef enum { - DapModeDisconnected, - DapModeSWD, - DapModeJTAG, -} DapMode; - -typedef enum { - DapVersionUnknown, - DapVersionV1, - DapVersionV2, -} DapVersion; - -typedef struct { - bool usb_connected; - DapMode dap_mode; - DapVersion dap_version; - uint32_t dap_counter; - uint32_t cdc_baudrate; - uint32_t cdc_tx_counter; - uint32_t cdc_rx_counter; -} DapState; - -typedef enum { - DapSwdPinsPA7PA6, // Pins 2, 3 - DapSwdPinsPA14PA13, // Pins 10, 12 -} DapSwdPins; - -typedef enum { - DapUartTypeUSART1, // Pins 13, 14 - DapUartTypeLPUART1, // Pins 15, 16 -} DapUartType; - -typedef enum { - DapUartTXRXNormal, - DapUartTXRXSwap, -} DapUartTXRX; - -typedef struct { - DapSwdPins swd_pins; - DapUartType uart_pins; - DapUartTXRX uart_swap; -} DapConfig; - -typedef struct DapApp DapApp; - -void dap_app_get_state(DapApp* app, DapState* state); - -const char* dap_app_get_serial(DapApp* app); - -void dap_app_set_config(DapApp* app, DapConfig* config); - -DapConfig* dap_app_get_config(DapApp* app); \ No newline at end of file diff --git a/applications/external/dap_link/dap_link.png b/applications/external/dap_link/dap_link.png deleted file mode 100644 index 2278ce2b6..000000000 Binary files a/applications/external/dap_link/dap_link.png and /dev/null differ diff --git a/applications/external/dap_link/gui/dap_gui.c b/applications/external/dap_link/gui/dap_gui.c deleted file mode 100644 index 4dd986153..000000000 --- a/applications/external/dap_link/gui/dap_gui.c +++ /dev/null @@ -1,92 +0,0 @@ -#include "dap_gui.h" -#include "dap_gui_i.h" - -#define DAP_GUI_TICK 250 - -static bool dap_gui_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - DapGuiApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool dap_gui_back_event_callback(void* context) { - furi_assert(context); - DapGuiApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -static void dap_gui_tick_event_callback(void* context) { - furi_assert(context); - DapGuiApp* app = context; - scene_manager_handle_tick_event(app->scene_manager); -} - -DapGuiApp* dap_gui_alloc() { - DapGuiApp* app = malloc(sizeof(DapGuiApp)); - app->gui = furi_record_open(RECORD_GUI); - app->view_dispatcher = view_dispatcher_alloc(); - app->scene_manager = scene_manager_alloc(&dap_scene_handlers, app); - view_dispatcher_enable_queue(app->view_dispatcher); - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - - view_dispatcher_set_custom_event_callback(app->view_dispatcher, dap_gui_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, dap_gui_back_event_callback); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, dap_gui_tick_event_callback, DAP_GUI_TICK); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - app->notifications = furi_record_open(RECORD_NOTIFICATION); - - app->var_item_list = variable_item_list_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - DapGuiAppViewVarItemList, - variable_item_list_get_view(app->var_item_list)); - - app->main_view = dap_main_view_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, DapGuiAppViewMainView, dap_main_view_get_view(app->main_view)); - - app->widget = widget_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, DapGuiAppViewWidget, widget_get_view(app->widget)); - - scene_manager_next_scene(app->scene_manager, DapSceneMain); - - return app; -} - -void dap_gui_free(DapGuiApp* app) { - view_dispatcher_remove_view(app->view_dispatcher, DapGuiAppViewVarItemList); - variable_item_list_free(app->var_item_list); - - view_dispatcher_remove_view(app->view_dispatcher, DapGuiAppViewMainView); - dap_main_view_free(app->main_view); - - view_dispatcher_remove_view(app->view_dispatcher, DapGuiAppViewWidget); - widget_free(app->widget); - - // View dispatcher - view_dispatcher_free(app->view_dispatcher); - scene_manager_free(app->scene_manager); - - // Close records - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_NOTIFICATION); - - free(app); -} - -int32_t dap_gui_thread(void* arg) { - DapGuiApp* app = dap_gui_alloc(); - app->dap_app = arg; - - notification_message_block(app->notifications, &sequence_display_backlight_enforce_on); - view_dispatcher_run(app->view_dispatcher); - notification_message_block(app->notifications, &sequence_display_backlight_enforce_auto); - - dap_gui_free(app); - return 0; -} \ No newline at end of file diff --git a/applications/external/dap_link/gui/dap_gui.h b/applications/external/dap_link/gui/dap_gui.h deleted file mode 100644 index 3d8e6bdf9..000000000 --- a/applications/external/dap_link/gui/dap_gui.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include - -int32_t dap_gui_thread(void* arg); \ No newline at end of file diff --git a/applications/external/dap_link/gui/dap_gui_custom_event.h b/applications/external/dap_link/gui/dap_gui_custom_event.h deleted file mode 100644 index 8b127c9d4..000000000 --- a/applications/external/dap_link/gui/dap_gui_custom_event.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -typedef enum { - DapAppCustomEventConfig, - DapAppCustomEventHelp, - DapAppCustomEventAbout, -} DapAppCustomEvent; diff --git a/applications/external/dap_link/gui/dap_gui_i.h b/applications/external/dap_link/gui/dap_gui_i.h deleted file mode 100644 index 59411e78c..000000000 --- a/applications/external/dap_link/gui/dap_gui_i.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include "dap_gui.h" -#include "../dap_link.h" -#include "scenes/config/dap_scene.h" -#include "dap_gui_custom_event.h" -#include "views/dap_main_view.h" - -typedef struct { - DapApp* dap_app; - - Gui* gui; - NotificationApp* notifications; - ViewDispatcher* view_dispatcher; - SceneManager* scene_manager; - - VariableItemList* var_item_list; - DapMainView* main_view; - Widget* widget; -} DapGuiApp; - -typedef enum { - DapGuiAppViewVarItemList, - DapGuiAppViewMainView, - DapGuiAppViewWidget, -} DapGuiAppView; diff --git a/applications/external/dap_link/gui/scenes/config/dap_scene.c b/applications/external/dap_link/gui/scenes/config/dap_scene.c deleted file mode 100644 index 37e235540..000000000 --- a/applications/external/dap_link/gui/scenes/config/dap_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "dap_scene.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const dap_scene_on_enter_handlers[])(void*) = { -#include "dap_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 dap_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "dap_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 dap_scene_on_exit_handlers[])(void* context) = { -#include "dap_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers dap_scene_handlers = { - .on_enter_handlers = dap_scene_on_enter_handlers, - .on_event_handlers = dap_scene_on_event_handlers, - .on_exit_handlers = dap_scene_on_exit_handlers, - .scene_num = DapSceneNum, -}; diff --git a/applications/external/dap_link/gui/scenes/config/dap_scene.h b/applications/external/dap_link/gui/scenes/config/dap_scene.h deleted file mode 100644 index 6fb38da4a..000000000 --- a/applications/external/dap_link/gui/scenes/config/dap_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) DapScene##id, -typedef enum { -#include "dap_scene_config.h" - DapSceneNum, -} DapScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers dap_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "dap_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 "dap_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 "dap_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/dap_link/gui/scenes/config/dap_scene_config.h b/applications/external/dap_link/gui/scenes/config/dap_scene_config.h deleted file mode 100644 index 8957aca06..000000000 --- a/applications/external/dap_link/gui/scenes/config/dap_scene_config.h +++ /dev/null @@ -1,4 +0,0 @@ -ADD_SCENE(dap, main, Main) -ADD_SCENE(dap, config, Config) -ADD_SCENE(dap, help, Help) -ADD_SCENE(dap, about, About) \ No newline at end of file diff --git a/applications/external/dap_link/gui/scenes/dap_scene_about.c b/applications/external/dap_link/gui/scenes/dap_scene_about.c deleted file mode 100644 index 0974e60a7..000000000 --- a/applications/external/dap_link/gui/scenes/dap_scene_about.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "../dap_gui_i.h" - -#define DAP_VERSION_APP "0.1.0" -#define DAP_DEVELOPED "Dr_Zlo" -#define DAP_GITHUB "https://github.com/flipperdevices/flipperzero-firmware" - -void dap_scene_about_on_enter(void* context) { - DapGuiApp* app = context; - - FuriString* temp_str; - temp_str = furi_string_alloc(); - furi_string_printf(temp_str, "\e#%s\n", "Information"); - - furi_string_cat_printf(temp_str, "Version: %s\n", DAP_VERSION_APP); - furi_string_cat_printf(temp_str, "Developed by: %s\n", DAP_DEVELOPED); - furi_string_cat_printf(temp_str, "Github: %s\n\n", DAP_GITHUB); - - furi_string_cat_printf(temp_str, "\e#%s\n", "Description"); - furi_string_cat_printf( - temp_str, "CMSIS-DAP debugger\nbased on Free-DAP\nThanks to Alex Taradov\n\n"); - - furi_string_cat_printf( - temp_str, - "Supported protocols:\n" - "SWD, JTAG, UART\n" - "DAP v1 (cmsis_backend hid), DAP v2 (cmsis_backend usb_bulk), VCP\n"); - - widget_add_text_box_element( - app->widget, - 0, - 0, - 128, - 14, - AlignCenter, - AlignBottom, - "\e#\e! \e!\n", - false); - widget_add_text_box_element( - app->widget, - 0, - 2, - 128, - 14, - AlignCenter, - AlignBottom, - "\e#\e! DAP Link \e!\n", - false); - widget_add_text_scroll_element(app->widget, 0, 16, 128, 50, furi_string_get_cstr(temp_str)); - furi_string_free(temp_str); - - view_dispatcher_switch_to_view(app->view_dispatcher, DapGuiAppViewWidget); -} - -bool dap_scene_about_on_event(void* context, SceneManagerEvent event) { - DapGuiApp* app = context; - bool consumed = false; - UNUSED(app); - UNUSED(event); - - return consumed; -} - -void dap_scene_about_on_exit(void* context) { - DapGuiApp* app = context; - - // Clear views - widget_reset(app->widget); -} diff --git a/applications/external/dap_link/gui/scenes/dap_scene_config.c b/applications/external/dap_link/gui/scenes/dap_scene_config.c deleted file mode 100644 index 48d5fedcd..000000000 --- a/applications/external/dap_link/gui/scenes/dap_scene_config.c +++ /dev/null @@ -1,107 +0,0 @@ -#include "../dap_gui_i.h" - -static const char* swd_pins[] = {[DapSwdPinsPA7PA6] = "2,3", [DapSwdPinsPA14PA13] = "10,12"}; -static const char* uart_pins[] = {[DapUartTypeUSART1] = "13,14", [DapUartTypeLPUART1] = "15,16"}; -static const char* uart_swap[] = {[DapUartTXRXNormal] = "No", [DapUartTXRXSwap] = "Yes"}; - -static void swd_pins_cb(VariableItem* item) { - DapGuiApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - - variable_item_set_current_value_text(item, swd_pins[index]); - - DapConfig* config = dap_app_get_config(app->dap_app); - config->swd_pins = index; - dap_app_set_config(app->dap_app, config); -} - -static void uart_pins_cb(VariableItem* item) { - DapGuiApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - - variable_item_set_current_value_text(item, uart_pins[index]); - - DapConfig* config = dap_app_get_config(app->dap_app); - config->uart_pins = index; - dap_app_set_config(app->dap_app, config); -} - -static void uart_swap_cb(VariableItem* item) { - DapGuiApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - - variable_item_set_current_value_text(item, uart_swap[index]); - - DapConfig* config = dap_app_get_config(app->dap_app); - config->uart_swap = index; - dap_app_set_config(app->dap_app, config); -} - -static void ok_cb(void* context, uint32_t index) { - DapGuiApp* app = context; - switch(index) { - case 3: - view_dispatcher_send_custom_event(app->view_dispatcher, DapAppCustomEventHelp); - break; - case 4: - view_dispatcher_send_custom_event(app->view_dispatcher, DapAppCustomEventAbout); - break; - default: - break; - } -} - -void dap_scene_config_on_enter(void* context) { - DapGuiApp* app = context; - VariableItemList* var_item_list = app->var_item_list; - VariableItem* item; - DapConfig* config = dap_app_get_config(app->dap_app); - - item = variable_item_list_add( - var_item_list, "SWC SWD Pins", COUNT_OF(swd_pins), swd_pins_cb, app); - variable_item_set_current_value_index(item, config->swd_pins); - variable_item_set_current_value_text(item, swd_pins[config->swd_pins]); - - item = - variable_item_list_add(var_item_list, "UART Pins", COUNT_OF(uart_pins), uart_pins_cb, app); - variable_item_set_current_value_index(item, config->uart_pins); - variable_item_set_current_value_text(item, uart_pins[config->uart_pins]); - - item = variable_item_list_add( - var_item_list, "Swap TX RX", COUNT_OF(uart_swap), uart_swap_cb, app); - variable_item_set_current_value_index(item, config->uart_swap); - variable_item_set_current_value_text(item, uart_swap[config->uart_swap]); - - variable_item_list_add(var_item_list, "Help and Pinout", 0, NULL, NULL); - variable_item_list_add(var_item_list, "About", 0, NULL, NULL); - - variable_item_list_set_selected_item( - var_item_list, scene_manager_get_scene_state(app->scene_manager, DapSceneConfig)); - - variable_item_list_set_enter_callback(var_item_list, ok_cb, app); - - view_dispatcher_switch_to_view(app->view_dispatcher, DapGuiAppViewVarItemList); -} - -bool dap_scene_config_on_event(void* context, SceneManagerEvent event) { - DapGuiApp* app = context; - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == DapAppCustomEventHelp) { - scene_manager_next_scene(app->scene_manager, DapSceneHelp); - return true; - } else if(event.event == DapAppCustomEventAbout) { - scene_manager_next_scene(app->scene_manager, DapSceneAbout); - return true; - } - } - return false; -} - -void dap_scene_config_on_exit(void* context) { - DapGuiApp* app = context; - scene_manager_set_scene_state( - app->scene_manager, - DapSceneConfig, - variable_item_list_get_selected_item_index(app->var_item_list)); - variable_item_list_reset(app->var_item_list); -} \ No newline at end of file diff --git a/applications/external/dap_link/gui/scenes/dap_scene_help.c b/applications/external/dap_link/gui/scenes/dap_scene_help.c deleted file mode 100644 index d8d70e7ff..000000000 --- a/applications/external/dap_link/gui/scenes/dap_scene_help.c +++ /dev/null @@ -1,102 +0,0 @@ -#include "../dap_gui_i.h" - -void dap_scene_help_on_enter(void* context) { - DapGuiApp* app = context; - DapConfig* config = dap_app_get_config(app->dap_app); - FuriString* string = furi_string_alloc(); - - furi_string_cat(string, "CMSIS DAP/DAP Link v2\r\n"); - furi_string_cat_printf(string, "Serial: %s\r\n", dap_app_get_serial(app->dap_app)); - furi_string_cat( - string, - "Pinout:\r\n" - "\e#SWD:\r\n"); - - switch(config->swd_pins) { - case DapSwdPinsPA7PA6: - furi_string_cat( - string, - " SWC: 2 [A7]\r\n" - " SWD: 3 [A6]\r\n"); - break; - case DapSwdPinsPA14PA13: - furi_string_cat( - string, - " SWC: 10 [SWC]\r\n" - " SWD: 12 [SIO]\r\n"); - break; - default: - break; - } - - furi_string_cat(string, "\e#JTAG:\r\n"); - switch(config->swd_pins) { - case DapSwdPinsPA7PA6: - furi_string_cat( - string, - " TCK: 2 [A7]\r\n" - " TMS: 3 [A6]\r\n" - " RST: 4 [A4]\r\n" - " TDO: 5 [B3]\r\n" - " TDI: 6 [B2]\r\n"); - break; - case DapSwdPinsPA14PA13: - furi_string_cat( - string, - " RST: 4 [A4]\r\n" - " TDO: 5 [B3]\r\n" - " TDI: 6 [B2]\r\n" - " TCK: 10 [SWC]\r\n" - " TMS: 12 [SIO]\r\n"); - break; - default: - break; - } - - furi_string_cat(string, "\e#UART:\r\n"); - switch(config->uart_pins) { - case DapUartTypeUSART1: - if(config->uart_swap == DapUartTXRXNormal) { - furi_string_cat( - string, - " TX: 13 [TX]\r\n" - " RX: 14 [RX]\r\n"); - } else { - furi_string_cat( - string, - " RX: 13 [TX]\r\n" - " TX: 14 [RX]\r\n"); - } - break; - case DapUartTypeLPUART1: - if(config->uart_swap == DapUartTXRXNormal) { - furi_string_cat( - string, - " TX: 15 [C1]\r\n" - " RX: 16 [C0]\r\n"); - } else { - furi_string_cat( - string, - " RX: 15 [C1]\r\n" - " TX: 16 [C0]\r\n"); - } - break; - default: - break; - } - - widget_add_text_scroll_element(app->widget, 0, 0, 128, 64, furi_string_get_cstr(string)); - furi_string_free(string); - view_dispatcher_switch_to_view(app->view_dispatcher, DapGuiAppViewWidget); -} - -bool dap_scene_help_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void dap_scene_help_on_exit(void* context) { - DapGuiApp* app = context; - widget_reset(app->widget); -} \ No newline at end of file diff --git a/applications/external/dap_link/gui/scenes/dap_scene_main.c b/applications/external/dap_link/gui/scenes/dap_scene_main.c deleted file mode 100644 index 8c19bd6a5..000000000 --- a/applications/external/dap_link/gui/scenes/dap_scene_main.c +++ /dev/null @@ -1,154 +0,0 @@ -#include "../dap_gui_i.h" -#include "../../dap_link.h" - -typedef struct { - DapState dap_state; - bool dap_active; - bool tx_active; - bool rx_active; -} DapSceneMainState; - -static bool process_dap_state(DapGuiApp* app) { - DapSceneMainState* state = - (DapSceneMainState*)scene_manager_get_scene_state(app->scene_manager, DapSceneMain); - if(state == NULL) return true; - - DapState* prev_state = &state->dap_state; - DapState next_state; - dap_app_get_state(app->dap_app, &next_state); - bool need_to_update = false; - - if(prev_state->dap_mode != next_state.dap_mode) { - switch(next_state.dap_mode) { - case DapModeDisconnected: - dap_main_view_set_mode(app->main_view, DapMainViewModeDisconnected); - notification_message(app->notifications, &sequence_blink_stop); - break; - case DapModeSWD: - dap_main_view_set_mode(app->main_view, DapMainViewModeSWD); - notification_message(app->notifications, &sequence_blink_start_blue); - break; - case DapModeJTAG: - dap_main_view_set_mode(app->main_view, DapMainViewModeJTAG); - notification_message(app->notifications, &sequence_blink_start_magenta); - break; - } - need_to_update = true; - } - - if(prev_state->dap_version != next_state.dap_version) { - switch(next_state.dap_version) { - case DapVersionUnknown: - dap_main_view_set_version(app->main_view, DapMainViewVersionUnknown); - break; - case DapVersionV1: - dap_main_view_set_version(app->main_view, DapMainViewVersionV1); - break; - case DapVersionV2: - dap_main_view_set_version(app->main_view, DapMainViewVersionV2); - break; - } - need_to_update = true; - } - - if(prev_state->usb_connected != next_state.usb_connected) { - dap_main_view_set_usb_connected(app->main_view, next_state.usb_connected); - need_to_update = true; - } - - if(prev_state->dap_counter != next_state.dap_counter) { - if(!state->dap_active) { - state->dap_active = true; - dap_main_view_set_dap(app->main_view, state->dap_active); - need_to_update = true; - } - } else { - if(state->dap_active) { - state->dap_active = false; - dap_main_view_set_dap(app->main_view, state->dap_active); - need_to_update = true; - } - } - - if(prev_state->cdc_baudrate != next_state.cdc_baudrate) { - dap_main_view_set_baudrate(app->main_view, next_state.cdc_baudrate); - need_to_update = true; - } - - if(prev_state->cdc_tx_counter != next_state.cdc_tx_counter) { - if(!state->tx_active) { - state->tx_active = true; - dap_main_view_set_tx(app->main_view, state->tx_active); - need_to_update = true; - notification_message(app->notifications, &sequence_blink_start_red); - } - } else { - if(state->tx_active) { - state->tx_active = false; - dap_main_view_set_tx(app->main_view, state->tx_active); - need_to_update = true; - notification_message(app->notifications, &sequence_blink_stop); - } - } - - if(prev_state->cdc_rx_counter != next_state.cdc_rx_counter) { - if(!state->rx_active) { - state->rx_active = true; - dap_main_view_set_rx(app->main_view, state->rx_active); - need_to_update = true; - notification_message(app->notifications, &sequence_blink_start_green); - } - } else { - if(state->rx_active) { - state->rx_active = false; - dap_main_view_set_rx(app->main_view, state->rx_active); - need_to_update = true; - notification_message(app->notifications, &sequence_blink_stop); - } - } - - if(need_to_update) { - dap_main_view_update(app->main_view); - } - - *prev_state = next_state; - return true; -} - -static void dap_scene_main_on_left(void* context) { - DapGuiApp* app = (DapGuiApp*)context; - view_dispatcher_send_custom_event(app->view_dispatcher, DapAppCustomEventConfig); -} - -void dap_scene_main_on_enter(void* context) { - DapGuiApp* app = context; - DapSceneMainState* state = malloc(sizeof(DapSceneMainState)); - dap_main_view_set_left_callback(app->main_view, dap_scene_main_on_left, app); - view_dispatcher_switch_to_view(app->view_dispatcher, DapGuiAppViewMainView); - scene_manager_set_scene_state(app->scene_manager, DapSceneMain, (uint32_t)state); -} - -bool dap_scene_main_on_event(void* context, SceneManagerEvent event) { - DapGuiApp* app = context; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == DapAppCustomEventConfig) { - scene_manager_next_scene(app->scene_manager, DapSceneConfig); - return true; - } - } else if(event.type == SceneManagerEventTypeTick) { - return process_dap_state(app); - } - - return false; -} - -void dap_scene_main_on_exit(void* context) { - DapGuiApp* app = context; - DapSceneMainState* state = - (DapSceneMainState*)scene_manager_get_scene_state(app->scene_manager, DapSceneMain); - scene_manager_set_scene_state(app->scene_manager, DapSceneMain, (uint32_t)NULL); - FURI_SW_MEMBARRIER(); - free(state); - notification_message(app->notifications, &sequence_blink_stop); -} \ No newline at end of file diff --git a/applications/external/dap_link/gui/views/dap_main_view.c b/applications/external/dap_link/gui/views/dap_main_view.c deleted file mode 100644 index f54c5e3d5..000000000 --- a/applications/external/dap_link/gui/views/dap_main_view.c +++ /dev/null @@ -1,189 +0,0 @@ -#include "dap_main_view.h" -#include "dap_link_icons.h" -#include - -// extern const Icon I_ArrowDownEmpty_12x18; -// extern const Icon I_ArrowDownFilled_12x18; -// extern const Icon I_ArrowUpEmpty_12x18; -// extern const Icon I_ArrowUpFilled_12x18; - -struct DapMainView { - View* view; - DapMainViewButtonCallback cb_left; - void* cb_context; -}; - -typedef struct { - DapMainViewMode mode; - DapMainViewVersion version; - bool usb_connected; - uint32_t baudrate; - bool dap_active; - bool tx_active; - bool rx_active; -} DapMainViewModel; - -static void dap_main_view_draw_callback(Canvas* canvas, void* _model) { - DapMainViewModel* model = _model; - UNUSED(model); - canvas_clear(canvas); - elements_button_left(canvas, "Config"); - - canvas_set_color(canvas, ColorBlack); - canvas_draw_box(canvas, 0, 0, 127, 11); - canvas_set_color(canvas, ColorWhite); - - const char* header_string; - if(model->usb_connected) { - if(model->version == DapMainViewVersionV1) { - header_string = "DAP Link V1 Connected"; - } else if(model->version == DapMainViewVersionV2) { - header_string = "DAP Link V2 Connected"; - } else { - header_string = "DAP Link Connected"; - } - } else { - header_string = "DAP Link"; - } - - canvas_draw_str_aligned(canvas, 64, 9, AlignCenter, AlignBottom, header_string); - - canvas_set_color(canvas, ColorBlack); - if(model->dap_active) { - canvas_draw_icon(canvas, 14, 16, &I_ArrowUpFilled_12x18); - canvas_draw_icon_ex(canvas, 28, 16, &I_ArrowUpFilled_12x18, IconRotation180); - } else { - canvas_draw_icon(canvas, 14, 16, &I_ArrowUpEmpty_12x18); - canvas_draw_icon_ex(canvas, 28, 16, &I_ArrowUpEmpty_12x18, IconRotation180); - } - - switch(model->mode) { - case DapMainViewModeDisconnected: - canvas_draw_str_aligned(canvas, 26, 38, AlignCenter, AlignTop, "----"); - break; - case DapMainViewModeSWD: - canvas_draw_str_aligned(canvas, 26, 38, AlignCenter, AlignTop, "SWD"); - break; - case DapMainViewModeJTAG: - canvas_draw_str_aligned(canvas, 26, 38, AlignCenter, AlignTop, "JTAG"); - break; - } - - if(model->tx_active) { - canvas_draw_icon(canvas, 87, 16, &I_ArrowUpFilled_12x18); - } else { - canvas_draw_icon(canvas, 87, 16, &I_ArrowUpEmpty_12x18); - } - - if(model->rx_active) { - canvas_draw_icon_ex(canvas, 101, 16, &I_ArrowUpFilled_12x18, IconRotation180); - } else { - canvas_draw_icon_ex(canvas, 101, 16, &I_ArrowUpEmpty_12x18, IconRotation180); - } - - canvas_draw_str_aligned(canvas, 100, 38, AlignCenter, AlignTop, "UART"); - - canvas_draw_line(canvas, 44, 52, 123, 52); - if(model->baudrate == 0) { - canvas_draw_str(canvas, 45, 62, "Baud: ????"); - } else { - char baudrate_str[18]; - snprintf(baudrate_str, 18, "Baud: %lu", model->baudrate); - canvas_draw_str(canvas, 45, 62, baudrate_str); - } -} - -static bool dap_main_view_input_callback(InputEvent* event, void* context) { - furi_assert(context); - DapMainView* dap_main_view = context; - bool consumed = false; - - if(event->type == InputTypeShort) { - if(event->key == InputKeyLeft) { - if(dap_main_view->cb_left) { - dap_main_view->cb_left(dap_main_view->cb_context); - } - consumed = true; - } - } - - return consumed; -} - -DapMainView* dap_main_view_alloc() { - DapMainView* dap_main_view = malloc(sizeof(DapMainView)); - - dap_main_view->view = view_alloc(); - view_allocate_model(dap_main_view->view, ViewModelTypeLocking, sizeof(DapMainViewModel)); - view_set_context(dap_main_view->view, dap_main_view); - view_set_draw_callback(dap_main_view->view, dap_main_view_draw_callback); - view_set_input_callback(dap_main_view->view, dap_main_view_input_callback); - return dap_main_view; -} - -void dap_main_view_free(DapMainView* dap_main_view) { - view_free(dap_main_view->view); - free(dap_main_view); -} - -View* dap_main_view_get_view(DapMainView* dap_main_view) { - return dap_main_view->view; -} - -void dap_main_view_set_left_callback( - DapMainView* dap_main_view, - DapMainViewButtonCallback callback, - void* context) { - with_view_model( - dap_main_view->view, - DapMainViewModel * model, - { - UNUSED(model); - dap_main_view->cb_left = callback; - dap_main_view->cb_context = context; - }, - true); -} - -void dap_main_view_set_mode(DapMainView* dap_main_view, DapMainViewMode mode) { - with_view_model( - dap_main_view->view, DapMainViewModel * model, { model->mode = mode; }, false); -} - -void dap_main_view_set_dap(DapMainView* dap_main_view, bool active) { - with_view_model( - dap_main_view->view, DapMainViewModel * model, { model->dap_active = active; }, false); -} - -void dap_main_view_set_tx(DapMainView* dap_main_view, bool active) { - with_view_model( - dap_main_view->view, DapMainViewModel * model, { model->tx_active = active; }, false); -} - -void dap_main_view_set_rx(DapMainView* dap_main_view, bool active) { - with_view_model( - dap_main_view->view, DapMainViewModel * model, { model->rx_active = active; }, false); -} - -void dap_main_view_set_baudrate(DapMainView* dap_main_view, uint32_t baudrate) { - with_view_model( - dap_main_view->view, DapMainViewModel * model, { model->baudrate = baudrate; }, false); -} - -void dap_main_view_update(DapMainView* dap_main_view) { - with_view_model( - dap_main_view->view, DapMainViewModel * model, { UNUSED(model); }, true); -} - -void dap_main_view_set_version(DapMainView* dap_main_view, DapMainViewVersion version) { - with_view_model( - dap_main_view->view, DapMainViewModel * model, { model->version = version; }, false); -} - -void dap_main_view_set_usb_connected(DapMainView* dap_main_view, bool connected) { - with_view_model( - dap_main_view->view, - DapMainViewModel * model, - { model->usb_connected = connected; }, - false); -} \ No newline at end of file diff --git a/applications/external/dap_link/gui/views/dap_main_view.h b/applications/external/dap_link/gui/views/dap_main_view.h deleted file mode 100644 index 1fd900452..000000000 --- a/applications/external/dap_link/gui/views/dap_main_view.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once -#include - -typedef struct DapMainView DapMainView; - -typedef void (*DapMainViewButtonCallback)(void* context); - -typedef enum { - DapMainViewVersionUnknown, - DapMainViewVersionV1, - DapMainViewVersionV2, -} DapMainViewVersion; - -typedef enum { - DapMainViewModeDisconnected, - DapMainViewModeSWD, - DapMainViewModeJTAG, -} DapMainViewMode; - -DapMainView* dap_main_view_alloc(); - -void dap_main_view_free(DapMainView* dap_main_view); - -View* dap_main_view_get_view(DapMainView* dap_main_view); - -void dap_main_view_set_left_callback( - DapMainView* dap_main_view, - DapMainViewButtonCallback callback, - void* context); - -void dap_main_view_set_mode(DapMainView* dap_main_view, DapMainViewMode mode); - -void dap_main_view_set_version(DapMainView* dap_main_view, DapMainViewVersion version); - -void dap_main_view_set_dap(DapMainView* dap_main_view, bool active); - -void dap_main_view_set_tx(DapMainView* dap_main_view, bool active); - -void dap_main_view_set_rx(DapMainView* dap_main_view, bool active); - -void dap_main_view_set_usb_connected(DapMainView* dap_main_view, bool connected); - -void dap_main_view_set_baudrate(DapMainView* dap_main_view, uint32_t baudrate); - -void dap_main_view_update(DapMainView* dap_main_view); \ No newline at end of file diff --git a/applications/external/dap_link/icons/ActiveConnection_50x64.png b/applications/external/dap_link/icons/ActiveConnection_50x64.png deleted file mode 100644 index 1d7686ddd..000000000 Binary files a/applications/external/dap_link/icons/ActiveConnection_50x64.png and /dev/null differ diff --git a/applications/external/dap_link/icons/ArrowUpEmpty_12x18.png b/applications/external/dap_link/icons/ArrowUpEmpty_12x18.png deleted file mode 100644 index c9365a67d..000000000 Binary files a/applications/external/dap_link/icons/ArrowUpEmpty_12x18.png and /dev/null differ diff --git a/applications/external/dap_link/icons/ArrowUpFilled_12x18.png b/applications/external/dap_link/icons/ArrowUpFilled_12x18.png deleted file mode 100644 index dc481517e..000000000 Binary files a/applications/external/dap_link/icons/ArrowUpFilled_12x18.png and /dev/null differ diff --git a/applications/external/dap_link/lib/free-dap b/applications/external/dap_link/lib/free-dap deleted file mode 160000 index e7752beb5..000000000 --- a/applications/external/dap_link/lib/free-dap +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e7752beb5e8a69119af67b70b9179cb3c90f3ac5 diff --git a/applications/external/dap_link/usb/dap_v2_usb.c b/applications/external/dap_link/usb/dap_v2_usb.c deleted file mode 100644 index cba786648..000000000 --- a/applications/external/dap_link/usb/dap_v2_usb.c +++ /dev/null @@ -1,977 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "dap_v2_usb.h" - -// #define DAP_USB_LOG - -#define HID_EP_IN 0x80 -#define HID_EP_OUT 0x00 - -#define DAP_HID_EP_SEND 1 -#define DAP_HID_EP_RECV 2 -#define DAP_HID_EP_BULK_RECV 3 -#define DAP_HID_EP_BULK_SEND 4 -#define DAP_CDC_EP_COMM 5 -#define DAP_CDC_EP_SEND 6 -#define DAP_CDC_EP_RECV 7 - -#define DAP_HID_EP_IN (HID_EP_IN | DAP_HID_EP_SEND) -#define DAP_HID_EP_OUT (HID_EP_OUT | DAP_HID_EP_RECV) -#define DAP_HID_EP_BULK_IN (HID_EP_IN | DAP_HID_EP_BULK_SEND) -#define DAP_HID_EP_BULK_OUT (HID_EP_OUT | DAP_HID_EP_BULK_RECV) - -#define DAP_HID_EP_SIZE 64 -#define DAP_CDC_COMM_EP_SIZE 8 -#define DAP_CDC_EP_SIZE 64 - -#define DAP_BULK_INTERVAL 0 -#define DAP_HID_INTERVAL 1 -#define DAP_CDC_INTERVAL 0 -#define DAP_CDC_COMM_INTERVAL 1 - -#define DAP_HID_VID 0x0483 -#define DAP_HID_PID 0x5740 - -#define DAP_USB_EP0_SIZE 8 - -#define EP_CFG_DECONFIGURE 0 -#define EP_CFG_CONFIGURE 1 - -enum { - USB_INTF_HID, - USB_INTF_BULK, - USB_INTF_CDC_COMM, - USB_INTF_CDC_DATA, - USB_INTF_COUNT, -}; - -enum { - USB_STR_ZERO, - USB_STR_MANUFACTURER, - USB_STR_PRODUCT, - USB_STR_SERIAL_NUMBER, - USB_STR_CMSIS_DAP_V1, - USB_STR_CMSIS_DAP_V2, - USB_STR_COM_PORT, - USB_STR_COUNT, -}; - -// static const char* usb_str[] = { -// [USB_STR_MANUFACTURER] = "Flipper Devices Inc.", -// [USB_STR_PRODUCT] = "Combined VCP and CMSIS-DAP Adapter", -// [USB_STR_COM_PORT] = "Virtual COM-Port", -// [USB_STR_CMSIS_DAP_V1] = "CMSIS-DAP v1 Adapter", -// [USB_STR_CMSIS_DAP_V2] = "CMSIS-DAP v2 Adapter", -// [USB_STR_SERIAL_NUMBER] = "01234567890ABCDEF", -// }; - -static const struct usb_string_descriptor dev_manuf_descr = - USB_STRING_DESC("Flipper Devices Inc."); - -static const struct usb_string_descriptor dev_prod_descr = - USB_STRING_DESC("Combined VCP and CMSIS-DAP Adapter"); - -static struct usb_string_descriptor* dev_serial_descr = NULL; - -static const struct usb_string_descriptor dev_dap_v1_descr = - USB_STRING_DESC("CMSIS-DAP v1 Adapter"); - -static const struct usb_string_descriptor dev_dap_v2_descr = - USB_STRING_DESC("CMSIS-DAP v2 Adapter"); - -static const struct usb_string_descriptor dev_com_descr = USB_STRING_DESC("Virtual COM-Port"); - -struct HidConfigDescriptor { - struct usb_config_descriptor configuration; - - // CMSIS-DAP v1 - struct usb_interface_descriptor hid_interface; - struct usb_hid_descriptor hid; - struct usb_endpoint_descriptor hid_ep_in; - struct usb_endpoint_descriptor hid_ep_out; - - // CMSIS-DAP v2 - struct usb_interface_descriptor bulk_interface; - struct usb_endpoint_descriptor bulk_ep_out; - struct usb_endpoint_descriptor bulk_ep_in; - - // CDC - struct usb_iad_descriptor iad; - struct usb_interface_descriptor interface_comm; - struct usb_cdc_header_desc cdc_header; - struct usb_cdc_call_mgmt_desc cdc_acm; - struct usb_cdc_acm_desc cdc_call_mgmt; - struct usb_cdc_union_desc cdc_union; - struct usb_endpoint_descriptor ep_comm; - struct usb_interface_descriptor interface_data; - struct usb_endpoint_descriptor ep_in; - struct usb_endpoint_descriptor ep_out; - -} __attribute__((packed)); - -static const struct usb_device_descriptor hid_device_desc = { - .bLength = sizeof(struct usb_device_descriptor), - .bDescriptorType = USB_DTYPE_DEVICE, - .bcdUSB = VERSION_BCD(2, 1, 0), - .bDeviceClass = USB_CLASS_MISC, - .bDeviceSubClass = USB_SUBCLASS_IAD, - .bDeviceProtocol = USB_PROTO_IAD, - .bMaxPacketSize0 = DAP_USB_EP0_SIZE, - .idVendor = DAP_HID_VID, - .idProduct = DAP_HID_PID, - .bcdDevice = VERSION_BCD(1, 0, 0), - .iManufacturer = USB_STR_MANUFACTURER, - .iProduct = USB_STR_PRODUCT, - .iSerialNumber = USB_STR_SERIAL_NUMBER, - .bNumConfigurations = 1, -}; - -static const uint8_t hid_report_desc[] = { - 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) - 0x09, 0x00, // Usage (Undefined) - 0xa1, 0x01, // Collection (Application) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xff, 0x00, // Logical Maximum (255) - 0x75, 0x08, // Report Size (8) - 0x95, 0x40, // Report Count (64) - 0x09, 0x00, // Usage (Undefined) - 0x81, 0x82, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0x75, 0x08, // Report Size (8) - 0x95, 0x40, // Report Count (64) - 0x09, 0x00, // Usage (Undefined) - 0x91, 0x82, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Volatile) - 0xc0, // End Collection -}; - -static const struct HidConfigDescriptor hid_cfg_desc = { - .configuration = - { - .bLength = sizeof(struct usb_config_descriptor), - .bDescriptorType = USB_DTYPE_CONFIGURATION, - .wTotalLength = sizeof(struct HidConfigDescriptor), - .bNumInterfaces = USB_INTF_COUNT, - .bConfigurationValue = 1, - .iConfiguration = NO_DESCRIPTOR, - .bmAttributes = USB_CFG_ATTR_RESERVED, - .bMaxPower = USB_CFG_POWER_MA(500), - }, - - // CMSIS-DAP v1 - .hid_interface = - { - .bLength = sizeof(struct usb_interface_descriptor), - .bDescriptorType = USB_DTYPE_INTERFACE, - .bInterfaceNumber = USB_INTF_HID, - .bAlternateSetting = 0, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_HID, - .bInterfaceSubClass = USB_HID_SUBCLASS_NONBOOT, - .bInterfaceProtocol = USB_HID_PROTO_NONBOOT, - .iInterface = USB_STR_CMSIS_DAP_V1, - }, - - .hid = - { - .bLength = sizeof(struct usb_hid_descriptor), - .bDescriptorType = USB_DTYPE_HID, - .bcdHID = VERSION_BCD(1, 1, 1), - .bCountryCode = USB_HID_COUNTRY_NONE, - .bNumDescriptors = 1, - .bDescriptorType0 = USB_DTYPE_HID_REPORT, - .wDescriptorLength0 = sizeof(hid_report_desc), - }, - - .hid_ep_in = - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DTYPE_ENDPOINT, - .bEndpointAddress = DAP_HID_EP_IN, - .bmAttributes = USB_EPTYPE_INTERRUPT, - .wMaxPacketSize = DAP_HID_EP_SIZE, - .bInterval = DAP_HID_INTERVAL, - }, - - .hid_ep_out = - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DTYPE_ENDPOINT, - .bEndpointAddress = DAP_HID_EP_OUT, - .bmAttributes = USB_EPTYPE_INTERRUPT, - .wMaxPacketSize = DAP_HID_EP_SIZE, - .bInterval = DAP_HID_INTERVAL, - }, - - // CMSIS-DAP v2 - .bulk_interface = - { - .bLength = sizeof(struct usb_interface_descriptor), - .bDescriptorType = USB_DTYPE_INTERFACE, - .bInterfaceNumber = USB_INTF_BULK, - .bAlternateSetting = 0, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_VENDOR, - .bInterfaceSubClass = 0, - .bInterfaceProtocol = 0, - .iInterface = USB_STR_CMSIS_DAP_V2, - }, - - .bulk_ep_out = - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DTYPE_ENDPOINT, - .bEndpointAddress = DAP_HID_EP_BULK_OUT, - .bmAttributes = USB_EPTYPE_BULK, - .wMaxPacketSize = DAP_HID_EP_SIZE, - .bInterval = DAP_BULK_INTERVAL, - }, - - .bulk_ep_in = - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DTYPE_ENDPOINT, - .bEndpointAddress = DAP_HID_EP_BULK_IN, - .bmAttributes = USB_EPTYPE_BULK, - .wMaxPacketSize = DAP_HID_EP_SIZE, - .bInterval = DAP_BULK_INTERVAL, - }, - - // CDC - .iad = - { - .bLength = sizeof(struct usb_iad_descriptor), - .bDescriptorType = USB_DTYPE_INTERFASEASSOC, - .bFirstInterface = USB_INTF_CDC_COMM, - .bInterfaceCount = 2, - .bFunctionClass = USB_CLASS_CDC, - .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, - .bFunctionProtocol = USB_PROTO_NONE, - .iFunction = USB_STR_COM_PORT, - }, - .interface_comm = - { - .bLength = sizeof(struct usb_interface_descriptor), - .bDescriptorType = USB_DTYPE_INTERFACE, - .bInterfaceNumber = USB_INTF_CDC_COMM, - .bAlternateSetting = 0, - .bNumEndpoints = 1, - .bInterfaceClass = USB_CLASS_CDC, - .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, - .bInterfaceProtocol = USB_PROTO_NONE, - .iInterface = 0, - }, - - .cdc_header = - { - .bFunctionLength = sizeof(struct usb_cdc_header_desc), - .bDescriptorType = USB_DTYPE_CS_INTERFACE, - .bDescriptorSubType = USB_DTYPE_CDC_HEADER, - .bcdCDC = VERSION_BCD(1, 1, 0), - }, - - .cdc_acm = - { - .bFunctionLength = sizeof(struct usb_cdc_call_mgmt_desc), - .bDescriptorType = USB_DTYPE_CS_INTERFACE, - .bDescriptorSubType = USB_DTYPE_CDC_CALL_MANAGEMENT, - // .bmCapabilities = USB_CDC_CAP_LINE | USB_CDC_CAP_BRK, - .bmCapabilities = 0, - }, - - .cdc_call_mgmt = - { - .bFunctionLength = sizeof(struct usb_cdc_acm_desc), - .bDescriptorType = USB_DTYPE_CS_INTERFACE, - .bDescriptorSubType = USB_DTYPE_CDC_ACM, - .bmCapabilities = USB_CDC_CALL_MGMT_CAP_DATA_INTF, - // .bDataInterface = USB_INTF_CDC_DATA, - }, - - .cdc_union = - { - .bFunctionLength = sizeof(struct usb_cdc_union_desc), - .bDescriptorType = USB_DTYPE_CS_INTERFACE, - .bDescriptorSubType = USB_DTYPE_CDC_UNION, - .bMasterInterface0 = USB_INTF_CDC_COMM, - .bSlaveInterface0 = USB_INTF_CDC_DATA, - }, - - .ep_comm = - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DTYPE_ENDPOINT, - .bEndpointAddress = HID_EP_IN | DAP_CDC_EP_COMM, - .bmAttributes = USB_EPTYPE_INTERRUPT, - .wMaxPacketSize = DAP_CDC_COMM_EP_SIZE, - .bInterval = DAP_CDC_COMM_INTERVAL, - }, - - .interface_data = - { - .bLength = sizeof(struct usb_interface_descriptor), - .bDescriptorType = USB_DTYPE_INTERFACE, - .bInterfaceNumber = USB_INTF_CDC_DATA, - .bAlternateSetting = 0, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_CDC_DATA, - .bInterfaceSubClass = USB_SUBCLASS_NONE, - .bInterfaceProtocol = USB_PROTO_NONE, - .iInterface = NO_DESCRIPTOR, - }, - - .ep_in = - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DTYPE_ENDPOINT, - .bEndpointAddress = HID_EP_IN | DAP_CDC_EP_SEND, - .bmAttributes = USB_EPTYPE_BULK, - .wMaxPacketSize = DAP_CDC_EP_SIZE, - .bInterval = DAP_CDC_INTERVAL, - }, - - .ep_out = - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DTYPE_ENDPOINT, - .bEndpointAddress = HID_EP_OUT | DAP_CDC_EP_RECV, - .bmAttributes = USB_EPTYPE_BULK, - .wMaxPacketSize = DAP_CDC_EP_SIZE, - .bInterval = DAP_CDC_INTERVAL, - }, -}; - -// WinUSB -#include "usb_winusb.h" - -typedef struct USB_PACK { - usb_binary_object_store_descriptor_t bos; - usb_winusb_capability_descriptor_t winusb; -} usb_bos_hierarchy_t; - -typedef struct USB_PACK { - usb_winusb_subset_header_function_t header; - usb_winusb_feature_compatble_id_t comp_id; - usb_winusb_feature_reg_property_guids_t property; -} usb_msos_descriptor_subset_t; - -typedef struct USB_PACK { - usb_winusb_set_header_descriptor_t header; - usb_msos_descriptor_subset_t subset; -} usb_msos_descriptor_set_t; - -#define USB_DTYPE_BINARY_OBJECT_STORE 15 -#define USB_DTYPE_DEVICE_CAPABILITY_DESCRIPTOR 16 -#define USB_DC_TYPE_PLATFORM 5 - -const usb_bos_hierarchy_t usb_bos_hierarchy = { - .bos = - { - .bLength = sizeof(usb_binary_object_store_descriptor_t), - .bDescriptorType = USB_DTYPE_BINARY_OBJECT_STORE, - .wTotalLength = sizeof(usb_bos_hierarchy_t), - .bNumDeviceCaps = 1, - }, - .winusb = - { - .bLength = sizeof(usb_winusb_capability_descriptor_t), - .bDescriptorType = USB_DTYPE_DEVICE_CAPABILITY_DESCRIPTOR, - .bDevCapabilityType = USB_DC_TYPE_PLATFORM, - .bReserved = 0, - .PlatformCapabilityUUID = USB_WINUSB_PLATFORM_CAPABILITY_ID, - .dwWindowsVersion = USB_WINUSB_WINDOWS_VERSION, - .wMSOSDescriptorSetTotalLength = sizeof(usb_msos_descriptor_set_t), - .bMS_VendorCode = USB_WINUSB_VENDOR_CODE, - .bAltEnumCode = 0, - }, -}; - -const usb_msos_descriptor_set_t usb_msos_descriptor_set = { - .header = - { - .wLength = sizeof(usb_winusb_set_header_descriptor_t), - .wDescriptorType = USB_WINUSB_SET_HEADER_DESCRIPTOR, - .dwWindowsVersion = USB_WINUSB_WINDOWS_VERSION, - .wDescriptorSetTotalLength = sizeof(usb_msos_descriptor_set_t), - }, - - .subset = - { - .header = - { - .wLength = sizeof(usb_winusb_subset_header_function_t), - .wDescriptorType = USB_WINUSB_SUBSET_HEADER_FUNCTION, - .bFirstInterface = USB_INTF_BULK, - .bReserved = 0, - .wSubsetLength = sizeof(usb_msos_descriptor_subset_t), - }, - - .comp_id = - { - .wLength = sizeof(usb_winusb_feature_compatble_id_t), - .wDescriptorType = USB_WINUSB_FEATURE_COMPATBLE_ID, - .CompatibleID = "WINUSB\0\0", - .SubCompatibleID = {0}, - }, - - .property = - { - .wLength = sizeof(usb_winusb_feature_reg_property_guids_t), - .wDescriptorType = USB_WINUSB_FEATURE_REG_PROPERTY, - .wPropertyDataType = USB_WINUSB_PROPERTY_DATA_TYPE_MULTI_SZ, - .wPropertyNameLength = - sizeof(usb_msos_descriptor_set.subset.property.PropertyName), - .PropertyName = {'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, 'I', 0, - 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, - 'e', 0, 'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0}, - .wPropertyDataLength = - sizeof(usb_msos_descriptor_set.subset.property.PropertyData), - .PropertyData = {'{', 0, 'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, - 'A', 0, 'D', 0, '-', 0, '2', 0, '9', 0, '3', 0, 'B', 0, - '-', 0, '4', 0, '6', 0, '6', 0, '3', 0, '-', 0, 'A', 0, - 'A', 0, '3', 0, '6', 0, '-', 0, '1', 0, 'A', 0, 'A', 0, - 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, - '7', 0, '6', 0, '}', 0, 0, 0, 0, 0}, - }, - }, -}; - -typedef struct { - FuriSemaphore* semaphore_v1; - FuriSemaphore* semaphore_v2; - FuriSemaphore* semaphore_cdc; - bool connected; - usbd_device* usb_dev; - DapStateCallback state_callback; - DapRxCallback rx_callback_v1; - DapRxCallback rx_callback_v2; - DapRxCallback rx_callback_cdc; - DapCDCControlLineCallback control_line_callback_cdc; - DapCDCConfigCallback config_callback_cdc; - void* context; - void* context_cdc; -} DAPState; - -static DAPState dap_state = { - .semaphore_v1 = NULL, - .semaphore_v2 = NULL, - .semaphore_cdc = NULL, - .connected = false, - .usb_dev = NULL, - .state_callback = NULL, - .rx_callback_v1 = NULL, - .rx_callback_v2 = NULL, - .rx_callback_cdc = NULL, - .control_line_callback_cdc = NULL, - .config_callback_cdc = NULL, - .context = NULL, - .context_cdc = NULL, -}; - -static struct usb_cdc_line_coding cdc_config = {0}; -static uint8_t cdc_ctrl_line_state = 0; - -#ifdef DAP_USB_LOG -void furi_console_log_printf(const char* format, ...) _ATTRIBUTE((__format__(__printf__, 1, 2))); - -void furi_console_log_printf(const char* format, ...) { - char buffer[256]; - va_list args; - va_start(args, format); - vsnprintf(buffer, sizeof(buffer), format, args); - va_end(args); - furi_hal_console_puts(buffer); - furi_hal_console_puts("\r\n"); - UNUSED(format); -} -#else -#define furi_console_log_printf(...) -#endif - -int32_t dap_v1_usb_tx(uint8_t* buffer, uint8_t size) { - if((dap_state.semaphore_v1 == NULL) || (dap_state.connected == false)) return 0; - - furi_check(furi_semaphore_acquire(dap_state.semaphore_v1, FuriWaitForever) == FuriStatusOk); - - if(dap_state.connected) { - int32_t len = usbd_ep_write(dap_state.usb_dev, DAP_HID_EP_IN, buffer, size); - furi_console_log_printf("v1 tx %ld", len); - return len; - } else { - return 0; - } -} - -int32_t dap_v2_usb_tx(uint8_t* buffer, uint8_t size) { - if((dap_state.semaphore_v2 == NULL) || (dap_state.connected == false)) return 0; - - furi_check(furi_semaphore_acquire(dap_state.semaphore_v2, FuriWaitForever) == FuriStatusOk); - - if(dap_state.connected) { - int32_t len = usbd_ep_write(dap_state.usb_dev, DAP_HID_EP_BULK_IN, buffer, size); - furi_console_log_printf("v2 tx %ld", len); - return len; - } else { - return 0; - } -} - -int32_t dap_cdc_usb_tx(uint8_t* buffer, uint8_t size) { - if((dap_state.semaphore_cdc == NULL) || (dap_state.connected == false)) return 0; - - furi_check(furi_semaphore_acquire(dap_state.semaphore_cdc, FuriWaitForever) == FuriStatusOk); - - if(dap_state.connected) { - int32_t len = usbd_ep_write(dap_state.usb_dev, HID_EP_IN | DAP_CDC_EP_SEND, buffer, size); - furi_console_log_printf("cdc tx %ld", len); - return len; - } else { - return 0; - } -} - -void dap_v1_usb_set_rx_callback(DapRxCallback callback) { - dap_state.rx_callback_v1 = callback; -} - -void dap_v2_usb_set_rx_callback(DapRxCallback callback) { - dap_state.rx_callback_v2 = callback; -} - -void dap_cdc_usb_set_rx_callback(DapRxCallback callback) { - dap_state.rx_callback_cdc = callback; -} - -void dap_cdc_usb_set_control_line_callback(DapCDCControlLineCallback callback) { - dap_state.control_line_callback_cdc = callback; -} - -void dap_cdc_usb_set_config_callback(DapCDCConfigCallback callback) { - dap_state.config_callback_cdc = callback; -} - -void dap_cdc_usb_set_context(void* context) { - dap_state.context_cdc = context; -} - -void dap_common_usb_set_context(void* context) { - dap_state.context = context; -} - -void dap_common_usb_set_state_callback(DapStateCallback callback) { - dap_state.state_callback = callback; -} - -static void* dap_usb_alloc_string_descr(const char* str) { - furi_assert(str); - - size_t len = strlen(str); - size_t wlen = (len + 1) * sizeof(uint16_t); - struct usb_string_descriptor* dev_str_desc = malloc(wlen); - dev_str_desc->bLength = wlen; - dev_str_desc->bDescriptorType = USB_DTYPE_STRING; - for(size_t i = 0; i < len; i++) { - dev_str_desc->wString[i] = str[i]; - } - - return dev_str_desc; -} - -void dap_common_usb_alloc_name(const char* name) { - dev_serial_descr = dap_usb_alloc_string_descr(name); -} - -void dap_common_usb_free_name() { - free(dev_serial_descr); -} - -static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx); -static void hid_deinit(usbd_device* dev); -static void hid_on_wakeup(usbd_device* dev); -static void hid_on_suspend(usbd_device* dev); - -static usbd_respond hid_ep_config(usbd_device* dev, uint8_t cfg); -static usbd_respond hid_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback); - -FuriHalUsbInterface dap_v2_usb_hid = { - .init = hid_init, - .deinit = hid_deinit, - .wakeup = hid_on_wakeup, - .suspend = hid_on_suspend, - .dev_descr = (struct usb_device_descriptor*)&hid_device_desc, - .cfg_descr = (void*)&hid_cfg_desc, -}; - -static void hid_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) { - UNUSED(intf); - UNUSED(ctx); - - dap_v2_usb_hid.str_manuf_descr = (void*)&dev_manuf_descr; - dap_v2_usb_hid.str_prod_descr = (void*)&dev_prod_descr; - dap_v2_usb_hid.str_serial_descr = (void*)dev_serial_descr; - - dap_state.usb_dev = dev; - if(dap_state.semaphore_v1 == NULL) dap_state.semaphore_v1 = furi_semaphore_alloc(1, 1); - if(dap_state.semaphore_v2 == NULL) dap_state.semaphore_v2 = furi_semaphore_alloc(1, 1); - if(dap_state.semaphore_cdc == NULL) dap_state.semaphore_cdc = furi_semaphore_alloc(1, 1); - - usbd_reg_config(dev, hid_ep_config); - usbd_reg_control(dev, hid_control); - - usbd_connect(dev, true); -} - -static void hid_deinit(usbd_device* dev) { - dap_state.usb_dev = NULL; - - furi_semaphore_free(dap_state.semaphore_v1); - furi_semaphore_free(dap_state.semaphore_v2); - furi_semaphore_free(dap_state.semaphore_cdc); - dap_state.semaphore_v1 = NULL; - dap_state.semaphore_v2 = NULL; - dap_state.semaphore_cdc = NULL; - - usbd_reg_config(dev, NULL); - usbd_reg_control(dev, NULL); -} - -static void hid_on_wakeup(usbd_device* dev) { - UNUSED(dev); - if(!dap_state.connected) { - dap_state.connected = true; - if(dap_state.state_callback != NULL) { - dap_state.state_callback(dap_state.connected, dap_state.context); - } - } -} - -static void hid_on_suspend(usbd_device* dev) { - UNUSED(dev); - if(dap_state.connected) { - dap_state.connected = false; - if(dap_state.state_callback != NULL) { - dap_state.state_callback(dap_state.connected, dap_state.context); - } - } -} - -size_t dap_v1_usb_rx(uint8_t* buffer, size_t size) { - size_t len = 0; - - if(dap_state.connected) { - len = usbd_ep_read(dap_state.usb_dev, DAP_HID_EP_OUT, buffer, size); - } - - return len; -} - -size_t dap_v2_usb_rx(uint8_t* buffer, size_t size) { - size_t len = 0; - - if(dap_state.connected) { - len = usbd_ep_read(dap_state.usb_dev, DAP_HID_EP_BULK_OUT, buffer, size); - } - - return len; -} - -size_t dap_cdc_usb_rx(uint8_t* buffer, size_t size) { - size_t len = 0; - - if(dap_state.connected) { - len = usbd_ep_read(dap_state.usb_dev, HID_EP_OUT | DAP_CDC_EP_RECV, buffer, size); - } - - return len; -} - -static void hid_txrx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) { - UNUSED(dev); - UNUSED(ep); - - switch(event) { - case usbd_evt_eptx: - furi_semaphore_release(dap_state.semaphore_v1); - furi_console_log_printf("hid tx complete"); - break; - case usbd_evt_eprx: - if(dap_state.rx_callback_v1 != NULL) { - dap_state.rx_callback_v1(dap_state.context); - } - break; - default: - furi_console_log_printf("hid %d, %d", event, ep); - break; - } -} - -static void hid_txrx_ep_bulk_callback(usbd_device* dev, uint8_t event, uint8_t ep) { - UNUSED(dev); - UNUSED(ep); - - switch(event) { - case usbd_evt_eptx: - furi_semaphore_release(dap_state.semaphore_v2); - furi_console_log_printf("bulk tx complete"); - break; - case usbd_evt_eprx: - if(dap_state.rx_callback_v2 != NULL) { - dap_state.rx_callback_v2(dap_state.context); - } - break; - default: - furi_console_log_printf("bulk %d, %d", event, ep); - break; - } -} - -static void cdc_txrx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) { - UNUSED(dev); - UNUSED(ep); - - switch(event) { - case usbd_evt_eptx: - furi_semaphore_release(dap_state.semaphore_cdc); - furi_console_log_printf("cdc tx complete"); - break; - case usbd_evt_eprx: - if(dap_state.rx_callback_cdc != NULL) { - dap_state.rx_callback_cdc(dap_state.context_cdc); - } - break; - default: - furi_console_log_printf("cdc %d, %d", event, ep); - break; - } -} - -static usbd_respond hid_ep_config(usbd_device* dev, uint8_t cfg) { - switch(cfg) { - case EP_CFG_DECONFIGURE: - usbd_ep_deconfig(dev, DAP_HID_EP_OUT); - usbd_ep_deconfig(dev, DAP_HID_EP_IN); - usbd_ep_deconfig(dev, DAP_HID_EP_BULK_IN); - usbd_ep_deconfig(dev, DAP_HID_EP_BULK_OUT); - usbd_ep_deconfig(dev, HID_EP_IN | DAP_CDC_EP_COMM); - usbd_ep_deconfig(dev, HID_EP_IN | DAP_CDC_EP_SEND); - usbd_ep_deconfig(dev, HID_EP_OUT | DAP_CDC_EP_RECV); - usbd_reg_endpoint(dev, DAP_HID_EP_OUT, NULL); - usbd_reg_endpoint(dev, DAP_HID_EP_IN, NULL); - usbd_reg_endpoint(dev, DAP_HID_EP_BULK_IN, NULL); - usbd_reg_endpoint(dev, DAP_HID_EP_BULK_OUT, NULL); - usbd_reg_endpoint(dev, HID_EP_IN | DAP_CDC_EP_SEND, 0); - usbd_reg_endpoint(dev, HID_EP_OUT | DAP_CDC_EP_RECV, 0); - return usbd_ack; - case EP_CFG_CONFIGURE: - usbd_ep_config(dev, DAP_HID_EP_IN, USB_EPTYPE_INTERRUPT, DAP_HID_EP_SIZE); - usbd_ep_config(dev, DAP_HID_EP_OUT, USB_EPTYPE_INTERRUPT, DAP_HID_EP_SIZE); - usbd_ep_config(dev, DAP_HID_EP_BULK_OUT, USB_EPTYPE_BULK, DAP_HID_EP_SIZE); - usbd_ep_config(dev, DAP_HID_EP_BULK_IN, USB_EPTYPE_BULK, DAP_HID_EP_SIZE); - usbd_ep_config(dev, HID_EP_OUT | DAP_CDC_EP_RECV, USB_EPTYPE_BULK, DAP_CDC_EP_SIZE); - usbd_ep_config(dev, HID_EP_IN | DAP_CDC_EP_SEND, USB_EPTYPE_BULK, DAP_CDC_EP_SIZE); - usbd_ep_config(dev, HID_EP_IN | DAP_CDC_EP_COMM, USB_EPTYPE_INTERRUPT, DAP_CDC_EP_SIZE); - usbd_reg_endpoint(dev, DAP_HID_EP_IN, hid_txrx_ep_callback); - usbd_reg_endpoint(dev, DAP_HID_EP_OUT, hid_txrx_ep_callback); - usbd_reg_endpoint(dev, DAP_HID_EP_BULK_OUT, hid_txrx_ep_bulk_callback); - usbd_reg_endpoint(dev, DAP_HID_EP_BULK_IN, hid_txrx_ep_bulk_callback); - usbd_reg_endpoint(dev, HID_EP_OUT | DAP_CDC_EP_RECV, cdc_txrx_ep_callback); - usbd_reg_endpoint(dev, HID_EP_IN | DAP_CDC_EP_SEND, cdc_txrx_ep_callback); - // usbd_ep_write(dev, DAP_HID_EP_IN, NULL, 0); - // usbd_ep_write(dev, DAP_HID_EP_BULK_IN, NULL, 0); - // usbd_ep_write(dev, HID_EP_IN | DAP_CDC_EP_SEND, NULL, 0); - return usbd_ack; - default: - return usbd_fail; - } -} - -#ifdef DAP_USB_LOG -static void dump_request_type(uint8_t type) { - switch(type & USB_REQ_DIRECTION) { - case USB_REQ_HOSTTODEV: - furi_hal_console_puts("host to dev, "); - break; - case USB_REQ_DEVTOHOST: - furi_hal_console_puts("dev to host, "); - break; - } - - switch(type & USB_REQ_TYPE) { - case USB_REQ_STANDARD: - furi_hal_console_puts("standard, "); - break; - case USB_REQ_CLASS: - furi_hal_console_puts("class, "); - break; - case USB_REQ_VENDOR: - furi_hal_console_puts("vendor, "); - break; - } - - switch(type & USB_REQ_RECIPIENT) { - case USB_REQ_DEVICE: - furi_hal_console_puts("device"); - break; - case USB_REQ_INTERFACE: - furi_hal_console_puts("interface"); - break; - case USB_REQ_ENDPOINT: - furi_hal_console_puts("endpoint"); - break; - case USB_REQ_OTHER: - furi_hal_console_puts("other"); - break; - } - - furi_hal_console_puts("\r\n"); -} -#else -#define dump_request_type(...) -#endif - -static usbd_respond hid_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback) { - UNUSED(callback); - - dump_request_type(req->bmRequestType); - furi_console_log_printf( - "control: RT %02x, R %02x, V %04x, I %04x, L %04x", - req->bmRequestType, - req->bRequest, - req->wValue, - req->wIndex, - req->wLength); - - if(((USB_REQ_RECIPIENT | USB_REQ_TYPE | USB_REQ_DIRECTION) & req->bmRequestType) == - (USB_REQ_STANDARD | USB_REQ_VENDOR | USB_REQ_DEVTOHOST)) { - // vendor request, device to host - furi_console_log_printf("vendor request"); - if(USB_WINUSB_VENDOR_CODE == req->bRequest) { - // WINUSB request - if(USB_WINUSB_DESCRIPTOR_INDEX == req->wIndex) { - furi_console_log_printf("WINUSB descriptor"); - uint16_t length = req->wLength; - if(length > sizeof(usb_msos_descriptor_set_t)) { - length = sizeof(usb_msos_descriptor_set_t); - } - - dev->status.data_ptr = (uint8_t*)&usb_msos_descriptor_set; - dev->status.data_count = length; - return usbd_ack; - } - } - } - - if(((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) == - (USB_REQ_STANDARD | USB_REQ_DEVICE)) { - // device request - if(req->bRequest == USB_STD_GET_DESCRIPTOR) { - const uint8_t dtype = req->wValue >> 8; - const uint8_t dnumber = req->wValue & 0xFF; - // get string descriptor - if(USB_DTYPE_STRING == dtype) { - if(dnumber == USB_STR_CMSIS_DAP_V1) { - furi_console_log_printf("str CMSIS-DAP v1"); - dev->status.data_ptr = (uint8_t*)&dev_dap_v1_descr; - dev->status.data_count = dev_dap_v1_descr.bLength; - return usbd_ack; - } else if(dnumber == USB_STR_CMSIS_DAP_V2) { - furi_console_log_printf("str CMSIS-DAP v2"); - dev->status.data_ptr = (uint8_t*)&dev_dap_v2_descr; - dev->status.data_count = dev_dap_v2_descr.bLength; - return usbd_ack; - } else if(dnumber == USB_STR_COM_PORT) { - furi_console_log_printf("str COM port"); - dev->status.data_ptr = (uint8_t*)&dev_com_descr; - dev->status.data_count = dev_com_descr.bLength; - return usbd_ack; - } - } else if(USB_DTYPE_BINARY_OBJECT_STORE == dtype) { - furi_console_log_printf("BOS descriptor"); - uint16_t length = req->wLength; - if(length > sizeof(usb_bos_hierarchy_t)) { - length = sizeof(usb_bos_hierarchy_t); - } - dev->status.data_ptr = (uint8_t*)&usb_bos_hierarchy; - dev->status.data_count = length; - return usbd_ack; - } - } - } - - if(((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) == - (USB_REQ_INTERFACE | USB_REQ_CLASS) && - req->wIndex == 0) { - // class request - switch(req->bRequest) { - // get hid descriptor - case USB_HID_GETREPORT: - furi_console_log_printf("get report"); - return usbd_fail; - // set hid idle - case USB_HID_SETIDLE: - furi_console_log_printf("set idle"); - return usbd_ack; - default: - break; - } - } - - if(((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) == - (USB_REQ_INTERFACE | USB_REQ_CLASS) && - req->wIndex == 2) { - // class request - switch(req->bRequest) { - // control line state - case USB_CDC_SET_CONTROL_LINE_STATE: - furi_console_log_printf("set control line state"); - cdc_ctrl_line_state = req->wValue; - if(dap_state.control_line_callback_cdc != NULL) { - dap_state.control_line_callback_cdc(cdc_ctrl_line_state, dap_state.context_cdc); - } - return usbd_ack; - // set cdc line coding - case USB_CDC_SET_LINE_CODING: - furi_console_log_printf("set line coding"); - memcpy(&cdc_config, req->data, sizeof(cdc_config)); - if(dap_state.config_callback_cdc != NULL) { - dap_state.config_callback_cdc(&cdc_config, dap_state.context_cdc); - } - return usbd_ack; - // get cdc line coding - case USB_CDC_GET_LINE_CODING: - furi_console_log_printf("get line coding"); - dev->status.data_ptr = &cdc_config; - dev->status.data_count = sizeof(cdc_config); - return usbd_ack; - default: - break; - } - } - - if(((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) == - (USB_REQ_INTERFACE | USB_REQ_STANDARD) && - req->wIndex == 0 && req->bRequest == USB_STD_GET_DESCRIPTOR) { - // standard request - switch(req->wValue >> 8) { - // get hid descriptor - case USB_DTYPE_HID: - furi_console_log_printf("get hid descriptor"); - dev->status.data_ptr = (uint8_t*)&(hid_cfg_desc.hid); - dev->status.data_count = sizeof(hid_cfg_desc.hid); - return usbd_ack; - // get hid report descriptor - case USB_DTYPE_HID_REPORT: - furi_console_log_printf("get hid report descriptor"); - dev->status.data_ptr = (uint8_t*)hid_report_desc; - dev->status.data_count = sizeof(hid_report_desc); - return usbd_ack; - default: - break; - } - } - - return usbd_fail; -} diff --git a/applications/external/dap_link/usb/dap_v2_usb.h b/applications/external/dap_link/usb/dap_v2_usb.h deleted file mode 100644 index 3f1534ffd..000000000 --- a/applications/external/dap_link/usb/dap_v2_usb.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once -#include -#include - -extern FuriHalUsbInterface dap_v2_usb_hid; - -// receive callback type -typedef void (*DapRxCallback)(void* context); - -typedef void (*DapStateCallback)(bool state, void* context); - -/************************************ V1 ***************************************/ - -int32_t dap_v1_usb_tx(uint8_t* buffer, uint8_t size); - -size_t dap_v1_usb_rx(uint8_t* buffer, size_t size); - -void dap_v1_usb_set_rx_callback(DapRxCallback callback); - -/************************************ V2 ***************************************/ - -int32_t dap_v2_usb_tx(uint8_t* buffer, uint8_t size); - -size_t dap_v2_usb_rx(uint8_t* buffer, size_t size); - -void dap_v2_usb_set_rx_callback(DapRxCallback callback); - -/************************************ CDC **************************************/ - -typedef void (*DapCDCControlLineCallback)(uint8_t state, void* context); -typedef void (*DapCDCConfigCallback)(struct usb_cdc_line_coding* config, void* context); - -int32_t dap_cdc_usb_tx(uint8_t* buffer, uint8_t size); - -size_t dap_cdc_usb_rx(uint8_t* buffer, size_t size); - -void dap_cdc_usb_set_rx_callback(DapRxCallback callback); - -void dap_cdc_usb_set_control_line_callback(DapCDCControlLineCallback callback); - -void dap_cdc_usb_set_config_callback(DapCDCConfigCallback callback); - -void dap_cdc_usb_set_context(void* context); - -/*********************************** Common ************************************/ - -void dap_common_usb_set_context(void* context); - -void dap_common_usb_set_state_callback(DapStateCallback callback); - -void dap_common_usb_alloc_name(const char* name); - -void dap_common_usb_free_name(); diff --git a/applications/external/dap_link/usb/usb_winusb.h b/applications/external/dap_link/usb/usb_winusb.h deleted file mode 100644 index 9c3a172dc..000000000 --- a/applications/external/dap_link/usb/usb_winusb.h +++ /dev/null @@ -1,143 +0,0 @@ -#pragma once -#include - -/*- Definitions -------------------------------------------------------------*/ - -#define USB_PACK __attribute__((packed)) - -#define USB_WINUSB_VENDOR_CODE 0x20 - -#define USB_WINUSB_WINDOWS_VERSION 0x06030000 // Windows 8.1 - -#define USB_WINUSB_PLATFORM_CAPABILITY_ID \ - { \ - 0xdf, 0x60, 0xdd, 0xd8, 0x89, 0x45, 0xc7, 0x4c, 0x9c, 0xd2, 0x65, 0x9d, 0x9e, 0x64, 0x8a, \ - 0x9f \ - } - -enum // WinUSB Microsoft OS 2.0 descriptor request codes -{ - USB_WINUSB_DESCRIPTOR_INDEX = 0x07, - USB_WINUSB_SET_ALT_ENUMERATION = 0x08, -}; - -enum // wDescriptorType -{ - USB_WINUSB_SET_HEADER_DESCRIPTOR = 0x00, - USB_WINUSB_SUBSET_HEADER_CONFIGURATION = 0x01, - USB_WINUSB_SUBSET_HEADER_FUNCTION = 0x02, - USB_WINUSB_FEATURE_COMPATBLE_ID = 0x03, - USB_WINUSB_FEATURE_REG_PROPERTY = 0x04, - USB_WINUSB_FEATURE_MIN_RESUME_TIME = 0x05, - USB_WINUSB_FEATURE_MODEL_ID = 0x06, - USB_WINUSB_FEATURE_CCGP_DEVICE = 0x07, - USB_WINUSB_FEATURE_VENDOR_REVISION = 0x08, -}; - -enum // wPropertyDataType -{ - USB_WINUSB_PROPERTY_DATA_TYPE_SZ = 1, - USB_WINUSB_PROPERTY_DATA_TYPE_EXPAND_SZ = 2, - USB_WINUSB_PROPERTY_DATA_TYPE_BINARY = 3, - USB_WINUSB_PROPERTY_DATA_TYPE_DWORD_LITTLE_ENDIAN = 4, - USB_WINUSB_PROPERTY_DATA_TYPE_DWORD_BIG_ENDIAN = 5, - USB_WINUSB_PROPERTY_DATA_TYPE_LINK = 6, - USB_WINUSB_PROPERTY_DATA_TYPE_MULTI_SZ = 7, -}; - -/*- Types BOS -------------------------------------------------------------------*/ - -typedef struct USB_PACK { - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t wTotalLength; - uint8_t bNumDeviceCaps; -} usb_binary_object_store_descriptor_t; - -/*- Types WinUSB -------------------------------------------------------------------*/ - -typedef struct USB_PACK { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDevCapabilityType; - uint8_t bReserved; - uint8_t PlatformCapabilityUUID[16]; - uint32_t dwWindowsVersion; - uint16_t wMSOSDescriptorSetTotalLength; - uint8_t bMS_VendorCode; - uint8_t bAltEnumCode; -} usb_winusb_capability_descriptor_t; - -typedef struct USB_PACK { - uint16_t wLength; - uint16_t wDescriptorType; - uint32_t dwWindowsVersion; - uint16_t wDescriptorSetTotalLength; -} usb_winusb_set_header_descriptor_t; - -typedef struct USB_PACK { - uint16_t wLength; - uint16_t wDescriptorType; - uint8_t bConfigurationValue; - uint8_t bReserved; - uint16_t wTotalLength; -} usb_winusb_subset_header_configuration_t; - -typedef struct USB_PACK { - uint16_t wLength; - uint16_t wDescriptorType; - uint8_t bFirstInterface; - uint8_t bReserved; - uint16_t wSubsetLength; -} usb_winusb_subset_header_function_t; - -typedef struct USB_PACK { - uint16_t wLength; - uint16_t wDescriptorType; - uint8_t CompatibleID[8]; - uint8_t SubCompatibleID[8]; -} usb_winusb_feature_compatble_id_t; - -typedef struct USB_PACK { - uint16_t wLength; - uint16_t wDescriptorType; - uint16_t wPropertyDataType; - //uint16_t wPropertyNameLength; - //uint8_t PropertyName[...]; - //uint16_t wPropertyDataLength - //uint8_t PropertyData[...]; -} usb_winusb_feature_reg_property_t; - -typedef struct USB_PACK { - uint16_t wLength; - uint16_t wDescriptorType; - uint16_t wPropertyDataType; - uint16_t wPropertyNameLength; - uint8_t PropertyName[42]; - uint16_t wPropertyDataLength; - uint8_t PropertyData[80]; -} usb_winusb_feature_reg_property_guids_t; - -typedef struct USB_PACK { - uint16_t wLength; - uint16_t wDescriptorType; - uint8_t bResumeRecoveryTime; - uint8_t bResumeSignalingTime; -} usb_winusb_feature_min_resume_time_t; - -typedef struct USB_PACK { - uint16_t wLength; - uint16_t wDescriptorType; - uint8_t ModelID[16]; -} usb_winusb_feature_model_id_t; - -typedef struct USB_PACK { - uint16_t wLength; - uint16_t wDescriptorType; -} usb_winusb_feature_ccgp_device_t; - -typedef struct USB_PACK { - uint16_t wLength; - uint16_t wDescriptorType; - uint16_t VendorRevision; -} usb_winusb_feature_vendor_revision_t; \ No newline at end of file diff --git a/applications/external/hid_app/application.fam b/applications/external/hid_app/application.fam deleted file mode 100644 index a9d8305dd..000000000 --- a/applications/external/hid_app/application.fam +++ /dev/null @@ -1,24 +0,0 @@ -App( - appid="hid_usb", - name="Remote", - apptype=FlipperAppType.EXTERNAL, - entry_point="hid_usb_app", - stack_size=1 * 1024, - fap_category="USB", - fap_icon="hid_usb_10px.png", - fap_icon_assets="assets", - fap_icon_assets_symbol="hid", -) - - -App( - appid="hid_ble", - name="Remote", - apptype=FlipperAppType.EXTERNAL, - entry_point="hid_ble_app", - stack_size=1 * 1024, - fap_category="Bluetooth", - fap_icon="hid_ble_10px.png", - fap_icon_assets="assets", - fap_icon_assets_symbol="hid", -) diff --git a/applications/external/hid_app/assets/Arr_dwn_7x9.png b/applications/external/hid_app/assets/Arr_dwn_7x9.png deleted file mode 100644 index d4034efc4..000000000 Binary files a/applications/external/hid_app/assets/Arr_dwn_7x9.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Arr_up_7x9.png b/applications/external/hid_app/assets/Arr_up_7x9.png deleted file mode 100644 index 28b4236a2..000000000 Binary files a/applications/external/hid_app/assets/Arr_up_7x9.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Ble_connected_15x15.png b/applications/external/hid_app/assets/Ble_connected_15x15.png deleted file mode 100644 index 64dab9b53..000000000 Binary files a/applications/external/hid_app/assets/Ble_connected_15x15.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Ble_disconnected_15x15.png b/applications/external/hid_app/assets/Ble_disconnected_15x15.png deleted file mode 100644 index bd54646d8..000000000 Binary files a/applications/external/hid_app/assets/Ble_disconnected_15x15.png and /dev/null differ diff --git a/applications/external/hid_app/assets/ButtonDown_7x4.png b/applications/external/hid_app/assets/ButtonDown_7x4.png deleted file mode 100644 index 2954bb6a6..000000000 Binary files a/applications/external/hid_app/assets/ButtonDown_7x4.png and /dev/null differ diff --git a/applications/external/hid_app/assets/ButtonF10_5x8.png b/applications/external/hid_app/assets/ButtonF10_5x8.png deleted file mode 100644 index d1a7a04f0..000000000 Binary files a/applications/external/hid_app/assets/ButtonF10_5x8.png and /dev/null differ diff --git a/applications/external/hid_app/assets/ButtonF11_5x8.png b/applications/external/hid_app/assets/ButtonF11_5x8.png deleted file mode 100644 index 7e177358e..000000000 Binary files a/applications/external/hid_app/assets/ButtonF11_5x8.png and /dev/null differ diff --git a/applications/external/hid_app/assets/ButtonF12_5x8.png b/applications/external/hid_app/assets/ButtonF12_5x8.png deleted file mode 100644 index 50d2a7dc6..000000000 Binary files a/applications/external/hid_app/assets/ButtonF12_5x8.png and /dev/null differ diff --git a/applications/external/hid_app/assets/ButtonF1_5x8.png b/applications/external/hid_app/assets/ButtonF1_5x8.png deleted file mode 100644 index 7394d2710..000000000 Binary files a/applications/external/hid_app/assets/ButtonF1_5x8.png and /dev/null differ diff --git a/applications/external/hid_app/assets/ButtonF2_5x8.png b/applications/external/hid_app/assets/ButtonF2_5x8.png deleted file mode 100644 index 9d922a385..000000000 Binary files a/applications/external/hid_app/assets/ButtonF2_5x8.png and /dev/null differ diff --git a/applications/external/hid_app/assets/ButtonF3_5x8.png b/applications/external/hid_app/assets/ButtonF3_5x8.png deleted file mode 100644 index 95c2dd4f4..000000000 Binary files a/applications/external/hid_app/assets/ButtonF3_5x8.png and /dev/null differ diff --git a/applications/external/hid_app/assets/ButtonF4_5x8.png b/applications/external/hid_app/assets/ButtonF4_5x8.png deleted file mode 100644 index 602466f4b..000000000 Binary files a/applications/external/hid_app/assets/ButtonF4_5x8.png and /dev/null differ diff --git a/applications/external/hid_app/assets/ButtonF5_5x8.png b/applications/external/hid_app/assets/ButtonF5_5x8.png deleted file mode 100644 index d73b54052..000000000 Binary files a/applications/external/hid_app/assets/ButtonF5_5x8.png and /dev/null differ diff --git a/applications/external/hid_app/assets/ButtonF6_5x8.png b/applications/external/hid_app/assets/ButtonF6_5x8.png deleted file mode 100644 index c50748257..000000000 Binary files a/applications/external/hid_app/assets/ButtonF6_5x8.png and /dev/null differ diff --git a/applications/external/hid_app/assets/ButtonF7_5x8.png b/applications/external/hid_app/assets/ButtonF7_5x8.png deleted file mode 100644 index 396c98f51..000000000 Binary files a/applications/external/hid_app/assets/ButtonF7_5x8.png and /dev/null differ diff --git a/applications/external/hid_app/assets/ButtonF8_5x8.png b/applications/external/hid_app/assets/ButtonF8_5x8.png deleted file mode 100644 index 6304d7fb8..000000000 Binary files a/applications/external/hid_app/assets/ButtonF8_5x8.png and /dev/null differ diff --git a/applications/external/hid_app/assets/ButtonF9_5x8.png b/applications/external/hid_app/assets/ButtonF9_5x8.png deleted file mode 100644 index 148e69580..000000000 Binary files a/applications/external/hid_app/assets/ButtonF9_5x8.png and /dev/null differ diff --git a/applications/external/hid_app/assets/ButtonLeft_4x7.png b/applications/external/hid_app/assets/ButtonLeft_4x7.png deleted file mode 100644 index 0b4655d43..000000000 Binary files a/applications/external/hid_app/assets/ButtonLeft_4x7.png and /dev/null differ diff --git a/applications/external/hid_app/assets/ButtonRight_4x7.png b/applications/external/hid_app/assets/ButtonRight_4x7.png deleted file mode 100644 index 8e1c74c1c..000000000 Binary files a/applications/external/hid_app/assets/ButtonRight_4x7.png and /dev/null differ diff --git a/applications/external/hid_app/assets/ButtonUp_7x4.png b/applications/external/hid_app/assets/ButtonUp_7x4.png deleted file mode 100644 index 1be79328b..000000000 Binary files a/applications/external/hid_app/assets/ButtonUp_7x4.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Button_18x18.png b/applications/external/hid_app/assets/Button_18x18.png deleted file mode 100644 index 30a5b4fab..000000000 Binary files a/applications/external/hid_app/assets/Button_18x18.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Circles_47x47.png b/applications/external/hid_app/assets/Circles_47x47.png deleted file mode 100644 index 6a16ebf7b..000000000 Binary files a/applications/external/hid_app/assets/Circles_47x47.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Left_mouse_icon_9x9.png b/applications/external/hid_app/assets/Left_mouse_icon_9x9.png deleted file mode 100644 index c533d8572..000000000 Binary files a/applications/external/hid_app/assets/Left_mouse_icon_9x9.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Like_def_11x9.png b/applications/external/hid_app/assets/Like_def_11x9.png deleted file mode 100644 index 555bea3d4..000000000 Binary files a/applications/external/hid_app/assets/Like_def_11x9.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Like_pressed_17x17.png b/applications/external/hid_app/assets/Like_pressed_17x17.png deleted file mode 100644 index f5bf276f3..000000000 Binary files a/applications/external/hid_app/assets/Like_pressed_17x17.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Ok_btn_9x9.png b/applications/external/hid_app/assets/Ok_btn_9x9.png deleted file mode 100644 index 9a1539da2..000000000 Binary files a/applications/external/hid_app/assets/Ok_btn_9x9.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Ok_btn_pressed_13x13.png b/applications/external/hid_app/assets/Ok_btn_pressed_13x13.png deleted file mode 100644 index 6b46ba3a8..000000000 Binary files a/applications/external/hid_app/assets/Ok_btn_pressed_13x13.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Pin_arrow_down_7x9.png b/applications/external/hid_app/assets/Pin_arrow_down_7x9.png deleted file mode 100644 index 9687397af..000000000 Binary files a/applications/external/hid_app/assets/Pin_arrow_down_7x9.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Pin_arrow_left_9x7.png b/applications/external/hid_app/assets/Pin_arrow_left_9x7.png deleted file mode 100644 index fb4ded78f..000000000 Binary files a/applications/external/hid_app/assets/Pin_arrow_left_9x7.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Pin_arrow_right_9x7.png b/applications/external/hid_app/assets/Pin_arrow_right_9x7.png deleted file mode 100644 index 97648d176..000000000 Binary files a/applications/external/hid_app/assets/Pin_arrow_right_9x7.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Pin_arrow_up_7x9.png b/applications/external/hid_app/assets/Pin_arrow_up_7x9.png deleted file mode 100644 index a91a6fd5e..000000000 Binary files a/applications/external/hid_app/assets/Pin_arrow_up_7x9.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Pin_back_arrow_10x8.png b/applications/external/hid_app/assets/Pin_back_arrow_10x8.png deleted file mode 100644 index 3bafabd14..000000000 Binary files a/applications/external/hid_app/assets/Pin_back_arrow_10x8.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Pressed_Button_13x13.png b/applications/external/hid_app/assets/Pressed_Button_13x13.png deleted file mode 100644 index 823926b84..000000000 Binary files a/applications/external/hid_app/assets/Pressed_Button_13x13.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Right_mouse_icon_9x9.png b/applications/external/hid_app/assets/Right_mouse_icon_9x9.png deleted file mode 100644 index 446d7176c..000000000 Binary files a/applications/external/hid_app/assets/Right_mouse_icon_9x9.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Space_60x18.png b/applications/external/hid_app/assets/Space_60x18.png deleted file mode 100644 index e29f50ae9..000000000 Binary files a/applications/external/hid_app/assets/Space_60x18.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Space_65x18.png b/applications/external/hid_app/assets/Space_65x18.png deleted file mode 100644 index b60ae5097..000000000 Binary files a/applications/external/hid_app/assets/Space_65x18.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Voldwn_6x6.png b/applications/external/hid_app/assets/Voldwn_6x6.png deleted file mode 100644 index d7a82a2df..000000000 Binary files a/applications/external/hid_app/assets/Voldwn_6x6.png and /dev/null differ diff --git a/applications/external/hid_app/assets/Volup_8x6.png b/applications/external/hid_app/assets/Volup_8x6.png deleted file mode 100644 index 4b7ec66d6..000000000 Binary files a/applications/external/hid_app/assets/Volup_8x6.png and /dev/null differ diff --git a/applications/external/hid_app/hid.c b/applications/external/hid_app/hid.c deleted file mode 100644 index 2be9afd91..000000000 --- a/applications/external/hid_app/hid.c +++ /dev/null @@ -1,447 +0,0 @@ -#include "hid.h" -#include "views.h" -#include - -#define TAG "HidApp" - -enum HidDebugSubmenuIndex { - HidSubmenuIndexKeynote, - HidSubmenuIndexKeynoteVertical, - HidSubmenuIndexKeyboard, - HidSubmenuIndexMedia, - HidSubmenuIndexTikTok, - HidSubmenuIndexMouse, - HidSubmenuIndexMouseClicker, - HidSubmenuIndexMouseJiggler, -}; - -static void hid_submenu_callback(void* context, uint32_t index) { - furi_assert(context); - Hid* app = context; - if(index == HidSubmenuIndexKeynote) { - app->view_id = HidViewKeynote; - hid_keynote_set_orientation(app->hid_keynote, false); - view_dispatcher_switch_to_view(app->view_dispatcher, HidViewKeynote); - } else if(index == HidSubmenuIndexKeynoteVertical) { - app->view_id = HidViewKeynote; - hid_keynote_set_orientation(app->hid_keynote, true); - view_dispatcher_switch_to_view(app->view_dispatcher, HidViewKeynote); - } else if(index == HidSubmenuIndexKeyboard) { - app->view_id = HidViewKeyboard; - view_dispatcher_switch_to_view(app->view_dispatcher, HidViewKeyboard); - } else if(index == HidSubmenuIndexMedia) { - app->view_id = HidViewMedia; - view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMedia); - } else if(index == HidSubmenuIndexMouse) { - app->view_id = HidViewMouse; - view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMouse); - } else if(index == HidSubmenuIndexTikTok) { - app->view_id = BtHidViewTikTok; - view_dispatcher_switch_to_view(app->view_dispatcher, BtHidViewTikTok); - } else if(index == HidSubmenuIndexMouseClicker) { - app->view_id = HidViewMouseClicker; - view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMouseClicker); - } else if(index == HidSubmenuIndexMouseJiggler) { - app->view_id = HidViewMouseJiggler; - view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMouseJiggler); - } -} - -static void bt_hid_connection_status_changed_callback(BtStatus status, void* context) { - furi_assert(context); - Hid* hid = context; - bool connected = (status == BtStatusConnected); - if(hid->transport == HidTransportBle) { - if(connected) { - notification_internal_message(hid->notifications, &sequence_set_blue_255); - } else { - notification_internal_message(hid->notifications, &sequence_reset_blue); - } - } - hid_keynote_set_connected_status(hid->hid_keynote, connected); - hid_keyboard_set_connected_status(hid->hid_keyboard, connected); - hid_media_set_connected_status(hid->hid_media, connected); - hid_mouse_set_connected_status(hid->hid_mouse, connected); - hid_mouse_clicker_set_connected_status(hid->hid_mouse_clicker, connected); - hid_mouse_jiggler_set_connected_status(hid->hid_mouse_jiggler, connected); - hid_tiktok_set_connected_status(hid->hid_tiktok, connected); -} - -static void hid_dialog_callback(DialogExResult result, void* context) { - furi_assert(context); - Hid* app = context; - if(result == DialogExResultLeft) { - view_dispatcher_stop(app->view_dispatcher); - } else if(result == DialogExResultRight) { - view_dispatcher_switch_to_view(app->view_dispatcher, app->view_id); // Show last view - } else if(result == DialogExResultCenter) { - view_dispatcher_switch_to_view(app->view_dispatcher, HidViewSubmenu); - } -} - -static uint32_t hid_exit_confirm_view(void* context) { - UNUSED(context); - return HidViewExitConfirm; -} - -static uint32_t hid_exit(void* context) { - UNUSED(context); - return VIEW_NONE; -} - -Hid* hid_alloc(HidTransport transport) { - Hid* app = malloc(sizeof(Hid)); - app->transport = transport; - - // Gui - app->gui = furi_record_open(RECORD_GUI); - - // Bt - app->bt = furi_record_open(RECORD_BT); - - // Notifications - app->notifications = furi_record_open(RECORD_NOTIFICATION); - - // View dispatcher - app->view_dispatcher = view_dispatcher_alloc(); - view_dispatcher_enable_queue(app->view_dispatcher); - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - // Device Type Submenu view - app->device_type_submenu = submenu_alloc(); - submenu_add_item( - app->device_type_submenu, "Keynote", HidSubmenuIndexKeynote, hid_submenu_callback, app); - submenu_add_item( - app->device_type_submenu, - "Keynote Vertical", - HidSubmenuIndexKeynoteVertical, - hid_submenu_callback, - app); - submenu_add_item( - app->device_type_submenu, "Keyboard", HidSubmenuIndexKeyboard, hid_submenu_callback, app); - submenu_add_item( - app->device_type_submenu, "Media", HidSubmenuIndexMedia, hid_submenu_callback, app); - submenu_add_item( - app->device_type_submenu, "Mouse", HidSubmenuIndexMouse, hid_submenu_callback, app); - if(app->transport == HidTransportBle) { - submenu_add_item( - app->device_type_submenu, - "TikTok Controller", - HidSubmenuIndexTikTok, - hid_submenu_callback, - app); - } - submenu_add_item( - app->device_type_submenu, - "Mouse Clicker", - HidSubmenuIndexMouseClicker, - hid_submenu_callback, - app); - submenu_add_item( - app->device_type_submenu, - "Mouse Jiggler", - HidSubmenuIndexMouseJiggler, - hid_submenu_callback, - app); - view_set_previous_callback(submenu_get_view(app->device_type_submenu), hid_exit); - view_dispatcher_add_view( - app->view_dispatcher, HidViewSubmenu, submenu_get_view(app->device_type_submenu)); - app->view_id = HidViewSubmenu; - view_dispatcher_switch_to_view(app->view_dispatcher, app->view_id); - return app; -} - -Hid* hid_app_alloc_view(void* context) { - furi_assert(context); - Hid* app = context; - // Dialog view - app->dialog = dialog_ex_alloc(); - dialog_ex_set_result_callback(app->dialog, hid_dialog_callback); - dialog_ex_set_context(app->dialog, app); - dialog_ex_set_left_button_text(app->dialog, "Exit"); - dialog_ex_set_right_button_text(app->dialog, "Stay"); - dialog_ex_set_center_button_text(app->dialog, "Menu"); - dialog_ex_set_header(app->dialog, "Close Current App?", 16, 12, AlignLeft, AlignTop); - view_dispatcher_add_view( - app->view_dispatcher, HidViewExitConfirm, dialog_ex_get_view(app->dialog)); - - // Keynote view - app->hid_keynote = hid_keynote_alloc(app); - view_set_previous_callback(hid_keynote_get_view(app->hid_keynote), hid_exit_confirm_view); - view_dispatcher_add_view( - app->view_dispatcher, HidViewKeynote, hid_keynote_get_view(app->hid_keynote)); - - // Keyboard view - app->hid_keyboard = hid_keyboard_alloc(app); - view_set_previous_callback(hid_keyboard_get_view(app->hid_keyboard), hid_exit_confirm_view); - view_dispatcher_add_view( - app->view_dispatcher, HidViewKeyboard, hid_keyboard_get_view(app->hid_keyboard)); - - // Media view - app->hid_media = hid_media_alloc(app); - view_set_previous_callback(hid_media_get_view(app->hid_media), hid_exit_confirm_view); - view_dispatcher_add_view( - app->view_dispatcher, HidViewMedia, hid_media_get_view(app->hid_media)); - - // TikTok view - app->hid_tiktok = hid_tiktok_alloc(app); - view_set_previous_callback(hid_tiktok_get_view(app->hid_tiktok), hid_exit_confirm_view); - view_dispatcher_add_view( - app->view_dispatcher, BtHidViewTikTok, hid_tiktok_get_view(app->hid_tiktok)); - - // Mouse view - app->hid_mouse = hid_mouse_alloc(app); - view_set_previous_callback(hid_mouse_get_view(app->hid_mouse), hid_exit_confirm_view); - view_dispatcher_add_view( - app->view_dispatcher, HidViewMouse, hid_mouse_get_view(app->hid_mouse)); - - // Mouse clicker view - app->hid_mouse_clicker = hid_mouse_clicker_alloc(app); - view_set_previous_callback( - hid_mouse_clicker_get_view(app->hid_mouse_clicker), hid_exit_confirm_view); - view_dispatcher_add_view( - app->view_dispatcher, - HidViewMouseClicker, - hid_mouse_clicker_get_view(app->hid_mouse_clicker)); - - // Mouse jiggler view - app->hid_mouse_jiggler = hid_mouse_jiggler_alloc(app); - view_set_previous_callback( - hid_mouse_jiggler_get_view(app->hid_mouse_jiggler), hid_exit_confirm_view); - view_dispatcher_add_view( - app->view_dispatcher, - HidViewMouseJiggler, - hid_mouse_jiggler_get_view(app->hid_mouse_jiggler)); - - return app; -} - -void hid_free(Hid* app) { - furi_assert(app); - - // Reset notification - if(app->transport == HidTransportBle) { - notification_internal_message(app->notifications, &sequence_reset_blue); - } - - // Free views - view_dispatcher_remove_view(app->view_dispatcher, HidViewSubmenu); - submenu_free(app->device_type_submenu); - view_dispatcher_remove_view(app->view_dispatcher, HidViewExitConfirm); - dialog_ex_free(app->dialog); - view_dispatcher_remove_view(app->view_dispatcher, HidViewKeynote); - hid_keynote_free(app->hid_keynote); - view_dispatcher_remove_view(app->view_dispatcher, HidViewKeyboard); - hid_keyboard_free(app->hid_keyboard); - view_dispatcher_remove_view(app->view_dispatcher, HidViewMedia); - hid_media_free(app->hid_media); - view_dispatcher_remove_view(app->view_dispatcher, HidViewMouse); - hid_mouse_free(app->hid_mouse); - view_dispatcher_remove_view(app->view_dispatcher, HidViewMouseClicker); - hid_mouse_clicker_free(app->hid_mouse_clicker); - view_dispatcher_remove_view(app->view_dispatcher, HidViewMouseJiggler); - hid_mouse_jiggler_free(app->hid_mouse_jiggler); - view_dispatcher_remove_view(app->view_dispatcher, BtHidViewTikTok); - hid_tiktok_free(app->hid_tiktok); - view_dispatcher_free(app->view_dispatcher); - - // Close records - furi_record_close(RECORD_GUI); - app->gui = NULL; - furi_record_close(RECORD_NOTIFICATION); - app->notifications = NULL; - furi_record_close(RECORD_BT); - app->bt = NULL; - - // Free rest - free(app); -} - -void hid_hal_keyboard_press(Hid* instance, uint16_t event) { - furi_assert(instance); - if(instance->transport == HidTransportBle) { - furi_hal_bt_hid_kb_press(event); - } else if(instance->transport == HidTransportUsb) { - furi_hal_hid_kb_press(event); - } else { - furi_crash(NULL); - } -} - -void hid_hal_keyboard_release(Hid* instance, uint16_t event) { - furi_assert(instance); - if(instance->transport == HidTransportBle) { - furi_hal_bt_hid_kb_release(event); - } else if(instance->transport == HidTransportUsb) { - furi_hal_hid_kb_release(event); - } else { - furi_crash(NULL); - } -} - -void hid_hal_keyboard_release_all(Hid* instance) { - furi_assert(instance); - if(instance->transport == HidTransportBle) { - furi_hal_bt_hid_kb_release_all(); - } else if(instance->transport == HidTransportUsb) { - furi_hal_hid_kb_release_all(); - } else { - furi_crash(NULL); - } -} - -void hid_hal_consumer_key_press(Hid* instance, uint16_t event) { - furi_assert(instance); - if(instance->transport == HidTransportBle) { - furi_hal_bt_hid_consumer_key_press(event); - } else if(instance->transport == HidTransportUsb) { - furi_hal_hid_consumer_key_press(event); - } else { - furi_crash(NULL); - } -} - -void hid_hal_consumer_key_release(Hid* instance, uint16_t event) { - furi_assert(instance); - if(instance->transport == HidTransportBle) { - furi_hal_bt_hid_consumer_key_release(event); - } else if(instance->transport == HidTransportUsb) { - furi_hal_hid_consumer_key_release(event); - } else { - furi_crash(NULL); - } -} - -void hid_hal_consumer_key_release_all(Hid* instance) { - furi_assert(instance); - if(instance->transport == HidTransportBle) { - furi_hal_bt_hid_consumer_key_release_all(); - } else if(instance->transport == HidTransportUsb) { - furi_hal_hid_kb_release_all(); - } else { - furi_crash(NULL); - } -} - -void hid_hal_mouse_move(Hid* instance, int8_t dx, int8_t dy) { - furi_assert(instance); - if(instance->transport == HidTransportBle) { - furi_hal_bt_hid_mouse_move(dx, dy); - } else if(instance->transport == HidTransportUsb) { - furi_hal_hid_mouse_move(dx, dy); - } else { - furi_crash(NULL); - } -} - -void hid_hal_mouse_scroll(Hid* instance, int8_t delta) { - furi_assert(instance); - if(instance->transport == HidTransportBle) { - furi_hal_bt_hid_mouse_scroll(delta); - } else if(instance->transport == HidTransportUsb) { - furi_hal_hid_mouse_scroll(delta); - } else { - furi_crash(NULL); - } -} - -void hid_hal_mouse_press(Hid* instance, uint16_t event) { - furi_assert(instance); - if(instance->transport == HidTransportBle) { - furi_hal_bt_hid_mouse_press(event); - } else if(instance->transport == HidTransportUsb) { - furi_hal_hid_mouse_press(event); - } else { - furi_crash(NULL); - } -} - -void hid_hal_mouse_release(Hid* instance, uint16_t event) { - furi_assert(instance); - if(instance->transport == HidTransportBle) { - furi_hal_bt_hid_mouse_release(event); - } else if(instance->transport == HidTransportUsb) { - furi_hal_hid_mouse_release(event); - } else { - furi_crash(NULL); - } -} - -void hid_hal_mouse_release_all(Hid* instance) { - furi_assert(instance); - if(instance->transport == HidTransportBle) { - furi_hal_bt_hid_mouse_release_all(); - } else if(instance->transport == HidTransportUsb) { - furi_hal_hid_mouse_release(HID_MOUSE_BTN_LEFT); - furi_hal_hid_mouse_release(HID_MOUSE_BTN_RIGHT); - } else { - furi_crash(NULL); - } -} - -int32_t hid_usb_app(void* p) { - UNUSED(p); - Hid* app = hid_alloc(HidTransportUsb); - app = hid_app_alloc_view(app); - FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config(); - furi_hal_usb_unlock(); - furi_check(furi_hal_usb_set_config(&usb_hid, NULL) == true); - - bt_hid_connection_status_changed_callback(BtStatusConnected, app); - - view_dispatcher_run(app->view_dispatcher); - - furi_hal_usb_set_config(usb_mode_prev, NULL); - - hid_free(app); - - return 0; -} - -int32_t hid_ble_app(void* p) { - UNUSED(p); - Hid* app = hid_alloc(HidTransportBle); - app = hid_app_alloc_view(app); - - bt_disconnect(app->bt); - - // Wait 2nd core to update nvm storage - furi_delay_ms(200); - - // Migrate data from old sd-card folder - Storage* storage = furi_record_open(RECORD_STORAGE); - - storage_common_migrate( - storage, - EXT_PATH("apps/Tools/" HID_BT_KEYS_STORAGE_NAME), - APP_DATA_PATH(HID_BT_KEYS_STORAGE_NAME)); - - bt_keys_storage_set_storage_path(app->bt, APP_DATA_PATH(HID_BT_KEYS_STORAGE_NAME)); - - furi_record_close(RECORD_STORAGE); - - if(!bt_set_profile(app->bt, BtProfileHidKeyboard)) { - FURI_LOG_E(TAG, "Failed to switch to HID profile"); - } - - furi_hal_bt_start_advertising(); - bt_set_status_changed_callback(app->bt, bt_hid_connection_status_changed_callback, app); - - view_dispatcher_run(app->view_dispatcher); - - bt_set_status_changed_callback(app->bt, NULL, NULL); - - bt_disconnect(app->bt); - - // Wait 2nd core to update nvm storage - furi_delay_ms(200); - - bt_keys_storage_set_default_path(app->bt); - - if(!bt_set_profile(app->bt, BtProfileSerial)) { - FURI_LOG_E(TAG, "Failed to switch to Serial profile"); - } - - hid_free(app); - - return 0; -} diff --git a/applications/external/hid_app/hid.h b/applications/external/hid_app/hid.h deleted file mode 100644 index 49d8b4e04..000000000 --- a/applications/external/hid_app/hid.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "views/hid_keynote.h" -#include "views/hid_keyboard.h" -#include "views/hid_media.h" -#include "views/hid_mouse.h" -#include "views/hid_mouse_clicker.h" -#include "views/hid_mouse_jiggler.h" -#include "views/hid_tiktok.h" - -#define HID_BT_KEYS_STORAGE_NAME ".bt_hid.keys" - -typedef enum { - HidTransportUsb, - HidTransportBle, -} HidTransport; - -typedef struct Hid Hid; - -struct Hid { - Bt* bt; - Gui* gui; - NotificationApp* notifications; - ViewDispatcher* view_dispatcher; - Submenu* device_type_submenu; - DialogEx* dialog; - HidKeynote* hid_keynote; - HidKeyboard* hid_keyboard; - HidMedia* hid_media; - HidMouse* hid_mouse; - HidMouseClicker* hid_mouse_clicker; - HidMouseJiggler* hid_mouse_jiggler; - HidTikTok* hid_tiktok; - - HidTransport transport; - uint32_t view_id; -}; - -void hid_hal_keyboard_press(Hid* instance, uint16_t event); -void hid_hal_keyboard_release(Hid* instance, uint16_t event); -void hid_hal_keyboard_release_all(Hid* instance); - -void hid_hal_consumer_key_press(Hid* instance, uint16_t event); -void hid_hal_consumer_key_release(Hid* instance, uint16_t event); -void hid_hal_consumer_key_release_all(Hid* instance); - -void hid_hal_mouse_move(Hid* instance, int8_t dx, int8_t dy); -void hid_hal_mouse_scroll(Hid* instance, int8_t delta); -void hid_hal_mouse_press(Hid* instance, uint16_t event); -void hid_hal_mouse_release(Hid* instance, uint16_t event); -void hid_hal_mouse_release_all(Hid* instance); \ No newline at end of file diff --git a/applications/external/hid_app/hid_ble_10px.png b/applications/external/hid_app/hid_ble_10px.png deleted file mode 100644 index d4d30afe0..000000000 Binary files a/applications/external/hid_app/hid_ble_10px.png and /dev/null differ diff --git a/applications/external/hid_app/hid_usb_10px.png b/applications/external/hid_app/hid_usb_10px.png deleted file mode 100644 index 415de7d23..000000000 Binary files a/applications/external/hid_app/hid_usb_10px.png and /dev/null differ diff --git a/applications/external/hid_app/views.h b/applications/external/hid_app/views.h deleted file mode 100644 index 1bea3355e..000000000 --- a/applications/external/hid_app/views.h +++ /dev/null @@ -1,11 +0,0 @@ -typedef enum { - HidViewSubmenu, - HidViewKeynote, - HidViewKeyboard, - HidViewMedia, - HidViewMouse, - HidViewMouseClicker, - HidViewMouseJiggler, - BtHidViewTikTok, - HidViewExitConfirm, -} HidView; \ No newline at end of file diff --git a/applications/external/hid_app/views/hid_keyboard.c b/applications/external/hid_app/views/hid_keyboard.c deleted file mode 100644 index 82e772b15..000000000 --- a/applications/external/hid_app/views/hid_keyboard.c +++ /dev/null @@ -1,411 +0,0 @@ -#include "hid_keyboard.h" -#include -#include -#include -#include "../hid.h" -#include "hid_icons.h" - -#define TAG "HidKeyboard" - -struct HidKeyboard { - View* view; - Hid* hid; -}; - -typedef struct { - bool shift; - bool alt; - bool ctrl; - bool gui; - uint8_t x; - uint8_t y; - uint8_t last_key_code; - uint16_t modifier_code; - bool ok_pressed; - bool back_pressed; - bool connected; - char key_string[5]; - HidTransport transport; -} HidKeyboardModel; - -typedef struct { - uint8_t width; - char* key; - const Icon* icon; - char* shift_key; - uint8_t value; -} HidKeyboardKey; - -typedef struct { - int8_t x; - int8_t y; -} HidKeyboardPoint; -// 4 BY 12 -#define MARGIN_TOP 0 -#define MARGIN_LEFT 4 -#define KEY_WIDTH 9 -#define KEY_HEIGHT 12 -#define KEY_PADDING 1 -#define ROW_COUNT 7 -#define COLUMN_COUNT 12 - -// 0 width items are not drawn, but there value is used -const HidKeyboardKey hid_keyboard_keyset[ROW_COUNT][COLUMN_COUNT] = { - { - {.width = 1, .icon = &I_ButtonF1_5x8, .value = HID_KEYBOARD_F1}, - {.width = 1, .icon = &I_ButtonF2_5x8, .value = HID_KEYBOARD_F2}, - {.width = 1, .icon = &I_ButtonF3_5x8, .value = HID_KEYBOARD_F3}, - {.width = 1, .icon = &I_ButtonF4_5x8, .value = HID_KEYBOARD_F4}, - {.width = 1, .icon = &I_ButtonF5_5x8, .value = HID_KEYBOARD_F5}, - {.width = 1, .icon = &I_ButtonF6_5x8, .value = HID_KEYBOARD_F6}, - {.width = 1, .icon = &I_ButtonF7_5x8, .value = HID_KEYBOARD_F7}, - {.width = 1, .icon = &I_ButtonF8_5x8, .value = HID_KEYBOARD_F8}, - {.width = 1, .icon = &I_ButtonF9_5x8, .value = HID_KEYBOARD_F9}, - {.width = 1, .icon = &I_ButtonF10_5x8, .value = HID_KEYBOARD_F10}, - {.width = 1, .icon = &I_ButtonF11_5x8, .value = HID_KEYBOARD_F11}, - {.width = 1, .icon = &I_ButtonF12_5x8, .value = HID_KEYBOARD_F12}, - }, - { - {.width = 1, .icon = NULL, .key = "1", .shift_key = "!", .value = HID_KEYBOARD_1}, - {.width = 1, .icon = NULL, .key = "2", .shift_key = "@", .value = HID_KEYBOARD_2}, - {.width = 1, .icon = NULL, .key = "3", .shift_key = "#", .value = HID_KEYBOARD_3}, - {.width = 1, .icon = NULL, .key = "4", .shift_key = "$", .value = HID_KEYBOARD_4}, - {.width = 1, .icon = NULL, .key = "5", .shift_key = "%", .value = HID_KEYBOARD_5}, - {.width = 1, .icon = NULL, .key = "6", .shift_key = "^", .value = HID_KEYBOARD_6}, - {.width = 1, .icon = NULL, .key = "7", .shift_key = "&", .value = HID_KEYBOARD_7}, - {.width = 1, .icon = NULL, .key = "8", .shift_key = "*", .value = HID_KEYBOARD_8}, - {.width = 1, .icon = NULL, .key = "9", .shift_key = "(", .value = HID_KEYBOARD_9}, - {.width = 1, .icon = NULL, .key = "0", .shift_key = ")", .value = HID_KEYBOARD_0}, - {.width = 2, .icon = &I_Pin_arrow_left_9x7, .value = HID_KEYBOARD_DELETE}, - {.width = 0, .value = HID_KEYBOARD_DELETE}, - }, - { - {.width = 1, .icon = NULL, .key = "q", .shift_key = "Q", .value = HID_KEYBOARD_Q}, - {.width = 1, .icon = NULL, .key = "w", .shift_key = "W", .value = HID_KEYBOARD_W}, - {.width = 1, .icon = NULL, .key = "e", .shift_key = "E", .value = HID_KEYBOARD_E}, - {.width = 1, .icon = NULL, .key = "r", .shift_key = "R", .value = HID_KEYBOARD_R}, - {.width = 1, .icon = NULL, .key = "t", .shift_key = "T", .value = HID_KEYBOARD_T}, - {.width = 1, .icon = NULL, .key = "y", .shift_key = "Y", .value = HID_KEYBOARD_Y}, - {.width = 1, .icon = NULL, .key = "u", .shift_key = "U", .value = HID_KEYBOARD_U}, - {.width = 1, .icon = NULL, .key = "i", .shift_key = "I", .value = HID_KEYBOARD_I}, - {.width = 1, .icon = NULL, .key = "o", .shift_key = "O", .value = HID_KEYBOARD_O}, - {.width = 1, .icon = NULL, .key = "p", .shift_key = "P", .value = HID_KEYBOARD_P}, - {.width = 1, .icon = NULL, .key = "[", .shift_key = "{", .value = HID_KEYBOARD_OPEN_BRACKET}, - {.width = 1, - .icon = NULL, - .key = "]", - .shift_key = "}", - .value = HID_KEYBOARD_CLOSE_BRACKET}, - }, - { - {.width = 1, .icon = NULL, .key = "a", .shift_key = "A", .value = HID_KEYBOARD_A}, - {.width = 1, .icon = NULL, .key = "s", .shift_key = "S", .value = HID_KEYBOARD_S}, - {.width = 1, .icon = NULL, .key = "d", .shift_key = "D", .value = HID_KEYBOARD_D}, - {.width = 1, .icon = NULL, .key = "f", .shift_key = "F", .value = HID_KEYBOARD_F}, - {.width = 1, .icon = NULL, .key = "g", .shift_key = "G", .value = HID_KEYBOARD_G}, - {.width = 1, .icon = NULL, .key = "h", .shift_key = "H", .value = HID_KEYBOARD_H}, - {.width = 1, .icon = NULL, .key = "j", .shift_key = "J", .value = HID_KEYBOARD_J}, - {.width = 1, .icon = NULL, .key = "k", .shift_key = "K", .value = HID_KEYBOARD_K}, - {.width = 1, .icon = NULL, .key = "l", .shift_key = "L", .value = HID_KEYBOARD_L}, - {.width = 1, .icon = NULL, .key = ";", .shift_key = ":", .value = HID_KEYBOARD_SEMICOLON}, - {.width = 2, .icon = &I_Pin_arrow_right_9x7, .value = HID_KEYBOARD_RETURN}, - {.width = 0, .value = HID_KEYBOARD_RETURN}, - }, - { - {.width = 1, .icon = NULL, .key = "z", .shift_key = "Z", .value = HID_KEYBOARD_Z}, - {.width = 1, .icon = NULL, .key = "x", .shift_key = "X", .value = HID_KEYBOARD_X}, - {.width = 1, .icon = NULL, .key = "c", .shift_key = "C", .value = HID_KEYBOARD_C}, - {.width = 1, .icon = NULL, .key = "v", .shift_key = "V", .value = HID_KEYBOARD_V}, - {.width = 1, .icon = NULL, .key = "b", .shift_key = "B", .value = HID_KEYBOARD_B}, - {.width = 1, .icon = NULL, .key = "n", .shift_key = "N", .value = HID_KEYBOARD_N}, - {.width = 1, .icon = NULL, .key = "m", .shift_key = "M", .value = HID_KEYBOARD_M}, - {.width = 1, .icon = NULL, .key = "/", .shift_key = "?", .value = HID_KEYBOARD_SLASH}, - {.width = 1, .icon = NULL, .key = "\\", .shift_key = "|", .value = HID_KEYBOARD_BACKSLASH}, - {.width = 1, .icon = NULL, .key = "`", .shift_key = "~", .value = HID_KEYBOARD_GRAVE_ACCENT}, - {.width = 1, .icon = &I_ButtonUp_7x4, .value = HID_KEYBOARD_UP_ARROW}, - {.width = 1, .icon = NULL, .key = "-", .shift_key = "_", .value = HID_KEYBOARD_MINUS}, - }, - { - {.width = 1, .icon = &I_Pin_arrow_up_7x9, .value = HID_KEYBOARD_L_SHIFT}, - {.width = 1, .icon = NULL, .key = ",", .shift_key = "<", .value = HID_KEYBOARD_COMMA}, - {.width = 1, .icon = NULL, .key = ".", .shift_key = ">", .value = HID_KEYBOARD_DOT}, - {.width = 4, .icon = NULL, .key = " ", .value = HID_KEYBOARD_SPACEBAR}, - {.width = 0, .value = HID_KEYBOARD_SPACEBAR}, - {.width = 0, .value = HID_KEYBOARD_SPACEBAR}, - {.width = 0, .value = HID_KEYBOARD_SPACEBAR}, - {.width = 1, .icon = NULL, .key = "'", .shift_key = "\"", .value = HID_KEYBOARD_APOSTROPHE}, - {.width = 1, .icon = NULL, .key = "=", .shift_key = "+", .value = HID_KEYBOARD_EQUAL_SIGN}, - {.width = 1, .icon = &I_ButtonLeft_4x7, .value = HID_KEYBOARD_LEFT_ARROW}, - {.width = 1, .icon = &I_ButtonDown_7x4, .value = HID_KEYBOARD_DOWN_ARROW}, - {.width = 1, .icon = &I_ButtonRight_4x7, .value = HID_KEYBOARD_RIGHT_ARROW}, - }, - { - {.width = 3, .icon = NULL, .key = "Ctrl", .value = HID_KEYBOARD_L_CTRL}, - {.width = 0, .icon = NULL, .value = HID_KEYBOARD_L_CTRL}, - {.width = 0, .icon = NULL, .value = HID_KEYBOARD_L_CTRL}, - {.width = 3, .icon = NULL, .key = "Alt", .value = HID_KEYBOARD_L_ALT}, - {.width = 0, .icon = NULL, .value = HID_KEYBOARD_L_ALT}, - {.width = 0, .icon = NULL, .value = HID_KEYBOARD_L_ALT}, - {.width = 3, .icon = NULL, .key = "Cmd", .value = HID_KEYBOARD_L_GUI}, - {.width = 0, .icon = NULL, .value = HID_KEYBOARD_L_GUI}, - {.width = 0, .icon = NULL, .value = HID_KEYBOARD_L_GUI}, - {.width = 3, .icon = NULL, .key = "Tab", .value = HID_KEYBOARD_TAB}, - {.width = 0, .icon = NULL, .value = HID_KEYBOARD_TAB}, - {.width = 0, .icon = NULL, .value = HID_KEYBOARD_TAB}, - }, -}; - -static void hid_keyboard_to_upper(char* str) { - while(*str) { - *str = toupper((unsigned char)*str); - str++; - } -} - -static void hid_keyboard_draw_key( - Canvas* canvas, - HidKeyboardModel* model, - uint8_t x, - uint8_t y, - HidKeyboardKey key, - bool selected) { - if(!key.width) return; - - canvas_set_color(canvas, ColorBlack); - uint8_t keyWidth = KEY_WIDTH * key.width + KEY_PADDING * (key.width - 1); - if(selected) { - // Draw a filled box - elements_slightly_rounded_box( - canvas, - MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING), - MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING), - keyWidth, - KEY_HEIGHT); - canvas_set_color(canvas, ColorWhite); - } else { - // Draw a framed box - elements_slightly_rounded_frame( - canvas, - MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING), - MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING), - keyWidth, - KEY_HEIGHT); - } - if(key.icon != NULL) { - // Draw the icon centered on the button - canvas_draw_icon( - canvas, - MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING) + keyWidth / 2 - key.icon->width / 2, - MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING) + KEY_HEIGHT / 2 - key.icon->height / 2, - key.icon); - } else { - // If shift is toggled use the shift key when available - strcpy(model->key_string, (model->shift && key.shift_key != 0) ? key.shift_key : key.key); - // Upper case if ctrl or alt was toggled true - if((model->ctrl && key.value == HID_KEYBOARD_L_CTRL) || - (model->alt && key.value == HID_KEYBOARD_L_ALT) || - (model->gui && key.value == HID_KEYBOARD_L_GUI)) { - hid_keyboard_to_upper(model->key_string); - } - canvas_draw_str_aligned( - canvas, - MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING) + keyWidth / 2 + 1, - MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING) + KEY_HEIGHT / 2, - AlignCenter, - AlignCenter, - model->key_string); - } -} - -static void hid_keyboard_draw_callback(Canvas* canvas, void* context) { - furi_assert(context); - HidKeyboardModel* model = context; - - // Header - if((!model->connected) && (model->transport == HidTransportBle)) { - canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15); - canvas_set_font(canvas, FontPrimary); - elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Keyboard"); - - canvas_draw_icon(canvas, 68, 3, &I_Pin_back_arrow_10x8); - canvas_set_font(canvas, FontSecondary); - elements_multiline_text_aligned(canvas, 127, 4, AlignRight, AlignTop, "Hold to exit"); - - elements_multiline_text_aligned( - canvas, 4, 60, AlignLeft, AlignBottom, "Waiting for Connection..."); - return; // Dont render the keyboard if we are not yet connected - } - - canvas_set_font(canvas, FontKeyboard); - // Start shifting the all keys up if on the next row (Scrolling) - uint8_t initY = model->y == 0 ? 0 : 1; - - if(model->y > 5) { - initY = model->y - 4; - } - - for(uint8_t y = initY; y < ROW_COUNT; y++) { - const HidKeyboardKey* keyboardKeyRow = hid_keyboard_keyset[y]; - uint8_t x = 0; - for(uint8_t i = 0; i < COLUMN_COUNT; i++) { - HidKeyboardKey key = keyboardKeyRow[i]; - // Select when the button is hovered - // Select if the button is hovered within its width - // Select if back is clicked and its the backspace key - // Deselect when the button clicked or not hovered - bool keySelected = (x <= model->x && model->x < (x + key.width)) && y == model->y; - bool backSelected = model->back_pressed && key.value == HID_KEYBOARD_DELETE; - hid_keyboard_draw_key( - canvas, - model, - x, - y - initY, - key, - (!model->ok_pressed && keySelected) || backSelected); - x += key.width; - } - } -} - -static uint8_t hid_keyboard_get_selected_key(HidKeyboardModel* model) { - HidKeyboardKey key = hid_keyboard_keyset[model->y][model->x]; - return key.value; -} - -static void hid_keyboard_get_select_key(HidKeyboardModel* model, HidKeyboardPoint delta) { - // Keep going until a valid spot is found, this allows for nulls and zero width keys in the map - do { - const int delta_sum = model->y + delta.y; - model->y = delta_sum < 0 ? ROW_COUNT - 1 : delta_sum % ROW_COUNT; - } while(delta.y != 0 && hid_keyboard_keyset[model->y][model->x].value == 0); - - do { - const int delta_sum = model->x + delta.x; - model->x = delta_sum < 0 ? COLUMN_COUNT - 1 : delta_sum % COLUMN_COUNT; - } while(delta.x != 0 && hid_keyboard_keyset[model->y][model->x].width == - 0); // Skip zero width keys, pretend they are one key -} - -static void hid_keyboard_process(HidKeyboard* hid_keyboard, InputEvent* event) { - with_view_model( - hid_keyboard->view, - HidKeyboardModel * model, - { - if(event->key == InputKeyOk) { - if(event->type == InputTypePress) { - model->ok_pressed = true; - } else if(event->type == InputTypeLong || event->type == InputTypeShort) { - model->last_key_code = hid_keyboard_get_selected_key(model); - - // Toggle the modifier key when clicked, and click the key - if(model->last_key_code == HID_KEYBOARD_L_SHIFT) { - model->shift = !model->shift; - if(model->shift) - model->modifier_code |= KEY_MOD_LEFT_SHIFT; - else - model->modifier_code &= ~KEY_MOD_LEFT_SHIFT; - } else if(model->last_key_code == HID_KEYBOARD_L_ALT) { - model->alt = !model->alt; - if(model->alt) - model->modifier_code |= KEY_MOD_LEFT_ALT; - else - model->modifier_code &= ~KEY_MOD_LEFT_ALT; - } else if(model->last_key_code == HID_KEYBOARD_L_CTRL) { - model->ctrl = !model->ctrl; - if(model->ctrl) - model->modifier_code |= KEY_MOD_LEFT_CTRL; - else - model->modifier_code &= ~KEY_MOD_LEFT_CTRL; - } else if(model->last_key_code == HID_KEYBOARD_L_GUI) { - model->gui = !model->gui; - if(model->gui) - model->modifier_code |= KEY_MOD_LEFT_GUI; - else - model->modifier_code &= ~KEY_MOD_LEFT_GUI; - } - hid_hal_keyboard_press( - hid_keyboard->hid, model->modifier_code | model->last_key_code); - } else if(event->type == InputTypeRelease) { - // Release happens after short and long presses - hid_hal_keyboard_release( - hid_keyboard->hid, model->modifier_code | model->last_key_code); - model->ok_pressed = false; - } - } else if(event->key == InputKeyBack) { - // If back is pressed for a short time, backspace - if(event->type == InputTypePress) { - model->back_pressed = true; - } else if(event->type == InputTypeShort) { - hid_hal_keyboard_press(hid_keyboard->hid, HID_KEYBOARD_DELETE); - hid_hal_keyboard_release(hid_keyboard->hid, HID_KEYBOARD_DELETE); - } else if(event->type == InputTypeRelease) { - model->back_pressed = false; - } - } else if(event->type == InputTypePress || event->type == InputTypeRepeat) { - // Cycle the selected keys - if(event->key == InputKeyUp) { - hid_keyboard_get_select_key(model, (HidKeyboardPoint){.x = 0, .y = -1}); - } else if(event->key == InputKeyDown) { - hid_keyboard_get_select_key(model, (HidKeyboardPoint){.x = 0, .y = 1}); - } else if(event->key == InputKeyLeft) { - hid_keyboard_get_select_key(model, (HidKeyboardPoint){.x = -1, .y = 0}); - } else if(event->key == InputKeyRight) { - hid_keyboard_get_select_key(model, (HidKeyboardPoint){.x = 1, .y = 0}); - } - } - }, - true); -} - -static bool hid_keyboard_input_callback(InputEvent* event, void* context) { - furi_assert(context); - HidKeyboard* hid_keyboard = context; - bool consumed = false; - - if(event->type == InputTypeLong && event->key == InputKeyBack) { - hid_hal_keyboard_release_all(hid_keyboard->hid); - } else { - hid_keyboard_process(hid_keyboard, event); - consumed = true; - } - - return consumed; -} - -HidKeyboard* hid_keyboard_alloc(Hid* bt_hid) { - HidKeyboard* hid_keyboard = malloc(sizeof(HidKeyboard)); - hid_keyboard->view = view_alloc(); - hid_keyboard->hid = bt_hid; - view_set_context(hid_keyboard->view, hid_keyboard); - view_allocate_model(hid_keyboard->view, ViewModelTypeLocking, sizeof(HidKeyboardModel)); - view_set_draw_callback(hid_keyboard->view, hid_keyboard_draw_callback); - view_set_input_callback(hid_keyboard->view, hid_keyboard_input_callback); - - with_view_model( - hid_keyboard->view, - HidKeyboardModel * model, - { - model->transport = bt_hid->transport; - model->y = 1; - }, - true); - - return hid_keyboard; -} - -void hid_keyboard_free(HidKeyboard* hid_keyboard) { - furi_assert(hid_keyboard); - view_free(hid_keyboard->view); - free(hid_keyboard); -} - -View* hid_keyboard_get_view(HidKeyboard* hid_keyboard) { - furi_assert(hid_keyboard); - return hid_keyboard->view; -} - -void hid_keyboard_set_connected_status(HidKeyboard* hid_keyboard, bool connected) { - furi_assert(hid_keyboard); - with_view_model( - hid_keyboard->view, HidKeyboardModel * model, { model->connected = connected; }, true); -} diff --git a/applications/external/hid_app/views/hid_keyboard.h b/applications/external/hid_app/views/hid_keyboard.h deleted file mode 100644 index 712771364..000000000 --- a/applications/external/hid_app/views/hid_keyboard.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -typedef struct Hid Hid; -typedef struct HidKeyboard HidKeyboard; - -HidKeyboard* hid_keyboard_alloc(Hid* bt_hid); - -void hid_keyboard_free(HidKeyboard* hid_keyboard); - -View* hid_keyboard_get_view(HidKeyboard* hid_keyboard); - -void hid_keyboard_set_connected_status(HidKeyboard* hid_keyboard, bool connected); diff --git a/applications/external/hid_app/views/hid_keynote.c b/applications/external/hid_app/views/hid_keynote.c deleted file mode 100644 index 543363bf6..000000000 --- a/applications/external/hid_app/views/hid_keynote.c +++ /dev/null @@ -1,312 +0,0 @@ -#include "hid_keynote.h" -#include -#include "../hid.h" - -#include "hid_icons.h" - -#define TAG "HidKeynote" - -struct HidKeynote { - View* view; - Hid* hid; -}; - -typedef struct { - bool left_pressed; - bool up_pressed; - bool right_pressed; - bool down_pressed; - bool ok_pressed; - bool back_pressed; - bool connected; - HidTransport transport; -} HidKeynoteModel; - -static void hid_keynote_draw_arrow(Canvas* canvas, uint8_t x, uint8_t y, CanvasDirection dir) { - canvas_draw_triangle(canvas, x, y, 5, 3, dir); - if(dir == CanvasDirectionBottomToTop) { - canvas_draw_line(canvas, x, y + 6, x, y - 1); - } else if(dir == CanvasDirectionTopToBottom) { - canvas_draw_line(canvas, x, y - 6, x, y + 1); - } else if(dir == CanvasDirectionRightToLeft) { - canvas_draw_line(canvas, x + 6, y, x - 1, y); - } else if(dir == CanvasDirectionLeftToRight) { - canvas_draw_line(canvas, x - 6, y, x + 1, y); - } -} - -static void hid_keynote_draw_callback(Canvas* canvas, void* context) { - furi_assert(context); - HidKeynoteModel* model = context; - - // Header - if(model->transport == HidTransportBle) { - if(model->connected) { - canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15); - } else { - canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15); - } - } - - canvas_set_font(canvas, FontPrimary); - elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Keynote"); - - canvas_draw_icon(canvas, 68, 2, &I_Pin_back_arrow_10x8); - canvas_set_font(canvas, FontSecondary); - elements_multiline_text_aligned(canvas, 127, 3, AlignRight, AlignTop, "Hold to exit"); - - // Up - canvas_draw_icon(canvas, 21, 24, &I_Button_18x18); - if(model->up_pressed) { - elements_slightly_rounded_box(canvas, 24, 26, 13, 13); - canvas_set_color(canvas, ColorWhite); - } - hid_keynote_draw_arrow(canvas, 30, 30, CanvasDirectionBottomToTop); - canvas_set_color(canvas, ColorBlack); - - // Down - canvas_draw_icon(canvas, 21, 45, &I_Button_18x18); - if(model->down_pressed) { - elements_slightly_rounded_box(canvas, 24, 47, 13, 13); - canvas_set_color(canvas, ColorWhite); - } - hid_keynote_draw_arrow(canvas, 30, 55, CanvasDirectionTopToBottom); - canvas_set_color(canvas, ColorBlack); - - // Left - canvas_draw_icon(canvas, 0, 45, &I_Button_18x18); - if(model->left_pressed) { - elements_slightly_rounded_box(canvas, 3, 47, 13, 13); - canvas_set_color(canvas, ColorWhite); - } - hid_keynote_draw_arrow(canvas, 7, 53, CanvasDirectionRightToLeft); - canvas_set_color(canvas, ColorBlack); - - // Right - canvas_draw_icon(canvas, 42, 45, &I_Button_18x18); - if(model->right_pressed) { - elements_slightly_rounded_box(canvas, 45, 47, 13, 13); - canvas_set_color(canvas, ColorWhite); - } - hid_keynote_draw_arrow(canvas, 53, 53, CanvasDirectionLeftToRight); - canvas_set_color(canvas, ColorBlack); - - // Ok - canvas_draw_icon(canvas, 63, 25, &I_Space_65x18); - if(model->ok_pressed) { - elements_slightly_rounded_box(canvas, 66, 27, 60, 13); - canvas_set_color(canvas, ColorWhite); - } - canvas_draw_icon(canvas, 74, 29, &I_Ok_btn_9x9); - elements_multiline_text_aligned(canvas, 91, 36, AlignLeft, AlignBottom, "Space"); - canvas_set_color(canvas, ColorBlack); - - // Back - canvas_draw_icon(canvas, 63, 45, &I_Space_65x18); - if(model->back_pressed) { - elements_slightly_rounded_box(canvas, 66, 47, 60, 13); - canvas_set_color(canvas, ColorWhite); - } - canvas_draw_icon(canvas, 74, 49, &I_Pin_back_arrow_10x8); - elements_multiline_text_aligned(canvas, 91, 57, AlignLeft, AlignBottom, "Back"); -} - -static void hid_keynote_draw_vertical_callback(Canvas* canvas, void* context) { - furi_assert(context); - HidKeynoteModel* model = context; - - // Header - if(model->transport == HidTransportBle) { - if(model->connected) { - canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15); - } else { - canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15); - } - canvas_set_font(canvas, FontPrimary); - elements_multiline_text_aligned(canvas, 20, 3, AlignLeft, AlignTop, "Keynote"); - } else { - canvas_set_font(canvas, FontPrimary); - elements_multiline_text_aligned(canvas, 12, 3, AlignLeft, AlignTop, "Keynote"); - } - - canvas_draw_icon(canvas, 2, 18, &I_Pin_back_arrow_10x8); - canvas_set_font(canvas, FontSecondary); - elements_multiline_text_aligned(canvas, 15, 19, AlignLeft, AlignTop, "Hold to exit"); - - const uint8_t x_2 = 23; - const uint8_t x_1 = 2; - const uint8_t x_3 = 44; - - const uint8_t y_1 = 44; - const uint8_t y_2 = 65; - - // Up - canvas_draw_icon(canvas, x_2, y_1, &I_Button_18x18); - if(model->up_pressed) { - elements_slightly_rounded_box(canvas, x_2 + 3, y_1 + 2, 13, 13); - canvas_set_color(canvas, ColorWhite); - } - hid_keynote_draw_arrow(canvas, x_2 + 9, y_1 + 6, CanvasDirectionBottomToTop); - canvas_set_color(canvas, ColorBlack); - - // Down - canvas_draw_icon(canvas, x_2, y_2, &I_Button_18x18); - if(model->down_pressed) { - elements_slightly_rounded_box(canvas, x_2 + 3, y_2 + 2, 13, 13); - canvas_set_color(canvas, ColorWhite); - } - hid_keynote_draw_arrow(canvas, x_2 + 9, y_2 + 10, CanvasDirectionTopToBottom); - canvas_set_color(canvas, ColorBlack); - - // Left - canvas_draw_icon(canvas, x_1, y_2, &I_Button_18x18); - if(model->left_pressed) { - elements_slightly_rounded_box(canvas, x_1 + 3, y_2 + 2, 13, 13); - canvas_set_color(canvas, ColorWhite); - } - hid_keynote_draw_arrow(canvas, x_1 + 7, y_2 + 8, CanvasDirectionRightToLeft); - canvas_set_color(canvas, ColorBlack); - - // Right - canvas_draw_icon(canvas, x_3, y_2, &I_Button_18x18); - if(model->right_pressed) { - elements_slightly_rounded_box(canvas, x_3 + 3, y_2 + 2, 13, 13); - canvas_set_color(canvas, ColorWhite); - } - hid_keynote_draw_arrow(canvas, x_3 + 11, y_2 + 8, CanvasDirectionLeftToRight); - canvas_set_color(canvas, ColorBlack); - - // Ok - canvas_draw_icon(canvas, 2, 86, &I_Space_60x18); - if(model->ok_pressed) { - elements_slightly_rounded_box(canvas, 5, 88, 55, 13); - canvas_set_color(canvas, ColorWhite); - } - canvas_draw_icon(canvas, 11, 90, &I_Ok_btn_9x9); - elements_multiline_text_aligned(canvas, 26, 98, AlignLeft, AlignBottom, "Space"); - canvas_set_color(canvas, ColorBlack); - - // Back - canvas_draw_icon(canvas, 2, 107, &I_Space_60x18); - if(model->back_pressed) { - elements_slightly_rounded_box(canvas, 5, 109, 55, 13); - canvas_set_color(canvas, ColorWhite); - } - canvas_draw_icon(canvas, 11, 111, &I_Pin_back_arrow_10x8); - elements_multiline_text_aligned(canvas, 26, 119, AlignLeft, AlignBottom, "Back"); -} - -static void hid_keynote_process(HidKeynote* hid_keynote, InputEvent* event) { - with_view_model( - hid_keynote->view, - HidKeynoteModel * model, - { - if(event->type == InputTypePress) { - if(event->key == InputKeyUp) { - model->up_pressed = true; - hid_hal_keyboard_press(hid_keynote->hid, HID_KEYBOARD_UP_ARROW); - } else if(event->key == InputKeyDown) { - model->down_pressed = true; - hid_hal_keyboard_press(hid_keynote->hid, HID_KEYBOARD_DOWN_ARROW); - } else if(event->key == InputKeyLeft) { - model->left_pressed = true; - hid_hal_keyboard_press(hid_keynote->hid, HID_KEYBOARD_LEFT_ARROW); - } else if(event->key == InputKeyRight) { - model->right_pressed = true; - hid_hal_keyboard_press(hid_keynote->hid, HID_KEYBOARD_RIGHT_ARROW); - } else if(event->key == InputKeyOk) { - model->ok_pressed = true; - hid_hal_keyboard_press(hid_keynote->hid, HID_KEYBOARD_SPACEBAR); - } else if(event->key == InputKeyBack) { - model->back_pressed = true; - } - } else if(event->type == InputTypeRelease) { - if(event->key == InputKeyUp) { - model->up_pressed = false; - hid_hal_keyboard_release(hid_keynote->hid, HID_KEYBOARD_UP_ARROW); - } else if(event->key == InputKeyDown) { - model->down_pressed = false; - hid_hal_keyboard_release(hid_keynote->hid, HID_KEYBOARD_DOWN_ARROW); - } else if(event->key == InputKeyLeft) { - model->left_pressed = false; - hid_hal_keyboard_release(hid_keynote->hid, HID_KEYBOARD_LEFT_ARROW); - } else if(event->key == InputKeyRight) { - model->right_pressed = false; - hid_hal_keyboard_release(hid_keynote->hid, HID_KEYBOARD_RIGHT_ARROW); - } else if(event->key == InputKeyOk) { - model->ok_pressed = false; - hid_hal_keyboard_release(hid_keynote->hid, HID_KEYBOARD_SPACEBAR); - } else if(event->key == InputKeyBack) { - model->back_pressed = false; - } - } else if(event->type == InputTypeShort) { - if(event->key == InputKeyBack) { - hid_hal_keyboard_press(hid_keynote->hid, HID_KEYBOARD_DELETE); - hid_hal_keyboard_release(hid_keynote->hid, HID_KEYBOARD_DELETE); - hid_hal_consumer_key_press(hid_keynote->hid, HID_CONSUMER_AC_BACK); - hid_hal_consumer_key_release(hid_keynote->hid, HID_CONSUMER_AC_BACK); - } - } - }, - true); -} - -static bool hid_keynote_input_callback(InputEvent* event, void* context) { - furi_assert(context); - HidKeynote* hid_keynote = context; - bool consumed = false; - - if(event->type == InputTypeLong && event->key == InputKeyBack) { - hid_hal_keyboard_release_all(hid_keynote->hid); - } else { - hid_keynote_process(hid_keynote, event); - consumed = true; - } - - return consumed; -} - -HidKeynote* hid_keynote_alloc(Hid* hid) { - HidKeynote* hid_keynote = malloc(sizeof(HidKeynote)); - hid_keynote->view = view_alloc(); - hid_keynote->hid = hid; - view_set_context(hid_keynote->view, hid_keynote); - view_allocate_model(hid_keynote->view, ViewModelTypeLocking, sizeof(HidKeynoteModel)); - view_set_draw_callback(hid_keynote->view, hid_keynote_draw_callback); - view_set_input_callback(hid_keynote->view, hid_keynote_input_callback); - - with_view_model( - hid_keynote->view, HidKeynoteModel * model, { model->transport = hid->transport; }, true); - - return hid_keynote; -} - -void hid_keynote_free(HidKeynote* hid_keynote) { - furi_assert(hid_keynote); - view_free(hid_keynote->view); - free(hid_keynote); -} - -View* hid_keynote_get_view(HidKeynote* hid_keynote) { - furi_assert(hid_keynote); - return hid_keynote->view; -} - -void hid_keynote_set_connected_status(HidKeynote* hid_keynote, bool connected) { - furi_assert(hid_keynote); - with_view_model( - hid_keynote->view, HidKeynoteModel * model, { model->connected = connected; }, true); -} - -void hid_keynote_set_orientation(HidKeynote* hid_keynote, bool vertical) { - furi_assert(hid_keynote); - - if(vertical) { - view_set_draw_callback(hid_keynote->view, hid_keynote_draw_vertical_callback); - view_set_orientation(hid_keynote->view, ViewOrientationVerticalFlip); - - } else { - view_set_draw_callback(hid_keynote->view, hid_keynote_draw_callback); - view_set_orientation(hid_keynote->view, ViewOrientationHorizontal); - } -} diff --git a/applications/external/hid_app/views/hid_keynote.h b/applications/external/hid_app/views/hid_keynote.h deleted file mode 100644 index 84bfed4ce..000000000 --- a/applications/external/hid_app/views/hid_keynote.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include - -typedef struct Hid Hid; -typedef struct HidKeynote HidKeynote; - -HidKeynote* hid_keynote_alloc(Hid* bt_hid); - -void hid_keynote_free(HidKeynote* hid_keynote); - -View* hid_keynote_get_view(HidKeynote* hid_keynote); - -void hid_keynote_set_connected_status(HidKeynote* hid_keynote, bool connected); - -void hid_keynote_set_orientation(HidKeynote* hid_keynote, bool vertical); diff --git a/applications/external/hid_app/views/hid_media.c b/applications/external/hid_app/views/hid_media.c deleted file mode 100644 index 468529d56..000000000 --- a/applications/external/hid_app/views/hid_media.c +++ /dev/null @@ -1,218 +0,0 @@ -#include "hid_media.h" -#include -#include -#include -#include -#include "../hid.h" - -#include "hid_icons.h" - -#define TAG "HidMedia" - -struct HidMedia { - View* view; - Hid* hid; -}; - -typedef struct { - bool left_pressed; - bool up_pressed; - bool right_pressed; - bool down_pressed; - bool ok_pressed; - bool connected; - HidTransport transport; -} HidMediaModel; - -static void hid_media_draw_arrow(Canvas* canvas, uint8_t x, uint8_t y, CanvasDirection dir) { - canvas_draw_triangle(canvas, x, y, 5, 3, dir); - if(dir == CanvasDirectionBottomToTop) { - canvas_draw_dot(canvas, x, y - 1); - } else if(dir == CanvasDirectionTopToBottom) { - canvas_draw_dot(canvas, x, y + 1); - } else if(dir == CanvasDirectionRightToLeft) { - canvas_draw_dot(canvas, x - 1, y); - } else if(dir == CanvasDirectionLeftToRight) { - canvas_draw_dot(canvas, x + 1, y); - } -} - -static void hid_media_draw_callback(Canvas* canvas, void* context) { - furi_assert(context); - HidMediaModel* model = context; - - // Header - if(model->transport == HidTransportBle) { - if(model->connected) { - canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15); - } else { - canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15); - } - } - - canvas_set_font(canvas, FontPrimary); - elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Media"); - canvas_set_font(canvas, FontSecondary); - - // Keypad circles - canvas_draw_icon(canvas, 76, 8, &I_Circles_47x47); - - // Up - if(model->up_pressed) { - canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 93, 9, &I_Pressed_Button_13x13); - canvas_set_bitmap_mode(canvas, 0); - canvas_set_color(canvas, ColorWhite); - } - canvas_draw_icon(canvas, 96, 12, &I_Volup_8x6); - canvas_set_color(canvas, ColorBlack); - - // Down - if(model->down_pressed) { - canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 93, 41, &I_Pressed_Button_13x13); - canvas_set_bitmap_mode(canvas, 0); - canvas_set_color(canvas, ColorWhite); - } - canvas_draw_icon(canvas, 96, 45, &I_Voldwn_6x6); - canvas_set_color(canvas, ColorBlack); - - // Left - if(model->left_pressed) { - canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 77, 25, &I_Pressed_Button_13x13); - canvas_set_bitmap_mode(canvas, 0); - canvas_set_color(canvas, ColorWhite); - } - hid_media_draw_arrow(canvas, 82, 31, CanvasDirectionRightToLeft); - hid_media_draw_arrow(canvas, 86, 31, CanvasDirectionRightToLeft); - canvas_set_color(canvas, ColorBlack); - - // Right - if(model->right_pressed) { - canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 109, 25, &I_Pressed_Button_13x13); - canvas_set_bitmap_mode(canvas, 0); - canvas_set_color(canvas, ColorWhite); - } - hid_media_draw_arrow(canvas, 112, 31, CanvasDirectionLeftToRight); - hid_media_draw_arrow(canvas, 116, 31, CanvasDirectionLeftToRight); - canvas_set_color(canvas, ColorBlack); - - // Ok - if(model->ok_pressed) { - canvas_draw_icon(canvas, 93, 25, &I_Pressed_Button_13x13); - canvas_set_color(canvas, ColorWhite); - } - hid_media_draw_arrow(canvas, 96, 31, CanvasDirectionLeftToRight); - canvas_draw_line(canvas, 100, 29, 100, 33); - canvas_draw_line(canvas, 102, 29, 102, 33); - canvas_set_color(canvas, ColorBlack); - - // Exit - canvas_draw_icon(canvas, 0, 54, &I_Pin_back_arrow_10x8); - canvas_set_font(canvas, FontSecondary); - elements_multiline_text_aligned(canvas, 13, 62, AlignLeft, AlignBottom, "Hold to exit"); -} - -static void hid_media_process_press(HidMedia* hid_media, InputEvent* event) { - with_view_model( - hid_media->view, - HidMediaModel * model, - { - if(event->key == InputKeyUp) { - model->up_pressed = true; - hid_hal_consumer_key_press(hid_media->hid, HID_CONSUMER_VOLUME_INCREMENT); - } else if(event->key == InputKeyDown) { - model->down_pressed = true; - hid_hal_consumer_key_press(hid_media->hid, HID_CONSUMER_VOLUME_DECREMENT); - } else if(event->key == InputKeyLeft) { - model->left_pressed = true; - hid_hal_consumer_key_press(hid_media->hid, HID_CONSUMER_SCAN_PREVIOUS_TRACK); - } else if(event->key == InputKeyRight) { - model->right_pressed = true; - hid_hal_consumer_key_press(hid_media->hid, HID_CONSUMER_SCAN_NEXT_TRACK); - } else if(event->key == InputKeyOk) { - model->ok_pressed = true; - hid_hal_consumer_key_press(hid_media->hid, HID_CONSUMER_PLAY_PAUSE); - } - }, - true); -} - -static void hid_media_process_release(HidMedia* hid_media, InputEvent* event) { - with_view_model( - hid_media->view, - HidMediaModel * model, - { - if(event->key == InputKeyUp) { - model->up_pressed = false; - hid_hal_consumer_key_release(hid_media->hid, HID_CONSUMER_VOLUME_INCREMENT); - } else if(event->key == InputKeyDown) { - model->down_pressed = false; - hid_hal_consumer_key_release(hid_media->hid, HID_CONSUMER_VOLUME_DECREMENT); - } else if(event->key == InputKeyLeft) { - model->left_pressed = false; - hid_hal_consumer_key_release(hid_media->hid, HID_CONSUMER_SCAN_PREVIOUS_TRACK); - } else if(event->key == InputKeyRight) { - model->right_pressed = false; - hid_hal_consumer_key_release(hid_media->hid, HID_CONSUMER_SCAN_NEXT_TRACK); - } else if(event->key == InputKeyOk) { - model->ok_pressed = false; - hid_hal_consumer_key_release(hid_media->hid, HID_CONSUMER_PLAY_PAUSE); - } - }, - true); -} - -static bool hid_media_input_callback(InputEvent* event, void* context) { - furi_assert(context); - HidMedia* hid_media = context; - bool consumed = false; - - if(event->type == InputTypePress) { - hid_media_process_press(hid_media, event); - consumed = true; - } else if(event->type == InputTypeRelease) { - hid_media_process_release(hid_media, event); - consumed = true; - } else if(event->type == InputTypeShort) { - if(event->key == InputKeyBack) { - hid_hal_consumer_key_release_all(hid_media->hid); - } - } - - return consumed; -} - -HidMedia* hid_media_alloc(Hid* hid) { - HidMedia* hid_media = malloc(sizeof(HidMedia)); - hid_media->view = view_alloc(); - hid_media->hid = hid; - view_set_context(hid_media->view, hid_media); - view_allocate_model(hid_media->view, ViewModelTypeLocking, sizeof(HidMediaModel)); - view_set_draw_callback(hid_media->view, hid_media_draw_callback); - view_set_input_callback(hid_media->view, hid_media_input_callback); - - with_view_model( - hid_media->view, HidMediaModel * model, { model->transport = hid->transport; }, true); - - return hid_media; -} - -void hid_media_free(HidMedia* hid_media) { - furi_assert(hid_media); - view_free(hid_media->view); - free(hid_media); -} - -View* hid_media_get_view(HidMedia* hid_media) { - furi_assert(hid_media); - return hid_media->view; -} - -void hid_media_set_connected_status(HidMedia* hid_media, bool connected) { - furi_assert(hid_media); - with_view_model( - hid_media->view, HidMediaModel * model, { model->connected = connected; }, true); -} diff --git a/applications/external/hid_app/views/hid_media.h b/applications/external/hid_app/views/hid_media.h deleted file mode 100644 index 4aa51dc17..000000000 --- a/applications/external/hid_app/views/hid_media.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include - -typedef struct HidMedia HidMedia; - -HidMedia* hid_media_alloc(); - -void hid_media_free(HidMedia* hid_media); - -View* hid_media_get_view(HidMedia* hid_media); - -void hid_media_set_connected_status(HidMedia* hid_media, bool connected); diff --git a/applications/external/hid_app/views/hid_mouse.c b/applications/external/hid_app/views/hid_mouse.c deleted file mode 100644 index 30a9d9d06..000000000 --- a/applications/external/hid_app/views/hid_mouse.c +++ /dev/null @@ -1,226 +0,0 @@ -#include "hid_mouse.h" -#include -#include "../hid.h" - -#include "hid_icons.h" - -#define TAG "HidMouse" - -struct HidMouse { - View* view; - Hid* hid; -}; - -typedef struct { - bool left_pressed; - bool up_pressed; - bool right_pressed; - bool down_pressed; - bool left_mouse_pressed; - bool left_mouse_held; - bool right_mouse_pressed; - bool connected; - HidTransport transport; -} HidMouseModel; - -static void hid_mouse_draw_callback(Canvas* canvas, void* context) { - furi_assert(context); - HidMouseModel* model = context; - - // Header - if(model->transport == HidTransportBle) { - if(model->connected) { - canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15); - } else { - canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15); - } - } - - canvas_set_font(canvas, FontPrimary); - elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Mouse"); - canvas_set_font(canvas, FontSecondary); - - if(model->left_mouse_held == true) { - elements_multiline_text_aligned(canvas, 0, 62, AlignLeft, AlignBottom, "Selecting..."); - } else { - canvas_draw_icon(canvas, 0, 54, &I_Pin_back_arrow_10x8); - canvas_set_font(canvas, FontSecondary); - elements_multiline_text_aligned(canvas, 13, 62, AlignLeft, AlignBottom, "Hold to exit"); - } - - // Keypad circles - canvas_draw_icon(canvas, 64, 8, &I_Circles_47x47); - - // Up - if(model->up_pressed) { - canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 81, 9, &I_Pressed_Button_13x13); - canvas_set_bitmap_mode(canvas, 0); - canvas_set_color(canvas, ColorWhite); - } - canvas_draw_icon(canvas, 84, 10, &I_Pin_arrow_up_7x9); - canvas_set_color(canvas, ColorBlack); - - // Down - if(model->down_pressed) { - canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 81, 41, &I_Pressed_Button_13x13); - canvas_set_bitmap_mode(canvas, 0); - canvas_set_color(canvas, ColorWhite); - } - canvas_draw_icon(canvas, 84, 43, &I_Pin_arrow_down_7x9); - canvas_set_color(canvas, ColorBlack); - - // Left - if(model->left_pressed) { - canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 65, 25, &I_Pressed_Button_13x13); - canvas_set_bitmap_mode(canvas, 0); - canvas_set_color(canvas, ColorWhite); - } - canvas_draw_icon(canvas, 67, 28, &I_Pin_arrow_left_9x7); - canvas_set_color(canvas, ColorBlack); - - // Right - if(model->right_pressed) { - canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 97, 25, &I_Pressed_Button_13x13); - canvas_set_bitmap_mode(canvas, 0); - canvas_set_color(canvas, ColorWhite); - } - canvas_draw_icon(canvas, 99, 28, &I_Pin_arrow_right_9x7); - canvas_set_color(canvas, ColorBlack); - - // Ok - if(model->left_mouse_pressed) { - canvas_draw_icon(canvas, 81, 25, &I_Ok_btn_pressed_13x13); - } else { - canvas_draw_icon(canvas, 83, 27, &I_Left_mouse_icon_9x9); - } - - // Back - if(model->right_mouse_pressed) { - canvas_draw_icon(canvas, 108, 48, &I_Ok_btn_pressed_13x13); - } else { - canvas_draw_icon(canvas, 110, 50, &I_Right_mouse_icon_9x9); - } -} - -static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { - with_view_model( - hid_mouse->view, - HidMouseModel * model, - { - if(event->key == InputKeyBack) { - if(event->type == InputTypeShort) { - hid_hal_mouse_press(hid_mouse->hid, HID_MOUSE_BTN_RIGHT); - hid_hal_mouse_release(hid_mouse->hid, HID_MOUSE_BTN_RIGHT); - } else if(event->type == InputTypePress) { - model->right_mouse_pressed = true; - } else if(event->type == InputTypeRelease) { - model->right_mouse_pressed = false; - } - } else if(event->key == InputKeyOk) { - if(event->type == InputTypeShort) { - // Just release if it was being held before - if(!model->left_mouse_held) - hid_hal_mouse_press(hid_mouse->hid, HID_MOUSE_BTN_LEFT); - hid_hal_mouse_release(hid_mouse->hid, HID_MOUSE_BTN_LEFT); - model->left_mouse_held = false; - } else if(event->type == InputTypeLong) { - hid_hal_mouse_press(hid_mouse->hid, HID_MOUSE_BTN_LEFT); - model->left_mouse_held = true; - model->left_mouse_pressed = true; - } else if(event->type == InputTypePress) { - model->left_mouse_pressed = true; - } else if(event->type == InputTypeRelease) { - // Only release if it wasn't a long press - if(!model->left_mouse_held) model->left_mouse_pressed = false; - } - } else if(event->key == InputKeyRight) { - if(event->type == InputTypePress) { - model->right_pressed = true; - hid_hal_mouse_move(hid_mouse->hid, MOUSE_MOVE_SHORT, 0); - } else if(event->type == InputTypeRepeat) { - hid_hal_mouse_move(hid_mouse->hid, MOUSE_MOVE_LONG, 0); - } else if(event->type == InputTypeRelease) { - model->right_pressed = false; - } - } else if(event->key == InputKeyLeft) { - if(event->type == InputTypePress) { - model->left_pressed = true; - hid_hal_mouse_move(hid_mouse->hid, -MOUSE_MOVE_SHORT, 0); - } else if(event->type == InputTypeRepeat) { - hid_hal_mouse_move(hid_mouse->hid, -MOUSE_MOVE_LONG, 0); - } else if(event->type == InputTypeRelease) { - model->left_pressed = false; - } - } else if(event->key == InputKeyDown) { - if(event->type == InputTypePress) { - model->down_pressed = true; - hid_hal_mouse_move(hid_mouse->hid, 0, MOUSE_MOVE_SHORT); - } else if(event->type == InputTypeRepeat) { - hid_hal_mouse_move(hid_mouse->hid, 0, MOUSE_MOVE_LONG); - } else if(event->type == InputTypeRelease) { - model->down_pressed = false; - } - } else if(event->key == InputKeyUp) { - if(event->type == InputTypePress) { - model->up_pressed = true; - hid_hal_mouse_move(hid_mouse->hid, 0, -MOUSE_MOVE_SHORT); - } else if(event->type == InputTypeRepeat) { - hid_hal_mouse_move(hid_mouse->hid, 0, -MOUSE_MOVE_LONG); - } else if(event->type == InputTypeRelease) { - model->up_pressed = false; - } - } - }, - true); -} - -static bool hid_mouse_input_callback(InputEvent* event, void* context) { - furi_assert(context); - HidMouse* hid_mouse = context; - bool consumed = false; - - if(event->type == InputTypeLong && event->key == InputKeyBack) { - hid_hal_mouse_release_all(hid_mouse->hid); - } else { - hid_mouse_process(hid_mouse, event); - consumed = true; - } - - return consumed; -} - -HidMouse* hid_mouse_alloc(Hid* hid) { - HidMouse* hid_mouse = malloc(sizeof(HidMouse)); - hid_mouse->view = view_alloc(); - hid_mouse->hid = hid; - view_set_context(hid_mouse->view, hid_mouse); - view_allocate_model(hid_mouse->view, ViewModelTypeLocking, sizeof(HidMouseModel)); - view_set_draw_callback(hid_mouse->view, hid_mouse_draw_callback); - view_set_input_callback(hid_mouse->view, hid_mouse_input_callback); - - with_view_model( - hid_mouse->view, HidMouseModel * model, { model->transport = hid->transport; }, true); - - return hid_mouse; -} - -void hid_mouse_free(HidMouse* hid_mouse) { - furi_assert(hid_mouse); - view_free(hid_mouse->view); - free(hid_mouse); -} - -View* hid_mouse_get_view(HidMouse* hid_mouse) { - furi_assert(hid_mouse); - return hid_mouse->view; -} - -void hid_mouse_set_connected_status(HidMouse* hid_mouse, bool connected) { - furi_assert(hid_mouse); - with_view_model( - hid_mouse->view, HidMouseModel * model, { model->connected = connected; }, true); -} diff --git a/applications/external/hid_app/views/hid_mouse.h b/applications/external/hid_app/views/hid_mouse.h deleted file mode 100644 index d9fb2fd88..000000000 --- a/applications/external/hid_app/views/hid_mouse.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include - -#define MOUSE_MOVE_SHORT 5 -#define MOUSE_MOVE_LONG 20 - -typedef struct Hid Hid; -typedef struct HidMouse HidMouse; - -HidMouse* hid_mouse_alloc(Hid* bt_hid); - -void hid_mouse_free(HidMouse* hid_mouse); - -View* hid_mouse_get_view(HidMouse* hid_mouse); - -void hid_mouse_set_connected_status(HidMouse* hid_mouse, bool connected); diff --git a/applications/external/hid_app/views/hid_mouse_clicker.c b/applications/external/hid_app/views/hid_mouse_clicker.c deleted file mode 100644 index d85affc43..000000000 --- a/applications/external/hid_app/views/hid_mouse_clicker.c +++ /dev/null @@ -1,214 +0,0 @@ -#include "hid_mouse_clicker.h" -#include -#include "../hid.h" - -#include "hid_icons.h" - -#define TAG "HidMouseClicker" -#define DEFAULT_CLICK_RATE 1 -#define MAXIMUM_CLICK_RATE 60 - -struct HidMouseClicker { - View* view; - Hid* hid; - FuriTimer* timer; -}; - -typedef struct { - bool connected; - bool running; - int rate; - HidTransport transport; -} HidMouseClickerModel; - -static void hid_mouse_clicker_start_or_restart_timer(void* context) { - furi_assert(context); - HidMouseClicker* hid_mouse_clicker = context; - - if(furi_timer_is_running(hid_mouse_clicker->timer)) { - furi_timer_stop(hid_mouse_clicker->timer); - } - - with_view_model( - hid_mouse_clicker->view, - HidMouseClickerModel * model, - { - furi_timer_start( - hid_mouse_clicker->timer, furi_kernel_get_tick_frequency() / model->rate); - }, - true); -} - -static void hid_mouse_clicker_draw_callback(Canvas* canvas, void* context) { - furi_assert(context); - HidMouseClickerModel* model = context; - - // Header - if(model->transport == HidTransportBle) { - if(model->connected) { - canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15); - } else { - canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15); - } - } - - canvas_set_font(canvas, FontPrimary); - elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Mouse Clicker"); - - // Ok - canvas_draw_icon(canvas, 63, 25, &I_Space_65x18); - if(model->running) { - canvas_set_font(canvas, FontPrimary); - - FuriString* rate_label = furi_string_alloc(); - furi_string_printf(rate_label, "%d clicks/s\n\nUp / Down", model->rate); - elements_multiline_text(canvas, AlignLeft, 35, furi_string_get_cstr(rate_label)); - canvas_set_font(canvas, FontSecondary); - furi_string_free(rate_label); - - elements_slightly_rounded_box(canvas, 66, 27, 60, 13); - canvas_set_color(canvas, ColorWhite); - } else { - canvas_set_font(canvas, FontPrimary); - elements_multiline_text(canvas, AlignLeft, 35, "Press Start\nto start\nclicking"); - canvas_set_font(canvas, FontSecondary); - } - canvas_draw_icon(canvas, 74, 29, &I_Ok_btn_9x9); - if(model->running) { - elements_multiline_text_aligned(canvas, 91, 36, AlignLeft, AlignBottom, "Stop"); - } else { - elements_multiline_text_aligned(canvas, 91, 36, AlignLeft, AlignBottom, "Start"); - } - canvas_set_color(canvas, ColorBlack); - - // Back - canvas_draw_icon(canvas, 74, 49, &I_Pin_back_arrow_10x8); - elements_multiline_text_aligned(canvas, 91, 57, AlignLeft, AlignBottom, "Quit"); -} - -static void hid_mouse_clicker_timer_callback(void* context) { - furi_assert(context); - HidMouseClicker* hid_mouse_clicker = context; - with_view_model( - hid_mouse_clicker->view, - HidMouseClickerModel * model, - { - if(model->running) { - hid_hal_mouse_press(hid_mouse_clicker->hid, HID_MOUSE_BTN_LEFT); - hid_hal_mouse_release(hid_mouse_clicker->hid, HID_MOUSE_BTN_LEFT); - } - }, - false); -} - -static void hid_mouse_clicker_enter_callback(void* context) { - hid_mouse_clicker_start_or_restart_timer(context); -} - -static void hid_mouse_clicker_exit_callback(void* context) { - furi_assert(context); - HidMouseClicker* hid_mouse_clicker = context; - furi_timer_stop(hid_mouse_clicker->timer); -} - -static bool hid_mouse_clicker_input_callback(InputEvent* event, void* context) { - furi_assert(context); - HidMouseClicker* hid_mouse_clicker = context; - - bool consumed = false; - bool rate_changed = false; - - if(event->type != InputTypeShort && event->type != InputTypeRepeat) { - return false; - } - - with_view_model( - hid_mouse_clicker->view, - HidMouseClickerModel * model, - { - switch(event->key) { - case InputKeyOk: - model->running = !model->running; - consumed = true; - break; - case InputKeyUp: - if(model->rate < MAXIMUM_CLICK_RATE) { - model->rate++; - } - rate_changed = true; - consumed = true; - break; - case InputKeyDown: - if(model->rate > 1) { - model->rate--; - } - rate_changed = true; - consumed = true; - break; - default: - consumed = true; - break; - } - }, - true); - - if(rate_changed) { - hid_mouse_clicker_start_or_restart_timer(context); - } - - return consumed; -} - -HidMouseClicker* hid_mouse_clicker_alloc(Hid* hid) { - HidMouseClicker* hid_mouse_clicker = malloc(sizeof(HidMouseClicker)); - - hid_mouse_clicker->view = view_alloc(); - view_set_context(hid_mouse_clicker->view, hid_mouse_clicker); - view_allocate_model( - hid_mouse_clicker->view, ViewModelTypeLocking, sizeof(HidMouseClickerModel)); - view_set_draw_callback(hid_mouse_clicker->view, hid_mouse_clicker_draw_callback); - view_set_input_callback(hid_mouse_clicker->view, hid_mouse_clicker_input_callback); - view_set_enter_callback(hid_mouse_clicker->view, hid_mouse_clicker_enter_callback); - view_set_exit_callback(hid_mouse_clicker->view, hid_mouse_clicker_exit_callback); - - hid_mouse_clicker->hid = hid; - - hid_mouse_clicker->timer = furi_timer_alloc( - hid_mouse_clicker_timer_callback, FuriTimerTypePeriodic, hid_mouse_clicker); - - with_view_model( - hid_mouse_clicker->view, - HidMouseClickerModel * model, - { - model->transport = hid->transport; - model->rate = DEFAULT_CLICK_RATE; - }, - true); - - return hid_mouse_clicker; -} - -void hid_mouse_clicker_free(HidMouseClicker* hid_mouse_clicker) { - furi_assert(hid_mouse_clicker); - - furi_timer_stop(hid_mouse_clicker->timer); - furi_timer_free(hid_mouse_clicker->timer); - - view_free(hid_mouse_clicker->view); - - free(hid_mouse_clicker); -} - -View* hid_mouse_clicker_get_view(HidMouseClicker* hid_mouse_clicker) { - furi_assert(hid_mouse_clicker); - return hid_mouse_clicker->view; -} - -void hid_mouse_clicker_set_connected_status(HidMouseClicker* hid_mouse_clicker, bool connected) { - furi_assert(hid_mouse_clicker); - with_view_model( - hid_mouse_clicker->view, - HidMouseClickerModel * model, - { model->connected = connected; }, - true); -} diff --git a/applications/external/hid_app/views/hid_mouse_clicker.h b/applications/external/hid_app/views/hid_mouse_clicker.h deleted file mode 100644 index d72847baa..000000000 --- a/applications/external/hid_app/views/hid_mouse_clicker.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -typedef struct Hid Hid; -typedef struct HidMouseClicker HidMouseClicker; - -HidMouseClicker* hid_mouse_clicker_alloc(Hid* bt_hid); - -void hid_mouse_clicker_free(HidMouseClicker* hid_mouse_clicker); - -View* hid_mouse_clicker_get_view(HidMouseClicker* hid_mouse_clicker); - -void hid_mouse_clicker_set_connected_status(HidMouseClicker* hid_mouse_clicker, bool connected); diff --git a/applications/external/hid_app/views/hid_mouse_jiggler.c b/applications/external/hid_app/views/hid_mouse_jiggler.c deleted file mode 100644 index 15547eb26..000000000 --- a/applications/external/hid_app/views/hid_mouse_jiggler.c +++ /dev/null @@ -1,159 +0,0 @@ -#include "hid_mouse_jiggler.h" -#include -#include "../hid.h" - -#include "hid_icons.h" - -#define TAG "HidMouseJiggler" - -struct HidMouseJiggler { - View* view; - Hid* hid; - FuriTimer* timer; -}; - -typedef struct { - bool connected; - bool running; - uint8_t counter; - HidTransport transport; -} HidMouseJigglerModel; - -static void hid_mouse_jiggler_draw_callback(Canvas* canvas, void* context) { - furi_assert(context); - HidMouseJigglerModel* model = context; - - // Header - if(model->transport == HidTransportBle) { - if(model->connected) { - canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15); - } else { - canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15); - } - } - - canvas_set_font(canvas, FontPrimary); - elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Mouse Jiggler"); - - canvas_set_font(canvas, FontPrimary); - elements_multiline_text(canvas, AlignLeft, 35, "Press Start\nto jiggle"); - canvas_set_font(canvas, FontSecondary); - - // Ok - canvas_draw_icon(canvas, 63, 25, &I_Space_65x18); - if(model->running) { - elements_slightly_rounded_box(canvas, 66, 27, 60, 13); - canvas_set_color(canvas, ColorWhite); - } - canvas_draw_icon(canvas, 74, 29, &I_Ok_btn_9x9); - if(model->running) { - elements_multiline_text_aligned(canvas, 91, 36, AlignLeft, AlignBottom, "Stop"); - } else { - elements_multiline_text_aligned(canvas, 91, 36, AlignLeft, AlignBottom, "Start"); - } - canvas_set_color(canvas, ColorBlack); - - // Back - canvas_draw_icon(canvas, 74, 49, &I_Pin_back_arrow_10x8); - elements_multiline_text_aligned(canvas, 91, 57, AlignLeft, AlignBottom, "Quit"); -} - -static void hid_mouse_jiggler_timer_callback(void* context) { - furi_assert(context); - HidMouseJiggler* hid_mouse_jiggler = context; - with_view_model( - hid_mouse_jiggler->view, - HidMouseJigglerModel * model, - { - if(model->running) { - model->counter++; - hid_hal_mouse_move( - hid_mouse_jiggler->hid, - (model->counter % 2 == 0) ? MOUSE_MOVE_SHORT : -MOUSE_MOVE_SHORT, - 0); - } - }, - false); -} - -static void hid_mouse_jiggler_enter_callback(void* context) { - furi_assert(context); - HidMouseJiggler* hid_mouse_jiggler = context; - - furi_timer_start(hid_mouse_jiggler->timer, 500); -} - -static void hid_mouse_jiggler_exit_callback(void* context) { - furi_assert(context); - HidMouseJiggler* hid_mouse_jiggler = context; - furi_timer_stop(hid_mouse_jiggler->timer); -} - -static bool hid_mouse_jiggler_input_callback(InputEvent* event, void* context) { - furi_assert(context); - HidMouseJiggler* hid_mouse_jiggler = context; - - bool consumed = false; - - if(event->type == InputTypeShort && event->key == InputKeyOk) { - with_view_model( - hid_mouse_jiggler->view, - HidMouseJigglerModel * model, - { model->running = !model->running; }, - true); - consumed = true; - } - - return consumed; -} - -HidMouseJiggler* hid_mouse_jiggler_alloc(Hid* hid) { - HidMouseJiggler* hid_mouse_jiggler = malloc(sizeof(HidMouseJiggler)); - - hid_mouse_jiggler->view = view_alloc(); - view_set_context(hid_mouse_jiggler->view, hid_mouse_jiggler); - view_allocate_model( - hid_mouse_jiggler->view, ViewModelTypeLocking, sizeof(HidMouseJigglerModel)); - view_set_draw_callback(hid_mouse_jiggler->view, hid_mouse_jiggler_draw_callback); - view_set_input_callback(hid_mouse_jiggler->view, hid_mouse_jiggler_input_callback); - view_set_enter_callback(hid_mouse_jiggler->view, hid_mouse_jiggler_enter_callback); - view_set_exit_callback(hid_mouse_jiggler->view, hid_mouse_jiggler_exit_callback); - - hid_mouse_jiggler->hid = hid; - - hid_mouse_jiggler->timer = furi_timer_alloc( - hid_mouse_jiggler_timer_callback, FuriTimerTypePeriodic, hid_mouse_jiggler); - - with_view_model( - hid_mouse_jiggler->view, - HidMouseJigglerModel * model, - { model->transport = hid->transport; }, - true); - - return hid_mouse_jiggler; -} - -void hid_mouse_jiggler_free(HidMouseJiggler* hid_mouse_jiggler) { - furi_assert(hid_mouse_jiggler); - - furi_timer_stop(hid_mouse_jiggler->timer); - furi_timer_free(hid_mouse_jiggler->timer); - - view_free(hid_mouse_jiggler->view); - - free(hid_mouse_jiggler); -} - -View* hid_mouse_jiggler_get_view(HidMouseJiggler* hid_mouse_jiggler) { - furi_assert(hid_mouse_jiggler); - return hid_mouse_jiggler->view; -} - -void hid_mouse_jiggler_set_connected_status(HidMouseJiggler* hid_mouse_jiggler, bool connected) { - furi_assert(hid_mouse_jiggler); - with_view_model( - hid_mouse_jiggler->view, - HidMouseJigglerModel * model, - { model->connected = connected; }, - true); -} diff --git a/applications/external/hid_app/views/hid_mouse_jiggler.h b/applications/external/hid_app/views/hid_mouse_jiggler.h deleted file mode 100644 index 0813b4351..000000000 --- a/applications/external/hid_app/views/hid_mouse_jiggler.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include - -#define MOUSE_MOVE_SHORT 5 -#define MOUSE_MOVE_LONG 20 - -typedef struct Hid Hid; -typedef struct HidMouseJiggler HidMouseJiggler; - -HidMouseJiggler* hid_mouse_jiggler_alloc(Hid* bt_hid); - -void hid_mouse_jiggler_free(HidMouseJiggler* hid_mouse_jiggler); - -View* hid_mouse_jiggler_get_view(HidMouseJiggler* hid_mouse_jiggler); - -void hid_mouse_jiggler_set_connected_status(HidMouseJiggler* hid_mouse_jiggler, bool connected); diff --git a/applications/external/hid_app/views/hid_tiktok.c b/applications/external/hid_app/views/hid_tiktok.c deleted file mode 100644 index e1f9f4bed..000000000 --- a/applications/external/hid_app/views/hid_tiktok.c +++ /dev/null @@ -1,241 +0,0 @@ -#include "hid_tiktok.h" -#include "../hid.h" -#include - -#include "hid_icons.h" - -#define TAG "HidTikTok" - -struct HidTikTok { - View* view; - Hid* hid; -}; - -typedef struct { - bool left_pressed; - bool up_pressed; - bool right_pressed; - bool down_pressed; - bool ok_pressed; - bool connected; - bool is_cursor_set; - HidTransport transport; -} HidTikTokModel; - -static void hid_tiktok_draw_callback(Canvas* canvas, void* context) { - furi_assert(context); - HidTikTokModel* model = context; - - // Header - if(model->transport == HidTransportBle) { - if(model->connected) { - canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15); - } else { - canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15); - } - } - - canvas_set_font(canvas, FontPrimary); - elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "TikTok"); - canvas_set_font(canvas, FontSecondary); - - // Keypad circles - canvas_draw_icon(canvas, 76, 8, &I_Circles_47x47); - - // Up - if(model->up_pressed) { - canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 93, 9, &I_Pressed_Button_13x13); - canvas_set_bitmap_mode(canvas, 0); - canvas_set_color(canvas, ColorWhite); - } - canvas_draw_icon(canvas, 96, 11, &I_Arr_up_7x9); - canvas_set_color(canvas, ColorBlack); - - // Down - if(model->down_pressed) { - canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 93, 41, &I_Pressed_Button_13x13); - canvas_set_bitmap_mode(canvas, 0); - canvas_set_color(canvas, ColorWhite); - } - canvas_draw_icon(canvas, 96, 44, &I_Arr_dwn_7x9); - canvas_set_color(canvas, ColorBlack); - - // Left - if(model->left_pressed) { - canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 77, 25, &I_Pressed_Button_13x13); - canvas_set_bitmap_mode(canvas, 0); - canvas_set_color(canvas, ColorWhite); - } - canvas_draw_icon(canvas, 81, 29, &I_Voldwn_6x6); - canvas_set_color(canvas, ColorBlack); - - // Right - if(model->right_pressed) { - canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 109, 25, &I_Pressed_Button_13x13); - canvas_set_bitmap_mode(canvas, 0); - canvas_set_color(canvas, ColorWhite); - } - canvas_draw_icon(canvas, 111, 29, &I_Volup_8x6); - canvas_set_color(canvas, ColorBlack); - - // Ok - if(model->ok_pressed) { - canvas_draw_icon(canvas, 91, 23, &I_Like_pressed_17x17); - } else { - canvas_draw_icon(canvas, 94, 27, &I_Like_def_11x9); - } - // Exit - canvas_draw_icon(canvas, 0, 54, &I_Pin_back_arrow_10x8); - canvas_set_font(canvas, FontSecondary); - elements_multiline_text_aligned(canvas, 13, 62, AlignLeft, AlignBottom, "Hold to exit"); -} - -static void hid_tiktok_reset_cursor(HidTikTok* hid_tiktok) { - // Set cursor to the phone's left up corner - // Delays to guarantee one packet per connection interval - for(size_t i = 0; i < 8; i++) { - hid_hal_mouse_move(hid_tiktok->hid, -127, -127); - furi_delay_ms(50); - } - // Move cursor from the corner - hid_hal_mouse_move(hid_tiktok->hid, 20, 120); - furi_delay_ms(50); -} - -static void - hid_tiktok_process_press(HidTikTok* hid_tiktok, HidTikTokModel* model, InputEvent* event) { - if(event->key == InputKeyUp) { - model->up_pressed = true; - } else if(event->key == InputKeyDown) { - model->down_pressed = true; - } else if(event->key == InputKeyLeft) { - model->left_pressed = true; - hid_hal_consumer_key_press(hid_tiktok->hid, HID_CONSUMER_VOLUME_DECREMENT); - } else if(event->key == InputKeyRight) { - model->right_pressed = true; - hid_hal_consumer_key_press(hid_tiktok->hid, HID_CONSUMER_VOLUME_INCREMENT); - } else if(event->key == InputKeyOk) { - model->ok_pressed = true; - } -} - -static void - hid_tiktok_process_release(HidTikTok* hid_tiktok, HidTikTokModel* model, InputEvent* event) { - if(event->key == InputKeyUp) { - model->up_pressed = false; - } else if(event->key == InputKeyDown) { - model->down_pressed = false; - } else if(event->key == InputKeyLeft) { - model->left_pressed = false; - hid_hal_consumer_key_release(hid_tiktok->hid, HID_CONSUMER_VOLUME_DECREMENT); - } else if(event->key == InputKeyRight) { - model->right_pressed = false; - hid_hal_consumer_key_release(hid_tiktok->hid, HID_CONSUMER_VOLUME_INCREMENT); - } else if(event->key == InputKeyOk) { - model->ok_pressed = false; - } -} - -static bool hid_tiktok_input_callback(InputEvent* event, void* context) { - furi_assert(context); - HidTikTok* hid_tiktok = context; - bool consumed = false; - - with_view_model( - hid_tiktok->view, - HidTikTokModel * model, - { - if(event->type == InputTypePress) { - hid_tiktok_process_press(hid_tiktok, model, event); - if(model->connected && !model->is_cursor_set) { - hid_tiktok_reset_cursor(hid_tiktok); - model->is_cursor_set = true; - } - consumed = true; - } else if(event->type == InputTypeRelease) { - hid_tiktok_process_release(hid_tiktok, model, event); - consumed = true; - } else if(event->type == InputTypeShort) { - if(event->key == InputKeyOk) { - hid_hal_mouse_press(hid_tiktok->hid, HID_MOUSE_BTN_LEFT); - furi_delay_ms(50); - hid_hal_mouse_release(hid_tiktok->hid, HID_MOUSE_BTN_LEFT); - furi_delay_ms(50); - hid_hal_mouse_press(hid_tiktok->hid, HID_MOUSE_BTN_LEFT); - furi_delay_ms(50); - hid_hal_mouse_release(hid_tiktok->hid, HID_MOUSE_BTN_LEFT); - consumed = true; - } else if(event->key == InputKeyUp) { - // Emulate up swipe - hid_hal_mouse_scroll(hid_tiktok->hid, -6); - hid_hal_mouse_scroll(hid_tiktok->hid, -12); - hid_hal_mouse_scroll(hid_tiktok->hid, -19); - hid_hal_mouse_scroll(hid_tiktok->hid, -12); - hid_hal_mouse_scroll(hid_tiktok->hid, -6); - consumed = true; - } else if(event->key == InputKeyDown) { - // Emulate down swipe - hid_hal_mouse_scroll(hid_tiktok->hid, 6); - hid_hal_mouse_scroll(hid_tiktok->hid, 12); - hid_hal_mouse_scroll(hid_tiktok->hid, 19); - hid_hal_mouse_scroll(hid_tiktok->hid, 12); - hid_hal_mouse_scroll(hid_tiktok->hid, 6); - consumed = true; - } else if(event->key == InputKeyBack) { - hid_hal_consumer_key_release_all(hid_tiktok->hid); - consumed = true; - } - } else if(event->type == InputTypeLong) { - if(event->key == InputKeyBack) { - hid_hal_consumer_key_release_all(hid_tiktok->hid); - model->is_cursor_set = false; - consumed = false; - } - } - }, - true); - - return consumed; -} - -HidTikTok* hid_tiktok_alloc(Hid* bt_hid) { - HidTikTok* hid_tiktok = malloc(sizeof(HidTikTok)); - hid_tiktok->hid = bt_hid; - hid_tiktok->view = view_alloc(); - view_set_context(hid_tiktok->view, hid_tiktok); - view_allocate_model(hid_tiktok->view, ViewModelTypeLocking, sizeof(HidTikTokModel)); - view_set_draw_callback(hid_tiktok->view, hid_tiktok_draw_callback); - view_set_input_callback(hid_tiktok->view, hid_tiktok_input_callback); - - with_view_model( - hid_tiktok->view, HidTikTokModel * model, { model->transport = bt_hid->transport; }, true); - - return hid_tiktok; -} - -void hid_tiktok_free(HidTikTok* hid_tiktok) { - furi_assert(hid_tiktok); - view_free(hid_tiktok->view); - free(hid_tiktok); -} - -View* hid_tiktok_get_view(HidTikTok* hid_tiktok) { - furi_assert(hid_tiktok); - return hid_tiktok->view; -} - -void hid_tiktok_set_connected_status(HidTikTok* hid_tiktok, bool connected) { - furi_assert(hid_tiktok); - with_view_model( - hid_tiktok->view, - HidTikTokModel * model, - { - model->connected = connected; - model->is_cursor_set = false; - }, - true); -} diff --git a/applications/external/hid_app/views/hid_tiktok.h b/applications/external/hid_app/views/hid_tiktok.h deleted file mode 100644 index b2efc3692..000000000 --- a/applications/external/hid_app/views/hid_tiktok.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -typedef struct Hid Hid; -typedef struct HidTikTok HidTikTok; - -HidTikTok* hid_tiktok_alloc(Hid* bt_hid); - -void hid_tiktok_free(HidTikTok* hid_tiktok); - -View* hid_tiktok_get_view(HidTikTok* hid_tiktok); - -void hid_tiktok_set_connected_status(HidTikTok* hid_tiktok, bool connected); diff --git a/applications/external/mfkey32/application.fam b/applications/external/mfkey32/application.fam deleted file mode 100644 index 9a9cbf581..000000000 --- a/applications/external/mfkey32/application.fam +++ /dev/null @@ -1,17 +0,0 @@ -App( - appid="mfkey32", - name="Mfkey32", - apptype=FlipperAppType.EXTERNAL, - targets=["f7"], - entry_point="mfkey32_main", - requires=[ - "gui", - "storage", - ], - stack_size=1 * 1024, - fap_icon="mfkey.png", - fap_category="Nfc", - fap_author="noproto", - fap_icon_assets="images", - fap_weburl="https://github.com/noproto/FlipperMfkey", -) diff --git a/applications/external/mfkey32/images/mfkey.png b/applications/external/mfkey32/images/mfkey.png deleted file mode 100644 index 52ab29efb..000000000 Binary files a/applications/external/mfkey32/images/mfkey.png and /dev/null differ diff --git a/applications/external/mfkey32/mfkey.png b/applications/external/mfkey32/mfkey.png deleted file mode 100644 index 52ab29efb..000000000 Binary files a/applications/external/mfkey32/mfkey.png and /dev/null differ diff --git a/applications/external/mfkey32/mfkey32.c b/applications/external/mfkey32/mfkey32.c deleted file mode 100644 index 5e790b01f..000000000 --- a/applications/external/mfkey32/mfkey32.c +++ /dev/null @@ -1,1349 +0,0 @@ -#pragma GCC optimize("O3") -#pragma GCC optimize("-funroll-all-loops") - -// TODO: Add keys to top of the user dictionary, not the bottom -// TODO: More efficient dictionary bruteforce by scanning through hardcoded very common keys and previously found dictionary keys first? -// (a cache for napi_key_already_found_for_nonce) - -#include -#include -#include "time.h" -#include -#include -#include -#include -#include "mfkey32_icons.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MF_CLASSIC_DICT_FLIPPER_PATH EXT_PATH("nfc/assets/mf_classic_dict.nfc") -#define MF_CLASSIC_DICT_USER_PATH EXT_PATH("nfc/assets/mf_classic_dict_user.nfc") -#define MF_CLASSIC_NONCE_PATH EXT_PATH("nfc/.mfkey32.log") -#define TAG "Mfkey32" -#define NFC_MF_CLASSIC_KEY_LEN (13) - -#define MIN_RAM 115632 -#define LF_POLY_ODD (0x29CE5C) -#define LF_POLY_EVEN (0x870804) -#define CONST_M1_1 (LF_POLY_EVEN << 1 | 1) -#define CONST_M2_1 (LF_POLY_ODD << 1) -#define CONST_M1_2 (LF_POLY_ODD) -#define CONST_M2_2 (LF_POLY_EVEN << 1 | 1) -#define BIT(x, n) ((x) >> (n)&1) -#define BEBIT(x, n) BIT(x, (n) ^ 24) -#define SWAPENDIAN(x) \ - ((x) = ((x) >> 8 & 0xff00ff) | ((x)&0xff00ff) << 8, (x) = (x) >> 16 | (x) << 16) -//#define SIZEOF(arr) sizeof(arr) / sizeof(*arr) - -static int eta_round_time = 56; -static int eta_total_time = 900; -// MSB_LIMIT: Chunk size (out of 256) -static int MSB_LIMIT = 16; - -struct Crypto1State { - uint32_t odd, even; -}; -struct Crypto1Params { - uint64_t key; - uint32_t nr0_enc, uid_xor_nt0, uid_xor_nt1, nr1_enc, p64b, ar1_enc; -}; -struct Msb { - int tail; - uint32_t states[768]; -}; - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} PluginEvent; - -typedef enum { - MissingNonces, - ZeroNonces, -} MfkeyError; - -typedef enum { - Ready, - Initializing, - DictionaryAttack, - MfkeyAttack, - Complete, - Error, - Help, -} MfkeyState; - -// TODO: Can we eliminate any of the members of this struct? -typedef struct { - FuriMutex* mutex; - MfkeyError err; - MfkeyState mfkey_state; - int cracked; - int unique_cracked; - int num_completed; - int total; - int dict_count; - int search; - int eta_timestamp; - int eta_total; - int eta_round; - bool is_thread_running; - bool close_thread_please; - FuriThread* mfkeythread; -} ProgramState; - -// TODO: Merge this with Crypto1Params? -typedef struct { - uint32_t uid; // serial number - uint32_t nt0; // tag challenge first - uint32_t nt1; // tag challenge second - uint32_t nr0_enc; // first encrypted reader challenge - uint32_t ar0_enc; // first encrypted reader response - uint32_t nr1_enc; // second encrypted reader challenge - uint32_t ar1_enc; // second encrypted reader response -} MfClassicNonce; - -typedef struct { - Stream* stream; - uint32_t total_nonces; - MfClassicNonce* remaining_nonce_array; - size_t remaining_nonces; -} MfClassicNonceArray; - -struct MfClassicDict { - Stream* stream; - uint32_t total_keys; -}; - -static const uint8_t table[256] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, - 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, - 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, - 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, - 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, - 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, - 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, - 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, - 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8}; -static const uint8_t lookup1[256] = { - 0, 0, 16, 16, 0, 16, 0, 0, 0, 16, 0, 0, 16, 16, 16, 16, 0, 0, 16, 16, 0, 16, 0, 0, - 0, 16, 0, 0, 16, 16, 16, 16, 0, 0, 16, 16, 0, 16, 0, 0, 0, 16, 0, 0, 16, 16, 16, 16, - 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24, 8, 8, 24, 24, 8, 24, 8, 8, - 8, 24, 8, 8, 24, 24, 24, 24, 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24, - 0, 0, 16, 16, 0, 16, 0, 0, 0, 16, 0, 0, 16, 16, 16, 16, 0, 0, 16, 16, 0, 16, 0, 0, - 0, 16, 0, 0, 16, 16, 16, 16, 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24, - 0, 0, 16, 16, 0, 16, 0, 0, 0, 16, 0, 0, 16, 16, 16, 16, 0, 0, 16, 16, 0, 16, 0, 0, - 0, 16, 0, 0, 16, 16, 16, 16, 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24, - 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24, 0, 0, 16, 16, 0, 16, 0, 0, - 0, 16, 0, 0, 16, 16, 16, 16, 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24, - 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24}; -static const uint8_t lookup2[256] = { - 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, - 4, 4, 4, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6, 2, 2, 6, 6, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6, - 2, 2, 6, 6, 6, 6, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 2, 2, 6, 6, 2, 6, 2, - 2, 2, 6, 2, 2, 6, 6, 6, 6, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 0, 0, 4, 4, - 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 2, - 2, 6, 6, 2, 6, 2, 2, 2, 6, 2, 2, 6, 6, 6, 6, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, - 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6, 2, - 2, 6, 6, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6, 2, 2, 6, 6, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, - 2, 6, 2, 2, 6, 6, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6, 2, 2, 6, 6, 6, 6}; - -uint32_t prng_successor(uint32_t x, uint32_t n) { - SWAPENDIAN(x); - while(n--) x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31; - return SWAPENDIAN(x); -} - -static inline int filter(uint32_t const x) { - uint32_t f; - f = lookup1[x & 0xff] | lookup2[(x >> 8) & 0xff]; - f |= 0x0d938 >> (x >> 16 & 0xf) & 1; - return BIT(0xEC57E80A, f); -} - -static inline uint8_t evenparity32(uint32_t x) { - if((table[x & 0xff] + table[(x >> 8) & 0xff] + table[(x >> 16) & 0xff] + table[x >> 24]) % 2 == - 0) { - return 0; - } else { - return 1; - } - //return ((table[x & 0xff] + table[(x >> 8) & 0xff] + table[(x >> 16) & 0xff] + table[x >> 24]) % 2) & 0xFF; -} - -static inline void update_contribution(unsigned int data[], int item, int mask1, int mask2) { - int p = data[item] >> 25; - p = p << 1 | evenparity32(data[item] & mask1); - p = p << 1 | evenparity32(data[item] & mask2); - data[item] = p << 24 | (data[item] & 0xffffff); -} - -void crypto1_get_lfsr(struct Crypto1State* state, uint64_t* lfsr) { - int i; - for(*lfsr = 0, i = 23; i >= 0; --i) { - *lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3); - *lfsr = *lfsr << 1 | BIT(state->even, i ^ 3); - } -} - -static inline uint32_t crypt_word(struct Crypto1State* s) { - // "in" and "x" are always 0 (last iteration) - uint32_t res_ret = 0; - uint32_t feedin, t; - for(int i = 0; i <= 31; i++) { - res_ret |= (filter(s->odd) << (24 ^ i)); //-V629 - feedin = LF_POLY_EVEN & s->even; - feedin ^= LF_POLY_ODD & s->odd; - s->even = s->even << 1 | (evenparity32(feedin)); - t = s->odd, s->odd = s->even, s->even = t; - } - return res_ret; -} - -static inline void crypt_word_noret(struct Crypto1State* s, uint32_t in, int x) { - uint8_t ret; - uint32_t feedin, t, next_in; - for(int i = 0; i <= 31; i++) { - next_in = BEBIT(in, i); - ret = filter(s->odd); - feedin = ret & (!!x); - feedin ^= LF_POLY_EVEN & s->even; - feedin ^= LF_POLY_ODD & s->odd; - feedin ^= !!next_in; - s->even = s->even << 1 | (evenparity32(feedin)); - t = s->odd, s->odd = s->even, s->even = t; - } - return; -} - -static inline void rollback_word_noret(struct Crypto1State* s, uint32_t in, int x) { - uint8_t ret; - uint32_t feedin, t, next_in; - for(int i = 31; i >= 0; i--) { - next_in = BEBIT(in, i); - s->odd &= 0xffffff; - t = s->odd, s->odd = s->even, s->even = t; - ret = filter(s->odd); - feedin = ret & (!!x); - feedin ^= s->even & 1; - feedin ^= LF_POLY_EVEN & (s->even >>= 1); - feedin ^= LF_POLY_ODD & s->odd; - feedin ^= !!next_in; - s->even |= (evenparity32(feedin)) << 23; - } - return; -} - -int key_already_found_for_nonce( - uint64_t* keyarray, - int keyarray_size, - uint32_t uid_xor_nt1, - uint32_t nr1_enc, - uint32_t p64b, - uint32_t ar1_enc) { - for(int k = 0; k < keyarray_size; k++) { - struct Crypto1State temp = {0, 0}; - - for(int i = 0; i < 24; i++) { - (&temp)->odd |= (BIT(keyarray[k], 2 * i + 1) << (i ^ 3)); - (&temp)->even |= (BIT(keyarray[k], 2 * i) << (i ^ 3)); - } - - crypt_word_noret(&temp, uid_xor_nt1, 0); - crypt_word_noret(&temp, nr1_enc, 1); - - if(ar1_enc == (crypt_word(&temp) ^ p64b)) { - return 1; - } - } - return 0; -} - -int check_state(struct Crypto1State* t, struct Crypto1Params* p) { - if(!(t->odd | t->even)) return 0; - rollback_word_noret(t, 0, 0); - rollback_word_noret(t, p->nr0_enc, 1); - rollback_word_noret(t, p->uid_xor_nt0, 0); - struct Crypto1State temp = {t->odd, t->even}; - crypt_word_noret(t, p->uid_xor_nt1, 0); - crypt_word_noret(t, p->nr1_enc, 1); - if(p->ar1_enc == (crypt_word(t) ^ p->p64b)) { - crypto1_get_lfsr(&temp, &(p->key)); - return 1; - } - return 0; -} - -static inline int state_loop(unsigned int* states_buffer, int xks, int m1, int m2) { - int states_tail = 0; - int round = 0, s = 0, xks_bit = 0; - - for(round = 1; round <= 12; round++) { - xks_bit = BIT(xks, round); - - for(s = 0; s <= states_tail; s++) { - states_buffer[s] <<= 1; - - if((filter(states_buffer[s]) ^ filter(states_buffer[s] | 1)) != 0) { - states_buffer[s] |= filter(states_buffer[s]) ^ xks_bit; - if(round > 4) { - update_contribution(states_buffer, s, m1, m2); - } - } else if(filter(states_buffer[s]) == xks_bit) { - // TODO: Refactor - if(round > 4) { - states_buffer[++states_tail] = states_buffer[s + 1]; - states_buffer[s + 1] = states_buffer[s] | 1; - update_contribution(states_buffer, s, m1, m2); - s++; - update_contribution(states_buffer, s, m1, m2); - } else { - states_buffer[++states_tail] = states_buffer[++s]; - states_buffer[s] = states_buffer[s - 1] | 1; - } - } else { - states_buffer[s--] = states_buffer[states_tail--]; - } - } - } - - return states_tail; -} - -int binsearch(unsigned int data[], int start, int stop) { - int mid, val = data[stop] & 0xff000000; - while(start != stop) { - mid = (stop - start) >> 1; - if((data[start + mid] ^ 0x80000000) > (val ^ 0x80000000)) - stop = start + mid; - else - start += mid + 1; - } - return start; -} -void quicksort(unsigned int array[], int low, int high) { - //if (SIZEOF(array) == 0) - // return; - if(low >= high) return; - int middle = low + (high - low) / 2; - unsigned int pivot = array[middle]; - int i = low, j = high; - while(i <= j) { - while(array[i] < pivot) { - i++; - } - while(array[j] > pivot) { - j--; - } - if(i <= j) { // swap - int temp = array[i]; - array[i] = array[j]; - array[j] = temp; - i++; - j--; - } - } - if(low < j) { - quicksort(array, low, j); - } - if(high > i) { - quicksort(array, i, high); - } -} -int extend_table(unsigned int data[], int tbl, int end, int bit, int m1, int m2) { - for(data[tbl] <<= 1; tbl <= end; data[++tbl] <<= 1) { - if((filter(data[tbl]) ^ filter(data[tbl] | 1)) != 0) { - data[tbl] |= filter(data[tbl]) ^ bit; - update_contribution(data, tbl, m1, m2); - } else if(filter(data[tbl]) == bit) { - data[++end] = data[tbl + 1]; - data[tbl + 1] = data[tbl] | 1; - update_contribution(data, tbl, m1, m2); - tbl++; - update_contribution(data, tbl, m1, m2); - } else { - data[tbl--] = data[end--]; - } - } - return end; -} - -int old_recover( - unsigned int odd[], - int o_head, - int o_tail, - int oks, - unsigned int even[], - int e_head, - int e_tail, - int eks, - int rem, - int s, - struct Crypto1Params* p, - int first_run) { - int o, e, i; - if(rem == -1) { - for(e = e_head; e <= e_tail; ++e) { - even[e] = (even[e] << 1) ^ evenparity32(even[e] & LF_POLY_EVEN); - for(o = o_head; o <= o_tail; ++o, ++s) { - struct Crypto1State temp = {0, 0}; - temp.even = odd[o]; - temp.odd = even[e] ^ evenparity32(odd[o] & LF_POLY_ODD); - if(check_state(&temp, p)) { - return -1; - } - } - } - return s; - } - if(first_run == 0) { - for(i = 0; (i < 4) && (rem-- != 0); i++) { - oks >>= 1; - eks >>= 1; - o_tail = extend_table( - odd, o_head, o_tail, oks & 1, LF_POLY_EVEN << 1 | 1, LF_POLY_ODD << 1); - if(o_head > o_tail) return s; - e_tail = - extend_table(even, e_head, e_tail, eks & 1, LF_POLY_ODD, LF_POLY_EVEN << 1 | 1); - if(e_head > e_tail) return s; - } - } - first_run = 0; - quicksort(odd, o_head, o_tail); - quicksort(even, e_head, e_tail); - while(o_tail >= o_head && e_tail >= e_head) { - if(((odd[o_tail] ^ even[e_tail]) >> 24) == 0) { - o_tail = binsearch(odd, o_head, o = o_tail); - e_tail = binsearch(even, e_head, e = e_tail); - s = old_recover(odd, o_tail--, o, oks, even, e_tail--, e, eks, rem, s, p, first_run); - if(s == -1) { - break; - } - } else if((odd[o_tail] ^ 0x80000000) > (even[e_tail] ^ 0x80000000)) { - o_tail = binsearch(odd, o_head, o_tail) - 1; - } else { - e_tail = binsearch(even, e_head, e_tail) - 1; - } - } - return s; -} - -static inline int sync_state(ProgramState* program_state) { - int ts = furi_hal_rtc_get_timestamp(); - program_state->eta_round = program_state->eta_round - (ts - program_state->eta_timestamp); - program_state->eta_total = program_state->eta_total - (ts - program_state->eta_timestamp); - program_state->eta_timestamp = ts; - if(program_state->close_thread_please) { - return 1; - } - return 0; -} - -int calculate_msb_tables( - int oks, - int eks, - int msb_round, - struct Crypto1Params* p, - unsigned int* states_buffer, - struct Msb* odd_msbs, - struct Msb* even_msbs, - unsigned int* temp_states_odd, - unsigned int* temp_states_even, - ProgramState* program_state) { - //FURI_LOG_I(TAG, "MSB GO %i", msb_iter); // DEBUG - unsigned int msb_head = (MSB_LIMIT * msb_round); // msb_iter ranges from 0 to (256/MSB_LIMIT)-1 - unsigned int msb_tail = (MSB_LIMIT * (msb_round + 1)); - int states_tail = 0, tail = 0; - int i = 0, j = 0, semi_state = 0, found = 0; - unsigned int msb = 0; - // TODO: Why is this necessary? - memset(odd_msbs, 0, MSB_LIMIT * sizeof(struct Msb)); - memset(even_msbs, 0, MSB_LIMIT * sizeof(struct Msb)); - - for(semi_state = 1 << 20; semi_state >= 0; semi_state--) { - if(semi_state % 32768 == 0) { - if(sync_state(program_state) == 1) { - return 0; - } - } - - if(filter(semi_state) == (oks & 1)) { //-V547 - states_buffer[0] = semi_state; - states_tail = state_loop(states_buffer, oks, CONST_M1_1, CONST_M2_1); - - for(i = states_tail; i >= 0; i--) { - msb = states_buffer[i] >> 24; - if((msb >= msb_head) && (msb < msb_tail)) { - found = 0; - for(j = 0; j < odd_msbs[msb - msb_head].tail - 1; j++) { - if(odd_msbs[msb - msb_head].states[j] == states_buffer[i]) { - found = 1; - break; - } - } - - if(!found) { - tail = odd_msbs[msb - msb_head].tail++; - odd_msbs[msb - msb_head].states[tail] = states_buffer[i]; - } - } - } - } - - if(filter(semi_state) == (eks & 1)) { //-V547 - states_buffer[0] = semi_state; - states_tail = state_loop(states_buffer, eks, CONST_M1_2, CONST_M2_2); - - for(i = 0; i <= states_tail; i++) { - msb = states_buffer[i] >> 24; - if((msb >= msb_head) && (msb < msb_tail)) { - found = 0; - - for(j = 0; j < even_msbs[msb - msb_head].tail; j++) { - if(even_msbs[msb - msb_head].states[j] == states_buffer[i]) { - found = 1; - break; - } - } - - if(!found) { - tail = even_msbs[msb - msb_head].tail++; - even_msbs[msb - msb_head].states[tail] = states_buffer[i]; - } - } - } - } - } - - oks >>= 12; - eks >>= 12; - - for(i = 0; i < MSB_LIMIT; i++) { - if(sync_state(program_state) == 1) { - return 0; - } - // TODO: Why is this necessary? - memset(temp_states_even, 0, sizeof(unsigned int) * (1280)); - memset(temp_states_odd, 0, sizeof(unsigned int) * (1280)); - memcpy(temp_states_odd, odd_msbs[i].states, odd_msbs[i].tail * sizeof(unsigned int)); - memcpy(temp_states_even, even_msbs[i].states, even_msbs[i].tail * sizeof(unsigned int)); - int res = old_recover( - temp_states_odd, - 0, - odd_msbs[i].tail, - oks, - temp_states_even, - 0, - even_msbs[i].tail, - eks, - 3, - 0, - p, - 1); - if(res == -1) { - return 1; - } - //odd_msbs[i].tail = 0; - //even_msbs[i].tail = 0; - } - - return 0; -} - -bool recover(struct Crypto1Params* p, int ks2, ProgramState* program_state) { - bool found = false; - unsigned int* states_buffer = malloc(sizeof(unsigned int) * (2 << 9)); - struct Msb* odd_msbs = (struct Msb*)malloc(MSB_LIMIT * sizeof(struct Msb)); - struct Msb* even_msbs = (struct Msb*)malloc(MSB_LIMIT * sizeof(struct Msb)); - unsigned int* temp_states_odd = malloc(sizeof(unsigned int) * (1280)); - unsigned int* temp_states_even = malloc(sizeof(unsigned int) * (1280)); - int oks = 0, eks = 0; - int i = 0, msb = 0; - for(i = 31; i >= 0; i -= 2) { - oks = oks << 1 | BEBIT(ks2, i); - } - for(i = 30; i >= 0; i -= 2) { - eks = eks << 1 | BEBIT(ks2, i); - } - int bench_start = furi_hal_rtc_get_timestamp(); - program_state->eta_total = eta_total_time; - program_state->eta_timestamp = bench_start; - for(msb = 0; msb <= ((256 / MSB_LIMIT) - 1); msb++) { - program_state->search = msb; - program_state->eta_round = eta_round_time; - program_state->eta_total = eta_total_time - (eta_round_time * msb); - if(calculate_msb_tables( - oks, - eks, - msb, - p, - states_buffer, - odd_msbs, - even_msbs, - temp_states_odd, - temp_states_even, - program_state)) { - int bench_stop = furi_hal_rtc_get_timestamp(); - FURI_LOG_I(TAG, "Cracked in %i seconds", bench_stop - bench_start); - found = true; - break; - } - if(program_state->close_thread_please) { - break; - } - } - free(states_buffer); - free(odd_msbs); - free(even_msbs); - free(temp_states_odd); - free(temp_states_even); - return found; -} - -bool napi_mf_classic_dict_check_presence(MfClassicDictType dict_type) { - Storage* storage = furi_record_open(RECORD_STORAGE); - - bool dict_present = false; - if(dict_type == MfClassicDictTypeSystem) { - dict_present = storage_common_stat(storage, MF_CLASSIC_DICT_FLIPPER_PATH, NULL) == FSE_OK; - } else if(dict_type == MfClassicDictTypeUser) { - dict_present = storage_common_stat(storage, MF_CLASSIC_DICT_USER_PATH, NULL) == FSE_OK; - } - - furi_record_close(RECORD_STORAGE); - - return dict_present; -} - -MfClassicDict* napi_mf_classic_dict_alloc(MfClassicDictType dict_type) { - MfClassicDict* dict = malloc(sizeof(MfClassicDict)); - Storage* storage = furi_record_open(RECORD_STORAGE); - dict->stream = buffered_file_stream_alloc(storage); - furi_record_close(RECORD_STORAGE); - - bool dict_loaded = false; - do { - if(dict_type == MfClassicDictTypeSystem) { - if(!buffered_file_stream_open( - dict->stream, - MF_CLASSIC_DICT_FLIPPER_PATH, - FSAM_READ_WRITE, - FSOM_OPEN_EXISTING)) { - buffered_file_stream_close(dict->stream); - break; - } - } else if(dict_type == MfClassicDictTypeUser) { - if(!buffered_file_stream_open( - dict->stream, MF_CLASSIC_DICT_USER_PATH, FSAM_READ_WRITE, FSOM_OPEN_ALWAYS)) { - buffered_file_stream_close(dict->stream); - break; - } - } - - // Check for newline ending - if(!stream_eof(dict->stream)) { - if(!stream_seek(dict->stream, -1, StreamOffsetFromEnd)) break; - uint8_t last_char = 0; - if(stream_read(dict->stream, &last_char, 1) != 1) break; - if(last_char != '\n') { - FURI_LOG_D(TAG, "Adding new line ending"); - if(stream_write_char(dict->stream, '\n') != 1) break; - } - if(!stream_rewind(dict->stream)) break; - } - - // Read total amount of keys - FuriString* next_line; - next_line = furi_string_alloc(); - while(true) { - if(!stream_read_line(dict->stream, next_line)) { - FURI_LOG_T(TAG, "No keys left in dict"); - break; - } - FURI_LOG_T( - TAG, - "Read line: %s, len: %zu", - furi_string_get_cstr(next_line), - furi_string_size(next_line)); - if(furi_string_get_char(next_line, 0) == '#') continue; - if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; - dict->total_keys++; - } - furi_string_free(next_line); - stream_rewind(dict->stream); - - dict_loaded = true; - FURI_LOG_I(TAG, "Loaded dictionary with %lu keys", dict->total_keys); - } while(false); - - if(!dict_loaded) { - buffered_file_stream_close(dict->stream); - free(dict); - dict = NULL; - } - - return dict; -} - -bool napi_mf_classic_dict_add_key_str(MfClassicDict* dict, FuriString* key) { - furi_assert(dict); - furi_assert(dict->stream); - FURI_LOG_I(TAG, "Saving key: %s", furi_string_get_cstr(key)); - - furi_string_cat_printf(key, "\n"); - - bool key_added = false; - do { - if(!stream_seek(dict->stream, 0, StreamOffsetFromEnd)) break; - if(!stream_insert_string(dict->stream, key)) break; - dict->total_keys++; - key_added = true; - } while(false); - - furi_string_left(key, 12); - return key_added; -} - -void napi_mf_classic_dict_free(MfClassicDict* dict) { - furi_assert(dict); - furi_assert(dict->stream); - - buffered_file_stream_close(dict->stream); - stream_free(dict->stream); - free(dict); -} - -static void napi_mf_classic_dict_int_to_str(uint8_t* key_int, FuriString* key_str) { - furi_string_reset(key_str); - for(size_t i = 0; i < 6; i++) { - furi_string_cat_printf(key_str, "%02X", key_int[i]); - } -} - -static void napi_mf_classic_dict_str_to_int(FuriString* key_str, uint64_t* key_int) { - uint8_t key_byte_tmp; - - *key_int = 0ULL; - for(uint8_t i = 0; i < 12; i += 2) { - args_char_to_hex( - furi_string_get_char(key_str, i), furi_string_get_char(key_str, i + 1), &key_byte_tmp); - *key_int |= (uint64_t)key_byte_tmp << (8 * (5 - i / 2)); - } -} - -uint32_t napi_mf_classic_dict_get_total_keys(MfClassicDict* dict) { - furi_assert(dict); - - return dict->total_keys; -} - -bool napi_mf_classic_dict_rewind(MfClassicDict* dict) { - furi_assert(dict); - furi_assert(dict->stream); - - return stream_rewind(dict->stream); -} - -bool napi_mf_classic_dict_get_next_key_str(MfClassicDict* dict, FuriString* key) { - furi_assert(dict); - furi_assert(dict->stream); - - bool key_read = false; - furi_string_reset(key); - while(!key_read) { - if(!stream_read_line(dict->stream, key)) break; - if(furi_string_get_char(key, 0) == '#') continue; - if(furi_string_size(key) != NFC_MF_CLASSIC_KEY_LEN) continue; - furi_string_left(key, 12); - key_read = true; - } - - return key_read; -} - -bool napi_mf_classic_dict_get_next_key(MfClassicDict* dict, uint64_t* key) { - furi_assert(dict); - furi_assert(dict->stream); - - FuriString* temp_key; - temp_key = furi_string_alloc(); - bool key_read = napi_mf_classic_dict_get_next_key_str(dict, temp_key); - if(key_read) { - napi_mf_classic_dict_str_to_int(temp_key, key); - } - furi_string_free(temp_key); - return key_read; -} - -bool napi_mf_classic_dict_is_key_present_str(MfClassicDict* dict, FuriString* key) { - furi_assert(dict); - furi_assert(dict->stream); - - FuriString* next_line; - next_line = furi_string_alloc(); - - bool key_found = false; - stream_rewind(dict->stream); - while(!key_found) { //-V654 - if(!stream_read_line(dict->stream, next_line)) break; - if(furi_string_get_char(next_line, 0) == '#') continue; - if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; - furi_string_left(next_line, 12); - if(!furi_string_equal(key, next_line)) continue; - key_found = true; - } - - furi_string_free(next_line); - return key_found; -} - -bool napi_mf_classic_dict_is_key_present(MfClassicDict* dict, uint8_t* key) { - FuriString* temp_key; - - temp_key = furi_string_alloc(); - napi_mf_classic_dict_int_to_str(key, temp_key); - bool key_found = napi_mf_classic_dict_is_key_present_str(dict, temp_key); - furi_string_free(temp_key); - return key_found; -} - -bool napi_key_already_found_for_nonce( - MfClassicDict* dict, - uint32_t uid_xor_nt1, - uint32_t nr1_enc, - uint32_t p64b, - uint32_t ar1_enc) { - bool found = false; - uint64_t k = 0; - napi_mf_classic_dict_rewind(dict); - while(napi_mf_classic_dict_get_next_key(dict, &k)) { - struct Crypto1State temp = {0, 0}; - int i; - for(i = 0; i < 24; i++) { - (&temp)->odd |= (BIT(k, 2 * i + 1) << (i ^ 3)); - (&temp)->even |= (BIT(k, 2 * i) << (i ^ 3)); - } - crypt_word_noret(&temp, uid_xor_nt1, 0); - crypt_word_noret(&temp, nr1_enc, 1); - if(ar1_enc == (crypt_word(&temp) ^ p64b)) { - found = true; - break; - } - } - return found; -} - -bool napi_mf_classic_nonces_check_presence() { - Storage* storage = furi_record_open(RECORD_STORAGE); - - bool nonces_present = storage_common_stat(storage, MF_CLASSIC_NONCE_PATH, NULL) == FSE_OK; - - furi_record_close(RECORD_STORAGE); - - return nonces_present; -} - -MfClassicNonceArray* napi_mf_classic_nonce_array_alloc( - MfClassicDict* system_dict, - bool system_dict_exists, - MfClassicDict* user_dict, - ProgramState* program_state) { - MfClassicNonceArray* nonce_array = malloc(sizeof(MfClassicNonceArray)); - MfClassicNonce* remaining_nonce_array_init = malloc(sizeof(MfClassicNonce) * 1); - nonce_array->remaining_nonce_array = remaining_nonce_array_init; - Storage* storage = furi_record_open(RECORD_STORAGE); - nonce_array->stream = buffered_file_stream_alloc(storage); - furi_record_close(RECORD_STORAGE); - - bool array_loaded = false; - do { - // https://github.com/flipperdevices/flipperzero-firmware/blob/5134f44c09d39344a8747655c0d59864bb574b96/applications/services/storage/filesystem_api_defines.h#L8-L22 - if(!buffered_file_stream_open( - nonce_array->stream, MF_CLASSIC_NONCE_PATH, FSAM_READ_WRITE, FSOM_OPEN_EXISTING)) { - buffered_file_stream_close(nonce_array->stream); - break; - } - - // Check for newline ending - if(!stream_eof(nonce_array->stream)) { - if(!stream_seek(nonce_array->stream, -1, StreamOffsetFromEnd)) break; - uint8_t last_char = 0; - if(stream_read(nonce_array->stream, &last_char, 1) != 1) break; - if(last_char != '\n') { - FURI_LOG_D(TAG, "Adding new line ending"); - if(stream_write_char(nonce_array->stream, '\n') != 1) break; - } - if(!stream_rewind(nonce_array->stream)) break; - } - - // Read total amount of nonces - FuriString* next_line; - next_line = furi_string_alloc(); - while(!(program_state->close_thread_please)) { - if(!stream_read_line(nonce_array->stream, next_line)) { - FURI_LOG_T(TAG, "No nonces left"); - break; - } - FURI_LOG_T( - TAG, - "Read line: %s, len: %zu", - furi_string_get_cstr(next_line), - furi_string_size(next_line)); - if(!furi_string_start_with_str(next_line, "Sec")) continue; - const char* next_line_cstr = furi_string_get_cstr(next_line); - MfClassicNonce res = {0}; - int i = 0; - char* endptr; - for(i = 0; i <= 17; i++) { - if(i != 0) { - next_line_cstr = strchr(next_line_cstr, ' '); - if(next_line_cstr) { - next_line_cstr++; - } else { - break; - } - } - unsigned long value = strtoul(next_line_cstr, &endptr, 16); - switch(i) { - case 5: - res.uid = value; - break; - case 7: - res.nt0 = value; - break; - case 9: - res.nr0_enc = value; - break; - case 11: - res.ar0_enc = value; - break; - case 13: - res.nt1 = value; - break; - case 15: - res.nr1_enc = value; - break; - case 17: - res.ar1_enc = value; - break; - default: - break; // Do nothing - } - next_line_cstr = endptr; - } - (program_state->total)++; - uint32_t p64b = prng_successor(res.nt1, 64); - if((system_dict_exists && - napi_key_already_found_for_nonce( - system_dict, res.uid ^ res.nt1, res.nr1_enc, p64b, res.ar1_enc)) || - (napi_key_already_found_for_nonce( - user_dict, res.uid ^ res.nt1, res.nr1_enc, p64b, res.ar1_enc))) { - (program_state->cracked)++; - (program_state->num_completed)++; - continue; - } - FURI_LOG_I(TAG, "No key found for %8lx %8lx", res.uid, res.ar1_enc); - // TODO: Refactor - nonce_array->remaining_nonce_array = realloc( //-V701 - nonce_array->remaining_nonce_array, - sizeof(MfClassicNonce) * ((nonce_array->remaining_nonces) + 1)); - nonce_array->remaining_nonces++; - nonce_array->remaining_nonce_array[(nonce_array->remaining_nonces) - 1] = res; - nonce_array->total_nonces++; - } - furi_string_free(next_line); - buffered_file_stream_close(nonce_array->stream); - - array_loaded = true; - FURI_LOG_I(TAG, "Loaded %lu nonces", nonce_array->total_nonces); - } while(false); - - if(!array_loaded) { - free(nonce_array); - nonce_array = NULL; - } - - return nonce_array; -} - -void napi_mf_classic_nonce_array_free(MfClassicNonceArray* nonce_array) { - furi_assert(nonce_array); - furi_assert(nonce_array->stream); - - buffered_file_stream_close(nonce_array->stream); - stream_free(nonce_array->stream); - free(nonce_array); -} - -static void finished_beep() { - // Beep to indicate completion - NotificationApp* notification = furi_record_open("notification"); - notification_message(notification, &sequence_audiovisual_alert); - notification_message(notification, &sequence_display_backlight_on); - furi_record_close("notification"); -} - -void mfkey32(ProgramState* program_state) { - uint64_t found_key; // recovered key - size_t keyarray_size = 0; - uint64_t* keyarray = malloc(sizeof(uint64_t) * 1); - uint32_t i = 0, j = 0; - // Check for nonces - if(!napi_mf_classic_nonces_check_presence()) { - program_state->err = MissingNonces; - program_state->mfkey_state = Error; - free(keyarray); - return; - } - // Read dictionaries (optional) - MfClassicDict* system_dict = {0}; - bool system_dict_exists = napi_mf_classic_dict_check_presence(MfClassicDictTypeSystem); - MfClassicDict* user_dict = {0}; - bool user_dict_exists = napi_mf_classic_dict_check_presence(MfClassicDictTypeUser); - uint32_t total_dict_keys = 0; - if(system_dict_exists) { - system_dict = napi_mf_classic_dict_alloc(MfClassicDictTypeSystem); - total_dict_keys += napi_mf_classic_dict_get_total_keys(system_dict); - } - user_dict = napi_mf_classic_dict_alloc(MfClassicDictTypeUser); - if(user_dict_exists) { - total_dict_keys += napi_mf_classic_dict_get_total_keys(user_dict); - } - user_dict_exists = true; - program_state->dict_count = total_dict_keys; - program_state->mfkey_state = DictionaryAttack; - // Read nonces - MfClassicNonceArray* nonce_arr; - nonce_arr = napi_mf_classic_nonce_array_alloc( - system_dict, system_dict_exists, user_dict, program_state); - if(system_dict_exists) { - napi_mf_classic_dict_free(system_dict); - } - if(nonce_arr->total_nonces == 0) { - // Nothing to crack - program_state->err = ZeroNonces; - program_state->mfkey_state = Error; - napi_mf_classic_nonce_array_free(nonce_arr); - napi_mf_classic_dict_free(user_dict); - free(keyarray); - return; - } - if(memmgr_get_free_heap() < MIN_RAM) { - // System has less than the guaranteed amount of RAM (140 KB) - adjust some parameters to run anyway at half speed - eta_round_time *= 2; - eta_total_time *= 2; - MSB_LIMIT /= 2; - } - program_state->mfkey_state = MfkeyAttack; - // TODO: Work backwards on this array and free memory - for(i = 0; i < nonce_arr->total_nonces; i++) { - MfClassicNonce next_nonce = nonce_arr->remaining_nonce_array[i]; - uint32_t p64 = prng_successor(next_nonce.nt0, 64); - uint32_t p64b = prng_successor(next_nonce.nt1, 64); - if(key_already_found_for_nonce( - keyarray, - keyarray_size, - next_nonce.uid ^ next_nonce.nt1, - next_nonce.nr1_enc, - p64b, - next_nonce.ar1_enc)) { - nonce_arr->remaining_nonces--; - (program_state->cracked)++; - (program_state->num_completed)++; - continue; - } - FURI_LOG_I(TAG, "Cracking %8lx %8lx", next_nonce.uid, next_nonce.ar1_enc); - struct Crypto1Params p = { - 0, - next_nonce.nr0_enc, - next_nonce.uid ^ next_nonce.nt0, - next_nonce.uid ^ next_nonce.nt1, - next_nonce.nr1_enc, - p64b, - next_nonce.ar1_enc}; - if(!recover(&p, next_nonce.ar0_enc ^ p64, program_state)) { - if(program_state->close_thread_please) { - break; - } - // No key found in recover() - (program_state->num_completed)++; - continue; - } - (program_state->cracked)++; - (program_state->num_completed)++; - found_key = p.key; - bool already_found = false; - for(j = 0; j < keyarray_size; j++) { - if(keyarray[j] == found_key) { - already_found = true; - break; - } - } - if(already_found == false) { - // New key - keyarray = realloc(keyarray, sizeof(uint64_t) * (keyarray_size + 1)); //-V701 - keyarray_size += 1; - keyarray[keyarray_size - 1] = found_key; - (program_state->unique_cracked)++; - } - } - // TODO: Update display to show all keys were found - // TODO: Prepend found key(s) to user dictionary file - //FURI_LOG_I(TAG, "Unique keys found:"); - for(i = 0; i < keyarray_size; i++) { - //FURI_LOG_I(TAG, "%012" PRIx64, keyarray[i]); - FuriString* temp_key = furi_string_alloc(); - furi_string_cat_printf(temp_key, "%012" PRIX64, keyarray[i]); - napi_mf_classic_dict_add_key_str(user_dict, temp_key); - furi_string_free(temp_key); - } - if(keyarray_size > 0) { - // TODO: Should we use DolphinDeedNfcMfcAdd? - dolphin_deed(DolphinDeedNfcMfcAdd); - } - napi_mf_classic_nonce_array_free(nonce_arr); - napi_mf_classic_dict_free(user_dict); - free(keyarray); - //FURI_LOG_I(TAG, "mfkey32 function completed normally"); // DEBUG - program_state->mfkey_state = Complete; - // No need to alert the user if they asked it to stop - if(!(program_state->close_thread_please)) { - finished_beep(); - } - return; -} - -// Screen is 128x64 px -static void render_callback(Canvas* const canvas, void* ctx) { - furi_assert(ctx); - ProgramState* program_state = ctx; - furi_mutex_acquire(program_state->mutex, FuriWaitForever); - char draw_str[44] = {}; - canvas_clear(canvas); - canvas_draw_frame(canvas, 0, 0, 128, 64); - canvas_draw_frame(canvas, 0, 15, 128, 64); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 5, 4, AlignLeft, AlignTop, "Mfkey32"); - canvas_draw_icon(canvas, 114, 4, &I_mfkey); - if(program_state->is_thread_running && program_state->mfkey_state == MfkeyAttack) { - float eta_round = (float)1 - ((float)program_state->eta_round / (float)eta_round_time); - float eta_total = (float)1 - ((float)program_state->eta_total / (float)eta_total_time); - float progress = (float)program_state->num_completed / (float)program_state->total; - if(eta_round < 0) { - // Round ETA miscalculated - eta_round = 1; - program_state->eta_round = 0; - } - if(eta_total < 0) { - // Total ETA miscalculated - eta_total = 1; - program_state->eta_total = 0; - } - canvas_set_font(canvas, FontSecondary); - snprintf( - draw_str, - sizeof(draw_str), - "Cracking: %d/%d - in prog.", - program_state->num_completed, - program_state->total); - elements_progress_bar_with_text(canvas, 5, 18, 118, progress, draw_str); - snprintf( - draw_str, - sizeof(draw_str), - "Round: %d/%d - ETA %02d Sec", - (program_state->search) + 1, // Zero indexed - 256 / MSB_LIMIT, - program_state->eta_round); - elements_progress_bar_with_text(canvas, 5, 31, 118, eta_round, draw_str); - snprintf(draw_str, sizeof(draw_str), "Total ETA %03d Sec", program_state->eta_total); - elements_progress_bar_with_text(canvas, 5, 44, 118, eta_total, draw_str); - } else if(program_state->is_thread_running && program_state->mfkey_state == DictionaryAttack) { - canvas_set_font(canvas, FontSecondary); - snprintf( - draw_str, sizeof(draw_str), "Dict solves: %d (in progress)", program_state->cracked); - canvas_draw_str_aligned(canvas, 10, 18, AlignLeft, AlignTop, draw_str); - snprintf(draw_str, sizeof(draw_str), "Keys in dict: %d", program_state->dict_count); - canvas_draw_str_aligned(canvas, 26, 28, AlignLeft, AlignTop, draw_str); - } else if(program_state->mfkey_state == Complete) { - // TODO: Scrollable list view to see cracked keys if user presses down - elements_progress_bar_with_text(canvas, 5, 18, 118, 1, draw_str); - canvas_set_font(canvas, FontSecondary); - snprintf(draw_str, sizeof(draw_str), "Complete"); - canvas_draw_str_aligned(canvas, 40, 31, AlignLeft, AlignTop, draw_str); - snprintf( - draw_str, - sizeof(draw_str), - "Keys added to user dict: %d", - program_state->unique_cracked); - canvas_draw_str_aligned(canvas, 10, 41, AlignLeft, AlignTop, draw_str); - } else if(program_state->mfkey_state == Ready) { - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 50, 30, AlignLeft, AlignTop, "Ready"); - elements_button_center(canvas, "Start"); - elements_button_right(canvas, "Help"); - } else if(program_state->mfkey_state == Help) { - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 7, 20, AlignLeft, AlignTop, "Collect nonces using"); - canvas_draw_str_aligned(canvas, 7, 30, AlignLeft, AlignTop, "Detect Reader."); - canvas_draw_str_aligned(canvas, 7, 40, AlignLeft, AlignTop, "Developers: noproto, AG"); - canvas_draw_str_aligned(canvas, 7, 50, AlignLeft, AlignTop, "Thanks: bettse"); - } else if(program_state->mfkey_state == Error) { - canvas_draw_str_aligned(canvas, 50, 25, AlignLeft, AlignTop, "Error"); - canvas_set_font(canvas, FontSecondary); - if(program_state->err == MissingNonces) { - canvas_draw_str_aligned(canvas, 25, 36, AlignLeft, AlignTop, "No nonces found"); - } else if(program_state->err == ZeroNonces) { - canvas_draw_str_aligned(canvas, 15, 36, AlignLeft, AlignTop, "Nonces already cracked"); - } else { - // Unhandled error - } - } else { - // Unhandled program state - } - furi_mutex_release(program_state->mutex); -} - -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - PluginEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void mfkey32_state_init(ProgramState* program_state) { - program_state->is_thread_running = false; - program_state->mfkey_state = Ready; - program_state->cracked = 0; - program_state->unique_cracked = 0; - program_state->num_completed = 0; - program_state->total = 0; - program_state->dict_count = 0; -} - -// Entrypoint for worker thread -static int32_t mfkey32_worker_thread(void* ctx) { - ProgramState* program_state = ctx; - program_state->is_thread_running = true; - program_state->mfkey_state = Initializing; - //FURI_LOG_I(TAG, "Hello from the mfkey32 worker thread"); // DEBUG - mfkey32(program_state); - program_state->is_thread_running = false; - return 0; -} - -void start_mfkey32_thread(ProgramState* program_state) { - if(!program_state->is_thread_running) { - furi_thread_start(program_state->mfkeythread); - } -} - -int32_t mfkey32_main() { - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); - - ProgramState* program_state = malloc(sizeof(ProgramState)); - - mfkey32_state_init(program_state); - - program_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!program_state->mutex) { - FURI_LOG_E(TAG, "cannot create mutex\r\n"); - free(program_state); - return 255; - } - - // Set system callbacks - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, render_callback, program_state); - view_port_input_callback_set(view_port, input_callback, event_queue); - - // Open GUI and register view_port - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - program_state->mfkeythread = furi_thread_alloc(); - furi_thread_set_name(program_state->mfkeythread, "Mfkey32 Worker"); - furi_thread_set_stack_size(program_state->mfkeythread, 2048); - furi_thread_set_context(program_state->mfkeythread, program_state); - furi_thread_set_callback(program_state->mfkeythread, mfkey32_worker_thread); - - PluginEvent event; - for(bool main_loop = true; main_loop;) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - - furi_mutex_acquire(program_state->mutex, FuriWaitForever); - - if(event_status == FuriStatusOk) { - // press events - if(event.type == EventTypeKey) { - if(event.input.type == InputTypePress) { - switch(event.input.key) { - case InputKeyUp: - break; - case InputKeyDown: - break; - case InputKeyRight: - if(!program_state->is_thread_running && - program_state->mfkey_state == Ready) { - program_state->mfkey_state = Help; - view_port_update(view_port); - } - break; - case InputKeyLeft: - break; - case InputKeyOk: - if(!program_state->is_thread_running && - program_state->mfkey_state == Ready) { - start_mfkey32_thread(program_state); - view_port_update(view_port); - } - break; - case InputKeyBack: - if(!program_state->is_thread_running && - program_state->mfkey_state == Help) { - program_state->mfkey_state = Ready; - view_port_update(view_port); - } else { - program_state->close_thread_please = true; - if(program_state->is_thread_running && program_state->mfkeythread) { - // Wait until thread is finished - furi_thread_join(program_state->mfkeythread); - } - program_state->close_thread_please = false; - main_loop = false; - } - break; - default: - break; - } - } - } - } - - view_port_update(view_port); - furi_mutex_release(program_state->mutex); - } - - furi_thread_free(program_state->mfkeythread); - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - furi_record_close("gui"); - view_port_free(view_port); - furi_message_queue_free(event_queue); - furi_mutex_free(program_state->mutex); - free(program_state); - - return 0; -} diff --git a/applications/external/nfc_magic/application.fam b/applications/external/nfc_magic/application.fam deleted file mode 100644 index a89b45d00..000000000 --- a/applications/external/nfc_magic/application.fam +++ /dev/null @@ -1,21 +0,0 @@ -App( - appid="nfc_magic", - name="Nfc Magic", - apptype=FlipperAppType.EXTERNAL, - targets=["f7"], - entry_point="nfc_magic_app", - requires=[ - "storage", - "gui", - ], - stack_size=4 * 1024, - order=30, - fap_icon="../../../assets/icons/Archive/125_10px.png", - fap_category="NFC", - fap_private_libs=[ - Lib( - name="magic", - ), - ], - fap_icon_assets="assets", -) diff --git a/applications/external/nfc_magic/assets/DolphinCommon_56x48.png b/applications/external/nfc_magic/assets/DolphinCommon_56x48.png deleted file mode 100644 index 089aaed83..000000000 Binary files a/applications/external/nfc_magic/assets/DolphinCommon_56x48.png and /dev/null differ diff --git a/applications/external/nfc_magic/assets/DolphinNice_96x59.png b/applications/external/nfc_magic/assets/DolphinNice_96x59.png deleted file mode 100644 index a299d3630..000000000 Binary files a/applications/external/nfc_magic/assets/DolphinNice_96x59.png and /dev/null differ diff --git a/applications/external/nfc_magic/assets/Loading_24.png b/applications/external/nfc_magic/assets/Loading_24.png deleted file mode 100644 index 93a59fe68..000000000 Binary files a/applications/external/nfc_magic/assets/Loading_24.png and /dev/null differ diff --git a/applications/external/nfc_magic/assets/NFC_manual_60x50.png b/applications/external/nfc_magic/assets/NFC_manual_60x50.png deleted file mode 100644 index 787c0bcfe..000000000 Binary files a/applications/external/nfc_magic/assets/NFC_manual_60x50.png and /dev/null differ diff --git a/applications/external/nfc_magic/lib/magic/classic_gen1.c b/applications/external/nfc_magic/lib/magic/classic_gen1.c deleted file mode 100644 index 8d87d6316..000000000 --- a/applications/external/nfc_magic/lib/magic/classic_gen1.c +++ /dev/null @@ -1,145 +0,0 @@ -#include "classic_gen1.h" - -#include - -#define TAG "Magic" - -#define MAGIC_CMD_WUPA (0x40) -#define MAGIC_CMD_ACCESS (0x43) - -#define MAGIC_MIFARE_READ_CMD (0x30) -#define MAGIC_MIFARE_WRITE_CMD (0xA0) - -#define MAGIC_ACK (0x0A) - -#define MAGIC_BUFFER_SIZE (32) - -bool magic_gen1_wupa() { - bool magic_activated = false; - uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; - uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; - uint16_t rx_len = 0; - FuriHalNfcReturn ret = 0; - - do { - // Start communication - tx_data[0] = MAGIC_CMD_WUPA; - ret = furi_hal_nfc_ll_txrx_bits( - tx_data, - 7, - rx_data, - sizeof(rx_data), - &rx_len, - FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | - FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP, - furi_hal_nfc_ll_ms2fc(20)); - if(ret != FuriHalNfcReturnIncompleteByte) break; - if(rx_len != 4) break; - if(rx_data[0] != MAGIC_ACK) break; - magic_activated = true; - } while(false); - - return magic_activated; -} - -bool magic_gen1_data_access_cmd() { - bool write_cmd_success = false; - uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; - uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; - uint16_t rx_len = 0; - FuriHalNfcReturn ret = 0; - - do { - tx_data[0] = MAGIC_CMD_ACCESS; - ret = furi_hal_nfc_ll_txrx_bits( - tx_data, - 8, - rx_data, - sizeof(rx_data), - &rx_len, - FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | - FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP, - furi_hal_nfc_ll_ms2fc(20)); - if(ret != FuriHalNfcReturnIncompleteByte) break; - if(rx_len != 4) break; - if(rx_data[0] != MAGIC_ACK) break; - - write_cmd_success = true; - } while(false); - - return write_cmd_success; -} - -bool magic_gen1_read_block(uint8_t block_num, MfClassicBlock* data) { - furi_assert(data); - - bool read_success = false; - - uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; - uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; - uint16_t rx_len = 0; - FuriHalNfcReturn ret = 0; - - do { - tx_data[0] = MAGIC_MIFARE_READ_CMD; - tx_data[1] = block_num; - ret = furi_hal_nfc_ll_txrx_bits( - tx_data, - 2 * 8, - rx_data, - sizeof(rx_data), - &rx_len, - FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON, - furi_hal_nfc_ll_ms2fc(20)); - - if(ret != FuriHalNfcReturnOk) break; - if(rx_len != 16 * 8) break; - memcpy(data->value, rx_data, sizeof(data->value)); - read_success = true; - } while(false); - - return read_success; -} - -bool magic_gen1_write_blk(uint8_t block_num, MfClassicBlock* data) { - furi_assert(data); - - bool write_success = false; - uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; - uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; - uint16_t rx_len = 0; - FuriHalNfcReturn ret = 0; - - do { - tx_data[0] = MAGIC_MIFARE_WRITE_CMD; - tx_data[1] = block_num; - ret = furi_hal_nfc_ll_txrx_bits( - tx_data, - 2 * 8, - rx_data, - sizeof(rx_data), - &rx_len, - FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP, - furi_hal_nfc_ll_ms2fc(20)); - if(ret != FuriHalNfcReturnIncompleteByte) break; - if(rx_len != 4) break; - if(rx_data[0] != MAGIC_ACK) break; - - memcpy(tx_data, data->value, sizeof(data->value)); - ret = furi_hal_nfc_ll_txrx_bits( - tx_data, - 16 * 8, - rx_data, - sizeof(rx_data), - &rx_len, - FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP, - furi_hal_nfc_ll_ms2fc(20)); - if(ret != FuriHalNfcReturnIncompleteByte) break; - if(rx_len != 4) break; - if(rx_data[0] != MAGIC_ACK) break; - - write_success = true; - } while(false); - - return write_success; -} diff --git a/applications/external/nfc_magic/lib/magic/classic_gen1.h b/applications/external/nfc_magic/lib/magic/classic_gen1.h deleted file mode 100644 index 98de12302..000000000 --- a/applications/external/nfc_magic/lib/magic/classic_gen1.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -bool magic_gen1_wupa(); - -bool magic_gen1_read_block(uint8_t block_num, MfClassicBlock* data); - -bool magic_gen1_data_access_cmd(); - -bool magic_gen1_write_blk(uint8_t block_num, MfClassicBlock* data); diff --git a/applications/external/nfc_magic/lib/magic/common.c b/applications/external/nfc_magic/lib/magic/common.c deleted file mode 100644 index 0ea3cb218..000000000 --- a/applications/external/nfc_magic/lib/magic/common.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "common.h" - -#include - -#define REQA (0x26) -#define CL1_PREFIX (0x93) -#define SELECT (0x70) - -#define MAGIC_BUFFER_SIZE (32) - -bool magic_activate() { - FuriHalNfcReturn ret = 0; - - // Setup nfc poller - furi_hal_nfc_exit_sleep(); - furi_hal_nfc_ll_txrx_on(); - furi_hal_nfc_ll_poll(); - ret = furi_hal_nfc_ll_set_mode( - FuriHalNfcModePollNfca, FuriHalNfcBitrate106, FuriHalNfcBitrate106); - if(ret != FuriHalNfcReturnOk) return false; - - furi_hal_nfc_ll_set_fdt_listen(FURI_HAL_NFC_LL_FDT_LISTEN_NFCA_POLLER); - furi_hal_nfc_ll_set_fdt_poll(FURI_HAL_NFC_LL_FDT_POLL_NFCA_POLLER); - furi_hal_nfc_ll_set_error_handling(FuriHalNfcErrorHandlingNfc); - furi_hal_nfc_ll_set_guard_time(FURI_HAL_NFC_LL_GT_NFCA); - - return true; -} - -void magic_deactivate() { - furi_hal_nfc_ll_txrx_off(); - furi_hal_nfc_sleep(); -} \ No newline at end of file diff --git a/applications/external/nfc_magic/lib/magic/common.h b/applications/external/nfc_magic/lib/magic/common.h deleted file mode 100644 index bef166c8f..000000000 --- a/applications/external/nfc_magic/lib/magic/common.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include -#include - -typedef enum { - MagicTypeClassicGen1, - MagicTypeClassicDirectWrite, - MagicTypeClassicAPDU, - MagicTypeUltralightGen1, - MagicTypeUltralightDirectWrite, - MagicTypeUltralightC_Gen1, - MagicTypeUltralightC_DirectWrite, - MagicTypeGen4, -} MagicType; - -bool magic_activate(); - -void magic_deactivate(); \ No newline at end of file diff --git a/applications/external/nfc_magic/lib/magic/gen4.c b/applications/external/nfc_magic/lib/magic/gen4.c deleted file mode 100644 index 31be649a0..000000000 --- a/applications/external/nfc_magic/lib/magic/gen4.c +++ /dev/null @@ -1,199 +0,0 @@ -#include "gen4.h" - -#include -#include - -#define TAG "Magic" - -#define MAGIC_CMD_PREFIX (0xCF) - -#define MAGIC_CMD_GET_CFG (0xC6) -#define MAGIC_CMD_WRITE (0xCD) -#define MAGIC_CMD_READ (0xCE) -#define MAGIC_CMD_SET_CFG (0xF0) -#define MAGIC_CMD_FUSE_CFG (0xF1) -#define MAGIC_CMD_SET_PWD (0xFE) - -#define MAGIC_BUFFER_SIZE (40) - -const uint8_t MAGIC_DEFAULT_CONFIG[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x09, 0x78, 0x00, 0x91, 0x02, 0xDA, 0xBC, 0x19, 0x10, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x04, 0x00, 0x08, 0x00 -}; - -const uint8_t MAGIC_DEFAULT_BLOCK0[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -const uint8_t MAGIC_EMPTY_BLOCK[16] = { 0 }; - -const uint8_t MAGIC_DEFAULT_SECTOR_TRAILER[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x80, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF -}; - -static bool magic_gen4_is_block_num_trailer(uint8_t n) { - n++; - if (n < 32 * 4) { - return (n % 4 == 0); - } - - return (n % 16 == 0); -} - -bool magic_gen4_get_cfg(uint32_t pwd, uint8_t* config) { - bool is_valid_config_len = false; - uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; - uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; - uint16_t rx_len = 0; - FuriHalNfcReturn ret = 0; - - do { - // Start communication - tx_data[0] = MAGIC_CMD_PREFIX; - tx_data[1] = (uint8_t)(pwd >> 24); - tx_data[2] = (uint8_t)(pwd >> 16); - tx_data[3] = (uint8_t)(pwd >> 8); - tx_data[4] = (uint8_t)pwd; - tx_data[5] = MAGIC_CMD_GET_CFG; - ret = furi_hal_nfc_ll_txrx( - tx_data, - 6, - rx_data, - sizeof(rx_data), - &rx_len, - FURI_HAL_NFC_TXRX_DEFAULT, - furi_hal_nfc_ll_ms2fc(20)); - if(ret != FuriHalNfcReturnOk) break; - if(rx_len != 30 && rx_len != 32) break; - memcpy(config, rx_data, rx_len); - is_valid_config_len = true; - } while(false); - - return is_valid_config_len; -} - -bool magic_gen4_set_cfg(uint32_t pwd, const uint8_t* config, uint8_t config_length, bool fuse) { - bool write_success = false; - uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; - uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; - uint16_t rx_len = 0; - FuriHalNfcReturn ret = 0; - - do { - // Start communication - tx_data[0] = MAGIC_CMD_PREFIX; - tx_data[1] = (uint8_t)(pwd >> 24); - tx_data[2] = (uint8_t)(pwd >> 16); - tx_data[3] = (uint8_t)(pwd >> 8); - tx_data[4] = (uint8_t)pwd; - tx_data[5] = fuse ? MAGIC_CMD_FUSE_CFG : MAGIC_CMD_SET_CFG; - memcpy(tx_data + 6, config, config_length); - ret = furi_hal_nfc_ll_txrx( - tx_data, - 6 + config_length, - rx_data, - sizeof(rx_data), - &rx_len, - FURI_HAL_NFC_TXRX_DEFAULT, - furi_hal_nfc_ll_ms2fc(20)); - if(ret != FuriHalNfcReturnOk) break; - if(rx_len != 2) break; - write_success = true; - } while(false); - - return write_success; -} - -bool magic_gen4_set_pwd(uint32_t old_pwd, uint32_t new_pwd) { - bool change_success = false; - uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; - uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; - uint16_t rx_len = 0; - FuriHalNfcReturn ret = 0; - - do { - // Start communication - tx_data[0] = MAGIC_CMD_PREFIX; - tx_data[1] = (uint8_t)(old_pwd >> 24); - tx_data[2] = (uint8_t)(old_pwd >> 16); - tx_data[3] = (uint8_t)(old_pwd >> 8); - tx_data[4] = (uint8_t)old_pwd; - tx_data[5] = MAGIC_CMD_SET_PWD; - tx_data[6] = (uint8_t)(new_pwd >> 24); - tx_data[7] = (uint8_t)(new_pwd >> 16); - tx_data[8] = (uint8_t)(new_pwd >> 8); - tx_data[9] = (uint8_t)new_pwd; - ret = furi_hal_nfc_ll_txrx( - tx_data, - 10, - rx_data, - sizeof(rx_data), - &rx_len, - FURI_HAL_NFC_TXRX_DEFAULT, - furi_hal_nfc_ll_ms2fc(20)); - FURI_LOG_I(TAG, "ret %d, len %d", ret, rx_len); - if(ret != FuriHalNfcReturnOk) break; - if(rx_len != 2) break; - change_success = true; - } while(false); - - return change_success; -} - -bool magic_gen4_write_blk(uint32_t pwd, uint8_t block_num, const uint8_t* data) { - bool write_success = false; - uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; - uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; - uint16_t rx_len = 0; - FuriHalNfcReturn ret = 0; - - do { - // Start communication - tx_data[0] = MAGIC_CMD_PREFIX; - tx_data[1] = (uint8_t)(pwd >> 24); - tx_data[2] = (uint8_t)(pwd >> 16); - tx_data[3] = (uint8_t)(pwd >> 8); - tx_data[4] = (uint8_t)pwd; - tx_data[5] = MAGIC_CMD_WRITE; - tx_data[6] = block_num; - memcpy(tx_data + 7, data, 16); - ret = furi_hal_nfc_ll_txrx( - tx_data, - 23, - rx_data, - sizeof(rx_data), - &rx_len, - FURI_HAL_NFC_TXRX_DEFAULT, - furi_hal_nfc_ll_ms2fc(200)); - if(ret != FuriHalNfcReturnOk) break; - if(rx_len != 2) break; - write_success = true; - } while(false); - - return write_success; -} - -bool magic_gen4_wipe(uint32_t pwd) { - if(!magic_gen4_set_cfg(pwd, MAGIC_DEFAULT_CONFIG, sizeof(MAGIC_DEFAULT_CONFIG), false)) { - FURI_LOG_E(TAG, "Set config failed"); - return false; - } - if(!magic_gen4_write_blk(pwd, 0, MAGIC_DEFAULT_BLOCK0)) { - FURI_LOG_E(TAG, "Block 0 write failed"); - return false; - } - for(size_t i = 1; i < 64; i++) { - const uint8_t* block = magic_gen4_is_block_num_trailer(i) ? MAGIC_DEFAULT_SECTOR_TRAILER : MAGIC_EMPTY_BLOCK; - if(!magic_gen4_write_blk(pwd, i, block)) { - FURI_LOG_E(TAG, "Block %d write failed", i); - return false; - } - } - for(size_t i = 65; i < 256; i++) { - if(!magic_gen4_write_blk(pwd, i, MAGIC_EMPTY_BLOCK)) { - FURI_LOG_E(TAG, "Block %d write failed", i); - return false; - } - } - - return true; -} \ No newline at end of file diff --git a/applications/external/nfc_magic/lib/magic/gen4.h b/applications/external/nfc_magic/lib/magic/gen4.h deleted file mode 100644 index c515af820..000000000 --- a/applications/external/nfc_magic/lib/magic/gen4.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include - -#define MAGIC_GEN4_DEFAULT_PWD 0x00000000 -#define MAGIC_GEN4_CONFIG_LEN 32 - -#define NFCID1_SINGLE_SIZE 4 -#define NFCID1_DOUBLE_SIZE 7 -#define NFCID1_TRIPLE_SIZE 10 - -typedef enum { - MagicGen4UIDLengthSingle = 0x00, - MagicGen4UIDLengthDouble = 0x01, - MagicGen4UIDLengthTriple = 0x02 -} MagicGen4UIDLength; - -typedef enum { - MagicGen4UltralightModeUL_EV1 = 0x00, - MagicGen4UltralightModeNTAG = 0x01, - MagicGen4UltralightModeUL_C = 0x02, - MagicGen4UltralightModeUL = 0x03 -} MagicGen4UltralightMode; - -typedef enum { - // for writing original (shadow) data - MagicGen4ShadowModePreWrite = 0x00, - // written data can be read once before restored to original - MagicGen4ShadowModeRestore = 0x01, - // written data is discarded - MagicGen4ShadowModeIgnore = 0x02, - // apparently for UL? - MagicGen4ShadowModeHighSpeedIgnore = 0x03 -} MagicGen4ShadowMode; - -bool magic_gen4_get_cfg(uint32_t pwd, uint8_t* config); - -bool magic_gen4_set_cfg(uint32_t pwd, const uint8_t* config, uint8_t config_length, bool fuse); - -bool magic_gen4_set_pwd(uint32_t old_pwd, uint32_t new_pwd); - -bool magic_gen4_read_blk(uint32_t pwd, uint8_t block_num, uint8_t* data); - -bool magic_gen4_write_blk(uint32_t pwd, uint8_t block_num, const uint8_t* data); - -bool magic_gen4_wipe(uint32_t pwd); - -void magic_gen4_deactivate(); diff --git a/applications/external/nfc_magic/lib/magic/types.c b/applications/external/nfc_magic/lib/magic/types.c deleted file mode 100644 index 77c6c0a4e..000000000 --- a/applications/external/nfc_magic/lib/magic/types.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "types.h" - -const char* nfc_magic_type(MagicType type) { - if(type == MagicTypeClassicGen1) { - return "Classic Gen 1A/B"; - } else if(type == MagicTypeClassicDirectWrite) { - return "Classic DirectWrite"; - } else if(type == MagicTypeClassicAPDU) { - return "Classic APDU"; - } else if(type == MagicTypeUltralightGen1) { - return "Ultralight Gen 1"; - } else if(type == MagicTypeUltralightDirectWrite) { - return "Ultralight DirectWrite"; - } else if(type == MagicTypeUltralightC_Gen1) { - return "Ultralight-C Gen 1"; - } else if(type == MagicTypeUltralightC_DirectWrite) { - return "Ultralight-C DirectWrite"; - } else if(type == MagicTypeGen4) { - return "Gen 4 GTU"; - } else { - return "Unknown"; - } -} diff --git a/applications/external/nfc_magic/lib/magic/types.h b/applications/external/nfc_magic/lib/magic/types.h deleted file mode 100644 index dbf554063..000000000 --- a/applications/external/nfc_magic/lib/magic/types.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include "common.h" - -const char* nfc_magic_type(MagicType type); \ No newline at end of file diff --git a/applications/external/nfc_magic/nfc_magic.c b/applications/external/nfc_magic/nfc_magic.c deleted file mode 100644 index 68c9a65b5..000000000 --- a/applications/external/nfc_magic/nfc_magic.c +++ /dev/null @@ -1,184 +0,0 @@ -#include "nfc_magic_i.h" - -bool nfc_magic_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - NfcMagic* nfc_magic = context; - return scene_manager_handle_custom_event(nfc_magic->scene_manager, event); -} - -bool nfc_magic_back_event_callback(void* context) { - furi_assert(context); - NfcMagic* nfc_magic = context; - return scene_manager_handle_back_event(nfc_magic->scene_manager); -} - -void nfc_magic_tick_event_callback(void* context) { - furi_assert(context); - NfcMagic* nfc_magic = context; - scene_manager_handle_tick_event(nfc_magic->scene_manager); -} - -void nfc_magic_show_loading_popup(void* context, bool show) { - NfcMagic* nfc_magic = context; - TaskHandle_t timer_task = xTaskGetHandle(configTIMER_SERVICE_TASK_NAME); - - if(show) { - // Raise timer priority so that animations can play - vTaskPrioritySet(timer_task, configMAX_PRIORITIES - 1); - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewLoading); - } else { - // Restore default timer priority - vTaskPrioritySet(timer_task, configTIMER_TASK_PRIORITY); - } -} - -NfcMagic* nfc_magic_alloc() { - NfcMagic* nfc_magic = malloc(sizeof(NfcMagic)); - - nfc_magic->worker = nfc_magic_worker_alloc(); - nfc_magic->view_dispatcher = view_dispatcher_alloc(); - nfc_magic->scene_manager = scene_manager_alloc(&nfc_magic_scene_handlers, nfc_magic); - view_dispatcher_enable_queue(nfc_magic->view_dispatcher); - view_dispatcher_set_event_callback_context(nfc_magic->view_dispatcher, nfc_magic); - view_dispatcher_set_custom_event_callback( - nfc_magic->view_dispatcher, nfc_magic_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - nfc_magic->view_dispatcher, nfc_magic_back_event_callback); - view_dispatcher_set_tick_event_callback( - nfc_magic->view_dispatcher, nfc_magic_tick_event_callback, 100); - - // Nfc device - nfc_magic->dev = malloc(sizeof(NfcMagicDevice)); - nfc_magic->source_dev = nfc_device_alloc(); - furi_string_set(nfc_magic->source_dev->folder, NFC_APP_FOLDER); - - // Open GUI record - nfc_magic->gui = furi_record_open(RECORD_GUI); - view_dispatcher_attach_to_gui( - nfc_magic->view_dispatcher, nfc_magic->gui, ViewDispatcherTypeFullscreen); - - // Open Notification record - nfc_magic->notifications = furi_record_open(RECORD_NOTIFICATION); - - // Submenu - nfc_magic->submenu = submenu_alloc(); - view_dispatcher_add_view( - nfc_magic->view_dispatcher, NfcMagicViewMenu, submenu_get_view(nfc_magic->submenu)); - - // Popup - nfc_magic->popup = popup_alloc(); - view_dispatcher_add_view( - nfc_magic->view_dispatcher, NfcMagicViewPopup, popup_get_view(nfc_magic->popup)); - - // Loading - nfc_magic->loading = loading_alloc(); - view_dispatcher_add_view( - nfc_magic->view_dispatcher, NfcMagicViewLoading, loading_get_view(nfc_magic->loading)); - - // Text Input - nfc_magic->text_input = text_input_alloc(); - view_dispatcher_add_view( - nfc_magic->view_dispatcher, - NfcMagicViewTextInput, - text_input_get_view(nfc_magic->text_input)); - - // Byte Input - nfc_magic->byte_input = byte_input_alloc(); - view_dispatcher_add_view( - nfc_magic->view_dispatcher, - NfcMagicViewByteInput, - byte_input_get_view(nfc_magic->byte_input)); - - // Custom Widget - nfc_magic->widget = widget_alloc(); - view_dispatcher_add_view( - nfc_magic->view_dispatcher, NfcMagicViewWidget, widget_get_view(nfc_magic->widget)); - - return nfc_magic; -} - -void nfc_magic_free(NfcMagic* nfc_magic) { - furi_assert(nfc_magic); - - // Nfc device - free(nfc_magic->dev); - nfc_device_free(nfc_magic->source_dev); - - // Submenu - view_dispatcher_remove_view(nfc_magic->view_dispatcher, NfcMagicViewMenu); - submenu_free(nfc_magic->submenu); - - // Popup - view_dispatcher_remove_view(nfc_magic->view_dispatcher, NfcMagicViewPopup); - popup_free(nfc_magic->popup); - - // Loading - view_dispatcher_remove_view(nfc_magic->view_dispatcher, NfcMagicViewLoading); - loading_free(nfc_magic->loading); - - // Text Input - view_dispatcher_remove_view(nfc_magic->view_dispatcher, NfcMagicViewTextInput); - text_input_free(nfc_magic->text_input); - - // Byte Input - view_dispatcher_remove_view(nfc_magic->view_dispatcher, NfcMagicViewByteInput); - byte_input_free(nfc_magic->byte_input); - - // Custom Widget - view_dispatcher_remove_view(nfc_magic->view_dispatcher, NfcMagicViewWidget); - widget_free(nfc_magic->widget); - - // Worker - nfc_magic_worker_stop(nfc_magic->worker); - nfc_magic_worker_free(nfc_magic->worker); - - // View Dispatcher - view_dispatcher_free(nfc_magic->view_dispatcher); - - // Scene Manager - scene_manager_free(nfc_magic->scene_manager); - - // GUI - furi_record_close(RECORD_GUI); - nfc_magic->gui = NULL; - - // Notifications - furi_record_close(RECORD_NOTIFICATION); - nfc_magic->notifications = NULL; - - free(nfc_magic); -} - -static const NotificationSequence nfc_magic_sequence_blink_start_cyan = { - &message_blink_start_10, - &message_blink_set_color_cyan, - &message_do_not_reset, - NULL, -}; - -static const NotificationSequence nfc_magic_sequence_blink_stop = { - &message_blink_stop, - NULL, -}; - -void nfc_magic_blink_start(NfcMagic* nfc_magic) { - notification_message(nfc_magic->notifications, &nfc_magic_sequence_blink_start_cyan); -} - -void nfc_magic_blink_stop(NfcMagic* nfc_magic) { - notification_message(nfc_magic->notifications, &nfc_magic_sequence_blink_stop); -} - -int32_t nfc_magic_app(void* p) { - UNUSED(p); - NfcMagic* nfc_magic = nfc_magic_alloc(); - - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneStart); - - view_dispatcher_run(nfc_magic->view_dispatcher); - - magic_deactivate(); - nfc_magic_free(nfc_magic); - - return 0; -} diff --git a/applications/external/nfc_magic/nfc_magic.h b/applications/external/nfc_magic/nfc_magic.h deleted file mode 100644 index f9cf395d8..000000000 --- a/applications/external/nfc_magic/nfc_magic.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -typedef struct NfcMagicDevice NfcMagicDevice; - -typedef struct NfcMagic NfcMagic; diff --git a/applications/external/nfc_magic/nfc_magic_i.h b/applications/external/nfc_magic/nfc_magic_i.h deleted file mode 100644 index 88bc5706f..000000000 --- a/applications/external/nfc_magic/nfc_magic_i.h +++ /dev/null @@ -1,94 +0,0 @@ -#pragma once - -#include "nfc_magic.h" -#include "nfc_magic_worker.h" - -#include "lib/magic/common.h" -#include "lib/magic/types.h" -#include "lib/magic/classic_gen1.h" -#include "lib/magic/gen4.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "scenes/nfc_magic_scene.h" - -#include -#include - -#include -#include "nfc_magic_icons.h" - -#define NFC_APP_FOLDER ANY_PATH("nfc") - -enum NfcMagicCustomEvent { - // Reserve first 100 events for button types and indexes, starting from 0 - NfcMagicCustomEventReserved = 100, - - NfcMagicCustomEventViewExit, - NfcMagicCustomEventWorkerExit, - NfcMagicCustomEventByteInputDone, - NfcMagicCustomEventTextInputDone, -}; - -struct NfcMagicDevice { - MagicType type; - uint32_t cuid; - uint8_t uid_len; - uint32_t password; -}; - -struct NfcMagic { - NfcMagicWorker* worker; - ViewDispatcher* view_dispatcher; - Gui* gui; - NotificationApp* notifications; - SceneManager* scene_manager; - struct NfcMagicDevice* dev; - NfcDevice* source_dev; - - uint32_t new_password; - - FuriString* text_box_store; - - // Common Views - Submenu* submenu; - Popup* popup; - Loading* loading; - TextInput* text_input; - ByteInput* byte_input; - Widget* widget; -}; - -typedef enum { - NfcMagicViewMenu, - NfcMagicViewPopup, - NfcMagicViewLoading, - NfcMagicViewTextInput, - NfcMagicViewByteInput, - NfcMagicViewWidget, -} NfcMagicView; - -NfcMagic* nfc_magic_alloc(); - -void nfc_magic_text_store_set(NfcMagic* nfc_magic, const char* text, ...); - -void nfc_magic_text_store_clear(NfcMagic* nfc_magic); - -void nfc_magic_blink_start(NfcMagic* nfc_magic); - -void nfc_magic_blink_stop(NfcMagic* nfc_magic); - -void nfc_magic_show_loading_popup(void* context, bool show); diff --git a/applications/external/nfc_magic/nfc_magic_worker.c b/applications/external/nfc_magic/nfc_magic_worker.c deleted file mode 100644 index eb715fe0d..000000000 --- a/applications/external/nfc_magic/nfc_magic_worker.c +++ /dev/null @@ -1,480 +0,0 @@ -#include "nfc_magic_worker_i.h" - -#include "nfc_magic_i.h" -#include "lib/magic/common.h" -#include "lib/magic/classic_gen1.h" -#include "lib/magic/gen4.h" - -#define TAG "NfcMagicWorker" - -static void - nfc_magic_worker_change_state(NfcMagicWorker* nfc_magic_worker, NfcMagicWorkerState state) { - furi_assert(nfc_magic_worker); - - nfc_magic_worker->state = state; -} - -NfcMagicWorker* nfc_magic_worker_alloc() { - NfcMagicWorker* nfc_magic_worker = malloc(sizeof(NfcMagicWorker)); - - // Worker thread attributes - nfc_magic_worker->thread = - furi_thread_alloc_ex("NfcMagicWorker", 8192, nfc_magic_worker_task, nfc_magic_worker); - - nfc_magic_worker->callback = NULL; - nfc_magic_worker->context = NULL; - - nfc_magic_worker_change_state(nfc_magic_worker, NfcMagicWorkerStateReady); - - return nfc_magic_worker; -} - -void nfc_magic_worker_free(NfcMagicWorker* nfc_magic_worker) { - furi_assert(nfc_magic_worker); - - furi_thread_free(nfc_magic_worker->thread); - free(nfc_magic_worker); -} - -void nfc_magic_worker_stop(NfcMagicWorker* nfc_magic_worker) { - furi_assert(nfc_magic_worker); - - nfc_magic_worker_change_state(nfc_magic_worker, NfcMagicWorkerStateStop); - furi_thread_join(nfc_magic_worker->thread); -} - -void nfc_magic_worker_start( - NfcMagicWorker* nfc_magic_worker, - NfcMagicWorkerState state, - NfcMagicDevice* magic_dev, - NfcDeviceData* dev_data, - uint32_t new_password, - NfcMagicWorkerCallback callback, - void* context) { - furi_assert(nfc_magic_worker); - furi_assert(magic_dev); - furi_assert(dev_data); - - nfc_magic_worker->callback = callback; - nfc_magic_worker->context = context; - nfc_magic_worker->magic_dev = magic_dev; - nfc_magic_worker->dev_data = dev_data; - nfc_magic_worker->new_password = new_password; - nfc_magic_worker_change_state(nfc_magic_worker, state); - furi_thread_start(nfc_magic_worker->thread); -} - -int32_t nfc_magic_worker_task(void* context) { - NfcMagicWorker* nfc_magic_worker = context; - - if(nfc_magic_worker->state == NfcMagicWorkerStateCheck) { - nfc_magic_worker_check(nfc_magic_worker); - } else if(nfc_magic_worker->state == NfcMagicWorkerStateWrite) { - nfc_magic_worker_write(nfc_magic_worker); - } else if(nfc_magic_worker->state == NfcMagicWorkerStateRekey) { - nfc_magic_worker_rekey(nfc_magic_worker); - } else if(nfc_magic_worker->state == NfcMagicWorkerStateWipe) { - nfc_magic_worker_wipe(nfc_magic_worker); - } - - nfc_magic_worker_change_state(nfc_magic_worker, NfcMagicWorkerStateReady); - - return 0; -} - -void nfc_magic_worker_write(NfcMagicWorker* nfc_magic_worker) { - bool card_found_notified = false; - bool done = false; - FuriHalNfcDevData nfc_data = {}; - NfcMagicDevice* magic_dev = nfc_magic_worker->magic_dev; - NfcDeviceData* dev_data = nfc_magic_worker->dev_data; - NfcProtocol dev_protocol = dev_data->protocol; - - while(nfc_magic_worker->state == NfcMagicWorkerStateWrite) { - do { - if(magic_dev->type == MagicTypeClassicGen1) { - if(furi_hal_nfc_detect(&nfc_data, 200)) { - magic_deactivate(); - magic_activate(); - if(!magic_gen1_wupa()) { - FURI_LOG_E(TAG, "No card response to WUPA (not a magic card)"); - nfc_magic_worker->callback( - NfcMagicWorkerEventWrongCard, nfc_magic_worker->context); - done = true; - break; - } - magic_deactivate(); - } - magic_activate(); - if(magic_gen1_wupa()) { - magic_gen1_data_access_cmd(); - - MfClassicData* mfc_data = &dev_data->mf_classic_data; - for(size_t i = 0; i < 64; i++) { - FURI_LOG_D(TAG, "Writing block %d", i); - if(!magic_gen1_write_blk(i, &mfc_data->block[i])) { - FURI_LOG_E(TAG, "Failed to write %d block", i); - done = true; - nfc_magic_worker->callback( - NfcMagicWorkerEventFail, nfc_magic_worker->context); - break; - } - } - - done = true; - nfc_magic_worker->callback( - NfcMagicWorkerEventSuccess, nfc_magic_worker->context); - break; - } - } else if(magic_dev->type == MagicTypeGen4) { - if(furi_hal_nfc_detect(&nfc_data, 200)) { - uint8_t gen4_config[28]; - uint32_t password = magic_dev->password; - - uint32_t cuid; - if(dev_protocol == NfcDeviceProtocolMifareClassic) { - gen4_config[0] = 0x00; - gen4_config[27] = 0x00; - } else if(dev_protocol == NfcDeviceProtocolMifareUl) { - MfUltralightData* mf_ul_data = &dev_data->mf_ul_data; - gen4_config[0] = 0x01; - switch(mf_ul_data->type) { - case MfUltralightTypeUL11: - case MfUltralightTypeUL21: - // UL-C? - // UL? - default: - gen4_config[27] = MagicGen4UltralightModeUL_EV1; - break; - case MfUltralightTypeNTAG203: - case MfUltralightTypeNTAG213: - case MfUltralightTypeNTAG215: - case MfUltralightTypeNTAG216: - case MfUltralightTypeNTAGI2C1K: - case MfUltralightTypeNTAGI2C2K: - case MfUltralightTypeNTAGI2CPlus1K: - case MfUltralightTypeNTAGI2CPlus2K: - gen4_config[27] = MagicGen4UltralightModeNTAG; - break; - } - } - - if(dev_data->nfc_data.uid_len == 4) { - gen4_config[1] = MagicGen4UIDLengthSingle; - } else if(dev_data->nfc_data.uid_len == 7) { - gen4_config[1] = MagicGen4UIDLengthDouble; - } else { - FURI_LOG_E(TAG, "Unexpected UID length %d", dev_data->nfc_data.uid_len); - nfc_magic_worker->callback( - NfcMagicWorkerEventFail, nfc_magic_worker->context); - done = true; - break; - } - - gen4_config[2] = (uint8_t)(password >> 24); - gen4_config[3] = (uint8_t)(password >> 16); - gen4_config[4] = (uint8_t)(password >> 8); - gen4_config[5] = (uint8_t)password; - - if(dev_protocol == NfcDeviceProtocolMifareUl) { - gen4_config[6] = MagicGen4ShadowModeHighSpeedIgnore; - } else { - gen4_config[6] = MagicGen4ShadowModeIgnore; - } - gen4_config[7] = 0x00; - memset(gen4_config + 8, 0, 16); - gen4_config[24] = dev_data->nfc_data.atqa[0]; - gen4_config[25] = dev_data->nfc_data.atqa[1]; - gen4_config[26] = dev_data->nfc_data.sak; - - furi_hal_nfc_sleep(); - furi_hal_nfc_activate_nfca(200, &cuid); - if(!magic_gen4_set_cfg(password, gen4_config, sizeof(gen4_config), false)) { - nfc_magic_worker->callback( - NfcMagicWorkerEventFail, nfc_magic_worker->context); - done = true; - break; - } - if(dev_protocol == NfcDeviceProtocolMifareClassic) { - MfClassicData* mfc_data = &dev_data->mf_classic_data; - size_t block_count = 64; - if(mfc_data->type == MfClassicType4k) block_count = 256; - for(size_t i = 0; i < block_count; i++) { - FURI_LOG_D(TAG, "Writing block %d", i); - if(!magic_gen4_write_blk(password, i, mfc_data->block[i].value)) { - FURI_LOG_E(TAG, "Failed to write %d block", i); - nfc_magic_worker->callback( - NfcMagicWorkerEventFail, nfc_magic_worker->context); - done = true; - break; - } - } - } else if(dev_protocol == NfcDeviceProtocolMifareUl) { - MfUltralightData* mf_ul_data = &dev_data->mf_ul_data; - for(size_t i = 0; (i * 4) < mf_ul_data->data_read; i++) { - size_t data_offset = i * 4; - FURI_LOG_D( - TAG, - "Writing page %zu (%zu/%u)", - i, - data_offset, - mf_ul_data->data_read); - uint8_t* block = mf_ul_data->data + data_offset; - if(!magic_gen4_write_blk(password, i, block)) { - FURI_LOG_E(TAG, "Failed to write %zu page", i); - nfc_magic_worker->callback( - NfcMagicWorkerEventFail, nfc_magic_worker->context); - done = true; - break; - } - } - - uint8_t buffer[16] = {0}; - - for(size_t i = 0; i < 8; i++) { - memcpy(buffer, &mf_ul_data->signature[i * 4], 4); //-V1086 - if(!magic_gen4_write_blk(password, 0xF2 + i, buffer)) { - FURI_LOG_E(TAG, "Failed to write signature block %d", i); - nfc_magic_worker->callback( - NfcMagicWorkerEventFail, nfc_magic_worker->context); - done = true; - break; - } - } - - buffer[0] = mf_ul_data->version.header; - buffer[1] = mf_ul_data->version.vendor_id; - buffer[2] = mf_ul_data->version.prod_type; - buffer[3] = mf_ul_data->version.prod_subtype; - if(!magic_gen4_write_blk(password, 0xFA, buffer)) { - FURI_LOG_E(TAG, "Failed to write version block 0"); - nfc_magic_worker->callback( - NfcMagicWorkerEventFail, nfc_magic_worker->context); - done = true; - break; - } - - buffer[0] = mf_ul_data->version.prod_ver_major; - buffer[1] = mf_ul_data->version.prod_ver_minor; - buffer[2] = mf_ul_data->version.storage_size; - buffer[3] = mf_ul_data->version.protocol_type; - if(!magic_gen4_write_blk(password, 0xFB, buffer)) { - FURI_LOG_E(TAG, "Failed to write version block 1"); - nfc_magic_worker->callback( - NfcMagicWorkerEventFail, nfc_magic_worker->context); - done = true; - break; - } - } - - nfc_magic_worker->callback( - NfcMagicWorkerEventSuccess, nfc_magic_worker->context); - done = true; - break; - } - } - } while(false); - - if(done) break; - - if(card_found_notified) { - nfc_magic_worker->callback( - NfcMagicWorkerEventNoCardDetected, nfc_magic_worker->context); - card_found_notified = false; - } - - furi_delay_ms(300); - } - magic_deactivate(); -} - -void nfc_magic_worker_check(NfcMagicWorker* nfc_magic_worker) { - FuriHalNfcDevData nfc_data = {}; - NfcMagicDevice* magic_dev = nfc_magic_worker->magic_dev; - bool card_found_notified = false; - uint8_t gen4_config[MAGIC_GEN4_CONFIG_LEN]; - - while(nfc_magic_worker->state == NfcMagicWorkerStateCheck) { - magic_activate(); - if(magic_gen1_wupa()) { - magic_dev->type = MagicTypeClassicGen1; - if(!card_found_notified) { - nfc_magic_worker->callback( - NfcMagicWorkerEventCardDetected, nfc_magic_worker->context); - card_found_notified = true; - } - - if(furi_hal_nfc_detect(&nfc_data, 200)) { - magic_dev->cuid = nfc_data.cuid; - magic_dev->uid_len = nfc_data.uid_len; - } else { - // wrong BCC - magic_dev->uid_len = 4; - } - nfc_magic_worker->callback(NfcMagicWorkerEventSuccess, nfc_magic_worker->context); - break; - } else { - magic_deactivate(); - magic_activate(); - if(furi_hal_nfc_detect(&nfc_data, 200)) { - magic_dev->cuid = nfc_data.cuid; - magic_dev->uid_len = nfc_data.uid_len; - if(magic_gen4_get_cfg(magic_dev->password, gen4_config)) { - magic_dev->type = MagicTypeGen4; - if(!card_found_notified) { - nfc_magic_worker->callback( - NfcMagicWorkerEventCardDetected, nfc_magic_worker->context); - card_found_notified = true; - } - - nfc_magic_worker->callback( - NfcMagicWorkerEventSuccess, nfc_magic_worker->context); - } else { - nfc_magic_worker->callback( - NfcMagicWorkerEventWrongCard, nfc_magic_worker->context); - card_found_notified = true; - } - break; - } else { - if(card_found_notified) { - nfc_magic_worker->callback( - NfcMagicWorkerEventNoCardDetected, nfc_magic_worker->context); - card_found_notified = false; - } - } - } - - magic_deactivate(); - furi_delay_ms(300); - } - - magic_deactivate(); -} - -void nfc_magic_worker_rekey(NfcMagicWorker* nfc_magic_worker) { - NfcMagicDevice* magic_dev = nfc_magic_worker->magic_dev; - bool card_found_notified = false; - - if(magic_dev->type != MagicTypeGen4) { - nfc_magic_worker->callback(NfcMagicWorkerEventCardDetected, nfc_magic_worker->context); - return; - } - - while(nfc_magic_worker->state == NfcMagicWorkerStateRekey) { - magic_activate(); - uint32_t cuid; - furi_hal_nfc_activate_nfca(200, &cuid); - if(cuid != magic_dev->cuid) { - if(card_found_notified) { - nfc_magic_worker->callback( - NfcMagicWorkerEventNoCardDetected, nfc_magic_worker->context); - card_found_notified = false; - } - continue; - } - - nfc_magic_worker->callback(NfcMagicWorkerEventCardDetected, nfc_magic_worker->context); - card_found_notified = true; - - if(magic_gen4_set_pwd(magic_dev->password, nfc_magic_worker->new_password)) { - magic_dev->password = nfc_magic_worker->new_password; - nfc_magic_worker->callback(NfcMagicWorkerEventSuccess, nfc_magic_worker->context); - break; - } - - if(card_found_notified) { //-V547 - nfc_magic_worker->callback( - NfcMagicWorkerEventNoCardDetected, nfc_magic_worker->context); - card_found_notified = false; - } - furi_delay_ms(300); - } - magic_deactivate(); -} - -void nfc_magic_worker_wipe(NfcMagicWorker* nfc_magic_worker) { - NfcMagicDevice* magic_dev = nfc_magic_worker->magic_dev; - bool card_found_notified = false; - bool card_wiped = false; - - MfClassicBlock block; - memset(&block, 0, sizeof(MfClassicBlock)); - MfClassicBlock empty_block; - memset(&empty_block, 0, sizeof(MfClassicBlock)); - MfClassicBlock trailer_block; - memset(&trailer_block, 0xff, sizeof(MfClassicBlock)); - - block.value[0] = 0x01; - block.value[1] = 0x02; - block.value[2] = 0x03; - block.value[3] = 0x04; - block.value[4] = 0x04; - block.value[5] = 0x08; - block.value[6] = 0x04; - - trailer_block.value[7] = 0x07; - trailer_block.value[8] = 0x80; - trailer_block.value[9] = 0x69; - - while(nfc_magic_worker->state == NfcMagicWorkerStateWipe) { - do { - magic_deactivate(); - furi_delay_ms(300); - if(!magic_activate()) break; - if(magic_dev->type == MagicTypeClassicGen1) { - if(!magic_gen1_wupa()) break; - if(!card_found_notified) { - nfc_magic_worker->callback( - NfcMagicWorkerEventCardDetected, nfc_magic_worker->context); - card_found_notified = true; - } - - if(!magic_gen1_data_access_cmd()) break; - if(!magic_gen1_write_blk(0, &block)) break; - - for(size_t i = 1; i < 64; i++) { - FURI_LOG_D(TAG, "Wiping block %d", i); - bool success = false; - if((i | 0x03) == i) { - success = magic_gen1_write_blk(i, &trailer_block); - } else { - success = magic_gen1_write_blk(i, &empty_block); - } - - if(!success) { - FURI_LOG_E(TAG, "Failed to write %d block", i); - nfc_magic_worker->callback( - NfcMagicWorkerEventFail, nfc_magic_worker->context); - break; - } - } - - card_wiped = true; - nfc_magic_worker->callback(NfcMagicWorkerEventSuccess, nfc_magic_worker->context); - } else if(magic_dev->type == MagicTypeGen4) { - uint32_t cuid; - if(!furi_hal_nfc_activate_nfca(200, &cuid)) break; - if(cuid != magic_dev->cuid) break; - if(!card_found_notified) { - nfc_magic_worker->callback( - NfcMagicWorkerEventCardDetected, nfc_magic_worker->context); - card_found_notified = true; - } - - if(!magic_gen4_wipe(magic_dev->password)) break; - - card_wiped = true; - nfc_magic_worker->callback(NfcMagicWorkerEventSuccess, nfc_magic_worker->context); - } - } while(false); - - if(card_wiped) break; - - if(card_found_notified) { - nfc_magic_worker->callback( - NfcMagicWorkerEventNoCardDetected, nfc_magic_worker->context); - card_found_notified = false; - } - } - magic_deactivate(); -} diff --git a/applications/external/nfc_magic/nfc_magic_worker.h b/applications/external/nfc_magic/nfc_magic_worker.h deleted file mode 100644 index 51ff4ee43..000000000 --- a/applications/external/nfc_magic/nfc_magic_worker.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include -#include "nfc_magic.h" - -typedef struct NfcMagicWorker NfcMagicWorker; - -typedef enum { - NfcMagicWorkerStateReady, - - NfcMagicWorkerStateCheck, - NfcMagicWorkerStateWrite, - NfcMagicWorkerStateRekey, - NfcMagicWorkerStateWipe, - - NfcMagicWorkerStateStop, -} NfcMagicWorkerState; - -typedef enum { - NfcMagicWorkerEventSuccess, - NfcMagicWorkerEventFail, - NfcMagicWorkerEventCardDetected, - NfcMagicWorkerEventNoCardDetected, - NfcMagicWorkerEventWrongCard, -} NfcMagicWorkerEvent; - -typedef bool (*NfcMagicWorkerCallback)(NfcMagicWorkerEvent event, void* context); - -NfcMagicWorker* nfc_magic_worker_alloc(); - -void nfc_magic_worker_free(NfcMagicWorker* nfc_magic_worker); - -void nfc_magic_worker_stop(NfcMagicWorker* nfc_magic_worker); - -void nfc_magic_worker_start( - NfcMagicWorker* nfc_magic_worker, - NfcMagicWorkerState state, - NfcMagicDevice* magic_dev, - NfcDeviceData* dev_data, - uint32_t new_password, - NfcMagicWorkerCallback callback, - void* context); diff --git a/applications/external/nfc_magic/nfc_magic_worker_i.h b/applications/external/nfc_magic/nfc_magic_worker_i.h deleted file mode 100644 index a354f8047..000000000 --- a/applications/external/nfc_magic/nfc_magic_worker_i.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -#include "nfc_magic_worker.h" -#include "lib/magic/common.h" - -struct NfcMagicWorker { - FuriThread* thread; - - NfcMagicDevice* magic_dev; - NfcDeviceData* dev_data; - uint32_t new_password; - - NfcMagicWorkerCallback callback; - void* context; - - NfcMagicWorkerState state; -}; - -int32_t nfc_magic_worker_task(void* context); - -void nfc_magic_worker_check(NfcMagicWorker* nfc_magic_worker); - -void nfc_magic_worker_write(NfcMagicWorker* nfc_magic_worker); - -void nfc_magic_worker_rekey(NfcMagicWorker* nfc_magic_worker); - -void nfc_magic_worker_wipe(NfcMagicWorker* nfc_magic_worker); diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene.c b/applications/external/nfc_magic/scenes/nfc_magic_scene.c deleted file mode 100644 index 520ef2a9d..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "nfc_magic_scene.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const nfc_magic_on_enter_handlers[])(void*) = { -#include "nfc_magic_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 nfc_magic_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "nfc_magic_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 nfc_magic_on_exit_handlers[])(void* context) = { -#include "nfc_magic_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers nfc_magic_scene_handlers = { - .on_enter_handlers = nfc_magic_on_enter_handlers, - .on_event_handlers = nfc_magic_on_event_handlers, - .on_exit_handlers = nfc_magic_on_exit_handlers, - .scene_num = NfcMagicSceneNum, -}; diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene.h b/applications/external/nfc_magic/scenes/nfc_magic_scene.h deleted file mode 100644 index f1e9f715d..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) NfcMagicScene##id, -typedef enum { -#include "nfc_magic_scene_config.h" - NfcMagicSceneNum, -} NfcMagicScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers nfc_magic_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "nfc_magic_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 "nfc_magic_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 "nfc_magic_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_actions.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_actions.c deleted file mode 100644 index 675262a9b..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_actions.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "../nfc_magic_i.h" -enum SubmenuIndex { - SubmenuIndexWrite, - SubmenuIndexWipe, -}; - -void nfc_magic_scene_actions_submenu_callback(void* context, uint32_t index) { - NfcMagic* nfc_magic = context; - view_dispatcher_send_custom_event(nfc_magic->view_dispatcher, index); -} - -void nfc_magic_scene_actions_on_enter(void* context) { - NfcMagic* nfc_magic = context; - - Submenu* submenu = nfc_magic->submenu; - submenu_add_item( - submenu, "Write", SubmenuIndexWrite, nfc_magic_scene_actions_submenu_callback, nfc_magic); - submenu_add_item( - submenu, "Wipe", SubmenuIndexWipe, nfc_magic_scene_actions_submenu_callback, nfc_magic); - - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(nfc_magic->scene_manager, NfcMagicSceneActions)); - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewMenu); -} - -bool nfc_magic_scene_actions_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexWrite) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneFileSelect); - consumed = true; - } else if(event.event == SubmenuIndexWipe) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneWipe); - consumed = true; - } - scene_manager_set_scene_state(nfc_magic->scene_manager, NfcMagicSceneActions, event.event); - } else if(event.type == SceneManagerEventTypeBack) { - consumed = scene_manager_search_and_switch_to_previous_scene( - nfc_magic->scene_manager, NfcMagicSceneStart); - } - - return consumed; -} - -void nfc_magic_scene_actions_on_exit(void* context) { - NfcMagic* nfc_magic = context; - submenu_reset(nfc_magic->submenu); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_check.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_check.c deleted file mode 100644 index 90b43d7d3..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_check.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "../nfc_magic_i.h" - -enum { - NfcMagicSceneCheckStateCardSearch, - NfcMagicSceneCheckStateCardFound, -}; - -bool nfc_magic_check_worker_callback(NfcMagicWorkerEvent event, void* context) { - furi_assert(context); - - NfcMagic* nfc_magic = context; - view_dispatcher_send_custom_event(nfc_magic->view_dispatcher, event); - - return true; -} - -static void nfc_magic_scene_check_setup_view(NfcMagic* nfc_magic) { - Popup* popup = nfc_magic->popup; - popup_reset(popup); - uint32_t state = scene_manager_get_scene_state(nfc_magic->scene_manager, NfcMagicSceneCheck); - - if(state == NfcMagicSceneCheckStateCardSearch) { - popup_set_icon(nfc_magic->popup, 0, 8, &I_NFC_manual_60x50); - popup_set_text( - nfc_magic->popup, "Apply card to\nthe back", 128, 32, AlignRight, AlignCenter); - } else { - popup_set_icon(popup, 12, 23, &I_Loading_24); - popup_set_header(popup, "Checking\nDon't move...", 52, 32, AlignLeft, AlignCenter); - } - - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewPopup); -} - -void nfc_magic_scene_check_on_enter(void* context) { - NfcMagic* nfc_magic = context; - - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneCheck, NfcMagicSceneCheckStateCardSearch); - nfc_magic_scene_check_setup_view(nfc_magic); - - // Setup and start worker - nfc_magic_worker_start( - nfc_magic->worker, - NfcMagicWorkerStateCheck, - nfc_magic->dev, - &nfc_magic->source_dev->dev_data, - nfc_magic->new_password, - nfc_magic_check_worker_callback, - nfc_magic); - nfc_magic_blink_start(nfc_magic); -} - -bool nfc_magic_scene_check_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == NfcMagicWorkerEventSuccess) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneMagicInfo); - consumed = true; - } else if(event.event == NfcMagicWorkerEventWrongCard) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneNotMagic); - consumed = true; - } else if(event.event == NfcMagicWorkerEventCardDetected) { - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneCheck, NfcMagicSceneCheckStateCardFound); - nfc_magic_scene_check_setup_view(nfc_magic); - consumed = true; - } else if(event.event == NfcMagicWorkerEventNoCardDetected) { - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneCheck, NfcMagicSceneCheckStateCardSearch); - nfc_magic_scene_check_setup_view(nfc_magic); - consumed = true; - } - } - return consumed; -} - -void nfc_magic_scene_check_on_exit(void* context) { - NfcMagic* nfc_magic = context; - - nfc_magic_worker_stop(nfc_magic->worker); - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneCheck, NfcMagicSceneCheckStateCardSearch); - // Clear view - popup_reset(nfc_magic->popup); - - nfc_magic_blink_stop(nfc_magic); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_config.h b/applications/external/nfc_magic/scenes/nfc_magic_scene_config.h deleted file mode 100644 index 2f9860d96..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_config.h +++ /dev/null @@ -1,18 +0,0 @@ -ADD_SCENE(nfc_magic, start, Start) -ADD_SCENE(nfc_magic, key_input, KeyInput) -ADD_SCENE(nfc_magic, actions, Actions) -ADD_SCENE(nfc_magic, gen4_actions, Gen4Actions) -ADD_SCENE(nfc_magic, new_key_input, NewKeyInput) -ADD_SCENE(nfc_magic, file_select, FileSelect) -ADD_SCENE(nfc_magic, write_confirm, WriteConfirm) -ADD_SCENE(nfc_magic, wrong_card, WrongCard) -ADD_SCENE(nfc_magic, write, Write) -ADD_SCENE(nfc_magic, write_fail, WriteFail) -ADD_SCENE(nfc_magic, success, Success) -ADD_SCENE(nfc_magic, check, Check) -ADD_SCENE(nfc_magic, not_magic, NotMagic) -ADD_SCENE(nfc_magic, magic_info, MagicInfo) -ADD_SCENE(nfc_magic, rekey, Rekey) -ADD_SCENE(nfc_magic, rekey_fail, RekeyFail) -ADD_SCENE(nfc_magic, wipe, Wipe) -ADD_SCENE(nfc_magic, wipe_fail, WipeFail) diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_file_select.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_file_select.c deleted file mode 100644 index 04b7024ff..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_file_select.c +++ /dev/null @@ -1,76 +0,0 @@ -#include "../nfc_magic_i.h" - -static bool nfc_magic_scene_file_select_is_file_suitable(NfcMagic* nfc_magic) { - NfcDevice* nfc_dev = nfc_magic->source_dev; - if(nfc_dev->format == NfcDeviceSaveFormatMifareClassic) { - switch(nfc_magic->dev->type) { - case MagicTypeClassicGen1: - case MagicTypeClassicDirectWrite: - case MagicTypeClassicAPDU: - if((nfc_dev->dev_data.mf_classic_data.type != MfClassicType1k) || - (nfc_dev->dev_data.nfc_data.uid_len != nfc_magic->dev->uid_len)) { - return false; - } - return true; - - case MagicTypeGen4: - return true; - default: - return false; - } - } else if( - (nfc_dev->format == NfcDeviceSaveFormatMifareUl) && - (nfc_dev->dev_data.nfc_data.uid_len == 7)) { - switch(nfc_magic->dev->type) { - case MagicTypeUltralightGen1: - case MagicTypeUltralightDirectWrite: - case MagicTypeUltralightC_Gen1: - case MagicTypeUltralightC_DirectWrite: - case MagicTypeGen4: - switch(nfc_dev->dev_data.mf_ul_data.type) { - case MfUltralightTypeNTAGI2C1K: - case MfUltralightTypeNTAGI2C2K: - case MfUltralightTypeNTAGI2CPlus1K: - case MfUltralightTypeNTAGI2CPlus2K: - return false; - default: - return true; - } - default: - return false; - } - } - - return false; -} - -void nfc_magic_scene_file_select_on_enter(void* context) { - NfcMagic* nfc_magic = context; - // Process file_select return - nfc_device_set_loading_callback( - nfc_magic->source_dev, nfc_magic_show_loading_popup, nfc_magic); - - if(!furi_string_size(nfc_magic->source_dev->load_path)) { - furi_string_set_str(nfc_magic->source_dev->load_path, NFC_APP_FOLDER); - } - if(nfc_file_select(nfc_magic->source_dev)) { - if(nfc_magic_scene_file_select_is_file_suitable(nfc_magic)) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneWriteConfirm); - } else { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneWrongCard); - } - } else { - scene_manager_previous_scene(nfc_magic->scene_manager); - } -} - -bool nfc_magic_scene_file_select_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void nfc_magic_scene_file_select_on_exit(void* context) { - NfcMagic* nfc_magic = context; - nfc_device_set_loading_callback(nfc_magic->source_dev, NULL, nfc_magic); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_gen4_actions.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_gen4_actions.c deleted file mode 100644 index ceaa33e29..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_gen4_actions.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "../nfc_magic_i.h" -enum SubmenuIndex { - SubmenuIndexWrite, - SubmenuIndexChangePassword, - SubmenuIndexWipe, -}; - -void nfc_magic_scene_gen4_actions_submenu_callback(void* context, uint32_t index) { - NfcMagic* nfc_magic = context; - view_dispatcher_send_custom_event(nfc_magic->view_dispatcher, index); -} - -void nfc_magic_scene_gen4_actions_on_enter(void* context) { - NfcMagic* nfc_magic = context; - - Submenu* submenu = nfc_magic->submenu; - submenu_add_item( - submenu, - "Write", - SubmenuIndexWrite, - nfc_magic_scene_gen4_actions_submenu_callback, - nfc_magic); - submenu_add_item( - submenu, - "Change password", - SubmenuIndexChangePassword, - nfc_magic_scene_gen4_actions_submenu_callback, - nfc_magic); - submenu_add_item( - submenu, - "Wipe", - SubmenuIndexWipe, - nfc_magic_scene_gen4_actions_submenu_callback, - nfc_magic); - - submenu_set_selected_item( - submenu, - scene_manager_get_scene_state(nfc_magic->scene_manager, NfcMagicSceneGen4Actions)); - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewMenu); -} - -bool nfc_magic_scene_gen4_actions_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexWrite) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneFileSelect); - consumed = true; - } else if(event.event == SubmenuIndexChangePassword) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneNewKeyInput); - consumed = true; - } else if(event.event == SubmenuIndexWipe) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneWipe); - consumed = true; - } - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneGen4Actions, event.event); - } else if(event.type == SceneManagerEventTypeBack) { - consumed = scene_manager_search_and_switch_to_previous_scene( - nfc_magic->scene_manager, NfcMagicSceneStart); - } - - return consumed; -} - -void nfc_magic_scene_gen4_actions_on_exit(void* context) { - NfcMagic* nfc_magic = context; - submenu_reset(nfc_magic->submenu); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_key_input.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_key_input.c deleted file mode 100644 index 58b487a09..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_key_input.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "../nfc_magic_i.h" - -void nfc_magic_scene_key_input_byte_input_callback(void* context) { - NfcMagic* nfc_magic = context; - - view_dispatcher_send_custom_event( - nfc_magic->view_dispatcher, NfcMagicCustomEventByteInputDone); -} - -void nfc_magic_scene_key_input_on_enter(void* context) { - NfcMagic* nfc_magic = context; - - // Setup view - ByteInput* byte_input = nfc_magic->byte_input; - byte_input_set_header_text(byte_input, "Enter the password in hex"); - byte_input_set_result_callback( - byte_input, - nfc_magic_scene_key_input_byte_input_callback, - NULL, - nfc_magic, - (uint8_t*)&nfc_magic->dev->password, - 4); - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewByteInput); -} - -bool nfc_magic_scene_key_input_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == NfcMagicCustomEventByteInputDone) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneCheck); - consumed = true; - } - } - return consumed; -} - -void nfc_magic_scene_key_input_on_exit(void* context) { - NfcMagic* nfc_magic = context; - - // Clear view - byte_input_set_result_callback(nfc_magic->byte_input, NULL, NULL, NULL, NULL, 0); - byte_input_set_header_text(nfc_magic->byte_input, ""); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_magic_info.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_magic_info.c deleted file mode 100644 index c147ac438..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_magic_info.c +++ /dev/null @@ -1,59 +0,0 @@ -#include "../nfc_magic_i.h" -#include "../lib/magic/types.h" - -void nfc_magic_scene_magic_info_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - NfcMagic* nfc_magic = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(nfc_magic->view_dispatcher, result); - } -} - -void nfc_magic_scene_magic_info_on_enter(void* context) { - NfcMagic* nfc_magic = context; - Widget* widget = nfc_magic->widget; - const char* card_type = nfc_magic_type(nfc_magic->dev->type); - - notification_message(nfc_magic->notifications, &sequence_success); - - widget_add_icon_element(widget, 73, 17, &I_DolphinCommon_56x48); - widget_add_string_element( - widget, 3, 4, AlignLeft, AlignTop, FontPrimary, "Magic card detected"); - widget_add_string_element(widget, 3, 17, AlignLeft, AlignTop, FontSecondary, card_type); - widget_add_button_element( - widget, GuiButtonTypeLeft, "Retry", nfc_magic_scene_magic_info_widget_callback, nfc_magic); - widget_add_button_element( - widget, GuiButtonTypeRight, "More", nfc_magic_scene_magic_info_widget_callback, nfc_magic); - - // Setup and start worker - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewWidget); -} - -bool nfc_magic_scene_magic_info_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeLeft) { - consumed = scene_manager_previous_scene(nfc_magic->scene_manager); - } else if(event.event == GuiButtonTypeRight) { - MagicType type = nfc_magic->dev->type; - if(type == MagicTypeGen4) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneGen4Actions); - consumed = true; - } else { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneActions); - consumed = true; - } - } - } - return consumed; -} - -void nfc_magic_scene_magic_info_on_exit(void* context) { - NfcMagic* nfc_magic = context; - - widget_reset(nfc_magic->widget); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_new_key_input.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_new_key_input.c deleted file mode 100644 index b5247f6c5..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_new_key_input.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "../nfc_magic_i.h" - -void nfc_magic_scene_new_key_input_byte_input_callback(void* context) { - NfcMagic* nfc_magic = context; - - view_dispatcher_send_custom_event( - nfc_magic->view_dispatcher, NfcMagicCustomEventByteInputDone); -} - -void nfc_magic_scene_new_key_input_on_enter(void* context) { - NfcMagic* nfc_magic = context; - - // Setup view - ByteInput* byte_input = nfc_magic->byte_input; - byte_input_set_header_text(byte_input, "Enter the password in hex"); - byte_input_set_result_callback( - byte_input, - nfc_magic_scene_new_key_input_byte_input_callback, - NULL, - nfc_magic, - (uint8_t*)&nfc_magic->new_password, - 4); - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewByteInput); -} - -bool nfc_magic_scene_new_key_input_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == NfcMagicCustomEventByteInputDone) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneRekey); - consumed = true; - } - } - return consumed; -} - -void nfc_magic_scene_new_key_input_on_exit(void* context) { - NfcMagic* nfc_magic = context; - - // Clear view - byte_input_set_result_callback(nfc_magic->byte_input, NULL, NULL, NULL, NULL, 0); - byte_input_set_header_text(nfc_magic->byte_input, ""); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_not_magic.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_not_magic.c deleted file mode 100644 index b4f579f44..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_not_magic.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "../nfc_magic_i.h" - -void nfc_magic_scene_not_magic_widget_callback(GuiButtonType result, InputType type, void* context) { - NfcMagic* nfc_magic = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(nfc_magic->view_dispatcher, result); - } -} - -void nfc_magic_scene_not_magic_on_enter(void* context) { - NfcMagic* nfc_magic = context; - Widget* widget = nfc_magic->widget; - - notification_message(nfc_magic->notifications, &sequence_error); - - widget_add_string_element( - widget, 3, 4, AlignLeft, AlignTop, FontPrimary, "This is wrong card"); - widget_add_string_multiline_element( - widget, 4, 17, AlignLeft, AlignTop, FontSecondary, "Not magic or unsupported\ncard"); - widget_add_button_element( - widget, GuiButtonTypeLeft, "Retry", nfc_magic_scene_not_magic_widget_callback, nfc_magic); - - // Setup and start worker - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewWidget); -} - -bool nfc_magic_scene_not_magic_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeLeft) { - consumed = scene_manager_previous_scene(nfc_magic->scene_manager); - } - } - return consumed; -} - -void nfc_magic_scene_not_magic_on_exit(void* context) { - NfcMagic* nfc_magic = context; - - widget_reset(nfc_magic->widget); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_rekey.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_rekey.c deleted file mode 100644 index 259dc78ea..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_rekey.c +++ /dev/null @@ -1,95 +0,0 @@ -#include "../nfc_magic_i.h" - -enum { - NfcMagicSceneRekeyStateCardSearch, - NfcMagicSceneRekeyStateCardFound, -}; - -bool nfc_magic_rekey_worker_callback(NfcMagicWorkerEvent event, void* context) { - furi_assert(context); - - NfcMagic* nfc_magic = context; - view_dispatcher_send_custom_event(nfc_magic->view_dispatcher, event); - - return true; -} - -static void nfc_magic_scene_rekey_setup_view(NfcMagic* nfc_magic) { - Popup* popup = nfc_magic->popup; - popup_reset(popup); - uint32_t state = scene_manager_get_scene_state(nfc_magic->scene_manager, NfcMagicSceneRekey); - - if(state == NfcMagicSceneRekeyStateCardSearch) { - popup_set_text( - nfc_magic->popup, - "Apply the\nsame card\nto the back", - 128, - 32, - AlignRight, - AlignCenter); - popup_set_icon(nfc_magic->popup, 0, 8, &I_NFC_manual_60x50); - } else { - popup_set_icon(popup, 12, 23, &I_Loading_24); - popup_set_header(popup, "Writing\nDon't move...", 52, 32, AlignLeft, AlignCenter); - } - - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewPopup); -} - -void nfc_magic_scene_rekey_on_enter(void* context) { - NfcMagic* nfc_magic = context; - - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneRekey, NfcMagicSceneRekeyStateCardSearch); - nfc_magic_scene_rekey_setup_view(nfc_magic); - - // Setup and start worker - nfc_magic_worker_start( - nfc_magic->worker, - NfcMagicWorkerStateRekey, - nfc_magic->dev, - &nfc_magic->source_dev->dev_data, - nfc_magic->new_password, - nfc_magic_rekey_worker_callback, - nfc_magic); - nfc_magic_blink_start(nfc_magic); -} - -bool nfc_magic_scene_rekey_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == NfcMagicWorkerEventSuccess) { - nfc_magic->dev->password = nfc_magic->new_password; - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneSuccess); - consumed = true; - } else if(event.event == NfcMagicWorkerEventFail) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneRekeyFail); - consumed = true; - } else if(event.event == NfcMagicWorkerEventCardDetected) { - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneRekey, NfcMagicSceneRekeyStateCardFound); - nfc_magic_scene_rekey_setup_view(nfc_magic); - consumed = true; - } else if(event.event == NfcMagicWorkerEventNoCardDetected) { - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneRekey, NfcMagicSceneRekeyStateCardSearch); - nfc_magic_scene_rekey_setup_view(nfc_magic); - consumed = true; - } - } - return consumed; -} - -void nfc_magic_scene_rekey_on_exit(void* context) { - NfcMagic* nfc_magic = context; - - nfc_magic_worker_stop(nfc_magic->worker); - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneRekey, NfcMagicSceneRekeyStateCardSearch); - // Clear view - popup_reset(nfc_magic->popup); - - nfc_magic_blink_stop(nfc_magic); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_rekey_fail.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_rekey_fail.c deleted file mode 100644 index d30ee57bc..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_rekey_fail.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "../nfc_magic_i.h" - -void nfc_magic_scene_rekey_fail_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - NfcMagic* nfc_magic = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(nfc_magic->view_dispatcher, result); - } -} - -void nfc_magic_scene_rekey_fail_on_enter(void* context) { - NfcMagic* nfc_magic = context; - Widget* widget = nfc_magic->widget; - - notification_message(nfc_magic->notifications, &sequence_error); - - widget_add_icon_element(widget, 72, 17, &I_DolphinCommon_56x48); - widget_add_string_element( - widget, 7, 4, AlignLeft, AlignTop, FontPrimary, "Can't change password!"); - - widget_add_button_element( - widget, GuiButtonTypeLeft, "Finish", nfc_magic_scene_rekey_fail_widget_callback, nfc_magic); - - // Setup and start worker - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewWidget); -} - -bool nfc_magic_scene_rekey_fail_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeLeft) { - consumed = scene_manager_search_and_switch_to_previous_scene( - nfc_magic->scene_manager, NfcMagicSceneStart); - } - } else if(event.type == SceneManagerEventTypeBack) { - consumed = scene_manager_search_and_switch_to_previous_scene( - nfc_magic->scene_manager, NfcMagicSceneStart); - } - return consumed; -} - -void nfc_magic_scene_rekey_fail_on_exit(void* context) { - NfcMagic* nfc_magic = context; - - widget_reset(nfc_magic->widget); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_start.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_start.c deleted file mode 100644 index b5861629e..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_start.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "../nfc_magic_i.h" -enum SubmenuIndex { - SubmenuIndexCheck, - SubmenuIndexAuthenticateGen4, -}; - -void nfc_magic_scene_start_submenu_callback(void* context, uint32_t index) { - NfcMagic* nfc_magic = context; - view_dispatcher_send_custom_event(nfc_magic->view_dispatcher, index); -} - -void nfc_magic_scene_start_on_enter(void* context) { - NfcMagic* nfc_magic = context; - - Submenu* submenu = nfc_magic->submenu; - submenu_add_item( - submenu, - "Check Magic Tag", - SubmenuIndexCheck, - nfc_magic_scene_start_submenu_callback, - nfc_magic); - submenu_add_item( - submenu, - "Authenticate Gen4", - SubmenuIndexAuthenticateGen4, - nfc_magic_scene_start_submenu_callback, - nfc_magic); - - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(nfc_magic->scene_manager, NfcMagicSceneStart)); - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewMenu); -} - -bool nfc_magic_scene_start_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexCheck) { - nfc_magic->dev->password = MAGIC_GEN4_DEFAULT_PWD; - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneStart, SubmenuIndexCheck); - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneCheck); - consumed = true; - } else if(event.event == SubmenuIndexAuthenticateGen4) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneKeyInput); - } - } - - return consumed; -} - -void nfc_magic_scene_start_on_exit(void* context) { - NfcMagic* nfc_magic = context; - submenu_reset(nfc_magic->submenu); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_success.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_success.c deleted file mode 100644 index 37441e80e..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_success.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "../nfc_magic_i.h" - -void nfc_magic_scene_success_popup_callback(void* context) { - NfcMagic* nfc_magic = context; - view_dispatcher_send_custom_event(nfc_magic->view_dispatcher, NfcMagicCustomEventViewExit); -} - -void nfc_magic_scene_success_on_enter(void* context) { - NfcMagic* nfc_magic = context; - - notification_message(nfc_magic->notifications, &sequence_success); - - Popup* popup = nfc_magic->popup; - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - popup_set_header(popup, "Success!", 10, 20, AlignLeft, AlignBottom); - popup_set_timeout(popup, 1500); - popup_set_context(popup, nfc_magic); - popup_set_callback(popup, nfc_magic_scene_success_popup_callback); - popup_enable_timeout(popup); - - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewPopup); -} - -bool nfc_magic_scene_success_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == NfcMagicCustomEventViewExit) { - consumed = scene_manager_search_and_switch_to_previous_scene( - nfc_magic->scene_manager, NfcMagicSceneStart); - } - } - return consumed; -} - -void nfc_magic_scene_success_on_exit(void* context) { - NfcMagic* nfc_magic = context; - - // Clear view - popup_reset(nfc_magic->popup); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_wipe.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_wipe.c deleted file mode 100644 index 29640f89c..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_wipe.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "../nfc_magic_i.h" - -enum { - NfcMagicSceneWipeStateCardSearch, - NfcMagicSceneWipeStateCardFound, -}; - -bool nfc_magic_wipe_worker_callback(NfcMagicWorkerEvent event, void* context) { - furi_assert(context); - - NfcMagic* nfc_magic = context; - view_dispatcher_send_custom_event(nfc_magic->view_dispatcher, event); - - return true; -} - -static void nfc_magic_scene_wipe_setup_view(NfcMagic* nfc_magic) { - Popup* popup = nfc_magic->popup; - popup_reset(popup); - uint32_t state = scene_manager_get_scene_state(nfc_magic->scene_manager, NfcMagicSceneWipe); - - if(state == NfcMagicSceneWipeStateCardSearch) { - popup_set_icon(nfc_magic->popup, 0, 8, &I_NFC_manual_60x50); - popup_set_text( - nfc_magic->popup, - "Apply the\nsame card\nto the back", - 128, - 32, - AlignRight, - AlignCenter); - } else { - popup_set_icon(popup, 12, 23, &I_Loading_24); - popup_set_header(popup, "Wiping\nDon't move...", 52, 32, AlignLeft, AlignCenter); - } - - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewPopup); -} - -void nfc_magic_scene_wipe_on_enter(void* context) { - NfcMagic* nfc_magic = context; - - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneWipe, NfcMagicSceneWipeStateCardSearch); - nfc_magic_scene_wipe_setup_view(nfc_magic); - - // Setup and start worker - nfc_magic_worker_start( - nfc_magic->worker, - NfcMagicWorkerStateWipe, - nfc_magic->dev, - &nfc_magic->source_dev->dev_data, - nfc_magic->new_password, - nfc_magic_wipe_worker_callback, - nfc_magic); - nfc_magic_blink_start(nfc_magic); -} - -bool nfc_magic_scene_wipe_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == NfcMagicWorkerEventSuccess) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneSuccess); - consumed = true; - } else if(event.event == NfcMagicWorkerEventFail) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneWipeFail); - consumed = true; - } else if(event.event == NfcMagicWorkerEventWrongCard) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneNotMagic); - consumed = true; - } else if(event.event == NfcMagicWorkerEventCardDetected) { - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneWipe, NfcMagicSceneWipeStateCardFound); - nfc_magic_scene_wipe_setup_view(nfc_magic); - consumed = true; - } else if(event.event == NfcMagicWorkerEventNoCardDetected) { - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneWipe, NfcMagicSceneWipeStateCardSearch); - nfc_magic_scene_wipe_setup_view(nfc_magic); - consumed = true; - } - } - return consumed; -} - -void nfc_magic_scene_wipe_on_exit(void* context) { - NfcMagic* nfc_magic = context; - - nfc_magic_worker_stop(nfc_magic->worker); - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneWipe, NfcMagicSceneWipeStateCardSearch); - // Clear view - popup_reset(nfc_magic->popup); - - nfc_magic_blink_stop(nfc_magic); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_wipe_fail.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_wipe_fail.c deleted file mode 100644 index 828b65e6c..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_wipe_fail.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "../nfc_magic_i.h" - -void nfc_magic_scene_wipe_fail_widget_callback(GuiButtonType result, InputType type, void* context) { - NfcMagic* nfc_magic = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(nfc_magic->view_dispatcher, result); - } -} - -void nfc_magic_scene_wipe_fail_on_enter(void* context) { - NfcMagic* nfc_magic = context; - Widget* widget = nfc_magic->widget; - - notification_message(nfc_magic->notifications, &sequence_error); - - widget_add_icon_element(widget, 73, 17, &I_DolphinCommon_56x48); - widget_add_string_element(widget, 3, 4, AlignLeft, AlignTop, FontPrimary, "Wipe failed"); - widget_add_button_element( - widget, GuiButtonTypeLeft, "Retry", nfc_magic_scene_wipe_fail_widget_callback, nfc_magic); - - // Setup and start worker - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewWidget); -} - -bool nfc_magic_scene_wipe_fail_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeLeft) { - consumed = scene_manager_previous_scene(nfc_magic->scene_manager); - } - } - return consumed; -} - -void nfc_magic_scene_wipe_fail_on_exit(void* context) { - NfcMagic* nfc_magic = context; - - widget_reset(nfc_magic->widget); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_write.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_write.c deleted file mode 100644 index 45c54557f..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_write.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "../nfc_magic_i.h" - -enum { - NfcMagicSceneWriteStateCardSearch, - NfcMagicSceneWriteStateCardFound, -}; - -bool nfc_magic_write_worker_callback(NfcMagicWorkerEvent event, void* context) { - furi_assert(context); - - NfcMagic* nfc_magic = context; - view_dispatcher_send_custom_event(nfc_magic->view_dispatcher, event); - - return true; -} - -static void nfc_magic_scene_write_setup_view(NfcMagic* nfc_magic) { - Popup* popup = nfc_magic->popup; - popup_reset(popup); - uint32_t state = scene_manager_get_scene_state(nfc_magic->scene_manager, NfcMagicSceneWrite); - - if(state == NfcMagicSceneWriteStateCardSearch) { - popup_set_text( - nfc_magic->popup, - "Apply the\nsame card\nto the back", - 128, - 32, - AlignRight, - AlignCenter); - popup_set_icon(nfc_magic->popup, 0, 8, &I_NFC_manual_60x50); - } else { - popup_set_icon(popup, 12, 23, &I_Loading_24); - popup_set_header(popup, "Writing\nDon't move...", 52, 32, AlignLeft, AlignCenter); - } - - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewPopup); -} - -void nfc_magic_scene_write_on_enter(void* context) { - NfcMagic* nfc_magic = context; - - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneWrite, NfcMagicSceneWriteStateCardSearch); - nfc_magic_scene_write_setup_view(nfc_magic); - - // Setup and start worker - nfc_magic_worker_start( - nfc_magic->worker, - NfcMagicWorkerStateWrite, - nfc_magic->dev, - &nfc_magic->source_dev->dev_data, - nfc_magic->new_password, - nfc_magic_write_worker_callback, - nfc_magic); - nfc_magic_blink_start(nfc_magic); -} - -bool nfc_magic_scene_write_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == NfcMagicWorkerEventSuccess) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneSuccess); - consumed = true; - } else if(event.event == NfcMagicWorkerEventFail) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneWriteFail); - consumed = true; - } else if(event.event == NfcMagicWorkerEventWrongCard) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneNotMagic); - consumed = true; - } else if(event.event == NfcMagicWorkerEventCardDetected) { - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneWrite, NfcMagicSceneWriteStateCardFound); - nfc_magic_scene_write_setup_view(nfc_magic); - consumed = true; - } else if(event.event == NfcMagicWorkerEventNoCardDetected) { - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneWrite, NfcMagicSceneWriteStateCardSearch); - nfc_magic_scene_write_setup_view(nfc_magic); - consumed = true; - } - } - return consumed; -} - -void nfc_magic_scene_write_on_exit(void* context) { - NfcMagic* nfc_magic = context; - - nfc_magic_worker_stop(nfc_magic->worker); - scene_manager_set_scene_state( - nfc_magic->scene_manager, NfcMagicSceneWrite, NfcMagicSceneWriteStateCardSearch); - // Clear view - popup_reset(nfc_magic->popup); - - nfc_magic_blink_stop(nfc_magic); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_write_confirm.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_write_confirm.c deleted file mode 100644 index d31c1c194..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_write_confirm.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "../nfc_magic_i.h" - -void nfc_magic_scene_write_confirm_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - NfcMagic* nfc_magic = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(nfc_magic->view_dispatcher, result); - } -} - -void nfc_magic_scene_write_confirm_on_enter(void* context) { - NfcMagic* nfc_magic = context; - Widget* widget = nfc_magic->widget; - - widget_add_string_element(widget, 3, 0, AlignLeft, AlignTop, FontPrimary, "Risky operation"); - widget_add_text_box_element( - widget, - 0, - 13, - 128, - 54, - AlignLeft, - AlignTop, - "Writing to this card will change manufacturer block. On some cards it may not be rewritten", - false); - widget_add_button_element( - widget, - GuiButtonTypeCenter, - "Continue", - nfc_magic_scene_write_confirm_widget_callback, - nfc_magic); - widget_add_button_element( - widget, - GuiButtonTypeLeft, - "Back", - nfc_magic_scene_write_confirm_widget_callback, - nfc_magic); - - // Setup and start worker - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewWidget); -} - -bool nfc_magic_scene_write_confirm_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeLeft) { - consumed = scene_manager_previous_scene(nfc_magic->scene_manager); - } else if(event.event == GuiButtonTypeCenter) { - scene_manager_next_scene(nfc_magic->scene_manager, NfcMagicSceneWrite); - consumed = true; - } - } - return consumed; -} - -void nfc_magic_scene_write_confirm_on_exit(void* context) { - NfcMagic* nfc_magic = context; - - widget_reset(nfc_magic->widget); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_write_fail.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_write_fail.c deleted file mode 100644 index 8a465bf61..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_write_fail.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "../nfc_magic_i.h" - -void nfc_magic_scene_write_fail_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - NfcMagic* nfc_magic = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(nfc_magic->view_dispatcher, result); - } -} - -void nfc_magic_scene_write_fail_on_enter(void* context) { - NfcMagic* nfc_magic = context; - Widget* widget = nfc_magic->widget; - - notification_message(nfc_magic->notifications, &sequence_error); - - widget_add_icon_element(widget, 72, 17, &I_DolphinCommon_56x48); - widget_add_string_element( - widget, 7, 4, AlignLeft, AlignTop, FontPrimary, "Writing gone wrong!"); - widget_add_string_multiline_element( - widget, - 7, - 17, - AlignLeft, - AlignTop, - FontSecondary, - "Not all sectors\nwere written\ncorrectly."); - - widget_add_button_element( - widget, GuiButtonTypeLeft, "Finish", nfc_magic_scene_write_fail_widget_callback, nfc_magic); - - // Setup and start worker - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewWidget); -} - -bool nfc_magic_scene_write_fail_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeLeft) { - consumed = scene_manager_search_and_switch_to_previous_scene( - nfc_magic->scene_manager, NfcMagicSceneStart); - } - } else if(event.type == SceneManagerEventTypeBack) { - consumed = scene_manager_search_and_switch_to_previous_scene( - nfc_magic->scene_manager, NfcMagicSceneStart); - } - return consumed; -} - -void nfc_magic_scene_write_fail_on_exit(void* context) { - NfcMagic* nfc_magic = context; - - widget_reset(nfc_magic->widget); -} diff --git a/applications/external/nfc_magic/scenes/nfc_magic_scene_wrong_card.c b/applications/external/nfc_magic/scenes/nfc_magic_scene_wrong_card.c deleted file mode 100644 index 857d50c1f..000000000 --- a/applications/external/nfc_magic/scenes/nfc_magic_scene_wrong_card.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "../nfc_magic_i.h" - -void nfc_magic_scene_wrong_card_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - NfcMagic* nfc_magic = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(nfc_magic->view_dispatcher, result); - } -} - -void nfc_magic_scene_wrong_card_on_enter(void* context) { - NfcMagic* nfc_magic = context; - Widget* widget = nfc_magic->widget; - - notification_message(nfc_magic->notifications, &sequence_error); - - widget_add_icon_element(widget, 73, 17, &I_DolphinCommon_56x48); - widget_add_string_element( - widget, 1, 4, AlignLeft, AlignTop, FontPrimary, "This is wrong card"); - widget_add_string_multiline_element( - widget, - 1, - 17, - AlignLeft, - AlignTop, - FontSecondary, - "Writing this file is\nnot supported for\nthis magic card."); - widget_add_button_element( - widget, GuiButtonTypeLeft, "Retry", nfc_magic_scene_wrong_card_widget_callback, nfc_magic); - - // Setup and start worker - view_dispatcher_switch_to_view(nfc_magic->view_dispatcher, NfcMagicViewWidget); -} - -bool nfc_magic_scene_wrong_card_on_event(void* context, SceneManagerEvent event) { - NfcMagic* nfc_magic = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeLeft) { - consumed = scene_manager_previous_scene(nfc_magic->scene_manager); - } - } - return consumed; -} - -void nfc_magic_scene_wrong_card_on_exit(void* context) { - NfcMagic* nfc_magic = context; - - widget_reset(nfc_magic->widget); -} diff --git a/applications/external/nfc_rfid_detector/application.fam b/applications/external/nfc_rfid_detector/application.fam deleted file mode 100644 index 70c91bc84..000000000 --- a/applications/external/nfc_rfid_detector/application.fam +++ /dev/null @@ -1,13 +0,0 @@ -App( - appid="nfc_rfid_detector", - name="NFC/RFID detector", - apptype=FlipperAppType.EXTERNAL, - targets=["f7"], - entry_point="nfc_rfid_detector_app", - requires=["gui"], - stack_size=4 * 1024, - order=50, - fap_icon="nfc_rfid_detector_10px.png", - fap_category="Tools", - fap_icon_assets="images", -) diff --git a/applications/external/nfc_rfid_detector/helpers/nfc_rfid_detector_event.h b/applications/external/nfc_rfid_detector/helpers/nfc_rfid_detector_event.h deleted file mode 100644 index bbffe2938..000000000 --- a/applications/external/nfc_rfid_detector/helpers/nfc_rfid_detector_event.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -typedef enum { - //NfcRfidDetectorCustomEvent - NfcRfidDetectorCustomEventStartId = 100, - -} NfcRfidDetectorCustomEvent; diff --git a/applications/external/nfc_rfid_detector/helpers/nfc_rfid_detector_types.h b/applications/external/nfc_rfid_detector/helpers/nfc_rfid_detector_types.h deleted file mode 100644 index 5d44b09b7..000000000 --- a/applications/external/nfc_rfid_detector/helpers/nfc_rfid_detector_types.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include -#include - -#define NFC_RFID_DETECTOR_VERSION_APP "0.1" -#define NFC_RFID_DETECTOR_DEVELOPED "SkorP" -#define NFC_RFID_DETECTOR_GITHUB "https://github.com/flipperdevices/flipperzero-firmware" - -typedef enum { - NfcRfidDetectorViewVariableItemList, - NfcRfidDetectorViewSubmenu, - NfcRfidDetectorViewFieldPresence, - NfcRfidDetectorViewWidget, -} NfcRfidDetectorView; diff --git a/applications/external/nfc_rfid_detector/images/Modern_reader_18x34.png b/applications/external/nfc_rfid_detector/images/Modern_reader_18x34.png deleted file mode 100644 index b19c0f30c..000000000 Binary files a/applications/external/nfc_rfid_detector/images/Modern_reader_18x34.png and /dev/null differ diff --git a/applications/external/nfc_rfid_detector/images/Move_flipper_26x39.png b/applications/external/nfc_rfid_detector/images/Move_flipper_26x39.png deleted file mode 100644 index ff4af9ff0..000000000 Binary files a/applications/external/nfc_rfid_detector/images/Move_flipper_26x39.png and /dev/null differ diff --git a/applications/external/nfc_rfid_detector/images/NFC_detect_45x30.png b/applications/external/nfc_rfid_detector/images/NFC_detect_45x30.png deleted file mode 100644 index 9d8a6f2ab..000000000 Binary files a/applications/external/nfc_rfid_detector/images/NFC_detect_45x30.png and /dev/null differ diff --git a/applications/external/nfc_rfid_detector/images/Rfid_detect_45x30.png b/applications/external/nfc_rfid_detector/images/Rfid_detect_45x30.png deleted file mode 100644 index 35c205049..000000000 Binary files a/applications/external/nfc_rfid_detector/images/Rfid_detect_45x30.png and /dev/null differ diff --git a/applications/external/nfc_rfid_detector/nfc_rfid_detector_10px.png b/applications/external/nfc_rfid_detector/nfc_rfid_detector_10px.png deleted file mode 100644 index 7e875e028..000000000 Binary files a/applications/external/nfc_rfid_detector/nfc_rfid_detector_10px.png and /dev/null differ diff --git a/applications/external/nfc_rfid_detector/nfc_rfid_detector_app.c b/applications/external/nfc_rfid_detector/nfc_rfid_detector_app.c deleted file mode 100644 index cba8b6085..000000000 --- a/applications/external/nfc_rfid_detector/nfc_rfid_detector_app.c +++ /dev/null @@ -1,108 +0,0 @@ -#include "nfc_rfid_detector_app_i.h" - -#include -#include - -static bool nfc_rfid_detector_app_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - NfcRfidDetectorApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool nfc_rfid_detector_app_back_event_callback(void* context) { - furi_assert(context); - NfcRfidDetectorApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -static void nfc_rfid_detector_app_tick_event_callback(void* context) { - furi_assert(context); - NfcRfidDetectorApp* app = context; - scene_manager_handle_tick_event(app->scene_manager); -} - -NfcRfidDetectorApp* nfc_rfid_detector_app_alloc() { - NfcRfidDetectorApp* app = malloc(sizeof(NfcRfidDetectorApp)); - - // GUI - app->gui = furi_record_open(RECORD_GUI); - - // View Dispatcher - app->view_dispatcher = view_dispatcher_alloc(); - app->scene_manager = scene_manager_alloc(&nfc_rfid_detector_scene_handlers, app); - view_dispatcher_enable_queue(app->view_dispatcher); - - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - view_dispatcher_set_custom_event_callback( - app->view_dispatcher, nfc_rfid_detector_app_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, nfc_rfid_detector_app_back_event_callback); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, nfc_rfid_detector_app_tick_event_callback, 100); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - // Open Notification record - app->notifications = furi_record_open(RECORD_NOTIFICATION); - - // SubMenu - app->submenu = submenu_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, NfcRfidDetectorViewSubmenu, submenu_get_view(app->submenu)); - - // Widget - app->widget = widget_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, NfcRfidDetectorViewWidget, widget_get_view(app->widget)); - - // Field Presence - app->nfc_rfid_detector_field_presence = nfc_rfid_detector_view_field_presence_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - NfcRfidDetectorViewFieldPresence, - nfc_rfid_detector_view_field_presence_get_view(app->nfc_rfid_detector_field_presence)); - - scene_manager_next_scene(app->scene_manager, NfcRfidDetectorSceneStart); - - return app; -} - -void nfc_rfid_detector_app_free(NfcRfidDetectorApp* app) { - furi_assert(app); - - // Submenu - view_dispatcher_remove_view(app->view_dispatcher, NfcRfidDetectorViewSubmenu); - submenu_free(app->submenu); - - // Widget - view_dispatcher_remove_view(app->view_dispatcher, NfcRfidDetectorViewWidget); - widget_free(app->widget); - - // Field Presence - view_dispatcher_remove_view(app->view_dispatcher, NfcRfidDetectorViewFieldPresence); - nfc_rfid_detector_view_field_presence_free(app->nfc_rfid_detector_field_presence); - - // View dispatcher - view_dispatcher_free(app->view_dispatcher); - scene_manager_free(app->scene_manager); - - // Notifications - furi_record_close(RECORD_NOTIFICATION); - app->notifications = NULL; - - // Close records - furi_record_close(RECORD_GUI); - - free(app); -} - -int32_t nfc_rfid_detector_app(void* p) { - UNUSED(p); - NfcRfidDetectorApp* nfc_rfid_detector_app = nfc_rfid_detector_app_alloc(); - - view_dispatcher_run(nfc_rfid_detector_app->view_dispatcher); - - nfc_rfid_detector_app_free(nfc_rfid_detector_app); - - return 0; -} diff --git a/applications/external/nfc_rfid_detector/nfc_rfid_detector_app_i.c b/applications/external/nfc_rfid_detector/nfc_rfid_detector_app_i.c deleted file mode 100644 index c59d40d50..000000000 --- a/applications/external/nfc_rfid_detector/nfc_rfid_detector_app_i.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "nfc_rfid_detector_app_i.h" - -#include - -#define TAG "NfcRfidDetector" - -void nfc_rfid_detector_app_field_presence_start(NfcRfidDetectorApp* app) { - furi_assert(app); - - // start the field presence rfid detection - furi_hal_rfid_field_detect_start(); - - // start the field presence nfc detection - furi_hal_nfc_exit_sleep(); - furi_hal_nfc_field_detect_start(); -} - -void nfc_rfid_detector_app_field_presence_stop(NfcRfidDetectorApp* app) { - furi_assert(app); - - // stop the field presence rfid detection - furi_hal_rfid_field_detect_stop(); - - // stop the field presence nfc detection - furi_hal_nfc_start_sleep(); -} - -bool nfc_rfid_detector_app_field_presence_is_nfc(NfcRfidDetectorApp* app) { - furi_assert(app); - - // check if the field presence is nfc - return furi_hal_nfc_field_is_present(); -} - -bool nfc_rfid_detector_app_field_presence_is_rfid(NfcRfidDetectorApp* app, uint32_t* frequency) { - furi_assert(app); - - // check if the field presence is rfid - return furi_hal_rfid_field_is_present(frequency); -} \ No newline at end of file diff --git a/applications/external/nfc_rfid_detector/nfc_rfid_detector_app_i.h b/applications/external/nfc_rfid_detector/nfc_rfid_detector_app_i.h deleted file mode 100644 index 72cb126d4..000000000 --- a/applications/external/nfc_rfid_detector/nfc_rfid_detector_app_i.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "helpers/nfc_rfid_detector_types.h" -#include "helpers/nfc_rfid_detector_event.h" - -#include "scenes/nfc_rfid_detector_scene.h" -#include -#include -#include -#include -#include -#include -#include "views/nfc_rfid_detector_view_field_presence.h" - -typedef struct NfcRfidDetectorApp NfcRfidDetectorApp; - -struct NfcRfidDetectorApp { - Gui* gui; - ViewDispatcher* view_dispatcher; - SceneManager* scene_manager; - NotificationApp* notifications; - Submenu* submenu; - Widget* widget; - NfcRfidDetectorFieldPresence* nfc_rfid_detector_field_presence; -}; - -void nfc_rfid_detector_app_field_presence_start(NfcRfidDetectorApp* app); -void nfc_rfid_detector_app_field_presence_stop(NfcRfidDetectorApp* app); -bool nfc_rfid_detector_app_field_presence_is_nfc(NfcRfidDetectorApp* app); -bool nfc_rfid_detector_app_field_presence_is_rfid(NfcRfidDetectorApp* app, uint32_t* frequency); \ No newline at end of file diff --git a/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene.c b/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene.c deleted file mode 100644 index d75eb2884..000000000 --- a/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "../nfc_rfid_detector_app_i.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const nfc_rfid_detector_scene_on_enter_handlers[])(void*) = { -#include "nfc_rfid_detector_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 nfc_rfid_detector_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = - { -#include "nfc_rfid_detector_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 nfc_rfid_detector_scene_on_exit_handlers[])(void* context) = { -#include "nfc_rfid_detector_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers nfc_rfid_detector_scene_handlers = { - .on_enter_handlers = nfc_rfid_detector_scene_on_enter_handlers, - .on_event_handlers = nfc_rfid_detector_scene_on_event_handlers, - .on_exit_handlers = nfc_rfid_detector_scene_on_exit_handlers, - .scene_num = NfcRfidDetectorSceneNum, -}; diff --git a/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene.h b/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene.h deleted file mode 100644 index 74d324b4d..000000000 --- a/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) NfcRfidDetectorScene##id, -typedef enum { -#include "nfc_rfid_detector_scene_config.h" - NfcRfidDetectorSceneNum, -} NfcRfidDetectorScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers nfc_rfid_detector_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "nfc_rfid_detector_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 "nfc_rfid_detector_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 "nfc_rfid_detector_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene_about.c b/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene_about.c deleted file mode 100644 index ddcb8aac0..000000000 --- a/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene_about.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "../nfc_rfid_detector_app_i.h" - -void nfc_rfid_detector_scene_about_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - NfcRfidDetectorApp* app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(app->view_dispatcher, result); - } -} - -void nfc_rfid_detector_scene_about_on_enter(void* context) { - NfcRfidDetectorApp* app = context; - - FuriString* temp_str; - temp_str = furi_string_alloc(); - furi_string_printf(temp_str, "\e#%s\n", "Information"); - - furi_string_cat_printf(temp_str, "Version: %s\n", NFC_RFID_DETECTOR_VERSION_APP); - furi_string_cat_printf(temp_str, "Developed by: %s\n", NFC_RFID_DETECTOR_DEVELOPED); - furi_string_cat_printf(temp_str, "Github: %s\n\n", NFC_RFID_DETECTOR_GITHUB); - - furi_string_cat_printf(temp_str, "\e#%s\n", "Description"); - furi_string_cat_printf( - temp_str, - "This application allows\nyou to determine what\ntype of electromagnetic\nfield the reader is using.\nFor LF RFID you can also\nsee the carrier frequency\n\n"); - - widget_add_text_box_element( - app->widget, - 0, - 0, - 128, - 14, - AlignCenter, - AlignBottom, - "\e#\e! \e!\n", - false); - widget_add_text_box_element( - app->widget, - 0, - 2, - 128, - 14, - AlignCenter, - AlignBottom, - "\e#\e! NFC/RFID detector \e!\n", - false); - widget_add_text_scroll_element(app->widget, 0, 16, 128, 50, furi_string_get_cstr(temp_str)); - furi_string_free(temp_str); - - view_dispatcher_switch_to_view(app->view_dispatcher, NfcRfidDetectorViewWidget); -} - -bool nfc_rfid_detector_scene_about_on_event(void* context, SceneManagerEvent event) { - NfcRfidDetectorApp* app = context; - bool consumed = false; - UNUSED(app); - UNUSED(event); - - return consumed; -} - -void nfc_rfid_detector_scene_about_on_exit(void* context) { - NfcRfidDetectorApp* app = context; - - // Clear views - widget_reset(app->widget); -} diff --git a/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene_config.h b/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene_config.h deleted file mode 100644 index ab49ad5c2..000000000 --- a/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene_config.h +++ /dev/null @@ -1,3 +0,0 @@ -ADD_SCENE(nfc_rfid_detector, start, Start) -ADD_SCENE(nfc_rfid_detector, about, About) -ADD_SCENE(nfc_rfid_detector, field_presence, FieldPresence) diff --git a/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene_field_presence.c b/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene_field_presence.c deleted file mode 100644 index ec53b5a0a..000000000 --- a/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene_field_presence.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "../nfc_rfid_detector_app_i.h" -#include "../views/nfc_rfid_detector_view_field_presence.h" - -void nfc_rfid_detector_scene_field_presence_callback( - NfcRfidDetectorCustomEvent event, - void* context) { - furi_assert(context); - NfcRfidDetectorApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -static const NotificationSequence notification_app_display_on = { - - &message_display_backlight_on, - NULL, -}; - -static void nfc_rfid_detector_scene_field_presence_update(void* context) { - furi_assert(context); - NfcRfidDetectorApp* app = context; - - uint32_t frequency = 0; - bool nfc_field = nfc_rfid_detector_app_field_presence_is_nfc(app); - bool rfid_field = nfc_rfid_detector_app_field_presence_is_rfid(app, &frequency); - - if(nfc_field || rfid_field) - notification_message(app->notifications, ¬ification_app_display_on); - - nfc_rfid_detector_view_field_presence_update( - app->nfc_rfid_detector_field_presence, nfc_field, rfid_field, frequency); -} - -void nfc_rfid_detector_scene_field_presence_on_enter(void* context) { - furi_assert(context); - NfcRfidDetectorApp* app = context; - - // Start detection of field presence - nfc_rfid_detector_app_field_presence_start(app); - - view_dispatcher_switch_to_view(app->view_dispatcher, NfcRfidDetectorViewFieldPresence); -} - -bool nfc_rfid_detector_scene_field_presence_on_event(void* context, SceneManagerEvent event) { - furi_assert(context); - NfcRfidDetectorApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeTick) { - nfc_rfid_detector_scene_field_presence_update(app); - } - - return consumed; -} - -void nfc_rfid_detector_scene_field_presence_on_exit(void* context) { - furi_assert(context); - NfcRfidDetectorApp* app = context; - // Stop detection of field presence - nfc_rfid_detector_app_field_presence_stop(app); -} diff --git a/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene_start.c b/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene_start.c deleted file mode 100644 index 7b71bd973..000000000 --- a/applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene_start.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "../nfc_rfid_detector_app_i.h" - -typedef enum { - SubmenuIndexNfcRfidDetectorFieldPresence, - SubmenuIndexNfcRfidDetectorAbout, -} SubmenuIndex; - -void nfc_rfid_detector_scene_start_submenu_callback(void* context, uint32_t index) { - NfcRfidDetectorApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void nfc_rfid_detector_scene_start_on_enter(void* context) { - UNUSED(context); - NfcRfidDetectorApp* app = context; - Submenu* submenu = app->submenu; - - submenu_add_item( - submenu, - "Detect field type", - SubmenuIndexNfcRfidDetectorFieldPresence, - nfc_rfid_detector_scene_start_submenu_callback, - app); - submenu_add_item( - submenu, - "About", - SubmenuIndexNfcRfidDetectorAbout, - nfc_rfid_detector_scene_start_submenu_callback, - app); - - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(app->scene_manager, NfcRfidDetectorSceneStart)); - - view_dispatcher_switch_to_view(app->view_dispatcher, NfcRfidDetectorViewSubmenu); -} - -bool nfc_rfid_detector_scene_start_on_event(void* context, SceneManagerEvent event) { - NfcRfidDetectorApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexNfcRfidDetectorAbout) { - scene_manager_next_scene(app->scene_manager, NfcRfidDetectorSceneAbout); - consumed = true; - } else if(event.event == SubmenuIndexNfcRfidDetectorFieldPresence) { - scene_manager_next_scene(app->scene_manager, NfcRfidDetectorSceneFieldPresence); - consumed = true; - } - scene_manager_set_scene_state(app->scene_manager, NfcRfidDetectorSceneStart, event.event); - } - - return consumed; -} - -void nfc_rfid_detector_scene_start_on_exit(void* context) { - NfcRfidDetectorApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/external/nfc_rfid_detector/views/nfc_rfid_detector_view_field_presence.c b/applications/external/nfc_rfid_detector/views/nfc_rfid_detector_view_field_presence.c deleted file mode 100644 index e65eb8362..000000000 --- a/applications/external/nfc_rfid_detector/views/nfc_rfid_detector_view_field_presence.c +++ /dev/null @@ -1,164 +0,0 @@ -#include "nfc_rfid_detector_view_field_presence.h" -#include "../nfc_rfid_detector_app_i.h" -#include - -#include -#include - -#define FIELD_FOUND_WEIGHT 5 - -typedef enum { - NfcRfidDetectorTypeFieldPresenceNfc, - NfcRfidDetectorTypeFieldPresenceRfid, -} NfcRfidDetectorTypeFieldPresence; - -static const Icon* NfcRfidDetectorFieldPresenceIcons[] = { - [NfcRfidDetectorTypeFieldPresenceNfc] = &I_NFC_detect_45x30, - [NfcRfidDetectorTypeFieldPresenceRfid] = &I_Rfid_detect_45x30, -}; - -struct NfcRfidDetectorFieldPresence { - View* view; -}; - -typedef struct { - uint8_t nfc_field; - uint8_t rfid_field; - uint32_t rfid_frequency; -} NfcRfidDetectorFieldPresenceModel; - -void nfc_rfid_detector_view_field_presence_update( - NfcRfidDetectorFieldPresence* instance, - bool nfc_field, - bool rfid_field, - uint32_t rfid_frequency) { - furi_assert(instance); - with_view_model( - instance->view, - NfcRfidDetectorFieldPresenceModel * model, - { - if(nfc_field) { - model->nfc_field = FIELD_FOUND_WEIGHT; - } else if(model->nfc_field) { - model->nfc_field--; - } - if(rfid_field) { - model->rfid_field = FIELD_FOUND_WEIGHT; - model->rfid_frequency = rfid_frequency; - } else if(model->rfid_field) { - model->rfid_field--; - } - }, - true); -} - -void nfc_rfid_detector_view_field_presence_draw( - Canvas* canvas, - NfcRfidDetectorFieldPresenceModel* model) { - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - - if(!model->nfc_field && !model->rfid_field) { - canvas_draw_icon(canvas, 0, 16, &I_Modern_reader_18x34); - canvas_draw_icon(canvas, 22, 12, &I_Move_flipper_26x39); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 56, 36, "Touch the reader"); - } else { - if(model->nfc_field) { - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 21, 10, "NFC"); - canvas_draw_icon( - canvas, - 9, - 17, - NfcRfidDetectorFieldPresenceIcons[NfcRfidDetectorTypeFieldPresenceNfc]); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 9, 62, "13,56 MHz"); - } - - if(model->rfid_field) { - char str[16]; - snprintf(str, sizeof(str), "%.02f KHz", (double)model->rfid_frequency / 1000); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 76, 10, "LF RFID"); - canvas_draw_icon( - canvas, - 71, - 17, - NfcRfidDetectorFieldPresenceIcons[NfcRfidDetectorTypeFieldPresenceRfid]); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 69, 62, str); - } - } -} - -bool nfc_rfid_detector_view_field_presence_input(InputEvent* event, void* context) { - furi_assert(context); - NfcRfidDetectorFieldPresence* instance = context; - UNUSED(instance); - - if(event->key == InputKeyBack) { - return false; - } - - return true; -} - -void nfc_rfid_detector_view_field_presence_enter(void* context) { - furi_assert(context); - NfcRfidDetectorFieldPresence* instance = context; - with_view_model( - instance->view, - NfcRfidDetectorFieldPresenceModel * model, - { - model->nfc_field = 0; - model->rfid_field = 0; - model->rfid_frequency = 0; - }, - true); -} - -void nfc_rfid_detector_view_field_presence_exit(void* context) { - furi_assert(context); - NfcRfidDetectorFieldPresence* instance = context; - UNUSED(instance); -} - -NfcRfidDetectorFieldPresence* nfc_rfid_detector_view_field_presence_alloc() { - NfcRfidDetectorFieldPresence* instance = malloc(sizeof(NfcRfidDetectorFieldPresence)); - - // View allocation and configuration - instance->view = view_alloc(); - - view_allocate_model( - instance->view, ViewModelTypeLocking, sizeof(NfcRfidDetectorFieldPresenceModel)); - view_set_context(instance->view, instance); - view_set_draw_callback( - instance->view, (ViewDrawCallback)nfc_rfid_detector_view_field_presence_draw); - view_set_input_callback(instance->view, nfc_rfid_detector_view_field_presence_input); - view_set_enter_callback(instance->view, nfc_rfid_detector_view_field_presence_enter); - view_set_exit_callback(instance->view, nfc_rfid_detector_view_field_presence_exit); - - with_view_model( - instance->view, - NfcRfidDetectorFieldPresenceModel * model, - { - model->nfc_field = 0; - model->rfid_field = 0; - model->rfid_frequency = 0; - }, - true); - return instance; -} - -void nfc_rfid_detector_view_field_presence_free(NfcRfidDetectorFieldPresence* instance) { - furi_assert(instance); - - view_free(instance->view); - free(instance); -} - -View* nfc_rfid_detector_view_field_presence_get_view(NfcRfidDetectorFieldPresence* instance) { - furi_assert(instance); - return instance->view; -} diff --git a/applications/external/nfc_rfid_detector/views/nfc_rfid_detector_view_field_presence.h b/applications/external/nfc_rfid_detector/views/nfc_rfid_detector_view_field_presence.h deleted file mode 100644 index 0ddb4e2cd..000000000 --- a/applications/external/nfc_rfid_detector/views/nfc_rfid_detector_view_field_presence.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include -#include "../helpers/nfc_rfid_detector_types.h" -#include "../helpers/nfc_rfid_detector_event.h" - -typedef struct NfcRfidDetectorFieldPresence NfcRfidDetectorFieldPresence; - -void nfc_rfid_detector_view_field_presence_update( - NfcRfidDetectorFieldPresence* instance, - bool nfc_field, - bool rfid_field, - uint32_t rfid_frequency); - -NfcRfidDetectorFieldPresence* nfc_rfid_detector_view_field_presence_alloc(); - -void nfc_rfid_detector_view_field_presence_free(NfcRfidDetectorFieldPresence* instance); - -View* nfc_rfid_detector_view_field_presence_get_view(NfcRfidDetectorFieldPresence* instance); diff --git a/applications/external/picopass/125_10px.png b/applications/external/picopass/125_10px.png deleted file mode 100644 index ce01284a2..000000000 Binary files a/applications/external/picopass/125_10px.png and /dev/null differ diff --git a/applications/external/picopass/application.fam b/applications/external/picopass/application.fam deleted file mode 100644 index c5087b804..000000000 --- a/applications/external/picopass/application.fam +++ /dev/null @@ -1,22 +0,0 @@ -App( - appid="picopass", - name="PicoPass", - apptype=FlipperAppType.EXTERNAL, - targets=["f7"], - entry_point="picopass_app", - requires=[ - "storage", - "gui", - ], - stack_size=4 * 1024, - order=30, - fap_icon="125_10px.png", - fap_category="NFC", - fap_libs=["mbedtls"], - fap_private_libs=[ - Lib( - name="loclass", - ), - ], - fap_icon_assets="icons", -) diff --git a/applications/external/picopass/helpers/iclass_elite_dict.c b/applications/external/picopass/helpers/iclass_elite_dict.c deleted file mode 100644 index f92dce0aa..000000000 --- a/applications/external/picopass/helpers/iclass_elite_dict.c +++ /dev/null @@ -1,164 +0,0 @@ -#include "iclass_elite_dict.h" - -#include -#include - -#define ICLASS_ELITE_DICT_FLIPPER_NAME APP_DATA_PATH("assets/iclass_elite_dict.txt") -#define ICLASS_ELITE_DICT_USER_NAME APP_DATA_PATH("assets/iclass_elite_dict_user.txt") -#define ICLASS_STANDARD_DICT_FLIPPER_NAME APP_DATA_PATH("assets/iclass_standard_dict.txt") - -#define TAG "IclassEliteDict" - -#define ICLASS_ELITE_KEY_LINE_LEN (17) -#define ICLASS_ELITE_KEY_LEN (8) - -struct IclassEliteDict { - Stream* stream; - uint32_t total_keys; -}; - -bool iclass_elite_dict_check_presence(IclassEliteDictType dict_type) { - Storage* storage = furi_record_open(RECORD_STORAGE); - - bool dict_present = false; - if(dict_type == IclassEliteDictTypeFlipper) { - dict_present = - (storage_common_stat(storage, ICLASS_ELITE_DICT_FLIPPER_NAME, NULL) == FSE_OK); - } else if(dict_type == IclassEliteDictTypeUser) { - dict_present = (storage_common_stat(storage, ICLASS_ELITE_DICT_USER_NAME, NULL) == FSE_OK); - } else if(dict_type == IclassStandardDictTypeFlipper) { - dict_present = - (storage_common_stat(storage, ICLASS_STANDARD_DICT_FLIPPER_NAME, NULL) == FSE_OK); - } - - furi_record_close(RECORD_STORAGE); - - return dict_present; -} - -IclassEliteDict* iclass_elite_dict_alloc(IclassEliteDictType dict_type) { - IclassEliteDict* dict = malloc(sizeof(IclassEliteDict)); - Storage* storage = furi_record_open(RECORD_STORAGE); - dict->stream = buffered_file_stream_alloc(storage); - FuriString* next_line = furi_string_alloc(); - - bool dict_loaded = false; - do { - if(dict_type == IclassEliteDictTypeFlipper) { - if(!buffered_file_stream_open( - dict->stream, ICLASS_ELITE_DICT_FLIPPER_NAME, FSAM_READ, FSOM_OPEN_EXISTING)) { - buffered_file_stream_close(dict->stream); - break; - } - } else if(dict_type == IclassEliteDictTypeUser) { - if(!buffered_file_stream_open( - dict->stream, ICLASS_ELITE_DICT_USER_NAME, FSAM_READ_WRITE, FSOM_OPEN_ALWAYS)) { - buffered_file_stream_close(dict->stream); - break; - } - } else if(dict_type == IclassStandardDictTypeFlipper) { - if(!buffered_file_stream_open( - dict->stream, - ICLASS_STANDARD_DICT_FLIPPER_NAME, - FSAM_READ, - FSOM_OPEN_EXISTING)) { - buffered_file_stream_close(dict->stream); - break; - } - } - - // Read total amount of keys - while(true) { //-V547 - if(!stream_read_line(dict->stream, next_line)) break; - if(furi_string_get_char(next_line, 0) == '#') continue; - if(furi_string_size(next_line) != ICLASS_ELITE_KEY_LINE_LEN) continue; - dict->total_keys++; - } - furi_string_reset(next_line); - stream_rewind(dict->stream); - - dict_loaded = true; - FURI_LOG_I(TAG, "Loaded dictionary with %lu keys", dict->total_keys); - } while(false); - - if(!dict_loaded) { //-V547 - buffered_file_stream_close(dict->stream); - free(dict); - dict = NULL; - } - - furi_record_close(RECORD_STORAGE); - furi_string_free(next_line); - - return dict; -} - -void iclass_elite_dict_free(IclassEliteDict* dict) { - furi_assert(dict); - furi_assert(dict->stream); - - buffered_file_stream_close(dict->stream); - stream_free(dict->stream); - free(dict); -} - -uint32_t iclass_elite_dict_get_total_keys(IclassEliteDict* dict) { - furi_assert(dict); - - return dict->total_keys; -} - -bool iclass_elite_dict_get_next_key(IclassEliteDict* dict, uint8_t* key) { - furi_assert(dict); - furi_assert(dict->stream); - - uint8_t key_byte_tmp = 0; - FuriString* next_line = furi_string_alloc(); - - bool key_read = false; - *key = 0ULL; - while(!key_read) { - if(!stream_read_line(dict->stream, next_line)) break; - if(furi_string_get_char(next_line, 0) == '#') continue; - if(furi_string_size(next_line) != ICLASS_ELITE_KEY_LINE_LEN) continue; - for(uint8_t i = 0; i < ICLASS_ELITE_KEY_LEN * 2; i += 2) { - args_char_to_hex( - furi_string_get_char(next_line, i), - furi_string_get_char(next_line, i + 1), - &key_byte_tmp); - key[i / 2] = key_byte_tmp; - } - key_read = true; - } - - furi_string_free(next_line); - return key_read; -} - -bool iclass_elite_dict_rewind(IclassEliteDict* dict) { - furi_assert(dict); - furi_assert(dict->stream); - - return stream_rewind(dict->stream); -} - -bool iclass_elite_dict_add_key(IclassEliteDict* dict, uint8_t* key) { - furi_assert(dict); - furi_assert(dict->stream); - - FuriString* key_str = furi_string_alloc(); - for(size_t i = 0; i < 6; i++) { - furi_string_cat_printf(key_str, "%02X", key[i]); - } - furi_string_cat_printf(key_str, "\n"); - - bool key_added = false; - do { - if(!stream_seek(dict->stream, 0, StreamOffsetFromEnd)) break; - if(!stream_insert_string(dict->stream, key_str)) break; - key_added = true; - } while(false); - - furi_string_free(key_str); - return key_added; -} diff --git a/applications/external/picopass/helpers/iclass_elite_dict.h b/applications/external/picopass/helpers/iclass_elite_dict.h deleted file mode 100644 index 150cd1b76..000000000 --- a/applications/external/picopass/helpers/iclass_elite_dict.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -typedef enum { - IclassEliteDictTypeUser, - IclassEliteDictTypeFlipper, - IclassStandardDictTypeFlipper, -} IclassEliteDictType; - -typedef struct IclassEliteDict IclassEliteDict; - -bool iclass_elite_dict_check_presence(IclassEliteDictType dict_type); - -IclassEliteDict* iclass_elite_dict_alloc(IclassEliteDictType dict_type); - -void iclass_elite_dict_free(IclassEliteDict* dict); - -uint32_t iclass_elite_dict_get_total_keys(IclassEliteDict* dict); - -bool iclass_elite_dict_get_next_key(IclassEliteDict* dict, uint8_t* key); - -bool iclass_elite_dict_rewind(IclassEliteDict* dict); - -bool iclass_elite_dict_add_key(IclassEliteDict* dict, uint8_t* key); diff --git a/applications/external/picopass/icons/DolphinMafia_115x62.png b/applications/external/picopass/icons/DolphinMafia_115x62.png deleted file mode 100644 index 66fdb40ff..000000000 Binary files a/applications/external/picopass/icons/DolphinMafia_115x62.png and /dev/null differ diff --git a/applications/external/picopass/icons/DolphinNice_96x59.png b/applications/external/picopass/icons/DolphinNice_96x59.png deleted file mode 100644 index a299d3630..000000000 Binary files a/applications/external/picopass/icons/DolphinNice_96x59.png and /dev/null differ diff --git a/applications/external/picopass/icons/Nfc_10px.png b/applications/external/picopass/icons/Nfc_10px.png deleted file mode 100644 index 6bc027111..000000000 Binary files a/applications/external/picopass/icons/Nfc_10px.png and /dev/null differ diff --git a/applications/external/picopass/icons/RFIDDolphinReceive_97x61.png b/applications/external/picopass/icons/RFIDDolphinReceive_97x61.png deleted file mode 100644 index e1f5f9f80..000000000 Binary files a/applications/external/picopass/icons/RFIDDolphinReceive_97x61.png and /dev/null differ diff --git a/applications/external/picopass/icons/RFIDDolphinSend_97x61.png b/applications/external/picopass/icons/RFIDDolphinSend_97x61.png deleted file mode 100644 index 380a970d9..000000000 Binary files a/applications/external/picopass/icons/RFIDDolphinSend_97x61.png and /dev/null differ diff --git a/applications/external/picopass/lib/loclass/optimized_cipher.c b/applications/external/picopass/lib/loclass/optimized_cipher.c deleted file mode 100644 index 94df07bae..000000000 --- a/applications/external/picopass/lib/loclass/optimized_cipher.c +++ /dev/null @@ -1,299 +0,0 @@ -//----------------------------------------------------------------------------- -// Borrowed initially from https://github.com/holiman/loclass -// Copyright (C) 2014 Martin Holst Swende -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// WARNING -// -// THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. -// -// USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL -// PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, -// AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. -// -// THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. -//----------------------------------------------------------------------------- -// It is a reconstruction of the cipher engine used in iClass, and RFID techology. -// -// The implementation is based on the work performed by -// Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and -// Milosch Meriac in the paper "Dismantling IClass". -//----------------------------------------------------------------------------- -/* - This file contains an optimized version of the MAC-calculation algorithm. Some measurements on - a std laptop showed it runs in about 1/3 of the time: - - Std: 0.428962 - Opt: 0.151609 - - Additionally, it is self-reliant, not requiring e.g. bitstreams from the cipherutils, thus can - be easily dropped into a code base. - - The optimizations have been performed in the following steps: - * Parameters passed by reference instead of by value. - * Iteration instead of recursion, un-nesting recursive loops into for-loops. - * Handling of bytes instead of individual bits, for less shuffling and masking - * Less creation of "objects", structs, and instead reuse of alloc:ed memory - * Inlining some functions via #define:s - - As a consequence, this implementation is less generic. Also, I haven't bothered documenting this. - For a thorough documentation, check out the MAC-calculation within cipher.c instead. - - -- MHS 2015 -**/ - -/** - - The runtime of opt_doTagMAC_2() with the MHS optimized version was 403 microseconds on Proxmark3. - This was still to slow for some newer readers which didn't want to wait that long. - - Further optimizations to speedup the MAC calculations: - * Optimized opt_Tt logic - * Look up table for opt_select - * Removing many unnecessary bit maskings (& 0x1) - * updating state in place instead of alternating use of a second state structure - * remove the necessity to reverse bits of input and output bytes - - opt_doTagMAC_2() now completes in 270 microseconds. - - -- piwi 2019 -**/ - -/** - add the possibility to do iCLASS on device only - -- iceman 2020 -**/ - -#include "optimized_cipher.h" -#include "optimized_elite.h" -#include "optimized_ikeys.h" -#include "optimized_cipherutils.h" - -static const uint8_t loclass_opt_select_LUT[256] = { - 00, 03, 02, 01, 02, 03, 00, 01, 04, 07, 07, 04, 06, 07, 05, 04, 01, 02, 03, 00, 02, 03, 00, 01, - 05, 06, 06, 05, 06, 07, 05, 04, 06, 05, 04, 07, 04, 05, 06, 07, 06, 05, 05, 06, 04, 05, 07, 06, - 07, 04, 05, 06, 04, 05, 06, 07, 07, 04, 04, 07, 04, 05, 07, 06, 06, 05, 04, 07, 04, 05, 06, 07, - 02, 01, 01, 02, 00, 01, 03, 02, 03, 00, 01, 02, 00, 01, 02, 03, 07, 04, 04, 07, 04, 05, 07, 06, - 00, 03, 02, 01, 02, 03, 00, 01, 00, 03, 03, 00, 02, 03, 01, 00, 05, 06, 07, 04, 06, 07, 04, 05, - 05, 06, 06, 05, 06, 07, 05, 04, 02, 01, 00, 03, 00, 01, 02, 03, 06, 05, 05, 06, 04, 05, 07, 06, - 03, 00, 01, 02, 00, 01, 02, 03, 07, 04, 04, 07, 04, 05, 07, 06, 02, 01, 00, 03, 00, 01, 02, 03, - 02, 01, 01, 02, 00, 01, 03, 02, 03, 00, 01, 02, 00, 01, 02, 03, 03, 00, 00, 03, 00, 01, 03, 02, - 04, 07, 06, 05, 06, 07, 04, 05, 00, 03, 03, 00, 02, 03, 01, 00, 01, 02, 03, 00, 02, 03, 00, 01, - 05, 06, 06, 05, 06, 07, 05, 04, 04, 07, 06, 05, 06, 07, 04, 05, 04, 07, 07, 04, 06, 07, 05, 04, - 01, 02, 03, 00, 02, 03, 00, 01, 01, 02, 02, 01, 02, 03, 01, 00}; - -/********************** the table above has been generated with this code: ******** -#include "util.h" -static void init_opt_select_LUT(void) { - for (int r = 0; r < 256; r++) { - uint8_t r_ls2 = r << 2; - uint8_t r_and_ls2 = r & r_ls2; - uint8_t r_or_ls2 = r | r_ls2; - uint8_t z0 = (r_and_ls2 >> 5) ^ ((r & ~r_ls2) >> 4) ^ ( r_or_ls2 >> 3); - uint8_t z1 = (r_or_ls2 >> 6) ^ ( r_or_ls2 >> 1) ^ (r >> 5) ^ r; - uint8_t z2 = ((r & ~r_ls2) >> 4) ^ (r_and_ls2 >> 3) ^ r; - loclass_opt_select_LUT[r] = (z0 & 4) | (z1 & 2) | (z2 & 1); - } - print_result("", loclass_opt_select_LUT, 256); -} -***********************************************************************************/ - -#define loclass_opt__select(x, y, r) \ - (4 & ((((r) & ((r) << 2)) >> 5) ^ (((r) & ~((r) << 2)) >> 4) ^ (((r) | (r) << 2) >> 3))) | \ - (2 & ((((r) | (r) << 2) >> 6) ^ (((r) | (r) << 2) >> 1) ^ ((r) >> 5) ^ (r) ^ (((x) ^ (y)) << 1))) | \ - (1 & ((((r) & ~((r) << 2)) >> 4) ^ (((r) & ((r) << 2)) >> 3) ^ (r) ^ (x))) - -static void loclass_opt_successor(const uint8_t* k, LoclassState_t* s, uint8_t y) { - uint16_t Tt = s->t & 0xc533; - Tt = Tt ^ (Tt >> 1); - Tt = Tt ^ (Tt >> 4); - Tt = Tt ^ (Tt >> 10); - Tt = Tt ^ (Tt >> 8); - - s->t = (s->t >> 1); - s->t |= (Tt ^ (s->r >> 7) ^ (s->r >> 3)) << 15; - - uint8_t opt_B = s->b; - opt_B ^= s->b >> 6; - opt_B ^= s->b >> 5; - opt_B ^= s->b >> 4; - - s->b = s->b >> 1; - s->b |= (opt_B ^ s->r) << 7; - - uint8_t opt_select = loclass_opt_select_LUT[s->r] & 0x04; - opt_select |= (loclass_opt_select_LUT[s->r] ^ ((Tt ^ y) << 1)) & 0x02; - opt_select |= (loclass_opt_select_LUT[s->r] ^ Tt) & 0x01; - - uint8_t r = s->r; - s->r = (k[opt_select] ^ s->b) + s->l; - s->l = s->r + r; -} - -static void loclass_opt_suc( - const uint8_t* k, - LoclassState_t* s, - const uint8_t* in, - uint8_t length, - bool add32Zeroes) { - for(int i = 0; i < length; i++) { - uint8_t head = in[i]; - for(int j = 0; j < 8; j++) { - loclass_opt_successor(k, s, head); - head >>= 1; - } - } - //For tag MAC, an additional 32 zeroes - if(add32Zeroes) { - for(int i = 0; i < 16; i++) { - loclass_opt_successor(k, s, 0); - loclass_opt_successor(k, s, 0); - } - } -} - -static void loclass_opt_output(const uint8_t* k, LoclassState_t* s, uint8_t* buffer) { - for(uint8_t times = 0; times < 4; times++) { - uint8_t bout = 0; - bout |= (s->r & 0x4) >> 2; - loclass_opt_successor(k, s, 0); - bout |= (s->r & 0x4) >> 1; - loclass_opt_successor(k, s, 0); - bout |= (s->r & 0x4); - loclass_opt_successor(k, s, 0); - bout |= (s->r & 0x4) << 1; - loclass_opt_successor(k, s, 0); - bout |= (s->r & 0x4) << 2; - loclass_opt_successor(k, s, 0); - bout |= (s->r & 0x4) << 3; - loclass_opt_successor(k, s, 0); - bout |= (s->r & 0x4) << 4; - loclass_opt_successor(k, s, 0); - bout |= (s->r & 0x4) << 5; - loclass_opt_successor(k, s, 0); - buffer[times] = bout; - } -} - -static void loclass_opt_MAC(uint8_t* k, uint8_t* input, uint8_t* out) { - LoclassState_t _init = { - ((k[0] ^ 0x4c) + 0xEC) & 0xFF, // l - ((k[0] ^ 0x4c) + 0x21) & 0xFF, // r - 0x4c, // b - 0xE012 // t - }; - - loclass_opt_suc(k, &_init, input, 12, false); - loclass_opt_output(k, &_init, out); -} - -static void loclass_opt_MAC_N(uint8_t* k, uint8_t* input, uint8_t in_size, uint8_t* out) { - LoclassState_t _init = { - ((k[0] ^ 0x4c) + 0xEC) & 0xFF, // l - ((k[0] ^ 0x4c) + 0x21) & 0xFF, // r - 0x4c, // b - 0xE012 // t - }; - - loclass_opt_suc(k, &_init, input, in_size, false); - loclass_opt_output(k, &_init, out); -} - -void loclass_opt_doReaderMAC(uint8_t* cc_nr_p, uint8_t* div_key_p, uint8_t mac[4]) { - uint8_t dest[] = {0, 0, 0, 0, 0, 0, 0, 0}; - loclass_opt_MAC(div_key_p, cc_nr_p, dest); - memcpy(mac, dest, 4); -} - -void loclass_opt_doReaderMAC_2( - LoclassState_t _init, - uint8_t* nr, - uint8_t mac[4], - const uint8_t* div_key_p) { - loclass_opt_suc(div_key_p, &_init, nr, 4, false); - loclass_opt_output(div_key_p, &_init, mac); -} - -void loclass_doMAC_N(uint8_t* in_p, uint8_t in_size, uint8_t* div_key_p, uint8_t mac[4]) { - uint8_t dest[] = {0, 0, 0, 0, 0, 0, 0, 0}; - loclass_opt_MAC_N(div_key_p, in_p, in_size, dest); - memcpy(mac, dest, 4); -} - -void loclass_opt_doTagMAC(uint8_t* cc_p, const uint8_t* div_key_p, uint8_t mac[4]) { - LoclassState_t _init = { - ((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF, // l - ((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF, // r - 0x4c, // b - 0xE012 // t - }; - loclass_opt_suc(div_key_p, &_init, cc_p, 12, true); - loclass_opt_output(div_key_p, &_init, mac); -} - -/** - * The tag MAC can be divided (both can, but no point in dividing the reader mac) into - * two functions, since the first 8 bytes are known, we can pre-calculate the state - * reached after feeding CC to the cipher. - * @param cc_p - * @param div_key_p - * @return the cipher state - */ -LoclassState_t loclass_opt_doTagMAC_1(uint8_t* cc_p, const uint8_t* div_key_p) { - LoclassState_t _init = { - ((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF, // l - ((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF, // r - 0x4c, // b - 0xE012 // t - }; - loclass_opt_suc(div_key_p, &_init, cc_p, 8, false); - return _init; -} - -/** - * The second part of the tag MAC calculation, since the CC is already calculated into the state, - * this function is fed only the NR, and internally feeds the remaining 32 0-bits to generate the tag - * MAC response. - * @param _init - precalculated cipher state - * @param nr - the reader challenge - * @param mac - where to store the MAC - * @param div_key_p - the key to use - */ -void loclass_opt_doTagMAC_2( - LoclassState_t _init, - uint8_t* nr, - uint8_t mac[4], - const uint8_t* div_key_p) { - loclass_opt_suc(div_key_p, &_init, nr, 4, true); - loclass_opt_output(div_key_p, &_init, mac); -} - -void loclass_iclass_calc_div_key(uint8_t* csn, uint8_t* key, uint8_t* div_key, bool elite) { - if(elite) { - uint8_t keytable[128] = {0}; - uint8_t key_index[8] = {0}; - uint8_t key_sel[8] = {0}; - uint8_t key_sel_p[8] = {0}; - loclass_hash2(key, keytable); - loclass_hash1(csn, key_index); - for(uint8_t i = 0; i < 8; i++) key_sel[i] = keytable[key_index[i]]; - - //Permute from iclass format to standard format - loclass_permutekey_rev(key_sel, key_sel_p); - loclass_diversifyKey(csn, key_sel_p, div_key); - } else { - loclass_diversifyKey(csn, key, div_key); - } -} diff --git a/applications/external/picopass/lib/loclass/optimized_cipher.h b/applications/external/picopass/lib/loclass/optimized_cipher.h deleted file mode 100644 index 2158f0acf..000000000 --- a/applications/external/picopass/lib/loclass/optimized_cipher.h +++ /dev/null @@ -1,98 +0,0 @@ -//----------------------------------------------------------------------------- -// Borrowed initially from https://github.com/holiman/loclass -// More recently from https://github.com/RfidResearchGroup/proxmark3 -// Copyright (C) 2014 Martin Holst Swende -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// WARNING -// -// THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. -// -// USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL -// PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, -// AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. -// -// THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. -//----------------------------------------------------------------------------- -// It is a reconstruction of the cipher engine used in iClass, and RFID techology. -// -// The implementation is based on the work performed by -// Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and -// Milosch Meriac in the paper "Dismantling IClass". -//----------------------------------------------------------------------------- -#ifndef OPTIMIZED_CIPHER_H -#define OPTIMIZED_CIPHER_H -#include -#include -#include -#include - -/** -* Definition 1 (Cipher state). A cipher state of iClass s is an element of F 40/2 -* consisting of the following four components: -* 1. the left register l = (l 0 . . . l 7 ) ∈ F 8/2 ; -* 2. the right register r = (r 0 . . . r 7 ) ∈ F 8/2 ; -* 3. the top register t = (t 0 . . . t 15 ) ∈ F 16/2 . -* 4. the bottom register b = (b 0 . . . b 7 ) ∈ F 8/2 . -**/ -typedef struct { - uint8_t l; - uint8_t r; - uint8_t b; - uint16_t t; -} LoclassState_t; - -/** The reader MAC is MAC(key, CC * NR ) - **/ -void loclass_opt_doReaderMAC(uint8_t* cc_nr_p, uint8_t* div_key_p, uint8_t mac[4]); - -void loclass_opt_doReaderMAC_2( - LoclassState_t _init, - uint8_t* nr, - uint8_t mac[4], - const uint8_t* div_key_p); - -/** - * The tag MAC is MAC(key, CC * NR * 32x0)) - */ -void loclass_opt_doTagMAC(uint8_t* cc_p, const uint8_t* div_key_p, uint8_t mac[4]); - -/** - * The tag MAC can be divided (both can, but no point in dividing the reader mac) into - * two functions, since the first 8 bytes are known, we can pre-calculate the state - * reached after feeding CC to the cipher. - * @param cc_p - * @param div_key_p - * @return the cipher state - */ -LoclassState_t loclass_opt_doTagMAC_1(uint8_t* cc_p, const uint8_t* div_key_p); -/** - * The second part of the tag MAC calculation, since the CC is already calculated into the state, - * this function is fed only the NR, and internally feeds the remaining 32 0-bits to generate the tag - * MAC response. - * @param _init - precalculated cipher state - * @param nr - the reader challenge - * @param mac - where to store the MAC - * @param div_key_p - the key to use - */ -void loclass_opt_doTagMAC_2( - LoclassState_t _init, - uint8_t* nr, - uint8_t mac[4], - const uint8_t* div_key_p); - -void loclass_doMAC_N(uint8_t* in_p, uint8_t in_size, uint8_t* div_key_p, uint8_t mac[4]); -void loclass_iclass_calc_div_key(uint8_t* csn, uint8_t* key, uint8_t* div_key, bool elite); -#endif // OPTIMIZED_CIPHER_H diff --git a/applications/external/picopass/lib/loclass/optimized_cipherutils.c b/applications/external/picopass/lib/loclass/optimized_cipherutils.c deleted file mode 100644 index e6a87c4a7..000000000 --- a/applications/external/picopass/lib/loclass/optimized_cipherutils.c +++ /dev/null @@ -1,136 +0,0 @@ -//----------------------------------------------------------------------------- -// Borrowed initially from https://github.com/holiman/loclass -// Copyright (C) 2014 Martin Holst Swende -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// WARNING -// -// THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. -// -// USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL -// PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, -// AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. -// -// THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. -//----------------------------------------------------------------------------- -// It is a reconstruction of the cipher engine used in iClass, and RFID techology. -// -// The implementation is based on the work performed by -// Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and -// Milosch Meriac in the paper "Dismantling IClass". -//----------------------------------------------------------------------------- -#include "optimized_cipherutils.h" -#include - -/** - * - * @brief Return and remove the first bit (x0) in the stream : - * @param stream - * @return - */ -bool loclass_headBit(LoclassBitstreamIn_t* stream) { - int bytepos = stream->position >> 3; // divide by 8 - int bitpos = (stream->position++) & 7; // mask out 00000111 - return (*(stream->buffer + bytepos) >> (7 - bitpos)) & 1; -} -/** - * @brief Return and remove the last bit (xn) in the stream: - * @param stream - * @return - */ -bool loclass_tailBit(LoclassBitstreamIn_t* stream) { - int bitpos = stream->numbits - 1 - (stream->position++); - - int bytepos = bitpos >> 3; - bitpos &= 7; - return (*(stream->buffer + bytepos) >> (7 - bitpos)) & 1; -} -/** - * @brief Pushes bit onto the stream - * @param stream - * @param bit - */ -void loclass_pushBit(LoclassBitstreamOut_t* stream, bool bit) { - int bytepos = stream->position >> 3; // divide by 8 - int bitpos = stream->position & 7; - *(stream->buffer + bytepos) |= (bit) << (7 - bitpos); - stream->position++; - stream->numbits++; -} - -/** - * @brief Pushes the lower six bits onto the stream - * as b0 b1 b2 b3 b4 b5 b6 - * @param stream - * @param bits - */ -void loclass_push6bits(LoclassBitstreamOut_t* stream, uint8_t bits) { - loclass_pushBit(stream, bits & 0x20); - loclass_pushBit(stream, bits & 0x10); - loclass_pushBit(stream, bits & 0x08); - loclass_pushBit(stream, bits & 0x04); - loclass_pushBit(stream, bits & 0x02); - loclass_pushBit(stream, bits & 0x01); -} - -/** - * @brief loclass_bitsLeft - * @param stream - * @return number of bits left in stream - */ -int loclass_bitsLeft(LoclassBitstreamIn_t* stream) { - return stream->numbits - stream->position; -} -/** - * @brief numBits - * @param stream - * @return Number of bits stored in stream - */ -void loclass_x_num_to_bytes(uint64_t n, size_t len, uint8_t* dest) { - while(len--) { - dest[len] = (uint8_t)n; - n >>= 8; - } -} - -uint64_t loclass_x_bytes_to_num(uint8_t* src, size_t len) { - uint64_t num = 0; - while(len--) { - num = (num << 8) | (*src); - src++; - } - return num; -} - -uint8_t loclass_reversebytes(uint8_t b) { - b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; - b = (b & 0xCC) >> 2 | (b & 0x33) << 2; - b = (b & 0xAA) >> 1 | (b & 0x55) << 1; - return b; -} - -void loclass_reverse_arraybytes(uint8_t* arr, size_t len) { - uint8_t i; - for(i = 0; i < len; i++) { - arr[i] = loclass_reversebytes(arr[i]); - } -} - -void loclass_reverse_arraycopy(uint8_t* arr, uint8_t* dest, size_t len) { - uint8_t i; - for(i = 0; i < len; i++) { - dest[i] = loclass_reversebytes(arr[i]); - } -} diff --git a/applications/external/picopass/lib/loclass/optimized_cipherutils.h b/applications/external/picopass/lib/loclass/optimized_cipherutils.h deleted file mode 100644 index 05b682079..000000000 --- a/applications/external/picopass/lib/loclass/optimized_cipherutils.h +++ /dev/null @@ -1,64 +0,0 @@ -//----------------------------------------------------------------------------- -// Borrowed initially from https://github.com/holiman/loclass -// More recently from https://github.com/RfidResearchGroup/proxmark3 -// Copyright (C) 2014 Martin Holst Swende -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// WARNING -// -// THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. -// -// USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL -// PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, -// AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. -// -// THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. -//----------------------------------------------------------------------------- -// It is a reconstruction of the cipher engine used in iClass, and RFID techology. -// -// The implementation is based on the work performed by -// Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and -// Milosch Meriac in the paper "Dismantling IClass". -//----------------------------------------------------------------------------- -#ifndef CIPHERUTILS_H -#define CIPHERUTILS_H -#include -#include -#include - -typedef struct { - uint8_t* buffer; - uint8_t numbits; - uint8_t position; -} LoclassBitstreamIn_t; - -typedef struct { - uint8_t* buffer; - uint8_t numbits; - uint8_t position; -} LoclassBitstreamOut_t; - -bool loclass_headBit(LoclassBitstreamIn_t* stream); -bool loclass_tailBit(LoclassBitstreamIn_t* stream); -void loclass_pushBit(LoclassBitstreamOut_t* stream, bool bit); -int loclass_bitsLeft(LoclassBitstreamIn_t* stream); - -void loclass_push6bits(LoclassBitstreamOut_t* stream, uint8_t bits); -void loclass_x_num_to_bytes(uint64_t n, size_t len, uint8_t* dest); -uint64_t loclass_x_bytes_to_num(uint8_t* src, size_t len); -uint8_t loclass_reversebytes(uint8_t b); -void loclass_reverse_arraybytes(uint8_t* arr, size_t len); -void loclass_reverse_arraycopy(uint8_t* arr, uint8_t* dest, size_t len); -#endif // CIPHERUTILS_H diff --git a/applications/external/picopass/lib/loclass/optimized_elite.c b/applications/external/picopass/lib/loclass/optimized_elite.c deleted file mode 100644 index 34e987060..000000000 --- a/applications/external/picopass/lib/loclass/optimized_elite.c +++ /dev/null @@ -1,232 +0,0 @@ -//----------------------------------------------------------------------------- -// Borrowed initially from https://github.com/holiman/loclass -// Copyright (C) 2014 Martin Holst Swende -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// WARNING -// -// THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. -// -// USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL -// PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, -// AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. -// -// THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. -//----------------------------------------------------------------------------- -// It is a reconstruction of the cipher engine used in iClass, and RFID techology. -// -// The implementation is based on the work performed by -// Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and -// Milosch Meriac in the paper "Dismantling IClass". -//----------------------------------------------------------------------------- -#include "optimized_elite.h" - -#include -#include -#include -#include -#include "optimized_ikeys.h" - -/** - * @brief Permutes a key from standard NIST format to Iclass specific format - * from http://www.proxmark.org/forum/viewtopic.php?pid=11220#p11220 - * - * If you loclass_permute [6c 8d 44 f9 2a 2d 01 bf] you get [8a 0d b9 88 bb a7 90 ea] as shown below. - * - * 1 0 1 1 1 1 1 1 bf - * 0 0 0 0 0 0 0 1 01 - * 0 0 1 0 1 1 0 1 2d - * 0 0 1 0 1 0 1 0 2a - * 1 1 1 1 1 0 0 1 f9 - * 0 1 0 0 0 1 0 0 44 - * 1 0 0 0 1 1 0 1 8d - * 0 1 1 0 1 1 0 0 6c - * - * 8 0 b 8 b a 9 e - * a d 9 8 b 7 0 a - * - * @param key - * @param dest - */ -void loclass_permutekey(const uint8_t key[8], uint8_t dest[8]) { - int i; - for(i = 0; i < 8; i++) { - dest[i] = (((key[7] & (0x80 >> i)) >> (7 - i)) << 7) | - (((key[6] & (0x80 >> i)) >> (7 - i)) << 6) | - (((key[5] & (0x80 >> i)) >> (7 - i)) << 5) | - (((key[4] & (0x80 >> i)) >> (7 - i)) << 4) | - (((key[3] & (0x80 >> i)) >> (7 - i)) << 3) | - (((key[2] & (0x80 >> i)) >> (7 - i)) << 2) | - (((key[1] & (0x80 >> i)) >> (7 - i)) << 1) | - (((key[0] & (0x80 >> i)) >> (7 - i)) << 0); - } -} -/** - * Permutes a key from iclass specific format to NIST format - * @brief loclass_permutekey_rev - * @param key - * @param dest - */ -void loclass_permutekey_rev(const uint8_t key[8], uint8_t dest[8]) { - int i; - for(i = 0; i < 8; i++) { - dest[7 - i] = (((key[0] & (0x80 >> i)) >> (7 - i)) << 7) | - (((key[1] & (0x80 >> i)) >> (7 - i)) << 6) | - (((key[2] & (0x80 >> i)) >> (7 - i)) << 5) | - (((key[3] & (0x80 >> i)) >> (7 - i)) << 4) | - (((key[4] & (0x80 >> i)) >> (7 - i)) << 3) | - (((key[5] & (0x80 >> i)) >> (7 - i)) << 2) | - (((key[6] & (0x80 >> i)) >> (7 - i)) << 1) | - (((key[7] & (0x80 >> i)) >> (7 - i)) << 0); - } -} - -/** - * Helper function for loclass_hash1 - * @brief loclass_rr - * @param val - * @return - */ -static uint8_t loclass_rr(uint8_t val) { - return val >> 1 | ((val & 1) << 7); -} - -/** - * Helper function for loclass_hash1 - * @brief rl - * @param val - * @return - */ -static uint8_t loclass_rl(uint8_t val) { - return val << 1 | ((val & 0x80) >> 7); -} - -/** - * Helper function for loclass_hash1 - * @brief loclass_swap - * @param val - * @return - */ -static uint8_t loclass_swap(uint8_t val) { - return ((val >> 4) & 0xFF) | ((val & 0xFF) << 4); -} - -/** - * Hash1 takes CSN as input, and determines what bytes in the keytable will be used - * when constructing the K_sel. - * @param csn the CSN used - * @param k output - */ -void loclass_hash1(const uint8_t csn[], uint8_t k[]) { - k[0] = csn[0] ^ csn[1] ^ csn[2] ^ csn[3] ^ csn[4] ^ csn[5] ^ csn[6] ^ csn[7]; - k[1] = csn[0] + csn[1] + csn[2] + csn[3] + csn[4] + csn[5] + csn[6] + csn[7]; - k[2] = loclass_rr(loclass_swap(csn[2] + k[1])); - k[3] = loclass_rl(loclass_swap(csn[3] + k[0])); - k[4] = ~loclass_rr(csn[4] + k[2]) + 1; - k[5] = ~loclass_rl(csn[5] + k[3]) + 1; - k[6] = loclass_rr(csn[6] + (k[4] ^ 0x3c)); - k[7] = loclass_rl(csn[7] + (k[5] ^ 0xc3)); - - k[7] &= 0x7F; - k[6] &= 0x7F; - k[5] &= 0x7F; - k[4] &= 0x7F; - k[3] &= 0x7F; - k[2] &= 0x7F; - k[1] &= 0x7F; - k[0] &= 0x7F; -} -/** -Definition 14. Define the rotate key function loclass_rk : (F 82 ) 8 × N → (F 82 ) 8 as -loclass_rk(x [0] . . . x [7] , 0) = x [0] . . . x [7] -loclass_rk(x [0] . . . x [7] , n + 1) = loclass_rk(loclass_rl(x [0] ) . . . loclass_rl(x [7] ), n) -**/ -static void loclass_rk(uint8_t* key, uint8_t n, uint8_t* outp_key) { - memcpy(outp_key, key, 8); - uint8_t j; - while(n-- > 0) { - for(j = 0; j < 8; j++) outp_key[j] = loclass_rl(outp_key[j]); - } - return; -} - -static mbedtls_des_context loclass_ctx_enc; -static mbedtls_des_context loclass_ctx_dec; - -static void loclass_desdecrypt_iclass(uint8_t* iclass_key, uint8_t* input, uint8_t* output) { - uint8_t key_std_format[8] = {0}; - loclass_permutekey_rev(iclass_key, key_std_format); - mbedtls_des_setkey_dec(&loclass_ctx_dec, key_std_format); - mbedtls_des_crypt_ecb(&loclass_ctx_dec, input, output); -} - -static void loclass_desencrypt_iclass(uint8_t* iclass_key, uint8_t* input, uint8_t* output) { - uint8_t key_std_format[8] = {0}; - loclass_permutekey_rev(iclass_key, key_std_format); - mbedtls_des_setkey_enc(&loclass_ctx_enc, key_std_format); - mbedtls_des_crypt_ecb(&loclass_ctx_enc, input, output); -} - -/** - * @brief Insert uint8_t[8] custom master key to calculate hash2 and return key_select. - * @param key unpermuted custom key - * @param loclass_hash1 loclass_hash1 - * @param key_sel output key_sel=h[loclass_hash1[i]] - */ -void loclass_hash2(uint8_t* key64, uint8_t* outp_keytable) { - /** - *Expected: - * High Security Key Table - - 00 F1 35 59 A1 0D 5A 26 7F 18 60 0B 96 8A C0 25 C1 - 10 BF A1 3B B0 FF 85 28 75 F2 1F C6 8F 0E 74 8F 21 - 20 14 7A 55 16 C8 A9 7D B3 13 0C 5D C9 31 8D A9 B2 - 30 A3 56 83 0F 55 7E DE 45 71 21 D2 6D C1 57 1C 9C - 40 78 2F 64 51 42 7B 64 30 FA 26 51 76 D3 E0 FB B6 - 50 31 9F BF 2F 7E 4F 94 B4 BD 4F 75 91 E3 1B EB 42 - 60 3F 88 6F B8 6C 2C 93 0D 69 2C D5 20 3C C1 61 95 - 70 43 08 A0 2F FE B3 26 D7 98 0B 34 7B 47 70 A0 AB - - **** The 64-bit HS Custom Key Value = 5B7C62C491C11B39 ******/ - uint8_t key64_negated[8] = {0}; - uint8_t z[8][8] = {{0}, {0}}; - uint8_t temp_output[8] = {0}; - - //calculate complement of key - int i; - for(i = 0; i < 8; i++) key64_negated[i] = ~key64[i]; - - // Once again, key is on iclass-format - loclass_desencrypt_iclass(key64, key64_negated, z[0]); - - uint8_t y[8][8] = {{0}, {0}}; - - // y[0]=DES_dec(z[0],~key) - // Once again, key is on iclass-format - loclass_desdecrypt_iclass(z[0], key64_negated, y[0]); - - for(i = 1; i < 8; i++) { - loclass_rk(key64, i, temp_output); - loclass_desdecrypt_iclass(temp_output, z[i - 1], z[i]); - loclass_desencrypt_iclass(temp_output, y[i - 1], y[i]); - } - - if(outp_keytable != NULL) { - for(i = 0; i < 8; i++) { - memcpy(outp_keytable + i * 16, y[i], 8); - memcpy(outp_keytable + 8 + i * 16, z[i], 8); - } - } -} diff --git a/applications/external/picopass/lib/loclass/optimized_elite.h b/applications/external/picopass/lib/loclass/optimized_elite.h deleted file mode 100644 index 5343ebb07..000000000 --- a/applications/external/picopass/lib/loclass/optimized_elite.h +++ /dev/null @@ -1,58 +0,0 @@ -//----------------------------------------------------------------------------- -// Borrowed initially from https://github.com/holiman/loclass -// More recently from https://github.com/RfidResearchGroup/proxmark3 -// Copyright (C) 2014 Martin Holst Swende -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// WARNING -// -// THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. -// -// USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL -// PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, -// AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. -// -// THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. -//----------------------------------------------------------------------------- -// It is a reconstruction of the cipher engine used in iClass, and RFID techology. -// -// The implementation is based on the work performed by -// Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and -// Milosch Meriac in the paper "Dismantling IClass". -//----------------------------------------------------------------------------- -#ifndef ELITE_CRACK_H -#define ELITE_CRACK_H - -#include -#include - -void loclass_permutekey(const uint8_t key[8], uint8_t dest[8]); -/** - * Permutes a key from iclass specific format to NIST format - * @brief loclass_permutekey_rev - * @param key - * @param dest - */ -void loclass_permutekey_rev(const uint8_t key[8], uint8_t dest[8]); -/** - * Hash1 takes CSN as input, and determines what bytes in the keytable will be used - * when constructing the K_sel. - * @param csn the CSN used - * @param k output - */ -void loclass_hash1(const uint8_t* csn, uint8_t* k); -void loclass_hash2(uint8_t* key64, uint8_t* outp_keytable); - -#endif diff --git a/applications/external/picopass/lib/loclass/optimized_ikeys.c b/applications/external/picopass/lib/loclass/optimized_ikeys.c deleted file mode 100644 index 1e6f12c56..000000000 --- a/applications/external/picopass/lib/loclass/optimized_ikeys.c +++ /dev/null @@ -1,320 +0,0 @@ -//----------------------------------------------------------------------------- -// Borrowed initially from https://github.com/holiman/loclass -// Copyright (C) 2014 Martin Holst Swende -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// WARNING -// -// THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. -// -// USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL -// PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, -// AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. -// -// THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. -//----------------------------------------------------------------------------- -// It is a reconstruction of the cipher engine used in iClass, and RFID techology. -// -// The implementation is based on the work performed by -// Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and -// Milosch Meriac in the paper "Dismantling IClass". -//----------------------------------------------------------------------------- - -/** -From "Dismantling iclass": - This section describes in detail the built-in key diversification algorithm of iClass. - Besides the obvious purpose of deriving a card key from a master key, this - algorithm intends to circumvent weaknesses in the cipher by preventing the - usage of certain ‘weak’ keys. In order to compute a diversified key, the iClass - reader first encrypts the card identity id with the master key K, using single - DES. The resulting ciphertext is then input to a function called loclass_hash0 which - outputs the diversified key k. - - k = loclass_hash0(DES enc (id, K)) - - Here the DES encryption of id with master key K outputs a cryptogram c - of 64 bits. These 64 bits are divided as c = x, y, z [0] , . . . , z [7] ∈ F 82 × F 82 × (F 62 ) 8 - which is used as input to the loclass_hash0 function. This function introduces some - obfuscation by performing a number of permutations, complement and modulo - operations, see Figure 2.5. Besides that, it checks for and removes patterns like - similar key bytes, which could produce a strong bias in the cipher. Finally, the - output of loclass_hash0 is the diversified card key k = k [0] , . . . , k [7] ∈ (F 82 ) 8 . - -**/ -#include "optimized_ikeys.h" - -#include -#include -#include -#include -#include "optimized_cipherutils.h" - -static const uint8_t loclass_pi[35] = {0x0F, 0x17, 0x1B, 0x1D, 0x1E, 0x27, 0x2B, 0x2D, 0x2E, - 0x33, 0x35, 0x39, 0x36, 0x3A, 0x3C, 0x47, 0x4B, 0x4D, - 0x4E, 0x53, 0x55, 0x56, 0x59, 0x5A, 0x5C, 0x63, 0x65, - 0x66, 0x69, 0x6A, 0x6C, 0x71, 0x72, 0x74, 0x78}; - -/** - * @brief The key diversification algorithm uses 6-bit bytes. - * This implementation uses 64 bit uint to pack seven of them into one - * variable. When they are there, they are placed as follows: - * XXXX XXXX N0 .... N7, occupying the last 48 bits. - * - * This function picks out one from such a collection - * @param all - * @param n bitnumber - * @return - */ -static uint8_t loclass_getSixBitByte(uint64_t c, int n) { - return (c >> (42 - 6 * n)) & 0x3F; -} - -/** - * @brief Puts back a six-bit 'byte' into a uint64_t. - * @param c buffer - * @param z the value to place there - * @param n bitnumber. - */ -static void loclass_pushbackSixBitByte(uint64_t* c, uint8_t z, int n) { - //0x XXXX YYYY ZZZZ ZZZZ ZZZZ - // ^z0 ^z7 - //z0: 1111 1100 0000 0000 - - uint64_t masked = z & 0x3F; - uint64_t eraser = 0x3F; - masked <<= 42 - 6 * n; - eraser <<= 42 - 6 * n; - - //masked <<= 6*n; - //eraser <<= 6*n; - - eraser = ~eraser; - (*c) &= eraser; - (*c) |= masked; -} -/** - * @brief Swaps the z-values. - * If the input value has format XYZ0Z1...Z7, the output will have the format - * XYZ7Z6...Z0 instead - * @param c - * @return - */ -static uint64_t loclass_swapZvalues(uint64_t c) { - uint64_t newz = 0; - loclass_pushbackSixBitByte(&newz, loclass_getSixBitByte(c, 0), 7); - loclass_pushbackSixBitByte(&newz, loclass_getSixBitByte(c, 1), 6); - loclass_pushbackSixBitByte(&newz, loclass_getSixBitByte(c, 2), 5); - loclass_pushbackSixBitByte(&newz, loclass_getSixBitByte(c, 3), 4); - loclass_pushbackSixBitByte(&newz, loclass_getSixBitByte(c, 4), 3); - loclass_pushbackSixBitByte(&newz, loclass_getSixBitByte(c, 5), 2); - loclass_pushbackSixBitByte(&newz, loclass_getSixBitByte(c, 6), 1); - loclass_pushbackSixBitByte(&newz, loclass_getSixBitByte(c, 7), 0); - newz |= (c & 0xFFFF000000000000); - return newz; -} - -/** -* @return 4 six-bit bytes chunked into a uint64_t,as 00..00a0a1a2a3 -*/ -static uint64_t loclass_ck(int i, int j, uint64_t z) { - if(i == 1 && j == -1) { - // loclass_ck(1, −1, z [0] . . . z [3] ) = z [0] . . . z [3] - return z; - } else if(j == -1) { - // loclass_ck(i, −1, z [0] . . . z [3] ) = loclass_ck(i − 1, i − 2, z [0] . . . z [3] ) - return loclass_ck(i - 1, i - 2, z); - } - - if(loclass_getSixBitByte(z, i) == loclass_getSixBitByte(z, j)) { - //loclass_ck(i, j − 1, z [0] . . . z [i] ↠j . . . z [3] ) - uint64_t newz = 0; - int c; - for(c = 0; c < 4; c++) { - uint8_t val = loclass_getSixBitByte(z, c); - if(c == i) - loclass_pushbackSixBitByte(&newz, j, c); - else - loclass_pushbackSixBitByte(&newz, val, c); - } - return loclass_ck(i, j - 1, newz); - } else { - return loclass_ck(i, j - 1, z); - } -} -/** - - Definition 8. - Let the function check : (F 62 ) 8 → (F 62 ) 8 be defined as - check(z [0] . . . z [7] ) = loclass_ck(3, 2, z [0] . . . z [3] ) · loclass_ck(3, 2, z [4] . . . z [7] ) - - where loclass_ck : N × N × (F 62 ) 4 → (F 62 ) 4 is defined as - - loclass_ck(1, −1, z [0] . . . z [3] ) = z [0] . . . z [3] - loclass_ck(i, −1, z [0] . . . z [3] ) = loclass_ck(i − 1, i − 2, z [0] . . . z [3] ) - loclass_ck(i, j, z [0] . . . z [3] ) = - loclass_ck(i, j − 1, z [0] . . . z [i] ↠j . . . z [3] ), if z [i] = z [j] ; - loclass_ck(i, j − 1, z [0] . . . z [3] ), otherwise - - otherwise. -**/ - -static uint64_t loclass_check(uint64_t z) { - //These 64 bits are divided as c = x, y, z [0] , . . . , z [7] - - // loclass_ck(3, 2, z [0] . . . z [3] ) - uint64_t ck1 = loclass_ck(3, 2, z); - - // loclass_ck(3, 2, z [4] . . . z [7] ) - uint64_t ck2 = loclass_ck(3, 2, z << 24); - - //The loclass_ck function will place the values - // in the middle of z. - ck1 &= 0x00000000FFFFFF000000; - ck2 &= 0x00000000FFFFFF000000; - - return ck1 | ck2 >> 24; -} - -static void loclass_permute( - LoclassBitstreamIn_t* p_in, - uint64_t z, - int l, - int r, - LoclassBitstreamOut_t* out) { - if(loclass_bitsLeft(p_in) == 0) return; - - bool pn = loclass_tailBit(p_in); - if(pn) { // pn = 1 - uint8_t zl = loclass_getSixBitByte(z, l); - - loclass_push6bits(out, zl + 1); - loclass_permute(p_in, z, l + 1, r, out); - } else { // otherwise - uint8_t zr = loclass_getSixBitByte(z, r); - - loclass_push6bits(out, zr); - loclass_permute(p_in, z, l, r + 1, out); - } -} - -/** - * @brief - *Definition 11. Let the function loclass_hash0 : F 82 × F 82 × (F 62 ) 8 → (F 82 ) 8 be defined as - * loclass_hash0(x, y, z [0] . . . z [7] ) = k [0] . . . k [7] where - * z'[i] = (z[i] mod (63-i)) + i i = 0...3 - * z'[i+4] = (z[i+4] mod (64-i)) + i i = 0...3 - * ẑ = check(z'); - * @param c - * @param k this is where the diversified key is put (should be 8 bytes) - * @return - */ -void loclass_hash0(uint64_t c, uint8_t k[8]) { - c = loclass_swapZvalues(c); - - //These 64 bits are divided as c = x, y, z [0] , . . . , z [7] - // x = 8 bits - // y = 8 bits - // z0-z7 6 bits each : 48 bits - uint8_t x = (c & 0xFF00000000000000) >> 56; - uint8_t y = (c & 0x00FF000000000000) >> 48; - uint64_t zP = 0; - - for(int n = 0; n < 4; n++) { - uint8_t zn = loclass_getSixBitByte(c, n); - uint8_t zn4 = loclass_getSixBitByte(c, n + 4); - uint8_t _zn = (zn % (63 - n)) + n; - uint8_t _zn4 = (zn4 % (64 - n)) + n; - loclass_pushbackSixBitByte(&zP, _zn, n); - loclass_pushbackSixBitByte(&zP, _zn4, n + 4); - } - - uint64_t zCaret = loclass_check(zP); - uint8_t p = loclass_pi[x % 35]; - - if(x & 1) //Check if x7 is 1 - p = ~p; - - LoclassBitstreamIn_t p_in = {&p, 8, 0}; - uint8_t outbuffer[] = {0, 0, 0, 0, 0, 0, 0, 0}; - LoclassBitstreamOut_t out = {outbuffer, 0, 0}; - loclass_permute(&p_in, zCaret, 0, 4, &out); //returns 48 bits? or 6 8-bytes - - //Out is now a buffer containing six-bit bytes, should be 48 bits - // if all went well - //Shift z-values down onto the lower segment - - uint64_t zTilde = loclass_x_bytes_to_num(outbuffer, sizeof(outbuffer)); - - zTilde >>= 16; - - for(int i = 0; i < 8; i++) { - // the key on index i is first a bit from y - // then six bits from z, - // then a bit from p - - // Init with zeroes - k[i] = 0; - // First, place yi leftmost in k - //k[i] |= (y << i) & 0x80 ; - - // First, place y(7-i) leftmost in k - k[i] |= (y << (7 - i)) & 0x80; - - uint8_t zTilde_i = loclass_getSixBitByte(zTilde, i); - // zTildeI is now on the form 00XXXXXX - // with one leftshift, it'll be - // 0XXXXXX0 - // So after leftshift, we can OR it into k - // However, when doing complement, we need to - // again MASK 0XXXXXX0 (0x7E) - zTilde_i <<= 1; - - //Finally, add bit from p or p-mod - //Shift bit i into rightmost location (mask only after complement) - uint8_t p_i = p >> i & 0x1; - - if(k[i]) { // yi = 1 - k[i] |= ~zTilde_i & 0x7E; - k[i] |= p_i & 1; - k[i] += 1; - - } else { // otherwise - k[i] |= zTilde_i & 0x7E; - k[i] |= (~p_i) & 1; - } - } -} -/** - * @brief Performs Elite-class key diversification - * @param csn - * @param key - * @param div_key - */ -void loclass_diversifyKey(uint8_t* csn, const uint8_t* key, uint8_t* div_key) { - mbedtls_des_context loclass_ctx_enc; - - // Prepare the DES key - mbedtls_des_setkey_enc(&loclass_ctx_enc, key); - - uint8_t crypted_csn[8] = {0}; - - // Calculate DES(CSN, KEY) - mbedtls_des_crypt_ecb(&loclass_ctx_enc, csn, crypted_csn); - - //Calculate HASH0(DES)) - uint64_t c_csn = loclass_x_bytes_to_num(crypted_csn, sizeof(crypted_csn)); - - loclass_hash0(c_csn, div_key); -} diff --git a/applications/external/picopass/lib/loclass/optimized_ikeys.h b/applications/external/picopass/lib/loclass/optimized_ikeys.h deleted file mode 100644 index f2711d31e..000000000 --- a/applications/external/picopass/lib/loclass/optimized_ikeys.h +++ /dev/null @@ -1,66 +0,0 @@ -//----------------------------------------------------------------------------- -// Borrowed initially from https://github.com/holiman/loclass -// More recently from https://github.com/RfidResearchGroup/proxmark3 -// Copyright (C) 2014 Martin Holst Swende -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// WARNING -// -// THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. -// -// USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL -// PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, -// AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. -// -// THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. -//----------------------------------------------------------------------------- -// It is a reconstruction of the cipher engine used in iClass, and RFID techology. -// -// The implementation is based on the work performed by -// Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and -// Milosch Meriac in the paper "Dismantling IClass". -//----------------------------------------------------------------------------- -#ifndef IKEYS_H -#define IKEYS_H - -#include - -/** - * @brief - *Definition 11. Let the function loclass_hash0 : F 82 × F 82 × (F 62 ) 8 → (F 82 ) 8 be defined as - * loclass_hash0(x, y, z [0] . . . z [7] ) = k [0] . . . k [7] where - * z'[i] = (z[i] mod (63-i)) + i i = 0...3 - * z'[i+4] = (z[i+4] mod (64-i)) + i i = 0...3 - * ẑ = check(z'); - * @param c - * @param k this is where the diversified key is put (should be 8 bytes) - * @return - */ -void loclass_hash0(uint64_t c, uint8_t k[8]); -/** - * @brief Performs Elite-class key diversification - * @param csn - * @param key - * @param div_key - */ - -void loclass_diversifyKey(uint8_t* csn, const uint8_t* key, uint8_t* div_key); -/** - * @brief Permutes a key from standard NIST format to Iclass specific format - * @param key - * @param dest - */ - -#endif // IKEYS_H diff --git a/applications/external/picopass/picopass.c b/applications/external/picopass/picopass.c deleted file mode 100644 index 6737d8077..000000000 --- a/applications/external/picopass/picopass.c +++ /dev/null @@ -1,212 +0,0 @@ -#include "picopass_i.h" - -#define TAG "PicoPass" - -bool picopass_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - Picopass* picopass = context; - return scene_manager_handle_custom_event(picopass->scene_manager, event); -} - -bool picopass_back_event_callback(void* context) { - furi_assert(context); - Picopass* picopass = context; - return scene_manager_handle_back_event(picopass->scene_manager); -} - -void picopass_tick_event_callback(void* context) { - furi_assert(context); - Picopass* picopass = context; - scene_manager_handle_tick_event(picopass->scene_manager); -} - -Picopass* picopass_alloc() { - Picopass* picopass = malloc(sizeof(Picopass)); - - picopass->worker = picopass_worker_alloc(); - picopass->view_dispatcher = view_dispatcher_alloc(); - picopass->scene_manager = scene_manager_alloc(&picopass_scene_handlers, picopass); - view_dispatcher_enable_queue(picopass->view_dispatcher); - view_dispatcher_set_event_callback_context(picopass->view_dispatcher, picopass); - view_dispatcher_set_custom_event_callback( - picopass->view_dispatcher, picopass_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - picopass->view_dispatcher, picopass_back_event_callback); - view_dispatcher_set_tick_event_callback( - picopass->view_dispatcher, picopass_tick_event_callback, 100); - - // Picopass device - picopass->dev = picopass_device_alloc(); - - // Open GUI record - picopass->gui = furi_record_open(RECORD_GUI); - view_dispatcher_attach_to_gui( - picopass->view_dispatcher, picopass->gui, ViewDispatcherTypeFullscreen); - - // Open Notification record - picopass->notifications = furi_record_open(RECORD_NOTIFICATION); - - // Submenu - picopass->submenu = submenu_alloc(); - view_dispatcher_add_view( - picopass->view_dispatcher, PicopassViewMenu, submenu_get_view(picopass->submenu)); - - // Popup - picopass->popup = popup_alloc(); - view_dispatcher_add_view( - picopass->view_dispatcher, PicopassViewPopup, popup_get_view(picopass->popup)); - - // Loading - picopass->loading = loading_alloc(); - view_dispatcher_add_view( - picopass->view_dispatcher, PicopassViewLoading, loading_get_view(picopass->loading)); - - // Text Input - picopass->text_input = text_input_alloc(); - view_dispatcher_add_view( - picopass->view_dispatcher, - PicopassViewTextInput, - text_input_get_view(picopass->text_input)); - - // Custom Widget - picopass->widget = widget_alloc(); - view_dispatcher_add_view( - picopass->view_dispatcher, PicopassViewWidget, widget_get_view(picopass->widget)); - - picopass->dict_attack = dict_attack_alloc(); - view_dispatcher_add_view( - picopass->view_dispatcher, - PicopassViewDictAttack, - dict_attack_get_view(picopass->dict_attack)); - - return picopass; -} - -void picopass_free(Picopass* picopass) { - furi_assert(picopass); - - // Picopass device - picopass_device_free(picopass->dev); - picopass->dev = NULL; - - // Submenu - view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewMenu); - submenu_free(picopass->submenu); - - // Popup - view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewPopup); - popup_free(picopass->popup); - - // Loading - view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewLoading); - loading_free(picopass->loading); - - // TextInput - view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewTextInput); - text_input_free(picopass->text_input); - - // Custom Widget - view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewWidget); - widget_free(picopass->widget); - - view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewDictAttack); - dict_attack_free(picopass->dict_attack); - - // Worker - picopass_worker_stop(picopass->worker); - picopass_worker_free(picopass->worker); - - // View Dispatcher - view_dispatcher_free(picopass->view_dispatcher); - - // Scene Manager - scene_manager_free(picopass->scene_manager); - - // GUI - furi_record_close(RECORD_GUI); - picopass->gui = NULL; - - // Notifications - furi_record_close(RECORD_NOTIFICATION); - picopass->notifications = NULL; - - free(picopass); -} - -void picopass_text_store_set(Picopass* picopass, const char* text, ...) { - va_list args; - va_start(args, text); - - vsnprintf(picopass->text_store, sizeof(picopass->text_store), text, args); - - va_end(args); -} - -void picopass_text_store_clear(Picopass* picopass) { - memset(picopass->text_store, 0, sizeof(picopass->text_store)); -} - -static const NotificationSequence picopass_sequence_blink_start_cyan = { - &message_blink_start_10, - &message_blink_set_color_cyan, - &message_do_not_reset, - NULL, -}; - -static const NotificationSequence picopass_sequence_blink_stop = { - &message_blink_stop, - NULL, -}; - -void picopass_blink_start(Picopass* picopass) { - notification_message(picopass->notifications, &picopass_sequence_blink_start_cyan); -} - -void picopass_blink_stop(Picopass* picopass) { - notification_message(picopass->notifications, &picopass_sequence_blink_stop); -} - -void picopass_show_loading_popup(void* context, bool show) { - Picopass* picopass = context; - TaskHandle_t timer_task = xTaskGetHandle(configTIMER_SERVICE_TASK_NAME); - - if(show) { - // Raise timer priority so that animations can play - vTaskPrioritySet(timer_task, configMAX_PRIORITIES - 1); - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewLoading); - } else { - // Restore default timer priority - vTaskPrioritySet(timer_task, configTIMER_TASK_PRIORITY); - } -} - -static void picopass_migrate_from_old_folder() { - Storage* storage = furi_record_open(RECORD_STORAGE); - storage_common_migrate(storage, "/ext/picopass", STORAGE_APP_DATA_PATH_PREFIX); - furi_record_close(RECORD_STORAGE); -} - -bool picopass_is_memset(const uint8_t* data, const uint8_t pattern, size_t size) { - bool result = size > 0; - while(size > 0) { - result &= (*data == pattern); - data++; - size--; - } - return result; -} - -int32_t picopass_app(void* p) { - UNUSED(p); - picopass_migrate_from_old_folder(); - - Picopass* picopass = picopass_alloc(); - - scene_manager_next_scene(picopass->scene_manager, PicopassSceneStart); - - view_dispatcher_run(picopass->view_dispatcher); - - picopass_free(picopass); - - return 0; -} diff --git a/applications/external/picopass/picopass.h b/applications/external/picopass/picopass.h deleted file mode 100644 index a1a87d7f8..000000000 --- a/applications/external/picopass/picopass.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -typedef struct Picopass Picopass; diff --git a/applications/external/picopass/picopass_device.c b/applications/external/picopass/picopass_device.c deleted file mode 100644 index de43b0bb7..000000000 --- a/applications/external/picopass/picopass_device.c +++ /dev/null @@ -1,380 +0,0 @@ -#include "picopass_device.h" - -#include -#include -#include - -#define TAG "PicopassDevice" - -static const char* picopass_file_header = "Flipper Picopass device"; -static const uint32_t picopass_file_version = 1; - -const uint8_t picopass_iclass_decryptionkey[] = - {0xb4, 0x21, 0x2c, 0xca, 0xb7, 0xed, 0x21, 0x0f, 0x7b, 0x93, 0xd4, 0x59, 0x39, 0xc7, 0xdd, 0x36}; - -PicopassDevice* picopass_device_alloc() { - PicopassDevice* picopass_dev = malloc(sizeof(PicopassDevice)); - picopass_dev->dev_data.pacs.legacy = false; - picopass_dev->dev_data.pacs.se_enabled = false; - picopass_dev->dev_data.pacs.elite_kdf = false; - picopass_dev->dev_data.pacs.pin_length = 0; - picopass_dev->storage = furi_record_open(RECORD_STORAGE); - picopass_dev->dialogs = furi_record_open(RECORD_DIALOGS); - picopass_dev->load_path = furi_string_alloc(); - return picopass_dev; -} - -void picopass_device_set_name(PicopassDevice* dev, const char* name) { - furi_assert(dev); - - strlcpy(dev->dev_name, name, PICOPASS_DEV_NAME_MAX_LEN); -} - -static bool picopass_device_save_file( - PicopassDevice* dev, - const char* dev_name, - const char* folder, - const char* extension, - bool use_load_path) { - furi_assert(dev); - - bool saved = false; - FlipperFormat* file = flipper_format_file_alloc(dev->storage); - PicopassPacs* pacs = &dev->dev_data.pacs; - PicopassBlock* AA1 = dev->dev_data.AA1; - FuriString* temp_str; - temp_str = furi_string_alloc(); - - do { - if(use_load_path && !furi_string_empty(dev->load_path)) { - // Get directory name - path_extract_dirname(furi_string_get_cstr(dev->load_path), temp_str); - // Make path to file to save - furi_string_cat_printf(temp_str, "/%s%s", dev_name, extension); - } else { - // First remove picopass device file if it was saved - furi_string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); - } - // Open file - if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break; - - if(dev->format == PicopassDeviceSaveFormatHF) { - uint32_t fc = pacs->record.FacilityCode; - uint32_t cn = pacs->record.CardNumber; - // Write header - if(!flipper_format_write_header_cstr(file, picopass_file_header, picopass_file_version)) - break; - if(pacs->record.valid) { - if(!flipper_format_write_uint32(file, "Facility Code", &fc, 1)) break; - if(!flipper_format_write_uint32(file, "Card Number", &cn, 1)) break; - if(!flipper_format_write_hex( - file, "Credential", pacs->credential, PICOPASS_BLOCK_LEN)) - break; - if(pacs->pin_length > 0) { - if(!flipper_format_write_hex(file, "PIN\t\t", pacs->pin0, PICOPASS_BLOCK_LEN)) - break; - if(!flipper_format_write_hex( - file, "PIN(cont.)\t", pacs->pin1, PICOPASS_BLOCK_LEN)) - break; - } - } - // TODO: Add elite - if(!flipper_format_write_comment_cstr(file, "Picopass blocks")) break; - bool block_saved = true; - - size_t app_limit = AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[0] < PICOPASS_MAX_APP_LIMIT ? - AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[0] : - PICOPASS_MAX_APP_LIMIT; - for(size_t i = 0; i < app_limit; i++) { - furi_string_printf(temp_str, "Block %d", i); - if(!flipper_format_write_hex( - file, furi_string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) { - block_saved = false; - break; - } - } - if(!block_saved) break; - } else if(dev->format == PicopassDeviceSaveFormatLF) { - const char* lf_header = "Flipper RFID key"; - // Write header - if(!flipper_format_write_header_cstr(file, lf_header, 1)) break; - if(!flipper_format_write_comment_cstr( - file, - "This was generated from the Picopass plugin and may not match current lfrfid")) - break; - // When lfrfid supports more formats, update this - if(!flipper_format_write_string_cstr(file, "Key type", "H10301")) break; - uint8_t H10301[3] = {0}; - H10301[0] = pacs->record.FacilityCode; - H10301[1] = pacs->record.CardNumber >> 8; - H10301[2] = pacs->record.CardNumber & 0x00FF; - if(!flipper_format_write_hex(file, "Data", H10301, 3)) break; - } - saved = true; - } while(0); - - if(!saved) { - dialog_message_show_storage_error(dev->dialogs, "Can not save\nfile"); - } - furi_string_free(temp_str); - flipper_format_free(file); - return saved; -} - -bool picopass_device_save(PicopassDevice* dev, const char* dev_name) { - if(dev->format == PicopassDeviceSaveFormatHF) { - return picopass_device_save_file( - dev, dev_name, STORAGE_APP_DATA_PATH_PREFIX, PICOPASS_APP_EXTENSION, true); - } else if(dev->format == PicopassDeviceSaveFormatLF) { - return picopass_device_save_file(dev, dev_name, ANY_PATH("lfrfid"), ".rfid", true); - } - - return false; -} - -static bool picopass_device_load_data(PicopassDevice* dev, FuriString* path, bool show_dialog) { - bool parsed = false; - FlipperFormat* file = flipper_format_file_alloc(dev->storage); - PicopassBlock* AA1 = dev->dev_data.AA1; - PicopassPacs* pacs = &dev->dev_data.pacs; - FuriString* temp_str; - temp_str = furi_string_alloc(); - bool deprecated_version = false; - - if(dev->loading_cb) { - dev->loading_cb(dev->loading_cb_ctx, true); - } - - do { - if(!flipper_format_file_open_existing(file, furi_string_get_cstr(path))) break; - - // Read and verify file header - uint32_t version = 0; - if(!flipper_format_read_header(file, temp_str, &version)) break; - if(furi_string_cmp_str(temp_str, picopass_file_header) || - (version != picopass_file_version)) { - deprecated_version = true; - break; - } - - // Parse header blocks - bool block_read = true; - for(size_t i = 0; i < 6; i++) { - furi_string_printf(temp_str, "Block %d", i); - if(!flipper_format_read_hex( - file, furi_string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) { - block_read = false; - break; - } - } - - size_t app_limit = AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[0]; - // Fix for unpersonalized cards that have app_limit set to 0xFF - if(app_limit > PICOPASS_MAX_APP_LIMIT) app_limit = PICOPASS_MAX_APP_LIMIT; - for(size_t i = 6; i < app_limit; i++) { - furi_string_printf(temp_str, "Block %d", i); - if(!flipper_format_read_hex( - file, furi_string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) { - block_read = false; - break; - } - } - if(!block_read) break; - - if(picopass_device_parse_credential(AA1, pacs) != ERR_NONE) break; - if(picopass_device_parse_wiegand(pacs->credential, &pacs->record) != ERR_NONE) break; - - parsed = true; - } while(false); - - if(dev->loading_cb) { - dev->loading_cb(dev->loading_cb_ctx, false); - } - - if((!parsed) && (show_dialog)) { - if(deprecated_version) { - dialog_message_show_storage_error(dev->dialogs, "File format deprecated"); - } else { - dialog_message_show_storage_error(dev->dialogs, "Can not parse\nfile"); - } - } - - furi_string_free(temp_str); - flipper_format_free(file); - - return parsed; -} - -void picopass_device_clear(PicopassDevice* dev) { - furi_assert(dev); - - picopass_device_data_clear(&dev->dev_data); - memset(&dev->dev_data, 0, sizeof(dev->dev_data)); - dev->format = PicopassDeviceSaveFormatHF; - furi_string_reset(dev->load_path); -} - -void picopass_device_free(PicopassDevice* picopass_dev) { - furi_assert(picopass_dev); - picopass_device_clear(picopass_dev); - furi_record_close(RECORD_STORAGE); - furi_record_close(RECORD_DIALOGS); - furi_string_free(picopass_dev->load_path); - free(picopass_dev); -} - -bool picopass_file_select(PicopassDevice* dev) { - furi_assert(dev); - - FuriString* picopass_app_folder; - picopass_app_folder = furi_string_alloc_set(STORAGE_APP_DATA_PATH_PREFIX); - - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, PICOPASS_APP_EXTENSION, &I_Nfc_10px); - browser_options.base_path = STORAGE_APP_DATA_PATH_PREFIX; - - bool res = dialog_file_browser_show( - dev->dialogs, dev->load_path, picopass_app_folder, &browser_options); - - furi_string_free(picopass_app_folder); - if(res) { - FuriString* filename; - filename = furi_string_alloc(); - path_extract_filename(dev->load_path, filename, true); - strncpy(dev->dev_name, furi_string_get_cstr(filename), PICOPASS_DEV_NAME_MAX_LEN); - res = picopass_device_load_data(dev, dev->load_path, true); - if(res) { - picopass_device_set_name(dev, dev->dev_name); - } - furi_string_free(filename); - } - - return res; -} - -void picopass_device_data_clear(PicopassDeviceData* dev_data) { - for(size_t i = 0; i < PICOPASS_MAX_APP_LIMIT; i++) { - memset(dev_data->AA1[i].data, 0, sizeof(dev_data->AA1[i].data)); - } - dev_data->pacs.legacy = false; - dev_data->pacs.se_enabled = false; - dev_data->pacs.elite_kdf = false; - dev_data->pacs.pin_length = 0; -} - -bool picopass_device_delete(PicopassDevice* dev, bool use_load_path) { - furi_assert(dev); - - bool deleted = false; - FuriString* file_path; - file_path = furi_string_alloc(); - - do { - // Delete original file - if(use_load_path && !furi_string_empty(dev->load_path)) { - furi_string_set(file_path, dev->load_path); - } else { - furi_string_printf( - file_path, APP_DATA_PATH("%s%s"), dev->dev_name, PICOPASS_APP_EXTENSION); - } - if(!storage_simply_remove(dev->storage, furi_string_get_cstr(file_path))) break; - deleted = true; - } while(0); - - if(!deleted) { - dialog_message_show_storage_error(dev->dialogs, "Can not remove file"); - } - - furi_string_free(file_path); - return deleted; -} - -void picopass_device_set_loading_callback( - PicopassDevice* dev, - PicopassLoadingCallback callback, - void* context) { - furi_assert(dev); - - dev->loading_cb = callback; - dev->loading_cb_ctx = context; -} - -ReturnCode picopass_device_decrypt(uint8_t* enc_data, uint8_t* dec_data) { - uint8_t key[32] = {0}; - memcpy(key, picopass_iclass_decryptionkey, sizeof(picopass_iclass_decryptionkey)); - mbedtls_des3_context ctx; - mbedtls_des3_init(&ctx); - mbedtls_des3_set2key_dec(&ctx, key); - mbedtls_des3_crypt_ecb(&ctx, enc_data, dec_data); - mbedtls_des3_free(&ctx); - return ERR_NONE; -} - -ReturnCode picopass_device_parse_credential(PicopassBlock* AA1, PicopassPacs* pacs) { - ReturnCode err; - - pacs->biometrics = AA1[6].data[4]; - pacs->pin_length = AA1[6].data[6] & 0x0F; - pacs->encryption = AA1[6].data[7]; - - if(pacs->encryption == PicopassDeviceEncryption3DES) { - FURI_LOG_D(TAG, "3DES Encrypted"); - err = picopass_device_decrypt(AA1[7].data, pacs->credential); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "decrypt error %d", err); - return err; - } - - err = picopass_device_decrypt(AA1[8].data, pacs->pin0); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "decrypt error %d", err); - return err; - } - - err = picopass_device_decrypt(AA1[9].data, pacs->pin1); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "decrypt error %d", err); - return err; - } - } else if(pacs->encryption == PicopassDeviceEncryptionNone) { - FURI_LOG_D(TAG, "No Encryption"); - memcpy(pacs->credential, AA1[7].data, PICOPASS_BLOCK_LEN); - memcpy(pacs->pin0, AA1[8].data, PICOPASS_BLOCK_LEN); - memcpy(pacs->pin1, AA1[9].data, PICOPASS_BLOCK_LEN); - } else if(pacs->encryption == PicopassDeviceEncryptionDES) { - FURI_LOG_D(TAG, "DES Encrypted"); - } else { - FURI_LOG_D(TAG, "Unknown encryption"); - } - - pacs->sio = (AA1[10].data[0] == 0x30); // rough check - - return ERR_NONE; -} - -ReturnCode picopass_device_parse_wiegand(uint8_t* data, PicopassWiegandRecord* record) { - uint32_t* halves = (uint32_t*)data; - if(halves[0] == 0) { - uint8_t leading0s = __builtin_clz(REVERSE_BYTES_U32(halves[1])); - record->bitLength = 31 - leading0s; - } else { - uint8_t leading0s = __builtin_clz(REVERSE_BYTES_U32(halves[0])); - record->bitLength = 63 - leading0s; - } - FURI_LOG_D(TAG, "bitLength: %d", record->bitLength); - - if(record->bitLength == 26) { - uint8_t* v4 = data + 4; - uint32_t bot = v4[3] | (v4[2] << 8) | (v4[1] << 16) | (v4[0] << 24); - - record->CardNumber = (bot >> 1) & 0xFFFF; - record->FacilityCode = (bot >> 17) & 0xFF; - FURI_LOG_D(TAG, "FC: %u CN: %u", record->FacilityCode, record->CardNumber); - record->valid = true; - } else { - record->CardNumber = 0; - record->FacilityCode = 0; - record->valid = false; - } - return ERR_NONE; -} diff --git a/applications/external/picopass/picopass_device.h b/applications/external/picopass/picopass_device.h deleted file mode 100644 index b45df346c..000000000 --- a/applications/external/picopass/picopass_device.h +++ /dev/null @@ -1,117 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include "rfal_picopass.h" -#include -#include -#include "helpers/iclass_elite_dict.h" - -#define PICOPASS_DEV_NAME_MAX_LEN 22 -#define PICOPASS_READER_DATA_MAX_SIZE 64 -#define PICOPASS_BLOCK_LEN 8 -#define PICOPASS_MAX_APP_LIMIT 32 - -#define PICOPASS_CSN_BLOCK_INDEX 0 -#define PICOPASS_CONFIG_BLOCK_INDEX 1 -#define PICOPASS_EPURSE_BLOCK_INDEX 2 -#define PICOPASS_KD_BLOCK_INDEX 3 -#define PICOPASS_KC_BLOCK_INDEX 4 -#define PICOPASS_AIA_BLOCK_INDEX 5 -#define PICOPASS_PACS_CFG_BLOCK_INDEX 6 - -#define PICOPASS_APP_EXTENSION ".picopass" -#define PICOPASS_APP_SHADOW_EXTENSION ".pas" - -#define PICOPASS_DICT_KEY_BATCH_SIZE 10 - -typedef void (*PicopassLoadingCallback)(void* context, bool state); - -typedef struct { - IclassEliteDict* dict; - IclassEliteDictType type; - uint8_t current_sector; -} IclassEliteDictAttackData; - -typedef enum { - PicopassDeviceEncryptionUnknown = 0, - PicopassDeviceEncryptionNone = 0x14, - PicopassDeviceEncryptionDES = 0x15, - PicopassDeviceEncryption3DES = 0x17, -} PicopassEncryption; - -typedef enum { - PicopassDeviceSaveFormatHF, - PicopassDeviceSaveFormatLF, -} PicopassDeviceSaveFormat; - -typedef struct { - bool valid; - uint8_t bitLength; - uint8_t FacilityCode; - uint16_t CardNumber; -} PicopassWiegandRecord; - -typedef struct { - bool legacy; - bool se_enabled; - bool sio; - bool biometrics; - uint8_t key[8]; - bool elite_kdf; - uint8_t pin_length; - PicopassEncryption encryption; - uint8_t credential[8]; - uint8_t pin0[8]; - uint8_t pin1[8]; - PicopassWiegandRecord record; -} PicopassPacs; - -typedef struct { - uint8_t data[PICOPASS_BLOCK_LEN]; -} PicopassBlock; - -typedef struct { - PicopassBlock AA1[PICOPASS_MAX_APP_LIMIT]; - PicopassPacs pacs; - IclassEliteDictAttackData iclass_elite_dict_attack_data; -} PicopassDeviceData; - -typedef struct { - Storage* storage; - DialogsApp* dialogs; - PicopassDeviceData dev_data; - char dev_name[PICOPASS_DEV_NAME_MAX_LEN + 1]; - FuriString* load_path; - PicopassDeviceSaveFormat format; - PicopassLoadingCallback loading_cb; - void* loading_cb_ctx; -} PicopassDevice; - -PicopassDevice* picopass_device_alloc(); - -void picopass_device_free(PicopassDevice* picopass_dev); - -void picopass_device_set_name(PicopassDevice* dev, const char* name); - -bool picopass_device_save(PicopassDevice* dev, const char* dev_name); - -bool picopass_file_select(PicopassDevice* dev); - -void picopass_device_data_clear(PicopassDeviceData* dev_data); - -void picopass_device_clear(PicopassDevice* dev); - -bool picopass_device_delete(PicopassDevice* dev, bool use_load_path); - -void picopass_device_set_loading_callback( - PicopassDevice* dev, - PicopassLoadingCallback callback, - void* context); - -ReturnCode picopass_device_parse_credential(PicopassBlock* AA1, PicopassPacs* pacs); -ReturnCode picopass_device_parse_wiegand(uint8_t* data, PicopassWiegandRecord* record); diff --git a/applications/external/picopass/picopass_i.h b/applications/external/picopass/picopass_i.h deleted file mode 100644 index 9147cfa0c..000000000 --- a/applications/external/picopass/picopass_i.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -#include "picopass.h" -#include "picopass_worker.h" -#include "picopass_device.h" - -#include "rfal_picopass.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "scenes/picopass_scene.h" -#include "views/dict_attack.h" - -#include -#include -#include - -#define PICOPASS_TEXT_STORE_SIZE 128 - -enum PicopassCustomEvent { - // Reserve first 100 events for button types and indexes, starting from 0 - PicopassCustomEventReserved = 100, - - PicopassCustomEventViewExit, - PicopassCustomEventWorkerExit, - PicopassCustomEventByteInputDone, - PicopassCustomEventTextInputDone, - PicopassCustomEventDictAttackSkip, -}; - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -struct Picopass { - PicopassWorker* worker; - ViewDispatcher* view_dispatcher; - Gui* gui; - NotificationApp* notifications; - SceneManager* scene_manager; - PicopassDevice* dev; - - char text_store[PICOPASS_TEXT_STORE_SIZE + 1]; - FuriString* text_box_store; - - // Common Views - Submenu* submenu; - Popup* popup; - Loading* loading; - TextInput* text_input; - Widget* widget; - DictAttack* dict_attack; -}; - -typedef enum { - PicopassViewMenu, - PicopassViewPopup, - PicopassViewLoading, - PicopassViewTextInput, - PicopassViewWidget, - PicopassViewDictAttack, -} PicopassView; - -Picopass* picopass_alloc(); - -void picopass_text_store_set(Picopass* picopass, const char* text, ...); - -void picopass_text_store_clear(Picopass* picopass); - -void picopass_blink_start(Picopass* picopass); - -void picopass_blink_stop(Picopass* picopass); - -void picopass_show_loading_popup(void* context, bool show); - -/** Check if memory is set to pattern - * - * @warning zero size will return false - * - * @param[in] data Pointer to the byte array - * @param[in] pattern The pattern - * @param[in] size The byte array size - * - * @return True if memory is set to pattern, false otherwise - */ -bool picopass_is_memset(const uint8_t* data, const uint8_t pattern, size_t size); diff --git a/applications/external/picopass/picopass_keys.c b/applications/external/picopass/picopass_keys.c deleted file mode 100644 index 43dfc6312..000000000 --- a/applications/external/picopass/picopass_keys.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "picopass_keys.h" - -const uint8_t picopass_iclass_key[] = {0xaf, 0xa7, 0x85, 0xa7, 0xda, 0xb3, 0x33, 0x78}; -const uint8_t picopass_factory_credit_key[] = {0x76, 0x65, 0x54, 0x43, 0x32, 0x21, 0x10, 0x00}; -const uint8_t picopass_factory_debit_key[] = {0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87}; -const uint8_t picopass_xice_key[] = {0x20, 0x20, 0x66, 0x66, 0x66, 0x66, 0x88, 0x88}; -const uint8_t picopass_xicl_key[] = {0x20, 0x20, 0x66, 0x66, 0x66, 0x66, 0x88, 0x88}; -const uint8_t picopass_xics_key[] = {0x66, 0x66, 0x20, 0x20, 0x66, 0x66, 0x88, 0x88}; diff --git a/applications/external/picopass/picopass_keys.h b/applications/external/picopass/picopass_keys.h deleted file mode 100644 index 2b5dba661..000000000 --- a/applications/external/picopass/picopass_keys.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "picopass_device.h" - -extern const uint8_t picopass_iclass_key[PICOPASS_BLOCK_LEN]; -extern const uint8_t picopass_factory_credit_key[PICOPASS_BLOCK_LEN]; -extern const uint8_t picopass_factory_debit_key[PICOPASS_BLOCK_LEN]; -extern const uint8_t picopass_xice_key[PICOPASS_BLOCK_LEN]; -extern const uint8_t picopass_xicl_key[PICOPASS_BLOCK_LEN]; -extern const uint8_t picopass_xics_key[PICOPASS_BLOCK_LEN]; diff --git a/applications/external/picopass/picopass_worker.c b/applications/external/picopass/picopass_worker.c deleted file mode 100644 index 6301704ca..000000000 --- a/applications/external/picopass/picopass_worker.c +++ /dev/null @@ -1,752 +0,0 @@ -#include "picopass_worker_i.h" - -#include - -#define TAG "PicopassWorker" - -static void picopass_worker_enable_field() { - furi_hal_nfc_ll_txrx_on(); - furi_hal_nfc_exit_sleep(); - furi_hal_nfc_ll_poll(); -} - -static ReturnCode picopass_worker_disable_field(ReturnCode rc) { - furi_hal_nfc_ll_txrx_off(); - furi_hal_nfc_start_sleep(); - return rc; -} - -/***************************** Picopass Worker API *******************************/ - -PicopassWorker* picopass_worker_alloc() { - PicopassWorker* picopass_worker = malloc(sizeof(PicopassWorker)); - - // Worker thread attributes - picopass_worker->thread = - furi_thread_alloc_ex("PicopassWorker", 8 * 1024, picopass_worker_task, picopass_worker); - - picopass_worker->callback = NULL; - picopass_worker->context = NULL; - picopass_worker->storage = furi_record_open(RECORD_STORAGE); - - picopass_worker_change_state(picopass_worker, PicopassWorkerStateReady); - - return picopass_worker; -} - -void picopass_worker_free(PicopassWorker* picopass_worker) { - furi_assert(picopass_worker); - - furi_thread_free(picopass_worker->thread); - - furi_record_close(RECORD_STORAGE); - - free(picopass_worker); -} - -PicopassWorkerState picopass_worker_get_state(PicopassWorker* picopass_worker) { - return picopass_worker->state; -} - -void picopass_worker_start( - PicopassWorker* picopass_worker, - PicopassWorkerState state, - PicopassDeviceData* dev_data, - PicopassWorkerCallback callback, - void* context) { - furi_assert(picopass_worker); - furi_assert(dev_data); - - picopass_worker->callback = callback; - picopass_worker->context = context; - picopass_worker->dev_data = dev_data; - picopass_worker_change_state(picopass_worker, state); - furi_thread_start(picopass_worker->thread); -} - -void picopass_worker_stop(PicopassWorker* picopass_worker) { - furi_assert(picopass_worker); - furi_assert(picopass_worker->thread); - - if(furi_thread_get_state(picopass_worker->thread) != FuriThreadStateStopped) { - picopass_worker_change_state(picopass_worker, PicopassWorkerStateStop); - furi_thread_join(picopass_worker->thread); - } -} - -void picopass_worker_change_state(PicopassWorker* picopass_worker, PicopassWorkerState state) { - picopass_worker->state = state; -} - -/***************************** Picopass Worker Thread *******************************/ - -ReturnCode picopass_detect_card(int timeout) { - UNUSED(timeout); - - ReturnCode err; - - err = rfalPicoPassPollerInitialize(); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerInitialize error %d", err); - return err; - } - - err = rfalFieldOnAndStartGT(); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalFieldOnAndStartGT error %d", err); - return err; - } - - err = rfalPicoPassPollerCheckPresence(); - if(err != ERR_RF_COLLISION) { - FURI_LOG_E(TAG, "rfalPicoPassPollerCheckPresence error %d", err); - return err; - } - - return ERR_NONE; -} - -ReturnCode picopass_read_preauth(PicopassBlock* AA1) { - rfalPicoPassIdentifyRes idRes; - rfalPicoPassSelectRes selRes; - - ReturnCode err; - - err = rfalPicoPassPollerIdentify(&idRes); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerIdentify error %d", err); - return err; - } - - err = rfalPicoPassPollerSelect(idRes.CSN, &selRes); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerSelect error %d", err); - return err; - } - - memcpy(AA1[PICOPASS_CSN_BLOCK_INDEX].data, selRes.CSN, sizeof(selRes.CSN)); - FURI_LOG_D( - TAG, - "csn %02x%02x%02x%02x%02x%02x%02x%02x", - AA1[PICOPASS_CSN_BLOCK_INDEX].data[0], - AA1[PICOPASS_CSN_BLOCK_INDEX].data[1], - AA1[PICOPASS_CSN_BLOCK_INDEX].data[2], - AA1[PICOPASS_CSN_BLOCK_INDEX].data[3], - AA1[PICOPASS_CSN_BLOCK_INDEX].data[4], - AA1[PICOPASS_CSN_BLOCK_INDEX].data[5], - AA1[PICOPASS_CSN_BLOCK_INDEX].data[6], - AA1[PICOPASS_CSN_BLOCK_INDEX].data[7]); - - rfalPicoPassReadBlockRes cfg = {0}; - rfalPicoPassPollerReadBlock(PICOPASS_CONFIG_BLOCK_INDEX, &cfg); - memcpy(AA1[PICOPASS_CONFIG_BLOCK_INDEX].data, cfg.data, sizeof(cfg.data)); - FURI_LOG_D( - TAG, - "config %02x%02x%02x%02x%02x%02x%02x%02x", - AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[0], - AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[1], - AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[2], - AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[3], - AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[4], - AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[5], - AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[6], - AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[7]); - - rfalPicoPassReadBlockRes aia; - rfalPicoPassPollerReadBlock(PICOPASS_AIA_BLOCK_INDEX, &aia); - memcpy(AA1[PICOPASS_AIA_BLOCK_INDEX].data, aia.data, sizeof(aia.data)); - FURI_LOG_D( - TAG, - "aia %02x%02x%02x%02x%02x%02x%02x%02x", - AA1[PICOPASS_AIA_BLOCK_INDEX].data[0], - AA1[PICOPASS_AIA_BLOCK_INDEX].data[1], - AA1[PICOPASS_AIA_BLOCK_INDEX].data[2], - AA1[PICOPASS_AIA_BLOCK_INDEX].data[3], - AA1[PICOPASS_AIA_BLOCK_INDEX].data[4], - AA1[PICOPASS_AIA_BLOCK_INDEX].data[5], - AA1[PICOPASS_AIA_BLOCK_INDEX].data[6], - AA1[PICOPASS_AIA_BLOCK_INDEX].data[7]); - - return ERR_NONE; -} - -static ReturnCode - picopass_auth_dict(PicopassWorker* picopass_worker, IclassEliteDictType dict_type) { - rfalPicoPassReadCheckRes rcRes; - rfalPicoPassCheckRes chkRes; - bool elite = (dict_type != IclassStandardDictTypeFlipper); - - PicopassDeviceData* dev_data = picopass_worker->dev_data; - PicopassBlock* AA1 = dev_data->AA1; - PicopassPacs* pacs = &dev_data->pacs; - - uint8_t* csn = AA1[PICOPASS_CSN_BLOCK_INDEX].data; - uint8_t* div_key = AA1[PICOPASS_KD_BLOCK_INDEX].data; - - ReturnCode err = ERR_PARAM; - - uint8_t mac[4] = {0}; - uint8_t ccnr[12] = {0}; - - size_t index = 0; - uint8_t key[PICOPASS_BLOCK_LEN] = {0}; - - if(!iclass_elite_dict_check_presence(dict_type)) { - FURI_LOG_E(TAG, "Dictionary not found"); - return ERR_PARAM; - } - - IclassEliteDict* dict = iclass_elite_dict_alloc(dict_type); - if(!dict) { - FURI_LOG_E(TAG, "Dictionary not allocated"); - return ERR_PARAM; - } - - FURI_LOG_D(TAG, "Loaded %lu keys", iclass_elite_dict_get_total_keys(dict)); - while(iclass_elite_dict_get_next_key(dict, key)) { - FURI_LOG_D( - TAG, - "Try to %s auth with key %zu %02x%02x%02x%02x%02x%02x%02x%02x", - elite ? "elite" : "standard", - index++, - key[0], - key[1], - key[2], - key[3], - key[4], - key[5], - key[6], - key[7]); - - err = rfalPicoPassPollerReadCheck(&rcRes); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerReadCheck error %d", err); - break; - } - memcpy(ccnr, rcRes.CCNR, sizeof(rcRes.CCNR)); // last 4 bytes left 0 - - loclass_iclass_calc_div_key(csn, key, div_key, elite); - loclass_opt_doReaderMAC(ccnr, div_key, mac); - - err = rfalPicoPassPollerCheck(mac, &chkRes); - if(err == ERR_NONE) { - memcpy(pacs->key, key, PICOPASS_BLOCK_LEN); - break; - } - - if(picopass_worker->state != PicopassWorkerStateDetect) break; - } - - iclass_elite_dict_free(dict); - - return err; -} - -ReturnCode picopass_auth(PicopassWorker* picopass_worker) { - ReturnCode err; - - FURI_LOG_I(TAG, "Starting system dictionary attack [Standard KDF]"); - err = picopass_auth_dict(picopass_worker, IclassStandardDictTypeFlipper); - if(err == ERR_NONE) { - return ERR_NONE; - } - - FURI_LOG_I(TAG, "Starting user dictionary attack [Elite KDF]"); - err = picopass_auth_dict(picopass_worker, IclassEliteDictTypeUser); - if(err == ERR_NONE) { - return ERR_NONE; - } - - FURI_LOG_I(TAG, "Starting system dictionary attack [Elite KDF]"); - err = picopass_auth_dict(picopass_worker, IclassEliteDictTypeFlipper); - if(err == ERR_NONE) { - return ERR_NONE; - } - - return err; -} - -ReturnCode picopass_read_card(PicopassBlock* AA1) { - ReturnCode err; - - size_t app_limit = AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[0] < PICOPASS_MAX_APP_LIMIT ? - AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[0] : - PICOPASS_MAX_APP_LIMIT; - - for(size_t i = 2; i < app_limit; i++) { - if(i == PICOPASS_KD_BLOCK_INDEX) { - // Skip over Kd block which is populated earlier (READ of Kd returns all FF's) - continue; - } - - rfalPicoPassReadBlockRes block; - err = rfalPicoPassPollerReadBlock(i, &block); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerReadBlock error %d", err); - return err; - } - - FURI_LOG_D( - TAG, - "rfalPicoPassPollerReadBlock %d %02x%02x%02x%02x%02x%02x%02x%02x", - i, - block.data[0], - block.data[1], - block.data[2], - block.data[3], - block.data[4], - block.data[5], - block.data[6], - block.data[7]); - - memcpy(AA1[i].data, block.data, sizeof(block.data)); - } - - return ERR_NONE; -} - -ReturnCode picopass_write_card(PicopassBlock* AA1) { - rfalPicoPassIdentifyRes idRes; - rfalPicoPassSelectRes selRes; - rfalPicoPassReadCheckRes rcRes; - rfalPicoPassCheckRes chkRes; - - ReturnCode err; - - uint8_t div_key[8] = {0}; - uint8_t mac[4] = {0}; - uint8_t ccnr[12] = {0}; - - err = rfalPicoPassPollerIdentify(&idRes); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerIdentify error %d", err); - return err; - } - - err = rfalPicoPassPollerSelect(idRes.CSN, &selRes); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerSelect error %d", err); - return err; - } - - err = rfalPicoPassPollerReadCheck(&rcRes); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerReadCheck error %d", err); - return err; - } - memcpy(ccnr, rcRes.CCNR, sizeof(rcRes.CCNR)); // last 4 bytes left 0 - - loclass_iclass_calc_div_key(selRes.CSN, (uint8_t*)picopass_iclass_key, div_key, false); - loclass_opt_doReaderMAC(ccnr, div_key, mac); - - err = rfalPicoPassPollerCheck(mac, &chkRes); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerCheck error %d", err); - return err; - } - - for(size_t i = 6; i < 10; i++) { - FURI_LOG_D(TAG, "rfalPicoPassPollerWriteBlock %d", i); - uint8_t data[9] = {0}; - data[0] = i; - memcpy(data + 1, AA1[i].data, RFAL_PICOPASS_MAX_BLOCK_LEN); - loclass_doMAC_N(data, sizeof(data), div_key, mac); - FURI_LOG_D( - TAG, - "loclass_doMAC_N %d %02x%02x%02x%02x%02x%02x%02x%02x %02x%02x%02x%02x", - i, - data[1], - data[2], - data[3], - data[4], - data[5], - data[6], - data[7], - data[8], - mac[0], - mac[1], - mac[2], - mac[3]); - - err = rfalPicoPassPollerWriteBlock(i, AA1[i].data, mac); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerWriteBlock error %d", err); - return err; - } - } - - return ERR_NONE; -} - -ReturnCode picopass_write_block(PicopassBlock* AA1, uint8_t blockNo, uint8_t* newBlock) { - rfalPicoPassIdentifyRes idRes; - rfalPicoPassSelectRes selRes; - rfalPicoPassReadCheckRes rcRes; - rfalPicoPassCheckRes chkRes; - - ReturnCode err; - - uint8_t mac[4] = {0}; - uint8_t ccnr[12] = {0}; - - err = rfalPicoPassPollerIdentify(&idRes); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerIdentify error %d", err); - return err; - } - - err = rfalPicoPassPollerSelect(idRes.CSN, &selRes); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerSelect error %d", err); - return err; - } - - err = rfalPicoPassPollerReadCheck(&rcRes); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerReadCheck error %d", err); - return err; - } - memcpy(ccnr, rcRes.CCNR, sizeof(rcRes.CCNR)); // last 4 bytes left 0 - - if(memcmp(selRes.CSN, AA1[PICOPASS_CSN_BLOCK_INDEX].data, PICOPASS_BLOCK_LEN) != 0) { - FURI_LOG_E(TAG, "Wrong CSN for write"); - return ERR_REQUEST; - } - - loclass_opt_doReaderMAC(ccnr, AA1[PICOPASS_KD_BLOCK_INDEX].data, mac); - err = rfalPicoPassPollerCheck(mac, &chkRes); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerCheck error %d", err); - return err; - } - - FURI_LOG_D(TAG, "rfalPicoPassPollerWriteBlock %d", blockNo); - uint8_t data[9] = { - blockNo, - newBlock[0], - newBlock[1], - newBlock[2], - newBlock[3], - newBlock[4], - newBlock[5], - newBlock[6], - newBlock[7]}; - loclass_doMAC_N(data, sizeof(data), AA1[PICOPASS_KD_BLOCK_INDEX].data, mac); - FURI_LOG_D( - TAG, - "loclass_doMAC_N %d %02x%02x%02x%02x%02x%02x%02x%02x %02x%02x%02x%02x", - blockNo, - data[1], - data[2], - data[3], - data[4], - data[5], - data[6], - data[7], - data[8], - mac[0], - mac[1], - mac[2], - mac[3]); - - err = rfalPicoPassPollerWriteBlock(data[0], data + 1, mac); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerWriteBlock error %d", err); - return err; - } - - return ERR_NONE; -} - -void picopass_worker_elite_dict_attack(PicopassWorker* picopass_worker) { - furi_assert(picopass_worker); - furi_assert(picopass_worker->callback); - - picopass_device_data_clear(picopass_worker->dev_data); - PicopassDeviceData* dev_data = picopass_worker->dev_data; - PicopassBlock* AA1 = dev_data->AA1; - PicopassPacs* pacs = &dev_data->pacs; - - for(size_t i = 0; i < PICOPASS_MAX_APP_LIMIT; i++) { - memset(AA1[i].data, 0, sizeof(AA1[i].data)); - } - memset(pacs, 0, sizeof(PicopassPacs)); - - IclassEliteDictAttackData* dict_attack_data = - &picopass_worker->dev_data->iclass_elite_dict_attack_data; - bool elite = (dict_attack_data->type != IclassStandardDictTypeFlipper); - - rfalPicoPassReadCheckRes rcRes; - rfalPicoPassCheckRes chkRes; - - ReturnCode err; - uint8_t mac[4] = {0}; - uint8_t ccnr[12] = {0}; - - size_t index = 0; - uint8_t key[PICOPASS_BLOCK_LEN] = {0}; - - // Load dictionary - IclassEliteDict* dict = dict_attack_data->dict; - if(!dict) { - FURI_LOG_E(TAG, "Dictionary not found"); - picopass_worker->callback(PicopassWorkerEventNoDictFound, picopass_worker->context); - return; - } - - do { - if(picopass_detect_card(1000) == ERR_NONE) { - picopass_worker->callback(PicopassWorkerEventCardDetected, picopass_worker->context); - - // Process first found device - err = picopass_read_preauth(AA1); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "picopass_read_preauth error %d", err); - picopass_worker->callback(PicopassWorkerEventAborted, picopass_worker->context); - return; - } - - // Thank you proxmark! - pacs->legacy = picopass_is_memset(AA1[5].data, 0xFF, 8); - pacs->se_enabled = (memcmp(AA1[5].data, "\xff\xff\xff\x00\x06\xff\xff\xff", 8) == 0); - if(pacs->se_enabled) { - FURI_LOG_D(TAG, "SE enabled"); - picopass_worker->callback(PicopassWorkerEventAborted, picopass_worker->context); - return; - } - - break; - } else { - picopass_worker->callback(PicopassWorkerEventNoCardDetected, picopass_worker->context); - } - if(picopass_worker->state != PicopassWorkerStateEliteDictAttack) break; - - furi_delay_ms(100); - } while(true); - - FURI_LOG_D( - TAG, "Start Dictionary attack, Key Count %lu", iclass_elite_dict_get_total_keys(dict)); - while(iclass_elite_dict_get_next_key(dict, key)) { - FURI_LOG_T(TAG, "Key %zu", index); - if(++index % PICOPASS_DICT_KEY_BATCH_SIZE == 0) { - picopass_worker->callback( - PicopassWorkerEventNewDictKeyBatch, picopass_worker->context); - } - - err = rfalPicoPassPollerReadCheck(&rcRes); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerReadCheck error %d", err); - break; - } - memcpy(ccnr, rcRes.CCNR, sizeof(rcRes.CCNR)); // last 4 bytes left 0 - - uint8_t* csn = AA1[PICOPASS_CSN_BLOCK_INDEX].data; - uint8_t* div_key = AA1[PICOPASS_KD_BLOCK_INDEX].data; - - loclass_iclass_calc_div_key(csn, key, div_key, elite); - loclass_opt_doReaderMAC(ccnr, div_key, mac); - - err = rfalPicoPassPollerCheck(mac, &chkRes); - if(err == ERR_NONE) { - FURI_LOG_I(TAG, "Found key"); - memcpy(pacs->key, key, PICOPASS_BLOCK_LEN); - pacs->elite_kdf = elite; - err = picopass_read_card(AA1); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "picopass_read_card error %d", err); - picopass_worker->callback(PicopassWorkerEventFail, picopass_worker->context); - break; - } - - err = picopass_device_parse_credential(AA1, pacs); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "picopass_device_parse_credential error %d", err); - picopass_worker->callback(PicopassWorkerEventFail, picopass_worker->context); - break; - } - - err = picopass_device_parse_wiegand(pacs->credential, &pacs->record); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "picopass_device_parse_wiegand error %d", err); - picopass_worker->callback(PicopassWorkerEventFail, picopass_worker->context); - break; - } - picopass_worker->callback(PicopassWorkerEventAborted, picopass_worker->context); - break; - } - - if(picopass_worker->state != PicopassWorkerStateEliteDictAttack) break; - } - FURI_LOG_D(TAG, "Dictionary complete"); - if(picopass_worker->state == PicopassWorkerStateEliteDictAttack) { - picopass_worker->callback(PicopassWorkerEventSuccess, picopass_worker->context); - } else { - picopass_worker->callback(PicopassWorkerEventAborted, picopass_worker->context); - } -} - -int32_t picopass_worker_task(void* context) { - PicopassWorker* picopass_worker = context; - - picopass_worker_enable_field(); - if(picopass_worker->state == PicopassWorkerStateDetect) { - picopass_worker_detect(picopass_worker); - } else if(picopass_worker->state == PicopassWorkerStateWrite) { - picopass_worker_write(picopass_worker); - } else if(picopass_worker->state == PicopassWorkerStateWriteKey) { - picopass_worker_write_key(picopass_worker); - } else if(picopass_worker->state == PicopassWorkerStateEliteDictAttack) { - picopass_worker_elite_dict_attack(picopass_worker); - } else if(picopass_worker->state == PicopassWorkerStateStop) { - FURI_LOG_D(TAG, "Worker state stop"); - // no-op - } else { - FURI_LOG_W(TAG, "Unknown state %d", picopass_worker->state); - } - picopass_worker_disable_field(ERR_NONE); - picopass_worker_change_state(picopass_worker, PicopassWorkerStateReady); - - return 0; -} - -void picopass_worker_detect(PicopassWorker* picopass_worker) { - picopass_device_data_clear(picopass_worker->dev_data); - PicopassDeviceData* dev_data = picopass_worker->dev_data; - - PicopassBlock* AA1 = dev_data->AA1; - PicopassPacs* pacs = &dev_data->pacs; - ReturnCode err; - - // reset device data - for(size_t i = 0; i < PICOPASS_MAX_APP_LIMIT; i++) { - memset(AA1[i].data, 0, sizeof(AA1[i].data)); - } - memset(pacs, 0, sizeof(PicopassPacs)); - - PicopassWorkerEvent nextState = PicopassWorkerEventSuccess; - - while(picopass_worker->state == PicopassWorkerStateDetect) { - if(picopass_detect_card(1000) == ERR_NONE) { - // Process first found device - err = picopass_read_preauth(AA1); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "picopass_read_preauth error %d", err); - nextState = PicopassWorkerEventFail; - } - - // Thank you proxmark! - pacs->legacy = picopass_is_memset(AA1[5].data, 0xFF, 8); - pacs->se_enabled = (memcmp(AA1[5].data, "\xff\xff\xff\x00\x06\xff\xff\xff", 8) == 0); - if(pacs->se_enabled) { - FURI_LOG_D(TAG, "SE enabled"); - nextState = PicopassWorkerEventFail; - } - - if(nextState == PicopassWorkerEventSuccess) { - err = picopass_auth(picopass_worker); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "picopass_try_auth error %d", err); - nextState = PicopassWorkerEventFail; - } - } - - if(nextState == PicopassWorkerEventSuccess) { - err = picopass_read_card(AA1); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "picopass_read_card error %d", err); - nextState = PicopassWorkerEventFail; - } - } - - if(nextState == PicopassWorkerEventSuccess) { - err = picopass_device_parse_credential(AA1, pacs); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "picopass_device_parse_credential error %d", err); - nextState = PicopassWorkerEventFail; - } - } - - if(nextState == PicopassWorkerEventSuccess) { - err = picopass_device_parse_wiegand(pacs->credential, &pacs->record); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "picopass_device_parse_wiegand error %d", err); - nextState = PicopassWorkerEventFail; - } - } - - // Notify caller and exit - if(picopass_worker->callback) { - picopass_worker->callback(nextState, picopass_worker->context); - } - break; - } - furi_delay_ms(100); - } -} - -void picopass_worker_write(PicopassWorker* picopass_worker) { - PicopassDeviceData* dev_data = picopass_worker->dev_data; - PicopassBlock* AA1 = dev_data->AA1; - ReturnCode err; - PicopassWorkerEvent nextState = PicopassWorkerEventSuccess; - - while(picopass_worker->state == PicopassWorkerStateWrite) { - if(picopass_detect_card(1000) == ERR_NONE) { - err = picopass_write_card(AA1); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "picopass_write_card error %d", err); - nextState = PicopassWorkerEventFail; - } - - // Notify caller and exit - if(picopass_worker->callback) { - picopass_worker->callback(nextState, picopass_worker->context); - } - break; - } - furi_delay_ms(100); - } -} - -void picopass_worker_write_key(PicopassWorker* picopass_worker) { - PicopassDeviceData* dev_data = picopass_worker->dev_data; - PicopassBlock* AA1 = dev_data->AA1; - PicopassPacs* pacs = &dev_data->pacs; - ReturnCode err; - PicopassWorkerEvent nextState = PicopassWorkerEventSuccess; - - uint8_t* csn = AA1[PICOPASS_CSN_BLOCK_INDEX].data; - uint8_t* configBlock = AA1[PICOPASS_CONFIG_BLOCK_INDEX].data; - uint8_t fuses = configBlock[7]; - uint8_t* oldKey = AA1[PICOPASS_KD_BLOCK_INDEX].data; - - uint8_t newKey[PICOPASS_BLOCK_LEN] = {0}; - loclass_iclass_calc_div_key(csn, pacs->key, newKey, pacs->elite_kdf); - - if((fuses & 0x80) == 0x80) { - FURI_LOG_D(TAG, "Plain write for personalized mode key change"); - } else { - FURI_LOG_D(TAG, "XOR write for application mode key change"); - // XOR when in application mode - for(size_t i = 0; i < PICOPASS_BLOCK_LEN; i++) { - newKey[i] ^= oldKey[i]; - } - } - - while(picopass_worker->state == PicopassWorkerStateWriteKey) { - if(picopass_detect_card(1000) == ERR_NONE) { - err = picopass_write_block(AA1, PICOPASS_KD_BLOCK_INDEX, newKey); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "picopass_write_block error %d", err); - nextState = PicopassWorkerEventFail; - } - - // Notify caller and exit - if(picopass_worker->callback) { - picopass_worker->callback(nextState, picopass_worker->context); - } - break; - } - furi_delay_ms(100); - } -} diff --git a/applications/external/picopass/picopass_worker.h b/applications/external/picopass/picopass_worker.h deleted file mode 100644 index e9d37481b..000000000 --- a/applications/external/picopass/picopass_worker.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include "picopass_device.h" -#include "picopass_keys.h" - -typedef struct PicopassWorker PicopassWorker; - -typedef enum { - // Init states - PicopassWorkerStateNone, - PicopassWorkerStateBroken, - PicopassWorkerStateReady, - // Main worker states - PicopassWorkerStateDetect, - PicopassWorkerStateWrite, - PicopassWorkerStateWriteKey, - PicopassWorkerStateEliteDictAttack, - // Transition - PicopassWorkerStateStop, -} PicopassWorkerState; - -typedef enum { - // Reserve first 50 events for application events - PicopassWorkerEventReserved = 50, - - // Picopass worker common events - PicopassWorkerEventSuccess, - PicopassWorkerEventFail, - PicopassWorkerEventNoCardDetected, - PicopassWorkerEventSeEnabled, - PicopassWorkerEventAborted, - PicopassWorkerEventCardDetected, - PicopassWorkerEventNewDictKeyBatch, - PicopassWorkerEventNoDictFound, -} PicopassWorkerEvent; - -typedef void (*PicopassWorkerCallback)(PicopassWorkerEvent event, void* context); - -PicopassWorker* picopass_worker_alloc(); - -PicopassWorkerState picopass_worker_get_state(PicopassWorker* picopass_worker); - -void picopass_worker_free(PicopassWorker* picopass_worker); - -void picopass_worker_start( - PicopassWorker* picopass_worker, - PicopassWorkerState state, - PicopassDeviceData* dev_data, - PicopassWorkerCallback callback, - void* context); - -void picopass_worker_stop(PicopassWorker* picopass_worker); diff --git a/applications/external/picopass/picopass_worker_i.h b/applications/external/picopass/picopass_worker_i.h deleted file mode 100644 index f41cfce45..000000000 --- a/applications/external/picopass/picopass_worker_i.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "picopass_worker.h" -#include "picopass_i.h" - -#include -#include - -#include - -#include -#include - -#include - -struct PicopassWorker { - FuriThread* thread; - Storage* storage; - Stream* dict_stream; - - PicopassDeviceData* dev_data; - PicopassWorkerCallback callback; - void* context; - - PicopassWorkerState state; -}; - -void picopass_worker_change_state(PicopassWorker* picopass_worker, PicopassWorkerState state); - -int32_t picopass_worker_task(void* context); - -void picopass_worker_detect(PicopassWorker* picopass_worker); -void picopass_worker_write(PicopassWorker* picopass_worker); -void picopass_worker_write_key(PicopassWorker* picopass_worker); diff --git a/applications/external/picopass/rfal_picopass.c b/applications/external/picopass/rfal_picopass.c deleted file mode 100644 index ac66cb92d..000000000 --- a/applications/external/picopass/rfal_picopass.c +++ /dev/null @@ -1,214 +0,0 @@ -#include "rfal_picopass.h" - -#define RFAL_PICOPASS_TXRX_FLAGS \ - (FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | \ - FURI_HAL_NFC_LL_TXRX_FLAGS_PAR_RX_REMV | FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP) - -#define TAG "RFAL_PICOPASS" - -typedef struct { - uint8_t CMD; - uint8_t CSN[RFAL_PICOPASS_UID_LEN]; -} rfalPicoPassSelectReq; - -typedef struct { - uint8_t CMD; - uint8_t null[4]; - uint8_t mac[4]; -} rfalPicoPassCheckReq; - -static uint16_t rfalPicoPassUpdateCcitt(uint16_t crcSeed, uint8_t dataByte) { - uint16_t crc = crcSeed; - uint8_t dat = dataByte; - - dat ^= (uint8_t)(crc & 0xFFU); - dat ^= (dat << 4); - - crc = (crc >> 8) ^ (((uint16_t)dat) << 8) ^ (((uint16_t)dat) << 3) ^ (((uint16_t)dat) >> 4); - - return crc; -} - -static uint16_t - rfalPicoPassCalculateCcitt(uint16_t preloadValue, const uint8_t* buf, uint16_t length) { - uint16_t crc = preloadValue; - uint16_t index; - - for(index = 0; index < length; index++) { - crc = rfalPicoPassUpdateCcitt(crc, buf[index]); - } - - return crc; -} - -FuriHalNfcReturn rfalPicoPassPollerInitialize(void) { - FuriHalNfcReturn ret; - - ret = furi_hal_nfc_ll_set_mode( - FuriHalNfcModePollPicopass, FuriHalNfcBitrate26p48, FuriHalNfcBitrate26p48); - if(ret != FuriHalNfcReturnOk) { - return ret; - }; - - furi_hal_nfc_ll_set_error_handling(FuriHalNfcErrorHandlingNfc); - furi_hal_nfc_ll_set_guard_time(FURI_HAL_NFC_LL_GT_PICOPASS); - furi_hal_nfc_ll_set_fdt_listen(FURI_HAL_NFC_LL_FDT_LISTEN_PICOPASS_POLLER); - furi_hal_nfc_ll_set_fdt_poll(FURI_HAL_NFC_LL_FDT_POLL_PICOPASS_POLLER); - - return FuriHalNfcReturnOk; -} - -FuriHalNfcReturn rfalPicoPassPollerCheckPresence(void) { - FuriHalNfcReturn ret; - uint8_t txBuf[1] = {RFAL_PICOPASS_CMD_ACTALL}; - uint8_t rxBuf[32] = {0}; - uint16_t recvLen = 0; - uint32_t flags = RFAL_PICOPASS_TXRX_FLAGS; - uint32_t fwt = furi_hal_nfc_ll_ms2fc(20); - - ret = furi_hal_nfc_ll_txrx(txBuf, 1, rxBuf, 32, &recvLen, flags, fwt); - return ret; -} - -FuriHalNfcReturn rfalPicoPassPollerIdentify(rfalPicoPassIdentifyRes* idRes) { - FuriHalNfcReturn ret; - - uint8_t txBuf[1] = {RFAL_PICOPASS_CMD_IDENTIFY}; - uint16_t recvLen = 0; - uint32_t flags = RFAL_PICOPASS_TXRX_FLAGS; - uint32_t fwt = furi_hal_nfc_ll_ms2fc(20); - - ret = furi_hal_nfc_ll_txrx( - txBuf, - sizeof(txBuf), - (uint8_t*)idRes, - sizeof(rfalPicoPassIdentifyRes), - &recvLen, - flags, - fwt); - // printf("identify rx: %d %s\n", recvLen, hex2Str(idRes->CSN, RFAL_PICOPASS_UID_LEN)); - - return ret; -} - -FuriHalNfcReturn rfalPicoPassPollerSelect(uint8_t* csn, rfalPicoPassSelectRes* selRes) { - FuriHalNfcReturn ret; - - rfalPicoPassSelectReq selReq; - selReq.CMD = RFAL_PICOPASS_CMD_SELECT; - memcpy(selReq.CSN, csn, RFAL_PICOPASS_UID_LEN); - uint16_t recvLen = 0; - uint32_t flags = RFAL_PICOPASS_TXRX_FLAGS; - uint32_t fwt = furi_hal_nfc_ll_ms2fc(20); - - ret = furi_hal_nfc_ll_txrx( - (uint8_t*)&selReq, - sizeof(rfalPicoPassSelectReq), - (uint8_t*)selRes, - sizeof(rfalPicoPassSelectRes), - &recvLen, - flags, - fwt); - // printf("select rx: %d %s\n", recvLen, hex2Str(selRes->CSN, RFAL_PICOPASS_UID_LEN)); - if(ret == FuriHalNfcReturnTimeout) { - return FuriHalNfcReturnOk; - } - - return ret; -} - -FuriHalNfcReturn rfalPicoPassPollerReadCheck(rfalPicoPassReadCheckRes* rcRes) { - FuriHalNfcReturn ret; - uint8_t txBuf[2] = {RFAL_PICOPASS_CMD_READCHECK, 0x02}; - uint16_t recvLen = 0; - uint32_t flags = RFAL_PICOPASS_TXRX_FLAGS; - uint32_t fwt = furi_hal_nfc_ll_ms2fc(20); - - ret = furi_hal_nfc_ll_txrx( - txBuf, - sizeof(txBuf), - (uint8_t*)rcRes, - sizeof(rfalPicoPassReadCheckRes), - &recvLen, - flags, - fwt); - // printf("readcheck rx: %d %s\n", recvLen, hex2Str(rcRes->CCNR, 8)); - - if(ret == FuriHalNfcReturnCrc) { - return FuriHalNfcReturnOk; - } - - return ret; -} - -FuriHalNfcReturn rfalPicoPassPollerCheck(uint8_t* mac, rfalPicoPassCheckRes* chkRes) { - FuriHalNfcReturn ret; - rfalPicoPassCheckReq chkReq; - chkReq.CMD = RFAL_PICOPASS_CMD_CHECK; - memcpy(chkReq.mac, mac, 4); - memset(chkReq.null, 0, 4); - uint16_t recvLen = 0; - uint32_t flags = RFAL_PICOPASS_TXRX_FLAGS; - uint32_t fwt = furi_hal_nfc_ll_ms2fc(20); - - // printf("check tx: %s\n", hex2Str((uint8_t *)&chkReq, sizeof(rfalPicoPassCheckReq))); - ret = furi_hal_nfc_ll_txrx( - (uint8_t*)&chkReq, - sizeof(rfalPicoPassCheckReq), - (uint8_t*)chkRes, - sizeof(rfalPicoPassCheckRes), - &recvLen, - flags, - fwt); - // printf("check rx: %d %s\n", recvLen, hex2Str(chkRes->mac, 4)); - if(ret == FuriHalNfcReturnCrc) { - return FuriHalNfcReturnOk; - } - - return ret; -} - -FuriHalNfcReturn rfalPicoPassPollerReadBlock(uint8_t blockNum, rfalPicoPassReadBlockRes* readRes) { - FuriHalNfcReturn ret; - - uint8_t txBuf[4] = {RFAL_PICOPASS_CMD_READ, 0, 0, 0}; - txBuf[1] = blockNum; - uint16_t crc = rfalPicoPassCalculateCcitt(0xE012, txBuf + 1, 1); - memcpy(txBuf + 2, &crc, sizeof(uint16_t)); - - uint16_t recvLen = 0; - uint32_t flags = RFAL_PICOPASS_TXRX_FLAGS; - uint32_t fwt = furi_hal_nfc_ll_ms2fc(20); - - ret = furi_hal_nfc_ll_txrx( - txBuf, - sizeof(txBuf), - (uint8_t*)readRes, - sizeof(rfalPicoPassReadBlockRes), - &recvLen, - flags, - fwt); - return ret; -} - -FuriHalNfcReturn rfalPicoPassPollerWriteBlock(uint8_t blockNum, uint8_t data[8], uint8_t mac[4]) { - FuriHalNfcReturn ret; - - uint8_t txBuf[14] = {RFAL_PICOPASS_CMD_WRITE, blockNum, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - memcpy(txBuf + 2, data, RFAL_PICOPASS_MAX_BLOCK_LEN); - memcpy(txBuf + 10, mac, 4); - - uint16_t recvLen = 0; - uint32_t flags = RFAL_PICOPASS_TXRX_FLAGS; - uint32_t fwt = furi_hal_nfc_ll_ms2fc(20); - rfalPicoPassReadBlockRes block; - - ret = furi_hal_nfc_ll_txrx( - txBuf, sizeof(txBuf), (uint8_t*)&block, sizeof(block), &recvLen, flags, fwt); - - if(ret == FuriHalNfcReturnOk) { - // TODO: compare response - } - - return ret; -} diff --git a/applications/external/picopass/rfal_picopass.h b/applications/external/picopass/rfal_picopass.h deleted file mode 100644 index 6926b2a79..000000000 --- a/applications/external/picopass/rfal_picopass.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include - -#define RFAL_PICOPASS_UID_LEN 8 -#define RFAL_PICOPASS_MAX_BLOCK_LEN 8 - -enum { - RFAL_PICOPASS_CMD_ACTALL = 0x0A, - RFAL_PICOPASS_CMD_IDENTIFY = 0x0C, - RFAL_PICOPASS_CMD_SELECT = 0x81, - RFAL_PICOPASS_CMD_READCHECK = 0x88, - RFAL_PICOPASS_CMD_CHECK = 0x05, - RFAL_PICOPASS_CMD_READ = 0x0C, - RFAL_PICOPASS_CMD_WRITE = 0x87, -}; - -typedef struct { - uint8_t CSN[RFAL_PICOPASS_UID_LEN]; // Anti-collision CSN - uint8_t crc[2]; -} rfalPicoPassIdentifyRes; - -typedef struct { - uint8_t CSN[RFAL_PICOPASS_UID_LEN]; // Real CSN - uint8_t crc[2]; -} rfalPicoPassSelectRes; - -typedef struct { - uint8_t CCNR[8]; -} rfalPicoPassReadCheckRes; - -typedef struct { - uint8_t mac[4]; -} rfalPicoPassCheckRes; - -typedef struct { - uint8_t data[RFAL_PICOPASS_MAX_BLOCK_LEN]; - uint8_t crc[2]; -} rfalPicoPassReadBlockRes; - -FuriHalNfcReturn rfalPicoPassPollerInitialize(void); -FuriHalNfcReturn rfalPicoPassPollerCheckPresence(void); -FuriHalNfcReturn rfalPicoPassPollerIdentify(rfalPicoPassIdentifyRes* idRes); -FuriHalNfcReturn rfalPicoPassPollerSelect(uint8_t* csn, rfalPicoPassSelectRes* selRes); -FuriHalNfcReturn rfalPicoPassPollerReadCheck(rfalPicoPassReadCheckRes* rcRes); -FuriHalNfcReturn rfalPicoPassPollerCheck(uint8_t* mac, rfalPicoPassCheckRes* chkRes); -FuriHalNfcReturn rfalPicoPassPollerReadBlock(uint8_t blockNum, rfalPicoPassReadBlockRes* readRes); -FuriHalNfcReturn rfalPicoPassPollerWriteBlock(uint8_t blockNum, uint8_t data[8], uint8_t mac[4]); diff --git a/applications/external/picopass/scenes/picopass_scene.c b/applications/external/picopass/scenes/picopass_scene.c deleted file mode 100644 index 61bd5e8fe..000000000 --- a/applications/external/picopass/scenes/picopass_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "picopass_scene.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const picopass_on_enter_handlers[])(void*) = { -#include "picopass_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 picopass_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "picopass_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 picopass_on_exit_handlers[])(void* context) = { -#include "picopass_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers picopass_scene_handlers = { - .on_enter_handlers = picopass_on_enter_handlers, - .on_event_handlers = picopass_on_event_handlers, - .on_exit_handlers = picopass_on_exit_handlers, - .scene_num = PicopassSceneNum, -}; diff --git a/applications/external/picopass/scenes/picopass_scene.h b/applications/external/picopass/scenes/picopass_scene.h deleted file mode 100644 index 2faa80b12..000000000 --- a/applications/external/picopass/scenes/picopass_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) PicopassScene##id, -typedef enum { -#include "picopass_scene_config.h" - PicopassSceneNum, -} PicopassScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers picopass_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "picopass_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 "picopass_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 "picopass_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/picopass/scenes/picopass_scene_card_menu.c b/applications/external/picopass/scenes/picopass_scene_card_menu.c deleted file mode 100644 index fe63f7c86..000000000 --- a/applications/external/picopass/scenes/picopass_scene_card_menu.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "../picopass_i.h" - -enum SubmenuIndex { - SubmenuIndexSave, - SubmenuIndexSaveAsLF, - SubmenuIndexChangeKey, -}; - -void picopass_scene_card_menu_submenu_callback(void* context, uint32_t index) { - Picopass* picopass = context; - - view_dispatcher_send_custom_event(picopass->view_dispatcher, index); -} - -void picopass_scene_card_menu_on_enter(void* context) { - Picopass* picopass = context; - Submenu* submenu = picopass->submenu; - - submenu_add_item( - submenu, "Save", SubmenuIndexSave, picopass_scene_card_menu_submenu_callback, picopass); - if(picopass->dev->dev_data.pacs.record.valid) { - submenu_add_item( - submenu, - "Save as LF", - SubmenuIndexSaveAsLF, - picopass_scene_card_menu_submenu_callback, - picopass); - } - submenu_add_item( - submenu, - "Change Key", - SubmenuIndexChangeKey, - picopass_scene_card_menu_submenu_callback, - picopass); - - submenu_set_selected_item( - picopass->submenu, - scene_manager_get_scene_state(picopass->scene_manager, PicopassSceneCardMenu)); - - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewMenu); -} - -bool picopass_scene_card_menu_on_event(void* context, SceneManagerEvent event) { - Picopass* picopass = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexSave) { - scene_manager_set_scene_state( - picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexSave); - scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveName); - picopass->dev->format = PicopassDeviceSaveFormatHF; - consumed = true; - } else if(event.event == SubmenuIndexSaveAsLF) { - scene_manager_set_scene_state( - picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexSaveAsLF); - picopass->dev->format = PicopassDeviceSaveFormatLF; - scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveName); - consumed = true; - } else if(event.event == SubmenuIndexChangeKey) { - scene_manager_set_scene_state( - picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexChangeKey); - scene_manager_next_scene(picopass->scene_manager, PicopassSceneKeyMenu); - consumed = true; - } - } else if(event.type == SceneManagerEventTypeBack) { - consumed = scene_manager_search_and_switch_to_previous_scene( - picopass->scene_manager, PicopassSceneStart); - } - - return consumed; -} - -void picopass_scene_card_menu_on_exit(void* context) { - Picopass* picopass = context; - - submenu_reset(picopass->submenu); -} diff --git a/applications/external/picopass/scenes/picopass_scene_config.h b/applications/external/picopass/scenes/picopass_scene_config.h deleted file mode 100644 index 8ea970498..000000000 --- a/applications/external/picopass/scenes/picopass_scene_config.h +++ /dev/null @@ -1,17 +0,0 @@ -ADD_SCENE(picopass, start, Start) -ADD_SCENE(picopass, read_card, ReadCard) -ADD_SCENE(picopass, read_card_success, ReadCardSuccess) -ADD_SCENE(picopass, card_menu, CardMenu) -ADD_SCENE(picopass, save_name, SaveName) -ADD_SCENE(picopass, save_success, SaveSuccess) -ADD_SCENE(picopass, saved_menu, SavedMenu) -ADD_SCENE(picopass, file_select, FileSelect) -ADD_SCENE(picopass, device_info, DeviceInfo) -ADD_SCENE(picopass, delete, Delete) -ADD_SCENE(picopass, delete_success, DeleteSuccess) -ADD_SCENE(picopass, write_card, WriteCard) -ADD_SCENE(picopass, write_card_success, WriteCardSuccess) -ADD_SCENE(picopass, read_factory_success, ReadFactorySuccess) -ADD_SCENE(picopass, write_key, WriteKey) -ADD_SCENE(picopass, key_menu, KeyMenu) -ADD_SCENE(picopass, elite_dict_attack, EliteDictAttack) diff --git a/applications/external/picopass/scenes/picopass_scene_delete.c b/applications/external/picopass/scenes/picopass_scene_delete.c deleted file mode 100644 index fb23cb5d4..000000000 --- a/applications/external/picopass/scenes/picopass_scene_delete.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "../picopass_i.h" - -void picopass_scene_delete_widget_callback(GuiButtonType result, InputType type, void* context) { - Picopass* picopass = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(picopass->view_dispatcher, result); - } -} - -void picopass_scene_delete_on_enter(void* context) { - Picopass* picopass = context; - - // Setup Custom Widget view - char temp_str[64]; - snprintf(temp_str, sizeof(temp_str), "\e#Delete %s?\e#", picopass->dev->dev_name); - widget_add_text_box_element( - picopass->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, temp_str, false); - widget_add_button_element( - picopass->widget, - GuiButtonTypeLeft, - "Back", - picopass_scene_delete_widget_callback, - picopass); - widget_add_button_element( - picopass->widget, - GuiButtonTypeRight, - "Delete", - picopass_scene_delete_widget_callback, - picopass); - - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewWidget); -} - -bool picopass_scene_delete_on_event(void* context, SceneManagerEvent event) { - Picopass* picopass = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeLeft) { - return scene_manager_previous_scene(picopass->scene_manager); - } else if(event.event == GuiButtonTypeRight) { - if(picopass_device_delete(picopass->dev, true)) { - scene_manager_next_scene(picopass->scene_manager, PicopassSceneDeleteSuccess); - } else { - scene_manager_search_and_switch_to_previous_scene( - picopass->scene_manager, PicopassSceneStart); - } - consumed = true; - } - } - return consumed; -} - -void picopass_scene_delete_on_exit(void* context) { - Picopass* picopass = context; - - widget_reset(picopass->widget); -} diff --git a/applications/external/picopass/scenes/picopass_scene_delete_success.c b/applications/external/picopass/scenes/picopass_scene_delete_success.c deleted file mode 100644 index f2a36a7fb..000000000 --- a/applications/external/picopass/scenes/picopass_scene_delete_success.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "../picopass_i.h" - -void picopass_scene_delete_success_popup_callback(void* context) { - Picopass* picopass = context; - view_dispatcher_send_custom_event(picopass->view_dispatcher, PicopassCustomEventViewExit); -} - -void picopass_scene_delete_success_on_enter(void* context) { - Picopass* picopass = context; - - // Setup view - Popup* popup = picopass->popup; - popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62); - popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom); - popup_set_timeout(popup, 1500); - popup_set_context(popup, picopass); - popup_set_callback(popup, picopass_scene_delete_success_popup_callback); - popup_enable_timeout(popup); - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewPopup); -} - -bool picopass_scene_delete_success_on_event(void* context, SceneManagerEvent event) { - Picopass* picopass = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == PicopassCustomEventViewExit) { - consumed = scene_manager_search_and_switch_to_previous_scene( - picopass->scene_manager, PicopassSceneStart); - } - } - return consumed; -} - -void picopass_scene_delete_success_on_exit(void* context) { - Picopass* picopass = context; - - // Clear view - popup_reset(picopass->popup); -} diff --git a/applications/external/picopass/scenes/picopass_scene_device_info.c b/applications/external/picopass/scenes/picopass_scene_device_info.c deleted file mode 100644 index bb149aa6b..000000000 --- a/applications/external/picopass/scenes/picopass_scene_device_info.c +++ /dev/null @@ -1,114 +0,0 @@ -#include "../picopass_i.h" -#include - -void picopass_scene_device_info_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - Picopass* picopass = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(picopass->view_dispatcher, result); - } -} - -void picopass_scene_device_info_on_enter(void* context) { - Picopass* picopass = context; - - FuriString* csn_str = furi_string_alloc_set("CSN:"); - FuriString* credential_str = furi_string_alloc(); - FuriString* wiegand_str = furi_string_alloc(); - FuriString* sio_str = furi_string_alloc(); - - dolphin_deed(DolphinDeedNfcReadSuccess); - - // Setup view - PicopassBlock* AA1 = picopass->dev->dev_data.AA1; - PicopassPacs* pacs = &picopass->dev->dev_data.pacs; - Widget* widget = picopass->widget; - - uint8_t csn[PICOPASS_BLOCK_LEN] = {0}; - memcpy(csn, AA1[PICOPASS_CSN_BLOCK_INDEX].data, PICOPASS_BLOCK_LEN); - for(uint8_t i = 0; i < PICOPASS_BLOCK_LEN; i++) { - furi_string_cat_printf(csn_str, "%02X ", csn[i]); - } - - if(pacs->record.bitLength == 0 || pacs->record.bitLength == 255) { - // Neither of these are valid. Indicates the block was all 0x00 or all 0xff - furi_string_cat_printf(wiegand_str, "Invalid PACS"); - } else { - size_t bytesLength = pacs->record.bitLength / 8; - if(pacs->record.bitLength % 8 > 0) { - // Add extra byte if there are bits remaining - bytesLength++; - } - furi_string_set(credential_str, ""); - for(uint8_t i = PICOPASS_BLOCK_LEN - bytesLength; i < PICOPASS_BLOCK_LEN; i++) { - furi_string_cat_printf(credential_str, " %02X", pacs->credential[i]); - } - - if(pacs->record.valid) { - furi_string_cat_printf( - wiegand_str, "FC: %u CN: %u", pacs->record.FacilityCode, pacs->record.CardNumber); - } else { - furi_string_cat_printf(wiegand_str, "%d bits", pacs->record.bitLength); - } - - if(pacs->sio) { - furi_string_cat_printf(sio_str, "+SIO"); - } - } - - widget_add_string_element( - widget, 64, 5, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(csn_str)); - widget_add_string_element( - widget, 64, 20, AlignCenter, AlignCenter, FontPrimary, furi_string_get_cstr(wiegand_str)); - widget_add_string_element( - widget, - 64, - 36, - AlignCenter, - AlignCenter, - FontSecondary, - furi_string_get_cstr(credential_str)); - widget_add_string_element( - widget, 64, 46, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(sio_str)); - - furi_string_free(csn_str); - furi_string_free(credential_str); - furi_string_free(wiegand_str); - furi_string_free(sio_str); - - widget_add_button_element( - picopass->widget, - GuiButtonTypeLeft, - "Back", - picopass_scene_device_info_widget_callback, - picopass); - - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewWidget); -} - -bool picopass_scene_device_info_on_event(void* context, SceneManagerEvent event) { - Picopass* picopass = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeLeft) { - consumed = scene_manager_previous_scene(picopass->scene_manager); - } else if(event.event == PicopassCustomEventViewExit) { - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewWidget); - consumed = true; - } - } else if(event.type == SceneManagerEventTypeBack) { - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewWidget); - consumed = true; - } - return consumed; -} - -void picopass_scene_device_info_on_exit(void* context) { - Picopass* picopass = context; - - // Clear views - widget_reset(picopass->widget); -} diff --git a/applications/external/picopass/scenes/picopass_scene_elite_dict_attack.c b/applications/external/picopass/scenes/picopass_scene_elite_dict_attack.c deleted file mode 100644 index e6191d5ba..000000000 --- a/applications/external/picopass/scenes/picopass_scene_elite_dict_attack.c +++ /dev/null @@ -1,172 +0,0 @@ -#include "../picopass_i.h" -#include - -#define TAG "IclassEliteDictAttack" - -typedef enum { - DictAttackStateIdle, - DictAttackStateUserDictInProgress, - DictAttackStateFlipperDictInProgress, - DictAttackStateStandardDictInProgress, -} DictAttackState; - -void picopass_dict_attack_worker_callback(PicopassWorkerEvent event, void* context) { - furi_assert(context); - Picopass* picopass = context; - view_dispatcher_send_custom_event(picopass->view_dispatcher, event); -} - -void picopass_dict_attack_result_callback(void* context) { - furi_assert(context); - Picopass* picopass = context; - view_dispatcher_send_custom_event( - picopass->view_dispatcher, PicopassCustomEventDictAttackSkip); -} - -static void - picopass_scene_elite_dict_attack_prepare_view(Picopass* picopass, DictAttackState state) { - IclassEliteDictAttackData* dict_attack_data = - &picopass->dev->dev_data.iclass_elite_dict_attack_data; - PicopassWorkerState worker_state = PicopassWorkerStateReady; - IclassEliteDict* dict = NULL; - - // Identify scene state - if(state == DictAttackStateIdle) { - if(iclass_elite_dict_check_presence(IclassEliteDictTypeUser)) { - FURI_LOG_D(TAG, "Starting with user dictionary"); - state = DictAttackStateUserDictInProgress; - } else { - FURI_LOG_D(TAG, "Starting with standard dictionary"); - state = DictAttackStateStandardDictInProgress; - } - } else if(state == DictAttackStateUserDictInProgress) { - FURI_LOG_D(TAG, "Moving from user dictionary to standard dictionary"); - state = DictAttackStateStandardDictInProgress; - } else if(state == DictAttackStateStandardDictInProgress) { - FURI_LOG_D(TAG, "Moving from standard dictionary to elite dictionary"); - state = DictAttackStateFlipperDictInProgress; - } - - // Setup view - if(state == DictAttackStateUserDictInProgress) { - worker_state = PicopassWorkerStateEliteDictAttack; - dict_attack_set_header(picopass->dict_attack, "Elite User Dictionary"); - dict_attack_data->type = IclassEliteDictTypeUser; - dict = iclass_elite_dict_alloc(IclassEliteDictTypeUser); - - // If failed to load user dictionary - try the system dictionary - if(!dict) { - FURI_LOG_E(TAG, "User dictionary not found"); - state = DictAttackStateStandardDictInProgress; - } - } - if(state == DictAttackStateStandardDictInProgress) { - worker_state = PicopassWorkerStateEliteDictAttack; - dict_attack_set_header(picopass->dict_attack, "Standard System Dictionary"); - dict_attack_data->type = IclassStandardDictTypeFlipper; - dict = iclass_elite_dict_alloc(IclassStandardDictTypeFlipper); - - if(!dict) { - FURI_LOG_E(TAG, "Flipper standard dictionary not found"); - state = DictAttackStateFlipperDictInProgress; - } - } - if(state == DictAttackStateFlipperDictInProgress) { - worker_state = PicopassWorkerStateEliteDictAttack; - dict_attack_set_header(picopass->dict_attack, "Elite System Dictionary"); - dict_attack_data->type = IclassEliteDictTypeFlipper; - dict = iclass_elite_dict_alloc(IclassEliteDictTypeFlipper); - if(!dict) { - FURI_LOG_E(TAG, "Flipper Elite dictionary not found"); - // Pass through to let the worker handle the failure - } - } - // Free previous dictionary - if(dict_attack_data->dict) { - iclass_elite_dict_free(dict_attack_data->dict); - } - dict_attack_data->dict = dict; - scene_manager_set_scene_state(picopass->scene_manager, PicopassSceneEliteDictAttack, state); - dict_attack_set_callback( - picopass->dict_attack, picopass_dict_attack_result_callback, picopass); - dict_attack_set_current_sector(picopass->dict_attack, 0); - dict_attack_set_card_detected(picopass->dict_attack); - dict_attack_set_total_dict_keys( - picopass->dict_attack, dict ? iclass_elite_dict_get_total_keys(dict) : 0); - picopass_worker_start( - picopass->worker, - worker_state, - &picopass->dev->dev_data, - picopass_dict_attack_worker_callback, - picopass); -} - -void picopass_scene_elite_dict_attack_on_enter(void* context) { - Picopass* picopass = context; - picopass_scene_elite_dict_attack_prepare_view(picopass, DictAttackStateIdle); - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewDictAttack); - picopass_blink_start(picopass); - notification_message(picopass->notifications, &sequence_display_backlight_enforce_on); -} - -bool picopass_scene_elite_dict_attack_on_event(void* context, SceneManagerEvent event) { - Picopass* picopass = context; - bool consumed = false; - - uint32_t state = - scene_manager_get_scene_state(picopass->scene_manager, PicopassSceneEliteDictAttack); - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == PicopassWorkerEventSuccess) { - if(state == DictAttackStateUserDictInProgress || - state == DictAttackStateStandardDictInProgress) { - picopass_worker_stop(picopass->worker); - picopass_scene_elite_dict_attack_prepare_view(picopass, state); - consumed = true; - } else { - scene_manager_next_scene(picopass->scene_manager, PicopassSceneReadCardSuccess); - consumed = true; - } - } else if(event.event == PicopassWorkerEventAborted) { - scene_manager_next_scene(picopass->scene_manager, PicopassSceneReadCardSuccess); - consumed = true; - } else if(event.event == PicopassWorkerEventCardDetected) { - dict_attack_set_card_detected(picopass->dict_attack); - consumed = true; - } else if(event.event == PicopassWorkerEventNoCardDetected) { - dict_attack_set_card_removed(picopass->dict_attack); - consumed = true; - } else if(event.event == PicopassWorkerEventNewDictKeyBatch) { - dict_attack_inc_current_dict_key(picopass->dict_attack, PICOPASS_DICT_KEY_BATCH_SIZE); - consumed = true; - } else if(event.event == PicopassCustomEventDictAttackSkip) { - if(state == DictAttackStateUserDictInProgress) { - picopass_worker_stop(picopass->worker); - consumed = true; - } else if(state == DictAttackStateFlipperDictInProgress) { - picopass_worker_stop(picopass->worker); - consumed = true; - } else if(state == DictAttackStateStandardDictInProgress) { - picopass_worker_stop(picopass->worker); - consumed = true; - } - } - } else if(event.type == SceneManagerEventTypeBack) { - consumed = scene_manager_previous_scene(picopass->scene_manager); - } - return consumed; -} - -void picopass_scene_elite_dict_attack_on_exit(void* context) { - Picopass* picopass = context; - IclassEliteDictAttackData* dict_attack_data = - &picopass->dev->dev_data.iclass_elite_dict_attack_data; - // Stop worker - picopass_worker_stop(picopass->worker); - if(dict_attack_data->dict) { - iclass_elite_dict_free(dict_attack_data->dict); - dict_attack_data->dict = NULL; - } - dict_attack_reset(picopass->dict_attack); - picopass_blink_stop(picopass); - notification_message(picopass->notifications, &sequence_display_backlight_enforce_auto); -} diff --git a/applications/external/picopass/scenes/picopass_scene_file_select.c b/applications/external/picopass/scenes/picopass_scene_file_select.c deleted file mode 100644 index 2fc64746e..000000000 --- a/applications/external/picopass/scenes/picopass_scene_file_select.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "../picopass_i.h" -#include "../picopass_device.h" - -void picopass_scene_file_select_on_enter(void* context) { - Picopass* picopass = context; - // Process file_select return - picopass_device_set_loading_callback(picopass->dev, picopass_show_loading_popup, picopass); - if(picopass_file_select(picopass->dev)) { - scene_manager_next_scene(picopass->scene_manager, PicopassSceneSavedMenu); - } else { - scene_manager_search_and_switch_to_previous_scene( - picopass->scene_manager, PicopassSceneStart); - } - picopass_device_set_loading_callback(picopass->dev, NULL, picopass); -} - -bool picopass_scene_file_select_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void picopass_scene_file_select_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/picopass/scenes/picopass_scene_key_menu.c b/applications/external/picopass/scenes/picopass_scene_key_menu.c deleted file mode 100644 index 15a32ff44..000000000 --- a/applications/external/picopass/scenes/picopass_scene_key_menu.c +++ /dev/null @@ -1,100 +0,0 @@ -#include "../picopass_i.h" -#include "../picopass_keys.h" - -enum SubmenuIndex { - SubmenuIndexWriteStandard, - SubmenuIndexWriteiCE, - SubmenuIndexWriteiCL, - SubmenuIndexWriteiCS, - SubmenuIndexWriteCustom, //TODO: user input of key -}; - -void picopass_scene_key_menu_submenu_callback(void* context, uint32_t index) { - Picopass* picopass = context; - - view_dispatcher_send_custom_event(picopass->view_dispatcher, index); -} - -void picopass_scene_key_menu_on_enter(void* context) { - Picopass* picopass = context; - Submenu* submenu = picopass->submenu; - - submenu_add_item( - submenu, - "Write Standard", - SubmenuIndexWriteStandard, - picopass_scene_key_menu_submenu_callback, - picopass); - submenu_add_item( - submenu, - "Write iCE", - SubmenuIndexWriteiCE, - picopass_scene_key_menu_submenu_callback, - picopass); - submenu_add_item( - submenu, - "Write iCL", - SubmenuIndexWriteiCL, - picopass_scene_key_menu_submenu_callback, - picopass); - submenu_add_item( - submenu, - "Write iCS", - SubmenuIndexWriteiCS, - picopass_scene_key_menu_submenu_callback, - picopass); - - submenu_set_selected_item( - picopass->submenu, - scene_manager_get_scene_state(picopass->scene_manager, PicopassSceneKeyMenu)); - - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewMenu); -} - -bool picopass_scene_key_menu_on_event(void* context, SceneManagerEvent event) { - Picopass* picopass = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexWriteStandard) { - scene_manager_set_scene_state( - picopass->scene_manager, PicopassSceneKeyMenu, SubmenuIndexWriteStandard); - memcpy(picopass->dev->dev_data.pacs.key, picopass_iclass_key, PICOPASS_BLOCK_LEN); - picopass->dev->dev_data.pacs.elite_kdf = false; - scene_manager_next_scene(picopass->scene_manager, PicopassSceneWriteKey); - consumed = true; - } else if(event.event == SubmenuIndexWriteiCE) { - scene_manager_set_scene_state( - picopass->scene_manager, PicopassSceneKeyMenu, SubmenuIndexWriteiCE); - memcpy(picopass->dev->dev_data.pacs.key, picopass_xice_key, PICOPASS_BLOCK_LEN); - picopass->dev->dev_data.pacs.elite_kdf = true; - scene_manager_next_scene(picopass->scene_manager, PicopassSceneWriteKey); - consumed = true; - } else if(event.event == SubmenuIndexWriteiCL) { - scene_manager_set_scene_state( - picopass->scene_manager, PicopassSceneKeyMenu, SubmenuIndexWriteiCL); - memcpy(picopass->dev->dev_data.pacs.key, picopass_xicl_key, PICOPASS_BLOCK_LEN); - picopass->dev->dev_data.pacs.elite_kdf = false; - scene_manager_next_scene(picopass->scene_manager, PicopassSceneWriteKey); - consumed = true; - } else if(event.event == SubmenuIndexWriteiCS) { - scene_manager_set_scene_state( - picopass->scene_manager, PicopassSceneKeyMenu, SubmenuIndexWriteiCS); - memcpy(picopass->dev->dev_data.pacs.key, picopass_xics_key, PICOPASS_BLOCK_LEN); - picopass->dev->dev_data.pacs.elite_kdf = false; - scene_manager_next_scene(picopass->scene_manager, PicopassSceneWriteKey); - consumed = true; - } - } else if(event.type == SceneManagerEventTypeBack) { - consumed = scene_manager_search_and_switch_to_previous_scene( - picopass->scene_manager, PicopassSceneStart); - } - - return consumed; -} - -void picopass_scene_key_menu_on_exit(void* context) { - Picopass* picopass = context; - - submenu_reset(picopass->submenu); -} diff --git a/applications/external/picopass/scenes/picopass_scene_read_card.c b/applications/external/picopass/scenes/picopass_scene_read_card.c deleted file mode 100644 index c1cc7249c..000000000 --- a/applications/external/picopass/scenes/picopass_scene_read_card.c +++ /dev/null @@ -1,61 +0,0 @@ -#include "../picopass_i.h" -#include -#include "../picopass_keys.h" - -void picopass_read_card_worker_callback(PicopassWorkerEvent event, void* context) { - UNUSED(event); - Picopass* picopass = context; - view_dispatcher_send_custom_event(picopass->view_dispatcher, PicopassCustomEventWorkerExit); -} - -void picopass_scene_read_card_on_enter(void* context) { - Picopass* picopass = context; - dolphin_deed(DolphinDeedNfcRead); - - // Setup view - Popup* popup = picopass->popup; - popup_set_header(popup, "Detecting\npicopass\ncard", 68, 30, AlignLeft, AlignTop); - popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); - - // Start worker - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewPopup); - picopass_worker_start( - picopass->worker, - PicopassWorkerStateDetect, - &picopass->dev->dev_data, - picopass_read_card_worker_callback, - picopass); - - picopass_blink_start(picopass); -} - -bool picopass_scene_read_card_on_event(void* context, SceneManagerEvent event) { - Picopass* picopass = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == PicopassCustomEventWorkerExit) { - if(memcmp( - picopass->dev->dev_data.pacs.key, - picopass_factory_debit_key, - PICOPASS_BLOCK_LEN) == 0) { - scene_manager_next_scene(picopass->scene_manager, PicopassSceneReadFactorySuccess); - } else { - scene_manager_next_scene(picopass->scene_manager, PicopassSceneReadCardSuccess); - } - consumed = true; - } - } - return consumed; -} - -void picopass_scene_read_card_on_exit(void* context) { - Picopass* picopass = context; - - // Stop worker - picopass_worker_stop(picopass->worker); - // Clear view - popup_reset(picopass->popup); - - picopass_blink_stop(picopass); -} diff --git a/applications/external/picopass/scenes/picopass_scene_read_card_success.c b/applications/external/picopass/scenes/picopass_scene_read_card_success.c deleted file mode 100644 index ffe7195b7..000000000 --- a/applications/external/picopass/scenes/picopass_scene_read_card_success.c +++ /dev/null @@ -1,172 +0,0 @@ -#include "../picopass_i.h" -#include - -void picopass_scene_read_card_success_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - furi_assert(context); - Picopass* picopass = context; - - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(picopass->view_dispatcher, result); - } -} - -void picopass_scene_read_card_success_on_enter(void* context) { - Picopass* picopass = context; - - FuriString* csn_str = furi_string_alloc_set("CSN:"); - FuriString* credential_str = furi_string_alloc(); - FuriString* wiegand_str = furi_string_alloc(); - FuriString* sio_str = furi_string_alloc(); - - dolphin_deed(DolphinDeedNfcReadSuccess); - - // Send notification - notification_message(picopass->notifications, &sequence_success); - - // Setup view - PicopassBlock* AA1 = picopass->dev->dev_data.AA1; - PicopassPacs* pacs = &picopass->dev->dev_data.pacs; - Widget* widget = picopass->widget; - - uint8_t csn[PICOPASS_BLOCK_LEN] = {0}; - memcpy(csn, AA1[PICOPASS_CSN_BLOCK_INDEX].data, PICOPASS_BLOCK_LEN); - for(uint8_t i = 0; i < PICOPASS_BLOCK_LEN; i++) { - furi_string_cat_printf(csn_str, "%02X", csn[i]); - } - - bool no_key = picopass_is_memset(pacs->key, 0x00, PICOPASS_BLOCK_LEN); - bool empty = - picopass_is_memset(AA1[PICOPASS_PACS_CFG_BLOCK_INDEX].data, 0xFF, PICOPASS_BLOCK_LEN); - - if(no_key) { - furi_string_cat_printf(wiegand_str, "Read Failed"); - - if(pacs->se_enabled) { - furi_string_cat_printf(credential_str, "SE enabled"); - } - - widget_add_button_element( - widget, - GuiButtonTypeCenter, - "Menu", - picopass_scene_read_card_success_widget_callback, - picopass); - } else if(empty) { - furi_string_cat_printf(wiegand_str, "Empty"); - widget_add_button_element( - widget, - GuiButtonTypeCenter, - "Menu", - picopass_scene_read_card_success_widget_callback, - picopass); - } else if(pacs->record.bitLength == 0 || pacs->record.bitLength == 255) { - // Neither of these are valid. Indicates the block was all 0x00 or all 0xff - furi_string_cat_printf(wiegand_str, "Invalid PACS"); - - if(pacs->se_enabled) { - furi_string_cat_printf(credential_str, "SE enabled"); - } - widget_add_button_element( - widget, - GuiButtonTypeCenter, - "Menu", - picopass_scene_read_card_success_widget_callback, - picopass); - } else { - size_t bytesLength = 1 + pacs->record.bitLength / 8; - furi_string_set(credential_str, ""); - for(uint8_t i = PICOPASS_BLOCK_LEN - bytesLength; i < PICOPASS_BLOCK_LEN; i++) { - furi_string_cat_printf(credential_str, " %02X", pacs->credential[i]); - } - - if(pacs->record.valid) { - furi_string_cat_printf( - wiegand_str, "FC: %u CN: %u", pacs->record.FacilityCode, pacs->record.CardNumber); - } else { - furi_string_cat_printf(wiegand_str, "%d bits", pacs->record.bitLength); - } - - if(pacs->sio) { - furi_string_cat_printf(sio_str, "+SIO"); - } - - if(pacs->key) { - if(pacs->sio) { - furi_string_cat_printf(sio_str, " "); - } - furi_string_cat_printf(sio_str, "Key: "); - - uint8_t key[PICOPASS_BLOCK_LEN]; - memcpy(key, &pacs->key, PICOPASS_BLOCK_LEN); - for(uint8_t i = 0; i < PICOPASS_BLOCK_LEN; i++) { - furi_string_cat_printf(sio_str, "%02X", key[i]); - } - } - - widget_add_button_element( - widget, - GuiButtonTypeRight, - "More", - picopass_scene_read_card_success_widget_callback, - picopass); - } - - widget_add_button_element( - widget, - GuiButtonTypeLeft, - "Retry", - picopass_scene_read_card_success_widget_callback, - picopass); - - widget_add_string_element( - widget, 64, 5, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(csn_str)); - widget_add_string_element( - widget, 64, 20, AlignCenter, AlignCenter, FontPrimary, furi_string_get_cstr(wiegand_str)); - widget_add_string_element( - widget, - 64, - 36, - AlignCenter, - AlignCenter, - FontSecondary, - furi_string_get_cstr(credential_str)); - widget_add_string_element( - widget, 64, 46, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(sio_str)); - - furi_string_free(csn_str); - furi_string_free(credential_str); - furi_string_free(wiegand_str); - furi_string_free(sio_str); - - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewWidget); -} - -bool picopass_scene_read_card_success_on_event(void* context, SceneManagerEvent event) { - Picopass* picopass = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeLeft) { - consumed = scene_manager_previous_scene(picopass->scene_manager); - } else if(event.event == GuiButtonTypeRight) { - // Clear device name - picopass_device_set_name(picopass->dev, ""); - scene_manager_next_scene(picopass->scene_manager, PicopassSceneCardMenu); - consumed = true; - } else if(event.event == GuiButtonTypeCenter) { - consumed = scene_manager_search_and_switch_to_another_scene( - picopass->scene_manager, PicopassSceneStart); - } - } - return consumed; -} - -void picopass_scene_read_card_success_on_exit(void* context) { - Picopass* picopass = context; - - // Clear view - widget_reset(picopass->widget); -} diff --git a/applications/external/picopass/scenes/picopass_scene_read_factory_success.c b/applications/external/picopass/scenes/picopass_scene_read_factory_success.c deleted file mode 100644 index f5fcd10fd..000000000 --- a/applications/external/picopass/scenes/picopass_scene_read_factory_success.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "../picopass_i.h" -#include -#include "../picopass_keys.h" - -void picopass_scene_read_factory_success_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - furi_assert(context); - Picopass* picopass = context; - - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(picopass->view_dispatcher, result); - } -} - -void picopass_scene_read_factory_success_on_enter(void* context) { - Picopass* picopass = context; - FuriString* title = furi_string_alloc_set("Factory Default"); - FuriString* subtitle = furi_string_alloc_set(""); - - dolphin_deed(DolphinDeedNfcReadSuccess); - - // Send notification - notification_message(picopass->notifications, &sequence_success); - - // Setup view - Widget* widget = picopass->widget; - //PicopassPacs* pacs = &picopass->dev->dev_data.pacs; - PicopassBlock* AA1 = picopass->dev->dev_data.AA1; - - uint8_t* configBlock = AA1[PICOPASS_CONFIG_BLOCK_INDEX].data; - uint8_t fuses = configBlock[7]; - - if((fuses & 0x80) == 0x80) { - furi_string_cat_printf(subtitle, "Personalization mode"); - } else { - furi_string_cat_printf(subtitle, "Application mode"); - } - - widget_add_button_element( - widget, - GuiButtonTypeCenter, - "Write Standard iClass Key", - picopass_scene_read_factory_success_widget_callback, - picopass); - - widget_add_string_element( - widget, 64, 5, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(title)); - widget_add_string_element( - widget, 64, 20, AlignCenter, AlignCenter, FontPrimary, furi_string_get_cstr(subtitle)); - - furi_string_free(title); - furi_string_free(subtitle); - - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewWidget); -} - -bool picopass_scene_read_factory_success_on_event(void* context, SceneManagerEvent event) { - Picopass* picopass = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeLeft) { - consumed = scene_manager_previous_scene(picopass->scene_manager); - } else if(event.event == GuiButtonTypeCenter) { - memcpy(picopass->dev->dev_data.pacs.key, picopass_iclass_key, PICOPASS_BLOCK_LEN); - scene_manager_next_scene(picopass->scene_manager, PicopassSceneWriteKey); - consumed = true; - } - } - return consumed; -} - -void picopass_scene_read_factory_success_on_exit(void* context) { - Picopass* picopass = context; - - // Clear view - widget_reset(picopass->widget); -} diff --git a/applications/external/picopass/scenes/picopass_scene_save_name.c b/applications/external/picopass/scenes/picopass_scene_save_name.c deleted file mode 100644 index baf882b80..000000000 --- a/applications/external/picopass/scenes/picopass_scene_save_name.c +++ /dev/null @@ -1,81 +0,0 @@ -#include "../picopass_i.h" -#include -#include -#include - -void picopass_scene_save_name_text_input_callback(void* context) { - Picopass* picopass = context; - - view_dispatcher_send_custom_event(picopass->view_dispatcher, PicopassCustomEventTextInputDone); -} - -void picopass_scene_save_name_on_enter(void* context) { - Picopass* picopass = context; - - // Setup view - TextInput* text_input = picopass->text_input; - bool dev_name_empty = false; - if(!strcmp(picopass->dev->dev_name, "")) { - set_random_name(picopass->text_store, sizeof(picopass->text_store)); - dev_name_empty = true; - } else { - picopass_text_store_set(picopass, picopass->dev->dev_name); - } - text_input_set_header_text(text_input, "Name the card"); - text_input_set_result_callback( - text_input, - picopass_scene_save_name_text_input_callback, - picopass, - picopass->text_store, - PICOPASS_DEV_NAME_MAX_LEN, - dev_name_empty); - - FuriString* folder_path; - folder_path = furi_string_alloc_set(STORAGE_APP_DATA_PATH_PREFIX); - - if(furi_string_end_with(picopass->dev->load_path, PICOPASS_APP_EXTENSION)) { - path_extract_dirname(furi_string_get_cstr(picopass->dev->load_path), folder_path); - } - - ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - furi_string_get_cstr(folder_path), PICOPASS_APP_EXTENSION, picopass->dev->dev_name); - text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewTextInput); - - furi_string_free(folder_path); -} - -bool picopass_scene_save_name_on_event(void* context, SceneManagerEvent event) { - Picopass* picopass = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == PicopassCustomEventTextInputDone) { - if(strcmp(picopass->dev->dev_name, "") != 0) { - // picopass_device_delete(picopass->dev, true); - } - strlcpy( - picopass->dev->dev_name, picopass->text_store, strlen(picopass->text_store) + 1); - if(picopass_device_save(picopass->dev, picopass->text_store)) { - scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveSuccess); - consumed = true; - } else { - consumed = scene_manager_search_and_switch_to_previous_scene( - picopass->scene_manager, PicopassSceneStart); - } - } - } - return consumed; -} - -void picopass_scene_save_name_on_exit(void* context) { - Picopass* picopass = context; - - // Clear view - void* validator_context = text_input_get_validator_callback_context(picopass->text_input); - text_input_set_validator(picopass->text_input, NULL, NULL); - validator_is_file_free(validator_context); - - text_input_reset(picopass->text_input); -} diff --git a/applications/external/picopass/scenes/picopass_scene_save_success.c b/applications/external/picopass/scenes/picopass_scene_save_success.c deleted file mode 100644 index 3b0a1cadd..000000000 --- a/applications/external/picopass/scenes/picopass_scene_save_success.c +++ /dev/null @@ -1,47 +0,0 @@ -#include "../picopass_i.h" -#include - -void picopass_scene_save_success_popup_callback(void* context) { - Picopass* picopass = context; - view_dispatcher_send_custom_event(picopass->view_dispatcher, PicopassCustomEventViewExit); -} - -void picopass_scene_save_success_on_enter(void* context) { - Picopass* picopass = context; - dolphin_deed(DolphinDeedNfcSave); - - // Setup view - Popup* popup = picopass->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, picopass); - popup_set_callback(popup, picopass_scene_save_success_popup_callback); - popup_enable_timeout(popup); - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewPopup); -} - -bool picopass_scene_save_success_on_event(void* context, SceneManagerEvent event) { - Picopass* picopass = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == PicopassCustomEventViewExit) { - if(scene_manager_has_previous_scene(picopass->scene_manager, PicopassSceneCardMenu)) { - consumed = scene_manager_search_and_switch_to_previous_scene( - picopass->scene_manager, PicopassSceneCardMenu); - } else { - consumed = scene_manager_search_and_switch_to_previous_scene( - picopass->scene_manager, PicopassSceneStart); - } - } - } - return consumed; -} - -void picopass_scene_save_success_on_exit(void* context) { - Picopass* picopass = context; - - // Clear view - popup_reset(picopass->popup); -} diff --git a/applications/external/picopass/scenes/picopass_scene_saved_menu.c b/applications/external/picopass/scenes/picopass_scene_saved_menu.c deleted file mode 100644 index 90a27ee81..000000000 --- a/applications/external/picopass/scenes/picopass_scene_saved_menu.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "../picopass_i.h" - -enum SubmenuIndex { - SubmenuIndexDelete, - SubmenuIndexInfo, - SubmenuIndexWrite, -}; - -void picopass_scene_saved_menu_submenu_callback(void* context, uint32_t index) { - Picopass* picopass = context; - - view_dispatcher_send_custom_event(picopass->view_dispatcher, index); -} - -void picopass_scene_saved_menu_on_enter(void* context) { - Picopass* picopass = context; - Submenu* submenu = picopass->submenu; - - submenu_add_item( - submenu, - "Delete", - SubmenuIndexDelete, - picopass_scene_saved_menu_submenu_callback, - picopass); - submenu_add_item( - submenu, "Info", SubmenuIndexInfo, picopass_scene_saved_menu_submenu_callback, picopass); - submenu_add_item( - submenu, "Write", SubmenuIndexWrite, picopass_scene_saved_menu_submenu_callback, picopass); - - submenu_set_selected_item( - picopass->submenu, - scene_manager_get_scene_state(picopass->scene_manager, PicopassSceneSavedMenu)); - - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewMenu); -} - -bool picopass_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { - Picopass* picopass = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - scene_manager_set_scene_state( - picopass->scene_manager, PicopassSceneSavedMenu, event.event); - - if(event.event == SubmenuIndexDelete) { - scene_manager_next_scene(picopass->scene_manager, PicopassSceneDelete); - consumed = true; - } else if(event.event == SubmenuIndexInfo) { - scene_manager_next_scene(picopass->scene_manager, PicopassSceneDeviceInfo); - consumed = true; - } else if(event.event == SubmenuIndexWrite) { - scene_manager_next_scene(picopass->scene_manager, PicopassSceneWriteCard); - consumed = true; - } - } - - return consumed; -} - -void picopass_scene_saved_menu_on_exit(void* context) { - Picopass* picopass = context; - - submenu_reset(picopass->submenu); -} diff --git a/applications/external/picopass/scenes/picopass_scene_start.c b/applications/external/picopass/scenes/picopass_scene_start.c deleted file mode 100644 index 8f7b627aa..000000000 --- a/applications/external/picopass/scenes/picopass_scene_start.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "../picopass_i.h" -enum SubmenuIndex { - SubmenuIndexRead, - SubmenuIndexEliteDictAttack, - SubmenuIndexSaved, -}; - -void picopass_scene_start_submenu_callback(void* context, uint32_t index) { - Picopass* picopass = context; - view_dispatcher_send_custom_event(picopass->view_dispatcher, index); -} -void picopass_scene_start_on_enter(void* context) { - Picopass* picopass = context; - - Submenu* submenu = picopass->submenu; - submenu_add_item( - submenu, "Read Card", SubmenuIndexRead, picopass_scene_start_submenu_callback, picopass); - submenu_add_item( - submenu, - "Elite Dict. Attack", - SubmenuIndexEliteDictAttack, - picopass_scene_start_submenu_callback, - picopass); - submenu_add_item( - submenu, "Saved", SubmenuIndexSaved, picopass_scene_start_submenu_callback, picopass); - - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(picopass->scene_manager, PicopassSceneStart)); - picopass_device_clear(picopass->dev); - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewMenu); -} - -bool picopass_scene_start_on_event(void* context, SceneManagerEvent event) { - Picopass* picopass = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexRead) { - scene_manager_set_scene_state( - picopass->scene_manager, PicopassSceneStart, SubmenuIndexRead); - scene_manager_next_scene(picopass->scene_manager, PicopassSceneReadCard); - consumed = true; - } else if(event.event == SubmenuIndexSaved) { - // Explicitly save state so that the correct item is - // reselected if the user cancels loading a file. - scene_manager_set_scene_state( - picopass->scene_manager, PicopassSceneStart, SubmenuIndexSaved); - scene_manager_next_scene(picopass->scene_manager, PicopassSceneFileSelect); - consumed = true; - } else if(event.event == SubmenuIndexEliteDictAttack) { - scene_manager_set_scene_state( - picopass->scene_manager, PicopassSceneStart, SubmenuIndexEliteDictAttack); - scene_manager_next_scene(picopass->scene_manager, PicopassSceneEliteDictAttack); - consumed = true; - } - } - - return consumed; -} - -void picopass_scene_start_on_exit(void* context) { - Picopass* picopass = context; - submenu_reset(picopass->submenu); -} diff --git a/applications/external/picopass/scenes/picopass_scene_write_card.c b/applications/external/picopass/scenes/picopass_scene_write_card.c deleted file mode 100644 index ce396fc10..000000000 --- a/applications/external/picopass/scenes/picopass_scene_write_card.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "../picopass_i.h" -#include - -void picopass_write_card_worker_callback(PicopassWorkerEvent event, void* context) { - UNUSED(event); - Picopass* picopass = context; - view_dispatcher_send_custom_event(picopass->view_dispatcher, PicopassCustomEventWorkerExit); -} - -void picopass_scene_write_card_on_enter(void* context) { - Picopass* picopass = context; - dolphin_deed(DolphinDeedNfcSave); - - // Setup view - Popup* popup = picopass->popup; - popup_set_header(popup, "Writing\npicopass\ncard", 68, 30, AlignLeft, AlignTop); - popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61); - - // Start worker - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewPopup); - picopass_worker_start( - picopass->worker, - PicopassWorkerStateWrite, - &picopass->dev->dev_data, - picopass_write_card_worker_callback, - picopass); - - picopass_blink_start(picopass); -} - -bool picopass_scene_write_card_on_event(void* context, SceneManagerEvent event) { - Picopass* picopass = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == PicopassCustomEventWorkerExit) { - scene_manager_next_scene(picopass->scene_manager, PicopassSceneWriteCardSuccess); - consumed = true; - } - } - return consumed; -} - -void picopass_scene_write_card_on_exit(void* context) { - Picopass* picopass = context; - - // Stop worker - picopass_worker_stop(picopass->worker); - // Clear view - popup_reset(picopass->popup); - - picopass_blink_stop(picopass); -} diff --git a/applications/external/picopass/scenes/picopass_scene_write_card_success.c b/applications/external/picopass/scenes/picopass_scene_write_card_success.c deleted file mode 100644 index cd760272f..000000000 --- a/applications/external/picopass/scenes/picopass_scene_write_card_success.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "../picopass_i.h" -#include - -void picopass_scene_write_card_success_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - furi_assert(context); - Picopass* picopass = context; - - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(picopass->view_dispatcher, result); - } -} - -void picopass_scene_write_card_success_on_enter(void* context) { - Picopass* picopass = context; - Widget* widget = picopass->widget; - FuriString* str = furi_string_alloc_set("Write Success!"); - - dolphin_deed(DolphinDeedNfcReadSuccess); - - // Send notification - notification_message(picopass->notifications, &sequence_success); - - widget_add_button_element( - widget, - GuiButtonTypeLeft, - "Retry", - picopass_scene_write_card_success_widget_callback, - picopass); - - widget_add_button_element( - widget, - GuiButtonTypeRight, - "Menu", - picopass_scene_write_card_success_widget_callback, - picopass); - - widget_add_string_element( - widget, 64, 5, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(str)); - - furi_string_free(str); - - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewWidget); -} - -bool picopass_scene_write_card_success_on_event(void* context, SceneManagerEvent event) { - Picopass* picopass = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeLeft) { - consumed = scene_manager_previous_scene(picopass->scene_manager); - } else if(event.event == GuiButtonTypeRight) { - // Clear device name - picopass_device_set_name(picopass->dev, ""); - scene_manager_next_scene(picopass->scene_manager, PicopassSceneCardMenu); - consumed = true; - } - } - return consumed; -} - -void picopass_scene_write_card_success_on_exit(void* context) { - Picopass* picopass = context; - - // Clear view - widget_reset(picopass->widget); -} diff --git a/applications/external/picopass/scenes/picopass_scene_write_key.c b/applications/external/picopass/scenes/picopass_scene_write_key.c deleted file mode 100644 index 806a2b5a8..000000000 --- a/applications/external/picopass/scenes/picopass_scene_write_key.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "../picopass_i.h" -#include - -void picopass_write_key_worker_callback(PicopassWorkerEvent event, void* context) { - UNUSED(event); - Picopass* picopass = context; - view_dispatcher_send_custom_event(picopass->view_dispatcher, PicopassCustomEventWorkerExit); -} - -void picopass_scene_write_key_on_enter(void* context) { - Picopass* picopass = context; - dolphin_deed(DolphinDeedNfcSave); - - // Setup view - Popup* popup = picopass->popup; - popup_set_header(popup, "Writing\niClass\nkey", 68, 30, AlignLeft, AlignTop); - popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61); - - // Start worker - view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewPopup); - picopass_worker_start( - picopass->worker, - PicopassWorkerStateWriteKey, - &picopass->dev->dev_data, - picopass_write_key_worker_callback, - picopass); - - picopass_blink_start(picopass); -} - -bool picopass_scene_write_key_on_event(void* context, SceneManagerEvent event) { - Picopass* picopass = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == PicopassCustomEventWorkerExit) { - scene_manager_next_scene(picopass->scene_manager, PicopassSceneWriteCardSuccess); - consumed = true; - } - } - return consumed; -} - -void picopass_scene_write_key_on_exit(void* context) { - Picopass* picopass = context; - - // Stop worker - picopass_worker_stop(picopass->worker); - // Clear view - popup_reset(picopass->popup); - - picopass_blink_stop(picopass); -} diff --git a/applications/external/picopass/views/dict_attack.c b/applications/external/picopass/views/dict_attack.c deleted file mode 100644 index fb7335f6c..000000000 --- a/applications/external/picopass/views/dict_attack.c +++ /dev/null @@ -1,281 +0,0 @@ -#include "dict_attack.h" - -#include - -typedef enum { - DictAttackStateRead, - DictAttackStateCardRemoved, -} DictAttackState; - -struct DictAttack { - View* view; - DictAttackCallback callback; - void* context; -}; - -typedef struct { - DictAttackState state; - MfClassicType type; - FuriString* header; - uint8_t sectors_total; - uint8_t sectors_read; - uint8_t sector_current; - uint8_t keys_total; - uint8_t keys_found; - uint16_t dict_keys_total; - uint16_t dict_keys_current; - bool is_key_attack; - uint8_t key_attack_current_sector; -} DictAttackViewModel; - -static void dict_attack_draw_callback(Canvas* canvas, void* model) { - DictAttackViewModel* m = model; - if(m->state == DictAttackStateCardRemoved) { - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 64, 4, AlignCenter, AlignTop, "Lost the tag!"); - canvas_set_font(canvas, FontSecondary); - elements_multiline_text_aligned( - canvas, 64, 23, AlignCenter, AlignTop, "Make sure the tag is\npositioned correctly."); - } else if(m->state == DictAttackStateRead) { - char draw_str[32] = {}; - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned( - canvas, 64, 0, AlignCenter, AlignTop, furi_string_get_cstr(m->header)); - if(m->is_key_attack) { - snprintf( - draw_str, - sizeof(draw_str), - "Reuse key check for sector: %d", - m->key_attack_current_sector); - } else { - snprintf(draw_str, sizeof(draw_str), "Unlocking sector: %d", m->sector_current); - } - canvas_draw_str_aligned(canvas, 0, 10, AlignLeft, AlignTop, draw_str); - float dict_progress = m->dict_keys_total == 0 ? - 0 : - (float)(m->dict_keys_current) / (float)(m->dict_keys_total); - float progress = m->sectors_total == 0 ? 0 : - ((float)(m->sector_current) + dict_progress) / - (float)(m->sectors_total); - if(progress > 1.0) { - progress = 1.0; - } - if(m->dict_keys_current == 0) { - // Cause when people see 0 they think it's broken - snprintf(draw_str, sizeof(draw_str), "%d/%d", 1, m->dict_keys_total); - } else { - snprintf( - draw_str, sizeof(draw_str), "%d/%d", m->dict_keys_current, m->dict_keys_total); - } - elements_progress_bar_with_text(canvas, 0, 20, 128, dict_progress, draw_str); - canvas_set_font(canvas, FontSecondary); - snprintf(draw_str, sizeof(draw_str), "Keys found: %d/%d", m->keys_found, m->keys_total); - canvas_draw_str_aligned(canvas, 0, 33, AlignLeft, AlignTop, draw_str); - snprintf( - draw_str, sizeof(draw_str), "Sectors Read: %d/%d", m->sectors_read, m->sectors_total); - canvas_draw_str_aligned(canvas, 0, 43, AlignLeft, AlignTop, draw_str); - } - elements_button_center(canvas, "Skip"); -} - -static bool dict_attack_input_callback(InputEvent* event, void* context) { - DictAttack* dict_attack = context; - bool consumed = false; - if(event->type == InputTypeShort && event->key == InputKeyOk) { - if(dict_attack->callback) { - dict_attack->callback(dict_attack->context); - } - consumed = true; - } - return consumed; -} - -DictAttack* dict_attack_alloc() { - DictAttack* dict_attack = malloc(sizeof(DictAttack)); - dict_attack->view = view_alloc(); - view_allocate_model(dict_attack->view, ViewModelTypeLocking, sizeof(DictAttackViewModel)); - view_set_draw_callback(dict_attack->view, dict_attack_draw_callback); - view_set_input_callback(dict_attack->view, dict_attack_input_callback); - view_set_context(dict_attack->view, dict_attack); - with_view_model( - dict_attack->view, - DictAttackViewModel * model, - { model->header = furi_string_alloc(); }, - false); - return dict_attack; -} - -void dict_attack_free(DictAttack* dict_attack) { - furi_assert(dict_attack); - with_view_model( - dict_attack->view, - DictAttackViewModel * model, - { furi_string_free(model->header); }, - false); - view_free(dict_attack->view); - free(dict_attack); -} - -void dict_attack_reset(DictAttack* dict_attack) { - furi_assert(dict_attack); - with_view_model( - dict_attack->view, - DictAttackViewModel * model, - { - model->state = DictAttackStateRead; - model->type = MfClassicType1k; - model->sectors_total = 1; - model->sectors_read = 0; - model->sector_current = 0; - model->keys_total = 0; - model->keys_found = 0; - model->dict_keys_total = 0; - model->dict_keys_current = 0; - model->is_key_attack = false; - furi_string_reset(model->header); - }, - false); -} - -View* dict_attack_get_view(DictAttack* dict_attack) { - furi_assert(dict_attack); - return dict_attack->view; -} - -void dict_attack_set_callback(DictAttack* dict_attack, DictAttackCallback callback, void* context) { - furi_assert(dict_attack); - furi_assert(callback); - dict_attack->callback = callback; - dict_attack->context = context; -} - -void dict_attack_set_header(DictAttack* dict_attack, const char* header) { - furi_assert(dict_attack); - furi_assert(header); - - with_view_model( - dict_attack->view, - DictAttackViewModel * model, - { furi_string_set(model->header, header); }, - true); -} - -void dict_attack_set_card_detected(DictAttack* dict_attack) { - furi_assert(dict_attack); - with_view_model( - dict_attack->view, - DictAttackViewModel * model, - { - model->state = DictAttackStateRead; - model->sectors_total = 1; - model->keys_total = model->sectors_total; - }, - true); -} - -void dict_attack_set_card_removed(DictAttack* dict_attack) { - furi_assert(dict_attack); - with_view_model( - dict_attack->view, - DictAttackViewModel * model, - { model->state = DictAttackStateCardRemoved; }, - true); -} - -void dict_attack_set_sector_read(DictAttack* dict_attack, uint8_t sec_read) { - furi_assert(dict_attack); - with_view_model( - dict_attack->view, DictAttackViewModel * model, { model->sectors_read = sec_read; }, true); -} - -void dict_attack_set_keys_found(DictAttack* dict_attack, uint8_t keys_found) { - furi_assert(dict_attack); - with_view_model( - dict_attack->view, DictAttackViewModel * model, { model->keys_found = keys_found; }, true); -} - -void dict_attack_set_current_sector(DictAttack* dict_attack, uint8_t curr_sec) { - furi_assert(dict_attack); - with_view_model( - dict_attack->view, - DictAttackViewModel * model, - { - model->sector_current = curr_sec; - model->dict_keys_current = 0; - }, - true); -} - -void dict_attack_inc_current_sector(DictAttack* dict_attack) { - furi_assert(dict_attack); - with_view_model( - dict_attack->view, - DictAttackViewModel * model, - { - if(model->sector_current < model->sectors_total) { - model->sector_current++; - model->dict_keys_current = 0; - } - }, - true); -} - -void dict_attack_inc_keys_found(DictAttack* dict_attack) { - furi_assert(dict_attack); - with_view_model( - dict_attack->view, - DictAttackViewModel * model, - { - if(model->keys_found < model->keys_total) { - model->keys_found++; - } - }, - true); -} - -void dict_attack_set_total_dict_keys(DictAttack* dict_attack, uint16_t dict_keys_total) { - furi_assert(dict_attack); - with_view_model( - dict_attack->view, - DictAttackViewModel * model, - { model->dict_keys_total = dict_keys_total; }, - true); -} - -void dict_attack_inc_current_dict_key(DictAttack* dict_attack, uint16_t keys_tried) { - furi_assert(dict_attack); - with_view_model( - dict_attack->view, - DictAttackViewModel * model, - { - if(model->dict_keys_current + keys_tried < model->dict_keys_total) { - model->dict_keys_current += keys_tried; - } - }, - true); -} - -void dict_attack_set_key_attack(DictAttack* dict_attack, bool is_key_attack, uint8_t sector) { - furi_assert(dict_attack); - with_view_model( - dict_attack->view, - DictAttackViewModel * model, - { - model->is_key_attack = is_key_attack; - model->key_attack_current_sector = sector; - }, - true); -} - -void dict_attack_inc_key_attack_current_sector(DictAttack* dict_attack) { - furi_assert(dict_attack); - with_view_model( - dict_attack->view, - DictAttackViewModel * model, - { - if(model->key_attack_current_sector < model->sectors_total) { - model->key_attack_current_sector++; - } - }, - true); -} diff --git a/applications/external/picopass/views/dict_attack.h b/applications/external/picopass/views/dict_attack.h deleted file mode 100644 index bdfa3e952..000000000 --- a/applications/external/picopass/views/dict_attack.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once -#include -#include -#include - -#include - -typedef struct DictAttack DictAttack; - -typedef void (*DictAttackCallback)(void* context); - -DictAttack* dict_attack_alloc(); - -void dict_attack_free(DictAttack* dict_attack); - -void dict_attack_reset(DictAttack* dict_attack); - -View* dict_attack_get_view(DictAttack* dict_attack); - -void dict_attack_set_callback(DictAttack* dict_attack, DictAttackCallback callback, void* context); - -void dict_attack_set_header(DictAttack* dict_attack, const char* header); - -void dict_attack_set_card_detected(DictAttack* dict_attack); - -void dict_attack_set_card_removed(DictAttack* dict_attack); - -void dict_attack_set_sector_read(DictAttack* dict_attack, uint8_t sec_read); - -void dict_attack_set_keys_found(DictAttack* dict_attack, uint8_t keys_found); - -void dict_attack_set_current_sector(DictAttack* dict_attack, uint8_t curr_sec); - -void dict_attack_inc_current_sector(DictAttack* dict_attack); - -void dict_attack_inc_keys_found(DictAttack* dict_attack); - -void dict_attack_set_total_dict_keys(DictAttack* dict_attack, uint16_t dict_keys_total); - -void dict_attack_inc_current_dict_key(DictAttack* dict_attack, uint16_t keys_tried); - -void dict_attack_set_key_attack(DictAttack* dict_attack, bool is_key_attack, uint8_t sector); - -void dict_attack_inc_key_attack_current_sector(DictAttack* dict_attack); diff --git a/applications/external/signal_generator/application.fam b/applications/external/signal_generator/application.fam deleted file mode 100644 index 094e784cc..000000000 --- a/applications/external/signal_generator/application.fam +++ /dev/null @@ -1,12 +0,0 @@ -App( - appid="signal_generator", - name="Signal Generator", - apptype=FlipperAppType.EXTERNAL, - entry_point="signal_gen_app", - requires=["gui"], - stack_size=1 * 1024, - order=50, - fap_icon="signal_gen_10px.png", - fap_category="GPIO", - fap_icon_assets="icons", -) diff --git a/applications/external/signal_generator/icons/SmallArrowDown_3x5.png b/applications/external/signal_generator/icons/SmallArrowDown_3x5.png deleted file mode 100644 index 1912e5d24..000000000 Binary files a/applications/external/signal_generator/icons/SmallArrowDown_3x5.png and /dev/null differ diff --git a/applications/external/signal_generator/icons/SmallArrowUp_3x5.png b/applications/external/signal_generator/icons/SmallArrowUp_3x5.png deleted file mode 100644 index 9c6242078..000000000 Binary files a/applications/external/signal_generator/icons/SmallArrowUp_3x5.png and /dev/null differ diff --git a/applications/external/signal_generator/scenes/signal_gen_scene.c b/applications/external/signal_generator/scenes/signal_gen_scene.c deleted file mode 100644 index 29b11ee3f..000000000 --- a/applications/external/signal_generator/scenes/signal_gen_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "../signal_gen_app_i.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const signal_gen_scene_on_enter_handlers[])(void*) = { -#include "signal_gen_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 signal_gen_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "signal_gen_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 signal_gen_scene_on_exit_handlers[])(void* context) = { -#include "signal_gen_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers signal_gen_scene_handlers = { - .on_enter_handlers = signal_gen_scene_on_enter_handlers, - .on_event_handlers = signal_gen_scene_on_event_handlers, - .on_exit_handlers = signal_gen_scene_on_exit_handlers, - .scene_num = SignalGenSceneNum, -}; diff --git a/applications/external/signal_generator/scenes/signal_gen_scene.h b/applications/external/signal_generator/scenes/signal_gen_scene.h deleted file mode 100644 index c139afa3b..000000000 --- a/applications/external/signal_generator/scenes/signal_gen_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) SignalGenScene##id, -typedef enum { -#include "signal_gen_scene_config.h" - SignalGenSceneNum, -} SignalGenScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers signal_gen_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "signal_gen_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 "signal_gen_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 "signal_gen_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/signal_generator/scenes/signal_gen_scene_config.h b/applications/external/signal_generator/scenes/signal_gen_scene_config.h deleted file mode 100644 index b6c750256..000000000 --- a/applications/external/signal_generator/scenes/signal_gen_scene_config.h +++ /dev/null @@ -1,3 +0,0 @@ -ADD_SCENE(signal_gen, start, Start) -ADD_SCENE(signal_gen, pwm, Pwm) -ADD_SCENE(signal_gen, mco, Mco) diff --git a/applications/external/signal_generator/scenes/signal_gen_scene_mco.c b/applications/external/signal_generator/scenes/signal_gen_scene_mco.c deleted file mode 100644 index 0855cde0a..000000000 --- a/applications/external/signal_generator/scenes/signal_gen_scene_mco.c +++ /dev/null @@ -1,145 +0,0 @@ -#include "../signal_gen_app_i.h" - -typedef enum { - LineIndexPin, - LineIndexSource, - LineIndexDivision, -} LineIndex; - -static const char* const mco_pin_names[] = { - "13(Tx)", -}; - -static const char* const mco_source_names[] = { - "32768Hz", - "64MHz", - "~100K", - "~200K", - "~400K", - "~800K", - "~1MHz", - "~2MHz", - "~4MHz", - "~8MHz", - "~16MHz", - "~24MHz", - "~32MHz", - "~48MHz", -}; - -static const FuriHalClockMcoSourceId mco_sources[] = { - FuriHalClockMcoLse, - FuriHalClockMcoSysclk, - FuriHalClockMcoMsi100k, - FuriHalClockMcoMsi200k, - FuriHalClockMcoMsi400k, - FuriHalClockMcoMsi800k, - FuriHalClockMcoMsi1m, - FuriHalClockMcoMsi2m, - FuriHalClockMcoMsi4m, - FuriHalClockMcoMsi8m, - FuriHalClockMcoMsi16m, - FuriHalClockMcoMsi24m, - FuriHalClockMcoMsi32m, - FuriHalClockMcoMsi48m, -}; - -static const char* const mco_divisor_names[] = { - "1", - "2", - "4", - "8", - "16", -}; - -static const FuriHalClockMcoDivisorId mco_divisors[] = { - FuriHalClockMcoDiv1, - FuriHalClockMcoDiv2, - FuriHalClockMcoDiv4, - FuriHalClockMcoDiv8, - FuriHalClockMcoDiv16, -}; - -static void mco_source_list_change_callback(VariableItem* item) { - SignalGenApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, mco_source_names[index]); - - app->mco_src = mco_sources[index]; - - view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenMcoEventUpdate); -} - -static void mco_divisor_list_change_callback(VariableItem* item) { - SignalGenApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, mco_divisor_names[index]); - - app->mco_div = mco_divisors[index]; - - view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenMcoEventUpdate); -} - -void signal_gen_scene_mco_on_enter(void* context) { - SignalGenApp* app = context; - VariableItemList* var_item_list = app->var_item_list; - - VariableItem* item; - - item = variable_item_list_add(var_item_list, "GPIO Pin", COUNT_OF(mco_pin_names), NULL, NULL); - variable_item_set_current_value_index(item, 0); - variable_item_set_current_value_text(item, mco_pin_names[0]); - - item = variable_item_list_add( - var_item_list, - "Frequency", - COUNT_OF(mco_source_names), - mco_source_list_change_callback, - app); - variable_item_set_current_value_index(item, 0); - variable_item_set_current_value_text(item, mco_source_names[0]); - - item = variable_item_list_add( - var_item_list, - "Freq. divider", - COUNT_OF(mco_divisor_names), - mco_divisor_list_change_callback, - app); - variable_item_set_current_value_index(item, 0); - variable_item_set_current_value_text(item, mco_divisor_names[0]); - - variable_item_list_set_selected_item(var_item_list, LineIndexSource); - - view_dispatcher_switch_to_view(app->view_dispatcher, SignalGenViewVarItemList); - - app->mco_src = FuriHalClockMcoLse; - app->mco_div = FuriHalClockMcoDiv1; - furi_hal_clock_mco_enable(app->mco_src, app->mco_div); - furi_hal_gpio_init_ex( - &gpio_usart_tx, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn0MCO); -} - -bool signal_gen_scene_mco_on_event(void* context, SceneManagerEvent event) { - SignalGenApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SignalGenMcoEventUpdate) { - consumed = true; - furi_hal_clock_mco_enable(app->mco_src, app->mco_div); - } - } - return consumed; -} - -void signal_gen_scene_mco_on_exit(void* context) { - SignalGenApp* app = context; - variable_item_list_reset(app->var_item_list); - furi_hal_gpio_init_ex( - &gpio_usart_tx, - GpioModeAltFunctionPushPull, - GpioPullUp, - GpioSpeedVeryHigh, - GpioAltFn7USART1); - furi_hal_clock_mco_disable(); -} diff --git a/applications/external/signal_generator/scenes/signal_gen_scene_pwm.c b/applications/external/signal_generator/scenes/signal_gen_scene_pwm.c deleted file mode 100644 index 1cadb3a1a..000000000 --- a/applications/external/signal_generator/scenes/signal_gen_scene_pwm.c +++ /dev/null @@ -1,79 +0,0 @@ -#include "../signal_gen_app_i.h" - -static const FuriHalPwmOutputId pwm_ch_id[] = { - FuriHalPwmOutputIdTim1PA7, - FuriHalPwmOutputIdLptim2PA4, -}; - -#define DEFAULT_FREQ 1000 -#define DEFAULT_DUTY 50 - -static void - signal_gen_pwm_callback(uint8_t channel_id, uint32_t freq, uint8_t duty, void* context) { - SignalGenApp* app = context; - - app->pwm_freq = freq; - app->pwm_duty = duty; - - if(app->pwm_ch != pwm_ch_id[channel_id]) { //-V1051 - app->pwm_ch_prev = app->pwm_ch; - app->pwm_ch = pwm_ch_id[channel_id]; - view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenPwmEventChannelChange); - } else { - app->pwm_ch = pwm_ch_id[channel_id]; //-V1048 - view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenPwmEventUpdate); - } -} - -void signal_gen_scene_pwm_on_enter(void* context) { - SignalGenApp* app = context; - - view_dispatcher_switch_to_view(app->view_dispatcher, SignalGenViewPwm); - - signal_gen_pwm_set_callback(app->pwm_view, signal_gen_pwm_callback, app); - - signal_gen_pwm_set_params(app->pwm_view, 0, DEFAULT_FREQ, DEFAULT_DUTY); - - if(!furi_hal_pwm_is_running(pwm_ch_id[0])) { - furi_hal_pwm_start(pwm_ch_id[0], DEFAULT_FREQ, DEFAULT_DUTY); - } else { - furi_hal_pwm_stop(pwm_ch_id[0]); - furi_hal_pwm_start(pwm_ch_id[0], DEFAULT_FREQ, DEFAULT_DUTY); - } -} - -bool signal_gen_scene_pwm_on_event(void* context, SceneManagerEvent event) { - SignalGenApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SignalGenPwmEventUpdate) { - consumed = true; - furi_hal_pwm_set_params(app->pwm_ch, app->pwm_freq, app->pwm_duty); - } else if(event.event == SignalGenPwmEventChannelChange) { - consumed = true; - // Stop previous channel PWM - if(furi_hal_pwm_is_running(app->pwm_ch_prev)) { - furi_hal_pwm_stop(app->pwm_ch_prev); - } - - // Start PWM and restart if it was starter already - if(furi_hal_pwm_is_running(app->pwm_ch)) { - furi_hal_pwm_stop(app->pwm_ch); - furi_hal_pwm_start(app->pwm_ch, app->pwm_freq, app->pwm_duty); - } else { - furi_hal_pwm_start(app->pwm_ch, app->pwm_freq, app->pwm_duty); - } - } - } - return consumed; -} - -void signal_gen_scene_pwm_on_exit(void* context) { - SignalGenApp* app = context; - variable_item_list_reset(app->var_item_list); - - if(furi_hal_pwm_is_running(app->pwm_ch)) { - furi_hal_pwm_stop(app->pwm_ch); - } -} diff --git a/applications/external/signal_generator/scenes/signal_gen_scene_start.c b/applications/external/signal_generator/scenes/signal_gen_scene_start.c deleted file mode 100644 index 3c7b9cc32..000000000 --- a/applications/external/signal_generator/scenes/signal_gen_scene_start.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "../signal_gen_app_i.h" - -typedef enum { - SubmenuIndexPwm, - SubmenuIndexClockOutput, -} SubmenuIndex; - -void signal_gen_scene_start_submenu_callback(void* context, uint32_t index) { - SignalGenApp* app = context; - - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void signal_gen_scene_start_on_enter(void* context) { - SignalGenApp* app = context; - Submenu* submenu = app->submenu; - - submenu_add_item( - submenu, "PWM Generator", SubmenuIndexPwm, signal_gen_scene_start_submenu_callback, app); - submenu_add_item( - submenu, - "Clock Generator", - SubmenuIndexClockOutput, - signal_gen_scene_start_submenu_callback, - app); - - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(app->scene_manager, SignalGenSceneStart)); - - view_dispatcher_switch_to_view(app->view_dispatcher, SignalGenViewSubmenu); -} - -bool signal_gen_scene_start_on_event(void* context, SceneManagerEvent event) { - SignalGenApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexPwm) { - scene_manager_next_scene(app->scene_manager, SignalGenScenePwm); - consumed = true; - } else if(event.event == SubmenuIndexClockOutput) { - scene_manager_next_scene(app->scene_manager, SignalGenSceneMco); - consumed = true; - } - scene_manager_set_scene_state(app->scene_manager, SignalGenSceneStart, event.event); - } - - return consumed; -} - -void signal_gen_scene_start_on_exit(void* context) { - SignalGenApp* app = context; - - submenu_reset(app->submenu); -} diff --git a/applications/external/signal_generator/signal_gen_10px.png b/applications/external/signal_generator/signal_gen_10px.png deleted file mode 100644 index 9f6dcc5d0..000000000 Binary files a/applications/external/signal_generator/signal_gen_10px.png and /dev/null differ diff --git a/applications/external/signal_generator/signal_gen_app.c b/applications/external/signal_generator/signal_gen_app.c deleted file mode 100644 index ca065d330..000000000 --- a/applications/external/signal_generator/signal_gen_app.c +++ /dev/null @@ -1,93 +0,0 @@ -#include "signal_gen_app_i.h" - -#include -#include - -static bool signal_gen_app_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - SignalGenApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool signal_gen_app_back_event_callback(void* context) { - furi_assert(context); - SignalGenApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -static void signal_gen_app_tick_event_callback(void* context) { - furi_assert(context); - SignalGenApp* app = context; - scene_manager_handle_tick_event(app->scene_manager); -} - -SignalGenApp* signal_gen_app_alloc() { - SignalGenApp* app = malloc(sizeof(SignalGenApp)); - - app->gui = furi_record_open(RECORD_GUI); - - app->view_dispatcher = view_dispatcher_alloc(); - app->scene_manager = scene_manager_alloc(&signal_gen_scene_handlers, app); - view_dispatcher_enable_queue(app->view_dispatcher); - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - - view_dispatcher_set_custom_event_callback( - app->view_dispatcher, signal_gen_app_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, signal_gen_app_back_event_callback); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, signal_gen_app_tick_event_callback, 100); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - app->var_item_list = variable_item_list_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - SignalGenViewVarItemList, - variable_item_list_get_view(app->var_item_list)); - - app->submenu = submenu_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, SignalGenViewSubmenu, submenu_get_view(app->submenu)); - - app->pwm_view = signal_gen_pwm_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, SignalGenViewPwm, signal_gen_pwm_get_view(app->pwm_view)); - - scene_manager_next_scene(app->scene_manager, SignalGenSceneStart); - - return app; -} - -void signal_gen_app_free(SignalGenApp* app) { - furi_assert(app); - - // Views - view_dispatcher_remove_view(app->view_dispatcher, SignalGenViewVarItemList); - view_dispatcher_remove_view(app->view_dispatcher, SignalGenViewSubmenu); - view_dispatcher_remove_view(app->view_dispatcher, SignalGenViewPwm); - - submenu_free(app->submenu); - variable_item_list_free(app->var_item_list); - signal_gen_pwm_free(app->pwm_view); - - // View dispatcher - view_dispatcher_free(app->view_dispatcher); - scene_manager_free(app->scene_manager); - - // Close records - furi_record_close(RECORD_GUI); - - free(app); -} - -int32_t signal_gen_app(void* p) { - UNUSED(p); - SignalGenApp* signal_gen_app = signal_gen_app_alloc(); - - view_dispatcher_run(signal_gen_app->view_dispatcher); - - signal_gen_app_free(signal_gen_app); - - return 0; -} diff --git a/applications/external/signal_generator/signal_gen_app_i.h b/applications/external/signal_generator/signal_gen_app_i.h deleted file mode 100644 index 60e4d7ed9..000000000 --- a/applications/external/signal_generator/signal_gen_app_i.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "scenes/signal_gen_scene.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include "views/signal_gen_pwm.h" - -typedef struct SignalGenApp SignalGenApp; - -struct SignalGenApp { - Gui* gui; - ViewDispatcher* view_dispatcher; - SceneManager* scene_manager; - - VariableItemList* var_item_list; - Submenu* submenu; - SignalGenPwm* pwm_view; - - FuriHalClockMcoSourceId mco_src; - FuriHalClockMcoDivisorId mco_div; - - FuriHalPwmOutputId pwm_ch_prev; - FuriHalPwmOutputId pwm_ch; - uint32_t pwm_freq; - uint8_t pwm_duty; -}; - -typedef enum { - SignalGenViewVarItemList, - SignalGenViewSubmenu, - SignalGenViewPwm, -} SignalGenAppView; - -typedef enum { - SignalGenMcoEventUpdate, - SignalGenPwmEventUpdate, - SignalGenPwmEventChannelChange, -} SignalGenCustomEvent; diff --git a/applications/external/signal_generator/views/signal_gen_pwm.c b/applications/external/signal_generator/views/signal_gen_pwm.c deleted file mode 100644 index d625ed5a9..000000000 --- a/applications/external/signal_generator/views/signal_gen_pwm.c +++ /dev/null @@ -1,310 +0,0 @@ -#include "../signal_gen_app_i.h" -#include -#include -#include - -typedef enum { - LineIndexChannel, - LineIndexFrequency, - LineIndexDuty, - LineIndexTotalCount -} LineIndex; - -static const char* const pwm_ch_names[] = {"2(A7)", "4(A4)"}; - -struct SignalGenPwm { - View* view; - SignalGenPwmViewCallback callback; - void* context; -}; - -typedef struct { - LineIndex line_sel; - bool edit_mode; - uint8_t edit_digit; - - uint8_t channel_id; - uint32_t freq; - uint8_t duty; - -} SignalGenPwmViewModel; - -#define ITEM_H 64 / 3 -#define ITEM_W 128 - -#define VALUE_X 100 -#define VALUE_W 45 - -#define FREQ_VALUE_X 62 -#define FREQ_MAX 1000000UL -#define FREQ_DIGITS_NB 7 - -static void pwm_set_config(SignalGenPwm* pwm) { - FuriHalPwmOutputId channel; - uint32_t freq; - uint8_t duty; - - with_view_model( - pwm->view, - SignalGenPwmViewModel * model, - { - channel = model->channel_id; - freq = model->freq; - duty = model->duty; - }, - false); - - furi_assert(pwm->callback); - pwm->callback(channel, freq, duty, pwm->context); -} - -static void pwm_channel_change(SignalGenPwmViewModel* model, InputEvent* event) { - if(event->key == InputKeyLeft) { - if(model->channel_id > 0) { - model->channel_id--; - } - } else if(event->key == InputKeyRight) { - if(model->channel_id < (COUNT_OF(pwm_ch_names) - 1)) { - model->channel_id++; - } - } -} - -static void pwm_duty_change(SignalGenPwmViewModel* model, InputEvent* event) { - if(event->key == InputKeyLeft) { - if(model->duty > 0) { - model->duty--; - } - } else if(event->key == InputKeyRight) { - if(model->duty < 100) { - model->duty++; - } - } -} - -static bool pwm_freq_edit(SignalGenPwmViewModel* model, InputEvent* event) { - bool consumed = false; - if((event->type == InputTypeShort) || (event->type == InputTypeRepeat)) { - if(event->key == InputKeyRight) { - if(model->edit_digit > 0) { - model->edit_digit--; - } - consumed = true; - } else if(event->key == InputKeyLeft) { - if(model->edit_digit < (FREQ_DIGITS_NB - 1)) { - model->edit_digit++; - } - consumed = true; - } else if(event->key == InputKeyUp) { - uint32_t step = 1; - for(uint8_t i = 0; i < model->edit_digit; i++) { - step *= 10; - } - if((model->freq + step) < FREQ_MAX) { - model->freq += step; - } else { - model->freq = FREQ_MAX; - } - consumed = true; - } else if(event->key == InputKeyDown) { - uint32_t step = 1; - for(uint8_t i = 0; i < model->edit_digit; i++) { - step *= 10; - } - if(model->freq > (step + 1)) { - model->freq -= step; - } else { - model->freq = 1; - } - consumed = true; - } - } - return consumed; -} - -static void signal_gen_pwm_draw_callback(Canvas* canvas, void* _model) { - SignalGenPwmViewModel* model = _model; - char* line_label = NULL; - char val_text[16]; - - for(size_t line = 0; line < LineIndexTotalCount; line++) { - if(line == LineIndexChannel) { - line_label = "GPIO Pin"; - } else if(line == LineIndexFrequency) { - line_label = "Frequency"; - } else if(line == LineIndexDuty) { //-V547 - line_label = "Pulse width"; - } - - canvas_set_color(canvas, ColorBlack); - if(line == model->line_sel) { - elements_slightly_rounded_box(canvas, 0, ITEM_H * line + 1, ITEM_W, ITEM_H - 1); - canvas_set_color(canvas, ColorWhite); - } - - uint8_t text_y = ITEM_H * line + ITEM_H / 2 + 2; - - canvas_draw_str_aligned(canvas, 6, text_y, AlignLeft, AlignCenter, line_label); - - if(line == LineIndexChannel) { - snprintf(val_text, sizeof(val_text), "%s", pwm_ch_names[model->channel_id]); - canvas_draw_str_aligned(canvas, VALUE_X, text_y, AlignCenter, AlignCenter, val_text); - if(model->channel_id != 0) { - canvas_draw_str_aligned( - canvas, VALUE_X - VALUE_W / 2, text_y, AlignCenter, AlignCenter, "<"); - } - if(model->channel_id != (COUNT_OF(pwm_ch_names) - 1)) { - canvas_draw_str_aligned( - canvas, VALUE_X + VALUE_W / 2, text_y, AlignCenter, AlignCenter, ">"); - } - } else if(line == LineIndexFrequency) { - snprintf(val_text, sizeof(val_text), "%7lu Hz", model->freq); - canvas_set_font(canvas, FontKeyboard); - canvas_draw_str_aligned( - canvas, FREQ_VALUE_X, text_y, AlignLeft, AlignCenter, val_text); - canvas_set_font(canvas, FontSecondary); - - if(model->edit_mode) { - uint8_t icon_x = (FREQ_VALUE_X) + (FREQ_DIGITS_NB - model->edit_digit - 1) * 6; - canvas_draw_icon(canvas, icon_x, text_y - 9, &I_SmallArrowUp_3x5); - canvas_draw_icon(canvas, icon_x, text_y + 5, &I_SmallArrowDown_3x5); - } - } else if(line == LineIndexDuty) { //-V547 - snprintf(val_text, sizeof(val_text), "%d%%", model->duty); - canvas_draw_str_aligned(canvas, VALUE_X, text_y, AlignCenter, AlignCenter, val_text); - if(model->duty != 0) { - canvas_draw_str_aligned( - canvas, VALUE_X - VALUE_W / 2, text_y, AlignCenter, AlignCenter, "<"); - } - if(model->duty != 100) { - canvas_draw_str_aligned( - canvas, VALUE_X + VALUE_W / 2, text_y, AlignCenter, AlignCenter, ">"); - } - } - } -} - -static bool signal_gen_pwm_input_callback(InputEvent* event, void* context) { - furi_assert(context); - SignalGenPwm* pwm = context; - bool consumed = false; - bool need_update = false; - - with_view_model( - pwm->view, - SignalGenPwmViewModel * model, - { - if(model->edit_mode == false) { - if((event->type == InputTypeShort) || (event->type == InputTypeRepeat)) { - if(event->key == InputKeyUp) { - if(model->line_sel == 0) { - model->line_sel = LineIndexTotalCount - 1; - } else { - model->line_sel = - CLAMP(model->line_sel - 1, LineIndexTotalCount - 1, 0); - } - consumed = true; - } else if(event->key == InputKeyDown) { - if(model->line_sel == LineIndexTotalCount - 1) { - model->line_sel = 0; - } else { - model->line_sel = - CLAMP(model->line_sel + 1, LineIndexTotalCount - 1, 0); - } - consumed = true; - } else if((event->key == InputKeyLeft) || (event->key == InputKeyRight)) { - if(model->line_sel == LineIndexChannel) { - pwm_channel_change(model, event); - need_update = true; - } else if(model->line_sel == LineIndexDuty) { - pwm_duty_change(model, event); - need_update = true; - } else if(model->line_sel == LineIndexFrequency) { - model->edit_mode = true; - } - consumed = true; - } else if(event->key == InputKeyOk) { - if(model->line_sel == LineIndexFrequency) { - model->edit_mode = true; - } - consumed = true; - } - } - } else { - if((event->key == InputKeyOk) || (event->key == InputKeyBack)) { - if(event->type == InputTypeShort) { - model->edit_mode = false; - consumed = true; - } - } else { - if(model->line_sel == LineIndexFrequency) { - consumed = pwm_freq_edit(model, event); - need_update = consumed; - } - } - } - }, - true); - - if(need_update) { - pwm_set_config(pwm); - } - - return consumed; -} - -SignalGenPwm* signal_gen_pwm_alloc() { - SignalGenPwm* pwm = malloc(sizeof(SignalGenPwm)); - - pwm->view = view_alloc(); - view_allocate_model(pwm->view, ViewModelTypeLocking, sizeof(SignalGenPwmViewModel)); - view_set_context(pwm->view, pwm); - view_set_draw_callback(pwm->view, signal_gen_pwm_draw_callback); - view_set_input_callback(pwm->view, signal_gen_pwm_input_callback); - - return pwm; -} - -void signal_gen_pwm_free(SignalGenPwm* pwm) { - furi_assert(pwm); - view_free(pwm->view); - free(pwm); -} - -View* signal_gen_pwm_get_view(SignalGenPwm* pwm) { - furi_assert(pwm); - return pwm->view; -} - -void signal_gen_pwm_set_callback( - SignalGenPwm* pwm, - SignalGenPwmViewCallback callback, - void* context) { - furi_assert(pwm); - furi_assert(callback); - - with_view_model( - pwm->view, - SignalGenPwmViewModel * model, - { - UNUSED(model); - pwm->callback = callback; - pwm->context = context; - }, - false); -} - -void signal_gen_pwm_set_params(SignalGenPwm* pwm, uint8_t channel_id, uint32_t freq, uint8_t duty) { - with_view_model( - pwm->view, - SignalGenPwmViewModel * model, - { - model->channel_id = channel_id; - model->freq = freq; - model->duty = duty; - }, - true); - - furi_assert(pwm->callback); - pwm->callback(channel_id, freq, duty, pwm->context); -} diff --git a/applications/external/signal_generator/views/signal_gen_pwm.h b/applications/external/signal_generator/views/signal_gen_pwm.h deleted file mode 100644 index 986794e7a..000000000 --- a/applications/external/signal_generator/views/signal_gen_pwm.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include -#include "../signal_gen_app_i.h" - -typedef struct SignalGenPwm SignalGenPwm; -typedef void ( - *SignalGenPwmViewCallback)(uint8_t channel_id, uint32_t freq, uint8_t duty, void* context); - -SignalGenPwm* signal_gen_pwm_alloc(); - -void signal_gen_pwm_free(SignalGenPwm* pwm); - -View* signal_gen_pwm_get_view(SignalGenPwm* pwm); - -void signal_gen_pwm_set_callback( - SignalGenPwm* pwm, - SignalGenPwmViewCallback callback, - void* context); - -void signal_gen_pwm_set_params(SignalGenPwm* pwm, uint8_t channel_id, uint32_t freq, uint8_t duty); diff --git a/applications/external/spi_mem_manager/application.fam b/applications/external/spi_mem_manager/application.fam deleted file mode 100644 index c1b10bfee..000000000 --- a/applications/external/spi_mem_manager/application.fam +++ /dev/null @@ -1,17 +0,0 @@ -App( - appid="spi_mem_manager", - name="SPI Mem Manager", - apptype=FlipperAppType.EXTERNAL, - entry_point="spi_mem_app", - requires=["gui"], - stack_size=1 * 2048, - order=30, - fap_icon="images/Dip8_10px.png", - fap_category="GPIO", - fap_icon_assets="images", - fap_private_libs=[ - Lib( - name="spi", - ), - ], -) diff --git a/applications/external/spi_mem_manager/images/ChipLooking_64x64/frame_01.png b/applications/external/spi_mem_manager/images/ChipLooking_64x64/frame_01.png deleted file mode 100644 index 4ff2e3042..000000000 Binary files a/applications/external/spi_mem_manager/images/ChipLooking_64x64/frame_01.png and /dev/null differ diff --git a/applications/external/spi_mem_manager/images/ChipLooking_64x64/frame_02.png b/applications/external/spi_mem_manager/images/ChipLooking_64x64/frame_02.png deleted file mode 100644 index 8893a4881..000000000 Binary files a/applications/external/spi_mem_manager/images/ChipLooking_64x64/frame_02.png and /dev/null differ diff --git a/applications/external/spi_mem_manager/images/ChipLooking_64x64/frame_03.png b/applications/external/spi_mem_manager/images/ChipLooking_64x64/frame_03.png deleted file mode 100644 index 1342dc7bf..000000000 Binary files a/applications/external/spi_mem_manager/images/ChipLooking_64x64/frame_03.png and /dev/null differ diff --git a/applications/external/spi_mem_manager/images/ChipLooking_64x64/frame_rate b/applications/external/spi_mem_manager/images/ChipLooking_64x64/frame_rate deleted file mode 100644 index d8263ee98..000000000 --- a/applications/external/spi_mem_manager/images/ChipLooking_64x64/frame_rate +++ /dev/null @@ -1 +0,0 @@ -2 \ No newline at end of file diff --git a/applications/external/spi_mem_manager/images/Dip8_10px.png b/applications/external/spi_mem_manager/images/Dip8_10px.png deleted file mode 100644 index 9de9364d1..000000000 Binary files a/applications/external/spi_mem_manager/images/Dip8_10px.png and /dev/null differ diff --git a/applications/external/spi_mem_manager/images/Dip8_32x36.png b/applications/external/spi_mem_manager/images/Dip8_32x36.png deleted file mode 100644 index 8f01af276..000000000 Binary files a/applications/external/spi_mem_manager/images/Dip8_32x36.png and /dev/null differ diff --git a/applications/external/spi_mem_manager/images/DolphinMafia_115x62.png b/applications/external/spi_mem_manager/images/DolphinMafia_115x62.png deleted file mode 100644 index 66fdb40ff..000000000 Binary files a/applications/external/spi_mem_manager/images/DolphinMafia_115x62.png and /dev/null differ diff --git a/applications/external/spi_mem_manager/images/DolphinNice_96x59.png b/applications/external/spi_mem_manager/images/DolphinNice_96x59.png deleted file mode 100644 index a299d3630..000000000 Binary files a/applications/external/spi_mem_manager/images/DolphinNice_96x59.png and /dev/null differ diff --git a/applications/external/spi_mem_manager/images/SDQuestion_35x43.png b/applications/external/spi_mem_manager/images/SDQuestion_35x43.png deleted file mode 100644 index 9b9c9a58e..000000000 Binary files a/applications/external/spi_mem_manager/images/SDQuestion_35x43.png and /dev/null differ diff --git a/applications/external/spi_mem_manager/images/Wiring_SPI_128x64.png b/applications/external/spi_mem_manager/images/Wiring_SPI_128x64.png deleted file mode 100644 index e6c3ce363..000000000 Binary files a/applications/external/spi_mem_manager/images/Wiring_SPI_128x64.png and /dev/null differ diff --git a/applications/external/spi_mem_manager/lib/spi/spi_mem_chip.c b/applications/external/spi_mem_manager/lib/spi/spi_mem_chip.c deleted file mode 100644 index f7f98dce2..000000000 --- a/applications/external/spi_mem_manager/lib/spi/spi_mem_chip.c +++ /dev/null @@ -1,105 +0,0 @@ -#include "spi_mem_chip_i.h" - -const SPIMemChipVendorName spi_mem_chip_vendor_names[] = { - {"Adesto", SPIMemChipVendorADESTO}, - {"AMIC", SPIMemChipVendorAMIC}, - {"Boya", SPIMemChipVendorBoya}, - {"EON", SPIMemChipVendorEON}, - {"PFlash", SPIMemChipVendorPFLASH}, - {"Terra", SPIMemChipVendorTERRA}, - {"Generalplus", SPIMemChipVendorGeneralplus}, - {"Deutron", SPIMemChipVendorDEUTRON}, - {"EFST", SPIMemChipVendorEFST}, - {"Excel Semi.", SPIMemChipVendorEXCELSEMI}, - {"Fidelix", SPIMemChipVendorFIDELIX}, - {"GigaDevice", SPIMemChipVendorGIGADEVICE}, - {"ICE", SPIMemChipVendorICE}, - {"Intel", SPIMemChipVendorINTEL}, - {"KHIC", SPIMemChipVendorKHIC}, - {"Macronix", SPIMemChipVendorMACRONIX}, - {"Micron", SPIMemChipVendorMICRON}, - {"Mshine", SPIMemChipVendorMSHINE}, - {"Nantronics", SPIMemChipVendorNANTRONICS}, - {"Nexflash", SPIMemChipVendorNEXFLASH}, - {"Numonyx", SPIMemChipVendorNUMONYX}, - {"PCT", SPIMemChipVendorPCT}, - {"Spansion", SPIMemChipVendorSPANSION}, - {"SST", SPIMemChipVendorSST}, - {"ST", SPIMemChipVendorST}, - {"Winbond", SPIMemChipVendorWINBOND}, - {"Zempro", SPIMemChipVendorZEMPRO}, - {"Zbit", SPIMemChipVendorZbit}, - {"Berg Micro.", SPIMemChipVendorBerg_Micro}, - {"Atmel", SPIMemChipVendorATMEL}, - {"ACE", SPIMemChipVendorACE}, - {"ATO", SPIMemChipVendorATO}, - {"Douqi", SPIMemChipVendorDOUQI}, - {"Fremont", SPIMemChipVendorFremont}, - {"Fudan", SPIMemChipVendorFudan}, - {"Genitop", SPIMemChipVendorGenitop}, - {"Paragon", SPIMemChipVendorParagon}, - {"Unknown", SPIMemChipVendorUnknown}}; - -static const char* spi_mem_chip_search_vendor_name(SPIMemChipVendor vendor_enum) { - const SPIMemChipVendorName* vendor = spi_mem_chip_vendor_names; - while(vendor->vendor_enum != SPIMemChipVendorUnknown && vendor->vendor_enum != vendor_enum) - vendor++; - return vendor->vendor_name; -} - -bool spi_mem_chip_find_all(SPIMemChip* chip_info, found_chips_t found_chips) { - const SPIMemChip* chip_info_arr; - found_chips_reset(found_chips); - for(chip_info_arr = SPIMemChips; chip_info_arr->model_name != NULL; chip_info_arr++) { - if(chip_info->vendor_id != chip_info_arr->vendor_id) continue; - if(chip_info->type_id != chip_info_arr->type_id) continue; - if(chip_info->capacity_id != chip_info_arr->capacity_id) continue; - found_chips_push_back(found_chips, chip_info_arr); - } - if(found_chips_size(found_chips)) return true; - return false; -} - -void spi_mem_chip_copy_chip_info(SPIMemChip* dest, const SPIMemChip* src) { - memcpy(dest, src, sizeof(SPIMemChip)); -} - -size_t spi_mem_chip_get_size(SPIMemChip* chip) { - return (chip->size); -} - -const char* spi_mem_chip_get_vendor_name(const SPIMemChip* chip) { - return (spi_mem_chip_search_vendor_name(chip->vendor_enum)); -} - -const char* spi_mem_chip_get_vendor_name_by_enum(uint32_t vendor_enum) { - return (spi_mem_chip_search_vendor_name(vendor_enum)); -} - -const char* spi_mem_chip_get_model_name(const SPIMemChip* chip) { - return (chip->model_name); -} - -uint8_t spi_mem_chip_get_vendor_id(SPIMemChip* chip) { - return (chip->vendor_id); -} - -uint8_t spi_mem_chip_get_type_id(SPIMemChip* chip) { - return (chip->type_id); -} - -uint8_t spi_mem_chip_get_capacity_id(SPIMemChip* chip) { - return (chip->capacity_id); -} - -SPIMemChipWriteMode spi_mem_chip_get_write_mode(SPIMemChip* chip) { - return (chip->write_mode); -} - -size_t spi_mem_chip_get_page_size(SPIMemChip* chip) { - return (chip->page_size); -} - -uint32_t spi_mem_chip_get_vendor_enum(const SPIMemChip* chip) { - return ((uint32_t)chip->vendor_enum); -} diff --git a/applications/external/spi_mem_manager/lib/spi/spi_mem_chip.h b/applications/external/spi_mem_manager/lib/spi/spi_mem_chip.h deleted file mode 100644 index 683937df4..000000000 --- a/applications/external/spi_mem_manager/lib/spi/spi_mem_chip.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include -#include - -typedef struct SPIMemChip SPIMemChip; - -ARRAY_DEF(found_chips, const SPIMemChip*, M_POD_OPLIST) - -typedef enum { - SPIMemChipStatusBusy, - SPIMemChipStatusIdle, - SPIMemChipStatusError -} SPIMemChipStatus; - -typedef enum { - SPIMemChipWriteModeUnknown = 0, - SPIMemChipWriteModePage = (0x01 << 0), - SPIMemChipWriteModeAAIByte = (0x01 << 1), - SPIMemChipWriteModeAAIWord = (0x01 << 2), -} SPIMemChipWriteMode; - -const char* spi_mem_chip_get_vendor_name(const SPIMemChip* chip); -const char* spi_mem_chip_get_model_name(const SPIMemChip* chip); -size_t spi_mem_chip_get_size(SPIMemChip* chip); -uint8_t spi_mem_chip_get_vendor_id(SPIMemChip* chip); -uint8_t spi_mem_chip_get_type_id(SPIMemChip* chip); -uint8_t spi_mem_chip_get_capacity_id(SPIMemChip* chip); -SPIMemChipWriteMode spi_mem_chip_get_write_mode(SPIMemChip* chip); -size_t spi_mem_chip_get_page_size(SPIMemChip* chip); -bool spi_mem_chip_find_all(SPIMemChip* chip_info, found_chips_t found_chips); -void spi_mem_chip_copy_chip_info(SPIMemChip* dest, const SPIMemChip* src); -uint32_t spi_mem_chip_get_vendor_enum(const SPIMemChip* chip); -const char* spi_mem_chip_get_vendor_name_by_enum(uint32_t vendor_enum); diff --git a/applications/external/spi_mem_manager/lib/spi/spi_mem_chip_arr.c b/applications/external/spi_mem_manager/lib/spi/spi_mem_chip_arr.c deleted file mode 100644 index 25b237d68..000000000 --- a/applications/external/spi_mem_manager/lib/spi/spi_mem_chip_arr.c +++ /dev/null @@ -1,1399 +0,0 @@ -#include "spi_mem_chip_i.h" -const SPIMemChip SPIMemChips[] = { - {0x1F, 0x40, 0x00, "AT25DN256", 32768, 256, SPIMemChipVendorADESTO, SPIMemChipWriteModePage}, - {0x37, 0x20, 0x20, "A25L05PT", 65536, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x20, 0x10, "A25L05PU", 65536, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x20, 0x21, "A25L10PT", 131072, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x20, 0x11, "A25L10PU", 131072, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x20, 0x22, "A25L20PT", 262144, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x20, 0x12, "A25L20PU", 262144, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x20, 0x23, "A25L40PT", 524288, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x20, 0x13, "A25L40PU", 524288, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x20, 0x24, "A25L80PT", 1048576, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x20, 0x14, "A25L80PU", 1048576, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x20, 0x25, "A25L16PT", 2097152, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x20, 0x15, "A25L16PU", 2097152, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x10, "A25L512", 65536, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x11, "A25L010", 131072, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x12, "A25L020", 262144, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x13, "A25L040", 524288, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x14, "A25L080", 1048576, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x15, "A25L016", 2097152, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x16, "A25L032", 4194304, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x40, 0x15, "A25LQ16", 2097152, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x37, 0x40, 0x16, "A25LQ32A", 4194304, 256, SPIMemChipVendorAMIC, SPIMemChipWriteModePage}, - {0x68, 0x40, 0x14, "BY25D80", 1048576, 256, SPIMemChipVendorBoya, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x10, "EN25B05", 65536, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x10, "EN25B05T", 65536, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x11, "EN25B10", 131072, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x11, "EN25B10T", 131072, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x12, "EN25B20", 262144, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x12, "EN25B20T", 262144, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x13, "EN25B40", 524288, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x13, "EN25B40T", 524288, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x14, "EN25B80", 1048576, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x14, "EN25B80T", 1048576, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x15, "EN25B16", 2097152, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x15, "EN25B16T", 2097152, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x16, "EN25B32", 4194304, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x16, "EN25B32T", 4194304, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x17, "EN25B64", 8388608, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x17, "EN25B64T", 8388608, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x31, 0x10, "EN25F05", 65536, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x31, 0x11, "EN25F10", 131072, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x31, 0x12, "EN25F20", 262144, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x31, 0x13, "EN25F40", 524288, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x31, 0x14, "EN25F80", 1048576, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x31, 0x15, "EN25F16", 2097152, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x31, 0x16, "EN25F32", 4194304, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x31, 0x10, "EN25LF05", 65536, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x31, 0x11, "EN25LF10", 131072, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x31, 0x12, "EN25LF20", 262144, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x31, 0x13, "EN25LF40", 524288, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x10, "EN25P05", 65536, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x11, "EN25P10", 131072, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x12, "EN25P20", 262144, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x13, "EN25P40", 524288, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x14, "EN25P80", 1048576, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x15, "EN25P16", 2097152, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x16, "EN25P32", 4194304, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x17, "EN25P64", 8388608, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x30, 0x13, "EN25Q40", 524288, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x30, 0x14, "EN25Q80A", 1048576, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x30, 0x15, "EN25Q16A", 2097152, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x30, 0x16, "EN25Q32A", 4194304, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x70, 0x16, "EN25Q32A", 4194304, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x30, 0x16, "EN25Q32B", 4194304, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x30, 0x17, "EN25Q64", 8388608, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x30, 0x18, "EN25Q128", 16777216, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x70, 0x15, "EN25QH16", 2097152, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x70, 0x16, "EN25QH32", 4194304, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x70, 0x17, "EN25QH64", 8388608, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x70, 0x18, "EN25QH128", 16777216, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x70, 0x19, "EN25QH256", 33554432, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x51, 0x14, "EN25T80", 1048576, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x51, 0x15, "EN25T16", 2097152, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x1C, 0x31, 0x17, "EN25F64", 8388608, 256, SPIMemChipVendorEON, SPIMemChipWriteModePage}, - {0x7F, 0x9D, 0x7C, "Pm25LV010", 131072, 256, SPIMemChipVendorPFLASH, SPIMemChipWriteModePage}, - {0x7F, 0x9D, 0x21, "Pm25LD010", 131072, 256, SPIMemChipVendorPFLASH, SPIMemChipWriteModePage}, - {0x7F, 0x9D, 0x22, "Pm25LV020", 262144, 256, SPIMemChipVendorPFLASH, SPIMemChipWriteModePage}, - {0x7F, 0x9D, 0x7D, "Pm25W020", 262144, 256, SPIMemChipVendorPFLASH, SPIMemChipWriteModePage}, - {0x7F, 0x9D, 0x7E, "Pm25LV040", 524288, 256, SPIMemChipVendorPFLASH, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x10, "TS25L512A", 65536, 256, SPIMemChipVendorTERRA, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x11, "TS25L010A", 131072, 256, SPIMemChipVendorTERRA, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x12, "TS25L020A", 262144, 256, SPIMemChipVendorTERRA, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x15, "TS25L16AP", 2097152, 256, SPIMemChipVendorTERRA, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x15, "TS25L16BP", 2097152, 256, SPIMemChipVendorTERRA, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x15, "ZP25L16P", 2097152, 256, SPIMemChipVendorTERRA, SPIMemChipWriteModePage}, - {0x20, 0x80, 0x15, "TS25L16PE", 2097152, 256, SPIMemChipVendorTERRA, SPIMemChipWriteModePage}, - {0x20, 0x80, 0x14, "TS25L80PE", 1048576, 256, SPIMemChipVendorTERRA, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x16, "TS25L032A", 4194304, 256, SPIMemChipVendorTERRA, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x13, "TS25L40P", 524288, 256, SPIMemChipVendorTERRA, SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x10, - "GPR25L005E", - 65536, - 256, - SPIMemChipVendorGeneralplus, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x15, - "GPR25L161B", - 262144, - 256, - SPIMemChipVendorGeneralplus, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x12, - "GPR25L020B", - 262144, - 256, - SPIMemChipVendorGeneralplus, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x16, - "GPR25L3203F", - 4194304, - 256, - SPIMemChipVendorGeneralplus, - SPIMemChipWriteModePage}, - {0x9D, 0x7B, 0x00, "AC25LV512", 65536, 256, SPIMemChipVendorDEUTRON, SPIMemChipWriteModePage}, - {0x9D, 0x7C, 0x00, "AC25LV010", 131072, 256, SPIMemChipVendorDEUTRON, SPIMemChipWriteModePage}, - {0x9D, 0x7B, 0x00, "EM25LV512", 65536, 256, SPIMemChipVendorEFST, SPIMemChipWriteModePage}, - {0x9D, 0x7C, 0x00, "EM25LV010", 131072, 256, SPIMemChipVendorEFST, SPIMemChipWriteModePage}, - {0x8C, 0x20, 0x13, "F25L004A", 524288, 256, SPIMemChipVendorEFST, SPIMemChipWriteModePage}, - {0x8C, 0x20, 0x14, "F25L008A", 1048576, 256, SPIMemChipVendorEFST, SPIMemChipWriteModePage}, - {0x8C, 0x20, 0x15, "F25L016A", 2097152, 256, SPIMemChipVendorEFST, SPIMemChipWriteModePage}, - {0x8C, 0x8C, 0x8C, "F25L04UA", 524288, 256, SPIMemChipVendorEFST, SPIMemChipWriteModePage}, - {0x8C, 0x20, 0x13, "F25L04P", 524288, 256, SPIMemChipVendorEFST, SPIMemChipWriteModePage}, - {0x8C, 0x30, 0x13, "F25S04P", 524288, 256, SPIMemChipVendorEFST, SPIMemChipWriteModePage}, - {0x8C, 0x20, 0x14, "F25L08P", 1048576, 256, SPIMemChipVendorEFST, SPIMemChipWriteModePage}, - {0x8C, 0x20, 0x15, "F25L16P", 2097152, 256, SPIMemChipVendorEFST, SPIMemChipWriteModePage}, - {0x8C, 0x20, 0x16, "F25L32P", 4194304, 256, SPIMemChipVendorEFST, SPIMemChipWriteModePage}, - {0x8C, 0x40, 0x16, "F25L32Q", 4194304, 256, SPIMemChipVendorEFST, SPIMemChipWriteModePage}, - {0x4A, 0x20, 0x11, "ES25P10", 131072, 256, SPIMemChipVendorEXCELSEMI, SPIMemChipWriteModePage}, - {0x4A, 0x20, 0x12, "ES25P20", 262144, 256, SPIMemChipVendorEXCELSEMI, SPIMemChipWriteModePage}, - {0x4A, 0x20, 0x13, "ES25P40", 524288, 256, SPIMemChipVendorEXCELSEMI, SPIMemChipWriteModePage}, - {0x4A, 0x20, 0x14, "ES25P80", 1048576, 256, SPIMemChipVendorEXCELSEMI, SPIMemChipWriteModePage}, - {0x4A, 0x20, 0x15, "ES25P16", 2097152, 256, SPIMemChipVendorEXCELSEMI, SPIMemChipWriteModePage}, - {0x4A, 0x20, 0x16, "ES25P32", 4194304, 256, SPIMemChipVendorEXCELSEMI, SPIMemChipWriteModePage}, - {0x4A, 0x32, 0x13, "ES25M40A", 524288, 256, SPIMemChipVendorEXCELSEMI, SPIMemChipWriteModePage}, - {0x4A, 0x32, 0x14, "ES25M80A", 1048576, 256, SPIMemChipVendorEXCELSEMI, SPIMemChipWriteModePage}, - {0x4A, 0x32, 0x15, "ES25M16A", 2097152, 256, SPIMemChipVendorEXCELSEMI, SPIMemChipWriteModePage}, - {0xF8, 0x32, 0x14, "FM25Q08A", 1048576, 256, SPIMemChipVendorFIDELIX, SPIMemChipWriteModePage}, - {0xF8, 0x32, 0x15, "FM25Q16A", 2097152, 256, SPIMemChipVendorFIDELIX, SPIMemChipWriteModePage}, - {0xF8, 0x32, 0x15, "FM25Q16B", 2097152, 256, SPIMemChipVendorFIDELIX, SPIMemChipWriteModePage}, - {0xF8, 0x32, 0x16, "FM25Q32A", 4194304, 256, SPIMemChipVendorFIDELIX, SPIMemChipWriteModePage}, - {0xF8, 0x32, 0x17, "FM25Q64A", 8388608, 256, SPIMemChipVendorFIDELIX, SPIMemChipWriteModePage}, - {0xC8, 0x30, 0x13, "GD25D40", 524288, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0xC8, 0x30, 0x14, "GD25D80", 1048576, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0xC8, 0x20, 0x13, "GD25F40", 524288, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0xC8, 0x20, 0x14, "GD25F80", 1048576, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0xC8, 0x40, 0x10, "GD25Q512", 65536, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0xC8, 0x40, 0x11, "GD25Q10", 131072, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0xC8, 0x40, 0x12, "GD25Q20", 262144, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0xC8, - 0x60, - 0x12, - "GD25LQ20C_1.8V", - 262144, - 256, - SPIMemChipVendorGIGADEVICE, - SPIMemChipWriteModePage}, - {0xC8, 0x40, 0x13, "GD25Q40", 524288, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0xC8, 0x40, 0x14, "GD25Q80", 1048576, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0xC8, - 0x40, - 0x14, - "GD25Q80B", - 1048576, - 256, - SPIMemChipVendorGIGADEVICE, - SPIMemChipWriteModePage}, - {0xC8, - 0x40, - 0x14, - "GD25Q80C", - 1048576, - 256, - SPIMemChipVendorGIGADEVICE, - SPIMemChipWriteModePage}, - {0xC8, 0x40, 0x15, "GD25Q16", 2097152, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0xC8, - 0x40, - 0x15, - "GD25Q16B", - 2097152, - 256, - SPIMemChipVendorGIGADEVICE, - SPIMemChipWriteModePage}, - {0xC8, 0x40, 0x16, "GD25Q32", 4194304, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0xC8, - 0x40, - 0x16, - "GD25Q32B", - 4194304, - 256, - SPIMemChipVendorGIGADEVICE, - SPIMemChipWriteModePage}, - {0xC8, 0x40, 0x17, "GD25Q64", 8388608, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0xC8, - 0x40, - 0x17, - "GD25Q64B", - 8388608, - 256, - SPIMemChipVendorGIGADEVICE, - SPIMemChipWriteModePage}, - {0xC8, - 0x40, - 0x17, - "GD25B64C", - 8388608, - 256, - SPIMemChipVendorGIGADEVICE, - SPIMemChipWriteModePage}, - {0xC8, - 0x40, - 0x18, - "GD25Q128B", - 16777216, - 256, - SPIMemChipVendorGIGADEVICE, - SPIMemChipWriteModePage}, - {0xC8, - 0x40, - 0x18, - "GD25Q128C", - 16777216, - 256, - SPIMemChipVendorGIGADEVICE, - SPIMemChipWriteModePage}, - {0xC8, - 0x60, - 0x17, - "GD25LQ064C_1.8V", - 8388608, - 256, - SPIMemChipVendorGIGADEVICE, - SPIMemChipWriteModePage}, - {0xC8, - 0x60, - 0x18, - "GD25LQ128C_1.8V", - 16777216, - 256, - SPIMemChipVendorGIGADEVICE, - SPIMemChipWriteModePage}, - {0xC8, - 0x60, - 0x19, - "GD25LQ256C_1.8V", - 33554432, - 256, - SPIMemChipVendorGIGADEVICE, - SPIMemChipWriteModePage}, - {0xC8, 0x31, 0x14, "MD25T80", 1048576, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0x51, 0x40, 0x12, "MD25D20", 262144, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0x51, 0x40, 0x13, "MD25D40", 524288, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0x51, 0x40, 0x14, "MD25D80", 1048576, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0x51, 0x40, 0x15, "MD25D16", 2097152, 256, SPIMemChipVendorGIGADEVICE, SPIMemChipWriteModePage}, - {0x1C, 0x20, 0x10, "ICE25P05", 65536, 128, SPIMemChipVendorICE, SPIMemChipWriteModePage}, - {0x89, 0x89, 0x11, "QB25F016S33B", 2097152, 256, SPIMemChipVendorINTEL, SPIMemChipWriteModePage}, - {0x89, 0x89, 0x11, "QB25F160S33B", 2097152, 256, SPIMemChipVendorINTEL, SPIMemChipWriteModePage}, - {0x89, 0x89, 0x12, "QB25F320S33B", 4194304, 256, SPIMemChipVendorINTEL, SPIMemChipWriteModePage}, - {0x89, 0x89, 0x13, "QB25F640S33B", 8388608, 256, SPIMemChipVendorINTEL, SPIMemChipWriteModePage}, - {0x89, 0x89, 0x11, "QH25F016S33B", 2097152, 256, SPIMemChipVendorINTEL, SPIMemChipWriteModePage}, - {0x89, 0x89, 0x11, "QH25F160S33B", 2097152, 256, SPIMemChipVendorINTEL, SPIMemChipWriteModePage}, - {0x89, 0x89, 0x12, "QH25F320S33B", 4194304, 256, SPIMemChipVendorINTEL, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x11, "KH25L1005", 131072, 256, SPIMemChipVendorKHIC, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x11, "KH25L1005A", 131072, 256, SPIMemChipVendorKHIC, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x12, "KH25L2005", 262144, 256, SPIMemChipVendorKHIC, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x13, "KH25L4005", 524288, 256, SPIMemChipVendorKHIC, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x13, "KH25L4005A", 524288, 256, SPIMemChipVendorKHIC, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x10, "KH25L512", 65536, 256, SPIMemChipVendorKHIC, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x10, "KH25L512A", 65536, 256, SPIMemChipVendorKHIC, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x14, "KH25L8005", 1048576, 256, SPIMemChipVendorKHIC, SPIMemChipWriteModePage}, - {0xC2, 0x26, 0x15, "KH25L8036D", 1048576, 256, SPIMemChipVendorKHIC, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x11, "MX25L1005", 131072, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x11, "MX25L1005A", 131072, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x11, "MX25L1005C", 131072, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x11, "MX25L1006E", 131072, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x22, 0x11, "MX25L1021E", 131072, 32, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x11, "MX25L1025C", 131072, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x11, "MX25L1026E", 131072, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x18, - "MX25L12805D", - 16777216, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x18, - "MX25L12835E", - 16777216, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x18, - "MX25L12835F", - 16777216, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x18, - "MX25L12836E", - 16777216, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x18, - "MX25L12839F", - 16777216, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x18, - "MX25L12845E", - 16777216, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x18, - "MX25L12845G", - 16777216, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x18, - "MX25L12845F", - 16777216, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x18, - "MX25L12865E", - 16777216, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x18, - "MX25L12865F", - 16777216, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x18, - "MX25L12873F", - 16777216, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x18, - "MX25L12875F", - 16777216, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x19, - "MX25L25635E", - 33554432, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x15, "MX25L1605", 2097152, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x15, - "MX25L1605A", - 2097152, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x15, - "MX25L1605D", - 2097152, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x15, - "MX25L1606E", - 2097152, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x24, - 0x15, - "MX25L1633E", - 2097152, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x24, - 0x15, - "MX25L1635D", - 2097152, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x15, - "MX25L1635E", - 2097152, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x24, - 0x15, - "MX25L1636D", - 2097152, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x15, - "MX25L1636E", - 2097152, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x24, - 0x15, - "MX25L1673E", - 2097152, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x24, - 0x15, - "MX25L1675E", - 2097152, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x12, "MX25L2005", 262144, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x12, "MX25L2005C", 262144, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x12, "MX25L2006E", 262144, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x12, "MX25L2026C", 262144, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x12, "MX25L2026E", 262144, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x16, "MX25L3205", 4194304, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x16, - "MX25L3205A", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x16, - "MX25L3205D", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x16, - "MX25L3206E", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x16, - "MX25L3208E", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x5E, - 0x16, - "MX25L3225D", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x16, - "MX25L3233F", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x5E, - 0x16, - "MX25L3235D", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x16, - "MX25L3235E", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x5E, - 0x16, - "MX25L3236D", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x5E, - 0x16, - "MX25L3237D", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x36, - "MX25L3239E", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x16, - "MX25L3273E", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x16, - "MX25L3273F", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x16, - "MX25L3275E", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x13, "MX25L4005", 524288, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x13, "MX25L4005A", 524288, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x13, "MX25L4005C", 524288, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x13, "MX25L4006E", 524288, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x13, "MX25L4026E", 524288, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x10, "MX25L512", 65536, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x10, "MX25L512A", 65536, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x10, "MX25L512C", 65536, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x22, 0x10, "MX25L5121E", 65536, 32, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x17, "MX25L6405", 8388608, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x17, - "MX25L6405D", - 8388608, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x17, - "MX25L6406E", - 8388608, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x17, - "MX25L6408E", - 8388608, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x17, - "MX25L6433F", - 8388608, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x17, - "MX25L6435E", - 8388608, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x17, - "MX25L6436E", - 8388608, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x17, - "MX25L6436F", - 8388608, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x37, - "MX25L6439E", - 8388608, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x17, - "MX25L6445E", - 8388608, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x17, - "MX25L6465E", - 8388608, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x17, - "MX25L6473E", - 8388608, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x17, - "MX25L6473F", - 8388608, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x17, - "MX25L6475E", - 8388608, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x14, "MX25L8005", 1048576, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x14, - "MX25L8006E", - 1048576, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x14, - "MX25L8008E", - 1048576, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x14, - "MX25L8035E", - 1048576, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x14, - "MX25L8036E", - 1048576, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x14, - "MX25L8073E", - 1048576, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x14, - "MX25L8075E", - 1048576, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x19, - "MX25L25673G", - 33554432, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, 0x28, 0x10, "MX25R512F", 65536, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x28, 0x11, "MX25R1035F", 131072, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, - 0x28, - 0x15, - "MX25R1635F", - 2097152, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, 0x28, 0x12, "MX25R2035F", 262144, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, - 0x28, - 0x16, - "MX25R3235F", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, 0x28, 0x13, "MX25R4035F", 524288, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, - 0x28, - 0x17, - "MX25R6435F", - 8388608, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x28, - 0x14, - "MX25R8035F", - 1048576, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x31, - "MX25U1001E_1.8V", - 131072, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x18, - "MX25U12835F_1.8V", - 16777216, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x39, - "MX25U25673G_1.8V", - 33554432, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x39, - "MX25U25645G_1.8V", - 33554432, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x35, - "MX25U1635E_1.8V", - 2097152, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x35, - "MX25U1635F_1.8V", - 2097152, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x32, - "MX25U2032E_1.8V", - 262144, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x32, - "MX25U2033E_1.8V", - 262144, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x36, - "MX25U3235E_1.8V", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x36, - "MX25U3235F_1.8V", - 4194304, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x33, - "MX25U4032E_1.8V", - 524288, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x33, - "MX25U4033E_1.8V", - 524288, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x33, - "MX25U4035_1.8V", - 524288, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x30, - "MX25U5121E_1.8V", - 65536, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x37, - "MX25U6435F_1.8V", - 8388608, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x37, - "MX25U6473F_1.8V", - 8388608, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x34, - "MX25U8032E_1.8V", - 1048576, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x34, - "MX25U8033E_1.8V", - 1048576, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x34, - "MX25U8035_1.8V", - 1048576, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x34, - "MX25U8035E_1.8V", - 1048576, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x38, - "MX25U12873F_1.8V", - 16777216, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x11, "MX25V1006E", 131072, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x23, 0x11, "MX25V1035F", 131072, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x12, "MX25V2006E", 262144, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x23, 0x12, "MX25V2035F", 262144, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x10, "MX25V512", 65536, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x10, "MX25V512C", 65536, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x10, "MX25V512E", 65536, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x23, 0x10, "MX25V512F", 65536, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x13, "MX25V4005", 524288, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x13, "MX25V4006E", 524288, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x25, 0x53, "MX25V4035", 524288, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x23, 0x13, "MX25V4035F", 524288, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, 0x20, 0x14, "MX25V8005", 1048576, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, - 0x20, - 0x14, - "MX25V8006E", - 1048576, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, 0x25, 0x54, "MX25V8035", 1048576, 256, SPIMemChipVendorMACRONIX, SPIMemChipWriteModePage}, - {0xC2, - 0x23, - 0x14, - "MX25V8035F", - 1048576, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x3A, - "MX66U51235F_1.8V", - 67108864, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0xC2, - 0x25, - 0x3B, - "MX66U1G45G_1.8V", - 134217728, - 256, - SPIMemChipVendorMACRONIX, - SPIMemChipWriteModePage}, - {0x20, 0xBA, 0x16, "N25Q032A", 4194304, 256, SPIMemChipVendorMICRON, SPIMemChipWriteModePage}, - {0x20, 0xBA, 0x17, "N25Q064A", 8388608, 256, SPIMemChipVendorMICRON, SPIMemChipWriteModePage}, - {0x20, 0xBA, 0x19, "N25Q256A13", 33554432, 256, SPIMemChipVendorMICRON, SPIMemChipWriteModePage}, - {0x20, 0xBA, 0x20, "N25Q512A83", 67108864, 256, SPIMemChipVendorMICRON, SPIMemChipWriteModePage}, - {0x2C, 0xCB, 0x19, "N25W256A11", 33554432, 256, SPIMemChipVendorMICRON, SPIMemChipWriteModePage}, - {0x20, - 0xBA, - 0x18, - "MT25QL128AB", - 16777216, - 256, - SPIMemChipVendorMICRON, - SPIMemChipWriteModePage}, - {0x20, 0xBA, 0x19, "MT25QL256A", 33554432, 256, SPIMemChipVendorMICRON, SPIMemChipWriteModePage}, - {0x20, 0xBA, 0x20, "MT25QL512A", 67108864, 256, SPIMemChipVendorMICRON, SPIMemChipWriteModePage}, - {0x20, - 0xBA, - 0x22, - "MT25QL02GC", - 268435456, - 256, - SPIMemChipVendorMICRON, - SPIMemChipWriteModePage}, - {0x20, 0xBB, 0x19, "MT25QU256", 33554432, 256, SPIMemChipVendorMICRON, SPIMemChipWriteModePage}, - {0x20, - 0xBA, - 0x21, - "N25Q00AA13G", - 134217728, - 256, - SPIMemChipVendorMICRON, - SPIMemChipWriteModePage}, - {0x37, 0x30, 0x10, "MS25X512", 65536, 256, SPIMemChipVendorMSHINE, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x11, "MS25X10", 131072, 256, SPIMemChipVendorMSHINE, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x12, "MS25X20", 262144, 256, SPIMemChipVendorMSHINE, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x13, "MS25X40", 524288, 256, SPIMemChipVendorMSHINE, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x14, "MS25X80", 1048576, 256, SPIMemChipVendorMSHINE, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x15, "MS25X16", 2097152, 256, SPIMemChipVendorMSHINE, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x16, "MS25X32", 4194304, 256, SPIMemChipVendorMSHINE, SPIMemChipWriteModePage}, - {0xD5, 0x30, 0x11, "N25S10", 131072, 256, SPIMemChipVendorNANTRONICS, SPIMemChipWriteModePage}, - {0xD5, 0x30, 0x12, "N25S20", 262144, 256, SPIMemChipVendorNANTRONICS, SPIMemChipWriteModePage}, - {0xD5, 0x30, 0x13, "N25S40", 524288, 256, SPIMemChipVendorNANTRONICS, SPIMemChipWriteModePage}, - {0xD5, 0x30, 0x15, "N25S16", 2097152, 256, SPIMemChipVendorNANTRONICS, SPIMemChipWriteModePage}, - {0xD5, 0x30, 0x16, "N25S32", 4194304, 256, SPIMemChipVendorNANTRONICS, SPIMemChipWriteModePage}, - {0xD5, 0x30, 0x14, "N25S80", 1048576, 256, SPIMemChipVendorNANTRONICS, SPIMemChipWriteModePage}, - {0x9D, 0x7F, 0x7C, "NX25P10", 131072, 256, SPIMemChipVendorNEXFLASH, SPIMemChipWriteModePage}, - {0xEF, 0x20, 0x15, "NX25P16", 2097152, 256, SPIMemChipVendorNEXFLASH, SPIMemChipWriteModePage}, - {0x9D, 0x7F, 0x7D, "NX25P20", 262144, 256, SPIMemChipVendorNEXFLASH, SPIMemChipWriteModePage}, - {0xEF, 0x20, 0x16, "NX25P32", 4194304, 256, SPIMemChipVendorNEXFLASH, SPIMemChipWriteModePage}, - {0x9D, 0x7F, 0x7E, "NX25P40", 524288, 256, SPIMemChipVendorNEXFLASH, SPIMemChipWriteModePage}, - {0x9D, 0x7F, 0x13, "NX25P80", 1048576, 256, SPIMemChipVendorNEXFLASH, SPIMemChipWriteModePage}, - {0x20, 0x40, 0x15, "M45PE16", 2097152, 256, SPIMemChipVendorNUMONYX, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x10, "M25P05", 65536, 128, SPIMemChipVendorNUMONYX, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x10, "M25P05A", 65536, 256, SPIMemChipVendorNUMONYX, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x11, "M25P10", 131072, 128, SPIMemChipVendorNUMONYX, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x11, "M25P10A", 131072, 256, SPIMemChipVendorNUMONYX, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x12, "M25P20", 262144, 256, SPIMemChipVendorNUMONYX, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x13, "M25P40", 524288, 256, SPIMemChipVendorNUMONYX, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x14, "M25P80", 1048576, 256, SPIMemChipVendorNUMONYX, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x15, "M25P16", 2097152, 256, SPIMemChipVendorNUMONYX, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x16, "M25P32", 4194304, 256, SPIMemChipVendorNUMONYX, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x17, "M25P64", 8388608, 256, SPIMemChipVendorNUMONYX, SPIMemChipWriteModePage}, - {0x20, - 0x20, - 0x18, - "M25P128_ST25P28V6G", - 16777216, - 256, - SPIMemChipVendorNUMONYX, - SPIMemChipWriteModePage}, - {0x20, 0x80, 0x11, "M25PE10", 131072, 256, SPIMemChipVendorNUMONYX, SPIMemChipWriteModePage}, - {0x20, 0x80, 0x15, "M25PE16", 2097152, 256, SPIMemChipVendorNUMONYX, SPIMemChipWriteModePage}, - {0x20, 0x80, 0x12, "M25PE20", 262144, 256, SPIMemChipVendorNUMONYX, SPIMemChipWriteModePage}, - {0x20, 0x80, 0x13, "M25PE40", 524288, 256, SPIMemChipVendorNUMONYX, SPIMemChipWriteModePage}, - {0x20, 0x80, 0x14, "M25PE80", 1048576, 256, SPIMemChipVendorNUMONYX, SPIMemChipWriteModePage}, - {0xBF, 0x43, 0x00, "PCT25LF020A", 262144, 256, SPIMemChipVendorPCT, SPIMemChipWriteModePage}, - {0xBF, 0x49, 0x00, "PCT25VF010A", 131072, 256, SPIMemChipVendorPCT, SPIMemChipWriteModePage}, - {0xBF, 0x25, 0x41, "PCT25VF016B", 2097152, 256, SPIMemChipVendorPCT, SPIMemChipWriteModePage}, - {0xBF, 0x43, 0x00, "PCT25VF020A", 262144, 256, SPIMemChipVendorPCT, SPIMemChipWriteModePage}, - {0xBF, 0x25, 0x4A, "PCT25VF032B", 4194304, 256, SPIMemChipVendorPCT, SPIMemChipWriteModePage}, - {0xBF, 0x44, 0x00, "PCT25VF040A", 524288, 256, SPIMemChipVendorPCT, SPIMemChipWriteModePage}, - {0xBF, 0x25, 0x8D, "PCT25VF040B", 524288, 256, SPIMemChipVendorPCT, SPIMemChipWriteModePage}, - {0xBF, 0x25, 0x8E, "PCT25VF080B", 1048576, 256, SPIMemChipVendorPCT, SPIMemChipWriteModePage}, - {0x01, 0x02, 0x10, "S25FL001D", 131072, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0x01, 0x02, 0x11, "S25FL002D", 262144, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0x01, 0x02, 0x12, "S25FL004A", 524288, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0x01, 0x02, 0x12, "S25FL004D", 524288, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x13, "S25FL004K", 524288, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0x01, 0x02, 0x13, "S25FL008A", 1048576, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0x01, 0x02, 0x13, "S25FL008D", 1048576, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x14, "S25FL008K", 1048576, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0x01, 0x02, 0x14, "S25FL016A", 2097152, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x15, "S25FL016K", 2097152, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0x01, 0x02, 0x15, "S25FL032A", 4194304, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x16, "S25FL032K", 4194304, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0x01, 0x02, 0x15, "S25FL032P", 4194304, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0x01, 0x02, 0x12, "S25FL040A", 524288, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0x01, - 0x02, - 0x26, - "S25FL040A_BOT", - 524288, - 256, - SPIMemChipVendorSPANSION, - SPIMemChipWriteModePage}, - {0x01, - 0x02, - 0x25, - "S25FL040A_TOP", - 524288, - 256, - SPIMemChipVendorSPANSION, - SPIMemChipWriteModePage}, - {0x01, 0x02, 0x16, "S25FL064A", 8388608, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x17, "S25FL064K", 8388608, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0x01, 0x02, 0x16, "S25FL064P", 8388608, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0x01, 0x40, 0x15, "S25FL116K", 2097152, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0xEF, - 0x40, - 0x18, - "S25FL128K", - 16777216, - 256, - SPIMemChipVendorSPANSION, - SPIMemChipWriteModePage}, - {0x01, - 0x20, - 0x18, - "S25FL128P", - 16777216, - 256, - SPIMemChipVendorSPANSION, - SPIMemChipWriteModePage}, - {0x01, - 0x20, - 0x18, - "S25FL128S", - 16777216, - 256, - SPIMemChipVendorSPANSION, - SPIMemChipWriteModePage}, - {0x01, 0x40, 0x16, "S25FL132K", 4194304, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0x01, 0x40, 0x17, "S25FL164K", 8388608, 256, SPIMemChipVendorSPANSION, SPIMemChipWriteModePage}, - {0x01, - 0x02, - 0x19, - "S25FL256S", - 33554432, - 256, - SPIMemChipVendorSPANSION, - SPIMemChipWriteModePage}, - {0xBF, 0x25, 0x41, "SST25VF016B", 2097152, 1, SPIMemChipVendorSST, SPIMemChipWriteModeAAIWord}, - {0xBF, 0x25, 0x8C, "SST25VF020B", 262144, 1, SPIMemChipVendorSST, SPIMemChipWriteModeAAIWord}, - {0xBF, 0x25, 0x4A, "SST25VF032B", 4194304, 1, SPIMemChipVendorSST, SPIMemChipWriteModeAAIWord}, - {0xBF, 0x25, 0x4B, "SST25VF064C", 8388608, 256, SPIMemChipVendorSST, SPIMemChipWriteModePage}, - {0xBF, 0x25, 0x8D, "SST25VF040B", 524288, 1, SPIMemChipVendorSST, SPIMemChipWriteModeAAIWord}, - {0xBF, 0x25, 0x8E, "SST25VF080B", 1048576, 1, SPIMemChipVendorSST, SPIMemChipWriteModeAAIWord}, - {0x20, 0x71, 0x15, "M25PX16", 2097152, 256, SPIMemChipVendorST, SPIMemChipWriteModePage}, - {0x20, 0x71, 0x16, "M25PX32", 4194304, 256, SPIMemChipVendorST, SPIMemChipWriteModePage}, - {0x20, 0x71, 0x17, "M25PX64", 8388608, 256, SPIMemChipVendorST, SPIMemChipWriteModePage}, - {0x20, 0x71, 0x14, "M25PX80", 1048576, 256, SPIMemChipVendorST, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x10, "ST25P05", 65536, 128, SPIMemChipVendorST, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x10, "ST25P05A", 65536, 256, SPIMemChipVendorST, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x11, "ST25P10", 131072, 128, SPIMemChipVendorST, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x11, "ST25P10A", 131072, 256, SPIMemChipVendorST, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x15, "ST25P16", 2097152, 256, SPIMemChipVendorST, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x12, "ST25P20", 262144, 256, SPIMemChipVendorST, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x16, "ST25P32", 4194304, 256, SPIMemChipVendorST, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x13, "ST25P40", 524288, 256, SPIMemChipVendorST, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x17, "ST25P64", 8388608, 256, SPIMemChipVendorST, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x14, "ST25P80", 1048576, 256, SPIMemChipVendorST, SPIMemChipWriteModePage}, - {0xEF, 0x10, 0x00, "W25P10", 131072, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x20, 0x15, "W25P16", 2097152, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x11, 0x00, "W25P20", 262144, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x20, 0x16, "W25P32", 4194304, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x12, 0x00, "W25P40", 524288, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x20, 0x17, "W25P64", 8388608, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x20, 0x14, "W25P80", 1048576, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, - 0x60, - 0x11, - "W25Q10EW_1.8V", - 131072, - 256, - SPIMemChipVendorWINBOND, - SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x18, "W25Q128BV", 16777216, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x18, "W25Q128FV", 16777216, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x70, 0x18, "W25Q128JV", 16777216, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x19, "W25Q256FV", 33554432, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x19, "W25Q256JV", 33554432, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x70, 0x19, "W25Q256JV", 33554432, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, - 0x60, - 0x18, - "W25Q128FW_1.8V", - 16777216, - 256, - SPIMemChipVendorWINBOND, - SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x15, "W25Q16", 2097152, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x15, "W25Q16BV", 2097152, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x15, "W25Q16CL", 2097152, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x15, "W25Q16CV", 2097152, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x15, "W25Q16DV", 2097152, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, - 0x60, - 0x15, - "W25Q16FW_1.8V", - 2097152, - 256, - SPIMemChipVendorWINBOND, - SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x15, "W25Q16V", 2097152, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x12, "W25Q20CL", 262144, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, - 0x60, - 0x12, - "W25Q20EW_1.8V", - 262144, - 256, - SPIMemChipVendorWINBOND, - SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x16, "W25Q32", 4194304, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x16, "W25Q32BV", 4194304, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x16, "W25Q32FV", 4194304, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, - 0x60, - 0x16, - "W25Q32FW_1.8V", - 4194304, - 256, - SPIMemChipVendorWINBOND, - SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x16, "W25Q32V", 4194304, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x13, "W25Q40BL", 524288, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x13, "W25Q40BV", 524288, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x13, "W25Q40CL", 524288, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, - 0x60, - 0x13, - "W25Q40EW_1.8V", - 524288, - 256, - SPIMemChipVendorWINBOND, - SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x17, "W25Q64BV", 8388608, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x17, "W25Q64CV", 8388608, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x17, "W25Q64FV", 8388608, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x17, "W25Q64JV", 8388608, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, - 0x60, - 0x17, - "W25Q64FW_1.8V", - 8388608, - 256, - SPIMemChipVendorWINBOND, - SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x14, "W25Q80BL", 1048576, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x14, "W25Q80BV", 1048576, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, - 0x50, - 0x14, - "W25Q80BW_1.8V", - 1048576, - 256, - SPIMemChipVendorWINBOND, - SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x14, "W25Q80DV", 1048576, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, - 0x60, - 0x14, - "W25Q80EW_1.8V", - 1048576, - 256, - SPIMemChipVendorWINBOND, - SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x10, "W25X05", 65536, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x10, "W25X05CL", 65536, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x11, "W25X10AV", 131072, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x11, "W25X10BL", 131072, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x11, "W25X10BV", 131072, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x11, "W25X10CL", 131072, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x11, "W25X10L", 131072, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x11, "W25X10V", 131072, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x15, "W25X16", 2097152, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x15, "W25X16AL", 2097152, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x15, "W25X16AV", 2097152, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x15, "W25X16BV", 2097152, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x15, "W25X16V", 2097152, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x12, "W25X20AL", 262144, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x12, "W25X20AV", 262144, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x12, "W25X20BL", 262144, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x12, "W25X20BV", 262144, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x12, "W25X20CL", 262144, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x12, "W25X20L", 262144, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x12, "W25X20V", 262144, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x16, "W25X32", 4194304, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x16, "W25X32AV", 4194304, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x16, "W25X32BV", 4194304, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x16, "W25X32V", 4194304, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x13, "W25X40AL", 524288, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x13, "W25X40AV", 524288, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x13, "W25X40BL", 524288, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x13, "W25X40BV", 524288, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x13, "W25X40CL", 524288, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x13, "W25X40L", 524288, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x13, "W25X40V", 524288, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x17, "W25X64", 8388608, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x17, "W25X64BV", 8388608, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x17, "W25X64V", 8388608, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x14, "W25X80AL", 1048576, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x14, "W25X80AV", 1048576, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x14, "W25X80BV", 1048576, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x14, "W25X80L", 1048576, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x30, 0x14, "W25X80V", 1048576, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x71, 0x19, "W25M512JV", 67108864, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0xEF, 0x40, 0x19, "W25R256JV", 33554432, 256, SPIMemChipVendorWINBOND, SPIMemChipWriteModePage}, - {0x37, 0x20, 0x10, "TS25L512A", 65536, 256, SPIMemChipVendorZEMPRO, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x11, "TS25L010A", 131072, 256, SPIMemChipVendorZEMPRO, SPIMemChipWriteModePage}, - {0x37, 0x30, 0x12, "TS25L020A", 262144, 256, SPIMemChipVendorZEMPRO, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x15, "TS25L16AP", 2097152, 256, SPIMemChipVendorZEMPRO, SPIMemChipWriteModePage}, - {0x20, 0x20, 0x15, "TS25L16BP", 2097152, 256, SPIMemChipVendorZEMPRO, SPIMemChipWriteModePage}, - {0x37, 0x20, 0x15, "TS25L16P", 2097152, 256, SPIMemChipVendorZEMPRO, SPIMemChipWriteModePage}, - {0x5E, 0x40, 0x15, "ZB25D16", 2097152, 256, SPIMemChipVendorZbit, SPIMemChipWriteModePage}, - {0xE0, 0x40, 0x13, "BG25Q40A", 524288, 256, SPIMemChipVendorBerg_Micro, SPIMemChipWriteModePage}, - {0xE0, - 0x40, - 0x14, - "BG25Q80A", - 1048576, - 256, - SPIMemChipVendorBerg_Micro, - SPIMemChipWriteModePage}, - {0xE0, - 0x40, - 0x15, - "BG25Q16A", - 2097152, - 256, - SPIMemChipVendorBerg_Micro, - SPIMemChipWriteModePage}, - {0xE0, - 0x40, - 0x16, - "BG25Q32A", - 4194304, - 256, - SPIMemChipVendorBerg_Micro, - SPIMemChipWriteModePage}, - {0x1F, 0x23, 0x00, "AT45DB021D", 270336, 264, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x24, 0x00, "AT45DB041D", 540672, 264, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x26, 0x00, "AT45DB161D", 2162688, 528, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x27, 0x01, "AT45DB321D", 4325376, 528, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x43, 0x00, "AT25DF021", 262144, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x44, 0x00, "AT25DF041", 524288, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x44, 0x00, "AT25DF041A", 524288, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x84, 0x00, "AT25SF041", 524288, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x45, 0x00, "AT25DF081", 1048576, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x45, 0x00, "AT25DF081A", 1048576, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x46, 0x00, "AT25DF161", 2097152, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x47, 0x00, "AT25DF321", 4194304, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x47, 0x00, "AT25DF321A", 4194304, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x48, 0x00, "AT25DF641", 8388608, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x65, 0x00, "AT25F512B", 65536, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x45, 0x00, "AT26DF081", 1048576, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x45, 0x00, "AT26DF081A", 1048576, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x46, 0x00, "AT26DF161", 2097152, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x46, 0x00, "AT26DF161A", 2097152, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x47, 0x00, "AT26DF321", 4194304, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x47, 0x00, "AT26DF321A", 4194304, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0x1F, 0x04, 0x00, "AT26F004", 524288, 256, SPIMemChipVendorATMEL, SPIMemChipWriteModePage}, - {0xE0, - 0x60, - 0x18, - "ACE25A128G_1.8V", - 16777216, - 256, - SPIMemChipVendorACE, - SPIMemChipWriteModePage}, - {0x9B, 0x32, 0x16, "ATO25Q32", 4194304, 256, SPIMemChipVendorATO, SPIMemChipWriteModePage}, - {0x54, 0x40, 0x17, "DQ25Q64A", 8388608, 256, SPIMemChipVendorDOUQI, SPIMemChipWriteModePage}, - {0x0E, 0x40, 0x15, "FT25H16", 2097152, 256, SPIMemChipVendorFremont, SPIMemChipWriteModePage}, - {0xA1, 0x40, 0x13, "FM25Q04A", 524288, 256, SPIMemChipVendorFudan, SPIMemChipWriteModePage}, - {0xA1, 0x40, 0x16, "FM25Q32", 4194304, 256, SPIMemChipVendorFudan, SPIMemChipWriteModePage}, - {0xE0, 0x40, 0x14, "GT25Q80A", 1048576, 256, SPIMemChipVendorGenitop, SPIMemChipWriteModePage}, - {0xE0, 0x40, 0x13, "PN25F04A", 524288, 256, SPIMemChipVendorParagon, SPIMemChipWriteModePage}}; diff --git a/applications/external/spi_mem_manager/lib/spi/spi_mem_chip_i.h b/applications/external/spi_mem_manager/lib/spi/spi_mem_chip_i.h deleted file mode 100644 index 30d607094..000000000 --- a/applications/external/spi_mem_manager/lib/spi/spi_mem_chip_i.h +++ /dev/null @@ -1,85 +0,0 @@ -#pragma once - -#include -#include "spi_mem_chip.h" - -typedef enum { - SPIMemChipVendorUnknown, - SPIMemChipVendorADESTO, - SPIMemChipVendorAMIC, - SPIMemChipVendorBoya, - SPIMemChipVendorEON, - SPIMemChipVendorPFLASH, - SPIMemChipVendorTERRA, - SPIMemChipVendorGeneralplus, - SPIMemChipVendorDEUTRON, - SPIMemChipVendorEFST, - SPIMemChipVendorEXCELSEMI, - SPIMemChipVendorFIDELIX, - SPIMemChipVendorGIGADEVICE, - SPIMemChipVendorICE, - SPIMemChipVendorINTEL, - SPIMemChipVendorKHIC, - SPIMemChipVendorMACRONIX, - SPIMemChipVendorMICRON, - SPIMemChipVendorMSHINE, - SPIMemChipVendorNANTRONICS, - SPIMemChipVendorNEXFLASH, - SPIMemChipVendorNUMONYX, - SPIMemChipVendorPCT, - SPIMemChipVendorSPANSION, - SPIMemChipVendorSST, - SPIMemChipVendorST, - SPIMemChipVendorWINBOND, - SPIMemChipVendorZEMPRO, - SPIMemChipVendorZbit, - SPIMemChipVendorBerg_Micro, - SPIMemChipVendorATMEL, - SPIMemChipVendorACE, - SPIMemChipVendorATO, - SPIMemChipVendorDOUQI, - SPIMemChipVendorFremont, - SPIMemChipVendorFudan, - SPIMemChipVendorGenitop, - SPIMemChipVendorParagon -} SPIMemChipVendor; - -typedef enum { - SPIMemChipCMDReadJEDECChipID = 0x9F, - SPIMemChipCMDReadData = 0x03, - SPIMemChipCMDChipErase = 0xC7, - SPIMemChipCMDWriteEnable = 0x06, - SPIMemChipCMDWriteDisable = 0x04, - SPIMemChipCMDReadStatus = 0x05, - SPIMemChipCMDWriteData = 0x02, - SPIMemChipCMDReleasePowerDown = 0xAB -} SPIMemChipCMD; - -enum SPIMemChipStatusBit { - SPIMemChipStatusBitBusy = (0x01 << 0), - SPIMemChipStatusBitWriteEnabled = (0x01 << 1), - SPIMemChipStatusBitBitProtection1 = (0x01 << 2), - SPIMemChipStatusBitBitProtection2 = (0x01 << 3), - SPIMemChipStatusBitBitProtection3 = (0x01 << 4), - SPIMemChipStatusBitTopBottomProtection = (0x01 << 5), - SPIMemChipStatusBitSectorProtect = (0x01 << 6), - SPIMemChipStatusBitRegisterProtect = (0x01 << 7) -}; - -typedef struct { - const char* vendor_name; - SPIMemChipVendor vendor_enum; -} SPIMemChipVendorName; - -struct SPIMemChip { - uint8_t vendor_id; - uint8_t type_id; - uint8_t capacity_id; - const char* model_name; - size_t size; - size_t page_size; - SPIMemChipVendor vendor_enum; - SPIMemChipWriteMode write_mode; -}; - -extern const SPIMemChip SPIMemChips[]; diff --git a/applications/external/spi_mem_manager/lib/spi/spi_mem_tools.c b/applications/external/spi_mem_manager/lib/spi/spi_mem_tools.c deleted file mode 100644 index 3518ca25c..000000000 --- a/applications/external/spi_mem_manager/lib/spi/spi_mem_tools.c +++ /dev/null @@ -1,152 +0,0 @@ -#include -#include -#include "spi_mem_chip_i.h" -#include "spi_mem_tools.h" - -static uint8_t spi_mem_tools_addr_to_byte_arr(uint32_t addr, uint8_t* cmd) { - uint8_t len = 3; // TODO(add support of 4 bytes address mode) - for(uint8_t i = 0; i < len; i++) { - cmd[i] = (addr >> ((len - (i + 1)) * 8)) & 0xFF; - } - return len; -} - -static bool spi_mem_tools_trx( - SPIMemChipCMD cmd, - uint8_t* tx_buf, - size_t tx_size, - uint8_t* rx_buf, - size_t rx_size) { - bool success = false; - furi_hal_spi_acquire(&furi_hal_spi_bus_handle_external); - do { - if(!furi_hal_spi_bus_tx( - &furi_hal_spi_bus_handle_external, (uint8_t*)&cmd, 1, SPI_MEM_SPI_TIMEOUT)) - break; - if(tx_buf) { - if(!furi_hal_spi_bus_tx( - &furi_hal_spi_bus_handle_external, tx_buf, tx_size, SPI_MEM_SPI_TIMEOUT)) - break; - } - if(rx_buf) { - if(!furi_hal_spi_bus_rx( - &furi_hal_spi_bus_handle_external, rx_buf, rx_size, SPI_MEM_SPI_TIMEOUT)) - break; - } - success = true; - } while(0); - furi_hal_spi_release(&furi_hal_spi_bus_handle_external); - return success; -} - -static bool spi_mem_tools_write_buffer(uint8_t* data, size_t size, size_t offset) { - furi_hal_spi_acquire(&furi_hal_spi_bus_handle_external); - uint8_t cmd = (uint8_t)SPIMemChipCMDWriteData; - uint8_t address[4]; - uint8_t address_size = spi_mem_tools_addr_to_byte_arr(offset, address); - bool success = false; - do { - if(!furi_hal_spi_bus_tx(&furi_hal_spi_bus_handle_external, &cmd, 1, SPI_MEM_SPI_TIMEOUT)) - break; - if(!furi_hal_spi_bus_tx( - &furi_hal_spi_bus_handle_external, address, address_size, SPI_MEM_SPI_TIMEOUT)) - break; - if(!furi_hal_spi_bus_tx(&furi_hal_spi_bus_handle_external, data, size, SPI_MEM_SPI_TIMEOUT)) - break; - success = true; - } while(0); - furi_hal_spi_release(&furi_hal_spi_bus_handle_external); - return success; -} - -bool spi_mem_tools_read_chip_info(SPIMemChip* chip) { - uint8_t rx_buf[3] = {0, 0, 0}; - do { - if(!spi_mem_tools_trx(SPIMemChipCMDReadJEDECChipID, NULL, 0, rx_buf, 3)) break; - if(rx_buf[0] == 0 || rx_buf[0] == 255) break; - chip->vendor_id = rx_buf[0]; - chip->type_id = rx_buf[1]; - chip->capacity_id = rx_buf[2]; - return true; - } while(0); - return false; -} - -bool spi_mem_tools_check_chip_info(SPIMemChip* chip) { - SPIMemChip new_chip_info; - spi_mem_tools_read_chip_info(&new_chip_info); - do { - if(chip->vendor_id != new_chip_info.vendor_id) break; - if(chip->type_id != new_chip_info.type_id) break; - if(chip->capacity_id != new_chip_info.capacity_id) break; - return true; - } while(0); - return false; -} - -bool spi_mem_tools_read_block(SPIMemChip* chip, size_t offset, uint8_t* data, size_t block_size) { - if(!spi_mem_tools_check_chip_info(chip)) return false; - for(size_t i = 0; i < block_size; i += SPI_MEM_MAX_BLOCK_SIZE) { - uint8_t cmd[4]; - if((offset + SPI_MEM_MAX_BLOCK_SIZE) > chip->size) return false; - if(!spi_mem_tools_trx( - SPIMemChipCMDReadData, - cmd, - spi_mem_tools_addr_to_byte_arr(offset, cmd), - data, - SPI_MEM_MAX_BLOCK_SIZE)) - return false; - offset += SPI_MEM_MAX_BLOCK_SIZE; - data += SPI_MEM_MAX_BLOCK_SIZE; - } - return true; -} - -size_t spi_mem_tools_get_file_max_block_size(SPIMemChip* chip) { - UNUSED(chip); - return (SPI_MEM_FILE_BUFFER_SIZE); -} - -SPIMemChipStatus spi_mem_tools_get_chip_status(SPIMemChip* chip) { - UNUSED(chip); - uint8_t status; - if(!spi_mem_tools_trx(SPIMemChipCMDReadStatus, NULL, 0, &status, 1)) - return SPIMemChipStatusError; - if(status & SPIMemChipStatusBitBusy) return SPIMemChipStatusBusy; - return SPIMemChipStatusIdle; -} - -static bool spi_mem_tools_set_write_enabled(SPIMemChip* chip, bool enable) { - UNUSED(chip); - uint8_t status; - SPIMemChipCMD cmd = SPIMemChipCMDWriteDisable; - if(enable) cmd = SPIMemChipCMDWriteEnable; - do { - if(!spi_mem_tools_trx(cmd, NULL, 0, NULL, 0)) break; - if(!spi_mem_tools_trx(SPIMemChipCMDReadStatus, NULL, 0, &status, 1)) break; - if(!(status & SPIMemChipStatusBitWriteEnabled) && enable) break; - if((status & SPIMemChipStatusBitWriteEnabled) && !enable) break; - return true; - } while(0); - return false; -} - -bool spi_mem_tools_erase_chip(SPIMemChip* chip) { - do { - if(!spi_mem_tools_set_write_enabled(chip, true)) break; - if(!spi_mem_tools_trx(SPIMemChipCMDChipErase, NULL, 0, NULL, 0)) break; - return true; - } while(0); - return true; -} - -bool spi_mem_tools_write_bytes(SPIMemChip* chip, size_t offset, uint8_t* data, size_t block_size) { - do { - if(!spi_mem_tools_check_chip_info(chip)) break; - if(!spi_mem_tools_set_write_enabled(chip, true)) break; - if((offset + block_size) > chip->size) break; - if(!spi_mem_tools_write_buffer(data, block_size, offset)) break; - return true; - } while(0); - return false; -} diff --git a/applications/external/spi_mem_manager/lib/spi/spi_mem_tools.h b/applications/external/spi_mem_manager/lib/spi/spi_mem_tools.h deleted file mode 100644 index ad006b8ff..000000000 --- a/applications/external/spi_mem_manager/lib/spi/spi_mem_tools.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "spi_mem_chip.h" - -#define SPI_MEM_SPI_TIMEOUT 1000 -#define SPI_MEM_MAX_BLOCK_SIZE 256 -#define SPI_MEM_FILE_BUFFER_SIZE 4096 - -bool spi_mem_tools_read_chip_info(SPIMemChip* chip); -bool spi_mem_tools_read_block(SPIMemChip* chip, size_t offset, uint8_t* data, size_t block_size); -size_t spi_mem_tools_get_file_max_block_size(SPIMemChip* chip); -SPIMemChipStatus spi_mem_tools_get_chip_status(SPIMemChip* chip); -bool spi_mem_tools_erase_chip(SPIMemChip* chip); -bool spi_mem_tools_write_bytes(SPIMemChip* chip, size_t offset, uint8_t* data, size_t block_size); diff --git a/applications/external/spi_mem_manager/lib/spi/spi_mem_worker.c b/applications/external/spi_mem_manager/lib/spi/spi_mem_worker.c deleted file mode 100644 index 438f338f1..000000000 --- a/applications/external/spi_mem_manager/lib/spi/spi_mem_worker.c +++ /dev/null @@ -1,129 +0,0 @@ -#include "spi_mem_worker_i.h" - -typedef enum { - SPIMemEventStopThread = (1 << 0), - SPIMemEventChipDetect = (1 << 1), - SPIMemEventRead = (1 << 2), - SPIMemEventVerify = (1 << 3), - SPIMemEventErase = (1 << 4), - SPIMemEventWrite = (1 << 5), - SPIMemEventAll = - (SPIMemEventStopThread | SPIMemEventChipDetect | SPIMemEventRead | SPIMemEventVerify | - SPIMemEventErase | SPIMemEventWrite) -} SPIMemEventEventType; - -static int32_t spi_mem_worker_thread(void* thread_context); - -SPIMemWorker* spi_mem_worker_alloc() { - SPIMemWorker* worker = malloc(sizeof(SPIMemWorker)); - worker->callback = NULL; - worker->thread = furi_thread_alloc(); - worker->mode_index = SPIMemWorkerModeIdle; - furi_thread_set_name(worker->thread, "SPIMemWorker"); - furi_thread_set_callback(worker->thread, spi_mem_worker_thread); - furi_thread_set_context(worker->thread, worker); - furi_thread_set_stack_size(worker->thread, 10240); - return worker; -} - -void spi_mem_worker_free(SPIMemWorker* worker) { - furi_thread_free(worker->thread); - free(worker); -} - -bool spi_mem_worker_check_for_stop(SPIMemWorker* worker) { - UNUSED(worker); - uint32_t flags = furi_thread_flags_get(); - return (flags & SPIMemEventStopThread); -} - -static int32_t spi_mem_worker_thread(void* thread_context) { - SPIMemWorker* worker = thread_context; - while(true) { - uint32_t flags = furi_thread_flags_wait(SPIMemEventAll, FuriFlagWaitAny, FuriWaitForever); - if(flags != (unsigned)FuriFlagErrorTimeout) { - if(flags & SPIMemEventStopThread) break; - if(flags & SPIMemEventChipDetect) worker->mode_index = SPIMemWorkerModeChipDetect; - if(flags & SPIMemEventRead) worker->mode_index = SPIMemWorkerModeRead; - if(flags & SPIMemEventVerify) worker->mode_index = SPIMemWorkerModeVerify; - if(flags & SPIMemEventErase) worker->mode_index = SPIMemWorkerModeErase; - if(flags & SPIMemEventWrite) worker->mode_index = SPIMemWorkerModeWrite; - if(spi_mem_worker_modes[worker->mode_index].process) { - spi_mem_worker_modes[worker->mode_index].process(worker); - } - worker->mode_index = SPIMemWorkerModeIdle; - } - } - return 0; -} - -void spi_mem_worker_start_thread(SPIMemWorker* worker) { - furi_thread_start(worker->thread); -} - -void spi_mem_worker_stop_thread(SPIMemWorker* worker) { - furi_thread_flags_set(furi_thread_get_id(worker->thread), SPIMemEventStopThread); - furi_thread_join(worker->thread); -} - -void spi_mem_worker_chip_detect_start( - SPIMemChip* chip_info, - found_chips_t* found_chips, - SPIMemWorker* worker, - SPIMemWorkerCallback callback, - void* context) { - furi_check(worker->mode_index == SPIMemWorkerModeIdle); - worker->callback = callback; - worker->cb_ctx = context; - worker->chip_info = chip_info; - worker->found_chips = found_chips; - furi_thread_flags_set(furi_thread_get_id(worker->thread), SPIMemEventChipDetect); -} - -void spi_mem_worker_read_start( - SPIMemChip* chip_info, - SPIMemWorker* worker, - SPIMemWorkerCallback callback, - void* context) { - furi_check(worker->mode_index == SPIMemWorkerModeIdle); - worker->callback = callback; - worker->cb_ctx = context; - worker->chip_info = chip_info; - furi_thread_flags_set(furi_thread_get_id(worker->thread), SPIMemEventRead); -} - -void spi_mem_worker_verify_start( - SPIMemChip* chip_info, - SPIMemWorker* worker, - SPIMemWorkerCallback callback, - void* context) { - furi_check(worker->mode_index == SPIMemWorkerModeIdle); - worker->callback = callback; - worker->cb_ctx = context; - worker->chip_info = chip_info; - furi_thread_flags_set(furi_thread_get_id(worker->thread), SPIMemEventVerify); -} - -void spi_mem_worker_erase_start( - SPIMemChip* chip_info, - SPIMemWorker* worker, - SPIMemWorkerCallback callback, - void* context) { - furi_check(worker->mode_index == SPIMemWorkerModeIdle); - worker->callback = callback; - worker->cb_ctx = context; - worker->chip_info = chip_info; - furi_thread_flags_set(furi_thread_get_id(worker->thread), SPIMemEventErase); -} - -void spi_mem_worker_write_start( - SPIMemChip* chip_info, - SPIMemWorker* worker, - SPIMemWorkerCallback callback, - void* context) { - furi_check(worker->mode_index == SPIMemWorkerModeIdle); - worker->callback = callback; - worker->cb_ctx = context; - worker->chip_info = chip_info; - furi_thread_flags_set(furi_thread_get_id(worker->thread), SPIMemEventWrite); -} diff --git a/applications/external/spi_mem_manager/lib/spi/spi_mem_worker.h b/applications/external/spi_mem_manager/lib/spi/spi_mem_worker.h deleted file mode 100644 index c3761cd5a..000000000 --- a/applications/external/spi_mem_manager/lib/spi/spi_mem_worker.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include -#include "spi_mem_chip.h" - -typedef struct SPIMemWorker SPIMemWorker; - -typedef struct { - void (*const process)(SPIMemWorker* worker); -} SPIMemWorkerModeType; - -typedef enum { - SPIMemCustomEventWorkerChipIdentified, - SPIMemCustomEventWorkerChipUnknown, - SPIMemCustomEventWorkerBlockReaded, - SPIMemCustomEventWorkerChipFail, - SPIMemCustomEventWorkerFileFail, - SPIMemCustomEventWorkerDone, - SPIMemCustomEventWorkerVerifyFail, -} SPIMemCustomEventWorker; - -typedef void (*SPIMemWorkerCallback)(void* context, SPIMemCustomEventWorker event); - -SPIMemWorker* spi_mem_worker_alloc(); -void spi_mem_worker_free(SPIMemWorker* worker); -void spi_mem_worker_start_thread(SPIMemWorker* worker); -void spi_mem_worker_stop_thread(SPIMemWorker* worker); -bool spi_mem_worker_check_for_stop(SPIMemWorker* worker); -void spi_mem_worker_chip_detect_start( - SPIMemChip* chip_info, - found_chips_t* found_chips, - SPIMemWorker* worker, - SPIMemWorkerCallback callback, - void* context); -void spi_mem_worker_read_start( - SPIMemChip* chip_info, - SPIMemWorker* worker, - SPIMemWorkerCallback callback, - void* context); -void spi_mem_worker_verify_start( - SPIMemChip* chip_info, - SPIMemWorker* worker, - SPIMemWorkerCallback callback, - void* context); -void spi_mem_worker_erase_start( - SPIMemChip* chip_info, - SPIMemWorker* worker, - SPIMemWorkerCallback callback, - void* context); -void spi_mem_worker_write_start( - SPIMemChip* chip_info, - SPIMemWorker* worker, - SPIMemWorkerCallback callback, - void* context); diff --git a/applications/external/spi_mem_manager/lib/spi/spi_mem_worker_i.h b/applications/external/spi_mem_manager/lib/spi/spi_mem_worker_i.h deleted file mode 100644 index 43e2d2287..000000000 --- a/applications/external/spi_mem_manager/lib/spi/spi_mem_worker_i.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "spi_mem_worker.h" - -typedef enum { - SPIMemWorkerModeIdle, - SPIMemWorkerModeChipDetect, - SPIMemWorkerModeRead, - SPIMemWorkerModeVerify, - SPIMemWorkerModeErase, - SPIMemWorkerModeWrite -} SPIMemWorkerMode; - -struct SPIMemWorker { - SPIMemChip* chip_info; - found_chips_t* found_chips; - SPIMemWorkerMode mode_index; - SPIMemWorkerCallback callback; - void* cb_ctx; - FuriThread* thread; - FuriString* file_name; -}; - -extern const SPIMemWorkerModeType spi_mem_worker_modes[]; diff --git a/applications/external/spi_mem_manager/lib/spi/spi_mem_worker_modes.c b/applications/external/spi_mem_manager/lib/spi/spi_mem_worker_modes.c deleted file mode 100644 index a393e5490..000000000 --- a/applications/external/spi_mem_manager/lib/spi/spi_mem_worker_modes.c +++ /dev/null @@ -1,214 +0,0 @@ -#include "spi_mem_worker_i.h" -#include "spi_mem_chip.h" -#include "spi_mem_tools.h" -#include "../../spi_mem_files.h" - -static void spi_mem_worker_chip_detect_process(SPIMemWorker* worker); -static void spi_mem_worker_read_process(SPIMemWorker* worker); -static void spi_mem_worker_verify_process(SPIMemWorker* worker); -static void spi_mem_worker_erase_process(SPIMemWorker* worker); -static void spi_mem_worker_write_process(SPIMemWorker* worker); - -const SPIMemWorkerModeType spi_mem_worker_modes[] = { - [SPIMemWorkerModeIdle] = {.process = NULL}, - [SPIMemWorkerModeChipDetect] = {.process = spi_mem_worker_chip_detect_process}, - [SPIMemWorkerModeRead] = {.process = spi_mem_worker_read_process}, - [SPIMemWorkerModeVerify] = {.process = spi_mem_worker_verify_process}, - [SPIMemWorkerModeErase] = {.process = spi_mem_worker_erase_process}, - [SPIMemWorkerModeWrite] = {.process = spi_mem_worker_write_process}}; - -static void spi_mem_worker_run_callback(SPIMemWorker* worker, SPIMemCustomEventWorker event) { - if(worker->callback) { - worker->callback(worker->cb_ctx, event); - } -} - -static bool spi_mem_worker_await_chip_busy(SPIMemWorker* worker) { - while(true) { - furi_delay_tick(10); // to give some time to OS - if(spi_mem_worker_check_for_stop(worker)) return true; - SPIMemChipStatus chip_status = spi_mem_tools_get_chip_status(worker->chip_info); - if(chip_status == SPIMemChipStatusError) return false; - if(chip_status == SPIMemChipStatusBusy) continue; - return true; - } -} - -static size_t spi_mem_worker_modes_get_total_size(SPIMemWorker* worker) { - size_t chip_size = spi_mem_chip_get_size(worker->chip_info); - size_t file_size = spi_mem_file_get_size(worker->cb_ctx); - size_t total_size = chip_size; - if(chip_size > file_size) total_size = file_size; - return total_size; -} - -// ChipDetect -static void spi_mem_worker_chip_detect_process(SPIMemWorker* worker) { - SPIMemCustomEventWorker event; - while(!spi_mem_tools_read_chip_info(worker->chip_info)) { - furi_delay_tick(10); // to give some time to OS - if(spi_mem_worker_check_for_stop(worker)) return; - } - if(spi_mem_chip_find_all(worker->chip_info, *worker->found_chips)) { - event = SPIMemCustomEventWorkerChipIdentified; - } else { - event = SPIMemCustomEventWorkerChipUnknown; - } - spi_mem_worker_run_callback(worker, event); -} - -// Read -static bool spi_mem_worker_read(SPIMemWorker* worker, SPIMemCustomEventWorker* event) { - uint8_t data_buffer[SPI_MEM_FILE_BUFFER_SIZE]; - size_t chip_size = spi_mem_chip_get_size(worker->chip_info); - size_t offset = 0; - bool success = true; - while(true) { - furi_delay_tick(10); // to give some time to OS - size_t block_size = SPI_MEM_FILE_BUFFER_SIZE; - if(spi_mem_worker_check_for_stop(worker)) break; - if(offset >= chip_size) break; - if((offset + block_size) > chip_size) block_size = chip_size - offset; - if(!spi_mem_tools_read_block(worker->chip_info, offset, data_buffer, block_size)) { - *event = SPIMemCustomEventWorkerChipFail; - success = false; - break; - } - if(!spi_mem_file_write_block(worker->cb_ctx, data_buffer, block_size)) { - success = false; - break; - } - offset += block_size; - spi_mem_worker_run_callback(worker, SPIMemCustomEventWorkerBlockReaded); - } - if(success) *event = SPIMemCustomEventWorkerDone; - return success; -} - -static void spi_mem_worker_read_process(SPIMemWorker* worker) { - SPIMemCustomEventWorker event = SPIMemCustomEventWorkerFileFail; - do { - if(!spi_mem_worker_await_chip_busy(worker)) break; - if(!spi_mem_file_create_open(worker->cb_ctx)) break; - if(!spi_mem_worker_read(worker, &event)) break; - } while(0); - spi_mem_file_close(worker->cb_ctx); - spi_mem_worker_run_callback(worker, event); -} - -// Verify -static bool - spi_mem_worker_verify(SPIMemWorker* worker, size_t total_size, SPIMemCustomEventWorker* event) { - uint8_t data_buffer_chip[SPI_MEM_FILE_BUFFER_SIZE]; - uint8_t data_buffer_file[SPI_MEM_FILE_BUFFER_SIZE]; - size_t offset = 0; - bool success = true; - while(true) { - furi_delay_tick(10); // to give some time to OS - size_t block_size = SPI_MEM_FILE_BUFFER_SIZE; - if(spi_mem_worker_check_for_stop(worker)) break; - if(offset >= total_size) break; - if((offset + block_size) > total_size) block_size = total_size - offset; - if(!spi_mem_tools_read_block(worker->chip_info, offset, data_buffer_chip, block_size)) { - *event = SPIMemCustomEventWorkerChipFail; - success = false; - break; - } - if(!spi_mem_file_read_block(worker->cb_ctx, data_buffer_file, block_size)) { - success = false; - break; - } - if(memcmp(data_buffer_chip, data_buffer_file, block_size) != 0) { - *event = SPIMemCustomEventWorkerVerifyFail; - success = false; - break; - } - offset += block_size; - spi_mem_worker_run_callback(worker, SPIMemCustomEventWorkerBlockReaded); - } - if(success) *event = SPIMemCustomEventWorkerDone; - return success; -} - -static void spi_mem_worker_verify_process(SPIMemWorker* worker) { - SPIMemCustomEventWorker event = SPIMemCustomEventWorkerFileFail; - size_t total_size = spi_mem_worker_modes_get_total_size(worker); - do { - if(!spi_mem_worker_await_chip_busy(worker)) break; - if(!spi_mem_file_open(worker->cb_ctx)) break; - if(!spi_mem_worker_verify(worker, total_size, &event)) break; - } while(0); - spi_mem_file_close(worker->cb_ctx); - spi_mem_worker_run_callback(worker, event); -} - -// Erase -static void spi_mem_worker_erase_process(SPIMemWorker* worker) { - SPIMemCustomEventWorker event = SPIMemCustomEventWorkerChipFail; - do { - if(!spi_mem_worker_await_chip_busy(worker)) break; - if(!spi_mem_tools_erase_chip(worker->chip_info)) break; - if(!spi_mem_worker_await_chip_busy(worker)) break; - event = SPIMemCustomEventWorkerDone; - } while(0); - spi_mem_worker_run_callback(worker, event); -} - -// Write -static bool spi_mem_worker_write_block_by_page( - SPIMemWorker* worker, - size_t offset, - uint8_t* data, - size_t block_size, - size_t page_size) { - for(size_t i = 0; i < block_size; i += page_size) { - if(!spi_mem_worker_await_chip_busy(worker)) return false; - if(!spi_mem_tools_write_bytes(worker->chip_info, offset, data, page_size)) return false; - offset += page_size; - data += page_size; - } - return true; -} - -static bool - spi_mem_worker_write(SPIMemWorker* worker, size_t total_size, SPIMemCustomEventWorker* event) { - bool success = true; - uint8_t data_buffer[SPI_MEM_FILE_BUFFER_SIZE]; - size_t page_size = spi_mem_chip_get_page_size(worker->chip_info); - size_t offset = 0; - while(true) { - furi_delay_tick(10); // to give some time to OS - size_t block_size = SPI_MEM_FILE_BUFFER_SIZE; - if(spi_mem_worker_check_for_stop(worker)) break; - if(offset >= total_size) break; - if((offset + block_size) > total_size) block_size = total_size - offset; - if(!spi_mem_file_read_block(worker->cb_ctx, data_buffer, block_size)) { - *event = SPIMemCustomEventWorkerFileFail; - success = false; - break; - } - if(!spi_mem_worker_write_block_by_page( - worker, offset, data_buffer, block_size, page_size)) { - success = false; - break; - } - offset += block_size; - spi_mem_worker_run_callback(worker, SPIMemCustomEventWorkerBlockReaded); - } - return success; -} - -static void spi_mem_worker_write_process(SPIMemWorker* worker) { - SPIMemCustomEventWorker event = SPIMemCustomEventWorkerChipFail; - size_t total_size = - spi_mem_worker_modes_get_total_size(worker); // need to be executed before opening file - do { - if(!spi_mem_file_open(worker->cb_ctx)) break; - if(!spi_mem_worker_await_chip_busy(worker)) break; - if(!spi_mem_worker_write(worker, total_size, &event)) break; - if(!spi_mem_worker_await_chip_busy(worker)) break; - event = SPIMemCustomEventWorkerDone; - } while(0); - spi_mem_file_close(worker->cb_ctx); - spi_mem_worker_run_callback(worker, event); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene.c deleted file mode 100644 index 7780005f4..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "spi_mem_scene.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const spi_mem_on_enter_handlers[])(void*) = { -#include "spi_mem_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 spi_mem_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "spi_mem_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 spi_mem_on_exit_handlers[])(void* context) = { -#include "spi_mem_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers spi_mem_scene_handlers = { - .on_enter_handlers = spi_mem_on_enter_handlers, - .on_event_handlers = spi_mem_on_event_handlers, - .on_exit_handlers = spi_mem_on_exit_handlers, - .scene_num = SPIMemSceneNum, -}; diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene.h b/applications/external/spi_mem_manager/scenes/spi_mem_scene.h deleted file mode 100644 index 2ac6d21e3..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) SPIMemScene##id, -typedef enum { -#include "spi_mem_scene_config.h" - SPIMemSceneNum, -} SPIMemScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers spi_mem_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "spi_mem_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 "spi_mem_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 "spi_mem_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_about.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_about.c deleted file mode 100644 index dc0cc4fe4..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_about.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "../spi_mem_app_i.h" -#include "../lib/spi/spi_mem_chip.h" - -#define SPI_MEM_VERSION_APP "0.1.0" -#define SPI_MEM_DEVELOPER "DrunkBatya" -#define SPI_MEM_GITHUB "https://github.com/flipperdevices/flipperzero-firmware" -#define SPI_MEM_NAME "\e#\e! SPI Mem Manager \e!\n" -#define SPI_MEM_BLANK_INV "\e#\e! \e!\n" - -void spi_mem_scene_about_on_enter(void* context) { - SPIMemApp* app = context; - FuriString* tmp_string = furi_string_alloc(); - - widget_add_text_box_element( - app->widget, 0, 0, 128, 14, AlignCenter, AlignBottom, SPI_MEM_BLANK_INV, false); - widget_add_text_box_element( - app->widget, 0, 2, 128, 14, AlignCenter, AlignBottom, SPI_MEM_NAME, false); - furi_string_printf(tmp_string, "\e#%s\n", "Information"); - furi_string_cat_printf(tmp_string, "Version: %s\n", SPI_MEM_VERSION_APP); - furi_string_cat_printf(tmp_string, "Developed by: %s\n", SPI_MEM_DEVELOPER); - furi_string_cat_printf(tmp_string, "Github: %s\n\n", SPI_MEM_GITHUB); - furi_string_cat_printf(tmp_string, "\e#%s\n", "Description"); - furi_string_cat_printf( - tmp_string, - "SPI memory dumper\n" - "Originally written by Hedger, ghettorce and x893 at\n" - "Flipper Hackathon 2021\n\n"); - widget_add_text_scroll_element(app->widget, 0, 16, 128, 50, furi_string_get_cstr(tmp_string)); - - furi_string_free(tmp_string); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget); -} - -bool spi_mem_scene_about_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} -void spi_mem_scene_about_on_exit(void* context) { - SPIMemApp* app = context; - widget_reset(app->widget); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_chip_detect.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_chip_detect.c deleted file mode 100644 index d9b8f0aa3..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_chip_detect.c +++ /dev/null @@ -1,37 +0,0 @@ -#include "../spi_mem_app_i.h" - -static void spi_mem_scene_chip_detect_callback(void* context, SPIMemCustomEventWorker event) { - SPIMemApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -void spi_mem_scene_chip_detect_on_enter(void* context) { - SPIMemApp* app = context; - notification_message(app->notifications, &sequence_blink_start_yellow); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewDetect); - spi_mem_worker_start_thread(app->worker); - spi_mem_worker_chip_detect_start( - app->chip_info, &app->found_chips, app->worker, spi_mem_scene_chip_detect_callback, app); -} - -bool spi_mem_scene_chip_detect_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - bool success = false; - if(event.type == SceneManagerEventTypeCustom) { - success = true; - if(event.event == SPIMemCustomEventWorkerChipIdentified) { - scene_manager_set_scene_state(app->scene_manager, SPIMemSceneSelectVendor, 0); - scene_manager_next_scene(app->scene_manager, SPIMemSceneSelectVendor); - } else if(event.event == SPIMemCustomEventWorkerChipUnknown) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneChipDetectFail); - } - } - return success; -} - -void spi_mem_scene_chip_detect_on_exit(void* context) { - SPIMemApp* app = context; - spi_mem_worker_stop_thread(app->worker); - notification_message(app->notifications, &sequence_blink_stop); - popup_reset(app->popup); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_chip_detect_fail.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_chip_detect_fail.c deleted file mode 100644 index 876a28721..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_chip_detect_fail.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "../spi_mem_app_i.h" -#include "../lib/spi/spi_mem_chip.h" - -static void spi_mem_scene_chip_detect_fail_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - SPIMemApp* app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(app->view_dispatcher, result); - } -} - -void spi_mem_scene_chip_detect_fail_on_enter(void* context) { - SPIMemApp* app = context; - FuriString* str = furi_string_alloc(); - widget_add_button_element( - app->widget, - GuiButtonTypeCenter, - "Retry", - spi_mem_scene_chip_detect_fail_widget_callback, - app); - widget_add_string_element( - app->widget, 64, 9, AlignCenter, AlignBottom, FontPrimary, "Detected"); - widget_add_string_element( - app->widget, 64, 20, AlignCenter, AlignBottom, FontPrimary, "unknown SPI chip"); - furi_string_printf(str, "Vendor\nid: 0x%02X", spi_mem_chip_get_vendor_id(app->chip_info)); - widget_add_string_multiline_element( - app->widget, 16, 44, AlignCenter, AlignBottom, FontSecondary, furi_string_get_cstr(str)); - furi_string_printf(str, "Type\nid: 0x%02X", spi_mem_chip_get_type_id(app->chip_info)); - widget_add_string_multiline_element( - app->widget, 64, 44, AlignCenter, AlignBottom, FontSecondary, furi_string_get_cstr(str)); - furi_string_printf(str, "Capacity\nid: 0x%02X", spi_mem_chip_get_capacity_id(app->chip_info)); - widget_add_string_multiline_element( - app->widget, 110, 44, AlignCenter, AlignBottom, FontSecondary, furi_string_get_cstr(str)); - furi_string_free(str); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget); -} - -bool spi_mem_scene_chip_detect_fail_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - bool success = false; - if(event.type == SceneManagerEventTypeBack) { - success = true; - scene_manager_search_and_switch_to_previous_scene(app->scene_manager, SPIMemSceneStart); - } else if(event.type == SceneManagerEventTypeCustom) { - success = true; - if(event.event == GuiButtonTypeCenter) { - scene_manager_previous_scene(app->scene_manager); - } - } - return success; -} -void spi_mem_scene_chip_detect_fail_on_exit(void* context) { - SPIMemApp* app = context; - widget_reset(app->widget); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_chip_detected.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_chip_detected.c deleted file mode 100644 index 539578a45..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_chip_detected.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "../spi_mem_app_i.h" - -static void spi_mem_scene_chip_detected_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - SPIMemApp* app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(app->view_dispatcher, result); - } -} - -static void spi_mem_scene_chip_detected_print_chip_info(Widget* widget, SPIMemChip* chip_info) { - FuriString* tmp_string = furi_string_alloc(); - widget_add_string_element( - widget, - 40, - 12, - AlignLeft, - AlignTop, - FontSecondary, - spi_mem_chip_get_vendor_name(chip_info)); - widget_add_string_element( - widget, 40, 20, AlignLeft, AlignTop, FontSecondary, spi_mem_chip_get_model_name(chip_info)); - furi_string_printf(tmp_string, "Size: %zu KB", spi_mem_chip_get_size(chip_info) / 1024); - widget_add_string_element( - widget, 40, 28, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(tmp_string)); - furi_string_free(tmp_string); -} - -static void spi_mem_scene_chip_detect_draw_next_button(SPIMemApp* app) { - FuriString* str = furi_string_alloc(); - if(app->mode == SPIMemModeRead) furi_string_printf(str, "%s", "Read"); - if(app->mode == SPIMemModeWrite) furi_string_printf(str, "%s", "Write"); - if(app->mode == SPIMemModeErase) furi_string_printf(str, "%s", "Erase"); - if(app->mode == SPIMemModeCompare) furi_string_printf(str, "%s", "Check"); - widget_add_button_element( - app->widget, - GuiButtonTypeRight, - furi_string_get_cstr(str), - spi_mem_scene_chip_detected_widget_callback, - app); - furi_string_free(str); -} - -static void spi_mem_scene_chip_detected_set_previous_scene(SPIMemApp* app) { - uint32_t scene = SPIMemSceneStart; - if(app->mode == SPIMemModeCompare || app->mode == SPIMemModeWrite) - scene = SPIMemSceneSavedFileMenu; - scene_manager_search_and_switch_to_previous_scene(app->scene_manager, scene); -} - -static void spi_mem_scene_chip_detected_set_next_scene(SPIMemApp* app) { - uint32_t scene = SPIMemSceneStart; - if(app->mode == SPIMemModeRead) scene = SPIMemSceneReadFilename; - if(app->mode == SPIMemModeWrite) scene = SPIMemSceneErase; - if(app->mode == SPIMemModeErase) scene = SPIMemSceneErase; - if(app->mode == SPIMemModeCompare) scene = SPIMemSceneVerify; - scene_manager_next_scene(app->scene_manager, scene); -} - -void spi_mem_scene_chip_detected_on_enter(void* context) { - SPIMemApp* app = context; - widget_add_button_element( - app->widget, GuiButtonTypeLeft, "Retry", spi_mem_scene_chip_detected_widget_callback, app); - spi_mem_scene_chip_detect_draw_next_button(app); - widget_add_icon_element(app->widget, 0, 12, &I_Dip8_32x36); - widget_add_string_element( - app->widget, 64, 9, AlignCenter, AlignBottom, FontPrimary, "Detected SPI chip"); - spi_mem_scene_chip_detected_print_chip_info(app->widget, app->chip_info); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget); -} - -bool spi_mem_scene_chip_detected_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - bool success = false; - if(event.type == SceneManagerEventTypeBack) { - success = true; - spi_mem_scene_chip_detected_set_previous_scene(app); - } else if(event.type == SceneManagerEventTypeCustom) { - success = true; - if(event.event == GuiButtonTypeLeft) { - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, SPIMemSceneChipDetect); - } else if(event.event == GuiButtonTypeRight) { - spi_mem_scene_chip_detected_set_next_scene(app); - } - } - return success; -} -void spi_mem_scene_chip_detected_on_exit(void* context) { - SPIMemApp* app = context; - widget_reset(app->widget); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_chip_error.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_chip_error.c deleted file mode 100644 index ca4b765a2..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_chip_error.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "../spi_mem_app_i.h" - -static void - spi_mem_scene_chip_error_widget_callback(GuiButtonType result, InputType type, void* context) { - SPIMemApp* app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(app->view_dispatcher, result); - } -} - -void spi_mem_scene_chip_error_on_enter(void* context) { - SPIMemApp* app = context; - widget_add_button_element( - app->widget, GuiButtonTypeLeft, "Back", spi_mem_scene_chip_error_widget_callback, app); - widget_add_string_element( - app->widget, 85, 15, AlignCenter, AlignBottom, FontPrimary, "SPI chip error"); - widget_add_string_multiline_element( - app->widget, - 85, - 52, - AlignCenter, - AlignBottom, - FontSecondary, - "Error while\ncommunicating\nwith chip"); - widget_add_icon_element(app->widget, 5, 6, &I_Dip8_32x36); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget); -} - -static void spi_mem_scene_chip_error_set_previous_scene(SPIMemApp* app) { - uint32_t scene = SPIMemSceneChipDetect; - if(app->mode == SPIMemModeRead || app->mode == SPIMemModeErase) scene = SPIMemSceneStart; - scene_manager_search_and_switch_to_previous_scene(app->scene_manager, scene); -} - -bool spi_mem_scene_chip_error_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - bool success = false; - if(event.type == SceneManagerEventTypeBack) { - success = true; - spi_mem_scene_chip_error_set_previous_scene(app); - } else if(event.type == SceneManagerEventTypeCustom) { - success = true; - if(event.event == GuiButtonTypeLeft) { - spi_mem_scene_chip_error_set_previous_scene(app); - } - } - return success; -} -void spi_mem_scene_chip_error_on_exit(void* context) { - SPIMemApp* app = context; - widget_reset(app->widget); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_config.h b/applications/external/spi_mem_manager/scenes/spi_mem_scene_config.h deleted file mode 100644 index c0e377303..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_config.h +++ /dev/null @@ -1,21 +0,0 @@ -ADD_SCENE(spi_mem, start, Start) -ADD_SCENE(spi_mem, chip_detect, ChipDetect) -ADD_SCENE(spi_mem, chip_detected, ChipDetected) -ADD_SCENE(spi_mem, chip_detect_fail, ChipDetectFail) -ADD_SCENE(spi_mem, select_file, SelectFile) -ADD_SCENE(spi_mem, saved_file_menu, SavedFileMenu) -ADD_SCENE(spi_mem, read, Read) -ADD_SCENE(spi_mem, read_filename, ReadFilename) -ADD_SCENE(spi_mem, delete_confirm, DeleteConfirm) -ADD_SCENE(spi_mem, success, Success) -ADD_SCENE(spi_mem, about, About) -ADD_SCENE(spi_mem, verify, Verify) -ADD_SCENE(spi_mem, file_info, FileInfo) -ADD_SCENE(spi_mem, erase, Erase) -ADD_SCENE(spi_mem, chip_error, ChipError) -ADD_SCENE(spi_mem, verify_error, VerifyError) -ADD_SCENE(spi_mem, write, Write) -ADD_SCENE(spi_mem, storage_error, StorageError) -ADD_SCENE(spi_mem, select_vendor, SelectVendor) -ADD_SCENE(spi_mem, select_model, SelectModel) -ADD_SCENE(spi_mem, wiring, Wiring) diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_delete_confirm.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_delete_confirm.c deleted file mode 100644 index bb5142452..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_delete_confirm.c +++ /dev/null @@ -1,62 +0,0 @@ -#include "../spi_mem_app_i.h" -#include "../spi_mem_files.h" - -static void spi_mem_scene_delete_confirm_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - SPIMemApp* app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(app->view_dispatcher, result); - } -} - -void spi_mem_scene_delete_confirm_on_enter(void* context) { - SPIMemApp* app = context; - FuriString* file_name = furi_string_alloc(); - FuriString* message = furi_string_alloc(); - path_extract_filename(app->file_path, file_name, true); - furi_string_printf(message, "\e#Delete %s?\e#", furi_string_get_cstr(file_name)); - widget_add_text_box_element( - app->widget, 0, 0, 128, 27, AlignCenter, AlignCenter, furi_string_get_cstr(message), true); - widget_add_button_element( - app->widget, - GuiButtonTypeLeft, - "Cancel", - spi_mem_scene_delete_confirm_widget_callback, - app); - widget_add_button_element( - app->widget, - GuiButtonTypeRight, - "Delete", - spi_mem_scene_delete_confirm_widget_callback, - app); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget); - furi_string_free(file_name); - furi_string_free(message); -} - -bool spi_mem_scene_delete_confirm_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - bool success = false; - if(event.type == SceneManagerEventTypeCustom) { - success = true; - if(event.event == GuiButtonTypeRight) { - app->mode = SPIMemModeDelete; - if(spi_mem_file_delete(app)) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneSuccess); - } else { - scene_manager_next_scene(app->scene_manager, SPIMemSceneStorageError); - } - } else if(event.event == GuiButtonTypeLeft) { - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, SPIMemSceneSavedFileMenu); - } - } - return success; -} - -void spi_mem_scene_delete_confirm_on_exit(void* context) { - SPIMemApp* app = context; - widget_reset(app->widget); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_erase.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_erase.c deleted file mode 100644 index 0d3ae66bf..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_erase.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "../spi_mem_app_i.h" - -static void - spi_mem_scene_erase_widget_callback(GuiButtonType result, InputType type, void* context) { - SPIMemApp* app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(app->view_dispatcher, result); - } -} - -static void spi_mem_scene_erase_callback(void* context, SPIMemCustomEventWorker event) { - SPIMemApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -void spi_mem_scene_erase_on_enter(void* context) { - SPIMemApp* app = context; - widget_add_button_element( - app->widget, GuiButtonTypeLeft, "Cancel", spi_mem_scene_erase_widget_callback, app); - widget_add_string_element( - app->widget, 64, 15, AlignCenter, AlignBottom, FontPrimary, "Erasing SPI chip"); - widget_add_string_element( - app->widget, 64, 27, AlignCenter, AlignBottom, FontSecondary, "Please be patient"); - notification_message(app->notifications, &sequence_blink_start_magenta); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget); - spi_mem_worker_start_thread(app->worker); - spi_mem_worker_erase_start(app->chip_info, app->worker, spi_mem_scene_erase_callback, app); -} - -static void spi_mem_scene_erase_set_previous_scene(SPIMemApp* app) { - uint32_t scene = SPIMemSceneStart; - if(app->mode == SPIMemModeWrite) scene = SPIMemSceneSavedFileMenu; - scene_manager_search_and_switch_to_previous_scene(app->scene_manager, scene); -} - -static void spi_mem_scene_erase_set_next_scene(SPIMemApp* app) { - uint32_t scene = SPIMemSceneSuccess; - if(app->mode == SPIMemModeWrite) scene = SPIMemSceneWrite; - scene_manager_next_scene(app->scene_manager, scene); -} - -bool spi_mem_scene_erase_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - bool success = false; - if(event.type == SceneManagerEventTypeBack) { - success = true; - spi_mem_scene_erase_set_previous_scene(app); - } else if(event.type == SceneManagerEventTypeCustom) { - success = true; - if(event.event == GuiButtonTypeLeft) { - scene_manager_previous_scene(app->scene_manager); - } else if(event.event == SPIMemCustomEventWorkerDone) { - spi_mem_scene_erase_set_next_scene(app); - } else if(event.event == SPIMemCustomEventWorkerChipFail) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneChipError); - } - } - return success; -} -void spi_mem_scene_erase_on_exit(void* context) { - SPIMemApp* app = context; - spi_mem_worker_stop_thread(app->worker); - notification_message(app->notifications, &sequence_blink_stop); - widget_reset(app->widget); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_file_info.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_file_info.c deleted file mode 100644 index 687f17f81..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_file_info.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "../spi_mem_app_i.h" -#include "../spi_mem_files.h" - -void spi_mem_scene_file_info_on_enter(void* context) { - SPIMemApp* app = context; - FuriString* str = furi_string_alloc(); - furi_string_printf(str, "Size: %zu KB", spi_mem_file_get_size(app) / 1024); - widget_add_string_element( - app->widget, 64, 9, AlignCenter, AlignBottom, FontPrimary, "File info"); - widget_add_string_element( - app->widget, 64, 20, AlignCenter, AlignBottom, FontSecondary, furi_string_get_cstr(str)); - furi_string_free(str); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget); -} - -bool spi_mem_scene_file_info_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - bool success = false; - if(event.type == SceneManagerEventTypeBack) { - success = true; - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, SPIMemSceneSavedFileMenu); - } - return success; -} -void spi_mem_scene_file_info_on_exit(void* context) { - SPIMemApp* app = context; - widget_reset(app->widget); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_read.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_read.c deleted file mode 100644 index bbf38a303..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_read.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "../spi_mem_app_i.h" -#include "../spi_mem_files.h" -#include "../lib/spi/spi_mem_chip.h" -#include "../lib/spi/spi_mem_tools.h" - -void spi_mem_scene_read_progress_view_result_callback(void* context) { - SPIMemApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SPIMemCustomEventViewReadCancel); -} - -static void spi_mem_scene_read_callback(void* context, SPIMemCustomEventWorker event) { - SPIMemApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -void spi_mem_scene_read_on_enter(void* context) { - SPIMemApp* app = context; - spi_mem_view_progress_set_read_callback( - app->view_progress, spi_mem_scene_read_progress_view_result_callback, app); - notification_message(app->notifications, &sequence_blink_start_blue); - spi_mem_view_progress_set_chip_size(app->view_progress, spi_mem_chip_get_size(app->chip_info)); - spi_mem_view_progress_set_block_size( - app->view_progress, spi_mem_tools_get_file_max_block_size(app->chip_info)); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewProgress); - spi_mem_worker_start_thread(app->worker); - spi_mem_worker_read_start(app->chip_info, app->worker, spi_mem_scene_read_callback, app); -} - -bool spi_mem_scene_read_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - UNUSED(app); - bool success = false; - if(event.type == SceneManagerEventTypeBack) { - success = true; - } else if(event.type == SceneManagerEventTypeCustom) { - success = true; - if(event.event == SPIMemCustomEventViewReadCancel) { - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, SPIMemSceneChipDetect); - } else if(event.event == SPIMemCustomEventWorkerBlockReaded) { - spi_mem_view_progress_inc_progress(app->view_progress); - } else if(event.event == SPIMemCustomEventWorkerDone) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneVerify); - } else if(event.event == SPIMemCustomEventWorkerChipFail) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneChipError); - } else if(event.event == SPIMemCustomEventWorkerFileFail) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneStorageError); - } - } - return success; -} -void spi_mem_scene_read_on_exit(void* context) { - SPIMemApp* app = context; - spi_mem_worker_stop_thread(app->worker); - spi_mem_view_progress_reset(app->view_progress); - notification_message(app->notifications, &sequence_blink_stop); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_read_filename.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_read_filename.c deleted file mode 100644 index 4b16baa2e..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_read_filename.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "../spi_mem_app_i.h" -#include "../spi_mem_files.h" - -void spi_mem_scene_read_filename_view_result_callback(void* context) { - SPIMemApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SPIMemCustomEventTextEditResult); -} - -void spi_mem_scene_read_set_random_filename(SPIMemApp* app) { - if(furi_string_end_with(app->file_path, SPI_MEM_FILE_EXTENSION)) { - size_t filename_start = furi_string_search_rchar(app->file_path, '/'); - furi_string_left(app->file_path, filename_start); - } - set_random_name(app->text_buffer, SPI_MEM_TEXT_BUFFER_SIZE); -} - -void spi_mem_scene_read_filename_on_enter(void* context) { - SPIMemApp* app = context; - spi_mem_scene_read_set_random_filename(app); - text_input_set_header_text(app->text_input, "Name the dump"); - text_input_set_result_callback( - app->text_input, - spi_mem_scene_read_filename_view_result_callback, - app, - app->text_buffer, - SPI_MEM_FILE_NAME_SIZE, - true); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewTextInput); -} - -bool spi_mem_scene_read_filename_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - UNUSED(app); - bool success = false; - if(event.type == SceneManagerEventTypeCustom) { - success = true; - if(event.event == SPIMemCustomEventTextEditResult) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneRead); - } - } - return success; -} -void spi_mem_scene_read_filename_on_exit(void* context) { - SPIMemApp* app = context; - text_input_reset(app->text_input); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_saved_file_menu.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_saved_file_menu.c deleted file mode 100644 index d5767455e..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_saved_file_menu.c +++ /dev/null @@ -1,76 +0,0 @@ -#include "../spi_mem_app_i.h" - -typedef enum { - SPIMemSceneSavedFileMenuSubmenuIndexWrite, - SPIMemSceneSavedFileMenuSubmenuIndexCompare, - SPIMemSceneSavedFileMenuSubmenuIndexInfo, - SPIMemSceneSavedFileMenuSubmenuIndexDelete, -} SPIMemSceneSavedFileMenuSubmenuIndex; - -static void spi_mem_scene_saved_file_menu_submenu_callback(void* context, uint32_t index) { - SPIMemApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void spi_mem_scene_saved_file_menu_on_enter(void* context) { - SPIMemApp* app = context; - submenu_add_item( - app->submenu, - "Write", - SPIMemSceneSavedFileMenuSubmenuIndexWrite, - spi_mem_scene_saved_file_menu_submenu_callback, - app); - submenu_add_item( - app->submenu, - "Compare", - SPIMemSceneSavedFileMenuSubmenuIndexCompare, - spi_mem_scene_saved_file_menu_submenu_callback, - app); - submenu_add_item( - app->submenu, - "Info", - SPIMemSceneSavedFileMenuSubmenuIndexInfo, - spi_mem_scene_saved_file_menu_submenu_callback, - app); - submenu_add_item( - app->submenu, - "Delete", - SPIMemSceneSavedFileMenuSubmenuIndexDelete, - spi_mem_scene_saved_file_menu_submenu_callback, - app); - submenu_set_selected_item( - app->submenu, scene_manager_get_scene_state(app->scene_manager, SPIMemSceneSavedFileMenu)); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewSubmenu); -} - -bool spi_mem_scene_saved_file_menu_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - bool success = false; - if(event.type == SceneManagerEventTypeCustom) { - scene_manager_set_scene_state(app->scene_manager, SPIMemSceneSavedFileMenu, event.event); - if(event.event == SPIMemSceneSavedFileMenuSubmenuIndexWrite) { - app->mode = SPIMemModeWrite; - scene_manager_next_scene(app->scene_manager, SPIMemSceneChipDetect); - success = true; - } - if(event.event == SPIMemSceneSavedFileMenuSubmenuIndexCompare) { - app->mode = SPIMemModeCompare; - scene_manager_next_scene(app->scene_manager, SPIMemSceneChipDetect); - success = true; - } - if(event.event == SPIMemSceneSavedFileMenuSubmenuIndexDelete) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneDeleteConfirm); - success = true; - } - if(event.event == SPIMemSceneSavedFileMenuSubmenuIndexInfo) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneFileInfo); - success = true; - } - } - return success; -} - -void spi_mem_scene_saved_file_menu_on_exit(void* context) { - SPIMemApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_select_file.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_select_file.c deleted file mode 100644 index cb48035b5..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_select_file.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "../spi_mem_app_i.h" -#include "../spi_mem_files.h" - -void spi_mem_scene_select_file_on_enter(void* context) { - SPIMemApp* app = context; - if(spi_mem_file_select(app)) { - scene_manager_set_scene_state(app->scene_manager, SPIMemSceneSavedFileMenu, 0); - scene_manager_next_scene(app->scene_manager, SPIMemSceneSavedFileMenu); - } else { - scene_manager_search_and_switch_to_previous_scene(app->scene_manager, SPIMemSceneStart); - } -} - -bool spi_mem_scene_select_file_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void spi_mem_scene_select_file_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_select_model.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_select_model.c deleted file mode 100644 index c39c4a182..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_select_model.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "../spi_mem_app_i.h" - -static void spi_mem_scene_select_model_submenu_callback(void* context, uint32_t index) { - SPIMemApp* app = context; - spi_mem_chip_copy_chip_info(app->chip_info, *found_chips_get(app->found_chips, index)); - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void spi_mem_scene_select_model_on_enter(void* context) { - SPIMemApp* app = context; - size_t models_on_vendor = 0; - for(size_t index = 0; index < found_chips_size(app->found_chips); index++) { - if(spi_mem_chip_get_vendor_enum(*found_chips_get(app->found_chips, index)) != - app->chip_vendor_enum) - continue; - submenu_add_item( - app->submenu, - spi_mem_chip_get_model_name(*found_chips_get(app->found_chips, index)), - index, - spi_mem_scene_select_model_submenu_callback, - app); - models_on_vendor++; - } - if(models_on_vendor == 1) spi_mem_scene_select_model_submenu_callback(context, 0); - submenu_set_header(app->submenu, "Choose chip model"); - submenu_set_selected_item( - app->submenu, scene_manager_get_scene_state(app->scene_manager, SPIMemSceneSelectVendor)); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewSubmenu); -} - -bool spi_mem_scene_select_model_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - bool success = false; - if(event.type == SceneManagerEventTypeCustom) { - scene_manager_set_scene_state(app->scene_manager, SPIMemSceneSelectVendor, event.event); - scene_manager_next_scene(app->scene_manager, SPIMemSceneChipDetected); - success = true; - } - return success; -} - -void spi_mem_scene_select_model_on_exit(void* context) { - SPIMemApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_select_vendor.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_select_vendor.c deleted file mode 100644 index c7f736f88..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_select_vendor.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "../spi_mem_app_i.h" -#include -#include - -ARRAY_DEF(vendors, uint32_t) -ALGO_DEF(vendors, ARRAY_OPLIST(vendors)) - -static void spi_mem_scene_select_vendor_submenu_callback(void* context, uint32_t index) { - SPIMemApp* app = context; - app->chip_vendor_enum = index; - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -static void spi_mem_scene_select_vendor_sort_vendors(SPIMemApp* app, vendors_t vendors_arr) { - for(size_t index = 0; index < found_chips_size(app->found_chips); index++) { - vendors_push_back( - vendors_arr, spi_mem_chip_get_vendor_enum(*found_chips_get(app->found_chips, index))); - } - vendors_uniq(vendors_arr); -} - -void spi_mem_scene_select_vendor_on_enter(void* context) { - SPIMemApp* app = context; - vendors_t vendors_arr; - vendors_init(vendors_arr); - spi_mem_scene_select_vendor_sort_vendors(app, vendors_arr); - size_t vendors_arr_size = vendors_size(vendors_arr); - if(vendors_arr_size == 1) - spi_mem_scene_select_vendor_submenu_callback(context, *vendors_get(vendors_arr, 0)); - for(size_t index = 0; index < vendors_arr_size; index++) { - uint32_t vendor_enum = *vendors_get(vendors_arr, index); - submenu_add_item( - app->submenu, - spi_mem_chip_get_vendor_name_by_enum(vendor_enum), - vendor_enum, - spi_mem_scene_select_vendor_submenu_callback, - app); - } - vendors_clear(vendors_arr); - submenu_set_header(app->submenu, "Choose chip vendor"); - submenu_set_selected_item( - app->submenu, scene_manager_get_scene_state(app->scene_manager, SPIMemSceneSelectVendor)); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewSubmenu); -} - -static void spi_mem_scene_select_vendor_set_previous_scene(SPIMemApp* app) { - uint32_t scene = SPIMemSceneStart; - if(app->mode == SPIMemModeCompare || app->mode == SPIMemModeWrite) - scene = SPIMemSceneSavedFileMenu; - scene_manager_search_and_switch_to_previous_scene(app->scene_manager, scene); -} - -bool spi_mem_scene_select_vendor_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - bool success = false; - if(event.type == SceneManagerEventTypeBack) { - success = true; - spi_mem_scene_select_vendor_set_previous_scene(app); - } else if(event.type == SceneManagerEventTypeCustom) { - scene_manager_set_scene_state(app->scene_manager, SPIMemSceneSelectVendor, event.event); - scene_manager_next_scene(app->scene_manager, SPIMemSceneSelectModel); - success = true; - } - return success; -} - -void spi_mem_scene_select_vendor_on_exit(void* context) { - SPIMemApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_start.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_start.c deleted file mode 100644 index 38d064a4d..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_start.c +++ /dev/null @@ -1,84 +0,0 @@ -#include "../spi_mem_app_i.h" - -typedef enum { - SPIMemSceneStartSubmenuIndexRead, - SPIMemSceneStartSubmenuIndexSaved, - SPIMemSceneStartSubmenuIndexErase, - SPIMemSceneStartSubmenuIndexWiring, - SPIMemSceneStartSubmenuIndexAbout -} SPIMemSceneStartSubmenuIndex; - -static void spi_mem_scene_start_submenu_callback(void* context, uint32_t index) { - SPIMemApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void spi_mem_scene_start_on_enter(void* context) { - SPIMemApp* app = context; - submenu_add_item( - app->submenu, - "Read", - SPIMemSceneStartSubmenuIndexRead, - spi_mem_scene_start_submenu_callback, - app); - submenu_add_item( - app->submenu, - "Saved", - SPIMemSceneStartSubmenuIndexSaved, - spi_mem_scene_start_submenu_callback, - app); - submenu_add_item( - app->submenu, - "Erase", - SPIMemSceneStartSubmenuIndexErase, - spi_mem_scene_start_submenu_callback, - app); - submenu_add_item( - app->submenu, - "Wiring", - SPIMemSceneStartSubmenuIndexWiring, - spi_mem_scene_start_submenu_callback, - app); - submenu_add_item( - app->submenu, - "About", - SPIMemSceneStartSubmenuIndexAbout, - spi_mem_scene_start_submenu_callback, - app); - submenu_set_selected_item( - app->submenu, scene_manager_get_scene_state(app->scene_manager, SPIMemSceneStart)); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewSubmenu); -} - -bool spi_mem_scene_start_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - bool success = false; - if(event.type == SceneManagerEventTypeCustom) { - scene_manager_set_scene_state(app->scene_manager, SPIMemSceneStart, event.event); - if(event.event == SPIMemSceneStartSubmenuIndexRead) { - app->mode = SPIMemModeRead; - scene_manager_next_scene(app->scene_manager, SPIMemSceneChipDetect); - success = true; - } else if(event.event == SPIMemSceneStartSubmenuIndexSaved) { - furi_string_set(app->file_path, STORAGE_APP_DATA_PATH_PREFIX); - scene_manager_next_scene(app->scene_manager, SPIMemSceneSelectFile); - success = true; - } else if(event.event == SPIMemSceneStartSubmenuIndexErase) { - app->mode = SPIMemModeErase; - scene_manager_next_scene(app->scene_manager, SPIMemSceneChipDetect); - success = true; - } else if(event.event == SPIMemSceneStartSubmenuIndexWiring) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneWiring); - success = true; - } else if(event.event == SPIMemSceneStartSubmenuIndexAbout) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneAbout); - success = true; - } - } - return success; -} - -void spi_mem_scene_start_on_exit(void* context) { - SPIMemApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_storage_error.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_storage_error.c deleted file mode 100644 index d5e289e24..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_storage_error.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "../spi_mem_app_i.h" - -static void spi_mem_scene_storage_error_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - SPIMemApp* app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(app->view_dispatcher, result); - } -} - -void spi_mem_scene_storage_error_on_enter(void* context) { - SPIMemApp* app = context; - widget_add_button_element( - app->widget, GuiButtonTypeLeft, "Back", spi_mem_scene_storage_error_widget_callback, app); - widget_add_string_element( - app->widget, 85, 15, AlignCenter, AlignBottom, FontPrimary, "Storage error"); - widget_add_string_multiline_element( - app->widget, - 85, - 52, - AlignCenter, - AlignBottom, - FontSecondary, - "Error while\nworking with\nfilesystem"); - widget_add_icon_element(app->widget, 5, 6, &I_SDQuestion_35x43); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget); -} - -static void spi_mem_scene_storage_error_set_previous_scene(SPIMemApp* app) { - uint32_t scene = SPIMemSceneChipDetect; - if(app->mode == SPIMemModeRead) scene = SPIMemSceneStart; - if(app->mode == SPIMemModeErase) scene = SPIMemSceneStart; - if(app->mode == SPIMemModeDelete) scene = SPIMemSceneStart; - scene_manager_search_and_switch_to_previous_scene(app->scene_manager, scene); -} - -bool spi_mem_scene_storage_error_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - bool success = false; - if(event.type == SceneManagerEventTypeBack) { - success = true; - spi_mem_scene_storage_error_set_previous_scene(app); - } else if(event.type == SceneManagerEventTypeCustom) { - success = true; - if(event.event == GuiButtonTypeLeft) { - spi_mem_scene_storage_error_set_previous_scene(app); - } - } - return success; -} -void spi_mem_scene_storage_error_on_exit(void* context) { - SPIMemApp* app = context; - widget_reset(app->widget); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_success.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_success.c deleted file mode 100644 index 39039466f..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_success.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "../spi_mem_app_i.h" - -static void spi_mem_scene_success_popup_callback(void* context) { - SPIMemApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SPIMemCustomEventPopupBack); -} - -void spi_mem_scene_success_on_enter(void* context) { - SPIMemApp* app = context; - popup_set_icon(app->popup, 32, 5, &I_DolphinNice_96x59); - popup_set_header(app->popup, "Success!", 5, 7, AlignLeft, AlignTop); - popup_set_callback(app->popup, spi_mem_scene_success_popup_callback); - popup_set_context(app->popup, app); - popup_set_timeout(app->popup, 1500); - popup_enable_timeout(app->popup); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewPopup); -} - -static void spi_mem_scene_success_set_previous_scene(SPIMemApp* app) { - uint32_t scene = SPIMemSceneSelectFile; - if(app->mode == SPIMemModeErase) scene = SPIMemSceneStart; - scene_manager_search_and_switch_to_another_scene(app->scene_manager, scene); -} - -bool spi_mem_scene_success_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - bool success = false; - if(event.type == SceneManagerEventTypeCustom) { - success = true; - if(event.event == SPIMemCustomEventPopupBack) { - spi_mem_scene_success_set_previous_scene(app); - } - } - return success; -} - -void spi_mem_scene_success_on_exit(void* context) { - SPIMemApp* app = context; - popup_reset(app->popup); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_verify.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_verify.c deleted file mode 100644 index 08a8d1057..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_verify.c +++ /dev/null @@ -1,59 +0,0 @@ -#include "../spi_mem_app_i.h" -#include "../spi_mem_files.h" -#include "../lib/spi/spi_mem_chip.h" -#include "../lib/spi/spi_mem_tools.h" - -void spi_mem_scene_verify_view_result_callback(void* context) { - SPIMemApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SPIMemCustomEventViewVerifySkip); -} - -static void spi_mem_scene_verify_callback(void* context, SPIMemCustomEventWorker event) { - SPIMemApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -void spi_mem_scene_verify_on_enter(void* context) { - SPIMemApp* app = context; - spi_mem_view_progress_set_verify_callback( - app->view_progress, spi_mem_scene_verify_view_result_callback, app); - notification_message(app->notifications, &sequence_blink_start_cyan); - spi_mem_view_progress_set_chip_size(app->view_progress, spi_mem_chip_get_size(app->chip_info)); - spi_mem_view_progress_set_file_size(app->view_progress, spi_mem_file_get_size(app)); - spi_mem_view_progress_set_block_size( - app->view_progress, spi_mem_tools_get_file_max_block_size(app->chip_info)); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewProgress); - spi_mem_worker_start_thread(app->worker); - spi_mem_worker_verify_start(app->chip_info, app->worker, spi_mem_scene_verify_callback, app); -} - -bool spi_mem_scene_verify_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - UNUSED(app); - bool success = false; - if(event.type == SceneManagerEventTypeBack) { - success = true; - } else if(event.type == SceneManagerEventTypeCustom) { - success = true; - if(event.event == SPIMemCustomEventViewVerifySkip) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneSuccess); - } else if(event.event == SPIMemCustomEventWorkerBlockReaded) { - spi_mem_view_progress_inc_progress(app->view_progress); - } else if(event.event == SPIMemCustomEventWorkerChipFail) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneChipError); - } else if(event.event == SPIMemCustomEventWorkerFileFail) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneStorageError); - } else if(event.event == SPIMemCustomEventWorkerDone) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneSuccess); - } else if(event.event == SPIMemCustomEventWorkerVerifyFail) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneVerifyError); - } - } - return success; -} -void spi_mem_scene_verify_on_exit(void* context) { - SPIMemApp* app = context; - spi_mem_worker_stop_thread(app->worker); - spi_mem_view_progress_reset(app->view_progress); - notification_message(app->notifications, &sequence_blink_stop); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_verify_error.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_verify_error.c deleted file mode 100644 index fbe954fa6..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_verify_error.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "../spi_mem_app_i.h" - -static void spi_mem_scene_verify_error_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - SPIMemApp* app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(app->view_dispatcher, result); - } -} - -void spi_mem_scene_verify_error_on_enter(void* context) { - SPIMemApp* app = context; - widget_add_button_element( - app->widget, GuiButtonTypeLeft, "Back", spi_mem_scene_verify_error_widget_callback, app); - widget_add_string_element( - app->widget, 64, 9, AlignCenter, AlignBottom, FontPrimary, "Verification error"); - widget_add_string_element( - app->widget, 64, 21, AlignCenter, AlignBottom, FontSecondary, "Data mismatch"); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget); -} - -bool spi_mem_scene_verify_error_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - bool success = false; - if(event.type == SceneManagerEventTypeBack) { - success = true; - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, SPIMemSceneChipDetect); - } else if(event.type == SceneManagerEventTypeCustom) { - success = true; - if(event.event == GuiButtonTypeLeft) { - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, SPIMemSceneChipDetect); - } - } - return success; -} -void spi_mem_scene_verify_error_on_exit(void* context) { - SPIMemApp* app = context; - widget_reset(app->widget); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_wiring.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_wiring.c deleted file mode 100644 index 22036f4bc..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_wiring.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "../spi_mem_app_i.h" -#include "../lib/spi/spi_mem_chip.h" - -void spi_mem_scene_wiring_on_enter(void* context) { - SPIMemApp* app = context; - widget_add_icon_element(app->widget, 0, 0, &I_Wiring_SPI_128x64); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewWidget); -} - -bool spi_mem_scene_wiring_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} -void spi_mem_scene_wiring_on_exit(void* context) { - SPIMemApp* app = context; - widget_reset(app->widget); -} diff --git a/applications/external/spi_mem_manager/scenes/spi_mem_scene_write.c b/applications/external/spi_mem_manager/scenes/spi_mem_scene_write.c deleted file mode 100644 index dfa384fbb..000000000 --- a/applications/external/spi_mem_manager/scenes/spi_mem_scene_write.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "../spi_mem_app_i.h" -#include "../spi_mem_files.h" -#include "../lib/spi/spi_mem_chip.h" -#include "../lib/spi/spi_mem_tools.h" - -void spi_mem_scene_write_progress_view_result_callback(void* context) { - SPIMemApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SPIMemCustomEventViewReadCancel); -} - -static void spi_mem_scene_write_callback(void* context, SPIMemCustomEventWorker event) { - SPIMemApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -void spi_mem_scene_write_on_enter(void* context) { - SPIMemApp* app = context; - spi_mem_view_progress_set_write_callback( - app->view_progress, spi_mem_scene_write_progress_view_result_callback, app); - notification_message(app->notifications, &sequence_blink_start_cyan); - spi_mem_view_progress_set_chip_size(app->view_progress, spi_mem_chip_get_size(app->chip_info)); - spi_mem_view_progress_set_file_size(app->view_progress, spi_mem_file_get_size(app)); - spi_mem_view_progress_set_block_size( - app->view_progress, spi_mem_tools_get_file_max_block_size(app->chip_info)); - view_dispatcher_switch_to_view(app->view_dispatcher, SPIMemViewProgress); - spi_mem_worker_start_thread(app->worker); - spi_mem_worker_write_start(app->chip_info, app->worker, spi_mem_scene_write_callback, app); -} - -bool spi_mem_scene_write_on_event(void* context, SceneManagerEvent event) { - SPIMemApp* app = context; - UNUSED(app); - bool success = false; - if(event.type == SceneManagerEventTypeBack) { - success = true; - } else if(event.type == SceneManagerEventTypeCustom) { - success = true; - if(event.event == SPIMemCustomEventViewReadCancel) { - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, SPIMemSceneChipDetect); - } else if(event.event == SPIMemCustomEventWorkerBlockReaded) { - spi_mem_view_progress_inc_progress(app->view_progress); - } else if(event.event == SPIMemCustomEventWorkerDone) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneVerify); - } else if(event.event == SPIMemCustomEventWorkerChipFail) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneChipError); - } else if(event.event == SPIMemCustomEventWorkerFileFail) { - scene_manager_next_scene(app->scene_manager, SPIMemSceneStorageError); - } - } - return success; -} -void spi_mem_scene_write_on_exit(void* context) { - SPIMemApp* app = context; - spi_mem_worker_stop_thread(app->worker); - spi_mem_view_progress_reset(app->view_progress); - notification_message(app->notifications, &sequence_blink_stop); -} diff --git a/applications/external/spi_mem_manager/spi_mem_app.c b/applications/external/spi_mem_manager/spi_mem_app.c deleted file mode 100644 index 96c3632d0..000000000 --- a/applications/external/spi_mem_manager/spi_mem_app.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include "spi_mem_app_i.h" -#include "spi_mem_files.h" -#include "lib/spi/spi_mem_chip_i.h" - -static bool spi_mem_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - SPIMemApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool spi_mem_back_event_callback(void* context) { - furi_assert(context); - SPIMemApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -SPIMemApp* spi_mem_alloc(void) { - SPIMemApp* instance = malloc(sizeof(SPIMemApp)); //-V799 - - instance->file_path = furi_string_alloc_set(STORAGE_APP_DATA_PATH_PREFIX); - instance->gui = furi_record_open(RECORD_GUI); - instance->notifications = furi_record_open(RECORD_NOTIFICATION); - instance->view_dispatcher = view_dispatcher_alloc(); - instance->scene_manager = scene_manager_alloc(&spi_mem_scene_handlers, instance); - instance->submenu = submenu_alloc(); - instance->dialog_ex = dialog_ex_alloc(); - instance->popup = popup_alloc(); - instance->worker = spi_mem_worker_alloc(); - instance->dialogs = furi_record_open(RECORD_DIALOGS); - instance->storage = furi_record_open(RECORD_STORAGE); - instance->widget = widget_alloc(); - instance->chip_info = malloc(sizeof(SPIMemChip)); - found_chips_init(instance->found_chips); - instance->view_progress = spi_mem_view_progress_alloc(); - instance->view_detect = spi_mem_view_detect_alloc(); - instance->text_input = text_input_alloc(); - instance->mode = SPIMemModeUnknown; - - // Migrate data from old sd-card folder - storage_common_migrate(instance->storage, EXT_PATH("spimem"), STORAGE_APP_DATA_PATH_PREFIX); - - view_dispatcher_enable_queue(instance->view_dispatcher); - view_dispatcher_set_event_callback_context(instance->view_dispatcher, instance); - view_dispatcher_set_custom_event_callback( - instance->view_dispatcher, spi_mem_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - instance->view_dispatcher, spi_mem_back_event_callback); - view_dispatcher_attach_to_gui( - instance->view_dispatcher, instance->gui, ViewDispatcherTypeFullscreen); - view_dispatcher_add_view( - instance->view_dispatcher, SPIMemViewSubmenu, submenu_get_view(instance->submenu)); - view_dispatcher_add_view( - instance->view_dispatcher, SPIMemViewDialogEx, dialog_ex_get_view(instance->dialog_ex)); - view_dispatcher_add_view( - instance->view_dispatcher, SPIMemViewPopup, popup_get_view(instance->popup)); - view_dispatcher_add_view( - instance->view_dispatcher, SPIMemViewWidget, widget_get_view(instance->widget)); - view_dispatcher_add_view( - instance->view_dispatcher, - SPIMemViewProgress, - spi_mem_view_progress_get_view(instance->view_progress)); - view_dispatcher_add_view( - instance->view_dispatcher, - SPIMemViewDetect, - spi_mem_view_detect_get_view(instance->view_detect)); - view_dispatcher_add_view( - instance->view_dispatcher, SPIMemViewTextInput, text_input_get_view(instance->text_input)); - - furi_hal_power_enable_otg(); - furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_external); - scene_manager_next_scene(instance->scene_manager, SPIMemSceneStart); - return instance; -} //-V773 - -void spi_mem_free(SPIMemApp* instance) { - view_dispatcher_remove_view(instance->view_dispatcher, SPIMemViewSubmenu); - view_dispatcher_remove_view(instance->view_dispatcher, SPIMemViewDialogEx); - view_dispatcher_remove_view(instance->view_dispatcher, SPIMemViewPopup); - view_dispatcher_remove_view(instance->view_dispatcher, SPIMemViewWidget); - view_dispatcher_remove_view(instance->view_dispatcher, SPIMemViewProgress); - view_dispatcher_remove_view(instance->view_dispatcher, SPIMemViewDetect); - view_dispatcher_remove_view(instance->view_dispatcher, SPIMemViewTextInput); - spi_mem_view_progress_free(instance->view_progress); - spi_mem_view_detect_free(instance->view_detect); - submenu_free(instance->submenu); - dialog_ex_free(instance->dialog_ex); - popup_free(instance->popup); - widget_free(instance->widget); - text_input_free(instance->text_input); - view_dispatcher_free(instance->view_dispatcher); - scene_manager_free(instance->scene_manager); - spi_mem_worker_free(instance->worker); - free(instance->chip_info); - found_chips_clear(instance->found_chips); - furi_record_close(RECORD_STORAGE); - furi_record_close(RECORD_DIALOGS); - furi_record_close(RECORD_NOTIFICATION); - furi_record_close(RECORD_GUI); - furi_string_free(instance->file_path); - furi_hal_spi_bus_handle_deinit(&furi_hal_spi_bus_handle_external); - furi_hal_power_disable_otg(); - free(instance); -} - -int32_t spi_mem_app(void* p) { - UNUSED(p); - SPIMemApp* instance = spi_mem_alloc(); - view_dispatcher_run(instance->view_dispatcher); - spi_mem_free(instance); - return 0; -} diff --git a/applications/external/spi_mem_manager/spi_mem_app.h b/applications/external/spi_mem_manager/spi_mem_app.h deleted file mode 100644 index 37ac927db..000000000 --- a/applications/external/spi_mem_manager/spi_mem_app.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -typedef struct SPIMemApp SPIMemApp; diff --git a/applications/external/spi_mem_manager/spi_mem_app_i.h b/applications/external/spi_mem_manager/spi_mem_app_i.h deleted file mode 100644 index 285ca66d2..000000000 --- a/applications/external/spi_mem_manager/spi_mem_app_i.h +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once - -#include -#include -#include -#include "spi_mem_app.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "scenes/spi_mem_scene.h" -#include "lib/spi/spi_mem_worker.h" -#include "spi_mem_manager_icons.h" -#include "views/spi_mem_view_progress.h" -#include "views/spi_mem_view_detect.h" - -#define TAG "SPIMem" -#define SPI_MEM_FILE_EXTENSION ".bin" -#define SPI_MEM_FILE_NAME_SIZE 100 -#define SPI_MEM_TEXT_BUFFER_SIZE 128 - -typedef enum { - SPIMemModeRead, - SPIMemModeWrite, - SPIMemModeCompare, - SPIMemModeErase, - SPIMemModeDelete, - SPIMemModeUnknown -} SPIMemMode; - -struct SPIMemApp { - Gui* gui; - ViewDispatcher* view_dispatcher; - SceneManager* scene_manager; - Submenu* submenu; - DialogEx* dialog_ex; - Popup* popup; - NotificationApp* notifications; - FuriString* file_path; - DialogsApp* dialogs; - Storage* storage; - File* file; - Widget* widget; - SPIMemWorker* worker; - SPIMemChip* chip_info; - found_chips_t found_chips; - uint32_t chip_vendor_enum; - SPIMemProgressView* view_progress; - SPIMemDetectView* view_detect; - TextInput* text_input; - SPIMemMode mode; - char text_buffer[SPI_MEM_TEXT_BUFFER_SIZE + 1]; -}; - -typedef enum { - SPIMemViewSubmenu, - SPIMemViewDialogEx, - SPIMemViewPopup, - SPIMemViewWidget, - SPIMemViewTextInput, - SPIMemViewProgress, - SPIMemViewDetect -} SPIMemView; - -typedef enum { - SPIMemCustomEventViewReadCancel, - SPIMemCustomEventViewVerifySkip, - SPIMemCustomEventTextEditResult, - SPIMemCustomEventPopupBack -} SPIMemCustomEvent; diff --git a/applications/external/spi_mem_manager/spi_mem_files.c b/applications/external/spi_mem_manager/spi_mem_files.c deleted file mode 100644 index 9b787bd7f..000000000 --- a/applications/external/spi_mem_manager/spi_mem_files.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "spi_mem_app_i.h" - -bool spi_mem_file_delete(SPIMemApp* app) { - return (storage_simply_remove(app->storage, furi_string_get_cstr(app->file_path))); -} - -bool spi_mem_file_select(SPIMemApp* app) { - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, SPI_MEM_FILE_EXTENSION, &I_Dip8_10px); - browser_options.base_path = STORAGE_APP_DATA_PATH_PREFIX; - bool success = - dialog_file_browser_show(app->dialogs, app->file_path, app->file_path, &browser_options); - return success; -} - -bool spi_mem_file_create_open(SPIMemApp* app) { - bool success = false; - app->file = storage_file_alloc(app->storage); - do { - if(furi_string_end_with(app->file_path, SPI_MEM_FILE_EXTENSION)) { - if(!spi_mem_file_delete(app)) break; - size_t filename_start = furi_string_search_rchar(app->file_path, '/'); - furi_string_left(app->file_path, filename_start); - } - furi_string_cat_printf(app->file_path, "/%s%s", app->text_buffer, SPI_MEM_FILE_EXTENSION); - if(!storage_file_open( - app->file, furi_string_get_cstr(app->file_path), FSAM_WRITE, FSOM_CREATE_NEW)) - break; - success = true; - } while(0); - if(!success) { //-V547 - dialog_message_show_storage_error(app->dialogs, "Cannot save\nfile"); - } - return success; -} - -bool spi_mem_file_open(SPIMemApp* app) { - app->file = storage_file_alloc(app->storage); - if(!storage_file_open( - app->file, furi_string_get_cstr(app->file_path), FSAM_READ_WRITE, FSOM_OPEN_EXISTING)) { - dialog_message_show_storage_error(app->dialogs, "Cannot save\nfile"); - return false; - } - return true; -} - -bool spi_mem_file_write_block(SPIMemApp* app, uint8_t* data, size_t size) { - if(storage_file_write(app->file, data, size) != size) return false; - return true; -} - -bool spi_mem_file_read_block(SPIMemApp* app, uint8_t* data, size_t size) { - if(storage_file_read(app->file, data, size) != size) return false; - return true; -} - -void spi_mem_file_close(SPIMemApp* app) { - storage_file_close(app->file); - storage_file_free(app->file); -} - -size_t spi_mem_file_get_size(SPIMemApp* app) { - FileInfo file_info; - if(storage_common_stat(app->storage, furi_string_get_cstr(app->file_path), &file_info) != - FSE_OK) - return 0; - return file_info.size; -} diff --git a/applications/external/spi_mem_manager/spi_mem_files.h b/applications/external/spi_mem_manager/spi_mem_files.h deleted file mode 100644 index 6a529d327..000000000 --- a/applications/external/spi_mem_manager/spi_mem_files.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "spi_mem_app.h" - -bool spi_mem_file_select(SPIMemApp* app); -bool spi_mem_file_create(SPIMemApp* app, const char* file_name); -bool spi_mem_file_delete(SPIMemApp* app); -bool spi_mem_file_create_open(SPIMemApp* app); -bool spi_mem_file_open(SPIMemApp* app); -bool spi_mem_file_write_block(SPIMemApp* app, uint8_t* data, size_t size); -bool spi_mem_file_read_block(SPIMemApp* app, uint8_t* data, size_t size); -void spi_mem_file_close(SPIMemApp* app); -void spi_mem_file_show_storage_error(SPIMemApp* app, const char* error_text); -size_t spi_mem_file_get_size(SPIMemApp* app); diff --git a/applications/external/spi_mem_manager/tools/README.md b/applications/external/spi_mem_manager/tools/README.md deleted file mode 100644 index 91080941f..000000000 --- a/applications/external/spi_mem_manager/tools/README.md +++ /dev/null @@ -1,7 +0,0 @@ -This utility can convert nofeletru's UsbAsp-flash's chiplist.xml to C array - -Usage: -```bash - ./chiplist_convert.py chiplist/chiplist.xml - mv spi_mem_chip_arr.c ../lib/spi/spi_mem_chip_arr.c -``` diff --git a/applications/external/spi_mem_manager/tools/chiplist/LICENSE b/applications/external/spi_mem_manager/tools/chiplist/LICENSE deleted file mode 100644 index 56364f150..000000000 --- a/applications/external/spi_mem_manager/tools/chiplist/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 nofeletru - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/applications/external/spi_mem_manager/tools/chiplist/chiplist.xml b/applications/external/spi_mem_manager/tools/chiplist/chiplist.xml deleted file mode 100644 index 91a654743..000000000 --- a/applications/external/spi_mem_manager/tools/chiplist/chiplist.xml +++ /dev/null @@ -1,984 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_25AA010A page="16" size="128" spicmd="95"/> - <_25AA020A page="16" size="256" spicmd="95"/> - <_25AA040 page="16" size="512" spicmd="95"/> - <_25AA040A page="16" size="512" spicmd="95"/> - <_25AA080 page="16" size="1024" spicmd="95"/> - <_25AA080A page="16" size="1024" spicmd="95"/> - <_25AA080B page="32" size="1024" spicmd="95"/> - <_25AA080C page="16" size="1024" spicmd="95"/> - <_25AA080D page="32" size="1024" spicmd="95"/> - <_25AA1024 page="256" size="131072" spicmd="95"/> - <_25AA128 page="64" size="16384" spicmd="95"/> - <_25AA160 page="16" size="2048" spicmd="95"/> - <_25AA160A page="16" size="2048" spicmd="95"/> - <_25AA160B page="32" size="2048" spicmd="95"/> - <_25AA256 page="64" size="32768" spicmd="95"/> - <_25AA320 page="32" size="4096" spicmd="95"/> - <_25AA512 page="128" size="65536" spicmd="95"/> - <_25AA640 page="32" size="8192" spicmd="95"/> - <_25C040 page="16" size="512" spicmd="95"/> - <_25C080 page="16" size="1024" spicmd="95"/> - <_25C160 page="16" size="2048" spicmd="95"/> - <_25C320 page="32" size="4096" spicmd="95"/> - <_25C640 page="32" size="8192" spicmd="95"/> - <_25LC010A page="16" size="128" spicmd="95"/> - <_25LC020A page="16" size="256" spicmd="95"/> - <_25LC040 page="16" size="512" spicmd="95"/> - <_25LC040A page="16" size="512" spicmd="95"/> - <_25LC080 page="16" size="1024" spicmd="95"/> - <_25LC080A page="16" size="1024" spicmd="95"/> - <_25LC080B page="32" size="1024" spicmd="95"/> - <_25LC080C page="16" size="1024" spicmd="95"/> - <_25LC080D page="32" size="1024" spicmd="95"/> - <_25LC1024 page="256" size="131072" spicmd="95"/> - <_25LC128 page="64" size="16384" spicmd="95"/> - <_25LC160 page="16" size="2048" spicmd="95"/> - <_25LC160A page="16" size="2048" spicmd="95"/> - <_25LC160B page="32" size="2048" spicmd="95"/> - <_25LC256 page="64" size="32768" spicmd="95"/> - <_25LC320 page="32" size="4096" spicmd="95"/> - <_25LC512 page="128" size="65536" spicmd="95"/> - <_25LC640 page="32" size="8192" spicmd="95"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_24Cxxx> - - <_24C01 page="1" size="128" addrtype="1"/> - <_24C02 page="1" size="256" addrtype="1"/> - <_24C04 page="1" size="512" addrtype="2"/> - <_24C08 page="16" size="1024" addrtype="3"/> - <_24C16 page="16" size="2048" addrtype="4"/> - <_24C32 page="32" size="4096" addrtype="5"/> - <_24C64 page="32" size="8192" addrtype="5"/> - <_24C128 page="64" size="16384" addrtype="5"/> - <_24C256 page="64" size="32768" addrtype="5"/> - <_24C512 page="128" size="65536" addrtype="5"/> - <_24C1024 page="128" size="131072" addrtype="6"/> - - - - - - - - - - - - - diff --git a/applications/external/spi_mem_manager/tools/chiplist_convert.py b/applications/external/spi_mem_manager/tools/chiplist_convert.py deleted file mode 100755 index 8b623eb3e..000000000 --- a/applications/external/spi_mem_manager/tools/chiplist_convert.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import xml.etree.ElementTree as XML -import sys - - -def getArgs(): - parser = argparse.ArgumentParser( - description="chiplist.xml to C array converter", - ) - parser.add_argument("file", help="chiplist.xml file") - return parser.parse_args() - - -def getXML(file): - tree = XML.parse(file) - root = tree.getroot() - return root - - -def parseChip(cur, arr, vendor, vendorCodeArr): - chip = {} - chipAttr = cur.attrib - if "page" not in chipAttr: # chip without page size not supported - return - if "id" not in chipAttr: # I2C not supported yet - return - if len(chipAttr["id"]) < 6: # ID wihout capacity id not supported yet - return - chip["modelName"] = cur.tag - chip["vendorEnum"] = "SPIMemChipVendor" + vendor - chip["vendorID"] = "0x" + chipAttr["id"][0] + chipAttr["id"][1] - chip["typeID"] = chipAttr["id"][2] + chipAttr["id"][3] - chip["capacityID"] = chipAttr["id"][4] + chipAttr["id"][5] - chip["size"] = chipAttr["size"] - if chipAttr["page"] == "SSTW": - chip["writeMode"] = "SPIMemChipWriteModeAAIWord" - chip["pageSize"] = "1" - elif chipAttr["page"] == "SSTB": - chip["writeMode"] = "SPIMemChipWriteModeAAIByte" - chip["pageSize"] = "1" - else: - chip["writeMode"] = "SPIMemChipWriteModePage" - chip["pageSize"] = chipAttr["page"] - arr.append(chip) - vendorCodeArr[vendor].add(chip["vendorID"]) - - -def cleanEmptyVendors(vendors): - for cur in list(vendors): - if not vendors[cur]: - vendors.pop(cur) - - -def getVendors(xml, interface): - arr = {} - for cur in xml.find(interface): - arr[cur.tag] = set() - return arr - - -def parseXML(xml, interface, vendorCodeArr): - arr = [] - for vendor in xml.find(interface): - for cur in vendor: - parseChip(cur, arr, vendor.tag, vendorCodeArr) - return arr - - -def getVendorNameEnum(vendorID): - try: - return vendors[vendorID] - except: - print("Unknown vendor: " + vendorID) - sys.exit(1) - - -def generateCArr(arr, filename): - with open(filename, "w") as out: - print('#include "spi_mem_chip_i.h"', file=out) - print("const SPIMemChip SPIMemChips[] = {", file=out) - for cur in arr: - print(" {" + cur["vendorID"] + ",", file=out, end="") - print(" 0x" + cur["typeID"] + ",", file=out, end="") - print(" 0x" + cur["capacityID"] + ",", file=out, end="") - print(' "' + cur["modelName"] + '",', file=out, end="") - print(" " + cur["size"] + ",", file=out, end="") - print(" " + cur["pageSize"] + ",", file=out, end="") - print(" " + cur["vendorEnum"] + ",", file=out, end="") - if cur == arr[-1]: - print(" " + cur["writeMode"] + "}};", file=out) - else: - print(" " + cur["writeMode"] + "},", file=out) - -def main(): - filename = "spi_mem_chip_arr.c" - args = getArgs() - xml = getXML(args.file) - vendors = getVendors(xml, "SPI") - chipArr = parseXML(xml, "SPI", vendors) - cleanEmptyVendors(vendors) - for cur in vendors: - print(' {"' + cur + '", SPIMemChipVendor' + cur + "},") - generateCArr(chipArr, filename) - - -if __name__ == "__main__": - main() diff --git a/applications/external/spi_mem_manager/views/spi_mem_view_detect.c b/applications/external/spi_mem_manager/views/spi_mem_view_detect.c deleted file mode 100644 index eddf36e49..000000000 --- a/applications/external/spi_mem_manager/views/spi_mem_view_detect.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "spi_mem_view_detect.h" -#include "spi_mem_manager_icons.h" -#include - -struct SPIMemDetectView { - View* view; - IconAnimation* icon; - SPIMemDetectViewCallback callback; - void* cb_ctx; -}; - -typedef struct { - IconAnimation* icon; -} SPIMemDetectViewModel; - -View* spi_mem_view_detect_get_view(SPIMemDetectView* app) { - return app->view; -} - -static void spi_mem_view_detect_draw_callback(Canvas* canvas, void* context) { - SPIMemDetectViewModel* model = context; - canvas_set_font(canvas, FontPrimary); - canvas_draw_icon_animation(canvas, 0, 0, model->icon); - canvas_draw_str_aligned(canvas, 64, 26, AlignLeft, AlignCenter, "Detecting"); - canvas_draw_str_aligned(canvas, 64, 36, AlignLeft, AlignCenter, "SPI chip..."); -} - -static void spi_mem_view_detect_enter_callback(void* context) { - SPIMemDetectView* app = context; - with_view_model( - app->view, SPIMemDetectViewModel * model, { icon_animation_start(model->icon); }, false); -} - -static void spi_mem_view_detect_exit_callback(void* context) { - SPIMemDetectView* app = context; - with_view_model( - app->view, SPIMemDetectViewModel * model, { icon_animation_stop(model->icon); }, false); -} - -SPIMemDetectView* spi_mem_view_detect_alloc() { - SPIMemDetectView* app = malloc(sizeof(SPIMemDetectView)); - app->view = view_alloc(); - view_set_context(app->view, app); - view_allocate_model(app->view, ViewModelTypeLocking, sizeof(SPIMemDetectViewModel)); - with_view_model( - app->view, - SPIMemDetectViewModel * model, - { - model->icon = icon_animation_alloc(&A_ChipLooking_64x64); - view_tie_icon_animation(app->view, model->icon); - }, - false); - view_set_draw_callback(app->view, spi_mem_view_detect_draw_callback); - view_set_enter_callback(app->view, spi_mem_view_detect_enter_callback); - view_set_exit_callback(app->view, spi_mem_view_detect_exit_callback); - return app; -} - -void spi_mem_view_detect_free(SPIMemDetectView* app) { - with_view_model( - app->view, SPIMemDetectViewModel * model, { icon_animation_free(model->icon); }, false); - view_free(app->view); - free(app); -} diff --git a/applications/external/spi_mem_manager/views/spi_mem_view_detect.h b/applications/external/spi_mem_manager/views/spi_mem_view_detect.h deleted file mode 100644 index f95edb60d..000000000 --- a/applications/external/spi_mem_manager/views/spi_mem_view_detect.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include - -typedef struct SPIMemDetectView SPIMemDetectView; -typedef void (*SPIMemDetectViewCallback)(void* context); - -View* spi_mem_view_detect_get_view(SPIMemDetectView* app); -SPIMemDetectView* spi_mem_view_detect_alloc(); -void spi_mem_view_detect_free(SPIMemDetectView* app); diff --git a/applications/external/spi_mem_manager/views/spi_mem_view_progress.c b/applications/external/spi_mem_manager/views/spi_mem_view_progress.c deleted file mode 100644 index 790f97997..000000000 --- a/applications/external/spi_mem_manager/views/spi_mem_view_progress.c +++ /dev/null @@ -1,230 +0,0 @@ -#include "spi_mem_view_progress.h" -#include - -struct SPIMemProgressView { - View* view; - SPIMemProgressViewCallback callback; - void* cb_ctx; -}; - -typedef enum { - SPIMemProgressViewTypeRead, - SPIMemProgressViewTypeVerify, - SPIMemProgressViewTypeWrite, - SPIMemProgressViewTypeUnknown -} SPIMemProgressViewType; - -typedef struct { - size_t chip_size; - size_t file_size; - size_t blocks_written; - size_t block_size; - float progress; - SPIMemProgressViewType view_type; -} SPIMemProgressViewModel; - -View* spi_mem_view_progress_get_view(SPIMemProgressView* app) { - return app->view; -} - -static void spi_mem_view_progress_draw_progress(Canvas* canvas, float progress) { - FuriString* progress_str = furi_string_alloc(); - if(progress > 1.0) progress = 1.0; - furi_string_printf(progress_str, "%d %%", (int)(progress * 100)); - elements_progress_bar(canvas, 13, 35, 100, progress); - canvas_draw_str_aligned( - canvas, 64, 25, AlignCenter, AlignTop, furi_string_get_cstr(progress_str)); - furi_string_free(progress_str); -} - -static void - spi_mem_view_progress_read_draw_callback(Canvas* canvas, SPIMemProgressViewModel* model) { - canvas_draw_str_aligned(canvas, 64, 4, AlignCenter, AlignTop, "Reading dump"); - spi_mem_view_progress_draw_progress(canvas, model->progress); - elements_button_left(canvas, "Cancel"); -} - -static void - spi_mem_view_progress_draw_size_warning(Canvas* canvas, SPIMemProgressViewModel* model) { - if(model->file_size > model->chip_size) { - canvas_draw_str_aligned(canvas, 64, 13, AlignCenter, AlignTop, "Size clamped to chip!"); - } - if(model->chip_size > model->file_size) { - canvas_draw_str_aligned(canvas, 64, 13, AlignCenter, AlignTop, "Size clamped to file!"); - } -} - -static void - spi_mem_view_progress_verify_draw_callback(Canvas* canvas, SPIMemProgressViewModel* model) { - canvas_draw_str_aligned(canvas, 64, 2, AlignCenter, AlignTop, "Verifying dump"); - spi_mem_view_progress_draw_size_warning(canvas, model); - spi_mem_view_progress_draw_progress(canvas, model->progress); - elements_button_center(canvas, "Skip"); -} - -static void - spi_mem_view_progress_write_draw_callback(Canvas* canvas, SPIMemProgressViewModel* model) { - canvas_draw_str_aligned(canvas, 64, 4, AlignCenter, AlignTop, "Writing dump"); - spi_mem_view_progress_draw_size_warning(canvas, model); - spi_mem_view_progress_draw_progress(canvas, model->progress); - elements_button_left(canvas, "Cancel"); -} - -static void spi_mem_view_progress_draw_callback(Canvas* canvas, void* context) { - SPIMemProgressViewModel* model = context; - SPIMemProgressViewType view_type = model->view_type; - if(view_type == SPIMemProgressViewTypeRead) { - spi_mem_view_progress_read_draw_callback(canvas, model); - } else if(view_type == SPIMemProgressViewTypeVerify) { - spi_mem_view_progress_verify_draw_callback(canvas, model); - } else if(view_type == SPIMemProgressViewTypeWrite) { - spi_mem_view_progress_write_draw_callback(canvas, model); - } -} - -static bool - spi_mem_view_progress_read_write_input_callback(InputEvent* event, SPIMemProgressView* app) { - bool success = false; - if(event->type == InputTypeShort && event->key == InputKeyLeft) { - if(app->callback) { - app->callback(app->cb_ctx); - } - success = true; - } - return success; -} - -static bool - spi_mem_view_progress_verify_input_callback(InputEvent* event, SPIMemProgressView* app) { - bool success = false; - if(event->type == InputTypeShort && event->key == InputKeyOk) { - if(app->callback) { - app->callback(app->cb_ctx); - } - success = true; - } - return success; -} - -static bool spi_mem_view_progress_input_callback(InputEvent* event, void* context) { - SPIMemProgressView* app = context; - bool success = false; - SPIMemProgressViewType view_type; - with_view_model( - app->view, SPIMemProgressViewModel * model, { view_type = model->view_type; }, true); - if(view_type == SPIMemProgressViewTypeRead) { - success = spi_mem_view_progress_read_write_input_callback(event, app); - } else if(view_type == SPIMemProgressViewTypeVerify) { - success = spi_mem_view_progress_verify_input_callback(event, app); - } else if(view_type == SPIMemProgressViewTypeWrite) { - success = spi_mem_view_progress_read_write_input_callback(event, app); - } - return success; -} - -SPIMemProgressView* spi_mem_view_progress_alloc() { - SPIMemProgressView* app = malloc(sizeof(SPIMemProgressView)); - app->view = view_alloc(); - view_allocate_model(app->view, ViewModelTypeLocking, sizeof(SPIMemProgressViewModel)); - view_set_context(app->view, app); - view_set_draw_callback(app->view, spi_mem_view_progress_draw_callback); - view_set_input_callback(app->view, spi_mem_view_progress_input_callback); - spi_mem_view_progress_reset(app); - return app; -} - -void spi_mem_view_progress_free(SPIMemProgressView* app) { - view_free(app->view); - free(app); -} - -void spi_mem_view_progress_set_read_callback( - SPIMemProgressView* app, - SPIMemProgressViewCallback callback, - void* cb_ctx) { - app->callback = callback; - app->cb_ctx = cb_ctx; - with_view_model( - app->view, - SPIMemProgressViewModel * model, - { model->view_type = SPIMemProgressViewTypeRead; }, - true); -} - -void spi_mem_view_progress_set_verify_callback( - SPIMemProgressView* app, - SPIMemProgressViewCallback callback, - void* cb_ctx) { - app->callback = callback; - app->cb_ctx = cb_ctx; - with_view_model( - app->view, - SPIMemProgressViewModel * model, - { model->view_type = SPIMemProgressViewTypeVerify; }, - true); -} - -void spi_mem_view_progress_set_write_callback( - SPIMemProgressView* app, - SPIMemProgressViewCallback callback, - void* cb_ctx) { - app->callback = callback; - app->cb_ctx = cb_ctx; - with_view_model( - app->view, - SPIMemProgressViewModel * model, - { model->view_type = SPIMemProgressViewTypeWrite; }, - true); -} - -void spi_mem_view_progress_set_chip_size(SPIMemProgressView* app, size_t chip_size) { - with_view_model( - app->view, SPIMemProgressViewModel * model, { model->chip_size = chip_size; }, true); -} - -void spi_mem_view_progress_set_file_size(SPIMemProgressView* app, size_t file_size) { - with_view_model( - app->view, SPIMemProgressViewModel * model, { model->file_size = file_size; }, true); -} - -void spi_mem_view_progress_set_block_size(SPIMemProgressView* app, size_t block_size) { - with_view_model( - app->view, SPIMemProgressViewModel * model, { model->block_size = block_size; }, true); -} - -static size_t spi_mem_view_progress_set_total_size(SPIMemProgressViewModel* model) { - size_t total_size = model->chip_size; - if((model->chip_size > model->file_size) && model->view_type != SPIMemProgressViewTypeRead) { - total_size = model->file_size; - } - return total_size; -} - -void spi_mem_view_progress_inc_progress(SPIMemProgressView* app) { - with_view_model( - app->view, - SPIMemProgressViewModel * model, - { - size_t total_size = spi_mem_view_progress_set_total_size(model); - if(total_size == 0) total_size = 1; - model->blocks_written++; - model->progress = - ((float)model->block_size * (float)model->blocks_written) / ((float)total_size); - }, - true); -} - -void spi_mem_view_progress_reset(SPIMemProgressView* app) { - with_view_model( - app->view, - SPIMemProgressViewModel * model, - { - model->blocks_written = 0; - model->block_size = 0; - model->chip_size = 0; - model->file_size = 0; - model->progress = 0; - model->view_type = SPIMemProgressViewTypeUnknown; - }, - true); -} diff --git a/applications/external/spi_mem_manager/views/spi_mem_view_progress.h b/applications/external/spi_mem_manager/views/spi_mem_view_progress.h deleted file mode 100644 index 6a8645b6c..000000000 --- a/applications/external/spi_mem_manager/views/spi_mem_view_progress.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once -#include - -typedef struct SPIMemProgressView SPIMemProgressView; -typedef void (*SPIMemProgressViewCallback)(void* context); - -View* spi_mem_view_progress_get_view(SPIMemProgressView* app); -SPIMemProgressView* spi_mem_view_progress_alloc(); -void spi_mem_view_progress_free(SPIMemProgressView* app); -void spi_mem_view_progress_set_read_callback( - SPIMemProgressView* app, - SPIMemProgressViewCallback callback, - void* cb_ctx); -void spi_mem_view_progress_set_verify_callback( - SPIMemProgressView* app, - SPIMemProgressViewCallback callback, - void* cb_ctx); -void spi_mem_view_progress_set_write_callback( - SPIMemProgressView* app, - SPIMemProgressViewCallback callback, - void* cb_ctx); -void spi_mem_view_progress_set_chip_size(SPIMemProgressView* app, size_t chip_size); -void spi_mem_view_progress_set_file_size(SPIMemProgressView* app, size_t file_size); -void spi_mem_view_progress_set_block_size(SPIMemProgressView* app, size_t block_size); -void spi_mem_view_progress_inc_progress(SPIMemProgressView* app); -void spi_mem_view_progress_reset(SPIMemProgressView* app); diff --git a/applications/external/weather_station/application.fam b/applications/external/weather_station/application.fam deleted file mode 100644 index 8dcaa1259..000000000 --- a/applications/external/weather_station/application.fam +++ /dev/null @@ -1,13 +0,0 @@ -App( - appid="weather_station", - name="Weather Station", - apptype=FlipperAppType.EXTERNAL, - targets=["f7"], - entry_point="weather_station_app", - requires=["gui"], - stack_size=4 * 1024, - order=50, - fap_icon="weather_station_10px.png", - fap_category="Sub-GHz", - fap_icon_assets="images", -) diff --git a/applications/external/weather_station/helpers/weather_station_event.h b/applications/external/weather_station/helpers/weather_station_event.h deleted file mode 100644 index b0486183d..000000000 --- a/applications/external/weather_station/helpers/weather_station_event.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -typedef enum { - //WSCustomEvent - WSCustomEventStartId = 100, - - WSCustomEventSceneSettingLock, - - WSCustomEventViewReceiverOK, - WSCustomEventViewReceiverConfig, - WSCustomEventViewReceiverBack, - WSCustomEventViewReceiverOffDisplay, - WSCustomEventViewReceiverUnlock, -} WSCustomEvent; diff --git a/applications/external/weather_station/helpers/weather_station_types.h b/applications/external/weather_station/helpers/weather_station_types.h deleted file mode 100644 index 111465978..000000000 --- a/applications/external/weather_station/helpers/weather_station_types.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include -#include - -#define WS_VERSION_APP "0.8" -#define WS_DEVELOPED "SkorP" -#define WS_GITHUB "https://github.com/flipperdevices/flipperzero-firmware" - -#define WS_KEY_FILE_VERSION 1 -#define WS_KEY_FILE_TYPE "Flipper Weather Station Key File" - -/** WSRxKeyState state */ -typedef enum { - WSRxKeyStateIDLE, - WSRxKeyStateBack, - WSRxKeyStateStart, - WSRxKeyStateAddKey, -} WSRxKeyState; - -/** WSHopperState state */ -typedef enum { - WSHopperStateOFF, - WSHopperStateRunnig, - WSHopperStatePause, - WSHopperStateRSSITimeOut, -} WSHopperState; - -/** WSLock */ -typedef enum { - WSLockOff, - WSLockOn, -} WSLock; - -typedef enum { - WeatherStationViewVariableItemList, - WeatherStationViewSubmenu, - WeatherStationViewReceiver, - WeatherStationViewReceiverInfo, - WeatherStationViewWidget, -} WeatherStationView; - -/** WeatherStationTxRx state */ -typedef enum { - WSTxRxStateIDLE, - WSTxRxStateRx, - WSTxRxStateTx, - WSTxRxStateSleep, -} WSTxRxState; diff --git a/applications/external/weather_station/images/Humid_10x15.png b/applications/external/weather_station/images/Humid_10x15.png deleted file mode 100644 index 34b074e5f..000000000 Binary files a/applications/external/weather_station/images/Humid_10x15.png and /dev/null differ diff --git a/applications/external/weather_station/images/Humid_8x13.png b/applications/external/weather_station/images/Humid_8x13.png deleted file mode 100644 index 6d8c71b00..000000000 Binary files a/applications/external/weather_station/images/Humid_8x13.png and /dev/null differ diff --git a/applications/external/weather_station/images/Lock_7x8.png b/applications/external/weather_station/images/Lock_7x8.png deleted file mode 100644 index f7c9ca2c7..000000000 Binary files a/applications/external/weather_station/images/Lock_7x8.png and /dev/null differ diff --git a/applications/external/weather_station/images/Pin_back_arrow_10x8.png b/applications/external/weather_station/images/Pin_back_arrow_10x8.png deleted file mode 100644 index 3bafabd14..000000000 Binary files a/applications/external/weather_station/images/Pin_back_arrow_10x8.png and /dev/null differ diff --git a/applications/external/weather_station/images/Quest_7x8.png b/applications/external/weather_station/images/Quest_7x8.png deleted file mode 100644 index 6825247fb..000000000 Binary files a/applications/external/weather_station/images/Quest_7x8.png and /dev/null differ diff --git a/applications/external/weather_station/images/Scanning_123x52.png b/applications/external/weather_station/images/Scanning_123x52.png deleted file mode 100644 index ec785948d..000000000 Binary files a/applications/external/weather_station/images/Scanning_123x52.png and /dev/null differ diff --git a/applications/external/weather_station/images/Therm_7x16.png b/applications/external/weather_station/images/Therm_7x16.png deleted file mode 100644 index 7c55500b7..000000000 Binary files a/applications/external/weather_station/images/Therm_7x16.png and /dev/null differ diff --git a/applications/external/weather_station/images/Timer_11x11.png b/applications/external/weather_station/images/Timer_11x11.png deleted file mode 100644 index 21ad47f4b..000000000 Binary files a/applications/external/weather_station/images/Timer_11x11.png and /dev/null differ diff --git a/applications/external/weather_station/images/Unlock_7x8.png b/applications/external/weather_station/images/Unlock_7x8.png deleted file mode 100644 index 9d82b4daf..000000000 Binary files a/applications/external/weather_station/images/Unlock_7x8.png and /dev/null differ diff --git a/applications/external/weather_station/images/WarningDolphin_45x42.png b/applications/external/weather_station/images/WarningDolphin_45x42.png deleted file mode 100644 index d766ffbb4..000000000 Binary files a/applications/external/weather_station/images/WarningDolphin_45x42.png and /dev/null differ diff --git a/applications/external/weather_station/images/station_icon.png b/applications/external/weather_station/images/station_icon.png deleted file mode 100644 index b839eeb7a..000000000 Binary files a/applications/external/weather_station/images/station_icon.png and /dev/null differ diff --git a/applications/external/weather_station/protocols/acurite_592txr.c b/applications/external/weather_station/protocols/acurite_592txr.c deleted file mode 100644 index 874f6dd33..000000000 --- a/applications/external/weather_station/protocols/acurite_592txr.c +++ /dev/null @@ -1,298 +0,0 @@ -#include "acurite_592txr.h" - -#define TAG "WSProtocolAcurite_592TXR" - -/* - * Help - * https://github.com/merbanan/rtl_433/blob/master/src/devices/acurite.c - * - * Acurite 592TXR Temperature Humidity sensor decoder - * Message Type 0x04, 7 bytes - * | Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | - * | --------- | --------- | --------- | --------- | --------- | --------- | --------- | - * | CCII IIII | IIII IIII | pB00 0100 | pHHH HHHH | p??T TTTT | pTTT TTTT | KKKK KKKK | - * - C: Channel 00: C, 10: B, 11: A, (01 is invalid) - * - I: Device ID (14 bits) - * - B: Battery, 1 is battery OK, 0 is battery low - * - M: Message type (6 bits), 0x04 - * - T: Temperature Celsius (11 - 14 bits?), + 1000 * 10 - * - H: Relative Humidity (%) (7 bits) - * - K: Checksum (8 bits) - * - p: Parity bit - * Notes: - * - Temperature - * - Encoded as Celsius + 1000 * 10 - * - only 11 bits needed for specified range -40 C to 70 C (-40 F - 158 F) - * - However 14 bits available for temperature, giving possible range of -100 C to 1538.4 C - * - @todo - check if high 3 bits ever used for anything else - * - */ - -static const SubGhzBlockConst ws_protocol_acurite_592txr_const = { - .te_short = 200, - .te_long = 400, - .te_delta = 90, - .min_count_bit_for_found = 56, -}; - -struct WSProtocolDecoderAcurite_592TXR { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; - - uint16_t header_count; -}; - -struct WSProtocolEncoderAcurite_592TXR { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - WSBlockGeneric generic; -}; - -typedef enum { - Acurite_592TXRDecoderStepReset = 0, - Acurite_592TXRDecoderStepCheckPreambule, - Acurite_592TXRDecoderStepSaveDuration, - Acurite_592TXRDecoderStepCheckDuration, -} Acurite_592TXRDecoderStep; - -const SubGhzProtocolDecoder ws_protocol_acurite_592txr_decoder = { - .alloc = ws_protocol_decoder_acurite_592txr_alloc, - .free = ws_protocol_decoder_acurite_592txr_free, - - .feed = ws_protocol_decoder_acurite_592txr_feed, - .reset = ws_protocol_decoder_acurite_592txr_reset, - - .get_hash_data = ws_protocol_decoder_acurite_592txr_get_hash_data, - .serialize = ws_protocol_decoder_acurite_592txr_serialize, - .deserialize = ws_protocol_decoder_acurite_592txr_deserialize, - .get_string = ws_protocol_decoder_acurite_592txr_get_string, -}; - -const SubGhzProtocolEncoder ws_protocol_acurite_592txr_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol ws_protocol_acurite_592txr = { - .name = WS_PROTOCOL_ACURITE_592TXR_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_acurite_592txr_decoder, - .encoder = &ws_protocol_acurite_592txr_encoder, -}; - -void* ws_protocol_decoder_acurite_592txr_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderAcurite_592TXR* instance = malloc(sizeof(WSProtocolDecoderAcurite_592TXR)); - instance->base.protocol = &ws_protocol_acurite_592txr; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void ws_protocol_decoder_acurite_592txr_free(void* context) { - furi_assert(context); - WSProtocolDecoderAcurite_592TXR* instance = context; - free(instance); -} - -void ws_protocol_decoder_acurite_592txr_reset(void* context) { - furi_assert(context); - WSProtocolDecoderAcurite_592TXR* instance = context; - instance->decoder.parser_step = Acurite_592TXRDecoderStepReset; -} - -static bool ws_protocol_acurite_592txr_check_crc(WSProtocolDecoderAcurite_592TXR* instance) { - uint8_t msg[] = { - instance->decoder.decode_data >> 48, - instance->decoder.decode_data >> 40, - instance->decoder.decode_data >> 32, - instance->decoder.decode_data >> 24, - instance->decoder.decode_data >> 16, - instance->decoder.decode_data >> 8}; - - if((subghz_protocol_blocks_add_bytes(msg, 6) == - (uint8_t)(instance->decoder.decode_data & 0xFF)) && - (!subghz_protocol_blocks_parity_bytes(&msg[2], 4))) { - return true; - } else { - return false; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static void ws_protocol_acurite_592txr_remote_controller(WSBlockGeneric* instance) { - uint8_t channel[] = {3, 0, 2, 1}; - uint8_t channel_raw = ((instance->data >> 54) & 0x03); - instance->channel = channel[channel_raw]; - instance->id = (instance->data >> 40) & 0x3FFF; - instance->battery_low = !((instance->data >> 38) & 1); - instance->humidity = (instance->data >> 24) & 0x7F; - - uint16_t temp_raw = ((instance->data >> 9) & 0xF80) | ((instance->data >> 8) & 0x7F); - instance->temp = ((float)(temp_raw)-1000) / 10.0f; - - instance->btn = WS_NO_BTN; -} - -void ws_protocol_decoder_acurite_592txr_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderAcurite_592TXR* instance = context; - - switch(instance->decoder.parser_step) { - case Acurite_592TXRDecoderStepReset: - if((level) && (DURATION_DIFF(duration, ws_protocol_acurite_592txr_const.te_short * 3) < - ws_protocol_acurite_592txr_const.te_delta * 2)) { - instance->decoder.parser_step = Acurite_592TXRDecoderStepCheckPreambule; - instance->decoder.te_last = duration; - instance->header_count = 0; - } - break; - - case Acurite_592TXRDecoderStepCheckPreambule: - if(level) { - instance->decoder.te_last = duration; - } else { - if((DURATION_DIFF( - instance->decoder.te_last, ws_protocol_acurite_592txr_const.te_short * 3) < - ws_protocol_acurite_592txr_const.te_delta * 2) && - (DURATION_DIFF(duration, ws_protocol_acurite_592txr_const.te_short * 3) < - ws_protocol_acurite_592txr_const.te_delta * 2)) { - //Found preambule - instance->header_count++; - } else if((instance->header_count > 2) && (instance->header_count < 5)) { - if((DURATION_DIFF( - instance->decoder.te_last, ws_protocol_acurite_592txr_const.te_short) < - ws_protocol_acurite_592txr_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_acurite_592txr_const.te_long) < - ws_protocol_acurite_592txr_const.te_delta)) { - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = Acurite_592TXRDecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, ws_protocol_acurite_592txr_const.te_long) < - ws_protocol_acurite_592txr_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_acurite_592txr_const.te_short) < - ws_protocol_acurite_592txr_const.te_delta)) { - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = Acurite_592TXRDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = Acurite_592TXRDecoderStepReset; - } - } else { - instance->decoder.parser_step = Acurite_592TXRDecoderStepReset; - } - } - break; - - case Acurite_592TXRDecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = Acurite_592TXRDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = Acurite_592TXRDecoderStepReset; - } - break; - - case Acurite_592TXRDecoderStepCheckDuration: - if(!level) { - if(duration >= ((uint32_t)ws_protocol_acurite_592txr_const.te_short * 5)) { - if((instance->decoder.decode_count_bit == - ws_protocol_acurite_592txr_const.min_count_bit_for_found) && - ws_protocol_acurite_592txr_check_crc(instance)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - ws_protocol_acurite_592txr_remote_controller(&instance->generic); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->decoder.parser_step = Acurite_592TXRDecoderStepReset; - break; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, ws_protocol_acurite_592txr_const.te_short) < - ws_protocol_acurite_592txr_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_acurite_592txr_const.te_long) < - ws_protocol_acurite_592txr_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = Acurite_592TXRDecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, ws_protocol_acurite_592txr_const.te_long) < - ws_protocol_acurite_592txr_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_acurite_592txr_const.te_short) < - ws_protocol_acurite_592txr_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = Acurite_592TXRDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = Acurite_592TXRDecoderStepReset; - } - } else { - instance->decoder.parser_step = Acurite_592TXRDecoderStepReset; - } - break; - } -} - -uint8_t ws_protocol_decoder_acurite_592txr_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderAcurite_592TXR* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_acurite_592txr_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderAcurite_592TXR* instance = context; - return ws_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus - ws_protocol_decoder_acurite_592txr_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderAcurite_592TXR* instance = context; - return ws_block_generic_deserialize_check_count_bit( - &instance->generic, - flipper_format, - ws_protocol_acurite_592txr_const.min_count_bit_for_found); -} - -void ws_protocol_decoder_acurite_592txr_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderAcurite_592TXR* instance = context; - furi_string_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%lX Ch:%d Bat:%d\r\n" - "Temp:%3.1f C Hum:%d%%", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data), - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (double)instance->generic.temp, - instance->generic.humidity); -} diff --git a/applications/external/weather_station/protocols/acurite_592txr.h b/applications/external/weather_station/protocols/acurite_592txr.h deleted file mode 100644 index 1071d1cf7..000000000 --- a/applications/external/weather_station/protocols/acurite_592txr.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "ws_generic.h" -#include - -#define WS_PROTOCOL_ACURITE_592TXR_NAME "Acurite 592TXR" - -typedef struct WSProtocolDecoderAcurite_592TXR WSProtocolDecoderAcurite_592TXR; -typedef struct WSProtocolEncoderAcurite_592TXR WSProtocolEncoderAcurite_592TXR; - -extern const SubGhzProtocolDecoder ws_protocol_acurite_592txr_decoder; -extern const SubGhzProtocolEncoder ws_protocol_acurite_592txr_encoder; -extern const SubGhzProtocol ws_protocol_acurite_592txr; - -/** - * Allocate WSProtocolDecoderAcurite_592TXR. - * @param environment Pointer to a SubGhzEnvironment instance - * @return WSProtocolDecoderAcurite_592TXR* pointer to a WSProtocolDecoderAcurite_592TXR instance - */ -void* ws_protocol_decoder_acurite_592txr_alloc(SubGhzEnvironment* environment); - -/** - * Free WSProtocolDecoderAcurite_592TXR. - * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance - */ -void ws_protocol_decoder_acurite_592txr_free(void* context); - -/** - * Reset decoder WSProtocolDecoderAcurite_592TXR. - * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance - */ -void ws_protocol_decoder_acurite_592txr_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void ws_protocol_decoder_acurite_592txr_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance - * @return hash Hash sum - */ -uint8_t ws_protocol_decoder_acurite_592txr_get_hash_data(void* context); - -/** - * Serialize data WSProtocolDecoderAcurite_592TXR. - * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_acurite_592txr_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSProtocolDecoderAcurite_592TXR. - * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus - ws_protocol_decoder_acurite_592txr_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance - * @param output Resulting text - */ -void ws_protocol_decoder_acurite_592txr_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/acurite_606tx.c b/applications/external/weather_station/protocols/acurite_606tx.c deleted file mode 100644 index e0d405c66..000000000 --- a/applications/external/weather_station/protocols/acurite_606tx.c +++ /dev/null @@ -1,239 +0,0 @@ -#include "acurite_606tx.h" - -#define TAG "WSProtocolAcurite_606TX" - -/* - * Help - * https://github.com/merbanan/rtl_433/blob/5bef4e43133ac4c0e2d18d36f87c52b4f9458453/src/devices/acurite.c#L1644 - * - * 0000 1111 | 0011 0000 | 0101 1100 | 1110 0111 - * iiii iiii | buuu tttt | tttt tttt | cccc cccc - * - i: identification; changes on battery switch - * - c: lfsr_digest8; - * - u: unknown; - * - b: battery low; flag to indicate low battery voltage - * - t: Temperature; in °C - * - */ - -static const SubGhzBlockConst ws_protocol_acurite_606tx_const = { - .te_short = 500, - .te_long = 2000, - .te_delta = 150, - .min_count_bit_for_found = 32, -}; - -struct WSProtocolDecoderAcurite_606TX { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; -}; - -struct WSProtocolEncoderAcurite_606TX { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - WSBlockGeneric generic; -}; - -typedef enum { - Acurite_606TXDecoderStepReset = 0, - Acurite_606TXDecoderStepSaveDuration, - Acurite_606TXDecoderStepCheckDuration, -} Acurite_606TXDecoderStep; - -const SubGhzProtocolDecoder ws_protocol_acurite_606tx_decoder = { - .alloc = ws_protocol_decoder_acurite_606tx_alloc, - .free = ws_protocol_decoder_acurite_606tx_free, - - .feed = ws_protocol_decoder_acurite_606tx_feed, - .reset = ws_protocol_decoder_acurite_606tx_reset, - - .get_hash_data = ws_protocol_decoder_acurite_606tx_get_hash_data, - .serialize = ws_protocol_decoder_acurite_606tx_serialize, - .deserialize = ws_protocol_decoder_acurite_606tx_deserialize, - .get_string = ws_protocol_decoder_acurite_606tx_get_string, -}; - -const SubGhzProtocolEncoder ws_protocol_acurite_606tx_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol ws_protocol_acurite_606tx = { - .name = WS_PROTOCOL_ACURITE_606TX_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_acurite_606tx_decoder, - .encoder = &ws_protocol_acurite_606tx_encoder, -}; - -void* ws_protocol_decoder_acurite_606tx_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderAcurite_606TX* instance = malloc(sizeof(WSProtocolDecoderAcurite_606TX)); - instance->base.protocol = &ws_protocol_acurite_606tx; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void ws_protocol_decoder_acurite_606tx_free(void* context) { - furi_assert(context); - WSProtocolDecoderAcurite_606TX* instance = context; - free(instance); -} - -void ws_protocol_decoder_acurite_606tx_reset(void* context) { - furi_assert(context); - WSProtocolDecoderAcurite_606TX* instance = context; - instance->decoder.parser_step = Acurite_606TXDecoderStepReset; -} - -static bool ws_protocol_acurite_606tx_check(WSProtocolDecoderAcurite_606TX* instance) { - if(!instance->decoder.decode_data) return false; - uint8_t msg[] = { - instance->decoder.decode_data >> 24, - instance->decoder.decode_data >> 16, - instance->decoder.decode_data >> 8}; - - uint8_t crc = subghz_protocol_blocks_lfsr_digest8(msg, 3, 0x98, 0xF1); - return (crc == (instance->decoder.decode_data & 0xFF)); -} - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static void ws_protocol_acurite_606tx_remote_controller(WSBlockGeneric* instance) { - instance->id = (instance->data >> 24) & 0xFF; - instance->battery_low = (instance->data >> 23) & 1; - - instance->channel = WS_NO_CHANNEL; - - if(!((instance->data >> 19) & 1)) { - instance->temp = (float)((instance->data >> 8) & 0x07FF) / 10.0f; - } else { - instance->temp = (float)((~(instance->data >> 8) & 0x07FF) + 1) / -10.0f; - } - instance->btn = WS_NO_BTN; - instance->humidity = WS_NO_HUMIDITY; -} - -void ws_protocol_decoder_acurite_606tx_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderAcurite_606TX* instance = context; - - switch(instance->decoder.parser_step) { - case Acurite_606TXDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, ws_protocol_acurite_606tx_const.te_short * 17) < - ws_protocol_acurite_606tx_const.te_delta * 8)) { - //Found syncPrefix - instance->decoder.parser_step = Acurite_606TXDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } - break; - - case Acurite_606TXDecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = Acurite_606TXDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = Acurite_606TXDecoderStepReset; - } - break; - - case Acurite_606TXDecoderStepCheckDuration: - if(!level) { - if(DURATION_DIFF(instance->decoder.te_last, ws_protocol_acurite_606tx_const.te_short) < - ws_protocol_acurite_606tx_const.te_delta) { - if((DURATION_DIFF(duration, ws_protocol_acurite_606tx_const.te_short) < - ws_protocol_acurite_606tx_const.te_delta) || - (duration > ws_protocol_acurite_606tx_const.te_long * 3)) { - //Found syncPostfix - instance->decoder.parser_step = Acurite_606TXDecoderStepReset; - if((instance->decoder.decode_count_bit == - ws_protocol_acurite_606tx_const.min_count_bit_for_found) && - ws_protocol_acurite_606tx_check(instance)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - ws_protocol_acurite_606tx_remote_controller(&instance->generic); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else if( - DURATION_DIFF(duration, ws_protocol_acurite_606tx_const.te_long) < - ws_protocol_acurite_606tx_const.te_delta * 2) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = Acurite_606TXDecoderStepSaveDuration; - } else if( - DURATION_DIFF(duration, ws_protocol_acurite_606tx_const.te_long * 2) < - ws_protocol_acurite_606tx_const.te_delta * 4) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = Acurite_606TXDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = Acurite_606TXDecoderStepReset; - } - } else { - instance->decoder.parser_step = Acurite_606TXDecoderStepReset; - } - } else { - instance->decoder.parser_step = Acurite_606TXDecoderStepReset; - } - break; - } -} - -uint8_t ws_protocol_decoder_acurite_606tx_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderAcurite_606TX* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_acurite_606tx_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderAcurite_606TX* instance = context; - return ws_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus - ws_protocol_decoder_acurite_606tx_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderAcurite_606TX* instance = context; - return ws_block_generic_deserialize_check_count_bit( - &instance->generic, - flipper_format, - ws_protocol_acurite_606tx_const.min_count_bit_for_found); -} - -void ws_protocol_decoder_acurite_606tx_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderAcurite_606TX* instance = context; - furi_string_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%lX Ch:%d Bat:%d\r\n" - "Temp:%3.1f C Hum:%d%%", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data), - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (double)instance->generic.temp, - instance->generic.humidity); -} diff --git a/applications/external/weather_station/protocols/acurite_606tx.h b/applications/external/weather_station/protocols/acurite_606tx.h deleted file mode 100644 index 15b6d1eb5..000000000 --- a/applications/external/weather_station/protocols/acurite_606tx.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "ws_generic.h" -#include - -#define WS_PROTOCOL_ACURITE_606TX_NAME "Acurite-606TX" - -typedef struct WSProtocolDecoderAcurite_606TX WSProtocolDecoderAcurite_606TX; -typedef struct WSProtocolEncoderAcurite_606TX WSProtocolEncoderAcurite_606TX; - -extern const SubGhzProtocolDecoder ws_protocol_acurite_606tx_decoder; -extern const SubGhzProtocolEncoder ws_protocol_acurite_606tx_encoder; -extern const SubGhzProtocol ws_protocol_acurite_606tx; - -/** - * Allocate WSProtocolDecoderAcurite_606TX. - * @param environment Pointer to a SubGhzEnvironment instance - * @return WSProtocolDecoderAcurite_606TX* pointer to a WSProtocolDecoderAcurite_606TX instance - */ -void* ws_protocol_decoder_acurite_606tx_alloc(SubGhzEnvironment* environment); - -/** - * Free WSProtocolDecoderAcurite_606TX. - * @param context Pointer to a WSProtocolDecoderAcurite_606TX instance - */ -void ws_protocol_decoder_acurite_606tx_free(void* context); - -/** - * Reset decoder WSProtocolDecoderAcurite_606TX. - * @param context Pointer to a WSProtocolDecoderAcurite_606TX instance - */ -void ws_protocol_decoder_acurite_606tx_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a WSProtocolDecoderAcurite_606TX instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void ws_protocol_decoder_acurite_606tx_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a WSProtocolDecoderAcurite_606TX instance - * @return hash Hash sum - */ -uint8_t ws_protocol_decoder_acurite_606tx_get_hash_data(void* context); - -/** - * Serialize data WSProtocolDecoderAcurite_606TX. - * @param context Pointer to a WSProtocolDecoderAcurite_606TX instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_acurite_606tx_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSProtocolDecoderAcurite_606TX. - * @param context Pointer to a WSProtocolDecoderAcurite_606TX instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus - ws_protocol_decoder_acurite_606tx_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a WSProtocolDecoderAcurite_606TX instance - * @param output Resulting text - */ -void ws_protocol_decoder_acurite_606tx_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/acurite_609txc.c b/applications/external/weather_station/protocols/acurite_609txc.c deleted file mode 100644 index 853b78446..000000000 --- a/applications/external/weather_station/protocols/acurite_609txc.c +++ /dev/null @@ -1,239 +0,0 @@ -#include "acurite_609txc.h" - -#define TAG "WSProtocolAcurite_609TXC" - -/* - * Help - * https://github.com/merbanan/rtl_433/blob/5bef4e43133ac4c0e2d18d36f87c52b4f9458453/src/devices/acurite.c#L216 - * - * 0000 1111 | 0011 0000 | 0101 1100 | 0000 0000 | 1110 0111 - * iiii iiii | buuu tttt | tttt tttt | hhhh hhhh | cccc cccc - * - i: identification; changes on battery switch - * - c: checksum (sum of previous by bytes) - * - u: unknown - * - b: battery low; flag to indicate low battery voltage - * - t: temperature; in °C * 10, 12 bit with complement - * - h: humidity - * - */ - -static const SubGhzBlockConst ws_protocol_acurite_609txc_const = { - .te_short = 500, - .te_long = 1000, - .te_delta = 150, - .min_count_bit_for_found = 40, -}; - -struct WSProtocolDecoderAcurite_609TXC { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; -}; - -struct WSProtocolEncoderAcurite_609TXC { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - WSBlockGeneric generic; -}; - -typedef enum { - Acurite_609TXCDecoderStepReset = 0, - Acurite_609TXCDecoderStepSaveDuration, - Acurite_609TXCDecoderStepCheckDuration, -} Acurite_609TXCDecoderStep; - -const SubGhzProtocolDecoder ws_protocol_acurite_609txc_decoder = { - .alloc = ws_protocol_decoder_acurite_609txc_alloc, - .free = ws_protocol_decoder_acurite_609txc_free, - - .feed = ws_protocol_decoder_acurite_609txc_feed, - .reset = ws_protocol_decoder_acurite_609txc_reset, - - .get_hash_data = ws_protocol_decoder_acurite_609txc_get_hash_data, - .serialize = ws_protocol_decoder_acurite_609txc_serialize, - .deserialize = ws_protocol_decoder_acurite_609txc_deserialize, - .get_string = ws_protocol_decoder_acurite_609txc_get_string, -}; - -const SubGhzProtocolEncoder ws_protocol_acurite_609txc_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol ws_protocol_acurite_609txc = { - .name = WS_PROTOCOL_ACURITE_609TXC_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_acurite_609txc_decoder, - .encoder = &ws_protocol_acurite_609txc_encoder, -}; - -void* ws_protocol_decoder_acurite_609txc_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderAcurite_609TXC* instance = malloc(sizeof(WSProtocolDecoderAcurite_609TXC)); - instance->base.protocol = &ws_protocol_acurite_609txc; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void ws_protocol_decoder_acurite_609txc_free(void* context) { - furi_assert(context); - WSProtocolDecoderAcurite_609TXC* instance = context; - free(instance); -} - -void ws_protocol_decoder_acurite_609txc_reset(void* context) { - furi_assert(context); - WSProtocolDecoderAcurite_609TXC* instance = context; - instance->decoder.parser_step = Acurite_609TXCDecoderStepReset; -} - -static bool ws_protocol_acurite_609txc_check(WSProtocolDecoderAcurite_609TXC* instance) { - if(!instance->decoder.decode_data) return false; - uint8_t crc = (uint8_t)(instance->decoder.decode_data >> 32) + - (uint8_t)(instance->decoder.decode_data >> 24) + - (uint8_t)(instance->decoder.decode_data >> 16) + - (uint8_t)(instance->decoder.decode_data >> 8); - return (crc == (instance->decoder.decode_data & 0xFF)); -} - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static void ws_protocol_acurite_609txc_remote_controller(WSBlockGeneric* instance) { - instance->id = (instance->data >> 32) & 0xFF; - instance->battery_low = (instance->data >> 31) & 1; - - instance->channel = WS_NO_CHANNEL; - - // Temperature in Celsius is encoded as a 12 bit integer value - // multiplied by 10 using the 4th - 6th nybbles (bytes 1 & 2) - // negative values are recovered by sign extend from int16_t. - int16_t temp_raw = - (int16_t)(((instance->data >> 12) & 0xf000) | ((instance->data >> 16) << 4)); - instance->temp = (temp_raw >> 4) * 0.1f; - instance->humidity = (instance->data >> 8) & 0xff; - instance->btn = WS_NO_BTN; -} - -void ws_protocol_decoder_acurite_609txc_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderAcurite_609TXC* instance = context; - - switch(instance->decoder.parser_step) { - case Acurite_609TXCDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, ws_protocol_acurite_609txc_const.te_short * 17) < - ws_protocol_acurite_609txc_const.te_delta * 8)) { - //Found syncPrefix - instance->decoder.parser_step = Acurite_609TXCDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } - break; - - case Acurite_609TXCDecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = Acurite_609TXCDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = Acurite_609TXCDecoderStepReset; - } - break; - - case Acurite_609TXCDecoderStepCheckDuration: - if(!level) { - if(DURATION_DIFF(instance->decoder.te_last, ws_protocol_acurite_609txc_const.te_short) < - ws_protocol_acurite_609txc_const.te_delta) { - if((DURATION_DIFF(duration, ws_protocol_acurite_609txc_const.te_short) < - ws_protocol_acurite_609txc_const.te_delta) || - (duration > ws_protocol_acurite_609txc_const.te_long * 3)) { - //Found syncPostfix - instance->decoder.parser_step = Acurite_609TXCDecoderStepReset; - if((instance->decoder.decode_count_bit == - ws_protocol_acurite_609txc_const.min_count_bit_for_found) && - ws_protocol_acurite_609txc_check(instance)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - ws_protocol_acurite_609txc_remote_controller(&instance->generic); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else if( - DURATION_DIFF(duration, ws_protocol_acurite_609txc_const.te_long) < - ws_protocol_acurite_609txc_const.te_delta * 2) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = Acurite_609TXCDecoderStepSaveDuration; - } else if( - DURATION_DIFF(duration, ws_protocol_acurite_609txc_const.te_long * 2) < - ws_protocol_acurite_609txc_const.te_delta * 4) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = Acurite_609TXCDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = Acurite_609TXCDecoderStepReset; - } - } else { - instance->decoder.parser_step = Acurite_609TXCDecoderStepReset; - } - } else { - instance->decoder.parser_step = Acurite_609TXCDecoderStepReset; - } - break; - } -} - -uint8_t ws_protocol_decoder_acurite_609txc_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderAcurite_609TXC* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_acurite_609txc_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderAcurite_609TXC* instance = context; - return ws_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus - ws_protocol_decoder_acurite_609txc_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderAcurite_609TXC* instance = context; - return ws_block_generic_deserialize_check_count_bit( - &instance->generic, - flipper_format, - ws_protocol_acurite_609txc_const.min_count_bit_for_found); -} - -void ws_protocol_decoder_acurite_609txc_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderAcurite_609TXC* instance = context; - furi_string_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%lX Ch:%d Bat:%d\r\n" - "Temp:%3.1f C Hum:%d%%", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 40), - (uint32_t)(instance->generic.data), - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (double)instance->generic.temp, - instance->generic.humidity); -} diff --git a/applications/external/weather_station/protocols/acurite_609txc.h b/applications/external/weather_station/protocols/acurite_609txc.h deleted file mode 100644 index 3e3b9cee8..000000000 --- a/applications/external/weather_station/protocols/acurite_609txc.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "ws_generic.h" -#include - -#define WS_PROTOCOL_ACURITE_609TXC_NAME "Acurite-609TXC" - -typedef struct WSProtocolDecoderAcurite_609TXC WSProtocolDecoderAcurite_609TXC; -typedef struct WSProtocolEncoderAcurite_609TXC WSProtocolEncoderAcurite_609TXC; - -extern const SubGhzProtocolDecoder ws_protocol_acurite_609txc_decoder; -extern const SubGhzProtocolEncoder ws_protocol_acurite_609txc_encoder; -extern const SubGhzProtocol ws_protocol_acurite_609txc; - -/** - * Allocate WSProtocolDecoderAcurite_609TXC. - * @param environment Pointer to a SubGhzEnvironment instance - * @return WSProtocolDecoderAcurite_609TXC* pointer to a WSProtocolDecoderAcurite_609TXC instance - */ -void* ws_protocol_decoder_acurite_609txc_alloc(SubGhzEnvironment* environment); - -/** - * Free WSProtocolDecoderAcurite_609TXC. - * @param context Pointer to a WSProtocolDecoderAcurite_609TXC instance - */ -void ws_protocol_decoder_acurite_609txc_free(void* context); - -/** - * Reset decoder WSProtocolDecoderAcurite_609TXC. - * @param context Pointer to a WSProtocolDecoderAcurite_609TXC instance - */ -void ws_protocol_decoder_acurite_609txc_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a WSProtocolDecoderAcurite_609TXC instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void ws_protocol_decoder_acurite_609txc_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a WSProtocolDecoderAcurite_609TXC instance - * @return hash Hash sum - */ -uint8_t ws_protocol_decoder_acurite_609txc_get_hash_data(void* context); - -/** - * Serialize data WSProtocolDecoderAcurite_609TXC. - * @param context Pointer to a WSProtocolDecoderAcurite_609TXC instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_acurite_609txc_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSProtocolDecoderAcurite_609TXC. - * @param context Pointer to a WSProtocolDecoderAcurite_609TXC instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus - ws_protocol_decoder_acurite_609txc_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a WSProtocolDecoderAcurite_609TXC instance - * @param output Resulting text - */ -void ws_protocol_decoder_acurite_609txc_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/ambient_weather.c b/applications/external/weather_station/protocols/ambient_weather.c deleted file mode 100644 index 588a7f82a..000000000 --- a/applications/external/weather_station/protocols/ambient_weather.c +++ /dev/null @@ -1,268 +0,0 @@ -#include "ambient_weather.h" -#include - -#define TAG "WSProtocolAmbient_Weather" - -/* - * Help - * https://github.com/merbanan/rtl_433/blob/master/src/devices/ambient_weather.c - * - * Decode Ambient Weather F007TH, F012TH, TF 30.3208.02, SwitchDoc F016TH. - * Devices supported: - * - Ambient Weather F007TH Thermo-Hygrometer. - * - Ambient Weather F012TH Indoor/Display Thermo-Hygrometer. - * - TFA senders 30.3208.02 from the TFA "Klima-Monitor" 30.3054, - * - SwitchDoc Labs F016TH. - * This decoder handles the 433mhz/868mhz thermo-hygrometers. - * The 915mhz (WH*) family of devices use different modulation/encoding. - * Byte 0 Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 - * xxxxMMMM IIIIIIII BCCCTTTT TTTTTTTT HHHHHHHH MMMMMMMM - * - x: Unknown 0x04 on F007TH/F012TH - * - M: Model Number?, 0x05 on F007TH/F012TH/SwitchDocLabs F016TH - * - I: ID byte (8 bits), volatie, changes at power up, - * - B: Battery Low - * - C: Channel (3 bits 1-8) - F007TH set by Dip switch, F012TH soft setting - * - T: Temperature 12 bits - Fahrenheit * 10 + 400 - * - H: Humidity (8 bits) - * - M: Message integrity check LFSR Digest-8, gen 0x98, key 0x3e, init 0x64 - * - * three repeats without gap - * full preamble is 0x00145 (the last bits might not be fixed, e.g. 0x00146) - * and on decoding also 0xffd45 - */ - -#define AMBIENT_WEATHER_PACKET_HEADER_1 0xFFD440000000000 //0xffd45 .. 0xffd46 -#define AMBIENT_WEATHER_PACKET_HEADER_2 0x001440000000000 //0x00145 .. 0x00146 -#define AMBIENT_WEATHER_PACKET_HEADER_MASK 0xFFFFC0000000000 - -static const SubGhzBlockConst ws_protocol_ambient_weather_const = { - .te_short = 500, - .te_long = 1000, - .te_delta = 120, - .min_count_bit_for_found = 48, -}; - -struct WSProtocolDecoderAmbient_Weather { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; - ManchesterState manchester_saved_state; - uint16_t header_count; -}; - -struct WSProtocolEncoderAmbient_Weather { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - WSBlockGeneric generic; -}; - -const SubGhzProtocolDecoder ws_protocol_ambient_weather_decoder = { - .alloc = ws_protocol_decoder_ambient_weather_alloc, - .free = ws_protocol_decoder_ambient_weather_free, - - .feed = ws_protocol_decoder_ambient_weather_feed, - .reset = ws_protocol_decoder_ambient_weather_reset, - - .get_hash_data = ws_protocol_decoder_ambient_weather_get_hash_data, - .serialize = ws_protocol_decoder_ambient_weather_serialize, - .deserialize = ws_protocol_decoder_ambient_weather_deserialize, - .get_string = ws_protocol_decoder_ambient_weather_get_string, -}; - -const SubGhzProtocolEncoder ws_protocol_ambient_weather_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol ws_protocol_ambient_weather = { - .name = WS_PROTOCOL_AMBIENT_WEATHER_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_ambient_weather_decoder, - .encoder = &ws_protocol_ambient_weather_encoder, -}; - -void* ws_protocol_decoder_ambient_weather_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderAmbient_Weather* instance = malloc(sizeof(WSProtocolDecoderAmbient_Weather)); - instance->base.protocol = &ws_protocol_ambient_weather; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void ws_protocol_decoder_ambient_weather_free(void* context) { - furi_assert(context); - WSProtocolDecoderAmbient_Weather* instance = context; - free(instance); -} - -void ws_protocol_decoder_ambient_weather_reset(void* context) { - furi_assert(context); - WSProtocolDecoderAmbient_Weather* instance = context; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); -} - -static bool ws_protocol_ambient_weather_check_crc(WSProtocolDecoderAmbient_Weather* instance) { - uint8_t msg[] = { - instance->decoder.decode_data >> 40, - instance->decoder.decode_data >> 32, - instance->decoder.decode_data >> 24, - instance->decoder.decode_data >> 16, - instance->decoder.decode_data >> 8}; - - uint8_t crc = subghz_protocol_blocks_lfsr_digest8(msg, 5, 0x98, 0x3e) ^ 0x64; - return (crc == (uint8_t)(instance->decoder.decode_data & 0xFF)); -} - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static void ws_protocol_ambient_weather_remote_controller(WSBlockGeneric* instance) { - instance->id = (instance->data >> 32) & 0xFF; - instance->battery_low = (instance->data >> 31) & 1; - instance->channel = ((instance->data >> 28) & 0x07) + 1; - instance->temp = - locale_fahrenheit_to_celsius(((float)((instance->data >> 16) & 0x0FFF) - 400.0f) / 10.0f); - instance->humidity = (instance->data >> 8) & 0xFF; - instance->btn = WS_NO_BTN; - - // ToDo maybe it won't be needed - /* - Sanity checks to reduce false positives and other bad data - Packets with Bad data often pass the MIC check. - - humidity > 100 (such as 255) and - - temperatures > 140 F (such as 369.5 F and 348.8 F - Specs in the F007TH and F012TH manuals state the range is: - - Temperature: -40 to 140 F - - Humidity: 10 to 99% - @todo - sanity check b[0] "model number" - - 0x45 - F007TH and F012TH - - 0x?5 - SwitchDocLabs F016TH temperature sensor (based on comment b[0] & 0x0f == 5) - - ? - TFA 30.3208.02 - if (instance->humidity < 0 || instance->humidity > 100) { - ERROR; - } - - if (instance->temp < -40.0 || instance->temp > 140.0) { - ERROR; - } - */ -} - -void ws_protocol_decoder_ambient_weather_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderAmbient_Weather* instance = context; - - ManchesterEvent event = ManchesterEventReset; - if(!level) { - if(DURATION_DIFF(duration, ws_protocol_ambient_weather_const.te_short) < - ws_protocol_ambient_weather_const.te_delta) { - event = ManchesterEventShortLow; - } else if( - DURATION_DIFF(duration, ws_protocol_ambient_weather_const.te_long) < - ws_protocol_ambient_weather_const.te_delta * 2) { - event = ManchesterEventLongLow; - } - } else { - if(DURATION_DIFF(duration, ws_protocol_ambient_weather_const.te_short) < - ws_protocol_ambient_weather_const.te_delta) { - event = ManchesterEventShortHigh; - } else if( - DURATION_DIFF(duration, ws_protocol_ambient_weather_const.te_long) < - ws_protocol_ambient_weather_const.te_delta * 2) { - event = ManchesterEventLongHigh; - } - } - if(event != ManchesterEventReset) { - bool data; - bool data_ok = manchester_advance( - instance->manchester_saved_state, event, &instance->manchester_saved_state, &data); - - if(data_ok) { - instance->decoder.decode_data = (instance->decoder.decode_data << 1) | !data; - } - - if(((instance->decoder.decode_data & AMBIENT_WEATHER_PACKET_HEADER_MASK) == - AMBIENT_WEATHER_PACKET_HEADER_1) || - ((instance->decoder.decode_data & AMBIENT_WEATHER_PACKET_HEADER_MASK) == - AMBIENT_WEATHER_PACKET_HEADER_2)) { - if(ws_protocol_ambient_weather_check_crc(instance)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = - ws_protocol_ambient_weather_const.min_count_bit_for_found; - ws_protocol_ambient_weather_remote_controller(&instance->generic); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } - } - } else { - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); - } -} - -uint8_t ws_protocol_decoder_ambient_weather_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderAmbient_Weather* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_ambient_weather_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderAmbient_Weather* instance = context; - return ws_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus - ws_protocol_decoder_ambient_weather_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderAmbient_Weather* instance = context; - return ws_block_generic_deserialize_check_count_bit( - &instance->generic, - flipper_format, - ws_protocol_ambient_weather_const.min_count_bit_for_found); -} - -void ws_protocol_decoder_ambient_weather_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderAmbient_Weather* instance = context; - furi_string_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%lX Ch:%d Bat:%d\r\n" - "Temp:%3.1f C Hum:%d%%", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data), - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (double)instance->generic.temp, - instance->generic.humidity); -} diff --git a/applications/external/weather_station/protocols/ambient_weather.h b/applications/external/weather_station/protocols/ambient_weather.h deleted file mode 100644 index 1694403cd..000000000 --- a/applications/external/weather_station/protocols/ambient_weather.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "ws_generic.h" -#include - -#define WS_PROTOCOL_AMBIENT_WEATHER_NAME "Ambient_Weather" - -typedef struct WSProtocolDecoderAmbient_Weather WSProtocolDecoderAmbient_Weather; -typedef struct WSProtocolEncoderAmbient_Weather WSProtocolEncoderAmbient_Weather; - -extern const SubGhzProtocolDecoder ws_protocol_ambient_weather_decoder; -extern const SubGhzProtocolEncoder ws_protocol_ambient_weather_encoder; -extern const SubGhzProtocol ws_protocol_ambient_weather; - -/** - * Allocate WSProtocolDecoderAmbient_Weather. - * @param environment Pointer to a SubGhzEnvironment instance - * @return WSProtocolDecoderAmbient_Weather* pointer to a WSProtocolDecoderAmbient_Weather instance - */ -void* ws_protocol_decoder_ambient_weather_alloc(SubGhzEnvironment* environment); - -/** - * Free WSProtocolDecoderAmbient_Weather. - * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance - */ -void ws_protocol_decoder_ambient_weather_free(void* context); - -/** - * Reset decoder WSProtocolDecoderAmbient_Weather. - * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance - */ -void ws_protocol_decoder_ambient_weather_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void ws_protocol_decoder_ambient_weather_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance - * @return hash Hash sum - */ -uint8_t ws_protocol_decoder_ambient_weather_get_hash_data(void* context); - -/** - * Serialize data WSProtocolDecoderAmbient_Weather. - * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_ambient_weather_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSProtocolDecoderAmbient_Weather. - * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus - ws_protocol_decoder_ambient_weather_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance - * @param output Resulting text - */ -void ws_protocol_decoder_ambient_weather_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/auriol_hg0601a.c b/applications/external/weather_station/protocols/auriol_hg0601a.c deleted file mode 100644 index 813fe1526..000000000 --- a/applications/external/weather_station/protocols/auriol_hg0601a.c +++ /dev/null @@ -1,248 +0,0 @@ -#include "auriol_hg0601a.h" - -#define TAG "WSProtocolAuriol_TH" - -/* - * -Auriol HG06061A-DCF-TX sensor. - -Data layout: - DDDDDDDD-B0-NN-TT-TTTTTTTTTT-CCCC-HHHHHHHH -Exmpl.: 11110100-10-01-00-0001001100-1111-01011101 - -- D: id, 8 bit -- B: where B is the battery status: 1=OK, 0=LOW, 1 bit -- 0: just zero :) -- N: NN is the channel: 00=CH1, 01=CH2, 11=CH3, 2bit -- T: temperature, 12 bit: 2's complement, scaled by 10 -- C: 4 bit: seems to be 0xf constantly, a separator between temp and humidity -- H: humidity sensor, humidity is 8 bits - - * The sensor sends 37 bits 10 times, - * the packets are ppm modulated (distance coding) with a pulse of ~500 us - * followed by a short gap of ~1000 us for a 0 bit or a long ~2000 us gap for a - * 1 bit, the sync gap is ~4000 us. - * - */ - -#define AURIOL_TH_CONST_DATA 0b1110 - -static const SubGhzBlockConst ws_protocol_auriol_th_const = { - .te_short = 500, - .te_long = 2000, - .te_delta = 150, - .min_count_bit_for_found = 37, -}; - -struct WSProtocolDecoderAuriol_TH { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; -}; - -struct WSProtocolEncoderAuriol_TH { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - WSBlockGeneric generic; -}; - -typedef enum { - auriol_THDecoderStepReset = 0, - auriol_THDecoderStepSaveDuration, - auriol_THDecoderStepCheckDuration, -} auriol_THDecoderStep; - -const SubGhzProtocolDecoder ws_protocol_auriol_th_decoder = { - .alloc = ws_protocol_decoder_auriol_th_alloc, - .free = ws_protocol_decoder_auriol_th_free, - - .feed = ws_protocol_decoder_auriol_th_feed, - .reset = ws_protocol_decoder_auriol_th_reset, - - .get_hash_data = ws_protocol_decoder_auriol_th_get_hash_data, - .serialize = ws_protocol_decoder_auriol_th_serialize, - .deserialize = ws_protocol_decoder_auriol_th_deserialize, - .get_string = ws_protocol_decoder_auriol_th_get_string, -}; - -const SubGhzProtocolEncoder ws_protocol_auriol_th_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol ws_protocol_auriol_th = { - .name = WS_PROTOCOL_AURIOL_TH_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_auriol_th_decoder, - .encoder = &ws_protocol_auriol_th_encoder, -}; - -void* ws_protocol_decoder_auriol_th_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderAuriol_TH* instance = malloc(sizeof(WSProtocolDecoderAuriol_TH)); - instance->base.protocol = &ws_protocol_auriol_th; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void ws_protocol_decoder_auriol_th_free(void* context) { - furi_assert(context); - WSProtocolDecoderAuriol_TH* instance = context; - free(instance); -} - -void ws_protocol_decoder_auriol_th_reset(void* context) { - furi_assert(context); - WSProtocolDecoderAuriol_TH* instance = context; - instance->decoder.parser_step = auriol_THDecoderStepReset; -} - -static bool ws_protocol_auriol_th_check(WSProtocolDecoderAuriol_TH* instance) { - uint8_t type = (instance->decoder.decode_data >> 8) & 0x0F; - - if((type == AURIOL_TH_CONST_DATA) && ((instance->decoder.decode_data >> 4) != 0xffffffff)) { - return true; - } else { - return false; - } - return true; -} - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static void ws_protocol_auriol_th_remote_controller(WSBlockGeneric* instance) { - instance->id = (instance->data >> 31) & 0xFF; - instance->battery_low = ((instance->data >> 30) & 1); - instance->channel = ((instance->data >> 25) & 0x03) + 1; - instance->btn = WS_NO_BTN; - if(!((instance->data >> 23) & 1)) { - instance->temp = (float)((instance->data >> 13) & 0x07FF) / 10.0f; - } else { - instance->temp = (float)((~(instance->data >> 13) & 0x07FF) + 1) / -10.0f; - } - - instance->humidity = (instance->data >> 1) & 0x7F; -} - -void ws_protocol_decoder_auriol_th_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderAuriol_TH* instance = context; - - switch(instance->decoder.parser_step) { - case auriol_THDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, ws_protocol_auriol_th_const.te_short * 8) < - ws_protocol_auriol_th_const.te_delta)) { - //Found sync - instance->decoder.parser_step = auriol_THDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } - break; - - case auriol_THDecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = auriol_THDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = auriol_THDecoderStepReset; - } - break; - - case auriol_THDecoderStepCheckDuration: - if(!level) { - if(DURATION_DIFF(duration, ws_protocol_auriol_th_const.te_short * 8) < - ws_protocol_auriol_th_const.te_delta) { - //Found sync - instance->decoder.parser_step = auriol_THDecoderStepReset; - if((instance->decoder.decode_count_bit == - ws_protocol_auriol_th_const.min_count_bit_for_found) && - ws_protocol_auriol_th_check(instance)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - ws_protocol_auriol_th_remote_controller(&instance->generic); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - instance->decoder.parser_step = auriol_THDecoderStepCheckDuration; - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - - break; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_auriol_th_const.te_short) < - ws_protocol_auriol_th_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_auriol_th_const.te_short * 2) < - ws_protocol_auriol_th_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = auriol_THDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_auriol_th_const.te_short) < - ws_protocol_auriol_th_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_auriol_th_const.te_short * 4) < - ws_protocol_auriol_th_const.te_delta * 2)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = auriol_THDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = auriol_THDecoderStepReset; - } - } else { - instance->decoder.parser_step = auriol_THDecoderStepReset; - } - break; - } -} - -uint8_t ws_protocol_decoder_auriol_th_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderAuriol_TH* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_auriol_th_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderAuriol_TH* instance = context; - return ws_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus - ws_protocol_decoder_auriol_th_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderAuriol_TH* instance = context; - return ws_block_generic_deserialize_check_count_bit( - &instance->generic, flipper_format, ws_protocol_auriol_th_const.min_count_bit_for_found); -} - -void ws_protocol_decoder_auriol_th_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderAuriol_TH* instance = context; - furi_string_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%lX Ch:%d Bat:%d\r\n" - "Temp:%3.1f C Hum:%d%%", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data), - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (double)instance->generic.temp, - instance->generic.humidity); -} diff --git a/applications/external/weather_station/protocols/auriol_hg0601a.h b/applications/external/weather_station/protocols/auriol_hg0601a.h deleted file mode 100644 index 155bb07fc..000000000 --- a/applications/external/weather_station/protocols/auriol_hg0601a.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "ws_generic.h" -#include - -#define WS_PROTOCOL_AURIOL_TH_NAME "Auriol HG06061" //HG06061A-DCF-TX - -typedef struct WSProtocolDecoderAuriol_TH WSProtocolDecoderAuriol_TH; -typedef struct WSProtocolEncoderAuriol_TH WSProtocolEncoderAuriol_TH; - -extern const SubGhzProtocolDecoder ws_protocol_auriol_th_decoder; -extern const SubGhzProtocolEncoder ws_protocol_auriol_th_encoder; -extern const SubGhzProtocol ws_protocol_auriol_th; - -/** - * Allocate WSProtocolDecoderAuriol_TH. - * @param environment Pointer to a SubGhzEnvironment instance - * @return WSProtocolDecoderAuriol_TH* pointer to a WSProtocolDecoderAuriol_TH instance - */ -void* ws_protocol_decoder_auriol_th_alloc(SubGhzEnvironment* environment); - -/** - * Free WSProtocolDecoderAuriol_TH. - * @param context Pointer to a WSProtocolDecoderAuriol_TH instance - */ -void ws_protocol_decoder_auriol_th_free(void* context); - -/** - * Reset decoder WSProtocolDecoderAuriol_TH. - * @param context Pointer to a WSProtocolDecoderAuriol_TH instance - */ -void ws_protocol_decoder_auriol_th_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a WSProtocolDecoderAuriol_TH instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void ws_protocol_decoder_auriol_th_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a WSProtocolDecoderAuriol_TH instance - * @return hash Hash sum - */ -uint8_t ws_protocol_decoder_auriol_th_get_hash_data(void* context); - -/** - * Serialize data WSProtocolDecoderAuriol_TH. - * @param context Pointer to a WSProtocolDecoderAuriol_TH instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_auriol_th_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSProtocolDecoderAuriol_TH. - * @param context Pointer to a WSProtocolDecoderAuriol_TH instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus - ws_protocol_decoder_auriol_th_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a WSProtocolDecoderAuriol_TH instance - * @param output Resulting text - */ -void ws_protocol_decoder_auriol_th_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/gt_wt_02.c b/applications/external/weather_station/protocols/gt_wt_02.c deleted file mode 100644 index d333164b4..000000000 --- a/applications/external/weather_station/protocols/gt_wt_02.c +++ /dev/null @@ -1,255 +0,0 @@ -#include "gt_wt_02.h" - -#define TAG "WSProtocolGT_WT02" - -/* - * Help - * https://github.com/merbanan/rtl_433/blob/master/src/devices/gt_wt_02.c - * - * GT-WT-02 sensor on 433.92MHz. - * Example and frame description provided by https://github.com/ludwich66 - * [01] {37} 34 00 ed 47 60 : 00110100 00000000 11101101 01000111 01100000 - * code, BatOK,not-man-send, Channel1, +23,7°C, 35% - * [01] {37} 34 8f 87 15 90 : 00110100 10001111 10000111 00010101 10010000 - * code, BatOK,not-man-send, Channel1,-12,1°C, 10% - * Humidity: - * - the working range is 20-90 % - * - if "LL" in display view it sends 10 % - * - if "HH" in display view it sends 110% - * SENSOR: GT-WT-02 (ALDI Globaltronics..) - * TYP IIIIIIII BMCCTTTT TTTTTTTT HHHHHHHX XXXXX - * TYPE Description: - * - I = Random Device Code, changes with battery reset - * - B = Battery 0=OK 1=LOW - * - M = Manual Send Button Pressed 0=not pressed 1=pressed - * - C = Channel 00=CH1, 01=CH2, 10=CH3 - * - T = Temperature, 12 Bit 2's complement, scaled by 10 - * - H = Humidity = 7 Bit bin2dez 00-99, Display LL=10%, Display HH=110% (Range 20-90%) - * - X = Checksum, sum modulo 64 - * A Lidl AURIO (from 12/2018) with PCB marking YJ-T12 V02 has two extra bits in front. - * -*/ - -static const SubGhzBlockConst ws_protocol_gt_wt_02_const = { - .te_short = 500, - .te_long = 2000, - .te_delta = 150, - .min_count_bit_for_found = 37, -}; - -struct WSProtocolDecoderGT_WT02 { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; -}; - -struct WSProtocolEncoderGT_WT02 { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - WSBlockGeneric generic; -}; - -typedef enum { - GT_WT02DecoderStepReset = 0, - GT_WT02DecoderStepSaveDuration, - GT_WT02DecoderStepCheckDuration, -} GT_WT02DecoderStep; - -const SubGhzProtocolDecoder ws_protocol_gt_wt_02_decoder = { - .alloc = ws_protocol_decoder_gt_wt_02_alloc, - .free = ws_protocol_decoder_gt_wt_02_free, - - .feed = ws_protocol_decoder_gt_wt_02_feed, - .reset = ws_protocol_decoder_gt_wt_02_reset, - - .get_hash_data = ws_protocol_decoder_gt_wt_02_get_hash_data, - .serialize = ws_protocol_decoder_gt_wt_02_serialize, - .deserialize = ws_protocol_decoder_gt_wt_02_deserialize, - .get_string = ws_protocol_decoder_gt_wt_02_get_string, -}; - -const SubGhzProtocolEncoder ws_protocol_gt_wt_02_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol ws_protocol_gt_wt_02 = { - .name = WS_PROTOCOL_GT_WT_02_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_gt_wt_02_decoder, - .encoder = &ws_protocol_gt_wt_02_encoder, -}; - -void* ws_protocol_decoder_gt_wt_02_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderGT_WT02* instance = malloc(sizeof(WSProtocolDecoderGT_WT02)); - instance->base.protocol = &ws_protocol_gt_wt_02; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void ws_protocol_decoder_gt_wt_02_free(void* context) { - furi_assert(context); - WSProtocolDecoderGT_WT02* instance = context; - free(instance); -} - -void ws_protocol_decoder_gt_wt_02_reset(void* context) { - furi_assert(context); - WSProtocolDecoderGT_WT02* instance = context; - instance->decoder.parser_step = GT_WT02DecoderStepReset; -} - -static bool ws_protocol_gt_wt_02_check(WSProtocolDecoderGT_WT02* instance) { - if(!instance->decoder.decode_data) return false; - uint8_t sum = (instance->decoder.decode_data >> 5) & 0xe; - uint64_t temp_data = instance->decoder.decode_data >> 9; - for(uint8_t i = 0; i < 7; i++) { - sum += (temp_data >> (i * 4)) & 0xF; - } - return ((uint8_t)(instance->decoder.decode_data & 0x3F) == (sum & 0x3F)); -} - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static void ws_protocol_gt_wt_02_remote_controller(WSBlockGeneric* instance) { - instance->id = (instance->data >> 29) & 0xFF; - instance->battery_low = (instance->data >> 28) & 1; - instance->btn = (instance->data >> 27) & 1; - instance->channel = ((instance->data >> 25) & 0x3) + 1; - - if(!((instance->data >> 24) & 1)) { - instance->temp = (float)((instance->data >> 13) & 0x07FF) / 10.0f; - } else { - instance->temp = (float)((~(instance->data >> 13) & 0x07FF) + 1) / -10.0f; - } - - instance->humidity = (instance->data >> 6) & 0x7F; - if(instance->humidity <= 10) // actually the sensors sends 10 below working range of 20% - instance->humidity = 0; - else if(instance->humidity > 90) // actually the sensors sends 110 above working range of 90% - instance->humidity = 100; -} - -void ws_protocol_decoder_gt_wt_02_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderGT_WT02* instance = context; - - switch(instance->decoder.parser_step) { - case GT_WT02DecoderStepReset: - if((!level) && (DURATION_DIFF(duration, ws_protocol_gt_wt_02_const.te_short * 18) < - ws_protocol_gt_wt_02_const.te_delta * 8)) { - //Found syncPrefix - instance->decoder.parser_step = GT_WT02DecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } - break; - - case GT_WT02DecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = GT_WT02DecoderStepCheckDuration; - } else { - instance->decoder.parser_step = GT_WT02DecoderStepReset; - } - break; - - case GT_WT02DecoderStepCheckDuration: - if(!level) { - if(DURATION_DIFF(instance->decoder.te_last, ws_protocol_gt_wt_02_const.te_short) < - ws_protocol_gt_wt_02_const.te_delta) { - if(DURATION_DIFF(duration, ws_protocol_gt_wt_02_const.te_short * 18) < - ws_protocol_gt_wt_02_const.te_delta * 8) { - //Found syncPostfix - instance->decoder.parser_step = GT_WT02DecoderStepReset; - if((instance->decoder.decode_count_bit == - ws_protocol_gt_wt_02_const.min_count_bit_for_found) && - ws_protocol_gt_wt_02_check(instance)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - ws_protocol_gt_wt_02_remote_controller(&instance->generic); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } else if(instance->decoder.decode_count_bit == 1) { - instance->decoder.parser_step = GT_WT02DecoderStepSaveDuration; - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else if( - DURATION_DIFF(duration, ws_protocol_gt_wt_02_const.te_long) < - ws_protocol_gt_wt_02_const.te_delta * 2) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = GT_WT02DecoderStepSaveDuration; - } else if( - DURATION_DIFF(duration, ws_protocol_gt_wt_02_const.te_long * 2) < - ws_protocol_gt_wt_02_const.te_delta * 4) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = GT_WT02DecoderStepSaveDuration; - } else { - instance->decoder.parser_step = GT_WT02DecoderStepReset; - } - } else { - instance->decoder.parser_step = GT_WT02DecoderStepReset; - } - } else { - instance->decoder.parser_step = GT_WT02DecoderStepReset; - } - break; - } -} - -uint8_t ws_protocol_decoder_gt_wt_02_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderGT_WT02* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_gt_wt_02_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderGT_WT02* instance = context; - return ws_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus - ws_protocol_decoder_gt_wt_02_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderGT_WT02* instance = context; - return ws_block_generic_deserialize_check_count_bit( - &instance->generic, flipper_format, ws_protocol_gt_wt_02_const.min_count_bit_for_found); -} - -void ws_protocol_decoder_gt_wt_02_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderGT_WT02* instance = context; - furi_string_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%lX Ch:%d Bat:%d\r\n" - "Temp:%3.1f C Hum:%d%%", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data), - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (double)instance->generic.temp, - instance->generic.humidity); -} diff --git a/applications/external/weather_station/protocols/gt_wt_02.h b/applications/external/weather_station/protocols/gt_wt_02.h deleted file mode 100644 index e13576d21..000000000 --- a/applications/external/weather_station/protocols/gt_wt_02.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "ws_generic.h" -#include - -#define WS_PROTOCOL_GT_WT_02_NAME "GT-WT02" - -typedef struct WSProtocolDecoderGT_WT02 WSProtocolDecoderGT_WT02; -typedef struct WSProtocolEncoderGT_WT02 WSProtocolEncoderGT_WT02; - -extern const SubGhzProtocolDecoder ws_protocol_gt_wt_02_decoder; -extern const SubGhzProtocolEncoder ws_protocol_gt_wt_02_encoder; -extern const SubGhzProtocol ws_protocol_gt_wt_02; - -/** - * Allocate WSProtocolDecoderGT_WT02. - * @param environment Pointer to a SubGhzEnvironment instance - * @return WSProtocolDecoderGT_WT02* pointer to a WSProtocolDecoderGT_WT02 instance - */ -void* ws_protocol_decoder_gt_wt_02_alloc(SubGhzEnvironment* environment); - -/** - * Free WSProtocolDecoderGT_WT02. - * @param context Pointer to a WSProtocolDecoderGT_WT02 instance - */ -void ws_protocol_decoder_gt_wt_02_free(void* context); - -/** - * Reset decoder WSProtocolDecoderGT_WT02. - * @param context Pointer to a WSProtocolDecoderGT_WT02 instance - */ -void ws_protocol_decoder_gt_wt_02_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a WSProtocolDecoderGT_WT02 instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void ws_protocol_decoder_gt_wt_02_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a WSProtocolDecoderGT_WT02 instance - * @return hash Hash sum - */ -uint8_t ws_protocol_decoder_gt_wt_02_get_hash_data(void* context); - -/** - * Serialize data WSProtocolDecoderGT_WT02. - * @param context Pointer to a WSProtocolDecoderGT_WT02 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_gt_wt_02_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSProtocolDecoderGT_WT02. - * @param context Pointer to a WSProtocolDecoderGT_WT02 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus - ws_protocol_decoder_gt_wt_02_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a WSProtocolDecoderGT_WT02 instance - * @param output Resulting text - */ -void ws_protocol_decoder_gt_wt_02_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/gt_wt_03.c b/applications/external/weather_station/protocols/gt_wt_03.c deleted file mode 100644 index 30430b839..000000000 --- a/applications/external/weather_station/protocols/gt_wt_03.c +++ /dev/null @@ -1,330 +0,0 @@ -#include "gt_wt_03.h" - -#define TAG "WSProtocolGT_WT03" - -/* - * Help - * https://github.com/merbanan/rtl_433/blob/master/src/devices/gt_wt_03.c - * - * - * Globaltronics GT-WT-03 sensor on 433.92MHz. - * The 01-set sensor has 60 ms packet gap with 10 repeats. - * The 02-set sensor has no packet gap with 23 repeats. - * Example: - * {41} 17 cf be fa 6a 80 [ S1 C1 26,1 C 78.9 F 48% Bat-Good Manual-Yes ] - * {41} 17 cf be fa 6a 80 [ S1 C1 26,1 C 78.9 F 48% Bat-Good Manual-Yes Batt-Changed ] - * {41} 17 cf fe fa ea 80 [ S1 C1 26,1 C 78.9 F 48% Bat-Good Manual-No Batt-Changed ] - * {41} 01 cf 6f 11 b2 80 [ S2 C2 23,8 C 74.8 F 48% Bat-LOW Manual-No ] - * {41} 01 c8 d0 2b 76 80 [ S2 C3 -4,4 C 24.1 F 55% Bat-Good Manual-No Batt-Changed ] - * Format string: - * ID:8h HUM:8d B:b M:b C:2d TEMP:12d CHK:8h 1x - * Data layout: - * TYP IIIIIIII HHHHHHHH BMCCTTTT TTTTTTTT XXXXXXXX - * - I: Random Device Code: changes with battery reset - * - H: Humidity: 8 Bit 00-99, Display LL=10%, Display HH=110% (Range 20-95%) - * - B: Battery: 0=OK 1=LOW - * - M: Manual Send Button Pressed: 0=not pressed, 1=pressed - * - C: Channel: 00=CH1, 01=CH2, 10=CH3 - * - T: Temperature: 12 Bit 2's complement, scaled by 10, range-50.0 C (-50.1 shown as Lo) to +70.0 C (+70.1 C is shown as Hi) - * - X: Checksum, xor shifting key per byte - * Humidity: - * - the working range is 20-95 % - * - if "LL" in display view it sends 10 % - * - if "HH" in display view it sends 110% - * Checksum: - * Per byte xor the key for each 1-bit, shift per bit. Key list per bit, starting at MSB: - * - 0x00 [07] - * - 0x80 [06] - * - 0x40 [05] - * - 0x20 [04] - * - 0x10 [03] - * - 0x88 [02] - * - 0xc4 [01] - * - 0x62 [00] - * Note: this can also be seen as lower byte of a Galois/Fibonacci LFSR-16, gen 0x00, init 0x3100 (or 0x62 if reversed) resetting at every byte. - * Battery voltages: - * - U=<2,65V +- ~5% Battery indicator - * - U=>2.10C +- 5% plausible readings - * - U=2,00V +- ~5% Temperature offset -5°C Humidity offset unknown - * - U=<1,95V +- ~5% does not initialize anymore - * - U=1,90V +- 5% temperature offset -15°C - * - U=1,80V +- 5% Display is showing refresh pattern - * - U=1.75V +- ~5% TX causes cut out - * - */ - -static const SubGhzBlockConst ws_protocol_gt_wt_03_const = { - .te_short = 285, - .te_long = 570, - .te_delta = 120, - .min_count_bit_for_found = 41, -}; - -struct WSProtocolDecoderGT_WT03 { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; - - uint16_t header_count; -}; - -struct WSProtocolEncoderGT_WT03 { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - WSBlockGeneric generic; -}; - -typedef enum { - GT_WT03DecoderStepReset = 0, - GT_WT03DecoderStepCheckPreambule, - GT_WT03DecoderStepSaveDuration, - GT_WT03DecoderStepCheckDuration, -} GT_WT03DecoderStep; - -const SubGhzProtocolDecoder ws_protocol_gt_wt_03_decoder = { - .alloc = ws_protocol_decoder_gt_wt_03_alloc, - .free = ws_protocol_decoder_gt_wt_03_free, - - .feed = ws_protocol_decoder_gt_wt_03_feed, - .reset = ws_protocol_decoder_gt_wt_03_reset, - - .get_hash_data = ws_protocol_decoder_gt_wt_03_get_hash_data, - .serialize = ws_protocol_decoder_gt_wt_03_serialize, - .deserialize = ws_protocol_decoder_gt_wt_03_deserialize, - .get_string = ws_protocol_decoder_gt_wt_03_get_string, -}; - -const SubGhzProtocolEncoder ws_protocol_gt_wt_03_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol ws_protocol_gt_wt_03 = { - .name = WS_PROTOCOL_GT_WT_03_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_gt_wt_03_decoder, - .encoder = &ws_protocol_gt_wt_03_encoder, -}; - -void* ws_protocol_decoder_gt_wt_03_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderGT_WT03* instance = malloc(sizeof(WSProtocolDecoderGT_WT03)); - instance->base.protocol = &ws_protocol_gt_wt_03; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void ws_protocol_decoder_gt_wt_03_free(void* context) { - furi_assert(context); - WSProtocolDecoderGT_WT03* instance = context; - free(instance); -} - -void ws_protocol_decoder_gt_wt_03_reset(void* context) { - furi_assert(context); - WSProtocolDecoderGT_WT03* instance = context; - instance->decoder.parser_step = GT_WT03DecoderStepReset; -} - -static bool ws_protocol_gt_wt_03_check_crc(WSProtocolDecoderGT_WT03* instance) { - uint8_t msg[] = { - instance->decoder.decode_data >> 33, - instance->decoder.decode_data >> 25, - instance->decoder.decode_data >> 17, - instance->decoder.decode_data >> 9}; - - uint8_t sum = 0; - for(unsigned k = 0; k < sizeof(msg); ++k) { - uint8_t data = msg[k]; - uint16_t key = 0x3100; - for(int i = 7; i >= 0; --i) { - // XOR key into sum if data bit is set - if((data >> i) & 1) sum ^= key & 0xff; - // roll the key right - key = (key >> 1); - } - } - return ((sum ^ (uint8_t)((instance->decoder.decode_data >> 1) & 0xFF)) == 0x2D); -} - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static void ws_protocol_gt_wt_03_remote_controller(WSBlockGeneric* instance) { - instance->id = instance->data >> 33; - instance->humidity = (instance->data >> 25) & 0xFF; - - if(instance->humidity <= 10) { // actually the sensors sends 10 below working range of 20% - instance->humidity = 0; - } else if(instance->humidity > 95) { // actually the sensors sends 110 above working range of 90% - instance->humidity = 100; - } - - instance->battery_low = (instance->data >> 24) & 1; - instance->btn = (instance->data >> 23) & 1; - instance->channel = ((instance->data >> 21) & 0x03) + 1; - - if(!((instance->data >> 20) & 1)) { - instance->temp = (float)((instance->data >> 9) & 0x07FF) / 10.0f; - } else { - instance->temp = (float)((~(instance->data >> 9) & 0x07FF) + 1) / -10.0f; - } -} - -void ws_protocol_decoder_gt_wt_03_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderGT_WT03* instance = context; - - switch(instance->decoder.parser_step) { - case GT_WT03DecoderStepReset: - if((level) && (DURATION_DIFF(duration, ws_protocol_gt_wt_03_const.te_short * 3) < - ws_protocol_gt_wt_03_const.te_delta * 2)) { - instance->decoder.parser_step = GT_WT03DecoderStepCheckPreambule; - instance->decoder.te_last = duration; - instance->header_count = 0; - } - break; - - case GT_WT03DecoderStepCheckPreambule: - if(level) { - instance->decoder.te_last = duration; - } else { - if((DURATION_DIFF(instance->decoder.te_last, ws_protocol_gt_wt_03_const.te_short * 3) < - ws_protocol_gt_wt_03_const.te_delta * 2) && - (DURATION_DIFF(duration, ws_protocol_gt_wt_03_const.te_short * 3) < - ws_protocol_gt_wt_03_const.te_delta * 2)) { - //Found preambule - instance->header_count++; - } else if(instance->header_count == 4) { - if((DURATION_DIFF(instance->decoder.te_last, ws_protocol_gt_wt_03_const.te_short) < - ws_protocol_gt_wt_03_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_gt_wt_03_const.te_long) < - ws_protocol_gt_wt_03_const.te_delta)) { - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = GT_WT03DecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_gt_wt_03_const.te_long) < - ws_protocol_gt_wt_03_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_gt_wt_03_const.te_short) < - ws_protocol_gt_wt_03_const.te_delta)) { - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = GT_WT03DecoderStepSaveDuration; - } else { - instance->decoder.parser_step = GT_WT03DecoderStepReset; - } - } else { - instance->decoder.parser_step = GT_WT03DecoderStepReset; - } - } - break; - - case GT_WT03DecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = GT_WT03DecoderStepCheckDuration; - } else { - instance->decoder.parser_step = GT_WT03DecoderStepReset; - } - break; - - case GT_WT03DecoderStepCheckDuration: - if(!level) { - if(((DURATION_DIFF(instance->decoder.te_last, ws_protocol_gt_wt_03_const.te_short * 3) < - ws_protocol_gt_wt_03_const.te_delta * 2) && - (DURATION_DIFF(duration, ws_protocol_gt_wt_03_const.te_short * 3) < - ws_protocol_gt_wt_03_const.te_delta * 2))) { - if((instance->decoder.decode_count_bit == - ws_protocol_gt_wt_03_const.min_count_bit_for_found) && - ws_protocol_gt_wt_03_check_crc(instance)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - ws_protocol_gt_wt_03_remote_controller(&instance->generic); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->header_count = 1; - instance->decoder.parser_step = GT_WT03DecoderStepCheckPreambule; - break; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_gt_wt_03_const.te_short) < - ws_protocol_gt_wt_03_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_gt_wt_03_const.te_long) < - ws_protocol_gt_wt_03_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = GT_WT03DecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_gt_wt_03_const.te_long) < - ws_protocol_gt_wt_03_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_gt_wt_03_const.te_short) < - ws_protocol_gt_wt_03_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = GT_WT03DecoderStepSaveDuration; - } else { - instance->decoder.parser_step = GT_WT03DecoderStepReset; - } - } else { - instance->decoder.parser_step = GT_WT03DecoderStepReset; - } - break; - } -} - -uint8_t ws_protocol_decoder_gt_wt_03_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderGT_WT03* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_gt_wt_03_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderGT_WT03* instance = context; - return ws_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus - ws_protocol_decoder_gt_wt_03_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderGT_WT03* instance = context; - return ws_block_generic_deserialize_check_count_bit( - &instance->generic, flipper_format, ws_protocol_gt_wt_03_const.min_count_bit_for_found); -} - -void ws_protocol_decoder_gt_wt_03_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderGT_WT03* instance = context; - furi_string_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%lX Ch:%d Bat:%d\r\n" - "Temp:%3.1f C Hum:%d%%", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data), - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (double)instance->generic.temp, - instance->generic.humidity); -} diff --git a/applications/external/weather_station/protocols/gt_wt_03.h b/applications/external/weather_station/protocols/gt_wt_03.h deleted file mode 100644 index d566bb399..000000000 --- a/applications/external/weather_station/protocols/gt_wt_03.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "ws_generic.h" -#include - -#define WS_PROTOCOL_GT_WT_03_NAME "GT-WT03" - -typedef struct WSProtocolDecoderGT_WT03 WSProtocolDecoderGT_WT03; -typedef struct WSProtocolEncoderGT_WT03 WSProtocolEncoderGT_WT03; - -extern const SubGhzProtocolDecoder ws_protocol_gt_wt_03_decoder; -extern const SubGhzProtocolEncoder ws_protocol_gt_wt_03_encoder; -extern const SubGhzProtocol ws_protocol_gt_wt_03; - -/** - * Allocate WSProtocolDecoderGT_WT03. - * @param environment Pointer to a SubGhzEnvironment instance - * @return WSProtocolDecoderGT_WT03* pointer to a WSProtocolDecoderGT_WT03 instance - */ -void* ws_protocol_decoder_gt_wt_03_alloc(SubGhzEnvironment* environment); - -/** - * Free WSProtocolDecoderGT_WT03. - * @param context Pointer to a WSProtocolDecoderGT_WT03 instance - */ -void ws_protocol_decoder_gt_wt_03_free(void* context); - -/** - * Reset decoder WSProtocolDecoderGT_WT03. - * @param context Pointer to a WSProtocolDecoderGT_WT03 instance - */ -void ws_protocol_decoder_gt_wt_03_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a WSProtocolDecoderGT_WT03 instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void ws_protocol_decoder_gt_wt_03_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a WSProtocolDecoderGT_WT03 instance - * @return hash Hash sum - */ -uint8_t ws_protocol_decoder_gt_wt_03_get_hash_data(void* context); - -/** - * Serialize data WSProtocolDecoderGT_WT03. - * @param context Pointer to a WSProtocolDecoderGT_WT03 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_gt_wt_03_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSProtocolDecoderGT_WT03. - * @param context Pointer to a WSProtocolDecoderGT_WT03 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus - ws_protocol_decoder_gt_wt_03_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a WSProtocolDecoderGT_WT03 instance - * @param output Resulting text - */ -void ws_protocol_decoder_gt_wt_03_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/infactory.c b/applications/external/weather_station/protocols/infactory.c deleted file mode 100644 index 4b0e6602a..000000000 --- a/applications/external/weather_station/protocols/infactory.c +++ /dev/null @@ -1,286 +0,0 @@ -#include "infactory.h" - -#define TAG "WSProtocolInfactory" - -/* - * Help - * https://github.com/merbanan/rtl_433/blob/master/src/devices/infactory.c - * - * Analysis using Genuino (see http://gitlab.com/hp-uno, e.g. uno_log_433): - * Observed On-Off-Key (OOK) data pattern: - * preamble syncPrefix data...(40 bit) syncPostfix - * HHLL HHLL HHLL HHLL HLLLLLLLLLLLLLLLL (HLLLL HLLLLLLLL HLLLL HLLLLLLLL ....) HLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL - * Breakdown: - * - four preamble pairs '1'/'0' each with a length of ca. 1000us - * - syncPre, syncPost, data0, data1 have a '1' start pulse of ca. 500us - * - syncPre pulse before dataPtr has a '0' pulse length of ca. 8000us - * - data0 (0-bits) have then a '0' pulse length of ca. 2000us - * - data1 (1-bits) have then a '0' pulse length of ca. 4000us - * - syncPost after dataPtr has a '0' pulse length of ca. 16000us - * This analysis is the reason for the new r_device definitions below. - * NB: pulse_slicer_ppm does not use .gap_limit if .tolerance is set. - * - * Outdoor sensor, transmits temperature and humidity data - * - inFactory NC-3982-913/NX-5817-902, Pearl (for FWS-686 station) - * - nor-tec 73383 (weather station + sensor), Schou Company AS, Denmark - * - DAY 73365 (weather station + sensor), Schou Company AS, Denmark - * Known brand names: inFactory, nor-tec, GreenBlue, DAY. Manufacturer in China. - * Transmissions includes an id. Every 60 seconds the sensor transmits 6 packets: - * 0000 1111 | 0011 0000 | 0101 1100 | 1110 0111 | 0110 0001 - * iiii iiii | cccc ub?? | tttt tttt | tttt hhhh | hhhh ??nn - * - i: identification; changes on battery switch - * - c: CRC-4; CCITT checksum, see below for computation specifics - * - u: unknown; (sometimes set at power-on, but not always) - * - b: battery low; flag to indicate low battery voltage - * - h: Humidity; BCD-encoded, each nibble is one digit, 'A0' means 100%rH - * - t: Temperature; in °F as binary number with one decimal place + 90 °F offset - * - n: Channel; Channel number 1 - 3 - * - */ - -static const SubGhzBlockConst ws_protocol_infactory_const = { - .te_short = 500, - .te_long = 2000, - .te_delta = 150, - .min_count_bit_for_found = 40, -}; - -struct WSProtocolDecoderInfactory { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; - - uint16_t header_count; -}; - -struct WSProtocolEncoderInfactory { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - WSBlockGeneric generic; -}; - -typedef enum { - InfactoryDecoderStepReset = 0, - InfactoryDecoderStepCheckPreambule, - InfactoryDecoderStepSaveDuration, - InfactoryDecoderStepCheckDuration, -} InfactoryDecoderStep; - -const SubGhzProtocolDecoder ws_protocol_infactory_decoder = { - .alloc = ws_protocol_decoder_infactory_alloc, - .free = ws_protocol_decoder_infactory_free, - - .feed = ws_protocol_decoder_infactory_feed, - .reset = ws_protocol_decoder_infactory_reset, - - .get_hash_data = ws_protocol_decoder_infactory_get_hash_data, - .serialize = ws_protocol_decoder_infactory_serialize, - .deserialize = ws_protocol_decoder_infactory_deserialize, - .get_string = ws_protocol_decoder_infactory_get_string, -}; - -const SubGhzProtocolEncoder ws_protocol_infactory_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol ws_protocol_infactory = { - .name = WS_PROTOCOL_INFACTORY_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_infactory_decoder, - .encoder = &ws_protocol_infactory_encoder, -}; - -void* ws_protocol_decoder_infactory_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderInfactory* instance = malloc(sizeof(WSProtocolDecoderInfactory)); - instance->base.protocol = &ws_protocol_infactory; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void ws_protocol_decoder_infactory_free(void* context) { - furi_assert(context); - WSProtocolDecoderInfactory* instance = context; - free(instance); -} - -void ws_protocol_decoder_infactory_reset(void* context) { - furi_assert(context); - WSProtocolDecoderInfactory* instance = context; - instance->decoder.parser_step = InfactoryDecoderStepReset; -} - -static bool ws_protocol_infactory_check_crc(WSProtocolDecoderInfactory* instance) { - uint8_t msg[] = { - instance->decoder.decode_data >> 32, - (((instance->decoder.decode_data >> 24) & 0x0F) | (instance->decoder.decode_data & 0x0F) - << 4), - instance->decoder.decode_data >> 16, - instance->decoder.decode_data >> 8, - instance->decoder.decode_data}; - - uint8_t crc = - subghz_protocol_blocks_crc4(msg, 4, 0x13, 0); // Koopmann 0x9, CCITT-4; FP-4; ITU-T G.704 - crc ^= msg[4] >> 4; // last nibble is only XORed - return (crc == ((instance->decoder.decode_data >> 28) & 0x0F)); -} - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static void ws_protocol_infactory_remote_controller(WSBlockGeneric* instance) { - instance->id = instance->data >> 32; - instance->battery_low = (instance->data >> 26) & 1; - instance->btn = WS_NO_BTN; - instance->temp = - locale_fahrenheit_to_celsius(((float)((instance->data >> 12) & 0x0FFF) - 900.0f) / 10.0f); - instance->humidity = - (((instance->data >> 8) & 0x0F) * 10) + ((instance->data >> 4) & 0x0F); // BCD, 'A0'=100%rH - instance->channel = instance->data & 0x03; -} - -void ws_protocol_decoder_infactory_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderInfactory* instance = context; - - switch(instance->decoder.parser_step) { - case InfactoryDecoderStepReset: - if((level) && (DURATION_DIFF(duration, ws_protocol_infactory_const.te_short * 2) < - ws_protocol_infactory_const.te_delta * 2)) { - instance->decoder.parser_step = InfactoryDecoderStepCheckPreambule; - instance->decoder.te_last = duration; - instance->header_count = 0; - } - break; - - case InfactoryDecoderStepCheckPreambule: - if(level) { - instance->decoder.te_last = duration; - } else { - if((DURATION_DIFF(instance->decoder.te_last, ws_protocol_infactory_const.te_short * 2) < - ws_protocol_infactory_const.te_delta * 2) && - (DURATION_DIFF(duration, ws_protocol_infactory_const.te_short * 2) < - ws_protocol_infactory_const.te_delta * 2)) { - //Found preambule - instance->header_count++; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_infactory_const.te_short) < - ws_protocol_infactory_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_infactory_const.te_short * 16) < - ws_protocol_infactory_const.te_delta * 8)) { - //Found syncPrefix - if(instance->header_count > 3) { - instance->decoder.parser_step = InfactoryDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } - } else { - instance->decoder.parser_step = InfactoryDecoderStepReset; - } - } - break; - - case InfactoryDecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = InfactoryDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = InfactoryDecoderStepReset; - } - break; - - case InfactoryDecoderStepCheckDuration: - if(!level) { - if(duration >= ((uint32_t)ws_protocol_infactory_const.te_short * 30)) { - //Found syncPostfix - if((instance->decoder.decode_count_bit == - ws_protocol_infactory_const.min_count_bit_for_found) && - ws_protocol_infactory_check_crc(instance)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - ws_protocol_infactory_remote_controller(&instance->generic); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->decoder.parser_step = InfactoryDecoderStepReset; - break; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_infactory_const.te_short) < - ws_protocol_infactory_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_infactory_const.te_long) < - ws_protocol_infactory_const.te_delta * 2)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = InfactoryDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_infactory_const.te_short) < - ws_protocol_infactory_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_infactory_const.te_long * 2) < - ws_protocol_infactory_const.te_delta * 4)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = InfactoryDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = InfactoryDecoderStepReset; - } - } else { - instance->decoder.parser_step = InfactoryDecoderStepReset; - } - break; - } -} - -uint8_t ws_protocol_decoder_infactory_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderInfactory* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_infactory_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderInfactory* instance = context; - return ws_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus - ws_protocol_decoder_infactory_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderInfactory* instance = context; - return ws_block_generic_deserialize_check_count_bit( - &instance->generic, flipper_format, ws_protocol_infactory_const.min_count_bit_for_found); -} - -void ws_protocol_decoder_infactory_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderInfactory* instance = context; - furi_string_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%lX Ch:%d Bat:%d\r\n" - "Temp:%3.1f C Hum:%d%%", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data), - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (double)instance->generic.temp, - instance->generic.humidity); -} diff --git a/applications/external/weather_station/protocols/infactory.h b/applications/external/weather_station/protocols/infactory.h deleted file mode 100644 index 9431a067e..000000000 --- a/applications/external/weather_station/protocols/infactory.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "ws_generic.h" -#include - -#define WS_PROTOCOL_INFACTORY_NAME "inFactory-TH" - -typedef struct WSProtocolDecoderInfactory WSProtocolDecoderInfactory; -typedef struct WSProtocolEncoderInfactory WSProtocolEncoderInfactory; - -extern const SubGhzProtocolDecoder ws_protocol_infactory_decoder; -extern const SubGhzProtocolEncoder ws_protocol_infactory_encoder; -extern const SubGhzProtocol ws_protocol_infactory; - -/** - * Allocate WSProtocolDecoderInfactory. - * @param environment Pointer to a SubGhzEnvironment instance - * @return WSProtocolDecoderInfactory* pointer to a WSProtocolDecoderInfactory instance - */ -void* ws_protocol_decoder_infactory_alloc(SubGhzEnvironment* environment); - -/** - * Free WSProtocolDecoderInfactory. - * @param context Pointer to a WSProtocolDecoderInfactory instance - */ -void ws_protocol_decoder_infactory_free(void* context); - -/** - * Reset decoder WSProtocolDecoderInfactory. - * @param context Pointer to a WSProtocolDecoderInfactory instance - */ -void ws_protocol_decoder_infactory_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a WSProtocolDecoderInfactory instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void ws_protocol_decoder_infactory_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a WSProtocolDecoderInfactory instance - * @return hash Hash sum - */ -uint8_t ws_protocol_decoder_infactory_get_hash_data(void* context); - -/** - * Serialize data WSProtocolDecoderInfactory. - * @param context Pointer to a WSProtocolDecoderInfactory instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_infactory_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSProtocolDecoderInfactory. - * @param context Pointer to a WSProtocolDecoderInfactory instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus - ws_protocol_decoder_infactory_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a WSProtocolDecoderInfactory instance - * @param output Resulting text - */ -void ws_protocol_decoder_infactory_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/lacrosse_tx.c b/applications/external/weather_station/protocols/lacrosse_tx.c deleted file mode 100644 index f4b850d76..000000000 --- a/applications/external/weather_station/protocols/lacrosse_tx.c +++ /dev/null @@ -1,319 +0,0 @@ -#include "lacrosse_tx.h" - -#define TAG "WSProtocolLaCrosse_TX" - -/* - * Help - * https://github.com/merbanan/rtl_433/blob/master/src/devices/lacrosse.c - * - * - * LaCrosse TX 433 Mhz Temperature and Humidity Sensors. - * - Tested: TX-7U and TX-6U (Temperature only) - * - Not Tested but should work: TX-3, TX-4 - * - also TFA Dostmann 30.3120.90 sensor (for e.g. 35.1018.06 (WS-9015) station) - * - also TFA Dostmann 30.3121 sensor - * Protocol Documentation: http://www.f6fbb.org/domo/sensors/tx3_th.php - * Message is 44 bits, 11 x 4 bit nybbles: - * [00] [cnt = 10] [type] [addr] [addr + parity] [v1] [v2] [v3] [iv1] [iv2] [check] - * Notes: - * - Zero Pulses are longer (1,400 uS High, 1,000 uS Low) = 2,400 uS - * - One Pulses are shorter ( 550 uS High, 1,000 uS Low) = 1,600 uS - * - Sensor id changes when the battery is changed - * - Primary Value are BCD with one decimal place: vvv = 12.3 - * - Secondary value is integer only intval = 12, seems to be a repeat of primary - * This may actually be an additional data check because the 4 bit checksum - * and parity bit is pretty week at detecting errors. - * - Temperature is in Celsius with 50.0 added (to handle negative values) - * - Humidity values appear to be integer precision, decimal always 0. - * - There is a 4 bit checksum and a parity bit covering the three digit value - * - Parity check for TX-3 and TX-4 might be different. - * - Msg sent with one repeat after 30 mS - * - Temperature and humidity are sent as separate messages - * - Frequency for each sensor may be could be off by as much as 50-75 khz - * - LaCrosse Sensors in other frequency ranges (915 Mhz) use FSK not OOK - * so they can't be decoded by rtl_433 currently. - * - Temperature and Humidity are sent in different messages bursts. -*/ - -#define LACROSSE_TX_GAP 1000 -#define LACROSSE_TX_BIT_SIZE 44 -#define LACROSSE_TX_SUNC_PATTERN 0x0A000000000 -#define LACROSSE_TX_SUNC_MASK 0x0F000000000 -#define LACROSSE_TX_MSG_TYPE_TEMP 0x00 -#define LACROSSE_TX_MSG_TYPE_HUM 0x0E - -static const SubGhzBlockConst ws_protocol_lacrosse_tx_const = { - .te_short = 550, - .te_long = 1300, - .te_delta = 120, - .min_count_bit_for_found = 40, -}; - -struct WSProtocolDecoderLaCrosse_TX { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; - - uint16_t header_count; -}; - -struct WSProtocolEncoderLaCrosse_TX { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - WSBlockGeneric generic; -}; - -typedef enum { - LaCrosse_TXDecoderStepReset = 0, - LaCrosse_TXDecoderStepCheckPreambule, - LaCrosse_TXDecoderStepSaveDuration, - LaCrosse_TXDecoderStepCheckDuration, -} LaCrosse_TXDecoderStep; - -const SubGhzProtocolDecoder ws_protocol_lacrosse_tx_decoder = { - .alloc = ws_protocol_decoder_lacrosse_tx_alloc, - .free = ws_protocol_decoder_lacrosse_tx_free, - - .feed = ws_protocol_decoder_lacrosse_tx_feed, - .reset = ws_protocol_decoder_lacrosse_tx_reset, - - .get_hash_data = ws_protocol_decoder_lacrosse_tx_get_hash_data, - .serialize = ws_protocol_decoder_lacrosse_tx_serialize, - .deserialize = ws_protocol_decoder_lacrosse_tx_deserialize, - .get_string = ws_protocol_decoder_lacrosse_tx_get_string, -}; - -const SubGhzProtocolEncoder ws_protocol_lacrosse_tx_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol ws_protocol_lacrosse_tx = { - .name = WS_PROTOCOL_LACROSSE_TX_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_lacrosse_tx_decoder, - .encoder = &ws_protocol_lacrosse_tx_encoder, -}; - -void* ws_protocol_decoder_lacrosse_tx_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderLaCrosse_TX* instance = malloc(sizeof(WSProtocolDecoderLaCrosse_TX)); - instance->base.protocol = &ws_protocol_lacrosse_tx; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void ws_protocol_decoder_lacrosse_tx_free(void* context) { - furi_assert(context); - WSProtocolDecoderLaCrosse_TX* instance = context; - free(instance); -} - -void ws_protocol_decoder_lacrosse_tx_reset(void* context) { - furi_assert(context); - WSProtocolDecoderLaCrosse_TX* instance = context; - instance->header_count = 0; - instance->decoder.parser_step = LaCrosse_TXDecoderStepReset; -} - -static bool ws_protocol_lacrosse_tx_check_crc(WSProtocolDecoderLaCrosse_TX* instance) { - if(!instance->decoder.decode_data) return false; - uint8_t msg[] = { - (instance->decoder.decode_data >> 36) & 0x0F, - (instance->decoder.decode_data >> 32) & 0x0F, - (instance->decoder.decode_data >> 28) & 0x0F, - (instance->decoder.decode_data >> 24) & 0x0F, - (instance->decoder.decode_data >> 20) & 0x0F, - (instance->decoder.decode_data >> 16) & 0x0F, - (instance->decoder.decode_data >> 12) & 0x0F, - (instance->decoder.decode_data >> 8) & 0x0F, - (instance->decoder.decode_data >> 4) & 0x0F}; - - uint8_t crc = subghz_protocol_blocks_add_bytes(msg, 9); - return ((crc & 0x0F) == ((instance->decoder.decode_data) & 0x0F)); -} - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static void ws_protocol_lacrosse_tx_remote_controller(WSBlockGeneric* instance) { - uint8_t msg_type = (instance->data >> 32) & 0x0F; - instance->id = (((instance->data >> 28) & 0x0F) << 3) | (((instance->data >> 24) & 0x0F) >> 1); - - float msg_value = (float)((instance->data >> 20) & 0x0F) * 10.0f + - (float)((instance->data >> 16) & 0x0F) + - (float)((instance->data >> 12) & 0x0F) * 0.1f; - - if(msg_type == LACROSSE_TX_MSG_TYPE_TEMP) { //-V1051 - instance->temp = msg_value - 50.0f; - instance->humidity = WS_NO_HUMIDITY; - } else if(msg_type == LACROSSE_TX_MSG_TYPE_HUM) { - //ToDo for verification, records are needed with sensors maintaining temperature and temperature for this standard - instance->humidity = (uint8_t)msg_value; - } else { - furi_crash("WS: WSProtocolLaCrosse_TX incorrect msg_type."); - } - - instance->btn = WS_NO_BTN; - instance->battery_low = WS_NO_BATT; - instance->channel = WS_NO_CHANNEL; -} - -void ws_protocol_decoder_lacrosse_tx_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderLaCrosse_TX* instance = context; - - switch(instance->decoder.parser_step) { - case LaCrosse_TXDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, LACROSSE_TX_GAP) < - ws_protocol_lacrosse_tx_const.te_delta * 2)) { - instance->decoder.parser_step = LaCrosse_TXDecoderStepCheckPreambule; - instance->header_count = 0; - } - break; - - case LaCrosse_TXDecoderStepCheckPreambule: - - if(level) { - if((DURATION_DIFF(duration, ws_protocol_lacrosse_tx_const.te_short) < - ws_protocol_lacrosse_tx_const.te_delta) && - (instance->header_count > 1)) { - instance->decoder.parser_step = LaCrosse_TXDecoderStepCheckDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->decoder.te_last = duration; - } else if(duration > (ws_protocol_lacrosse_tx_const.te_long * 2)) { - instance->decoder.parser_step = LaCrosse_TXDecoderStepReset; - } - } else { - if(DURATION_DIFF(duration, LACROSSE_TX_GAP) < - ws_protocol_lacrosse_tx_const.te_delta * 2) { - instance->decoder.te_last = duration; - instance->header_count++; - } else { - instance->decoder.parser_step = LaCrosse_TXDecoderStepReset; - } - } - - break; - - case LaCrosse_TXDecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = LaCrosse_TXDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = LaCrosse_TXDecoderStepReset; - } - break; - - case LaCrosse_TXDecoderStepCheckDuration: - - if(!level) { - if(duration > LACROSSE_TX_GAP * 3) { - if(DURATION_DIFF( - instance->decoder.te_last, ws_protocol_lacrosse_tx_const.te_short) < - ws_protocol_lacrosse_tx_const.te_delta) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = LaCrosse_TXDecoderStepSaveDuration; - } else if( - DURATION_DIFF( - instance->decoder.te_last, ws_protocol_lacrosse_tx_const.te_long) < - ws_protocol_lacrosse_tx_const.te_delta) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = LaCrosse_TXDecoderStepSaveDuration; - } - if((instance->decoder.decode_data & LACROSSE_TX_SUNC_MASK) == - LACROSSE_TX_SUNC_PATTERN) { - if(ws_protocol_lacrosse_tx_check_crc(instance)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = LACROSSE_TX_BIT_SIZE; - ws_protocol_lacrosse_tx_remote_controller(&instance->generic); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - } - - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->header_count = 0; - instance->decoder.parser_step = LaCrosse_TXDecoderStepReset; - break; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_lacrosse_tx_const.te_short) < - ws_protocol_lacrosse_tx_const.te_delta) && - (DURATION_DIFF(duration, LACROSSE_TX_GAP) < - ws_protocol_lacrosse_tx_const.te_delta * 2)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = LaCrosse_TXDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_lacrosse_tx_const.te_long) < - ws_protocol_lacrosse_tx_const.te_delta) && - (DURATION_DIFF(duration, LACROSSE_TX_GAP) < - ws_protocol_lacrosse_tx_const.te_delta * 2)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = LaCrosse_TXDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = LaCrosse_TXDecoderStepReset; - } - - } else { - instance->decoder.parser_step = LaCrosse_TXDecoderStepReset; - } - - break; - } -} - -uint8_t ws_protocol_decoder_lacrosse_tx_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderLaCrosse_TX* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_lacrosse_tx_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderLaCrosse_TX* instance = context; - return ws_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus - ws_protocol_decoder_lacrosse_tx_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderLaCrosse_TX* instance = context; - return ws_block_generic_deserialize_check_count_bit( - &instance->generic, flipper_format, ws_protocol_lacrosse_tx_const.min_count_bit_for_found); -} - -void ws_protocol_decoder_lacrosse_tx_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderLaCrosse_TX* instance = context; - furi_string_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%lX Ch:%d Bat:%d\r\n" - "Temp:%3.1f C Hum:%d%%", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data), - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (double)instance->generic.temp, - instance->generic.humidity); -} diff --git a/applications/external/weather_station/protocols/lacrosse_tx.h b/applications/external/weather_station/protocols/lacrosse_tx.h deleted file mode 100644 index 151282b3a..000000000 --- a/applications/external/weather_station/protocols/lacrosse_tx.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "ws_generic.h" -#include - -#define WS_PROTOCOL_LACROSSE_TX_NAME "LaCrosse_TX" - -typedef struct WSProtocolDecoderLaCrosse_TX WSProtocolDecoderLaCrosse_TX; -typedef struct WSProtocolEncoderLaCrosse_TX WSProtocolEncoderLaCrosse_TX; - -extern const SubGhzProtocolDecoder ws_protocol_lacrosse_tx_decoder; -extern const SubGhzProtocolEncoder ws_protocol_lacrosse_tx_encoder; -extern const SubGhzProtocol ws_protocol_lacrosse_tx; - -/** - * Allocate WSProtocolDecoderLaCrosse_TX. - * @param environment Pointer to a SubGhzEnvironment instance - * @return WSProtocolDecoderLaCrosse_TX* pointer to a WSProtocolDecoderLaCrosse_TX instance - */ -void* ws_protocol_decoder_lacrosse_tx_alloc(SubGhzEnvironment* environment); - -/** - * Free WSProtocolDecoderLaCrosse_TX. - * @param context Pointer to a WSProtocolDecoderLaCrosse_TX instance - */ -void ws_protocol_decoder_lacrosse_tx_free(void* context); - -/** - * Reset decoder WSProtocolDecoderLaCrosse_TX. - * @param context Pointer to a WSProtocolDecoderLaCrosse_TX instance - */ -void ws_protocol_decoder_lacrosse_tx_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a WSProtocolDecoderLaCrosse_TX instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void ws_protocol_decoder_lacrosse_tx_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a WSProtocolDecoderLaCrosse_TX instance - * @return hash Hash sum - */ -uint8_t ws_protocol_decoder_lacrosse_tx_get_hash_data(void* context); - -/** - * Serialize data WSProtocolDecoderLaCrosse_TX. - * @param context Pointer to a WSProtocolDecoderLaCrosse_TX instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_lacrosse_tx_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSProtocolDecoderLaCrosse_TX. - * @param context Pointer to a WSProtocolDecoderLaCrosse_TX instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus - ws_protocol_decoder_lacrosse_tx_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a WSProtocolDecoderLaCrosse_TX instance - * @param output Resulting text - */ -void ws_protocol_decoder_lacrosse_tx_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/lacrosse_tx141thbv2.c b/applications/external/weather_station/protocols/lacrosse_tx141thbv2.c deleted file mode 100644 index f2fddd40c..000000000 --- a/applications/external/weather_station/protocols/lacrosse_tx141thbv2.c +++ /dev/null @@ -1,294 +0,0 @@ -#include "lacrosse_tx141thbv2.h" - -#define TAG "WSProtocolLaCrosse_TX141THBv2" - -#define LACROSSE_TX141TH_BV2_BIT_COUNT 41 - -/* - * Help - * https://github.com/merbanan/rtl_433/blob/master/src/devices/lacrosse_tx141x.c - * - * iiii iiii | bkcc tttt | tttt tttt | hhhh hhhh | cccc cccc | u - 41 bit - * or - * iiii iiii | bkcc tttt | tttt tttt | hhhh hhhh | cccc cccc | -40 bit - * - i: identification; changes on battery switch - * - c: lfsr_digest8_reflect; - * - u: unknown; - * - b: battery low; flag to indicate low battery voltage - * - h: Humidity; - * - t: Temperature; in °F as binary number with one decimal place + 50 °F offset - * - n: Channel; Channel number 1 - 3 - */ - -static const SubGhzBlockConst ws_protocol_lacrosse_tx141thbv2_const = { - .te_short = 208, - .te_long = 417, - .te_delta = 120, - .min_count_bit_for_found = 40, -}; - -struct WSProtocolDecoderLaCrosse_TX141THBv2 { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; - - uint16_t header_count; -}; - -struct WSProtocolEncoderLaCrosse_TX141THBv2 { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - WSBlockGeneric generic; -}; - -typedef enum { - LaCrosse_TX141THBv2DecoderStepReset = 0, - LaCrosse_TX141THBv2DecoderStepCheckPreambule, - LaCrosse_TX141THBv2DecoderStepSaveDuration, - LaCrosse_TX141THBv2DecoderStepCheckDuration, -} LaCrosse_TX141THBv2DecoderStep; - -const SubGhzProtocolDecoder ws_protocol_lacrosse_tx141thbv2_decoder = { - .alloc = ws_protocol_decoder_lacrosse_tx141thbv2_alloc, - .free = ws_protocol_decoder_lacrosse_tx141thbv2_free, - - .feed = ws_protocol_decoder_lacrosse_tx141thbv2_feed, - .reset = ws_protocol_decoder_lacrosse_tx141thbv2_reset, - - .get_hash_data = ws_protocol_decoder_lacrosse_tx141thbv2_get_hash_data, - .serialize = ws_protocol_decoder_lacrosse_tx141thbv2_serialize, - .deserialize = ws_protocol_decoder_lacrosse_tx141thbv2_deserialize, - .get_string = ws_protocol_decoder_lacrosse_tx141thbv2_get_string, -}; - -const SubGhzProtocolEncoder ws_protocol_lacrosse_tx141thbv2_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol ws_protocol_lacrosse_tx141thbv2 = { - .name = WS_PROTOCOL_LACROSSE_TX141THBV2_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_lacrosse_tx141thbv2_decoder, - .encoder = &ws_protocol_lacrosse_tx141thbv2_encoder, -}; - -void* ws_protocol_decoder_lacrosse_tx141thbv2_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderLaCrosse_TX141THBv2* instance = - malloc(sizeof(WSProtocolDecoderLaCrosse_TX141THBv2)); - instance->base.protocol = &ws_protocol_lacrosse_tx141thbv2; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void ws_protocol_decoder_lacrosse_tx141thbv2_free(void* context) { - furi_assert(context); - WSProtocolDecoderLaCrosse_TX141THBv2* instance = context; - free(instance); -} - -void ws_protocol_decoder_lacrosse_tx141thbv2_reset(void* context) { - furi_assert(context); - WSProtocolDecoderLaCrosse_TX141THBv2* instance = context; - instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepReset; -} - -static bool - ws_protocol_lacrosse_tx141thbv2_check_crc(WSProtocolDecoderLaCrosse_TX141THBv2* instance) { - if(!instance->decoder.decode_data) return false; - uint64_t data = instance->decoder.decode_data; - if(instance->decoder.decode_count_bit == LACROSSE_TX141TH_BV2_BIT_COUNT) { - data >>= 1; - } - uint8_t msg[] = {data >> 32, data >> 24, data >> 16, data >> 8}; - - uint8_t crc = subghz_protocol_blocks_lfsr_digest8_reflect(msg, 4, 0x31, 0xF4); - return (crc == (data & 0xFF)); -} - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static void ws_protocol_lacrosse_tx141thbv2_remote_controller(WSBlockGeneric* instance) { - uint64_t data = instance->data; - if(instance->data_count_bit == LACROSSE_TX141TH_BV2_BIT_COUNT) { - data >>= 1; - } - instance->id = data >> 32; - instance->battery_low = (data >> 31) & 1; - instance->btn = (data >> 30) & 1; - instance->channel = ((data >> 28) & 0x03) + 1; - instance->temp = ((float)((data >> 16) & 0x0FFF) - 500.0f) / 10.0f; - instance->humidity = (data >> 8) & 0xFF; -} - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static bool ws_protocol_decoder_lacrosse_tx141thbv2_add_bit( - WSProtocolDecoderLaCrosse_TX141THBv2* instance, - uint32_t te_last, - uint32_t te_current) { - furi_assert(instance); - bool ret = false; - if(DURATION_DIFF( - te_last + te_current, - ws_protocol_lacrosse_tx141thbv2_const.te_short + - ws_protocol_lacrosse_tx141thbv2_const.te_long) < - ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2) { - if(te_last > te_current) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - } else { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - } - ret = true; - } - - return ret; -} -void ws_protocol_decoder_lacrosse_tx141thbv2_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderLaCrosse_TX141THBv2* instance = context; - - switch(instance->decoder.parser_step) { - case LaCrosse_TX141THBv2DecoderStepReset: - if((level) && - (DURATION_DIFF(duration, ws_protocol_lacrosse_tx141thbv2_const.te_short * 4) < - ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2)) { - instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepCheckPreambule; - instance->decoder.te_last = duration; - instance->header_count = 0; - } - break; - - case LaCrosse_TX141THBv2DecoderStepCheckPreambule: - if(level) { - instance->decoder.te_last = duration; - } else { - if((DURATION_DIFF( - instance->decoder.te_last, - ws_protocol_lacrosse_tx141thbv2_const.te_short * 4) < - ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2) && - (DURATION_DIFF(duration, ws_protocol_lacrosse_tx141thbv2_const.te_short * 4) < - ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2)) { - //Found preambule - instance->header_count++; - } else if(instance->header_count == 4) { - if(ws_protocol_decoder_lacrosse_tx141thbv2_add_bit( - instance, instance->decoder.te_last, duration)) { - instance->decoder.decode_data = instance->decoder.decode_data & 1; - instance->decoder.decode_count_bit = 1; - instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepSaveDuration; - } else { - instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepReset; - } - } else { - instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepReset; - } - } - break; - - case LaCrosse_TX141THBv2DecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepCheckDuration; - } else { - instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepReset; - } - break; - - case LaCrosse_TX141THBv2DecoderStepCheckDuration: - if(!level) { - if(((DURATION_DIFF( - instance->decoder.te_last, - ws_protocol_lacrosse_tx141thbv2_const.te_short * 3) < - ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2) && - (DURATION_DIFF(duration, ws_protocol_lacrosse_tx141thbv2_const.te_short * 4) < - ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2))) { - if((instance->decoder.decode_count_bit == - ws_protocol_lacrosse_tx141thbv2_const.min_count_bit_for_found) || - (instance->decoder.decode_count_bit == LACROSSE_TX141TH_BV2_BIT_COUNT)) { - if(ws_protocol_lacrosse_tx141thbv2_check_crc(instance)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - ws_protocol_lacrosse_tx141thbv2_remote_controller(&instance->generic); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->header_count = 1; - instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepCheckPreambule; - break; - } - } else if(ws_protocol_decoder_lacrosse_tx141thbv2_add_bit( - instance, instance->decoder.te_last, duration)) { - instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepSaveDuration; - } else { - instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepReset; - } - } else { - instance->decoder.parser_step = LaCrosse_TX141THBv2DecoderStepReset; - } - break; - } -} - -uint8_t ws_protocol_decoder_lacrosse_tx141thbv2_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderLaCrosse_TX141THBv2* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_lacrosse_tx141thbv2_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderLaCrosse_TX141THBv2* instance = context; - return ws_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus ws_protocol_decoder_lacrosse_tx141thbv2_deserialize( - void* context, - FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderLaCrosse_TX141THBv2* instance = context; - return ws_block_generic_deserialize_check_count_bit( - &instance->generic, - flipper_format, - ws_protocol_lacrosse_tx141thbv2_const.min_count_bit_for_found); -} - -void ws_protocol_decoder_lacrosse_tx141thbv2_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderLaCrosse_TX141THBv2* instance = context; - furi_string_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%lX Ch:%d Bat:%d\r\n" - "Temp:%3.1f C Hum:%d%%", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data), - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (double)instance->generic.temp, - instance->generic.humidity); -} diff --git a/applications/external/weather_station/protocols/lacrosse_tx141thbv2.h b/applications/external/weather_station/protocols/lacrosse_tx141thbv2.h deleted file mode 100644 index 036db0548..000000000 --- a/applications/external/weather_station/protocols/lacrosse_tx141thbv2.h +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "ws_generic.h" -#include - -#define WS_PROTOCOL_LACROSSE_TX141THBV2_NAME "TX141THBv2" - -typedef struct WSProtocolDecoderLaCrosse_TX141THBv2 WSProtocolDecoderLaCrosse_TX141THBv2; -typedef struct WSProtocolEncoderLaCrosse_TX141THBv2 WSProtocolEncoderLaCrosse_TX141THBv2; - -extern const SubGhzProtocolDecoder ws_protocol_lacrosse_tx141thbv2_decoder; -extern const SubGhzProtocolEncoder ws_protocol_lacrosse_tx141thbv2_encoder; -extern const SubGhzProtocol ws_protocol_lacrosse_tx141thbv2; - -/** - * Allocate WSProtocolDecoderLaCrosse_TX141THBv2. - * @param environment Pointer to a SubGhzEnvironment instance - * @return WSProtocolDecoderLaCrosse_TX141THBv2* pointer to a WSProtocolDecoderLaCrosse_TX141THBv2 instance - */ -void* ws_protocol_decoder_lacrosse_tx141thbv2_alloc(SubGhzEnvironment* environment); - -/** - * Free WSProtocolDecoderLaCrosse_TX141THBv2. - * @param context Pointer to a WSProtocolDecoderLaCrosse_TX141THBv2 instance - */ -void ws_protocol_decoder_lacrosse_tx141thbv2_free(void* context); - -/** - * Reset decoder WSProtocolDecoderLaCrosse_TX141THBv2. - * @param context Pointer to a WSProtocolDecoderLaCrosse_TX141THBv2 instance - */ -void ws_protocol_decoder_lacrosse_tx141thbv2_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a WSProtocolDecoderLaCrosse_TX141THBv2 instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void ws_protocol_decoder_lacrosse_tx141thbv2_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a WSProtocolDecoderLaCrosse_TX141THBv2 instance - * @return hash Hash sum - */ -uint8_t ws_protocol_decoder_lacrosse_tx141thbv2_get_hash_data(void* context); - -/** - * Serialize data WSProtocolDecoderLaCrosse_TX141THBv2. - * @param context Pointer to a WSProtocolDecoderLaCrosse_TX141THBv2 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_lacrosse_tx141thbv2_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSProtocolDecoderLaCrosse_TX141THBv2. - * @param context Pointer to a WSProtocolDecoderLaCrosse_TX141THBv2 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_lacrosse_tx141thbv2_deserialize( - void* context, - FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a WSProtocolDecoderLaCrosse_TX141THBv2 instance - * @param output Resulting text - */ -void ws_protocol_decoder_lacrosse_tx141thbv2_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/nexus_th.c b/applications/external/weather_station/protocols/nexus_th.c deleted file mode 100644 index 14ba8b273..000000000 --- a/applications/external/weather_station/protocols/nexus_th.c +++ /dev/null @@ -1,254 +0,0 @@ -#include "nexus_th.h" - -#define TAG "WSProtocolNexus_TH" - -/* - * Help - * https://github.com/merbanan/rtl_433/blob/master/src/devices/nexus.c - * - * Nexus sensor protocol with ID, temperature and optional humidity - * also FreeTec (Pearl) NC-7345 sensors for FreeTec Weatherstation NC-7344, - * also infactory/FreeTec (Pearl) NX-3980 sensors for infactory/FreeTec NX-3974 station, - * also Solight TE82S sensors for Solight TE76/TE82/TE83/TE84 stations, - * also TFA 30.3209.02 temperature/humidity sensor. - * The sensor sends 36 bits 12 times, - * the packets are ppm modulated (distance coding) with a pulse of ~500 us - * followed by a short gap of ~1000 us for a 0 bit or a long ~2000 us gap for a - * 1 bit, the sync gap is ~4000 us. - * The data is grouped in 9 nibbles: - * [id0] [id1] [flags] [temp0] [temp1] [temp2] [const] [humi0] [humi1] - * - The 8-bit id changes when the battery is changed in the sensor. - * - flags are 4 bits B 0 C C, where B is the battery status: 1=OK, 0=LOW - * - and CC is the channel: 0=CH1, 1=CH2, 2=CH3 - * - temp is 12 bit signed scaled by 10 - * - const is always 1111 (0x0F) - * - humidity is 8 bits - * The sensors can be bought at Clas Ohlsen (Nexus) and Pearl (infactory/FreeTec). - * - */ - -#define NEXUS_TH_CONST_DATA 0b1111 - -static const SubGhzBlockConst ws_protocol_nexus_th_const = { - .te_short = 500, - .te_long = 2000, - .te_delta = 150, - .min_count_bit_for_found = 36, -}; - -struct WSProtocolDecoderNexus_TH { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; -}; - -struct WSProtocolEncoderNexus_TH { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - WSBlockGeneric generic; -}; - -typedef enum { - Nexus_THDecoderStepReset = 0, - Nexus_THDecoderStepSaveDuration, - Nexus_THDecoderStepCheckDuration, -} Nexus_THDecoderStep; - -const SubGhzProtocolDecoder ws_protocol_nexus_th_decoder = { - .alloc = ws_protocol_decoder_nexus_th_alloc, - .free = ws_protocol_decoder_nexus_th_free, - - .feed = ws_protocol_decoder_nexus_th_feed, - .reset = ws_protocol_decoder_nexus_th_reset, - - .get_hash_data = ws_protocol_decoder_nexus_th_get_hash_data, - .serialize = ws_protocol_decoder_nexus_th_serialize, - .deserialize = ws_protocol_decoder_nexus_th_deserialize, - .get_string = ws_protocol_decoder_nexus_th_get_string, -}; - -const SubGhzProtocolEncoder ws_protocol_nexus_th_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol ws_protocol_nexus_th = { - .name = WS_PROTOCOL_NEXUS_TH_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_nexus_th_decoder, - .encoder = &ws_protocol_nexus_th_encoder, -}; - -void* ws_protocol_decoder_nexus_th_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderNexus_TH* instance = malloc(sizeof(WSProtocolDecoderNexus_TH)); - instance->base.protocol = &ws_protocol_nexus_th; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void ws_protocol_decoder_nexus_th_free(void* context) { - furi_assert(context); - WSProtocolDecoderNexus_TH* instance = context; - free(instance); -} - -void ws_protocol_decoder_nexus_th_reset(void* context) { - furi_assert(context); - WSProtocolDecoderNexus_TH* instance = context; - instance->decoder.parser_step = Nexus_THDecoderStepReset; -} - -static bool ws_protocol_nexus_th_check(WSProtocolDecoderNexus_TH* instance) { - uint8_t type = (instance->decoder.decode_data >> 8) & 0x0F; - - if((type == NEXUS_TH_CONST_DATA) && ((instance->decoder.decode_data >> 4) != 0xffffffff)) { - return true; - } else { - return false; - } - return true; -} - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static void ws_protocol_nexus_th_remote_controller(WSBlockGeneric* instance) { - instance->id = (instance->data >> 28) & 0xFF; - instance->battery_low = !((instance->data >> 27) & 1); - instance->channel = ((instance->data >> 24) & 0x03) + 1; - instance->btn = WS_NO_BTN; - if(!((instance->data >> 23) & 1)) { - instance->temp = (float)((instance->data >> 12) & 0x07FF) / 10.0f; - } else { - instance->temp = (float)((~(instance->data >> 12) & 0x07FF) + 1) / -10.0f; - } - - instance->humidity = instance->data & 0xFF; - if(instance->humidity > 95) - instance->humidity = 95; - else if(instance->humidity < 20) - instance->humidity = 20; -} - -void ws_protocol_decoder_nexus_th_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderNexus_TH* instance = context; - - switch(instance->decoder.parser_step) { - case Nexus_THDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, ws_protocol_nexus_th_const.te_short * 8) < - ws_protocol_nexus_th_const.te_delta * 4)) { - //Found sync - instance->decoder.parser_step = Nexus_THDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } - break; - - case Nexus_THDecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = Nexus_THDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = Nexus_THDecoderStepReset; - } - break; - - case Nexus_THDecoderStepCheckDuration: - if(!level) { - if(DURATION_DIFF(duration, ws_protocol_nexus_th_const.te_short * 8) < - ws_protocol_nexus_th_const.te_delta * 4) { - //Found sync - instance->decoder.parser_step = Nexus_THDecoderStepReset; - if((instance->decoder.decode_count_bit == - ws_protocol_nexus_th_const.min_count_bit_for_found) && - ws_protocol_nexus_th_check(instance)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - ws_protocol_nexus_th_remote_controller(&instance->generic); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - instance->decoder.parser_step = Nexus_THDecoderStepCheckDuration; - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - - break; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_nexus_th_const.te_short) < - ws_protocol_nexus_th_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_nexus_th_const.te_short * 2) < - ws_protocol_nexus_th_const.te_delta * 2)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = Nexus_THDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_nexus_th_const.te_short) < - ws_protocol_nexus_th_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_nexus_th_const.te_short * 4) < - ws_protocol_nexus_th_const.te_delta * 4)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = Nexus_THDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = Nexus_THDecoderStepReset; - } - } else { - instance->decoder.parser_step = Nexus_THDecoderStepReset; - } - break; - } -} - -uint8_t ws_protocol_decoder_nexus_th_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderNexus_TH* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_nexus_th_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderNexus_TH* instance = context; - return ws_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus - ws_protocol_decoder_nexus_th_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderNexus_TH* instance = context; - return ws_block_generic_deserialize_check_count_bit( - &instance->generic, flipper_format, ws_protocol_nexus_th_const.min_count_bit_for_found); -} - -void ws_protocol_decoder_nexus_th_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderNexus_TH* instance = context; - furi_string_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%lX Ch:%d Bat:%d\r\n" - "Temp:%3.1f C Hum:%d%%", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data), - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (double)instance->generic.temp, - instance->generic.humidity); -} diff --git a/applications/external/weather_station/protocols/nexus_th.h b/applications/external/weather_station/protocols/nexus_th.h deleted file mode 100644 index 6c2715b85..000000000 --- a/applications/external/weather_station/protocols/nexus_th.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "ws_generic.h" -#include - -#define WS_PROTOCOL_NEXUS_TH_NAME "Nexus-TH" - -typedef struct WSProtocolDecoderNexus_TH WSProtocolDecoderNexus_TH; -typedef struct WSProtocolEncoderNexus_TH WSProtocolEncoderNexus_TH; - -extern const SubGhzProtocolDecoder ws_protocol_nexus_th_decoder; -extern const SubGhzProtocolEncoder ws_protocol_nexus_th_encoder; -extern const SubGhzProtocol ws_protocol_nexus_th; - -/** - * Allocate WSProtocolDecoderNexus_TH. - * @param environment Pointer to a SubGhzEnvironment instance - * @return WSProtocolDecoderNexus_TH* pointer to a WSProtocolDecoderNexus_TH instance - */ -void* ws_protocol_decoder_nexus_th_alloc(SubGhzEnvironment* environment); - -/** - * Free WSProtocolDecoderNexus_TH. - * @param context Pointer to a WSProtocolDecoderNexus_TH instance - */ -void ws_protocol_decoder_nexus_th_free(void* context); - -/** - * Reset decoder WSProtocolDecoderNexus_TH. - * @param context Pointer to a WSProtocolDecoderNexus_TH instance - */ -void ws_protocol_decoder_nexus_th_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a WSProtocolDecoderNexus_TH instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void ws_protocol_decoder_nexus_th_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a WSProtocolDecoderNexus_TH instance - * @return hash Hash sum - */ -uint8_t ws_protocol_decoder_nexus_th_get_hash_data(void* context); - -/** - * Serialize data WSProtocolDecoderNexus_TH. - * @param context Pointer to a WSProtocolDecoderNexus_TH instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_nexus_th_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSProtocolDecoderNexus_TH. - * @param context Pointer to a WSProtocolDecoderNexus_TH instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus - ws_protocol_decoder_nexus_th_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a WSProtocolDecoderNexus_TH instance - * @param output Resulting text - */ -void ws_protocol_decoder_nexus_th_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/oregon2.c b/applications/external/weather_station/protocols/oregon2.c deleted file mode 100644 index 313748ccf..000000000 --- a/applications/external/weather_station/protocols/oregon2.c +++ /dev/null @@ -1,429 +0,0 @@ -#include "oregon2.h" - -#include -#include -#include -#include -#include "ws_generic.h" - -#include -#include - -#define TAG "WSProtocolOregon2" - -static const SubGhzBlockConst ws_oregon2_const = { - .te_long = 1000, - .te_short = 500, - .te_delta = 200, - .min_count_bit_for_found = 32, -}; - -#define OREGON2_PREAMBLE_BITS 19 -#define OREGON2_PREAMBLE_MASK 0b1111111111111111111 -#define OREGON2_SENSOR_ID(d) (((d) >> 16) & 0xFFFF) -#define OREGON2_CHECKSUM_BITS 8 - -// 15 ones + 0101 (inverted A) -#define OREGON2_PREAMBLE 0b1111111111111110101 - -// bit indicating the low battery -#define OREGON2_FLAG_BAT_LOW 0x4 - -/// Documentation for Oregon Scientific protocols can be found here: -/// http://wmrx00.sourceforge.net/Arduino/OregonScientific-RF-Protocols.pdf -// Sensors ID -#define ID_THGR122N 0x1d20 -#define ID_THGR968 0x1d30 -#define ID_BTHR918 0x5d50 -#define ID_BHTR968 0x5d60 -#define ID_RGR968 0x2d10 -#define ID_THR228N 0xec40 -#define ID_THN132N 0xec40 // same as THR228N but different packet size -#define ID_RTGN318 0x0cc3 // warning: id is from 0x0cc3 and 0xfcc3 -#define ID_RTGN129 0x0cc3 // same as RTGN318 but different packet size -#define ID_THGR810 0xf824 // This might be ID_THGR81, but what's true is lost in (git) history -#define ID_THGR810a 0xf8b4 // unconfirmed version -#define ID_THN802 0xc844 -#define ID_PCR800 0x2914 -#define ID_PCR800a 0x2d14 // Different PCR800 ID - AU version I think -#define ID_WGR800 0x1984 -#define ID_WGR800a 0x1994 // unconfirmed version -#define ID_WGR968 0x3d00 -#define ID_UV800 0xd874 -#define ID_THN129 0xcc43 // THN129 Temp only -#define ID_RTHN129 0x0cd3 // RTHN129 Temp, clock sensors -#define ID_RTHN129_1 0x9cd3 -#define ID_RTHN129_2 0xacd3 -#define ID_RTHN129_3 0xbcd3 -#define ID_RTHN129_4 0xccd3 -#define ID_RTHN129_5 0xdcd3 -#define ID_BTHGN129 0x5d53 // Baro, Temp, Hygro sensor -#define ID_UVR128 0xec70 -#define ID_THGR328N 0xcc23 // Temp & Hygro sensor similar to THR228N with 5 channel instead of 3 -#define ID_RTGR328N_1 0xdcc3 // RTGR328N_[1-5] RFclock(date &time)&Temp&Hygro sensor -#define ID_RTGR328N_2 0xccc3 -#define ID_RTGR328N_3 0xbcc3 -#define ID_RTGR328N_4 0xacc3 -#define ID_RTGR328N_5 0x9cc3 -#define ID_RTGR328N_6 0x8ce3 // RTGR328N_6&7 RFclock(date &time)&Temp&Hygro sensor like THGR328N -#define ID_RTGR328N_7 0x8ae3 - -struct WSProtocolDecoderOregon2 { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; - ManchesterState manchester_state; - bool prev_bit; - bool have_bit; - - uint8_t var_bits; - uint32_t var_data; -}; - -typedef struct WSProtocolDecoderOregon2 WSProtocolDecoderOregon2; - -typedef enum { - Oregon2DecoderStepReset = 0, - Oregon2DecoderStepFoundPreamble, - Oregon2DecoderStepVarData, -} Oregon2DecoderStep; - -void* ws_protocol_decoder_oregon2_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderOregon2* instance = malloc(sizeof(WSProtocolDecoderOregon2)); - instance->base.protocol = &ws_protocol_oregon2; - instance->generic.protocol_name = instance->base.protocol->name; - instance->generic.humidity = WS_NO_HUMIDITY; - instance->generic.temp = WS_NO_TEMPERATURE; - instance->generic.btn = WS_NO_BTN; - instance->generic.channel = WS_NO_CHANNEL; - instance->generic.battery_low = WS_NO_BATT; - instance->generic.id = WS_NO_ID; - return instance; -} - -void ws_protocol_decoder_oregon2_free(void* context) { - furi_assert(context); - WSProtocolDecoderOregon2* instance = context; - free(instance); -} - -void ws_protocol_decoder_oregon2_reset(void* context) { - furi_assert(context); - WSProtocolDecoderOregon2* instance = context; - instance->decoder.parser_step = Oregon2DecoderStepReset; - instance->decoder.decode_data = 0UL; - instance->decoder.decode_count_bit = 0; - manchester_advance( - instance->manchester_state, ManchesterEventReset, &instance->manchester_state, NULL); - instance->have_bit = false; - instance->var_data = 0; - instance->var_bits = 0; -} - -static ManchesterEvent level_and_duration_to_event(bool level, uint32_t duration) { - bool is_long = false; - - if(DURATION_DIFF(duration, ws_oregon2_const.te_long) < ws_oregon2_const.te_delta) { - is_long = true; - } else if(DURATION_DIFF(duration, ws_oregon2_const.te_short) < ws_oregon2_const.te_delta) { - is_long = false; - } else { - return ManchesterEventReset; - } - - if(level) - return is_long ? ManchesterEventLongHigh : ManchesterEventShortHigh; - else - return is_long ? ManchesterEventLongLow : ManchesterEventShortLow; -} - -// From sensor id code return amount of bits in variable section -// https://temofeev.ru/info/articles/o-dekodirovanii-protokola-pogodnykh-datchikov-oregon-scientific -static uint8_t oregon2_sensor_id_var_bits(uint16_t sensor_id) { - switch(sensor_id) { - case ID_THR228N: - case ID_RTHN129_1: - case ID_RTHN129_2: - case ID_RTHN129_3: - case ID_RTHN129_4: - case ID_RTHN129_5: - return 16; - case ID_THGR122N: - return 24; - default: - return 0; - } -} - -static void ws_oregon2_decode_const_data(WSBlockGeneric* ws_block) { - ws_block->id = OREGON2_SENSOR_ID(ws_block->data); - - uint8_t ch_bits = (ws_block->data >> 12) & 0xF; - ws_block->channel = 1; - while(ch_bits > 1) { - ws_block->channel++; - ch_bits >>= 1; - } - - ws_block->battery_low = (ws_block->data & OREGON2_FLAG_BAT_LOW) ? 1 : 0; -} - -uint16_t bcd_decode_short(uint32_t data) { - return (data & 0xF) * 10 + ((data >> 4) & 0xF); -} - -static float ws_oregon2_decode_temp(uint32_t data) { - int32_t temp_val; - temp_val = bcd_decode_short(data >> 4); - temp_val *= 10; - temp_val += (data >> 12) & 0xF; - if(data & 0xF) temp_val = -temp_val; - return (float)temp_val / 10.0; -} - -static void ws_oregon2_decode_var_data(WSBlockGeneric* ws_b, uint16_t sensor_id, uint32_t data) { - switch(sensor_id) { - case ID_THR228N: - case ID_RTHN129_1: - case ID_RTHN129_2: - case ID_RTHN129_3: - case ID_RTHN129_4: - case ID_RTHN129_5: - ws_b->temp = ws_oregon2_decode_temp(data); - ws_b->humidity = WS_NO_HUMIDITY; - return; - case ID_THGR122N: - ws_b->humidity = bcd_decode_short(data); - ws_b->temp = ws_oregon2_decode_temp(data >> 8); - return; - default: - break; - } -} - -void ws_protocol_decoder_oregon2_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderOregon2* instance = context; - // oregon v2.1 signal is inverted - ManchesterEvent event = level_and_duration_to_event(!level, duration); - bool data; - - // low-level bit sequence decoding - if(event == ManchesterEventReset) { - instance->decoder.parser_step = Oregon2DecoderStepReset; - instance->have_bit = false; - instance->decoder.decode_data = 0UL; - instance->decoder.decode_count_bit = 0; - } - if(manchester_advance(instance->manchester_state, event, &instance->manchester_state, &data)) { - if(instance->have_bit) { - if(!instance->prev_bit && data) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - } else if(instance->prev_bit && !data) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - } else { - ws_protocol_decoder_oregon2_reset(context); - } - instance->have_bit = false; - } else { - instance->prev_bit = data; - instance->have_bit = true; - } - } - - switch(instance->decoder.parser_step) { - case Oregon2DecoderStepReset: - // waiting for fixed oregon2 preamble - if(instance->decoder.decode_count_bit >= OREGON2_PREAMBLE_BITS && - ((instance->decoder.decode_data & OREGON2_PREAMBLE_MASK) == OREGON2_PREAMBLE)) { - instance->decoder.parser_step = Oregon2DecoderStepFoundPreamble; - instance->decoder.decode_count_bit = 0; - instance->decoder.decode_data = 0UL; - } - break; - case Oregon2DecoderStepFoundPreamble: - // waiting for fixed oregon2 data - if(instance->decoder.decode_count_bit == 32) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - instance->decoder.decode_data = 0UL; - instance->decoder.decode_count_bit = 0; - - // reverse nibbles in decoded data - instance->generic.data = (instance->generic.data & 0x55555555) << 1 | - (instance->generic.data & 0xAAAAAAAA) >> 1; - instance->generic.data = (instance->generic.data & 0x33333333) << 2 | - (instance->generic.data & 0xCCCCCCCC) >> 2; - - ws_oregon2_decode_const_data(&instance->generic); - instance->var_bits = - oregon2_sensor_id_var_bits(OREGON2_SENSOR_ID(instance->generic.data)); - - if(!instance->var_bits) { - // sensor is not supported, stop decoding, but showing the decoded fixed part - instance->decoder.parser_step = Oregon2DecoderStepReset; - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } else { - instance->decoder.parser_step = Oregon2DecoderStepVarData; - } - } - break; - case Oregon2DecoderStepVarData: - // waiting for variable (sensor-specific data) - if(instance->decoder.decode_count_bit == instance->var_bits + OREGON2_CHECKSUM_BITS) { - instance->var_data = instance->decoder.decode_data & 0xFFFFFFFF; - - // reverse nibbles in var data - instance->var_data = (instance->var_data & 0x55555555) << 1 | - (instance->var_data & 0xAAAAAAAA) >> 1; - instance->var_data = (instance->var_data & 0x33333333) << 2 | - (instance->var_data & 0xCCCCCCCC) >> 2; - - ws_oregon2_decode_var_data( - &instance->generic, - OREGON2_SENSOR_ID(instance->generic.data), - instance->var_data >> OREGON2_CHECKSUM_BITS); - - instance->decoder.parser_step = Oregon2DecoderStepReset; - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - break; - } -} - -uint8_t ws_protocol_decoder_oregon2_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderOregon2* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_oregon2_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderOregon2* instance = context; - SubGhzProtocolStatus ret = SubGhzProtocolStatusError; - ret = ws_block_generic_serialize(&instance->generic, flipper_format, preset); - if(ret != SubGhzProtocolStatusOk) return ret; - uint32_t temp = instance->var_bits; - if(!flipper_format_write_uint32(flipper_format, "VarBits", &temp, 1)) { - FURI_LOG_E(TAG, "Error adding VarBits"); - return SubGhzProtocolStatusErrorParserOthers; - } - if(!flipper_format_write_hex( - flipper_format, - "VarData", - (const uint8_t*)&instance->var_data, - sizeof(instance->var_data))) { - FURI_LOG_E(TAG, "Error adding VarData"); - return SubGhzProtocolStatusErrorParserOthers; - } - return ret; -} - -SubGhzProtocolStatus - ws_protocol_decoder_oregon2_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderOregon2* instance = context; - uint32_t temp_data; - SubGhzProtocolStatus ret = SubGhzProtocolStatusError; - do { - ret = ws_block_generic_deserialize(&instance->generic, flipper_format); - if(ret != SubGhzProtocolStatusOk) { - break; - } - if(!flipper_format_read_uint32(flipper_format, "VarBits", &temp_data, 1)) { - FURI_LOG_E(TAG, "Missing VarLen"); - ret = SubGhzProtocolStatusErrorParserOthers; - break; - } - instance->var_bits = (uint8_t)temp_data; - if(!flipper_format_read_hex( - flipper_format, - "VarData", - (uint8_t*)&instance->var_data, - sizeof(instance->var_data))) { //-V1051 - FURI_LOG_E(TAG, "Missing VarData"); - ret = SubGhzProtocolStatusErrorParserOthers; - break; - } - if(instance->generic.data_count_bit != ws_oregon2_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key: %d", instance->generic.data_count_bit); - ret = SubGhzProtocolStatusErrorValueBitCount; - break; - } - } while(false); - return ret; -} - -static void oregon2_append_check_sum(uint32_t fix_data, uint32_t var_data, FuriString* output) { - uint8_t sum = fix_data & 0xF; - uint8_t ref_sum = var_data & 0xFF; - var_data >>= 8; - - for(uint8_t i = 1; i < 8; i++) { - fix_data >>= 4; - var_data >>= 4; - sum += (fix_data & 0xF) + (var_data & 0xF); - } - - // swap calculated sum nibbles - sum = (((sum >> 4) & 0xF) | (sum << 4)) & 0xFF; - if(sum == ref_sum) - furi_string_cat_printf(output, "Sum ok: 0x%hhX", ref_sum); - else - furi_string_cat_printf(output, "Sum err: 0x%hhX vs 0x%hhX", ref_sum, sum); -} - -void ws_protocol_decoder_oregon2_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderOregon2* instance = context; - furi_string_cat_printf( - output, - "%s\r\n" - "ID: 0x%04lX, ch: %d, bat: %d, rc: 0x%02lX\r\n", - instance->generic.protocol_name, - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (uint32_t)(instance->generic.data >> 4) & 0xFF); - - if(instance->var_bits > 0) { - furi_string_cat_printf( - output, - "Temp:%d.%d C Hum:%d%%", - (int16_t)instance->generic.temp, - abs( - ((int16_t)(instance->generic.temp * 10) - - (((int16_t)instance->generic.temp) * 10))), - instance->generic.humidity); - oregon2_append_check_sum((uint32_t)instance->generic.data, instance->var_data, output); - } -} - -const SubGhzProtocolDecoder ws_protocol_oregon2_decoder = { - .alloc = ws_protocol_decoder_oregon2_alloc, - .free = ws_protocol_decoder_oregon2_free, - - .feed = ws_protocol_decoder_oregon2_feed, - .reset = ws_protocol_decoder_oregon2_reset, - - .get_hash_data = ws_protocol_decoder_oregon2_get_hash_data, - .serialize = ws_protocol_decoder_oregon2_serialize, - .deserialize = ws_protocol_decoder_oregon2_deserialize, - .get_string = ws_protocol_decoder_oregon2_get_string, -}; - -const SubGhzProtocol ws_protocol_oregon2 = { - .name = WS_PROTOCOL_OREGON2_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_oregon2_decoder, -}; diff --git a/applications/external/weather_station/protocols/oregon2.h b/applications/external/weather_station/protocols/oregon2.h deleted file mode 100644 index cfe938e6d..000000000 --- a/applications/external/weather_station/protocols/oregon2.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include - -#define WS_PROTOCOL_OREGON2_NAME "Oregon2" -extern const SubGhzProtocol ws_protocol_oregon2; diff --git a/applications/external/weather_station/protocols/oregon3.c b/applications/external/weather_station/protocols/oregon3.c deleted file mode 100644 index bd35c2fd5..000000000 --- a/applications/external/weather_station/protocols/oregon3.c +++ /dev/null @@ -1,365 +0,0 @@ -#include "oregon3.h" - -#include -#include -#include -#include -#include "ws_generic.h" - -#include -#include - -#define TAG "WSProtocolOregon3" - -static const SubGhzBlockConst ws_oregon3_const = { - .te_long = 1100, - .te_short = 500, - .te_delta = 300, - .min_count_bit_for_found = 32, -}; - -#define OREGON3_PREAMBLE_BITS 28 -#define OREGON3_PREAMBLE_MASK 0b1111111111111111111111111111 -// 24 ones + 0101 (inverted A) -#define OREGON3_PREAMBLE 0b1111111111111111111111110101 - -// Fixed part contains: -// - Sensor type: 16 bits -// - Channel: 4 bits -// - ID (changes when batteries are changed): 8 bits -// - Battery status: 4 bits -#define OREGON3_FIXED_PART_BITS (16 + 4 + 8 + 4) -#define OREGON3_SENSOR_ID(d) (((d) >> 16) & 0xFFFF) -#define OREGON3_CHECKSUM_BITS 8 - -// bit indicating the low battery -#define OREGON3_FLAG_BAT_LOW 0x4 - -/// Documentation for Oregon Scientific protocols can be found here: -/// https://www.osengr.org/Articles/OS-RF-Protocols-IV.pdf -// Sensors ID -#define ID_THGR221 0xf824 - -struct WSProtocolDecoderOregon3 { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; - ManchesterState manchester_state; - bool prev_bit; - - uint8_t var_bits; - uint64_t var_data; -}; - -typedef struct WSProtocolDecoderOregon3 WSProtocolDecoderOregon3; - -typedef enum { - Oregon3DecoderStepReset = 0, - Oregon3DecoderStepFoundPreamble, - Oregon3DecoderStepVarData, -} Oregon3DecoderStep; - -void* ws_protocol_decoder_oregon3_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderOregon3* instance = malloc(sizeof(WSProtocolDecoderOregon3)); - instance->base.protocol = &ws_protocol_oregon3; - instance->generic.protocol_name = instance->base.protocol->name; - instance->generic.humidity = WS_NO_HUMIDITY; - instance->generic.temp = WS_NO_TEMPERATURE; - instance->generic.btn = WS_NO_BTN; - instance->generic.channel = WS_NO_CHANNEL; - instance->generic.battery_low = WS_NO_BATT; - instance->generic.id = WS_NO_ID; - instance->prev_bit = false; - return instance; -} - -void ws_protocol_decoder_oregon3_free(void* context) { - furi_assert(context); - WSProtocolDecoderOregon3* instance = context; - free(instance); -} - -void ws_protocol_decoder_oregon3_reset(void* context) { - furi_assert(context); - WSProtocolDecoderOregon3* instance = context; - instance->decoder.parser_step = Oregon3DecoderStepReset; - instance->decoder.decode_data = 0UL; - instance->decoder.decode_count_bit = 0; - manchester_advance( - instance->manchester_state, ManchesterEventReset, &instance->manchester_state, NULL); - instance->prev_bit = false; - instance->var_data = 0; - instance->var_bits = 0; -} - -static ManchesterEvent level_and_duration_to_event(bool level, uint32_t duration) { - bool is_long = false; - - if(DURATION_DIFF(duration, ws_oregon3_const.te_long) < ws_oregon3_const.te_delta) { - is_long = true; - } else if(DURATION_DIFF(duration, ws_oregon3_const.te_short) < ws_oregon3_const.te_delta) { - is_long = false; - } else { - return ManchesterEventReset; - } - - if(level) - return is_long ? ManchesterEventLongHigh : ManchesterEventShortHigh; - else - return is_long ? ManchesterEventLongLow : ManchesterEventShortLow; -} - -// From sensor id code return amount of bits in variable section -// https://temofeev.ru/info/articles/o-dekodirovanii-protokola-pogodnykh-datchikov-oregon-scientific -static uint8_t oregon3_sensor_id_var_bits(uint16_t sensor_id) { - switch(sensor_id) { - case ID_THGR221: - // nibbles: temp + hum + '0' - return (4 + 2 + 1) * 4; - default: - FURI_LOG_D(TAG, "Unsupported sensor id 0x%x", sensor_id); - return 0; - } -} - -static void ws_oregon3_decode_const_data(WSBlockGeneric* ws_block) { - ws_block->id = OREGON3_SENSOR_ID(ws_block->data); - ws_block->channel = (ws_block->data >> 12) & 0xF; - ws_block->battery_low = (ws_block->data & OREGON3_FLAG_BAT_LOW) ? 1 : 0; -} - -static uint16_t ws_oregon3_bcd_decode_short(uint32_t data) { - return (data & 0xF) * 10 + ((data >> 4) & 0xF); -} - -static float ws_oregon3_decode_temp(uint32_t data) { - int32_t temp_val; - temp_val = ws_oregon3_bcd_decode_short(data >> 4); - temp_val *= 10; - temp_val += (data >> 12) & 0xF; - if(data & 0xF) temp_val = -temp_val; - return (float)temp_val / 10.0; -} - -static void ws_oregon3_decode_var_data(WSBlockGeneric* ws_b, uint16_t sensor_id, uint32_t data) { - switch(sensor_id) { - case ID_THGR221: - default: - ws_b->humidity = ws_oregon3_bcd_decode_short(data >> 4); - ws_b->temp = ws_oregon3_decode_temp(data >> 12); - break; - } -} - -void ws_protocol_decoder_oregon3_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderOregon3* instance = context; - // Oregon v3.0 protocol is inverted - ManchesterEvent event = level_and_duration_to_event(!level, duration); - - // low-level bit sequence decoding - if(event == ManchesterEventReset) { - instance->decoder.parser_step = Oregon3DecoderStepReset; - instance->prev_bit = false; - instance->decoder.decode_data = 0UL; - instance->decoder.decode_count_bit = 0; - } - if(manchester_advance( - instance->manchester_state, event, &instance->manchester_state, &instance->prev_bit)) { - subghz_protocol_blocks_add_bit(&instance->decoder, instance->prev_bit); - } - - switch(instance->decoder.parser_step) { - case Oregon3DecoderStepReset: - // waiting for fixed oregon3 preamble - if(instance->decoder.decode_count_bit >= OREGON3_PREAMBLE_BITS && - ((instance->decoder.decode_data & OREGON3_PREAMBLE_MASK) == OREGON3_PREAMBLE)) { - instance->decoder.parser_step = Oregon3DecoderStepFoundPreamble; - instance->decoder.decode_count_bit = 0; - instance->decoder.decode_data = 0UL; - } - break; - case Oregon3DecoderStepFoundPreamble: - // waiting for fixed oregon3 data - if(instance->decoder.decode_count_bit == OREGON3_FIXED_PART_BITS) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - instance->decoder.decode_data = 0UL; - instance->decoder.decode_count_bit = 0; - - // reverse nibbles in decoded data as oregon v3.0 is LSB first - instance->generic.data = (instance->generic.data & 0x55555555) << 1 | - (instance->generic.data & 0xAAAAAAAA) >> 1; - instance->generic.data = (instance->generic.data & 0x33333333) << 2 | - (instance->generic.data & 0xCCCCCCCC) >> 2; - - ws_oregon3_decode_const_data(&instance->generic); - instance->var_bits = - oregon3_sensor_id_var_bits(OREGON3_SENSOR_ID(instance->generic.data)); - - if(!instance->var_bits) { - // sensor is not supported, stop decoding - instance->decoder.parser_step = Oregon3DecoderStepReset; - } else { - instance->decoder.parser_step = Oregon3DecoderStepVarData; - } - } - break; - case Oregon3DecoderStepVarData: - // waiting for variable (sensor-specific data) - if(instance->decoder.decode_count_bit == instance->var_bits + OREGON3_CHECKSUM_BITS) { - instance->var_data = instance->decoder.decode_data & 0xFFFFFFFFFFFFFFFF; - - // reverse nibbles in var data - instance->var_data = (instance->var_data & 0x5555555555555555) << 1 | - (instance->var_data & 0xAAAAAAAAAAAAAAAA) >> 1; - instance->var_data = (instance->var_data & 0x3333333333333333) << 2 | - (instance->var_data & 0xCCCCCCCCCCCCCCCC) >> 2; - - ws_oregon3_decode_var_data( - &instance->generic, - OREGON3_SENSOR_ID(instance->generic.data), - instance->var_data >> OREGON3_CHECKSUM_BITS); - - instance->decoder.parser_step = Oregon3DecoderStepReset; - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - break; - } -} - -uint8_t ws_protocol_decoder_oregon3_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderOregon3* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_oregon3_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderOregon3* instance = context; - SubGhzProtocolStatus ret = SubGhzProtocolStatusError; - ret = ws_block_generic_serialize(&instance->generic, flipper_format, preset); - if(ret != SubGhzProtocolStatusOk) return ret; - uint32_t temp = instance->var_bits; - if(!flipper_format_write_uint32(flipper_format, "VarBits", &temp, 1)) { - FURI_LOG_E(TAG, "Error adding VarBits"); - return SubGhzProtocolStatusErrorParserOthers; - } - if(!flipper_format_write_hex( - flipper_format, - "VarData", - (const uint8_t*)&instance->var_data, - sizeof(instance->var_data))) { - FURI_LOG_E(TAG, "Error adding VarData"); - return SubGhzProtocolStatusErrorParserOthers; - } - return ret; -} - -SubGhzProtocolStatus - ws_protocol_decoder_oregon3_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderOregon3* instance = context; - uint32_t temp_data; - SubGhzProtocolStatus ret = SubGhzProtocolStatusError; - do { - ret = ws_block_generic_deserialize(&instance->generic, flipper_format); - if(ret != SubGhzProtocolStatusOk) { - break; - } - if(!flipper_format_read_uint32(flipper_format, "VarBits", &temp_data, 1)) { - FURI_LOG_E(TAG, "Missing VarLen"); - ret = SubGhzProtocolStatusErrorParserOthers; - break; - } - instance->var_bits = (uint8_t)temp_data; - if(!flipper_format_read_hex( - flipper_format, - "VarData", - (uint8_t*)&instance->var_data, - sizeof(instance->var_data))) { //-V1051 - FURI_LOG_E(TAG, "Missing VarData"); - ret = SubGhzProtocolStatusErrorParserOthers; - break; - } - if(instance->generic.data_count_bit != ws_oregon3_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key: %d", instance->generic.data_count_bit); - ret = SubGhzProtocolStatusErrorValueBitCount; - break; - } - } while(false); - return ret; -} - -static void oregon3_append_check_sum(uint32_t fix_data, uint64_t var_data, FuriString* output) { - uint8_t sum = fix_data & 0xF; - uint8_t ref_sum = var_data & 0xFF; - var_data >>= 4; - - for(uint8_t i = 1; i < 8; i++) { - fix_data >>= 4; - var_data >>= 4; - sum += (fix_data & 0xF) + (var_data & 0xF); - } - - // swap calculated sum nibbles - sum = (((sum >> 4) & 0xF) | (sum << 4)) & 0xFF; - if(sum == ref_sum) - furi_string_cat_printf(output, "Sum ok: 0x%hhX", ref_sum); - else - furi_string_cat_printf(output, "Sum err: 0x%hhX vs 0x%hhX", ref_sum, sum); -} - -void ws_protocol_decoder_oregon3_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderOregon3* instance = context; - furi_string_cat_printf( - output, - "%s\r\n" - "ID: 0x%04lX, ch: %d, bat: %d, rc: 0x%02lX\r\n", - instance->generic.protocol_name, - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (uint32_t)(instance->generic.data >> 4) & 0xFF); - - if(instance->var_bits > 0) { - furi_string_cat_printf( - output, - "Temp:%d.%d C Hum:%d%%", - (int16_t)instance->generic.temp, - abs( - ((int16_t)(instance->generic.temp * 10) - - (((int16_t)instance->generic.temp) * 10))), - instance->generic.humidity); - oregon3_append_check_sum((uint32_t)instance->generic.data, instance->var_data, output); - } -} - -const SubGhzProtocolDecoder ws_protocol_oregon3_decoder = { - .alloc = ws_protocol_decoder_oregon3_alloc, - .free = ws_protocol_decoder_oregon3_free, - - .feed = ws_protocol_decoder_oregon3_feed, - .reset = ws_protocol_decoder_oregon3_reset, - - .get_hash_data = ws_protocol_decoder_oregon3_get_hash_data, - .serialize = ws_protocol_decoder_oregon3_serialize, - .deserialize = ws_protocol_decoder_oregon3_deserialize, - .get_string = ws_protocol_decoder_oregon3_get_string, -}; - -const SubGhzProtocol ws_protocol_oregon3 = { - .name = WS_PROTOCOL_OREGON3_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_oregon3_decoder, -}; diff --git a/applications/external/weather_station/protocols/oregon3.h b/applications/external/weather_station/protocols/oregon3.h deleted file mode 100644 index ec51ddb00..000000000 --- a/applications/external/weather_station/protocols/oregon3.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include - -#define WS_PROTOCOL_OREGON3_NAME "Oregon3" -extern const SubGhzProtocol ws_protocol_oregon3; diff --git a/applications/external/weather_station/protocols/oregon_v1.c b/applications/external/weather_station/protocols/oregon_v1.c deleted file mode 100644 index 03215bbf5..000000000 --- a/applications/external/weather_station/protocols/oregon_v1.c +++ /dev/null @@ -1,321 +0,0 @@ -#include "oregon_v1.h" -#include - -#define TAG "WSProtocolOregon_V1" - -/* - * Help - * https://github.dev/merbanan/rtl_433/blob/bb1be7f186ac0fdb7dc5d77693847d96fb95281e/src/devices/oregon_scientific_v1.c - * - * OSv1 protocol. - * - * MC with nominal bit width of 2930 us. - * Pulses are somewhat longer than nominal half-bit width, 1748 us / 3216 us, - * Gaps are somewhat shorter than nominal half-bit width, 1176 us / 2640 us. - * After 12 preamble bits there is 4200 us gap, 5780 us pulse, 5200 us gap. - * And next 32 bit data - * - * Care must be taken with the gap after the sync pulse since it - * is outside of the normal clocking. Because of this a data stream - * beginning with a 0 will have data in this gap. - * - * - * Data is in reverse order of bits - * RevBit(data32bit)=> tib23atad - * - * tib23atad => xxxxxxxx | busuTTTT | ttttzzzz | ccuuiiii - * - * - i: ID - * - x: CRC; - * - u: unknown; - * - b: battery low; flag to indicate low battery voltage - * - s: temperature sign - * - T: BCD, Temperature; in °C * 10 - * - t: BCD, Temperature; in °C * 1 - * - z: BCD, Temperature; in °C * 0.1 - * - c: Channel 00=CH1, 01=CH2, 10=CH3 - * - */ - -#define OREGON_V1_HEADER_OK 0xFF - -static const SubGhzBlockConst ws_protocol_oregon_v1_const = { - .te_short = 1465, - .te_long = 2930, - .te_delta = 350, - .min_count_bit_for_found = 32, -}; - -struct WSProtocolDecoderOregon_V1 { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; - ManchesterState manchester_state; - uint16_t header_count; - uint8_t first_bit; -}; - -struct WSProtocolEncoderOregon_V1 { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - WSBlockGeneric generic; -}; - -typedef enum { - Oregon_V1DecoderStepReset = 0, - Oregon_V1DecoderStepFoundPreamble, - Oregon_V1DecoderStepParse, -} Oregon_V1DecoderStep; - -const SubGhzProtocolDecoder ws_protocol_oregon_v1_decoder = { - .alloc = ws_protocol_decoder_oregon_v1_alloc, - .free = ws_protocol_decoder_oregon_v1_free, - - .feed = ws_protocol_decoder_oregon_v1_feed, - .reset = ws_protocol_decoder_oregon_v1_reset, - - .get_hash_data = ws_protocol_decoder_oregon_v1_get_hash_data, - .serialize = ws_protocol_decoder_oregon_v1_serialize, - .deserialize = ws_protocol_decoder_oregon_v1_deserialize, - .get_string = ws_protocol_decoder_oregon_v1_get_string, -}; - -const SubGhzProtocolEncoder ws_protocol_oregon_v1_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol ws_protocol_oregon_v1 = { - .name = WS_PROTOCOL_OREGON_V1_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_oregon_v1_decoder, - .encoder = &ws_protocol_oregon_v1_encoder, -}; - -void* ws_protocol_decoder_oregon_v1_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderOregon_V1* instance = malloc(sizeof(WSProtocolDecoderOregon_V1)); - instance->base.protocol = &ws_protocol_oregon_v1; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void ws_protocol_decoder_oregon_v1_free(void* context) { - furi_assert(context); - WSProtocolDecoderOregon_V1* instance = context; - free(instance); -} - -void ws_protocol_decoder_oregon_v1_reset(void* context) { - furi_assert(context); - WSProtocolDecoderOregon_V1* instance = context; - instance->decoder.parser_step = Oregon_V1DecoderStepReset; -} - -static bool ws_protocol_oregon_v1_check(WSProtocolDecoderOregon_V1* instance) { - if(!instance->decoder.decode_data) return false; - uint64_t data = subghz_protocol_blocks_reverse_key(instance->decoder.decode_data, 32); - uint16_t crc = (data & 0xff) + ((data >> 8) & 0xff) + ((data >> 16) & 0xff); - crc = (crc & 0xff) + ((crc >> 8) & 0xff); - return (crc == ((data >> 24) & 0xFF)); -} - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static void ws_protocol_oregon_v1_remote_controller(WSBlockGeneric* instance) { - uint64_t data = subghz_protocol_blocks_reverse_key(instance->data, 32); - - instance->id = data & 0xFF; - instance->channel = ((data >> 6) & 0x03) + 1; - - float temp_raw = - ((data >> 8) & 0x0F) * 0.1f + ((data >> 12) & 0x0F) + ((data >> 16) & 0x0F) * 10.0f; - if(!((data >> 21) & 1)) { - instance->temp = temp_raw; - } else { - instance->temp = -temp_raw; - } - - instance->battery_low = !((instance->data >> 23) & 1ULL); - - instance->btn = WS_NO_BTN; - instance->humidity = WS_NO_HUMIDITY; -} - -void ws_protocol_decoder_oregon_v1_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderOregon_V1* instance = context; - ManchesterEvent event = ManchesterEventReset; - switch(instance->decoder.parser_step) { - case Oregon_V1DecoderStepReset: - if((level) && (DURATION_DIFF(duration, ws_protocol_oregon_v1_const.te_short) < - ws_protocol_oregon_v1_const.te_delta)) { - instance->decoder.parser_step = Oregon_V1DecoderStepFoundPreamble; - instance->decoder.te_last = duration; - instance->header_count = 0; - } - break; - case Oregon_V1DecoderStepFoundPreamble: - if(level) { - //keep high levels, if they suit our durations - if((DURATION_DIFF(duration, ws_protocol_oregon_v1_const.te_short) < - ws_protocol_oregon_v1_const.te_delta) || - (DURATION_DIFF(duration, ws_protocol_oregon_v1_const.te_short * 4) < - ws_protocol_oregon_v1_const.te_delta)) { - instance->decoder.te_last = duration; - } else { - instance->decoder.parser_step = Oregon_V1DecoderStepReset; - } - } else if( - //checking low levels - (DURATION_DIFF(duration, ws_protocol_oregon_v1_const.te_short) < - ws_protocol_oregon_v1_const.te_delta) && - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_oregon_v1_const.te_short) < - ws_protocol_oregon_v1_const.te_delta)) { - // Found header - instance->header_count++; - } else if( - (DURATION_DIFF(duration, ws_protocol_oregon_v1_const.te_short * 3) < - ws_protocol_oregon_v1_const.te_delta) && - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_oregon_v1_const.te_short) < - ws_protocol_oregon_v1_const.te_delta)) { - // check header - if(instance->header_count > 7) { - instance->header_count = OREGON_V1_HEADER_OK; - } - } else if( - (instance->header_count == OREGON_V1_HEADER_OK) && - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_oregon_v1_const.te_short * 4) < - ws_protocol_oregon_v1_const.te_delta)) { - //found all the necessary patterns - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 1; - manchester_advance( - instance->manchester_state, - ManchesterEventReset, - &instance->manchester_state, - NULL); - instance->decoder.parser_step = Oregon_V1DecoderStepParse; - if(duration < ws_protocol_oregon_v1_const.te_short * 4) { - instance->first_bit = 1; - } else { - instance->first_bit = 0; - } - } else { - instance->decoder.parser_step = Oregon_V1DecoderStepReset; - } - break; - case Oregon_V1DecoderStepParse: - if(level) { - if(DURATION_DIFF(duration, ws_protocol_oregon_v1_const.te_short) < - ws_protocol_oregon_v1_const.te_delta) { - event = ManchesterEventShortHigh; - } else if( - DURATION_DIFF(duration, ws_protocol_oregon_v1_const.te_long) < - ws_protocol_oregon_v1_const.te_delta) { - event = ManchesterEventLongHigh; - } else { - instance->decoder.parser_step = Oregon_V1DecoderStepReset; - } - } else { - if(DURATION_DIFF(duration, ws_protocol_oregon_v1_const.te_short) < - ws_protocol_oregon_v1_const.te_delta) { - event = ManchesterEventShortLow; - } else if( - DURATION_DIFF(duration, ws_protocol_oregon_v1_const.te_long) < - ws_protocol_oregon_v1_const.te_delta) { - event = ManchesterEventLongLow; - } else if(duration >= ((uint32_t)ws_protocol_oregon_v1_const.te_long * 2)) { - if(instance->decoder.decode_count_bit == - ws_protocol_oregon_v1_const.min_count_bit_for_found) { - if(instance->first_bit) { - instance->decoder.decode_data = ~instance->decoder.decode_data | (1 << 31); - } - if(ws_protocol_oregon_v1_check(instance)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - ws_protocol_oregon_v1_remote_controller(&instance->generic); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - manchester_advance( - instance->manchester_state, - ManchesterEventReset, - &instance->manchester_state, - NULL); - } else { - instance->decoder.parser_step = Oregon_V1DecoderStepReset; - } - } - if(event != ManchesterEventReset) { - bool data; - bool data_ok = manchester_advance( - instance->manchester_state, event, &instance->manchester_state, &data); - - if(data_ok) { - instance->decoder.decode_data = (instance->decoder.decode_data << 1) | !data; - instance->decoder.decode_count_bit++; - } - } - - break; - } -} - -uint8_t ws_protocol_decoder_oregon_v1_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderOregon_V1* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_oregon_v1_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderOregon_V1* instance = context; - return ws_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus - ws_protocol_decoder_oregon_v1_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderOregon_V1* instance = context; - return ws_block_generic_deserialize_check_count_bit( - &instance->generic, flipper_format, ws_protocol_oregon_v1_const.min_count_bit_for_found); -} - -void ws_protocol_decoder_oregon_v1_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderOregon_V1* instance = context; - furi_string_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%lX Ch:%d Bat:%d\r\n" - "Temp:%3.1f C Hum:%d%%", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data), - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (double)instance->generic.temp, - instance->generic.humidity); -} diff --git a/applications/external/weather_station/protocols/oregon_v1.h b/applications/external/weather_station/protocols/oregon_v1.h deleted file mode 100644 index 48937601d..000000000 --- a/applications/external/weather_station/protocols/oregon_v1.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "ws_generic.h" -#include - -#define WS_PROTOCOL_OREGON_V1_NAME "Oregon-v1" - -typedef struct WSProtocolDecoderOregon_V1 WSProtocolDecoderOregon_V1; -typedef struct WSProtocolEncoderOregon_V1 WSProtocolEncoderOregon_V1; - -extern const SubGhzProtocolDecoder ws_protocol_oregon_v1_decoder; -extern const SubGhzProtocolEncoder ws_protocol_oregon_v1_encoder; -extern const SubGhzProtocol ws_protocol_oregon_v1; - -/** - * Allocate WSProtocolDecoderOregon_V1. - * @param environment Pointer to a SubGhzEnvironment instance - * @return WSProtocolDecoderOregon_V1* pointer to a WSProtocolDecoderOregon_V1 instance - */ -void* ws_protocol_decoder_oregon_v1_alloc(SubGhzEnvironment* environment); - -/** - * Free WSProtocolDecoderOregon_V1. - * @param context Pointer to a WSProtocolDecoderOregon_V1 instance - */ -void ws_protocol_decoder_oregon_v1_free(void* context); - -/** - * Reset decoder WSProtocolDecoderOregon_V1. - * @param context Pointer to a WSProtocolDecoderOregon_V1 instance - */ -void ws_protocol_decoder_oregon_v1_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a WSProtocolDecoderOregon_V1 instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void ws_protocol_decoder_oregon_v1_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a WSProtocolDecoderOregon_V1 instance - * @return hash Hash sum - */ -uint8_t ws_protocol_decoder_oregon_v1_get_hash_data(void* context); - -/** - * Serialize data WSProtocolDecoderOregon_V1. - * @param context Pointer to a WSProtocolDecoderOregon_V1 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_oregon_v1_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSProtocolDecoderOregon_V1. - * @param context Pointer to a WSProtocolDecoderOregon_V1 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus - ws_protocol_decoder_oregon_v1_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a WSProtocolDecoderOregon_V1 instance - * @param output Resulting text - */ -void ws_protocol_decoder_oregon_v1_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/protocol_items.c b/applications/external/weather_station/protocols/protocol_items.c deleted file mode 100644 index 93dc25488..000000000 --- a/applications/external/weather_station/protocols/protocol_items.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "protocol_items.h" - -const SubGhzProtocol* weather_station_protocol_registry_items[] = { - &ws_protocol_infactory, - &ws_protocol_thermopro_tx4, - &ws_protocol_nexus_th, - &ws_protocol_gt_wt_02, - &ws_protocol_gt_wt_03, - &ws_protocol_acurite_606tx, - &ws_protocol_acurite_609txc, - &ws_protocol_lacrosse_tx, - &ws_protocol_lacrosse_tx141thbv2, - &ws_protocol_oregon2, - &ws_protocol_oregon3, - &ws_protocol_acurite_592txr, - &ws_protocol_ambient_weather, - &ws_protocol_auriol_th, - &ws_protocol_oregon_v1, - &ws_protocol_tx_8300, - &ws_protocol_wendox_w6726, -}; - -const SubGhzProtocolRegistry weather_station_protocol_registry = { - .items = weather_station_protocol_registry_items, - .size = COUNT_OF(weather_station_protocol_registry_items)}; diff --git a/applications/external/weather_station/protocols/protocol_items.h b/applications/external/weather_station/protocols/protocol_items.h deleted file mode 100644 index 712eb07f2..000000000 --- a/applications/external/weather_station/protocols/protocol_items.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -#include "../weather_station_app_i.h" - -#include "infactory.h" -#include "thermopro_tx4.h" -#include "nexus_th.h" -#include "gt_wt_02.h" -#include "gt_wt_03.h" -#include "acurite_606tx.h" -#include "acurite_609txc.h" -#include "lacrosse_tx.h" -#include "lacrosse_tx141thbv2.h" -#include "oregon2.h" -#include "oregon3.h" -#include "acurite_592txr.h" -#include "ambient_weather.h" -#include "auriol_hg0601a.h" -#include "oregon_v1.h" -#include "tx_8300.h" -#include "wendox_w6726.h" - -extern const SubGhzProtocolRegistry weather_station_protocol_registry; diff --git a/applications/external/weather_station/protocols/thermopro_tx4.c b/applications/external/weather_station/protocols/thermopro_tx4.c deleted file mode 100644 index 24e883e60..000000000 --- a/applications/external/weather_station/protocols/thermopro_tx4.c +++ /dev/null @@ -1,251 +0,0 @@ -#include "thermopro_tx4.h" - -#define TAG "WSProtocolThermoPRO_TX4" - -/* - * Help - * https://github.com/merbanan/rtl_433/blob/master/src/devices/thermopro_tx2.c - * - * The sensor sends 37 bits 6 times, before the first packet there is a sync pulse. - * The packets are ppm modulated (distance coding) with a pulse of ~500 us - * followed by a short gap of ~2000 us for a 0 bit or a long ~4000 us gap for a - * 1 bit, the sync gap is ~9000 us. - * The data is grouped in 9 nibbles - * [type] [id0] [id1] [flags] [temp0] [temp1] [temp2] [humi0] [humi1] - * - type: 4 bit fixed 1001 (9) or 0110 (5) - * - id: 8 bit a random id that is generated when the sensor starts, could include battery status - * the same batteries often generate the same id - * - flags(3): is 1 when the battery is low, otherwise 0 (ok) - * - flags(2): is 1 when the sensor sends a reading when pressing the button on the sensor - * - flags(1,0): the channel number that can be set by the sensor (1, 2, 3, X) - * - temp: 12 bit signed scaled by 10 - * - humi: 8 bit always 11001100 (0xCC) if no humidity sensor is available - * - */ - -#define THERMO_PRO_TX4_TYPE_1 0b1001 -#define THERMO_PRO_TX4_TYPE_2 0b0110 - -static const SubGhzBlockConst ws_protocol_thermopro_tx4_const = { - .te_short = 500, - .te_long = 2000, - .te_delta = 150, - .min_count_bit_for_found = 37, -}; - -struct WSProtocolDecoderThermoPRO_TX4 { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; -}; - -struct WSProtocolEncoderThermoPRO_TX4 { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - WSBlockGeneric generic; -}; - -typedef enum { - ThermoPRO_TX4DecoderStepReset = 0, - ThermoPRO_TX4DecoderStepSaveDuration, - ThermoPRO_TX4DecoderStepCheckDuration, -} ThermoPRO_TX4DecoderStep; - -const SubGhzProtocolDecoder ws_protocol_thermopro_tx4_decoder = { - .alloc = ws_protocol_decoder_thermopro_tx4_alloc, - .free = ws_protocol_decoder_thermopro_tx4_free, - - .feed = ws_protocol_decoder_thermopro_tx4_feed, - .reset = ws_protocol_decoder_thermopro_tx4_reset, - - .get_hash_data = ws_protocol_decoder_thermopro_tx4_get_hash_data, - .serialize = ws_protocol_decoder_thermopro_tx4_serialize, - .deserialize = ws_protocol_decoder_thermopro_tx4_deserialize, - .get_string = ws_protocol_decoder_thermopro_tx4_get_string, -}; - -const SubGhzProtocolEncoder ws_protocol_thermopro_tx4_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol ws_protocol_thermopro_tx4 = { - .name = WS_PROTOCOL_THERMOPRO_TX4_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_thermopro_tx4_decoder, - .encoder = &ws_protocol_thermopro_tx4_encoder, -}; - -void* ws_protocol_decoder_thermopro_tx4_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderThermoPRO_TX4* instance = malloc(sizeof(WSProtocolDecoderThermoPRO_TX4)); - instance->base.protocol = &ws_protocol_thermopro_tx4; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void ws_protocol_decoder_thermopro_tx4_free(void* context) { - furi_assert(context); - WSProtocolDecoderThermoPRO_TX4* instance = context; - free(instance); -} - -void ws_protocol_decoder_thermopro_tx4_reset(void* context) { - furi_assert(context); - WSProtocolDecoderThermoPRO_TX4* instance = context; - instance->decoder.parser_step = ThermoPRO_TX4DecoderStepReset; -} - -static bool ws_protocol_thermopro_tx4_check(WSProtocolDecoderThermoPRO_TX4* instance) { - uint8_t type = instance->decoder.decode_data >> 33; - - if((type == THERMO_PRO_TX4_TYPE_1) || (type == THERMO_PRO_TX4_TYPE_2)) { - return true; - } else { - return false; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static void ws_protocol_thermopro_tx4_remote_controller(WSBlockGeneric* instance) { - instance->id = (instance->data >> 25) & 0xFF; - instance->battery_low = (instance->data >> 24) & 1; - instance->btn = (instance->data >> 23) & 1; - instance->channel = ((instance->data >> 21) & 0x03) + 1; - - if(!((instance->data >> 20) & 1)) { - instance->temp = (float)((instance->data >> 9) & 0x07FF) / 10.0f; - } else { - instance->temp = (float)((~(instance->data >> 9) & 0x07FF) + 1) / -10.0f; - } - - instance->humidity = (instance->data >> 1) & 0xFF; -} - -void ws_protocol_decoder_thermopro_tx4_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderThermoPRO_TX4* instance = context; - - switch(instance->decoder.parser_step) { - case ThermoPRO_TX4DecoderStepReset: - if((!level) && (DURATION_DIFF(duration, ws_protocol_thermopro_tx4_const.te_short * 18) < - ws_protocol_thermopro_tx4_const.te_delta * 10)) { - //Found sync - instance->decoder.parser_step = ThermoPRO_TX4DecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } - break; - - case ThermoPRO_TX4DecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = ThermoPRO_TX4DecoderStepCheckDuration; - } else { - instance->decoder.parser_step = ThermoPRO_TX4DecoderStepReset; - } - break; - - case ThermoPRO_TX4DecoderStepCheckDuration: - if(!level) { - if(DURATION_DIFF(duration, ws_protocol_thermopro_tx4_const.te_short * 18) < - ws_protocol_thermopro_tx4_const.te_delta * 10) { - //Found sync - instance->decoder.parser_step = ThermoPRO_TX4DecoderStepReset; - if((instance->decoder.decode_count_bit == - ws_protocol_thermopro_tx4_const.min_count_bit_for_found) && - ws_protocol_thermopro_tx4_check(instance)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - ws_protocol_thermopro_tx4_remote_controller(&instance->generic); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - instance->decoder.parser_step = ThermoPRO_TX4DecoderStepCheckDuration; - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - - break; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, ws_protocol_thermopro_tx4_const.te_short) < - ws_protocol_thermopro_tx4_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_thermopro_tx4_const.te_long) < - ws_protocol_thermopro_tx4_const.te_delta * 2)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = ThermoPRO_TX4DecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, ws_protocol_thermopro_tx4_const.te_short) < - ws_protocol_thermopro_tx4_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_thermopro_tx4_const.te_long * 2) < - ws_protocol_thermopro_tx4_const.te_delta * 4)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = ThermoPRO_TX4DecoderStepSaveDuration; - } else { - instance->decoder.parser_step = ThermoPRO_TX4DecoderStepReset; - } - } else { - instance->decoder.parser_step = ThermoPRO_TX4DecoderStepReset; - } - break; - } -} - -uint8_t ws_protocol_decoder_thermopro_tx4_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderThermoPRO_TX4* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_thermopro_tx4_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderThermoPRO_TX4* instance = context; - return ws_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus - ws_protocol_decoder_thermopro_tx4_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderThermoPRO_TX4* instance = context; - return ws_block_generic_deserialize_check_count_bit( - &instance->generic, - flipper_format, - ws_protocol_thermopro_tx4_const.min_count_bit_for_found); -} - -void ws_protocol_decoder_thermopro_tx4_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderThermoPRO_TX4* instance = context; - furi_string_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%lX Ch:%d Bat:%d\r\n" - "Temp:%3.1f C Hum:%d%%", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data), - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (double)instance->generic.temp, - instance->generic.humidity); -} diff --git a/applications/external/weather_station/protocols/thermopro_tx4.h b/applications/external/weather_station/protocols/thermopro_tx4.h deleted file mode 100644 index 526648d1e..000000000 --- a/applications/external/weather_station/protocols/thermopro_tx4.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "ws_generic.h" -#include - -#define WS_PROTOCOL_THERMOPRO_TX4_NAME "ThermoPRO-TX4" - -typedef struct WSProtocolDecoderThermoPRO_TX4 WSProtocolDecoderThermoPRO_TX4; -typedef struct WSProtocolEncoderThermoPRO_TX4 WSProtocolEncoderThermoPRO_TX4; - -extern const SubGhzProtocolDecoder ws_protocol_thermopro_tx4_decoder; -extern const SubGhzProtocolEncoder ws_protocol_thermopro_tx4_encoder; -extern const SubGhzProtocol ws_protocol_thermopro_tx4; - -/** - * Allocate WSProtocolDecoderThermoPRO_TX4. - * @param environment Pointer to a SubGhzEnvironment instance - * @return WSProtocolDecoderThermoPRO_TX4* pointer to a WSProtocolDecoderThermoPRO_TX4 instance - */ -void* ws_protocol_decoder_thermopro_tx4_alloc(SubGhzEnvironment* environment); - -/** - * Free WSProtocolDecoderThermoPRO_TX4. - * @param context Pointer to a WSProtocolDecoderThermoPRO_TX4 instance - */ -void ws_protocol_decoder_thermopro_tx4_free(void* context); - -/** - * Reset decoder WSProtocolDecoderThermoPRO_TX4. - * @param context Pointer to a WSProtocolDecoderThermoPRO_TX4 instance - */ -void ws_protocol_decoder_thermopro_tx4_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a WSProtocolDecoderThermoPRO_TX4 instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void ws_protocol_decoder_thermopro_tx4_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a WSProtocolDecoderThermoPRO_TX4 instance - * @return hash Hash sum - */ -uint8_t ws_protocol_decoder_thermopro_tx4_get_hash_data(void* context); - -/** - * Serialize data WSProtocolDecoderThermoPRO_TX4. - * @param context Pointer to a WSProtocolDecoderThermoPRO_TX4 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_thermopro_tx4_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSProtocolDecoderThermoPRO_TX4. - * @param context Pointer to a WSProtocolDecoderThermoPRO_TX4 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus - ws_protocol_decoder_thermopro_tx4_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a WSProtocolDecoderThermoPRO_TX4 instance - * @param output Resulting text - */ -void ws_protocol_decoder_thermopro_tx4_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/tx_8300.c b/applications/external/weather_station/protocols/tx_8300.c deleted file mode 100644 index 3a06ce49d..000000000 --- a/applications/external/weather_station/protocols/tx_8300.c +++ /dev/null @@ -1,284 +0,0 @@ -#include "tx_8300.h" - -#define TAG "WSProtocolTX_8300" - -/* - * Help - * https://github.com/merbanan/rtl_433/blob/master/src/devices/ambientweather_tx8300.c - * - * Ambient Weather TX-8300 (also sold as TFA 30.3211.02). - * 1970us pulse with variable gap (third pulse 3920 us). - * Above 79% humidity, gap after third pulse is 5848 us. - * - Bit 1 : 1970us pulse with 3888 us gap - * - Bit 0 : 1970us pulse with 1936 us gap - * 74 bit (2 bit preamble and 72 bit data => 9 bytes => 18 nibbles) - * The preamble seems to be a repeat counter (00, and 01 seen), - * the first 4 bytes are data, - * the second 4 bytes the same data inverted, - * the last byte is a checksum. - * Preamble format (2 bits): - * [1 bit (0)] [1 bit rolling count] - * Payload format (32 bits): - * HHHHhhhh ??CCNIII IIIITTTT ttttuuuu - * - H = First BCD digit humidity (the MSB might be distorted by the demod) - * - h = Second BCD digit humidity, invalid humidity seems to be 0x0e - * - ? = Likely battery flag, 2 bits - * - C = Channel, 2 bits - * - N = Negative temperature sign bit - * - I = ID, 7-bit - * - T = First BCD digit temperature - * - t = Second BCD digit temperature - * - u = Third BCD digit temperature - * The Checksum seems to covers the 4 data bytes and is something like Fletcher-8. - **/ - -#define TX_8300_PACKAGE_SIZE 32 - -static const SubGhzBlockConst ws_protocol_tx_8300_const = { - .te_short = 1940, - .te_long = 3880, - .te_delta = 250, - .min_count_bit_for_found = 72, -}; - -struct WSProtocolDecoderTX_8300 { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; - uint32_t package_1; - uint32_t package_2; -}; - -struct WSProtocolEncoderTX_8300 { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - WSBlockGeneric generic; -}; - -typedef enum { - TX_8300DecoderStepReset = 0, - TX_8300DecoderStepCheckPreambule, - TX_8300DecoderStepSaveDuration, - TX_8300DecoderStepCheckDuration, -} TX_8300DecoderStep; - -const SubGhzProtocolDecoder ws_protocol_tx_8300_decoder = { - .alloc = ws_protocol_decoder_tx_8300_alloc, - .free = ws_protocol_decoder_tx_8300_free, - - .feed = ws_protocol_decoder_tx_8300_feed, - .reset = ws_protocol_decoder_tx_8300_reset, - - .get_hash_data = ws_protocol_decoder_tx_8300_get_hash_data, - .serialize = ws_protocol_decoder_tx_8300_serialize, - .deserialize = ws_protocol_decoder_tx_8300_deserialize, - .get_string = ws_protocol_decoder_tx_8300_get_string, -}; - -const SubGhzProtocolEncoder ws_protocol_tx_8300_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol ws_protocol_tx_8300 = { - .name = WS_PROTOCOL_TX_8300_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_tx_8300_decoder, - .encoder = &ws_protocol_tx_8300_encoder, -}; - -void* ws_protocol_decoder_tx_8300_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderTX_8300* instance = malloc(sizeof(WSProtocolDecoderTX_8300)); - instance->base.protocol = &ws_protocol_tx_8300; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void ws_protocol_decoder_tx_8300_free(void* context) { - furi_assert(context); - WSProtocolDecoderTX_8300* instance = context; - free(instance); -} - -void ws_protocol_decoder_tx_8300_reset(void* context) { - furi_assert(context); - WSProtocolDecoderTX_8300* instance = context; - instance->decoder.parser_step = TX_8300DecoderStepReset; -} - -static bool ws_protocol_tx_8300_check_crc(WSProtocolDecoderTX_8300* instance) { - if(!instance->package_2) return false; - if(instance->package_1 != ~instance->package_2) return false; - - uint16_t x = 0; - uint16_t y = 0; - for(int i = 0; i < 32; i += 4) { - x += (instance->package_1 >> i) & 0x0F; - y += (instance->package_1 >> i) & 0x05; - } - uint8_t crc = (~x & 0xF) << 4 | (~y & 0xF); - return (crc == ((instance->decoder.decode_data) & 0xFF)); -} - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static void ws_protocol_tx_8300_remote_controller(WSBlockGeneric* instance) { - instance->humidity = (((instance->data >> 28) & 0x0F) * 10) + ((instance->data >> 24) & 0x0F); - instance->btn = WS_NO_BTN; - if(!((instance->data >> 22) & 0x03)) - instance->battery_low = 0; - else - instance->battery_low = 1; - instance->channel = (instance->data >> 20) & 0x03; - instance->id = (instance->data >> 12) & 0x7F; - - float temp_raw = ((instance->data >> 8) & 0x0F) * 10.0f + ((instance->data >> 4) & 0x0F) + - (instance->data & 0x0F) * 0.1f; - if(!((instance->data >> 19) & 1)) { - instance->temp = temp_raw; - } else { - instance->temp = -temp_raw; - } -} - -void ws_protocol_decoder_tx_8300_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderTX_8300* instance = context; - - switch(instance->decoder.parser_step) { - case TX_8300DecoderStepReset: - if((level) && (DURATION_DIFF(duration, ws_protocol_tx_8300_const.te_short * 2) < - ws_protocol_tx_8300_const.te_delta)) { - instance->decoder.parser_step = TX_8300DecoderStepCheckPreambule; - } - break; - - case TX_8300DecoderStepCheckPreambule: - if((!level) && ((DURATION_DIFF(duration, ws_protocol_tx_8300_const.te_short * 2) < - ws_protocol_tx_8300_const.te_delta) || - (DURATION_DIFF(duration, ws_protocol_tx_8300_const.te_short * 3) < - ws_protocol_tx_8300_const.te_delta))) { - instance->decoder.parser_step = TX_8300DecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 1; - instance->package_1 = 0; - instance->package_2 = 0; - } else { - instance->decoder.parser_step = TX_8300DecoderStepReset; - } - break; - - case TX_8300DecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = TX_8300DecoderStepCheckDuration; - } else { - instance->decoder.parser_step = TX_8300DecoderStepReset; - } - break; - - case TX_8300DecoderStepCheckDuration: - if(!level) { - if(duration >= ((uint32_t)ws_protocol_tx_8300_const.te_short * 5)) { - //Found syncPostfix - if((instance->decoder.decode_count_bit == - ws_protocol_tx_8300_const.min_count_bit_for_found) && - ws_protocol_tx_8300_check_crc(instance)) { - instance->generic.data = instance->package_1; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - ws_protocol_tx_8300_remote_controller(&instance->generic); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 1; - instance->decoder.parser_step = TX_8300DecoderStepReset; - break; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_tx_8300_const.te_short) < - ws_protocol_tx_8300_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_tx_8300_const.te_long) < - ws_protocol_tx_8300_const.te_delta * 2)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = TX_8300DecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_tx_8300_const.te_short) < - ws_protocol_tx_8300_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_tx_8300_const.te_short) < - ws_protocol_tx_8300_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = TX_8300DecoderStepSaveDuration; - } else { - instance->decoder.parser_step = TX_8300DecoderStepReset; - } - - if(instance->decoder.decode_count_bit == TX_8300_PACKAGE_SIZE) { - instance->package_1 = instance->decoder.decode_data; - instance->decoder.decode_data = 0; - } else if(instance->decoder.decode_count_bit == TX_8300_PACKAGE_SIZE * 2) { - instance->package_2 = instance->decoder.decode_data; - instance->decoder.decode_data = 0; - } - - } else { - instance->decoder.parser_step = TX_8300DecoderStepReset; - } - break; - } -} - -uint8_t ws_protocol_decoder_tx_8300_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderTX_8300* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_tx_8300_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderTX_8300* instance = context; - return ws_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus - ws_protocol_decoder_tx_8300_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderTX_8300* instance = context; - return ws_block_generic_deserialize_check_count_bit( - &instance->generic, flipper_format, ws_protocol_tx_8300_const.min_count_bit_for_found); -} - -void ws_protocol_decoder_tx_8300_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderTX_8300* instance = context; - furi_string_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%lX Ch:%d Bat:%d\r\n" - "Temp:%3.1f C Hum:%d%%", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data), - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (double)instance->generic.temp, - instance->generic.humidity); -} diff --git a/applications/external/weather_station/protocols/tx_8300.h b/applications/external/weather_station/protocols/tx_8300.h deleted file mode 100644 index 088ccd7c0..000000000 --- a/applications/external/weather_station/protocols/tx_8300.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "ws_generic.h" -#include - -#define WS_PROTOCOL_TX_8300_NAME "TX8300" - -typedef struct WSProtocolDecoderTX_8300 WSProtocolDecoderTX_8300; -typedef struct WSProtocolEncoderTX_8300 WSProtocolEncoderTX_8300; - -extern const SubGhzProtocolDecoder ws_protocol_tx_8300_decoder; -extern const SubGhzProtocolEncoder ws_protocol_tx_8300_encoder; -extern const SubGhzProtocol ws_protocol_tx_8300; - -/** - * Allocate WSProtocolDecoderTX_8300. - * @param environment Pointer to a SubGhzEnvironment instance - * @return WSProtocolDecoderTX_8300* pointer to a WSProtocolDecoderTX_8300 instance - */ -void* ws_protocol_decoder_tx_8300_alloc(SubGhzEnvironment* environment); - -/** - * Free WSProtocolDecoderTX_8300. - * @param context Pointer to a WSProtocolDecoderTX_8300 instance - */ -void ws_protocol_decoder_tx_8300_free(void* context); - -/** - * Reset decoder WSProtocolDecoderTX_8300. - * @param context Pointer to a WSProtocolDecoderTX_8300 instance - */ -void ws_protocol_decoder_tx_8300_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a WSProtocolDecoderTX_8300 instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void ws_protocol_decoder_tx_8300_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a WSProtocolDecoderTX_8300 instance - * @return hash Hash sum - */ -uint8_t ws_protocol_decoder_tx_8300_get_hash_data(void* context); - -/** - * Serialize data WSProtocolDecoderTX_8300. - * @param context Pointer to a WSProtocolDecoderTX_8300 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_tx_8300_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSProtocolDecoderTX_8300. - * @param context Pointer to a WSProtocolDecoderTX_8300 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus - ws_protocol_decoder_tx_8300_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a WSProtocolDecoderTX_8300 instance - * @param output Resulting text - */ -void ws_protocol_decoder_tx_8300_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/wendox_w6726.c b/applications/external/weather_station/protocols/wendox_w6726.c deleted file mode 100644 index 2fbe961f7..000000000 --- a/applications/external/weather_station/protocols/wendox_w6726.c +++ /dev/null @@ -1,299 +0,0 @@ -#include "wendox_w6726.h" - -#define TAG "WSProtocolWendoxW6726" - -/* - * Wendox W6726 - * - * Temperature -50C to +70C - * _ _ _ __ _ - * _| |___| |___| |___ ... | |_| |__...._______________ - * preamble data guard time - * - * 3 reps every 3 minutes - * in the first message 11 bytes of the preamble in the rest by 7 - * - * bit 0: 1955-hi, 5865-lo - * bit 1: 5865-hi, 1955-lo - * guard time: 12*1955+(lo last bit) - * data: 29 bit - * - * IIIII | ZTTTTTTTTT | uuuuuuuBuu | CCCC - * - * I: identification; - * Z: temperature sign; - * T: temperature sign dependent +12C; - * B: battery low; flag to indicate low battery voltage; - * C: CRC4 (polynomial = 0x9, start_data = 0xD); - * u: unknown; - */ - -static const SubGhzBlockConst ws_protocol_wendox_w6726_const = { - .te_short = 1955, - .te_long = 5865, - .te_delta = 300, - .min_count_bit_for_found = 29, -}; - -struct WSProtocolDecoderWendoxW6726 { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - WSBlockGeneric generic; - - uint16_t header_count; -}; - -struct WSProtocolEncoderWendoxW6726 { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - WSBlockGeneric generic; -}; - -typedef enum { - WendoxW6726DecoderStepReset = 0, - WendoxW6726DecoderStepCheckPreambule, - WendoxW6726DecoderStepSaveDuration, - WendoxW6726DecoderStepCheckDuration, -} WendoxW6726DecoderStep; - -const SubGhzProtocolDecoder ws_protocol_wendox_w6726_decoder = { - .alloc = ws_protocol_decoder_wendox_w6726_alloc, - .free = ws_protocol_decoder_wendox_w6726_free, - - .feed = ws_protocol_decoder_wendox_w6726_feed, - .reset = ws_protocol_decoder_wendox_w6726_reset, - - .get_hash_data = ws_protocol_decoder_wendox_w6726_get_hash_data, - .serialize = ws_protocol_decoder_wendox_w6726_serialize, - .deserialize = ws_protocol_decoder_wendox_w6726_deserialize, - .get_string = ws_protocol_decoder_wendox_w6726_get_string, -}; - -const SubGhzProtocolEncoder ws_protocol_wendox_w6726_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol ws_protocol_wendox_w6726 = { - .name = WS_PROTOCOL_WENDOX_W6726_NAME, - .type = SubGhzProtocolWeatherStation, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &ws_protocol_wendox_w6726_decoder, - .encoder = &ws_protocol_wendox_w6726_encoder, -}; - -void* ws_protocol_decoder_wendox_w6726_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - WSProtocolDecoderWendoxW6726* instance = malloc(sizeof(WSProtocolDecoderWendoxW6726)); - instance->base.protocol = &ws_protocol_wendox_w6726; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void ws_protocol_decoder_wendox_w6726_free(void* context) { - furi_assert(context); - WSProtocolDecoderWendoxW6726* instance = context; - free(instance); -} - -void ws_protocol_decoder_wendox_w6726_reset(void* context) { - furi_assert(context); - WSProtocolDecoderWendoxW6726* instance = context; - instance->decoder.parser_step = WendoxW6726DecoderStepReset; -} - -static bool ws_protocol_wendox_w6726_check(WSProtocolDecoderWendoxW6726* instance) { - if(!instance->decoder.decode_data) return false; - uint8_t msg[] = { - instance->decoder.decode_data >> 28, - instance->decoder.decode_data >> 20, - instance->decoder.decode_data >> 12, - instance->decoder.decode_data >> 4}; - - uint8_t crc = subghz_protocol_blocks_crc4(msg, 4, 0x9, 0xD); - return (crc == (instance->decoder.decode_data & 0x0F)); -} - -/** - * Analysis of received data - * @param instance Pointer to a WSBlockGeneric* instance - */ -static void ws_protocol_wendox_w6726_remote_controller(WSBlockGeneric* instance) { - instance->id = (instance->data >> 24) & 0xFF; - instance->battery_low = (instance->data >> 6) & 1; - instance->channel = WS_NO_CHANNEL; - - if(((instance->data >> 23) & 1)) { - instance->temp = (float)(((instance->data >> 14) & 0x1FF) + 12) / 10.0f; - } else { - instance->temp = (float)((~(instance->data >> 14) & 0x1FF) + 1 - 12) / -10.0f; - } - - if(instance->temp < -50.0f) { - instance->temp = -50.0f; - } else if(instance->temp > 70.0f) { - instance->temp = 70.0f; - } - - instance->btn = WS_NO_BTN; - instance->humidity = WS_NO_HUMIDITY; -} - -void ws_protocol_decoder_wendox_w6726_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - WSProtocolDecoderWendoxW6726* instance = context; - - switch(instance->decoder.parser_step) { - case WendoxW6726DecoderStepReset: - if((level) && (DURATION_DIFF(duration, ws_protocol_wendox_w6726_const.te_short) < - ws_protocol_wendox_w6726_const.te_delta)) { - instance->decoder.parser_step = WendoxW6726DecoderStepCheckPreambule; - instance->decoder.te_last = duration; - instance->header_count = 0; - } - break; - - case WendoxW6726DecoderStepCheckPreambule: - if(level) { - instance->decoder.te_last = duration; - } else { - if((DURATION_DIFF(instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_short) < - ws_protocol_wendox_w6726_const.te_delta * 1) && - (DURATION_DIFF(duration, ws_protocol_wendox_w6726_const.te_long) < - ws_protocol_wendox_w6726_const.te_delta * 2)) { - instance->header_count++; - } else if((instance->header_count > 4) && (instance->header_count < 12)) { - if((DURATION_DIFF( - instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_long) < - ws_protocol_wendox_w6726_const.te_delta * 2) && - (DURATION_DIFF(duration, ws_protocol_wendox_w6726_const.te_short) < - ws_protocol_wendox_w6726_const.te_delta)) { - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = WendoxW6726DecoderStepSaveDuration; - } else { - instance->decoder.parser_step = WendoxW6726DecoderStepReset; - } - - } else { - instance->decoder.parser_step = WendoxW6726DecoderStepReset; - } - } - break; - - case WendoxW6726DecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = WendoxW6726DecoderStepCheckDuration; - } else { - instance->decoder.parser_step = WendoxW6726DecoderStepReset; - } - break; - - case WendoxW6726DecoderStepCheckDuration: - if(!level) { - if(duration > - ws_protocol_wendox_w6726_const.te_short + ws_protocol_wendox_w6726_const.te_long) { - if(DURATION_DIFF( - instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_short) < - ws_protocol_wendox_w6726_const.te_delta) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = WendoxW6726DecoderStepSaveDuration; - } else if( - DURATION_DIFF( - instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_long) < - ws_protocol_wendox_w6726_const.te_delta * 2) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = WendoxW6726DecoderStepSaveDuration; - } else { - instance->decoder.parser_step = WendoxW6726DecoderStepReset; - } - if((instance->decoder.decode_count_bit == - ws_protocol_wendox_w6726_const.min_count_bit_for_found) && - ws_protocol_wendox_w6726_check(instance)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - ws_protocol_wendox_w6726_remote_controller(&instance->generic); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - - instance->decoder.parser_step = WendoxW6726DecoderStepReset; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_short) < - ws_protocol_wendox_w6726_const.te_delta) && - (DURATION_DIFF(duration, ws_protocol_wendox_w6726_const.te_long) < - ws_protocol_wendox_w6726_const.te_delta * 3)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = WendoxW6726DecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_long) < - ws_protocol_wendox_w6726_const.te_delta * 2) && - (DURATION_DIFF(duration, ws_protocol_wendox_w6726_const.te_short) < - ws_protocol_wendox_w6726_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = WendoxW6726DecoderStepSaveDuration; - } else { - instance->decoder.parser_step = WendoxW6726DecoderStepReset; - } - } else { - instance->decoder.parser_step = WendoxW6726DecoderStepReset; - } - break; - } -} - -uint8_t ws_protocol_decoder_wendox_w6726_get_hash_data(void* context) { - furi_assert(context); - WSProtocolDecoderWendoxW6726* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -SubGhzProtocolStatus ws_protocol_decoder_wendox_w6726_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - WSProtocolDecoderWendoxW6726* instance = context; - return ws_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -SubGhzProtocolStatus - ws_protocol_decoder_wendox_w6726_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - WSProtocolDecoderWendoxW6726* instance = context; - return ws_block_generic_deserialize_check_count_bit( - &instance->generic, - flipper_format, - ws_protocol_wendox_w6726_const.min_count_bit_for_found); -} - -void ws_protocol_decoder_wendox_w6726_get_string(void* context, FuriString* output) { - furi_assert(context); - WSProtocolDecoderWendoxW6726* instance = context; - furi_string_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%lX Ch:%d Bat:%d\r\n" - "Temp:%3.1f C Hum:%d%%", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data), - instance->generic.id, - instance->generic.channel, - instance->generic.battery_low, - (double)instance->generic.temp, - instance->generic.humidity); -} diff --git a/applications/external/weather_station/protocols/wendox_w6726.h b/applications/external/weather_station/protocols/wendox_w6726.h deleted file mode 100644 index 236777a1c..000000000 --- a/applications/external/weather_station/protocols/wendox_w6726.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include "ws_generic.h" -#include - -#define WS_PROTOCOL_WENDOX_W6726_NAME "Wendox W6726" - -typedef struct WSProtocolDecoderWendoxW6726 WSProtocolDecoderWendoxW6726; -typedef struct WSProtocolEncoderWendoxW6726 WSProtocolEncoderWendoxW6726; - -extern const SubGhzProtocolDecoder ws_protocol_wendox_w6726_decoder; -extern const SubGhzProtocolEncoder ws_protocol_wendox_w6726_encoder; -extern const SubGhzProtocol ws_protocol_wendox_w6726; - -/** - * Allocate WSProtocolDecoderWendoxW6726. - * @param environment Pointer to a SubGhzEnvironment instance - * @return WSProtocolDecoderWendoxW6726* pointer to a WSProtocolDecoderWendoxW6726 instance - */ -void* ws_protocol_decoder_wendox_w6726_alloc(SubGhzEnvironment* environment); - -/** - * Free WSProtocolDecoderWendoxW6726. - * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance - */ -void ws_protocol_decoder_wendox_w6726_free(void* context); - -/** - * Reset decoder WSProtocolDecoderWendoxW6726. - * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance - */ -void ws_protocol_decoder_wendox_w6726_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void ws_protocol_decoder_wendox_w6726_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance - * @return hash Hash sum - */ -uint8_t ws_protocol_decoder_wendox_w6726_get_hash_data(void* context); - -/** - * Serialize data WSProtocolDecoderWendoxW6726. - * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_protocol_decoder_wendox_w6726_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSProtocolDecoderWendoxW6726. - * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus - ws_protocol_decoder_wendox_w6726_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance - * @param output Resulting text - */ -void ws_protocol_decoder_wendox_w6726_get_string(void* context, FuriString* output); diff --git a/applications/external/weather_station/protocols/ws_generic.c b/applications/external/weather_station/protocols/ws_generic.c deleted file mode 100644 index 026856a9e..000000000 --- a/applications/external/weather_station/protocols/ws_generic.c +++ /dev/null @@ -1,256 +0,0 @@ -#include "ws_generic.h" -#include -#include -#include "../helpers/weather_station_types.h" - -#define TAG "WSBlockGeneric" - -void ws_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str) { - const char* preset_name_temp; - if(!strcmp(preset_name, "AM270")) { - preset_name_temp = "FuriHalSubGhzPresetOok270Async"; - } else if(!strcmp(preset_name, "AM650")) { - preset_name_temp = "FuriHalSubGhzPresetOok650Async"; - } else if(!strcmp(preset_name, "FM238")) { - preset_name_temp = "FuriHalSubGhzPreset2FSKDev238Async"; - } else if(!strcmp(preset_name, "FM476")) { - preset_name_temp = "FuriHalSubGhzPreset2FSKDev476Async"; - } else { - preset_name_temp = "FuriHalSubGhzPresetCustom"; - } - furi_string_set(preset_str, preset_name_temp); -} - -SubGhzProtocolStatus ws_block_generic_serialize( - WSBlockGeneric* instance, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(instance); - SubGhzProtocolStatus res = SubGhzProtocolStatusError; - FuriString* temp_str; - temp_str = furi_string_alloc(); - do { - stream_clean(flipper_format_get_raw_stream(flipper_format)); - if(!flipper_format_write_header_cstr( - flipper_format, WS_KEY_FILE_TYPE, WS_KEY_FILE_VERSION)) { - FURI_LOG_E(TAG, "Unable to add header"); - res = SubGhzProtocolStatusErrorParserHeader; - break; - } - - if(!flipper_format_write_uint32(flipper_format, "Frequency", &preset->frequency, 1)) { - FURI_LOG_E(TAG, "Unable to add Frequency"); - res = SubGhzProtocolStatusErrorParserFrequency; - break; - } - - ws_block_generic_get_preset_name(furi_string_get_cstr(preset->name), temp_str); - if(!flipper_format_write_string_cstr( - flipper_format, "Preset", furi_string_get_cstr(temp_str))) { - FURI_LOG_E(TAG, "Unable to add Preset"); - res = SubGhzProtocolStatusErrorParserPreset; - break; - } - if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { - if(!flipper_format_write_string_cstr( - flipper_format, "Custom_preset_module", "CC1101")) { - FURI_LOG_E(TAG, "Unable to add Custom_preset_module"); - res = SubGhzProtocolStatusErrorParserCustomPreset; - break; - } - if(!flipper_format_write_hex( - flipper_format, "Custom_preset_data", preset->data, preset->data_size)) { - FURI_LOG_E(TAG, "Unable to add Custom_preset_data"); - res = SubGhzProtocolStatusErrorParserCustomPreset; - break; - } - } - if(!flipper_format_write_string_cstr(flipper_format, "Protocol", instance->protocol_name)) { - FURI_LOG_E(TAG, "Unable to add Protocol"); - res = SubGhzProtocolStatusErrorParserProtocolName; - break; - } - - uint32_t temp_data = instance->id; - if(!flipper_format_write_uint32(flipper_format, "Id", &temp_data, 1)) { - FURI_LOG_E(TAG, "Unable to add Id"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - - temp_data = instance->data_count_bit; - if(!flipper_format_write_uint32(flipper_format, "Bit", &temp_data, 1)) { - FURI_LOG_E(TAG, "Unable to add Bit"); - res = SubGhzProtocolStatusErrorParserBitCount; - break; - } - - uint8_t key_data[sizeof(uint64_t)] = {0}; - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (instance->data >> (i * 8)) & 0xFF; - } - - if(!flipper_format_write_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to add Data"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - - temp_data = instance->battery_low; - if(!flipper_format_write_uint32(flipper_format, "Batt", &temp_data, 1)) { - FURI_LOG_E(TAG, "Unable to add Battery_low"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - - temp_data = instance->humidity; - if(!flipper_format_write_uint32(flipper_format, "Hum", &temp_data, 1)) { - FURI_LOG_E(TAG, "Unable to add Humidity"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - - //DATE AGE set - FuriHalRtcDateTime curr_dt; - furi_hal_rtc_get_datetime(&curr_dt); - uint32_t curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt); - - temp_data = curr_ts; - if(!flipper_format_write_uint32(flipper_format, "Ts", &temp_data, 1)) { - FURI_LOG_E(TAG, "Unable to add timestamp"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - - temp_data = instance->channel; - if(!flipper_format_write_uint32(flipper_format, "Ch", &temp_data, 1)) { - FURI_LOG_E(TAG, "Unable to add Channel"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - - temp_data = instance->btn; - if(!flipper_format_write_uint32(flipper_format, "Btn", &temp_data, 1)) { - FURI_LOG_E(TAG, "Unable to add Btn"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - - float temp = instance->temp; - if(!flipper_format_write_float(flipper_format, "Temp", &temp, 1)) { - FURI_LOG_E(TAG, "Unable to add Temperature"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - - res = SubGhzProtocolStatusOk; - } while(false); - furi_string_free(temp_str); - return res; -} - -SubGhzProtocolStatus - ws_block_generic_deserialize(WSBlockGeneric* instance, FlipperFormat* flipper_format) { - furi_assert(instance); - SubGhzProtocolStatus res = SubGhzProtocolStatusError; - uint32_t temp_data = 0; - - do { - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - - if(!flipper_format_read_uint32(flipper_format, "Id", (uint32_t*)&temp_data, 1)) { - FURI_LOG_E(TAG, "Missing Id"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - instance->id = (uint32_t)temp_data; - - if(!flipper_format_read_uint32(flipper_format, "Bit", (uint32_t*)&temp_data, 1)) { - FURI_LOG_E(TAG, "Missing Bit"); - res = SubGhzProtocolStatusErrorParserBitCount; - break; - } - instance->data_count_bit = (uint8_t)temp_data; - - uint8_t key_data[sizeof(uint64_t)] = {0}; - if(!flipper_format_read_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Missing Data"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - - for(uint8_t i = 0; i < sizeof(uint64_t); i++) { - instance->data = instance->data << 8 | key_data[i]; - } - - if(!flipper_format_read_uint32(flipper_format, "Batt", (uint32_t*)&temp_data, 1)) { - FURI_LOG_E(TAG, "Missing Battery_low"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - instance->battery_low = (uint8_t)temp_data; - - if(!flipper_format_read_uint32(flipper_format, "Hum", (uint32_t*)&temp_data, 1)) { - FURI_LOG_E(TAG, "Missing Humidity"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - instance->humidity = (uint8_t)temp_data; - - if(!flipper_format_read_uint32(flipper_format, "Ts", (uint32_t*)&temp_data, 1)) { - FURI_LOG_E(TAG, "Missing timestamp"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - instance->timestamp = (uint32_t)temp_data; - - if(!flipper_format_read_uint32(flipper_format, "Ch", (uint32_t*)&temp_data, 1)) { - FURI_LOG_E(TAG, "Missing Channel"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - instance->channel = (uint8_t)temp_data; - - if(!flipper_format_read_uint32(flipper_format, "Btn", (uint32_t*)&temp_data, 1)) { - FURI_LOG_E(TAG, "Missing Btn"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - instance->btn = (uint8_t)temp_data; - - float temp; - if(!flipper_format_read_float(flipper_format, "Temp", (float*)&temp, 1)) { - FURI_LOG_E(TAG, "Missing Temperature"); - res = SubGhzProtocolStatusErrorParserOthers; - break; - } - instance->temp = temp; - - res = SubGhzProtocolStatusOk; - } while(0); - - return res; -} - -SubGhzProtocolStatus ws_block_generic_deserialize_check_count_bit( - WSBlockGeneric* instance, - FlipperFormat* flipper_format, - uint16_t count_bit) { - SubGhzProtocolStatus ret = SubGhzProtocolStatusError; - do { - ret = ws_block_generic_deserialize(instance, flipper_format); - if(ret != SubGhzProtocolStatusOk) { - break; - } - if(instance->data_count_bit != count_bit) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - ret = SubGhzProtocolStatusErrorValueBitCount; - break; - } - } while(false); - return ret; -} \ No newline at end of file diff --git a/applications/external/weather_station/protocols/ws_generic.h b/applications/external/weather_station/protocols/ws_generic.h deleted file mode 100644 index ff047fae6..000000000 --- a/applications/external/weather_station/protocols/ws_generic.h +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include "furi.h" -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define WS_NO_ID 0xFFFFFFFF -#define WS_NO_BATT 0xFF -#define WS_NO_HUMIDITY 0xFF -#define WS_NO_CHANNEL 0xFF -#define WS_NO_BTN 0xFF -#define WS_NO_TEMPERATURE -273.0f - -typedef struct WSBlockGeneric WSBlockGeneric; - -struct WSBlockGeneric { - const char* protocol_name; - uint64_t data; - uint32_t id; - uint8_t data_count_bit; - uint8_t battery_low; - uint8_t humidity; - uint32_t timestamp; - uint8_t channel; - uint8_t btn; - float temp; -}; - -/** - * Get name preset. - * @param preset_name name preset - * @param preset_str Output name preset - */ -void ws_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str); - -/** - * Serialize data WSBlockGeneric. - * @param instance Pointer to a WSBlockGeneric instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return status - */ -SubGhzProtocolStatus ws_block_generic_serialize( - WSBlockGeneric* instance, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data WSBlockGeneric. - * @param instance Pointer to a WSBlockGeneric instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return status - */ -SubGhzProtocolStatus - ws_block_generic_deserialize(WSBlockGeneric* instance, FlipperFormat* flipper_format); - -/** - * Deserialize data WSBlockGeneric. - * @param instance Pointer to a WSBlockGeneric instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param count_bit Count bit protocol - * @return status - */ -SubGhzProtocolStatus ws_block_generic_deserialize_check_count_bit( - WSBlockGeneric* instance, - FlipperFormat* flipper_format, - uint16_t count_bit); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/applications/external/weather_station/scenes/weather_station_receiver.c b/applications/external/weather_station/scenes/weather_station_receiver.c deleted file mode 100644 index e76810430..000000000 --- a/applications/external/weather_station/scenes/weather_station_receiver.c +++ /dev/null @@ -1,211 +0,0 @@ -#include "../weather_station_app_i.h" -#include "../views/weather_station_receiver.h" - -static const NotificationSequence subghs_sequence_rx = { - &message_green_255, - - &message_vibro_on, - &message_note_c6, - &message_delay_50, - &message_sound_off, - &message_vibro_off, - - &message_delay_50, - NULL, -}; - -static const NotificationSequence subghs_sequence_rx_locked = { - &message_green_255, - - &message_display_backlight_on, - - &message_vibro_on, - &message_note_c6, - &message_delay_50, - &message_sound_off, - &message_vibro_off, - - &message_delay_500, - - &message_display_backlight_off, - NULL, -}; - -static void weather_station_scene_receiver_update_statusbar(void* context) { - WeatherStationApp* app = context; - FuriString* history_stat_str; - history_stat_str = furi_string_alloc(); - if(!ws_history_get_text_space_left(app->txrx->history, history_stat_str)) { - FuriString* frequency_str; - FuriString* modulation_str; - - frequency_str = furi_string_alloc(); - modulation_str = furi_string_alloc(); - - ws_get_frequency_modulation(app, frequency_str, modulation_str); - - ws_view_receiver_add_data_statusbar( - app->ws_receiver, - furi_string_get_cstr(frequency_str), - furi_string_get_cstr(modulation_str), - furi_string_get_cstr(history_stat_str)); - - furi_string_free(frequency_str); - furi_string_free(modulation_str); - } else { - ws_view_receiver_add_data_statusbar( - app->ws_receiver, furi_string_get_cstr(history_stat_str), "", ""); - } - furi_string_free(history_stat_str); -} - -void weather_station_scene_receiver_callback(WSCustomEvent event, void* context) { - furi_assert(context); - WeatherStationApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -static void weather_station_scene_receiver_add_to_history_callback( - SubGhzReceiver* receiver, - SubGhzProtocolDecoderBase* decoder_base, - void* context) { - furi_assert(context); - WeatherStationApp* app = context; - FuriString* str_buff; - str_buff = furi_string_alloc(); - - if(ws_history_add_to_history(app->txrx->history, decoder_base, app->txrx->preset) == - WSHistoryStateAddKeyNewDada) { - furi_string_reset(str_buff); - - ws_history_get_text_item_menu( - app->txrx->history, str_buff, ws_history_get_item(app->txrx->history) - 1); - ws_view_receiver_add_item_to_menu( - app->ws_receiver, - furi_string_get_cstr(str_buff), - ws_history_get_type_protocol( - app->txrx->history, ws_history_get_item(app->txrx->history) - 1)); - - weather_station_scene_receiver_update_statusbar(app); - notification_message(app->notifications, &sequence_blink_green_10); - if(app->lock != WSLockOn) { - notification_message(app->notifications, &subghs_sequence_rx); - } else { - notification_message(app->notifications, &subghs_sequence_rx_locked); - } - } - subghz_receiver_reset(receiver); - furi_string_free(str_buff); - app->txrx->rx_key_state = WSRxKeyStateAddKey; -} - -void weather_station_scene_receiver_on_enter(void* context) { - WeatherStationApp* app = context; - - FuriString* str_buff; - str_buff = furi_string_alloc(); - - if(app->txrx->rx_key_state == WSRxKeyStateIDLE) { - ws_preset_init(app, "AM650", subghz_setting_get_default_frequency(app->setting), NULL, 0); - ws_history_reset(app->txrx->history); - app->txrx->rx_key_state = WSRxKeyStateStart; - } - - ws_view_receiver_set_lock(app->ws_receiver, app->lock); - - //Load history to receiver - ws_view_receiver_exit(app->ws_receiver); - for(uint8_t i = 0; i < ws_history_get_item(app->txrx->history); i++) { - furi_string_reset(str_buff); - ws_history_get_text_item_menu(app->txrx->history, str_buff, i); - ws_view_receiver_add_item_to_menu( - app->ws_receiver, - furi_string_get_cstr(str_buff), - ws_history_get_type_protocol(app->txrx->history, i)); - app->txrx->rx_key_state = WSRxKeyStateAddKey; - } - furi_string_free(str_buff); - weather_station_scene_receiver_update_statusbar(app); - - ws_view_receiver_set_callback(app->ws_receiver, weather_station_scene_receiver_callback, app); - subghz_receiver_set_rx_callback( - app->txrx->receiver, weather_station_scene_receiver_add_to_history_callback, app); - - if(app->txrx->txrx_state == WSTxRxStateRx) { - ws_rx_end(app); - }; - if((app->txrx->txrx_state == WSTxRxStateIDLE) || (app->txrx->txrx_state == WSTxRxStateSleep)) { - ws_begin( - app, - subghz_setting_get_preset_data_by_name( - app->setting, furi_string_get_cstr(app->txrx->preset->name))); - - ws_rx(app, app->txrx->preset->frequency); - } - - ws_view_receiver_set_idx_menu(app->ws_receiver, app->txrx->idx_menu_chosen); - view_dispatcher_switch_to_view(app->view_dispatcher, WeatherStationViewReceiver); -} - -bool weather_station_scene_receiver_on_event(void* context, SceneManagerEvent event) { - WeatherStationApp* app = context; - bool consumed = false; - if(event.type == SceneManagerEventTypeCustom) { - switch(event.event) { - case WSCustomEventViewReceiverBack: - // Stop CC1101 Rx - if(app->txrx->txrx_state == WSTxRxStateRx) { - ws_rx_end(app); - ws_sleep(app); - }; - app->txrx->hopper_state = WSHopperStateOFF; - app->txrx->idx_menu_chosen = 0; - subghz_receiver_set_rx_callback(app->txrx->receiver, NULL, app); - - app->txrx->rx_key_state = WSRxKeyStateIDLE; - ws_preset_init( - app, "AM650", subghz_setting_get_default_frequency(app->setting), NULL, 0); - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, WeatherStationSceneStart); - consumed = true; - break; - case WSCustomEventViewReceiverOK: - app->txrx->idx_menu_chosen = ws_view_receiver_get_idx_menu(app->ws_receiver); - scene_manager_next_scene(app->scene_manager, WeatherStationSceneReceiverInfo); - consumed = true; - break; - case WSCustomEventViewReceiverConfig: - app->txrx->idx_menu_chosen = ws_view_receiver_get_idx_menu(app->ws_receiver); - scene_manager_next_scene(app->scene_manager, WeatherStationSceneReceiverConfig); - consumed = true; - break; - case WSCustomEventViewReceiverOffDisplay: - notification_message(app->notifications, &sequence_display_backlight_off); - consumed = true; - break; - case WSCustomEventViewReceiverUnlock: - app->lock = WSLockOff; - consumed = true; - break; - default: - break; - } - } else if(event.type == SceneManagerEventTypeTick) { - if(app->txrx->hopper_state != WSHopperStateOFF) { - ws_hopper_update(app); - weather_station_scene_receiver_update_statusbar(app); - } - // Get current RSSI - float rssi = furi_hal_subghz_get_rssi(); - ws_view_receiver_set_rssi(app->ws_receiver, rssi); - - if(app->txrx->txrx_state == WSTxRxStateRx) { - notification_message(app->notifications, &sequence_blink_cyan_10); - } - } - return consumed; -} - -void weather_station_scene_receiver_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/weather_station/scenes/weather_station_scene.c b/applications/external/weather_station/scenes/weather_station_scene.c deleted file mode 100644 index f9306e5f4..000000000 --- a/applications/external/weather_station/scenes/weather_station_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "../weather_station_app_i.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const weather_station_scene_on_enter_handlers[])(void*) = { -#include "weather_station_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 weather_station_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "weather_station_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 weather_station_scene_on_exit_handlers[])(void* context) = { -#include "weather_station_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers weather_station_scene_handlers = { - .on_enter_handlers = weather_station_scene_on_enter_handlers, - .on_event_handlers = weather_station_scene_on_event_handlers, - .on_exit_handlers = weather_station_scene_on_exit_handlers, - .scene_num = WeatherStationSceneNum, -}; diff --git a/applications/external/weather_station/scenes/weather_station_scene.h b/applications/external/weather_station/scenes/weather_station_scene.h deleted file mode 100644 index 8cee4ee60..000000000 --- a/applications/external/weather_station/scenes/weather_station_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) WeatherStationScene##id, -typedef enum { -#include "weather_station_scene_config.h" - WeatherStationSceneNum, -} WeatherStationScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers weather_station_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "weather_station_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 "weather_station_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 "weather_station_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/weather_station/scenes/weather_station_scene_about.c b/applications/external/weather_station/scenes/weather_station_scene_about.c deleted file mode 100644 index d916dc76f..000000000 --- a/applications/external/weather_station/scenes/weather_station_scene_about.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "../weather_station_app_i.h" -#include "../helpers/weather_station_types.h" - -void weather_station_scene_about_widget_callback( - GuiButtonType result, - InputType type, - void* context) { - WeatherStationApp* app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(app->view_dispatcher, result); - } -} - -void weather_station_scene_about_on_enter(void* context) { - WeatherStationApp* app = context; - - FuriString* temp_str; - temp_str = furi_string_alloc(); - furi_string_printf(temp_str, "\e#%s\n", "Information"); - - furi_string_cat_printf(temp_str, "Version: %s\n", WS_VERSION_APP); - furi_string_cat_printf(temp_str, "Developed by: %s\n", WS_DEVELOPED); - furi_string_cat_printf(temp_str, "Github: %s\n\n", WS_GITHUB); - - furi_string_cat_printf(temp_str, "\e#%s\n", "Description"); - furi_string_cat_printf( - temp_str, "Reading messages from\nweather stations that work\nwith SubGhz sensors\n\n"); - - furi_string_cat_printf(temp_str, "Supported protocols:\n"); - size_t i = 0; - const char* protocol_name = - subghz_environment_get_protocol_name_registry(app->txrx->environment, i++); - do { - furi_string_cat_printf(temp_str, "%s\n", protocol_name); - protocol_name = subghz_environment_get_protocol_name_registry(app->txrx->environment, i++); - } while(protocol_name != NULL); - - widget_add_text_box_element( - app->widget, - 0, - 0, - 128, - 14, - AlignCenter, - AlignBottom, - "\e#\e! \e!\n", - false); - widget_add_text_box_element( - app->widget, - 0, - 2, - 128, - 14, - AlignCenter, - AlignBottom, - "\e#\e! Weather station \e!\n", - false); - widget_add_text_scroll_element(app->widget, 0, 16, 128, 50, furi_string_get_cstr(temp_str)); - furi_string_free(temp_str); - - view_dispatcher_switch_to_view(app->view_dispatcher, WeatherStationViewWidget); -} - -bool weather_station_scene_about_on_event(void* context, SceneManagerEvent event) { - WeatherStationApp* app = context; - bool consumed = false; - UNUSED(app); - UNUSED(event); - - return consumed; -} - -void weather_station_scene_about_on_exit(void* context) { - WeatherStationApp* app = context; - - // Clear views - widget_reset(app->widget); -} diff --git a/applications/external/weather_station/scenes/weather_station_scene_config.h b/applications/external/weather_station/scenes/weather_station_scene_config.h deleted file mode 100644 index 0ba8ec013..000000000 --- a/applications/external/weather_station/scenes/weather_station_scene_config.h +++ /dev/null @@ -1,5 +0,0 @@ -ADD_SCENE(weather_station, start, Start) -ADD_SCENE(weather_station, about, About) -ADD_SCENE(weather_station, receiver, Receiver) -ADD_SCENE(weather_station, receiver_config, ReceiverConfig) -ADD_SCENE(weather_station, receiver_info, ReceiverInfo) diff --git a/applications/external/weather_station/scenes/weather_station_scene_receiver_config.c b/applications/external/weather_station/scenes/weather_station_scene_receiver_config.c deleted file mode 100644 index fcd8f6d3e..000000000 --- a/applications/external/weather_station/scenes/weather_station_scene_receiver_config.c +++ /dev/null @@ -1,223 +0,0 @@ -#include "../weather_station_app_i.h" - -enum WSSettingIndex { - WSSettingIndexFrequency, - WSSettingIndexHopping, - WSSettingIndexModulation, - WSSettingIndexLock, -}; - -#define HOPPING_COUNT 2 -const char* const hopping_text[HOPPING_COUNT] = { - "OFF", - "ON", -}; -const uint32_t hopping_value[HOPPING_COUNT] = { - WSHopperStateOFF, - WSHopperStateRunnig, -}; - -uint8_t weather_station_scene_receiver_config_next_frequency(const uint32_t value, void* context) { - furi_assert(context); - WeatherStationApp* app = context; - uint8_t index = 0; - for(uint8_t i = 0; i < subghz_setting_get_frequency_count(app->setting); i++) { - if(value == subghz_setting_get_frequency(app->setting, i)) { - index = i; - break; - } else { - index = subghz_setting_get_frequency_default_index(app->setting); - } - } - return index; -} - -uint8_t weather_station_scene_receiver_config_next_preset(const char* preset_name, void* context) { - furi_assert(context); - WeatherStationApp* app = context; - uint8_t index = 0; - for(uint8_t i = 0; i < subghz_setting_get_preset_count(app->setting); i++) { - if(!strcmp(subghz_setting_get_preset_name(app->setting, i), preset_name)) { - index = i; - break; - } else { - // index = subghz_setting_get_frequency_default_index(app ->setting); - } - } - return index; -} - -uint8_t weather_station_scene_receiver_config_hopper_value_index( - const uint32_t value, - const uint32_t values[], - uint8_t values_count, - void* context) { - furi_assert(context); - UNUSED(values_count); - WeatherStationApp* app = context; - - if(value == values[0]) { - return 0; - } else { - variable_item_set_current_value_text( - (VariableItem*)scene_manager_get_scene_state( - app->scene_manager, WeatherStationSceneReceiverConfig), - " -----"); - return 1; - } -} - -static void weather_station_scene_receiver_config_set_frequency(VariableItem* item) { - WeatherStationApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - - if(app->txrx->hopper_state == WSHopperStateOFF) { - char text_buf[10] = {0}; - snprintf( - text_buf, - sizeof(text_buf), - "%lu.%02lu", - subghz_setting_get_frequency(app->setting, index) / 1000000, - (subghz_setting_get_frequency(app->setting, index) % 1000000) / 10000); - variable_item_set_current_value_text(item, text_buf); - app->txrx->preset->frequency = subghz_setting_get_frequency(app->setting, index); - } else { - variable_item_set_current_value_index( - item, subghz_setting_get_frequency_default_index(app->setting)); - } -} - -static void weather_station_scene_receiver_config_set_preset(VariableItem* item) { - WeatherStationApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text( - item, subghz_setting_get_preset_name(app->setting, index)); - ws_preset_init( - app, - subghz_setting_get_preset_name(app->setting, index), - app->txrx->preset->frequency, - subghz_setting_get_preset_data(app->setting, index), - subghz_setting_get_preset_data_size(app->setting, index)); -} - -static void weather_station_scene_receiver_config_set_hopping_running(VariableItem* item) { - WeatherStationApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - - variable_item_set_current_value_text(item, hopping_text[index]); - if(hopping_value[index] == WSHopperStateOFF) { - char text_buf[10] = {0}; - snprintf( - text_buf, - sizeof(text_buf), - "%lu.%02lu", - subghz_setting_get_default_frequency(app->setting) / 1000000, - (subghz_setting_get_default_frequency(app->setting) % 1000000) / 10000); - variable_item_set_current_value_text( - (VariableItem*)scene_manager_get_scene_state( - app->scene_manager, WeatherStationSceneReceiverConfig), - text_buf); - app->txrx->preset->frequency = subghz_setting_get_default_frequency(app->setting); - variable_item_set_current_value_index( - (VariableItem*)scene_manager_get_scene_state( - app->scene_manager, WeatherStationSceneReceiverConfig), - subghz_setting_get_frequency_default_index(app->setting)); - } else { - variable_item_set_current_value_text( - (VariableItem*)scene_manager_get_scene_state( - app->scene_manager, WeatherStationSceneReceiverConfig), - " -----"); - variable_item_set_current_value_index( - (VariableItem*)scene_manager_get_scene_state( - app->scene_manager, WeatherStationSceneReceiverConfig), - subghz_setting_get_frequency_default_index(app->setting)); - } - - app->txrx->hopper_state = hopping_value[index]; -} - -static void - weather_station_scene_receiver_config_var_list_enter_callback(void* context, uint32_t index) { - furi_assert(context); - WeatherStationApp* app = context; - if(index == WSSettingIndexLock) { - view_dispatcher_send_custom_event(app->view_dispatcher, WSCustomEventSceneSettingLock); - } -} - -void weather_station_scene_receiver_config_on_enter(void* context) { - WeatherStationApp* app = context; - VariableItem* item; - uint8_t value_index; - - item = variable_item_list_add( - app->variable_item_list, - "Frequency:", - subghz_setting_get_frequency_count(app->setting), - weather_station_scene_receiver_config_set_frequency, - app); - value_index = - weather_station_scene_receiver_config_next_frequency(app->txrx->preset->frequency, app); - scene_manager_set_scene_state( - app->scene_manager, WeatherStationSceneReceiverConfig, (uint32_t)item); - variable_item_set_current_value_index(item, value_index); - char text_buf[10] = {0}; - snprintf( - text_buf, - sizeof(text_buf), - "%lu.%02lu", - subghz_setting_get_frequency(app->setting, value_index) / 1000000, - (subghz_setting_get_frequency(app->setting, value_index) % 1000000) / 10000); - variable_item_set_current_value_text(item, text_buf); - - item = variable_item_list_add( - app->variable_item_list, - "Hopping:", - HOPPING_COUNT, - weather_station_scene_receiver_config_set_hopping_running, - app); - value_index = weather_station_scene_receiver_config_hopper_value_index( - app->txrx->hopper_state, hopping_value, HOPPING_COUNT, app); - variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, hopping_text[value_index]); - - item = variable_item_list_add( - app->variable_item_list, - "Modulation:", - subghz_setting_get_preset_count(app->setting), - weather_station_scene_receiver_config_set_preset, - app); - value_index = weather_station_scene_receiver_config_next_preset( - furi_string_get_cstr(app->txrx->preset->name), app); - variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text( - item, subghz_setting_get_preset_name(app->setting, value_index)); - - variable_item_list_add(app->variable_item_list, "Lock Keyboard", 1, NULL, NULL); - variable_item_list_set_enter_callback( - app->variable_item_list, - weather_station_scene_receiver_config_var_list_enter_callback, - app); - - view_dispatcher_switch_to_view(app->view_dispatcher, WeatherStationViewVariableItemList); -} - -bool weather_station_scene_receiver_config_on_event(void* context, SceneManagerEvent event) { - WeatherStationApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == WSCustomEventSceneSettingLock) { - app->lock = WSLockOn; - scene_manager_previous_scene(app->scene_manager); - consumed = true; - } - } - return consumed; -} - -void weather_station_scene_receiver_config_on_exit(void* context) { - WeatherStationApp* app = context; - variable_item_list_set_selected_item(app->variable_item_list, 0); - variable_item_list_reset(app->variable_item_list); -} diff --git a/applications/external/weather_station/scenes/weather_station_scene_receiver_info.c b/applications/external/weather_station/scenes/weather_station_scene_receiver_info.c deleted file mode 100644 index b26661be3..000000000 --- a/applications/external/weather_station/scenes/weather_station_scene_receiver_info.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "../weather_station_app_i.h" -#include "../views/weather_station_receiver.h" - -void weather_station_scene_receiver_info_callback(WSCustomEvent event, void* context) { - furi_assert(context); - WeatherStationApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -static void weather_station_scene_receiver_info_add_to_history_callback( - SubGhzReceiver* receiver, - SubGhzProtocolDecoderBase* decoder_base, - void* context) { - furi_assert(context); - WeatherStationApp* app = context; - - if(ws_history_add_to_history(app->txrx->history, decoder_base, app->txrx->preset) == - WSHistoryStateAddKeyUpdateData) { - ws_view_receiver_info_update( - app->ws_receiver_info, - ws_history_get_raw_data(app->txrx->history, app->txrx->idx_menu_chosen)); - subghz_receiver_reset(receiver); - - notification_message(app->notifications, &sequence_blink_green_10); - app->txrx->rx_key_state = WSRxKeyStateAddKey; - } -} - -void weather_station_scene_receiver_info_on_enter(void* context) { - WeatherStationApp* app = context; - - subghz_receiver_set_rx_callback( - app->txrx->receiver, weather_station_scene_receiver_info_add_to_history_callback, app); - ws_view_receiver_info_update( - app->ws_receiver_info, - ws_history_get_raw_data(app->txrx->history, app->txrx->idx_menu_chosen)); - view_dispatcher_switch_to_view(app->view_dispatcher, WeatherStationViewReceiverInfo); -} - -bool weather_station_scene_receiver_info_on_event(void* context, SceneManagerEvent event) { - WeatherStationApp* app = context; - bool consumed = false; - UNUSED(app); - UNUSED(event); - return consumed; -} - -void weather_station_scene_receiver_info_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/weather_station/scenes/weather_station_scene_start.c b/applications/external/weather_station/scenes/weather_station_scene_start.c deleted file mode 100644 index 56dd6fa86..000000000 --- a/applications/external/weather_station/scenes/weather_station_scene_start.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "../weather_station_app_i.h" - -typedef enum { - SubmenuIndexWeatherStationReceiver, - SubmenuIndexWeatherStationAbout, -} SubmenuIndex; - -void weather_station_scene_start_submenu_callback(void* context, uint32_t index) { - WeatherStationApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void weather_station_scene_start_on_enter(void* context) { - UNUSED(context); - WeatherStationApp* app = context; - Submenu* submenu = app->submenu; - - submenu_add_item( - submenu, - "Read Weather Station", - SubmenuIndexWeatherStationReceiver, - weather_station_scene_start_submenu_callback, - app); - submenu_add_item( - submenu, - "About", - SubmenuIndexWeatherStationAbout, - weather_station_scene_start_submenu_callback, - app); - - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(app->scene_manager, WeatherStationSceneStart)); - - view_dispatcher_switch_to_view(app->view_dispatcher, WeatherStationViewSubmenu); -} - -bool weather_station_scene_start_on_event(void* context, SceneManagerEvent event) { - WeatherStationApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexWeatherStationAbout) { - scene_manager_next_scene(app->scene_manager, WeatherStationSceneAbout); - consumed = true; - } else if(event.event == SubmenuIndexWeatherStationReceiver) { - scene_manager_next_scene(app->scene_manager, WeatherStationSceneReceiver); - consumed = true; - } - scene_manager_set_scene_state(app->scene_manager, WeatherStationSceneStart, event.event); - } - - return consumed; -} - -void weather_station_scene_start_on_exit(void* context) { - WeatherStationApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/external/weather_station/views/weather_station_receiver.c b/applications/external/weather_station/views/weather_station_receiver.c deleted file mode 100644 index c4ce1627e..000000000 --- a/applications/external/weather_station/views/weather_station_receiver.c +++ /dev/null @@ -1,464 +0,0 @@ -#include "weather_station_receiver.h" -#include "../weather_station_app_i.h" -#include -#include - -#include -#include -#include - -#define FRAME_HEIGHT 12 -#define MAX_LEN_PX 112 -#define MENU_ITEMS 4u -#define UNLOCK_CNT 3 - -#define SUBGHZ_RAW_THRESHOLD_MIN -90.0f -typedef struct { - FuriString* item_str; - uint8_t type; -} WSReceiverMenuItem; - -ARRAY_DEF(WSReceiverMenuItemArray, WSReceiverMenuItem, M_POD_OPLIST) - -#define M_OPL_WSReceiverMenuItemArray_t() ARRAY_OPLIST(WSReceiverMenuItemArray, M_POD_OPLIST) - -struct WSReceiverHistory { - WSReceiverMenuItemArray_t data; -}; - -typedef struct WSReceiverHistory WSReceiverHistory; - -static const Icon* ReceiverItemIcons[] = { - [SubGhzProtocolTypeUnknown] = &I_Quest_7x8, - [SubGhzProtocolTypeStatic] = &I_Unlock_7x8, - [SubGhzProtocolTypeDynamic] = &I_Lock_7x8, - [SubGhzProtocolWeatherStation] = &I_station_icon, -}; - -typedef enum { - WSReceiverBarShowDefault, - WSReceiverBarShowLock, - WSReceiverBarShowToUnlockPress, - WSReceiverBarShowUnlock, -} WSReceiverBarShow; - -struct WSReceiver { - WSLock lock; - uint8_t lock_count; - FuriTimer* timer; - View* view; - WSReceiverCallback callback; - void* context; -}; - -typedef struct { - FuriString* frequency_str; - FuriString* preset_str; - FuriString* history_stat_str; - WSReceiverHistory* history; - uint16_t idx; - uint16_t list_offset; - uint16_t history_item; - WSReceiverBarShow bar_show; - uint8_t u_rssi; -} WSReceiverModel; - -void ws_view_receiver_set_rssi(WSReceiver* instance, float rssi) { - furi_assert(instance); - with_view_model( - instance->view, - WSReceiverModel * model, - { - if(rssi < SUBGHZ_RAW_THRESHOLD_MIN) { - model->u_rssi = 0; - } else { - model->u_rssi = (uint8_t)(rssi - SUBGHZ_RAW_THRESHOLD_MIN); - } - }, - true); -} - -void ws_view_receiver_set_lock(WSReceiver* ws_receiver, WSLock lock) { - furi_assert(ws_receiver); - ws_receiver->lock_count = 0; - if(lock == WSLockOn) { - ws_receiver->lock = lock; - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { model->bar_show = WSReceiverBarShowLock; }, - true); - furi_timer_start(ws_receiver->timer, pdMS_TO_TICKS(1000)); - } else { - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { model->bar_show = WSReceiverBarShowDefault; }, - true); - } -} - -void ws_view_receiver_set_callback( - WSReceiver* ws_receiver, - WSReceiverCallback callback, - void* context) { - furi_assert(ws_receiver); - furi_assert(callback); - ws_receiver->callback = callback; - ws_receiver->context = context; -} - -static void ws_view_receiver_update_offset(WSReceiver* ws_receiver) { - furi_assert(ws_receiver); - - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - size_t history_item = model->history_item; - uint16_t bounds = history_item > 3 ? 2 : history_item; - - if(history_item > 3 && model->idx >= (int16_t)(history_item - 1)) { - model->list_offset = model->idx - 3; - } else if(model->list_offset < model->idx - bounds) { - model->list_offset = - CLAMP(model->list_offset + 1, (int16_t)(history_item - bounds), 0); - } else if(model->list_offset > model->idx - bounds) { - model->list_offset = CLAMP(model->idx - 1, (int16_t)(history_item - bounds), 0); - } - }, - true); -} - -void ws_view_receiver_add_item_to_menu(WSReceiver* ws_receiver, const char* name, uint8_t type) { - furi_assert(ws_receiver); - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - WSReceiverMenuItem* item_menu = WSReceiverMenuItemArray_push_raw(model->history->data); - item_menu->item_str = furi_string_alloc_set(name); - item_menu->type = type; - if((model->idx == model->history_item - 1)) { - model->history_item++; - model->idx++; - } else { - model->history_item++; - } - }, - true); - ws_view_receiver_update_offset(ws_receiver); -} - -void ws_view_receiver_add_data_statusbar( - WSReceiver* ws_receiver, - const char* frequency_str, - const char* preset_str, - const char* history_stat_str) { - furi_assert(ws_receiver); - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - furi_string_set_str(model->frequency_str, frequency_str); - furi_string_set_str(model->preset_str, preset_str); - furi_string_set_str(model->history_stat_str, history_stat_str); - }, - true); -} - -static void ws_view_receiver_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar) { - canvas_set_color(canvas, ColorBlack); - canvas_draw_box(canvas, 0, 0 + idx * FRAME_HEIGHT, scrollbar ? 122 : 127, FRAME_HEIGHT); - - canvas_set_color(canvas, ColorWhite); - canvas_draw_dot(canvas, 0, 0 + idx * FRAME_HEIGHT); - canvas_draw_dot(canvas, 1, 0 + idx * FRAME_HEIGHT); - canvas_draw_dot(canvas, 0, (0 + idx * FRAME_HEIGHT) + 1); - - canvas_draw_dot(canvas, 0, (0 + idx * FRAME_HEIGHT) + 11); - canvas_draw_dot(canvas, scrollbar ? 121 : 126, 0 + idx * FRAME_HEIGHT); - canvas_draw_dot(canvas, scrollbar ? 121 : 126, (0 + idx * FRAME_HEIGHT) + 11); -} - -static void ws_view_rssi_draw(Canvas* canvas, WSReceiverModel* model) { - for(uint8_t i = 1; i < model->u_rssi; i++) { - if(i % 5) { - canvas_draw_dot(canvas, 46 + i, 50); - canvas_draw_dot(canvas, 47 + i, 51); - canvas_draw_dot(canvas, 46 + i, 52); - } - } -} - -void ws_view_receiver_draw(Canvas* canvas, WSReceiverModel* model) { - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontSecondary); - - elements_button_left(canvas, "Config"); - - bool scrollbar = model->history_item > 4; - FuriString* str_buff; - str_buff = furi_string_alloc(); - - WSReceiverMenuItem* item_menu; - - for(size_t i = 0; i < MIN(model->history_item, MENU_ITEMS); ++i) { - size_t idx = CLAMP((uint16_t)(i + model->list_offset), model->history_item, 0); - item_menu = WSReceiverMenuItemArray_get(model->history->data, idx); - furi_string_set(str_buff, item_menu->item_str); - elements_string_fit_width(canvas, str_buff, scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX); - if(model->idx == idx) { - ws_view_receiver_draw_frame(canvas, i, scrollbar); - } else { - canvas_set_color(canvas, ColorBlack); - } - canvas_draw_icon(canvas, 4, 2 + i * FRAME_HEIGHT, ReceiverItemIcons[item_menu->type]); - canvas_draw_str(canvas, 14, 9 + i * FRAME_HEIGHT, furi_string_get_cstr(str_buff)); - furi_string_reset(str_buff); - } - if(scrollbar) { - elements_scrollbar_pos(canvas, 128, 0, 49, model->idx, model->history_item); - } - furi_string_free(str_buff); - - canvas_set_color(canvas, ColorBlack); - - if(model->history_item == 0) { - canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 63, 46, "Scanning..."); - canvas_set_font(canvas, FontSecondary); - } - - // Draw RSSI - ws_view_rssi_draw(canvas, model); - - switch(model->bar_show) { - case WSReceiverBarShowLock: - canvas_draw_icon(canvas, 64, 55, &I_Lock_7x8); - canvas_draw_str(canvas, 74, 62, "Locked"); - break; - case WSReceiverBarShowToUnlockPress: - canvas_draw_str(canvas, 44, 62, furi_string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 79, 62, furi_string_get_cstr(model->preset_str)); - canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str)); - canvas_set_font(canvas, FontSecondary); - elements_bold_rounded_frame(canvas, 14, 8, 99, 48); - elements_multiline_text(canvas, 65, 26, "To unlock\npress:"); - canvas_draw_icon(canvas, 65, 42, &I_Pin_back_arrow_10x8); - canvas_draw_icon(canvas, 80, 42, &I_Pin_back_arrow_10x8); - canvas_draw_icon(canvas, 95, 42, &I_Pin_back_arrow_10x8); - canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42); - canvas_draw_dot(canvas, 17, 61); - break; - case WSReceiverBarShowUnlock: - canvas_draw_icon(canvas, 64, 55, &I_Unlock_7x8); - canvas_draw_str(canvas, 74, 62, "Unlocked"); - break; - default: - canvas_draw_str(canvas, 44, 62, furi_string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 79, 62, furi_string_get_cstr(model->preset_str)); - canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str)); - break; - } -} - -static void ws_view_receiver_timer_callback(void* context) { - furi_assert(context); - WSReceiver* ws_receiver = context; - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { model->bar_show = WSReceiverBarShowDefault; }, - true); - if(ws_receiver->lock_count < UNLOCK_CNT) { - ws_receiver->callback(WSCustomEventViewReceiverOffDisplay, ws_receiver->context); - } else { - ws_receiver->lock = WSLockOff; - ws_receiver->callback(WSCustomEventViewReceiverUnlock, ws_receiver->context); - } - ws_receiver->lock_count = 0; -} - -bool ws_view_receiver_input(InputEvent* event, void* context) { - furi_assert(context); - WSReceiver* ws_receiver = context; - - if(ws_receiver->lock == WSLockOn) { - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { model->bar_show = WSReceiverBarShowToUnlockPress; }, - true); - if(ws_receiver->lock_count == 0) { - furi_timer_start(ws_receiver->timer, pdMS_TO_TICKS(1000)); - } - if(event->key == InputKeyBack && event->type == InputTypeShort) { - ws_receiver->lock_count++; - } - if(ws_receiver->lock_count >= UNLOCK_CNT) { - ws_receiver->callback(WSCustomEventViewReceiverUnlock, ws_receiver->context); - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { model->bar_show = WSReceiverBarShowUnlock; }, - true); - ws_receiver->lock = WSLockOff; - furi_timer_start(ws_receiver->timer, pdMS_TO_TICKS(650)); - } - - return true; - } - - if(event->key == InputKeyBack && event->type == InputTypeShort) { - ws_receiver->callback(WSCustomEventViewReceiverBack, ws_receiver->context); - } else if( - event->key == InputKeyUp && - (event->type == InputTypeShort || event->type == InputTypeRepeat)) { - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - if(model->idx != 0) model->idx--; - }, - true); - } else if( - event->key == InputKeyDown && - (event->type == InputTypeShort || event->type == InputTypeRepeat)) { - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - if(model->history_item && model->idx != model->history_item - 1) model->idx++; - }, - true); - } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { - ws_receiver->callback(WSCustomEventViewReceiverConfig, ws_receiver->context); - } else if(event->key == InputKeyOk && event->type == InputTypeShort) { - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - if(model->history_item != 0) { - ws_receiver->callback(WSCustomEventViewReceiverOK, ws_receiver->context); - } - }, - false); - } - - ws_view_receiver_update_offset(ws_receiver); - - return true; -} - -void ws_view_receiver_enter(void* context) { - furi_assert(context); -} - -void ws_view_receiver_exit(void* context) { - furi_assert(context); - WSReceiver* ws_receiver = context; - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - furi_string_reset(model->frequency_str); - furi_string_reset(model->preset_str); - furi_string_reset(model->history_stat_str); - for - M_EACH(item_menu, model->history->data, WSReceiverMenuItemArray_t) { - furi_string_free(item_menu->item_str); - item_menu->type = 0; - } - WSReceiverMenuItemArray_reset(model->history->data); - model->idx = 0; - model->list_offset = 0; - model->history_item = 0; - }, - false); - furi_timer_stop(ws_receiver->timer); -} - -WSReceiver* ws_view_receiver_alloc() { - WSReceiver* ws_receiver = malloc(sizeof(WSReceiver)); - - // View allocation and configuration - ws_receiver->view = view_alloc(); - - ws_receiver->lock = WSLockOff; - ws_receiver->lock_count = 0; - view_allocate_model(ws_receiver->view, ViewModelTypeLocking, sizeof(WSReceiverModel)); - view_set_context(ws_receiver->view, ws_receiver); - view_set_draw_callback(ws_receiver->view, (ViewDrawCallback)ws_view_receiver_draw); - view_set_input_callback(ws_receiver->view, ws_view_receiver_input); - view_set_enter_callback(ws_receiver->view, ws_view_receiver_enter); - view_set_exit_callback(ws_receiver->view, ws_view_receiver_exit); - - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - model->frequency_str = furi_string_alloc(); - model->preset_str = furi_string_alloc(); - model->history_stat_str = furi_string_alloc(); - model->bar_show = WSReceiverBarShowDefault; - model->history = malloc(sizeof(WSReceiverHistory)); - WSReceiverMenuItemArray_init(model->history->data); - }, - true); - ws_receiver->timer = - furi_timer_alloc(ws_view_receiver_timer_callback, FuriTimerTypeOnce, ws_receiver); - return ws_receiver; -} - -void ws_view_receiver_free(WSReceiver* ws_receiver) { - furi_assert(ws_receiver); - - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - furi_string_free(model->frequency_str); - furi_string_free(model->preset_str); - furi_string_free(model->history_stat_str); - for - M_EACH(item_menu, model->history->data, WSReceiverMenuItemArray_t) { - furi_string_free(item_menu->item_str); - item_menu->type = 0; - } - WSReceiverMenuItemArray_clear(model->history->data); - free(model->history); - }, - false); - furi_timer_free(ws_receiver->timer); - view_free(ws_receiver->view); - free(ws_receiver); -} - -View* ws_view_receiver_get_view(WSReceiver* ws_receiver) { - furi_assert(ws_receiver); - return ws_receiver->view; -} - -uint16_t ws_view_receiver_get_idx_menu(WSReceiver* ws_receiver) { - furi_assert(ws_receiver); - uint32_t idx = 0; - with_view_model( - ws_receiver->view, WSReceiverModel * model, { idx = model->idx; }, false); - return idx; -} - -void ws_view_receiver_set_idx_menu(WSReceiver* ws_receiver, uint16_t idx) { - furi_assert(ws_receiver); - with_view_model( - ws_receiver->view, - WSReceiverModel * model, - { - model->idx = idx; - if(model->idx > 2) model->list_offset = idx - 2; - }, - true); - ws_view_receiver_update_offset(ws_receiver); -} diff --git a/applications/external/weather_station/views/weather_station_receiver.h b/applications/external/weather_station/views/weather_station_receiver.h deleted file mode 100644 index f81aa1f5e..000000000 --- a/applications/external/weather_station/views/weather_station_receiver.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include -#include "../helpers/weather_station_types.h" -#include "../helpers/weather_station_event.h" - -typedef struct WSReceiver WSReceiver; - -typedef void (*WSReceiverCallback)(WSCustomEvent event, void* context); - -void ws_view_receiver_set_rssi(WSReceiver* instance, float rssi); - -void ws_view_receiver_set_lock(WSReceiver* ws_receiver, WSLock keyboard); - -void ws_view_receiver_set_callback( - WSReceiver* ws_receiver, - WSReceiverCallback callback, - void* context); - -WSReceiver* ws_view_receiver_alloc(); - -void ws_view_receiver_free(WSReceiver* ws_receiver); - -View* ws_view_receiver_get_view(WSReceiver* ws_receiver); - -void ws_view_receiver_add_data_statusbar( - WSReceiver* ws_receiver, - const char* frequency_str, - const char* preset_str, - const char* history_stat_str); - -void ws_view_receiver_add_item_to_menu(WSReceiver* ws_receiver, const char* name, uint8_t type); - -uint16_t ws_view_receiver_get_idx_menu(WSReceiver* ws_receiver); - -void ws_view_receiver_set_idx_menu(WSReceiver* ws_receiver, uint16_t idx); - -void ws_view_receiver_exit(void* context); diff --git a/applications/external/weather_station/views/weather_station_receiver_info.c b/applications/external/weather_station/views/weather_station_receiver_info.c deleted file mode 100644 index b3b3f2193..000000000 --- a/applications/external/weather_station/views/weather_station_receiver_info.c +++ /dev/null @@ -1,245 +0,0 @@ -#include "weather_station_receiver.h" -#include "../weather_station_app_i.h" -#include "weather_station_icons.h" -#include "../protocols/ws_generic.h" -#include -#include -#include - -struct WSReceiverInfo { - View* view; - FuriTimer* timer; -}; - -typedef struct { - uint32_t curr_ts; - FuriString* protocol_name; - WSBlockGeneric* generic; -} WSReceiverInfoModel; - -void ws_view_receiver_info_update(WSReceiverInfo* ws_receiver_info, FlipperFormat* fff) { - furi_assert(ws_receiver_info); - furi_assert(fff); - - with_view_model( - ws_receiver_info->view, - WSReceiverInfoModel * model, - { - flipper_format_rewind(fff); - flipper_format_read_string(fff, "Protocol", model->protocol_name); - - ws_block_generic_deserialize(model->generic, fff); - - FuriHalRtcDateTime curr_dt; - furi_hal_rtc_get_datetime(&curr_dt); - model->curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt); - }, - true); -} - -void ws_view_receiver_info_draw(Canvas* canvas, WSReceiverInfoModel* model) { - char buffer[64]; - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontSecondary); - - snprintf( - buffer, - sizeof(buffer), - "%s %db", - furi_string_get_cstr(model->protocol_name), - model->generic->data_count_bit); - canvas_draw_str(canvas, 0, 8, buffer); - - if(model->generic->channel != WS_NO_CHANNEL) { - snprintf(buffer, sizeof(buffer), "Ch: %01d", model->generic->channel); - canvas_draw_str(canvas, 106, 8, buffer); - } - - if(model->generic->id != WS_NO_ID) { - snprintf(buffer, sizeof(buffer), "Sn: 0x%02lX", model->generic->id); - canvas_draw_str(canvas, 0, 20, buffer); - } - - if(model->generic->btn != WS_NO_BTN) { - snprintf(buffer, sizeof(buffer), "Btn: %01d", model->generic->btn); - canvas_draw_str(canvas, 57, 20, buffer); - } - - if(model->generic->battery_low != WS_NO_BATT) { - snprintf( - buffer, sizeof(buffer), "Batt: %s", (!model->generic->battery_low ? "ok" : "low")); - canvas_draw_str_aligned(canvas, 126, 17, AlignRight, AlignCenter, buffer); - } - - snprintf(buffer, sizeof(buffer), "Data: 0x%llX", model->generic->data); - canvas_draw_str(canvas, 0, 32, buffer); - - elements_bold_rounded_frame(canvas, 0, 38, 127, 25); - canvas_set_font(canvas, FontPrimary); - - if(!float_is_equal(model->generic->temp, WS_NO_TEMPERATURE)) { - canvas_draw_icon(canvas, 6, 43, &I_Therm_7x16); - - uint8_t temp_x1 = 0; - uint8_t temp_x2 = 0; - if(furi_hal_rtc_get_locale_units() == FuriHalRtcLocaleUnitsMetric) { - snprintf(buffer, sizeof(buffer), "%3.1f C", (double)model->generic->temp); - if(model->generic->temp < -9.0f) { - temp_x1 = 49; - temp_x2 = 40; - } else { - temp_x1 = 47; - temp_x2 = 38; - } - } else { - snprintf( - buffer, - sizeof(buffer), - "%3.1f F", - (double)locale_celsius_to_fahrenheit(model->generic->temp)); - if((model->generic->temp < -27.77f) || (model->generic->temp > 37.77f)) { - temp_x1 = 50; - temp_x2 = 42; - } else { - temp_x1 = 48; - temp_x2 = 40; - } - } - - canvas_draw_str_aligned(canvas, temp_x1, 47, AlignRight, AlignTop, buffer); - canvas_draw_circle(canvas, temp_x2, 46, 1); - } - - if(model->generic->humidity != WS_NO_HUMIDITY) { - canvas_draw_icon(canvas, 53, 44, &I_Humid_8x13); - snprintf(buffer, sizeof(buffer), "%d%%", model->generic->humidity); - canvas_draw_str(canvas, 64, 55, buffer); - } - - if((int)model->generic->timestamp > 0 && model->curr_ts) { - int ts_diff = (int)model->curr_ts - (int)model->generic->timestamp; - - canvas_draw_icon(canvas, 91, 46, &I_Timer_11x11); - - if(ts_diff > 60) { - int tmp_sec = ts_diff; - int cnt_min = 1; - for(int i = 1; tmp_sec > 60; i++) { - tmp_sec = tmp_sec - 60; - cnt_min = i; - } - - if(model->curr_ts % 2 == 0) { - canvas_draw_str_aligned(canvas, 105, 51, AlignLeft, AlignCenter, "Old"); - } else { - if(cnt_min >= 59) { - canvas_draw_str_aligned(canvas, 105, 51, AlignLeft, AlignCenter, "Old"); - } else { - snprintf(buffer, sizeof(buffer), "%dm", cnt_min); - canvas_draw_str_aligned(canvas, 114, 51, AlignCenter, AlignCenter, buffer); - } - } - - } else { - snprintf(buffer, sizeof(buffer), "%d", ts_diff); - canvas_draw_str_aligned(canvas, 112, 51, AlignCenter, AlignCenter, buffer); - } - } -} - -bool ws_view_receiver_info_input(InputEvent* event, void* context) { - furi_assert(context); - //WSReceiverInfo* ws_receiver_info = context; - - if(event->key == InputKeyBack) { - return false; - } - - return true; -} - -static void ws_view_receiver_info_enter(void* context) { - furi_assert(context); - WSReceiverInfo* ws_receiver_info = context; - - furi_timer_start(ws_receiver_info->timer, 1000); -} - -static void ws_view_receiver_info_exit(void* context) { - furi_assert(context); - WSReceiverInfo* ws_receiver_info = context; - - furi_timer_stop(ws_receiver_info->timer); - - with_view_model( - ws_receiver_info->view, - WSReceiverInfoModel * model, - { furi_string_reset(model->protocol_name); }, - false); -} - -static void ws_view_receiver_info_timer(void* context) { - WSReceiverInfo* ws_receiver_info = context; - // Force redraw - with_view_model( - ws_receiver_info->view, - WSReceiverInfoModel * model, - { - FuriHalRtcDateTime curr_dt; - furi_hal_rtc_get_datetime(&curr_dt); - model->curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt); - }, - true); -} - -WSReceiverInfo* ws_view_receiver_info_alloc() { - WSReceiverInfo* ws_receiver_info = malloc(sizeof(WSReceiverInfo)); - - // View allocation and configuration - ws_receiver_info->view = view_alloc(); - - view_allocate_model(ws_receiver_info->view, ViewModelTypeLocking, sizeof(WSReceiverInfoModel)); - view_set_context(ws_receiver_info->view, ws_receiver_info); - view_set_draw_callback(ws_receiver_info->view, (ViewDrawCallback)ws_view_receiver_info_draw); - view_set_input_callback(ws_receiver_info->view, ws_view_receiver_info_input); - view_set_enter_callback(ws_receiver_info->view, ws_view_receiver_info_enter); - view_set_exit_callback(ws_receiver_info->view, ws_view_receiver_info_exit); - - with_view_model( - ws_receiver_info->view, - WSReceiverInfoModel * model, - { - model->generic = malloc(sizeof(WSBlockGeneric)); - model->protocol_name = furi_string_alloc(); - }, - true); - - ws_receiver_info->timer = - furi_timer_alloc(ws_view_receiver_info_timer, FuriTimerTypePeriodic, ws_receiver_info); - - return ws_receiver_info; -} - -void ws_view_receiver_info_free(WSReceiverInfo* ws_receiver_info) { - furi_assert(ws_receiver_info); - - furi_timer_free(ws_receiver_info->timer); - - with_view_model( - ws_receiver_info->view, - WSReceiverInfoModel * model, - { - furi_string_free(model->protocol_name); - free(model->generic); - }, - false); - - view_free(ws_receiver_info->view); - free(ws_receiver_info); -} - -View* ws_view_receiver_info_get_view(WSReceiverInfo* ws_receiver_info) { - furi_assert(ws_receiver_info); - return ws_receiver_info->view; -} diff --git a/applications/external/weather_station/views/weather_station_receiver_info.h b/applications/external/weather_station/views/weather_station_receiver_info.h deleted file mode 100644 index 705434a23..000000000 --- a/applications/external/weather_station/views/weather_station_receiver_info.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include -#include "../helpers/weather_station_types.h" -#include "../helpers/weather_station_event.h" -#include - -typedef struct WSReceiverInfo WSReceiverInfo; - -void ws_view_receiver_info_update(WSReceiverInfo* ws_receiver_info, FlipperFormat* fff); - -WSReceiverInfo* ws_view_receiver_info_alloc(); - -void ws_view_receiver_info_free(WSReceiverInfo* ws_receiver_info); - -View* ws_view_receiver_info_get_view(WSReceiverInfo* ws_receiver_info); diff --git a/applications/external/weather_station/weather_station_10px.png b/applications/external/weather_station/weather_station_10px.png deleted file mode 100644 index 7d5cc318c..000000000 Binary files a/applications/external/weather_station/weather_station_10px.png and /dev/null differ diff --git a/applications/external/weather_station/weather_station_app.c b/applications/external/weather_station/weather_station_app.c deleted file mode 100644 index b17f2acfc..000000000 --- a/applications/external/weather_station/weather_station_app.c +++ /dev/null @@ -1,178 +0,0 @@ -#include "weather_station_app_i.h" - -#include -#include -#include "protocols/protocol_items.h" - -static bool weather_station_app_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - WeatherStationApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool weather_station_app_back_event_callback(void* context) { - furi_assert(context); - WeatherStationApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -static void weather_station_app_tick_event_callback(void* context) { - furi_assert(context); - WeatherStationApp* app = context; - scene_manager_handle_tick_event(app->scene_manager); -} - -WeatherStationApp* weather_station_app_alloc() { - WeatherStationApp* app = malloc(sizeof(WeatherStationApp)); - - // GUI - app->gui = furi_record_open(RECORD_GUI); - - // View Dispatcher - app->view_dispatcher = view_dispatcher_alloc(); - app->scene_manager = scene_manager_alloc(&weather_station_scene_handlers, app); - view_dispatcher_enable_queue(app->view_dispatcher); - - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - view_dispatcher_set_custom_event_callback( - app->view_dispatcher, weather_station_app_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, weather_station_app_back_event_callback); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, weather_station_app_tick_event_callback, 100); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - // Open Notification record - app->notifications = furi_record_open(RECORD_NOTIFICATION); - - // Variable Item List - app->variable_item_list = variable_item_list_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - WeatherStationViewVariableItemList, - variable_item_list_get_view(app->variable_item_list)); - - // SubMenu - app->submenu = submenu_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, WeatherStationViewSubmenu, submenu_get_view(app->submenu)); - - // Widget - app->widget = widget_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, WeatherStationViewWidget, widget_get_view(app->widget)); - - // Receiver - app->ws_receiver = ws_view_receiver_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - WeatherStationViewReceiver, - ws_view_receiver_get_view(app->ws_receiver)); - - // Receiver Info - app->ws_receiver_info = ws_view_receiver_info_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - WeatherStationViewReceiverInfo, - ws_view_receiver_info_get_view(app->ws_receiver_info)); - - //init setting - app->setting = subghz_setting_alloc(); - - //ToDo FIX file name setting - subghz_setting_load(app->setting, EXT_PATH("subghz/assets/setting_user")); - - //init Worker & Protocol & History - app->lock = WSLockOff; - app->txrx = malloc(sizeof(WeatherStationTxRx)); - app->txrx->preset = malloc(sizeof(SubGhzRadioPreset)); - app->txrx->preset->name = furi_string_alloc(); - ws_preset_init(app, "AM650", subghz_setting_get_default_frequency(app->setting), NULL, 0); - - app->txrx->hopper_state = WSHopperStateOFF; - app->txrx->history = ws_history_alloc(); - app->txrx->worker = subghz_worker_alloc(); - app->txrx->environment = subghz_environment_alloc(); - subghz_environment_set_protocol_registry( - app->txrx->environment, (void*)&weather_station_protocol_registry); - app->txrx->receiver = subghz_receiver_alloc_init(app->txrx->environment); - - subghz_receiver_set_filter(app->txrx->receiver, SubGhzProtocolFlag_Decodable); - subghz_worker_set_overrun_callback( - app->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset); - subghz_worker_set_pair_callback( - app->txrx->worker, (SubGhzWorkerPairCallback)subghz_receiver_decode); - subghz_worker_set_context(app->txrx->worker, app->txrx->receiver); - - furi_hal_power_suppress_charge_enter(); - - scene_manager_next_scene(app->scene_manager, WeatherStationSceneStart); - - return app; -} - -void weather_station_app_free(WeatherStationApp* app) { - furi_assert(app); - - //CC1101 off - ws_sleep(app); - - // Submenu - view_dispatcher_remove_view(app->view_dispatcher, WeatherStationViewSubmenu); - submenu_free(app->submenu); - - // Variable Item List - view_dispatcher_remove_view(app->view_dispatcher, WeatherStationViewVariableItemList); - variable_item_list_free(app->variable_item_list); - - // Widget - view_dispatcher_remove_view(app->view_dispatcher, WeatherStationViewWidget); - widget_free(app->widget); - - // Receiver - view_dispatcher_remove_view(app->view_dispatcher, WeatherStationViewReceiver); - ws_view_receiver_free(app->ws_receiver); - - // Receiver Info - view_dispatcher_remove_view(app->view_dispatcher, WeatherStationViewReceiverInfo); - ws_view_receiver_info_free(app->ws_receiver_info); - - //setting - subghz_setting_free(app->setting); - - //Worker & Protocol & History - subghz_receiver_free(app->txrx->receiver); - subghz_environment_free(app->txrx->environment); - ws_history_free(app->txrx->history); - subghz_worker_free(app->txrx->worker); - furi_string_free(app->txrx->preset->name); - free(app->txrx->preset); - free(app->txrx); - - // View dispatcher - view_dispatcher_free(app->view_dispatcher); - scene_manager_free(app->scene_manager); - - // Notifications - furi_record_close(RECORD_NOTIFICATION); - app->notifications = NULL; - - // Close records - furi_record_close(RECORD_GUI); - - furi_hal_power_suppress_charge_exit(); - - free(app); -} - -int32_t weather_station_app(void* p) { - UNUSED(p); - WeatherStationApp* weather_station_app = weather_station_app_alloc(); - - view_dispatcher_run(weather_station_app->view_dispatcher); - - weather_station_app_free(weather_station_app); - - return 0; -} diff --git a/applications/external/weather_station/weather_station_app_i.c b/applications/external/weather_station/weather_station_app_i.c deleted file mode 100644 index 712634a2c..000000000 --- a/applications/external/weather_station/weather_station_app_i.c +++ /dev/null @@ -1,156 +0,0 @@ -#include "weather_station_app_i.h" - -#define TAG "WeatherStation" -#include - -void ws_preset_init( - void* context, - const char* preset_name, - uint32_t frequency, - uint8_t* preset_data, - size_t preset_data_size) { - furi_assert(context); - WeatherStationApp* app = context; - furi_string_set(app->txrx->preset->name, preset_name); - app->txrx->preset->frequency = frequency; - app->txrx->preset->data = preset_data; - app->txrx->preset->data_size = preset_data_size; -} - -bool ws_set_preset(WeatherStationApp* app, const char* preset) { - if(!strcmp(preset, "FuriHalSubGhzPresetOok270Async")) { - furi_string_set(app->txrx->preset->name, "AM270"); - } else if(!strcmp(preset, "FuriHalSubGhzPresetOok650Async")) { - furi_string_set(app->txrx->preset->name, "AM650"); - } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev238Async")) { - furi_string_set(app->txrx->preset->name, "FM238"); - } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev476Async")) { - furi_string_set(app->txrx->preset->name, "FM476"); - } else if(!strcmp(preset, "FuriHalSubGhzPresetCustom")) { - furi_string_set(app->txrx->preset->name, "CUSTOM"); - } else { - FURI_LOG_E(TAG, "Unknown preset"); - return false; - } - return true; -} - -void ws_get_frequency_modulation( - WeatherStationApp* app, - FuriString* frequency, - FuriString* modulation) { - furi_assert(app); - if(frequency != NULL) { - furi_string_printf( - frequency, - "%03ld.%02ld", - app->txrx->preset->frequency / 1000000 % 1000, - app->txrx->preset->frequency / 10000 % 100); - } - if(modulation != NULL) { - furi_string_printf(modulation, "%.2s", furi_string_get_cstr(app->txrx->preset->name)); - } -} - -void ws_begin(WeatherStationApp* app, uint8_t* preset_data) { - furi_assert(app); - UNUSED(preset_data); - furi_hal_subghz_reset(); - furi_hal_subghz_idle(); - furi_hal_subghz_load_custom_preset(preset_data); - furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); - app->txrx->txrx_state = WSTxRxStateIDLE; -} - -uint32_t ws_rx(WeatherStationApp* app, uint32_t frequency) { - furi_assert(app); - if(!furi_hal_subghz_is_frequency_valid(frequency)) { - furi_crash("WeatherStation: Incorrect RX frequency."); - } - furi_assert( - app->txrx->txrx_state != WSTxRxStateRx && app->txrx->txrx_state != WSTxRxStateSleep); - - furi_hal_subghz_idle(); - uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency); - furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); - furi_hal_subghz_flush_rx(); - furi_hal_subghz_rx(); - - furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, app->txrx->worker); - subghz_worker_start(app->txrx->worker); - app->txrx->txrx_state = WSTxRxStateRx; - return value; -} - -void ws_idle(WeatherStationApp* app) { - furi_assert(app); - furi_assert(app->txrx->txrx_state != WSTxRxStateSleep); - furi_hal_subghz_idle(); - app->txrx->txrx_state = WSTxRxStateIDLE; -} - -void ws_rx_end(WeatherStationApp* app) { - furi_assert(app); - furi_assert(app->txrx->txrx_state == WSTxRxStateRx); - if(subghz_worker_is_running(app->txrx->worker)) { - subghz_worker_stop(app->txrx->worker); - furi_hal_subghz_stop_async_rx(); - } - furi_hal_subghz_idle(); - app->txrx->txrx_state = WSTxRxStateIDLE; -} - -void ws_sleep(WeatherStationApp* app) { - furi_assert(app); - furi_hal_subghz_sleep(); - app->txrx->txrx_state = WSTxRxStateSleep; -} - -void ws_hopper_update(WeatherStationApp* app) { - furi_assert(app); - - switch(app->txrx->hopper_state) { - case WSHopperStateOFF: - case WSHopperStatePause: - return; - case WSHopperStateRSSITimeOut: - if(app->txrx->hopper_timeout != 0) { - app->txrx->hopper_timeout--; - return; - } - break; - default: - break; - } - float rssi = -127.0f; - if(app->txrx->hopper_state != WSHopperStateRSSITimeOut) { - // See RSSI Calculation timings in CC1101 17.3 RSSI - rssi = furi_hal_subghz_get_rssi(); - - // Stay if RSSI is high enough - if(rssi > -90.0f) { - app->txrx->hopper_timeout = 10; - app->txrx->hopper_state = WSHopperStateRSSITimeOut; - return; - } - } else { - app->txrx->hopper_state = WSHopperStateRunnig; - } - // Select next frequency - if(app->txrx->hopper_idx_frequency < - subghz_setting_get_hopper_frequency_count(app->setting) - 1) { - app->txrx->hopper_idx_frequency++; - } else { - app->txrx->hopper_idx_frequency = 0; - } - - if(app->txrx->txrx_state == WSTxRxStateRx) { - ws_rx_end(app); - }; - if(app->txrx->txrx_state == WSTxRxStateIDLE) { - subghz_receiver_reset(app->txrx->receiver); - app->txrx->preset->frequency = - subghz_setting_get_hopper_frequency(app->setting, app->txrx->hopper_idx_frequency); - ws_rx(app, app->txrx->preset->frequency); - } -} diff --git a/applications/external/weather_station/weather_station_app_i.h b/applications/external/weather_station/weather_station_app_i.h deleted file mode 100644 index 41e248112..000000000 --- a/applications/external/weather_station/weather_station_app_i.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include "helpers/weather_station_types.h" - -#include "scenes/weather_station_scene.h" -#include -#include -#include -#include -#include -#include -#include -#include "views/weather_station_receiver.h" -#include "views/weather_station_receiver_info.h" -#include "weather_station_history.h" - -#include -#include -#include -#include -#include - -typedef struct WeatherStationApp WeatherStationApp; - -struct WeatherStationTxRx { - SubGhzWorker* worker; - - SubGhzEnvironment* environment; - SubGhzReceiver* receiver; - SubGhzRadioPreset* preset; - WSHistory* history; - uint16_t idx_menu_chosen; - WSTxRxState txrx_state; - WSHopperState hopper_state; - uint8_t hopper_timeout; - uint8_t hopper_idx_frequency; - WSRxKeyState rx_key_state; -}; - -typedef struct WeatherStationTxRx WeatherStationTxRx; - -struct WeatherStationApp { - Gui* gui; - ViewDispatcher* view_dispatcher; - WeatherStationTxRx* txrx; - SceneManager* scene_manager; - NotificationApp* notifications; - VariableItemList* variable_item_list; - Submenu* submenu; - Widget* widget; - WSReceiver* ws_receiver; - WSReceiverInfo* ws_receiver_info; - WSLock lock; - SubGhzSetting* setting; -}; - -void ws_preset_init( - void* context, - const char* preset_name, - uint32_t frequency, - uint8_t* preset_data, - size_t preset_data_size); -bool ws_set_preset(WeatherStationApp* app, const char* preset); -void ws_get_frequency_modulation( - WeatherStationApp* app, - FuriString* frequency, - FuriString* modulation); -void ws_begin(WeatherStationApp* app, uint8_t* preset_data); -uint32_t ws_rx(WeatherStationApp* app, uint32_t frequency); -void ws_idle(WeatherStationApp* app); -void ws_rx_end(WeatherStationApp* app); -void ws_sleep(WeatherStationApp* app); -void ws_hopper_update(WeatherStationApp* app); diff --git a/applications/external/weather_station/weather_station_history.c b/applications/external/weather_station/weather_station_history.c deleted file mode 100644 index 9adff39c6..000000000 --- a/applications/external/weather_station/weather_station_history.c +++ /dev/null @@ -1,245 +0,0 @@ -#include "weather_station_history.h" -#include -#include -#include -#include "protocols/ws_generic.h" - -#include - -#define WS_HISTORY_MAX 50 -#define TAG "WSHistory" - -typedef struct { - FuriString* item_str; - FlipperFormat* flipper_string; - uint8_t type; - uint32_t id; - SubGhzRadioPreset* preset; -} WSHistoryItem; - -ARRAY_DEF(WSHistoryItemArray, WSHistoryItem, M_POD_OPLIST) - -#define M_OPL_WSHistoryItemArray_t() ARRAY_OPLIST(WSHistoryItemArray, M_POD_OPLIST) - -typedef struct { - WSHistoryItemArray_t data; -} WSHistoryStruct; - -struct WSHistory { - uint32_t last_update_timestamp; - uint16_t last_index_write; - uint8_t code_last_hash_data; - FuriString* tmp_string; - WSHistoryStruct* history; -}; - -WSHistory* ws_history_alloc(void) { - WSHistory* instance = malloc(sizeof(WSHistory)); - instance->tmp_string = furi_string_alloc(); - instance->history = malloc(sizeof(WSHistoryStruct)); - WSHistoryItemArray_init(instance->history->data); - return instance; -} - -void ws_history_free(WSHistory* instance) { - furi_assert(instance); - furi_string_free(instance->tmp_string); - for - M_EACH(item, instance->history->data, WSHistoryItemArray_t) { - furi_string_free(item->item_str); - furi_string_free(item->preset->name); - free(item->preset); - flipper_format_free(item->flipper_string); - item->type = 0; - } - WSHistoryItemArray_clear(instance->history->data); - free(instance->history); - free(instance); -} - -uint32_t ws_history_get_frequency(WSHistory* instance, uint16_t idx) { - furi_assert(instance); - WSHistoryItem* item = WSHistoryItemArray_get(instance->history->data, idx); - return item->preset->frequency; -} - -SubGhzRadioPreset* ws_history_get_radio_preset(WSHistory* instance, uint16_t idx) { - furi_assert(instance); - WSHistoryItem* item = WSHistoryItemArray_get(instance->history->data, idx); - return item->preset; -} - -const char* ws_history_get_preset(WSHistory* instance, uint16_t idx) { - furi_assert(instance); - WSHistoryItem* item = WSHistoryItemArray_get(instance->history->data, idx); - return furi_string_get_cstr(item->preset->name); -} - -void ws_history_reset(WSHistory* instance) { - furi_assert(instance); - furi_string_reset(instance->tmp_string); - for - M_EACH(item, instance->history->data, WSHistoryItemArray_t) { - furi_string_free(item->item_str); - furi_string_free(item->preset->name); - free(item->preset); - flipper_format_free(item->flipper_string); - item->type = 0; - } - WSHistoryItemArray_reset(instance->history->data); - instance->last_index_write = 0; - instance->code_last_hash_data = 0; -} - -uint16_t ws_history_get_item(WSHistory* instance) { - furi_assert(instance); - return instance->last_index_write; -} - -uint8_t ws_history_get_type_protocol(WSHistory* instance, uint16_t idx) { - furi_assert(instance); - WSHistoryItem* item = WSHistoryItemArray_get(instance->history->data, idx); - return item->type; -} - -const char* ws_history_get_protocol_name(WSHistory* instance, uint16_t idx) { - furi_assert(instance); - WSHistoryItem* item = WSHistoryItemArray_get(instance->history->data, idx); - flipper_format_rewind(item->flipper_string); - if(!flipper_format_read_string(item->flipper_string, "Protocol", instance->tmp_string)) { - FURI_LOG_E(TAG, "Missing Protocol"); - furi_string_reset(instance->tmp_string); - } - return furi_string_get_cstr(instance->tmp_string); -} - -FlipperFormat* ws_history_get_raw_data(WSHistory* instance, uint16_t idx) { - furi_assert(instance); - WSHistoryItem* item = WSHistoryItemArray_get(instance->history->data, idx); - if(item->flipper_string) { - return item->flipper_string; - } else { - return NULL; - } -} -bool ws_history_get_text_space_left(WSHistory* instance, FuriString* output) { - furi_assert(instance); - if(instance->last_index_write == WS_HISTORY_MAX) { - if(output != NULL) furi_string_printf(output, "Memory is FULL"); - return true; - } - if(output != NULL) - furi_string_printf(output, "%02u/%02u", instance->last_index_write, WS_HISTORY_MAX); - return false; -} - -void ws_history_get_text_item_menu(WSHistory* instance, FuriString* output, uint16_t idx) { - WSHistoryItem* item = WSHistoryItemArray_get(instance->history->data, idx); - furi_string_set(output, item->item_str); -} - -WSHistoryStateAddKey - ws_history_add_to_history(WSHistory* instance, void* context, SubGhzRadioPreset* preset) { - furi_assert(instance); - furi_assert(context); - - if(instance->last_index_write >= WS_HISTORY_MAX) return WSHistoryStateAddKeyOverflow; - - SubGhzProtocolDecoderBase* decoder_base = context; - if((instance->code_last_hash_data == - subghz_protocol_decoder_base_get_hash_data(decoder_base)) && - ((furi_get_tick() - instance->last_update_timestamp) < 500)) { - instance->last_update_timestamp = furi_get_tick(); - return WSHistoryStateAddKeyTimeOut; - } - - instance->code_last_hash_data = subghz_protocol_decoder_base_get_hash_data(decoder_base); - instance->last_update_timestamp = furi_get_tick(); - - FlipperFormat* fff = flipper_format_string_alloc(); - uint32_t id = 0; - subghz_protocol_decoder_base_serialize(decoder_base, fff, preset); - - do { - if(!flipper_format_rewind(fff)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_uint32(fff, "Id", (uint32_t*)&id, 1)) { - FURI_LOG_E(TAG, "Missing Id"); - break; - } - } while(false); - flipper_format_free(fff); - - //Update record if found - bool sensor_found = false; - for(size_t i = 0; i < WSHistoryItemArray_size(instance->history->data); i++) { - WSHistoryItem* item = WSHistoryItemArray_get(instance->history->data, i); - if(item->id == id) { - sensor_found = true; - Stream* flipper_string_stream = flipper_format_get_raw_stream(item->flipper_string); - stream_clean(flipper_string_stream); - subghz_protocol_decoder_base_serialize(decoder_base, item->flipper_string, preset); - return WSHistoryStateAddKeyUpdateData; - } - } - - // or add new record - if(!sensor_found) { //-V547 - WSHistoryItem* item = WSHistoryItemArray_push_raw(instance->history->data); - item->preset = malloc(sizeof(SubGhzRadioPreset)); - item->type = decoder_base->protocol->type; - item->preset->frequency = preset->frequency; - item->preset->name = furi_string_alloc(); - furi_string_set(item->preset->name, preset->name); - item->preset->data = preset->data; - item->preset->data_size = preset->data_size; - item->id = id; - - item->item_str = furi_string_alloc(); - item->flipper_string = flipper_format_string_alloc(); - subghz_protocol_decoder_base_serialize(decoder_base, item->flipper_string, preset); - - do { - if(!flipper_format_rewind(item->flipper_string)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_string( - item->flipper_string, "Protocol", instance->tmp_string)) { - FURI_LOG_E(TAG, "Missing Protocol"); - break; - } - - if(!flipper_format_rewind(item->flipper_string)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - uint8_t key_data[sizeof(uint64_t)] = {0}; - if(!flipper_format_read_hex(item->flipper_string, "Data", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Missing Data"); - break; - } - uint64_t data = 0; - for(uint8_t i = 0; i < sizeof(uint64_t); i++) { - data = (data << 8) | key_data[i]; - } - uint32_t temp_data = 0; - if(!flipper_format_read_uint32(item->flipper_string, "Ch", (uint32_t*)&temp_data, 1)) { - FURI_LOG_E(TAG, "Missing Channel"); - break; - } - if(temp_data != WS_NO_CHANNEL) { - furi_string_cat_printf(instance->tmp_string, " Ch:%X", (uint8_t)temp_data); - } - - furi_string_printf( - item->item_str, "%s %llX", furi_string_get_cstr(instance->tmp_string), data); - - } while(false); - instance->last_index_write++; - return WSHistoryStateAddKeyNewDada; - } - return WSHistoryStateAddKeyUnknown; -} diff --git a/applications/external/weather_station/weather_station_history.h b/applications/external/weather_station/weather_station_history.h deleted file mode 100644 index 11601fe79..000000000 --- a/applications/external/weather_station/weather_station_history.h +++ /dev/null @@ -1,112 +0,0 @@ - -#pragma once - -#include -#include -#include -#include -#include - -typedef struct WSHistory WSHistory; - -/** History state add key */ -typedef enum { - WSHistoryStateAddKeyUnknown, - WSHistoryStateAddKeyTimeOut, - WSHistoryStateAddKeyNewDada, - WSHistoryStateAddKeyUpdateData, - WSHistoryStateAddKeyOverflow, -} WSHistoryStateAddKey; - -/** Allocate WSHistory - * - * @return WSHistory* - */ -WSHistory* ws_history_alloc(void); - -/** Free WSHistory - * - * @param instance - WSHistory instance - */ -void ws_history_free(WSHistory* instance); - -/** Clear history - * - * @param instance - WSHistory instance - */ -void ws_history_reset(WSHistory* instance); - -/** Get frequency to history[idx] - * - * @param instance - WSHistory instance - * @param idx - record index - * @return frequency - frequency Hz - */ -uint32_t ws_history_get_frequency(WSHistory* instance, uint16_t idx); - -SubGhzRadioPreset* ws_history_get_radio_preset(WSHistory* instance, uint16_t idx); - -/** Get preset to history[idx] - * - * @param instance - WSHistory instance - * @param idx - record index - * @return preset - preset name - */ -const char* ws_history_get_preset(WSHistory* instance, uint16_t idx); - -/** Get history index write - * - * @param instance - WSHistory instance - * @return idx - current record index - */ -uint16_t ws_history_get_item(WSHistory* instance); - -/** Get type protocol to history[idx] - * - * @param instance - WSHistory instance - * @param idx - record index - * @return type - type protocol - */ -uint8_t ws_history_get_type_protocol(WSHistory* instance, uint16_t idx); - -/** Get name protocol to history[idx] - * - * @param instance - WSHistory instance - * @param idx - record index - * @return name - const char* name protocol - */ -const char* ws_history_get_protocol_name(WSHistory* instance, uint16_t idx); - -/** Get string item menu to history[idx] - * - * @param instance - WSHistory instance - * @param output - FuriString* output - * @param idx - record index - */ -void ws_history_get_text_item_menu(WSHistory* instance, FuriString* output, uint16_t idx); - -/** Get string the remaining number of records to history - * - * @param instance - WSHistory instance - * @param output - FuriString* output - * @return bool - is FUUL - */ -bool ws_history_get_text_space_left(WSHistory* instance, FuriString* output); - -/** Add protocol to history - * - * @param instance - WSHistory instance - * @param context - SubGhzProtocolCommon context - * @param preset - SubGhzRadioPreset preset - * @return WSHistoryStateAddKey; - */ -WSHistoryStateAddKey - ws_history_add_to_history(WSHistory* instance, void* context, SubGhzRadioPreset* preset); - -/** Get SubGhzProtocolCommonLoad to load into the protocol decoder bin data - * - * @param instance - WSHistory instance - * @param idx - record index - * @return SubGhzProtocolCommonLoad* - */ -FlipperFormat* ws_history_get_raw_data(WSHistory* instance, uint16_t idx); diff --git a/applications/main/application.fam b/applications/main/application.fam index 0a90ee224..e3ceac34d 100644 --- a/applications/main/application.fam +++ b/applications/main/application.fam @@ -11,6 +11,9 @@ App( "subghz", "bad_usb", "u2f", + "clock", + "music_player", + "snake_game", "archive", "main_apps_on_start", ], diff --git a/applications/external/clock/application.fam b/applications/main/clock/application.fam similarity index 100% rename from applications/external/clock/application.fam rename to applications/main/clock/application.fam diff --git a/applications/external/clock/clock.png b/applications/main/clock/clock.png similarity index 100% rename from applications/external/clock/clock.png rename to applications/main/clock/clock.png diff --git a/applications/external/clock/clock_app.c b/applications/main/clock/clock_app.c similarity index 100% rename from applications/external/clock/clock_app.c rename to applications/main/clock/clock_app.c diff --git a/applications/external/music_player/application.fam b/applications/main/music_player/application.fam similarity index 100% rename from applications/external/music_player/application.fam rename to applications/main/music_player/application.fam diff --git a/applications/external/music_player/icons/music_10px.png b/applications/main/music_player/icons/music_10px.png similarity index 100% rename from applications/external/music_player/icons/music_10px.png rename to applications/main/music_player/icons/music_10px.png diff --git a/applications/external/music_player/music_player.c b/applications/main/music_player/music_player.c similarity index 100% rename from applications/external/music_player/music_player.c rename to applications/main/music_player/music_player.c diff --git a/applications/external/snake_game/application.fam b/applications/main/snake_game/application.fam similarity index 100% rename from applications/external/snake_game/application.fam rename to applications/main/snake_game/application.fam diff --git a/applications/external/snake_game/snake_10px.png b/applications/main/snake_game/snake_10px.png similarity index 100% rename from applications/external/snake_game/snake_10px.png rename to applications/main/snake_game/snake_10px.png diff --git a/applications/external/snake_game/snake_game.c b/applications/main/snake_game/snake_game.c similarity index 100% rename from applications/external/snake_game/snake_game.c rename to applications/main/snake_game/snake_game.c diff --git a/documentation/Doxyfile b/documentation/Doxyfile index bb43ce8a7..f31cbb9d8 100644 --- a/documentation/Doxyfile +++ b/documentation/Doxyfile @@ -939,8 +939,7 @@ EXCLUDE = \ lib/FreeRTOS-Kernel \ lib/microtar \ lib/mbedtls \ - lib/cxxheaderparser \ - applications/external/dap_link/lib/free-dap + lib/cxxheaderparser # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded diff --git a/site_scons/commandline.scons b/site_scons/commandline.scons index 776977cda..0d3b1f92e 100644 --- a/site_scons/commandline.scons +++ b/site_scons/commandline.scons @@ -226,7 +226,6 @@ vars.AddVariables( ("applications/settings", False), ("applications/system", False), ("applications/debug", False), - ("applications/external", False), ("applications/examples", False), ("applications/drivers", False), ("applications_user", False),