From fb63e53d9ac2c1bc53223eb2d7c0f519e828e0cc Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Thu, 10 Aug 2023 00:18:40 +0300 Subject: [PATCH] [FL-3435] External apps removed (#2934) Co-authored-by: Aleksandr Kutuzov --- .github/CODEOWNERS | 3 - .github/workflows/build.yml | 2 +- .gitmodules | 3 - .pvsoptions | 2 +- applications/ReadMe.md | 14 +- applications/external/application.fam | 6 - .../avr_isp_programmer/application.fam | 17 - .../avr_isp_programmer/avr_app_icon_10x10.png | Bin 3614 -> 0 bytes .../external/avr_isp_programmer/avr_isp_app.c | 179 --- .../avr_isp_programmer/avr_isp_app_i.c | 31 - .../avr_isp_programmer/avr_isp_app_i.h | 44 - .../avr_isp_programmer/helpers/avr_isp.c | 496 ------ .../avr_isp_programmer/helpers/avr_isp.h | 70 - .../helpers/avr_isp_event.h | 23 - .../helpers/avr_isp_types.h | 32 - .../helpers/avr_isp_worker.c | 266 ---- .../helpers/avr_isp_worker.h | 49 - .../helpers/avr_isp_worker_rw.c | 1157 -------------- .../helpers/avr_isp_worker_rw.h | 99 -- .../helpers/flipper_i32hex_file.c | 321 ---- .../helpers/flipper_i32hex_file.h | 55 - .../images/avr_app_icon_10x10.png | Bin 3614 -> 0 bytes .../avr_isp_programmer/images/avr_wiring.png | Bin 4513 -> 0 bytes .../images/chif_not_found_83x37.png | Bin 3742 -> 0 bytes .../images/chip_error_70x22.png | Bin 3688 -> 0 bytes .../images/chip_long_70x22.png | Bin 3656 -> 0 bytes .../images/chip_not_found_83x37.png | Bin 3779 -> 0 bytes .../images/dolphin_nice_96x59.png | Bin 2459 -> 0 bytes .../images/isp_active_128x53.png | Bin 3961 -> 0 bytes .../images/link_waiting_77x56.png | Bin 3883 -> 0 bytes .../lib/driver/avr_isp_chip_arr.c | 386 ----- .../lib/driver/avr_isp_chip_arr.h | 33 - .../lib/driver/avr_isp_prog.c | 639 -------- .../lib/driver/avr_isp_prog.h | 16 - .../lib/driver/avr_isp_prog_cmd.h | 97 -- .../lib/driver/avr_isp_spi_sw.c | 71 - .../lib/driver/avr_isp_spi_sw.h | 24 - .../avr_isp_programmer/lib/driver/clock.png | Bin 3649 -> 0 bytes .../avr_isp_programmer/scenes/avr_isp_scene.c | 30 - .../avr_isp_programmer/scenes/avr_isp_scene.h | 29 - .../scenes/avr_isp_scene_about.c | 99 -- .../scenes/avr_isp_scene_chip_detect.c | 72 - .../scenes/avr_isp_scene_config.h | 10 - .../scenes/avr_isp_scene_input_name.c | 89 -- .../scenes/avr_isp_scene_load.c | 22 - .../scenes/avr_isp_scene_programmer.c | 28 - .../scenes/avr_isp_scene_reader.c | 64 - .../scenes/avr_isp_scene_start.c | 75 - .../scenes/avr_isp_scene_success.c | 44 - .../scenes/avr_isp_scene_wiring.c | 21 - .../scenes/avr_isp_scene_writer.c | 69 - .../views/avr_isp_view_chip_detect.c | 213 --- .../views/avr_isp_view_chip_detect.h | 32 - .../views/avr_isp_view_programmer.c | 134 -- .../views/avr_isp_view_programmer.h | 27 - .../views/avr_isp_view_reader.c | 215 --- .../views/avr_isp_view_reader.h | 35 - .../views/avr_isp_view_writer.c | 268 ---- .../views/avr_isp_view_writer.h | 37 - applications/external/dap_link/README.md | 105 -- .../external/dap_link/application.fam | 24 - applications/external/dap_link/dap_config.h | 234 --- applications/external/dap_link/dap_link.c | 527 ------- applications/external/dap_link/dap_link.h | 55 - applications/external/dap_link/dap_link.png | Bin 143 -> 0 bytes applications/external/dap_link/gui/dap_gui.c | 92 -- applications/external/dap_link/gui/dap_gui.h | 4 - .../dap_link/gui/dap_gui_custom_event.h | 7 - .../external/dap_link/gui/dap_gui_i.h | 34 - .../dap_link/gui/scenes/config/dap_scene.c | 30 - .../dap_link/gui/scenes/config/dap_scene.h | 29 - .../gui/scenes/config/dap_scene_config.h | 4 - .../dap_link/gui/scenes/dap_scene_about.c | 68 - .../dap_link/gui/scenes/dap_scene_config.c | 107 -- .../dap_link/gui/scenes/dap_scene_help.c | 102 -- .../dap_link/gui/scenes/dap_scene_main.c | 154 -- .../dap_link/gui/views/dap_main_view.c | 189 --- .../dap_link/gui/views/dap_main_view.h | 45 - .../dap_link/icons/ActiveConnection_50x64.png | Bin 3842 -> 0 bytes .../dap_link/icons/ArrowUpEmpty_12x18.png | Bin 159 -> 0 bytes .../dap_link/icons/ArrowUpFilled_12x18.png | Bin 173 -> 0 bytes applications/external/dap_link/lib/free-dap | 1 - .../external/dap_link/usb/dap_v2_usb.c | 977 ------------ .../external/dap_link/usb/dap_v2_usb.h | 53 - .../external/dap_link/usb/usb_winusb.h | 143 -- applications/external/hid_app/application.fam | 24 - .../external/hid_app/assets/Arr_dwn_7x9.png | Bin 3602 -> 0 bytes .../external/hid_app/assets/Arr_up_7x9.png | Bin 3605 -> 0 bytes .../hid_app/assets/Ble_connected_15x15.png | Bin 3634 -> 0 bytes .../hid_app/assets/Ble_disconnected_15x15.png | Bin 657 -> 0 bytes .../hid_app/assets/ButtonDown_7x4.png | Bin 102 -> 0 bytes .../external/hid_app/assets/ButtonF10_5x8.png | Bin 172 -> 0 bytes .../external/hid_app/assets/ButtonF11_5x8.png | Bin 173 -> 0 bytes .../external/hid_app/assets/ButtonF12_5x8.png | Bin 180 -> 0 bytes .../external/hid_app/assets/ButtonF1_5x8.png | Bin 177 -> 0 bytes .../external/hid_app/assets/ButtonF2_5x8.png | Bin 179 -> 0 bytes .../external/hid_app/assets/ButtonF3_5x8.png | Bin 178 -> 0 bytes .../external/hid_app/assets/ButtonF4_5x8.png | Bin 177 -> 0 bytes .../external/hid_app/assets/ButtonF5_5x8.png | Bin 178 -> 0 bytes .../external/hid_app/assets/ButtonF6_5x8.png | Bin 177 -> 0 bytes .../external/hid_app/assets/ButtonF7_5x8.png | Bin 176 -> 0 bytes .../external/hid_app/assets/ButtonF8_5x8.png | Bin 176 -> 0 bytes .../external/hid_app/assets/ButtonF9_5x8.png | Bin 179 -> 0 bytes .../hid_app/assets/ButtonLeft_4x7.png | Bin 1415 -> 0 bytes .../hid_app/assets/ButtonRight_4x7.png | Bin 1839 -> 0 bytes .../external/hid_app/assets/ButtonUp_7x4.png | Bin 102 -> 0 bytes .../external/hid_app/assets/Button_18x18.png | Bin 3609 -> 0 bytes .../external/hid_app/assets/Circles_47x47.png | Bin 3712 -> 0 bytes .../hid_app/assets/Left_mouse_icon_9x9.png | Bin 3622 -> 0 bytes .../external/hid_app/assets/Like_def_11x9.png | Bin 3616 -> 0 bytes .../hid_app/assets/Like_pressed_17x17.png | Bin 3643 -> 0 bytes .../external/hid_app/assets/Ok_btn_9x9.png | Bin 3605 -> 0 bytes .../hid_app/assets/Ok_btn_pressed_13x13.png | Bin 3625 -> 0 bytes .../hid_app/assets/Pin_arrow_down_7x9.png | Bin 3607 -> 0 bytes .../hid_app/assets/Pin_arrow_left_9x7.png | Bin 3603 -> 0 bytes .../hid_app/assets/Pin_arrow_right_9x7.png | Bin 3602 -> 0 bytes .../hid_app/assets/Pin_arrow_up_7x9.png | Bin 3603 -> 0 bytes .../hid_app/assets/Pin_back_arrow_10x8.png | Bin 3606 -> 0 bytes .../hid_app/assets/Pressed_Button_13x13.png | Bin 3606 -> 0 bytes .../hid_app/assets/Right_mouse_icon_9x9.png | Bin 3622 -> 0 bytes .../external/hid_app/assets/Space_60x18.png | Bin 2871 -> 0 bytes .../external/hid_app/assets/Space_65x18.png | Bin 3619 -> 0 bytes .../external/hid_app/assets/Voldwn_6x6.png | Bin 3593 -> 0 bytes .../external/hid_app/assets/Volup_8x6.png | Bin 3595 -> 0 bytes applications/external/hid_app/hid.c | 447 ------ applications/external/hid_app/hid.h | 67 - .../external/hid_app/hid_ble_10px.png | Bin 151 -> 0 bytes .../external/hid_app/hid_usb_10px.png | Bin 969 -> 0 bytes applications/external/hid_app/views.h | 11 - .../external/hid_app/views/hid_keyboard.c | 411 ----- .../external/hid_app/views/hid_keyboard.h | 14 - .../external/hid_app/views/hid_keynote.c | 312 ---- .../external/hid_app/views/hid_keynote.h | 16 - .../external/hid_app/views/hid_media.c | 218 --- .../external/hid_app/views/hid_media.h | 13 - .../external/hid_app/views/hid_mouse.c | 226 --- .../external/hid_app/views/hid_mouse.h | 17 - .../hid_app/views/hid_mouse_clicker.c | 214 --- .../hid_app/views/hid_mouse_clicker.h | 14 - .../hid_app/views/hid_mouse_jiggler.c | 159 -- .../hid_app/views/hid_mouse_jiggler.h | 17 - .../external/hid_app/views/hid_tiktok.c | 241 --- .../external/hid_app/views/hid_tiktok.h | 14 - applications/external/mfkey32/application.fam | 17 - .../external/mfkey32/images/mfkey.png | Bin 9060 -> 0 bytes applications/external/mfkey32/mfkey.png | Bin 9060 -> 0 bytes applications/external/mfkey32/mfkey32.c | 1349 ---------------- .../external/nfc_magic/application.fam | 21 - .../nfc_magic/assets/DolphinCommon_56x48.png | Bin 1416 -> 0 bytes .../nfc_magic/assets/DolphinNice_96x59.png | Bin 2459 -> 0 bytes .../external/nfc_magic/assets/Loading_24.png | Bin 3649 -> 0 bytes .../nfc_magic/assets/NFC_manual_60x50.png | Bin 3804 -> 0 bytes .../nfc_magic/lib/magic/classic_gen1.c | 145 -- .../nfc_magic/lib/magic/classic_gen1.h | 11 - .../external/nfc_magic/lib/magic/common.c | 33 - .../external/nfc_magic/lib/magic/common.h | 19 - .../external/nfc_magic/lib/magic/gen4.c | 199 --- .../external/nfc_magic/lib/magic/gen4.h | 48 - .../external/nfc_magic/lib/magic/types.c | 23 - .../external/nfc_magic/lib/magic/types.h | 5 - applications/external/nfc_magic/nfc_magic.c | 184 --- applications/external/nfc_magic/nfc_magic.h | 5 - applications/external/nfc_magic/nfc_magic_i.h | 94 -- .../external/nfc_magic/nfc_magic_worker.c | 480 ------ .../external/nfc_magic/nfc_magic_worker.h | 42 - .../external/nfc_magic/nfc_magic_worker_i.h | 29 - .../nfc_magic/scenes/nfc_magic_scene.c | 30 - .../nfc_magic/scenes/nfc_magic_scene.h | 29 - .../scenes/nfc_magic_scene_actions.c | 50 - .../nfc_magic/scenes/nfc_magic_scene_check.c | 89 -- .../nfc_magic/scenes/nfc_magic_scene_config.h | 18 - .../scenes/nfc_magic_scene_file_select.c | 76 - .../scenes/nfc_magic_scene_gen4_actions.c | 70 - .../scenes/nfc_magic_scene_key_input.c | 45 - .../scenes/nfc_magic_scene_magic_info.c | 59 - .../scenes/nfc_magic_scene_new_key_input.c | 45 - .../scenes/nfc_magic_scene_not_magic.c | 43 - .../nfc_magic/scenes/nfc_magic_scene_rekey.c | 95 -- .../scenes/nfc_magic_scene_rekey_fail.c | 50 - .../nfc_magic/scenes/nfc_magic_scene_start.c | 56 - .../scenes/nfc_magic_scene_success.c | 42 - .../nfc_magic/scenes/nfc_magic_scene_wipe.c | 97 -- .../scenes/nfc_magic_scene_wipe_fail.c | 41 - .../nfc_magic/scenes/nfc_magic_scene_write.c | 97 -- .../scenes/nfc_magic_scene_write_confirm.c | 64 - .../scenes/nfc_magic_scene_write_fail.c | 58 - .../scenes/nfc_magic_scene_wrong_card.c | 53 - .../nfc_rfid_detector/application.fam | 13 - .../helpers/nfc_rfid_detector_event.h | 7 - .../helpers/nfc_rfid_detector_types.h | 15 - .../images/Modern_reader_18x34.png | Bin 3670 -> 0 bytes .../images/Move_flipper_26x39.png | Bin 3698 -> 0 bytes .../images/NFC_detect_45x30.png | Bin 168 -> 0 bytes .../images/Rfid_detect_45x30.png | Bin 158 -> 0 bytes .../nfc_rfid_detector_10px.png | Bin 124 -> 0 bytes .../nfc_rfid_detector/nfc_rfid_detector_app.c | 108 -- .../nfc_rfid_detector_app_i.c | 40 - .../nfc_rfid_detector_app_i.h | 30 - .../scenes/nfc_rfid_detector_scene.c | 31 - .../scenes/nfc_rfid_detector_scene.h | 29 - .../scenes/nfc_rfid_detector_scene_about.c | 69 - .../scenes/nfc_rfid_detector_scene_config.h | 3 - .../nfc_rfid_detector_scene_field_presence.c | 60 - .../scenes/nfc_rfid_detector_scene_start.c | 58 - .../nfc_rfid_detector_view_field_presence.c | 164 -- .../nfc_rfid_detector_view_field_presence.h | 19 - applications/external/picopass/125_10px.png | Bin 308 -> 0 bytes .../external/picopass/application.fam | 22 - .../picopass/helpers/iclass_elite_dict.c | 164 -- .../picopass/helpers/iclass_elite_dict.h | 29 - .../picopass/icons/DolphinMafia_115x62.png | Bin 2504 -> 0 bytes .../picopass/icons/DolphinNice_96x59.png | Bin 2459 -> 0 bytes .../external/picopass/icons/Nfc_10px.png | Bin 304 -> 0 bytes .../icons/RFIDDolphinReceive_97x61.png | Bin 1421 -> 0 bytes .../picopass/icons/RFIDDolphinSend_97x61.png | Bin 1418 -> 0 bytes .../picopass/lib/loclass/optimized_cipher.c | 299 ---- .../picopass/lib/loclass/optimized_cipher.h | 98 -- .../lib/loclass/optimized_cipherutils.c | 136 -- .../lib/loclass/optimized_cipherutils.h | 64 - .../picopass/lib/loclass/optimized_elite.c | 232 --- .../picopass/lib/loclass/optimized_elite.h | 58 - .../picopass/lib/loclass/optimized_ikeys.c | 320 ---- .../picopass/lib/loclass/optimized_ikeys.h | 66 - applications/external/picopass/picopass.c | 212 --- applications/external/picopass/picopass.h | 3 - .../external/picopass/picopass_device.c | 380 ----- .../external/picopass/picopass_device.h | 117 -- applications/external/picopass/picopass_i.h | 99 -- .../external/picopass/picopass_keys.c | 8 - .../external/picopass/picopass_keys.h | 10 - .../external/picopass/picopass_worker.c | 752 --------- .../external/picopass/picopass_worker.h | 52 - .../external/picopass/picopass_worker_i.h | 34 - .../external/picopass/rfal_picopass.c | 214 --- .../external/picopass/rfal_picopass.h | 48 - .../external/picopass/scenes/picopass_scene.c | 30 - .../external/picopass/scenes/picopass_scene.h | 29 - .../scenes/picopass_scene_card_menu.c | 78 - .../picopass/scenes/picopass_scene_config.h | 17 - .../picopass/scenes/picopass_scene_delete.c | 58 - .../scenes/picopass_scene_delete_success.c | 40 - .../scenes/picopass_scene_device_info.c | 114 -- .../scenes/picopass_scene_elite_dict_attack.c | 172 -- .../scenes/picopass_scene_file_select.c | 25 - .../picopass/scenes/picopass_scene_key_menu.c | 100 -- .../scenes/picopass_scene_read_card.c | 61 - .../scenes/picopass_scene_read_card_success.c | 172 -- .../picopass_scene_read_factory_success.c | 80 - .../scenes/picopass_scene_save_name.c | 81 - .../scenes/picopass_scene_save_success.c | 47 - .../scenes/picopass_scene_saved_menu.c | 64 - .../picopass/scenes/picopass_scene_start.c | 64 - .../scenes/picopass_scene_write_card.c | 53 - .../picopass_scene_write_card_success.c | 70 - .../scenes/picopass_scene_write_key.c | 53 - .../external/picopass/views/dict_attack.c | 281 ---- .../external/picopass/views/dict_attack.h | 44 - .../external/signal_generator/application.fam | 12 - .../icons/SmallArrowDown_3x5.png | Bin 3592 -> 0 bytes .../icons/SmallArrowUp_3x5.png | Bin 7976 -> 0 bytes .../scenes/signal_gen_scene.c | 30 - .../scenes/signal_gen_scene.h | 29 - .../scenes/signal_gen_scene_config.h | 3 - .../scenes/signal_gen_scene_mco.c | 145 -- .../scenes/signal_gen_scene_pwm.c | 79 - .../scenes/signal_gen_scene_start.c | 55 - .../signal_generator/signal_gen_10px.png | Bin 6082 -> 0 bytes .../signal_generator/signal_gen_app.c | 93 -- .../signal_generator/signal_gen_app_i.h | 46 - .../signal_generator/views/signal_gen_pwm.c | 310 ---- .../signal_generator/views/signal_gen_pwm.h | 21 - .../external/spi_mem_manager/application.fam | 17 - .../images/ChipLooking_64x64/frame_01.png | Bin 7231 -> 0 bytes .../images/ChipLooking_64x64/frame_02.png | Bin 6909 -> 0 bytes .../images/ChipLooking_64x64/frame_03.png | Bin 7308 -> 0 bytes .../images/ChipLooking_64x64/frame_rate | 1 - .../spi_mem_manager/images/Dip8_10px.png | Bin 195 -> 0 bytes .../spi_mem_manager/images/Dip8_32x36.png | Bin 977 -> 0 bytes .../images/DolphinMafia_115x62.png | Bin 2504 -> 0 bytes .../images/DolphinNice_96x59.png | Bin 2459 -> 0 bytes .../images/SDQuestion_35x43.png | Bin 1950 -> 0 bytes .../images/Wiring_SPI_128x64.png | Bin 4446 -> 0 bytes .../spi_mem_manager/lib/spi/spi_mem_chip.c | 105 -- .../spi_mem_manager/lib/spi/spi_mem_chip.h | 34 - .../lib/spi/spi_mem_chip_arr.c | 1399 ----------------- .../spi_mem_manager/lib/spi/spi_mem_chip_i.h | 85 - .../spi_mem_manager/lib/spi/spi_mem_tools.c | 152 -- .../spi_mem_manager/lib/spi/spi_mem_tools.h | 14 - .../spi_mem_manager/lib/spi/spi_mem_worker.c | 129 -- .../spi_mem_manager/lib/spi/spi_mem_worker.h | 54 - .../lib/spi/spi_mem_worker_i.h | 24 - .../lib/spi/spi_mem_worker_modes.c | 214 --- .../spi_mem_manager/scenes/spi_mem_scene.c | 30 - .../spi_mem_manager/scenes/spi_mem_scene.h | 29 - .../scenes/spi_mem_scene_about.c | 42 - .../scenes/spi_mem_scene_chip_detect.c | 37 - .../scenes/spi_mem_scene_chip_detect_fail.c | 57 - .../scenes/spi_mem_scene_chip_detected.c | 94 -- .../scenes/spi_mem_scene_chip_error.c | 52 - .../scenes/spi_mem_scene_config.h | 21 - .../scenes/spi_mem_scene_delete_confirm.c | 62 - .../scenes/spi_mem_scene_erase.c | 65 - .../scenes/spi_mem_scene_file_info.c | 29 - .../scenes/spi_mem_scene_read.c | 57 - .../scenes/spi_mem_scene_read_filename.c | 46 - .../scenes/spi_mem_scene_saved_file_menu.c | 76 - .../scenes/spi_mem_scene_select_file.c | 22 - .../scenes/spi_mem_scene_select_model.c | 45 - .../scenes/spi_mem_scene_select_vendor.c | 70 - .../scenes/spi_mem_scene_start.c | 84 - .../scenes/spi_mem_scene_storage_error.c | 56 - .../scenes/spi_mem_scene_success.c | 40 - .../scenes/spi_mem_scene_verify.c | 59 - .../scenes/spi_mem_scene_verify_error.c | 43 - .../scenes/spi_mem_scene_wiring.c | 18 - .../scenes/spi_mem_scene_write.c | 58 - .../external/spi_mem_manager/spi_mem_app.c | 112 -- .../external/spi_mem_manager/spi_mem_app.h | 3 - .../external/spi_mem_manager/spi_mem_app_i.h | 78 - .../external/spi_mem_manager/spi_mem_files.c | 68 - .../external/spi_mem_manager/spi_mem_files.h | 13 - .../external/spi_mem_manager/tools/README.md | 7 - .../spi_mem_manager/tools/chiplist/LICENSE | 22 - .../tools/chiplist/chiplist.xml | 984 ------------ .../spi_mem_manager/tools/chiplist_convert.py | 109 -- .../views/spi_mem_view_detect.c | 64 - .../views/spi_mem_view_detect.h | 9 - .../views/spi_mem_view_progress.c | 230 --- .../views/spi_mem_view_progress.h | 26 - .../external/weather_station/application.fam | 13 - .../helpers/weather_station_event.h | 14 - .../helpers/weather_station_types.h | 49 - .../weather_station/images/Humid_10x15.png | Bin 3624 -> 0 bytes .../weather_station/images/Humid_8x13.png | Bin 3618 -> 0 bytes .../weather_station/images/Lock_7x8.png | Bin 3597 -> 0 bytes .../images/Pin_back_arrow_10x8.png | Bin 3606 -> 0 bytes .../weather_station/images/Quest_7x8.png | Bin 3675 -> 0 bytes .../images/Scanning_123x52.png | Bin 1690 -> 0 bytes .../weather_station/images/Therm_7x16.png | Bin 3611 -> 0 bytes .../weather_station/images/Timer_11x11.png | Bin 3616 -> 0 bytes .../weather_station/images/Unlock_7x8.png | Bin 3598 -> 0 bytes .../images/WarningDolphin_45x42.png | Bin 1139 -> 0 bytes .../weather_station/images/station_icon.png | Bin 3607 -> 0 bytes .../protocols/acurite_592txr.c | 298 ---- .../protocols/acurite_592txr.h | 80 - .../weather_station/protocols/acurite_606tx.c | 239 --- .../weather_station/protocols/acurite_606tx.h | 80 - .../protocols/acurite_609txc.c | 239 --- .../protocols/acurite_609txc.h | 80 - .../protocols/ambient_weather.c | 268 ---- .../protocols/ambient_weather.h | 80 - .../protocols/auriol_hg0601a.c | 248 --- .../protocols/auriol_hg0601a.h | 80 - .../weather_station/protocols/gt_wt_02.c | 255 --- .../weather_station/protocols/gt_wt_02.h | 80 - .../weather_station/protocols/gt_wt_03.c | 330 ---- .../weather_station/protocols/gt_wt_03.h | 80 - .../weather_station/protocols/infactory.c | 286 ---- .../weather_station/protocols/infactory.h | 80 - .../weather_station/protocols/lacrosse_tx.c | 319 ---- .../weather_station/protocols/lacrosse_tx.h | 80 - .../protocols/lacrosse_tx141thbv2.c | 294 ---- .../protocols/lacrosse_tx141thbv2.h | 81 - .../weather_station/protocols/nexus_th.c | 254 --- .../weather_station/protocols/nexus_th.h | 80 - .../weather_station/protocols/oregon2.c | 429 ----- .../weather_station/protocols/oregon2.h | 6 - .../weather_station/protocols/oregon3.c | 365 ----- .../weather_station/protocols/oregon3.h | 6 - .../weather_station/protocols/oregon_v1.c | 321 ---- .../weather_station/protocols/oregon_v1.h | 80 - .../protocols/protocol_items.c | 25 - .../protocols/protocol_items.h | 22 - .../weather_station/protocols/thermopro_tx4.c | 251 --- .../weather_station/protocols/thermopro_tx4.h | 80 - .../weather_station/protocols/tx_8300.c | 284 ---- .../weather_station/protocols/tx_8300.h | 80 - .../weather_station/protocols/wendox_w6726.c | 299 ---- .../weather_station/protocols/wendox_w6726.h | 80 - .../weather_station/protocols/ws_generic.c | 256 --- .../weather_station/protocols/ws_generic.h | 81 - .../scenes/weather_station_receiver.c | 211 --- .../scenes/weather_station_scene.c | 30 - .../scenes/weather_station_scene.h | 29 - .../scenes/weather_station_scene_about.c | 78 - .../scenes/weather_station_scene_config.h | 5 - .../weather_station_scene_receiver_config.c | 223 --- .../weather_station_scene_receiver_info.c | 50 - .../scenes/weather_station_scene_start.c | 58 - .../views/weather_station_receiver.c | 464 ------ .../views/weather_station_receiver.h | 38 - .../views/weather_station_receiver_info.c | 245 --- .../views/weather_station_receiver_info.h | 16 - .../weather_station/weather_station_10px.png | Bin 175 -> 0 bytes .../weather_station/weather_station_app.c | 178 --- .../weather_station/weather_station_app_i.c | 156 -- .../weather_station/weather_station_app_i.h | 73 - .../weather_station/weather_station_history.c | 245 --- .../weather_station/weather_station_history.h | 112 -- applications/main/application.fam | 3 + .../{external => main}/clock/application.fam | 0 .../{external => main}/clock/clock.png | Bin .../{external => main}/clock/clock_app.c | 0 .../music_player/application.fam | 0 .../music_player/icons/music_10px.png | Bin .../music_player/music_player.c | 0 .../snake_game/application.fam | 0 .../snake_game/snake_10px.png | Bin .../snake_game/snake_game.c | 0 documentation/Doxyfile | 3 +- site_scons/commandline.scons | 1 - 411 files changed, 7 insertions(+), 35705 deletions(-) delete mode 100644 applications/external/application.fam delete mode 100644 applications/external/avr_isp_programmer/application.fam delete mode 100644 applications/external/avr_isp_programmer/avr_app_icon_10x10.png delete mode 100644 applications/external/avr_isp_programmer/avr_isp_app.c delete mode 100644 applications/external/avr_isp_programmer/avr_isp_app_i.c delete mode 100644 applications/external/avr_isp_programmer/avr_isp_app_i.h delete mode 100644 applications/external/avr_isp_programmer/helpers/avr_isp.c delete mode 100644 applications/external/avr_isp_programmer/helpers/avr_isp.h delete mode 100644 applications/external/avr_isp_programmer/helpers/avr_isp_event.h delete mode 100644 applications/external/avr_isp_programmer/helpers/avr_isp_types.h delete mode 100644 applications/external/avr_isp_programmer/helpers/avr_isp_worker.c delete mode 100644 applications/external/avr_isp_programmer/helpers/avr_isp_worker.h delete mode 100644 applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c delete mode 100644 applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.h delete mode 100644 applications/external/avr_isp_programmer/helpers/flipper_i32hex_file.c delete mode 100644 applications/external/avr_isp_programmer/helpers/flipper_i32hex_file.h delete mode 100644 applications/external/avr_isp_programmer/images/avr_app_icon_10x10.png delete mode 100644 applications/external/avr_isp_programmer/images/avr_wiring.png delete mode 100644 applications/external/avr_isp_programmer/images/chif_not_found_83x37.png delete mode 100644 applications/external/avr_isp_programmer/images/chip_error_70x22.png delete mode 100644 applications/external/avr_isp_programmer/images/chip_long_70x22.png delete mode 100644 applications/external/avr_isp_programmer/images/chip_not_found_83x37.png delete mode 100644 applications/external/avr_isp_programmer/images/dolphin_nice_96x59.png delete mode 100644 applications/external/avr_isp_programmer/images/isp_active_128x53.png delete mode 100644 applications/external/avr_isp_programmer/images/link_waiting_77x56.png delete mode 100644 applications/external/avr_isp_programmer/lib/driver/avr_isp_chip_arr.c delete mode 100644 applications/external/avr_isp_programmer/lib/driver/avr_isp_chip_arr.h delete mode 100644 applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c delete mode 100644 applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.h delete mode 100644 applications/external/avr_isp_programmer/lib/driver/avr_isp_prog_cmd.h delete mode 100644 applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c delete mode 100644 applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.h delete mode 100644 applications/external/avr_isp_programmer/lib/driver/clock.png delete mode 100644 applications/external/avr_isp_programmer/scenes/avr_isp_scene.c delete mode 100644 applications/external/avr_isp_programmer/scenes/avr_isp_scene.h delete mode 100644 applications/external/avr_isp_programmer/scenes/avr_isp_scene_about.c delete mode 100644 applications/external/avr_isp_programmer/scenes/avr_isp_scene_chip_detect.c delete mode 100644 applications/external/avr_isp_programmer/scenes/avr_isp_scene_config.h delete mode 100644 applications/external/avr_isp_programmer/scenes/avr_isp_scene_input_name.c delete mode 100644 applications/external/avr_isp_programmer/scenes/avr_isp_scene_load.c delete mode 100644 applications/external/avr_isp_programmer/scenes/avr_isp_scene_programmer.c delete mode 100644 applications/external/avr_isp_programmer/scenes/avr_isp_scene_reader.c delete mode 100644 applications/external/avr_isp_programmer/scenes/avr_isp_scene_start.c delete mode 100644 applications/external/avr_isp_programmer/scenes/avr_isp_scene_success.c delete mode 100644 applications/external/avr_isp_programmer/scenes/avr_isp_scene_wiring.c delete mode 100644 applications/external/avr_isp_programmer/scenes/avr_isp_scene_writer.c delete mode 100644 applications/external/avr_isp_programmer/views/avr_isp_view_chip_detect.c delete mode 100644 applications/external/avr_isp_programmer/views/avr_isp_view_chip_detect.h delete mode 100644 applications/external/avr_isp_programmer/views/avr_isp_view_programmer.c delete mode 100644 applications/external/avr_isp_programmer/views/avr_isp_view_programmer.h delete mode 100644 applications/external/avr_isp_programmer/views/avr_isp_view_reader.c delete mode 100644 applications/external/avr_isp_programmer/views/avr_isp_view_reader.h delete mode 100644 applications/external/avr_isp_programmer/views/avr_isp_view_writer.c delete mode 100644 applications/external/avr_isp_programmer/views/avr_isp_view_writer.h delete mode 100644 applications/external/dap_link/README.md delete mode 100644 applications/external/dap_link/application.fam delete mode 100644 applications/external/dap_link/dap_config.h delete mode 100644 applications/external/dap_link/dap_link.c delete mode 100644 applications/external/dap_link/dap_link.h delete mode 100644 applications/external/dap_link/dap_link.png delete mode 100644 applications/external/dap_link/gui/dap_gui.c delete mode 100644 applications/external/dap_link/gui/dap_gui.h delete mode 100644 applications/external/dap_link/gui/dap_gui_custom_event.h delete mode 100644 applications/external/dap_link/gui/dap_gui_i.h delete mode 100644 applications/external/dap_link/gui/scenes/config/dap_scene.c delete mode 100644 applications/external/dap_link/gui/scenes/config/dap_scene.h delete mode 100644 applications/external/dap_link/gui/scenes/config/dap_scene_config.h delete mode 100644 applications/external/dap_link/gui/scenes/dap_scene_about.c delete mode 100644 applications/external/dap_link/gui/scenes/dap_scene_config.c delete mode 100644 applications/external/dap_link/gui/scenes/dap_scene_help.c delete mode 100644 applications/external/dap_link/gui/scenes/dap_scene_main.c delete mode 100644 applications/external/dap_link/gui/views/dap_main_view.c delete mode 100644 applications/external/dap_link/gui/views/dap_main_view.h delete mode 100644 applications/external/dap_link/icons/ActiveConnection_50x64.png delete mode 100644 applications/external/dap_link/icons/ArrowUpEmpty_12x18.png delete mode 100644 applications/external/dap_link/icons/ArrowUpFilled_12x18.png delete mode 160000 applications/external/dap_link/lib/free-dap delete mode 100644 applications/external/dap_link/usb/dap_v2_usb.c delete mode 100644 applications/external/dap_link/usb/dap_v2_usb.h delete mode 100644 applications/external/dap_link/usb/usb_winusb.h delete mode 100644 applications/external/hid_app/application.fam delete mode 100644 applications/external/hid_app/assets/Arr_dwn_7x9.png delete mode 100644 applications/external/hid_app/assets/Arr_up_7x9.png delete mode 100644 applications/external/hid_app/assets/Ble_connected_15x15.png delete mode 100644 applications/external/hid_app/assets/Ble_disconnected_15x15.png delete mode 100644 applications/external/hid_app/assets/ButtonDown_7x4.png delete mode 100644 applications/external/hid_app/assets/ButtonF10_5x8.png delete mode 100644 applications/external/hid_app/assets/ButtonF11_5x8.png delete mode 100644 applications/external/hid_app/assets/ButtonF12_5x8.png delete mode 100644 applications/external/hid_app/assets/ButtonF1_5x8.png delete mode 100644 applications/external/hid_app/assets/ButtonF2_5x8.png delete mode 100644 applications/external/hid_app/assets/ButtonF3_5x8.png delete mode 100644 applications/external/hid_app/assets/ButtonF4_5x8.png delete mode 100644 applications/external/hid_app/assets/ButtonF5_5x8.png delete mode 100644 applications/external/hid_app/assets/ButtonF6_5x8.png delete mode 100644 applications/external/hid_app/assets/ButtonF7_5x8.png delete mode 100644 applications/external/hid_app/assets/ButtonF8_5x8.png delete mode 100644 applications/external/hid_app/assets/ButtonF9_5x8.png delete mode 100644 applications/external/hid_app/assets/ButtonLeft_4x7.png delete mode 100644 applications/external/hid_app/assets/ButtonRight_4x7.png delete mode 100644 applications/external/hid_app/assets/ButtonUp_7x4.png delete mode 100644 applications/external/hid_app/assets/Button_18x18.png delete mode 100644 applications/external/hid_app/assets/Circles_47x47.png delete mode 100644 applications/external/hid_app/assets/Left_mouse_icon_9x9.png delete mode 100644 applications/external/hid_app/assets/Like_def_11x9.png delete mode 100644 applications/external/hid_app/assets/Like_pressed_17x17.png delete mode 100644 applications/external/hid_app/assets/Ok_btn_9x9.png delete mode 100644 applications/external/hid_app/assets/Ok_btn_pressed_13x13.png delete mode 100644 applications/external/hid_app/assets/Pin_arrow_down_7x9.png delete mode 100644 applications/external/hid_app/assets/Pin_arrow_left_9x7.png delete mode 100644 applications/external/hid_app/assets/Pin_arrow_right_9x7.png delete mode 100644 applications/external/hid_app/assets/Pin_arrow_up_7x9.png delete mode 100644 applications/external/hid_app/assets/Pin_back_arrow_10x8.png delete mode 100644 applications/external/hid_app/assets/Pressed_Button_13x13.png delete mode 100644 applications/external/hid_app/assets/Right_mouse_icon_9x9.png delete mode 100644 applications/external/hid_app/assets/Space_60x18.png delete mode 100644 applications/external/hid_app/assets/Space_65x18.png delete mode 100644 applications/external/hid_app/assets/Voldwn_6x6.png delete mode 100644 applications/external/hid_app/assets/Volup_8x6.png delete mode 100644 applications/external/hid_app/hid.c delete mode 100644 applications/external/hid_app/hid.h delete mode 100644 applications/external/hid_app/hid_ble_10px.png delete mode 100644 applications/external/hid_app/hid_usb_10px.png delete mode 100644 applications/external/hid_app/views.h delete mode 100644 applications/external/hid_app/views/hid_keyboard.c delete mode 100644 applications/external/hid_app/views/hid_keyboard.h delete mode 100644 applications/external/hid_app/views/hid_keynote.c delete mode 100644 applications/external/hid_app/views/hid_keynote.h delete mode 100644 applications/external/hid_app/views/hid_media.c delete mode 100644 applications/external/hid_app/views/hid_media.h delete mode 100644 applications/external/hid_app/views/hid_mouse.c delete mode 100644 applications/external/hid_app/views/hid_mouse.h delete mode 100644 applications/external/hid_app/views/hid_mouse_clicker.c delete mode 100644 applications/external/hid_app/views/hid_mouse_clicker.h delete mode 100644 applications/external/hid_app/views/hid_mouse_jiggler.c delete mode 100644 applications/external/hid_app/views/hid_mouse_jiggler.h delete mode 100644 applications/external/hid_app/views/hid_tiktok.c delete mode 100644 applications/external/hid_app/views/hid_tiktok.h delete mode 100644 applications/external/mfkey32/application.fam delete mode 100644 applications/external/mfkey32/images/mfkey.png delete mode 100644 applications/external/mfkey32/mfkey.png delete mode 100644 applications/external/mfkey32/mfkey32.c delete mode 100644 applications/external/nfc_magic/application.fam delete mode 100644 applications/external/nfc_magic/assets/DolphinCommon_56x48.png delete mode 100644 applications/external/nfc_magic/assets/DolphinNice_96x59.png delete mode 100644 applications/external/nfc_magic/assets/Loading_24.png delete mode 100644 applications/external/nfc_magic/assets/NFC_manual_60x50.png delete mode 100644 applications/external/nfc_magic/lib/magic/classic_gen1.c delete mode 100644 applications/external/nfc_magic/lib/magic/classic_gen1.h delete mode 100644 applications/external/nfc_magic/lib/magic/common.c delete mode 100644 applications/external/nfc_magic/lib/magic/common.h delete mode 100644 applications/external/nfc_magic/lib/magic/gen4.c delete mode 100644 applications/external/nfc_magic/lib/magic/gen4.h delete mode 100644 applications/external/nfc_magic/lib/magic/types.c delete mode 100644 applications/external/nfc_magic/lib/magic/types.h delete mode 100644 applications/external/nfc_magic/nfc_magic.c delete mode 100644 applications/external/nfc_magic/nfc_magic.h delete mode 100644 applications/external/nfc_magic/nfc_magic_i.h delete mode 100644 applications/external/nfc_magic/nfc_magic_worker.c delete mode 100644 applications/external/nfc_magic/nfc_magic_worker.h delete mode 100644 applications/external/nfc_magic/nfc_magic_worker_i.h delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene.h delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_actions.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_check.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_config.h delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_file_select.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_gen4_actions.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_key_input.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_magic_info.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_new_key_input.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_not_magic.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_rekey.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_rekey_fail.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_start.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_success.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_wipe.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_wipe_fail.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_write.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_write_confirm.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_write_fail.c delete mode 100644 applications/external/nfc_magic/scenes/nfc_magic_scene_wrong_card.c delete mode 100644 applications/external/nfc_rfid_detector/application.fam delete mode 100644 applications/external/nfc_rfid_detector/helpers/nfc_rfid_detector_event.h delete mode 100644 applications/external/nfc_rfid_detector/helpers/nfc_rfid_detector_types.h delete mode 100644 applications/external/nfc_rfid_detector/images/Modern_reader_18x34.png delete mode 100644 applications/external/nfc_rfid_detector/images/Move_flipper_26x39.png delete mode 100644 applications/external/nfc_rfid_detector/images/NFC_detect_45x30.png delete mode 100644 applications/external/nfc_rfid_detector/images/Rfid_detect_45x30.png delete mode 100644 applications/external/nfc_rfid_detector/nfc_rfid_detector_10px.png delete mode 100644 applications/external/nfc_rfid_detector/nfc_rfid_detector_app.c delete mode 100644 applications/external/nfc_rfid_detector/nfc_rfid_detector_app_i.c delete mode 100644 applications/external/nfc_rfid_detector/nfc_rfid_detector_app_i.h delete mode 100644 applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene.c delete mode 100644 applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene.h delete mode 100644 applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene_about.c delete mode 100644 applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene_config.h delete mode 100644 applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene_field_presence.c delete mode 100644 applications/external/nfc_rfid_detector/scenes/nfc_rfid_detector_scene_start.c delete mode 100644 applications/external/nfc_rfid_detector/views/nfc_rfid_detector_view_field_presence.c delete mode 100644 applications/external/nfc_rfid_detector/views/nfc_rfid_detector_view_field_presence.h delete mode 100644 applications/external/picopass/125_10px.png delete mode 100644 applications/external/picopass/application.fam delete mode 100644 applications/external/picopass/helpers/iclass_elite_dict.c delete mode 100644 applications/external/picopass/helpers/iclass_elite_dict.h delete mode 100644 applications/external/picopass/icons/DolphinMafia_115x62.png delete mode 100644 applications/external/picopass/icons/DolphinNice_96x59.png delete mode 100644 applications/external/picopass/icons/Nfc_10px.png delete mode 100644 applications/external/picopass/icons/RFIDDolphinReceive_97x61.png delete mode 100644 applications/external/picopass/icons/RFIDDolphinSend_97x61.png delete mode 100644 applications/external/picopass/lib/loclass/optimized_cipher.c delete mode 100644 applications/external/picopass/lib/loclass/optimized_cipher.h delete mode 100644 applications/external/picopass/lib/loclass/optimized_cipherutils.c delete mode 100644 applications/external/picopass/lib/loclass/optimized_cipherutils.h delete mode 100644 applications/external/picopass/lib/loclass/optimized_elite.c delete mode 100644 applications/external/picopass/lib/loclass/optimized_elite.h delete mode 100644 applications/external/picopass/lib/loclass/optimized_ikeys.c delete mode 100644 applications/external/picopass/lib/loclass/optimized_ikeys.h delete mode 100644 applications/external/picopass/picopass.c delete mode 100644 applications/external/picopass/picopass.h delete mode 100644 applications/external/picopass/picopass_device.c delete mode 100644 applications/external/picopass/picopass_device.h delete mode 100644 applications/external/picopass/picopass_i.h delete mode 100644 applications/external/picopass/picopass_keys.c delete mode 100644 applications/external/picopass/picopass_keys.h delete mode 100644 applications/external/picopass/picopass_worker.c delete mode 100644 applications/external/picopass/picopass_worker.h delete mode 100644 applications/external/picopass/picopass_worker_i.h delete mode 100644 applications/external/picopass/rfal_picopass.c delete mode 100644 applications/external/picopass/rfal_picopass.h delete mode 100644 applications/external/picopass/scenes/picopass_scene.c delete mode 100644 applications/external/picopass/scenes/picopass_scene.h delete mode 100644 applications/external/picopass/scenes/picopass_scene_card_menu.c delete mode 100644 applications/external/picopass/scenes/picopass_scene_config.h delete mode 100644 applications/external/picopass/scenes/picopass_scene_delete.c delete mode 100644 applications/external/picopass/scenes/picopass_scene_delete_success.c delete mode 100644 applications/external/picopass/scenes/picopass_scene_device_info.c delete mode 100644 applications/external/picopass/scenes/picopass_scene_elite_dict_attack.c delete mode 100644 applications/external/picopass/scenes/picopass_scene_file_select.c delete mode 100644 applications/external/picopass/scenes/picopass_scene_key_menu.c delete mode 100644 applications/external/picopass/scenes/picopass_scene_read_card.c delete mode 100644 applications/external/picopass/scenes/picopass_scene_read_card_success.c delete mode 100644 applications/external/picopass/scenes/picopass_scene_read_factory_success.c delete mode 100644 applications/external/picopass/scenes/picopass_scene_save_name.c delete mode 100644 applications/external/picopass/scenes/picopass_scene_save_success.c delete mode 100644 applications/external/picopass/scenes/picopass_scene_saved_menu.c delete mode 100644 applications/external/picopass/scenes/picopass_scene_start.c delete mode 100644 applications/external/picopass/scenes/picopass_scene_write_card.c delete mode 100644 applications/external/picopass/scenes/picopass_scene_write_card_success.c delete mode 100644 applications/external/picopass/scenes/picopass_scene_write_key.c delete mode 100644 applications/external/picopass/views/dict_attack.c delete mode 100644 applications/external/picopass/views/dict_attack.h delete mode 100644 applications/external/signal_generator/application.fam delete mode 100644 applications/external/signal_generator/icons/SmallArrowDown_3x5.png delete mode 100644 applications/external/signal_generator/icons/SmallArrowUp_3x5.png delete mode 100644 applications/external/signal_generator/scenes/signal_gen_scene.c delete mode 100644 applications/external/signal_generator/scenes/signal_gen_scene.h delete mode 100644 applications/external/signal_generator/scenes/signal_gen_scene_config.h delete mode 100644 applications/external/signal_generator/scenes/signal_gen_scene_mco.c delete mode 100644 applications/external/signal_generator/scenes/signal_gen_scene_pwm.c delete mode 100644 applications/external/signal_generator/scenes/signal_gen_scene_start.c delete mode 100644 applications/external/signal_generator/signal_gen_10px.png delete mode 100644 applications/external/signal_generator/signal_gen_app.c delete mode 100644 applications/external/signal_generator/signal_gen_app_i.h delete mode 100644 applications/external/signal_generator/views/signal_gen_pwm.c delete mode 100644 applications/external/signal_generator/views/signal_gen_pwm.h delete mode 100644 applications/external/spi_mem_manager/application.fam delete mode 100644 applications/external/spi_mem_manager/images/ChipLooking_64x64/frame_01.png delete mode 100644 applications/external/spi_mem_manager/images/ChipLooking_64x64/frame_02.png delete mode 100644 applications/external/spi_mem_manager/images/ChipLooking_64x64/frame_03.png delete mode 100644 applications/external/spi_mem_manager/images/ChipLooking_64x64/frame_rate delete mode 100644 applications/external/spi_mem_manager/images/Dip8_10px.png delete mode 100644 applications/external/spi_mem_manager/images/Dip8_32x36.png delete mode 100644 applications/external/spi_mem_manager/images/DolphinMafia_115x62.png delete mode 100644 applications/external/spi_mem_manager/images/DolphinNice_96x59.png delete mode 100644 applications/external/spi_mem_manager/images/SDQuestion_35x43.png delete mode 100644 applications/external/spi_mem_manager/images/Wiring_SPI_128x64.png delete mode 100644 applications/external/spi_mem_manager/lib/spi/spi_mem_chip.c delete mode 100644 applications/external/spi_mem_manager/lib/spi/spi_mem_chip.h delete mode 100644 applications/external/spi_mem_manager/lib/spi/spi_mem_chip_arr.c delete mode 100644 applications/external/spi_mem_manager/lib/spi/spi_mem_chip_i.h delete mode 100644 applications/external/spi_mem_manager/lib/spi/spi_mem_tools.c delete mode 100644 applications/external/spi_mem_manager/lib/spi/spi_mem_tools.h delete mode 100644 applications/external/spi_mem_manager/lib/spi/spi_mem_worker.c delete mode 100644 applications/external/spi_mem_manager/lib/spi/spi_mem_worker.h delete mode 100644 applications/external/spi_mem_manager/lib/spi/spi_mem_worker_i.h delete mode 100644 applications/external/spi_mem_manager/lib/spi/spi_mem_worker_modes.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene.h delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_about.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_chip_detect.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_chip_detect_fail.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_chip_detected.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_chip_error.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_config.h delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_delete_confirm.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_erase.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_file_info.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_read.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_read_filename.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_saved_file_menu.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_select_file.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_select_model.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_select_vendor.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_start.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_storage_error.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_success.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_verify.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_verify_error.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_wiring.c delete mode 100644 applications/external/spi_mem_manager/scenes/spi_mem_scene_write.c delete mode 100644 applications/external/spi_mem_manager/spi_mem_app.c delete mode 100644 applications/external/spi_mem_manager/spi_mem_app.h delete mode 100644 applications/external/spi_mem_manager/spi_mem_app_i.h delete mode 100644 applications/external/spi_mem_manager/spi_mem_files.c delete mode 100644 applications/external/spi_mem_manager/spi_mem_files.h delete mode 100644 applications/external/spi_mem_manager/tools/README.md delete mode 100644 applications/external/spi_mem_manager/tools/chiplist/LICENSE delete mode 100644 applications/external/spi_mem_manager/tools/chiplist/chiplist.xml delete mode 100755 applications/external/spi_mem_manager/tools/chiplist_convert.py delete mode 100644 applications/external/spi_mem_manager/views/spi_mem_view_detect.c delete mode 100644 applications/external/spi_mem_manager/views/spi_mem_view_detect.h delete mode 100644 applications/external/spi_mem_manager/views/spi_mem_view_progress.c delete mode 100644 applications/external/spi_mem_manager/views/spi_mem_view_progress.h delete mode 100644 applications/external/weather_station/application.fam delete mode 100644 applications/external/weather_station/helpers/weather_station_event.h delete mode 100644 applications/external/weather_station/helpers/weather_station_types.h delete mode 100644 applications/external/weather_station/images/Humid_10x15.png delete mode 100644 applications/external/weather_station/images/Humid_8x13.png delete mode 100644 applications/external/weather_station/images/Lock_7x8.png delete mode 100644 applications/external/weather_station/images/Pin_back_arrow_10x8.png delete mode 100644 applications/external/weather_station/images/Quest_7x8.png delete mode 100644 applications/external/weather_station/images/Scanning_123x52.png delete mode 100644 applications/external/weather_station/images/Therm_7x16.png delete mode 100644 applications/external/weather_station/images/Timer_11x11.png delete mode 100644 applications/external/weather_station/images/Unlock_7x8.png delete mode 100644 applications/external/weather_station/images/WarningDolphin_45x42.png delete mode 100644 applications/external/weather_station/images/station_icon.png delete mode 100644 applications/external/weather_station/protocols/acurite_592txr.c delete mode 100644 applications/external/weather_station/protocols/acurite_592txr.h delete mode 100644 applications/external/weather_station/protocols/acurite_606tx.c delete mode 100644 applications/external/weather_station/protocols/acurite_606tx.h delete mode 100644 applications/external/weather_station/protocols/acurite_609txc.c delete mode 100644 applications/external/weather_station/protocols/acurite_609txc.h delete mode 100644 applications/external/weather_station/protocols/ambient_weather.c delete mode 100644 applications/external/weather_station/protocols/ambient_weather.h delete mode 100644 applications/external/weather_station/protocols/auriol_hg0601a.c delete mode 100644 applications/external/weather_station/protocols/auriol_hg0601a.h delete mode 100644 applications/external/weather_station/protocols/gt_wt_02.c delete mode 100644 applications/external/weather_station/protocols/gt_wt_02.h delete mode 100644 applications/external/weather_station/protocols/gt_wt_03.c delete mode 100644 applications/external/weather_station/protocols/gt_wt_03.h delete mode 100644 applications/external/weather_station/protocols/infactory.c delete mode 100644 applications/external/weather_station/protocols/infactory.h delete mode 100644 applications/external/weather_station/protocols/lacrosse_tx.c delete mode 100644 applications/external/weather_station/protocols/lacrosse_tx.h delete mode 100644 applications/external/weather_station/protocols/lacrosse_tx141thbv2.c delete mode 100644 applications/external/weather_station/protocols/lacrosse_tx141thbv2.h delete mode 100644 applications/external/weather_station/protocols/nexus_th.c delete mode 100644 applications/external/weather_station/protocols/nexus_th.h delete mode 100644 applications/external/weather_station/protocols/oregon2.c delete mode 100644 applications/external/weather_station/protocols/oregon2.h delete mode 100644 applications/external/weather_station/protocols/oregon3.c delete mode 100644 applications/external/weather_station/protocols/oregon3.h delete mode 100644 applications/external/weather_station/protocols/oregon_v1.c delete mode 100644 applications/external/weather_station/protocols/oregon_v1.h delete mode 100644 applications/external/weather_station/protocols/protocol_items.c delete mode 100644 applications/external/weather_station/protocols/protocol_items.h delete mode 100644 applications/external/weather_station/protocols/thermopro_tx4.c delete mode 100644 applications/external/weather_station/protocols/thermopro_tx4.h delete mode 100644 applications/external/weather_station/protocols/tx_8300.c delete mode 100644 applications/external/weather_station/protocols/tx_8300.h delete mode 100644 applications/external/weather_station/protocols/wendox_w6726.c delete mode 100644 applications/external/weather_station/protocols/wendox_w6726.h delete mode 100644 applications/external/weather_station/protocols/ws_generic.c delete mode 100644 applications/external/weather_station/protocols/ws_generic.h delete mode 100644 applications/external/weather_station/scenes/weather_station_receiver.c delete mode 100644 applications/external/weather_station/scenes/weather_station_scene.c delete mode 100644 applications/external/weather_station/scenes/weather_station_scene.h delete mode 100644 applications/external/weather_station/scenes/weather_station_scene_about.c delete mode 100644 applications/external/weather_station/scenes/weather_station_scene_config.h delete mode 100644 applications/external/weather_station/scenes/weather_station_scene_receiver_config.c delete mode 100644 applications/external/weather_station/scenes/weather_station_scene_receiver_info.c delete mode 100644 applications/external/weather_station/scenes/weather_station_scene_start.c delete mode 100644 applications/external/weather_station/views/weather_station_receiver.c delete mode 100644 applications/external/weather_station/views/weather_station_receiver.h delete mode 100644 applications/external/weather_station/views/weather_station_receiver_info.c delete mode 100644 applications/external/weather_station/views/weather_station_receiver_info.h delete mode 100644 applications/external/weather_station/weather_station_10px.png delete mode 100644 applications/external/weather_station/weather_station_app.c delete mode 100644 applications/external/weather_station/weather_station_app_i.c delete mode 100644 applications/external/weather_station/weather_station_app_i.h delete mode 100644 applications/external/weather_station/weather_station_history.c delete mode 100644 applications/external/weather_station/weather_station_history.h rename applications/{external => main}/clock/application.fam (100%) rename applications/{external => main}/clock/clock.png (100%) rename applications/{external => main}/clock/clock_app.c (100%) rename applications/{external => main}/music_player/application.fam (100%) rename applications/{external => main}/music_player/icons/music_10px.png (100%) rename applications/{external => main}/music_player/music_player.c (100%) rename applications/{external => main}/snake_game/application.fam (100%) rename applications/{external => main}/snake_game/snake_10px.png (100%) rename applications/{external => main}/snake_game/snake_game.c (100%) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bed54dfa..6626f9ae 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 9fbcb16e..b9eb4d70 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 4fba0483..52cf4a20 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 b25d4633..2e0b2fb8 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 10e54ce2..91ef02bb 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 12dc1cc1..00000000 --- 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 19556d03..00000000 --- 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 533787fe3569f70196d3f71e8373102dfd3967a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3614 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 Vpqb^9w@m;7?5&;gRaoD1{{|C}E&c!i 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 740dc361..00000000 --- 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 7a7fa6d7..00000000 --- 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 17c69f8f..00000000 --- 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 283c17bf..00000000 --- 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 476fc3d6..00000000 --- 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 c704b5b3..00000000 --- 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 5e174ec3..00000000 --- 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 dfe1f43c..00000000 --- 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 cd9897df..00000000 --- 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 b4c12cbc..00000000 --- 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 2c52a870..00000000 --- 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 a8c20a0b..00000000 --- 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 765b94be..00000000 --- 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 533787fe3569f70196d3f71e8373102dfd3967a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3614 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 Vpqb^9w@m;7?5&;gRaoD1{{|C}E&c!i 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 957012405127ce4504ef8cd4e805b1fc31963026..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4513 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 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 b03bf3567ade9b2e4ce2d29328032ebd40c89401..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3742 zcmaJ@c{r4N`+r3CEm@K{W62gXW^B!vvCLx07Dh%=4Kv21F=I@Pr9`q-hor0#mFy}? z31!Qg5mMR9k`UfwiIbS$IPdAazdzpI=X##!`~BY6{rTLVdwH(wNjU6eBO$t16aWAT zJ6o(PZ*}86`-S;=ZxMz43jiRBqhc_J?JyV+gGu+Jo+bl8$Y8b`1@AT^k6IgDLEFbi z-ms^;$_ay9(N`j6lQnf!MWheKtL6>Jxisv;;RKZ0a^v|E6Cs7X2VJsd^_d z`fmK?j*U;@cLUzlu6^#>dh*_Ux^y|avRkNLSUlC%(8V}Xya=tb>tl3lbIYemuw|5} z1_O{5t|X}jZ>sYF>k&xg0kwLe7XV*KpO`RE@0e9@urH1)HH*$T#us^sub!2B&|WxF z7O)IUMBfK2t@$Fe(>2|ITmj%@r?1Zha9AHWsdeFV9}tHyOD43{~3Y&v9|j0#kfWk%sa|PVEtp`>lKImecjhZF8K_9PO|y&RE+yWxlgUx&ZnB7 zD?8yL6O@R}yt)j_S4%)&*Lk(SmrEKS)7#)TA2S9Xo-*ePPu4H=_T~R(uO&@j)sL?M zz)}sp;jOkXf24o(r*1ZP(PGmkcRvv6XLmga0FGld!1#_zi&kL(z~)BjKD1I=Y1pGz zFSxH^=Wv7AkCP^s&>GE+Xlb-4DRLk4q)zEYw03OQLuK8Qkhhk~M)fZKu_+8maHIP( zNfblsJ5e~NLAy3eM8K*|csEgXFrLrnGC@62SRo^3UA4hhK<0`Ds6AfRMa@3h*cR$~ z84q%|RbE0dcfjM0SwBxUYXe{xf5g_>KyO4f8N@Eg%zxs~0g5V531q6)RhU1HtKoZ6Ro%hS9D;5mOQVOD>ICYAJ>Gk2Rm~`m=eD z4-6Vdu+>w4CzG@rA{`!&X*Si6Nx;Cgs;}*^dvp)qE7NP;8|bP&qgRw=WV=^ArG1bT zP$2}rp$9t97BiVW*)(Z5sWhp&!< zVIF>$anezASzeXv1DCkM-9~3J;a$=4cJ}#YcW(CW^;hs;qdxe;dcJGqrixSA8;{=3 z8JjO@U-(zp;u5iP(XH_mZN;oTLVGBR>^%?C9qudkT~Tbs8<;}p(x)?|GU)CE-74L4 za>*T{HxJ#^ys4xM!507wsOc3;Ja%ghK+;ho&bYh~m1tjLHSQ(;dnU@bS@TiXz`3)! zHR+qmHCIr@MR{u@!m8&Q&0t%tOZY1vScI6Jea-3Hu73PcO!9Z`tY za&U1#zEWNdmi;oYU?Dx{#qr1-2YSJ1Xx;Spedi&Y_)XgPf>j%Ff?%b%hTxDmXAkm~ zaS$D;3~3$u!v*8rWQoZq-Xx}dx|CeqgS^{s{kyf)Rcgzz35^L_3$5j@rl6*(roH2= z<3gsZWA%NV`(_Si4y|3UyY6(o%P`JDLEposv!=7&XN^5Qc{JpxUR7b$GqPR9?){sN^vU5c}Hn__(xTHRnb$$hf^N}hsvvH zRp*Hm9|g+OSLIC$DRn95pP&DI6D1@OHy~M}d{j9i_%Tx!aRf1%$+@*)asJgx>I{TJ z=$7vOU^r2=yHlr`n(da=XG2k-R0l^d$6raXzt{;*GY4lWwT!gYO&(&c26=x9>s`&x zs?2JfFC2QXV6s46h#S8B+UT}Uj;CSpo2E9*N0+G{3$fcb4FbkWBb+hLQIsds>JVQ@ zvPaqbhfnj_#cRYx1@mv_%-a*@6G+oh*r?};*QWJP+n#nhH_>xW#EfAssB=l&Fm4Y} z5V@a^!k-Xj73H;KV?FGg>dQn6#1Q#g#lXDP)!b?;Ijf|LWf!L!%2fT^zFsR+U7Jql zBy*^eF^40*yn7=={7k&k6d|q^6BpwVYmvx^C+zKkrWvz)hB3io*zed>>}VDR>I{FN zf5=$Zycm26IcWOa=($A;*w6EIKOvi7ciMg*9IRVz5_tN>*pK<;xbf_9v59bnbV!>w zBQ%fGxDrz!Uj&xXL!??d#5*0l@h>ZB-9q`R`)f#t~CzTcx9NcH&uN}tLR#-gM`CK79vMJ^DKx4Lm}#*(bto&1)+;o9aE|( zvy{(%XFE&DF%?^{0~fVZ zt>3w1-XpC%qE0i+F(B%AL&wF2Cwu{OV(y|-G3V!o-_LtH6Cj>rPl(@Rvz5%{5-yj^ z4k@I`UHG6q95SU8NAGxj)wiP8Tw7?mJ!l3^w2WCojN#ku`h+P)O|JkX7>3A z@SnpchwfB`Py2GlPD#-hpG&ho_2Rf!rp;>2ILDTrv6d=^rgnQg^T>RFI6<3b%_6r_ z`kY&9Zq;O#S04+gUI?pu67IJ)qm*OH8Cj_d{X?Gnu0IEk8mU_jqp!VMTOE@hiC}7N zayn}U*jfu^wa&FCRxIbO1~4OW{T5zZ!yguhFPy4p=PvgQ+pG!3M0al`uO>-hb|z&c zb;e4>&gC35hr`D$n42>{3NYQIZp|Eptvg$td03hFTh1R9>`)7($P)9NCy}U=OpE7w?WqIZvJgUC`$G|M_Uu?M=Z(iegF%SAai# z`NyL1jf=ehN<|iqz;dJevDic=8L%SJeaIj?8j(VFB@;=ZLG5HD0Pt&5@dOsZ(E;I0 zr-6yvKHv}(0fqcjmY9LB&vF4>3h)P1Kc^EqyI5IF~f2wU5lk67e zg!c^#@P(7qEX+a35Co5aMrIK~A+*zh!H5u)+F!f~-hSH*Q3L(u!U{mC{aX~l@h}KO zXOcmtV5q*Yfq?enh%g^RKccT52xb6-LZH0cR3B=JfEgm7aM0hE8ZRJ|4z6!T3-H8RAL~rk`Q@@_Of|z8#8zz%a=~7M+Qw(@*~_Mf`iUj|2aEkBc6%Ub3|?d`nMplMCRsD-G|*pJBdEXD zV)aYDzpjS`{dS`D2EscJb2lO0{+PQx=-(}3(8oy0uhgTX+fL`k zyt(6*cX@@0I3*>}r~j|T>)y@tdH&;DIV$ov7@BF+XQ7hWqLV(GY3!CV9|KV_4;@Qw zHgg+M-MBTofZWY;GdHGi+ddaS#dNqK9JDfZcS%67m6T`CT6nRQe wIH}{3#|#He;{>wqaxL5a-a2W^9f$+?fvxTxD_~Z-3{Ny*hjYS~qfcJ^KPy3ZW&i*H 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 16f81178c0ec857591db3fe40830a5955db54e73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3688 zcmaJ@c|25m|34!8R#}pC#}E>;7|WeuEHie7Ff!6&j4>vS8DnZJktJKYB-tY^_NAgo zC|igSQrXLraPeGA+${5q``qsH`{UPhUgweFF0Af~_ zrjFdxocqWK@^atSp@&QWK-i3m#h$RjVnGZh-HUpG3;+Q`*-jL^)2s}7eQXtD6B~BR zhVCdW2y(>4he;)=s4EIdTE{Bh9h7!x+-GLSC*PhM%bSo8c3s**L-d;PM}aBDdkK;E zW3P2=eh$9x^S*BVOV`fR4~8?PE7_Gj0u6$qsg?)_oiNcN%#nScBHLP8KTko7!-bU@ zfTUohr=tJ15)ZHuYG802+#v7*;0fp#5d<1=Sq-qmF&v3GOvY)Ru&X=`tfXIU1jD2N z;soUK0q&h7k4fN!Cg84mKUN$XA;G-r0vvTpW1Rhlb4c(F=6@Z{90CR|qItK6s1MclgN&&#t z3_!|!*~Q?Gbw>fBCcR2bAKBhA9y1U3BxTwEYW)Vi%?k4xzi_YgCUAx(i9a$4cq z5}#Jy06=b%G`HH7?SO9a^6qZkgeviKnsYDtIbaWu$(`w*5{5AVd}f9A?r1*@thdf*yJ@F*8v`#H{=OU(kwhf;{9f$DoJ29OsoUI zaxJ~_othwTn0Mso9yVvmXxk$9C=ljlb<+<3&YCJi@Ew&#ZGr$`nj5bE$V7g%@t{Tn z|KY~HBaI?k?z&eo$}LS8NsO>(*kPvovC;^PT6EVV1$B4mJ7Wdy1_$rxWQI7T$@!T$ znj!I>D45fzRu?YBXVNZsfT%bW%j0p4pp+men-R64*l5YOKVBL1I#$X7Y?Gv833t4P z2RU0RETfrwkTIvtpC{?J16mPV(RCK^Tj3QB=y#$|u{DKyhpw966M5^&f@dbmCcJPl)%bLz5~vxzOf`%JY4HwjA`( zg2xanHI&}(PdosX435RN=qc}y!)mG4+}LCF_yN9ef1i1uucOkeMp2fwQ-K}zb=nzwQK>K1QvMW-?$|kSuUP}KVZ&~kk>cg+B=le!ej@YHWb?NJz zwfLI$m3NgbDi$pr*%nJtlgm0NaF8O$KKL-*HeaqkUak!f(}T~a&tyns(47hDRqB_e zlRAV`tW#7{AGv0@SD73WTTV$oTrkaBZpgwte^(7V(U=i=-W^G@je%q6ZVjsseV=7yqH{{9P&Kmw{5h5Sj?b!iNYy`Q2!@PDbz{SSZ4R_MWc{ctEsb43ZX}` z=ObdW>OkkQ7HYOrR=)*BmQv#%xe^;6XA{v0Ni&3G$+wQS*H2lq*8I+V4(eOW&Z^96 zS|}WTxTw2GU5pvI^G5s5u^d-~|J&wv>?eomUL%n^DKMY$(olP>eK_Umj1rUtO>!yw z@TfYEUA#_Qk~REh$hG)s~B7`xt?2NB5jfwQ5G@XSf=RR{`-wG#r2u=?xb$2 zc+`o|ukYUq5Wf)Pn?praqhg|5qKy(5v4lgt@H8EE?+Dg^-1NI?s_9r31#XXgsA;XE zZdeRCZ!o0yT>H6EE5yt7%>W^rV0FRfFcP9(uIqc@#rW33O3Xy|gveyDY&x|43?uMv zchhQAflLu(zXmGR*f!Sg*IWNGkyI~~xqfu{0Q+cyaA1={69o+I)$NV_h&`=-#BSMA z9T#--_oO76JdNp^tExpe>TJbqN3&2lGMSe^G%Yl$9v*o!>4qPsSP_?8MVX^~ z@w(JmN{*`7dF2~l4Ly<~@Y<*HM(JKxP2nm`{#X1dwGZk76%?|I*UPTB4rFRc&hf5= zHsFajf?jLTxwW0 zP5R15wUK~n`51b~%Z!m*Pl`%fYCL$< zvtejjm)dY`WEHmN{!4>rb>xEA-Cg=d_y_n^{CB+WV&CXf;)f02-bMM~x^LRQ4-C82 zt#2E?elhIK$1u^&?`ap-b0;OFs+r|8hxzq5wUQ z$z0Af&vMG#bn|d~ZvV!x_x;>h(3ZvUFA}%44O|1QSMaZ?L$eY6$&}@u>)9#UA)$~z zN8E?+RRzzGy2sB;(3hS|vOf2japGt6>-4)%FF#`~R}4=daCzpE`4DxEHpiMX*h%iU zZ>zmsn^|6S+NWkQsQziN*ZQn{j$ZfZYJK1zGMx7VIY{(q{Ynsh{nh%~xXfrMQ+2z$ zvv!cJx>#0cUw3ZRc)?^4I~p@!NacShr`383GO7DopI)7AT&rZ@>q6BttVn$+T zv{>|f&aZ|@b;+vC}zk|VowZ>O_dRt6fnF);t3yEnb}ZrXBM@=My~yzRM$ zdAWzftxc^*Uc3%Kz|XFp++1j6kFXV%?vG2@PhAFGQR8_3`FPFgZNX-;Tyippk2if~ zYf0x;1oyvEj%7w*InljXY$B5kn0V4X$RH~kkwSJP6Fmd{UXu*~fLD!*C$I=OTNH^- zgAjLpAOSQ67YzUgMga^W$%o7Wd5|eoUo?2B_9YlZ^+bbRbZ{^n155U%S_U!6PC<5f zQjiY`=?OM61Q`UNxCAsZiwFv!UGVis1)#xy@uIl$t{Dmj{pG^)L4*I36ajYvgrzgd zAUz0NlLUjoKzc|B*^{W{f$$=dG(cJ~EjSd;z4bKVdMGUf3XTN*eSx_FnVw!KM^p2^ z!*Mk<*qg;-prBATn+;(jAao`L3P&Q5P?#1}OG}gMq3Iv!%OVD7`uZ#VU@#^7lbBQn zi%Rze?J^QQ=oeXNFgMx%R6%3>L+k7Rcc-{Lg9Z>8P&fp(Th$Lo9PWR+(rEv9`?DO$ z|IPRRCHBV$GRROzvOoPIlf<2!m(p%11`5k06Ipa7o=(5;qmd`P=`6axH=O~}LO|dk zH5`#d_1(1``wN1@p{#uUSwvqF*~%0R=8{0DR8JHZ4%0>;b#$>XBo+=gGc|!>v@zyz zQynt|9Al1v{lJ>iNf&8kU)B$-=YO$!KgI4Y1dYLsY)WQQFOfaXnRFWHuc}ehpXZ|e zQ@+2ko^z?v~Ddd$}J5{|Q^X z8TaIHIC+D2M!C`+mZO~$2bivgS#vdRcTMmCLnHW3@dl7+1cyVd?D{H}c}t`9$XpaC z^gxtEu?7bkl3ytJxhZPZQkmCMaxE~Jj2l(+ars{7Ne!u&D$(TTYS rZ!D(kg$^oGqHiD&F%zvyD87S$apRsd$%N)XZa~1w%+9nN;~w#Ehp<_S 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 3edfff82de952d6f49a012154a23104e3fd935fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3656 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 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 a299d3630239b4486e249cc501872bed5996df3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2459 zcmbVO3s4i+8V(M(gEFORwSrA`4O0uPn|M|5y* zB*aMDxC&7(gP9JN;POOi-9khrC>Z9YJs2U!LnVcQEEC0fDtKo&ILlzb30%M}3J^;~ zv7RzcsilOs4Mq@tD*&R;!LMSk2A~{(`HK9|hQBqEX)3sQr9Je6SZU*F-^fD-p+~Hs; zHLkO%v?>ZoxEv+F#whudr%615FkA0DYR0tMEo}3OOY#xecLWe>xV?u5KtSmC^ z7)Fmj6gjfKstiEV-*Cxbbb+&rRWuI_rBJ)ybs_f1Rn&f2>q3pYwI^|J(hdn{j{0EZIm_F zpIyIWLsRUgOItR-dUbVd|6Zo=_BU_Tj4|{{jxO#=JH4o8er(5{!nZD_j4}MH&zh~9 zVLC~y(0-D6GO0ghZD8BYzP?o{>22~lT6^d@X{SwQ8vrNY-PPIMajIwC)`s14Ep72@ zeq7YOzM`?U{+W)ocXBr`eSOcpk?Rxc=ou5&)fWW|pD};-Z0mvk9}=&`Rb&y<77W~a z(>6YM;6Y5aIU~JKZ}mQZynKHiSTQ#Bczn@&jTiN^?vPJ(jhm7cXLx0oum5P$`TceG zU+wR;OO^)8CVlnM)5p$CO&e94KJt>HccCaHGusmW_b`T6m| z-R6V6Db1pErTot?^d22ojm+2>_)FbD`_+WbDGMx9f@hO27maS2`csiV(D&Fs`PS2& zvrq18du_&zXID(!KIxsU$)iuTYuZ?zmYiP&n&i@Be{IdbS-jA2c0QAlu5NXQv_0K< z3Hvs4eeu6B7yD&CNT~gIkMV&UkRU=V!iQ(+_(O&u^ah$+s{_yn(yBYeD40HeU{xGsIT6W Zfq!wOp!QjS=r55&&8K)tZJ>! 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 B&F}yK 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 d7d32aed59a19e24a7e1f2216c806872610a0af5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3883 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 - -//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 66f16a7b..00000000 --- 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 bbb6d473..00000000 --- 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 2c15ab06..00000000 --- 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 f8b07203..00000000 --- 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 c6d9d54c..00000000 --- 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 44de5ff7..00000000 --- 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 93a59fe681d26795d0db342a0c55ba42fc2c7529..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3649 zcmaJ@c{r3^8-FYniewGR7?BDy24yB=8_Oum7~4q77=ytqjlm2hDWzn~mNi>R4Q+~K zs}!Vu|T0fG&^kldAlcBl>S5JG204rZ&Cc^O@cJQ3w^Qg>RR zx8UiyV9wOk>ZjF;v5c{`7FO%duw7y*@uRsu02~{khv-s>wL#Z5REF_NqWk$lqN9zk zytcdnfEhj(GnDbrV2$Si72pME9UA+@>IQyYEXSxg0ibxGA1pSuohJ?p)N9z+O91t| zfroZaJcNKm0Ptg-H3kFsgn`K)7W!L&uEK;~X`m~2PoV%1%>$&Wn(yN^d;z#QT)?XF z*1Q6;*@j>Z{+eQ*Fz075bKbDZEkIxlE^eox8xWRitkwj8ba?^PUh!r=kR@L>w7t5& z@H8!=49x@7G$u8t9BC`)=T8#Fi5Kd3nP%I}deUiyHjr{FL+BPCr)96iQo*|Gxw zWS84sZs;1sjg1ZujCzjwaelnX-SC~Eg7p<=`!*`B^YR0t)~%fG(<39De6%{AhXK{T zg)Tt1BjDY)?5foxn0-R%eeiM=OLxt1Z&nVbUQd3H(Dv<9%I-Op(4i>(Us?my{;1GJ z?(RlU@Cl;(z*(Pd0m3+JI=uOHEzjv3{|W7ba-Z zTiteNz1m%IS&-kTUO*hLh=|>6`(r_iNryc~mwsx(;Tr=^)V_UwDya9&K?<&Y%dzv6_Jb4d+LR~!ZNE zNW`rZ7Ub+e48-nAp}2NHnsRfx6sj>_J+I?^8p(^a z6H7uQIVOcBjoq_%@OLoiVBOnpf8Sx}{Zo$T?wC0|!3-4&ew4c3Q7G^5qVRBW3pNNF zi)pnzomX{wJ$!{A{P=Q&S@vago;{)TtxU9{)LR&F7H8Z^cjTK;^Sx>1?(%qf(lT(% zs$3u>#L^Dsf6tTc8Sj}ndZw92F=CQPMg9JsJ6i2I2k`pUBXOL9O0YqO;TCg%%y?5yBfXA<7>V1+AQ++m#Iu& z@fy-$O6z;Fse9bn+FyyizIu3f609e`Hvi3V)q&Q(#uliikvlbn3+ce|Nv8cmQb;;eyXB)R9TO}{CZ#wEbvK$v2Kd~)3Pfn;!kUO3H zFmg`mJJJ#9jnD2Dr5Du(rjz?51|?z-v>#ZoqjYOdu1yL}rcG|0f-mA1l^4m2t@2HK z#N<1VGLD|5GXk0d{b&^v`2*Uo3u_Bsk2`tEdFA+L&g)3uIUd(2mJ*mEZAUJ+RzSHG z+?X^XJ6+!X^ut14`iu15qR-@yUz(6_&fQ#;wp2Uv4bv({VOcwX|1@Kj!qz3_z3mrsE|mH+lOoh{K@UTlTz z(3dpcAt>yuKu@67NYBYF6SR80)Y94{-w9+&o{(FCHmO+d?c5b}xmBP~G?aR0*>b$; znLuQ}xnE?N0!b!Sdik8hfrGGn8sBY8>=M!t2kE_V_%b2YRu6 z{IGt6$@H?YvU_D0m{)$9&ZdYl#PWw&h?FJd?jfejZWm@5x)Ocj zqgJ2i#`k5V?cq{qE8`ww${s%HDq}j&_JgZUUq~rM*+~a!Xu4v{J(#4K_H&KijgOPp zF@rd)!<-MRcP<8dvHkXK)S+-E?WDrQhDJ*9j}y-clK3PK2aZolhl}I+gVIT-*);au z;-3%A%0>sBtWS5GU0{*ByT2YQeK$3Mp2(k|u$P>x9~`UnG3t1Kc}BQMZZ>*E?lk$> zS4K{-&q7RdN%OmAJ{`QyluOeycF$bS;k?D*%=4~|j_XDDORGMsbaz&N2@07PxhOAr z^eZQEvf}9>rju`_>A3|;`*ir1SXp{-d09!qeoQ=$>xS13nwh!9Yx6YG?fovDhPT^Z^Wi45*rTV(sx>kCjTC)tK8Pk@fr;6aM$d`ql?mkGJC1x@NX7N3~WLvkK?w zoco0j5Oqp*3KcCZoH9;%UtOg_s_L5I24=o(g-}=U-eyUE?Ci!GWa-lU zY8YI37x%AHhGB|h*ik(hL3lb5F!G?f6G0YaycZEm#Cx#LG!XRwfKQcVk7MAhED;1M zSp&c6qroK8xM%>-Ghov21YaTp+3>pFg2?`3*2-4D^(!C&>a5x+Sg+X92b*_iHKa0Y^Gu0{nO1~LQi2ejR ziN+vNDWFY8ygN03fdq4t{r4%zw0~$R{(o1BTQdj~PlIS`KsQhI+tJGE|GSdO|9JZ| zu*Co5`#*{O?O8M;1WWX%2G9xI-gzo*hN2-*bRwQXrQ1`fe!mNe@uo7U{@zp?2&Sc> z1yZ%b6G)Uz%YnZjR#pfLia!HSArLK0kYFx}28rZ>(AGYzWd?^Do9aN1Xlk0GjEr@( zOwCY7bYYq>xRw_DH`ato2p|(FjNe#~|6oyn#BK_LOyfp2A<{{KL=Q7Ml??jp)Ckg_ zbAkVn?{BQfpK~$#BNoC<2C~`P|LXN`6IVc+(|^RvUHl_|B897YI#=9}_AkY9FUD4k zrM>B|@Xb4NEn;?-J6Kzo7}+zs^RX^M07#%``usTPM&dJQT7TW0pZvvcreZ!fk89eR zxb$l$y&OrR&%MN0k$&Et1-(znrXGup@9h&S%{ikQa$ LTALIbyM_M?u*zuP 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 4af125ae..00000000 --- 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 658ee743..00000000 --- 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 e5f530fe..00000000 --- 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 79c23939..00000000 --- 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 6f22511d..00000000 --- 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 3394f436..00000000 --- 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 e8890e37..00000000 --- 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 0915e1e8..00000000 --- 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 8dcb4759..00000000 --- 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 b00bfefc..00000000 --- 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 a88ed28a..00000000 --- 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 787ed567..00000000 --- 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 39c944fd..00000000 --- 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 fdcf71c3..00000000 --- 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 37f2ae23..00000000 --- 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 34e18770..00000000 --- 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 9f005b02..00000000 --- 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 92d15bd7..00000000 --- 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 44a43994..00000000 --- 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 a06b7853..00000000 --- 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 1ff72838..00000000 --- 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 aead0a60..00000000 --- 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 01714380..00000000 --- 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 88b90bd3..00000000 --- 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 eafb435e..00000000 --- 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 d51726c4..00000000 --- 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 2278ce2b61cf97e51720bafb2d07dae48d986560..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 143 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>@$__Y43U`H zI>D2R!GMF={pJ7tHnyBWw`O@WO=4vXnQOryxnPsm9sxmyCsV>A?tXRt_DY<&Wq)IO q>DB4a%~XFc{Gk)L^WR4G>Gvdb>|Y;BDpm&?%HZkh=d#Wzp$P!!VJ~6; 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 4dd98615..00000000 --- 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 3d8e6bdf..00000000 --- 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 8b127c9d..00000000 --- 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 59411e78..00000000 --- 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 37e23554..00000000 --- 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 6fb38da4..00000000 --- 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 8957aca0..00000000 --- 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 0974e60a..00000000 --- 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 48d5fedc..00000000 --- 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 d8d70e7f..00000000 --- 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 8c19bd6a..00000000 --- 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 f54c5e3d..00000000 --- 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 1fd90045..00000000 --- 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 1d7686dddf8a33b724c7528ed36435514b7518b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3842 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 G5}E*=05`}0 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 dc481517ebae2d875880d96c3a6863c9ca985690..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eO!3HGrSK5O(jKx9jP7LeL$-D$|(mh=qLo_Cy zop_M%fC7he^yB~ki^>fomK}Y&?Q6<{^IZXxHgu>k9N2PUPNa~E?*^7bKA+0AH5l)R zS}i4d#BjFRWa(K?7>YJFIonF7y_qz@_V#wWmAe;3-!N4C_Ce~$H&1(?8x60XU0}74 WwRe~lwXYaxC4;A{pUXO@geCw-ib4GV diff --git a/applications/external/dap_link/lib/free-dap b/applications/external/dap_link/lib/free-dap deleted file mode 160000 index e7752beb..00000000 --- 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 cba78664..00000000 --- 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 3f1534ff..00000000 --- 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 9c3a172d..00000000 --- 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 a9d8305d..00000000 --- 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 d4034efc432b102f6f751d001dc6891b0763c55c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3602 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 JTZ;Aw|2NmVF(Lo} 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 28b4236a292708b412629ffafe30f6d011491505..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3605 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 AV*mgE 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 d1a7a04f06dcc4b5446aad5a40a9863038bf56b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c!2~4tO5(ej@)Wnk16ovB4k_-iRPv3y>Mm}+% zA~jDJ#}JO|$tewu|Ns9tHZU+a6e)0^L#NYq9;5F(PTxtKzKT}z3_A)0e;QviHwNlp N@O1TaS?83{1OPU#E%g8Z 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 7e177358e81695342f2a283a220c7cacc7bda939..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c!2~4tOpBPSmNg(OQ{BTAg}b8}PkN*J7rQWHy3QxwWGOEMJPJ$(bh8~Mb6 ziqt(_978y+C#N(t{{R2q*ucQxP^7?t4xLU{IYmyznHN-MN(3-k$uq=X7x{LAUCkJ% Og~8L+&t;ucLK6T7Y%hHP 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 50d2a7dc63b9d366ccfbacbc05e6bb0d9e335b5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c!2~4tO zk)EfEV+hCf+#W|R1_Pc$J^%l2ww|&zRcE|OcGEe{j 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 7394d27105fd0a27067803bfd633a26bedd0f1d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c!2~4tO5(ej@)Wnk16ovB4k_-iRPv3y>Mm}+% zB5h9>#}JO|$tewu|Ns9tHZU+a6e)0^L+9jy0|#0HPM+X+s?4mGa`wiPi$55Iw(~PB TTpxE5sExtX)z4*}Q$iB}`k6I% 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 9d922a3858147116d65b6f03e2b36ea846b2f60c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c!2~4tO zk*=qUV+hCf)NV&U1_ho&w~qX;m*hWYIaS!#v1}4USoB8kx*gxNJa@^Tf4zarr_o#d UH)s04hd_-Cp00i_>zopr0BX-NbN~PV 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 95c2dd4f4198e182a1a62927c4d3627400a7b883..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c!2~4tO zk&dT}V+hCf)GkXd1_g%0LLdIeuWPOlF*aSY$&;z#+9C5#-hV?Uh3H=_oX_AhhhO~n UO!>#_f%+IcUHx3vIVCg!073*Z7ytkO 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 602466f4b667b6df4d5335517bd9d43e5f0b6e69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c!2~4tO5(ej@)Wnk16ovB4k_-iRPv3y>Mm}+% zB5h9>#}JO|vE3Va85}s64*o6Qr{DAJBNr3n8pa7vN_+nsOQj%x4ZT`lf}PS TtvtgA)W+cH>gTe~DWM4fb!sy& 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 d73b5405275f6c53f7a2f157df063db1ca351caa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c!2~4tOFVdQ&MBb@0Fom!%>V!Z 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 c50748257ab8e06f90007e93b913d5be4999d096..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c!2~4tOA;}Wgh!W@g+}zZ>5(ej@)Wnk16ovB4k_-iRPv3y>Mm}+% zB5h9>#}JO|shy5|3<^BWD?a{@Kh_*L{p89i1p$qBwtDvdG5Wpwnq5@=JeG)jb@A^; T#rkJ}+88`t{an^LB{Ts5$FwwN 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 396c98f5104f94b6310593ce6c7e6ce3d2369ef3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c!2~4tO+nf~Hxmr&P}udD~(3jVRo RuLQY`!PC{xWt~$(69B*FH3|R# 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 6304d7fb888b2cf38c54e7124aaa604d1610629c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c!2~4tO5(ej@)Wnk16ovB4k_-iRPv3y>Mm}+% zA}voB#}JO|wVjT93<^BWEB^mCmh0Jd#>H=GOE1@xHLh7tre2KydVRe*qgvi_@vq`% Sf29C*F?hQAxvXEZzkxv|` zNY~TFF@)oKa!Nzv|NsAu4GatpMG73~&^g&~GSNx=@BjbyU3DUS%F5hxSQ8l-I!}xL U>{@7g2&j?4)78&qol`;+0Ic0IyZ`_I 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 0b4655d43247083aa705620e9836ac415b42ca46..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1415 zcmbVM+iKK67*5rq)>aU2M7$VM1Vxif;vTv~W2u`S7ED{V3s&&L*<`XiG|9wd+THd> z5CnY!sdyuJtrvQyAo>KpiLcV|{Tkc)riAbluXfwSZCApL`ztB&p zx6LGKvks4K_4~)qD&oGa-YdJlW)hAKMNJd7<=t?6c^RI1>c$ifyjaM>^|&8!ey zB4!nh9u>5uen6Ve@<H5rru6h<2Ef#GQdQ*CmZOlQi~N!?9H`Rp;C% zU}CB21#?;r`&0|6C0}b-=jODa5|nEJ#ntxQ&{~jpgtwDta4hftr~G=#p@V36e4Zjh zq%J~{y26Jjn=1Nw-l*3%QW5YFE*v4z3gt0$&(*xf2en34c?JpH8+FYldo+Alvg8af-pG4(=!fyUi-Wsg z`g#n9VUcf(DFr{poMSNzw-lz>w+HV+n1ELr&SLA#LHUb0p(xWQ(1*vJ-i+1!`swxZ Z!O7;c$;lT_->m1Ovaz)0yuI`A$q$F8u*d)a 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 8e1c74c1c0038ea55172f19ac875003fc80c2d06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1839 zcmcIlO>f*p7#Yw)M6zw!O+@VZ{?d|D~WYi~8rHRY?X-&T}Yen`g$^+EJ;z+|RV zE@PoDvZ9%#+_}3bC_5Cj8jDGq541mi{7F+&KF}W65sr$Xn5H|YrMQ2(J7%Yc%;(zO z57ax000=TsQ+1Ke@+w#iw3au3cGGQWY740k2ijH>P(6tD)S)be>gX6Tj7`<`b>di- zgWp$8Y+?i31~CzF0&E4uRlA=C(Mp~K`{74jEchB|)4DDK!ZVhSwdFyw0YIZ1cDh0S{OvfO-U_~ zvmRF*m9sWDXNH)GOyqS1Skhxbr6}s*7t&@~kFM(NW5}qh?Lu@lJ}HE;FDiLdGO>LO z5pS*%E2grR)l^;|?O5b_?u0me&c1U}%jrk8*%=Wk%i)8yp2P|kuxmKg<=(u_`oQRI_0 zS`-DNysBx=#3&qSkgA@hJP>~D+ZM(s5jI6Owp`?yE=3e`YGUqkVOp#Cp=3wR3O4hX zX6BLsN3UBzV(vI5;|SZHgOb=HD0VFjpTyfFW}GnQuh>2*Q`k>*cAmA#iUT7EXSpo# zkPm5~#I-o^cpgfe#P$=4-Pi*SpT!-@nJgp8L347xe>5EKl`=_ZFc8XGy+_j=_R_7! z@vZZMowS1GJ?Zw)eetks%~G{BTR>T}9|jt0j3Btyb*C3-`C?fwY3EY`q*oYZ39DpM z&uJ;PCZPLs4QO1Jd_|A1PF)azZJ)RZ`^-VMWr6e#XUOA%3eLG_Ch@BDOHzMk*MF0G zCo7xMd?Mg*HMIXw%nNz?%60fZiZPlqb?GqUpXO`F&Yi!okZl(n>P@r1P2i)yk3DgRwbHeNn6e|;J^SK4TM LH~i+q&mR8;k>NTA 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 1be79328b40a93297a5609756328406565c437c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)I!3HFqj;YoHDIHH2#}J8d-yTOk1_O>mFaFD) zeWb+ZHz{mGZZ1QpXe09^4tcYT#4oe=UbmGC^A-KE*|F&zP#=S*tDnm{r-UX30HgpM AM*si- 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 30a5b4fab236d8b57242559ef94fb1c5dbb5d10a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3609 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 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 6a16ebf7bbe999fa143c683bef713a6e2f466cbb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3712 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 biU<_Yn+9Io=xs3K`2!qm58ISjpSt)z2v?8| 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 c533d85729f9b778cba33227141c90dea298f5e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3622 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 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 555bea3d4b0239ae1be630d0306316d3e9494c4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3616 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 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 9687397afa81c92fb727bd40542830392fabdccb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3607 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 QX&eA7&1_6djNPvM5BL~PlmGw# 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 fb4ded78fde8d1bf4f053ba0b353e7acf14f031a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3603 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 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 a91a6fd5e99a72112e28865cd8a004c7d1933fff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3603 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 TFC+3}9cE|kU{!4CefEC<&8td2 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 823926b842b8f9868fd70d6f1434dff071c04d5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3606 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 VN_%sSbR7Ty002ovPDHLkV1hy!X)pi) 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 b60ae50970b8be827ae32ddbd9e1b0d28c8b3a9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3619 zcmaJ@c{r5q+kR|?vSeS9G2*Q(Gqz$f_GOf18r!JE7=ytq%?xHFO-U))vSm#u)X=6# zwu*&|8!^APw~9?k(a6Vz_{`1J?VwO%hlm80mweJ_2Ll%+w5Jal|B#ZToHj zkX!A1wWV(yKRGcrJmE7L$o^5EyA?1;0vjpK4{lZ7;N}HH?K{|g9^>OZJmdzhM?p0K zMW=v17r<|D)m^7wAm^muyU^8WhW>`hzU({5Mni?Yg1dIjs(9V0f{sQT{n8mG4Mm49 zbG~l%ht2_K(@oNfYx5#D&tizdC8*fR7G5(g;>x7*Rzu{4&DevTBf5`It4m&=M_(&P zg6$d@FHi{BFL>ue9`qCWpjMUz{dO z@9>n#el1gZMS$0|kzX961dH0^726AL=a){4^e8+sFE>V1@t?G01xkRvR~uHtV6d@Jy=*+_LjJ^<;I%HkfZ+ zJ{WS&*3q1L--qRs;FC3Rwv9{p?cw*6_FMFK^@Q9yZ8!?f0Ei>znMIVlCNa;%nYvD_=OIcyvaxrpYxGcGRWZCqbo>reG^tc8h zWbb>x%$fc-l1kK>Pg=_9^WFC8k{QaNGP~oK)fB= zk~}W=y`t;c`=z{$ml*@ap9mj5x5DesKUlZZ%#d$#e*hBLJ2$e|kFK?B#{H}rW-Lg}+w*yHz2X|@s=6q5@hMLLk0Ngx@77A0z{8^GG<=3FCsOHJ6w{_pD*!j4k8!wLb`#+}y`?CB4 zQGwW*jB;lA{ql?St3NI0Q^jcF`vqpNjn(zm!LN-{xhDhDbu!1&ol`GQ%#aWnhw%cUor3tn<%~!N%j(>i+!K$>%8wb|oXB!X zUe^D7^t}0+-xUX|ptm{#4k$H7g6z!~%8Pa`7Cm2B9iPsA(lAKMOv=nd3E@*p)jmSY z4wO0gsHr6ijWH$&&GLy?n^(q^SE-Brl7W%7oq46G5~Q${Eu>J5eoE#Py&O@6IQcl%pM`Lo~JAQ5D{F{9M=h7QdD!DVxX< zG|G9wpE0lyi;C#Fd)Hj;lB;fVQBqS2vE;|e7g$M5vbQtaKehXm%Y{SI$sQ~+tFYwf zBdhX>5m$SU?yw~Wp|9`Dv9jjbX~cB?G?BI9R`c*!mA`5CyDM`-#q#qpezqJMP@wb32zU+0*_sQsBVDnwlp9 z1k~Y}eFzwNJcCK<%a~0Mc}6~YNcgqs_^ZDL?}eQkMSi{0{$}7!+hE#-vL*g$1VgP0 zRujb1$Rp&y?^LnB-pI>RIHO=)UG^)Stu=}bYS4>w&Cba>0H0qSyOcOu;9ZcNWp51s zkT$?rvE4`ua6jQ*ND(zN(xGR}RjlKca_;?=KGcDxu~0=Et)Zw@0K zo+3@-R$69V4NGW0?52-)vfp1=^RMlue*F1S)BQH1iv4y*zKp2)d2hK&#nR8<o8NY>iF~_Iy7d@WOBnj;S?k&H#!ZAREO0e@E9uw!tHWK^t=8Sj zR?0DPS&EACLUL6L-tCFQ1y2gZJDS5?ele!04<-jUN7j#bpf`HwcCAKt)RZua7Afop zMGs*O$_4u!*bGtM^Q3;}>g74L+mq3vv8SQ0@K zvyIWD6UZDk02mt6$rx+^jt26=`QnLiF#BZ<7=-tRgI)FPpmt<)oF5($O2IjX+B;!G z1F#0(U}GbYAsxmMAmC^i5S7-)K9yf9cVFLjVMR9g!I)rDy3YCxed9RrxIF6f^D=D4GH`@m2ZR{uET z?BHNO8jTEtKte)7G(&VWNfcj*mVto*1gZ_u*4E%4G^h+B4MW!;Qk8!zSm3Bw3Z6{E zlZc>gMT{3Ihz199LjBJf2;_fdiPV4c#K{#)rmpIK~Oj6!<%hNIw#dMD-()LE1W+P|yK8 z3>Ht^wjBJMVrK`lAyR1=A{J+30S9wLH1T+En5mAg1yo=Eh@P&MzLu7yxtX4op5xA}2IPRCO?t!+X9zvoGZ%D;b1(Y*s+gO-7(fhnSIU^r{GM99afXqQXz`L$cAW!v1IOaB9=s#hui 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 d7a82a2df8262667a9a03419f437ff9b350e645f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3593 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 - -#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 49d8b4e0..00000000 --- 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 d4d30afe0465e3bd0d87355a09bbdfc6c44aa5d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2VGmzZ%#=aj&u?6^qxc>kDAIJlDSNs& zhE&W+PH5C8xG 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 415de7d2304fe982c025b2b9a942abbf0a2b6dd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 969 zcmaJ=J#W)M7(OY0prTdS3e(9IQYsOjefe;0)l|h!Xha;MG(g5)>`P;{_8I$1oJb(V z#>Co{9{@i91|(QuX5%*?v9pwOnxqT_55D(az0dQ0J@>lZy1%+|YXtzX+Ss!@;>_%o zt2y!i@N?&lIBxPQduOaNrjU+e?;YX%)UR2L%LyN@}>atRF6-9xXE~}dAVr@YBcOX_U zM#>gat3`~BQpG5%aP~Eh*gj89{x|#<%&i_M$ zU=f}04!x-NpTtRb98uJv2|I~hvAe-WmMSu=m=ez7E@Q{@LAHmCvt-C3h|9793l4Gp zF!O9qA&z4-!i1C1r48GZ1c~hXo`JDuS-aJ0wOrd$)taqWN;ON>tZH4WV;fs@tj*k$ zfQEdI^)9g5QfwxOAQG8v8vD3;Z_1q-{ zl$i_hipxU&G!&YTg}8q|eDGX6j4SPCw{~`RCd@~lzrPU2?S{SEO@H(cJnv<$o(G-l ph0_~rZ>7^_`EovpzT_W+OY7j;8rXcd{ -#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 71277136..00000000 --- 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 543363bf..00000000 --- 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 84bfed4c..00000000 --- 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 468529d5..00000000 --- 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 4aa51dc1..00000000 --- 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 30a9d9d0..00000000 --- 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 d9fb2fd8..00000000 --- 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 d85affc4..00000000 --- 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 d72847ba..00000000 --- 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 15547eb2..00000000 --- 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 0813b435..00000000 --- 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 e1f9f4be..00000000 --- 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 b2efc369..00000000 --- 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 9a9cbf58..00000000 --- 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 52ab29efb92bf5aa7c790b8043d2d07a7e74704d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9060 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 T2_+RDfDS|^SsNGcaF6&O#taN} diff --git a/applications/external/mfkey32/mfkey.png b/applications/external/mfkey32/mfkey.png deleted file mode 100644 index 52ab29efb92bf5aa7c790b8043d2d07a7e74704d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9060 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 T2_+RDfDS|^SsNGcaF6&O#taN} diff --git a/applications/external/mfkey32/mfkey32.c b/applications/external/mfkey32/mfkey32.c deleted file mode 100644 index 5e790b01..00000000 --- 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 a89b45d0..00000000 --- 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 089aaed83507431993a76ca25d32fdd9664c1c84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1416 zcmaJ>eNYr-7(dh;KXS5&nWVIBjS_NizYg|x=Pr^vz*7zxJO|P-dw2IeZq?gec9-rD zoPZchQ_6}yP{Slc4I!!28K==nodOJ_nsCY-(wOq2uZbLx!rlYU{KIi)_Wj!D_j`WN z^FGgREXdEDF)ewT&1Re7Tj(uBvlG44lnH3;I%IzsO|z`*Vr!`uv?9QOwgs{#Ld+Ki zC9n_zxxBOkx@@+IwMwAaD)#3Ik`}gun2kLe))Crfb7e+#AgzHGCc+X$b>qJuIf`S7 z?8b}I{ghw#z>uiaLknQh@LJUrqHcVYS3v97F^OZN zCe|7^J|?QzUx0Zu17e(=CM1fYFpjtLk|a4~$g}e?hGH0!VoBOT&<=s(1ct%J9~?O} z$)jW_dkX9yTX~%W*i_IM%0{ z7EmP^_pKn`<5>E(SixgJU};7`)7Hidp&+DLnizsebUk}_-GfgbN^il9b`v)f+ z{o5Zry)d<7`fHQ^uw_;+x>mcPw0&8iW69x{k92O{Q}`yFdH=5d$pbf49w1&NS)G+vhr6y}5TMsofQirRDUmKilk5=(KGouJ{H9hW=$X zgi;)vI!jl!_4H3jD(?Jz=8By|i47I&tKA1y9{nfp;_|FxKBDNWp{hN9hJ1nU?z%J6 z?>UxyzWvO}Pgc~rCZ#5%Eq+_hNS~bBdiGlT&f%%e`hHjSySR2=JuK2^+%;$R3#Wz~ z=e_mfqW23bPa0fhe)HdE5+GelU&!jS3ckUZOQ)CC5?mo zo=tzG_4|RuvPUO|mhCwA>y)1c%SWC%a4?a-x|J*?ch~+n=R7o@>p6J2dE=$stKZmK z-xoTRwET2^Wu)&1U7!Ebw!!D?x`xwQX3pMnrRwCT?`4GHt4&?|cIiI{_^XYp-np>6 xE^lPSXzOYCC4X`6tl@OB1M5_S7jml-Y~(TPp{aTIejNKZ`m*!Atyxdk{0EAy49frj 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 a299d3630239b4486e249cc501872bed5996df3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2459 zcmbVO3s4i+8V(M(gEFORwSrA`4O0uPn|M|5y* zB*aMDxC&7(gP9JN;POOi-9khrC>Z9YJs2U!LnVcQEEC0fDtKo&ILlzb30%M}3J^;~ zv7RzcsilOs4Mq@tD*&R;!LMSk2A~{(`HK9|hQBqEX)3sQr9Je6SZU*F-^fD-p+~Hs; zHLkO%v?>ZoxEv+F#whudr%615FkA0DYR0tMEo}3OOY#xecLWe>xV?u5KtSmC^ z7)Fmj6gjfKstiEV-*Cxbbb+&rRWuI_rBJ)ybs_f1Rn&f2>q3pYwI^|J(hdn{j{0EZIm_F zpIyIWLsRUgOItR-dUbVd|6Zo=_BU_Tj4|{{jxO#=JH4o8er(5{!nZD_j4}MH&zh~9 zVLC~y(0-D6GO0ghZD8BYzP?o{>22~lT6^d@X{SwQ8vrNY-PPIMajIwC)`s14Ep72@ zeq7YOzM`?U{+W)ocXBr`eSOcpk?Rxc=ou5&)fWW|pD};-Z0mvk9}=&`Rb&y<77W~a z(>6YM;6Y5aIU~JKZ}mQZynKHiSTQ#Bczn@&jTiN^?vPJ(jhm7cXLx0oum5P$`TceG zU+wR;OO^)8CVlnM)5p$CO&e94KJt>HccCaHGusmW_b`T6m| z-R6V6Db1pErTot?^d22ojm+2>_)FbD`_+WbDGMx9f@hO27maS2`csiV(D&Fs`PS2& zvrq18du_&zXID(!KIxsU$)iuTYuZ?zmYiP&n&i@Be{IdbS-jA2c0QAlu5NXQv_0K< z3Hvs4eeu6B7yD&CNT~gIkMV&UkRU=V!iQ(+_(O&u^ah$+s{_yn(yBYeD40HeU{xGsIT6W Zfq!wOp!QR4Q+~K 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 LTALIbyM_M?u*zuP 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 787c0bcfe01755f4dcadcdce004a1a0fcfb06f41..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3804 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 IrsqTc1+$%)k^lez 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 8d87d631..00000000 --- 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 98de1230..00000000 --- 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 0ea3cb21..00000000 --- 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 bef166c8..00000000 --- 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 31be649a..00000000 --- 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 c515af82..00000000 --- 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 77c6c0a4..00000000 --- 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 dbf55406..00000000 --- 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 68c9a65b..00000000 --- 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 f9cf395d..00000000 --- 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 88bc5706..00000000 --- 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 eb715fe0..00000000 --- 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 51ff4ee4..00000000 --- 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 a354f804..00000000 --- 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 520ef2a9..00000000 --- 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 f1e9f715..00000000 --- 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 675262a9..00000000 --- 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 90b43d7d..00000000 --- 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 2f9860d9..00000000 --- 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 04b7024f..00000000 --- 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 ceaa33e2..00000000 --- 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 58b487a0..00000000 --- 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 c147ac43..00000000 --- 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 b5247f6c..00000000 --- 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 b4f579f4..00000000 --- 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 259dc78e..00000000 --- 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 d30ee57b..00000000 --- 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 b5861629..00000000 --- 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 37441e80..00000000 --- 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 29640f89..00000000 --- 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 828b65e6..00000000 --- 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 45c54557..00000000 --- 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 d31c1c19..00000000 --- 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 8a465bf6..00000000 --- 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 857d50c1..00000000 --- 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 70c91bc8..00000000 --- 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 bbffe293..00000000 --- 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 5d44b09b..00000000 --- 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 b19c0f30c9f3928d3129acc9da92d5a9e962d084..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3670 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 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 ff4af9ff05989e5ff04d3888971b7f7801c59ed4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3698 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 QfL1Vgy85}Sb4q9e0PSTwjsO4v 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 35c205049bc5a6c7f0bb13a0cb3057963a023c6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^xG+l41V{G`^6RB9^&ce?Q{EhH1o(i zcG0sF=jLrIU`gfJ9e<(w?c#$+`{GybuV0XK^{NaL55t;h1_!r?84rQRGkCiCxvXf4IeWS|hDc0ZJK-P~g93;1_80%_ zf0mxq_>?eVL9oQDG>54hmUMGg2<9ZE<@p-^(r|y*a$w%vQ*}A2s_`AWqh21A3+I&= XdhU3CV!O&Kpm7YIu6{1-oD!M<1Jf%z 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 cba8b608..00000000 --- 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 c59d40d5..00000000 --- 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 72cb126d..00000000 --- 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 d75eb288..00000000 --- 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 74d324b4..00000000 --- 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 ddcb8aac..00000000 --- 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 ab49ad5c..00000000 --- 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 ec53b5a0..00000000 --- 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 7b71bd97..00000000 --- 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 e65eb836..00000000 --- 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 0ddb4e2c..00000000 --- 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 ce01284a2c1f3eb413f581b84f1fb3f3a2a7223b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 308 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xkYHHq`AGmsv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpafHrx4R1i<>&pI=m5)bWZjP>yH&963)5S4_<9hOs!iI -#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 150cd1b7..00000000 --- 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 66fdb40ff2651916faed4a2ae1d564cafdbf7bcb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2504 zcmbVO3se(V8ji5Kg5ZmV3I#ewZHbsZB8b0=g#+k z_y7La$vcsnwa$(njyxXES*27&ad(Ehf@a%szx(??vFC0MMrAy=Img9%&ES885R5X2P@K{dB9p<$p?SQ()g~i~r4cNkC3JdH&i}sg6d%yza(--p8dMv@ zh!njtmnNcfH8EIj8V2M1)j>d@3E>C~1d9SDLpsSICOLnC7va{{Z80C1fUs$Deu(uz zAWj_#gi$mBNJXF!13?Io!6J#&-(L!@03Z+o#bAI~0tqEj1oTHFGGOY%=T4*XWF$)Q z`>C_ICpkZbWsQhfoSmI5%Jvgcv`#F6VOR`8Vh9p)2qBY0vZzT&GE1fz6a<6OdLyf+ zNWjX7YNwhuAF&nut zlTM%T7{|m!I$L;81?0JCCML&7h@%LG%A_%3 zO%`|J5~~^`5=Ij!OVKeDl|G%Q$Z2^1BoRS?PpqEAscc5@GXp|_vV@$^WlbUkA?_Ok zK?n#V5acTX5fGe&s<}GAQ5OB*z!a`e&iO^CEx1S+l}^!W3g`Ur;{!N`BvZ5jW@%VH?>OF2Tk@O zPGOv@&rGEfX|lv0Cxk2gKu)ie6Af#Vr9x}>!CI+Aiv@szVry$~6u{(al2-hTBEgTzn_D^}jklllIvu1V{Q`ig6OgP|0jI zN)sVEE|=@hm?j7H6PqgYzU5==|fB0<6@J90B?N8); z?B48M`Q6&q<>QYftD|a*tJ$!0YduA;TS}(23t@i9jJ}9E&d>+O-{j}lDtd6mP7wiU?pLh0* zla-TQ!!6f>9b(>jct-Z*@vzVmEjaUp9adYyRH)W#u&{1)0G7#K8z}OOe9Z4J`?k~5 z;u#n4^?R%GdBZDjly!H8xtVMF9ud_Q|CsUp%X4BI?jMd19&&9{QqgG_a)Rz9J*BH| z$zM9cbZYA6R(n(=QYD(cO(#Aoy6CQh;hG<}_gRz&>ZIovmNuT&Z9VwM8m5pu&$kG$ zvTJ!+pA|E6E-UBtJJrv;*XaRo7|Z#x4L(qON`UQa?6`jZqnkg3XliTEuJKo%PCa~M z@WlnE3u1ZRT?c;b@m&$07PGImr1km-TQZ8*DS|rZudw{x4R!5F9=$VOt{XWj(Y>BT zd-yG`a(KJ-o0Dfs8h&U=J*C(_ z=8hNq6aC?^r7wqGy5!v`zvX@KNEDDEpXqBVXiB`Z=eNZRgGG2tG`F;x~xDn9)G1Y@4Fl28Px*E!|ivy@~-8Lx%@`DyQ}?V z4f!BGF*jl}N~1D%!=YeZY6W)9lyDw_Uq#NDJx^=CJZDD2|CF# zA7Ixt{Z7BT8@4fZgFkI{D9fJxang<$JS``+d(*81cbB@prG*c!rZ)8U4y-<__Pt)Z zZ3lJfK;Y5eZHd?A3O-!mWX3$UChhmy)r@4iKkvyz(mdTtF7?TWn4`7t4=} zZ`OLe!fHzEo3eUH7jwVD-n?Xnx$AC<-H6`;RB2iYH9UO}ROfZkPOl32mRZ%`xW#FL zD@GqK${E&#=gzidc(qkxLZ^tk7u}u0Uu|;00}}A@rq4$9xE75>Hwj!4$Nk!`)YmDg{{4HeKCy?7Z85xPzg%Peucca}QJ6#D*z!+`G0ZOj diff --git a/applications/external/picopass/icons/DolphinNice_96x59.png b/applications/external/picopass/icons/DolphinNice_96x59.png deleted file mode 100644 index a299d3630239b4486e249cc501872bed5996df3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2459 zcmbVO3s4i+8V(M(gEFORwSrA`4O0uPn|M|5y* zB*aMDxC&7(gP9JN;POOi-9khrC>Z9YJs2U!LnVcQEEC0fDtKo&ILlzb30%M}3J^;~ zv7RzcsilOs4Mq@tD*&R;!LMSk2A~{(`HK9|hQBqEX)3sQr9Je6SZU*F-^fD-p+~Hs; zHLkO%v?>ZoxEv+F#whudr%615FkA0DYR0tMEo}3OOY#xecLWe>xV?u5KtSmC^ z7)Fmj6gjfKstiEV-*Cxbbb+&rRWuI_rBJ)ybs_f1Rn&f2>q3pYwI^|J(hdn{j{0EZIm_F zpIyIWLsRUgOItR-dUbVd|6Zo=_BU_Tj4|{{jxO#=JH4o8er(5{!nZD_j4}MH&zh~9 zVLC~y(0-D6GO0ghZD8BYzP?o{>22~lT6^d@X{SwQ8vrNY-PPIMajIwC)`s14Ep72@ zeq7YOzM`?U{+W)ocXBr`eSOcpk?Rxc=ou5&)fWW|pD};-Z0mvk9}=&`Rb&y<77W~a z(>6YM;6Y5aIU~JKZ}mQZynKHiSTQ#Bczn@&jTiN^?vPJ(jhm7cXLx0oum5P$`TceG zU+wR;OO^)8CVlnM)5p$CO&e94KJt>HccCaHGusmW_b`T6m| z-R6V6Db1pErTot?^d22ojm+2>_)FbD`_+WbDGMx9f@hO27maS2`csiV(D&Fs`PS2& zvrq18du_&zXID(!KIxsU$)iuTYuZ?zmYiP&n&i@Be{IdbS-jA2c0QAlu5NXQv_0K< z3Hvs4eeu6B7yD&CNT~gIkMV&UkRU=V!iQ(+_(O&u^ah$+s{_yn(yBYeD40HeU{xGsIT6W Zfq!wOp!Q<>&pI=m5)b(dHL6nbwD9yPZ!4!j_b)k${QZ;XFmLn zjqNsD+YPq1J8W%_*aXBie!OR3*tC!PwU_7Q9H4U564!{5l*E!$tK_0oAjM#0U}UIk zV5)0q5@Kj%Wo%$&Y@uynU}a#izM}XGiiX_$l+3hBs0L%8o)7~QD^p9LQiz6svOM}g O4Gf;HelF{r5}E+GUQp8j diff --git a/applications/external/picopass/icons/RFIDDolphinReceive_97x61.png b/applications/external/picopass/icons/RFIDDolphinReceive_97x61.png deleted file mode 100644 index e1f5f9f8017b49ab1ea78a9394ed8ea7684e3083..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1421 zcmaJ>eQXnD7{Agv#{x2p_yIvKhl^r%z3;AfTbW%yMuEcUiZn{X?&IxtS=&4BZnPU= zlx>i)WI>$aQvw7<5XB`bIuRj@1WD9@Lr2D(5=YPwGc*zsSTf&kEAj{7lDqeL-}m`F zpTFm}Rj;U;Sva>4L6DijCB86RMfkc4?C{(9_MQ1~dCu}jtr{(6r9=ZD9z~M?8cc|F zAPhvM>5U7Z96{_EH4?R=q2+?CB^+W_$B|Cx5RD+^6=_|R8-RsMpiWJ?vC&g!FjQ6C z*cvWGhIB8eSC=#!pr(06L~d@7c?GLjjFzVbXdnSB5ltuJNmEF>u?f2Zl(WYKhEAwh z4Q^~QsA#Af^=bw{oemP0Nz#dy@(x9mL|KwbP@1GEf@BGb#Ys|Nc!6cnsRx7Z3?(Ln zeSs-waOcMAElU>&B9%%xQj9}0>IjPGd4i+~n#Q39ZZ;(?F^wn9g*gj8V9JK7TdI~s zvlc~3YqZ=L40SSxgdPgrH=H!5Dg|psq(z;e93+uQWD}dvHmxxDKa7WJn~^3R5Mf|y zjfM;x5?h!9!{R;KQC1N~Bdj!3*cCDE)8xhkNLoRk8-q6vMO6faWjLq8D>(0>TsY@s zOL2+gT{ut5lFP+&G;q>6I}gJ}uK`3$Ga{N6&(WZ|Ub8f_Uei&p7kz1snpCuuxhUJA$%K8tP}c(` zU}y<+qQrvwF!u}>V`HR<(=n36VBt1B^`_fx&WPzU_AMY;oo7=&mIg2tu^u1f5 z)@y#lGg2HF{icooYxXeey6HJl+%===Q-Yg*f$J(< z+gbGCvVprluc__jmS6m=F>l7JjJ;Cb^sMdho~B4w{1|(u#k_H5R;4;`zs)u0gC*%S zI_>C5rsHbY>U}-r=8b&^Mh7zat>Eaqs$E;p%^t}^&M*C`d_!V*2g<#^ZLQq9;N6x= zv^)OzpYh#+OwHKfQ+kHHZreNi()*6Nw&PX5?kxF@U2EB*+}LH?toC1`{oRjksXb78 zx8u;V!Qv~6!ySjp4u16f-y8F;3}d=*b!=ao^)Gw)nS({6qa!CbyuwrWMvi?_zz4rL rb-KI#{JuTj%qEZPotyLfwj*}ruaRky;O7Gyvp>k7e}(TvWo_$!Vg&g_ diff --git a/applications/external/picopass/icons/RFIDDolphinSend_97x61.png b/applications/external/picopass/icons/RFIDDolphinSend_97x61.png deleted file mode 100644 index 380a970d9004cba5520560fd9aa24aa42924e2a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1418 zcmaJ>eQXnD7{6`EHeeAZ8ii;s2g4C}y=!}S>mBQswzrLLl$EYRfoyOe?`_T2-g$Sk z9pb2CPQ(a0XM$+dKhO~O0nx;1L}kUOGdh8Ve-^?LG)CD7lOfXp&bQl&{IPJ!-TS=n z`~05I-*YefH&^B@S+xW~kUZ~3J^)t%zRsL1_&wM?{Wx46Gs{C}t*V$YK?jISRz-k% zBSHfR06}hjW(brZNLC^o44EO{CQec#79pi$iAOYuMv#)SxF$$Vz(hsR5RN*rYhQeg zp<&sHZKHjpPxFAr@WwqlsNJ(UDD7#ISQ#rTMN8rwG!Ox%fW{-uQG<&+v01wulvBq9 zhR&*(O-^hssF2T(dQ=^tjD^G{l4Q_g)*=g{AcBJ%MzrGu-R~^fg7z+Q;6eHV@=uu4-82U zYi3xDqA81lsJ56+42C+FLqzlW?i!97^Ob@%BjSQaSS=(GiKG&n)i%rk_&3wK+`#f1_%uMx&~s9uHc$EgY5An6W<9p}B;4 zpogCYa)qu&(Ag4m;RW0?c3PnnQowBrN#lw@*>TY-L0(ZbMKQG9>QDeSkC*Q$-5f{Z z2~0stN5WYZfssX-#AS)L;{r{IxG2~K90(F6+7!i3SxJn5ArdLp+{2>u5u|2HygL+d zb9byj6wZ} zqrIB@aESUiV~B&zwY0sUci%;mf;cmkA+7cD0^$ih9{f{w;v_DJ`sY;R`f3( z?7BXf_vMbW zuU1_w753GAG_~{axB58aI?KM!#N|b)zyZV)ZU9QaOj9KuN$fX{&>fy=f`f8Io+CbZIMpovDCx1HL z?$&C^=R1DyispWLc%|FSKGs*ccUMOLz=7=zt7r7(!|y7;X08;c-@aJ>V5pwIR`S;) wTk7+73`}?J{<7dJ@~ 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 94df07ba..00000000 --- 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 2158f0ac..00000000 --- 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 e6a87c4a..00000000 --- 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 05b68207..00000000 --- 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 34e98706..00000000 --- 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 5343ebb0..00000000 --- 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 1e6f12c5..00000000 --- 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 f2711d31..00000000 --- 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 6737d807..00000000 --- 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 a1a87d7f..00000000 --- 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 de43b0bb..00000000 --- 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 b45df346..00000000 --- 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 9147cfa0..00000000 --- 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 43dfc631..00000000 --- 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 2b5dba66..00000000 --- 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 6301704c..00000000 --- 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 e9d37481..00000000 --- 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 f41cfce4..00000000 --- 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 ac66cb92..00000000 --- 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 6926b2a7..00000000 --- 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 61bd5e8f..00000000 --- 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 2faa80b1..00000000 --- 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 fe63f7c8..00000000 --- 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 8ea97049..00000000 --- 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 fb23cb5d..00000000 --- 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 f2a36a7f..00000000 --- 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 bb149aa6..00000000 --- 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 e6191d5b..00000000 --- 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 2fc64746..00000000 --- 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 15a32ff4..00000000 --- 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 c1cc7249..00000000 --- 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 ffe7195b..00000000 --- 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 f5fcd10f..00000000 --- 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 baf882b8..00000000 --- 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 3b0a1cad..00000000 --- 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 90a27ee8..00000000 --- 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 8f7b627a..00000000 --- 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 ce396fc1..00000000 --- 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 cd760272..00000000 --- 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 806a2b5a..00000000 --- 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 fb7335f6..00000000 --- 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 bdfa3e95..00000000 --- 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 094e784c..00000000 --- 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 1912e5d246268d75a20984bdc8b996d503f3d166..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3592 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 BDRuw= 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 9c6242078d3bcc9a93eb55b6b5f358720ee6662c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7976 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 - -// 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 b6c75025..00000000 --- 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 0855cde0..00000000 --- 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 1cadb3a1..00000000 --- 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 3c7b9cc3..00000000 --- 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 9f6dcc5d0d9a9c1fbc54b7459b46c50c16c7e863..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6082 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 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 ca065d33..00000000 --- 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 60e4d7ed..00000000 --- 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 d625ed5a..00000000 --- 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 986794e7..00000000 --- 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 c1b10bfe..00000000 --- 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 4ff2e3042e540d8b499118e9edf4ecd180b39511..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7231 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 NY%KPgSDX4C`yZHc9FG71 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 1342dc7bf95265db5d0ab2924e1ef03fe4df9943..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7308 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 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 d8263ee9..00000000 --- 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 9de9364d13c5cbd7fe43a6df59789193d9133057..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V6Od#Ih{XE z)7O>#85cXB6sN>NS&&A_64!_l=ltB<)VvY~=c3falGGH1^30M91$R&1fbd2>aiAhw zPZ!4!iOaqHj$8}|9EV^1`~UonL4lUvGtG!wL5x*034X4|#-7<_>P#}{{_l#8SgPZ+ js&kpz9*+3KCj7Uj_`9EfRa>$PXb^*^tDnm{r-UW|gHJf_ 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 8f01af2760363b31029cbc425d9a9f2e2becf96b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 977 zcmeAS@N?(olHy`uVBq!ia0vp^3P7yF!3-qto1VD9z`)E9;1l8s2$&H|6fVg?3oVGw3ym^DWNC|K_4;uvDl`*xDGP=kVibG*#E`lk^cO$zev z+}xJ~R3@KooBBeTVTU7E1RI;jy{)QdNiPgUSiTrM5ocMrlj*@Cjo*LH^-f?g|F=lv zl)Fs&L8nKli4M~yCl?8HDNptH;hVjxE12WemhD};j?@R{i;C*6a`dzQvVm!LtxQw_ S>l}Mfba=Y@xvXZB8b0=g#+k z_y7La$vcsnwa$(njyxXES*27&ad(Ehf@a%szx(??vFC0MMrAy=Img9%&ES885R5X2P@K{dB9p<$p?SQ()g~i~r4cNkC3JdH&i}sg6d%yza(--p8dMv@ zh!njtmnNcfH8EIj8V2M1)j>d@3E>C~1d9SDLpsSICOLnC7va{{Z80C1fUs$Deu(uz zAWj_#gi$mBNJXF!13?Io!6J#&-(L!@03Z+o#bAI~0tqEj1oTHFGGOY%=T4*XWF$)Q z`>C_ICpkZbWsQhfoSmI5%Jvgcv`#F6VOR`8Vh9p)2qBY0vZzT&GE1fz6a<6OdLyf+ zNWjX7YNwhuAF&nut zlTM%T7{|m!I$L;81?0JCCML&7h@%LG%A_%3 zO%`|J5~~^`5=Ij!OVKeDl|G%Q$Z2^1BoRS?PpqEAscc5@GXp|_vV@$^WlbUkA?_Ok zK?n#V5acTX5fGe&s<}GAQ5OB*z!a`e&iO^CEx1S+l}^!W3g`Ur;{!N`BvZ5jW@%VH?>OF2Tk@O zPGOv@&rGEfX|lv0Cxk2gKu)ie6Af#Vr9x}>!CI+Aiv@szVry$~6u{(al2-hTBEgTzn_D^}jklllIvu1V{Q`ig6OgP|0jI zN)sVEE|=@hm?j7H6PqgYzU5==|fB0<6@J90B?N8); z?B48M`Q6&q<>QYftD|a*tJ$!0YduA;TS}(23t@i9jJ}9E&d>+O-{j}lDtd6mP7wiU?pLh0* zla-TQ!!6f>9b(>jct-Z*@vzVmEjaUp9adYyRH)W#u&{1)0G7#K8z}OOe9Z4J`?k~5 z;u#n4^?R%GdBZDjly!H8xtVMF9ud_Q|CsUp%X4BI?jMd19&&9{QqgG_a)Rz9J*BH| z$zM9cbZYA6R(n(=QYD(cO(#Aoy6CQh;hG<}_gRz&>ZIovmNuT&Z9VwM8m5pu&$kG$ zvTJ!+pA|E6E-UBtJJrv;*XaRo7|Z#x4L(qON`UQa?6`jZqnkg3XliTEuJKo%PCa~M z@WlnE3u1ZRT?c;b@m&$07PGImr1km-TQZ8*DS|rZudw{x4R!5F9=$VOt{XWj(Y>BT zd-yG`a(KJ-o0Dfs8h&U=J*C(_ z=8hNq6aC?^r7wqGy5!v`zvX@KNEDDEpXqBVXiB`Z=eNZRgGG2tG`F;x~xDn9)G1Y@4Fl28Px*E!|ivy@~-8Lx%@`DyQ}?V z4f!BGF*jl}N~1D%!=YeZY6W)9lyDw_Uq#NDJx^=CJZDD2|CF# zA7Ixt{Z7BT8@4fZgFkI{D9fJxang<$JS``+d(*81cbB@prG*c!rZ)8U4y-<__Pt)Z zZ3lJfK;Y5eZHd?A3O-!mWX3$UChhmy)r@4iKkvyz(mdTtF7?TWn4`7t4=} zZ`OLe!fHzEo3eUH7jwVD-n?Xnx$AC<-H6`;RB2iYH9UO}ROfZkPOl32mRZ%`xW#FL zD@GqK${E&#=gzidc(qkxLZ^tk7u}u0Uu|;00}}A@rq4$9xE75>Hwj!4$Nk!`)YmDg{{4HeKCy?7Z85xPzg%Peucca}QJ6#D*z!+`G0ZOj 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 a299d3630239b4486e249cc501872bed5996df3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2459 zcmbVO3s4i+8V(M(gEFORwSrA`4O0uPn|M|5y* zB*aMDxC&7(gP9JN;POOi-9khrC>Z9YJs2U!LnVcQEEC0fDtKo&ILlzb30%M}3J^;~ zv7RzcsilOs4Mq@tD*&R;!LMSk2A~{(`HK9|hQBqEX)3sQr9Je6SZU*F-^fD-p+~Hs; zHLkO%v?>ZoxEv+F#whudr%615FkA0DYR0tMEo}3OOY#xecLWe>xV?u5KtSmC^ z7)Fmj6gjfKstiEV-*Cxbbb+&rRWuI_rBJ)ybs_f1Rn&f2>q3pYwI^|J(hdn{j{0EZIm_F zpIyIWLsRUgOItR-dUbVd|6Zo=_BU_Tj4|{{jxO#=JH4o8er(5{!nZD_j4}MH&zh~9 zVLC~y(0-D6GO0ghZD8BYzP?o{>22~lT6^d@X{SwQ8vrNY-PPIMajIwC)`s14Ep72@ zeq7YOzM`?U{+W)ocXBr`eSOcpk?Rxc=ou5&)fWW|pD};-Z0mvk9}=&`Rb&y<77W~a z(>6YM;6Y5aIU~JKZ}mQZynKHiSTQ#Bczn@&jTiN^?vPJ(jhm7cXLx0oum5P$`TceG zU+wR;OO^)8CVlnM)5p$CO&e94KJt>HccCaHGusmW_b`T6m| z-R6V6Db1pErTot?^d22ojm+2>_)FbD`_+WbDGMx9f@hO27maS2`csiV(D&Fs`PS2& zvrq18du_&zXID(!KIxsU$)iuTYuZ?zmYiP&n&i@Be{IdbS-jA2c0QAlu5NXQv_0K< z3Hvs4eeu6B7yD&CNT~gIkMV&UkRU=V!iQ(+_(O&u^ah$+s{_yn(yBYeD40HeU{xGsIT6W Zfq!wOp!Q8gyJRa{_+4UIP z$!=1i2t*O^Q!1)9DGybMBGF3a6SW|L6h5LVfJD{LegT4thW>zPQHvPws{yrXept!t zv3=&;bMHMf^XAC#V8_NS8##{a$PeX4*}aQh-5b`i|CfLH7_-|w{?PLw$KCsIeBHqv zeQy)T-TjJN7>~xyod%|r1hT0`619rY&>XjYN6klgf<(MUimsOtE`R=|z`J%v*qt1RpF9hwQq*vxPN&rD$57IyUT+iM0RsE`QpwMy9wjao*i^BQa%zm^2P4v8i*LT?<9 zA2&z%EDZ>+C4h(lkolCJfSRgm;7MKvGLS%0g0cuT1E>Z}@y(yWq6M~NjOGTKvDi~a zC`FNPNK&<0O;nWx4T=)fbzK6oB+DX0h~cysp_=H0T`h(j331^1kxM;3W<(a9j4}dK z+DM_|w`skwSteF6sfK(BCP1803uv0FLo1awI*j_KSd^yTn-YhGX`e`=B&3r8CjC>y zi@I9D{1T05SfaPk*8co2g*I*n^e2OIy*xISNSRa^cgV1?uFp5J0YMQB3Y3;xjT&i1 zyC$M##e?pUVhLRKj&_L)9?Wld>u%HCq;SStTN}Y*kccThRe>U`i)-U2J}i z;>oxY@%)BuZHgI3yPAgMs43vsNJP47iHfQ!qLpHl$)u9T2onYB=@#3rz-223l~=OH zs_a-*O3@VL0MW4s7KyDoOqHyNDzSA4a2n~Dsk#w2OUpDcsm-dZtbCu(W=8_*xMlVs z93AZA^Zi*3>Y66X2`KP3HXIsM5Hp%vK}90@UNN>klflv*azobR>E=QjBQG^aWtXqJ z(?B?06d3`>ZXmYMeC^(>%xg-hL0c^mM!Jei8nBQ$Q56NGx5!#@TNg^V5+9y5Z&x22##B&{B?u64ye+M3KZ=XlsY71%@jTp=Dy zHDISkcY5&@J8>5Bx!%I~{^i3@-@m}$cNaW+{nKk_j+x(U>F+k}c?6!^@X+fADi3lO z_rLKG{`yum;ZU>ayk!Z+q>VzZOn^bqQ>?UO0Drz@_TNg$rjt zNcQEpt?wS&gMaKe^8V2SorGL{ZtT%R?yPd~`n9FG(}zAOOPl5My;t&Z3(*F9I?g}- zvp)ag@#QCe{o%9hrGrn+&dpu9`rFcD;MqUV>^-?JG4|Gpeamy-PL6)jzu5T`{Cd7~ fwr}T&J8Rt1;5!ej|9##1_yo=O59dzx?S1thQe1#H 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 e6c3ce363f801cff5080d10599ca258d07783fa1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4446 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 != 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 683937df..00000000 --- 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 25b237d6..00000000 --- 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 30d60709..00000000 --- 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 3518ca25..00000000 --- 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 ad006b8f..00000000 --- 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 438f338f..00000000 --- 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 c3761cd5..00000000 --- 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 43e2d228..00000000 --- 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 a393e549..00000000 --- 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 7780005f..00000000 --- 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 2ac6d21e..00000000 --- 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 dc0cc4fe..00000000 --- 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 d9b8f0aa..00000000 --- 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 876a2872..00000000 --- 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 539578a4..00000000 --- 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 ca4b765a..00000000 --- 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 c0e37730..00000000 --- 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 bb514245..00000000 --- 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 0d3ae66b..00000000 --- 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 687f17f8..00000000 --- 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 bbf38a30..00000000 --- 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 4b16baa2..00000000 --- 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 d5767455..00000000 --- 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 cb48035b..00000000 --- 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 c39c4a18..00000000 --- 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 c7f736f8..00000000 --- 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 38d064a4..00000000 --- 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 d5e289e2..00000000 --- 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 39039466..00000000 --- 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 08a8d105..00000000 --- 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 fbe954fa..00000000 --- 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 22036f4b..00000000 --- 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 dfa384fb..00000000 --- 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 96c3632d..00000000 --- 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 37ac927d..00000000 --- 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 285ca66d..00000000 --- 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 9b787bd7..00000000 --- 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 6a529d32..00000000 --- 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 91080941..00000000 --- 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 56364f15..00000000 --- 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 91a65474..00000000 --- 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 8b623eb3..00000000 --- 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 eddf36e4..00000000 --- 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 f95edb60..00000000 --- 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 790f9799..00000000 --- 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 6a8645b6..00000000 --- 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 8dcaa125..00000000 --- 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 b0486183..00000000 --- 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 11146597..00000000 --- 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 34b074e5f75150853ec976d7521e1663f0f30f1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3624 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 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 6d8c71b000699e148e9480f7ddf9795b33e2fe7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3618 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 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 f7c9ca2c702f1b93d7d06bd12ae708655c79d7c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3597 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 a9|QyVQ~@!E@+ey_4zMz}H7hmoyzn0`d`!~- 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 3bafabd144864b575144c75b592e5eaf53974566..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3606 zcmaJ@c{r49+rKTOBBhHB}+m>LbCLY=Y4wK?~kwVKJMeb&hxs?-|t+n40QpA+b4G8*k_>A)gsvzul2%)`{+ zGXO-B3u=_{$d$PU5YEZSn%Bo%6nB$X*pi8HtvlN(j>)<>oU^ms-{SJc!?CVM_kGpq zD|mb=fG|Jac@dmEE>EYKyFP!dPw~V2q0~L3V4zJ7VgZs-lDyFoU9CnK9lA z{|)s3FeAcdMKT|ltq9$x0m1;iQ-6nS!_cqj3MXxM0Gt2}LS)A!gg7{$QQxIe9%xhs z9ymYp6$g?4Aeep95(3@bioPky5s{%vM(c>C~+;D?q3rCl<9Vk3~u)C^5I%(w`)RT2PH zm)f7N?K9(ykBtnC`Hctjzt`uk1dC{xK3DmG+T--QM)Dliz9M@cHh&jC)x2t{F@ZnKih0C+}OXW@w z`v&$?T!Pj1rsQGSiPMN#jg(cf#BeEqd)~3u;mM}Qyx`i%uR_AH()f-rz&vtJ?~1BK z0wCjWh+r=QKw`~Oyt$4L(2|<}2>>cTD<8d+q=bD10syO=GrJ#HY?6E~&#jfte6C(u zt0YX=Xk{+Bqt-;ma^pzUR`Hw4DHbX&wa9MK#}7nQbGD=p$&@~a?~@uIls$T8lCHGT zTRHoMa^-n3QHw^99AP{1;ufE{Zb&OgDJ@PELckbai^>O2T$Dcqsc&TD3l~}jCU{~r zzv(gLjjtXx|H*H&$^=ebjw433!=?SMd>|aXa>3gB5?)oiL6JC$H*$+NBC6x}hAF7kW)t|J z9m26ua#NsV=VV?4pXG3D@mM_ij@FcBscZ$vT`c+>{Ka38#5<0qS`o5Kbu1s`Lk`}C ztNnHRw(Z$k$NrL*^Gd|*kZ!s*;vl|Vi-WL}unWTUV)XKz^G!Qs$eCE}Ne-py;|QoE ziVIFnDC2DAI9^+BdO1=ikF38qj1|k>fy+;lJzzvK8x_5E17Vq#bN5h7VfH)F-HXT@ zhwUgiVNOuz3x#rqq3K#J8H#9LzFuDEn{={2c`*Pw!K@JLkKSgT`X;p_=<}wD@rmf~ z;gVA4rJ@@!K08%{R8FWAD3_@~)3CQUyiHAObb-A`sHOQ|-+Z0sir>Ak`=mm`YuRLE zvRiUw^7vgB*AQ2;PWD|1mwT?8?;UeHb=$`Ek<+I_v3H91It$fZpB3&YZpDS;;+@(K zdF54mt)Bf!lqxwNW0P|pljlM#d!=%9yW%SZX%=tU#c&gu)D60B?{lPNX$l**VOcE< zdIIZ=4!P^c^-J)}8av)1B>n2);EeHy%mc04Tcui0=!xi=={@WUEb=RgEZW->(No>y zGtHP*oSy9AhtjjmvvjlOkrd=&s943GibEAK6}_QtUrgT;C)pEX^RMTnC;HoM=PBRw z=9RwiyZG%Idtrv4Jsg!__&(xHGl%#&=sLN)edgTIoh`h8iiEm=ymq_1zsj}0Uhw~9 z#8NW#s4ujm8iU4JvG{?xr?d;JWxCeN2BzQy;MMf~vb=1*A#83ixqIOEV` zVaGg#~3WwEx!kV?Q+q$;Ioo@pT$VAd^FJUK|pMWk7 z+6G@N*C4B;DJ`9n-?bZYSO3eQQfKCI=Av#Fcf@1azbbAvzVOP^{k?%t7-9b0z+hZ3 zaVn!cs{C&G8PM z+2JN0Mjo7#`(m!krk0qEMuRP#pvsP;1yp-=xo_t(VjQijbFbzedRSI|z~tIkmRs_| zzW)8E&_4stJKBW4G7xjb>97-2u07S9vv;%V`p9kjaQuUwaZ+YdW*$z8oKmXu9#*!q z%+XIrCsAsIJw|!0mU!Xy;)v!_$Xu^Na16FRuM}78B&~>r-qB$lQ9i;d$5deszcU!{ zTl=!4DREZuWEJOuQ~85O-Q_Hg*+EE+^)p4ySZAeheYhvC!k0y!={Us;;FYATIt}A- zuHORLec$46(H*yLp>@u>8zvVfHSws$-w!_}DiD%=UHO5jok!eG?^a6o;?lWyihn$? zDIXhlckt>wInSo_^n5%}_Ii2}Gnqe0E+&@qiXwmuR{ESqQ+U(U)H80A6kIb79 zf%9=Kr7f>pM2rYV(?^=0aC^Vq+>^Huk#*XW=eAmOudMomc28GLfB11cI@{U7;B zQ-8QzAye z?YX)QgQSmUMA3ROrqjb8(+}^Keqk~C{I7xACr^BG`h2tXW#7w|fwa?Q^Pou#Tc-nA z6Ux=gqvW7&R`EYy$;(ndrfyqZ_A8PP|3nOJFp782&dJ(|nq3+>oA{}~w;(&q!3^~- zt&hEkT}cb_JmgvBk8aC0Q(}I_mU%5U&3zn?_nfJue}^pk^lFtIEJ78dY$NHbLzw$V zXp^Kx-n6?(G4s3qJ66M%C`$TCPDSu}Lmjrwww;{p%X+9*d9fjae!jTBR?Bh)&695p|Np`_A@%C6Gkw(!c ztlQ|bD0BfD08GqSbOJGm#02}0{K-@lg#WAt0w(*SAnr!?Fncs1cZ-)AAzU~M!*noC|vOF)r0RvA`FmlWAHx@MBtF&>xaZy+5F>9 zprIfEOeP%(g@%WR>xUcY(-{6xxUsP@6o!Bz5PAX&y%08)Nnq(wLo|OgSdl`A3^JWb zrcuG`j07KAC=&${1pA*XDD;16sUiPVN>DQ>i$I6M^|Nl)Xlz**5m^jjZ zpQ#thS=L9?WiG40+mRzvqC`xB>H5sFVffs4KqX-!S)&$7{TGz=zWF=INHY2 z0tT}-KpPtw|HfL;h@lh`mH8X%`(G^lkJ$BrpwI=Ltw;=V7|GX$L8E~G&KgPnV=RW& zf8_fI>-)!83~m01g$ja!uJ`tT_4@agV1U-ee}`9~{5$?6s$k|Bg5ln!QST+V7#p3i zF4n&y*YC(C3v7{K(X_L&aAEcMczb*MMhV&2h)M`^tW<_XOB8+kL0OWLfY3%j)E-d2 TFC+3}9cE|kU{!4CefEC<&8td2 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 6825247fbeaf98b4d0d9f8aa15d4f2c5f45dcf3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3675 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 N!3~Mzlm%~0{|8*@s)qmo 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 7c55500b7e7ea9112c92ba966643e3684887eb92..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3611 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 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 21ad47f4b2bf69d81929187ca63d7a3d1b111ea4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3616 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 Y4M;=-T9{t958 z2#qC*WXVoKV+mP%$Mbu7e(xV|@42pXzW4V&pU>yMzxREg>pE8*?5qU^WCQ>J5VS#9 zpg8MJ&J6Mcqn^zcKy?O)nxYMMjNADIC77ua?(V;KVX20HiY%aC)gwEo2w(aB@jcrV37&d zYhS(w0GQ)p&?9J%j5oL*k^ydj(xrYtv~l=XRHcKmD*#Rch9IJoySNfjK$E&tlQ__{ z7kK3O)LQ^Z0RRFc%nSnD7X)U0*ckBvJ;llWQb14szG4s%#|2~@v_8OX@)GcLzJOBY zu6qsSF-;)qymh5qk#5hmthpnr`GDYfbfU0{ClHxorrH94^|=A_{bH>=U?fkTMrZ9% zu?Ho(0>K5;u~J*pk9TT|SERm|30asM8c`T|O?YgEkvb&e!#@VePR~*lLrn4@+jawh z%xcH0Eq&v}$%(Py37<&<`$t3mR=^w?Vx%xXxK(wXn->tVYiIX*jE{HoP#U=&1=R)= zp8|Sa0KdUickMp@ypsa&Lsw%N`Wq(ub8kB|8OrSw*tKg`$?JBt#%Qe3FYRISP;A69 z=j~Qs=p1l1(~_R>S!@m03f+`HNixM3usL*90h=?uX|75OOZmp1p$CX-i5=DOn2^nCC;o9%6=tR zRVT%b*g8Oa!B;_g=vb^ z4$r;0ulH76=I1qS0*PT1U@?2V;(H)%AgPRaUI+%Eb0e}4JQX8;0@Bb#E#xjX^G|X| zC@!c`#SP+4o2(`FHG#FRZCtCe)=atZ#^N2cWmbjXzL zhetloFX}k{HHZd;UyH{^c4!LuT>p$Yef^51=T)?fa-$@69Ifk;po^759|@L_t;@x* zK?k^FBgJMwXD*4nCR|KRv_>P*=J%9l6w5>_L9YB!mo#7h1xdbVU#1i)x>`^7f;~<| zTQQZtE9_UuRXX#RkeEj@;($=|jWIg`1*JqSn_V^mh(3f`p<|&@rwBe9sXU!XZ2mF^ zdJ@S5rze#s3Mbm%SZ{taRxS=}h#5ih=N~{7ridQX#Tk$D-npe^mXUY=L~C*GN6`Hk z*sYT`#Jpe!sNiKKU; zsjyU+)QHr{`%cb*&cABJkzQHH*LL6Jz1SW2J@}U z21Cyw9nAyp`!Icyd~znvwsHx*eLOU0@HzWfn?jpl+c`BJHDk5M-Toy$B@rb@dP93_ zdc9_;vy!vZz3d=Lj!BMc&Jv6WTM6Q?)T=yE8C}^I)c(!r19qA*#lQ4!NoZ=I!+MGM zqhLwu8@rp`A%8?e2c(xMP0-ZG&b1_BzXsgIS9Hu>8osxOMN`-Y#6IK)S42I=~LNJ_JP*Y(xlqY>|r*~#2a*F z2jpUEK3DZ^#6{n+%x*Xqs~6jt)|(c_;!CqlTVdXGF>+zJEV+DQ+H{|uR-GnxyAm8^ zU9)y)!LnG-@0Dbg)CXq~2gOIk6ApDAT5=@yYR+uT2+U;8?3guJ#w;r>6PMfNTK0*` zbswc24WrV6T7n6bs_DXEoj1kx#c!ruePw-b2j(p5O5Hu4$P!HtPM2~d7F{bM-3n!; zj>~+n?0oiNsUYiRR)5K7;>Up&ctiMubzAi;*=F}QaJK1>xfS%t*_P3qqO79Vi;0ua zGr?!v&a7AOw||;Lkc{6zL?9}Cp<9oRSy4y&? zY&XB4n>;m{Tqm_4yNcEB_f^g8ka!2mkvJ*4rqQB|+~2(?{&G8LP$YtUcNIC+@*EU1 zWKD>vkjG1BNUes8A3CgcU;W#OGDq53+KOs7bIfhsw>o}4q4@fXqkaC*slmQXe*%ht zoyn?*thirsfqvzu<$Ss*P3!>w?A5XQo_hGz(LnA=LZ){1Sf*1N4O=?ipZ`K?Vycam z8)E3D>y{X%AAM6a{fY5-6xhrGy4QZZh-51#ws0vc+TOAzKQ8~otfOUh1vf3>}NHDlV zdmj~*WWh1U1o540@|AZhV~VSRi+vJ=XkLXr$Rrq_Y}PXQH?nHQG3v5 z>)Wd0u8Wdk)rpTBDjq%Usi3>f4?$`zUrH**I!cA8Yr3Nq*+C!w4GX zyx`C1Ux-IVb>6vSu5!^;C$%`GnMEr7aqil`XtzWC zm*QK?THm$u=wftdPqjQ}_AT7jD_9QAIq%ML*(`ZbUh`SGx4U*A*D?ws4XY{{PXr;!Q$4{K|m@Dovb zar+T4%6L{Jxi@PzGvpcNv8oV2JZq(uH?Y1}lZ(0X4&X+HNrV$L4PFQUa zQ>}oQ2ftm-{(8M2NA8TAbxrxN2)5=ZHmFfI!8JE8=OBE3b?jpDXpwhOZjPNX{9{Hx zV+Fa95#WBpz1r8jJ=a)@_8nR7vC_QwWir8iu8Q&lvf|aJRDQe!UJAF4pll8!9-bmk z<5pO+u7;(wAGXs+JJ=u2uld(?1%CSZN!|SxqniD8Mz)-!Jg~1qsdDLO@bauwh`@Jb zzk6r`{ozJU@8-9iYr@~omu)@9)e(n&de(Wizi|_03-Mpc-AeiO;mUBQb&GYEqLpG? zLXNz=te{Nwf_Gc;aM6<@vG#WnF25Mlfe$7JH%Hcwx1%?D=60>dw%3+2iWjNu2gMIz zjf#!(Rc#FT{N0U`w!Uz71-o*vv06Uk;D*VT!(zu8wz25F{fg0K*wzMg<B>T`pFjO31>P_~-fo+HwUmOaD@n)QD#u)+tk22l~O+(uvVOTOz9kY#5 zrxPh0HUJnJ(;gG*|VH|tg4TXUJhR_1wkpCowwsioTlc_kcp1Ot_ zRzpJ%e8fQA8{>t+dU>gWwKTLep&B|+O&v824Vbn8Oh*U&&jsOxqk8+mP!?AI1mo=B z5I-7?0)s+BLPFF-wAIN}U#O;mfdN!Q3#z51#zCkBGDtKGU5yl|_*=mO7l@_eDKtEp z1m0G}c#(r>a0n;W|D1tH`B#<{_)ncU6@$_-6sV@U#`c+h18r^pe<+doFFKHh!u>bj z|5G^7i9x|ZQMf>I5EaYmoR8vmC<@G+io?*zR3|c-@Vkr-eq(`ynw+1+toQ;L46TR2V)7#tA6A(24DVXY@MO2ZIUc4X;fENVFW;}?ba)5x1 MrJY5ondim-0h+K&wEzGB 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 d766ffbb444db1739f2ccd030e506e8bada11ee8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1139 zcmaJ=TWAz#6rQ4%BpO*okt7zz3Bkm=bK9L=XV}qhW_HceY#KHzP4Z$UGyf(-b}pUy z<8ESW=_MtCk6tj|`k)VrCbo(SMH0n`eW+KIU`wG5O`$IeMg)Vzf7adDhv+af=lqBB zo%5Z`zqhqzdu2s+1%_dji6%LPq#u2o%9fzN?;7Dlq6)^^VVjkKImH23RI|DPo-mXi zkOGP}@Wrnnf?-SQ^>jOIPc{pxWsr*JL*@+|p)oA7EpIDoAAoo_=+RA)c=F3Qf$N$` ze9k55q%DD7y=l+^ZG$aob+Aw6HDcRVJdzhs00Te;&l_3O74jlch$|r7GgAa!aDjay z@rG1;vK5ys2jF3n@vAgV<6)izn!k6Qhd>D(EhD7l zcrhJ1i9|1iwm?z2T#n2INXzM=7@p@Tnx$CQk39VDfC-hn-*jtB5oF-1j&4KUGI1}W z(rxuakw9eMRAJc3%8 zlBq3$QTyJX$a6$&1ldyi4Pe5AEE32Sg@vDzY~7qR?1u@oXh zd9(fBtV<@eK%Tm=yy&p7{=h^#@1W)WFFSe!U5pP~o71uR`FW)7xc*=d5_b}EG@XBZ z@<7MRp-;+|o}SzJvMyfx>37Y4etBizf%0H*zaIF?2ObZt?$D;{o|esJ z*PgAOIO^*8tL%z2)|}k$DP5kN5}8qo*wNa8y?R2=%wO{gCD(`sHt}TzWQuK zMDIJap(nb2=7*ns*oDcRBbC23yy`kvKYV`ovU`a=EmxNv-90;;5r6+l8hQTp^u`Hn XX6*+%8gHC`h)Tl}u@-r>vFqE{F~5F& 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 b839eeb7aebfcf8aee9b2ba9570a3d9cf1d8af12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3607 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 PjRq`CY_X+i_pAQ_NTe=6 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 874f6dd3..00000000 --- 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 1071d1cf..00000000 --- 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 e0d405c6..00000000 --- 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 15b6d1eb..00000000 --- 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 853b7844..00000000 --- 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 3e3b9cee..00000000 --- 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 588a7f82..00000000 --- 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 1694403c..00000000 --- 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 813fe152..00000000 --- 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 155bb07f..00000000 --- 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 d333164b..00000000 --- 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 e13576d2..00000000 --- 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 30430b83..00000000 --- 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 d566bb39..00000000 --- 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 4b0e6602..00000000 --- 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 9431a067..00000000 --- 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 f4b850d7..00000000 --- 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 151282b3..00000000 --- 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 f2fddd40..00000000 --- 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 036db054..00000000 --- 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 14ba8b27..00000000 --- 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 6c2715b8..00000000 --- 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 313748cc..00000000 --- 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 cfe938e6..00000000 --- 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 bd35c2fd..00000000 --- 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 ec51ddb0..00000000 --- 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 03215bbf..00000000 --- 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 48937601..00000000 --- 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 93dc2548..00000000 --- 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 712eb07f..00000000 --- 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 24e883e6..00000000 --- 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 526648d1..00000000 --- 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 3a06ce49..00000000 --- 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 088ccd7c..00000000 --- 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 2fbe961f..00000000 --- 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 236777a1..00000000 --- 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 026856a9..00000000 --- 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 ff047fae..00000000 --- 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 e7681043..00000000 --- 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 f9306e5f..00000000 --- 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 8cee4ee6..00000000 --- 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 d916dc76..00000000 --- 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 0ba8ec01..00000000 --- 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 fcd8f6d3..00000000 --- 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 b26661be..00000000 --- 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 56dd6fa8..00000000 --- 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 c4ce1627..00000000 --- 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 f81aa1f5..00000000 --- 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 b3b3f219..00000000 --- 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 705434a2..00000000 --- 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 7d5cc318c369f583c531ca5e8846a9a498ec44b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V6Od#Ihk44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`0h7I;J!GcfQS24TkI`72U@f-asejv*Ssy?udP3<@01TYulb=@zZ(cJX(> z9E<0IiRH6?9buO;SoeAj)2m&2)(%T&iEpuE4*KbLE`4W{EU(#4ulkv@OZPmG6Pd23 R{2OQ -#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 712634a2..00000000 --- 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 41e24811..00000000 --- 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 9adff39c..00000000 --- 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 11601fe7..00000000 --- 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 0a90ee22..e3ceac34 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 bb43ce8a..f31cbb9d 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 776977cd..0d3b1f92 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),