From e292fbfcd508137ade8cead388bf9ff90364bc92 Mon Sep 17 00:00:00 2001 From: UberGuidoZ <57457139+UberGuidoZ@users.noreply.github.com> Date: Wed, 25 Jan 2023 23:52:38 -0800 Subject: [PATCH] Added xMasterX API v11.x source --- .../DEV_FW/source/xMasterX/airmouse/LICENSE | 201 + .../DEV_FW/source/xMasterX/airmouse/README.md | 60 + .../source/xMasterX/airmouse/air_mouse.c | 156 + .../source/xMasterX/airmouse/air_mouse.h | 30 + .../source/xMasterX/airmouse/application.fam | 9 + .../source/xMasterX/airmouse/mouse_10px.png | Bin 0 -> 1634 bytes .../airmouse/tracking/calibration_data.cc | 85 + .../airmouse/tracking/calibration_data.h | 117 + .../xMasterX/airmouse/tracking/imu/bmi160.c | 5988 ++++++++++++++ .../xMasterX/airmouse/tracking/imu/bmi160.h | 992 +++ .../airmouse/tracking/imu/bmi160_defs.h | 1619 ++++ .../xMasterX/airmouse/tracking/imu/imu.c | 29 + .../xMasterX/airmouse/tracking/imu/imu.h | 18 + .../airmouse/tracking/imu/imu_bmi160.c | 88 + .../airmouse/tracking/imu/imu_lsm6ds3trc.c | 94 + .../airmouse/tracking/imu/lsm6ds3tr_c_reg.c | 7105 +++++++++++++++++ .../airmouse/tracking/imu/lsm6ds3tr_c_reg.h | 2448 ++++++ .../xMasterX/airmouse/tracking/main_loop.cc | 189 + .../xMasterX/airmouse/tracking/main_loop.h | 21 + .../airmouse/tracking/orientation_tracker.cc | 95 + .../airmouse/tracking/orientation_tracker.h | 68 + .../tracking/sensors/accelerometer_data.h | 38 + .../sensors/gyroscope_bias_estimator.cc | 313 + .../sensors/gyroscope_bias_estimator.h | 134 + .../tracking/sensors/gyroscope_data.h | 38 + .../tracking/sensors/lowpass_filter.cc | 84 + .../tracking/sensors/lowpass_filter.h | 81 + .../airmouse/tracking/sensors/mean_filter.cc | 46 + .../airmouse/tracking/sensors/mean_filter.h | 48 + .../tracking/sensors/median_filter.cc | 69 + .../airmouse/tracking/sensors/median_filter.h | 53 + .../tracking/sensors/pose_prediction.cc | 71 + .../tracking/sensors/pose_prediction.h | 55 + .../airmouse/tracking/sensors/pose_state.h | 56 + .../tracking/sensors/sensor_fusion_ekf.cc | 333 + .../tracking/sensors/sensor_fusion_ekf.h | 188 + .../xMasterX/airmouse/tracking/util/logging.h | 38 + .../airmouse/tracking/util/matrix_3x3.cc | 121 + .../airmouse/tracking/util/matrix_3x3.h | 138 + .../airmouse/tracking/util/matrix_4x4.cc | 87 + .../airmouse/tracking/util/matrix_4x4.h | 37 + .../airmouse/tracking/util/matrixutils.cc | 148 + .../airmouse/tracking/util/matrixutils.h | 65 + .../airmouse/tracking/util/rotation.cc | 117 + .../airmouse/tracking/util/rotation.h | 156 + .../xMasterX/airmouse/tracking/util/vector.h | 251 + .../airmouse/tracking/util/vectorutils.cc | 40 + .../airmouse/tracking/util/vectorutils.h | 76 + .../source/xMasterX/airmouse/views/bt_mouse.c | 310 + .../source/xMasterX/airmouse/views/bt_mouse.h | 14 + .../xMasterX/airmouse/views/calibration.c | 69 + .../xMasterX/airmouse/views/calibration.h | 12 + .../xMasterX/airmouse/views/usb_mouse.c | 139 + .../xMasterX/airmouse/views/usb_mouse.h | 12 + .../source/xMasterX/barcode_generator/LICENSE | 22 + .../xMasterX/barcode_generator/README.md | 71 + .../barcode_generator/application.fam | 11 + .../xMasterX/barcode_generator/barcode_app.c | 342 + .../xMasterX/barcode_generator/barcode_app.h | 87 + .../barcode_generator/barcode_utils.c | 125 + .../barcode_generator/barcode_utils.h | 53 + .../barcode_generator/barcode_validator.c | 344 + .../barcode_generator/barcode_validator.h | 13 + .../xMasterX/barcode_generator/encodings.c | 52 + .../xMasterX/barcode_generator/encodings.h | 6 + .../barcode_generator/images/barcode_10.png | Bin 0 -> 161 bytes .../screenshots/Creating Barcode.png | Bin 0 -> 1681 bytes .../screenshots/Flipper Barcode.png | Bin 0 -> 1207 bytes .../screenshots/Flipper Box Barcode.png | Bin 0 -> 1372 bytes .../barcode_generator/views/barcode_view.c | 444 + .../barcode_generator/views/barcode_view.h | 23 + .../barcode_generator/views/create_view.c | 493 ++ .../barcode_generator/views/create_view.h | 46 + .../barcode_generator/views/message_view.c | 77 + .../barcode_generator/views/message_view.h | 22 + .../DEV_FW/source/xMasterX/bpmtapper/LICENSE | 674 ++ .../source/xMasterX/bpmtapper/README.md | 14 + .../source/xMasterX/bpmtapper/application.fam | 13 + .../DEV_FW/source/xMasterX/bpmtapper/bpm.c | 262 + .../source/xMasterX/bpmtapper/bpm_10px.png | Bin 0 -> 181 bytes .../bpmtapper/icons/DolphinCommon_56x48.png | Bin 0 -> 1416 bytes .../bpmtapper/images/DolphinCommon_56x48.png | Bin 0 -> 1416 bytes .../xMasterX/bpmtapper/img/screenshot.png | Bin 0 -> 1987 bytes .../source/xMasterX/brainfuck/README.md | 10 + .../source/xMasterX/brainfuck/application.fam | 14 + .../source/xMasterX/brainfuck/bfico.png | Bin 0 -> 1822 bytes .../source/xMasterX/brainfuck/brainfuck.c | 137 + .../source/xMasterX/brainfuck/brainfuck.h | 3 + .../source/xMasterX/brainfuck/brainfuck_i.h | 86 + .../brainfuck/icons/ButtonRightSmall_3x5.png | Bin 0 -> 1738 bytes .../icons/KeyBackspaceSelected_24x11.png | Bin 0 -> 1977 bytes .../brainfuck/icons/KeyBackspace_24x11.png | Bin 0 -> 1979 bytes .../icons/KeyInputSelected_30x11.png | Bin 0 -> 1992 bytes .../brainfuck/icons/KeyInput_30x11.png | Bin 0 -> 1994 bytes .../brainfuck/icons/KeyRunSelected_24x11.png | Bin 0 -> 1984 bytes .../xMasterX/brainfuck/icons/KeyRun_24x11.png | Bin 0 -> 1984 bytes .../brainfuck/icons/KeySaveSelected_24x11.png | Bin 0 -> 1853 bytes .../brainfuck/icons/KeySave_24x11.png | Bin 0 -> 1863 bytes .../source/xMasterX/brainfuck/icons/bfico.png | Bin 0 -> 1822 bytes .../brainfuck/scenes/brainfuck_scene.c | 30 + .../brainfuck/scenes/brainfuck_scene.h | 29 + .../brainfuck/scenes/brainfuck_scene_config.h | 6 + .../brainfuck/scenes/brainfuck_scene_dev.c | 16 + .../brainfuck/scenes/brainfuck_scene_exec.c | 16 + .../scenes/brainfuck_scene_file_create.c | 54 + .../scenes/brainfuck_scene_file_select.c | 35 + .../scenes/brainfuck_scene_set_input.c | 39 + .../brainfuck/scenes/brainfuck_scene_start.c | 49 + .../xMasterX/brainfuck/views/bf_dev_env.c | 396 + .../xMasterX/brainfuck/views/bf_dev_env.h | 18 + .../DEV_FW/source/xMasterX/brainfuck/worker.c | 207 + .../DEV_FW/source/xMasterX/brainfuck/worker.h | 8 + .../xMasterX/bt_serial_example/README.md | 1 + .../bt_serial_example/application.fam | 13 + .../source/xMasterX/bt_serial_example/fbs.c | 108 + .../source/xMasterX/bt_serial_example/fbs.h | 23 + .../xMasterX/bt_serial_example/uart_10px.png | Bin 0 -> 1883 bytes .../source/xMasterX/caesarcipher/LICENSE | 674 ++ .../source/xMasterX/caesarcipher/README.md | 17 + .../xMasterX/caesarcipher/application.fam | 14 + .../xMasterX/caesarcipher/caesar_cipher.c | 147 + .../caesarcipher/caesar_cipher_icon.png | Bin 0 -> 172 bytes .../source/xMasterX/caesarcipher/img/1.png | Bin 0 -> 2197 bytes .../source/xMasterX/caesarcipher/img/2.png | Bin 0 -> 2063 bytes .../xMasterX/calculator/application.fam | 12 + .../source/xMasterX/calculator/calc.png | Bin 0 -> 1206 bytes .../source/xMasterX/calculator/calcIcon.png | Bin 0 -> 2002 bytes .../source/xMasterX/calculator/calculator.c | 453 ++ .../source/xMasterX/calculator/tinyexpr.c | 785 ++ .../source/xMasterX/calculator/tinyexpr.h | 97 + .../source/xMasterX/cli-bridge/.gitignore | 1 + .../DEV_FW/source/xMasterX/cli-bridge/LICENSE | 674 ++ .../source/xMasterX/cli-bridge/README.md | 24 + .../xMasterX/cli-bridge/application.fam | 10 + .../source/xMasterX/cli-bridge/cli_control.c | 109 + .../source/xMasterX/cli-bridge/cli_control.h | 8 + .../source/xMasterX/cli-bridge/cligui.png | Bin 0 -> 8410 bytes .../source/xMasterX/cli-bridge/cligui_main.c | 133 + .../xMasterX/cli-bridge/cligui_main_i.h | 41 + .../xMasterX/cli-bridge/console_output.c | 13 + .../xMasterX/cli-bridge/console_output.h | 4 + .../xMasterX/cli-bridge/internal_defs.h | 118 + .../source/xMasterX/cli-bridge/text_input.c | 33 + .../source/xMasterX/cli-bridge/text_input.h | 5 + .../DEV_FW/source/xMasterX/counter/README.md | 8 + .../source/xMasterX/counter/application.fam | 12 + .../DEV_FW/source/xMasterX/counter/counter.c | 108 + .../xMasterX/counter/icons/counter_icon.png | Bin 0 -> 233 bytes .../DEV_FW/source/xMasterX/dice/README.md | 16 + .../source/xMasterX/dice/application.fam | 13 + .../source/xMasterX/dice/assets/coin_1.png | Bin 0 -> 539 bytes .../source/xMasterX/dice/assets/coin_2.png | Bin 0 -> 535 bytes .../source/xMasterX/dice/assets/coin_3.png | Bin 0 -> 204 bytes .../source/xMasterX/dice/assets/coin_4.png | Bin 0 -> 546 bytes .../source/xMasterX/dice/assets/coin_5.png | Bin 0 -> 530 bytes .../source/xMasterX/dice/assets/coin_6.png | Bin 0 -> 546 bytes .../source/xMasterX/dice/assets/coin_7.png | Bin 0 -> 535 bytes .../source/xMasterX/dice/assets/d100_1.png | Bin 0 -> 628 bytes .../source/xMasterX/dice/assets/d100_2.png | Bin 0 -> 618 bytes .../source/xMasterX/dice/assets/d100_3.png | Bin 0 -> 630 bytes .../source/xMasterX/dice/assets/d100_4.png | Bin 0 -> 635 bytes .../source/xMasterX/dice/assets/d10_1.png | Bin 0 -> 544 bytes .../source/xMasterX/dice/assets/d10_2.png | Bin 0 -> 531 bytes .../source/xMasterX/dice/assets/d10_3.png | Bin 0 -> 516 bytes .../source/xMasterX/dice/assets/d10_4.png | Bin 0 -> 517 bytes .../source/xMasterX/dice/assets/d12_1.png | Bin 0 -> 514 bytes .../source/xMasterX/dice/assets/d12_2.png | Bin 0 -> 517 bytes .../source/xMasterX/dice/assets/d12_3.png | Bin 0 -> 523 bytes .../source/xMasterX/dice/assets/d12_4.png | Bin 0 -> 493 bytes .../source/xMasterX/dice/assets/d20_1.png | Bin 0 -> 523 bytes .../source/xMasterX/dice/assets/d20_2.png | Bin 0 -> 508 bytes .../source/xMasterX/dice/assets/d20_3.png | Bin 0 -> 503 bytes .../source/xMasterX/dice/assets/d20_4.png | Bin 0 -> 504 bytes .../source/xMasterX/dice/assets/d4_1.png | Bin 0 -> 376 bytes .../source/xMasterX/dice/assets/d4_2.png | Bin 0 -> 490 bytes .../source/xMasterX/dice/assets/d4_3.png | Bin 0 -> 369 bytes .../source/xMasterX/dice/assets/d6_1.png | Bin 0 -> 471 bytes .../source/xMasterX/dice/assets/d6_2.png | Bin 0 -> 483 bytes .../source/xMasterX/dice/assets/d6_3.png | Bin 0 -> 478 bytes .../source/xMasterX/dice/assets/d6_4.png | Bin 0 -> 467 bytes .../source/xMasterX/dice/assets/d8_1.png | Bin 0 -> 457 bytes .../source/xMasterX/dice/assets/d8_2.png | Bin 0 -> 482 bytes .../source/xMasterX/dice/assets/d8_3.png | Bin 0 -> 444 bytes .../source/xMasterX/dice/assets/d8_4.png | Bin 0 -> 471 bytes .../xMasterX/dice/assets/ui_button_back.png | Bin 0 -> 220 bytes .../xMasterX/dice/assets/ui_button_down.png | Bin 0 -> 102 bytes .../xMasterX/dice/assets/ui_button_exit.png | Bin 0 -> 211 bytes .../xMasterX/dice/assets/ui_button_left.png | Bin 0 -> 1415 bytes .../xMasterX/dice/assets/ui_button_right.png | Bin 0 -> 1839 bytes .../xMasterX/dice/assets/ui_button_roll.png | Bin 0 -> 189 bytes .../xMasterX/dice/assets/ui_button_up.png | Bin 0 -> 102 bytes .../source/xMasterX/dice/assets/ui_count.png | Bin 0 -> 182 bytes .../xMasterX/dice/assets/ui_count_1.png | Bin 0 -> 180 bytes .../xMasterX/dice/assets/ui_result_1.png | Bin 0 -> 126 bytes .../xMasterX/dice/assets/ui_result_2.png | Bin 0 -> 126 bytes .../xMasterX/dice/assets/ui_result_3.png | Bin 0 -> 129 bytes .../DEV_FW/source/xMasterX/dice/constants.h | 116 + .../DEV_FW/source/xMasterX/dice/dice_app.c | 267 + .../DEV_FW/source/xMasterX/dice/icon.png | Bin 0 -> 128 bytes .../source/xMasterX/dice/sources/coin.pixil | 1 + .../source/xMasterX/dice/sources/d10.pixil | 1 + .../source/xMasterX/dice/sources/d100.pixil | 1 + .../source/xMasterX/dice/sources/d12.pixil | 1 + .../source/xMasterX/dice/sources/d20.pixil | 1 + .../source/xMasterX/dice/sources/d6.pixil | 1 + .../source/xMasterX/dice/sources/d8.pixil | 1 + .../xMasterX/dice/sources/flipper-screen.png | Bin 0 -> 30526 bytes .../xMasterX/dice/sources/main-screen.png | Bin 0 -> 2583 bytes .../xMasterX/dice/sources/roll-screen.png | Bin 0 -> 2375 bytes .../source/xMasterX/etch-a-sketch/LICENSE | 674 ++ .../source/xMasterX/etch-a-sketch/README.md | 13 + .../xMasterX/etch-a-sketch/Screenshot.png | Bin 0 -> 1769 bytes .../xMasterX/etch-a-sketch/application.fam | 12 + .../etch-a-sketch/assets/125_10px.png | Bin 0 -> 308 bytes .../assets/ActiveConnection_50x64.png | Bin 0 -> 3842 bytes .../etch-a-sketch/assets/Alert_9x8.png | Bin 0 -> 3611 bytes .../etch-a-sketch/assets/ArrowC_1_36x36.png | Bin 0 -> 3692 bytes .../assets/ArrowDownEmpty_14x15.png | Bin 0 -> 654 bytes .../assets/ArrowDownFilled_14x15.png | Bin 0 -> 669 bytes .../assets/ArrowUpEmpty_14x15.png | Bin 0 -> 3616 bytes .../assets/ArrowUpFilled_14x15.png | Bin 0 -> 3628 bytes .../etch-a-sketch/assets/Attention_5x8.png | Bin 0 -> 1690 bytes .../etch-a-sketch/assets/Auth_62x31.png | Bin 0 -> 3761 bytes .../assets/BLE_Pairing_128x64.png | Bin 0 -> 2307 bytes .../assets/Background_128x11.png | Bin 0 -> 410 bytes .../assets/BatteryBody_52x28.png | Bin 0 -> 327 bytes .../etch-a-sketch/assets/Battery_16x16.png | Bin 0 -> 281 bytes .../etch-a-sketch/assets/Battery_26x8.png | Bin 0 -> 313 bytes .../assets/Ble_connected_15x15.png | Bin 0 -> 3634 bytes .../assets/Ble_disconnected_15x15.png | Bin 0 -> 3632 bytes .../assets/Bluetooth_Connected_16x8.png | Bin 0 -> 3613 bytes .../assets/Bluetooth_Idle_5x8.png | Bin 0 -> 79 bytes .../etch-a-sketch/assets/ButtonCenter_7x7.png | Bin 0 -> 1440 bytes .../etch-a-sketch/assets/ButtonDown_7x4.png | Bin 0 -> 102 bytes .../assets/ButtonLeftSmall_3x5.png | Bin 0 -> 1741 bytes .../etch-a-sketch/assets/ButtonLeft_4x7.png | Bin 0 -> 1415 bytes .../assets/ButtonRightSmall_3x5.png | Bin 0 -> 1738 bytes .../etch-a-sketch/assets/ButtonRight_4x7.png | Bin 0 -> 1839 bytes .../etch-a-sketch/assets/ButtonUp_7x4.png | Bin 0 -> 102 bytes .../etch-a-sketch/assets/Button_18x18.png | Bin 0 -> 3609 bytes .../assets/Certification1_103x56.png | Bin 0 -> 3038 bytes .../assets/Certification2_98x33.png | Bin 0 -> 2495 bytes .../assets/Charging-lightning_9x10.png | Bin 0 -> 3674 bytes .../assets/Charging-lightning_mask_9x10.png | Bin 0 -> 10182 bytes .../etch-a-sketch/assets/Circles_47x47.png | Bin 0 -> 3712 bytes .../etch-a-sketch/assets/Clock_18x18.png | Bin 0 -> 1083 bytes .../etch-a-sketch/assets/Connect_me_62x31.png | Bin 0 -> 3767 bytes .../etch-a-sketch/assets/Connected_62x31.png | Bin 0 -> 3765 bytes .../etch-a-sketch/assets/CoolHi_25x27.png | Bin 0 -> 3680 bytes .../etch-a-sketch/assets/CoolHi_hvr_25x27.png | Bin 0 -> 3669 bytes .../etch-a-sketch/assets/CoolLo_25x27.png | Bin 0 -> 3676 bytes .../etch-a-sketch/assets/CoolLo_hvr_25x27.png | Bin 0 -> 3657 bytes .../etch-a-sketch/assets/Cry_dolph_55x52.png | Bin 0 -> 3898 bytes .../etch-a-sketch/assets/DFU_128x50.png | Bin 0 -> 3177 bytes .../etch-a-sketch/assets/Dehumidify_25x27.png | Bin 0 -> 3665 bytes .../assets/Dehumidify_hvr_25x27.png | Bin 0 -> 3652 bytes .../assets/Detailed_chip_17x13.png | Bin 0 -> 981 bytes .../assets/DolphinCommon_56x48.png | Bin 0 -> 1416 bytes .../assets/DolphinMafia_115x62.png | Bin 0 -> 2504 bytes .../assets/DolphinNice_96x59.png | Bin 0 -> 2459 bytes .../assets/DolphinReadingSuccess_59x63.png | Bin 0 -> 1177 bytes .../assets/DolphinWait_61x59.png | Bin 0 -> 2023 bytes .../etch-a-sketch/assets/DoorLeft_70x55.png | Bin 0 -> 564 bytes .../etch-a-sketch/assets/DoorRight_70x55.png | Bin 0 -> 570 bytes .../etch-a-sketch/assets/Down_25x27.png | Bin 0 -> 3650 bytes .../etch-a-sketch/assets/Down_hvr_25x27.png | Bin 0 -> 3629 bytes .../etch-a-sketch/assets/Drive_112x35.png | Bin 0 -> 3695 bytes .../etch-a-sketch/assets/Error_18x18.png | Bin 0 -> 1083 bytes .../etch-a-sketch/assets/Error_62x31.png | Bin 0 -> 3751 bytes .../etch-a-sketch/assets/EviSmile1_18x21.png | Bin 0 -> 3645 bytes .../etch-a-sketch/assets/EviSmile2_18x21.png | Bin 0 -> 3649 bytes .../assets/EviWaiting1_18x21.png | Bin 0 -> 13020 bytes .../assets/EviWaiting2_18x21.png | Bin 0 -> 12913 bytes .../assets/FaceCharging_29x14.png | Bin 0 -> 308 bytes .../assets/FaceConfused_29x14.png | Bin 0 -> 317 bytes .../assets/FaceNopower_29x14.png | Bin 0 -> 302 bytes .../etch-a-sketch/assets/FaceNormal_29x14.png | Bin 0 -> 295 bytes .../etch-a-sketch/assets/GameMode_11x8.png | Bin 0 -> 3610 bytes .../etch-a-sketch/assets/Health_16x16.png | Bin 0 -> 282 bytes .../etch-a-sketch/assets/HeatHi_25x27.png | Bin 0 -> 3676 bytes .../etch-a-sketch/assets/HeatHi_hvr_25x27.png | Bin 0 -> 3661 bytes .../etch-a-sketch/assets/HeatLo_25x27.png | Bin 0 -> 3670 bytes .../etch-a-sketch/assets/HeatLo_hvr_25x27.png | Bin 0 -> 3655 bytes .../assets/Hidden_window_9x8.png | Bin 0 -> 3604 bytes .../assets/InfraredArrowDown_4x8.png | Bin 0 -> 3589 bytes .../assets/InfraredArrowUp_4x8.png | Bin 0 -> 3592 bytes .../assets/InfraredLearnShort_128x31.png | Bin 0 -> 3952 bytes .../assets/KeyBackspaceSelected_16x9.png | Bin 0 -> 1812 bytes .../assets/KeyBackspace_16x9.png | Bin 0 -> 1829 bytes .../assets/KeySaveSelected_24x11.png | Bin 0 -> 1853 bytes .../etch-a-sketch/assets/KeySave_24x11.png | Bin 0 -> 1863 bytes .../etch-a-sketch/assets/Keychain_39x36.png | Bin 0 -> 3775 bytes .../assets/Left_mouse_icon_9x9.png | Bin 0 -> 3622 bytes .../etch-a-sketch/assets/Lock_7x8.png | Bin 0 -> 3597 bytes .../etch-a-sketch/assets/Lock_8x8.png | Bin 0 -> 303 bytes .../etch-a-sketch/assets/MHz_25x11.png | Bin 0 -> 1660 bytes .../assets/Medium-chip-22x21.png | Bin 0 -> 3740 bytes .../assets/Modern_reader_18x34.png | Bin 0 -> 3670 bytes .../assets/Move_flipper_26x39.png | Bin 0 -> 3698 bytes .../etch-a-sketch/assets/Mute_25x27.png | Bin 0 -> 3670 bytes .../etch-a-sketch/assets/Mute_hvr_25x27.png | Bin 0 -> 3657 bytes .../etch-a-sketch/assets/NFC_manual_60x50.png | Bin 0 -> 3804 bytes .../etch-a-sketch/assets/Nfc_10px.png | Bin 0 -> 304 bytes .../etch-a-sketch/assets/Off_25x27.png | Bin 0 -> 9530 bytes .../etch-a-sketch/assets/Off_hvr_25x27.png | Bin 0 -> 8460 bytes .../etch-a-sketch/assets/Ok_btn_9x9.png | Bin 0 -> 3605 bytes .../assets/Ok_btn_pressed_13x13.png | Bin 0 -> 3625 bytes .../etch-a-sketch/assets/Percent_10x14.png | Bin 0 -> 3624 bytes .../assets/Pin_arrow_down_7x9.png | Bin 0 -> 3607 bytes .../assets/Pin_arrow_left_9x7.png | Bin 0 -> 3603 bytes .../assets/Pin_arrow_right_9x7.png | Bin 0 -> 3602 bytes .../etch-a-sketch/assets/Pin_arrow_up_7x9.png | Bin 0 -> 3603 bytes .../assets/Pin_attention_dpad_29x29.png | Bin 0 -> 3688 bytes .../assets/Pin_back_arrow_10x8.png | Bin 0 -> 3606 bytes .../assets/Pin_back_full_40x8.png | Bin 0 -> 3641 bytes .../etch-a-sketch/assets/Pin_pointer_5x3.png | Bin 0 -> 3592 bytes .../etch-a-sketch/assets/Pin_star_7x7.png | Bin 0 -> 3600 bytes .../etch-a-sketch/assets/Power_25x27.png | Bin 0 -> 3669 bytes .../etch-a-sketch/assets/Power_hvr_25x27.png | Bin 0 -> 3651 bytes .../assets/Pressed_Button_13x13.png | Bin 0 -> 3606 bytes .../etch-a-sketch/assets/Quest_7x8.png | Bin 0 -> 3675 bytes .../assets/RFIDBigChip_37x36.png | Bin 0 -> 2372 bytes .../assets/RFIDDolphinReceive_97x61.png | Bin 0 -> 1421 bytes .../assets/RFIDDolphinSend_97x61.png | Bin 0 -> 1418 bytes .../assets/RFIDDolphinSuccess_108x57.png | Bin 0 -> 2681 bytes .../assets/Reader_detect_43x40.png | Bin 0 -> 3799 bytes .../assets/Release_arrow_18x15.png | Bin 0 -> 3631 bytes .../etch-a-sketch/assets/Restoring_38x32.png | Bin 0 -> 3794 bytes .../assets/Right_mouse_icon_9x9.png | Bin 0 -> 3622 bytes .../etch-a-sketch/assets/SDQuestion_35x43.png | Bin 0 -> 1950 bytes .../etch-a-sketch/assets/SDcardFail_11x8.png | Bin 0 -> 81 bytes .../assets/SDcardMounted_11x8.png | Bin 0 -> 74 bytes .../etch-a-sketch/assets/Scanning_123x52.png | Bin 0 -> 1690 bytes .../assets/SmallArrowDown_3x5.png | Bin 0 -> 3592 bytes .../assets/SmallArrowDown_4x7.png | Bin 0 -> 8340 bytes .../etch-a-sketch/assets/SmallArrowUp_3x5.png | Bin 0 -> 7976 bytes .../etch-a-sketch/assets/SmallArrowUp_4x7.png | Bin 0 -> 8552 bytes .../etch-a-sketch/assets/Smile_18x18.png | Bin 0 -> 1080 bytes .../etch-a-sketch/assets/Space_65x18.png | Bin 0 -> 3619 bytes .../etch-a-sketch/assets/Tap_reader_36x38.png | Bin 0 -> 3748 bytes .../assets/Temperature_16x16.png | Bin 0 -> 283 bytes .../etch-a-sketch/assets/Unlock_7x8.png | Bin 0 -> 3598 bytes .../assets/Unplug_bg_bottom_128x10.png | Bin 0 -> 5355 bytes .../assets/Unplug_bg_top_128x14.png | Bin 0 -> 5945 bytes .../etch-a-sketch/assets/Up_25x27.png | Bin 0 -> 3650 bytes .../etch-a-sketch/assets/Up_hvr_25x27.png | Bin 0 -> 3630 bytes .../etch-a-sketch/assets/Updating_32x40.png | Bin 0 -> 3704 bytes .../etch-a-sketch/assets/UsbTree_48x22.png | Bin 0 -> 3653 bytes .../etch-a-sketch/assets/Vol_down_25x27.png | Bin 0 -> 3622 bytes .../assets/Vol_down_hvr_25x27.png | Bin 0 -> 3611 bytes .../etch-a-sketch/assets/Vol_up_25x27.png | Bin 0 -> 3628 bytes .../etch-a-sketch/assets/Vol_up_hvr_25x27.png | Bin 0 -> 3617 bytes .../etch-a-sketch/assets/Voldwn_6x6.png | Bin 0 -> 3593 bytes .../etch-a-sketch/assets/Voltage_16x16.png | Bin 0 -> 294 bytes .../etch-a-sketch/assets/Volup_8x6.png | Bin 0 -> 3595 bytes .../assets/WarningDolphin_45x42.png | Bin 0 -> 1139 bytes .../etch-a-sketch/assets/Warning_30x23.png | Bin 0 -> 347 bytes .../assets/_FaceNormal_29x14.png | Bin 0 -> 295 bytes .../etch-a-sketch/assets/back_10px.png | Bin 0 -> 154 bytes .../etch-a-sketch/assets/badusb_10px.png | Bin 0 -> 576 bytes .../etch-a-sketch/assets/dir_10px.png | Bin 0 -> 311 bytes .../iButtonDolphinVerySuccess_108x52.png | Bin 0 -> 2157 bytes .../etch-a-sketch/assets/iButtonKey_49x44.png | Bin 0 -> 1970 bytes .../etch-a-sketch/assets/ibutt_10px.png | Bin 0 -> 304 bytes .../xMasterX/etch-a-sketch/assets/ir_10px.png | Bin 0 -> 305 bytes .../etch-a-sketch/assets/loading_10px.png | Bin 0 -> 4349 bytes .../etch-a-sketch/assets/music_10px.png | Bin 0 -> 142 bytes .../assets/passport_bad1_46x49.png | Bin 0 -> 1237 bytes .../assets/passport_bad2_46x49.png | Bin 0 -> 1295 bytes .../assets/passport_bad3_46x49.png | Bin 0 -> 1304 bytes .../assets/passport_bottom_128x18.png | Bin 0 -> 1149 bytes .../assets/passport_happy1_46x49.png | Bin 0 -> 1296 bytes .../assets/passport_happy2_46x49.png | Bin 0 -> 1328 bytes .../assets/passport_happy3_46x49.png | Bin 0 -> 1348 bytes .../assets/passport_left_6x46.png | Bin 0 -> 1083 bytes .../assets/passport_okay1_46x49.png | Bin 0 -> 1244 bytes .../assets/passport_okay2_46x49.png | Bin 0 -> 1281 bytes .../assets/passport_okay3_46x49.png | Bin 0 -> 1304 bytes .../etch-a-sketch/assets/sub1_10px.png | Bin 0 -> 299 bytes .../etch-a-sketch/assets/u2f_10px.png | Bin 0 -> 583 bytes .../etch-a-sketch/assets/unknown_10px.png | Bin 0 -> 312 bytes .../etch-a-sketch/assets/update_10px.png | Bin 0 -> 156 bytes .../etch-a-sketch/etch-a-sketch-icon.png | Bin 0 -> 239 bytes .../xMasterX/etch-a-sketch/etch-a-sketch.c | 271 + .../etch-a-sketch/etch-a-sketch_icons.c | 4324 ++++++++++ .../source/xMasterX/flipp_pomodoro/LICENSE.md | 21 + .../source/xMasterX/flipp_pomodoro/README.md | 36 + .../xMasterX/flipp_pomodoro/application.fam | 11 + .../flipp_pomodoro/flipp_pomodoro_10.png | Bin 0 -> 157 bytes .../flipp_pomodoro/flipp_pomodoro_app.c | 101 + .../flipp_pomodoro/flipp_pomodoro_app.h | 34 + .../flipp_pomodoro/flipp_pomodoro_app_i.h | 31 + .../xMasterX/flipp_pomodoro/helpers/debug.h | 5 + .../flipp_pomodoro/helpers/notifications.c | 49 + .../flipp_pomodoro/helpers/notifications.h | 13 + .../xMasterX/flipp_pomodoro/helpers/time.c | 21 + .../xMasterX/flipp_pomodoro/helpers/time.h | 25 + .../images/flipp_pomodoro_rest_64.png | Bin 0 -> 1083 bytes .../images/flipp_pomodoro_work_64.png | Bin 0 -> 1215 bytes .../flipp_pomodoro/modules/flipp_pomodoro.c | 72 + .../flipp_pomodoro/modules/flipp_pomodoro.h | 45 + .../xMasterX/flipp_pomodoro/scenes/.keep | 0 .../config/flipp_pomodoro_scene_config.h | 1 + .../scenes/flipp_pomodoro_scene.c | 30 + .../scenes/flipp_pomodoro_scene.h | 28 + .../scenes/flipp_pomodoro_scene_timer.c | 75 + .../xMasterX/flipp_pomodoro/views/.keep | 0 .../views/flipp_pomodoro_timer_view.c | 151 + .../views/flipp_pomodoro_timer_view.h | 18 + .../source/xMasterX/flipper-asteroids/LICENSE | 24 + .../xMasterX/flipper-asteroids/README.md | 60 + .../source/xMasterX/flipper-asteroids/app.c | 789 ++ .../xMasterX/flipper-asteroids/appicon.png | Bin 0 -> 145 bytes .../flipper-asteroids/application.fam | 12 + .../flipper-asteroids/images/Asteroids.jpg | Bin 0 -> 18158 bytes .../source/xMasterX/flipper-bp/README.md | 3 + .../xMasterX/flipper-bp/application.fam | 13 + .../DEV_FW/source/xMasterX/flipper-bp/fbp.c | 103 + .../DEV_FW/source/xMasterX/flipper-bp/fbp.h | 38 + .../DEV_FW/source/xMasterX/flipper-bp/tcode.c | 183 + .../DEV_FW/source/xMasterX/flipper-bp/tcode.h | 63 + .../source/xMasterX/flipper-bp/uart_10px.png | Bin 0 -> 1883 bytes .../flipper-bp/views/gpio_simple_motor.c | 149 + .../flipper-bp/views/gpio_simple_motor.h | 13 + .../xMasterX/flipper-bp/views/internal.c | 133 + .../xMasterX/flipper-bp/views/internal.h | 12 + .../source/xMasterX/flipper-dcf77/.gitignore | 52 + .../source/xMasterX/flipper-dcf77/LICENSE.txt | 674 ++ .../source/xMasterX/flipper-dcf77/README.md | 22 + .../xMasterX/flipper-dcf77/application.fam | 12 + .../source/xMasterX/flipper-dcf77/dcf77_app.c | 445 ++ .../source/xMasterX/flipper-dcf77/dcf77_app.h | 168 + .../xMasterX/flipper-dcf77/dcf77_util.c | 135 + .../xMasterX/flipper-dcf77/dcf77_util.h | 18 + .../xMasterX/flipper-dcf77/icons/app.png | Bin 0 -> 226 bytes .../xMasterX/flipper-flashlight/LICENSE | 21 + .../xMasterX/flipper-flashlight/README.md | 7 + .../flipper-flashlight/application.fam | 14 + .../xMasterX/flipper-flashlight/flash10px.png | Bin 0 -> 148 bytes .../xMasterX/flipper-flashlight/flashlight.c | 130 + .../xMasterX/flipper_analog_clock/README.md | 1 + .../flipper_analog_clock/analog_clock.c | 154 + .../flipper_analog_clock/analog_clock.png | Bin 0 -> 7920 bytes .../flipper_analog_clock/application.fam | 17 + .../source/xMasterX/flipper_geiger/README.md | 64 + .../xMasterX/flipper_geiger/application.fam | 13 + .../xMasterX/flipper_geiger/flipper_geiger.c | 190 + .../source/xMasterX/flipper_geiger/geiger.png | Bin 0 -> 8048 bytes .../xMasterX/flipper_geiger/img/flipper1.png | Bin 0 -> 2005 bytes .../xMasterX/flipper_geiger/img/flipper2.png | Bin 0 -> 1246 bytes .../xMasterX/flipper_geiger/img/flipper3.png | Bin 0 -> 1376 bytes .../xMasterX/flipper_geiger/img/flipper4.png | Bin 0 -> 1420 bytes .../xMasterX/flipper_geiger/img/flipper5.png | Bin 0 -> 1480 bytes .../xMasterX/flipper_geiger/img/flipper6.png | Bin 0 -> 1560 bytes .../xMasterX/flipper_geiger/img/logo.jpg | Bin 0 -> 351585 bytes .../xMasterX/flipper_geiger/img/schematic.jpg | Bin 0 -> 370586 bytes .../xMasterX/flipper_passgen/.clang-format | 191 + .../xMasterX/flipper_passgen/.editorconfig | 13 + .../xMasterX/flipper_passgen/.gitignore | 54 + .../source/xMasterX/flipper_passgen/LICENSE | 21 + .../source/xMasterX/flipper_passgen/README.md | 4 + .../xMasterX/flipper_passgen/application.fam | 12 + .../icons/Horizontal_arrow_9x7.png | Bin 0 -> 1479 bytes .../flipper_passgen/icons/Ok_btn_9x9.png | Bin 0 -> 3605 bytes .../icons/Pin_back_arrow_10x8.png | Bin 0 -> 3606 bytes .../icons/Vertical_arrow_7x9.png | Bin 0 -> 1482 bytes .../flipper_passgen/icons/passgen_icon.png | Bin 0 -> 173 bytes .../flipper_passgen/images/preview.png | Bin 0 -> 980 bytes .../source/xMasterX/flipper_passgen/passgen.c | 202 + .../source/xMasterX/flipper_pong/README.md | 23 + .../xMasterX/flipper_pong/application.fam | 13 + .../xMasterX/flipper_pong/flipper_pong.c | 293 + .../flipper_pong/img/Flipper_Zero.jpg | Bin 0 -> 44250 bytes .../xMasterX/flipper_pong/img/flipper1.png | Bin 0 -> 1935 bytes .../xMasterX/flipper_pong/img/flipper2.png | Bin 0 -> 1574 bytes .../xMasterX/flipper_pong/img/flipper3.png | Bin 0 -> 1615 bytes .../source/xMasterX/flipper_pong/pong.png | Bin 0 -> 6459 bytes .../.github/workflows/release.yml | 30 + .../xMasterX/flipperzero-qrcode/.gitignore | 52 + .../xMasterX/flipperzero-qrcode/LICENSE | 21 + .../xMasterX/flipperzero-qrcode/README.md | 156 + .../flipperzero-qrcode/application.fam | 19 + .../flipperzero-qrcode/icons/qrcode_10px.png | Bin 0 -> 1758 bytes .../xMasterX/flipperzero-qrcode/qrcode.c | 858 ++ .../xMasterX/flipperzero-qrcode/qrcode.h | 100 + .../xMasterX/flipperzero-qrcode/qrcode_app.c | 586 ++ .../scripts/check-firmware.sh | 26 + .../scripts/update-firmware.sh | 43 + .../xMasterX/flipperzero-tuning-fork/LICENSE | 674 ++ .../flipperzero-tuning-fork/README.md | 30 + .../flipperzero-tuning-fork/application.fam | 14 + .../img/screenshot_1.png | Bin 0 -> 1638 bytes .../img/screenshot_2.png | Bin 0 -> 1874 bytes .../img/tuning_fork.gif | Bin 0 -> 90811 bytes .../xMasterX/flipperzero-tuning-fork/notes.h | 158 + .../flipperzero-tuning-fork/tuning_fork.c | 408 + .../tuning_fork_icon.png | Bin 0 -> 1187 bytes .../flipperzero-tuning-fork/tunings.h | 151 + .../flipperzero-yatzee-main/.gitignore | 52 + .../xMasterX/flipperzero-yatzee-main/LICENSE | 674 ++ .../flipperzero-yatzee-main/README.md | 48 + .../flipperzero-yatzee-main/application.fam | 13 + .../flipperzero-yatzee-main/images/die_1.png | Bin 0 -> 1252 bytes .../flipperzero-yatzee-main/images/die_2.png | Bin 0 -> 1271 bytes .../flipperzero-yatzee-main/images/die_3.png | Bin 0 -> 1284 bytes .../flipperzero-yatzee-main/images/die_4.png | Bin 0 -> 1271 bytes .../flipperzero-yatzee-main/images/die_5.png | Bin 0 -> 1290 bytes .../flipperzero-yatzee-main/images/die_6.png | Bin 0 -> 1274 bytes .../images/yatzee_icon_10px.png | Bin 0 -> 1250 bytes .../xMasterX/flipperzero-yatzee-main/yatzee.c | 780 ++ .../flipperzero_GPIO_read-main/GPIO_reader.c | 129 + .../GPIO_reader_item.c | 26 + .../GPIO_reader_item.h | 42 + .../flipperzero_GPIO_read-main/README.md | 3 + .../application.fam | 11 + .../flipperzero_GPIO_read-main/icon.png | Bin 0 -> 135 bytes .../xMasterX/flipperzero_gpioreader/LICENSE | 674 ++ .../xMasterX/flipperzero_gpioreader/README.md | 16 + .../flipperzero_gpioreader/application.fam | 13 + .../flipperzero_gpioreader/gpio_app.c | 111 + .../flipperzero_gpioreader/gpio_app.h | 11 + .../flipperzero_gpioreader/gpio_app_i.h | 44 + .../gpio_custom_event.h | 14 + .../flipperzero_gpioreader/gpio_item.c | 60 + .../flipperzero_gpioreader/gpio_item.h | 17 + .../flipperzero_gpioreader/gpioreader.png | Bin 0 -> 1919 bytes .../xMasterX/flipperzero_gpioreader/icon.png | Bin 0 -> 135 bytes .../scenes/gpio_scene.c | 30 + .../scenes/gpio_scene.h | 29 + .../scenes/gpio_scene_config.h | 6 + .../scenes/gpio_scene_reader.c | 30 + .../scenes/gpio_scene_start.c | 114 + .../scenes/gpio_scene_test.c | 30 + .../scenes/gpio_scene_usb_uart.c | 67 + .../scenes/gpio_scene_usb_uart_close_rpc.c | 41 + .../scenes/gpio_scene_usb_uart_config.c | 169 + .../flipperzero_gpioreader/usb_uart_bridge.c | 375 + .../flipperzero_gpioreader/usb_uart_bridge.h | 30 + .../views/gpio_reader.c | 164 + .../views/gpio_reader.h | 14 + .../flipperzero_gpioreader/views/gpio_test.c | 139 + .../flipperzero_gpioreader/views/gpio_test.h | 14 + .../views/gpio_usb_uart.c | 161 + .../views/gpio_usb_uart.h | 18 + .../.github/FUNDING.yml | 1 + .../.github/workflows/build-fap.yml | 12 + .../xMasterX/flipperzero_vb_migrate/LICENSE | 674 ++ .../xMasterX/flipperzero_vb_migrate/README.md | 170 + .../flipperzero_vb_migrate/application.fam | 34 + .../gui/modules/file_select.c | 481 ++ .../gui/modules/file_select.h | 31 + .../gui/modules/variable_item_list_ex.c | 419 + .../gui/modules/variable_item_list_ex.h | 117 + .../icons/AppInteract_32x27.png | Bin 0 -> 777 bytes .../icons/Background_128x64.png | Bin 0 -> 10987 bytes .../icons/CommComplete_32x20.png | Bin 0 -> 757 bytes .../icons/CommReady_32x27.png | Bin 0 -> 783 bytes .../icons/CommReturn_10x8.png | Bin 0 -> 592 bytes .../icons/CommVB_32x20.png | Bin 0 -> 757 bytes .../icons/CommWave_12x8.png | Bin 0 -> 604 bytes .../icons/Comm_32x20.png | Bin 0 -> 709 bytes .../icons/Delete_32x20.png | Bin 0 -> 742 bytes .../icons/LeftButtonBg_54x15.png | Bin 0 -> 5903 bytes .../icons/PulsemonLeftStand_14x16.png | Bin 0 -> 658 bytes .../icons/PulsemonLeftWait_15x15.png | Bin 0 -> 656 bytes .../icons/PulsemonRightHappy_14x16.png | Bin 0 -> 660 bytes .../icons/PulsemonRightSad_15x15.png | Bin 0 -> 660 bytes .../icons/PulsemonRightWaiting_15x16.png | Bin 0 -> 666 bytes .../icons/RightButtonBg_54x15.png | Bin 0 -> 622 bytes .../icons/TextClearCaptures_49x13.png | Bin 0 -> 718 bytes .../icons/TextCleared_47x6.png | Bin 0 -> 638 bytes .../icons/TextDeleteVb_49x13.png | Bin 0 -> 715 bytes .../icons/TextDeleted_46x6.png | Bin 0 -> 642 bytes .../icons/TextErrLoadCapture_65x13.png | Bin 0 -> 713 bytes .../icons/TextErrLoadTemplate_69x13.png | Bin 0 -> 733 bytes .../icons/TextErrReadFailed_71x20.png | Bin 0 -> 815 bytes .../TextErrRegisterDifferentTag_47x20.png | Bin 0 -> 765 bytes .../icons/TextErrSaveCapture_65x13.png | Bin 0 -> 727 bytes .../icons/TextRegister1_71x20.png | Bin 0 -> 863 bytes .../icons/TextRegisterErrNotVb_71x20.png | Bin 0 -> 848 bytes .../icons/TextRegisterTapAgain_67x20.png | Bin 0 -> 861 bytes .../icons/TextSaved_30x6.png | Bin 0 -> 623 bytes .../icons/TextTapApp_56x27.png | Bin 0 -> 856 bytes .../icons/TextTransferCaptured_97x13.png | Bin 0 -> 801 bytes .../icons/TextTransferDimCheck_70x20.png | Bin 0 -> 853 bytes .../TextTransferSecondDimCheck_71x20.png | Bin 0 -> 849 bytes .../icons/TextTransfersDone_51x13.png | Bin 0 -> 710 bytes .../icons/WrongDevice_32x27.png | Bin 0 -> 796 bytes .../scenes/vb_migrate_scene.c | 48 + .../scenes/vb_migrate_scene.h | 47 + .../scenes/vb_migrate_scene_about.c | 57 + .../scenes/vb_migrate_scene_config.h | 33 + .../scenes/vb_migrate_scene_delete.c | 78 + .../scenes/vb_migrate_scene_delete_captures.c | 87 + ...vb_migrate_scene_delete_captures_success.c | 68 + .../scenes/vb_migrate_scene_delete_success.c | 65 + .../scenes/vb_migrate_scene_dev_menu.c | 184 + .../scenes/vb_migrate_scene_from_app.c | 370 + .../scenes/vb_migrate_scene_info.c | 85 + .../scenes/vb_migrate_scene_load.c | 61 + .../scenes/vb_migrate_scene_main_menu.c | 78 + .../scenes/vb_migrate_scene_register.c | 420 + .../scenes/vb_migrate_scene_register_save.c | 119 + .../scenes/vb_migrate_scene_save_success.c | 64 + .../scenes/vb_migrate_scene_select.c | 57 + .../scenes/vb_migrate_scene_to_app.c | 297 + .../flipperzero_vb_migrate/vb_migrate.c | 331 + .../flipperzero_vb_migrate/vb_migrate.h | 31 + .../vb_migrate_10px.png | Bin 0 -> 618 bytes .../flipperzero_vb_migrate/vb_migrate_i.h | 107 + .../xMasterX/flipperzero_vb_migrate/vb_tag.c | 235 + .../xMasterX/flipperzero_vb_migrate/vb_tag.h | 77 + .../xMasterX/fpz_cntdown_timer-main/README.md | 11 + .../xMasterX/fpz_cntdown_timer-main/app.c | 71 + .../xMasterX/fpz_cntdown_timer-main/app.h | 22 + .../fpz_cntdown_timer-main/application.fam | 16 + .../fpz_cntdown_timer-main/cntdown_timer.png | Bin 0 -> 306 bytes .../fpz_cntdown_timer-main/utils/utils.c | 34 + .../fpz_cntdown_timer-main/utils/utils.h | 12 + .../views/countdown_view.c | 346 + .../views/countdown_view.h | 59 + .../DEV_FW/source/xMasterX/game2048/2048.png | Bin 0 -> 159 bytes .../source/xMasterX/game2048/application.fam | 12 + .../DEV_FW/source/xMasterX/game2048/font.c | 155 + .../DEV_FW/source/xMasterX/game2048/font.h | 3 + .../source/xMasterX/game2048/game_2048.c | 494 ++ .../xMasterX/game_of_life/application.fam | 12 + .../xMasterX/game_of_life/game_of_life.c | 160 + .../source/xMasterX/game_of_life/golIcon.png | Bin 0 -> 1921 bytes .../source/xMasterX/ifttt/application.fam | 14 + .../DEV_FW/source/xMasterX/ifttt/icon.png | Bin 0 -> 1762 bytes .../xMasterX/ifttt/ifttt_virtual_button.c | 251 + .../xMasterX/ifttt/ifttt_virtual_button.h | 56 + .../ifttt/scenes/virtual_button_scene.c | 30 + .../ifttt/scenes/virtual_button_scene.h | 29 + .../ifttt/scenes/virtual_button_scene_about.c | 26 + .../scenes/virtual_button_scene_config.h | 3 + .../ifttt/scenes/virtual_button_scene_send.c | 26 + .../ifttt/scenes/virtual_button_scene_start.c | 55 + .../source/xMasterX/ifttt/views/about_view.c | 48 + .../source/xMasterX/ifttt/views/about_view.h | 11 + .../source/xMasterX/ifttt/views/send_view.c | 137 + .../source/xMasterX/ifttt/views/send_view.h | 11 + .../source/xMasterX/ir_remote/README.md | 63 + .../source/xMasterX/ir_remote/application.fam | 14 + .../source/xMasterX/ir_remote/example.txt | 12 + .../ir_remote/images/ButtonDown_7x4.png | Bin 0 -> 102 bytes .../ir_remote/images/ButtonLeft_4x7.png | Bin 0 -> 1415 bytes .../ir_remote/images/ButtonRight_4x7.png | Bin 0 -> 1839 bytes .../ir_remote/images/ButtonUp_7x4.png | Bin 0 -> 102 bytes .../xMasterX/ir_remote/images/Ok_btn_9x9.png | Bin 0 -> 3605 bytes .../xMasterX/ir_remote/images/back_10px.png | Bin 0 -> 154 bytes .../xMasterX/ir_remote/images/sub1_10px.png | Bin 0 -> 299 bytes .../xMasterX/ir_remote/infrared_remote.c | 188 + .../xMasterX/ir_remote/infrared_remote.h | 29 + .../xMasterX/ir_remote/infrared_remote_app.c | 532 ++ .../ir_remote/infrared_remote_button.c | 37 + .../ir_remote/infrared_remote_button.h | 14 + .../xMasterX/ir_remote/infrared_signal.c | 300 + .../xMasterX/ir_remote/infrared_signal.h | 45 + .../DEV_FW/source/xMasterX/ir_remote/ir.png | Bin 0 -> 1514 bytes .../DEV_FW/source/xMasterX/ir_remote/ir2.png | Bin 0 -> 3109 bytes .../source/xMasterX/ir_remote/ir_10px.png | Bin 0 -> 305 bytes .../source/xMasterX/mandelbrot/Mandelbrot.png | Bin 0 -> 1918 bytes .../xMasterX/mandelbrot/application.fam | 12 + .../source/xMasterX/mandelbrot/mandelbrot.c | 172 + .../source/xMasterX/montyhall/Monty.png | Bin 0 -> 1912 bytes .../source/xMasterX/montyhall/application.fam | 12 + .../source/xMasterX/montyhall/monteyhall.c | 450 ++ .../xMasterX/music_beeper/application.fam | 25 + .../music_beeper/icons/music_10px.png | Bin 0 -> 142 bytes .../xMasterX/music_beeper/music_10px.png | Bin 0 -> 142 bytes .../xMasterX/music_beeper/music_beeper.c | 367 + .../xMasterX/music_beeper/music_beeper_cli.c | 48 + .../music_beeper/music_beeper_worker.c | 510 ++ .../music_beeper/music_beeper_worker.h | 46 + .../.github/workflows/build_dev.yml | 19 + .../source/xMasterX/musictracker/README.md | 4 + .../xMasterX/musictracker/application.fam | 14 + .../xMasterX/musictracker/icons/.gitignore | 0 .../musictracker/tracker_engine/speaker_hal.c | 107 + .../musictracker/tracker_engine/speaker_hal.h | 19 + .../musictracker/tracker_engine/tracker.c | 441 + .../musictracker/tracker_engine/tracker.h | 38 + .../tracker_engine/tracker_notes.h | 64 + .../tracker_engine/tracker_song.h | 109 + .../xMasterX/musictracker/view/tracker_view.c | 182 + .../xMasterX/musictracker/view/tracker_view.h | 29 + .../xMasterX/musictracker/zero_tracker.c | 536 ++ .../xMasterX/musictracker/zero_tracker.h | 0 .../xMasterX/musictracker/zero_tracker.png | Bin 0 -> 136 bytes .../nrf24scan/Distr/Nrf24_Scanner.fap | Bin 0 -> 27120 bytes .../nrf24scan/Distr/nrf24scan/addr-WCO1.txt | 7 + .../nrf24scan/Distr/nrf24scan/addresses.txt | 11 + .../nrf24scan/Distr/nrf24scan/sniff.txt | 5 + .../DEV_FW/source/xMasterX/nrf24scan/LICENSE | 674 ++ .../source/xMasterX/nrf24scan/README.md | 110 + .../xMasterX/nrf24scan/Screenshot-1.png | Bin 0 -> 2347 bytes .../xMasterX/nrf24scan/Screenshot-2.png | Bin 0 -> 3275 bytes .../xMasterX/nrf24scan/Screenshot-3.png | Bin 0 -> 2064 bytes .../xMasterX/nrf24scan/Screenshot-4.png | Bin 0 -> 1664 bytes .../xMasterX/nrf24scan/Screenshot-5.png | Bin 0 -> 7483 bytes .../xMasterX/nrf24scan/Screenshot-6.png | Bin 0 -> 3226 bytes .../xMasterX/nrf24scan/Screenshot-7.png | Bin 0 -> 1959 bytes .../source/xMasterX/nrf24scan/application.fam | 20 + .../xMasterX/nrf24scan/lib/nrf24/nrf24.c | 533 ++ .../xMasterX/nrf24scan/lib/nrf24/nrf24.h | 381 + .../nrf24scan/nrf24_packet_decoder.py | 131 + .../source/xMasterX/nrf24scan/nrf24scan.c | 1387 ++++ .../source/xMasterX/nrf24scan/nrf24scan.h | 42 + .../xMasterX/nrf24scan/nrf24scan_10px.png | Bin 0 -> 1771 bytes .../DEV_FW/source/xMasterX/ocarina/README.md | 4 + .../source/xMasterX/ocarina/application.fam | 13 + .../xMasterX/ocarina/icons/music_10px.png | Bin 0 -> 142 bytes .../source/xMasterX/ocarina/music_10px.png | Bin 0 -> 142 bytes .../DEV_FW/source/xMasterX/ocarina/ocarina.c | 134 + .../source/xMasterX/paint/application.fam | 12 + .../DEV_FW/source/xMasterX/paint/paint.c | 148 + .../source/xMasterX/paint/paintIcon.png | Bin 0 -> 1911 bytes .../DEV_FW/source/xMasterX/pomodoro/LICENSE | 121 + .../DEV_FW/source/xMasterX/pomodoro/README.md | 34 + .../source/xMasterX/pomodoro/application.fam | 15 + .../pomodoro/icons/ButtonLeft_4x7.png | Bin 0 -> 1415 bytes .../xMasterX/pomodoro/icons/Ok_btn_9x9.png | Bin 0 -> 3605 bytes .../pomodoro/icons/Pin_back_arrow_10x8.png | Bin 0 -> 3606 bytes .../xMasterX/pomodoro/icons/Space_65x18.png | Bin 0 -> 3619 bytes .../source/xMasterX/pomodoro/misc/1.png | Bin 0 -> 12663 bytes .../source/xMasterX/pomodoro/misc/2.png | Bin 0 -> 12446 bytes .../source/xMasterX/pomodoro/misc/3.png | Bin 0 -> 12478 bytes .../source/xMasterX/pomodoro/misc/4.png | Bin 0 -> 12896 bytes .../source/xMasterX/pomodoro/misc/5.png | Bin 0 -> 12592 bytes .../source/xMasterX/pomodoro/pomodoro.c | 164 + .../source/xMasterX/pomodoro/pomodoro.h | 34 + .../source/xMasterX/pomodoro/pomodoro_timer.c | 242 + .../source/xMasterX/pomodoro/pomodoro_timer.h | 33 + .../xMasterX/pomodoro/pomodoro_timer.png | Bin 0 -> 306 bytes .../xMasterX/pomodoro/views/pomodoro_10.c | 46 + .../xMasterX/pomodoro/views/pomodoro_10.h | 10 + .../xMasterX/pomodoro/views/pomodoro_25.c | 46 + .../xMasterX/pomodoro/views/pomodoro_25.h | 10 + .../xMasterX/pomodoro/views/pomodoro_50.c | 46 + .../xMasterX/pomodoro/views/pomodoro_50.h | 10 + .../DEV_FW/source/xMasterX/protoview/LICENSE | 24 + .../source/xMasterX/protoview/README.md | 103 + .../DEV_FW/source/xMasterX/protoview/TODO | 20 + .../DEV_FW/source/xMasterX/protoview/app.c | 225 + .../DEV_FW/source/xMasterX/protoview/app.h | 154 + .../source/xMasterX/protoview/app_buffer.c | 73 + .../source/xMasterX/protoview/app_buffer.h | 30 + .../source/xMasterX/protoview/app_subghz.c | 85 + .../source/xMasterX/protoview/appicon.png | Bin 0 -> 116 bytes .../source/xMasterX/protoview/application.fam | 12 + .../xMasterX/protoview/custom_presets.h | 46 + .../protoview/images/ProtoViewSignal.jpg | Bin 0 -> 85828 bytes .../DEV_FW/source/xMasterX/protoview/proto.c | 120 + .../xMasterX/protoview/protocols/b4b1.c | 44 + .../xMasterX/protoview/protocols/oregon2.c | 65 + .../xMasterX/protoview/protocols/oregon2.txt | 6 + .../protoview/protocols/renault_tpms.c | 63 + .../DEV_FW/source/xMasterX/protoview/signal.c | 420 + .../DEV_FW/source/xMasterX/protoview/ui.c | 30 + .../source/xMasterX/protoview/view_info.c | 41 + .../xMasterX/protoview/view_raw_signal.c | 97 + .../source/xMasterX/protoview/view_settings.c | 93 + .../source/xMasterX/rc2014_coleco/.gitignore | 52 + .../source/xMasterX/rc2014_coleco/LICENSE | 674 ++ .../source/xMasterX/rc2014_coleco/README.md | 38 + .../xMasterX/rc2014_coleco/application.fam | 13 + .../source/xMasterX/rc2014_coleco/coleco.c | 366 + .../xMasterX/rc2014_coleco/coleco_10px.png | Bin 0 -> 6667 bytes .../rc2014_coleco/icons/Coleco0_17x17.png | Bin 0 -> 628 bytes .../rc2014_coleco/icons/Coleco0_hvr_17x17.png | Bin 0 -> 627 bytes .../rc2014_coleco/icons/Coleco1_17x17.png | Bin 0 -> 623 bytes .../rc2014_coleco/icons/Coleco1_hvr_17x17.png | Bin 0 -> 618 bytes .../rc2014_coleco/icons/Coleco2_17x17.png | Bin 0 -> 642 bytes .../rc2014_coleco/icons/Coleco2_hvr_17x17.png | Bin 0 -> 643 bytes .../rc2014_coleco/icons/Coleco3_17x17.png | Bin 0 -> 645 bytes .../rc2014_coleco/icons/Coleco3_hvr_17x17.png | Bin 0 -> 640 bytes .../rc2014_coleco/icons/Coleco4_17x17.png | Bin 0 -> 635 bytes .../rc2014_coleco/icons/Coleco4_hvr_17x17.png | Bin 0 -> 627 bytes .../rc2014_coleco/icons/Coleco5_17x17.png | Bin 0 -> 640 bytes .../rc2014_coleco/icons/Coleco5_hvr_17x17.png | Bin 0 -> 633 bytes .../rc2014_coleco/icons/Coleco6_17x17.png | Bin 0 -> 635 bytes .../rc2014_coleco/icons/Coleco6_hvr_17x17.png | Bin 0 -> 634 bytes .../rc2014_coleco/icons/Coleco7_17x17.png | Bin 0 -> 636 bytes .../rc2014_coleco/icons/Coleco7_hvr_17x17.png | Bin 0 -> 628 bytes .../rc2014_coleco/icons/Coleco8_17x17.png | Bin 0 -> 629 bytes .../rc2014_coleco/icons/Coleco8_hvr_17x17.png | Bin 0 -> 625 bytes .../rc2014_coleco/icons/Coleco9_17x17.png | Bin 0 -> 642 bytes .../rc2014_coleco/icons/Coleco9_hvr_17x17.png | Bin 0 -> 639 bytes .../rc2014_coleco/icons/ColecoAlt_18x9.png | Bin 0 -> 5677 bytes .../icons/ColecoAlt_hvr_18x9.png | Bin 0 -> 5037 bytes .../rc2014_coleco/icons/ColecoFire_18x9.png | Bin 0 -> 5660 bytes .../icons/ColecoFire_hvr_18x9.png | Bin 0 -> 5044 bytes .../icons/ColecoFire_sel_18x9.png | Bin 0 -> 6111 bytes .../icons/ColecoJoystick_33x33.png | Bin 0 -> 737 bytes .../icons/ColecoJoystick_hvr_33x33.png | Bin 0 -> 763 bytes .../icons/ColecoJoystick_sel_33x33.png | Bin 0 -> 776 bytes .../rc2014_coleco/icons/ColecoPound_17x17.png | Bin 0 -> 626 bytes .../icons/ColecoPound_hvr_17x17.png | Bin 0 -> 625 bytes .../rc2014_coleco/icons/ColecoStar_17x17.png | Bin 0 -> 638 bytes .../icons/ColecoStar_hvr_17x17.png | Bin 0 -> 632 bytes .../interface/flipper-coleco.brd | 2554 ++++++ .../interface/flipper-coleco.sch | 5482 +++++++++++++ .../source/xMasterX/rc2014_coleco/ui.png | Bin 0 -> 92556 bytes .../source/xMasterX/rgb_led/application.fam | 16 + .../xMasterX/rgb_led/assets/Arr_dwn_7x9.png | Bin 0 -> 3602 bytes .../xMasterX/rgb_led/assets/Arr_up_7x9.png | Bin 0 -> 3605 bytes .../DEV_FW/source/xMasterX/rgb_led/led_ll.c | 316 + .../DEV_FW/source/xMasterX/rgb_led/led_ll.h | 28 + .../DEV_FW/source/xMasterX/rgb_led/rgb_led.c | 118 + .../DEV_FW/source/xMasterX/rgb_led/rgb_led.h | 27 + .../source/xMasterX/rgb_led/rgb_led_10px.png | Bin 0 -> 2378 bytes .../xMasterX/rgb_led/views/rgb_led_default.c | 127 + .../xMasterX/rgb_led/views/rgb_led_default.h | 17 + .../source/xMasterX/rmdice/application.fam | 12 + .../DEV_FW/source/xMasterX/rmdice/dice.c | 575 ++ .../DEV_FW/source/xMasterX/rmdice/dice.png | Bin 0 -> 207 bytes .../xMasterX/rubiks_cube_scrambler/LICENSE | 21 + .../xMasterX/rubiks_cube_scrambler/README.md | 13 + .../rubiks_cube_scrambler/application.fam | 20 + .../xMasterX/rubiks_cube_scrambler/cube.png | Bin 0 -> 96 bytes .../rubiks_cube_scrambler.c | 129 + .../rubiks_cube_scrambler/scrambler.c | 118 + .../rubiks_cube_scrambler/scrambler.h | 3 + .../source/xMasterX/sam/application.fam | 45 + .../source/xMasterX/sam/icons/music_10px.png | Bin 0 -> 142 bytes .../DEV_FW/source/xMasterX/sam/music_10px.png | Bin 0 -> 142 bytes .../DEV_FW/source/xMasterX/sam/sam_app.cpp | 36 + .../DEV_FW/source/xMasterX/sam/stm32_sam.cpp | 5704 +++++++++++++ .../DEV_FW/source/xMasterX/sam/stm32_sam.h | 96 + .../source/xMasterX/scorched_tanks/LICENSE | 674 ++ .../source/xMasterX/scorched_tanks/README.md | 35 + .../xMasterX/scorched_tanks/application.fam | 12 + .../scorched_tanks/scorchedTanks_10px.png | Bin 0 -> 614 bytes .../scorched_tanks/scorched_tanks_game_app.c | 540 ++ .../scorched_tanks/scorched_tanks_v1.gif | Bin 0 -> 139343 bytes .../DEV_FW/source/xMasterX/tama_p1/README.md | 55 + .../source/xMasterX/tama_p1/application.fam | 12 + .../xMasterX/tama_p1/compiled/assets_icons.h | 66 + .../DEV_FW/source/xMasterX/tama_p1/hal.c | 146 + .../source/xMasterX/tama_p1/hal_types.h | 35 + .../source/xMasterX/tama_p1/icons/icon_0.png | Bin 0 -> 641 bytes .../source/xMasterX/tama_p1/icons/icon_1.png | Bin 0 -> 658 bytes .../source/xMasterX/tama_p1/icons/icon_2.png | Bin 0 -> 652 bytes .../source/xMasterX/tama_p1/icons/icon_3.png | Bin 0 -> 656 bytes .../source/xMasterX/tama_p1/icons/icon_4.png | Bin 0 -> 661 bytes .../source/xMasterX/tama_p1/icons/icon_5.png | Bin 0 -> 664 bytes .../source/xMasterX/tama_p1/icons/icon_6.png | Bin 0 -> 640 bytes .../source/xMasterX/tama_p1/icons/icon_7.png | Bin 0 -> 664 bytes .../DEV_FW/source/xMasterX/tama_p1/tama.h | 43 + .../source/xMasterX/tama_p1/tamaIcon.png | Bin 0 -> 1924 bytes .../DEV_FW/source/xMasterX/tama_p1/tama_p1.c | 530 ++ .../source/xMasterX/tama_p1/tamalib/LICENSE | 339 + .../source/xMasterX/tama_p1/tamalib/README.md | 64 + .../source/xMasterX/tama_p1/tamalib/cpu.c | 2033 +++++ .../source/xMasterX/tama_p1/tamalib/cpu.h | 215 + .../source/xMasterX/tama_p1/tamalib/hal.h | 89 + .../tama_p1/tamalib/hal_types.h.template | 32 + .../source/xMasterX/tama_p1/tamalib/hw.c | 134 + .../source/xMasterX/tama_p1/tamalib/hw.h | 50 + .../source/xMasterX/tama_p1/tamalib/tamalib.c | 128 + .../source/xMasterX/tama_p1/tamalib/tamalib.h | 65 + .../source/xMasterX/tanksgame/application.fam | 13 + .../source/xMasterX/tanksgame/constants.h | 19 + .../tanksgame/images/HappyFlipper_128x64.png | Bin 0 -> 633 bytes .../images/TanksSplashScreen_128x64.png | Bin 0 -> 649 bytes .../xMasterX/tanksgame/images/enemy_down.png | Bin 0 -> 157 bytes .../xMasterX/tanksgame/images/enemy_left.png | Bin 0 -> 159 bytes .../xMasterX/tanksgame/images/enemy_right.png | Bin 0 -> 159 bytes .../xMasterX/tanksgame/images/enemy_up.png | Bin 0 -> 160 bytes .../tanksgame/images/projectile_down.png | Bin 0 -> 104 bytes .../tanksgame/images/projectile_left.png | Bin 0 -> 106 bytes .../tanksgame/images/projectile_right.png | Bin 0 -> 108 bytes .../tanksgame/images/projectile_up.png | Bin 0 -> 102 bytes .../xMasterX/tanksgame/images/tank_base.png | Bin 0 -> 3047 bytes .../xMasterX/tanksgame/images/tank_down.png | Bin 0 -> 3040 bytes .../tanksgame/images/tank_explosion.png | Bin 0 -> 3050 bytes .../tanksgame/images/tank_hedgehog.png | Bin 0 -> 3049 bytes .../xMasterX/tanksgame/images/tank_left.png | Bin 0 -> 159 bytes .../xMasterX/tanksgame/images/tank_right.png | Bin 0 -> 155 bytes .../xMasterX/tanksgame/images/tank_stone.png | Bin 0 -> 3046 bytes .../xMasterX/tanksgame/images/tank_up.png | Bin 0 -> 157 bytes .../xMasterX/tanksgame/images/tank_wall.png | Bin 0 -> 3039 bytes .../source/xMasterX/tanksgame/tanksIcon.png | Bin 0 -> 1913 bytes .../source/xMasterX/tanksgame/tanks_game.c | 1456 ++++ .../source/xMasterX/timelapse/.gitattributes | 2 + .../source/xMasterX/timelapse/.gitignore | 1 + .../source/xMasterX/timelapse/README.md | 78 + .../source/xMasterX/timelapse/application.fam | 21 + .../source/xMasterX/timelapse/gpio_item.c | 51 + .../source/xMasterX/timelapse/gpio_item.h | 15 + .../timelapse/icons/ButtonDown_7x4.png | Bin 0 -> 102 bytes .../timelapse/icons/ButtonLeft_4x7.png | Bin 0 -> 1415 bytes .../timelapse/icons/ButtonRight_4x7.png | Bin 0 -> 1839 bytes .../xMasterX/timelapse/icons/ButtonUp_7x4.png | Bin 0 -> 102 bytes .../xMasterX/timelapse/icons/Pin_star_7x7.png | Bin 0 -> 3600 bytes .../xMasterX/timelapse/icons/loading_10px.png | Bin 0 -> 4349 bytes .../source/xMasterX/timelapse/zeitraffer.c | 435 + .../source/xMasterX/timelapse/zeitraffer.png | Bin 0 -> 199 bytes .../xMasterX/usb_hid_autofire/.gitignore | 1 + .../xMasterX/usb_hid_autofire/CHANGELOG.md | 13 + .../source/xMasterX/usb_hid_autofire/LICENSE | 674 ++ .../xMasterX/usb_hid_autofire/README.md | 32 + .../xMasterX/usb_hid_autofire/application.fam | 13 + .../xMasterX/usb_hid_autofire/screenshot.png | Bin 0 -> 2176 bytes .../source/xMasterX/usb_hid_autofire/tools.c | 56 + .../source/xMasterX/usb_hid_autofire/tools.h | 7 + .../usb_hid_autofire/usb_hid_autofire.c | 127 + .../usb_hid_autofire/usb_hid_autofire.kra | Bin 0 -> 50949 bytes .../usb_hid_autofire/usb_hid_autofire.png | Bin 0 -> 641 bytes .../usb_hid_autofire/usb_hid_autofire.svg | 75 + .../xMasterX/usb_hid_autofire/version.h | 1 + .../source/xMasterX/usb_midi/.gitattributes | 2 + .../source/xMasterX/usb_midi/.gitignore | 52 + .../source/xMasterX/usb_midi/application.fam | 14 + .../source/xMasterX/usb_midi/midi/config.h | 3 + .../source/xMasterX/usb_midi/midi/message.c | 144 + .../source/xMasterX/usb_midi/midi/message.h | 251 + .../source/xMasterX/usb_midi/midi/parser.c | 149 + .../source/xMasterX/usb_midi/midi/parser.h | 14 + .../xMasterX/usb_midi/midi/usb_message.c | 40 + .../xMasterX/usb_midi/midi/usb_message.h | 28 + .../xMasterX/usb_midi/usb/cm3_usb_audio.h | 234 + .../xMasterX/usb_midi/usb/cm3_usb_midi.h | 190 + .../xMasterX/usb_midi/usb/usb_midi_driver.c | 428 + .../xMasterX/usb_midi/usb/usb_midi_driver.h | 14 + .../source/xMasterX/usb_midi/usb_midi.c | 86 + .../source/xMasterX/usb_midi/usb_midi.png | Bin 0 -> 146 bytes .../xMasterX/videopoker/application.fam | 12 + .../DEV_FW/source/xMasterX/videopoker/poker.c | 820 ++ .../source/xMasterX/videopoker/pokerIcon.png | Bin 0 -> 1899 bytes .../source/xMasterX/wifi_deauther/LICENSE | 674 ++ .../source/xMasterX/wifi_deauther/README.md | 50 + .../xMasterX/wifi_deauther/application.fam | 12 + .../scenes/wifi_deauther_scene.c | 30 + .../scenes/wifi_deauther_scene.h | 29 + .../scenes/wifi_deauther_scene_config.h | 3 + .../wifi_deauther_scene_console_output.c | 90 + .../scenes/wifi_deauther_scene_start.c | 172 + .../scenes/wifi_deauther_scene_text_input.c | 72 + .../xMasterX/wifi_deauther/wifi_10px.png | Bin 0 -> 1781 bytes .../wifi_deauther/wifi_deauther_app.c | 106 + .../wifi_deauther/wifi_deauther_app.h | 11 + .../wifi_deauther/wifi_deauther_app_i.h | 69 + .../wifi_deauther_custom_event.h | 7 + .../wifi_deauther/wifi_deauther_uart.c | 98 + .../wifi_deauther/wifi_deauther_uart.h | 14 + .../source/xMasterX/wii_ec_anal/LICENSE | 21 + .../source/xMasterX/wii_ec_anal/README.md | 233 + .../source/xMasterX/wii_ec_anal/README.txt | 67 + .../source/xMasterX/wii_ec_anal/WiiEC.png | Bin 0 -> 116 bytes .../xMasterX/wii_ec_anal/_image_tool/LICENSE | 21 + .../xMasterX/wii_ec_anal/_image_tool/README | 30 + .../wii_ec_anal/_image_tool/_convert.c | 138 + .../wii_ec_anal/_image_tool/_convert.sh | 79 + .../wii_ec_anal/_image_tool/_convert_images.c | 141 + .../wii_ec_anal/_image_tool/_convert_images.h | 53 + .../wii_ec_anal/_image_tool/_convert_test.c | 59 + .../xMasterX/wii_ec_anal/_images/CLASSIC.png | Bin 0 -> 4373 bytes .../wii_ec_anal/_images/CLASSIC_N.png | Bin 0 -> 5147 bytes .../xMasterX/wii_ec_anal/_images/DEBUG.png | Bin 0 -> 3942 bytes .../xMasterX/wii_ec_anal/_images/DUMP.png | Bin 0 -> 4763 bytes .../wii_ec_anal/_images/GIMP/Nunchuck_acc.xcf | Bin 0 -> 555803 bytes .../xMasterX/wii_ec_anal/_images/GIMP/RIP.xcf | Bin 0 -> 11823 bytes .../wii_ec_anal/_images/GIMP/Wiring.xcf | Bin 0 -> 1519579 bytes .../wii_ec_anal/_images/GIMP/classic.xcf | Bin 0 -> 44768 bytes .../wii_ec_anal/_images/GIMP/csLogo.xcf | Bin 0 -> 28597 bytes .../wii_ec_anal/_images/GIMP/fonts.xcf | Bin 0 -> 33845 bytes .../wii_ec_anal/_images/GIMP/frame.xcf | Bin 0 -> 1584236 bytes .../wii_ec_anal/_images/GIMP/port.xcf | Bin 0 -> 33732 bytes .../wii_ec_anal/_images/GIMP/social.xcf | Bin 0 -> 5041256 bytes .../xMasterX/wii_ec_anal/_images/NUNCHUCK.png | Bin 0 -> 4457 bytes .../wii_ec_anal/_images/NUNCHUCK_acc.png | Bin 0 -> 81659 bytes .../wii_ec_anal/_images/NUNCHUCK_anal.png | Bin 0 -> 4410 bytes .../wii_ec_anal/_images/NUNCHUCK_cal.gif | Bin 0 -> 5868 bytes .../wii_ec_anal/_images/NUNCHUCK_cal.png | Bin 0 -> 4403 bytes .../wii_ec_anal/_images/Nunchucky.png | Bin 0 -> 319083 bytes .../xMasterX/wii_ec_anal/_images/RIP.png | Bin 0 -> 4983 bytes .../xMasterX/wii_ec_anal/_images/SPLASH.png | Bin 0 -> 5214 bytes .../xMasterX/wii_ec_anal/_images/WAIT.png | Bin 0 -> 4006 bytes .../xMasterX/wii_ec_anal/_images/WiiChuck.png | Bin 0 -> 101207 bytes .../xMasterX/wii_ec_anal/_images/Wiring.png | Bin 0 -> 347489 bytes .../xMasterX/wii_ec_anal/_images/plug.png | Bin 0 -> 75270 bytes .../xMasterX/wii_ec_anal/_images/social.png | Bin 0 -> 718696 bytes .../xMasterX/wii_ec_anal/application.fam | 36 + .../source/xMasterX/wii_ec_anal/bc_logging.h | 70 + .../DEV_FW/source/xMasterX/wii_ec_anal/err.h | 69 + .../source/xMasterX/wii_ec_anal/gfx/images.c | 141 + .../source/xMasterX/wii_ec_anal/gfx/images.h | 134 + .../xMasterX/wii_ec_anal/gfx/img_3x5_0.c | 11 + .../xMasterX/wii_ec_anal/gfx/img_3x5_1.c | 11 + .../xMasterX/wii_ec_anal/gfx/img_3x5_2.c | 11 + .../xMasterX/wii_ec_anal/gfx/img_3x5_3.c | 11 + .../xMasterX/wii_ec_anal/gfx/img_3x5_4.c | 11 + .../xMasterX/wii_ec_anal/gfx/img_3x5_5.c | 11 + .../xMasterX/wii_ec_anal/gfx/img_3x5_6.c | 11 + .../xMasterX/wii_ec_anal/gfx/img_3x5_7.c | 11 + .../xMasterX/wii_ec_anal/gfx/img_3x5_8.c | 11 + .../xMasterX/wii_ec_anal/gfx/img_3x5_9.c | 11 + .../xMasterX/wii_ec_anal/gfx/img_3x5_v.c | 11 + .../xMasterX/wii_ec_anal/gfx/img_5x7_0.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_5x7_1.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_5x7_2.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_5x7_3.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_5x7_4.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_5x7_5.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_5x7_6.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_5x7_7.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_5x7_8.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_5x7_9.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_5x7_A.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_5x7_B.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_5x7_C.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_5x7_D.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_5x7_E.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_5x7_F.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_6x8_0.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_1.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_2.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_3.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_4.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_5.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_6.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_7.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_8.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_9.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_A.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_B.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_C.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_D.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_E.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_F.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_G.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_X.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_Y.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_Z.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_d_.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_n_.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_6x8_v_.c | 14 + .../source/xMasterX/wii_ec_anal/gfx/img_RIP.c | 122 + .../xMasterX/wii_ec_anal/gfx/img_cc_Cable.c | 17 + .../xMasterX/wii_ec_anal/gfx/img_cc_Joy.c | 25 + .../xMasterX/wii_ec_anal/gfx/img_cc_Main.c | 92 + .../xMasterX/wii_ec_anal/gfx/img_cc_btn_A1.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_cc_btn_B1.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_cc_btn_X1.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_cc_btn_Y1.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_cc_pad_LR1.c | 11 + .../xMasterX/wii_ec_anal/gfx/img_cc_pad_UD1.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_cc_trg_L1.c | 12 + .../xMasterX/wii_ec_anal/gfx/img_cc_trg_L2.c | 12 + .../xMasterX/wii_ec_anal/gfx/img_cc_trg_L3.c | 12 + .../xMasterX/wii_ec_anal/gfx/img_cc_trg_L4.c | 12 + .../xMasterX/wii_ec_anal/gfx/img_cc_trg_R1.c | 12 + .../xMasterX/wii_ec_anal/gfx/img_cc_trg_R2.c | 12 + .../xMasterX/wii_ec_anal/gfx/img_cc_trg_R3.c | 12 + .../xMasterX/wii_ec_anal/gfx/img_cc_trg_R4.c | 12 + .../wii_ec_anal/gfx/img_csLogo_FULL.c | 81 + .../wii_ec_anal/gfx/img_csLogo_Small.c | 18 + .../xMasterX/wii_ec_anal/gfx/img_ecp_SCL.c | 13 + .../xMasterX/wii_ec_anal/gfx/img_ecp_SDA.c | 19 + .../xMasterX/wii_ec_anal/gfx/img_ecp_port.c | 66 + .../xMasterX/wii_ec_anal/gfx/img_key_Back.c | 15 + .../xMasterX/wii_ec_anal/gfx/img_key_D.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_key_L.c | 15 + .../xMasterX/wii_ec_anal/gfx/img_key_OK.c | 15 + .../xMasterX/wii_ec_anal/gfx/img_key_OKi.c | 15 + .../xMasterX/wii_ec_anal/gfx/img_key_R.c | 15 + .../xMasterX/wii_ec_anal/gfx/img_key_U.c | 14 + .../xMasterX/wii_ec_anal/gfx/img_key_Ui.c | 14 + .../xMasterX/wii_ec_anal/i2c_workaround.h | 119 + .../source/xMasterX/wii_ec_anal/info.sh | 11 + .../source/xMasterX/wii_ec_anal/notes.txt | 87 + .../source/xMasterX/wii_ec_anal/wii_anal.c | 540 ++ .../source/xMasterX/wii_ec_anal/wii_anal.h | 97 + .../source/xMasterX/wii_ec_anal/wii_anal_ec.c | 97 + .../source/xMasterX/wii_ec_anal/wii_anal_ec.h | 14 + .../xMasterX/wii_ec_anal/wii_anal_keys.c | 297 + .../xMasterX/wii_ec_anal/wii_anal_keys.h | 16 + .../xMasterX/wii_ec_anal/wii_anal_lcd.c | 223 + .../xMasterX/wii_ec_anal/wii_anal_lcd.h | 43 + .../xMasterX/wii_ec_anal/wii_anal_ver.h | 9 + .../source/xMasterX/wii_ec_anal/wii_ec.c | 220 + .../source/xMasterX/wii_ec_anal/wii_ec.h | 177 + .../xMasterX/wii_ec_anal/wii_ec_classic.c | 398 + .../xMasterX/wii_ec_anal/wii_ec_classic.h | 84 + .../xMasterX/wii_ec_anal/wii_ec_macros.h | 84 + .../xMasterX/wii_ec_anal/wii_ec_nunchuck.c | 459 ++ .../xMasterX/wii_ec_anal/wii_ec_nunchuck.h | 53 + .../xMasterX/wii_ec_anal/wii_ec_udraw.c | 145 + .../xMasterX/wii_ec_anal/wii_ec_udraw.h | 18 + .../source/xMasterX/wii_ec_anal/wii_i2c.c | 309 + .../source/xMasterX/wii_ec_anal/wii_i2c.h | 42 + 1094 files changed, 102160 insertions(+) create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/air_mouse.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/air_mouse.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/mouse_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/calibration_data.cc create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/calibration_data.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/bmi160.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/bmi160.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/bmi160_defs.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/imu.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/imu.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/imu_bmi160.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/imu_lsm6ds3trc.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/lsm6ds3tr_c_reg.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/lsm6ds3tr_c_reg.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/main_loop.cc create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/main_loop.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/orientation_tracker.cc create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/orientation_tracker.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/accelerometer_data.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/gyroscope_bias_estimator.cc create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/gyroscope_bias_estimator.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/gyroscope_data.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/lowpass_filter.cc create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/lowpass_filter.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/mean_filter.cc create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/mean_filter.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/median_filter.cc create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/median_filter.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/pose_prediction.cc create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/pose_prediction.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/pose_state.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/sensor_fusion_ekf.cc create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/sensor_fusion_ekf.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/logging.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrix_3x3.cc create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrix_3x3.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrix_4x4.cc create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrix_4x4.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrixutils.cc create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrixutils.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/rotation.cc create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/rotation.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/vector.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/vectorutils.cc create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/vectorutils.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/views/bt_mouse.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/views/bt_mouse.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/views/calibration.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/views/calibration.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/views/usb_mouse.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/airmouse/views/usb_mouse.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_app.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_app.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_utils.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_utils.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_validator.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_validator.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/encodings.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/encodings.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/images/barcode_10.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/screenshots/Creating Barcode.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/screenshots/Flipper Barcode.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/screenshots/Flipper Box Barcode.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/barcode_view.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/barcode_view.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/create_view.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/create_view.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/message_view.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/message_view.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/bpmtapper/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/bpmtapper/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/bpmtapper/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/bpmtapper/bpm.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/bpmtapper/bpm_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/bpmtapper/icons/DolphinCommon_56x48.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/bpmtapper/images/DolphinCommon_56x48.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/bpmtapper/img/screenshot.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/bfico.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/brainfuck.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/brainfuck.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/brainfuck_i.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/ButtonRightSmall_3x5.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeyBackspaceSelected_24x11.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeyBackspace_24x11.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeyInputSelected_30x11.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeyInput_30x11.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeyRunSelected_24x11.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeyRun_24x11.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeySaveSelected_24x11.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeySave_24x11.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/bfico.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_config.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_dev.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_exec.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_file_create.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_file_select.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_set_input.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_start.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/views/bf_dev_env.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/views/bf_dev_env.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/worker.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/brainfuck/worker.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/fbs.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/fbs.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/uart_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/caesarcipher/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/caesarcipher/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/caesarcipher/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/caesarcipher/caesar_cipher.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/caesarcipher/caesar_cipher_icon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/caesarcipher/img/1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/caesarcipher/img/2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/calculator/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/calculator/calc.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/calculator/calcIcon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/calculator/calculator.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/calculator/tinyexpr.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/calculator/tinyexpr.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/cli-bridge/.gitignore create mode 100644 Applications/Official/DEV_FW/source/xMasterX/cli-bridge/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/cli-bridge/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/cli-bridge/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/cli-bridge/cli_control.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/cli-bridge/cli_control.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/cli-bridge/cligui.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/cli-bridge/cligui_main.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/cli-bridge/cligui_main_i.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/cli-bridge/console_output.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/cli-bridge/console_output.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/cli-bridge/internal_defs.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/cli-bridge/text_input.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/cli-bridge/text_input.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/counter/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/counter/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/counter/counter.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/counter/icons/counter_icon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_3.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_5.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_6.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d100_1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d100_2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d100_3.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d100_4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d10_1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d10_2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d10_3.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d10_4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d12_1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d12_2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d12_3.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d12_4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d20_1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d20_2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d20_3.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d20_4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d4_1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d4_2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d4_3.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d6_1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d6_2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d6_3.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d6_4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d8_1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d8_2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d8_3.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/d8_4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_button_back.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_button_down.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_button_exit.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_button_left.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_button_right.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_button_roll.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_button_up.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_count.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_count_1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_result_1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_result_2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_result_3.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/constants.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/dice_app.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/icon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/sources/coin.pixil create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/sources/d10.pixil create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/sources/d100.pixil create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/sources/d12.pixil create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/sources/d20.pixil create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/sources/d6.pixil create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/sources/d8.pixil create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/sources/flipper-screen.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/sources/main-screen.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/dice/sources/roll-screen.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/Screenshot.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/125_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ActiveConnection_50x64.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Alert_9x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ArrowC_1_36x36.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ArrowDownEmpty_14x15.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ArrowDownFilled_14x15.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ArrowUpEmpty_14x15.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ArrowUpFilled_14x15.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Attention_5x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Auth_62x31.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/BLE_Pairing_128x64.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Background_128x11.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/BatteryBody_52x28.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Battery_16x16.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Battery_26x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Ble_connected_15x15.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Ble_disconnected_15x15.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Bluetooth_Connected_16x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Bluetooth_Idle_5x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonCenter_7x7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonDown_7x4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonLeftSmall_3x5.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonLeft_4x7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonRightSmall_3x5.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonRight_4x7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonUp_7x4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Button_18x18.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Certification1_103x56.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Certification2_98x33.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Charging-lightning_9x10.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Charging-lightning_mask_9x10.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Circles_47x47.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Clock_18x18.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Connect_me_62x31.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Connected_62x31.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/CoolHi_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/CoolHi_hvr_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/CoolLo_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/CoolLo_hvr_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Cry_dolph_55x52.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/DFU_128x50.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Dehumidify_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Dehumidify_hvr_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Detailed_chip_17x13.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/DolphinCommon_56x48.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/DolphinMafia_115x62.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/DolphinNice_96x59.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/DolphinReadingSuccess_59x63.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/DolphinWait_61x59.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/DoorLeft_70x55.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/DoorRight_70x55.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Down_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Down_hvr_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Drive_112x35.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Error_18x18.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Error_62x31.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/EviSmile1_18x21.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/EviSmile2_18x21.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/EviWaiting1_18x21.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/EviWaiting2_18x21.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/FaceCharging_29x14.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/FaceConfused_29x14.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/FaceNopower_29x14.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/FaceNormal_29x14.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/GameMode_11x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Health_16x16.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/HeatHi_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/HeatHi_hvr_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/HeatLo_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/HeatLo_hvr_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Hidden_window_9x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/InfraredArrowDown_4x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/InfraredArrowUp_4x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/InfraredLearnShort_128x31.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/KeyBackspaceSelected_16x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/KeyBackspace_16x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/KeySaveSelected_24x11.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/KeySave_24x11.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Keychain_39x36.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Left_mouse_icon_9x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Lock_7x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Lock_8x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/MHz_25x11.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Medium-chip-22x21.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Modern_reader_18x34.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Move_flipper_26x39.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Mute_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Mute_hvr_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/NFC_manual_60x50.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Nfc_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Off_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Off_hvr_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Ok_btn_9x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Ok_btn_pressed_13x13.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Percent_10x14.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_arrow_down_7x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_arrow_left_9x7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_arrow_right_9x7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_arrow_up_7x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_attention_dpad_29x29.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_back_arrow_10x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_back_full_40x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_pointer_5x3.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_star_7x7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Power_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Power_hvr_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pressed_Button_13x13.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Quest_7x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/RFIDBigChip_37x36.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/RFIDDolphinReceive_97x61.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/RFIDDolphinSend_97x61.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/RFIDDolphinSuccess_108x57.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Reader_detect_43x40.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Release_arrow_18x15.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Restoring_38x32.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Right_mouse_icon_9x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/SDQuestion_35x43.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/SDcardFail_11x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/SDcardMounted_11x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Scanning_123x52.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/SmallArrowDown_3x5.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/SmallArrowDown_4x7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/SmallArrowUp_3x5.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/SmallArrowUp_4x7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Smile_18x18.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Space_65x18.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Tap_reader_36x38.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Temperature_16x16.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Unlock_7x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Unplug_bg_bottom_128x10.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Unplug_bg_top_128x14.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Up_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Up_hvr_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Updating_32x40.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/UsbTree_48x22.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Vol_down_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Vol_down_hvr_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Vol_up_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Vol_up_hvr_25x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Voldwn_6x6.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Voltage_16x16.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Volup_8x6.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/WarningDolphin_45x42.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Warning_30x23.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/_FaceNormal_29x14.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/back_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/badusb_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/dir_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/iButtonDolphinVerySuccess_108x52.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/iButtonKey_49x44.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ibutt_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ir_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/loading_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/music_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_bad1_46x49.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_bad2_46x49.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_bad3_46x49.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_bottom_128x18.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_happy1_46x49.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_happy2_46x49.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_happy3_46x49.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_left_6x46.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_okay1_46x49.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_okay2_46x49.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_okay3_46x49.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/sub1_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/u2f_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/unknown_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/update_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/etch-a-sketch-icon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/etch-a-sketch.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/etch-a-sketch_icons.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/LICENSE.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/flipp_pomodoro_10.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/flipp_pomodoro_app.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/flipp_pomodoro_app.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/flipp_pomodoro_app_i.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/debug.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/notifications.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/notifications.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/time.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/time.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/images/flipp_pomodoro_rest_64.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/images/flipp_pomodoro_work_64.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/modules/flipp_pomodoro.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/modules/flipp_pomodoro.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/.keep create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/config/flipp_pomodoro_scene_config.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/flipp_pomodoro_scene.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/flipp_pomodoro_scene.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/flipp_pomodoro_scene_timer.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/views/.keep create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/views/flipp_pomodoro_timer_view.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/views/flipp_pomodoro_timer_view.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/app.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/appicon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/images/Asteroids.jpg create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-bp/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-bp/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-bp/fbp.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-bp/fbp.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-bp/tcode.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-bp/tcode.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-bp/uart_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-bp/views/gpio_simple_motor.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-bp/views/gpio_simple_motor.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-bp/views/internal.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-bp/views/internal.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/.gitignore create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/LICENSE.txt create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/dcf77_app.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/dcf77_app.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/dcf77_util.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/dcf77_util.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/icons/app.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/flash10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/flashlight.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_analog_clock/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_analog_clock/analog_clock.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_analog_clock/analog_clock.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_analog_clock/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/flipper_geiger.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/geiger.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/flipper1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/flipper2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/flipper3.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/flipper4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/flipper5.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/flipper6.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/logo.jpg create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/schematic.jpg create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/.clang-format create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/.editorconfig create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/.gitignore create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/icons/Horizontal_arrow_9x7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/icons/Ok_btn_9x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/icons/Pin_back_arrow_10x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/icons/Vertical_arrow_7x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/icons/passgen_icon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/images/preview.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/passgen.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_pong/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_pong/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_pong/flipper_pong.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_pong/img/Flipper_Zero.jpg create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_pong/img/flipper1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_pong/img/flipper2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_pong/img/flipper3.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipper_pong/pong.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/.github/workflows/release.yml create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/.gitignore create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/icons/qrcode_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/qrcode.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/qrcode.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/qrcode_app.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/scripts/check-firmware.sh create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/scripts/update-firmware.sh create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/img/screenshot_1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/img/screenshot_2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/img/tuning_fork.gif create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/notes.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/tuning_fork.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/tuning_fork_icon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/tunings.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/.gitignore create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/die_1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/die_2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/die_3.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/die_4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/die_5.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/die_6.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/yatzee_icon_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/yatzee.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/GPIO_reader.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/GPIO_reader_item.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/GPIO_reader_item.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/icon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_app.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_app.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_app_i.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_custom_event.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_item.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_item.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpioreader.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/icon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_config.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_reader.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_start.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_test.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_usb_uart.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_usb_uart_close_rpc.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_usb_uart_config.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/usb_uart_bridge.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/usb_uart_bridge.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_reader.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_reader.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_test.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_test.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_usb_uart.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_usb_uart.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/.github/FUNDING.yml create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/.github/workflows/build-fap.yml create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/gui/modules/file_select.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/gui/modules/file_select.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/gui/modules/variable_item_list_ex.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/gui/modules/variable_item_list_ex.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/AppInteract_32x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/Background_128x64.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/CommComplete_32x20.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/CommReady_32x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/CommReturn_10x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/CommVB_32x20.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/CommWave_12x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/Comm_32x20.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/Delete_32x20.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/LeftButtonBg_54x15.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/PulsemonLeftStand_14x16.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/PulsemonLeftWait_15x15.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/PulsemonRightHappy_14x16.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/PulsemonRightSad_15x15.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/PulsemonRightWaiting_15x16.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/RightButtonBg_54x15.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextClearCaptures_49x13.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextCleared_47x6.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextDeleteVb_49x13.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextDeleted_46x6.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextErrLoadCapture_65x13.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextErrLoadTemplate_69x13.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextErrReadFailed_71x20.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextErrRegisterDifferentTag_47x20.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextErrSaveCapture_65x13.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextRegister1_71x20.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextRegisterErrNotVb_71x20.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextRegisterTapAgain_67x20.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextSaved_30x6.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextTapApp_56x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextTransferCaptured_97x13.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextTransferDimCheck_70x20.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextTransferSecondDimCheck_71x20.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextTransfersDone_51x13.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/WrongDevice_32x27.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_about.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_config.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_delete.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_delete_captures.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_delete_captures_success.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_delete_success.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_dev_menu.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_from_app.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_info.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_load.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_main_menu.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_register.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_register_save.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_save_success.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_select.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_to_app.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_migrate.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_migrate.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_migrate_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_migrate_i.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_tag.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_tag.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/app.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/app.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/cntdown_timer.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/utils/utils.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/utils/utils.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/views/countdown_view.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/views/countdown_view.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/game2048/2048.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/game2048/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/game2048/font.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/game2048/font.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/game2048/game_2048.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/game_of_life/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/game_of_life/game_of_life.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/game_of_life/golIcon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ifttt/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ifttt/icon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ifttt/ifttt_virtual_button.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ifttt/ifttt_virtual_button.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene_about.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene_config.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene_send.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene_start.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ifttt/views/about_view.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ifttt/views/about_view.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ifttt/views/send_view.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ifttt/views/send_view.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/example.txt create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/ButtonDown_7x4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/ButtonLeft_4x7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/ButtonRight_4x7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/ButtonUp_7x4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/Ok_btn_9x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/back_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/sub1_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote_app.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote_button.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote_button.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_signal.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_signal.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/ir.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/ir2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ir_remote/ir_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/mandelbrot/Mandelbrot.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/mandelbrot/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/mandelbrot/mandelbrot.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/montyhall/Monty.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/montyhall/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/montyhall/monteyhall.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/music_beeper/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/music_beeper/icons/music_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_beeper.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_beeper_cli.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_beeper_worker.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_beeper_worker.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/musictracker/.github/workflows/build_dev.yml create mode 100644 Applications/Official/DEV_FW/source/xMasterX/musictracker/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/musictracker/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/musictracker/icons/.gitignore create mode 100644 Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/speaker_hal.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/speaker_hal.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/tracker.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/tracker.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/tracker_notes.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/tracker_song.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/musictracker/view/tracker_view.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/musictracker/view/tracker_view.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/musictracker/zero_tracker.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/musictracker/zero_tracker.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/musictracker/zero_tracker.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Distr/Nrf24_Scanner.fap create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Distr/nrf24scan/addr-WCO1.txt create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Distr/nrf24scan/addresses.txt create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Distr/nrf24scan/sniff.txt create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Screenshot-1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Screenshot-2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Screenshot-3.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Screenshot-4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Screenshot-5.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Screenshot-6.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Screenshot-7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/lib/nrf24/nrf24.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/lib/nrf24/nrf24.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/nrf24_packet_decoder.py create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/nrf24scan.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/nrf24scan.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/nrf24scan/nrf24scan_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ocarina/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ocarina/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ocarina/icons/music_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ocarina/music_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/ocarina/ocarina.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/paint/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/paint/paint.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/paint/paintIcon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/icons/ButtonLeft_4x7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/icons/Ok_btn_9x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/icons/Pin_back_arrow_10x8.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/icons/Space_65x18.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/misc/1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/misc/2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/misc/3.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/misc/4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/misc/5.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro_timer.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro_timer.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro_timer.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_10.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_10.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_25.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_25.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_50.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_50.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/TODO create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/app.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/app.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/app_buffer.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/app_buffer.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/app_subghz.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/appicon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/custom_presets.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/images/ProtoViewSignal.jpg create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/proto.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/protocols/b4b1.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/protocols/oregon2.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/protocols/oregon2.txt create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/protocols/renault_tpms.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/signal.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/ui.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/view_info.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/view_raw_signal.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/protoview/view_settings.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/.gitignore create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/coleco.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/coleco_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco0_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco0_hvr_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco1_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco1_hvr_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco2_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco2_hvr_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco3_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco3_hvr_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco4_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco4_hvr_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco5_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco5_hvr_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco6_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco6_hvr_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco7_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco7_hvr_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco8_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco8_hvr_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco9_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco9_hvr_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoAlt_18x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoAlt_hvr_18x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoFire_18x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoFire_hvr_18x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoFire_sel_18x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoJoystick_33x33.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoJoystick_hvr_33x33.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoJoystick_sel_33x33.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoPound_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoPound_hvr_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoStar_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoStar_hvr_17x17.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/interface/flipper-coleco.brd create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/interface/flipper-coleco.sch create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/ui.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rgb_led/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rgb_led/assets/Arr_dwn_7x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rgb_led/assets/Arr_up_7x9.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rgb_led/led_ll.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rgb_led/led_ll.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rgb_led/rgb_led.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rgb_led/rgb_led.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rgb_led/rgb_led_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rgb_led/views/rgb_led_default.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rgb_led/views/rgb_led_default.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rmdice/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rmdice/dice.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rmdice/dice.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/cube.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/rubiks_cube_scrambler.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/scrambler.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/scrambler.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/sam/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/sam/icons/music_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/sam/music_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/sam/sam_app.cpp create mode 100644 Applications/Official/DEV_FW/source/xMasterX/sam/stm32_sam.cpp create mode 100644 Applications/Official/DEV_FW/source/xMasterX/sam/stm32_sam.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/scorchedTanks_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/scorched_tanks_game_app.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/scorched_tanks_v1.gif create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/compiled/assets_icons.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/hal.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/hal_types.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/icons/icon_0.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/icons/icon_1.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/icons/icon_2.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/icons/icon_3.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/icons/icon_4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/icons/icon_5.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/icons/icon_6.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/icons/icon_7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/tama.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamaIcon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/tama_p1.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/cpu.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/cpu.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/hal.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/hal_types.h.template create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/hw.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/hw.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/tamalib.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/tamalib.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/constants.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/HappyFlipper_128x64.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/TanksSplashScreen_128x64.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/enemy_down.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/enemy_left.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/enemy_right.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/enemy_up.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/projectile_down.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/projectile_left.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/projectile_right.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/projectile_up.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/tank_base.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/tank_down.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/tank_explosion.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/tank_hedgehog.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/tank_left.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/tank_right.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/tank_stone.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/tank_up.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/tank_wall.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/tanksIcon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/tanksgame/tanks_game.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/timelapse/.gitattributes create mode 100644 Applications/Official/DEV_FW/source/xMasterX/timelapse/.gitignore create mode 100644 Applications/Official/DEV_FW/source/xMasterX/timelapse/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/timelapse/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/timelapse/gpio_item.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/timelapse/gpio_item.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/ButtonDown_7x4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/ButtonLeft_4x7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/ButtonRight_4x7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/ButtonUp_7x4.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/Pin_star_7x7.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/loading_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/timelapse/zeitraffer.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/timelapse/zeitraffer.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/.gitignore create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/CHANGELOG.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/screenshot.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/tools.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/tools.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/usb_hid_autofire.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/usb_hid_autofire.kra create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/usb_hid_autofire.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/usb_hid_autofire.svg create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/version.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_midi/.gitattributes create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_midi/.gitignore create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_midi/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/config.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/message.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/message.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/parser.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/parser.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/usb_message.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/usb_message.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb/cm3_usb_audio.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb/cm3_usb_midi.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb/usb_midi_driver.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb/usb_midi_driver.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb_midi.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb_midi.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/videopoker/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/videopoker/poker.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/videopoker/pokerIcon.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene_config.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene_console_output.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene_start.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene_text_input.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_10px.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_app.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_app.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_app_i.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_custom_event.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_uart.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_uart.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/README.md create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/README.txt create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/WiiEC.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/LICENSE create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/README create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert.sh create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert_images.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert_images.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert_test.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/CLASSIC.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/CLASSIC_N.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/DEBUG.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/DUMP.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/Nunchuck_acc.xcf create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/RIP.xcf create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/Wiring.xcf create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/classic.xcf create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/csLogo.xcf create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/fonts.xcf create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/frame.xcf create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/port.xcf create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/social.xcf create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/NUNCHUCK.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/NUNCHUCK_acc.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/NUNCHUCK_anal.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/NUNCHUCK_cal.gif create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/NUNCHUCK_cal.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/Nunchucky.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/RIP.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/SPLASH.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/WAIT.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/WiiChuck.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/Wiring.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/plug.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/social.png create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/application.fam create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/bc_logging.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/err.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/images.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/images.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_3x5_0.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_3x5_1.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_3x5_2.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_3x5_3.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_3x5_4.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_3x5_5.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_3x5_6.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_3x5_7.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_3x5_8.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_3x5_9.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_3x5_v.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_5x7_0.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_5x7_1.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_5x7_2.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_5x7_3.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_5x7_4.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_5x7_5.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_5x7_6.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_5x7_7.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_5x7_8.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_5x7_9.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_5x7_A.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_5x7_B.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_5x7_C.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_5x7_D.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_5x7_E.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_5x7_F.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_0.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_1.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_2.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_3.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_4.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_5.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_6.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_7.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_8.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_9.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_A.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_B.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_C.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_D.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_E.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_F.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_G.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_X.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_Y.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_Z.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_d_.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_n_.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_6x8_v_.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_RIP.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_Cable.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_Joy.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_Main.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_btn_A1.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_btn_B1.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_btn_X1.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_btn_Y1.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_pad_LR1.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_pad_UD1.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_trg_L1.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_trg_L2.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_trg_L3.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_trg_L4.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_trg_R1.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_trg_R2.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_trg_R3.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_cc_trg_R4.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_csLogo_FULL.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_csLogo_Small.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_ecp_SCL.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_ecp_SDA.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_ecp_port.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_key_Back.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_key_D.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_key_L.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_key_OK.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_key_OKi.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_key_R.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_key_U.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/gfx/img_key_Ui.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/i2c_workaround.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/info.sh create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/notes.txt create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_anal.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_anal.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_anal_ec.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_anal_ec.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_anal_keys.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_anal_keys.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_anal_lcd.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_anal_lcd.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_anal_ver.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_ec.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_ec.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_ec_classic.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_ec_classic.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_ec_macros.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_ec_nunchuck.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_ec_nunchuck.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_ec_udraw.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_ec_udraw.h create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_i2c.c create mode 100644 Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/wii_i2c.h diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/airmouse/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/README.md b/Applications/Official/DEV_FW/source/xMasterX/airmouse/README.md new file mode 100644 index 000000000..04e346e4b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/README.md @@ -0,0 +1,60 @@ +# Flipper Air Mouse + +## Brief + +> "You can turn anything into an air mouse if you're brave enough" + + — Piper, a.k.a. Pez + +Naturally, the quote above applies to [Flipper](https://flipperzero.one/) as well. + +## What? + +The app allows you to turn your Flipper into a USB or Bluetooth air mouse (you do need an extra module, see the Hardware section below)... + +Using it is really simple: + * Connect the Flipper via a USB cable and pick `USB`, or pick `Bluetooth` and pair it with your PC; + * Hold the Flipper in your hand with the buttons pointing towards the screen; + * Wave your Flipper like you don't care to move the cursor; + * Up button for Left mouse click; + * Down button for Right mouse click; + * Center button for Middle mouse click; + * Left and Right buttons for scrolling; + * Use calibration menu option if you notice significant drift (place your Flipper onto a level surface, make sure it doesn't move, run this option, wait 2 seconds, done). + +See early prototype [in action](https://www.youtube.com/watch?v=DdxAmmsYfMA). + +## Hardware + +The custom module is using Bosch BMI160 accelerometer/gyroscope chip connected via I2C. + +Take a look into the [schematic](https://github.com/ginkage/FlippAirMouse/tree/main/schematic) folder for Gerber, BOM and CPL files, so you can order directly from JLCPCB. + +Original idea: + +![What I thought it would look like](https://github.com/ginkage/FlippAirMouse/blob/main/schematic/schematic.png) + +Expectation: + +![What EDA though it would look like](https://github.com/ginkage/FlippAirMouse/blob/main/schematic/render.png) + +Reality: + +![What it looks like](https://github.com/ginkage/FlippAirMouse/blob/main/schematic/flipper.jpg) + +## Software + +The code is based on the original Bosch [driver](https://github.com/BoschSensortec/BMI160_driver/) and an orientation tracking implementation from the Google [Cardboard](https://github.com/googlevr/cardboard/tree/master/sdk/sensors) project + +If you're familiar with Flipper applications, start in the [firmware](https://github.com/flipperdevices/flipperzero-firmware) checkout folder and do the following: +``` +cd applications/plugins +git clone https://github.com/ginkage/FlippAirMouse +cd ../.. +./fbt fap_air_mouse +``` +If you're not familiar with those, just grab a `fap` file from Releases. + +## License + +TL;DR: Use the code however you want, give credit where it's due, no warranty of any kind is provided. diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/air_mouse.c b/Applications/Official/DEV_FW/source/xMasterX/airmouse/air_mouse.c new file mode 100644 index 000000000..7a90e49f1 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/air_mouse.c @@ -0,0 +1,156 @@ +#include "air_mouse.h" + +#include +#include + +#include "tracking/imu/imu.h" + +#define TAG "AirMouseApp" + +enum AirMouseSubmenuIndex { + AirMouseSubmenuIndexBtMouse, + AirMouseSubmenuIndexUsbMouse, + AirMouseSubmenuIndexCalibration, +}; + +void air_mouse_submenu_callback(void* context, uint32_t index) { + furi_assert(context); + AirMouse* app = context; + if(index == AirMouseSubmenuIndexBtMouse) { + app->view_id = AirMouseViewBtMouse; + view_dispatcher_switch_to_view(app->view_dispatcher, AirMouseViewBtMouse); + } else if(index == AirMouseSubmenuIndexUsbMouse) { + app->view_id = AirMouseViewUsbMouse; + view_dispatcher_switch_to_view(app->view_dispatcher, AirMouseViewUsbMouse); + } else if(index == AirMouseSubmenuIndexCalibration) { + app->view_id = AirMouseViewCalibration; + view_dispatcher_switch_to_view(app->view_dispatcher, AirMouseViewCalibration); + } +} + +void air_mouse_dialog_callback(DialogExResult result, void* context) { + furi_assert(context); + AirMouse* app = context; + if(result == DialogExResultLeft) { + view_dispatcher_switch_to_view(app->view_dispatcher, VIEW_NONE); // Exit + } 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, AirMouseViewSubmenu); // Menu + } +} + +uint32_t air_mouse_exit_confirm_view(void* context) { + UNUSED(context); + return AirMouseViewExitConfirm; +} + +uint32_t air_mouse_exit(void* context) { + UNUSED(context); + return VIEW_NONE; +} + +AirMouse* air_mouse_app_alloc() { + AirMouse* app = malloc(sizeof(AirMouse)); + + // Gui + app->gui = furi_record_open(RECORD_GUI); + + // 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); + + // Submenu view + app->submenu = submenu_alloc(); + submenu_add_item( + app->submenu, "Bluetooth", AirMouseSubmenuIndexBtMouse, air_mouse_submenu_callback, app); + submenu_add_item( + app->submenu, "USB", AirMouseSubmenuIndexUsbMouse, air_mouse_submenu_callback, app); + submenu_add_item( + app->submenu, + "Calibration", + AirMouseSubmenuIndexCalibration, + air_mouse_submenu_callback, + app); + view_set_previous_callback(submenu_get_view(app->submenu), air_mouse_exit); + view_dispatcher_add_view( + app->view_dispatcher, AirMouseViewSubmenu, submenu_get_view(app->submenu)); + + // Dialog view + app->dialog = dialog_ex_alloc(); + dialog_ex_set_result_callback(app->dialog, air_mouse_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, AirMouseViewExitConfirm, dialog_ex_get_view(app->dialog)); + + // Bluetooth view + app->bt_mouse = bt_mouse_alloc(app->view_dispatcher); + view_set_previous_callback(bt_mouse_get_view(app->bt_mouse), air_mouse_exit_confirm_view); + view_dispatcher_add_view( + app->view_dispatcher, AirMouseViewBtMouse, bt_mouse_get_view(app->bt_mouse)); + + // USB view + app->usb_mouse = usb_mouse_alloc(app->view_dispatcher); + view_set_previous_callback(usb_mouse_get_view(app->usb_mouse), air_mouse_exit_confirm_view); + view_dispatcher_add_view( + app->view_dispatcher, AirMouseViewUsbMouse, usb_mouse_get_view(app->usb_mouse)); + + // Calibration view + app->calibration = calibration_alloc(app->view_dispatcher); + view_set_previous_callback( + calibration_get_view(app->calibration), air_mouse_exit_confirm_view); + view_dispatcher_add_view( + app->view_dispatcher, AirMouseViewCalibration, calibration_get_view(app->calibration)); + + app->view_id = AirMouseViewSubmenu; + view_dispatcher_switch_to_view(app->view_dispatcher, app->view_id); + + return app; +} + +void air_mouse_app_free(AirMouse* app) { + furi_assert(app); + + // Free views + view_dispatcher_remove_view(app->view_dispatcher, AirMouseViewSubmenu); + submenu_free(app->submenu); + view_dispatcher_remove_view(app->view_dispatcher, AirMouseViewExitConfirm); + dialog_ex_free(app->dialog); + view_dispatcher_remove_view(app->view_dispatcher, AirMouseViewBtMouse); + bt_mouse_free(app->bt_mouse); + view_dispatcher_remove_view(app->view_dispatcher, AirMouseViewUsbMouse); + usb_mouse_free(app->usb_mouse); + view_dispatcher_remove_view(app->view_dispatcher, AirMouseViewCalibration); + calibration_free(app->calibration); + view_dispatcher_free(app->view_dispatcher); + + // Close records + furi_record_close(RECORD_GUI); + app->gui = NULL; + + // Free rest + free(app); +} + +int32_t air_mouse_app(void* p) { + UNUSED(p); + + AirMouse* app = air_mouse_app_alloc(); + if(!imu_begin()) { + air_mouse_app_free(app); + return -1; + } + + DOLPHIN_DEED(DolphinDeedPluginStart); + view_dispatcher_run(app->view_dispatcher); + + imu_end(); + air_mouse_app_free(app); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/air_mouse.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/air_mouse.h new file mode 100644 index 000000000..3a1ba783e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/air_mouse.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "views/bt_mouse.h" +#include "views/usb_mouse.h" +#include "views/calibration.h" + +typedef struct { + Gui* gui; + ViewDispatcher* view_dispatcher; + Submenu* submenu; + DialogEx* dialog; + BtMouse* bt_mouse; + UsbMouse* usb_mouse; + Calibration* calibration; + uint32_t view_id; +} AirMouse; + +typedef enum { + AirMouseViewSubmenu, + AirMouseViewBtMouse, + AirMouseViewUsbMouse, + AirMouseViewCalibration, + AirMouseViewExitConfirm, +} AirMouseView; diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/application.fam b/Applications/Official/DEV_FW/source/xMasterX/airmouse/application.fam new file mode 100644 index 000000000..9014b14a6 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/application.fam @@ -0,0 +1,9 @@ +App( + appid="Air_Mouse", + name="[BMI160] Air Mouse", + apptype=FlipperAppType.EXTERNAL, + entry_point="air_mouse_app", + stack_size=10 * 1024, + fap_category="GPIO_Extra", + fap_icon="mouse_10px.png", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/mouse_10px.png b/Applications/Official/DEV_FW/source/xMasterX/airmouse/mouse_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..94c3a7a14143c00d6747ed59274c96e98d178b41 GIT binary patch literal 1634 zcmcIlJB-{!7&a%6$Vmq+qQUr@@EFhdxoa!V>DWEk75F$^R?1O;7|)D%&8k)*M)rWN~tLNw!9yhU*9=Vl!v}cMn~0A_>xa} zs$VxlvP-rr_-$T=Yh85^~G2&Lrq;ms^dW0l?K(L@IdYHf~g(d1Oy?Zc0ApP zTnBf&XH^rKCPXeYEMRne+w~1wZ7xliD`@N=_MdNziCLgcsw(#(tm|5@Eu9x*Xn39n zkqJ!`2m~k>S%v2yE4SASeO8hp$*Y8Cs$|3wpH+b-q^^8O^OiO%n>dMx!8y*Mp(E+j z8W@IWL({ZHm(|{hu+r$gD{(nm5h8wYLZc2mrqGW%>mZO6$><( zHGn)|I3ol3mhD^JXOQJ1w1S4B5Gbzj`M{he@!~wtF!YC6S>cSZVL#A>C_PE2Z#b6e zA`^+?A|~kCb__hy?E>T?f~+p~3>GhSiSvCW(+XPalJUQ4JS6%Y%dpy_;m2}c2=p13PwU>H;$+aT+fJrXV^CA8eJDyj!mt| zH6x3fno5Zu^CHEfPLdRl8O*b>rv9g<$EUmqITbOtWHk$R;l&^+Md}vK_i=^2*^H)% zx-2>$6IttlMr4v1)tcqxF3~%m&J}GvVS@CGJd@c8GYe#Fi=y7t`c2_ZJ`!mY~bs@U%7a!kv zLv-$)VSjh@*ash7`}z?DJ=lBVr(3s*`kMXuyR>}z`rcsU?e{MJy!q)5e_j6NkHv+- tXNTsuyY-KM{|0Z~_ +#include + +#define TAG "tracker" + +#include "calibration_data.h" + +#include +#include + +// Student's distribution T value for 95% (two-sided) confidence interval. +static const double Tn = 1.960; + +// Number of samples (degrees of freedom) for the corresponding T values. +static const int Nn = 200; + +void CalibrationData::reset() +{ + complete = false; + count = 0; + sum = Vector::Zero(); + sumSq = Vector::Zero(); + mean = Vector::Zero(); + median = Vector::Zero(); + sigma = Vector::Zero(); + delta = Vector::Zero(); + xData.clear(); + yData.clear(); + zData.clear(); +} + +bool CalibrationData::add(Vector& data) +{ + if (complete) { + return true; + } + + xData.push_back(data[0]); + yData.push_back(data[1]); + zData.push_back(data[2]); + + sum += data; + sumSq += data * data; + count++; + + if (count >= Nn) { + calcDelta(); + complete = true; + } + + return complete; +} + +static inline double medianOf(std::vector& list) +{ + std::sort(list.begin(), list.end()); + int count = list.size(); + int middle = count / 2; + return (count % 2 == 1) ? list[middle] : (list[middle - 1] + list[middle]) / 2.0l; +} + +void CalibrationData::calcDelta() +{ + median.Set(medianOf(xData), medianOf(yData), medianOf(zData)); + + mean = sum / count; + Vector m2 = mean * mean; + Vector d = sumSq / count - m2; + Vector s2 = (d * count) / (count - 1); + sigma = Vector(std::sqrt(d[0]), std::sqrt(d[1]), std::sqrt(d[2])); + Vector s = Vector(std::sqrt(s2[0]), std::sqrt(s2[1]), std::sqrt(s2[2])); + delta = s * Tn / std::sqrt((double)count); + Vector low = mean - delta; + Vector high = mean + delta; + + FURI_LOG_I(TAG, + "M[x] = { %f ... %f } // median = %f // avg = %f // delta = %f // sigma = %f", + low[0], high[0], median[0], mean[0], delta[0], sigma[0]); + FURI_LOG_I(TAG, + "M[y] = { %f ... %f } // median = %f // avg = %f // delta = %f // sigma = %f", + low[1], high[1], median[1], mean[1], delta[1], sigma[1]); + FURI_LOG_I(TAG, + "M[z] = { %f ... %f } // median = %f // avg = %f // delta = %f // sigma = %f", + low[2], high[2], median[2], mean[2], delta[2], sigma[2]); +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/calibration_data.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/calibration_data.h new file mode 100644 index 000000000..d47dab08d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/calibration_data.h @@ -0,0 +1,117 @@ +#pragma once + +#include +#include +#include + +#include "util/vector.h" + +#define CALIBRATION_DATA_VER (1) +#define CALIBRATION_DATA_FILE_NAME ".calibration.data" +#define CALIBRATION_DATA_PATH INT_PATH(CALIBRATION_DATA_FILE_NAME) +#define CALIBRATION_DATA_MAGIC (0x23) + +#define CALIBRATION_DATA_SAVE(x) \ + saved_struct_save( \ + CALIBRATION_DATA_PATH, \ + (x), \ + sizeof(CalibrationMedian), \ + CALIBRATION_DATA_MAGIC, \ + CALIBRATION_DATA_VER) + +#define CALIBRATION_DATA_LOAD(x) \ + saved_struct_load( \ + CALIBRATION_DATA_PATH, \ + (x), \ + sizeof(CalibrationMedian), \ + CALIBRATION_DATA_MAGIC, \ + CALIBRATION_DATA_VER) + +typedef struct { + double x; + double y; + double z; +} CalibrationMedian; + +typedef cardboard::Vector3 Vector; + +/** + * Helper class to gather some stats and store the calibration data. Right now it calculates a lot + * more stats than actually needed. Some of them are used for logging the sensors quality (and + * filing bugs), other may be required in the future, e.g. for bias. + */ +class CalibrationData { +public: + /** + * Check if the sensors were calibrated before. + * + * @return {@code true} if calibration data is available, or {@code false} otherwise. + */ + bool isComplete() { + return complete; + } + + /** Prepare to collect new calibration data. */ + void reset(); + + /** + * Retrieve the median gyroscope readings. + * + * @return Three-axis median vector. + */ + Vector getMedian() { + return median; + } + + /** + * Retrieve the mean gyroscope readings. + * + * @return Three-axis mean vector. + */ + Vector getMean() { + return mean; + } + + /** + * Retrieve the standard deviation of gyroscope readings. + * + * @return Three-axis standard deviation vector. + */ + Vector getSigma() { + return sigma; + } + + /** + * Retrieve the confidence interval size of gyroscope readings. + * + * @return Three-axis confidence interval size vector. + */ + Vector getDelta() { + return delta; + } + + /** + * Add a new gyroscope reading to the stats. + * + * @param data gyroscope values vector. + * @return {@code true} if we now have enough data for calibration, or {@code false} otherwise. + */ + bool add(Vector& data); + +private: + // Calculates the confidence interval (mean +- delta) and some other related values, like + // standard deviation, etc. See https://en.wikipedia.org/wiki/Student%27s_t-distribution + void calcDelta(); + + int count; + bool complete; + Vector sum; + Vector sumSq; + Vector mean; + Vector median; + Vector sigma; + Vector delta; + std::vector xData; + std::vector yData; + std::vector zData; +}; diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/bmi160.c b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/bmi160.c new file mode 100644 index 000000000..968dddd4d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/bmi160.c @@ -0,0 +1,5988 @@ +/** +* Copyright (c) 2021 Bosch Sensortec GmbH. All rights reserved. +* +* BSD-3-Clause +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* 3. Neither the name of the copyright holder nor the names of its +* contributors may be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +* @file bmi160.c +* @date 2021-10-05 +* @version v3.9.2 +* +*/ + +#include "bmi160.h" + +/* Below look up table follows the enum bmi160_int_types. + * Hence any change should match to the enum bmi160_int_types + */ +const uint8_t int_mask_lookup_table[13] = { + BMI160_INT1_SLOPE_MASK, + BMI160_INT1_SLOPE_MASK, + BMI160_INT2_LOW_STEP_DETECT_MASK, + BMI160_INT1_DOUBLE_TAP_MASK, + BMI160_INT1_SINGLE_TAP_MASK, + BMI160_INT1_ORIENT_MASK, + BMI160_INT1_FLAT_MASK, + BMI160_INT1_HIGH_G_MASK, + BMI160_INT1_LOW_G_MASK, + BMI160_INT1_NO_MOTION_MASK, + BMI160_INT2_DATA_READY_MASK, + BMI160_INT2_FIFO_FULL_MASK, + BMI160_INT2_FIFO_WM_MASK}; + +/*********************************************************************/ +/* Static function declarations */ + +/*! + * @brief This API configures the pins to fire the + * interrupt signal when it occurs + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t + set_intr_pin_config(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); + +/*! + * @brief This API sets the any-motion interrupt of the sensor. + * This interrupt occurs when accel values exceeds preset threshold + * for a certain period of time. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t + set_accel_any_motion_int(struct bmi160_int_settg* int_config, struct bmi160_dev* dev); + +/*! + * @brief This API sets tap interrupts.Interrupt is fired when + * tap movements happen. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_accel_tap_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); + +/*! + * @brief This API sets the data ready interrupt for both accel and gyro. + * This interrupt occurs when new accel and gyro data come. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_accel_gyro_data_ready_int( + const struct bmi160_int_settg* int_config, + const struct bmi160_dev* dev); + +/*! + * @brief This API sets the significant motion interrupt of the sensor.This + * interrupt occurs when there is change in user location. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t + set_accel_sig_motion_int(struct bmi160_int_settg* int_config, struct bmi160_dev* dev); + +/*! + * @brief This API sets the no motion/slow motion interrupt of the sensor. + * Slow motion is similar to any motion interrupt.No motion interrupt + * occurs when slope bet. two accel values falls below preset threshold + * for preset duration. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t + set_accel_no_motion_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); + +/*! + * @brief This API sets the step detection interrupt.This interrupt + * occurs when the single step causes accel values to go above + * preset threshold. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t + set_accel_step_detect_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); + +/*! + * @brief This API sets the orientation interrupt of the sensor.This + * interrupt occurs when there is orientation change in the sensor + * with respect to gravitational field vector g. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t + set_accel_orientation_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); + +/*! + * @brief This API sets the flat interrupt of the sensor.This interrupt + * occurs in case of flat orientation + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t + set_accel_flat_detect_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); + +/*! + * @brief This API sets the low-g interrupt of the sensor.This interrupt + * occurs during free-fall. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t + set_accel_low_g_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); + +/*! + * @brief This API sets the high-g interrupt of the sensor.The interrupt + * occurs if the absolute value of acceleration data of any enabled axis + * exceeds the programmed threshold and the sign of the value does not + * change for a preset duration. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t + set_accel_high_g_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); + +/*! + * @brief This API sets the default configuration parameters of accel & gyro. + * Also maintain the previous state of configurations. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static void default_param_settg(struct bmi160_dev* dev); + +/*! + * @brief This API is used to validate the device structure pointer for + * null conditions. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t null_ptr_check(const struct bmi160_dev* dev); + +/*! + * @brief This API set the accel configuration. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_accel_conf(struct bmi160_dev* dev); + +/*! + * @brief This API gets the accel configuration. + * + * @param[out] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t get_accel_conf(struct bmi160_dev* dev); + +/*! + * @brief This API check the accel configuration. + * + * @param[in] data : Pointer to store the updated accel config. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t check_accel_config(uint8_t* data, const struct bmi160_dev* dev); + +/*! + * @brief This API process the accel odr. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t process_accel_odr(uint8_t* data, const struct bmi160_dev* dev); + +/*! + * @brief This API process the accel bandwidth. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t process_accel_bw(uint8_t* data, const struct bmi160_dev* dev); + +/*! + * @brief This API process the accel range. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t process_accel_range(uint8_t* data, const struct bmi160_dev* dev); + +/*! + * @brief This API checks the invalid settings for ODR & Bw for Accel and Gyro. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t check_invalid_settg(const struct bmi160_dev* dev); + +/*! + * @brief This API set the gyro configuration. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_gyro_conf(struct bmi160_dev* dev); + +/*! + * @brief This API get the gyro configuration. + * + * @param[out] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t get_gyro_conf(struct bmi160_dev* dev); + +/*! + * @brief This API check the gyro configuration. + * + * @param[in] data : Pointer to store the updated gyro config. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t check_gyro_config(uint8_t* data, const struct bmi160_dev* dev); + +/*! + * @brief This API process the gyro odr. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t process_gyro_odr(uint8_t* data, const struct bmi160_dev* dev); + +/*! + * @brief This API process the gyro bandwidth. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t process_gyro_bw(uint8_t* data, const struct bmi160_dev* dev); + +/*! + * @brief This API process the gyro range. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t process_gyro_range(uint8_t* data, const struct bmi160_dev* dev); + +/*! + * @brief This API sets the accel power mode. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_accel_pwr(struct bmi160_dev* dev); + +/*! + * @brief This API process the undersampling setting of Accel. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t process_under_sampling(uint8_t* data, const struct bmi160_dev* dev); + +/*! + * @brief This API sets the gyro power mode. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_gyro_pwr(struct bmi160_dev* dev); + +/*! + * @brief This API reads accel data along with sensor time if time is requested + * by user. Kindly refer the user guide(README.md) for more info. + * + * @param[in] len : len to read no of bytes + * @param[out] accel : Structure pointer to store accel data + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t + get_accel_data(uint8_t len, struct bmi160_sensor_data* accel, const struct bmi160_dev* dev); + +/*! + * @brief This API reads accel data along with sensor time if time is requested + * by user. Kindly refer the user guide(README.md) for more info. + * + * @param[in] len : len to read no of bytes + * @param[out] gyro : Structure pointer to store accel data + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t + get_gyro_data(uint8_t len, struct bmi160_sensor_data* gyro, const struct bmi160_dev* dev); + +/*! + * @brief This API reads accel and gyro data along with sensor time + * if time is requested by user. + * Kindly refer the user guide(README.md) for more info. + * + * @param[in] len : len to read no of bytes + * @param[out] accel : Structure pointer to store accel data + * @param[out] gyro : Structure pointer to store accel data + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t get_accel_gyro_data( + uint8_t len, + struct bmi160_sensor_data* accel, + struct bmi160_sensor_data* gyro, + const struct bmi160_dev* dev); + +/*! + * @brief This API enables the any-motion interrupt for accel. + * + * @param[in] any_motion_int_cfg : Structure instance of + * bmi160_acc_any_mot_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_accel_any_motion_int( + const struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg, + struct bmi160_dev* dev); + +/*! + * @brief This API disable the sig-motion interrupt. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t disable_sig_motion_int(const struct bmi160_dev* dev); + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for any-motion interrupt. + * + * @param[in] any_motion_int_cfg : Structure instance of + * bmi160_acc_any_mot_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_any_motion_src( + const struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the duration and threshold of + * any-motion interrupt. + * + * @param[in] any_motion_int_cfg : Structure instance of + * bmi160_acc_any_mot_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_any_dur_threshold( + const struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure necessary setting of any-motion interrupt. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] any_motion_int_cfg : Structure instance of + * bmi160_acc_any_mot_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_any_motion_int_settg( + const struct bmi160_int_settg* int_config, + const struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API enable the data ready interrupt. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_data_ready_int(const struct bmi160_dev* dev); + +/*! + * @brief This API enables the no motion/slow motion interrupt. + * + * @param[in] no_mot_int_cfg : Structure instance of + * bmi160_acc_no_motion_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_no_motion_int( + const struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the interrupt PIN setting for + * no motion/slow motion interrupt. + * + * @param[in] int_config : structure instance of bmi160_int_settg. + * @param[in] no_mot_int_cfg : Structure instance of + * bmi160_acc_no_motion_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_no_motion_int_settg( + const struct bmi160_int_settg* int_config, + const struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the source of interrupt for no motion. + * + * @param[in] no_mot_int_cfg : Structure instance of + * bmi160_acc_no_motion_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_no_motion_data_src( + const struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the duration and threshold of + * no motion/slow motion interrupt along with selection of no/slow motion. + * + * @param[in] no_mot_int_cfg : Structure instance of + * bmi160_acc_no_motion_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_no_motion_dur_thr( + const struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API enables the sig-motion motion interrupt. + * + * @param[in] sig_mot_int_cfg : Structure instance of + * bmi160_acc_sig_mot_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_sig_motion_int( + const struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg, + struct bmi160_dev* dev); + +/*! + * @brief This API configure the interrupt PIN setting for + * significant motion interrupt. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] sig_mot_int_cfg : Structure instance of + * bmi160_acc_sig_mot_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_sig_motion_int_settg( + const struct bmi160_int_settg* int_config, + const struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for sig motion interrupt. + * + * @param[in] sig_mot_int_cfg : Structure instance of + * bmi160_acc_sig_mot_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_sig_motion_data_src( + const struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the threshold, skip and proof time of + * sig motion interrupt. + * + * @param[in] sig_mot_int_cfg : Structure instance of + * bmi160_acc_sig_mot_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_sig_dur_threshold( + const struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API enables the step detector interrupt. + * + * @param[in] step_detect_int_cfg : Structure instance of + * bmi160_acc_step_detect_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_step_detect_int( + const struct bmi160_acc_step_detect_int_cfg* step_detect_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the step detector parameter. + * + * @param[in] step_detect_int_cfg : Structure instance of + * bmi160_acc_step_detect_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_step_detect( + const struct bmi160_acc_step_detect_int_cfg* step_detect_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API enables the single/double tap interrupt. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_tap_int( + const struct bmi160_int_settg* int_config, + const struct bmi160_acc_tap_int_cfg* tap_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the interrupt PIN setting for + * tap interrupt. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] tap_int_cfg : Structure instance of bmi160_acc_tap_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_tap_int_settg( + const struct bmi160_int_settg* int_config, + const struct bmi160_acc_tap_int_cfg* tap_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for tap interrupt. + * + * @param[in] tap_int_cfg : Structure instance of bmi160_acc_tap_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_tap_data_src( + const struct bmi160_acc_tap_int_cfg* tap_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the parameters of tap interrupt. + * Threshold, quite, shock, and duration. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] tap_int_cfg : Structure instance of bmi160_acc_tap_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_tap_param( + const struct bmi160_int_settg* int_config, + const struct bmi160_acc_tap_int_cfg* tap_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API enable the external mode configuration. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_sec_if(const struct bmi160_dev* dev); + +/*! + * @brief This API configure the ODR of the auxiliary sensor. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_aux_odr(const struct bmi160_dev* dev); + +/*! + * @brief This API maps the actual burst read length set by user. + * + * @param[in] len : Pointer to store the read length. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t map_read_len(uint16_t* len, const struct bmi160_dev* dev); + +/*! + * @brief This API configure the settings of auxiliary sensor. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_aux_settg(const struct bmi160_dev* dev); + +/*! + * @brief This API extract the read data from auxiliary sensor. + * + * @param[in] map_len : burst read value. + * @param[in] reg_addr : Address of register to read. + * @param[in] aux_data : Pointer to store the read data. + * @param[in] len : length to read the data. + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t extract_aux_read( + uint16_t map_len, + uint8_t reg_addr, + uint8_t* aux_data, + uint16_t len, + const struct bmi160_dev* dev); + +/*! + * @brief This API enables the orient interrupt. + * + * @param[in] orient_int_cfg : Structure instance of bmi160_acc_orient_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_orient_int( + const struct bmi160_acc_orient_int_cfg* orient_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the necessary setting of orientation interrupt. + * + * @param[in] orient_int_cfg : Structure instance of bmi160_acc_orient_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_orient_int_settg( + const struct bmi160_acc_orient_int_cfg* orient_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API enables the flat interrupt. + * + * @param[in] flat_int : Structure instance of bmi160_acc_flat_detect_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_flat_int( + const struct bmi160_acc_flat_detect_int_cfg* flat_int, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the necessary setting of flat interrupt. + * + * @param[in] flat_int : Structure instance of bmi160_acc_flat_detect_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_flat_int_settg( + const struct bmi160_acc_flat_detect_int_cfg* flat_int, + const struct bmi160_dev* dev); + +/*! + * @brief This API enables the Low-g interrupt. + * + * @param[in] low_g_int : Structure instance of bmi160_acc_low_g_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_low_g_int( + const struct bmi160_acc_low_g_int_cfg* low_g_int, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the source of data(filter & pre-filter) for low-g interrupt. + * + * @param[in] low_g_int : Structure instance of bmi160_acc_low_g_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_low_g_data_src( + const struct bmi160_acc_low_g_int_cfg* low_g_int, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the necessary setting of low-g interrupt. + * + * @param[in] low_g_int : Structure instance of bmi160_acc_low_g_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_low_g_int_settg( + const struct bmi160_acc_low_g_int_cfg* low_g_int, + const struct bmi160_dev* dev); + +/*! + * @brief This API enables the high-g interrupt. + * + * @param[in] high_g_int_cfg : Structure instance of bmi160_acc_high_g_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_high_g_int( + const struct bmi160_acc_high_g_int_cfg* high_g_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for high-g interrupt. + * + * @param[in] high_g_int_cfg : Structure instance of bmi160_acc_high_g_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_high_g_data_src( + const struct bmi160_acc_high_g_int_cfg* high_g_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the necessary setting of high-g interrupt. + * + * @param[in] high_g_int_cfg : Structure instance of bmi160_acc_high_g_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_high_g_int_settg( + const struct bmi160_acc_high_g_int_cfg* high_g_int_cfg, + const struct bmi160_dev* dev); + +/*! + * @brief This API configure the behavioural setting of interrupt pin. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t + config_int_out_ctrl(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); + +/*! + * @brief This API configure the mode(input enable, latch or non-latch) of interrupt pin. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t + config_int_latch(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); + +/*! + * @brief This API performs the self test for accelerometer of BMI160 + * + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t perform_accel_self_test(struct bmi160_dev* dev); + +/*! + * @brief This API enables to perform the accel self test by setting proper + * configurations to facilitate accel self test + * + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_accel_self_test(struct bmi160_dev* dev); + +/*! + * @brief This API performs accel self test with positive excitation + * + * @param[in] accel_pos : Structure pointer to store accel data + * for positive excitation + * @param[in] dev : structure instance of bmi160_dev + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t accel_self_test_positive_excitation( + struct bmi160_sensor_data* accel_pos, + const struct bmi160_dev* dev); + +/*! + * @brief This API performs accel self test with negative excitation + * + * @param[in] accel_neg : Structure pointer to store accel data + * for negative excitation + * @param[in] dev : structure instance of bmi160_dev + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t accel_self_test_negative_excitation( + struct bmi160_sensor_data* accel_neg, + const struct bmi160_dev* dev); + +/*! + * @brief This API validates the accel self test results + * + * @param[in] accel_pos : Structure pointer to store accel data + * for positive excitation + * @param[in] accel_neg : Structure pointer to store accel data + * for negative excitation + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error / +ve value -> Self test fail + */ +static int8_t validate_accel_self_test( + const struct bmi160_sensor_data* accel_pos, + const struct bmi160_sensor_data* accel_neg); + +/*! + * @brief This API performs the self test for gyroscope of BMI160 + * + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t perform_gyro_self_test(const struct bmi160_dev* dev); + +/*! + * @brief This API enables the self test bit to trigger self test for gyro + * + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_gyro_self_test(const struct bmi160_dev* dev); + +/*! + * @brief This API validates the self test results of gyro + * + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t validate_gyro_self_test(const struct bmi160_dev* dev); + +/*! + * @brief This API sets FIFO full interrupt of the sensor.This interrupt + * occurs when the FIFO is full and the next full data sample would cause + * a FIFO overflow, which may delete the old samples. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t + set_fifo_full_int(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); + +/*! + * @brief This enable the FIFO full interrupt engine. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t + enable_fifo_full_int(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); + +/*! + * @brief This API sets FIFO watermark interrupt of the sensor.The FIFO + * watermark interrupt is fired, when the FIFO fill level is above a fifo + * watermark. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t + set_fifo_watermark_int(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); + +/*! + * @brief This enable the FIFO watermark interrupt engine. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t + enable_fifo_wtm_int(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); + +/*! + * @brief This API is used to reset the FIFO related configurations + * in the fifo_frame structure. + * + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void reset_fifo_data_structure(const struct bmi160_dev* dev); + +/*! + * @brief This API is used to read number of bytes filled + * currently in FIFO buffer. + * + * @param[in] bytes_to_read : Number of bytes available in FIFO at the + * instant which is obtained from FIFO counter. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + * @retval Any non zero value -> Fail + * + */ +static int8_t get_fifo_byte_counter(uint16_t* bytes_to_read, struct bmi160_dev const* dev); + +/*! + * @brief This API is used to compute the number of bytes of accel FIFO data + * which is to be parsed in header-less mode + * + * @param[out] data_index : The start index for parsing data + * @param[out] data_read_length : Number of bytes to be parsed + * @param[in] acc_frame_count : Number of accelerometer frames to be read + * @param[in] dev : Structure instance of bmi160_dev. + * + */ +static void get_accel_len_to_parse( + uint16_t* data_index, + uint16_t* data_read_length, + const uint8_t* acc_frame_count, + const struct bmi160_dev* dev); + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data in both header mode and header-less mode. + * It updates the idx value which is used to store the index of + * the current data byte which is parsed. + * + * @param[in,out] acc : structure instance of sensor data + * @param[in,out] idx : Index value of number of bytes parsed + * @param[in,out] acc_idx : Index value of accelerometer data + * (x,y,z axes) frames parsed + * @param[in] frame_info : It consists of either fifo_data_enable + * parameter in header-less mode or + * frame header data in header mode + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void unpack_accel_frame( + struct bmi160_sensor_data* acc, + uint16_t* idx, + uint8_t* acc_idx, + uint8_t frame_info, + const struct bmi160_dev* dev); + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data and store it in the instance of the structure bmi160_sensor_data. + * + * @param[in,out] accel_data : structure instance of sensor data + * @param[in,out] data_start_index : Index value of number of bytes parsed + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void unpack_accel_data( + struct bmi160_sensor_data* accel_data, + uint16_t data_start_index, + const struct bmi160_dev* dev); + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data in header mode. + * + * @param[in,out] accel_data : Structure instance of sensor data + * @param[in,out] accel_length : Number of accelerometer frames + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void extract_accel_header_mode( + struct bmi160_sensor_data* accel_data, + uint8_t* accel_length, + const struct bmi160_dev* dev); + +/*! + * @brief This API computes the number of bytes of gyro FIFO data + * which is to be parsed in header-less mode + * + * @param[out] data_index : The start index for parsing data + * @param[out] data_read_length : No of bytes to be parsed from FIFO buffer + * @param[in] gyro_frame_count : Number of Gyro data frames to be read + * @param[in] dev : Structure instance of bmi160_dev. + */ +static void get_gyro_len_to_parse( + uint16_t* data_index, + uint16_t* data_read_length, + const uint8_t* gyro_frame_count, + const struct bmi160_dev* dev); + +/*! + * @brief This API is used to parse the gyroscope's data from the + * FIFO data in both header mode and header-less mode. + * It updates the idx value which is used to store the index of + * the current data byte which is parsed. + * + * @param[in,out] gyro : structure instance of sensor data + * @param[in,out] idx : Index value of number of bytes parsed + * @param[in,out] gyro_idx : Index value of gyro data + * (x,y,z axes) frames parsed + * @param[in] frame_info : It consists of either fifo_data_enable + * parameter in header-less mode or + * frame header data in header mode + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void unpack_gyro_frame( + struct bmi160_sensor_data* gyro, + uint16_t* idx, + uint8_t* gyro_idx, + uint8_t frame_info, + const struct bmi160_dev* dev); + +/*! + * @brief This API is used to parse the gyro data from the + * FIFO data and store it in the instance of the structure bmi160_sensor_data. + * + * @param[in,out] gyro_data : structure instance of sensor data + * @param[in,out] data_start_index : Index value of number of bytes parsed + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void unpack_gyro_data( + struct bmi160_sensor_data* gyro_data, + uint16_t data_start_index, + const struct bmi160_dev* dev); + +/*! + * @brief This API is used to parse the gyro data from the + * FIFO data in header mode. + * + * @param[in,out] gyro_data : Structure instance of sensor data + * @param[in,out] gyro_length : Number of gyro frames + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void extract_gyro_header_mode( + struct bmi160_sensor_data* gyro_data, + uint8_t* gyro_length, + const struct bmi160_dev* dev); + +/*! + * @brief This API computes the number of bytes of aux FIFO data + * which is to be parsed in header-less mode + * + * @param[out] data_index : The start index for parsing data + * @param[out] data_read_length : No of bytes to be parsed from FIFO buffer + * @param[in] aux_frame_count : Number of Aux data frames to be read + * @param[in] dev : Structure instance of bmi160_dev. + */ +static void get_aux_len_to_parse( + uint16_t* data_index, + uint16_t* data_read_length, + const uint8_t* aux_frame_count, + const struct bmi160_dev* dev); + +/*! + * @brief This API is used to parse the aux's data from the + * FIFO data in both header mode and header-less mode. + * It updates the idx value which is used to store the index of + * the current data byte which is parsed + * + * @param[in,out] aux_data : structure instance of sensor data + * @param[in,out] idx : Index value of number of bytes parsed + * @param[in,out] aux_index : Index value of gyro data + * (x,y,z axes) frames parsed + * @param[in] frame_info : It consists of either fifo_data_enable + * parameter in header-less mode or + * frame header data in header mode + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void unpack_aux_frame( + struct bmi160_aux_data* aux_data, + uint16_t* idx, + uint8_t* aux_index, + uint8_t frame_info, + const struct bmi160_dev* dev); + +/*! + * @brief This API is used to parse the aux data from the + * FIFO data and store it in the instance of the structure bmi160_aux_data. + * + * @param[in,out] aux_data : structure instance of sensor data + * @param[in,out] data_start_index : Index value of number of bytes parsed + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void unpack_aux_data( + struct bmi160_aux_data* aux_data, + uint16_t data_start_index, + const struct bmi160_dev* dev); + +/*! + * @brief This API is used to parse the aux data from the + * FIFO data in header mode. + * + * @param[in,out] aux_data : Structure instance of sensor data + * @param[in,out] aux_length : Number of aux frames + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void extract_aux_header_mode( + struct bmi160_aux_data* aux_data, + uint8_t* aux_length, + const struct bmi160_dev* dev); + +/*! + * @brief This API checks the presence of non-valid frames in the read fifo data. + * + * @param[in,out] data_index : The index of the current data to + * be parsed from fifo data + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void check_frame_validity(uint16_t* data_index, const struct bmi160_dev* dev); + +/*! + * @brief This API is used to move the data index ahead of the + * current_frame_length parameter when unnecessary FIFO data appears while + * extracting the user specified data. + * + * @param[in,out] data_index : Index of the FIFO data which + * is to be moved ahead of the + * current_frame_length + * @param[in] current_frame_length : Number of bytes in a particular frame + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void move_next_frame( + uint16_t* data_index, + uint8_t current_frame_length, + const struct bmi160_dev* dev); + +/*! + * @brief This API is used to parse and store the sensor time from the + * FIFO data in the structure instance dev. + * + * @param[in,out] data_index : Index of the FIFO data which + * has the sensor time. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void unpack_sensortime_frame(uint16_t* data_index, const struct bmi160_dev* dev); + +/*! + * @brief This API is used to parse and store the skipped_frame_count from + * the FIFO data in the structure instance dev. + * + * @param[in,out] data_index : Index of the FIFO data which + * has the skipped frame count. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void unpack_skipped_frame(uint16_t* data_index, const struct bmi160_dev* dev); + +/*! + * @brief This API is used to get the FOC status from the sensor + * + * @param[in,out] foc_status : Result of FOC status. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t get_foc_status(uint8_t* foc_status, struct bmi160_dev const* dev); + +/*! + * @brief This API is used to configure the offset enable bits in the sensor + * + * @param[in,out] foc_conf : Structure instance of bmi160_foc_conf which + * has the FOC and offset configurations + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t + configure_offset_enable(const struct bmi160_foc_conf* foc_conf, struct bmi160_dev const* dev); + +/*! + * @brief This API is used to trigger the FOC in the sensor + * + * @param[in,out] offset : Structure instance of bmi160_offsets which + * reads and stores the offset values after FOC + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t trigger_foc(struct bmi160_offsets* offset, struct bmi160_dev const* dev); + +/*! + * @brief This API is used to map/unmap the Dataready(Accel & Gyro), FIFO full + * and FIFO watermark interrupt + * + * @param[in] int_config : Structure instance of bmi160_int_settg which + * stores the interrupt type and interrupt channel + * configurations to map/unmap the interrupt pins + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t + map_hardware_interrupt(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); + +/*! + * @brief This API is used to map/unmap the Any/Sig motion, Step det/Low-g, + * Double tap, Single tap, Orientation, Flat, High-G, Nomotion interrupt pins. + * + * @param[in] int_config : Structure instance of bmi160_int_settg which + * stores the interrupt type and interrupt channel + * configurations to map/unmap the interrupt pins + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t + map_feature_interrupt(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); + +/*********************** User function definitions ****************************/ + +/*! + * @brief This API reads the data from the given register address + * of sensor. + */ +int8_t + bmi160_get_regs(uint8_t reg_addr, uint8_t* data, uint16_t len, const struct bmi160_dev* dev) { + int8_t rslt = BMI160_OK; + + /* Null-pointer check */ + if((dev == NULL) || (dev->read == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else if(len == 0) { + rslt = BMI160_E_READ_WRITE_LENGTH_INVALID; + } else { + /* Configuring reg_addr for SPI Interface */ + if(dev->intf == BMI160_SPI_INTF) { + reg_addr = (reg_addr | BMI160_SPI_RD_MASK); + } + + rslt = dev->read(dev->id, reg_addr, data, len); + } + + return rslt; +} + +/*! + * @brief This API writes the given data to the register address + * of sensor. + */ +int8_t + bmi160_set_regs(uint8_t reg_addr, uint8_t* data, uint16_t len, const struct bmi160_dev* dev) { + int8_t rslt = BMI160_OK; + uint8_t count = 0; + + /* Null-pointer check */ + if((dev == NULL) || (dev->write == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else if(len == 0) { + rslt = BMI160_E_READ_WRITE_LENGTH_INVALID; + } else { + /* Configuring reg_addr for SPI Interface */ + if(dev->intf == BMI160_SPI_INTF) { + reg_addr = (reg_addr & BMI160_SPI_WR_MASK); + } + + if((dev->prev_accel_cfg.power == BMI160_ACCEL_NORMAL_MODE) || + (dev->prev_gyro_cfg.power == BMI160_GYRO_NORMAL_MODE)) { + rslt = dev->write(dev->id, reg_addr, data, len); + + /* Kindly refer bmi160 data sheet section 3.2.4 */ + dev->delay_ms(1); + + } else { + /*Burst write is not allowed in + * suspend & low power mode */ + for(; count < len; count++) { + rslt = dev->write(dev->id, reg_addr, &data[count], 1); + reg_addr++; + + /* Kindly refer bmi160 data sheet section 3.2.4 */ + dev->delay_ms(1); + } + } + + if(rslt != BMI160_OK) { + rslt = BMI160_E_COM_FAIL; + } + } + + return rslt; +} + +/*! + * @brief This API is the entry point for sensor.It performs + * the selection of I2C/SPI read mechanism according to the + * selected interface and reads the chip-id of bmi160 sensor. + */ +int8_t bmi160_init(struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data; + uint8_t try = 3; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + + /* Dummy read of 0x7F register to enable SPI Interface + * if SPI is used */ + if((rslt == BMI160_OK) && (dev->intf == BMI160_SPI_INTF)) { + rslt = bmi160_get_regs(BMI160_SPI_COMM_TEST_ADDR, &data, 1, dev); + } + + if(rslt == BMI160_OK) { + /* Assign chip id as zero */ + dev->chip_id = 0; + + while((try--) && (dev->chip_id != BMI160_CHIP_ID)) { + /* Read chip_id */ + rslt = bmi160_get_regs(BMI160_CHIP_ID_ADDR, &dev->chip_id, 1, dev); + } + + if((rslt == BMI160_OK) && (dev->chip_id == BMI160_CHIP_ID)) { + dev->any_sig_sel = BMI160_BOTH_ANY_SIG_MOTION_DISABLED; + + /* Soft reset */ + rslt = bmi160_soft_reset(dev); + } else { + rslt = BMI160_E_DEV_NOT_FOUND; + } + } + + return rslt; +} + +/*! + * @brief This API resets and restarts the device. + * All register values are overwritten with default parameters. + */ +int8_t bmi160_soft_reset(struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = BMI160_SOFT_RESET_CMD; + + /* Null-pointer check */ + if((dev == NULL) || (dev->delay_ms == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + /* Reset the device */ + rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &data, 1, dev); + dev->delay_ms(BMI160_SOFT_RESET_DELAY_MS); + if((rslt == BMI160_OK) && (dev->intf == BMI160_SPI_INTF)) { + /* Dummy read of 0x7F register to enable SPI Interface + * if SPI is used */ + rslt = bmi160_get_regs(BMI160_SPI_COMM_TEST_ADDR, &data, 1, dev); + } + + if(rslt == BMI160_OK) { + /* Update the default parameters */ + default_param_settg(dev); + } + } + + return rslt; +} + +/*! + * @brief This API configures the power mode, range and bandwidth + * of sensor. + */ +int8_t bmi160_set_sens_conf(struct bmi160_dev* dev) { + int8_t rslt = BMI160_OK; + + /* Null-pointer check */ + if((dev == NULL) || (dev->delay_ms == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + rslt = set_accel_conf(dev); + if(rslt == BMI160_OK) { + rslt = set_gyro_conf(dev); + if(rslt == BMI160_OK) { + /* write power mode for accel and gyro */ + rslt = bmi160_set_power_mode(dev); + if(rslt == BMI160_OK) { + rslt = check_invalid_settg(dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This API gets accel and gyro configurations. + */ +int8_t bmi160_get_sens_conf(struct bmi160_dev* dev) { + int8_t rslt = BMI160_OK; + + /* Null-pointer check */ + if((dev == NULL) || (dev->delay_ms == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + rslt = get_accel_conf(dev); + if(rslt == BMI160_OK) { + rslt = get_gyro_conf(dev); + } + } + + return rslt; +} + +/*! + * @brief This API sets the power mode of the sensor. + */ +int8_t bmi160_set_power_mode(struct bmi160_dev* dev) { + int8_t rslt = 0; + + /* Null-pointer check */ + if((dev == NULL) || (dev->delay_ms == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + rslt = set_accel_pwr(dev); + if(rslt == BMI160_OK) { + rslt = set_gyro_pwr(dev); + } + } + + return rslt; +} + +/*! + * @brief This API gets the power mode of the sensor. + */ +int8_t bmi160_get_power_mode(struct bmi160_dev* dev) { + int8_t rslt = 0; + uint8_t power_mode = 0; + + /* Null-pointer check */ + if((dev == NULL) || (dev->delay_ms == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + rslt = bmi160_get_regs(BMI160_PMU_STATUS_ADDR, &power_mode, 1, dev); + if(rslt == BMI160_OK) { + /* Power mode of the accel, gyro sensor is obtained */ + dev->gyro_cfg.power = BMI160_GET_BITS(power_mode, BMI160_GYRO_POWER_MODE); + dev->accel_cfg.power = BMI160_GET_BITS(power_mode, BMI160_ACCEL_POWER_MODE); + } + } + + return rslt; +} + +/*! + * @brief This API reads sensor data, stores it in + * the bmi160_sensor_data structure pointer passed by the user. + */ +int8_t bmi160_get_sensor_data( + uint8_t select_sensor, + struct bmi160_sensor_data* accel, + struct bmi160_sensor_data* gyro, + const struct bmi160_dev* dev) { + int8_t rslt = BMI160_OK; + uint8_t time_sel; + uint8_t sen_sel; + uint8_t len = 0; + + /*Extract the sensor and time select information*/ + sen_sel = select_sensor & BMI160_SEN_SEL_MASK; + time_sel = ((sen_sel & BMI160_TIME_SEL) >> 2); + sen_sel = sen_sel & (BMI160_ACCEL_SEL | BMI160_GYRO_SEL); + if(time_sel == 1) { + len = 3; + } + + /* Null-pointer check */ + if(dev != NULL) { + switch(sen_sel) { + case BMI160_ACCEL_ONLY: + + /* Null-pointer check */ + if(accel == NULL) { + rslt = BMI160_E_NULL_PTR; + } else { + rslt = get_accel_data(len, accel, dev); + } + + break; + case BMI160_GYRO_ONLY: + + /* Null-pointer check */ + if(gyro == NULL) { + rslt = BMI160_E_NULL_PTR; + } else { + rslt = get_gyro_data(len, gyro, dev); + } + + break; + case BMI160_BOTH_ACCEL_AND_GYRO: + + /* Null-pointer check */ + if((gyro == NULL) || (accel == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + rslt = get_accel_gyro_data(len, accel, gyro, dev); + } + + break; + default: + rslt = BMI160_E_INVALID_INPUT; + break; + } + } else { + rslt = BMI160_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API configures the necessary interrupt based on + * the user settings in the bmi160_int_settg structure instance. + */ +int8_t bmi160_set_int_config(struct bmi160_int_settg* int_config, struct bmi160_dev* dev) { + int8_t rslt = BMI160_OK; + + switch(int_config->int_type) { + case BMI160_ACC_ANY_MOTION_INT: + + /*Any-motion interrupt*/ + rslt = set_accel_any_motion_int(int_config, dev); + break; + case BMI160_ACC_SIG_MOTION_INT: + + /* Significant motion interrupt */ + rslt = set_accel_sig_motion_int(int_config, dev); + break; + case BMI160_ACC_SLOW_NO_MOTION_INT: + + /* Slow or no motion interrupt */ + rslt = set_accel_no_motion_int(int_config, dev); + break; + case BMI160_ACC_DOUBLE_TAP_INT: + case BMI160_ACC_SINGLE_TAP_INT: + + /* Double tap and single tap Interrupt */ + rslt = set_accel_tap_int(int_config, dev); + break; + case BMI160_STEP_DETECT_INT: + + /* Step detector interrupt */ + rslt = set_accel_step_detect_int(int_config, dev); + break; + case BMI160_ACC_ORIENT_INT: + + /* Orientation interrupt */ + rslt = set_accel_orientation_int(int_config, dev); + break; + case BMI160_ACC_FLAT_INT: + + /* Flat detection interrupt */ + rslt = set_accel_flat_detect_int(int_config, dev); + break; + case BMI160_ACC_LOW_G_INT: + + /* Low-g interrupt */ + rslt = set_accel_low_g_int(int_config, dev); + break; + case BMI160_ACC_HIGH_G_INT: + + /* High-g interrupt */ + rslt = set_accel_high_g_int(int_config, dev); + break; + case BMI160_ACC_GYRO_DATA_RDY_INT: + + /* Data ready interrupt */ + rslt = set_accel_gyro_data_ready_int(int_config, dev); + break; + case BMI160_ACC_GYRO_FIFO_FULL_INT: + + /* Fifo full interrupt */ + rslt = set_fifo_full_int(int_config, dev); + break; + case BMI160_ACC_GYRO_FIFO_WATERMARK_INT: + + /* Fifo water-mark interrupt */ + rslt = set_fifo_watermark_int(int_config, dev); + break; + case BMI160_FIFO_TAG_INT_PIN: + + /* Fifo tagging feature support */ + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + break; + default: + break; + } + + return rslt; +} + +/*! + * @brief This API enables or disable the step counter feature. + * 1 - enable step counter (0 - disable) + */ +int8_t bmi160_set_step_counter(uint8_t step_cnt_enable, const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if(rslt != BMI160_OK) { + rslt = BMI160_E_NULL_PTR; + } else { + rslt = bmi160_get_regs(BMI160_INT_STEP_CONFIG_1_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + if(step_cnt_enable == BMI160_ENABLE) { + data |= (uint8_t)(step_cnt_enable << 3); + } else { + data &= ~BMI160_STEP_COUNT_EN_BIT_MASK; + } + + rslt = bmi160_set_regs(BMI160_INT_STEP_CONFIG_1_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API reads the step counter value. + */ +int8_t bmi160_read_step_counter(uint16_t* step_val, const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data[2] = {0, 0}; + uint16_t msb = 0; + uint8_t lsb = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if(rslt != BMI160_OK) { + rslt = BMI160_E_NULL_PTR; + } else { + rslt = bmi160_get_regs(BMI160_INT_STEP_CNT_0_ADDR, data, 2, dev); + if(rslt == BMI160_OK) { + lsb = data[0]; + msb = data[1] << 8; + *step_val = msb | lsb; + } + } + + return rslt; +} + +/*! + * @brief This API reads the mention no of byte of data from the given + * register address of auxiliary sensor. + */ +int8_t bmi160_aux_read( + uint8_t reg_addr, + uint8_t* aux_data, + uint16_t len, + const struct bmi160_dev* dev) { + int8_t rslt = BMI160_OK; + uint16_t map_len = 0; + + /* Null-pointer check */ + if((dev == NULL) || (dev->read == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + if(dev->aux_cfg.aux_sensor_enable == BMI160_ENABLE) { + rslt = map_read_len(&map_len, dev); + if(rslt == BMI160_OK) { + rslt = extract_aux_read(map_len, reg_addr, aux_data, len, dev); + } + } else { + rslt = BMI160_E_INVALID_INPUT; + } + } + + return rslt; +} + +/*! + * @brief This API writes the mention no of byte of data to the given + * register address of auxiliary sensor. + */ +int8_t bmi160_aux_write( + uint8_t reg_addr, + uint8_t* aux_data, + uint16_t len, + const struct bmi160_dev* dev) { + int8_t rslt = BMI160_OK; + uint8_t count = 0; + + /* Null-pointer check */ + if((dev == NULL) || (dev->write == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + for(; count < len; count++) { + /* set data to write */ + rslt = bmi160_set_regs(BMI160_AUX_IF_4_ADDR, aux_data, 1, dev); + dev->delay_ms(BMI160_AUX_COM_DELAY); + if(rslt == BMI160_OK) { + /* set address to write */ + rslt = bmi160_set_regs(BMI160_AUX_IF_3_ADDR, ®_addr, 1, dev); + dev->delay_ms(BMI160_AUX_COM_DELAY); + if(rslt == BMI160_OK && (count < len - 1)) { + aux_data++; + reg_addr++; + } + } + } + } + + return rslt; +} + +/*! + * @brief This API initialize the auxiliary sensor + * in order to access it. + */ +int8_t bmi160_aux_init(const struct bmi160_dev* dev) { + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if(rslt != BMI160_OK) { + rslt = BMI160_E_NULL_PTR; + } else { + if(dev->aux_cfg.aux_sensor_enable == BMI160_ENABLE) { + /* Configures the auxiliary sensor interface settings */ + rslt = config_aux_settg(dev); + } else { + rslt = BMI160_E_INVALID_INPUT; + } + } + + return rslt; +} + +/*! + * @brief This API is used to setup the auxiliary sensor of bmi160 in auto mode + * Thus enabling the auto update of 8 bytes of data from auxiliary sensor + * to BMI160 register address 0x04 to 0x0B + */ +int8_t bmi160_set_aux_auto_mode(uint8_t* data_addr, struct bmi160_dev* dev) { + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if(rslt != BMI160_OK) { + rslt = BMI160_E_NULL_PTR; + } else { + if(dev->aux_cfg.aux_sensor_enable == BMI160_ENABLE) { + /* Write the aux. address to read in 0x4D of BMI160*/ + rslt = bmi160_set_regs(BMI160_AUX_IF_2_ADDR, data_addr, 1, dev); + dev->delay_ms(BMI160_AUX_COM_DELAY); + if(rslt == BMI160_OK) { + /* Configure the polling ODR for + * auxiliary sensor */ + rslt = config_aux_odr(dev); + if(rslt == BMI160_OK) { + /* Disable the aux. manual mode, i.e aux. + * sensor is in auto-mode (data-mode) */ + dev->aux_cfg.manual_enable = BMI160_DISABLE; + rslt = bmi160_config_aux_mode(dev); + + /* Auxiliary sensor data is obtained + * in auto mode from this point */ + } + } + } else { + rslt = BMI160_E_INVALID_INPUT; + } + } + + return rslt; +} + +/*! + * @brief This API configures the 0x4C register and settings like + * Auxiliary sensor manual enable/ disable and aux burst read length. + */ +int8_t bmi160_config_aux_mode(const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t aux_if[2] = {(uint8_t)(dev->aux_cfg.aux_i2c_addr * 2), 0}; + + rslt = bmi160_get_regs(BMI160_AUX_IF_1_ADDR, &aux_if[1], 1, dev); + if(rslt == BMI160_OK) { + /* update the Auxiliary interface to manual/auto mode */ + aux_if[1] = BMI160_SET_BITS(aux_if[1], BMI160_MANUAL_MODE_EN, dev->aux_cfg.manual_enable); + + /* update the burst read length defined by user */ + aux_if[1] = + BMI160_SET_BITS_POS_0(aux_if[1], BMI160_AUX_READ_BURST, dev->aux_cfg.aux_rd_burst_len); + + /* Set the secondary interface address and manual mode + * along with burst read length */ + rslt = bmi160_set_regs(BMI160_AUX_IF_0_ADDR, &aux_if[0], 2, dev); + dev->delay_ms(BMI160_AUX_COM_DELAY); + } + + return rslt; +} + +/*! + * @brief This API is used to read the raw uncompensated auxiliary sensor + * data of 8 bytes from BMI160 register address 0x04 to 0x0B + */ +int8_t bmi160_read_aux_data_auto_mode(uint8_t* aux_data, const struct bmi160_dev* dev) { + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if(rslt != BMI160_OK) { + rslt = BMI160_E_NULL_PTR; + } else { + if((dev->aux_cfg.aux_sensor_enable == BMI160_ENABLE) && + (dev->aux_cfg.manual_enable == BMI160_DISABLE)) { + /* Read the aux. sensor's raw data */ + rslt = bmi160_get_regs(BMI160_AUX_DATA_ADDR, aux_data, 8, dev); + } else { + rslt = BMI160_E_INVALID_INPUT; + } + } + + return rslt; +} + +/*! + * @brief This is used to perform self test of accel/gyro of the BMI160 sensor + */ +int8_t bmi160_perform_self_test(uint8_t select_sensor, struct bmi160_dev* dev) { + int8_t rslt; + int8_t self_test_rslt = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if(rslt != BMI160_OK) { + rslt = BMI160_E_NULL_PTR; + } else { + /* Proceed if null check is fine */ + switch(select_sensor) { + case BMI160_ACCEL_ONLY: + rslt = perform_accel_self_test(dev); + break; + case BMI160_GYRO_ONLY: + + /* Set the power mode as normal mode */ + dev->gyro_cfg.power = BMI160_GYRO_NORMAL_MODE; + rslt = bmi160_set_power_mode(dev); + + /* Perform gyro self test */ + if(rslt == BMI160_OK) { + /* Perform gyro self test */ + rslt = perform_gyro_self_test(dev); + } + + break; + default: + rslt = BMI160_E_INVALID_INPUT; + break; + } + + /* Check to ensure bus error does not occur */ + if(rslt >= BMI160_OK) { + /* Store the status of self test result */ + self_test_rslt = rslt; + + /* Perform soft reset */ + rslt = bmi160_soft_reset(dev); + } + + /* Check to ensure bus operations are success */ + if(rslt == BMI160_OK) { + /* Restore self_test_rslt as return value */ + rslt = self_test_rslt; + } + } + + return rslt; +} + +/*! + * @brief This API reads the data from fifo buffer. + */ +int8_t bmi160_get_fifo_data(struct bmi160_dev const* dev) { + int8_t rslt = 0; + uint16_t bytes_to_read = 0; + uint16_t user_fifo_len = 0; + + /* check the bmi160 structure as NULL*/ + if((dev == NULL) || (dev->fifo->data == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + reset_fifo_data_structure(dev); + + /* get current FIFO fill-level*/ + rslt = get_fifo_byte_counter(&bytes_to_read, dev); + if(rslt == BMI160_OK) { + user_fifo_len = dev->fifo->length; + if((dev->fifo->length > bytes_to_read)) { + /* Handling the case where user requests + * more data than available in FIFO */ + dev->fifo->length = bytes_to_read; + } + + if((dev->fifo->fifo_time_enable == BMI160_FIFO_TIME_ENABLE) && + (bytes_to_read + BMI160_FIFO_BYTES_OVERREAD <= user_fifo_len)) { + /* Handling case of sensor time availability*/ + dev->fifo->length = dev->fifo->length + BMI160_FIFO_BYTES_OVERREAD; + } + + /* read only the filled bytes in the FIFO Buffer */ + rslt = bmi160_get_regs(BMI160_FIFO_DATA_ADDR, dev->fifo->data, dev->fifo->length, dev); + } + } + + return rslt; +} + +/*! + * @brief This API writes fifo_flush command to command register.This + * action clears all data in the Fifo without changing fifo configuration + * settings + */ +int8_t bmi160_set_fifo_flush(const struct bmi160_dev* dev) { + int8_t rslt = 0; + uint8_t data = BMI160_FIFO_FLUSH_VALUE; + uint8_t reg_addr = BMI160_COMMAND_REG_ADDR; + + /* Check the bmi160_dev structure for NULL address*/ + if(dev == NULL) { + rslt = BMI160_E_NULL_PTR; + } else { + rslt = bmi160_set_regs(reg_addr, &data, BMI160_ONE, dev); + } + + return rslt; +} + +/*! + * @brief This API sets the FIFO configuration in the sensor. + */ +int8_t bmi160_set_fifo_config(uint8_t config, uint8_t enable, struct bmi160_dev const* dev) { + int8_t rslt = 0; + uint8_t data = 0; + uint8_t reg_addr = BMI160_FIFO_CONFIG_1_ADDR; + uint8_t fifo_config = config & BMI160_FIFO_CONFIG_1_MASK; + + /* Check the bmi160_dev structure for NULL address*/ + if(dev == NULL) { + rslt = BMI160_E_NULL_PTR; + } else { + rslt = bmi160_get_regs(reg_addr, &data, BMI160_ONE, dev); + if(rslt == BMI160_OK) { + if(fifo_config > 0) { + if(enable == BMI160_ENABLE) { + data = data | fifo_config; + } else { + data = data & (~fifo_config); + } + } + + /* write fifo frame content configuration*/ + rslt = bmi160_set_regs(reg_addr, &data, BMI160_ONE, dev); + if(rslt == BMI160_OK) { + /* read fifo frame content configuration*/ + rslt = bmi160_get_regs(reg_addr, &data, BMI160_ONE, dev); + if(rslt == BMI160_OK) { + /* extract fifo header enabled status */ + dev->fifo->fifo_header_enable = data & BMI160_FIFO_HEAD_ENABLE; + + /* extract accel/gyr/aux. data enabled status */ + dev->fifo->fifo_data_enable = data & BMI160_FIFO_M_G_A_ENABLE; + + /* extract fifo sensor time enabled status */ + dev->fifo->fifo_time_enable = data & BMI160_FIFO_TIME_ENABLE; + } + } + } + } + + return rslt; +} + +/*! @brief This API is used to configure the down sampling ratios of + * the accel and gyro data for FIFO.Also, it configures filtered or + * pre-filtered data for accel and gyro. + * + */ +int8_t bmi160_set_fifo_down(uint8_t fifo_down, const struct bmi160_dev* dev) { + int8_t rslt = 0; + uint8_t data = 0; + uint8_t reg_addr = BMI160_FIFO_DOWN_ADDR; + + /* Check the bmi160_dev structure for NULL address*/ + if(dev == NULL) { + rslt = BMI160_E_NULL_PTR; + } else { + rslt = bmi160_get_regs(reg_addr, &data, BMI160_ONE, dev); + if(rslt == BMI160_OK) { + data = data | fifo_down; + rslt = bmi160_set_regs(reg_addr, &data, BMI160_ONE, dev); + } + } + + return rslt; +} + +/*! + * @brief This API sets the FIFO watermark level in the sensor. + * + */ +int8_t bmi160_set_fifo_wm(uint8_t fifo_wm, const struct bmi160_dev* dev) { + int8_t rslt = 0; + uint8_t data = fifo_wm; + uint8_t reg_addr = BMI160_FIFO_CONFIG_0_ADDR; + + /* Check the bmi160_dev structure for NULL address*/ + if(dev == NULL) { + rslt = BMI160_E_NULL_PTR; + } else { + rslt = bmi160_set_regs(reg_addr, &data, BMI160_ONE, dev); + } + + return rslt; +} + +/*! + * @brief This API parses and extracts the accelerometer frames from + * FIFO data read by the "bmi160_get_fifo_data" API and stores it in + * the "accel_data" structure instance. + */ +int8_t bmi160_extract_accel( + struct bmi160_sensor_data* accel_data, + uint8_t* accel_length, + struct bmi160_dev const* dev) { + int8_t rslt = 0; + uint16_t data_index = 0; + uint16_t data_read_length = 0; + uint8_t accel_index = 0; + uint8_t fifo_data_enable = 0; + + if(dev == NULL || dev->fifo == NULL || dev->fifo->data == NULL) { + rslt = BMI160_E_NULL_PTR; + } else { + /* Parsing the FIFO data in header-less mode */ + if(dev->fifo->fifo_header_enable == 0) { + /* Number of bytes to be parsed from FIFO */ + get_accel_len_to_parse(&data_index, &data_read_length, accel_length, dev); + for(; data_index < data_read_length;) { + /*Check for the availability of next two bytes of FIFO data */ + check_frame_validity(&data_index, dev); + fifo_data_enable = dev->fifo->fifo_data_enable; + unpack_accel_frame(accel_data, &data_index, &accel_index, fifo_data_enable, dev); + } + + /* update number of accel data read*/ + *accel_length = accel_index; + + /*update the accel byte index*/ + dev->fifo->accel_byte_start_idx = data_index; + } else { + /* Parsing the FIFO data in header mode */ + extract_accel_header_mode(accel_data, accel_length, dev); + } + } + + return rslt; +} + +/*! + * @brief This API parses and extracts the gyro frames from + * FIFO data read by the "bmi160_get_fifo_data" API and stores it in + * the "gyro_data" structure instance. + */ +int8_t bmi160_extract_gyro( + struct bmi160_sensor_data* gyro_data, + uint8_t* gyro_length, + struct bmi160_dev const* dev) { + int8_t rslt = 0; + uint16_t data_index = 0; + uint16_t data_read_length = 0; + uint8_t gyro_index = 0; + uint8_t fifo_data_enable = 0; + + if(dev == NULL || dev->fifo->data == NULL) { + rslt = BMI160_E_NULL_PTR; + } else { + /* Parsing the FIFO data in header-less mode */ + if(dev->fifo->fifo_header_enable == 0) { + /* Number of bytes to be parsed from FIFO */ + get_gyro_len_to_parse(&data_index, &data_read_length, gyro_length, dev); + for(; data_index < data_read_length;) { + /*Check for the availability of next two bytes of FIFO data */ + check_frame_validity(&data_index, dev); + fifo_data_enable = dev->fifo->fifo_data_enable; + unpack_gyro_frame(gyro_data, &data_index, &gyro_index, fifo_data_enable, dev); + } + + /* update number of gyro data read */ + *gyro_length = gyro_index; + + /* update the gyro byte index */ + dev->fifo->gyro_byte_start_idx = data_index; + } else { + /* Parsing the FIFO data in header mode */ + extract_gyro_header_mode(gyro_data, gyro_length, dev); + } + } + + return rslt; +} + +/*! + * @brief This API parses and extracts the aux frames from + * FIFO data read by the "bmi160_get_fifo_data" API and stores it in + * the "aux_data" structure instance. + */ +int8_t bmi160_extract_aux( + struct bmi160_aux_data* aux_data, + uint8_t* aux_len, + struct bmi160_dev const* dev) { + int8_t rslt = 0; + uint16_t data_index = 0; + uint16_t data_read_length = 0; + uint8_t aux_index = 0; + uint8_t fifo_data_enable = 0; + + if((dev == NULL) || (dev->fifo->data == NULL) || (aux_data == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + /* Parsing the FIFO data in header-less mode */ + if(dev->fifo->fifo_header_enable == 0) { + /* Number of bytes to be parsed from FIFO */ + get_aux_len_to_parse(&data_index, &data_read_length, aux_len, dev); + for(; data_index < data_read_length;) { + /* Check for the availability of next two + * bytes of FIFO data */ + check_frame_validity(&data_index, dev); + fifo_data_enable = dev->fifo->fifo_data_enable; + unpack_aux_frame(aux_data, &data_index, &aux_index, fifo_data_enable, dev); + } + + /* update number of aux data read */ + *aux_len = aux_index; + + /* update the aux byte index */ + dev->fifo->aux_byte_start_idx = data_index; + } else { + /* Parsing the FIFO data in header mode */ + extract_aux_header_mode(aux_data, aux_len, dev); + } + } + + return rslt; +} + +/*! + * @brief This API starts the FOC of accel and gyro + * + * @note FOC should not be used in low-power mode of sensor + * + * @note Accel FOC targets values of +1g , 0g , -1g + * Gyro FOC always targets value of 0 dps + */ +int8_t bmi160_start_foc( + const struct bmi160_foc_conf* foc_conf, + struct bmi160_offsets* offset, + struct bmi160_dev const* dev) { + int8_t rslt; + uint8_t data; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if(rslt != BMI160_OK) { + rslt = BMI160_E_NULL_PTR; + } else { + /* Set the offset enable bits */ + rslt = configure_offset_enable(foc_conf, dev); + if(rslt == BMI160_OK) { + /* Read the FOC config from the sensor */ + rslt = bmi160_get_regs(BMI160_FOC_CONF_ADDR, &data, 1, dev); + + /* Set the FOC config for gyro */ + data = BMI160_SET_BITS(data, BMI160_GYRO_FOC_EN, foc_conf->foc_gyr_en); + + /* Set the FOC config for accel xyz axes */ + data = BMI160_SET_BITS(data, BMI160_ACCEL_FOC_X_CONF, foc_conf->foc_acc_x); + data = BMI160_SET_BITS(data, BMI160_ACCEL_FOC_Y_CONF, foc_conf->foc_acc_y); + data = BMI160_SET_BITS_POS_0(data, BMI160_ACCEL_FOC_Z_CONF, foc_conf->foc_acc_z); + if(rslt == BMI160_OK) { + /* Set the FOC config in the sensor */ + rslt = bmi160_set_regs(BMI160_FOC_CONF_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + /* Procedure to trigger + * FOC and check status */ + rslt = trigger_foc(offset, dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This API reads and stores the offset values of accel and gyro + */ +int8_t bmi160_get_offsets(struct bmi160_offsets* offset, const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data[7]; + uint8_t lsb, msb; + int16_t offset_msb, offset_lsb; + int16_t offset_data; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if(rslt != BMI160_OK) { + rslt = BMI160_E_NULL_PTR; + } else { + /* Read the FOC config from the sensor */ + rslt = bmi160_get_regs(BMI160_OFFSET_ADDR, data, 7, dev); + + /* Accel offsets */ + offset->off_acc_x = (int8_t)data[0]; + offset->off_acc_y = (int8_t)data[1]; + offset->off_acc_z = (int8_t)data[2]; + + /* Gyro x-axis offset */ + lsb = data[3]; + msb = BMI160_GET_BITS_POS_0(data[6], BMI160_GYRO_OFFSET_X); + offset_msb = (int16_t)(msb << 14); + offset_lsb = lsb << 6; + offset_data = offset_msb | offset_lsb; + + /* Divide by 64 to get the Right shift by 6 value */ + offset->off_gyro_x = (int16_t)(offset_data / 64); + + /* Gyro y-axis offset */ + lsb = data[4]; + msb = BMI160_GET_BITS(data[6], BMI160_GYRO_OFFSET_Y); + offset_msb = (int16_t)(msb << 14); + offset_lsb = lsb << 6; + offset_data = offset_msb | offset_lsb; + + /* Divide by 64 to get the Right shift by 6 value */ + offset->off_gyro_y = (int16_t)(offset_data / 64); + + /* Gyro z-axis offset */ + lsb = data[5]; + msb = BMI160_GET_BITS(data[6], BMI160_GYRO_OFFSET_Z); + offset_msb = (int16_t)(msb << 14); + offset_lsb = lsb << 6; + offset_data = offset_msb | offset_lsb; + + /* Divide by 64 to get the Right shift by 6 value */ + offset->off_gyro_z = (int16_t)(offset_data / 64); + } + + return rslt; +} + +/*! + * @brief This API writes the offset values of accel and gyro to + * the sensor but these values will be reset on POR or soft reset. + */ +int8_t bmi160_set_offsets( + const struct bmi160_foc_conf* foc_conf, + const struct bmi160_offsets* offset, + struct bmi160_dev const* dev) { + int8_t rslt; + uint8_t data[7]; + uint8_t x_msb, y_msb, z_msb; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if(rslt != BMI160_OK) { + rslt = BMI160_E_NULL_PTR; + } else { + /* Update the accel offset */ + data[0] = (uint8_t)offset->off_acc_x; + data[1] = (uint8_t)offset->off_acc_y; + data[2] = (uint8_t)offset->off_acc_z; + + /* Update the LSB of gyro offset */ + data[3] = BMI160_GET_LSB(offset->off_gyro_x); + data[4] = BMI160_GET_LSB(offset->off_gyro_y); + data[5] = BMI160_GET_LSB(offset->off_gyro_z); + + /* Update the MSB of gyro offset */ + x_msb = BMI160_GET_BITS(offset->off_gyro_x, BMI160_GYRO_OFFSET); + y_msb = BMI160_GET_BITS(offset->off_gyro_y, BMI160_GYRO_OFFSET); + z_msb = BMI160_GET_BITS(offset->off_gyro_z, BMI160_GYRO_OFFSET); + data[6] = (uint8_t)(z_msb << 4 | y_msb << 2 | x_msb); + + /* Set the offset enable/disable for gyro and accel */ + data[6] = BMI160_SET_BITS(data[6], BMI160_GYRO_OFFSET_EN, foc_conf->gyro_off_en); + data[6] = BMI160_SET_BITS(data[6], BMI160_ACCEL_OFFSET_EN, foc_conf->acc_off_en); + + /* Set the offset config and values in the sensor */ + rslt = bmi160_set_regs(BMI160_OFFSET_ADDR, data, 7, dev); + } + + return rslt; +} + +/*! + * @brief This API writes the image registers values to NVM which is + * stored even after POR or soft reset + */ +int8_t bmi160_update_nvm(struct bmi160_dev const* dev) { + int8_t rslt; + uint8_t data; + uint8_t cmd = BMI160_NVM_BACKUP_EN; + + /* Read the nvm_prog_en configuration */ + rslt = bmi160_get_regs(BMI160_CONF_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + data = BMI160_SET_BITS(data, BMI160_NVM_UPDATE, 1); + + /* Set the nvm_prog_en bit in the sensor */ + rslt = bmi160_set_regs(BMI160_CONF_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + /* Update NVM */ + rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &cmd, 1, dev); + if(rslt == BMI160_OK) { + /* Check for NVM ready status */ + rslt = bmi160_get_regs(BMI160_STATUS_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + data = BMI160_GET_BITS(data, BMI160_NVM_STATUS); + if(data != BMI160_ENABLE) { + /* Delay to update NVM */ + dev->delay_ms(25); + } + } + } + } + } + + return rslt; +} + +/*! + * @brief This API gets the interrupt status from the sensor. + */ +int8_t bmi160_get_int_status( + enum bmi160_int_status_sel int_status_sel, + union bmi160_int_status* int_status, + struct bmi160_dev const* dev) { + int8_t rslt = 0; + + /* To get the status of all interrupts */ + if(int_status_sel == BMI160_INT_STATUS_ALL) { + rslt = bmi160_get_regs(BMI160_INT_STATUS_ADDR, &int_status->data[0], 4, dev); + } else { + if(int_status_sel & BMI160_INT_STATUS_0) { + rslt = bmi160_get_regs(BMI160_INT_STATUS_ADDR, &int_status->data[0], 1, dev); + } + + if(int_status_sel & BMI160_INT_STATUS_1) { + rslt = bmi160_get_regs(BMI160_INT_STATUS_ADDR + 1, &int_status->data[1], 1, dev); + } + + if(int_status_sel & BMI160_INT_STATUS_2) { + rslt = bmi160_get_regs(BMI160_INT_STATUS_ADDR + 2, &int_status->data[2], 1, dev); + } + + if(int_status_sel & BMI160_INT_STATUS_3) { + rslt = bmi160_get_regs(BMI160_INT_STATUS_ADDR + 3, &int_status->data[3], 1, dev); + } + } + + return rslt; +} + +/*********************** Local function definitions ***************************/ + +/*! + * @brief This API sets the any-motion interrupt of the sensor. + * This interrupt occurs when accel values exceeds preset threshold + * for a certain period of time. + */ +static int8_t + set_accel_any_motion_int(struct bmi160_int_settg* int_config, struct bmi160_dev* dev) { + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if((rslt != BMI160_OK) || (int_config == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg = + &(int_config->int_type_cfg.acc_any_motion_int); + rslt = enable_accel_any_motion_int(any_motion_int_cfg, dev); + if(rslt == BMI160_OK) { + rslt = config_any_motion_int_settg(int_config, any_motion_int_cfg, dev); + } + } + + return rslt; +} + +/*! + * @brief This API sets tap interrupts.Interrupt is fired when + * tap movements happen. + */ +static int8_t + set_accel_tap_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if((rslt != BMI160_OK) || (int_config == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_tap_int_cfg* tap_int_cfg = &(int_config->int_type_cfg.acc_tap_int); + rslt = enable_tap_int(int_config, tap_int_cfg, dev); + if(rslt == BMI160_OK) { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if(rslt == BMI160_OK) { + rslt = config_tap_int_settg(int_config, tap_int_cfg, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API sets the data ready interrupt for both accel and gyro. + * This interrupt occurs when new accel and gyro data comes. + */ +static int8_t set_accel_gyro_data_ready_int( + const struct bmi160_int_settg* int_config, + const struct bmi160_dev* dev) { + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if((rslt != BMI160_OK) || (int_config == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + rslt = enable_data_ready_int(dev); + if(rslt == BMI160_OK) { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if(rslt == BMI160_OK) { + rslt = map_hardware_interrupt(int_config, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API sets the significant motion interrupt of the sensor.This + * interrupt occurs when there is change in user location. + */ +static int8_t + set_accel_sig_motion_int(struct bmi160_int_settg* int_config, struct bmi160_dev* dev) { + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if((rslt != BMI160_OK) || (int_config == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg = + &(int_config->int_type_cfg.acc_sig_motion_int); + rslt = enable_sig_motion_int(sig_mot_int_cfg, dev); + if(rslt == BMI160_OK) { + rslt = config_sig_motion_int_settg(int_config, sig_mot_int_cfg, dev); + } + } + + return rslt; +} + +/*! + * @brief This API sets the no motion/slow motion interrupt of the sensor. + * Slow motion is similar to any motion interrupt.No motion interrupt + * occurs when slope bet. two accel values falls below preset threshold + * for preset duration. + */ +static int8_t + set_accel_no_motion_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if((rslt != BMI160_OK) || (int_config == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg = + &(int_config->int_type_cfg.acc_no_motion_int); + rslt = enable_no_motion_int(no_mot_int_cfg, dev); + if(rslt == BMI160_OK) { + /* Configure the INT PIN settings*/ + rslt = config_no_motion_int_settg(int_config, no_mot_int_cfg, dev); + } + } + + return rslt; +} + +/*! + * @brief This API sets the step detection interrupt.This interrupt + * occurs when the single step causes accel values to go above + * preset threshold. + */ +static int8_t + set_accel_step_detect_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if((rslt != BMI160_OK) || (int_config == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_step_detect_int_cfg* step_detect_int_cfg = + &(int_config->int_type_cfg.acc_step_detect_int); + rslt = enable_step_detect_int(step_detect_int_cfg, dev); + if(rslt == BMI160_OK) { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if(rslt == BMI160_OK) { + rslt = map_feature_interrupt(int_config, dev); + if(rslt == BMI160_OK) { + rslt = config_step_detect(step_detect_int_cfg, dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This API sets the orientation interrupt of the sensor.This + * interrupt occurs when there is orientation change in the sensor + * with respect to gravitational field vector g. + */ +static int8_t + set_accel_orientation_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if((rslt != BMI160_OK) || (int_config == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_orient_int_cfg* orient_int_cfg = + &(int_config->int_type_cfg.acc_orient_int); + rslt = enable_orient_int(orient_int_cfg, dev); + if(rslt == BMI160_OK) { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if(rslt == BMI160_OK) { + /* map INT pin to orient interrupt */ + rslt = map_feature_interrupt(int_config, dev); + if(rslt == BMI160_OK) { + /* configure the + * orientation setting*/ + rslt = config_orient_int_settg(orient_int_cfg, dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This API sets the flat interrupt of the sensor.This interrupt + * occurs in case of flat orientation + */ +static int8_t + set_accel_flat_detect_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if((rslt != BMI160_OK) || (int_config == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_flat_detect_int_cfg* flat_detect_int = + &(int_config->int_type_cfg.acc_flat_int); + + /* enable the flat interrupt */ + rslt = enable_flat_int(flat_detect_int, dev); + if(rslt == BMI160_OK) { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if(rslt == BMI160_OK) { + /* map INT pin to flat interrupt */ + rslt = map_feature_interrupt(int_config, dev); + if(rslt == BMI160_OK) { + /* configure the flat setting*/ + rslt = config_flat_int_settg(flat_detect_int, dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This API sets the low-g interrupt of the sensor.This interrupt + * occurs during free-fall. + */ +static int8_t + set_accel_low_g_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if((rslt != BMI160_OK) || (int_config == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_low_g_int_cfg* low_g_int = &(int_config->int_type_cfg.acc_low_g_int); + + /* Enable the low-g interrupt*/ + rslt = enable_low_g_int(low_g_int, dev); + if(rslt == BMI160_OK) { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if(rslt == BMI160_OK) { + /* Map INT pin to low-g interrupt */ + rslt = map_feature_interrupt(int_config, dev); + if(rslt == BMI160_OK) { + /* configure the data source + * for low-g interrupt*/ + rslt = config_low_g_data_src(low_g_int, dev); + if(rslt == BMI160_OK) { + rslt = config_low_g_int_settg(low_g_int, dev); + } + } + } + } + } + + return rslt; +} + +/*! + * @brief This API sets the high-g interrupt of the sensor.The interrupt + * occurs if the absolute value of acceleration data of any enabled axis + * exceeds the programmed threshold and the sign of the value does not + * change for a preset duration. + */ +static int8_t + set_accel_high_g_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if((rslt != BMI160_OK) || (int_config == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_high_g_int_cfg* high_g_int_cfg = + &(int_config->int_type_cfg.acc_high_g_int); + + /* Enable the high-g interrupt */ + rslt = enable_high_g_int(high_g_int_cfg, dev); + if(rslt == BMI160_OK) { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if(rslt == BMI160_OK) { + /* Map INT pin to high-g interrupt */ + rslt = map_feature_interrupt(int_config, dev); + if(rslt == BMI160_OK) { + /* configure the data source + * for high-g interrupt*/ + rslt = config_high_g_data_src(high_g_int_cfg, dev); + if(rslt == BMI160_OK) { + rslt = config_high_g_int_settg(high_g_int_cfg, dev); + } + } + } + } + } + + return rslt; +} + +/*! + * @brief This API configures the pins to fire the + * interrupt signal when it occurs. + */ +static int8_t + set_intr_pin_config(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { + int8_t rslt; + + /* configure the behavioural settings of interrupt pin */ + rslt = config_int_out_ctrl(int_config, dev); + if(rslt == BMI160_OK) { + rslt = config_int_latch(int_config, dev); + } + + return rslt; +} + +/*! + * @brief This internal API is used to validate the device structure pointer for + * null conditions. + */ +static int8_t null_ptr_check(const struct bmi160_dev* dev) { + int8_t rslt; + + if((dev == NULL) || (dev->read == NULL) || (dev->write == NULL) || (dev->delay_ms == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + /* Device structure is fine */ + rslt = BMI160_OK; + } + + return rslt; +} + +/*! + * @brief This API sets the default configuration parameters of accel & gyro. + * Also maintain the previous state of configurations. + */ +static void default_param_settg(struct bmi160_dev* dev) { + /* Initializing accel and gyro params with + * default values */ + dev->accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4; + dev->accel_cfg.odr = BMI160_ACCEL_ODR_100HZ; + dev->accel_cfg.power = BMI160_ACCEL_SUSPEND_MODE; + dev->accel_cfg.range = BMI160_ACCEL_RANGE_2G; + dev->gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE; + dev->gyro_cfg.odr = BMI160_GYRO_ODR_100HZ; + dev->gyro_cfg.power = BMI160_GYRO_SUSPEND_MODE; + dev->gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS; + + /* To maintain the previous state of accel configuration */ + dev->prev_accel_cfg = dev->accel_cfg; + + /* To maintain the previous state of gyro configuration */ + dev->prev_gyro_cfg = dev->gyro_cfg; +} + +/*! + * @brief This API set the accel configuration. + */ +static int8_t set_accel_conf(struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data[2] = {0}; + + rslt = check_accel_config(data, dev); + if(rslt == BMI160_OK) { + /* Write output data rate and bandwidth */ + rslt = bmi160_set_regs(BMI160_ACCEL_CONFIG_ADDR, &data[0], 1, dev); + if(rslt == BMI160_OK) { + dev->prev_accel_cfg.odr = dev->accel_cfg.odr; + dev->prev_accel_cfg.bw = dev->accel_cfg.bw; + + /* write accel range */ + rslt = bmi160_set_regs(BMI160_ACCEL_RANGE_ADDR, &data[1], 1, dev); + if(rslt == BMI160_OK) { + dev->prev_accel_cfg.range = dev->accel_cfg.range; + } + } + } + + return rslt; +} + +/*! + * @brief This API gets the accel configuration. + */ +static int8_t get_accel_conf(struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data[2] = {0}; + + /* Get accel configurations */ + rslt = bmi160_get_regs(BMI160_ACCEL_CONFIG_ADDR, data, 2, dev); + if(rslt == BMI160_OK) { + dev->accel_cfg.odr = (data[0] & BMI160_ACCEL_ODR_MASK); + dev->accel_cfg.bw = (data[0] & BMI160_ACCEL_BW_MASK) >> BMI160_ACCEL_BW_POS; + dev->accel_cfg.range = (data[1] & BMI160_ACCEL_RANGE_MASK); + } + + return rslt; +} + +/*! + * @brief This API check the accel configuration. + */ +static int8_t check_accel_config(uint8_t* data, const struct bmi160_dev* dev) { + int8_t rslt; + + /* read accel Output data rate and bandwidth */ + rslt = bmi160_get_regs(BMI160_ACCEL_CONFIG_ADDR, data, 2, dev); + if(rslt == BMI160_OK) { + rslt = process_accel_odr(&data[0], dev); + if(rslt == BMI160_OK) { + rslt = process_accel_bw(&data[0], dev); + if(rslt == BMI160_OK) { + rslt = process_accel_range(&data[1], dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API process the accel odr. + */ +static int8_t process_accel_odr(uint8_t* data, const struct bmi160_dev* dev) { + int8_t rslt = 0; + uint8_t temp = 0; + uint8_t odr = 0; + + if(dev->accel_cfg.odr <= BMI160_ACCEL_ODR_1600HZ) { + if(dev->accel_cfg.odr != dev->prev_accel_cfg.odr) { + odr = (uint8_t)dev->accel_cfg.odr; + temp = *data & ~BMI160_ACCEL_ODR_MASK; + + /* Adding output data rate */ + *data = temp | (odr & BMI160_ACCEL_ODR_MASK); + } + } else { + rslt = BMI160_E_OUT_OF_RANGE; + } + + return rslt; +} + +/*! + * @brief This API process the accel bandwidth. + */ +static int8_t process_accel_bw(uint8_t* data, const struct bmi160_dev* dev) { + int8_t rslt = 0; + uint8_t temp = 0; + uint8_t bw = 0; + + if(dev->accel_cfg.bw <= BMI160_ACCEL_BW_RES_AVG128) { + if(dev->accel_cfg.bw != dev->prev_accel_cfg.bw) { + bw = (uint8_t)dev->accel_cfg.bw; + temp = *data & ~BMI160_ACCEL_BW_MASK; + + /* Adding bandwidth */ + *data = temp | ((bw << 4) & BMI160_ACCEL_BW_MASK); + } + } else { + rslt = BMI160_E_OUT_OF_RANGE; + } + + return rslt; +} + +/*! + * @brief This API process the accel range. + */ +static int8_t process_accel_range(uint8_t* data, const struct bmi160_dev* dev) { + int8_t rslt = 0; + uint8_t temp = 0; + uint8_t range = 0; + + if(dev->accel_cfg.range <= BMI160_ACCEL_RANGE_16G) { + if(dev->accel_cfg.range != dev->prev_accel_cfg.range) { + range = (uint8_t)dev->accel_cfg.range; + temp = *data & ~BMI160_ACCEL_RANGE_MASK; + + /* Adding range */ + *data = temp | (range & BMI160_ACCEL_RANGE_MASK); + } + } else { + rslt = BMI160_E_OUT_OF_RANGE; + } + + return rslt; +} + +/*! + * @brief This API checks the invalid settings for ODR & Bw for + * Accel and Gyro. + */ +static int8_t check_invalid_settg(const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + + /* read the error reg */ + rslt = bmi160_get_regs(BMI160_ERROR_REG_ADDR, &data, 1, dev); + data = data >> 1; + data = data & BMI160_ERR_REG_MASK; + if(data == 1) { + rslt = BMI160_E_ACCEL_ODR_BW_INVALID; + } else if(data == 2) { + rslt = BMI160_E_GYRO_ODR_BW_INVALID; + } else if(data == 3) { + rslt = BMI160_E_LWP_PRE_FLTR_INT_INVALID; + } else if(data == 7) { + rslt = BMI160_E_LWP_PRE_FLTR_INVALID; + } + + return rslt; +} +static int8_t set_gyro_conf(struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data[2] = {0}; + + rslt = check_gyro_config(data, dev); + if(rslt == BMI160_OK) { + /* Write output data rate and bandwidth */ + rslt = bmi160_set_regs(BMI160_GYRO_CONFIG_ADDR, &data[0], 1, dev); + if(rslt == BMI160_OK) { + dev->prev_gyro_cfg.odr = dev->gyro_cfg.odr; + dev->prev_gyro_cfg.bw = dev->gyro_cfg.bw; + + /* Write gyro range */ + rslt = bmi160_set_regs(BMI160_GYRO_RANGE_ADDR, &data[1], 1, dev); + if(rslt == BMI160_OK) { + dev->prev_gyro_cfg.range = dev->gyro_cfg.range; + } + } + } + + return rslt; +} + +/*! + * @brief This API gets the gyro configuration. + */ +static int8_t get_gyro_conf(struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data[2] = {0}; + + /* Get accel configurations */ + rslt = bmi160_get_regs(BMI160_GYRO_CONFIG_ADDR, data, 2, dev); + if(rslt == BMI160_OK) { + dev->gyro_cfg.odr = (data[0] & BMI160_GYRO_ODR_MASK); + dev->gyro_cfg.bw = (data[0] & BMI160_GYRO_BW_MASK) >> BMI160_GYRO_BW_POS; + dev->gyro_cfg.range = (data[1] & BMI160_GYRO_RANGE_MASK); + } + + return rslt; +} + +/*! + * @brief This API check the gyro configuration. + */ +static int8_t check_gyro_config(uint8_t* data, const struct bmi160_dev* dev) { + int8_t rslt; + + /* read gyro Output data rate and bandwidth */ + rslt = bmi160_get_regs(BMI160_GYRO_CONFIG_ADDR, data, 2, dev); + if(rslt == BMI160_OK) { + rslt = process_gyro_odr(&data[0], dev); + if(rslt == BMI160_OK) { + rslt = process_gyro_bw(&data[0], dev); + if(rslt == BMI160_OK) { + rslt = process_gyro_range(&data[1], dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API process the gyro odr. + */ +static int8_t process_gyro_odr(uint8_t* data, const struct bmi160_dev* dev) { + int8_t rslt = 0; + uint8_t temp = 0; + uint8_t odr = 0; + + if(dev->gyro_cfg.odr <= BMI160_GYRO_ODR_3200HZ) { + if(dev->gyro_cfg.odr != dev->prev_gyro_cfg.odr) { + odr = (uint8_t)dev->gyro_cfg.odr; + temp = (*data & ~BMI160_GYRO_ODR_MASK); + + /* Adding output data rate */ + *data = temp | (odr & BMI160_GYRO_ODR_MASK); + } + } else { + rslt = BMI160_E_OUT_OF_RANGE; + } + + return rslt; +} + +/*! + * @brief This API process the gyro bandwidth. + */ +static int8_t process_gyro_bw(uint8_t* data, const struct bmi160_dev* dev) { + int8_t rslt = 0; + uint8_t temp = 0; + uint8_t bw = 0; + + if(dev->gyro_cfg.bw <= BMI160_GYRO_BW_NORMAL_MODE) { + bw = (uint8_t)dev->gyro_cfg.bw; + temp = *data & ~BMI160_GYRO_BW_MASK; + + /* Adding bandwidth */ + *data = temp | ((bw << 4) & BMI160_GYRO_BW_MASK); + } else { + rslt = BMI160_E_OUT_OF_RANGE; + } + + return rslt; +} + +/*! + * @brief This API process the gyro range. + */ +static int8_t process_gyro_range(uint8_t* data, const struct bmi160_dev* dev) { + int8_t rslt = 0; + uint8_t temp = 0; + uint8_t range = 0; + + if(dev->gyro_cfg.range <= BMI160_GYRO_RANGE_125_DPS) { + if(dev->gyro_cfg.range != dev->prev_gyro_cfg.range) { + range = (uint8_t)dev->gyro_cfg.range; + temp = *data & ~BMI160_GYRO_RANGE_MASK; + + /* Adding range */ + *data = temp | (range & BMI160_GYRO_RANGE_MASK); + } + } else { + rslt = BMI160_E_OUT_OF_RANGE; + } + + return rslt; +} + +/*! + * @brief This API sets the accel power. + */ +static int8_t set_accel_pwr(struct bmi160_dev* dev) { + int8_t rslt = 0; + uint8_t data = 0; + + if((dev->accel_cfg.power >= BMI160_ACCEL_SUSPEND_MODE) && + (dev->accel_cfg.power <= BMI160_ACCEL_LOWPOWER_MODE)) { + if(dev->accel_cfg.power != dev->prev_accel_cfg.power) { + rslt = process_under_sampling(&data, dev); + if(rslt == BMI160_OK) { + /* Write accel power */ + rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &dev->accel_cfg.power, 1, dev); + + /* Add delay of 3.8 ms - refer data sheet table 24*/ + if(dev->prev_accel_cfg.power == BMI160_ACCEL_SUSPEND_MODE) { + dev->delay_ms(BMI160_ACCEL_DELAY_MS); + } + + dev->prev_accel_cfg.power = dev->accel_cfg.power; + } + } + } else { + rslt = BMI160_E_INVALID_CONFIG; + } + + return rslt; +} + +/*! + * @brief This API process the undersampling setting of Accel. + */ +static int8_t process_under_sampling(uint8_t* data, const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t temp = 0; + uint8_t pre_filter[2] = {0}; + + rslt = bmi160_get_regs(BMI160_ACCEL_CONFIG_ADDR, data, 1, dev); + if(rslt == BMI160_OK) { + if(dev->accel_cfg.power == BMI160_ACCEL_LOWPOWER_MODE) { + temp = *data & ~BMI160_ACCEL_UNDERSAMPLING_MASK; + + /* Set under-sampling parameter */ + *data = temp | ((1 << 7) & BMI160_ACCEL_UNDERSAMPLING_MASK); + + /* Write data */ + rslt = bmi160_set_regs(BMI160_ACCEL_CONFIG_ADDR, data, 1, dev); + + /* Disable the pre-filter data in low power mode */ + if(rslt == BMI160_OK) { + /* Disable the Pre-filter data*/ + rslt = bmi160_set_regs(BMI160_INT_DATA_0_ADDR, pre_filter, 2, dev); + } + } else if(*data & BMI160_ACCEL_UNDERSAMPLING_MASK) { + temp = *data & ~BMI160_ACCEL_UNDERSAMPLING_MASK; + + /* Disable under-sampling parameter if already enabled */ + *data = temp; + + /* Write data */ + rslt = bmi160_set_regs(BMI160_ACCEL_CONFIG_ADDR, data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API sets the gyro power mode. + */ +static int8_t set_gyro_pwr(struct bmi160_dev* dev) { + int8_t rslt = 0; + + if((dev->gyro_cfg.power == BMI160_GYRO_SUSPEND_MODE) || + (dev->gyro_cfg.power == BMI160_GYRO_NORMAL_MODE) || + (dev->gyro_cfg.power == BMI160_GYRO_FASTSTARTUP_MODE)) { + if(dev->gyro_cfg.power != dev->prev_gyro_cfg.power) { + /* Write gyro power */ + rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &dev->gyro_cfg.power, 1, dev); + if(dev->prev_gyro_cfg.power == BMI160_GYRO_SUSPEND_MODE) { + /* Delay of 80 ms - datasheet Table 24 */ + dev->delay_ms(BMI160_GYRO_DELAY_MS); + } else if( + (dev->prev_gyro_cfg.power == BMI160_GYRO_FASTSTARTUP_MODE) && + (dev->gyro_cfg.power == BMI160_GYRO_NORMAL_MODE)) { + /* This delay is required for transition from + * fast-startup mode to normal mode - datasheet Table 3 */ + dev->delay_ms(10); + } else { + /* do nothing */ + } + + dev->prev_gyro_cfg.power = dev->gyro_cfg.power; + } + } else { + rslt = BMI160_E_INVALID_CONFIG; + } + + return rslt; +} + +/*! + * @brief This API reads accel data along with sensor time if time is requested + * by user. Kindly refer the user guide(README.md) for more info. + */ +static int8_t + get_accel_data(uint8_t len, struct bmi160_sensor_data* accel, const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t idx = 0; + uint8_t data_array[9] = {0}; + uint8_t time_0 = 0; + uint16_t time_1 = 0; + uint32_t time_2 = 0; + uint8_t lsb; + uint8_t msb; + int16_t msblsb; + + /* read accel sensor data along with time if requested */ + rslt = bmi160_get_regs(BMI160_ACCEL_DATA_ADDR, data_array, 6 + len, dev); + if(rslt == BMI160_OK) { + /* Accel Data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + accel->x = msblsb; /* Data in X axis */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + accel->y = msblsb; /* Data in Y axis */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + accel->z = msblsb; /* Data in Z axis */ + if(len == 3) { + time_0 = data_array[idx++]; + time_1 = (uint16_t)(data_array[idx++] << 8); + time_2 = (uint32_t)(data_array[idx++] << 16); + accel->sensortime = (uint32_t)(time_2 | time_1 | time_0); + } else { + accel->sensortime = 0; + } + } else { + rslt = BMI160_E_COM_FAIL; + } + + return rslt; +} + +/*! + * @brief This API reads accel data along with sensor time if time is requested + * by user. Kindly refer the user guide(README.md) for more info. + */ +static int8_t + get_gyro_data(uint8_t len, struct bmi160_sensor_data* gyro, const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t idx = 0; + uint8_t data_array[15] = {0}; + uint8_t time_0 = 0; + uint16_t time_1 = 0; + uint32_t time_2 = 0; + uint8_t lsb; + uint8_t msb; + int16_t msblsb; + + if(len == 0) { + /* read gyro data only */ + rslt = bmi160_get_regs(BMI160_GYRO_DATA_ADDR, data_array, 6, dev); + if(rslt == BMI160_OK) { + /* Gyro Data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->x = msblsb; /* Data in X axis */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->y = msblsb; /* Data in Y axis */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->z = msblsb; /* Data in Z axis */ + gyro->sensortime = 0; + } else { + rslt = BMI160_E_COM_FAIL; + } + } else { + /* read gyro sensor data along with time */ + rslt = bmi160_get_regs(BMI160_GYRO_DATA_ADDR, data_array, 12 + len, dev); + if(rslt == BMI160_OK) { + /* Gyro Data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->x = msblsb; /* gyro X axis data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->y = msblsb; /* gyro Y axis data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->z = msblsb; /* gyro Z axis data */ + idx = idx + 6; + time_0 = data_array[idx++]; + time_1 = (uint16_t)(data_array[idx++] << 8); + time_2 = (uint32_t)(data_array[idx++] << 16); + gyro->sensortime = (uint32_t)(time_2 | time_1 | time_0); + } else { + rslt = BMI160_E_COM_FAIL; + } + } + + return rslt; +} + +/*! + * @brief This API reads accel and gyro data along with sensor time + * if time is requested by user. + * Kindly refer the user guide(README.md) for more info. + */ +static int8_t get_accel_gyro_data( + uint8_t len, + struct bmi160_sensor_data* accel, + struct bmi160_sensor_data* gyro, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t idx = 0; + uint8_t data_array[15] = {0}; + uint8_t time_0 = 0; + uint16_t time_1 = 0; + uint32_t time_2 = 0; + uint8_t lsb; + uint8_t msb; + int16_t msblsb; + + /* read both accel and gyro sensor data + * along with time if requested */ + rslt = bmi160_get_regs(BMI160_GYRO_DATA_ADDR, data_array, 12 + len, dev); + if(rslt == BMI160_OK) { + /* Gyro Data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->x = msblsb; /* gyro X axis data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->y = msblsb; /* gyro Y axis data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->z = msblsb; /* gyro Z axis data */ + /* Accel Data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + accel->x = (int16_t)msblsb; /* accel X axis data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + accel->y = (int16_t)msblsb; /* accel Y axis data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + accel->z = (int16_t)msblsb; /* accel Z axis data */ + if(len == 3) { + time_0 = data_array[idx++]; + time_1 = (uint16_t)(data_array[idx++] << 8); + time_2 = (uint32_t)(data_array[idx++] << 16); + accel->sensortime = (uint32_t)(time_2 | time_1 | time_0); + gyro->sensortime = (uint32_t)(time_2 | time_1 | time_0); + } else { + accel->sensortime = 0; + gyro->sensortime = 0; + } + } else { + rslt = BMI160_E_COM_FAIL; + } + + return rslt; +} + +/*! + * @brief This API enables the any-motion interrupt for accel. + */ +static int8_t enable_accel_any_motion_int( + const struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg, + struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable any motion x, any motion y, any motion z + * in Int Enable 0 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + if(any_motion_int_cfg->anymotion_en == BMI160_ENABLE) { + temp = data & ~BMI160_ANY_MOTION_X_INT_EN_MASK; + + /* Adding Any_motion x axis */ + data = temp | (any_motion_int_cfg->anymotion_x & BMI160_ANY_MOTION_X_INT_EN_MASK); + temp = data & ~BMI160_ANY_MOTION_Y_INT_EN_MASK; + + /* Adding Any_motion y axis */ + data = temp | + ((any_motion_int_cfg->anymotion_y << 1) & BMI160_ANY_MOTION_Y_INT_EN_MASK); + temp = data & ~BMI160_ANY_MOTION_Z_INT_EN_MASK; + + /* Adding Any_motion z axis */ + data = temp | + ((any_motion_int_cfg->anymotion_z << 2) & BMI160_ANY_MOTION_Z_INT_EN_MASK); + + /* any-motion feature selected*/ + dev->any_sig_sel = BMI160_ANY_MOTION_ENABLED; + } else { + data = data & ~BMI160_ANY_MOTION_ALL_INT_EN_MASK; + + /* neither any-motion feature nor sig-motion selected */ + dev->any_sig_sel = BMI160_BOTH_ANY_SIG_MOTION_DISABLED; + } + + /* write data to Int Enable 0 register */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API disable the sig-motion interrupt. + */ +static int8_t disable_sig_motion_int(const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Disabling Significant motion interrupt if enabled */ + rslt = bmi160_get_regs(BMI160_INT_MOTION_3_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + temp = (data & BMI160_SIG_MOTION_SEL_MASK); + if(temp) { + temp = data & ~BMI160_SIG_MOTION_SEL_MASK; + data = temp; + + /* Write data to register */ + rslt = bmi160_set_regs(BMI160_INT_MOTION_3_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API is used to map/unmap the Any/Sig motion, Step det/Low-g, + * Double tap, Single tap, Orientation, Flat, High-G, Nomotion interrupt pins. + */ +static int8_t + map_feature_interrupt(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data[3] = {0, 0, 0}; + uint8_t temp[3] = {0, 0, 0}; + + rslt = bmi160_get_regs(BMI160_INT_MAP_0_ADDR, data, 3, dev); + if(rslt == BMI160_OK) { + temp[0] = data[0] & ~int_mask_lookup_table[int_config->int_type]; + temp[2] = data[2] & ~int_mask_lookup_table[int_config->int_type]; + switch(int_config->int_channel) { + case BMI160_INT_CHANNEL_NONE: + data[0] = temp[0]; + data[2] = temp[2]; + break; + case BMI160_INT_CHANNEL_1: + data[0] = temp[0] | int_mask_lookup_table[int_config->int_type]; + data[2] = temp[2]; + break; + case BMI160_INT_CHANNEL_2: + data[2] = temp[2] | int_mask_lookup_table[int_config->int_type]; + data[0] = temp[0]; + break; + case BMI160_INT_CHANNEL_BOTH: + data[0] = temp[0] | int_mask_lookup_table[int_config->int_type]; + data[2] = temp[2] | int_mask_lookup_table[int_config->int_type]; + break; + default: + rslt = BMI160_E_OUT_OF_RANGE; + } + if(rslt == BMI160_OK) { + rslt = bmi160_set_regs(BMI160_INT_MAP_0_ADDR, data, 3, dev); + } + } + + return rslt; +} + +/*! + * @brief This API is used to map/unmap the Dataready(Accel & Gyro), FIFO full + * and FIFO watermark interrupt. + */ +static int8_t map_hardware_interrupt( + const struct bmi160_int_settg* int_config, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + rslt = bmi160_get_regs(BMI160_INT_MAP_1_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + temp = data & ~int_mask_lookup_table[int_config->int_type]; + temp = temp & ~((uint8_t)(int_mask_lookup_table[int_config->int_type] << 4)); + switch(int_config->int_channel) { + case BMI160_INT_CHANNEL_NONE: + data = temp; + break; + case BMI160_INT_CHANNEL_1: + data = temp | (uint8_t)((int_mask_lookup_table[int_config->int_type]) << 4); + break; + case BMI160_INT_CHANNEL_2: + data = temp | int_mask_lookup_table[int_config->int_type]; + break; + case BMI160_INT_CHANNEL_BOTH: + data = temp | int_mask_lookup_table[int_config->int_type]; + data = data | (uint8_t)((int_mask_lookup_table[int_config->int_type]) << 4); + break; + default: + rslt = BMI160_E_OUT_OF_RANGE; + } + if(rslt == BMI160_OK) { + rslt = bmi160_set_regs(BMI160_INT_MAP_1_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for any-motion interrupt. + */ +static int8_t config_any_motion_src( + const struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Configure Int data 1 register to add source of interrupt */ + rslt = bmi160_get_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + temp = data & ~BMI160_MOTION_SRC_INT_MASK; + data = temp | ((any_motion_int_cfg->anymotion_data_src << 7) & BMI160_MOTION_SRC_INT_MASK); + + /* Write data to DATA 1 address */ + rslt = bmi160_set_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the duration and threshold of + * any-motion interrupt. + */ +static int8_t config_any_dur_threshold( + const struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + uint8_t data_array[2] = {0}; + uint8_t dur; + + /* Configure Int Motion 0 register */ + rslt = bmi160_get_regs(BMI160_INT_MOTION_0_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + /* slope duration */ + dur = (uint8_t)any_motion_int_cfg->anymotion_dur; + temp = data & ~BMI160_SLOPE_INT_DUR_MASK; + data = temp | (dur & BMI160_MOTION_SRC_INT_MASK); + data_array[0] = data; + + /* add slope threshold */ + data_array[1] = any_motion_int_cfg->anymotion_thr; + + /* INT MOTION 0 and INT MOTION 1 address lie consecutively, + * hence writing data to respective registers at one go */ + + /* Writing to Int_motion 0 and + * Int_motion 1 Address simultaneously */ + rslt = bmi160_set_regs(BMI160_INT_MOTION_0_ADDR, data_array, 2, dev); + } + + return rslt; +} + +/*! + * @brief This API configure necessary setting of any-motion interrupt. + */ +static int8_t config_any_motion_int_settg( + const struct bmi160_int_settg* int_config, + const struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if(rslt == BMI160_OK) { + rslt = disable_sig_motion_int(dev); + if(rslt == BMI160_OK) { + rslt = map_feature_interrupt(int_config, dev); + if(rslt == BMI160_OK) { + rslt = config_any_motion_src(any_motion_int_cfg, dev); + if(rslt == BMI160_OK) { + rslt = config_any_dur_threshold(any_motion_int_cfg, dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This API enable the data ready interrupt. + */ +static int8_t enable_data_ready_int(const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable data ready interrupt in Int Enable 1 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + temp = data & ~BMI160_DATA_RDY_INT_EN_MASK; + data = temp | ((1 << 4) & BMI160_DATA_RDY_INT_EN_MASK); + + /* Writing data to INT ENABLE 1 Address */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API enables the no motion/slow motion interrupt. + */ +static int8_t enable_no_motion_int( + const struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable no motion x, no motion y, no motion z + * in Int Enable 2 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_2_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + if(no_mot_int_cfg->no_motion_x == 1) { + temp = data & ~BMI160_NO_MOTION_X_INT_EN_MASK; + + /* Adding No_motion x axis */ + data = temp | (1 & BMI160_NO_MOTION_X_INT_EN_MASK); + } + + if(no_mot_int_cfg->no_motion_y == 1) { + temp = data & ~BMI160_NO_MOTION_Y_INT_EN_MASK; + + /* Adding No_motion x axis */ + data = temp | ((1 << 1) & BMI160_NO_MOTION_Y_INT_EN_MASK); + } + + if(no_mot_int_cfg->no_motion_z == 1) { + temp = data & ~BMI160_NO_MOTION_Z_INT_EN_MASK; + + /* Adding No_motion x axis */ + data = temp | ((1 << 2) & BMI160_NO_MOTION_Z_INT_EN_MASK); + } + + /* write data to Int Enable 2 register */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_2_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the interrupt PIN setting for + * no motion/slow motion interrupt. + */ +static int8_t config_no_motion_int_settg( + const struct bmi160_int_settg* int_config, + const struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if(rslt == BMI160_OK) { + rslt = map_feature_interrupt(int_config, dev); + if(rslt == BMI160_OK) { + rslt = config_no_motion_data_src(no_mot_int_cfg, dev); + if(rslt == BMI160_OK) { + rslt = config_no_motion_dur_thr(no_mot_int_cfg, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API configure the source of interrupt for no motion. + */ +static int8_t config_no_motion_data_src( + const struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Configure Int data 1 register to add source of interrupt */ + rslt = bmi160_get_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + temp = data & ~BMI160_MOTION_SRC_INT_MASK; + data = temp | ((no_mot_int_cfg->no_motion_src << 7) & BMI160_MOTION_SRC_INT_MASK); + + /* Write data to DATA 1 address */ + rslt = bmi160_set_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the duration and threshold of + * no motion/slow motion interrupt along with selection of no/slow motion. + */ +static int8_t config_no_motion_dur_thr( + const struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + uint8_t temp_1 = 0; + uint8_t reg_addr; + uint8_t data_array[2] = {0}; + + /* Configuring INT_MOTION register */ + reg_addr = BMI160_INT_MOTION_0_ADDR; + rslt = bmi160_get_regs(reg_addr, &data, 1, dev); + if(rslt == BMI160_OK) { + temp = data & ~BMI160_NO_MOTION_INT_DUR_MASK; + + /* Adding no_motion duration */ + data = temp | ((no_mot_int_cfg->no_motion_dur << 2) & BMI160_NO_MOTION_INT_DUR_MASK); + + /* Write data to NO_MOTION 0 address */ + rslt = bmi160_set_regs(reg_addr, &data, 1, dev); + if(rslt == BMI160_OK) { + reg_addr = BMI160_INT_MOTION_3_ADDR; + rslt = bmi160_get_regs(reg_addr, &data, 1, dev); + if(rslt == BMI160_OK) { + temp = data & ~BMI160_NO_MOTION_SEL_BIT_MASK; + + /* Adding no_motion_sel bit */ + temp_1 = (no_mot_int_cfg->no_motion_sel & BMI160_NO_MOTION_SEL_BIT_MASK); + data = (temp | temp_1); + data_array[1] = data; + + /* Adding no motion threshold */ + data_array[0] = no_mot_int_cfg->no_motion_thres; + reg_addr = BMI160_INT_MOTION_2_ADDR; + + /* writing data to INT_MOTION 2 and INT_MOTION 3 + * address simultaneously */ + rslt = bmi160_set_regs(reg_addr, data_array, 2, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API enables the sig-motion motion interrupt. + */ +static int8_t enable_sig_motion_int( + const struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg, + struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* For significant motion,enable any motion x,any motion y, + * any motion z in Int Enable 0 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + if(sig_mot_int_cfg->sig_en == BMI160_ENABLE) { + temp = data & ~BMI160_SIG_MOTION_INT_EN_MASK; + data = temp | (7 & BMI160_SIG_MOTION_INT_EN_MASK); + + /* sig-motion feature selected*/ + dev->any_sig_sel = BMI160_SIG_MOTION_ENABLED; + } else { + data = data & ~BMI160_SIG_MOTION_INT_EN_MASK; + + /* neither any-motion feature nor sig-motion selected */ + dev->any_sig_sel = BMI160_BOTH_ANY_SIG_MOTION_DISABLED; + } + + /* write data to Int Enable 0 register */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the interrupt PIN setting for + * significant motion interrupt. + */ +static int8_t config_sig_motion_int_settg( + const struct bmi160_int_settg* int_config, + const struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if(rslt == BMI160_OK) { + rslt = map_feature_interrupt(int_config, dev); + if(rslt == BMI160_OK) { + rslt = config_sig_motion_data_src(sig_mot_int_cfg, dev); + if(rslt == BMI160_OK) { + rslt = config_sig_dur_threshold(sig_mot_int_cfg, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for sig motion interrupt. + */ +static int8_t config_sig_motion_data_src( + const struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Configure Int data 1 register to add source of interrupt */ + rslt = bmi160_get_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + temp = data & ~BMI160_MOTION_SRC_INT_MASK; + data = temp | ((sig_mot_int_cfg->sig_data_src << 7) & BMI160_MOTION_SRC_INT_MASK); + + /* Write data to DATA 1 address */ + rslt = bmi160_set_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the threshold, skip and proof time of + * sig motion interrupt. + */ +static int8_t config_sig_dur_threshold( + const struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data; + uint8_t temp = 0; + + /* Configuring INT_MOTION registers */ + + /* Write significant motion threshold. + * This threshold is same as any motion threshold */ + data = sig_mot_int_cfg->sig_mot_thres; + + /* Write data to INT_MOTION 1 address */ + rslt = bmi160_set_regs(BMI160_INT_MOTION_1_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + rslt = bmi160_get_regs(BMI160_INT_MOTION_3_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + temp = data & ~BMI160_SIG_MOTION_SKIP_MASK; + + /* adding skip time of sig_motion interrupt*/ + data = temp | ((sig_mot_int_cfg->sig_mot_skip << 2) & BMI160_SIG_MOTION_SKIP_MASK); + temp = data & ~BMI160_SIG_MOTION_PROOF_MASK; + + /* adding proof time of sig_motion interrupt */ + data = temp | ((sig_mot_int_cfg->sig_mot_proof << 4) & BMI160_SIG_MOTION_PROOF_MASK); + + /* configure the int_sig_mot_sel bit to select + * significant motion interrupt */ + temp = data & ~BMI160_SIG_MOTION_SEL_MASK; + data = temp | ((sig_mot_int_cfg->sig_en << 1) & BMI160_SIG_MOTION_SEL_MASK); + rslt = bmi160_set_regs(BMI160_INT_MOTION_3_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API enables the step detector interrupt. + */ +static int8_t enable_step_detect_int( + const struct bmi160_acc_step_detect_int_cfg* step_detect_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable data ready interrupt in Int Enable 2 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_2_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + temp = data & ~BMI160_STEP_DETECT_INT_EN_MASK; + data = temp | + ((step_detect_int_cfg->step_detector_en << 3) & BMI160_STEP_DETECT_INT_EN_MASK); + + /* Writing data to INT ENABLE 2 Address */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_2_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the step detector parameter. + */ +static int8_t config_step_detect( + const struct bmi160_acc_step_detect_int_cfg* step_detect_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t temp = 0; + uint8_t data_array[2] = {0}; + + if(step_detect_int_cfg->step_detector_mode == BMI160_STEP_DETECT_NORMAL) { + /* Normal mode setting */ + data_array[0] = 0x15; + data_array[1] = 0x03; + } else if(step_detect_int_cfg->step_detector_mode == BMI160_STEP_DETECT_SENSITIVE) { + /* Sensitive mode setting */ + data_array[0] = 0x2D; + data_array[1] = 0x00; + } else if(step_detect_int_cfg->step_detector_mode == BMI160_STEP_DETECT_ROBUST) { + /* Robust mode setting */ + data_array[0] = 0x1D; + data_array[1] = 0x07; + } else if(step_detect_int_cfg->step_detector_mode == BMI160_STEP_DETECT_USER_DEFINE) { + /* Non recommended User defined setting */ + /* Configuring STEP_CONFIG register */ + rslt = bmi160_get_regs(BMI160_INT_STEP_CONFIG_0_ADDR, &data_array[0], 2, dev); + if(rslt == BMI160_OK) { + temp = data_array[0] & ~BMI160_STEP_DETECT_MIN_THRES_MASK; + + /* Adding min_threshold */ + data_array[0] = temp | ((step_detect_int_cfg->min_threshold << 3) & + BMI160_STEP_DETECT_MIN_THRES_MASK); + temp = data_array[0] & ~BMI160_STEP_DETECT_STEPTIME_MIN_MASK; + + /* Adding steptime_min */ + data_array[0] = temp | ((step_detect_int_cfg->steptime_min) & + BMI160_STEP_DETECT_STEPTIME_MIN_MASK); + temp = data_array[1] & ~BMI160_STEP_MIN_BUF_MASK; + + /* Adding steptime_min */ + data_array[1] = temp | + ((step_detect_int_cfg->step_min_buf) & BMI160_STEP_MIN_BUF_MASK); + } + } + + /* Write data to STEP_CONFIG register */ + rslt = bmi160_set_regs(BMI160_INT_STEP_CONFIG_0_ADDR, data_array, 2, dev); + + return rslt; +} + +/*! + * @brief This API enables the single/double tap interrupt. + */ +static int8_t enable_tap_int( + const struct bmi160_int_settg* int_config, + const struct bmi160_acc_tap_int_cfg* tap_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable single tap or double tap interrupt in Int Enable 0 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + if(int_config->int_type == BMI160_ACC_SINGLE_TAP_INT) { + temp = data & ~BMI160_SINGLE_TAP_INT_EN_MASK; + data = temp | ((tap_int_cfg->tap_en << 5) & BMI160_SINGLE_TAP_INT_EN_MASK); + } else { + temp = data & ~BMI160_DOUBLE_TAP_INT_EN_MASK; + data = temp | ((tap_int_cfg->tap_en << 4) & BMI160_DOUBLE_TAP_INT_EN_MASK); + } + + /* Write to Enable 0 Address */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the interrupt PIN setting for + * tap interrupt. + */ +static int8_t config_tap_int_settg( + const struct bmi160_int_settg* int_config, + const struct bmi160_acc_tap_int_cfg* tap_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if(rslt == BMI160_OK) { + rslt = map_feature_interrupt(int_config, dev); + if(rslt == BMI160_OK) { + rslt = config_tap_data_src(tap_int_cfg, dev); + if(rslt == BMI160_OK) { + rslt = config_tap_param(int_config, tap_int_cfg, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for tap interrupt. + */ +static int8_t config_tap_data_src( + const struct bmi160_acc_tap_int_cfg* tap_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Configure Int data 0 register to add source of interrupt */ + rslt = bmi160_get_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + temp = data & ~BMI160_TAP_SRC_INT_MASK; + data = temp | ((tap_int_cfg->tap_data_src << 3) & BMI160_TAP_SRC_INT_MASK); + + /* Write data to Data 0 address */ + rslt = bmi160_set_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the parameters of tap interrupt. + * Threshold, quite, shock, and duration. + */ +static int8_t config_tap_param( + const struct bmi160_int_settg* int_config, + const struct bmi160_acc_tap_int_cfg* tap_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t temp = 0; + uint8_t data = 0; + uint8_t data_array[2] = {0}; + uint8_t count = 0; + uint8_t dur, shock, quiet, thres; + + /* Configure tap 0 register for tap shock,tap quiet duration + * in case of single tap interrupt */ + rslt = bmi160_get_regs(BMI160_INT_TAP_0_ADDR, data_array, 2, dev); + if(rslt == BMI160_OK) { + data = data_array[count]; + if(int_config->int_type == BMI160_ACC_DOUBLE_TAP_INT) { + dur = (uint8_t)tap_int_cfg->tap_dur; + temp = (data & ~BMI160_TAP_DUR_MASK); + + /* Add tap duration data in case of + * double tap interrupt */ + data = temp | (dur & BMI160_TAP_DUR_MASK); + } + + shock = (uint8_t)tap_int_cfg->tap_shock; + temp = data & ~BMI160_TAP_SHOCK_DUR_MASK; + data = temp | ((shock << 6) & BMI160_TAP_SHOCK_DUR_MASK); + quiet = (uint8_t)tap_int_cfg->tap_quiet; + temp = data & ~BMI160_TAP_QUIET_DUR_MASK; + data = temp | ((quiet << 7) & BMI160_TAP_QUIET_DUR_MASK); + data_array[count++] = data; + data = data_array[count]; + thres = (uint8_t)tap_int_cfg->tap_thr; + temp = data & ~BMI160_TAP_THRES_MASK; + data = temp | (thres & BMI160_TAP_THRES_MASK); + data_array[count++] = data; + + /* TAP 0 and TAP 1 address lie consecutively, + * hence writing data to respective registers at one go */ + + /* Writing to Tap 0 and Tap 1 Address simultaneously */ + rslt = bmi160_set_regs(BMI160_INT_TAP_0_ADDR, data_array, count, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the secondary interface. + */ +static int8_t config_sec_if(const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t if_conf = 0; + uint8_t cmd = BMI160_AUX_NORMAL_MODE; + + /* set the aux power mode to normal*/ + rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &cmd, 1, dev); + if(rslt == BMI160_OK) { + /* 0.5ms delay - refer datasheet table 24*/ + dev->delay_ms(1); + rslt = bmi160_get_regs(BMI160_IF_CONF_ADDR, &if_conf, 1, dev); + if_conf |= (uint8_t)(1 << 5); + if(rslt == BMI160_OK) { + /*enable the secondary interface also*/ + rslt = bmi160_set_regs(BMI160_IF_CONF_ADDR, &if_conf, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API configure the ODR of the auxiliary sensor. + */ +static int8_t config_aux_odr(const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t aux_odr; + + rslt = bmi160_get_regs(BMI160_AUX_ODR_ADDR, &aux_odr, 1, dev); + if(rslt == BMI160_OK) { + aux_odr = (uint8_t)(dev->aux_cfg.aux_odr); + + /* Set the secondary interface ODR + * i.e polling rate of secondary sensor */ + rslt = bmi160_set_regs(BMI160_AUX_ODR_ADDR, &aux_odr, 1, dev); + dev->delay_ms(BMI160_AUX_COM_DELAY); + } + + return rslt; +} + +/*! + * @brief This API maps the actual burst read length set by user. + */ +static int8_t map_read_len(uint16_t* len, const struct bmi160_dev* dev) { + int8_t rslt = BMI160_OK; + + switch(dev->aux_cfg.aux_rd_burst_len) { + case BMI160_AUX_READ_LEN_0: + *len = 1; + break; + case BMI160_AUX_READ_LEN_1: + *len = 2; + break; + case BMI160_AUX_READ_LEN_2: + *len = 6; + break; + case BMI160_AUX_READ_LEN_3: + *len = 8; + break; + default: + rslt = BMI160_E_INVALID_INPUT; + break; + } + + return rslt; +} + +/*! + * @brief This API configure the settings of auxiliary sensor. + */ +static int8_t config_aux_settg(const struct bmi160_dev* dev) { + int8_t rslt; + + rslt = config_sec_if(dev); + if(rslt == BMI160_OK) { + /* Configures the auxiliary interface settings */ + rslt = bmi160_config_aux_mode(dev); + } + + return rslt; +} + +/*! + * @brief This API extract the read data from auxiliary sensor. + */ +static int8_t extract_aux_read( + uint16_t map_len, + uint8_t reg_addr, + uint8_t* aux_data, + uint16_t len, + const struct bmi160_dev* dev) { + int8_t rslt = BMI160_OK; + uint8_t data[8] = { + 0, + }; + uint8_t read_addr = BMI160_AUX_DATA_ADDR; + uint8_t count = 0; + uint8_t read_count; + uint8_t read_len = (uint8_t)map_len; + + for(; count < len;) { + /* set address to read */ + rslt = bmi160_set_regs(BMI160_AUX_IF_2_ADDR, ®_addr, 1, dev); + dev->delay_ms(BMI160_AUX_COM_DELAY); + if(rslt == BMI160_OK) { + rslt = bmi160_get_regs(read_addr, data, map_len, dev); + if(rslt == BMI160_OK) { + read_count = 0; + + /* if read len is less the burst read len + * mention by user*/ + if(len < map_len) { + read_len = (uint8_t)len; + } else if((len - count) < map_len) { + read_len = (uint8_t)(len - count); + } + + for(; read_count < read_len; read_count++) { + aux_data[count + read_count] = data[read_count]; + } + + reg_addr += (uint8_t)map_len; + count += (uint8_t)map_len; + } else { + rslt = BMI160_E_COM_FAIL; + break; + } + } + } + + return rslt; +} + +/*! + * @brief This API enables the orient interrupt. + */ +static int8_t enable_orient_int( + const struct bmi160_acc_orient_int_cfg* orient_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable data ready interrupt in Int Enable 0 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + temp = data & ~BMI160_ORIENT_INT_EN_MASK; + data = temp | ((orient_int_cfg->orient_en << 6) & BMI160_ORIENT_INT_EN_MASK); + + /* write data to Int Enable 0 register */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the necessary setting of orientation interrupt. + */ +static int8_t config_orient_int_settg( + const struct bmi160_acc_orient_int_cfg* orient_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + uint8_t data_array[2] = {0, 0}; + + /* Configuring INT_ORIENT registers */ + rslt = bmi160_get_regs(BMI160_INT_ORIENT_0_ADDR, data_array, 2, dev); + if(rslt == BMI160_OK) { + data = data_array[0]; + temp = data & ~BMI160_ORIENT_MODE_MASK; + + /* Adding Orientation mode */ + data = temp | ((orient_int_cfg->orient_mode) & BMI160_ORIENT_MODE_MASK); + temp = data & ~BMI160_ORIENT_BLOCK_MASK; + + /* Adding Orientation blocking */ + data = temp | ((orient_int_cfg->orient_blocking << 2) & BMI160_ORIENT_BLOCK_MASK); + temp = data & ~BMI160_ORIENT_HYST_MASK; + + /* Adding Orientation hysteresis */ + data = temp | ((orient_int_cfg->orient_hyst << 4) & BMI160_ORIENT_HYST_MASK); + data_array[0] = data; + data = data_array[1]; + temp = data & ~BMI160_ORIENT_THETA_MASK; + + /* Adding Orientation threshold */ + data = temp | ((orient_int_cfg->orient_theta) & BMI160_ORIENT_THETA_MASK); + temp = data & ~BMI160_ORIENT_UD_ENABLE; + + /* Adding Orient_ud_en */ + data = temp | ((orient_int_cfg->orient_ud_en << 6) & BMI160_ORIENT_UD_ENABLE); + temp = data & ~BMI160_AXES_EN_MASK; + + /* Adding axes_en */ + data = temp | ((orient_int_cfg->axes_ex << 7) & BMI160_AXES_EN_MASK); + data_array[1] = data; + + /* Writing data to INT_ORIENT 0 and INT_ORIENT 1 + * registers simultaneously */ + rslt = bmi160_set_regs(BMI160_INT_ORIENT_0_ADDR, data_array, 2, dev); + } + + return rslt; +} + +/*! + * @brief This API enables the flat interrupt. + */ +static int8_t enable_flat_int( + const struct bmi160_acc_flat_detect_int_cfg* flat_int, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable flat interrupt in Int Enable 0 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + temp = data & ~BMI160_FLAT_INT_EN_MASK; + data = temp | ((flat_int->flat_en << 7) & BMI160_FLAT_INT_EN_MASK); + + /* write data to Int Enable 0 register */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the necessary setting of flat interrupt. + */ +static int8_t config_flat_int_settg( + const struct bmi160_acc_flat_detect_int_cfg* flat_int, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + uint8_t data_array[2] = {0, 0}; + + /* Configuring INT_FLAT register */ + rslt = bmi160_get_regs(BMI160_INT_FLAT_0_ADDR, data_array, 2, dev); + if(rslt == BMI160_OK) { + data = data_array[0]; + temp = data & ~BMI160_FLAT_THRES_MASK; + + /* Adding flat theta */ + data = temp | ((flat_int->flat_theta) & BMI160_FLAT_THRES_MASK); + data_array[0] = data; + data = data_array[1]; + temp = data & ~BMI160_FLAT_HOLD_TIME_MASK; + + /* Adding flat hold time */ + data = temp | ((flat_int->flat_hold_time << 4) & BMI160_FLAT_HOLD_TIME_MASK); + temp = data & ~BMI160_FLAT_HYST_MASK; + + /* Adding flat hysteresis */ + data = temp | ((flat_int->flat_hy) & BMI160_FLAT_HYST_MASK); + data_array[1] = data; + + /* Writing data to INT_FLAT 0 and INT_FLAT 1 + * registers simultaneously */ + rslt = bmi160_set_regs(BMI160_INT_FLAT_0_ADDR, data_array, 2, dev); + } + + return rslt; +} + +/*! + * @brief This API enables the Low-g interrupt. + */ +static int8_t enable_low_g_int( + const struct bmi160_acc_low_g_int_cfg* low_g_int, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable low-g interrupt in Int Enable 1 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + temp = data & ~BMI160_LOW_G_INT_EN_MASK; + data = temp | ((low_g_int->low_en << 3) & BMI160_LOW_G_INT_EN_MASK); + + /* write data to Int Enable 0 register */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for low-g interrupt. + */ +static int8_t config_low_g_data_src( + const struct bmi160_acc_low_g_int_cfg* low_g_int, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Configure Int data 0 register to add source of interrupt */ + rslt = bmi160_get_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + temp = data & ~BMI160_LOW_HIGH_SRC_INT_MASK; + data = temp | ((low_g_int->low_data_src << 7) & BMI160_LOW_HIGH_SRC_INT_MASK); + + /* Write data to Data 0 address */ + rslt = bmi160_set_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the necessary setting of low-g interrupt. + */ +static int8_t config_low_g_int_settg( + const struct bmi160_acc_low_g_int_cfg* low_g_int, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t temp = 0; + uint8_t data_array[3] = {0, 0, 0}; + + /* Configuring INT_LOWHIGH register for low-g interrupt */ + rslt = bmi160_get_regs(BMI160_INT_LOWHIGH_2_ADDR, &data_array[2], 1, dev); + if(rslt == BMI160_OK) { + temp = data_array[2] & ~BMI160_LOW_G_HYST_MASK; + + /* Adding low-g hysteresis */ + data_array[2] = temp | (low_g_int->low_hyst & BMI160_LOW_G_HYST_MASK); + temp = data_array[2] & ~BMI160_LOW_G_LOW_MODE_MASK; + + /* Adding low-mode */ + data_array[2] = temp | ((low_g_int->low_mode << 2) & BMI160_LOW_G_LOW_MODE_MASK); + + /* Adding low-g threshold */ + data_array[1] = low_g_int->low_thres; + + /* Adding low-g interrupt delay */ + data_array[0] = low_g_int->low_dur; + + /* Writing data to INT_LOWHIGH 0,1,2 registers simultaneously*/ + rslt = bmi160_set_regs(BMI160_INT_LOWHIGH_0_ADDR, data_array, 3, dev); + } + + return rslt; +} + +/*! + * @brief This API enables the high-g interrupt. + */ +static int8_t enable_high_g_int( + const struct bmi160_acc_high_g_int_cfg* high_g_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable low-g interrupt in Int Enable 1 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + /* Adding high-g X-axis */ + temp = data & ~BMI160_HIGH_G_X_INT_EN_MASK; + data = temp | (high_g_int_cfg->high_g_x & BMI160_HIGH_G_X_INT_EN_MASK); + + /* Adding high-g Y-axis */ + temp = data & ~BMI160_HIGH_G_Y_INT_EN_MASK; + data = temp | ((high_g_int_cfg->high_g_y << 1) & BMI160_HIGH_G_Y_INT_EN_MASK); + + /* Adding high-g Z-axis */ + temp = data & ~BMI160_HIGH_G_Z_INT_EN_MASK; + data = temp | ((high_g_int_cfg->high_g_z << 2) & BMI160_HIGH_G_Z_INT_EN_MASK); + + /* write data to Int Enable 0 register */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for high-g interrupt. + */ +static int8_t config_high_g_data_src( + const struct bmi160_acc_high_g_int_cfg* high_g_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Configure Int data 0 register to add source of interrupt */ + rslt = bmi160_get_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + temp = data & ~BMI160_LOW_HIGH_SRC_INT_MASK; + data = temp | ((high_g_int_cfg->high_data_src << 7) & BMI160_LOW_HIGH_SRC_INT_MASK); + + /* Write data to Data 0 address */ + rslt = bmi160_set_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the necessary setting of high-g interrupt. + */ +static int8_t config_high_g_int_settg( + const struct bmi160_acc_high_g_int_cfg* high_g_int_cfg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t temp = 0; + uint8_t data_array[3] = {0, 0, 0}; + + rslt = bmi160_get_regs(BMI160_INT_LOWHIGH_2_ADDR, &data_array[0], 1, dev); + if(rslt == BMI160_OK) { + temp = data_array[0] & ~BMI160_HIGH_G_HYST_MASK; + + /* Adding high-g hysteresis */ + data_array[0] = temp | ((high_g_int_cfg->high_hy << 6) & BMI160_HIGH_G_HYST_MASK); + + /* Adding high-g duration */ + data_array[1] = high_g_int_cfg->high_dur; + + /* Adding high-g threshold */ + data_array[2] = high_g_int_cfg->high_thres; + rslt = bmi160_set_regs(BMI160_INT_LOWHIGH_2_ADDR, data_array, 3, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the behavioural setting of interrupt pin. + */ +static int8_t + config_int_out_ctrl(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t temp = 0; + uint8_t data = 0; + + /* Configuration of output interrupt signals on pins INT1 and INT2 are + * done in BMI160_INT_OUT_CTRL_ADDR register*/ + rslt = bmi160_get_regs(BMI160_INT_OUT_CTRL_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + /* updating the interrupt pin structure to local structure */ + const struct bmi160_int_pin_settg* intr_pin_sett = &(int_config->int_pin_settg); + + /* Configuring channel 1 */ + if(int_config->int_channel == BMI160_INT_CHANNEL_1) { + /* Output enable */ + temp = data & ~BMI160_INT1_OUTPUT_EN_MASK; + data = temp | ((intr_pin_sett->output_en << 3) & BMI160_INT1_OUTPUT_EN_MASK); + + /* Output mode */ + temp = data & ~BMI160_INT1_OUTPUT_MODE_MASK; + data = temp | ((intr_pin_sett->output_mode << 2) & BMI160_INT1_OUTPUT_MODE_MASK); + + /* Output type */ + temp = data & ~BMI160_INT1_OUTPUT_TYPE_MASK; + data = temp | ((intr_pin_sett->output_type << 1) & BMI160_INT1_OUTPUT_TYPE_MASK); + + /* edge control */ + temp = data & ~BMI160_INT1_EDGE_CTRL_MASK; + data = temp | ((intr_pin_sett->edge_ctrl) & BMI160_INT1_EDGE_CTRL_MASK); + } else { + /* Configuring channel 2 */ + /* Output enable */ + temp = data & ~BMI160_INT2_OUTPUT_EN_MASK; + data = temp | ((intr_pin_sett->output_en << 7) & BMI160_INT2_OUTPUT_EN_MASK); + + /* Output mode */ + temp = data & ~BMI160_INT2_OUTPUT_MODE_MASK; + data = temp | ((intr_pin_sett->output_mode << 6) & BMI160_INT2_OUTPUT_MODE_MASK); + + /* Output type */ + temp = data & ~BMI160_INT2_OUTPUT_TYPE_MASK; + data = temp | ((intr_pin_sett->output_type << 5) & BMI160_INT2_OUTPUT_TYPE_MASK); + + /* edge control */ + temp = data & ~BMI160_INT2_EDGE_CTRL_MASK; + data = temp | ((intr_pin_sett->edge_ctrl << 4) & BMI160_INT2_EDGE_CTRL_MASK); + } + + rslt = bmi160_set_regs(BMI160_INT_OUT_CTRL_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the mode(input enable, latch or non-latch) of interrupt pin. + */ +static int8_t + config_int_latch(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t temp = 0; + uint8_t data = 0; + + /* Configuration of latch on pins INT1 and INT2 are done in + * BMI160_INT_LATCH_ADDR register*/ + rslt = bmi160_get_regs(BMI160_INT_LATCH_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + /* updating the interrupt pin structure to local structure */ + const struct bmi160_int_pin_settg* intr_pin_sett = &(int_config->int_pin_settg); + if(int_config->int_channel == BMI160_INT_CHANNEL_1) { + /* Configuring channel 1 */ + /* Input enable */ + temp = data & ~BMI160_INT1_INPUT_EN_MASK; + data = temp | ((intr_pin_sett->input_en << 4) & BMI160_INT1_INPUT_EN_MASK); + } else { + /* Configuring channel 2 */ + /* Input enable */ + temp = data & ~BMI160_INT2_INPUT_EN_MASK; + data = temp | ((intr_pin_sett->input_en << 5) & BMI160_INT2_INPUT_EN_MASK); + } + + /* In case of latch interrupt,update the latch duration */ + + /* Latching holds the interrupt for the amount of latch + * duration time */ + temp = data & ~BMI160_INT_LATCH_MASK; + data = temp | (intr_pin_sett->latch_dur & BMI160_INT_LATCH_MASK); + + /* OUT_CTRL_INT and LATCH_INT address lie consecutively, + * hence writing data to respective registers at one go */ + rslt = bmi160_set_regs(BMI160_INT_LATCH_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API performs the self test for accelerometer of BMI160 + */ +static int8_t perform_accel_self_test(struct bmi160_dev* dev) { + int8_t rslt; + struct bmi160_sensor_data accel_pos, accel_neg; + + /* Enable Gyro self test bit */ + rslt = enable_accel_self_test(dev); + if(rslt == BMI160_OK) { + /* Perform accel self test with positive excitation */ + rslt = accel_self_test_positive_excitation(&accel_pos, dev); + if(rslt == BMI160_OK) { + /* Perform accel self test with negative excitation */ + rslt = accel_self_test_negative_excitation(&accel_neg, dev); + if(rslt == BMI160_OK) { + /* Validate the self test result */ + rslt = validate_accel_self_test(&accel_pos, &accel_neg); + } + } + } + + return rslt; +} + +/*! + * @brief This API enables to perform the accel self test by setting proper + * configurations to facilitate accel self test + */ +static int8_t enable_accel_self_test(struct bmi160_dev* dev) { + int8_t rslt; + uint8_t reg_data; + + /* Set the Accel power mode as normal mode */ + dev->accel_cfg.power = BMI160_ACCEL_NORMAL_MODE; + + /* Set the sensor range configuration as 8G */ + dev->accel_cfg.range = BMI160_ACCEL_RANGE_8G; + rslt = bmi160_set_sens_conf(dev); + if(rslt == BMI160_OK) { + /* Accel configurations are set to facilitate self test + * acc_odr - 1600Hz ; acc_bwp = 2 ; acc_us = 0 */ + reg_data = BMI160_ACCEL_SELF_TEST_CONFIG; + rslt = bmi160_set_regs(BMI160_ACCEL_CONFIG_ADDR, ®_data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API performs accel self test with positive excitation + */ +static int8_t accel_self_test_positive_excitation( + struct bmi160_sensor_data* accel_pos, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t reg_data; + + /* Enable accel self test with positive self-test excitation + * and with amplitude of deflection set as high */ + reg_data = BMI160_ACCEL_SELF_TEST_POSITIVE_EN; + rslt = bmi160_set_regs(BMI160_SELF_TEST_ADDR, ®_data, 1, dev); + if(rslt == BMI160_OK) { + /* Read the data after a delay of 50ms - refer datasheet 2.8.1 accel self test*/ + dev->delay_ms(BMI160_ACCEL_SELF_TEST_DELAY); + rslt = bmi160_get_sensor_data(BMI160_ACCEL_ONLY, accel_pos, NULL, dev); + } + + return rslt; +} + +/*! + * @brief This API performs accel self test with negative excitation + */ +static int8_t accel_self_test_negative_excitation( + struct bmi160_sensor_data* accel_neg, + const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t reg_data; + + /* Enable accel self test with negative self-test excitation + * and with amplitude of deflection set as high */ + reg_data = BMI160_ACCEL_SELF_TEST_NEGATIVE_EN; + rslt = bmi160_set_regs(BMI160_SELF_TEST_ADDR, ®_data, 1, dev); + if(rslt == BMI160_OK) { + /* Read the data after a delay of 50ms */ + dev->delay_ms(BMI160_ACCEL_SELF_TEST_DELAY); + rslt = bmi160_get_sensor_data(BMI160_ACCEL_ONLY, accel_neg, NULL, dev); + } + + return rslt; +} + +/*! + * @brief This API validates the accel self test results + */ +static int8_t validate_accel_self_test( + const struct bmi160_sensor_data* accel_pos, + const struct bmi160_sensor_data* accel_neg) { + int8_t rslt; + + /* Validate the results of self test */ + if(((accel_neg->x - accel_pos->x) > BMI160_ACCEL_SELF_TEST_LIMIT) && + ((accel_neg->y - accel_pos->y) > BMI160_ACCEL_SELF_TEST_LIMIT) && + ((accel_neg->z - accel_pos->z) > BMI160_ACCEL_SELF_TEST_LIMIT)) { + /* Self test pass condition */ + rslt = BMI160_OK; + } else { + rslt = BMI160_W_ACCEl_SELF_TEST_FAIL; + } + + return rslt; +} + +/*! + * @brief This API performs the self test for gyroscope of BMI160 + */ +static int8_t perform_gyro_self_test(const struct bmi160_dev* dev) { + int8_t rslt; + + /* Enable Gyro self test bit */ + rslt = enable_gyro_self_test(dev); + if(rslt == BMI160_OK) { + /* Validate the gyro self test a delay of 50ms */ + dev->delay_ms(50); + + /* Validate the gyro self test results */ + rslt = validate_gyro_self_test(dev); + } + + return rslt; +} + +/*! + * @brief This API enables the self test bit to trigger self test for Gyro + */ +static int8_t enable_gyro_self_test(const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t reg_data; + + /* Enable the Gyro self test bit to trigger the self test */ + rslt = bmi160_get_regs(BMI160_SELF_TEST_ADDR, ®_data, 1, dev); + if(rslt == BMI160_OK) { + reg_data = BMI160_SET_BITS(reg_data, BMI160_GYRO_SELF_TEST, 1); + rslt = bmi160_set_regs(BMI160_SELF_TEST_ADDR, ®_data, 1, dev); + if(rslt == BMI160_OK) { + /* Delay to enable gyro self test */ + dev->delay_ms(15); + } + } + + return rslt; +} + +/*! + * @brief This API validates the self test results of Gyro + */ +static int8_t validate_gyro_self_test(const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t reg_data; + + /* Validate the Gyro self test result */ + rslt = bmi160_get_regs(BMI160_STATUS_ADDR, ®_data, 1, dev); + if(rslt == BMI160_OK) { + reg_data = BMI160_GET_BITS(reg_data, BMI160_GYRO_SELF_TEST_STATUS); + if(reg_data == BMI160_ENABLE) { + /* Gyro self test success case */ + rslt = BMI160_OK; + } else { + rslt = BMI160_W_GYRO_SELF_TEST_FAIL; + } + } + + return rslt; +} + +/*! + * @brief This API sets FIFO full interrupt of the sensor.This interrupt + * occurs when the FIFO is full and the next full data sample would cause + * a FIFO overflow, which may delete the old samples. + */ +static int8_t + set_fifo_full_int(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { + int8_t rslt = BMI160_OK; + + /* Null-pointer check */ + if((dev == NULL) || (dev->delay_ms == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + /*enable the fifo full interrupt */ + rslt = enable_fifo_full_int(int_config, dev); + if(rslt == BMI160_OK) { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if(rslt == BMI160_OK) { + rslt = map_hardware_interrupt(int_config, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This enable the FIFO full interrupt engine. + */ +static int8_t + enable_fifo_full_int(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + + rslt = bmi160_get_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + data = BMI160_SET_BITS(data, BMI160_FIFO_FULL_INT, int_config->fifo_full_int_en); + + /* Writing data to INT ENABLE 1 Address */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API sets FIFO watermark interrupt of the sensor.The FIFO + * watermark interrupt is fired, when the FIFO fill level is above a fifo + * watermark. + */ +static int8_t set_fifo_watermark_int( + const struct bmi160_int_settg* int_config, + const struct bmi160_dev* dev) { + int8_t rslt = BMI160_OK; + + if((dev == NULL) || (dev->delay_ms == NULL)) { + rslt = BMI160_E_NULL_PTR; + } else { + /* Enable fifo-watermark interrupt in Int Enable 1 register */ + rslt = enable_fifo_wtm_int(int_config, dev); + if(rslt == BMI160_OK) { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if(rslt == BMI160_OK) { + rslt = map_hardware_interrupt(int_config, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This enable the FIFO watermark interrupt engine. + */ +static int8_t + enable_fifo_wtm_int(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { + int8_t rslt; + uint8_t data = 0; + + rslt = bmi160_get_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + data = BMI160_SET_BITS(data, BMI160_FIFO_WTM_INT, int_config->fifo_wtm_int_en); + + /* Writing data to INT ENABLE 1 Address */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API is used to reset the FIFO related configurations + * in the fifo_frame structure. + */ +static void reset_fifo_data_structure(const struct bmi160_dev* dev) { + /*Prepare for next FIFO read by resetting FIFO's + * internal data structures*/ + dev->fifo->accel_byte_start_idx = 0; + dev->fifo->gyro_byte_start_idx = 0; + dev->fifo->aux_byte_start_idx = 0; + dev->fifo->sensor_time = 0; + dev->fifo->skipped_frame_count = 0; +} + +/*! + * @brief This API is used to read fifo_byte_counter value (i.e) + * current fill-level in Fifo buffer. + */ +static int8_t get_fifo_byte_counter(uint16_t* bytes_to_read, struct bmi160_dev const* dev) { + int8_t rslt = 0; + uint8_t data[2]; + uint8_t addr = BMI160_FIFO_LENGTH_ADDR; + + rslt |= bmi160_get_regs(addr, data, 2, dev); + data[1] = data[1] & BMI160_FIFO_BYTE_COUNTER_MASK; + + /* Available data in FIFO is stored in bytes_to_read*/ + *bytes_to_read = (((uint16_t)data[1] << 8) | ((uint16_t)data[0])); + + return rslt; +} + +/*! + * @brief This API is used to compute the number of bytes of accel FIFO data + * which is to be parsed in header-less mode + */ +static void get_accel_len_to_parse( + uint16_t* data_index, + uint16_t* data_read_length, + const uint8_t* acc_frame_count, + const struct bmi160_dev* dev) { + /* Data start index */ + *data_index = dev->fifo->accel_byte_start_idx; + if(dev->fifo->fifo_data_enable == BMI160_FIFO_A_ENABLE) { + *data_read_length = (*acc_frame_count) * BMI160_FIFO_A_LENGTH; + } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_G_A_ENABLE) { + *data_read_length = (*acc_frame_count) * BMI160_FIFO_GA_LENGTH; + } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_M_A_ENABLE) { + *data_read_length = (*acc_frame_count) * BMI160_FIFO_MA_LENGTH; + } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_M_G_A_ENABLE) { + *data_read_length = (*acc_frame_count) * BMI160_FIFO_MGA_LENGTH; + } else { + /* When accel is not enabled ,there will be no accel data. + * so we update the data index as complete */ + *data_index = dev->fifo->length; + } + + if(*data_read_length > dev->fifo->length) { + /* Handling the case where more data is requested + * than that is available*/ + *data_read_length = dev->fifo->length; + } +} + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data in both header mode and header-less mode. + * It updates the idx value which is used to store the index of + * the current data byte which is parsed. + */ +static void unpack_accel_frame( + struct bmi160_sensor_data* acc, + uint16_t* idx, + uint8_t* acc_idx, + uint8_t frame_info, + const struct bmi160_dev* dev) { + switch(frame_info) { + case BMI160_FIFO_HEAD_A: + case BMI160_FIFO_A_ENABLE: + + /*Partial read, then skip the data*/ + if((*idx + BMI160_FIFO_A_LENGTH) > dev->fifo->length) { + /*Update the data index as complete*/ + *idx = dev->fifo->length; + break; + } + + /*Unpack the data array into the structure instance "acc" */ + unpack_accel_data(&acc[*acc_idx], *idx, dev); + + /*Move the data index*/ + *idx = *idx + BMI160_FIFO_A_LENGTH; + (*acc_idx)++; + break; + case BMI160_FIFO_HEAD_G_A: + case BMI160_FIFO_G_A_ENABLE: + + /*Partial read, then skip the data*/ + if((*idx + BMI160_FIFO_GA_LENGTH) > dev->fifo->length) { + /*Update the data index as complete*/ + *idx = dev->fifo->length; + break; + } + + /*Unpack the data array into structure instance "acc"*/ + unpack_accel_data(&acc[*acc_idx], *idx + BMI160_FIFO_G_LENGTH, dev); + + /*Move the data index*/ + *idx = *idx + BMI160_FIFO_GA_LENGTH; + (*acc_idx)++; + break; + case BMI160_FIFO_HEAD_M_A: + case BMI160_FIFO_M_A_ENABLE: + + /*Partial read, then skip the data*/ + if((*idx + BMI160_FIFO_MA_LENGTH) > dev->fifo->length) { + /*Update the data index as complete*/ + *idx = dev->fifo->length; + break; + } + + /*Unpack the data array into structure instance "acc"*/ + unpack_accel_data(&acc[*acc_idx], *idx + BMI160_FIFO_M_LENGTH, dev); + + /*Move the data index*/ + *idx = *idx + BMI160_FIFO_MA_LENGTH; + (*acc_idx)++; + break; + case BMI160_FIFO_HEAD_M_G_A: + case BMI160_FIFO_M_G_A_ENABLE: + + /*Partial read, then skip the data*/ + if((*idx + BMI160_FIFO_MGA_LENGTH) > dev->fifo->length) { + /*Update the data index as complete*/ + *idx = dev->fifo->length; + break; + } + + /*Unpack the data array into structure instance "acc"*/ + unpack_accel_data(&acc[*acc_idx], *idx + BMI160_FIFO_MG_LENGTH, dev); + + /*Move the data index*/ + *idx = *idx + BMI160_FIFO_MGA_LENGTH; + (*acc_idx)++; + break; + case BMI160_FIFO_HEAD_M: + case BMI160_FIFO_M_ENABLE: + (*idx) = (*idx) + BMI160_FIFO_M_LENGTH; + break; + case BMI160_FIFO_HEAD_G: + case BMI160_FIFO_G_ENABLE: + (*idx) = (*idx) + BMI160_FIFO_G_LENGTH; + break; + case BMI160_FIFO_HEAD_M_G: + case BMI160_FIFO_M_G_ENABLE: + (*idx) = (*idx) + BMI160_FIFO_MG_LENGTH; + break; + default: + break; + } +} + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data and store it in the instance of the structure bmi160_sensor_data. + */ +static void unpack_accel_data( + struct bmi160_sensor_data* accel_data, + uint16_t data_start_index, + const struct bmi160_dev* dev) { + uint16_t data_lsb; + uint16_t data_msb; + + /* Accel raw x data */ + data_lsb = dev->fifo->data[data_start_index++]; + data_msb = dev->fifo->data[data_start_index++]; + accel_data->x = (int16_t)((data_msb << 8) | data_lsb); + + /* Accel raw y data */ + data_lsb = dev->fifo->data[data_start_index++]; + data_msb = dev->fifo->data[data_start_index++]; + accel_data->y = (int16_t)((data_msb << 8) | data_lsb); + + /* Accel raw z data */ + data_lsb = dev->fifo->data[data_start_index++]; + data_msb = dev->fifo->data[data_start_index++]; + accel_data->z = (int16_t)((data_msb << 8) | data_lsb); +} + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data in header mode. + */ +static void extract_accel_header_mode( + struct bmi160_sensor_data* accel_data, + uint8_t* accel_length, + const struct bmi160_dev* dev) { + uint8_t frame_header = 0; + uint16_t data_index; + uint8_t accel_index = 0; + + for(data_index = dev->fifo->accel_byte_start_idx; data_index < dev->fifo->length;) { + /* extracting Frame header */ + frame_header = (dev->fifo->data[data_index] & BMI160_FIFO_TAG_INTR_MASK); + + /*Index is moved to next byte where the data is starting*/ + data_index++; + switch(frame_header) { + /* Accel frame */ + case BMI160_FIFO_HEAD_A: + case BMI160_FIFO_HEAD_M_A: + case BMI160_FIFO_HEAD_G_A: + case BMI160_FIFO_HEAD_M_G_A: + unpack_accel_frame(accel_data, &data_index, &accel_index, frame_header, dev); + break; + case BMI160_FIFO_HEAD_M: + move_next_frame(&data_index, BMI160_FIFO_M_LENGTH, dev); + break; + case BMI160_FIFO_HEAD_G: + move_next_frame(&data_index, BMI160_FIFO_G_LENGTH, dev); + break; + case BMI160_FIFO_HEAD_M_G: + move_next_frame(&data_index, BMI160_FIFO_MG_LENGTH, dev); + break; + + /* Sensor time frame */ + case BMI160_FIFO_HEAD_SENSOR_TIME: + unpack_sensortime_frame(&data_index, dev); + break; + + /* Skip frame */ + case BMI160_FIFO_HEAD_SKIP_FRAME: + unpack_skipped_frame(&data_index, dev); + break; + + /* Input config frame */ + case BMI160_FIFO_HEAD_INPUT_CONFIG: + move_next_frame(&data_index, 1, dev); + break; + case BMI160_FIFO_HEAD_OVER_READ: + + /* Update the data index as complete in case of Over read */ + data_index = dev->fifo->length; + break; + default: + break; + } + if(*accel_length == accel_index) { + /* Number of frames to read completed */ + break; + } + } + + /*Update number of accel data read*/ + *accel_length = accel_index; + + /*Update the accel frame index*/ + dev->fifo->accel_byte_start_idx = data_index; +} + +/*! + * @brief This API computes the number of bytes of gyro FIFO data + * which is to be parsed in header-less mode + */ +static void get_gyro_len_to_parse( + uint16_t* data_index, + uint16_t* data_read_length, + const uint8_t* gyro_frame_count, + const struct bmi160_dev* dev) { + /* Data start index */ + *data_index = dev->fifo->gyro_byte_start_idx; + if(dev->fifo->fifo_data_enable == BMI160_FIFO_G_ENABLE) { + *data_read_length = (*gyro_frame_count) * BMI160_FIFO_G_LENGTH; + } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_G_A_ENABLE) { + *data_read_length = (*gyro_frame_count) * BMI160_FIFO_GA_LENGTH; + } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_M_G_ENABLE) { + *data_read_length = (*gyro_frame_count) * BMI160_FIFO_MG_LENGTH; + } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_M_G_A_ENABLE) { + *data_read_length = (*gyro_frame_count) * BMI160_FIFO_MGA_LENGTH; + } else { + /* When gyro is not enabled ,there will be no gyro data. + * so we update the data index as complete */ + *data_index = dev->fifo->length; + } + + if(*data_read_length > dev->fifo->length) { + /* Handling the case where more data is requested + * than that is available*/ + *data_read_length = dev->fifo->length; + } +} + +/*! + * @brief This API is used to parse the gyroscope's data from the + * FIFO data in both header mode and header-less mode. + * It updates the idx value which is used to store the index of + * the current data byte which is parsed. + */ +static void unpack_gyro_frame( + struct bmi160_sensor_data* gyro, + uint16_t* idx, + uint8_t* gyro_idx, + uint8_t frame_info, + const struct bmi160_dev* dev) { + switch(frame_info) { + case BMI160_FIFO_HEAD_G: + case BMI160_FIFO_G_ENABLE: + + /*Partial read, then skip the data*/ + if((*idx + BMI160_FIFO_G_LENGTH) > dev->fifo->length) { + /*Update the data index as complete*/ + *idx = dev->fifo->length; + break; + } + + /*Unpack the data array into structure instance "gyro"*/ + unpack_gyro_data(&gyro[*gyro_idx], *idx, dev); + + /*Move the data index*/ + (*idx) = (*idx) + BMI160_FIFO_G_LENGTH; + (*gyro_idx)++; + break; + case BMI160_FIFO_HEAD_G_A: + case BMI160_FIFO_G_A_ENABLE: + + /*Partial read, then skip the data*/ + if((*idx + BMI160_FIFO_GA_LENGTH) > dev->fifo->length) { + /*Update the data index as complete*/ + *idx = dev->fifo->length; + break; + } + + /* Unpack the data array into structure instance "gyro" */ + unpack_gyro_data(&gyro[*gyro_idx], *idx, dev); + + /* Move the data index */ + *idx = *idx + BMI160_FIFO_GA_LENGTH; + (*gyro_idx)++; + break; + case BMI160_FIFO_HEAD_M_G_A: + case BMI160_FIFO_M_G_A_ENABLE: + + /*Partial read, then skip the data*/ + if((*idx + BMI160_FIFO_MGA_LENGTH) > dev->fifo->length) { + /*Update the data index as complete*/ + *idx = dev->fifo->length; + break; + } + + /*Unpack the data array into structure instance "gyro"*/ + unpack_gyro_data(&gyro[*gyro_idx], *idx + BMI160_FIFO_M_LENGTH, dev); + + /*Move the data index*/ + *idx = *idx + BMI160_FIFO_MGA_LENGTH; + (*gyro_idx)++; + break; + case BMI160_FIFO_HEAD_M_A: + case BMI160_FIFO_M_A_ENABLE: + + /* Move the data index */ + *idx = *idx + BMI160_FIFO_MA_LENGTH; + break; + case BMI160_FIFO_HEAD_M: + case BMI160_FIFO_M_ENABLE: + (*idx) = (*idx) + BMI160_FIFO_M_LENGTH; + break; + case BMI160_FIFO_HEAD_M_G: + case BMI160_FIFO_M_G_ENABLE: + + /*Partial read, then skip the data*/ + if((*idx + BMI160_FIFO_MG_LENGTH) > dev->fifo->length) { + /*Update the data index as complete*/ + *idx = dev->fifo->length; + break; + } + + /*Unpack the data array into structure instance "gyro"*/ + unpack_gyro_data(&gyro[*gyro_idx], *idx + BMI160_FIFO_M_LENGTH, dev); + + /*Move the data index*/ + (*idx) = (*idx) + BMI160_FIFO_MG_LENGTH; + (*gyro_idx)++; + break; + case BMI160_FIFO_HEAD_A: + case BMI160_FIFO_A_ENABLE: + + /*Move the data index*/ + *idx = *idx + BMI160_FIFO_A_LENGTH; + break; + default: + break; + } +} + +/*! + * @brief This API is used to parse the gyro data from the + * FIFO data and store it in the instance of the structure bmi160_sensor_data. + */ +static void unpack_gyro_data( + struct bmi160_sensor_data* gyro_data, + uint16_t data_start_index, + const struct bmi160_dev* dev) { + uint16_t data_lsb; + uint16_t data_msb; + + /* Gyro raw x data */ + data_lsb = dev->fifo->data[data_start_index++]; + data_msb = dev->fifo->data[data_start_index++]; + gyro_data->x = (int16_t)((data_msb << 8) | data_lsb); + + /* Gyro raw y data */ + data_lsb = dev->fifo->data[data_start_index++]; + data_msb = dev->fifo->data[data_start_index++]; + gyro_data->y = (int16_t)((data_msb << 8) | data_lsb); + + /* Gyro raw z data */ + data_lsb = dev->fifo->data[data_start_index++]; + data_msb = dev->fifo->data[data_start_index++]; + gyro_data->z = (int16_t)((data_msb << 8) | data_lsb); +} + +/*! + * @brief This API is used to parse the gyro data from the + * FIFO data in header mode. + */ +static void extract_gyro_header_mode( + struct bmi160_sensor_data* gyro_data, + uint8_t* gyro_length, + const struct bmi160_dev* dev) { + uint8_t frame_header = 0; + uint16_t data_index; + uint8_t gyro_index = 0; + + for(data_index = dev->fifo->gyro_byte_start_idx; data_index < dev->fifo->length;) { + /* extracting Frame header */ + frame_header = (dev->fifo->data[data_index] & BMI160_FIFO_TAG_INTR_MASK); + + /*Index is moved to next byte where the data is starting*/ + data_index++; + switch(frame_header) { + /* GYRO frame */ + case BMI160_FIFO_HEAD_G: + case BMI160_FIFO_HEAD_G_A: + case BMI160_FIFO_HEAD_M_G: + case BMI160_FIFO_HEAD_M_G_A: + unpack_gyro_frame(gyro_data, &data_index, &gyro_index, frame_header, dev); + break; + case BMI160_FIFO_HEAD_A: + move_next_frame(&data_index, BMI160_FIFO_A_LENGTH, dev); + break; + case BMI160_FIFO_HEAD_M: + move_next_frame(&data_index, BMI160_FIFO_M_LENGTH, dev); + break; + case BMI160_FIFO_HEAD_M_A: + move_next_frame(&data_index, BMI160_FIFO_M_LENGTH, dev); + break; + + /* Sensor time frame */ + case BMI160_FIFO_HEAD_SENSOR_TIME: + unpack_sensortime_frame(&data_index, dev); + break; + + /* Skip frame */ + case BMI160_FIFO_HEAD_SKIP_FRAME: + unpack_skipped_frame(&data_index, dev); + break; + + /* Input config frame */ + case BMI160_FIFO_HEAD_INPUT_CONFIG: + move_next_frame(&data_index, 1, dev); + break; + case BMI160_FIFO_HEAD_OVER_READ: + + /* Update the data index as complete in case of over read */ + data_index = dev->fifo->length; + break; + default: + break; + } + if(*gyro_length == gyro_index) { + /*Number of frames to read completed*/ + break; + } + } + + /*Update number of gyro data read*/ + *gyro_length = gyro_index; + + /*Update the gyro frame index*/ + dev->fifo->gyro_byte_start_idx = data_index; +} + +/*! + * @brief This API computes the number of bytes of aux FIFO data + * which is to be parsed in header-less mode + */ +static void get_aux_len_to_parse( + uint16_t* data_index, + uint16_t* data_read_length, + const uint8_t* aux_frame_count, + const struct bmi160_dev* dev) { + /* Data start index */ + *data_index = dev->fifo->gyro_byte_start_idx; + if(dev->fifo->fifo_data_enable == BMI160_FIFO_M_ENABLE) { + *data_read_length = (*aux_frame_count) * BMI160_FIFO_M_LENGTH; + } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_M_A_ENABLE) { + *data_read_length = (*aux_frame_count) * BMI160_FIFO_MA_LENGTH; + } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_M_G_ENABLE) { + *data_read_length = (*aux_frame_count) * BMI160_FIFO_MG_LENGTH; + } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_M_G_A_ENABLE) { + *data_read_length = (*aux_frame_count) * BMI160_FIFO_MGA_LENGTH; + } else { + /* When aux is not enabled ,there will be no aux data. + * so we update the data index as complete */ + *data_index = dev->fifo->length; + } + + if(*data_read_length > dev->fifo->length) { + /* Handling the case where more data is requested + * than that is available */ + *data_read_length = dev->fifo->length; + } +} + +/*! + * @brief This API is used to parse the aux's data from the + * FIFO data in both header mode and header-less mode. + * It updates the idx value which is used to store the index of + * the current data byte which is parsed + */ +static void unpack_aux_frame( + struct bmi160_aux_data* aux_data, + uint16_t* idx, + uint8_t* aux_index, + uint8_t frame_info, + const struct bmi160_dev* dev) { + switch(frame_info) { + case BMI160_FIFO_HEAD_M: + case BMI160_FIFO_M_ENABLE: + + /* Partial read, then skip the data */ + if((*idx + BMI160_FIFO_M_LENGTH) > dev->fifo->length) { + /* Update the data index as complete */ + *idx = dev->fifo->length; + break; + } + + /* Unpack the data array into structure instance */ + unpack_aux_data(&aux_data[*aux_index], *idx, dev); + + /* Move the data index */ + *idx = *idx + BMI160_FIFO_M_LENGTH; + (*aux_index)++; + break; + case BMI160_FIFO_HEAD_M_A: + case BMI160_FIFO_M_A_ENABLE: + + /* Partial read, then skip the data */ + if((*idx + BMI160_FIFO_MA_LENGTH) > dev->fifo->length) { + /* Update the data index as complete */ + *idx = dev->fifo->length; + break; + } + + /* Unpack the data array into structure instance */ + unpack_aux_data(&aux_data[*aux_index], *idx, dev); + + /* Move the data index */ + *idx = *idx + BMI160_FIFO_MA_LENGTH; + (*aux_index)++; + break; + case BMI160_FIFO_HEAD_M_G: + case BMI160_FIFO_M_G_ENABLE: + + /* Partial read, then skip the data */ + if((*idx + BMI160_FIFO_MG_LENGTH) > dev->fifo->length) { + /* Update the data index as complete */ + *idx = dev->fifo->length; + break; + } + + /* Unpack the data array into structure instance */ + unpack_aux_data(&aux_data[*aux_index], *idx, dev); + + /* Move the data index */ + (*idx) = (*idx) + BMI160_FIFO_MG_LENGTH; + (*aux_index)++; + break; + case BMI160_FIFO_HEAD_M_G_A: + case BMI160_FIFO_M_G_A_ENABLE: + + /*Partial read, then skip the data*/ + if((*idx + BMI160_FIFO_MGA_LENGTH) > dev->fifo->length) { + /* Update the data index as complete */ + *idx = dev->fifo->length; + break; + } + + /* Unpack the data array into structure instance */ + unpack_aux_data(&aux_data[*aux_index], *idx, dev); + + /*Move the data index*/ + *idx = *idx + BMI160_FIFO_MGA_LENGTH; + (*aux_index)++; + break; + case BMI160_FIFO_HEAD_G: + case BMI160_FIFO_G_ENABLE: + + /* Move the data index */ + (*idx) = (*idx) + BMI160_FIFO_G_LENGTH; + break; + case BMI160_FIFO_HEAD_G_A: + case BMI160_FIFO_G_A_ENABLE: + + /* Move the data index */ + *idx = *idx + BMI160_FIFO_GA_LENGTH; + break; + case BMI160_FIFO_HEAD_A: + case BMI160_FIFO_A_ENABLE: + + /* Move the data index */ + *idx = *idx + BMI160_FIFO_A_LENGTH; + break; + default: + break; + } +} + +/*! + * @brief This API is used to parse the aux data from the + * FIFO data and store it in the instance of the structure bmi160_aux_data. + */ +static void unpack_aux_data( + struct bmi160_aux_data* aux_data, + uint16_t data_start_index, + const struct bmi160_dev* dev) { + /* Aux data bytes */ + aux_data->data[0] = dev->fifo->data[data_start_index++]; + aux_data->data[1] = dev->fifo->data[data_start_index++]; + aux_data->data[2] = dev->fifo->data[data_start_index++]; + aux_data->data[3] = dev->fifo->data[data_start_index++]; + aux_data->data[4] = dev->fifo->data[data_start_index++]; + aux_data->data[5] = dev->fifo->data[data_start_index++]; + aux_data->data[6] = dev->fifo->data[data_start_index++]; + aux_data->data[7] = dev->fifo->data[data_start_index++]; +} + +/*! + * @brief This API is used to parse the aux data from the + * FIFO data in header mode. + */ +static void extract_aux_header_mode( + struct bmi160_aux_data* aux_data, + uint8_t* aux_length, + const struct bmi160_dev* dev) { + uint8_t frame_header = 0; + uint16_t data_index; + uint8_t aux_index = 0; + + for(data_index = dev->fifo->aux_byte_start_idx; data_index < dev->fifo->length;) { + /* extracting Frame header */ + frame_header = (dev->fifo->data[data_index] & BMI160_FIFO_TAG_INTR_MASK); + + /*Index is moved to next byte where the data is starting*/ + data_index++; + switch(frame_header) { + /* Aux frame */ + case BMI160_FIFO_HEAD_M: + case BMI160_FIFO_HEAD_M_A: + case BMI160_FIFO_HEAD_M_G: + case BMI160_FIFO_HEAD_M_G_A: + unpack_aux_frame(aux_data, &data_index, &aux_index, frame_header, dev); + break; + case BMI160_FIFO_HEAD_G: + move_next_frame(&data_index, BMI160_FIFO_G_LENGTH, dev); + break; + case BMI160_FIFO_HEAD_G_A: + move_next_frame(&data_index, BMI160_FIFO_GA_LENGTH, dev); + break; + case BMI160_FIFO_HEAD_A: + move_next_frame(&data_index, BMI160_FIFO_A_LENGTH, dev); + break; + + /* Sensor time frame */ + case BMI160_FIFO_HEAD_SENSOR_TIME: + unpack_sensortime_frame(&data_index, dev); + break; + + /* Skip frame */ + case BMI160_FIFO_HEAD_SKIP_FRAME: + unpack_skipped_frame(&data_index, dev); + break; + + /* Input config frame */ + case BMI160_FIFO_HEAD_INPUT_CONFIG: + move_next_frame(&data_index, 1, dev); + break; + case BMI160_FIFO_HEAD_OVER_READ: + + /* Update the data index as complete in case + * of over read */ + data_index = dev->fifo->length; + break; + default: + + /* Update the data index as complete in case of + * getting other headers like 0x00 */ + data_index = dev->fifo->length; + break; + } + if(*aux_length == aux_index) { + /*Number of frames to read completed*/ + break; + } + } + + /* Update number of aux data read */ + *aux_length = aux_index; + + /* Update the aux frame index */ + dev->fifo->aux_byte_start_idx = data_index; +} + +/*! + * @brief This API checks the presence of non-valid frames in the read fifo data. + */ +static void check_frame_validity(uint16_t* data_index, const struct bmi160_dev* dev) { + if((*data_index + 2) < dev->fifo->length) { + /* Check if FIFO is empty */ + if((dev->fifo->data[*data_index] == FIFO_CONFIG_MSB_CHECK) && + (dev->fifo->data[*data_index + 1] == FIFO_CONFIG_LSB_CHECK)) { + /*Update the data index as complete*/ + *data_index = dev->fifo->length; + } + } +} + +/*! + * @brief This API is used to move the data index ahead of the + * current_frame_length parameter when unnecessary FIFO data appears while + * extracting the user specified data. + */ +static void move_next_frame( + uint16_t* data_index, + uint8_t current_frame_length, + const struct bmi160_dev* dev) { + /*Partial read, then move the data index to last data*/ + if((*data_index + current_frame_length) > dev->fifo->length) { + /*Update the data index as complete*/ + *data_index = dev->fifo->length; + } else { + /*Move the data index to next frame*/ + *data_index = *data_index + current_frame_length; + } +} + +/*! + * @brief This API is used to parse and store the sensor time from the + * FIFO data in the structure instance dev. + */ +static void unpack_sensortime_frame(uint16_t* data_index, const struct bmi160_dev* dev) { + uint32_t sensor_time_byte3 = 0; + uint16_t sensor_time_byte2 = 0; + uint8_t sensor_time_byte1 = 0; + + /*Partial read, then move the data index to last data*/ + if((*data_index + BMI160_SENSOR_TIME_LENGTH) > dev->fifo->length) { + /*Update the data index as complete*/ + *data_index = dev->fifo->length; + } else { + sensor_time_byte3 = dev->fifo->data[(*data_index) + BMI160_SENSOR_TIME_MSB_BYTE] << 16; + sensor_time_byte2 = dev->fifo->data[(*data_index) + BMI160_SENSOR_TIME_XLSB_BYTE] << 8; + sensor_time_byte1 = dev->fifo->data[(*data_index)]; + + /* Sensor time */ + dev->fifo->sensor_time = + (uint32_t)(sensor_time_byte3 | sensor_time_byte2 | sensor_time_byte1); + *data_index = (*data_index) + BMI160_SENSOR_TIME_LENGTH; + } +} + +/*! + * @brief This API is used to parse and store the skipped_frame_count from + * the FIFO data in the structure instance dev. + */ +static void unpack_skipped_frame(uint16_t* data_index, const struct bmi160_dev* dev) { + /*Partial read, then move the data index to last data*/ + if(*data_index >= dev->fifo->length) { + /*Update the data index as complete*/ + *data_index = dev->fifo->length; + } else { + dev->fifo->skipped_frame_count = dev->fifo->data[*data_index]; + + /*Move the data index*/ + *data_index = (*data_index) + 1; + } +} + +/*! + * @brief This API is used to get the FOC status from the sensor + */ +static int8_t get_foc_status(uint8_t* foc_status, struct bmi160_dev const* dev) { + int8_t rslt; + uint8_t data; + + /* Read the FOC status from sensor */ + rslt = bmi160_get_regs(BMI160_STATUS_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + /* Get the foc_status bit */ + *foc_status = BMI160_GET_BITS(data, BMI160_FOC_STATUS); + } + + return rslt; +} + +/*! + * @brief This API is used to configure the offset enable bits in the sensor + */ +static int8_t + configure_offset_enable(const struct bmi160_foc_conf* foc_conf, struct bmi160_dev const* dev) { + int8_t rslt; + uint8_t data; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if(rslt != BMI160_OK) { + rslt = BMI160_E_NULL_PTR; + } else { + /* Read the FOC config from the sensor */ + rslt = bmi160_get_regs(BMI160_OFFSET_CONF_ADDR, &data, 1, dev); + if(rslt == BMI160_OK) { + /* Set the offset enable/disable for gyro */ + data = BMI160_SET_BITS(data, BMI160_GYRO_OFFSET_EN, foc_conf->gyro_off_en); + + /* Set the offset enable/disable for accel */ + data = BMI160_SET_BITS(data, BMI160_ACCEL_OFFSET_EN, foc_conf->acc_off_en); + + /* Set the offset config in the sensor */ + rslt = bmi160_set_regs(BMI160_OFFSET_CONF_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +static int8_t trigger_foc(struct bmi160_offsets* offset, struct bmi160_dev const* dev) { + int8_t rslt; + uint8_t foc_status = BMI160_ENABLE; + uint8_t cmd = BMI160_START_FOC_CMD; + uint8_t timeout = 0; + uint8_t data_array[20]; + + /* Start the FOC process */ + rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &cmd, 1, dev); + if(rslt == BMI160_OK) { + /* Check the FOC status*/ + rslt = get_foc_status(&foc_status, dev); + + if((rslt != BMI160_OK) || (foc_status != BMI160_ENABLE)) { + while((foc_status != BMI160_ENABLE) && (timeout < 11)) { + /* Maximum time of 250ms is given in 10 + * steps of 25ms each - 250ms refer datasheet 2.9.1 */ + dev->delay_ms(25); + + /* Check the FOC status*/ + rslt = get_foc_status(&foc_status, dev); + timeout++; + } + + if((rslt == BMI160_OK) && (foc_status == BMI160_ENABLE)) { + /* Get offset values from sensor */ + rslt = bmi160_get_offsets(offset, dev); + } else { + /* FOC failure case */ + rslt = BMI160_E_FOC_FAILURE; + } + } + + if(rslt == BMI160_OK) { + /* Read registers 0x04-0x17 */ + rslt = bmi160_get_regs(BMI160_GYRO_DATA_ADDR, data_array, 20, dev); + } + } + + return rslt; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/bmi160.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/bmi160.h new file mode 100644 index 000000000..d4d98094c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/bmi160.h @@ -0,0 +1,992 @@ +/** +* Copyright (c) 2021 Bosch Sensortec GmbH. All rights reserved. +* +* BSD-3-Clause +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* 3. Neither the name of the copyright holder nor the names of its +* contributors may be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +* @file bmi160.h +* @date 2021-10-05 +* @version v3.9.2 +* +*/ + +/*! + * @defgroup bmi160 BMI160 + */ + +#ifndef BMI160_H_ +#define BMI160_H_ + +/*************************** C++ guard macro *****************************/ +#ifdef __cplusplus +extern "C" { +#endif + +#include "bmi160_defs.h" +#ifdef __KERNEL__ +#include +#else +#include +#include +#include +#endif + +/*********************** User function prototypes ************************/ + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiInit Initialization + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup bmi160ApiInit + * \page bmi160_api_bmi160_init bmi160_init + * \code + * int8_t bmi160_init(struct bmi160_dev *dev); + * \endcode + * @details This API is the entry point for sensor.It performs + * the selection of I2C/SPI read mechanism according to the + * selected interface and reads the chip-id of bmi160 sensor. + * + * @param[in,out] dev : Structure instance of bmi160_dev + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_init(struct bmi160_dev* dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiRegs Registers + * @brief Read data from the given register address of sensor + */ + +/*! + * \ingroup bmi160ApiRegs + * \page bmi160_api_bmi160_get_regs bmi160_get_regs + * \code + * int8_t bmi160_get_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, const struct bmi160_dev *dev); + * \endcode + * @details This API reads the data from the given register address of sensor. + * + * @param[in] reg_addr : Register address from where the data to be read + * @param[out] data : Pointer to data buffer to store the read data. + * @param[in] len : No of bytes of data to be read. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @note For most of the registers auto address increment applies, with the + * exception of a few special registers, which trap the address. For e.g., + * Register address - 0x24(BMI160_FIFO_DATA_ADDR) + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t + bmi160_get_regs(uint8_t reg_addr, uint8_t* data, uint16_t len, const struct bmi160_dev* dev); + +/*! + * \ingroup bmi160ApiRegs + * \page bmi160_api_bmi160_set_regs bmi160_set_regs + * \code + * int8_t bmi160_set_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, const struct bmi160_dev *dev); + * \endcode + * @details This API writes the given data to the register address + * of sensor. + * + * @param[in] reg_addr : Register address from where the data to be written. + * @param[in] data : Pointer to data buffer which is to be written + * in the sensor. + * @param[in] len : No of bytes of data to write.. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t + bmi160_set_regs(uint8_t reg_addr, uint8_t* data, uint16_t len, const struct bmi160_dev* dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiSoftreset Soft reset + * @brief Perform soft reset of the sensor + */ + +/*! + * \ingroup bmi160ApiSoftreset + * \page bmi160_api_bmi160_soft_reset bmi160_soft_reset + * \code + * int8_t bmi160_soft_reset(struct bmi160_dev *dev); + * \endcode + * @details This API resets and restarts the device. + * All register values are overwritten with default parameters. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_soft_reset(struct bmi160_dev* dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiConfig Configuration + * @brief Configuration of the sensor + */ + +/*! + * \ingroup bmi160ApiConfig + * \page bmi160_api_bmi160_set_sens_conf bmi160_set_sens_conf + * \code + * int8_t bmi160_set_sens_conf(struct bmi160_dev *dev); + * \endcode + * @details This API configures the power mode, range and bandwidth + * of sensor. + * + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_set_sens_conf(struct bmi160_dev* dev); + +/*! + * \ingroup bmi160ApiConfig + * \page bmi160_api_bmi160_get_sens_conf bmi160_get_sens_conf + * \code + * int8_t bmi160_get_sens_conf(struct bmi160_dev *dev); + * \endcode + * @details This API gets accel and gyro configurations. + * + * @param[out] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_get_sens_conf(struct bmi160_dev* dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiPowermode Power mode + * @brief Set / Get power mode of the sensor + */ + +/*! + * \ingroup bmi160ApiPowermode + * \page bmi160_api_bmi160_set_power_mode bmi160_set_power_mode + * \code + * int8_t bmi160_set_power_mode(struct bmi160_dev *dev); + * \endcode + * @details This API sets the power mode of the sensor. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_set_power_mode(struct bmi160_dev* dev); + +/*! + * \ingroup bmi160ApiPowermode + * \page bmi160_api_bmi160_get_power_mode bmi160_get_power_mode + * \code + * int8_t bmi160_get_power_mode(struct bmi160_dev *dev); + * \endcode + * @details This API gets the power mode of the sensor. + * + * @param[in] dev : Structure instance of bmi160_dev + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_get_power_mode(struct bmi160_dev* dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiData Sensor Data + * @brief Read sensor data + */ + +/*! + * \ingroup bmi160ApiData + * \page bmi160_api_bmi160_get_sensor_data bmi160_get_sensor_data + * \code + * int8_t bmi160_get_sensor_data(uint8_t select_sensor, + * struct bmi160_sensor_data *accel, + * struct bmi160_sensor_data *gyro, + * const struct bmi160_dev *dev); + * + * \endcode + * @details This API reads sensor data, stores it in + * the bmi160_sensor_data structure pointer passed by the user. + * The user can ask for accel data ,gyro data or both sensor + * data using bmi160_select_sensor enum + * + * @param[in] select_sensor : enum to choose accel,gyro or both sensor data + * @param[out] accel : Structure pointer to store accel data + * @param[out] gyro : Structure pointer to store gyro data + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_get_sensor_data( + uint8_t select_sensor, + struct bmi160_sensor_data* accel, + struct bmi160_sensor_data* gyro, + const struct bmi160_dev* dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiInt Interrupt configuration + * @brief Set interrupt configuration of the sensor + */ + +/*! + * \ingroup bmi160ApiInt + * \page bmi160_api_bmi160_set_int_config bmi160_set_int_config + * \code + * int8_t bmi160_set_int_config(struct bmi160_int_settg *int_config, struct bmi160_dev *dev); + * \endcode + * @details This API configures the necessary interrupt based on + * the user settings in the bmi160_int_settg structure instance. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_set_int_config(struct bmi160_int_settg* int_config, struct bmi160_dev* dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiStepC Step counter + * @brief Step counter operations + */ + +/*! + * \ingroup bmi160ApiStepC + * \page bmi160_api_bmi160_set_step_counter bmi160_set_step_counter + * \code + * int8_t bmi160_set_step_counter(uint8_t step_cnt_enable, const struct bmi160_dev *dev); + * \endcode + * @details This API enables the step counter feature. + * + * @param[in] step_cnt_enable : value to enable or disable + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_set_step_counter(uint8_t step_cnt_enable, const struct bmi160_dev* dev); + +/*! + * \ingroup bmi160ApiStepC + * \page bmi160_api_bmi160_read_step_counter bmi160_read_step_counter + * \code + * int8_t bmi160_read_step_counter(uint16_t *step_val, const struct bmi160_dev *dev); + * \endcode + * @details This API reads the step counter value. + * + * @param[in] step_val : Pointer to store the step counter value. + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_read_step_counter(uint16_t* step_val, const struct bmi160_dev* dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiAux Auxiliary sensor + * @brief Auxiliary sensor operations + */ + +/*! + * \ingroup bmi160ApiAux + * \page bmi160_api_bmi160_aux_read bmi160_aux_read + * \code + * int8_t bmi160_aux_read(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, const struct bmi160_dev *dev); + * \endcode + * @details This API reads the mention no of byte of data from the given + * register address of auxiliary sensor. + * + * @param[in] reg_addr : Address of register to read. + * @param[in] aux_data : Pointer to store the read data. + * @param[in] len : No of bytes to read. + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_aux_read( + uint8_t reg_addr, + uint8_t* aux_data, + uint16_t len, + const struct bmi160_dev* dev); + +/*! + * \ingroup bmi160ApiAux + * \page bmi160_api_bmi160_aux_write bmi160_aux_write + * \code + * int8_t bmi160_aux_write(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, const struct bmi160_dev *dev); + * \endcode + * @details This API writes the mention no of byte of data to the given + * register address of auxiliary sensor. + * + * @param[in] reg_addr : Address of register to write. + * @param[in] aux_data : Pointer to write data. + * @param[in] len : No of bytes to write. + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_aux_write( + uint8_t reg_addr, + uint8_t* aux_data, + uint16_t len, + const struct bmi160_dev* dev); + +/*! + * \ingroup bmi160ApiAux + * \page bmi160_api_bmi160_aux_init bmi160_aux_init + * \code + * int8_t bmi160_aux_init(const struct bmi160_dev *dev); + * \endcode + * @details This API initialize the auxiliary sensor + * in order to access it. + * + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_aux_init(const struct bmi160_dev* dev); + +/*! + * \ingroup bmi160ApiAux + * \page bmi160_api_bmi160_set_aux_auto_mode bmi160_set_aux_auto_mode + * \code + * int8_t bmi160_set_aux_auto_mode(uint8_t *data_addr, struct bmi160_dev *dev); + * \endcode + * @details This API is used to setup the auxiliary sensor of bmi160 in auto mode + * Thus enabling the auto update of 8 bytes of data from auxiliary sensor + * to BMI160 register address 0x04 to 0x0B + * + * @param[in] data_addr : Starting address of aux. sensor's data register + * (BMI160 registers 0x04 to 0x0B will be updated + * with 8 bytes of data from auxiliary sensor + * starting from this register address.) + * @param[in] dev : Structure instance of bmi160_dev. + * + * @note : Set the value of auxiliary polling rate by setting + * dev->aux_cfg.aux_odr to the required value from the table + * before calling this API + * + *@verbatim + * dev->aux_cfg.aux_odr | Auxiliary ODR (Hz) + * -----------------------|----------------------- + * BMI160_AUX_ODR_0_78HZ | 25/32 + * BMI160_AUX_ODR_1_56HZ | 25/16 + * BMI160_AUX_ODR_3_12HZ | 25/8 + * BMI160_AUX_ODR_6_25HZ | 25/4 + * BMI160_AUX_ODR_12_5HZ | 25/2 + * BMI160_AUX_ODR_25HZ | 25 + * BMI160_AUX_ODR_50HZ | 50 + * BMI160_AUX_ODR_100HZ | 100 + * BMI160_AUX_ODR_200HZ | 200 + * BMI160_AUX_ODR_400HZ | 400 + * BMI160_AUX_ODR_800HZ | 800 + *@endverbatim + * + * @note : Other values of dev->aux_cfg.aux_odr are reserved and not for use + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_set_aux_auto_mode(uint8_t* data_addr, struct bmi160_dev* dev); + +/*! + * \ingroup bmi160ApiAux + * \page bmi160_api_bmi160_config_aux_mode bmi160_config_aux_mode + * \code + * int8_t bmi160_config_aux_mode(const struct bmi160_dev *dev); + * \endcode + * @details This API configures the 0x4C register and settings like + * Auxiliary sensor manual enable/ disable and aux burst read length. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_config_aux_mode(const struct bmi160_dev* dev); + +/*! + * \ingroup bmi160ApiAux + * \page bmi160_api_bmi160_read_aux_data_auto_mode bmi160_read_aux_data_auto_mode + * \code + * int8_t bmi160_read_aux_data_auto_mode(uint8_t *aux_data, const struct bmi160_dev *dev); + * \endcode + * @details This API is used to read the raw uncompensated auxiliary sensor + * data of 8 bytes from BMI160 register address 0x04 to 0x0B + * + * @param[in] aux_data : Pointer to user array of length 8 bytes + * Ensure that the aux_data array is of + * length 8 bytes + * @param[in] dev : Structure instance of bmi160_dev + * + * @retval zero -> Success / -ve value -> Error + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_read_aux_data_auto_mode(uint8_t* aux_data, const struct bmi160_dev* dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiSelfTest Self test + * @brief Perform self test of the sensor + */ + +/*! + * \ingroup bmi160ApiSelfTest + * \page bmi160_api_bmi160_perform_self_test bmi160_perform_self_test + * \code + * int8_t bmi160_perform_self_test(uint8_t select_sensor, struct bmi160_dev *dev); + * \endcode + * @details This is used to perform self test of accel/gyro of the BMI160 sensor + * + * @param[in] select_sensor : enum to choose accel or gyro for self test + * @param[in] dev : Structure instance of bmi160_dev + * + * @note self test can be performed either for accel/gyro at any instant. + * + *@verbatim + * value of select_sensor | Inference + *----------------------------------|-------------------------------- + * BMI160_ACCEL_ONLY | Accel self test enabled + * BMI160_GYRO_ONLY | Gyro self test enabled + * BMI160_BOTH_ACCEL_AND_GYRO | NOT TO BE USED + *@endverbatim + * + * @note The return value of this API gives us the result of self test. + * + * @note Performing self test does soft reset of the sensor, User can + * set the desired settings after performing the self test. + * + * @return Result of API execution status + * @retval BMI160_OK Self test success + * @retval BMI160_W_GYRO_SELF_TEST_FAIL Gyro self test fail + * @retval BMI160_W_ACCEl_SELF_TEST_FAIL Accel self test fail + */ +int8_t bmi160_perform_self_test(uint8_t select_sensor, struct bmi160_dev* dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiFIFO FIFO + * @brief FIFO operations of the sensor + */ + +/*! + * \ingroup bmi160ApiFIFO + * \page bmi160_api_bmi160_get_fifo_data bmi160_get_fifo_data + * \code + * int8_t bmi160_get_fifo_data(struct bmi160_dev const *dev); + * \endcode + * @details This API reads data from the fifo buffer. + * + * @note User has to allocate the FIFO buffer along with + * corresponding fifo length from his side before calling this API + * as mentioned in the readme.md + * + * @note User must specify the number of bytes to read from the FIFO in + * dev->fifo->length , It will be updated by the number of bytes actually + * read from FIFO after calling this API + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_get_fifo_data(struct bmi160_dev const* dev); + +/*! + * \ingroup bmi160ApiFIFO + * \page bmi160_api_bmi160_set_fifo_flush bmi160_set_fifo_flush + * \code + * int8_t bmi160_set_fifo_flush(const struct bmi160_dev *dev); + * \endcode + * @details This API writes fifo_flush command to command register.This + * action clears all data in the Fifo without changing fifo configuration + * settings. + * + * @param[in] dev : Structure instance of bmi160_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + * + */ +int8_t bmi160_set_fifo_flush(const struct bmi160_dev* dev); + +/*! + * \ingroup bmi160ApiFIFO + * \page bmi160_api_bmi160_set_fifo_config bmi160_set_fifo_config + * \code + * int8_t bmi160_set_fifo_config(uint8_t config, uint8_t enable, struct bmi160_dev const *dev); + * \endcode + * @details This API sets the FIFO configuration in the sensor. + * + * @param[in] config : variable used to specify the FIFO + * configurations which are to be enabled or disabled in the sensor. + * + * @note : User can set either set one or more or all FIFO configurations + * by ORing the below mentioned macros. + * + *@verbatim + * config | Value + * ------------------------|--------------------------- + * BMI160_FIFO_TIME | 0x02 + * BMI160_FIFO_TAG_INT2 | 0x04 + * BMI160_FIFO_TAG_INT1 | 0x08 + * BMI160_FIFO_HEADER | 0x10 + * BMI160_FIFO_AUX | 0x20 + * BMI160_FIFO_ACCEL | 0x40 + * BMI160_FIFO_GYRO | 0x80 + *@endverbatim + * + * @param[in] enable : Parameter used to enable or disable the above + * FIFO configuration + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return status of bus communication result + * @retval 0 -> Success + * @retval Any non zero value -> Fail + * + */ +int8_t bmi160_set_fifo_config(uint8_t config, uint8_t enable, struct bmi160_dev const* dev); + +/*! + * \ingroup bmi160ApiFIFO + * \page bmi160_api_bmi160_set_fifo_down bmi160_set_fifo_down + * \code + * int8_t bmi160_set_fifo_down(uint8_t fifo_down, const struct bmi160_dev *dev); + * \endcode + * @details This API is used to configure the down sampling ratios of + * the accel and gyro data for FIFO.Also, it configures filtered or + * pre-filtered data for the fifo for accel and gyro. + * + * @param[in] fifo_down : variable used to specify the FIFO down + * configurations which are to be enabled or disabled in the sensor. + * + * @note The user must select one among the following macros to + * select down-sampling ratio for accel + * + *@verbatim + * config | Value + * -------------------------------------|--------------------------- + * BMI160_ACCEL_FIFO_DOWN_ZERO | 0x00 + * BMI160_ACCEL_FIFO_DOWN_ONE | 0x10 + * BMI160_ACCEL_FIFO_DOWN_TWO | 0x20 + * BMI160_ACCEL_FIFO_DOWN_THREE | 0x30 + * BMI160_ACCEL_FIFO_DOWN_FOUR | 0x40 + * BMI160_ACCEL_FIFO_DOWN_FIVE | 0x50 + * BMI160_ACCEL_FIFO_DOWN_SIX | 0x60 + * BMI160_ACCEL_FIFO_DOWN_SEVEN | 0x70 + *@endverbatim + * + * @note The user must select one among the following macros to + * select down-sampling ratio for gyro + * + *@verbatim + * config | Value + * -------------------------------------|--------------------------- + * BMI160_GYRO_FIFO_DOWN_ZERO | 0x00 + * BMI160_GYRO_FIFO_DOWN_ONE | 0x01 + * BMI160_GYRO_FIFO_DOWN_TWO | 0x02 + * BMI160_GYRO_FIFO_DOWN_THREE | 0x03 + * BMI160_GYRO_FIFO_DOWN_FOUR | 0x04 + * BMI160_GYRO_FIFO_DOWN_FIVE | 0x05 + * BMI160_GYRO_FIFO_DOWN_SIX | 0x06 + * BMI160_GYRO_FIFO_DOWN_SEVEN | 0x07 + *@endverbatim + * + * @note The user can enable filtered accel data by the following macro + * + *@verbatim + * config | Value + * -------------------------------------|--------------------------- + * BMI160_ACCEL_FIFO_FILT_EN | 0x80 + *@endverbatim + * + * @note The user can enable filtered gyro data by the following macro + * + *@verbatim + * config | Value + * -------------------------------------|--------------------------- + * BMI160_GYRO_FIFO_FILT_EN | 0x08 + *@endverbatim + * + * @note : By ORing the above mentioned macros, the user can select + * the required FIFO down config settings + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return status of bus communication result + * @retval 0 -> Success + * @retval Any non zero value -> Fail + * + */ +int8_t bmi160_set_fifo_down(uint8_t fifo_down, const struct bmi160_dev* dev); + +/*! + * \ingroup bmi160ApiFIFO + * \page bmi160_api_bmi160_set_fifo_wm bmi160_set_fifo_wm + * \code + * int8_t bmi160_set_fifo_wm(uint8_t fifo_wm, const struct bmi160_dev *dev); + * \endcode + * @details This API sets the FIFO watermark level in the sensor. + * + * @note The FIFO watermark is issued when the FIFO fill level is + * equal or above the watermark level and units of watermark is 4 bytes. + * + * @param[in] fifo_wm : Variable used to set the FIFO water mark level + * @param[in] dev : Structure instance of bmi160_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + * + */ +int8_t bmi160_set_fifo_wm(uint8_t fifo_wm, const struct bmi160_dev* dev); + +/*! + * \ingroup bmi160ApiFIFO + * \page bmi160_api_bmi160_extract_accel bmi160_extract_accel + * \code + * int8_t bmi160_extract_accel(struct bmi160_sensor_data *accel_data, uint8_t *accel_length, struct bmi160_dev const + **dev); + * \endcode + * @details This API parses and extracts the accelerometer frames from + * FIFO data read by the "bmi160_get_fifo_data" API and stores it in + * the "accel_data" structure instance. + * + * @note The bmi160_extract_accel API should be called only after + * reading the FIFO data by calling the bmi160_get_fifo_data() API. + * + * @param[out] accel_data : Structure instance of bmi160_sensor_data + * where the accelerometer data in FIFO is stored. + * @param[in,out] accel_length : Number of valid accelerometer frames + * (x,y,z axes data) read out from fifo. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @note accel_length is updated with the number of valid accelerometer + * frames extracted from fifo (1 accel frame = 6 bytes) at the end of + * execution of this API. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + * + */ +int8_t bmi160_extract_accel( + struct bmi160_sensor_data* accel_data, + uint8_t* accel_length, + struct bmi160_dev const* dev); + +/*! + * \ingroup bmi160ApiFIFO + * \page bmi160_api_bmi160_extract_gyro bmi160_extract_gyro + * \code + * int8_t bmi160_extract_gyro(struct bmi160_sensor_data *gyro_data, uint8_t *gyro_length, struct bmi160_dev const *dev); + * \endcode + * @details This API parses and extracts the gyro frames from + * FIFO data read by the "bmi160_get_fifo_data" API and stores it in + * the "gyro_data" structure instance. + * + * @note The bmi160_extract_gyro API should be called only after + * reading the FIFO data by calling the bmi160_get_fifo_data() API. + * + * @param[out] gyro_data : Structure instance of bmi160_sensor_data + * where the gyro data in FIFO is stored. + * @param[in,out] gyro_length : Number of valid gyro frames + * (x,y,z axes data) read out from fifo. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @note gyro_length is updated with the number of valid gyro + * frames extracted from fifo (1 gyro frame = 6 bytes) at the end of + * execution of this API. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + * + */ +int8_t bmi160_extract_gyro( + struct bmi160_sensor_data* gyro_data, + uint8_t* gyro_length, + struct bmi160_dev const* dev); + +/*! + * \ingroup bmi160ApiFIFO + * \page bmi160_api_bmi160_extract_aux bmi160_extract_aux + * \code + * int8_t bmi160_extract_aux(struct bmi160_aux_data *aux_data, uint8_t *aux_len, struct bmi160_dev const *dev); + * \endcode + * @details This API parses and extracts the aux frames from + * FIFO data read by the "bmi160_get_fifo_data" API and stores it in + * the bmi160_aux_data structure instance. + * + * @note The bmi160_extract_aux API should be called only after + * reading the FIFO data by calling the bmi160_get_fifo_data() API. + * + * @param[out] aux_data : Structure instance of bmi160_aux_data + * where the aux data in FIFO is stored. + * @param[in,out] aux_len : Number of valid aux frames (8bytes) + * read out from FIFO. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @note aux_len is updated with the number of valid aux + * frames extracted from fifo (1 aux frame = 8 bytes) at the end of + * execution of this API. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + * + */ +int8_t bmi160_extract_aux( + struct bmi160_aux_data* aux_data, + uint8_t* aux_len, + struct bmi160_dev const* dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiFOC FOC + * @brief Start FOC of accel and gyro sensors + */ + +/*! + * \ingroup bmi160ApiFOC + * \page bmi160_api_bmi160_start_foc bmi160_start_foc + * \code + * int8_t bmi160_start_foc(const struct bmi160_foc_conf *foc_conf, + * \endcode + * @details This API starts the FOC of accel and gyro + * + * @note FOC should not be used in low-power mode of sensor + * + * @note Accel FOC targets values of +1g , 0g , -1g + * Gyro FOC always targets value of 0 dps + * + * @param[in] foc_conf : Structure instance of bmi160_foc_conf which + * has the FOC configuration + * @param[in,out] offset : Structure instance to store Offset + * values read from sensor + * @param[in] dev : Structure instance of bmi160_dev. + * + * @note Pre-requisites for triggering FOC in accel , Set the following, + * Enable the acc_off_en + * Ex : foc_conf.acc_off_en = BMI160_ENABLE; + * + * Set the desired target values of FOC to each axes (x,y,z) by using the + * following macros + * - BMI160_FOC_ACCEL_DISABLED + * - BMI160_FOC_ACCEL_POSITIVE_G + * - BMI160_FOC_ACCEL_NEGATIVE_G + * - BMI160_FOC_ACCEL_0G + * + * Ex : foc_conf.foc_acc_x = BMI160_FOC_ACCEL_0G; + * foc_conf.foc_acc_y = BMI160_FOC_ACCEL_0G; + * foc_conf.foc_acc_z = BMI160_FOC_ACCEL_POSITIVE_G; + * + * @note Pre-requisites for triggering FOC in gyro , + * Set the following parameters, + * + * Ex : foc_conf.foc_gyr_en = BMI160_ENABLE; + * foc_conf.gyro_off_en = BMI160_ENABLE; + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + */ +int8_t bmi160_start_foc( + const struct bmi160_foc_conf* foc_conf, + struct bmi160_offsets* offset, + struct bmi160_dev const* dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiOffsets Offsets + * @brief Set / Get offset values of accel and gyro sensors + */ + +/*! + * \ingroup bmi160ApiOffsets + * \page bmi160_api_bmi160_get_offsets bmi160_get_offsets + * \code + * int8_t bmi160_get_offsets(struct bmi160_offsets *offset, const struct bmi160_dev *dev); + * \endcode + * @details This API reads and stores the offset values of accel and gyro + * + * @param[in,out] offset : Structure instance of bmi160_offsets in which + * the offset values are read and stored + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + */ +int8_t bmi160_get_offsets(struct bmi160_offsets* offset, const struct bmi160_dev* dev); + +/*! + * \ingroup bmi160ApiOffsets + * \page bmi160_api_bmi160_set_offsets bmi160_set_offsets + * \code + * int8_t bmi160_set_offsets(const struct bmi160_foc_conf *foc_conf, + * const struct bmi160_offsets *offset, + * struct bmi160_dev const *dev); + * \endcode + * @details This API writes the offset values of accel and gyro to + * the sensor but these values will be reset on POR or soft reset. + * + * @param[in] foc_conf : Structure instance of bmi160_foc_conf which + * has the FOC configuration + * @param[in] offset : Structure instance in which user updates offset + * values which are to be written in the sensor + * @param[in] dev : Structure instance of bmi160_dev. + * + * @note Offsets can be set by user like offset->off_acc_x = 10; + * where 1LSB = 3.9mg and for gyro 1LSB = 0.061degrees/second + * + * @note BMI160 offset values for xyz axes of accel should be within range of + * BMI160_ACCEL_MIN_OFFSET (-128) to BMI160_ACCEL_MAX_OFFSET (127) + * + * @note BMI160 offset values for xyz axes of gyro should be within range of + * BMI160_GYRO_MIN_OFFSET (-512) to BMI160_GYRO_MAX_OFFSET (511) + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + */ +int8_t bmi160_set_offsets( + const struct bmi160_foc_conf* foc_conf, + const struct bmi160_offsets* offset, + struct bmi160_dev const* dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiNVM NVM + * @brief Write image registers values to NVM + */ + +/*! + * \ingroup bmi160ApiNVM + * \page bmi160_api_bmi160_update_nvm bmi160_update_nvm + * \code + * int8_t bmi160_update_nvm(struct bmi160_dev const *dev); + * \endcode + * @details This API writes the image registers values to NVM which is + * stored even after POR or soft reset + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + */ +int8_t bmi160_update_nvm(struct bmi160_dev const* dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiInts Interrupt status + * @brief Read interrupt status from the sensor + */ + +/*! + * \ingroup bmi160ApiInts + * \page bmi160_api_bmi160_get_int_status bmi160_get_int_status + * \code + * int8_t bmi160_get_int_status(enum bmi160_int_status_sel int_status_sel, + * union bmi160_int_status *int_status, + * struct bmi160_dev const *dev); + * \endcode + * @details This API gets the interrupt status from the sensor. + * + * @param[in] int_status_sel : Enum variable to select either individual or all the + * interrupt status bits. + * @param[in] int_status : pointer variable to get the interrupt status + * from the sensor. + * param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + */ +int8_t bmi160_get_int_status( + enum bmi160_int_status_sel int_status_sel, + union bmi160_int_status* int_status, + struct bmi160_dev const* dev); + +/*************************** C++ guard macro *****************************/ +#ifdef __cplusplus +} +#endif + +#endif /* BMI160_H_ */ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/bmi160_defs.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/bmi160_defs.h new file mode 100644 index 000000000..458ecaad5 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/bmi160_defs.h @@ -0,0 +1,1619 @@ +/** +* Copyright (c) 2021 Bosch Sensortec GmbH. All rights reserved. +* +* BSD-3-Clause +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* 3. Neither the name of the copyright holder nor the names of its +* contributors may be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +* @file bmi160_defs.h +* @date 2021-10-05 +* @version v3.9.2 +* +*/ + +#ifndef BMI160_DEFS_H_ +#define BMI160_DEFS_H_ + +/*************************** C types headers *****************************/ +#ifdef __KERNEL__ +#include +#include +#else +#include +#include +#endif + +/*************************** Common macros *****************************/ + +#if !defined(UINT8_C) && !defined(INT8_C) +#define INT8_C(x) S8_C(x) +#define UINT8_C(x) U8_C(x) +#endif + +#if !defined(UINT16_C) && !defined(INT16_C) +#define INT16_C(x) S16_C(x) +#define UINT16_C(x) U16_C(x) +#endif + +#if !defined(INT32_C) && !defined(UINT32_C) +#define INT32_C(x) S32_C(x) +#define UINT32_C(x) U32_C(x) +#endif + +#if !defined(INT64_C) && !defined(UINT64_C) +#define INT64_C(x) S64_C(x) +#define UINT64_C(x) U64_C(x) +#endif + +/**@}*/ +/**\name C standard macros */ +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void*)0) +#endif +#endif + +/*************************** Sensor macros *****************************/ +/* Test for an endian machine */ +#ifndef __ORDER_LITTLE_ENDIAN__ +#define __ORDER_LITTLE_ENDIAN__ 0 +#endif + +#ifndef __BYTE_ORDER__ +#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +#endif + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1 +#endif +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#ifndef BIG_ENDIAN +#define BIG_ENDIAN 1 +#endif +#else +#error "Code does not support Endian format of the processor" +#endif + +/** Mask definitions */ +#define BMI160_ACCEL_BW_MASK UINT8_C(0x70) +#define BMI160_ACCEL_ODR_MASK UINT8_C(0x0F) +#define BMI160_ACCEL_UNDERSAMPLING_MASK UINT8_C(0x80) +#define BMI160_ACCEL_RANGE_MASK UINT8_C(0x0F) +#define BMI160_GYRO_BW_MASK UINT8_C(0x30) +#define BMI160_GYRO_ODR_MASK UINT8_C(0x0F) +#define BMI160_GYRO_RANGE_MASK UINT8_C(0x07) + +#define BMI160_ACCEL_BW_POS UINT8_C(4) +#define BMI160_GYRO_BW_POS UINT8_C(4) + +/** Mask definitions for INT_EN registers */ +#define BMI160_ANY_MOTION_X_INT_EN_MASK UINT8_C(0x01) +#define BMI160_HIGH_G_X_INT_EN_MASK UINT8_C(0x01) +#define BMI160_NO_MOTION_X_INT_EN_MASK UINT8_C(0x01) +#define BMI160_ANY_MOTION_Y_INT_EN_MASK UINT8_C(0x02) +#define BMI160_HIGH_G_Y_INT_EN_MASK UINT8_C(0x02) +#define BMI160_NO_MOTION_Y_INT_EN_MASK UINT8_C(0x02) +#define BMI160_ANY_MOTION_Z_INT_EN_MASK UINT8_C(0x04) +#define BMI160_HIGH_G_Z_INT_EN_MASK UINT8_C(0x04) +#define BMI160_NO_MOTION_Z_INT_EN_MASK UINT8_C(0x04) +#define BMI160_SIG_MOTION_INT_EN_MASK UINT8_C(0x07) +#define BMI160_ANY_MOTION_ALL_INT_EN_MASK UINT8_C(0x07) +#define BMI160_STEP_DETECT_INT_EN_MASK UINT8_C(0x08) +#define BMI160_DOUBLE_TAP_INT_EN_MASK UINT8_C(0x10) +#define BMI160_SINGLE_TAP_INT_EN_MASK UINT8_C(0x20) +#define BMI160_FIFO_FULL_INT_EN_MASK UINT8_C(0x20) +#define BMI160_ORIENT_INT_EN_MASK UINT8_C(0x40) +#define BMI160_FIFO_WATERMARK_INT_EN_MASK UINT8_C(0x40) +#define BMI160_LOW_G_INT_EN_MASK UINT8_C(0x08) +#define BMI160_STEP_DETECT_EN_MASK UINT8_C(0x08) +#define BMI160_FLAT_INT_EN_MASK UINT8_C(0x80) +#define BMI160_DATA_RDY_INT_EN_MASK UINT8_C(0x10) + +/** PMU status Macros */ +#define BMI160_AUX_PMU_SUSPEND UINT8_C(0x00) +#define BMI160_AUX_PMU_NORMAL UINT8_C(0x01) +#define BMI160_AUX_PMU_LOW_POWER UINT8_C(0x02) + +#define BMI160_GYRO_PMU_SUSPEND UINT8_C(0x00) +#define BMI160_GYRO_PMU_NORMAL UINT8_C(0x01) +#define BMI160_GYRO_PMU_FSU UINT8_C(0x03) + +#define BMI160_ACCEL_PMU_SUSPEND UINT8_C(0x00) +#define BMI160_ACCEL_PMU_NORMAL UINT8_C(0x01) +#define BMI160_ACCEL_PMU_LOW_POWER UINT8_C(0x02) + +/** Mask definitions for INT_OUT_CTRL register */ +#define BMI160_INT1_EDGE_CTRL_MASK UINT8_C(0x01) +#define BMI160_INT1_OUTPUT_MODE_MASK UINT8_C(0x04) +#define BMI160_INT1_OUTPUT_TYPE_MASK UINT8_C(0x02) +#define BMI160_INT1_OUTPUT_EN_MASK UINT8_C(0x08) +#define BMI160_INT2_EDGE_CTRL_MASK UINT8_C(0x10) +#define BMI160_INT2_OUTPUT_MODE_MASK UINT8_C(0x40) +#define BMI160_INT2_OUTPUT_TYPE_MASK UINT8_C(0x20) +#define BMI160_INT2_OUTPUT_EN_MASK UINT8_C(0x80) + +/** Mask definitions for INT_LATCH register */ +#define BMI160_INT1_INPUT_EN_MASK UINT8_C(0x10) +#define BMI160_INT2_INPUT_EN_MASK UINT8_C(0x20) +#define BMI160_INT_LATCH_MASK UINT8_C(0x0F) + +/** Mask definitions for INT_MAP register */ +#define BMI160_INT1_LOW_G_MASK UINT8_C(0x01) +#define BMI160_INT1_HIGH_G_MASK UINT8_C(0x02) +#define BMI160_INT1_SLOPE_MASK UINT8_C(0x04) +#define BMI160_INT1_NO_MOTION_MASK UINT8_C(0x08) +#define BMI160_INT1_DOUBLE_TAP_MASK UINT8_C(0x10) +#define BMI160_INT1_SINGLE_TAP_MASK UINT8_C(0x20) +#define BMI160_INT1_FIFO_FULL_MASK UINT8_C(0x20) +#define BMI160_INT1_FIFO_WM_MASK UINT8_C(0x40) +#define BMI160_INT1_ORIENT_MASK UINT8_C(0x40) +#define BMI160_INT1_FLAT_MASK UINT8_C(0x80) +#define BMI160_INT1_DATA_READY_MASK UINT8_C(0x80) +#define BMI160_INT2_LOW_G_MASK UINT8_C(0x01) +#define BMI160_INT1_LOW_STEP_DETECT_MASK UINT8_C(0x01) +#define BMI160_INT2_LOW_STEP_DETECT_MASK UINT8_C(0x01) +#define BMI160_INT2_HIGH_G_MASK UINT8_C(0x02) +#define BMI160_INT2_FIFO_FULL_MASK UINT8_C(0x02) +#define BMI160_INT2_FIFO_WM_MASK UINT8_C(0x04) +#define BMI160_INT2_SLOPE_MASK UINT8_C(0x04) +#define BMI160_INT2_DATA_READY_MASK UINT8_C(0x08) +#define BMI160_INT2_NO_MOTION_MASK UINT8_C(0x08) +#define BMI160_INT2_DOUBLE_TAP_MASK UINT8_C(0x10) +#define BMI160_INT2_SINGLE_TAP_MASK UINT8_C(0x20) +#define BMI160_INT2_ORIENT_MASK UINT8_C(0x40) +#define BMI160_INT2_FLAT_MASK UINT8_C(0x80) + +/** Mask definitions for INT_DATA register */ +#define BMI160_TAP_SRC_INT_MASK UINT8_C(0x08) +#define BMI160_LOW_HIGH_SRC_INT_MASK UINT8_C(0x80) +#define BMI160_MOTION_SRC_INT_MASK UINT8_C(0x80) + +/** Mask definitions for INT_MOTION register */ +#define BMI160_SLOPE_INT_DUR_MASK UINT8_C(0x03) +#define BMI160_NO_MOTION_INT_DUR_MASK UINT8_C(0xFC) +#define BMI160_NO_MOTION_SEL_BIT_MASK UINT8_C(0x01) + +/** Mask definitions for INT_TAP register */ +#define BMI160_TAP_DUR_MASK UINT8_C(0x07) +#define BMI160_TAP_SHOCK_DUR_MASK UINT8_C(0x40) +#define BMI160_TAP_QUIET_DUR_MASK UINT8_C(0x80) +#define BMI160_TAP_THRES_MASK UINT8_C(0x1F) + +/** Mask definitions for INT_FLAT register */ +#define BMI160_FLAT_THRES_MASK UINT8_C(0x3F) +#define BMI160_FLAT_HOLD_TIME_MASK UINT8_C(0x30) +#define BMI160_FLAT_HYST_MASK UINT8_C(0x07) + +/** Mask definitions for INT_LOWHIGH register */ +#define BMI160_LOW_G_HYST_MASK UINT8_C(0x03) +#define BMI160_LOW_G_LOW_MODE_MASK UINT8_C(0x04) +#define BMI160_HIGH_G_HYST_MASK UINT8_C(0xC0) + +/** Mask definitions for INT_SIG_MOTION register */ +#define BMI160_SIG_MOTION_SEL_MASK UINT8_C(0x02) +#define BMI160_SIG_MOTION_SKIP_MASK UINT8_C(0x0C) +#define BMI160_SIG_MOTION_PROOF_MASK UINT8_C(0x30) + +/** Mask definitions for INT_ORIENT register */ +#define BMI160_ORIENT_MODE_MASK UINT8_C(0x03) +#define BMI160_ORIENT_BLOCK_MASK UINT8_C(0x0C) +#define BMI160_ORIENT_HYST_MASK UINT8_C(0xF0) +#define BMI160_ORIENT_THETA_MASK UINT8_C(0x3F) +#define BMI160_ORIENT_UD_ENABLE UINT8_C(0x40) +#define BMI160_AXES_EN_MASK UINT8_C(0x80) + +/** Mask definitions for FIFO_CONFIG register */ +#define BMI160_FIFO_GYRO UINT8_C(0x80) +#define BMI160_FIFO_ACCEL UINT8_C(0x40) +#define BMI160_FIFO_AUX UINT8_C(0x20) +#define BMI160_FIFO_TAG_INT1 UINT8_C(0x08) +#define BMI160_FIFO_TAG_INT2 UINT8_C(0x04) +#define BMI160_FIFO_TIME UINT8_C(0x02) +#define BMI160_FIFO_HEADER UINT8_C(0x10) +#define BMI160_FIFO_CONFIG_1_MASK UINT8_C(0xFE) + +/** Mask definitions for STEP_CONF register */ +#define BMI160_STEP_COUNT_EN_BIT_MASK UINT8_C(0x08) +#define BMI160_STEP_DETECT_MIN_THRES_MASK UINT8_C(0x18) +#define BMI160_STEP_DETECT_STEPTIME_MIN_MASK UINT8_C(0x07) +#define BMI160_STEP_MIN_BUF_MASK UINT8_C(0x07) + +/** Mask definition for FIFO Header Data Tag */ +#define BMI160_FIFO_TAG_INTR_MASK UINT8_C(0xFC) + +/** Fifo byte counter mask definitions */ +#define BMI160_FIFO_BYTE_COUNTER_MASK UINT8_C(0x07) + +/** Enable/disable bit value */ +#define BMI160_ENABLE UINT8_C(0x01) +#define BMI160_DISABLE UINT8_C(0x00) + +/** Latch Duration */ +#define BMI160_LATCH_DUR_NONE UINT8_C(0x00) +#define BMI160_LATCH_DUR_312_5_MICRO_SEC UINT8_C(0x01) +#define BMI160_LATCH_DUR_625_MICRO_SEC UINT8_C(0x02) +#define BMI160_LATCH_DUR_1_25_MILLI_SEC UINT8_C(0x03) +#define BMI160_LATCH_DUR_2_5_MILLI_SEC UINT8_C(0x04) +#define BMI160_LATCH_DUR_5_MILLI_SEC UINT8_C(0x05) +#define BMI160_LATCH_DUR_10_MILLI_SEC UINT8_C(0x06) +#define BMI160_LATCH_DUR_20_MILLI_SEC UINT8_C(0x07) +#define BMI160_LATCH_DUR_40_MILLI_SEC UINT8_C(0x08) +#define BMI160_LATCH_DUR_80_MILLI_SEC UINT8_C(0x09) +#define BMI160_LATCH_DUR_160_MILLI_SEC UINT8_C(0x0A) +#define BMI160_LATCH_DUR_320_MILLI_SEC UINT8_C(0x0B) +#define BMI160_LATCH_DUR_640_MILLI_SEC UINT8_C(0x0C) +#define BMI160_LATCH_DUR_1_28_SEC UINT8_C(0x0D) +#define BMI160_LATCH_DUR_2_56_SEC UINT8_C(0x0E) +#define BMI160_LATCHED UINT8_C(0x0F) + +/** BMI160 Register map */ +#define BMI160_CHIP_ID_ADDR UINT8_C(0x00) +#define BMI160_ERROR_REG_ADDR UINT8_C(0x02) +#define BMI160_PMU_STATUS_ADDR UINT8_C(0x03) +#define BMI160_AUX_DATA_ADDR UINT8_C(0x04) +#define BMI160_GYRO_DATA_ADDR UINT8_C(0x0C) +#define BMI160_ACCEL_DATA_ADDR UINT8_C(0x12) +#define BMI160_STATUS_ADDR UINT8_C(0x1B) +#define BMI160_INT_STATUS_ADDR UINT8_C(0x1C) +#define BMI160_FIFO_LENGTH_ADDR UINT8_C(0x22) +#define BMI160_FIFO_DATA_ADDR UINT8_C(0x24) +#define BMI160_ACCEL_CONFIG_ADDR UINT8_C(0x40) +#define BMI160_ACCEL_RANGE_ADDR UINT8_C(0x41) +#define BMI160_GYRO_CONFIG_ADDR UINT8_C(0x42) +#define BMI160_GYRO_RANGE_ADDR UINT8_C(0x43) +#define BMI160_AUX_ODR_ADDR UINT8_C(0x44) +#define BMI160_FIFO_DOWN_ADDR UINT8_C(0x45) +#define BMI160_FIFO_CONFIG_0_ADDR UINT8_C(0x46) +#define BMI160_FIFO_CONFIG_1_ADDR UINT8_C(0x47) +#define BMI160_AUX_IF_0_ADDR UINT8_C(0x4B) +#define BMI160_AUX_IF_1_ADDR UINT8_C(0x4C) +#define BMI160_AUX_IF_2_ADDR UINT8_C(0x4D) +#define BMI160_AUX_IF_3_ADDR UINT8_C(0x4E) +#define BMI160_AUX_IF_4_ADDR UINT8_C(0x4F) +#define BMI160_INT_ENABLE_0_ADDR UINT8_C(0x50) +#define BMI160_INT_ENABLE_1_ADDR UINT8_C(0x51) +#define BMI160_INT_ENABLE_2_ADDR UINT8_C(0x52) +#define BMI160_INT_OUT_CTRL_ADDR UINT8_C(0x53) +#define BMI160_INT_LATCH_ADDR UINT8_C(0x54) +#define BMI160_INT_MAP_0_ADDR UINT8_C(0x55) +#define BMI160_INT_MAP_1_ADDR UINT8_C(0x56) +#define BMI160_INT_MAP_2_ADDR UINT8_C(0x57) +#define BMI160_INT_DATA_0_ADDR UINT8_C(0x58) +#define BMI160_INT_DATA_1_ADDR UINT8_C(0x59) +#define BMI160_INT_LOWHIGH_0_ADDR UINT8_C(0x5A) +#define BMI160_INT_LOWHIGH_1_ADDR UINT8_C(0x5B) +#define BMI160_INT_LOWHIGH_2_ADDR UINT8_C(0x5C) +#define BMI160_INT_LOWHIGH_3_ADDR UINT8_C(0x5D) +#define BMI160_INT_LOWHIGH_4_ADDR UINT8_C(0x5E) +#define BMI160_INT_MOTION_0_ADDR UINT8_C(0x5F) +#define BMI160_INT_MOTION_1_ADDR UINT8_C(0x60) +#define BMI160_INT_MOTION_2_ADDR UINT8_C(0x61) +#define BMI160_INT_MOTION_3_ADDR UINT8_C(0x62) +#define BMI160_INT_TAP_0_ADDR UINT8_C(0x63) +#define BMI160_INT_TAP_1_ADDR UINT8_C(0x64) +#define BMI160_INT_ORIENT_0_ADDR UINT8_C(0x65) +#define BMI160_INT_ORIENT_1_ADDR UINT8_C(0x66) +#define BMI160_INT_FLAT_0_ADDR UINT8_C(0x67) +#define BMI160_INT_FLAT_1_ADDR UINT8_C(0x68) +#define BMI160_FOC_CONF_ADDR UINT8_C(0x69) +#define BMI160_CONF_ADDR UINT8_C(0x6A) + +#define BMI160_IF_CONF_ADDR UINT8_C(0x6B) +#define BMI160_SELF_TEST_ADDR UINT8_C(0x6D) +#define BMI160_OFFSET_ADDR UINT8_C(0x71) +#define BMI160_OFFSET_CONF_ADDR UINT8_C(0x77) +#define BMI160_INT_STEP_CNT_0_ADDR UINT8_C(0x78) +#define BMI160_INT_STEP_CONFIG_0_ADDR UINT8_C(0x7A) +#define BMI160_INT_STEP_CONFIG_1_ADDR UINT8_C(0x7B) +#define BMI160_COMMAND_REG_ADDR UINT8_C(0x7E) +#define BMI160_SPI_COMM_TEST_ADDR UINT8_C(0x7F) +#define BMI160_INTL_PULLUP_CONF_ADDR UINT8_C(0x85) + +/** Error code definitions */ +#define BMI160_OK INT8_C(0) +#define BMI160_E_NULL_PTR INT8_C(-1) +#define BMI160_E_COM_FAIL INT8_C(-2) +#define BMI160_E_DEV_NOT_FOUND INT8_C(-3) +#define BMI160_E_OUT_OF_RANGE INT8_C(-4) +#define BMI160_E_INVALID_INPUT INT8_C(-5) +#define BMI160_E_ACCEL_ODR_BW_INVALID INT8_C(-6) +#define BMI160_E_GYRO_ODR_BW_INVALID INT8_C(-7) +#define BMI160_E_LWP_PRE_FLTR_INT_INVALID INT8_C(-8) +#define BMI160_E_LWP_PRE_FLTR_INVALID INT8_C(-9) +#define BMI160_E_AUX_NOT_FOUND INT8_C(-10) +#define BMI160_E_FOC_FAILURE INT8_C(-11) +#define BMI160_E_READ_WRITE_LENGTH_INVALID INT8_C(-12) +#define BMI160_E_INVALID_CONFIG INT8_C(-13) + +/**\name API warning codes */ +#define BMI160_W_GYRO_SELF_TEST_FAIL INT8_C(1) +#define BMI160_W_ACCEl_SELF_TEST_FAIL INT8_C(2) + +/** BMI160 unique chip identifier */ +#define BMI160_CHIP_ID UINT8_C(0xD1) + +/** Soft reset command */ +#define BMI160_SOFT_RESET_CMD UINT8_C(0xb6) +#define BMI160_SOFT_RESET_DELAY_MS UINT8_C(1) + +/** Start FOC command */ +#define BMI160_START_FOC_CMD UINT8_C(0x03) + +/** NVM backup enabling command */ +#define BMI160_NVM_BACKUP_EN UINT8_C(0xA0) + +/* Delay in ms settings */ +#define BMI160_ACCEL_DELAY_MS UINT8_C(5) +#define BMI160_GYRO_DELAY_MS UINT8_C(80) +#define BMI160_ONE_MS_DELAY UINT8_C(1) +#define BMI160_AUX_COM_DELAY UINT8_C(10) +#define BMI160_GYRO_SELF_TEST_DELAY UINT8_C(20) +#define BMI160_ACCEL_SELF_TEST_DELAY UINT8_C(50) + +/** Self test configurations */ +#define BMI160_ACCEL_SELF_TEST_CONFIG UINT8_C(0x2C) +#define BMI160_ACCEL_SELF_TEST_POSITIVE_EN UINT8_C(0x0D) +#define BMI160_ACCEL_SELF_TEST_NEGATIVE_EN UINT8_C(0x09) +#define BMI160_ACCEL_SELF_TEST_LIMIT UINT16_C(8192) + +/** Power mode settings */ +/* Accel power mode */ +#define BMI160_ACCEL_NORMAL_MODE UINT8_C(0x11) +#define BMI160_ACCEL_LOWPOWER_MODE UINT8_C(0x12) +#define BMI160_ACCEL_SUSPEND_MODE UINT8_C(0x10) + +/* Gyro power mode */ +#define BMI160_GYRO_SUSPEND_MODE UINT8_C(0x14) +#define BMI160_GYRO_NORMAL_MODE UINT8_C(0x15) +#define BMI160_GYRO_FASTSTARTUP_MODE UINT8_C(0x17) + +/* Aux power mode */ +#define BMI160_AUX_SUSPEND_MODE UINT8_C(0x18) +#define BMI160_AUX_NORMAL_MODE UINT8_C(0x19) +#define BMI160_AUX_LOWPOWER_MODE UINT8_C(0x1A) + +/** Range settings */ +/* Accel Range */ +#define BMI160_ACCEL_RANGE_2G UINT8_C(0x03) +#define BMI160_ACCEL_RANGE_4G UINT8_C(0x05) +#define BMI160_ACCEL_RANGE_8G UINT8_C(0x08) +#define BMI160_ACCEL_RANGE_16G UINT8_C(0x0C) + +/* Gyro Range */ +#define BMI160_GYRO_RANGE_2000_DPS UINT8_C(0x00) +#define BMI160_GYRO_RANGE_1000_DPS UINT8_C(0x01) +#define BMI160_GYRO_RANGE_500_DPS UINT8_C(0x02) +#define BMI160_GYRO_RANGE_250_DPS UINT8_C(0x03) +#define BMI160_GYRO_RANGE_125_DPS UINT8_C(0x04) + +/** Bandwidth settings */ +/* Accel Bandwidth */ +#define BMI160_ACCEL_BW_OSR4_AVG1 UINT8_C(0x00) +#define BMI160_ACCEL_BW_OSR2_AVG2 UINT8_C(0x01) +#define BMI160_ACCEL_BW_NORMAL_AVG4 UINT8_C(0x02) +#define BMI160_ACCEL_BW_RES_AVG8 UINT8_C(0x03) +#define BMI160_ACCEL_BW_RES_AVG16 UINT8_C(0x04) +#define BMI160_ACCEL_BW_RES_AVG32 UINT8_C(0x05) +#define BMI160_ACCEL_BW_RES_AVG64 UINT8_C(0x06) +#define BMI160_ACCEL_BW_RES_AVG128 UINT8_C(0x07) + +#define BMI160_GYRO_BW_OSR4_MODE UINT8_C(0x00) +#define BMI160_GYRO_BW_OSR2_MODE UINT8_C(0x01) +#define BMI160_GYRO_BW_NORMAL_MODE UINT8_C(0x02) + +/* Output Data Rate settings */ +/* Accel Output data rate */ +#define BMI160_ACCEL_ODR_RESERVED UINT8_C(0x00) +#define BMI160_ACCEL_ODR_0_78HZ UINT8_C(0x01) +#define BMI160_ACCEL_ODR_1_56HZ UINT8_C(0x02) +#define BMI160_ACCEL_ODR_3_12HZ UINT8_C(0x03) +#define BMI160_ACCEL_ODR_6_25HZ UINT8_C(0x04) +#define BMI160_ACCEL_ODR_12_5HZ UINT8_C(0x05) +#define BMI160_ACCEL_ODR_25HZ UINT8_C(0x06) +#define BMI160_ACCEL_ODR_50HZ UINT8_C(0x07) +#define BMI160_ACCEL_ODR_100HZ UINT8_C(0x08) +#define BMI160_ACCEL_ODR_200HZ UINT8_C(0x09) +#define BMI160_ACCEL_ODR_400HZ UINT8_C(0x0A) +#define BMI160_ACCEL_ODR_800HZ UINT8_C(0x0B) +#define BMI160_ACCEL_ODR_1600HZ UINT8_C(0x0C) +#define BMI160_ACCEL_ODR_RESERVED0 UINT8_C(0x0D) +#define BMI160_ACCEL_ODR_RESERVED1 UINT8_C(0x0E) +#define BMI160_ACCEL_ODR_RESERVED2 UINT8_C(0x0F) + +/* Gyro Output data rate */ +#define BMI160_GYRO_ODR_RESERVED UINT8_C(0x00) +#define BMI160_GYRO_ODR_25HZ UINT8_C(0x06) +#define BMI160_GYRO_ODR_50HZ UINT8_C(0x07) +#define BMI160_GYRO_ODR_100HZ UINT8_C(0x08) +#define BMI160_GYRO_ODR_200HZ UINT8_C(0x09) +#define BMI160_GYRO_ODR_400HZ UINT8_C(0x0A) +#define BMI160_GYRO_ODR_800HZ UINT8_C(0x0B) +#define BMI160_GYRO_ODR_1600HZ UINT8_C(0x0C) +#define BMI160_GYRO_ODR_3200HZ UINT8_C(0x0D) + +/* Auxiliary sensor Output data rate */ +#define BMI160_AUX_ODR_RESERVED UINT8_C(0x00) +#define BMI160_AUX_ODR_0_78HZ UINT8_C(0x01) +#define BMI160_AUX_ODR_1_56HZ UINT8_C(0x02) +#define BMI160_AUX_ODR_3_12HZ UINT8_C(0x03) +#define BMI160_AUX_ODR_6_25HZ UINT8_C(0x04) +#define BMI160_AUX_ODR_12_5HZ UINT8_C(0x05) +#define BMI160_AUX_ODR_25HZ UINT8_C(0x06) +#define BMI160_AUX_ODR_50HZ UINT8_C(0x07) +#define BMI160_AUX_ODR_100HZ UINT8_C(0x08) +#define BMI160_AUX_ODR_200HZ UINT8_C(0x09) +#define BMI160_AUX_ODR_400HZ UINT8_C(0x0A) +#define BMI160_AUX_ODR_800HZ UINT8_C(0x0B) + +/** FIFO_CONFIG Definitions */ +#define BMI160_FIFO_TIME_ENABLE UINT8_C(0x02) +#define BMI160_FIFO_TAG_INT2_ENABLE UINT8_C(0x04) +#define BMI160_FIFO_TAG_INT1_ENABLE UINT8_C(0x08) +#define BMI160_FIFO_HEAD_ENABLE UINT8_C(0x10) +#define BMI160_FIFO_M_ENABLE UINT8_C(0x20) +#define BMI160_FIFO_A_ENABLE UINT8_C(0x40) +#define BMI160_FIFO_M_A_ENABLE UINT8_C(0x60) +#define BMI160_FIFO_G_ENABLE UINT8_C(0x80) +#define BMI160_FIFO_M_G_ENABLE UINT8_C(0xA0) +#define BMI160_FIFO_G_A_ENABLE UINT8_C(0xC0) +#define BMI160_FIFO_M_G_A_ENABLE UINT8_C(0xE0) + +/* Macro to specify the number of bytes over-read from the + * FIFO in order to get the sensor time at the end of FIFO */ +#ifndef BMI160_FIFO_BYTES_OVERREAD +#define BMI160_FIFO_BYTES_OVERREAD UINT8_C(25) +#endif + +/* Accel, gyro and aux. sensor length and also their combined + * length definitions in FIFO */ +#define BMI160_FIFO_G_LENGTH UINT8_C(6) +#define BMI160_FIFO_A_LENGTH UINT8_C(6) +#define BMI160_FIFO_M_LENGTH UINT8_C(8) +#define BMI160_FIFO_GA_LENGTH UINT8_C(12) +#define BMI160_FIFO_MA_LENGTH UINT8_C(14) +#define BMI160_FIFO_MG_LENGTH UINT8_C(14) +#define BMI160_FIFO_MGA_LENGTH UINT8_C(20) + +/** FIFO Header Data definitions */ +#define BMI160_FIFO_HEAD_SKIP_FRAME UINT8_C(0x40) +#define BMI160_FIFO_HEAD_SENSOR_TIME UINT8_C(0x44) +#define BMI160_FIFO_HEAD_INPUT_CONFIG UINT8_C(0x48) +#define BMI160_FIFO_HEAD_OVER_READ UINT8_C(0x80) +#define BMI160_FIFO_HEAD_A UINT8_C(0x84) +#define BMI160_FIFO_HEAD_G UINT8_C(0x88) +#define BMI160_FIFO_HEAD_G_A UINT8_C(0x8C) +#define BMI160_FIFO_HEAD_M UINT8_C(0x90) +#define BMI160_FIFO_HEAD_M_A UINT8_C(0x94) +#define BMI160_FIFO_HEAD_M_G UINT8_C(0x98) +#define BMI160_FIFO_HEAD_M_G_A UINT8_C(0x9C) + +/** FIFO sensor time length definitions */ +#define BMI160_SENSOR_TIME_LENGTH UINT8_C(3) + +/** FIFO DOWN selection */ +/* Accel fifo down-sampling values*/ +#define BMI160_ACCEL_FIFO_DOWN_ZERO UINT8_C(0x00) +#define BMI160_ACCEL_FIFO_DOWN_ONE UINT8_C(0x10) +#define BMI160_ACCEL_FIFO_DOWN_TWO UINT8_C(0x20) +#define BMI160_ACCEL_FIFO_DOWN_THREE UINT8_C(0x30) +#define BMI160_ACCEL_FIFO_DOWN_FOUR UINT8_C(0x40) +#define BMI160_ACCEL_FIFO_DOWN_FIVE UINT8_C(0x50) +#define BMI160_ACCEL_FIFO_DOWN_SIX UINT8_C(0x60) +#define BMI160_ACCEL_FIFO_DOWN_SEVEN UINT8_C(0x70) + +/* Gyro fifo down-smapling values*/ +#define BMI160_GYRO_FIFO_DOWN_ZERO UINT8_C(0x00) +#define BMI160_GYRO_FIFO_DOWN_ONE UINT8_C(0x01) +#define BMI160_GYRO_FIFO_DOWN_TWO UINT8_C(0x02) +#define BMI160_GYRO_FIFO_DOWN_THREE UINT8_C(0x03) +#define BMI160_GYRO_FIFO_DOWN_FOUR UINT8_C(0x04) +#define BMI160_GYRO_FIFO_DOWN_FIVE UINT8_C(0x05) +#define BMI160_GYRO_FIFO_DOWN_SIX UINT8_C(0x06) +#define BMI160_GYRO_FIFO_DOWN_SEVEN UINT8_C(0x07) + +/* Accel Fifo filter enable*/ +#define BMI160_ACCEL_FIFO_FILT_EN UINT8_C(0x80) + +/* Gyro Fifo filter enable*/ +#define BMI160_GYRO_FIFO_FILT_EN UINT8_C(0x08) + +/** Definitions to check validity of FIFO frames */ +#define FIFO_CONFIG_MSB_CHECK UINT8_C(0x80) +#define FIFO_CONFIG_LSB_CHECK UINT8_C(0x00) + +/*! BMI160 accel FOC configurations */ +#define BMI160_FOC_ACCEL_DISABLED UINT8_C(0x00) +#define BMI160_FOC_ACCEL_POSITIVE_G UINT8_C(0x01) +#define BMI160_FOC_ACCEL_NEGATIVE_G UINT8_C(0x02) +#define BMI160_FOC_ACCEL_0G UINT8_C(0x03) + +/** Array Parameter DefinItions */ +#define BMI160_SENSOR_TIME_LSB_BYTE UINT8_C(0) +#define BMI160_SENSOR_TIME_XLSB_BYTE UINT8_C(1) +#define BMI160_SENSOR_TIME_MSB_BYTE UINT8_C(2) + +/** Interface settings */ +#define BMI160_SPI_INTF UINT8_C(1) +#define BMI160_I2C_INTF UINT8_C(0) +#define BMI160_SPI_RD_MASK UINT8_C(0x80) +#define BMI160_SPI_WR_MASK UINT8_C(0x7F) + +/* Sensor & time select definition*/ +#define BMI160_ACCEL_SEL UINT8_C(0x01) +#define BMI160_GYRO_SEL UINT8_C(0x02) +#define BMI160_TIME_SEL UINT8_C(0x04) + +/* Sensor select mask*/ +#define BMI160_SEN_SEL_MASK UINT8_C(0x07) + +/* Error code mask */ +#define BMI160_ERR_REG_MASK UINT8_C(0x0F) + +/* BMI160 I2C address */ +#define BMI160_I2C_ADDR UINT8_C(0x68) + +/* BMI160 secondary IF address */ +#define BMI160_AUX_BMM150_I2C_ADDR UINT8_C(0x10) + +/** BMI160 Length definitions */ +#define BMI160_ONE UINT8_C(1) +#define BMI160_TWO UINT8_C(2) +#define BMI160_THREE UINT8_C(3) +#define BMI160_FOUR UINT8_C(4) +#define BMI160_FIVE UINT8_C(5) + +/** BMI160 fifo level Margin */ +#define BMI160_FIFO_LEVEL_MARGIN UINT8_C(16) + +/** BMI160 fifo flush Command */ +#define BMI160_FIFO_FLUSH_VALUE UINT8_C(0xB0) + +/** BMI160 offset values for xyz axes of accel */ +#define BMI160_ACCEL_MIN_OFFSET INT8_C(-128) +#define BMI160_ACCEL_MAX_OFFSET INT8_C(127) + +/** BMI160 offset values for xyz axes of gyro */ +#define BMI160_GYRO_MIN_OFFSET INT16_C(-512) +#define BMI160_GYRO_MAX_OFFSET INT16_C(511) + +/** BMI160 fifo full interrupt position and mask */ +#define BMI160_FIFO_FULL_INT_POS UINT8_C(5) +#define BMI160_FIFO_FULL_INT_MSK UINT8_C(0x20) +#define BMI160_FIFO_WTM_INT_POS UINT8_C(6) +#define BMI160_FIFO_WTM_INT_MSK UINT8_C(0x40) + +#define BMI160_FIFO_FULL_INT_PIN1_POS UINT8_C(5) +#define BMI160_FIFO_FULL_INT_PIN1_MSK UINT8_C(0x20) +#define BMI160_FIFO_FULL_INT_PIN2_POS UINT8_C(1) +#define BMI160_FIFO_FULL_INT_PIN2_MSK UINT8_C(0x02) + +#define BMI160_FIFO_WTM_INT_PIN1_POS UINT8_C(6) +#define BMI160_FIFO_WTM_INT_PIN1_MSK UINT8_C(0x40) +#define BMI160_FIFO_WTM_INT_PIN2_POS UINT8_C(2) +#define BMI160_FIFO_WTM_INT_PIN2_MSK UINT8_C(0x04) + +#define BMI160_MANUAL_MODE_EN_POS UINT8_C(7) +#define BMI160_MANUAL_MODE_EN_MSK UINT8_C(0x80) +#define BMI160_AUX_READ_BURST_POS UINT8_C(0) +#define BMI160_AUX_READ_BURST_MSK UINT8_C(0x03) + +#define BMI160_GYRO_SELF_TEST_POS UINT8_C(4) +#define BMI160_GYRO_SELF_TEST_MSK UINT8_C(0x10) +#define BMI160_GYRO_SELF_TEST_STATUS_POS UINT8_C(1) +#define BMI160_GYRO_SELF_TEST_STATUS_MSK UINT8_C(0x02) + +#define BMI160_GYRO_FOC_EN_POS UINT8_C(6) +#define BMI160_GYRO_FOC_EN_MSK UINT8_C(0x40) + +#define BMI160_ACCEL_FOC_X_CONF_POS UINT8_C(4) +#define BMI160_ACCEL_FOC_X_CONF_MSK UINT8_C(0x30) + +#define BMI160_ACCEL_FOC_Y_CONF_POS UINT8_C(2) +#define BMI160_ACCEL_FOC_Y_CONF_MSK UINT8_C(0x0C) + +#define BMI160_ACCEL_FOC_Z_CONF_MSK UINT8_C(0x03) + +#define BMI160_FOC_STATUS_POS UINT8_C(3) +#define BMI160_FOC_STATUS_MSK UINT8_C(0x08) + +#define BMI160_GYRO_OFFSET_X_MSK UINT8_C(0x03) + +#define BMI160_GYRO_OFFSET_Y_POS UINT8_C(2) +#define BMI160_GYRO_OFFSET_Y_MSK UINT8_C(0x0C) + +#define BMI160_GYRO_OFFSET_Z_POS UINT8_C(4) +#define BMI160_GYRO_OFFSET_Z_MSK UINT8_C(0x30) + +#define BMI160_GYRO_OFFSET_EN_POS UINT8_C(7) +#define BMI160_GYRO_OFFSET_EN_MSK UINT8_C(0x80) + +#define BMI160_ACCEL_OFFSET_EN_POS UINT8_C(6) +#define BMI160_ACCEL_OFFSET_EN_MSK UINT8_C(0x40) + +#define BMI160_GYRO_OFFSET_POS UINT16_C(8) +#define BMI160_GYRO_OFFSET_MSK UINT16_C(0x0300) + +#define BMI160_NVM_UPDATE_POS UINT8_C(1) +#define BMI160_NVM_UPDATE_MSK UINT8_C(0x02) + +#define BMI160_NVM_STATUS_POS UINT8_C(4) +#define BMI160_NVM_STATUS_MSK UINT8_C(0x10) + +#define BMI160_MAG_POWER_MODE_MSK UINT8_C(0x03) + +#define BMI160_ACCEL_POWER_MODE_MSK UINT8_C(0x30) +#define BMI160_ACCEL_POWER_MODE_POS UINT8_C(4) + +#define BMI160_GYRO_POWER_MODE_MSK UINT8_C(0x0C) +#define BMI160_GYRO_POWER_MODE_POS UINT8_C(2) + +/* BIT SLICE GET AND SET FUNCTIONS */ +#define BMI160_GET_BITS(regvar, bitname) ((regvar & bitname##_MSK) >> bitname##_POS) +#define BMI160_SET_BITS(regvar, bitname, val) \ + ((regvar & ~bitname##_MSK) | ((val << bitname##_POS) & bitname##_MSK)) + +#define BMI160_SET_BITS_POS_0(reg_data, bitname, data) \ + ((reg_data & ~(bitname##_MSK)) | (data & bitname##_MSK)) + +#define BMI160_GET_BITS_POS_0(reg_data, bitname) (reg_data & (bitname##_MSK)) + +/**\name UTILITY MACROS */ +#define BMI160_SET_LOW_BYTE UINT16_C(0x00FF) +#define BMI160_SET_HIGH_BYTE UINT16_C(0xFF00) + +#define BMI160_GET_LSB(var) (uint8_t)(var & BMI160_SET_LOW_BYTE) +#define BMI160_GET_MSB(var) (uint8_t)((var & BMI160_SET_HIGH_BYTE) >> 8) + +/*****************************************************************************/ +/* type definitions */ + +/*! + * @brief Bus communication function pointer which should be mapped to + * the platform specific read functions of the user + */ +typedef int8_t ( + *bmi160_read_fptr_t)(uint8_t dev_addr, uint8_t reg_addr, uint8_t* data, uint16_t len); + +/*! + * @brief Bus communication function pointer which should be mapped to + * the platform specific write functions of the user + */ +typedef int8_t ( + *bmi160_write_fptr_t)(uint8_t dev_addr, uint8_t reg_addr, uint8_t* read_data, uint16_t len); +typedef void (*bmi160_delay_fptr_t)(uint32_t period); + +/*************************** Data structures *********************************/ + +/*! + * @brief bmi160 interrupt status selection enum. + */ +enum bmi160_int_status_sel { + BMI160_INT_STATUS_0 = 1, + BMI160_INT_STATUS_1 = 2, + BMI160_INT_STATUS_2 = 4, + BMI160_INT_STATUS_3 = 8, + BMI160_INT_STATUS_ALL = 15 +}; + +/*! + * @brief bmi160 interrupt status bits structure + */ +struct bmi160_int_status_bits { +#ifdef LITTLE_ENDIAN + + uint32_t step : 1; + uint32_t sigmot : 1; + uint32_t anym : 1; + + /* pmu trigger will be handled later */ + uint32_t pmu_trigger_reserved : 1; + uint32_t d_tap : 1; + uint32_t s_tap : 1; + uint32_t orient : 1; + uint32_t flat_int : 1; + uint32_t reserved : 2; + uint32_t high_g : 1; + uint32_t low_g : 1; + uint32_t drdy : 1; + uint32_t ffull : 1; + uint32_t fwm : 1; + uint32_t nomo : 1; + uint32_t anym_first_x : 1; + uint32_t anym_first_y : 1; + uint32_t anym_first_z : 1; + uint32_t anym_sign : 1; + uint32_t tap_first_x : 1; + uint32_t tap_first_y : 1; + uint32_t tap_first_z : 1; + uint32_t tap_sign : 1; + uint32_t high_first_x : 1; + uint32_t high_first_y : 1; + uint32_t high_first_z : 1; + uint32_t high_sign : 1; + uint32_t orient_1_0 : 2; + uint32_t orient_2 : 1; + uint32_t flat : 1; +#else + uint32_t high_first_x : 1; + uint32_t high_first_y : 1; + uint32_t high_first_z : 1; + uint32_t high_sign : 1; + uint32_t orient_1_0 : 2; + uint32_t orient_2 : 1; + uint32_t flat : 1; + uint32_t anym_first_x : 1; + uint32_t anym_first_y : 1; + uint32_t anym_first_z : 1; + uint32_t anym_sign : 1; + uint32_t tap_first_x : 1; + uint32_t tap_first_y : 1; + uint32_t tap_first_z : 1; + uint32_t tap_sign : 1; + uint32_t reserved : 2; + uint32_t high_g : 1; + uint32_t low_g : 1; + uint32_t drdy : 1; + uint32_t ffull : 1; + uint32_t fwm : 1; + uint32_t nomo : 1; + uint32_t step : 1; + uint32_t sigmot : 1; + uint32_t anym : 1; + + /* pmu trigger will be handled later */ + uint32_t pmu_trigger_reserved : 1; + uint32_t d_tap : 1; + uint32_t s_tap : 1; + uint32_t orient : 1; + uint32_t flat_int : 1; +#endif +}; + +/*! + * @brief bmi160 interrupt status structure + */ +union bmi160_int_status { + uint8_t data[4]; + struct bmi160_int_status_bits bit; +}; + +/*! + * @brief bmi160 sensor data structure which comprises of accel data + */ +struct bmi160_sensor_data { + /*! X-axis sensor data */ + int16_t x; + + /*! Y-axis sensor data */ + int16_t y; + + /*! Z-axis sensor data */ + int16_t z; + + /*! sensor time */ + uint32_t sensortime; +}; + +/*! + * @brief bmi160 aux data structure which comprises of 8 bytes of accel data + */ +struct bmi160_aux_data { + /*! Auxiliary data */ + uint8_t data[8]; +}; + +/*! + * @brief bmi160 FOC configuration structure + */ +struct bmi160_foc_conf { + /*! Enabling FOC in gyro + * Assignable macros : + * - BMI160_ENABLE + * - BMI160_DISABLE + */ + uint8_t foc_gyr_en; + + /*! Accel FOC configurations + * Assignable macros : + * - BMI160_FOC_ACCEL_DISABLED + * - BMI160_FOC_ACCEL_POSITIVE_G + * - BMI160_FOC_ACCEL_NEGATIVE_G + * - BMI160_FOC_ACCEL_0G + */ + uint8_t foc_acc_x; + uint8_t foc_acc_y; + uint8_t foc_acc_z; + + /*! Enabling offset compensation for accel in data registers + * Assignable macros : + * - BMI160_ENABLE + * - BMI160_DISABLE + */ + uint8_t acc_off_en; + + /*! Enabling offset compensation for gyro in data registers + * Assignable macros : + * - BMI160_ENABLE + * - BMI160_DISABLE + */ + uint8_t gyro_off_en; +}; + +/*! + * @brief bmi160 accel gyro offsets + */ +struct bmi160_offsets { + /*! Accel offset for x axis */ + int8_t off_acc_x; + + /*! Accel offset for y axis */ + int8_t off_acc_y; + + /*! Accel offset for z axis */ + int8_t off_acc_z; + + /*! Gyro offset for x axis */ + int16_t off_gyro_x; + + /*! Gyro offset for y axis */ + int16_t off_gyro_y; + + /*! Gyro offset for z axis */ + int16_t off_gyro_z; +}; + +/*! + * @brief FIFO aux. sensor data structure + */ +struct bmi160_aux_fifo_data { + /*! The value of aux. sensor x LSB data */ + uint8_t aux_x_lsb; + + /*! The value of aux. sensor x MSB data */ + uint8_t aux_x_msb; + + /*! The value of aux. sensor y LSB data */ + uint8_t aux_y_lsb; + + /*! The value of aux. sensor y MSB data */ + uint8_t aux_y_msb; + + /*! The value of aux. sensor z LSB data */ + uint8_t aux_z_lsb; + + /*! The value of aux. sensor z MSB data */ + uint8_t aux_z_msb; + + /*! The value of aux. sensor r for BMM150 LSB data */ + uint8_t aux_r_y2_lsb; + + /*! The value of aux. sensor r for BMM150 MSB data */ + uint8_t aux_r_y2_msb; +}; + +/*! + * @brief bmi160 sensor select structure + */ +enum bmi160_select_sensor { BMI160_ACCEL_ONLY = 1, BMI160_GYRO_ONLY, BMI160_BOTH_ACCEL_AND_GYRO }; + +/*! + * @brief bmi160 sensor step detector mode structure + */ +enum bmi160_step_detect_mode { + BMI160_STEP_DETECT_NORMAL, + BMI160_STEP_DETECT_SENSITIVE, + BMI160_STEP_DETECT_ROBUST, + + /*! Non recommended User defined setting */ + BMI160_STEP_DETECT_USER_DEFINE +}; + +/*! + * @brief enum for auxiliary burst read selection + */ +enum bmi160_aux_read_len { + BMI160_AUX_READ_LEN_0, + BMI160_AUX_READ_LEN_1, + BMI160_AUX_READ_LEN_2, + BMI160_AUX_READ_LEN_3 +}; + +/*! + * @brief bmi160 sensor configuration structure + */ +struct bmi160_cfg { + /*! power mode */ + uint8_t power; + + /*! output data rate */ + uint8_t odr; + + /*! range */ + uint8_t range; + + /*! bandwidth */ + uint8_t bw; +}; + +/*! + * @brief Aux sensor configuration structure + */ +struct bmi160_aux_cfg { + /*! Aux sensor, 1 - enable 0 - disable */ + uint8_t aux_sensor_enable : 1; + + /*! Aux manual/auto mode status */ + uint8_t manual_enable : 1; + + /*! Aux read burst length */ + uint8_t aux_rd_burst_len : 2; + + /*! output data rate */ + uint8_t aux_odr : 4; + + /*! i2c addr of auxiliary sensor */ + uint8_t aux_i2c_addr; +}; + +/*! + * @brief bmi160 interrupt channel selection structure + */ +enum bmi160_int_channel { + /*! Un-map both channels */ + BMI160_INT_CHANNEL_NONE, + + /*! interrupt Channel 1 */ + BMI160_INT_CHANNEL_1, + + /*! interrupt Channel 2 */ + BMI160_INT_CHANNEL_2, + + /*! Map both channels */ + BMI160_INT_CHANNEL_BOTH +}; +enum bmi160_int_types { + /*! Slope/Any-motion interrupt */ + BMI160_ACC_ANY_MOTION_INT, + + /*! Significant motion interrupt */ + BMI160_ACC_SIG_MOTION_INT, + + /*! Step detector interrupt */ + BMI160_STEP_DETECT_INT, + + /*! double tap interrupt */ + BMI160_ACC_DOUBLE_TAP_INT, + + /*! single tap interrupt */ + BMI160_ACC_SINGLE_TAP_INT, + + /*! orientation interrupt */ + BMI160_ACC_ORIENT_INT, + + /*! flat interrupt */ + BMI160_ACC_FLAT_INT, + + /*! high-g interrupt */ + BMI160_ACC_HIGH_G_INT, + + /*! low-g interrupt */ + BMI160_ACC_LOW_G_INT, + + /*! slow/no-motion interrupt */ + BMI160_ACC_SLOW_NO_MOTION_INT, + + /*! data ready interrupt */ + BMI160_ACC_GYRO_DATA_RDY_INT, + + /*! fifo full interrupt */ + BMI160_ACC_GYRO_FIFO_FULL_INT, + + /*! fifo watermark interrupt */ + BMI160_ACC_GYRO_FIFO_WATERMARK_INT, + + /*! fifo tagging feature support */ + BMI160_FIFO_TAG_INT_PIN +}; + +/*! + * @brief bmi160 active state of any & sig motion interrupt. + */ +enum bmi160_any_sig_motion_active_interrupt_state { + /*! Both any & sig motion are disabled */ + BMI160_BOTH_ANY_SIG_MOTION_DISABLED = -1, + + /*! Any-motion selected */ + BMI160_ANY_MOTION_ENABLED, + + /*! Sig-motion selected */ + BMI160_SIG_MOTION_ENABLED +}; +struct bmi160_acc_tap_int_cfg { +#ifdef LITTLE_ENDIAN + + /*! tap threshold */ + uint16_t tap_thr : 5; + + /*! tap shock */ + uint16_t tap_shock : 1; + + /*! tap quiet */ + uint16_t tap_quiet : 1; + + /*! tap duration */ + uint16_t tap_dur : 3; + + /*! data source 0- filter & 1 pre-filter*/ + uint16_t tap_data_src : 1; + + /*! tap enable, 1 - enable, 0 - disable */ + uint16_t tap_en : 1; +#else + + /*! tap enable, 1 - enable, 0 - disable */ + uint16_t tap_en : 1; + + /*! data source 0- filter & 1 pre-filter*/ + uint16_t tap_data_src : 1; + + /*! tap duration */ + uint16_t tap_dur : 3; + + /*! tap quiet */ + uint16_t tap_quiet : 1; + + /*! tap shock */ + uint16_t tap_shock : 1; + + /*! tap threshold */ + uint16_t tap_thr : 5; +#endif +}; +struct bmi160_acc_any_mot_int_cfg { +#ifdef LITTLE_ENDIAN + + /*! 1 any-motion enable, 0 - any-motion disable */ + uint8_t anymotion_en : 1; + + /*! slope interrupt x, 1 - enable, 0 - disable */ + uint8_t anymotion_x : 1; + + /*! slope interrupt y, 1 - enable, 0 - disable */ + uint8_t anymotion_y : 1; + + /*! slope interrupt z, 1 - enable, 0 - disable */ + uint8_t anymotion_z : 1; + + /*! slope duration */ + uint8_t anymotion_dur : 2; + + /*! data source 0- filter & 1 pre-filter*/ + uint8_t anymotion_data_src : 1; + + /*! slope threshold */ + uint8_t anymotion_thr; +#else + + /*! slope threshold */ + uint8_t anymotion_thr; + + /*! data source 0- filter & 1 pre-filter*/ + uint8_t anymotion_data_src : 1; + + /*! slope duration */ + uint8_t anymotion_dur : 2; + + /*! slope interrupt z, 1 - enable, 0 - disable */ + uint8_t anymotion_z : 1; + + /*! slope interrupt y, 1 - enable, 0 - disable */ + uint8_t anymotion_y : 1; + + /*! slope interrupt x, 1 - enable, 0 - disable */ + uint8_t anymotion_x : 1; + + /*! 1 any-motion enable, 0 - any-motion disable */ + uint8_t anymotion_en : 1; +#endif +}; +struct bmi160_acc_sig_mot_int_cfg { +#ifdef LITTLE_ENDIAN + + /*! skip time of sig-motion interrupt */ + uint8_t sig_mot_skip : 2; + + /*! proof time of sig-motion interrupt */ + uint8_t sig_mot_proof : 2; + + /*! data source 0- filter & 1 pre-filter*/ + uint8_t sig_data_src : 1; + + /*! 1 - enable sig, 0 - disable sig & enable anymotion */ + uint8_t sig_en : 1; + + /*! sig-motion threshold */ + uint8_t sig_mot_thres; +#else + + /*! sig-motion threshold */ + uint8_t sig_mot_thres; + + /*! 1 - enable sig, 0 - disable sig & enable anymotion */ + uint8_t sig_en : 1; + + /*! data source 0- filter & 1 pre-filter*/ + uint8_t sig_data_src : 1; + + /*! proof time of sig-motion interrupt */ + uint8_t sig_mot_proof : 2; + + /*! skip time of sig-motion interrupt */ + uint8_t sig_mot_skip : 2; +#endif +}; +struct bmi160_acc_step_detect_int_cfg { +#ifdef LITTLE_ENDIAN + + /*! 1- step detector enable, 0- step detector disable */ + uint16_t step_detector_en : 1; + + /*! minimum threshold */ + uint16_t min_threshold : 2; + + /*! minimal detectable step time */ + uint16_t steptime_min : 3; + + /*! enable step counter mode setting */ + uint16_t step_detector_mode : 2; + + /*! minimum step buffer size*/ + uint16_t step_min_buf : 3; +#else + + /*! minimum step buffer size*/ + uint16_t step_min_buf : 3; + + /*! enable step counter mode setting */ + uint16_t step_detector_mode : 2; + + /*! minimal detectable step time */ + uint16_t steptime_min : 3; + + /*! minimum threshold */ + uint16_t min_threshold : 2; + + /*! 1- step detector enable, 0- step detector disable */ + uint16_t step_detector_en : 1; +#endif +}; +struct bmi160_acc_no_motion_int_cfg { +#ifdef LITTLE_ENDIAN + + /*! no motion interrupt x */ + uint16_t no_motion_x : 1; + + /*! no motion interrupt y */ + uint16_t no_motion_y : 1; + + /*! no motion interrupt z */ + uint16_t no_motion_z : 1; + + /*! no motion duration */ + uint16_t no_motion_dur : 6; + + /*! no motion sel , 1 - enable no-motion ,0- enable slow-motion */ + uint16_t no_motion_sel : 1; + + /*! data source 0- filter & 1 pre-filter*/ + uint16_t no_motion_src : 1; + + /*! no motion threshold */ + uint8_t no_motion_thres; +#else + + /*! no motion threshold */ + uint8_t no_motion_thres; + + /*! data source 0- filter & 1 pre-filter*/ + uint16_t no_motion_src : 1; + + /*! no motion sel , 1 - enable no-motion ,0- enable slow-motion */ + uint16_t no_motion_sel : 1; + + /*! no motion duration */ + uint16_t no_motion_dur : 6; + + /* no motion interrupt z */ + uint16_t no_motion_z : 1; + + /*! no motion interrupt y */ + uint16_t no_motion_y : 1; + + /*! no motion interrupt x */ + uint16_t no_motion_x : 1; +#endif +}; +struct bmi160_acc_orient_int_cfg { +#ifdef LITTLE_ENDIAN + + /*! thresholds for switching between the different orientations */ + uint16_t orient_mode : 2; + + /*! blocking_mode */ + uint16_t orient_blocking : 2; + + /*! Orientation interrupt hysteresis */ + uint16_t orient_hyst : 4; + + /*! Orientation interrupt theta */ + uint16_t orient_theta : 6; + + /*! Enable/disable Orientation interrupt */ + uint16_t orient_ud_en : 1; + + /*! exchange x- and z-axis in algorithm ,0 - z, 1 - x */ + uint16_t axes_ex : 1; + + /*! 1 - orient enable, 0 - orient disable */ + uint8_t orient_en : 1; +#else + + /*! 1 - orient enable, 0 - orient disable */ + uint8_t orient_en : 1; + + /*! exchange x- and z-axis in algorithm ,0 - z, 1 - x */ + uint16_t axes_ex : 1; + + /*! Enable/disable Orientation interrupt */ + uint16_t orient_ud_en : 1; + + /*! Orientation interrupt theta */ + uint16_t orient_theta : 6; + + /*! Orientation interrupt hysteresis */ + uint16_t orient_hyst : 4; + + /*! blocking_mode */ + uint16_t orient_blocking : 2; + + /*! thresholds for switching between the different orientations */ + uint16_t orient_mode : 2; +#endif +}; +struct bmi160_acc_flat_detect_int_cfg { +#ifdef LITTLE_ENDIAN + + /*! flat threshold */ + uint16_t flat_theta : 6; + + /*! flat interrupt hysteresis */ + uint16_t flat_hy : 3; + + /*! delay time for which the flat value must remain stable for the + * flat interrupt to be generated */ + uint16_t flat_hold_time : 2; + + /*! 1 - flat enable, 0 - flat disable */ + uint16_t flat_en : 1; +#else + + /*! 1 - flat enable, 0 - flat disable */ + uint16_t flat_en : 1; + + /*! delay time for which the flat value must remain stable for the + * flat interrupt to be generated */ + uint16_t flat_hold_time : 2; + + /*! flat interrupt hysteresis */ + uint16_t flat_hy : 3; + + /*! flat threshold */ + uint16_t flat_theta : 6; +#endif +}; +struct bmi160_acc_low_g_int_cfg { +#ifdef LITTLE_ENDIAN + + /*! low-g interrupt trigger delay */ + uint8_t low_dur; + + /*! low-g interrupt trigger threshold */ + uint8_t low_thres; + + /*! hysteresis of low-g interrupt */ + uint8_t low_hyst : 2; + + /*! 0 - single-axis mode ,1 - axis-summing mode */ + uint8_t low_mode : 1; + + /*! data source 0- filter & 1 pre-filter */ + uint8_t low_data_src : 1; + + /*! 1 - enable low-g, 0 - disable low-g */ + uint8_t low_en : 1; +#else + + /*! 1 - enable low-g, 0 - disable low-g */ + uint8_t low_en : 1; + + /*! data source 0- filter & 1 pre-filter */ + uint8_t low_data_src : 1; + + /*! 0 - single-axis mode ,1 - axis-summing mode */ + uint8_t low_mode : 1; + + /*! hysteresis of low-g interrupt */ + uint8_t low_hyst : 2; + + /*! low-g interrupt trigger threshold */ + uint8_t low_thres; + + /*! low-g interrupt trigger delay */ + uint8_t low_dur; +#endif +}; +struct bmi160_acc_high_g_int_cfg { +#ifdef LITTLE_ENDIAN + + /*! High-g interrupt x, 1 - enable, 0 - disable */ + uint8_t high_g_x : 1; + + /*! High-g interrupt y, 1 - enable, 0 - disable */ + uint8_t high_g_y : 1; + + /*! High-g interrupt z, 1 - enable, 0 - disable */ + uint8_t high_g_z : 1; + + /*! High-g hysteresis */ + uint8_t high_hy : 2; + + /*! data source 0- filter & 1 pre-filter */ + uint8_t high_data_src : 1; + + /*! High-g threshold */ + uint8_t high_thres; + + /*! High-g duration */ + uint8_t high_dur; +#else + + /*! High-g duration */ + uint8_t high_dur; + + /*! High-g threshold */ + uint8_t high_thres; + + /*! data source 0- filter & 1 pre-filter */ + uint8_t high_data_src : 1; + + /*! High-g hysteresis */ + uint8_t high_hy : 2; + + /*! High-g interrupt z, 1 - enable, 0 - disable */ + uint8_t high_g_z : 1; + + /*! High-g interrupt y, 1 - enable, 0 - disable */ + uint8_t high_g_y : 1; + + /*! High-g interrupt x, 1 - enable, 0 - disable */ + uint8_t high_g_x : 1; +#endif +}; +struct bmi160_int_pin_settg { +#ifdef LITTLE_ENDIAN + + /*! To enable either INT1 or INT2 pin as output. + * 0- output disabled ,1- output enabled */ + uint16_t output_en : 1; + + /*! 0 - push-pull 1- open drain,only valid if output_en is set 1 */ + uint16_t output_mode : 1; + + /*! 0 - active low , 1 - active high level. + * if output_en is 1,this applies to interrupts,else PMU_trigger */ + uint16_t output_type : 1; + + /*! 0 - level trigger , 1 - edge trigger */ + uint16_t edge_ctrl : 1; + + /*! To enable either INT1 or INT2 pin as input. + * 0 - input disabled ,1 - input enabled */ + uint16_t input_en : 1; + + /*! latch duration*/ + uint16_t latch_dur : 4; +#else + + /*! latch duration*/ + uint16_t latch_dur : 4; + + /*! Latched,non-latched or temporary interrupt modes */ + uint16_t input_en : 1; + + /*! 1 - edge trigger, 0 - level trigger */ + uint16_t edge_ctrl : 1; + + /*! 0 - active low , 1 - active high level. + * if output_en is 1,this applies to interrupts,else PMU_trigger */ + uint16_t output_type : 1; + + /*! 0 - push-pull , 1 - open drain,only valid if output_en is set 1 */ + uint16_t output_mode : 1; + + /*! To enable either INT1 or INT2 pin as output. + * 0 - output disabled , 1 - output enabled */ + uint16_t output_en : 1; +#endif +}; +union bmi160_int_type_cfg { + /*! Tap interrupt structure */ + struct bmi160_acc_tap_int_cfg acc_tap_int; + + /*! Slope interrupt structure */ + struct bmi160_acc_any_mot_int_cfg acc_any_motion_int; + + /*! Significant motion interrupt structure */ + struct bmi160_acc_sig_mot_int_cfg acc_sig_motion_int; + + /*! Step detector interrupt structure */ + struct bmi160_acc_step_detect_int_cfg acc_step_detect_int; + + /*! No motion interrupt structure */ + struct bmi160_acc_no_motion_int_cfg acc_no_motion_int; + + /*! Orientation interrupt structure */ + struct bmi160_acc_orient_int_cfg acc_orient_int; + + /*! Flat interrupt structure */ + struct bmi160_acc_flat_detect_int_cfg acc_flat_int; + + /*! Low-g interrupt structure */ + struct bmi160_acc_low_g_int_cfg acc_low_g_int; + + /*! High-g interrupt structure */ + struct bmi160_acc_high_g_int_cfg acc_high_g_int; +}; +struct bmi160_int_settg { + /*! Interrupt channel */ + enum bmi160_int_channel int_channel; + + /*! Select Interrupt */ + enum bmi160_int_types int_type; + + /*! Structure configuring Interrupt pins */ + struct bmi160_int_pin_settg int_pin_settg; + + /*! Union configures required interrupt */ + union bmi160_int_type_cfg int_type_cfg; + + /*! FIFO FULL INT 1-enable, 0-disable */ + uint8_t fifo_full_int_en : 1; + + /*! FIFO WTM INT 1-enable, 0-disable */ + uint8_t fifo_wtm_int_en : 1; +}; + +/*! + * @brief This structure holds the information for usage of + * FIFO by the user. + */ +struct bmi160_fifo_frame { + /*! Data buffer of user defined length is to be mapped here */ + uint8_t* data; + + /*! While calling the API "bmi160_get_fifo_data" , length stores + * number of bytes in FIFO to be read (specified by user as input) + * and after execution of the API ,number of FIFO data bytes + * available is provided as an output to user + */ + uint16_t length; + + /*! FIFO time enable */ + uint8_t fifo_time_enable; + + /*! Enabling of the FIFO header to stream in header mode */ + uint8_t fifo_header_enable; + + /*! Streaming of the Accelerometer, Gyroscope + * sensor data or both in FIFO */ + uint8_t fifo_data_enable; + + /*! Will be equal to length when no more frames are there to parse */ + uint16_t accel_byte_start_idx; + + /*! Will be equal to length when no more frames are there to parse */ + uint16_t gyro_byte_start_idx; + + /*! Will be equal to length when no more frames are there to parse */ + uint16_t aux_byte_start_idx; + + /*! Value of FIFO sensor time time */ + uint32_t sensor_time; + + /*! Value of Skipped frame counts */ + uint8_t skipped_frame_count; +}; +struct bmi160_dev { + /*! Chip Id */ + uint8_t chip_id; + + /*! Device Id */ + uint8_t id; + + /*! 0 - I2C , 1 - SPI Interface */ + uint8_t intf; + + /*! Hold active interrupts status for any and sig motion + * 0 - Any-motion enable, 1 - Sig-motion enable, + * -1 neither any-motion nor sig-motion selected */ + enum bmi160_any_sig_motion_active_interrupt_state any_sig_sel; + + /*! Structure to configure Accel sensor */ + struct bmi160_cfg accel_cfg; + + /*! Structure to hold previous/old accel config parameters. + * This is used at driver level to prevent overwriting of same + * data, hence user does not change it in the code */ + struct bmi160_cfg prev_accel_cfg; + + /*! Structure to configure Gyro sensor */ + struct bmi160_cfg gyro_cfg; + + /*! Structure to hold previous/old gyro config parameters. + * This is used at driver level to prevent overwriting of same + * data, hence user does not change it in the code */ + struct bmi160_cfg prev_gyro_cfg; + + /*! Structure to configure the auxiliary sensor */ + struct bmi160_aux_cfg aux_cfg; + + /*! Structure to hold previous/old aux config parameters. + * This is used at driver level to prevent overwriting of same + * data, hence user does not change it in the code */ + struct bmi160_aux_cfg prev_aux_cfg; + + /*! FIFO related configurations */ + struct bmi160_fifo_frame* fifo; + + /*! Read function pointer */ + bmi160_read_fptr_t read; + + /*! Write function pointer */ + bmi160_write_fptr_t write; + + /*! Delay function pointer */ + bmi160_delay_fptr_t delay_ms; + + /*! User set read/write length */ + uint16_t read_write_len; +}; + +#endif /* BMI160_DEFS_H_ */ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/imu.c b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/imu.c new file mode 100644 index 000000000..5e89c9504 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/imu.c @@ -0,0 +1,29 @@ +#include "imu.h" +#include + +bool bmi160_begin(); +int bmi160_read(double* vec); + +bool lsm6ds3trc_begin(); +void lsm6ds3trc_end(); +int lsm6ds3trc_read(double* vec); + +bool imu_begin() { + furi_hal_i2c_acquire(&furi_hal_i2c_handle_external); + bool ret = bmi160_begin(); // lsm6ds3trc_begin(); + furi_hal_i2c_release(&furi_hal_i2c_handle_external); + return ret; +} + +void imu_end() { + // furi_hal_i2c_acquire(&furi_hal_i2c_handle_external); + // lsm6ds3trc_end(); + // furi_hal_i2c_release(&furi_hal_i2c_handle_external); +} + +int imu_read(double* vec) { + furi_hal_i2c_acquire(&furi_hal_i2c_handle_external); + int ret = bmi160_read(vec); // lsm6ds3trc_read(vec); + furi_hal_i2c_release(&furi_hal_i2c_handle_external); + return ret; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/imu.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/imu.h new file mode 100644 index 000000000..f4c5e4b1d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/imu.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ACC_DATA_READY (1 << 0) +#define GYR_DATA_READY (1 << 1) + +bool imu_begin(); +void imu_end(); +int imu_read(double* vec); + +#ifdef __cplusplus +} +#endif diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/imu_bmi160.c b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/imu_bmi160.c new file mode 100644 index 000000000..af771302f --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/imu_bmi160.c @@ -0,0 +1,88 @@ +#include "bmi160.h" + +#include + +#include "imu.h" + +#define TAG "BMI160" + +#define BMI160_DEV_ADDR (0x69 << 1) + +static const double DEG_TO_RAD = 0.017453292519943295769236907684886; +static const double G = 9.81; + +struct bmi160_dev bmi160dev; +struct bmi160_sensor_data bmi160_accel; +struct bmi160_sensor_data bmi160_gyro; + +int8_t bmi160_write_i2c(uint8_t dev_addr, uint8_t reg_addr, uint8_t* data, uint16_t len) { + if(furi_hal_i2c_write_mem(&furi_hal_i2c_handle_external, dev_addr, reg_addr, data, len, 50)) + return BMI160_OK; + return BMI160_E_COM_FAIL; +} + +int8_t bmi160_read_i2c(uint8_t dev_addr, uint8_t reg_addr, uint8_t* read_data, uint16_t len) { + if(furi_hal_i2c_read_mem(&furi_hal_i2c_handle_external, dev_addr, reg_addr, read_data, len, 50)) + return BMI160_OK; + return BMI160_E_COM_FAIL; +} + +bool bmi160_begin() { + FURI_LOG_I(TAG, "Init BMI160"); + + if(!furi_hal_i2c_is_device_ready(&furi_hal_i2c_handle_external, BMI160_DEV_ADDR, 50)) { + FURI_LOG_E(TAG, "Device not ready!"); + return false; + } + + FURI_LOG_I(TAG, "Device ready!"); + + bmi160dev.id = BMI160_DEV_ADDR; + bmi160dev.intf = BMI160_I2C_INTF; + bmi160dev.read = bmi160_read_i2c; + bmi160dev.write = bmi160_write_i2c; + bmi160dev.delay_ms = furi_delay_ms; + + if(bmi160_init(&bmi160dev) != BMI160_OK) { + FURI_LOG_E(TAG, "Initialization failure!"); + FURI_LOG_E(TAG, "Chip ID 0x%X", bmi160dev.chip_id); + return false; + } + + bmi160dev.accel_cfg.odr = BMI160_ACCEL_ODR_400HZ; + bmi160dev.accel_cfg.range = BMI160_ACCEL_RANGE_4G; + bmi160dev.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4; + bmi160dev.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE; + bmi160dev.gyro_cfg.odr = BMI160_GYRO_ODR_400HZ; + bmi160dev.gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS; + bmi160dev.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE; + bmi160dev.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE; + + if(bmi160_set_sens_conf(&bmi160dev) != BMI160_OK) { + FURI_LOG_E(TAG, "Initialization failure!"); + FURI_LOG_E(TAG, "Chip ID 0x%X", bmi160dev.chip_id); + return false; + } + + FURI_LOG_I(TAG, "Initialization success!"); + FURI_LOG_I(TAG, "Chip ID 0x%X", bmi160dev.chip_id); + + return true; +} + +int bmi160_read(double* vec) { + if(bmi160_get_sensor_data( + (BMI160_ACCEL_SEL | BMI160_GYRO_SEL), &bmi160_accel, &bmi160_gyro, &bmi160dev) != + BMI160_OK) { + return 0; + } + + vec[0] = ((double)bmi160_accel.x * 4 / 32768) * G; + vec[1] = ((double)bmi160_accel.y * 4 / 32768) * G; + vec[2] = ((double)bmi160_accel.z * 4 / 32768) * G; + vec[3] = ((double)bmi160_gyro.x * 2000 / 32768) * DEG_TO_RAD; + vec[4] = ((double)bmi160_gyro.y * 2000 / 32768) * DEG_TO_RAD; + vec[5] = ((double)bmi160_gyro.z * 2000 / 32768) * DEG_TO_RAD; + + return ACC_DATA_READY | GYR_DATA_READY; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/imu_lsm6ds3trc.c b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/imu_lsm6ds3trc.c new file mode 100644 index 000000000..c013fc6e6 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/imu_lsm6ds3trc.c @@ -0,0 +1,94 @@ +#include "lsm6ds3tr_c_reg.h" + +#include + +#include "imu.h" + +#define TAG "LSM6DS3TR-C" + +#define LSM6DS3_ADDRESS (0x6A << 1) + +static const double DEG_TO_RAD = 0.017453292519943295769236907684886; + +stmdev_ctx_t lsm6ds3trc_ctx; + +int32_t lsm6ds3trc_write_i2c(void* handle, uint8_t reg_addr, const uint8_t* data, uint16_t len) { + if(furi_hal_i2c_write_mem(handle, LSM6DS3_ADDRESS, reg_addr, (uint8_t*)data, len, 50)) + return 0; + return -1; +} + +int32_t lsm6ds3trc_read_i2c(void* handle, uint8_t reg_addr, uint8_t* read_data, uint16_t len) { + if(furi_hal_i2c_read_mem(handle, LSM6DS3_ADDRESS, reg_addr, read_data, len, 50)) return 0; + return -1; +} + +bool lsm6ds3trc_begin() { + FURI_LOG_I(TAG, "Init LSM6DS3TR-C"); + + if(!furi_hal_i2c_is_device_ready(&furi_hal_i2c_handle_external, LSM6DS3_ADDRESS, 50)) { + FURI_LOG_E(TAG, "Not ready"); + return false; + } + + lsm6ds3trc_ctx.write_reg = lsm6ds3trc_write_i2c; + lsm6ds3trc_ctx.read_reg = lsm6ds3trc_read_i2c; + lsm6ds3trc_ctx.mdelay = furi_delay_ms; + lsm6ds3trc_ctx.handle = &furi_hal_i2c_handle_external; + + uint8_t whoami; + lsm6ds3tr_c_device_id_get(&lsm6ds3trc_ctx, &whoami); + if(whoami != LSM6DS3TR_C_ID) { + FURI_LOG_I(TAG, "Unknown model: %x", (int)whoami); + return false; + } + + lsm6ds3tr_c_reset_set(&lsm6ds3trc_ctx, PROPERTY_ENABLE); + uint8_t rst = PROPERTY_ENABLE; + while(rst) lsm6ds3tr_c_reset_get(&lsm6ds3trc_ctx, &rst); + + lsm6ds3tr_c_block_data_update_set(&lsm6ds3trc_ctx, PROPERTY_ENABLE); + lsm6ds3tr_c_fifo_mode_set(&lsm6ds3trc_ctx, LSM6DS3TR_C_BYPASS_MODE); + + lsm6ds3tr_c_xl_data_rate_set(&lsm6ds3trc_ctx, LSM6DS3TR_C_XL_ODR_104Hz); + lsm6ds3tr_c_xl_full_scale_set(&lsm6ds3trc_ctx, LSM6DS3TR_C_4g); + lsm6ds3tr_c_xl_lp1_bandwidth_set(&lsm6ds3trc_ctx, LSM6DS3TR_C_XL_LP1_ODR_DIV_4); + + lsm6ds3tr_c_gy_data_rate_set(&lsm6ds3trc_ctx, LSM6DS3TR_C_GY_ODR_104Hz); + lsm6ds3tr_c_gy_full_scale_set(&lsm6ds3trc_ctx, LSM6DS3TR_C_2000dps); + lsm6ds3tr_c_gy_power_mode_set(&lsm6ds3trc_ctx, LSM6DS3TR_C_GY_HIGH_PERFORMANCE); + lsm6ds3tr_c_gy_band_pass_set(&lsm6ds3trc_ctx, LSM6DS3TR_C_LP2_ONLY); + + FURI_LOG_I(TAG, "Init OK"); + return true; +} + +void lsm6ds3trc_end() { + lsm6ds3tr_c_xl_data_rate_set(&lsm6ds3trc_ctx, LSM6DS3TR_C_XL_ODR_OFF); + lsm6ds3tr_c_gy_data_rate_set(&lsm6ds3trc_ctx, LSM6DS3TR_C_GY_ODR_OFF); +} + +int lsm6ds3trc_read(double* vec) { + int ret = 0; + int16_t data[3]; + lsm6ds3tr_c_reg_t reg; + lsm6ds3tr_c_status_reg_get(&lsm6ds3trc_ctx, ®.status_reg); + + if(reg.status_reg.xlda) { + lsm6ds3tr_c_acceleration_raw_get(&lsm6ds3trc_ctx, data); + vec[2] = (double)lsm6ds3tr_c_from_fs2g_to_mg(data[0]) / 1000; + vec[0] = (double)lsm6ds3tr_c_from_fs2g_to_mg(data[1]) / 1000; + vec[1] = (double)lsm6ds3tr_c_from_fs2g_to_mg(data[2]) / 1000; + ret |= ACC_DATA_READY; + } + + if(reg.status_reg.gda) { + lsm6ds3tr_c_angular_rate_raw_get(&lsm6ds3trc_ctx, data); + vec[5] = (double)lsm6ds3tr_c_from_fs2000dps_to_mdps(data[0]) * DEG_TO_RAD / 1000; + vec[3] = (double)lsm6ds3tr_c_from_fs2000dps_to_mdps(data[1]) * DEG_TO_RAD / 1000; + vec[4] = (double)lsm6ds3tr_c_from_fs2000dps_to_mdps(data[2]) * DEG_TO_RAD / 1000; + ret |= GYR_DATA_READY; + } + + return ret; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/lsm6ds3tr_c_reg.c b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/lsm6ds3tr_c_reg.c new file mode 100644 index 000000000..9f1890d2c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/lsm6ds3tr_c_reg.c @@ -0,0 +1,7105 @@ +/** + ****************************************************************************** + * @file lsm6ds3tr_c_reg.c + * @author Sensors Software Solution Team + * @brief LSM6DS3TR_C driver file + ****************************************************************************** + * @attention + * + *

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

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +#include "lsm6ds3tr_c_reg.h" + +/** + * @defgroup LSM6DS3TR_C + * @brief This file provides a set of functions needed to drive the + * lsm6ds3tr_c enanced inertial module. + * @{ + * + */ + +/** + * @defgroup LSM6DS3TR_C_interfaces_functions + * @brief This section provide a set of functions used to read and + * write a generic register of the device. + * MANDATORY: return 0 -> no Error. + * @{ + * + */ + +/** + * @brief Read generic device register + * + * @param ctx read / write interface definitions(ptr) + * @param reg register to read + * @param data pointer to buffer that store the data read(ptr) + * @param len number of consecutive register to read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6ds3tr_c_read_reg(stmdev_ctx_t* ctx, uint8_t reg, uint8_t* data, uint16_t len) { + int32_t ret; + + ret = ctx->read_reg(ctx->handle, reg, data, len); + + return ret; +} + +/** + * @brief Write generic device register + * + * @param ctx read / write interface definitions(ptr) + * @param reg register to write + * @param data pointer to data to write in register reg(ptr) + * @param len number of consecutive register to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6ds3tr_c_write_reg(stmdev_ctx_t* ctx, uint8_t reg, uint8_t* data, uint16_t len) { + int32_t ret; + + ret = ctx->write_reg(ctx->handle, reg, data, len); + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_Sensitivity + * @brief These functions convert raw-data into engineering units. + * @{ + * + */ + +float_t lsm6ds3tr_c_from_fs2g_to_mg(int16_t lsb) { + return ((float_t)lsb * 0.061f); +} + +float_t lsm6ds3tr_c_from_fs4g_to_mg(int16_t lsb) { + return ((float_t)lsb * 0.122f); +} + +float_t lsm6ds3tr_c_from_fs8g_to_mg(int16_t lsb) { + return ((float_t)lsb * 0.244f); +} + +float_t lsm6ds3tr_c_from_fs16g_to_mg(int16_t lsb) { + return ((float_t)lsb * 0.488f); +} + +float_t lsm6ds3tr_c_from_fs125dps_to_mdps(int16_t lsb) { + return ((float_t)lsb * 4.375f); +} + +float_t lsm6ds3tr_c_from_fs250dps_to_mdps(int16_t lsb) { + return ((float_t)lsb * 8.750f); +} + +float_t lsm6ds3tr_c_from_fs500dps_to_mdps(int16_t lsb) { + return ((float_t)lsb * 17.50f); +} + +float_t lsm6ds3tr_c_from_fs1000dps_to_mdps(int16_t lsb) { + return ((float_t)lsb * 35.0f); +} + +float_t lsm6ds3tr_c_from_fs2000dps_to_mdps(int16_t lsb) { + return ((float_t)lsb * 70.0f); +} + +float_t lsm6ds3tr_c_from_lsb_to_celsius(int16_t lsb) { + return (((float_t)lsb / 256.0f) + 25.0f); +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_data_generation + * @brief This section groups all the functions concerning data + * generation + * @{ + * + */ + +/** + * @brief Accelerometer full-scale selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of fs_xl in reg CTRL1_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_full_scale_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_fs_xl_t val) { + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); + + if(ret == 0) { + ctrl1_xl.fs_xl = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); + } + + return ret; +} + +/** + * @brief Accelerometer full-scale selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of fs_xl in reg CTRL1_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_full_scale_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_fs_xl_t* val) { + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); + + switch(ctrl1_xl.fs_xl) { + case LSM6DS3TR_C_2g: + *val = LSM6DS3TR_C_2g; + break; + + case LSM6DS3TR_C_16g: + *val = LSM6DS3TR_C_16g; + break; + + case LSM6DS3TR_C_4g: + *val = LSM6DS3TR_C_4g; + break; + + case LSM6DS3TR_C_8g: + *val = LSM6DS3TR_C_8g; + break; + + default: + *val = LSM6DS3TR_C_XL_FS_ND; + break; + } + + return ret; +} + +/** + * @brief Accelerometer data rate selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of odr_xl in reg CTRL1_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_data_rate_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_xl_t val) { + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); + + if(ret == 0) { + ctrl1_xl.odr_xl = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); + } + + return ret; +} + +/** + * @brief Accelerometer data rate selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of odr_xl in reg CTRL1_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_data_rate_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_xl_t* val) { + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); + + switch(ctrl1_xl.odr_xl) { + case LSM6DS3TR_C_XL_ODR_OFF: + *val = LSM6DS3TR_C_XL_ODR_OFF; + break; + + case LSM6DS3TR_C_XL_ODR_12Hz5: + *val = LSM6DS3TR_C_XL_ODR_12Hz5; + break; + + case LSM6DS3TR_C_XL_ODR_26Hz: + *val = LSM6DS3TR_C_XL_ODR_26Hz; + break; + + case LSM6DS3TR_C_XL_ODR_52Hz: + *val = LSM6DS3TR_C_XL_ODR_52Hz; + break; + + case LSM6DS3TR_C_XL_ODR_104Hz: + *val = LSM6DS3TR_C_XL_ODR_104Hz; + break; + + case LSM6DS3TR_C_XL_ODR_208Hz: + *val = LSM6DS3TR_C_XL_ODR_208Hz; + break; + + case LSM6DS3TR_C_XL_ODR_416Hz: + *val = LSM6DS3TR_C_XL_ODR_416Hz; + break; + + case LSM6DS3TR_C_XL_ODR_833Hz: + *val = LSM6DS3TR_C_XL_ODR_833Hz; + break; + + case LSM6DS3TR_C_XL_ODR_1k66Hz: + *val = LSM6DS3TR_C_XL_ODR_1k66Hz; + break; + + case LSM6DS3TR_C_XL_ODR_3k33Hz: + *val = LSM6DS3TR_C_XL_ODR_3k33Hz; + break; + + case LSM6DS3TR_C_XL_ODR_6k66Hz: + *val = LSM6DS3TR_C_XL_ODR_6k66Hz; + break; + + case LSM6DS3TR_C_XL_ODR_1Hz6: + *val = LSM6DS3TR_C_XL_ODR_1Hz6; + break; + + default: + *val = LSM6DS3TR_C_XL_ODR_ND; + break; + } + + return ret; +} + +/** + * @brief Gyroscope chain full-scale selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of fs_g in reg CTRL2_G + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_full_scale_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_fs_g_t val) { + lsm6ds3tr_c_ctrl2_g_t ctrl2_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL2_G, (uint8_t*)&ctrl2_g, 1); + + if(ret == 0) { + ctrl2_g.fs_g = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL2_G, (uint8_t*)&ctrl2_g, 1); + } + + return ret; +} + +/** + * @brief Gyroscope chain full-scale selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of fs_g in reg CTRL2_G + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_full_scale_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_fs_g_t* val) { + lsm6ds3tr_c_ctrl2_g_t ctrl2_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL2_G, (uint8_t*)&ctrl2_g, 1); + + switch(ctrl2_g.fs_g) { + case LSM6DS3TR_C_250dps: + *val = LSM6DS3TR_C_250dps; + break; + + case LSM6DS3TR_C_125dps: + *val = LSM6DS3TR_C_125dps; + break; + + case LSM6DS3TR_C_500dps: + *val = LSM6DS3TR_C_500dps; + break; + + case LSM6DS3TR_C_1000dps: + *val = LSM6DS3TR_C_1000dps; + break; + + case LSM6DS3TR_C_2000dps: + *val = LSM6DS3TR_C_2000dps; + break; + + default: + *val = LSM6DS3TR_C_GY_FS_ND; + break; + } + + return ret; +} + +/** + * @brief Gyroscope data rate selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of odr_g in reg CTRL2_G + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_data_rate_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_g_t val) { + lsm6ds3tr_c_ctrl2_g_t ctrl2_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL2_G, (uint8_t*)&ctrl2_g, 1); + + if(ret == 0) { + ctrl2_g.odr_g = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL2_G, (uint8_t*)&ctrl2_g, 1); + } + + return ret; +} + +/** + * @brief Gyroscope data rate selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of odr_g in reg CTRL2_G + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_data_rate_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_g_t* val) { + lsm6ds3tr_c_ctrl2_g_t ctrl2_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL2_G, (uint8_t*)&ctrl2_g, 1); + + switch(ctrl2_g.odr_g) { + case LSM6DS3TR_C_GY_ODR_OFF: + *val = LSM6DS3TR_C_GY_ODR_OFF; + break; + + case LSM6DS3TR_C_GY_ODR_12Hz5: + *val = LSM6DS3TR_C_GY_ODR_12Hz5; + break; + + case LSM6DS3TR_C_GY_ODR_26Hz: + *val = LSM6DS3TR_C_GY_ODR_26Hz; + break; + + case LSM6DS3TR_C_GY_ODR_52Hz: + *val = LSM6DS3TR_C_GY_ODR_52Hz; + break; + + case LSM6DS3TR_C_GY_ODR_104Hz: + *val = LSM6DS3TR_C_GY_ODR_104Hz; + break; + + case LSM6DS3TR_C_GY_ODR_208Hz: + *val = LSM6DS3TR_C_GY_ODR_208Hz; + break; + + case LSM6DS3TR_C_GY_ODR_416Hz: + *val = LSM6DS3TR_C_GY_ODR_416Hz; + break; + + case LSM6DS3TR_C_GY_ODR_833Hz: + *val = LSM6DS3TR_C_GY_ODR_833Hz; + break; + + case LSM6DS3TR_C_GY_ODR_1k66Hz: + *val = LSM6DS3TR_C_GY_ODR_1k66Hz; + break; + + case LSM6DS3TR_C_GY_ODR_3k33Hz: + *val = LSM6DS3TR_C_GY_ODR_3k33Hz; + break; + + case LSM6DS3TR_C_GY_ODR_6k66Hz: + *val = LSM6DS3TR_C_GY_ODR_6k66Hz; + break; + + default: + *val = LSM6DS3TR_C_GY_ODR_ND; + break; + } + + return ret; +} + +/** + * @brief Block data update.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of bdu in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_block_data_update_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + + if(ret == 0) { + ctrl3_c.bdu = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief Block data update.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of bdu in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_block_data_update_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + *val = ctrl3_c.bdu; + + return ret; +} + +/** + * @brief Weight of XL user offset bits of registers + * X_OFS_USR(73h), Y_OFS_USR(74h), Z_OFS_USR(75h).[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of usr_off_w in reg CTRL6_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_offset_weight_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_usr_off_w_t val) { + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); + + if(ret == 0) { + ctrl6_c.usr_off_w = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); + } + + return ret; +} + +/** + * @brief Weight of XL user offset bits of registers + * X_OFS_USR(73h), Y_OFS_USR(74h), Z_OFS_USR(75h).[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of usr_off_w in reg CTRL6_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_offset_weight_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_usr_off_w_t* val) { + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); + + switch(ctrl6_c.usr_off_w) { + case LSM6DS3TR_C_LSb_1mg: + *val = LSM6DS3TR_C_LSb_1mg; + break; + + case LSM6DS3TR_C_LSb_16mg: + *val = LSM6DS3TR_C_LSb_16mg; + break; + + default: + *val = LSM6DS3TR_C_WEIGHT_ND; + break; + } + + return ret; +} + +/** + * @brief High-performance operating mode for accelerometer[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of xl_hm_mode in reg CTRL6_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_power_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_xl_hm_mode_t val) { + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); + + if(ret == 0) { + ctrl6_c.xl_hm_mode = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); + } + + return ret; +} + +/** + * @brief High-performance operating mode for accelerometer.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of xl_hm_mode in reg CTRL6_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_power_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_xl_hm_mode_t* val) { + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); + + switch(ctrl6_c.xl_hm_mode) { + case LSM6DS3TR_C_XL_HIGH_PERFORMANCE: + *val = LSM6DS3TR_C_XL_HIGH_PERFORMANCE; + break; + + case LSM6DS3TR_C_XL_NORMAL: + *val = LSM6DS3TR_C_XL_NORMAL; + break; + + default: + *val = LSM6DS3TR_C_XL_PW_MODE_ND; + break; + } + + return ret; +} + +/** + * @brief Source register rounding function on WAKE_UP_SRC (1Bh), + * TAP_SRC (1Ch), D6D_SRC (1Dh), STATUS_REG (1Eh) and + * FUNC_SRC1 (53h) registers in the primary interface.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of rounding_status in reg CTRL7_G + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_rounding_on_status_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_rounding_status_t val) { + lsm6ds3tr_c_ctrl7_g_t ctrl7_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); + + if(ret == 0) { + ctrl7_g.rounding_status = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); + } + + return ret; +} + +/** + * @brief Source register rounding function on WAKE_UP_SRC (1Bh), + * TAP_SRC (1Ch), D6D_SRC (1Dh), STATUS_REG (1Eh) and + * FUNC_SRC1 (53h) registers in the primary interface.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of rounding_status in reg CTRL7_G + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_rounding_on_status_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_rounding_status_t* val) { + lsm6ds3tr_c_ctrl7_g_t ctrl7_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); + + switch(ctrl7_g.rounding_status) { + case LSM6DS3TR_C_STAT_RND_DISABLE: + *val = LSM6DS3TR_C_STAT_RND_DISABLE; + break; + + case LSM6DS3TR_C_STAT_RND_ENABLE: + *val = LSM6DS3TR_C_STAT_RND_ENABLE; + break; + + default: + *val = LSM6DS3TR_C_STAT_RND_ND; + break; + } + + return ret; +} + +/** + * @brief High-performance operating mode disable for gyroscope.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of g_hm_mode in reg CTRL7_G + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_power_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_g_hm_mode_t val) { + lsm6ds3tr_c_ctrl7_g_t ctrl7_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); + + if(ret == 0) { + ctrl7_g.g_hm_mode = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); + } + + return ret; +} + +/** + * @brief High-performance operating mode disable for gyroscope.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of g_hm_mode in reg CTRL7_G + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_power_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_g_hm_mode_t* val) { + lsm6ds3tr_c_ctrl7_g_t ctrl7_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); + + switch(ctrl7_g.g_hm_mode) { + case LSM6DS3TR_C_GY_HIGH_PERFORMANCE: + *val = LSM6DS3TR_C_GY_HIGH_PERFORMANCE; + break; + + case LSM6DS3TR_C_GY_NORMAL: + *val = LSM6DS3TR_C_GY_NORMAL; + break; + + default: + *val = LSM6DS3TR_C_GY_PW_MODE_ND; + break; + } + + return ret; +} + +/** + * @brief Read all the interrupt/status flag of the device.[get] + * + * @param ctx Read / write interface definitions + * @param val WAKE_UP_SRC, TAP_SRC, D6D_SRC, STATUS_REG, + * FUNC_SRC1, FUNC_SRC2, WRIST_TILT_IA, A_WRIST_TILT_Mask + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_all_sources_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_all_sources_t* val) { + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_SRC, (uint8_t*)&(val->wake_up_src), 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_SRC, (uint8_t*)&(val->tap_src), 1); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_D6D_SRC, (uint8_t*)&(val->d6d_src), 1); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STATUS_REG, (uint8_t*)&(val->status_reg), 1); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FUNC_SRC1, (uint8_t*)&(val->func_src1), 1); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FUNC_SRC2, (uint8_t*)&(val->func_src2), 1); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_WRIST_TILT_IA, (uint8_t*)&(val->wrist_tilt_ia), 1); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_A_WRIST_TILT_MASK, (uint8_t*)&(val->a_wrist_tilt_mask), 1); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + + return ret; +} +/** + * @brief The STATUS_REG register is read by the primary interface[get] + * + * @param ctx Read / write interface definitions + * @param val Registers STATUS_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_status_reg_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_status_reg_t* val) { + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STATUS_REG, (uint8_t*)val, 1); + + return ret; +} + +/** + * @brief Accelerometer new data available.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of xlda in reg STATUS_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_flag_data_ready_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_status_reg_t status_reg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STATUS_REG, (uint8_t*)&status_reg, 1); + *val = status_reg.xlda; + + return ret; +} + +/** + * @brief Gyroscope new data available.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of gda in reg STATUS_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_flag_data_ready_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_status_reg_t status_reg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STATUS_REG, (uint8_t*)&status_reg, 1); + *val = status_reg.gda; + + return ret; +} + +/** + * @brief Temperature new data available.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tda in reg STATUS_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_temp_flag_data_ready_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_status_reg_t status_reg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STATUS_REG, (uint8_t*)&status_reg, 1); + *val = status_reg.tda; + + return ret; +} + +/** + * @brief Accelerometer axis user offset correction expressed in two’s + * complement, weight depends on USR_OFF_W in CTRL6_C. + * The value must be in the range [-127 127].[set] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that contains data to write + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_usr_offset_set(stmdev_ctx_t* ctx, uint8_t* buff) { + int32_t ret; + + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_X_OFS_USR, buff, 3); + + return ret; +} + +/** + * @brief Accelerometer axis user offset correction xpressed in two’s + * complement, weight depends on USR_OFF_W in CTRL6_C. + * The value must be in the range [-127 127].[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_usr_offset_get(stmdev_ctx_t* ctx, uint8_t* buff) { + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_X_OFS_USR, buff, 3); + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_Timestamp + * @brief This section groups all the functions that manage the + * timestamp generation. + * @{ + * + */ + +/** + * @brief Enable timestamp count. The count is saved in TIMESTAMP0_REG (40h), + * TIMESTAMP1_REG (41h) and TIMESTAMP2_REG (42h).[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of timer_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_timestamp_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + + if(ret == 0) { + ctrl10_c.timer_en = val; + + if(val != 0x00U) { + ctrl10_c.func_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + } + } + + return ret; +} + +/** + * @brief Enable timestamp count. The count is saved in TIMESTAMP0_REG (40h), + * TIMESTAMP1_REG (41h) and TIMESTAMP2_REG (42h).[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of timer_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_timestamp_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + *val = ctrl10_c.timer_en; + + return ret; +} + +/** + * @brief Timestamp register resolution setting. + * Configuration of this bit affects + * TIMESTAMP0_REG(40h), TIMESTAMP1_REG(41h), + * TIMESTAMP2_REG(42h), STEP_TIMESTAMP_L(49h), + * STEP_TIMESTAMP_H(4Ah) and + * STEP_COUNT_DELTA(15h) registers.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of timer_hr in reg WAKE_UP_DUR + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_timestamp_res_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_timer_hr_t val) { + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); + + if(ret == 0) { + wake_up_dur.timer_hr = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); + } + + return ret; +} + +/** + * @brief Timestamp register resolution setting. + * Configuration of this bit affects + * TIMESTAMP0_REG(40h), TIMESTAMP1_REG(41h), + * TIMESTAMP2_REG(42h), STEP_TIMESTAMP_L(49h), + * STEP_TIMESTAMP_H(4Ah) and + * STEP_COUNT_DELTA(15h) registers.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of timer_hr in reg WAKE_UP_DUR + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_timestamp_res_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_timer_hr_t* val) { + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); + + switch(wake_up_dur.timer_hr) { + case LSM6DS3TR_C_LSB_6ms4: + *val = LSM6DS3TR_C_LSB_6ms4; + break; + + case LSM6DS3TR_C_LSB_25us: + *val = LSM6DS3TR_C_LSB_25us; + break; + + default: + *val = LSM6DS3TR_C_TS_RES_ND; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_Dataoutput + * @brief This section groups all the data output functions. + * @{ + * + */ + +/** + * @brief Circular burst-mode (rounding) read from output registers + * through the primary interface.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of rounding in reg CTRL5_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_rounding_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_rounding_t val) { + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); + + if(ret == 0) { + ctrl5_c.rounding = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); + } + + return ret; +} + +/** + * @brief Circular burst-mode (rounding) read from output registers + * through the primary interface.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of rounding in reg CTRL5_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_rounding_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_rounding_t* val) { + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); + + switch(ctrl5_c.rounding) { + case LSM6DS3TR_C_ROUND_DISABLE: + *val = LSM6DS3TR_C_ROUND_DISABLE; + break; + + case LSM6DS3TR_C_ROUND_XL: + *val = LSM6DS3TR_C_ROUND_XL; + break; + + case LSM6DS3TR_C_ROUND_GY: + *val = LSM6DS3TR_C_ROUND_GY; + break; + + case LSM6DS3TR_C_ROUND_GY_XL: + *val = LSM6DS3TR_C_ROUND_GY_XL; + break; + + case LSM6DS3TR_C_ROUND_SH1_TO_SH6: + *val = LSM6DS3TR_C_ROUND_SH1_TO_SH6; + break; + + case LSM6DS3TR_C_ROUND_XL_SH1_TO_SH6: + *val = LSM6DS3TR_C_ROUND_XL_SH1_TO_SH6; + break; + + case LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH12: + *val = LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH12; + break; + + case LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH6: + *val = LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH6; + break; + + default: + *val = LSM6DS3TR_C_ROUND_OUT_ND; + break; + } + + return ret; +} + +/** + * @brief Temperature data output register (r). L and H registers together + * express a 16-bit word in two’s complement.[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_temperature_raw_get(stmdev_ctx_t* ctx, int16_t* val) { + uint8_t buff[2]; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_OUT_TEMP_L, buff, 2); + *val = (int16_t)buff[1]; + *val = (*val * 256) + (int16_t)buff[0]; + + return ret; +} + +/** + * @brief Angular rate sensor. The value is expressed as a 16-bit word in + * two’s complement.[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_angular_rate_raw_get(stmdev_ctx_t* ctx, int16_t* val) { + uint8_t buff[6]; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_OUTX_L_G, buff, 6); + val[0] = (int16_t)buff[1]; + val[0] = (val[0] * 256) + (int16_t)buff[0]; + val[1] = (int16_t)buff[3]; + val[1] = (val[1] * 256) + (int16_t)buff[2]; + val[2] = (int16_t)buff[5]; + val[2] = (val[2] * 256) + (int16_t)buff[4]; + + return ret; +} + +/** + * @brief Linear acceleration output register. The value is expressed + * as a 16-bit word in two’s complement.[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_acceleration_raw_get(stmdev_ctx_t* ctx, int16_t* val) { + uint8_t buff[6]; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_OUTX_L_XL, buff, 6); + val[0] = (int16_t)buff[1]; + val[0] = (val[0] * 256) + (int16_t)buff[0]; + val[1] = (int16_t)buff[3]; + val[1] = (val[1] * 256) + (int16_t)buff[2]; + val[2] = (int16_t)buff[5]; + val[2] = (val[2] * 256) + (int16_t)buff[4]; + + return ret; +} + +/** + * @brief External magnetometer raw data.[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_calibrated_raw_get(stmdev_ctx_t* ctx, int16_t* val) { + uint8_t buff[6]; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_OUT_MAG_RAW_X_L, buff, 6); + val[0] = (int16_t)buff[1]; + val[0] = (val[0] * 256) + (int16_t)buff[0]; + val[1] = (int16_t)buff[3]; + val[1] = (val[1] * 256) + (int16_t)buff[2]; + val[2] = (int16_t)buff[5]; + val[2] = (val[2] * 256) + (int16_t)buff[4]; + + return ret; +} + +/** + * @brief Read data in FIFO.[get] + * + * @param ctx Read / write interface definitions + * @param buffer Data buffer to store FIFO data. + * @param len Number of data to read from FIFO. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_raw_data_get(stmdev_ctx_t* ctx, uint8_t* buffer, uint8_t len) { + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_DATA_OUT_L, buffer, len); + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_common + * @brief This section groups common useful functions. + * @{ + * + */ + +/** + * @brief Enable access to the embedded functions/sensor hub + * configuration registers[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of func_cfg_en in reg FUNC_CFG_ACCESS + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mem_bank_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_func_cfg_en_t val) { + lsm6ds3tr_c_func_cfg_access_t func_cfg_access; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FUNC_CFG_ACCESS, (uint8_t*)&func_cfg_access, 1); + + if(ret == 0) { + func_cfg_access.func_cfg_en = (uint8_t)val; + ret = + lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FUNC_CFG_ACCESS, (uint8_t*)&func_cfg_access, 1); + } + + return ret; +} + +/** + * @brief Enable access to the embedded functions/sensor hub configuration + * registers[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of func_cfg_en in reg FUNC_CFG_ACCESS + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mem_bank_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_func_cfg_en_t* val) { + lsm6ds3tr_c_func_cfg_access_t func_cfg_access; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FUNC_CFG_ACCESS, (uint8_t*)&func_cfg_access, 1); + + switch(func_cfg_access.func_cfg_en) { + case LSM6DS3TR_C_USER_BANK: + *val = LSM6DS3TR_C_USER_BANK; + break; + + case LSM6DS3TR_C_BANK_B: + *val = LSM6DS3TR_C_BANK_B; + break; + + default: + *val = LSM6DS3TR_C_BANK_ND; + break; + } + + return ret; +} + +/** + * @brief Data-ready pulsed / letched mode[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of drdy_pulsed in reg DRDY_PULSE_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_data_ready_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_drdy_pulsed_g_t val) { + lsm6ds3tr_c_drdy_pulse_cfg_g_t drdy_pulse_cfg_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, (uint8_t*)&drdy_pulse_cfg_g, 1); + + if(ret == 0) { + drdy_pulse_cfg_g.drdy_pulsed = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg( + ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, (uint8_t*)&drdy_pulse_cfg_g, 1); + } + + return ret; +} + +/** + * @brief Data-ready pulsed / letched mode[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of drdy_pulsed in reg DRDY_PULSE_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_data_ready_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_drdy_pulsed_g_t* val) { + lsm6ds3tr_c_drdy_pulse_cfg_g_t drdy_pulse_cfg_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, (uint8_t*)&drdy_pulse_cfg_g, 1); + + switch(drdy_pulse_cfg_g.drdy_pulsed) { + case LSM6DS3TR_C_DRDY_LATCHED: + *val = LSM6DS3TR_C_DRDY_LATCHED; + break; + + case LSM6DS3TR_C_DRDY_PULSED: + *val = LSM6DS3TR_C_DRDY_PULSED; + break; + + default: + *val = LSM6DS3TR_C_DRDY_ND; + break; + } + + return ret; +} + +/** + * @brief DeviceWhoamI.[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_device_id_get(stmdev_ctx_t* ctx, uint8_t* buff) { + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WHO_AM_I, buff, 1); + + return ret; +} + +/** + * @brief Software reset. Restore the default values in user registers[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sw_reset in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_reset_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + + if(ret == 0) { + ctrl3_c.sw_reset = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief Software reset. Restore the default values in user registers[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sw_reset in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_reset_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + *val = ctrl3_c.sw_reset; + + return ret; +} + +/** + * @brief Big/Little Endian Data selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of ble in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_data_format_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_ble_t val) { + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + + if(ret == 0) { + ctrl3_c.ble = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief Big/Little Endian Data selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of ble in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_data_format_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_ble_t* val) { + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + + switch(ctrl3_c.ble) { + case LSM6DS3TR_C_LSB_AT_LOW_ADD: + *val = LSM6DS3TR_C_LSB_AT_LOW_ADD; + break; + + case LSM6DS3TR_C_MSB_AT_LOW_ADD: + *val = LSM6DS3TR_C_MSB_AT_LOW_ADD; + break; + + default: + *val = LSM6DS3TR_C_DATA_FMT_ND; + break; + } + + return ret; +} + +/** + * @brief Register address automatically incremented during a multiple byte + * access with a serial interface.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of if_inc in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_auto_increment_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + + if(ret == 0) { + ctrl3_c.if_inc = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief Register address automatically incremented during a multiple byte + * access with a serial interface.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of if_inc in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_auto_increment_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + *val = ctrl3_c.if_inc; + + return ret; +} + +/** + * @brief Reboot memory content. Reload the calibration parameters.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of boot in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_boot_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + + if(ret == 0) { + ctrl3_c.boot = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief Reboot memory content. Reload the calibration parameters.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of boot in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_boot_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + *val = ctrl3_c.boot; + + return ret; +} + +/** + * @brief Linear acceleration sensor self-test enable.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of st_xl in reg CTRL5_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_self_test_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_st_xl_t val) { + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); + + if(ret == 0) { + ctrl5_c.st_xl = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); + } + + return ret; +} + +/** + * @brief Linear acceleration sensor self-test enable.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of st_xl in reg CTRL5_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_self_test_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_st_xl_t* val) { + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); + + switch(ctrl5_c.st_xl) { + case LSM6DS3TR_C_XL_ST_DISABLE: + *val = LSM6DS3TR_C_XL_ST_DISABLE; + break; + + case LSM6DS3TR_C_XL_ST_POSITIVE: + *val = LSM6DS3TR_C_XL_ST_POSITIVE; + break; + + case LSM6DS3TR_C_XL_ST_NEGATIVE: + *val = LSM6DS3TR_C_XL_ST_NEGATIVE; + break; + + default: + *val = LSM6DS3TR_C_XL_ST_ND; + break; + } + + return ret; +} + +/** + * @brief Angular rate sensor self-test enable.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of st_g in reg CTRL5_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_self_test_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_st_g_t val) { + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); + + if(ret == 0) { + ctrl5_c.st_g = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); + } + + return ret; +} + +/** + * @brief Angular rate sensor self-test enable.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of st_g in reg CTRL5_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_self_test_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_st_g_t* val) { + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); + + switch(ctrl5_c.st_g) { + case LSM6DS3TR_C_GY_ST_DISABLE: + *val = LSM6DS3TR_C_GY_ST_DISABLE; + break; + + case LSM6DS3TR_C_GY_ST_POSITIVE: + *val = LSM6DS3TR_C_GY_ST_POSITIVE; + break; + + case LSM6DS3TR_C_GY_ST_NEGATIVE: + *val = LSM6DS3TR_C_GY_ST_NEGATIVE; + break; + + default: + *val = LSM6DS3TR_C_GY_ST_ND; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_filters + * @brief This section group all the functions concerning the filters + * configuration that impact both accelerometer and gyro. + * @{ + * + */ + +/** + * @brief Mask DRDY on pin (both XL & Gyro) until filter settling ends + * (XL and Gyro independently masked).[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of drdy_mask in reg CTRL4_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_filter_settling_mask_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + + if(ret == 0) { + ctrl4_c.drdy_mask = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + } + + return ret; +} + +/** + * @brief Mask DRDY on pin (both XL & Gyro) until filter settling ends + * (XL and Gyro independently masked).[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of drdy_mask in reg CTRL4_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_filter_settling_mask_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + *val = ctrl4_c.drdy_mask; + + return ret; +} + +/** + * @brief HPF or SLOPE filter selection on wake-up and Activity/Inactivity + * functions.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of slope_fds in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_hp_path_internal_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slope_fds_t val) { + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + + if(ret == 0) { + tap_cfg.slope_fds = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + } + + return ret; +} + +/** + * @brief HPF or SLOPE filter selection on wake-up and Activity/Inactivity + * functions.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of slope_fds in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_hp_path_internal_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slope_fds_t* val) { + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + + switch(tap_cfg.slope_fds) { + case LSM6DS3TR_C_USE_SLOPE: + *val = LSM6DS3TR_C_USE_SLOPE; + break; + + case LSM6DS3TR_C_USE_HPF: + *val = LSM6DS3TR_C_USE_HPF; + break; + + default: + *val = LSM6DS3TR_C_HP_PATH_ND; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_accelerometer_filters + * @brief This section group all the functions concerning the filters + * configuration that impact accelerometer in every mode. + * @{ + * + */ + +/** + * @brief Accelerometer analog chain bandwidth selection (only for + * accelerometer ODR ≥ 1.67 kHz).[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of bw0_xl in reg CTRL1_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_filter_analog_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_bw0_xl_t val) { + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); + + if(ret == 0) { + ctrl1_xl.bw0_xl = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); + } + + return ret; +} + +/** + * @brief Accelerometer analog chain bandwidth selection (only for + * accelerometer ODR ≥ 1.67 kHz).[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of bw0_xl in reg CTRL1_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_filter_analog_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_bw0_xl_t* val) { + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); + + switch(ctrl1_xl.bw0_xl) { + case LSM6DS3TR_C_XL_ANA_BW_1k5Hz: + *val = LSM6DS3TR_C_XL_ANA_BW_1k5Hz; + break; + + case LSM6DS3TR_C_XL_ANA_BW_400Hz: + *val = LSM6DS3TR_C_XL_ANA_BW_400Hz; + break; + + default: + *val = LSM6DS3TR_C_XL_ANA_BW_ND; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_accelerometer_filters + * @brief This section group all the functions concerning the filters + * configuration that impact accelerometer. + * @{ + * + */ + +/** + * @brief Accelerometer digital LPF (LPF1) bandwidth selection LPF2 is + * not used.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of lpf1_bw_sel in reg CTRL1_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_lp1_bandwidth_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_lpf1_bw_sel_t val) { + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); + + if(ret == 0) { + ctrl1_xl.lpf1_bw_sel = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); + + if(ret == 0) { + ctrl8_xl.lpf2_xl_en = 0; + ctrl8_xl.hp_slope_xl_en = 0; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); + } + } + } + + return ret; +} + +/** + * @brief Accelerometer digital LPF (LPF1) bandwidth selection LPF2 + * is not used.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of lpf1_bw_sel in reg CTRL1_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_lp1_bandwidth_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_lpf1_bw_sel_t* val) { + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); + + if(ret == 0) { + if((ctrl8_xl.lpf2_xl_en != 0x00U) || (ctrl8_xl.hp_slope_xl_en != 0x00U)) { + *val = LSM6DS3TR_C_XL_LP1_NA; + } + + else { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); + + switch(ctrl1_xl.lpf1_bw_sel) { + case LSM6DS3TR_C_XL_LP1_ODR_DIV_2: + *val = LSM6DS3TR_C_XL_LP1_ODR_DIV_2; + break; + + case LSM6DS3TR_C_XL_LP1_ODR_DIV_4: + *val = LSM6DS3TR_C_XL_LP1_ODR_DIV_4; + break; + + default: + *val = LSM6DS3TR_C_XL_LP1_NA; + break; + } + } + } + + return ret; +} + +/** + * @brief LPF2 on outputs[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of input_composite in reg CTRL8_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_lp2_bandwidth_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_input_composite_t val) { + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); + + if(ret == 0) { + ctrl8_xl.input_composite = ((uint8_t)val & 0x10U) >> 4; + ctrl8_xl.hpcf_xl = (uint8_t)val & 0x03U; + ctrl8_xl.lpf2_xl_en = 1; + ctrl8_xl.hp_slope_xl_en = 0; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); + } + + return ret; +} + +/** + * @brief LPF2 on outputs[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of input_composite in reg CTRL8_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_lp2_bandwidth_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_input_composite_t* val) { + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); + + if(ret == 0) { + if((ctrl8_xl.lpf2_xl_en == 0x00U) || (ctrl8_xl.hp_slope_xl_en != 0x00U)) { + *val = LSM6DS3TR_C_XL_LP_NA; + } + + else { + switch((ctrl8_xl.input_composite << 4) + ctrl8_xl.hpcf_xl) { + case LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_50: + *val = LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_50; + break; + + case LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_100: + *val = LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_100; + break; + + case LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_9: + *val = LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_9; + break; + + case LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_400: + *val = LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_400; + break; + + case LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_50: + *val = LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_50; + break; + + case LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_100: + *val = LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_100; + break; + + case LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_9: + *val = LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_9; + break; + + case LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_400: + *val = LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_400; + break; + + default: + *val = LSM6DS3TR_C_XL_LP_NA; + break; + } + } + } + + return ret; +} + +/** + * @brief Enable HP filter reference mode.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of hp_ref_mode in reg CTRL8_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_reference_mode_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); + + if(ret == 0) { + ctrl8_xl.hp_ref_mode = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); + } + + return ret; +} + +/** + * @brief Enable HP filter reference mode.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of hp_ref_mode in reg CTRL8_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_reference_mode_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); + *val = ctrl8_xl.hp_ref_mode; + + return ret; +} + +/** + * @brief High pass/Slope on outputs.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of hpcf_xl in reg CTRL8_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_hp_bandwidth_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_hpcf_xl_t val) { + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); + + if(ret == 0) { + ctrl8_xl.input_composite = 0; + ctrl8_xl.hpcf_xl = (uint8_t)val & 0x03U; + ctrl8_xl.hp_slope_xl_en = 1; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); + } + + return ret; +} + +/** + * @brief High pass/Slope on outputs.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of hpcf_xl in reg CTRL8_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_hp_bandwidth_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_hpcf_xl_t* val) { + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); + + if(ctrl8_xl.hp_slope_xl_en == 0x00U) { + *val = LSM6DS3TR_C_XL_HP_NA; + } + + switch(ctrl8_xl.hpcf_xl) { + case LSM6DS3TR_C_XL_HP_ODR_DIV_4: + *val = LSM6DS3TR_C_XL_HP_ODR_DIV_4; + break; + + case LSM6DS3TR_C_XL_HP_ODR_DIV_100: + *val = LSM6DS3TR_C_XL_HP_ODR_DIV_100; + break; + + case LSM6DS3TR_C_XL_HP_ODR_DIV_9: + *val = LSM6DS3TR_C_XL_HP_ODR_DIV_9; + break; + + case LSM6DS3TR_C_XL_HP_ODR_DIV_400: + *val = LSM6DS3TR_C_XL_HP_ODR_DIV_400; + break; + + default: + *val = LSM6DS3TR_C_XL_HP_NA; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_gyroscope_filters + * @brief This section group all the functions concerning the filters + * configuration that impact gyroscope. + * @{ + * + */ + +/** + * @brief Gyroscope low pass path bandwidth.[set] + * + * @param ctx Read / write interface definitions + * @param val gyroscope filtering chain configuration. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_band_pass_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_lpf1_sel_g_t val) { + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + lsm6ds3tr_c_ctrl7_g_t ctrl7_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); + + if(ret == 0) { + ctrl7_g.hpm_g = ((uint8_t)val & 0x30U) >> 4; + ctrl7_g.hp_en_g = ((uint8_t)val & 0x80U) >> 7; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); + + if(ret == 0) { + ctrl6_c.ftype = (uint8_t)val & 0x03U; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + + if(ret == 0) { + ctrl4_c.lpf1_sel_g = ((uint8_t)val & 0x08U) >> 3; + ret = + lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + } + } + } + } + } + + return ret; +} + +/** + * @brief Gyroscope low pass path bandwidth.[get] + * + * @param ctx Read / write interface definitions + * @param val gyroscope filtering chain + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_band_pass_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_lpf1_sel_g_t* val) { + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + lsm6ds3tr_c_ctrl7_g_t ctrl7_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); + + switch((ctrl7_g.hp_en_g << 7) + (ctrl7_g.hpm_g << 4) + (ctrl4_c.lpf1_sel_g << 3) + + ctrl6_c.ftype) { + case LSM6DS3TR_C_HP_16mHz_LP2: + *val = LSM6DS3TR_C_HP_16mHz_LP2; + break; + + case LSM6DS3TR_C_HP_65mHz_LP2: + *val = LSM6DS3TR_C_HP_65mHz_LP2; + break; + + case LSM6DS3TR_C_HP_260mHz_LP2: + *val = LSM6DS3TR_C_HP_260mHz_LP2; + break; + + case LSM6DS3TR_C_HP_1Hz04_LP2: + *val = LSM6DS3TR_C_HP_1Hz04_LP2; + break; + + case LSM6DS3TR_C_HP_DISABLE_LP1_LIGHT: + *val = LSM6DS3TR_C_HP_DISABLE_LP1_LIGHT; + break; + + case LSM6DS3TR_C_HP_DISABLE_LP1_NORMAL: + *val = LSM6DS3TR_C_HP_DISABLE_LP1_NORMAL; + break; + + case LSM6DS3TR_C_HP_DISABLE_LP_STRONG: + *val = LSM6DS3TR_C_HP_DISABLE_LP_STRONG; + break; + + case LSM6DS3TR_C_HP_DISABLE_LP1_AGGRESSIVE: + *val = LSM6DS3TR_C_HP_DISABLE_LP1_AGGRESSIVE; + break; + + case LSM6DS3TR_C_HP_16mHz_LP1_LIGHT: + *val = LSM6DS3TR_C_HP_16mHz_LP1_LIGHT; + break; + + case LSM6DS3TR_C_HP_65mHz_LP1_NORMAL: + *val = LSM6DS3TR_C_HP_65mHz_LP1_NORMAL; + break; + + case LSM6DS3TR_C_HP_260mHz_LP1_STRONG: + *val = LSM6DS3TR_C_HP_260mHz_LP1_STRONG; + break; + + case LSM6DS3TR_C_HP_1Hz04_LP1_AGGRESSIVE: + *val = LSM6DS3TR_C_HP_1Hz04_LP1_AGGRESSIVE; + break; + + default: + *val = LSM6DS3TR_C_HP_GY_BAND_NA; + break; + } + } + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_serial_interface + * @brief This section groups all the functions concerning serial + * interface management + * @{ + * + */ + +/** + * @brief SPI Serial Interface Mode selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sim in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_spi_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_sim_t val) { + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + + if(ret == 0) { + ctrl3_c.sim = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief SPI Serial Interface Mode selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of sim in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_spi_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_sim_t* val) { + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + + switch(ctrl3_c.sim) { + case LSM6DS3TR_C_SPI_4_WIRE: + *val = LSM6DS3TR_C_SPI_4_WIRE; + break; + + case LSM6DS3TR_C_SPI_3_WIRE: + *val = LSM6DS3TR_C_SPI_3_WIRE; + break; + + default: + *val = LSM6DS3TR_C_SPI_MODE_ND; + break; + } + + return ret; +} + +/** + * @brief Disable / Enable I2C interface.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of i2c_disable in reg CTRL4_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_i2c_interface_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_i2c_disable_t val) { + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + + if(ret == 0) { + ctrl4_c.i2c_disable = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + } + + return ret; +} + +/** + * @brief Disable / Enable I2C interface.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of i2c_disable in reg CTRL4_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_i2c_interface_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_i2c_disable_t* val) { + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + + switch(ctrl4_c.i2c_disable) { + case LSM6DS3TR_C_I2C_ENABLE: + *val = LSM6DS3TR_C_I2C_ENABLE; + break; + + case LSM6DS3TR_C_I2C_DISABLE: + *val = LSM6DS3TR_C_I2C_DISABLE; + break; + + default: + *val = LSM6DS3TR_C_I2C_MODE_ND; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_interrupt_pins + * @brief This section groups all the functions that manage + * interrupt pins + * @{ + * + */ + +/** + * @brief Select the signal that need to route on int1 pad[set] + * + * @param ctx Read / write interface definitions + * @param val configure INT1_CTRL, MD1_CFG, CTRL4_C(den_drdy_int1), + * MASTER_CONFIG(drdy_on_int1) + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pin_int1_route_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_int1_route_t val) { + lsm6ds3tr_c_master_config_t master_config; + lsm6ds3tr_c_int1_ctrl_t int1_ctrl; + lsm6ds3tr_c_md1_cfg_t md1_cfg; + lsm6ds3tr_c_md2_cfg_t md2_cfg; + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT1_CTRL, (uint8_t*)&int1_ctrl, 1); + + if(ret == 0) { + int1_ctrl.int1_drdy_xl = val.int1_drdy_xl; + int1_ctrl.int1_drdy_g = val.int1_drdy_g; + int1_ctrl.int1_boot = val.int1_boot; + int1_ctrl.int1_fth = val.int1_fth; + int1_ctrl.int1_fifo_ovr = val.int1_fifo_ovr; + int1_ctrl.int1_full_flag = val.int1_full_flag; + int1_ctrl.int1_sign_mot = val.int1_sign_mot; + int1_ctrl.int1_step_detector = val.int1_step_detector; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_INT1_CTRL, (uint8_t*)&int1_ctrl, 1); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD1_CFG, (uint8_t*)&md1_cfg, 1); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD2_CFG, (uint8_t*)&md2_cfg, 1); + } + + if(ret == 0) { + md1_cfg.int1_timer = val.int1_timer; + md1_cfg.int1_tilt = val.int1_tilt; + md1_cfg.int1_6d = val.int1_6d; + md1_cfg.int1_double_tap = val.int1_double_tap; + md1_cfg.int1_ff = val.int1_ff; + md1_cfg.int1_wu = val.int1_wu; + md1_cfg.int1_single_tap = val.int1_single_tap; + md1_cfg.int1_inact_state = val.int1_inact_state; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MD1_CFG, (uint8_t*)&md1_cfg, 1); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + } + + if(ret == 0) { + ctrl4_c.den_drdy_int1 = val.den_drdy_int1; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + } + + if(ret == 0) { + master_config.drdy_on_int1 = val.den_drdy_int1; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + + if((val.int1_6d != 0x00U) || (val.int1_ff != 0x00U) || (val.int1_wu != 0x00U) || + (val.int1_single_tap != 0x00U) || (val.int1_double_tap != 0x00U) || + (val.int1_inact_state != 0x00U) || (md2_cfg.int2_6d != 0x00U) || + (md2_cfg.int2_ff != 0x00U) || (md2_cfg.int2_wu != 0x00U) || + (md2_cfg.int2_single_tap != 0x00U) || (md2_cfg.int2_double_tap != 0x00U) || + (md2_cfg.int2_inact_state != 0x00U)) { + tap_cfg.interrupts_enable = PROPERTY_ENABLE; + } + + else { + tap_cfg.interrupts_enable = PROPERTY_DISABLE; + } + } + + if(ret == 0) { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + } + + return ret; +} + +/** + * @brief Select the signal that need to route on int1 pad[get] + * + * @param ctx Read / write interface definitions + * @param val read INT1_CTRL, MD1_CFG, CTRL4_C(den_drdy_int1), + * MASTER_CONFIG(drdy_on_int1) + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pin_int1_route_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_int1_route_t* val) { + lsm6ds3tr_c_master_config_t master_config; + lsm6ds3tr_c_int1_ctrl_t int1_ctrl; + lsm6ds3tr_c_md1_cfg_t md1_cfg; + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT1_CTRL, (uint8_t*)&int1_ctrl, 1); + + if(ret == 0) { + val->int1_drdy_xl = int1_ctrl.int1_drdy_xl; + val->int1_drdy_g = int1_ctrl.int1_drdy_g; + val->int1_boot = int1_ctrl.int1_boot; + val->int1_fth = int1_ctrl.int1_fth; + val->int1_fifo_ovr = int1_ctrl.int1_fifo_ovr; + val->int1_full_flag = int1_ctrl.int1_full_flag; + val->int1_sign_mot = int1_ctrl.int1_sign_mot; + val->int1_step_detector = int1_ctrl.int1_step_detector; + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD1_CFG, (uint8_t*)&md1_cfg, 1); + + if(ret == 0) { + val->int1_timer = md1_cfg.int1_timer; + val->int1_tilt = md1_cfg.int1_tilt; + val->int1_6d = md1_cfg.int1_6d; + val->int1_double_tap = md1_cfg.int1_double_tap; + val->int1_ff = md1_cfg.int1_ff; + val->int1_wu = md1_cfg.int1_wu; + val->int1_single_tap = md1_cfg.int1_single_tap; + val->int1_inact_state = md1_cfg.int1_inact_state; + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + + if(ret == 0) { + val->den_drdy_int1 = ctrl4_c.den_drdy_int1; + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + val->den_drdy_int1 = master_config.drdy_on_int1; + } + } + } + + return ret; +} + +/** + * @brief Select the signal that need to route on int2 pad[set] + * + * @param ctx Read / write interface definitions + * @param val INT2_CTRL, DRDY_PULSE_CFG(int2_wrist_tilt), MD2_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pin_int2_route_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_int2_route_t val) { + lsm6ds3tr_c_int2_ctrl_t int2_ctrl; + lsm6ds3tr_c_md1_cfg_t md1_cfg; + lsm6ds3tr_c_md2_cfg_t md2_cfg; + lsm6ds3tr_c_drdy_pulse_cfg_g_t drdy_pulse_cfg_g; + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT2_CTRL, (uint8_t*)&int2_ctrl, 1); + + if(ret == 0) { + int2_ctrl.int2_drdy_xl = val.int2_drdy_xl; + int2_ctrl.int2_drdy_g = val.int2_drdy_g; + int2_ctrl.int2_drdy_temp = val.int2_drdy_temp; + int2_ctrl.int2_fth = val.int2_fth; + int2_ctrl.int2_fifo_ovr = val.int2_fifo_ovr; + int2_ctrl.int2_full_flag = val.int2_full_flag; + int2_ctrl.int2_step_count_ov = val.int2_step_count_ov; + int2_ctrl.int2_step_delta = val.int2_step_delta; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_INT2_CTRL, (uint8_t*)&int2_ctrl, 1); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD1_CFG, (uint8_t*)&md1_cfg, 1); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD2_CFG, (uint8_t*)&md2_cfg, 1); + } + + if(ret == 0) { + md2_cfg.int2_iron = val.int2_iron; + md2_cfg.int2_tilt = val.int2_tilt; + md2_cfg.int2_6d = val.int2_6d; + md2_cfg.int2_double_tap = val.int2_double_tap; + md2_cfg.int2_ff = val.int2_ff; + md2_cfg.int2_wu = val.int2_wu; + md2_cfg.int2_single_tap = val.int2_single_tap; + md2_cfg.int2_inact_state = val.int2_inact_state; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MD2_CFG, (uint8_t*)&md2_cfg, 1); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, (uint8_t*)&drdy_pulse_cfg_g, 1); + } + + if(ret == 0) { + drdy_pulse_cfg_g.int2_wrist_tilt = val.int2_wrist_tilt; + ret = lsm6ds3tr_c_write_reg( + ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, (uint8_t*)&drdy_pulse_cfg_g, 1); + } + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + + if((md1_cfg.int1_6d != 0x00U) || (md1_cfg.int1_ff != 0x00U) || + (md1_cfg.int1_wu != 0x00U) || (md1_cfg.int1_single_tap != 0x00U) || + (md1_cfg.int1_double_tap != 0x00U) || (md1_cfg.int1_inact_state != 0x00U) || + (val.int2_6d != 0x00U) || (val.int2_ff != 0x00U) || (val.int2_wu != 0x00U) || + (val.int2_single_tap != 0x00U) || (val.int2_double_tap != 0x00U) || + (val.int2_inact_state != 0x00U)) { + tap_cfg.interrupts_enable = PROPERTY_ENABLE; + } + + else { + tap_cfg.interrupts_enable = PROPERTY_DISABLE; + } + } + + if(ret == 0) { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + } + + return ret; +} + +/** + * @brief Select the signal that need to route on int2 pad[get] + * + * @param ctx Read / write interface definitions + * @param val INT2_CTRL, DRDY_PULSE_CFG(int2_wrist_tilt), MD2_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pin_int2_route_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_int2_route_t* val) { + lsm6ds3tr_c_int2_ctrl_t int2_ctrl; + lsm6ds3tr_c_md2_cfg_t md2_cfg; + lsm6ds3tr_c_drdy_pulse_cfg_g_t drdy_pulse_cfg_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT2_CTRL, (uint8_t*)&int2_ctrl, 1); + + if(ret == 0) { + val->int2_drdy_xl = int2_ctrl.int2_drdy_xl; + val->int2_drdy_g = int2_ctrl.int2_drdy_g; + val->int2_drdy_temp = int2_ctrl.int2_drdy_temp; + val->int2_fth = int2_ctrl.int2_fth; + val->int2_fifo_ovr = int2_ctrl.int2_fifo_ovr; + val->int2_full_flag = int2_ctrl.int2_full_flag; + val->int2_step_count_ov = int2_ctrl.int2_step_count_ov; + val->int2_step_delta = int2_ctrl.int2_step_delta; + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD2_CFG, (uint8_t*)&md2_cfg, 1); + + if(ret == 0) { + val->int2_iron = md2_cfg.int2_iron; + val->int2_tilt = md2_cfg.int2_tilt; + val->int2_6d = md2_cfg.int2_6d; + val->int2_double_tap = md2_cfg.int2_double_tap; + val->int2_ff = md2_cfg.int2_ff; + val->int2_wu = md2_cfg.int2_wu; + val->int2_single_tap = md2_cfg.int2_single_tap; + val->int2_inact_state = md2_cfg.int2_inact_state; + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, (uint8_t*)&drdy_pulse_cfg_g, 1); + val->int2_wrist_tilt = drdy_pulse_cfg_g.int2_wrist_tilt; + } + } + + return ret; +} + +/** + * @brief Push-pull/open drain selection on interrupt pads.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pp_od in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pin_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_pp_od_t val) { + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + + if(ret == 0) { + ctrl3_c.pp_od = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief Push-pull/open drain selection on interrupt pads.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of pp_od in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pin_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_pp_od_t* val) { + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + + switch(ctrl3_c.pp_od) { + case LSM6DS3TR_C_PUSH_PULL: + *val = LSM6DS3TR_C_PUSH_PULL; + break; + + case LSM6DS3TR_C_OPEN_DRAIN: + *val = LSM6DS3TR_C_OPEN_DRAIN; + break; + + default: + *val = LSM6DS3TR_C_PIN_MODE_ND; + break; + } + + return ret; +} + +/** + * @brief Interrupt active-high/low.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of h_lactive in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pin_polarity_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_h_lactive_t val) { + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + + if(ret == 0) { + ctrl3_c.h_lactive = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief Interrupt active-high/low.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of h_lactive in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pin_polarity_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_h_lactive_t* val) { + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); + + switch(ctrl3_c.h_lactive) { + case LSM6DS3TR_C_ACTIVE_HIGH: + *val = LSM6DS3TR_C_ACTIVE_HIGH; + break; + + case LSM6DS3TR_C_ACTIVE_LOW: + *val = LSM6DS3TR_C_ACTIVE_LOW; + break; + + default: + *val = LSM6DS3TR_C_POLARITY_ND; + break; + } + + return ret; +} + +/** + * @brief All interrupt signals become available on INT1 pin.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of int2_on_int1 in reg CTRL4_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_all_on_int1_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + + if(ret == 0) { + ctrl4_c.int2_on_int1 = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + } + + return ret; +} + +/** + * @brief All interrupt signals become available on INT1 pin.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of int2_on_int1 in reg CTRL4_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_all_on_int1_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + *val = ctrl4_c.int2_on_int1; + + return ret; +} + +/** + * @brief Latched/pulsed interrupt.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of lir in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_int_notification_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_lir_t val) { + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + + if(ret == 0) { + tap_cfg.lir = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + } + + return ret; +} + +/** + * @brief Latched/pulsed interrupt.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of lir in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_int_notification_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_lir_t* val) { + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + + switch(tap_cfg.lir) { + case LSM6DS3TR_C_INT_PULSED: + *val = LSM6DS3TR_C_INT_PULSED; + break; + + case LSM6DS3TR_C_INT_LATCHED: + *val = LSM6DS3TR_C_INT_LATCHED; + break; + + default: + *val = LSM6DS3TR_C_INT_MODE; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_Wake_Up_event + * @brief This section groups all the functions that manage the + * Wake Up event generation. + * @{ + * + */ + +/** + * @brief Threshold for wakeup.1 LSB = FS_XL / 64.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of wk_ths in reg WAKE_UP_THS + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_wkup_threshold_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_wake_up_ths_t wake_up_ths; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, (uint8_t*)&wake_up_ths, 1); + + if(ret == 0) { + wake_up_ths.wk_ths = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, (uint8_t*)&wake_up_ths, 1); + } + + return ret; +} + +/** + * @brief Threshold for wakeup.1 LSB = FS_XL / 64.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of wk_ths in reg WAKE_UP_THS + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_wkup_threshold_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_wake_up_ths_t wake_up_ths; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, (uint8_t*)&wake_up_ths, 1); + *val = wake_up_ths.wk_ths; + + return ret; +} + +/** + * @brief Wake up duration event.1LSb = 1 / ODR[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of wake_dur in reg WAKE_UP_DUR + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_wkup_dur_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); + + if(ret == 0) { + wake_up_dur.wake_dur = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); + } + + return ret; +} + +/** + * @brief Wake up duration event.1LSb = 1 / ODR[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of wake_dur in reg WAKE_UP_DUR + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_wkup_dur_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); + *val = wake_up_dur.wake_dur; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_Activity/Inactivity_detection + * @brief This section groups all the functions concerning + * activity/inactivity detection. + * @{ + * + */ + +/** + * @brief Enables gyroscope Sleep mode.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sleep in reg CTRL4_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_sleep_mode_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + + if(ret == 0) { + ctrl4_c.sleep = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + } + + return ret; +} + +/** + * @brief Enables gyroscope Sleep mode.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sleep in reg CTRL4_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_sleep_mode_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + *val = ctrl4_c.sleep; + + return ret; +} + +/** + * @brief Enable inactivity function.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of inact_en in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_act_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_inact_en_t val) { + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + + if(ret == 0) { + tap_cfg.inact_en = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + } + + return ret; +} + +/** + * @brief Enable inactivity function.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of inact_en in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_act_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_inact_en_t* val) { + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + + switch(tap_cfg.inact_en) { + case LSM6DS3TR_C_PROPERTY_DISABLE: + *val = LSM6DS3TR_C_PROPERTY_DISABLE; + break; + + case LSM6DS3TR_C_XL_12Hz5_GY_NOT_AFFECTED: + *val = LSM6DS3TR_C_XL_12Hz5_GY_NOT_AFFECTED; + break; + + case LSM6DS3TR_C_XL_12Hz5_GY_SLEEP: + *val = LSM6DS3TR_C_XL_12Hz5_GY_SLEEP; + break; + + case LSM6DS3TR_C_XL_12Hz5_GY_PD: + *val = LSM6DS3TR_C_XL_12Hz5_GY_PD; + break; + + default: + *val = LSM6DS3TR_C_ACT_MODE_ND; + break; + } + + return ret; +} + +/** + * @brief Duration to go in sleep mode.1 LSb = 512 / ODR[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sleep_dur in reg WAKE_UP_DUR + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_act_sleep_dur_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); + + if(ret == 0) { + wake_up_dur.sleep_dur = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); + } + + return ret; +} + +/** + * @brief Duration to go in sleep mode. 1 LSb = 512 / ODR[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sleep_dur in reg WAKE_UP_DUR + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_act_sleep_dur_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); + *val = wake_up_dur.sleep_dur; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_tap_generator + * @brief This section groups all the functions that manage the + * tap and double tap event generation. + * @{ + * + */ + +/** + * @brief Read the tap / double tap source register.[get] + * + * @param ctx Read / write interface definitions + * @param val Structure of registers from TAP_SRC + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_src_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_tap_src_t* val) { + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_SRC, (uint8_t*)val, 1); + + return ret; +} + +/** + * @brief Enable Z direction in tap recognition.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tap_z_en in reg TAP_CFG + * + */ +int32_t lsm6ds3tr_c_tap_detection_on_z_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + + if(ret == 0) { + tap_cfg.tap_z_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + } + + return ret; +} + +/** + * @brief Enable Z direction in tap recognition.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tap_z_en in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_detection_on_z_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + *val = tap_cfg.tap_z_en; + + return ret; +} + +/** + * @brief Enable Y direction in tap recognition.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tap_y_en in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_detection_on_y_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + + if(ret == 0) { + tap_cfg.tap_y_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + } + + return ret; +} + +/** + * @brief Enable Y direction in tap recognition.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tap_y_en in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_detection_on_y_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + *val = tap_cfg.tap_y_en; + + return ret; +} + +/** + * @brief Enable X direction in tap recognition.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tap_x_en in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_detection_on_x_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + + if(ret == 0) { + tap_cfg.tap_x_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + } + + return ret; +} + +/** + * @brief Enable X direction in tap recognition.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tap_x_en in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_detection_on_x_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); + *val = tap_cfg.tap_x_en; + + return ret; +} + +/** + * @brief Threshold for tap recognition.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tap_ths in reg TAP_THS_6D + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_threshold_x_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); + + if(ret == 0) { + tap_ths_6d.tap_ths = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); + } + + return ret; +} + +/** + * @brief Threshold for tap recognition.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tap_ths in reg TAP_THS_6D + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_threshold_x_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); + *val = tap_ths_6d.tap_ths; + + return ret; +} + +/** + * @brief Maximum duration is the maximum time of an overthreshold signal + * detection to be recognized as a tap event. + * The default value of these bits is 00b which corresponds to + * 4*ODR_XL time. + * If the SHOCK[1:0] bits are set to a different + * value, 1LSB corresponds to 8*ODR_XL time.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of shock in reg INT_DUR2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_shock_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_int_dur2_t int_dur2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); + + if(ret == 0) { + int_dur2.shock = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); + } + + return ret; +} + +/** + * @brief Maximum duration is the maximum time of an overthreshold signal + * detection to be recognized as a tap event. + * The default value of these bits is 00b which corresponds to + * 4*ODR_XL time. + * If the SHOCK[1:0] bits are set to a different value, 1LSB + * corresponds to 8*ODR_XL time.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of shock in reg INT_DUR2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_shock_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_int_dur2_t int_dur2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); + *val = int_dur2.shock; + + return ret; +} + +/** + * @brief Quiet time is the time after the first detected tap in which there + * must not be any overthreshold event. + * The default value of these bits is 00b which corresponds to + * 2*ODR_XL time. + * If the QUIET[1:0] bits are set to a different value, 1LSB + * corresponds to 4*ODR_XL time.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of quiet in reg INT_DUR2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_quiet_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_int_dur2_t int_dur2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); + + if(ret == 0) { + int_dur2.quiet = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); + } + + return ret; +} + +/** + * @brief Quiet time is the time after the first detected tap in which there + * must not be any overthreshold event. + * The default value of these bits is 00b which corresponds to + * 2*ODR_XL time. + * If the QUIET[1:0] bits are set to a different value, 1LSB + * corresponds to 4*ODR_XL time.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of quiet in reg INT_DUR2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_quiet_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_int_dur2_t int_dur2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); + *val = int_dur2.quiet; + + return ret; +} + +/** + * @brief When double tap recognition is enabled, this register expresses the + * maximum time between two consecutive detected taps to determine a + * double tap event. + * The default value of these bits is 0000b which corresponds to + * 16*ODR_XL time. + * If the DUR[3:0] bits are set to a different value,1LSB corresponds + * to 32*ODR_XL time.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of dur in reg INT_DUR2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_dur_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_int_dur2_t int_dur2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); + + if(ret == 0) { + int_dur2.dur = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); + } + + return ret; +} + +/** + * @brief When double tap recognition is enabled, this register expresses the + * maximum time between two consecutive detected taps to determine a + * double tap event. + * The default value of these bits is 0000b which corresponds to + * 16*ODR_XL time. + * If the DUR[3:0] bits are set to a different value,1LSB corresponds + * to 32*ODR_XL time.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of dur in reg INT_DUR2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_dur_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_int_dur2_t int_dur2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); + *val = int_dur2.dur; + + return ret; +} + +/** + * @brief Single/double-tap event enable/disable.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of + * single_double_tap in reg WAKE_UP_THS + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_single_double_tap_t val) { + lsm6ds3tr_c_wake_up_ths_t wake_up_ths; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, (uint8_t*)&wake_up_ths, 1); + + if(ret == 0) { + wake_up_ths.single_double_tap = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, (uint8_t*)&wake_up_ths, 1); + } + + return ret; +} + +/** + * @brief Single/double-tap event enable/disable.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of single_double_tap + * in reg WAKE_UP_THS + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_single_double_tap_t* val) { + lsm6ds3tr_c_wake_up_ths_t wake_up_ths; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, (uint8_t*)&wake_up_ths, 1); + + switch(wake_up_ths.single_double_tap) { + case LSM6DS3TR_C_ONLY_SINGLE: + *val = LSM6DS3TR_C_ONLY_SINGLE; + break; + + case LSM6DS3TR_C_BOTH_SINGLE_DOUBLE: + *val = LSM6DS3TR_C_BOTH_SINGLE_DOUBLE; + break; + + default: + *val = LSM6DS3TR_C_TAP_MODE_ND; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_ Six_position_detection(6D/4D) + * @brief This section groups all the functions concerning six + * position detection (6D). + * @{ + * + */ + +/** + * @brief LPF2 feed 6D function selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of low_pass_on_6d in + * reg CTRL8_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_6d_feed_data_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_low_pass_on_6d_t val) { + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); + + if(ret == 0) { + ctrl8_xl.low_pass_on_6d = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); + } + + return ret; +} + +/** + * @brief LPF2 feed 6D function selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of low_pass_on_6d in reg CTRL8_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_6d_feed_data_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_low_pass_on_6d_t* val) { + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); + + switch(ctrl8_xl.low_pass_on_6d) { + case LSM6DS3TR_C_ODR_DIV_2_FEED: + *val = LSM6DS3TR_C_ODR_DIV_2_FEED; + break; + + case LSM6DS3TR_C_LPF2_FEED: + *val = LSM6DS3TR_C_LPF2_FEED; + break; + + default: + *val = LSM6DS3TR_C_6D_FEED_ND; + break; + } + + return ret; +} + +/** + * @brief Threshold for 4D/6D function.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sixd_ths in reg TAP_THS_6D + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_6d_threshold_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_sixd_ths_t val) { + lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); + + if(ret == 0) { + tap_ths_6d.sixd_ths = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); + } + + return ret; +} + +/** + * @brief Threshold for 4D/6D function.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of sixd_ths in reg TAP_THS_6D + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_6d_threshold_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_sixd_ths_t* val) { + lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); + + switch(tap_ths_6d.sixd_ths) { + case LSM6DS3TR_C_DEG_80: + *val = LSM6DS3TR_C_DEG_80; + break; + + case LSM6DS3TR_C_DEG_70: + *val = LSM6DS3TR_C_DEG_70; + break; + + case LSM6DS3TR_C_DEG_60: + *val = LSM6DS3TR_C_DEG_60; + break; + + case LSM6DS3TR_C_DEG_50: + *val = LSM6DS3TR_C_DEG_50; + break; + + default: + *val = LSM6DS3TR_C_6D_TH_ND; + break; + } + + return ret; +} + +/** + * @brief 4D orientation detection enable.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of d4d_en in reg TAP_THS_6D + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_4d_mode_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); + + if(ret == 0) { + tap_ths_6d.d4d_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); + } + + return ret; +} + +/** + * @brief 4D orientation detection enable.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of d4d_en in reg TAP_THS_6D + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_4d_mode_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); + *val = tap_ths_6d.d4d_en; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_free_fall + * @brief This section group all the functions concerning the free + * fall detection. + * @{ + * + */ + +/** + * @brief Free-fall duration event. 1LSb = 1 / ODR[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of ff_dur in reg WAKE_UP_DUR + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_ff_dur_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + lsm6ds3tr_c_free_fall_t free_fall; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FREE_FALL, (uint8_t*)&free_fall, 1); + + if(ret == 0) { + free_fall.ff_dur = (val & 0x1FU); + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FREE_FALL, (uint8_t*)&free_fall, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); + + if(ret == 0) { + wake_up_dur.ff_dur = (val & 0x20U) >> 5; + ret = + lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); + } + } + } + + return ret; +} + +/** + * @brief Free-fall duration event. 1LSb = 1 / ODR[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of ff_dur in reg WAKE_UP_DUR + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_ff_dur_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + lsm6ds3tr_c_free_fall_t free_fall; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FREE_FALL, (uint8_t*)&free_fall, 1); + } + + *val = (wake_up_dur.ff_dur << 5) + free_fall.ff_dur; + + return ret; +} + +/** + * @brief Free fall threshold setting.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of ff_ths in reg FREE_FALL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_ff_threshold_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_ff_ths_t val) { + lsm6ds3tr_c_free_fall_t free_fall; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FREE_FALL, (uint8_t*)&free_fall, 1); + + if(ret == 0) { + free_fall.ff_ths = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FREE_FALL, (uint8_t*)&free_fall, 1); + } + + return ret; +} + +/** + * @brief Free fall threshold setting.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of ff_ths in reg FREE_FALL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_ff_threshold_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_ff_ths_t* val) { + lsm6ds3tr_c_free_fall_t free_fall; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FREE_FALL, (uint8_t*)&free_fall, 1); + + switch(free_fall.ff_ths) { + case LSM6DS3TR_C_FF_TSH_156mg: + *val = LSM6DS3TR_C_FF_TSH_156mg; + break; + + case LSM6DS3TR_C_FF_TSH_219mg: + *val = LSM6DS3TR_C_FF_TSH_219mg; + break; + + case LSM6DS3TR_C_FF_TSH_250mg: + *val = LSM6DS3TR_C_FF_TSH_250mg; + break; + + case LSM6DS3TR_C_FF_TSH_312mg: + *val = LSM6DS3TR_C_FF_TSH_312mg; + break; + + case LSM6DS3TR_C_FF_TSH_344mg: + *val = LSM6DS3TR_C_FF_TSH_344mg; + break; + + case LSM6DS3TR_C_FF_TSH_406mg: + *val = LSM6DS3TR_C_FF_TSH_406mg; + break; + + case LSM6DS3TR_C_FF_TSH_469mg: + *val = LSM6DS3TR_C_FF_TSH_469mg; + break; + + case LSM6DS3TR_C_FF_TSH_500mg: + *val = LSM6DS3TR_C_FF_TSH_500mg; + break; + + default: + *val = LSM6DS3TR_C_FF_TSH_ND; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_fifo + * @brief This section group all the functions concerning the + * fifo usage + * @{ + * + */ + +/** + * @brief FIFO watermark level selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of fth in reg FIFO_CTRL1 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_watermark_set(stmdev_ctx_t* ctx, uint16_t val) { + lsm6ds3tr_c_fifo_ctrl1_t fifo_ctrl1; + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); + + if(ret == 0) { + fifo_ctrl1.fth = (uint8_t)(0x00FFU & val); + fifo_ctrl2.fth = (uint8_t)((0x0700U & val) >> 8); + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL1, (uint8_t*)&fifo_ctrl1, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); + } + } + + return ret; +} + +/** + * @brief FIFO watermark level selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of fth in reg FIFO_CTRL1 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_watermark_get(stmdev_ctx_t* ctx, uint16_t* val) { + lsm6ds3tr_c_fifo_ctrl1_t fifo_ctrl1; + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL1, (uint8_t*)&fifo_ctrl1, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); + } + + *val = ((uint16_t)fifo_ctrl2.fth << 8) + (uint16_t)fifo_ctrl1.fth; + + return ret; +} + +/** + * @brief FIFO data level.[get] + * + * @param ctx Read / write interface definitions + * @param val get the values of diff_fifo in reg FIFO_STATUS1 and + * FIFO_STATUS2(diff_fifo), it is recommended to set the + * BDU bit. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_data_level_get(stmdev_ctx_t* ctx, uint16_t* val) { + lsm6ds3tr_c_fifo_status1_t fifo_status1; + lsm6ds3tr_c_fifo_status2_t fifo_status2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_STATUS1, (uint8_t*)&fifo_status1, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_STATUS2, (uint8_t*)&fifo_status2, 1); + *val = ((uint16_t)fifo_status2.diff_fifo << 8) + (uint16_t)fifo_status1.diff_fifo; + } + + return ret; +} + +/** + * @brief FIFO watermark.[get] + * + * @param ctx Read / write interface definitions + * @param val get the values of watermark in reg FIFO_STATUS2 and + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_wtm_flag_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_fifo_status2_t fifo_status2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_STATUS2, (uint8_t*)&fifo_status2, 1); + *val = fifo_status2.waterm; + + return ret; +} + +/** + * @brief FIFO pattern.[get] + * + * @param ctx Read / write interface definitions + * @param val get the values of fifo_pattern in reg FIFO_STATUS3 and + * FIFO_STATUS4, it is recommended to set the BDU bit + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_pattern_get(stmdev_ctx_t* ctx, uint16_t* val) { + lsm6ds3tr_c_fifo_status3_t fifo_status3; + lsm6ds3tr_c_fifo_status4_t fifo_status4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_STATUS3, (uint8_t*)&fifo_status3, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_STATUS4, (uint8_t*)&fifo_status4, 1); + *val = ((uint16_t)fifo_status4.fifo_pattern << 8) + fifo_status3.fifo_pattern; + } + + return ret; +} + +/** + * @brief Batching of temperature data[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of fifo_temp_en in reg FIFO_CTRL2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_temp_batch_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); + + if(ret == 0) { + fifo_ctrl2.fifo_temp_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); + } + + return ret; +} + +/** + * @brief Batching of temperature data[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of fifo_temp_en in reg FIFO_CTRL2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_temp_batch_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); + *val = fifo_ctrl2.fifo_temp_en; + + return ret; +} + +/** + * @brief Trigger signal for FIFO write operation.[set] + * + * @param ctx Read / write interface definitions + * @param val act on FIFO_CTRL2(timer_pedo_fifo_drdy) + * and MASTER_CONFIG(data_valid_sel_fifo) + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_write_trigger_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_trigger_fifo_t val) { + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); + + if(ret == 0) { + fifo_ctrl2.timer_pedo_fifo_drdy = (uint8_t)val & 0x01U; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); + + if(ret == 0) { + ret = + lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + + if(ret == 0) { + master_config.data_valid_sel_fifo = (((uint8_t)val & 0x02U) >> 1); + ret = lsm6ds3tr_c_write_reg( + ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + } + } + } + + return ret; +} + +/** + * @brief Trigger signal for FIFO write operation.[get] + * + * @param ctx Read / write interface definitions + * @param val act on FIFO_CTRL2(timer_pedo_fifo_drdy) + * and MASTER_CONFIG(data_valid_sel_fifo) + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_write_trigger_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_trigger_fifo_t* val) { + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + + switch((fifo_ctrl2.timer_pedo_fifo_drdy << 1) + fifo_ctrl2.timer_pedo_fifo_drdy) { + case LSM6DS3TR_C_TRG_XL_GY_DRDY: + *val = LSM6DS3TR_C_TRG_XL_GY_DRDY; + break; + + case LSM6DS3TR_C_TRG_STEP_DETECT: + *val = LSM6DS3TR_C_TRG_STEP_DETECT; + break; + + case LSM6DS3TR_C_TRG_SH_DRDY: + *val = LSM6DS3TR_C_TRG_SH_DRDY; + break; + + default: + *val = LSM6DS3TR_C_TRG_SH_ND; + break; + } + } + + return ret; +} + +/** + * @brief Enable pedometer step counter and timestamp as 4th + * FIFO data set.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of timer_pedo_fifo_en in reg FIFO_CTRL2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_pedo_and_timestamp_batch_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); + + if(ret == 0) { + fifo_ctrl2.timer_pedo_fifo_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); + } + + return ret; +} + +/** + * @brief Enable pedometer step counter and timestamp as 4th + * FIFO data set.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of timer_pedo_fifo_en in reg FIFO_CTRL2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_pedo_and_timestamp_batch_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); + *val = fifo_ctrl2.timer_pedo_fifo_en; + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) for + * accelerometer data.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of dec_fifo_xl in reg FIFO_CTRL3 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_xl_batch_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_fifo_xl_t val) { + lsm6ds3tr_c_fifo_ctrl3_t fifo_ctrl3; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, (uint8_t*)&fifo_ctrl3, 1); + + if(ret == 0) { + fifo_ctrl3.dec_fifo_xl = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, (uint8_t*)&fifo_ctrl3, 1); + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) for + * accelerometer data.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of dec_fifo_xl in reg FIFO_CTRL3 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_xl_batch_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_fifo_xl_t* val) { + lsm6ds3tr_c_fifo_ctrl3_t fifo_ctrl3; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, (uint8_t*)&fifo_ctrl3, 1); + + switch(fifo_ctrl3.dec_fifo_xl) { + case LSM6DS3TR_C_FIFO_XL_DISABLE: + *val = LSM6DS3TR_C_FIFO_XL_DISABLE; + break; + + case LSM6DS3TR_C_FIFO_XL_NO_DEC: + *val = LSM6DS3TR_C_FIFO_XL_NO_DEC; + break; + + case LSM6DS3TR_C_FIFO_XL_DEC_2: + *val = LSM6DS3TR_C_FIFO_XL_DEC_2; + break; + + case LSM6DS3TR_C_FIFO_XL_DEC_3: + *val = LSM6DS3TR_C_FIFO_XL_DEC_3; + break; + + case LSM6DS3TR_C_FIFO_XL_DEC_4: + *val = LSM6DS3TR_C_FIFO_XL_DEC_4; + break; + + case LSM6DS3TR_C_FIFO_XL_DEC_8: + *val = LSM6DS3TR_C_FIFO_XL_DEC_8; + break; + + case LSM6DS3TR_C_FIFO_XL_DEC_16: + *val = LSM6DS3TR_C_FIFO_XL_DEC_16; + break; + + case LSM6DS3TR_C_FIFO_XL_DEC_32: + *val = LSM6DS3TR_C_FIFO_XL_DEC_32; + break; + + default: + *val = LSM6DS3TR_C_FIFO_XL_DEC_ND; + break; + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) + * for gyroscope data.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of dec_fifo_gyro in reg FIFO_CTRL3 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_gy_batch_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_fifo_gyro_t val) { + lsm6ds3tr_c_fifo_ctrl3_t fifo_ctrl3; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, (uint8_t*)&fifo_ctrl3, 1); + + if(ret == 0) { + fifo_ctrl3.dec_fifo_gyro = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, (uint8_t*)&fifo_ctrl3, 1); + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) + * for gyroscope data.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of dec_fifo_gyro in reg FIFO_CTRL3 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_gy_batch_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_fifo_gyro_t* val) { + lsm6ds3tr_c_fifo_ctrl3_t fifo_ctrl3; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, (uint8_t*)&fifo_ctrl3, 1); + + switch(fifo_ctrl3.dec_fifo_gyro) { + case LSM6DS3TR_C_FIFO_GY_DISABLE: + *val = LSM6DS3TR_C_FIFO_GY_DISABLE; + break; + + case LSM6DS3TR_C_FIFO_GY_NO_DEC: + *val = LSM6DS3TR_C_FIFO_GY_NO_DEC; + break; + + case LSM6DS3TR_C_FIFO_GY_DEC_2: + *val = LSM6DS3TR_C_FIFO_GY_DEC_2; + break; + + case LSM6DS3TR_C_FIFO_GY_DEC_3: + *val = LSM6DS3TR_C_FIFO_GY_DEC_3; + break; + + case LSM6DS3TR_C_FIFO_GY_DEC_4: + *val = LSM6DS3TR_C_FIFO_GY_DEC_4; + break; + + case LSM6DS3TR_C_FIFO_GY_DEC_8: + *val = LSM6DS3TR_C_FIFO_GY_DEC_8; + break; + + case LSM6DS3TR_C_FIFO_GY_DEC_16: + *val = LSM6DS3TR_C_FIFO_GY_DEC_16; + break; + + case LSM6DS3TR_C_FIFO_GY_DEC_32: + *val = LSM6DS3TR_C_FIFO_GY_DEC_32; + break; + + default: + *val = LSM6DS3TR_C_FIFO_GY_DEC_ND; + break; + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) + * for third data set.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of dec_ds3_fifo in reg FIFO_CTRL4 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_dataset_3_batch_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_ds3_fifo_t val) { + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); + + if(ret == 0) { + fifo_ctrl4.dec_ds3_fifo = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) + * for third data set.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of dec_ds3_fifo in reg FIFO_CTRL4 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_dataset_3_batch_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_ds3_fifo_t* val) { + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); + + switch(fifo_ctrl4.dec_ds3_fifo) { + case LSM6DS3TR_C_FIFO_DS3_DISABLE: + *val = LSM6DS3TR_C_FIFO_DS3_DISABLE; + break; + + case LSM6DS3TR_C_FIFO_DS3_NO_DEC: + *val = LSM6DS3TR_C_FIFO_DS3_NO_DEC; + break; + + case LSM6DS3TR_C_FIFO_DS3_DEC_2: + *val = LSM6DS3TR_C_FIFO_DS3_DEC_2; + break; + + case LSM6DS3TR_C_FIFO_DS3_DEC_3: + *val = LSM6DS3TR_C_FIFO_DS3_DEC_3; + break; + + case LSM6DS3TR_C_FIFO_DS3_DEC_4: + *val = LSM6DS3TR_C_FIFO_DS3_DEC_4; + break; + + case LSM6DS3TR_C_FIFO_DS3_DEC_8: + *val = LSM6DS3TR_C_FIFO_DS3_DEC_8; + break; + + case LSM6DS3TR_C_FIFO_DS3_DEC_16: + *val = LSM6DS3TR_C_FIFO_DS3_DEC_16; + break; + + case LSM6DS3TR_C_FIFO_DS3_DEC_32: + *val = LSM6DS3TR_C_FIFO_DS3_DEC_32; + break; + + default: + *val = LSM6DS3TR_C_FIFO_DS3_DEC_ND; + break; + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) + * for fourth data set.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of dec_ds4_fifo in reg FIFO_CTRL4 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_dataset_4_batch_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_ds4_fifo_t val) { + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); + + if(ret == 0) { + fifo_ctrl4.dec_ds4_fifo = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) for + * fourth data set.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of dec_ds4_fifo in reg FIFO_CTRL4 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_dataset_4_batch_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_ds4_fifo_t* val) { + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); + + switch(fifo_ctrl4.dec_ds4_fifo) { + case LSM6DS3TR_C_FIFO_DS4_DISABLE: + *val = LSM6DS3TR_C_FIFO_DS4_DISABLE; + break; + + case LSM6DS3TR_C_FIFO_DS4_NO_DEC: + *val = LSM6DS3TR_C_FIFO_DS4_NO_DEC; + break; + + case LSM6DS3TR_C_FIFO_DS4_DEC_2: + *val = LSM6DS3TR_C_FIFO_DS4_DEC_2; + break; + + case LSM6DS3TR_C_FIFO_DS4_DEC_3: + *val = LSM6DS3TR_C_FIFO_DS4_DEC_3; + break; + + case LSM6DS3TR_C_FIFO_DS4_DEC_4: + *val = LSM6DS3TR_C_FIFO_DS4_DEC_4; + break; + + case LSM6DS3TR_C_FIFO_DS4_DEC_8: + *val = LSM6DS3TR_C_FIFO_DS4_DEC_8; + break; + + case LSM6DS3TR_C_FIFO_DS4_DEC_16: + *val = LSM6DS3TR_C_FIFO_DS4_DEC_16; + break; + + case LSM6DS3TR_C_FIFO_DS4_DEC_32: + *val = LSM6DS3TR_C_FIFO_DS4_DEC_32; + break; + + default: + *val = LSM6DS3TR_C_FIFO_DS4_DEC_ND; + break; + } + + return ret; +} + +/** + * @brief 8-bit data storage in FIFO.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of only_high_data in reg FIFO_CTRL4 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_xl_gy_8bit_format_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); + + if(ret == 0) { + fifo_ctrl4.only_high_data = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); + } + + return ret; +} + +/** + * @brief 8-bit data storage in FIFO.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of only_high_data in reg FIFO_CTRL4 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_xl_gy_8bit_format_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); + *val = fifo_ctrl4.only_high_data; + + return ret; +} + +/** + * @brief Sensing chain FIFO stop values memorization at threshold + * level.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of stop_on_fth in reg FIFO_CTRL4 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_stop_on_wtm_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); + + if(ret == 0) { + fifo_ctrl4.stop_on_fth = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); + } + + return ret; +} + +/** + * @brief Sensing chain FIFO stop values memorization at threshold + * level.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of stop_on_fth in reg FIFO_CTRL4 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_stop_on_wtm_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); + *val = fifo_ctrl4.stop_on_fth; + + return ret; +} + +/** + * @brief FIFO mode selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of fifo_mode in reg FIFO_CTRL5 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_fifo_mode_t val) { + lsm6ds3tr_c_fifo_ctrl5_t fifo_ctrl5; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, (uint8_t*)&fifo_ctrl5, 1); + + if(ret == 0) { + fifo_ctrl5.fifo_mode = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, (uint8_t*)&fifo_ctrl5, 1); + } + + return ret; +} + +/** + * @brief FIFO mode selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of fifo_mode in reg FIFO_CTRL5 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_fifo_mode_t* val) { + lsm6ds3tr_c_fifo_ctrl5_t fifo_ctrl5; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, (uint8_t*)&fifo_ctrl5, 1); + + switch(fifo_ctrl5.fifo_mode) { + case LSM6DS3TR_C_BYPASS_MODE: + *val = LSM6DS3TR_C_BYPASS_MODE; + break; + + case LSM6DS3TR_C_FIFO_MODE: + *val = LSM6DS3TR_C_FIFO_MODE; + break; + + case LSM6DS3TR_C_STREAM_TO_FIFO_MODE: + *val = LSM6DS3TR_C_STREAM_TO_FIFO_MODE; + break; + + case LSM6DS3TR_C_BYPASS_TO_STREAM_MODE: + *val = LSM6DS3TR_C_BYPASS_TO_STREAM_MODE; + break; + + case LSM6DS3TR_C_STREAM_MODE: + *val = LSM6DS3TR_C_STREAM_MODE; + break; + + default: + *val = LSM6DS3TR_C_FIFO_MODE_ND; + break; + } + + return ret; +} + +/** + * @brief FIFO ODR selection, setting FIFO_MODE also.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of odr_fifo in reg FIFO_CTRL5 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_data_rate_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_fifo_t val) { + lsm6ds3tr_c_fifo_ctrl5_t fifo_ctrl5; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, (uint8_t*)&fifo_ctrl5, 1); + + if(ret == 0) { + fifo_ctrl5.odr_fifo = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, (uint8_t*)&fifo_ctrl5, 1); + } + + return ret; +} + +/** + * @brief FIFO ODR selection, setting FIFO_MODE also.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of odr_fifo in reg FIFO_CTRL5 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_data_rate_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_fifo_t* val) { + lsm6ds3tr_c_fifo_ctrl5_t fifo_ctrl5; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, (uint8_t*)&fifo_ctrl5, 1); + + switch(fifo_ctrl5.odr_fifo) { + case LSM6DS3TR_C_FIFO_DISABLE: + *val = LSM6DS3TR_C_FIFO_DISABLE; + break; + + case LSM6DS3TR_C_FIFO_12Hz5: + *val = LSM6DS3TR_C_FIFO_12Hz5; + break; + + case LSM6DS3TR_C_FIFO_26Hz: + *val = LSM6DS3TR_C_FIFO_26Hz; + break; + + case LSM6DS3TR_C_FIFO_52Hz: + *val = LSM6DS3TR_C_FIFO_52Hz; + break; + + case LSM6DS3TR_C_FIFO_104Hz: + *val = LSM6DS3TR_C_FIFO_104Hz; + break; + + case LSM6DS3TR_C_FIFO_208Hz: + *val = LSM6DS3TR_C_FIFO_208Hz; + break; + + case LSM6DS3TR_C_FIFO_416Hz: + *val = LSM6DS3TR_C_FIFO_416Hz; + break; + + case LSM6DS3TR_C_FIFO_833Hz: + *val = LSM6DS3TR_C_FIFO_833Hz; + break; + + case LSM6DS3TR_C_FIFO_1k66Hz: + *val = LSM6DS3TR_C_FIFO_1k66Hz; + break; + + case LSM6DS3TR_C_FIFO_3k33Hz: + *val = LSM6DS3TR_C_FIFO_3k33Hz; + break; + + case LSM6DS3TR_C_FIFO_6k66Hz: + *val = LSM6DS3TR_C_FIFO_6k66Hz; + break; + + default: + *val = LSM6DS3TR_C_FIFO_RATE_ND; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_DEN_functionality + * @brief This section groups all the functions concerning DEN + * functionality. + * @{ + * + */ + +/** + * @brief DEN active level configuration.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_lh in reg CTRL5_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_polarity_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_lh_t val) { + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); + + if(ret == 0) { + ctrl5_c.den_lh = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); + } + + return ret; +} + +/** + * @brief DEN active level configuration.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of den_lh in reg CTRL5_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_polarity_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_lh_t* val) { + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); + + switch(ctrl5_c.den_lh) { + case LSM6DS3TR_C_DEN_ACT_LOW: + *val = LSM6DS3TR_C_DEN_ACT_LOW; + break; + + case LSM6DS3TR_C_DEN_ACT_HIGH: + *val = LSM6DS3TR_C_DEN_ACT_HIGH; + break; + + default: + *val = LSM6DS3TR_C_DEN_POL_ND; + break; + } + + return ret; +} + +/** + * @brief DEN functionality marking mode[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_mode in reg CTRL6_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_mode_t val) { + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); + + if(ret == 0) { + ctrl6_c.den_mode = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); + } + + return ret; +} + +/** + * @brief DEN functionality marking mode[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_mode in reg CTRL6_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_mode_t* val) { + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); + + switch(ctrl6_c.den_mode) { + case LSM6DS3TR_C_DEN_DISABLE: + *val = LSM6DS3TR_C_DEN_DISABLE; + break; + + case LSM6DS3TR_C_LEVEL_LETCHED: + *val = LSM6DS3TR_C_LEVEL_LETCHED; + break; + + case LSM6DS3TR_C_LEVEL_TRIGGER: + *val = LSM6DS3TR_C_LEVEL_TRIGGER; + break; + + case LSM6DS3TR_C_EDGE_TRIGGER: + *val = LSM6DS3TR_C_EDGE_TRIGGER; + break; + + default: + *val = LSM6DS3TR_C_DEN_MODE_ND; + break; + } + + return ret; +} + +/** + * @brief Extend DEN functionality to accelerometer sensor.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_xl_g in reg CTRL9_XL + * and den_xl_en in CTRL4_C. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_enable_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_xl_en_t val) { + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); + + if(ret == 0) { + ctrl9_xl.den_xl_g = (uint8_t)val & 0x01U; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + + if(ret == 0) { + ctrl4_c.den_xl_en = (uint8_t)val & 0x02U; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + } + } + } + + return ret; +} + +/** + * @brief Extend DEN functionality to accelerometer sensor. [get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of den_xl_g in reg CTRL9_XL + * and den_xl_en in CTRL4_C. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_enable_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_xl_en_t* val) { + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); + + switch((ctrl4_c.den_xl_en << 1) + ctrl9_xl.den_xl_g) { + case LSM6DS3TR_C_STAMP_IN_GY_DATA: + *val = LSM6DS3TR_C_STAMP_IN_GY_DATA; + break; + + case LSM6DS3TR_C_STAMP_IN_XL_DATA: + *val = LSM6DS3TR_C_STAMP_IN_XL_DATA; + break; + + case LSM6DS3TR_C_STAMP_IN_GY_XL_DATA: + *val = LSM6DS3TR_C_STAMP_IN_GY_XL_DATA; + break; + + default: + *val = LSM6DS3TR_C_DEN_STAMP_ND; + break; + } + } + + return ret; +} + +/** + * @brief DEN value stored in LSB of Z-axis.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_z in reg CTRL9_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_mark_axis_z_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); + + if(ret == 0) { + ctrl9_xl.den_z = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); + } + + return ret; +} + +/** + * @brief DEN value stored in LSB of Z-axis.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_z in reg CTRL9_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_mark_axis_z_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); + *val = ctrl9_xl.den_z; + + return ret; +} + +/** + * @brief DEN value stored in LSB of Y-axis.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_y in reg CTRL9_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_mark_axis_y_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); + + if(ret == 0) { + ctrl9_xl.den_y = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); + } + + return ret; +} + +/** + * @brief DEN value stored in LSB of Y-axis.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_y in reg CTRL9_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_mark_axis_y_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); + *val = ctrl9_xl.den_y; + + return ret; +} + +/** + * @brief DEN value stored in LSB of X-axis.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_x in reg CTRL9_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_mark_axis_x_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); + + if(ret == 0) { + ctrl9_xl.den_x = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); + } + + return ret; +} + +/** + * @brief DEN value stored in LSB of X-axis.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_x in reg CTRL9_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_mark_axis_x_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); + *val = ctrl9_xl.den_x; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_Pedometer + * @brief This section groups all the functions that manage pedometer. + * @{ + * + */ + +/** + * @brief Reset pedometer step counter.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pedo_rst_step in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_step_reset_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + + if(ret == 0) { + ctrl10_c.pedo_rst_step = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + } + + return ret; +} + +/** + * @brief Reset pedometer step counter.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pedo_rst_step in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_step_reset_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + *val = ctrl10_c.pedo_rst_step; + + return ret; +} + +/** + * @brief Enable pedometer algorithm.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pedo_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_sens_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + + if(ret == 0) { + ctrl10_c.pedo_en = val; + + if(val != 0x00U) { + ctrl10_c.func_en = val; + } + + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + } + + return ret; +} + +/** + * @brief pedo_sens: Enable pedometer algorithm.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pedo_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_sens_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + *val = ctrl10_c.pedo_en; + + return ret; +} + +/** + * @brief Minimum threshold to detect a peak. Default is 10h.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of ths_min in reg + * CONFIG_PEDO_THS_MIN + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_threshold_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_config_pedo_ths_min_t config_pedo_ths_min; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, (uint8_t*)&config_pedo_ths_min, 1); + + if(ret == 0) { + config_pedo_ths_min.ths_min = val; + ret = lsm6ds3tr_c_write_reg( + ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, (uint8_t*)&config_pedo_ths_min, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Minimum threshold to detect a peak. Default is 10h.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of ths_min in reg CONFIG_PEDO_THS_MIN + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_threshold_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_config_pedo_ths_min_t config_pedo_ths_min; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, (uint8_t*)&config_pedo_ths_min, 1); + + if(ret == 0) { + *val = config_pedo_ths_min.ths_min; + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief pedo_full_scale: Pedometer data range.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pedo_fs in + * reg CONFIG_PEDO_THS_MIN + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_full_scale_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_pedo_fs_t val) { + lsm6ds3tr_c_config_pedo_ths_min_t config_pedo_ths_min; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, (uint8_t*)&config_pedo_ths_min, 1); + + if(ret == 0) { + config_pedo_ths_min.pedo_fs = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg( + ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, (uint8_t*)&config_pedo_ths_min, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Pedometer data range.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of pedo_fs in + * reg CONFIG_PEDO_THS_MIN + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_full_scale_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_pedo_fs_t* val) { + lsm6ds3tr_c_config_pedo_ths_min_t config_pedo_ths_min; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, (uint8_t*)&config_pedo_ths_min, 1); + + if(ret == 0) { + switch(config_pedo_ths_min.pedo_fs) { + case LSM6DS3TR_C_PEDO_AT_2g: + *val = LSM6DS3TR_C_PEDO_AT_2g; + break; + + case LSM6DS3TR_C_PEDO_AT_4g: + *val = LSM6DS3TR_C_PEDO_AT_4g; + break; + + default: + *val = LSM6DS3TR_C_PEDO_FS_ND; + break; + } + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Pedometer debounce configuration register (r/w).[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of deb_step in reg PEDO_DEB_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_debounce_steps_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_pedo_deb_reg_t pedo_deb_reg; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, (uint8_t*)&pedo_deb_reg, 1); + + if(ret == 0) { + pedo_deb_reg.deb_step = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, (uint8_t*)&pedo_deb_reg, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Pedometer debounce configuration register (r/w).[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of deb_step in reg PEDO_DEB_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_debounce_steps_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_pedo_deb_reg_t pedo_deb_reg; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, (uint8_t*)&pedo_deb_reg, 1); + + if(ret == 0) { + *val = pedo_deb_reg.deb_step; + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Debounce time. If the time between two consecutive steps is + * greater than DEB_TIME*80ms, the debouncer is reactivated. + * Default value: 01101[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of deb_time in reg PEDO_DEB_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_timeout_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_pedo_deb_reg_t pedo_deb_reg; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, (uint8_t*)&pedo_deb_reg, 1); + + if(ret == 0) { + pedo_deb_reg.deb_time = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, (uint8_t*)&pedo_deb_reg, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Debounce time. If the time between two consecutive steps is + * greater than DEB_TIME*80ms, the debouncer is reactivated. + * Default value: 01101[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of deb_time in reg PEDO_DEB_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_timeout_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_pedo_deb_reg_t pedo_deb_reg; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, (uint8_t*)&pedo_deb_reg, 1); + + if(ret == 0) { + *val = pedo_deb_reg.deb_time; + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Time period register for step detection on delta time (r/w).[set] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that contains data to write + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_steps_period_set(stmdev_ctx_t* ctx, uint8_t* buff) { + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_STEP_COUNT_DELTA, buff, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Time period register for step detection on delta time (r/w).[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_steps_period_get(stmdev_ctx_t* ctx, uint8_t* buff) { + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STEP_COUNT_DELTA, buff, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_significant_motion + * @brief This section groups all the functions that manage the + * significant motion detection. + * @{ + * + */ + +/** + * @brief Enable significant motion detection function.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sign_motion_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_motion_sens_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + + if(ret == 0) { + ctrl10_c.sign_motion_en = val; + + if(val != 0x00U) { + ctrl10_c.func_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + } + } + + return ret; +} + +/** + * @brief Enable significant motion detection function.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sign_motion_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_motion_sens_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + *val = ctrl10_c.sign_motion_en; + + return ret; +} + +/** + * @brief Significant motion threshold.[set] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that store significant motion threshold. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_motion_threshold_set(stmdev_ctx_t* ctx, uint8_t* buff) { + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SM_THS, buff, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Significant motion threshold.[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that store significant motion threshold. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_motion_threshold_get(stmdev_ctx_t* ctx, uint8_t* buff) { + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SM_THS, buff, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_tilt_detection + * @brief This section groups all the functions that manage the tilt + * event detection. + * @{ + * + */ + +/** + * @brief Enable tilt calculation.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tilt_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tilt_sens_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + + if(ret == 0) { + ctrl10_c.tilt_en = val; + + if(val != 0x00U) { + ctrl10_c.func_en = val; + } + + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + } + + return ret; +} + +/** + * @brief Enable tilt calculation.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tilt_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tilt_sens_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + *val = ctrl10_c.tilt_en; + + return ret; +} + +/** + * @brief Enable tilt calculation.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tilt_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_wrist_tilt_sens_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + + if(ret == 0) { + ctrl10_c.wrist_tilt_en = val; + + if(val != 0x00U) { + ctrl10_c.func_en = val; + } + + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + } + + return ret; +} + +/** + * @brief Enable tilt calculation.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tilt_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_wrist_tilt_sens_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + *val = ctrl10_c.wrist_tilt_en; + + return ret; +} + +/** + * @brief Absolute Wrist Tilt latency register (r/w). + * Absolute wrist tilt latency parameters. + * 1 LSB = 40 ms. Default value: 0Fh (600 ms).[set] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that contains data to write + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tilt_latency_set(stmdev_ctx_t* ctx, uint8_t* buff) { + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); + + if(ret == 0) { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_LAT, buff, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Absolute Wrist Tilt latency register (r/w). + * Absolute wrist tilt latency parameters. + * 1 LSB = 40 ms. Default value: 0Fh (600 ms).[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tilt_latency_get(stmdev_ctx_t* ctx, uint8_t* buff) { + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_LAT, buff, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Absolute Wrist Tilt threshold register(r/w). + * Absolute wrist tilt threshold parameters. + * 1 LSB = 15.625 mg.Default value: 20h (500 mg).[set] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that contains data to write + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tilt_threshold_set(stmdev_ctx_t* ctx, uint8_t* buff) { + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); + + if(ret == 0) { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_THS, buff, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Absolute Wrist Tilt threshold register(r/w). + * Absolute wrist tilt threshold parameters. + * 1 LSB = 15.625 mg.Default value: 20h (500 mg).[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tilt_threshold_get(stmdev_ctx_t* ctx, uint8_t* buff) { + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_THS, buff, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Absolute Wrist Tilt mask register (r/w).[set] + * + * @param ctx Read / write interface definitions + * @param val Registers A_WRIST_TILT_MASK + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tilt_src_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_a_wrist_tilt_mask_t* val) { + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_MASK, (uint8_t*)val, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Absolute Wrist Tilt mask register (r/w).[get] + * + * @param ctx Read / write interface definitions + * @param val Registers A_WRIST_TILT_MASK + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tilt_src_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_a_wrist_tilt_mask_t* val) { + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_MASK, (uint8_t*)val, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_ magnetometer_sensor + * @brief This section groups all the functions that manage additional + * magnetometer sensor. + * @{ + * + */ + +/** + * @brief Enable soft-iron correction algorithm for magnetometer.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of soft_en in reg CTRL9_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_soft_iron_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); + + if(ret == 0) { + ctrl9_xl.soft_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); + } + + return ret; +} + +/** + * @brief Enable soft-iron correction algorithm for magnetometer.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of soft_en in reg CTRL9_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_soft_iron_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); + *val = ctrl9_xl.soft_en; + + return ret; +} + +/** + * @brief Enable hard-iron correction algorithm for magnetometer.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of iron_en in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_hard_iron_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_master_config_t master_config; + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + + if(ret == 0) { + master_config.iron_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + + if(ret == 0) { + if(val != 0x00U) { + ctrl10_c.func_en = val; + } + + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + } + } + } + + return ret; +} + +/** + * @brief Enable hard-iron correction algorithm for magnetometer.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of iron_en in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_hard_iron_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + *val = master_config.iron_en; + + return ret; +} + +/** + * @brief Soft iron 3x3 matrix. Value are expressed in sign-module format. + * (Es. SVVVVVVVb where S is the sign 0/+1/- and V is the value).[set] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that contains data to write + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_soft_iron_mat_set(stmdev_ctx_t* ctx, uint8_t* buff) { + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MAG_SI_XX, buff, 9); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Soft iron 3x3 matrix. Value are expressed in sign-module format. + * (Es. SVVVVVVVb where S is the sign 0/+1/- and V is the value).[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_soft_iron_mat_get(stmdev_ctx_t* ctx, uint8_t* buff) { + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MAG_SI_XX, buff, 9); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Offset for hard-iron compensation register (r/w). The value is + * expressed as a 16-bit word in two’s complement.[set] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that contains data to write + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_offset_set(stmdev_ctx_t* ctx, int16_t* val) { + uint8_t buff[6]; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + buff[1] = (uint8_t)((uint16_t)val[0] / 256U); + buff[0] = (uint8_t)((uint16_t)val[0] - (buff[1] * 256U)); + buff[3] = (uint8_t)((uint16_t)val[1] / 256U); + buff[2] = (uint8_t)((uint16_t)val[1] - (buff[3] * 256U)); + buff[5] = (uint8_t)((uint16_t)val[2] / 256U); + buff[4] = (uint8_t)((uint16_t)val[2] - (buff[5] * 256U)); + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MAG_OFFX_L, buff, 6); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Offset for hard-iron compensation register(r/w). + * The value is expressed as a 16-bit word in two’s complement.[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_offset_get(stmdev_ctx_t* ctx, int16_t* val) { + uint8_t buff[6]; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MAG_OFFX_L, buff, 6); + + if(ret == 0) { + val[0] = (int16_t)buff[1]; + val[0] = (val[0] * 256) + (int16_t)buff[0]; + val[1] = (int16_t)buff[3]; + val[1] = (val[1] * 256) + (int16_t)buff[2]; + val[2] = (int16_t)buff[5]; + val[2] = (val[2] * 256) + (int16_t)buff[4]; + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_Sensor_hub + * @brief This section groups all the functions that manage the sensor + * hub functionality. + * @{ + * + */ + +/** + * @brief Enable function.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values func_en + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_func_en_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + + if(ret == 0) { + ctrl10_c.func_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); + } + + return ret; +} + +/** + * @brief Sensor synchronization time frame with the step of 500 ms and + * full range of 5s. Unsigned 8-bit.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tph in reg SENSOR_SYNC_TIME_FRAME + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_sync_sens_frame_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_sensor_sync_time_frame_t sensor_sync_time_frame; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_SENSOR_SYNC_TIME_FRAME, (uint8_t*)&sensor_sync_time_frame, 1); + + if(ret == 0) { + sensor_sync_time_frame.tph = val; + ret = lsm6ds3tr_c_write_reg( + ctx, LSM6DS3TR_C_SENSOR_SYNC_TIME_FRAME, (uint8_t*)&sensor_sync_time_frame, 1); + } + + return ret; +} + +/** + * @brief Sensor synchronization time frame with the step of 500 ms and + * full range of 5s. Unsigned 8-bit.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tph in reg SENSOR_SYNC_TIME_FRAME + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_sync_sens_frame_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_sensor_sync_time_frame_t sensor_sync_time_frame; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_SENSOR_SYNC_TIME_FRAME, (uint8_t*)&sensor_sync_time_frame, 1); + *val = sensor_sync_time_frame.tph; + + return ret; +} + +/** + * @brief Resolution ratio of error code for sensor synchronization.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of rr in reg SENSOR_SYNC_RES_RATIO + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_sync_sens_ratio_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_rr_t val) { + lsm6ds3tr_c_sensor_sync_res_ratio_t sensor_sync_res_ratio; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_SENSOR_SYNC_RES_RATIO, (uint8_t*)&sensor_sync_res_ratio, 1); + + if(ret == 0) { + sensor_sync_res_ratio.rr = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg( + ctx, LSM6DS3TR_C_SENSOR_SYNC_RES_RATIO, (uint8_t*)&sensor_sync_res_ratio, 1); + } + + return ret; +} + +/** + * @brief Resolution ratio of error code for sensor synchronization.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of rr in reg SENSOR_SYNC_RES_RATIO + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_sync_sens_ratio_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_rr_t* val) { + lsm6ds3tr_c_sensor_sync_res_ratio_t sensor_sync_res_ratio; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_SENSOR_SYNC_RES_RATIO, (uint8_t*)&sensor_sync_res_ratio, 1); + + switch(sensor_sync_res_ratio.rr) { + case LSM6DS3TR_C_RES_RATIO_2_11: + *val = LSM6DS3TR_C_RES_RATIO_2_11; + break; + + case LSM6DS3TR_C_RES_RATIO_2_12: + *val = LSM6DS3TR_C_RES_RATIO_2_12; + break; + + case LSM6DS3TR_C_RES_RATIO_2_13: + *val = LSM6DS3TR_C_RES_RATIO_2_13; + break; + + case LSM6DS3TR_C_RES_RATIO_2_14: + *val = LSM6DS3TR_C_RES_RATIO_2_14; + break; + + default: + *val = LSM6DS3TR_C_RES_RATIO_ND; + break; + } + + return ret; +} + +/** + * @brief Sensor hub I2C master enable.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of master_on in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_master_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + + if(ret == 0) { + master_config.master_on = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + } + + return ret; +} + +/** + * @brief Sensor hub I2C master enable.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of master_on in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_master_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + *val = master_config.master_on; + + return ret; +} + +/** + * @brief I2C interface pass-through.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pass_through_mode in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_pass_through_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + + if(ret == 0) { + master_config.pass_through_mode = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + } + + return ret; +} + +/** + * @brief I2C interface pass-through.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pass_through_mode in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_pass_through_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + *val = master_config.pass_through_mode; + + return ret; +} + +/** + * @brief Master I2C pull-up enable/disable.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pull_up_en in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_pin_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_pull_up_en_t val) { + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + + if(ret == 0) { + master_config.pull_up_en = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + } + + return ret; +} + +/** + * @brief Master I2C pull-up enable/disable.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of pull_up_en in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_pin_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_pull_up_en_t* val) { + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + + switch(master_config.pull_up_en) { + case LSM6DS3TR_C_EXT_PULL_UP: + *val = LSM6DS3TR_C_EXT_PULL_UP; + break; + + case LSM6DS3TR_C_INTERNAL_PULL_UP: + *val = LSM6DS3TR_C_INTERNAL_PULL_UP; + break; + + default: + *val = LSM6DS3TR_C_SH_PIN_MODE; + break; + } + + return ret; +} + +/** + * @brief Sensor hub trigger signal selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of start_config in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_syncro_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_start_config_t val) { + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + + if(ret == 0) { + master_config.start_config = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + } + + return ret; +} + +/** + * @brief Sensor hub trigger signal selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of start_config in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_syncro_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_start_config_t* val) { + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + + switch(master_config.start_config) { + case LSM6DS3TR_C_XL_GY_DRDY: + *val = LSM6DS3TR_C_XL_GY_DRDY; + break; + + case LSM6DS3TR_C_EXT_ON_INT2_PIN: + *val = LSM6DS3TR_C_EXT_ON_INT2_PIN; + break; + + default: + *val = LSM6DS3TR_C_SH_SYNCRO_ND; + break; + } + + return ret; +} + +/** + * @brief Manage the Master DRDY signal on INT1 pad.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of drdy_on_int1 in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_drdy_on_int1_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + + if(ret == 0) { + master_config.drdy_on_int1 = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + } + + return ret; +} + +/** + * @brief Manage the Master DRDY signal on INT1 pad.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of drdy_on_int1 in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_drdy_on_int1_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); + *val = master_config.drdy_on_int1; + + return ret; +} + +/** + * @brief Sensor hub output registers.[get] + * + * @param ctx Read / write interface definitions + * @param val Structure of registers from SENSORHUB1_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_read_data_raw_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_emb_sh_read_t* val) { + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SENSORHUB1_REG, (uint8_t*)&(val->sh_byte_1), 12); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_SENSORHUB13_REG, (uint8_t*)&(val->sh_byte_13), 6); + } + + return ret; +} + +/** + * @brief Master command code used for stamping for sensor sync.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of master_cmd_code in + * reg MASTER_CMD_CODE + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_cmd_sens_sync_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_master_cmd_code_t master_cmd_code; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CMD_CODE, (uint8_t*)&master_cmd_code, 1); + + if(ret == 0) { + master_cmd_code.master_cmd_code = val; + ret = + lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CMD_CODE, (uint8_t*)&master_cmd_code, 1); + } + + return ret; +} + +/** + * @brief Master command code used for stamping for sensor sync.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of master_cmd_code in + * reg MASTER_CMD_CODE + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_cmd_sens_sync_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_master_cmd_code_t master_cmd_code; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CMD_CODE, (uint8_t*)&master_cmd_code, 1); + *val = master_cmd_code.master_cmd_code; + + return ret; +} + +/** + * @brief Error code used for sensor synchronization.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of error_code in + * reg SENS_SYNC_SPI_ERROR_CODE. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_spi_sync_error_set(stmdev_ctx_t* ctx, uint8_t val) { + lsm6ds3tr_c_sens_sync_spi_error_code_t sens_sync_spi_error_code; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_SENS_SYNC_SPI_ERROR_CODE, (uint8_t*)&sens_sync_spi_error_code, 1); + + if(ret == 0) { + sens_sync_spi_error_code.error_code = val; + ret = lsm6ds3tr_c_write_reg( + ctx, LSM6DS3TR_C_SENS_SYNC_SPI_ERROR_CODE, (uint8_t*)&sens_sync_spi_error_code, 1); + } + + return ret; +} + +/** + * @brief Error code used for sensor synchronization.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of error_code in + * reg SENS_SYNC_SPI_ERROR_CODE. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_spi_sync_error_get(stmdev_ctx_t* ctx, uint8_t* val) { + lsm6ds3tr_c_sens_sync_spi_error_code_t sens_sync_spi_error_code; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_SENS_SYNC_SPI_ERROR_CODE, (uint8_t*)&sens_sync_spi_error_code, 1); + *val = sens_sync_spi_error_code.error_code; + + return ret; +} + +/** + * @brief Number of external sensors to be read by the sensor hub.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of aux_sens_on in reg SLAVE0_CONFIG. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_num_of_dev_connected_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_aux_sens_on_t val) { + lsm6ds3tr_c_slave0_config_t slave0_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, (uint8_t*)&slave0_config, 1); + + if(ret == 0) { + slave0_config.aux_sens_on = (uint8_t)val; + ret = + lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, (uint8_t*)&slave0_config, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Number of external sensors to be read by the sensor hub.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of aux_sens_on in reg SLAVE0_CONFIG. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t + lsm6ds3tr_c_sh_num_of_dev_connected_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_aux_sens_on_t* val) { + lsm6ds3tr_c_slave0_config_t slave0_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, (uint8_t*)&slave0_config, 1); + + if(ret == 0) { + switch(slave0_config.aux_sens_on) { + case LSM6DS3TR_C_SLV_0: + *val = LSM6DS3TR_C_SLV_0; + break; + + case LSM6DS3TR_C_SLV_0_1: + *val = LSM6DS3TR_C_SLV_0_1; + break; + + case LSM6DS3TR_C_SLV_0_1_2: + *val = LSM6DS3TR_C_SLV_0_1_2; + break; + + case LSM6DS3TR_C_SLV_0_1_2_3: + *val = LSM6DS3TR_C_SLV_0_1_2_3; + break; + + default: + *val = LSM6DS3TR_C_SLV_EN_ND; + break; + } + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Configure slave 0 for perform a write.[set] + * + * @param ctx Read / write interface definitions + * @param val Structure that contain: + * - uint8_t slv_add; 8 bit i2c device address + * - uint8_t slv_subadd; 8 bit register device address + * - uint8_t slv_data; 8 bit data to write + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_cfg_write(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_write_t* val) { + lsm6ds3tr_c_slv0_add_t slv0_add; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + slv0_add.slave0_add = val->slv0_add; + slv0_add.rw_0 = 0; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV0_ADD, (uint8_t*)&slv0_add, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV0_SUBADD, &(val->slv0_subadd), 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_write_reg( + ctx, LSM6DS3TR_C_DATAWRITE_SRC_MODE_SUB_SLV0, &(val->slv0_data), 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + } + + return ret; +} + +/** + * @brief Configure slave 0 for perform a read.[get] + * + * @param ctx Read / write interface definitions + * @param val Structure that contain: + * - uint8_t slv_add; 8 bit i2c device address + * - uint8_t slv_subadd; 8 bit register device address + * - uint8_t slv_len; num of bit to read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slv0_cfg_read(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_read_t* val) { + lsm6ds3tr_c_slave0_config_t slave0_config; + lsm6ds3tr_c_slv0_add_t slv0_add; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + slv0_add.slave0_add = val->slv_add; + slv0_add.rw_0 = 1; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV0_ADD, (uint8_t*)&slv0_add, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV0_SUBADD, &(val->slv_subadd), 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_SLAVE0_CONFIG, (uint8_t*)&slave0_config, 1); + slave0_config.slave0_numop = val->slv_len; + + if(ret == 0) { + ret = lsm6ds3tr_c_write_reg( + ctx, LSM6DS3TR_C_SLAVE0_CONFIG, (uint8_t*)&slave0_config, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + } + } + + return ret; +} + +/** + * @brief Configure slave 1 for perform a read.[get] + * + * @param ctx Read / write interface definitions + * @param val Structure that contain: + * - uint8_t slv_add; 8 bit i2c device address + * - uint8_t slv_subadd; 8 bit register device address + * - uint8_t slv_len; num of bit to read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slv1_cfg_read(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_read_t* val) { + lsm6ds3tr_c_slave1_config_t slave1_config; + lsm6ds3tr_c_slv1_add_t slv1_add; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + slv1_add.slave1_add = val->slv_add; + slv1_add.r_1 = 1; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV1_ADD, (uint8_t*)&slv1_add, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV1_SUBADD, &(val->slv_subadd), 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_SLAVE1_CONFIG, (uint8_t*)&slave1_config, 1); + slave1_config.slave1_numop = val->slv_len; + + if(ret == 0) { + ret = lsm6ds3tr_c_write_reg( + ctx, LSM6DS3TR_C_SLAVE1_CONFIG, (uint8_t*)&slave1_config, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + } + } + + return ret; +} + +/** + * @brief Configure slave 2 for perform a read.[get] + * + * @param ctx Read / write interface definitions + * @param val Structure that contain: + * - uint8_t slv_add; 8 bit i2c device address + * - uint8_t slv_subadd; 8 bit register device address + * - uint8_t slv_len; num of bit to read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slv2_cfg_read(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_read_t* val) { + lsm6ds3tr_c_slv2_add_t slv2_add; + lsm6ds3tr_c_slave2_config_t slave2_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + slv2_add.slave2_add = val->slv_add; + slv2_add.r_2 = 1; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV2_ADD, (uint8_t*)&slv2_add, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV2_SUBADD, &(val->slv_subadd), 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_SLAVE2_CONFIG, (uint8_t*)&slave2_config, 1); + + if(ret == 0) { + slave2_config.slave2_numop = val->slv_len; + ret = lsm6ds3tr_c_write_reg( + ctx, LSM6DS3TR_C_SLAVE2_CONFIG, (uint8_t*)&slave2_config, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + } + } + + return ret; +} + +/** + * @brief Configure slave 3 for perform a read.[get] + * + * @param ctx Read / write interface definitions + * @param val Structure that contain: + * - uint8_t slv_add; 8 bit i2c device address + * - uint8_t slv_subadd; 8 bit register device address + * - uint8_t slv_len; num of bit to read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slv3_cfg_read(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_read_t* val) { + lsm6ds3tr_c_slave3_config_t slave3_config; + lsm6ds3tr_c_slv3_add_t slv3_add; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + slv3_add.slave3_add = val->slv_add; + slv3_add.r_3 = 1; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV3_ADD, (uint8_t*)&slv3_add, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_write_reg( + ctx, LSM6DS3TR_C_SLV3_SUBADD, (uint8_t*)&(val->slv_subadd), 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg( + ctx, LSM6DS3TR_C_SLAVE3_CONFIG, (uint8_t*)&slave3_config, 1); + + if(ret == 0) { + slave3_config.slave3_numop = val->slv_len; + ret = lsm6ds3tr_c_write_reg( + ctx, LSM6DS3TR_C_SLAVE3_CONFIG, (uint8_t*)&slave3_config, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + } + } + + return ret; +} + +/** + * @brief Decimation of read operation on Slave 0 starting from the + * sensor hub trigger.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of slave0_rate in reg SLAVE0_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slave_0_dec_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave0_rate_t val) { + lsm6ds3tr_c_slave0_config_t slave0_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, (uint8_t*)&slave0_config, 1); + + if(ret == 0) { + slave0_config.slave0_rate = (uint8_t)val; + ret = + lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, (uint8_t*)&slave0_config, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Decimation of read operation on Slave 0 starting from the + * sensor hub trigger.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of slave0_rate in reg SLAVE0_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slave_0_dec_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave0_rate_t* val) { + lsm6ds3tr_c_slave0_config_t slave0_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, (uint8_t*)&slave0_config, 1); + + if(ret == 0) { + switch(slave0_config.slave0_rate) { + case LSM6DS3TR_C_SL0_NO_DEC: + *val = LSM6DS3TR_C_SL0_NO_DEC; + break; + + case LSM6DS3TR_C_SL0_DEC_2: + *val = LSM6DS3TR_C_SL0_DEC_2; + break; + + case LSM6DS3TR_C_SL0_DEC_4: + *val = LSM6DS3TR_C_SL0_DEC_4; + break; + + case LSM6DS3TR_C_SL0_DEC_8: + *val = LSM6DS3TR_C_SL0_DEC_8; + break; + + default: + *val = LSM6DS3TR_C_SL0_DEC_ND; + break; + } + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Slave 0 write operation is performed only at the first sensor + * hub cycle. + * This is effective if the Aux_sens_on[1:0] field in + * SLAVE0_CONFIG(04h) is set to a value other than 00.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of write_once in reg SLAVE1_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_write_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_write_once_t val) { + lsm6ds3tr_c_slave1_config_t slave1_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, (uint8_t*)&slave1_config, 1); + slave1_config.write_once = (uint8_t)val; + + if(ret == 0) { + ret = + lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, (uint8_t*)&slave1_config, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Slave 0 write operation is performed only at the first sensor + * hub cycle. + * This is effective if the Aux_sens_on[1:0] field in + * SLAVE0_CONFIG(04h) is set to a value other than 00.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of write_once in reg SLAVE1_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_write_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_write_once_t* val) { + lsm6ds3tr_c_slave1_config_t slave1_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, (uint8_t*)&slave1_config, 1); + + if(ret == 0) { + switch(slave1_config.write_once) { + case LSM6DS3TR_C_EACH_SH_CYCLE: + *val = LSM6DS3TR_C_EACH_SH_CYCLE; + break; + + case LSM6DS3TR_C_ONLY_FIRST_CYCLE: + *val = LSM6DS3TR_C_ONLY_FIRST_CYCLE; + break; + + default: + *val = LSM6DS3TR_C_SH_WR_MODE_ND; + break; + } + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Decimation of read operation on Slave 1 starting from the + * sensor hub trigger.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of slave1_rate in reg SLAVE1_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slave_1_dec_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave1_rate_t val) { + lsm6ds3tr_c_slave1_config_t slave1_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, (uint8_t*)&slave1_config, 1); + + if(ret == 0) { + slave1_config.slave1_rate = (uint8_t)val; + ret = + lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, (uint8_t*)&slave1_config, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Decimation of read operation on Slave 1 starting from the + * sensor hub trigger.[get] + * + * @param ctx Read / write interface definitions reg SLAVE1_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slave_1_dec_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave1_rate_t* val) { + lsm6ds3tr_c_slave1_config_t slave1_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, (uint8_t*)&slave1_config, 1); + + if(ret == 0) { + switch(slave1_config.slave1_rate) { + case LSM6DS3TR_C_SL1_NO_DEC: + *val = LSM6DS3TR_C_SL1_NO_DEC; + break; + + case LSM6DS3TR_C_SL1_DEC_2: + *val = LSM6DS3TR_C_SL1_DEC_2; + break; + + case LSM6DS3TR_C_SL1_DEC_4: + *val = LSM6DS3TR_C_SL1_DEC_4; + break; + + case LSM6DS3TR_C_SL1_DEC_8: + *val = LSM6DS3TR_C_SL1_DEC_8; + break; + + default: + *val = LSM6DS3TR_C_SL1_DEC_ND; + break; + } + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Decimation of read operation on Slave 2 starting from the + * sensor hub trigger.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of slave2_rate in reg SLAVE2_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slave_2_dec_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave2_rate_t val) { + lsm6ds3tr_c_slave2_config_t slave2_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE2_CONFIG, (uint8_t*)&slave2_config, 1); + + if(ret == 0) { + slave2_config.slave2_rate = (uint8_t)val; + ret = + lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE2_CONFIG, (uint8_t*)&slave2_config, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Decimation of read operation on Slave 2 starting from the + * sensor hub trigger.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of slave2_rate in reg SLAVE2_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slave_2_dec_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave2_rate_t* val) { + lsm6ds3tr_c_slave2_config_t slave2_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE2_CONFIG, (uint8_t*)&slave2_config, 1); + + if(ret == 0) { + switch(slave2_config.slave2_rate) { + case LSM6DS3TR_C_SL2_NO_DEC: + *val = LSM6DS3TR_C_SL2_NO_DEC; + break; + + case LSM6DS3TR_C_SL2_DEC_2: + *val = LSM6DS3TR_C_SL2_DEC_2; + break; + + case LSM6DS3TR_C_SL2_DEC_4: + *val = LSM6DS3TR_C_SL2_DEC_4; + break; + + case LSM6DS3TR_C_SL2_DEC_8: + *val = LSM6DS3TR_C_SL2_DEC_8; + break; + + default: + *val = LSM6DS3TR_C_SL2_DEC_ND; + break; + } + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Decimation of read operation on Slave 3 starting from the + * sensor hub trigger.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of slave3_rate in reg SLAVE3_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slave_3_dec_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave3_rate_t val) { + lsm6ds3tr_c_slave3_config_t slave3_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE3_CONFIG, (uint8_t*)&slave3_config, 1); + slave3_config.slave3_rate = (uint8_t)val; + + if(ret == 0) { + ret = + lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE3_CONFIG, (uint8_t*)&slave3_config, 1); + + if(ret == 0) { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Decimation of read operation on Slave 3 starting from the + * sensor hub trigger.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of slave3_rate in reg SLAVE3_CONFIG. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slave_3_dec_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave3_rate_t* val) { + lsm6ds3tr_c_slave3_config_t slave3_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if(ret == 0) { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE3_CONFIG, (uint8_t*)&slave3_config, 1); + + if(ret == 0) { + switch(slave3_config.slave3_rate) { + case LSM6DS3TR_C_SL3_NO_DEC: + *val = LSM6DS3TR_C_SL3_NO_DEC; + break; + + case LSM6DS3TR_C_SL3_DEC_2: + *val = LSM6DS3TR_C_SL3_DEC_2; + break; + + case LSM6DS3TR_C_SL3_DEC_4: + *val = LSM6DS3TR_C_SL3_DEC_4; + break; + + case LSM6DS3TR_C_SL3_DEC_8: + *val = LSM6DS3TR_C_SL3_DEC_8; + break; + + default: + *val = LSM6DS3TR_C_SL3_DEC_ND; + break; + } + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @} + * + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/lsm6ds3tr_c_reg.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/lsm6ds3tr_c_reg.h new file mode 100644 index 000000000..8cb592c0d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/imu/lsm6ds3tr_c_reg.h @@ -0,0 +1,2448 @@ +/** + ****************************************************************************** + * @file lsm6ds3tr_c_reg.h + * @author Sensors Software Solution Team + * @brief This file contains all the functions prototypes for the + * lsm6ds3tr_c_reg.c driver. + ****************************************************************************** + * @attention + * + *

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

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef LSM6DS3TR_C_DRIVER_H +#define LSM6DS3TR_C_DRIVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include + +/** @addtogroup LSM6DS3TR_C + * @{ + * + */ + +/** @defgroup Endianness definitions + * @{ + * + */ + +#ifndef DRV_BYTE_ORDER +#ifndef __BYTE_ORDER__ + +#define DRV_LITTLE_ENDIAN 1234 +#define DRV_BIG_ENDIAN 4321 + +/** if _BYTE_ORDER is not defined, choose the endianness of your architecture + * by uncommenting the define which fits your platform endianness + */ +//#define DRV_BYTE_ORDER DRV_BIG_ENDIAN +#define DRV_BYTE_ORDER DRV_LITTLE_ENDIAN + +#else /* defined __BYTE_ORDER__ */ + +#define DRV_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ +#define DRV_BIG_ENDIAN __ORDER_BIG_ENDIAN__ +#define DRV_BYTE_ORDER __BYTE_ORDER__ + +#endif /* __BYTE_ORDER__*/ +#endif /* DRV_BYTE_ORDER */ + +/** + * @} + * + */ + +/** @defgroup STMicroelectronics sensors common types + * @{ + * + */ + +#ifndef MEMS_SHARED_TYPES +#define MEMS_SHARED_TYPES + +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} bitwise_t; + +#define PROPERTY_DISABLE (0U) +#define PROPERTY_ENABLE (1U) + +/** @addtogroup Interfaces_Functions + * @brief This section provide a set of functions used to read and + * write a generic register of the device. + * MANDATORY: return 0 -> no Error. + * @{ + * + */ + +typedef int32_t (*stmdev_write_ptr)(void*, uint8_t, const uint8_t*, uint16_t); +typedef int32_t (*stmdev_read_ptr)(void*, uint8_t, uint8_t*, uint16_t); +typedef void (*stmdev_mdelay_ptr)(uint32_t millisec); + +typedef struct { + /** Component mandatory fields **/ + stmdev_write_ptr write_reg; + stmdev_read_ptr read_reg; + /** Component optional fields **/ + stmdev_mdelay_ptr mdelay; + /** Customizable optional pointer **/ + void* handle; +} stmdev_ctx_t; + +/** + * @} + * + */ + +#endif /* MEMS_SHARED_TYPES */ + +#ifndef MEMS_UCF_SHARED_TYPES +#define MEMS_UCF_SHARED_TYPES + +/** @defgroup Generic address-data structure definition + * @brief This structure is useful to load a predefined configuration + * of a sensor. + * You can create a sensor configuration by your own or using + * Unico / Unicleo tools available on STMicroelectronics + * web site. + * + * @{ + * + */ + +typedef struct { + uint8_t address; + uint8_t data; +} ucf_line_t; + +/** + * @} + * + */ + +#endif /* MEMS_UCF_SHARED_TYPES */ + +/** + * @} + * + */ + +/** @defgroup LSM6DS3TR_C_Infos + * @{ + * + */ + +/** I2C Device Address 8 bit format if SA0=0 -> D5 if SA0=1 -> D7 **/ +#define LSM6DS3TR_C_I2C_ADD_L 0xD5U +#define LSM6DS3TR_C_I2C_ADD_H 0xD7U + +/** Device Identification (Who am I) **/ +#define LSM6DS3TR_C_ID 0x6AU + +/** + * @} + * + */ + +#define LSM6DS3TR_C_FUNC_CFG_ACCESS 0x01U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 5; + uint8_t func_cfg_en : 3; /* func_cfg_en + func_cfg_en_b */ +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t func_cfg_en : 3; /* func_cfg_en + func_cfg_en_b */ + uint8_t not_used_01 : 5; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_func_cfg_access_t; + +#define LSM6DS3TR_C_SENSOR_SYNC_TIME_FRAME 0x04U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t tph : 4; + uint8_t not_used_01 : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 4; + uint8_t tph : 4; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensor_sync_time_frame_t; + +#define LSM6DS3TR_C_SENSOR_SYNC_RES_RATIO 0x05U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t rr : 2; + uint8_t not_used_01 : 6; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 6; + uint8_t rr : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensor_sync_res_ratio_t; + +#define LSM6DS3TR_C_FIFO_CTRL1 0x06U +typedef struct { + uint8_t fth : 8; /* + FIFO_CTRL2(fth) */ +} lsm6ds3tr_c_fifo_ctrl1_t; + +#define LSM6DS3TR_C_FIFO_CTRL2 0x07U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t fth : 3; /* + FIFO_CTRL1(fth) */ + uint8_t fifo_temp_en : 1; + uint8_t not_used_01 : 2; + uint8_t timer_pedo_fifo_drdy : 1; + uint8_t timer_pedo_fifo_en : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t timer_pedo_fifo_en : 1; + uint8_t timer_pedo_fifo_drdy : 1; + uint8_t not_used_01 : 2; + uint8_t fifo_temp_en : 1; + uint8_t fth : 3; /* + FIFO_CTRL1(fth) */ +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_fifo_ctrl2_t; + +#define LSM6DS3TR_C_FIFO_CTRL3 0x08U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t dec_fifo_xl : 3; + uint8_t dec_fifo_gyro : 3; + uint8_t not_used_01 : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 2; + uint8_t dec_fifo_gyro : 3; + uint8_t dec_fifo_xl : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_fifo_ctrl3_t; + +#define LSM6DS3TR_C_FIFO_CTRL4 0x09U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t dec_ds3_fifo : 3; + uint8_t dec_ds4_fifo : 3; + uint8_t only_high_data : 1; + uint8_t stop_on_fth : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t stop_on_fth : 1; + uint8_t only_high_data : 1; + uint8_t dec_ds4_fifo : 3; + uint8_t dec_ds3_fifo : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_fifo_ctrl4_t; + +#define LSM6DS3TR_C_FIFO_CTRL5 0x0AU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t fifo_mode : 3; + uint8_t odr_fifo : 4; + uint8_t not_used_01 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 1; + uint8_t odr_fifo : 4; + uint8_t fifo_mode : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_fifo_ctrl5_t; + +#define LSM6DS3TR_C_DRDY_PULSE_CFG_G 0x0BU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int2_wrist_tilt : 1; + uint8_t not_used_01 : 6; + uint8_t drdy_pulsed : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t drdy_pulsed : 1; + uint8_t not_used_01 : 6; + uint8_t int2_wrist_tilt : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_drdy_pulse_cfg_g_t; + +#define LSM6DS3TR_C_INT1_CTRL 0x0DU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int1_drdy_xl : 1; + uint8_t int1_drdy_g : 1; + uint8_t int1_boot : 1; + uint8_t int1_fth : 1; + uint8_t int1_fifo_ovr : 1; + uint8_t int1_full_flag : 1; + uint8_t int1_sign_mot : 1; + uint8_t int1_step_detector : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int1_step_detector : 1; + uint8_t int1_sign_mot : 1; + uint8_t int1_full_flag : 1; + uint8_t int1_fifo_ovr : 1; + uint8_t int1_fth : 1; + uint8_t int1_boot : 1; + uint8_t int1_drdy_g : 1; + uint8_t int1_drdy_xl : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_int1_ctrl_t; + +#define LSM6DS3TR_C_INT2_CTRL 0x0EU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int2_drdy_xl : 1; + uint8_t int2_drdy_g : 1; + uint8_t int2_drdy_temp : 1; + uint8_t int2_fth : 1; + uint8_t int2_fifo_ovr : 1; + uint8_t int2_full_flag : 1; + uint8_t int2_step_count_ov : 1; + uint8_t int2_step_delta : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int2_step_delta : 1; + uint8_t int2_step_count_ov : 1; + uint8_t int2_full_flag : 1; + uint8_t int2_fifo_ovr : 1; + uint8_t int2_fth : 1; + uint8_t int2_drdy_temp : 1; + uint8_t int2_drdy_g : 1; + uint8_t int2_drdy_xl : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_int2_ctrl_t; + +#define LSM6DS3TR_C_WHO_AM_I 0x0FU +#define LSM6DS3TR_C_CTRL1_XL 0x10U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bw0_xl : 1; + uint8_t lpf1_bw_sel : 1; + uint8_t fs_xl : 2; + uint8_t odr_xl : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t odr_xl : 4; + uint8_t fs_xl : 2; + uint8_t lpf1_bw_sel : 1; + uint8_t bw0_xl : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl1_xl_t; + +#define LSM6DS3TR_C_CTRL2_G 0x11U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 1; + uint8_t fs_g : 3; /* fs_g + fs_125 */ + uint8_t odr_g : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t odr_g : 4; + uint8_t fs_g : 3; /* fs_g + fs_125 */ + uint8_t not_used_01 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl2_g_t; + +#define LSM6DS3TR_C_CTRL3_C 0x12U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t sw_reset : 1; + uint8_t ble : 1; + uint8_t if_inc : 1; + uint8_t sim : 1; + uint8_t pp_od : 1; + uint8_t h_lactive : 1; + uint8_t bdu : 1; + uint8_t boot : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t boot : 1; + uint8_t bdu : 1; + uint8_t h_lactive : 1; + uint8_t pp_od : 1; + uint8_t sim : 1; + uint8_t if_inc : 1; + uint8_t ble : 1; + uint8_t sw_reset : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl3_c_t; + +#define LSM6DS3TR_C_CTRL4_C 0x13U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 1; + uint8_t lpf1_sel_g : 1; + uint8_t i2c_disable : 1; + uint8_t drdy_mask : 1; + uint8_t den_drdy_int1 : 1; + uint8_t int2_on_int1 : 1; + uint8_t sleep : 1; + uint8_t den_xl_en : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t den_xl_en : 1; + uint8_t sleep : 1; + uint8_t int2_on_int1 : 1; + uint8_t den_drdy_int1 : 1; + uint8_t drdy_mask : 1; + uint8_t i2c_disable : 1; + uint8_t lpf1_sel_g : 1; + uint8_t not_used_01 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl4_c_t; + +#define LSM6DS3TR_C_CTRL5_C 0x14U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t st_xl : 2; + uint8_t st_g : 2; + uint8_t den_lh : 1; + uint8_t rounding : 3; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t rounding : 3; + uint8_t den_lh : 1; + uint8_t st_g : 2; + uint8_t st_xl : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl5_c_t; + +#define LSM6DS3TR_C_CTRL6_C 0x15U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t ftype : 2; + uint8_t not_used_01 : 1; + uint8_t usr_off_w : 1; + uint8_t xl_hm_mode : 1; + uint8_t den_mode : 3; /* trig_en + lvl_en + lvl2_en */ +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t den_mode : 3; /* trig_en + lvl_en + lvl2_en */ + uint8_t xl_hm_mode : 1; + uint8_t usr_off_w : 1; + uint8_t not_used_01 : 1; + uint8_t ftype : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl6_c_t; + +#define LSM6DS3TR_C_CTRL7_G 0x16U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 2; + uint8_t rounding_status : 1; + uint8_t not_used_02 : 1; + uint8_t hpm_g : 2; + uint8_t hp_en_g : 1; + uint8_t g_hm_mode : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t g_hm_mode : 1; + uint8_t hp_en_g : 1; + uint8_t hpm_g : 2; + uint8_t not_used_02 : 1; + uint8_t rounding_status : 1; + uint8_t not_used_01 : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl7_g_t; + +#define LSM6DS3TR_C_CTRL8_XL 0x17U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t low_pass_on_6d : 1; + uint8_t not_used_01 : 1; + uint8_t hp_slope_xl_en : 1; + uint8_t input_composite : 1; + uint8_t hp_ref_mode : 1; + uint8_t hpcf_xl : 2; + uint8_t lpf2_xl_en : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t lpf2_xl_en : 1; + uint8_t hpcf_xl : 2; + uint8_t hp_ref_mode : 1; + uint8_t input_composite : 1; + uint8_t hp_slope_xl_en : 1; + uint8_t not_used_01 : 1; + uint8_t low_pass_on_6d : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl8_xl_t; + +#define LSM6DS3TR_C_CTRL9_XL 0x18U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 2; + uint8_t soft_en : 1; + uint8_t not_used_02 : 1; + uint8_t den_xl_g : 1; + uint8_t den_z : 1; + uint8_t den_y : 1; + uint8_t den_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t den_x : 1; + uint8_t den_y : 1; + uint8_t den_z : 1; + uint8_t den_xl_g : 1; + uint8_t not_used_02 : 1; + uint8_t soft_en : 1; + uint8_t not_used_01 : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl9_xl_t; + +#define LSM6DS3TR_C_CTRL10_C 0x19U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t sign_motion_en : 1; + uint8_t pedo_rst_step : 1; + uint8_t func_en : 1; + uint8_t tilt_en : 1; + uint8_t pedo_en : 1; + uint8_t timer_en : 1; + uint8_t not_used_01 : 1; + uint8_t wrist_tilt_en : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t wrist_tilt_en : 1; + uint8_t not_used_01 : 1; + uint8_t timer_en : 1; + uint8_t pedo_en : 1; + uint8_t tilt_en : 1; + uint8_t func_en : 1; + uint8_t pedo_rst_step : 1; + uint8_t sign_motion_en : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl10_c_t; + +#define LSM6DS3TR_C_MASTER_CONFIG 0x1AU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t master_on : 1; + uint8_t iron_en : 1; + uint8_t pass_through_mode : 1; + uint8_t pull_up_en : 1; + uint8_t start_config : 1; + uint8_t not_used_01 : 1; + uint8_t data_valid_sel_fifo : 1; + uint8_t drdy_on_int1 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t drdy_on_int1 : 1; + uint8_t data_valid_sel_fifo : 1; + uint8_t not_used_01 : 1; + uint8_t start_config : 1; + uint8_t pull_up_en : 1; + uint8_t pass_through_mode : 1; + uint8_t iron_en : 1; + uint8_t master_on : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_master_config_t; + +#define LSM6DS3TR_C_WAKE_UP_SRC 0x1BU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t z_wu : 1; + uint8_t y_wu : 1; + uint8_t x_wu : 1; + uint8_t wu_ia : 1; + uint8_t sleep_state_ia : 1; + uint8_t ff_ia : 1; + uint8_t not_used_01 : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 2; + uint8_t ff_ia : 1; + uint8_t sleep_state_ia : 1; + uint8_t wu_ia : 1; + uint8_t x_wu : 1; + uint8_t y_wu : 1; + uint8_t z_wu : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_wake_up_src_t; + +#define LSM6DS3TR_C_TAP_SRC 0x1CU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t z_tap : 1; + uint8_t y_tap : 1; + uint8_t x_tap : 1; + uint8_t tap_sign : 1; + uint8_t double_tap : 1; + uint8_t single_tap : 1; + uint8_t tap_ia : 1; + uint8_t not_used_01 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 1; + uint8_t tap_ia : 1; + uint8_t single_tap : 1; + uint8_t double_tap : 1; + uint8_t tap_sign : 1; + uint8_t x_tap : 1; + uint8_t y_tap : 1; + uint8_t z_tap : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_tap_src_t; + +#define LSM6DS3TR_C_D6D_SRC 0x1DU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t xl : 1; + uint8_t xh : 1; + uint8_t yl : 1; + uint8_t yh : 1; + uint8_t zl : 1; + uint8_t zh : 1; + uint8_t d6d_ia : 1; + uint8_t den_drdy : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t den_drdy : 1; + uint8_t d6d_ia : 1; + uint8_t zh : 1; + uint8_t zl : 1; + uint8_t yh : 1; + uint8_t yl : 1; + uint8_t xh : 1; + uint8_t xl : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_d6d_src_t; + +#define LSM6DS3TR_C_STATUS_REG 0x1EU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t xlda : 1; + uint8_t gda : 1; + uint8_t tda : 1; + uint8_t not_used_01 : 5; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 5; + uint8_t tda : 1; + uint8_t gda : 1; + uint8_t xlda : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_status_reg_t; + +#define LSM6DS3TR_C_OUT_TEMP_L 0x20U +#define LSM6DS3TR_C_OUT_TEMP_H 0x21U +#define LSM6DS3TR_C_OUTX_L_G 0x22U +#define LSM6DS3TR_C_OUTX_H_G 0x23U +#define LSM6DS3TR_C_OUTY_L_G 0x24U +#define LSM6DS3TR_C_OUTY_H_G 0x25U +#define LSM6DS3TR_C_OUTZ_L_G 0x26U +#define LSM6DS3TR_C_OUTZ_H_G 0x27U +#define LSM6DS3TR_C_OUTX_L_XL 0x28U +#define LSM6DS3TR_C_OUTX_H_XL 0x29U +#define LSM6DS3TR_C_OUTY_L_XL 0x2AU +#define LSM6DS3TR_C_OUTY_H_XL 0x2BU +#define LSM6DS3TR_C_OUTZ_L_XL 0x2CU +#define LSM6DS3TR_C_OUTZ_H_XL 0x2DU +#define LSM6DS3TR_C_SENSORHUB1_REG 0x2EU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub1_reg_t; + +#define LSM6DS3TR_C_SENSORHUB2_REG 0x2FU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub2_reg_t; + +#define LSM6DS3TR_C_SENSORHUB3_REG 0x30U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub3_reg_t; + +#define LSM6DS3TR_C_SENSORHUB4_REG 0x31U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub4_reg_t; + +#define LSM6DS3TR_C_SENSORHUB5_REG 0x32U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub5_reg_t; + +#define LSM6DS3TR_C_SENSORHUB6_REG 0x33U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub6_reg_t; + +#define LSM6DS3TR_C_SENSORHUB7_REG 0x34U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub7_reg_t; + +#define LSM6DS3TR_C_SENSORHUB8_REG 0x35U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub8_reg_t; + +#define LSM6DS3TR_C_SENSORHUB9_REG 0x36U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub9_reg_t; + +#define LSM6DS3TR_C_SENSORHUB10_REG 0x37U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub10_reg_t; + +#define LSM6DS3TR_C_SENSORHUB11_REG 0x38U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub11_reg_t; + +#define LSM6DS3TR_C_SENSORHUB12_REG 0x39U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub12_reg_t; + +#define LSM6DS3TR_C_FIFO_STATUS1 0x3AU +typedef struct { + uint8_t diff_fifo : 8; /* + FIFO_STATUS2(diff_fifo) */ +} lsm6ds3tr_c_fifo_status1_t; + +#define LSM6DS3TR_C_FIFO_STATUS2 0x3BU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t diff_fifo : 3; /* + FIFO_STATUS1(diff_fifo) */ + uint8_t not_used_01 : 1; + uint8_t fifo_empty : 1; + uint8_t fifo_full_smart : 1; + uint8_t over_run : 1; + uint8_t waterm : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t waterm : 1; + uint8_t over_run : 1; + uint8_t fifo_full_smart : 1; + uint8_t fifo_empty : 1; + uint8_t not_used_01 : 1; + uint8_t diff_fifo : 3; /* + FIFO_STATUS1(diff_fifo) */ +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_fifo_status2_t; + +#define LSM6DS3TR_C_FIFO_STATUS3 0x3CU +typedef struct { + uint8_t fifo_pattern : 8; /* + FIFO_STATUS4(fifo_pattern) */ +} lsm6ds3tr_c_fifo_status3_t; + +#define LSM6DS3TR_C_FIFO_STATUS4 0x3DU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t fifo_pattern : 2; /* + FIFO_STATUS3(fifo_pattern) */ + uint8_t not_used_01 : 6; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 6; + uint8_t fifo_pattern : 2; /* + FIFO_STATUS3(fifo_pattern) */ +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_fifo_status4_t; + +#define LSM6DS3TR_C_FIFO_DATA_OUT_L 0x3EU +#define LSM6DS3TR_C_FIFO_DATA_OUT_H 0x3FU +#define LSM6DS3TR_C_TIMESTAMP0_REG 0x40U +#define LSM6DS3TR_C_TIMESTAMP1_REG 0x41U +#define LSM6DS3TR_C_TIMESTAMP2_REG 0x42U +#define LSM6DS3TR_C_STEP_TIMESTAMP_L 0x49U +#define LSM6DS3TR_C_STEP_TIMESTAMP_H 0x4AU +#define LSM6DS3TR_C_STEP_COUNTER_L 0x4BU +#define LSM6DS3TR_C_STEP_COUNTER_H 0x4CU + +#define LSM6DS3TR_C_SENSORHUB13_REG 0x4DU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub13_reg_t; + +#define LSM6DS3TR_C_SENSORHUB14_REG 0x4EU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub14_reg_t; + +#define LSM6DS3TR_C_SENSORHUB15_REG 0x4FU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub15_reg_t; + +#define LSM6DS3TR_C_SENSORHUB16_REG 0x50U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub16_reg_t; + +#define LSM6DS3TR_C_SENSORHUB17_REG 0x51U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub17_reg_t; + +#define LSM6DS3TR_C_SENSORHUB18_REG 0x52U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub18_reg_t; + +#define LSM6DS3TR_C_FUNC_SRC1 0x53U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t sensorhub_end_op : 1; + uint8_t si_end_op : 1; + uint8_t hi_fail : 1; + uint8_t step_overflow : 1; + uint8_t step_detected : 1; + uint8_t tilt_ia : 1; + uint8_t sign_motion_ia : 1; + uint8_t step_count_delta_ia : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t step_count_delta_ia : 1; + uint8_t sign_motion_ia : 1; + uint8_t tilt_ia : 1; + uint8_t step_detected : 1; + uint8_t step_overflow : 1; + uint8_t hi_fail : 1; + uint8_t si_end_op : 1; + uint8_t sensorhub_end_op : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_func_src1_t; + +#define LSM6DS3TR_C_FUNC_SRC2 0x54U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t wrist_tilt_ia : 1; + uint8_t not_used_01 : 2; + uint8_t slave0_nack : 1; + uint8_t slave1_nack : 1; + uint8_t slave2_nack : 1; + uint8_t slave3_nack : 1; + uint8_t not_used_02 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_02 : 1; + uint8_t slave3_nack : 1; + uint8_t slave2_nack : 1; + uint8_t slave1_nack : 1; + uint8_t slave0_nack : 1; + uint8_t not_used_01 : 2; + uint8_t wrist_tilt_ia : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_func_src2_t; + +#define LSM6DS3TR_C_WRIST_TILT_IA 0x55U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 2; + uint8_t wrist_tilt_ia_zneg : 1; + uint8_t wrist_tilt_ia_zpos : 1; + uint8_t wrist_tilt_ia_yneg : 1; + uint8_t wrist_tilt_ia_ypos : 1; + uint8_t wrist_tilt_ia_xneg : 1; + uint8_t wrist_tilt_ia_xpos : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t wrist_tilt_ia_xpos : 1; + uint8_t wrist_tilt_ia_xneg : 1; + uint8_t wrist_tilt_ia_ypos : 1; + uint8_t wrist_tilt_ia_yneg : 1; + uint8_t wrist_tilt_ia_zpos : 1; + uint8_t wrist_tilt_ia_zneg : 1; + uint8_t not_used_01 : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_wrist_tilt_ia_t; + +#define LSM6DS3TR_C_TAP_CFG 0x58U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t lir : 1; + uint8_t tap_z_en : 1; + uint8_t tap_y_en : 1; + uint8_t tap_x_en : 1; + uint8_t slope_fds : 1; + uint8_t inact_en : 2; + uint8_t interrupts_enable : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t interrupts_enable : 1; + uint8_t inact_en : 2; + uint8_t slope_fds : 1; + uint8_t tap_x_en : 1; + uint8_t tap_y_en : 1; + uint8_t tap_z_en : 1; + uint8_t lir : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_tap_cfg_t; + +#define LSM6DS3TR_C_TAP_THS_6D 0x59U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t tap_ths : 5; + uint8_t sixd_ths : 2; + uint8_t d4d_en : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t d4d_en : 1; + uint8_t sixd_ths : 2; + uint8_t tap_ths : 5; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_tap_ths_6d_t; + +#define LSM6DS3TR_C_INT_DUR2 0x5AU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t shock : 2; + uint8_t quiet : 2; + uint8_t dur : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t dur : 4; + uint8_t quiet : 2; + uint8_t shock : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_int_dur2_t; + +#define LSM6DS3TR_C_WAKE_UP_THS 0x5BU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t wk_ths : 6; + uint8_t not_used_01 : 1; + uint8_t single_double_tap : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t single_double_tap : 1; + uint8_t not_used_01 : 1; + uint8_t wk_ths : 6; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_wake_up_ths_t; + +#define LSM6DS3TR_C_WAKE_UP_DUR 0x5CU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t sleep_dur : 4; + uint8_t timer_hr : 1; + uint8_t wake_dur : 2; + uint8_t ff_dur : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t ff_dur : 1; + uint8_t wake_dur : 2; + uint8_t timer_hr : 1; + uint8_t sleep_dur : 4; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_wake_up_dur_t; + +#define LSM6DS3TR_C_FREE_FALL 0x5DU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t ff_ths : 3; + uint8_t ff_dur : 5; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t ff_dur : 5; + uint8_t ff_ths : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_free_fall_t; + +#define LSM6DS3TR_C_MD1_CFG 0x5EU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int1_timer : 1; + uint8_t int1_tilt : 1; + uint8_t int1_6d : 1; + uint8_t int1_double_tap : 1; + uint8_t int1_ff : 1; + uint8_t int1_wu : 1; + uint8_t int1_single_tap : 1; + uint8_t int1_inact_state : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int1_inact_state : 1; + uint8_t int1_single_tap : 1; + uint8_t int1_wu : 1; + uint8_t int1_ff : 1; + uint8_t int1_double_tap : 1; + uint8_t int1_6d : 1; + uint8_t int1_tilt : 1; + uint8_t int1_timer : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_md1_cfg_t; + +#define LSM6DS3TR_C_MD2_CFG 0x5FU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int2_iron : 1; + uint8_t int2_tilt : 1; + uint8_t int2_6d : 1; + uint8_t int2_double_tap : 1; + uint8_t int2_ff : 1; + uint8_t int2_wu : 1; + uint8_t int2_single_tap : 1; + uint8_t int2_inact_state : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int2_inact_state : 1; + uint8_t int2_single_tap : 1; + uint8_t int2_wu : 1; + uint8_t int2_ff : 1; + uint8_t int2_double_tap : 1; + uint8_t int2_6d : 1; + uint8_t int2_tilt : 1; + uint8_t int2_iron : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_md2_cfg_t; + +#define LSM6DS3TR_C_MASTER_CMD_CODE 0x60U +typedef struct { + uint8_t master_cmd_code : 8; +} lsm6ds3tr_c_master_cmd_code_t; + +#define LSM6DS3TR_C_SENS_SYNC_SPI_ERROR_CODE 0x61U +typedef struct { + uint8_t error_code : 8; +} lsm6ds3tr_c_sens_sync_spi_error_code_t; + +#define LSM6DS3TR_C_OUT_MAG_RAW_X_L 0x66U +#define LSM6DS3TR_C_OUT_MAG_RAW_X_H 0x67U +#define LSM6DS3TR_C_OUT_MAG_RAW_Y_L 0x68U +#define LSM6DS3TR_C_OUT_MAG_RAW_Y_H 0x69U +#define LSM6DS3TR_C_OUT_MAG_RAW_Z_L 0x6AU +#define LSM6DS3TR_C_OUT_MAG_RAW_Z_H 0x6BU +#define LSM6DS3TR_C_X_OFS_USR 0x73U +#define LSM6DS3TR_C_Y_OFS_USR 0x74U +#define LSM6DS3TR_C_Z_OFS_USR 0x75U +#define LSM6DS3TR_C_SLV0_ADD 0x02U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t rw_0 : 1; + uint8_t slave0_add : 7; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave0_add : 7; + uint8_t rw_0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_slv0_add_t; + +#define LSM6DS3TR_C_SLV0_SUBADD 0x03U +typedef struct { + uint8_t slave0_reg : 8; +} lsm6ds3tr_c_slv0_subadd_t; + +#define LSM6DS3TR_C_SLAVE0_CONFIG 0x04U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t slave0_numop : 3; + uint8_t src_mode : 1; + uint8_t aux_sens_on : 2; + uint8_t slave0_rate : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave0_rate : 2; + uint8_t aux_sens_on : 2; + uint8_t src_mode : 1; + uint8_t slave0_numop : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_slave0_config_t; + +#define LSM6DS3TR_C_SLV1_ADD 0x05U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t r_1 : 1; + uint8_t slave1_add : 7; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave1_add : 7; + uint8_t r_1 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_slv1_add_t; + +#define LSM6DS3TR_C_SLV1_SUBADD 0x06U +typedef struct { + uint8_t slave1_reg : 8; +} lsm6ds3tr_c_slv1_subadd_t; + +#define LSM6DS3TR_C_SLAVE1_CONFIG 0x07U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t slave1_numop : 3; + uint8_t not_used_01 : 2; + uint8_t write_once : 1; + uint8_t slave1_rate : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave1_rate : 2; + uint8_t write_once : 1; + uint8_t not_used_01 : 2; + uint8_t slave1_numop : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_slave1_config_t; + +#define LSM6DS3TR_C_SLV2_ADD 0x08U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t r_2 : 1; + uint8_t slave2_add : 7; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave2_add : 7; + uint8_t r_2 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_slv2_add_t; + +#define LSM6DS3TR_C_SLV2_SUBADD 0x09U +typedef struct { + uint8_t slave2_reg : 8; +} lsm6ds3tr_c_slv2_subadd_t; + +#define LSM6DS3TR_C_SLAVE2_CONFIG 0x0AU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t slave2_numop : 3; + uint8_t not_used_01 : 3; + uint8_t slave2_rate : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave2_rate : 2; + uint8_t not_used_01 : 3; + uint8_t slave2_numop : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_slave2_config_t; + +#define LSM6DS3TR_C_SLV3_ADD 0x0BU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t r_3 : 1; + uint8_t slave3_add : 7; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave3_add : 7; + uint8_t r_3 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_slv3_add_t; + +#define LSM6DS3TR_C_SLV3_SUBADD 0x0CU +typedef struct { + uint8_t slave3_reg : 8; +} lsm6ds3tr_c_slv3_subadd_t; + +#define LSM6DS3TR_C_SLAVE3_CONFIG 0x0DU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t slave3_numop : 3; + uint8_t not_used_01 : 3; + uint8_t slave3_rate : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave3_rate : 2; + uint8_t not_used_01 : 3; + uint8_t slave3_numop : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_slave3_config_t; + +#define LSM6DS3TR_C_DATAWRITE_SRC_MODE_SUB_SLV0 0x0EU +typedef struct { + uint8_t slave_dataw : 8; +} lsm6ds3tr_c_datawrite_src_mode_sub_slv0_t; + +#define LSM6DS3TR_C_CONFIG_PEDO_THS_MIN 0x0FU +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t ths_min : 5; + uint8_t not_used_01 : 2; + uint8_t pedo_fs : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t pedo_fs : 1; + uint8_t not_used_01 : 2; + uint8_t ths_min : 5; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_config_pedo_ths_min_t; + +#define LSM6DS3TR_C_SM_THS 0x13U +#define LSM6DS3TR_C_PEDO_DEB_REG 0x14U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t deb_step : 3; + uint8_t deb_time : 5; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t deb_time : 5; + uint8_t deb_step : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_pedo_deb_reg_t; + +#define LSM6DS3TR_C_STEP_COUNT_DELTA 0x15U +#define LSM6DS3TR_C_MAG_SI_XX 0x24U +#define LSM6DS3TR_C_MAG_SI_XY 0x25U +#define LSM6DS3TR_C_MAG_SI_XZ 0x26U +#define LSM6DS3TR_C_MAG_SI_YX 0x27U +#define LSM6DS3TR_C_MAG_SI_YY 0x28U +#define LSM6DS3TR_C_MAG_SI_YZ 0x29U +#define LSM6DS3TR_C_MAG_SI_ZX 0x2AU +#define LSM6DS3TR_C_MAG_SI_ZY 0x2BU +#define LSM6DS3TR_C_MAG_SI_ZZ 0x2CU +#define LSM6DS3TR_C_MAG_OFFX_L 0x2DU +#define LSM6DS3TR_C_MAG_OFFX_H 0x2EU +#define LSM6DS3TR_C_MAG_OFFY_L 0x2FU +#define LSM6DS3TR_C_MAG_OFFY_H 0x30U +#define LSM6DS3TR_C_MAG_OFFZ_L 0x31U +#define LSM6DS3TR_C_MAG_OFFZ_H 0x32U +#define LSM6DS3TR_C_A_WRIST_TILT_LAT 0x50U +#define LSM6DS3TR_C_A_WRIST_TILT_THS 0x54U +#define LSM6DS3TR_C_A_WRIST_TILT_MASK 0x59U +typedef struct { +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 2; + uint8_t wrist_tilt_mask_zneg : 1; + uint8_t wrist_tilt_mask_zpos : 1; + uint8_t wrist_tilt_mask_yneg : 1; + uint8_t wrist_tilt_mask_ypos : 1; + uint8_t wrist_tilt_mask_xneg : 1; + uint8_t wrist_tilt_mask_xpos : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t wrist_tilt_mask_xpos : 1; + uint8_t wrist_tilt_mask_xneg : 1; + uint8_t wrist_tilt_mask_ypos : 1; + uint8_t wrist_tilt_mask_yneg : 1; + uint8_t wrist_tilt_mask_zpos : 1; + uint8_t wrist_tilt_mask_zneg : 1; + uint8_t not_used_01 : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_a_wrist_tilt_mask_t; + +/** + * @defgroup LSM6DS3TR_C_Register_Union + * @brief This union group all the registers having a bit-field + * description. + * This union is useful but it's not needed by the driver. + * + * REMOVING this union you are compliant with: + * MISRA-C 2012 [Rule 19.2] -> " Union are not allowed " + * + * @{ + * + */ +typedef union { + lsm6ds3tr_c_func_cfg_access_t func_cfg_access; + lsm6ds3tr_c_sensor_sync_time_frame_t sensor_sync_time_frame; + lsm6ds3tr_c_sensor_sync_res_ratio_t sensor_sync_res_ratio; + lsm6ds3tr_c_fifo_ctrl1_t fifo_ctrl1; + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + lsm6ds3tr_c_fifo_ctrl3_t fifo_ctrl3; + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + lsm6ds3tr_c_fifo_ctrl5_t fifo_ctrl5; + lsm6ds3tr_c_drdy_pulse_cfg_g_t drdy_pulse_cfg_g; + lsm6ds3tr_c_int1_ctrl_t int1_ctrl; + lsm6ds3tr_c_int2_ctrl_t int2_ctrl; + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + lsm6ds3tr_c_ctrl2_g_t ctrl2_g; + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + lsm6ds3tr_c_ctrl7_g_t ctrl7_g; + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + lsm6ds3tr_c_master_config_t master_config; + lsm6ds3tr_c_wake_up_src_t wake_up_src; + lsm6ds3tr_c_tap_src_t tap_src; + lsm6ds3tr_c_d6d_src_t d6d_src; + lsm6ds3tr_c_status_reg_t status_reg; + lsm6ds3tr_c_sensorhub1_reg_t sensorhub1_reg; + lsm6ds3tr_c_sensorhub2_reg_t sensorhub2_reg; + lsm6ds3tr_c_sensorhub3_reg_t sensorhub3_reg; + lsm6ds3tr_c_sensorhub4_reg_t sensorhub4_reg; + lsm6ds3tr_c_sensorhub5_reg_t sensorhub5_reg; + lsm6ds3tr_c_sensorhub6_reg_t sensorhub6_reg; + lsm6ds3tr_c_sensorhub7_reg_t sensorhub7_reg; + lsm6ds3tr_c_sensorhub8_reg_t sensorhub8_reg; + lsm6ds3tr_c_sensorhub9_reg_t sensorhub9_reg; + lsm6ds3tr_c_sensorhub10_reg_t sensorhub10_reg; + lsm6ds3tr_c_sensorhub11_reg_t sensorhub11_reg; + lsm6ds3tr_c_sensorhub12_reg_t sensorhub12_reg; + lsm6ds3tr_c_fifo_status1_t fifo_status1; + lsm6ds3tr_c_fifo_status2_t fifo_status2; + lsm6ds3tr_c_fifo_status3_t fifo_status3; + lsm6ds3tr_c_fifo_status4_t fifo_status4; + lsm6ds3tr_c_sensorhub13_reg_t sensorhub13_reg; + lsm6ds3tr_c_sensorhub14_reg_t sensorhub14_reg; + lsm6ds3tr_c_sensorhub15_reg_t sensorhub15_reg; + lsm6ds3tr_c_sensorhub16_reg_t sensorhub16_reg; + lsm6ds3tr_c_sensorhub17_reg_t sensorhub17_reg; + lsm6ds3tr_c_sensorhub18_reg_t sensorhub18_reg; + lsm6ds3tr_c_func_src1_t func_src1; + lsm6ds3tr_c_func_src2_t func_src2; + lsm6ds3tr_c_wrist_tilt_ia_t wrist_tilt_ia; + lsm6ds3tr_c_tap_cfg_t tap_cfg; + lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; + lsm6ds3tr_c_int_dur2_t int_dur2; + lsm6ds3tr_c_wake_up_ths_t wake_up_ths; + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + lsm6ds3tr_c_free_fall_t free_fall; + lsm6ds3tr_c_md1_cfg_t md1_cfg; + lsm6ds3tr_c_md2_cfg_t md2_cfg; + lsm6ds3tr_c_master_cmd_code_t master_cmd_code; + lsm6ds3tr_c_sens_sync_spi_error_code_t sens_sync_spi_error_code; + lsm6ds3tr_c_slv0_add_t slv0_add; + lsm6ds3tr_c_slv0_subadd_t slv0_subadd; + lsm6ds3tr_c_slave0_config_t slave0_config; + lsm6ds3tr_c_slv1_add_t slv1_add; + lsm6ds3tr_c_slv1_subadd_t slv1_subadd; + lsm6ds3tr_c_slave1_config_t slave1_config; + lsm6ds3tr_c_slv2_add_t slv2_add; + lsm6ds3tr_c_slv2_subadd_t slv2_subadd; + lsm6ds3tr_c_slave2_config_t slave2_config; + lsm6ds3tr_c_slv3_add_t slv3_add; + lsm6ds3tr_c_slv3_subadd_t slv3_subadd; + lsm6ds3tr_c_slave3_config_t slave3_config; + lsm6ds3tr_c_datawrite_src_mode_sub_slv0_t datawrite_src_mode_sub_slv0; + lsm6ds3tr_c_config_pedo_ths_min_t config_pedo_ths_min; + lsm6ds3tr_c_pedo_deb_reg_t pedo_deb_reg; + lsm6ds3tr_c_a_wrist_tilt_mask_t a_wrist_tilt_mask; + bitwise_t bitwise; + uint8_t byte; +} lsm6ds3tr_c_reg_t; + +/** + * @} + * + */ + +int32_t lsm6ds3tr_c_read_reg(stmdev_ctx_t* ctx, uint8_t reg, uint8_t* data, uint16_t len); +int32_t lsm6ds3tr_c_write_reg(stmdev_ctx_t* ctx, uint8_t reg, uint8_t* data, uint16_t len); + +float_t lsm6ds3tr_c_from_fs2g_to_mg(int16_t lsb); +float_t lsm6ds3tr_c_from_fs4g_to_mg(int16_t lsb); +float_t lsm6ds3tr_c_from_fs8g_to_mg(int16_t lsb); +float_t lsm6ds3tr_c_from_fs16g_to_mg(int16_t lsb); + +float_t lsm6ds3tr_c_from_fs125dps_to_mdps(int16_t lsb); +float_t lsm6ds3tr_c_from_fs250dps_to_mdps(int16_t lsb); +float_t lsm6ds3tr_c_from_fs500dps_to_mdps(int16_t lsb); +float_t lsm6ds3tr_c_from_fs1000dps_to_mdps(int16_t lsb); +float_t lsm6ds3tr_c_from_fs2000dps_to_mdps(int16_t lsb); + +float_t lsm6ds3tr_c_from_lsb_to_celsius(int16_t lsb); + +typedef enum { + LSM6DS3TR_C_2g = 0, + LSM6DS3TR_C_16g = 1, + LSM6DS3TR_C_4g = 2, + LSM6DS3TR_C_8g = 3, + LSM6DS3TR_C_XL_FS_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_fs_xl_t; +int32_t lsm6ds3tr_c_xl_full_scale_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_fs_xl_t val); +int32_t lsm6ds3tr_c_xl_full_scale_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_fs_xl_t* val); + +typedef enum { + LSM6DS3TR_C_XL_ODR_OFF = 0, + LSM6DS3TR_C_XL_ODR_12Hz5 = 1, + LSM6DS3TR_C_XL_ODR_26Hz = 2, + LSM6DS3TR_C_XL_ODR_52Hz = 3, + LSM6DS3TR_C_XL_ODR_104Hz = 4, + LSM6DS3TR_C_XL_ODR_208Hz = 5, + LSM6DS3TR_C_XL_ODR_416Hz = 6, + LSM6DS3TR_C_XL_ODR_833Hz = 7, + LSM6DS3TR_C_XL_ODR_1k66Hz = 8, + LSM6DS3TR_C_XL_ODR_3k33Hz = 9, + LSM6DS3TR_C_XL_ODR_6k66Hz = 10, + LSM6DS3TR_C_XL_ODR_1Hz6 = 11, + LSM6DS3TR_C_XL_ODR_ND = 12, /* ERROR CODE */ +} lsm6ds3tr_c_odr_xl_t; +int32_t lsm6ds3tr_c_xl_data_rate_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_xl_t val); +int32_t lsm6ds3tr_c_xl_data_rate_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_xl_t* val); + +typedef enum { + LSM6DS3TR_C_250dps = 0, + LSM6DS3TR_C_125dps = 1, + LSM6DS3TR_C_500dps = 2, + LSM6DS3TR_C_1000dps = 4, + LSM6DS3TR_C_2000dps = 6, + LSM6DS3TR_C_GY_FS_ND = 7, /* ERROR CODE */ +} lsm6ds3tr_c_fs_g_t; +int32_t lsm6ds3tr_c_gy_full_scale_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_fs_g_t val); +int32_t lsm6ds3tr_c_gy_full_scale_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_fs_g_t* val); + +typedef enum { + LSM6DS3TR_C_GY_ODR_OFF = 0, + LSM6DS3TR_C_GY_ODR_12Hz5 = 1, + LSM6DS3TR_C_GY_ODR_26Hz = 2, + LSM6DS3TR_C_GY_ODR_52Hz = 3, + LSM6DS3TR_C_GY_ODR_104Hz = 4, + LSM6DS3TR_C_GY_ODR_208Hz = 5, + LSM6DS3TR_C_GY_ODR_416Hz = 6, + LSM6DS3TR_C_GY_ODR_833Hz = 7, + LSM6DS3TR_C_GY_ODR_1k66Hz = 8, + LSM6DS3TR_C_GY_ODR_3k33Hz = 9, + LSM6DS3TR_C_GY_ODR_6k66Hz = 10, + LSM6DS3TR_C_GY_ODR_ND = 11, /* ERROR CODE */ +} lsm6ds3tr_c_odr_g_t; +int32_t lsm6ds3tr_c_gy_data_rate_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_g_t val); +int32_t lsm6ds3tr_c_gy_data_rate_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_g_t* val); + +int32_t lsm6ds3tr_c_block_data_update_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_block_data_update_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_LSb_1mg = 0, + LSM6DS3TR_C_LSb_16mg = 1, + LSM6DS3TR_C_WEIGHT_ND = 2, +} lsm6ds3tr_c_usr_off_w_t; +int32_t lsm6ds3tr_c_xl_offset_weight_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_usr_off_w_t val); +int32_t lsm6ds3tr_c_xl_offset_weight_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_usr_off_w_t* val); + +typedef enum { + LSM6DS3TR_C_XL_HIGH_PERFORMANCE = 0, + LSM6DS3TR_C_XL_NORMAL = 1, + LSM6DS3TR_C_XL_PW_MODE_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_xl_hm_mode_t; +int32_t lsm6ds3tr_c_xl_power_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_xl_hm_mode_t val); +int32_t lsm6ds3tr_c_xl_power_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_xl_hm_mode_t* val); + +typedef enum { + LSM6DS3TR_C_STAT_RND_DISABLE = 0, + LSM6DS3TR_C_STAT_RND_ENABLE = 1, + LSM6DS3TR_C_STAT_RND_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_rounding_status_t; +int32_t lsm6ds3tr_c_rounding_on_status_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_rounding_status_t val); +int32_t lsm6ds3tr_c_rounding_on_status_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_rounding_status_t* val); + +typedef enum { + LSM6DS3TR_C_GY_HIGH_PERFORMANCE = 0, + LSM6DS3TR_C_GY_NORMAL = 1, + LSM6DS3TR_C_GY_PW_MODE_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_g_hm_mode_t; +int32_t lsm6ds3tr_c_gy_power_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_g_hm_mode_t val); +int32_t lsm6ds3tr_c_gy_power_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_g_hm_mode_t* val); + +typedef struct { + lsm6ds3tr_c_wake_up_src_t wake_up_src; + lsm6ds3tr_c_tap_src_t tap_src; + lsm6ds3tr_c_d6d_src_t d6d_src; + lsm6ds3tr_c_status_reg_t status_reg; + lsm6ds3tr_c_func_src1_t func_src1; + lsm6ds3tr_c_func_src2_t func_src2; + lsm6ds3tr_c_wrist_tilt_ia_t wrist_tilt_ia; + lsm6ds3tr_c_a_wrist_tilt_mask_t a_wrist_tilt_mask; +} lsm6ds3tr_c_all_sources_t; +int32_t lsm6ds3tr_c_all_sources_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_all_sources_t* val); + +int32_t lsm6ds3tr_c_status_reg_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_status_reg_t* val); + +int32_t lsm6ds3tr_c_xl_flag_data_ready_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_gy_flag_data_ready_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_temp_flag_data_ready_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_xl_usr_offset_set(stmdev_ctx_t* ctx, uint8_t* buff); +int32_t lsm6ds3tr_c_xl_usr_offset_get(stmdev_ctx_t* ctx, uint8_t* buff); +int32_t lsm6ds3tr_c_timestamp_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_timestamp_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_LSB_6ms4 = 0, + LSM6DS3TR_C_LSB_25us = 1, + LSM6DS3TR_C_TS_RES_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_timer_hr_t; +int32_t lsm6ds3tr_c_timestamp_res_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_timer_hr_t val); +int32_t lsm6ds3tr_c_timestamp_res_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_timer_hr_t* val); + +typedef enum { + LSM6DS3TR_C_ROUND_DISABLE = 0, + LSM6DS3TR_C_ROUND_XL = 1, + LSM6DS3TR_C_ROUND_GY = 2, + LSM6DS3TR_C_ROUND_GY_XL = 3, + LSM6DS3TR_C_ROUND_SH1_TO_SH6 = 4, + LSM6DS3TR_C_ROUND_XL_SH1_TO_SH6 = 5, + LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH12 = 6, + LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH6 = 7, + LSM6DS3TR_C_ROUND_OUT_ND = 8, /* ERROR CODE */ +} lsm6ds3tr_c_rounding_t; +int32_t lsm6ds3tr_c_rounding_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_rounding_t val); +int32_t lsm6ds3tr_c_rounding_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_rounding_t* val); + +int32_t lsm6ds3tr_c_temperature_raw_get(stmdev_ctx_t* ctx, int16_t* val); +int32_t lsm6ds3tr_c_angular_rate_raw_get(stmdev_ctx_t* ctx, int16_t* val); +int32_t lsm6ds3tr_c_acceleration_raw_get(stmdev_ctx_t* ctx, int16_t* val); + +int32_t lsm6ds3tr_c_mag_calibrated_raw_get(stmdev_ctx_t* ctx, int16_t* val); + +int32_t lsm6ds3tr_c_fifo_raw_data_get(stmdev_ctx_t* ctx, uint8_t* buffer, uint8_t len); + +typedef enum { + LSM6DS3TR_C_USER_BANK = 0, + LSM6DS3TR_C_BANK_A = 4, + LSM6DS3TR_C_BANK_B = 5, + LSM6DS3TR_C_BANK_ND = 6, /* ERROR CODE */ +} lsm6ds3tr_c_func_cfg_en_t; +int32_t lsm6ds3tr_c_mem_bank_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_func_cfg_en_t val); +int32_t lsm6ds3tr_c_mem_bank_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_func_cfg_en_t* val); + +typedef enum { + LSM6DS3TR_C_DRDY_LATCHED = 0, + LSM6DS3TR_C_DRDY_PULSED = 1, + LSM6DS3TR_C_DRDY_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_drdy_pulsed_g_t; +int32_t lsm6ds3tr_c_data_ready_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_drdy_pulsed_g_t val); +int32_t lsm6ds3tr_c_data_ready_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_drdy_pulsed_g_t* val); + +int32_t lsm6ds3tr_c_device_id_get(stmdev_ctx_t* ctx, uint8_t* buff); +int32_t lsm6ds3tr_c_reset_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_reset_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_LSB_AT_LOW_ADD = 0, + LSM6DS3TR_C_MSB_AT_LOW_ADD = 1, + LSM6DS3TR_C_DATA_FMT_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_ble_t; +int32_t lsm6ds3tr_c_data_format_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_ble_t val); +int32_t lsm6ds3tr_c_data_format_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_ble_t* val); + +int32_t lsm6ds3tr_c_auto_increment_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_auto_increment_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_boot_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_boot_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_XL_ST_DISABLE = 0, + LSM6DS3TR_C_XL_ST_POSITIVE = 1, + LSM6DS3TR_C_XL_ST_NEGATIVE = 2, + LSM6DS3TR_C_XL_ST_ND = 3, /* ERROR CODE */ +} lsm6ds3tr_c_st_xl_t; +int32_t lsm6ds3tr_c_xl_self_test_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_st_xl_t val); +int32_t lsm6ds3tr_c_xl_self_test_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_st_xl_t* val); + +typedef enum { + LSM6DS3TR_C_GY_ST_DISABLE = 0, + LSM6DS3TR_C_GY_ST_POSITIVE = 1, + LSM6DS3TR_C_GY_ST_NEGATIVE = 3, + LSM6DS3TR_C_GY_ST_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_st_g_t; +int32_t lsm6ds3tr_c_gy_self_test_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_st_g_t val); +int32_t lsm6ds3tr_c_gy_self_test_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_st_g_t* val); + +int32_t lsm6ds3tr_c_filter_settling_mask_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_filter_settling_mask_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_USE_SLOPE = 0, + LSM6DS3TR_C_USE_HPF = 1, + LSM6DS3TR_C_HP_PATH_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_slope_fds_t; +int32_t lsm6ds3tr_c_xl_hp_path_internal_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slope_fds_t val); +int32_t lsm6ds3tr_c_xl_hp_path_internal_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slope_fds_t* val); + +typedef enum { + LSM6DS3TR_C_XL_ANA_BW_1k5Hz = 0, + LSM6DS3TR_C_XL_ANA_BW_400Hz = 1, + LSM6DS3TR_C_XL_ANA_BW_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_bw0_xl_t; +int32_t lsm6ds3tr_c_xl_filter_analog_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_bw0_xl_t val); +int32_t lsm6ds3tr_c_xl_filter_analog_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_bw0_xl_t* val); + +typedef enum { + LSM6DS3TR_C_XL_LP1_ODR_DIV_2 = 0, + LSM6DS3TR_C_XL_LP1_ODR_DIV_4 = 1, + LSM6DS3TR_C_XL_LP1_NA = 2, /* ERROR CODE */ +} lsm6ds3tr_c_lpf1_bw_sel_t; +int32_t lsm6ds3tr_c_xl_lp1_bandwidth_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_lpf1_bw_sel_t val); +int32_t lsm6ds3tr_c_xl_lp1_bandwidth_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_lpf1_bw_sel_t* val); + +typedef enum { + LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_50 = 0x00, + LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_100 = 0x01, + LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_9 = 0x02, + LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_400 = 0x03, + LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_50 = 0x10, + LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_100 = 0x11, + LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_9 = 0x12, + LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_400 = 0x13, + LSM6DS3TR_C_XL_LP_NA = 0x20, /* ERROR CODE */ +} lsm6ds3tr_c_input_composite_t; +int32_t lsm6ds3tr_c_xl_lp2_bandwidth_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_input_composite_t val); +int32_t lsm6ds3tr_c_xl_lp2_bandwidth_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_input_composite_t* val); + +int32_t lsm6ds3tr_c_xl_reference_mode_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_xl_reference_mode_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_XL_HP_ODR_DIV_4 = 0x00, /* Slope filter */ + LSM6DS3TR_C_XL_HP_ODR_DIV_100 = 0x01, + LSM6DS3TR_C_XL_HP_ODR_DIV_9 = 0x02, + LSM6DS3TR_C_XL_HP_ODR_DIV_400 = 0x03, + LSM6DS3TR_C_XL_HP_NA = 0x10, /* ERROR CODE */ +} lsm6ds3tr_c_hpcf_xl_t; +int32_t lsm6ds3tr_c_xl_hp_bandwidth_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_hpcf_xl_t val); +int32_t lsm6ds3tr_c_xl_hp_bandwidth_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_hpcf_xl_t* val); + +typedef enum { + LSM6DS3TR_C_LP2_ONLY = 0x00, + + LSM6DS3TR_C_HP_16mHz_LP2 = 0x80, + LSM6DS3TR_C_HP_65mHz_LP2 = 0x90, + LSM6DS3TR_C_HP_260mHz_LP2 = 0xA0, + LSM6DS3TR_C_HP_1Hz04_LP2 = 0xB0, + + LSM6DS3TR_C_HP_DISABLE_LP1_LIGHT = 0x0A, + LSM6DS3TR_C_HP_DISABLE_LP1_NORMAL = 0x09, + LSM6DS3TR_C_HP_DISABLE_LP_STRONG = 0x08, + LSM6DS3TR_C_HP_DISABLE_LP1_AGGRESSIVE = 0x0B, + + LSM6DS3TR_C_HP_16mHz_LP1_LIGHT = 0x8A, + LSM6DS3TR_C_HP_65mHz_LP1_NORMAL = 0x99, + LSM6DS3TR_C_HP_260mHz_LP1_STRONG = 0xA8, + LSM6DS3TR_C_HP_1Hz04_LP1_AGGRESSIVE = 0xBB, + + LSM6DS3TR_C_HP_GY_BAND_NA = 0xFF, /* ERROR CODE */ +} lsm6ds3tr_c_lpf1_sel_g_t; +int32_t lsm6ds3tr_c_gy_band_pass_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_lpf1_sel_g_t val); +int32_t lsm6ds3tr_c_gy_band_pass_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_lpf1_sel_g_t* val); + +typedef enum { + LSM6DS3TR_C_SPI_4_WIRE = 0, + LSM6DS3TR_C_SPI_3_WIRE = 1, + LSM6DS3TR_C_SPI_MODE_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_sim_t; +int32_t lsm6ds3tr_c_spi_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_sim_t val); +int32_t lsm6ds3tr_c_spi_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_sim_t* val); + +typedef enum { + LSM6DS3TR_C_I2C_ENABLE = 0, + LSM6DS3TR_C_I2C_DISABLE = 1, + LSM6DS3TR_C_I2C_MODE_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_i2c_disable_t; +int32_t lsm6ds3tr_c_i2c_interface_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_i2c_disable_t val); +int32_t lsm6ds3tr_c_i2c_interface_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_i2c_disable_t* val); + +typedef struct { + uint8_t int1_drdy_xl : 1; + uint8_t int1_drdy_g : 1; + uint8_t int1_boot : 1; + uint8_t int1_fth : 1; + uint8_t int1_fifo_ovr : 1; + uint8_t int1_full_flag : 1; + uint8_t int1_sign_mot : 1; + uint8_t int1_step_detector : 1; + uint8_t int1_timer : 1; + uint8_t int1_tilt : 1; + uint8_t int1_6d : 1; + uint8_t int1_double_tap : 1; + uint8_t int1_ff : 1; + uint8_t int1_wu : 1; + uint8_t int1_single_tap : 1; + uint8_t int1_inact_state : 1; + uint8_t den_drdy_int1 : 1; + uint8_t drdy_on_int1 : 1; +} lsm6ds3tr_c_int1_route_t; +int32_t lsm6ds3tr_c_pin_int1_route_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_int1_route_t val); +int32_t lsm6ds3tr_c_pin_int1_route_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_int1_route_t* val); + +typedef struct { + uint8_t int2_drdy_xl : 1; + uint8_t int2_drdy_g : 1; + uint8_t int2_drdy_temp : 1; + uint8_t int2_fth : 1; + uint8_t int2_fifo_ovr : 1; + uint8_t int2_full_flag : 1; + uint8_t int2_step_count_ov : 1; + uint8_t int2_step_delta : 1; + uint8_t int2_iron : 1; + uint8_t int2_tilt : 1; + uint8_t int2_6d : 1; + uint8_t int2_double_tap : 1; + uint8_t int2_ff : 1; + uint8_t int2_wu : 1; + uint8_t int2_single_tap : 1; + uint8_t int2_inact_state : 1; + uint8_t int2_wrist_tilt : 1; +} lsm6ds3tr_c_int2_route_t; +int32_t lsm6ds3tr_c_pin_int2_route_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_int2_route_t val); +int32_t lsm6ds3tr_c_pin_int2_route_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_int2_route_t* val); + +typedef enum { + LSM6DS3TR_C_PUSH_PULL = 0, + LSM6DS3TR_C_OPEN_DRAIN = 1, + LSM6DS3TR_C_PIN_MODE_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_pp_od_t; +int32_t lsm6ds3tr_c_pin_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_pp_od_t val); +int32_t lsm6ds3tr_c_pin_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_pp_od_t* val); + +typedef enum { + LSM6DS3TR_C_ACTIVE_HIGH = 0, + LSM6DS3TR_C_ACTIVE_LOW = 1, + LSM6DS3TR_C_POLARITY_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_h_lactive_t; +int32_t lsm6ds3tr_c_pin_polarity_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_h_lactive_t val); +int32_t lsm6ds3tr_c_pin_polarity_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_h_lactive_t* val); + +int32_t lsm6ds3tr_c_all_on_int1_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_all_on_int1_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_INT_PULSED = 0, + LSM6DS3TR_C_INT_LATCHED = 1, + LSM6DS3TR_C_INT_MODE = 2, /* ERROR CODE */ +} lsm6ds3tr_c_lir_t; +int32_t lsm6ds3tr_c_int_notification_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_lir_t val); +int32_t lsm6ds3tr_c_int_notification_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_lir_t* val); + +int32_t lsm6ds3tr_c_wkup_threshold_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_wkup_threshold_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_wkup_dur_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_wkup_dur_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_gy_sleep_mode_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_gy_sleep_mode_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_PROPERTY_DISABLE = 0, + LSM6DS3TR_C_XL_12Hz5_GY_NOT_AFFECTED = 1, + LSM6DS3TR_C_XL_12Hz5_GY_SLEEP = 2, + LSM6DS3TR_C_XL_12Hz5_GY_PD = 3, + LSM6DS3TR_C_ACT_MODE_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_inact_en_t; +int32_t lsm6ds3tr_c_act_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_inact_en_t val); +int32_t lsm6ds3tr_c_act_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_inact_en_t* val); + +int32_t lsm6ds3tr_c_act_sleep_dur_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_act_sleep_dur_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_tap_src_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_tap_src_t* val); + +int32_t lsm6ds3tr_c_tap_detection_on_z_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_tap_detection_on_z_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_tap_detection_on_y_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_tap_detection_on_y_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_tap_detection_on_x_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_tap_detection_on_x_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_tap_threshold_x_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_tap_threshold_x_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_tap_shock_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_tap_shock_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_tap_quiet_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_tap_quiet_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_tap_dur_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_tap_dur_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_ONLY_SINGLE = 0, + LSM6DS3TR_C_BOTH_SINGLE_DOUBLE = 1, + LSM6DS3TR_C_TAP_MODE_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_single_double_tap_t; +int32_t lsm6ds3tr_c_tap_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_single_double_tap_t val); +int32_t lsm6ds3tr_c_tap_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_single_double_tap_t* val); + +typedef enum { + LSM6DS3TR_C_ODR_DIV_2_FEED = 0, + LSM6DS3TR_C_LPF2_FEED = 1, + LSM6DS3TR_C_6D_FEED_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_low_pass_on_6d_t; +int32_t lsm6ds3tr_c_6d_feed_data_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_low_pass_on_6d_t val); +int32_t lsm6ds3tr_c_6d_feed_data_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_low_pass_on_6d_t* val); + +typedef enum { + LSM6DS3TR_C_DEG_80 = 0, + LSM6DS3TR_C_DEG_70 = 1, + LSM6DS3TR_C_DEG_60 = 2, + LSM6DS3TR_C_DEG_50 = 3, + LSM6DS3TR_C_6D_TH_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_sixd_ths_t; +int32_t lsm6ds3tr_c_6d_threshold_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_sixd_ths_t val); +int32_t lsm6ds3tr_c_6d_threshold_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_sixd_ths_t* val); + +int32_t lsm6ds3tr_c_4d_mode_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_4d_mode_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_ff_dur_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_ff_dur_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_FF_TSH_156mg = 0, + LSM6DS3TR_C_FF_TSH_219mg = 1, + LSM6DS3TR_C_FF_TSH_250mg = 2, + LSM6DS3TR_C_FF_TSH_312mg = 3, + LSM6DS3TR_C_FF_TSH_344mg = 4, + LSM6DS3TR_C_FF_TSH_406mg = 5, + LSM6DS3TR_C_FF_TSH_469mg = 6, + LSM6DS3TR_C_FF_TSH_500mg = 7, + LSM6DS3TR_C_FF_TSH_ND = 8, /* ERROR CODE */ +} lsm6ds3tr_c_ff_ths_t; +int32_t lsm6ds3tr_c_ff_threshold_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_ff_ths_t val); +int32_t lsm6ds3tr_c_ff_threshold_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_ff_ths_t* val); + +int32_t lsm6ds3tr_c_fifo_watermark_set(stmdev_ctx_t* ctx, uint16_t val); +int32_t lsm6ds3tr_c_fifo_watermark_get(stmdev_ctx_t* ctx, uint16_t* val); + +int32_t lsm6ds3tr_c_fifo_data_level_get(stmdev_ctx_t* ctx, uint16_t* val); + +int32_t lsm6ds3tr_c_fifo_wtm_flag_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_fifo_pattern_get(stmdev_ctx_t* ctx, uint16_t* val); + +int32_t lsm6ds3tr_c_fifo_temp_batch_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_fifo_temp_batch_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_TRG_XL_GY_DRDY = 0, + LSM6DS3TR_C_TRG_STEP_DETECT = 1, + LSM6DS3TR_C_TRG_SH_DRDY = 2, + LSM6DS3TR_C_TRG_SH_ND = 3, /* ERROR CODE */ +} lsm6ds3tr_c_trigger_fifo_t; +int32_t lsm6ds3tr_c_fifo_write_trigger_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_trigger_fifo_t val); +int32_t lsm6ds3tr_c_fifo_write_trigger_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_trigger_fifo_t* val); + +int32_t lsm6ds3tr_c_fifo_pedo_and_timestamp_batch_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_fifo_pedo_and_timestamp_batch_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_FIFO_XL_DISABLE = 0, + LSM6DS3TR_C_FIFO_XL_NO_DEC = 1, + LSM6DS3TR_C_FIFO_XL_DEC_2 = 2, + LSM6DS3TR_C_FIFO_XL_DEC_3 = 3, + LSM6DS3TR_C_FIFO_XL_DEC_4 = 4, + LSM6DS3TR_C_FIFO_XL_DEC_8 = 5, + LSM6DS3TR_C_FIFO_XL_DEC_16 = 6, + LSM6DS3TR_C_FIFO_XL_DEC_32 = 7, + LSM6DS3TR_C_FIFO_XL_DEC_ND = 8, /* ERROR CODE */ +} lsm6ds3tr_c_dec_fifo_xl_t; +int32_t lsm6ds3tr_c_fifo_xl_batch_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_fifo_xl_t val); +int32_t lsm6ds3tr_c_fifo_xl_batch_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_fifo_xl_t* val); + +typedef enum { + LSM6DS3TR_C_FIFO_GY_DISABLE = 0, + LSM6DS3TR_C_FIFO_GY_NO_DEC = 1, + LSM6DS3TR_C_FIFO_GY_DEC_2 = 2, + LSM6DS3TR_C_FIFO_GY_DEC_3 = 3, + LSM6DS3TR_C_FIFO_GY_DEC_4 = 4, + LSM6DS3TR_C_FIFO_GY_DEC_8 = 5, + LSM6DS3TR_C_FIFO_GY_DEC_16 = 6, + LSM6DS3TR_C_FIFO_GY_DEC_32 = 7, + LSM6DS3TR_C_FIFO_GY_DEC_ND = 8, /* ERROR CODE */ +} lsm6ds3tr_c_dec_fifo_gyro_t; +int32_t lsm6ds3tr_c_fifo_gy_batch_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_fifo_gyro_t val); +int32_t lsm6ds3tr_c_fifo_gy_batch_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_fifo_gyro_t* val); + +typedef enum { + LSM6DS3TR_C_FIFO_DS3_DISABLE = 0, + LSM6DS3TR_C_FIFO_DS3_NO_DEC = 1, + LSM6DS3TR_C_FIFO_DS3_DEC_2 = 2, + LSM6DS3TR_C_FIFO_DS3_DEC_3 = 3, + LSM6DS3TR_C_FIFO_DS3_DEC_4 = 4, + LSM6DS3TR_C_FIFO_DS3_DEC_8 = 5, + LSM6DS3TR_C_FIFO_DS3_DEC_16 = 6, + LSM6DS3TR_C_FIFO_DS3_DEC_32 = 7, + LSM6DS3TR_C_FIFO_DS3_DEC_ND = 8, /* ERROR CODE */ +} lsm6ds3tr_c_dec_ds3_fifo_t; +int32_t lsm6ds3tr_c_fifo_dataset_3_batch_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_ds3_fifo_t val); +int32_t lsm6ds3tr_c_fifo_dataset_3_batch_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_ds3_fifo_t* val); + +typedef enum { + LSM6DS3TR_C_FIFO_DS4_DISABLE = 0, + LSM6DS3TR_C_FIFO_DS4_NO_DEC = 1, + LSM6DS3TR_C_FIFO_DS4_DEC_2 = 2, + LSM6DS3TR_C_FIFO_DS4_DEC_3 = 3, + LSM6DS3TR_C_FIFO_DS4_DEC_4 = 4, + LSM6DS3TR_C_FIFO_DS4_DEC_8 = 5, + LSM6DS3TR_C_FIFO_DS4_DEC_16 = 6, + LSM6DS3TR_C_FIFO_DS4_DEC_32 = 7, + LSM6DS3TR_C_FIFO_DS4_DEC_ND = 8, /* ERROR CODE */ +} lsm6ds3tr_c_dec_ds4_fifo_t; +int32_t lsm6ds3tr_c_fifo_dataset_4_batch_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_ds4_fifo_t val); +int32_t lsm6ds3tr_c_fifo_dataset_4_batch_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_ds4_fifo_t* val); + +int32_t lsm6ds3tr_c_fifo_xl_gy_8bit_format_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_fifo_xl_gy_8bit_format_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_fifo_stop_on_wtm_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_fifo_stop_on_wtm_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_BYPASS_MODE = 0, + LSM6DS3TR_C_FIFO_MODE = 1, + LSM6DS3TR_C_STREAM_TO_FIFO_MODE = 3, + LSM6DS3TR_C_BYPASS_TO_STREAM_MODE = 4, + LSM6DS3TR_C_STREAM_MODE = 6, + LSM6DS3TR_C_FIFO_MODE_ND = 8, /* ERROR CODE */ +} lsm6ds3tr_c_fifo_mode_t; +int32_t lsm6ds3tr_c_fifo_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_fifo_mode_t val); +int32_t lsm6ds3tr_c_fifo_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_fifo_mode_t* val); + +typedef enum { + LSM6DS3TR_C_FIFO_DISABLE = 0, + LSM6DS3TR_C_FIFO_12Hz5 = 1, + LSM6DS3TR_C_FIFO_26Hz = 2, + LSM6DS3TR_C_FIFO_52Hz = 3, + LSM6DS3TR_C_FIFO_104Hz = 4, + LSM6DS3TR_C_FIFO_208Hz = 5, + LSM6DS3TR_C_FIFO_416Hz = 6, + LSM6DS3TR_C_FIFO_833Hz = 7, + LSM6DS3TR_C_FIFO_1k66Hz = 8, + LSM6DS3TR_C_FIFO_3k33Hz = 9, + LSM6DS3TR_C_FIFO_6k66Hz = 10, + LSM6DS3TR_C_FIFO_RATE_ND = 11, /* ERROR CODE */ +} lsm6ds3tr_c_odr_fifo_t; +int32_t lsm6ds3tr_c_fifo_data_rate_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_fifo_t val); +int32_t lsm6ds3tr_c_fifo_data_rate_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_fifo_t* val); + +typedef enum { + LSM6DS3TR_C_DEN_ACT_LOW = 0, + LSM6DS3TR_C_DEN_ACT_HIGH = 1, + LSM6DS3TR_C_DEN_POL_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_den_lh_t; +int32_t lsm6ds3tr_c_den_polarity_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_lh_t val); +int32_t lsm6ds3tr_c_den_polarity_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_lh_t* val); + +typedef enum { + LSM6DS3TR_C_DEN_DISABLE = 0, + LSM6DS3TR_C_LEVEL_FIFO = 6, + LSM6DS3TR_C_LEVEL_LETCHED = 3, + LSM6DS3TR_C_LEVEL_TRIGGER = 2, + LSM6DS3TR_C_EDGE_TRIGGER = 4, + LSM6DS3TR_C_DEN_MODE_ND = 5, /* ERROR CODE */ +} lsm6ds3tr_c_den_mode_t; +int32_t lsm6ds3tr_c_den_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_mode_t val); +int32_t lsm6ds3tr_c_den_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_mode_t* val); + +typedef enum { + LSM6DS3TR_C_STAMP_IN_GY_DATA = 0, + LSM6DS3TR_C_STAMP_IN_XL_DATA = 1, + LSM6DS3TR_C_STAMP_IN_GY_XL_DATA = 2, + LSM6DS3TR_C_DEN_STAMP_ND = 3, /* ERROR CODE */ +} lsm6ds3tr_c_den_xl_en_t; +int32_t lsm6ds3tr_c_den_enable_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_xl_en_t val); +int32_t lsm6ds3tr_c_den_enable_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_xl_en_t* val); + +int32_t lsm6ds3tr_c_den_mark_axis_z_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_den_mark_axis_z_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_den_mark_axis_y_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_den_mark_axis_y_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_den_mark_axis_x_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_den_mark_axis_x_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_pedo_step_reset_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_pedo_step_reset_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_pedo_sens_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_pedo_sens_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_pedo_threshold_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_pedo_threshold_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_PEDO_AT_2g = 0, + LSM6DS3TR_C_PEDO_AT_4g = 1, + LSM6DS3TR_C_PEDO_FS_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_pedo_fs_t; +int32_t lsm6ds3tr_c_pedo_full_scale_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_pedo_fs_t val); +int32_t lsm6ds3tr_c_pedo_full_scale_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_pedo_fs_t* val); + +int32_t lsm6ds3tr_c_pedo_debounce_steps_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_pedo_debounce_steps_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_pedo_timeout_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_pedo_timeout_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_pedo_steps_period_set(stmdev_ctx_t* ctx, uint8_t* buff); +int32_t lsm6ds3tr_c_pedo_steps_period_get(stmdev_ctx_t* ctx, uint8_t* buff); + +int32_t lsm6ds3tr_c_motion_sens_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_motion_sens_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_motion_threshold_set(stmdev_ctx_t* ctx, uint8_t* buff); +int32_t lsm6ds3tr_c_motion_threshold_get(stmdev_ctx_t* ctx, uint8_t* buff); + +int32_t lsm6ds3tr_c_tilt_sens_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_tilt_sens_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_wrist_tilt_sens_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_wrist_tilt_sens_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_tilt_latency_set(stmdev_ctx_t* ctx, uint8_t* buff); +int32_t lsm6ds3tr_c_tilt_latency_get(stmdev_ctx_t* ctx, uint8_t* buff); + +int32_t lsm6ds3tr_c_tilt_threshold_set(stmdev_ctx_t* ctx, uint8_t* buff); +int32_t lsm6ds3tr_c_tilt_threshold_get(stmdev_ctx_t* ctx, uint8_t* buff); + +int32_t lsm6ds3tr_c_tilt_src_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_a_wrist_tilt_mask_t* val); +int32_t lsm6ds3tr_c_tilt_src_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_a_wrist_tilt_mask_t* val); + +int32_t lsm6ds3tr_c_mag_soft_iron_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_mag_soft_iron_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_mag_hard_iron_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_mag_hard_iron_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_mag_soft_iron_mat_set(stmdev_ctx_t* ctx, uint8_t* buff); +int32_t lsm6ds3tr_c_mag_soft_iron_mat_get(stmdev_ctx_t* ctx, uint8_t* buff); + +int32_t lsm6ds3tr_c_mag_offset_set(stmdev_ctx_t* ctx, int16_t* val); +int32_t lsm6ds3tr_c_mag_offset_get(stmdev_ctx_t* ctx, int16_t* val); + +int32_t lsm6ds3tr_c_func_en_set(stmdev_ctx_t* ctx, uint8_t val); + +int32_t lsm6ds3tr_c_sh_sync_sens_frame_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_sh_sync_sens_frame_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_RES_RATIO_2_11 = 0, + LSM6DS3TR_C_RES_RATIO_2_12 = 1, + LSM6DS3TR_C_RES_RATIO_2_13 = 2, + LSM6DS3TR_C_RES_RATIO_2_14 = 3, + LSM6DS3TR_C_RES_RATIO_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_rr_t; +int32_t lsm6ds3tr_c_sh_sync_sens_ratio_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_rr_t val); +int32_t lsm6ds3tr_c_sh_sync_sens_ratio_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_rr_t* val); + +int32_t lsm6ds3tr_c_sh_master_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_sh_master_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_sh_pass_through_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_sh_pass_through_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_EXT_PULL_UP = 0, + LSM6DS3TR_C_INTERNAL_PULL_UP = 1, + LSM6DS3TR_C_SH_PIN_MODE = 2, /* ERROR CODE */ +} lsm6ds3tr_c_pull_up_en_t; +int32_t lsm6ds3tr_c_sh_pin_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_pull_up_en_t val); +int32_t lsm6ds3tr_c_sh_pin_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_pull_up_en_t* val); + +typedef enum { + LSM6DS3TR_C_XL_GY_DRDY = 0, + LSM6DS3TR_C_EXT_ON_INT2_PIN = 1, + LSM6DS3TR_C_SH_SYNCRO_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_start_config_t; +int32_t lsm6ds3tr_c_sh_syncro_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_start_config_t val); +int32_t lsm6ds3tr_c_sh_syncro_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_start_config_t* val); + +int32_t lsm6ds3tr_c_sh_drdy_on_int1_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_sh_drdy_on_int1_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef struct { + lsm6ds3tr_c_sensorhub1_reg_t sh_byte_1; + lsm6ds3tr_c_sensorhub2_reg_t sh_byte_2; + lsm6ds3tr_c_sensorhub3_reg_t sh_byte_3; + lsm6ds3tr_c_sensorhub4_reg_t sh_byte_4; + lsm6ds3tr_c_sensorhub5_reg_t sh_byte_5; + lsm6ds3tr_c_sensorhub6_reg_t sh_byte_6; + lsm6ds3tr_c_sensorhub7_reg_t sh_byte_7; + lsm6ds3tr_c_sensorhub8_reg_t sh_byte_8; + lsm6ds3tr_c_sensorhub9_reg_t sh_byte_9; + lsm6ds3tr_c_sensorhub10_reg_t sh_byte_10; + lsm6ds3tr_c_sensorhub11_reg_t sh_byte_11; + lsm6ds3tr_c_sensorhub12_reg_t sh_byte_12; + lsm6ds3tr_c_sensorhub13_reg_t sh_byte_13; + lsm6ds3tr_c_sensorhub14_reg_t sh_byte_14; + lsm6ds3tr_c_sensorhub15_reg_t sh_byte_15; + lsm6ds3tr_c_sensorhub16_reg_t sh_byte_16; + lsm6ds3tr_c_sensorhub17_reg_t sh_byte_17; + lsm6ds3tr_c_sensorhub18_reg_t sh_byte_18; +} lsm6ds3tr_c_emb_sh_read_t; +int32_t lsm6ds3tr_c_sh_read_data_raw_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_emb_sh_read_t* val); + +int32_t lsm6ds3tr_c_sh_cmd_sens_sync_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_sh_cmd_sens_sync_get(stmdev_ctx_t* ctx, uint8_t* val); + +int32_t lsm6ds3tr_c_sh_spi_sync_error_set(stmdev_ctx_t* ctx, uint8_t val); +int32_t lsm6ds3tr_c_sh_spi_sync_error_get(stmdev_ctx_t* ctx, uint8_t* val); + +typedef enum { + LSM6DS3TR_C_SLV_0 = 0, + LSM6DS3TR_C_SLV_0_1 = 1, + LSM6DS3TR_C_SLV_0_1_2 = 2, + LSM6DS3TR_C_SLV_0_1_2_3 = 3, + LSM6DS3TR_C_SLV_EN_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_aux_sens_on_t; +int32_t lsm6ds3tr_c_sh_num_of_dev_connected_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_aux_sens_on_t val); +int32_t lsm6ds3tr_c_sh_num_of_dev_connected_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_aux_sens_on_t* val); + +typedef struct { + uint8_t slv0_add; + uint8_t slv0_subadd; + uint8_t slv0_data; +} lsm6ds3tr_c_sh_cfg_write_t; +int32_t lsm6ds3tr_c_sh_cfg_write(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_write_t* val); + +typedef struct { + uint8_t slv_add; + uint8_t slv_subadd; + uint8_t slv_len; +} lsm6ds3tr_c_sh_cfg_read_t; +int32_t lsm6ds3tr_c_sh_slv0_cfg_read(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_read_t* val); +int32_t lsm6ds3tr_c_sh_slv1_cfg_read(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_read_t* val); +int32_t lsm6ds3tr_c_sh_slv2_cfg_read(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_read_t* val); +int32_t lsm6ds3tr_c_sh_slv3_cfg_read(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_read_t* val); + +typedef enum { + LSM6DS3TR_C_SL0_NO_DEC = 0, + LSM6DS3TR_C_SL0_DEC_2 = 1, + LSM6DS3TR_C_SL0_DEC_4 = 2, + LSM6DS3TR_C_SL0_DEC_8 = 3, + LSM6DS3TR_C_SL0_DEC_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_slave0_rate_t; +int32_t lsm6ds3tr_c_sh_slave_0_dec_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave0_rate_t val); +int32_t lsm6ds3tr_c_sh_slave_0_dec_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave0_rate_t* val); + +typedef enum { + LSM6DS3TR_C_EACH_SH_CYCLE = 0, + LSM6DS3TR_C_ONLY_FIRST_CYCLE = 1, + LSM6DS3TR_C_SH_WR_MODE_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_write_once_t; +int32_t lsm6ds3tr_c_sh_write_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_write_once_t val); +int32_t lsm6ds3tr_c_sh_write_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_write_once_t* val); + +typedef enum { + LSM6DS3TR_C_SL1_NO_DEC = 0, + LSM6DS3TR_C_SL1_DEC_2 = 1, + LSM6DS3TR_C_SL1_DEC_4 = 2, + LSM6DS3TR_C_SL1_DEC_8 = 3, + LSM6DS3TR_C_SL1_DEC_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_slave1_rate_t; +int32_t lsm6ds3tr_c_sh_slave_1_dec_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave1_rate_t val); +int32_t lsm6ds3tr_c_sh_slave_1_dec_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave1_rate_t* val); + +typedef enum { + LSM6DS3TR_C_SL2_NO_DEC = 0, + LSM6DS3TR_C_SL2_DEC_2 = 1, + LSM6DS3TR_C_SL2_DEC_4 = 2, + LSM6DS3TR_C_SL2_DEC_8 = 3, + LSM6DS3TR_C_SL2_DEC_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_slave2_rate_t; +int32_t lsm6ds3tr_c_sh_slave_2_dec_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave2_rate_t val); +int32_t lsm6ds3tr_c_sh_slave_2_dec_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave2_rate_t* val); + +typedef enum { + LSM6DS3TR_C_SL3_NO_DEC = 0, + LSM6DS3TR_C_SL3_DEC_2 = 1, + LSM6DS3TR_C_SL3_DEC_4 = 2, + LSM6DS3TR_C_SL3_DEC_8 = 3, + LSM6DS3TR_C_SL3_DEC_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_slave3_rate_t; +int32_t lsm6ds3tr_c_sh_slave_3_dec_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave3_rate_t val); +int32_t lsm6ds3tr_c_sh_slave_3_dec_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave3_rate_t* val); + +/** + * @} + * + */ + +#ifdef __cplusplus +} +#endif + +#endif /* LSM6DS3TR_C_DRIVER_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/main_loop.cc b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/main_loop.cc new file mode 100644 index 000000000..2caffb717 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/main_loop.cc @@ -0,0 +1,189 @@ +#include "main_loop.h" + +#include +#include + +#include "imu/imu.h" +#include "orientation_tracker.h" +#include "calibration_data.h" + +#define TAG "tracker" + +static const float CURSOR_SPEED = 1024.0 / (M_PI / 4); +static const float STABILIZE_BIAS = 16.0; + +float g_yaw = 0; +float g_pitch = 0; +float g_dYaw = 0; +float g_dPitch = 0; +bool firstRead = true; +bool stabilize = true; +CalibrationData calibration; +cardboard::OrientationTracker tracker(10000000l); // 10 ms / 100 Hz +uint64_t ippms, ippms2; + +static inline float clamp(float val) +{ + while (val <= -M_PI) { + val += 2 * M_PI; + } + while (val >= M_PI) { + val -= 2 * M_PI; + } + return val; +} + +static inline float highpass(float oldVal, float newVal) +{ + if (!stabilize) { + return newVal; + } + float delta = clamp(oldVal - newVal); + float alpha = (float) std::max(0.0, 1 - std::pow(std::fabs(delta) * CURSOR_SPEED / STABILIZE_BIAS, 3.0)); + return newVal + alpha * delta; +} + +void sendCurrentState(MouseMoveCallback mouse_move, void *context) +{ + float dX = g_dYaw * CURSOR_SPEED; + float dY = g_dPitch * CURSOR_SPEED; + + // Scale the shift down to fit the protocol. + if (dX > 127) { + dY *= 127.0 / dX; + dX = 127; + } + if (dX < -127) { + dY *= -127.0 / dX; + dX = -127; + } + if (dY > 127) { + dX *= 127.0 / dY; + dY = 127; + } + if (dY < -127) { + dX *= -127.0 / dY; + dY = -127; + } + + const int8_t x = (int8_t)std::floor(dX + 0.5); + const int8_t y = (int8_t)std::floor(dY + 0.5); + + mouse_move(x, y, context); + + // Only subtract the part of the error that was already sent. + if (x != 0) { + g_dYaw -= x / CURSOR_SPEED; + } + if (y != 0) { + g_dPitch -= y / CURSOR_SPEED; + } +} + +void onOrientation(cardboard::Vector4& quaternion) +{ + float q1 = quaternion[0]; // X * sin(T/2) + float q2 = quaternion[1]; // Y * sin(T/2) + float q3 = quaternion[2]; // Z * sin(T/2) + float q0 = quaternion[3]; // cos(T/2) + + float yaw = std::atan2(2 * (q0 * q3 - q1 * q2), (1 - 2 * (q1 * q1 + q3 * q3))); + float pitch = std::asin(2 * (q0 * q1 + q2 * q3)); + // float roll = std::atan2(2 * (q0 * q2 - q1 * q3), (1 - 2 * (q1 * q1 + q2 * q2))); + + if (yaw == NAN || pitch == NAN) { + // NaN case, skip it + return; + } + + if (firstRead) { + g_yaw = yaw; + g_pitch = pitch; + firstRead = false; + } else { + const float newYaw = highpass(g_yaw, yaw); + const float newPitch = highpass(g_pitch, pitch); + + float dYaw = clamp(g_yaw - newYaw); + float dPitch = g_pitch - newPitch; + g_yaw = newYaw; + g_pitch = newPitch; + + // Accumulate the error locally. + g_dYaw += dYaw; + g_dPitch += dPitch; + } +} + +extern "C" { + +void calibration_begin() { + calibration.reset(); + FURI_LOG_I(TAG, "Calibrating"); +} + +bool calibration_step() { + if (calibration.isComplete()) + return true; + + double vec[6]; + if (imu_read(vec) & GYR_DATA_READY) { + cardboard::Vector3 data(vec[3], vec[4], vec[5]); + furi_delay_ms(9); // Artificially limit to ~100Hz + return calibration.add(data); + } + + return false; +} + +void calibration_end() { + CalibrationMedian store; + cardboard::Vector3 median = calibration.getMedian(); + store.x = median[0]; + store.y = median[1]; + store.z = median[2]; + CALIBRATION_DATA_SAVE(&store); +} + +void tracking_begin() { + CalibrationMedian store; + cardboard::Vector3 median = calibration.getMedian(); + if (CALIBRATION_DATA_LOAD(&store)) { + median[0] = store.x; + median[1] = store.y; + median[2] = store.z; + } + + ippms = furi_hal_cortex_instructions_per_microsecond(); + ippms2 = ippms / 2; + tracker.SetCalibration(median); + tracker.Resume(); +} + +void tracking_step(MouseMoveCallback mouse_move, void *context) { + double vec[6]; + int ret = imu_read(vec); + if (ret != 0) { + uint64_t t = (DWT->CYCCNT * 1000llu + ippms2) / ippms; + if (ret & ACC_DATA_READY) { + cardboard::AccelerometerData adata + = { .system_timestamp = t, .sensor_timestamp_ns = t, + .data = cardboard::Vector3(vec[0], vec[1], vec[2]) }; + tracker.OnAccelerometerData(adata); + } + if (ret & GYR_DATA_READY) { + cardboard::GyroscopeData gdata + = { .system_timestamp = t, .sensor_timestamp_ns = t, + .data = cardboard::Vector3(vec[3], vec[4], vec[5]) }; + cardboard::Vector4 pose = tracker.OnGyroscopeData(gdata); + onOrientation(pose); + sendCurrentState(mouse_move, context); + } + } +} + +void tracking_end() { + tracker.Pause(); +} + +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/main_loop.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/main_loop.h new file mode 100644 index 000000000..cd592161f --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/main_loop.h @@ -0,0 +1,21 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef bool (*MouseMoveCallback)(int8_t x, int8_t y, void* context); + +void calibration_begin(); +bool calibration_step(); +void calibration_end(); + +void tracking_begin(); +void tracking_step(MouseMoveCallback mouse_move, void* context); +void tracking_end(); + +#ifdef __cplusplus +} +#endif diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/orientation_tracker.cc b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/orientation_tracker.cc new file mode 100644 index 000000000..ac20e9672 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/orientation_tracker.cc @@ -0,0 +1,95 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "orientation_tracker.h" + +#include "sensors/pose_prediction.h" +#include "util/logging.h" +#include "util/vector.h" +#include "util/vectorutils.h" + +namespace cardboard { + +OrientationTracker::OrientationTracker(const long sampling_period_ns) + : sampling_period_ns_(sampling_period_ns) + , calibration_(Vector3::Zero()) + , is_tracking_(false) + , sensor_fusion_(new SensorFusionEkf()) + , latest_gyroscope_data_({ 0, 0, Vector3::Zero() }) +{ + sensor_fusion_->SetBiasEstimationEnabled(/*kGyroBiasEstimationEnabled*/ true); +} + +void OrientationTracker::SetCalibration(const Vector3& calibration) { + calibration_ = calibration; +} + +void OrientationTracker::Pause() +{ + if (!is_tracking_) { + return; + } + + // Create a gyro event with zero velocity. This effectively stops the prediction. + GyroscopeData event = latest_gyroscope_data_; + event.data = Vector3::Zero(); + + OnGyroscopeData(event); + + is_tracking_ = false; +} + +void OrientationTracker::Resume() { is_tracking_ = true; } + +Vector4 OrientationTracker::GetPose(int64_t timestamp_ns) const +{ + Rotation predicted_rotation; + const PoseState pose_state = sensor_fusion_->GetLatestPoseState(); + if (sensor_fusion_->IsFullyInitialized()) { + predicted_rotation = pose_state.sensor_from_start_rotation; + } else { + CARDBOARD_LOGI("Tracker not fully initialized yet. Using pose prediction only."); + predicted_rotation = pose_prediction::PredictPose(timestamp_ns, pose_state); + } + + return (-predicted_rotation).GetQuaternion(); +} + +void OrientationTracker::OnAccelerometerData(const AccelerometerData& event) +{ + if (!is_tracking_) { + return; + } + sensor_fusion_->ProcessAccelerometerSample(event); +} + +Vector4 OrientationTracker::OnGyroscopeData(const GyroscopeData& event) +{ + if (!is_tracking_) { + return Vector4(); + } + + const GyroscopeData data = { .system_timestamp = event.system_timestamp, + .sensor_timestamp_ns = event.sensor_timestamp_ns, + .data = event.data - calibration_ }; + + latest_gyroscope_data_ = data; + + sensor_fusion_->ProcessGyroscopeSample(data); + + return OrientationTracker::GetPose(data.sensor_timestamp_ns + sampling_period_ns_); +} + +} // namespace cardboard diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/orientation_tracker.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/orientation_tracker.h new file mode 100644 index 000000000..fb49c9859 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/orientation_tracker.h @@ -0,0 +1,68 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include +#include // NOLINT + +#include "sensors/accelerometer_data.h" +#include "sensors/gyroscope_data.h" +#include "sensors/sensor_fusion_ekf.h" +#include "util/rotation.h" + +namespace cardboard { + +// OrientationTracker encapsulates pose tracking by connecting sensors +// to SensorFusion. +// This pose tracker reports poses in display space. +class OrientationTracker { +public: + OrientationTracker(const long sampling_period_ns); + + void SetCalibration(const Vector3& calibration); + + // Pauses tracking and sensors. + void Pause(); + + // Resumes tracking ans sensors. + void Resume(); + + // Gets the predicted pose for a given timestamp. + Vector4 GetPose(int64_t timestamp_ns) const; + + // Function called when receiving AccelerometerData. + // + // @param event sensor event. + void OnAccelerometerData(const AccelerometerData& event); + + // Function called when receiving GyroscopeData. + // + // @param event sensor event. + Vector4 OnGyroscopeData(const GyroscopeData& event); + +private: + long sampling_period_ns_; + Vector3 calibration_; + + std::atomic is_tracking_; + // Sensor Fusion object that stores the internal state of the filter. + std::unique_ptr sensor_fusion_; + // Latest gyroscope data. + GyroscopeData latest_gyroscope_data_; +}; + +} // namespace cardboard diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/accelerometer_data.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/accelerometer_data.h new file mode 100644 index 000000000..bdf3289af --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/accelerometer_data.h @@ -0,0 +1,38 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CARDBOARD_SDK_SENSORS_ACCELEROMETER_DATA_H_ +#define CARDBOARD_SDK_SENSORS_ACCELEROMETER_DATA_H_ + +#include "../util/vector.h" + +namespace cardboard { + +struct AccelerometerData { + // System wall time. + uint64_t system_timestamp; + + // Sensor clock time in nanoseconds. + uint64_t sensor_timestamp_ns; + + // Acceleration force along the x,y,z axes in m/s^2. This follows android + // specification + // (https://developer.android.com/guide/topics/sensors/sensors_overview.html#sensors-coords). + Vector3 data; +}; + +} // namespace cardboard + +#endif // CARDBOARD_SDK_SENSORS_ACCELEROMETER_DATA_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/gyroscope_bias_estimator.cc b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/gyroscope_bias_estimator.cc new file mode 100644 index 000000000..96f2f7346 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/gyroscope_bias_estimator.cc @@ -0,0 +1,313 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "gyroscope_bias_estimator.h" + +#include +#include // NOLINT + +#include "../util/rotation.h" +#include "../util/vector.h" + +namespace { + +// Cutoff frequencies in Hertz applied to our various signals, and their +// corresponding filters. +const float kAccelerometerLowPassCutOffFrequencyHz = 1.0f; +const float kRotationVelocityBasedAccelerometerLowPassCutOffFrequencyHz = 0.15f; +const float kGyroscopeLowPassCutOffFrequencyHz = 1.0f; +const float kGyroscopeBiasLowPassCutOffFrequencyHz = 0.15f; + +// Note that MEMS IMU are not that precise. +const double kEpsilon = 1.0e-8; + +// Size of the filtering window for the mean and median filter. The larger the +// windows the larger the filter delay. +const int kFilterWindowSize = 5; + +// Threshold used to compare rotation computed from the accelerometer and the +// gyroscope bias. +const double kRatioBetweenGyroBiasAndAccel = 1.5; + +// The minimum sum of weights we need to acquire before returning a bias +// estimation. +const float kMinSumOfWeightsGyroBiasThreshold = 25.0f; + +// Amount of change in m/s^3 we allow on the smoothed accelerometer values to +// consider the phone static. +const double kAccelerometerDeltaStaticThreshold = 0.5; + +// Amount of change in radians/s^2 we allow on the smoothed gyroscope values to +// consider the phone static. +const double kGyroscopeDeltaStaticThreshold = 0.03; + +// If the gyroscope value is above this threshold, don't update the gyroscope +// bias estimation. This threshold is applied to the magnitude of gyroscope +// vectors in radians/s. +const float kGyroscopeForBiasThreshold = 0.30f; + +// Used to monitor if accelerometer and gyroscope have been static for a few +// frames. +const int kStaticFrameDetectionThreshold = 50; + +// Minimum time step between sensor updates. +const double kMinTimestep = 1; // std::chrono::nanoseconds(1); +} // namespace + +namespace cardboard { + +// A helper class to keep track of whether some signal can be considered static +// over specified number of frames. +class GyroscopeBiasEstimator::IsStaticCounter { +public: + // Initializes a counter with the number of consecutive frames we require + // the signal to be static before IsRecentlyStatic returns true. + // + // @param min_static_frames_threshold number of consecutive frames we + // require the signal to be static before IsRecentlyStatic returns true. + explicit IsStaticCounter(int min_static_frames_threshold) + : min_static_frames_threshold_(min_static_frames_threshold) + , consecutive_static_frames_(0) + { + } + + // Specifies whether the current frame is considered static. + // + // @param is_static static flag for current frame. + void AppendFrame(bool is_static) + { + if (is_static) { + ++consecutive_static_frames_; + } else { + consecutive_static_frames_ = 0; + } + } + + // Returns if static movement is assumed. + bool IsRecentlyStatic() const + { + return consecutive_static_frames_ >= min_static_frames_threshold_; + } + // Resets counter. + void Reset() { consecutive_static_frames_ = 0; } + +private: + const int min_static_frames_threshold_; + int consecutive_static_frames_; +}; + +GyroscopeBiasEstimator::GyroscopeBiasEstimator() + : accelerometer_lowpass_filter_(kAccelerometerLowPassCutOffFrequencyHz) + , simulated_gyroscope_from_accelerometer_lowpass_filter_( + kRotationVelocityBasedAccelerometerLowPassCutOffFrequencyHz) + , gyroscope_lowpass_filter_(kGyroscopeLowPassCutOffFrequencyHz) + , gyroscope_bias_lowpass_filter_(kGyroscopeBiasLowPassCutOffFrequencyHz) + , accelerometer_static_counter_(new IsStaticCounter(kStaticFrameDetectionThreshold)) + , gyroscope_static_counter_(new IsStaticCounter(kStaticFrameDetectionThreshold)) + , current_accumulated_weights_gyroscope_bias_(0.f) + , mean_filter_(kFilterWindowSize) + , median_filter_(kFilterWindowSize) + , last_mean_filtered_accelerometer_value_({ 0, 0, 0 }) +{ + Reset(); +} + +GyroscopeBiasEstimator::~GyroscopeBiasEstimator() { } + +void GyroscopeBiasEstimator::Reset() +{ + accelerometer_lowpass_filter_.Reset(); + gyroscope_lowpass_filter_.Reset(); + gyroscope_bias_lowpass_filter_.Reset(); + accelerometer_static_counter_->Reset(); + gyroscope_static_counter_->Reset(); +} + +void GyroscopeBiasEstimator::ProcessGyroscope( + const Vector3& gyroscope_sample, uint64_t timestamp_ns) +{ + // Update gyroscope and gyroscope delta low-pass filters. + gyroscope_lowpass_filter_.AddSample(gyroscope_sample, timestamp_ns); + + const auto smoothed_gyroscope_delta + = gyroscope_sample - gyroscope_lowpass_filter_.GetFilteredData(); + + gyroscope_static_counter_->AppendFrame( + Length(smoothed_gyroscope_delta) < kGyroscopeDeltaStaticThreshold); + + // Only update the bias if the gyroscope and accelerometer signals have been + // relatively static recently. + if (gyroscope_static_counter_->IsRecentlyStatic() + && accelerometer_static_counter_->IsRecentlyStatic()) { + // Reset static counter when updating the bias fails. + if (!UpdateGyroscopeBias(gyroscope_sample, timestamp_ns)) { + // Bias update fails because of large motion, thus reset the static + // counter. + gyroscope_static_counter_->AppendFrame(false); + } + } else { + // Reset weights, if not static. + current_accumulated_weights_gyroscope_bias_ = 0; + } +} + +void GyroscopeBiasEstimator::ProcessAccelerometer( + const Vector3& accelerometer_sample, uint64_t timestamp_ns) +{ + // Get current state of the filter. + const uint64_t previous_accel_timestamp_ns + = accelerometer_lowpass_filter_.GetMostRecentTimestampNs(); + const bool is_low_pass_filter_init = accelerometer_lowpass_filter_.IsInitialized(); + + // Update accel and accel delta low-pass filters. + accelerometer_lowpass_filter_.AddSample(accelerometer_sample, timestamp_ns); + + const auto smoothed_accelerometer_delta + = accelerometer_sample - accelerometer_lowpass_filter_.GetFilteredData(); + + accelerometer_static_counter_->AppendFrame( + Length(smoothed_accelerometer_delta) < kAccelerometerDeltaStaticThreshold); + + // Rotation from accel cannot be differentiated with only one sample. + if (!is_low_pass_filter_init) { + simulated_gyroscope_from_accelerometer_lowpass_filter_.AddSample({ 0, 0, 0 }, timestamp_ns); + return; + } + + // No need to update the simulated gyroscope at this point because the motion + // is too large. + if (!accelerometer_static_counter_->IsRecentlyStatic()) { + return; + } + + median_filter_.AddSample(accelerometer_lowpass_filter_.GetFilteredData()); + + // This processing can only be started if the buffer is fully initialized. + if (!median_filter_.IsValid()) { + mean_filter_.AddSample(accelerometer_lowpass_filter_.GetFilteredData()); + + // Update the last filtered accelerometer value. + last_mean_filtered_accelerometer_value_ = accelerometer_lowpass_filter_.GetFilteredData(); + return; + } + + mean_filter_.AddSample(median_filter_.GetFilteredData()); + + // Compute a mock gyroscope value from accelerometer. + const int64_t diff = timestamp_ns - previous_accel_timestamp_ns; + const double timestep = static_cast(diff); + + simulated_gyroscope_from_accelerometer_lowpass_filter_.AddSample( + ComputeAngularVelocityFromLatestAccelerometer(timestep), timestamp_ns); + last_mean_filtered_accelerometer_value_ = mean_filter_.GetFilteredData(); +} + +Vector3 GyroscopeBiasEstimator::ComputeAngularVelocityFromLatestAccelerometer(double timestep) const +{ + if (timestep < kMinTimestep) { + return { 0, 0, 0 }; + } + + const auto mean_of_median = mean_filter_.GetFilteredData(); + + // Compute an incremental rotation between the last state and the current + // state. + // + // Note that we switch to double precision here because of precision problem + // with small rotation. + const auto incremental_rotation = Rotation::RotateInto( + Vector3(last_mean_filtered_accelerometer_value_[0], + last_mean_filtered_accelerometer_value_[1], last_mean_filtered_accelerometer_value_[2]), + Vector3(mean_of_median[0], mean_of_median[1], mean_of_median[2])); + + // We use axis angle here because this is how gyroscope values are stored. + Vector3 incremental_rotation_axis; + double incremental_rotation_angle; + incremental_rotation.GetAxisAndAngle(&incremental_rotation_axis, &incremental_rotation_angle); + + incremental_rotation_axis *= incremental_rotation_angle / timestep; + + return { static_cast(incremental_rotation_axis[0]), + static_cast(incremental_rotation_axis[1]), + static_cast(incremental_rotation_axis[2]) }; +} + +bool GyroscopeBiasEstimator::UpdateGyroscopeBias( + const Vector3& gyroscope_sample, uint64_t timestamp_ns) +{ + // Gyroscope values that are too big are potentially dangerous as they could + // originate from slow and steady head rotations. + // + // Therefore we compute an update weight which: + // * favors gyroscope values that are closer to 0 + // * is set to zero if gyroscope values are greater than a threshold. + // + // This way, the gyroscope bias estimation converges faster if the phone is + // flat on a table, as opposed to held up somewhat stationary in the user's + // hands. + + // If magnitude is too big, don't update the filter at all so that we don't + // artificially increase the number of samples accumulated by the filter. + const float gyroscope_sample_norm2 = Length(gyroscope_sample); + if (gyroscope_sample_norm2 >= kGyroscopeForBiasThreshold) { + return false; + } + + float update_weight + = std::max(0.0f, 1 - gyroscope_sample_norm2 / kGyroscopeForBiasThreshold); + update_weight *= update_weight; + gyroscope_bias_lowpass_filter_.AddWeightedSample( + gyroscope_lowpass_filter_.GetFilteredData(), timestamp_ns, update_weight); + + // This counter is only partially valid as the low pass filter drops large + // samples. + current_accumulated_weights_gyroscope_bias_ += update_weight; + + return true; +} + +Vector3 GyroscopeBiasEstimator::GetGyroscopeBias() const +{ + return gyroscope_bias_lowpass_filter_.GetFilteredData(); +} + +bool GyroscopeBiasEstimator::IsCurrentEstimateValid() const +{ + // Remove any bias component along the gravity because they cannot be + // evaluated from accelerometer. + const auto current_gravity_dir = Normalized(last_mean_filtered_accelerometer_value_); + const auto gyro_bias_lowpass = gyroscope_bias_lowpass_filter_.GetFilteredData(); + + const auto off_gravity_gyro_bias + = gyro_bias_lowpass - current_gravity_dir * Dot(gyro_bias_lowpass, current_gravity_dir); + + // Checks that the current bias estimate is not correlated with the + // rotation computed from accelerometer. + const auto gyro_from_accel + = simulated_gyroscope_from_accelerometer_lowpass_filter_.GetFilteredData(); + const bool isGyroscopeBiasCorrelatedWithSimulatedGyro + = (Length(gyro_from_accel) * kRatioBetweenGyroBiasAndAccel + > (Length(off_gravity_gyro_bias) + kEpsilon)); + const bool hasEnoughSamples + = current_accumulated_weights_gyroscope_bias_ > kMinSumOfWeightsGyroBiasThreshold; + const bool areCountersStatic = gyroscope_static_counter_->IsRecentlyStatic() + && accelerometer_static_counter_->IsRecentlyStatic(); + + const bool isStatic + = hasEnoughSamples && areCountersStatic && !isGyroscopeBiasCorrelatedWithSimulatedGyro; + return isStatic; +} + +} // namespace cardboard diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/gyroscope_bias_estimator.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/gyroscope_bias_estimator.h new file mode 100644 index 000000000..1a46f96be --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/gyroscope_bias_estimator.h @@ -0,0 +1,134 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CARDBOARD_SDK_SENSORS_GYROSCOPE_BIAS_ESTIMATOR_H_ +#define CARDBOARD_SDK_SENSORS_GYROSCOPE_BIAS_ESTIMATOR_H_ + +#include // NOLINT +#include +#include +#include +#include + +#include "lowpass_filter.h" +#include "mean_filter.h" +#include "median_filter.h" +#include "../util/vector.h" + +namespace cardboard { + +// Class that attempts to estimate the gyroscope's bias. +// Its main idea is that it averages the gyroscope values when the phone is +// considered stationary. +// Usage: A client should call the ProcessGyroscope and ProcessAccelerometer +// methods for every accelerometer and gyroscope sensor sample. This class +// expects these calls to be frequent, i.e., at least at 10 Hz. The client can +// then call GetGyroBias to retrieve the current estimate of the gyroscope bias. +// For best results, the fastest available delay option should be used when +// registering to sensors. Note that this class is not thread-safe. +// +// The filtering applied to the accelerometer to estimate a rotation +// from it follows : +// Baptiste Delporte, Laurent Perroton, Thierry Grandpierre, Jacques Trichet. +// Accelerometer and Magnetometer Based Gyroscope Emulation on Smart Sensor +// for a Virtual Reality Application. Sensor and Transducers Journal, 2012. +// +// which is a combination of a IIR filter, a median and a mean filter. +class GyroscopeBiasEstimator { +public: + GyroscopeBiasEstimator(); + virtual ~GyroscopeBiasEstimator(); + + // Updates the estimator with a gyroscope event. + // + // @param gyroscope_sample the angular speed around the x, y, z axis in + // radians/sec. + // @param timestamp_ns the nanosecond at which the event occurred. Only + // guaranteed to be comparable with timestamps from other PocessGyroscope + // invocations. + virtual void ProcessGyroscope(const Vector3& gyroscope_sample, uint64_t timestamp_ns); + + // Processes accelerometer samples to estimate if device is + // stable or not. + // + // First we filter the accelerometer. This is done with 3 filters. + // - A IIR low-pass filter + // - A median filter + // - A mean filter. + // Then a rotation is computed between consecutive filtered accelerometer + // samples. + // Finally this is converted to a velocity to emulate a gyroscope. + // + // @param accelerometer_sample the acceleration (including gravity) on the x, + // y, z axis in meters/s^2. + // @param timestamp_ns the nanosecond at which the event occurred. Only + // guaranteed to be comparable with timestamps from other + // ProcessAccelerometer invocations. + virtual void ProcessAccelerometer(const Vector3& accelerometer_sample, uint64_t timestamp_ns); + + // Returns the estimated gyroscope bias. + // + // @return Estimated gyroscope bias. A vector with zeros is returned if no + // estimate has been computed. + virtual Vector3 GetGyroscopeBias() const; + + // Resets the estimator state. + void Reset(); + + // Returns true if the current estimate returned by GetGyroscopeBias is + // correct. The device (measured using the sensors) has to be static for this + // function to return true. + virtual bool IsCurrentEstimateValid() const; + +private: + // A helper class to keep track of whether some signal can be considered + // static over specified number of frames. + class IsStaticCounter; + + // Updates gyroscope bias estimation. + // + // @return false if the current sample is too large. + bool UpdateGyroscopeBias(const Vector3& gyroscope_sample, uint64_t timestamp_ns); + + // Returns device angular velocity (rad/s) from the latest accelerometer data. + // + // @param timestep in seconds between the last two samples. + // @return rotation velocity from latest accelerometer. This can be + // interpreted as an gyroscope. + Vector3 ComputeAngularVelocityFromLatestAccelerometer(double timestep) const; + + LowpassFilter accelerometer_lowpass_filter_; + LowpassFilter simulated_gyroscope_from_accelerometer_lowpass_filter_; + LowpassFilter gyroscope_lowpass_filter_; + LowpassFilter gyroscope_bias_lowpass_filter_; + + std::unique_ptr accelerometer_static_counter_; + std::unique_ptr gyroscope_static_counter_; + + // Sum of the weight of sample used for gyroscope filtering. + float current_accumulated_weights_gyroscope_bias_; + + // Set of filters for accelerometer data to estimate a rotation + // based only on accelerometer. + MeanFilter mean_filter_; + MedianFilter median_filter_; + + // Last computed filter accelerometer value used for finite differences. + Vector3 last_mean_filtered_accelerometer_value_; +}; + +} // namespace cardboard + +#endif // CARDBOARD_SDK_SENSORS_GYROSCOPE_BIAS_ESTIMATOR_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/gyroscope_data.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/gyroscope_data.h new file mode 100644 index 000000000..085e85209 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/gyroscope_data.h @@ -0,0 +1,38 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CARDBOARD_SDK_SENSORS_GYROSCOPE_DATA_H_ +#define CARDBOARD_SDK_SENSORS_GYROSCOPE_DATA_H_ + +#include "../util/vector.h" + +namespace cardboard { + +struct GyroscopeData { + // System wall time. + uint64_t system_timestamp; + + // Sensor clock time in nanoseconds. + uint64_t sensor_timestamp_ns; + + // Rate of rotation around the x,y,z axes in rad/s. This follows android + // specification + // (https://developer.android.com/guide/topics/sensors/sensors_overview.html#sensors-coords). + Vector3 data; +}; + +} // namespace cardboard + +#endif // CARDBOARD_SDK_SENSORS_GYROSCOPE_DATA_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/lowpass_filter.cc b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/lowpass_filter.cc new file mode 100644 index 000000000..efadfbf4e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/lowpass_filter.cc @@ -0,0 +1,84 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "lowpass_filter.h" + +#include + +namespace { + +const double kSecondsFromNanoseconds = 1.0e-9; + +// Minimum time step between sensor updates. This corresponds to 1000 Hz. +const double kMinTimestepS = 0.001f; + +// Maximum time step between sensor updates. This corresponds to 1 Hz. +const double kMaxTimestepS = 1.00f; + +} // namespace + +namespace cardboard { + +LowpassFilter::LowpassFilter(double cutoff_freq_hz) + : cutoff_time_constant_(1 / (2 * (double)M_PI * cutoff_freq_hz)) + , initialized_(false) +{ + Reset(); +} + +void LowpassFilter::AddSample(const Vector3& sample, uint64_t timestamp_ns) +{ + AddWeightedSample(sample, timestamp_ns, 1.0); +} + +void LowpassFilter::AddWeightedSample(const Vector3& sample, uint64_t timestamp_ns, double weight) +{ + if (!initialized_) { + // Initialize filter state + filtered_data_ = { sample[0], sample[1], sample[2] }; + timestamp_most_recent_update_ns_ = timestamp_ns; + initialized_ = true; + return; + } + + if (timestamp_ns < timestamp_most_recent_update_ns_) { + timestamp_most_recent_update_ns_ = timestamp_ns; + return; + } + + const double delta_s = static_cast(timestamp_ns - timestamp_most_recent_update_ns_) + * kSecondsFromNanoseconds; + if (delta_s <= kMinTimestepS || delta_s > kMaxTimestepS) { + timestamp_most_recent_update_ns_ = timestamp_ns; + return; + } + + const double weighted_delta_secs = weight * delta_s; + + const double alpha = weighted_delta_secs / (cutoff_time_constant_ + weighted_delta_secs); + + for (int i = 0; i < 3; ++i) { + filtered_data_[i] = (1 - alpha) * filtered_data_[i] + alpha * sample[i]; + } + timestamp_most_recent_update_ns_ = timestamp_ns; +} + +void LowpassFilter::Reset() +{ + initialized_ = false; + filtered_data_ = { 0, 0, 0 }; +} + +} // namespace cardboard diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/lowpass_filter.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/lowpass_filter.h new file mode 100644 index 000000000..c4994c425 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/lowpass_filter.h @@ -0,0 +1,81 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CARDBOARD_SDK_SENSORS_LOWPASS_FILTER_H_ +#define CARDBOARD_SDK_SENSORS_LOWPASS_FILTER_H_ + +#include +#include + +#include "../util/vector.h" + +namespace cardboard { + +// Implements an IIR, first order, low pass filter over vectors of the given +// dimension = 3. +// See http://en.wikipedia.org/wiki/Low-pass_filter +class LowpassFilter { +public: + // Initializes a filter with the given cutoff frequency in Hz. + explicit LowpassFilter(double cutoff_freq_hz); + + // Updates the filter with the given sample. Note that samples with + // non-monotonic timestamps and successive samples with a time steps below 1 + // ms or above 1 s are ignored. + // + // @param sample current sample data. + // @param timestamp_ns timestamp associated to this sample in nanoseconds. + void AddSample(const Vector3& sample, uint64_t timestamp_ns); + + // Updates the filter with the given weighted sample. + // + // @param sample current sample data. + // @param timestamp_ns timestamp associated to this sample in nanoseconds. + // @param weight typically a [0, 1] weight factor used when applying a new + // sample. A weight of 1 corresponds to calling AddSample. A weight of 0 + // makes the update no-op. The first initial sample is not affected by + // this. + void AddWeightedSample(const Vector3& sample, uint64_t timestamp_ns, double weight); + + // Returns the filtered value. A vector with zeros is returned if no samples + // have been added. + Vector3 GetFilteredData() const { + return filtered_data_; + } + + // Returns the most recent update timestamp in ns. + uint64_t GetMostRecentTimestampNs() const { + return timestamp_most_recent_update_ns_; + } + + // Returns true when the filter is initialized. + bool IsInitialized() const { + return initialized_; + } + + // Resets filter state. + void Reset(); + +private: + const double cutoff_time_constant_; + uint64_t timestamp_most_recent_update_ns_; + bool initialized_; + + Vector3 filtered_data_; +}; + +} // namespace cardboard + +#endif // CARDBOARD_SDK_SENSORS_LOWPASS_FILTER_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/mean_filter.cc b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/mean_filter.cc new file mode 100644 index 000000000..02fb8034c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/mean_filter.cc @@ -0,0 +1,46 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mean_filter.h" + +namespace cardboard { + +MeanFilter::MeanFilter(size_t filter_size) + : filter_size_(filter_size) +{ +} + +void MeanFilter::AddSample(const Vector3& sample) +{ + buffer_.push_back(sample); + if (buffer_.size() > filter_size_) { + buffer_.pop_front(); + } +} + +bool MeanFilter::IsValid() const { return buffer_.size() == filter_size_; } + +Vector3 MeanFilter::GetFilteredData() const +{ + // Compute mean of the samples stored in buffer_. + Vector3 mean = Vector3::Zero(); + for (auto sample : buffer_) { + mean += sample; + } + + return mean / static_cast(filter_size_); +} + +} // namespace cardboard diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/mean_filter.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/mean_filter.h new file mode 100644 index 000000000..6b4956fef --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/mean_filter.h @@ -0,0 +1,48 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CARDBOARD_SDK_SENSORS_MEAN_FILTER_H_ +#define CARDBOARD_SDK_SENSORS_MEAN_FILTER_H_ + +#include + +#include "../util/vector.h" + +namespace cardboard { + +// Fixed window FIFO mean filter for vectors of the given dimension. +class MeanFilter { +public: + // Create a mean filter of size filter_size. + // @param filter_size size of the internal filter. + explicit MeanFilter(size_t filter_size); + + // Add sample to buffer_ if buffer_ is full it drop the oldest sample. + void AddSample(const Vector3& sample); + + // Returns true if buffer has filter_size_ sample, false otherwise. + bool IsValid() const; + + // Returns the mean of values stored in the internal buffer. + Vector3 GetFilteredData() const; + +private: + const size_t filter_size_; + std::deque buffer_; +}; + +} // namespace cardboard + +#endif // CARDBOARD_SDK_SENSORS_MEAN_FILTER_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/median_filter.cc b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/median_filter.cc new file mode 100644 index 000000000..d27c19f47 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/median_filter.cc @@ -0,0 +1,69 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "median_filter.h" + +#include +#include + +#include "../util/vector.h" +#include "../util/vectorutils.h" + +namespace cardboard { + +MedianFilter::MedianFilter(size_t filter_size) + : filter_size_(filter_size) +{ +} + +void MedianFilter::AddSample(const Vector3& sample) +{ + buffer_.push_back(sample); + norms_.push_back(Length(sample)); + if (buffer_.size() > filter_size_) { + buffer_.pop_front(); + norms_.pop_front(); + } +} + +bool MedianFilter::IsValid() const { return buffer_.size() == filter_size_; } + +Vector3 MedianFilter::GetFilteredData() const +{ + std::vector norms(norms_.begin(), norms_.end()); + + // Get median of value of the norms. + std::nth_element(norms.begin(), norms.begin() + filter_size_ / 2, norms.end()); + const float median_norm = norms[filter_size_ / 2]; + + // Get median value based on their norm. + auto median_it = buffer_.begin(); + for (const auto norm : norms_) { + if (norm == median_norm) { + break; + } + ++median_it; + } + + return *median_it; +} + +void MedianFilter::Reset() +{ + buffer_.clear(); + norms_.clear(); +} + +} // namespace cardboard diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/median_filter.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/median_filter.h new file mode 100644 index 000000000..9a8e7cfc7 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/median_filter.h @@ -0,0 +1,53 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CARDBOARD_SDK_SENSORS_MEDIAN_FILTER_H_ +#define CARDBOARD_SDK_SENSORS_MEDIAN_FILTER_H_ + +#include + +#include "../util/vector.h" + +namespace cardboard { + +// Fixed window FIFO median filter for vectors of the given dimension = 3. +class MedianFilter { +public: + // Creates a median filter of size filter_size. + // @param filter_size size of the internal filter. + explicit MedianFilter(size_t filter_size); + + // Adds sample to buffer_ if buffer_ is full it drops the oldest sample. + void AddSample(const Vector3& sample); + + // Returns true if buffer has filter_size_ sample, false otherwise. + bool IsValid() const; + + // Returns the median of values store in the internal buffer. + Vector3 GetFilteredData() const; + + // Resets the filter, removing all samples that have been added. + void Reset(); + +private: + const size_t filter_size_; + std::deque buffer_; + // Contains norms of the elements stored in buffer_. + std::deque norms_; +}; + +} // namespace cardboard + +#endif // CARDBOARD_SDK_SENSORS_MEDIAN_FILTER_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/pose_prediction.cc b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/pose_prediction.cc new file mode 100644 index 000000000..baaf844dd --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/pose_prediction.cc @@ -0,0 +1,71 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "pose_prediction.h" + +#include // NOLINT + +#include "../util/logging.h" +#include "../util/vectorutils.h" + +namespace cardboard { + +namespace { + const double kEpsilon = 1.0e-15; +} // namespace + +namespace pose_prediction { + + Rotation GetRotationFromGyroscope(const Vector3& gyroscope_value, double timestep_s) + { + const double velocity = Length(gyroscope_value); + + // When there is no rotation data return an identity rotation. + if (velocity < kEpsilon) { + CARDBOARD_LOGI("PosePrediction::GetRotationFromGyroscope: Velocity really small, " + "returning identity rotation."); + return Rotation::Identity(); + } + // Since the gyroscope_value is a start from sensor transformation we need to + // invert it to have a sensor from start transformation, hence the minus sign. + // For more info: + // http://developer.android.com/guide/topics/sensors/sensors_motion.html#sensors-motion-gyro + return Rotation::FromAxisAndAngle(gyroscope_value / velocity, -timestep_s * velocity); + } + + Rotation PredictPose(int64_t requested_pose_timestamp, const PoseState& current_state) + { + // Subtracting unsigned numbers is bad when the result is negative. + const int64_t diff = requested_pose_timestamp - current_state.timestamp; + const double timestep_s = diff * 1.0e-9; + + const Rotation update = GetRotationFromGyroscope( + current_state.sensor_from_start_rotation_velocity, timestep_s); + return update * current_state.sensor_from_start_rotation; + } + + Rotation PredictPoseInv(int64_t requested_pose_timestamp, const PoseState& current_state) + { + // Subtracting unsigned numbers is bad when the result is negative. + const int64_t diff = requested_pose_timestamp - current_state.timestamp; + const double timestep_s = diff * 1.0e-9; + + const Rotation update = GetRotationFromGyroscope( + current_state.sensor_from_start_rotation_velocity, timestep_s); + return current_state.sensor_from_start_rotation * (-update); + } + +} // namespace pose_prediction +} // namespace cardboard diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/pose_prediction.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/pose_prediction.h new file mode 100644 index 000000000..9ab311b33 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/pose_prediction.h @@ -0,0 +1,55 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CARDBOARD_SDK_SENSORS_POSE_PREDICTION_H_ +#define CARDBOARD_SDK_SENSORS_POSE_PREDICTION_H_ + +#include + +#include "pose_state.h" +#include "../util/rotation.h" + +namespace cardboard { +namespace pose_prediction { + +// Returns a rotation matrix based on the integration of the gyroscope_value +// over the timestep_s in seconds. +// TODO(pfg): Document the space better here. +// +// @param gyroscope_value gyroscope sensor values. +// @param timestep_s integration period in seconds. +// @return Integration of the gyroscope value the rotation is from Start to +// Sensor Space. +Rotation GetRotationFromGyroscope(const Vector3& gyroscope_value, double timestep_s); + +// Gets a predicted pose for a given time in the future (e.g. rendering time) +// based on a linear prediction model. This uses the system current state +// (position, velocity, etc) from the past to extrapolate a position in the +// future. +// +// @param requested_pose_timestamp time at which you want the pose. +// @param current_state current state that stores the pose and linear model at a +// given time prior to requested_pose_timestamp_ns. +// @return pose from Start to Sensor Space. +Rotation PredictPose(int64_t requested_pose_timestamp, const PoseState& current_state); + +// Equivalent to PredictPose, but for use with poses relative to Start Space +// rather than sensor space. +Rotation PredictPoseInv(int64_t requested_pose_timestamp, const PoseState& current_state); + +} // namespace pose_prediction +} // namespace cardboard + +#endif // CARDBOARD_SDK_SENSORS_POSE_PREDICTION_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/pose_state.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/pose_state.h new file mode 100644 index 000000000..f7801c9f3 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/pose_state.h @@ -0,0 +1,56 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CARDBOARD_SDK_SENSORS_POSE_STATE_H_ +#define CARDBOARD_SDK_SENSORS_POSE_STATE_H_ + +#include "../util/rotation.h" +#include "../util/vector.h" + +namespace cardboard { + +enum { + kPoseStateFlagInvalid = 1U << 0, + kPoseStateFlagInitializing = 1U << 1, + kPoseStateFlagHas6DoF = 1U << 2, +}; + +// Stores a head pose pose plus derivatives. This can be used for prediction. +struct PoseState { + // System wall time. + int64_t timestamp; + + // Rotation from Sensor Space to Start Space. + Rotation sensor_from_start_rotation; + + // First derivative of the rotation. + Vector3 sensor_from_start_rotation_velocity; + + // Current gyroscope bias in rad/s. + Vector3 bias; + + // The position of the headset. + Vector3 position = Vector3(0, 0, 0); + + // In the same coordinate frame as the position. + Vector3 velocity = Vector3(0, 0, 0); + + // Flags indicating the status of the pose. + uint64_t flags = 0U; +}; + +} // namespace cardboard + +#endif // CARDBOARD_SDK_SENSORS_POSE_STATE_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/sensor_fusion_ekf.cc b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/sensor_fusion_ekf.cc new file mode 100644 index 000000000..575dde6f0 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/sensor_fusion_ekf.cc @@ -0,0 +1,333 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "sensor_fusion_ekf.h" + +#include +#include + +#include "accelerometer_data.h" +#include "gyroscope_data.h" +#include "pose_prediction.h" +#include "../util/matrixutils.h" + +namespace cardboard { + +namespace { + + const double kFiniteDifferencingEpsilon = 1.0e-7; + const double kEpsilon = 1.0e-15; + // Default gyroscope frequency. This corresponds to 100 Hz. + const double kDefaultGyroscopeTimestep_s = 0.01f; + // Maximum time between gyroscope before we start limiting the integration. + const double kMaximumGyroscopeSampleDelay_s = 0.04f; + // Compute a first-order exponential moving average of changes in accel norm per + // frame. + const double kSmoothingFactor = 0.5; + // Minimum and maximum values used for accelerometer noise covariance matrix. + // The smaller the sigma value, the more weight is given to the accelerometer + // signal. + const double kMinAccelNoiseSigma = 0.75; + const double kMaxAccelNoiseSigma = 7.0; + // Initial value for the diagonal elements of the different covariance matrices. + const double kInitialStateCovarianceValue = 25.0; + const double kInitialProcessCovarianceValue = 1.0; + // Maximum accelerometer norm change allowed before capping it covariance to a + // large value. + const double kMaxAccelNormChange = 0.15; + // Timestep IIR filtering coefficient. + const double kTimestepFilterCoeff = 0.95; + // Minimum number of sample for timestep filtering. + const int kTimestepFilterMinSamples = 10; + + // Z direction in start space. + const Vector3 kCanonicalZDirection(0.0, 0.0, 1.0); + + // Computes an axis-angle rotation from the input vector. + // angle = norm(a) + // axis = a.normalized() + // If norm(a) == 0, it returns an identity rotation. + static inline Rotation RotationFromVector(const Vector3& a) + { + const double norm_a = Length(a); + if (norm_a < kEpsilon) { + return Rotation::Identity(); + } + return Rotation::FromAxisAndAngle(a / norm_a, norm_a); + } + +} // namespace + +SensorFusionEkf::SensorFusionEkf() + : execute_reset_with_next_accelerometer_sample_(false) + , bias_estimation_enabled_(true) + , gyroscope_bias_estimate_({ 0, 0, 0 }) +{ + ResetState(); +} + +void SensorFusionEkf::Reset() { execute_reset_with_next_accelerometer_sample_ = true; } + +void SensorFusionEkf::ResetState() +{ + current_state_.sensor_from_start_rotation = Rotation::Identity(); + current_state_.sensor_from_start_rotation_velocity = Vector3::Zero(); + + current_gyroscope_sensor_timestamp_ns_ = 0; + current_accelerometer_sensor_timestamp_ns_ = 0; + + state_covariance_ = Matrix3x3::Identity() * kInitialStateCovarianceValue; + process_covariance_ = Matrix3x3::Identity() * kInitialProcessCovarianceValue; + accelerometer_measurement_covariance_ + = Matrix3x3::Identity() * kMinAccelNoiseSigma * kMinAccelNoiseSigma; + innovation_covariance_ = Matrix3x3::Identity(); + + accelerometer_measurement_jacobian_ = Matrix3x3::Zero(); + kalman_gain_ = Matrix3x3::Zero(); + innovation_ = Vector3::Zero(); + accelerometer_measurement_ = Vector3::Zero(); + prediction_ = Vector3::Zero(); + control_input_ = Vector3::Zero(); + state_update_ = Vector3::Zero(); + + moving_average_accelerometer_norm_change_ = 0.0; + + is_timestep_filter_initialized_ = false; + is_gyroscope_filter_valid_ = false; + is_aligned_with_gravity_ = false; + + // Reset biases. + gyroscope_bias_estimator_.Reset(); + gyroscope_bias_estimate_ = { 0, 0, 0 }; +} + +// Here I am doing something wrong relative to time stamps. The state timestamps +// always correspond to the gyrostamps because it would require additional +// extrapolation if I wanted to do otherwise. +PoseState SensorFusionEkf::GetLatestPoseState() const { return current_state_; } + +void SensorFusionEkf::ProcessGyroscopeSample(const GyroscopeData& sample) +{ + // Don't accept gyroscope sample when waiting for a reset. + if (execute_reset_with_next_accelerometer_sample_) { + return; + } + + // Discard outdated samples. + if (current_gyroscope_sensor_timestamp_ns_ >= sample.sensor_timestamp_ns) { + current_gyroscope_sensor_timestamp_ns_ = sample.sensor_timestamp_ns; + return; + } + + // Checks that we received at least one gyroscope sample in the past. + if (current_gyroscope_sensor_timestamp_ns_ != 0) { + double current_timestep_s = std::chrono::duration_cast>( + std::chrono::nanoseconds( + sample.sensor_timestamp_ns - current_gyroscope_sensor_timestamp_ns_)) + .count(); + if (current_timestep_s > kMaximumGyroscopeSampleDelay_s) { + if (is_gyroscope_filter_valid_) { + // Replaces the delta timestamp by the filtered estimates of the delta time. + current_timestep_s = filtered_gyroscope_timestep_s_; + } else { + current_timestep_s = kDefaultGyroscopeTimestep_s; + } + } else { + FilterGyroscopeTimestep(current_timestep_s); + } + + if (bias_estimation_enabled_) { + gyroscope_bias_estimator_.ProcessGyroscope(sample.data, sample.sensor_timestamp_ns); + + if (gyroscope_bias_estimator_.IsCurrentEstimateValid()) { + // As soon as the device is considered to be static, the bias estimator + // should have a precise estimate of the gyroscope bias. + gyroscope_bias_estimate_ = gyroscope_bias_estimator_.GetGyroscopeBias(); + } + } + + // Only integrate after receiving an accelerometer sample. + if (is_aligned_with_gravity_) { + const Rotation rotation_from_gyroscope = pose_prediction::GetRotationFromGyroscope( + { sample.data[0] - gyroscope_bias_estimate_[0], + sample.data[1] - gyroscope_bias_estimate_[1], + sample.data[2] - gyroscope_bias_estimate_[2] }, + current_timestep_s); + current_state_.sensor_from_start_rotation + = rotation_from_gyroscope * current_state_.sensor_from_start_rotation; + UpdateStateCovariance(RotationMatrixNH(rotation_from_gyroscope)); + state_covariance_ = state_covariance_ + + ((current_timestep_s * current_timestep_s) * process_covariance_); + } + } + + // Saves gyroscope event for future prediction. + current_state_.timestamp = sample.system_timestamp; + current_gyroscope_sensor_timestamp_ns_ = sample.sensor_timestamp_ns; + current_state_.sensor_from_start_rotation_velocity.Set( + sample.data[0] - gyroscope_bias_estimate_[0], sample.data[1] - gyroscope_bias_estimate_[1], + sample.data[2] - gyroscope_bias_estimate_[2]); +} + +Vector3 SensorFusionEkf::ComputeInnovation(const Rotation& pose) +{ + const Vector3 predicted_down_direction = pose * kCanonicalZDirection; + + const Rotation rotation + = Rotation::RotateInto(predicted_down_direction, accelerometer_measurement_); + Vector3 axis; + double angle; + rotation.GetAxisAndAngle(&axis, &angle); + return axis * angle; +} + +void SensorFusionEkf::ComputeMeasurementJacobian() +{ + for (int dof = 0; dof < 3; dof++) { + Vector3 delta = Vector3::Zero(); + delta[dof] = kFiniteDifferencingEpsilon; + + const Rotation epsilon_rotation = RotationFromVector(delta); + const Vector3 delta_rotation + = ComputeInnovation(epsilon_rotation * current_state_.sensor_from_start_rotation); + + const Vector3 col = (innovation_ - delta_rotation) / kFiniteDifferencingEpsilon; + accelerometer_measurement_jacobian_(0, dof) = col[0]; + accelerometer_measurement_jacobian_(1, dof) = col[1]; + accelerometer_measurement_jacobian_(2, dof) = col[2]; + } +} + +void SensorFusionEkf::ProcessAccelerometerSample(const AccelerometerData& sample) +{ + // Discard outdated samples. + if (current_accelerometer_sensor_timestamp_ns_ >= sample.sensor_timestamp_ns) { + current_accelerometer_sensor_timestamp_ns_ = sample.sensor_timestamp_ns; + return; + } + + // Call reset state if required. + if (execute_reset_with_next_accelerometer_sample_.exchange(false)) { + ResetState(); + } + + accelerometer_measurement_.Set(sample.data[0], sample.data[1], sample.data[2]); + current_accelerometer_sensor_timestamp_ns_ = sample.sensor_timestamp_ns; + + if (bias_estimation_enabled_) { + gyroscope_bias_estimator_.ProcessAccelerometer(sample.data, sample.sensor_timestamp_ns); + } + + if (!is_aligned_with_gravity_) { + // This is the first accelerometer measurement so it initializes the + // orientation estimate. + current_state_.sensor_from_start_rotation + = Rotation::RotateInto(kCanonicalZDirection, accelerometer_measurement_); + is_aligned_with_gravity_ = true; + + previous_accelerometer_norm_ = Length(accelerometer_measurement_); + return; + } + + UpdateMeasurementCovariance(); + + innovation_ = ComputeInnovation(current_state_.sensor_from_start_rotation); + ComputeMeasurementJacobian(); + + // S = H * P * H' + R + innovation_covariance_ = accelerometer_measurement_jacobian_ * state_covariance_ + * Transpose(accelerometer_measurement_jacobian_) + + accelerometer_measurement_covariance_; + + // K = P * H' * S^-1 + kalman_gain_ = state_covariance_ * Transpose(accelerometer_measurement_jacobian_) + * Inverse(innovation_covariance_); + + // x_update = K*nu + state_update_ = kalman_gain_ * innovation_; + + // P = (I - K * H) * P; + state_covariance_ = (Matrix3x3::Identity() - kalman_gain_ * accelerometer_measurement_jacobian_) + * state_covariance_; + + // Updates pose and associate covariance matrix. + const Rotation rotation_from_state_update = RotationFromVector(state_update_); + + current_state_.sensor_from_start_rotation + = rotation_from_state_update * current_state_.sensor_from_start_rotation; + UpdateStateCovariance(RotationMatrixNH(rotation_from_state_update)); +} + +void SensorFusionEkf::UpdateStateCovariance(const Matrix3x3& motion_update) +{ + state_covariance_ = motion_update * state_covariance_ * Transpose(motion_update); +} + +void SensorFusionEkf::FilterGyroscopeTimestep(double gyroscope_timestep_s) +{ + if (!is_timestep_filter_initialized_) { + // Initializes the filter. + filtered_gyroscope_timestep_s_ = gyroscope_timestep_s; + num_gyroscope_timestep_samples_ = 1; + is_timestep_filter_initialized_ = true; + return; + } + + // Computes the IIR filter response. + filtered_gyroscope_timestep_s_ = kTimestepFilterCoeff * filtered_gyroscope_timestep_s_ + + (1 - kTimestepFilterCoeff) * gyroscope_timestep_s; + ++num_gyroscope_timestep_samples_; + + if (num_gyroscope_timestep_samples_ > kTimestepFilterMinSamples) { + is_gyroscope_filter_valid_ = true; + } +} + +void SensorFusionEkf::UpdateMeasurementCovariance() +{ + const double current_accelerometer_norm = Length(accelerometer_measurement_); + // Norm change between current and previous accel readings. + const double current_accelerometer_norm_change + = std::abs(current_accelerometer_norm - previous_accelerometer_norm_); + previous_accelerometer_norm_ = current_accelerometer_norm; + + moving_average_accelerometer_norm_change_ = kSmoothingFactor * current_accelerometer_norm_change + + (1 - kSmoothingFactor) * moving_average_accelerometer_norm_change_; + + // If we hit the accel norm change threshold, we use the maximum noise sigma + // for the accel covariance. For anything below that, we use a linear + // combination between min and max sigma values. + const double norm_change_ratio + = moving_average_accelerometer_norm_change_ / kMaxAccelNormChange; + const double accelerometer_noise_sigma = std::min(kMaxAccelNoiseSigma, + kMinAccelNoiseSigma + norm_change_ratio * (kMaxAccelNoiseSigma - kMinAccelNoiseSigma)); + + // Updates the accel covariance matrix with the new sigma value. + accelerometer_measurement_covariance_ + = Matrix3x3::Identity() * accelerometer_noise_sigma * accelerometer_noise_sigma; +} + +bool SensorFusionEkf::IsBiasEstimationEnabled() const { return bias_estimation_enabled_; } + +void SensorFusionEkf::SetBiasEstimationEnabled(bool enable) +{ + if (bias_estimation_enabled_ != enable) { + bias_estimation_enabled_ = enable; + gyroscope_bias_estimate_ = { 0, 0, 0 }; + gyroscope_bias_estimator_.Reset(); + } +} + +} // namespace cardboard diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/sensor_fusion_ekf.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/sensor_fusion_ekf.h new file mode 100644 index 000000000..a66fe33f4 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/sensors/sensor_fusion_ekf.h @@ -0,0 +1,188 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CARDBOARD_SDK_SENSORS_SENSOR_FUSION_EKF_H_ +#define CARDBOARD_SDK_SENSORS_SENSOR_FUSION_EKF_H_ + +#include +#include +#include + +#include "accelerometer_data.h" +#include "gyroscope_bias_estimator.h" +#include "gyroscope_data.h" +#include "pose_state.h" +#include "../util/matrix_3x3.h" +#include "../util/rotation.h" +#include "../util/vector.h" + +namespace cardboard { + +// Sensor fusion class that implements an Extended Kalman Filter (EKF) to +// estimate a 3D rotation from a gyroscope and an accelerometer. +// This system only has one state, the pose. It does not estimate any velocity +// or acceleration. +// +// To learn more about Kalman filtering one can read this article which is a +// good introduction: https://en.wikipedia.org/wiki/Kalman_filter +class SensorFusionEkf { +public: + SensorFusionEkf(); + + // Resets the state of the sensor fusion. It sets the velocity for + // prediction to zero. The reset will happen with the next + // accelerometer sample. Gyroscope sample will be discarded until a new + // accelerometer sample arrives. + void Reset(); + + // Gets the PoseState representing the latest pose and derivatives at a + // particular timestamp as estimated by SensorFusion. + PoseState GetLatestPoseState() const; + + // Processes one gyroscope sample event. This updates the pose of the system + // and the prediction model. The gyroscope data is assumed to be in axis angle + // form. Angle = ||v|| and Axis = v / ||v||, with v = [v_x, v_y, v_z]^T. + // + // @param sample gyroscope sample data. + void ProcessGyroscopeSample(const GyroscopeData& sample); + + // Processes one accelerometer sample event. This updates the pose of the + // system. If the Accelerometer norm changes too much between sample it is not + // trusted as much. + // + // @param sample accelerometer sample data. + void ProcessAccelerometerSample(const AccelerometerData& sample); + + // Enables or disables the drift correction by estimating the gyroscope bias. + // + // @param enable Enable drift correction. + void SetBiasEstimationEnabled(bool enable); + + // Returns a boolean that indicates if bias estimation is enabled or disabled. + // + // @return true if bias estimation is enabled, false otherwise. + bool IsBiasEstimationEnabled() const; + + // Returns the current gyroscope bias estimate from GyroscopeBiasEstimator. + Vector3 GetGyroscopeBias() const { + return { + gyroscope_bias_estimate_[0], gyroscope_bias_estimate_[1], gyroscope_bias_estimate_[2]}; + } + + // Returns true after receiving the first accelerometer measurement. + bool IsFullyInitialized() const { + return is_aligned_with_gravity_; + } + +private: + // Estimates the average timestep between gyroscope event. + void FilterGyroscopeTimestep(double gyroscope_timestep); + + // Updates the state covariance with an incremental motion. It changes the + // space of the quadric. + void UpdateStateCovariance(const Matrix3x3& motion_update); + + // Computes the innovation vector of the Kalman based on the input pose. + // It uses the latest measurement vector (i.e. accelerometer data), which must + // be set prior to calling this function. + Vector3 ComputeInnovation(const Rotation& pose); + + // This computes the measurement_jacobian_ via numerical differentiation based + // on the current value of sensor_from_start_rotation_. + void ComputeMeasurementJacobian(); + + // Updates the accelerometer covariance matrix. + // + // This looks at the norm of recent accelerometer readings. If it has changed + // significantly, it means the phone receives additional acceleration than + // just gravity, and so the down vector information gravity signal is noisier. + void UpdateMeasurementCovariance(); + + // Reset all internal states. This is not thread safe. Lock should be acquired + // outside of it. This function is called in ProcessAccelerometerSample. + void ResetState(); + + // Current transformation from Sensor Space to Start Space. + // x_sensor = sensor_from_start_rotation_ * x_start; + PoseState current_state_; + + // Filtering of the gyroscope timestep started? + bool is_timestep_filter_initialized_; + // Filtered gyroscope timestep valid? + bool is_gyroscope_filter_valid_; + // Sensor fusion currently aligned with gravity? After initialization + // it will requires a couple of accelerometer data for the system to get + // aligned. + std::atomic is_aligned_with_gravity_; + + // Covariance of Kalman filter state (P in common formulation). + Matrix3x3 state_covariance_; + // Covariance of the process noise (Q in common formulation). + Matrix3x3 process_covariance_; + // Covariance of the accelerometer measurement (R in common formulation). + Matrix3x3 accelerometer_measurement_covariance_; + // Covariance of innovation (S in common formulation). + Matrix3x3 innovation_covariance_; + // Jacobian of the measurements (H in common formulation). + Matrix3x3 accelerometer_measurement_jacobian_; + // Gain of the Kalman filter (K in common formulation). + Matrix3x3 kalman_gain_; + // Parameter update a.k.a. innovation vector. (\nu in common formulation). + Vector3 innovation_; + // Measurement vector (z in common formulation). + Vector3 accelerometer_measurement_; + // Current prediction vector (g in common formulation). + Vector3 prediction_; + // Control input, currently this is only the gyroscope data (\mu in common + // formulation). + Vector3 control_input_; + // Update of the state vector. (x in common formulation). + Vector3 state_update_; + + // Sensor time of the last gyroscope processed event. + uint64_t current_gyroscope_sensor_timestamp_ns_; + // Sensor time of the last accelerometer processed event. + uint64_t current_accelerometer_sensor_timestamp_ns_; + + // Estimates of the timestep between gyroscope event in seconds. + double filtered_gyroscope_timestep_s_; + // Number of timestep samples processed so far by the filter. + uint32_t num_gyroscope_timestep_samples_; + // Norm of the accelerometer for the previous measurement. + double previous_accelerometer_norm_; + // Moving average of the accelerometer norm changes. It is computed for every + // sensor datum. + double moving_average_accelerometer_norm_change_; + + // Flag indicating if a state reset should be executed with the next + // accelerometer sample. + std::atomic execute_reset_with_next_accelerometer_sample_; + + // Flag indicating if bias estimation is enabled (enabled by default). + std::atomic bias_estimation_enabled_; + + // Bias estimator and static device detector. + GyroscopeBiasEstimator gyroscope_bias_estimator_; + + // Current bias estimate_; + Vector3 gyroscope_bias_estimate_; + + SensorFusionEkf(const SensorFusionEkf&) = delete; + SensorFusionEkf& operator=(const SensorFusionEkf&) = delete; +}; + +} // namespace cardboard + +#endif // CARDBOARD_SDK_SENSORS_SENSOR_FUSION_EKF_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/logging.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/logging.h new file mode 100644 index 000000000..dee224b1c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/logging.h @@ -0,0 +1,38 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CARDBOARD_SDK_UTIL_LOGGING_H_ +#define CARDBOARD_SDK_UTIL_LOGGING_H_ + +#include +#include + +#if defined(__ANDROID__) + +#include + +// Uncomment these to enable debug logging from native code + +#define CARDBOARD_LOGI(...) // __android_log_print(ANDROID_LOG_INFO, "CardboardSDK", __VA_ARGS__) +#define CARDBOARD_LOGE(...) // __android_log_print(ANDROID_LOG_ERROR, "CardboardSDK", __VA_ARGS__) + +#else + +#define CARDBOARD_LOGI(...) // FURI_LOG_I("CardboardSDK", __VA_ARGS__) +#define CARDBOARD_LOGE(...) // FURI_LOG_E("CardboardSDK", __VA_ARGS__) + +#endif + +#endif // CARDBOARD_SDK_UTIL_LOGGING_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrix_3x3.cc b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrix_3x3.cc new file mode 100644 index 000000000..9ddd847b0 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrix_3x3.cc @@ -0,0 +1,121 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "matrix_3x3.h" + +namespace cardboard { + +Matrix3x3::Matrix3x3(double m00, double m01, double m02, double m10, double m11, double m12, + double m20, double m21, double m22) + : elem_ { { { m00, m01, m02 }, { m10, m11, m12 }, { m20, m21, m22 } } } +{ +} + +Matrix3x3::Matrix3x3() +{ + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) + elem_[row][col] = 0; + } +} + +Matrix3x3 Matrix3x3::Zero() +{ + Matrix3x3 result; + return result; +} + +Matrix3x3 Matrix3x3::Identity() +{ + Matrix3x3 result; + for (int row = 0; row < 3; ++row) { + result.elem_[row][row] = 1; + } + return result; +} + +void Matrix3x3::MultiplyScalar(double s) +{ + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) + elem_[row][col] *= s; + } +} + +Matrix3x3 Matrix3x3::Negation() const +{ + Matrix3x3 result; + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) + result.elem_[row][col] = -elem_[row][col]; + } + return result; +} + +Matrix3x3 Matrix3x3::Scale(const Matrix3x3& m, double s) +{ + Matrix3x3 result; + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) + result.elem_[row][col] = m.elem_[row][col] * s; + } + return result; +} + +Matrix3x3 Matrix3x3::Addition(const Matrix3x3& lhs, const Matrix3x3& rhs) +{ + Matrix3x3 result; + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) + result.elem_[row][col] = lhs.elem_[row][col] + rhs.elem_[row][col]; + } + return result; +} + +Matrix3x3 Matrix3x3::Subtraction(const Matrix3x3& lhs, const Matrix3x3& rhs) +{ + Matrix3x3 result; + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) + result.elem_[row][col] = lhs.elem_[row][col] - rhs.elem_[row][col]; + } + return result; +} + +Matrix3x3 Matrix3x3::Product(const Matrix3x3& m0, const Matrix3x3& m1) +{ + Matrix3x3 result; + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) { + result.elem_[row][col] = 0; + for (int i = 0; i < 3; ++i) + result.elem_[row][col] += m0.elem_[row][i] * m1.elem_[i][col]; + } + } + return result; +} + +bool Matrix3x3::AreEqual(const Matrix3x3& m0, const Matrix3x3& m1) +{ + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) { + if (m0.elem_[row][col] != m1.elem_[row][col]) + return false; + } + } + return true; +} + +} // namespace cardboard diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrix_3x3.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrix_3x3.h new file mode 100644 index 000000000..81e4f2158 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrix_3x3.h @@ -0,0 +1,138 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CARDBOARD_SDK_UTIL_MATRIX_3X3_H_ +#define CARDBOARD_SDK_UTIL_MATRIX_3X3_H_ + +#include +#include // For memcpy(). +#include // NOLINT +#include // NOLINT + +namespace cardboard { + +// The Matrix3x3 class defines a square 3-dimensional matrix. Elements are +// stored in row-major order. +// TODO(b/135461889): Make this class consistent with Matrix4x4. +class Matrix3x3 { +public: + // The default constructor zero-initializes all elements. + Matrix3x3(); + + // Dimension-specific constructors that are passed individual element values. + Matrix3x3( + double m00, + double m01, + double m02, + double m10, + double m11, + double m12, + double m20, + double m21, + double m22); + + // Constructor that reads elements from a linear array of the correct size. + explicit Matrix3x3(const double array[3 * 3]); + + // Returns a Matrix3x3 containing all zeroes. + static Matrix3x3 Zero(); + + // Returns an identity Matrix3x3. + static Matrix3x3 Identity(); + + // Mutable element accessors. + double& operator()(int row, int col) { + return elem_[row][col]; + } + std::array& operator[](int row) { + return elem_[row]; + } + + // Read-only element accessors. + const double& operator()(int row, int col) const { + return elem_[row][col]; + } + const std::array& operator[](int row) const { + return elem_[row]; + } + + // Return a pointer to the data for interfacing with libraries. + double* Data() { + return &elem_[0][0]; + } + const double* Data() const { + return &elem_[0][0]; + } + + // Self-modifying multiplication operators. + void operator*=(double s) { + MultiplyScalar(s); + } + void operator*=(const Matrix3x3& m) { + *this = Product(*this, m); + } + + // Unary operators. + Matrix3x3 operator-() const { + return Negation(); + } + + // Binary scale operators. + friend Matrix3x3 operator*(const Matrix3x3& m, double s) { + return Scale(m, s); + } + friend Matrix3x3 operator*(double s, const Matrix3x3& m) { + return Scale(m, s); + } + + // Binary matrix addition. + friend Matrix3x3 operator+(const Matrix3x3& lhs, const Matrix3x3& rhs) { + return Addition(lhs, rhs); + } + + // Binary matrix subtraction. + friend Matrix3x3 operator-(const Matrix3x3& lhs, const Matrix3x3& rhs) { + return Subtraction(lhs, rhs); + } + + // Binary multiplication operator. + friend Matrix3x3 operator*(const Matrix3x3& m0, const Matrix3x3& m1) { + return Product(m0, m1); + } + + // Exact equality and inequality comparisons. + friend bool operator==(const Matrix3x3& m0, const Matrix3x3& m1) { + return AreEqual(m0, m1); + } + friend bool operator!=(const Matrix3x3& m0, const Matrix3x3& m1) { + return !AreEqual(m0, m1); + } + +private: + // These private functions implement most of the operators. + void MultiplyScalar(double s); + Matrix3x3 Negation() const; + static Matrix3x3 Addition(const Matrix3x3& lhs, const Matrix3x3& rhs); + static Matrix3x3 Subtraction(const Matrix3x3& lhs, const Matrix3x3& rhs); + static Matrix3x3 Scale(const Matrix3x3& m, double s); + static Matrix3x3 Product(const Matrix3x3& m0, const Matrix3x3& m1); + static bool AreEqual(const Matrix3x3& m0, const Matrix3x3& m1); + + std::array, 3> elem_; +}; + +} // namespace cardboard + +#endif // CARDBOARD_SDK_UTIL_MATRIX_3X3_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrix_4x4.cc b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrix_4x4.cc new file mode 100644 index 000000000..8db3cbc5b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrix_4x4.cc @@ -0,0 +1,87 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "matrix_4x4.h" + +#include +#include +#include + +namespace cardboard { + +Matrix4x4 Matrix4x4::Identity() +{ + Matrix4x4 ret; + for (int j = 0; j < 4; ++j) { + for (int i = 0; i < 4; ++i) { + ret.m[j][i] = (i == j) ? 1 : 0; + } + } + + return ret; +} + +Matrix4x4 Matrix4x4::Zeros() +{ + Matrix4x4 ret; + for (int j = 0; j < 4; ++j) { + for (int i = 0; i < 4; ++i) { + ret.m[j][i] = 0; + } + } + + return ret; +} + +Matrix4x4 Matrix4x4::Translation(float x, float y, float z) +{ + Matrix4x4 ret = Matrix4x4::Identity(); + ret.m[3][0] = x; + ret.m[3][1] = y; + ret.m[3][2] = z; + + return ret; +} + +Matrix4x4 Matrix4x4::Perspective(const std::array& fov, float zNear, float zFar) +{ + Matrix4x4 ret = Matrix4x4::Zeros(); + + const float xLeft = -std::tan(fov[0] * M_PI / 180.0f) * zNear; + const float xRight = std::tan(fov[1] * M_PI / 180.0f) * zNear; + const float yBottom = -std::tan(fov[2] * M_PI / 180.0f) * zNear; + const float yTop = std::tan(fov[3] * M_PI / 180.0f) * zNear; + + const float X = (2 * zNear) / (xRight - xLeft); + const float Y = (2 * zNear) / (yTop - yBottom); + const float A = (xRight + xLeft) / (xRight - xLeft); + const float B = (yTop + yBottom) / (yTop - yBottom); + const float C = (zNear + zFar) / (zNear - zFar); + const float D = (2 * zNear * zFar) / (zNear - zFar); + + ret.m[0][0] = X; + ret.m[2][0] = A; + ret.m[1][1] = Y; + ret.m[2][1] = B; + ret.m[2][2] = C; + ret.m[3][2] = D; + ret.m[2][3] = -1; + + return ret; +} + +void Matrix4x4::ToArray(float* array) const { std::memcpy(array, &m[0][0], 16 * sizeof(float)); } + +} // namespace cardboard diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrix_4x4.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrix_4x4.h new file mode 100644 index 000000000..9934f6be0 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrix_4x4.h @@ -0,0 +1,37 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CARDBOARD_SDK_UTIL_MATRIX_4X4_H_ +#define CARDBOARD_SDK_UTIL_MATRIX_4X4_H_ + +#include + +namespace cardboard { + +class Matrix4x4 { +public: + static Matrix4x4 Identity(); + static Matrix4x4 Zeros(); + static Matrix4x4 Translation(float x, float y, float z); + static Matrix4x4 Perspective(const std::array& fov, float zNear, float zFar); + void ToArray(float* array) const; + +private: + std::array, 4> m; +}; + +} // namespace cardboard + +#endif // CARDBOARD_SDK_UTIL_MATRIX4X4_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrixutils.cc b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrixutils.cc new file mode 100644 index 000000000..12470beae --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrixutils.cc @@ -0,0 +1,148 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "matrixutils.h" + +#include "vectorutils.h" + +namespace cardboard { + +namespace { + + // Returns true if the cofactor for a given row and column should be negated. + static bool IsCofactorNegated(int row, int col) + { + // Negated iff (row + col) is odd. + return ((row + col) & 1) != 0; + } + + static double CofactorElement3(const Matrix3x3& m, int row, int col) + { + static const int index[3][2] = { { 1, 2 }, { 0, 2 }, { 0, 1 } }; + const int i0 = index[row][0]; + const int i1 = index[row][1]; + const int j0 = index[col][0]; + const int j1 = index[col][1]; + const double cofactor = m(i0, j0) * m(i1, j1) - m(i0, j1) * m(i1, j0); + return IsCofactorNegated(row, col) ? -cofactor : cofactor; + } + + // Multiplies a matrix and some type of column vector to + // produce another column vector of the same type. + Vector3 MultiplyMatrixAndVector(const Matrix3x3& m, const Vector3& v) + { + Vector3 result = Vector3::Zero(); + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) + result[row] += m(row, col) * v[col]; + } + return result; + } + + // Sets the upper 3x3 of a Matrix to represent a 3D rotation. + void RotationMatrix3x3(const Rotation& r, Matrix3x3* matrix) + { + // + // Given a quaternion (a,b,c,d) where d is the scalar part, the 3x3 rotation + // matrix is: + // + // a^2 - b^2 - c^2 + d^2 2ab - 2cd 2ac + 2bd + // 2ab + 2cd -a^2 + b^2 - c^2 + d^2 2bc - 2ad + // 2ac - 2bd 2bc + 2ad -a^2 - b^2 + c^2 + d^2 + // + const Vector<4>& quat = r.GetQuaternion(); + const double aa = quat[0] * quat[0]; + const double bb = quat[1] * quat[1]; + const double cc = quat[2] * quat[2]; + const double dd = quat[3] * quat[3]; + + const double ab = quat[0] * quat[1]; + const double ac = quat[0] * quat[2]; + const double bc = quat[1] * quat[2]; + + const double ad = quat[0] * quat[3]; + const double bd = quat[1] * quat[3]; + const double cd = quat[2] * quat[3]; + + Matrix3x3& m = *matrix; + m[0][0] = aa - bb - cc + dd; + m[0][1] = 2 * ab - 2 * cd; + m[0][2] = 2 * ac + 2 * bd; + m[1][0] = 2 * ab + 2 * cd; + m[1][1] = -aa + bb - cc + dd; + m[1][2] = 2 * bc - 2 * ad; + m[2][0] = 2 * ac - 2 * bd; + m[2][1] = 2 * bc + 2 * ad; + m[2][2] = -aa - bb + cc + dd; + } + +} // anonymous namespace + +Vector3 operator*(const Matrix3x3& m, const Vector3& v) { return MultiplyMatrixAndVector(m, v); } + +Matrix3x3 CofactorMatrix(const Matrix3x3& m) +{ + Matrix3x3 result; + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) + result(row, col) = CofactorElement3(m, row, col); + } + return result; +} + +Matrix3x3 AdjugateWithDeterminant(const Matrix3x3& m, double* determinant) +{ + const Matrix3x3 cofactor_matrix = CofactorMatrix(m); + if (determinant) { + *determinant = m(0, 0) * cofactor_matrix(0, 0) + m(0, 1) * cofactor_matrix(0, 1) + + m(0, 2) * cofactor_matrix(0, 2); + } + return Transpose(cofactor_matrix); +} + +// Returns the transpose of a matrix. +Matrix3x3 Transpose(const Matrix3x3& m) +{ + Matrix3x3 result; + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) + result(row, col) = m(col, row); + } + return result; +} + +Matrix3x3 InverseWithDeterminant(const Matrix3x3& m, double* determinant) +{ + // The inverse is the adjugate divided by the determinant. + double det; + Matrix3x3 adjugate = AdjugateWithDeterminant(m, &det); + if (determinant) + *determinant = det; + if (det == 0) + return Matrix3x3::Zero(); + else + return adjugate * (1 / det); +} + +Matrix3x3 Inverse(const Matrix3x3& m) { return InverseWithDeterminant(m, nullptr); } + +Matrix3x3 RotationMatrixNH(const Rotation& r) +{ + Matrix3x3 m; + RotationMatrix3x3(r, &m); + return m; +} + +} // namespace cardboard diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrixutils.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrixutils.h new file mode 100644 index 000000000..80f9b2168 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/matrixutils.h @@ -0,0 +1,65 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CARDBOARD_SDK_UTIL_MATRIXUTILS_H_ +#define CARDBOARD_SDK_UTIL_MATRIXUTILS_H_ + +// +// This file contains operators and free functions that define generic Matrix +// operations. +// + +#include "matrix_3x3.h" +#include "rotation.h" +#include "vector.h" + +namespace cardboard { + +// Returns the transpose of a matrix. +Matrix3x3 Transpose(const Matrix3x3& m); + +// Multiplies a Matrix and a column Vector of the same Dimension to produce +// another column Vector. +Vector3 operator*(const Matrix3x3& m, const Vector3& v); + +// Returns the determinant of the matrix. This function is defined for all the +// typedef'ed Matrix types. +double Determinant(const Matrix3x3& m); + +// Returns the adjugate of the matrix, which is defined as the transpose of the +// cofactor matrix. This function is defined for all the typedef'ed Matrix +// types. The determinant of the matrix is computed as a side effect, so it is +// returned in the determinant parameter if it is not null. +Matrix3x3 AdjugateWithDeterminant(const Matrix3x3& m, double* determinant); + +// Returns the inverse of the matrix. This function is defined for all the +// typedef'ed Matrix types. The determinant of the matrix is computed as a +// side effect, so it is returned in the determinant parameter if it is not +// null. If the determinant is 0, the returned matrix has all zeroes. +Matrix3x3 InverseWithDeterminant(const Matrix3x3& m, double* determinant); + +// Returns the inverse of the matrix. This function is defined for all the +// typedef'ed Matrix types. If the determinant of the matrix is 0, the returned +// matrix has all zeroes. +Matrix3x3 Inverse(const Matrix3x3& m); + +// Returns a 3x3 Matrix representing a 3D rotation. This creates a Matrix that +// does not work with homogeneous coordinates, so the function name ends in +// "NH". +Matrix3x3 RotationMatrixNH(const Rotation& r); + +} // namespace cardboard + +#endif // CARDBOARD_SDK_UTIL_MATRIXUTILS_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/rotation.cc b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/rotation.cc new file mode 100644 index 000000000..5c3d09a2b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/rotation.cc @@ -0,0 +1,117 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "rotation.h" + +#include +#include + +#include "vectorutils.h" + +namespace cardboard { + +void Rotation::SetAxisAndAngle(const VectorType& axis, double angle) +{ + VectorType unit_axis = axis; + if (!Normalize(&unit_axis)) { + *this = Identity(); + } else { + double a = angle / 2; + const double s = sin(a); + const VectorType v(unit_axis * s); + SetQuaternion(QuaternionType(v[0], v[1], v[2], cos(a))); + } +} + +Rotation Rotation::FromRotationMatrix(const Matrix3x3& mat) +{ + static const double kOne = 1.0; + static const double kFour = 4.0; + + const double d0 = mat(0, 0), d1 = mat(1, 1), d2 = mat(2, 2); + const double ww = kOne + d0 + d1 + d2; + const double xx = kOne + d0 - d1 - d2; + const double yy = kOne - d0 + d1 - d2; + const double zz = kOne - d0 - d1 + d2; + + const double max = std::max(ww, std::max(xx, std::max(yy, zz))); + if (ww == max) { + const double w4 = sqrt(ww * kFour); + return Rotation::FromQuaternion(QuaternionType((mat(2, 1) - mat(1, 2)) / w4, + (mat(0, 2) - mat(2, 0)) / w4, (mat(1, 0) - mat(0, 1)) / w4, w4 / kFour)); + } + + if (xx == max) { + const double x4 = sqrt(xx * kFour); + return Rotation::FromQuaternion(QuaternionType(x4 / kFour, (mat(0, 1) + mat(1, 0)) / x4, + (mat(0, 2) + mat(2, 0)) / x4, (mat(2, 1) - mat(1, 2)) / x4)); + } + + if (yy == max) { + const double y4 = sqrt(yy * kFour); + return Rotation::FromQuaternion(QuaternionType((mat(0, 1) + mat(1, 0)) / y4, y4 / kFour, + (mat(1, 2) + mat(2, 1)) / y4, (mat(0, 2) - mat(2, 0)) / y4)); + } + + // zz is the largest component. + const double z4 = sqrt(zz * kFour); + return Rotation::FromQuaternion(QuaternionType((mat(0, 2) + mat(2, 0)) / z4, + (mat(1, 2) + mat(2, 1)) / z4, z4 / kFour, (mat(1, 0) - mat(0, 1)) / z4)); +} + +void Rotation::GetAxisAndAngle(VectorType* axis, double* angle) const +{ + VectorType vec(quat_[0], quat_[1], quat_[2]); + if (Normalize(&vec)) { + *angle = 2 * acos(quat_[3]); + *axis = vec; + } else { + *axis = VectorType(1, 0, 0); + *angle = 0.0; + } +} + +Rotation Rotation::RotateInto(const VectorType& from, const VectorType& to) +{ + static const double kTolerance = std::numeric_limits::epsilon() * 100; + + // Directly build the quaternion using the following technique: + // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final + const double norm_u_norm_v = sqrt(LengthSquared(from) * LengthSquared(to)); + double real_part = norm_u_norm_v + Dot(from, to); + VectorType w; + if (real_part < kTolerance * norm_u_norm_v) { + // If |from| and |to| are exactly opposite, rotate 180 degrees around an + // arbitrary orthogonal axis. Axis normalization can happen later, when we + // normalize the quaternion. + real_part = 0.0; + w = (abs(from[0]) > abs(from[2])) ? VectorType(-from[1], from[0], 0) + : VectorType(0, -from[2], from[1]); + } else { + // Otherwise, build the quaternion the standard way. + w = Cross(from, to); + } + + // Build and return a normalized quaternion. + // Note that Rotation::FromQuaternion automatically performs normalization. + return Rotation::FromQuaternion(QuaternionType(w[0], w[1], w[2], real_part)); +} + +Rotation::VectorType Rotation::operator*(const Rotation::VectorType& v) const +{ + return ApplyToVector(v); +} + +} // namespace cardboard diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/rotation.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/rotation.h new file mode 100644 index 000000000..8730cb3b0 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/rotation.h @@ -0,0 +1,156 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CARDBOARD_SDK_UTIL_ROTATION_H_ +#define CARDBOARD_SDK_UTIL_ROTATION_H_ + +#include "matrix_3x3.h" +#include "vector.h" +#include "vectorutils.h" + +namespace cardboard { + +// The Rotation class represents a rotation around a 3-dimensional axis. It +// uses normalized quaternions internally to make the math robust. +class Rotation { +public: + // Convenience typedefs for vector of the correct type. + typedef Vector<3> VectorType; + typedef Vector<4> QuaternionType; + + // The default constructor creates an identity Rotation, which has no effect. + Rotation() { + quat_.Set(0, 0, 0, 1); + } + + // Returns an identity Rotation, which has no effect. + static Rotation Identity() { + return Rotation(); + } + + // Sets the Rotation from a quaternion (4D vector), which is first normalized. + void SetQuaternion(const QuaternionType& quaternion) { + quat_ = Normalized(quaternion); + } + + // Returns the Rotation as a normalized quaternion (4D vector). + const QuaternionType& GetQuaternion() const { + return quat_; + } + + // Sets the Rotation to rotate by the given angle around the given axis, + // following the right-hand rule. The axis does not need to be unit + // length. If it is zero length, this results in an identity Rotation. + void SetAxisAndAngle(const VectorType& axis, double angle); + + // Returns the right-hand rule axis and angle corresponding to the + // Rotation. If the Rotation is the identity rotation, this returns the +X + // axis and an angle of 0. + void GetAxisAndAngle(VectorType* axis, double* angle) const; + + // Convenience function that constructs and returns a Rotation given an axis + // and angle. + static Rotation FromAxisAndAngle(const VectorType& axis, double angle) { + Rotation r; + r.SetAxisAndAngle(axis, angle); + return r; + } + + // Convenience function that constructs and returns a Rotation given a + // quaternion. + static Rotation FromQuaternion(const QuaternionType& quat) { + Rotation r; + r.SetQuaternion(quat); + return r; + } + + // Convenience function that constructs and returns a Rotation given a + // rotation matrix R with $R^\top R = I && det(R) = 1$. + static Rotation FromRotationMatrix(const Matrix3x3& mat); + + // Convenience function that constructs and returns a Rotation given Euler + // angles that are applied in the order of rotate-Z by roll, rotate-X by + // pitch, rotate-Y by yaw (same as GetRollPitchYaw). + static Rotation FromRollPitchYaw(double roll, double pitch, double yaw) { + VectorType x(1, 0, 0), y(0, 1, 0), z(0, 0, 1); + return FromAxisAndAngle(z, roll) * (FromAxisAndAngle(x, pitch) * FromAxisAndAngle(y, yaw)); + } + + // Convenience function that constructs and returns a Rotation given Euler + // angles that are applied in the order of rotate-Y by yaw, rotate-X by + // pitch, rotate-Z by roll (same as GetYawPitchRoll). + static Rotation FromYawPitchRoll(double yaw, double pitch, double roll) { + VectorType x(1, 0, 0), y(0, 1, 0), z(0, 0, 1); + return FromAxisAndAngle(y, yaw) * (FromAxisAndAngle(x, pitch) * FromAxisAndAngle(z, roll)); + } + + // Constructs and returns a Rotation that rotates one vector to another along + // the shortest arc. This returns an identity rotation if either vector has + // zero length. + static Rotation RotateInto(const VectorType& from, const VectorType& to); + + // The negation operator returns the inverse rotation. + friend Rotation operator-(const Rotation& r) { + // Because we store normalized quaternions, the inverse is found by + // negating the vector part. + return Rotation(-r.quat_[0], -r.quat_[1], -r.quat_[2], r.quat_[3]); + } + + // Appends a rotation to this one. + Rotation& operator*=(const Rotation& r) { + const QuaternionType& qr = r.quat_; + QuaternionType& qt = quat_; + SetQuaternion(QuaternionType( + qr[3] * qt[0] + qr[0] * qt[3] + qr[2] * qt[1] - qr[1] * qt[2], + qr[3] * qt[1] + qr[1] * qt[3] + qr[0] * qt[2] - qr[2] * qt[0], + qr[3] * qt[2] + qr[2] * qt[3] + qr[1] * qt[0] - qr[0] * qt[1], + qr[3] * qt[3] - qr[0] * qt[0] - qr[1] * qt[1] - qr[2] * qt[2])); + return *this; + } + + // Binary multiplication operator - returns a composite Rotation. + friend const Rotation operator*(const Rotation& r0, const Rotation& r1) { + Rotation r = r0; + r *= r1; + return r; + } + + // Multiply a Rotation and a Vector to get a Vector. + VectorType operator*(const VectorType& v) const; + +private: + // Private constructor that builds a Rotation from quaternion components. + Rotation(double q0, double q1, double q2, double q3) + : quat_(q0, q1, q2, q3) { + } + + // Applies a Rotation to a Vector to rotate the Vector. Method borrowed from: + // http://blog.molecular-matters.com/2013/05/24/a-faster-quaternion-vector-multiplication/ + VectorType ApplyToVector(const VectorType& v) const { + VectorType im(quat_[0], quat_[1], quat_[2]); + VectorType temp = 2.0 * Cross(im, v); + return v + quat_[3] * temp + Cross(im, temp); + } + + // The rotation represented as a normalized quaternion. (Unit quaternions are + // required for constructing rotation matrices, so it makes sense to always + // store them that way.) The vector part is in the first 3 elements, and the + // scalar part is in the last element. + QuaternionType quat_; +}; + +} // namespace cardboard + +#endif // CARDBOARD_SDK_UTIL_ROTATION_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/vector.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/vector.h new file mode 100644 index 000000000..64c4f2546 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/vector.h @@ -0,0 +1,251 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CARDBOARD_SDK_UTIL_VECTOR_H_ +#define CARDBOARD_SDK_UTIL_VECTOR_H_ + +#include + +namespace cardboard { + +// Geometric N-dimensional Vector class. +template +class Vector { +public: + // The default constructor zero-initializes all elements. + Vector(); + + // Dimension-specific constructors that are passed individual element values. + constexpr Vector(double e0, double e1, double e2); + constexpr Vector(double e0, double e1, double e2, double e3); + + // Constructor for a Vector of dimension N from a Vector of dimension N-1 and + // a scalar of the correct type, assuming N is at least 2. + // constexpr Vector(const Vector& v, double s); + + void Set(double e0, double e1, double e2); // Only when Dimension == 3. + void Set(double e0, double e1, double e2, + double e3); // Only when Dimension == 4. + + // Mutable element accessor. + double& operator[](int index) { + return elem_[index]; + } + + // Element accessor. + double operator[](int index) const { + return elem_[index]; + } + + // Returns a Vector containing all zeroes. + static Vector Zero(); + + // Self-modifying operators. + void operator+=(const Vector& v) { + Add(v); + } + void operator-=(const Vector& v) { + Subtract(v); + } + void operator*=(double s) { + Multiply(s); + } + void operator/=(double s) { + Divide(s); + } + + // Unary negation operator. + Vector operator-() const { + return Negation(); + } + + // Binary operators. + friend Vector operator+(const Vector& v0, const Vector& v1) { + return Sum(v0, v1); + } + friend Vector operator-(const Vector& v0, const Vector& v1) { + return Difference(v0, v1); + } + friend Vector operator*(const Vector& v, double s) { + return Scale(v, s); + } + friend Vector operator*(double s, const Vector& v) { + return Scale(v, s); + } + friend Vector operator*(const Vector& v, const Vector& s) { + return Product(v, s); + } + friend Vector operator/(const Vector& v, double s) { + return Divide(v, s); + } + + // Self-modifying addition. + void Add(const Vector& v); + // Self-modifying subtraction. + void Subtract(const Vector& v); + // Self-modifying multiplication by a scalar. + void Multiply(double s); + // Self-modifying division by a scalar. + void Divide(double s); + + // Unary negation. + Vector Negation() const; + + // Binary component-wise multiplication. + static Vector Product(const Vector& v0, const Vector& v1); + // Binary component-wise addition. + static Vector Sum(const Vector& v0, const Vector& v1); + // Binary component-wise subtraction. + static Vector Difference(const Vector& v0, const Vector& v1); + // Binary multiplication by a scalar. + static Vector Scale(const Vector& v, double s); + // Binary division by a scalar. + static Vector Divide(const Vector& v, double s); + +private: + std::array elem_; +}; +//------------------------------------------------------------------------------ + +template +Vector::Vector() { + for(int i = 0; i < Dimension; i++) { + elem_[i] = 0; + } +} + +template +constexpr Vector::Vector(double e0, double e1, double e2) + : elem_{e0, e1, e2} { +} + +template +constexpr Vector::Vector(double e0, double e1, double e2, double e3) + : elem_{e0, e1, e2, e3} { +} +/* +template <> +constexpr Vector<4>::Vector(const Vector<3>& v, double s) + : elem_{v[0], v[1], v[2], s} {} +*/ +template +void Vector::Set(double e0, double e1, double e2) { + elem_[0] = e0; + elem_[1] = e1; + elem_[2] = e2; +} + +template +void Vector::Set(double e0, double e1, double e2, double e3) { + elem_[0] = e0; + elem_[1] = e1; + elem_[2] = e2; + elem_[3] = e3; +} + +template +Vector Vector::Zero() { + Vector v; + return v; +} + +template +void Vector::Add(const Vector& v) { + for(int i = 0; i < Dimension; i++) { + elem_[i] += v[i]; + } +} + +template +void Vector::Subtract(const Vector& v) { + for(int i = 0; i < Dimension; i++) { + elem_[i] -= v[i]; + } +} + +template +void Vector::Multiply(double s) { + for(int i = 0; i < Dimension; i++) { + elem_[i] *= s; + } +} + +template +void Vector::Divide(double s) { + for(int i = 0; i < Dimension; i++) { + elem_[i] /= s; + } +} + +template +Vector Vector::Negation() const { + Vector ret; + for(int i = 0; i < Dimension; i++) { + ret.elem_[i] = -elem_[i]; + } + return ret; +} + +template +Vector Vector::Product(const Vector& v0, const Vector& v1) { + Vector ret; + for(int i = 0; i < Dimension; i++) { + ret.elem_[i] = v0[i] * v1[i]; + } + return ret; +} + +template +Vector Vector::Sum(const Vector& v0, const Vector& v1) { + Vector ret; + for(int i = 0; i < Dimension; i++) { + ret.elem_[i] = v0[i] + v1[i]; + } + return ret; +} + +template +Vector Vector::Difference(const Vector& v0, const Vector& v1) { + Vector ret; + for(int i = 0; i < Dimension; i++) { + ret.elem_[i] = v0[i] - v1[i]; + } + return ret; +} + +template +Vector Vector::Scale(const Vector& v, double s) { + Vector ret; + for(int i = 0; i < Dimension; i++) { + ret.elem_[i] = v[i] * s; + } + return ret; +} + +template +Vector Vector::Divide(const Vector& v, double s) { + Vector ret; + for(int i = 0; i < Dimension; i++) { + ret.elem_[i] = v[i] / s; + } + return ret; +} + +typedef Vector<3> Vector3; +typedef Vector<4> Vector4; + +} // namespace cardboard + +#endif // CARDBOARD_SDK_UTIL_VECTOR_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/vectorutils.cc b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/vectorutils.cc new file mode 100644 index 000000000..b8f419c04 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/vectorutils.cc @@ -0,0 +1,40 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "vectorutils.h" + +namespace cardboard { + +// Returns the dot (inner) product of two Vectors. +double Dot(const Vector<3>& v0, const Vector<3>& v1) +{ + return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2]; +} + +// Returns the dot (inner) product of two Vectors. +double Dot(const Vector<4>& v0, const Vector<4>& v1) +{ + return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2] + v0[3] * v1[3]; +} + +// Returns the 3-dimensional cross product of 2 Vectors. Note that this is +// defined only for 3-dimensional Vectors. +Vector<3> Cross(const Vector<3>& v0, const Vector<3>& v1) +{ + return Vector<3>(v0[1] * v1[2] - v0[2] * v1[1], v0[2] * v1[0] - v0[0] * v1[2], + v0[0] * v1[1] - v0[1] * v1[0]); +} + +} // namespace cardboard diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/vectorutils.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/vectorutils.h new file mode 100644 index 000000000..054236713 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/tracking/util/vectorutils.h @@ -0,0 +1,76 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CARDBOARD_SDK_UTIL_VECTORUTILS_H_ +#define CARDBOARD_SDK_UTIL_VECTORUTILS_H_ + +// +// This file contains free functions that operate on Vector instances. +// + +#include + +#include "vector.h" + +namespace cardboard { + +// Returns the dot (inner) product of two Vectors. +double Dot(const Vector<3>& v0, const Vector<3>& v1); + +// Returns the dot (inner) product of two Vectors. +double Dot(const Vector<4>& v0, const Vector<4>& v1); + +// Returns the 3-dimensional cross product of 2 Vectors. Note that this is +// defined only for 3-dimensional Vectors. +Vector<3> Cross(const Vector<3>& v0, const Vector<3>& v1); + +// Returns the square of the length of a Vector. +template +double LengthSquared(const Vector& v) { + return Dot(v, v); +} + +// Returns the geometric length of a Vector. +template +double Length(const Vector& v) { + return sqrt(LengthSquared(v)); +} + +// the Vector untouched and returns false. +template +bool Normalize(Vector* v) { + const double len = Length(*v); + if(len == 0) { + return false; + } else { + (*v) /= len; + return true; + } +} + +// Returns a unit-length version of a Vector. If the given Vector has no +// length, this returns a Zero() Vector. +template +Vector Normalized(const Vector& v) { + Vector result = v; + if(Normalize(&result)) + return result; + else + return Vector::Zero(); +} + +} // namespace cardboard + +#endif // CARDBOARD_SDK_UTIL_VECTORUTILS_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/bt_mouse.c b/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/bt_mouse.c new file mode 100644 index 000000000..7d9c0e6db --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/bt_mouse.c @@ -0,0 +1,310 @@ +#include "bt_mouse.h" +#include "../tracking/main_loop.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct ButtonEvent { + int8_t button; + bool state; +} ButtonEvent; + +#define BTN_EVT_QUEUE_SIZE 32 + +struct BtMouse { + View* view; + ViewDispatcher* view_dispatcher; + Bt* bt; + NotificationApp* notifications; + FuriMutex* mutex; + FuriThread* thread; + bool connected; + + // Current mouse state + uint8_t btn; + int dx; + int dy; + int wheel; + + // Circular buffer; + // (qhead == qtail) means either empty or overflow. + // We'll ignore overflow and treat it as empty. + int qhead; + int qtail; + ButtonEvent queue[BTN_EVT_QUEUE_SIZE]; +}; + +#define BT_MOUSE_FLAG_INPUT_EVENT (1UL << 0) +#define BT_MOUSE_FLAG_KILL_THREAD (1UL << 1) +#define BT_MOUSE_FLAG_ALL (BT_MOUSE_FLAG_INPUT_EVENT | BT_MOUSE_FLAG_KILL_THREAD) + +#define MOUSE_SCROLL 2 + +static void bt_mouse_notify_event(BtMouse* bt_mouse) { + FuriThreadId thread_id = furi_thread_get_id(bt_mouse->thread); + furi_assert(thread_id); + furi_thread_flags_set(thread_id, BT_MOUSE_FLAG_INPUT_EVENT); +} + +static void bt_mouse_draw_callback(Canvas* canvas, void* context) { + UNUSED(context); + canvas_clear(canvas); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 0, 10, "Bluetooth Mouse mode"); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 0, 63, "Hold [back] to exit"); +} + +static void bt_mouse_button_state(BtMouse* bt_mouse, int8_t button, bool state) { + ButtonEvent event; + event.button = button; + event.state = state; + + if(bt_mouse->connected) { + furi_mutex_acquire(bt_mouse->mutex, FuriWaitForever); + bt_mouse->queue[bt_mouse->qtail++] = event; + bt_mouse->qtail %= BTN_EVT_QUEUE_SIZE; + furi_mutex_release(bt_mouse->mutex); + bt_mouse_notify_event(bt_mouse); + } +} + +static void bt_mouse_process(BtMouse* bt_mouse, InputEvent* event) { + with_view_model( + bt_mouse->view, + void* model, + { + UNUSED(model); + if(event->key == InputKeyUp) { + if(event->type == InputTypePress) { + bt_mouse_button_state(bt_mouse, HID_MOUSE_BTN_LEFT, true); + } else if(event->type == InputTypeRelease) { + bt_mouse_button_state(bt_mouse, HID_MOUSE_BTN_LEFT, false); + } + } else if(event->key == InputKeyDown) { + if(event->type == InputTypePress) { + bt_mouse_button_state(bt_mouse, HID_MOUSE_BTN_RIGHT, true); + } else if(event->type == InputTypeRelease) { + bt_mouse_button_state(bt_mouse, HID_MOUSE_BTN_RIGHT, false); + } + } else if(event->key == InputKeyOk) { + if(event->type == InputTypePress) { + bt_mouse_button_state(bt_mouse, HID_MOUSE_BTN_WHEEL, true); + } else if(event->type == InputTypeRelease) { + bt_mouse_button_state(bt_mouse, HID_MOUSE_BTN_WHEEL, false); + } + } else if(event->key == InputKeyRight) { + if(event->type == InputTypePress || event->type == InputTypeRepeat) { + bt_mouse->wheel = MOUSE_SCROLL; + } + } else if(event->key == InputKeyLeft) { + if(event->type == InputTypePress || event->type == InputTypeRepeat) { + bt_mouse->wheel = -MOUSE_SCROLL; + } + } + }, + true); +} + +static bool bt_mouse_input_callback(InputEvent* event, void* context) { + furi_assert(context); + BtMouse* bt_mouse = context; + bool consumed = false; + + if(event->type == InputTypeLong && event->key == InputKeyBack) { + furi_hal_bt_hid_mouse_release_all(); + } else { + bt_mouse_process(bt_mouse, event); + consumed = true; + } + + return consumed; +} + +void bt_mouse_connection_status_changed_callback(BtStatus status, void* context) { + furi_assert(context); + BtMouse* bt_mouse = context; + + bt_mouse->connected = (status == BtStatusConnected); + if(bt_mouse->connected) { + notification_internal_message(bt_mouse->notifications, &sequence_set_blue_255); + tracking_begin(); + view_dispatcher_send_custom_event(bt_mouse->view_dispatcher, 0); + } else { + tracking_end(); + notification_internal_message(bt_mouse->notifications, &sequence_reset_blue); + } + + //with_view_model( + // bt_mouse->view, void * model, { model->connected = connected; }, true); +} + +bool bt_mouse_move(int8_t dx, int8_t dy, void* context) { + furi_assert(context); + BtMouse* bt_mouse = context; + + if(bt_mouse->connected) { + furi_mutex_acquire(bt_mouse->mutex, FuriWaitForever); + bt_mouse->dx += dx; + bt_mouse->dy += dy; + furi_mutex_release(bt_mouse->mutex); + bt_mouse_notify_event(bt_mouse); + } + + return true; +} + +void bt_mouse_enter_callback(void* context) { + furi_assert(context); + BtMouse* bt_mouse = context; + + bt_mouse->bt = furi_record_open(RECORD_BT); + bt_mouse->notifications = furi_record_open(RECORD_NOTIFICATION); + bt_set_status_changed_callback( + bt_mouse->bt, bt_mouse_connection_status_changed_callback, bt_mouse); + furi_assert(bt_set_profile(bt_mouse->bt, BtProfileHidKeyboard)); + furi_hal_bt_start_advertising(); +} + +bool bt_mouse_custom_callback(uint32_t event, void* context) { + UNUSED(event); + furi_assert(context); + BtMouse* bt_mouse = context; + + tracking_step(bt_mouse_move, context); + furi_delay_ms(3); // Magic! Removing this will break the buttons + + view_dispatcher_send_custom_event(bt_mouse->view_dispatcher, 0); + return true; +} + +void bt_mouse_exit_callback(void* context) { + furi_assert(context); + BtMouse* bt_mouse = context; + + tracking_end(); + notification_internal_message(bt_mouse->notifications, &sequence_reset_blue); + + furi_hal_bt_stop_advertising(); + bt_set_profile(bt_mouse->bt, BtProfileSerial); + + furi_record_close(RECORD_NOTIFICATION); + bt_mouse->notifications = NULL; + furi_record_close(RECORD_BT); + bt_mouse->bt = NULL; +} + +static int8_t clamp(int t) { + if(t < -128) { + return -128; + } else if(t > 127) { + return 127; + } + return t; +} + +static int32_t bt_mouse_thread_callback(void* context) { + furi_assert(context); + BtMouse* bt_mouse = (BtMouse*)context; + + while(1) { + uint32_t flags = + furi_thread_flags_wait(BT_MOUSE_FLAG_ALL, FuriFlagWaitAny, FuriWaitForever); + if(flags & BT_MOUSE_FLAG_KILL_THREAD) { + break; + } + if(flags & BT_MOUSE_FLAG_INPUT_EVENT) { + furi_mutex_acquire(bt_mouse->mutex, FuriWaitForever); + + ButtonEvent event; + bool send_buttons = false; + if(bt_mouse->qhead != bt_mouse->qtail) { + event = bt_mouse->queue[bt_mouse->qhead++]; + bt_mouse->qhead %= BTN_EVT_QUEUE_SIZE; + send_buttons = true; + } + + int8_t dx = clamp(bt_mouse->dx); + bt_mouse->dx -= dx; + int8_t dy = clamp(bt_mouse->dy); + bt_mouse->dy -= dy; + int8_t wheel = clamp(bt_mouse->wheel); + bt_mouse->wheel -= wheel; + + furi_mutex_release(bt_mouse->mutex); + + if(bt_mouse->connected && send_buttons) { + if(event.state) { + furi_hal_bt_hid_mouse_press(event.button); + } else { + furi_hal_bt_hid_mouse_release(event.button); + } + } + + if(bt_mouse->connected && (dx != 0 || dy != 0)) { + furi_hal_bt_hid_mouse_move(dx, dy); + } + + if(bt_mouse->connected && wheel != 0) { + furi_hal_bt_hid_mouse_scroll(wheel); + } + } + } + + return 0; +} + +void bt_mouse_thread_start(BtMouse* bt_mouse) { + furi_assert(bt_mouse); + bt_mouse->mutex = furi_mutex_alloc(FuriMutexTypeNormal); + bt_mouse->thread = furi_thread_alloc(); + furi_thread_set_name(bt_mouse->thread, "BtSender"); + furi_thread_set_stack_size(bt_mouse->thread, 1024); + furi_thread_set_context(bt_mouse->thread, bt_mouse); + furi_thread_set_callback(bt_mouse->thread, bt_mouse_thread_callback); + furi_thread_start(bt_mouse->thread); +} + +void bt_mouse_thread_stop(BtMouse* bt_mouse) { + furi_assert(bt_mouse); + FuriThreadId thread_id = furi_thread_get_id(bt_mouse->thread); + furi_assert(thread_id); + furi_thread_flags_set(thread_id, BT_MOUSE_FLAG_KILL_THREAD); + furi_thread_join(bt_mouse->thread); + furi_thread_free(bt_mouse->thread); + furi_mutex_free(bt_mouse->mutex); +} + +BtMouse* bt_mouse_alloc(ViewDispatcher* view_dispatcher) { + BtMouse* bt_mouse = malloc(sizeof(BtMouse)); + memset(bt_mouse, 0, sizeof(BtMouse)); + + bt_mouse->view = view_alloc(); + bt_mouse->view_dispatcher = view_dispatcher; + view_set_context(bt_mouse->view, bt_mouse); + view_set_draw_callback(bt_mouse->view, bt_mouse_draw_callback); + view_set_input_callback(bt_mouse->view, bt_mouse_input_callback); + view_set_enter_callback(bt_mouse->view, bt_mouse_enter_callback); + view_set_custom_callback(bt_mouse->view, bt_mouse_custom_callback); + view_set_exit_callback(bt_mouse->view, bt_mouse_exit_callback); + bt_mouse_thread_start(bt_mouse); + return bt_mouse; +} + +void bt_mouse_free(BtMouse* bt_mouse) { + furi_assert(bt_mouse); + bt_mouse_thread_stop(bt_mouse); + view_free(bt_mouse->view); + free(bt_mouse); +} + +View* bt_mouse_get_view(BtMouse* bt_mouse) { + furi_assert(bt_mouse); + return bt_mouse->view; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/bt_mouse.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/bt_mouse.h new file mode 100644 index 000000000..09153d8fa --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/bt_mouse.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include + +typedef struct BtMouse BtMouse; + +BtMouse* bt_mouse_alloc(ViewDispatcher* view_dispatcher); + +void bt_mouse_free(BtMouse* bt_mouse); + +View* bt_mouse_get_view(BtMouse* bt_mouse); + +void bt_mouse_set_connected_status(BtMouse* bt_mouse, bool connected); diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/calibration.c b/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/calibration.c new file mode 100644 index 000000000..a92f68be4 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/calibration.c @@ -0,0 +1,69 @@ +#include "calibration.h" +#include "../tracking/main_loop.h" +#include "../air_mouse.h" + +#include +#include + +struct Calibration { + View* view; + ViewDispatcher* view_dispatcher; +}; + +static void calibration_draw_callback(Canvas* canvas, void* context) { + UNUSED(context); + canvas_clear(canvas); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 0, 10, "Calibrating..."); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 0, 63, "Please wait"); +} + +void calibration_enter_callback(void* context) { + furi_assert(context); + Calibration* calibration = context; + calibration_begin(); + view_dispatcher_send_custom_event(calibration->view_dispatcher, 0); +} + +bool calibration_custom_callback(uint32_t event, void* context) { + UNUSED(event); + furi_assert(context); + Calibration* calibration = context; + + if(calibration_step()) { + view_dispatcher_switch_to_view(calibration->view_dispatcher, AirMouseViewSubmenu); + } else { + view_dispatcher_send_custom_event(calibration->view_dispatcher, 0); + } + + return true; +} + +void calibration_exit_callback(void* context) { + furi_assert(context); + calibration_end(); +} + +Calibration* calibration_alloc(ViewDispatcher* view_dispatcher) { + Calibration* calibration = malloc(sizeof(Calibration)); + calibration->view = view_alloc(); + calibration->view_dispatcher = view_dispatcher; + view_set_context(calibration->view, calibration); + view_set_draw_callback(calibration->view, calibration_draw_callback); + view_set_enter_callback(calibration->view, calibration_enter_callback); + view_set_custom_callback(calibration->view, calibration_custom_callback); + view_set_exit_callback(calibration->view, calibration_exit_callback); + return calibration; +} + +void calibration_free(Calibration* calibration) { + furi_assert(calibration); + view_free(calibration->view); + free(calibration); +} + +View* calibration_get_view(Calibration* calibration) { + furi_assert(calibration); + return calibration->view; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/calibration.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/calibration.h new file mode 100644 index 000000000..da44ce0cd --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/calibration.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include + +typedef struct Calibration Calibration; + +Calibration* calibration_alloc(ViewDispatcher* view_dispatcher); + +void calibration_free(Calibration* calibration); + +View* calibration_get_view(Calibration* calibration); diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/usb_mouse.c b/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/usb_mouse.c new file mode 100644 index 000000000..09075b566 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/usb_mouse.c @@ -0,0 +1,139 @@ +#include "usb_mouse.h" +#include "../tracking/main_loop.h" + +#include +#include +#include +#include + +struct UsbMouse { + View* view; + ViewDispatcher* view_dispatcher; + FuriHalUsbInterface* usb_mode_prev; +}; + +static void usb_mouse_draw_callback(Canvas* canvas, void* context) { + UNUSED(context); + canvas_clear(canvas); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 0, 10, "USB Mouse mode"); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 0, 63, "Hold [back] to exit"); +} + +#define MOUSE_SCROLL 2 + +static void usb_mouse_process(UsbMouse* usb_mouse, InputEvent* event) { + with_view_model( + usb_mouse->view, + void* model, + { + UNUSED(model); + if(event->key == InputKeyUp) { + if(event->type == InputTypePress) { + furi_hal_hid_mouse_press(HID_MOUSE_BTN_LEFT); + } else if(event->type == InputTypeRelease) { + furi_hal_hid_mouse_release(HID_MOUSE_BTN_LEFT); + } + } else if(event->key == InputKeyDown) { + if(event->type == InputTypePress) { + furi_hal_hid_mouse_press(HID_MOUSE_BTN_RIGHT); + } else if(event->type == InputTypeRelease) { + furi_hal_hid_mouse_release(HID_MOUSE_BTN_RIGHT); + } + } else if(event->key == InputKeyOk) { + if(event->type == InputTypePress) { + furi_hal_hid_mouse_press(HID_MOUSE_BTN_WHEEL); + } else if(event->type == InputTypeRelease) { + furi_hal_hid_mouse_release(HID_MOUSE_BTN_WHEEL); + } + } else if(event->key == InputKeyRight) { + if(event->type == InputTypePress || event->type == InputTypeRepeat) { + furi_hal_hid_mouse_scroll(MOUSE_SCROLL); + } + } else if(event->key == InputKeyLeft) { + if(event->type == InputTypePress || event->type == InputTypeRepeat) { + furi_hal_hid_mouse_scroll(-MOUSE_SCROLL); + } + } + }, + true); +} + +static bool usb_mouse_input_callback(InputEvent* event, void* context) { + furi_assert(context); + UsbMouse* usb_mouse = context; + bool consumed = false; + + if(event->type == InputTypeLong && event->key == InputKeyBack) { + // furi_hal_hid_mouse_release_all(); + } else { + usb_mouse_process(usb_mouse, event); + consumed = true; + } + + return consumed; +} + +void usb_mouse_enter_callback(void* context) { + furi_assert(context); + UsbMouse* usb_mouse = context; + + usb_mouse->usb_mode_prev = furi_hal_usb_get_config(); + furi_hal_usb_unlock(); + furi_check(furi_hal_usb_set_config(&usb_hid, NULL) == true); + + tracking_begin(); + + view_dispatcher_send_custom_event(usb_mouse->view_dispatcher, 0); +} + +bool usb_mouse_move(int8_t dx, int8_t dy, void* context) { + UNUSED(context); + return furi_hal_hid_mouse_move(dx, dy); +} + +bool usb_mouse_custom_callback(uint32_t event, void* context) { + UNUSED(event); + furi_assert(context); + UsbMouse* usb_mouse = context; + + tracking_step(usb_mouse_move, context); + furi_delay_ms(3); // Magic! Removing this will break the buttons + + view_dispatcher_send_custom_event(usb_mouse->view_dispatcher, 0); + return true; +} + +void usb_mouse_exit_callback(void* context) { + furi_assert(context); + UsbMouse* usb_mouse = context; + + tracking_end(); + + furi_hal_usb_set_config(usb_mouse->usb_mode_prev, NULL); +} + +UsbMouse* usb_mouse_alloc(ViewDispatcher* view_dispatcher) { + UsbMouse* usb_mouse = malloc(sizeof(UsbMouse)); + usb_mouse->view = view_alloc(); + usb_mouse->view_dispatcher = view_dispatcher; + view_set_context(usb_mouse->view, usb_mouse); + view_set_draw_callback(usb_mouse->view, usb_mouse_draw_callback); + view_set_input_callback(usb_mouse->view, usb_mouse_input_callback); + view_set_enter_callback(usb_mouse->view, usb_mouse_enter_callback); + view_set_custom_callback(usb_mouse->view, usb_mouse_custom_callback); + view_set_exit_callback(usb_mouse->view, usb_mouse_exit_callback); + return usb_mouse; +} + +void usb_mouse_free(UsbMouse* usb_mouse) { + furi_assert(usb_mouse); + view_free(usb_mouse->view); + free(usb_mouse); +} + +View* usb_mouse_get_view(UsbMouse* usb_mouse) { + furi_assert(usb_mouse); + return usb_mouse->view; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/usb_mouse.h b/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/usb_mouse.h new file mode 100644 index 000000000..5ce589a69 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/airmouse/views/usb_mouse.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include + +typedef struct UsbMouse UsbMouse; + +UsbMouse* usb_mouse_alloc(ViewDispatcher* view_dispatcher); + +void usb_mouse_free(UsbMouse* usb_mouse); + +View* usb_mouse_get_view(UsbMouse* usb_mouse); diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/LICENSE new file mode 100644 index 000000000..4c02d8221 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/LICENSE @@ -0,0 +1,22 @@ + +MIT License + +Copyright (c) 2023 Alan Tsui + +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. \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/README.md b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/README.md new file mode 100644 index 000000000..856f47344 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/README.md @@ -0,0 +1,71 @@ +

+

Barcode Generator

+

+ +A barcode generator for the Flipper Zero that supports **UPC-A**, **EAN-8**, **EAN-13**, **Code-39**, and **Code-128**[1] +

+ + +## Table of Contents +- [Table of Contents](#table-of-contents) +- [Installing](#installing) +- [Usage](#usage) + - [Creating a barcode](#creating-a-barcode) + - [Editing a barcode](#editing-a-barcode) + - [Deleting a barcode](#deleting-a-barcode) + - [Viewing a barcode](#viewing-a-barcode) +- [Screenshots](#screenshots) +- [Credits](#credits) + + +## Installing +1) Download the `.zip` file from the release section +2) Extract/unzip the `.zip` file onto your computer +3) Open qFlipper and go to the file manager +4) Navigate to the `apps` folder +5) Drag & Drop the `.fap` file into the `apps` folder +6) Navigate back to the root folder and create the folder `app_data`, if not already there +7) Navigate into `app_data` and create another folder called `barcode_data` +8) Navigate into `barcode_data` +9) Drag & Drop the encoding txts (`code39_encodings.txt` & `code128_encodings.txt`) into the `barcode_data` folder + + +## Usage + +### Creating a barcode +1) To create a barcode click on `Create Barcode` +2) Next select your type using the left and right arrows +3) Enter your filename and then your barcode data +4) Click save + +### Editing a barcode +1) To edit a barcode click on `Edit Barcode` +2) Next select the barcode file you want to edit +3) Edit the type, name, or data +4) Click save + +### Deleting a barcode +1) To delete a barcode click on `Edit Barcode` +2) Next select the barcode file you want to delete +3) Scroll all the way to the bottom +4) Click delete + +### Viewing a barcode +1) To view a barcode click on `Load Barcode` +2) Next select the barcode file you want to view + +## Screenshots +![Barcode Create Screen](screenshots/Creating%20Barcode.png "Barcode Create Screen") + +![Flipper Code-128 Barcode](screenshots/Flipper%20Barcode.png "Flipper Code-128 Barcode") + +![Flipper Box EAN-13 Barcode](screenshots/Flipper%20Box%20Barcode.png "Flipper Box EAN-13 Barcode") + +## Credits + +[Kingal1337](https://github.com/Kingal1337) - Developer + +[@teeebor](https://github.com/teeebor) - Menu Code Snippet + + +[1] - Only supports Set B and only the characters from 0-94 \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/application.fam b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/application.fam new file mode 100644 index 000000000..060900fea --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/application.fam @@ -0,0 +1,11 @@ +App( + appid="barcode_app", + name="Barcode", + apptype=FlipperAppType.EXTERNAL, + entry_point="barcode_main", + requires=["gui", "storage"], + stack_size=2 * 1024, + fap_category="Misc_Extra", + fap_icon="images/barcode_10.png", + fap_icon_assets="images", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_app.c b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_app.c new file mode 100644 index 000000000..45f10fb57 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_app.c @@ -0,0 +1,342 @@ +#include "barcode_app.h" + +#include "barcode_app_icons.h" + +/** + * Opens a file browser dialog and returns the filepath of the selected file + * + * @param folder the folder to view when the browser opens + * @param file_path a string pointer for the file_path when a file is selected, + * file_path will be the folder path is nothing is selected + * @returns true if a file is selected +*/ +static bool select_file(const char* folder, FuriString* file_path) { + DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); + DialogsFileBrowserOptions browser_options; + dialog_file_browser_set_basic_options(&browser_options, BARCODE_EXTENSION, &I_barcode_10); + browser_options.base_path = DEFAULT_USER_BARCODES; + furi_string_set(file_path, folder); + + bool res = dialog_file_browser_show(dialogs, file_path, file_path, &browser_options); + + furi_record_close(RECORD_DIALOGS); + + return res; +} + +/** + * Reads the data from a file and stores them in the FuriStrings raw_type and raw_data +*/ +ErrorCode read_raw_data(FuriString* file_path, FuriString* raw_type, FuriString* raw_data) { + //Open Storage + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* ff = flipper_format_file_alloc(storage); + + ErrorCode reason = OKCode; + + if(!flipper_format_file_open_existing(ff, furi_string_get_cstr(file_path))) { + FURI_LOG_E(TAG, "Could not open file %s", furi_string_get_cstr(file_path)); + reason = FileOpening; + } else { + if(!flipper_format_read_string(ff, "Type", raw_type)) { + FURI_LOG_E(TAG, "Could not read \"Type\" string"); + reason = InvalidFileData; + } + if(!flipper_format_read_string(ff, "Data", raw_data)) { + FURI_LOG_E(TAG, "Could not read \"Data\" string"); + reason = InvalidFileData; + } + } + + //Close Storage + flipper_format_free(ff); + furi_record_close(RECORD_STORAGE); + + return reason; +} + +/** + * Gets the file name from a file path + * @param file_path the file path + * @param file_name the FuriString to store the file name + * @param remove_extension true if the extension should be removed, otherwise false +*/ +bool get_file_name_from_path(FuriString* file_path, FuriString* file_name, bool remove_extension) { + if(file_path == NULL || file_name == NULL) { + return false; + } + int slash_index = furi_string_search_rchar(file_path, '/', 0); + if(slash_index == FURI_STRING_FAILURE || slash_index >= (furi_string_size(file_path) - 1)) { + return false; + } + + furi_string_set(file_name, file_path); + furi_string_right(file_name, slash_index + 1); + if(remove_extension) { + int ext_index = furi_string_search_rchar(file_name, '.', 0); + if(ext_index != FURI_STRING_FAILURE && ext_index < (furi_string_size(file_path))) { + furi_string_left(file_name, ext_index); + } + } + + return true; +} + +/** + * Creates the barcode folder +*/ +void init_folder() { + Storage* storage = furi_record_open(RECORD_STORAGE); + FURI_LOG_I(TAG, "Creating barcodes folder"); + if(storage_simply_mkdir(storage, DEFAULT_USER_BARCODES)) { + FURI_LOG_I(TAG, "Barcodes folder successfully created!"); + } else { + FURI_LOG_I(TAG, "Barcodes folder already exists."); + } + furi_record_close(RECORD_STORAGE); +} + +void select_barcode_item(BarcodeApp* app) { + FuriString* file_path = furi_string_alloc(); + FuriString* raw_type = furi_string_alloc(); + FuriString* raw_data = furi_string_alloc(); + + //this determines if the data was read correctly or if the + bool loaded_success = true; + ErrorCode reason = OKCode; + + bool file_selected = select_file(DEFAULT_USER_BARCODES, file_path); + if(file_selected) { + FURI_LOG_I(TAG, "The file selected is %s", furi_string_get_cstr(file_path)); + Barcode* barcode = app->barcode_view; + + reason = read_raw_data(file_path, raw_type, raw_data); + if(reason != OKCode) { + loaded_success = false; + FURI_LOG_E(TAG, "Could not read data correctly"); + } + + //Free the data from the previous barcode + barcode_free_model(barcode); + + with_view_model( + barcode->view, + BarcodeModel * model, + { + model->file_path = furi_string_alloc_set(file_path); + + model->data = malloc(sizeof(BarcodeData)); + model->data->valid = loaded_success; + + if(loaded_success) { + model->data->raw_data = furi_string_alloc_set(raw_data); + model->data->correct_data = furi_string_alloc(); + + model->data->type_obj = get_type(raw_type); + + barcode_loader(model->data); + } else { + model->data->reason = reason; + } + }, + true); + + view_dispatcher_switch_to_view(app->view_dispatcher, BarcodeView); + } + + furi_string_free(raw_type); + furi_string_free(raw_data); + furi_string_free(file_path); +} + +void edit_barcode_item(BarcodeApp* app) { + FuriString* file_path = furi_string_alloc(); + FuriString* file_name = furi_string_alloc(); + FuriString* raw_type = furi_string_alloc(); + FuriString* raw_data = furi_string_alloc(); + + //this determines if the data was read correctly or if the + ErrorCode reason = OKCode; + + bool file_selected = select_file(DEFAULT_USER_BARCODES, file_path); + if(file_selected) { + FURI_LOG_I(TAG, "The file selected is %s", furi_string_get_cstr(file_path)); + CreateView* create_view_object = app->create_view; + + reason = read_raw_data(file_path, raw_type, raw_data); + if(reason != OKCode) { + FURI_LOG_E(TAG, "Could not read data correctly"); + with_view_model( + app->message_view->view, + MessageViewModel * model, + { model->message = get_error_code_message(reason); }, + true); + + view_dispatcher_switch_to_view( + create_view_object->barcode_app->view_dispatcher, MessageErrorView); + + } else { + BarcodeTypeObj* type_obj = get_type(raw_type); + if(type_obj->type == UNKNOWN) { + type_obj = barcode_type_objs[0]; + } + get_file_name_from_path(file_path, file_name, true); + + create_view_free_model(create_view_object); + with_view_model( + create_view_object->view, + CreateViewModel * model, + { + model->selected_menu_item = 0; + model->barcode_type = type_obj; + model->file_path = furi_string_alloc_set(file_path); + model->file_name = furi_string_alloc_set(file_name); + model->barcode_data = furi_string_alloc_set(raw_data); + model->mode = EditMode; + }, + true); + view_dispatcher_switch_to_view(app->view_dispatcher, CreateBarcodeView); + } + } + + furi_string_free(raw_type); + furi_string_free(raw_data); + furi_string_free(file_name); + furi_string_free(file_path); +} + +void create_barcode_item(BarcodeApp* app) { + CreateView* create_view_object = app->create_view; + + create_view_free_model(create_view_object); + + with_view_model( + create_view_object->view, + CreateViewModel * model, + { + model->selected_menu_item = 0; + model->barcode_type = barcode_type_objs[0]; + model->file_path = furi_string_alloc(); + model->file_name = furi_string_alloc(); + model->barcode_data = furi_string_alloc(); + model->mode = NewMode; + }, + true); + view_dispatcher_switch_to_view(app->view_dispatcher, CreateBarcodeView); +} + +void submenu_callback(void* context, uint32_t index) { + furi_assert(context); + + BarcodeApp* app = context; + + if(index == SelectBarcodeItem) { + select_barcode_item(app); + } else if(index == EditBarcodeItem) { + edit_barcode_item(app); + } else if(index == CreateBarcodeItem) { + create_barcode_item(app); + } +} + +uint32_t main_menu_callback(void* context) { + UNUSED(context); + return MainMenuView; +} + +uint32_t exit_callback(void* context) { + UNUSED(context); + return VIEW_NONE; +} + +void free_app(BarcodeApp* app) { + FURI_LOG_I(TAG, "Freeing Data"); + + init_folder(); + free_types(); + + view_dispatcher_remove_view(app->view_dispatcher, TextInputView); + text_input_free(app->text_input); + + view_dispatcher_remove_view(app->view_dispatcher, MessageErrorView); + message_view_free(app->message_view); + + view_dispatcher_remove_view(app->view_dispatcher, MainMenuView); + submenu_free(app->main_menu); + + view_dispatcher_remove_view(app->view_dispatcher, CreateBarcodeView); + create_view_free(app->create_view); + + view_dispatcher_remove_view(app->view_dispatcher, BarcodeView); + barcode_free(app->barcode_view); + + //free the dispatcher + view_dispatcher_free(app->view_dispatcher); + + furi_message_queue_free(app->event_queue); + + furi_record_close(RECORD_GUI); + app->gui = NULL; + + free(app); +} + +int32_t barcode_main(void* p) { + UNUSED(p); + BarcodeApp* app = malloc(sizeof(BarcodeApp)); + init_types(); + app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + // Register view port in GUI + app->gui = furi_record_open(RECORD_GUI); + + app->view_dispatcher = view_dispatcher_alloc(); + view_dispatcher_enable_queue(app->view_dispatcher); + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + app->main_menu = submenu_alloc(); + submenu_add_item(app->main_menu, "Load Barcode", SelectBarcodeItem, submenu_callback, app); + view_set_previous_callback(submenu_get_view(app->main_menu), exit_callback); + view_dispatcher_add_view(app->view_dispatcher, MainMenuView, submenu_get_view(app->main_menu)); + + submenu_add_item(app->main_menu, "Edit Barcode", EditBarcodeItem, submenu_callback, app); + + /***************************** + * Creating Text Input View + ******************************/ + app->text_input = text_input_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, TextInputView, text_input_get_view(app->text_input)); + + /***************************** + * Creating Message View + ******************************/ + app->message_view = message_view_allocate(app); + view_dispatcher_add_view( + app->view_dispatcher, MessageErrorView, message_get_view(app->message_view)); + + /***************************** + * Creating Create View + ******************************/ + app->create_view = create_view_allocate(app); + submenu_add_item(app->main_menu, "Create Barcode", CreateBarcodeItem, submenu_callback, app); + view_set_previous_callback(create_get_view(app->create_view), main_menu_callback); + view_dispatcher_add_view( + app->view_dispatcher, CreateBarcodeView, create_get_view(app->create_view)); + + /***************************** + * Creating Barcode View + ******************************/ + app->barcode_view = barcode_view_allocate(app); + view_set_previous_callback(barcode_get_view(app->barcode_view), main_menu_callback); + view_dispatcher_add_view( + app->view_dispatcher, BarcodeView, barcode_get_view(app->barcode_view)); + + //switch view to submenu and run dispatcher + view_dispatcher_switch_to_view(app->view_dispatcher, MainMenuView); + view_dispatcher_run(app->view_dispatcher); + + free_app(app); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_app.h b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_app.h new file mode 100644 index 000000000..31c805a69 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_app.h @@ -0,0 +1,87 @@ +#pragma once +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "barcode_utils.h" + +#define TAG "BARCODE" +#define VERSION "1.0" +#define FILE_VERSION "1" + +#define TEXT_BUFFER_SIZE 128 + +#define BARCODE_HEIGHT 50 +#define BARCODE_Y_START 3 + +#define APPS_DATA EXT_PATH("apps_data") + +//the folder where the encodings are located +#define BARCODE_DATA_FILE_DIR_PATH APPS_DATA "/barcode_data" + +//the folder where the code 39 encoding table is located +#define CODE39_DICT_FILE_PATH BARCODE_DATA_FILE_DIR_PATH "/code39_encodings.txt" + +//the folder where the code 128 encoding table is located +#define CODE128_DICT_FILE_PATH BARCODE_DATA_FILE_DIR_PATH "/code128_encodings.txt" + +//the folder where the user stores their barcodes +#define DEFAULT_USER_BARCODES EXT_PATH("barcodes") + +//The extension barcode files use +#define BARCODE_EXTENSION ".barcode" +#define BARCODE_EXTENSION_LENGTH 8 + +#include "views/barcode_view.h" +#include "views/create_view.h" +#include "views/message_view.h" +#include "barcode_validator.h" + +typedef struct BarcodeApp BarcodeApp; + +struct BarcodeApp { + Submenu* main_menu; + ViewDispatcher* view_dispatcher; + Gui* gui; + + FuriMessageQueue* event_queue; + + CreateView* create_view; + Barcode* barcode_view; + + MessageView* message_view; + TextInput* text_input; +}; + +enum SubmenuItems { + SelectBarcodeItem, + EditBarcodeItem, + + CreateBarcodeItem +}; + +enum Views { + TextInputView, + MessageErrorView, + MainMenuView, + CreateBarcodeView, + + BarcodeView +}; + +void submenu_callback(void* context, uint32_t index); + +uint32_t main_menu_callback(void* context); + +uint32_t exit_callback(void* context); + +int32_t barcode_main(void* p); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_utils.c b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_utils.c new file mode 100644 index 000000000..0a4770045 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_utils.c @@ -0,0 +1,125 @@ +#include "barcode_utils.h" + +BarcodeTypeObj* barcode_type_objs[NUMBER_OF_BARCODE_TYPES] = {NULL}; + +void init_types() { + BarcodeTypeObj* upc_a = malloc(sizeof(BarcodeTypeObj)); + upc_a->name = "UPC-A"; + upc_a->type = UPCA; + upc_a->min_digits = 11; + upc_a->max_digits = 12; + upc_a->start_pos = 16; + barcode_type_objs[UPCA] = upc_a; + + BarcodeTypeObj* ean_8 = malloc(sizeof(BarcodeTypeObj)); + ean_8->name = "EAN-8"; + ean_8->type = EAN8; + ean_8->min_digits = 7; + ean_8->max_digits = 8; + ean_8->start_pos = 32; + barcode_type_objs[EAN8] = ean_8; + + BarcodeTypeObj* ean_13 = malloc(sizeof(BarcodeTypeObj)); + ean_13->name = "EAN-13"; + ean_13->type = EAN13; + ean_13->min_digits = 12; + ean_13->max_digits = 13; + ean_13->start_pos = 16; + barcode_type_objs[EAN13] = ean_13; + + BarcodeTypeObj* code_39 = malloc(sizeof(BarcodeTypeObj)); + code_39->name = "CODE-39"; + code_39->type = CODE39; + code_39->min_digits = 1; + code_39->max_digits = -1; + code_39->start_pos = 0; + barcode_type_objs[CODE39] = code_39; + + BarcodeTypeObj* code_128 = malloc(sizeof(BarcodeTypeObj)); + code_128->name = "CODE-128"; + code_128->type = CODE128; + code_128->min_digits = 1; + code_128->max_digits = -1; + code_128->start_pos = 0; + barcode_type_objs[CODE128] = code_128; + + BarcodeTypeObj* unknown = malloc(sizeof(BarcodeTypeObj)); + unknown->name = "Unknown"; + unknown->type = UNKNOWN; + unknown->min_digits = 0; + unknown->max_digits = 0; + unknown->start_pos = 0; + barcode_type_objs[UNKNOWN] = unknown; +} + +void free_types() { + for(int i = 0; i < NUMBER_OF_BARCODE_TYPES; i++) { + free(barcode_type_objs[i]); + } +} + +BarcodeTypeObj* get_type(FuriString* type_string) { + if(furi_string_cmp_str(type_string, "UPC-A") == 0) { + return barcode_type_objs[UPCA]; + } + if(furi_string_cmp_str(type_string, "EAN-8") == 0) { + return barcode_type_objs[EAN8]; + } + if(furi_string_cmp_str(type_string, "EAN-13") == 0) { + return barcode_type_objs[EAN13]; + } + if(furi_string_cmp_str(type_string, "CODE-39") == 0) { + return barcode_type_objs[CODE39]; + } + if(furi_string_cmp_str(type_string, "CODE-128") == 0) { + return barcode_type_objs[CODE128]; + } + + return barcode_type_objs[UNKNOWN]; +} + +const char* get_error_code_name(ErrorCode error_code) { + switch(error_code) { + case WrongNumberOfDigits: + return "Wrong Number Of Digits"; + case InvalidCharacters: + return "Invalid Characters"; + case UnsupportedType: + return "Unsupported Type"; + case FileOpening: + return "File Opening Error"; + case InvalidFileData: + return "Invalid File Data"; + case MissingEncodingTable: + return "Missing Encoding Table"; + case EncodingTableError: + return "Encoding Table Error"; + case OKCode: + return "OK"; + default: + return "Unknown Code"; + }; +} + +const char* get_error_code_message(ErrorCode error_code) { + switch(error_code) { + case WrongNumberOfDigits: + return "Wrong # of characters"; + case InvalidCharacters: + return "Invalid characters"; + case UnsupportedType: + return "Unsupported barcode type"; + case FileOpening: + return "Could not open file"; + case InvalidFileData: + return "Invalid file data"; + case MissingEncodingTable: + return "Missing encoding table"; + case EncodingTableError: + return "Encoding table error"; + case OKCode: + return "OK"; + default: + return "Could not read barcode data"; + }; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_utils.h b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_utils.h new file mode 100644 index 000000000..212923a89 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_utils.h @@ -0,0 +1,53 @@ + +#pragma once +#include +#include + +#define NUMBER_OF_BARCODE_TYPES 6 + +typedef enum { + WrongNumberOfDigits, //There is too many or too few digits in the barcode + InvalidCharacters, //The barcode contains invalid characters + UnsupportedType, //the barcode type is not supported + FileOpening, //A problem occurred when opening the barcode data file + InvalidFileData, //One of the key in the file doesn't exist or there is a typo + MissingEncodingTable, //The encoding table txt for the barcode type is missing + EncodingTableError, //Something is wrong with the encoding table, probably missing data or typo + OKCode +} ErrorCode; + +typedef enum { + UPCA, + EAN8, + EAN13, + CODE39, + CODE128, + + UNKNOWN +} BarcodeType; + +typedef struct { + char* name; //The name of the barcode type + BarcodeType type; //The barcode type enum + int min_digits; //the minimum number of digits + int max_digits; //the maximum number of digits + int start_pos; //where to start drawing the barcode, set to -1 to dynamically draw barcode +} BarcodeTypeObj; + +typedef struct { + BarcodeTypeObj* type_obj; + int check_digit; //A place to store the check digit + FuriString* raw_data; //the data directly from the file + FuriString* correct_data; //the corrected/processed data + bool valid; //true if the raw data is correctly formatted, such as correct num of digits, valid characters, etc. + ErrorCode reason; //the reason why this barcode is invalid +} BarcodeData; + +//All available barcode types +extern BarcodeTypeObj* barcode_type_objs[NUMBER_OF_BARCODE_TYPES]; + +void init_types(); +void free_types(); +BarcodeTypeObj* get_type(FuriString* type_string); +const char* get_error_code_name(ErrorCode error_code); +const char* get_error_code_message(ErrorCode error_code); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_validator.c b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_validator.c new file mode 100644 index 000000000..abb1d9fba --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_validator.c @@ -0,0 +1,344 @@ +#include "barcode_validator.h" + +void barcode_loader(BarcodeData* barcode_data) { + switch(barcode_data->type_obj->type) { + case UPCA: + case EAN8: + case EAN13: + ean_upc_loader(barcode_data); + break; + case CODE39: + code_39_loader(barcode_data); + break; + case CODE128: + code_128_loader(barcode_data); + break; + case UNKNOWN: + barcode_data->reason = UnsupportedType; + barcode_data->valid = false; + default: + break; + } +} + +/** + * Calculates the check digit of a barcode if they have one + * @param barcode_data the barcode data + * @returns a check digit or -1 for either an invalid +*/ +int calculate_check_digit(BarcodeData* barcode_data) { + int check_digit = -1; + switch(barcode_data->type_obj->type) { + case UPCA: + case EAN8: + case EAN13: + check_digit = calculate_ean_upc_check_digit(barcode_data); + break; + case CODE39: + case CODE128: + case UNKNOWN: + default: + break; + } + + return check_digit; +} + +/** + * Calculates the check digit of barcode types UPC-A, EAN-8, & EAN-13 +*/ +int calculate_ean_upc_check_digit(BarcodeData* barcode_data) { + int check_digit = 0; + int odd = 0; + int even = 0; + + int length = barcode_data->type_obj->min_digits; + + //Get sum of odd digits + for(int i = 0; i < length; i += 2) { + odd += furi_string_get_char(barcode_data->raw_data, i) - '0'; + } + + //Get sum of even digits + for(int i = 1; i < length; i += 2) { + even += furi_string_get_char(barcode_data->raw_data, i) - '0'; + } + + if(barcode_data->type_obj->type == EAN13) { + check_digit = even * 3 + odd; + } else { + check_digit = odd * 3 + even; + } + + check_digit = check_digit % 10; + + return (10 - check_digit) % 10; +} + +/** + * Loads and validates Barcode Types EAN-8, EAN-13, and UPC-A + * barcode_data and its strings should already be allocated; +*/ +void ean_upc_loader(BarcodeData* barcode_data) { + int barcode_length = furi_string_size(barcode_data->raw_data); + + int min_digits = barcode_data->type_obj->min_digits; + int max_digit = barcode_data->type_obj->max_digits; + + //check the length of the barcode + if(barcode_length < min_digits || barcode_length > max_digit) { + barcode_data->reason = WrongNumberOfDigits; + barcode_data->valid = false; + return; + } + + //checks if the barcode contains any characters that aren't a number + for(int i = 0; i < barcode_length; i++) { + char character = furi_string_get_char(barcode_data->raw_data, i); + int digit = character - '0'; //convert the number into an int (also the index) + if(digit < 0 || digit > 9) { + barcode_data->reason = InvalidCharacters; + barcode_data->valid = false; + return; + } + } + + int check_digit = calculate_check_digit(barcode_data); + char check_digit_char = check_digit + '0'; + + barcode_data->check_digit = check_digit; + + //if the barcode length is at max length then we will verify if the check digit is correct + if(barcode_length == max_digit) { + //append the raw_data to the correct data string + furi_string_cat(barcode_data->correct_data, barcode_data->raw_data); + + //append the check digit to the correct data string + furi_string_set_char(barcode_data->correct_data, min_digits, check_digit_char); + } + //if the barcode length is at min length, we will calculate the check digit + if(barcode_length == min_digits) { + //append the raw_data to the correct data string + furi_string_cat(barcode_data->correct_data, barcode_data->raw_data); + + //append the check digit to the correct data string + furi_string_push_back(barcode_data->correct_data, check_digit_char); + } +} + +void code_39_loader(BarcodeData* barcode_data) { + int barcode_length = furi_string_size(barcode_data->raw_data); + + int min_digits = barcode_data->type_obj->min_digits; + int max_digit = barcode_data->type_obj->max_digits; + + //check the length of the barcode, must contain atleast a character, + //this can have as many characters as it wants, it might not fit on the screen + if(barcode_length < min_digits) { + barcode_data->reason = WrongNumberOfDigits; + barcode_data->valid = false; + return; + } + + FuriString* barcode_bits = furi_string_alloc(); + FuriString* temp_string = furi_string_alloc(); + + //add starting and ending * + if(!furi_string_start_with(barcode_data->raw_data, "*")) { + furi_string_push_back(temp_string, '*'); + furi_string_cat(temp_string, barcode_data->raw_data); + furi_string_set(barcode_data->raw_data, temp_string); + } + + if(!furi_string_end_with(barcode_data->raw_data, "*")) { + furi_string_push_back(barcode_data->raw_data, '*'); + } + + furi_string_free(temp_string); + barcode_length = furi_string_size(barcode_data->raw_data); + + //Open Storage + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* ff = flipper_format_file_alloc(storage); + + if(!flipper_format_file_open_existing(ff, CODE39_DICT_FILE_PATH)) { + FURI_LOG_E(TAG, "Could not open file %s", CODE39_DICT_FILE_PATH); + barcode_data->reason = MissingEncodingTable; + barcode_data->valid = false; + } else { + FuriString* char_bits = furi_string_alloc(); + for(int i = 0; i < barcode_length; i++) { + char barcode_char = toupper(furi_string_get_char(barcode_data->raw_data, i)); + + //convert a char into a string so it used in flipper_format_read_string + char current_character[2]; + snprintf(current_character, 2, "%c", barcode_char); + + if(!flipper_format_read_string(ff, current_character, char_bits)) { + FURI_LOG_E(TAG, "Could not read \"%c\" string", barcode_char); + barcode_data->reason = InvalidCharacters; + barcode_data->valid = false; + break; + } else { + FURI_LOG_I( + TAG, "\"%c\" string: %s", barcode_char, furi_string_get_cstr(char_bits)); + furi_string_cat(barcode_bits, char_bits); + } + flipper_format_rewind(ff); + } + furi_string_free(char_bits); + } + + //Close Storage + flipper_format_free(ff); + furi_record_close(RECORD_STORAGE); + + furi_string_cat(barcode_data->correct_data, barcode_bits); + furi_string_free(barcode_bits); +} + +/** + * Loads a code 128 barcode + * + * Only supports character set B +*/ +void code_128_loader(BarcodeData* barcode_data) { + int barcode_length = furi_string_size(barcode_data->raw_data); + + //the start code for character set B + int start_code_value = 104; + + //The bits for the start code + const char* start_code_bits = "11010010000"; + + //The bits for the stop code + const char* stop_code_bits = "1100011101011"; + + int min_digits = barcode_data->type_obj->min_digits; + int max_digit = barcode_data->type_obj->max_digits; + + /** + * A sum of all of the characters values + * Ex: + * Barcode Data : ABC + * A has a value of 33 + * B has a value of 34 + * C has a value of 35 + * + * the checksum_adder would be (33 * 1) + (34 * 2) + (35 * 3) + 104 = 310 + * + * Add 104 since we are using set B + */ + int checksum_adder = start_code_value; + /** + * Checksum digits is the number of characters it has read so far + * In the above example the checksum_digits would be 3 + */ + int checksum_digits = 0; + + //the calculated check digit + int final_check_digit = 0; + + //check the length of the barcode, must contain atleast a character, + //this can have as many characters as it wants, it might not fit on the screen + if(barcode_length < min_digits) { + barcode_data->reason = WrongNumberOfDigits; + barcode_data->valid = false; + return; + } + + //Open Storage + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* ff = flipper_format_file_alloc(storage); + + FuriString* barcode_bits = furi_string_alloc(); + + //add the start code + furi_string_cat(barcode_bits, start_code_bits); + + if(!flipper_format_file_open_existing(ff, CODE128_DICT_FILE_PATH)) { + FURI_LOG_E(TAG, "Could not open file %s", CODE128_DICT_FILE_PATH); + barcode_data->reason = MissingEncodingTable; + barcode_data->valid = false; + } else { + FuriString* value = furi_string_alloc(); + FuriString* char_bits = furi_string_alloc(); + for(int i = 0; i < barcode_length; i++) { + char barcode_char = furi_string_get_char(barcode_data->raw_data, i); + + //convert a char into a string so it used in flipper_format_read_string + char current_character[2]; + snprintf(current_character, 2, "%c", barcode_char); + + //get the value of the character + if(!flipper_format_read_string(ff, current_character, value)) { + FURI_LOG_E(TAG, "Could not read \"%c\" string", barcode_char); + barcode_data->reason = InvalidCharacters; + barcode_data->valid = false; + break; + } + //using the value of the character, get the characters bits + if(!flipper_format_read_string(ff, furi_string_get_cstr(value), char_bits)) { + FURI_LOG_E(TAG, "Could not read \"%c\" string", barcode_char); + barcode_data->reason = EncodingTableError; + barcode_data->valid = false; + break; + } else { + //add the bits to the full barcode + furi_string_cat(barcode_bits, char_bits); + + //calculate the checksum + checksum_digits += 1; + checksum_adder += (atoi(furi_string_get_cstr(value)) * checksum_digits); + + FURI_LOG_D( + TAG, + "\"%c\" string: %s : %s : %d : %d : %d", + barcode_char, + furi_string_get_cstr(char_bits), + furi_string_get_cstr(value), + checksum_digits, + (atoi(furi_string_get_cstr(value)) * checksum_digits), + checksum_adder); + } + //bring the file pointer back to the beginning + flipper_format_rewind(ff); + } + + //calculate the check digit and convert it into a c string for lookup in the encoding table + final_check_digit = checksum_adder % 103; + int length = snprintf(NULL, 0, "%d", final_check_digit); + char* final_check_digit_string = malloc(length + 1); + snprintf(final_check_digit_string, length + 1, "%d", final_check_digit); + + //after the checksum has been calculated, add the bits to the full barcode + if(!flipper_format_read_string(ff, final_check_digit_string, char_bits)) { + FURI_LOG_E(TAG, "Could not read \"%s\" string", final_check_digit_string); + barcode_data->reason = EncodingTableError; + barcode_data->valid = false; + } else { + //add the check digit bits to the full barcode + furi_string_cat(barcode_bits, char_bits); + + FURI_LOG_D( + TAG, + "\"%s\" string: %s", + final_check_digit_string, + furi_string_get_cstr(char_bits)); + } + + free(final_check_digit_string); + furi_string_free(value); + furi_string_free(char_bits); + } + + //add the stop code + furi_string_cat(barcode_bits, stop_code_bits); + + //Close Storage + flipper_format_free(ff); + furi_record_close(RECORD_STORAGE); + + furi_string_cat(barcode_data->correct_data, barcode_bits); + furi_string_free(barcode_bits); +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_validator.h b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_validator.h new file mode 100644 index 000000000..962d14729 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/barcode_validator.h @@ -0,0 +1,13 @@ +#pragma once + +#include "barcode_app.h" + +int calculate_check_digit(BarcodeData* barcode_data); +int calculate_ean_upc_check_digit(BarcodeData* barcode_data); +void ean_upc_loader(BarcodeData* barcode_data); +void upc_a_loader(BarcodeData* barcode_data); +void ean_8_loader(BarcodeData* barcode_data); +void ean_13_loader(BarcodeData* barcode_data); +void code_39_loader(BarcodeData* barcode_data); +void code_128_loader(BarcodeData* barcode_data); +void barcode_loader(BarcodeData* barcode_data); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/encodings.c b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/encodings.c new file mode 100644 index 000000000..764fde796 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/encodings.c @@ -0,0 +1,52 @@ +#include "encodings.h" + +const char EAN_13_STRUCTURE_CODES[10][6] = { + "LLLLLL", + "LLGLGG", + "LLGGLG", + "LLGGGL", + "LGLLGG", + "LGGLLG", + "LGGGLL", + "LGLGLG", + "LGLGGL", + "LGGLGL"}; + +const char UPC_EAN_L_CODES[10][8] = { + "0001101", // 0 + "0011001", // 1 + "0010011", // 2 + "0111101", // 3 + "0100011", // 4 + "0110001", // 5 + "0101111", // 6 + "0111011", // 7 + "0110111", // 8 + "0001011" // 9 +}; + +const char EAN_G_CODES[10][8] = { + "0100111", // 0 + "0110011", // 1 + "0011011", // 2 + "0100001", // 3 + "0011101", // 4 + "0111001", // 5 + "0000101", // 6 + "0010001", // 7 + "0001001", // 8 + "0010111" // 9 +}; + +const char UPC_EAN_R_CODES[10][8] = { + "1110010", // 0 + "1100110", // 1 + "1101100", // 2 + "1000010", // 3 + "1011100", // 4 + "1001110", // 5 + "1010000", // 6 + "1000100", // 7 + "1001000", // 8 + "1110100" // 9 +}; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/encodings.h b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/encodings.h new file mode 100644 index 000000000..c5b8d61ff --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/encodings.h @@ -0,0 +1,6 @@ +#pragma once + +extern const char EAN_13_STRUCTURE_CODES[10][6]; +extern const char UPC_EAN_L_CODES[10][8]; +extern const char EAN_G_CODES[10][8]; +extern const char UPC_EAN_R_CODES[10][8]; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/images/barcode_10.png b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/images/barcode_10.png new file mode 100644 index 0000000000000000000000000000000000000000..32d4971ad355874ef62be4cf9eb9586fdef48ad7 GIT binary patch literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2ZGmxy8xzq=w7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1M1^9%x0_p$%|1Z5c|1OZlS>O>_%)r2R2!t6$HM|;tf-0Uajv*44lM@6) zL{btGSSB$ks7+8-IB?=bM{COorw}H~CLRWdH%zMMw$JzmRL|h)>gTe~DWM4f+!!l! literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/screenshots/Creating Barcode.png b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/screenshots/Creating Barcode.png new file mode 100644 index 0000000000000000000000000000000000000000..e976b5682a82cb4f18f8e92893876b0733d7be1a GIT binary patch literal 1681 zcmcgtdraF^6h4K4JPHUzo&^>Ot^pBD2MV(V9UHJH8P33ft*|iGXh-O*l}B63G!RV) z9eV&(9?|{*i)$Mo4uloD;#QrdKS;1$8Mf=t7I}=&biPDPzIDq@n?2NZR zsA^yO?QZj76MjjE4Vjx~+7d0_p2XD!b)V+(^UFMylS;wCDy7&f;A zEUR_H!bX^B#`7@fj)E@&pbool=wVMDy10ZFN;)k!HS?QiqUrp4&TJ#GJ2QfWyw2_u zn;5j?0J$#kVvHTe$UxV6EvFXWr{PWODK%!EB#PFaDR@iP&odL)g&Nzt(YxV$G)Z;b zMUHJ6#~LWpTGcOUQ#k`-%tFhrGF|M`XCvdcvN50fCeUM`<>l=VwCONW?ghCYqgzvJ zeuPKj^sh`)rFe;Yy`zCcJ@TMn0p*lTYq4uvuXrX(Qm9eQ4}Vqd*F|W>_jXoJRk%x6 z@BqXU0N);fgRw&Q5~4wsNAx?r#Na>a(U;fjS@qOJmtC%Ej?Aay)(g1wMgt!5HWv|H z=WL^DpjIA9z~xnS0{;mricDER@%wu8X6^l-fkN1~h&ys`YZ=F!n$_e)rrEf) z$^j-htx^#j*tkuEBdrDn)Y(WEnp9>2QgUEhReMrN-@8+$@ITR?-cSwctF^0Kb!iCm zHB6bdFx-M>6N|ZmVH!rUu@H*-n*zs!-{YaAi`jj;RUEaMD~YlUKm5EtH*=iF9+68) z2Bkt4q}U*b?46Ie9Xv5-xs!jXd(>N(O3qP|43(;DT~4`muF;{g&<{J~EfsE|Z8G}W zH7C|T9QC}jmU=gr-ZWMqGopw2f_r;Z&-0RXZYTSoqH3MT%DPm3Sv>pCUu1 zl4@I?uVBV}0Rm?u)^1kThW>X4o}#iiN`ogj@(2Nx@;s=NDieIGGv$w{a z_#U6Zh=k?V+Og0>uA(h_mF;-`e+7b!fHHLJ1eI`N1y=o(R9m`zegAW5 z2HWqO{TUjHIT#$KFfh1q;-PH&><;|>`}z3w>E{)q_NBkQ>7x8z(z1QxM&;*wzD7hp zmznwe#p?}bWtr>G7rwqB7;fJ_v(oL&*Lw3}U$k^IdiTD4yxi_P^-<@H zKUo=^=VDOsVqjRr!k}uGMS-v2W>+w^asLAucWW)t~#lw{dgg;Bx3M%^>bP0l+XkK2Z=AV literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/screenshots/Flipper Box Barcode.png b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/screenshots/Flipper Box Barcode.png new file mode 100644 index 0000000000000000000000000000000000000000..8dbd7d2a9c1b0564a1a2188e6de48fe9370ad426 GIT binary patch literal 1372 zcmeAS@N?(olHy`uVBq!ia0y~yU;;8388|?c*QZDWAjMhW5n0T@z;^_M8K-LVNi#68 z@_D*AhE&XXd)M3VwE=^}MfN1iHT|v|?5;K6<0%!=419F!rEPl4Dzo{=UTEdb-t)Jv z{vY##=e6J17!2AO7+g3R9H!u*t{i{EYw`N;>*w#^AAc>CYrF63E%)kq`=3jBRd379 z-s`?S_e)jy?Ka!>dtZHATWTxy@t&OQ;c(gGf{#D1`af6j{LRmQ7N6e9ozB1z$iyI^ zI!cWO!H`M?`TOtB-@N_dl<({3@82)~J@s|rtRCTSD|&^IQndW$us;^dx21lGx!qB@ zclEdI^F?m@|6f!WO;4S-@zV^;UF#x`Kk7^V9cszU&>_Uopuxz{QS~aF!Tq^>`q}OC zBA<2qon`ue_w%3Sk$~yq>ajDi76?7FzF9ZuDnE;s&yBsGoVxYB z>H2N@L_AKW^J5uTZKKS~}5{XBJZ&y8os_ov?b{P*>0yYPxoyXX8zo#$ z{h9gt{2Bvsn@6?Mg@5O)j2BYgfF$?abI_=KPCw;X0F^`vvZs1y6c9o=N(pl*O@i*eBpG%&FQh5>$Y!9k4^tp tzSVHE5mM-0wqs^U&_fcySC0H=oN}tJOPWI=6Ifg_c)I$ztaD0e0suzQQWgLJ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/barcode_view.c b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/barcode_view.c new file mode 100644 index 000000000..afd727b63 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/barcode_view.c @@ -0,0 +1,444 @@ +#include "../barcode_app.h" +#include "barcode_view.h" +#include "../encodings.h" + +/** + * @brief Draws a single bit from a barcode at a specified location + * @param canvas + * @param bit a 1 or a 0 to signify a bit of data + * @param x the top left x coordinate + * @param y the top left y coordinate + * @param width the width of the bit + * @param height the height of the bit + */ +static void draw_bit(Canvas* canvas, int bit, int x, int y, int width, int height) { + if(bit == 1) { + canvas_set_color(canvas, ColorBlack); + } else { + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_box(canvas, x, y, width, height); +} + +/** + * +*/ +static void draw_error_str(Canvas* canvas, const char* error) { + canvas_clear(canvas); + canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignCenter, error); +} + +/** + * @param bits a string of 1's and 0's + * @returns the x coordinate after the bits have been drawn, useful for drawing the next section of bits +*/ +static int draw_bits(Canvas* canvas, const char* bits, int x, int y, int width, int height) { + int bits_length = strlen(bits); + for(int i = 0; i < bits_length; i++) { + char c = bits[i]; + int num = c - '0'; + + draw_bit(canvas, num, x, y, width, height); + + x += width; + } + return x; +} + +/** + * Draws an EAN-8 type barcode, does not check if the barcode is valid + * @param canvas the canvas + * @param barcode_digits the digits in the barcode, must be 8 characters long +*/ +static void draw_ean_8(Canvas* canvas, BarcodeData* barcode_data) { + FuriString* barcode_digits = barcode_data->correct_data; + BarcodeTypeObj* type_obj = barcode_data->type_obj; + + int barcode_length = furi_string_size(barcode_digits); + + int x = type_obj->start_pos; + int y = BARCODE_Y_START; + int width = 1; + int height = BARCODE_HEIGHT; + + //the guard patterns for the beginning, center, ending + const char* end_bits = "101"; + const char* center_bits = "01010"; + + //draw the starting guard pattern + x = draw_bits(canvas, end_bits, x, y, width, height + 5); + + FuriString* code_part = furi_string_alloc(); + + //loop through each digit, find the encoding, and draw it + for(int i = 0; i < barcode_length; i++) { + char current_digit = furi_string_get_char(barcode_digits, i); + + //the actual number and the index of the bits + int index = current_digit - '0'; + //use the L-codes for the first 4 digits and the R-Codes for the last 4 digits + if(i <= 3) { + furi_string_set_str(code_part, UPC_EAN_L_CODES[index]); + } else { + furi_string_set_str(code_part, UPC_EAN_R_CODES[index]); + } + + //convert the current_digit char into a string so it can be printed + char current_digit_string[2]; + snprintf(current_digit_string, 2, "%c", current_digit); + + //set the canvas color to black to print the digit + canvas_set_color(canvas, ColorBlack); + canvas_draw_str(canvas, x + 1, y + height + 8, current_digit_string); + + //draw the bits of the barcode + x = draw_bits(canvas, furi_string_get_cstr(code_part), x, y, width, height); + + //if the index has reached 3, that means 4 digits have been drawn and now draw the center guard pattern + if(i == 3) { + x = draw_bits(canvas, center_bits, x, y, width, height + 5); + } + } + furi_string_free(code_part); + + //draw the ending guard pattern + x = draw_bits(canvas, end_bits, x, y, width, height + 5); +} + +static void draw_ean_13(Canvas* canvas, BarcodeData* barcode_data) { + FuriString* barcode_digits = barcode_data->correct_data; + BarcodeTypeObj* type_obj = barcode_data->type_obj; + + int barcode_length = furi_string_size(barcode_digits); + + int x = type_obj->start_pos; + int y = BARCODE_Y_START; + int width = 1; + int height = BARCODE_HEIGHT; + + //the guard patterns for the beginning, center, ending + const char* end_bits = "101"; + const char* center_bits = "01010"; + + //draw the starting guard pattern + x = draw_bits(canvas, end_bits, x, y, width, height + 5); + + FuriString* left_structure = furi_string_alloc(); + FuriString* code_part = furi_string_alloc(); + + //loop through each digit, find the encoding, and draw it + for(int i = 0; i < barcode_length; i++) { + char current_digit = furi_string_get_char(barcode_digits, i); + int index = current_digit - '0'; + + if(i == 0) { + furi_string_set_str(left_structure, EAN_13_STRUCTURE_CODES[index]); + + //convert the current_digit char into a string so it can be printed + char current_digit_string[2]; + snprintf(current_digit_string, 2, "%c", current_digit); + + //set the canvas color to black to print the digit + canvas_set_color(canvas, ColorBlack); + canvas_draw_str(canvas, x - 10, y + height + 8, current_digit_string); + + continue; + } else { + //use the L-codes for the first 6 digits and the R-Codes for the last 6 digits + if(i <= 6) { + //get the encoding type at the current barcode bit position + char encoding_type = furi_string_get_char(left_structure, i - 1); + if(encoding_type == 'L') { + furi_string_set_str(code_part, UPC_EAN_L_CODES[index]); + } else { + furi_string_set_str(code_part, EAN_G_CODES[index]); + } + } else { + furi_string_set_str(code_part, UPC_EAN_R_CODES[index]); + } + + //convert the current_digit char into a string so it can be printed + char current_digit_string[2]; + snprintf(current_digit_string, 2, "%c", current_digit); + + //set the canvas color to black to print the digit + canvas_set_color(canvas, ColorBlack); + canvas_draw_str(canvas, x + 1, y + height + 8, current_digit_string); + + //draw the bits of the barcode + x = draw_bits(canvas, furi_string_get_cstr(code_part), x, y, width, height); + + //if the index has reached 6, that means 6 digits have been drawn and we now draw the center guard pattern + if(i == 6) { + x = draw_bits(canvas, center_bits, x, y, width, height + 5); + } + } + } + + furi_string_free(left_structure); + furi_string_free(code_part); + + //draw the ending guard pattern + x = draw_bits(canvas, end_bits, x, y, width, height + 5); +} + +/** + * Draw a UPC-A barcode +*/ +static void draw_upc_a(Canvas* canvas, BarcodeData* barcode_data) { + FuriString* barcode_digits = barcode_data->correct_data; + BarcodeTypeObj* type_obj = barcode_data->type_obj; + + int barcode_length = furi_string_size(barcode_digits); + + int x = type_obj->start_pos; + int y = BARCODE_Y_START; + int width = 1; + int height = BARCODE_HEIGHT; + + //the guard patterns for the beginning, center, ending + char* end_bits = "101"; + char* center_bits = "01010"; + + //draw the starting guard pattern + x = draw_bits(canvas, end_bits, x, y, width, height + 5); + + FuriString* code_part = furi_string_alloc(); + + //loop through each digit, find the encoding, and draw it + for(int i = 0; i < barcode_length; i++) { + char current_digit = furi_string_get_char(barcode_digits, i); + int index = current_digit - '0'; //convert the number into an int (also the index) + + //use the L-codes for the first 6 digits and the R-Codes for the last 6 digits + if(i <= 5) { + furi_string_set_str(code_part, UPC_EAN_L_CODES[index]); + } else { + furi_string_set_str(code_part, UPC_EAN_R_CODES[index]); + } + + //convert the current_digit char into a string so it can be printed + char current_digit_string[2]; + snprintf(current_digit_string, 2, "%c", current_digit); + + //set the canvas color to black to print the digit + canvas_set_color(canvas, ColorBlack); + canvas_draw_str(canvas, x + 1, y + height + 8, current_digit_string); + + //draw the bits of the barcode + x = draw_bits(canvas, furi_string_get_cstr(code_part), x, y, width, height); + + //if the index has reached 6, that means 6 digits have been drawn and we now draw the center guard pattern + if(i == 5) { + x = draw_bits(canvas, center_bits, x, y, width, height + 5); + } + } + + furi_string_free(code_part); + + //draw the ending guard pattern + x = draw_bits(canvas, end_bits, x, y, width, height + 5); +} + +static void draw_code_39(Canvas* canvas, BarcodeData* barcode_data) { + FuriString* raw_data = barcode_data->raw_data; + FuriString* barcode_digits = barcode_data->correct_data; + //BarcodeTypeObj* type_obj = barcode_data->type_obj; + + int barcode_length = furi_string_size(barcode_digits); + int total_pixels = 0; + + for(int i = 0; i < barcode_length; i++) { + //1 for wide, 0 for narrow + char wide_or_narrow = furi_string_get_char(barcode_digits, i); + int wn_digit = wide_or_narrow - '0'; //wide(1) or narrow(0) digit + + if(wn_digit == 1) { + total_pixels += 3; + } else { + total_pixels += 1; + } + if((i + 1) % 9 == 0) { + total_pixels += 1; + } + } + + int x = (128 - total_pixels) / 2; + int y = BARCODE_Y_START; + int width = 1; + int height = BARCODE_HEIGHT; + bool filled_in = true; + + //set the canvas color to black to print the digit + canvas_set_color(canvas, ColorBlack); + // canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignCenter, error); + canvas_draw_str_aligned( + canvas, 62, y + height + 8, AlignCenter, AlignBottom, furi_string_get_cstr(raw_data)); + + for(int i = 0; i < barcode_length; i++) { + //1 for wide, 0 for narrow + char wide_or_narrow = furi_string_get_char(barcode_digits, i); + int wn_digit = wide_or_narrow - '0'; //wide(1) or narrow(0) digit + + if(filled_in) { + if(wn_digit == 1) { + x = draw_bits(canvas, "111", x, y, width, height); + } else { + x = draw_bits(canvas, "1", x, y, width, height); + } + filled_in = false; + } else { + if(wn_digit == 1) { + x = draw_bits(canvas, "000", x, y, width, height); + } else { + x = draw_bits(canvas, "0", x, y, width, height); + } + filled_in = true; + } + if((i + 1) % 9 == 0) { + x = draw_bits(canvas, "0", x, y, width, height); + filled_in = true; + } + } +} + +static void draw_code_128(Canvas* canvas, BarcodeData* barcode_data) { + FuriString* raw_data = barcode_data->raw_data; + FuriString* barcode_digits = barcode_data->correct_data; + + int barcode_length = furi_string_size(barcode_digits); + + int x = (128 - barcode_length) / 2; + int y = BARCODE_Y_START; + int width = 1; + int height = BARCODE_HEIGHT; + + x = draw_bits(canvas, furi_string_get_cstr(barcode_digits), x, y, width, height); + + //set the canvas color to black to print the digit + canvas_set_color(canvas, ColorBlack); + // canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignCenter, error); + canvas_draw_str_aligned( + canvas, 62, y + height + 8, AlignCenter, AlignBottom, furi_string_get_cstr(raw_data)); +} + +static void barcode_draw_callback(Canvas* canvas, void* ctx) { + furi_assert(ctx); + BarcodeModel* barcode_model = ctx; + BarcodeData* data = barcode_model->data; + // const char* barcode_digits =; + + canvas_clear(canvas); + if(data->valid) { + switch(data->type_obj->type) { + case UPCA: + draw_upc_a(canvas, data); + break; + case EAN8: + draw_ean_8(canvas, data); + break; + case EAN13: + draw_ean_13(canvas, data); + break; + case CODE39: + draw_code_39(canvas, data); + break; + case CODE128: + draw_code_128(canvas, data); + break; + case UNKNOWN: + default: + break; + } + } else { + switch(data->reason) { + case WrongNumberOfDigits: + draw_error_str(canvas, "Wrong # of characters"); + break; + case InvalidCharacters: + draw_error_str(canvas, "Invalid characters"); + break; + case UnsupportedType: + draw_error_str(canvas, "Unsupported barcode type"); + break; + case FileOpening: + draw_error_str(canvas, "Could not open file"); + break; + case InvalidFileData: + draw_error_str(canvas, "Invalid file data"); + break; + case MissingEncodingTable: + draw_error_str(canvas, "Missing encoding table"); + break; + case EncodingTableError: + draw_error_str(canvas, "Encoding table error"); + break; + default: + draw_error_str(canvas, "Could not read barcode data"); + break; + } + } +} + +bool barcode_input_callback(InputEvent* input_event, void* ctx) { + UNUSED(ctx); + //furi_assert(ctx); + + //Barcode* test_view_object = ctx; + + if(input_event->key == InputKeyBack) { + return false; + } else { + return true; + } +} + +Barcode* barcode_view_allocate(BarcodeApp* barcode_app) { + furi_assert(barcode_app); + + Barcode* barcode = malloc(sizeof(Barcode)); + + barcode->view = view_alloc(); + barcode->barcode_app = barcode_app; + + view_set_context(barcode->view, barcode); + view_allocate_model(barcode->view, ViewModelTypeLocking, sizeof(BarcodeModel)); + view_set_draw_callback(barcode->view, barcode_draw_callback); + view_set_input_callback(barcode->view, barcode_input_callback); + + return barcode; +} + +void barcode_free_model(Barcode* barcode) { + with_view_model( + barcode->view, + BarcodeModel * model, + { + if(model->file_path != NULL) { + furi_string_free(model->file_path); + } + if(model->data != NULL) { + if(model->data->raw_data != NULL) { + furi_string_free(model->data->raw_data); + } + if(model->data->correct_data != NULL) { + furi_string_free(model->data->correct_data); + } + free(model->data); + } + }, + false); +} + +void barcode_free(Barcode* barcode) { + furi_assert(barcode); + + barcode_free_model(barcode); + view_free(barcode->view); + free(barcode); +} + +View* barcode_get_view(Barcode* barcode) { + furi_assert(barcode); + return barcode->view; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/barcode_view.h b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/barcode_view.h new file mode 100644 index 000000000..828428c08 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/barcode_view.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +typedef struct BarcodeApp BarcodeApp; + +typedef struct { + View* view; + BarcodeApp* barcode_app; +} Barcode; + +typedef struct { + FuriString* file_path; + BarcodeData* data; +} BarcodeModel; + +Barcode* barcode_view_allocate(BarcodeApp* barcode_app); + +void barcode_free_model(Barcode* barcode); + +void barcode_free(Barcode* barcode); + +View* barcode_get_view(Barcode* barcode); diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/create_view.c b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/create_view.c new file mode 100644 index 000000000..23a5fa409 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/create_view.c @@ -0,0 +1,493 @@ +#include "../barcode_app.h" +#include "create_view.h" +#include + +#define LINE_HEIGHT 16 +#define TEXT_PADDING 4 +#define TOTAL_MENU_ITEMS 5 + +typedef enum { + TypeMenuItem, + FileNameMenuItem, + BarcodeDataMenuItem, + SaveMenuButton, + DeleteMenuButton +} MenuItems; + +/** + * Took this function from blackjack + * @author @teeebor +*/ +void draw_menu_item( + Canvas* const canvas, + const char* text, + const char* value, + int y, + bool left_caret, + bool right_caret, + bool selected) { + UNUSED(selected); + if(y < 0 || y >= 64) { + return; + } + + if(selected) { + canvas_set_color(canvas, ColorBlack); + canvas_draw_box(canvas, 0, y, 123, LINE_HEIGHT); + canvas_set_color(canvas, ColorWhite); + } + + canvas_draw_str_aligned(canvas, 4, y + TEXT_PADDING, AlignLeft, AlignTop, text); + if(left_caret) { + canvas_draw_str_aligned(canvas, 60, y + TEXT_PADDING, AlignLeft, AlignTop, "<"); + } + + canvas_draw_str_aligned(canvas, 90, y + TEXT_PADDING, AlignCenter, AlignTop, value); + if(right_caret) { + canvas_draw_str_aligned(canvas, 120, y + TEXT_PADDING, AlignRight, AlignTop, ">"); + } + + canvas_set_color(canvas, ColorBlack); +} + +void draw_button(Canvas* const canvas, const char* text, int y, bool selected) { + if(selected) { + canvas_set_color(canvas, ColorBlack); + canvas_draw_box(canvas, 0, y, 123, LINE_HEIGHT); + canvas_set_color(canvas, ColorWhite); + } + + canvas_draw_str_aligned(canvas, 64, y + TEXT_PADDING, AlignCenter, AlignTop, text); + + canvas_set_color(canvas, ColorBlack); +} + +static void app_draw_callback(Canvas* canvas, void* ctx) { + furi_assert(ctx); + + CreateViewModel* create_view_model = ctx; + + BarcodeTypeObj* type_obj = create_view_model->barcode_type; + if(create_view_model->barcode_type == NULL) { + return; + } + BarcodeType selected_type = type_obj->type; + + int selected_menu_item = create_view_model->selected_menu_item; + + int total_menu_items = create_view_model->mode == EditMode ? TOTAL_MENU_ITEMS : + TOTAL_MENU_ITEMS - 1; + + int startY = 0; + + //the menu items index that is/would be in view + //int current_last_menu_item = selected_menu_item + 3; + if(selected_menu_item > 1) { + int offset = 2; + if(selected_menu_item + offset > total_menu_items) { + offset = 3; + } + startY -= (LINE_HEIGHT * (selected_menu_item - offset)); + } + + //ensure that the scroll height is atleast 1 + int scrollHeight = ceil(64.0 / total_menu_items); + int scrollPos = scrollHeight * selected_menu_item; + + canvas_set_color(canvas, ColorBlack); + //draw the scroll bar box + canvas_draw_box(canvas, 125, scrollPos, 3, scrollHeight); + //draw the scroll bar track + canvas_draw_box(canvas, 126, 0, 1, 64); + + draw_menu_item( + canvas, + "Type", + type_obj->name, + TypeMenuItem * LINE_HEIGHT + startY, + selected_type > 0, + selected_type < NUMBER_OF_BARCODE_TYPES - 2, + selected_menu_item == TypeMenuItem); + + draw_menu_item( + canvas, + "Name", + furi_string_empty(create_view_model->file_name) ? + "--" : + furi_string_get_cstr(create_view_model->file_name), + FileNameMenuItem * LINE_HEIGHT + startY, + false, + false, + selected_menu_item == FileNameMenuItem); + + draw_menu_item( + canvas, + "Data", + furi_string_empty(create_view_model->barcode_data) ? + "--" : + furi_string_get_cstr(create_view_model->barcode_data), + BarcodeDataMenuItem * LINE_HEIGHT + startY, + false, + false, + selected_menu_item == BarcodeDataMenuItem); + + draw_button( + canvas, + "Save", + SaveMenuButton * LINE_HEIGHT + startY, + selected_menu_item == SaveMenuButton); + + if(create_view_model->mode == EditMode) { + draw_button( + canvas, + "Delete", + DeleteMenuButton * LINE_HEIGHT + startY, + selected_menu_item == DeleteMenuButton); + } +} + +void text_input_callback(void* ctx) { + CreateView* create_view_object = ctx; + + with_view_model( + create_view_object->view, + CreateViewModel * model, + { + if(create_view_object->setter == FileNameSetter) { + furi_string_set_str(model->file_name, create_view_object->input); + } + if(create_view_object->setter == BarcodeDataSetter) { + furi_string_set_str(model->barcode_data, create_view_object->input); + } + }, + true); + + view_dispatcher_switch_to_view( + create_view_object->barcode_app->view_dispatcher, CreateBarcodeView); +} + +static bool app_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + + if(input_event->key == InputKeyBack) { + return false; + } + + CreateView* create_view_object = ctx; + + //get the currently selected menu item from the model + int selected_menu_item = 0; + BarcodeTypeObj* barcode_type = NULL; + FuriString* file_name; + FuriString* barcode_data; + CreateMode mode; + + with_view_model( + create_view_object->view, + CreateViewModel * model, + { + selected_menu_item = model->selected_menu_item; + barcode_type = model->barcode_type; + file_name = model->file_name; + barcode_data = model->barcode_data; + mode = model->mode; + }, + true); + + int total_menu_items = mode == EditMode ? TOTAL_MENU_ITEMS : TOTAL_MENU_ITEMS - 1; + + if(input_event->type == InputTypePress) { + if(input_event->key == InputKeyUp && selected_menu_item > 0) { + selected_menu_item--; + } else if(input_event->key == InputKeyDown && selected_menu_item < total_menu_items - 1) { + selected_menu_item++; + } else if(input_event->key == InputKeyLeft) { + if(selected_menu_item == TypeMenuItem && barcode_type != NULL) { //Select Barcode Type + if(barcode_type->type > 0) { + barcode_type = barcode_type_objs[barcode_type->type - 1]; + } + } + } else if(input_event->key == InputKeyRight) { + if(selected_menu_item == TypeMenuItem && barcode_type != NULL) { //Select Barcode Type + if(barcode_type->type < NUMBER_OF_BARCODE_TYPES - 2) { + barcode_type = barcode_type_objs[barcode_type->type + 1]; + } + } + } else if(input_event->key == InputKeyOk) { + if(selected_menu_item == FileNameMenuItem && barcode_type != NULL) { + create_view_object->setter = FileNameSetter; + + snprintf( + create_view_object->input, + sizeof(create_view_object->input), + "%s", + furi_string_get_cstr(file_name)); + + text_input_set_result_callback( + create_view_object->barcode_app->text_input, + text_input_callback, + create_view_object, + create_view_object->input, + TEXT_BUFFER_SIZE - BARCODE_EXTENSION_LENGTH, //remove the barcode length + //clear default text + false); + text_input_set_header_text( + create_view_object->barcode_app->text_input, "File Name"); + + view_dispatcher_switch_to_view( + create_view_object->barcode_app->view_dispatcher, TextInputView); + } + if(selected_menu_item == BarcodeDataMenuItem && barcode_type != NULL) { + create_view_object->setter = BarcodeDataSetter; + + snprintf( + create_view_object->input, + sizeof(create_view_object->input), + "%s", + furi_string_get_cstr(barcode_data)); + + text_input_set_result_callback( + create_view_object->barcode_app->text_input, + text_input_callback, + create_view_object, + create_view_object->input, + TEXT_BUFFER_SIZE, + //clear default text + false); + text_input_set_header_text( + create_view_object->barcode_app->text_input, "Barcode Data"); + + view_dispatcher_switch_to_view( + create_view_object->barcode_app->view_dispatcher, TextInputView); + } + if(selected_menu_item == SaveMenuButton && barcode_type != NULL) { + save_barcode(create_view_object); + } + if(selected_menu_item == DeleteMenuButton && barcode_type != NULL) { + if(mode == EditMode) { + remove_barcode(create_view_object); + } else if(mode == NewMode) { + view_dispatcher_switch_to_view( + create_view_object->barcode_app->view_dispatcher, MainMenuView); + } + } + } + } + + //change the currently selected menu item + with_view_model( + create_view_object->view, + CreateViewModel * model, + { + model->selected_menu_item = selected_menu_item; + model->barcode_type = barcode_type; + }, + true); + + return true; +} + +CreateView* create_view_allocate(BarcodeApp* barcode_app) { + furi_assert(barcode_app); + + CreateView* create_view_object = malloc(sizeof(CreateView)); + + create_view_object->view = view_alloc(); + create_view_object->barcode_app = barcode_app; + + view_set_context(create_view_object->view, create_view_object); + view_allocate_model(create_view_object->view, ViewModelTypeLocking, sizeof(CreateViewModel)); + view_set_draw_callback(create_view_object->view, app_draw_callback); + view_set_input_callback(create_view_object->view, app_input_callback); + + return create_view_object; +} + +void create_view_free_model(CreateView* create_view_object) { + with_view_model( + create_view_object->view, + CreateViewModel * model, + { + if(model->file_path != NULL) { + furi_string_free(model->file_path); + } + if(model->file_name != NULL) { + furi_string_free(model->file_name); + } + if(model->barcode_data != NULL) { + furi_string_free(model->barcode_data); + } + }, + true); +} + +void remove_barcode(CreateView* create_view_object) { + Storage* storage = furi_record_open(RECORD_STORAGE); + + bool success = false; + + with_view_model( + create_view_object->view, + CreateViewModel * model, + { + FURI_LOG_I(TAG, "Attempting to remove file"); + if(model->file_path != NULL) { + FURI_LOG_I(TAG, "Removing File: %s", furi_string_get_cstr(model->file_path)); + if(storage_simply_remove(storage, furi_string_get_cstr(model->file_path))) { + FURI_LOG_I( + TAG, + "File: \"%s\" was successfully removed", + furi_string_get_cstr(model->file_path)); + success = true; + } else { + FURI_LOG_E(TAG, "Unable to remove file!"); + success = false; + } + } else { + FURI_LOG_E(TAG, "Could not remove barcode file"); + success = false; + } + }, + true); + furi_record_close(RECORD_STORAGE); + + with_view_model( + create_view_object->barcode_app->message_view->view, + MessageViewModel * model, + { + if(success) { + model->message = "File Deleted"; + } else { + model->message = "Could not delete file"; + } + }, + true); + + view_dispatcher_switch_to_view( + create_view_object->barcode_app->view_dispatcher, MessageErrorView); +} + +void save_barcode(CreateView* create_view_object) { + BarcodeTypeObj* barcode_type = NULL; + FuriString* file_path; //this may be empty + FuriString* file_name; + FuriString* barcode_data; + CreateMode mode; + + with_view_model( + create_view_object->view, + CreateViewModel * model, + { + file_path = model->file_path; + file_name = model->file_name; + barcode_data = model->barcode_data; + barcode_type = model->barcode_type; + mode = model->mode; + }, + true); + + if(file_name == NULL || furi_string_empty(file_name)) { + FURI_LOG_E(TAG, "File Name cannot be empty"); + return; + } + if(barcode_data == NULL || furi_string_empty(barcode_data)) { + FURI_LOG_E(TAG, "Barcode Data cannot be empty"); + return; + } + if(barcode_type == NULL) { + FURI_LOG_E(TAG, "Type not defined"); + return; + } + + bool success = false; + + FuriString* full_file_path = furi_string_alloc_set(DEFAULT_USER_BARCODES); + furi_string_push_back(full_file_path, '/'); + furi_string_cat(full_file_path, file_name); + furi_string_cat_str(full_file_path, BARCODE_EXTENSION); + + Storage* storage = furi_record_open(RECORD_STORAGE); + + if(mode == EditMode) { + if(!furi_string_empty(file_path)) { + if(!furi_string_equal(file_path, full_file_path)) { + FS_Error error = storage_common_rename( + storage, + furi_string_get_cstr(file_path), + furi_string_get_cstr(full_file_path)); + if(error != FSE_OK) { + FURI_LOG_E(TAG, "Rename error: %s", storage_error_get_desc(error)); + } else { + FURI_LOG_I(TAG, "Rename Success"); + } + } + } + } + + FlipperFormat* ff = flipper_format_file_alloc(storage); + + FURI_LOG_I(TAG, "Saving Barcode to: %s", furi_string_get_cstr(full_file_path)); + + bool file_opened_status = false; + if(mode == NewMode) { + file_opened_status = + flipper_format_file_open_new(ff, furi_string_get_cstr(full_file_path)); + } else if(mode == EditMode) { + file_opened_status = + flipper_format_file_open_always(ff, furi_string_get_cstr(full_file_path)); + } + + if(file_opened_status) { + // Filetype: Barcode + // Version: 1 + + // # Types - UPC-A, EAN-8, EAN-13, CODE-39 + // Type: CODE-39 + // Data: AB + flipper_format_write_string_cstr(ff, "Filetype", "Barcode"); + + flipper_format_write_string_cstr(ff, "Version", FILE_VERSION); + + flipper_format_write_comment_cstr(ff, "Types - UPC-A, EAN-8, EAN-13, CODE-39, CODE-128"); + + flipper_format_write_string_cstr(ff, "Type", barcode_type->name); + + flipper_format_write_string_cstr(ff, "Data", furi_string_get_cstr(barcode_data)); + + success = true; + } else { + FURI_LOG_E(TAG, "Save error"); + success = false; + } + furi_string_free(full_file_path); + flipper_format_free(ff); + furi_record_close(RECORD_STORAGE); + + with_view_model( + create_view_object->barcode_app->message_view->view, + MessageViewModel * model, + { + if(success) { + model->message = "File Saved!"; + } else { + model->message = "A saving error has occurred"; + } + }, + true); + + view_dispatcher_switch_to_view( + create_view_object->barcode_app->view_dispatcher, MessageErrorView); +} + +void create_view_free(CreateView* create_view_object) { + furi_assert(create_view_object); + + create_view_free_model(create_view_object); + view_free(create_view_object->view); + free(create_view_object); +} + +View* create_get_view(CreateView* create_view_object) { + furi_assert(create_view_object); + return create_view_object->view; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/create_view.h b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/create_view.h new file mode 100644 index 000000000..6063786d9 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/create_view.h @@ -0,0 +1,46 @@ +#pragma once + +#include + +typedef struct BarcodeApp BarcodeApp; + +typedef enum { + FileNameSetter, + BarcodeDataSetter +} InputSetter; //what value to set for the text input view + +typedef enum { + EditMode, + + NewMode +} CreateMode; + +typedef struct { + View* view; + BarcodeApp* barcode_app; + + InputSetter setter; + char input[TEXT_BUFFER_SIZE]; +} CreateView; + +typedef struct { + int selected_menu_item; + + CreateMode mode; + BarcodeTypeObj* barcode_type; + FuriString* file_path; //the current file that is opened + FuriString* file_name; + FuriString* barcode_data; +} CreateViewModel; + +CreateView* create_view_allocate(BarcodeApp* barcode_app); + +void remove_barcode(CreateView* create_view_object); + +void save_barcode(CreateView* create_view_object); + +void create_view_free_model(CreateView* create_view_object); + +void create_view_free(CreateView* create_view_object); + +View* create_get_view(CreateView* create_view_object); diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/message_view.c b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/message_view.c new file mode 100644 index 000000000..0001e98e6 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/message_view.c @@ -0,0 +1,77 @@ +#include "../barcode_app.h" +#include "message_view.h" + +static void app_draw_callback(Canvas* canvas, void* ctx) { + furi_assert(ctx); + + MessageViewModel* message_view_model = ctx; + + canvas_clear(canvas); + if(message_view_model->message != NULL) { + canvas_draw_str_aligned( + canvas, 62, 30, AlignCenter, AlignCenter, message_view_model->message); + } + + canvas_set_color(canvas, ColorBlack); + canvas_draw_box(canvas, 100, 52, 28, 12); + canvas_set_color(canvas, ColorWhite); + canvas_draw_str_aligned(canvas, 114, 58, AlignCenter, AlignCenter, "OK"); +} + +static bool app_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + + MessageView* message_view_object = ctx; + + if(input_event->key == InputKeyBack) { + view_dispatcher_switch_to_view( + message_view_object->barcode_app->view_dispatcher, MainMenuView); + } + if(input_event->type == InputTypeShort) { + if(input_event->key == InputKeyOk) { + view_dispatcher_switch_to_view( + message_view_object->barcode_app->view_dispatcher, MainMenuView); + } + } + + return true; +} + +MessageView* message_view_allocate(BarcodeApp* barcode_app) { + furi_assert(barcode_app); + + MessageView* message_view_object = malloc(sizeof(MessageView)); + + message_view_object->view = view_alloc(); + message_view_object->barcode_app = barcode_app; + + view_set_context(message_view_object->view, message_view_object); + view_allocate_model(message_view_object->view, ViewModelTypeLocking, sizeof(MessageViewModel)); + view_set_draw_callback(message_view_object->view, app_draw_callback); + view_set_input_callback(message_view_object->view, app_input_callback); + + return message_view_object; +} + +void message_view_free_model(MessageView* message_view_object) { + with_view_model( + message_view_object->view, + MessageViewModel * model, + { + + }, + true); +} + +void message_view_free(MessageView* message_view_object) { + furi_assert(message_view_object); + + message_view_free_model(message_view_object); + view_free(message_view_object->view); + free(message_view_object); +} + +View* message_get_view(MessageView* message_view_object) { + furi_assert(message_view_object); + return message_view_object->view; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/message_view.h b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/message_view.h new file mode 100644 index 000000000..33acc3d0c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/barcode_generator/views/message_view.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +typedef struct BarcodeApp BarcodeApp; + +typedef struct { + View* view; + BarcodeApp* barcode_app; +} MessageView; + +typedef struct { + const char* message; +} MessageViewModel; + +MessageView* message_view_allocate(BarcodeApp* barcode_app); + +void message_view_free_model(MessageView* message_view_object); + +void message_view_free(MessageView* message_view_object); + +View* message_get_view(MessageView* message_view_object); diff --git a/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/LICENSE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/README.md b/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/README.md new file mode 100644 index 000000000..8e88863ee --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/README.md @@ -0,0 +1,14 @@ +# BPM Tapper + +A BPM Tapper for the Flipper Zero. + +![screenshot](img/screenshot.png) + +Hit any button other than back repeatedly. Calculates based on the average of the last 8 inputs. + +## Compiling + +``` +./fbt firmware_bpm_tapper +``` + diff --git a/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/application.fam b/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/application.fam new file mode 100644 index 000000000..e256aaed6 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/application.fam @@ -0,0 +1,13 @@ +App( + appid="BPM_Tapper", + name="BPM Tapper", + apptype=FlipperAppType.EXTERNAL, + entry_point="bpm_tapper_app", + cdefines=["APP_BPM_TAPPER"], + requires=["gui"], + stack_size=2 * 1024, + fap_icon="bpm_10px.png", + fap_category="Music_Extra", + fap_icon_assets="icons", + order=15, +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/bpm.c b/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/bpm.c new file mode 100644 index 000000000..cee83a6a4 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/bpm.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include +#include +#include +#include "BPM_Tapper_icons.h" + +typedef enum { + EventTypeTick, + EventTypeKey, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} PluginEvent; + +//QUEUE + +struct node { + int interval; + struct node* next; +}; +typedef struct node node; + +typedef struct { + int size; + int max_size; + node* front; + node* rear; +} queue; + +static void init_queue(queue* q) { + q->size = 0; + q->max_size = 8; + q->front = NULL; + q->rear = NULL; +} + +static void queue_remove(queue* q) { + node* tmp; + tmp = q->front; + q->front = q->front->next; + q->size--; + free(tmp); +} + +static void queue_add(queue* q, int value) { + node* tmp = malloc(sizeof(node)); + tmp->interval = value; + tmp->next = NULL; + if(q->size == q->max_size) { + queue_remove(q); + } + // check if empty + if(q->rear == NULL) { + q->front = tmp; + q->rear = tmp; + } else { + q->rear->next = tmp; + q->rear = tmp; + } + q->size++; +} + +static float queue_avg(queue* q) { + float avg = 0.0; + if(q->size == 0) { + return avg; + } else { + node* tmp; + float sum = 0.0; + tmp = q->front; + while(tmp != NULL) { + sum = sum + tmp->interval; + tmp = tmp->next; + } + avg = sum / q->size; + FURI_LOG_D("BPM-Tapper", "Sum: %.2f Avg: %.2f", (double)sum, (double)avg); + return avg; + } +} + +// TOO SLOW! +//uint64_t dolphin_state_timestamp() { +// FuriHalRtcDateTime datetime; +// furi_hal_rtc_get_datetime(&datetime); +// return furi_hal_rtc_datetime_to_timestamp(&datetime); +//} +// +typedef struct { + int taps; + double bpm; + uint32_t last_stamp; + uint32_t interval; + queue* tap_queue; +} BPMTapper; + +static void show_hello() { + // BEGIN HELLO DIALOG + DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); + DialogMessage* message = dialog_message_alloc(); + + const char* header_text = "BPM Tapper"; + const char* message_text = "Tap center to start"; + + dialog_message_set_header(message, header_text, 63, 3, AlignCenter, AlignTop); + dialog_message_set_text(message, message_text, 0, 17, AlignLeft, AlignTop); + dialog_message_set_buttons(message, NULL, "Tap", NULL); + + dialog_message_set_icon(message, &I_DolphinCommon_56x48, 72, 17); + + dialog_message_show(dialogs, message); + + dialog_message_free(message); + furi_record_close(RECORD_DIALOGS); + // END HELLO DIALOG +} + +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 render_callback(Canvas* const canvas, void* ctx) { + FuriString* tempStr; + + const BPMTapper* bpm_state = acquire_mutex((ValueMutex*)ctx, 25); + if(bpm_state == NULL) { + return; + } + // border + //canvas_draw_frame(canvas, 0, 0, 128, 64); + canvas_set_font(canvas, FontPrimary); + + tempStr = furi_string_alloc(); + + furi_string_printf(tempStr, "Taps: %d", bpm_state->taps); + canvas_draw_str_aligned(canvas, 5, 10, AlignLeft, AlignBottom, furi_string_get_cstr(tempStr)); + furi_string_reset(tempStr); + + furi_string_printf(tempStr, "Queue: %d", bpm_state->tap_queue->size); + canvas_draw_str_aligned(canvas, 70, 10, AlignLeft, AlignBottom, furi_string_get_cstr(tempStr)); + furi_string_reset(tempStr); + + furi_string_printf(tempStr, "Interval: %ldms", bpm_state->interval); + canvas_draw_str_aligned(canvas, 5, 20, AlignLeft, AlignBottom, furi_string_get_cstr(tempStr)); + furi_string_reset(tempStr); + + furi_string_printf(tempStr, "x2 %.2f /2 %.2f", bpm_state->bpm * 2, bpm_state->bpm / 2); + canvas_draw_str_aligned( + canvas, 64, 60, AlignCenter, AlignCenter, furi_string_get_cstr(tempStr)); + furi_string_reset(tempStr); + + furi_string_printf(tempStr, "%.2f", bpm_state->bpm); + canvas_set_font(canvas, FontBigNumbers); + canvas_draw_str_aligned( + canvas, 64, 40, AlignCenter, AlignCenter, furi_string_get_cstr(tempStr)); + furi_string_reset(tempStr); + + furi_string_free(tempStr); + + release_mutex((ValueMutex*)ctx, bpm_state); +} + +static void bpm_state_init(BPMTapper* const plugin_state) { + plugin_state->taps = 0; + plugin_state->bpm = 120.0; + plugin_state->last_stamp = 0; // furi_get_tick(); + plugin_state->interval = 0; + queue* q; + q = malloc(sizeof(queue)); + init_queue(q); + plugin_state->tap_queue = q; +} + +int32_t bpm_tapper_app(void* p) { + UNUSED(p); + + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); + + BPMTapper* bpm_state = malloc(sizeof(BPMTapper)); + // setup + bpm_state_init(bpm_state); + + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, bpm_state, sizeof(bpm_state))) { + FURI_LOG_E("BPM-Tapper", "cannot create mutex\r\n"); + free(bpm_state); + return 255; + } + show_hello(); + + // BEGIN IMPLEMENTATION + + // Set system callbacks + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, render_callback, &state_mutex); + view_port_input_callback_set(view_port, input_callback, event_queue); + + // Open GUI and register view_port + Gui* gui = furi_record_open("gui"); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + PluginEvent event; + for(bool processing = true; processing;) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); + BPMTapper* bpm_state = (BPMTapper*)acquire_mutex_block(&state_mutex); + if(event_status == FuriStatusOk) { + // press events + if(event.type == EventTypeKey) { + if(event.input.type == InputTypePress) { + switch(event.input.key) { + case InputKeyUp: + case InputKeyDown: + case InputKeyRight: + case InputKeyLeft: + case InputKeyOk: + bpm_state->taps++; + uint32_t new_stamp = furi_get_tick(); + if(bpm_state->last_stamp == 0) { + bpm_state->last_stamp = new_stamp; + break; + } + bpm_state->interval = new_stamp - bpm_state->last_stamp; + bpm_state->last_stamp = new_stamp; + queue_add(bpm_state->tap_queue, bpm_state->interval); + float avg = queue_avg(bpm_state->tap_queue); + float bps = 1.0 / (avg / 1000.0); + bpm_state->bpm = bps * 60.0; + break; + case InputKeyBack: + // Exit the plugin + processing = false; + break; + default: + break; + } + } + } + } else { + FURI_LOG_D("BPM-Tapper", "FuriMessageQueue: event timeout"); + // event timeout + } + view_port_update(view_port); + release_mutex(&state_mutex, bpm_state); + } + 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); + delete_mutex(&state_mutex); + queue* q = bpm_state->tap_queue; + free(q); + free(bpm_state); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/bpm_10px.png b/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/bpm_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..ebf27486ccc443f2c9e12a4ac7d0f5c7afa8f868 GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V6Od#Ihk44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`0h7I;J!GcfQS24TkI`72U@f?l33jv*Sst$mI{3M=&{Dmz&k1q|155PO^5%q;jgjp2 XGIrOm?w|4%XexuJtDnm{r-UW|LGL)B literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/icons/DolphinCommon_56x48.png b/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/icons/DolphinCommon_56x48.png new file mode 100644 index 0000000000000000000000000000000000000000..089aaed83507431993a76ca25d32fdd9664c1c84 GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/images/DolphinCommon_56x48.png b/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/images/DolphinCommon_56x48.png new file mode 100644 index 0000000000000000000000000000000000000000..089aaed83507431993a76ca25d32fdd9664c1c84 GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/img/screenshot.png b/Applications/Official/DEV_FW/source/xMasterX/bpmtapper/img/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..fbba2aad9026c40fd85788ed73ff4279b825cff0 GIT binary patch literal 1987 zcmd6odrVVT9LG;VMd}pe#uOzmmpGkOqBfum3r-n`Tfq8&ImJqd)U+y$4q94hL543L zH3sIa(7JU3N*}O_6``$*NEa+tx?t0AB7_6j(SH_E-*WatGgx-G?XuENPv4P!*UZs{ruH zii`gI0IhOtD7maE=7XZn?;bsvoZh~Wt$x{HxpeNxr>hI9(H9*;=tT0a$u8|@HP@%7 zol}lrV9g!I0bpJYz|Zr*j&cCbF9QJY1wPsXKy+Tj6fcT3vvSMA@sD#mxKoO()9ND; z8nObbInVGHRiWRe`GWjfb^uNw9PaOO9LMxgPRCZUG?QdeOH9eZ=Ir$#e;o=eUE|&& zUgooDpjJN^3yr63r?PIRPq#*<{?=)1&Pw1mrL)UYY|a)fZF;T0N6MoP)JbTElu5C| z5{8)3CfOqEhVN+S@@yum5l;BU>mSXerto~66ULMpd>@JACjB7&kifc(|a@y3Q8c^6|1 zLR&CZIEf=g@P~bA?OO}ff#UI-N7LIlVX?CzX}N{e#!1!PbFo#tiklvHIa_?{z4A_R zPmDlkXi*4j1oP)D>V)-s5JPUaGDajeu5p&*FX{|R68TZmwok+#@H8mLFaLEK%jd2e?SdNg^r3ZKH622T}j7VeDxy93?4e6yRY8%^9_KL2{`66C;wm*hfi+tQA>3*2K(*Yn^c#BY zkT|XKTo1j=y;QN@*>o9!no@-dO!mtw3O#tIt)58W_i_|ZYbkPVw#eGLdFlva$4Ki^ z6bE6K8`Qr^{5S0XyUDy}2ACO}Qi@qlSQn*87;>GARYs92`Hu(otK_UQGhC~MzA5lH zvyK8bq_oYn8pEI~%1qgC;X6~yn~VW7II}@&4qwY3UQMI3a*7;Eh>nC%g{rT_;&htX z=AF8h`w%?@LDVY{@@q{3J;~21f(CIqnXVo7Q{V8A&>jdL24II-34p0y3~!;L_7*a|J9u1OY(0B z2VvdH!zn>8L~zuKFFpTjd3gS%8moZU2kYz|Bz^W-yz)fIbNV~WX51p;ZlyP8>UcR; z=Qu*VVHY8b+ibta5WO}v2sfSGDB&Gu*(sCM4)3Y}Zvr1tCIjHHy%aHYimZ&dHkE@z zSTyVn&hPW6ojdXVYtEoCGpeOf9jtJ{TNNxOfkdE|zEOqoXeLJ6#659;>VU+_cVx{* zUGczC%ihT&pA`nZ;4;mflt>bxt~94RJ2AqBE3;isS~1WLKP9Cy(TGAXz@W?q*=Ahr z+-LjkY$A8F&QhMLOYL?nO~7w!tJ&`{q2fpHKKf($wXr}jp|V^JJry$s_w+Ud%X|{$ zW~{*G^3m*lCz}?^7-C}>*BN%LM02sJPRg+Mu|?k4m#Y>OG409lA3?-dUb+f|{K3Hc zT&Av*Ir2WEksmn56FpgUw4Y>jDeADgt<1Fu0+vw#QSOuRs>y;+H1?Enmgi{FZ*z8O z#WU2~UdZ~w^D!OMZTD*%O}x9GFyHhgxsE=p&`WatkXMKyA-7b%xiWJA<-V0c+!yiD JqMgUi{0T658(RPX literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/README.md b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/README.md new file mode 100644 index 000000000..bb62a4298 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/README.md @@ -0,0 +1,10 @@ +# FlipperZeroBrainfuck + +Brainfuck interpreter and editor for the F0. +Supports text inputs and outputs. +No protection against infinite loops or syntax errors. +Major limitation is that programs MUST terminate, or it will freeze at "RUNNING" + +![Screenshot-20230117-202147](https://user-images.githubusercontent.com/16545187/213004616-8846e897-506e-4510-8012-fd2fe2bbe8a1.png) + +![Screenshot-20230117-202208](https://user-images.githubusercontent.com/16545187/213004659-d74751d2-76c4-4a7b-a0f2-f58623478b95.png) diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/application.fam b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/application.fam new file mode 100644 index 000000000..4d9c0e741 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/application.fam @@ -0,0 +1,14 @@ +App( + appid="Brainfuck", + name="Brainfuck", + apptype=FlipperAppType.EXTERNAL, + entry_point="brainfuck_app", + requires=[ + "storage", + "gui", + ], + stack_size=8 * 1024, + fap_icon="bfico.png", + fap_category="Misc_Extra", + fap_icon_assets="icons", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/bfico.png b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/bfico.png new file mode 100644 index 0000000000000000000000000000000000000000..b25368fb53e03b73878a9aa17a044c2d8dffea4a GIT binary patch literal 1822 zcma)6eM}o=7(YOmKyZGbBNNT#*c_9!cReT{7dirMfhxy3z6O4=Yws<+(e}=}D=ip7*(DuemTUCTeXIf*>)bd_xg@E9&+&;9yN=+jdK75 zNgO}WHlAeI8at9@wST^cjE;Wo&AI%pY})Zgdviz1zO505+S5*dbUq^E9Q0s*?vo}AfY~MGw zu|Mzolpned^&i|}@9r|UW{rFobKix^-<~<~`{a9D*2O#=KX^8w_sE*&4b4qS;g_z_ z%>ItO>znt#TrbxizB$-4;%pp9ch2lSSGO*{^-4$cf!Wn9^V_xE*PDC9E7G@MaPIMA z4|>R~WYsWTmK4E!G2Km^j|*v-P2Ti%9v(J(z9sA0(ByRSCR5*&W!-zmFpiA<@d0Pp79Ia%{^SR_JA^Z1H*V=KHF3l8&g!tuPanB6%y+!KYUx`BAxQK?$`gWgbjBe_ zcqCU+E|=2M$QM1=orh$50Da& zB0#ljt(w4KIErS9tc@x%g0It(iCNdsPPiQFXx3II!iD;`{ux2YWdl}(wAWi=})ahK5Ey>0jm~fzeL6R4UrIK0! z;6*^<-J%s3Yk*5mz)+0+$5K3LV69PsLrH#lrZ> zXr6^!$r!q1hqEFuDs-4sl$V2=jQUhfMrx{xRKr7+N>L^!Qw0iut4g-}4_vZtbMH0)HCkr@LcL%}2g`%FWsNTP($QYj>* z(IycY6aiEBfq9m*)&3XM*WD=mWx^Pmrt&#S=Ed4YbD(F7!HdgG0i%Oc4uV09RY^^U z2_nzBt$_6jfOd(u$sR@o*;VlVbXc~{#=-P!QM1yws79?J)Ts+tj~zgU;G8rm6p_A= z6TYGVUoWj7z;FM50{qyO1OydzxqwVu`Er+6B@scene_manager, event); +} + +bool brainfuck_back_event_callback(void* context) { + furi_assert(context); + BFApp* brainfuck = context; + return scene_manager_handle_back_event(brainfuck->scene_manager); +} + +BFApp* brainfuck_alloc() { + BFApp* brainfuck = malloc(sizeof(BFApp)); + + brainfuck->dataSize = 0; + brainfuck->view_dispatcher = view_dispatcher_alloc(); + brainfuck->scene_manager = scene_manager_alloc(&brainfuck_scene_handlers, brainfuck); + view_dispatcher_enable_queue(brainfuck->view_dispatcher); + view_dispatcher_set_event_callback_context(brainfuck->view_dispatcher, brainfuck); + view_dispatcher_set_custom_event_callback(brainfuck->view_dispatcher, brainfuck_custom_event_callback); + view_dispatcher_set_navigation_event_callback(brainfuck->view_dispatcher, brainfuck_back_event_callback); + + // Open GUI record + brainfuck->gui = furi_record_open(RECORD_GUI); + view_dispatcher_attach_to_gui(brainfuck->view_dispatcher, brainfuck->gui, ViewDispatcherTypeFullscreen); + + // Open Notification record + brainfuck->notifications = furi_record_open(RECORD_NOTIFICATION); + + // Submenu + brainfuck->submenu = submenu_alloc(); + view_dispatcher_add_view(brainfuck->view_dispatcher, brainfuckViewMenu, submenu_get_view(brainfuck->submenu)); + + // Popup + brainfuck->popup = popup_alloc(); + view_dispatcher_add_view(brainfuck->view_dispatcher, brainfuckViewPopup, popup_get_view(brainfuck->popup)); + + // Text Input + brainfuck->text_input = text_input_alloc(); + view_dispatcher_add_view(brainfuck->view_dispatcher, brainfuckViewTextInput, text_input_get_view(brainfuck->text_input)); + + // Textbox + brainfuck->text_box = text_box_alloc(); + view_dispatcher_add_view(brainfuck->view_dispatcher, brainfuckViewTextBox, text_box_get_view(brainfuck->text_box)); + brainfuck->text_box_store = furi_string_alloc(); + + // Dev environment + brainfuck->BF_dev_env = bf_dev_env_alloc(brainfuck); + view_dispatcher_add_view(brainfuck->view_dispatcher, brainfuckViewDev, bf_dev_env_get_view(brainfuck->BF_dev_env)); + + // File path + brainfuck->BF_file_path = furi_string_alloc(); + + return brainfuck; +} + +void brainfuck_free(BFApp* brainfuck) { + furi_assert(brainfuck); + + // Submenu + view_dispatcher_remove_view(brainfuck->view_dispatcher, brainfuckViewMenu); + submenu_free(brainfuck->submenu); + + // Popup + view_dispatcher_remove_view(brainfuck->view_dispatcher, brainfuckViewPopup); + popup_free(brainfuck->popup); + + // TextInput + view_dispatcher_remove_view(brainfuck->view_dispatcher, brainfuckViewTextInput); + text_input_free(brainfuck->text_input); + + // TextBox + view_dispatcher_remove_view(brainfuck->view_dispatcher, brainfuckViewTextBox); + text_box_free(brainfuck->text_box); + furi_string_free(brainfuck->text_box_store); + + //dev env + view_dispatcher_remove_view(brainfuck->view_dispatcher, brainfuckViewDev); + bf_dev_env_free(brainfuck->BF_dev_env); + + // View Dispatcher + view_dispatcher_free(brainfuck->view_dispatcher); + + // Scene Manager + scene_manager_free(brainfuck->scene_manager); + + // GUI + furi_record_close(RECORD_GUI); + brainfuck->gui = NULL; + + // Notifications + furi_record_close(RECORD_NOTIFICATION); + brainfuck->notifications = NULL; + + free(brainfuck); +} + +void brainfuck_show_loading_popup(void* context, bool show) { + BFApp* brainfuck = 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(brainfuck->view_dispatcher, brainfuckViewLoading); + } else { + // Restore default timer priority + vTaskPrioritySet(timer_task, configTIMER_TASK_PRIORITY); + } +} + +int32_t brainfuck_app(void* p) { + UNUSED(p); + BFApp* brainfuck = brainfuck_alloc(); + if(!brainfuck){ return 0; } + + Storage* storage = furi_record_open(RECORD_STORAGE); + storage_simply_mkdir(storage, "/ext/brainfuck"); + + scene_manager_next_scene(brainfuck->scene_manager, brainfuckSceneStart); + + view_dispatcher_run(brainfuck->view_dispatcher); + + brainfuck_free(brainfuck); + + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/brainfuck.h b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/brainfuck.h new file mode 100644 index 000000000..2e58321a6 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/brainfuck.h @@ -0,0 +1,3 @@ +#pragma once + +typedef struct BFApp BFApp; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/brainfuck_i.h b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/brainfuck_i.h new file mode 100644 index 000000000..3e5a956af --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/brainfuck_i.h @@ -0,0 +1,86 @@ +#pragma once + +typedef struct BFDevEnv BFDevEnv; +typedef struct BFExecEnv BFExecEnv; +typedef unsigned char byte; + +#include "brainfuck.h" +#include "worker.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "scenes/brainfuck_scene.h" + +#include "views/bf_dev_env.h" + +#include +#include +#include + +#include +#include +#include +#include + +#define BF_INST_BUFFER_SIZE 2048 +#define BF_OUTPUT_SIZE 512 +#define BF_STACK_INITIAL_SIZE 128 +#define BF_INPUT_BUFFER_SIZE 64 +#define BF_STACK_STEP_SIZE 32 + +enum brainfuckCustomEvent { + // Reserve first 100 events for button types and indexes, starting from 0 + brainfuckCustomEventReserved = 100, + + brainfuckCustomEventViewExit, + brainfuckCustomEventWorkerExit, + brainfuckCustomEventByteInputDone, + brainfuckCustomEventTextInputDone, +}; + +typedef enum { + EventTypeTick, + EventTypeKey, +} EventType; + +struct BFApp { + ViewDispatcher* view_dispatcher; + Gui* gui; + NotificationApp* notifications; + SceneManager* scene_manager; + Submenu* submenu; + Popup* popup; + TextInput* text_input; + TextBox* text_box; + FuriString* text_box_store; + FuriString* BF_file_path; + BFDevEnv* BF_dev_env; + int dataSize; + char dataBuffer[BF_INST_BUFFER_SIZE]; + char inputBuffer[BF_INPUT_BUFFER_SIZE]; +}; + +typedef enum { + brainfuckViewMenu, + brainfuckViewPopup, + brainfuckViewLoading, + brainfuckViewTextInput, + brainfuckViewTextBox, + brainfuckViewWidget, + brainfuckViewDev, + brainfuckViewExec, +} brainfuckView; diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/ButtonRightSmall_3x5.png b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/ButtonRightSmall_3x5.png new file mode 100644 index 0000000000000000000000000000000000000000..b9d5f87db1ca55141449cfcc3bf054417eaa84e1 GIT binary patch literal 1738 zcmcIl%Wm676lEHu%>zLLWYHwZf?zfc+Tjd`l=wgx!?E02K7gZd!)A>b-AnNYDb z=UD-0O?$90FBm_PwI0iHnuo^kzrHc_RD{NpUPPi|OHR_A(^5V@-5v4MBkl`h`li))oId$h zr-Twrdf1}K>IcLLELU%T22?9W66_DYYiq$%XiVz52r!<_X6DQ`RXN6%@B5fgOeq2c zsup?8<|wc3bqoVp@iHyyRONcZ$YOO|hXyEJO(84Rw0YIq1cu=`E3jpfW=b6}iq3{+ z*&1Ed+b2+^)%#K6YP2XM-j|g+F1g%3k$HWuD^^TYt*VLogtqnH|4=CSx?pi!PM7uw zj^$Klz+C~>TIwr;tx~dDl_RC5T~K>nMV(qE)xUm{=0eS?`;DS@fE=(|h6bc&Ap((k zBdZr!eqejwSR^211&yE&1gqKkz)Gaa;ylnO3Wj-Avz*J}AT&UfnWiG(Hm6?C6^L<1 zqL@1bP64XW zqKrwxT^V~c?$~}TQ}}Y&^h4H0l>o-Xk=)_jK{NqDuJ0r$_IQFAaV$sJiQn_7p}()Y zrKYNklmK^aLl-wVr`&ul_BH)&R_4UgD(ZOFr}nOx%X#N!gVeJ4h)=Wyh? zQXrf4V!h1m}&`|!B-3a0&FC= whJ($~<(FI>9{%<2-NwbcKNmOR7sY+;Hox}g7dMW6Yj&IA_U_=9M~Bb;1{rl65&!@I literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeyBackspaceSelected_24x11.png b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeyBackspaceSelected_24x11.png new file mode 100644 index 0000000000000000000000000000000000000000..c79cfb6c61feb86ebd442c0ed12f4b64f54fad54 GIT binary patch literal 1977 zcmcIlPmkL~6n8~;E4ErxK@Syhu)IBh%Gfjh8(T@MY_jY|s+VY+s>`jD@i?(I@fh2? z$u1HH-~bYW8wkWF0I3oeB;bHV#g$9H09Q_Y0mSlbCuxwD?OurFjOY2y@BRC|c^`Lo zx7XKRUXvtgy|dHagY^bHS1&&Y|6jb){Tr4`+1~c1^ys%&|A5WqLDO$a(s!R-{fn-^ zezkkIw{?1Y3a|HndGa1C&nG)?X8`e1@m!L=`WgVQtVF&2eBZz8F)>zYAo^ULjuX(9 zr23s{LfHY&))cu^$qyPzv#==d`(3#uQZCynMhs(Jc3hR%rfK6hWF6~R z!`oEh~hv@veyfbW(Rni=DeXm z^$5Z`!lXw`Psg5FyG5{vai!`59|D@wiz$mB3Xdib?N&T<+v-f1@!a7vA$z+;YK z5sTIkCmbUZm>9XlaFJ~}w(dBVV}zvi3(mI%J1jC$oUiB`2nHC7YxGqH)7?S=$1 z%OIAc$WQII#7LyR2q3%0vb@u3byE>WBlu9<4030yWfRx7k*-2m0rNtUjwui=8q)#S zl6WxZKCmCWfv9()3`%`m_EptnWp~};H1T|2wL^{2d=bF&FuQ?MXg%2dgMO*&W-Em&~-?Dnv0yx+GSj;J1TEH zrrxbiyV<+(ggw08mR6hQ3mY$POJ6>gR^(5mPac1ye(=qeU(K8EUQ@4Km!#jV)gM0m S{KuQcwCrr{wjXUieE%Qfkx0w{ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeyBackspace_24x11.png b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeyBackspace_24x11.png new file mode 100644 index 0000000000000000000000000000000000000000..00e66428d76e298f0c2c784e1fad66b98d832b8a GIT binary patch literal 1979 zcmcIl&2Jk;6yK<6DpJCQ9tu=wwY`8~yfgdhUD+*;Z5m76V5P1aZW+(c+N;<*+ucp< zM2JIgNJ#XCg!l_Us>B6Fa6sb3iA(+pBqYRvTSa)gYr94YX)ah=&(7O7zxVZf^FHft z-`iM!b6t|8jm}nU2iBYLTwlEc|6jh<{Tr5*bm!it^z7GLzrkj8(C`|P^xYTNpVOB!4C3F%ToBi#Ebo`P!g8W;Uzv%+b1HDT zSWDQ+kOSxi1S-{15o8mZ@WueD^>Tu$mk1=KhZl!&IU@a^VU*ZxNTUIV8yQ-4Ik1|V zUtY^qtEuM~xb}iqb8a@EYjPH(OPMNIut^6?q6G`?oZlW+mG}FW%@NfCjvTXS4^2l^ zN;T|gRa@)x($7)21Y3%hP1V$w`&gb@y1fg;QVOF1c94MiT*`Ng*~TMCUjmcs+q3T< z!qh{ZR-)xFint52(+|8nc(HThcfMEc>?Z{EIf`t9YlHa)U U{I8QgKgs81r@h^Jwz>D@AE;?dx&QzG literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeyInputSelected_30x11.png b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeyInputSelected_30x11.png new file mode 100644 index 0000000000000000000000000000000000000000..4c04a08566958747a8977da87a884723241f8ad2 GIT binary patch literal 1992 zcmcIl&5zqe6!)s#!fv&vUJ62Bxg4lq>=}Q?R?;e)EZs=!CEBLy!UZPwII%YI7~8wa z?x9GnIB-BcajEzZkcuiq#mAwv7sRDPs?;8P=ERW;((-I4X^@ufUWnw3=lRX=ef{3N zFWQ?|R+e9176f6Xwcgx<^-Xxro<0TtcNWDTVOdDGuB-}oAHVSjY)<#;Ze0-W-9Gy_ zU4;Fa_C{yz@bC~`uRVHl1D2(D{lgR>&gIX7aOdmug7C^>*xAmu-3`a%Lz()#%jEGe z25mv8ULMEP+hLj5WxX(}Nq_$QKoUd0CS5mN?8Xh&57!S8cJ*Mh;~ngHwl7`2w6a_s zJAg1`85PIFL6kb-HQ%3@gI!JPXIbnh%4jr_N1Du&otcVdV2sdNKECa)32y z#%dB&k07ifOgcn&RP5-LcL{bdE>&INgHJPhGG*?E!Tw29UDs(vX+|TDwVE{voRY)P zcRWioh(Rle5rz@*b&PDH*~m03Q?)F^(gITW1?QXG+s!kPpD*d_a}O|P*>p7KRhX}L zQJ`yGWL0z@b#;v*tP|pUR5MLOpQ3$`gwR5CFprvhxRIe% z=L4%M`Q-dS`1M&V8}L# z_E0rcp;X1TTCvnFEBzdVbFigo-c(h2xsT0UlOTWg!myQ`nv{0Aa^SG)iK literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeyInput_30x11.png b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeyInput_30x11.png new file mode 100644 index 0000000000000000000000000000000000000000..d23e24aaf79f293d10680c29a582ecb0fbecd6ed GIT binary patch literal 1994 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeySaveSelected_24x11.png b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeySaveSelected_24x11.png new file mode 100644 index 0000000000000000000000000000000000000000..eeb3569d3accc5a5c56829b12c85079172b56729 GIT binary patch literal 1853 zcmcIlPiW*+7#}^zw%YZuf+B)3d$6*;fxiXAXK-X$#&ks`?Z1FR>QX z26aVbT~%`&N5w=X1OWo&yGcQZD9KMx7+O3JvM4Pgkw_&Y^~HA4kU?pcLYz)%lYCqz zD405=sj4ZsOlbo2yrZFUJVocl(hfu!>phe>@9d^rUFW&j&H}!)!;|9lBv{%Lg~)s2 z4%()#|Dlit(}3xA)*qFJ1uF0J7`Su5Y9oEA+srsEMAi|aKWWt3B%(w#g-G)oQNqL^ zf1*@0Ucg(l;0+nNrXfra);gN*63r#X84bG_S5Oapz-U2_2No;}caH=0Jhz?X1x*6p zZZ%{Or9=^P?a(oNj2+}NPLO5lb>xS(hK#yzQ(Fto(z;~|u)ZaN?XnW(`pULU1i&$^ zrW-ON3~kFtm|7MJL)}ES1tUU3N-T@l>$)*vdoGLM%c1>)tfeXjj8tQ`U&jXGx~+pC zJw&zve}0HDBg6^Jz?Y@lahswqGEXq5ZvEhVyV+dJL>TqqMZUhgD7BZGrskL?B8nzU zEO0}S#T1Md#k9-SH0hSMuhLzKa_I5y_(QtDUmB14ku-9rOM~*GXvjh71`cJarlUj3 ze7uCJ^@AP<(j#0_!EzB61Df%LF0|x7U8vqkd`@?cmVP{k{EyPdWes{X>2la%Rk=(? zE%&0TDeAxbb=w#db1i`F%Wmf5GAz>Wv>@jW_p)ho-#0CeC9cGbyZ*s9Cn^o)Rq=_$h#NIZix%+wt GFa8a7)lmol literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeySave_24x11.png b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/KeySave_24x11.png new file mode 100644 index 0000000000000000000000000000000000000000..e7dba987a04dad7dd96001913c55566dbde96c8e GIT binary patch literal 1863 zcmcIlO^6&t6dpxnjjSF75f9pQJZy|LUDdzSZ6$n-*6-2D5s-9_fx~uK( zotfQBVDX?Q(UXLzXF6aX)%U*l z-d9y`w^q+Do_PF3p-@5qOL5h2N9RU z^i-~BIziNECdw*wjUcQeOxncsbnKa>(*%1MPoPck0jC)~9$50g-#!ks+4LGwn$d`f zMy;%ZsA3Rsk2!`#ELuW>2#g3fF>;CFBHMCo-El0(@X1&g%&$qdl~*F4Kd~*B3^?Z1 z^bEmDf}0)Wn??sYC6l9$X;6esLO7#_ZCmDy?ZqU3l|%anS#wn!7%f39-Qp(l9fyJ- z(?=x}n~2%2PcX9#VmYdECvH{tWzv)!s%sn^Z&a(TMEXG=KBQ~smzBm!)h4cOBfSV| zapw6l2`LyY2x(Vnan#Li4>BO#dXPeox2Fr~f_P*4)DM)gJ3Y$sMNw8+?gqit>2PpJ znU9yygm%~yKzf8rCa_fc*^nlp(uJ1%rwg^aiBIX^Xz9mu$p0vPT2|JhQCGkYtEqW1 zTD})enxg%?Uw4c#Ggk#{pLa8zmSLH8=LI=?xR>pc=yYsHAgcQUxz^arx`9fR>e$sw zj@}Uy75!kQXF{tT9e=F+z^*!*3|n>nI6oucWq!(t2og`=40-O!tAE1z^ID@;X)nEd zVK7xqj`wg%Ed2Op{k=a*YZpKHX787$ zzhKuN9(?M5ojmn%xcU1}OP>$^`ZD?cW@lIaTn=x3xBtP#z16o~{qVMZ>hecsD?jQQ ME3387mS5lf8`39Il>h($ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/bfico.png b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/icons/bfico.png new file mode 100644 index 0000000000000000000000000000000000000000..b25368fb53e03b73878a9aa17a044c2d8dffea4a GIT binary patch literal 1822 zcma)6eM}o=7(YOmKyZGbBNNT#*c_9!cReT{7dirMfhxy3z6O4=Yws<+(e}=}D=ip7*(DuemTUCTeXIf*>)bd_xg@E9&+&;9yN=+jdK75 zNgO}WHlAeI8at9@wST^cjE;Wo&AI%pY})Zgdviz1zO505+S5*dbUq^E9Q0s*?vo}AfY~MGw zu|Mzolpned^&i|}@9r|UW{rFobKix^-<~<~`{a9D*2O#=KX^8w_sE*&4b4qS;g_z_ z%>ItO>znt#TrbxizB$-4;%pp9ch2lSSGO*{^-4$cf!Wn9^V_xE*PDC9E7G@MaPIMA z4|>R~WYsWTmK4E!G2Km^j|*v-P2Ti%9v(J(z9sA0(ByRSCR5*&W!-zmFpiA<@d0Pp79Ia%{^SR_JA^Z1H*V=KHF3l8&g!tuPanB6%y+!KYUx`BAxQK?$`gWgbjBe_ zcqCU+E|=2M$QM1=orh$50Da& zB0#ljt(w4KIErS9tc@x%g0It(iCNdsPPiQFXx3II!iD;`{ux2YWdl}(wAWi=})ahK5Ey>0jm~fzeL6R4UrIK0! z;6*^<-J%s3Yk*5mz)+0+$5K3LV69PsLrH#lrZ> zXr6^!$r!q1hqEFuDs-4sl$V2=jQUhfMrx{xRKr7+N>L^!Qw0iut4g-}4_vZtbMH0)HCkr@LcL%}2g`%FWsNTP($QYj>* z(IycY6aiEBfq9m*)&3XM*WD=mWx^Pmrt&#S=Ed4YbD(F7!HdgG0i%Oc4uV09RY^^U z2_nzBt$_6jfOd(u$sR@o*;VlVbXc~{#=-P!QM1yws79?J)Ts+tj~zgU;G8rm6p_A= z6TYGVUoWj7z;FM50{qyO1OydzxqwVu`Er+6B@ + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) brainfuckScene##id, +typedef enum { +#include "brainfuck_scene_config.h" + brainfuckSceneNum, +} brainfuckScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers brainfuck_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "brainfuck_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 "brainfuck_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 "brainfuck_scene_config.h" +#undef ADD_SCENE diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_config.h b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_config.h new file mode 100644 index 000000000..0efc41641 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_config.h @@ -0,0 +1,6 @@ +ADD_SCENE(brainfuck, start, Start) +ADD_SCENE(brainfuck, file_select, FileSelect) +ADD_SCENE(brainfuck, file_create, FileCreate) +ADD_SCENE(brainfuck, dev_env, DevEnv) +ADD_SCENE(brainfuck, exec_env, ExecEnv) +ADD_SCENE(brainfuck, set_input, SetInput) \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_dev.c b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_dev.c new file mode 100644 index 000000000..475e9e573 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_dev.c @@ -0,0 +1,16 @@ +#include "../brainfuck_i.h" + +void brainfuck_scene_dev_env_on_enter(void* context) { + BFApp* app = context; + view_dispatcher_switch_to_view(app->view_dispatcher, brainfuckViewDev); +} + +bool brainfuck_scene_dev_env_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + return false; +} + +void brainfuck_scene_dev_env_on_exit(void* context) { + UNUSED(context); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_exec.c b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_exec.c new file mode 100644 index 000000000..d344f7271 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_exec.c @@ -0,0 +1,16 @@ +#include "../brainfuck_i.h" + +void brainfuck_scene_exec_env_on_enter(void* context) { + BFApp* app = context; + view_dispatcher_switch_to_view(app->view_dispatcher, brainfuckViewTextBox); +} + +bool brainfuck_scene_exec_env_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + return false; +} + +void brainfuck_scene_exec_env_on_exit(void* context) { + UNUSED(context); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_file_create.c b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_file_create.c new file mode 100644 index 000000000..525fb049e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_file_create.c @@ -0,0 +1,54 @@ +#include "../brainfuck_i.h" + +void file_name_text_input_callback(void* context) { + BFApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, brainfuckCustomEventTextInputDone); +} + +char tmpName[64] = {}; +byte empty[1] = {0x00}; +void brainfuck_scene_file_create_on_enter(void* context) { + BFApp* app = context; + TextInput* text_input = app->text_input; + + text_input_set_header_text(text_input, "New script name"); + text_input_set_result_callback( + text_input, + file_name_text_input_callback, + app, + tmpName, + 64, + true); + + view_dispatcher_switch_to_view(app->view_dispatcher, brainfuckViewTextInput); +} + +bool brainfuck_scene_file_create_on_event(void* context, SceneManagerEvent event) { + BFApp* app = context; + UNUSED(app); + + bool consumed = false; + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == brainfuckCustomEventTextInputDone) { + furi_string_cat_printf(app->BF_file_path, "/ext/brainfuck/%s.b", tmpName); + + //remove old file + Storage* storage = furi_record_open(RECORD_STORAGE); + storage_simply_remove(storage, furi_string_get_cstr(app->BF_file_path)); + + //save new file + Stream* stream = buffered_file_stream_alloc(storage); + buffered_file_stream_open(stream, furi_string_get_cstr(app->BF_file_path), FSAM_WRITE, FSOM_CREATE_ALWAYS); + stream_write(stream, (const uint8_t*)empty, 1); + buffered_file_stream_close(stream); + + //scene_manager_next_scene(app->scene_manager, brainfuckSceneFileSelect); + scene_manager_next_scene(app->scene_manager, brainfuckSceneDevEnv); + } + } + return consumed; +} + +void brainfuck_scene_file_create_on_exit(void* context) { + UNUSED(context); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_file_select.c b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_file_select.c new file mode 100644 index 000000000..5d262d4a5 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_file_select.c @@ -0,0 +1,35 @@ +#include "../brainfuck_i.h" + +void brainfuck_scene_file_select_on_enter(void* context) { + BFApp* app = context; + + DialogsApp* dialogs = furi_record_open("dialogs"); + FuriString* path; + path = furi_string_alloc(); + furi_string_set(path, "/ext/brainfuck"); + + DialogsFileBrowserOptions browser_options; + dialog_file_browser_set_basic_options(&browser_options, ".b", &I_bfico); + browser_options.base_path = "/ext/brainfuck"; + browser_options.hide_ext = false; + + bool selected = dialog_file_browser_show(dialogs, path, path, &browser_options); + + if(selected){ + furi_string_set(app->BF_file_path, path); + scene_manager_next_scene(app->scene_manager, brainfuckSceneDevEnv); + } + else{ + scene_manager_search_and_switch_to_previous_scene(app->scene_manager, brainfuckSceneStart); + } +} + +bool brainfuck_scene_file_select_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + return false; +} + +void brainfuck_scene_file_select_on_exit(void* context) { + UNUSED(context); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_set_input.c b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_set_input.c new file mode 100644 index 000000000..b6c5f5b9e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_set_input.c @@ -0,0 +1,39 @@ +#include "../brainfuck_i.h" + +void set_input_text_input_callback(void* context) { + BFApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, brainfuckCustomEventTextInputDone); +} + +void brainfuck_scene_set_input_on_enter(void* context) { + BFApp* app = context; + TextInput* text_input = app->text_input; + + text_input_set_header_text(text_input, "Edit input buffer"); + text_input_set_result_callback( + text_input, + set_input_text_input_callback, + app, + app->inputBuffer, + 64, + true); + + view_dispatcher_switch_to_view(app->view_dispatcher, brainfuckViewTextInput); +} + +bool brainfuck_scene_set_input_on_event(void* context, SceneManagerEvent event) { + BFApp* app = context; + + bool consumed = false; + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == brainfuckCustomEventTextInputDone) { + scene_manager_search_and_switch_to_previous_scene(app->scene_manager, brainfuckSceneDevEnv); + } + } + return consumed; +} + +void brainfuck_scene_set_input_on_exit(void* context) { + BFApp* app = context; + scene_manager_search_and_switch_to_previous_scene(app->scene_manager, brainfuckSceneDevEnv); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_start.c b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_start.c new file mode 100644 index 000000000..876e019a5 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/scenes/brainfuck_scene_start.c @@ -0,0 +1,49 @@ +#include "../brainfuck_i.h" +enum SubmenuIndex { + SubmenuIndexNew, + SubmenuIndexOpen, + SubmenuIndexAbout, +}; + +void brainfuck_scene_start_submenu_callback(void* context, uint32_t index) { + BFApp* brainfuck = context; + view_dispatcher_send_custom_event(brainfuck->view_dispatcher, index); +} +void brainfuck_scene_start_on_enter(void* context) { + BFApp* brainfuck = context; + + Submenu* submenu = brainfuck->submenu; + submenu_add_item(submenu, "New", SubmenuIndexNew, brainfuck_scene_start_submenu_callback, brainfuck); + submenu_add_item(submenu, "Open", SubmenuIndexOpen, brainfuck_scene_start_submenu_callback, brainfuck); + submenu_add_item(submenu, "About", SubmenuIndexAbout, brainfuck_scene_start_submenu_callback, brainfuck); + + submenu_set_selected_item(submenu, scene_manager_get_scene_state(brainfuck->scene_manager, brainfuckSceneStart)); + view_dispatcher_switch_to_view(brainfuck->view_dispatcher, brainfuckViewMenu); +} + +bool brainfuck_scene_start_on_event(void* context, SceneManagerEvent event) { + BFApp* brainfuck = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexNew) { + scene_manager_next_scene(brainfuck->scene_manager, brainfuckSceneFileCreate); + consumed = true; + } else if(event.event == SubmenuIndexOpen) { + scene_manager_next_scene(brainfuck->scene_manager, brainfuckSceneFileSelect); + consumed = true; + } else if(event.event == SubmenuIndexAbout) { + text_box_set_text(brainfuck->text_box, "FlipperBrainfuck\n\nAn F0 brainfuck intepretor\nBy github.com/Nymda"); + scene_manager_next_scene(brainfuck->scene_manager, brainfuckSceneExecEnv); + consumed = true; + } + scene_manager_set_scene_state(brainfuck->scene_manager, brainfuckSceneStart, event.event); + } + + return consumed; +} + +void brainfuck_scene_start_on_exit(void* context) { + BFApp* brainfuck = context; + submenu_reset(brainfuck->submenu); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/views/bf_dev_env.c b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/views/bf_dev_env.c new file mode 100644 index 000000000..0bc852b72 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/views/bf_dev_env.c @@ -0,0 +1,396 @@ +#include "bf_dev_env.h" +#include + +typedef struct BFDevEnv { + View* view; + DevEnvOkCallback callback; + void* context; + BFApp* appDev; +} BFDevEnv; + +typedef struct { + uint32_t row; + uint32_t col; +} BFDevEnvModel; + +typedef struct{ + int up; + int down; + int left; + int right; +}bMapping; + +static bool bf_dev_process_up(BFDevEnv* devEnv); +static bool bf_dev_process_down(BFDevEnv* devEnv); +static bool bf_dev_process_left(BFDevEnv* devEnv); +static bool bf_dev_process_right(BFDevEnv* devEnv); +static bool bf_dev_process_ok(BFDevEnv* devEnv, InputEvent* event); + +BFApp* appDev; + +char bfChars[9] = {'<', '>', '[', ']', '+', '-', '.', ',', 0x00}; + +int selectedButton = 0; +int saveNotifyCountdown = 0; +int execCountdown = 0; + +char dspLine0[25] = {}; +char dspLine1[25] = {}; +char dspLine2[25] = {}; + +static bMapping buttonMappings[12] = { + { 8, 8, 7, 1}, //0 + { 8, 8, 0, 2}, //1 + { 9, 9, 1, 3}, //2 + { 9, 9, 2, 4}, //3 + {10, 10, 3, 5}, //4 + {10, 10, 4, 6}, //5 + {11, 11, 5, 7}, //6 + {11, 11, 6, 0}, //7 + + { 0, 0, 11, 9}, //8 + { 3, 3, 8, 10}, //9 + { 5, 5, 9, 11}, //10 + { 6, 6, 10, 8} //11 +}; + +#define BT_X 14 +#define BT_Y 14 +static void bf_dev_draw_button(Canvas* canvas, int x, int y, bool selected, const char* lbl){ + UNUSED(lbl); + + if(selected){ + canvas_draw_rbox(canvas, x, y, BT_X, BT_Y, 3); + canvas_invert_color(canvas); + canvas_set_font(canvas, FontBatteryPercent); + canvas_draw_str_aligned(canvas, x + (BT_X/2), y + (BT_Y/2) - 1, AlignCenter, AlignCenter, lbl); + canvas_invert_color(canvas); + } + else{ + canvas_draw_rbox(canvas, x, y, BT_X, BT_Y, 3); + canvas_invert_color(canvas); + canvas_draw_rbox(canvas, x+2, y-1, BT_X - 2, BT_Y - 1, 3); + canvas_invert_color(canvas); + canvas_draw_rframe(canvas, x, y, BT_X, BT_Y, 3); + canvas_set_font(canvas, FontBatteryPercent); + canvas_draw_str_aligned(canvas, x + (BT_X/2), y + (BT_Y/2) - 1, AlignCenter, AlignCenter, lbl); + } +} + +static void bf_dev_draw_callback(Canvas* canvas, void* _model) { + UNUSED(_model); + + if(execCountdown > 0){ + execCountdown--; + canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignCenter, "RUNNING..."); + if(execCountdown == 0){ + initWorker(appDev); + beginWorker(); + text_box_set_text(appDev->text_box, workerGetOutput()); + scene_manager_next_scene(appDev->scene_manager, brainfuckSceneExecEnv); + } + return; + } + + if(saveNotifyCountdown > 0){ + canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignCenter, "SAVED"); + saveNotifyCountdown--; + return; + } + + bf_dev_draw_button(canvas, 1, 36, (selectedButton == 0), "+"); //T 0 + bf_dev_draw_button(canvas, 17, 36, (selectedButton == 1), "-"); //T 1 + bf_dev_draw_button(canvas, 33, 36, (selectedButton == 2), "<"); //T 2 + bf_dev_draw_button(canvas, 49, 36, (selectedButton == 3), ">"); //T 3 + bf_dev_draw_button(canvas, 65, 36, (selectedButton == 4), "["); //B 0 + bf_dev_draw_button(canvas, 81, 36, (selectedButton == 5), "]"); //B 1 + bf_dev_draw_button(canvas, 97, 36, (selectedButton == 6), "."); //B 2 + bf_dev_draw_button(canvas, 113, 36, (selectedButton == 7), ","); //B 3 + + //backspace, input, run, save + canvas_draw_icon(canvas, 1, 52, (selectedButton == 8) ? &I_KeyBackspaceSelected_24x11 : &I_KeyBackspace_24x11); + canvas_draw_icon(canvas, 45, 52, (selectedButton == 9) ? &I_KeyInputSelected_30x11 : &I_KeyInput_30x11); + canvas_draw_icon(canvas, 77, 52, (selectedButton == 10) ? &I_KeyRunSelected_24x11 : &I_KeyRun_24x11); + canvas_draw_icon(canvas, 103, 52, (selectedButton == 11) ? &I_KeySaveSelected_24x11 : &I_KeySave_24x11); + + if(saveNotifyCountdown > 0){ + canvas_draw_icon(canvas, 98, 54, &I_ButtonRightSmall_3x5); + saveNotifyCountdown--; + } + + //textbox + //grossly overcomplicated. not fixing it. + canvas_draw_rframe(canvas, 1, 1, 125, 33, 2); + canvas_set_font(canvas, FontBatteryPercent); + + int dbOffset = 0; + if(appDev->dataSize > 72){ + dbOffset = (appDev->dataSize - 72); + } + + memset(dspLine0, 0x00, 25); + memset(dspLine1, 0x00, 25); + memset(dspLine2, 0x00, 25); + + int tpM = 0; + int tp0 = 0; + int tp1 = 0; + int tp2 = 0; + + for(int p = dbOffset; p < appDev->dataSize; p++){ + if(tpM < 24 * 1){ + dspLine0[tp0] = appDev->dataBuffer[p]; + tp0++; + } + else if(tpM < 24 * 2){ + dspLine1[tp1] = appDev->dataBuffer[p]; + tp1++; + } + else if(tpM < 24 * 3){ + dspLine2[tp2] = appDev->dataBuffer[p]; + tp2++; + } + tpM++; + } + + canvas_draw_str_aligned(canvas, 3, 8, AlignLeft, AlignCenter, dspLine0); + canvas_draw_str_aligned(canvas, 3, 17, AlignLeft, AlignCenter, dspLine1); + canvas_draw_str_aligned(canvas, 3, 26, AlignLeft, AlignCenter, dspLine2); +} + + +static bool bf_dev_input_callback(InputEvent* event, void* context) { + furi_assert(context); + BFDevEnv* devEnv = context; + bool consumed = false; + + if(event->type == InputTypeShort) { + if(event->key == InputKeyRight) { + consumed = bf_dev_process_right(devEnv); + } else if(event->key == InputKeyLeft) { + consumed = bf_dev_process_left(devEnv); + } else if(event->key == InputKeyUp) { + consumed = bf_dev_process_up(devEnv); + } else if(event->key == InputKeyDown) { + consumed = bf_dev_process_down(devEnv); + } + } else if(event->key == InputKeyOk) { + consumed = bf_dev_process_ok(devEnv, event); + } + + return consumed; +} + +static bool bf_dev_process_up(BFDevEnv* devEnv) { + UNUSED(devEnv); + selectedButton = buttonMappings[selectedButton].up; + return true; +} + +static bool bf_dev_process_down(BFDevEnv* devEnv) { + UNUSED(devEnv); + selectedButton = buttonMappings[selectedButton].down; + return true; +} + +static bool bf_dev_process_left(BFDevEnv* devEnv) { + UNUSED(devEnv); + selectedButton = buttonMappings[selectedButton].left; + return true; +} + +static bool bf_dev_process_right(BFDevEnv* devEnv) { + UNUSED(devEnv); + selectedButton = buttonMappings[selectedButton].right; + return true; +} + +static bool bf_dev_process_ok(BFDevEnv* devEnv, InputEvent* event) { + UNUSED(devEnv); + UNUSED(event); + + if(event->type != InputTypePress){ return false; } + + switch(selectedButton){ + case 0: + { + if(appDev->dataSize < BF_INST_BUFFER_SIZE){ + appDev->dataBuffer[appDev->dataSize] = (uint32_t)'+'; + appDev->dataSize++; } + break; + } + + case 1: + { + if(appDev->dataSize < BF_INST_BUFFER_SIZE){ + appDev->dataBuffer[appDev->dataSize] = (uint32_t)'-'; + appDev->dataSize++; } + break; + } + + case 2: + { + if(appDev->dataSize < BF_INST_BUFFER_SIZE){ + appDev->dataBuffer[appDev->dataSize] = (uint32_t)'<'; + appDev->dataSize++; } + break; + } + + case 3: + { + if(appDev->dataSize < BF_INST_BUFFER_SIZE){ + appDev->dataBuffer[appDev->dataSize] = (uint32_t)'>'; + appDev->dataSize++; } + break; + } + + case 4: + { + if(appDev->dataSize < BF_INST_BUFFER_SIZE){ + appDev->dataBuffer[appDev->dataSize] = (uint32_t)'['; + appDev->dataSize++; } + break; + } + + case 5: + { + if(appDev->dataSize < BF_INST_BUFFER_SIZE){ + appDev->dataBuffer[appDev->dataSize] = (uint32_t)']'; + appDev->dataSize++; } + break; + } + + case 6: + { + if(appDev->dataSize < BF_INST_BUFFER_SIZE){ + appDev->dataBuffer[appDev->dataSize] = (uint32_t)'.'; + appDev->dataSize++; } + break; + } + + case 7: + { + if(appDev->dataSize < BF_INST_BUFFER_SIZE){ + appDev->dataBuffer[appDev->dataSize] = (uint32_t)','; + appDev->dataSize++; } + break; + } + + case 8: + { + if(appDev->dataSize > 0){ + appDev->dataSize--; + appDev->dataBuffer[appDev->dataSize] = (uint32_t)0x00;} + break; + } + + case 9: + { + //todo: input + scene_manager_next_scene(appDev->scene_manager, brainfuckSceneSetInput); + break; + } + + case 10: + { + execCountdown = 3; + break; + } + + case 11: + { + //remove old file + Storage* storage = furi_record_open(RECORD_STORAGE); + storage_simply_remove(storage, furi_string_get_cstr(appDev->BF_file_path)); + + //save new file + Stream* stream = buffered_file_stream_alloc(storage); + buffered_file_stream_open(stream, furi_string_get_cstr(appDev->BF_file_path), FSAM_WRITE, FSOM_CREATE_ALWAYS); + stream_write(stream, (const uint8_t*)appDev->dataBuffer, appDev->dataSize); + buffered_file_stream_close(stream); + + //notify + saveNotifyCountdown = 3; + break; + } + } + + bool consumed = false; + return consumed; +} + +static void bf_dev_enter_callback(void* context) { + furi_assert(context); + BFDevEnv* devEnv = context; + + with_view_model( + devEnv->view, + BFDevEnvModel* model, + { + model->col = 0; + model->row = 0; + }, + true); + + appDev = devEnv->appDev; + selectedButton = 0; + + //clear the bf instruction buffer + memset(appDev->dataBuffer, 0x00, BF_INST_BUFFER_SIZE * sizeof(char)); + + //open the file + Storage* storage = furi_record_open(RECORD_STORAGE); + Stream* stream = buffered_file_stream_alloc(storage); + buffered_file_stream_open(stream, furi_string_get_cstr(appDev->BF_file_path), FSAM_READ, FSOM_OPEN_EXISTING); + + //read into the buffer + appDev->dataSize = stream_size(stream); + stream_read(stream, (uint8_t*)appDev->dataBuffer, appDev->dataSize); + buffered_file_stream_close(stream); + + //replaces any invalid characters with an underscore. strips out newlines, comments, etc + for(int i = 0; i < appDev->dataSize; i++){ + if(!strchr(bfChars, appDev->dataBuffer[i])){ + appDev->dataBuffer[i] = '_'; + } + } + + //find the end of the file to begin editing + int tptr = 0; + while(appDev->dataBuffer[tptr] != 0x00){ tptr++; } + appDev->dataSize = tptr; +} + +BFDevEnv* bf_dev_env_alloc(BFApp* appDev) { + BFDevEnv* devEnv = malloc(sizeof(BFDevEnv)); + + devEnv->view = view_alloc(); + devEnv->appDev = appDev; + view_allocate_model(devEnv->view, ViewModelTypeLocking, sizeof(BFDevEnvModel)); + + with_view_model( + devEnv->view, + BFDevEnvModel* model, + { + model->col = 0; + model->row = 0; + }, + true); + + view_set_context(devEnv->view, devEnv); + view_set_draw_callback(devEnv->view, bf_dev_draw_callback); + view_set_input_callback(devEnv->view, bf_dev_input_callback); + view_set_enter_callback(devEnv->view, bf_dev_enter_callback); + return devEnv; +} + +void bf_dev_env_free(BFDevEnv* devEnv) { + furi_assert(devEnv); + view_free(devEnv->view); + free(devEnv); +} + +View* bf_dev_env_get_view(BFDevEnv* devEnv) { + furi_assert(devEnv); + return devEnv->view; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/views/bf_dev_env.h b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/views/bf_dev_env.h new file mode 100644 index 000000000..ea1f6e41f --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/views/bf_dev_env.h @@ -0,0 +1,18 @@ +#pragma once +#include "../brainfuck_i.h" +#include + +typedef void (*DevEnvOkCallback)(InputType type, void* context); + +BFDevEnv* bf_dev_env_alloc(BFApp* application); + +void bf_dev_set_file_path(FuriString* path); + +void bf_dev_env_free(BFDevEnv* devEnv); + +View* bf_dev_env_get_view(BFDevEnv* devEnv); + +void bf_dev_env_set_ok( + BFDevEnv* devEnv, + DevEnvOkCallback callback, + void* context); diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/worker.c b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/worker.c new file mode 100644 index 000000000..db05c3c41 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/worker.c @@ -0,0 +1,207 @@ +#include "worker.h" + +int status = 0; //0: idle, 1: running, 2: failure + +char* inst = 0; +int instCount = 0; +int instPtr = 0; +int runOpCount = 0; + +char* wOutput = 0; +int wOutputPtr = 0; + +char* wInput = 0; +int wInputPtr = 0; + +uint8_t* bfStack = 0; +int stackPtr = 0; +int stackSize = BF_STACK_INITIAL_SIZE; +int stackSizeReal = 0; + +bool validateInstPtr(){ + if(instPtr > instCount || instPtr < 0){ + return false; + } + return true; +} + +bool validateStackPtr(){ + if(stackPtr > stackSize || stackPtr < 0){ + return false; + } + return true; +} + +char* workerGetOutput(){ + return wOutput; +} + +int getStackSize(){ + return stackSizeReal; +} + +int getOpCount(){ + return runOpCount; +} + +int getStatus(){ + return status; +} + +void initWorker(BFApp* app){ + //rebuild output + if(wOutput){ free(wOutput); } + wOutput = (char*)malloc(BF_OUTPUT_SIZE); + wOutputPtr = 0; + + //rebuild stack + if(bfStack){ free(bfStack); } + bfStack = (uint8_t*)malloc(BF_STACK_INITIAL_SIZE); + memset(bfStack, 0x00, BF_STACK_INITIAL_SIZE); + stackSize = BF_STACK_INITIAL_SIZE; + stackSizeReal = 0; + stackPtr = 0; + + //set instructions + inst = app->dataBuffer; + instCount = app->dataSize; + instPtr = 0; + runOpCount = 0; + + //set input + wInput = app->inputBuffer; + wInputPtr = 0; + + //set status + status = 0; +} + +void rShift(){ + runOpCount++; + stackPtr++; + if(!validateStackPtr()){ status = 2; return; } + + while(stackPtr > stackSize){ + stackSize += BF_STACK_STEP_SIZE; + void* tmp = realloc(bfStack, stackSize); + + if(!tmp){ + status = 2; + return; + } + + memset((tmp + stackSize) - BF_STACK_STEP_SIZE, 0x00, BF_STACK_STEP_SIZE); + bfStack = (uint8_t*)tmp; + }; + if(stackPtr > stackSizeReal){ + stackSizeReal = stackPtr; + } +} + +void lShift(){ + runOpCount++; + stackPtr--; + if(!validateStackPtr()){ status = 2; return; } +} + +void inc(){ + runOpCount++; + if(!validateStackPtr()){ status = 2; return; } + bfStack[stackPtr]++; +} + +void dec(){ + runOpCount++; + if(!validateStackPtr()){ status = 2; return; } + bfStack[stackPtr]--; +} + +void print(){ + runOpCount++; + wOutput[wOutputPtr] = bfStack[stackPtr]; + wOutputPtr++; + if(wOutputPtr > (BF_OUTPUT_SIZE - 1)){ wOutputPtr = 0;} +} + +void input(){ + runOpCount++; + + bfStack[stackPtr] = (uint8_t)wInput[wInputPtr]; + if(wInput[wInputPtr] == 0x00 || wInputPtr >= 64){ + wInputPtr = 0; + } + else{ + wInputPtr++; + } +} + +void loop() { + runOpCount++; + if (bfStack[stackPtr] == 0) { + int loopCount = 1; + while (loopCount > 0) { + instPtr++; + if(!validateInstPtr()){ status = 2; return; } + if (inst[instPtr] == '[') { loopCount++; } + else if (inst[instPtr] == ']') { loopCount--; } + } + } +} + +void endLoop() { + runOpCount++; + if (bfStack[stackPtr] != 0) { + int loopCount = 1; + while (loopCount > 0) { + instPtr--; + if(!validateInstPtr()){ status = 2; return; } + if (inst[instPtr] == ']') { loopCount++; } + else if (inst[instPtr] == '[') { loopCount--; } + } + } +} + +void beginWorker(){ + status = 1; + while (inst[instPtr] != 0x00) { + if(status == 2){ return; } + switch (inst[instPtr]) { + case '>': + rShift(); + break; + case '<': + lShift(); + break; + + case '+': + inc(); + break; + + case '-': + dec(); + break; + + case '.': + print(); + break; + + case ',': + input(); + break; + + case '[': + loop(); + break; + + case ']': + endLoop(); + break; + + default: + break; + } + instPtr++; + if(!validateInstPtr()){ status = 2; return; } + } + status = 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/brainfuck/worker.h b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/worker.h new file mode 100644 index 000000000..e0b79d5c6 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/brainfuck/worker.h @@ -0,0 +1,8 @@ +#include "brainfuck_i.h" + +void initWorker(BFApp* application); +char* workerGetOutput(); +int getStackSize(); +int getOpCount(); +int getStatus(); +void beginWorker(); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/README.md b/Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/README.md new file mode 100644 index 000000000..60b8258f3 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/README.md @@ -0,0 +1 @@ +Flipper Zero BT Serial Example App diff --git a/Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/application.fam b/Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/application.fam new file mode 100644 index 000000000..bd3b10046 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/application.fam @@ -0,0 +1,13 @@ +App( + appid="fbs", + name="BT Serial App", + apptype=FlipperAppType.EXTERNAL, + entry_point="fbs_app", + stack_size=1 * 1024, + requires=[ + "bt", + "gui", + ], + fap_category="Misc_Extra", + fap_icon="uart_10px.png", +) \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/fbs.c b/Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/fbs.c new file mode 100644 index 000000000..e548351d7 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/fbs.c @@ -0,0 +1,108 @@ +#include "fbs.h" + +const uint16_t BT_SERIAL_BUFFER_SIZE = 128; + +void draw_callback(Canvas* canvas, void* ctx) { + FBS* app = ctx; + furi_check(furi_mutex_acquire(app->app_mutex, FuriWaitForever) == FuriStatusOk); + + canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignCenter, (char*)app->display_text); + + furi_mutex_release(app->app_mutex); +} + +void input_callback(InputEvent* input, void* ctx) { + FBS* app = ctx; + furi_message_queue_put(app->event_queue, input, FuriWaitForever); +} + +FBS* fbs_alloc() { + FBS* app = malloc(sizeof(FBS)); + app->app_mutex = furi_mutex_alloc(FuriMutexTypeNormal); + app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + app->gui = furi_record_open(RECORD_GUI); + app->view_port = view_port_alloc(); + view_port_draw_callback_set(app->view_port, draw_callback, app); + view_port_input_callback_set(app->view_port, input_callback, app); + gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen); + + app->bt_connected = false; + app->bt = furi_record_open(RECORD_BT); + return app; +} + +void fbs_free(FBS* app) { + view_port_enabled_set(app->view_port, false); + gui_remove_view_port(app->gui, app->view_port); + furi_record_close(RECORD_GUI); + app->gui = NULL; + view_port_free(app->view_port); + free(app->display_text); + + furi_mutex_free(app->app_mutex); + furi_message_queue_free(app->event_queue); + + furi_record_close(RECORD_BT); + app->bt = NULL; + + free(app); +} + +static uint16_t bt_serial_event_callback(SerialServiceEvent event, void* context) { + furi_assert(context); + Bt* bt = context; + UNUSED(bt); + uint16_t ret = 0; + + if(event.event == SerialServiceEventTypeDataReceived) { + FURI_LOG_D(TAG, "SerialServiceEventTypeDataReceived"); + FURI_LOG_D(TAG, "Size: %u", event.data.size); + FURI_LOG_D(TAG, "Data: "); + for (size_t i = 0; i < event.data.size; i++) + { + printf("%X ", event.data.buffer[i]); + } + printf("\r\n"); + } else if(event.event == SerialServiceEventTypeDataSent) { + FURI_LOG_D(TAG, "SerialServiceEventTypeDataSent"); + FURI_LOG_D(TAG, "Size: %u", event.data.size); + FURI_LOG_D(TAG, "Data: "); + for (size_t i = 0; i < event.data.size; i++) + { + printf("%X ", event.data.buffer[i]); + } + printf("\r\n"); + } + return ret; +} + +int32_t fbs_app(void* p) { + UNUSED(p); + FBS* app = fbs_alloc(); + + if (furi_hal_bt_is_active()) { + FURI_LOG_D(TAG, "BT is working, hijacking the serial connection..."); + furi_hal_bt_serial_set_event_callback(BT_SERIAL_BUFFER_SIZE, bt_serial_event_callback, app); + furi_hal_bt_start_advertising(); + } else { + FURI_LOG_D(TAG, "Please, enable the Bluetooth and restart the app"); + } + + InputEvent event; + for(bool processing = true; processing;) { + int status = furi_message_queue_get(app->event_queue, &event, 100); + furi_check(furi_mutex_acquire(app->app_mutex, FuriWaitForever) == FuriStatusOk); + if(status == FuriStatusOk && event.type == InputTypePress && event.key == InputKeyBack) { + processing = false; + } + furi_mutex_release(app->app_mutex); + view_port_update(app->view_port); + } + + furi_hal_bt_serial_set_event_callback(0, NULL, NULL); + + fbs_free(app); + FURI_LOG_D(TAG, "Released everything"); + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/fbs.h b/Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/fbs.h new file mode 100644 index 000000000..325936be2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/fbs.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#define TAG "FlipperBTSerial" + +typedef struct { + Bt* bt; + bool bt_connected; + + char* display_text; + + ViewPort* view_port; + Gui* gui; + + FuriMutex* app_mutex; + FuriMessageQueue* event_queue; +} FBS; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/uart_10px.png b/Applications/Official/DEV_FW/source/xMasterX/bt_serial_example/uart_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..8420f569279aa5ca170da19d080fd27f61b4339c GIT binary patch literal 1883 zcmcIlO^72!6z&~VbYxWUvIs(N?;25X-v&lFK*fSv$c1OHesj5zzNxFKv zJCn?y7xCgj5JVAKyom@RBB%$!MGu}mdJw#O5l?~_eVxA@b#@#U3?yBt{_1<*d+)2N zH(J|UYpYMJDvGk!Y}DKEEXS)4uE6g~Yws6$Jd`$G%oXL~$II^p<^5Y173G0%;?7>N z7rqcMIn*haU7=5gDWDbQ+WI7=Y+n>=SM=hfs{Q))ZB31NRlDhgI81AzA2*IOv3tDT zVaNN-=i2&n>a|G#1Vd3!but_zc`&JJQ{Di^<+P!xQ%JF2)i%n2>R#AVYcdn6t7F74 zCThjkP1m+P?^%^#f(=|TOpFK#up2m*I{#=8E#pzpu0KDI1^=pAzbMkcFvjDtKDKn3 z^$gSZeFGDN5CjO6A0-8ypd`P%V5p0nWpP@>GEqxL+LfcCs)5p33d3|so8*gS+NbG@e$=bfWe7;TZuQO3mPp-76$i(s5B*QTRvFwK-R zLkz?aU^xggm!Z&a9i0an zhCwsQ3z{&|tXDMxWcW%fMZ#qz^S;DR2+ePhg0PHwvD=;VFxyI|ItfO;OcY z=?1~I`E-0rna`KdjCR}?KzfEtX0TjF#h7MdqX#YdPZt_@6Q9$=v!&aNVrpY(gJ2Gd zh)oggMlOnQ{^`kgKYR1w(jV=$#&;iGIr!?vQ?dEQ>mTlH{W$vgv8!)?a%u2`GV#_g{QmvU em*#svf3EDVT)F?1TY9Cu{+gTH^-r(A{Muh4WJ_-V literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/caesarcipher/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/caesarcipher/LICENSE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/caesarcipher/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Applications/Official/DEV_FW/source/xMasterX/caesarcipher/README.md b/Applications/Official/DEV_FW/source/xMasterX/caesarcipher/README.md new file mode 100644 index 000000000..0d434f9de --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/caesarcipher/README.md @@ -0,0 +1,17 @@ +# Caesar Cipher + +A [caesar cipher](https://en.wikipedia.org/wiki/Caesar_cipher) encoder for the Flipper Zero device. + +![input](img/1.png) +![output](img/2.png) + +## Usage + +Start app, painfully input your ciphertext with the onscreen keyboard. Replace spaces with underscores. Hit "Save", scroll output. + +## Compiling + +``` +./fbt firmware_caesar_cipher +``` + diff --git a/Applications/Official/DEV_FW/source/xMasterX/caesarcipher/application.fam b/Applications/Official/DEV_FW/source/xMasterX/caesarcipher/application.fam new file mode 100644 index 000000000..30b12a636 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/caesarcipher/application.fam @@ -0,0 +1,14 @@ +App( + appid="Caesar_Cipher", + name="Caesar Cipher", + apptype=FlipperAppType.PLUGIN, + entry_point="caesar_cipher_app", + cdefines=["APP_CAESAR_CIPHER"], + requires=[ + "gui", + ], + stack_size=2 * 1024, + fap_icon="caesar_cipher_icon.png", + fap_category="Misc_Extra", + order=20, +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/caesarcipher/caesar_cipher.c b/Applications/Official/DEV_FW/source/xMasterX/caesarcipher/caesar_cipher.c new file mode 100644 index 000000000..9eb93e925 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/caesarcipher/caesar_cipher.c @@ -0,0 +1,147 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#define TEXT_BUFFER_SIZE 256 + +typedef enum { + EventTypeTick, + EventTypeKey, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} PluginEvent; + +typedef struct { + ViewDispatcher* view_dispatcher; + TextInput* text_input; + TextBox* text_box; + char input[TEXT_BUFFER_SIZE]; + char output[(TEXT_BUFFER_SIZE * 26) + (26)]; // linebreaks +} CaesarState; + +static void string_to_uppercase(char* input) { + int i; + for(i = 0; input[i] != '\0'; i++) { + if(input[i] >= 'a' && input[i] <= 'z') { + input[i] = input[i] - 32; + } else { + input[i] = input[i]; + } + } +} + +static void build_output(char* input, char* output) { + int out = 0; + for(int rot = 1; rot < 26; rot++) { + int in; + for(in = 0; input[in] != '\0'; in++) { + if(input[in] >= 'A' && input[in] <= 'Z') { + output[out] = 65 + (((input[in] - 65) + rot) % 26); + } else { + output[out] = input[in]; + } + out++; + } + output[out] = '\n'; + out++; + } + output[out] = '\0'; +} + +static void text_input_callback(void* ctx) { + CaesarState* caesar_state = acquire_mutex((ValueMutex*)ctx, 25); + FURI_LOG_D("caesar_cipher", "Input text: %s", caesar_state->input); + // this is where we build the output. + string_to_uppercase(caesar_state->input); + FURI_LOG_D("caesar_cipher", "Upper text: %s", caesar_state->input); + build_output(caesar_state->input, caesar_state->output); + text_box_set_text(caesar_state->text_box, caesar_state->output); + view_dispatcher_switch_to_view(caesar_state->view_dispatcher, 1); + + release_mutex((ValueMutex*)ctx, caesar_state); +} + +static bool back_event_callback(void* ctx) { + const CaesarState* caesar_state = acquire_mutex((ValueMutex*)ctx, 25); + view_dispatcher_stop(caesar_state->view_dispatcher); + release_mutex((ValueMutex*)ctx, caesar_state); + return true; +} + +static void caesar_cipher_state_init(CaesarState* const caesar_state) { + caesar_state->view_dispatcher = view_dispatcher_alloc(); + caesar_state->text_input = text_input_alloc(); + caesar_state->text_box = text_box_alloc(); + text_box_set_font(caesar_state->text_box, TextBoxFontText); +} + +static void caesar_cipher_state_free(CaesarState* const caesar_state) { + text_input_free(caesar_state->text_input); + text_box_free(caesar_state->text_box); + view_dispatcher_remove_view(caesar_state->view_dispatcher, 0); + view_dispatcher_remove_view(caesar_state->view_dispatcher, 1); + view_dispatcher_free(caesar_state->view_dispatcher); + free(caesar_state); +} + +int32_t caesar_cipher_app() { + CaesarState* caesar_state = malloc(sizeof(CaesarState)); + + FURI_LOG_D("caesar_cipher", "Running caesar_cipher_state_init"); + caesar_cipher_state_init(caesar_state); + + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, caesar_state, sizeof(CaesarState))) { + FURI_LOG_E("caesar_cipher", "cannot create mutex\r\n"); + free(caesar_state); + return 255; + } + + FURI_LOG_D("caesar_cipher", "Assigning text input callback"); + text_input_set_result_callback( + caesar_state->text_input, + text_input_callback, + &state_mutex, + caesar_state->input, + TEXT_BUFFER_SIZE, + //clear default text + true); + text_input_set_header_text(caesar_state->text_input, "Input"); + + // Open GUI and register view_port + Gui* gui = furi_record_open("gui"); + //gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + FURI_LOG_D("caesar_cipher", "Enabling view dispatcher queue"); + view_dispatcher_enable_queue(caesar_state->view_dispatcher); + + FURI_LOG_D("caesar_cipher", "Adding text input view to dispatcher"); + view_dispatcher_add_view( + caesar_state->view_dispatcher, 0, text_input_get_view(caesar_state->text_input)); + view_dispatcher_add_view( + caesar_state->view_dispatcher, 1, text_box_get_view(caesar_state->text_box)); + FURI_LOG_D("caesar_cipher", "Attaching view dispatcher to GUI"); + view_dispatcher_attach_to_gui( + caesar_state->view_dispatcher, gui, ViewDispatcherTypeFullscreen); + FURI_LOG_D("ceasar_cipher", "starting view dispatcher"); + view_dispatcher_set_navigation_event_callback( + caesar_state->view_dispatcher, back_event_callback); + view_dispatcher_set_event_callback_context(caesar_state->view_dispatcher, &state_mutex); + view_dispatcher_switch_to_view(caesar_state->view_dispatcher, 0); + view_dispatcher_run(caesar_state->view_dispatcher); + + furi_record_close("gui"); + delete_mutex(&state_mutex); + caesar_cipher_state_free(caesar_state); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/caesarcipher/caesar_cipher_icon.png b/Applications/Official/DEV_FW/source/xMasterX/caesarcipher/caesar_cipher_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..13077e89251aa97a40ebc82d36f70c394bb045d2 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V6Od#Ihk44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`0h7I;J!GcfQS24TkI`72U@f{vapjv*Sst)~O|7!){|F1)MHZ1PyXZteHh z72F57&NycqU%#+J^|^cM{HFqX2%Dh OVGN$GelF{r5}E+;+BUKP literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/caesarcipher/img/1.png b/Applications/Official/DEV_FW/source/xMasterX/caesarcipher/img/1.png new file mode 100644 index 0000000000000000000000000000000000000000..93a9bcdbe494128a7407e460180301ce7019e43d GIT binary patch literal 2197 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 F{0ovmJ~99R literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/calculator/application.fam b/Applications/Official/DEV_FW/source/xMasterX/calculator/application.fam new file mode 100644 index 000000000..33f1d6cf8 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/calculator/application.fam @@ -0,0 +1,12 @@ +App( + appid="Calculator", + name="Calculator", + apptype=FlipperAppType.EXTERNAL, + entry_point="calculator_app", + cdefines=["APP_CALCULATOR"], + requires=["gui"], + stack_size=1 * 1024, + order=45, + fap_icon="calcIcon.png", + fap_category="Misc_Extra", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/calculator/calc.png b/Applications/Official/DEV_FW/source/xMasterX/calculator/calc.png new file mode 100644 index 0000000000000000000000000000000000000000..838d7b964feaf466887daedbf8cfaa0966ee6d4b GIT binary patch literal 1206 zcmV;n1WEgeP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&1WQRoK~#8N?VRnA z<1h$@lPzG|xB{<$n=LbKTmv~?Cu9hR5R$CKv3X{g_(NC-zY<#i*z@(zuj}c^{JxyN z?uUov{C&zKT>oYgQVAfHK%^3gR05GoAW{iLDuGBP5UB(rl|U>?IR9L3CkOq75>EF& zrLRZ*h2{5z{GLG5BC7++?PFR2}r&mr2p*dm@!U z6qRr!poFXrR2|OrbL=D#kLhq!uqG@@=w11F9r<+sR6^~qNMuS{D?L81#{Hgv0YGNb zS_ajd0Lu^8*jkAA6qNu+Yo1xxEM&(Vh_(`?WJmjM#Z&?U80pX(U=%A6Jfz$?B!|JCu5jB>-BI&odZPuOYc6{IS_YzX`ud#-Ibxpv-rM1!< z+$-69b$A6(LViymQVFbt-nqMlg$<1QrxMoQF@7SOt`3l@v?yL%>t0m}EuCvPc(xYM z9`jsU^ckhL{7j9jgx0_%BZB}s*wO$>=>9x^R|zehYDNdaz^~UAJ`w-vYr@DN0Q}e& z&zZs0>cE5VO~5F!e=mWdHKFGXNMC7DbX%OaBvZHd60zwWqYS$Ae9Ir#y!N^+n7Ss6 zfMD5L@Y-AVa>q#I_XOgxCfrVsODbW@)gi)K{;7nl4y1;x4nZaGylDYGmbEbA+d@?d zBb{Th(iR2%_WHKsRtFA*e=Rsk`o5LCQXgPVf6G^5wKbK1n^vb$;H#|`oMzNNin}JD zQ|`DmfLQ@Y(8<%L!J1IrEMY*U`#f0l;VKbcn;HHQ;6HVrfWV}+GU^{Cv`?5Bz!u0I zBau5s;;~P-ogSA|g12Lguttdj@Agk6WOX1l?7ccb?kxEdMJ2GawiZTw!Kil!nyI-oQCCanNGM*X9>N*L`F{?b|*^^daqeL^IGxnm@DuY?FtLViym zQVFbt-qjbS3w*l2s{}OShI=Ke12Mfie1ek9HK7)?)z+GmxX0J!vBdL_VEOa45?0$O zO3;JGaV@xaQLPSErX{8OItie34V0c=V=e#OC+x90;O%;*sa6NbtVe3_ksac=SF*GD zZ%wc=Wue=b2Kes#HQ0aZbU<*u0ltdOuL-Y6BG!b%{{i(_6K@O}3;>-4=Fg=>}R4tG=1{CK;NUH_l9( zwBVuMytwxkJlK{}g~b+6{-J{CUPL|UT|q1AVg(Ns6zZEyl8sQiy%JD# zf5S(qT%5aEojN@|Jvlj{($Ue;;o;%v=;-nB@xj5t@bK`?&d%Q6UM`p0*x1MFMw0>KEnPDFL%BwCWi`GrkAwCZg zu`%EBLuyUqj<-VSEa8N;am@=#-0_Ep9P6PHx1d;}6;9&1H@z0&TWhmbXKl$b5I253 zH&|?$6v4*{WLthCh|N}sYXh6~Jyi=F+crs-N?bXO$SzuQ>?DaWtMM{$L{VflgO_Yo zftv9wD~qx$h^ipvfuxxQ)szZs=flx>EL)6_YtC1m@5G~0iK{0`XbM8J+2osfoK1c%$Ok0UA>5@WtlTUoWQ`r zGnEoYlj1!OnW9}#= z(d(wEO0q54vJG@q#X!+0ny$DCkY&ThiUesewTt#bIzz_4`}sII6RswN=`$sGG2?j&iD$Rdb#H_x%iF9dYM-jJ0u7IC^U;J(x&|fAN#~Cd*HL?CH1=X8WU$RTrl9BW zA~TDLn>1mB%QZTLhx1OjKp`<)IlqjH@#Ft2Bg1y;FsNaA($Wp=FRUn}XHx&vio)3g zEAW@BH=WrvCBiZ7`~?e^eN_uit*_i8udvyZG8YHq)$ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/calculator/calculator.c b/Applications/Official/DEV_FW/source/xMasterX/calculator/calculator.c new file mode 100644 index 000000000..b121641b0 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/calculator/calculator.c @@ -0,0 +1,453 @@ +#include +#include +#include +#include +#include +#include +#include // Header-file for boolean data-type. +#include // Header-file for string functions. +#include "tinyexpr.h" // Header-file for the TinyExpr library. + +#include +#include + +const short MAX_TEXT_LENGTH = 20; + +typedef struct { + short x; + short y; +} selectedPosition; + +typedef struct { + selectedPosition position; + //string with the inputted calculator text + char text[20]; + short textLength; + char log[20]; +} Calculator; + +char getKeyAtPosition(short x, short y) { + if(x == 0 && y == 0) { + return 'C'; + } + if(x == 1 && y == 0) { + return '<'; + } + if(x == 2 && y == 0) { + return '%'; + } + if(x == 3 && y == 0) { + return '/'; + } + if(x == 0 && y == 1) { + return '1'; + } + if(x == 1 && y == 1) { + return '2'; + } + if(x == 2 && y == 1) { + return '3'; + } + if(x == 3 && y == 1) { + return '*'; + } + if(x == 0 && y == 2) { + return '4'; + } + if(x == 1 && y == 2) { + return '5'; + } + if(x == 2 && y == 2) { + return '6'; + } + if(x == 3 && y == 2) { + return '-'; + } + if(x == 0 && y == 3) { + return '7'; + } + if(x == 1 && y == 3) { + return '8'; + } + if(x == 2 && y == 3) { + return '9'; + } + if(x == 3 && y == 3) { + return '+'; + } + if(x == 0 && y == 4) { + return '('; + } + if(x == 1 && y == 4) { + return '0'; + } + if(x == 2 && y == 4) { + return '.'; + } + if(x == 3 && y == 4) { + return '='; + } + return ' '; +} + +short calculateStringWidth(const char* str, short lenght) { + /* widths: + 1 = 2 + 2, 3, 4, 5, 6, 7, 8, 9, 0, X, -, +, . = = 5 + %, / = 7 + S = 5 + (, ) = 3 + + */ + short width = 0; + for(short i = 0; i < lenght; i++) { + switch(str[i]) { + case '1': + width += 2; + break; + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '0': + case '*': + case '-': + case '+': + case '.': + width += 5; + break; + case '%': + case '/': + width += 7; + break; + case 'S': + width += 5; + break; + case '(': + case ')': + width += 3; + break; + default: + break; + } + width += 1; + } + + return width; +} + +void generate_calculator_layout(Canvas* canvas) { + //draw dotted lines + for(int i = 0; i <= 64; i++) { + if(i % 2 == 0) { + canvas_draw_dot(canvas, i, 14); + canvas_draw_dot(canvas, i, 33); + } + if(i % 2 == 1) { + canvas_draw_dot(canvas, i, 15); + canvas_draw_dot(canvas, i, 34); + } + } + + //draw horizontal lines + canvas_draw_box(canvas, 0, 41, 64, 2); + canvas_draw_box(canvas, 0, 57, 64, 2); + canvas_draw_box(canvas, 0, 73, 64, 2); + canvas_draw_box(canvas, 0, 89, 64, 2); + canvas_draw_box(canvas, 0, 105, 64, 2); + canvas_draw_box(canvas, 0, 121, 64, 2); + + //draw vertical lines + canvas_draw_box(canvas, 0, 43, 1, 80); + canvas_draw_box(canvas, 15, 43, 2, 80); + canvas_draw_box(canvas, 31, 43, 2, 80); + canvas_draw_box(canvas, 47, 43, 2, 80); + canvas_draw_box(canvas, 63, 43, 1, 80); + + //draw buttons + //row 1 (C, ;, %, ÷) + canvas_draw_str(canvas, 5, 54, "C"); + canvas_draw_str(canvas, 19, 54, " <-"); + canvas_draw_str(canvas, 35, 54, " %"); + canvas_draw_str(canvas, 51, 54, " /"); + + //row 2 (1, 2, 3, X) + canvas_draw_str(canvas, 5, 70, " 1"); + canvas_draw_str(canvas, 19, 70, " 2"); + canvas_draw_str(canvas, 35, 70, " 3"); + canvas_draw_str(canvas, 51, 70, " X"); + + //row 3 (4, 5, 6, -) + canvas_draw_str(canvas, 5, 86, " 4"); + canvas_draw_str(canvas, 19, 86, " 5"); + canvas_draw_str(canvas, 35, 86, " 6"); + canvas_draw_str(canvas, 51, 86, " -"); + + //row 4 (7, 8, 9, +) + canvas_draw_str(canvas, 5, 102, " 7"); + canvas_draw_str(canvas, 19, 102, " 8"); + canvas_draw_str(canvas, 35, 102, " 9"); + canvas_draw_str(canvas, 51, 102, " +"); + + //row 5 (+/-, 0, ., =) + canvas_draw_str(canvas, 3, 118, "( )"); + canvas_draw_str(canvas, 19, 118, " 0"); + canvas_draw_str(canvas, 35, 118, " ."); + canvas_draw_str(canvas, 51, 118, " ="); +}; + +void calculator_draw_callback(Canvas* canvas, void* ctx) { + const Calculator* calculator_state = acquire_mutex((ValueMutex*)ctx, 25); + UNUSED(ctx); + canvas_clear(canvas); + + //show selected button + short startX = 1; + short startY = 43; + + canvas_set_color(canvas, ColorBlack); + canvas_draw_box( + canvas, + startX + (calculator_state->position.x) * 16, + (startY) + (calculator_state->position.y) * 16, + 16, + 16); + canvas_set_color(canvas, ColorWhite); + canvas_draw_box( + canvas, + startX + (calculator_state->position.x) * 16 + 2, + (startY) + (calculator_state->position.y) * 16 + 2, + 10, + 10); + + canvas_set_color(canvas, ColorBlack); + generate_calculator_layout(canvas); + + //draw text + short stringWidth = calculateStringWidth(calculator_state->text, calculator_state->textLength); + short startingPosition = 5; + if(stringWidth > 60) { + startingPosition += 60 - (stringWidth + 5); + } + canvas_set_color(canvas, ColorBlack); + canvas_draw_str(canvas, startingPosition, 28, calculator_state->text); + //canvas_draw_str(canvas, 10, 10, calculator_state->log); + + //draw cursor + canvas_draw_box(canvas, stringWidth + 5, 29, 5, 1); + + release_mutex((ValueMutex*)ctx, calculator_state); +} + +void calculator_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + furi_message_queue_put(event_queue, input_event, FuriWaitForever); +} + +void calculate(Calculator* calculator_state) { + double result; + result = te_interp(calculator_state->text, 0); + + calculator_state->textLength = 0; + calculator_state->text[0] = '\0'; + // sprintf(calculator_state->text, "%f", result); + + //invert sign if negative + if(result < 0) { + calculator_state->text[calculator_state->textLength++] = '-'; + result = -result; + } + + //get numbers before and after decimal + int beforeDecimal = result; + int afterDecimal = (result - beforeDecimal) * 100; + + char beforeDecimalString[10]; + char afterDecimalString[10]; + int i = 0; + //parse to a string + while(beforeDecimal > 0) { + beforeDecimalString[i++] = beforeDecimal % 10 + '0'; + beforeDecimal /= 10; + } + // invert string + for(int j = 0; j < i / 2; j++) { + char temp = beforeDecimalString[j]; + beforeDecimalString[j] = beforeDecimalString[i - j - 1]; + beforeDecimalString[i - j - 1] = temp; + } + //add it to the answer + for(int j = 0; j < i; j++) { + calculator_state->text[calculator_state->textLength++] = beforeDecimalString[j]; + } + + i = 0; + if(afterDecimal > 0) { + while(afterDecimal > 0) { + afterDecimalString[i++] = afterDecimal % 10 + '0'; + afterDecimal /= 10; + } + // invert string + for(int j = 0; j < i / 2; j++) { + char temp = afterDecimalString[j]; + afterDecimalString[j] = afterDecimalString[i - j - 1]; + afterDecimalString[i - j - 1] = temp; + } + + //add decimal point + calculator_state->text[calculator_state->textLength++] = '.'; + + //add numbers after decimal + for(int j = 0; j < i; j++) { + calculator_state->text[calculator_state->textLength++] = afterDecimalString[j]; + } + } + calculator_state->text[calculator_state->textLength] = '\0'; +} + +int32_t calculator_app(void* p) { + UNUSED(p); + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + Calculator* calculator_state = malloc(sizeof(Calculator)); + ValueMutex calculator_state_mutex; + if(!init_mutex(&calculator_state_mutex, calculator_state, sizeof(Calculator))) { + //FURI_LOG_E("calculator", "cannot create mutex\r\n"); + free(calculator_state); + return -1; + } + + // Configure view port + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, calculator_draw_callback, &calculator_state_mutex); + view_port_input_callback_set(view_port, calculator_input_callback, event_queue); + view_port_set_orientation(view_port, ViewPortOrientationVertical); + + // Register view port in GUI + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + //NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + + InputEvent event; + + while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) { + //break out of the loop if the back key is pressed + if(event.type == InputTypeShort && event.key == InputKeyBack) { + break; + } + + if(event.type == InputTypeShort) { + switch(event.key) { + case InputKeyUp: + if(calculator_state->position.y > 0) { + calculator_state->position.y--; + } + break; + case InputKeyDown: + if(calculator_state->position.y < 4) { + calculator_state->position.y++; + } + break; + case InputKeyLeft: + if(calculator_state->position.x > 0) { + calculator_state->position.x--; + } + break; + case InputKeyRight: + if(calculator_state->position.x < 3) { + calculator_state->position.x++; + } + break; + case InputKeyOk: { + //add the selected button to the text + //char* text = calculator_state->text; + // short* textLength = &calculator_state->textLength; + + char key = + getKeyAtPosition(calculator_state->position.x, calculator_state->position.y); + + switch(key) { + case 'C': + while(calculator_state->textLength > 0) { + calculator_state->text[calculator_state->textLength--] = '\0'; + } + calculator_state->text[0] = '\0'; + calculator_state->log[2] = key; + break; + case '<': + calculator_state->log[2] = key; + if(calculator_state->textLength > 0) { + calculator_state->text[--calculator_state->textLength] = '\0'; + } else { + calculator_state->text[0] = '\0'; + } + break; + case '=': + calculator_state->log[2] = key; + calculate(calculator_state); + break; + case '%': + case '/': + case '*': + case '-': + case '+': + case '.': + case '(': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '0': + if(calculator_state->textLength < MAX_TEXT_LENGTH) { + calculator_state->text[calculator_state->textLength++] = key; + calculator_state->text[calculator_state->textLength] = '\0'; + } + //calculator_state->log[1] = calculator_state->text[*textLength]; + break; + default: + break; + } + } + default: + break; + } + + view_port_update(view_port); + } + + if(event.type == InputTypeLong) { + switch(event.key) { + case InputKeyOk: + if(calculator_state->position.x == 0 && calculator_state->position.y == 4) { + if(calculator_state->textLength < MAX_TEXT_LENGTH) { + calculator_state->text[calculator_state->textLength++] = ')'; + calculator_state->text[calculator_state->textLength] = '\0'; + } + view_port_update(view_port); + } + break; + default: + break; + } + } + } + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + furi_message_queue_free(event_queue); + + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_GUI); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/calculator/tinyexpr.c b/Applications/Official/DEV_FW/source/xMasterX/calculator/tinyexpr.c new file mode 100644 index 000000000..40e25236f --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/calculator/tinyexpr.c @@ -0,0 +1,785 @@ +// SPDX-License-Identifier: Zlib +/* + * TINYEXPR - Tiny recursive descent parser and evaluation engine in C + * + * Copyright (c) 2015-2020 Lewis Van Winkle + * + * http://CodePlea.com + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgement in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +/* COMPILE TIME OPTIONS */ + +/* Exponentiation associativity: +For a^b^c = (a^b)^c and -a^b = (-a)^b do nothing. +For a^b^c = a^(b^c) and -a^b = -(a^b) uncomment the next line.*/ +/* #define TE_POW_FROM_RIGHT */ + +/* Logarithms +For log = base 10 log do nothing +For log = natural log uncomment the next line. */ +/* #define TE_NAT_LOG */ + +#include "tinyexpr.h" +#include +#include +#include +#include +#include +#include + +#ifndef NAN +#define NAN (0.0 / 0.0) +#endif + +#ifndef INFINITY +#define INFINITY (1.0 / 0.0) +#endif + +typedef double (*te_fun2)(double, double); + +enum { + TOK_NULL = TE_CLOSURE7 + 1, + TOK_ERROR, + TOK_END, + TOK_SEP, + TOK_OPEN, + TOK_CLOSE, + TOK_NUMBER, + TOK_VARIABLE, + TOK_INFIX +}; + +enum { TE_CONSTANT = 1 }; + +typedef struct state { + const char* start; + const char* next; + int type; + union { + double value; + const double* bound; + const void* function; + }; + void* context; + + const te_variable* lookup; + int lookup_len; +} state; + +#define TYPE_MASK(TYPE) ((TYPE)&0x0000001F) + +#define IS_PURE(TYPE) (((TYPE)&TE_FLAG_PURE) != 0) +#define IS_FUNCTION(TYPE) (((TYPE)&TE_FUNCTION0) != 0) +#define IS_CLOSURE(TYPE) (((TYPE)&TE_CLOSURE0) != 0) +#define ARITY(TYPE) (((TYPE) & (TE_FUNCTION0 | TE_CLOSURE0)) ? ((TYPE)&0x00000007) : 0) +#define NEW_EXPR(type, ...) new_expr((type), (const te_expr*[]){__VA_ARGS__}) + +static te_expr* new_expr(const int type, const te_expr* parameters[]) { + const int arity = ARITY(type); + const int psize = sizeof(void*) * arity; + const int size = + (sizeof(te_expr) - sizeof(void*)) + psize + (IS_CLOSURE(type) ? sizeof(void*) : 0); + te_expr* ret = malloc(size); + memset(ret, 0, size); + if(arity && parameters) { + memcpy(ret->parameters, parameters, psize); + } + ret->type = type; + ret->bound = 0; + return ret; +} + +void te_free_parameters(te_expr* n) { + if(!n) return; + switch(TYPE_MASK(n->type)) { + case TE_FUNCTION7: + case TE_CLOSURE7: + te_free(n->parameters[6]); /* Falls through. */ + case TE_FUNCTION6: + case TE_CLOSURE6: + te_free(n->parameters[5]); /* Falls through. */ + case TE_FUNCTION5: + case TE_CLOSURE5: + te_free(n->parameters[4]); /* Falls through. */ + case TE_FUNCTION4: + case TE_CLOSURE4: + te_free(n->parameters[3]); /* Falls through. */ + case TE_FUNCTION3: + case TE_CLOSURE3: + te_free(n->parameters[2]); /* Falls through. */ + case TE_FUNCTION2: + case TE_CLOSURE2: + te_free(n->parameters[1]); /* Falls through. */ + case TE_FUNCTION1: + case TE_CLOSURE1: + te_free(n->parameters[0]); + } +} + +void te_free(te_expr* n) { + if(!n) return; + te_free_parameters(n); + free(n); +} + +static double pi(void) { + return 3.14159265358979323846; +} +static double e(void) { + return 2.71828182845904523536; +} +static double fac(double a) { /* simplest version of fac */ + if(a < 0.0) return NAN; + if(a > UINT_MAX) return INFINITY; + unsigned int ua = (unsigned int)(a); + unsigned long int result = 1, i; + for(i = 1; i <= ua; i++) { + if(i > ULONG_MAX / result) return INFINITY; + result *= i; + } + return (double)result; +} +static double ncr(double n, double r) { + if(n < 0.0 || r < 0.0 || n < r) return NAN; + if(n > UINT_MAX || r > UINT_MAX) return INFINITY; + unsigned long int un = (unsigned int)(n), ur = (unsigned int)(r), i; + unsigned long int result = 1; + if(ur > un / 2) ur = un - ur; + for(i = 1; i <= ur; i++) { + if(result > ULONG_MAX / (un - ur + i)) return INFINITY; + result *= un - ur + i; + result /= i; + } + return result; +} +static double npr(double n, double r) { + return ncr(n, r) * fac(r); +} + +#ifdef _MSC_VER +#pragma function(ceil) +#pragma function(floor) +#endif + +static const te_variable functions[] = { + /* must be in alphabetical order */ + {"abs", fabs, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {"acos", acos, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {"asin", asin, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {"atan", atan, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {"atan2", atan2, TE_FUNCTION2 | TE_FLAG_PURE, 0}, + {"ceil", ceil, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {"cos", cos, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {"cosh", cosh, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {"e", e, TE_FUNCTION0 | TE_FLAG_PURE, 0}, + {"exp", exp, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {"fac", fac, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {"floor", floor, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {"ln", log, TE_FUNCTION1 | TE_FLAG_PURE, 0}, +#ifdef TE_NAT_LOG + {"log", log, TE_FUNCTION1 | TE_FLAG_PURE, 0}, +#else + {"log", log10, TE_FUNCTION1 | TE_FLAG_PURE, 0}, +#endif + {"log10", log10, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {"ncr", ncr, TE_FUNCTION2 | TE_FLAG_PURE, 0}, + {"npr", npr, TE_FUNCTION2 | TE_FLAG_PURE, 0}, + {"pi", pi, TE_FUNCTION0 | TE_FLAG_PURE, 0}, + {"pow", pow, TE_FUNCTION2 | TE_FLAG_PURE, 0}, + {"sin", sin, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {"sinh", sinh, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {"sqrt", sqrt, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {"tan", tan, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {"tanh", tanh, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {0, 0, 0, 0}}; + +static const te_variable* find_builtin(const char* name, int len) { + int imin = 0; + int imax = sizeof(functions) / sizeof(te_variable) - 2; + + /*Binary search.*/ + while(imax >= imin) { + const int i = (imin + ((imax - imin) / 2)); + int c = strncmp(name, functions[i].name, len); + if(!c) c = '\0' - functions[i].name[len]; + if(c == 0) { + return functions + i; + } else if(c > 0) { + imin = i + 1; + } else { + imax = i - 1; + } + } + + return 0; +} + +static const te_variable* find_lookup(const state* s, const char* name, int len) { + int iters; + const te_variable* var; + if(!s->lookup) return 0; + + for(var = s->lookup, iters = s->lookup_len; iters; ++var, --iters) { + if(strncmp(name, var->name, len) == 0 && var->name[len] == '\0') { + return var; + } + } + return 0; +} + +static double add(double a, double b) { + return a + b; +} +static double sub(double a, double b) { + return a - b; +} +static double mul(double a, double b) { + return a * b; +} +static double divide(double a, double b) { + return a / b; +} +static double negate(double a) { + return -a; +} +static double comma(double a, double b) { + (void)a; + return b; +} + +void next_token(state* s) { + s->type = TOK_NULL; + + do { + if(!*s->next) { + s->type = TOK_END; + return; + } + + /* Try reading a number. */ + if((s->next[0] >= '0' && s->next[0] <= '9') || s->next[0] == '.') { + s->value = strtof(s->next, (char**)&s->next); + s->type = TOK_NUMBER; + } else { + /* Look for a variable or builtin function call. */ + if(isalpha(s->next[0])) { + const char* start; + start = s->next; + while(isalpha(s->next[0]) || isdigit(s->next[0]) || (s->next[0] == '_')) s->next++; + + const te_variable* var = find_lookup(s, start, s->next - start); + if(!var) var = find_builtin(start, s->next - start); + + if(!var) { + s->type = TOK_ERROR; + } else { + switch(TYPE_MASK(var->type)) { + case TE_VARIABLE: + s->type = TOK_VARIABLE; + s->bound = var->address; + break; + + case TE_CLOSURE0: + case TE_CLOSURE1: + case TE_CLOSURE2: + case TE_CLOSURE3: /* Falls through. */ + case TE_CLOSURE4: + case TE_CLOSURE5: + case TE_CLOSURE6: + case TE_CLOSURE7: /* Falls through. */ + s->context = var->context; /* Falls through. */ + + case TE_FUNCTION0: + case TE_FUNCTION1: + case TE_FUNCTION2: + case TE_FUNCTION3: /* Falls through. */ + case TE_FUNCTION4: + case TE_FUNCTION5: + case TE_FUNCTION6: + case TE_FUNCTION7: /* Falls through. */ + s->type = var->type; + s->function = var->address; + break; + } + } + + } else { + /* Look for an operator or special character. */ + switch(s->next++[0]) { + case '+': + s->type = TOK_INFIX; + s->function = add; + break; + case '-': + s->type = TOK_INFIX; + s->function = sub; + break; + case '*': + s->type = TOK_INFIX; + s->function = mul; + break; + case '/': + s->type = TOK_INFIX; + s->function = divide; + break; + case '^': + s->type = TOK_INFIX; + s->function = pow; + break; + case '%': + s->type = TOK_INFIX; + s->function = fmod; + break; + case '(': + s->type = TOK_OPEN; + break; + case ')': + s->type = TOK_CLOSE; + break; + case ',': + s->type = TOK_SEP; + break; + case ' ': + case '\t': + case '\n': + case '\r': + break; + default: + s->type = TOK_ERROR; + break; + } + } + } + } while(s->type == TOK_NULL); +} + +static te_expr* list(state* s); +static te_expr* expr(state* s); +static te_expr* power(state* s); + +static te_expr* base(state* s) { + /* = | | {"(" ")"} | | "(" {"," } ")" | "(" ")" */ + te_expr* ret; + int arity; + + switch(TYPE_MASK(s->type)) { + case TOK_NUMBER: + ret = new_expr(TE_CONSTANT, 0); + ret->value = s->value; + next_token(s); + break; + + case TOK_VARIABLE: + ret = new_expr(TE_VARIABLE, 0); + ret->bound = s->bound; + next_token(s); + break; + + case TE_FUNCTION0: + case TE_CLOSURE0: + ret = new_expr(s->type, 0); + ret->function = s->function; + if(IS_CLOSURE(s->type)) ret->parameters[0] = s->context; + next_token(s); + if(s->type == TOK_OPEN) { + next_token(s); + if(s->type != TOK_CLOSE) { + s->type = TOK_ERROR; + } else { + next_token(s); + } + } + break; + + case TE_FUNCTION1: + case TE_CLOSURE1: + ret = new_expr(s->type, 0); + ret->function = s->function; + if(IS_CLOSURE(s->type)) ret->parameters[1] = s->context; + next_token(s); + ret->parameters[0] = power(s); + break; + + case TE_FUNCTION2: + case TE_FUNCTION3: + case TE_FUNCTION4: + case TE_FUNCTION5: + case TE_FUNCTION6: + case TE_FUNCTION7: + case TE_CLOSURE2: + case TE_CLOSURE3: + case TE_CLOSURE4: + case TE_CLOSURE5: + case TE_CLOSURE6: + case TE_CLOSURE7: + arity = ARITY(s->type); + + ret = new_expr(s->type, 0); + ret->function = s->function; + if(IS_CLOSURE(s->type)) ret->parameters[arity] = s->context; + next_token(s); + + if(s->type != TOK_OPEN) { + s->type = TOK_ERROR; + } else { + int i; + for(i = 0; i < arity; i++) { + next_token(s); + ret->parameters[i] = expr(s); + if(s->type != TOK_SEP) { + break; + } + } + if(s->type != TOK_CLOSE || i != arity - 1) { + s->type = TOK_ERROR; + } else { + next_token(s); + } + } + + break; + + case TOK_OPEN: + next_token(s); + ret = list(s); + if(s->type != TOK_CLOSE) { + s->type = TOK_ERROR; + } else { + next_token(s); + } + break; + + default: + ret = new_expr(0, 0); + s->type = TOK_ERROR; + ret->value = NAN; + break; + } + + return ret; +} + +static te_expr* power(state* s) { + /* = {("-" | "+")} */ + int sign = 1; + while(s->type == TOK_INFIX && (s->function == add || s->function == sub)) { + if(s->function == sub) sign = -sign; + next_token(s); + } + + te_expr* ret; + + if(sign == 1) { + ret = base(s); + } else { + ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, base(s)); + ret->function = negate; + } + + return ret; +} + +#ifdef TE_POW_FROM_RIGHT +static te_expr* factor(state* s) { + /* = {"^" } */ + te_expr* ret = power(s); + + int neg = 0; + + if(ret->type == (TE_FUNCTION1 | TE_FLAG_PURE) && ret->function == negate) { + te_expr* se = ret->parameters[0]; + free(ret); + ret = se; + neg = 1; + } + + te_expr* insertion = 0; + + while(s->type == TOK_INFIX && (s->function == pow)) { + te_fun2 t = s->function; + next_token(s); + + if(insertion) { + /* Make exponentiation go right-to-left. */ + te_expr* insert = + NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, insertion->parameters[1], power(s)); + insert->function = t; + insertion->parameters[1] = insert; + insertion = insert; + } else { + ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, power(s)); + ret->function = t; + insertion = ret; + } + } + + if(neg) { + ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, ret); + ret->function = negate; + } + + return ret; +} +#else +static te_expr* factor(state* s) { + /* = {"^" } */ + te_expr* ret = power(s); + + while(s->type == TOK_INFIX && (s->function == pow)) { + te_fun2 t = s->function; + next_token(s); + ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, power(s)); + ret->function = t; + } + + return ret; +} +#endif + +static te_expr* term(state* s) { + /* = {("*" | "/" | "%") } */ + te_expr* ret = factor(s); + + while(s->type == TOK_INFIX && + (s->function == mul || s->function == divide || s->function == fmod)) { + te_fun2 t = s->function; + next_token(s); + ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, factor(s)); + ret->function = t; + } + + return ret; +} + +static te_expr* expr(state* s) { + /* = {("+" | "-") } */ + te_expr* ret = term(s); + + while(s->type == TOK_INFIX && (s->function == add || s->function == sub)) { + te_fun2 t = s->function; + next_token(s); + ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, term(s)); + ret->function = t; + } + + return ret; +} + +static te_expr* list(state* s) { + /* = {"," } */ + te_expr* ret = expr(s); + + while(s->type == TOK_SEP) { + next_token(s); + ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, expr(s)); + ret->function = comma; + } + + return ret; +} + +#define TE_FUN(...) ((double (*)(__VA_ARGS__))n->function) +#define M(e) te_eval(n->parameters[e]) + +double te_eval(const te_expr* n) { + if(!n) return NAN; + + switch(TYPE_MASK(n->type)) { + case TE_CONSTANT: + return n->value; + case TE_VARIABLE: + return *n->bound; + + case TE_FUNCTION0: + case TE_FUNCTION1: + case TE_FUNCTION2: + case TE_FUNCTION3: + case TE_FUNCTION4: + case TE_FUNCTION5: + case TE_FUNCTION6: + case TE_FUNCTION7: + switch(ARITY(n->type)) { + case 0: + return TE_FUN(void)(); + case 1: + return TE_FUN(double)(M(0)); + case 2: + return TE_FUN(double, double)(M(0), M(1)); + case 3: + return TE_FUN(double, double, double)(M(0), M(1), M(2)); + case 4: + return TE_FUN(double, double, double, double)(M(0), M(1), M(2), M(3)); + case 5: + return TE_FUN(double, double, double, double, double)(M(0), M(1), M(2), M(3), M(4)); + case 6: + return TE_FUN(double, double, double, double, double, double)( + M(0), M(1), M(2), M(3), M(4), M(5)); + case 7: + return TE_FUN(double, double, double, double, double, double, double)( + M(0), M(1), M(2), M(3), M(4), M(5), M(6)); + default: + return NAN; + } + + case TE_CLOSURE0: + case TE_CLOSURE1: + case TE_CLOSURE2: + case TE_CLOSURE3: + case TE_CLOSURE4: + case TE_CLOSURE5: + case TE_CLOSURE6: + case TE_CLOSURE7: + switch(ARITY(n->type)) { + case 0: + return TE_FUN(void*)(n->parameters[0]); + case 1: + return TE_FUN(void*, double)(n->parameters[1], M(0)); + case 2: + return TE_FUN(void*, double, double)(n->parameters[2], M(0), M(1)); + case 3: + return TE_FUN(void*, double, double, double)(n->parameters[3], M(0), M(1), M(2)); + case 4: + return TE_FUN(void*, double, double, double, double)( + n->parameters[4], M(0), M(1), M(2), M(3)); + case 5: + return TE_FUN(void*, double, double, double, double, double)( + n->parameters[5], M(0), M(1), M(2), M(3), M(4)); + case 6: + return TE_FUN(void*, double, double, double, double, double, double)( + n->parameters[6], M(0), M(1), M(2), M(3), M(4), M(5)); + case 7: + return TE_FUN(void*, double, double, double, double, double, double, double)( + n->parameters[7], M(0), M(1), M(2), M(3), M(4), M(5), M(6)); + default: + return NAN; + } + + default: + return NAN; + } +} + +#undef TE_FUN +#undef M + +static void optimize(te_expr* n) { + /* Evaluates as much as possible. */ + if(n->type == TE_CONSTANT) return; + if(n->type == TE_VARIABLE) return; + + /* Only optimize out functions flagged as pure. */ + if(IS_PURE(n->type)) { + const int arity = ARITY(n->type); + int known = 1; + int i; + for(i = 0; i < arity; ++i) { + optimize(n->parameters[i]); + if(((te_expr*)(n->parameters[i]))->type != TE_CONSTANT) { + known = 0; + } + } + if(known) { + const double value = te_eval(n); + te_free_parameters(n); + n->type = TE_CONSTANT; + n->value = value; + } + } +} + +te_expr* + te_compile(const char* expression, const te_variable* variables, int var_count, int* error) { + state s; + s.start = s.next = expression; + s.lookup = variables; + s.lookup_len = var_count; + + next_token(&s); + te_expr* root = list(&s); + + if(s.type != TOK_END) { + te_free(root); + if(error) { + *error = (s.next - s.start); + if(*error == 0) *error = 1; + } + return 0; + } else { + optimize(root); + if(error) *error = 0; + return root; + } +} + +double te_interp(const char* expression, int* error) { + te_expr* n = te_compile(expression, 0, 0, error); + double ret; + if(n) { + ret = te_eval(n); + te_free(n); + } else { + ret = NAN; + } + return ret; +} + +static void pn(const te_expr* n, int depth) { + int i, arity; + printf("%*s", depth, ""); + + switch(TYPE_MASK(n->type)) { + case TE_CONSTANT: + printf("%f\n", n->value); + break; + case TE_VARIABLE: + printf("bound %p\n", n->bound); + break; + + case TE_FUNCTION0: + case TE_FUNCTION1: + case TE_FUNCTION2: + case TE_FUNCTION3: + case TE_FUNCTION4: + case TE_FUNCTION5: + case TE_FUNCTION6: + case TE_FUNCTION7: + case TE_CLOSURE0: + case TE_CLOSURE1: + case TE_CLOSURE2: + case TE_CLOSURE3: + case TE_CLOSURE4: + case TE_CLOSURE5: + case TE_CLOSURE6: + case TE_CLOSURE7: + arity = ARITY(n->type); + printf("f%d", arity); + for(i = 0; i < arity; i++) { + printf(" %p", n->parameters[i]); + } + printf("\n"); + for(i = 0; i < arity; i++) { + pn(n->parameters[i], depth + 1); + } + break; + } +} + +void te_print(const te_expr* n) { + pn(n, 0); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/calculator/tinyexpr.h b/Applications/Official/DEV_FW/source/xMasterX/calculator/tinyexpr.h new file mode 100644 index 000000000..3833965a1 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/calculator/tinyexpr.h @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: Zlib +/* + * TINYEXPR - Tiny recursive descent parser and evaluation engine in C + * + * Copyright (c) 2015-2020 Lewis Van Winkle + * + * http://CodePlea.com + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgement in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#ifndef TINYEXPR_H +#define TINYEXPR_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct te_expr { + int type; + union { + double value; + const double* bound; + const void* function; + }; + void* parameters[1]; +} te_expr; + +enum { + TE_VARIABLE = 0, + + TE_FUNCTION0 = 8, + TE_FUNCTION1, + TE_FUNCTION2, + TE_FUNCTION3, + TE_FUNCTION4, + TE_FUNCTION5, + TE_FUNCTION6, + TE_FUNCTION7, + + TE_CLOSURE0 = 16, + TE_CLOSURE1, + TE_CLOSURE2, + TE_CLOSURE3, + TE_CLOSURE4, + TE_CLOSURE5, + TE_CLOSURE6, + TE_CLOSURE7, + + TE_FLAG_PURE = 32 +}; + +typedef struct te_variable { + const char* name; + const void* address; + int type; + void* context; +} te_variable; + +/* Parses the input expression, evaluates it, and frees it. */ +/* Returns NaN on error. */ +double te_interp(const char* expression, int* error); + +/* Parses the input expression and binds variables. */ +/* Returns NULL on error. */ +te_expr* + te_compile(const char* expression, const te_variable* variables, int var_count, int* error); + +/* Evaluates the expression. */ +double te_eval(const te_expr* n); + +/* Prints debugging information on the syntax tree. */ +void te_print(const te_expr* n); + +/* Frees the expression. */ +/* This is safe to call on NULL pointers. */ +void te_free(te_expr* n); + +#ifdef __cplusplus +} +#endif + +#endif /*TINYEXPR_H*/ diff --git a/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/.gitignore b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/.gitignore new file mode 100644 index 000000000..600d2d33b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/.gitignore @@ -0,0 +1 @@ +.vscode \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/LICENSE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/README.md b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/README.md new file mode 100644 index 000000000..b6d35fa7f --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/README.md @@ -0,0 +1,24 @@ +# flipperzero-cli-bridge +Allows CLI control from GUI, giving untethered access to sub-ghz chat, system diagnostics, and more. +# Installation +## Easy way - get a .fap file from the releases page +Swing by the [releases](https://github.com/ranchordo/flipperzero-cli-bridge/releases) page, and download a pre-built .fap file for the latest flipperzero firmware. Use [qFlipper](https://flipperzero.one/update) to copy the .fap file into SD Card/apps/Tools/. MAKE SURE TO UPGRADE FLIPPERZERO FIRMWARE TO NEWEST VERSION BEFORE INSTALLING. +## Hard way - building from source +The following commands will (probably) not work on Windows. If you run Windows, use wsl or a linux vm or something. +```sh +git clone https://github.com/flipperdevices/flipperzero-firmware +cd ./flipperzero-firmware +git clone https://github.com/ranchordo/flipperzero-cli-bridge ./applications_user/flipperzero-cli-bridge/ +./fbt fap_dist APPSRC=applications_user/flipperzero-cli-bridge +# If everything went well, the built .fap file can be found in ./dist/f7-D/apps/apps/Tools/cli_gui.fap +``` +# Usage +On the flipperzero, you should be able to find a new application (CLI-GUI Bridge) under Applications->Tools. Opening it will result in a text prompt - the prompt for the command line. Enter a suitable command (quickly pressing the back button or holding `_` on the keyboard will input a space) such as `subghz chat [freq in hz, e.g. 310000000]`, etc, then navigate to and press the SAVE key. You should then see the command window. Use Up and Down to scroll, and use Left or Center to get back to the text input prompt. A quick tap of the back key while viewing the console output sends a Ctrl-C to the console, and a long press of the left or right keys during text input will navigate back to the console output without executing. +## Exiting the app +Holding and then releasing the back key for at least a second or so (long press) will exit the app normally, meaning that the inner terminal will send Ctrl-C and close. Any sessions will be disconnected. + + +Holding and then releasing the OK key while focusing on the console output for at least a second or so (long press) will exit the app while keeping the terminal open. Terminal output will be cleared the next time you launch the app, but whatever command or session was running previously will be resumed. This is especially handy with subghz chat - exiting the app while keeping the terminal open will not disconnect you from the chat, and the flipper will still vibrate briefly whenever a new message comes in (even if the app is closed). + + +NOTE: USB functionality (qFlipper, normal USB CLI) may not work after running the app (especially after exiting without closing the terminal), simply restart your flipper and all USB functionality will return to normal. diff --git a/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/application.fam b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/application.fam new file mode 100644 index 000000000..9acc4d2be --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/application.fam @@ -0,0 +1,10 @@ +App( + appid="cli_gui", + name="CLI-GUI Bridge", + apptype=FlipperAppType.EXTERNAL, + entry_point="cligui_main", + requires=["gui","cli"], + stack_size=8 * 1024, + fap_icon="cligui.png", + fap_category="Misc_Extra", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/cli_control.c b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/cli_control.c new file mode 100644 index 000000000..e159d7424 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/cli_control.c @@ -0,0 +1,109 @@ +#include "cli_control.h" + +#include +#include +#include +#include "cligui_main_i.h" +#include + +volatile bool gotCallbackSet = false; + +FuriStreamBuffer* tx_stream; +FuriStreamBuffer* rx_stream; +static FuriThread* volatile cliThread = NULL; +static void tx_handler_stdout(const char* buffer, size_t size) { + furi_stream_buffer_send(tx_stream, buffer, size, FuriWaitForever); +} +static void tx_handler(const uint8_t* buffer, size_t size) { + furi_thread_set_stdout_callback(tx_handler_stdout); + cliThread = furi_thread_get_current(); + furi_stream_buffer_send(tx_stream, buffer, size, FuriWaitForever); +} +static size_t real_rx_handler(uint8_t* buffer, size_t size, uint32_t timeout) { + size_t rx_cnt = 0; + while(size > 0) { + size_t batch_size = size; + if(batch_size > 128) batch_size = 128; + size_t len = furi_stream_buffer_receive(rx_stream, buffer, batch_size, timeout); + if(len == 0) break; + size -= len; + buffer += len; + rx_cnt += len; + } + return rx_cnt; +} + +static CliCommand_internal* getInternalCliCommand(Cli* cli, const char* name) { + FuriString* target_command = furi_string_alloc(); + furi_string_set_str(target_command, name); + CliCommand_internal* command = + CliCommandTree_internal_get(((Cli_internal*)cli)->commands, target_command); + furi_string_free(target_command); + return command; +} + +static void session_init(void) { +} +static void session_deinit(void) { +} +static bool session_connected(void) { + return true; +} +static CliSession session; +void latch_tx_handler() { + Cli* global_cli = furi_record_open(RECORD_CLI); + + CliCommand_internal* help_command = getInternalCliCommand(global_cli, "help"); + cliThread = help_command->context; + + furi_thread_set_stdout_callback(tx_handler_stdout); + if(cliThread != NULL) { + ((FuriThread_internal*)cliThread)->output.write_callback = &tx_handler_stdout; + } + + rx_stream = furi_stream_buffer_alloc(128, 1); + tx_stream = furi_stream_buffer_alloc(128, 1); + + session.tx = &tx_handler; + session.rx = &real_rx_handler; + session.tx_stdout = &tx_handler_stdout; + session.init = &session_init; + session.deinit = &session_deinit; + session.is_connected = &session_connected; + cli_session_close(global_cli); + cli_session_open(global_cli, &session); + // Unlock loader-lock + Loader* loader = furi_record_open(RECORD_LOADER); + Loader_internal* loader_i = (Loader_internal*)loader; + loader_i->lock_count = 0; + furi_record_close(RECORD_CLI); + furi_record_close(RECORD_LOADER); +} +void unlatch_tx_handler(bool persist) { + Cli* global_cli = furi_record_open(RECORD_CLI); + // Stash cliThread if not null + if(cliThread != NULL) { + CliCommand_internal* help_command = getInternalCliCommand(global_cli, "help"); + help_command->context = cliThread; + } + // Switch to new session + if(persist) { + // Use dummy debug firmware function as is_connected + cli_vcp.is_connected = &furi_hal_version_do_i_belong_here; + } else { + // Send CTRL-C + char eot = 0x03; + furi_stream_buffer_send(rx_stream, &eot, 1, FuriWaitForever); + } + cli_session_open(global_cli, &cli_vcp); + furi_record_close(RECORD_CLI); + // Unblock waiting rx handler + furi_stream_buffer_send(rx_stream, "_", 1, FuriWaitForever); + // Reconfigure stdout_callback to cli_vcp + if(cliThread != NULL) { + ((FuriThread_internal*)cliThread)->output.write_callback = cli_vcp.tx_stdout; + } + // At this point, all cli_vcp functions should be back. + furi_stream_buffer_free(rx_stream); + furi_stream_buffer_free(tx_stream); +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/cli_control.h b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/cli_control.h new file mode 100644 index 000000000..9ea959155 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/cli_control.h @@ -0,0 +1,8 @@ +#pragma once + +#include +#include +extern void latch_tx_handler(); +extern void unlatch_tx_handler(bool persist); +extern FuriStreamBuffer* tx_stream; +extern FuriStreamBuffer* rx_stream; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/cligui.png b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/cligui.png new file mode 100644 index 0000000000000000000000000000000000000000..57a97049ee9f9774e2e02b7e942e86cbe4b01da4 GIT binary patch literal 8410 zcmeHNc{r49)E`22WnYRhB1>b&7=y{0b*w|OBr#?Nli8TDMn#q+iX;h$-ZVu zc8Q3Tid3(tq`qfpdzWu{uj~81zcQD{^PF?;-#Pd1oclcP`-cDtue=?H#q zRaxYYh&n#?MygnQc#6iJMyP66ud2l34_?&s2<{N(fQTeq2>1K)d_3_>tel|w&WSX9 zLeIq3H0++{c=Dos&-ft6O7+2)Z>e&}``*Vk${!D@{hFCPwWvqE30f|k6dC74)2NT8 zBtCvrs@7u-ZUytP9{x`Y{99D_9l7kSCmwXe)NrF6`N-4v zB}ZHu zKCCx4Hi}L&M+~lG7b*0WDa71Y^ml0EKcwmyVo=V-v8`0bvX^sSq3E6+HOX4oO@FBP zQEQ%sQFMmCo&$6y0g1d&;S_ zTb_}uJDp{HqghO7Y)aT#wIa9 zF!Ur&?nK;13+b>lhfCSHz5FMAvl4uAh=ZIrptTK?VlKPGPVIvA3p&+SABf7-$1;wl zWt~>D181?LLIk>lR&v9s;q;T7v5b3lDnBfh!OyxX_RRE_6`uLRUcslG`J!%)XP=3WyGv8Bgq4u=@z;&I1H{kqQ5EC& zB6Qzen*Yl2Nsj9s=fpFFhhOBGyUHdVqm~FXLU6F9L+inTXy0Idm+U#I!?b5PBbK@s z1|mVeRi2uU;z%55eh$@{9zBbzfw`^4&c;jqDmyRUD|Ta-tj)^E>F=yEdbfmYZ5nm= z?wIVv7!B3^9IM-aV&y7&uvdyn-w~Qos@HOqLq;;TkRPGGgUI{>n zI;S1X?Q$ehbW&tRES|_GH^qt_30Ou&#UO`}bWnR%R#RKY=>N) zM{f^ti=;F)7CzW5Y0xrT&Q`Gre=Y1-YPD@bmGSAuOGMW=ly`?Q-^M@oh^xub57g(I zyT%Wdj5w^M-h5k8o^@4rvsCIj4$3+VLVbVKCVeO60wS;Yh;L)%rv|-E8;VuicQxT$ zW!`cfak6VGEcQ5UsoFvzaF_BX6jrNp#4W^uon5ak zYq^V+@;uRSI+nfSk?Ru49N5sDZng^_iZCh+fXO z7&DDMQWL}5AMujS{C2(9VyfM(Qsomp{nxd4im#=U#EjNEWPrwnOt*Z~fbM<9C z+aJDpPRL!4%GzcwTgEQU+DJ=*?6k$YrOcwqY$|lHI(Fey?%~N zdOOAS(x}oYck%tTx{Ow%a4X}&KE?4%p>n-R=!8(u9@M%QQk;r~bhVYCW7%bLqaU0r zCepbw^GPpn<0EWktX_J}v2*CWb{viA+?jaklz9sMa$N9bm5c8lR5(ZM%(O@+B-TeBCUj<)$3A*pkXxm}yRO+=B>W&fYW}vuwsoarA|0O! zR6Y+N_2e=y+ISAo{ab8Y&$u=8DOWw2-2Hf)U4yr_{L)!1V{Rd<38fuE6umPke5&J- znNN9J!k;^cv>)y@$^=g-c=tu=H)Xnt-d1`?=s2rFHVX;0u{WMGz251H*>E!9M#w2j z_iT4==DeSkMW6C`b1b=K9iQ&C$%=fN>eHgt>jjFEPneeL zZ8@QLv|p?1T;1aQ7Rkx^OWvSG1FRKH*fFxeX_zvwVA{KK`t9roUhRb6YBu01uM~-X z+S(o!;8Hd(Y;&5+P;zE^>8{9Z@~yqY+5R5yYxXTvliP2)rvz2pT+II?Q*q%=@H3|7 zw`*}W$<%3dmKhs(cf6{wi{Lli-VrybfMRa0@fr}H-Z)0?g?9OHzX{AhEVL^vDv-Z(xAs3Kb?d`ac!s8*TnNDUrjkE~D z_5SM%8P>K}N-rapjwpWG#$b4j%Yjxl-Ewhp-dB(ElYa(59J{{@iHI;iC%-f;uas_K zFxR7@+z;N^Fmqw%s@0NJpmLwB_3hOD>S49sF2BvCMvDW(<1_givFio1p>{3(l7~1O zk9pKlm6YHxq=eM6%!L;+=7v{|b{>1oEq9jlEiWeia-!t<`>!?xCBV(5WseEBiJDE* zwN=hEbKT-n>n<%au8Er&8p$fiD@A?ut8cX6O@hf)Xg_!l*UJ^nvKQVf0ap&x(0j0KQ^8~umeY}NZhPVU%j@n2uX-`Z2Z!6iPt_MB(~Kl$-`63h zrG8)$JAF0+3O-_%FE!LU3)^2G?Yfs2^sGzh z=m&~LC<(nOPtR!Pbn?x)qk`@y+tVS*@r5|GDyw4Dt0FDjM~eSGLvm81HT)nV&@l3n zkiC<&Hq?hYULw~iIoa$YRB7{4<(Y5yUOCz7qo4T9r{qUAc5n-<6JSF$Fob4}h*qE^ z?u%Yoii!D=+o3AS1NFt#{rsY7U zL^Xc)Qdp1X>#vx-3vOGhyAuaHENeRw5A;1ToHiSe`doTaWJdP_)94yc*xwUhH8hx%*J=xf7v$O&+ErWsll;=hB<1`sVE! z`Q5JX475L$j2hlgI?yrUQqg0reBg}C3jfRJ6+PX#2XbU0t;$0xdi=38`;!I%?rC3J zF0P2o+|q28J@SR`&_wF~^1Gf^AP`$L$;1T9aJ1L~#+aF)G;~oYC_-HW*bQX`rF5&A zI*7I!a&63a(B$Jw#2oHF)^a%^3DJv9ZBed8Y0?f{37dNV*s^5T?W4jnwc?*S$)|2P znp&loD4}e+!!&m)oMCKVig>;Bm{Ga3r^u}I=)V4s#$D6zEp?veWSLrG;cqWS4br@M?zL4$F<8}e4e{1&1Rc?gwpK5 zbaX>Vx-9JNwdNPX2i>n*C@6UOiv?dg81Pv_P0B+o{q&SWshZVCgF)-rd!wCYO@eQO z`5`epPkgc*%(;78b32VAIA%_X?RvM;{27z3=#t`w7syuZCA3Y61({vls(8`VzP+u) z=lxfjXOh#wT&FSF=uf_V5%V!|6lL<6XG19@@#MTk9(Bg4&(kK7A2vi@J0B)kSIqX@ zMGRWQCvo<{;^pQASBI-&cM2Te1oJ`}6L+I7#yWPlFK6i)F+FNtN-r+vS>N9-eh`!a z_5IAm>jPU*p;;2JKXtXWLE~u@bsT}_O;iu1(1HCc2&88iO2^^-iA=CJ(U(Nkhs;;i zLck<~KEy@K7H&&7A^MRl!vl#s!|j~#;r@7C0>sdOS1%L|08ofb95|FhrZUi>`jAyz zG;q%n!yw>Q6Q;jD#MKrHHlYO)!ANzaIvi>iN(x3m40yqMfdn74qpA5f2;fN{;>Tpt z(J)v@NQiofraCRq7p9@Bs|$l8Uhuz)hcs7zcal*&+GL9Ahz5*heF5}iq+QNb)s zoHs3qsSkkwdhqx7D0ExfAMjMhHx>XsV4*lVOhX+GqflVKj$km&f&q|k0sZ3$h7+*O zhdB}%w4gvd(JYuqWh(p%LBRhQPY((tuTF=6hY`s{3Si0rylVW(CF{W8$A~|9WNB7| z{1x5;V~hP^&SK1$M4_)b0dn&vV7ecTNn`lY=s(Q=g#JVQHy2Ej&wmmTOY=8#!0$hM z_|EZa_<)tIE!vcZ4`R`PG1Z5#0!I^QcoG4Y8h~KZ*ctLL<`xZD|CeK4fjsPZb8}>T5?_`jEeM_f-e1x{N&DA5~-gd#OHQBYl!mJU=K zg@YsU-blQT7V6LF44Mx!1Q$p&_5~6Ha0RT;Rj$Cws}-m6XX_9@B9OQrglRcxpwI{n zG_dI4+TRIV?Zqq(zRw9bEF}a1%ltdk8bg0^Z0zGh0#Y9a#t8YOuZ(|J z*Z&$_yg#?_L@My_U3XU7|g5>$v zWqdata->streams.app_rx); + for(size_t i = 0; i < available; i++) { + char c = 0; + size_t len = furi_stream_buffer_receive(app->data->streams.app_rx, &c, 1, 100); + if(len > 0) { + furi_string_push_back(app->text_box_store, c); + } + } + if(available > 0) { + text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store)); + } + // Set input header stuff + size_t len = furi_string_size(app->text_box_store); + size_t idx = len - 2; + while(idx > 0) { + if(furi_string_get_char(app->text_box_store, idx) == '\n') { + idx++; + break; + } + idx--; + } + text_input_set_header_text(app->text_input, furi_string_get_cstr(app->text_box_store) + idx); + UNUSED(app); +} + +ViewPortInputCallback prev_input_callback; +volatile bool persistent_exit = false; +static void input_callback_wrapper(InputEvent* event, void* context) { + CliguiApp* app = context; + if(event->type == InputTypeLong && event->key == InputKeyBack) { + persistent_exit = false; + view_dispatcher_stop(app->view_dispatcher); + } + if(event->type == InputTypeLong && event->key == InputKeyOk) { + if(app->data->state == ViewConsoleOutput) { + persistent_exit = true; + view_dispatcher_stop(app->view_dispatcher); + } + } + if(app->data->state == ViewTextInput) { + text_input_input_handler(app, event); + } else { + console_output_input_handler(app, event); + } + prev_input_callback(event, app->view_dispatcher); +} + +int32_t cligui_main(void* p) { + UNUSED(p); + CliguiApp* cligui = malloc(sizeof(CliguiApp)); + cligui->data = malloc(sizeof(CliguiData)); + + latch_tx_handler(); + cligui->data->streams.app_tx = rx_stream; + cligui->data->streams.app_rx = tx_stream; + + cligui->gui = furi_record_open(RECORD_GUI); + cligui->view_dispatcher = view_dispatcher_alloc(); + cligui->view_dispatcher_i = (ViewDispatcher_internal*)(cligui->view_dispatcher); + prev_input_callback = + ((ViewPort_internal*)cligui->view_dispatcher_i->view_port)->input_callback; + view_port_input_callback_set( + cligui->view_dispatcher_i->view_port, input_callback_wrapper, cligui); + view_dispatcher_enable_queue(cligui->view_dispatcher); + view_dispatcher_set_event_callback_context(cligui->view_dispatcher, cligui); + view_dispatcher_set_custom_event_callback(cligui->view_dispatcher, cligui_custom_event_cb); + view_dispatcher_set_navigation_event_callback(cligui->view_dispatcher, cligui_back_event_cb); + view_dispatcher_set_tick_event_callback(cligui->view_dispatcher, cligui_tick_event_cb, 100); + + view_dispatcher_attach_to_gui( + cligui->view_dispatcher, cligui->gui, ViewDispatcherTypeFullscreen); + + view_dispatcher_send_to_front(cligui->view_dispatcher); + + cligui->text_box = text_box_alloc(); + view_dispatcher_add_view( + cligui->view_dispatcher, ViewConsoleOutput, text_box_get_view(cligui->text_box)); + cligui->text_box_store = furi_string_alloc(); + furi_string_reserve(cligui->text_box_store, TEXT_BOX_STORE_SIZE); + furi_string_set_char(cligui->text_box_store, 0, 0); + text_box_set_text(cligui->text_box, furi_string_get_cstr(cligui->text_box_store)); + text_box_set_focus(cligui->text_box, TextBoxFocusEnd); + + cligui->text_input = text_input_alloc(); + text_input_set_result_callback( + cligui->text_input, + text_input_result_callback, + cligui, + cligui->text_input_store, + TEXT_INPUT_STORE_SIZE, + true); + view_dispatcher_add_view( + cligui->view_dispatcher, ViewTextInput, text_input_get_view(cligui->text_input)); + + view_dispatcher_switch_to_view(cligui->view_dispatcher, ViewTextInput); + cligui->data->state = ViewTextInput; + + view_dispatcher_run(cligui->view_dispatcher); + + view_dispatcher_remove_view(cligui->view_dispatcher, ViewConsoleOutput); + view_dispatcher_remove_view(cligui->view_dispatcher, ViewTextInput); + text_box_free(cligui->text_box); + furi_string_free(cligui->text_box_store); + text_input_free(cligui->text_input); + view_dispatcher_free(cligui->view_dispatcher); + + unlatch_tx_handler(persistent_exit); + + furi_record_close(RECORD_GUI); + + free(cligui->data); + free(cligui); + + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/cligui_main_i.h b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/cligui_main_i.h new file mode 100644 index 000000000..b3b5823c9 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/cligui_main_i.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal_defs.h" + +#define TEXT_BOX_STORE_SIZE (4096) +#define TEXT_INPUT_STORE_SIZE (512) + +typedef enum { + ViewTextInput, + ViewConsoleOutput, +} CliguiState; + +typedef struct { + CliguiState state; + struct { + FuriStreamBuffer* app_tx; + FuriStreamBuffer* app_rx; + } streams; +} CliguiData; + +typedef struct { + CliguiData* data; + Gui* gui; + TextBox* text_box; + FuriString* text_box_store; + char text_input_store[TEXT_INPUT_STORE_SIZE + 1]; + TextInput* text_input; + ViewDispatcher* view_dispatcher; + ViewDispatcher_internal* view_dispatcher_i; +} CliguiApp; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/console_output.c b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/console_output.c new file mode 100644 index 000000000..933ee8431 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/console_output.c @@ -0,0 +1,13 @@ +#include "console_output.h" + +void console_output_input_handler(CliguiApp* app, InputEvent* event) { + if(event->type == InputTypeShort && (event->key == InputKeyOk || event->key == InputKeyLeft)) { + view_dispatcher_switch_to_view(app->view_dispatcher, ViewTextInput); + app->data->state = ViewTextInput; + } + if(event->type == InputTypeShort && event->key == InputKeyBack) { + char eot = 0x03; + furi_stream_buffer_send(app->data->streams.app_tx, &eot, 1, FuriWaitForever); + } + +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/console_output.h b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/console_output.h new file mode 100644 index 000000000..63e0d9afe --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/console_output.h @@ -0,0 +1,4 @@ +#pragma once +#include "cligui_main_i.h" + +extern void console_output_input_handler(CliguiApp*, InputEvent*); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/internal_defs.h b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/internal_defs.h new file mode 100644 index 000000000..cdb5f2fa9 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/internal_defs.h @@ -0,0 +1,118 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +typedef struct { + FuriThreadStdoutWriteCallback write_callback; + FuriString* buffer; +} FuriThreadStdout_internal; + +typedef struct { + bool is_service; + FuriThreadState state; + int32_t ret; + + FuriThreadCallback callback; + void* context; + + FuriThreadStateCallback state_callback; + void* state_context; + + char* name; + configSTACK_DEPTH_TYPE stack_size; + FuriThreadPriority priority; + + TaskHandle_t task_handle; + bool heap_trace_enabled; + size_t heap_size; + + FuriThreadStdout_internal output; +} FuriThread_internal; + +DICT_DEF2(ViewDict, uint32_t, M_DEFAULT_OPLIST, View*, M_PTR_OPLIST) +typedef struct { + FuriMessageQueue* queue; + Gui* gui; + ViewPort* view_port; + ViewDict_t views; + + View* current_view; + + View* ongoing_input_view; + uint8_t ongoing_input; + + ViewDispatcherCustomEventCallback custom_event_callback; + ViewDispatcherNavigationEventCallback navigation_event_callback; + ViewDispatcherTickEventCallback tick_event_callback; + uint32_t tick_period; + void* event_context; +} ViewDispatcher_internal; + +typedef struct { + Gui* gui; + bool is_enabled; + ViewPortOrientation orientation; + + uint8_t width; + uint8_t height; + + ViewPortDrawCallback draw_callback; + void* draw_callback_context; + + ViewPortInputCallback input_callback; + void* input_callback_context; +} ViewPort_internal; + +typedef struct { + FuriThreadId loader_thread; + + const void* application; + FuriThread* application_thread; + char* application_arguments; + + void* cli; + void* gui; + + void* view_dispatcher; + void* primary_menu; + void* plugins_menu; + void* debug_menu; + void* settings_menu; + + volatile uint8_t lock_count; + + void* pubsub; +} Loader_internal; + + +typedef struct { + CliCallback callback; + void* context; + uint32_t flags; +} CliCommand_internal; + +#define CLI_COMMANDS_TREE_RANK 4 +BPTREE_DEF2( + CliCommandTree_internal, + CLI_COMMANDS_TREE_RANK, + FuriString*, + FURI_STRING_OPLIST, + CliCommand_internal, + M_POD_OPLIST) + +#define M_OPL_CliCommandTree_internal_t() BPTREE_OPLIST(CliCommandTree_internal, M_POD_OPLIST) + +typedef struct { + CliCommandTree_internal_t commands; + void* mutex; + void* idle_sem; + void* last_line; + void* line; + void* session; + + size_t cursor_position; +} Cli_internal; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/text_input.c b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/text_input.c new file mode 100644 index 000000000..c5cc2ad39 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/text_input.c @@ -0,0 +1,33 @@ +#include "text_input.h" +#include "cligui_main_i.h" + +void text_input_result_callback(void* ctx) { + CliguiApp* app = ctx; + char* data = app->text_input_store; + size_t len = strlen(data); + for(size_t i = 0; i < len; i++) { + if(data[i] >= 0x41 && data[i] <= 0x5A) { + // Char is uppercase + data[i] += 0x20; + } + } + furi_stream_buffer_send(app->data->streams.app_tx, data, len, FuriWaitForever); + furi_stream_buffer_send(app->data->streams.app_tx, "\r\n", 2, FuriWaitForever); + data[0] = 0; + view_dispatcher_switch_to_view(app->view_dispatcher, ViewConsoleOutput); + app->data->state = ViewConsoleOutput; +} + +void text_input_input_handler(CliguiApp* app, InputEvent* event) { + if(event->type == InputTypeShort && event->key == InputKeyBack) { + // view_dispatcher_switch_to_view(app->view_dispatcher, ViewConsoleOutput); + // app->data->state = ViewConsoleOutput; + size_t len = strlen(app->text_input_store); + app->text_input_store[len] = ' '; + app->text_input_store[len + 1] = 0; + } + if(event->type == InputTypeLong && (event->key == InputKeyLeft || event->key == InputKeyRight)) { + view_dispatcher_switch_to_view(app->view_dispatcher, ViewConsoleOutput); + app->data->state = ViewConsoleOutput; + } +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/text_input.h b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/text_input.h new file mode 100644 index 000000000..77cc30efa --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/cli-bridge/text_input.h @@ -0,0 +1,5 @@ +#pragma once +#include "cligui_main_i.h" + +extern void text_input_result_callback(void* ctx); +extern void text_input_input_handler(CliguiApp*, InputEvent*); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/counter/README.md b/Applications/Official/DEV_FW/source/xMasterX/counter/README.md new file mode 100644 index 000000000..803c68634 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/counter/README.md @@ -0,0 +1,8 @@ +# Dolphin counter +This is a simple plugin for the [Flipper Zero](https://www.flipperzero.one). +It gives you access to a counter which you can increment and decrement using the up and down buttons respectively. + +![preview](https://github.com/Krulknul/dolphin-counter/blob/main/media/preview.gif) + +# How to install this? +I'd recommend using [flipperzero-ufbt](https://github.com/flipperdevices/flipperzero-ufbt), which is a lightweight tool for quickly testing Flipper Zero applications. The app will stay present on your device so it is not necessary to flash the entire firmware. diff --git a/Applications/Official/DEV_FW/source/xMasterX/counter/application.fam b/Applications/Official/DEV_FW/source/xMasterX/counter/application.fam new file mode 100644 index 000000000..f7b7f1e9a --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/counter/application.fam @@ -0,0 +1,12 @@ +App( + appid="counter", + name="Counter", + apptype=FlipperAppType.PLUGIN, + entry_point="counterapp", + requires=[ + "gui", + ], + fap_category="Misc_Extra", + fap_icon="icons/counter_icon.png", + fap_icon_assets="icons", +) \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/counter/counter.c b/Applications/Official/DEV_FW/source/xMasterX/counter/counter.c new file mode 100644 index 000000000..22fa8cd80 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/counter/counter.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include + +#define MAX_COUNT 99 +#define BOXTIME 2 +#define BOXWIDTH 30 +#define MIDDLE_X 64 - BOXWIDTH / 2 +#define MIDDLE_Y 32 - BOXWIDTH / 2 +#define OFFSET_Y 9 + +typedef struct { + FuriMessageQueue* input_queue; + ViewPort* view_port; + Gui* gui; + FuriMutex** mutex; + + int count; + bool pressed; + int boxtimer; +} Counter; + +void state_free(Counter* c) { + gui_remove_view_port(c->gui, c->view_port); + furi_record_close(RECORD_GUI); + view_port_free(c->view_port); + furi_message_queue_free(c->input_queue); + furi_mutex_free(c->mutex); + free(c); +} + +static void input_callback(InputEvent* input_event, void* ctx) { + Counter* c = ctx; + if(input_event->type == InputTypeShort) { + furi_message_queue_put(c->input_queue, input_event, 0); + } +} + +static void render_callback(Canvas* canvas, void* ctx) { + Counter* c = ctx; + furi_check(furi_mutex_acquire(c->mutex, FuriWaitForever) == FuriStatusOk); + canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned(canvas, 64, 10, AlignCenter, AlignCenter, "Counter :)"); + canvas_set_font(canvas, FontBigNumbers); + + char scount[5]; + if(c->pressed == true || c->boxtimer > 0) { + canvas_draw_rframe(canvas, MIDDLE_X, MIDDLE_Y + OFFSET_Y, BOXWIDTH, BOXWIDTH, 5); + canvas_draw_rframe( + canvas, MIDDLE_X - 1, MIDDLE_Y + OFFSET_Y - 1, BOXWIDTH + 2, BOXWIDTH + 2, 5); + canvas_draw_rframe( + canvas, MIDDLE_X - 2, MIDDLE_Y + OFFSET_Y - 2, BOXWIDTH + 4, BOXWIDTH + 4, 5); + c->pressed = false; + c->boxtimer--; + } else { + canvas_draw_rframe(canvas, MIDDLE_X, MIDDLE_Y + OFFSET_Y, BOXWIDTH, BOXWIDTH, 5); + } + snprintf(scount, sizeof(scount), "%d", c->count); + canvas_draw_str_aligned(canvas, 64, 32 + OFFSET_Y, AlignCenter, AlignCenter, scount); + furi_mutex_release(c->mutex); +} + +Counter* state_init() { + Counter* c = malloc(sizeof(Counter)); + c->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + c->view_port = view_port_alloc(); + c->gui = furi_record_open(RECORD_GUI); + c->mutex = furi_mutex_alloc(FuriMutexTypeNormal); + c->count = 0; + c->boxtimer = 0; + view_port_input_callback_set(c->view_port, input_callback, c); + view_port_draw_callback_set(c->view_port, render_callback, c); + gui_add_view_port(c->gui, c->view_port, GuiLayerFullscreen); + return c; +} + +int32_t counterapp(void) { + Counter* c = state_init(); + + while(1) { + InputEvent input; + while(furi_message_queue_get(c->input_queue, &input, FuriWaitForever) == FuriStatusOk) { + furi_check(furi_mutex_acquire(c->mutex, FuriWaitForever) == FuriStatusOk); + + if(input.key == InputKeyBack) { + furi_mutex_release(c->mutex); + state_free(c); + return 0; + } else if((input.key == InputKeyUp || input.key == InputKeyOk) && c->count < MAX_COUNT) { + c->pressed = true; + c->boxtimer = BOXTIME; + c->count++; + } else if(input.key == InputKeyDown && c->count != 0) { + c->pressed = true; + c->boxtimer = BOXTIME; + c->count--; + } + furi_mutex_release(c->mutex); + view_port_update(c->view_port); + } + } + state_free(c); + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/counter/icons/counter_icon.png b/Applications/Official/DEV_FW/source/xMasterX/counter/icons/counter_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4b8358b42f80a58a3e37f95e130f1bc423ad9fff GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>S?uZJ7@`qu z8{o;rY{pZ0NaD9(AaX|0?Oc=WtiM4b@)sd + +## Screenshots + +
+
+
+ +## Compiling + +1. Clone the [flipperzero-firmware](https://github.com/flipperdevices/flipperzero-firmware) repository or another firmware that you use. +2. Create a symbolic link in `applications_user` named **dice**, pointing to this repository. +3. Compile by command `./fbt fap_dice_app` +4. Copy `build/f7-firmware-D/.extapps/dice_app.fap` to **apps/Tools** on the SD card or by [qFlipper](https://flipperzero.one/update) app. diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/application.fam b/Applications/Official/DEV_FW/source/xMasterX/dice/application.fam new file mode 100644 index 000000000..6ff28f302 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/dice/application.fam @@ -0,0 +1,13 @@ +App( + appid="dice_app", + name="Dice", + apptype=FlipperAppType.PLUGIN, + entry_point="dice_tool_app", + cdefines=["APP_DICE"], + requires=["gui"], + stack_size=1 * 1024, + order=90, + fap_icon="icon.png", + fap_category="Games_Extra", + fap_icon_assets="assets", +) \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_1.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_1.png new file mode 100644 index 0000000000000000000000000000000000000000..6f56f964478a8ace0a501f031dc7f95547a7c6d5 GIT binary patch literal 539 zcmV+$0_6RPP)500001b5ch_0Itp) z=>Px$)k#D_R9Hu?m`iemFbqWF`yZMV)R+?O{>aQ^lLf|pYPBUX<2a7vZ}V@A(RyQd z>(PZlfOOFA`ZKx+Q#VBbrI1_ag0L|2u(|;Qn9tp_EAmfz6_A9%7o9@NK6uBNU^=Qy2zMEnEhvm_W~C0{m3>4B>s+dCA(%1=1|!ERJLPAvHh^xL-ZV-F z(@s;3EP1Hg8eA)oX_|A#a_z>jeXIi|EAPi&tvbVc5A#I=dJThzb<2OJHK>$PWiVCj zwtS-u21Y%zV_cQG1j$snE3ukqraG#oyiv=6T<56~VrSax_(}StPL^)c>i~TV@~{RQ z$mvK}K54ttAgkJLZlZ;(`h+SRE2QERQ~V!F?)}gg|=Xrhf<%ZRlGZX#Ggc1ajO%Z>hj&9S=DXBsEV6X dmAqBo{|8=Fy|#JGK~Dex002ovPDHLkV1g(E@5TTC literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_2.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_2.png new file mode 100644 index 0000000000000000000000000000000000000000..08c5872d92409cf7cefac8980d590943eaa35a58 GIT binary patch literal 535 zcmV+y0_gpTP)500001b5ch_0Itp) z=>Px$(Md!>R9Hvtmq`wTFbqY5Kp^1$R|PRwL3QOgo}gWH0jn0U^YT4~;y8{Y{K-{3 zFhV45DN_`MJFr)>zzstIJd0qP`2IZ4p{{FjBPI-Wh&^cvVOV(2+JFkfInm%aPyq1Q zi7-`Fg>Bmcb;j+EQwZC6RbpYNBJsZ@vGff4z`yr>4`o@NB2u3jOf-y1HciuMa0i5j zi&LrZ`!Ebc0>r{lW3CD~NGUJk{bgA~3_Z4^J`xxzEjZw6QB#b*pDp?hdzKD(9DtFv zkfjR1NJ)&tpC|<|R28i!SV>EhQ-Y6cBW@UvGKs|Z$Nnj~VoD-~s z)#7i#NJ$0vxh7?WM|v)mw_4g+heSsQoP1Y6DG0U|VXz|a9cCc~N1nXNdJ5UtxgI@s zVxx6k&#q~O%7W4QQZhs(7%54u>cR=jH9wk1Dh#MFj$>%s_8epsAP&){X_EWeB3yB> zYDr%QT&ZKIIJc||24g%jz}blAPBP)OPZc_=@P7-0hS@Xs+-G127dQOGzJU&9KY^hM z`3;QKk4$A~IJj!kl))7hPj+3`i4ndG!DNScOMw>obyi! Z`~nUKLbkrCS4;o^002ovPDHLkV1is#;U)k8 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_3.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_3.png new file mode 100644 index 0000000000000000000000000000000000000000..c757caa6695c5312daed96171c726a2722044a5d GIT binary patch literal 204 zcmeAS@N?(olHy`uVBq!ia0vp^${@_a1|;QfZjJ;}jKx9jP7LeL$-D$|+B{txLn7SY zPJ7GMpuppL`?vj5Q@DM$uO*UeC}z!)y<95re0zpUXO@geCwn C98iV; literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_4.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_4.png new file mode 100644 index 0000000000000000000000000000000000000000..508184d14b3aa917e5fc8421c6ba671d05a6b8e3 GIT binary patch literal 546 zcmV+-0^R+IP)500001b5ch_0Itp) z=>Px$+(|@1R9HvtSJ{q(FbqsMis1i$6%Yu-%BYFFj<2kE=t}JqDj^<^Cu1jG*L8&t z`Nc07p%VX_nHZy~u)oSsWoB8HFilgy08$|MPkK&hYeA`C5(p0f4VV{{2qtB&G2jJB zlalJ}2IJ8R4gx@FLO3xF5DNxp0?%#RhVwjcjU2~e3b^n4yoQ2;7gE^@FrI8QmLSl! zZDAOOLiq6Ax~^dyM;6d8FkBF<3w%oGT4`PSM%z2D!Rz&t)gy@yM@0K*+uOm&eB%ANw1fG1HGiKa41eqsT^;I!bll$?jb`CdMebwI+Jj_TL?!W#$$ST41rkQIGe~ z0BEt;qwP7OTyV)8)Bj+4(6`K^O*h9IB-fNYhIVVp9Q3N!>y_D;SS)%IOm_1;-}`wP zGTS)W3!3P@??tm@yEbeNBSX_PavwosXRThOF~Xc@BnNhNVbUn!8<>rxnMj@VJk3pV zTCTxLjO2u^8ztLamFtQoa?3K*+X09yodU{|CR%CmvV>lBqvUiV1+Z9PjnOKTmCcjy ktC)E*@RykyHb1INKOyjAwkz_P#sB~S07*qoM6N<$g37({+W-In literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_5.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_5.png new file mode 100644 index 0000000000000000000000000000000000000000..85831d239d67638a09a6aa78757bc2d3b2d160f7 GIT binary patch literal 530 zcmV+t0`2{YP)500001b5ch_0Itp) z=>Px$%t=H+R9HvNnCq^CFbsp&_kU<6(1KFePFyriJHL*gmoKrKhK=Jmj@Rbj7{i*e zyYz5j5TM&=cl;S$3zHW`0F|L?ToptK6Px7)7(l$Q-d&M@#aPf0f^h|e>vTW6Q`Q37wGOaT24v5NL1h}Y> zGgGA;qsSYfft9zIoYS5RhWVy4FCOhKd#J!YKVZ~=?%1*d*TF>1Imb==W*FyGD0z0~ zW|#>KVLB7DOg%Z?Oo_YB#DcqWsVFOX7kNIlio$#&KRq6u=#R}UCu;TIJbX=$WZO4M|5!M#8ow_g;6I%)farujI6S1!!RgEs-0^62F0Q0 UwhRtf7XSbN07*qoM6N<$f^nYiB>(^b literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_6.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_6.png new file mode 100644 index 0000000000000000000000000000000000000000..17cdbf1057ef6a657ec5fc8331ea661d991fd844 GIT binary patch literal 546 zcmV+-0^R+IP)500001b5ch_0Itp) z=>Px$+(|@1R9HvtSKF?HFbJ&o=>Pw!8jZ#iOlpu06y29S$?n^l7KUM9v^b9A2w(Cm zeqfYN{9k5@qHwG0jTB90)^!bS+XfE8lSG2{+@UJ7ZHj?;K#L)n_(>ru7!(8nlYP^Y zyY8aV*4W6gqp=d7Q{1Ym!nSQtdkHfU$iDBPEXzwT-oB$O6q5s@Gbr8-3|$(AA&ldA z#^gcJ|Cm@4tOOAObX^x{I1(m#o6u#Vw65y}m;}Nrm+f4Z<(f+E+-;h;PM$I%lOyfW zGb*fUnv)Tz%g9UwAc1IG&eIy}ZUl5IgurO5c*ap`Nh=2Bknv9eTVOm>qzM)6AkN5R zFxnXML>@37Gvjqd4;Ta?M>Zf=2@rs;h1({>PgQ9@_Et<8R_XuHEo;Bk6%|1lVEm2b}d kz`PRh8>&CK^Hpv71J|8gwlxgUJpcdz07*qoM6N<$g1OoHh5!Hn literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_7.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/coin_7.png new file mode 100644 index 0000000000000000000000000000000000000000..82f828a94e8d920e8959415a8d09bc69c8b18698 GIT binary patch literal 535 zcmV+y0_gpTP)500001b5ch_0Itp) z=>Px$(Md!>R9HvtSKF$CKnz@|DC+wAczP63z)^03xI(T zF*rpg7~Cj*yM`eP04R?k?N`A_j8MPK^X%d&%klv6dcD%Ru7|I<+%$*?1~v@Ckea5s z1b~eYa2&@}*Yz1#LdCtIv222oN|pxJs>z~>`iZZ*#OC9G(zq;30;=Jo(W@C!Gd_Zm z;$38t%9r+uoBK(B(U_s~pv*M6%QMQ1m(4|A0f;0a9vtaCH)d!VT0XG)g~y=UuaKEf zvcjd6fJ^e7%)ARm^8uHM8kqN;Fc`1ob0vMmjAlxnq1TSNR3;cor)DrN1ue^Wz?_w4 zl{U;DoG&>COTeTAZ+%Vbz`Q3+)0C>JQfE=*Mu*+pWL*LS2g5M5DuI@7wCB)uUDq8q zKXW!obI3a^@*ZX0w(Yo5NV2Q<8So0;L99Xf#JHOO+?yWX=#@Gxd2cY@#)kKg(mGsf zgnSg_u500001b5ch_0Itp) z=>Px%E=fc|R9HvNSV3}xFbrGZ|4#-wX4Z^QBqyOgluKD4wqnb&)8#zR^Yc%xZgHa2WmhdyRb6154Hf&(Z?{sEwQo@!ciaSO_juXf)<(Tdj8bi-;u1`y87_iYf!UW_ zvrHR`H;>4;2Ie?~m4uBldlZ9Y`%H%>Oq$V=Hd-zYx87cBY;D8Vqv8rJ)kco*+t{8Cm3jji%$zA~OSa_S+xkI3LA2M6nhC O0000500001b5ch_0Itp) z=>Px%BuPX;R9HvVm`jp_Knz1^xc`xXl&P2!LjFKDGug}(0rzWLmYa-y-}mW{e8w*@ zV+^^CxBGhxg8;TD1M#&dU~L$Nu$0&}Ukv~Ebonz~pcV`URi*K4sH{8zDq%R7XF&Z$ z0bw?}Kq(BDVO`g0S(ckWx!Rf16hEV4 zGSCgC3Ty$C9{jq}m@kT1c|Kc$SupB z8D(1Aw%xkN0q1$XX^^{5i8K;+nHdab5DpL-pK|3#nX}BG=qwwyDC$RnWTsY)2G-`O zHH5($vcq!CrB948Ie2H5v11?Il=(`hW$~V>oU*0A1NQ=he&B$(Q`Nd^WVlO5W*H7! zl^Jg7N|?4Nb{@~L%zrLbQJS&9xVs3(caH6D!FfjE^WGq+ms6h+3=hN1<}EM+sDa7a zV@VtvL(@|olIaNV_cHNhSGq}C8{0NgJMYYe%`V-A;kK3z9EnX$a}|)`s-wik+p4L} zM(Fx*m&WfAB%48zfws;wN_=Q;_Pqk}=c4ae60MUS!bE49O8l%#smN1ITYeEi;o?#x3mJC?GGzk-1n@c;k- literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d100_3.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d100_3.png new file mode 100644 index 0000000000000000000000000000000000000000..92d5a5c0c5c5241af4365a4b989614ef4206525f GIT binary patch literal 630 zcmV-+0*U>JP)500001b5ch_0Itp) z=>Px%FiAu~R9HvNnA>uLFbqTk{QoBd88MM(y}XHIAPCo6m91)CERPD( zeGD+s=(5A=cZ}G|x9@vv?&ch(@X0)i9_j^WM>V1XkHp;8B9xl21~VgE(PS}b1mq3w zWgC2YX0lpx^QsAn01y;m5UANxFiftL6vzI$F3DnJj1mB|g`I#gl?>au}?s4{~_ zXU5$d(49ud3RG$ae7-SEv=MSNnd;g%bT+F|4ThtM`iS?T=vaYrz_t}=%Z&e_5-%nD z)%0OzvMddOMWUBY80v=-M2uVso$8mz4#My>sl9~Xsj~?;J|n4|II66oN@oyA zfpCz~xhCDUBO@q=ymO=cBe>Eq?7bl~JOOARQ&M(RodEcIQ+RcWQzt#&Z`8h`GF6@a zWUoaxN>zIVnsJt$e`MLR>uod@s!up`m546Gu!dlBa+>)#p)#jR)9r&Z7k?%B*?Cqq za0Mc#Nu^KiGbrV%;nB_v$P$bySp@zK$TCb<-{5~UmC$7Ylo$V*=>KZX8+sof#rCpI QzW@LL07*qoM6N<$f(29@$N&HU literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d100_4.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d100_4.png new file mode 100644 index 0000000000000000000000000000000000000000..324b7f6332929d6efd21a50495339da417ff9a37 GIT binary patch literal 635 zcmV->0)+jEP)500001b5ch_0Itp) z=>Px%HAzH4R9HvNSV3~aKn!c(|4)W=oIxE$k?e&YT23S(yRvM_UbcPT_pg8Q***oc zZJQ0@H?h41Mgi2ue9v9KL;4b!wBh6N_`2P0EuaFk%GL;`fFR<;M1i{B?=fvyV`8ZV z!;82YVUV@a^Z7hL6}b8oYxTjq6GIVex zPB_J!qQuYzj8lxVGUYyjVbBiH3CyZ$cu^<{08ux%?&Pn4ESQvgrJaFrO)wy=l|1US z7aW)uo4%ufRV`W%alE9L(l2l~XnwU{~wN45sJOvE7x^YTV0sQP$ zU^)r9l(FMF_w54V6ki0xU>I@HjlQFc13=xc-+?73U3GDG=Lkj{S}Hz72IqCnlGjRL z>U{-&NIUf%c3UFqQl-RnnV@9LZc7R#|)vi6bG;5c) zHRGb_`iR!SRBy^6g5kmJ*sn9au9h4i*O|3fITlYoGcglQ>NN%GbCx?l)251jFJMx^ zO^wb)>UxxGA(z&}M-_EqJ9E5_C`r<*K(v?-GW6WkncZabZuDR&yYCFX9XqE{qEp;d zhnDqpqI4;9!xeiCt503pjSO0EOGgzud(iPVjS1XPRXNrur?a*jj=B+&*>g44sc$?{ zzT0D*n$)2apd~O0=%fHLzU0cTSU*aWZp=oN(xqlL86%!AGjpl@zy5z_HNsDS_YH2W VAH{?w500001b5ch_0Itp) z=>Px$+DSw~R9HvtSnZC&Fbvzq`#&<2TWFUZ4-0TH4zx&MUuc>`w$o&SPNCm zb-@%K)`Ny9*+A3`D2M7HI+xlPk08InW>~xma!4}(gYYOA$50Zj%P8LLZI~Dgr?>h8 zQ=UZ146(kP*k9|q^9-`6w35uKYrhk8Vy7(!suO4bobpM$&K8{UwN*QTi90hQR?l%E zZL>);N=*>N5Gho#I9WZDrReWcbx7lR1aE|I28LB~a zgWyuq-kVaGx=?AoacpwiFc@WrLAXU3d;*oODX})C-LND7WwDO6X)x-hcazUP|LnW= iEE^X|eE**b^!)%Ua*DR=dnq{p0000XP)500001b5ch_0Itp) z=>Px$%}GQ-R9HvtSJ{q(Kn&yf|4#;1K~3cvdot5yrLELHQI3qqu^pI?<2a^&@|(Y4 zOea2znR%Ws`}ixFmCPWR0HMGk+TQ>j0uzh27OQ}k&$ryvVkJT4Jw1$6EpIZzV6q(y zpjw1QXX}nIgGC*nZQG`0SR!hQf^ovF=qF~j0xFxd*;dHz?f zaZWmGjWXkQhGLXXfw96ZZ!&|$_!tYRP~;lSkL4vd;Nz0t4qA~nMr zK`^;1%o^V5CE_10V&SVPf3Y@;Hx|ZzN0A(as!ga1^Q>hYqL&tFE`S)O6(CAO8G?*b7$X%sWin^-TFidDlWcb-rL6OFzfw VfwmOS>_7kj002ovPDHLkV1lYq^B({J literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d10_3.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d10_3.png new file mode 100644 index 0000000000000000000000000000000000000000..ab67316c6bf228a286d4bac43914ba989d72f902 GIT binary patch literal 516 zcmV+f0{i`mP)500001b5ch_0Itp) z=>Px$zDYzuR9HvtR}G7UPz=-g|9`SNDs<$sqgWd^~hLr1{6Xj~8_m{`Q1;u$x~XMV4Mv;nGYQj79k1q1=%e8r+< z+krt=a$yBBm>7|BUDs(@mV-E+FJ;OIw{4pqkH@hPe=C+!mdZ;3BtHS@6qs08>3qh- z2_!%yJD0#H$q=Z`4k!-@z%g6O#0NTq;=E)a=H@rX(JPmj!L&`S(ag%&n9?{No=Zl4 z#Y}FRCg!xQvM43awfTHHwKK|*Omb<@V4OsU)Lds&v5E~M#hG4~k)y`(F0Cz?$`@|T z6-j;{EUOyRg5f&jOzirXW6oAk7 zaK#KZyErgCp^W}^HGuBzBziM&7eSY{?po39Yh^;(I*nEBQ5UjHU>FEz0grcJN3%#W zqYkUybzrMXuJ--d-&+N=GOw(_XW6-P{>PZP0`d#SvGxR)3yQWK%U#+40000500001b5ch_0Itp) z=>Px$zez+vR9HvtSj&=wFbqrJ|38_qrs++I9vB#c zEt$kRg9nW<+OjMMuWjAExAk>hKN4X^I2_YXG8lD`3lTrv;|K^kb{mX)>MZb~$c!-; zX@(u}EK3E??EpbUf^1{71|j57;XY39OgE=GgSx=)-}*s7&{L%;1jAwGswlxQrBSM8 z!gYZ^29s4zRZ}8%D&0*n!-w;xOcN^eRAwn5PirP)L@|J=&-Kgd(=-@NZ~MM&TUr34 z^hc0(hF{ZQxR{;d`r8Ur0aU{G=e(jDsM}z!v0}8>gh!qQpv4f{DYG4vXx+$4aHAnR<)(ijkY%=lQ z0>fTr<^M~y7`%L~O7AjEE<79+xJzf_0c*)wQQbRyJ5Uuj1Hne4XH($O>uq#+mFAgt zs)?^;M$yS3tHjIe(X=-OCNh?dkXHeI9DM(U2xxnmiS+aXi2jPUw;%>d00000NkvXX Hu0mjf26E=E literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d12_1.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d12_1.png new file mode 100644 index 0000000000000000000000000000000000000000..053ead3cd4c8dc937179c0d5e81fcb8ccfdf9e24 GIT binary patch literal 514 zcmV+d0{#7oP)500001b5ch_0Itp) z=>Px$yh%hsR9Hvdm%$FgFbqTK|9|w*CW?$_$LYoa!39LO^(Aqfb!^+VJ$~df{sv}@ zamwkPL@#9~ZJySX8rm>(BaVFkfB$cO zzLXi)o~KB{pk$|3?%dLhGdL$kHJ_^Ts*bW{!V;`>l!8^=C*fUdvsM(GnoqODGIE&k z^SZK3szbUCT7jrW;8|r`TfG{j&0O|wmFYzM>Y9|HYLv9xTA3ba03YOlIw0)Iu}o;) zEHWobB}Uhc{Cq25?hYnT9p%hYl_>g*vvyNtZ8Bpv)6PzTESlQY10h^q_` zBjwix=RFRj)QqKv7b@kbS0LJD>OifQ<93;<^nPpY3D38)ww52S^Z)<=07*qoM6N<$ Eg5l=t$^ZZW literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d12_2.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d12_2.png new file mode 100644 index 0000000000000000000000000000000000000000..752abaf33959cb8766bbb94d694cd591b5af6938 GIT binary patch literal 517 zcmV+g0{Z=lP)500001b5ch_0Itp) z=>Px$zez+vR9HvNSJ95cFbul<|3`P~be<>$*v&OJ6l^!&O~Xx~*Z#o(fD3)DwH| z-sF-U1xco~(38(EG4tfYU(d`7vct5tSkb==00000NkvXX Hu0mjfd86a8 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d12_3.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d12_3.png new file mode 100644 index 0000000000000000000000000000000000000000..711d1851423e72ad4aa1f7e082896eec39e93917 GIT binary patch literal 523 zcmV+m0`&cfP)500001b5ch_0Itp) z=>Px$#Ysd#R9HvNS3z>bFbt~y|LAnmsdoqgA-R|CX_Gh>LI^qQx~}W%pZwM-n6=h& zIUMhK`r-}5;W;Jyh#3W91HflfP$MuZ(0xwn3N$i!NJ}8d!0)BQ6^_<*cDDAa&s}h zl*r36rA~1|tN^JpzS!h4u_vV3Gw=yRI7)sJtOU%9Q){}8>Q4AlGcV-O4ctkSwYJQY zGP!_mLgRW@zK52Q&+vxM@|AbEca<|s&7k|Dm|ZXyaGFnS4J9*f0$bMvFL54{7_vU& z#y>NryvSv(ju(W>WdOLa{_k94s}{g$;9s_bx2ai$gP@2fnqd*NupMr zbOPix4m$N`f2q1HX@ujon87wpo>Dze-8TaB$|Rg|Q}91AGu?c;{u`ABx3)5uMP>j1 N002ovPDHLkV1g5%=s5rY literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d12_4.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d12_4.png new file mode 100644 index 0000000000000000000000000000000000000000..dff920c423b6fbce2ebccd5478a6355f7a3ed7ec GIT binary patch literal 493 zcmV500001b5ch_0Itp) z=>Px$r%6OXR9HvtSJ4u}FbK2%|Izd2$&O`7V7*O!&=dnqsmH6Z0Oaj{htvnIp(dc3`_3 zb>@nyUK)mm{pCG3M$_hrO2r2qq^b`yF0)4Kt=yB2zF~$a3N-AXVvB6}UOA znAv4{QrS{P-~H1u$Fyq~CPimvLx~txhHD*Ig*&^!jOsC6rR@N6jrL^+!7$;%9Kth9 zGgNuo@O_gRtkxYfs(&zMl=L%3SQXL+{E2F+v}PlLfw@v=l&Uk~n^xd6)x(A`n&7j& zsj4V7f@G~a=++%w+W}EUa%hyDnFWQ*b#pcex@oU9=_zX2jN&|Zav+&eUAUt+2qq`G zn;=UtnDMIHI`FysW0SRtFLS500001b5ch_0Itp) z=>Px$#Ysd#R9HvdSkaEcFbuo?|3?oE(aCtWlk8qj#|wzHjpNu!VI9YD{QQyE`d47q zS{JXsCHXNk2!gBp6x0}u0$$OkgXYlwg!5_ID?c^E1Am0lUB%oCV{A z$v~W5(mGeZ8yLsL&i)LJ8gc9(L%e1ua4RwP8O&yHz%pzg`#UZP9-j7D))g4cUS-J7 zl`vJAl&#Z^DU|pzkMQgjp zR+UKUh?}Egs_ZlDq-aMmC{v?US}Lurtj9r;#aWzJzz=v#ID&Dtb_0?FrTyyqQG($) zGO@hVigIJAnd&g5scB1S&!$^5`ZP9WbFO{5`ITkvTp>`XiZ#@XV~E$tR^Y&(oz+3E z?{M~<2s_Yfh6i2RSUJcsfoH~RXXgN>H)$mGAqMg$BK_93qaG%83aFkb5VFsx%{-aA z*Uu@Cl9?pF38=)zSB&XjB95tax9OI${CVpRQo&X4=mHs)X>#b(wJ$DA!nVi500001b5ch_0Itp) z=>Px$wn;=mR9HvtSV?ZfKn$z@|7aI3ItI<*qM$kSkX{OS(NGjc$vMvRJiq?Q-|+!s zDluZ_IF7dzvMHj1K_D*J^~`mT|E~-tF|KDLn8pZ#Yd{dJqj?O5S#dxa;C1l2w%)M} zyKb6LyV&@lIOs|-sMwLraNw40($ZoE%ZO|tsF%Q~fQov>QWE$rbS@JH=Y#lO(h(m% z(ay$TbBv-uF|l?1!SK?IW96at z-}bGx4vw4{Wk9!Prou&wXESpLE7OzgA~Pzu5~b@5ry)P8n@IxLf;G}*xW854|rit_HmPZ5g>Q1r_X)8k%u$#Qi@?CdL%yKI! z&ZacrHcx<+!L_)W{&6F4gHj!?%+BdWl`8?+#=)di%1ih?WGWfnCIPkSxeVGwSIMw; zTr!dw7m#Uh-ok#>4Ap{ZfF{FF`BiQA^m!YVKUlz<=`nlbPnF4-P~Ory2;=_wi;`E% y1}N=96^v_l#Z500001b5ch_0Itp) z=>Px$u}MThR9HvdSJ4i_Fc7l;|Isru)*yr9S`%aRNweAGIH2t~j^nuf$Y=Zom@$Us zbC>L8W)z57oS&_NYJ;hmI4Q!yyPzVN1cGPv38)gxDi8$bKvkoYU^*aBC+GL`KTbPJ z=?c^Z%!*6qy9@@4FRh0;Q#oZ8U<5MHTI&aM|Gj9G# zBMt;M!0aN+=d%kl2xh*_3o3>tOG?P9L8Y?@#ue!>RW-8&20@@UDhFY4wz>M<8q;Hb zkQ;2(wC5Zu8Gu0Us5T#ntncn^qj4nCk?k6umoKIg6^KRU${`#fp_JJ;Z-m=R}rIo@>FcJ6TJnF?@500001b5ch_0Itp) z=>Px$vPnciR9HvtSIcsPKn&~t|3}lI6K9N84^w)`p}8bsz$?qLY}Roc$Jd8^);}0g zi4ikvtv@MbQbYvPfmE=%cK$zq_v`FH7K3GX3(OfH0XpwVOe%&fn9e{y1Oc%u`+*4V z*I;@nT*i2SN~D0(a;nzGIx`?F`vPAjMNM@Uw*(Rx7F-3agZnqrnPP`(2D=3VGR>qi zDPdpOWy~W!cTRLs1qO|A zQc~t!R=})uDtl#&ZoqEt-c2t}SJX&cmR?I4OMtE-=)iYO&y|OXSIxOMFa<_UUo`}k zPVhP#4H8T@HdSx6IH{F_nI-LBHz;XcUpsHI{M2D%FfJ3f%Q#yY`ObM{OJoCfiuw*v=oVvZZL>0LXuGFvCuilDT1VQvDZ9>CV^KyYr|DNo%S-zbw- ukZSioj*rC5ox`5qJ7VVPA=BqS3d}d3vy8SI^*ogT0000500001b5ch_0Itp) z=>Px$GD$>1R9Hvtm*EP+Fbst4`#*H0U?4kl=_Q*WWB!sk*UvB4q>ee~eErF5JTRmZ zj~N!x`jIsEu|=;k)Pl(jc(AIWHcVtCyQVbxGK{yv$`j@3 zXD~`u7Em?RB{Pu~p9}W6y35Ki-bxfuGqTEp@7J{~)H2M@N|XsSvNKeI*;!#gK09_# zXjM7SbgbB-*mu$%rNS^PN|TGq)iRS=QOCfgFp-rAB+bKT!drgIW)v&_;h6z^RtpBZ zZPtC!41@Fi$L~P8wRby6DHH26tofxd%u2LvSzgdWd26%DjCJ#L_kDY?A>0000500001b5ch_0Itp) z=>Px$q)9|UR9Hvdm%)<5APhs7|NrQ8va@82kZhS;I@?R9gu;uElyq4oECl zrVLX@jV)`%-sH;Zz+^zmKZ`Q4G_g!ocqwJ({EpHOOcv?bi?DR>-x<6Mw7{^^R80}* zR)JStU)lkNSKKUS3U+6vNTww7+jFGTz*SW+&#>dcB(7S?QvL{|GGxL`08C&sEW$IN z#l5y;V%;~}Br3xa8E-&&@)>t>hBZUgn<~GsW1}!uN|FaDR47vH(om0KUshnU2W_RpBY@x?Uv8+2isRPl1 zQB_7w7~V3SM@`!^%0pP5(KA_aX6i2qTuoFJ5y!hqY&TmOSV2}v+qt>6XHFLH{-=D2 g>n`|a{#U_#00xg@wqrW?(f|Me07*qoM6N<$f=ag6aR2}S literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d4_3.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..8d1687ac805aac3fd89ec99dbcdc3abf9ea41a55 GIT binary patch literal 369 zcmV-%0gnEOP)500001b5ch_0Itp) z=>Px$D@jB_R9HvtSJ4i{AP77E|D#=8&V(ZrsIto*+~a1Xwxzh%d+(o@Jneu1N*rd8 zMYox0t|NaDUpGf{CS zc}u!UPgx!5l0DR2@Df!qwWHk0f}%a+rDz6}239f-sz5yshB3Nis#GS=n4Zzg?laLO z&UBw-k{XmuafT^(;;;T4FkrnqQ8*}>LX~T`e&Q;D+=>1VnX;e{7{t^CzDJ6ujA>500001b5ch_0Itp) z=>Px$kx4{BR9Hvdm*H*$F$jZ~_kZY{Zdxkp+1OlfQq}&dq6>Th1Iap$zz>D-ZP49 zKZRiq69?!-fy;I5GaU$?2FrS)8|tURxYIM3bFCUa|1%v$+CmsKzEA5?S4$Q9j)MCG z&R|Z%U6jyxb)JH3A5XRv3`Rs%K+<93gH6+885+f!xDvvU~2D3z^q>|N7bkTQC)hh8CO{y42l}7 z=-*-7Fh%&d&#>^;riVi8h9n!NQDks#xOT3pL-n3fHB}>Bc{&ZyOZV^7CaNY(gS;XV zqZoG9Fj<-({p-q257Sn|&fvSwEd}hZ4Or$ZO?7QD$$zBLy|udu&8lNEEUBK7hkpmf zZfs5~>Oy88afx9jTz7!Wk-?2jz|45}(7O$W37v^mrQ?<~O^r{#{{}+kxwfVJr0@U$ N002ovPDHLkV1nKB(500001b5ch_0Itp) z=>Px$ok>JNR9HvtS3#1)FbrD%|Iz8Bv+l?Q1abDz!}io^V;NyU&Nz3s^Fm*8&y35uCaIV`1Qx`Ho30qxL_539>ic(h?8Doqn zc3Los+FA_1Go_z(TodOy3P$Opf;$(pP1JAi&5B+aI}!|TJUi}aSE5GUA>dj20w!_L zqwX7aD45QMonD?gYXOspY_Z~RGA9{=>*#UUL7BJ&yJrndaigk(L=D4>o16}qfK@500001b5ch_0Itp) z=>Px$m`OxIR9HvdnBA_!APj@Y`#*H2PGWM6lQ?iQ?OdJ~@?qzPZd})Oy?*3x{0+<) zW6|_P=(aKn;3m2u@YxQO4U+}BpJDJ_s1nB6m|>=O&RX<2go!p%|DQ1P8C&E+Eif(w z24)yMZO6U`j5=9$+L^df0=M?WK7-yn(xM^=qbiA^B&33g)ZnJlfw|WzpofhS%zViy zX@<(GiPg7ZI7w%7!(f~mwO>yXoy-j-rHDN}*k80;{1`4LVh2mAcCscWOr^+^wjVO(lS1E>tx( zlo~cn)o=Lng;qHi`lWk!euZ!XIPWNHmuiY$a^}wogzUgBj8jeBy|$Iv3FNGK11B)K Uwj1xLM*si-07*qoM6N<$g0x%L*#H0l literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d6_4.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d6_4.png new file mode 100644 index 0000000000000000000000000000000000000000..ac7928e2c98a67bc3d17be6d3e31e96d8b1729b0 GIT binary patch literal 467 zcmV;^0WAKBP)500001b5ch_0Itp) z=>Px$jY&j7R9HvtSkVr`KnU~x|D$JShGAS=deaym=95O`N`ZFg*tTtZ{K;$FU`Qt{ zX2uvFH`1Ag7EAzfk}6T@096SbCIC1L z$$6@Furh!s)+q*U+SI1iRg9VG3aHz*f39poFltzlzBn5+t?;q_Q}NLz#)@M~ovxs* zL+rcyy!qL@W*MK74f#FjV@T6DE@6{=En2rB|@s45tGQ>Pm%CYqV*1o9_F$p(IU z@Iv>dj`k}8#~3>K76X&zy1uV-(`^abROoZ;Myc3Aw7Uzy9;_zUR#xAwth?&U120`w z9IIf;tcq&ExQr-(RjsKYcK<>+{^T&_6xH6f-GjancY|RpJ^`snhPKOJT15Z=002ov JPDHLkV1iv+%%cDR literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d8_1.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d8_1.png new file mode 100644 index 0000000000000000000000000000000000000000..b4c3b692ec6768938817e1dba587023e7c6bbbb1 GIT binary patch literal 457 zcmV;)0XF`LP)500001b5ch_0Itp) z=>Px$gGod|R9HvNm`f7EFbqS<{SRHH%!DzjWyx+Au;E+sq9{^e9mjFJ{^Yjqz^t_{ z)3`IYG0X;ugJ-XGM86Gl4t4^eN)v@fFqHxkstYuR*#l*RPl4JnQ5E%g`^8mg1QS(3 z180hDUnw)UV3-nn5T%q-s11{;azZ$-D}`(rrAkx>mx?{dWoyAOuf#9KZNF7>a>#;l zRjIs#;h6cyhH+Fug;*9vkNsSuic+b<0uD|6h%#)aoL^qGcIKT3)Lte>m0gnYUhS;W zGF7T5W#aqjw>FGY1!qqOfIzJJitZ*SRjaPSd~t#=g>h9;#mAP4)dGcK?dt$!pJDAT zbB3+|6y(xD!ABO1YS<}Qd1Pe?oCVqx0Iy@`nzEa!sCSfO4bCPdi!uYsJQcTcX4YzX zzL}+p5|0I0Xdy^el9rM#Oa@hLfBa#m&cB~b>cU_rRcDqe`ZM2*U@Dautg{nu!7x8{ z6=@sTnpyaZ#PP@_nJ1ocz$Tx0WSJ%dXV<&|Q>Xu@0G0=400000NkvXXu0mjfHe$ra literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d8_2.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d8_2.png new file mode 100644 index 0000000000000000000000000000000000000000..705416e49902c327c1de592f3032e762df351ca2 GIT binary patch literal 482 zcmV<80UiE{P)500001b5ch_0Itp) z=>Px$oJmAMR9HvNm(i}mFbqTK|9|w*5JAD%iQ5hYPZzG%o;Z%%jpI0u+n;>K6) zUf~}L1~&=?m@1WWU7WQrs^U}r43%55+O86&G9oi^1?Tuj!c_h^7golNR&>v^mQfhh zccq4^de%Q5Fx^xrGlyDuBwztmyWU`2A5>G6<&TVU4c)>pe_*!YWaaN!u?)u)k}wFt z+Q2Gi$|xXAXXzQNBCEmV&+vF&sgOiLF(rV2w;@oTRtZ&f^B_Sv<-^~lmRbxDh_wysAmg;8hDOl!71(~Z4j*6q<=-Nb$F Y4r^^(wo?Yv7ytkO07*qoM6N<$f<+$PmH+?% literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d8_3.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/d8_3.png new file mode 100644 index 0000000000000000000000000000000000000000..4c95fdcbf0b27cdcf5799c22f64155da3ce1b23e GIT binary patch literal 444 zcmV;t0Ym500001b5ch_0Itp) z=>Px$c1c7*R9HvNm(i}nAPhst|9>jSk7C+a{LW>yPg!ThS3YD%3D z28CHBN4n}z7?!HpQ_@ifRM)PmQ-(nyw~L|>+(u7%4IOPXIhsr< z<5ODsO&;w`u57cT=2-ELH1J-Xl{?dsGYNgmC$>#KZKIHrVfMS8s*WBS*f&5`RE^6m zj|{9P?~XGgr##awioT1Exa`_bg6z520g(5ZY^O#SEabW9BuW@|q*>~spi_$cq17)+ z)CfHYYXez`G>i>B-)F3!{C0M7NnXg=zB9$DYS;y(VUR*qgQ}BRg7H9Tn^eJQybKd5 mbOLhCt4`Btfy(!500001b5ch_0Itp) z=>Px$kx4{BR9HvNn86N%FbqT2|Nm$vCKW}-iJib zKFRKPfLbu@DO6-8q;!nPOQu-jq>3VW!2!)nQsN zl~1Z^os|kl1~d2XS}c=uA{K7hW?As1^9^CxYXSO$4Lvlq+wO6#QW@Nol_)bZJG}}% z3WE^VTp_QZEMKZQWp~pQFt&Y!qovMrrcxs-7d}%3XA1@sRGGK}R9-0)7;}Khi{Ter z9$Q_NN5WJ<-QcTCo3?h9AIylAI&7G-^;Y;00001b5ch_0Itp) z=>Px#mPtfGR5(w~lu-_VFbG58{)e8~NR?oz`!VX*G8nv;IXAOmAAe&6g1-raCQ7UO zL7pJ3;%0Zq2L!A?b6-JZXjIF!93fwt#gSouoY8e>LJV7%EHjUO9 zX6sb2Gd7G)IfGg`N5bU0qSSY>>~<9=VRpyVsjhdfb2g8*_WaGSz1)5Co!Na$;o_E)I!3HFqj;YoHDIHH2#}J9|(o>FH3<^BV2haYO z-y5_sM4;GPjq%Ck6>60csmUj6EiNa>ORduPH4*)h!w|e3sE@(Z)z4*}Q$iC10Gods AV*mgE literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_button_exit.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_button_exit.png new file mode 100644 index 0000000000000000000000000000000000000000..22f35791382668794bd6d9892677057109ad1fcd GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^%0SG;!3HGls-7o978Pp z&rW&B*Py`B^6;iu?pk;w>p0J?ZoHS!L{CoN0~R2Py2cKSV14qVGN$G KelF{r5}E*@*j5Mt literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_button_left.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_button_left.png new file mode 100644 index 0000000000000000000000000000000000000000..0b4655d43247083aa705620e9836ac415b42ca46 GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_button_right.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_button_right.png new file mode 100644 index 0000000000000000000000000000000000000000..8e1c74c1c0038ea55172f19ac875003fc80c2d06 GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_button_roll.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_button_roll.png new file mode 100644 index 0000000000000000000000000000000000000000..f20d7f5651b2232ec6609199cf8ea77f86b78b5f GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^%0SG;!3HGls-7_kj978Pp z?@qbRbwGi~`S$<+FZy~|HwCmBwi(4=sd|~2eP-3Fj*c@f+qbADa1<5#HtuV2vpRQ1 z;K)IP@)LY_E)I!3HFqj;YoHDIHH2#}J8d-yTOk1_O>mFaFD) zeWb+ZHz{mGZZ1QpXe09^4tcYT#4oe=UbmGC^A-KE*|F&zP#=S*tDnm{r-UX30HgpM AM*si- literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_count.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_count.png new file mode 100644 index 0000000000000000000000000000000000000000..a408de0253f5e9d6b8eb9f19960a2abba06b1ebb GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^av(Mb8<5;rbZ$OxrnOa1_>y{BCSXDH?uF})JQS8$Xt*l) z=I#Z@qi^1|VgIn?7k^3mW$m?{t-23<4y@WE^JnT-4t;j{|J_;rOS@F%)_=A77U}u& gRm82GB71)^bv;gg&)TQO0koUJ)78&qol`;+05<7LEdT%j literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_count_1.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_count_1.png new file mode 100644 index 0000000000000000000000000000000000000000..ec61bde963d9d278e27a82f8095a26c891c6eb4a GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^av(Mb8<5;rbZk44ofy`glX(f`Sa`ZPhDe0B z_Fd#+FyLVN`rrOnTeE_a+5J_)#tpfQzgAj!N4;!ex%DLL)W%y@Hs$6z%Osw4um8zV X%cTC}+S@)upcxFFu6{1-oD!Mn3#Xi2ED^|jLu^5O>*gg>*L~v3FPf%uMZC1)bG|3nvS|H# Zj2@xtKP0cS#RAP>@O1TaS?83{1OT=dDM$bS literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_result_3.png b/Applications/Official/DEV_FW/source/xMasterX/dice/assets/ui_result_3.png new file mode 100644 index 0000000000000000000000000000000000000000..8a23ac36d90ab6b04a4ac06f027d5d3d4a03ca2e GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^l0eMD!3HF&7fw+FQjEnx?oJHr&dIz4a;!aF978mM z*G}-{Vo=~=p8VgwO2sK(Y3+>SGUgj%3+`*gdrR$H?sG(V$26Cc=whRHAIev@s4S?y c$(_&mZIAj7<#qRfrZ6ygy85}Sb4q9e07T0uA^-pY literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/constants.h b/Applications/Official/DEV_FW/source/xMasterX/dice/constants.h new file mode 100644 index 000000000..f2fe03d31 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/dice/constants.h @@ -0,0 +1,116 @@ +#include +#include "dice_app_icons.h" + +#define TAG "DiceApp" + +#define DICE_TYPES 8 + +#define MAX_DICE_COUNT 10 +#define MAX_COIN_FRAMES 9 +#define MAX_DICE_FRAMES 4 + +#define DICE_X 45 +#define DICE_Y 6 +#define DICE_Y_T 0 + +#define DICE_GAP 44 + +#define SWIPE_DIST 11 + +const Icon* coin_heads_start[] = {&I_coin_1, &I_coin_2}; +const Icon* coin_heads_end[] = {&I_coin_7, &I_coin_1}; +const Icon* coin_tails_start[] = {&I_coin_5, &I_coin_6}; +const Icon* coin_tails_end[] = {&I_coin_4, &I_coin_5}; +const Icon* coin_frames[] = { + &I_coin_1, + &I_coin_2, + &I_coin_3, + &I_coin_4, + &I_coin_5, + &I_coin_6, + &I_coin_3, + &I_coin_7, + &I_coin_1, +}; + +const Icon* dice_frames[] = { + &I_d4_1, &I_d4_2, &I_d4_3, &I_d4_1, // d4 + &I_d6_1, &I_d6_2, &I_d6_3, &I_d6_4, // d6 + &I_d8_1, &I_d8_2, &I_d8_3, &I_d8_4, // d8 + &I_d10_1, &I_d10_2, &I_d10_3, &I_d10_4, // d10 + &I_d12_1, &I_d12_2, &I_d12_3, &I_d12_4, // d12 + &I_d20_1, &I_d20_2, &I_d20_3, &I_d20_4, // d20 + &I_d100_1, &I_d100_2, &I_d100_3, &I_d100_4, // d100 +}; + +typedef struct { + uint8_t type; + int x; + int y; + char* name; +} Dice; + +const uint8_t screen_pos[] = {}; + +static const Dice dice_types[] = { + {2, 0, 0, "Coin"}, + {4, 0, 0, "d4"}, + {6, 0, 0, "d6"}, + {8, 0, 0, "d8"}, + {10, 0, 0, "d10"}, + {12, 0, 0, "d12"}, + {20, 0, 0, "d20"}, + {100, 0, 0, "d100"}, +}; + +typedef enum { EventTypeTick, EventTypeKey } EventType; +typedef enum { SelectState, SwipeLeftState, SwipeRightState, AnimState, ResultState } AppState; + +typedef struct { + EventType type; + InputEvent input; +} AppEvent; + +typedef struct { + AppState app_state; + uint16_t roll_result; + uint8_t rolled_dices[MAX_DICE_COUNT]; + uint8_t anim_frame; + uint8_t dice_index; + uint8_t dice_count; + Dice dices[DICE_TYPES]; +} State; + +void init(State* const state) { + state->app_state = SelectState; + state->roll_result = 0; + state->dice_index = 0; + state->anim_frame = 0; + state->dice_count = 1; + + for(uint8_t i = 0; i < DICE_TYPES; i++) { + state->dices[i] = dice_types[i]; + state->dices[i].x = DICE_X + (i * DICE_GAP); + state->dices[i].y = i == 0 ? DICE_Y_T : DICE_Y; + } +} + +void coin_set_start(uint16_t type) { + if(type == 1) { + coin_frames[0] = coin_heads_start[0]; + coin_frames[1] = coin_heads_start[1]; + } else { + coin_frames[0] = coin_tails_start[0]; + coin_frames[1] = coin_tails_start[1]; + } +} + +void coin_set_end(uint16_t type) { + if(type == 1) { + coin_frames[MAX_COIN_FRAMES - 2] = coin_heads_end[0]; + coin_frames[MAX_COIN_FRAMES - 1] = coin_heads_end[1]; + } else { + coin_frames[MAX_COIN_FRAMES - 2] = coin_tails_end[0]; + coin_frames[MAX_COIN_FRAMES - 1] = coin_tails_end[1]; + } +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/dice_app.c b/Applications/Official/DEV_FW/source/xMasterX/dice/dice_app.c new file mode 100644 index 000000000..054e57999 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/dice/dice_app.c @@ -0,0 +1,267 @@ +#include +#include +#include +#include "constants.h" + +const Icon* draw_dice_frame; + +static void update(State* const state) { + if(state->app_state == SwipeLeftState) { + for(uint8_t i = 0; i < DICE_TYPES; i++) { + state->dices[i].x -= SWIPE_DIST; + state->dices[i].y = DICE_Y; + } + + if(state->dices[state->dice_index].x == DICE_X) { + state->app_state = SelectState; + state->dices[state->dice_index].y = DICE_Y_T; + } + + } else if(state->app_state == SwipeRightState) { + for(uint8_t i = 0; i < DICE_TYPES; i++) { + state->dices[i].x += SWIPE_DIST; + state->dices[i].y = DICE_Y; + } + + if(state->dices[state->dice_index].x == DICE_X) { + state->app_state = SelectState; + state->dices[state->dice_index].y = DICE_Y_T; + } + } else if(state->app_state == AnimState) { + state->anim_frame += 1; + + if(state->dice_index == 0) { + if(state->anim_frame == 3) coin_set_start(state->roll_result); // change coin anim + + if(state->anim_frame >= MAX_COIN_FRAMES) { + state->anim_frame = 0; + state->app_state = ResultState; + } + } else { + if(state->anim_frame >= MAX_DICE_FRAMES) { + state->anim_frame = 0; + state->app_state = ResultState; + } + } + } +} + +static void roll(State* const state) { + state->roll_result = 0; + + for(uint8_t i = 0; i < MAX_DICE_COUNT; i++) { + if(i < state->dice_count) { + state->rolled_dices[i] = (rand() % dice_types[state->dice_index].type) + 1; + state->roll_result += state->rolled_dices[i]; + } else { + state->rolled_dices[i] = 0; + } + } + + if(state->dice_index == 0) coin_set_end(state->roll_result); // change coin anim + + state->app_state = AnimState; +} + +static void draw_ui(const State* state, Canvas* canvas) { + canvas_set_font(canvas, FontSecondary); + + FuriString* count = furi_string_alloc(); + furi_string_printf(count, "%01d", state->dice_count); + + // dice name and arrows + if(state->app_state != SwipeLeftState && state->app_state != SwipeRightState) { + canvas_draw_str_aligned( + canvas, 63, 50, AlignCenter, AlignBottom, dice_types[state->dice_index].name); + + if(state->dice_index > 0) canvas_draw_icon(canvas, 45, 44, &I_ui_button_left); + if(state->dice_index < DICE_TYPES - 1) + canvas_draw_icon(canvas, 78, 44, &I_ui_button_right); + } + + // dice settings + if(state->dice_index == 0) + canvas_draw_icon(canvas, 48, 51, &I_ui_count_1); + else + canvas_draw_icon(canvas, 48, 51, &I_ui_count); + canvas_draw_str_aligned(canvas, 58, 61, AlignCenter, AlignBottom, furi_string_get_cstr(count)); + + // buttons + canvas_draw_icon(canvas, 92, 54, &I_ui_button_roll); + canvas_draw_icon(canvas, 0, 54, &I_ui_button_exit); + + furi_string_free(count); +} + +static void draw_dice(const State* state, Canvas* canvas) { + for(uint8_t i = 0; i < DICE_TYPES; i++) { + if(state->app_state == ResultState && state->dice_index == i && state->dice_index != 0) + continue; // draw results except coin + if(state->dices[i].x > 128 || state->dices[i].x < -35) continue; // outside the screen + + if(i == state->dice_index) { // draw dice with animation + if(i == 0) { // coin + draw_dice_frame = coin_frames[state->anim_frame]; + } else { // dices + draw_dice_frame = dice_frames[(i - 1) * MAX_DICE_FRAMES + state->anim_frame]; + } + } else { // draw first dice frame + if(i == 0) { // coin + draw_dice_frame = coin_frames[0]; + } else { // dices + draw_dice_frame = dice_frames[(i - 1) * MAX_DICE_FRAMES]; + } + } + + canvas_draw_icon(canvas, state->dices[i].x, state->dices[i].y, draw_dice_frame); + } +} + +static void draw_results(const State* state, Canvas* canvas) { + if(state->app_state != ResultState) return; + if(state->dice_index == 0) return; // skip for coin + + canvas_set_font(canvas, FontPrimary); + + FuriString* sum = furi_string_alloc(); + furi_string_printf(sum, "%01d", state->roll_result); + + // result text + canvas_draw_str_aligned(canvas, 64, 20, AlignCenter, AlignCenter, furi_string_get_cstr(sum)); + // ui frame + if(state->roll_result > 99) + canvas_draw_icon(canvas, 52, 26, &I_ui_result_3); + else if(state->roll_result > 9) + canvas_draw_icon(canvas, 56, 26, &I_ui_result_2); + else + canvas_draw_icon(canvas, 58, 26, &I_ui_result_1); + + furi_string_free(sum); +} + +static void draw_callback(Canvas* canvas, void* ctx) { + const State* state = acquire_mutex((ValueMutex*)ctx, 25); + if(state == NULL) { + return; + } + + canvas_clear(canvas); + + draw_ui(state, canvas); + draw_dice(state, canvas); + draw_results(state, canvas); + + release_mutex((ValueMutex*)ctx, state); +} + +static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { + furi_assert(event_queue); + + AppEvent event = {.type = EventTypeKey, .input = *input_event}; + furi_message_queue_put(event_queue, &event, FuriWaitForever); +} + +static void timer_callback(FuriMessageQueue* event_queue) { + furi_assert(event_queue); + + AppEvent event = {.type = EventTypeTick}; + furi_message_queue_put(event_queue, &event, 0); +} + +int32_t dice_tool_app(void* p) { + UNUSED(p); + + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(AppEvent)); + + FURI_LOG_E(TAG, ">>> Started...\r\n"); + State* state = malloc(sizeof(State)); + init(state); + + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, state, sizeof(State))) { + FURI_LOG_E(TAG, "cannot create mutex\r\n"); + free(state); + return 255; + } + + // Set callbacks + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, draw_callback, &state_mutex); + view_port_input_callback_set(view_port, input_callback, event_queue); + + FuriTimer* timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, event_queue); + furi_timer_start(timer, furi_kernel_get_tick_frequency() * 0.2); + + // Create GUI, register view port + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + AppEvent event; + for(bool processing = true; processing;) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); + State* state = (State*)acquire_mutex_block(&state_mutex); + + if(event_status == FuriStatusOk) { + // timer evetn + if(event.type == EventTypeTick) { + update(state); + } + // button events + if(event.type == EventTypeKey) { + if(event.input.type == InputTypePress) { + // lock input while animations + if(state->app_state == SelectState || state->app_state == ResultState) { + // input + if(event.input.key == InputKeyUp) { + if(state->dice_index != 0) { + state->dice_count += 1; + if(state->dice_count > MAX_DICE_COUNT) { + state->dice_count = MAX_DICE_COUNT; + } + } + } else if(event.input.key == InputKeyDown) { + state->dice_count -= 1; + if(state->dice_count < 1) { + state->dice_count = 1; + } + } else if(event.input.key == InputKeyRight) { + if(state->dice_index < DICE_TYPES - 1) { + state->dice_index += 1; + state->app_state = SwipeLeftState; + } + } else if(event.input.key == InputKeyLeft) { + if(state->dice_index > 0) { + state->dice_index -= 1; + state->app_state = SwipeRightState; + if(state->dice_index == 0) state->dice_count = 1; + } + } else if(event.input.key == InputKeyOk) { + roll(state); + } + } + // quit from app + if(event.input.key == InputKeyBack) { + processing = false; + } + } + } + } else { + FURI_LOG_D(TAG, "osMessageQueue: event timeout"); + } + + view_port_update(view_port); + release_mutex(&state_mutex, state); + } + + // Clear + free(state); + furi_timer_free(timer); + furi_message_queue_free(event_queue); + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + furi_record_close(RECORD_GUI); + view_port_free(view_port); + delete_mutex(&state_mutex); + + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/icon.png b/Applications/Official/DEV_FW/source/xMasterX/dice/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..840088565327533035cafbde39119b257c4b3cb5 GIT binary patch literal 128 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>vGR0r4ABTq z{`3F;|9Unh24x>bWo6~Crv}9bxE#9*BzYz?OEPbljbyfxc2(3{-ekhNq|@d1tQ!R^ Z45x&>KgkKWOaYq0;OXk;vd$@?2>{vvBaZ+8 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/sources/coin.pixil b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/coin.pixil new file mode 100644 index 000000000..838aeafc0 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/coin.pixil @@ -0,0 +1 @@ +{"application":"pixil","version":"2.6.1","website":"pixilart.com","author":"https://www.pixilart.com","contact":"support@pixilart.com","width":"35","height":"35","colors":{"default":["000000","ffffff","f44336","E91E63","9C27B0","673AB7","3F51B5","2196F3","03A9F4","00BCD4","009688","4CAF50","8BC34A","CDDC39","FFEB3B","FFC107","FF9800","FF5722","795548","9E9E9E","607D8B","ffebee","ffcdd2","ef9a9a","e57373","ef5350","e53935","d32f2f","c62828","b71c1c","ff8a80","ff5252","ff1744","d50000","fce4ec","f8bbd0","f48fb1","f06292","ec407a","e91e63","d81b60","c2185b","ad1457","880e4f","ff80ab","ff4081","f50057","c51162","f3e5f5","e1bee7","ce93d8","ba68c8","ab47bc","9c27b0","8e24aa","7b1fa2","6a1b9a","4a148c","ea80fc","e040fb","d500f9","aa00ff","ede7f6","d1c4e9","b39ddb","9575cd","7e57c2","673ab7","5e35b1","512da8","4527a0","311b92","b388ff","7c4dff","651fff","6200ea","e8eaf6","c5cae9","9fa8da","7986cb","5c6bc0","3f51b5","3949ab","303f9f","283593","1a237e","8c9eff","536dfe","3d5afe","304ffe","e3f2fd","bbdefb","90caf9","64b5f6","42a5f5","2196f3","1e88e5","1976d2","1565c0","0d47a1","82b1ff","448aff","2979ff","2962ff","e1f5fe","b3e5fc","81d4fa","4fc3f7","29b6f6","03a9f4","039be5","0288d1","0277bd","01579b","80d8ff","40c4ff","00b0ff","0091ea","e0f7fa","b2ebf2","80deea","4dd0e1","26c6da","00bcd4","00acc1","0097a7","00838f","006064","84ffff","18ffff","00e5ff","00b8d4","e0f2f1","b2dfdb","80cbc4","4db6ac","26a69a","009688","00897b","00796b","00695c","004d40","a7ffeb","64ffda","1de9b6","00bfa5","e8f5e9","c8e6c9","a5d6a7","81c784","66bb6a","4caf50","43a047","388e3c","2e7d32","1b5e20","b9f6ca","69f0ae","00e676","00c853","f1f8e9","dcedc8","c5e1a5","aed581","9ccc65","8bc34a","7cb342","689f38","558b2f","33691e","ccff90","b2ff59","76ff03","64dd17","f9fbe7","f0f4c3","e6ee9c","dce775","d4e157","cddc39","c0ca33","afb42b","9e9d24","827717","f4ff81","eeff41","c6ff00","aeea00","fffde7","fff9c4","fff59d","fff176","ffee58","ffeb3b","fdd835","fbc02d","f9a825","f57f17","ffff8d","ffff00","ffea00","ffd600","fff8e1","ffecb3","ffe082","ffd54f","ffca28","ffc107","ffb300","ffa000","ff8f00","ff6f00","ffe57f","ffd740","ffc400","ffab00","fff3e0","ffe0b2","ffcc80","ffb74d","ffa726","ff9800","fb8c00","f57c00","ef6c00","e65100","ffd180","ffab40","ff9100","ff6d00","fbe9e7","ffccbc","ffab91","ff8a65","ff7043","ff5722","f4511e","e64a19","d84315","bf360c","ff9e80","ff6e40","ff3d00","dd2c00","efebe9","d7ccc8","bcaaa4","a1887f","8d6e63","795548","6d4c41","5d4037","4e342e","3e2723","fafafa","f5f5f5","eeeeee","e0e0e0","bdbdbd","9e9e9e","757575","616161","424242","212121","eceff1","cfd8dc","b0bec5","90a4ae","78909c","607d8b","546e7a","455a64","37474f","263238"],"simple":["ffffff","d4d4d4","a1a1a1","787878","545454","303030","000000","edc5c5","e68383","ff0000","de2424","ad3636","823737","592b2b","f5d2ee","eb8dd7","f700b9","bf1f97","9c277f","732761","4f2445","e2bcf7","bf79e8","9d00ff","8330ba","6d3096","502c69","351b47","c5c3f0","736feb","0905f7","2e2eb0","2d2d80","252554","090936","c7e2ed","6ac3e6","00bbff","279ac4","347c96","2d5b6b","103947","bbf0d9","6febb3","00ff88","2eb878","349166","2b694c","0c3d25","c2edc0","76ed70","0dff00","36c72c","408c3b","315c2e","144511","d6edbb","b5eb73","8cff00","89c93a","6f8f44","4b632a","2a400c","f1f2bf","eef069","ffff00","baba30","91913f","5e5e2b","3b3b09","ffdeb8","f2ae61","ff8400","c48037","85623d","573e25","3d2309","fcbbae","ff8066","ff2b00","cc553d","9c5b4e","61372e","36130b"],"common":["000000","FFFFFF","7F7F7F","a1a1a1","C3C3C3","c40424","880015","B97A57","dba88c","ED1C24","f75b63","f26f9b","FF7F27","f7ab79","FFC90E","FFF200","cfc532","EFE4B0","1ee656","0c6624","22B14C","B5E61D","5487ff","00A2E8","99D9EA","3F48CC","7f86e3","7092BE","720899","cd55cf","A349A4","C8BFE7","ffffff"],"skin tones":["ffe0bd","ffdbac","ffcd94","eac086","e0ac69","f1c27d","ffad60","c68642","8d5524","896347","765339","613D24","4C2D17","391E0B","351606","2D1304","180A01","090300"]},"frames":[{"name":"","speed":100,"layers":[{"id":0,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAFlJREFUWEft1MEJACAMBEGv/6IvFeRxhoDC+hYMm0HZ9nnkiGGaTVCmI0oZyqTfF2Ywg5m0AGbSYvwzYzOS1iuuP5C4YZixmST37V3WxJpSO5jBDGbSAl+YKXbCj5ghLqGvAAAAAElFTkSuQmCC","edit":false,"name":"Layer 1","opacity":"1","active":true,"unqid":"zdzpbp","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":1,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAf5JREFUWEftVkFywjAMVAZooP//apukScYdq7ariJXsAAcO4UICtrxerVbq6I0+3RthoQOMlY1nmAkNKd4Vf9fidLgEkffH36znjDn+/0lE369gJoPYHBpCCF3XUQiBuvhA8fH/WYGMOEwCWpiRIO4Y2AmGwVqAamDyRvTdIJmyRIJ4CAxipOhlnucqmMvlwiBOpxOt65pTpNO9QYyChmEY6Ha76QD8Po5juF6v+baterRYdsGgkpXptKrJY0qKXq8rsZFm+LBYEcuyUKKaf0pR9B5LA1D4XGqRXi48/phgSoBcJeIaFvA9RcCHW7HRLbNnuJ5glChKYWYV+pNkx6K8UJ9u8SgrmdicHdcYkTBdYxItAbKq1IlaRAGY9FKk8UowUuQ6xUjkstT/NC1uYtm+vIlZll5dO/qSXtUExhKlpruC564nucxI1VsjgU5FreIkQJ0q7ch37XyTqth/zuczNKgaDeB/dMGNkdZKlgNM0xT6vvd6Uc34aJ7nkBunMYjBQScC+CGivrGM9UDlkSbZ+UqTn9ubpC48n/D0oAGVdKzryiOFdF74oiIsRBR36Y7L744zIyCWhWzW1nKNOnWt1LUvofEBnlsDA11VsIJmHwYjhnKUdqirFjCWA7fs1Sx+pOJ4GowWbKvVtIDmWM0LW09+Zt0BxmLvYMZi5hdntuIk2wS1xwAAAABJRU5ErkJggg==","edit":false,"name":"Layer 2 Copy","opacity":"1","active":true,"unqid":"","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":2,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAmlJREFUWEelWOt6qDAIs+//0O5rV1hIA9Rz9mdOsYQQLm48//bzXr42Lu2W2RfjAOB9azxjHEe3vlqD53ncKwMQDleEjV3qswOzgODhCoA9r56tNPyxJf1WYAIQdETgjjPebaDeqQBlYCSQTieZWA2AYDD4V2CugIxMMBuRsWMAbwBJMFUE00kHxAAIWxWoY2AwboyRoPMEjKrzwbb7b6841s8BBlmBa7cjB6razNYAhnetqoj9ZSPBcH73AYrFdQ/1IVK4Hs/7XGX7vuNAByFFXfnuZhjAFOmcZzsYZAdTFcB8SNE6HIVKTc2jBZ0wcG+mG1AYIEZnaOlJtAGMpUpVWQXGunsLxmg1B5TvtD9R47OKYqbm+1y5mhkUXAYm6SHmxH+DnevGxDwZQREfmgGD0CfUvGHdUFN2jeyADp1dgdlUc9PCxtZNe88WMwNpvEsTCMtzyxpCbVQjgsBgb8O0/RYjIk1KW4nPq/rrtlj5uAGD7PCWkI2JbJvwZm16gf6UM2OpglFw9BZuesnYWOPCRAzV0zc9c0DIefh5Y8SZA++mS5uBEatsZIbYCA6RBSjVLB1c1nbWZIjP9eme7jOQSw84afu8y1Q6yvbqeoXgbU98fvDED4HdrJ3VCrEChx7DAuNPFtTR/wDx1iEHXqF4zzeWJDdALALQ2rokzTiQcAEHhi9IrCqhIwUuiJqrBgPdhk5INWPCfoOVpiIndgIg/piz/YVLsQSDFPNnUvdBp+zVVEdAN9PXGRIUZ33G72OTyxgJvaM5UWqIZ0s2ACuNfEkT26bCroDBIW0WWgPB2u1/rb6wv2x/ACDUeEL6Qq7OAAAAAElFTkSuQmCC","edit":false,"name":"Background","opacity":"1","active":false,"unqid":"u6oba5","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":3,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAfZJREFUWEftVl1vgzAMNCoM2P//qxtQiDw5JZkxdj5YH6qpeULCdu7OziUNvNBqXggL/AswWKFoMeHiQACQAEpyeQ7FfwDA3SJypSAgIjZNQ7mmQogIewztHeKS++XAaEUkW4uozM3mpcBsAHADiEN+KM7U4cw5sFCb8vg+pkoWGI1VKlb7x2vEb+cc3m7E0a9DnlWEhqzfEyQzzt7/I5V85cccycXz+fcXAHxyQEXJy7Jg3/cyVgNpzQWu6wpd14WhV1uobRDk8wXati1hnLMdbW74afQ4LLap1oSBtYiUDDGvEfeypvwKGHmqZO0U8cfIMRpy+muY17ZJKlMMJmdWORUD0OzclChjmZbqFQmJqsCoQ7U7be3GZ7M5epG3Jna/maeJLkIKtE4bB5ZroSZUNErmkcnNvKsKQ9VaGj1JsQnNiX28Vdu8U0idbduCa/Jjm3NtUw1f5Lddp9anLjjNvFJeYinB2629fyIG8yaepgnGceRtiEzmecZhGLida2rk3P1kCRYY2ZaQGJnRvZVb4WKkJ4NzThI77Z0Cox31E6gcoP0/v61Nk8yBsRSKQMPJ4L6hecj+DpZPiAOXEjAhQX39VYLRvCsCqgEjQclToj2YpCnSy+7bau0VMBqop9T/C5jC2S0Pe4N5Sk/LBb8W+W6TpdsPAVbkJHCu0MYAAAAASUVORK5CYII=","edit":false,"name":"Layer 2","opacity":"1","active":false,"unqid":"","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":4,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAKFJREFUWEftVVsKwCAMa+9/6I4Oiw/cap2Cg+zHQWuaJXEyHfTwQVwIZJ7cgDJQJnpSkRlkBpmJKjCSGVkFOonD5dEWkcyHuaq5+Lo5sqcclkb1yViRiJSdEq7WNJiMvPa/vVu9Xe0Lt5BJytzES8KfyCjjiOSuh50G16YZ0IV7YiFdOLgLhYty5Ke32wUXHzbBJjckTQMyg8wgM1EFfpGZCziRWCSDveGOAAAAAElFTkSuQmCC","edit":false,"name":"Layer 4","opacity":"1","active":false,"unqid":"","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":5,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAfhJREFUWEftl91uwjAMhR21HbC9/6sOOkCZ0tWVe+q/VprEBVyh4iZfju3jUOiFPuWFWOgNY2XjiDI1kdoj64Zp+iSibyKSALxRe2Z9Z95dUFEwQ6w2rbXWUqZHhb/XWqn8PUTIKS6hphvEi24U2AnDgCGUR4wwmVqRAkiVtINtxLJgZHpq13X0fD6nk93v9xBqGAYPylRIg9EUwTgPqNxut3o+n2V6GKBer1e6XC4qUGYTWbyySxDIiuN3tAOs9ldhWmdM6HPLQIdkGgMBpn1aivu+b+uqrS9hFnJoU5RUdpd2atd7vLU3MIZfyE2t1KLHtHdU8HmPjToIs5gYG5pIl6XIZg3Io/fe6jcsOu10Vo1EIwLfW9nF7Morh49gcBxoYNaM8mKlfSw1mYGJ5koW5uWUwUZQ0yQrXys4z1v2KINtrxYwwyy2DWPfAsTnZlxr58fjQfPcUie55hkr+uaawzBYXRZafPOacRzpdDrhGhtwDabd7L7mvIQnb3cbGB2eFfB+IxF94KXLmtrTlaHrOlXOLKigwrpKTW11wDmbowrs4JplcF22i1Gvyed5iOWw6qlABW0qhwYaGRp2GYn7r1UbljrRIcJbeyuyH+OvSuQ98vfMoUMYa9h5IFqKMvG7YVKLHg1KyXd08b3vvWHMNtwr5X/G/wLO/uskz2jgOQAAAABJRU5ErkJggg==","edit":false,"name":"Layer 2 Copy Copy","opacity":"1","active":false,"unqid":"","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":6,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAkBJREFUWEetl1t2wyAMRO39L9o9pkgZDSMJ2vQrTQRcRk/u629/z+aye9NumJ0YB4DnqXnue9m6Pas1uK7LT2UAceC4YWOXntnBDBDcXAHY79Vvww0fteS5FUwAwYMIbtnjmQZqTQWUwUiQBKKNJQMQCobzFUwLMiW3ta/98tnUsWzaAZIwzQ3w8J3MZViPwQnoDAzjquBN7o+jx4Xh/xLmNZ62A2j+7xnH8bPAoCrw+bXDDXGdKjit4qT+sJcwiX+34ysrppxlU2XnWG5oBl36QjEc8kNQZwq+seIqvhcGmN/l4HS3NUPKmrEZxg8GDMRSCHBa40B0hoahwPXMnJUYYQKLSm+xJkuQGmZu7rckV3AWyVqTXMBsGWx1E/jSM8g2RbcJl6kiyK4dW2GaYxAvMVPBFPXlWBmrOS3M9EFQpim1xzCWjVswnHbfDGCMR6jKZ6mdqGO1Q8bMEukwXnAVPqozGzAMtizBKrwNgxNe0xjb3oSZx80SJkDtJjNQjTILZCr1WR/zzi1G2QhDamCr93j48ghhGbtUYCtIPPyElmBFq0n1qlWo/esRgqc98fz499hZjRBBGdFV+cmCMKiEjxQu6YwGHty6Sc/bUDFAo8zpMwWyxGMPv2NVxm/C9+EFiQrxAbb25BFHlT0wZO+mRSHMNJZfVNnwFT/m+FXAGaKSY1EopMjhw79SZAcGvDCeJzyzbmU3ztSZIkcwGBsIlTxrQh3ZUeQExlkUlAV1BgbyVfE5zFqDKtu2/HRwxg9BIkRCZQ/enQAAAABJRU5ErkJggg==","edit":false,"name":"Background Copy","opacity":"1","active":false,"unqid":"u6oba5","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":7,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAfpJREFUWEftV9tugzAMdQQM2P7/VwcUUKakJHKMHZuqk3hon6piHx8f36iDG33cjbjAh4xUjavK+AtlvYqtlukLAB4AgElYglDSFh+VTBAiAUdA7713rortDptkZE6khsqBFMSEkknBVV+JDOcYfsP2XP9IqmCVdgBouUQ4MjHIvu/QNE14rmZkaGqciIhHyQTDXwD4OQJwahQ+Qg9hJbjvCwCE4SiwODKF87quvuu6pJCoJAI+JbAsC/R9TzGoHdsDXOCTI1IufKW9dErSew/btkHXdcn+VC4ORApMW0PaJRb/ZFPY0l3ASUkz5/qVNqhWTkwm41vIWLanhUxaoDjholQWMrdRxrBCoolVmYRXLVMGRHsjbtMoy/MWWbc118DSvmIbOB/EEN89o6sLT9jOml/MER3bnCR7awghrIrlPnEq5jVQwT5JH52O6iSFaE9Y++j0+hG2edu2rCrVDFBEOnFUqWRas8PEcDLV2yTtAu6GSQq5eZ79MAz44ucTME0TjOPIDoRlQnzTNPGVIkxUkFqr03F/sGLsKFOc2nal90MlQcDppq1d/uh6hYy4i8KYCivBpAhtOkl5euYjOF2MChkt6RxbO4Lfx5sfLlHx8nUg0XNgTbYQQSPDKWbpnVdwTf+btOF52/OXMnhbdGb8/gv7Mu5HGUmyP5KE6CQNV8vwAAAAAElFTkSuQmCC","edit":false,"name":"Layer 2 Copy","opacity":"1","active":false,"unqid":"","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}}],"active":true,"selectedLayer":1,"unqid":"rs6rne","preview":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAdFJREFUWEftV9uqg0AMXKko6v//quL9ECESY25r+1AO7UuL7mYnM5NkW+z7vqcv+RQ/MIoS/4OZoihcp+XaMZsZCgIPg2fab0QM7/u+T23bqkmEwSCICAALmMWWC4aCsBiIgqQxOEUmGNwofbuGIQsAKI8h7VfBSIxQv8zz7OIpy/IA8Xq90rquh6+43DSICAY2DMOQmqa5BICNEHAcx1TX9RlYQsW9obFsgpFKlgbWqsmiifqJr7vE5uOA0rgsSwKq4aPRqxlSMz6CkeJdZJLKl/aJm/tJf9GYofKgzDS5yzPKjJfNRV8BiCQhHhzpPTdmaBlaPrD6hceg2q+QmU+ywqWVgEvyncy8C0bzAZeJGpj3nTAYr+RzJX3EjGZKnqHXjrlUJhhKp2YwLgUty3fAnJVmlTbMH5wvOQdLwKQEb31N6sC8J0zTlKqqUmdR5EaH3dxkXQIDB8MwtCqBlm+059B1XdcdNz9zNklzyDss8h5l3rbtuFJIsqv3GfAK3kGsQfnEuJr/3Jse3+iVOi15bzDexob3j9I6XGqEfBTksOpeyHmm0mGaVDwRrEp1vceM1jM8r+SAPhN+AiYKJHddWKbcwE/W/8B81MBPJIjs+QPyMEG2lHD1VgAAAABJRU5ErkJggg==","width":"35","height":"35"}],"currentFrame":0,"name":"Untitled","preview":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMA/sfR5H8Fkddasdmnacvx//8745jkhasdASD945kjknhj/AAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAdFJREFUWEftV9uqg0AMXKko6v//quL9ECESY25r+1AO7UuL7mYnM5NkW+z7vqcv+RQ/MIoS/4OZoihcp+XaMZsZCgIPg2fab0QM7/u+T23bqkmEwSCICAALmMWWC4aCsBiIgqQxOEUmGNwofbuGIQsAKI8h7VfBSIxQv8zz7OIpy/IA8Xq90rquh6+43DSICAY2DMOQmqa5BICNEHAcx1TX9RlYQsW9obFsgpFKlgbWqsmiifqJr7vE5uOA0rgsSwKq4aPRqxlSMz6CkeJdZJLKl/aJm/tJf9GYofKgzDS5yzPKjJfNRV8BiCQhHhzpPTdmaBlaPrD6hceg2q+QmU+ywqWVgEvyncy8C0bzAZeJGpj3nTAYr+RzJX3EjGZKnqHXjrlUJhhKp2YwLgUty3fAnJVmlTbMH5wvOQdLwKQEb31N6sC8J0zTlKqqUmdR5EaH3dxkXQIDB8MwtCqBlm+059B1XdcdNz9zNklzyDss8h5l3rbtuFJIsqv3GfAK3kGsQfnEuJr/3Jse3+iVOi15bzDexob3j9I6XGqEfBTksOpeyHmm0mGaVDwRrEp1vceM1jM8r+SAPhN+AiYKJHddWKbcwE/W/8B81MBPJIjs+QPyMEG2lHD1VgAAAABJRU5ErkJggg==","palette_id":false} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d10.pixil b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d10.pixil new file mode 100644 index 000000000..3356c453c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d10.pixil @@ -0,0 +1 @@ +{"application":"pixil","version":"2.6.1","website":"pixilart.com","author":"https://www.pixilart.com","contact":"support@pixilart.com","width":"35","height":"35","colors":{"default":["000000","ffffff","f44336","E91E63","9C27B0","673AB7","3F51B5","2196F3","03A9F4","00BCD4","009688","4CAF50","8BC34A","CDDC39","FFEB3B","FFC107","FF9800","FF5722","795548","9E9E9E","607D8B","ffebee","ffcdd2","ef9a9a","e57373","ef5350","e53935","d32f2f","c62828","b71c1c","ff8a80","ff5252","ff1744","d50000","fce4ec","f8bbd0","f48fb1","f06292","ec407a","e91e63","d81b60","c2185b","ad1457","880e4f","ff80ab","ff4081","f50057","c51162","f3e5f5","e1bee7","ce93d8","ba68c8","ab47bc","9c27b0","8e24aa","7b1fa2","6a1b9a","4a148c","ea80fc","e040fb","d500f9","aa00ff","ede7f6","d1c4e9","b39ddb","9575cd","7e57c2","673ab7","5e35b1","512da8","4527a0","311b92","b388ff","7c4dff","651fff","6200ea","e8eaf6","c5cae9","9fa8da","7986cb","5c6bc0","3f51b5","3949ab","303f9f","283593","1a237e","8c9eff","536dfe","3d5afe","304ffe","e3f2fd","bbdefb","90caf9","64b5f6","42a5f5","2196f3","1e88e5","1976d2","1565c0","0d47a1","82b1ff","448aff","2979ff","2962ff","e1f5fe","b3e5fc","81d4fa","4fc3f7","29b6f6","03a9f4","039be5","0288d1","0277bd","01579b","80d8ff","40c4ff","00b0ff","0091ea","e0f7fa","b2ebf2","80deea","4dd0e1","26c6da","00bcd4","00acc1","0097a7","00838f","006064","84ffff","18ffff","00e5ff","00b8d4","e0f2f1","b2dfdb","80cbc4","4db6ac","26a69a","009688","00897b","00796b","00695c","004d40","a7ffeb","64ffda","1de9b6","00bfa5","e8f5e9","c8e6c9","a5d6a7","81c784","66bb6a","4caf50","43a047","388e3c","2e7d32","1b5e20","b9f6ca","69f0ae","00e676","00c853","f1f8e9","dcedc8","c5e1a5","aed581","9ccc65","8bc34a","7cb342","689f38","558b2f","33691e","ccff90","b2ff59","76ff03","64dd17","f9fbe7","f0f4c3","e6ee9c","dce775","d4e157","cddc39","c0ca33","afb42b","9e9d24","827717","f4ff81","eeff41","c6ff00","aeea00","fffde7","fff9c4","fff59d","fff176","ffee58","ffeb3b","fdd835","fbc02d","f9a825","f57f17","ffff8d","ffff00","ffea00","ffd600","fff8e1","ffecb3","ffe082","ffd54f","ffca28","ffc107","ffb300","ffa000","ff8f00","ff6f00","ffe57f","ffd740","ffc400","ffab00","fff3e0","ffe0b2","ffcc80","ffb74d","ffa726","ff9800","fb8c00","f57c00","ef6c00","e65100","ffd180","ffab40","ff9100","ff6d00","fbe9e7","ffccbc","ffab91","ff8a65","ff7043","ff5722","f4511e","e64a19","d84315","bf360c","ff9e80","ff6e40","ff3d00","dd2c00","efebe9","d7ccc8","bcaaa4","a1887f","8d6e63","795548","6d4c41","5d4037","4e342e","3e2723","fafafa","f5f5f5","eeeeee","e0e0e0","bdbdbd","9e9e9e","757575","616161","424242","212121","eceff1","cfd8dc","b0bec5","90a4ae","78909c","607d8b","546e7a","455a64","37474f","263238"],"simple":["ffffff","d4d4d4","a1a1a1","787878","545454","303030","000000","edc5c5","e68383","ff0000","de2424","ad3636","823737","592b2b","f5d2ee","eb8dd7","f700b9","bf1f97","9c277f","732761","4f2445","e2bcf7","bf79e8","9d00ff","8330ba","6d3096","502c69","351b47","c5c3f0","736feb","0905f7","2e2eb0","2d2d80","252554","090936","c7e2ed","6ac3e6","00bbff","279ac4","347c96","2d5b6b","103947","bbf0d9","6febb3","00ff88","2eb878","349166","2b694c","0c3d25","c2edc0","76ed70","0dff00","36c72c","408c3b","315c2e","144511","d6edbb","b5eb73","8cff00","89c93a","6f8f44","4b632a","2a400c","f1f2bf","eef069","ffff00","baba30","91913f","5e5e2b","3b3b09","ffdeb8","f2ae61","ff8400","c48037","85623d","573e25","3d2309","fcbbae","ff8066","ff2b00","cc553d","9c5b4e","61372e","36130b"],"common":["000000","FFFFFF","7F7F7F","a1a1a1","C3C3C3","c40424","880015","B97A57","dba88c","ED1C24","f75b63","f26f9b","FF7F27","f7ab79","FFC90E","FFF200","cfc532","EFE4B0","1ee656","0c6624","22B14C","B5E61D","5487ff","00A2E8","99D9EA","3F48CC","7f86e3","7092BE","720899","cd55cf","A349A4","C8BFE7","ffffff"],"skin tones":["ffe0bd","ffdbac","ffcd94","eac086","e0ac69","f1c27d","ffad60","c68642","8d5524","896347","765339","613D24","4C2D17","391E0B","351606","2D1304","180A01","090300"]},"frames":[{"name":"","speed":100,"layers":[{"id":0,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAEpJREFUWEft1MENACAIADHZf2kn8HE/TOoE5KjMWfRm0SzHMK9tKKNM/anMMMNMLcBMLebOMMNMLcBMLebOMMNMLcBMLebOfGHmAm5UACTjh/FnAAAAAElFTkSuQmCC","edit":false,"name":"Background","opacity":"1","active":true,"unqid":"vbd6q","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":1,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAhVJREFUWEftV9GOwjAMW7f//+R2p+Sa4npJ2wEPCIF04hgjcRzHzdJ5nuf2Ia/0AxN04ruZSSlNFRjJNGRmJWiU1UuG8W6BWfmhAZF7Jbi9y/X0H0Bng4pq171CXGY8Viiw9UJsQRPQuyKxOMbErMgLGPtBznk7jqMrYJV+LylcC9lxwQgQezEgRDcCZ9+VUqQoZTLnfO773rUU44VgBISBGgHi3iNA0w7co/lQX1Mw9Qalk9sVTkIdadCHaUk1bbq6DQYB4P+SyP4kAzDWKpbrVezeRD3HjAUspWifvYnw9EMj3m7B8V9uU/WJ5h0iQANDE+HI5eErkhzF+1SbDIy1xwGDHtO8r7ZH1xH2FwKFt3YFhabH4w2m18A4Rtg2EgRUwWhi/A0PwxCMeQIFYWbQgbuqPQdG7S2D8aqowdn+sVUXZiKT9EQ8PLWZUgCjWKt/UL5exA0prBZ8sLZ7orUTT2NkSbQk7atC7VoWgG9aQXFbzKEDYyVecAODVs8epJ9L2VI9k0xI7EFLmuEKIgGHq8EDCD55XKZwGYxH6Wg18E5p2nM0JC9d3cE6elTh5NGy5DDUnVW8gEXjPXw6GG1mEbDq3O6J/1ZmeEw9Rmjk2/hjB6IibzGzopluVFPq4ke79dRnPLPyvIGSdwef9yFazlTds2ftSMRR1lGyGdJbYCzYKwlHgKZgZtW88/sfmIjNj2LmD0cIcLZmv4arAAAAAElFTkSuQmCC","edit":false,"name":"Layer 1","opacity":"1","active":false,"unqid":"syuab","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":2,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAjJJREFUWEfVl9u2gyAMRKX+/yerXaEMaxgSQHseevpSeyHsJDNB0/ZDr/RDLNv/gbmu64oql1L680SGAQ3G23PAmNmfgt6CMYhZQWagI9gQBi3SzUebzUANxFuPSg5hOLhWBUHpPznWRGedBEvcvPYWDCIBwAHizZrYDOkk+Rym9D1vrEDHcWz7vgPE3GjXcGU6juN6vV5Ve48rE1VEgCoItRZATSst3hTGE68G1org83meTWVEaxmKv1uC8VxUvmtaoLMoQ53nlj6t4qHZVYwSijWDDZwMNtNE6XktvVZSgKCtPEC5olyV0E0rMDS8cvZe29Q1LHys4WndWZuz9CpD46C6tQTkz43TAohGvG5lWAMDGLUsYnVAPHh4+qqThjCkjZqlI+AKEVSsm0W3NIPKGAxe+76jpJxAN9DK/zvrFrtrUuttKpN0s0DmHpkzWX/UAm/QsairNtkceoK75wf1cwSjh15UkeY4EKc2+3cwPPLtmisDV8j5U1z6KZTMkgqCysr7HIbFi3ZhLlgwa5vnEk2EDskIag3GRGvB7JQt193sYKDgEE1yXCjUOgwcxTAqFEc4tV3lN96w6kqPgm7ORLaOAIJbyG628E3cIwGzVgAz2hyagoh1DYwguhq3SYNp0OCmu7ldiO51HF3FMPCod9qOtMJ25mTkxqqG8PTSaYYHxspjxxMtoZ3eg577dDB63Ji5aSWJ5crMNhv9fieJ5cp8A/TN2vAh7pugT9f+FMwbzj9NQl0XLG4AAAAASUVORK5CYII=","edit":false,"name":"Layer 2","opacity":"1","active":false,"unqid":"n3umw","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":3,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAj5JREFUWEfNVwGOwyAMK93/n8yYwhHOMQnQ3k7qpGnayoLjOCak40Gv9CAsx/PBlFLKLmMppa8l5AYSMDt7XMA85OYlsQXG23QHbMSuxmNAKzDyvJdMgjQQSUsp3/X3FVOYQPuP2X8AwyWCLGqiFESAKmD8rEth/UCSx84MTGeFAekm8snZ8q5czpzz8Xq9vMTG1lZmBMD7/ZY/VsA553KeZw2iG1zVkgDRlwDiUoXMwEJs864VZmVlBQpEQCg7d8GgkI14sWSzEkF5TPmxo7aZ4U7CUrWAlUFlQJ7rW39XrdxlpretZo1i9oSN7OBz0d95npVVJ5EfLTK1KGDI2IiYgrlxuLUbmMGTwjKhkSHQWSdBMCP0lmQNKeAVTFSiISOHwhpTAkhbc0urGzsGp4x3MKu2DsHMdEE66ZuCE2PcDka7rnnX4DFLMJGXOIC4RP2YgC40zbA8m0i8XdvotBviVSCNjH64TsU71QyamXPa4tmioGvJtAmoHGa9x8qyTDAedAsoOZcjFnONKYD+BMabT6C97flEgBwWh25iM5xOekFbmzOptfDyFI/KSqAHw/2lv9l00Cne4daHJ+y6YBgzzRAN8QMYRc+GRoddElfGIckD1JUNF4hIvEbA0bjZNmFzq5jR6DxGvgZGA5HHmOGKN4vG09UgbrwB/QFVv3Mdmd0I+P/eEG72wy/Ufu6tUsRHp3sUwp2FZjfQ21fT1RXYY3Um3sGBwxQvPpgB/RdmLuLbWn67TFvRLy56FJgPoS1QQmVa3RoAAAAASUVORK5CYII=","edit":false,"name":"Layer 3","opacity":"1","active":false,"unqid":"syuab","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":4,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAiVJREFUWEfdl9uOwyAMRHP5/09OUxkxaBhsQ6OtVO0+dUuCj8djQ/fth/72H2LZ/j/Mfd93pPi+76EAj5XJAhqIF9MYH8HMgkUBWZEavH21DOMFTxTtAiQl6ZZQvUidViaDiaRdqH/xCAVTNZbUCWHYg04mg0EVRN5/DmMbvV6v7TxPg0VgfC4JXNd1n+dZgmQg6q3MN4MyTl0NpoCQIfFesxpK7IFx+T+CQaZ1g6aMgpgyx3EUZQIQTUBVHMZKpww29hQgE+/3dd3bcXSzhDKGkjWvMluGrvI6qnsKHcVSq6wKImUtILZP9VzxEytnn6NSuTBIY9aqznoBsff/DMabnACM/AEI8tpQJuwbDb+0TNkZQ2vc/uXrOg4GAzsl6+IveWbSMUUBggCQq4yUbw4j7W0DbrM2ViNWAMCoKh2M7YE/G5aeiQdlpL3d1ndmEQO5ypgilpBBLcEgFWm/dhxg0CUKdfOEpzZgMhMPU5BnDUG1ZuKukdZue+Hc4nWFIXXbe1OYSpF2iNd1FtySgYpcnsjEIYxAsOHCw1FrxMdAhSlJRb5ZUYafCS9RCqL/o5vMvE9hOpDZvSUakgCbtXdaJlyy9KoA82lwvt01x8uJDVWWDZxMXPeeK9O3Vcg7aLHonU+DMjxrnKExXKR4SM58M7vxLcGsyD8D4fWlU5skdH+2eEp9AsHPTm96DLMaJPu5urpHM/unL3zzedcz3wyY7f1TMG9hxkxC7RN4kQAAAABJRU5ErkJggg==","edit":false,"name":"Layer 4","opacity":"1","active":true,"unqid":"n3umw","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}}],"active":true,"selectedLayer":4,"unqid":"rbcl7d","preview":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAiVJREFUWEfdl9uOwyAMRHP5/09OUxkxaBhsQ6OtVO0+dUuCj8djQ/fth/72H2LZ/j/Mfd93pPi+76EAj5XJAhqIF9MYH8HMgkUBWZEavH21DOMFTxTtAiQl6ZZQvUidViaDiaRdqH/xCAVTNZbUCWHYg04mg0EVRN5/DmMbvV6v7TxPg0VgfC4JXNd1n+dZgmQg6q3MN4MyTl0NpoCQIfFesxpK7IFx+T+CQaZ1g6aMgpgyx3EUZQIQTUBVHMZKpww29hQgE+/3dd3bcXSzhDKGkjWvMluGrvI6qnsKHcVSq6wKImUtILZP9VzxEytnn6NSuTBIY9aqznoBsff/DMabnACM/AEI8tpQJuwbDb+0TNkZQ2vc/uXrOg4GAzsl6+IveWbSMUUBggCQq4yUbw4j7W0DbrM2ViNWAMCoKh2M7YE/G5aeiQdlpL3d1ndmEQO5ypgilpBBLcEgFWm/dhxg0CUKdfOEpzZgMhMPU5BnDUG1ZuKukdZue+Hc4nWFIXXbe1OYSpF2iNd1FtySgYpcnsjEIYxAsOHCw1FrxMdAhSlJRb5ZUYafCS9RCqL/o5vMvE9hOpDZvSUakgCbtXdaJlyy9KoA82lwvt01x8uJDVWWDZxMXPeeK9O3Vcg7aLHonU+DMjxrnKExXKR4SM58M7vxLcGsyD8D4fWlU5skdH+2eEp9AsHPTm96DLMaJPu5urpHM/unL3zzedcz3wyY7f1TMG9hxkxC7RN4kQAAAABJRU5ErkJggg==","width":"35","height":"35","old_width":"35","old_height":"35"}],"currentFrame":0,"name":"Untitled","preview":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMA/sfR5H8Fkddasdmnacvx//8745jkhasdASD945kjknhj/AAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAn9JREFUWEfNmFGOwyAMRCG5y+b+x0nvQlmZYjQMNmSjrpT+VGkbPDyPbdIYQvgJIbye8B7D5/UIQSLmEUJEx7+QyTnnSnx4izG6AG6TmQUUBZ+Y/Us0xhgPz6MumZzz6e1OP7cC4j01ePuoXq/JWDtdBZMok4wMdPS3XqoaGSHhoZ3kX5EXj0AwpsHXZqoaMiGDYnDHxk6GFLIQuv9SqkwystD7/Q77vssONLD8VgiUDaSUzn3fS5CZEDbzzMQDGVgYU1CEgCH1vtMTopT/YmKXTF2skWEhQmbbtkIGA8M1b4ApDlXVkdGFLAJg4iOndIZt66oFyralUlLMZDStVr/p+oyaGNFzjlkIlWsRIutUzxU/ccq8ftOh4vJelarxfREiu78gZihvl8ykzK0KOrRjg9fkWIKmb5SMIinD2iTj9Qj1DRHB8pef6HV5t9IEvuniX/LMpGKG8q+C2+cshtLXpcr1DC6SUgpSxkbvaP2miugaI5KRNfQlzdIy8UCGyrspJ09glbAgTVXnGSEiGxJRIMYnIybC8q4zSQ9Khza6CSE+SzfPqBglbpl4OM9oeeNNUFld1ZCRW8pTSll3r6RZjGXioSUTGU0zemEoVx6G2mdkE7oRTI9nYpcMVEWZ2tCJ3eEII6ObWXJRxZRyJ980IFfIoMmaMIsGi8FrrSZJn2filWc6Iatzy0rgqrxdMpoaNR4H8ubWLFWQrjZScHqbZCYd1zznwgjotFiCjZHie0aOlLPDOR+ksEnOPGOR5bP1QAYbH+8Cg115jPHEXZra+qTnkeHFcbqvqBhemp9n9E+A1aMrERqK4O6fCV9b6K4AvM/0zDcWvvMH1KPI/AIAOS/9S+9jJwAAAABJRU5ErkJggg==","palette_id":false} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d100.pixil b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d100.pixil new file mode 100644 index 000000000..c4fd81342 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d100.pixil @@ -0,0 +1 @@ +{"application":"pixil","version":"2.6.1","website":"pixilart.com","author":"https://www.pixilart.com","contact":"support@pixilart.com","width":"35","height":"35","colors":{"default":["000000","ffffff","f44336","E91E63","9C27B0","673AB7","3F51B5","2196F3","03A9F4","00BCD4","009688","4CAF50","8BC34A","CDDC39","FFEB3B","FFC107","FF9800","FF5722","795548","9E9E9E","607D8B","ffebee","ffcdd2","ef9a9a","e57373","ef5350","e53935","d32f2f","c62828","b71c1c","ff8a80","ff5252","ff1744","d50000","fce4ec","f8bbd0","f48fb1","f06292","ec407a","e91e63","d81b60","c2185b","ad1457","880e4f","ff80ab","ff4081","f50057","c51162","f3e5f5","e1bee7","ce93d8","ba68c8","ab47bc","9c27b0","8e24aa","7b1fa2","6a1b9a","4a148c","ea80fc","e040fb","d500f9","aa00ff","ede7f6","d1c4e9","b39ddb","9575cd","7e57c2","673ab7","5e35b1","512da8","4527a0","311b92","b388ff","7c4dff","651fff","6200ea","e8eaf6","c5cae9","9fa8da","7986cb","5c6bc0","3f51b5","3949ab","303f9f","283593","1a237e","8c9eff","536dfe","3d5afe","304ffe","e3f2fd","bbdefb","90caf9","64b5f6","42a5f5","2196f3","1e88e5","1976d2","1565c0","0d47a1","82b1ff","448aff","2979ff","2962ff","e1f5fe","b3e5fc","81d4fa","4fc3f7","29b6f6","03a9f4","039be5","0288d1","0277bd","01579b","80d8ff","40c4ff","00b0ff","0091ea","e0f7fa","b2ebf2","80deea","4dd0e1","26c6da","00bcd4","00acc1","0097a7","00838f","006064","84ffff","18ffff","00e5ff","00b8d4","e0f2f1","b2dfdb","80cbc4","4db6ac","26a69a","009688","00897b","00796b","00695c","004d40","a7ffeb","64ffda","1de9b6","00bfa5","e8f5e9","c8e6c9","a5d6a7","81c784","66bb6a","4caf50","43a047","388e3c","2e7d32","1b5e20","b9f6ca","69f0ae","00e676","00c853","f1f8e9","dcedc8","c5e1a5","aed581","9ccc65","8bc34a","7cb342","689f38","558b2f","33691e","ccff90","b2ff59","76ff03","64dd17","f9fbe7","f0f4c3","e6ee9c","dce775","d4e157","cddc39","c0ca33","afb42b","9e9d24","827717","f4ff81","eeff41","c6ff00","aeea00","fffde7","fff9c4","fff59d","fff176","ffee58","ffeb3b","fdd835","fbc02d","f9a825","f57f17","ffff8d","ffff00","ffea00","ffd600","fff8e1","ffecb3","ffe082","ffd54f","ffca28","ffc107","ffb300","ffa000","ff8f00","ff6f00","ffe57f","ffd740","ffc400","ffab00","fff3e0","ffe0b2","ffcc80","ffb74d","ffa726","ff9800","fb8c00","f57c00","ef6c00","e65100","ffd180","ffab40","ff9100","ff6d00","fbe9e7","ffccbc","ffab91","ff8a65","ff7043","ff5722","f4511e","e64a19","d84315","bf360c","ff9e80","ff6e40","ff3d00","dd2c00","efebe9","d7ccc8","bcaaa4","a1887f","8d6e63","795548","6d4c41","5d4037","4e342e","3e2723","fafafa","f5f5f5","eeeeee","e0e0e0","bdbdbd","9e9e9e","757575","616161","424242","212121","eceff1","cfd8dc","b0bec5","90a4ae","78909c","607d8b","546e7a","455a64","37474f","263238"],"simple":["ffffff","d4d4d4","a1a1a1","787878","545454","303030","000000","edc5c5","e68383","ff0000","de2424","ad3636","823737","592b2b","f5d2ee","eb8dd7","f700b9","bf1f97","9c277f","732761","4f2445","e2bcf7","bf79e8","9d00ff","8330ba","6d3096","502c69","351b47","c5c3f0","736feb","0905f7","2e2eb0","2d2d80","252554","090936","c7e2ed","6ac3e6","00bbff","279ac4","347c96","2d5b6b","103947","bbf0d9","6febb3","00ff88","2eb878","349166","2b694c","0c3d25","c2edc0","76ed70","0dff00","36c72c","408c3b","315c2e","144511","d6edbb","b5eb73","8cff00","89c93a","6f8f44","4b632a","2a400c","f1f2bf","eef069","ffff00","baba30","91913f","5e5e2b","3b3b09","ffdeb8","f2ae61","ff8400","c48037","85623d","573e25","3d2309","fcbbae","ff8066","ff2b00","cc553d","9c5b4e","61372e","36130b"],"common":["000000","FFFFFF","7F7F7F","a1a1a1","C3C3C3","c40424","880015","B97A57","dba88c","ED1C24","f75b63","f26f9b","FF7F27","f7ab79","FFC90E","FFF200","cfc532","EFE4B0","1ee656","0c6624","22B14C","B5E61D","5487ff","00A2E8","99D9EA","3F48CC","7f86e3","7092BE","720899","cd55cf","A349A4","C8BFE7","ffffff"],"skin tones":["ffe0bd","ffdbac","ffcd94","eac086","e0ac69","f1c27d","ffad60","c68642","8d5524","896347","765339","613D24","4C2D17","391E0B","351606","2D1304","180A01","090300"]},"frames":[{"name":"","speed":100,"layers":[{"id":0,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAExJREFUWEft1LERACAMAzGy/9DOBCncUYgJuI/OkyTvkzc+c1xCmYuoMsq088UMM8y0BZhpi9kZZphpCzDTFrMzzDDTFmCmLWZnrmIL7qWLmCXUhAcAAAAASUVORK5CYII=","edit":false,"name":"Background","opacity":"1","active":true,"unqid":"1exvb","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":1,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAArBJREFUWEfNWMF2wjAMa+n/fzJ0zyEyiiKn5W2H9bIBia3IsmLYt3/07L/AclZ7z/Pc9n3/Ova3G0oAfwHsFpjzPE86aOwJUNXfCVcwFc8VW5dgCEhL3kuwPZ/P7TgOAAKAnYFTudq+K0BLMMJICwYwCA4Ur9crGTmOA+sGsFeASjDmhAMYrUUwFU8AYdDu/4ohC6YCIgmx14oaDAI0v64YmsCoRhBMT87MxGePxwOaSGY6A7bRHKABjDLCUUITKEG8zwA0GzqPEvKS1JECUmYa5UoxRWqBHBMCaEro6AnQbJAJRsoTJ2/AiA13omzpfgjnRxOOSj/MzCREMMDObvylectQh89NwK2dgu8xcgvYUTCDsVHJMqgEGkyuR9+DVTDqEqv+BjBVBzkwRPGqtRNQrOfkWiLopnVePw3fNYOA2dJF3G4v31dtuTM9B67lITAAl/V3rfktM647XbdOYLjNIMrFbZ3gsQ9akWSsq9Sk1Y0wY93SeAhKkA0AK8DaLuAGRBOrbyV7WiZ2YXVZYSk1geDuPlo5d3wW10iaHwvYjQycKB3u7SOtY4SJ9hL3WPzPV0gkD8D83nCQThGcc3BZN8aKqBsqLZEBmNdIBYRbmzWghopxseoynfZUd5VhDoNajKTTdVC1c0NOy7Vj4CmrDmA3Nub3iV4MVGXZKq+owMRB3NzMY4Sb9PTCTG9gdpTBYnZJQaNryPUh1/zWMA1XSOjatCqVXhkFO9b8esx3e+pGdl62/qu273py44QttU55Fkxy1wVr6J8GMoCGQJkp3o91DkgJRgERe0MbayItY99X7Zmq4gScuauS8TdLPm23CvfVt8WsGEHCJZgFQww475aCmVtAlmViYbMl6xWh5uU6Lk9+8TPJJTMVqDss3AVxu0yFZ7x/jlg8Vz9/uK0/fGymIjAHw4EAAAAASUVORK5CYII=","edit":false,"name":"Layer 1","opacity":"1","active":false,"unqid":"oo532f","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":2,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAArJJREFUWEe1mFt2wjAMRDHsf8khPVItdTwaOaGn5QuSWL4ePcN4/PJznue5WzrGGJ+a/nhBbGAw3X7G+e8wAsAOwwot1z4Bu6VMA2EiGciA+/E97AYoX5cevIQhEKWEGfbrU4XcCH9HiO3ct4VBEJA7N4XNCiTGd8TWFVALI6R/HMfxeL1eRWKliMsFCRXP7IAkDMdIGDIY+yAQGF9glWpXQAVGuMaCIU+pygu6QX2PmPKIn7aUQguMAkED4B9cl6lN7sIsi6XLNQZiZTxVsXaQay6zCWPljopYh+QJ4xg3QZaA5mAOZSmg81CoDsO4jGH9/X6X7AnA5/OZEFA7cvmmNQXIAmQ2tsrgkQ3CAOYa1SSz6mKGiVLb1qRSto/jOOemWVkDREidfXN+KUAZuT/nLtU64efDeNKl10SZ34Dg4c9ZGEuzjPWdah5rBHPZY6gxIoivBZhopLJiLwvH+K4/QpmlyEGs+OFU48S+1WWg6lWLpJ0yaJBkVYXMIS3Wok1wD0NYTHWuSUoZN2wPmnGEEf5O19jzEfgIw4eBBMkyYkkt3WQXub5wb1LpjQAM0/Qr9xL2KldmN8+CXzNDKEh9fRyAO7tqshPuXtHjngK1sQBhrBj4FYxSNWKqVOAu2BQQ5azHwA0XZx2MhlxgcLLjiZ8Dl9I9U55AVM3CwdyTpGuUS+xw9+Xf2CLMqAKJzfBeY9c9VIarkvuzp4CRbqYplTYusOvx+tyvwkRmIRAZjAO0L26mAicA1quwje7BIConiqEEg5ZH0jQAU4ga2EH9ZTxFRbYwSqE4iZ08qjOPFhwPVKPQrHwX5xl4UQkV2myUryiboM/MUopcKgOx4vLyGCnglmapwHYgJZu6dMC5WL0liiBPUzQ6bD2xvclw/AfR7v8ZXHv3v5qPYNpC8kc3vgArjLsiNA/itgAAAABJRU5ErkJggg==","edit":false,"name":"Layer 2","opacity":"1","active":false,"unqid":"oo532f","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":3,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAqNJREFUWEell9uSgzAMQ6H9/0+m3bEbZ2RFduiWl90Bkhxk+dLz+Of1fr/f3dLzPM9vt/5qAQNU5zHnXbBbMAjBAHZw3AsIfAfBdlBbmADpVLBnCgTDBM/LM1sYBAEFbI0/Cgj468+O4+C/zrUDKmEKReIQ3rxTplqznC1hWBE7GcI019h7qM51Xcfz+XSw4Y9pN1Zx7JnOX2Cq0MTBKl0xhCLjpjKF2SdDgilAlpAEEPkmhUNAn/BB03eokAoTFzNeKOG6bLLwPR6PCDWeGYng95b4h+uHR6TE9M4UoSvKtt/wVGnoREnptxzCxYxM3bYH2ywMzh8ThmeYFJKgicxAr0CGbb0yak+CQaAEw8aqwiCU84+5rkuqYmk+LgdGZWR1Hje9au7SF5RyYRACDnYF4sL7r9fLaxDeS5kJMH4AAkUWEAQaPymCdSRUNAAGtcyyy55FlvlagkH1qv9xzfQch2oA+McxEGycsxVhoIx/OuHaBrAJhkKzVhgQtIMpqCp2DKiUKRthiu1niOtUdT9FeFT45FyEBo4U5B6CqU2jhFtDjAwJlPdDVVJLGUbz7gubzrBiBw5TwrsBw/6ayth6dTjuNVsJ7DK/sFOGaoUqBylEXFsYDqDSBL8ULmpwzi36iwOhNEWbmKFTgGYF1ShTVeUqGl8iMs0z8E6/quYaHiH8C9n9XBewGBaDeqofZcEag3yIsgxX/LMjNuoq6eLeIXgx4yygEqbLrOg3qq8opbphi0I9BVGTXoo9hoyA2lbSFbrqJ4uEIYWShyo/sXKiPHg0KxAs6dJjaqTAiomLzFNx8c+VuN+BbGGUhwJGzbM8gmD13oHcguGQFX2Iu3lS+g7IbRhqGVXZqEIdvy6360oDb1d+uvXPALjBLzA3eL975Q81aKYi/zu6FwAAAABJRU5ErkJggg==","edit":false,"name":"Layer 3","opacity":"1","active":false,"unqid":"oo532f","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":4,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAp5JREFUWEe9l8uWgzAMQ0v7/59M6bEbe2RFDtDFdDPTB/hGVuSwPX58HcdxrC7dtm27e+vLF3DxrhYz3oE6hUEIBrDC+Jl6H+pcgVrCBEhXcN/3x+v1sntkyxjIYEKtM6AWhkC8YKfEgJIWiWuuAEkYAeIL5Gpc6P1+m1IPg7PX8/n0v6HsGdAEo1pj9xsgCRQFrXi80LwIMNrj166ACgyC8I2jOBgyVz5gWTnZ2hVQwjSKuMr23Y+xUXyGnlMKFZjVrrH+w/e5g0yx8IaRh2+wdd19B1wy+D9ClVAji8KqJhD2BAKBAux/bKNzJIxaNcuKKwxFEISqlYXgrhKtb2HSo+gVBFM7KQJw3/cDdtgEhBsA4NfKsLwdDCnk9++AusGZtSI/uhinvIhiHm6jcP6PK+1UjWtoQ3j+ZJjhVrMbDROmybDnEf92jf3OXgNO+gRVhhbPMw2TVSWoyhmcRWpYRrCFuRuY2ECZzFPMr6I9kpYMjKHIUZDK8naXxxH0DBpskbi+ADBpkZtVgfd5e5VZxTMIgrI2obURjNooPBizLZC89Rw0yHP2dNRCNW4xDt0CAi3ittW2MgwFkTzDwM5qPRfG51nVZM3pOJi8wOYevirzzX5D2z3r81CFUVJhMEfwfNINOhWSi1UfaoRQFzL0fHLbStWZQ+0yguxU9M8bkLimHiHCN6hO6/hvb/6Cqj6rTSbmrS1OAjMMA1EbJMAdFZXq/OiCK/Fu8DmYzzk8vW0mKV9ha9hffMILG0wwJ0CycGdmHKg4p7qHOQnTeShXMD/TZ5hRO8phvlNkqQzkiRtVnWnImMvdBL9tFx+zoomH78djy2OxDDkhvcFPqXymyCVlkFI8Oyk1ymdXIW7DnIDl13cBSqAue/TPX34AQUDBIiqR4IkAAAAASUVORK5CYII=","edit":false,"name":"Layer 4","opacity":"1","active":true,"unqid":"oo532f","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}}],"active":true,"selectedLayer":1,"unqid":"vr50fd","preview":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAjVJREFUWEfNWEFywkAMa+D/T4Z0nEEdRZHshR5aTiQhu7JsyV62fd/3r3/y2T4Fs22bDeE3sb0FRgHUxnzPXb9D+hKYtOHj8fi63W4toAKzytYIpoAg4sREgbrf7zFtWGNiqQXDi7gaYZC10fP5PEAVuPoUa/XBuxNDEYymhhet79iQGeHNFMAKIAtGaa1rbA6q6x4i1/ShTjjFnKLE0AWMU4yyMuU+gWHQDtAJzKpqeFEoCgBRN7ju5K+ALJiUe6WdgXBNMCCslTzqtBccmBebvqOAVS1aF1MRX54rGKZXZYmXnZLAkrKSVGTVmphRerVOCig8BQy5unFKUwH87FVgOgm6lLHjOvftAuEUXwTDYBhx0Y2+o4sDQN2v34ElJ111cXbnCEYbWio+RAbndc2S10pg6n0Ff0g79R12WzYyLmBmrWMmFfbJj1KaHECOGIunVpCU2LqzY0aj1XaAWgHVrj24NGuXtzXjouj6iNbBVG/KIoLhwezYrzO9rpYcINeZtVc5Fk8+MzETTeo1Bepzljs/06aKfS9gUsFNjc5F6nqUayGX1sNHFXViO3O8jihJ0qtAtJgPMvTc1JndZPNu9GApu+8Mvh07p1GiU9xUh5b1dKJ0KXPDFXsNq09d2o0MWm9LRxU7e9DxNo0J3FBVOdYop7O2G466EZLZczXWqW88Ub7bY5ya1KEToCUwCuikADK+5MquWD9Kk27MRpXSpWY2GSOeLzNzqfy//n9mNcJPf/cNbqwfxYQm5T8AAAAASUVORK5CYII=","width":"35","height":"35"}],"currentFrame":0,"name":"Untitled","preview":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMA/sfR5H8Fkddasdmnacvx//8745jkhasdASD945kjknhj/AAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAjVJREFUWEfNWEFywkAMa+D/T4Z0nEEdRZHshR5aTiQhu7JsyV62fd/3r3/y2T4Fs22bDeE3sb0FRgHUxnzPXb9D+hKYtOHj8fi63W4toAKzytYIpoAg4sREgbrf7zFtWGNiqQXDi7gaYZC10fP5PEAVuPoUa/XBuxNDEYymhhet79iQGeHNFMAKIAtGaa1rbA6q6x4i1/ShTjjFnKLE0AWMU4yyMuU+gWHQDtAJzKpqeFEoCgBRN7ju5K+ALJiUe6WdgXBNMCCslTzqtBccmBebvqOAVS1aF1MRX54rGKZXZYmXnZLAkrKSVGTVmphRerVOCig8BQy5unFKUwH87FVgOgm6lLHjOvftAuEUXwTDYBhx0Y2+o4sDQN2v34ElJ111cXbnCEYbWio+RAbndc2S10pg6n0Ff0g79R12WzYyLmBmrWMmFfbJj1KaHECOGIunVpCU2LqzY0aj1XaAWgHVrj24NGuXtzXjouj6iNbBVG/KIoLhwezYrzO9rpYcINeZtVc5Fk8+MzETTeo1Bepzljs/06aKfS9gUsFNjc5F6nqUayGX1sNHFXViO3O8jihJ0qtAtJgPMvTc1JndZPNu9GApu+8Mvh07p1GiU9xUh5b1dKJ0KXPDFXsNq09d2o0MWm9LRxU7e9DxNo0J3FBVOdYop7O2G466EZLZczXWqW88Ub7bY5ya1KEToCUwCuikADK+5MquWD9Kk27MRpXSpWY2GSOeLzNzqfy//n9mNcJPf/cNbqwfxYQm5T8AAAAASUVORK5CYII=","palette_id":false} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d12.pixil b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d12.pixil new file mode 100644 index 000000000..70e25c5ae --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d12.pixil @@ -0,0 +1 @@ +{"application":"pixil","version":"2.6.1","website":"pixilart.com","author":"https://www.pixilart.com","contact":"support@pixilart.com","width":"35","height":"35","colors":{"default":["000000","ffffff","f44336","E91E63","9C27B0","673AB7","3F51B5","2196F3","03A9F4","00BCD4","009688","4CAF50","8BC34A","CDDC39","FFEB3B","FFC107","FF9800","FF5722","795548","9E9E9E","607D8B","ffebee","ffcdd2","ef9a9a","e57373","ef5350","e53935","d32f2f","c62828","b71c1c","ff8a80","ff5252","ff1744","d50000","fce4ec","f8bbd0","f48fb1","f06292","ec407a","e91e63","d81b60","c2185b","ad1457","880e4f","ff80ab","ff4081","f50057","c51162","f3e5f5","e1bee7","ce93d8","ba68c8","ab47bc","9c27b0","8e24aa","7b1fa2","6a1b9a","4a148c","ea80fc","e040fb","d500f9","aa00ff","ede7f6","d1c4e9","b39ddb","9575cd","7e57c2","673ab7","5e35b1","512da8","4527a0","311b92","b388ff","7c4dff","651fff","6200ea","e8eaf6","c5cae9","9fa8da","7986cb","5c6bc0","3f51b5","3949ab","303f9f","283593","1a237e","8c9eff","536dfe","3d5afe","304ffe","e3f2fd","bbdefb","90caf9","64b5f6","42a5f5","2196f3","1e88e5","1976d2","1565c0","0d47a1","82b1ff","448aff","2979ff","2962ff","e1f5fe","b3e5fc","81d4fa","4fc3f7","29b6f6","03a9f4","039be5","0288d1","0277bd","01579b","80d8ff","40c4ff","00b0ff","0091ea","e0f7fa","b2ebf2","80deea","4dd0e1","26c6da","00bcd4","00acc1","0097a7","00838f","006064","84ffff","18ffff","00e5ff","00b8d4","e0f2f1","b2dfdb","80cbc4","4db6ac","26a69a","009688","00897b","00796b","00695c","004d40","a7ffeb","64ffda","1de9b6","00bfa5","e8f5e9","c8e6c9","a5d6a7","81c784","66bb6a","4caf50","43a047","388e3c","2e7d32","1b5e20","b9f6ca","69f0ae","00e676","00c853","f1f8e9","dcedc8","c5e1a5","aed581","9ccc65","8bc34a","7cb342","689f38","558b2f","33691e","ccff90","b2ff59","76ff03","64dd17","f9fbe7","f0f4c3","e6ee9c","dce775","d4e157","cddc39","c0ca33","afb42b","9e9d24","827717","f4ff81","eeff41","c6ff00","aeea00","fffde7","fff9c4","fff59d","fff176","ffee58","ffeb3b","fdd835","fbc02d","f9a825","f57f17","ffff8d","ffff00","ffea00","ffd600","fff8e1","ffecb3","ffe082","ffd54f","ffca28","ffc107","ffb300","ffa000","ff8f00","ff6f00","ffe57f","ffd740","ffc400","ffab00","fff3e0","ffe0b2","ffcc80","ffb74d","ffa726","ff9800","fb8c00","f57c00","ef6c00","e65100","ffd180","ffab40","ff9100","ff6d00","fbe9e7","ffccbc","ffab91","ff8a65","ff7043","ff5722","f4511e","e64a19","d84315","bf360c","ff9e80","ff6e40","ff3d00","dd2c00","efebe9","d7ccc8","bcaaa4","a1887f","8d6e63","795548","6d4c41","5d4037","4e342e","3e2723","fafafa","f5f5f5","eeeeee","e0e0e0","bdbdbd","9e9e9e","757575","616161","424242","212121","eceff1","cfd8dc","b0bec5","90a4ae","78909c","607d8b","546e7a","455a64","37474f","263238"],"simple":["ffffff","d4d4d4","a1a1a1","787878","545454","303030","000000","edc5c5","e68383","ff0000","de2424","ad3636","823737","592b2b","f5d2ee","eb8dd7","f700b9","bf1f97","9c277f","732761","4f2445","e2bcf7","bf79e8","9d00ff","8330ba","6d3096","502c69","351b47","c5c3f0","736feb","0905f7","2e2eb0","2d2d80","252554","090936","c7e2ed","6ac3e6","00bbff","279ac4","347c96","2d5b6b","103947","bbf0d9","6febb3","00ff88","2eb878","349166","2b694c","0c3d25","c2edc0","76ed70","0dff00","36c72c","408c3b","315c2e","144511","d6edbb","b5eb73","8cff00","89c93a","6f8f44","4b632a","2a400c","f1f2bf","eef069","ffff00","baba30","91913f","5e5e2b","3b3b09","ffdeb8","f2ae61","ff8400","c48037","85623d","573e25","3d2309","fcbbae","ff8066","ff2b00","cc553d","9c5b4e","61372e","36130b"],"common":["000000","FFFFFF","7F7F7F","a1a1a1","C3C3C3","c40424","880015","B97A57","dba88c","ED1C24","f75b63","f26f9b","FF7F27","f7ab79","FFC90E","FFF200","cfc532","EFE4B0","1ee656","0c6624","22B14C","B5E61D","5487ff","00A2E8","99D9EA","3F48CC","7f86e3","7092BE","720899","cd55cf","A349A4","C8BFE7","ffffff"],"skin tones":["ffe0bd","ffdbac","ffcd94","eac086","e0ac69","f1c27d","ffad60","c68642","8d5524","896347","765339","613D24","4C2D17","391E0B","351606","2D1304","180A01","090300"]},"frames":[{"name":"","speed":100,"layers":[{"id":0,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAFpJREFUWEftlDEKAEAIw67/f3TvBQ4tCA5xVzSGyrbfkVK7jCRNN9Qz28YNmDUZltkgMM3kTZBJfcMZnMGZlADOpMTIGZzBmZQAzqTEyBmcwZmUAM6kxE7lzAeBa4+YB9sR7AAAAABJRU5ErkJggg==","edit":false,"name":"Background","opacity":"1","active":true,"unqid":"4anbk4","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":1,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAjZJREFUWEfNmEuSwzAIRMf3P7SnrBFU0zQIezXZJLEt8fi1SK6ff/S6vrLc931Xa6/r+rTveJEyrmwqxincCMZATsa7+xOgIwyDoOfbwJOuZ5/1jhE0OFtzAmphKpBtxAC4dNZ1AFj3J0AlzABk2cCoGIRF7C2QhKlqhDa3tdhVfo1BLHxdhBKMiggWZtPRqdNFzbQpCzAVyAPwUTrcOBTviqSKkMOI1KTOeBMVC9PjBDgTUstAAQa8907B3NPiUoGxxQEm1BOm0KKmYLBlQ/tyAReqXLY2SoJFa78vjgRDD3mIJyCQmgTEdfcGxhV1GwgiRirsXaTUmerFdektzJJRyu2K5uSsQuFTe6CTZc0g8bK8u8E+CxiMIkZQpgq7zFq8hVELGpggdtxxlRLbMdIWMAmSixPApFRhXRxOedScJIiVzkhvGYj1vwMpUm5wfWsLQ35JzSkTENxz1E18umI0VEtjzvdIEVJL0UyH6VH0uIDZI3E/HR/FHmnsGBWwGhs4PcJrOXaC0tt5FuBla2ORKcOHlJ1AUhmWOrNvuOJyi3ff2Qqd/mspPKOmwdhNBqO859O2ilDR+pwamaK1VmkF10t1tuDZldrk70I4KuB7P+lBSy9PKqD9nJ87NMmhEYQJn6uhfPzrQE15PPuAQyFQRWcm2xJG1Q8WMGtIBYVEYtZJmS1hEIjTpoyIUWM9NoFw54rCC5fV72c0NPhDoHX6FQwX9yRS+5kRxCcYBaUie/q3ocrGL7FUikLdy+7AAAAAAElFTkSuQmCC","edit":false,"name":"Layer 1","opacity":"1","active":false,"unqid":"a2sj1t","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":2,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAi9JREFUWEfVV9FuAzEI6/3/R98UFpBxDEmr09Ttpes1CY4xhrteX/R3fRGW1/8Dc9/37Qxe10f4jzZtFzkQBDGwje/+OYAC3sj89bvJL7KNtV0Ah6WADG4gmM/8TARxBKgEMxipUuIs+O/IirOBrA2cJwx1zIROOLinhcHCOg9un2K/jFuBWYCwgFkvBOxyZhGI2JPiL2AwPUR1aEbppao2SmGytXl+YEhgGiCSblVBGK3THOpt6iybXkftRrTLjdnZC7HbMmeI02RaAfriO5RuVeJ4Vtrne1k/+Hyw04GxtRNclHmhARMspSgqChkHL7ItYJ4JTKogwBkecQoExBxaw6D+O4HMYCp794OK8o4yhiDYEqJtcPrZDFOelblx32Ehiv6z6Ez0ssS2p64VnRLevHJpCcwONlT2rcEM2InWDJelsHnDOQ/ivvM8M5XLYloKkEvpc9VQ04yOHnSL8mvnFWViwuhkNTmjmKLwEThk26mV3W8Gq9Q0lc+4n73Vm7iy0JX9QLwY+1LlwBLMPIhbApKx2DwBirXMVtebSjBKO1TOEhDrpQIJvS88dPmHDsM+o0bGElA1/bF7K7+Skx6pfATGMdIup8wNLhSNE6yA28YS+2QGVqaGzxad8AgqqvWtGdimaOrcQQY2uGLGTQP5E28HO0AGrhiyu3FEad2edWnyYO37k5h70qBVsCsBbcHM29tNP3zPxjG2ZOWImXb3wz8eMfNwzM8181dARpwfC5kXQnaygo4AAAAASUVORK5CYII=","edit":false,"name":"Layer 2","opacity":"1","active":false,"unqid":"a2sj1t","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":3,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAjxJREFUWEfNV0GSwzAIa/7/aO/YaxghC3A7PXRP3YSAIiRwntcP/T0/hOX1MZgxxnie9PGP8r79UAZijLFIRoBw7arOVdAswiCwuAKC7Z/3n4JGi23BVO3YRSZQZ8SAeYHYyrJeejNjQhVRoGbHZg7VuowlCYaAzJh/QbyW4K1GYGN2ARjCZwJzkOcw8gEmAWLJQxHORtpYoE0q+Htr8NBRANMAMWZWLkuIgLAwtCdlc8c4hgyMXbf2tEBYS+ywzPqoH24TakMN54ORncx1hILNnEWC18ywUElsKRBDjcWTlq1Q0k8L5mhLpRFzGceoOScAX4EJbSqG2UqG4q8Y4rmzX8TnBhYNdlT0K01M3fCAU4CokNm+ZkbtncItanAqfSlDoByOI4RbGRXfAHE2aUtLQMLiJTPHlKUEcudwS9ny7C4ailozyhENmLAqmJ3sqEF7LAXj0zfZLW8zQ/uJ3Ze3SWxe3y07qYNhm7KDmNHdyqmllcPyuSZJ4oe1WcgKENtE6YXPPFdtYma4VSi8sJBsd/yjPc48sFrC2agcerQ7Qn+VdZPhEXSV2PlYyt15xib9mpa8ErIphtf5OWshMOXh2Rk4oG6+kVpMrBcFJIxikTFMUDW0OhT8DQX/SxLSrwOwodcsrMruzARcEtCBWZrBqYzWhjmxZseODUOTZlFZ7wZMCghOhkGzxefMV8AcgPYbh72EH27IyBZw++JtAE9oFu3lIeqqzlVQ4Rr8lFlh4nh6XeM6sLPxN+7/AbQmAUIHBi45AAAAAElFTkSuQmCC","edit":false,"name":"Layer 3","opacity":"1","active":false,"unqid":"a2sj1t","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":4,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAjJJREFUWEftV9FuxDAIu/z/R2dqLlDjGJKe9nCTtpdNbQaOMYa21xf9tC/C8vqbYHrvvbXPsPfeRwHaJsCT6COiBYbg1/Mrjr/Pcl7/WwE6BZMlasjYTIYyxPgYQ+Y9AfPm+L69sTB+GwAohYHBc/asBLQDg0BCQCxZUpYAmi5klwvNXIHhWwxtDCpuMRpY1xIBs/ioK2Q05M/ALEmce+ooFLQ4g2Cw1FhKZ0eBOeqKnVkCQwxosHi95+5iMKp9R15mQOmkOBPykGf5uwUMdoX6e+pFCXC5CJwNJUILQHYkmHnrpXWnYQUhB1OZeqpYFBbgF8vAmJm5qcFtvKOUbqx8GSDBimtncUi0dmtlEBuPg0AMtL13iz2jkikrCH3qbooGRcqXQWwuAXifVeRNVRNKMBiI2zAzt6VNZ9YgamNY6Wz4KLz4NWawJDTlAzMk5ghGzQ/zBB6ISgNXt/EUR1dWwLAxnBlKmj0fGFCURHnYa5LxkK4jZVJeESqfgXey48j6lSTuHRiZsRJsHJhdeDtKcF6pkbAww3MoMzHWzO7/lFfxsEwHmFghXR5qbajGAo4XA42XtL14WSHUV8BJewqxSk/KhqSavCOmWrJZPyjY5LYWK3hLsgmOM0c7MJvTtH9cQRczw6TVpA7lrYYFWnrybRQ8h8X+9Ptpx4xh5c8VZNU9ULEhui7NeQpmyMLGhXJg6g4fsH6bg0/cJ2AQ0EF130eoE8t8T8Ecg/jk4D+YjLUfNgMXQvU7QCMAAAAASUVORK5CYII=","edit":false,"name":"Layer 4","opacity":"1","active":true,"unqid":"a2sj1t","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}}],"active":true,"selectedLayer":4,"unqid":"d602vs","preview":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAadJREFUWEftV9ESwjAIs///0fPmyY5lSWC9TX3QF7XtSggQ2FiWZXn8yGfMghljDOXD9J2zD95B5ilmDBkWWzcT2mACCF68rq9reV+BrkC1wChDcXm1v9KmnMmUlmDQULDAvtFosBYGK0AWDHs4hwCZyV4i2HUPw4mJJsEgEPQysxCG3JpisgwT8x6pjv8sKZkjyEx2YLsbdeaKqmAJiw5SpjMYlyOspDHm6kyHvZcDCCYnJfsdXncNM6ZVIlMwWchy4ikgVelWFbg5rZjZZXlS2VJF3/3TMce0axcmRWdmQ4kYVoZrHViFO7vBjOoxXaXtAHKN9mUHwTDhwhzCM0wzVHnb8H2TGazWHTOqfzBmlPQzRlgV0gb8iWqqtGYjgYG5UmeUqjPhm1bgM9XDhjCa4LO9qaooNYJkrTro1h1d2wFRRXJolJ2ZBYXLdXM2CbpprzXpKWrZjOI8d3IgmVFduKM3CCYnupsgSzCY8arbOvC5+2OTxL3yVcUBQmVVnleMbM5037XVWMBYwQlANdIpZlSVsRDgWjWM5fOtMHWMXnHmD0ax+AT6o7S2HI0/tgAAAABJRU5ErkJggg==","width":"35","height":"35"}],"currentFrame":0,"name":"Untitled","preview":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMA/sfR5H8Fkddasdmnacvx//8745jkhasdASD945kjknhj/AAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAbFJREFUWEftV1sSgzAITC7T+5+nl7GjLRlcdwEz9vFRf2wTDcsCC/ZlWZb2I1efBdN77621W2vtjvfpM2dffAeZp5h5knH+qmZCGYwBwYPX9XXN7yvQGagSGGXIDs/2Vy6VM57nFAwaMhbYHY0aa2YwAxSCYS/7ECAz3ksEu+5hODH7JBgEgl56FsxQtKaYTMPEvEeq7T9LSuYIMuMdGGejzlxRFSxh0UHKtAcT5QgraYy5eqbC3uYAgvFJyX6b11XDjGmVyBSMFzKfeApIVrpZBQ6nFTO7LHcqm6roq2VEzDHt2oVJ0enZUCKGlRG1DqzCnV1jRvWYqtJWAEWNdrODYJhwYQ7hM0wzVHmH4fsmM1itO2ZU/2DMKOlnjLAqpA34E9WUac0ggYG5UmeUqjPhm1bgM9XDhjCa4LO9KasoNYJ4rTro1ju6dgREFcmhUVZmFhSuqJuzSTCa9kqTnqKWzSiR55EcSGZUF67oDYLxiR5NkCkYzHjVbSPwvvtjk8S99FMlAoTKqjzPGBnOVL+11VjAWMEJQDXSKWZUlbEQ4Fo2jPnnS2GqGL3imT8YxeIDSbO3tqGpQPgAAAAASUVORK5CYII=","palette_id":false} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d20.pixil b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d20.pixil new file mode 100644 index 000000000..4e2baeb61 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d20.pixil @@ -0,0 +1 @@ +{"application":"pixil","version":"2.6.1","website":"pixilart.com","author":"https://www.pixilart.com","contact":"support@pixilart.com","width":"35","height":"35","colors":{"default":["000000","ffffff","f44336","E91E63","9C27B0","673AB7","3F51B5","2196F3","03A9F4","00BCD4","009688","4CAF50","8BC34A","CDDC39","FFEB3B","FFC107","FF9800","FF5722","795548","9E9E9E","607D8B","ffebee","ffcdd2","ef9a9a","e57373","ef5350","e53935","d32f2f","c62828","b71c1c","ff8a80","ff5252","ff1744","d50000","fce4ec","f8bbd0","f48fb1","f06292","ec407a","e91e63","d81b60","c2185b","ad1457","880e4f","ff80ab","ff4081","f50057","c51162","f3e5f5","e1bee7","ce93d8","ba68c8","ab47bc","9c27b0","8e24aa","7b1fa2","6a1b9a","4a148c","ea80fc","e040fb","d500f9","aa00ff","ede7f6","d1c4e9","b39ddb","9575cd","7e57c2","673ab7","5e35b1","512da8","4527a0","311b92","b388ff","7c4dff","651fff","6200ea","e8eaf6","c5cae9","9fa8da","7986cb","5c6bc0","3f51b5","3949ab","303f9f","283593","1a237e","8c9eff","536dfe","3d5afe","304ffe","e3f2fd","bbdefb","90caf9","64b5f6","42a5f5","2196f3","1e88e5","1976d2","1565c0","0d47a1","82b1ff","448aff","2979ff","2962ff","e1f5fe","b3e5fc","81d4fa","4fc3f7","29b6f6","03a9f4","039be5","0288d1","0277bd","01579b","80d8ff","40c4ff","00b0ff","0091ea","e0f7fa","b2ebf2","80deea","4dd0e1","26c6da","00bcd4","00acc1","0097a7","00838f","006064","84ffff","18ffff","00e5ff","00b8d4","e0f2f1","b2dfdb","80cbc4","4db6ac","26a69a","009688","00897b","00796b","00695c","004d40","a7ffeb","64ffda","1de9b6","00bfa5","e8f5e9","c8e6c9","a5d6a7","81c784","66bb6a","4caf50","43a047","388e3c","2e7d32","1b5e20","b9f6ca","69f0ae","00e676","00c853","f1f8e9","dcedc8","c5e1a5","aed581","9ccc65","8bc34a","7cb342","689f38","558b2f","33691e","ccff90","b2ff59","76ff03","64dd17","f9fbe7","f0f4c3","e6ee9c","dce775","d4e157","cddc39","c0ca33","afb42b","9e9d24","827717","f4ff81","eeff41","c6ff00","aeea00","fffde7","fff9c4","fff59d","fff176","ffee58","ffeb3b","fdd835","fbc02d","f9a825","f57f17","ffff8d","ffff00","ffea00","ffd600","fff8e1","ffecb3","ffe082","ffd54f","ffca28","ffc107","ffb300","ffa000","ff8f00","ff6f00","ffe57f","ffd740","ffc400","ffab00","fff3e0","ffe0b2","ffcc80","ffb74d","ffa726","ff9800","fb8c00","f57c00","ef6c00","e65100","ffd180","ffab40","ff9100","ff6d00","fbe9e7","ffccbc","ffab91","ff8a65","ff7043","ff5722","f4511e","e64a19","d84315","bf360c","ff9e80","ff6e40","ff3d00","dd2c00","efebe9","d7ccc8","bcaaa4","a1887f","8d6e63","795548","6d4c41","5d4037","4e342e","3e2723","fafafa","f5f5f5","eeeeee","e0e0e0","bdbdbd","9e9e9e","757575","616161","424242","212121","eceff1","cfd8dc","b0bec5","90a4ae","78909c","607d8b","546e7a","455a64","37474f","263238"],"simple":["ffffff","d4d4d4","a1a1a1","787878","545454","303030","000000","edc5c5","e68383","ff0000","de2424","ad3636","823737","592b2b","f5d2ee","eb8dd7","f700b9","bf1f97","9c277f","732761","4f2445","e2bcf7","bf79e8","9d00ff","8330ba","6d3096","502c69","351b47","c5c3f0","736feb","0905f7","2e2eb0","2d2d80","252554","090936","c7e2ed","6ac3e6","00bbff","279ac4","347c96","2d5b6b","103947","bbf0d9","6febb3","00ff88","2eb878","349166","2b694c","0c3d25","c2edc0","76ed70","0dff00","36c72c","408c3b","315c2e","144511","d6edbb","b5eb73","8cff00","89c93a","6f8f44","4b632a","2a400c","f1f2bf","eef069","ffff00","baba30","91913f","5e5e2b","3b3b09","ffdeb8","f2ae61","ff8400","c48037","85623d","573e25","3d2309","fcbbae","ff8066","ff2b00","cc553d","9c5b4e","61372e","36130b"],"common":["000000","FFFFFF","7F7F7F","a1a1a1","C3C3C3","c40424","880015","B97A57","dba88c","ED1C24","f75b63","f26f9b","FF7F27","f7ab79","FFC90E","FFF200","cfc532","EFE4B0","1ee656","0c6624","22B14C","B5E61D","5487ff","00A2E8","99D9EA","3F48CC","7f86e3","7092BE","720899","cd55cf","A349A4","C8BFE7","ffffff"],"skin tones":["ffe0bd","ffdbac","ffcd94","eac086","e0ac69","f1c27d","ffad60","c68642","8d5524","896347","765339","613D24","4C2D17","391E0B","351606","2D1304","180A01","090300"]},"frames":[{"name":"","speed":100,"layers":[{"id":0,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAExJREFUWEft1LERACAMAzGy/9DOBCncUYgJuI/OkyTvkzc+c1xCmYuoMsq088UMM8y0BZhpi9kZZphpCzDTFrMzzDDTFmCmLWZnrmIL7qWLmCXUhAcAAAAASUVORK5CYII=","edit":false,"name":"Background","opacity":"1","active":true,"unqid":"epa8u","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":1,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAjNJREFUWEfNWNFy5CAMK///0WlhYo8QkoHcy+1LO9mAZVmyYdvPf/Rp/4LleZ6H17fWPu/5aSGCwNiI7QuoKzAOBLPzFdQRmB2ICM4VugVVgtmB6IywbJRkTkFJMDtNRMAe5P2/75PLnIZ3oCYwOxCdCQFkkowo2QCKLzlQCSaAKHf0Z8BClgZZ6TiRHQUc98ASh/MmMJh1ZKKAwLMpa8p4SYD3CkAlGBamKo3od1O5qjXMvgXDVEYEztp1blVOLBnuRwyPOo9P10x8qRar4Ce2rtYdgwlAkSm4pKmZVM04Z4ojzaA9mXY3i1DwXFqhkcT+7j8qJMuEqlfAkCXqIcmac+GVZoC60NL4y+5wQu+vov6UDgXbNTPORagh1fSw+VECS0/aChiZqUpUOG4plTLD21uGF8o+w4tflib6UbA0MLNNqJIbLfkyUdZyZKD40dY440jo2NJSh1tmXK2N5XHyB+0p/ihHsBvuI+3trS0YymCQkX0G61O8bIAjZjBYOERphw5SHBQdlEcM7mPbQYmIidpFyNxLWNDQGKOkis21A4tWPjagw5d1FjsohK4Ob0ezSTU87is8QLEdkFZCzONUwB+rmaKRTaMBN6z6RoyFBcH7gK0vD+TudE/9hHsFn40dhikxvHkuvN3cEMpo5ks6MU7x7SWuElzEOWHQsCnjfr5Rnp6JwzGQgI1ZggFX5SWM2cARoZxyAiLfuan7yd37hgmOfcSMyHj5kWjZ+FZQfxv8AsTOxkLIDDsGAAAAAElFTkSuQmCC","edit":false,"name":"Layer 1","opacity":"1","active":false,"unqid":"c2f8it","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":2,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAiFJREFUWEfVV0FuwzAMa/7/6Aw2LIGmSMUbcuh6aZHFNk2RlHZ9vuhzfRGWz/8Bc9/3PZi7rncwr+3GfnJDe4oCEptxacfe42/8He/h2eu934N5YgTBPQFBsIvtAkgiPGHFAWWA42AozyTLsVPAdECi1vgOH6TcqRhU7EgwfGu6yRT10PX6DmwFR+zDenLsbGCcewDMADLWIKD5W5UH0TmBo7MKGL6NqjkAmutdaVHUJ9pJMLxhc5MUobMuPlfijezi3NnAICu4ADQkmTAlmuVs9FKcZcGIcl0PTsPNMwSVbvhZOAs1swkx6o0LBXMJkN8LRljcwbgAufWIBKPKRQIMR00wFAUbQBBxuhCBos03ZlyANZqYe0HuSJvD4RbQ7MdAV4otnnFjJB2lmFVIsqMce2iOopkSoz7QMoH/ygzpp2qmU38kMeiEAc39VWbhwa5xtsw0EY8HyhTnkYEZVzOOzBlaWNyhNIVR4NpAl9ijRx2BAceU2YQsn/dg+4KFt7viRGB7E95+gY6OnY2RA0y5T7UDZjZIsV2bS4UREO7BQYY1EEBFdnHWJIajeQYHKbJxNkOlBy6NahF2nlmLOd5ZJ3K4UpY+iQl8R46drAW4IQORgxXb+GTKm2eaxHX/vMkxQh1+EnIlexQYVy53KIrVdXznoLZMsKiww9aF2+coYUTK+SMrIh92gByTJ8955j0u08nmb7/TMvP2YU/7fRWYH/oqWEIZZe9qAAAAAElFTkSuQmCC","edit":false,"name":"Layer 2","opacity":"1","active":false,"unqid":"c2f8it","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":3,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAhpJREFUWEfNV9uuwyAMW///ozuBSGSMDeE8HG0v2yraGF8S+nx+6PP8EJbPFZj3fd8A/zz+Vlj2eXYLiYkSmBOIKM51b0FtwZxA4Mao8LTnKigLJoBcsNwBVEA56RYwN2zszO9A7ViawNywgT5pvxuDzjsKNKxNDAuYU0qC4gY81jIYLF59XruHZcroxgNHIVyXSiIb/WGDHQSAssQal+gtGEFlBxtMKMMCeATd6xgbaJli/dhZLAq28r/yiPDQg1KGCnENNnQGQ4sTkCiQ0iLI4S3cSPudAP8KJrw1ecU92Ow85RXeOjMzTNYWSlbUzlBmEfNJtjIz4PpEjeZTPYISgkafkoimJ2/qaJP22eapr1hDkxTJrmmOXiblBU7KKIYSJjE8BlzyoBeVPdPrqm47otoTMnzVv5nV3Yy6kon13UR3YoY7MZsZmyZOgaUD08Kl29JAZKk6ixxfN1RLzHDLFwlYzi5BDc8lN0xLnrkpvDvPtA68Y0m1DymTma6ydmEqL/eRh67SJI+S7C2u6FJER5MYNf2yPULsEsBsMBD2iTpqwD3bpjd1XD67qAMVPlgMykykYat27HRjgZKzND30nBkBuGEPRkV0XJtmjDM5M+kiD9etTIH4+BorEpGjoNIe1LsTG3jy4ukdqhpr8oqtuQUDMbRMiUNUbqgKIiXbdVHRO47yiRiXNqz6TAmbk++WiaU/lar/06IvOzpSQih7Kx4AAAAASUVORK5CYII=","edit":false,"name":"Layer 3","opacity":"1","active":false,"unqid":"c2f8it","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":4,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAidJREFUWEfVV9GOwzAMWv//o3uKVWeYgNNKfdjt5XTr4hDAOD0+P/Q5fgjL5/+AOc/zHMwdxzuYr3KjnizY7jLA4DooFuqO/8fz6++olfiL+qbGsrcF41jpACWCHZMAvoJ2BkZWFICdfCRJyJ0fJ5dkBlkhKWzziQ0SwMFyp8TXgSYGC4Z1VtSb04d3LtTFR1yD5VrAsFeSGTSsohxkSzAMKkp0ckkwcIJZEH3DHkLagXpkZ9qFdUZ2Cpiug6CFo5Xxo1qX/DAWbL2zgDG6ls1ROjKj6piCm6UC+b9JqFhxDGCHpVfwtxumKq3f8KxgXBGWRCQvMpIjBA1cpHXTYMr0JOSaQMt6QfSYQWqkbMGklqJTZlakiZMG1XXDqNfzYMjJJ9KzTM+y+JqsU1/2CeRKMW1OZMW0OMQctnE5AITLxpyibzNDKvQGRhnypET7YlJgNPyCDLqJn4eWBp5xacJNSQYSWBAok/JmAdP4QIYezy1ez13n5lx2nk1gtRC+W2aWkWPpLPRd2sCC4UTFBQ/TNtjkAYszjp6vF+Nd+HExLggZIyc+zKIJNuOgvc9Q7C85ZQJtuVzdmdjBukjCuOKTnhhOyxWCwqz4JPdwV098bbl1B1bJyYcwl6+o390ItmCygDIvekRFwS6jjMdi2a33JpUn2FnNmFAuwJe+8tyCYXYUI2xwvowpeSkIn4HppJDHbr7sgLQyPd3ojd+3Mr2xwZMaPwXmDyLsWEINgQlHAAAAAElFTkSuQmCC","edit":false,"name":"Layer 4","opacity":"1","active":true,"unqid":"c2f8it","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}}],"active":true,"selectedLayer":"0","unqid":"unboeg","preview":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAbJJREFUWEftV8tyg0AM6/7/R9OhE2eMVg9TesihuSRhwCvLsmzWcRzH14d81j8YUYkRM2utPylkUkQE04FUsLp2/j9/9+vsQBaDZXcLzBkgATrvSUwqhiyYzkA/BAGxLPuBCO7XYHopXMZ4gEqkgNNyqtbGOjMgLPsCXyVFTXUWtwQSGBZcBayD+zfTmWKHaga7BQMyzaQyKWFf2GXMMMFh1p2d1LrTUm3MKCBYGuc/qjS95KzUFoyj3pmdY8o1wgVMorvqjs6rZoWKpwBRMMxlmemhKNVYmNrEG4xzWyXe1HVdO2lM/LBd3YRgWNZdJyz4pL1d3A1Md050UQUGjXFSUuZdVsCsdCp7ZYxuwG7u3k0vTVfUSFyWXksZS4CuIujAd0zPlYeJV825NzAFRk1fNQSVTvA6Gw0STDc2VW+1OKmVgpkl7V43KGldXztvsvzUYWMwLhO3yzhbGPnSdLlimeJMcnp4BAa1M7Fz9kwHnAbxo7cDB3Bijhuz6V07tTJbJ9iKoLR2YW4Cph7A1u1AcG7dKU/dG98ok1aQavc/jo/EzJ3Dnt47YubpIdPnPwrMN5+zjLYb9TyVAAAAAElFTkSuQmCC","width":"35","height":"35"}],"currentFrame":0,"name":"Untitled","preview":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMA/sfR5H8Fkddasdmnacvx//8745jkhasdASD945kjknhj/AAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAbJJREFUWEftV8tyg0AM6/7/R9OhE2eMVg9TesihuSRhwCvLsmzWcRzH14d81j8YUYkRM2utPylkUkQE04FUsLp2/j9/9+vsQBaDZXcLzBkgATrvSUwqhiyYzkA/BAGxLPuBCO7XYHopXMZ4gEqkgNNyqtbGOjMgLPsCXyVFTXUWtwQSGBZcBayD+zfTmWKHaga7BQMyzaQyKWFf2GXMMMFh1p2d1LrTUm3MKCBYGuc/qjS95KzUFoyj3pmdY8o1wgVMorvqjs6rZoWKpwBRMMxlmemhKNVYmNrEG4xzWyXe1HVdO2lM/LBd3YRgWNZdJyz4pL1d3A1Md050UQUGjXFSUuZdVsCsdCp7ZYxuwG7u3k0vTVfUSFyWXksZS4CuIujAd0zPlYeJV825NzAFRk1fNQSVTvA6Gw0STDc2VW+1OKmVgpkl7V43KGldXztvsvzUYWMwLhO3yzhbGPnSdLlimeJMcnp4BAa1M7Fz9kwHnAbxo7cDB3Bijhuz6V07tTJbJ9iKoLR2YW4Cph7A1u1AcG7dKU/dG98ok1aQavc/jo/EzJ3Dnt47YubpIdPnPwrMN5+zjLYb9TyVAAAAAElFTkSuQmCC","palette_id":false} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d6.pixil b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d6.pixil new file mode 100644 index 000000000..4d9d44d7b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d6.pixil @@ -0,0 +1 @@ +{"application":"pixil","version":"2.6.1","website":"pixilart.com","author":"https://www.pixilart.com","contact":"support@pixilart.com","width":"35","height":"35","colors":{"default":["000000","ffffff","f44336","E91E63","9C27B0","673AB7","3F51B5","2196F3","03A9F4","00BCD4","009688","4CAF50","8BC34A","CDDC39","FFEB3B","FFC107","FF9800","FF5722","795548","9E9E9E","607D8B","ffebee","ffcdd2","ef9a9a","e57373","ef5350","e53935","d32f2f","c62828","b71c1c","ff8a80","ff5252","ff1744","d50000","fce4ec","f8bbd0","f48fb1","f06292","ec407a","e91e63","d81b60","c2185b","ad1457","880e4f","ff80ab","ff4081","f50057","c51162","f3e5f5","e1bee7","ce93d8","ba68c8","ab47bc","9c27b0","8e24aa","7b1fa2","6a1b9a","4a148c","ea80fc","e040fb","d500f9","aa00ff","ede7f6","d1c4e9","b39ddb","9575cd","7e57c2","673ab7","5e35b1","512da8","4527a0","311b92","b388ff","7c4dff","651fff","6200ea","e8eaf6","c5cae9","9fa8da","7986cb","5c6bc0","3f51b5","3949ab","303f9f","283593","1a237e","8c9eff","536dfe","3d5afe","304ffe","e3f2fd","bbdefb","90caf9","64b5f6","42a5f5","2196f3","1e88e5","1976d2","1565c0","0d47a1","82b1ff","448aff","2979ff","2962ff","e1f5fe","b3e5fc","81d4fa","4fc3f7","29b6f6","03a9f4","039be5","0288d1","0277bd","01579b","80d8ff","40c4ff","00b0ff","0091ea","e0f7fa","b2ebf2","80deea","4dd0e1","26c6da","00bcd4","00acc1","0097a7","00838f","006064","84ffff","18ffff","00e5ff","00b8d4","e0f2f1","b2dfdb","80cbc4","4db6ac","26a69a","009688","00897b","00796b","00695c","004d40","a7ffeb","64ffda","1de9b6","00bfa5","e8f5e9","c8e6c9","a5d6a7","81c784","66bb6a","4caf50","43a047","388e3c","2e7d32","1b5e20","b9f6ca","69f0ae","00e676","00c853","f1f8e9","dcedc8","c5e1a5","aed581","9ccc65","8bc34a","7cb342","689f38","558b2f","33691e","ccff90","b2ff59","76ff03","64dd17","f9fbe7","f0f4c3","e6ee9c","dce775","d4e157","cddc39","c0ca33","afb42b","9e9d24","827717","f4ff81","eeff41","c6ff00","aeea00","fffde7","fff9c4","fff59d","fff176","ffee58","ffeb3b","fdd835","fbc02d","f9a825","f57f17","ffff8d","ffff00","ffea00","ffd600","fff8e1","ffecb3","ffe082","ffd54f","ffca28","ffc107","ffb300","ffa000","ff8f00","ff6f00","ffe57f","ffd740","ffc400","ffab00","fff3e0","ffe0b2","ffcc80","ffb74d","ffa726","ff9800","fb8c00","f57c00","ef6c00","e65100","ffd180","ffab40","ff9100","ff6d00","fbe9e7","ffccbc","ffab91","ff8a65","ff7043","ff5722","f4511e","e64a19","d84315","bf360c","ff9e80","ff6e40","ff3d00","dd2c00","efebe9","d7ccc8","bcaaa4","a1887f","8d6e63","795548","6d4c41","5d4037","4e342e","3e2723","fafafa","f5f5f5","eeeeee","e0e0e0","bdbdbd","9e9e9e","757575","616161","424242","212121","eceff1","cfd8dc","b0bec5","90a4ae","78909c","607d8b","546e7a","455a64","37474f","263238"],"simple":["ffffff","d4d4d4","a1a1a1","787878","545454","303030","000000","edc5c5","e68383","ff0000","de2424","ad3636","823737","592b2b","f5d2ee","eb8dd7","f700b9","bf1f97","9c277f","732761","4f2445","e2bcf7","bf79e8","9d00ff","8330ba","6d3096","502c69","351b47","c5c3f0","736feb","0905f7","2e2eb0","2d2d80","252554","090936","c7e2ed","6ac3e6","00bbff","279ac4","347c96","2d5b6b","103947","bbf0d9","6febb3","00ff88","2eb878","349166","2b694c","0c3d25","c2edc0","76ed70","0dff00","36c72c","408c3b","315c2e","144511","d6edbb","b5eb73","8cff00","89c93a","6f8f44","4b632a","2a400c","f1f2bf","eef069","ffff00","baba30","91913f","5e5e2b","3b3b09","ffdeb8","f2ae61","ff8400","c48037","85623d","573e25","3d2309","fcbbae","ff8066","ff2b00","cc553d","9c5b4e","61372e","36130b"],"common":["000000","FFFFFF","7F7F7F","a1a1a1","C3C3C3","c40424","880015","B97A57","dba88c","ED1C24","f75b63","f26f9b","FF7F27","f7ab79","FFC90E","FFF200","cfc532","EFE4B0","1ee656","0c6624","22B14C","B5E61D","5487ff","00A2E8","99D9EA","3F48CC","7f86e3","7092BE","720899","cd55cf","A349A4","C8BFE7","ffffff"],"skin tones":["ffe0bd","ffdbac","ffcd94","eac086","e0ac69","f1c27d","ffad60","c68642","8d5524","896347","765339","613D24","4C2D17","391E0B","351606","2D1304","180A01","090300"]},"frames":[{"name":"","speed":100,"layers":[{"id":0,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAExJREFUWEft1LERACAMAzGy/9DOBCncUYgJuI/OkyTvkzc+c1xCmYuoMsq088UMM8y0BZhpi9kZZphpCzDTFrMzzDDTFmCmLWZnrmIL7qWLmCXUhAcAAAAASUVORK5CYII=","edit":false,"name":"Background","opacity":1,"active":true,"unqid":"ynvcrq","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":1,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAgxJREFUWEfNmNGOQyEIROv/f/RtrhEyjoOgfek+bVLF4wAjbfv80V/7heV5nkftb61dxb3ahBB8LvKdQh3BRBAGgGA3UCWYDIJTdQu1hckgVGmQIs5ZUUrCHEJgDC/oG6gFxkA2UvfbBo3UP8v24n4s8gmGQbLbjUBTe7974ID+GYMbLBR+51hgeCHdtAHwu1f6jMV91yqV8BIIz2lack63VzAIZf/juiWtDGhKKhgPrtJE0kpl2HeiOC9UpowB7jqj3xxU8z0VECiPnvWtMllrn75nu7pJYawws27iNubO2bX4gCilaWlXUyM6ANWq+ky1Zl6YSu1MnULPg3TmEddqpaxMD6bqJ0ofqLNchDztHAYNTpld1DnWZeTGmMk7GLZ8OMCt3nKPBc3rBolZgqWnniayc3ZazyIUYlRDk5Hi+mpr+y1I325SBkot6jD8WFoMXv8TDD+Cu+ADQL3qx2nyDZZveKVDZdQIYe1spniUJkyBcFlveRF0KkhWBou67MBYuDwAWdXi3BPdlHtZzDFpN/lkBo7q8wk/C6pmhpqVWSmGUYqwd6gZd9PakxNv5ho9dqrD1CMZtaoo9mkG3owT8wwcvUU8GginValNITid4Ze4kwELnwMs2kTl5ez0620FSsHcfMVNYaA23EnFdM+CTG9U0F3LnjJMBgWRJxs4+VnkGEZBKVlOIGz/F/AshkJzdMK+AAAAAElFTkSuQmCC","edit":false,"name":"Layer 1","opacity":1,"active":false,"unqid":"eiymk","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":2,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAi5JREFUWEfdWMF2wzAIS/7/o9NnD5iQBU7THva2YxZjIYQgPY8/9Hd+guW6rkudP8/zUdxHhz5JoDvbgvHMHyYq73UyFXslGAVkBPIgVYnazK16GAffb8EAI+M918c5gLzLFjByVOxIMMgKatQBYODjOCKGYsuYnIkYI5MMxU4Jhi92OvE5MeevpA6DSwPrOKfYWcAoVvDwuJGCzUeGRLa6YCTYsXjzvARTlAOzQaqDNNNV0hc8s+r84FXsJDAVK6h4FiJoAkFwU+E98xoq98oMdgkf8GxYiMauX+CAsGzMfqmdpRMqPTSsxcWdoXmNVAO4yBOYXadw64puwqwrCUz2VLkXMIU5hQZ4NhYJhNiTw8L8VF6VhFUYE3dLmFenq24sKCOdDQaHEnXjn4Xtx3PKTrKxm/BY6q+C2V28+X9mhsrEzISPeHlUmZ4AMnZ+wXhJCkNCm58gcVZxue4AEmdWMMiO8g0GokywsYClK93XhpOXptdM7WCmGZiJHF7UlPATmJ1DclmEv6Quo5kVLscJIPt3B6Wy/DTFUWtCMwub20HZseMXqN1EuGmsqL5CYIPcWiFw4RB6WJjAoLheMjO87Yl9SS9Xih27NPlOMQqWnaaadTQSejBMZeMrM1D36dKtDVa+GkzDzsREYpVLvYEPcywYcrb3YJwd0sBb301qQoOGUuguq+QNdqp9fzMG4tvJNcjvb4N/83t7t5ZuwdwZet9653+A2f0K8eQHoxeuA2tCWhaNlwAAAABJRU5ErkJggg==","edit":false,"name":"Layer 2","opacity":1,"active":false,"unqid":"eiymk","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":3,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAh9JREFUWEfNmEuSwyAQQ8f3P7SnIIgSQg0NmcVkk8SB9EP9tZ+ff/R6vmF53/d1+5/nufrfo01svBmcYJjvFCoFIxBWzALBgtxALWEiCPVOgRDjHfgEysJkIWBRYfg6PmegBpgMhHMFYPCbUy4DNcEs/M6xUvbV4EWsaMwExif3cZCrm7oBI3VdC/VYBVUGkOXdqaXXADTBQGIpFdadDMHKGDcNSirkEoZAnqKEqxftunVTA+sHCNSsgLzWKtNgAKKxUr9HMALSiyIrTmtyMBKQXeYSBkkYgEzB3k6XVybIjkF6FzORMpR5gPsbGLjIpTZgeA2nOfW0a5hdNvRAhhtRh9p3rknXynCs1IxUVZCmGmNGGc7MApdXhk7IVbOkeYdyRU3LQltTQfC5qXYNw3MLgng3y6AE9MNQvbpSxkHUuNXec9DTsP9IGXeyqdFxRWS3cX/S61d1xjTLcIhaGQ8Gr70yyJjVKVWN1ffNKLpuB1on3Kmks3NAD+kbjaJsI9sorUuCEWNopq5LG5en3BQGLoEMVZQDUtw8NFiFlH716cD06p12t5HTW/7DFbidyp9KOpB8BqlJGQnmYYRYgNgyEIyhHiZbK4I72wqwmnu5BJSKzJOkuqkP3FkoUfekMk+2pwvQ9vQeivYN6phiGNoMfziBGvKaHkBk7iKHvdlqulPq25v+KZsyYKsnEqdKqL2tmyLA6EER1p8+myn7fgE8c4RCu8Kc0wAAAABJRU5ErkJggg==","edit":false,"name":"Layer 3","opacity":1,"active":false,"unqid":"eiymk","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":4,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAiZJREFUWEfNWFEWwiAMc/c/9Hwg4YWQdgx+9EcdUEJI2ur1+aPXdYLlvu/brb+uayvu1qKTA2RrUzA4+eZBh31BYsZaCMYAOWGxXucToBQMGGFprLJU1jQWBl1lgCwYZoUWM+0ZS50FPQx/d9cVgpGFFUhgnjpGwbvJSgxdw88U0AQmYiVgqOJQfbUr6gcomwZz6nOAsmAMK1gUObOPM2g9gBtjVgcwGSskxrIGoqyfdRN3xTiFspaC0UCifptxsUHCCg5t9TRd04JWekDoBGIEa0Yrg4AjU1gwmRXFMaqd8MRavzLmu2aaqjlLTmI1Nu36cVrQAyj7mndYwJqyl+vhg0tYZ4MrWWvlqgYwWVJ7Qubop/DKYHchz5mYedo0GzcW5zQwJEFNCTWJU/Dhmt6AcsLPCiW7r+nq95aBWanQLsuS5RE+FHp0Ta0W/vTGQJyWdNy1G1EcKZbVwYOAA2tzgQtLR8HeKLBXrUZBBxBaG2CiiU5DUomXUr6rZchHQ9IDraIDrezl9LY0tOerzZW6qwfFQOkteFLFpyI3LEGgtpXg+UExrXsstRDKhLYQbxhhUWs/vNpcQfFR+kn14q5fmvyZGfa22o/bBkFkc9WT1WHntO0EoKBb61ZnQFGNi37q8PUsgQmctVwlTDlwxXKIN2kGo5p3llG0iWCL4yCHIa9ozBSMpvO3gHR+9mtysvbpZqfrQ2ZOA++s3wYT/VEEEDt/GH0BxdBvQrBEJaEAAAAASUVORK5CYII=","edit":false,"name":"Layer 4","opacity":1,"active":true,"unqid":"eiymk","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}}],"active":true,"selectedLayer":4,"unqid":"m1fr0o","preview":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAY1JREFUWEftWNEOwkAI8/7/o2dmhmFcW3rTGB/mk0bkSoF259i2bXv8yWvcYEgnLGbGGB830pmGFkwAcZIxxG4OCQYlcVkK8DVeFdWCQUllwqOle0wtpmOIgsk/7JLk9uyxuYAKPH9f2yrBoKSKdqcAVRgEU5Oy/kdlDHT9nWJsz0XBqAMU2DoriEnGzgSGHfRCTvQmADgMyXmqdrAygCjWKQZt2tSm1VWMmekKqNu2f65sQjBqWJG+OBs0rfCx/lPx0SbGimNKna6grUPsvAdYiZEDCM2KYi3OO8VUZpyDWcyKSMLhZ21aAYVa3BnlMhimKxkoUlnYAmKgsE0haq5LZ6BMN6pQtqKYRW9FL5jGxJY4D1p0tXMVqlJ0CCsCbagqGHpTpxsrJpqZ6gTyJ0bJBn568EL3po72KwLHGDr5FgOT5bq+r3PTbQnaVOhz7Eap2EG0uwvAHqwm11ZW362su+rKAy9dVRyrYMqsimrBuIwogFWtqSB2/0I4/uQw5RTV3rXdg74Rd4NhLD4BqUiGtstfWkUAAAAASUVORK5CYII=","width":"35","height":"35"}],"currentFrame":0,"name":"Untitled","preview":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMA/sfR5H8Fkddasdmnacvx//8745jkhasdASD945kjknhj/AAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAY1JREFUWEftWNEOwkAI8/7/o2dmhmFcW3rTGB/mk0bkSoF259i2bXv8yWvcYEgnLGbGGB830pmGFkwAcZIxxG4OCQYlcVkK8DVeFdWCQUllwqOle0wtpmOIgsk/7JLk9uyxuYAKPH9f2yrBoKSKdqcAVRgEU5Oy/kdlDHT9nWJsz0XBqAMU2DoriEnGzgSGHfRCTvQmADgMyXmqdrAygCjWKQZt2tSm1VWMmekKqNu2f65sQjBqWJG+OBs0rfCx/lPx0SbGimNKna6grUPsvAdYiZEDCM2KYi3OO8VUZpyDWcyKSMLhZ21aAYVa3BnlMhimKxkoUlnYAmKgsE0haq5LZ6BMN6pQtqKYRW9FL5jGxJY4D1p0tXMVqlJ0CCsCbagqGHpTpxsrJpqZ6gTyJ0bJBn568EL3po72KwLHGDr5FgOT5bq+r3PTbQnaVOhz7Eap2EG0uwvAHqwm11ZW362su+rKAy9dVRyrYMqsimrBuIwogFWtqSB2/0I4/uQw5RTV3rXdg74Rd4NhLD4BqUiGtstfWkUAAAAASUVORK5CYII=","palette_id":false} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d8.pixil b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d8.pixil new file mode 100644 index 000000000..4f7ff440e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/d8.pixil @@ -0,0 +1 @@ +{"application":"pixil","version":"2.6.1","website":"pixilart.com","author":"https://www.pixilart.com","contact":"support@pixilart.com","width":"35","height":"35","colors":{"default":["000000","ffffff","f44336","E91E63","9C27B0","673AB7","3F51B5","2196F3","03A9F4","00BCD4","009688","4CAF50","8BC34A","CDDC39","FFEB3B","FFC107","FF9800","FF5722","795548","9E9E9E","607D8B","ffebee","ffcdd2","ef9a9a","e57373","ef5350","e53935","d32f2f","c62828","b71c1c","ff8a80","ff5252","ff1744","d50000","fce4ec","f8bbd0","f48fb1","f06292","ec407a","e91e63","d81b60","c2185b","ad1457","880e4f","ff80ab","ff4081","f50057","c51162","f3e5f5","e1bee7","ce93d8","ba68c8","ab47bc","9c27b0","8e24aa","7b1fa2","6a1b9a","4a148c","ea80fc","e040fb","d500f9","aa00ff","ede7f6","d1c4e9","b39ddb","9575cd","7e57c2","673ab7","5e35b1","512da8","4527a0","311b92","b388ff","7c4dff","651fff","6200ea","e8eaf6","c5cae9","9fa8da","7986cb","5c6bc0","3f51b5","3949ab","303f9f","283593","1a237e","8c9eff","536dfe","3d5afe","304ffe","e3f2fd","bbdefb","90caf9","64b5f6","42a5f5","2196f3","1e88e5","1976d2","1565c0","0d47a1","82b1ff","448aff","2979ff","2962ff","e1f5fe","b3e5fc","81d4fa","4fc3f7","29b6f6","03a9f4","039be5","0288d1","0277bd","01579b","80d8ff","40c4ff","00b0ff","0091ea","e0f7fa","b2ebf2","80deea","4dd0e1","26c6da","00bcd4","00acc1","0097a7","00838f","006064","84ffff","18ffff","00e5ff","00b8d4","e0f2f1","b2dfdb","80cbc4","4db6ac","26a69a","009688","00897b","00796b","00695c","004d40","a7ffeb","64ffda","1de9b6","00bfa5","e8f5e9","c8e6c9","a5d6a7","81c784","66bb6a","4caf50","43a047","388e3c","2e7d32","1b5e20","b9f6ca","69f0ae","00e676","00c853","f1f8e9","dcedc8","c5e1a5","aed581","9ccc65","8bc34a","7cb342","689f38","558b2f","33691e","ccff90","b2ff59","76ff03","64dd17","f9fbe7","f0f4c3","e6ee9c","dce775","d4e157","cddc39","c0ca33","afb42b","9e9d24","827717","f4ff81","eeff41","c6ff00","aeea00","fffde7","fff9c4","fff59d","fff176","ffee58","ffeb3b","fdd835","fbc02d","f9a825","f57f17","ffff8d","ffff00","ffea00","ffd600","fff8e1","ffecb3","ffe082","ffd54f","ffca28","ffc107","ffb300","ffa000","ff8f00","ff6f00","ffe57f","ffd740","ffc400","ffab00","fff3e0","ffe0b2","ffcc80","ffb74d","ffa726","ff9800","fb8c00","f57c00","ef6c00","e65100","ffd180","ffab40","ff9100","ff6d00","fbe9e7","ffccbc","ffab91","ff8a65","ff7043","ff5722","f4511e","e64a19","d84315","bf360c","ff9e80","ff6e40","ff3d00","dd2c00","efebe9","d7ccc8","bcaaa4","a1887f","8d6e63","795548","6d4c41","5d4037","4e342e","3e2723","fafafa","f5f5f5","eeeeee","e0e0e0","bdbdbd","9e9e9e","757575","616161","424242","212121","eceff1","cfd8dc","b0bec5","90a4ae","78909c","607d8b","546e7a","455a64","37474f","263238"],"simple":["ffffff","d4d4d4","a1a1a1","787878","545454","303030","000000","edc5c5","e68383","ff0000","de2424","ad3636","823737","592b2b","f5d2ee","eb8dd7","f700b9","bf1f97","9c277f","732761","4f2445","e2bcf7","bf79e8","9d00ff","8330ba","6d3096","502c69","351b47","c5c3f0","736feb","0905f7","2e2eb0","2d2d80","252554","090936","c7e2ed","6ac3e6","00bbff","279ac4","347c96","2d5b6b","103947","bbf0d9","6febb3","00ff88","2eb878","349166","2b694c","0c3d25","c2edc0","76ed70","0dff00","36c72c","408c3b","315c2e","144511","d6edbb","b5eb73","8cff00","89c93a","6f8f44","4b632a","2a400c","f1f2bf","eef069","ffff00","baba30","91913f","5e5e2b","3b3b09","ffdeb8","f2ae61","ff8400","c48037","85623d","573e25","3d2309","fcbbae","ff8066","ff2b00","cc553d","9c5b4e","61372e","36130b"],"common":["000000","FFFFFF","7F7F7F","a1a1a1","C3C3C3","c40424","880015","B97A57","dba88c","ED1C24","f75b63","f26f9b","FF7F27","f7ab79","FFC90E","FFF200","cfc532","EFE4B0","1ee656","0c6624","22B14C","B5E61D","5487ff","00A2E8","99D9EA","3F48CC","7f86e3","7092BE","720899","cd55cf","A349A4","C8BFE7","ffffff"],"skin tones":["ffe0bd","ffdbac","ffcd94","eac086","e0ac69","f1c27d","ffad60","c68642","8d5524","896347","765339","613D24","4C2D17","391E0B","351606","2D1304","180A01","090300"]},"frames":[{"name":"","speed":100,"layers":[{"id":0,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAFtJREFUWEftlEEOACAIw9z/Hz0foBwWTdCknomQUibbHo88MUyxCchUikIGMml84QzO4ExKAGdSYkvOSGrLnrbGO2oMwzUdX1P6wc16BEbg1CecwRmcSQl84cwEPw2PmDu06wcAAAAASUVORK5CYII=","edit":false,"name":"Background","opacity":"1","active":true,"unqid":"f9mfzy5","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":1,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAhRJREFUWEfNmFtu7DAMQ5v9LzqFDUugGephX1yg/ZlM09jHFPVIn59//Hnf9+Ulnud5bpa9esg2MhDc29hugK5hFAhAzstToCuYQpEJMhT67zCRImidEbabcB0pI0DG8x8Pm4dOgdowDAJhcBhSxMPV9U8Jg8cWJ0Z/eDaDIkdAKUzgDw8NK7HUYoC2f0KYBGQmy8hc84tS7EadFIY3sTislJ2V19TgT7u3/NIKl4QZqmT+sA3o9LyWwzJQVH8+MAgyQgHfZ1iUGqgC9qQifJ+9t18QyDzQWtyaoQMxFJ4+ClFVfxyGFUGTmlkjAMwiVCaqRQTrDBIGFkdlMGRu3LW5KaY+LfswxWX/CmFAdgylzy4ILMK7bRYlBLeL0DNcJxKPzDVsQ0xxaANbXYqyK80mBOJrGuY2haEeoYX8Wqw1n5cwqlCJ09jzn7GTTayIMLOs7pRFj9NUhc/qkZTBHB6MxTiEhTBk4NmqsDHebqxUT5VBQ1LqenpWvmALQOPdBjJsDe2uHRU2gN1GvuBthVvKtn8IY+qYrCpMa0MvjFwsaQzZQCDtPeIpjAgXFjPMRpVRYZNVIDK12ZjRa0mhSjV8SRFKZThcBkshqZRpjZ4tGAWUVeSbkbMVJqqmUwFRPfF1ZZuBTt6d2spAeDagbAA7ATlWpgE0I0otpH3g9h92sgzNHaVv2kaym9W9P/P/mQr05v4vDlEtQnsbdYsAAAAASUVORK5CYII=","edit":false,"name":"Layer 1","opacity":"1","active":false,"unqid":"rly08e","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":2,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAchJREFUWEfNmNtygzAQQ8P/fzQdezAjhGSv3DwkL02L8R6kvZgenx/6HDss53me7b7jeN9+XWrX4r3jGxpEgxmxRnCE2wWKYYwqbZ+u1vjsAG3BKFUGBLqTAkUwqAoEUmpsKRTDoCqr76llZRinCiewUuxK+s42q7IIxinB+dKAZmsdUAlmpUoLjIq47yuFyjDqSZvqomkO9oc6lT60hJlU0HFHBSIu+6EaN+TLykf8EswqV1gdo2K3kq7VYVJVEIrzCMsc1MpgXK6osbAq821lZqrgCGKLuM+o32NleDJDAvbEvXpFG45jSPafNI9kZZVhsEKE793j4DzTJzn3nTKMOq+oCmAbCRwT86XOAORO/CrtVQVdYA+FqIrGnn0r1XcimEpfmQ08tpqtimHc9BXtv/QnVfYlm9D/UqRwUTmB3WE7jGeXR+NgVrbfAnJnYzkoK60ek9JBugnuTnx2as+AOKdUN1Z9yFXRfVKcSa9KFKcvHTfdWLhDrF5dlucZbP94WlO9Ax8MGx6ttTFLMKDG6x3b9KPHG+ZKkZJNykJnnXrnriqyDcMqsXVslasc9aCRTTtKJf8a+TeMUgqqLNo/WvytDuz2+QMl8/wzbBarJwAAAABJRU5ErkJggg==","edit":false,"name":"Layer 2","opacity":"1","active":true,"unqid":"tqny2","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":3,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAgdJREFUWEfNmEF2AyEMQ8v9Dz15UOwnhAyGySLdpZ2BH1kWpuXv8ud5nodfLaWUy+Xaa1cvGwjubWxvgI5hFIip8RboCsYUgc29Om+AjmBQFbQMW+UWKA3D5WH/dqC6XjP2DVAKJgKpAFSqUp8VZUzts31oBYLGjXxE5VzudwTDhq2fWR37XY8Nz6JM2ZYwB+Vp5SLf2NppoBBmVx5UxdSBrmrewTTGMkbBuIRZ5Am/53sLU7PJTcVpbwmj8oTBFt8aS2ZHTluyK+KtzwpNMKo8ycRlCAfp4NJDCDTAbHwyZAgqs+kqhLJQHMLRgCaYhE+qzLwoL95YqTSuDHTe4B+H2fmk0mO6CmUaEG5E5el8/02mumuACVRxCAw9au3hW9tmDBaEpjNMMGosYBXsM3XDEG4qmSNFfD04X6YDToyVu6lyKpUaNaKjQZaJdxTj7vAI5geND1PgkbHHdVAZlhE/nwIK37hq/W/rBKac8fNFnCXTzQAVAU+hHcLknTyjvMNjADzjQgFoCJgdtrbHgQEJ02GmTK3NZbqeZ8R1BLvE05Z8JBMW1dzdqY7mGTE8hercXPCOJz1uY1BHHgeZ8oQGFi3cjLkbIzZD1fJLp2F6yw5AdkdXUZDtHBXlKeIFkLXzMDidlAah0jArhfqC1zfJozIh/U/9FyJQ6Opuzb45KpMy3Td/9wFxxy9CEK7yBQAAAABJRU5ErkJggg==","edit":false,"name":"Layer 3","opacity":"1","active":false,"unqid":"rly08e","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}},{"id":4,"src":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAcZJREFUWEfNWFsOwzAIW+5/6E6JAmLU5pF10vYzqXk5xmDa8fqj3zjBcl3XNdeNcV++h+ZYe+/2Ag9EDrfg5rOfgwkYmZdabM3fKTtlZhAQy4oAkeicsFMCEwGx0jCMHLGTgmGh2TfXsDhG7PP0DGU1yqYIiAjWC/gbdihqlDXs9kQvbXYgGJa+Ewy5eeV5Gq7bhAiIS9sVKRDmleJAU2dgfPGUjS0rFpgFtIud3GlV6WrdgcwgbaDbMvGfZhYFY2n24UHF7gl2yswg4XqzdOFoa6fEDNMKMWa7Z0s7J2CGyzgxSf2f4yLkTmalYDwrM52b/UyZnVAzUV2xgEDqr303Q8y/bmenAgZNkxY7vbJJJdNUreFO3WmDMT6U+lrXs0LN+M0ih6+M+fLgW9MSmMpBnTliEWUwzHs6h6K5UVuauva3h6P1zDjTfqbi1M6XNJWR5iIHDzPCuy/wno+qaw8HxTJtJdL0ZN3/bqymGS5A6GVOwLkxembYfbFXlOS1VqNWBaGMZgIlPiTh+dAHYTFtN8tgxGNY75I8LwNRj8nYYYDsum5IYA2qADFCvH0KeQJEK0yOAf3aYFK5FQ5GwCObdNiN5r4BawL8M515sSoAAAAASUVORK5CYII=","edit":false,"name":"Layer 4","opacity":"1","active":false,"unqid":"tqny2","options":{"blend":"source-over","locked":false,"filter":{"brightness":"100%","contrast":"100%","grayscale":"0%","blur":0,"dropshadow_x":0,"dropshadow_y":0,"dropshadow_blur":0,"dropshadow_alpha":1}}}],"active":true,"selectedLayer":2,"unqid":"jv591w","preview":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAYNJREFUWEfNmEsSwjAMQ8n9D12mzIQxqmXJbhew4VvyoihSYB3Hcbz+5LbuwKy1LtO4M7cxzAaJg2evdUS/DXMOdgKhShOFRjCVAhGqCzSG2QNlg0+B2jBRFfV4+8VVaAQTVUEDZ4ptXykzt2CYEnsQpZRSqA2TqXJCOK8rhWwYpUpUB5eKPcdla8Ewr8QvxW2/VXNyyIJxVam8g+GY+ceGcVRBhVgWRY/9XKOKUqnCAg5N/YgybKecX161duadCNReJkeVXZLxXu2s0TJVqihl4vvotzaMUgVnTweAQKz6iu4mJ1WrrsF8cYIvhXFVUcXHlorVAoVh7esAZJ9h7S5zhq3/FOTSQcFHFoxq2ClYeWRlCZwF2hQAr2PnmrKbqqh3lGMNziYlizIDyjwVt3Jm1mp5vpmlihKPBVloIUhWkpaSLkwGVW1//GGnzr+fTOrCYCdVZ5Yq+jPfjGAqlRissxNvwTA/dRVpG9iaWfiLxPHIJZknnnHAJp95ZJkmA2fXvAFTp/+nAJYHZgAAAABJRU5ErkJggg==","width":"35","height":"35","old_width":"35","old_height":"35"}],"currentFrame":0,"name":"Untitled","preview":"data:image/pngp98kjasdnasd983/24kasdjasdbase64,iVBORw0KGgoAAAANSUhEUgAAACMA/sfR5H8Fkddasdmnacvx//8745jkhasdASD945kjknhj/AAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAYNJREFUWEfNmEsSwjAMQ8n9D12mzIQxqmXJbhew4VvyoihSYB3Hcbz+5LbuwKy1LtO4M7cxzAaJg2evdUS/DXMOdgKhShOFRjCVAhGqCzSG2QNlg0+B2jBRFfV4+8VVaAQTVUEDZ4ptXykzt2CYEnsQpZRSqA2TqXJCOK8rhWwYpUpUB5eKPcdla8Ewr8QvxW2/VXNyyIJxVam8g+GY+ceGcVRBhVgWRY/9XKOKUqnCAg5N/YgybKecX161duadCNReJkeVXZLxXu2s0TJVqihl4vvotzaMUgVnTweAQKz6iu4mJ1WrrsF8cYIvhXFVUcXHlorVAoVh7esAZJ9h7S5zhq3/FOTSQcFHFoxq2ClYeWRlCZwF2hQAr2PnmrKbqqh3lGMNziYlizIDyjwVt3Jm1mp5vpmlihKPBVloIUhWkpaSLkwGVW1//GGnzr+fTOrCYCdVZ5Yq+jPfjGAqlRissxNvwTA/dRVpG9iaWfiLxPHIJZknnnHAJp95ZJkmA2fXvAFTp/+nAJYHZgAAAABJRU5ErkJggg==","palette_id":false} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/sources/flipper-screen.png b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/flipper-screen.png new file mode 100644 index 0000000000000000000000000000000000000000..af759a20f83ec07bd7511f95e27ac20c58d4440c GIT binary patch literal 30526 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 F{{V>x!UF&R literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/sources/main-screen.png b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/main-screen.png new file mode 100644 index 0000000000000000000000000000000000000000..20a4e9c2c5ace8f92799da3e1cd81afc2de066af GIT binary patch literal 2583 zcmb_eX;f3!7CwL)ho{uKSVa)1k81nKvc+0NzyvMIqzJ_!OhGGx3lKt$fFZ=BY8~o; zv_?@$Kol7=pu`9!kWgKWB?+J;iy;J+F$oC>Nl4;N9<=W*FYovJao4%`uC@31zVCc{ z?{hg~U(m|sPRjuRD?@^JMFLpW7u%rAp z*M<|MXLvcQgg*Po=`A)(1d-pOTFa1Cov~U33>lY&c+AjPZ~Dgcj!qmITBpeozvOKu z9Wb0sI*ixr{1ncCf2W)WkWzstUS(+|)HY#NmZJJ9RW0V?=vH3+KCgutiwB_OQnyJd zzWQjQ#>$4AEA!TeWzwKFohV6B6N_tD`ceBZ1E5FRv*PWJ4LkB^3~`cqFGl}#roQQ* zc4hpN=2Oy!W%)SVuDmx$^$T(-@ub~otT6!ePPW=-#vqo2W}pmhyc-Po@_ zv&S{2tF5}X53qPEqe`dNg$e}jUJ%DBd> zoz&^-APc$IDEu=xja2IGX%;wG%kWiGEim!Y`s|BeQ1MpDsq$AFqAKb&%H6DfoI|Rt zu9a=HIN&EG{apJ=s^K!sLA_GD)1f5%v9uf1Ost1~$?4ybGDwlh%6mOy;8lBf{J8Q- zx*{9KsN3X2c|bJ^-MtQT<*I{4qxq@zDxD-nBu^2z9FWam=+3p(QpFqeW|*J*asbk6 z1}PJ3A{60_6;)09eaxG3b41ydavnbz{aPT;OccVwS@l5GP@g;HUrE9NEep?pOc2L=hEED^;PZeO8%;v5? z*a^f?Y(Y3p+lsyVvGu$@Wq%|~e5TR$xx;i?cDLC>x}H!{Cdp&pia3nsyua6xhNbmz zDLlBQ0VoPq^^-Q{RYGF8m}+qO;R${ARsA?;k{Foswp-}zKtJ6c1Xn0|Q*pi*R8?qC zl)2g=Gp%LqpIun)E_6m#5lVX!G?OH681y|TN`8!9J#E8JAuBBzRs1su-df{z#j{(T zo3zUtCg$48Up;__@Qf9*j!RCIKYoBsO<_eD)1sqSjI{}hVTLo6 z$Kw+cNpxyV)NWQrqWzE<|MUG`wwWw5Wb27BQ&`R9y(2K4Z{>jFZ00%b-7T?Gg6xTK z5dPCJ?uFVg6~?t}fzhk1Lu4c+hJD~mP5uc2fAv8KRXNs*n&RW&$@GiRoYeS<9;-0b z4a+@K+th+^Gn&tNA0nRceR2RMZWA&ZjpXm3T+g2L&I8?WpW>Z3uEkyyKg!yk?#`#|U-)7yXUvweGoruPK z*tGo@m~dToM_TWt49oRJ+j3qJ9@)ccvJ}zqG@bjN`p$>J$~IpOGTEq)!dTA$$1c`J zbR@#xZ^XO1LopLwOJ9(9@IVcZ{7b%M_NK3S|MlO|FlXL$1!eT=tzu@rX?BfjJltoW z2|lQDz(3|WW^K>@!EhXo))WzNtZ~igpZ@vNdlxT&y5so}!Q`Hccz$I8hT`))t9FVs z6be%~)Si+SsI<_uHCWOWEYaZ<8dG-;7G;{7wzG;gse{@BNF}BnHQ&6(GT3njtw;)CEY=pTqmP77e-mZAij>fp{r)iY${8O@ z53lQl3wcfTs0V$#d16OFwnRP!wzpWRLVwtiB;a4VKuygXp3PkK6U#` z*DbOF)=oZI&pWBTQDa#Jb6@#5mvTKxWyUEH>n3{fvzHIC&1{1_F&Wo=mgr}s-+|N) z5M?!o=v){*zMl1g^*{2@X{zTjmh_7Dn|$TlA)Z@iZH@fmVW{hy=WzMQZN7W|$fV8p tRT~C!e*@?Qc^?1( literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/dice/sources/roll-screen.png b/Applications/Official/DEV_FW/source/xMasterX/dice/sources/roll-screen.png new file mode 100644 index 0000000000000000000000000000000000000000..2dda26e59767e6f215eb0da7cdacce726919f379 GIT binary patch literal 2375 zcmcImdsGv57XAgcA}9}QsmjBwhqb4NbX8M~5_mBN=|CsZeIdkXU z@80`;_s)&j=!32It*TaV*jsxIezeRzytH+TS@w@DYbM~Ql8UX7yu3jimQMnm_ zwM&O1_Qx?Q=f?JPM}s}y>izurDx2Q>UlMMQZ2GEUP z)|I5<3zy#tugc1G2OQQ~z=?GLzx~?oYC8Z2od4gC1171{cl|B0m2#$4$j28&IrQ?k zfbjQGz~cx2SImrb-~1X?p|P;3ZPUcD?$?mw;H`3=f%y(H zXbq=Sn%qoUjx2dd$#IL~E)~&oa`yR+2pL(|SPlr+1IOK~@91O=VqC+A!UK5Do+0`% zYmu}-L%-FlBc^^hEukqres(z1LP*Qk1Q)1}02Q?puNFqQm89gvu(KcTpQD2Zsm zF~qCBrRrgUF|W#xFKzB|qxb{}(lxl+tCn}9M)DJ^kJMZmvyX(#LcCSpcPNuxyJwfB z)l-=Fg9M#jRs>sflVvgr_Kren!xGp0+Rs-d%1PFzUU0RQORF45ZyU?x*excn`uln& zbzVSTQH-^Mu;j_ULv#K|s*u9g~k50!Y63?!OgsFKc?@v}W zXYqF{T82eGJrmGb{;C}#PY@*$onBWrB6>h3{u~P(rHT2ub1Pc7-{7b_+4s_W$?}vz z(Crz1)6s(78 zPC}L3acfZFsp{4f?BbQiBFzJ>CLBqcCa3S3xyG9+2kow({*XJUW2@P5coWN5#o^&P zdDcjT?aB6cd!N$Sr^I=+JPP9yU0P+5!Uj*}x`llJbiEokc3Gs=v}-am`7WwYudz-J zSjmMNl5)WfzEO@4`OH@N$7~t1nCmH3&ESR&K7X2s!C1vZv>apndw!Bz7KA3WM73c? zD)=&`#4!o z%IWsCb-EEJ*of#~Zw38Pf?KlVEemn|?rED4O{;a1e?g@idGrFVu+W?kZbmgCb;Jaf zT7pS4b%TN`W^{$jbRfXapt3WJ%sgGKPWi!qd$e+R3vK6rU#%eC#UtJsZeM-s0xOd` z3hrG-u<~Dy)k)VZYeH#m7vIDd?o3}1Ucg=4j__ee92}FHSa?d4u7);->M`Sw5TMwj zSYR_fuE?T~tq8o#U9_vK)7o;Yb!Sb9h8eeq>&Wr`4;AhEske`3P!Tg18>7vOX8n#a zW5+BbXAC|6jxTrminZ-;2+vlPX`bzuB?RVf)Yf5Lg!H3Dg8`ig~A{VgjOc6Q{iXxL1q{1NmIdi7XoCa)P3Su zP80fKP1I7*m~n&$pIB(sidq#o_>B$wkHAY9m4oD;8#|ZZ!zjz^f)oFovph?mf<7EK zhovECbx-XOTG6DJ)uXcqnu6K2JUx2~^8WyvD4KW{jU$m(O!j$teTeK`89%eFsZEW* zVs8b9tCM`QEC`5W97(-@^M0ZJpf5MG^Etl&E*lMT1JvKWTKY^-+*WU6)wo$&TMG0C mxtDN@0C)gUzq;@XQ5zzLpKpkG`?3Ac2po=#ju0G3yZmqSl + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/README.md b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/README.md new file mode 100644 index 000000000..8c4e45ec0 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/README.md @@ -0,0 +1,13 @@ +# FlipperZero-Etch-A-Sketch +Turn the Flipper Zero into an Etch A Sketch + +This is a modification of the original paint app. + +![](Screenshot.png) + + ## Changes + - LED indicator turns red when draw mode is enabled + - Pressing and holding the DPad will continously draw + - Vibration effects added for mechanical feedback + - Audio cues added for feedback + - Smaller brush size for more creativity \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/Screenshot.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/Screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..6cc086ec958c7dacab1973f43b754dfc29027808 GIT binary patch literal 1769 zcmb_dZA?>F7(OiwghArRmaRZ5h8Zyn2r`(3BIpnV6lHG4N)Z@y9r9Hz1=@ljgbg+Z zA(P0LEr{C^11&;8Iw*FqfMY<{Oy?W&2w|l$@@O% zeV+F{WoKg|oE=>p0RYaCC&NAl0B!z6fgKwVr6&5A!GUs;NCjYb*2asHez7+f0K59g zuw$R(HY`p@XG{iyP|$3gOpmaAV^hAMDmy0&Jb38PVxDvnh zxBT8(eGLd)qytj&tW*{!Ov{~CltY0e9_-~&kn_2rLuSC8G3C_`?Evmk0Nk+!?!zvE z;%X?aax93eHMF5UHc4!xNd>WSP?xIqcPV30#8WqO@5E! zd?{9=*EDPTJs$eau<#zbh>3Puo_5`c>!@4{%I_OVw%&ifKAN9e5I%N>eINd*h3eKh zVRD@*-z2obs|7`=%L$Y)2bp+AhEbfVQpd0l$*eXIo{Fdg5sGx(lq+;wQ9_oz`K6E{ zs2=LouBk^Y$6KIkJ5Hf$$n&^!WR(*Ty1zmfvu1O2(CekUS7ah1Nhj_jj}rGzkCpS( zP0X9@<%uVRtEZor8Ah&$TSAIKMq9rd95n8y3TY3J*JwCaoTucp7#;1U!$=~SUfz!K`_WpnkrK10epyt>_ zn+v6QrGIO7!jG76=}Zsqdu#pE>aMb3jBa6k=Ah8FPg#?|8|^XLuimmydkn=3quxlI z`a^SkOo{=lV-^j~-rBO*b};OBXUak9% zZe7B}61?7J$jx{eDURHZOC64b?s5a{`JHTXJlAJH>`P!^1w_dQFUKDQbNT9;N|K-N z%n|lVP#&V$+U+RC!PLJxpvKBRZOfXtil;hoF{#4PlDwqJ53yF3l7%anB`KOUU7=rF zDqt3;q&xFBUO49mN(jc$ifmhoFnBqFlhUo$7gs?j(u)^Ed9#_=e3c*T)>%YLtkA`p z6QeySQsz8;-|O1+RTE~r>GOZDt;{T8S2rI03bdSVgkjBcI{LIqk430Nn{*MB<2zdy zxjqs*LiDqsVMLey>0cO3z2ZSliknPG;y7POSVS&g(Ypvl_|7V7rY>!W0sg+XZXK9k zI97L#+3BAXU|`_{hJ$$#2$OF#&{iM)2X1E{YCIs#gvty~StG`Z!9KKBf z-)MG}#Ujl0pcU0y=PT*zH=v~hJ=c-Ryzbip!3rXZ(dKYuQwO`kHP(E0fyfgvVVvWM GMgIUi;Dk^B literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/application.fam b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/application.fam new file mode 100644 index 000000000..64b7a0a8a --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/application.fam @@ -0,0 +1,12 @@ +App( + appid="etch", + name="Etch A Sketch", + apptype=FlipperAppType.EXTERNAL, + entry_point="etch_a_sketch_app", + cdefines=["APP_ETCH_A_SKETCH"], + requires=["gui"], + stack_size=2 * 1024, + order=175, + fap_icon="etch-a-sketch-icon.png", + fap_category="Misc_Extra", +) \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/125_10px.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/125_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..ce01284a2c1f3eb413f581b84f1fb3f3a2a7223b GIT binary patch literal 308 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 T?I80e8v&Rb+u+JDu3`TM+ZHm< literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ArrowC_1_36x36.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ArrowC_1_36x36.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0c6dd0cb2b7cb6eebb1507fa68a8dbda11b146 GIT binary patch literal 3692 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ArrowDownEmpty_14x15.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ArrowDownEmpty_14x15.png new file mode 100644 index 0000000000000000000000000000000000000000..8c6d54f9cbee1fa08f30d7d8d309fcf0eae24dc3 GIT binary patch literal 654 zcmeAS@N?(olHy`uVBq!ia0vp^d_c_4!3-oHpW<@^QfvV}A+G=b{|7Qd4_&SUQk(@I zk;M!QLM0%~crQ)90w^e1;u=vBoS#-wo>-L1;Fyx1l&avFo0y&&l$w}QS$HzlhJk_c zLS{%rNrbPDRdRl=ULr`1UPW#J10zFdh?}kj1E!3|#M((0^KL7Mw8gVtob5Y{ciZEr z1y!L*+oSYtLL-;F6-&Og;7UV-PF~zv@#-ae4;4hEUsjo}eeU6ZzUK$(OKl~Nl^<#j zv+)W&bYFkJ!h~4P{m*&xd{no6I(@M#|M+_8x;urJ4!%DBAZvkhe$_)siC^kZUj#T^ zdl`0NgZyQVrpZU%d+m_nKhXb7F60(hz!A?QhQ}5t6dsQ{cKe&KN8v1mJq{<84$Vkw z(Gz=+d$3^cTe%mz_SNpzaZ$Zfm9OE{ept~iW#hJf4aF9PIg3nso0N*qpW3V#^e$;t z0Qd2=CUIG;$7XD;dhgA#T(YWIZ*@$~EcIu*+?kCvIt_oh-!OUa{rlgVvN~P4d*Qp! zZWheYopUc*ujx-x3-8)B330c3ulZj#zL&rCdfsYYkINS9@>0i^N*T-hdtAO?{nREn z=FU}Bo|zG+`X1?MbF2)%c{X*biuqNo^Q%`y=)T^w%crZyCui-?ed4G5bG}bsn|AXe z-})^ZJ}rNdxAxt^%q*?v)rz0@?%8y=M*noASZmsa`g+@?O^wIi-rS{VF*|<6g9_<2 zf7vTDzg+!NYwQP10J@$ojv*W~lM{fTg^7(L!DZo!W3D$C(hg2JAY!oS!-O9_H#ACI fU$`~sG+tm3J;R{=vM6pJP$Pq-L1;Fyx1l&avFo0y&&l$w}QS$HzlhJk_c zVrEE0NrbPDRdRl=ULr`1UPW#J10zFdh?}kj1E!3|#M((0^KL7Mw8gVtob5Y{@phrj z;;PW>?NRzMp_xnGiY4D#aHXL^Coe8nyn4yrLj_UkmsO@~pL_V9@A-lHIzx$L+YdE| z*?5K?x^G|asIXh8?zGgU8D2S0t~ZPFx9>K!&#An4uv`B@%>w8As)v#iztW$+2ynXg zGVHdK%QDtj zoddU<9$MYDy%bvexh%57YsbfX0X^S;+umC4aa&zR+_llOX|f7e*NMFv=i5AXZeHo6 zE3^Gl#Y$0$MPDkdvSK)%Gbe*RMOz4@)|?HAcpI8PmDZ!27R?96fHOD12!EYFLG zZ!hI^X7jumIB8jB;FZd%y=xx**tP4_rd6lb>%CqRb*wVVCui-?b>gS|bG}diYje7< ztYT^FRC|~5(O2No3raw??{Y^3PVTzU>EZ z)icCw`?A5F(eXDh1z3B!IEHY{OiloT7A7{11eb*kCJ}ryPd6M&Rqzu_;!^IaOknJY s?cqo_P+H?E(ff=iBss+_DwdCiO;ROJI-wJ7l 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ArrowUpFilled_14x15.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ArrowUpFilled_14x15.png new file mode 100644 index 0000000000000000000000000000000000000000..fa35eb2f827bbf3b125673521e94c40ace83f035 GIT binary patch literal 3628 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Attention_5x8.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Attention_5x8.png new file mode 100644 index 0000000000000000000000000000000000000000..137d4c4d054227f27ad6a7e3e374b100d975d9af GIT binary patch literal 1690 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/BLE_Pairing_128x64.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/BLE_Pairing_128x64.png new file mode 100644 index 0000000000000000000000000000000000000000..34068c300386e0c88e45b40a8995b0a4360ed79f GIT binary patch literal 2307 zcmbVO4Nwzj8csqH!AcR^;-I$60s@0cc0(X!Ar(w8LGgNGFX7@NWA_5Fl{{xFJ*vX=x>q zLB{5ph;@1KiCA7HCda{LuK|%}gd;EzEDD$ndLx6F72qT!kIDckl#cziMcc(UP~}kwh1F* zws30t+O44xrHMdU%9Kb^`k9wXm{A#!NJODP;0Dr&Q#nk~GZzRI$`T6D{%S%~jQ7RKml#bMM2h3XaazGQK41?uiVM2)ro>W(>MKnf+MU5Dt zQ7J&qIUp{ zIp?wE!;2e(vR=`fGE00N(|8`_fMVLvgK}tE0)h zkVk2$NWzcKs9*Egvh>2TrrMjHq;zSzjeDiNPac?k+;Nj{%X|jg9Ay0y5tk@Htw3ATT`ta`*~H% zYe_H9zW>k1Ri}IQZ>);(2=qDpM%n&Sb0+Kq=eaeOtnjIekp77l^*k)AYTAt5>ALjg z+2T)qXky}Q!=soY-Mq&se4l^;{W38Ba{gd^uX_}D|75jW(}jfQPe!BKY)66FoASnv z75Sa(h8vC!EQE!v_vQ0D`5&k|^Q|o}ba=i}w#g-K$dE6u|Ln7SJEgVM(wZdWa7p$o zLE*JoRaK>`t~q_KYQKt&0eyc#I;-i(dpkztJ;~?sUp}dqR@R@pxF*DSw^hGn57pD~ zYLipcf$_+l9cLykomn#1*J^dXe0!kWgFkFr;M5k;)v$W+-x`jMkM_@trF1SyPre>E z9gO-$+zq2k%*zgP5c;N!u^=w_-D`mTR z#mt!ZsvlaOL|fjt6)d>!8+8;|IsB&67oP_=6uq=cyzA);t>r^|)q2}=SGuhweuIeK l-D+9gIS9B;cu3u!2$I*mZhd=eoz4E6qKS!DH7-xx_AmDMVyyrG literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Background_128x11.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Background_128x11.png new file mode 100644 index 0000000000000000000000000000000000000000..78ef029ae737fe82080bd709545aff7ccdae948e GIT binary patch literal 410 zcmeAS@N?(olHy`uVBq!ia0vp^4M5Dz#0(@)spmQaDVB6cUq=Rpjs4tz5?O(Kg=CK) zUj~LMHK5uS28Lfip@tU>45bDP46hOx7_4S6Fo+k-*%fF5l;8~T332`ZAIM?=k_T^V zeFCx=OM?7@862M7NCR<_yxm_V@sW8a-VcLnJPT z1~~E^P~d1jayNa^|HRIFrW60yr@Gu>&}-W^MJYtBAT;u{K+{9k<&Lvot+tTstUP<| z#4-;3vevG9_gAsjw(zVxqm%MWw{cQe@xAvG?T;szm0Xkxq!^40 zj0|-RjCBnyLkujfOih4D+rYrez+mCd+=VC_a`RI%(<(7Fm>5Dd_?7)q0cv3IboFyt I=akR{0I2AM5dZ)H literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/BatteryBody_52x28.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/BatteryBody_52x28.png new file mode 100644 index 0000000000000000000000000000000000000000..1fe56834610cb41c959a49f8fc0984829f8e20e0 GIT binary patch literal 327 zcmeAS@N?(olHy`uVBq!ia0vp^CO|C12qYNT{w$OQQY`6?zK#qG8~eHcB(ehe3dtTp zz6=aiY77hwEes65fItZejeiaPg*{{Si_^q49 z(b-ZJ2{c-@#5JNMC9x#cD!C{XNHG{07#Zps80#8Zgcw*@85>y{8)_RESQ!{B-o0}o eiiX_$l+3hB+!`)DW7Gv|VDNPHb6Mw<&;$UHx?2bU literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Battery_16x16.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Battery_16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..49af3c2259a086ca262876e062c1ef2cdc99c285 GIT binary patch literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^0wBx?BpA#)4xIr~Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZEE?e4qb@eTvkfNuHV+hCfRdP`(kYX@0Ff!CNFxEA+2r;m*GB&g_G0`?Kure?Z hC{)ow(U6;;l9^VCTSKDGoC!b;44$rjF6*2UngG10Ol|-G literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Battery_26x8.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Battery_26x8.png new file mode 100644 index 0000000000000000000000000000000000000000..5fc1b0cd6d93a694ee460f7253bac4fa368285c2 GIT binary patch literal 313 zcmeAS@N?(olHy`uVBq!ia0vp^Qb5eX#0(^7S+So5QY`6?zK#qG8~eHcB(ehe3dtTp zz6=aiY77hwEes65fIC7!;n>`$46IoXB1>;0Aig%mtp978y+ zCkybhHVLq?v9l>8v|MBih+^pFYgpao>z40R2Rbqy^;3@ofnEv-xpwG9lc3=G7b1=gZy$jwj5OsmAyU~B}@5No`9Do_K1 Mr>mdKI;Vst0P~nnl>h($ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Ble_connected_15x15.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Ble_connected_15x15.png new file mode 100644 index 0000000000000000000000000000000000000000..64dab9b5307410bb10fd7a6634cc35ed88af4671 GIT binary patch literal 3634 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 X0xtk%_Z)B;2L)JL*qN7_d0hG*G(b{c literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Bluetooth_Idle_5x8.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Bluetooth_Idle_5x8.png new file mode 100644 index 0000000000000000000000000000000000000000..dc4a8733cd2d2bd2f980f1b9cbf6bd58e55526d3 GIT binary patch literal 79 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c2qYLJyEvu+DKSqM#}JO|$vX}{IB3xLkVU|c cVN)IhgZc!Pk4&*=ia{zpUHx3vIVCg!0BRQ#5dZ)H literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonCenter_7x7.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonCenter_7x7.png new file mode 100644 index 0000000000000000000000000000000000000000..a66461b227b321f11bc85a38c63afda0d982d78d GIT binary patch literal 1440 zcmbVMO>5LZ7>3B0UTd{6LeL$!>SMgR$1#+OC>f>WbBi&Q4}`hi)=4nY!B^ zRS++F@uGMUJb3aT=s^*^`ByxtKS0pQengRK)xc!Fo_XHy_wM4t+~~;u5yLP>tMip5 zJ#SCPj;;EC7QMf%r=8LK<-{;{ji+Oa@#yhB!`QZ0)RxtQGk2+A_%pkO15A>@E!$;O3zzJQJa2RR6$Nr)W_ z7YND|Tm*y9)Y4+VL6$0~2eS0eHCswW1j0_IV|Q}4jGGXbN+pOK=s1=}Sjk$bXx9pp z14D)iPgpD>C1eOvMp~Dv$~Cp7eG`HxqYaaRo3z7VmqrlVC^e}E^jU_BR^xV0xX&PO z^MHpc(O8^ewU<0EgKtP11Q|L}vp2Lx1KT!4C$+VR!zG@`)tK?w8(QLlp<+=>Dw(w8 zZ|umfGixGJjyY8_u1VP*25NE00vv2R;P538`m&Q8Nu>-P@CsGjHFeamg|L;wH8e#W zO!E1o7!ic}P*3N9PZj+;u=GV^ZBwYvNJGW})m{<-ZE_fe&7L&RBh@fbG-SM5aZRnN zErd@BC0xw0I=6BS)Uc*#9$8bxdfj3UYD_xCJf@Ru_`V|9Y8t`ed;cHbpO1yEAlm+a zo-9J7EZZ{nq_4f4Gr^DZYPq}^%Z6y{i)3l;6sXRY3%FD$SdNX;MDHaWnHPzU>e`@m zF7WGvRa<~wjuFbzGH^|n#-ID<;8^^(3;VR47T2VI$csKKkqyJgp_fv5X;ksj_%dA!DP1fvqs5@M&TiMq)XFS~oQMEEt+wm~CH#1^@v8^9I ze!KeW*2}SvVq)w;aB`3F^wYBk_vc38mDg{_-`&1AJ@Mku!7q1qAAXYd(CX|$<@u>= GH@^cCN4$jq literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonDown_7x4.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonDown_7x4.png new file mode 100644 index 0000000000000000000000000000000000000000..2954bb6a67d1c23c0bb5d765e8d2aa04b9b5adec GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)I!3HFqj;YoHDIHH2#}J9|(o>FH3<^BV2haYO z-y5_sM4;GPjq%Ck6>60csmUj6EiNa>ORduPH4*)h!w|e3sE@(Z)z4*}Q$iC10Gods AV*mgE literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonLeftSmall_3x5.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonLeftSmall_3x5.png new file mode 100644 index 0000000000000000000000000000000000000000..51411acaf8d921da05d3eb2c9dc54af6253d0c5a GIT binary patch literal 1741 zcmcIlO>f*p7&ahKo2qaqhfpq-djZk$%y|8=w(3@C9LP#IMCnQmH^wvLT`OykYkRYs zoT^?B;uo|6iC@4U;DCBW;=gbKi5tA$wYLSeAr~xpJ>z}md7t-vAJ2Sqc<|Zvt(#k# zrd=QHM@R5{3+}hCya~VW-FW^7Jg%1eU)Gv-?M8dQp*{ONVOnfB!?F;G2Nuyqc}b zBRG~bnFDtXSh~_z2D_DHjjF~<&H6?i_7Qc9nwI|2!>kZ$QGeVj>K4d|H8M1yYZMV^ z*>FsqfcgO$enLq=$Ql}h4+Lx2<-kg0>DgtVaU6__x?u&EqbM{$l$m8BV7}+tuE$a0 zSq@@}Em1=3A@YVvlBUw7iI6K@us%|J-d3VrzqYMV95^=B4BW&`9Yz?k9m-HjY=#mp zIHKIL++;u<+p&ALFRBc_95#EIwN)j6(XkWHXZ{dLo4UxhZ3_)KOnG8C7G)_(9LvyO z#NAahRmDm`bq9tnc#x_pXW*YKXA_CbV$!-9*ddGktcKQ|b>GJW`KTMsGJR#bfbrJr zp~2fGOJQ`cvsYB_ayr+vi>U-vE z8hTQo0do@}q+|1ew~jl@dIf7Dd~w8;)|a-&elhI1?QpZ%!(?+@$O2NW;4p~JZ~p=Z y$%mt8XME);|MRca^}+V`_7CrGJ^q$H_qAWYe)sq9x5o4Kz!~iwL_gmD>dD{nYamVl literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonLeft_4x7.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonLeft_4x7.png new file mode 100644 index 0000000000000000000000000000000000000000..0b4655d43247083aa705620e9836ac415b42ca46 GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonRightSmall_3x5.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonRightSmall_3x5.png new file mode 100644 index 0000000000000000000000000000000000000000..b9d5f87db1ca55141449cfcc3bf054417eaa84e1 GIT binary patch literal 1738 zcmcIl%Wm676lEHu%>zLLWYHwZf?zfc+Tjd`l=wgx!?E02K7gZd!)A>b-AnNYDb z=UD-0O?$90FBm_PwI0iHnuo^kzrHc_RD{NpUPPi|OHR_A(^5V@-5v4MBkl`h`li))oId$h zr-Twrdf1}K>IcLLELU%T22?9W66_DYYiq$%XiVz52r!<_X6DQ`RXN6%@B5fgOeq2c zsup?8<|wc3bqoVp@iHyyRONcZ$YOO|hXyEJO(84Rw0YIq1cu=`E3jpfW=b6}iq3{+ z*&1Ed+b2+^)%#K6YP2XM-j|g+F1g%3k$HWuD^^TYt*VLogtqnH|4=CSx?pi!PM7uw zj^$Klz+C~>TIwr;tx~dDl_RC5T~K>nMV(qE)xUm{=0eS?`;DS@fE=(|h6bc&Ap((k zBdZr!eqejwSR^211&yE&1gqKkz)Gaa;ylnO3Wj-Avz*J}AT&UfnWiG(Hm6?C6^L<1 zqL@1bP64XW zqKrwxT^V~c?$~}TQ}}Y&^h4H0l>o-Xk=)_jK{NqDuJ0r$_IQFAaV$sJiQn_7p}()Y zrKYNklmK^aLl-wVr`&ul_BH)&R_4UgD(ZOFr}nOx%X#N!gVeJ4h)=Wyh? zQXrf4V!h1m}&`|!B-3a0&FC= whJ($~<(FI>9{%<2-NwbcKNmOR7sY+;Hox}g7dMW6Yj&IA_U_=9M~Bb;1{rl65&!@I literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonRight_4x7.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonRight_4x7.png new file mode 100644 index 0000000000000000000000000000000000000000..8e1c74c1c0038ea55172f19ac875003fc80c2d06 GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonUp_7x4.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ButtonUp_7x4.png new file mode 100644 index 0000000000000000000000000000000000000000..1be79328b40a93297a5609756328406565c437c0 GIT binary patch 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- literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Button_18x18.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Button_18x18.png new file mode 100644 index 0000000000000000000000000000000000000000..30a5b4fab236d8b57242559ef94fb1c5dbb5d10a GIT binary patch literal 3609 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Certification1_103x56.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Certification1_103x56.png new file mode 100644 index 0000000000000000000000000000000000000000..6e11bbbb222cc54a3e6883f81522af25fd847e52 GIT binary patch literal 3038 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 E55wqT-~a#s literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Charging-lightning_mask_9x10.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Charging-lightning_mask_9x10.png new file mode 100644 index 0000000000000000000000000000000000000000..d44a32ae0819d72acb29b5bed228b24511de2f03 GIT binary patch literal 10182 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 bb{4?N2Y_krILTll8lbMMqx4w8Cg^_v(=Zo_ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Circles_47x47.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Circles_47x47.png new file mode 100644 index 0000000000000000000000000000000000000000..6a16ebf7bbe999fa143c683bef713a6e2f466cbb GIT binary patch literal 3712 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 biU<_Yn+9Io=xs3K`2!qm58ISjpSt)z2v?8| literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Clock_18x18.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Clock_18x18.png new file mode 100644 index 0000000000000000000000000000000000000000..ab06d008eeba32030ecbf0168f5bed327343f340 GIT binary patch literal 1083 zcmbVLO=#0l91j+x4hG`Ik5kMJDwyOYO`0Y&&aLTOV4bC_tjE3Py{=)+hsoQTP4M7F z9e5TGqC4y=cofAC7@`;Py5R@tNf883-s(%cP7h-T1Ihcy|M&a<{$IDNvzJCkPK_`O zGipy;HM$;4-)x3{;nC}uE+B0yz6DVk6*7o2cu3?B)ufD}ahRLkB^#*BF zW(+6r1en?gi5F5d!xYDp5IRekuuZ(^`X=}D=?ji^k;%=g6;KIFxb04_MR;y)w(hJg zIXdFTFR;bLpadQ!kWIXf9~+6u^?41tPp?Ie?VFG#lN*R?RH|$#h%l=O67K*2SWOoY zY(l5mJkQENmPDY4lEMREdK@474sq7K^@ouJQ&cpTmLrE2q%}4K)8rlOC^e*NjLVTrs{%V#;4FLC zC$?pB^pAjCWaN;hs}59oNrgFH$!nM|I5OsSpkPOmF>o*%^6ZOOHK6O|ypof1l2k5D z6iP}#E0is5(vovJ7-DTdCeU~A(6^iV9$?i2u|_GvkOWaZ2s*MpIGXvHdg~?miN9E#E=_7kHFcWtsy;;hPX5UXe8_3#zDq zXb1y5`rq`4RFs(Z%0Im`yrK=6Zudrk9`=R_`*eaLIw~^@<_9`vhpRL7GF^MU-sbj$ zk923-)AZh6%COnY%az{dohuhNinsKw?88Ir*M#iW8F~86kI!WN-olal-?vXQ tH&1*4&tJE{{+|EzEA!;>$7pBdE|X#GcTBi({Mk23%Gl*u>(S)GjXwlaS&0Au literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Connect_me_62x31.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Connect_me_62x31.png new file mode 100644 index 0000000000000000000000000000000000000000..68c48c0e68142548919d6a4b02e40b48a243b04e GIT binary patch literal 3767 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/CoolHi_hvr_25x27.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/CoolHi_hvr_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..692ac7b8be718dfe02b460c9ce9a710857feb562 GIT binary patch literal 3669 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/CoolLo_25x27.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/CoolLo_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..23288e44f158d4034bebfd6a2a9005514b132a9d GIT binary patch literal 3676 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 + +## Build the program + +Assuming the toolchain is already installed, copy **flipper_geiger** directory to **applications_user** + +Plug your **Flipper Zero** and build the geiger counter : +``` +./fbt launch_app APPSRC=applications_user/flipper_geiger +``` + +The program will automatically be launched after compilation + + + +**A4** GPIO can be connected on **A7** GPIO to test this application without using a geiger tube. **A4** GPIO is generating a signal whose frequency changes every second. + +Press Ok button to clear the graph, press back button to quit + +If you don't want to build this application, just simply copy **flipper_geiger.fap** on your **Flipper Zero** + +## Use cases + +Ambient radioactivity : + + + +Measure of uranium ore piece inside a lead container : + + + +Measure of uranium ore piece in contact with the geiger tube : + + + +All previous measures in a row (the scale of the graph is automatically adjusted) : + + + +**A4** GPIO on **A7** GPIO : + + + +## Changelog + +* 2023-01-15 + * Code fix & a lot of optimizations. Now a lot of events can be handled without any issue + +* 2023-01-09 + * Schematic was added & code fix + +* 2023-01-08 + * Initial release \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/application.fam b/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/application.fam new file mode 100644 index 000000000..5bbbddf99 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/application.fam @@ -0,0 +1,13 @@ +App( + appid="flipper_geiger", + name="Geiger counter", + apptype=FlipperAppType.EXTERNAL, + entry_point="flipper_geiger_app", + cdefines=["APP_GEIGER"], + requires=[ + "gui", + ], + stack_size=1 * 1024, + fap_icon="geiger.png", + fap_category="GPIO_Extra", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/flipper_geiger.c b/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/flipper_geiger.c new file mode 100644 index 000000000..2ed83a9fc --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/flipper_geiger.c @@ -0,0 +1,190 @@ +// CC0 1.0 Universal (CC0 1.0) +// Public Domain Dedication +// https://github.com/nmrr + +#include +#include +#include +#include +#include +#include +#include + +#define SCREEN_SIZE_X 128 +#define SCREEN_SIZE_Y 64 + +typedef enum { + EventTypeInput, + ClockEventTypeTick, + EventGPIO, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} EventApp; + +typedef struct { + uint32_t cps, cpm; + uint32_t line[SCREEN_SIZE_X/2]; + float coef; +} mutexStruct; + +static void draw_callback(Canvas* canvas, void* ctx) +{ + UNUSED(ctx); + + mutexStruct displayStruct; + mutexStruct* lfsrMutex = (mutexStruct*)acquire_mutex_block((ValueMutex*)ctx); + memcpy(&displayStruct, lfsrMutex, sizeof(mutexStruct)); + release_mutex((ValueMutex*)ctx, lfsrMutex); + + char buffer[32]; + snprintf(buffer, sizeof(buffer), "%ld cps - %ld cpm", displayStruct.cps, displayStruct.cpm); + + for (int i=0;iline[SCREEN_SIZE_X/2-1-i] = lfsrMutex->line[SCREEN_SIZE_X/2-2-i]; + + lfsrMutex->line[0] = counter; + lfsrMutex->cps = counter; + counter = 0; + + lfsrMutex->cpm = lfsrMutex->line[0]; + uint32_t max = lfsrMutex->line[0]; + for (int i=1;icpm += lfsrMutex->line[i]; + if (lfsrMutex->line[i] > max) max = lfsrMutex->line[i]; + } + + if (max > 0) lfsrMutex->coef = ((float)(SCREEN_SIZE_Y-15))/((float)max); + else lfsrMutex->coef = 1; + + screenRefresh = 1; + release_mutex(&state_mutex, lfsrMutex); + } + else if (event.type == EventGPIO) + { + counter++; + } + } + + if (screenRefresh == 1) view_port_update(view_port); + } + + furi_hal_gpio_disable_int_callback(&gpio_ext_pa7); + furi_hal_gpio_remove_int_callback(&gpio_ext_pa7); + furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4); + + furi_message_queue_free(event_queue); + delete_mutex(&state_mutex); + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + furi_timer_free(timer); + furi_record_close(RECORD_GUI); + + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/geiger.png b/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/geiger.png new file mode 100644 index 0000000000000000000000000000000000000000..d41e1915b6821ab19f982f1c99cad821d5a38abe GIT binary patch literal 8048 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/flipper3.png b/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/flipper3.png new file mode 100644 index 0000000000000000000000000000000000000000..99636bddec5d0b08de881715a8d8a4c486522f14 GIT binary patch literal 1376 zcmeAS@N?(olHy`uVBq!ia0y~yU;;8388|?c*QZDWAjMhW5n0T@z;^_M8K-LVNi#68 z3VFIXhE&XXd)L?Ru>nKFMaHidbNZbN?9Mf(9n?v4T(V4M>)iKyRhg%LHvW}jUK+p8 z?%qF!3!km37#MmK85jbY7z9*Ns8VU$hS0tH>h1n)x2rbnuU_}q_ImcV>y6bj7#UnR z862iCFu3fE@V7aCt!iDd-8I|msYmZO?mff6u!x00!3#*$@Ff^l&lmpx|9gK_aNOU> zuZxeF-G2SX^i|xiv#%@kpG2e~?6YGp*kF83_$n5 zRUjMBGsYab`FdV-_WJWN%kLE(`}`yN_>VJNe=k0^dAjKrK4XRk4Mv6zAt3dhQD(t6 zn@_gYd;X-&tvdQSY&ZK3HWYcFN$1<*GkbrpNS^t&w6Eyf-Xk_hj^D$+p<(au4|kH^ z@A_=~oyqF<&EuQC?=G8PnU}s}`iyoYN4;m+XYqQo%+b9iwn!dA4Ng0D27y#I^bkf3 zZzvBK>yKejq^MPse-;dAh`?st2w@A*Zwcl~SZ|kYAM$C{D08I$Es7>M*?6>X> zka@p-wcPt@Yd;%EUw>_h6#vjPOaztp?QY$f6~Gi0xApN{-?x9_zgBGTJIw>h0|fNH z+V+({{I2lhoO8F6x1GDKQGNXJuXCB(erKItQ8){c&G3a*?mN~k*K?{Ltl7kV;#J!2 zcWY9o{$K9i`}xh|yT5-CnS|QkvX)HQTYdVF_8fZ z%5{jqu9CEEs9yW8mO# literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/flipper4.png b/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/flipper4.png new file mode 100644 index 0000000000000000000000000000000000000000..1190b18e3b4d302ba4041e975b6284e3904fb3b2 GIT binary patch literal 1420 zcmeAS@N?(olHy`uVBq!ia0y~yU;;8388|?c*QZDWAjMhW5n0T@z;^_M8K-LVNi#68 z+IhM-hE&XXdpFu|i35Yf#cMlcu0L0bxxeQ4nfAIFJw8&i-9^98Ip3+IaLzZ>^uw2r z|Eic5JpcJdmf?X66N7*%14AGxrJw%(z{Pp@|NZ$@J^kIx9qF^*ZI?KH;`)J%+YfK` zFfc4)VNmb_QuEF*|I5z&_vQD_Td%S$?uG52uDo9Ox=OVH6GMj(LxTn*L&vGR>;}8H z&VT>!-`D7~tiOAHF2C6Kam`=L*RyI;tgkuQNis6Ha56YdVPJ5HWd33FY0d-X;#uCe zBY)jn`z&<&Hsejo@A)k*$^AAyWV-WeS=#))@5-;bPoG4FA0N?qmqosVy&?@jC! zgt!6dl#nXk2ZGA>?^FA0CEiwS|8$~K`t6*aJ@%X9)x%Q}Mtu#LH~aSQpYQu~idWCy zdc3%F-50+HYx|zAy1nywzJ221h6vl2rVUM>{-`Av`Su;=fCL~k91+y1 zTA+F)J*d%w$^%9cgZ<}wAqn|JYCzSFj|VdPPTuz0pKs5X|Nr;#->(mB8~KzWF$#@X zoYZ-yT^#2xFgxbl}}M-TxF4AKpZ*~w>4APGqw5HH?Q{PB0wag_AO5Vo1Em>0>^YYYhr z&#u*{zyG}L+g`!VNa=c39nedf%Eh(+;@|%1Dcggj>F`>{9y52g@JH`oOI`aXH+|nd zgw0unybo5L-zRZ4<9X$lzc){19N+r=-<;At^G<%wT>baXU#pv?uNio}AwiP0<2OUY z@2k&_d^bB?mvz-@v4^D+wJ!J)kuN9>rE}gGl53c zfAv375XpAyZ>a-1=a1gIopC;W{?RwT`Q4*_e@{Zlm)`u%uq}!2SGkRHhv1Ljf9;WC zJ)40+-TJNF!r(eBhULPL)Ub)oKyrSz-Sp4rr%E8QGBigMK~>5#w12Xxm1sv~z$=%- xq<>Y^|NVIX>`$hilL&94q!eITNEP7pkI7QBS!AN{^QR#5JYD@<);T3K0RZy~*cbo+ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/flipper5.png b/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/flipper5.png new file mode 100644 index 0000000000000000000000000000000000000000..45f74701e00b07a0e137112ebff5493db3a57ed4 GIT binary patch literal 1480 zcmeAS@N?(olHy`uVBq!ia0y~yU;;8388|?c*QZDWAjMhW5n0T@z;^_M8K-LVNi#68 zR(ZNOhE&XXd)GVfii3zlVAG~KYx-SNYS*YI9Z=!m(fgx$`}>^27c>04!`Gi$SNF4` z{x_4u`Rg~u84k!WF$kzKFa)Af>o@B^c(t$Y_rLS=Kk6K7zgV3UXjjMk9mSewu?v46v9CJCY{{CJ&=J4HeR!C~*G4Ggg@%QfO?-K8C68m$d z`pot_{rjI}y+15?-T1Zf&ZnhsTGymAF?0wqG-xm~bZlZbxH--A?9%IzzqVJeUA@lI z{yCT1|NV>C|GX*q{onkbR*TnHen~G{e|_iU=ihwPAeumWs~OA-zEnM(WqNtb2?VvHhlB(hV3HTsRpVrZ6zL++=MmXN7i#!E7^o0Mu1GRZLqiaoHOU*{jJAdl+OG4 ze{c8dz3N-ft2{@tYHvjIZvEG*VtUU%**k-QVG#?1f)@s5!_FX(im(|P5Ll_IxwVY` zkF5h6cOzK>^%j(>A9Ed2&|)hp z$&B~TTx21J<+HYy8~vJlI3NMxe26H#vcDGT2=dXXu zTOr?oJBIYi#V%aDlqmAXCmS^Z$JA6@pKkOQ$-$9ne714a^cqN$5Gl1BZF%ADqG&Gwt^58%pF&7>bd6iZxwB1#8ql9JcJ{ zj6lj<_*3GAlyk38+>GQppj#{X7$mlR`E%;{@7pKC4~e0K?SU<(wbh)+E_=gxfMs#^ z{p#BMBQI|Kdhy=&*Kb|7`1&`DvoOyO`My%@vR4eSZ5g^RZj_daha9 z>;L`x%+F9&clR$F!;W?a1{Y2Shbbu3mETkU-(0`HuKu@i^*iqw4@mS*AZwukSz5hGmZ-rl(K+nd+@x-vhpPWjq9_Zq*n-#OO(^A55w2&ghJ1TrxQ znEtVA*nI8Nx)|X(m483JnDzDeeEaOTUp=pvyth;{UH#|nwmYSLdp=o}zipktz_5sg zLBR`1>HXDPFf+Dt@3+A9YZUYLp1Zc+He0s%b?J@srk{SFE$Ex`)hc|RyBb4-1|vg< z5JSU?+us<{qKoZ!v6X+R`gt+Ca`E-n?=tf@-#dTt^~bfH@yTCpJ45e1pXvi~6v%DC zHo_Hc*>C%`;-Bw(e(QO7pa0v6I+MfczZc)U$B*nu-uuiImv;T1Ci#uItv>z4k>m4= zZNKK*9K7KR7lmD?ZE{q}vBb9M8)>${%s`nvdk*^$?8KA!sQ_kG6O?|U!tocEO5 zo4)P2X}aC@Z#!PgSiZiwKm6T6BrmtUXDnF1Jnk}Yy5@XkgwLQJgi+stfj<)wPSD`O zO5J;3$Glm?UR-3Gh5o#=h!}xJ43v6m$FS^~Rf)uLgo0Fl2DPN~&Du!zn0;qhdkfcZxvQ+A*HbowhY;=2V!f=FI-1T z$fxhHZ{VtyJCL#b?)k!Fvl$a?q2B(+P`9G2w(#wD+f(=WwUM&zO=gB2H)E@F5cX}fjbYIm&BN(iKOaKaf|LY+;q=t5p?&t-UC$QZ4`u2} zMnvMST>b-5AFiiG@0LIN{_AX4p`LNuqT{N&1V4TO@jYGrT-G@yGywo&GZm)* literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/logo.jpg b/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4d3e714e5e603ce1a442350e4e8df552286098fd GIT binary patch literal 351585 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 }j3lODFzD!RF8gaw)wi|O$z53i@kY0OfNuH*ZK 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 z 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 z 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%0AZ2F+IJ6bl}HRN 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

Ajy*9qeM84`-kAg6z#596Fd*n_2a* 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 YsBei+#x78eGmJ^DF870WTibL0*%jXBxc~qF literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/schematic.jpg b/Applications/Official/DEV_FW/source/xMasterX/flipper_geiger/img/schematic.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d6072596e22d6236d6bea08cadc4698685e291c5 GIT binary patch literal 370586 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%0A36M*QVufp|^)wbZLb{nUM2p-%FM`7tSHdAbEo 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 z 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

840tjKAGLt%R&CmRRfGNw3#zsHYT=8_CeIR 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 z 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/.clang-format b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/.clang-format new file mode 100644 index 000000000..4b76f7fa4 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/.clang-format @@ -0,0 +1,191 @@ +--- +Language: Cpp +AccessModifierOffset: -4 +AlignAfterOpenBracket: AlwaysBreak +AlignArrayOfStructures: None +AlignConsecutiveMacros: None +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Left +AlignOperands: Align +AlignTrailingComments: false +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +AttributeMacros: + - __capability +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: true +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: false +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeComma +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: false +ColumnLimit: 99 +CommentPragmas: '^ IWYU pragma:' +QualifierAlignment: Leave +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +PackConstructorInitializers: BinPack +BasedOnStyle: '' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +AllowAllConstructorInitializersOnNextLine: true +FixNamespaceComments: false +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseLabels: false +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentRequires: false +IndentWidth: 4 +IndentWrappedFunctionNames: true +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +LambdaBodyIndentation: Signature +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 4 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 10 +PenaltyBreakBeforeFirstCallParameter: 30 +PenaltyBreakComment: 10 +PenaltyBreakFirstLessLess: 0 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakString: 10 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 100 +PenaltyReturnTypeOnItsOwnLine: 60 +PenaltyIndentedWhitespace: 0 +PointerAlignment: Left +PPIndentWidth: -1 +ReferenceAlignment: Pointer +ReflowComments: false +RemoveBracesLLVM: false +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SortIncludes: Never +SortJavaStaticImport: Before +SortUsingDeclarations: false +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: Never +SpaceBeforeParensOptions: + AfterControlStatements: false + AfterForeachMacros: false + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: false + AfterOverloadedOperator: false + BeforeNonEmptyParentheses: false +SpaceAroundPointerQualifiers: Default +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInConditionalStatement: false +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +BitFieldColonSpacing: Both +Standard: c++03 +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 4 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE + - NS_SWIFT_NAME + - CF_SWIFT_NAME +... + diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/.editorconfig b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/.editorconfig new file mode 100644 index 000000000..a31ef8e75 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 + +[*.{cpp,h,c,py,sh}] +indent_style = space +indent_size = 4 + +[{Makefile,*.mk}] +indent_size = tab diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/.gitignore b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/.gitignore new file mode 100644 index 000000000..9bf2d4d7d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/.gitignore @@ -0,0 +1,54 @@ +dist/ + +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/LICENSE new file mode 100644 index 000000000..85e363072 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Skurydin Alexey + +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/Official/DEV_FW/source/xMasterX/flipper_passgen/README.md b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/README.md new file mode 100644 index 000000000..fbeb41680 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/README.md @@ -0,0 +1,4 @@ +# flipper_passgen +This is a simple Password Generator plugin (**fap**) for the [Flipper Zero](https://www.flipperzero.one). + +![preview](images/preview.png) \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/application.fam b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/application.fam new file mode 100644 index 000000000..ebc879f1d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/application.fam @@ -0,0 +1,12 @@ +App( + appid="passgen", + name="Password Generator", + apptype=FlipperAppType.PLUGIN, + entry_point="passgenapp", + requires=[ + "gui", + ], + fap_category="Misc_Extra", + fap_icon="icons/passgen_icon.png", + fap_icon_assets="icons", +) \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/icons/Horizontal_arrow_9x7.png b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/icons/Horizontal_arrow_9x7.png new file mode 100644 index 0000000000000000000000000000000000000000..caca887186695e1da342df00e85ff3f22054dcda GIT binary patch literal 1479 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 TFC+3}9cE|kU{!4CefEC<&8td2 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/icons/Vertical_arrow_7x9.png b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/icons/Vertical_arrow_7x9.png new file mode 100644 index 0000000000000000000000000000000000000000..b889fc8f3c320807b9c39cc66a8592e4d93b6c39 GIT binary patch literal 1482 zcmbVM%d6B@7>}T>-lE`EMGmnA?QN2iIM1W0%$?lFP;)!IcktepE_x<8nK|4fCr!>c zGncv%q1cU3Xjg?&x-2L{!9^F{v`cNfa@$Q2p{4(TXur%OO0jAUoSfJ1{J!^hwY|Q2 zaN)>;q9_MjYt9DDufjO6{}uQ@+^&2J)1GW&bxFB?=h%JN?Cmw&hN9fO_SyrwFGnV8 z?`Mi~=%;+_`C{?VQAOEzn0L12wtJp~ zMDEyXBNvFa-8O29l%a}_H4kG8RqMK0DU~YtEo5N}8@OzkmS$E6E)lbeW}gbuQa>OY z&dN*{>}<6!WkL*NI2`K3)4E7|hFP!I4Qv^fr2#_A#<8R$EzVBN861{*DNiI9G0GWf zR}7@Bf~HdwqNJdWvzeQ~VaA9ihNx=)eqqr`tNk}tgREo4C zL^uyrd(MI^Q@7B`Egt(~n4QX{%pNd@N@lANHB-Z;cG~RVDk)pUG#5=wFrGqP$OE5B z`eI<=^I-g3sPBIF5ej(w^H z)snAutF@XIRDyCnpt#ztO|^yhj_?L~1n2Ml|M~viltTs4@a1`m2$7};Md}J4ylkrI z@p-G+Y^NgNAzU~@qE*UcsGc|S9G~PGS>qW5bUdq?P4@9@6>>C5FG9V%0&LaGL(hD5 zcFbSedsEtBp8@GJQeq0rL?DMWWsM$q`nf4*fbvFOt5Z9Sf15bDd!nxAaA+3!vglH< zDf%3Xp}D2d#eV(pMhG2nspT{}CpRx$ySkvD{moksAASAK&x_w2zf!w*_?GhN>mPjf z$8QVvn-~7P{Q1hb+)MuY>XS2fzk6?Rrhi2J<;Iov%J0fn_xPjlmu`QVH`Lbhx^sQ$ Hqs#vQWTela literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/icons/passgen_icon.png b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/icons/passgen_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1ed4f77fc1a13b05214e2840b8e34f95ef1de27c GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>VM%xNb!1@J z*w6hZkrl}2EbxddW?X?_wfUrhf=-?;jv*Ss$$$7+cw89V6x8Ar6`du4V8((R z0|w57#f}WFiYHPgsF+C`__S!cvAgURTqAJkD1Qf^yNLNCHXa^^8GX_`yDxYA0-DC) M>FVdQ&MBb@0H)F^m;e9( literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/images/preview.png b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/images/preview.png new file mode 100644 index 0000000000000000000000000000000000000000..3224b0a8d4209a9fe33daa8596965944ed0bd25a GIT binary patch literal 980 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!3HERU8}DLQjEnx?oJHr&dIz4a#)I;JVQ8u zpoSx*gMop$&eO#)q+-t7x!Fap40u{S+s|&;uh;yy)bfkFx@@mSm1-H2Os(y)%wHtHiJd4`+ZELe? zWBs>B_Li!xv_0@@O4%JLoBV*qWov#1u;;&&QE|HxrmCirW4qw$x9!KmpJuW-tlBbf z$JQ9@oT=|q`{$nV3EisP`D@jwz-rcF{st>f%ha{&SNvI%c`lpzsPxT`ulB!6JD+s@ zw!_aU>8JXaZ2A-Ox3=|%+e9ITsPh-BG?zPu#AP1et#7?!Q(T#@+{@@?>(9+IoaS9G z;^SK{QKlLI9B5!V-SyozB7!rSL zThiTGQFgoPmvJ1hl1eQ-;q{H-RK}vRRN22#zg7Q#n^&{`Z^kp}lLd?svSPe-N7G6V zq&3uR{NutLDSKw(<$Woqcnl6-4EK!t+IQ~dbt&7g;e2P#bk*MyYB=@fp6`|;3$i8mq%JNJS+i;3ng+98{l9t+ z>${6|&+Oa!Ij2u$bNYryD}`*IUYnPwcKUJM>&=Zvcz!Fq2<<%gar5VoOfMS0y?oDv zH*}m88_Iu_SD*iMQMBP);O2GxM@|dhNY?+=XE(c`Fyu^J?BB^7v#%QO=ecBl#>acp ztu3dv-Eua3VWjVO`rf>Koopw)gE~)KX*NE<@iqG9rnmzaAB4;hWIlEK{22o|jm@6_ zLO!u6-=DB{xuimtfw6|wSMJmcZj~Ra)90Mp8+eZ4ldJrX8?RSCXP&imOTXmr6?%W< zosCX*3o2jpni9U_XS6WPM@A&`B#W{(w_adb}A>G zxG{h3@#&(|=7ehV&)>;;rEQb6@>>_Rn?+(bC3H4*u3G%)L>|-Py}>Je+m>8VzISks owun5-*9W%)I2LRKCY#UPeE%I!Bn0%{0Om{vPgg&ebxsLQ07o6q=Kufz literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/passgen.c b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/passgen.c new file mode 100644 index 000000000..12cdc10fb --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper_passgen/passgen.c @@ -0,0 +1,202 @@ +#include +#include +#include +#include +#include +#include +#include + +#define PASSGEN_MAX_LENGTH 16 +#define PASSGEN_CHARACTERS_LENGTH (26 * 4) + +#define PASSGEN_DIGITS "0123456789" +#define PASSGEN_LETTERS_LOW "abcdefghijklmnopqrstuvwxyz" +#define PASSGEN_LETTERS_UP "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define PASSGEN_SPECIAL "!#$%^&*.-_" + +typedef enum PassGen_Alphabet { + Digits = 1, + Lowercase = 2, + + Uppercase = 4, + Special = 8, + + DigitsLower = Digits | Lowercase, + DigitsAllLetters = Digits | Lowercase | Uppercase, + Mixed = DigitsAllLetters | Special +} PassGen_Alphabet; + +const int AlphabetLevels[] = {Digits, Lowercase, DigitsLower, DigitsAllLetters, Mixed}; +const char* AlphabetLevelNames[] = {"1234", "abcd", "ab12", "Ab12", "Ab1#"}; +const int AlphabetLevelsCount = sizeof(AlphabetLevels) / sizeof(int); + +const NotificationSequence PassGen_Alert_vibro = { + &message_vibro_on, + &message_blue_255, + &message_delay_50, + &message_vibro_off, + NULL, +}; + +typedef struct { + FuriMessageQueue* input_queue; + ViewPort* view_port; + Gui* gui; + FuriMutex** mutex; + NotificationApp* notify; + char password[PASSGEN_MAX_LENGTH + 1]; + char alphabet[PASSGEN_CHARACTERS_LENGTH + 1]; + int length; + int level; +} PassGen; + +void state_free(PassGen* app) { + gui_remove_view_port(app->gui, app->view_port); + furi_record_close(RECORD_GUI); + view_port_free(app->view_port); + furi_message_queue_free(app->input_queue); + furi_mutex_free(app->mutex); + furi_record_close(RECORD_NOTIFICATION); + free(app); +} + +static void input_callback(InputEvent* input_event, void* ctx) { + PassGen* app = ctx; + if(input_event->type == InputTypeShort) { + furi_message_queue_put(app->input_queue, input_event, 0); + } +} + +static void render_callback(Canvas* canvas, void* ctx) { + char str_length[8]; + PassGen* app = ctx; + furi_check(furi_mutex_acquire(app->mutex, FuriWaitForever) == FuriStatusOk); + + canvas_clear(canvas); + canvas_draw_box(canvas, 0, 0, 128, 14); + canvas_set_color(canvas, ColorWhite); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 2, 11, "Password Generator"); + + canvas_set_color(canvas, ColorBlack); + canvas_draw_str_aligned(canvas, 64, 35, AlignCenter, AlignCenter, app->password); + + // Navigation menu: + canvas_set_font(canvas, FontSecondary); + canvas_draw_icon(canvas, 96, 52, &I_Pin_back_arrow_10x8); + canvas_draw_str(canvas, 108, 60, "Exit"); + + canvas_draw_icon(canvas, 54, 52, &I_Vertical_arrow_7x9); + canvas_draw_str(canvas, 64, 60, AlphabetLevelNames[app->level]); + + snprintf(str_length, sizeof(str_length), "Len: %d", app->length); + canvas_draw_icon(canvas, 4, 53, &I_Horizontal_arrow_9x7); + canvas_draw_str(canvas, 15, 60, str_length); + + furi_mutex_release(app->mutex); +} + +void build_alphabet(PassGen* app) { + PassGen_Alphabet mode = AlphabetLevels[app->level]; + app->alphabet[0] = '\0'; + if((mode & Digits) != 0) strcat(app->alphabet, PASSGEN_DIGITS); + if((mode & Lowercase) != 0) strcat(app->alphabet, PASSGEN_LETTERS_LOW); + if((mode & Uppercase) != 0) strcat(app->alphabet, PASSGEN_LETTERS_UP); + if((mode & Special) != 0) strcat(app->alphabet, PASSGEN_SPECIAL); +} + +PassGen* state_init() { + PassGen* app = malloc(sizeof(PassGen)); + app->length = 8; + app->level = 2; + build_alphabet(app); + app->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + app->view_port = view_port_alloc(); + app->gui = furi_record_open(RECORD_GUI); + app->mutex = furi_mutex_alloc(FuriMutexTypeNormal); + view_port_input_callback_set(app->view_port, input_callback, app); + view_port_draw_callback_set(app->view_port, render_callback, app); + gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen); + + app->notify = furi_record_open(RECORD_NOTIFICATION); + + return app; +} + +void generate(PassGen* app) { + int hi = strlen(app->alphabet); + for(int i = 0; i < app->length; i++) { + int x = rand() % hi; + app->password[i] = app->alphabet[x]; + } + app->password[app->length] = '\0'; +} + +void update_password(PassGen* app, bool vibro) { + generate(app); + + if(vibro) + notification_message(app->notify, &PassGen_Alert_vibro); + else + notification_message(app->notify, &sequence_blink_blue_100); + view_port_update(app->view_port); +} + +int32_t passgenapp(void) { + PassGen* app = state_init(); + generate(app); + + while(1) { + InputEvent input; + while(furi_message_queue_get(app->input_queue, &input, FuriWaitForever) == FuriStatusOk) { + furi_check(furi_mutex_acquire(app->mutex, FuriWaitForever) == FuriStatusOk); + + if(input.type == InputTypeShort) { + switch(input.key) { + case InputKeyBack: + furi_mutex_release(app->mutex); + state_free(app); + return 0; + case InputKeyDown: + if(app->level > 0) { + app->level--; + build_alphabet(app); + update_password(app, false); + } else + notification_message(app->notify, &sequence_blink_red_100); + break; + case InputKeyUp: + if(app->level < AlphabetLevelsCount - 1) { + app->level++; + build_alphabet(app); + update_password(app, false); + } else + notification_message(app->notify, &sequence_blink_red_100); + break; + case InputKeyLeft: + if(app->length > 1) { + app->length--; + update_password(app, false); + } else + notification_message(app->notify, &sequence_blink_red_100); + break; + case InputKeyRight: + if(app->length < PASSGEN_MAX_LENGTH) { + app->length++; + update_password(app, false); + } else + notification_message(app->notify, &sequence_blink_red_100); + break; + case InputKeyOk: + update_password(app, true); + break; + default: + break; + } + } + furi_mutex_release(app->mutex); + } + } + state_free(app); + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_pong/README.md b/Applications/Official/DEV_FW/source/xMasterX/flipper_pong/README.md new file mode 100644 index 000000000..b9e20fc0d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper_pong/README.md @@ -0,0 +1,23 @@ +# flipperzero-pong +A Pong game for the Flipper Zero + +![](https://github.com/nmrr/flipperzero-pong/blob/main/img/Flipper_Zero.jpg) + +Assuming the toolchain is already installed, copy **flipper_pong** directory to **applications_user** + +Plug your **Flipper Zero** and build the Pong : +``` +./fbt DEBUG=no LIB_DEBUG=no COMPACT=yes launch_app APPSRC=applications_user/flipper_pong +``` + +The game will automatically be launched after compilation + +Because of the position of control pad on the **Flipper Zero**, this Pong has been programmed to be played in vertical position + +Press **Up** or **Down** to move your paddle. Press back button to quit + +If you don't want to build the game, just simply copy **flipper_pong.fap** on your **Flipper Zero** + +## Gallery ## + + diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_pong/application.fam b/Applications/Official/DEV_FW/source/xMasterX/flipper_pong/application.fam new file mode 100644 index 000000000..b4593c656 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper_pong/application.fam @@ -0,0 +1,13 @@ +App( + appid="flipper_pong", + name="Pong", + apptype=FlipperAppType.EXTERNAL, + entry_point="flipper_pong_app", + cdefines=["APP_FLIPPER_PONG"], + requires=[ + "gui", + ], + stack_size=1 * 1024, + fap_icon="pong.png", + fap_category="Games_Extra", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_pong/flipper_pong.c b/Applications/Official/DEV_FW/source/xMasterX/flipper_pong/flipper_pong.c new file mode 100644 index 000000000..b9abe4c1e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper_pong/flipper_pong.c @@ -0,0 +1,293 @@ +// CC0 1.0 Universal (CC0 1.0) +// Public Domain Dedication +// https://github.com/nmrr + +#include +#include +#include +#include +#include +#include + +#define SCREEN_SIZE_X 128 +#define SCREEN_SIZE_Y 64 +#define FPS 20 + +#define PAD_SIZE_X 3 +#define PAD_SIZE_Y 8 +#define PLAYER1_PAD_SPEED 2 +#define PLAYER2_PAD_SPEED 2 +#define BALL_SIZE 4 + +typedef enum { + EventTypeInput, + ClockEventTypeTick, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} EventApp; + +typedef struct Players { + uint8_t player1_X, player1_Y, player2_X, player2_Y; + uint16_t player1_score, player2_score; + uint8_t ball_X, ball_Y, ball_X_speed, ball_Y_speed, ball_X_direction, ball_Y_direction; +} Players; + +static void draw_callback(Canvas* canvas, void* ctx) { + UNUSED(ctx); + Players* playersMutex = (Players*)acquire_mutex_block((ValueMutex*)ctx); + + canvas_draw_frame(canvas, 0, 0, 128, 64); + canvas_draw_box( + canvas, playersMutex->player1_X, playersMutex->player1_Y, PAD_SIZE_X, PAD_SIZE_Y); + canvas_draw_box( + canvas, playersMutex->player2_X, playersMutex->player2_Y, PAD_SIZE_X, PAD_SIZE_Y); + canvas_draw_box(canvas, playersMutex->ball_X, playersMutex->ball_Y, BALL_SIZE, BALL_SIZE); + + canvas_set_font(canvas, FontPrimary); + canvas_set_font_direction(canvas, CanvasDirectionBottomToTop); + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "%u - %u", + playersMutex->player1_score, + playersMutex->player2_score); + canvas_draw_str_aligned( + canvas, SCREEN_SIZE_X / 2 + 15, SCREEN_SIZE_Y / 2 + 2, AlignCenter, AlignTop, buffer); + + release_mutex((ValueMutex*)ctx, playersMutex); +} + +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + EventApp event = {.type = EventTypeInput, .input = *input_event}; + furi_message_queue_put(event_queue, &event, FuriWaitForever); +} + +static void clock_tick(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* queue = ctx; + EventApp event = {.type = ClockEventTypeTick}; + furi_message_queue_put(queue, &event, 0); +} + +bool insidePad(uint8_t x, uint8_t y, uint8_t playerX, uint8_t playerY) { + if(x >= playerX && x <= playerX + PAD_SIZE_X && y >= playerY && y <= playerY + PAD_SIZE_Y) + return true; + return false; +} + +uint8_t changeSpeed() { + uint8_t randomuint8[1]; + while(1) { + furi_hal_random_fill_buf(randomuint8, 1); + randomuint8[0] &= 0b00000011; + if(randomuint8[0] >= 1) break; + } + return randomuint8[0]; +} + +uint8_t changeDirection() { + uint8_t randomuint8[1]; + furi_hal_random_fill_buf(randomuint8, 1); + randomuint8[0] &= 0b1; + return randomuint8[0]; +} + +int32_t flipper_pong_app() { + EventApp event; + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(EventApp)); + + Players players; + players.player1_X = SCREEN_SIZE_X - PAD_SIZE_X - 1; + players.player1_Y = SCREEN_SIZE_Y / 2 - PAD_SIZE_Y / 2; + players.player1_score = 0; + + players.player2_X = 1; + players.player2_Y = SCREEN_SIZE_Y / 2 - PAD_SIZE_Y / 2; + players.player2_score = 0; + + players.ball_X = SCREEN_SIZE_X / 2 - BALL_SIZE / 2; + players.ball_Y = SCREEN_SIZE_Y / 2 - BALL_SIZE / 2; + players.ball_X_speed = 1; + players.ball_Y_speed = 1; + players.ball_X_direction = changeDirection(); + players.ball_Y_direction = changeDirection(); + + ValueMutex state_mutex; + init_mutex(&state_mutex, &players, sizeof(Players)); + + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, draw_callback, &state_mutex); + view_port_input_callback_set(view_port, input_callback, event_queue); + + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + if(players.ball_X_direction == 0) + notification_message(notification, &sequence_set_only_red_255); + else + notification_message(notification, &sequence_set_only_blue_255); + + FuriTimer* timer = furi_timer_alloc(clock_tick, FuriTimerTypePeriodic, event_queue); + furi_timer_start(timer, 1000 / FPS); + + while(1) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, FuriWaitForever); + Players* playersMutex = (Players*)acquire_mutex_block(&state_mutex); + + if(event_status == FuriStatusOk) { + if(event.type == EventTypeInput) { + if(event.input.key == InputKeyBack) { + release_mutex(&state_mutex, playersMutex); + notification_message(notification, &sequence_set_only_green_255); + break; + } else if(event.input.key == InputKeyUp) { + if(playersMutex->player1_Y >= 1 + PLAYER1_PAD_SPEED) + playersMutex->player1_Y -= PLAYER1_PAD_SPEED; + else + playersMutex->player1_Y = 1; + } else if(event.input.key == InputKeyDown) { + if(playersMutex->player1_Y <= + SCREEN_SIZE_Y - PAD_SIZE_Y - PLAYER1_PAD_SPEED - 1) + playersMutex->player1_Y += PLAYER1_PAD_SPEED; + else + playersMutex->player1_Y = SCREEN_SIZE_Y - PAD_SIZE_Y - 1; + } + } else if(event.type == ClockEventTypeTick) { + if(playersMutex->ball_X + BALL_SIZE / 2 <= SCREEN_SIZE_X * 0.35 && + playersMutex->ball_X_direction == 0) { + if(playersMutex->ball_Y + BALL_SIZE / 2 < + playersMutex->player2_Y + PAD_SIZE_Y / 2) { + if(playersMutex->player2_Y >= 1 + PLAYER2_PAD_SPEED) + playersMutex->player2_Y -= PLAYER2_PAD_SPEED; + else + playersMutex->player2_Y = 1; + } else if( + playersMutex->ball_Y + BALL_SIZE / 2 > + playersMutex->player2_Y + PAD_SIZE_Y / 2) { + if(playersMutex->player2_Y <= + SCREEN_SIZE_Y - PAD_SIZE_Y - PLAYER2_PAD_SPEED - 1) + playersMutex->player2_Y += PLAYER2_PAD_SPEED; + else + playersMutex->player2_Y = SCREEN_SIZE_Y - PAD_SIZE_Y - 1; + } + } + + uint8_t ball_corner_X[4] = { + playersMutex->ball_X, + playersMutex->ball_X + BALL_SIZE, + playersMutex->ball_X + BALL_SIZE, + playersMutex->ball_X}; + uint8_t ball_corner_Y[4] = { + playersMutex->ball_Y, + playersMutex->ball_Y, + playersMutex->ball_Y + BALL_SIZE, + playersMutex->ball_Y + BALL_SIZE}; + bool insidePlayer1 = false, insidePlayer2 = false; + + for(int i = 0; i < 4; i++) { + if(insidePad( + ball_corner_X[i], + ball_corner_Y[i], + playersMutex->player1_X, + playersMutex->player1_Y) == true) { + insidePlayer1 = true; + break; + } + + if(insidePad( + ball_corner_X[i], + ball_corner_Y[i], + playersMutex->player2_X, + playersMutex->player2_Y) == true) { + insidePlayer2 = true; + break; + } + } + + if(insidePlayer1 == true) { + playersMutex->ball_X_direction = 0; + playersMutex->ball_X -= playersMutex->ball_X_speed; + playersMutex->ball_X_speed = changeSpeed(); + playersMutex->ball_Y_speed = changeSpeed(); + notification_message(notification, &sequence_set_only_red_255); + } else if(insidePlayer2 == true) { + playersMutex->ball_X_direction = 1; + playersMutex->ball_X += playersMutex->ball_X_speed; + playersMutex->ball_X_speed = changeSpeed(); + playersMutex->ball_Y_speed = changeSpeed(); + notification_message(notification, &sequence_set_only_blue_255); + } else { + if(playersMutex->ball_X_direction == 1) { + if(playersMutex->ball_X <= + SCREEN_SIZE_X - BALL_SIZE - 1 - playersMutex->ball_X_speed) { + playersMutex->ball_X += playersMutex->ball_X_speed; + } else { + playersMutex->ball_X = SCREEN_SIZE_X / 2 - BALL_SIZE / 2; + playersMutex->ball_Y = SCREEN_SIZE_Y / 2 - BALL_SIZE / 2; + playersMutex->ball_X_speed = 1; + playersMutex->ball_Y_speed = 1; + playersMutex->ball_X_direction = 0; + playersMutex->player2_score++; + notification_message(notification, &sequence_set_only_red_255); + } + } else { + if(playersMutex->ball_X >= 1 + playersMutex->ball_X_speed) { + playersMutex->ball_X -= playersMutex->ball_X_speed; + } else { + playersMutex->ball_X = SCREEN_SIZE_X / 2 - BALL_SIZE / 2; + playersMutex->ball_Y = SCREEN_SIZE_Y / 2 - BALL_SIZE / 2; + playersMutex->ball_X_speed = 1; + playersMutex->ball_Y_speed = 1; + playersMutex->ball_X_direction = 1; + playersMutex->player1_score++; + notification_message(notification, &sequence_set_only_blue_255); + } + } + } + + if(playersMutex->ball_Y_direction == 1) { + if(playersMutex->ball_Y <= + SCREEN_SIZE_Y - BALL_SIZE - 1 - playersMutex->ball_Y_speed) { + playersMutex->ball_Y += playersMutex->ball_Y_speed; + } else { + playersMutex->ball_Y = SCREEN_SIZE_Y - BALL_SIZE - 1; + playersMutex->ball_X_speed = changeSpeed(); + playersMutex->ball_Y_speed = changeSpeed(); + playersMutex->ball_Y_direction = 0; + } + } else { + if(playersMutex->ball_Y >= 1 + playersMutex->ball_Y_speed) { + playersMutex->ball_Y -= playersMutex->ball_Y_speed; + } else { + playersMutex->ball_Y = 1; + playersMutex->ball_X_speed = changeSpeed(); + playersMutex->ball_Y_speed = changeSpeed(); + playersMutex->ball_Y_direction = 1; + } + } + } + } + + release_mutex(&state_mutex, playersMutex); + view_port_update(view_port); + } + + notification_message(notification, &sequence_reset_rgb); + + furi_message_queue_free(event_queue); + delete_mutex(&state_mutex); + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + furi_timer_free(timer); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); + + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_pong/img/Flipper_Zero.jpg b/Applications/Official/DEV_FW/source/xMasterX/flipper_pong/img/Flipper_Zero.jpg new file mode 100644 index 0000000000000000000000000000000000000000..76774824d565bf30f35df8e1e5394bb24c254bf4 GIT binary patch literal 44250 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 YxW?B~JgRBUbs&$y)78&qol`;+06CVnNdN!< literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_pong/img/flipper3.png b/Applications/Official/DEV_FW/source/xMasterX/flipper_pong/img/flipper3.png new file mode 100644 index 0000000000000000000000000000000000000000..fbabec8e2efe4853cf33c15b611528ef71a2c8a9 GIT binary patch literal 1615 zcmeAS@N?(olHy`uVBq!ia0y~yU<5Lm7&w@K)T1A&Yk(AUv6E*A2M5RPhyD*37}(f7 zT^vIy=DfXgGWU=JgG1m3jrLy}O}}FJPqj9ScDAU-J^Fu-_hiwrw)K+jo_y>K3=5uE z)E4fZcU_7-UqbKkn&-zIvTakVf*CX<3M!xGL06UGT@43}6OW-)kx1>bJ@ z#!zuT?)xj9lRR)itSUzZ(SmL?KyU;|SyVMcv|-G#`2L--=ec{H6j$$>wsR&UG{ITa z21bk9MQQuLKWuzF=it0`sd<-wC$K@1=aw(u8LFdxzk3-qEd?%Qd_cJ_{$3)SAGaX= z&(+TdjH|!cTmD~dzx_|#ZEluwa034+m!RmqZs*$H^V8wVjStMbb_(bORhSdb#x2sQUpD^(^~0%izW&+%y7JoR&9!OB hg)y3LV4ZN{2h-E6z@`H&XAOWn22WQ%mvv4FO#rxt&gcLD literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_pong/pong.png b/Applications/Official/DEV_FW/source/xMasterX/flipper_pong/pong.png new file mode 100644 index 0000000000000000000000000000000000000000..507ce711c0f97ee36d4c2d76800d0ba5463974da GIT binary patch literal 6459 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/.github/workflows/release.yml b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/.github/workflows/release.yml new file mode 100644 index 000000000..6f6b08a43 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/.github/workflows/release.yml @@ -0,0 +1,30 @@ +name: Release + +on: + push: + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' + +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: Checkout Flipper Zero Firmware + uses: actions/checkout@v3 + with: + repository: 'flipperdevices/flipperzero-firmware' + ref: '0.74.2' + submodules: true + - name: Checkout + uses: actions/checkout@v3 + with: + path: 'applications_user/qrcode_app' + - name: Build + run: ./fbt fap_qrcode + - name: Publish + uses: softprops/action-gh-release@v1 + with: + files: build/f7-firmware-D/.extapps/qrcode.fap + generate_release_notes: true + fail_on_unmatched_files: true diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/.gitignore b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/.gitignore new file mode 100644 index 000000000..c6127b38c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/.gitignore @@ -0,0 +1,52 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/LICENSE new file mode 100644 index 000000000..85e7f6b40 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Bob Matcuk + +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/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/README.md b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/README.md new file mode 100644 index 000000000..3a08bff24 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/README.md @@ -0,0 +1,156 @@ +# flipperzero-qrcode +Display qrcodes on the [Flipper Zero] + +## Download +Grab the latest `qrcode.fap` from [Releases]. + +## Installation +Copy the `qrcode.fap` file onto your [Flipper Zero] sd card in the `apps/Tools` +directory. Then create a top level directory called `qrcodes` to store your +qrcode files. This can be done using [qFlipper], for example, by +draging-and-dropping `qrcode.fap` into `apps/Tools` and then navigating back to +the top level (where the directories like `infrared` and `nfc` live), right +click, and create a new folder called `qrcodes`. + +## Creating QR Codes +qrcode files are simple text files with the extension `.qrcode`. This app will +expect them to live in a top-level directory on your sd card called `qrcodes`. +They should have the following content: + +``` +Filetype: QRCode +Version: 0 +Message: your content here +``` + +### Message Format +qrcodes support 4 formats called "modes": numeric, alpha-numeric, binary, and +kanji. Because of the limited screen real-estate on the [Flipper Zero], you'll +want to pick the best mode for the data you are trying to display. + +The app will automatically detect the best mode to use, so the only thing you +need to do is make sure the message in your file is formatted to use the best +mode. For example, if your message is entirely numeric, make sure you don't +include any extraneous punctuation in your file. If you're only encoding a +domain name, make sure it's uppercase to take advantage of alpha-numeric mode, +etc. + +#### Numeric Mode +Consists of only numbers, nothing else. This mode can encode the most data. + +#### Alpha-Numeric Mode +This mode can encode numbers, uppercase letters *only*, spaces, and the +following symbols: `$%*+-./:`. This format _may_ be appropriate for urls, as +long as you're only encoding the domain name and you remember to use uppercase +letters (ex: `HTTP://EXAMPLE.COM`). If your url includes some path after the +domain, you'll likely need to use binary mode because the paths are usually +case-sensitive. + +A qrcode in alpha-numeric mode can encode ~40% less data than numeric mode. + +#### Binary Mode +This mode is a little bit of a misnomer: binary mode simply means that the +message will be encoded as 8-bit bytes. The qrcode standard stipulates that +text will use ISO-8859-1 (also known as Latin-1) encoding, _not_ utf8 as would +be the standard these days. However, _some_ readers _may_ automatically detect +utf8. To be standard-compliant, that basically means you can only use Latin +letters, numbers, and symbols. + +A qrcode in binary mode can encode ~60% less data than numeric mode, and ~30% +less than alpha-numeric. + +#### Kanji Mode +This mode is unsupported, so I won't go into detail. A limitation of the +underlying qrcode library that I'm using, unfortunately. If there's interest, +perhaps I'll hack in support sometime. + +## Using the App +The app is fairly straightforward. When it first starts, the file browser will +automatically open to the `qrcodes` directory and display any `.qrcode` files. +Select one using the arrow keys and the center button. The qrcode will display. +If you push the right arrow, some stats will display: the qrcode "Version" - +which corresponds to how big it is; the ECC level - which determines the +qrcode's resilience to damage, such as a dirty screen (Low, Medium, Quartile, +and High); and the qrcode Mode (Numeric, Alpha-Numeric, Binary, or Kanji). + +While viewing the stats, you can select Version or ECC using the up and down +arrows and the center button. You can then increase or decrease the Version or +ECC using up and down and save your choice using the center buttton. This +feature was mostly added for my own amusement and testing, but, theoretically, +it may help a reader that's having trouble if the default ECC is less than the +highest value ("H"): you can increase the Version by 1 and then set the ECC to +"H". Whether or not this helps depends on the reader. + +You can hide the stats by pressing the left arrow. + +When you're done viewing the qrcode, press the back button to return to the +file browser. If you push the back button in the file browser, the app will +exit. + +I will ask that you temper your expectations: the Flipper Zero screen is small +and many readers may have difficulty reading the qrcodes, especially if they +are encoding a lot of data. However, I have successfully got my iPhone to read +qrcodes encoding phone numbers, wifi info, and a url, all the way up to a +version 11 qrcode (ie, the largest size the screen will fit). + +## Example: Wifi QRCodes +Most phones can automatically connect to wifi networks from a qrcode. If you +should like to encode your wifi's connection info into a qrcode, here's how +you'd do it: + +``` +Filetype: QRCode +Version: 0 +Message: WIFI:S:;P:;T:; +``` + +Replace `` with the name of your wifi, `` with the password. +`` would be "WPA" or "WEP". If your wifi is open (no password), +this can be "None" and you can remove `P:;` from the message. If your +wifi is hidden (ie, does not broadcast the ssid), you can add `H:true;` to the +end. + +Note that if your ssid or password contain any of these characters: `\";,:`, +you'll need to "escape" it by placing a backslash (`\`) before it. + +For example, if my ssid was "wifiball" and not broadcast, and the password was +"pa$$:word" with WPA encryption, the message would be: + +``` +Message: WIFI:S:wifiball;P:pa$$\:word;T:WPA;H:true; +``` + +## Building +First, clone the [flipperzero-firmware] repo and then clone this repo in the +`applications_user` directory: + +```bash +git clone git@github.com:flipperdevices/flipperzero-firmware.git +cd flipperzero-firmware/applications_user +git clone git@github.com:bmatcuk/flipperzero-qrcode.git +``` + +Next, in the base of the [flipperzero-firmware] directory, run fbt: + +```bash +cd .. +./fbt fap_qrcode +``` + +This will automatically install dependencies and build the application. When it +has finished building, the .fap will be in +`build/f7-firmware-D/.extapps/qrcode.fap` (fbt output will tell you where to +find the .fap, should it change in the future). + +## qrcode library +This application uses the [QRCode] library by ricmoo. This is the same library +that is in the lib directory of the flipper-firmware repo (which was originally +included for a [now-removed demo app]), but modified slightly to fix some +compiler errors. + +[now-removed demo app]: https://github.com/flipperdevices/flipperzero-firmware/pull/160/files +[flipperzero-firmware]: https://github.com/flipperdevices/flipperzero-firmware +[Flipper Zero]: https://flipperzero.one/ +[QRCode]: https://github.com/ricmoo/QRCode +[qFlipper]: https://docs.flipperzero.one/qflipper +[Releases]: https://github.com/bmatcuk/flipperzero-qrcode/releases/latest diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/application.fam b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/application.fam new file mode 100644 index 000000000..b3a67697e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/application.fam @@ -0,0 +1,19 @@ +App( + appid="qrcode", + name="QR Code", + fap_version=(1,1), + fap_description="Display qrcodes", + fap_author="Bob Matcuk", + fap_weburl="https://github.com/bmatcuk/flipperzero-qrcode", + apptype=FlipperAppType.EXTERNAL, + entry_point="qrcode_app", + stack_size=2 * 1024, + cdefines=["APP_QRCODE"], + requires=[ + "gui", + "dialogs", + ], + fap_category="Misc_Extra", + fap_icon="icons/qrcode_10px.png", + fap_icon_assets="icons", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/icons/qrcode_10px.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/icons/qrcode_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..cb31f09559d63b5bac586e22bd87fd6734b85628 GIT binary patch literal 1758 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V6Od#Ih^nUk#C56lsTcvPQUjyF)=hTc$kE){7;3~h6 zMhJ1(0FE1&_nsU?XD6}dTi#a0!zN?>!XfNYSkzLEl1NlCV?QiN}Sf^&XR zs)DJWsh)w79hZVlQA(Oskc%5sGmvMilu=SrV5P5LUS6(OZmgGIl&)`RX=$l%V5Dzk zqzhD`TU?n}l31aeSF8*&0%C?sYH@N=WG$~JK=YXR8 zw9Fi!Tyc=QlY*zKvzei#nVGJU9>f@6q*(#=W~NoTB$fbG85sc6rlFCpk!6UXk(G&| zm5GI}fvJ@NB)Gt;fq5Y%u_Td@dQgg1umS4u^|kWIEH23}sssx`l6i1yA%q9v=467? zw}JvVmaP(#L7{G|R8W+kQktBa0`?ZrIEZXx!bMZi*K$M&zU85kHFGlB7f5g!Z;8WT$=-q&splsImGJ0nSIp-2{I_~M0P z=BK8)>8_pm>2+H5+xA<}-qvp4az|^sw%45>r3d2=tSwqAGI5gkPPM!XuPc3hH$DF{ z=XvqI=QjS&ZP?dL+%oCnYMTispKU2P@O;+Hxy3i-3oke-=WcNkjg{qXZ3@}4U0Nq? z&nwgHP`mHzuj(EvWz{h~q};XYY0L4}W^K!>PkbMysfxym*ol>87dbx64(^}&*uBO{=O-$;GP)za~1cEdyR6I?_+*2C03+A zt}Wwl09F^A1s;*b3=DinK$vl=HlH+5(9P4uF+^f&t-m7|g8|2-8~^ve;cMN}RLZe+ zlhVBjEDb4)-m#{9!qO8=Z0{C7mW(WZwqCp=W^?gfMa|0X8-*UBj6U T(@m3sCNg-s`njxgN@xNA>JMyz literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/qrcode.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/qrcode.c new file mode 100644 index 000000000..c36285a17 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/qrcode.c @@ -0,0 +1,858 @@ +/** + * The MIT License (MIT) + * + * This library is written and maintained by Richard Moore. + * Major parts were derived from Project Nayuki's library. + * + * Copyright (c) 2017 Richard Moore (https://github.com/ricmoo/QRCode) + * Copyright (c) 2017 Project Nayuki (https://www.nayuki.io/page/qr-code-generator-library) + * + * 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. + */ + +/** + * Special thanks to Nayuki (https://www.nayuki.io/) from which this library was + * heavily inspired and compared against. + * + * See: https://github.com/nayuki/QR-Code-generator/tree/master/cpp + */ + +#include "qrcode.h" + +#include +#include + +#if LOCK_VERSION == 0 + +static const uint16_t NUM_ERROR_CORRECTION_CODEWORDS[4][40] = { + // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level + { 10, 16, 26, 36, 48, 64, 72, 88, 110, 130, 150, 176, 198, 216, 240, 280, 308, 338, 364, 416, 442, 476, 504, 560, 588, 644, 700, 728, 784, 812, 868, 924, 980, 1036, 1064, 1120, 1204, 1260, 1316, 1372}, // Medium + { 7, 10, 15, 20, 26, 36, 40, 48, 60, 72, 80, 96, 104, 120, 132, 144, 168, 180, 196, 224, 224, 252, 270, 300, 312, 336, 360, 390, 420, 450, 480, 510, 540, 570, 570, 600, 630, 660, 720, 750}, // Low + { 17, 28, 44, 64, 88, 112, 130, 156, 192, 224, 264, 308, 352, 384, 432, 480, 532, 588, 650, 700, 750, 816, 900, 960, 1050, 1110, 1200, 1260, 1350, 1440, 1530, 1620, 1710, 1800, 1890, 1980, 2100, 2220, 2310, 2430}, // High + { 13, 22, 36, 52, 72, 96, 108, 132, 160, 192, 224, 260, 288, 320, 360, 408, 448, 504, 546, 600, 644, 690, 750, 810, 870, 952, 1020, 1050, 1140, 1200, 1290, 1350, 1440, 1530, 1590, 1680, 1770, 1860, 1950, 2040}, // Quartile +}; + +static const uint8_t NUM_ERROR_CORRECTION_BLOCKS[4][40] = { + // Version: (note that index 0 is for padding, and is set to an illegal value) + // 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level + { 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49}, // Medium + { 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25}, // Low + { 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81}, // High + { 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68}, // Quartile +}; + +static const uint16_t NUM_RAW_DATA_MODULES[40] = { + // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 208, 359, 567, 807, 1079, 1383, 1568, 1936, 2336, 2768, 3232, 3728, 4256, 4651, 5243, 5867, 6523, + // 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 7211, 7931, 8683, 9252, 10068, 10916, 11796, 12708, 13652, 14628, 15371, 16411, 17483, 18587, + // 32, 33, 34, 35, 36, 37, 38, 39, 40 + 19723, 20891, 22091, 23008, 24272, 25568, 26896, 28256, 29648 +}; + +// @TODO: Put other LOCK_VERSIONS here +#elif LOCK_VERSION == 3 + +static const int16_t NUM_ERROR_CORRECTION_CODEWORDS[4] = { + 26, 15, 44, 36 +}; + +static const int8_t NUM_ERROR_CORRECTION_BLOCKS[4] = { + 1, 1, 2, 2 +}; + +static const uint16_t NUM_RAW_DATA_MODULES = 567; + +#else + +#error Unsupported LOCK_VERSION (add it...) + +#endif + + +static int max(int a, int b) { + if (a > b) { return a; } + return b; +} + +/* +static int abs(int value) { + if (value < 0) { return -value; } + return value; +} +*/ + + +static int8_t getAlphanumeric(char c) { + + if (c >= '0' && c <= '9') { return (c - '0'); } + if (c >= 'A' && c <= 'Z') { return (c - 'A' + 10); } + + switch (c) { + case ' ': return 36; + case '$': return 37; + case '%': return 38; + case '*': return 39; + case '+': return 40; + case '-': return 41; + case '.': return 42; + case '/': return 43; + case ':': return 44; + } + + return -1; +} + +static bool isAlphanumeric(const char *text, uint16_t length) { + while (length != 0) { + if (getAlphanumeric(text[--length]) == -1) { return false; } + } + return true; +} + + +static bool isNumeric(const char *text, uint16_t length) { + while (length != 0) { + char c = text[--length]; + if (c < '0' || c > '9') { return false; } + } + return true; +} + + +// We store the following tightly packed (less 8) in modeInfo +// <=9 <=26 <= 40 +// NUMERIC ( 10, 12, 14); +// ALPHANUMERIC ( 9, 11, 13); +// BYTE ( 8, 16, 16); +static char getModeBits(uint8_t version, uint8_t mode) { + // Note: We use 15 instead of 16; since 15 doesn't exist and we cannot store 16 (8 + 8) in 3 bits + // hex(int("".join(reversed([('00' + bin(x - 8)[2:])[-3:] for x in [10, 9, 8, 12, 11, 15, 14, 13, 15]])), 2)) + unsigned int modeInfo = 0x7bbb80a; + +#if LOCK_VERSION == 0 || LOCK_VERSION > 9 + if (version > 9) { modeInfo >>= 9; } +#endif + +#if LOCK_VERSION == 0 || LOCK_VERSION > 26 + if (version > 26) { modeInfo >>= 9; } +#endif + + char result = 8 + ((modeInfo >> (3 * mode)) & 0x07); + if (result == 15) { result = 16; } + + return result; +} + + +typedef struct BitBucket { + uint32_t bitOffsetOrWidth; + uint16_t capacityBytes; + uint8_t *data; +} BitBucket; + +/* +void bb_dump(BitBucket *bitBuffer) { + printf("Buffer: "); + for (uint32_t i = 0; i < bitBuffer->capacityBytes; i++) { + printf("%02x", bitBuffer->data[i]); + if ((i % 4) == 3) { printf(" "); } + } + printf("\n"); +} +*/ + +static uint16_t bb_getGridSizeBytes(uint8_t size) { + return (((size * size) + 7) / 8); +} + +static uint16_t bb_getBufferSizeBytes(uint32_t bits) { + return ((bits + 7) / 8); +} + +static void bb_initBuffer(BitBucket *bitBuffer, uint8_t *data, int32_t capacityBytes) { + bitBuffer->bitOffsetOrWidth = 0; + bitBuffer->capacityBytes = capacityBytes; + bitBuffer->data = data; + + memset(data, 0, bitBuffer->capacityBytes); +} + +static void bb_initGrid(BitBucket *bitGrid, uint8_t *data, uint8_t size) { + bitGrid->bitOffsetOrWidth = size; + bitGrid->capacityBytes = bb_getGridSizeBytes(size); + bitGrid->data = data; + + memset(data, 0, bitGrid->capacityBytes); +} + +static void bb_appendBits(BitBucket *bitBuffer, uint32_t val, uint8_t length) { + uint32_t offset = bitBuffer->bitOffsetOrWidth; + for (int8_t i = length - 1; i >= 0; i--, offset++) { + bitBuffer->data[offset >> 3] |= ((val >> i) & 1) << (7 - (offset & 7)); + } + bitBuffer->bitOffsetOrWidth = offset; +} +/* +void bb_setBits(BitBucket *bitBuffer, uint32_t val, int offset, uint8_t length) { + for (int8_t i = length - 1; i >= 0; i--, offset++) { + bitBuffer->data[offset >> 3] |= ((val >> i) & 1) << (7 - (offset & 7)); + } +} +*/ +static void bb_setBit(BitBucket *bitGrid, uint8_t x, uint8_t y, bool on) { + uint32_t offset = y * bitGrid->bitOffsetOrWidth + x; + uint8_t mask = 1 << (7 - (offset & 0x07)); + if (on) { + bitGrid->data[offset >> 3] |= mask; + } else { + bitGrid->data[offset >> 3] &= ~mask; + } +} + +static void bb_invertBit(BitBucket *bitGrid, uint8_t x, uint8_t y, bool invert) { + uint32_t offset = y * bitGrid->bitOffsetOrWidth + x; + uint8_t mask = 1 << (7 - (offset & 0x07)); + bool on = ((bitGrid->data[offset >> 3] & (1 << (7 - (offset & 0x07)))) != 0); + if (on ^ invert) { + bitGrid->data[offset >> 3] |= mask; + } else { + bitGrid->data[offset >> 3] &= ~mask; + } +} + +static bool bb_getBit(BitBucket *bitGrid, uint8_t x, uint8_t y) { + uint32_t offset = y * bitGrid->bitOffsetOrWidth + x; + return (bitGrid->data[offset >> 3] & (1 << (7 - (offset & 0x07)))) != 0; +} + + +// XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical +// properties, calling applyMask(m) twice with the same value is equivalent to no change at all. +// This means it is possible to apply a mask, undo it, and try another mask. Note that a final +// well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.). +static void applyMask(BitBucket *modules, BitBucket *isFunction, uint8_t mask) { + uint8_t size = modules->bitOffsetOrWidth; + + for (uint8_t y = 0; y < size; y++) { + for (uint8_t x = 0; x < size; x++) { + if (bb_getBit(isFunction, x, y)) { continue; } + + bool invert = 0; + switch (mask) { + case 0: invert = (x + y) % 2 == 0; break; + case 1: invert = y % 2 == 0; break; + case 2: invert = x % 3 == 0; break; + case 3: invert = (x + y) % 3 == 0; break; + case 4: invert = (x / 3 + y / 2) % 2 == 0; break; + case 5: invert = x * y % 2 + x * y % 3 == 0; break; + case 6: invert = (x * y % 2 + x * y % 3) % 2 == 0; break; + case 7: invert = ((x + y) % 2 + x * y % 3) % 2 == 0; break; + } + bb_invertBit(modules, x, y, invert); + } + } +} + +static void setFunctionModule(BitBucket *modules, BitBucket *isFunction, uint8_t x, uint8_t y, bool on) { + bb_setBit(modules, x, y, on); + bb_setBit(isFunction, x, y, true); +} + +// Draws a 9*9 finder pattern including the border separator, with the center module at (x, y). +static void drawFinderPattern(BitBucket *modules, BitBucket *isFunction, uint8_t x, uint8_t y) { + uint8_t size = modules->bitOffsetOrWidth; + + for (int8_t i = -4; i <= 4; i++) { + for (int8_t j = -4; j <= 4; j++) { + uint8_t dist = max(abs(i), abs(j)); // Chebyshev/infinity norm + int16_t xx = x + j, yy = y + i; + if (0 <= xx && xx < size && 0 <= yy && yy < size) { + setFunctionModule(modules, isFunction, xx, yy, dist != 2 && dist != 4); + } + } + } +} + +// Draws a 5*5 alignment pattern, with the center module at (x, y). +static void drawAlignmentPattern(BitBucket *modules, BitBucket *isFunction, uint8_t x, uint8_t y) { + for (int8_t i = -2; i <= 2; i++) { + for (int8_t j = -2; j <= 2; j++) { + setFunctionModule(modules, isFunction, x + j, y + i, max(abs(i), abs(j)) != 1); + } + } +} + +// Draws two copies of the format bits (with its own error correction code) +// based on the given mask and this object's error correction level field. +static void drawFormatBits(BitBucket *modules, BitBucket *isFunction, uint8_t ecc, uint8_t mask) { + + uint8_t size = modules->bitOffsetOrWidth; + + // Calculate error correction code and pack bits + uint32_t data = ecc << 3 | mask; // errCorrLvl is uint2, mask is uint3 + uint32_t rem = data; + for (int i = 0; i < 10; i++) { + rem = (rem << 1) ^ ((rem >> 9) * 0x537); + } + + data = data << 10 | rem; + data ^= 0x5412; // uint15 + + // Draw first copy + for (uint8_t i = 0; i <= 5; i++) { + setFunctionModule(modules, isFunction, 8, i, ((data >> i) & 1) != 0); + } + + setFunctionModule(modules, isFunction, 8, 7, ((data >> 6) & 1) != 0); + setFunctionModule(modules, isFunction, 8, 8, ((data >> 7) & 1) != 0); + setFunctionModule(modules, isFunction, 7, 8, ((data >> 8) & 1) != 0); + + for (int8_t i = 9; i < 15; i++) { + setFunctionModule(modules, isFunction, 14 - i, 8, ((data >> i) & 1) != 0); + } + + // Draw second copy + for (int8_t i = 0; i <= 7; i++) { + setFunctionModule(modules, isFunction, size - 1 - i, 8, ((data >> i) & 1) != 0); + } + + for (int8_t i = 8; i < 15; i++) { + setFunctionModule(modules, isFunction, 8, size - 15 + i, ((data >> i) & 1) != 0); + } + + setFunctionModule(modules, isFunction, 8, size - 8, true); +} + + +// Draws two copies of the version bits (with its own error correction code), +// based on this object's version field (which only has an effect for 7 <= version <= 40). +static void drawVersion(BitBucket *modules, BitBucket *isFunction, uint8_t version) { + + int8_t size = modules->bitOffsetOrWidth; + +#if LOCK_VERSION != 0 && LOCK_VERSION < 7 + return; + +#else + if (version < 7) { return; } + + // Calculate error correction code and pack bits + uint32_t rem = version; // version is uint6, in the range [7, 40] + for (uint8_t i = 0; i < 12; i++) { + rem = (rem << 1) ^ ((rem >> 11) * 0x1F25); + } + + uint32_t data = version << 12 | rem; // uint18 + + // Draw two copies + for (uint8_t i = 0; i < 18; i++) { + bool bit = ((data >> i) & 1) != 0; + uint8_t a = size - 11 + i % 3, b = i / 3; + setFunctionModule(modules, isFunction, a, b, bit); + setFunctionModule(modules, isFunction, b, a, bit); + } + +#endif +} + +static void drawFunctionPatterns(BitBucket *modules, BitBucket *isFunction, uint8_t version, uint8_t ecc) { + + uint8_t size = modules->bitOffsetOrWidth; + + // Draw the horizontal and vertical timing patterns + for (uint8_t i = 0; i < size; i++) { + setFunctionModule(modules, isFunction, 6, i, i % 2 == 0); + setFunctionModule(modules, isFunction, i, 6, i % 2 == 0); + } + + // Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules) + drawFinderPattern(modules, isFunction, 3, 3); + drawFinderPattern(modules, isFunction, size - 4, 3); + drawFinderPattern(modules, isFunction, 3, size - 4); + +#if LOCK_VERSION == 0 || LOCK_VERSION > 1 + + if (version > 1) { + + // Draw the numerous alignment patterns + + uint8_t alignCount = version / 7 + 2; + uint8_t step; + if (version != 32) { + step = (version * 4 + alignCount * 2 + 1) / (2 * alignCount - 2) * 2; // ceil((size - 13) / (2*numAlign - 2)) * 2 + } else { // C-C-C-Combo breaker! + step = 26; + } + + uint8_t alignPositionIndex = alignCount - 1; + uint8_t alignPosition[alignCount]; + + alignPosition[0] = 6; + + uint8_t size = version * 4 + 17; + for (uint8_t i = 0, pos = size - 7; i < alignCount - 1; i++, pos -= step) { + alignPosition[alignPositionIndex--] = pos; + } + + for (uint8_t i = 0; i < alignCount; i++) { + for (uint8_t j = 0; j < alignCount; j++) { + if ((i == 0 && j == 0) || (i == 0 && j == alignCount - 1) || (i == alignCount - 1 && j == 0)) { + continue; // Skip the three finder corners + } else { + drawAlignmentPattern(modules, isFunction, alignPosition[i], alignPosition[j]); + } + } + } + } + +#endif + + // Draw configuration data + drawFormatBits(modules, isFunction, ecc, 0); // Dummy mask value; overwritten later in the constructor + drawVersion(modules, isFunction, version); +} + + +// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire +// data area of this QR Code symbol. Function modules need to be marked off before this is called. +static void drawCodewords(BitBucket *modules, BitBucket *isFunction, BitBucket *codewords) { + + uint32_t bitLength = codewords->bitOffsetOrWidth; + uint8_t *data = codewords->data; + + uint8_t size = modules->bitOffsetOrWidth; + + // Bit index into the data + uint32_t i = 0; + + // Do the funny zigzag scan + for (int16_t right = size - 1; right >= 1; right -= 2) { // Index of right column in each column pair + if (right == 6) { right = 5; } + + for (uint8_t vert = 0; vert < size; vert++) { // Vertical counter + for (int j = 0; j < 2; j++) { + uint8_t x = right - j; // Actual x coordinate + bool upwards = ((right & 2) == 0) ^ (x < 6); + uint8_t y = upwards ? size - 1 - vert : vert; // Actual y coordinate + if (!bb_getBit(isFunction, x, y) && i < bitLength) { + bb_setBit(modules, x, y, ((data[i >> 3] >> (7 - (i & 7))) & 1) != 0); + i++; + } + // If there are any remainder bits (0 to 7), they are already + // set to 0/false/white when the grid of modules was initialized + } + } + } +} + + + +#define PENALTY_N1 3 +#define PENALTY_N2 3 +#define PENALTY_N3 40 +#define PENALTY_N4 10 + +// Calculates and returns the penalty score based on state of this QR Code's current modules. +// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score. +// @TODO: This can be optimized by working with the bytes instead of bits. +static uint32_t getPenaltyScore(BitBucket *modules) { + uint32_t result = 0; + + uint8_t size = modules->bitOffsetOrWidth; + + // Adjacent modules in row having same color + for (uint8_t y = 0; y < size; y++) { + + bool colorX = bb_getBit(modules, 0, y); + for (uint8_t x = 1, runX = 1; x < size; x++) { + bool cx = bb_getBit(modules, x, y); + if (cx != colorX) { + colorX = cx; + runX = 1; + + } else { + runX++; + if (runX == 5) { + result += PENALTY_N1; + } else if (runX > 5) { + result++; + } + } + } + } + + // Adjacent modules in column having same color + for (uint8_t x = 0; x < size; x++) { + bool colorY = bb_getBit(modules, x, 0); + for (uint8_t y = 1, runY = 1; y < size; y++) { + bool cy = bb_getBit(modules, x, y); + if (cy != colorY) { + colorY = cy; + runY = 1; + } else { + runY++; + if (runY == 5) { + result += PENALTY_N1; + } else if (runY > 5) { + result++; + } + } + } + } + + uint16_t black = 0; + for (uint8_t y = 0; y < size; y++) { + uint16_t bitsRow = 0, bitsCol = 0; + for (uint8_t x = 0; x < size; x++) { + bool color = bb_getBit(modules, x, y); + + // 2*2 blocks of modules having same color + if (x > 0 && y > 0) { + bool colorUL = bb_getBit(modules, x - 1, y - 1); + bool colorUR = bb_getBit(modules, x, y - 1); + bool colorL = bb_getBit(modules, x - 1, y); + if (color == colorUL && color == colorUR && color == colorL) { + result += PENALTY_N2; + } + } + + // Finder-like pattern in rows and columns + bitsRow = ((bitsRow << 1) & 0x7FF) | color; + bitsCol = ((bitsCol << 1) & 0x7FF) | bb_getBit(modules, y, x); + + // Needs 11 bits accumulated + if (x >= 10) { + if (bitsRow == 0x05D || bitsRow == 0x5D0) { + result += PENALTY_N3; + } + if (bitsCol == 0x05D || bitsCol == 0x5D0) { + result += PENALTY_N3; + } + } + + // Balance of black and white modules + if (color) { black++; } + } + } + + // Find smallest k such that (45-5k)% <= dark/total <= (55+5k)% + uint16_t total = size * size; + for (uint16_t k = 0; black * 20 < (9 - k) * total || black * 20 > (11 + k) * total; k++) { + result += PENALTY_N4; + } + + return result; +} + + +static uint8_t rs_multiply(uint8_t x, uint8_t y) { + // Russian peasant multiplication + // See: https://en.wikipedia.org/wiki/Ancient_Egyptian_multiplication + uint16_t z = 0; + for (int8_t i = 7; i >= 0; i--) { + z = (z << 1) ^ ((z >> 7) * 0x11D); + z ^= ((y >> i) & 1) * x; + } + return z; +} + +static void rs_init(uint8_t degree, uint8_t *coeff) { + memset(coeff, 0, degree); + coeff[degree - 1] = 1; + + // Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}), + // drop the highest term, and store the rest of the coefficients in order of descending powers. + // Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D). + uint16_t root = 1; + for (uint8_t i = 0; i < degree; i++) { + // Multiply the current product by (x - r^i) + for (uint8_t j = 0; j < degree; j++) { + coeff[j] = rs_multiply(coeff[j], root); + if (j + 1 < degree) { + coeff[j] ^= coeff[j + 1]; + } + } + root = (root << 1) ^ ((root >> 7) * 0x11D); // Multiply by 0x02 mod GF(2^8/0x11D) + } +} + +static void rs_getRemainder(uint8_t degree, uint8_t *coeff, uint8_t *data, uint8_t length, uint8_t *result, uint8_t stride) { + // Compute the remainder by performing polynomial division + + //for (uint8_t i = 0; i < degree; i++) { result[] = 0; } + //memset(result, 0, degree); + + for (uint8_t i = 0; i < length; i++) { + uint8_t factor = data[i] ^ result[0]; + for (uint8_t j = 1; j < degree; j++) { + result[(j - 1) * stride] = result[j * stride]; + } + result[(degree - 1) * stride] = 0; + + for (uint8_t j = 0; j < degree; j++) { + result[j * stride] ^= rs_multiply(coeff[j], factor); + } + } +} + + + +static int8_t encodeDataCodewords(BitBucket *dataCodewords, const uint8_t *text, uint16_t length, uint8_t version) { + int8_t mode = MODE_BYTE; + + if (isNumeric((char*)text, length)) { + mode = MODE_NUMERIC; + bb_appendBits(dataCodewords, 1 << MODE_NUMERIC, 4); + bb_appendBits(dataCodewords, length, getModeBits(version, MODE_NUMERIC)); + + uint16_t accumData = 0; + uint8_t accumCount = 0; + for (uint16_t i = 0; i < length; i++) { + accumData = accumData * 10 + ((char)(text[i]) - '0'); + accumCount++; + if (accumCount == 3) { + bb_appendBits(dataCodewords, accumData, 10); + accumData = 0; + accumCount = 0; + } + } + + // 1 or 2 digits remaining + if (accumCount > 0) { + bb_appendBits(dataCodewords, accumData, accumCount * 3 + 1); + } + + } else if (isAlphanumeric((char*)text, length)) { + mode = MODE_ALPHANUMERIC; + bb_appendBits(dataCodewords, 1 << MODE_ALPHANUMERIC, 4); + bb_appendBits(dataCodewords, length, getModeBits(version, MODE_ALPHANUMERIC)); + + uint16_t accumData = 0; + uint8_t accumCount = 0; + for (uint16_t i = 0; i < length; i++) { + accumData = accumData * 45 + getAlphanumeric((char)(text[i])); + accumCount++; + if (accumCount == 2) { + bb_appendBits(dataCodewords, accumData, 11); + accumData = 0; + accumCount = 0; + } + } + + // 1 character remaining + if (accumCount > 0) { + bb_appendBits(dataCodewords, accumData, 6); + } + + } else { + bb_appendBits(dataCodewords, 1 << MODE_BYTE, 4); + bb_appendBits(dataCodewords, length, getModeBits(version, MODE_BYTE)); + for (uint16_t i = 0; i < length; i++) { + bb_appendBits(dataCodewords, (char)(text[i]), 8); + } + } + + //bb_setBits(dataCodewords, length, 4, getModeBits(version, mode)); + + return mode; +} + +static void performErrorCorrection(uint8_t version, uint8_t ecc, BitBucket *data) { + + // See: http://www.thonky.com/qr-code-tutorial/structure-final-message + +#if LOCK_VERSION == 0 + uint8_t numBlocks = NUM_ERROR_CORRECTION_BLOCKS[ecc][version - 1]; + uint16_t totalEcc = NUM_ERROR_CORRECTION_CODEWORDS[ecc][version - 1]; + uint16_t moduleCount = NUM_RAW_DATA_MODULES[version - 1]; +#else + uint8_t numBlocks = NUM_ERROR_CORRECTION_BLOCKS[ecc]; + uint16_t totalEcc = NUM_ERROR_CORRECTION_CODEWORDS[ecc]; + uint16_t moduleCount = NUM_RAW_DATA_MODULES; +#endif + + uint8_t blockEccLen = totalEcc / numBlocks; + uint8_t numShortBlocks = numBlocks - moduleCount / 8 % numBlocks; + uint8_t shortBlockLen = moduleCount / 8 / numBlocks; + + uint8_t shortDataBlockLen = shortBlockLen - blockEccLen; + + uint8_t result[data->capacityBytes]; + memset(result, 0, sizeof(result)); + + uint8_t coeff[blockEccLen]; + rs_init(blockEccLen, coeff); + + uint16_t offset = 0; + uint8_t *dataBytes = data->data; + + + // Interleave all short blocks + for (uint8_t i = 0; i < shortDataBlockLen; i++) { + uint16_t index = i; + uint8_t stride = shortDataBlockLen; + for (uint8_t blockNum = 0; blockNum < numBlocks; blockNum++) { + result[offset++] = dataBytes[index]; + +#if LOCK_VERSION == 0 || LOCK_VERSION >= 5 + if (blockNum == numShortBlocks) { stride++; } +#endif + index += stride; + } + } + + // Version less than 5 only have short blocks +#if LOCK_VERSION == 0 || LOCK_VERSION >= 5 + { + // Interleave long blocks + uint16_t index = shortDataBlockLen * (numShortBlocks + 1); + uint8_t stride = shortDataBlockLen; + for (uint8_t blockNum = 0; blockNum < numBlocks - numShortBlocks; blockNum++) { + result[offset++] = dataBytes[index]; + + if (blockNum == 0) { stride++; } + index += stride; + } + } +#endif + + // Add all ecc blocks, interleaved + uint8_t blockSize = shortDataBlockLen; + for (uint8_t blockNum = 0; blockNum < numBlocks; blockNum++) { + +#if LOCK_VERSION == 0 || LOCK_VERSION >= 5 + if (blockNum == numShortBlocks) { blockSize++; } +#endif + rs_getRemainder(blockEccLen, coeff, dataBytes, blockSize, &result[offset + blockNum], numBlocks); + dataBytes += blockSize; + } + + memcpy(data->data, result, data->capacityBytes); + data->bitOffsetOrWidth = moduleCount; +} + +// We store the Format bits tightly packed into a single byte (each of the 4 modes is 2 bits) +// The format bits can be determined by ECC_FORMAT_BITS >> (2 * ecc) +static const uint8_t ECC_FORMAT_BITS = (0x02 << 6) | (0x03 << 4) | (0x00 << 2) | (0x01 << 0); + + +uint16_t qrcode_getBufferSize(uint8_t version) { + return bb_getGridSizeBytes(4 * version + 17); +} + +// @TODO: Return error if data is too big. +int8_t qrcode_initBytes(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, uint8_t *data, uint16_t length) { + uint8_t size = version * 4 + 17; + qrcode->version = version; + qrcode->size = size; + qrcode->ecc = ecc; + qrcode->modules = modules; + + uint8_t eccFormatBits = (ECC_FORMAT_BITS >> (2 * ecc)) & 0x03; + +#if LOCK_VERSION == 0 + uint16_t moduleCount = NUM_RAW_DATA_MODULES[version - 1]; + uint16_t dataCapacity = moduleCount / 8 - NUM_ERROR_CORRECTION_CODEWORDS[eccFormatBits][version - 1]; +#else + version = LOCK_VERSION; + uint16_t moduleCount = NUM_RAW_DATA_MODULES; + uint16_t dataCapacity = moduleCount / 8 - NUM_ERROR_CORRECTION_CODEWORDS[eccFormatBits]; +#endif + + struct BitBucket codewords; + uint8_t codewordBytes[bb_getBufferSizeBytes(moduleCount)]; + bb_initBuffer(&codewords, codewordBytes, (int32_t)sizeof(codewordBytes)); + + // Place the data code words into the buffer + int8_t mode = encodeDataCodewords(&codewords, data, length, version); + + if (mode < 0) { return -1; } + qrcode->mode = mode; + + // Add terminator and pad up to a byte if applicable + uint32_t padding = (dataCapacity * 8) - codewords.bitOffsetOrWidth; + if (padding > 4) { padding = 4; } + bb_appendBits(&codewords, 0, padding); + bb_appendBits(&codewords, 0, (8 - codewords.bitOffsetOrWidth % 8) % 8); + + // Pad with alternate bytes until data capacity is reached + for (uint8_t padByte = 0xEC; codewords.bitOffsetOrWidth < (dataCapacity * 8); padByte ^= 0xEC ^ 0x11) { + bb_appendBits(&codewords, padByte, 8); + } + + BitBucket modulesGrid; + bb_initGrid(&modulesGrid, modules, size); + + BitBucket isFunctionGrid; + uint8_t isFunctionGridBytes[bb_getGridSizeBytes(size)]; + bb_initGrid(&isFunctionGrid, isFunctionGridBytes, size); + + // Draw function patterns, draw all codewords, do masking + drawFunctionPatterns(&modulesGrid, &isFunctionGrid, version, eccFormatBits); + performErrorCorrection(version, eccFormatBits, &codewords); + drawCodewords(&modulesGrid, &isFunctionGrid, &codewords); + + // Find the best (lowest penalty) mask + uint8_t mask = 0; + int32_t minPenalty = INT32_MAX; + for (uint8_t i = 0; i < 8; i++) { + drawFormatBits(&modulesGrid, &isFunctionGrid, eccFormatBits, i); + applyMask(&modulesGrid, &isFunctionGrid, i); + int penalty = getPenaltyScore(&modulesGrid); + if (penalty < minPenalty) { + mask = i; + minPenalty = penalty; + } + applyMask(&modulesGrid, &isFunctionGrid, i); // Undoes the mask due to XOR + } + + qrcode->mask = mask; + + // Overwrite old format bits + drawFormatBits(&modulesGrid, &isFunctionGrid, eccFormatBits, mask); + + // Apply the final choice of mask + applyMask(&modulesGrid, &isFunctionGrid, mask); + + return 0; +} + +int8_t qrcode_initText(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, const char *data) { + return qrcode_initBytes(qrcode, modules, version, ecc, (uint8_t*)data, strlen(data)); +} + +bool qrcode_getModule(QRCode *qrcode, uint8_t x, uint8_t y) { + if (x >= qrcode->size || y >= qrcode->size) { + return false; + } + + uint32_t offset = y * qrcode->size + x; + return (qrcode->modules[offset >> 3] & (1 << (7 - (offset & 0x07)))) != 0; +} + +/* +uint8_t qrcode_getHexLength(QRCode *qrcode) { + return ((qrcode->size * qrcode->size) + 7) / 4; +} + +void qrcode_getHex(QRCode *qrcode, char *result) { + +} +*/ diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/qrcode.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/qrcode.h new file mode 100644 index 000000000..6e8bf1c36 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/qrcode.h @@ -0,0 +1,100 @@ +/** + * The MIT License (MIT) + * + * This library is written and maintained by Richard Moore. + * Major parts were derived from Project Nayuki's library. + * + * Copyright (c) 2017 Richard Moore (https://github.com/ricmoo/QRCode) + * Copyright (c) 2017 Project Nayuki (https://www.nayuki.io/page/qr-code-generator-library) + * + * 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. + */ + +/** + * Special thanks to Nayuki (https://www.nayuki.io/) from which this library was + * heavily inspired and compared against. + * + * See: https://github.com/nayuki/QR-Code-generator/tree/master/cpp + */ + + +#ifndef __QRCODE_H_ +#define __QRCODE_H_ + +// #ifndef __cplusplus +// typedef unsigned char bool; +// static const bool false = 0; +// static const bool true = 1; +// #endif + +#include +#include + + +// QR Code Format Encoding +#define MODE_NUMERIC 0 +#define MODE_ALPHANUMERIC 1 +#define MODE_BYTE 2 + + +// Error Correction Code Levels +#define ECC_LOW 0 +#define ECC_MEDIUM 1 +#define ECC_QUARTILE 2 +#define ECC_HIGH 3 + + +// If set to non-zero, this library can ONLY produce QR codes at that version +// This saves a lot of dynamic memory, as the codeword tables are skipped +#ifndef LOCK_VERSION +#define LOCK_VERSION 0 +#endif + + +typedef struct QRCode { + uint8_t version; + uint8_t size; + uint8_t ecc; + uint8_t mode; + uint8_t mask; + uint8_t *modules; +} QRCode; + + +#ifdef __cplusplus +extern "C"{ +#endif /* __cplusplus */ + + + +uint16_t qrcode_getBufferSize(uint8_t version); + +int8_t qrcode_initText(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, const char *data); +int8_t qrcode_initBytes(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, uint8_t *data, uint16_t length); + +bool qrcode_getModule(QRCode *qrcode, uint8_t x, uint8_t y); + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __QRCODE_H_ */ diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/qrcode_app.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/qrcode_app.c new file mode 100644 index 000000000..8a4d36783 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/qrcode_app.c @@ -0,0 +1,586 @@ +#include + +#include +#include +#include + +#include + +// this file is generated by the build script +#include +#include "qrcode.h" + +#define TAG "qrcode" +#define QRCODE_FOLDER ANY_PATH("qrcodes") +#define QRCODE_EXTENSION ".qrcode" +#define QRCODE_FILETYPE "QRCode" +#define QRCODE_FILE_VERSION 0 + +/** + * Maximum version is 11 because the f0 screen is only 64 pixels high and + * version 12 is 65x65. Version 11 is 61x61. + */ +#define MAX_QRCODE_VERSION 11 + +/** Maximum length by mode, ecc, and version */ +static const uint16_t MAX_LENGTH[3][4][MAX_QRCODE_VERSION] = { + { + // Numeric + {41, 77, 127, 187, 255, 322, 370, 461, 552, 652, 772}, // Low + {34, 63, 101, 149, 202, 255, 293, 365, 432, 513, 604}, // Medium + {27, 48, 77, 111, 144, 178, 207, 259, 312, 364, 427}, // Quartile + {17, 34, 58, 82, 106, 139, 154, 202, 235, 288, 331}, // High + }, + { + // Alphanumeric + {25, 47, 77, 114, 154, 195, 224, 279, 335, 395, 468}, // Low + {20, 38, 61, 90, 122, 154, 178, 221, 262, 311, 366}, // Medium + {16, 29, 47, 67, 87, 108, 125, 157, 189, 221, 259}, // Quartile + {10, 20, 35, 50, 64, 84, 93, 122, 143, 174, 200}, // High + }, + { + // Binary + {17, 32, 53, 78, 106, 134, 154, 192, 230, 271, 321}, // Low + {14, 26, 42, 62, 84, 106, 122, 152, 180, 213, 251}, // Medium + {11, 20, 32, 46, 60, 74, 86, 108, 130, 151, 177}, // Quartile + {7, 14, 24, 34, 44, 58, 64, 84, 98, 119, 137}, // High + }, +}; + +/** Main app instance */ +typedef struct { + FuriMessageQueue* input_queue; + Gui* gui; + ViewPort* view_port; + + FuriMutex** mutex; + FuriString* message; + QRCode* qrcode; + uint8_t min_version; + uint8_t max_ecc_at_min_version; + bool loading; + bool too_long; + bool show_stats; + uint8_t selected_idx; + bool edit; + uint8_t set_version; + uint8_t set_ecc; +} QRCodeApp; + +/** + * @param ecc ECC number + * @returns a character corresponding to the ecc level + */ +static char get_ecc_char(uint8_t ecc) { + switch (ecc) { + case 0: return 'L'; + case 1: return 'M'; + case 2: return 'Q'; + case 3: return 'H'; + default: return '?'; + } +} + +/** + * @param mode qrcode mode + * @returns a character corresponding to the mode + */ +static char get_mode_char(uint8_t mode) { + switch (mode) { + case 0: return 'N'; + case 1: return 'A'; + case 2: return 'B'; + case 3: return 'K'; + default: return '?'; + } +} + +/** + * Render + * @param canvas The canvas to render to + * @param ctx Context provided to the callback by view_port_draw_callback_set + */ +static void render_callback(Canvas* canvas, void* ctx) { + furi_assert(canvas); + furi_assert(ctx); + + QRCodeApp* instance = ctx; + furi_check(furi_mutex_acquire(instance->mutex, FuriWaitForever) == FuriStatusOk); + + canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontPrimary); + + uint8_t font_height = canvas_current_font_height(canvas); + uint8_t width = canvas_width(canvas); + uint8_t height = canvas_height(canvas); + if (instance->loading) { + canvas_draw_str_aligned(canvas, width / 2, height / 2, AlignCenter, AlignCenter, "Loading..."); + } else if (instance->qrcode) { + uint8_t size = instance->qrcode->size; + uint8_t pixel_size = height / size; + uint8_t top = (height - pixel_size * size) / 2; + uint8_t left = ((instance->show_stats ? 65 : width) - pixel_size * size) / 2; + for (uint8_t y = 0; y < size; y++) { + for (uint8_t x = 0; x < size; x++) { + if (qrcode_getModule(instance->qrcode, x, y)) { + if (pixel_size == 1) { + canvas_draw_dot(canvas, left + x * pixel_size, top + y * pixel_size); + } else { + canvas_draw_box(canvas, left + x * pixel_size, top + y * pixel_size, pixel_size, pixel_size); + } + } + } + } + + if (instance->show_stats) { + top = 10; + left = 66; + + FuriString* str = furi_string_alloc(); + + if (!instance->edit || instance->selected_idx == 0) { + furi_string_printf(str, "Ver: %i", instance->set_version); + canvas_draw_str(canvas, left + 5, top + font_height, furi_string_get_cstr(str)); + if (instance->selected_idx == 0) { + canvas_draw_triangle(canvas, left, top + font_height / 2, font_height - 4, 4, CanvasDirectionLeftToRight); + } + if (instance->edit) { + uint8_t arrow_left = left + 5 + canvas_string_width(canvas, "Ver: 8") / 2; + canvas_draw_triangle(canvas, arrow_left, top, font_height - 4, 4, CanvasDirectionBottomToTop); + canvas_draw_triangle(canvas, arrow_left, top + font_height + 1, font_height - 4, 4, CanvasDirectionTopToBottom); + } + } + + if (!instance->edit || instance->selected_idx == 1) { + furi_string_printf(str, "ECC: %c", get_ecc_char(instance->set_ecc)); + canvas_draw_str(canvas, left + 5, 2 * font_height + top + 2, furi_string_get_cstr(str)); + if (instance->selected_idx == 1) { + canvas_draw_triangle(canvas, left, 3 * font_height / 2 + top + 2, font_height - 4, 4, CanvasDirectionLeftToRight); + } + if (instance->edit) { + uint8_t arrow_left = left + 5 + canvas_string_width(canvas, "ECC: H") / 2; + canvas_draw_triangle(canvas, arrow_left, font_height + top + 2, font_height - 4, 4, CanvasDirectionBottomToTop); + canvas_draw_triangle(canvas, arrow_left, 2 * font_height + top + 3, font_height - 4, 4, CanvasDirectionTopToBottom); + } + } + + if (!instance->edit) { + furi_string_printf(str, "Mod: %c", get_mode_char(instance->qrcode->mode)); + canvas_draw_str(canvas, left + 5, 3 * font_height + top + 4, furi_string_get_cstr(str)); + } + + furi_string_free(str); + } + } else { + uint8_t margin = (height - font_height * 2) / 3; + canvas_draw_str_aligned(canvas, width / 2, margin, AlignCenter, AlignTop, "Could not load qrcode."); + if (instance->too_long) { + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, width / 2, margin * 2 + font_height, "Message is too long."); + } + } + + furi_mutex_release(instance->mutex); +} + +/** + * Handle input + * @param input_event The received input event + * @param ctx Context provided to the callback by view_port_input_callback_set + */ +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(input_event); + furi_assert(ctx); + if (input_event->type == InputTypeShort) { + QRCodeApp* instance = ctx; + furi_message_queue_put(instance->input_queue, input_event, 0); + } +} + +/** + * Determine if the given string is all numeric + * @param str The string to test + * @returns true if the string is all numeric + */ +static bool is_numeric(const char* str, uint16_t len) { + furi_assert(str); + while (len > 0) { + char c = str[--len]; + if (c < '0' || c > '9') return false; + } + return true; +} + +/** + * Determine if the given string is alphanumeric + * @param str The string to test + * @returns true if the string is alphanumeric + */ +static bool is_alphanumeric(const char* str, uint16_t len) { + furi_assert(str); + while (len > 0) { + char c = str[--len]; + if (c >= '0' && c <= '9') continue; + if (c >= 'A' && c <= 'Z') continue; + if (c == ' ' + || c == '$' + || c == '%' + || c == '*' + || c == '+' + || c == '-' + || c == '.' + || c == '/' + || c == ':') + continue; + return false; + } + return true; +} + +/** + * Allocate a qrcode + * @param version qrcode version + * @returns an allocated QRCode + */ +static QRCode* qrcode_alloc(uint8_t version) { + QRCode* qrcode = malloc(sizeof(QRCode)); + qrcode->modules = malloc(qrcode_getBufferSize(version)); + return qrcode; +} + +/** + * Free a QRCode + * @param qrcode The QRCode to free + */ +static void qrcode_free(QRCode* qrcode) { + furi_assert(qrcode); + free(qrcode->modules); + free(qrcode); +} + +/** + * Rebuild the qrcode. Assumes that instance->message is the message to encode, + * that the mutex has been acquired, and the specified version/ecc will be + * sufficiently large enough to encode the full message. It is also assumed + * that the old qrcode will be free'd by the caller. + * @param instance The qrcode app instance + * @param version The qrcode version to use + * @param ecc The qrcode ECC level to use + * @returns true if the qrcode was successfully created + */ +static bool rebuild_qrcode(QRCodeApp* instance, uint8_t version, uint8_t ecc) { + furi_assert(instance); + furi_assert(instance->message); + + const char* cstr = furi_string_get_cstr(instance->message); + uint16_t len = strlen(cstr); + instance->qrcode = qrcode_alloc(version); + + int8_t res = qrcode_initBytes(instance->qrcode, instance->qrcode->modules, version, ecc, (uint8_t*)cstr, len); + if (res != 0) { + FURI_LOG_E(TAG, "Could not create qrcode"); + + qrcode_free(instance->qrcode); + instance->qrcode = NULL; + + return false; + } + return true; +} + +/** + * Load a qrcode from a string + * @param instance The qrcode app instance + * @param str The message to encode as a qrcode + * @returns true if the string was successfully loaded + */ +static bool qrcode_load_string(QRCodeApp* instance, FuriString* str) { + furi_assert(instance); + furi_assert(str); + + furi_check(furi_mutex_acquire(instance->mutex, FuriWaitForever) == FuriStatusOk); + if (instance->message) { + furi_string_free(instance->message); + instance->message = NULL; + } + if (instance->qrcode) { + qrcode_free(instance->qrcode); + instance->qrcode = NULL; + } + instance->too_long = false; + instance->show_stats = false; + instance->selected_idx = 0; + instance->edit = false; + + bool result = false; + do { + const char* cstr = furi_string_get_cstr(str); + uint16_t len = strlen(cstr); + + instance->message = furi_string_alloc_set(str); + if (!instance->message) { + FURI_LOG_E(TAG, "Could not allocate message"); + break; + } + + // figure out the qrcode "mode" + uint8_t mode = MODE_BYTE; + if (is_numeric(cstr, len)) mode = MODE_NUMERIC; + else if (is_alphanumeric(cstr, len)) mode = MODE_ALPHANUMERIC; + + // Figure out the smallest qrcode version that'll fit all of the data - + // we prefer the smallest version to maximize the pixel size of each + // module to improve reader performance. Here, version is the 0-based + // index. The qrcode_initBytes function will want a 1-based version + // number, so we'll add one later. + uint8_t ecc = ECC_LOW; + uint8_t version = 0; + while (version < MAX_QRCODE_VERSION && MAX_LENGTH[mode][ecc][version] < len) { + version++; + } + + if (version == MAX_QRCODE_VERSION) { + instance->too_long = true; + break; + } + + // Figure out the maximum ECC we can use. I shouldn't need to + // bounds-check ecc in this loop because I already know from the loop + // above that ECC_LOW (0) works... don't forget to add one to that + // version number... + ecc = ECC_HIGH; + while (MAX_LENGTH[mode][ecc][version] < len) { + ecc--; + } + version++; + + // Build the qrcode + if (!rebuild_qrcode(instance, version, ecc)) { + furi_string_free(instance->message); + instance->message = NULL; + break; + } + + instance->min_version = instance->set_version = version; + instance->max_ecc_at_min_version = instance->set_ecc = ecc; + result = true; + } while (false); + + instance->loading = false; + + furi_mutex_release(instance->mutex); + + return result; +} + +/** + * Load a qrcode from a file + * @param instance The qrcode app instance + * @param file_path Path to the file to read + * @returns true if the file was successfully loaded + */ +static bool qrcode_load_file(QRCodeApp* instance, const char* file_path) { + furi_assert(instance); + furi_assert(file_path); + + FuriString* temp_str = furi_string_alloc(); + bool result = false; + + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* file = flipper_format_file_alloc(storage); + + do { + if (!flipper_format_file_open_existing(file, file_path)) break; + + uint32_t version = 0; + if (!flipper_format_read_header(file, temp_str, &version)) break; + if (furi_string_cmp_str(temp_str, QRCODE_FILETYPE) + || version != QRCODE_FILE_VERSION) { + FURI_LOG_E(TAG, "Incorrect file format or version"); + break; + } + + if (!flipper_format_read_string(file, "Message", temp_str)) { + FURI_LOG_E(TAG, "Message is missing"); + break; + } + + if (!qrcode_load_string(instance, temp_str)) { + break; + } + + result = true; + } while (false); + + furi_record_close(RECORD_STORAGE); + flipper_format_free(file); + furi_string_free(temp_str); + + return result; +} + +/** + * Allocate the qrcode app + * @returns a qrcode app instance + */ +static QRCodeApp* qrcode_app_alloc() { + QRCodeApp* instance = malloc(sizeof(QRCodeApp)); + + instance->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + instance->view_port = view_port_alloc(); + view_port_draw_callback_set(instance->view_port, render_callback, instance); + view_port_input_callback_set(instance->view_port, input_callback, instance); + + instance->gui = furi_record_open(RECORD_GUI); + gui_add_view_port(instance->gui, instance->view_port, GuiLayerFullscreen); + + instance->mutex = furi_mutex_alloc(FuriMutexTypeNormal); + + instance->message = NULL; + instance->qrcode = NULL; + instance->loading = true; + instance->too_long = false; + instance->show_stats = false; + instance->selected_idx = 0; + instance->edit = false; + + return instance; +} + +/** + * Free the qrcode app + * @param qrcode_app The app to free + */ +static void qrcode_app_free(QRCodeApp* instance) { + if (instance->message) furi_string_free(instance->message); + if (instance->qrcode) qrcode_free(instance->qrcode); + + gui_remove_view_port(instance->gui, instance->view_port); + furi_record_close(RECORD_GUI); + + view_port_free(instance->view_port); + + furi_message_queue_free(instance->input_queue); + + furi_mutex_free(instance->mutex); + + free(instance); +} + +/** App entrypoint */ +int32_t qrcode_app(void* p) { + QRCodeApp* instance = qrcode_app_alloc(); + FuriString* file_path = furi_string_alloc(); + + do { + if (p && strlen(p)) { + furi_string_set(file_path, (const char*)p); + } else { + furi_string_set(file_path, QRCODE_FOLDER); + + DialogsFileBrowserOptions browser_options; + dialog_file_browser_set_basic_options( + &browser_options, QRCODE_EXTENSION, &I_qrcode_10px); + browser_options.hide_ext = true; + browser_options.base_path = QRCODE_FOLDER; + + DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); + bool res = dialog_file_browser_show(dialogs, file_path, file_path, &browser_options); + + furi_record_close(RECORD_DIALOGS); + if (!res) { + FURI_LOG_E(TAG, "No file selected"); + break; + } + } + + if (!qrcode_load_file(instance, furi_string_get_cstr(file_path))) { + FURI_LOG_E(TAG, "Unable to load file"); + } + + InputEvent input; + while (furi_message_queue_get(instance->input_queue, &input, FuriWaitForever) == FuriStatusOk) { + furi_check(furi_mutex_acquire(instance->mutex, FuriWaitForever) == FuriStatusOk); + + if (input.key == InputKeyBack) { + if (instance->message) { + furi_string_free(instance->message); + instance->message = NULL; + } + if (instance->qrcode) { + qrcode_free(instance->qrcode); + instance->qrcode = NULL; + } + instance->loading = true; + instance->edit = false; + furi_mutex_release(instance->mutex); + break; + } else if (input.key == InputKeyRight) { + instance->show_stats = true; + } else if (input.key == InputKeyLeft) { + instance->show_stats = false; + } else if (instance->show_stats && !instance->loading && instance->qrcode) { + if (input.key == InputKeyUp) { + if (!instance->edit) { + instance->selected_idx = MAX(0, instance->selected_idx - 1); + } else { + if (instance->selected_idx == 0 && instance->set_version < MAX_QRCODE_VERSION) { + instance->set_version++; + } else if (instance->selected_idx == 1) { + uint8_t max_ecc = instance->set_version == instance->min_version ? instance->max_ecc_at_min_version : ECC_HIGH; + if (instance->set_ecc < max_ecc) { + instance->set_ecc++; + } + } + } + } else if (input.key == InputKeyDown) { + if (!instance->edit) { + instance->selected_idx = MIN(1, instance->selected_idx + 1); + } else { + if (instance->selected_idx == 0 && instance->set_version > instance->min_version) { + instance->set_version--; + if (instance->set_version == instance->min_version) { + instance->set_ecc = MAX(instance->set_ecc, instance->max_ecc_at_min_version); + } + } else if (instance->selected_idx == 1 && instance->set_ecc > 0) { + instance->set_ecc--; + } + } + } else if (input.key == InputKeyOk) { + if (instance->edit && (instance->set_version != instance->qrcode->version || instance->set_ecc != instance->qrcode->ecc)) { + QRCode* qrcode = instance->qrcode; + instance->loading = true; + + if (rebuild_qrcode(instance, instance->set_version, instance->set_ecc)) { + qrcode_free(qrcode); + } else { + FURI_LOG_E(TAG, "Could not rebuild qrcode"); + instance->qrcode = qrcode; + instance->set_version = qrcode->version; + instance->set_ecc = qrcode->ecc; + } + + instance->loading = false; + } + instance->edit = !instance->edit; + } + } + + furi_mutex_release(instance->mutex); + view_port_update(instance->view_port); + } + + if (p && strlen(p)) { + // if started with an arg, exit instead + // of looping back to the browser + break; + } + } while (true); + + furi_string_free(file_path); + qrcode_app_free(instance); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/scripts/check-firmware.sh b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/scripts/check-firmware.sh new file mode 100644 index 000000000..15f3bc9e1 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/scripts/check-firmware.sh @@ -0,0 +1,26 @@ +#!/bin/bash +set -Exeuo pipefail + +print_status() { + local level="$1" + local body="${2//%/%25}" + body="${body//$'\r'/}" + body="${body//$'\n'/%0A}" + + echo "::$level::$body" +} + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd -P)" +FIRMWARE_DIR="$1" + +LASTVER="$(git -C "$SCRIPT_DIR" tag | grep firmware-v | sort -V | tail -n1 | sed -e 's/^firmware-v//')" +print_status notice "last built against firmware version: $LASTVER" + +VER="$(git -C "$FIRMWARE_DIR" tag | sed -E -e '/^[0-9]+\.[0-9]+\.[0-9]+$/!d' | sort -V | sed -e "1,/$LASTVER/d" | tail -n1)" +# VER="$(curl https://api.github.com/repos/flipperdevices/flipperzero-firmware/tags | jq -r --arg current "$LASTVER" 'def ver($v): $v | ltrimstr("v") | split(".") | map(tonumber); map(.name) | map(select(. | test("^\\d+\\.\\d+\\.\\d+$";"s"))) | map(ver(.)) | map(select(. > ver($current))) | sort | last | if . == null then "" else join(".") end')" +if [ -z "$VER" ]; then + print_status notice "no new firmware version" + exit 0 +fi +print_status notice "new firmware version: $VER" +echo "version=$VER" >> $GITHUB_OUTPUT diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/scripts/update-firmware.sh b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/scripts/update-firmware.sh new file mode 100644 index 000000000..fadc99a4a --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-qrcode/scripts/update-firmware.sh @@ -0,0 +1,43 @@ +#!/bin/bash +set -Exeuo pipefail + +print_status() { + local level="$1" + local body="${2//%/%25}" + body="${body//$'\r'/}" + body="${body//$'\n'/%0A}" + + echo "::$level::$body" +} + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd -P)" +FIRMWARE_VER="$1" + +pushd "$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel)" +print_status notice "updating to firmware $FIRMWARE_VER" + +# setup git +git config --local user.name $GIT_USER_NAME +git config --local user.email $GIT_USER_EMAIL + +# construct a new version number for the qrcode app +VER="$(git tag | sed -E -e '/^v[0-9]+\.[0-9]+\.[0-9]+$/!d' | sort -V | tail -n1)" +if [[ "$VER" =~ ^(v[0-9]+.[0-9]+).([0-9]+)$ ]]; then + VER="${BASH_REMATCH[1]}.$(( ${BASH_REMATCH[2]} + 1 ))" +else + print_status warning "couldn't construct new version number from $VER" + exit 1 +fi +print_status notice "new qrcode version: $VER" + +# update firmware version in automation +sed -i -e "/firmware_version:/s/'.*'/'$FIRMWARE_VER'/" .github/workflows/release.yml + +# commit and tag +git add .github/workflows/release.yml +git commit -m "update to firmware $FIRMWARE_VER" +git tag -a -m "$VER" "$VER" +git tag "firmware-v$FIRMWARE_VER" +git push --atomic origin main "$VER" "firmware-v$FIRMWARE_VER" + +popd diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/LICENSE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/README.md b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/README.md new file mode 100644 index 000000000..5524eba3e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/README.md @@ -0,0 +1,30 @@ +# Tuning Fork + +Inspired by [Metronome](https://github.com/panki27/Metronome) + +A tuning fork for the [Flipper Zero](https://flipperzero.one/) device. +Allows to play different notes in different pitches. + +![screenshot](img/tuning_fork.gif) + +## Features +- Tuning forks (440Hz, 432Hz, etc.) +- Scientific pitch (..., 256Hz, 512Hz, 1024Hz, ...) +- Guitar Standard (6 strings) +- Guitar Drop D (6 strings) +- Guitar D (6 strings) +- Guitar Drop C (6 strings) +- Guitar Standard (7 strings) +- Bass Standard (4 strings) +- Bass Standard Tenor (4 strings) +- Bass Standard (5 strings) +- Bass Standard Tenor (5 strings) +- Bass Drop D (4 strings) +- Bass D (4 strings) +- Bass Drop A (5 strings) + +## Compiling + +``` +./fbt firmware_tuning_fork +``` diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/application.fam b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/application.fam new file mode 100644 index 000000000..f45f93b12 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/application.fam @@ -0,0 +1,14 @@ +App( + appid="tuning_fork", + name="Tuning Fork", + apptype=FlipperAppType.EXTERNAL, + entry_point="tuning_fork_app", + cdefines=["APP_TUNING_FORM"], + requires=[ + "gui", + ], + fap_icon="tuning_fork_icon.png", + fap_category="Music_Extra", + stack_size=2 * 1024, + order=20, +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/img/screenshot_1.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/img/screenshot_1.png new file mode 100644 index 0000000000000000000000000000000000000000..04727988936235f3ba0760c472bd3cd0b5533b23 GIT binary patch literal 1638 zcmeH{Z&2EG9LGQC^qfU@c{h96&s-h<^0l zmR^_n=vnJwDA0Y7slL0}*qK|cNj|5Gk(^pC?I^tL71UpW?l(^`Y4qu7<9_rlfb}nz z#w=}-;0+D|@@@;Y!^4`HCQq7_>s=S9lK$2Qg!h7#k7L+Kk-8173e zNw)M5|Kftr&pnyc5dUw0^<6Pd4{SYuGb4*7~KVt0xR zRcAt7cx}I7(U&JfLS*5!vT=doP^7}6Y#_kN!YIaRJQQ?N0QSIl+eCN3K9Q?S!$eT= z(RI+8P@hjzNr^GZxl{9vyMz1?TT`O#9iqH!e1Lm=Wg)F!!P z)ZRa0ekdnSxH;;T!4b0!_gZkwb|qlwLTpb*ql^-F+C?NHrM?B>O^Df=yOXn98C_Y< z9PX}Va|^cSLg-R`pW^VAPV44viPR>Y1Zh4O(k{{1w9m7wuLe`Cyhj^l)W9f9;I5tW zgxCIRUgh;-qP0TX<*JD7p?dP2#0-fvIb-J9(k~+a#UD~be7$mAH^5&NPjfU%WavCH zpip(wRF9>tsty?TTH!dy-6+>)uUl9%zHTp5mBRgG)iW!KFtV&o2PGQ>fSWt5Ixv~? z+nT?fT~VuXr?aXBR4bdLa1!Z^`_hN`r}g$@#PUtw8(|W_7u%gjKi3x=xP{gwr-|yR zlE(F)3AFv$We|^e2qzFP)7UoOI{y_Lv;65!Jhw*_(ehb6_gm3IsRw0!}5i# YxFhu+FP?f~8MOf@I#x`VzFyPuHz~C-6aWAK literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/img/screenshot_2.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/img/screenshot_2.png new file mode 100644 index 0000000000000000000000000000000000000000..c31f37744ddcb463906f7c58313d030b4da86abe GIT binary patch literal 1874 zcmcIlYfuwc6uuD&NO@=(HBbd9)1uArFiHWV;sZs|()i*L3MkZK6H$Q@agmU5sBH%V zS{@1lK@lG$gc&pnSz>I9X0S>?LNXAeSSBtQlJE*41VTd_hjpg5f9#LlyLWf?obPkZ07F_ z*}OlaT&;)+SFFQf+t1(}`w|!C6%1F6-aqe}L!-)Qrwvl*3?(4N=hBxZb)b-rF~G99fI<4_t&RX=@O*CZo`f;iu!5d6 z#qri8nnXn|hv-~d@WVxF-==I@P_Sn|2IPDQz~%X1)5=6J!>$Xa$LuqXjQ$8EkeR7U z>MxTN(c_=BE*s`DE#81_CukeLcBI!EjJ&j$?!3#i{Hf~kqNCYkvcBTeP zjwQ9E=qTB_x5+b}kR=BOEc^_zueuPeYbhy9O;*D-5pkJxh*{4$O{XAN^|f_kz6PJ? zFnBNGsV(ZKN4QPj7fP47$7ZV2-6*Oyfiyij`8nhZf2CiQ&v5t+eg&dZMKh14`w}hnT2k>|ki#K*A=+$Y$b@Rb6Qf?ojcou zA#Ydze&1@@yas7|H%f$})eI(+D=s;D{cx6>6bWM78hFd2KSUi`&q&d59 z=$c%t7>*Ks_j#19-lKd_DX$N?TM!LnqaGnfRnhe8xe9N@h=61oL+6{4o72{BLh)Vv6~b^y*oK{>D%OClD)QqDSbu~w#`QmSEU>8^XfW~C}Cqgf~)QXoe#5de#~BKC77 f{&kFj6X#|?V&IG0Ysd|UX5Z}G79PUga`4Qb68W

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

LE0adHEt{4OVq>_g4OC$HHoWg5SeawC{1 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/notes.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/notes.h new file mode 100644 index 000000000..c00b4f8ed --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/notes.h @@ -0,0 +1,158 @@ +#ifndef NOTES +#define NOTES + +#define C0 16.35f +#define Cs0 17.32f +#define Db0 17.32f +#define D0 18.35f +#define Ds0 19.45f +#define Eb0 19.45f +#define E0 20.60f +#define F0 21.83f +#define Fs0 23.12f +#define Gb0 23.12f +#define G0 24.50f +#define Gs0 25.96f +#define Ab0 25.96f +#define A0 27.50f +#define As0 29.14f +#define Bb0 29.14f +#define B0 30.868f +#define C1 32.70f +#define Cs1 34.65f +#define Db1 34.65f +#define D1 36.71f +#define Ds1 38.89f +#define Eb1 38.89f +#define E1 41.203f +#define F1 43.65f +#define Fs1 46.25f +#define Gb1 46.25f +#define G1 49.00f +#define Gs1 51.91f +#define Ab1 51.91f +#define A1 55.00f +#define As1 58.27f +#define Bb1 58.27f +#define B1 61.74f +#define C2 65.41f +#define Cs2 69.30f +#define Db2 69.30f +#define D2 73.416f +#define Ds2 77.78f +#define Eb2 77.78f +#define E2 82.41f +#define F2 87.31f +#define Fs2 92.50f +#define Gb2 92.50f +#define G2 97.999f +#define Gs2 103.83f +#define Ab2 103.83f +#define A2 110.00f +#define As2 116.54f +#define Bb2 116.54f +#define B2 123.47f +#define C3 130.813f +#define Cs3 138.59f +#define Db3 138.59f +#define D3 146.83f +#define Ds3 155.56f +#define Eb3 155.56f +#define E3 164.81f +#define F3 174.61f +#define Fs3 185.00f +#define Gb3 185.00f +#define G3 196.00f +#define Gs3 207.65f +#define Ab3 207.65f +#define A3 220.00f +#define As3 233.08f +#define Bb3 233.08f +#define B3 246.94f +#define C4 261.63f +#define Cs4 277.18f +#define Db4 277.18f +#define D4 293.66f +#define Ds4 311.13f +#define Eb4 311.13f +#define E4 329.63f +#define F4 349.23f +#define Fs4 369.99f +#define Gb4 369.99f +#define G4 392.00f +#define Gs4 415.30f +#define Ab4 415.30f +#define A4 440.00f +#define As4 466.16f +#define Bb4 466.16f +#define B4 493.88f +#define C5 523.25f +#define Cs5 554.37f +#define Db5 554.37f +#define D5 587.33f +#define Ds5 622.25f +#define Eb5 622.25f +#define E5 659.25f +#define F5 698.46f +#define Fs5 739.99f +#define Gb5 739.99f +#define G5 783.99f +#define Gs5 830.61f +#define Ab5 830.61f +#define A5 880.00f +#define As5 932.33f +#define Bb5 932.33f +#define B5 987.77f +#define C6 1046.50f +#define Cs6 1108.73f +#define Db6 1108.73f +#define D6 1174.66f +#define Ds6 1244.51f +#define Eb6 1244.51f +#define E6 1318.51f +#define F6 1396.91f +#define Fs6 1479.98f +#define Gb6 1479.98f +#define G6 1567.98f +#define Gs6 1661.22f +#define Ab6 1661.22f +#define A6 1760.00f +#define As6 1864.66f +#define Bb6 1864.66f +#define B6 1975.53f +#define C7 2093.00f +#define Cs7 2217.46f +#define Db7 2217.46f +#define D7 2349.32f +#define Ds7 2489.02f +#define Eb7 2489.02f +#define E7 2637.02f +#define F7 2793.83f +#define Fs7 2959.96f +#define Gb7 2959.96f +#define G7 3135.96f +#define Gs7 3322.44f +#define Ab7 3322.44f +#define A7 3520.00f +#define As7 3729.31f +#define Bb7 3729.31f +#define B7 3951.07f +#define C8 4186.01f +#define Cs8 4434.92f +#define Db8 4434.92f +#define D8 4698.63f +#define Ds8 4978.03f +#define Eb8 4978.03f +#define E8 5274.04f +#define F8 5587.65f +#define Fs8 5919.91f +#define Gb8 5919.91f +#define G8 6271.93f +#define Gs8 6644.88f +#define Ab8 6644.88f +#define A8 7040.00f +#define As8 7458.62f +#define Bb8 7458.62f +#define B8 7902.13f + +#endif //NOTES diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/tuning_fork.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/tuning_fork.c new file mode 100644 index 000000000..b2bc6fb96 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/tuning_fork.c @@ -0,0 +1,408 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "notes.h" +#include "tunings.h" + +typedef enum { + EventTypeTick, + EventTypeKey, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} PluginEvent; + +enum Page { Tunings, Notes }; + +typedef struct { + bool playing; + enum Page page; + int current_tuning_note_index; + int current_tuning_index; + float volume; + TUNING tuning; +} TuningForkState; + +static TUNING current_tuning(TuningForkState* tuningForkState) { + return tuningForkState->tuning; +} + +static NOTE current_tuning_note(TuningForkState* tuningForkState) { + return current_tuning(tuningForkState).notes[tuningForkState->current_tuning_note_index]; +} + +static float current_tuning_note_freq(TuningForkState* tuningForkState) { + return current_tuning_note(tuningForkState).frequency; +} + +static void current_tuning_note_label(TuningForkState* tuningForkState, char* outNoteLabel) { + for(int i = 0; i < 20; ++i) { + outNoteLabel[i] = current_tuning_note(tuningForkState).label[i]; + } +} + +static void current_tuning_label(TuningForkState* tuningForkState, char* outTuningLabel) { + for(int i = 0; i < 20; ++i) { + outTuningLabel[i] = current_tuning(tuningForkState).label[i]; + } +} + +static void updateTuning(TuningForkState* tuning_fork_state) { + tuning_fork_state->tuning = TuningList[tuning_fork_state->current_tuning_index]; + tuning_fork_state->current_tuning_note_index = 0; +} + +static void next_tuning(TuningForkState* tuning_fork_state) { + if(tuning_fork_state->current_tuning_index == TUNINGS_COUNT - 1) { + tuning_fork_state->current_tuning_index = 0; + } else { + tuning_fork_state->current_tuning_index += 1; + } + updateTuning(tuning_fork_state); +} + +static void prev_tuning(TuningForkState* tuning_fork_state) { + if(tuning_fork_state->current_tuning_index - 1 < 0) { + tuning_fork_state->current_tuning_index = TUNINGS_COUNT - 1; + } else { + tuning_fork_state->current_tuning_index -= 1; + } + updateTuning(tuning_fork_state); +} + +static void next_note(TuningForkState* tuning_fork_state) { + if(tuning_fork_state->current_tuning_note_index == + current_tuning(tuning_fork_state).notes_length - 1) { + tuning_fork_state->current_tuning_note_index = 0; + } else { + tuning_fork_state->current_tuning_note_index += 1; + } +} + +static void prev_note(TuningForkState* tuning_fork_state) { + if(tuning_fork_state->current_tuning_note_index == 0) { + tuning_fork_state->current_tuning_note_index = + current_tuning(tuning_fork_state).notes_length - 1; + } else { + tuning_fork_state->current_tuning_note_index -= 1; + } +} + +static void increase_volume(TuningForkState* tuning_fork_state) { + if(tuning_fork_state->volume < 1.0f) { + tuning_fork_state->volume += 0.1f; + } +} + +static void decrease_volume(TuningForkState* tuning_fork_state) { + if(tuning_fork_state->volume > 0.0f) { + tuning_fork_state->volume -= 0.1f; + } +} + +static void play(TuningForkState* tuning_fork_state) { + if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { + furi_hal_speaker_start( + current_tuning_note_freq(tuning_fork_state), tuning_fork_state->volume); + } +} + +static void stop() { + if(furi_hal_speaker_is_mine()) { + furi_hal_speaker_stop(); + furi_hal_speaker_release(); + } +} + +static void replay(TuningForkState* tuning_fork_state) { + stop(); + play(tuning_fork_state); +} + +static void render_callback(Canvas* const canvas, void* ctx) { + TuningForkState* tuning_fork_state = acquire_mutex((ValueMutex*)ctx, 25); + if(tuning_fork_state == NULL) { + return; + } + + string_t tempStr; + string_init(tempStr); + + canvas_draw_frame(canvas, 0, 0, 128, 64); + + canvas_set_font(canvas, FontPrimary); + + if(tuning_fork_state->page == Tunings) { + char tuningLabel[20]; + current_tuning_label(tuning_fork_state, tuningLabel); + string_printf(tempStr, "< %s >", tuningLabel); + canvas_draw_str_aligned( + canvas, 64, 28, AlignCenter, AlignCenter, string_get_cstr(tempStr)); + string_reset(tempStr); + } else { + char tuningLabel[20]; + current_tuning_label(tuning_fork_state, tuningLabel); + string_printf(tempStr, "%s", tuningLabel); + canvas_draw_str_aligned(canvas, 64, 8, AlignCenter, AlignCenter, string_get_cstr(tempStr)); + string_reset(tempStr); + + char tuningNoteLabel[20]; + current_tuning_note_label(tuning_fork_state, tuningNoteLabel); + string_printf(tempStr, "< %s >", tuningNoteLabel); + canvas_draw_str_aligned( + canvas, 64, 24, AlignCenter, AlignCenter, string_get_cstr(tempStr)); + string_reset(tempStr); + } + + canvas_set_font(canvas, FontSecondary); + elements_button_left(canvas, "Prev"); + elements_button_right(canvas, "Next"); + + if(tuning_fork_state->page == Notes) { + if(tuning_fork_state->playing) { + elements_button_center(canvas, "Stop "); + } else { + elements_button_center(canvas, "Play"); + } + } else { + elements_button_center(canvas, "Select"); + } + if(tuning_fork_state->page == Notes) { + elements_progress_bar(canvas, 8, 36, 112, tuning_fork_state->volume); + } + + string_clear(tempStr); + release_mutex((ValueMutex*)ctx, tuning_fork_state); +} + +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 tuning_fork_state_init(TuningForkState* const tuning_fork_state) { + tuning_fork_state->playing = false; + tuning_fork_state->page = Tunings; + tuning_fork_state->volume = 1.0f; + tuning_fork_state->tuning = GuitarStandard6; + tuning_fork_state->current_tuning_index = 2; + tuning_fork_state->current_tuning_note_index = 0; +} + +int32_t tuning_fork_app() { + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); + + TuningForkState* tuning_fork_state = malloc(sizeof(TuningForkState)); + tuning_fork_state_init(tuning_fork_state); + + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, tuning_fork_state, sizeof(TuningForkState))) { + FURI_LOG_E("TuningFork", "cannot create mutex\r\n"); + free(tuning_fork_state); + return 255; + } + + // Set system callbacks + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, render_callback, &state_mutex); + view_port_input_callback_set(view_port, input_callback, event_queue); + + Gui* gui = furi_record_open("gui"); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + PluginEvent event; + for(bool processing = true; processing;) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); + + TuningForkState* tuning_fork_state = (TuningForkState*)acquire_mutex_block(&state_mutex); + + if(event_status == FuriStatusOk) { + if(event.type == EventTypeKey) { + if(event.input.type == InputTypeShort) { + // push events + switch(event.input.key) { + case InputKeyUp: + if(tuning_fork_state->page == Notes) { + increase_volume(tuning_fork_state); + if(tuning_fork_state->playing) { + replay(tuning_fork_state); + } + } + break; + case InputKeyDown: + if(tuning_fork_state->page == Notes) { + decrease_volume(tuning_fork_state); + if(tuning_fork_state->playing) { + replay(tuning_fork_state); + } + } + break; + case InputKeyRight: + if(tuning_fork_state->page == Tunings) { + next_tuning(tuning_fork_state); + } else { + next_note(tuning_fork_state); + if(tuning_fork_state->playing) { + replay(tuning_fork_state); + } + } + break; + case InputKeyLeft: + if(tuning_fork_state->page == Tunings) { + prev_tuning(tuning_fork_state); + } else { + prev_note(tuning_fork_state); + if(tuning_fork_state->playing) { + replay(tuning_fork_state); + } + } + break; + case InputKeyOk: + if(tuning_fork_state->page == Tunings) { + tuning_fork_state->page = Notes; + } else { + tuning_fork_state->playing = !tuning_fork_state->playing; + if(tuning_fork_state->playing) { + play(tuning_fork_state); + } else { + stop(); + } + } + break; + case InputKeyBack: + if(tuning_fork_state->page == Tunings) { + processing = false; + } else { + tuning_fork_state->playing = false; + tuning_fork_state->current_tuning_note_index = 0; + stop(); + tuning_fork_state->page = Tunings; + } + break; + default: + break; + } + } else if(event.input.type == InputTypeLong) { + // hold events + switch(event.input.key) { + case InputKeyUp: + break; + case InputKeyDown: + break; + case InputKeyRight: + if(tuning_fork_state->page == Tunings) { + next_tuning(tuning_fork_state); + } else { + next_note(tuning_fork_state); + if(tuning_fork_state->playing) { + replay(tuning_fork_state); + } + } + + break; + case InputKeyLeft: + if(tuning_fork_state->page == Tunings) { + prev_tuning(tuning_fork_state); + } else { + prev_note(tuning_fork_state); + if(tuning_fork_state->playing) { + replay(tuning_fork_state); + } + } + + break; + case InputKeyOk: + break; + case InputKeyBack: + if(tuning_fork_state->page == Tunings) { + processing = false; + } else { + tuning_fork_state->playing = false; + stop(); + tuning_fork_state->page = Tunings; + tuning_fork_state->current_tuning_note_index = 0; + } + break; + default: + break; + } + } else if(event.input.type == InputTypeRepeat) { + // repeat events + switch(event.input.key) { + case InputKeyUp: + break; + case InputKeyDown: + break; + case InputKeyRight: + if(tuning_fork_state->page == Tunings) { + next_tuning(tuning_fork_state); + } else { + next_note(tuning_fork_state); + if(tuning_fork_state->playing) { + replay(tuning_fork_state); + } + } + + break; + case InputKeyLeft: + if(tuning_fork_state->page == Tunings) { + prev_tuning(tuning_fork_state); + } else { + prev_note(tuning_fork_state); + if(tuning_fork_state->playing) { + replay(tuning_fork_state); + } + } + + break; + case InputKeyOk: + break; + case InputKeyBack: + if(tuning_fork_state->page == Tunings) { + processing = false; + } else { + tuning_fork_state->playing = false; + stop(); + tuning_fork_state->page = Tunings; + tuning_fork_state->current_tuning_note_index = 0; + } + break; + default: + break; + } + } + } + } else { + FURI_LOG_D("TuningFork", "FuriMessageQueue: event timeout"); + } + + view_port_update(view_port); + release_mutex(&state_mutex, tuning_fork_state); + } + + 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); + delete_mutex(&state_mutex); + furi_record_close(RECORD_NOTIFICATION); + free(tuning_fork_state); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/tuning_fork_icon.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/tuning_fork_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..074d9d5900e574dbac03b4e3785152c5e2cb0632 GIT binary patch literal 1187 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xkYHHq`AGmsv7|ftIx;Y9?C1WI$O_~$C3(BM zFfiWj5?%u2aTa()7Bet#3xP1>rMq>1fP(BLp1!W^&$xKGrB$O!lIj^47*|wxlq$-qD7Njav8u=Vft-Pbg>skKI`f8C{(J)v^; z{fpYh)>fAiK3#Tl`lM=67FW{Ck)nPoH0Jll5cAEO8-*lJhCVxRZ}N5S|JyQ5m%K2X zbLK%z^6njO4Li)bPOSEsl>5Q!QH$Zh9n*C==Ls2KTJ&bd4v9ux`K>Y9pW>KZ0}s07 zT{4PUvEl<;gFa85MWX1Tj@>TL1%>CjL@LRi%rd=tIB(BkdtHH=Zo|xANhYgEmYgZ%k`ZWGAR7I| z@k+*v^&iSpL@v!|wROxB`7-D5?U!ez^4vc!nDLI&OvaY!xYD=W`OVEYT6VC;FLf0? zov8jhq3GCGy(b+O!IwHNo6EmB%+vJD=wVE&-b=|Yt2gpZpH^5^X=X?iy=BZvtA3UH zU?caO=o@VBe9x?2yY=Q?-Jtv#+g$c*rn_I>IGOboFd7;2i~K?u&o3&U1>^{Ox;Tb# zTu-(rZeZlKwK?!XvWwyMBmw4G3qGX*rCU-XJkxxA8MJ_G4hB|6AqHlU2|&oeD8&Fu zH=s1-#V8GD2Qg|u)i5zIv}ZD~K-EM6X%O%LVvrsP&AfmSVd4TNxN5Ei%m_9}+X<(u z-++{AiEBhjN@7W>RdP`(kYX@0Ff!6LG|)9P4ly*eGBUF=G1fLPure_4?BSb^q9Hdw zB{QuOO@pDim5~WVgRf&kktouW<0pIuN(+E=1G6uR=UMqqTm;IA!Q?P~*T_3%Ertpd&&AC4)c~qs N@O1TaS?83{1OV5mj{N`t literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/tunings.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/tunings.h new file mode 100644 index 000000000..14bf469fe --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-tuning-fork/tunings.h @@ -0,0 +1,151 @@ +#include "notes.h" + +#ifndef TUNINGS +#define TUNINGS + +typedef struct { + char label[20]; + float frequency; +} NOTE; + +typedef struct { + char label[20]; + int notes_length; + NOTE notes[20]; +} TUNING; + +const TUNING TuningForks = { + "Tuning forks", + 6, + { + {"Common A4 (440)", 440.00f}, + {"Sarti's A4 (436)", 436.00f}, + {"1858 A4 (435)", 435.00f}, + {"Verdi's A4 (432)", 432.00f}, + {"1750-1820 A4 (423.5)", 423.50f}, + {"Verdi's C4 (256.00)", 256.00f}, + }}; + +const TUNING ScientificPitch = { + "Scientific pitch", + 12, + {{"C0 (16Hz)", 16.0f}, + {"C1 (32Hz)", 32.0f}, + {"C2 (64Hz)", 64.0f}, + {"C3 (128Hz)", 128.0f}, + {"C4 (256Hz)", 256.0f}, + {"C5 (512Hz)", 512.0f}, + {"C6 (1024Hz)", 1024.0f}, + {"C7 (2048Hz)", 2048.0f}, + {"C8 (4096Hz)", 4096.0f}, + {"C9 (8192Hz)", 8192.0f}, + {"C10 (16384Hz)", 16384.0f}, + {"C11 (32768Hz)", 32768.0f}}}; + +const TUNING GuitarStandard6 = { + "Guitar Standard 6", + 6, + {{"String 1", E4}, + {"String 2", B3}, + {"String 3", G3}, + {"String 4", D3}, + {"String 5", A2}, + {"String 6", E2}}}; + +const TUNING GuitarDropD6 = { + "Guitar Drop D 6", + 6, + {{"String 1", E4}, + {"String 2", B3}, + {"String 3", G3}, + {"String 4", D3}, + {"String 5", A2}, + {"String 6", D2}}}; + +const TUNING GuitarD6 = { + "Guitar D 6", + 6, + {{"String 1", D4}, + {"String 2", A3}, + {"String 3", F3}, + {"String 4", C3}, + {"String 5", G2}, + {"String 6", D2}}}; + +const TUNING GuitarDropC6 = { + "Guitar Drop C 6", + 6, + {{"String 1", D4}, + {"String 2", A3}, + {"String 3", F3}, + {"String 4", C3}, + {"String 5", G2}, + {"String 6", C2}}}; + +const TUNING GuitarStandard7 = { + "Guitar Standard 7", + 7, + {{"String 1", E4}, + {"String 2", B3}, + {"String 3", G3}, + {"String 4", D3}, + {"String 5", A2}, + {"String 6", E2}, + {"String 7", B1}}}; + +const TUNING BassStandard4 = { + "Bass Standard 4", + 4, + {{"String 1", G2}, {"String 2", D2}, {"String 3", A1}, {"String 4", E1}}}; + +const TUNING BassStandardTenor4 = { + "Bass Stand Tenor 4", + 4, + {{"String 1", C3}, {"String 2", G2}, {"String 3", D2}, {"String 4", A1}}}; + +const TUNING BassStandard5 = { + "Bass Standard 5", + 5, + {{"String 1", G2}, {"String 2", D2}, {"String 3", A1}, {"String 4", E1}, {"String 5", B0}}}; + +const TUNING BassStandardTenor5 = { + "Bass Stand Tenor 5", + 5, + {{"String 1", C3}, {"String 2", G2}, {"String 3", D2}, {"String 4", A1}, {"String 5", E1}}}; + +const TUNING BassDropD4 = { + "Bass Drop D 4", + 4, + {{"String 1", G2}, {"String 2", D2}, {"String 3", A1}, {"String 4", D1}}}; + +const TUNING BassD4 = { + "Bass D 4", + 4, + {{"String 1", F2}, {"String 2", C2}, {"String 3", G1}, {"String 4", D1}}}; + +const TUNING BassDropA5 = { + "Bass Drop A 5", + 5, + {{"String 1", G2}, {"String 2", D2}, {"String 3", A1}, {"String 4", E1}, {"String 5", A0}}}; + +#define TUNINGS_COUNT 14 + +TUNING TuningList[TUNINGS_COUNT] = { + ScientificPitch, + TuningForks, + + GuitarStandard6, + GuitarDropD6, + GuitarD6, + GuitarDropC6, + GuitarStandard7, + + BassStandard4, + BassStandardTenor4, + BassStandard5, + BassStandardTenor5, + BassDropD4, + BassD4, + BassDropA5}; + +#endif //TUNINGS diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/.gitignore b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/.gitignore new file mode 100644 index 000000000..c6127b38c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/.gitignore @@ -0,0 +1,52 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/LICENSE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/README.md b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/README.md new file mode 100644 index 000000000..25351ef49 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/README.md @@ -0,0 +1,48 @@ +# flipperzero-yatzee +Yahtzee game for flipperzero + +Its not beautiful, but it works and now I can play Yahtzee on my flipper while I shit at work. + +Installation: + +Download fap from releases. Copy fap to flipper sd at ext > apps > Games + + +Controls: + +- Up to Roll +- Left/Right to move cursor +- OK to Hold a die +- Moving cursor past the dice will move the cursor up to the scorecard. Moving the scores cursor will show you the potential score you would get. + + +Rules & Scoring: + +- Between rolls, move the cursor and use the OK button to select which dice you will hold for the next roll +- 3 rolls per round and then you are forced to select a score. +- To score, move cursor with Left/Right up to the scorecard, when desired score to count is underlined, press the Down button to confirm. + +- 1-6 add up the corresponding dice of that number in your roll. +- 3 of a Kind (3k) = total of dice when 3 of a kind is rolled +- 4 of a Kind (4k) = total of dice when 4 of a kind is rolled +- Full House (Fh) = 25 +- Small Straight (Sm) = 30 +- Large Straight (Lg) = 40 +- Chance (Ch) = total of all dice in roll +- Yatzee (Yz) = 50 for the first yatzee. Successive Yatzees do not show in the score card, but add 100 each to the total score +- Game ends when every scoring value has been selected once. +- If sub score is at least 63, 35 points are added to the total score. + +Todo +- Redo the scorecard now that I understand a little better how this works + - Would like to make it a grid with 4 rows, and 4 columns + - Rows 0 and 2 will have the scores 'names' + - Rows 1 and 3 will be empty until filled by a score. + - Column 3 will span all rows and show each bonus yatzee as an icon like a star or something. + - Once grided score card is implemented, identify a better mechanism to show that a score has already been counted- instead of the '.' that shows up now. + - Maybe invert the grid color to show which score is being selected by the cursor. +- If upper score >= 63, add a pop-up message at the end game to give a visual indication that a bonus for the top row is being. +- Redo button mapping so that + - the middle button can be used to both hold on dice or confirm score. Leaves the down arrow open for something else. + - Would be nice if up/down could be used to move through the scorecard and left/right move through the dice, but then theres not enough buttons for ROLL so idk yet. +- Learn more about C so that I can move stuff to a header file like everyone else does. diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/application.fam b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/application.fam new file mode 100644 index 000000000..d46228ec9 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/application.fam @@ -0,0 +1,13 @@ +App( + appid="yatzee", + name="Yatzee", + apptype=FlipperAppType.EXTERNAL, + entry_point="yatzee_main", + requires=["gui"], + stack_size=4 * 1024, + order=99, + fap_icon="images/yatzee_icon_10px.png", + fap_category="Games_Extra", + fap_icon_assets="images", + +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/die_1.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/die_1.png new file mode 100644 index 0000000000000000000000000000000000000000..84f86cbb45b9d9b61ce6c5188880fdb7120ae4e5 GIT binary patch literal 1252 zcmVBE1ZQLxAY_vg;$?V;oX(lt{{G@3qJ`_O^!KmPq;Qw2}Cn0L9?Tam?khm;cmfj@-EE=vY<#k5o0f^m&*sM6pBI0EL{uRZtU4R5Z z`^X8`V)zNfJ8YaF;u6EP09P2E5Ad?jnUOMxUqvh^s*L``+lU9}BlcPZ2XpY-jyyG} zttleQMaed+noc9ry@UIIwng1*#M^^UkFzj+6yF25_LnMhmf?pGpH<}CbcnAmX|u%; z|7E#p3GpKUUAw%6atiT2#A8)^yd3Cssj4^8z$>TJnP(8+gLrkpJj%xIMEtceUz`ec zeo~wa<_{hK;NmJRuzL3+9o0iVC08s$)vACv7|KExH6jmbd4gn8^0FkllzkRT6fd|P0n zrwSVAXrbt(XrcJk;OyVRDf#{Yw^VBW$m{6QFhZvPBk<6w!tZERBfJcLd1$M3&)TehHS09YRtkN(Z(GDi^F2;vKBX;HY+Q*UEnTqUvgh@A9J5aYSek}G;8j! zqp=F+X_rylpF&#LEj%b>g+0Q~5^H*5N-?MwSLAe5T{?GXqX;9WfX;*4pXw6&V*io?m|<6;W0GAb4f<-njQ>$>Q>9MPr@ zwU=n+0I+*9IKpp9{{0u*d8K7@p9VPmCp-6AwmA>rtOL;dXv;Q$XXCx^0IWWyc=l3w zC&Xgk0yx!!!@*Zi8qcdA>-AfBZYACT*nGWS|NH%Vee(m<-vGFv{{#Oecnig2*2@3@ z061k>NoGw=04e|g00;m9hiL!=000010000Q0000000N)_00aO40096101%)900aO4 z0096101yBG000-AQ^)`S08L3mK~y*qV`N}p_z%Qn117R{LN&6$4EX<_G>0%UGJ>^I z?1JHL04Shffdva}beiHYfJY;`$sj&4QA@E4hJgW~1Wj5dKnrb(!vFweMF=F1=(!;P O0000BE1ZQLxAY_vg;$?V;oX(lt{{G@3qJ`_O^!KmPq;Qw2}Cn0L9?Tam?khm;cmfj@-EE=vY<#k5o0f^m&*sM6pBI0EL{uRZtU4R5Z z`^X8`V)zNfJ8YaF;u6EP09P2E5Ad?jnUOMxUqvh^s*L``+lU9}BlcPZ2XpY-jyyG} zttleQMaed+noc9ry@UIIwng1*#M^^UkFzj+6yF25_LnMhmf?pGpH<}CbcnAmX|u%; z|7E#p3GpKUUAw%6atiT2#A8)^yd3Cssj4^8z$>TJnP(8+gLrkpJj%xIMEtceUz`ec zeo~wa<_{hK;NmJRuzL3+9o0iVC08s$)vACv7|KExH6jmbd4gn8^0FkllzkRT6fd|P0n zrwSVAXrbt(XrcJk;OyVRDf#{Yw^VBW$m{6QFhZvPBk<6w!tZERBfJcLd1$M3&)TehHS09YRtkN(Z(GDi^F2;vKBX;HY+Q*UEnTqUvgh@A9J5aYSek}G;8j! zqp=F+X_rylpF&#LEj%b>g+0Q~5^H*5N-?MwSLAe5T{?GXqX;9WfX;*4pXw6&V*io?m|<6;W0GAb4f<-njQ>$>Q>9MPr@ zwU=n+0I+*9IKpp9{{0u*d8K7@p9VPmCp-6AwmA>rtOL;dXv;Q$XXCx^0IWWyc=l3w zC&Xgk0yx!!!@*Zi8qcdA>-AfBZYACT*nGWS|NH%Vee(m<-vGFv{{#Oecnig2*2@3@ z061k>NoGw=04e|g00;m9hiL!=000010000Q0000000N)_00aO40096101%)900aO4 z0096101yBG000-AQ^)`S0ANW(K~y*qV`N}p_z%Qn117R{LN&6$4EX<_G>0%UGJ>^I z>;e=6K&HY>hPjLojbZ>H#n|NGVE~dOH5@>CD0aaRGXPsGQS1ejSOA48K7cKjD0TrT hL6epV(40uI3jk{w3n?i+&Y=JR002ovPDHLkV1fvuPT>Fm literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/die_3.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/die_3.png new file mode 100644 index 0000000000000000000000000000000000000000..4c0db3f26aa5e4bb68e5b37837f2263c44a8d834 GIT binary patch literal 1284 zcmV+f1^fDmP)BE1ZQLxAY_vg;$?V;oX(lt{{G@3qJ`_O^!KmPq;Qw2}Cn0L9?Tam?khm;cmfj@-EE=vY<#k5o0f^m&*sM6pBI0EL{uRZtU4R5Z z`^X8`V)zNfJ8YaF;u6EP09P2E5Ad?jnUOMxUqvh^s*L``+lU9}BlcPZ2XpY-jyyG} zttleQMaed+noc9ry@UIIwng1*#M^^UkFzj+6yF25_LnMhmf?pGpH<}CbcnAmX|u%; z|7E#p3GpKUUAw%6atiT2#A8)^yd3Cssj4^8z$>TJnP(8+gLrkpJj%xIMEtceUz`ec zeo~wa<_{hK;NmJRuzL3+9o0iVC08s$)vACv7|KExH6jmbd4gn8^0FkllzkRT6fd|P0n zrwSVAXrbt(XrcJk;OyVRDf#{Yw^VBW$m{6QFhZvPBk<6w!tZERBfJcLd1$M3&)TehHS09YRtkN(Z(GDi^F2;vKBX;HY+Q*UEnTqUvgh@A9J5aYSek}G;8j! zqp=F+X_rylpF&#LEj%b>g+0Q~5^H*5N-?MwSLAe5T{?GXqX;9WfX;*4pXw6&V*io?m|<6;W0GAb4f<-njQ>$>Q>9MPr@ zwU=n+0I+*9IKpp9{{0u*d8K7@p9VPmCp-6AwmA>rtOL;dXv;Q$XXCx^0IWWyc=l3w zC&Xgk0yx!!!@*Zi8qcdA>-AfBZYACT*nGWS|NH%Vee(m<-vGFv{{#Oecnig2*2@3@ z061k>NoGw=04e|g00;m9hiL!=000010000Q0000000N)_00aO40096101%)900aO4 z0096101yBG000-AQ^)`S0BuP`K~y*qrIUdQz#s@jb?pCt+3jKu6wyo}BJ!?xQA|Yg zj^nzHm7nld1CbsGGcW0wz!<<)ot3PbjX~8M?f-Xx&F(!wlM?JiN)2#ARVIRO-ig#A uh$6KNJR#O;1TTmpjS29ed!N8zjR_uc?G7&WSJO!V0000BE1ZQLxAY_vg;$?V;oX(lt{{G@3qJ`_O^!KmPq;Qw2}Cn0L9?Tam?khm;cmfj@-EE=vY<#k5o0f^m&*sM6pBI0EL{uRZtU4R5Z z`^X8`V)zNfJ8YaF;u6EP09P2E5Ad?jnUOMxUqvh^s*L``+lU9}BlcPZ2XpY-jyyG} zttleQMaed+noc9ry@UIIwng1*#M^^UkFzj+6yF25_LnMhmf?pGpH<}CbcnAmX|u%; z|7E#p3GpKUUAw%6atiT2#A8)^yd3Cssj4^8z$>TJnP(8+gLrkpJj%xIMEtceUz`ec zeo~wa<_{hK;NmJRuzL3+9o0iVC08s$)vACv7|KExH6jmbd4gn8^0FkllzkRT6fd|P0n zrwSVAXrbt(XrcJk;OyVRDf#{Yw^VBW$m{6QFhZvPBk<6w!tZERBfJcLd1$M3&)TehHS09YRtkN(Z(GDi^F2;vKBX;HY+Q*UEnTqUvgh@A9J5aYSek}G;8j! zqp=F+X_rylpF&#LEj%b>g+0Q~5^H*5N-?MwSLAe5T{?GXqX;9WfX;*4pXw6&V*io?m|<6;W0GAb4f<-njQ>$>Q>9MPr@ zwU=n+0I+*9IKpp9{{0u*d8K7@p9VPmCp-6AwmA>rtOL;dXv;Q$XXCx^0IWWyc=l3w zC&Xgk0yx!!!@*Zi8qcdA>-AfBZYACT*nGWS|NH%Vee(m<-vGFv{{#Oecnig2*2@3@ z061k>NoGw=04e|g00;m9hiL!=000010000Q0000000N)_00aO40096101%)900aO4 z0096101yBG000-AQ^)`S0ANW(K~y*qV`N}p_z%Qn117R{LN&6$4EX<_G>0%UGJ>^I z>;e=6K&HY>hPe!x#wL$q0J36Y+3+v`X&@91*yJg8!5}jLTPPz3CN_DBy)f{x07}rL hWdh_t0kSC$0|0TQ5ic+X0w@3g002ovPDHLkV1gbiPJ;jd literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/die_5.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/die_5.png new file mode 100644 index 0000000000000000000000000000000000000000..c251d3a788ed2ff7b9bef556b95d9404765e12a1 GIT binary patch literal 1290 zcmV+l1@-!gP)BE1ZQLxAY_vg;$?V;oX(lt{{G@3qJ`_O^!KmPq;Qw2}Cn0L9?Tam?khm;cmfj@-EE=vY<#k5o0f^m&*sM6pBI0EL{uRZtU4R5Z z`^X8`V)zNfJ8YaF;u6EP09P2E5Ad?jnUOMxUqvh^s*L``+lU9}BlcPZ2XpY-jyyG} zttleQMaed+noc9ry@UIIwng1*#M^^UkFzj+6yF25_LnMhmf?pGpH<}CbcnAmX|u%; z|7E#p3GpKUUAw%6atiT2#A8)^yd3Cssj4^8z$>TJnP(8+gLrkpJj%xIMEtceUz`ec zeo~wa<_{hK;NmJRuzL3+9o0iVC08s$)vACv7|KExH6jmbd4gn8^0FkllzkRT6fd|P0n zrwSVAXrbt(XrcJk;OyVRDf#{Yw^VBW$m{6QFhZvPBk<6w!tZERBfJcLd1$M3&)TehHS09YRtkN(Z(GDi^F2;vKBX;HY+Q*UEnTqUvgh@A9J5aYSek}G;8j! zqp=F+X_rylpF&#LEj%b>g+0Q~5^H*5N-?MwSLAe5T{?GXqX;9WfX;*4pXw6&V*io?m|<6;W0GAb4f<-njQ>$>Q>9MPr@ zwU=n+0I+*9IKpp9{{0u*d8K7@p9VPmCp-6AwmA>rtOL;dXv;Q$XXCx^0IWWyc=l3w zC&Xgk0yx!!!@*Zi8qcdA>-AfBZYACT*nGWS|NH%Vee(m<-vGFv{{#Oecnig2*2@3@ z061k>NoGw=04e|g00;m9hiL!=000010000Q0000000N)_00aO40096101%)900aO4 z0096101yBG000-AQ^)`S0CP!1K~y*qrIUdQz#s@jbL{_r+0B@vlOrpGDA7BfQqo$} zcOS3oSosNWH&ERJ5s@w}6M%uay0epwC(DDuSiE}wXJCSC4lF+9b8vpUx_ A>i_@% literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/die_6.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/die_6.png new file mode 100644 index 0000000000000000000000000000000000000000..77e300d88e8b22ced32ffef4c5f69c5d9d52773e GIT binary patch literal 1274 zcmVBE1ZQLxAY_vg;$?V;oX(lt{{G@3qJ`_O^!KmPq;Qw2}Cn0L9?Tam?khm;cmfj@-EE=vY<#k5o0f^m&*sM6pBI0EL{uRZtU4R5Z z`^X8`V)zNfJ8YaF;u6EP09P2E5Ad?jnUOMxUqvh^s*L``+lU9}BlcPZ2XpY-jyyG} zttleQMaed+noc9ry@UIIwng1*#M^^UkFzj+6yF25_LnMhmf?pGpH<}CbcnAmX|u%; z|7E#p3GpKUUAw%6atiT2#A8)^yd3Cssj4^8z$>TJnP(8+gLrkpJj%xIMEtceUz`ec zeo~wa<_{hK;NmJRuzL3+9o0iVC08s$)vACv7|KExH6jmbd4gn8^0FkllzkRT6fd|P0n zrwSVAXrbt(XrcJk;OyVRDf#{Yw^VBW$m{6QFhZvPBk<6w!tZERBfJcLd1$M3&)TehHS09YRtkN(Z(GDi^F2;vKBX;HY+Q*UEnTqUvgh@A9J5aYSek}G;8j! zqp=F+X_rylpF&#LEj%b>g+0Q~5^H*5N-?MwSLAe5T{?GXqX;9WfX;*4pXw6&V*io?m|<6;W0GAb4f<-njQ>$>Q>9MPr@ zwU=n+0I+*9IKpp9{{0u*d8K7@p9VPmCp-6AwmA>rtOL;dXv;Q$XXCx^0IWWyc=l3w zC&Xgk0yx!!!@*Zi8qcdA>-AfBZYACT*nGWS|NH%Vee(m<-vGFv{{#Oecnig2*2@3@ z061k>NoGw=04e|g00;m9hiL!=000010000Q0000000N)_00aO40096101%)900aO4 z0096101yBG000-AQ^)`S0Aoo+K~y*qV`N}p_z%Qn117R{LN&6$4EX<_G>0%UGJ>^I z>;e=6K&HY>hPe!x#wL$q0J36Y+3+v`X&@91*yK@MfX#`>F2N>`VgRyYV%ei!U|^s) k5J3r=v`l~&JruhD0DHd|HzpB|$N&HU07*qoM6N<$f}1;2F#rGn literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/yatzee_icon_10px.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero-yatzee-main/images/yatzee_icon_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..38dfd172f1325d65e93fd55c6eb0fab282d0a110 GIT binary patch literal 1250 zcmV<81ReW{P)BE1ZQLxAY_vg;$?V;oX(lt{{G@3qJ`_O^!KmPq;Qw2}Cn0L9?Tam?khm;cmfj@-EE=vY<#k5o0f^m&*sM6pBI0EL{uRZtU4R5Z z`^X8`V)zNfJ8YaF;u6EP09P2E5Ad?jnUOMxUqvh^s*L``+lU9}BlcPZ2XpY-jyyG} zttleQMaed+noc9ry@UIIwng1*#M^^UkFzj+6yF25_LnMhmf?pGpH<}CbcnAmX|u%; z|7E#p3GpKUUAw%6atiT2#A8)^yd3Cssj4^8z$>TJnP(8+gLrkpJj%xIMEtceUz`ec zeo~wa<_{hK;NmJRuzL3+9o0iVC08s$)vACv7|KExH6jmbd4gn8^0FkllzkRT6fd|P0n zrwSVAXrbt(XrcJk;OyVRDf#{Yw^VBW$m{6QFhZvPBk<6w!tZERBfJcLd1$M3&)TehHS09YRtkN(Z(GDi^F2;vKBX;HY+Q*UEnTqUvgh@A9J5aYSek}G;8j! zqp=F+X_rylpF&#LEj%b>g+0Q~5^H*5N-?MwSLAe5T{?GXqX;9WfX;*4pXw6&V*io?m|<6;W0GAb4f<-njQ>$>Q>9MPr@ zwU=n+0I+*9IKpp9{{0u*d8K7@p9VPmCp-6AwmA>rtOL;dXv;Q$XXCx^0IWWyc=l3w zC&Xgk0yx!!!@*Zi8qcdA>-AfBZYACT*nGWS|NH%Vee(m<-vGFv{{#Oecnig2*2@3@ z061k>NoGw=04e|g00;m9hiL!=000010000Q0000000N)_00aO40096101BW300aO4 z00961015yA000=Un$G|L082?kK~xwSg^)oC05Ax{*8Ts_ZXO(MQRYReA%cio0M@UP zh=eXbvMJiUbu(uH-O5?Ova_jXEy$)8bQ5PWx{339Po0>$7$+#r2Or@Z4ExeF761SM M07*qoM6N<$f{ +#include + +#include +#include +#include + +#include +#include + +#define BASE_X 18 +#define BASE_Y 44 +#define DICE_OFFSET 12 +#define HOLD "*" +#define MAX_DICE 5 +#define NUM_SCORES 13 + +bool new_game = true; +bool game_over = false; +bool bonus_added = false; +int8_t num_bonus_yatzees = 0; + +// struct to hold image posistion for dice +typedef struct { + // +-----x + // | + // | + // y + uint8_t x; + uint8_t y; +} ImagePosition; + + +typedef struct { + char* name; + uint32_t value; + bool used; + int8_t row; + int8_t col; + uint8_t (*fn)(); // pointer to function that calculates score +} Score; + +typedef struct { + uint8_t index; + uint8_t value; + bool isHeld; +} Die; + +typedef struct { + int index; + char* symbol; +} Cursor; + +// locations for the dice images +ImagePosition position[5] = { + {.x = BASE_X-DICE_OFFSET, .y = BASE_Y}, + {.x = BASE_X*2-DICE_OFFSET, .y = BASE_Y}, + {.x = BASE_X*3-DICE_OFFSET, .y = BASE_Y}, + {.x = BASE_X*4-DICE_OFFSET, .y = BASE_Y}, + {.x = BASE_X*5-DICE_OFFSET, .y = BASE_Y}, +}; + +// these are the positions that the score cursor will cycle through +ImagePosition score_positions[13] = { + {.x=15, .y=0}, + {.x=15, .y=9}, + {.x=15, .y=18}, + {.x=15, .y=27}, + {.x=44, .y=0}, + {.x=44, .y=9}, + {.x=44, .y=18}, + {.x=44, .y=27}, + {.x=77, .y=0}, + {.x=77, .y=9}, + {.x=77, .y=18}, + {.x=77, .y=27}, + {.x=91, .y=21}, +}; + +// cursor to select dice +Cursor cursor = { + .index = 0, + .symbol = "^" +}; + +// cursor to select score +Cursor scoreCursor = { + .index = -1, + .symbol = "_" +}; + +// setup array to store dice info +Die die[5] = { + {.index = 0, .value = 1, .isHeld = false}, + {.index = 1, .value = 1, .isHeld = false}, + {.index = 2, .value = 1, .isHeld = false}, + {.index = 3, .value = 1, .isHeld = false}, + {.index = 4, .value = 1, .isHeld = false}, +}; + +uint8_t upperScore = 0; +int32_t lowerScore = 0; +int32_t totalScore = 0; +uint8_t roll = 0; +uint8_t totalrolls = 0; + +// ############################################# +// # The following methods add the score for # +// # whichever number is mentioned. # +// ############################################# +static uint8_t ones() { + uint8_t sum = 0; + for (uint8_t i = 0; i < 5; i++) { + if (die[i].value == 1) { + sum++; + } + } + return sum; +} + +static uint8_t twos() { + uint8_t sum = 0; + for (uint8_t i = 0; i < 5; i++) { + if (die[i].value == 2) { + sum = sum+2; + } + } + return sum; +} + +static uint8_t threes() { + uint8_t sum = 0; + for (uint8_t i = 0; i < 5; i++) { + if (die[i].value == 3) { + sum = sum+3; + } + } + return sum; +} + +static uint8_t fours() { + uint8_t sum = 0; + for (uint8_t i = 0; i < 5; i++) { + if (die[i].value == 4) { + sum = sum+4; + } + } + return sum; +} + +static uint8_t fives() { + uint8_t sum = 0; + for (uint8_t i = 0; i < 5; i++) { + if (die[i].value == 5) { + sum = sum+5; + } + } + return sum; +} + +static uint8_t sixes() { + uint8_t sum = 0; + for (uint8_t i = 0; i < 5; i++) { + if (die[i].value == 6) { + sum = sum+6; + } + } + return sum; +} + +// #################################################### +// # Helper methods for the special score types # +// # defined before them so they can be used # +// # since this whole thing is a linear mess # +// # lol. # +// # add_dice: # +// # inputs: none # +// # output: int8_t value of roll # +// # check_if_score_used: +// # inputs: Score +// # output: true if score.used = true +// # # # # # # # # # # # # # # # # # # # # # # # # # # +int8_t add_dice() { + int8_t sum = 0; + for (int8_t i=0; i 2) { + score = add_dice(); + } + } + } + return score; +} + +static uint8_t fourkind() { + int8_t score = 0; + for (int8_t num=1; num<7; num++) { + int8_t sum = 0; + + for (int8_t i=0; i 3) { + score = add_dice(); + } + } + } + return score; +} + +static uint8_t fullhouse() { + + bool check1 = false; + bool check2 = false; + int8_t val1 = 0; + int8_t val2 = 0; + UNUSED(val2); + UNUSED(val1); + + //check 1 for three of a kind + for (int8_t num=1; num<7; num++) { + int8_t sum = 0; + + for (int8_t i=0; i 2) { + val1 = die[i].value; + check1 = true; + } + } + } + + // return if check 1 failed + if (check1 == false) { + return 0; + } + + // check 2 for two of a kind. + for (int8_t num=1; num<7; num++) { + if (num==val1) {continue;} + int8_t sum = 0; + + for (int8_t i=0; i 1) { + val2 = die[i].value; + check2 = true; + } + } + if (check1 && check2) { + return 25; + } + } + return 0; +} + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # +// # I'm dumb so I asked ChatGPT to write the # +// # smallstraight function for me. Then I adapted it # +// # fo the largestraight function. # +// # # # # # # # # # # # # # # # # # # # # # # # # # # # +static uint8_t smallstraight() { + // Create a new array with the frequencies of the different die faces + int8_t frequencies[6] = {0}; + + for (int8_t i = 0; i < 5; i++) { + int8_t face = die[i].value; + frequencies[face - 1]++; + } + + // Check if there is a sequence of 4 consecutive die faces with at least one die + bool found_small_straight = false; + for (int i = 0; i < 3 && !found_small_straight; i++) { + if (frequencies[i] > 0 && frequencies[i + 1] > 0 && frequencies[i + 2] > 0 && frequencies[i + 3] > 0) { + found_small_straight = true; + } + } + + if (found_small_straight) { + return 30; + } else { + return 0; + } +} + +static uint8_t largestraight() { + // Create a new array with the frequencies of the different die faces + int8_t frequencies[6] = {0}; + + for (int8_t i = 0; i < 5; i++) { + int8_t face = die[i].value; + frequencies[face - 1]++; + } + + // Check if there is a sequence of 4 consecutive die faces with at least one die + bool found_large_straight = false; + for (int i = 0; i < 3 && !found_large_straight; i++) { + if (frequencies[i] > 0 && frequencies[i + 1] > 0 && frequencies[i + 2] > 0 && frequencies[i + 3] > 0 && frequencies[i + 4] > 0) { + found_large_straight = true; + } + } + + if (found_large_straight) { + return 40; + } else { + return 0; + } +} + +static uint8_t chance() { + // chance allows your roll to count for the raw number of pips showing + int8_t sum = 0; + for (int8_t i = 0; i63 at the end of the game, + // a 35 point bonus is added to the total score + snprintf(buffer, sizeof(buffer), "Sub\n%u", upperScore); + elements_multiline_text_aligned(canvas, 117, 0, AlignCenter, AlignTop, buffer); + + snprintf(buffer, sizeof(buffer), "Total\n%ld", totalScore); + elements_multiline_text_aligned(canvas, 117, 22, AlignCenter, AlignTop, buffer); + + if (totalrolls == 0) { + snprintf(buffer, sizeof(buffer), "Roll\n%s", " "); + elements_multiline_text_aligned(canvas, 117, 64, AlignCenter, AlignBottom, buffer); + } else { + snprintf(buffer, sizeof(buffer), "Roll\n%u", totalrolls); + elements_multiline_text_aligned(canvas, 117, 64, AlignCenter, AlignBottom, buffer); + } + + // Check for then handle end of game + + // add num_bonus_yatzees to total rounds so that multiple + // yatzees can be scored without impacting the number of rounds before + // the game is over + int8_t total_rounds = num_bonus_yatzees; + // add up number of scores counted so far + for (int8_t i = 0; i= 63 && bonus_added == false) { + totalScore+=35; + bonus_added = true; + } + // set game over to true and tell the user the game is over + game_over = true; + elements_button_center(canvas, "Game Over"); + } + } +} + +// define the callback for helping ViewPort get InputEvent and place it in the event_queue defined in the main method +static void app_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + + FuriMessageQueue* event_queue = ctx; + furi_message_queue_put(event_queue, input_event, FuriWaitForever); +} + +// roll them diiiiceeee +static void roll_dice() { + // increment roll count + totalrolls++; + for (uint8_t i = 0; i < MAX_DICE; i++) { + // dont reroll if the dice is being held + if (die[i].isHeld == false) { + die[i].value = 1 + rand() % 6; + } + } + // if 3 rolls have been used, force user to select a score. + if(totalrolls == 3) { + scoreCursor.index = 0; + } +} + +static void clear_board() { + // reset board after adding score + totalrolls = 0; + for (int8_t i=0; i < MAX_DICE; i++) { + die[i].isHeld = false; + } + scoreCursor.index = -1; + cursor.index = 0; +} + +static void add_score() { + // return when scoring is not possible + if (cursor.index != -1 || totalrolls == 0 || (scorecard[scoreCursor.index].used && strcmp(scorecard[scoreCursor.index].name,"Yz")!=0)){ + return; + } + + // extra yatzee scores + if (scoreCursor.index == 12 && scorecard[scoreCursor.index].used) { + uint8_t yatzee_score = (*scorecard[12].fn)(); + scorecard[12].value += 2*yatzee_score; + lowerScore+=100; + num_bonus_yatzees++; + } + + + // upper score + for (int8_t i = 0; i < 6; i++) { + if (scoreCursor.index == i && scorecard[scoreCursor.index].used == false) { + scorecard[i].value =(*scorecard[i].fn)(); + upperScore+=scorecard[i].value; + scorecard[i].used = true; + } + } + + // lower score + for (int8_t i = 6; i < 13; i++) { + if (scoreCursor.index == i && scorecard[scoreCursor.index].used == false) { + scorecard[i].value = (*scorecard[i].fn)(); + lowerScore+=scorecard[i].value; + scorecard[i].used = true; + } + } + + // recalculate total score + totalScore = lowerScore + upperScore; + clear_board(); +} + + + + +// Entry Point +int32_t yatzee_main(void* p) { + UNUSED(p); + + // Initialize event queue to handle incoming events like button presses + // Use FuriMessageQueue as type as defined in furi api + // InputEvents are supported by app_input_callback + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + // Initialize viewport + ViewPort* view_port = view_port_alloc(); + + // Set system callbacks + view_port_draw_callback_set(view_port, app_draw_callback, view_port); + view_port_input_callback_set(view_port, app_input_callback, event_queue); + + // Open GUI & register viewport + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + // hold input event + InputEvent event; + + // Create a loop for the app to run in and handle InputEvents + bool isRunning = true; + + while(isRunning) { + + if (totalrolls == 3) { + cursor.index = -1; + } + if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) { + if((event.type == InputTypePress) || event.type == InputTypeRepeat) { + switch(event.key) { + case InputKeyLeft: + if(cursor.index == -1) { + if(scoreCursor.index == 0 && totalrolls == 3){ + scoreCursor.index = NUM_SCORES-1; + } else if (scoreCursor.index==0) { + scoreCursor.index = -1; + cursor.index = 4; + } else { + scoreCursor.index--; + } + } else { + if(cursor.index == 0) { + cursor.index = -1; + scoreCursor.index = NUM_SCORES-1; + } else { + cursor.index--; + } + } + break; + case InputKeyRight: + // cursor.index == -1 means that scoreCursor is active + if(cursor.index == -1) { + if(scoreCursor.index == NUM_SCORES-1 && totalrolls == 3){ + scoreCursor.index = 0; + } else if (scoreCursor.index == NUM_SCORES-1) { + scoreCursor.index = -1; + cursor.index = 0; + } else { + scoreCursor.index++; + } + // if cursor.index is not -1, then dice cursor is active + } else { + if(cursor.index == 4) { + cursor.index = -1; + scoreCursor.index = 0; + } else { + cursor.index++; + } + } + break; + case InputKeyUp: + + if (totalrolls < 3) { + roll_dice(); + } + // if (check_for_bonus_yatzee() && scorecard[13].used) { + // num_bonus_yatzees++; + // totalScore+=100; + // + // clear_board(); + // } + break; + case InputKeyDown: + add_score(); + break; + case InputKeyOk: + if (new_game) { + new_game = false; + break; + } + if (game_over) { + isRunning = false; + } + if (cursor.index == -1 || totalrolls == 0) { + break; + } + if (die[cursor.index].isHeld == false) { + die[cursor.index].isHeld = true; + } else { + die[cursor.index].isHeld = false; + } + break; + default: + isRunning = false; + break; + } + } + } + // after every event, update view_port + // uses app_draw_callback which is set before the game loop begins. + view_port_update(view_port); + } + + // cleanup + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + furi_message_queue_free(event_queue); + furi_record_close(RECORD_GUI); + + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/GPIO_reader.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/GPIO_reader.c new file mode 100644 index 000000000..144147b67 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/GPIO_reader.c @@ -0,0 +1,129 @@ +#include +#include +#include +#include +#include "GPIO_reader_item.h" + +typedef enum { + EventTypeTick, + EventTypeKey, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} PluginEvent; + +typedef struct { + int pin; + int pullMode; +} PluginState; + + +static void render_callback(Canvas* const canvas, void* ctx) { + const PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25); + + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned(canvas, canvas_width(canvas) / 2, canvas_height(canvas) / 10, AlignCenter, AlignCenter, "GPIO reader"); + + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned(canvas, canvas_width(canvas) / 2, canvas_height(canvas) / 10 * 3, AlignCenter, AlignCenter, + gpio_item_get_pin_name(plugin_state->pin)); + + canvas_draw_str_aligned(canvas, canvas_width(canvas) / 2, canvas_height(canvas) / 10 * 5, AlignCenter, AlignCenter, + gpio_item_get_pull_mode(plugin_state->pullMode)); + + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned(canvas, canvas_width(canvas) / 2, canvas_height(canvas) / 10 * 8, AlignCenter, AlignCenter, + gpio_item_get_pin_level(plugin_state->pin)); + + release_mutex((ValueMutex*)ctx, plugin_state); +} + +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 GPIO_reader_state_init(PluginState* const plugin_state) { + plugin_state->pin = 0; + plugin_state->pullMode = 0; + gpio_item_configure_pin(plugin_state->pin, plugin_state->pullMode); +} + +int32_t GPIO_reader_app(void* p) { + UNUSED(p); + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); + + PluginState* plugin_state = malloc(sizeof(PluginState)); + GPIO_reader_state_init(plugin_state); + ValueMutex state_mutex; + if (!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) { + FURI_LOG_E("GPIO_reader", "cannot create mutex\r\n"); + free(plugin_state); + return 255; + } + + // Set system callbacks + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, render_callback, &state_mutex); + view_port_input_callback_set(view_port, input_callback, event_queue); + + // Open GUI and register view_port + Gui* gui = furi_record_open("gui"); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + + PluginEvent event; + for(bool processing = true; processing;) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); + PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex); + + if(event_status == FuriStatusOk) { + // press events + if(event.type == EventTypeKey) { + if(event.input.type == InputTypePress || event.input.type == InputTypeRepeat) { + switch(event.input.key) { + case InputKeyRight: + plugin_state->pin = (plugin_state->pin + 1) % GPIO_ITEM_COUNT; + gpio_item_configure_pin(plugin_state->pin, plugin_state->pullMode); + break; + case InputKeyLeft: + plugin_state->pin = (plugin_state->pin - 1 + GPIO_ITEM_COUNT) % GPIO_ITEM_COUNT; + gpio_item_configure_pin(plugin_state->pin, plugin_state->pullMode); + break; + case InputKeyUp: + plugin_state->pullMode = (plugin_state->pullMode + 1) % GPIO_PULL_COUNT; + gpio_item_configure_pin(plugin_state->pin, plugin_state->pullMode); + break; + case InputKeyDown: + plugin_state->pullMode = (plugin_state->pullMode - 1 + GPIO_PULL_COUNT) % GPIO_PULL_COUNT; + gpio_item_configure_pin(plugin_state->pin, plugin_state->pullMode); + break; + case InputKeyBack: + processing = false; + break; + default: + break; + } + } + } + } else { + FURI_LOG_D("GPIO_reader", "FuriMessageQueue: event timeout"); + // event timeout + } + + view_port_update(view_port); + release_mutex(&state_mutex, plugin_state); + } + + 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); + + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/GPIO_reader_item.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/GPIO_reader_item.c new file mode 100644 index 000000000..15726722c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/GPIO_reader_item.c @@ -0,0 +1,26 @@ +#include "GPIO_reader_item.h" + +const char* gpio_item_get_pin_name(uint8_t index) { + furi_assert(index < GPIO_ITEM_COUNT); + return gpio_item[index].name; +} + +const char* gpio_item_get_pull_mode(uint8_t pull_mode) { + furi_assert(pull_mode < GPIO_PULL_COUNT); + return gpio_pull_mode[pull_mode].name; +} + +const char* gpio_item_get_pin_level(uint8_t index) { + furi_assert(index < GPIO_ITEM_COUNT); + //furi_hal_gpio_write(gpio_item[index].pin, level); + if (furi_hal_gpio_read(gpio_item[index].pin)){ + return "High"; + }else{ + return "Low"; + } +} + +void gpio_item_configure_pin(uint8_t index, uint8_t pull_mode) { + furi_assert(index < GPIO_ITEM_COUNT); + furi_hal_gpio_init(gpio_item[index].pin, GpioModeInput, gpio_pull_mode[pull_mode].pull, GpioSpeedVeryHigh); +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/GPIO_reader_item.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/GPIO_reader_item.h new file mode 100644 index 000000000..da6bcc89f --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/GPIO_reader_item.h @@ -0,0 +1,42 @@ +#ifndef GPIO_READER_ITEM +#define GPIO_READER_ITEM + +#include +#include + +#define GPIO_ITEM_COUNT 8 +#define GPIO_PULL_COUNT 3 + +typedef struct { + const char* name; + const GpioPin* pin; +} GpioItem; + +static const GpioItem gpio_item[GPIO_ITEM_COUNT] = { + {"2: PA7", &gpio_ext_pa7}, + {"3: PA6", &gpio_ext_pa6}, + {"4: PA4", &gpio_ext_pa4}, + {"5: PB3", &gpio_ext_pb3}, + {"6: PB2", &gpio_ext_pb2}, + {"7: PC3", &gpio_ext_pc3}, + {"15: PC1", &gpio_ext_pc1}, + {"16: PC0", &gpio_ext_pc0}, +}; + +typedef struct { + const char* name; + const GpioPull pull; +} GpioPullMode; + +static const GpioPullMode gpio_pull_mode[3] = { + {"high impedence", GpioPullNo}, + {"pull up", GpioPullUp}, + {"pull down", GpioPullDown}, +}; + +const char* gpio_item_get_pin_name(uint8_t index); +const char* gpio_item_get_pin_level(uint8_t index); +void gpio_item_configure_pin(uint8_t index, uint8_t pullMode); +const char* gpio_item_get_pull_mode(uint8_t pull_mode); + +#endif \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/README.md b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/README.md new file mode 100644 index 000000000..c911cf313 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/README.md @@ -0,0 +1,3 @@ +# flipperzero_GPIO_read + +Plugin to read the GPIOs on the Flipper Zero. diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/application.fam b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/application.fam new file mode 100644 index 000000000..7f1aa05a7 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/application.fam @@ -0,0 +1,11 @@ +App( + appid="GPIO_reader", + name="[GPIO] Reader", + apptype=FlipperAppType.EXTERNAL, + entry_point="GPIO_reader_app", + requires=["gui"], + stack_size=1 * 1024, + fap_category="GPIO_Extra", + fap_icon="icon.png", + order=1, +) \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/icon.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_GPIO_read-main/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..201d033e74e36c5488a571920b3fee257c3e03ad GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>vG;Uw4ABTq z{`3F;|9Uo+11C;!JX^?VY;Y+|@l4bV?+I(&H_rOSZdngu5+k1a4|d9Bh_Z irt#1_$AXE$%-QMLBh#tYK%*EuUHx3vIVChPFaQ90iY%J| literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/LICENSE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/README.md b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/README.md new file mode 100644 index 000000000..35426a9e1 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/README.md @@ -0,0 +1,16 @@ +# flipperzero-gpioreader + +![image info](./gpioreader.png) + +This is a fork of the `gpio` app built into the flipper, with added functionality to read GPIO inputs. + +Supports pulling high or low. + +Does not (yet) support analog reads. + +Installation instructions (Linux): + + - Clone the following repo: https://github.com/flipperdevices/flipperzero-firmware + - Clone this repo into flipperzero-firmware/applications_user + - Plug in your FlipperZero + - Run `./fbt launch_app APPSRC=flipperzero-gpioreader` from within the flipperzero-firmware folder diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/application.fam b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/application.fam new file mode 100644 index 000000000..9a1a63688 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/application.fam @@ -0,0 +1,13 @@ +App( + appid="gpioreader2", + name="[GPIO] Input Reader 2", + apptype=FlipperAppType.EXTERNAL, + entry_point="gpio_app", + cdefines=["APP_GPIOREADER"], + requires=["gui"], + stack_size=1 * 1024, + order=50, + fap_libs=["assets"], + fap_category="GPIO_Extra", + fap_icon="icon.png", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_app.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_app.c new file mode 100644 index 000000000..07a79cb89 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_app.c @@ -0,0 +1,111 @@ +#include "gpio_app_i.h" + +#include +#include + +static bool gpio_app_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + GpioApp* app = context; + return scene_manager_handle_custom_event(app->scene_manager, event); +} + +static bool gpio_app_back_event_callback(void* context) { + furi_assert(context); + GpioApp* app = context; + return scene_manager_handle_back_event(app->scene_manager); +} + +static void gpio_app_tick_event_callback(void* context) { + furi_assert(context); + GpioApp* app = context; + scene_manager_handle_tick_event(app->scene_manager); +} + +GpioApp* gpio_app_alloc() { + GpioApp* app = malloc(sizeof(GpioApp)); + + app->gui = furi_record_open(RECORD_GUI); + + app->view_dispatcher = view_dispatcher_alloc(); + app->scene_manager = scene_manager_alloc(&gpio_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, gpio_app_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + app->view_dispatcher, gpio_app_back_event_callback); + view_dispatcher_set_tick_event_callback( + app->view_dispatcher, gpio_app_tick_event_callback, 100); + + 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, + GpioAppViewVarItemList, + variable_item_list_get_view(app->var_item_list)); + app->gpio_test = gpio_test_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, GpioAppViewGpioTest, gpio_test_get_view(app->gpio_test)); + app->gpio_reader = gpio_reader_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, GpioAppViewGpioReader, gpio_reader_get_view(app->gpio_reader)); + + app->widget = widget_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, GpioAppViewUsbUartCloseRpc, widget_get_view(app->widget)); + + app->gpio_usb_uart = gpio_usb_uart_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, GpioAppViewUsbUart, gpio_usb_uart_get_view(app->gpio_usb_uart)); + + view_dispatcher_add_view( + app->view_dispatcher, + GpioAppViewUsbUartCfg, + variable_item_list_get_view(app->var_item_list)); + + scene_manager_next_scene(app->scene_manager, GpioSceneStart); + + return app; +} + +void gpio_app_free(GpioApp* app) { + furi_assert(app); + + // Views + view_dispatcher_remove_view(app->view_dispatcher, GpioAppViewVarItemList); + view_dispatcher_remove_view(app->view_dispatcher, GpioAppViewGpioTest); + view_dispatcher_remove_view(app->view_dispatcher, GpioAppViewGpioReader); + view_dispatcher_remove_view(app->view_dispatcher, GpioAppViewUsbUart); + view_dispatcher_remove_view(app->view_dispatcher, GpioAppViewUsbUartCfg); + view_dispatcher_remove_view(app->view_dispatcher, GpioAppViewUsbUartCloseRpc); + variable_item_list_free(app->var_item_list); + widget_free(app->widget); + gpio_test_free(app->gpio_test); + gpio_reader_free(app->gpio_reader); + gpio_usb_uart_free(app->gpio_usb_uart); + + // 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 gpio_app(void* p) { + UNUSED(p); + GpioApp* gpio_app = gpio_app_alloc(); + + view_dispatcher_run(gpio_app->view_dispatcher); + + gpio_app_free(gpio_app); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_app.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_app.h new file mode 100644 index 000000000..156ddc922 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_app.h @@ -0,0 +1,11 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct GpioApp GpioApp; + +#ifdef __cplusplus +} +#endif diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_app_i.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_app_i.h new file mode 100644 index 000000000..52f76949d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_app_i.h @@ -0,0 +1,44 @@ +#pragma once + +#include "gpio_app.h" +#include "gpio_item.h" +#include "scenes/gpio_scene.h" +#include "gpio_custom_event.h" +#include "usb_uart_bridge.h" + +#include +#include +#include +#include +#include +#include +#include +#include "views/gpio_test.h" +#include "views/gpio_reader.h" +#include "views/gpio_usb_uart.h" +#include + +struct GpioApp { + Gui* gui; + NotificationApp* notifications; + ViewDispatcher* view_dispatcher; + SceneManager* scene_manager; + Widget* widget; + + VariableItemList* var_item_list; + VariableItem* var_item_flow; + GpioTest* gpio_test; + GpioReader* gpio_reader; + GpioUsbUart* gpio_usb_uart; + UsbUartBridge* usb_uart_bridge; + UsbUartConfig* usb_uart_cfg; +}; + +typedef enum { + GpioAppViewVarItemList, + GpioAppViewGpioTest, + GpioAppViewGpioReader, + GpioAppViewUsbUart, + GpioAppViewUsbUartCfg, + GpioAppViewUsbUartCloseRpc, +} GpioAppView; diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_custom_event.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_custom_event.h new file mode 100644 index 000000000..f5648e10c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_custom_event.h @@ -0,0 +1,14 @@ +#pragma once + +typedef enum { + GpioStartEventOtgOff = 0, + GpioStartEventOtgOn, + GpioStartEventManualControl, + GpioStartEventReader, + GpioStartEventUsbUart, + + GpioCustomEventErrorBack, + + GpioUsbUartEventConfig, + GpioUsbUartEventConfigSet, +} GpioCustomEvent; diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_item.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_item.c new file mode 100644 index 000000000..f516bd258 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_item.c @@ -0,0 +1,60 @@ +#include "gpio_item.h" + +#include + +typedef struct { + const char* name; + const GpioPin* pin; +} GpioItem; + +static const GpioItem gpio_item[GPIO_ITEM_COUNT] = { + {"1.2: PA7", &gpio_ext_pa7}, + {"1.3: PA6", &gpio_ext_pa6}, + {"1.4: PA4", &gpio_ext_pa4}, + {"1.5: PB3", &gpio_ext_pb3}, + {"1.6: PB2", &gpio_ext_pb2}, + {"1.7: PC3", &gpio_ext_pc3}, + {"2.7: PC1", &gpio_ext_pc1}, + {"2.8: PC0", &gpio_ext_pc0}, +}; + +void gpio_item_configure_pin(uint8_t index, GpioMode mode, GpioPull pull) { + furi_assert(index < GPIO_ITEM_COUNT); + furi_hal_gpio_write(gpio_item[index].pin, false); + furi_hal_gpio_init(gpio_item[index].pin, mode, pull, GpioSpeedVeryHigh); +} + +void gpio_item_configure_all_pins(GpioMode mode) { + GpioPull pull = GpioPullNo; + if(mode == GpioModeInput){ + pull = GpioPullDown; + } + for(uint8_t i = 0; i < GPIO_ITEM_COUNT; i++) { + gpio_item_configure_pin(i, mode, pull); + } +} + +void gpio_item_set_pin(uint8_t index, bool level) { + furi_assert(index < GPIO_ITEM_COUNT); + furi_hal_gpio_write(gpio_item[index].pin, level); +} + +bool gpio_item_get_pin(uint8_t index) { + furi_assert(index < GPIO_ITEM_COUNT); + return furi_hal_gpio_read(gpio_item[index].pin); +} + +void gpio_item_set_all_pins(bool level) { + for(uint8_t i = 0; i < GPIO_ITEM_COUNT; i++) { + gpio_item_set_pin(i, level); + } +} + +const char* gpio_item_get_pin_name(uint8_t index) { + furi_assert(index < GPIO_ITEM_COUNT + 1); + if(index == GPIO_ITEM_COUNT) { + return "ALL"; + } else { + return gpio_item[index].name; + } +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_item.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_item.h new file mode 100644 index 000000000..fe73e3851 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpio_item.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +#define GPIO_ITEM_COUNT 8 + +void gpio_item_configure_pin(uint8_t index, GpioMode mode, GpioPull pull); + +void gpio_item_configure_all_pins(GpioMode mode); + +void gpio_item_set_pin(uint8_t index, bool level); + +void gpio_item_set_all_pins(bool level); + +const char* gpio_item_get_pin_name(uint8_t index); + +bool gpio_item_get_pin(uint8_t index); diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpioreader.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/gpioreader.png new file mode 100644 index 0000000000000000000000000000000000000000..218764e782d72b4018a1e2be998da69cba428eea GIT binary patch literal 1919 zcmcIldrVVT7(dl%!6^8`1r#t_WD5AKI;38}7YI&7U1f9@)Tx~yC=y_$V!K7%CJcic z4b_&ajarJd3@Iw4)cBxThpiiJ3eJ`QVc>0PGobByOYdC?C0v}_A4~Sf&ADIhchC2I zzsEV>rX(lKnH4k(05B(U=k|R7O!K@FfX~>HG?cc+v-qCgnU)8D-_x;&P!Zv`7y#nh z#O+%?{(?7X*pl-qYVM2|C*D{7Rrt*ZFWxwP|U zNCu0A5#y>Z>t=wuivaj617NE!V5dw2OMmc&ZYm9EibtL1Ce+L*Gv-Q4JBL0>+yx1% zc0cSjMl=n%dgNRJI6ohN8}ER)cwt$L_E~KCXcr$72f13W-L0q=eT!A0+_1`d33Fg6Ri}{gQ)h6 zMamP^{cXXT%ugI$f7(y=^s=A|sD8DtMD=GAu;~8U3 znh6U@nS)V`-37n90@S4liW;t9$@43x%uqtvOjJCpxR*D= zVUDRVudk(m1gA^P!>!WS;s0o#mtH#!Hjag=H`h&h3cxS4ZZX5GpTy^q|#_Fr*{mV z>94DU4W{4eLr0MC%cIOgPk;ZM9^sJ>*V=P`RL>k2ydDQr6Oij|M z=aVdHpS)Zj7e<2@TeQ;XdoVY9M3m%~TZ3wEs^kM$)fLl+IIH|@ z2kI6n^%x{6a_e4?Z^F|1*Z8pajXBPv{>)AnD2Sp9Q*B61J0=r5GTeJwm#muw`X;c_ zLhMVXoCKXonvChiMwX3*_e2Ou|BR}x?qKjeB@zM@3u@mw(S8R29be;Eo-n=Ffd5~J z$eMt$ODWJuObQfjkzMTlla3k5YLV$Mo~L8}?CQJMp2XlC2LaXRor^{FtQSKkpQ>%c zAyYrzuD82sHur3J9S(6js8mrmnxEj*iKBn)lw|m^*Oh7JHt<$7Y?~vu##!8H4<6&v zp}VBVXVnOuh!f)28HIyL8*y0M<7E0M%5$GD(O2&t|ChwaW7>F6DV-3#P>k;!yOgOUodEy z{uIv7oIwJwI76l?IyfmCOcHuv9=J6jn|cSqd|DkZg>9*KCM2=x=t7{H=T&bt69niD zWnz5>-`fb@($H~9iHx`Z$Khz24Y?eC?gQ#uhq`ScfI9zw^II_hBpFYT7uFrP0+-hp lxs;vq&j`N(_!}Y2ve|Q9NNaOto*NY;?nvG)*?Q=!zW}&R^fUkf literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/icon.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..201d033e74e36c5488a571920b3fee257c3e03ad GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>vG;Uw4ABTq z{`3F;|9Uo+11C;!JX^?VY;Y+|@l4bV?+I(&H_rOSZdngu5+k1a4|d9Bh_Z irt#1_$AXE$%-QMLBh#tYK%*EuUHx3vIVChPFaQ90iY%J| literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene.c new file mode 100644 index 000000000..d5aa4cbe8 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene.c @@ -0,0 +1,30 @@ +#include "gpio_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const gpio_scene_on_enter_handlers[])(void*) = { +#include "gpio_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 gpio_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "gpio_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 gpio_scene_on_exit_handlers[])(void* context) = { +#include "gpio_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers gpio_scene_handlers = { + .on_enter_handlers = gpio_scene_on_enter_handlers, + .on_event_handlers = gpio_scene_on_event_handlers, + .on_exit_handlers = gpio_scene_on_exit_handlers, + .scene_num = GpioSceneNum, +}; diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene.h new file mode 100644 index 000000000..15556c8d5 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) GpioScene##id, +typedef enum { +#include "gpio_scene_config.h" + GpioSceneNum, +} GpioScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers gpio_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "gpio_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 "gpio_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 "gpio_scene_config.h" +#undef ADD_SCENE diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_config.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_config.h new file mode 100644 index 000000000..269c32aaf --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_config.h @@ -0,0 +1,6 @@ +ADD_SCENE(gpio, start, Start) +ADD_SCENE(gpio, test, Test) +ADD_SCENE(gpio, reader, Reader) +ADD_SCENE(gpio, usb_uart, UsbUart) +ADD_SCENE(gpio, usb_uart_cfg, UsbUartCfg) +ADD_SCENE(gpio, usb_uart_close_rpc, UsbUartCloseRpc) diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_reader.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_reader.c new file mode 100644 index 000000000..5995ff253 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_reader.c @@ -0,0 +1,30 @@ +#include "../gpio_app_i.h" + +void gpio_scene_reader_ok_callback(InputType type, void* context) { + furi_assert(context); + GpioApp* app = context; + + if(type == InputTypePress) { + notification_message(app->notifications, &sequence_set_green_255); + } else if(type == InputTypeRelease) { + notification_message(app->notifications, &sequence_reset_green); + } +} + +void gpio_scene_reader_on_enter(void* context) { + GpioApp* app = context; + gpio_item_configure_all_pins(GpioModeInput); + gpio_reader_set_ok_callback(app->gpio_reader, gpio_scene_reader_ok_callback, app); + view_dispatcher_switch_to_view(app->view_dispatcher, GpioAppViewGpioReader); +} + +bool gpio_scene_reader_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + return false; +} + +void gpio_scene_reader_on_exit(void* context) { + UNUSED(context); + gpio_item_configure_all_pins(GpioModeAnalog); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_start.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_start.c new file mode 100644 index 000000000..71ddd6593 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_start.c @@ -0,0 +1,114 @@ +#include "../gpio_app_i.h" +#include "furi_hal_power.h" +#include "furi_hal_usb.h" +#include + +enum GpioItem { + GpioItemUsbUart, + GpioItemTest, + GpioItemReader, + GpioItemOtg, +}; + +enum GpioOtg { + GpioOtgOff, + GpioOtgOn, + GpioOtgSettingsNum, +}; + +const char* const gpio_otg_text[GpioOtgSettingsNum] = { + "OFF", + "ON", +}; + +static void gpio_scene_start_var_list_enter_callback(void* context, uint32_t index) { + furi_assert(context); + GpioApp* app = context; + if(index == GpioItemTest) { + view_dispatcher_send_custom_event(app->view_dispatcher, GpioStartEventManualControl); + } else if(index == GpioItemUsbUart) { + view_dispatcher_send_custom_event(app->view_dispatcher, GpioStartEventUsbUart); + } else if(index == GpioItemReader) { + view_dispatcher_send_custom_event(app->view_dispatcher, GpioStartEventReader); + } +} + +static void gpio_scene_start_var_list_change_callback(VariableItem* item) { + GpioApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + + variable_item_set_current_value_text(item, gpio_otg_text[index]); + if(index == GpioOtgOff) { + view_dispatcher_send_custom_event(app->view_dispatcher, GpioStartEventOtgOff); + } else if(index == GpioOtgOn) { + view_dispatcher_send_custom_event(app->view_dispatcher, GpioStartEventOtgOn); + } +} + +void gpio_scene_start_on_enter(void* context) { + GpioApp* app = context; + VariableItemList* var_item_list = app->var_item_list; + + VariableItem* item; + variable_item_list_set_enter_callback( + var_item_list, gpio_scene_start_var_list_enter_callback, app); + + variable_item_list_add(var_item_list, "USB-UART Bridge", 0, NULL, NULL); + + variable_item_list_add(var_item_list, "GPIO Manual Control", 0, NULL, NULL); + + variable_item_list_add(var_item_list, "GPIO Manual Read", 0, NULL, NULL); + + item = variable_item_list_add( + var_item_list, + "5V on GPIO", + GpioOtgSettingsNum, + gpio_scene_start_var_list_change_callback, + app); + if(furi_hal_power_is_otg_enabled()) { + variable_item_set_current_value_index(item, GpioOtgOn); + variable_item_set_current_value_text(item, gpio_otg_text[GpioOtgOn]); + } else { + variable_item_set_current_value_index(item, GpioOtgOff); + variable_item_set_current_value_text(item, gpio_otg_text[GpioOtgOff]); + } + + variable_item_list_set_selected_item( + var_item_list, scene_manager_get_scene_state(app->scene_manager, GpioSceneStart)); + + view_dispatcher_switch_to_view(app->view_dispatcher, GpioAppViewVarItemList); +} + +bool gpio_scene_start_on_event(void* context, SceneManagerEvent event) { + GpioApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GpioStartEventOtgOn) { + furi_hal_power_enable_otg(); + } else if(event.event == GpioStartEventOtgOff) { + furi_hal_power_disable_otg(); + } else if(event.event == GpioStartEventManualControl) { + scene_manager_set_scene_state(app->scene_manager, GpioSceneStart, GpioItemTest); + scene_manager_next_scene(app->scene_manager, GpioSceneTest); + } else if(event.event == GpioStartEventReader) { + scene_manager_set_scene_state(app->scene_manager, GpioSceneStart, GpioItemReader); + scene_manager_next_scene(app->scene_manager, GpioSceneReader); + } else if(event.event == GpioStartEventUsbUart) { + scene_manager_set_scene_state(app->scene_manager, GpioSceneStart, GpioItemUsbUart); + if(!furi_hal_usb_is_locked()) { + DOLPHIN_DEED(DolphinDeedGpioUartBridge); + scene_manager_next_scene(app->scene_manager, GpioSceneUsbUart); + } else { + scene_manager_next_scene(app->scene_manager, GpioSceneUsbUartCloseRpc); + } + } + consumed = true; + } + return consumed; +} + +void gpio_scene_start_on_exit(void* context) { + GpioApp* app = context; + variable_item_list_reset(app->var_item_list); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_test.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_test.c new file mode 100644 index 000000000..b015d8090 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_test.c @@ -0,0 +1,30 @@ +#include "../gpio_app_i.h" + +void gpio_scene_test_ok_callback(InputType type, void* context) { + furi_assert(context); + GpioApp* app = context; + + if(type == InputTypePress) { + notification_message(app->notifications, &sequence_set_green_255); + } else if(type == InputTypeRelease) { + notification_message(app->notifications, &sequence_reset_green); + } +} + +void gpio_scene_test_on_enter(void* context) { + GpioApp* app = context; + gpio_item_configure_all_pins(GpioModeOutputPushPull); + gpio_test_set_ok_callback(app->gpio_test, gpio_scene_test_ok_callback, app); + view_dispatcher_switch_to_view(app->view_dispatcher, GpioAppViewGpioTest); +} + +bool gpio_scene_test_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + return false; +} + +void gpio_scene_test_on_exit(void* context) { + UNUSED(context); + gpio_item_configure_all_pins(GpioModeAnalog); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_usb_uart.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_usb_uart.c new file mode 100644 index 000000000..aa41aaf98 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_usb_uart.c @@ -0,0 +1,67 @@ +#include "../gpio_app_i.h" +#include "../usb_uart_bridge.h" + +typedef struct { + UsbUartConfig cfg; + UsbUartState state; +} SceneUsbUartBridge; + +static SceneUsbUartBridge* scene_usb_uart; + +void gpio_scene_usb_uart_callback(GpioCustomEvent event, void* context) { + furi_assert(context); + GpioApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, event); +} + +void gpio_scene_usb_uart_on_enter(void* context) { + GpioApp* app = context; + uint32_t prev_state = scene_manager_get_scene_state(app->scene_manager, GpioAppViewUsbUart); + if(prev_state == 0) { + scene_usb_uart = malloc(sizeof(SceneUsbUartBridge)); + scene_usb_uart->cfg.vcp_ch = 0; // TODO: settings load + scene_usb_uart->cfg.uart_ch = 0; + scene_usb_uart->cfg.flow_pins = 0; + scene_usb_uart->cfg.baudrate_mode = 0; + scene_usb_uart->cfg.baudrate = 0; + app->usb_uart_bridge = usb_uart_enable(&scene_usb_uart->cfg); + } + + usb_uart_get_config(app->usb_uart_bridge, &scene_usb_uart->cfg); + usb_uart_get_state(app->usb_uart_bridge, &scene_usb_uart->state); + + gpio_usb_uart_set_callback(app->gpio_usb_uart, gpio_scene_usb_uart_callback, app); + scene_manager_set_scene_state(app->scene_manager, GpioSceneUsbUart, 0); + view_dispatcher_switch_to_view(app->view_dispatcher, GpioAppViewUsbUart); + notification_message(app->notifications, &sequence_display_backlight_enforce_on); +} + +bool gpio_scene_usb_uart_on_event(void* context, SceneManagerEvent event) { + GpioApp* app = context; + if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state(app->scene_manager, GpioSceneUsbUart, 1); + scene_manager_next_scene(app->scene_manager, GpioSceneUsbUartCfg); + return true; + } else if(event.type == SceneManagerEventTypeTick) { + uint32_t tx_cnt_last = scene_usb_uart->state.tx_cnt; + uint32_t rx_cnt_last = scene_usb_uart->state.rx_cnt; + usb_uart_get_state(app->usb_uart_bridge, &scene_usb_uart->state); + gpio_usb_uart_update_state( + app->gpio_usb_uart, &scene_usb_uart->cfg, &scene_usb_uart->state); + if(tx_cnt_last != scene_usb_uart->state.tx_cnt) + notification_message(app->notifications, &sequence_blink_blue_10); + if(rx_cnt_last != scene_usb_uart->state.rx_cnt) + notification_message(app->notifications, &sequence_blink_green_10); + } + return false; +} + +void gpio_scene_usb_uart_on_exit(void* context) { + GpioApp* app = context; + uint32_t prev_state = scene_manager_get_scene_state(app->scene_manager, GpioSceneUsbUart); + if(prev_state == 0) { + usb_uart_disable(app->usb_uart_bridge); + free(scene_usb_uart); + } + notification_message(app->notifications, &sequence_display_backlight_enforce_auto); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_usb_uart_close_rpc.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_usb_uart_close_rpc.c new file mode 100644 index 000000000..2cb53cab2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_usb_uart_close_rpc.c @@ -0,0 +1,41 @@ +#include "../gpio_app_i.h" +#include "../gpio_custom_event.h" + +void gpio_scene_usb_uart_close_rpc_on_enter(void* context) { + GpioApp* app = context; + + widget_add_icon_element(app->widget, 78, 0, &I_ActiveConnection_50x64); + widget_add_string_multiline_element( + app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "Connection\nis active!"); + widget_add_string_multiline_element( + app->widget, + 3, + 30, + AlignLeft, + AlignTop, + FontSecondary, + "Disconnect from\nPC or phone to\nuse this function."); + + view_dispatcher_switch_to_view(app->view_dispatcher, GpioAppViewUsbUartCloseRpc); +} + +bool gpio_scene_usb_uart_close_rpc_on_event(void* context, SceneManagerEvent event) { + GpioApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GpioCustomEventErrorBack) { + if(!scene_manager_previous_scene(app->scene_manager)) { + scene_manager_stop(app->scene_manager); + view_dispatcher_stop(app->view_dispatcher); + } + consumed = true; + } + } + return consumed; +} + +void gpio_scene_usb_uart_close_rpc_on_exit(void* context) { + GpioApp* app = context; + widget_reset(app->widget); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_usb_uart_config.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_usb_uart_config.c new file mode 100644 index 000000000..55b04ed67 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/scenes/gpio_scene_usb_uart_config.c @@ -0,0 +1,169 @@ +#include "../usb_uart_bridge.h" +#include "../gpio_app_i.h" +#include "furi_hal.h" + +typedef enum { + UsbUartLineIndexVcp, + UsbUartLineIndexBaudrate, + UsbUartLineIndexUart, + UsbUartLineIndexFlow, +} LineIndex; + +static const char* vcp_ch[] = {"0 (CLI)", "1"}; +static const char* uart_ch[] = {"13,14", "15,16"}; +static const char* flow_pins[] = {"None", "2,3", "6,7", "16,15"}; +static const char* baudrate_mode[] = {"Host"}; +static const uint32_t baudrate_list[] = { + 2400, + 9600, + 19200, + 38400, + 57600, + 115200, + 230400, + 460800, + 921600, +}; + +bool gpio_scene_usb_uart_cfg_on_event(void* context, SceneManagerEvent event) { + GpioApp* app = context; + furi_assert(app); + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GpioUsbUartEventConfigSet) { + usb_uart_set_config(app->usb_uart_bridge, app->usb_uart_cfg); + return true; + } + } + return false; +} + +void line_ensure_flow_invariant(GpioApp* app) { + // GPIO pins PC0, PC1 (16,15) are unavailable for RTS/DTR when LPUART is + // selected. This function enforces that invariant by resetting flow_pins + // to None if it is configured to 16,15 when LPUART is selected. + + uint8_t available_flow_pins = app->usb_uart_cfg->uart_ch == FuriHalUartIdLPUART1 ? 3 : 4; + VariableItem* item = app->var_item_flow; + variable_item_set_values_count(item, available_flow_pins); + + if(app->usb_uart_cfg->flow_pins >= available_flow_pins) { + app->usb_uart_cfg->flow_pins = 0; + + variable_item_set_current_value_index(item, app->usb_uart_cfg->flow_pins); + variable_item_set_current_value_text(item, flow_pins[app->usb_uart_cfg->flow_pins]); + } +} + +static void line_vcp_cb(VariableItem* item) { + GpioApp* app = variable_item_get_context(item); + furi_assert(app); + uint8_t index = variable_item_get_current_value_index(item); + + variable_item_set_current_value_text(item, vcp_ch[index]); + + app->usb_uart_cfg->vcp_ch = index; + view_dispatcher_send_custom_event(app->view_dispatcher, GpioUsbUartEventConfigSet); +} + +static void line_port_cb(VariableItem* item) { + GpioApp* app = variable_item_get_context(item); + furi_assert(app); + uint8_t index = variable_item_get_current_value_index(item); + + variable_item_set_current_value_text(item, uart_ch[index]); + + if(index == 0) + app->usb_uart_cfg->uart_ch = FuriHalUartIdUSART1; + else if(index == 1) + app->usb_uart_cfg->uart_ch = FuriHalUartIdLPUART1; + + line_ensure_flow_invariant(app); + view_dispatcher_send_custom_event(app->view_dispatcher, GpioUsbUartEventConfigSet); +} + +static void line_flow_cb(VariableItem* item) { + GpioApp* app = variable_item_get_context(item); + furi_assert(app); + uint8_t index = variable_item_get_current_value_index(item); + + variable_item_set_current_value_text(item, flow_pins[index]); + + app->usb_uart_cfg->flow_pins = index; + view_dispatcher_send_custom_event(app->view_dispatcher, GpioUsbUartEventConfigSet); +} + +static void line_baudrate_cb(VariableItem* item) { + GpioApp* app = variable_item_get_context(item); + furi_assert(app); + uint8_t index = variable_item_get_current_value_index(item); + + char br_text[8]; + + if(index > 0) { + snprintf(br_text, 7, "%lu", baudrate_list[index - 1]); + variable_item_set_current_value_text(item, br_text); + app->usb_uart_cfg->baudrate = baudrate_list[index - 1]; + } else { + variable_item_set_current_value_text(item, baudrate_mode[index]); + app->usb_uart_cfg->baudrate = 0; + } + app->usb_uart_cfg->baudrate_mode = index; + view_dispatcher_send_custom_event(app->view_dispatcher, GpioUsbUartEventConfigSet); +} + +void gpio_scene_usb_uart_cfg_on_enter(void* context) { + GpioApp* app = context; + furi_assert(app); + VariableItemList* var_item_list = app->var_item_list; + + app->usb_uart_cfg = malloc(sizeof(UsbUartConfig)); + usb_uart_get_config(app->usb_uart_bridge, app->usb_uart_cfg); + + VariableItem* item; + char br_text[8]; + + item = variable_item_list_add(var_item_list, "USB Channel", 2, line_vcp_cb, app); + variable_item_set_current_value_index(item, app->usb_uart_cfg->vcp_ch); + variable_item_set_current_value_text(item, vcp_ch[app->usb_uart_cfg->vcp_ch]); + + item = variable_item_list_add( + var_item_list, + "Baudrate", + sizeof(baudrate_list) / sizeof(baudrate_list[0]) + 1, + line_baudrate_cb, + app); + variable_item_set_current_value_index(item, app->usb_uart_cfg->baudrate_mode); + if(app->usb_uart_cfg->baudrate_mode > 0) { + snprintf(br_text, 7, "%lu", baudrate_list[app->usb_uart_cfg->baudrate_mode - 1]); + variable_item_set_current_value_text(item, br_text); + } else { + variable_item_set_current_value_text( + item, baudrate_mode[app->usb_uart_cfg->baudrate_mode]); + } + + item = variable_item_list_add(var_item_list, "UART Pins", 2, line_port_cb, app); + variable_item_set_current_value_index(item, app->usb_uart_cfg->uart_ch); + variable_item_set_current_value_text(item, uart_ch[app->usb_uart_cfg->uart_ch]); + + item = variable_item_list_add( + var_item_list, "RTS/DTR Pins", COUNT_OF(flow_pins), line_flow_cb, app); + variable_item_set_current_value_index(item, app->usb_uart_cfg->flow_pins); + variable_item_set_current_value_text(item, flow_pins[app->usb_uart_cfg->flow_pins]); + app->var_item_flow = item; + line_ensure_flow_invariant(app); + + variable_item_list_set_selected_item( + var_item_list, scene_manager_get_scene_state(app->scene_manager, GpioAppViewUsbUartCfg)); + + view_dispatcher_switch_to_view(app->view_dispatcher, GpioAppViewUsbUartCfg); +} + +void gpio_scene_usb_uart_cfg_on_exit(void* context) { + GpioApp* app = context; + scene_manager_set_scene_state( + app->scene_manager, + GpioAppViewUsbUartCfg, + variable_item_list_get_selected_item_index(app->var_item_list)); + variable_item_list_reset(app->var_item_list); + free(app->usb_uart_cfg); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/usb_uart_bridge.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/usb_uart_bridge.c new file mode 100644 index 000000000..1a82dbdc2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/usb_uart_bridge.c @@ -0,0 +1,375 @@ +#include "usb_uart_bridge.h" +#include "furi_hal.h" +#include +#include "usb_cdc.h" +#include "cli/cli_vcp.h" +#include +#include "cli/cli.h" + +#define USB_CDC_PKT_LEN CDC_DATA_SZ +#define USB_UART_RX_BUF_SIZE (USB_CDC_PKT_LEN * 5) + +#define USB_CDC_BIT_DTR (1 << 0) +#define USB_CDC_BIT_RTS (1 << 1) + +static const GpioPin* flow_pins[][2] = { + {&gpio_ext_pa7, &gpio_ext_pa6}, // 2, 3 + {&gpio_ext_pb2, &gpio_ext_pc3}, // 6, 7 + {&gpio_ext_pc0, &gpio_ext_pc1}, // 16, 15 +}; + +typedef enum { + WorkerEvtStop = (1 << 0), + WorkerEvtRxDone = (1 << 1), + + WorkerEvtTxStop = (1 << 2), + WorkerEvtCdcRx = (1 << 3), + + WorkerEvtCfgChange = (1 << 4), + + WorkerEvtLineCfgSet = (1 << 5), + WorkerEvtCtrlLineSet = (1 << 6), + +} WorkerEvtFlags; + +#define WORKER_ALL_RX_EVENTS \ + (WorkerEvtStop | WorkerEvtRxDone | WorkerEvtCfgChange | WorkerEvtLineCfgSet | \ + WorkerEvtCtrlLineSet) +#define WORKER_ALL_TX_EVENTS (WorkerEvtTxStop | WorkerEvtCdcRx) + +struct UsbUartBridge { + UsbUartConfig cfg; + UsbUartConfig cfg_new; + + FuriThread* thread; + FuriThread* tx_thread; + + FuriStreamBuffer* rx_stream; + + FuriMutex* usb_mutex; + + FuriSemaphore* tx_sem; + + UsbUartState st; + + FuriApiLock cfg_lock; + + uint8_t rx_buf[USB_CDC_PKT_LEN]; +}; + +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, +}; + +/* USB UART worker */ + +static int32_t usb_uart_tx_thread(void* context); + +static void usb_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) { + UsbUartBridge* usb_uart = (UsbUartBridge*)context; + + if(ev == UartIrqEventRXNE) { + furi_stream_buffer_send(usb_uart->rx_stream, &data, 1, 0); + furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtRxDone); + } +} + +static void usb_uart_vcp_init(UsbUartBridge* usb_uart, uint8_t vcp_ch) { + furi_hal_usb_unlock(); + if(vcp_ch == 0) { + Cli* cli = furi_record_open(RECORD_CLI); + cli_session_close(cli); + furi_record_close(RECORD_CLI); + furi_check(furi_hal_usb_set_config(&usb_cdc_single, NULL) == true); + } else { + furi_check(furi_hal_usb_set_config(&usb_cdc_dual, NULL) == true); + Cli* cli = furi_record_open(RECORD_CLI); + cli_session_open(cli, &cli_vcp); + furi_record_close(RECORD_CLI); + } + furi_hal_cdc_set_callbacks(vcp_ch, (CdcCallbacks*)&cdc_cb, usb_uart); +} + +static void usb_uart_vcp_deinit(UsbUartBridge* usb_uart, uint8_t vcp_ch) { + UNUSED(usb_uart); + furi_hal_cdc_set_callbacks(vcp_ch, NULL, NULL); + if(vcp_ch != 0) { + Cli* cli = furi_record_open(RECORD_CLI); + cli_session_close(cli); + furi_record_close(RECORD_CLI); + } +} + +static void usb_uart_serial_init(UsbUartBridge* usb_uart, uint8_t uart_ch) { + if(uart_ch == FuriHalUartIdUSART1) { + furi_hal_console_disable(); + } else if(uart_ch == FuriHalUartIdLPUART1) { + furi_hal_uart_init(uart_ch, 115200); + } + furi_hal_uart_set_irq_cb(uart_ch, usb_uart_on_irq_cb, usb_uart); +} + +static void usb_uart_serial_deinit(UsbUartBridge* usb_uart, uint8_t uart_ch) { + UNUSED(usb_uart); + furi_hal_uart_set_irq_cb(uart_ch, NULL, NULL); + if(uart_ch == FuriHalUartIdUSART1) + furi_hal_console_enable(); + else if(uart_ch == FuriHalUartIdLPUART1) + furi_hal_uart_deinit(uart_ch); +} + +static void usb_uart_set_baudrate(UsbUartBridge* usb_uart, uint32_t baudrate) { + if(baudrate != 0) { + furi_hal_uart_set_br(usb_uart->cfg.uart_ch, baudrate); + usb_uart->st.baudrate_cur = baudrate; + } else { + struct usb_cdc_line_coding* line_cfg = + furi_hal_cdc_get_port_settings(usb_uart->cfg.vcp_ch); + if(line_cfg->dwDTERate > 0) { + furi_hal_uart_set_br(usb_uart->cfg.uart_ch, line_cfg->dwDTERate); + usb_uart->st.baudrate_cur = line_cfg->dwDTERate; + } + } +} + +static void usb_uart_update_ctrl_lines(UsbUartBridge* usb_uart) { + if(usb_uart->cfg.flow_pins != 0) { + furi_assert((size_t)(usb_uart->cfg.flow_pins - 1) < COUNT_OF(flow_pins)); + uint8_t state = furi_hal_cdc_get_ctrl_line_state(usb_uart->cfg.vcp_ch); + + furi_hal_gpio_write(flow_pins[usb_uart->cfg.flow_pins - 1][0], !(state & USB_CDC_BIT_RTS)); + furi_hal_gpio_write(flow_pins[usb_uart->cfg.flow_pins - 1][1], !(state & USB_CDC_BIT_DTR)); + } +} + +static int32_t usb_uart_worker(void* context) { + UsbUartBridge* usb_uart = (UsbUartBridge*)context; + + memcpy(&usb_uart->cfg, &usb_uart->cfg_new, sizeof(UsbUartConfig)); + + usb_uart->rx_stream = furi_stream_buffer_alloc(USB_UART_RX_BUF_SIZE, 1); + + usb_uart->tx_sem = furi_semaphore_alloc(1, 1); + usb_uart->usb_mutex = furi_mutex_alloc(FuriMutexTypeNormal); + + usb_uart->tx_thread = + furi_thread_alloc_ex("UsbUartTxWorker", 512, usb_uart_tx_thread, usb_uart); + + usb_uart_vcp_init(usb_uart, usb_uart->cfg.vcp_ch); + usb_uart_serial_init(usb_uart, usb_uart->cfg.uart_ch); + usb_uart_set_baudrate(usb_uart, usb_uart->cfg.baudrate); + if(usb_uart->cfg.flow_pins != 0) { + furi_assert((size_t)(usb_uart->cfg.flow_pins - 1) < COUNT_OF(flow_pins)); + furi_hal_gpio_init_simple( + flow_pins[usb_uart->cfg.flow_pins - 1][0], GpioModeOutputPushPull); + furi_hal_gpio_init_simple( + flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeOutputPushPull); + usb_uart_update_ctrl_lines(usb_uart); + } + + furi_thread_flags_set(furi_thread_get_id(usb_uart->tx_thread), WorkerEvtCdcRx); + + furi_thread_start(usb_uart->tx_thread); + + while(1) { + uint32_t events = + furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever); + furi_check(!(events & FuriFlagError)); + if(events & WorkerEvtStop) break; + if(events & WorkerEvtRxDone) { + size_t len = furi_stream_buffer_receive( + usb_uart->rx_stream, usb_uart->rx_buf, USB_CDC_PKT_LEN, 0); + if(len > 0) { + if(furi_semaphore_acquire(usb_uart->tx_sem, 100) == FuriStatusOk) { + usb_uart->st.rx_cnt += len; + furi_check( + furi_mutex_acquire(usb_uart->usb_mutex, FuriWaitForever) == FuriStatusOk); + furi_hal_cdc_send(usb_uart->cfg.vcp_ch, usb_uart->rx_buf, len); + furi_check(furi_mutex_release(usb_uart->usb_mutex) == FuriStatusOk); + } else { + furi_stream_buffer_reset(usb_uart->rx_stream); + } + } + } + if(events & WorkerEvtCfgChange) { + if(usb_uart->cfg.vcp_ch != usb_uart->cfg_new.vcp_ch) { + furi_thread_flags_set(furi_thread_get_id(usb_uart->tx_thread), WorkerEvtTxStop); + furi_thread_join(usb_uart->tx_thread); + + usb_uart_vcp_deinit(usb_uart, usb_uart->cfg.vcp_ch); + usb_uart_vcp_init(usb_uart, usb_uart->cfg_new.vcp_ch); + + usb_uart->cfg.vcp_ch = usb_uart->cfg_new.vcp_ch; + furi_thread_start(usb_uart->tx_thread); + events |= WorkerEvtCtrlLineSet; + events |= WorkerEvtLineCfgSet; + } + if(usb_uart->cfg.uart_ch != usb_uart->cfg_new.uart_ch) { + furi_thread_flags_set(furi_thread_get_id(usb_uart->tx_thread), WorkerEvtTxStop); + furi_thread_join(usb_uart->tx_thread); + + usb_uart_serial_deinit(usb_uart, usb_uart->cfg.uart_ch); + usb_uart_serial_init(usb_uart, usb_uart->cfg_new.uart_ch); + + usb_uart->cfg.uart_ch = usb_uart->cfg_new.uart_ch; + usb_uart_set_baudrate(usb_uart, usb_uart->cfg.baudrate); + + furi_thread_start(usb_uart->tx_thread); + } + if(usb_uart->cfg.baudrate != usb_uart->cfg_new.baudrate) { + usb_uart_set_baudrate(usb_uart, usb_uart->cfg_new.baudrate); + usb_uart->cfg.baudrate = usb_uart->cfg_new.baudrate; + } + if(usb_uart->cfg.flow_pins != usb_uart->cfg_new.flow_pins) { + if(usb_uart->cfg.flow_pins != 0) { + furi_hal_gpio_init_simple( + flow_pins[usb_uart->cfg.flow_pins - 1][0], GpioModeAnalog); + furi_hal_gpio_init_simple( + flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeAnalog); + } + if(usb_uart->cfg_new.flow_pins != 0) { + furi_assert((size_t)(usb_uart->cfg_new.flow_pins - 1) < COUNT_OF(flow_pins)); + furi_hal_gpio_init_simple( + flow_pins[usb_uart->cfg_new.flow_pins - 1][0], GpioModeOutputPushPull); + furi_hal_gpio_init_simple( + flow_pins[usb_uart->cfg_new.flow_pins - 1][1], GpioModeOutputPushPull); + } + usb_uart->cfg.flow_pins = usb_uart->cfg_new.flow_pins; + events |= WorkerEvtCtrlLineSet; + } + api_lock_unlock(usb_uart->cfg_lock); + } + if(events & WorkerEvtLineCfgSet) { + if(usb_uart->cfg.baudrate == 0) + usb_uart_set_baudrate(usb_uart, usb_uart->cfg.baudrate); + } + if(events & WorkerEvtCtrlLineSet) { + usb_uart_update_ctrl_lines(usb_uart); + } + } + usb_uart_vcp_deinit(usb_uart, usb_uart->cfg.vcp_ch); + usb_uart_serial_deinit(usb_uart, usb_uart->cfg.uart_ch); + + if(usb_uart->cfg.flow_pins != 0) { + furi_hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][0], GpioModeAnalog); + furi_hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeAnalog); + } + + furi_thread_flags_set(furi_thread_get_id(usb_uart->tx_thread), WorkerEvtTxStop); + furi_thread_join(usb_uart->tx_thread); + furi_thread_free(usb_uart->tx_thread); + + furi_stream_buffer_free(usb_uart->rx_stream); + furi_mutex_free(usb_uart->usb_mutex); + furi_semaphore_free(usb_uart->tx_sem); + + furi_hal_usb_unlock(); + furi_check(furi_hal_usb_set_config(&usb_cdc_single, NULL) == true); + Cli* cli = furi_record_open(RECORD_CLI); + cli_session_open(cli, &cli_vcp); + furi_record_close(RECORD_CLI); + + return 0; +} + +static int32_t usb_uart_tx_thread(void* context) { + UsbUartBridge* usb_uart = (UsbUartBridge*)context; + + uint8_t data[USB_CDC_PKT_LEN]; + while(1) { + uint32_t events = + furi_thread_flags_wait(WORKER_ALL_TX_EVENTS, FuriFlagWaitAny, FuriWaitForever); + furi_check(!(events & FuriFlagError)); + if(events & WorkerEvtTxStop) break; + if(events & WorkerEvtCdcRx) { + furi_check(furi_mutex_acquire(usb_uart->usb_mutex, FuriWaitForever) == FuriStatusOk); + size_t len = furi_hal_cdc_receive(usb_uart->cfg.vcp_ch, data, USB_CDC_PKT_LEN); + furi_check(furi_mutex_release(usb_uart->usb_mutex) == FuriStatusOk); + + if(len > 0) { + usb_uart->st.tx_cnt += len; + furi_hal_uart_tx(usb_uart->cfg.uart_ch, data, len); + } + } + } + return 0; +} + +/* VCP callbacks */ + +static void vcp_on_cdc_tx_complete(void* context) { + UsbUartBridge* usb_uart = (UsbUartBridge*)context; + furi_semaphore_release(usb_uart->tx_sem); +} + +static void vcp_on_cdc_rx(void* context) { + UsbUartBridge* usb_uart = (UsbUartBridge*)context; + furi_thread_flags_set(furi_thread_get_id(usb_uart->tx_thread), WorkerEvtCdcRx); +} + +static void vcp_state_callback(void* context, uint8_t state) { + UNUSED(context); + UNUSED(state); +} + +static void vcp_on_cdc_control_line(void* context, uint8_t state) { + UNUSED(state); + UsbUartBridge* usb_uart = (UsbUartBridge*)context; + furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtCtrlLineSet); +} + +static void vcp_on_line_config(void* context, struct usb_cdc_line_coding* config) { + UNUSED(config); + UsbUartBridge* usb_uart = (UsbUartBridge*)context; + furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtLineCfgSet); +} + +UsbUartBridge* usb_uart_enable(UsbUartConfig* cfg) { + UsbUartBridge* usb_uart = malloc(sizeof(UsbUartBridge)); + + memcpy(&(usb_uart->cfg_new), cfg, sizeof(UsbUartConfig)); + + usb_uart->thread = furi_thread_alloc_ex("UsbUartWorker", 1024, usb_uart_worker, usb_uart); + + furi_thread_start(usb_uart->thread); + return usb_uart; +} + +void usb_uart_disable(UsbUartBridge* usb_uart) { + furi_assert(usb_uart); + furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtStop); + furi_thread_join(usb_uart->thread); + furi_thread_free(usb_uart->thread); + free(usb_uart); +} + +void usb_uart_set_config(UsbUartBridge* usb_uart, UsbUartConfig* cfg) { + furi_assert(usb_uart); + furi_assert(cfg); + usb_uart->cfg_lock = api_lock_alloc_locked(); + memcpy(&(usb_uart->cfg_new), cfg, sizeof(UsbUartConfig)); + furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtCfgChange); + api_lock_wait_unlock_and_free(usb_uart->cfg_lock); +} + +void usb_uart_get_config(UsbUartBridge* usb_uart, UsbUartConfig* cfg) { + furi_assert(usb_uart); + furi_assert(cfg); + memcpy(cfg, &(usb_uart->cfg_new), sizeof(UsbUartConfig)); +} + +void usb_uart_get_state(UsbUartBridge* usb_uart, UsbUartState* st) { + furi_assert(usb_uart); + furi_assert(st); + memcpy(st, &(usb_uart->st), sizeof(UsbUartState)); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/usb_uart_bridge.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/usb_uart_bridge.h new file mode 100644 index 000000000..b456c3cc4 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/usb_uart_bridge.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +typedef struct UsbUartBridge UsbUartBridge; + +typedef struct { + uint8_t vcp_ch; + uint8_t uart_ch; + uint8_t flow_pins; + uint8_t baudrate_mode; + uint32_t baudrate; +} UsbUartConfig; + +typedef struct { + uint32_t rx_cnt; + uint32_t tx_cnt; + uint32_t baudrate_cur; +} UsbUartState; + +UsbUartBridge* usb_uart_enable(UsbUartConfig* cfg); + +void usb_uart_disable(UsbUartBridge* usb_uart); + +void usb_uart_set_config(UsbUartBridge* usb_uart, UsbUartConfig* cfg); + +void usb_uart_get_config(UsbUartBridge* usb_uart, UsbUartConfig* cfg); + +void usb_uart_get_state(UsbUartBridge* usb_uart, UsbUartState* st); diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_reader.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_reader.c new file mode 100644 index 000000000..95a425fda --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_reader.c @@ -0,0 +1,164 @@ +#include "gpio_reader.h" +#include "../gpio_item.h" + +#include +#include + +struct GpioReader { + View* view; + GpioReaderOkCallback callback; + void* context; +}; + +typedef struct { + uint8_t pin_idx; + bool pullUp[GPIO_ITEM_COUNT]; +} GpioReaderModel; + +static bool gpio_reader_process_ok(GpioReader* gpio_reader, InputEvent* event); +static bool gpio_reader_process_left(GpioReader* gpio_reader); +static bool gpio_reader_process_right(GpioReader* gpio_reader); + +static void gpio_reader_draw_callback(Canvas* canvas, void* _model) { + GpioReaderModel* model = _model; + canvas_set_font(canvas, FontPrimary); + elements_multiline_text_aligned(canvas, 64, 2, AlignCenter, AlignTop, "GPIO Reader"); + canvas_set_font(canvas, FontSecondary); + elements_multiline_text_aligned( + canvas, 64, 16, AlignCenter, AlignTop, "A7 A6 A4 B3 B2 C3 C1 C0"); + elements_multiline_text_aligned( + canvas, 64, 40, AlignCenter, AlignTop, "Pull Up"); + int charOffset = 10; + for(uint8_t i = 0; i < GPIO_ITEM_COUNT; i++) { + bool high = gpio_item_get_pin(i); + if(high) { + elements_multiline_text_aligned( + canvas, charOffset, 25, AlignCenter, AlignTop, "1"); + } else { + elements_multiline_text_aligned( + canvas, charOffset, 25, AlignCenter, AlignTop, "0"); + } + + if(model->pullUp[i]) { + elements_multiline_text_aligned( + canvas, charOffset, 50, AlignCenter, AlignTop, "1"); + } else { + elements_multiline_text_aligned( + canvas, charOffset, 50, AlignCenter, AlignTop, "0"); + } + if(i == model->pin_idx) { + elements_multiline_text_aligned( + canvas, charOffset, 53, AlignCenter, AlignTop, "_"); + } + + + charOffset += 16; + } + //~ free(charOffset); +} + +static bool gpio_reader_input_callback(InputEvent* event, void* context) { + furi_assert(context); + GpioReader* gpio_reader = context; + bool consumed = false; + + if(event->type == InputTypeShort) { + if(event->key == InputKeyRight) { + consumed = gpio_reader_process_right(gpio_reader); + } else if(event->key == InputKeyLeft) { + consumed = gpio_reader_process_left(gpio_reader); + } + } else if(event->key == InputKeyOk) { + consumed = gpio_reader_process_ok(gpio_reader, event); + } + + return consumed; +} + +static bool gpio_reader_process_left(GpioReader* gpio_reader) { + with_view_model( + gpio_reader->view, + GpioReaderModel * model, + { + if(model->pin_idx) { + model->pin_idx--; + } + }, + true); + return true; +} + +static bool gpio_reader_process_right(GpioReader* gpio_reader) { + with_view_model( + gpio_reader->view, + GpioReaderModel * model, + { + if(model->pin_idx < GPIO_ITEM_COUNT-1) { + model->pin_idx++; + } + }, + true); + return true; +} + +static bool gpio_reader_process_ok(GpioReader* gpio_reader, InputEvent* event) { + bool consumed = false; + + with_view_model( + gpio_reader->view, + GpioReaderModel * model, + { + if(event->type == InputTypePress) { + if(model->pullUp[model->pin_idx]){ + gpio_item_configure_pin(model->pin_idx, GpioModeInput, GpioPullDown); + model->pullUp[model->pin_idx] = 0; + consumed = true; + }else{ + gpio_item_configure_pin(model->pin_idx, GpioModeInput, GpioPullUp); + model->pullUp[model->pin_idx] = 1; + consumed = true; + } + } + gpio_reader->callback(event->type, gpio_reader->context); + }, + true); + + return consumed; +} + +GpioReader* gpio_reader_alloc() { + GpioReader* gpio_reader = malloc(sizeof(GpioReader)); + + gpio_reader->view = view_alloc(); + view_allocate_model(gpio_reader->view, ViewModelTypeLocking, sizeof(GpioReaderModel)); + view_set_context(gpio_reader->view, gpio_reader); + view_set_draw_callback(gpio_reader->view, gpio_reader_draw_callback); + view_set_input_callback(gpio_reader->view, gpio_reader_input_callback); + + return gpio_reader; +} + +void gpio_reader_free(GpioReader* gpio_reader) { + furi_assert(gpio_reader); + view_free(gpio_reader->view); + free(gpio_reader); +} + +View* gpio_reader_get_view(GpioReader* gpio_reader) { + furi_assert(gpio_reader); + return gpio_reader->view; +} + +void gpio_reader_set_ok_callback(GpioReader* gpio_reader, GpioReaderOkCallback callback, void* context) { + furi_assert(gpio_reader); + furi_assert(callback); + with_view_model( + gpio_reader->view, + GpioReaderModel * model, + { + UNUSED(model); + gpio_reader->callback = callback; + gpio_reader->context = context; + }, + false); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_reader.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_reader.h new file mode 100644 index 000000000..d027d0138 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_reader.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +typedef struct GpioReader GpioReader; +typedef void (*GpioReaderOkCallback)(InputType type, void* context); + +GpioReader* gpio_reader_alloc(); + +void gpio_reader_free(GpioReader* gpio_reader); + +View* gpio_reader_get_view(GpioReader* gpio_reader); + +void gpio_reader_set_ok_callback(GpioReader* gpio_reader, GpioReaderOkCallback callback, void* context); diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_test.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_test.c new file mode 100644 index 000000000..69dc0f67b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_test.c @@ -0,0 +1,139 @@ +#include "gpio_test.h" +#include "../gpio_item.h" + +#include + +struct GpioTest { + View* view; + GpioTestOkCallback callback; + void* context; +}; + +typedef struct { + uint8_t pin_idx; +} GpioTestModel; + +static bool gpio_test_process_left(GpioTest* gpio_test); +static bool gpio_test_process_right(GpioTest* gpio_test); +static bool gpio_test_process_ok(GpioTest* gpio_test, InputEvent* event); + +static void gpio_test_draw_callback(Canvas* canvas, void* _model) { + GpioTestModel* model = _model; + canvas_set_font(canvas, FontPrimary); + elements_multiline_text_aligned(canvas, 64, 2, AlignCenter, AlignTop, "GPIO Output Mode Test"); + canvas_set_font(canvas, FontSecondary); + elements_multiline_text_aligned( + canvas, 64, 16, AlignCenter, AlignTop, "Press < or > to change pin"); + elements_multiline_text_aligned( + canvas, 64, 32, AlignCenter, AlignTop, gpio_item_get_pin_name(model->pin_idx)); +} + +static bool gpio_test_input_callback(InputEvent* event, void* context) { + furi_assert(context); + GpioTest* gpio_test = context; + bool consumed = false; + + if(event->type == InputTypeShort) { + if(event->key == InputKeyRight) { + consumed = gpio_test_process_right(gpio_test); + } else if(event->key == InputKeyLeft) { + consumed = gpio_test_process_left(gpio_test); + } + } else if(event->key == InputKeyOk) { + consumed = gpio_test_process_ok(gpio_test, event); + } + + return consumed; +} + +static bool gpio_test_process_left(GpioTest* gpio_test) { + with_view_model( + gpio_test->view, + GpioTestModel * model, + { + if(model->pin_idx) { + model->pin_idx--; + } + }, + true); + return true; +} + +static bool gpio_test_process_right(GpioTest* gpio_test) { + with_view_model( + gpio_test->view, + GpioTestModel * model, + { + if(model->pin_idx < GPIO_ITEM_COUNT) { + model->pin_idx++; + } + }, + true); + return true; +} + +static bool gpio_test_process_ok(GpioTest* gpio_test, InputEvent* event) { + bool consumed = false; + + with_view_model( + gpio_test->view, + GpioTestModel * model, + { + if(event->type == InputTypePress) { + if(model->pin_idx < GPIO_ITEM_COUNT) { + gpio_item_set_pin(model->pin_idx, true); + } else { + gpio_item_set_all_pins(true); + } + consumed = true; + } else if(event->type == InputTypeRelease) { + if(model->pin_idx < GPIO_ITEM_COUNT) { + gpio_item_set_pin(model->pin_idx, false); + } else { + gpio_item_set_all_pins(false); + } + consumed = true; + } + gpio_test->callback(event->type, gpio_test->context); + }, + true); + + return consumed; +} + +GpioTest* gpio_test_alloc() { + GpioTest* gpio_test = malloc(sizeof(GpioTest)); + + gpio_test->view = view_alloc(); + view_allocate_model(gpio_test->view, ViewModelTypeLocking, sizeof(GpioTestModel)); + view_set_context(gpio_test->view, gpio_test); + view_set_draw_callback(gpio_test->view, gpio_test_draw_callback); + view_set_input_callback(gpio_test->view, gpio_test_input_callback); + + return gpio_test; +} + +void gpio_test_free(GpioTest* gpio_test) { + furi_assert(gpio_test); + view_free(gpio_test->view); + free(gpio_test); +} + +View* gpio_test_get_view(GpioTest* gpio_test) { + furi_assert(gpio_test); + return gpio_test->view; +} + +void gpio_test_set_ok_callback(GpioTest* gpio_test, GpioTestOkCallback callback, void* context) { + furi_assert(gpio_test); + furi_assert(callback); + with_view_model( + gpio_test->view, + GpioTestModel * model, + { + UNUSED(model); + gpio_test->callback = callback; + gpio_test->context = context; + }, + false); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_test.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_test.h new file mode 100644 index 000000000..5cbd11e82 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_test.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +typedef struct GpioTest GpioTest; +typedef void (*GpioTestOkCallback)(InputType type, void* context); + +GpioTest* gpio_test_alloc(); + +void gpio_test_free(GpioTest* gpio_test); + +View* gpio_test_get_view(GpioTest* gpio_test); + +void gpio_test_set_ok_callback(GpioTest* gpio_test, GpioTestOkCallback callback, void* context); diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_usb_uart.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_usb_uart.c new file mode 100644 index 000000000..c7406d29b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_usb_uart.c @@ -0,0 +1,161 @@ +#include "../usb_uart_bridge.h" +#include "../gpio_app_i.h" +#include "furi_hal.h" +#include + +struct GpioUsbUart { + View* view; + GpioUsbUartCallback callback; + void* context; +}; + +typedef struct { + uint32_t baudrate; + uint32_t tx_cnt; + uint32_t rx_cnt; + uint8_t vcp_port; + uint8_t tx_pin; + uint8_t rx_pin; + bool tx_active; + bool rx_active; +} GpioUsbUartModel; + +static void gpio_usb_uart_draw_callback(Canvas* canvas, void* _model) { + GpioUsbUartModel* model = _model; + char temp_str[18]; + elements_button_left(canvas, "Config"); + canvas_draw_line(canvas, 2, 10, 125, 10); + canvas_draw_line(canvas, 44, 52, 123, 52); + + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 2, 9, "USB Serial"); + canvas_draw_str(canvas, 3, 25, "TX:"); + canvas_draw_str(canvas, 3, 42, "RX:"); + + canvas_set_font(canvas, FontSecondary); + snprintf(temp_str, 18, "COM PORT:%u", model->vcp_port); + canvas_draw_str_aligned(canvas, 126, 8, AlignRight, AlignBottom, temp_str); + snprintf(temp_str, 18, "Pin %u", model->tx_pin); + canvas_draw_str(canvas, 22, 25, temp_str); + snprintf(temp_str, 18, "Pin %u", model->rx_pin); + canvas_draw_str(canvas, 22, 42, temp_str); + + if(model->baudrate == 0) + snprintf(temp_str, 18, "Baud: ????"); + else + snprintf(temp_str, 18, "Baud: %lu", model->baudrate); + canvas_draw_str(canvas, 45, 62, temp_str); + + if(model->tx_cnt < 100000000) { + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned(canvas, 127, 24, AlignRight, AlignBottom, "B."); + canvas_set_font(canvas, FontKeyboard); + snprintf(temp_str, 18, "%lu", model->tx_cnt); + canvas_draw_str_aligned(canvas, 116, 24, AlignRight, AlignBottom, temp_str); + } else { + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned(canvas, 127, 24, AlignRight, AlignBottom, "KiB."); + canvas_set_font(canvas, FontKeyboard); + snprintf(temp_str, 18, "%lu", model->tx_cnt / 1024); + canvas_draw_str_aligned(canvas, 111, 24, AlignRight, AlignBottom, temp_str); + } + + if(model->rx_cnt < 100000000) { + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned(canvas, 127, 41, AlignRight, AlignBottom, "B."); + canvas_set_font(canvas, FontKeyboard); + snprintf(temp_str, 18, "%lu", model->rx_cnt); + canvas_draw_str_aligned(canvas, 116, 41, AlignRight, AlignBottom, temp_str); + } else { + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned(canvas, 127, 41, AlignRight, AlignBottom, "KiB."); + canvas_set_font(canvas, FontKeyboard); + snprintf(temp_str, 18, "%lu", model->rx_cnt / 1024); + canvas_draw_str_aligned(canvas, 111, 41, AlignRight, AlignBottom, temp_str); + } + + if(model->tx_active) + canvas_draw_icon(canvas, 48, 14, &I_ArrowUpFilled_14x15); + else + canvas_draw_icon(canvas, 48, 14, &I_ArrowUpEmpty_14x15); + + if(model->rx_active) + canvas_draw_icon(canvas, 48, 34, &I_ArrowDownFilled_14x15); + else + canvas_draw_icon(canvas, 48, 34, &I_ArrowDownEmpty_14x15); +} + +static bool gpio_usb_uart_input_callback(InputEvent* event, void* context) { + furi_assert(context); + GpioUsbUart* usb_uart = context; + bool consumed = false; + + if(event->type == InputTypeShort) { + if(event->key == InputKeyLeft) { + consumed = true; + furi_assert(usb_uart->callback); + usb_uart->callback(GpioUsbUartEventConfig, usb_uart->context); + } + } + + return consumed; +} + +GpioUsbUart* gpio_usb_uart_alloc() { + GpioUsbUart* usb_uart = malloc(sizeof(GpioUsbUart)); + + usb_uart->view = view_alloc(); + view_allocate_model(usb_uart->view, ViewModelTypeLocking, sizeof(GpioUsbUartModel)); + view_set_context(usb_uart->view, usb_uart); + view_set_draw_callback(usb_uart->view, gpio_usb_uart_draw_callback); + view_set_input_callback(usb_uart->view, gpio_usb_uart_input_callback); + + return usb_uart; +} + +void gpio_usb_uart_free(GpioUsbUart* usb_uart) { + furi_assert(usb_uart); + view_free(usb_uart->view); + free(usb_uart); +} + +View* gpio_usb_uart_get_view(GpioUsbUart* usb_uart) { + furi_assert(usb_uart); + return usb_uart->view; +} + +void gpio_usb_uart_set_callback(GpioUsbUart* usb_uart, GpioUsbUartCallback callback, void* context) { + furi_assert(usb_uart); + furi_assert(callback); + + with_view_model( + usb_uart->view, + GpioUsbUartModel * model, + { + UNUSED(model); + usb_uart->callback = callback; + usb_uart->context = context; + }, + false); +} + +void gpio_usb_uart_update_state(GpioUsbUart* instance, UsbUartConfig* cfg, UsbUartState* st) { + furi_assert(instance); + furi_assert(cfg); + furi_assert(st); + + with_view_model( + instance->view, + GpioUsbUartModel * model, + { + model->baudrate = st->baudrate_cur; + model->vcp_port = cfg->vcp_ch; + model->tx_pin = (cfg->uart_ch == 0) ? (13) : (15); + model->rx_pin = (cfg->uart_ch == 0) ? (14) : (16); + model->tx_active = (model->tx_cnt != st->tx_cnt); + model->rx_active = (model->rx_cnt != st->rx_cnt); + model->tx_cnt = st->tx_cnt; + model->rx_cnt = st->rx_cnt; + }, + true); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_usb_uart.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_usb_uart.h new file mode 100644 index 000000000..854b51f8d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_gpioreader/views/gpio_usb_uart.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include "../gpio_custom_event.h" +#include "../usb_uart_bridge.h" + +typedef struct GpioUsbUart GpioUsbUart; +typedef void (*GpioUsbUartCallback)(GpioCustomEvent event, void* context); + +GpioUsbUart* gpio_usb_uart_alloc(); + +void gpio_usb_uart_free(GpioUsbUart* usb_uart); + +View* gpio_usb_uart_get_view(GpioUsbUart* usb_uart); + +void gpio_usb_uart_set_callback(GpioUsbUart* usb_uart, GpioUsbUartCallback callback, void* context); + +void gpio_usb_uart_update_state(GpioUsbUart* instance, UsbUartConfig* cfg, UsbUartState* st); diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/.github/FUNDING.yml b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/.github/FUNDING.yml new file mode 100644 index 000000000..2cabf7401 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/.github/FUNDING.yml @@ -0,0 +1 @@ +ko_fi: caralynx diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/.github/workflows/build-fap.yml b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/.github/workflows/build-fap.yml new file mode 100644 index 000000000..f65b8609a --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/.github/workflows/build-fap.yml @@ -0,0 +1,12 @@ +name: Build FAP +on: [push] + +jobs: + build: + if: ${{ false }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Build + uses: oleksiikutuzov/flipperzero-ufbt-action@v1 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/LICENSE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/README.md b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/README.md new file mode 100644 index 000000000..7f680fcc6 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/README.md @@ -0,0 +1,170 @@ +VB Lab Migration Assistant for Flipper Zero +=========================================== + +This app is designed to make transferring your characters from VB Lab and VBC +Lab more convenient. + +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/C0C81P4PX) + +Background +---------- +The Vital Bracelet Arena app is going to be the new companion app for the Vital +Bracelet series of fitness bracelet toys, however the app does not support +account linking from VB Lab and VBC Lab, and requires you to transfer characters +one by one from those apps through your Vital Bracelet. Because the Vital +Bracelet can only hold at most two characters at a time and requires inserting +Dim/VBM to complete the transfer, transferring all of your characters may take a +significant amount of time. The VB Lab Migration Assistant is designed to make +this process faster by allowing you to store an unlimited amount of characters +on the Flipper and to bypass the Dim loading process, therefore allowing you to +transfer your characters without having to flip back and forth between the apps +or wasting time loading data that will never be used. + +Usage +----- + +### 1. Register Vital Bracelet + +Registering your Vital Bracelet to the Flipper creates template data used for +emulating the VB using the Flipper. + +- Select "Register Vital Bracelet" from Migration Assistant's main menu. +- If you have an active character on your Vital Bracelet, **transfer it to VB + Lab/Arena**. The active character slot on the VB has to be empty to avoid + issues when transferring character from VB Lab/Arena to the Flipper. Press the + right key on Flipper. + +If using VB Lab: +- If there is an active character in VB Lab, put it in storage. +- On VB Lab's "Scan" page, tap "Vital Bracelet -> App". Press the right key on + Flipper. + +If using VB Arena: +- Select the device type matching your VB and any franchise. +- Tap the "Send" button. Press the right key on Flipper. + +- Tap the Flipper to your Vital Bracelet. You do not have to put the VB in scan + mode. When Flipper finishes reading, it will beep. +- On VB Lab, tap "Send", or on VB Arena, tap "Transfer Data", and tap the + Flipper to your phone. VB Lab/Arena will give you an error message. This is + normal, and you can dismiss it. The Flipper will beep. Wait for it to switch + to the next screen. +- Tap the Flipper to the original Vital Bracelet again. The Flipper will beep + when it's finished reading. +- Name the Vital Bracelet and select "Save". + +The Vital Bracelet info will show after saving. + +### 2. Select Vital Bracelet, Vital Bracelet Info + +Use the "Select Vital Bracelet" menu to load a previously registered VB. After +loading, you will see information about this Vital Bracelet: + +- Registered name +- Vital Bracelet type +- Number of characters captured + +Press the right key to see a menu of options you can use with the registered VB. + +### Spoof Version + +Vital Bracelet Arena splits Vital Bracelet and Vital Hero Digimon into +mutually-exclusive categories, and currently transferring VBM characters from +VBDM has not been tested, so if you want to transfer between categories, you can +select the Vital Bracelet version to spoof to change the VB type and force the +app to perform transfers between categories. + +Note that spoofing a Vital Bracelet Characters from a non-VBC registration and +vice versa will not work because different encryption keys are used. + +### Unlink Account + +This option unsets the account flag in the NFC data so the character is not +bound to any particular account, and you can transfer it to a different Vital +Bracelet that is using a different account when using VB Arena. + +If enabled when transferring from app, the flag will be unset on the capture and +will still be unset when transferring to app. If enabled when transferring to +app, the flag will be unset on all transfers, regardless whether the flag was +set when captured. + +Note that VB Lab may still complain because it also uses character ID embedded +in character data to check whether the character belongs to the current account. + +### 3. Transfer App > Flipper + +Use this mode to transfer characters from VB Lab to Flipper. + +- An instructions screen is displayed. Press right key to continue. + +If using VB Lab: +- On your VB Lab app, wake up the character you want to send (if you have not + already). +- Go to the "Scan" screen, and tap "App -> Vital Bracelet". Select "Check Dim + Card". If prompted to send Special Missions or items, tap "No". + +If using VB Arena: +- Select the device and franchise for the character you want to transfer. +- Tap the "Assign" button. +- Press and hold on the character you want to transfer. +- Tap the "Send" button. +- Tap "OK". +- Tap "Check Card". + +- Tap the Flipper to your phone. Release when VB Lab indicates to do so, and + wait for Flipper to beep. +- Tap "Check Dim/Card Installation" on VB Lab/Arena, and tap Flipper to your + phone. Flipper will beep. +- Tap "Send" on VB Lab, or "Transfer Data" on VB Arena, and tap Flipper to your + phone. Hold it there until VB Lab/Arena shows the transfer animation. Flipper + will beep after it has received the character. +- Tap "OK" on VB Lab/Arena. Flipper will have automatically reloaded the + template so you can repeat the above again to transfer more characters. +- When you are done transferring characters, press the left key on Flipper to + exit the transfer mode. + +Note if you have previously transferred characters to Flipper, the new +characters you transfer will be put at the end of the sequence of characters +when transferring from Flipper to app. + +### 4. Transfer Flipper > App + +Use this mode to transfer characters from Flipper to VB Lab. + +- An instructions screen is displayed. Press right key to continue. + +If using VB Lab: +- If there is an active character in VB Lab, put it in storage. +- On VB Lab's "Scan" page, tap "Vital Bracelet -> App". +- Tap "Send". + +If using VB Arena: +- Select the device type matching your VB and any franchise. +- Tap the "Send" button. +- Tap the "Transfer Data" button. + +- Tap your Flipper to your phone, and hold until VB Lab/Arena shows the +- transfer animation. Flipper will beep when it detected the transfer and will +- load the next character. +- Repeat the above until all of your characters have been transferred. +- If you want to skip a certain character, press the right key to skip and load +- the next character. +- You will see the "Transfers complete" screen on Flipper when all characters +- have been transferred. Press the right key to return to the menu. + +### 5. Clear Captures + +If you are doing transfers in batches, you can clear the currently captured +characters so you do not have to skip them when transferring to app. Check the +details, and press the right key to confirm deletion. + +### 6. Delete Vital Bracelet + +If you want to unregister the Vital Bracelet, you can use this option to delete +its captures and remove it from the "Select Vital Bracelet" list. Check the +details, and press the right key to confirm deletion. + +Credits +------- + +Graphics by [Aderek](https://twitter.com/AderekArt) diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/application.fam b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/application.fam new file mode 100644 index 000000000..2c5ba480d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/application.fam @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# +# VB Lab Migration Assistant for Flipper Zero +# Copyright (C) 2022 cyanic +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +App( + appid="vb_migrate", + name="VB Migration Assistant", + apptype=FlipperAppType.EXTERNAL, + entry_point="vb_migrate_app", + requires=["gui", "storage"], + stack_size=2 * 1024, + fap_version=(1,0), + fap_libs=["nfc", "misc", "mbedtls", "ST25RFAL002", "gcc", "toolbox"], + fap_icon="vb_migrate_10px.png", + fap_category="Misc_Extra", + fap_description="Makes transferring characters with VB Lab less cumbersome", + fap_author="cyanic", + fap_weburl="https://github.com/GMMan/flipperzero-vb-migrate", + fap_icon_assets="icons", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/gui/modules/file_select.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/gui/modules/file_select.c new file mode 100644 index 000000000..c7560af75 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/gui/modules/file_select.c @@ -0,0 +1,481 @@ +#include "file_select.h" +#include +#include + +#define FILENAME_COUNT 4 + +struct FileSelect { + // public + View* view; + Storage* fs_api; + const char* path; + const char* extension; + + bool init_completed; + + FileSelectCallback callback; + void* context; + + char* buffer; + uint8_t buffer_size; +}; + +typedef struct { + FuriString* filename[FILENAME_COUNT]; + uint8_t position; + + uint16_t first_file_index; + uint16_t file_count; + +} FileSelectModel; + +bool file_select_fill_strings(FileSelect* file_select); +bool file_select_fill_count(FileSelect* file_select); +static bool file_select_init_inner(FileSelect* file_select); + +static void file_select_draw_callback(Canvas* canvas, void* _model) { + FileSelectModel* model = _model; + + FuriString* string_buff; + const uint8_t item_height = 16; + const uint8_t item_width = 123; + const uint8_t text_max_width = 115; + + canvas_clear(canvas); + canvas_set_font(canvas, FontSecondary); + + if(model->file_count) { + for(uint8_t i = 0; i < MIN(FILENAME_COUNT, model->file_count); i++) { + if(i == model->position) { + canvas_set_color(canvas, ColorBlack); + canvas_draw_box(canvas, 0, (i * item_height) + 1, item_width, item_height - 2); + + canvas_set_color(canvas, ColorWhite); + canvas_draw_dot(canvas, 0, (i * item_height) + 1); + canvas_draw_dot(canvas, 0, (i * item_height) + item_height - 2); + canvas_draw_dot(canvas, item_width - 1, (i * item_height) + 1); + canvas_draw_dot(canvas, item_width - 1, (i * item_height) + item_height - 2); + } else { + canvas_set_color(canvas, ColorBlack); + } + + string_buff = furi_string_alloc_set(model->filename[i]); + elements_string_fit_width(canvas, string_buff, text_max_width); + canvas_draw_str( + canvas, 6, (i * item_height) + item_height - 4, furi_string_get_cstr(string_buff)); + + furi_string_free(string_buff); + } + } else { + canvas_draw_str(canvas, 6, item_height, "Empty folder"); + } + elements_scrollbar(canvas, model->first_file_index + model->position, model->file_count); +} + +static bool file_select_input_callback(InputEvent* event, void* context) { + FileSelect* file_select = (FileSelect*)context; + bool consumed = false; + + if((event->type == InputTypeShort) | (event->type == InputTypeRepeat)) { + if(!file_select->init_completed) { + if(!file_select_init_inner(file_select)) { + file_select->callback(false, file_select->context); + } + } else if(event->key == InputKeyUp) { + with_view_model( + file_select->view, + FileSelectModel * model, + { + if(model->position == 0) { + if(model->first_file_index == 0) { + // wrap + int16_t max_first_file_index = model->file_count - FILENAME_COUNT; + model->position = MIN(FILENAME_COUNT - 1, model->file_count - 1); + model->first_file_index = + max_first_file_index < 0 ? 0 : max_first_file_index; + } else { + model->first_file_index--; + } + } else if(model->position == 1) { + if(model->first_file_index == 0) { + model->position--; + } else { + model->first_file_index--; + } + } else { + model->position--; + } + }, + true); + consumed = true; + if(!file_select_fill_strings(file_select)) { + file_select->callback(false, file_select->context); + } + } else if(event->key == InputKeyDown) { + with_view_model( + file_select->view, + FileSelectModel * model, + { + uint16_t max_first_file_index = model->file_count > FILENAME_COUNT ? + model->file_count - FILENAME_COUNT : + 0; + + if(model->position >= MIN(FILENAME_COUNT - 1, model->file_count - 1)) { + if(model->first_file_index >= max_first_file_index) { + // wrap + model->position = 0; + model->first_file_index = 0; + } else { + model->first_file_index++; + } + } else if(model->position >= (FILENAME_COUNT - 2)) { + if(model->first_file_index >= max_first_file_index) { + model->position++; + } else { + model->first_file_index++; + } + } else { + model->position++; + } + }, + true); + consumed = true; + if(!file_select_fill_strings(file_select)) { + file_select->callback(false, file_select->context); + } + } else if(event->key == InputKeyOk) { + if(file_select->callback != NULL) { + size_t files = 0; + if(file_select->buffer) { + with_view_model( + file_select->view, + FileSelectModel * model, + { + files = model->file_count; + strlcpy( + file_select->buffer, + furi_string_get_cstr(model->filename[model->position]), + file_select->buffer_size); + }, + false); + }; + if(files > 0) { + file_select->callback(true, file_select->context); + } + } + consumed = true; + } + } + + return consumed; +} + +static bool file_select_init_inner(FileSelect* file_select) { + bool result = false; + if(file_select->path && file_select->extension && file_select->fs_api) { + if(file_select_fill_count(file_select)) { + if(file_select_fill_strings(file_select)) { + file_select->init_completed = true; + result = true; + } + } + } + + return result; +} + +FileSelect* file_select_alloc() { + FileSelect* file_select = malloc(sizeof(FileSelect)); + file_select->view = view_alloc(); + file_select->fs_api = furi_record_open("storage"); + + view_set_context(file_select->view, file_select); + view_allocate_model(file_select->view, ViewModelTypeLockFree, sizeof(FileSelectModel)); + view_set_draw_callback(file_select->view, file_select_draw_callback); + view_set_input_callback(file_select->view, file_select_input_callback); + + with_view_model( + file_select->view, + FileSelectModel * model, + { + for(uint8_t i = 0; i < FILENAME_COUNT; i++) { + model->filename[i] = furi_string_alloc(); + } + + model->first_file_index = 0; + model->file_count = 0; + }, + false); + + return file_select; +} + +void file_select_free(FileSelect* file_select) { + furi_assert(file_select); + with_view_model( + file_select->view, + FileSelectModel * model, + { + for(uint8_t i = 0; i < FILENAME_COUNT; i++) { + furi_string_free(model->filename[i]); + } + }, + false); + view_free(file_select->view); + free(file_select); + furi_record_close("storage"); +} + +View* file_select_get_view(FileSelect* file_select) { + furi_assert(file_select); + return file_select->view; +} + +void file_select_set_callback(FileSelect* file_select, FileSelectCallback callback, void* context) { + file_select->context = context; + file_select->callback = callback; +} + +void file_select_set_filter(FileSelect* file_select, const char* path, const char* extension) { + furi_assert(file_select); + file_select->path = path; + file_select->extension = extension; +} + +void file_select_set_result_buffer(FileSelect* file_select, char* buffer, uint8_t buffer_size) { + file_select->buffer = buffer; + file_select->buffer_size = buffer_size; + + if(file_select->buffer) { + strlcpy(file_select->buffer, "", file_select->buffer_size); + } +} + +bool file_select_init(FileSelect* file_select) { + if(!file_select_init_inner(file_select)) { + file_select->callback(false, file_select->context); + return false; + } else { + return true; + } +} + +static bool filter_file(FileSelect* file_select, FileInfo* file_info, char* name) { + bool result = false; + + if((file_info->flags & FSF_DIRECTORY)) { + if(strcmp(file_select->extension, "*") == 0) { + result = true; + } else if(strstr(name, file_select->extension) != NULL) { + result = true; + } + } + + return result; +} + +bool file_select_fill_strings(FileSelect* file_select) { + furi_assert(file_select); + furi_assert(file_select->fs_api); + furi_assert(file_select->path); + furi_assert(file_select->extension); + + FileInfo file_info; + File* directory = storage_file_alloc(file_select->fs_api); + + uint8_t string_counter = 0; + uint16_t file_counter = 0; + const uint8_t name_length = 100; + char* name = malloc(name_length); + uint16_t first_file_index = 0; + + with_view_model( + file_select->view, + FileSelectModel * model, + { first_file_index = model->first_file_index; }, + false); + + if(!storage_dir_open(directory, file_select->path)) { + storage_dir_close(directory); + storage_file_free(directory); + free(name); + return true; + } + + while(1) { + if(!storage_dir_read(directory, &file_info, name, name_length)) { + break; + } + + if(storage_file_get_error(directory) == FSE_OK) { + if(filter_file(file_select, &file_info, name)) { + if(file_counter >= first_file_index) { + with_view_model( + file_select->view, + FileSelectModel * model, + { + furi_string_set(model->filename[string_counter], name); + + if(strcmp(file_select->extension, "*") != 0) { + furi_string_replace_all_str( + model->filename[string_counter], file_select->extension, ""); + } + }, + true); + string_counter++; + + if(string_counter >= FILENAME_COUNT) { + break; + } + } + file_counter++; + } + } else { + storage_dir_close(directory); + storage_file_free(directory); + free(name); + return false; + } + } + + storage_dir_close(directory); + storage_file_free(directory); + free(name); + return true; +} + +bool file_select_fill_count(FileSelect* file_select) { + furi_assert(file_select); + furi_assert(file_select->fs_api); + furi_assert(file_select->path); + furi_assert(file_select->extension); + + FileInfo file_info; + File* directory = storage_file_alloc(file_select->fs_api); + + uint16_t file_counter = 0; + const uint8_t name_length = 100; + char* name = malloc(name_length); + + if(!storage_dir_open(directory, file_select->path)) { + storage_dir_close(directory); + storage_file_free(directory); + free(name); + return true; + } + + while(1) { + if(!storage_dir_read(directory, &file_info, name, name_length)) { + break; + } + + if(storage_file_get_error(directory) == FSE_OK) { + if(filter_file(file_select, &file_info, name)) { + file_counter++; + } + } else { + storage_dir_close(directory); + storage_file_free(directory); + free(name); + return false; + } + } + + with_view_model( + file_select->view, FileSelectModel * model, { model->file_count = file_counter; }, false); + + storage_dir_close(directory); + storage_file_free(directory); + free(name); + return true; +} + +void file_select_set_selected_file_internal(FileSelect* file_select, const char* filename) { + furi_assert(file_select); + furi_assert(filename); + furi_assert(file_select->fs_api); + furi_assert(file_select->path); + furi_assert(file_select->extension); + + if(strlen(filename) == 0) return; + + FileInfo file_info; + File* directory = storage_file_alloc(file_select->fs_api); + + const uint8_t name_length = 100; + char* name = malloc(name_length); + uint16_t file_position = 0; + bool file_found = false; + + FuriString* filename_str = furi_string_alloc_set_str(filename); + if(strcmp(file_select->extension, "*") != 0) { + furi_string_cat_str(filename_str, file_select->extension); + } + + if(!storage_dir_open(directory, file_select->path)) { + furi_string_free(filename_str); + storage_dir_close(directory); + storage_file_free(directory); + free(name); + return; + } + + while(1) { + if(!storage_dir_read(directory, &file_info, name, name_length)) { + break; + } + + if(storage_file_get_error(directory) == FSE_OK) { + if(filter_file(file_select, &file_info, name)) { + if(strcmp(furi_string_get_cstr(filename_str), name) == 0) { + file_found = true; + break; + } + + file_position++; + } + } else { + furi_string_free(filename_str); + storage_dir_close(directory); + storage_file_free(directory); + free(name); + return; + } + } + + if(file_found) { + with_view_model( + file_select->view, + FileSelectModel * model, + { + uint16_t max_first_file_index = + model->file_count > FILENAME_COUNT ? model->file_count - FILENAME_COUNT : 0; + + model->first_file_index = file_position; + + if(model->first_file_index > 0) { + model->first_file_index -= 1; + } + + if(model->first_file_index >= max_first_file_index) { + model->first_file_index = max_first_file_index; + } + + model->position = file_position - model->first_file_index; + }, + true); + } + + furi_string_free(filename_str); + storage_dir_close(directory); + storage_file_free(directory); + free(name); +} + +void file_select_set_selected_file(FileSelect* file_select, const char* filename) { + file_select_set_selected_file_internal(file_select, filename); + + if(!file_select_fill_strings(file_select)) { + file_select->callback(false, file_select->context); + } +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/gui/modules/file_select.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/gui/modules/file_select.h new file mode 100644 index 000000000..ed3d5b60c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/gui/modules/file_select.h @@ -0,0 +1,31 @@ +/** + * @file file_select.h + * GUI: FileSelect view module API + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FileSelect FileSelect; + +typedef void (*FileSelectCallback)(bool result, void* context); + +FileSelect* file_select_alloc(); + +void file_select_free(FileSelect* file_select); +View* file_select_get_view(FileSelect* file_select); + +void file_select_set_callback(FileSelect* file_select, FileSelectCallback callback, void* context); +void file_select_set_filter(FileSelect* file_select, const char* path, const char* extension); +void file_select_set_result_buffer(FileSelect* file_select, char* buffer, uint8_t buffer_size); +bool file_select_init(FileSelect* file_select); +void file_select_set_selected_file(FileSelect* file_select, const char* filename); + +#ifdef __cplusplus +} +#endif diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/gui/modules/variable_item_list_ex.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/gui/modules/variable_item_list_ex.c new file mode 100644 index 000000000..69543891a --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/gui/modules/variable_item_list_ex.c @@ -0,0 +1,419 @@ +#include "variable_item_list_ex.h" +#include "gui/canvas.h" +#include +#include +#include +#include + +struct VariableItemEx { + const char* label; + uint8_t current_value_index; + FuriString* current_value_text; + uint8_t values_count; + VariableItemExChangeCallback change_callback; + void* context; + int32_t callback_index; +}; + +ARRAY_DEF(VariableItemExArray, VariableItemEx, M_POD_OPLIST); + +struct VariableItemListEx { + View* view; + VariableItemListExEnterCallback callback; + void* context; +}; + +typedef struct { + VariableItemExArray_t items; + uint8_t position; + uint8_t window_position; +} VariableItemListExModel; + +static void variable_item_list_ex_process_up(VariableItemListEx* variable_item_list); +static void variable_item_list_ex_process_down(VariableItemListEx* variable_item_list); +static void variable_item_list_ex_process_left(VariableItemListEx* variable_item_list); +static void variable_item_list_ex_process_right(VariableItemListEx* variable_item_list); +static void variable_item_list_ex_process_ok(VariableItemListEx* variable_item_list); + +static void variable_item_list_ex_draw_callback(Canvas* canvas, void* _model) { + VariableItemListExModel* model = _model; + + const uint8_t item_height = 16; + const uint8_t item_width = 123; + + canvas_clear(canvas); + + uint8_t position = 0; + VariableItemExArray_it_t it; + + canvas_set_font(canvas, FontSecondary); + for(VariableItemExArray_it(it, model->items); !VariableItemExArray_end_p(it); + VariableItemExArray_next(it)) { + uint8_t item_position = position - model->window_position; + uint8_t items_on_screen = 4; + uint8_t y_offset = 0; + + if(item_position < items_on_screen) { + const VariableItemEx* item = VariableItemExArray_cref(it); + uint8_t item_y = y_offset + (item_position * item_height); + uint8_t item_text_y = item_y + item_height - 4; + + if(position == model->position) { + canvas_set_color(canvas, ColorBlack); + elements_slightly_rounded_box(canvas, 0, item_y + 1, item_width, item_height - 2); + canvas_set_color(canvas, ColorWhite); + } else { + canvas_set_color(canvas, ColorBlack); + } + + canvas_draw_str(canvas, 6, item_text_y, item->label); + + if(item->current_value_index > 0) { + canvas_draw_str(canvas, 73, item_text_y, "<"); + } + + canvas_draw_str_aligned( + canvas, + (115 + 73) / 2 + 1, + item_text_y, + AlignCenter, + AlignBottom, + furi_string_get_cstr(item->current_value_text)); + + if(item->current_value_index < (item->values_count - 1)) { + canvas_draw_str(canvas, 115, item_text_y, ">"); + } + } + + position++; + } + + elements_scrollbar(canvas, model->position, VariableItemExArray_size(model->items)); +} + +void variable_item_list_ex_set_selected_item(VariableItemListEx* variable_item_list, uint8_t index) { + with_view_model( + variable_item_list->view, + VariableItemListExModel * model, + { + uint8_t position = index; + if(position >= VariableItemExArray_size(model->items)) { + position = 0; + } + + model->position = position; + model->window_position = position; + + if(model->window_position > 0) { + model->window_position -= 1; + } + + if(VariableItemExArray_size(model->items) <= 4) { + model->window_position = 0; + } else { + if(model->window_position >= (VariableItemExArray_size(model->items) - 4)) { + model->window_position = (VariableItemExArray_size(model->items) - 4); + } + } + }, + true); +} + +uint8_t variable_item_list_ex_get_selected_item_index(VariableItemListEx* variable_item_list) { + VariableItemListExModel* model = view_get_model(variable_item_list->view); + uint8_t idx = model->position; + view_commit_model(variable_item_list->view, false); + return idx; +} + +static bool variable_item_list_ex_input_callback(InputEvent* event, void* context) { + VariableItemListEx* variable_item_list = context; + furi_assert(variable_item_list); + bool consumed = false; + + if(event->type == InputTypeShort) { + switch(event->key) { + case InputKeyUp: + consumed = true; + variable_item_list_ex_process_up(variable_item_list); + break; + case InputKeyDown: + consumed = true; + variable_item_list_ex_process_down(variable_item_list); + break; + case InputKeyLeft: + consumed = true; + variable_item_list_ex_process_left(variable_item_list); + break; + case InputKeyRight: + consumed = true; + variable_item_list_ex_process_right(variable_item_list); + break; + case InputKeyOk: + variable_item_list_ex_process_ok(variable_item_list); + break; + default: + break; + } + } else if(event->type == InputTypeRepeat) { + switch(event->key) { + case InputKeyUp: + consumed = true; + variable_item_list_ex_process_up(variable_item_list); + break; + case InputKeyDown: + consumed = true; + variable_item_list_ex_process_down(variable_item_list); + break; + case InputKeyLeft: + consumed = true; + variable_item_list_ex_process_left(variable_item_list); + break; + case InputKeyRight: + consumed = true; + variable_item_list_ex_process_right(variable_item_list); + break; + default: + break; + } + } + + return consumed; +} + +void variable_item_list_ex_process_up(VariableItemListEx* variable_item_list) { + with_view_model( + variable_item_list->view, + VariableItemListExModel * model, + { + uint8_t items_on_screen = 4; + if(model->position > 0) { + model->position--; + if(((model->position - model->window_position) < 1) && + model->window_position > 0) { + model->window_position--; + } + } else { + model->position = VariableItemExArray_size(model->items) - 1; + if(model->position > (items_on_screen - 1)) { + model->window_position = model->position - (items_on_screen - 1); + } + } + }, + true); +} + +void variable_item_list_ex_process_down(VariableItemListEx* variable_item_list) { + with_view_model( + variable_item_list->view, + VariableItemListExModel * model, + { + uint8_t items_on_screen = 4; + if(model->position < (VariableItemExArray_size(model->items) - 1)) { + model->position++; + if((model->position - model->window_position) > (items_on_screen - 2) && + model->window_position < + (VariableItemExArray_size(model->items) - items_on_screen)) { + model->window_position++; + } + } else { + model->position = 0; + model->window_position = 0; + } + }, + true); +} + +VariableItemEx* variable_item_list_ex_get_selected_item(VariableItemListExModel* model) { + VariableItemEx* item = NULL; + + VariableItemExArray_it_t it; + uint8_t position = 0; + for(VariableItemExArray_it(it, model->items); !VariableItemExArray_end_p(it); + VariableItemExArray_next(it)) { + if(position == model->position) { + break; + } + position++; + } + + item = VariableItemExArray_ref(it); + + furi_assert(item); + return item; +} + +void variable_item_list_ex_process_left(VariableItemListEx* variable_item_list) { + with_view_model( + variable_item_list->view, + VariableItemListExModel * model, + { + VariableItemEx* item = variable_item_list_ex_get_selected_item(model); + if(item->current_value_index > 0) { + item->current_value_index--; + if(item->change_callback) { + item->change_callback(item); + } + } + }, + true); +} + +void variable_item_list_ex_process_right(VariableItemListEx* variable_item_list) { + with_view_model( + variable_item_list->view, + VariableItemListExModel * model, + { + VariableItemEx* item = variable_item_list_ex_get_selected_item(model); + if(item->current_value_index < (item->values_count - 1)) { + item->current_value_index++; + if(item->change_callback) { + item->change_callback(item); + } + } + }, + true); +} + +void variable_item_list_ex_process_ok(VariableItemListEx* variable_item_list) { + with_view_model( + variable_item_list->view, + VariableItemListExModel * model, + { + if(variable_item_list->callback) { + const VariableItemEx* variable_item = + VariableItemExArray_cget(model->items, model->position); + variable_item_list->callback( + variable_item_list->context, variable_item->callback_index); + } + }, + false); +} + +VariableItemListEx* variable_item_list_ex_alloc() { + VariableItemListEx* variable_item_list = malloc(sizeof(VariableItemListEx)); + variable_item_list->view = view_alloc(); + view_set_context(variable_item_list->view, variable_item_list); + view_allocate_model( + variable_item_list->view, ViewModelTypeLocking, sizeof(VariableItemListExModel)); + view_set_draw_callback(variable_item_list->view, variable_item_list_ex_draw_callback); + view_set_input_callback(variable_item_list->view, variable_item_list_ex_input_callback); + + with_view_model( + variable_item_list->view, + VariableItemListExModel * model, + { + VariableItemExArray_init(model->items); + model->position = 0; + model->window_position = 0; + }, + true); + + return variable_item_list; +} + +void variable_item_list_ex_free(VariableItemListEx* variable_item_list) { + furi_assert(variable_item_list); + + with_view_model( + variable_item_list->view, + VariableItemListExModel * model, + { + VariableItemExArray_it_t it; + for(VariableItemExArray_it(it, model->items); !VariableItemExArray_end_p(it); + VariableItemExArray_next(it)) { + furi_string_free(VariableItemExArray_ref(it)->current_value_text); + } + VariableItemExArray_clear(model->items); + }, + false); + view_free(variable_item_list->view); + free(variable_item_list); +} + +void variable_item_list_ex_reset(VariableItemListEx* variable_item_list) { + furi_assert(variable_item_list); + + with_view_model( + variable_item_list->view, + VariableItemListExModel * model, + { + VariableItemExArray_it_t it; + for(VariableItemExArray_it(it, model->items); !VariableItemExArray_end_p(it); + VariableItemExArray_next(it)) { + furi_string_free(VariableItemExArray_ref(it)->current_value_text); + } + VariableItemExArray_reset(model->items); + }, + false); +} + +View* variable_item_list_ex_get_view(VariableItemListEx* variable_item_list) { + furi_assert(variable_item_list); + return variable_item_list->view; +} + +VariableItemEx* variable_item_list_ex_add( + VariableItemListEx* variable_item_list, + const char* label, + uint8_t values_count, + VariableItemExChangeCallback change_callback, + void* context, + int32_t callback_index) { + VariableItemEx* item = NULL; + furi_assert(label); + furi_assert(variable_item_list); + + with_view_model( + variable_item_list->view, + VariableItemListExModel * model, + { + item = VariableItemExArray_push_new(model->items); + item->label = label; + item->values_count = values_count; + item->change_callback = change_callback; + item->context = context; + item->current_value_index = 0; + item->current_value_text = furi_string_alloc(); + item->callback_index = callback_index; + }, + true); + + return item; +} + +void variable_item_list_ex_set_enter_callback( + VariableItemListEx* variable_item_list, + VariableItemListExEnterCallback callback, + void* context) { + furi_assert(callback); + with_view_model( + variable_item_list->view, + VariableItemListExModel * model, + { + UNUSED(model); + variable_item_list->callback = callback; + variable_item_list->context = context; + }, + false); +} + +void variable_item_ex_set_current_value_index(VariableItemEx* item, uint8_t current_value_index) { + item->current_value_index = current_value_index; +} + +void variable_item_ex_set_values_count(VariableItemEx* item, uint8_t values_count) { + item->values_count = values_count; +} + +void variable_item_ex_set_current_value_text(VariableItemEx* item, const char* current_value_text) { + furi_string_set(item->current_value_text, current_value_text); +} + +uint8_t variable_item_ex_get_current_value_index(VariableItemEx* item) { + return item->current_value_index; +} + +void* variable_item_ex_get_context(VariableItemEx* item) { + return item->context; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/gui/modules/variable_item_list_ex.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/gui/modules/variable_item_list_ex.h new file mode 100644 index 000000000..3af5886b0 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/gui/modules/variable_item_list_ex.h @@ -0,0 +1,117 @@ +/** + * @file variable_item_list.h + * GUI: VariableItemList view module API + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct VariableItemListEx VariableItemListEx; +typedef struct VariableItemEx VariableItemEx; +typedef void (*VariableItemExChangeCallback)(VariableItemEx* item); +typedef void (*VariableItemListExEnterCallback)(void* context, uint32_t index); + +/** Allocate and initialize VariableItemList + * + * @return VariableItemList* + */ +VariableItemListEx* variable_item_list_ex_alloc(); + +/** Deinitialize and free VariableItemList + * + * @param variable_item_list VariableItemList instance + */ +void variable_item_list_ex_free(VariableItemListEx* variable_item_list); + +/** Clear all elements from list + * + * @param variable_item_list VariableItemList instance + */ +void variable_item_list_ex_reset(VariableItemListEx* variable_item_list); + +/** Get VariableItemList View instance + * + * @param variable_item_list VariableItemList instance + * + * @return View instance + */ +View* variable_item_list_ex_get_view(VariableItemListEx* variable_item_list); + +/** Add item to VariableItemList + * + * @param variable_item_list VariableItemList instance + * @param label item name + * @param values_count item values count + * @param change_callback called on value change in gui + * @param context item context + * + * @return VariableItemEx* item instance + */ +VariableItemEx* variable_item_list_ex_add( + VariableItemListEx* variable_item_list, + const char* label, + uint8_t values_count, + VariableItemExChangeCallback change_callback, + void* context, + int32_t callback_index); + +/** Set enter callback + * + * @param variable_item_list VariableItemList instance + * @param callback VariableItemListEnterCallback instance + * @param context pointer to context + */ +void variable_item_list_ex_set_enter_callback( + VariableItemListEx* variable_item_list, + VariableItemListExEnterCallback callback, + void* context); + +void variable_item_list_ex_set_selected_item(VariableItemListEx* variable_item_list, uint8_t index); + +uint8_t variable_item_list_ex_get_selected_item_index(VariableItemListEx* variable_item_list); + +/** Set item current selected index + * + * @param item VariableItemEx* instance + * @param current_value_index The current value index + */ +void variable_item_ex_set_current_value_index(VariableItemEx* item, uint8_t current_value_index); + +/** Set number of values for item + * + * @param item VariableItemEx* instance + * @param values_count The new values count + */ +void variable_item_ex_set_values_count(VariableItemEx* item, uint8_t values_count); + +/** Set item current selected text + * + * @param item VariableItemEx* instance + * @param current_value_text The current value text + */ +void variable_item_ex_set_current_value_text(VariableItemEx* item, const char* current_value_text); + +/** Get item current selected index + * + * @param item VariableItemEx* instance + * + * @return uint8_t current selected index + */ +uint8_t variable_item_ex_get_current_value_index(VariableItemEx* item); + +/** Get item context + * + * @param item VariableItemEx* instance + * + * @return void* item context + */ +void* variable_item_ex_get_context(VariableItemEx* item); + +#ifdef __cplusplus +} +#endif diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/AppInteract_32x27.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/AppInteract_32x27.png new file mode 100644 index 0000000000000000000000000000000000000000..282d884b66d3899f5608605478820b05217188c0 GIT binary patch literal 777 zcmV+k1NQuhP)EX>4Tx04R}tkv&MmKpe$i(~2S$2P=ql$WWauh!t^^Di*;)X)CnqU~=gfG-*gu zTpR`0f`cE6RR0!X5l%$?&0I>U6f~epZjwRC4rtTK|Hf* z>74h8L#!+*#OK5l23?T&k?XR{Z=6dG3p_JqWYhD+A!4!A#c~(3vY`@B6Gs$PqkJLf zvch?bvs$gQ_C5Ivg9U9R!*!ZrB(Q`eQV=1djtZ)<5T#Wk#YCF+;~xG|$DbmXOs)zT zITlcZ3d!+<|H1EW&0=iIO$x?=o)_Ex7z28DfmXw|zmILZbprUGfh(=!uQh?$PtqG5 zEph}5ZUYzB9ZlW?E_Z;DCtWfmNAlAYibdf4jJ_!k4BZ0#Yi@7teVjf3S?X%}1~@nb z#!HmF?(y!v?%w`A)9&vFu_SW9l0g*)00009a7bBm000ie000ie0hKEb8vpy0-6PXJbNM!$M{1K%9|7x;Q&klJ^w!%Q;}&HWm6)y6NG8RBQH5-#wu-ZlR$VS^aNEw( zBHAHmX$n}zM?i+Y<&w2YFCy!ZA*gKu^&PW|h52&dCJMl_1(qap=_+?Y=^j`)8pbO? zyX0(dPENDkodOR;w1%(V1JPNv8mr^qF$3cIL2?ts=QrUGLa@~r?0M^E00000NkvXX Hu0mjfQBOp~ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/Background_128x64.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/Background_128x64.png new file mode 100644 index 0000000000000000000000000000000000000000..e3733663d8096e09d6b68c090e5bf5f5ed84dd51 GIT binary patch literal 10987 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 N002ovPDHLkV1i2UQGNgb literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/CommReturn_10x8.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/CommReturn_10x8.png new file mode 100644 index 0000000000000000000000000000000000000000..41d3033fa62269bf76ce4813bc2f108dcc451859 GIT binary patch literal 592 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 Y0}4Q}CaE?n0ssI207*qoM6N<$f^A4V!vFvP literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/LeftButtonBg_54x15.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/LeftButtonBg_54x15.png new file mode 100644 index 0000000000000000000000000000000000000000..725d02160afbb754fffebe45ab26579cffec0b89 GIT binary patch literal 5903 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/PulsemonLeftStand_14x16.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/PulsemonLeftStand_14x16.png new file mode 100644 index 0000000000000000000000000000000000000000..ea0bc9a3bcbfa4407fcd42d51ff8213f4ec38fb9 GIT binary patch literal 658 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 ArvLx| literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextCleared_47x6.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextCleared_47x6.png new file mode 100644 index 0000000000000000000000000000000000000000..04ff71e73f94e868724c96ec842be5742a4ddce8 GIT binary patch literal 638 zcmV-^0)hRBP)EX>4Tx04R}tkv&MmKpe$iQ>7vm2P=qn$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwdPj9^e=rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK8023?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6Gs$PqkJLj zvch?bvs$UK);;+PgL!Qw&2^e##Ib|~k`N)IhB7L!5T#Wk#YBqsV;=rt$DbsZOs+B* zITlcb3d!+<|H1EW&BD~An-q)z-7mKNF$x5Bfo9#dzmILZc>?&Kfh(=;uQq_$Ptxmc zEpi0(Zvz+CZB5<-E_Z;TCtWfmNAlAY3I*W(jJ_!c4BP^}Yi@6?eVjf38R}~J1~@nb z#)_1^?(y!P&ffk#)9UXBeEV{%Rd~Ka00009a7bBm000ie000ie0hKEb8vp)J*re$&6z!_N&0#poihqNod4*x+Up)NN=Z(K9 YoXyH(4w25`*8l(j07*qoM6N<$f+zG7!TEX>4Tx04R}tkv&MmKpe$iQ>7vm2P=qn$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwdPj9^e=rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK8023?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6Gs$PqkJLj zvch?bvs$UK);;+PgL!Qw&2^e##Ib|~k`N)IhB7L!5T#Wk#YBqsV;=rt$DbsZOs+B* zITlcb3d!+<|H1EW&BD~An-q)z-7mKNF$x5Bfo9#dzmILZc>?&Kfh(=;uQq_$Ptxmc zEpi0(Zvz+CZB5<-E_Z;TCtWfmNAlAY3I*W(jJ_!c4BP^}Yi@6?eVjf38R}~J1~@nb z#)_1^?(y!P&ffk#)9UXBeEV{%Rd~Ka00009a7bBm000ie000ie0hKEb8vpium-a3T z&db6@zrT$$pD2@8hJE*^Dn>+0AGZ>EX>4Tx04R}tkv&MmKpe$iQ>7vm2P=qn$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwdPj9^e=rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK8023?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6Gs$PqkJLj zvch?bvs$UK);;+PgL!Qw&2^e##Ib|~k`N)IhB7L!5T#Wk#YBqsV;=rt$DbsZOs+B* zITlcb3d!+<|H1EW&BD~An-q)z-7mKNF$x5Bfo9#dzmILZc>?&Kfh(=;uQq_$Ptxmc zEpi0(Zvz+CZB5<-E_Z;TCtWfmNAlAY3I*W(jJ_!c4BP^}Yi@6?eVjf38R}~J1~@nb z#)_1^?(y!P&ffk#)9UXBeEV{%Rd~Ka00009a7bBm000ie000ie0hKEb8vp{qZ&0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbN zY)M2xR5;7Ulfe$aAP7V0;{X3LJ1i`u0YrA#J83BfQ6M5J4%KH1Kv)Ox#*NI!M0%!m zSZwyibq`^mzkC+Uv?wRys)7K*?oEBC-fhRbo&4%M^^Obw6MGdu2Y$VH!1%vaLtAOP cf~NV#4Jouz3IMk!!~g&Q07*qoM6N<$f@1p;4gdfE literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextErrLoadCapture_65x13.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextErrLoadCapture_65x13.png new file mode 100644 index 0000000000000000000000000000000000000000..829a19d3c382cedd5dd79fa9e40b743f987e32bc GIT binary patch literal 713 zcmV;)0yh1LP)EX>4Tx04R}tkv&MmKpe$iQ>7vm2P=qn$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwdPj9^e=rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK8023?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6Gs$PqkJLj zvch?bvs$UK);;+PgL!Qw&2^e##Ib|~k`N)IhB7L!5T#Wk#YBqsV;=rt$DbsZOs+B* zITlcb3d!+<|H1EW&BD~An-q)z-7mKNF$x5Bfo9#dzmILZc>?&Kfh(=;uQq_$Ptxmc zEpi0(Zvz+CZB5<-E_Z;TCtWfmNAlAY3I*W(jJ_!c4BP^}Yi@6?eVjf38R}~J1~@nb z#)_1^?(y!P&ffk#)9UXBeEV{%Rd~Ka00009a7bBm000ie000ie0hKEb8vp(H?UXQxuN4VZwL#s?!YEX>4Tx04R}tkv&MmKpe$iQ>7vm2P=qn$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwdPj9^e=rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK8023?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6Gs$PqkJLj zvch?bvs$UK);;+PgL!Qw&2^e##Ib|~k`N)IhB7L!5T#Wk#YBqsV;=rt$DbsZOs+B* zITlcb3d!+<|H1EW&BD~An-q)z-7mKNF$x5Bfo9#dzmILZc>?&Kfh(=;uQq_$Ptxmc zEpi0(Zvz+CZB5<-E_Z;TCtWfmNAlAY3I*W(jJ_!c4BP^}Yi@6?eVjf38R}~J1~@nb z#)_1^?(y!P&ffk#)9UXBeEV{%Rd~Ka00009a7bBm000ie000ie0hKEb8vp*|%&5?Zw`V>NFELigqE!&60lVx!K4=Ag>1%OS0DC zPb&-|)r-Irq<;kZKGjFz)j3(4P&qx77rLpwYYW->YVsYbbC{4%E-Ygt*+qSqGnIz8 zp%bz;W=g_2U8hQPi9$ueT`tULX)MzPu0)qN4Za036EEs%U2_-IdB^1ep-1@lWa(Y> P00000NkvXXu0mjf@Gw0< literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextErrReadFailed_71x20.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextErrReadFailed_71x20.png new file mode 100644 index 0000000000000000000000000000000000000000..bf7c5ac26e87b219154a7f0dd94aab31aefff1d9 GIT binary patch literal 815 zcmV+~1JL}5P)EX>4Tx04R}tkv&MmKpe$iQ>7vm2P=qn$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwdPj9^e=rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK8023?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6Gs$PqkJLj zvch?bvs$UK);;+PgL!Qw&2^e##Ib|~k`N)IhB7L!5T#Wk#YBqsV;=rt$DbsZOs+B* zITlcb3d!+<|H1EW&BD~An-q)z-7mKNF$x5Bfo9#dzmILZc>?&Kfh(=;uQq_$Ptxmc zEpi0(Zvz+CZB5<-E_Z;TCtWfmNAlAY3I*W(jJ_!c4BP^}Yi@6?eVjf38R}~J1~@nb z#)_1^?(y!P&ffk#)9UXBeEV{%Rd~Ka00009a7bBm000ie000ie0hKEb8vpT=r(xKK`N)eG^S!=z&O|r?{ zV#CrDL;6jH{tgmo&{=z14xS7cj?7zqTtfZxerOm{rOoMHq7WEv{f{|^Yla!Q;>A^vb~Vr0GSKAeM!4uI{XG59 z4pYp?TFqrPL;7T9{GfzQWu9tZa$%2UN#7ZlDfhCcZ)A3U+6GgYNfghmJa_wyzdTF6 z%j_s-Aroea0X+iv#%3$foIE6hGX(8N4am-Q?qFSGQA%rj(hWO t!4{li_Js^=Oxm^G8F@fjx$r0q@dJJtvh2M&5y=1m002ovPDHLkV1k{RWjFu; literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextErrRegisterDifferentTag_47x20.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextErrRegisterDifferentTag_47x20.png new file mode 100644 index 0000000000000000000000000000000000000000..249ff39abe46608d8c98c8b938b63d4554a5727e GIT binary patch literal 765 zcmVEX>4Tx04R}tkv&MmKpe$iQ>7vm2P=qn$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwdPj9^e=rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK8023?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6Gs$PqkJLj zvch?bvs$UK);;+PgL!Qw&2^e##Ib|~k`N)IhB7L!5T#Wk#YBqsV;=rt$DbsZOs+B* zITlcb3d!+<|H1EW&BD~An-q)z-7mKNF$x5Bfo9#dzmILZc>?&Kfh(=;uQq_$Ptxmc zEpi0(Zvz+CZB5<-E_Z;TCtWfmNAlAY3I*W(jJ_!c4BP^}Yi@6?eVjf38R}~J1~@nb z#)_1^?(y!P&ffk#)9UXBeEV{%Rd~Ka00009a7bBm000ie000ie0hKEb8vpz^u2I({Q2`T<7X%Z?OPSVU|OpAR;QZ6_(AtdovOu5nt^|(%ntY$kNJH;M;>z z2B!sXtwbfM7CNs|8Ah(G!sVnaY4$ssT^6rv7`Y0WB1dbx2nU-(lp;Lxr6Og(E~Ql? z{B+6pWD@xEX>4Tx04R}tkv&MmKpe$iQ>7vm2P=qn$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwdPj9^e=rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK8023?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6Gs$PqkJLj zvch?bvs$UK);;+PgL!Qw&2^e##Ib|~k`N)IhB7L!5T#Wk#YBqsV;=rt$DbsZOs+B* zITlcb3d!+<|H1EW&BD~An-q)z-7mKNF$x5Bfo9#dzmILZc>?&Kfh(=;uQq_$Ptxmc zEpi0(Zvz+CZB5<-E_Z;TCtWfmNAlAY3I*W(jJ_!c4BP^}Yi@6?eVjf38R}~J1~@nb z#)_1^?(y!P&ffk#)9UXBeEV{%Rd~Ka00009a7bBm000ie000ie0hKEb8vpQl_72D~Mxw*3lIH=KJrFspDNf ztdewh!zD%{4t;&__U%v^Bw6)7d@0kmVrMFjn7(i6CK;#iIRRm55dD(K5)J?W002ov JPDHLkV1h}?J0}1D literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextRegister1_71x20.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextRegister1_71x20.png new file mode 100644 index 0000000000000000000000000000000000000000..f75495c7bc5814fe83340138b1aa793e7d2ab16a GIT binary patch literal 863 zcmV-l1EBngP)M)+0004mX+uL$Nkc;* zaB^>EX>4Tx04R}tkv&MmKpe$iQ?()$2aAYw$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwe07{aW?Og)ia%)oPe-NVP%yC~1{KKJM7SMnwUd?N82(+!JwgLr1s z(mC%FhgeBch|h_~4Z0xlBiCh@-#8Z?7I zj1?(+-Q(T8oxS~grq$mM#TIhN9=&x?00006VoOIv00000008+zyMF)x010qNS#tmY z4#WTe4#WYKD-Ig~000McNliru<_sJLD;FZzQw0D302y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00B2iL_t(o!|hl>4g?_xla2rXvU_r33}6d*nGCl@LGiX`e zr+U@Q7zS`2i0Pc~C| zXa%3hszp1XhFlG~%(RVChX?@dcG`EQ&??frqtiB%a3o2HUC;0a_9L?Y)3Axk+Pz{b pzePWKC8B;_Sp1J@4002ovPDHLkV1nX$d;M)+0004mX+uL$Nkc;* zaB^>EX>4Tx04R}tkv&MmKpe$iQ?()$2aAYw$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwe07{aW?Og)ia%)oPe-NVP%yC~1{KKJM7SMnwUd?N82(+!JwgLr1s z(mC%FhgeBch|h_~4Z0xlBiCh@-#8Z?7I zj1?(+-Q(T8oxS~grq$mM#TIhN9=&x?00006VoOIv0RI600RN!9r;`8x010qNS#tmY z4#WTe4#WYKD-Ig~000McNliru<_sJM1}()rx^Dmg02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00AgTL_t(o!|hn@4#OY_l*adeW%jGhLOi}y+ASqn);UzX z9UP8YYs}1zh?+EJzMhHb`Ye5spEeJzCD%jqDy)x!)dH}-M?MHNYhMlQGH|>mSvCsv z^jUR?5xX7PORGr}9O z&T0+3(Vj9!Xc}H#%pZqFq8cB24h^G4l8HVwPW*DHJI| z8HtTBXBMbgzrT?3UA<4=-O=v2CuwbgRj9SGSIVPO?rHtKsx@15EX>4Tx04R}tkv&MmKpe$iQ?()$2aAYw$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwe07{aW?Og)ia%)oPe-NVP%yC~1{KKJM7SMnwUd?N82(+!JwgLr1s z(mC%FhgeBch|h_~4Z0xlBiCh@-#8Z?7I zj1?(+-Q(T8oxS~grq$mM#TIhN9=&x?00006VoOIv0RI600RN!9r;`8x010qNS#tmY z4#WTe4#WYKD-Ig~000McNliru<_sJM6B0!4aYg_D02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00A{gL_t(o!|hnn4#OY_l*a%6W%p#`tQ?1Ew`?WpgNR5G z?`S2ZR7xqSiio5-7Lilm>PGghZEN5AsdK#_#+OHr;?X2)L1-_H1kE$Spk&rDqqls( zWV9#MXVfEg?PyaphkT(b8|fKam<&&led5}6yDDQ=@2!j@J#wuKtpY|_MgZuk1h4&W zUs9q`{90u&6zTyshTcX%jVPUAxo9hpJrs%@&jOycKLdO#S^*KcV#ds^LHOdO)CikJ zaVD?2Z=PmoWkOcQe4uRo9e^?=UiF$S3zW=BqIhQ3dHg-p+IFD*sn)TGygeEKjpjZ2 zc0VnSk9VL}Z_m=KrAPGmHSIWa-EX>4Tx04R}tkv&MmKpe$iQ>7vm2P=qn$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwdPj9^e=rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK8023?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6Gs$PqkJLj zvch?bvs$UK);;+PgL!Qw&2^e##Ib|~k`N)IhB7L!5T#Wk#YBqsV;=rt$DbsZOs+B* zITlcb3d!+<|H1EW&BD~An-q)z-7mKNF$x5Bfo9#dzmILZc>?&Kfh(=;uQq_$Ptxmc zEpi0(Zvz+CZB5<-E_Z;TCtWfmNAlAY3I*W(jJ_!c4BP^}Yi@6?eVjf38R}~J1~@nb z#)_1^?(y!P&ffk#)9UXBeEV{%Rd~Ka00009a7bBm000ie000ie0hKEb8vpWNGL0EqhbLy#7^ep-^Vy#f1)W!>eY(Nq8c002ov JPDHLkV1led48Z^Z literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextTapApp_56x27.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextTapApp_56x27.png new file mode 100644 index 0000000000000000000000000000000000000000..7bede36c22f221bc3f97c371b5ee66f0417f5788 GIT binary patch literal 856 zcmV-e1E>6nP)EX>4Tx04R}tkv&MmKpe$iQ?()$2aAYw$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwe07{aW?Og)ia%)oPe-NVP%yC~1{KKJM7SMnwUd?N82(+!JwgLr1s z(mC%FhgeBch|h_~4Z0xlBiCh@-#8Z?7I zj1?(+-Q(T8oxS~grq$mM#TIhN9=&x?00006VoOIv0RI600RN!9r;`8x010qNS#tmY z4#WTe4#WYKD-Ig~000McNliru<_sJM3n6(VhzS4y02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00A&bL_t(o!{u1Z62l+}gpU9J%l42-$6*9nq-q;Zl~|NV zST;;Vm4wuKshHW+wfa_ido*49|9g#|(cVqkE7n78?cJvZPF}R9N6u*1@>wB6WF)QV zY1xt&k-Ab{kfEEgI0q;N;~=*$UR)MivLjI%UQft zYmFfaEn7;|+x};vWt)RY=bV9-uR7S`hKy_^>Yk>uGJ{)Tf|)--(0-?ss5VWE$_gpF zT_ySqm>A7-7Ib(9;Y_xI+Edwtr->j8B8#n{_Fy)V$p}_JiVNsH2Syk{l&$;>OdQE3 zkSTwqXbj_dFkykd#WE26N_J5q2cYd8{iu}gV6XK@-b3VL)2h*JI)hRDstg_l6PYYx i2osqlw2Mg)5xoJJe6ao-ZtFDw0000`>& literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextTransferCaptured_97x13.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextTransferCaptured_97x13.png new file mode 100644 index 0000000000000000000000000000000000000000..7ca7f666113916aba34f85daaa88c18e5a724a39 GIT binary patch literal 801 zcmV++1K#|JP)EX>4Tx04R}tkv&MmKpe$iQ>7vm2P=qn$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwdPj9^e=rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK8023?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6Gs$PqkJLj zvch?bvs$UK);;+PgL!Qw&2^e##Ib|~k`N)IhB7L!5T#Wk#YBqsV;=rt$DbsZOs+B* zITlcb3d!+<|H1EW&BD~An-q)z-7mKNF$x5Bfo9#dzmILZc>?&Kfh(=;uQq_$Ptxmc zEpi0(Zvz+CZB5<-E_Z;TCtWfmNAlAY3I*W(jJ_!c4BP^}Yi@6?eVjf38R}~J1~@nb z#)_1^?(y!P&ffk#)9UXBeEV{%Rd~Ka00009a7bBm000ie000ie0hKEb8vp;Ao>v>YIF%w zVWY~?m0;;XWuAiwV-dfy$oLhZu4Xz*zf8p-RWy^3mB7#X72zr$gIE2h+Db$*6ILpu z1p^tZE3G1GcX#`O>K`ox-Q486t^Om;hHH1bknfG2TBgtBHy-0gdQSl}Khut8lM@YK zWQ9al#*}it8o<_~pEhkDuc7Ojo6HZ97o;UjWvrLeG)lcEX>4Tx04R}tkv&MmKpe$iQ>7vm2P=qn$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwdPj9^e=rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK8023?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6Gs$PqkJLj zvch?bvs$UK);;+PgL!Qw&2^e##Ib|~k`N)IhB7L!5T#Wk#YBqsV;=rt$DbsZOs+B* zITlcb3d!+<|H1EW&BD~An-q)z-7mKNF$x5Bfo9#dzmILZc>?&Kfh(=;uQq_$Ptxmc zEpi0(Zvz+CZB5<-E_Z;TCtWfmNAlAY3I*W(jJ_!c4BP^}Yi@6?eVjf38R}~J1~@nb z#)_1^?(y!P&ffk#)9UXBeEV{%Rd~Ka00009a7bBm000ie000ie0hKEb8vp$Jy|0=1bHBeQ zB45w?HU0BU+lda-nlsGdfSp~5VnA~7Oyy#hU-*&Mxn+o*^cvzUXD(fdY< zLF|kAS^Ksqf>n^bV}}696gXnv$j<}zq8lv(z-eo!VXg$AXGfO)6`zXrd$2tDwcThJ zGgJT5=;{98H7(Cy$MV)j{Er@`NCQLPE)n^yN^!QKE@jLr+4WSyVjNctui>S>IoyJ-g(MP)Ag!^GmJSsgkG!V_Na1fkm;Z4de>X1 f#2+>N6G!X?`hsywvOoJ%00000NkvXXu0mjf-S2%z literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextTransferSecondDimCheck_71x20.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextTransferSecondDimCheck_71x20.png new file mode 100644 index 0000000000000000000000000000000000000000..5f569b5e25ed2358213060c04d3f5c4ec54147e9 GIT binary patch literal 849 zcmV-X1FrmuP)EX>4Tx04R}tkv&MmKpe$iQ>7vm2P=qn$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwdPj9^e=rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK8023?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6Gs$PqkJLj zvch?bvs$UK);;+PgL!Qw&2^e##Ib|~k`N)IhB7L!5T#Wk#YBqsV;=rt$DbsZOs+B* zITlcb3d!+<|H1EW&BD~An-q)z-7mKNF$x5Bfo9#dzmILZc>?&Kfh(=;uQq_$Ptxmc zEpi0(Zvz+CZB5<-E_Z;TCtWfmNAlAY3I*W(jJ_!c4BP^}Yi@6?eVjf38R}~J1~@nb z#)_1^?(y!P&ffk#)9UXBeEV{%Rd~Ka00009a7bBm000ie000ie0hKEb8vpXqY`9{D?v)*9GM zqpI!_*MW5jJdUcVODFuDeBCQrBNNRla%>%z{>E3Z b|0t>-%^aaB;BO9I00000NkvXXu0mjf*1~y6 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextTransfersDone_51x13.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/TextTransfersDone_51x13.png new file mode 100644 index 0000000000000000000000000000000000000000..1394cfc32395095ec887ded3040d570b2d0c63ea GIT binary patch literal 710 zcmV;%0y+JOP)EX>4Tx04R}tkv&MmKpe$iQ>7vm2P=qn$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o+5kwdPj9^e=rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK8023?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6Gs$PqkJLj zvch?bvs$UK);;+PgL!Qw&2^e##Ib|~k`N)IhB7L!5T#Wk#YBqsV;=rt$DbsZOs+B* zITlcb3d!+<|H1EW&BD~An-q)z-7mKNF$x5Bfo9#dzmILZc>?&Kfh(=;uQq_$Ptxmc zEpi0(Zvz+CZB5<-E_Z;TCtWfmNAlAY3I*W(jJ_!c4BP^}Yi@6?eVjf38R}~J1~@nb z#)_1^?(y!P&ffk#)9UXBeEV{%Rd~Ka00009a7bBm000ie000ie0hKEb8vpA`-AhqgbD$T5RmUn$qN9+#@@z(sQ1xIgZ=d9YVEV!~ltK<0gP53>IZ2PYb sU}V9MQD&y$?aEaDup@PR{%!*}0W+=C@ZOLbE&u=k07*qoM6N<$f`A}2-v9sr literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/WrongDevice_32x27.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/icons/WrongDevice_32x27.png new file mode 100644 index 0000000000000000000000000000000000000000..12ce0859486bf6fbcbb33932f267e85234fc0395 GIT binary patch literal 796 zcmV+%1LOROP)EX>4Tx04R}tkv&MmKpe$i(~2S$2P=ql$WWauh!t^^Di*;)X)CnqU~=gfG-*gu zTpR`0f`cE6RR0!X5l%$?&0I>U6f~epZjwRC4rtTK|Hf* z>74h8L#!+*#OK5l23?T&k?XR{Z=6dG3p_JqWYhD+A!4!A#c~(3vY`@B6Gs$PqkJLf zvch?bvs$gQ_C5Ivg9U9R!*!ZrB(Q`eQV=1djtZ)<5T#Wk#YCF+;~xG|$DbmXOs)zT zITlcZ3d!+<|H1EW&0=iIO$x?=o)_Ex7z28DfmXw|zmILZbprUGfh(=!uQh?$PtqG5 zEph}5ZUYzB9ZlW?E_Z;DCtWfmNAlAYibdf4jJ_!k4BZ0#Yi@7teVjf3S?X%}1~@nb z#!HmF?(y!v?%w`A)9&vFu_SW9l0g*)00009a7bBm000ie000ie0hKEb8vppREju<3WK?~8Ah`{ROlN#0flnE^9Wva?rh0)#%TX41!$_15 z`%ETi)!{ue|I`lgpz)efr`2YS=&u=Njm6sE2F_. + +#include "vb_migrate_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const vb_migrate_on_enter_handlers[])(void*) = { +#include "vb_migrate_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 vb_migrate_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "vb_migrate_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 vb_migrate_on_exit_handlers[])(void* context) = { +#include "vb_migrate_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers vb_migrate_scene_handlers = { + .on_enter_handlers = vb_migrate_on_enter_handlers, + .on_event_handlers = vb_migrate_on_event_handlers, + .on_exit_handlers = vb_migrate_on_exit_handlers, + .scene_num = VbMigrateSceneNum, +}; diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene.h new file mode 100644 index 000000000..7187bdf0b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene.h @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) VbMigrateScene##id, +typedef enum { +#include "vb_migrate_scene_config.h" + VbMigrateSceneNum, +} VbMigrateScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers vb_migrate_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "vb_migrate_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 "vb_migrate_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 "vb_migrate_scene_config.h" +#undef ADD_SCENE diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_about.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_about.c new file mode 100644 index 000000000..fbd880dda --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_about.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "../vb_migrate_i.h" + +void vb_migrate_scene_about_on_enter(void* context) { + VbMigrate* inst = context; + + // Perform your setup here + FuriString* temp_str = furi_string_alloc_printf( + "\e#Information\n" + "Version: %s\n" + "Developed by: cyanic\n" + "Graphics by: Aderek\n" + "GitHub: https://github.com/GMMan/flipperzero-vb-migrate\n" + "\n" + "\e#Description\n" + "Makes transferring\n" + "characters with VB Lab/\n" + "Arena less cumbersome", + VB_MIGRATE_VERSION); + + Widget* widget = inst->widget; + vb_migrate_add_bg(widget, VbMigrateBgTypeNone); + widget_add_text_scroll_element(widget, 8, 16, 113, 33, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); +} + +bool vb_migrate_scene_about_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + return false; +} + +void vb_migrate_scene_about_on_exit(void* context) { + VbMigrate* inst = context; + + // Perform your cleanup here + widget_reset(inst->widget); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_config.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_config.h new file mode 100644 index 000000000..f090de9df --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_config.h @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +ADD_SCENE(vb_migrate, main_menu, MainMenu) +ADD_SCENE(vb_migrate, register, Register) +ADD_SCENE(vb_migrate, register_save, RegisterSave) +ADD_SCENE(vb_migrate, save_success, SaveSuccess) +ADD_SCENE(vb_migrate, select, Select) +ADD_SCENE(vb_migrate, load, Load) +ADD_SCENE(vb_migrate, info, Info) +ADD_SCENE(vb_migrate, dev_menu, DevMenu) +ADD_SCENE(vb_migrate, delete, Delete) +ADD_SCENE(vb_migrate, delete_success, DeleteSuccess) +ADD_SCENE(vb_migrate, from_app, FromApp) +ADD_SCENE(vb_migrate, to_app, ToApp) +ADD_SCENE(vb_migrate, delete_captures, DeleteCaptures) +ADD_SCENE(vb_migrate, delete_captures_success, DeleteCapturesSuccess) +ADD_SCENE(vb_migrate, about, About) diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_delete.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_delete.c new file mode 100644 index 000000000..c197cf1b8 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_delete.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "../vb_migrate_i.h" +#include "../vb_tag.h" + +static void + vb_migrate_scene_delete_widget_callback(GuiButtonType result, InputType type, void* context) { + VbMigrate* inst = context; + + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(inst->view_dispatcher, result); + } +} + +void vb_migrate_scene_delete_on_enter(void* context) { + VbMigrate* inst = context; + + // Perform your setup here + Widget* widget = inst->widget; + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton | VbMigrateBgTypeRightButton); + widget_add_icon_element(widget, 11, 18, &I_Delete_32x20); + widget_add_icon_element(widget, 48, 18, &I_TextDeleteVb_49x13); + + FuriString* temp_str = furi_string_alloc_printf("%d", inst->num_captured); + widget_add_string_element( + widget, 99, 24, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); + + widget_add_button_element( + inst->widget, GuiButtonTypeLeft, "Cancel", vb_migrate_scene_delete_widget_callback, inst); + widget_add_button_element( + inst->widget, GuiButtonTypeRight, "Delete", vb_migrate_scene_delete_widget_callback, inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); +} + +bool vb_migrate_scene_delete_on_event(void* context, SceneManagerEvent event) { + VbMigrate* inst = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GuiButtonTypeLeft) { + consumed = scene_manager_previous_scene(inst->scene_manager); + } else if(event.event == GuiButtonTypeRight) { + if(vb_migrate_delete(inst, inst->text_store, true)) { + scene_manager_next_scene(inst->scene_manager, VbMigrateSceneDeleteSuccess); + consumed = true; + } else { + consumed = scene_manager_search_and_switch_to_previous_scene( + inst->scene_manager, VbMigrateSceneSelect); + } + } + } + return consumed; +} + +void vb_migrate_scene_delete_on_exit(void* context) { + VbMigrate* inst = context; + + // Perform your cleanup here + widget_reset(inst->widget); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_delete_captures.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_delete_captures.c new file mode 100644 index 000000000..997141690 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_delete_captures.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "../vb_migrate_i.h" + +static void vb_migrate_scene_delete_captures_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + VbMigrate* inst = context; + + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(inst->view_dispatcher, result); + } +} + +void vb_migrate_scene_delete_captures_on_enter(void* context) { + VbMigrate* inst = context; + + // Perform your setup here + Widget* widget = inst->widget; + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton | VbMigrateBgTypeRightButton); + widget_add_icon_element(widget, 11, 18, &I_Delete_32x20); + widget_add_icon_element(widget, 48, 18, &I_TextClearCaptures_49x13); + + FuriString* temp_str = furi_string_alloc_printf("%d", inst->num_captured); + widget_add_string_element( + widget, 99, 24, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); + + widget_add_button_element( + inst->widget, + GuiButtonTypeLeft, + "Cancel", + vb_migrate_scene_delete_captures_widget_callback, + inst); + widget_add_button_element( + inst->widget, + GuiButtonTypeRight, + "Delete", + vb_migrate_scene_delete_captures_widget_callback, + inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); +} + +bool vb_migrate_scene_delete_captures_on_event(void* context, SceneManagerEvent event) { + VbMigrate* inst = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GuiButtonTypeLeft) { + consumed = scene_manager_previous_scene(inst->scene_manager); + } else if(event.event == GuiButtonTypeRight) { + if(vb_migrate_delete(inst, inst->text_store, false)) { + scene_manager_next_scene(inst->scene_manager, VbMigrateSceneDeleteCapturesSuccess); + consumed = true; + } else { + consumed = scene_manager_previous_scene(inst->scene_manager); + } + inst->num_captured = vb_migrate_count_captured_mons(inst, inst->text_store); + } + } + return consumed; +} + +void vb_migrate_scene_delete_captures_on_exit(void* context) { + VbMigrate* inst = context; + + // Perform your cleanup here + widget_reset(inst->widget); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_delete_captures_success.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_delete_captures_success.c new file mode 100644 index 000000000..0e52d4e9e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_delete_captures_success.c @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "../vb_migrate_i.h" + +static void vb_migrate_scene_delete_captures_success_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + VbMigrate* inst = context; + + if(type == InputTypeShort) { + if(result == GuiButtonTypeRight) + view_dispatcher_send_custom_event(inst->view_dispatcher, 0); + } +} + +void vb_migrate_scene_delete_captures_success_on_enter(void* context) { + VbMigrate* inst = context; + + // Perform your setup here + Widget* widget = inst->widget; + vb_migrate_add_bg(widget, VbMigrateBgTypeRightButton); + widget_add_icon_element(widget, 11, 18, &I_Delete_32x20); + widget_add_icon_element(widget, 48, 18, &I_TextCleared_47x6); + widget_add_icon_element(widget, 9, 41, &I_PulsemonRightSad_15x15); + widget_add_button_element( + widget, + GuiButtonTypeRight, + "OK", + vb_migrate_scene_delete_captures_success_widget_callback, + inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); +} + +bool vb_migrate_scene_delete_captures_success_on_event(void* context, SceneManagerEvent event) { + VbMigrate* inst = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom || event.type == SceneManagerEventTypeBack) { + consumed = scene_manager_search_and_switch_to_previous_scene( + inst->scene_manager, VbMigrateSceneDevMenu); + } + return consumed; +} + +void vb_migrate_scene_delete_captures_success_on_exit(void* context) { + VbMigrate* inst = context; + + // Perform your cleanup here + widget_reset(inst->widget); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_delete_success.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_delete_success.c new file mode 100644 index 000000000..863afc777 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_delete_success.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "../vb_migrate_i.h" + +static void vb_migrate_scene_delete_success_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + VbMigrate* inst = context; + if(type == InputTypeShort) { + if(result == GuiButtonTypeRight) + + view_dispatcher_send_custom_event(inst->view_dispatcher, 0); + } +} + +void vb_migrate_scene_delete_success_on_enter(void* context) { + VbMigrate* inst = context; + + // Perform your setup here + Widget* widget = inst->widget; + vb_migrate_add_bg(widget, VbMigrateBgTypeRightButton); + widget_add_icon_element(widget, 11, 18, &I_Delete_32x20); + widget_add_icon_element(widget, 48, 18, &I_TextDeleted_46x6); + widget_add_icon_element(widget, 9, 41, &I_PulsemonRightSad_15x15); + widget_add_button_element( + widget, GuiButtonTypeRight, "OK", vb_migrate_scene_delete_success_widget_callback, inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); +} + +bool vb_migrate_scene_delete_success_on_event(void* context, SceneManagerEvent event) { + VbMigrate* inst = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom || event.type == SceneManagerEventTypeBack) { + uint32_t back_scenes[] = {VbMigrateSceneSelect, VbMigrateSceneMainMenu}; + consumed = scene_manager_search_and_switch_to_previous_scene_one_of( + inst->scene_manager, back_scenes, COUNT_OF(back_scenes)); + } + return consumed; +} + +void vb_migrate_scene_delete_success_on_exit(void* context) { + VbMigrate* inst = context; + + // Perform your cleanup here + widget_reset(inst->widget); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_dev_menu.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_dev_menu.c new file mode 100644 index 000000000..08f82d8ee --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_dev_menu.c @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "../vb_migrate_i.h" + +typedef enum { + SubmenuDevMenuIndexTransferFromApp, + SubmenuDevMenuIndexTransferToApp, + SubmenuDevMenuClearAccountId, + SubmenuDevMenuIndexSpoof, + SubmenuDevMenuIndexClearCaptures, + SubmenuDevMenuIndexDeleteVb, + // ----- + SubmenuDevMenuClearAccountIdOff, + SubmenuDevMenuClearAccountIdOn, + // ----- + SubmenuDevMenuIndexSpoofSelection, // Always keep this last because we add tag type to it +} SubmenuDevMenuIndex; + +static void vb_migrate_scene_dev_menu_var_list_enter_callback(void* context, uint32_t index) { + VbMigrate* inst = context; + + view_dispatcher_send_custom_event(inst->view_dispatcher, index); +} + +static VbTagType + vb_migrate_scene_dev_menu_spoof_set_item_by_index(VariableItemEx* item, uint8_t index) { + VbTagType type; + if(index >= 2) { // VBC + type = (VbTagType)(index + 2); + } else { + type = (VbTagType)(index + 1); + } + + variable_item_ex_set_current_value_index(item, index); + variable_item_ex_set_current_value_text(item, vb_tag_get_tag_type_name(type)); + return type; +} + +static uint8_t + vb_migrate_scene_dev_menu_spoof_set_item_by_type(VariableItemEx* item, VbTagType type) { + uint8_t index; + if(type >= VbTagTypeVH) { + index = (uint8_t)type - 2; + } else { + index = (uint8_t)type - 1; + } + + variable_item_ex_set_current_value_index(item, index); + variable_item_ex_set_current_value_text(item, vb_tag_get_tag_type_name(type)); + return index; +} + +static void vb_migrate_scene_dev_menu_spoof_change_callback(VariableItemEx* item) { + VbMigrate* inst = variable_item_ex_get_context(item); + uint8_t index = variable_item_ex_get_current_value_index(item); + + VbTagType tag_type = vb_migrate_scene_dev_menu_spoof_set_item_by_index(item, index); + view_dispatcher_send_custom_event( + inst->view_dispatcher, SubmenuDevMenuIndexSpoofSelection + tag_type); +} + +static void vb_migrate_scene_dev_menu_clear_account_id_change_callback(VariableItemEx* item) { + VbMigrate* inst = variable_item_ex_get_context(item); + uint8_t index = variable_item_ex_get_current_value_index(item); + + variable_item_ex_set_current_value_text(item, index ? "On" : "Off"); + view_dispatcher_send_custom_event( + inst->view_dispatcher, + index ? SubmenuDevMenuClearAccountIdOn : SubmenuDevMenuClearAccountIdOff); +} + +void vb_migrate_scene_dev_menu_on_enter(void* context) { + VbMigrate* inst = context; + VariableItemListEx* variable_list = inst->variable_list; + VariableItemEx* item; + + variable_item_list_ex_set_enter_callback( + variable_list, vb_migrate_scene_dev_menu_var_list_enter_callback, inst); + variable_item_list_ex_add( + variable_list, "Transfer App > Flipper", 0, NULL, NULL, SubmenuDevMenuIndexTransferFromApp); + + if(inst->num_captured != 0) { + variable_item_list_ex_add( + variable_list, + "Transfer Flipper > App", + 0, + NULL, + NULL, + SubmenuDevMenuIndexTransferToApp); + } + + item = variable_item_list_ex_add( + variable_list, + "Unlink Account", + 2, + vb_migrate_scene_dev_menu_clear_account_id_change_callback, + inst, + SubmenuDevMenuClearAccountId); + variable_item_ex_set_current_value_index(item, inst->clear_account_id ? 1 : 0); + variable_item_ex_set_current_value_text(item, inst->clear_account_id ? "On" : "Off"); + + if(inst->orig_type == VbTagTypeVBDM || inst->orig_type == VbTagTypeVBV || + inst->orig_type == VbTagTypeVH) { + item = variable_item_list_ex_add( + variable_list, + "Spoof Version", + VbTagTypeMax - 1 - 2, // Removing VBC from list, skip VBBE + vb_migrate_scene_dev_menu_spoof_change_callback, + inst, + SubmenuDevMenuIndexSpoof); + vb_migrate_scene_dev_menu_spoof_set_item_by_type(item, inst->override_type); + } + + if(inst->num_captured != 0) { + variable_item_list_ex_add( + variable_list, "Clear Captures", 0, NULL, NULL, SubmenuDevMenuIndexClearCaptures); + } + + variable_item_list_ex_add( + variable_list, "Delete Vital Bracelet", 0, NULL, NULL, SubmenuDevMenuIndexDeleteVb); + + // variable_item_list_ex_set_selected_item( + // variable_list, scene_manager_get_scene_state(inst->scene_manager, VbMigrateSceneDevMenu)); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewVariableItemList); +} + +bool vb_migrate_scene_dev_menu_on_event(void* context, SceneManagerEvent event) { + VbMigrate* inst = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + // if(event.event < SubmenuDevMenuIndexSpoofSelection) { + // scene_manager_set_scene_state(inst->scene_manager, VbMigrateSceneDevMenu, event.event); + // } + + if(event.event == SubmenuDevMenuIndexTransferFromApp) { + scene_manager_next_scene(inst->scene_manager, VbMigrateSceneFromApp); + consumed = true; + } else if(event.event == SubmenuDevMenuIndexTransferToApp) { + scene_manager_next_scene(inst->scene_manager, VbMigrateSceneToApp); + consumed = true; + } else if(event.event == SubmenuDevMenuIndexClearCaptures) { + scene_manager_next_scene(inst->scene_manager, VbMigrateSceneDeleteCaptures); + consumed = true; + } else if(event.event == SubmenuDevMenuIndexDeleteVb) { + scene_manager_next_scene(inst->scene_manager, VbMigrateSceneDelete); + consumed = true; + } else if(event.event == SubmenuDevMenuClearAccountIdOff) { + inst->clear_account_id = false; + consumed = true; + } else if(event.event == SubmenuDevMenuClearAccountIdOn) { + inst->clear_account_id = true; + consumed = true; + } else if(event.event >= SubmenuDevMenuIndexSpoofSelection) { + // Note: skipping SubmenuDevMenuIndexSpoof because there's nothing to do on enter + inst->override_type = event.event - SubmenuDevMenuIndexSpoofSelection; + consumed = true; + } + } + return consumed; +} + +void vb_migrate_scene_dev_menu_on_exit(void* context) { + VbMigrate* inst = context; + + variable_item_list_ex_reset(inst->variable_list); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_from_app.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_from_app.c new file mode 100644 index 000000000..7b4eaa012 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_from_app.c @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include + +#include "../vb_migrate_i.h" +#include "../vb_tag.h" + +#define TAG "vb_migrate_scene_from_app" + +typedef enum { + FromAppStateInitial, + FromAppStateInstructions, + FromAppStateEmulateReady, + FromAppStateEmulateCheckDim, + FromAppStateEmulateTransferFromApp, + FromAppStateTemplateError, + FromAppStateSaveError, +} FromAppState; + +typedef enum { + FromAppEventTypeWidgetLeft, + FromAppEventTypeWidgetRight, + FromAppEventTypeTemplateLoadError, + FromAppEventTypeTagWrite, + FromAppEventTypeCaptureSaveError, + FromAppEventTypeCaptureSaveSuccess, +} FromAppEventType; + +static void + vb_migrate_scene_from_app_widget_callback(GuiButtonType result, InputType type, void* context) { + VbMigrate* inst = context; + + if(type == InputTypeShort) { + if(result == GuiButtonTypeLeft) + view_dispatcher_send_custom_event(inst->view_dispatcher, FromAppEventTypeWidgetLeft); + else if(result == GuiButtonTypeRight) + view_dispatcher_send_custom_event(inst->view_dispatcher, FromAppEventTypeWidgetRight); + } +} + +static bool vb_migrate_scene_from_app_worker_callback(NfcWorkerEvent event, void* context) { + VbMigrate* inst = context; + bool result = false; + + if(event == NfcWorkerEventSuccess) { + view_dispatcher_send_custom_event(inst->view_dispatcher, FromAppEventTypeTagWrite); + result = true; + } + + return result; +} + +static void vb_migrate_scene_from_app_set_nfc_state(VbMigrate* inst, FromAppState state) { + BantBlock* bant = vb_tag_get_bant_block(&inst->nfc_dev->dev_data); + if(state == FromAppStateEmulateReady) { + vb_tag_set_random_nonce(bant); + vb_tag_set_status(bant, VbTagStatusReady); + vb_tag_set_operation(bant, VbTagOperationReady); + } else if(state == FromAppStateEmulateCheckDim) { + vb_tag_set_status(bant, VbTagStatusReady | VbTagStatusDimReady); + vb_tag_set_operation(bant, VbTagOperationReady); + } else if(state == FromAppStateEmulateTransferFromApp) { + vb_tag_set_status(bant, 0); + vb_tag_set_operation(bant, VbTagOperationIdle); + } + + // Override tag type + if(inst->override_type != inst->orig_type && inst->override_type != VbTagTypeUnknown) { + vb_tag_set_item_id_no(bant, vb_tag_get_default_product(inst->override_type)); + } + + if(inst->clear_account_id) { + vb_tag_set_app_flag(bant, false); + } +} + +static bool vb_migrate_scene_from_app_is_state_changed(VbMigrate* inst, FromAppState state) { + BantBlock* bant = vb_tag_get_bant_block(&inst->nfc_dev->dev_data); + VbTagOperation operation = vb_tag_get_operation(bant); + + if(state == FromAppStateEmulateReady) { + return operation == VbTagOperationCheckDim; + } else if(state == FromAppStateEmulateCheckDim) { + return operation == VbTagOperationCheckDim || operation == VbTagOperationReturnFromApp; + } + + return false; +} + +static void vb_migrate_scene_from_app_set_state(VbMigrate* inst, FromAppState state) { + uint32_t curr_state = + scene_manager_get_scene_state(inst->scene_manager, VbMigrateSceneFromApp); + if(state != curr_state) { + Widget* widget = inst->widget; + + if(state == FromAppStateInstructions) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton | VbMigrateBgTypeRightButton); + widget_add_text_scroll_element( + widget, + 8, + 16, + 113, + 33, + "\e#To transfer\n" + "\e#characters to Flipper:\n" + "0. If on VB Arena, select\n" + "the device type that\n" + "matches your current\n" + "settings\n" + "1. If on VB Lab, wake up\n" + "character from storage\n" + "2. Sync character to\n" + "Flipper as if it was a\n" + "Vital Bracelet. Flipper\n" + "will beep when it is\n" + "ready for the next step\n" + "3. The character is\n" + "automatically saved when\n" + "the transfer is complete,\n" + "and will be ready for\n" + "another transfer\n" + "4. Repeat the above until\n" + "you have transferred all\n" + "the characters you want\n" + "\n" + "You can cancel at any\n" + "time to finish transferring."); + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Cancel", + vb_migrate_scene_from_app_widget_callback, + inst); + widget_add_button_element( + widget, + GuiButtonTypeRight, + "Next", + vb_migrate_scene_from_app_widget_callback, + inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + } else if(state == FromAppStateEmulateReady) { + vb_migrate_show_loading_popup(inst, true); + if(vb_migrate_load_nfc(inst, inst->text_store, VB_MIGRATE_TEMPLATE_NAME)) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton); + widget_add_icon_element(widget, 11, 18, &I_CommReady_32x27); + widget_add_icon_element(widget, 48, 18, &I_TextTransferDimCheck_70x20); + FuriString* temp_str = furi_string_alloc_printf("%d", inst->num_captured); + widget_add_string_element( + widget, + 100, + 31, + AlignLeft, + AlignTop, + FontSecondary, + furi_string_get_cstr(temp_str)); + widget_add_icon_element(widget, 106, 40, &I_PulsemonRightWaiting_15x16); + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Cancel", + vb_migrate_scene_from_app_widget_callback, + inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + furi_string_free(temp_str); + + vb_migrate_scene_from_app_set_nfc_state(inst, state); + nfc_worker_start( + inst->worker, + NfcWorkerStateMfUltralightEmulate, + &inst->nfc_dev->dev_data, + vb_migrate_scene_from_app_worker_callback, + inst); + vb_migrate_blink_emulate(inst); + } else { + view_dispatcher_send_custom_event( + inst->view_dispatcher, FromAppEventTypeTemplateLoadError); + } + vb_migrate_show_loading_popup(inst, false); + } else if(state == FromAppStateEmulateCheckDim) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton); + widget_add_icon_element(widget, 11, 18, &I_CommReady_32x27); + widget_add_icon_element(widget, 48, 18, &I_TextTransferSecondDimCheck_71x20); + widget_add_icon_element(widget, 106, 40, &I_PulsemonRightWaiting_15x16); + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Cancel", + vb_migrate_scene_from_app_widget_callback, + inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + notification_message(inst->notifications, &sequence_success); + vb_migrate_scene_from_app_set_nfc_state(inst, state); + nfc_worker_start( + inst->worker, + NfcWorkerStateMfUltralightEmulate, + &inst->nfc_dev->dev_data, + vb_migrate_scene_from_app_worker_callback, + inst); + vb_migrate_blink_emulate(inst); + } else if(state == FromAppStateEmulateTransferFromApp) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton); + widget_add_icon_element(widget, 15, 18, &I_TextTransferCaptured_97x13); + widget_add_icon_element(widget, 106, 40, &I_PulsemonRightWaiting_15x16); + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Cancel", + vb_migrate_scene_from_app_widget_callback, + inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + nfc_worker_stop(inst->worker); + vb_migrate_blink_stop(inst); + vb_migrate_scene_from_app_set_nfc_state(inst, state); + notification_message(inst->notifications, &sequence_success); + + // Restore original tag type if necessary + if(inst->override_type != inst->orig_type && inst->override_type != VbTagTypeUnknown) { + BantBlock* bant = vb_tag_get_bant_block(&inst->nfc_dev->dev_data); + vb_tag_set_item_id_no(bant, inst->orig_product); + } + + // Save the tag + inst->next_id = vb_migrate_get_next_id(inst, inst->text_store, inst->next_id, false); + FuriString* save_path = furi_string_alloc_printf( + VB_MIGRATE_CAPTURE_FORMAT, inst->next_id, NFC_APP_EXTENSION); + if(vb_migrate_save_nfc(inst, inst->text_store, furi_string_get_cstr(save_path))) { + view_dispatcher_send_custom_event( + inst->view_dispatcher, FromAppEventTypeCaptureSaveSuccess); + } else { + view_dispatcher_send_custom_event( + inst->view_dispatcher, FromAppEventTypeCaptureSaveError); + } + furi_string_free(save_path); + } else if(state == FromAppStateTemplateError) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton); + widget_add_icon_element(widget, 11, 18, &I_WrongDevice_32x27); + widget_add_icon_element(widget, 48, 18, &I_TextErrLoadTemplate_69x13); + widget_add_icon_element(widget, 104, 41, &I_PulsemonLeftWait_15x15); + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Cancel", + vb_migrate_scene_from_app_widget_callback, + inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + notification_message(inst->notifications, &sequence_error); + notification_message(inst->notifications, &sequence_set_red_255); + } else if(state == FromAppStateSaveError) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton); + widget_add_icon_element(widget, 11, 18, &I_WrongDevice_32x27); + widget_add_icon_element(widget, 48, 18, &I_TextErrSaveCapture_65x13); + widget_add_icon_element(widget, 104, 41, &I_PulsemonLeftWait_15x15); + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Cancel", + vb_migrate_scene_from_app_widget_callback, + inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + notification_message(inst->notifications, &sequence_error); + notification_message(inst->notifications, &sequence_set_red_255); + } else { + furi_crash("Unknown new state in vb_migrate_scene_from_app_set_state"); + } + + scene_manager_set_scene_state(inst->scene_manager, VbMigrateSceneFromApp, state); + } +} + +void vb_migrate_scene_from_app_on_enter(void* context) { + VbMigrate* inst = context; + + // Perform your setup here + inst->next_id = 0; + scene_manager_set_scene_state(inst->scene_manager, VbMigrateSceneFromApp, FromAppStateInitial); + vb_migrate_scene_from_app_set_state(inst, FromAppStateInstructions); +} + +bool vb_migrate_scene_from_app_on_event(void* context, SceneManagerEvent event) { + VbMigrate* inst = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == FromAppEventTypeWidgetLeft) { + consumed = scene_manager_previous_scene(inst->scene_manager); + } else if(event.event == FromAppEventTypeWidgetRight) { + vb_migrate_scene_from_app_set_state(inst, FromAppStateEmulateReady); + consumed = true; + } else if(event.event == FromAppEventTypeTagWrite) { + uint32_t state = + scene_manager_get_scene_state(inst->scene_manager, VbMigrateSceneFromApp); + if(vb_migrate_scene_from_app_is_state_changed(inst, state)) { + if(state == FromAppStateEmulateReady) { + nfc_worker_stop(inst->worker); + vb_migrate_blink_stop(inst); + vb_migrate_scene_from_app_set_state(inst, FromAppStateEmulateCheckDim); + consumed = true; + } else if(state == FromAppStateEmulateCheckDim) { + BantBlock* bant = vb_tag_get_bant_block(&inst->nfc_dev->dev_data); + VbTagOperation operation = vb_tag_get_operation(bant); + + if(operation == VbTagOperationReturnFromApp) { + nfc_worker_stop(inst->worker); + vb_migrate_blink_stop(inst); + vb_migrate_scene_from_app_set_state( + inst, FromAppStateEmulateTransferFromApp); + consumed = true; + } else if(operation == VbTagOperationCheckDim) { + // Don't need to reset tag, but should make a beep + vb_migrate_blink_stop(inst); + notification_message_block(inst->notifications, &sequence_success); + vb_migrate_blink_emulate(inst); + } + } + } + } else if(event.event == FromAppEventTypeTemplateLoadError) { + vb_migrate_scene_from_app_set_state(inst, FromAppStateTemplateError); + consumed = true; + } else if(event.event == FromAppEventTypeCaptureSaveError) { + vb_migrate_scene_from_app_set_state(inst, FromAppStateSaveError); + consumed = true; + } else if(event.event == FromAppEventTypeCaptureSaveSuccess) { + ++inst->num_captured; + ++inst->next_id; + vb_migrate_scene_from_app_set_state(inst, FromAppStateEmulateReady); + consumed = true; + } else { + furi_crash("Unknown event in vb_migrate_scene_from_app_on_event"); + } + } + return consumed; +} + +void vb_migrate_scene_from_app_on_exit(void* context) { + VbMigrate* inst = context; + + // Perform your cleanup here + widget_reset(inst->widget); + nfc_worker_stop(inst->worker); + vb_migrate_blink_stop(inst); + notification_message_block(inst->notifications, &sequence_reset_red); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_info.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_info.c new file mode 100644 index 000000000..f5a991a56 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_info.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "../vb_migrate_i.h" +#include "../vb_tag.h" + +static void + vb_migrate_scene_info_button_callback(GuiButtonType result, InputType type, void* context) { + VbMigrate* inst = context; + + if(type == InputTypeShort) { + if(result == GuiButtonTypeRight) { + view_dispatcher_send_custom_event(inst->view_dispatcher, result); + } + } +} + +void vb_migrate_scene_info_on_enter(void* context) { + VbMigrate* inst = context; + FuriString* temp_str = furi_string_alloc(); + + // Build info scroll + // Name + furi_string_cat_printf(temp_str, "\ec%s\n", inst->text_store); + + // Type + if(inst->orig_product == NULL) + furi_string_cat(temp_str, "Unknown product\n"); + else + furi_string_cat_printf(temp_str, "\e#%s\n", inst->orig_product->name); + + // Number of mons loaded + furi_string_cat_printf(temp_str, "Charas. captured: %d", inst->num_captured); + + vb_migrate_add_bg(inst->widget, VbMigrateBgTypeRightButton); + + widget_add_text_scroll_element(inst->widget, 8, 16, 113, 33, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); + + widget_add_button_element( + inst->widget, GuiButtonTypeRight, "More", vb_migrate_scene_info_button_callback, inst); + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); +} + +bool vb_migrate_scene_info_on_event(void* context, SceneManagerEvent event) { + VbMigrate* inst = context; + bool consumed = false; + UNUSED(inst); + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GuiButtonTypeRight) { + // Reset menu selection index + scene_manager_set_scene_state(inst->scene_manager, VbMigrateSceneDevMenu, 0); + scene_manager_next_scene(inst->scene_manager, VbMigrateSceneDevMenu); + consumed = true; + } + } else if(event.type == SceneManagerEventTypeBack) { + uint32_t back_scenes[] = {VbMigrateSceneSelect, VbMigrateSceneMainMenu}; + consumed = scene_manager_search_and_switch_to_previous_scene_one_of( + inst->scene_manager, back_scenes, COUNT_OF(back_scenes)); + } + return consumed; +} + +void vb_migrate_scene_info_on_exit(void* context) { + VbMigrate* inst = context; + + // Perform your cleanup here + widget_reset(inst->widget); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_load.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_load.c new file mode 100644 index 000000000..8f316a1ed --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_load.c @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "../vb_migrate_i.h" + +#define TAG "vb_migrate_scene_load" + +void vb_migrate_scene_load_on_enter(void* context) { + VbMigrate* inst = context; + + // Perform your setup here + vb_migrate_show_loading_popup(inst, true); + view_dispatcher_send_custom_event(inst->view_dispatcher, 0); +} + +bool vb_migrate_scene_load_on_event(void* context, SceneManagerEvent event) { + VbMigrate* inst = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(vb_migrate_load_nfc(inst, inst->text_store, VB_MIGRATE_TEMPLATE_NAME)) { + inst->num_captured = vb_migrate_count_captured_mons(inst, inst->text_store); + + BantBlock* bant = vb_tag_get_bant_block(&inst->nfc_dev->dev_data); + const VbTagProduct* product = vb_tag_find_product(bant); + inst->orig_product = product; + if(product) { + inst->orig_type = product->type; + } else { + inst->orig_type = VbTagTypeUnknown; + } + inst->override_type = inst->orig_type; + + scene_manager_next_scene(inst->scene_manager, VbMigrateSceneInfo); + consumed = true; + } else { + consumed = scene_manager_previous_scene(inst->scene_manager); + } + vb_migrate_show_loading_popup(inst, false); + } + return consumed; +} + +void vb_migrate_scene_load_on_exit(void* context) { + UNUSED(context); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_main_menu.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_main_menu.c new file mode 100644 index 000000000..13dea042d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_main_menu.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "../vb_migrate_i.h" + +typedef enum { + SubmenuMainIndexRegister, + SubmenuMainIndexSelect, + SubmenuMainIndexAbout, +} SubmenuMainIndex; + +static void vb_migrate_scene_main_menu_submenu_callback(void* context, uint32_t index) { + VbMigrate* inst = context; + + view_dispatcher_send_custom_event(inst->view_dispatcher, index); +} + +void vb_migrate_scene_main_menu_on_enter(void* context) { + VbMigrate* inst = context; + Submenu* submenu = inst->submenu; + + submenu_add_item( + submenu, + "Register Vital Bracelet", + SubmenuMainIndexRegister, + vb_migrate_scene_main_menu_submenu_callback, + inst); + submenu_add_item( + submenu, + "Select Vital Bracelet", + SubmenuMainIndexSelect, + vb_migrate_scene_main_menu_submenu_callback, + inst); + submenu_add_item( + submenu, "About", SubmenuMainIndexAbout, vb_migrate_scene_main_menu_submenu_callback, inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewMenu); +} + +bool vb_migrate_scene_main_menu_on_event(void* context, SceneManagerEvent event) { + VbMigrate* inst = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuMainIndexRegister) { + scene_manager_next_scene(inst->scene_manager, VbMigrateSceneRegister); + consumed = true; + } else if(event.event == SubmenuMainIndexSelect) { + scene_manager_next_scene(inst->scene_manager, VbMigrateSceneSelect); + consumed = true; + } else if(event.event == SubmenuMainIndexAbout) { + scene_manager_next_scene(inst->scene_manager, VbMigrateSceneAbout); + consumed = true; + } + } + return consumed; +} + +void vb_migrate_scene_main_menu_on_exit(void* context) { + VbMigrate* inst = context; + + submenu_reset(inst->submenu); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_register.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_register.c new file mode 100644 index 000000000..ce4c05008 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_register.c @@ -0,0 +1,420 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include + +#include "../vb_tag.h" +#include "../vb_migrate_i.h" + +typedef enum { + RegisterStateInitial, + RegisterStateInstructionInitial, + RegisterStateInstructionConnect, + RegisterStateCaptureInitial, + RegisterStateCaptureInvalidTag, + RegisterStateCapturePwd, + RegisterStateCaptureFull, + RegisterStateCaptureFailed, + RegisterStateCaptureIncorrectTag, +} RegisterState; + +typedef enum { + RegisterEventTypeNextButton, + RegisterEventTypePrevButton, + RegisterEventTypeVbReadInitial, + RegisterEventTypeVbPwdAuth, + RegisterEventTypeVbReadFullSuccess, + RegisterEventTypeVbReadFullFail, +} RegisterEventType; + +static void + vb_migrate_scene_register_widget_callback(GuiButtonType result, InputType type, void* context) { + VbMigrate* inst = context; + + if(type == InputTypeShort) { + if(result == GuiButtonTypeRight) + view_dispatcher_send_custom_event(inst->view_dispatcher, RegisterEventTypeNextButton); + else if(result == GuiButtonTypeLeft) + view_dispatcher_send_custom_event(inst->view_dispatcher, RegisterEventTypePrevButton); + } +} + +static bool + vb_migrate_scene_register_worker_read_initial_callback(NfcWorkerEvent event, void* context) { + VbMigrate* inst = context; + bool consumed = false; + + if(event == NfcWorkerEventReadMfUltralight) { + view_dispatcher_send_custom_event(inst->view_dispatcher, RegisterEventTypeVbReadInitial); + consumed = true; + } + + return consumed; +} + +static bool vb_migrate_scene_register_worker_auth_callback(NfcWorkerEvent event, void* context) { + VbMigrate* inst = context; + bool consumed = false; + + if(event == NfcWorkerEventMfUltralightPwdAuth) { + view_dispatcher_send_custom_event(inst->view_dispatcher, RegisterEventTypeVbPwdAuth); + consumed = true; + } + + return consumed; +} + +static bool + vb_migrate_scene_register_worker_full_capture_callback(NfcWorkerEvent event, void* context) { + VbMigrate* inst = context; + bool consumed = false; + + if(event == NfcWorkerEventMfUltralightPassKey) { + memcpy( + inst->nfc_dev->dev_data.mf_ul_data.auth_key, + inst->captured_pwd, + sizeof(inst->captured_pwd)); + consumed = true; + } else if(event == NfcWorkerEventSuccess) { + view_dispatcher_send_custom_event( + inst->view_dispatcher, RegisterEventTypeVbReadFullSuccess); + consumed = true; + } else if(event == NfcWorkerEventFail) { + view_dispatcher_send_custom_event(inst->view_dispatcher, RegisterEventTypeVbReadFullFail); + consumed = true; + } + + return consumed; +} + +static void vb_migrate_scene_register_cleanup_state(VbMigrate* inst, RegisterState state) { + if(state == RegisterStateCaptureInvalidTag || state == RegisterStateCaptureFailed || + state == RegisterStateCaptureIncorrectTag) { + notification_message(inst->notifications, &sequence_reset_red); + } else if( + state == RegisterStateCaptureInitial || state == RegisterStateCapturePwd || + state == RegisterStateCaptureFull) { + vb_migrate_blink_stop(inst); + nfc_worker_stop(inst->worker); + } +} + +static void vb_migrate_scene_register_set_state(VbMigrate* inst, RegisterState state) { + uint32_t curr_state = + scene_manager_get_scene_state(inst->scene_manager, VbMigrateSceneRegister); + if(state != curr_state) { + vb_migrate_scene_register_cleanup_state(inst, curr_state); + Widget* widget = inst->widget; + + if(state == RegisterStateInstructionInitial) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton | VbMigrateBgTypeRightButton); + widget_add_text_scroll_element( + widget, + 8, + 16, + 113, + 33, + "Please make sure your\n" + "current character has\n" + "been sent to VB Lab/\n" + "Arena before\n" + "continuing."); + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Cancel", + vb_migrate_scene_register_widget_callback, + inst); + widget_add_button_element( + widget, + GuiButtonTypeRight, + "Next", + vb_migrate_scene_register_widget_callback, + inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + } else if(state == RegisterStateInstructionConnect) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton | VbMigrateBgTypeRightButton); + widget_add_text_scroll_element( + widget, + 8, + 16, + 113, + 33, + "Prepare VB Lab:\n" + "1. Ensure current\n" + "character in VB Lab has\n" + "been put in storage\n" + "2. Open the \"Scan\" screen\n" + "3. Tap \"Vital Bracelet ->\n" + "App\"\n" + "\n" + "Prepare VB Arena:\n" + "1. Select the device type\n" + "that matches your VB\n" + "2. Tap the \"Send\" button"); + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Cancel", + vb_migrate_scene_register_widget_callback, + inst); + widget_add_button_element( + widget, + GuiButtonTypeRight, + "Next", + vb_migrate_scene_register_widget_callback, + inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + } else if(state == RegisterStateCaptureInitial) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton); + widget_add_icon_element(widget, 11, 25, &I_CommVB_32x20); + widget_add_icon_element(widget, 21, 17, &I_CommWave_12x8); + widget_add_icon_element(widget, 48, 18, &I_TextRegister1_71x20); + widget_add_icon_element(widget, 105, 40, &I_PulsemonLeftStand_14x16); + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Previous", + vb_migrate_scene_register_widget_callback, + inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + nfc_device_clear(inst->nfc_dev); + inst->nfc_dev->dev_data.read_mode = NfcReadModeMfUltralight; + nfc_worker_start( + inst->worker, + NfcWorkerStateRead, + &inst->nfc_dev->dev_data, + vb_migrate_scene_register_worker_read_initial_callback, + inst); + vb_migrate_blink_read(inst); + } else if(state == RegisterStateCaptureInvalidTag) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton); + widget_add_icon_element(widget, 11, 18, &I_WrongDevice_32x27); + widget_add_icon_element(widget, 48, 18, &I_TextRegisterErrNotVb_71x20); + widget_add_icon_element(widget, 104, 41, &I_PulsemonLeftWait_15x15); + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Retry", + vb_migrate_scene_register_widget_callback, + inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + notification_message(inst->notifications, &sequence_set_red_255); + } else if(state == RegisterStateCapturePwd) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton); + widget_add_icon_element(widget, 11, 18, &I_AppInteract_32x27); + widget_add_icon_element(widget, 48, 18, &I_TextTapApp_56x27); + widget_add_icon_element(widget, 105, 40, &I_PulsemonLeftStand_14x16); + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Previous", + vb_migrate_scene_register_widget_callback, + inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + + BantBlock* bant = vb_tag_get_bant_block(&inst->nfc_dev->dev_data); + vb_tag_set_operation(bant, VbTagOperationReady); + vb_tag_set_status(bant, VbTagStatusReady); + nfc_worker_start( + inst->worker, + NfcWorkerStateMfUltralightEmulate, + &inst->nfc_dev->dev_data, + vb_migrate_scene_register_worker_auth_callback, + inst); + vb_migrate_blink_emulate(inst); + } else if(state == RegisterStateCaptureFull) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton); + widget_add_icon_element(widget, 11, 25, &I_CommVB_32x20); + widget_add_icon_element(widget, 23, 18, &I_CommReturn_10x8); + widget_add_icon_element(widget, 48, 18, &I_TextRegisterTapAgain_67x20); + widget_add_icon_element(widget, 104, 41, &I_PulsemonLeftWait_15x15); + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Previous", + vb_migrate_scene_register_widget_callback, + inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + + inst->nfc_dev->dev_data.mf_ul_data.auth_method = MfUltralightAuthMethodAuto; + nfc_worker_start( + inst->worker, + NfcWorkerStateReadMfUltralightReadAuth, + &inst->nfc_dev->dev_data, + vb_migrate_scene_register_worker_full_capture_callback, + inst); + vb_migrate_blink_read(inst); + } else if(state == RegisterStateCaptureFailed) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton); + widget_add_icon_element(widget, 11, 18, &I_WrongDevice_32x27); + widget_add_icon_element(widget, 48, 18, &I_TextErrReadFailed_71x20); + widget_add_icon_element(widget, 104, 41, &I_PulsemonLeftWait_15x15); + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Retry", + vb_migrate_scene_register_widget_callback, + inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + notification_message(inst->notifications, &sequence_set_red_255); + } else if(state == RegisterStateCaptureIncorrectTag) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton); + widget_add_icon_element(widget, 11, 18, &I_WrongDevice_32x27); + widget_add_icon_element(widget, 48, 18, &I_TextErrRegisterDifferentTag_47x20); + widget_add_icon_element(widget, 104, 41, &I_PulsemonLeftWait_15x15); + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Retry", + vb_migrate_scene_register_widget_callback, + inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + notification_message(inst->notifications, &sequence_set_red_255); + } else { + furi_crash("Unknown new state in vb_migrate_scene_register_set_state"); + } + + scene_manager_set_scene_state(inst->scene_manager, VbMigrateSceneRegister, state); + } +} + +static bool vb_migrate_scene_register_next_state(VbMigrate* inst, RegisterState state) { + if(state == RegisterStateInstructionInitial) { + vb_migrate_scene_register_set_state(inst, RegisterStateInstructionConnect); + return true; + } else if(state == RegisterStateInstructionConnect) { + vb_migrate_scene_register_set_state(inst, RegisterStateCaptureInitial); + return true; + } + + return false; +} + +static bool + vb_migrate_scene_register_prev_state(VbMigrate* inst, RegisterState state, bool is_back) { + UNUSED(is_back); + + if(state == RegisterStateInstructionInitial || state == RegisterStateInstructionConnect) { + return scene_manager_previous_scene(inst->scene_manager); + } else if(state == RegisterStateCaptureInitial) { + vb_migrate_scene_register_set_state(inst, RegisterStateInstructionConnect); + return true; + } else if( + state == RegisterStateCaptureInvalidTag || state == RegisterStateCapturePwd || + state == RegisterStateCaptureFull) { + vb_migrate_scene_register_set_state(inst, RegisterStateCaptureInitial); + return true; + } else if(state == RegisterStateCaptureFailed || state == RegisterStateCaptureIncorrectTag) { + vb_migrate_scene_register_set_state(inst, RegisterStateCaptureFull); + return true; + } + + return is_back; +} + +void vb_migrate_scene_register_on_enter(void* context) { + VbMigrate* inst = context; + + scene_manager_set_scene_state( + inst->scene_manager, VbMigrateSceneRegister, RegisterStateInitial); + vb_migrate_scene_register_set_state(inst, RegisterStateInstructionInitial); +} + +bool vb_migrate_scene_register_on_event(void* context, SceneManagerEvent event) { + VbMigrate* inst = context; + bool consumed = false; + RegisterState state = + scene_manager_get_scene_state(inst->scene_manager, VbMigrateSceneRegister); + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == RegisterEventTypeNextButton) { + consumed = vb_migrate_scene_register_next_state(inst, state); + } else if(event.event == RegisterEventTypePrevButton) { + consumed = vb_migrate_scene_register_prev_state(inst, state, false); + } else if(event.event == RegisterEventTypeVbReadInitial) { + if(vb_tag_validate_product(&inst->nfc_dev->dev_data)) { + memcpy( + inst->captured_uid, + inst->nfc_dev->dev_data.nfc_data.uid, + sizeof(inst->captured_uid)); + notification_message(inst->notifications, &sequence_success); + vb_migrate_scene_register_set_state(inst, RegisterStateCapturePwd); + } else { + notification_message(inst->notifications, &sequence_error); + vb_migrate_scene_register_set_state(inst, RegisterStateCaptureInvalidTag); + } + consumed = true; + } else if(event.event == RegisterEventTypeVbPwdAuth) { + // Set up for auth + memcpy( + inst->captured_pwd, + inst->nfc_dev->dev_data.mf_ul_auth.pwd.raw, + sizeof(inst->captured_pwd)); + + notification_message(inst->notifications, &sequence_success); + vb_migrate_scene_register_set_state(inst, RegisterStateCaptureFull); + consumed = true; + } else if(event.event == RegisterEventTypeVbReadFullSuccess) { + NfcDeviceData* dev_data = &inst->nfc_dev->dev_data; + if(memcmp(dev_data->nfc_data.uid, inst->captured_uid, sizeof(inst->captured_uid)) || + dev_data->mf_ul_data.data_read != dev_data->mf_ul_data.data_size) { + notification_message(inst->notifications, &sequence_error); + vb_migrate_scene_register_set_state(inst, RegisterStateCaptureIncorrectTag); + } else { + notification_message(inst->notifications, &sequence_success); + scene_manager_next_scene(inst->scene_manager, VbMigrateSceneRegisterSave); + } + consumed = true; + } else if(event.event == RegisterEventTypeVbReadFullFail) { + notification_message(inst->notifications, &sequence_error); + vb_migrate_scene_register_set_state(inst, RegisterStateCaptureFailed); + consumed = true; + } else { + furi_crash("Unknown event in vb_migrate_scene_register_on_event"); + } + } else if(event.type == SceneManagerEventTypeBack) { + consumed = vb_migrate_scene_register_prev_state(inst, state, true); + } + return consumed; +} + +void vb_migrate_scene_register_on_exit(void* context) { + VbMigrate* inst = context; + RegisterState state = + scene_manager_get_scene_state(inst->scene_manager, VbMigrateSceneRegister); + + vb_migrate_scene_register_cleanup_state(inst, state); + widget_reset(inst->widget); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_register_save.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_register_save.c new file mode 100644 index 000000000..e388ed25e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_register_save.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include + +#include "../vb_migrate_i.h" +#include "../vb_tag.h" + +// This thing doesn't know what a FuriString is +#include + +typedef enum { + RegisterSaveEventTextInput, +} RegisterSaveEvent; + +static void vb_migrate_scene_register_save_text_input_callback(void* context) { + VbMigrate* inst = context; + + view_dispatcher_send_custom_event(inst->view_dispatcher, RegisterSaveEventTextInput); +} + +void vb_migrate_scene_register_save_on_enter(void* context) { + VbMigrate* inst = context; + + // Setup view + TextInput* text_input = inst->text_input; + text_input_set_header_text(text_input, "Name this Vital Bracelet"); + text_input_set_result_callback( + text_input, + vb_migrate_scene_register_save_text_input_callback, + inst, + inst->text_store, + VB_MIGRATE_MAX_DEV_NAME_LENGTH, + true); + + // Set default name + FuriString* temp_str; + NfcDeviceData* dev_data = &inst->nfc_dev->dev_data; + BantBlock* bant = vb_tag_get_bant_block(dev_data); + const VbTagProduct* prod = vb_tag_find_product(bant); + temp_str = furi_string_alloc_printf("%s_", prod->short_name); + for(size_t i = 0; i < dev_data->nfc_data.uid_len; ++i) { + furi_string_cat_printf(temp_str, "%02x", dev_data->nfc_data.uid[i]); + } + vb_migrate_text_store_set(inst, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); + + // We're validating whether folder exists + ValidatorIsFile* validator_is_file = + validator_is_file_alloc_init(VB_MIGRATE_FOLDER, "/" VB_MIGRATE_TEMPLATE_NAME, NULL); + text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewTextInput); + notification_message(inst->notifications, &sequence_set_green_255); +} + +bool vb_migrate_scene_register_save_on_event(void* context, SceneManagerEvent event) { + VbMigrate* inst = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == RegisterSaveEventTextInput) { + if(strlen(inst->text_store) != 0) { + vb_migrate_show_loading_popup(inst, true); + if(vb_migrate_save_nfc(inst, inst->text_store, VB_MIGRATE_TEMPLATE_NAME)) { + inst->num_captured = 0; + + BantBlock* bant = vb_tag_get_bant_block(&inst->nfc_dev->dev_data); + const VbTagProduct* product = vb_tag_find_product(bant); + inst->orig_product = product; + if(product) { + inst->orig_type = product->type; + } else { + inst->orig_type = VbTagTypeUnknown; + } + inst->override_type = inst->orig_type; + + // Go to success + scene_manager_next_scene(inst->scene_manager, VbMigrateSceneSaveSuccess); + } else { + // Otherwise just stay here + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewTextInput); + } + vb_migrate_show_loading_popup(inst, false); + + consumed = true; + } + } + } + return consumed; +} + +void vb_migrate_scene_register_save_on_exit(void* context) { + VbMigrate* inst = context; + + // Clear view + TextInput* text_input = inst->text_input; + ValidatorIsFile* validator = text_input_get_validator_callback_context(text_input); + text_input_set_validator(text_input, NULL, NULL); + validator_is_file_free(validator); + + text_input_reset(text_input); + notification_message_block(inst->notifications, &sequence_reset_green); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_save_success.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_save_success.c new file mode 100644 index 000000000..f62b4d24c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_save_success.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "../vb_migrate_i.h" + +static void vb_migrate_scene_save_success_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + VbMigrate* inst = context; + + if(type == InputTypeShort) { + if(result == GuiButtonTypeRight) + view_dispatcher_send_custom_event(inst->view_dispatcher, 0); + } +} + +void vb_migrate_scene_save_success_on_enter(void* context) { + VbMigrate* inst = context; + + // Setup view + Widget* widget = inst->widget; + vb_migrate_add_bg(widget, VbMigrateBgTypeRightButton); + widget_add_icon_element(widget, 11, 18, &I_CommComplete_32x20); + widget_add_icon_element(widget, 48, 18, &I_TextSaved_30x6); + widget_add_icon_element(widget, 9, 40, &I_PulsemonRightHappy_14x16); + widget_add_button_element( + widget, GuiButtonTypeRight, "OK", vb_migrate_scene_save_success_widget_callback, inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); +} + +bool vb_migrate_scene_save_success_on_event(void* context, SceneManagerEvent event) { + VbMigrate* inst = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom || event.type == SceneManagerEventTypeBack) { + scene_manager_next_scene(inst->scene_manager, VbMigrateSceneInfo); + consumed = true; + } + return consumed; +} + +void vb_migrate_scene_save_success_on_exit(void* context) { + VbMigrate* inst = context; + + // Clear view + widget_reset(inst->widget); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_select.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_select.c new file mode 100644 index 000000000..84f8590d8 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_select.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "../vb_migrate_i.h" + +static void vb_migrate_scene_select_file_select_callback(bool result, void* context) { + VbMigrate* inst = context; + + view_dispatcher_send_custom_event(inst->view_dispatcher, result); +} + +void vb_migrate_scene_select_on_enter(void* context) { + VbMigrate* inst = context; + + // Perform your setup here + file_select_set_callback( + inst->file_select, vb_migrate_scene_select_file_select_callback, inst); + file_select_set_filter(inst->file_select, VB_MIGRATE_FOLDER, "*"); + file_select_set_result_buffer(inst->file_select, inst->text_store, sizeof(inst->text_store)); + file_select_init(inst->file_select); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewFileSelect); +} + +bool vb_migrate_scene_select_on_event(void* context, SceneManagerEvent event) { + VbMigrate* inst = context; + bool consumed = false; + UNUSED(inst); + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event) { + // File selected + scene_manager_next_scene(inst->scene_manager, VbMigrateSceneLoad); + consumed = true; + } + } + return consumed; +} + +void vb_migrate_scene_select_on_exit(void* context) { + UNUSED(context); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_to_app.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_to_app.c new file mode 100644 index 000000000..08941332a --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/scenes/vb_migrate_scene_to_app.c @@ -0,0 +1,297 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include + +#include "../vb_migrate_i.h" +#include "../vb_tag.h" + +#define TAG "vb_migrate_scene_to_app" + +typedef enum { + ToAppStateInitial, + ToAppStateInstructions, + ToAppStateEmulateReady, + ToAppStateEmulateTransferToApp, + ToAppStateLoadError, + ToAppStateComplete, +} ToAppState; + +typedef enum { + ToAppEventTypeWidgetLeft, + ToAppEventTypeWidgetRight, + ToAppEventTypeEmulateStart, + ToAppEventTypeCaptureLoadError, + ToAppEventTypeTagWrite, +} ToAppEventType; + +static void + vb_migrate_scene_to_app_widget_callback(GuiButtonType result, InputType type, void* context) { + VbMigrate* inst = context; + + if(type == InputTypeShort) { + if(result == GuiButtonTypeLeft) + view_dispatcher_send_custom_event(inst->view_dispatcher, ToAppEventTypeWidgetLeft); + else if(result == GuiButtonTypeRight) + view_dispatcher_send_custom_event(inst->view_dispatcher, ToAppEventTypeWidgetRight); + } +} + +static bool vb_migrate_scene_to_app_worker_callback(NfcWorkerEvent event, void* context) { + VbMigrate* inst = context; + bool result = false; + + if(event == NfcWorkerEventSuccess) { + view_dispatcher_send_custom_event(inst->view_dispatcher, ToAppEventTypeTagWrite); + result = true; + } + + return result; +} + +static void vb_migrate_scene_to_app_set_nfc_state(VbMigrate* inst, ToAppState state) { + BantBlock* bant = vb_tag_get_bant_block(&inst->nfc_dev->dev_data); + if(state == ToAppStateEmulateReady) { + vb_tag_set_random_nonce(bant); + vb_tag_set_status(bant, VbTagStatusReady); + vb_tag_set_operation(bant, VbTagOperationReady); + } + + // Override tag type + if(inst->override_type != inst->orig_type && inst->override_type != VbTagTypeUnknown) { + vb_tag_set_item_id_no(bant, vb_tag_get_default_product(inst->override_type)); + } + + if(inst->clear_account_id) { + vb_tag_set_app_flag(bant, false); + } +} + +static bool vb_migrate_scene_to_app_is_state_changed(VbMigrate* inst, ToAppState state) { + BantBlock* bant = vb_tag_get_bant_block(&inst->nfc_dev->dev_data); + VbTagOperation operation = vb_tag_get_operation(bant); + + if(state == ToAppStateEmulateReady) { + return operation == VbTagOperationTransferToApp; + } + + return false; +} + +static void vb_migrate_scene_to_app_set_state(VbMigrate* inst, ToAppState state) { + uint32_t curr_state = scene_manager_get_scene_state(inst->scene_manager, VbMigrateSceneToApp); + if(state != curr_state) { + Widget* widget = inst->widget; + + if(state == ToAppStateInstructions) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton | VbMigrateBgTypeRightButton); + widget_add_text_scroll_element( + widget, + 8, + 16, + 113, + 33, + "\e#To transfer\n" + "\e#characters from\n" + "\e#Flipper:\n" + "0. If on VB Arena, select\n" + "the device type that\n" + "matches your current\n" + "settings and the correct\n" + "franchise for the\n" + "characters you're\n" + "transferring\n" + "1. If on VB Lab, put the\n" + "current character into\n" + "storage\n" + "2. Sync character from\n" + "Flipper as if it was a Vital\n" + "Bracelet. Flipper will beep\n" + "and automatically\n" + "advance to the next\n" + "captured character when\n" + "VB Lab/Arena has\n" + "transferred the current\n" + "character\n" + "\n" + "-> You can press the right\n" + "key to skip sending the\n" + "current character\n" + "3. Repeat the above until\n" + "you have transferred all\n" + "the characters you want\n" + "\n" + "You can cancel at any\n" + "time to finish transferring."); + widget_add_button_element( + widget, GuiButtonTypeLeft, "Cancel", vb_migrate_scene_to_app_widget_callback, inst); + widget_add_button_element( + widget, GuiButtonTypeRight, "Next", vb_migrate_scene_to_app_widget_callback, inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + } else if(state == ToAppStateEmulateReady) { + view_dispatcher_send_custom_event(inst->view_dispatcher, ToAppEventTypeEmulateStart); + } else if(state == ToAppStateLoadError) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton); + widget_add_icon_element(widget, 11, 18, &I_WrongDevice_32x27); + widget_add_icon_element(widget, 48, 18, &I_TextErrLoadCapture_65x13); + widget_add_icon_element(widget, 104, 41, &I_PulsemonLeftWait_15x15); + FuriString* temp_str = furi_string_alloc_printf("%03d", inst->next_id); + widget_add_string_multiline_element( + widget, 48, 32, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); + widget_add_button_element( + widget, GuiButtonTypeLeft, "Cancel", vb_migrate_scene_to_app_widget_callback, inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + furi_string_free(temp_str); + notification_message(inst->notifications, &sequence_error); + notification_message(inst->notifications, &sequence_set_red_255); + } else if(state == ToAppStateComplete) { + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeRightButton); + widget_add_icon_element(widget, 11, 18, &I_CommComplete_32x20); + widget_add_icon_element(widget, 48, 18, &I_TextTransfersDone_51x13); + widget_add_icon_element(widget, 9, 40, &I_PulsemonRightHappy_14x16); + widget_add_button_element( + widget, GuiButtonTypeRight, "OK", vb_migrate_scene_to_app_widget_callback, inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + } else { + furi_crash("Unknown new state in vb_migrate_scene_to_app_set_state"); + } + + scene_manager_set_scene_state(inst->scene_manager, VbMigrateSceneToApp, state); + } +} + +static void vb_migrate_scene_to_app_load_capture(VbMigrate* inst, bool go_next) { + if(go_next) { + nfc_worker_stop(inst->worker); + vb_migrate_blink_stop(inst); + ++inst->next_id; + ++inst->num_sent; + } + + if(inst->num_sent == inst->num_captured) { + vb_migrate_scene_to_app_set_state(inst, ToAppStateComplete); + } else { + uint32_t state = scene_manager_get_scene_state(inst->scene_manager, VbMigrateSceneToApp); + inst->next_id = vb_migrate_get_next_id(inst, inst->text_store, inst->next_id, true); + FuriString* temp_str = + furi_string_alloc_printf(VB_MIGRATE_CAPTURE_FORMAT, inst->next_id, NFC_APP_EXTENSION); + + vb_migrate_show_loading_popup(inst, true); + if(vb_migrate_load_nfc(inst, inst->text_store, furi_string_get_cstr(temp_str))) { + Widget* widget = inst->widget; + + widget_reset(widget); + vb_migrate_add_bg(widget, VbMigrateBgTypeLeftButton | VbMigrateBgTypeRightButton); + widget_add_icon_element(widget, 11, 18, &I_AppInteract_32x27); + widget_add_icon_element(widget, 48, 18, &I_TextTapApp_56x27); + furi_string_printf(temp_str, "%d/%d", inst->num_sent + 1, inst->num_captured); + widget_add_string_element( + widget, + 120, + 48, + AlignRight, + AlignBottom, + FontSecondary, + furi_string_get_cstr(temp_str)); + widget_add_button_element( + widget, GuiButtonTypeLeft, "Cancel", vb_migrate_scene_to_app_widget_callback, inst); + widget_add_button_element( + widget, GuiButtonTypeRight, "Skip", vb_migrate_scene_to_app_widget_callback, inst); + + view_dispatcher_switch_to_view(inst->view_dispatcher, VbMigrateViewWidget); + + vb_migrate_scene_to_app_set_nfc_state(inst, state); + nfc_worker_start( + inst->worker, + NfcWorkerStateMfUltralightEmulate, + &inst->nfc_dev->dev_data, + vb_migrate_scene_to_app_worker_callback, + inst); + vb_migrate_blink_emulate(inst); + } else { + view_dispatcher_send_custom_event( + inst->view_dispatcher, ToAppEventTypeCaptureLoadError); + } + vb_migrate_show_loading_popup(inst, false); + furi_string_free(temp_str); + } +} + +void vb_migrate_scene_to_app_on_enter(void* context) { + VbMigrate* inst = context; + + // Perform your setup here + inst->next_id = 0; + inst->num_sent = 0; + scene_manager_set_scene_state(inst->scene_manager, VbMigrateSceneToApp, ToAppStateInitial); + vb_migrate_scene_to_app_set_state(inst, ToAppStateInstructions); +} + +bool vb_migrate_scene_to_app_on_event(void* context, SceneManagerEvent event) { + VbMigrate* inst = context; + uint32_t state = scene_manager_get_scene_state(inst->scene_manager, VbMigrateSceneToApp); + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == ToAppEventTypeWidgetLeft) { + consumed = scene_manager_previous_scene(inst->scene_manager); + } else if(event.event == ToAppEventTypeWidgetRight) { + if(state == ToAppStateInstructions) { + vb_migrate_scene_to_app_set_state(inst, ToAppStateEmulateReady); + consumed = true; + } else if(state == ToAppStateEmulateReady) { + vb_migrate_scene_to_app_load_capture(inst, true); + consumed = true; + } else if(state == ToAppStateComplete) { + consumed = scene_manager_previous_scene(inst->scene_manager); + } + } else if(event.event == ToAppEventTypeEmulateStart) { + vb_migrate_scene_to_app_load_capture(inst, false); + } else if(event.event == ToAppEventTypeTagWrite) { + if(vb_migrate_scene_to_app_is_state_changed(inst, state)) { + if(state == ToAppStateEmulateReady) { + notification_message(inst->notifications, &sequence_success); + vb_migrate_scene_to_app_load_capture(inst, true); + consumed = true; + } + } + } else if(event.event == ToAppEventTypeCaptureLoadError) { + vb_migrate_scene_to_app_set_state(inst, ToAppStateLoadError); + consumed = true; + } else { + furi_crash("Unknown event in vb_migrate_scene_to_app_on_event"); + } + } + return consumed; +} + +void vb_migrate_scene_to_app_on_exit(void* context) { + VbMigrate* inst = context; + + // Perform your cleanup here + widget_reset(inst->widget); + nfc_worker_stop(inst->worker); + vb_migrate_blink_stop(inst); + notification_message_block(inst->notifications, &sequence_reset_red); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_migrate.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_migrate.c new file mode 100644 index 000000000..06846458e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_migrate.c @@ -0,0 +1,331 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include + +#include "vb_migrate_i.h" + +#define TAG "vb_migrate" + +bool vb_migrate_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + VbMigrate* inst = context; + return scene_manager_handle_custom_event(inst->scene_manager, event); +} + +bool vb_migrate_back_event_callback(void* context) { + furi_assert(context); + VbMigrate* inst = context; + return scene_manager_handle_back_event(inst->scene_manager); +} + +void vb_migrate_blink_read(VbMigrate* inst) { + notification_message(inst->notifications, &sequence_blink_start_cyan); +} + +void vb_migrate_blink_emulate(VbMigrate* inst) { + notification_message(inst->notifications, &sequence_blink_start_magenta); +} + +void vb_migrate_blink_stop(VbMigrate* inst) { + notification_message_block(inst->notifications, &sequence_blink_stop); +} + +void vb_migrate_text_store_set(VbMigrate* inst, const char* text, ...) { + va_list args; + va_start(args, text); + + vsnprintf(inst->text_store, sizeof(inst->text_store), text, args); + + va_end(args); +} + +void vb_migrate_text_store_clear(VbMigrate* inst) { + memset(inst->text_store, 0, sizeof(inst->text_store)); +} + +bool vb_migrate_save_nfc(VbMigrate* inst, const char* dev_name, const char* file_name) { + bool saved = false; + FuriString* temp_str = furi_string_alloc(); + + do { + furi_string_printf(temp_str, "%s/%s", VB_MIGRATE_FOLDER, dev_name); + if(!storage_simply_mkdir(inst->storage, furi_string_get_cstr(temp_str))) { + dialog_message_show_storage_error(inst->dialogs, "Can not create\ndata folder"); + break; + } + furi_string_cat_printf(temp_str, "/%s", file_name); + inst->nfc_dev->format = NfcDeviceSaveFormatMifareUl; + saved = nfc_device_save(inst->nfc_dev, furi_string_get_cstr(temp_str)); + } while(false); + + furi_string_free(temp_str); + return saved; +} + +bool vb_migrate_load_nfc(VbMigrate* inst, const char* dev_name, const char* file_name) { + bool saved = false; + FuriString* temp_str = + furi_string_alloc_printf("%s/%s/%s", VB_MIGRATE_FOLDER, dev_name, file_name); + saved = nfc_device_load(inst->nfc_dev, furi_string_get_cstr(temp_str), true); + + furi_string_free(temp_str); + return saved; +} + +bool vb_migrate_delete(VbMigrate* inst, const char* dev_name, bool whole_vb) { + bool deleted = false; + FuriString* dir_path = furi_string_alloc_printf("%s/%s", VB_MIGRATE_FOLDER, dev_name); + + if(whole_vb) { + deleted = storage_simply_remove_recursive(inst->storage, furi_string_get_cstr(dir_path)); + } else { + File* dir_handle = storage_file_alloc(inst->storage); + if(storage_dir_open(dir_handle, furi_string_get_cstr(dir_path))) { + FileInfo file_info; + char name[256]; + FuriString* file_path = furi_string_alloc(); + while(storage_dir_read(dir_handle, &file_info, name, sizeof(name))) { + // Files that is .nfc, but is not template + if(!(file_info.flags & FSF_DIRECTORY) && strstr(name, NFC_APP_EXTENSION) && + !strstr(name, VB_MIGRATE_TEMPLATE_NAME)) { + furi_string_printf(file_path, "%s/%s", furi_string_get_cstr(dir_path), name); + deleted = + storage_simply_remove(inst->storage, furi_string_get_cstr(file_path)); + if(!deleted) break; + } + } + + furi_string_free(file_path); + storage_dir_close(dir_handle); + } + storage_file_free(dir_handle); + } + + furi_string_free(dir_path); + return deleted; +} + +int vb_migrate_count_captured_mons(VbMigrate* inst, const char* dev_name) { + int count = 0; + + FuriString* dir_path = furi_string_alloc_printf("%s/%s", VB_MIGRATE_FOLDER, dev_name); + File* dir_handle = storage_file_alloc(inst->storage); + if(storage_dir_open(dir_handle, furi_string_get_cstr(dir_path))) { + FileInfo file_info; + char name[256]; + while(storage_dir_read(dir_handle, &file_info, name, sizeof(name))) { + // Files that is .nfc, but is not template + if(!(file_info.flags & FSF_DIRECTORY) && strstr(name, NFC_APP_EXTENSION) && + !strstr(name, VB_MIGRATE_TEMPLATE_NAME)) + ++count; + } + + storage_dir_close(dir_handle); + } + storage_file_free(dir_handle); + furi_string_free(dir_path); + + return count; +} + +int vb_migrate_get_next_id(VbMigrate* inst, const char* dev_name, int i, bool is_load) { + FuriString* dir_path = furi_string_alloc_printf("%s/%s", VB_MIGRATE_FOLDER, dev_name); + FuriString* file_path = furi_string_alloc(); + while(true) { + furi_string_printf( + file_path, + "%s/" VB_MIGRATE_CAPTURE_FORMAT, + furi_string_get_cstr(dir_path), + i, + NFC_APP_EXTENSION); + bool exit_cond = + storage_common_stat(inst->storage, furi_string_get_cstr(file_path), NULL) == + FSE_NOT_EXIST; + if(is_load) exit_cond = !exit_cond; + if(exit_cond) break; + ++i; + } + + furi_string_free(file_path); + furi_string_free(dir_path); + return i; +} + +void vb_migrate_show_loading_popup(VbMigrate* inst, bool show) { + 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(inst->view_dispatcher, VbMigrateViewLoading); + } else { + // Restore default timer priority + vTaskPrioritySet(timer_task, configTIMER_TASK_PRIORITY); + } +} + +VbMigrate* vb_migrate_alloc() { + VbMigrate* inst = malloc(sizeof(VbMigrate)); + + inst->view_dispatcher = view_dispatcher_alloc(); + inst->scene_manager = scene_manager_alloc(&vb_migrate_scene_handlers, inst); + view_dispatcher_enable_queue(inst->view_dispatcher); + view_dispatcher_set_event_callback_context(inst->view_dispatcher, inst); + view_dispatcher_set_custom_event_callback( + inst->view_dispatcher, vb_migrate_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + inst->view_dispatcher, vb_migrate_back_event_callback); + + inst->clear_account_id = false; + + // GUI + inst->gui = furi_record_open(RECORD_GUI); + + // Storage + inst->storage = furi_record_open(RECORD_STORAGE); + + // Notifications service + inst->notifications = furi_record_open(RECORD_NOTIFICATION); + + // Dialogs + inst->dialogs = furi_record_open(RECORD_DIALOGS); + + // NFC + inst->nfc_dev = nfc_device_alloc(); + inst->worker = nfc_worker_alloc(); + + // Submenu + inst->submenu = submenu_alloc(); + view_dispatcher_add_view( + inst->view_dispatcher, VbMigrateViewMenu, submenu_get_view(inst->submenu)); + + // Popup + inst->popup = popup_alloc(); + view_dispatcher_add_view( + inst->view_dispatcher, VbMigrateViewPopup, popup_get_view(inst->popup)); + + // Widget + inst->widget = widget_alloc(); + view_dispatcher_add_view( + inst->view_dispatcher, VbMigrateViewWidget, widget_get_view(inst->widget)); + + // File select + inst->file_select = file_select_alloc(); + view_dispatcher_add_view( + inst->view_dispatcher, VbMigrateViewFileSelect, file_select_get_view(inst->file_select)); + + // Text input + inst->text_input = text_input_alloc(); + view_dispatcher_add_view( + inst->view_dispatcher, VbMigrateViewTextInput, text_input_get_view(inst->text_input)); + + // Loading + inst->loading = loading_alloc(); + view_dispatcher_add_view( + inst->view_dispatcher, VbMigrateViewLoading, loading_get_view(inst->loading)); + + // Variable item list + inst->variable_list = variable_item_list_ex_alloc(); + view_dispatcher_add_view( + inst->view_dispatcher, + VbMigrateViewVariableItemList, + variable_item_list_ex_get_view(inst->variable_list)); + + // Dialog ex + // inst->dialog_ex = dialog_ex_alloc(); + // view_dispatcher_add_view( + // inst->view_dispatcher, VbMigrateViewDialogEx, dialog_ex_get_view(inst->dialog_ex)); + + return inst; +} + +void vb_migrate_free(VbMigrate* inst) { + // Dialog ex + // view_dispatcher_remove_view(inst->view_dispatcher, VbMigrateViewDialogEx); + // dialog_ex_free(inst->dialog_ex); + + // Variable item list + view_dispatcher_remove_view(inst->view_dispatcher, VbMigrateViewVariableItemList); + variable_item_list_ex_free(inst->variable_list); + + // Loading + view_dispatcher_remove_view(inst->view_dispatcher, VbMigrateViewLoading); + loading_free(inst->loading); + + // Text input + view_dispatcher_remove_view(inst->view_dispatcher, VbMigrateViewTextInput); + text_input_free(inst->text_input); + + // File select + view_dispatcher_remove_view(inst->view_dispatcher, VbMigrateViewFileSelect); + file_select_free(inst->file_select); + + // Widget + view_dispatcher_remove_view(inst->view_dispatcher, VbMigrateViewWidget); + widget_free(inst->widget); + + // Popup + view_dispatcher_remove_view(inst->view_dispatcher, VbMigrateViewPopup); + popup_free(inst->popup); + + // Submenu + view_dispatcher_remove_view(inst->view_dispatcher, VbMigrateViewMenu); + submenu_free(inst->submenu); + + // NFC + nfc_worker_free(inst->worker); + nfc_device_free(inst->nfc_dev); + + furi_record_close(RECORD_DIALOGS); + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_STORAGE); + furi_record_close(RECORD_GUI); + + view_dispatcher_free(inst->view_dispatcher); + scene_manager_free(inst->scene_manager); + + free(inst); +} + +int32_t vb_migrate_app(void* p) { + UNUSED(p); + + VbMigrate* inst = vb_migrate_alloc(); + view_dispatcher_attach_to_gui(inst->view_dispatcher, inst->gui, ViewDispatcherTypeFullscreen); + + if(storage_simply_mkdir(inst->storage, VB_MIGRATE_FOLDER)) { + scene_manager_next_scene(inst->scene_manager, VbMigrateSceneMainMenu); + view_dispatcher_run(inst->view_dispatcher); + } else { + dialog_message_show_storage_error(inst->dialogs, "Can not create\napp folder"); + } + + vb_migrate_free(inst); + return 0; +} + +void vb_migrate_add_bg(Widget* widget, VbMigrateBgType type) { + widget_add_icon_element(widget, 0, 0, &I_Background_128x64); + if(type & VbMigrateBgTypeLeftButton) { + widget_add_icon_element(widget, 0, 49, &I_LeftButtonBg_54x15); + } + if(type & VbMigrateBgTypeRightButton) { + widget_add_icon_element(widget, 74, 49, &I_RightButtonBg_54x15); + } +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_migrate.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_migrate.h new file mode 100644 index 000000000..4104cf3fe --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_migrate.h @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#include + +#define VB_MIGRATE_VERSION "1.0" + +#define VB_MIGRATE_FOLDER ANY_PATH("vb_migrate") + +typedef struct VbMigrate VbMigrate; + +VbMigrate* vb_migrate_alloc(); + +void vb_migrate_free(VbMigrate* inst); diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_migrate_10px.png b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_migrate_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..d9e7536ff2f90e7302a5516a2591a3303e91d395 GIT binary patch literal 618 zcmV-w0+s!VP)EX>4Tx04R}tkv&MmKpe$i(~2S$2P=ql$WWauh!t^^Di*;)X)CnqU~=gfG-*gu zTpR`0f`cE6RR0!X5l%$?&0I>U6f~epZjwRC4rtTK|Hf* z>74h8L#!+*#OK5l23?T&k?XR{Z=6dG3p_JqWYhD+A!4!A#c~(3vY`@B6Gs$PqkJLf zvch?bvs$gQ_C5Ivg9U9R!*!ZrB(Q`eQV=1djtZ)<5T#Wk#YCF+;~xG|$DbmXOs)zT zITlcZ3d!+<|H1EW&0=iIO$x?=o)_Ex7z28DfmXw|zmILZbprUGfh(=!uQh?$PtqG5 zEph}5ZUYzB9ZlW?E_Z;DCtWfmNAlAYibdf4jJ_!k4BZ0#Yi@7teVjf3S?X%}1~@nb z#!HmF?(y!v?%w`A)9&vFu_SW9l0g*)00006VoOIv0RI600RN!9r;`8x010qNS#tmY z4#WTe4#WYKD-Ig~000McNliru<_sJJ9w0l=;L-p902y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002TsL_t&-)1{C>3IH((#4@G-|8n-!vMja;o1. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#include "gui/modules/file_select.h" +#include +#include "gui/modules/variable_item_list_ex.h" + +#include +#include + +#include + +#include "vb_migrate.h" +#include "scenes/vb_migrate_scene.h" +#include "vb_tag.h" + +#include "vb_migrate_icons.h" + +#define VB_MIGRATE_TEMPLATE_NAME "template" NFC_APP_EXTENSION +#define VB_MIGRATE_CAPTURE_FORMAT "%03d%s" + +#define VB_MIGRATE_MAX_DEV_NAME_LENGTH (30) + +struct VbMigrate { + Gui* gui; + Storage* storage; + DialogsApp* dialogs; + NotificationApp* notifications; + ViewDispatcher* view_dispatcher; + SceneManager* scene_manager; + Submenu* submenu; + Popup* popup; + Widget* widget; + // DialogEx* dialog_ex; + FileSelect* file_select; + TextInput* text_input; + Loading* loading; + VariableItemListEx* variable_list; + NfcWorker* worker; + NfcDevice* nfc_dev; + char text_store[128]; + uint8_t captured_pwd[4]; + uint8_t captured_uid[7]; + bool clear_account_id; + int num_captured; + int next_id; + int num_sent; + VbTagType orig_type; + VbTagType override_type; + const VbTagProduct* orig_product; +}; + +typedef enum { + VbMigrateViewMenu, + VbMigrateViewPopup, + VbMigrateViewWidget, + VbMigrateViewTextInput, + // VbMigrateViewDialogEx, + VbMigrateViewFileSelect, + VbMigrateViewLoading, + VbMigrateViewVariableItemList, +} VbMigrateView; + +typedef enum { + VbMigrateBgTypeNone, + VbMigrateBgTypeLeftButton = 1 << 0, + VbMigrateBgTypeRightButton = 1 << 1, +} VbMigrateBgType; + +void vb_migrate_blink_read(VbMigrate* inst); +void vb_migrate_blink_emulate(VbMigrate* inst); +void vb_migrate_blink_stop(VbMigrate* inst); +void vb_migrate_text_store_set(VbMigrate* inst, const char* text, ...); +void vb_migrate_text_store_clear(VbMigrate* inst); +bool vb_migrate_save_nfc(VbMigrate* inst, const char* dev_name, const char* file_name); +bool vb_migrate_load_nfc(VbMigrate* inst, const char* dev_name, const char* file_name); +int vb_migrate_count_captured_mons(VbMigrate* inst, const char* dev_name); +bool vb_migrate_delete(VbMigrate* inst, const char* dev_name, bool whole_vb); +int vb_migrate_get_next_id(VbMigrate* inst, const char* dev_name, int i, bool is_load); +void vb_migrate_show_loading_popup(VbMigrate* inst, bool show); +void vb_migrate_add_bg(Widget* widget, VbMigrateBgType type); diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_tag.c b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_tag.c new file mode 100644 index 000000000..3020e67a5 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_tag.c @@ -0,0 +1,235 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include "vb_tag.h" + +#define VB_NAME_VBDM "VB Digital Monster" +#define VB_NAME_VBV "VB Digivice -V-" +#define VB_NAME_VBC "VB Characters" +#define VB_NAME_VH "Vital Hero" +#define VB_NAME_VBBE "Vital Bracelet BE" + +#define VB_NAME_VBDM_SHORT "VBDM" +#define VB_NAME_VBV_SHORT "VBV" +#define VB_NAME_VBC_SHORT "VBC" +#define VB_NAME_VH_SHORT "VH" +#define VB_NAME_VBBE_SHORT "VBBE" + +struct BantBlockCommon { + uint32_t magic; + // Note: this should be big endian, but for convenience, we'll treat them as little endian + uint16_t item_id; + uint16_t item_no; + uint8_t status; +} __attribute__((packed)); + +struct BantBlockVb { + uint8_t dim_no; + uint8_t operation; + uint8_t reserved; + uint8_t app_flag; + uint8_t padding[3]; +} __attribute__((packed)); + +struct BantBlockBe { + uint8_t operation; + uint16_t dim_no; + uint8_t app_flag; + uint8_t nonce[3]; +} __attribute__((packed)); + +struct BantBlock { + struct BantBlockCommon common; + union { + struct BantBlockVb vb; + struct BantBlockBe be; + }; +} __attribute__((packed)); + +static const VbTagProduct vb_tag_valid_products[] = { + {.item_id = 0x0200, + .item_no = 0x0100, + .name = VB_NAME_VBDM, + .short_name = VB_NAME_VBDM_SHORT, + .type = VbTagTypeVBDM}, + {.item_id = 0x0200, + .item_no = 0x0200, + .name = VB_NAME_VBDM, + .short_name = VB_NAME_VBDM_SHORT, + .type = VbTagTypeVBDM}, + {.item_id = 0x0200, + .item_no = 0x0300, + .name = VB_NAME_VBDM, + .short_name = VB_NAME_VBDM_SHORT, + .type = VbTagTypeVBDM}, + {.item_id = 0x0200, + .item_no = 0x0400, + .name = VB_NAME_VBV, + .short_name = VB_NAME_VBV_SHORT, + .type = VbTagTypeVBV}, + {.item_id = 0x0200, + .item_no = 0x0500, + .name = VB_NAME_VBV, + .short_name = VB_NAME_VBV_SHORT, + .type = VbTagTypeVBV}, + {.item_id = 0x0200, + .item_no = 0x0600, + .name = VB_NAME_VH, + .short_name = VB_NAME_VH_SHORT, + .type = VbTagTypeVH}, + {.item_id = 0x0300, + .item_no = 0x0100, + .name = VB_NAME_VBC, + .short_name = VB_NAME_VBC_SHORT, + .type = VbTagTypeVBC}, + {.item_id = 0x0400, + .item_no = 0x0100, + .name = VB_NAME_VBBE, + .short_name = VB_NAME_VBBE_SHORT, + .type = VbTagTypeVBBE}, +}; + +static const char* vb_tag_type_names[] = { + "Unknown", + VB_NAME_VBDM_SHORT, + VB_NAME_VBV_SHORT, + VB_NAME_VBC_SHORT, + VB_NAME_VH_SHORT, + VB_NAME_VBBE_SHORT, +}; + +BantBlock* vb_tag_get_bant_block(NfcDeviceData* dev) { + return (BantBlock*)&dev->mf_ul_data.data[16]; +} + +const VbTagProduct* vb_tag_find_product(const BantBlock* bant) { + for(size_t i = 0; i < COUNT_OF(vb_tag_valid_products); ++i) { + const VbTagProduct* product = &vb_tag_valid_products[i]; + if(bant->common.item_id == product->item_id && bant->common.item_no == product->item_no) + return product; + } + + return NULL; +} + +bool vb_tag_validate_product(NfcDeviceData* dev) { + // Must be NTAG I2C Plus 1k + if(dev->protocol != NfcDeviceProtocolMifareUl) return false; + if(dev->mf_ul_data.type != MfUltralightTypeNTAGI2CPlus1K) return false; + // Must match one of the known product IDs + BantBlock* bant = vb_tag_get_bant_block(dev); + if(bant->common.magic != BANT_MAGIC) return false; + return vb_tag_find_product(bant) != NULL; +} + +VbTagStatus vb_tag_get_status(const BantBlock* bant) { + return bant->common.status; +} + +void vb_tag_set_status(BantBlock* bant, VbTagStatus status) { + bant->common.status = status; +} + +VbTagOperation vb_tag_get_operation(const BantBlock* bant) { + return vb_tag_is_vbbe(bant) ? bant->be.operation : bant->vb.operation; +} + +void vb_tag_set_operation(BantBlock* bant, VbTagOperation operation) { + uint8_t* p_op = vb_tag_is_vbbe(bant) ? &bant->be.operation : &bant->vb.operation; + *p_op = operation; +} + +const VbTagProduct* vb_tag_get_default_product(VbTagType type) { + // IMPORTANT: Update when vb_tag_valid_products changes + switch(type) { + case VbTagTypeVBDM: + return &vb_tag_valid_products[2]; + case VbTagTypeVBV: + return &vb_tag_valid_products[4]; + case VbTagTypeVBC: + return &vb_tag_valid_products[6]; + case VbTagTypeVH: + return &vb_tag_valid_products[5]; + case VbTagTypeVBBE: + return &vb_tag_valid_products[7]; + + default: + return NULL; + } +} + +void vb_tag_set_item_id_no(BantBlock* bant, const VbTagProduct* product) { + bant->common.item_id = product->item_id; + bant->common.item_no = product->item_no; +} + +const char* vb_tag_get_tag_type_name(VbTagType type) { + if(type < VbTagTypeMax) { + return vb_tag_type_names[type]; + } else { + return NULL; + } +} + +bool vb_tag_get_app_flag(const BantBlock* bant) { + uint8_t app_flag = vb_tag_is_vbbe(bant) ? bant->be.app_flag : bant->vb.app_flag; + return app_flag == 1; +} + +void vb_tag_set_app_flag(BantBlock* bant, bool value) { + uint8_t* app_flag = vb_tag_is_vbbe(bant) ? &bant->be.app_flag : &bant->vb.app_flag; + *app_flag = value ? 1 : 0xff; +} + +// Lookup is expensive, let's check tag ID directly +bool vb_tag_is_vbbe(const BantBlock* bant) { + return bant->common.item_id == 0x0400; +} + +uint32_t vb_tag_get_nonce(const BantBlock* bant) { + if(vb_tag_is_vbbe(bant)) { + return (bant->be.nonce[0] << 16) | (bant->be.nonce[1] << 8) | bant->be.nonce[2]; + } else { + return 0; + } +} + +void vb_tag_set_nonce(BantBlock* bant, uint32_t value) { + if(vb_tag_is_vbbe(bant)) { + uint8_t* nonce = bant->be.nonce; + nonce[0] = value >> 16; + nonce[1] = value >> 8; + nonce[2] = value; + } +} + +void vb_tag_set_random_nonce(BantBlock* bant) { + if(vb_tag_is_vbbe(bant)) { + uint32_t orig_nonce = vb_tag_get_nonce(bant); + uint32_t new_nonce; + do { + new_nonce = rand() & 0xffffff; + // Original nonce is generated as ((rand() % 0xffff) << 8) | (rand() % 0xff), + // so don't inclue 0xffff** and 0x****ff as valid values + if((new_nonce & 0xff) == 0xff) --new_nonce; + if(new_nonce >= 0xffff00) new_nonce -= 0x100; + } while(new_nonce == 0 || new_nonce == orig_nonce); + vb_tag_set_nonce(bant, new_nonce); + } +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_tag.h b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_tag.h new file mode 100644 index 000000000..ee1375a8f --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipperzero_vb_migrate/vb_tag.h @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// +// VB Lab Migration Assistant for Flipper Zero +// Copyright (C) 2022 cyanic +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#include +#include + +#define BANT_MAGIC (0x544E4142) + +typedef struct BantBlock BantBlock; + +typedef enum { + VbTagTypeUnknown, + VbTagTypeVBDM, + VbTagTypeVBV, + VbTagTypeVBC, + VbTagTypeVH, + VbTagTypeVBBE, + VbTagTypeMax +} VbTagType; + +typedef struct { + uint16_t item_id; + uint16_t item_no; + const char* name; + const char* short_name; + VbTagType type; +} VbTagProduct; + +typedef enum { + VbTagStatusReady = 1 << 0, + VbTagStatusDimReady = 1 << 1, + VbTagStatusActiveIsAvatar = 1 << 2, +} VbTagStatus; + +typedef enum { + VbTagOperationIdle, + VbTagOperationReady, + VbTagOperationTransferToApp, + VbTagOperationCheckDim, + VbTagOperationReturnFromApp, + VbTagOperationSpotInit, + VbTagOperationSpotCommit, +} VbTagOperation; + +BantBlock* vb_tag_get_bant_block(NfcDeviceData* dev); +const VbTagProduct* vb_tag_find_product(const BantBlock* bant); +bool vb_tag_validate_product(NfcDeviceData* dev); +VbTagStatus vb_tag_get_status(const BantBlock* bant); +void vb_tag_set_status(BantBlock* bant, VbTagStatus status); +VbTagOperation vb_tag_get_operation(const BantBlock* bant); +void vb_tag_set_operation(BantBlock* bant, VbTagOperation operation); +const VbTagProduct* vb_tag_get_default_product(VbTagType type); +void vb_tag_set_item_id_no(BantBlock* bant, const VbTagProduct* product); +const char* vb_tag_get_tag_type_name(VbTagType type); +bool vb_tag_get_app_flag(const BantBlock* bant); +void vb_tag_set_app_flag(BantBlock* bant, bool value); +bool vb_tag_is_vbbe(const BantBlock* bant); +uint32_t vb_tag_get_nonce(const BantBlock* bant); +void vb_tag_set_nonce(BantBlock* bant, uint32_t value); +void vb_tag_set_random_nonce(BantBlock* bant); diff --git a/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/README.md b/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/README.md new file mode 100644 index 000000000..3cd3d4d53 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/README.md @@ -0,0 +1,11 @@ +## Simple count down timer application for flipper zero + +### How to use +`up/down`: set second/minute/hour value. + +`ok`: start/stop counting. + +`long press on ok`: stop counting and reset counter. + +`left/right`: select second/minute/hour value. + diff --git a/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/app.c b/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/app.c new file mode 100644 index 000000000..5c03ea246 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/app.c @@ -0,0 +1,71 @@ +#include "views/countdown_view.h" +#include "app.h" + +static void register_view(ViewDispatcher* dispatcher, View* view, uint32_t viewid); + +int32_t app_main(void* p) { + UNUSED(p); + + CountDownTimerApp* app = countdown_app_new(); + + countdown_app_run(app); + + countdown_app_delete(app); + + return 0; +} + +static uint32_t view_exit(void* ctx) { + furi_assert(ctx); + + return VIEW_NONE; +} + +CountDownTimerApp* countdown_app_new(void) { + CountDownTimerApp* app = (CountDownTimerApp*)(malloc(sizeof(CountDownTimerApp))); + + // 1.1 open gui + app->gui = furi_record_open(RECORD_GUI); + + // 2.1 setup view dispatcher + app->view_dispatcher = view_dispatcher_alloc(); + view_dispatcher_enable_queue(app->view_dispatcher); + + // 2.2 attach view dispatcher to gui + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + // 2.3 attach views to the dispatcher + // helloworld view + app->helloworld_view = countdown_timer_view_new(); + register_view(app->view_dispatcher, countdown_timer_view_get_view(app->helloworld_view), 0xff); + + // 2.5 switch to default view + view_dispatcher_switch_to_view(app->view_dispatcher, 0xff); + + return app; +} + +void countdown_app_delete(CountDownTimerApp* app) { + furi_assert(app); + + // delete views + view_dispatcher_remove_view(app->view_dispatcher, 0xff); + countdown_timer_view_delete(app->helloworld_view); // hello world view + + // delete view dispatcher + view_dispatcher_free(app->view_dispatcher); + furi_record_close(RECORD_GUI); + + // self + free(app); +} + +void countdown_app_run(CountDownTimerApp* app) { + view_dispatcher_run(app->view_dispatcher); +} + +static void register_view(ViewDispatcher* dispatcher, View* view, uint32_t viewid) { + view_dispatcher_add_view(dispatcher, viewid, view); + + view_set_previous_callback(view, view_exit); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/app.h b/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/app.h new file mode 100644 index 000000000..413b3dbbf --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/app.h @@ -0,0 +1,22 @@ +#ifndef __APP_H__ +#define __APP_H__ + +#include +#include +#include + +// app +typedef struct { + Gui* gui; // gui object + ViewDispatcher* view_dispatcher; // view dispacther of the gui + + // views + CountDownTimView* helloworld_view; + +} CountDownTimerApp; + +CountDownTimerApp* countdown_app_new(void); +void countdown_app_delete(CountDownTimerApp* app); +void countdown_app_run(CountDownTimerApp* app); + +#endif \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/application.fam b/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/application.fam new file mode 100644 index 000000000..419b63125 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/application.fam @@ -0,0 +1,16 @@ +# qv. https://github.com/flipperdevices/flipperzero-firmware/blob/dev/documentation/AppManifests.md + +App( + appid="cntdown_tim", + name="Count Down Timer", + apptype=FlipperAppType.EXTERNAL, + entry_point="app_main", + cdefines=["APP_COUNT_DOWN_TIMER"], + requires=[ + "gui", + ], + stack_size=2 * 1024, + order=20, + fap_icon="cntdown_timer.png", + fap_category="Misc_Extra", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/cntdown_timer.png b/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/cntdown_timer.png new file mode 100644 index 0000000000000000000000000000000000000000..b25c2718e0e6e84fa1c074e48b432c16cd0215f9 GIT binary patch literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>aY>EvO!M_+ z&;qhK7#Q0#8CXC{fLIEM85o!sFfuR$X-1IP0w%aD*8*k)8>G;>V#ik?C6npm9|EMA zKw?0^3d9;v8pKX5;9)5Q(uSTcjv*SNNk95oBqSvMDJQF}{Lf>+=fP;@AjW)p5yyhe zhLen$A(JosRETy+a?u94>i_?)x=pWv40Dj?*gi%s1_KVJzyFs@d$Dg*I295!Y1!!= zx9>dC&JnI|v9S1ec~ORfMT2wLn$P8%C# +#include "utils.h" + +static const NotificationSequence sequence_beep = { + &message_blue_255, + &message_note_d5, + &message_delay_100, + &message_sound_off, + + NULL, +}; + +void notification_beep_once() { + notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_beep); + notification_off(); +} + +void notification_off() { + furi_record_close(RECORD_NOTIFICATION); +} + +void notification_timeup() { + notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_audiovisual_alert); +} + +void parse_sec_to_time_str(char* buffer, size_t len, int32_t sec) { + snprintf( + buffer, + len, + "%02ld:%02ld:%02ld", + (sec % (60 * 60 * 24)) / (60 * 60), // hour + (sec % (60 * 60)) / 60, // minute + sec % 60); // second +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/utils/utils.h b/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/utils/utils.h new file mode 100644 index 000000000..c72db7319 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/utils/utils.h @@ -0,0 +1,12 @@ +#ifndef __UTILS_H__ +#define __UTILS_H__ +#include +#include + +void notification_beep_once(); +void notification_off(); +void notification_timeup(); + +void parse_sec_to_time_str(char *buffer, size_t len, int32_t sec); + +#endif // __UTILS_H__ \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/views/countdown_view.c b/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/views/countdown_view.c new file mode 100644 index 000000000..97e8cb248 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/views/countdown_view.c @@ -0,0 +1,346 @@ +#include "countdown_view.h" +#include "../utils/utils.h" + +// internal +static void handle_misc_cmd(CountDownTimView* hw, CountDownViewCmd cmd); +static void handle_time_setting_updown(CountDownTimView* cdv, CountDownViewCmd cmd); +static void handle_time_setting_select(InputKey key, CountDownTimView* cdv); +static void draw_selection(Canvas* canvas, CountDownViewSelect selection); + +static void countdown_timer_start_counting(CountDownTimView* cdv); +static void countdown_timer_pause_counting(CountDownTimView* cdv); + +// callbacks +static void countdown_timer_view_on_enter(void* ctx); +static void countdown_timer_view_on_draw(Canvas* canvas, void* ctx); +static bool countdown_timer_view_on_input(InputEvent* event, void* ctx); +static void timer_cb(void* ctx); + +CountDownTimView* countdown_timer_view_new() { + CountDownTimView* cdv = (CountDownTimView*)(malloc(sizeof(CountDownTimView))); + + cdv->view = view_alloc(); + + cdv->timer = furi_timer_alloc(timer_cb, FuriTimerTypePeriodic, cdv); + + cdv->counting = false; + + view_set_context(cdv->view, cdv); + + view_allocate_model(cdv->view, ViewModelTypeLocking, sizeof(CountDownModel)); + + view_set_draw_callback(cdv->view, countdown_timer_view_on_draw); + view_set_input_callback(cdv->view, countdown_timer_view_on_input); + view_set_enter_callback(cdv->view, countdown_timer_view_on_enter); + + return cdv; +} + +void countdown_timer_view_delete(CountDownTimView* cdv) { + furi_assert(cdv); + + view_free(cdv->view); + furi_timer_stop(cdv->timer); + furi_timer_free(cdv->timer); + + free(cdv); +} + +View* countdown_timer_view_get_view(CountDownTimView* cdv) { + return cdv->view; +} + +void countdown_timer_view_state_reset(CountDownTimView* cdv) { + cdv->counting = false; + + with_view_model( + cdv->view, CountDownModel * model, { model->count = model->saved_count_setting; }, true) +} + +void countdown_timer_state_toggle(CountDownTimView* cdv) { + bool on = cdv->counting; + if(!on) { + countdown_timer_start_counting(cdv); + } else { + countdown_timer_pause_counting(cdv); + } + + cdv->counting = !on; +} + +// on enter callback, CountDownTimView as ctx +static void countdown_timer_view_on_enter(void* ctx) { + furi_assert(ctx); + + CountDownTimView* cdv = (CountDownTimView*)ctx; + + // set current count to a initial value + with_view_model( + cdv->view, + CountDownModel * model, + { + model->count = INIT_COUNT; + model->saved_count_setting = INIT_COUNT; + }, + true); +} + +// view draw callback, CountDownModel as ctx +static void countdown_timer_view_on_draw(Canvas* canvas, void* ctx) { + furi_assert(ctx); + CountDownModel* model = (CountDownModel*)ctx; + + char buffer[64]; + + int32_t count = model->count; + int32_t expected_count = model->saved_count_setting; + + CountDownViewSelect select = model->select; + + // elements_frame(canvas, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + + canvas_set_font(canvas, FontBigNumbers); + draw_selection(canvas, select); + + parse_sec_to_time_str(buffer, sizeof(buffer), count); + canvas_draw_str_aligned( + canvas, SCREEN_CENTER_X, SCREEN_CENTER_Y, AlignCenter, AlignCenter, buffer); + + elements_progress_bar(canvas, 0, 0, SCREEN_WIDTH, (1.0 * count / expected_count)); +} + +// keys input event callback, CountDownTimView as ctx +static bool countdown_timer_view_on_input(InputEvent* event, void* ctx) { + furi_assert(ctx); + + CountDownTimView* hw = (CountDownTimView*)ctx; + + if(event->type == InputTypeShort || event->type == InputTypeRepeat) { + switch(event->key) { + case InputKeyUp: + case InputKeyDown: + case InputKeyRight: + case InputKeyLeft: + handle_time_setting_select(event->key, hw); + break; + + case InputKeyOk: + if(event->type == InputTypeShort) { + handle_misc_cmd(hw, CountDownTimerToggleCounting); + } + break; + + default: + break; + } + + return true; + } + + if(event->type == InputTypeLong) { + switch(event->key) { + case InputKeyOk: + handle_misc_cmd(hw, CountDownTimerReset); + break; + + case InputKeyBack: + return false; + break; + + default: + break; + } + + return true; + } + + return false; +} + +static void timer_cb(void* ctx) { + furi_assert(ctx); + + CountDownTimView* cdv = (CountDownTimView*)ctx; + + int32_t count; + bool timeup = false; + + // decrement counter + with_view_model( + cdv->view, + CountDownModel * model, + { + count = model->count; + count--; + + // check timeup + if(count <= 0) { + count = 0; + timeup = true; + } + + model->count = count; + }, + true); + + if(timeup) { + handle_misc_cmd(cdv, CountDownTimerTimeUp); + } +} + +static void handle_time_setting_updown(CountDownTimView* cdv, CountDownViewCmd cmd) { + int32_t count; + + with_view_model( + cdv->view, + CountDownModel * model, + { + count = model->count; + switch(cmd) { + case CountDownTimerMinuteUp: + count += 60; + break; + case CountDownTimerMinuteDown: + count -= 60; + break; + case CountDownTimerHourDown: + count -= 3600; + break; + case CountDownTimerHourUp: + count += 3600; + break; + case CountDownTimerSecUp: + count++; + break; + case CountDownTimerSecDown: + count--; + break; + default: + break; + } + + if(count < 0) { + count = 0; + } + + // update count state + model->count = count; + + // save the count time setting + model->saved_count_setting = count; + }, + true); +} + +static void handle_misc_cmd(CountDownTimView* hw, CountDownViewCmd cmd) { + switch(cmd) { + case CountDownTimerTimeUp: + notification_timeup(); + break; + + case CountDownTimerReset: + furi_timer_stop(hw->timer); + countdown_timer_view_state_reset(hw); + notification_off(); + + break; + + case CountDownTimerToggleCounting: + countdown_timer_state_toggle(hw); + break; + + default: + break; + } + + return; +} + +static void handle_time_setting_select(InputKey key, CountDownTimView* cdv) { + bool counting = cdv->counting; + CountDownViewCmd setting_cmd = CountDownTimerSecUp; + CountDownViewSelect selection; + + if(counting) { + return; + } + + // load current selection from model context + with_view_model( + cdv->view, CountDownModel * model, { selection = model->select; }, false); + + // select + switch(key) { + case InputKeyUp: + switch(selection) { + case CountDownTimerSelectSec: + setting_cmd = CountDownTimerSecUp; + break; + case CountDownTimerSelectMinute: + setting_cmd = CountDownTimerMinuteUp; + break; + case CountDownTimerSelectHour: + setting_cmd = CountDownTimerHourUp; + break; + } + + handle_time_setting_updown(cdv, setting_cmd); + break; + + case InputKeyDown: + switch(selection) { + case CountDownTimerSelectSec: + setting_cmd = CountDownTimerSecDown; + break; + case CountDownTimerSelectMinute: + setting_cmd = CountDownTimerMinuteDown; + break; + case CountDownTimerSelectHour: + setting_cmd = CountDownTimerHourDown; + break; + } + + handle_time_setting_updown(cdv, setting_cmd); + break; + + case InputKeyRight: + selection--; + selection = selection % 3; + break; + + case InputKeyLeft: + selection++; + selection = selection % 3; + break; + + default: + break; + } + + // save selection to model context + with_view_model( + cdv->view, CountDownModel * model, { model->select = selection; }, false); +} + +static void draw_selection(Canvas* canvas, CountDownViewSelect selection) { + switch(selection) { + case CountDownTimerSelectSec: + elements_slightly_rounded_box(canvas, SCREEN_CENTER_X + 25, SCREEN_CENTER_Y + 11, 24, 2); + break; + case CountDownTimerSelectMinute: + elements_slightly_rounded_box(canvas, SCREEN_CENTER_X - 10, SCREEN_CENTER_Y + 11, 21, 2); + break; + case CountDownTimerSelectHour: + elements_slightly_rounded_box(canvas, SCREEN_CENTER_X - 47, SCREEN_CENTER_Y + 11, 24, 2); + break; + } +} + +static void countdown_timer_start_counting(CountDownTimView* cdv) { + furi_timer_start(cdv->timer, furi_kernel_get_tick_frequency() * 1); // 1s +} + +static void countdown_timer_pause_counting(CountDownTimView* cdv) { + furi_timer_stop(cdv->timer); + notification_off(); +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/views/countdown_view.h b/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/views/countdown_view.h new file mode 100644 index 000000000..ed8114f8e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/fpz_cntdown_timer-main/views/countdown_view.h @@ -0,0 +1,59 @@ +#ifndef __COUNTDOWN_VIEW_H__ +#define __COUNTDOWN_VIEW_H__ + +#include +#include +#include +#include + +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 64 +#define SCREEN_CENTER_X (SCREEN_WIDTH / 2) +#define SCREEN_CENTER_Y (SCREEN_HEIGHT / 2) + +#define INIT_COUNT 10 + +typedef enum { + CountDownTimerMinuteUp, + CountDownTimerMinuteDown, + CountDownTimerSecDown, + CountDownTimerSecUp, + CountDownTimerHourUp, + CountDownTimerHourDown, + CountDownTimerReset, + CountDownTimerTimeUp, + CountDownTimerToggleCounting, +} CountDownViewCmd; + +typedef enum { + CountDownTimerSelectSec, + CountDownTimerSelectMinute, + CountDownTimerSelectHour, +} CountDownViewSelect; + +typedef struct { + int32_t count; + int32_t saved_count_setting; + CountDownViewSelect select; // setting +} CountDownModel; + +typedef struct { + View* view; + FuriTimer* timer; // 1Hz tick timer + bool counting; + +} CountDownTimView; + +// functions +// allocate helloworld view +CountDownTimView* countdown_timer_view_new(); + +// delete helloworld view +void countdown_timer_view_delete(CountDownTimView* cdv); + +// return view +View* countdown_timer_view_get_view(CountDownTimView* cdv); + +void countdown_timer_view_state_reset(CountDownTimView* cdv); // set initial state +void countdown_timer_state_toggle(CountDownTimView* cdv); +#endif // __COUNTDOWN_VIEW_H__ \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/game2048/2048.png b/Applications/Official/DEV_FW/source/xMasterX/game2048/2048.png new file mode 100644 index 0000000000000000000000000000000000000000..6f46d4de543e8ee590f58b4cd9988ee95a7196f6 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2VGmzZ%#=aj&F%}28J29*~C-V}>VM%xNb!1@J z*w6hZkrl}23GfMV1=9cj|Nr~<@4tWlPRVDj0P;BtJR*x382Ao?FyoGi*>8b@GM+Au xArj%q4s1O=0W2v-jTvca9V|Qn%NiOP8MwYMmt)6!PC{xWt~$(69D~ZE+YT{ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/game2048/application.fam b/Applications/Official/DEV_FW/source/xMasterX/game2048/application.fam new file mode 100644 index 000000000..efafb9b82 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/game2048/application.fam @@ -0,0 +1,12 @@ +App( + appid="2048", + name="2048", + apptype=FlipperAppType.EXTERNAL, + entry_point="game_2048_app", + cdefines=["APP_2048_GAME"], + requires=["gui"], + stack_size=2 * 1024, + order=10, + fap_icon="2048.png", + fap_category="Games_Extra", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/game2048/font.c b/Applications/Official/DEV_FW/source/xMasterX/game2048/font.c new file mode 100644 index 000000000..9acfe8d23 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/game2048/font.c @@ -0,0 +1,155 @@ +#include +#include +#include + +/* 7px 3 width digit font by Sefjor + * digit encoding example + *7 ¦¦¦ 111 + *6 ¦ ¦ 101 + *5 ¦ ¦ 101 + *4 ¦ ¦ 101 + *3 ¦ ¦ 101 + *2 ¦ ¦ 101 + *1 ¦¦¦ 111 + *0 000 this string is empty, used to align + * ? ? ? + * FE 82 FE //0 + */ + +static uint8_t font[10][3] = { + {0xFE, 0x82, 0xFE}, // 0; + {0x00, 0xFE, 0x00}, // 1; + {0xF2, 0x92, 0x9E}, // 2; + {0x92, 0x92, 0xFE}, // 3; + {0x1E, 0x10, 0xFE}, // 4; + {0x9E, 0x92, 0xF2}, // 5; + {0xFE, 0x92, 0xF2}, // 6; + {0x02, 0x02, 0xFE}, // 7; + {0xFE, 0x92, 0xFE}, // 8; + {0x9E, 0x92, 0xFE}, // 9; +}; + +#define FONT_HEIGHT 8 +#define FONT_WIDTH 3 + +static void game_2048_draw_black_point(Canvas* const canvas, uint8_t x, uint8_t y) { + canvas_set_color(canvas, ColorBlack); + canvas_draw_dot(canvas, x, y); +} + +static void game_2048_draw_white_square(Canvas* const canvas, uint8_t x, uint8_t y) { + canvas_set_color(canvas, ColorWhite); + canvas_draw_box(canvas, x, y, 15 - 1, 15 - 3); +} + +static void _game_2048_draw_column( + Canvas* const canvas, + int digit, + int coord_x, + int coord_y, + uint8_t column) { + for(int x = 0; x < FONT_HEIGHT; ++x) { + bool is_filled = (font[digit][column] >> x) & 0x1; + if(is_filled) { + game_2048_draw_black_point(canvas, coord_x, coord_y + x); + } + } +} + +static uint8_t + _game_2048_draw_digit(Canvas* const canvas, uint8_t digit, uint8_t coord_x, uint8_t coord_y) { + uint8_t x_shift = 0; + + if(digit != 1) { + for(int column = 0; column < FONT_WIDTH; column++) { + _game_2048_draw_column(canvas, digit, coord_x + column, coord_y, column); + } + x_shift = 3; + } else { + _game_2048_draw_column(canvas, digit, coord_x, coord_y, true); + x_shift = 1; + } + + return x_shift; +} + +/* We drawing text field with 1px white border + * at given coords. Total size is: + * x = 9 = 1 + 7 + 1 + * y = 1 + total text width + 1 + */ + +/* + * Returns array of digits and it's size, + * digits should be at least 4 size + * works from 1 to 9999 + */ +static void _game_2048_parse_number(uint16_t number, uint8_t* digits, uint8_t* size) { + *size = 0; + uint16_t divider = 1000; + //find first digit, result is highest divider + while(number / divider == 0) { + divider /= 10; + if(divider == 0) { + break; + } + } + + for(int i = 0; divider != 0; i++) { + digits[i] = number / divider; + number %= divider; + *size += 1; + divider /= 10; + } +} + +uint8_t _game_2048_calculate_shift(uint16_t num) { + uint8_t shift = 0; + switch(num) { + case 1: + shift = 7; + break; + case 2: + case 4: + case 8: + shift = 6; + break; + case 16: + shift = 5; + break; + case 32: + case 64: + shift = 4; + break; + case 128: + shift = 3; + break; + case 256: + shift = 2; + break; + case 512: + shift = 3; + break; + case 1024: + shift = 2; + break; + } + return shift; +} + +void game_2048_draw_number(Canvas* const canvas, uint8_t x, uint8_t y, int number) { + uint8_t digits[4]; + uint8_t size; + + _game_2048_parse_number(number, digits, &size); + if(number > 512) { + game_2048_draw_white_square(canvas, x, y); + } + + x += _game_2048_calculate_shift(number); + y += 4; + for(int i = 0; i < size; ++i) { + x += _game_2048_draw_digit(canvas, digits[i], x, y); + x++; + } +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/game2048/font.h b/Applications/Official/DEV_FW/source/xMasterX/game2048/font.h new file mode 100644 index 000000000..500123ac3 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/game2048/font.h @@ -0,0 +1,3 @@ +#include + +void game_2048_draw_number(Canvas* const canvas, uint8_t x, uint8_t y, int number); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/game2048/game_2048.c b/Applications/Official/DEV_FW/source/xMasterX/game2048/game_2048.c new file mode 100644 index 000000000..77b85e8da --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/game2048/game_2048.c @@ -0,0 +1,494 @@ +#include +#include +#include +#include + +#include "font.h" + +#define DEBUG false +/* + 0 empty + 1 2 + 2 4 + 3 8 + 4 16 + 5 32 + 6 64 + 7 128 + 8 256 + 9 512 +10 1024 +11 2048 +12 4096 +... + */ +typedef uint8_t cell_state; + +/* DirectionLeft <-- +┌╌╌╌╌â”┌╌╌╌╌â”┌╌╌╌╌â”┌╌╌╌╌┠+â•Ž â•Žâ•Ž â•Žâ•Ž â•Žâ•Ž â•Ž +└╌╌╌╌┘└╌╌╌╌┘└╌╌╌╌┘└╌╌╌╌┘ +┌╌╌╌╌â”┌╌╌╌╌â”┌╌╌╌╌â”┌╌╌╌╌┠+â•Ž â•Žâ•Ž â•Žâ•Ž â•Žâ•Ž â•Ž +└╌╌╌╌┘└╌╌╌╌┘└╌╌╌╌┘└╌╌╌╌┘ +┌╌╌┌╌╌╌╌â”╌╌â”┌╌╌╌╌â”┌╌╌╌╌┠+â•Ž 2â•Ž 2 â•Ž â•Žâ•Ž â•Žâ•Ž â•Ž +└╌╌└╌╌╌╌┘╌╌┘└╌╌╌╌┘└╌╌╌╌┘ +┌╌╌┌╌╌╌╌â”┌╌╌┌╌╌╌╌â”┌╌╌╌╌┠+â•Ž 4â•Ž 4 â•Žâ•Ž 2â•Ž 2 â•Žâ•Ž â•Ž +└╌╌└╌╌╌╌┘└╌╌└╌╌╌╌┘└╌╌╌╌┘ +*/ +typedef enum { + DirectionIdle, + DirectionUp, + DirectionRight, + DirectionDown, + DirectionLeft, +} Direction; + +typedef struct { + uint8_t y; // 0 <= y <= 3 + uint8_t x; // 0 <= x <= 3 +} Point; + +typedef struct { + uint32_t gameScore; + uint32_t highScore; +} Score; + +typedef struct { + /* + +----X + | + | field[x][y] + Y + */ + uint8_t field[4][4]; + + uint8_t next_field[4][4]; + + Score score; // original scoring + + Direction direction; + /* + field { + animation-timing-function: linear; + animation-duration: 300ms; + } + */ + uint32_t animation_start_ticks; + + Point keyframe_from[4][4]; + + Point keyframe_to[4][4]; + + bool debug; + +} GameState; + +#define XtoPx(x) (33 + x * 15) + +#define YtoPx(x) (1 + y * 15) + +static void game_2048_render_callback(Canvas* const canvas, ValueMutex* const vm) { + const GameState* game_state = acquire_mutex(vm, 25); + if(game_state == NULL) { + return; + } + + // Before the function is called, the state is set with the canvas_reset(canvas) + + if(game_state->direction == DirectionIdle) { + for(uint8_t y = 0; y < 4; y++) { + for(uint8_t x = 0; x < 4; x++) { + uint8_t field = game_state->field[y][x]; + canvas_set_color(canvas, ColorBlack); + canvas_draw_frame(canvas, XtoPx(x), YtoPx(y), 16, 16); + if(field != 0) { + game_2048_draw_number(canvas, XtoPx(x), YtoPx(y), 1 << field); + } + } + } + + // display score + char buffer[12]; + snprintf(buffer, sizeof(buffer), "%lu", game_state->score.gameScore); + canvas_draw_str_aligned(canvas, 127, 8, AlignRight, AlignBottom, buffer); + + if(game_state->score.highScore > 0) { + char buffer2[12]; + snprintf(buffer2, sizeof(buffer2), "%lu", game_state->score.highScore); + canvas_draw_str_aligned(canvas, 127, 62, AlignRight, AlignBottom, buffer2); + } + } else { // if animation + // for animation + // (osKernelGetSysTimerCount() - game_state->animation_start_ticks) / osKernelGetSysTimerFreq(); + + // TODO: end animation event/callback/set AnimationIdle + } + + release_mutex(vm, game_state); +} + +static void + game_2048_input_callback(const InputEvent* const input_event, FuriMessageQueue* event_queue) { + furi_assert(event_queue); + + furi_message_queue_put(event_queue, input_event, FuriWaitForever); +} + +// if return false then Game Over +static bool game_2048_set_new_number(GameState* const game_state) { + uint8_t empty = 0; + for(uint8_t y = 0; y < 4; y++) { + for(uint8_t x = 0; x < 4; x++) { + if(game_state->field[y][x] == 0) { + empty++; + } + } + } + + if(empty == 0) { + return false; + } + + if(empty == 1) { + // If it is 1 move before losing, we help the player and get rid of randomness. + for(uint8_t y = 0; y < 4; y++) { + for(uint8_t x = 0; x < 4; x++) { + if(game_state->field[y][x] == 0) { + bool haveFour = + // +----X + // | + // | field[x][y], 0 <= x, y <= 3 + // Y + + // up == 4 or + (y > 0 && game_state->field[y - 1][x] == 2) || + // right == 4 or + (x < 3 && game_state->field[y][x + 1] == 2) || + // down == 4 + (y < 3 && game_state->field[y + 1][x] == 2) || + // left == 4 + (x > 0 && game_state->field[y][x - 1] == 2); + + if(haveFour) { + game_state->field[y][x] = 2; + return true; + } + + game_state->field[y][x] = 1; + return true; + } + } + } + } + + uint8_t target = rand() % empty; + uint8_t twoOrFore = rand() % 4 < 3; + for(uint8_t y = 0; y < 4; y++) { + for(uint8_t x = 0; x < 4; x++) { + if(game_state->field[y][x] == 0) { + if(target == 0) { + if(twoOrFore) { + game_state->field[y][x] = 1; // 2^1 == 2 75% + } else { + game_state->field[y][x] = 2; // 2^2 == 4 25% + } + goto exit; + } + target--; + } + } + } +exit: + return true; +} + +// static void game_2048_process_row(uint8_t before[4], uint8_t *(after[4])) { +// // move 1 row left. +// for(uint8_t i = 0; i <= 2; i++) { +// if(before[i] != 0 && before[i] == before[i + 1]) { +// before[i]++; +// before[i + 1] = 0; +// i++; +// } +// } +// for(uint8_t i = 0, j = 0; i <= 3; i++) { +// if (before[i] != 0) { +// before[j] = before[i]; +// i++; +// } +// } +// } + +static void game_2048_process_move(GameState* const game_state) { + memset(game_state->next_field, 0, sizeof(game_state->next_field)); + // +----X + // | + // | field[x][y], 0 <= x, y <= 3 + // Y + + // up + if(game_state->direction == DirectionUp) { + for(uint8_t x = 0; x < 4; x++) { + uint8_t next_y = 0; + for(int8_t y = 0; y < 4; y++) { + uint8_t field = game_state->field[y][x]; + if(field == 0) { + continue; + } + + if(game_state->next_field[next_y][x] == 0) { + game_state->next_field[next_y][x] = field; + continue; + } + + if(field == game_state->next_field[next_y][x]) { + game_state->next_field[next_y][x]++; + game_state->score.gameScore += pow(2, game_state->next_field[next_y][x]); + /*if(game_state->next_field[next_y][x] == 11 && !game_state->debug) { + DOLPHIN_DEED(getRandomDeed()); + } // get some xp for making a 2048 tile*/ + next_y++; + continue; + } + + next_y++; + game_state->next_field[next_y][x] = field; + } + } + } + + // right + if(game_state->direction == DirectionRight) { + for(uint8_t y = 0; y < 4; y++) { + uint8_t next_x = 3; + for(int8_t x = 3; x >= 0; x--) { + uint8_t field = game_state->field[y][x]; + if(field == 0) { + continue; + } + + if(game_state->next_field[y][next_x] == 0) { + game_state->next_field[y][next_x] = field; + continue; + } + + if(field == game_state->next_field[y][next_x]) { + game_state->next_field[y][next_x]++; + game_state->score.gameScore += pow(2, game_state->next_field[y][next_x]); + /*if(game_state->next_field[y][next_x] == 11 && !game_state->debug) { + DOLPHIN_DEED(getRandomDeed()); + } // get some xp for making a 2048 tile*/ + next_x--; + continue; + } + + next_x--; + game_state->next_field[y][next_x] = field; + } + } + } + + // down + if(game_state->direction == DirectionDown) { + for(uint8_t x = 0; x < 4; x++) { + uint8_t next_y = 3; + for(int8_t y = 3; y >= 0; y--) { + uint8_t field = game_state->field[y][x]; + if(field == 0) { + continue; + } + + if(game_state->next_field[next_y][x] == 0) { + game_state->next_field[next_y][x] = field; + continue; + } + + if(field == game_state->next_field[next_y][x]) { + game_state->next_field[next_y][x]++; + game_state->score.gameScore += pow(2, game_state->next_field[next_y][x]); + /*if(game_state->next_field[next_y][x] == 11 && !game_state->debug) { + DOLPHIN_DEED(getRandomDeed()); + } // get some xp for making a 2048 tile*/ + next_y--; + continue; + } + + next_y--; + game_state->next_field[next_y][x] = field; + } + } + } + + // 0, 0, 1, 1 + // 1, 0, 0, 0 + + // left + if(game_state->direction == DirectionLeft) { + for(uint8_t y = 0; y < 4; y++) { + uint8_t next_x = 0; + for(uint8_t x = 0; x < 4; x++) { + uint8_t field = game_state->field[y][x]; + if(field == 0) { + continue; + } + + if(game_state->next_field[y][next_x] == 0) { + game_state->next_field[y][next_x] = field; + continue; + } + + if(field == game_state->next_field[y][next_x]) { + game_state->next_field[y][next_x]++; + game_state->score.gameScore += pow(2, game_state->next_field[y][next_x]); + /*if(game_state->next_field[y][next_x] == 11 && !game_state->debug) { + DOLPHIN_DEED(getRandomDeed()); + } // get some xp for making a 2048 tile*/ + next_x++; + continue; + } + + next_x++; + game_state->next_field[y][next_x] = field; + } + } + } + + // + game_state->direction = DirectionIdle; + memcpy(game_state->field, game_state->next_field, sizeof(game_state->field)); + // +} + +static void game_2048_restart(GameState* const game_state) { + game_state->debug = DEBUG; + + // check score + if(game_state->score.gameScore > game_state->score.highScore) { + game_state->score.highScore = game_state->score.gameScore; + } + + // clear all cells + for(uint8_t y = 0; y < 4; y++) { + for(uint8_t x = 0; x < 4; x++) { + game_state->field[y][x] = 0; + } + } + + // start next game + game_state->score.gameScore = 0; + game_2048_set_new_number(game_state); + game_2048_set_new_number(game_state); +} + +int32_t game_2048_app(void* p) { + UNUSED(p); + int32_t return_code = 0; + + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + GameState* game_state = malloc(sizeof(GameState)); + + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, game_state, sizeof(GameState))) { + return_code = 255; + goto free_and_exit; + } + + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set( + view_port, (ViewPortDrawCallback)game_2048_render_callback, &state_mutex); + view_port_input_callback_set( + view_port, (ViewPortInputCallback)game_2048_input_callback, event_queue); + + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + game_state->direction = DirectionIdle; + game_2048_restart(game_state); + + if(game_state->debug) { + game_state->field[0][0] = 0; + game_state->field[0][1] = 0; + game_state->field[0][2] = 0; + game_state->field[0][3] = 0; + + game_state->field[1][0] = 1; + game_state->field[1][1] = 2; + game_state->field[1][2] = 3; + game_state->field[1][3] = 4; + + game_state->field[2][0] = 5; + game_state->field[2][1] = 6; + game_state->field[2][2] = 7; + game_state->field[2][3] = 8; + + game_state->field[3][0] = 9; + game_state->field[3][1] = 10; + game_state->field[3][2] = 11; + game_state->field[3][3] = 12; + } + + InputEvent event; + for(bool loop = true; loop;) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); + GameState* game_state = (GameState*)acquire_mutex_block(&state_mutex); + + if(event_status == FuriStatusOk) { + if(event.type == InputTypeShort) { + switch(event.key) { + case InputKeyUp: + game_state->direction = DirectionUp; + game_2048_process_move(game_state); + game_2048_set_new_number(game_state); + break; + case InputKeyDown: + game_state->direction = DirectionDown; + game_2048_process_move(game_state); + game_2048_set_new_number(game_state); + break; + case InputKeyRight: + game_state->direction = DirectionRight; + game_2048_process_move(game_state); + game_2048_set_new_number(game_state); + break; + case InputKeyLeft: + game_state->direction = DirectionLeft; + game_2048_process_move(game_state); + game_2048_set_new_number(game_state); + break; + case InputKeyOk: + game_state->direction = DirectionIdle; + break; + case InputKeyBack: + loop = false; + break; + default: + break; + } + } else if(event.type == InputTypeLong) { + if(event.key == InputKeyOk) { + game_state->direction = DirectionIdle; + game_2048_restart(game_state); + } + } + } + + view_port_update(view_port); + release_mutex(&state_mutex, game_state); + } + + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + furi_record_close(RECORD_GUI); + view_port_free(view_port); + delete_mutex(&state_mutex); + +free_and_exit: + free(game_state); + furi_message_queue_free(event_queue); + + return return_code; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/game_of_life/application.fam b/Applications/Official/DEV_FW/source/xMasterX/game_of_life/application.fam new file mode 100644 index 000000000..bc254500b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/game_of_life/application.fam @@ -0,0 +1,12 @@ +App( + appid="GameOfLife", + name="Game of Life", + apptype=FlipperAppType.EXTERNAL, + entry_point="game_of_life_app", + cdefines=["APP_GAMEOFLIFE_GAME"], + requires=["gui"], + stack_size=2 * 1024, + order=110, + fap_icon="golIcon.png", + fap_category="Games_Extra", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/game_of_life/game_of_life.c b/Applications/Official/DEV_FW/source/xMasterX/game_of_life/game_of_life.c new file mode 100644 index 000000000..65be8cb72 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/game_of_life/game_of_life.c @@ -0,0 +1,160 @@ +#include +#include + +#include +#include + +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 64 +#define TOTAL_PIXELS SCREEN_WIDTH* SCREEN_HEIGHT + +typedef enum { + EventTypeTick, + EventTypeKey, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} AppEvent; + +typedef struct { + bool revive; + int evo; +} State; + +unsigned char new[TOTAL_PIXELS] = {}; +unsigned char old[TOTAL_PIXELS] = {}; +unsigned char* fields[] = {new, old}; + +int current = 0; +int next = 1; + +unsigned char get_cell(int x, int y) { + if(x <= 0 || x >= SCREEN_WIDTH) return 0; + if(y <= 0 || y >= SCREEN_HEIGHT) return 0; + + int pix = (y * SCREEN_WIDTH) + x; + return fields[current][pix]; +} + +int count_neightbors(int x, int y) { + return get_cell(x + 1, y - 1) + get_cell(x - 1, y - 1) + get_cell(x - 1, y + 1) + + get_cell(x + 1, y + 1) + get_cell(x + 1, y) + get_cell(x - 1, y) + get_cell(x, y - 1) + + get_cell(x, y + 1); +} + +static void update_field(State* state) { + if(state->revive) { + for(int i = 0; i < TOTAL_PIXELS; ++i) { + if((random() % 100) == 1) { + fields[current][i] = 1; + } + state->revive = false; + } + } + + for(int i = 0; i < TOTAL_PIXELS; ++i) { + int x = i % SCREEN_WIDTH; + int y = (int)(i / SCREEN_WIDTH); + + int v = get_cell(x, y); + int n = count_neightbors(x, y); + + if(v && n == 3) { + ++state->evo; + } else if(v && (n < 2 || n > 3)) { + ++state->evo; + v = 0; + } else if(!v && n == 3) { + ++state->evo; + v = 1; + } + + fields[next][i] = v; + } + + next ^= current; + current ^= next; + next ^= current; + + if(state->evo < TOTAL_PIXELS) { + state->revive = true; + state->evo = 0; + } +} + +static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { + furi_assert(event_queue); + + AppEvent event = {.type = EventTypeKey, .input = *input_event}; + furi_message_queue_put(event_queue, &event, 0); +} + +static void render_callback(Canvas* canvas, void* ctx) { + State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25); + canvas_clear(canvas); + + for(int i = 0; i < TOTAL_PIXELS; ++i) { + int x = i % SCREEN_WIDTH; + int y = (int)(i / SCREEN_WIDTH); + if(fields[current][i] == 1) canvas_draw_dot(canvas, x, y); + } + release_mutex((ValueMutex*)ctx, state); +} + +int32_t game_of_life_app(void* p) { + UNUSED(p); + srand(DWT->CYCCNT); + + FuriMessageQueue* event_queue = furi_message_queue_alloc(1, sizeof(AppEvent)); + furi_check(event_queue); + + State* _state = malloc(sizeof(State)); + + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, _state, sizeof(State))) { + printf("cannot create mutex\r\n"); + furi_message_queue_free(event_queue); + free(_state); + return 255; + } + + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, render_callback, &state_mutex); + view_port_input_callback_set(view_port, input_callback, event_queue); + + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + AppEvent event; + for(bool processing = true; processing;) { + State* state = (State*)acquire_mutex_block(&state_mutex); + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 25); + + if(event_status == FuriStatusOk && event.type == EventTypeKey && + event.input.type == InputTypePress) { + if(event.input.key == InputKeyBack) { + // furiac_exit(NULL); + processing = false; + release_mutex(&state_mutex, state); + break; + } + } + + update_field(state); + + view_port_update(view_port); + release_mutex(&state_mutex, state); + } + + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + furi_record_close(RECORD_GUI); + view_port_free(view_port); + furi_message_queue_free(event_queue); + delete_mutex(&state_mutex); + free(_state); + + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/game_of_life/golIcon.png b/Applications/Official/DEV_FW/source/xMasterX/game_of_life/golIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..df14f812c2d4bd216dfb21ffc46b47813ce58cf0 GIT binary patch literal 1921 zcmcIlO>g5w7F}B;J zJs{W{r|*oVjpALgEh~mDh2S4N~dmLZoCq^33yoJ@3pX2m24# z*WOrD6lJ~LY97Lv&)04&!|ykLZa#%!DLs6+r9As-;}2N8(rtJRMfvLKtAEoKSg#)J zb#^W)Y=%HRN^e$n>xmZ;M{ox=6&Mi~SC}IAIRgHXp37)kZEb3`9oN z(V!ot?x?PfiCviI+q$NXA=yb?YvdNyWA8xSmWfd95gy`7P zjWRN9w_>?QMV)*!u&1iEga__nb9Z77R&}kHWwER4!{M+rESF@`)eXmSbWC(Y5Fk)` z9%XcdqV!%tGNEaTlqF%Dg)&leTI$QwtgeB}MJ$7O#vP@TghA@`5sh`Dg!9;@K+n4# zIvC8*X|{6)RwhngNt|}hW1%04RGubG?3{@xyEio!_hcs1p8OBrW`F<7L(XOfAQgB4{R)j+Fgr#SW$xRZ=dQ>RU%)#N{x(pL;YpAeuB2buF(R z!VWUbj$ygjbj##zTy`-opdJW<(~K?#mOKp37lC@7+m6zVMohGubq$;SDHE2!#JIC4x}Mzm}MwqbIcRoK`sINy})G|xnSzR)k13^-=lbS;DUhEIG{wJd>5 z8`!F5U?M^sUzi33W7d@I-6Vt_qWyW++$#=@f>dqG5ENmzcFUT|nH$JtKtVs@fOdr*N8PEULDXObf@y^*RPcP(QkwZ-ctV^7;#|O}4`;61!Lk1?{jWfb<$&6tGkV*^nlp(S;(sTzC2c zfu!{8`Y;yL$Nw2d!OeO!>I%4Np#$dwtLgcjG+(uveszIsFXS?nTmzaRS3x?Lsj&*S zXm@UFrh*4keNtNH4q+78R<(>AQn67rz&>I;Ae`6+vjeN}tRK!16m$>+Czyn#RZZ27tR^Glnz5nDN_OLgi literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/ifttt/application.fam b/Applications/Official/DEV_FW/source/xMasterX/ifttt/application.fam new file mode 100644 index 000000000..141929645 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ifttt/application.fam @@ -0,0 +1,14 @@ +App( + appid="ESP8266_IFTTT_Virtual_Button", + name="[ESP] IFTTT Button", + apptype=FlipperAppType.EXTERNAL, + entry_point="ifttt_virtual_button_app", + cdefines=["APP_IFTTT_VIRTUAL_BUTTON"], + requires=[ + "gui", + ], + stack_size=2 * 1024, + order=20, + fap_icon="icon.png", + fap_category="GPIO_Extra", +) \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/ifttt/icon.png b/Applications/Official/DEV_FW/source/xMasterX/ifttt/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f6d586b381030275e4cefb9bfec2d8b3e9b4e0ba GIT binary patch literal 1762 zcmcIlPl)4G7|);%>kQ*zMHc_SWU?MsG|kIvn>3+u=}c$01v5KL3p>kR_T}ZJjnm}C zBs1*{9zEWy&t8NDFCwlYd+@p{vKJ4s=z=UFF5Xsz@k`Uz9>%d33vKe!-}n2z z-}f(XZ*E*%T6ktb5QL>>qrL^#?0(_YJp3NwZ@z@fT(Wg>Rk(5cx%+TF;QV;hxRMCM=`{P!{pc+Z1Y!P3zrCGq+pn0E2LGzvoNuuvs(&e&^>}ZX3{l-DeS_d0#day$cS33Xl(n57$0z<%3A`XIHn3w}g z8WNjupFLJ2aR^CwEUA`x6u0e7agE1J)Cx$Z2w_n-3aVBrRVpuu7-6I!T~U#Yv57RZ zTogwi3EYWdHFiC7tA1hR4o;TTP1DF!lzzWo=obq-?kK8Z7z)A)#xfw}WIs&FKn|0$ zImw8o&Jr5?QR?$h%xH#})3ak|E}hs$yK!$Q*QE;Uu>fER1g1`0MO~iqq|5(B z$K>ycn#f#>8A*BE=Das9*yfl;#JGUObC>yY%$dJ`i8y8L0 zFw6KwR5TIFp*Hk`OHwi$n7h8WKMT~h&1RUSB&4iawLn~YSa)Tj z7AZ!W%7~V$1hz}D40A~*(j@J%xIZ8lIT*? z<8eTsPyB#%m=c8@N&F|8HQwW~&0WZOaop0-)Zhf%H~a)DxIY}1e0GLI(_*hpJsOQb z&liXNXcC%@fhEzb{>+s|kNsm3JDY@@w%=tydO~01u!MVQpTw-zfg=2O-zhT)Nyy&G zGG^XBPVM^|n(KK$UV@2#}^{>l$uocYf6E-BvE zXP&<||Jj~>tJYfl<@2lS&$d23TwQta^rv^1uYUXM>(~F>dG(`}dv`8ee`w!bd}6u! a)7(?H&7save_ssid); + flipper_format_write_comment_cstr(file, "Enter here the PASSWORD of the wifi network"); + flipper_format_write_string_cstr(file, CONF_PASSWORD, settings->save_password); + flipper_format_write_comment_cstr(file, "Enter here the WEBHOOKS of your IFTTT account"); + flipper_format_write_string_cstr(file, CONF_KEY, settings->save_key); + flipper_format_write_comment_cstr(file, "Enter here the EVENT name of your trigger"); + flipper_format_write_string_cstr(file, CONF_EVENT, settings->save_event); +} + +Settings* load_settings() { + Settings* settings = malloc(sizeof(Settings)); + + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* file = flipper_format_file_alloc(storage); + + FuriString* string_value; + string_value = furi_string_alloc(); + FuriString* text_ssid_value; + text_ssid_value = furi_string_alloc(); + FuriString* text_password_value; + text_password_value = furi_string_alloc(); + FuriString* text_key_value; + text_key_value = furi_string_alloc(); + FuriString* text_event_value; + text_event_value = furi_string_alloc(); + + if(storage_common_stat(storage, CONFIG_FILE_PATH, NULL) != FSE_OK) { + if(!flipper_format_file_open_new(file, CONFIG_FILE_PATH)) { + flipper_format_file_close(file); + } else { + settings->save_ssid = malloc(1); + settings->save_password = malloc(1); + settings->save_key = malloc(1); + settings->save_event = malloc(1); + + settings->save_ssid[0] = '\0'; + settings->save_password[0] = '\0'; + settings->save_key[0] = '\0'; + settings->save_event[0] = '\0'; + + save_settings_file(file, settings); + flipper_format_file_close(file); + } + } else { + if(!flipper_format_file_open_existing(file, CONFIG_FILE_PATH)) { + flipper_format_file_close(file); + } else { + uint32_t value; + if(!flipper_format_read_header(file, string_value, &value)) { + } else { + if(flipper_format_read_string(file, CONF_SSID, text_ssid_value)) { + settings->save_ssid = malloc(furi_string_size(text_ssid_value) + 1); + strcpy(settings->save_ssid, furi_string_get_cstr(text_ssid_value)); + } + if(flipper_format_read_string(file, CONF_PASSWORD, text_password_value)) { + settings->save_password = malloc(furi_string_size(text_password_value) + 1); + strcpy(settings->save_password, furi_string_get_cstr(text_password_value)); + } + if(flipper_format_read_string(file, CONF_KEY, text_key_value)) { + settings->save_key = malloc(furi_string_size(text_key_value) + 1); + strcpy(settings->save_key, furi_string_get_cstr(text_key_value)); + } + if(flipper_format_read_string(file, CONF_EVENT, text_event_value)) { + settings->save_event = malloc(furi_string_size(text_event_value) + 1); + strcpy(settings->save_event, furi_string_get_cstr(text_event_value)); + } + } + flipper_format_file_close(file); + } + } + + furi_string_free(text_ssid_value); + furi_string_free(text_password_value); + furi_string_free(text_key_value); + furi_string_free(text_event_value); + flipper_format_free(file); + furi_record_close(RECORD_STORAGE); + return settings; +} + +void send_serial_command_config(ESerialCommand command, Settings* settings) { + uint8_t data[1] = {0}; + + char config_tmp[100]; + strcpy(config_tmp, "config,"); + strcat(config_tmp, settings->save_key); + char config_tmp2[5]; + strcpy(config_tmp2, config_tmp); + strcat(config_tmp2, ","); + char config_tmp3[100]; + strcpy(config_tmp3, config_tmp2); + strcat(config_tmp3, settings->save_ssid); + char config_tmp4[5]; + strcpy(config_tmp4, config_tmp3); + strcat(config_tmp4, ","); + char config_tmp5[100]; + strcpy(config_tmp5, config_tmp4); + strcat(config_tmp5, settings->save_password); + char config_tmp6[5]; + strcpy(config_tmp6, config_tmp5); + strcat(config_tmp6, ","); + char config[350]; + strcpy(config, config_tmp6); + strcat(config, settings->save_event); + + int length = strlen(config); + for(int i = 0; i < length; i++) { + switch(command) { + case ESerialCommand_Config: + data[0] = config[i]; + break; + default: + return; + }; + + furi_hal_uart_tx(FuriHalUartIdUSART1, data, 1); + } +} + +static bool ifttt_virtual_button_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + VirtualButtonApp* app = context; + return scene_manager_handle_custom_event(app->scene_manager, event); +} + +static bool ifttt_virtual_button_back_event_callback(void* context) { + furi_assert(context); + VirtualButtonApp* app = context; + return scene_manager_handle_back_event(app->scene_manager); +} + +static void ifttt_virtual_button_tick_event_callback(void* context) { + furi_assert(context); + VirtualButtonApp* app = context; + scene_manager_handle_tick_event(app->scene_manager); +} + +VirtualButtonApp* ifttt_virtual_button_app_alloc(uint32_t first_scene) { + VirtualButtonApp* app = malloc(sizeof(VirtualButtonApp)); + + // Records + app->gui = furi_record_open(RECORD_GUI); + app->power = furi_record_open(RECORD_POWER); + + // View dispatcher + app->view_dispatcher = view_dispatcher_alloc(); + app->scene_manager = scene_manager_alloc(&virtual_button_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, ifttt_virtual_button_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + app->view_dispatcher, ifttt_virtual_button_back_event_callback); + view_dispatcher_set_tick_event_callback( + app->view_dispatcher, ifttt_virtual_button_tick_event_callback, 2000); + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + // Views + app->sen_view = send_view_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, VirtualButtonAppViewSendView, send_view_get_view(app->sen_view)); + + app->abou_view = about_view_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, VirtualButtonAppViewAboutView, about_view_get_view(app->abou_view)); + + app->submenu = submenu_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, VirtualButtonAppViewSubmenu, submenu_get_view(app->submenu)); + app->dialog = dialog_ex_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, VirtualButtonAppViewDialog, dialog_ex_get_view(app->dialog)); + + // Set first scene + scene_manager_next_scene(app->scene_manager, first_scene); + return app; +} + +void ifttt_virtual_button_app_free(VirtualButtonApp* app) { + furi_assert(app); + + free(app->settings.save_ssid); + free(app->settings.save_password); + free(app->settings.save_key); + + // Views + view_dispatcher_remove_view(app->view_dispatcher, VirtualButtonAppViewSendView); + send_view_free(app->sen_view); + view_dispatcher_remove_view(app->view_dispatcher, VirtualButtonAppViewAboutView); + about_view_free(app->abou_view); + view_dispatcher_remove_view(app->view_dispatcher, VirtualButtonAppViewSubmenu); + submenu_free(app->submenu); + view_dispatcher_remove_view(app->view_dispatcher, VirtualButtonAppViewDialog); + dialog_ex_free(app->dialog); + // View dispatcher + view_dispatcher_free(app->view_dispatcher); + scene_manager_free(app->scene_manager); + // Records + furi_record_close(RECORD_POWER); + furi_record_close(RECORD_GUI); + + free(app); +} + +int32_t ifttt_virtual_button_app(void* p) { + UNUSED(p); + + Storage* storage = furi_record_open(RECORD_STORAGE); + if(!storage_simply_mkdir(storage, IFTTT_FOLDER)) { + } + if(!storage_simply_mkdir(storage, IFTTT_CONFIG_FOLDER)) { + } + furi_record_close(RECORD_STORAGE); + + uint32_t first_scene = VirtualButtonAppSceneStart; + VirtualButtonApp* app = ifttt_virtual_button_app_alloc(first_scene); + memcpy(&app->settings, load_settings(), sizeof(Settings)); + send_serial_command_config(ESerialCommand_Config, &(app->settings)); + + view_dispatcher_run(app->view_dispatcher); + ifttt_virtual_button_app_free(app); + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/ifttt/ifttt_virtual_button.h b/Applications/Official/DEV_FW/source/xMasterX/ifttt/ifttt_virtual_button.h new file mode 100644 index 000000000..563f5cd95 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ifttt/ifttt_virtual_button.h @@ -0,0 +1,56 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include "views/send_view.h" +#include "views/about_view.h" +#include +#include +#include +#include +#include +#include +#include "scenes/virtual_button_scene.h" + +#define APP_NAME "[ESP8266] IFTTT Virtual Button" + +#define CONF_SSID "wifi_ssid" +#define CONF_PASSWORD "wifi_password" +#define CONF_KEY "webhooks_key" +#define CONF_EVENT "event" +#define CONFIG_FILE_HEADER "IFTTT Virtual Button Config File" +#define CONFIG_FILE_VERSION 1 + +typedef struct { + char* save_ssid; + char* save_password; + char* save_key; + char* save_event; +} Settings; + +typedef struct { + Power* power; + Gui* gui; + SceneManager* scene_manager; + ViewDispatcher* view_dispatcher; + SendView* sen_view; + AboutView* abou_view; + Submenu* submenu; + DialogEx* dialog; + PowerInfo info; + Settings settings; +} VirtualButtonApp; + +typedef enum { + VirtualButtonAppViewSendView, + VirtualButtonAppViewAboutView, + VirtualButtonAppViewSubmenu, + VirtualButtonAppViewDialog, +} VirtualButtonAppView; + +Settings save_settings(Settings settings); +Settings* load_settings(); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene.c b/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene.c new file mode 100644 index 000000000..a75d822fc --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene.c @@ -0,0 +1,30 @@ +#include "virtual_button_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const virtual_button_on_enter_handlers[])(void*) = { +#include "virtual_button_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 virtual_button_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "virtual_button_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 virtual_button_on_exit_handlers[])(void* context) = { +#include "virtual_button_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers virtual_button_scene_handlers = { + .on_enter_handlers = virtual_button_on_enter_handlers, + .on_event_handlers = virtual_button_on_event_handlers, + .on_exit_handlers = virtual_button_on_exit_handlers, + .scene_num = VirtualButtonAppSceneNum, +}; diff --git a/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene.h b/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene.h new file mode 100644 index 000000000..870807dee --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) VirtualButtonAppScene##id, +typedef enum { +#include "virtual_button_scene_config.h" + VirtualButtonAppSceneNum, +} VirtualButtonAppScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers virtual_button_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "virtual_button_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 "virtual_button_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 "virtual_button_scene_config.h" +#undef ADD_SCENE diff --git a/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene_about.c b/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene_about.c new file mode 100644 index 000000000..86fe1a9d0 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene_about.c @@ -0,0 +1,26 @@ +#include "../ifttt_virtual_button.h" + +static void virtual_button_scene_about_view_update_model(VirtualButtonApp* app) { + power_get_info(app->power, &app->info); +} + +void virtual_button_scene_about_view_on_enter(void* context) { + VirtualButtonApp* app = context; + virtual_button_scene_about_view_update_model(app); + view_dispatcher_switch_to_view(app->view_dispatcher, VirtualButtonAppViewAboutView); +} + +bool virtual_button_scene_about_view_on_event(void* context, SceneManagerEvent event) { + VirtualButtonApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeTick) { + virtual_button_scene_about_view_update_model(app); + consumed = true; + } + return consumed; +} + +void virtual_button_scene_about_view_on_exit(void* context) { + UNUSED(context); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene_config.h b/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene_config.h new file mode 100644 index 000000000..70af5ccf7 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene_config.h @@ -0,0 +1,3 @@ +ADD_SCENE(virtual_button, start, Start) +ADD_SCENE(virtual_button, send_view, SendView) +ADD_SCENE(virtual_button, about_view, AboutView) diff --git a/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene_send.c b/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene_send.c new file mode 100644 index 000000000..caa23fadf --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene_send.c @@ -0,0 +1,26 @@ +#include "../ifttt_virtual_button.h" + +static void virtual_button_scene_send_view_update_model(VirtualButtonApp* app) { + power_get_info(app->power, &app->info); +} + +void virtual_button_scene_send_view_on_enter(void* context) { + VirtualButtonApp* app = context; + virtual_button_scene_send_view_update_model(app); + view_dispatcher_switch_to_view(app->view_dispatcher, VirtualButtonAppViewSendView); +} + +bool virtual_button_scene_send_view_on_event(void* context, SceneManagerEvent event) { + VirtualButtonApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeTick) { + virtual_button_scene_send_view_update_model(app); + consumed = true; + } + return consumed; +} + +void virtual_button_scene_send_view_on_exit(void* context) { + UNUSED(context); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene_start.c b/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene_start.c new file mode 100644 index 000000000..6b03a35f0 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ifttt/scenes/virtual_button_scene_start.c @@ -0,0 +1,55 @@ +#include "../ifttt_virtual_button.h" + +enum VirtualButtonSubmenuIndex { + VirtualButtonSubmenuIndexSendView, + VirtualButtonSubmenuIndexAboutView, +}; + +static void virtual_button_scene_start_submenu_callback(void* context, uint32_t index) { + furi_assert(context); + VirtualButtonApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void virtual_button_scene_start_on_enter(void* context) { + VirtualButtonApp* app = context; + Submenu* submenu = app->submenu; + + submenu_add_item( + submenu, + "Send IFTTT command", + VirtualButtonSubmenuIndexSendView, + virtual_button_scene_start_submenu_callback, + app); + submenu_add_item( + submenu, + "About", + VirtualButtonSubmenuIndexAboutView, + virtual_button_scene_start_submenu_callback, + app); + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(app->scene_manager, VirtualButtonAppSceneStart)); + + view_dispatcher_switch_to_view(app->view_dispatcher, VirtualButtonAppViewSubmenu); +} + +bool virtual_button_scene_start_on_event(void* context, SceneManagerEvent event) { + VirtualButtonApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == VirtualButtonSubmenuIndexSendView) { + scene_manager_next_scene(app->scene_manager, VirtualButtonAppSceneSendView); + } else if(event.event == VirtualButtonSubmenuIndexAboutView) { + scene_manager_next_scene(app->scene_manager, VirtualButtonAppSceneAboutView); + } + scene_manager_set_scene_state(app->scene_manager, VirtualButtonAppSceneStart, event.event); + consumed = true; + } + return consumed; +} + +void virtual_button_scene_start_on_exit(void* context) { + VirtualButtonApp* app = context; + submenu_reset(app->submenu); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/ifttt/views/about_view.c b/Applications/Official/DEV_FW/source/xMasterX/ifttt/views/about_view.c new file mode 100644 index 000000000..80c00883a --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ifttt/views/about_view.c @@ -0,0 +1,48 @@ +#include "about_view.h" +#include +#include +#include +#include + +struct AboutView { + View* view; +}; + +typedef struct { + bool connected; +} AboutViewModel; + +static void about_view_draw_callback(Canvas* canvas, void* context) { + furi_assert(context); + canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + canvas_draw_str_aligned(canvas, 0, 0, AlignLeft, AlignTop, "IFTTT Virtual button"); + canvas_draw_str_aligned(canvas, 0, 15, AlignLeft, AlignTop, "Version 0.2"); + canvas_draw_str_aligned(canvas, 0, 50, AlignLeft, AlignTop, "press back"); +} + +AboutView* about_view_alloc() { + AboutView* about_view = malloc(sizeof(AboutView)); + about_view->view = view_alloc(); + view_set_context(about_view->view, about_view); + view_allocate_model(about_view->view, ViewModelTypeLocking, sizeof(AboutViewModel)); + view_set_draw_callback(about_view->view, about_view_draw_callback); + return about_view; +} + +void about_view_free(AboutView* about_view) { + furi_assert(about_view); + view_free(about_view->view); + free(about_view); +} + +View* about_view_get_view(AboutView* about_view) { + furi_assert(about_view); + return about_view->view; +} + +void about_view_set_data(AboutView* about_view, bool connected) { + furi_assert(about_view); + with_view_model( + about_view->view, AboutViewModel * model, { model->connected = connected; }, true); +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/ifttt/views/about_view.h b/Applications/Official/DEV_FW/source/xMasterX/ifttt/views/about_view.h new file mode 100644 index 000000000..d1ac287e3 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ifttt/views/about_view.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +typedef struct AboutView AboutView; + +AboutView* about_view_alloc(); + +void about_view_free(AboutView* about_view); + +View* about_view_get_view(AboutView* about_view); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/ifttt/views/send_view.c b/Applications/Official/DEV_FW/source/xMasterX/ifttt/views/send_view.c new file mode 100644 index 000000000..6046c39e3 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ifttt/views/send_view.c @@ -0,0 +1,137 @@ +#include "send_view.h" +#include +#include +#include +#include +#include +#include +#include + +#define FLIPPERZERO_SERIAL_BAUD 115200 + +typedef enum ESerialCommand { ESerialCommand_Send } ESerialCommand; + +struct SendView { + View* view; +}; + +typedef struct { + bool right_pressed; + bool connected; +} SendViewModel; + +static void Shake(void) { + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + notification_message(notification, &sequence_single_vibro); + furi_record_close(RECORD_NOTIFICATION); +} + +void send_serial_command_send(ESerialCommand command) { + uint8_t data[1] = {0}; + + char name[10] = "send"; + int length = strlen(name); + for(int i = 0; i < length; i++) { + switch(command) { + case ESerialCommand_Send: + data[0] = name[i]; + break; + default: + return; + }; + + furi_hal_uart_tx(FuriHalUartIdUSART1, data, 1); + } +} + +static void send_view_draw_callback(Canvas* canvas, void* context) { + furi_assert(context); + SendViewModel* model = context; + canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + canvas_draw_str_aligned(canvas, 64, 0, AlignCenter, AlignTop, "SEND MODULE"); + canvas_draw_line(canvas, 0, 10, 128, 10); + canvas_draw_str_aligned(canvas, 64, 15, AlignCenter, AlignTop, "Press right to send IFTTT"); + canvas_draw_str_aligned(canvas, 64, 25, AlignCenter, AlignTop, "command or press and hold"); + canvas_draw_str_aligned(canvas, 64, 35, AlignCenter, AlignTop, "back to return to the menu"); + + // Right + if(model->right_pressed) { + } +} + +static void send_view_process(SendView* send_view, InputEvent* event) { + with_view_model( + send_view->view, + SendViewModel * model, + { + if(event->type == InputTypePress) { + if(event->key == InputKeyUp) { + } else if(event->key == InputKeyDown) { + } else if(event->key == InputKeyLeft) { + } else if(event->key == InputKeyRight) { + model->right_pressed = true; + Shake(); + send_serial_command_send(ESerialCommand_Send); + } else if(event->key == InputKeyOk) { + } else if(event->key == InputKeyBack) { + } + } else if(event->type == InputTypeRelease) { + if(event->key == InputKeyUp) { + } else if(event->key == InputKeyDown) { + } else if(event->key == InputKeyLeft) { + } else if(event->key == InputKeyRight) { + model->right_pressed = false; + } else if(event->key == InputKeyOk) { + } else if(event->key == InputKeyBack) { + } + } else if(event->type == InputTypeShort) { + if(event->key == InputKeyBack) { + } + } + }, + true); +} + +static bool send_view_input_callback(InputEvent* event, void* context) { + furi_assert(context); + SendView* send_view = context; + bool consumed = false; + + if(event->type == InputTypeLong && event->key == InputKeyBack) { + } else { + send_view_process(send_view, event); + consumed = true; + } + + return consumed; +} + +SendView* send_view_alloc() { + SendView* send_view = malloc(sizeof(SendView)); + send_view->view = view_alloc(); + view_set_context(send_view->view, send_view); + view_allocate_model(send_view->view, ViewModelTypeLocking, sizeof(SendViewModel)); + view_set_draw_callback(send_view->view, send_view_draw_callback); + view_set_input_callback(send_view->view, send_view_input_callback); + furi_hal_uart_set_br(FuriHalUartIdUSART1, FLIPPERZERO_SERIAL_BAUD); + + return send_view; +} + +void send_view_free(SendView* send_view) { + furi_assert(send_view); + view_free(send_view->view); + free(send_view); +} + +View* send_view_get_view(SendView* send_view) { + furi_assert(send_view); + return send_view->view; +} + +void send_view_set_data(SendView* send_view, bool connected) { + furi_assert(send_view); + with_view_model( + send_view->view, SendViewModel * model, { model->connected = connected; }, true); +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/ifttt/views/send_view.h b/Applications/Official/DEV_FW/source/xMasterX/ifttt/views/send_view.h new file mode 100644 index 000000000..4b1944dd4 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ifttt/views/send_view.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +typedef struct SendView SendView; + +SendView* send_view_alloc(); + +void send_view_free(SendView* send_view); + +View* send_view_get_view(SendView* send_view); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/README.md b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/README.md new file mode 100644 index 000000000..f1a3161db --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/README.md @@ -0,0 +1,63 @@ +# Alternative Infrared Remote for Flipperzero + +It is a plugin like [UniversalRF Remix](https://github.com/ESurge/flipperzero-firmware-unirfremix) but for infrared files. I do this plugin for convenience, because the main IR app need to navigate for different button abit troublesome (buttons like up,down,left,right,back). I found it useful for TV and TV box. + +It supports short press and long press input for different ir remote buttons. Tested on the [unleashed firmware version unlshd-023](https://github.com/DarkFlippers/unleashed-firmware/releases/tag/unlshd-023) + + +## How to install + +1. Update unleashed firmware to the version unlshd-023, then download the `ir_remote.fap` from [releases](https://github.com/Hong5489/ir_remote/tags) + +2. Put the `ir_remote.fap` file in your flipper's SD card, under `apps` folder + +## How to use + +1. Similar to UniRF app, put the path of the ir file and the ir button for each button on flipper (UP,DOWN,LEFT,RIGHT,BACK) + +The format With `HOLD` one is long press, without is short press + +Example of the configuration file: +``` +REMOTE: /ext/infrared/Philips_32PFL4208T.ir +UP: Up +DOWN: Down +LEFT: Left +RIGHT: Right +OK: +BACK: Back +UPHOLD: VOL+ +DOWNHOLD: VOL- +LEFTHOLD: Source +RIGHTHOLD: SmartTV +OKHOLD: POWER +``` + +Leave it empty for the button you don't need + +2. Save it as `.txt` file, then create a new folder in your SD card `ir_remote`, put it inside the folder + +3. Lastly, you can open the app, choose the configuration file, then you can try out the ir for each buttons + +4. Long press back button to exit the app + +## How to build + +You can clone this repo and put it inside the `applications_user` folder, then build it with the command: +``` +./fbt fap_ir_remote +``` +Or you can build and run it on your flipper with the command: +``` +./fbt launch_app APPSRC=applications_user/ir_remote +``` + +## Screenshots + +Choose config file to map + +![image](ir.png) + +Show all button name in the config file (If empty will show N/A). Upper part short press, Lower part long press + +![image2](ir2.png) \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/application.fam b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/application.fam new file mode 100644 index 000000000..cd3f33da9 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/application.fam @@ -0,0 +1,14 @@ +App( + appid="ir_remote", + name="IR Remote", + apptype=FlipperAppType.EXTERNAL, + entry_point="infrared_remote_app", + stack_size=3 * 1024, + requires=[ + "gui", + "dialogs", + ], + fap_category="Misc_Extra", + fap_icon="ir_10px.png", + fap_icon_assets="images", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/example.txt b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/example.txt new file mode 100644 index 000000000..ffd192b8d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/example.txt @@ -0,0 +1,12 @@ +REMOTE: /ext/infrared/Philips_32PFL4208T.ir +UP: Up +DOWN: Down +LEFT: Left +RIGHT: Right +OK: +BACK: Back +UPHOLD: VOL+ +DOWNHOLD: VOL- +LEFTHOLD: Source +RIGHTHOLD: SmartTV +OKHOLD: POWER \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/ButtonDown_7x4.png b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/ButtonDown_7x4.png new file mode 100644 index 0000000000000000000000000000000000000000..2954bb6a67d1c23c0bb5d765e8d2aa04b9b5adec GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)I!3HFqj;YoHDIHH2#}J9|(o>FH3<^BV2haYO z-y5_sM4;GPjq%Ck6>60csmUj6EiNa>ORduPH4*)h!w|e3sE@(Z)z4*}Q$iC10Gods AV*mgE literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/ButtonLeft_4x7.png b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/ButtonLeft_4x7.png new file mode 100644 index 0000000000000000000000000000000000000000..0b4655d43247083aa705620e9836ac415b42ca46 GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/ButtonRight_4x7.png b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/ButtonRight_4x7.png new file mode 100644 index 0000000000000000000000000000000000000000..8e1c74c1c0038ea55172f19ac875003fc80c2d06 GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/ButtonUp_7x4.png b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/ButtonUp_7x4.png new file mode 100644 index 0000000000000000000000000000000000000000..1be79328b40a93297a5609756328406565c437c0 GIT binary patch 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- literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/Ok_btn_9x9.png b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/images/Ok_btn_9x9.png new file mode 100644 index 0000000000000000000000000000000000000000..9a1539da2049f12f7b25f96b11a9c40cd8227302 GIT binary patch literal 3605 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 +#include +#include +#include +#include +#include +#include + +#define TAG "InfraredRemote" + +ARRAY_DEF(InfraredButtonArray, InfraredRemoteButton*, M_PTR_OPLIST); + +struct InfraredRemote { + InfraredButtonArray_t buttons; + FuriString* name; + FuriString* path; +}; + +static void infrared_remote_clear_buttons(InfraredRemote* remote) { + InfraredButtonArray_it_t it; + for(InfraredButtonArray_it(it, remote->buttons); !InfraredButtonArray_end_p(it); + InfraredButtonArray_next(it)) { + infrared_remote_button_free(*InfraredButtonArray_cref(it)); + } + InfraredButtonArray_reset(remote->buttons); +} + +InfraredRemote* infrared_remote_alloc() { + InfraredRemote* remote = malloc(sizeof(InfraredRemote)); + InfraredButtonArray_init(remote->buttons); + remote->name = furi_string_alloc(); + remote->path = furi_string_alloc(); + return remote; +} + +void infrared_remote_free(InfraredRemote* remote) { + infrared_remote_clear_buttons(remote); + InfraredButtonArray_clear(remote->buttons); + furi_string_free(remote->path); + furi_string_free(remote->name); + free(remote); +} + +void infrared_remote_reset(InfraredRemote* remote) { + infrared_remote_clear_buttons(remote); + furi_string_reset(remote->name); + furi_string_reset(remote->path); +} + +void infrared_remote_set_name(InfraredRemote* remote, const char* name) { + furi_string_set(remote->name, name); +} + +const char* infrared_remote_get_name(InfraredRemote* remote) { + return furi_string_get_cstr(remote->name); +} + +void infrared_remote_set_path(InfraredRemote* remote, const char* path) { + furi_string_set(remote->path, path); +} + +const char* infrared_remote_get_path(InfraredRemote* remote) { + return furi_string_get_cstr(remote->path); +} + +size_t infrared_remote_get_button_count(InfraredRemote* remote) { + return InfraredButtonArray_size(remote->buttons); +} + +InfraredRemoteButton* infrared_remote_get_button(InfraredRemote* remote, size_t index) { + furi_assert(index < InfraredButtonArray_size(remote->buttons)); + return *InfraredButtonArray_get(remote->buttons, index); +} + +bool infrared_remote_find_button_by_name(InfraredRemote* remote, const char* name, size_t* index) { + for(size_t i = 0; i < InfraredButtonArray_size(remote->buttons); i++) { + InfraredRemoteButton* button = *InfraredButtonArray_get(remote->buttons, i); + if(!strcmp(infrared_remote_button_get_name(button), name)) { + *index = i; + return true; + } + } + return false; +} + +bool infrared_remote_add_button(InfraredRemote* remote, const char* name, InfraredSignal* signal) { + InfraredRemoteButton* button = infrared_remote_button_alloc(); + infrared_remote_button_set_name(button, name); + infrared_remote_button_set_signal(button, signal); + InfraredButtonArray_push_back(remote->buttons, button); + return infrared_remote_store(remote); +} + +bool infrared_remote_rename_button(InfraredRemote* remote, const char* new_name, size_t index) { + furi_assert(index < InfraredButtonArray_size(remote->buttons)); + InfraredRemoteButton* button = *InfraredButtonArray_get(remote->buttons, index); + infrared_remote_button_set_name(button, new_name); + return infrared_remote_store(remote); +} + +bool infrared_remote_delete_button(InfraredRemote* remote, size_t index) { + furi_assert(index < InfraredButtonArray_size(remote->buttons)); + InfraredRemoteButton* button; + InfraredButtonArray_pop_at(&button, remote->buttons, index); + infrared_remote_button_free(button); + return infrared_remote_store(remote); +} + +bool infrared_remote_store(InfraredRemote* remote) { + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* ff = flipper_format_file_alloc(storage); + const char* path = furi_string_get_cstr(remote->path); + + FURI_LOG_I(TAG, "store file: \'%s\'", path); + + bool success = flipper_format_file_open_always(ff, path) && + flipper_format_write_header_cstr(ff, "IR signals file", 1); + if(success) { + InfraredButtonArray_it_t it; + for(InfraredButtonArray_it(it, remote->buttons); !InfraredButtonArray_end_p(it); + InfraredButtonArray_next(it)) { + InfraredRemoteButton* button = *InfraredButtonArray_cref(it); + success = infrared_signal_save( + infrared_remote_button_get_signal(button), + ff, + infrared_remote_button_get_name(button)); + if(!success) { + break; + } + } + } + + flipper_format_free(ff); + furi_record_close(RECORD_STORAGE); + return success; +} + +bool infrared_remote_load(InfraredRemote* remote, FuriString* path) { + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* ff = flipper_format_buffered_file_alloc(storage); + + FuriString* buf; + buf = furi_string_alloc(); + + FURI_LOG_I(TAG, "load file: \'%s\'", furi_string_get_cstr(path)); + bool success = flipper_format_buffered_file_open_existing(ff, furi_string_get_cstr(path)); + + if(success) { + uint32_t version; + success = flipper_format_read_header(ff, buf, &version) && + !furi_string_cmp(buf, "IR signals file") && (version == 1); + } + + if(success) { + path_extract_filename(path, buf, true); + infrared_remote_clear_buttons(remote); + infrared_remote_set_name(remote, furi_string_get_cstr(buf)); + infrared_remote_set_path(remote, furi_string_get_cstr(path)); + + for(bool can_read = true; can_read;) { + InfraredRemoteButton* button = infrared_remote_button_alloc(); + can_read = infrared_signal_read(infrared_remote_button_get_signal(button), ff, buf); + if(can_read) { + infrared_remote_button_set_name(button, furi_string_get_cstr(buf)); + InfraredButtonArray_push_back(remote->buttons, button); + } else { + infrared_remote_button_free(button); + } + } + } + + furi_string_free(buf); + flipper_format_free(ff); + furi_record_close(RECORD_STORAGE); + return success; +} + +bool infrared_remote_remove(InfraredRemote* remote) { + Storage* storage = furi_record_open(RECORD_STORAGE); + + FS_Error status = storage_common_remove(storage, furi_string_get_cstr(remote->path)); + infrared_remote_reset(remote); + + furi_record_close(RECORD_STORAGE); + return (status == FSE_OK || status == FSE_NOT_EXIST); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote.h b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote.h new file mode 100644 index 000000000..6eac193d3 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +#include "infrared_remote_button.h" + +typedef struct InfraredRemote InfraredRemote; + +InfraredRemote* infrared_remote_alloc(); +void infrared_remote_free(InfraredRemote* remote); +void infrared_remote_reset(InfraredRemote* remote); + +void infrared_remote_set_name(InfraredRemote* remote, const char* name); +const char* infrared_remote_get_name(InfraredRemote* remote); + +void infrared_remote_set_path(InfraredRemote* remote, const char* path); +const char* infrared_remote_get_path(InfraredRemote* remote); + +size_t infrared_remote_get_button_count(InfraredRemote* remote); +InfraredRemoteButton* infrared_remote_get_button(InfraredRemote* remote, size_t index); +bool infrared_remote_find_button_by_name(InfraredRemote* remote, const char* name, size_t* index); + +bool infrared_remote_add_button(InfraredRemote* remote, const char* name, InfraredSignal* signal); +bool infrared_remote_rename_button(InfraredRemote* remote, const char* new_name, size_t index); +bool infrared_remote_delete_button(InfraredRemote* remote, size_t index); + +bool infrared_remote_store(InfraredRemote* remote); +bool infrared_remote_load(InfraredRemote* remote, FuriString* path); +bool infrared_remote_remove(InfraredRemote* remote); diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote_app.c b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote_app.c new file mode 100644 index 000000000..93105a8b2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote_app.c @@ -0,0 +1,532 @@ +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "infrared_signal.h" +#include "infrared_remote.h" +#include "infrared_remote_button.h" +#define TAG "ir_remote" + +#include + +typedef struct { + int status; + ViewPort* view_port; + FuriString* up_button; + FuriString* down_button; + FuriString* left_button; + FuriString* right_button; + FuriString* ok_button; + FuriString* back_button; + FuriString* up_hold_button; + FuriString* down_hold_button; + FuriString* left_hold_button; + FuriString* right_hold_button; + FuriString* ok_hold_button; +} IRApp; + +// Screen is 128x64 px +static void app_draw_callback(Canvas* canvas, void* ctx) { + // Show config is incorrect when cannot read the remote file + // Showing button string in the screen, upper part is short press, lower part is long press + IRApp* app = ctx; + if(app->status) { + canvas_clear(canvas); + view_port_set_orientation(app->view_port, ViewPortOrientationHorizontal); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned(canvas, 62, 5, AlignCenter, AlignTop, "Config is incorrect."); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignTop, "Please configure map."); + canvas_draw_str_aligned(canvas, 62, 60, AlignCenter, AlignBottom, "Press Back to Exit."); + } else { + canvas_clear(canvas); + view_port_set_orientation(app->view_port, ViewPortOrientationVertical); + canvas_draw_icon(canvas, 1, 5, &I_ButtonUp_7x4); + canvas_draw_icon(canvas, 1, 15, &I_ButtonDown_7x4); + canvas_draw_icon(canvas, 2, 23, &I_ButtonLeft_4x7); + canvas_draw_icon(canvas, 2, 33, &I_ButtonRight_4x7); + canvas_draw_icon(canvas, 0, 42, &I_Ok_btn_9x9); + canvas_draw_icon(canvas, 0, 53, &I_back_10px); + + //Labels + canvas_set_font(canvas, FontSecondary); + + canvas_draw_str_aligned( + canvas, 32, 8, AlignCenter, AlignCenter, furi_string_get_cstr(app->up_button)); + canvas_draw_str_aligned( + canvas, 32, 18, AlignCenter, AlignCenter, furi_string_get_cstr(app->down_button)); + canvas_draw_str_aligned( + canvas, 32, 28, AlignCenter, AlignCenter, furi_string_get_cstr(app->left_button)); + canvas_draw_str_aligned( + canvas, 32, 38, AlignCenter, AlignCenter, furi_string_get_cstr(app->right_button)); + canvas_draw_str_aligned( + canvas, 32, 48, AlignCenter, AlignCenter, furi_string_get_cstr(app->ok_button)); + canvas_draw_str_aligned( + canvas, 32, 58, AlignCenter, AlignCenter, furi_string_get_cstr(app->back_button)); + + canvas_draw_line(canvas, 0, 65, 64, 65); + + canvas_draw_icon(canvas, 1, 70, &I_ButtonUp_7x4); + canvas_draw_icon(canvas, 1, 80, &I_ButtonDown_7x4); + canvas_draw_icon(canvas, 2, 88, &I_ButtonLeft_4x7); + canvas_draw_icon(canvas, 2, 98, &I_ButtonRight_4x7); + canvas_draw_icon(canvas, 0, 107, &I_Ok_btn_9x9); + canvas_draw_icon(canvas, 0, 118, &I_back_10px); + + canvas_draw_str_aligned( + canvas, 32, 73, AlignCenter, AlignCenter, furi_string_get_cstr(app->up_hold_button)); + canvas_draw_str_aligned( + canvas, 32, 83, AlignCenter, AlignCenter, furi_string_get_cstr(app->down_hold_button)); + canvas_draw_str_aligned( + canvas, 32, 93, AlignCenter, AlignCenter, furi_string_get_cstr(app->left_hold_button)); + canvas_draw_str_aligned( + canvas, + 32, + 103, + AlignCenter, + AlignCenter, + furi_string_get_cstr(app->right_hold_button)); + canvas_draw_str_aligned( + canvas, 32, 113, AlignCenter, AlignCenter, furi_string_get_cstr(app->ok_hold_button)); + canvas_draw_str_aligned(canvas, 32, 123, AlignCenter, AlignCenter, "Exit App"); + } +} + +static void app_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + + FuriMessageQueue* event_queue = ctx; + furi_message_queue_put(event_queue, input_event, FuriWaitForever); +} + +int32_t infrared_remote_app(void* p) { + UNUSED(p); + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + // App button string + IRApp* app = malloc(sizeof(IRApp)); + app->up_button = furi_string_alloc(); + app->down_button = furi_string_alloc(); + app->left_button = furi_string_alloc(); + app->right_button = furi_string_alloc(); + app->ok_button = furi_string_alloc(); + app->back_button = furi_string_alloc(); + app->up_hold_button = furi_string_alloc(); + app->down_hold_button = furi_string_alloc(); + app->left_hold_button = furi_string_alloc(); + app->right_hold_button = furi_string_alloc(); + app->ok_hold_button = furi_string_alloc(); + app->view_port = view_port_alloc(); + + // Configure view port + view_port_draw_callback_set(app->view_port, app_draw_callback, app); + view_port_input_callback_set(app->view_port, app_input_callback, event_queue); + + // Register view port in GUI + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, app->view_port, GuiLayerFullscreen); + + InputEvent event; + + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* ff = flipper_format_file_alloc(storage); + + DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); + DialogsFileBrowserOptions browser_options; + dialog_file_browser_set_basic_options(&browser_options, ".txt", &I_sub1_10px); + FuriString* map_file = furi_string_alloc(); + furi_string_set(map_file, "/ext/ir_remote"); + + bool res = dialog_file_browser_show(dialogs, map_file, map_file, &browser_options); + + furi_record_close(RECORD_DIALOGS); + + // if user didn't choose anything, free everything and exit + if(!res) { + FURI_LOG_I(TAG, "exit"); + flipper_format_free(ff); + furi_record_close(RECORD_STORAGE); + + furi_string_free(app->up_button); + furi_string_free(app->down_button); + furi_string_free(app->left_button); + furi_string_free(app->right_button); + furi_string_free(app->ok_button); + furi_string_free(app->back_button); + furi_string_free(app->up_hold_button); + furi_string_free(app->down_hold_button); + furi_string_free(app->left_hold_button); + furi_string_free(app->right_hold_button); + furi_string_free(app->ok_hold_button); + + view_port_enabled_set(app->view_port, false); + gui_remove_view_port(gui, app->view_port); + view_port_free(app->view_port); + free(app); + furi_message_queue_free(event_queue); + + furi_record_close(RECORD_GUI); + return 255; + } + + InfraredRemote* remote = infrared_remote_alloc(); + FuriString* remote_path = furi_string_alloc(); + + InfraredSignal* up_signal = infrared_signal_alloc(); + InfraredSignal* down_signal = infrared_signal_alloc(); + InfraredSignal* left_signal = infrared_signal_alloc(); + InfraredSignal* right_signal = infrared_signal_alloc(); + InfraredSignal* ok_signal = infrared_signal_alloc(); + InfraredSignal* back_signal = infrared_signal_alloc(); + InfraredSignal* up_hold_signal = infrared_signal_alloc(); + InfraredSignal* down_hold_signal = infrared_signal_alloc(); + InfraredSignal* left_hold_signal = infrared_signal_alloc(); + InfraredSignal* right_hold_signal = infrared_signal_alloc(); + InfraredSignal* ok_hold_signal = infrared_signal_alloc(); + + bool up_enabled = false; + bool down_enabled = false; + bool left_enabled = false; + bool right_enabled = false; + bool ok_enabled = false; + bool back_enabled = false; + bool up_hold_enabled = false; + bool down_hold_enabled = false; + bool left_hold_enabled = false; + bool right_hold_enabled = false; + bool ok_hold_enabled = false; + + if(!flipper_format_file_open_existing(ff, furi_string_get_cstr(map_file))) { + FURI_LOG_E(TAG, "Could not open MAP file %s", furi_string_get_cstr(map_file)); + app->status = 1; + } else { + //Filename Assignment/Check Start + + if(!flipper_format_read_string(ff, "REMOTE", remote_path)) { + FURI_LOG_E(TAG, "Could not read REMOTE string"); + app->status = 1; + } else { + if(!infrared_remote_load(remote, remote_path)) { + FURI_LOG_E(TAG, "Could not load ir file: %s", furi_string_get_cstr(remote_path)); + app->status = 1; + } else { + FURI_LOG_I(TAG, "Loaded REMOTE file: %s", furi_string_get_cstr(remote_path)); + } + } + + //assign variables to values within map file + //set missing filenames to N/A + //assign button signals + size_t index = 0; + if(!flipper_format_read_string(ff, "UP", app->up_button)) { + FURI_LOG_W(TAG, "Could not read UP string"); + furi_string_set(app->up_button, "N/A"); + } else { + if(!infrared_remote_find_button_by_name( + remote, furi_string_get_cstr(app->up_button), &index)) { + FURI_LOG_W(TAG, "Error"); + } else { + up_signal = + infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); + up_enabled = true; + } + } + + if(!flipper_format_read_string(ff, "DOWN", app->down_button)) { + FURI_LOG_W(TAG, "Could not read DOWN string"); + furi_string_set(app->down_button, "N/A"); + } else { + if(!infrared_remote_find_button_by_name( + remote, furi_string_get_cstr(app->down_button), &index)) { + FURI_LOG_W(TAG, "Error"); + } else { + down_signal = + infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); + down_enabled = true; + } + } + + if(!flipper_format_read_string(ff, "LEFT", app->left_button)) { + FURI_LOG_W(TAG, "Could not read LEFT string"); + furi_string_set(app->left_button, "N/A"); + } else { + if(!infrared_remote_find_button_by_name( + remote, furi_string_get_cstr(app->left_button), &index)) { + FURI_LOG_W(TAG, "Error"); + } else { + left_signal = + infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); + left_enabled = true; + } + } + + if(!flipper_format_read_string(ff, "RIGHT", app->right_button)) { + FURI_LOG_W(TAG, "Could not read RIGHT string"); + furi_string_set(app->right_button, "N/A"); + } else { + if(!infrared_remote_find_button_by_name( + remote, furi_string_get_cstr(app->right_button), &index)) { + FURI_LOG_W(TAG, "Error"); + } else { + right_signal = + infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); + right_enabled = true; + } + } + + if(!flipper_format_read_string(ff, "OK", app->ok_button)) { + FURI_LOG_W(TAG, "Could not read OK string"); + furi_string_set(app->ok_button, "N/A"); + } else { + if(!infrared_remote_find_button_by_name( + remote, furi_string_get_cstr(app->ok_button), &index)) { + FURI_LOG_W(TAG, "Error"); + } else { + ok_signal = + infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); + ok_enabled = true; + } + } + + if(!flipper_format_read_string(ff, "BACK", app->back_button)) { + FURI_LOG_W(TAG, "Could not read BACK string"); + furi_string_set(app->back_button, "N/A"); + } else { + if(!infrared_remote_find_button_by_name( + remote, furi_string_get_cstr(app->back_button), &index)) { + FURI_LOG_W(TAG, "Error"); + } else { + back_signal = + infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); + back_enabled = true; + } + } + + if(!flipper_format_read_string(ff, "UPHOLD", app->up_hold_button)) { + FURI_LOG_W(TAG, "Could not read UPHOLD string"); + furi_string_set(app->up_hold_button, "N/A"); + } else { + if(!infrared_remote_find_button_by_name( + remote, furi_string_get_cstr(app->up_hold_button), &index)) { + FURI_LOG_W(TAG, "Error"); + } else { + up_hold_signal = + infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); + up_hold_enabled = true; + } + } + + if(!flipper_format_read_string(ff, "DOWNHOLD", app->down_hold_button)) { + FURI_LOG_W(TAG, "Could not read DOWNHOLD string"); + furi_string_set(app->down_hold_button, "N/A"); + } else { + if(!infrared_remote_find_button_by_name( + remote, furi_string_get_cstr(app->down_hold_button), &index)) { + FURI_LOG_W(TAG, "Error"); + } else { + down_hold_signal = + infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); + down_hold_enabled = true; + } + } + + if(!flipper_format_read_string(ff, "LEFTHOLD", app->left_hold_button)) { + FURI_LOG_W(TAG, "Could not read LEFTHOLD string"); + furi_string_set(app->left_hold_button, "N/A"); + } else { + if(!infrared_remote_find_button_by_name( + remote, furi_string_get_cstr(app->left_hold_button), &index)) { + FURI_LOG_W(TAG, "Error"); + } else { + left_hold_signal = + infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); + left_hold_enabled = true; + } + } + + if(!flipper_format_read_string(ff, "RIGHTHOLD", app->right_hold_button)) { + FURI_LOG_W(TAG, "Could not read RIGHTHOLD string"); + furi_string_set(app->right_hold_button, "N/A"); + } else { + if(!infrared_remote_find_button_by_name( + remote, furi_string_get_cstr(app->right_hold_button), &index)) { + FURI_LOG_W(TAG, "Error"); + } else { + right_hold_signal = + infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); + right_hold_enabled = true; + } + } + + if(!flipper_format_read_string(ff, "OKHOLD", app->ok_hold_button)) { + FURI_LOG_W(TAG, "Could not read OKHOLD string"); + furi_string_set(app->ok_hold_button, "N/A"); + } else { + if(!infrared_remote_find_button_by_name( + remote, furi_string_get_cstr(app->ok_hold_button), &index)) { + FURI_LOG_W(TAG, "Error"); + } else { + ok_hold_signal = + infrared_remote_button_get_signal(infrared_remote_get_button(remote, index)); + ok_hold_enabled = true; + } + } + } + + furi_string_free(remote_path); + + flipper_format_free(ff); + furi_record_close(RECORD_STORAGE); + + bool running = true; + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + + if(app->status) { + view_port_update(app->view_port); + while(running) { + if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) { + if(event.type == InputTypeShort) { + switch(event.key) { + case InputKeyBack: + running = false; + break; + default: + break; + } + } + } + } + } else { + view_port_update(app->view_port); + while(running) { + if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) { + // short press signal + if(event.type == InputTypeShort) { + switch(event.key) { + case InputKeyUp: + if(up_enabled) { + infrared_signal_transmit(up_signal); + notification_message(notification, &sequence_blink_start_magenta); + FURI_LOG_I(TAG, "up"); + } + break; + case InputKeyDown: + if(down_enabled) { + infrared_signal_transmit(down_signal); + notification_message(notification, &sequence_blink_start_magenta); + FURI_LOG_I(TAG, "down"); + } + break; + case InputKeyRight: + if(right_enabled) { + infrared_signal_transmit(right_signal); + notification_message(notification, &sequence_blink_start_magenta); + FURI_LOG_I(TAG, "right"); + } + break; + case InputKeyLeft: + if(left_enabled) { + infrared_signal_transmit(left_signal); + notification_message(notification, &sequence_blink_start_magenta); + FURI_LOG_I(TAG, "left"); + } + break; + case InputKeyOk: + if(ok_enabled) { + infrared_signal_transmit(ok_signal); + notification_message(notification, &sequence_blink_start_magenta); + FURI_LOG_I(TAG, "ok"); + } + break; + case InputKeyBack: + if(back_enabled) { + infrared_signal_transmit(back_signal); + notification_message(notification, &sequence_blink_start_magenta); + FURI_LOG_I(TAG, "back"); + } + break; + default: + running = false; + break; + } + // long press signal + } else if(event.type == InputTypeLong) { + switch(event.key) { + case InputKeyUp: + if(up_hold_enabled) { + infrared_signal_transmit(up_hold_signal); + notification_message(notification, &sequence_blink_start_magenta); + FURI_LOG_I(TAG, "up!"); + } + break; + case InputKeyDown: + if(down_hold_enabled) { + infrared_signal_transmit(down_hold_signal); + notification_message(notification, &sequence_blink_start_magenta); + FURI_LOG_I(TAG, "down!"); + } + break; + case InputKeyRight: + if(right_hold_enabled) { + infrared_signal_transmit(right_hold_signal); + notification_message(notification, &sequence_blink_start_magenta); + FURI_LOG_I(TAG, "right!"); + } + break; + case InputKeyLeft: + if(left_hold_enabled) { + infrared_signal_transmit(left_hold_signal); + notification_message(notification, &sequence_blink_start_magenta); + FURI_LOG_I(TAG, "left!"); + } + break; + case InputKeyOk: + if(ok_hold_enabled) { + infrared_signal_transmit(ok_hold_signal); + notification_message(notification, &sequence_blink_start_magenta); + FURI_LOG_I(TAG, "ok!"); + } + break; + default: + running = false; + break; + } + } else if(event.type == InputTypeRelease) { + notification_message(notification, &sequence_blink_stop); + } + } + } + } + + // Free all things + furi_string_free(app->up_button); + furi_string_free(app->down_button); + furi_string_free(app->left_button); + furi_string_free(app->right_button); + furi_string_free(app->ok_button); + furi_string_free(app->back_button); + furi_string_free(app->up_hold_button); + furi_string_free(app->down_hold_button); + furi_string_free(app->left_hold_button); + furi_string_free(app->right_hold_button); + furi_string_free(app->ok_hold_button); + + infrared_remote_free(remote); + view_port_enabled_set(app->view_port, false); + gui_remove_view_port(gui, app->view_port); + view_port_free(app->view_port); + free(app); + furi_message_queue_free(event_queue); + + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_GUI); + + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote_button.c b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote_button.c new file mode 100644 index 000000000..1f6315ec5 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote_button.c @@ -0,0 +1,37 @@ +#include "infrared_remote_button.h" + +#include + +struct InfraredRemoteButton { + FuriString* name; + InfraredSignal* signal; +}; + +InfraredRemoteButton* infrared_remote_button_alloc() { + InfraredRemoteButton* button = malloc(sizeof(InfraredRemoteButton)); + button->name = furi_string_alloc(); + button->signal = infrared_signal_alloc(); + return button; +} + +void infrared_remote_button_free(InfraredRemoteButton* button) { + furi_string_free(button->name); + infrared_signal_free(button->signal); + free(button); +} + +void infrared_remote_button_set_name(InfraredRemoteButton* button, const char* name) { + furi_string_set(button->name, name); +} + +const char* infrared_remote_button_get_name(InfraredRemoteButton* button) { + return furi_string_get_cstr(button->name); +} + +void infrared_remote_button_set_signal(InfraredRemoteButton* button, InfraredSignal* signal) { + infrared_signal_set_signal(button->signal, signal); +} + +InfraredSignal* infrared_remote_button_get_signal(InfraredRemoteButton* button) { + return button->signal; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote_button.h b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote_button.h new file mode 100644 index 000000000..f25b759b5 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_remote_button.h @@ -0,0 +1,14 @@ +#pragma once + +#include "infrared_signal.h" + +typedef struct InfraredRemoteButton InfraredRemoteButton; + +InfraredRemoteButton* infrared_remote_button_alloc(); +void infrared_remote_button_free(InfraredRemoteButton* button); + +void infrared_remote_button_set_name(InfraredRemoteButton* button, const char* name); +const char* infrared_remote_button_get_name(InfraredRemoteButton* button); + +void infrared_remote_button_set_signal(InfraredRemoteButton* button, InfraredSignal* signal); +InfraredSignal* infrared_remote_button_get_signal(InfraredRemoteButton* button); diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_signal.c b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_signal.c new file mode 100644 index 000000000..0c7e3d3bf --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_signal.c @@ -0,0 +1,300 @@ +#include "infrared_signal.h" + +#include +#include +#include +#include +#include + +#define TAG "InfraredSignal" + +struct InfraredSignal { + bool is_raw; + union { + InfraredMessage message; + InfraredRawSignal raw; + } payload; +}; + +static void infrared_signal_clear_timings(InfraredSignal* signal) { + if(signal->is_raw) { + free(signal->payload.raw.timings); + signal->payload.raw.timings_size = 0; + signal->payload.raw.timings = NULL; + } +} + +static bool infrared_signal_is_message_valid(InfraredMessage* message) { + if(!infrared_is_protocol_valid(message->protocol)) { + FURI_LOG_E(TAG, "Unknown protocol"); + return false; + } + + uint32_t address_length = infrared_get_protocol_address_length(message->protocol); + uint32_t address_mask = (1UL << address_length) - 1; + + if(message->address != (message->address & address_mask)) { + FURI_LOG_E( + TAG, + "Address is out of range (mask 0x%08lX): 0x%lX\r\n", + address_mask, + message->address); + return false; + } + + uint32_t command_length = infrared_get_protocol_command_length(message->protocol); + uint32_t command_mask = (1UL << command_length) - 1; + + if(message->command != (message->command & command_mask)) { + FURI_LOG_E( + TAG, + "Command is out of range (mask 0x%08lX): 0x%lX\r\n", + command_mask, + message->command); + return false; + } + + return true; +} + +static bool infrared_signal_is_raw_valid(InfraredRawSignal* raw) { + if((raw->frequency > INFRARED_MAX_FREQUENCY) || (raw->frequency < INFRARED_MIN_FREQUENCY)) { + FURI_LOG_E( + TAG, + "Frequency is out of range (%X - %X): %lX", + INFRARED_MIN_FREQUENCY, + INFRARED_MAX_FREQUENCY, + raw->frequency); + return false; + + } else if((raw->duty_cycle <= 0) || (raw->duty_cycle > 1)) { + FURI_LOG_E(TAG, "Duty cycle is out of range (0 - 1): %f", (double)raw->duty_cycle); + return false; + + } else if((raw->timings_size <= 0) || (raw->timings_size > MAX_TIMINGS_AMOUNT)) { + FURI_LOG_E( + TAG, + "Timings amount is out of range (0 - %X): %X", + MAX_TIMINGS_AMOUNT, + raw->timings_size); + return false; + } + + return true; +} + +static inline bool infrared_signal_save_message(InfraredMessage* message, FlipperFormat* ff) { + const char* protocol_name = infrared_get_protocol_name(message->protocol); + return flipper_format_write_string_cstr(ff, "type", "parsed") && + flipper_format_write_string_cstr(ff, "protocol", protocol_name) && + flipper_format_write_hex(ff, "address", (uint8_t*)&message->address, 4) && + flipper_format_write_hex(ff, "command", (uint8_t*)&message->command, 4); +} + +static inline bool infrared_signal_save_raw(InfraredRawSignal* raw, FlipperFormat* ff) { + furi_assert(raw->timings_size <= MAX_TIMINGS_AMOUNT); + return flipper_format_write_string_cstr(ff, "type", "raw") && + flipper_format_write_uint32(ff, "frequency", &raw->frequency, 1) && + flipper_format_write_float(ff, "duty_cycle", &raw->duty_cycle, 1) && + flipper_format_write_uint32(ff, "data", raw->timings, raw->timings_size); +} + +static inline bool infrared_signal_read_message(InfraredSignal* signal, FlipperFormat* ff) { + FuriString* buf; + buf = furi_string_alloc(); + bool success = false; + + do { + if(!flipper_format_read_string(ff, "protocol", buf)) break; + + InfraredMessage message; + message.protocol = infrared_get_protocol_by_name(furi_string_get_cstr(buf)); + + success = flipper_format_read_hex(ff, "address", (uint8_t*)&message.address, 4) && + flipper_format_read_hex(ff, "command", (uint8_t*)&message.command, 4) && + infrared_signal_is_message_valid(&message); + + if(!success) break; + + infrared_signal_set_message(signal, &message); + } while(0); + + furi_string_free(buf); + return success; +} + +static inline bool infrared_signal_read_raw(InfraredSignal* signal, FlipperFormat* ff) { + uint32_t timings_size, frequency; + float duty_cycle; + + bool success = flipper_format_read_uint32(ff, "frequency", &frequency, 1) && + flipper_format_read_float(ff, "duty_cycle", &duty_cycle, 1) && + flipper_format_get_value_count(ff, "data", &timings_size); + + if(!success || timings_size > MAX_TIMINGS_AMOUNT) { + return false; + } + + uint32_t* timings = malloc(sizeof(uint32_t) * timings_size); + success = flipper_format_read_uint32(ff, "data", timings, timings_size); + + if(success) { + infrared_signal_set_raw_signal(signal, timings, timings_size, frequency, duty_cycle); + } + + free(timings); + return success; +} + +static bool infrared_signal_read_body(InfraredSignal* signal, FlipperFormat* ff) { + FuriString* tmp = furi_string_alloc(); + + bool success = false; + + do { + if(!flipper_format_read_string(ff, "type", tmp)) break; + if(furi_string_equal(tmp, "raw")) { + success = infrared_signal_read_raw(signal, ff); + } else if(furi_string_equal(tmp, "parsed")) { + success = infrared_signal_read_message(signal, ff); + } else { + FURI_LOG_E(TAG, "Unknown signal type"); + } + } while(false); + + furi_string_free(tmp); + return success; +} + +InfraredSignal* infrared_signal_alloc() { + InfraredSignal* signal = malloc(sizeof(InfraredSignal)); + + signal->is_raw = false; + signal->payload.message.protocol = InfraredProtocolUnknown; + + return signal; +} + +void infrared_signal_free(InfraredSignal* signal) { + infrared_signal_clear_timings(signal); + free(signal); +} + +bool infrared_signal_is_raw(InfraredSignal* signal) { + return signal->is_raw; +} + +bool infrared_signal_is_valid(InfraredSignal* signal) { + return signal->is_raw ? infrared_signal_is_raw_valid(&signal->payload.raw) : + infrared_signal_is_message_valid(&signal->payload.message); +} + +void infrared_signal_set_signal(InfraredSignal* signal, const InfraredSignal* other) { + if(other->is_raw) { + const InfraredRawSignal* raw = &other->payload.raw; + infrared_signal_set_raw_signal( + signal, raw->timings, raw->timings_size, raw->frequency, raw->duty_cycle); + } else { + const InfraredMessage* message = &other->payload.message; + infrared_signal_set_message(signal, message); + } +} + +void infrared_signal_set_raw_signal( + InfraredSignal* signal, + const uint32_t* timings, + size_t timings_size, + uint32_t frequency, + float duty_cycle) { + infrared_signal_clear_timings(signal); + + signal->is_raw = true; + + signal->payload.raw.timings_size = timings_size; + signal->payload.raw.frequency = frequency; + signal->payload.raw.duty_cycle = duty_cycle; + + signal->payload.raw.timings = malloc(timings_size * sizeof(uint32_t)); + memcpy(signal->payload.raw.timings, timings, timings_size * sizeof(uint32_t)); +} + +InfraredRawSignal* infrared_signal_get_raw_signal(InfraredSignal* signal) { + furi_assert(signal->is_raw); + return &signal->payload.raw; +} + +void infrared_signal_set_message(InfraredSignal* signal, const InfraredMessage* message) { + infrared_signal_clear_timings(signal); + + signal->is_raw = false; + signal->payload.message = *message; +} + +InfraredMessage* infrared_signal_get_message(InfraredSignal* signal) { + furi_assert(!signal->is_raw); + return &signal->payload.message; +} + +bool infrared_signal_save(InfraredSignal* signal, FlipperFormat* ff, const char* name) { + if(!flipper_format_write_comment_cstr(ff, "") || + !flipper_format_write_string_cstr(ff, "name", name)) { + return false; + } else if(signal->is_raw) { + return infrared_signal_save_raw(&signal->payload.raw, ff); + } else { + return infrared_signal_save_message(&signal->payload.message, ff); + } +} + +bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, FuriString* name) { + FuriString* tmp = furi_string_alloc(); + + bool success = false; + + do { + if(!flipper_format_read_string(ff, "name", tmp)) break; + furi_string_set(name, tmp); + if(!infrared_signal_read_body(signal, ff)) break; + success = true; + } while(0); + + furi_string_free(tmp); + return success; +} + +bool infrared_signal_search_and_read( + InfraredSignal* signal, + FlipperFormat* ff, + const FuriString* name) { + bool success = false; + FuriString* tmp = furi_string_alloc(); + + do { + bool is_name_found = false; + while(flipper_format_read_string(ff, "name", tmp)) { + is_name_found = furi_string_equal(name, tmp); + if(is_name_found) break; + } + if(!is_name_found) break; + if(!infrared_signal_read_body(signal, ff)) break; + success = true; + } while(false); + + furi_string_free(tmp); + return success; +} + +void infrared_signal_transmit(InfraredSignal* signal) { + if(signal->is_raw) { + InfraredRawSignal* raw_signal = &signal->payload.raw; + infrared_send_raw_ext( + raw_signal->timings, + raw_signal->timings_size, + true, + raw_signal->frequency, + raw_signal->duty_cycle); + } else { + InfraredMessage* message = &signal->payload.message; + infrared_send(message, 2); + } +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_signal.h b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_signal.h new file mode 100644 index 000000000..637d859b0 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/infrared_signal.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include + +#include +#include + +typedef struct InfraredSignal InfraredSignal; + +typedef struct { + size_t timings_size; + uint32_t* timings; + uint32_t frequency; + float duty_cycle; +} InfraredRawSignal; + +InfraredSignal* infrared_signal_alloc(); +void infrared_signal_free(InfraredSignal* signal); + +bool infrared_signal_is_raw(InfraredSignal* signal); +bool infrared_signal_is_valid(InfraredSignal* signal); + +void infrared_signal_set_signal(InfraredSignal* signal, const InfraredSignal* other); + +void infrared_signal_set_raw_signal( + InfraredSignal* signal, + const uint32_t* timings, + size_t timings_size, + uint32_t frequency, + float duty_cycle); +InfraredRawSignal* infrared_signal_get_raw_signal(InfraredSignal* signal); + +void infrared_signal_set_message(InfraredSignal* signal, const InfraredMessage* message); +InfraredMessage* infrared_signal_get_message(InfraredSignal* signal); + +bool infrared_signal_save(InfraredSignal* signal, FlipperFormat* ff, const char* name); +bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, FuriString* name); +bool infrared_signal_search_and_read( + InfraredSignal* signal, + FlipperFormat* ff, + const FuriString* name); + +void infrared_signal_transmit(InfraredSignal* signal); diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/ir.png b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/ir.png new file mode 100644 index 0000000000000000000000000000000000000000..71bb60fa34c08e9924578e1ebd75903082cae694 GIT binary patch literal 1514 zcmeAS@N?(olHy`uVBq!ia0y~yU;;8388|?c*QZDWAjMhW5n0T@AXEavjQ7&yD;OA9 z=Xkm}hE&XXdpB_1Wh)Vfz%B{C$H@Xc?|Ywj^4B#@P@R3u^Y-3r`aAb7^~m|TqfqYu z|3Cj&8|JMq-_OYKPLY8jkcmM+6%X|__X~S`{h#uuzZnuHU!0jAhEUu8IOoJ2`3IZ- zeyso3`<}T$nv=m{3Il_S?YSz&YEFjr=jA}Y2mqPx|CX`m+;odg@(drW-Y_yKFffDy z?cKVE-N5*}{6=|(0{vNi08OZyddB)6(@s+&4fBac^ z63PBob`6WKR(^a@$((kU;rk{gh7KWy1`S4rj;MRg5|Xz572ns?fBpV$M|on(*UHnz z*XMt&3%mREJ@*?VYfEp*9hmygDn8@*y#vPU?RPy}bN+~>--nxPAbtdSb=r4^u;=Gi zUtcq8=Fa|m&F{CJkN!KS@p?Lv+wU+(*dDJxKGViHto~a0?f<>!8SVN-A&~|QmMd3k z8LXe}Pe1#2{U5#muYUe3w|s3}c%G%kOdH~0pu1Nb@7w&T|4hgFhxb?$rXuu$;vE{Y zAd@n`GctULLvkH3BB1dBqL$6$-1B%%<@4*zcTOXPRE5}uGd=%KWxKsmW%whFWa-M^ z41Hng?~Z4mdCeHtjy_?&_JS=|yUky-|2T{A3X)%eK7aMF`XhrcQqDn5y}{?1E$rOCuldbZwnvTOGg7Fv zr8AyA^J4v;XQF#f|7Mwyh!mHl@&_)ylKE57D`|D$^#;^LWqIy*5a>DYrj4_#CYZhLeZ(H@uu5D(v-ODv95B5eNatJ7x(k`T*JyKq5 zCU^ij;~%zdxElHMm8IEwgZl0A3{%j9O6}j7>~-_@*MG@Me|P>*>>E!8Yb0}R&&|@G z9nZW+91-@Q+yKoKpfq;*9Ww)pQxGW&HJuG^-d`qO=PsMif$|f8g*StztDnm{r-UW| D?#1+} literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/ir2.png b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/ir2.png new file mode 100644 index 0000000000000000000000000000000000000000..133b1c8667675631cdc58cc9c635b39b1d1cc060 GIT binary patch literal 3109 zcma)8dr(tn7QX?NDid*aSR@OiJ50B`n-L!|OnC&bx&=!GtF94*1QCcdq97VVLLPRf zcD2+^x0C#1F#;XH#o;mZ(+?A6Swx~pIb?=h{R$)kf3 zU8R!Iv$wu~{XODuYK1s0W#Zo2+|9s$7B=^;C>~F6xr*(RDNEMrT}ADSwgdm2O4k{v z2bed>Rvl_tfFXY5h)Qdl$%YT4Qa)+G;%hN;&JRE|WBOnKl zdVb9-v=CtCQ?FtP@MocLlGdzJoD!=$$|%(UmvIvG9l+xC*9eRrG5yyjp%G3T3kyPR zlC63!!@JB?IadsBcRqkG*)io=!#c-f7vO6!8er`|jlI)j7b2D}m8pZ1_tM3FW*>XU z_bnUp1BYmpjjNuU49cw%t0KZjvF~lUx9h#;{OGnP5^E??t}#a)@~qj9GJ(|g-D3u| ze%13UO59L52#k3QyLZd%6KNLA423&b3;`P3WfGJPzIsEC*YrU^AL6ZFgJPA9-NJrm zYcsOw@>8bMno7+XG@J$#sclT;c&KyF5uDi!!6ZPc{~EGjCXXZ`G%Gx)G96cyOQ^R# zTKSgiDPF8YVT0Wrg}+gDR^e0YO~*1n`5IIs$7|?zK@mT)iXA37T1i%OQPlQ99kMBw zk?*$Ik&=pA!T?|ugWd-u9C7FIg^ox<{9l9fgZ%ej2L;qXiMxbul$WLk{Yu<8ZL!Zd z5Pp)D2ttag!KfSo{czvF7a$OqWzK#xNg+SACoNMet?^>o=O>P)lrKKy9QX%tjx^NA ziDASFID|ZAj-uri6Y`@T@CL5{AFJCGtjP*JUU)MEDcE75+s#^_hrA02H3^B!Ojfg% zpz3G#rVf6!tnECD(lf<$IAdg^I{ba9b-*IKcNus^2%DJFeVCS)Q2Shs11MPSn5evi zC%I?TTn(=jpmtfY;S+S@Ywo@w{j$d#z4y!y_P-02jW7Bx>SS(3EI_4H0})&nol~U? za`drJFa&xOR-WJ3Fw&JBVFNm5=0eF<5}?xT5ro_l^Zod`7LJiJ^MZ0*x{Y2ALT~XK zJJL*v>dD9VF|!7k4H1cG;a9hHwb~r7v<$(_smBuxkANsfn8MpGhkqG?1R8uDt~-fdLO^GaN_xT=LC<-e57>(o=iR?UUHs?=Dj{URzMPA5dS zeXkykqsci57h8V~gOqvJUIr=Zy3j=RZrn{Toog^d#Sn5aeZhPFG2JMZgkk@^%|1LAU?1a+d-Tq1J+On6%f=hLC3afV2=qt@1jjK;>s zj*jr0k=Cx_d~@yU0wv!MfTE>(7T20h)W)gEM-XwwsO;a#*>8Ie7&@uA3TGv6_NrY6cyj#m?pzXr+~Zqoe3GFQi_T zICP@ItfL33#7TXy?r3W|Ulm@u6apR@5oCQWf&DL?D`h;dKpD`-{I_}QMODB0meAsl z@|SZqC`-w@VJF`eOSP(Ye4jd4JBZHOYR_qnLLNQn=uN~M%9L5H>i}=xN`G=*2EU!V z5iU1rk9U^jP>d&}cf~}4Gg`t)QKLT=Ct6me>CDOLNIxwxqM8KRGqKZZ(6dIRaMAOh Yx$EjO#DnR`EP!_ZDPdRbhiRYx2WswUlmGw# literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/ir_remote/ir_10px.png b/Applications/Official/DEV_FW/source/xMasterX/ir_remote/ir_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..22c986180a2bed76dbe4ff439df1cf9177533c32 GIT binary patch literal 305 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xkYHHq`AGmsv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpafHrx4R1i<>&pI=m5)bWC*+s&X`qmbr;B3<$Ms~3f`-KX%+5*7 zhxan`%;z`w!#>%c-@wM^z<~n{3>VXQv+hhNs0FH5Epd$~Nl7e8wMs5Z1yT$~21bUu z2Bx}(CLxAKR>lTa#unNJ237_J>nn=CplHa=PsvQHglaGb>IpG01*)?$HiBr_e$xf$ PHwFezS3j3^P6vp%ql!dB0WA$k5wuVsK?4+_pr%1INJ#tvq|3XzwqvBr#SND1`S3H(`}MptAMb46 zTV1)iA_&52uiM#$v7E15y9~eI{=N19hD-VGy>;Q?qgVcd#g#$ZZwtaV4_^2eKM(7x zJ6rwDv$HdpzW2j#AHr}w?Y^H2f-IHaOJDx+`zL_PmCs0Yl6R zEKcH4l6#YuR1teHFSiv*tRTf9Cw+QCdVi5ldPe@S~z7fy;F)aXRNt@@c{#b;<;%iYBXNY%`$m zUkr`oIXW*kkHN~+>2rzm{z=M|U6%8sjIhmPmK3*V#?m1#cs}G$@ooP1e>|jQZZJK{ zMpcd|QP_yZz?}nDtNcs7jf~-fXMN5`vx@D^EQ-1zo8s$xQ9}7Rf1~thdVqCs!CF#T zJ*2uwGy9t5sitS>Z>ol;sx{OHK~P-a<-nXq;mI;k-}ib+Uf_hVUZ*92Q*snhPYoKT z-f%E-%%FiBw?UC>ss_S_7TTIgZPFl>UvR#|$x)e!@_emd$_a4Hv*}ry9%z9cAjh&8 zGHqaU%+N%-?gq@%Fc`CDZ0}|f^bj5`vX)*^U}U;uTN=Yi)hru@tf3+|a6)8-s^eO= zMm4HS;uE_Ye8e-KQ^>9%iIjLD&teSviDEopN}3F2k_J(O5eTLmE^1iL!(xmx)*e6+o~=7& zi9m9Ed~q1d>Er(lqvj?SO#y +#include +#include +#include +#include + +typedef enum { + EventTypeTick, + EventTypeKey, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} PluginEvent; + +typedef struct { + float xZoom; + float yZoom; + float xOffset; + float yOffset; + float zoom; +} PluginState; + +bool mandelbrot_pixel(int x, int y, float xZoom, float yZoom, float xOffset, float yOffset) { + float ratio = 128.0 / 64.0; + //x0 := scaled x coordinate of pixel (scaled to lie in the Mandelbrot X scale (-2.00, 0.47)) + float x0 = (((x / 128.0) * ratio * xZoom)) - xOffset; + //y0 := scaled y coordinate of pixel (scaled to lie in the Mandelbrot Y scale (-1.12, 1.12)) + float y0 = ((y / 64.0) * yZoom) - yOffset; + float x1 = 0.0; + float y1 = 0.0; + float x2 = 0.0; + float y2 = 0.0; + + int iteration = 0; + int max_iteration = 50; + + while(x2 + y2 <= 4.0 && iteration < max_iteration) { + y1 = 2.0 * x1 * y1 + y0; + x1 = x2 - y2 + x0; + x2 = x1 * x1; + y2 = y1 * y1; + iteration++; + } + + if(iteration > 49) { + return true; + } + + return false; +} + +static void render_callback(Canvas* const canvas, void* ctx) { + const PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25); + if(plugin_state == NULL) { + return; + } + // border around the edge of the screen + canvas_draw_frame(canvas, 0, 0, 128, 64); + + for(int y = 0; y < 64; y++) { + for(int x = 0; x < 128; x++) { + // did you know if you just pass the indivdiual bits of plugin_state instead of plugin_state + // you dont get any compiler warnings :) + if(mandelbrot_pixel( + x, + y, + plugin_state->xZoom, + plugin_state->yZoom, + plugin_state->xOffset, + plugin_state->yOffset)) { + canvas_draw_dot(canvas, x, y); + } + } + } + + release_mutex((ValueMutex*)ctx, plugin_state); +} + +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 mandelbrot_state_init(PluginState* const plugin_state) { + plugin_state->xOffset = 3.0; + plugin_state->yOffset = 1.12; + plugin_state->xZoom = 2.47; + plugin_state->yZoom = 2.24; + plugin_state->zoom = 1; // this controls the camera when +} + +int32_t mandelbrot_app(void* p) { + UNUSED(p); + + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); + + PluginState* plugin_state = malloc(sizeof(PluginState)); + mandelbrot_state_init(plugin_state); + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) { + FURI_LOG_E("mandelbrot", "cannot create mutex\r\n"); + furi_message_queue_free(event_queue); + free(plugin_state); + return 255; + } + + // Set system callbacks + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, render_callback, &state_mutex); + view_port_input_callback_set(view_port, input_callback, event_queue); + + // Open GUI and register view_port + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + PluginEvent event; + for(bool processing = true; processing;) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); + PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex); + + if(event_status == FuriStatusOk) { + // press events + if(event.type == EventTypeKey) { + if(event.input.type == InputTypePress) { + switch(event.input.key) { + case InputKeyUp: + plugin_state->yOffset += 0.1 / plugin_state->zoom; + break; + case InputKeyDown: + plugin_state->yOffset += -0.1 / plugin_state->zoom; + break; + case InputKeyRight: + plugin_state->xOffset += -0.1 / plugin_state->zoom; + break; + case InputKeyLeft: + plugin_state->xOffset += 0.1 / plugin_state->zoom; + break; + case InputKeyOk: + plugin_state->xZoom -= (2.47 / 10) / plugin_state->zoom; + plugin_state->yZoom -= (2.24 / 10) / plugin_state->zoom; + // used to make camera control finer the more zoomed you are + // this needs to be some sort of curve + plugin_state->zoom += 0.15; + break; + case InputKeyBack: + processing = false; + break; + default: + break; + } + } + } + } else { + FURI_LOG_D("mandelbrot", "osMessageQueue: event timeout"); + // event timeout + } + view_port_update(view_port); + release_mutex(&state_mutex, plugin_state); + } + + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + furi_record_close(RECORD_GUI); + view_port_free(view_port); + furi_message_queue_free(event_queue); + + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/montyhall/Monty.png b/Applications/Official/DEV_FW/source/xMasterX/montyhall/Monty.png new file mode 100644 index 0000000000000000000000000000000000000000..1f4c14cd63d166b73db3711be872d01d1cc02f62 GIT binary patch literal 1912 zcmcIlO>f*p7Kz^?!y@dqk}*Y@sqkwUr`EZH;j`km+fdfu5w`+N5`H{RJ0 z1Yxt^>m0yX&Npschwrn$ww}OnEkC%oEj<18)*rA~8@BznApG#;%@_DJSg-Hz4!Rc? z7chPB{P%BQcq8q7o(qEfUin^o{figyZ~eDua8w-myB^`Oj42P8JdIP(7KG;3G{xkY z6=J}KQPPtB{^@5)jA%9}|~KTX!}$no|!DVpd>r8jq9Q zo3^A1*n@c~RwS`fDUMrGyR;}C`TODy&zNY-IwGp7inc3jfn{Rb{aDmhT~|~~(F~;7 zUc>UVhB$j9uqTSmjE3Gp=kClNtXk5jC{j;RCXBMb#BuN1%c7v!uXN zl;pQ-kQq#e0kWlp2;Y!y}C_xed*;DoS#rzL??auiWd4H~B2a4>Sr zpn)8>L6K{!2Ev9G+L}pi(jb*zu)o8}Ntuaqf6ZUY31BR;=~xHL6SE zOS?OK%rl=;$gUxYlz1V}VhsF=VmxF@nhfWZ22z6&2&Nb1P{FgRUFzPcn&v+HYDqL} zfpH{OeDp9W+n^&S&%Pfs$#)59xjO% zEVwi0C&mVKb%K#?IRy=&KDqw*aqq1gHy?fb>GSS)U#|&& fJ`~5hch`lrABA_{eK%ZL8}|D-n9 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/montyhall/application.fam b/Applications/Official/DEV_FW/source/xMasterX/montyhall/application.fam new file mode 100644 index 000000000..c6446b413 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/montyhall/application.fam @@ -0,0 +1,12 @@ +App( + appid="MontyHall", + name="Monty Hall", + apptype=FlipperAppType.EXTERNAL, + entry_point="montyhall_game_app", + cdefines=["APP_MONTYHALL_GAME"], + requires=["gui"], + stack_size=1 * 1024, + order=185, + fap_icon="Monty.png", + fap_category="Games_Extra", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/montyhall/monteyhall.c b/Applications/Official/DEV_FW/source/xMasterX/montyhall/monteyhall.c new file mode 100644 index 000000000..024d539ec --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/montyhall/monteyhall.c @@ -0,0 +1,450 @@ +#include +#include +#include +#include + +#include +#include + +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 64 + +//AUTHOR: https://github.com/DevMilanIan +//I_DoorClosed_22x35 sourced from VideoPoker/poker.c -> I_CardBack22x35 +//PRs for syntax, formatting, etc can get you listed as a contributor :) + +// CONCEPT: one of three doors will have a car while the other two have only a goat +// randomize a winning door each round, let the player choose a first selection +// reveal a goat door and allow the player to keep or switch their selection +// based on the Monty Hall problem from Let's Make a Deal + +//void draw_goat(Canvas* canvas, int x, int y) { TODO } + +void draw_car(Canvas* canvas, int x, int y) { + // x -> leftmost pixel, y -> topmost pixel + // could be in another file or a pixel array but idk how to so feel free to PR + + canvas_draw_dot(canvas, x + 1, y + 4); + canvas_draw_dot(canvas, x + 1, y + 5); + canvas_draw_dot(canvas, x + 2, y + 3); + canvas_draw_dot(canvas, x + 2, y + 6); + canvas_draw_dot(canvas, x + 3, y + 3); + canvas_draw_dot(canvas, x + 3, y + 6); + + canvas_draw_dot(canvas, x + 4, y + 2); + canvas_draw_dot(canvas, x + 4, y + 3); + canvas_draw_dot(canvas, x + 4, y + 6); + canvas_draw_dot(canvas, x + 4, y + 7); + + canvas_draw_dot(canvas, x + 5, y + 1); + canvas_draw_dot(canvas, x + 5, y + 2); + canvas_draw_dot(canvas, x + 5, y + 3); + canvas_draw_dot(canvas, x + 5, y + 5); + canvas_draw_dot(canvas, x + 5, y + 8); + + canvas_draw_dot(canvas, x + 6, y); + canvas_draw_dot(canvas, x + 6, y + 1); + canvas_draw_dot(canvas, x + 6, y + 3); + canvas_draw_dot(canvas, x + 6, y + 5); + canvas_draw_dot(canvas, x + 6, y + 8); + + canvas_draw_dot(canvas, x + 7, y); + canvas_draw_dot(canvas, x + 7, y + 3); + canvas_draw_dot(canvas, x + 7, y + 6); + canvas_draw_dot(canvas, x + 7, y + 7); + + canvas_draw_dot(canvas, x + 8, y); + canvas_draw_dot(canvas, x + 8, y + 3); + canvas_draw_dot(canvas, x + 8, y + 6); + + canvas_draw_dot(canvas, x + 9, y); + canvas_draw_dot(canvas, x + 9, y + 3); + canvas_draw_dot(canvas, x + 9, y + 6); + + canvas_draw_dot(canvas, x + 10, y); + canvas_draw_dot(canvas, x + 10, y + 3); + canvas_draw_dot(canvas, x + 10, y + 6); + + canvas_draw_dot(canvas, x + 11, y); + canvas_draw_dot(canvas, x + 11, y + 1); + canvas_draw_dot(canvas, x + 11, y + 3); + canvas_draw_dot(canvas, x + 11, y + 6); + + canvas_draw_dot(canvas, x + 12, y + 1); + canvas_draw_dot(canvas, x + 12, y + 2); + canvas_draw_dot(canvas, x + 12, y + 3); + canvas_draw_dot(canvas, x + 12, y + 6); + canvas_draw_dot(canvas, x + 12, y + 7); + + canvas_draw_dot(canvas, x + 13, y + 2); + canvas_draw_dot(canvas, x + 13, y + 3); + canvas_draw_dot(canvas, x + 13, y + 5); + canvas_draw_dot(canvas, x + 13, y + 8); + + canvas_draw_dot(canvas, x + 14, y + 1); + canvas_draw_dot(canvas, x + 14, y + 2); + canvas_draw_dot(canvas, x + 14, y + 5); + canvas_draw_dot(canvas, x + 14, y + 8); + + canvas_draw_dot(canvas, x + 15, y); + canvas_draw_dot(canvas, x + 15, y + 1); + canvas_draw_dot(canvas, x + 15, y + 6); + canvas_draw_dot(canvas, x + 15, y + 7); + + canvas_draw_dot(canvas, x + 16, y); + canvas_draw_dot(canvas, x + 16, y + 1); + canvas_draw_dot(canvas, x + 16, y + 2); + canvas_draw_dot(canvas, x + 16, y + 3); + canvas_draw_dot(canvas, x + 16, y + 4); + canvas_draw_dot(canvas, x + 16, y + 5); +} + +const uint8_t _I_DoorClosed_22x35_0[] = { + 0x01, 0x00, 0x23, 0x00, 0xfe, 0x7f, 0xe1, 0xf0, 0x28, 0x04, 0x43, 0xe3, 0xff, + 0x91, 0xea, 0x75, 0x52, 0x6a, 0xad, 0x56, 0x5b, 0xad, 0xd5, 0x4a, 0x80, 0xbe, + 0x05, 0xf0, 0x2f, 0x81, 0x7c, 0x0b, 0x45, 0x32, 0x2c, 0x91, 0x7c, 0x8c, 0xa4, +}; +const uint8_t* _I_DoorClosed_22x35[] = {_I_DoorClosed_22x35_0}; +const Icon I_DoorClosed_22x35 = + {.width = 22, .height = 35, .frame_count = 1, .frame_rate = 0, .frames = _I_DoorClosed_22x35}; + +typedef struct { + bool isOpen; + bool isSelected; // picked in RoundOne, RoundThree + bool isWinningDoor; // randomized in RoundOne +} Door; + +typedef struct { + Door doors[3]; + bool didSelect; // false in RoundOne -> RoundTwo when true + bool didSwitch; // determined in RoundFour +} DoorState; + +typedef enum { + RoundOne, // all doors closed, player selects a door when ready + RoundTwo, // door selected, reveal one of the remaining two (can go straight to GameOver) + RoundThree, // player can keep or switch their selection + RoundFour, // reveal all doors + GameOver // score has been updated, allow restart +} GameState; + +typedef struct { + GameState game_state; + DoorState door_state; + uint16_t score; +} MontyState; + +static void montyhall_game_init_state(MontyState* monty_state) { + if(!monty_state->score) { + monty_state->score = 0; + } + monty_state->door_state.didSelect = false; + + for(int i = 0; i < 3; i++) { + monty_state->door_state.doors[i].isOpen = false; + monty_state->door_state.doors[i].isSelected = false; + monty_state->door_state.doors[i].isWinningDoor = false; + } + + monty_state->game_state = RoundOne; + int doorIndex = random() % 3; + monty_state->door_state.doors[doorIndex].isWinningDoor = true; +} + +void selectDoor(MontyState* monty_state, int doorIndex) { + if(monty_state->game_state == RoundOne) { + monty_state->door_state.doors[doorIndex].isSelected = true; + if(monty_state->door_state.doors[doorIndex].isSelected) { + monty_state->door_state.didSelect = true; + monty_state->game_state = RoundTwo; + } + } else if(monty_state->game_state == RoundThree) { + for(int i = 0; i < 3; i++) { + monty_state->door_state.doors[i].isSelected = false; + } + + monty_state->door_state.doors[doorIndex].isSelected = true; + } +} + +int getRandomDoorIndex() { + int randomDoorIndex = random() % 3; + return randomDoorIndex; +} + +void revealBadDoor(MontyState* monty_state) { + int doorToReveal = getRandomDoorIndex(); + while(!monty_state->door_state.doors[doorToReveal].isOpen) { + if(!(monty_state->door_state.doors[doorToReveal].isSelected || + monty_state->door_state.doors[doorToReveal].isWinningDoor)) { + monty_state->door_state.doors[doorToReveal].isOpen = true; + } else { + doorToReveal = getRandomDoorIndex(); + } + } +} + +void revealDoors_updateScore(MontyState* monty_state) { + for(int i = 0; i < 3; i++) { + monty_state->door_state.doors[i].isOpen = true; + + if(monty_state->door_state.doors[i].isWinningDoor && + monty_state->door_state.doors[i].isSelected) { + monty_state->score++; + } + } +} + +static void draw_top(Canvas* canvas, const MontyState* monty_state) { + char buffer[16]; + snprintf(buffer, sizeof(buffer), "Cars: %u", monty_state->score); + canvas_draw_str_aligned(canvas, 2, 8, AlignLeft, AlignBottom, buffer); + + if(monty_state->game_state == RoundThree) { + canvas_draw_str_aligned( + canvas, SCREEN_WIDTH - 5, 8, AlignRight, AlignBottom, "Opened a decoy door"); + } +} + +static void draw_doors(Canvas* canvas, const MontyState* monty_state) { + // {| 16 | <22> | 15 | <22> | 15 | <22> | 16 |} = SCREEN_WIDTH + if(monty_state->door_state.doors[0].isOpen) { + if(monty_state->door_state.doors[0].isWinningDoor) { + canvas_draw_frame(canvas, 16, 12, 22, 35); + draw_car(canvas, 18, 26); + } else { + canvas_draw_frame(canvas, 16, 12, 22, 35); + canvas_draw_str(canvas, 18, 34, "Goat"); + } + } else { + canvas_draw_icon(canvas, 16, 12, &I_DoorClosed_22x35); + } + + if(monty_state->door_state.doors[1].isOpen) { + if(monty_state->door_state.doors[1].isWinningDoor) { + canvas_draw_frame(canvas, 53, 12, 22, 35); + draw_car(canvas, 55, 26); + } else { + canvas_draw_frame(canvas, 53, 12, 22, 35); + canvas_draw_str(canvas, 55, 34, "Goat"); + } + } else { + canvas_draw_icon(canvas, 53, 12, &I_DoorClosed_22x35); + } + + if(monty_state->door_state.doors[2].isOpen) { + if(monty_state->door_state.doors[2].isWinningDoor) { + canvas_draw_frame(canvas, 90, 12, 22, 35); + draw_car(canvas, 92, 26); + } else { + canvas_draw_frame(canvas, 90, 12, 22, 35); + canvas_draw_str(canvas, 92, 34, "Goat"); + } + } else { + canvas_draw_icon(canvas, 90, 12, &I_DoorClosed_22x35); + } +} + +static void draw_bottom(Canvas* canvas, const MontyState* monty_state) { + if(monty_state->game_state == RoundOne) { + elements_button_left(canvas, "Left"); + elements_button_center(canvas, "Center"); + elements_button_right(canvas, "Right"); + } + + if(monty_state->game_state == RoundThree) { + if(monty_state->door_state.doors[0].isSelected) { + elements_button_left(canvas, "Keep"); + if(!monty_state->door_state.doors[1].isOpen) { + elements_button_center(canvas, "Switch"); + } else { + elements_button_right(canvas, "Switch"); + } + } else if(monty_state->door_state.doors[1].isSelected) { + elements_button_center(canvas, "Keep"); + if(!monty_state->door_state.doors[0].isOpen) { + elements_button_left(canvas, "Switch"); + } else { + elements_button_right(canvas, "Switch"); + } + } else if(monty_state->door_state.doors[2].isSelected) { + elements_button_right(canvas, "Keep"); + if(!monty_state->door_state.doors[0].isOpen) { + elements_button_left(canvas, "Switch"); + } else { + elements_button_center(canvas, "Switch"); + } + } + } + + if(monty_state->game_state == RoundFour) { + elements_button_center(canvas, "Reveal"); + } + + if(monty_state->game_state == GameOver) { + canvas_draw_str(canvas, 16, SCREEN_HEIGHT - 5, "Hold center to restart"); + } +} + +static void montyhall_render_callback(Canvas* const canvas, void* ctx) { + const MontyState* monty_state = acquire_mutex((ValueMutex*)ctx, 25); + if(monty_state == NULL) { + return; + } + + canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + draw_top(canvas, monty_state); + draw_doors(canvas, monty_state); + draw_bottom(canvas, monty_state); + + release_mutex((ValueMutex*)ctx, monty_state); +} + +static void montyhall_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { + furi_assert(event_queue); + + furi_message_queue_put(event_queue, input_event, FuriWaitForever); +} + +int32_t montyhall_game_app(void* p) { + UNUSED(p); + int32_t return_code = 0; + + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + MontyState* monty_state = malloc(sizeof(MontyState)); + + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, monty_state, sizeof(MontyState))) { + return_code = 255; + goto free_and_exit; + } + + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, montyhall_render_callback, &state_mutex); + view_port_input_callback_set(view_port, montyhall_input_callback, event_queue); + + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + // Start the game + montyhall_game_init_state(monty_state); + + InputEvent event; + for(bool loop = true; loop;) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); + MontyState* monty_state = (MontyState*)acquire_mutex_block(&state_mutex); + + if(event_status == FuriStatusOk) { + if(event.type == InputTypeShort) { + switch(event.key) { + case InputKeyUp: /* + if(monty_state->game_state == RoundOne) { + monty_state->score++; + } else if(monty_state->game_state == RoundTwo) { + monty_state->score += 2; + } else if(monty_state->game_state == RoundThree) { + monty_state->score += 3; + } else if(monty_state->game_state == RoundFour) { + monty_state->score += 4; + } else if(monty_state->game_state == GameOver) { + monty_state->score += 5; + } */ + break; + case InputKeyDown: /* + if(monty_state->game_state == RoundOne) { + monty_state->score--; + } else if(monty_state->game_state == RoundTwo) { + monty_state->score -= 2; + } else if(monty_state->game_state == RoundThree) { + monty_state->score -= 3; + } else if(monty_state->game_state == RoundFour) { + monty_state->score -= 4; + } else if(monty_state->game_state == GameOver) { + monty_state->score -= 5; + } */ + break; + case InputKeyLeft: + if(monty_state->game_state == RoundOne) { + selectDoor(monty_state, 0); + if(monty_state->game_state == RoundTwo) { + revealBadDoor(monty_state); + monty_state->game_state = RoundThree; + } + } else if(monty_state->game_state == RoundThree) { + if(monty_state->door_state.doors[0].isSelected) { + monty_state->door_state.didSwitch = false; + } else if(!monty_state->door_state.doors[0].isOpen) { + monty_state->door_state.didSwitch = true; + selectDoor(monty_state, 0); + } + monty_state->game_state = RoundFour; + } + break; + case InputKeyOk: + if(monty_state->game_state == RoundOne) { + selectDoor(monty_state, 1); + if(monty_state->game_state == RoundTwo) { + revealBadDoor(monty_state); + monty_state->game_state = RoundThree; + } + } else if(monty_state->game_state == RoundThree) { + if(monty_state->door_state.doors[1].isSelected) { + monty_state->door_state.didSwitch = false; + } else if(!monty_state->door_state.doors[1].isOpen) { + monty_state->door_state.didSwitch = true; + selectDoor(monty_state, 1); + } + monty_state->game_state = RoundFour; + } else if(monty_state->game_state == RoundFour) { + revealDoors_updateScore(monty_state); + monty_state->game_state = GameOver; + } + break; + case InputKeyRight: + if(monty_state->game_state == RoundOne) { + selectDoor(monty_state, 2); + if(monty_state->game_state == RoundTwo) { + revealBadDoor(monty_state); + monty_state->game_state = RoundThree; + } + } else if(monty_state->game_state == RoundThree) { + if(monty_state->door_state.doors[2].isSelected) { + monty_state->door_state.didSwitch = false; + } else if(!monty_state->door_state.doors[2].isOpen) { + monty_state->door_state.didSwitch = true; + selectDoor(monty_state, 2); + } + monty_state->game_state = RoundFour; + } + break; + case InputKeyBack: + loop = false; + break; + default: + break; + } + } + } else if(event.type == InputTypeLong) { + if(event.key == InputKeyOk && monty_state->game_state == GameOver) { + montyhall_game_init_state(monty_state); + } + } + + view_port_update(view_port); + release_mutex(&state_mutex, monty_state); + } + + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + furi_record_close(RECORD_GUI); + view_port_free(view_port); + delete_mutex(&state_mutex); + +free_and_exit: + free(monty_state); + furi_message_queue_free(event_queue); + + return return_code; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/music_beeper/application.fam b/Applications/Official/DEV_FW/source/xMasterX/music_beeper/application.fam new file mode 100644 index 000000000..affd2fa4e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/music_beeper/application.fam @@ -0,0 +1,25 @@ +App( + appid="Music_Beeper", + name="Music Beeper", + apptype=FlipperAppType.EXTERNAL, + entry_point="music_beeper_app", + cdefines=["APP_MUSIC_BEEPER"], + requires=[ + "gui", + "dialogs", + ], + provides=["music_beeper_start"], + stack_size=2 * 1024, + order=45, + fap_icon="music_10px.png", + fap_icon_assets="icons", + fap_category="Music_Extra", +) + +App( + appid="music_beeper_start", + apptype=FlipperAppType.STARTUP, + entry_point="music_beeper_on_system_start", + requires=["music_beeper"], + order=30, +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/music_beeper/icons/music_10px.png b/Applications/Official/DEV_FW/source/xMasterX/music_beeper/icons/music_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..d41eb0db8c822c60be6c097393b3682680b81a6c GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xGmzZ=C-xtZVhivIasA%~WHIdey2}7aaTa() z7Bet#3xhBt!>l_x9Asc&(0a_=e)W&n8K5!-Pgg&ebxsLQ0Ao%f>i_@% literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_10px.png b/Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..d41eb0db8c822c60be6c097393b3682680b81a6c GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xGmzZ=C-xtZVhivIasA%~WHIdey2}7aaTa() z7Bet#3xhBt!>l_x9Asc&(0a_=e)W&n8K5!-Pgg&ebxsLQ0Ao%f>i_@% literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_beeper.c b/Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_beeper.c new file mode 100644 index 000000000..edebbc597 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_beeper.c @@ -0,0 +1,367 @@ +#include "music_beeper_worker.h" + +#include +#include + +#include +#include +#include +#include + +#define TAG "MusicBeeper" + +#define MUSIC_BEEPER_APP_PATH_FOLDER ANY_PATH("music_player") +#define MUSIC_BEEPER_APP_EXTENSION "*" + +#define MUSIC_BEEPER_SEMITONE_HISTORY_SIZE 4 + +typedef struct { + uint8_t semitone_history[MUSIC_BEEPER_SEMITONE_HISTORY_SIZE]; + uint8_t duration_history[MUSIC_BEEPER_SEMITONE_HISTORY_SIZE]; + + uint8_t volume; + uint8_t semitone; + uint8_t dots; + uint8_t duration; + float position; +} MusicBeeperModel; + +typedef struct { + MusicBeeperModel* model; + FuriMutex** model_mutex; + + FuriMessageQueue* input_queue; + + ViewPort* view_port; + Gui* gui; + + MusicBeeperWorker* worker; +} MusicBeeper; + +static const float MUSIC_BEEPER_VOLUMES[] = {0, .25, .5, .75, 1}; + +static const char* semitone_to_note(int8_t semitone) { + switch(semitone) { + case 0: + return "C"; + case 1: + return "C#"; + case 2: + return "D"; + case 3: + return "D#"; + case 4: + return "E"; + case 5: + return "F"; + case 6: + return "F#"; + case 7: + return "G"; + case 8: + return "G#"; + case 9: + return "A"; + case 10: + return "A#"; + case 11: + return "B"; + default: + return "--"; + } +} + +static bool is_white_note(uint8_t semitone, uint8_t id) { + switch(semitone) { + case 0: + if(id == 0) return true; + break; + case 2: + if(id == 1) return true; + break; + case 4: + if(id == 2) return true; + break; + case 5: + if(id == 3) return true; + break; + case 7: + if(id == 4) return true; + break; + case 9: + if(id == 5) return true; + break; + case 11: + if(id == 6) return true; + break; + default: + break; + } + + return false; +} + +static bool is_black_note(uint8_t semitone, uint8_t id) { + switch(semitone) { + case 1: + if(id == 0) return true; + break; + case 3: + if(id == 1) return true; + break; + case 6: + if(id == 3) return true; + break; + case 8: + if(id == 4) return true; + break; + case 10: + if(id == 5) return true; + break; + default: + break; + } + + return false; +} + +static void render_callback(Canvas* canvas, void* ctx) { + MusicBeeper* music_beeper = ctx; + furi_check(furi_mutex_acquire(music_beeper->model_mutex, FuriWaitForever) == FuriStatusOk); + + canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 0, 12, "MusicBeeper"); + + uint8_t x_pos = 0; + uint8_t y_pos = 24; + const uint8_t white_w = 10; + const uint8_t white_h = 40; + + const int8_t black_x = 6; + const int8_t black_y = -5; + const uint8_t black_w = 8; + const uint8_t black_h = 32; + + // white keys + for(size_t i = 0; i < 7; i++) { + if(is_white_note(music_beeper->model->semitone, i)) { + canvas_draw_box(canvas, x_pos + white_w * i, y_pos, white_w + 1, white_h); + } else { + canvas_draw_frame(canvas, x_pos + white_w * i, y_pos, white_w + 1, white_h); + } + } + + // black keys + for(size_t i = 0; i < 7; i++) { + if(i != 2 && i != 6) { + canvas_set_color(canvas, ColorWhite); + canvas_draw_box( + canvas, x_pos + white_w * i + black_x, y_pos + black_y, black_w + 1, black_h); + canvas_set_color(canvas, ColorBlack); + if(is_black_note(music_beeper->model->semitone, i)) { + canvas_draw_box( + canvas, x_pos + white_w * i + black_x, y_pos + black_y, black_w + 1, black_h); + } else { + canvas_draw_frame( + canvas, x_pos + white_w * i + black_x, y_pos + black_y, black_w + 1, black_h); + } + } + } + + // volume view_port + x_pos = 124; + y_pos = 0; + const uint8_t volume_h = + (64 / (COUNT_OF(MUSIC_BEEPER_VOLUMES) - 1)) * music_beeper->model->volume; + canvas_draw_frame(canvas, x_pos, y_pos, 4, 64); + canvas_draw_box(canvas, x_pos, y_pos + (64 - volume_h), 4, volume_h); + + // note stack view_port + x_pos = 73; + y_pos = 0; + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontPrimary); + canvas_draw_frame(canvas, x_pos, y_pos, 49, 64); + canvas_draw_line(canvas, x_pos + 28, 0, x_pos + 28, 64); + + char duration_text[16]; + for(uint8_t i = 0; i < MUSIC_BEEPER_SEMITONE_HISTORY_SIZE; i++) { + if(music_beeper->model->duration_history[i] == 0xFF) { + snprintf(duration_text, 15, "--"); + } else { + snprintf(duration_text, 15, "%d", music_beeper->model->duration_history[i]); + } + + if(i == 0) { + canvas_draw_box(canvas, x_pos, y_pos + 48, 49, 16); + canvas_set_color(canvas, ColorWhite); + } else { + canvas_set_color(canvas, ColorBlack); + } + canvas_draw_str( + canvas, + x_pos + 4, + 64 - 16 * i - 3, + semitone_to_note(music_beeper->model->semitone_history[i])); + canvas_draw_str(canvas, x_pos + 31, 64 - 16 * i - 3, duration_text); + canvas_draw_line(canvas, x_pos, 64 - 16 * i, x_pos + 48, 64 - 16 * i); + } + + furi_mutex_release(music_beeper->model_mutex); +} + +static void input_callback(InputEvent* input_event, void* ctx) { + MusicBeeper* music_beeper = ctx; + if(input_event->type == InputTypeShort) { + furi_message_queue_put(music_beeper->input_queue, input_event, 0); + } +} + +static void music_beeper_worker_callback( + uint8_t semitone, + uint8_t dots, + uint8_t duration, + float position, + void* context) { + MusicBeeper* music_beeper = context; + furi_check(furi_mutex_acquire(music_beeper->model_mutex, FuriWaitForever) == FuriStatusOk); + + for(size_t i = 0; i < MUSIC_BEEPER_SEMITONE_HISTORY_SIZE - 1; i++) { + size_t r = MUSIC_BEEPER_SEMITONE_HISTORY_SIZE - 1 - i; + music_beeper->model->duration_history[r] = music_beeper->model->duration_history[r - 1]; + music_beeper->model->semitone_history[r] = music_beeper->model->semitone_history[r - 1]; + } + + semitone = (semitone == 0xFF) ? 0xFF : semitone % 12; + + music_beeper->model->semitone = semitone; + music_beeper->model->dots = dots; + music_beeper->model->duration = duration; + music_beeper->model->position = position; + + music_beeper->model->semitone_history[0] = semitone; + music_beeper->model->duration_history[0] = duration; + + furi_mutex_release(music_beeper->model_mutex); + view_port_update(music_beeper->view_port); +} + +void music_beeper_clear(MusicBeeper* instance) { + memset(instance->model->duration_history, 0xff, MUSIC_BEEPER_SEMITONE_HISTORY_SIZE); + memset(instance->model->semitone_history, 0xff, MUSIC_BEEPER_SEMITONE_HISTORY_SIZE); + music_beeper_worker_clear(instance->worker); +} + +MusicBeeper* music_beeper_alloc() { + MusicBeeper* instance = malloc(sizeof(MusicBeeper)); + + instance->model = malloc(sizeof(MusicBeeperModel)); + instance->model->volume = 4; + + instance->model_mutex = furi_mutex_alloc(FuriMutexTypeNormal); + + instance->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + instance->worker = music_beeper_worker_alloc(); + music_beeper_worker_set_volume( + instance->worker, MUSIC_BEEPER_VOLUMES[instance->model->volume]); + music_beeper_worker_set_callback(instance->worker, music_beeper_worker_callback, instance); + + music_beeper_clear(instance); + + instance->view_port = view_port_alloc(); + view_port_draw_callback_set(instance->view_port, render_callback, instance); + view_port_input_callback_set(instance->view_port, input_callback, instance); + + // Open GUI and register view_port + instance->gui = furi_record_open(RECORD_GUI); + gui_add_view_port(instance->gui, instance->view_port, GuiLayerFullscreen); + + return instance; +} + +void music_beeper_free(MusicBeeper* instance) { + gui_remove_view_port(instance->gui, instance->view_port); + furi_record_close(RECORD_GUI); + view_port_free(instance->view_port); + + music_beeper_worker_free(instance->worker); + + furi_message_queue_free(instance->input_queue); + + furi_mutex_free(instance->model_mutex); + + free(instance->model); + free(instance); +} + +int32_t music_beeper_app(void* p) { + MusicBeeper* music_beeper = music_beeper_alloc(); + + FuriString* file_path; + file_path = furi_string_alloc(); + + do { + if(p && strlen(p)) { + furi_string_set(file_path, (const char*)p); + } else { + furi_string_set(file_path, MUSIC_BEEPER_APP_PATH_FOLDER); + + DialogsFileBrowserOptions browser_options; + dialog_file_browser_set_basic_options( + &browser_options, MUSIC_BEEPER_APP_EXTENSION, &I_music_10px); + browser_options.hide_ext = false; + + DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); + bool res = dialog_file_browser_show(dialogs, file_path, file_path, &browser_options); + + furi_record_close(RECORD_DIALOGS); + if(!res) { + FURI_LOG_E(TAG, "No file selected"); + break; + } + } + + if(!music_beeper_worker_load(music_beeper->worker, furi_string_get_cstr(file_path))) { + FURI_LOG_E(TAG, "Unable to load file"); + break; + } + + music_beeper_worker_start(music_beeper->worker); + + InputEvent input; + while(furi_message_queue_get(music_beeper->input_queue, &input, FuriWaitForever) == + FuriStatusOk) { + furi_check( + furi_mutex_acquire(music_beeper->model_mutex, FuriWaitForever) == FuriStatusOk); + + if(input.key == InputKeyBack) { + furi_mutex_release(music_beeper->model_mutex); + break; + } else if(input.key == InputKeyUp) { + if(music_beeper->model->volume < COUNT_OF(MUSIC_BEEPER_VOLUMES) - 1) + music_beeper->model->volume++; + music_beeper_worker_set_volume( + music_beeper->worker, MUSIC_BEEPER_VOLUMES[music_beeper->model->volume]); + } else if(input.key == InputKeyDown) { + if(music_beeper->model->volume > 0) music_beeper->model->volume--; + music_beeper_worker_set_volume( + music_beeper->worker, MUSIC_BEEPER_VOLUMES[music_beeper->model->volume]); + } + + furi_mutex_release(music_beeper->model_mutex); + view_port_update(music_beeper->view_port); + } + + music_beeper_worker_stop(music_beeper->worker); + if(p && strlen(p)) break; // Exit instead of going to browser if launched with arg + music_beeper_clear(music_beeper); + } while(1); + + furi_string_free(file_path); + music_beeper_free(music_beeper); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_beeper_cli.c b/Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_beeper_cli.c new file mode 100644 index 000000000..26299fa64 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_beeper_cli.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include "music_beeper_worker.h" + +static void music_beeper_cli(Cli* cli, FuriString* args, void* context) { + UNUSED(context); + MusicBeeperWorker* music_beeper_worker = music_beeper_worker_alloc(); + Storage* storage = furi_record_open(RECORD_STORAGE); + + do { + if(storage_common_stat(storage, furi_string_get_cstr(args), NULL) == FSE_OK) { + if(!music_beeper_worker_load(music_beeper_worker, furi_string_get_cstr(args))) { + printf("Failed to open file %s\r\n", furi_string_get_cstr(args)); + break; + } + } else { + if(!music_beeper_worker_load_rtttl_from_string( + music_beeper_worker, furi_string_get_cstr(args))) { + printf("Argument is not a file or RTTTL\r\n"); + break; + } + } + + printf("Press CTRL+C to stop\r\n"); + music_beeper_worker_set_volume(music_beeper_worker, 1.0f); + music_beeper_worker_start(music_beeper_worker); + while(!cli_cmd_interrupt_received(cli)) { + furi_delay_ms(50); + } + music_beeper_worker_stop(music_beeper_worker); + } while(0); + + furi_record_close(RECORD_STORAGE); + music_beeper_worker_free(music_beeper_worker); +} + +void music_beeper_on_system_start() { +#ifdef SRV_CLI + Cli* cli = furi_record_open(RECORD_CLI); + + cli_add_command(cli, "music_beeper", CliCommandFlagDefault, music_beeper_cli, NULL); + + furi_record_close(RECORD_CLI); +#else + UNUSED(music_beeper_cli); +#endif +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_beeper_worker.c b/Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_beeper_worker.c new file mode 100644 index 000000000..e06e77447 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_beeper_worker.c @@ -0,0 +1,510 @@ +#include "music_beeper_worker.h" + +#include +#include + +#include +#include + +#include + +#define TAG "MusicBeeperWorker" + +#define MUSIC_BEEPER_FILETYPE "Flipper Music Format" +#define MUSIC_BEEPER_VERSION 0 + +#define SEMITONE_PAUSE 0xFF + +#define NOTE_C4 261.63f +#define NOTE_C4_SEMITONE (4.0f * 12.0f) +#define TWO_POW_TWELTH_ROOT 1.059463094359f + +typedef struct { + uint8_t semitone; + uint8_t duration; + uint8_t dots; +} NoteBlock; + +ARRAY_DEF(NoteBlockArray, NoteBlock, M_POD_OPLIST); + +struct MusicBeeperWorker { + FuriThread* thread; + bool should_work; + + MusicBeeperWorkerCallback callback; + void* callback_context; + + float volume; + uint32_t bpm; + uint32_t duration; + uint32_t octave; + NoteBlockArray_t notes; +}; + +static int32_t music_beeper_worker_thread_callback(void* context) { + furi_assert(context); + MusicBeeperWorker* instance = context; + + NoteBlockArray_it_t it; + NoteBlockArray_it(it, instance->notes); + if(furi_hal_speaker_acquire(1000)) { + while(instance->should_work) { + if(NoteBlockArray_end_p(it)) { + NoteBlockArray_it(it, instance->notes); + furi_delay_ms(10); + } else { + NoteBlock* note_block = NoteBlockArray_ref(it); + + float note_from_a4 = (float)note_block->semitone - NOTE_C4_SEMITONE; + float frequency = NOTE_C4 * powf(TWO_POW_TWELTH_ROOT, note_from_a4); + float duration = 60.0 * furi_kernel_get_tick_frequency() * 4 / instance->bpm / + note_block->duration; + uint32_t dots = note_block->dots; + while(dots > 0) { + duration += duration / 2; + dots--; + } + uint32_t next_tick = furi_get_tick() + duration; + float volume = instance->volume; + + if(instance->callback) { + instance->callback( + note_block->semitone, + note_block->dots, + note_block->duration, + 0.0, + instance->callback_context); + } + + furi_hal_speaker_stop(); + furi_hal_speaker_start(frequency, volume); + while(instance->should_work && furi_get_tick() < next_tick) { + volume *= 1; + furi_hal_speaker_set_volume(volume); + furi_delay_ms(2); + } + NoteBlockArray_next(it); + } + } + + furi_hal_speaker_stop(); + furi_hal_speaker_release(); + } else { + FURI_LOG_E(TAG, "Speaker system is busy with another process."); + } + + return 0; +} + +MusicBeeperWorker* music_beeper_worker_alloc() { + MusicBeeperWorker* instance = malloc(sizeof(MusicBeeperWorker)); + + NoteBlockArray_init(instance->notes); + + instance->thread = furi_thread_alloc(); + furi_thread_set_name(instance->thread, "MusicBeeperWorker"); + furi_thread_set_stack_size(instance->thread, 1024); + furi_thread_set_context(instance->thread, instance); + furi_thread_set_callback(instance->thread, music_beeper_worker_thread_callback); + + instance->volume = 1.0f; + + return instance; +} + +void music_beeper_worker_clear(MusicBeeperWorker* instance) { + NoteBlockArray_reset(instance->notes); +} + +void music_beeper_worker_free(MusicBeeperWorker* instance) { + furi_assert(instance); + furi_thread_free(instance->thread); + NoteBlockArray_clear(instance->notes); + free(instance); +} + +static bool is_digit(const char c) { + return isdigit(c) != 0; +} + +static bool is_letter(const char c) { + return islower(c) != 0 || isupper(c) != 0; +} + +static bool is_space(const char c) { + return c == ' ' || c == '\t'; +} + +static size_t extract_number(const char* string, uint32_t* number) { + size_t ret = 0; + *number = 0; + while(is_digit(*string)) { + *number *= 10; + *number += (*string - '0'); + string++; + ret++; + } + return ret; +} + +static size_t extract_dots(const char* string, uint32_t* number) { + size_t ret = 0; + *number = 0; + while(*string == '.') { + *number += 1; + string++; + ret++; + } + return ret; +} + +static size_t extract_char(const char* string, char* symbol) { + if(is_letter(*string)) { + *symbol = *string; + return 1; + } else { + return 0; + } +} + +static size_t extract_sharp(const char* string, char* symbol) { + if(*string == '#' || *string == '_') { + *symbol = '#'; + return 1; + } else { + return 0; + } +} + +static size_t skip_till(const char* string, const char symbol) { + size_t ret = 0; + while(*string != '\0' && *string != symbol) { + string++; + ret++; + } + if(*string != symbol) { + ret = 0; + } + return ret; +} + +static bool music_beeper_worker_add_note( + MusicBeeperWorker* instance, + uint8_t semitone, + uint8_t duration, + uint8_t dots) { + NoteBlock note_block; + + note_block.semitone = semitone; + note_block.duration = duration; + note_block.dots = dots; + + NoteBlockArray_push_back(instance->notes, note_block); + + return true; +} + +static int8_t note_to_semitone(const char note) { + switch(note) { + case 'C': + return 0; + // C# + case 'D': + return 2; + // D# + case 'E': + return 4; + case 'F': + return 5; + // F# + case 'G': + return 7; + // G# + case 'A': + return 9; + // A# + case 'B': + return 11; + default: + return 0; + } +} + +static bool music_beeper_worker_parse_notes(MusicBeeperWorker* instance, const char* string) { + const char* cursor = string; + bool result = true; + + while(*cursor != '\0') { + if(!is_space(*cursor)) { + uint32_t duration = 0; + char note_char = '\0'; + char sharp_char = '\0'; + uint32_t octave = 0; + uint32_t dots = 0; + + // Parsing + cursor += extract_number(cursor, &duration); + cursor += extract_char(cursor, ¬e_char); + cursor += extract_sharp(cursor, &sharp_char); + cursor += extract_number(cursor, &octave); + cursor += extract_dots(cursor, &dots); + + // Post processing + note_char = toupper(note_char); + if(!duration) { + duration = instance->duration; + } + if(!octave) { + octave = instance->octave; + } + + // Validation + bool is_valid = true; + is_valid &= (duration >= 1 && duration <= 128); + is_valid &= ((note_char >= 'A' && note_char <= 'G') || note_char == 'P'); + is_valid &= (sharp_char == '#' || sharp_char == '\0'); + is_valid &= (octave <= 16); + is_valid &= (dots <= 16); + if(!is_valid) { + FURI_LOG_E( + TAG, + "Invalid note: %lu%c%c%lu.%lu", + duration, + note_char == '\0' ? '_' : note_char, + sharp_char == '\0' ? '_' : sharp_char, + octave, + dots); + result = false; + break; + } + + // Note to semitones + uint8_t semitone = 0; + if(note_char == 'P') { + semitone = SEMITONE_PAUSE; + } else { + semitone += octave * 12; + semitone += note_to_semitone(note_char); + semitone += sharp_char == '#' ? 1 : 0; + } + + if(music_beeper_worker_add_note(instance, semitone, duration, dots)) { + FURI_LOG_D( + TAG, + "Added note: %c%c%lu.%lu = %u %lu", + note_char == '\0' ? '_' : note_char, + sharp_char == '\0' ? '_' : sharp_char, + octave, + dots, + semitone, + duration); + } else { + FURI_LOG_E( + TAG, + "Invalid note: %c%c%lu.%lu = %u %lu", + note_char == '\0' ? '_' : note_char, + sharp_char == '\0' ? '_' : sharp_char, + octave, + dots, + semitone, + duration); + } + cursor += skip_till(cursor, ','); + } + + if(*cursor != '\0') cursor++; + } + + return result; +} + +bool music_beeper_worker_load(MusicBeeperWorker* instance, const char* file_path) { + furi_assert(instance); + furi_assert(file_path); + + bool ret = false; + if(strcasestr(file_path, ".fmf")) { + ret = music_beeper_worker_load_fmf_from_file(instance, file_path); + } else { + ret = music_beeper_worker_load_rtttl_from_file(instance, file_path); + } + return ret; +} + +bool music_beeper_worker_load_fmf_from_file(MusicBeeperWorker* instance, const char* file_path) { + furi_assert(instance); + furi_assert(file_path); + + bool result = false; + FuriString* temp_str; + temp_str = furi_string_alloc(); + + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* file = flipper_format_file_alloc(storage); + + do { + if(!flipper_format_file_open_existing(file, file_path)) break; + + uint32_t version = 0; + if(!flipper_format_read_header(file, temp_str, &version)) break; + if(furi_string_cmp_str(temp_str, MUSIC_BEEPER_FILETYPE) || + (version != MUSIC_BEEPER_VERSION)) { + FURI_LOG_E(TAG, "Incorrect file format or version"); + break; + } + + if(!flipper_format_read_uint32(file, "BPM", &instance->bpm, 1)) { + FURI_LOG_E(TAG, "BPM is missing"); + break; + } + if(!flipper_format_read_uint32(file, "Duration", &instance->duration, 1)) { + FURI_LOG_E(TAG, "Duration is missing"); + break; + } + if(!flipper_format_read_uint32(file, "Octave", &instance->octave, 1)) { + FURI_LOG_E(TAG, "Octave is missing"); + break; + } + + if(!flipper_format_read_string(file, "Notes", temp_str)) { + FURI_LOG_E(TAG, "Notes is missing"); + break; + } + + if(!music_beeper_worker_parse_notes(instance, furi_string_get_cstr(temp_str))) { + break; + } + + result = true; + } while(false); + + furi_record_close(RECORD_STORAGE); + flipper_format_free(file); + furi_string_free(temp_str); + + return result; +} + +bool music_beeper_worker_load_rtttl_from_file(MusicBeeperWorker* instance, const char* file_path) { + furi_assert(instance); + furi_assert(file_path); + + bool result = false; + FuriString* content; + content = furi_string_alloc(); + Storage* storage = furi_record_open(RECORD_STORAGE); + File* file = storage_file_alloc(storage); + + do { + if(!storage_file_open(file, file_path, FSAM_READ, FSOM_OPEN_EXISTING)) { + FURI_LOG_E(TAG, "Unable to open file"); + break; + }; + + uint16_t ret = 0; + do { + uint8_t buffer[65] = {0}; + ret = storage_file_read(file, buffer, sizeof(buffer) - 1); + for(size_t i = 0; i < ret; i++) { + furi_string_push_back(content, buffer[i]); + } + } while(ret > 0); + + furi_string_trim(content); + if(!furi_string_size(content)) { + FURI_LOG_E(TAG, "Empty file"); + break; + } + + if(!music_beeper_worker_load_rtttl_from_string(instance, furi_string_get_cstr(content))) { + FURI_LOG_E(TAG, "Invalid file content"); + break; + } + + result = true; + } while(0); + + storage_file_free(file); + furi_record_close(RECORD_STORAGE); + furi_string_free(content); + + return result; +} + +bool music_beeper_worker_load_rtttl_from_string(MusicBeeperWorker* instance, const char* string) { + furi_assert(instance); + + const char* cursor = string; + + // Skip name + cursor += skip_till(cursor, ':'); + if(*cursor != ':') { + return false; + } + + // Duration + cursor += skip_till(cursor, '='); + if(*cursor != '=') { + return false; + } + cursor++; + cursor += extract_number(cursor, &instance->duration); + + // Octave + cursor += skip_till(cursor, '='); + if(*cursor != '=') { + return false; + } + cursor++; + cursor += extract_number(cursor, &instance->octave); + + // BPM + cursor += skip_till(cursor, '='); + if(*cursor != '=') { + return false; + } + cursor++; + cursor += extract_number(cursor, &instance->bpm); + + // Notes + cursor += skip_till(cursor, ':'); + if(*cursor != ':') { + return false; + } + cursor++; + if(!music_beeper_worker_parse_notes(instance, cursor)) { + return false; + } + + return true; +} + +void music_beeper_worker_set_callback( + MusicBeeperWorker* instance, + MusicBeeperWorkerCallback callback, + void* context) { + furi_assert(instance); + instance->callback = callback; + instance->callback_context = context; +} + +void music_beeper_worker_set_volume(MusicBeeperWorker* instance, float volume) { + furi_assert(instance); + instance->volume = volume; +} + +void music_beeper_worker_start(MusicBeeperWorker* instance) { + furi_assert(instance); + furi_assert(instance->should_work == false); + + instance->should_work = true; + furi_thread_start(instance->thread); +} + +void music_beeper_worker_stop(MusicBeeperWorker* instance) { + furi_assert(instance); + furi_assert(instance->should_work == true); + + instance->should_work = false; + furi_thread_join(instance->thread); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_beeper_worker.h b/Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_beeper_worker.h new file mode 100644 index 000000000..bc30abf81 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/music_beeper/music_beeper_worker.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*MusicBeeperWorkerCallback)( + uint8_t semitone, + uint8_t dots, + uint8_t duration, + float position, + void* context); + +typedef struct MusicBeeperWorker MusicBeeperWorker; + +MusicBeeperWorker* music_beeper_worker_alloc(); + +void music_beeper_worker_clear(MusicBeeperWorker* instance); + +void music_beeper_worker_free(MusicBeeperWorker* instance); + +bool music_beeper_worker_load(MusicBeeperWorker* instance, const char* file_path); + +bool music_beeper_worker_load_fmf_from_file(MusicBeeperWorker* instance, const char* file_path); + +bool music_beeper_worker_load_rtttl_from_file(MusicBeeperWorker* instance, const char* file_path); + +bool music_beeper_worker_load_rtttl_from_string(MusicBeeperWorker* instance, const char* string); + +void music_beeper_worker_set_callback( + MusicBeeperWorker* instance, + MusicBeeperWorkerCallback callback, + void* context); + +void music_beeper_worker_set_volume(MusicBeeperWorker* instance, float volume); + +void music_beeper_worker_start(MusicBeeperWorker* instance); + +void music_beeper_worker_stop(MusicBeeperWorker* instance); + +#ifdef __cplusplus +} +#endif diff --git a/Applications/Official/DEV_FW/source/xMasterX/musictracker/.github/workflows/build_dev.yml b/Applications/Official/DEV_FW/source/xMasterX/musictracker/.github/workflows/build_dev.yml new file mode 100644 index 000000000..4d3da2331 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/musictracker/.github/workflows/build_dev.yml @@ -0,0 +1,19 @@ +name: Build dev + +on: + push: + branches: + - master + +jobs: + build_dev: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Build + uses: oleksiikutuzov/flipperzero-ufbt-action@v1 + with: + channel: dev \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/musictracker/README.md b/Applications/Official/DEV_FW/source/xMasterX/musictracker/README.md new file mode 100644 index 000000000..584c2ff86 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/musictracker/README.md @@ -0,0 +1,4 @@ +# Flipper Zero music tracker +-=-=- MVP Stage: minimum viable player -=-=- + +[>Get latest build<](https://nightly.link/DrZlo13/flipper-zero-music-tracker/workflows/build_dev/master/zero_tracker.fap.zip) diff --git a/Applications/Official/DEV_FW/source/xMasterX/musictracker/application.fam b/Applications/Official/DEV_FW/source/xMasterX/musictracker/application.fam new file mode 100644 index 000000000..15328c3fa --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/musictracker/application.fam @@ -0,0 +1,14 @@ +App( + appid="zero_tracker", + name="Zero Tracker", + apptype=FlipperAppType.PLUGIN, + entry_point="zero_tracker_app", + requires=[ + "gui", + ], + stack_size=4 * 1024, + order=20, + fap_icon="zero_tracker.png", + fap_category="Music_Extra", + fap_icon_assets="icons", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/musictracker/icons/.gitignore b/Applications/Official/DEV_FW/source/xMasterX/musictracker/icons/.gitignore new file mode 100644 index 000000000..e69de29bb diff --git a/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/speaker_hal.c b/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/speaker_hal.c new file mode 100644 index 000000000..94489f1b6 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/speaker_hal.c @@ -0,0 +1,107 @@ +#include "speaker_hal.h" + +#define FURI_HAL_SPEAKER_TIMER TIM16 +#define FURI_HAL_SPEAKER_CHANNEL LL_TIM_CHANNEL_CH1 +#define FURI_HAL_SPEAKER_PRESCALER 500 + +void tracker_speaker_play(float frequency, float pwm) { + uint32_t autoreload = (SystemCoreClock / FURI_HAL_SPEAKER_PRESCALER / frequency) - 1; + if(autoreload < 2) { + autoreload = 2; + } else if(autoreload > UINT16_MAX) { + autoreload = UINT16_MAX; + } + + if(pwm < 0) pwm = 0; + if(pwm > 1) pwm = 1; + + uint32_t compare_value = pwm * autoreload; + + if(compare_value == 0) { + compare_value = 1; + } + + if(LL_TIM_OC_GetCompareCH1(FURI_HAL_SPEAKER_TIMER) != compare_value) { + LL_TIM_OC_SetCompareCH1(FURI_HAL_SPEAKER_TIMER, compare_value); + } + + if(LL_TIM_GetAutoReload(FURI_HAL_SPEAKER_TIMER) != autoreload) { + LL_TIM_SetAutoReload(FURI_HAL_SPEAKER_TIMER, autoreload); + if(LL_TIM_GetCounter(FURI_HAL_SPEAKER_TIMER) > autoreload) { + LL_TIM_SetCounter(FURI_HAL_SPEAKER_TIMER, 0); + } + } + + LL_TIM_EnableAllOutputs(FURI_HAL_SPEAKER_TIMER); +} + +void tracker_speaker_stop() { + LL_TIM_DisableAllOutputs(FURI_HAL_SPEAKER_TIMER); +} + +void tracker_speaker_init() { + if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { + furi_hal_speaker_start(200.0f, 0.01f); + tracker_speaker_stop(); + } +} + +void tracker_speaker_deinit() { + if(furi_hal_speaker_is_mine()) { + furi_hal_speaker_stop(); + furi_hal_speaker_release(); + } +} + +static FuriHalInterruptISR tracker_isr; +static void* tracker_isr_context; +static void tracker_interrupt_cb(void* context) { + UNUSED(context); + + if(LL_TIM_IsActiveFlag_UPDATE(TIM2)) { + LL_TIM_ClearFlag_UPDATE(TIM2); + + if(tracker_isr) { + tracker_isr(tracker_isr_context); + } + } +} + +void tracker_interrupt_init(float freq, FuriHalInterruptISR isr, void* context) { + tracker_isr = isr; + tracker_isr_context = context; + + furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, tracker_interrupt_cb, NULL); + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + // Prescaler to get 1kHz clock + TIM_InitStruct.Prescaler = SystemCoreClock / 1000000 - 1; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + // Auto reload to get freq Hz interrupt + TIM_InitStruct.Autoreload = (1000000 / freq) - 1; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + LL_TIM_Init(TIM2, &TIM_InitStruct); + LL_TIM_EnableIT_UPDATE(TIM2); + LL_TIM_EnableAllOutputs(TIM2); + LL_TIM_EnableCounter(TIM2); +} + +void tracker_interrupt_deinit() { + FURI_CRITICAL_ENTER(); + LL_TIM_DeInit(TIM2); + FURI_CRITICAL_EXIT(); + + furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL); +} + +void tracker_debug_init() { + furi_hal_gpio_init(&gpio_ext_pc3, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); +} + +void tracker_debug_set(bool value) { + furi_hal_gpio_write(&gpio_ext_pc3, value); +} + +void tracker_debug_deinit() { + furi_hal_gpio_init(&gpio_ext_pc3, GpioModeAnalog, GpioPullNo, GpioSpeedLow); +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/speaker_hal.h b/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/speaker_hal.h new file mode 100644 index 000000000..7867fe93f --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/speaker_hal.h @@ -0,0 +1,19 @@ +#include + +void tracker_speaker_init(); + +void tracker_speaker_deinit(); + +void tracker_speaker_play(float frequency, float pwm); + +void tracker_speaker_stop(); + +void tracker_interrupt_init(float freq, FuriHalInterruptISR isr, void* context); + +void tracker_interrupt_deinit(); + +void tracker_debug_init(); + +void tracker_debug_set(bool value); + +void tracker_debug_deinit(); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/tracker.c b/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/tracker.c new file mode 100644 index 000000000..e5efcea17 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/tracker.c @@ -0,0 +1,441 @@ +#include "tracker.h" +#include +#include "speaker_hal.h" + +// SongState song_state = { +// .tick = 0, +// .tick_limit = 2, +// .row = 0, +// }; + +typedef struct { + uint8_t speed; + uint8_t depth; + int8_t direction; + int8_t value; +} IntegerOscillator; + +typedef struct { + float frequency; + float frequency_target; + float pwm; + bool play; + IntegerOscillator vibrato; +} ChannelState; + +typedef struct { + ChannelState* channels; + uint8_t tick; + uint8_t tick_limit; + + uint8_t pattern_index; + uint8_t row_index; + uint8_t order_list_index; +} SongState; + +typedef struct { + uint8_t note; + uint8_t effect; + uint8_t data; +} UnpackedRow; + +struct Tracker { + const Song* song; + bool playing; + TrackerMessageCallback callback; + void* context; + SongState song_state; +}; + +static void channels_state_init(ChannelState* channel) { + channel->frequency = 0; + channel->frequency_target = FREQUENCY_UNSET; + channel->pwm = PWM_DEFAULT; + channel->play = false; + channel->vibrato.speed = 0; + channel->vibrato.depth = 0; + channel->vibrato.direction = 0; + channel->vibrato.value = 0; +} + +static void tracker_song_state_init(Tracker* tracker) { + tracker->song_state.tick = 0; + tracker->song_state.tick_limit = 2; + tracker->song_state.row_index = 0; + tracker->song_state.order_list_index = 0; + tracker->song_state.pattern_index = tracker->song->order_list[0]; + + if(tracker->song_state.channels != NULL) { + free(tracker->song_state.channels); + } + + tracker->song_state.channels = malloc(sizeof(ChannelState) * tracker->song->channels_count); + for(uint8_t i = 0; i < tracker->song->channels_count; i++) { + channels_state_init(&tracker->song_state.channels[i]); + } +} + +static void tracker_song_state_clear(Tracker* tracker) { + if(tracker->song_state.channels != NULL) { + free(tracker->song_state.channels); + tracker->song_state.channels = NULL; + } +} + +static uint8_t record_get_note(Row note) { + return note & ROW_NOTE_MASK; +} + +static uint8_t record_get_effect(Row note) { + return (note >> 6) & ROW_EFFECT_MASK; +} + +static uint8_t record_get_effect_data(Row note) { + return (note >> 10) & ROW_EFFECT_DATA_MASK; +} + +#define NOTES_PER_OCT 12 +const float notes_oct[NOTES_PER_OCT] = { + 130.813f, + 138.591f, + 146.832f, + 155.563f, + 164.814f, + 174.614f, + 184.997f, + 195.998f, + 207.652f, + 220.00f, + 233.082f, + 246.942f, +}; + +static float note_to_freq(uint8_t note) { + if(note == NOTE_NONE) return 0.0f; + note = note - NOTE_C2; + uint8_t octave = note / NOTES_PER_OCT; + uint8_t note_in_oct = note % NOTES_PER_OCT; + return notes_oct[note_in_oct] * (1 << octave); +} + +static float frequency_offset_semitones(float frequency, uint8_t semitones) { + return frequency * (1.0f + ((1.0f / 12.0f) * semitones)); +} + +static float frequency_get_seventh_of_a_semitone(float frequency) { + return frequency * ((1.0f / 12.0f) / 7.0f); +} + +static UnpackedRow get_current_row(const Song* song, SongState* song_state, uint8_t channel) { + const Pattern* pattern = &song->patterns[song_state->pattern_index]; + const Row row = pattern->channels[channel].rows[song_state->row_index]; + return (UnpackedRow){ + .note = record_get_note(row), + .effect = record_get_effect(row), + .data = record_get_effect_data(row), + }; +} + +static int16_t advance_order_and_get_next_pattern_index(const Song* song, SongState* song_state) { + song_state->order_list_index++; + if(song_state->order_list_index >= song->order_list_size) { + return -1; + } else { + return song->order_list[song_state->order_list_index]; + } +} + +typedef struct { + int16_t pattern; + int16_t row; + bool change_pattern; + bool change_row; +} Location; + +static void tracker_send_position_message(Tracker* tracker) { + if(tracker->callback != NULL) { + tracker->callback( + (TrackerMessage){ + .type = TrackerPositionChanged, + .data = + { + .position = + { + .order_list_index = tracker->song_state.order_list_index, + .row = tracker->song_state.row_index, + }, + }, + }, + tracker->context); + } +} + +static void tracker_send_end_message(Tracker* tracker) { + if(tracker->callback != NULL) { + tracker->callback((TrackerMessage){.type = TrackerEndOfSong}, tracker->context); + } +} + +static void advance_to_pattern(Tracker* tracker, Location advance) { + if(advance.change_pattern) { + if(advance.pattern < 0 || advance.pattern >= tracker->song->patterns_count) { + tracker->playing = false; + tracker_send_end_message(tracker); + } else { + tracker->song_state.pattern_index = advance.pattern; + tracker->song_state.row_index = 0; + } + } + + if(advance.change_row) { + if(advance.row < 0) advance.row = 0; + if(advance.row >= PATTERN_SIZE) advance.row = PATTERN_SIZE - 1; + tracker->song_state.row_index = advance.row; + } + + tracker_send_position_message(tracker); +} + +static void tracker_interrupt_body(Tracker* tracker) { + if(!tracker->playing) { + tracker_speaker_stop(); + return; + } + + const uint8_t channel_index = 0; + SongState* song_state = &tracker->song_state; + ChannelState* channel_state = &song_state->channels[channel_index]; + const Song* song = tracker->song; + UnpackedRow row = get_current_row(song, song_state, channel_index); + + // load frequency from note at tick 0 + if(song_state->tick == 0) { + bool invalidate_row = false; + // handle "on first tick" effects + if(row.effect == EffectBreakPattern) { + int16_t next_row_index = row.data; + int16_t next_pattern_index = + advance_order_and_get_next_pattern_index(song, song_state); + advance_to_pattern( + tracker, + (Location){ + .pattern = next_pattern_index, + .row = next_row_index, + .change_pattern = true, + .change_row = true, + }); + + invalidate_row = true; + } + + if(row.effect == EffectJumpToOrder) { + song_state->order_list_index = row.data; + int16_t next_pattern_index = song->order_list[song_state->order_list_index]; + + advance_to_pattern( + tracker, + (Location){ + .pattern = next_pattern_index, + .change_pattern = true, + }); + + invalidate_row = true; + } + + // tracker state can be affected by effects + if(!tracker->playing) { + tracker_speaker_stop(); + return; + } + + if(invalidate_row) { + row = get_current_row(song, song_state, channel_index); + + if(row.effect == EffectSetSpeed) { + song_state->tick_limit = row.data; + } + } + + // handle note effects + if(row.note == NOTE_OFF) { + channel_state->play = false; + } else if((row.note > NOTE_NONE) && (row.note < NOTE_OFF)) { + channel_state->play = true; + + // reset vibrato + channel_state->vibrato.speed = 0; + channel_state->vibrato.depth = 0; + channel_state->vibrato.value = 0; + channel_state->vibrato.direction = 0; + + // reset pwm + channel_state->pwm = PWM_DEFAULT; + + if(row.effect == EffectSlideToNote) { + channel_state->frequency_target = note_to_freq(row.note); + } else { + channel_state->frequency = note_to_freq(row.note); + channel_state->frequency_target = FREQUENCY_UNSET; + } + } + } + + if(channel_state->play) { + float frequency, pwm; + + if((row.effect == EffectSlideUp || row.effect == EffectSlideDown) && + row.data != EFFECT_DATA_NONE) { + // apply slide effect + channel_state->frequency += (row.effect == EffectSlideUp ? 1 : -1) * row.data; + } else if(row.effect == EffectSlideToNote) { + // apply slide to note effect, if target frequency is set + if(channel_state->frequency_target > 0) { + if(channel_state->frequency_target > channel_state->frequency) { + channel_state->frequency += row.data; + if(channel_state->frequency > channel_state->frequency_target) { + channel_state->frequency = channel_state->frequency_target; + channel_state->frequency_target = FREQUENCY_UNSET; + } + } else if(channel_state->frequency_target < channel_state->frequency) { + channel_state->frequency -= row.data; + if(channel_state->frequency < channel_state->frequency_target) { + channel_state->frequency = channel_state->frequency_target; + channel_state->frequency_target = FREQUENCY_UNSET; + } + } + } + } + + frequency = channel_state->frequency; + pwm = channel_state->pwm; + + // apply arpeggio effect + if(row.effect == EffectArpeggio) { + if(row.data != EFFECT_DATA_NONE) { + if((song_state->tick % 3) == 1) { + uint8_t note_offset = EFFECT_DATA_GET_X(row.data); + frequency = frequency_offset_semitones(frequency, note_offset); + } else if((song_state->tick % 3) == 2) { + uint8_t note_offset = EFFECT_DATA_GET_Y(row.data); + frequency = frequency_offset_semitones(frequency, note_offset); + } + } + } else if(row.effect == EffectVibrato) { + // apply vibrato effect, data = speed, depth + uint8_t vibrato_speed = EFFECT_DATA_GET_X(row.data); + uint8_t vibrato_depth = EFFECT_DATA_GET_Y(row.data); + + // update vibrato parameters if speed or depth is non-zero + if(vibrato_speed != 0) channel_state->vibrato.speed = vibrato_speed; + if(vibrato_depth != 0) channel_state->vibrato.depth = vibrato_depth; + + // update vibrato value + channel_state->vibrato.value += + channel_state->vibrato.direction * channel_state->vibrato.speed; + + // change direction if value is at the limit + if(channel_state->vibrato.value > channel_state->vibrato.depth) { + channel_state->vibrato.direction = -1; + } else if(channel_state->vibrato.value < -channel_state->vibrato.depth) { + channel_state->vibrato.direction = 1; + } else if(channel_state->vibrato.direction == 0) { + // set initial direction, if it is not set + channel_state->vibrato.direction = 1; + } + + frequency += + (frequency_get_seventh_of_a_semitone(frequency) * channel_state->vibrato.value); + } else if(row.effect == EffectPWM) { + pwm = (pwm - PWM_MIN) / EFFECT_DATA_1_MAX * row.data + PWM_MIN; + } + + tracker_speaker_play(frequency, pwm); + } else { + tracker_speaker_stop(); + } + + song_state->tick++; + if(song_state->tick >= song_state->tick_limit) { + song_state->tick = 0; + + // next note + song_state->row_index = (song_state->row_index + 1); + + if(song_state->row_index >= PATTERN_SIZE) { + int16_t next_pattern_index = + advance_order_and_get_next_pattern_index(song, song_state); + advance_to_pattern( + tracker, + (Location){ + .pattern = next_pattern_index, + .change_pattern = true, + }); + } else { + tracker_send_position_message(tracker); + } + } +} + +static void tracker_interrupt_cb(void* context) { + Tracker* tracker = (Tracker*)context; + tracker_debug_set(true); + tracker_interrupt_body(tracker); + tracker_debug_set(false); +} + +/********************************************************************* + * Tracker Interface + *********************************************************************/ + +Tracker* tracker_alloc() { + Tracker* tracker = malloc(sizeof(Tracker)); + return tracker; +} + +void tracker_free(Tracker* tracker) { + tracker_song_state_clear(tracker); + free(tracker); +} + +void tracker_set_message_callback(Tracker* tracker, TrackerMessageCallback callback, void* context) { + furi_check(tracker->playing == false); + tracker->callback = callback; + tracker->context = context; +} + +void tracker_set_song(Tracker* tracker, const Song* song) { + furi_check(tracker->playing == false); + tracker->song = song; + tracker_song_state_init(tracker); +} + +void tracker_set_order_index(Tracker* tracker, uint8_t order_index) { + furi_check(tracker->playing == false); + furi_check(order_index < tracker->song->order_list_size); + tracker->song_state.order_list_index = order_index; + tracker->song_state.pattern_index = tracker->song->order_list[order_index]; +} + +void tracker_set_row(Tracker* tracker, uint8_t row) { + furi_check(tracker->playing == false); + furi_check(row < PATTERN_SIZE); + tracker->song_state.row_index = row; +} + +void tracker_start(Tracker* tracker) { + furi_check(tracker->song != NULL); + + tracker->playing = true; + tracker_send_position_message(tracker); + tracker_debug_init(); + tracker_speaker_init(); + tracker_interrupt_init(tracker->song->ticks_per_second, tracker_interrupt_cb, tracker); +} + +void tracker_stop(Tracker* tracker) { + tracker_interrupt_deinit(); + tracker_speaker_deinit(); + tracker_debug_deinit(); + + tracker->playing = false; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/tracker.h b/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/tracker.h new file mode 100644 index 000000000..70bf4bd6b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/tracker.h @@ -0,0 +1,38 @@ +#pragma once +#include "tracker_notes.h" +#include "tracker_song.h" + +typedef enum { + TrackerPositionChanged, + TrackerEndOfSong, +} TrackerMessageType; + +typedef struct { + TrackerMessageType type; + union tracker_message_data { + struct { + uint8_t order_list_index; + uint8_t row; + } position; + } data; +} TrackerMessage; + +typedef void (*TrackerMessageCallback)(TrackerMessage message, void* context); + +typedef struct Tracker Tracker; + +Tracker* tracker_alloc(); + +void tracker_free(Tracker* tracker); + +void tracker_set_message_callback(Tracker* tracker, TrackerMessageCallback callback, void* context); + +void tracker_set_song(Tracker* tracker, const Song* song); + +void tracker_set_order_index(Tracker* tracker, uint8_t order_index); + +void tracker_set_row(Tracker* tracker, uint8_t row); + +void tracker_start(Tracker* tracker); + +void tracker_stop(Tracker* tracker); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/tracker_notes.h b/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/tracker_notes.h new file mode 100644 index 000000000..22ab3590f --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/tracker_notes.h @@ -0,0 +1,64 @@ +#pragma once + +#define NOTE_NONE 0 +#define NOTE_C2 1 +#define NOTE_Cs2 2 +#define NOTE_D2 3 +#define NOTE_Ds2 4 +#define NOTE_E2 5 +#define NOTE_F2 6 +#define NOTE_Fs2 7 +#define NOTE_G2 8 +#define NOTE_Gs2 9 +#define NOTE_A2 10 +#define NOTE_As2 11 +#define NOTE_B2 12 +#define NOTE_C3 13 +#define NOTE_Cs3 14 +#define NOTE_D3 15 +#define NOTE_Ds3 16 +#define NOTE_E3 17 +#define NOTE_F3 18 +#define NOTE_Fs3 19 +#define NOTE_G3 20 +#define NOTE_Gs3 21 +#define NOTE_A3 22 +#define NOTE_As3 23 +#define NOTE_B3 24 +#define NOTE_C4 25 +#define NOTE_Cs4 26 +#define NOTE_D4 27 +#define NOTE_Ds4 28 +#define NOTE_E4 29 +#define NOTE_F4 30 +#define NOTE_Fs4 31 +#define NOTE_G4 32 +#define NOTE_Gs4 33 +#define NOTE_A4 34 +#define NOTE_As4 35 +#define NOTE_B4 36 +#define NOTE_C5 37 +#define NOTE_Cs5 38 +#define NOTE_D5 39 +#define NOTE_Ds5 40 +#define NOTE_E5 41 +#define NOTE_F5 42 +#define NOTE_Fs5 43 +#define NOTE_G5 44 +#define NOTE_Gs5 45 +#define NOTE_A5 46 +#define NOTE_As5 47 +#define NOTE_B5 48 +#define NOTE_C6 49 +#define NOTE_Cs6 50 +#define NOTE_D6 51 +#define NOTE_Ds6 52 +#define NOTE_E6 53 +#define NOTE_F6 54 +#define NOTE_Fs6 55 +#define NOTE_G6 56 +#define NOTE_Gs6 57 +#define NOTE_A6 58 +#define NOTE_As6 59 +#define NOTE_B6 60 +#define NOTE_OFF 63 \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/tracker_song.h b/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/tracker_song.h new file mode 100644 index 000000000..7a054f7b1 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/musictracker/tracker_engine/tracker_song.h @@ -0,0 +1,109 @@ +#pragma once +#include + +/** + * @brief Row + * + * AH AL + * FEDCBA98 76543210 + * nnnnnnee eedddddd + * -------- -------- + * nnnnnn = [0] do nothing, [1..60] note number, [61] note off, [62..63] not used + * ee ee = [0..F] effect + * 111222 = [0..63] or [0..7, 0..7] effect data + */ +typedef uint16_t Row; + +#define ROW_NOTE_MASK 0x3F +#define ROW_EFFECT_MASK 0x0F +#define ROW_EFFECT_DATA_MASK 0x3F + +typedef enum { + // 0xy, x - first semitones offset, y - second semitones offset. 0 - no offset .. 7 - +7 semitones... + // Play the arpeggio chord with three notes. The first note is the base note, the second and third are offset by x and y. + // Each note plays one tick. + EffectArpeggio = 0x00, + + // 1xx, xx - effect speed, 0 - no effect, 1 - slowest, 0x3F - fastest. + // Slide the note pitch up by xx Hz every tick. + EffectSlideUp = 0x01, + + // 2xx, xx - effect speed, 0 - no effect, 1 - slowest, 0x3F - fastest. + // Slide the note pitch down by xx Hz every tick. + EffectSlideDown = 0x02, + + // 3xx, xx - effect speed, 0 - no effect, 1 - slowest, 0x3F - fastest. + // Slide the already playing note pitch towards another one by xx Hz every tick. + // The note value is saved until the note is playing, so you don't have to repeat the note value to continue sliding. + EffectSlideToNote = 0x03, + + // 4xy, x - vibrato speed (0..7), y - vibrato depth (0..7). + // Vibrato effect. The pitch of the note increases by x Hz each tick to a positive vibrato depth, then decreases to a negative depth. + // Value 1 of depth means 1/7 of a semitone (about 14.28 ct), so value 7 means full semitone. + // Note will play without vibrato on the first tick at the beginning of the effect. + // Vibrato speed and depth are saved until the note is playing, and will be updated only if they are not zero, so you doesn't have to repeat them every tick. + EffectVibrato = 0x04, + + // Effect05 = 0x05, + // Effect06 = 0x06, + // Effect07 = 0x07, + // Effect08 = 0x08, + // Effect09 = 0x09, + // Effect0A = 0x0A, + + // Bxx, xx - pattern number + // Jump to the order xx in the pattern order table at first tick of current row. + // So if you want to jump to the pattern after note 4, you should put this effect on the 5th note. + EffectJumpToOrder = 0x0B, + + // Cxx, xx - pwm value + // Set the PWM value to xx for current row. + EffectPWM = 0x0C, + + // Bxx, xx - row number + // Jump to the row xx in next pattern at first tick of current row. + // So if you want to jump to the pattern after note 4, you should put this effect on the 5th note. + EffectBreakPattern = 0x0D, + + // Effect0E = 0x0E, + + // Fxx, xx - song speed, 0 - 1 tick per note, 1 - 2 ticks per note, 0x3F - 64 ticks per note. + // Set the speed of the song in terms of ticks per note. + // Will be applied at the first tick of current row. + EffectSetSpeed = 0x0F, +} Effect; + +#define EFFECT_DATA_2(x, y) ((x) | ((y) << 3)) +#define EFFECT_DATA_GET_X(data) ((data)&0x07) +#define EFFECT_DATA_GET_Y(data) (((data) >> 3) & 0x07) +#define EFFECT_DATA_NONE 0 +#define EFFECT_DATA_1_MAX 0x3F +#define EFFECT_DATA_2_MAX 0x07 + +#define FREQUENCY_UNSET -1.0f + +#define PWM_MIN 0.01f +#define PWM_MAX 0.5f +#define PWM_DEFAULT PWM_MAX + +#define PATTERN_SIZE 64 + +#define ROW_MAKE(note, effect, data) \ + ((Row)(((note)&0x3F) | (((effect)&0xF) << 6) | (((data)&0x3F) << 10))) + +typedef struct { + Row rows[PATTERN_SIZE]; +} Channel; + +typedef struct { + Channel* channels; +} Pattern; + +typedef struct { + uint8_t channels_count; + uint8_t patterns_count; + Pattern* patterns; + uint8_t order_list_size; + uint8_t* order_list; + uint16_t ticks_per_second; +} Song; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/musictracker/view/tracker_view.c b/Applications/Official/DEV_FW/source/xMasterX/musictracker/view/tracker_view.c new file mode 100644 index 000000000..87e6b0fcf --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/musictracker/view/tracker_view.c @@ -0,0 +1,182 @@ +#include "tracker_view.h" +#include +#include + +typedef struct { + const Song* song; + uint8_t order_list_index; + uint8_t row; +} TrackerViewModel; + +struct TrackerView { + View* view; + void* back_context; + TrackerViewCallback back_callback; +}; + +static Channel* get_current_channel(TrackerViewModel* model) { + uint8_t channel_id = 0; + uint8_t pattern_id = model->song->order_list[model->order_list_index]; + Pattern* pattern = &model->song->patterns[pattern_id]; + return &pattern->channels[channel_id]; +} + +static const char* get_note_from_id(uint8_t note) { +#define NOTE_COUNT 12 + const char* notes[NOTE_COUNT] = { + "C ", + "C#", + "D ", + "D#", + "E ", + "F ", + "F#", + "G ", + "G#", + "A ", + "A#", + "B ", + }; + return notes[(note) % NOTE_COUNT]; +#undef NOTE_COUNT +} + +static uint8_t get_octave_from_id(uint8_t note) { + return ((note) / 12) + 2; +} + +static uint8_t get_first_row_id(uint8_t row) { + return (row / 10) * 10; +} + +static void + draw_row(Canvas* canvas, uint8_t i, Channel* channel, uint8_t row, FuriString* buffer) { + uint8_t x = 12 * (i + 1); + uint8_t first_row_id = get_first_row_id(row); + uint8_t current_row_id = first_row_id + i; + + if((current_row_id) >= 64) { + return; + } + + Row current_row = channel->rows[current_row_id]; + uint8_t note = current_row & ROW_NOTE_MASK; + uint8_t effect = (current_row >> 6) & ROW_EFFECT_MASK; + uint8_t data = (current_row >> 10) & ROW_EFFECT_DATA_MASK; + + if(current_row_id == row) { + canvas_set_color(canvas, ColorBlack); + canvas_draw_line(canvas, x - 9, 1, x - 9, 62); + canvas_draw_box(canvas, x - 8, 0, 9, 64); + canvas_draw_line(canvas, x + 1, 1, x + 1, 62); + canvas_set_color(canvas, ColorWhite); + } + + furi_string_printf(buffer, "%02X", current_row_id); + canvas_draw_str(canvas, x, 61, furi_string_get_cstr(buffer)); + + if(note > 0 && note < NOTE_OFF) { + furi_string_printf( + buffer, "%s%d", get_note_from_id(note - 1), get_octave_from_id(note - 1)); + canvas_draw_str(canvas, x, 44, furi_string_get_cstr(buffer)); + } else if(note == NOTE_OFF) { + canvas_draw_str(canvas, x, 44, "OFF"); + } else { + canvas_draw_str(canvas, x, 44, "---"); + } + + if(effect == 0 && data == 0) { + canvas_draw_str(canvas, x, 21, "-"); + canvas_draw_str(canvas, x, 12, "--"); + } else { + furi_string_printf(buffer, "%X", effect); + canvas_draw_str(canvas, x, 21, furi_string_get_cstr(buffer)); + + if(effect == EffectArpeggio || effect == EffectVibrato) { + uint8_t data_x = EFFECT_DATA_GET_X(data); + uint8_t data_y = EFFECT_DATA_GET_Y(data); + furi_string_printf(buffer, "%d%d", data_x, data_y); + canvas_draw_str(canvas, x, 12, furi_string_get_cstr(buffer)); + } else { + furi_string_printf(buffer, "%02X", data); + canvas_draw_str(canvas, x, 12, furi_string_get_cstr(buffer)); + } + } + + if(current_row_id == row) { + canvas_set_color(canvas, ColorBlack); + } +} + +static void tracker_view_draw_callback(Canvas* canvas, void* _model) { + TrackerViewModel* model = _model; + if(model->song == NULL) { + return; + } + + canvas_set_font_direction(canvas, CanvasDirectionBottomToTop); + canvas_set_font(canvas, FontKeyboard); + + Channel* channel = get_current_channel(model); + FuriString* buffer = furi_string_alloc(); + + for(uint8_t i = 0; i < 10; i++) { + draw_row(canvas, i, channel, model->row, buffer); + } + furi_string_free(buffer); +} + +static bool tracker_view_input_callback(InputEvent* event, void* context) { + TrackerView* tracker_view = context; + + if(tracker_view->back_callback) { + if(event->type == InputTypeShort && event->key == InputKeyBack) { + tracker_view->back_callback(tracker_view->back_context); + return true; + } + } + return false; +} + +TrackerView* tracker_view_alloc() { + TrackerView* tracker_view = malloc(sizeof(TrackerView)); + tracker_view->view = view_alloc(); + view_allocate_model(tracker_view->view, ViewModelTypeLocking, sizeof(TrackerViewModel)); + view_set_context(tracker_view->view, tracker_view); + view_set_draw_callback(tracker_view->view, (ViewDrawCallback)tracker_view_draw_callback); + view_set_input_callback(tracker_view->view, (ViewInputCallback)tracker_view_input_callback); + return tracker_view; +} + +void tracker_view_free(TrackerView* tracker_view) { + view_free(tracker_view->view); + free(tracker_view); +} + +View* tracker_view_get_view(TrackerView* tracker_view) { + return tracker_view->view; +} + +void tracker_view_set_back_callback( + TrackerView* tracker_view, + TrackerViewCallback callback, + void* context) { + tracker_view->back_callback = callback; + tracker_view->back_context = context; +} + +void tracker_view_set_song(TrackerView* tracker_view, const Song* song) { + with_view_model( + tracker_view->view, TrackerViewModel * model, { model->song = song; }, true); +} + +void tracker_view_set_position(TrackerView* tracker_view, uint8_t order_list_index, uint8_t row) { + with_view_model( + tracker_view->view, + TrackerViewModel * model, + { + model->order_list_index = order_list_index; + model->row = row; + }, + true); +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/musictracker/view/tracker_view.h b/Applications/Official/DEV_FW/source/xMasterX/musictracker/view/tracker_view.h new file mode 100644 index 000000000..6c2e69ba4 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/musictracker/view/tracker_view.h @@ -0,0 +1,29 @@ +#include +#include "../tracker_engine/tracker.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct TrackerView TrackerView; + +TrackerView* tracker_view_alloc(); + +void tracker_view_free(TrackerView* tracker_view); + +View* tracker_view_get_view(TrackerView* tracker_view); + +typedef void (*TrackerViewCallback)(void* context); + +void tracker_view_set_back_callback( + TrackerView* tracker_view, + TrackerViewCallback callback, + void* context); + +void tracker_view_set_song(TrackerView* tracker_view, const Song* song); + +void tracker_view_set_position(TrackerView* tracker_view, uint8_t order_list_index, uint8_t row); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/musictracker/zero_tracker.c b/Applications/Official/DEV_FW/source/xMasterX/musictracker/zero_tracker.c new file mode 100644 index 000000000..f4c10d9ef --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/musictracker/zero_tracker.c @@ -0,0 +1,536 @@ +#include +#include +#include +#include +#include "zero_tracker.h" +#include "tracker_engine/tracker.h" +#include "view/tracker_view.h" + +// Channel p_0_channels[] = { +// { +// .rows = +// { +// // 1/4 +// ROW_MAKE(NOTE_C3, EffectArpeggio, EFFECT_DATA_2(4, 7)), +// ROW_MAKE(0, EffectArpeggio, EFFECT_DATA_2(4, 7)), +// ROW_MAKE(NOTE_C4, EffectSlideToNote, 0x20), +// ROW_MAKE(0, EffectSlideToNote, 0x20), +// // +// ROW_MAKE(0, EffectSlideToNote, 0x20), +// ROW_MAKE(0, EffectSlideToNote, 0x20), +// ROW_MAKE(0, EffectSlideToNote, 0x20), +// ROW_MAKE(0, EffectSlideToNote, 0x20), +// // +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)), +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)), +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)), +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)), +// // +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)), +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)), +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)), +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)), +// // 2/4 +// ROW_MAKE(NOTE_C3, EffectSlideDown, 0x20), +// ROW_MAKE(0, EffectSlideDown, 0x20), +// ROW_MAKE(NOTE_C4, EffectVibrato, EFFECT_DATA_2(3, 3)), +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)), +// // +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)), +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)), +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)), +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)), +// // +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)), +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)), +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)), +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)), +// // +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)), +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)), +// ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(3, 3)), +// ROW_MAKE(NOTE_OFF, EffectVibrato, EFFECT_DATA_2(3, 3)), +// // 3/4 +// ROW_MAKE(NOTE_C3, EffectArpeggio, EFFECT_DATA_2(4, 7)), +// ROW_MAKE(0, EffectArpeggio, EFFECT_DATA_2(4, 7)), +// ROW_MAKE(NOTE_OFF, 0, 0), +// ROW_MAKE(0, 0, 0), +// // +// ROW_MAKE(0, 0, 0), +// ROW_MAKE(0, 0, 0), +// ROW_MAKE(0, 0, 0), +// ROW_MAKE(0, 0, 0), +// // +// ROW_MAKE(NOTE_C2, EffectPWM, 60), +// ROW_MAKE(0, EffectPWM, 32), +// ROW_MAKE(0, EffectPWM, 12), +// ROW_MAKE(NOTE_OFF, 0, 0), +// // +// ROW_MAKE(0, 0, 0), +// ROW_MAKE(0, 0, 0), +// ROW_MAKE(0, 0, 0), +// ROW_MAKE(0, 0, 0), +// // 4/4 +// ROW_MAKE(NOTE_C3, EffectSlideDown, 0x20), +// ROW_MAKE(0, EffectSlideDown, 0x20), +// ROW_MAKE(0, EffectSlideDown, 0x20), +// ROW_MAKE(NOTE_OFF, 0, 0), +// // +// ROW_MAKE(0, 0, 0), +// ROW_MAKE(0, 0, 0), +// ROW_MAKE(0, 0, 0), +// ROW_MAKE(0, 0, 0), +// // +// ROW_MAKE(NOTE_C2, EffectPWM, 60), +// ROW_MAKE(0, EffectPWM, 32), +// ROW_MAKE(0, EffectPWM, 12), +// ROW_MAKE(NOTE_OFF, 0, 0), +// // +// ROW_MAKE(0, 0, 0), +// ROW_MAKE(0, 0, 0), +// ROW_MAKE(0, 0, 0), +// ROW_MAKE(0, 0, 0), +// }, +// }, +// }; + +Channel p_0_channels[] = { + { + .rows = + { + // + ROW_MAKE(NOTE_A4, EffectArpeggio, EFFECT_DATA_2(4, 7)), + ROW_MAKE(NOTE_C3, 0, 0), + ROW_MAKE(NOTE_F2, 0, 0), + ROW_MAKE(NOTE_C3, 0, 0), + // + ROW_MAKE(NOTE_E4, 0, 0), + ROW_MAKE(NOTE_C3, 0, 0), + ROW_MAKE(NOTE_E4, EffectPWM, 50), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_A4, 0, 0), + ROW_MAKE(0, EffectPWM, 55), + ROW_MAKE(0, EffectPWM, 45), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_E5, 0, 0), + ROW_MAKE(0, EffectPWM, 55), + ROW_MAKE(0, EffectPWM, 45), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_D5, 0, 0), + ROW_MAKE(NOTE_C3, EffectSlideDown, 0x30), + ROW_MAKE(NOTE_F2, 0, 0), + ROW_MAKE(NOTE_C3, 0, 0), + // + ROW_MAKE(NOTE_C5, 0, 0), + ROW_MAKE(NOTE_C3, 0, 0), + ROW_MAKE(NOTE_C5, 0, 0), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_A4, 0, 0), + ROW_MAKE(0, 0, 0), + ROW_MAKE(0, 0, 0), + ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)), + // + ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)), + ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)), + ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_B4, EffectArpeggio, EFFECT_DATA_2(4, 7)), + ROW_MAKE(NOTE_D3, 0, 0), + ROW_MAKE(NOTE_G2, 0, 0), + ROW_MAKE(NOTE_D3, 0, 0), + // + ROW_MAKE(NOTE_E4, 0, 0), + ROW_MAKE(NOTE_D3, 0, 0), + ROW_MAKE(NOTE_E4, EffectPWM, 50), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_A4, 0, 0), + ROW_MAKE(0, EffectPWM, 55), + ROW_MAKE(0, EffectPWM, 45), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_E5, 0, 0), + ROW_MAKE(0, EffectPWM, 55), + ROW_MAKE(0, EffectPWM, 45), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_D5, 0, 0), + ROW_MAKE(NOTE_D3, EffectSlideDown, 0x3F), + ROW_MAKE(NOTE_G2, 0, 0), + ROW_MAKE(NOTE_D3, 0, 0), + // + ROW_MAKE(NOTE_C5, 0, 0), + ROW_MAKE(NOTE_D3, 0, 0), + ROW_MAKE(NOTE_C5, 0, 0), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_A4, 0, 0), + ROW_MAKE(0, 0, 0), + ROW_MAKE(0, 0, 0), + ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)), + // + ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)), + ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)), + ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)), + ROW_MAKE(NOTE_OFF, 0, 0), + }, + }, +}; + +Channel p_1_channels[] = { + { + .rows = + { + // + ROW_MAKE(NOTE_C5, EffectArpeggio, EFFECT_DATA_2(4, 7)), + ROW_MAKE(NOTE_E3, 0, 0), + ROW_MAKE(NOTE_A2, 0, 0), + ROW_MAKE(NOTE_E3, 0, 0), + // + ROW_MAKE(NOTE_B4, 0, 0), + ROW_MAKE(NOTE_E3, 0, 0), + ROW_MAKE(NOTE_B4, EffectPWM, 50), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_G4, 0, 0), + ROW_MAKE(0, EffectPWM, 55), + ROW_MAKE(0, EffectPWM, 45), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_C5, 0, 0), + ROW_MAKE(0, EffectPWM, 55), + ROW_MAKE(0, EffectPWM, 45), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_C6, 0, 0), + ROW_MAKE(NOTE_E3, EffectSlideDown, 0x30), + ROW_MAKE(NOTE_A2, 0, 0), + ROW_MAKE(NOTE_E3, 0, 0), + // + ROW_MAKE(NOTE_B4, 0, 0), + ROW_MAKE(NOTE_E3, 0, 0), + ROW_MAKE(NOTE_B4, EffectPWM, 50), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_G4, 0, 0), + ROW_MAKE(0, 0, 0), + ROW_MAKE(0, 0, 0), + ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)), + // + ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)), + ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)), + ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_C5, EffectArpeggio, EFFECT_DATA_2(4, 7)), + ROW_MAKE(NOTE_E3, 0, 0), + ROW_MAKE(NOTE_A2, 0, 0), + ROW_MAKE(NOTE_E3, 0, 0), + // + ROW_MAKE(NOTE_B4, 0, 0), + ROW_MAKE(NOTE_E3, 0, 0), + ROW_MAKE(NOTE_B4, EffectPWM, 50), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_G4, 0, 0), + ROW_MAKE(0, EffectPWM, 55), + ROW_MAKE(0, EffectPWM, 45), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_D5, 0, 0), + ROW_MAKE(0, EffectPWM, 55), + ROW_MAKE(0, EffectPWM, 45), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_C6, 0, 0), + ROW_MAKE(NOTE_E3, EffectSlideDown, 0x30), + ROW_MAKE(NOTE_A2, 0, 0), + ROW_MAKE(NOTE_E3, 0, 0), + // + ROW_MAKE(NOTE_B4, 0, 0), + ROW_MAKE(NOTE_E3, 0, 0), + ROW_MAKE(NOTE_B4, EffectPWM, 50), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_G4, 0, 0), + ROW_MAKE(0, 0, 0), + ROW_MAKE(0, 0, 0), + ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)), + // + ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(1, 1)), + ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)), + ROW_MAKE(0, EffectVibrato, EFFECT_DATA_2(2, 2)), + ROW_MAKE(NOTE_OFF, 0, 0), + }, + }, +}; + +Channel p_2_channels[] = { + { + .rows = + { + // + ROW_MAKE(NOTE_C5, EffectArpeggio, EFFECT_DATA_2(4, 7)), + ROW_MAKE(NOTE_E3, 0, 0), + ROW_MAKE(NOTE_A2, 0, 0), + ROW_MAKE(NOTE_E3, 0, 0), + // + ROW_MAKE(NOTE_C5, 0, 0), + ROW_MAKE(NOTE_A4, 0, 0), + ROW_MAKE(NOTE_C5, 0, 0), + ROW_MAKE(NOTE_A4, 0, 0), + // + ROW_MAKE(NOTE_C5, EffectPWM, 55), + ROW_MAKE(NOTE_A4, EffectPWM, 45), + ROW_MAKE(NOTE_C5, EffectPWM, 35), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_C5, 0, 0), + ROW_MAKE(NOTE_A4, 0, 0), + ROW_MAKE(NOTE_C5, EffectPWM, 55), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_D5, 0, 0), + ROW_MAKE(NOTE_E3, EffectSlideDown, 0x30), + ROW_MAKE(NOTE_A2, 0, 0), + ROW_MAKE(NOTE_E3, 0, 0), + // + ROW_MAKE(NOTE_OFF, 0, 0), + ROW_MAKE(NOTE_E3, 0, 0), + ROW_MAKE(NOTE_B4, EffectPWM, 55), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_D5, 0, 0), + ROW_MAKE(NOTE_B4, 0, 0), + ROW_MAKE(NOTE_D5, EffectPWM, 55), + ROW_MAKE(NOTE_B4, EffectPWM, 55), + // + ROW_MAKE(NOTE_D5, EffectPWM, 45), + ROW_MAKE(NOTE_B4, EffectPWM, 45), + ROW_MAKE(NOTE_D5, EffectPWM, 35), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_D5, EffectArpeggio, EFFECT_DATA_2(4, 7)), + ROW_MAKE(NOTE_E3, 0, 0), + ROW_MAKE(NOTE_A2, 0, 0), + ROW_MAKE(NOTE_E3, 0, 0), + // + ROW_MAKE(NOTE_E5, 0, 0), + ROW_MAKE(NOTE_C5, 0, 0), + ROW_MAKE(NOTE_E5, 0, 0), + ROW_MAKE(NOTE_C5, 0, 0), + // + ROW_MAKE(NOTE_E5, EffectPWM, 55), + ROW_MAKE(NOTE_C5, EffectPWM, 45), + ROW_MAKE(NOTE_E5, EffectPWM, 35), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_E5, 0, 0), + ROW_MAKE(NOTE_C5, 0, 0), + ROW_MAKE(NOTE_E5, EffectPWM, 55), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_D5, 0, 0), + ROW_MAKE(NOTE_E3, EffectSlideDown, 0x30), + ROW_MAKE(NOTE_A2, 0, 0), + ROW_MAKE(NOTE_E3, 0, 0), + // + ROW_MAKE(NOTE_OFF, 0, 0), + ROW_MAKE(NOTE_E3, 0, 0), + ROW_MAKE(NOTE_B4, EffectPWM, 55), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_D5, 0, 0), + ROW_MAKE(NOTE_B4, 0, 0), + ROW_MAKE(NOTE_D5, EffectPWM, 55), + ROW_MAKE(NOTE_B4, EffectPWM, 55), + // + ROW_MAKE(NOTE_D5, EffectPWM, 45), + ROW_MAKE(NOTE_B4, EffectPWM, 45), + ROW_MAKE(NOTE_D5, EffectPWM, 35), + ROW_MAKE(NOTE_OFF, 0, 0), + }, + }, +}; + +Channel p_3_channels[] = { + { + .rows = + { + // + ROW_MAKE(NOTE_Ds5, EffectArpeggio, EFFECT_DATA_2(4, 6)), + ROW_MAKE(NOTE_C5, 0, 0), + ROW_MAKE(NOTE_Ds5, 0, 0), + ROW_MAKE(NOTE_C5, EffectPWM, 55), + // + ROW_MAKE(NOTE_Ds5, EffectPWM, 45), + ROW_MAKE(NOTE_C5, EffectPWM, 35), + ROW_MAKE(NOTE_Ds5, EffectPWM, 30), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_D5, 0, 0), + ROW_MAKE(NOTE_B4, 0, 0), + ROW_MAKE(NOTE_D5, 0, 0), + ROW_MAKE(NOTE_B4, EffectPWM, 55), + // + ROW_MAKE(NOTE_D5, EffectPWM, 45), + ROW_MAKE(NOTE_B4, EffectPWM, 35), + ROW_MAKE(NOTE_D5, EffectPWM, 30), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_Cs5, EffectArpeggio, EFFECT_DATA_2(4, 6)), + ROW_MAKE(NOTE_As4, 0, 0), + ROW_MAKE(NOTE_Cs5, 0, 0), + ROW_MAKE(NOTE_As4, EffectPWM, 55), + // + ROW_MAKE(NOTE_Cs5, EffectPWM, 45), + ROW_MAKE(NOTE_As4, EffectPWM, 35), + ROW_MAKE(NOTE_Cs5, EffectPWM, 30), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_C5, 0, 0), + ROW_MAKE(NOTE_A4, 0, 0), + ROW_MAKE(NOTE_C5, 0, 0), + ROW_MAKE(NOTE_A4, EffectPWM, 55), + // + ROW_MAKE(NOTE_C5, EffectPWM, 45), + ROW_MAKE(NOTE_A4, EffectPWM, 35), + ROW_MAKE(NOTE_C5, EffectPWM, 30), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_B4, EffectArpeggio, EFFECT_DATA_2(4, 6)), + ROW_MAKE(NOTE_Gs4, 0, 0), + ROW_MAKE(NOTE_B4, 0, 0), + ROW_MAKE(NOTE_Gs4, EffectPWM, 55), + // + ROW_MAKE(NOTE_B4, EffectPWM, 45), + ROW_MAKE(NOTE_Gs4, EffectPWM, 35), + ROW_MAKE(NOTE_B4, EffectPWM, 30), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_C5, 0, 0), + ROW_MAKE(NOTE_A4, 0, 0), + ROW_MAKE(NOTE_C5, 0, 0), + ROW_MAKE(NOTE_A4, EffectPWM, 55), + // + ROW_MAKE(NOTE_C5, EffectPWM, 45), + ROW_MAKE(NOTE_A4, EffectPWM, 35), + ROW_MAKE(NOTE_C5, EffectPWM, 30), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_Cs5, EffectArpeggio, EFFECT_DATA_2(4, 6)), + ROW_MAKE(NOTE_As4, 0, 0), + ROW_MAKE(NOTE_Cs5, 0, 0), + ROW_MAKE(NOTE_As4, EffectPWM, 55), + // + ROW_MAKE(NOTE_Cs5, EffectPWM, 45), + ROW_MAKE(NOTE_As4, EffectPWM, 35), + ROW_MAKE(NOTE_Cs5, EffectPWM, 30), + ROW_MAKE(NOTE_OFF, 0, 0), + // + ROW_MAKE(NOTE_D5, 0, 0), + ROW_MAKE(NOTE_B4, 0, 0), + ROW_MAKE(NOTE_D5, 0, 0), + ROW_MAKE(NOTE_B4, EffectPWM, 55), + // + ROW_MAKE(NOTE_D5, EffectPWM, 45), + ROW_MAKE(NOTE_B4, EffectPWM, 35), + ROW_MAKE(NOTE_D5, EffectPWM, 30), + ROW_MAKE(NOTE_OFF, 0, 0), + }, + }, +}; +Pattern patterns[] = { + {.channels = p_0_channels}, + {.channels = p_1_channels}, + {.channels = p_2_channels}, + {.channels = p_3_channels}, +}; + +uint8_t order_list[] = { + 0, + 1, + 0, + 2, + 0, + 1, + 0, + 3, +}; + +Song song = { + .channels_count = 1, + .patterns_count = sizeof(patterns) / sizeof(patterns[0]), + .patterns = patterns, + + .order_list_size = sizeof(order_list) / sizeof(order_list[0]), + .order_list = order_list, + + .ticks_per_second = 60, +}; + +void tracker_message(TrackerMessage message, void* context) { + FuriMessageQueue* queue = context; + furi_assert(queue); + furi_message_queue_put(queue, &message, 0); +} + +int32_t zero_tracker_app(void* p) { + UNUSED(p); + + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + notification_message(notification, &sequence_display_backlight_enforce_on); + + Gui* gui = furi_record_open(RECORD_GUI); + ViewDispatcher* view_dispatcher = view_dispatcher_alloc(); + TrackerView* tracker_view = tracker_view_alloc(); + tracker_view_set_song(tracker_view, &song); + view_dispatcher_add_view(view_dispatcher, 0, tracker_view_get_view(tracker_view)); + view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen); + view_dispatcher_switch_to_view(view_dispatcher, 0); + + FuriMessageQueue* queue = furi_message_queue_alloc(8, sizeof(TrackerMessage)); + Tracker* tracker = tracker_alloc(); + tracker_set_message_callback(tracker, tracker_message, queue); + tracker_set_song(tracker, &song); + tracker_start(tracker); + + while(1) { + TrackerMessage message; + FuriStatus status = furi_message_queue_get(queue, &message, portMAX_DELAY); + if(status == FuriStatusOk) { + if(message.type == TrackerPositionChanged) { + uint8_t order_list_index = message.data.position.order_list_index; + uint8_t row = message.data.position.row; + uint8_t pattern = song.order_list[order_list_index]; + tracker_view_set_position(tracker_view, order_list_index, row); + FURI_LOG_I("Tracker", "O:%d P:%d R:%d", order_list_index, pattern, row); + } else if(message.type == TrackerEndOfSong) { + FURI_LOG_I("Tracker", "End of song"); + break; + } + } + } + + tracker_stop(tracker); + tracker_free(tracker); + furi_message_queue_free(queue); + + furi_delay_ms(500); + + view_dispatcher_remove_view(view_dispatcher, 0); + tracker_view_free(tracker_view); + view_dispatcher_free(view_dispatcher); + + notification_message(notification, &sequence_display_backlight_enforce_auto); + + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_GUI); + + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/musictracker/zero_tracker.h b/Applications/Official/DEV_FW/source/xMasterX/musictracker/zero_tracker.h new file mode 100644 index 000000000..e69de29bb diff --git a/Applications/Official/DEV_FW/source/xMasterX/musictracker/zero_tracker.png b/Applications/Official/DEV_FW/source/xMasterX/musictracker/zero_tracker.png new file mode 100644 index 0000000000000000000000000000000000000000..61488d153425baaa51969f8fcefc68b065e09824 GIT binary patch literal 136 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 #0R(KDv87_Z`GtTRnq|aRPjR$RJL0wYj++0@d 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 F{~wvO_cH(h literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Distr/nrf24scan/addr-WCO1.txt b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Distr/nrf24scan/addr-WCO1.txt new file mode 100644 index 000000000..658340d03 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Distr/nrf24scan/addr-WCO1.txt @@ -0,0 +1,7 @@ +Rate: 1 +Ch: 120 +ESB: 1 +DPL: 1 +CRC: 2 +Payload: 4 +P0: C8C8E5 diff --git a/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Distr/nrf24scan/addresses.txt b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Distr/nrf24scan/addresses.txt new file mode 100644 index 000000000..e5bd3ed32 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Distr/nrf24scan/addresses.txt @@ -0,0 +1,11 @@ +Rate: 1 +Ch: 2 +ESB: 1 +DPL: 0 +CRC: 2 +Payload: 4 +P0: C8C8C0 +P1: C8C8C1 +P2: C2 +P3: C3 +P4: E5 diff --git a/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Distr/nrf24scan/sniff.txt b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Distr/nrf24scan/sniff.txt new file mode 100644 index 000000000..fa8c5ba9f --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Distr/nrf24scan/sniff.txt @@ -0,0 +1,5 @@ +SNIFF +ESB: 1 +CRC: 2 +P0: 00AA +P1: 0055 diff --git a/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/LICENSE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/README.md b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/README.md new file mode 100644 index 000000000..a93ec913e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/README.md @@ -0,0 +1,110 @@ +# NRF24 scanner with logging and resend ability for Flipper Zero + +An [NRF24](https://www.sparkfun.com/datasheets/Components/SMD/nRF24L01Pluss_Preliminary_Product_Specification_v1_0.pdf) driver for the [Flipper Zero](https://flipperzero.one/) device. The NRF24 is a popular line of 2.4GHz radio transceivers from Nordic Semiconductors.
+NRF24L01+ Enhanced ShockBurst packet decoder example using Python: [nrf24_packet_decoder.py](https://raw.githubusercontent.com/vad7/nrf24scan/master/nrf24_packet_decoder.py)
+
+Flipper Zero FAP file: [Nrf24_Scanner.fap](https://raw.githubusercontent.com/vad7/nrf24scan/master/Nrf24_Scanner.fap) +

+___________________________________________________________________________ +
+Приложение Ð´Ð»Ñ Flipper Zero, читающее Ñфир на радиомодулÑÑ… nRF24L01.
+Выбор пукта меню - Ñтрелки вверх/вниз, Ñтрелки влево/вправо либо изменют наÑтройки либо управлÑÑŽÑ‚ видом ÑпиÑка, кнопка ОК либо выбирает режим (короткое нажатие), либо выполнÑет дополнительное дейÑтвие (длительное нажатие).

+
+По умолчанию при запуÑке включаетÑÑ Ñ€ÐµÐ¶Ð¸Ð¼ поиÑка (sniff) - ищутÑÑ Ð²Ñе валидные пакеты Ñ ÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ñ‹Ð¼ заголовком и CRC.
+Размер CRC и тип пакета (Enhanced ShockBurst или нет) задаетÑÑ. CRC может быть или 1 или 2 байта.
+Так как пакеты читаютÑÑ Ð² RAW формате, то длина полезной нагрузки не может быть больше 23 байт, пакеты Ñ Ð±Ð¾Ð»ÑŒÑˆÐµÐ¹ длинной не будут пойманы.
+Ð’ наÑтройках задаетÑÑ Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ð¹ размер нагрузки (payload)
+ПоÑле принÑтиÑ, пакет ÑдвигаетÑÑ Ð¿Ð¾Ð±Ð¸Ñ‚Ð½Ð¾ и валидируетÑÑ. Побитный Ñдвиг Ñильно увеличивает вероÑтноÑÑ‚ÑŒ отлова пакета, но так же увеличиваетÑÑ ÐºÐ¾Ð»Ð¸Ñ‡ÐµÑтво муÑорных пакетов.
+КоличеÑтво уникальных адреÑов запоминаетÑÑ (проÑмотр - Ñтрелка вниз в режиме проÑмотра адреÑов)
+ПоÑле поиÑка можно переключитьÑÑ Ð² режим ÑÐºÐ°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ найденным адреÑам или Ñканировать Ð°Ð´Ñ€ÐµÑ ÐºÐ¾Ð½ÐºÑ€ÐµÑ‚Ð½Ð¾Ð³Ð¾ пакета или группы адреÑов Ñ Ñ€Ð°Ð·Ð»Ð¸Ñ‡Ð½Ñ‹Ð¼ LSB в адреÑе
+
+ +
+ÐдреÑа, которые попалиÑÑŒ дважды и более раз отображаютÑÑ ÑпиÑком:
+ +

+Изменение режима sniff/scan - Ñтрелками на пункте Scan.

+Режим ÑÐºÐ°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ (scan) - проÑто чтение пакетов по заданным в наÑтройках мак адреÑам и виду пакета - ESB/DPL.
+Ðа начальном Ñкране в режиме Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ загрузить файл наÑтроек (по умолчанию загружаетÑÑ settings.txt из папки nrf24_scanner на SD карте).
+Ð’ файле наÑтройке задаютÑÑ Ð°Ð´Ñ€ÐµÑа (макÑимум 6) в шеÑтнадцатеричном виде (Ñтарший байт - первый), длина адреÑа вычиÑлÑетÑÑ Ð¿Ð¾ P0.
+ОÑтальные наÑтройки можно поменÑÑ‚ÑŒ интерактивно
+ÐаÑтройки ÑохранÑÑŽÑ‚ÑÑ Ð´Ð»Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ð¼ нажатием на ОК.

+ОпиÑание наÑтроек:
+Ch - номер канала.
+Rate - ÑкороÑÑ‚ÑŒ передачи данных
+Next Ch time - через Ñколько Ñекунд будет увеличен номер канала
+Log - выбор режима авто ÑÐ¾Ñ…Ñ€Ð°Ð½Ð½ÐµÐ½Ð¸Ñ Ð² файлы log-xx.txt. Yes - ÑохранÑÑ‚ÑŒ в новый файл при заполнении буфера в 99 запиÑей, Append - добавлÑÑ‚ÑŒ в поÑледний файл, Clear - только очиÑтка буфера

+Ð’ пунктах Ch, Rate, Next при нажатии OK менÑÑŽÑ‚ÑÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ‹ ÑвÑзи:
+ESB - Enhanced ShockBurst (включена автоотправка Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð°ÐºÐµÑ‚Ð°, работающий приемник тоже попытаетÑÑ Ñто Ñделать, возможны коллизии)
+DPL - ДинамичеÑкий пакет
+CRC1/2 - Размер CRC в байтах
+Payload - размер пакета в байтах
+
+ПроÑмотр принÑÑ‚Ñ‹Ñ… пакетов

+ +
+Ð’ пункте "Start scan/sniff" можно выбрать Ñтрелками Ñканировать и Ñмотреть или проÑто Ñмотреть (view).
+ЕÑли в файле наÑтройки было неÑколько адреÑов, то Ð¿ÐµÑ€Ð²Ð°Ñ Ñ†Ð¸Ñ„Ñ€Ð° - номер канала (pipe) от 0 до 5.
+Стрелки - перемещение по ÑпиÑку и горизонтальное Ñкролирование
+Долгий OK - отправка пакета
+OK - вход в режим проÑмотра адреÑов и Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð´ÐµÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ° ESB пакета и CRC.
+При декодировании заголовка (PCF) - первые 2 цифры - длина пакета в hex или 33, еÑли длина пакета фикÑирована
+3-Ñ Ñ†Ð¸Ñ„Ñ€Ð° - PID (2bit) << 1 + флаг NO_ACK
+ЕÑли включен режим Ð´ÐµÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ CRC, то по вÑему пакету ищетÑÑ Ð¿Ð¾Ð´Ñ…Ð¾Ð´ÑÑ‰Ð°Ñ CRC и подчеркиваетÑÑ Ð² ÑпиÑке, а так же вмеÑто ":" выводитÑÑ "=" поÑле номера запиÑи в буфере
+
+ +
+ +
+ +
+
+_________________________________________________________________________________ +
+
+Settings file (default addr.txt) format:
+ +Rate: 0/1/2 - rate in Mbps (=0.25/1/2)
+Ch: 0..125 - default channel
+ESB: 0/1 (1 - Enhanced ShockBurst)
+DPL: 0/1 (1 - Dynamic Payload Length)
+CRC: 0/1/2 (CRC length)
+Payload: 1..32 (bytes)
+P0: address pipe #0 in hex (max 5 bytes, LSB last)
+P1: address pipe #1 in hex (max 5 bytes, LSB last)
+P2: address pipe #2, LSB in hex (1 byte)
+P3: address pipe #3, LSB in hex (1 byte)
+P4: address pipe #4, LSB in hex (1 byte)
+P5: address pipe #5, LSB in hex (1 byte)
+captured data in raw format, first byte = address # 0..5, Payload len if DPL
+... up to MAX_LOG_RECORDS-1
+
+In the list of the received:
+Press OK - send the packet,
+Long press OK - view addresses.
+
+Decode the Packet Control Field and check CRC (long press OK in the list and then press '<' / '>').
+ESB (Enhanced Shockburst) option must be turned off. +Press '>' to decode CRC.
+1 - pipe #
+2 - Payload length (for valide packet must be 1..20 or 33 hex)
+3 - PID (2 bit) + NO_ACK (1 bit)
+
+
+
+## PinOut from from NoComp/Frog + + +# NRF24 pinout by UberGuidoZ +2/A7 on FZ goes to MOSI/6 on nrf24l01
+3/A6 on FZ goes to MISO/7 on nrf24l01
+4/A4 on FZ goes to CSN/4 on nrf24l01
+5/B3 on FZ goes to SCK/5 on nrf24l01
+6/B2 on FZ goes to CE/3 on nrf24l01
+8/GND on FZ goes to GND/1 on nrf24l01
+9/3V3 on FZ goes to VCC/2 on nrf24l01
+IRQ/8 is left disconnected on nrf24l01 +![NRF_Pins](https://user-images.githubusercontent.com/57457139/178093717-39effd5c-ebe2-4253-b13c-70517d7902f9.png) +If the nRF module is acting a bit flakey, try adding a capacitor to the vcc/gnd lines! I've not tried the Plus model so it may have a bigger need for a cap. Otherwise, I haven't had any major issues. Anything from a 3.3 uF to 10 uF should do. (Watch your positive/negative placement! Negative to ground.) I learned if you wanna get fancy, include a 0.1 uF cap in parallel. The 3.3 uF to 10 uF will respond to slow freq changes while the 0.1 uF will respond to the high freq switching spikes that the larger one cannot. That said, a single 10 uF will likely suffice for the Mousejack attack. ¯\\\_(ツ)_/¯ +![NRF_Capacitor](https://user-images.githubusercontent.com/57457139/178169959-d030f9a6-d2ac-46af-af8b-470ff092c8a7.jpg) + diff --git a/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Screenshot-1.png b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Screenshot-1.png new file mode 100644 index 0000000000000000000000000000000000000000..61ca892d8fd4025ace79f7c4558d6094187bd696 GIT binary patch literal 2347 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Screenshot-5.png b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/Screenshot-5.png new file mode 100644 index 0000000000000000000000000000000000000000..d9e3173a260ac6a61d6ad48e6db750d903b860bf GIT binary patch literal 7483 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 azxcYVtasi}$a&jm3Zl1TBZUzM&i)OaheApK literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/application.fam b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/application.fam new file mode 100644 index 000000000..09f9fcab8 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/application.fam @@ -0,0 +1,20 @@ +App( + appid="Nrf24_Scanner", + name="[NRF24] Scanner", + apptype=FlipperAppType.EXTERNAL, + entry_point="nrf24scan_app", + cdefines=["APP_NRF24SCAN"], + requires=["gui"], + stack_size=2 * 1024, + order=60, + fap_icon="nrf24scan_10px.png", + fap_category="GPIO_Extra", + fap_private_libs=[ + Lib( + name="nrf24", + sources=[ + "nrf24.c", + ], + ), + ], +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/lib/nrf24/nrf24.c b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/lib/nrf24/nrf24.c new file mode 100644 index 000000000..83f0613a1 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/lib/nrf24/nrf24.c @@ -0,0 +1,533 @@ +// Modified by vad7, 25.11.2022 +// +#include "nrf24.h" +#include +#include +#include +#include +#include + +void nrf24_init() { + furi_hal_spi_bus_handle_init(nrf24_HANDLE); + furi_hal_spi_acquire(nrf24_HANDLE); + furi_hal_gpio_init(nrf24_CE_PIN, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); + furi_hal_gpio_write(nrf24_CE_PIN, false); +} + +void nrf24_deinit() { + furi_hal_spi_release(nrf24_HANDLE); + furi_hal_spi_bus_handle_deinit(nrf24_HANDLE); + furi_hal_gpio_write(nrf24_CE_PIN, false); + furi_hal_gpio_init(nrf24_CE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow); +} + +void nrf24_spi_trx( + FuriHalSpiBusHandle* handle, + uint8_t* tx, + uint8_t* rx, + uint8_t size, + uint32_t timeout) { + UNUSED(timeout); + furi_hal_gpio_write(handle->cs, false); + furi_hal_spi_bus_trx(handle, tx, rx, size, nrf24_TIMEOUT); + furi_hal_gpio_write(handle->cs, true); +} + +uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data) { + uint8_t tx[2] = {W_REGISTER | (REGISTER_MASK & reg), data}; + uint8_t rx[2] = {0}; + nrf24_spi_trx(handle, tx, rx, 2, nrf24_TIMEOUT); + //FURI_LOG_D("NRF_WR", " #%02X=%02X", reg, data); + return rx[0]; +} + +uint8_t nrf24_write_buf_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) { + uint8_t tx[size + 1]; + uint8_t rx[size + 1]; + memset(rx, 0, size + 1); + tx[0] = W_REGISTER | (REGISTER_MASK & reg); + memcpy(&tx[1], data, size); + nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT); + //FURI_LOG_D("NRF_WR", " #%02X(%02X)=0x%02X%02X%02X%02X%02X", reg, size, data[0], data[1], data[2], data[3], data[4] ); + return rx[0]; +} + +uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) { + uint8_t tx[size + 1]; + uint8_t rx[size + 1]; + memset(rx, 0, size + 1); + tx[0] = R_REGISTER | (REGISTER_MASK & reg); + memset(&tx[1], 0, size); + nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT); + memcpy(data, &rx[1], size); + return rx[0]; +} + +uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle) { + uint8_t tx[] = {FLUSH_RX}; + uint8_t rx[] = {0}; + nrf24_spi_trx(handle, tx, rx, 1, nrf24_TIMEOUT); + return rx[0]; +} + +uint8_t nrf24_flush_tx(FuriHalSpiBusHandle* handle) { + uint8_t tx[] = {FLUSH_TX}; + uint8_t rx[] = {0}; + nrf24_spi_trx(handle, tx, rx, 1, nrf24_TIMEOUT); + return rx[0]; +} + +uint8_t nrf24_get_maclen(FuriHalSpiBusHandle* handle) { + uint8_t maclen; + nrf24_read_reg(handle, REG_SETUP_AW, &maclen, 1); + maclen &= 3; + return maclen + 2; +} + +uint8_t nrf24_set_maclen(FuriHalSpiBusHandle* handle, uint8_t maclen) { + assert(maclen > 1 && maclen < 6); + uint8_t status = 0; + status = nrf24_write_reg(handle, REG_SETUP_AW, maclen - 2); + return status; +} + +uint8_t nrf24_status(FuriHalSpiBusHandle* handle) { + uint8_t status; + uint8_t tx[] = {R_REGISTER | (REGISTER_MASK & REG_STATUS)}; + nrf24_spi_trx(handle, tx, &status, 1, nrf24_TIMEOUT); + return status; +} + +uint32_t nrf24_get_rate(FuriHalSpiBusHandle* handle) { + uint8_t setup = 0; + uint32_t rate = 0; + nrf24_read_reg(handle, REG_RF_SETUP, &setup, 1); + setup &= 0x28; + if(setup == 0x20) + rate = 250000; // 250kbps + else if(setup == 0x08) + rate = 2000000; // 2Mbps + else if(setup == 0x00) + rate = 1000000; // 1Mbps + + return rate; +} + +uint8_t nrf24_set_rate(FuriHalSpiBusHandle* handle, uint32_t rate) { + uint8_t r6 = 0; + uint8_t status = 0; + if(!rate) rate = 2000000; + + nrf24_read_reg(handle, REG_RF_SETUP, &r6, 1); // RF_SETUP register + r6 = r6 & (~0x28); // Clear rate fields. + if(rate == 2000000) + r6 = r6 | 0x08; + else if(rate == 1000000) + r6 = r6; + else if(rate == 250000) + r6 = r6 | 0x20; + + status = nrf24_write_reg(handle, REG_RF_SETUP, r6); // Write new rate. + return status; +} + +uint8_t nrf24_get_chan(FuriHalSpiBusHandle* handle) { + uint8_t channel = 0; + nrf24_read_reg(handle, REG_RF_CH, &channel, 1); + return channel; +} + +uint8_t nrf24_set_chan(FuriHalSpiBusHandle* handle, uint8_t chan) { + uint8_t status; + status = nrf24_write_reg(handle, REG_RF_CH, chan); + return status; +} + +uint8_t nrf24_get_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac) { + uint8_t size = 0; + uint8_t status = 0; + size = nrf24_get_maclen(handle); + status = nrf24_read_reg(handle, REG_RX_ADDR_P0, mac, size); + return status; +} + +uint8_t nrf24_set_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size) { + uint8_t status = 0; + uint8_t clearmac[] = {0, 0, 0, 0, 0}; + nrf24_set_maclen(handle, size); + nrf24_write_buf_reg(handle, REG_RX_ADDR_P0, clearmac, 5); + status = nrf24_write_buf_reg(handle, REG_RX_ADDR_P0, mac, size); + return status; +} + +uint8_t nrf24_get_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac) { + uint8_t size = 0; + uint8_t status = 0; + size = nrf24_get_maclen(handle); + status = nrf24_read_reg(handle, REG_TX_ADDR, mac, size); + return status; +} + +uint8_t nrf24_set_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size) { + uint8_t status = 0; + uint8_t clearmac[] = {0, 0, 0, 0, 0}; + nrf24_set_maclen(handle, size); + nrf24_write_buf_reg(handle, REG_TX_ADDR, clearmac, 5); + status = nrf24_write_buf_reg(handle, REG_TX_ADDR, mac, size); + return status; +} + +uint8_t nrf24_get_packetlen(FuriHalSpiBusHandle* handle, uint8_t pipe) { + uint8_t len = 0; + if(pipe > 5) pipe = 0; + nrf24_read_reg(handle, RX_PW_P0 + pipe, &len, 1); + return len; +} + +uint8_t nrf24_set_packetlen(FuriHalSpiBusHandle* handle, uint8_t len) { + uint8_t status = 0; + status = nrf24_write_reg(handle, RX_PW_P0, len); + return status; +} + +uint8_t nrf24_rxpacket(FuriHalSpiBusHandle* handle, uint8_t* packet, uint8_t* ret_packetsize, uint8_t packet_size) { + uint8_t status = 0; + uint8_t tx_cmd[33] = {0}; // 32 max payload size + 1 for command + uint8_t tmp_packet[33] = {0}; + + status = nrf24_status(handle); + if(!(status & RX_DR)) { + tx_cmd[0] = R_REGISTER | (REGISTER_MASK & REG_FIFO_STATUS); + nrf24_spi_trx(handle, tx_cmd, tmp_packet, 2, nrf24_TIMEOUT); + if((tmp_packet[1] & 1) == 0) status |= RX_DR; // packet in FIFO buffer + } + if(status & RX_DR) { + if(packet_size == 1) + packet_size = nrf24_get_packetlen(handle, (status >> 1) & 7); + else if(packet_size == 0){ + tx_cmd[0] = R_RX_PL_WID; tx_cmd[1] = 0; + nrf24_spi_trx(handle, tx_cmd, tmp_packet, 2, nrf24_TIMEOUT); + packet_size = tmp_packet[1]; + } + if(packet_size > 32 || packet_size == 0) packet_size = 32; + tx_cmd[0] = R_RX_PAYLOAD; tx_cmd[1] = 0; + nrf24_spi_trx(handle, tx_cmd, tmp_packet, packet_size + 1, nrf24_TIMEOUT); + memcpy(packet, &tmp_packet[1], packet_size); + nrf24_write_reg(handle, REG_STATUS, RX_DR); // clear RX_DR + } else if(status & (TX_DS | MAX_RT)) { // MAX_RT, TX_DS + nrf24_write_reg(handle, REG_STATUS, (TX_DS | MAX_RT)); // clear RX_DR, MAX_RT. + } + + *ret_packetsize = packet_size; + return status; +} + +// Return 0 when error +uint8_t nrf24_txpacket(FuriHalSpiBusHandle* handle, uint8_t* payload, uint8_t size, bool ack) { + uint8_t status = 0; + uint8_t tx[size + 1]; + uint8_t rx[size + 1]; + memset(tx, 0, size + 1); + memset(rx, 0, size + 1); + + if(!ack) + tx[0] = W_TX_PAYLOAD_NOACK; + else + tx[0] = W_TX_PAYLOAD; + + memcpy(&tx[1], payload, size); + nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT); + nrf24_set_tx_mode(handle); + + uint32_t start_time = furi_get_tick(); + while(!(status & (TX_DS | MAX_RT)) && furi_get_tick() - start_time < 2000UL) status = nrf24_status(handle); + + if(status & MAX_RT) nrf24_flush_tx(handle); + + nrf24_set_idle(handle); + nrf24_write_reg(handle, REG_STATUS, TX_DS | MAX_RT); + return status & TX_DS; +} + +uint8_t nrf24_power_up(FuriHalSpiBusHandle* handle) { + uint8_t status = 0; + uint8_t cfg = 0; + nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); + cfg = cfg | 2; + status = nrf24_write_reg(handle, REG_CONFIG, cfg); + furi_delay_ms(1000); + return status; +} + +uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle) { + uint8_t status = 0; + uint8_t cfg = 0; + nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); + cfg &= 0xfc; // clear bottom two bits to power down the radio + status = nrf24_write_reg(handle, REG_CONFIG, cfg); + //nr204_write_reg(handle, REG_EN_RXADDR, 0x0); + furi_hal_gpio_write(nrf24_CE_PIN, false); + return status; +} + +uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle) { + uint8_t status = 0; + uint8_t cfg = 0; + //status = nrf24_write_reg(handle, REG_CONFIG, 0x0F); // enable 2-byte CRC, PWR_UP, and PRIM_RX + nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); + cfg |= 0x03; // PWR_UP, and PRIM_RX + status = nrf24_write_reg(handle, REG_CONFIG, cfg); + //nr204_write_reg(REG_EN_RXADDR, 0x03) // Set RX Pipe 0 and 1 + furi_hal_gpio_write(nrf24_CE_PIN, true); + furi_delay_ms(2); + return status; +} + +uint8_t nrf24_set_tx_mode(FuriHalSpiBusHandle* handle) { + uint8_t status = 0; + uint8_t cfg = 0; + furi_hal_gpio_write(nrf24_CE_PIN, false); + nrf24_write_reg(handle, REG_STATUS, 0x30); + //status = nrf24_write_reg(handle, REG_CONFIG, 0x0E); // enable 2-byte CRC, PWR_UP + nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); + cfg &= 0xfe; // disable PRIM_RX + cfg |= 0x02; // PWR_UP + status = nrf24_write_reg(handle, REG_CONFIG, cfg); + furi_hal_gpio_write(nrf24_CE_PIN, true); + furi_delay_ms(2); + return status; +} + +void nrf24_configure( + FuriHalSpiBusHandle* handle, + uint8_t rate, + uint8_t* srcmac, + uint8_t* dstmac, + uint8_t maclen, + uint8_t channel, + bool noack, + bool disable_aa) { + assert(channel <= 125); + assert(rate == 1 || rate == 2); + if(rate == 2) + rate = 8; // 2Mbps + else + rate = 0; // 1Mbps + + nrf24_write_reg(handle, REG_CONFIG, 0x00); // Stop nRF + nrf24_set_idle(handle); + nrf24_write_reg(handle, REG_STATUS, 0x70); // clear interrupts + if(disable_aa) + nrf24_write_reg(handle, REG_EN_AA, 0x00); // Disable Shockburst + else + nrf24_write_reg(handle, REG_EN_AA, 0x1F); // Enable Shockburst + + nrf24_write_reg(handle, REG_DYNPD, 0x3F); // enable dynamic payload length on all pipes + if(noack) + nrf24_write_reg(handle, REG_FEATURE, 0x05); // disable payload-with-ack, enable noack + else { + nrf24_write_reg(handle, REG_CONFIG, 0x0C); // 2 byte CRC + nrf24_write_reg(handle, REG_FEATURE, 0x07); // enable dyn payload and ack + nrf24_write_reg( + handle, REG_SETUP_RETR, 0x1f); // 15 retries for AA, 500us auto retransmit delay + } + + nrf24_set_idle(handle); + nrf24_flush_rx(handle); + nrf24_flush_tx(handle); + + if(maclen) nrf24_set_maclen(handle, maclen); + if(srcmac) nrf24_set_src_mac(handle, srcmac, maclen); + if(dstmac) nrf24_set_dst_mac(handle, dstmac, maclen); + + nrf24_write_reg(handle, REG_RF_CH, channel); + nrf24_write_reg(handle, REG_RF_SETUP, rate); + furi_delay_ms(200); +} + +void nrf24_init_promisc_mode(FuriHalSpiBusHandle* handle, uint8_t channel, uint8_t rate) { + //uint8_t preamble[] = {0x55, 0x00}; // little endian + uint8_t preamble[] = {0xAA, 0x00}; // little endian + //uint8_t preamble[] = {0x00, 0x55}; // little endian + //uint8_t preamble[] = {0x00, 0xAA}; // little endian + nrf24_write_reg(handle, REG_CONFIG, 0x00); // Stop nRF + nrf24_write_reg(handle, REG_STATUS, 0x70); // clear interrupts + nrf24_write_reg(handle, REG_DYNPD, 0x0); // disable shockburst + nrf24_write_reg(handle, REG_EN_AA, 0x00); // Disable Shockburst + nrf24_write_reg(handle, REG_FEATURE, 0x05); // disable payload-with-ack, enable noack + nrf24_set_maclen(handle, 2); // shortest address + nrf24_set_src_mac(handle, preamble, 2); // set src mac to preamble bits to catch everything + nrf24_set_packetlen(handle, 32); // set max packet length + nrf24_set_idle(handle); + nrf24_flush_rx(handle); + nrf24_flush_tx(handle); + nrf24_write_reg(handle, REG_RF_CH, channel); + nrf24_write_reg(handle, REG_RF_SETUP, rate); + + // prime for RX, no checksum + nrf24_write_reg(handle, REG_CONFIG, 0x03); // PWR_UP and PRIM_RX, disable AA and CRC + furi_hal_gpio_write(nrf24_CE_PIN, true); + furi_delay_ms(100); +} + +void hexlify(uint8_t* in, uint8_t size, char* out) { + memset(out, 0, size * 2); + for(int i = 0; i < size; i++) + snprintf(out + strlen(out), sizeof(out + strlen(out)), "%02X", in[i]); +} + +uint64_t bytes_to_int64(uint8_t* bytes, uint8_t size, bool bigendian) { + uint64_t ret = 0; + for(int i = 0; i < size; i++) + if(bigendian) + ret |= bytes[i] << ((size - 1 - i) * 8); + else + ret |= bytes[i] << (i * 8); + + return ret; +} + +void int64_to_bytes(uint64_t val, uint8_t* out, bool bigendian) { + for(int i = 0; i < 8; i++) { + if(bigendian) + out[i] = (val >> ((7 - i) * 8)) & 0xff; + else + out[i] = (val >> (i * 8)) & 0xff; + } +} + +uint32_t bytes_to_int32(uint8_t* bytes, bool bigendian) { + uint32_t ret = 0; + for(int i = 0; i < 4; i++) + if(bigendian) + ret |= bytes[i] << ((3 - i) * 8); + else + ret |= bytes[i] << (i * 8); + + return ret; +} + +void int32_to_bytes(uint32_t val, uint8_t* out, bool bigendian) { + for(int i = 0; i < 4; i++) { + if(bigendian) + out[i] = (val >> ((3 - i) * 8)) & 0xff; + else + out[i] = (val >> (i * 8)) & 0xff; + } +} + +uint64_t bytes_to_int16(uint8_t* bytes, bool bigendian) { + uint16_t ret = 0; + for(int i = 0; i < 2; i++) + if(bigendian) + ret |= bytes[i] << ((1 - i) * 8); + else + ret |= bytes[i] << (i * 8); + + return ret; +} + +void int16_to_bytes(uint16_t val, uint8_t* out, bool bigendian) { + for(int i = 0; i < 2; i++) { + if(bigendian) + out[i] = (val >> ((1 - i) * 8)) & 0xff; + else + out[i] = (val >> (i * 8)) & 0xff; + } +} + +// handle iffyness with preamble processing sometimes being a bit (literally) off +void alt_address_old(uint8_t* packet, uint8_t* altaddr) { + uint8_t macmess_hi_b[4]; + uint8_t macmess_lo_b[2]; + uint32_t macmess_hi; + uint16_t macmess_lo; + uint8_t preserved; + + // get first 6 bytes into 32-bit and 16-bit variables + memcpy(macmess_hi_b, packet, 4); + memcpy(macmess_lo_b, packet + 4, 2); + + macmess_hi = bytes_to_int32(macmess_hi_b, true); + + //preserve least 7 bits from hi that will be shifted down to lo + preserved = macmess_hi & 0x7f; + macmess_hi >>= 7; + + macmess_lo = bytes_to_int16(macmess_lo_b, true); + macmess_lo >>= 7; + macmess_lo = (preserved << 9) | macmess_lo; + int32_to_bytes(macmess_hi, macmess_hi_b, true); + int16_to_bytes(macmess_lo, macmess_lo_b, true); + memcpy(altaddr, &macmess_hi_b[1], 3); + memcpy(altaddr + 3, macmess_lo_b, 2); +} + +bool validate_address(uint8_t* addr) { + uint8_t bad[][3] = {{0x55, 0x55}, {0xAA, 0xAA}, {0x00, 0x00}, {0xFF, 0xFF}}; + for(int i = 0; i < 4; i++) + for(int j = 0; j < 2; j++) + if(!memcmp(addr + j * 2, bad[i], 2)) return false; + + return true; +} + +bool nrf24_sniff_address(FuriHalSpiBusHandle* handle, uint8_t maclen, uint8_t* address) { + bool found = false; + uint8_t packet[32] = {0}; + uint8_t packetsize; + //char printit[65]; + uint8_t status = 0; + status = nrf24_rxpacket(handle, packet, &packetsize, true); + if(status & 0x40) { + if(validate_address(packet)) { + for(int i = 0; i < maclen; i++) address[i] = packet[maclen - 1 - i]; + + /* + alt_address(packet, packet); + + for(i = 0; i < maclen; i++) + address[i + 5] = packet[maclen - 1 - i]; + */ + + //memcpy(address, packet, maclen); + //hexlify(packet, packetsize, printit); + found = true; + } + } + + return found; +} + +uint8_t nrf24_find_channel( + FuriHalSpiBusHandle* handle, + uint8_t* srcmac, + uint8_t* dstmac, + uint8_t maclen, + uint8_t rate, + uint8_t min_channel, + uint8_t max_channel, + bool autoinit) { + uint8_t ping_packet[] = {0x0f, 0x0f, 0x0f, 0x0f}; // this can be anything, we just need an ack + uint8_t ch = max_channel + 1; // means fail + nrf24_configure(handle, rate, srcmac, dstmac, maclen, 2, false, false); + for(ch = min_channel; ch <= max_channel + 1; ch++) { + nrf24_write_reg(handle, REG_RF_CH, ch); + if(nrf24_txpacket(handle, ping_packet, 4, true)) break; + } + + if(autoinit) { + FURI_LOG_D("nrf24", "initializing radio for channel %d", ch); + nrf24_configure(handle, rate, srcmac, dstmac, maclen, ch, false, false); + return ch; + } + + return ch; +} + +uint8_t nrf24_set_mac(uint8_t mac_addr, uint8_t *mac, uint8_t mlen) +{ + uint8_t addr[5]; + for(int i = 0; i < mlen; i++) addr[i] = mac[mlen - i - 1]; + return nrf24_write_buf_reg(nrf24_HANDLE, mac_addr, addr, mlen); +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/lib/nrf24/nrf24.h b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/lib/nrf24/nrf24.h new file mode 100644 index 000000000..cd994dc40 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/lib/nrf24/nrf24.h @@ -0,0 +1,381 @@ +#pragma once +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define R_REGISTER 0x00 +#define W_REGISTER 0x20 +#define REGISTER_MASK 0x1F +#define ACTIVATE 0x50 +#define R_RX_PL_WID 0x60 +#define R_RX_PAYLOAD 0x61 +#define W_TX_PAYLOAD 0xA0 +#define W_TX_PAYLOAD_NOACK 0xB0 +#define W_ACK_PAYLOAD 0xA8 +#define FLUSH_TX 0xE1 +#define FLUSH_RX 0xE2 +#define REUSE_TX_PL 0xE3 +#define RF24_NOP 0xFF + +#define REG_CONFIG 0x00 +#define REG_EN_AA 0x01 +#define REG_EN_RXADDR 0x02 +#define REG_SETUP_AW 0x03 +#define REG_SETUP_RETR 0x04 +#define REG_DYNPD 0x1C +#define REG_FEATURE 0x1D +#define REG_RF_SETUP 0x06 +#define REG_STATUS 0x07 +#define REG_RX_ADDR_P0 0x0A +#define REG_RX_ADDR_P1 0x0B +#define REG_RX_ADDR_P2 0x0C +#define REG_RX_ADDR_P3 0x0D +#define REG_RX_ADDR_P4 0x0E +#define REG_RX_ADDR_P5 0x0F +#define REG_RF_CH 0x05 +#define REG_TX_ADDR 0x10 +#define REG_FIFO_STATUS 0x17 + +#define RX_PW_P0 0x11 +#define RX_PW_P1 0x12 +#define RX_PW_P2 0x13 +#define RX_PW_P3 0x14 +#define RX_PW_P4 0x15 +#define RX_PW_P5 0x16 +#define RX_DR 0x40 +#define TX_DS 0x20 +#define MAX_RT 0x10 + +#define nrf24_TIMEOUT 500 +#define nrf24_CE_PIN &gpio_ext_pb2 +#define nrf24_HANDLE &furi_hal_spi_bus_handle_external + +/* Low level API */ + +/** Write device register + * + * @param handle - pointer to FuriHalSpiHandle + * @param reg - register + * @param data - data to write + * + * @return device status + */ +uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data); + +/** Write buffer to device register + * + * @param handle - pointer to FuriHalSpiHandle + * @param reg - register + * @param data - data to write + * @param size - size of data to write + * + * @return device status + */ +uint8_t nrf24_write_buf_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size); + +/** Read device register + * + * @param handle - pointer to FuriHalSpiHandle + * @param reg - register + * @param[out] data - pointer to data + * + * @return device status + */ +uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size); + +/** Power up the radio for operation + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return device status + */ +uint8_t nrf24_power_up(FuriHalSpiBusHandle* handle); + +/** Power down the radio + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return device status + */ +uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle); + +/** Sets the radio to RX mode + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return device status + */ +uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle); + +/** Sets the radio to TX mode + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return device status + */ +uint8_t nrf24_set_tx_mode(FuriHalSpiBusHandle* handle); + +/*=============================================================================================================*/ + +/* High level API */ + +/** Must call this before using any other nrf24 API + * + */ +void nrf24_init(); + +/** Must call this when we end using nrf24 device + * + */ +void nrf24_deinit(); + +/** Send flush rx command + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return device status + */ +uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle); + +/** Send flush tx command + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return device status + */ +uint8_t nrf24_flush_tx(FuriHalSpiBusHandle* handle); + +/** Gets the RX packet length in data pipe 0 + * + * @param handle - pointer to FuriHalSpiHandle + * pipe - pipe index (0..5) + * @return packet length in data pipe 0 + */ +uint8_t nrf24_get_packetlen(FuriHalSpiBusHandle* handle, uint8_t pipe); + +/** Sets the RX packet length in data pipe 0 + * + * @param handle - pointer to FuriHalSpiHandle + * @param len - length to set + * + * @return device status + */ +uint8_t nrf24_set_packetlen(FuriHalSpiBusHandle* handle, uint8_t len); + +/** Gets configured length of MAC address + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return MAC address length + */ +uint8_t nrf24_get_maclen(FuriHalSpiBusHandle* handle); + +/** Sets configured length of MAC address + * + * @param handle - pointer to FuriHalSpiHandle + * @param maclen - length to set MAC address to, must be greater than 1 and less than 6 + * + * @return MAC address length + */ +uint8_t nrf24_set_maclen(FuriHalSpiBusHandle* handle, uint8_t maclen); + +/** Gets the current status flags from the STATUS register + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return status flags + */ +uint8_t nrf24_status(FuriHalSpiBusHandle* handle); + +/** Gets the current transfer rate + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return transfer rate in bps + */ +uint32_t nrf24_get_rate(FuriHalSpiBusHandle* handle); + +/** Sets the transfer rate + * + * @param handle - pointer to FuriHalSpiHandle + * @param rate - the transfer rate in bps + * + * @return device status + */ +uint8_t nrf24_set_rate(FuriHalSpiBusHandle* handle, uint32_t rate); + +/** Gets the current channel + * In nrf24, the channel number is multiplied times 1MHz and added to 2400MHz to get the frequency + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return channel + */ +uint8_t nrf24_get_chan(FuriHalSpiBusHandle* handle); + +/** Sets the channel + * + * @param handle - pointer to FuriHalSpiHandle + * @param frequency - the frequency in hertz + * + * @return device status + */ +uint8_t nrf24_set_chan(FuriHalSpiBusHandle* handle, uint8_t chan); + +/** Gets the source mac address + * + * @param handle - pointer to FuriHalSpiHandle + * @param[out] mac - the source mac address + * + * @return device status + */ +uint8_t nrf24_get_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac); + +/** Sets the source mac address + * + * @param handle - pointer to FuriHalSpiHandle + * @param mac - the mac address to set + * @param size - the size of the mac address (2 to 5) + * + * @return device status + */ +uint8_t nrf24_set_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size); + +/** Gets the dest mac address + * + * @param handle - pointer to FuriHalSpiHandle + * @param[out] mac - the source mac address + * + * @return device status + */ +uint8_t nrf24_get_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac); + +/** Sets the dest mac address + * + * @param handle - pointer to FuriHalSpiHandle + * @param mac - the mac address to set + * @param size - the size of the mac address (2 to 5) + * + * @return device status + */ +uint8_t nrf24_set_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size); + +/** Reads RX packet + * + * @param handle - pointer to FuriHalSpiHandle + * @param[out] packet - the packet contents + * @param[out] ret_packetsize - size of the received packet + * @param packet_size: >1 - size, 1 - packet length is determined by RX_PW_P0 register, 0 - it is determined by dynamic payload length command + * + * @return device status + */ +uint8_t + nrf24_rxpacket(FuriHalSpiBusHandle* handle, uint8_t* packet, uint8_t* ret_packetsize, uint8_t packet_size_flag); + +/** Sends TX packet + * + * @param handle - pointer to FuriHalSpiHandle + * @param packet - the packet contents + * @param size - packet size + * @param ack - boolean to determine whether an ACK is required for the packet or not + * + * @return device status + */ +uint8_t nrf24_txpacket(FuriHalSpiBusHandle* handle, uint8_t* payload, uint8_t size, bool ack); + +/** Configure the radio + * This is not comprehensive, but covers a lot of the common configuration options that may be changed + * @param handle - pointer to FuriHalSpiHandle + * @param rate - transfer rate in Mbps (1 or 2) + * @param srcmac - source mac address + * @param dstmac - destination mac address + * @param maclen - length of mac address + * @param channel - channel to tune to + * @param noack - if true, disable auto-acknowledge + * @param disable_aa - if true, disable ShockBurst + * + */ +void nrf24_configure( + FuriHalSpiBusHandle* handle, + uint8_t rate, + uint8_t* srcmac, + uint8_t* dstmac, + uint8_t maclen, + uint8_t channel, + bool noack, + bool disable_aa); + +// Set mac address (MSB first), Return: Status +uint8_t nrf24_set_mac(uint8_t mac_addr, uint8_t *mac, uint8_t mlen); + +/** Configures the radio for "promiscuous mode" and primes it for rx + * This is not an actual mode of the nrf24, but this function exploits a few bugs in the chip that allows it to act as if it were. + * See http://travisgoodspeed.blogspot.com/2011/02/promiscuity-is-nrf24l01s-duty.html for details. + * @param handle - pointer to FuriHalSpiHandle + * @param channel - channel to tune to + * @param rate - transfer rate in Mbps (1 or 2) + */ +void nrf24_init_promisc_mode(FuriHalSpiBusHandle* handle, uint8_t channel, uint8_t rate); + +/** Listens for a packet and returns first possible address sniffed + * Call this only after calling nrf24_init_promisc_mode + * @param handle - pointer to FuriHalSpiHandle + * @param maclen - length of target mac address + * @param[out] addresses - sniffed address + * + * @return success + */ +bool nrf24_sniff_address(FuriHalSpiBusHandle* handle, uint8_t maclen, uint8_t* address); + +/** Sends ping packet on each channel for designated tx mac looking for ack + * + * @param handle - pointer to FuriHalSpiHandle + * @param srcmac - source address + * @param dstmac - destination address + * @param maclen - length of address + * @param rate - transfer rate in Mbps (1 or 2) + * @param min_channel - channel to start with + * @param max_channel - channel to end at + * @param autoinit - if true, automatically configure radio for this channel + * + * @return channel that the address is listening on, if this value is above the max_channel param, it failed + */ +uint8_t nrf24_find_channel( + FuriHalSpiBusHandle* handle, + uint8_t* srcmac, + uint8_t* dstmac, + uint8_t maclen, + uint8_t rate, + uint8_t min_channel, + uint8_t max_channel, + bool autoinit); + +/** Converts 64 bit value into uint8_t array + * @param val - 64-bit integer + * @param[out] out - bytes out + * @param bigendian - if true, convert as big endian, otherwise little endian + */ +void int64_to_bytes(uint64_t val, uint8_t* out, bool bigendian); + +/** Converts 32 bit value into uint8_t array + * @param val - 32-bit integer + * @param[out] out - bytes out + * @param bigendian - if true, convert as big endian, otherwise little endian + */ +void int32_to_bytes(uint32_t val, uint8_t* out, bool bigendian); + +/** Converts uint8_t array into 32 bit value + * @param bytes - uint8_t array + * @param bigendian - if true, convert as big endian, otherwise little endian + * + * @return 32-bit value + */ +uint32_t bytes_to_int32(uint8_t* bytes, bool bigendian); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/nrf24_packet_decoder.py b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/nrf24_packet_decoder.py new file mode 100644 index 000000000..d0ebc9c24 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/nrf24_packet_decoder.py @@ -0,0 +1,131 @@ +# +# NRF24L01+ Enhanced ShockBurst packets decoder +# +payload_len_default = 4 +packets = \ +( + '10101010 11101110 00000011 00001000 00001011 01000111 000100 10 0 10101010 10101010 10101010 10101010 00011101', + '10101010 11001000 11001000 11000011 110011 10 0 00001011 00000011 00000101 00000000 0010001100100000', + '10101010 11001000 11001000 11000100 000100 11 1 00001011 00000011 00000101 00000000 0010010011100010', + '10101010 11001000 11001000 11000100 00001011 00000011 00000101 00000010 1000010101000010', + '10101010 11001000 11001000 11000000 110011 10 0 11110101 00000010 00000011 00000000 0000111001000000', + '01010101 01000000 01101000 00010101 000000 00 0 0100100000100000', +# '01010101 01000010 11100100 10100110 01010101 01000100 110011 00 0 10010101 10110011 01100100 10101100 10101011 01010010 01111100 01001010 1100110100110001', + +) + +def bin2hex(x): + def bin2hex_helper(r): + while r: + yield r[0:2].upper() + r = r[2:] + if len(x) == 0: return + fmt = "{0:0" + str(int(len(x) / 8 * 2)) + "X}" + hex_data = fmt.format(int(x, 2)) + return list(bin2hex_helper(hex_data)) + +def bin2hexlong(b): + b = b.replace(" ", "") + out = ""; + n = 8 + for i in range(0, len(b), n): + b2 = b[i:i+n] + out = out + "{0:02X}".format(int(b2.ljust(8, '0'),2)) + return out + + +def split_packet(packet, parts): + """Split a string of 1s and 0s into multiple substrings as specified by parts. + Example: "111000011000", (3, 4, 2) -> ["111", "0000", "11", "000"] + :param packet: String of 1s and 0s + :param parts: Tuple of length of substrings + :return: list of substrings + """ + out = [] + packet = packet.replace(' ', '') + for part_length in parts: + out.append(packet[0:part_length]) + packet = packet[part_length:] + out.append(packet) + return out + + +def parse_packet(packet, address_length, ESB): + """Split a packet into its fields and return them as tuple.""" + if ESB: + preamble, address, payload_length, pid, no_ack, rest = split_packet(packet=packet, parts=(8, 8 * address_length, 6, 2, 1)) + payload, crc = split_packet(packet=rest, parts=((payload_len_default if int(payload_length, 2) > 32 else int(payload_length, 2)) * 8,)) + else: + preamble, address, rest = split_packet(packet=packet, parts=(8, 8 * address_length)) + crc = packet.rsplit(' ', 1)[1] + payload = rest[0:len(rest) - len(crc)] + payload_length = pid = no_ack = '' + + assert preamble in ('10101010', '01010101') + assert len(crc) in (8, 16) + + return preamble, address, payload_length, pid, no_ack, payload, crc + + +def crc(bits, size=8): + """Calculate the crc value for the polynomial initialized with 0xFF/0xFFFF) + :param size: 8 or 16 bit crc + :param bits: String of 1s and 0s + :return: + :polynomial: 1 byte CRC - standard is 0x107 = 0b100000111 = x^8+x^2+x^1+1, result the same for 0x07 + :polynomial: 2 byte CRC - standard is 0x11021 = X^16+X^12+X^5+1, result the same for 0x1021 + """ + if size == 8: + polynomial = 0x107 + crc = 0xFF + else: + polynomial = 0x11021 + crc = 0xFFFF + max_crc_value = (1 << size) - 1 # e.g. 0xFF for mode 8bit-crc + for bit in bits: + bit = int(bit, 2) + crc <<= 1 + if (crc >> size) ^ bit: # top most lfsr bit xor current data bit + crc ^= polynomial + crc &= max_crc_value # trim the crc to reject carry over bits +# print('{:X}'.format(crc)) + return crc + + +if __name__ == '__main__': + for packet in packets: + fld = packet.split(' '); + address_length = -1 + ESB = True + for f in fld: + if len(f) == 6 : break + if len(f) == 0 : + ESB = False + break + address_length += 1 + preamble, address, payload_length, pid, no_ack, payload, crc_received = \ + parse_packet(packet=packet, address_length=address_length, ESB=ESB) + crc_size = len(crc_received) + crc_received = '0x' + '{:X}'.format(int(crc_received, 2)) + print(f"Packet: {packet}") + print('\n'.join(( + f'Hex: {bin2hexlong(packet)}', + 'Preamble: 0x%X' % int(preamble,2), + f'Address: {address_length} bytes - {bin2hex(address)}'))) + if ESB: + print('\n'.join(( + f'Payload length in packet: {int(payload_length, 2)}, used: {(payload_len_default if int(payload_length, 2) > 32 else int(payload_length, 2))}', + f'Payload: {bin2hex(payload)}', + f'Pid: {int(pid, 2)}', + f'No_ack: {int(no_ack, 2) == 1}'))) + else: + print(f'Not Enhanced ShockBurst packet, payload length: {int(len(payload) / 8)}') + print(f'Payload: {bin2hex(payload)}') + print(f'CRC{crc_size}: {crc_received}') + crc_calculated = '0x' + '{:X}'.format(crc(address + payload_length + pid + no_ack + payload, size=crc_size)) + if crc_received == crc_calculated: + print('CRC is valid!') + else: + print(f'CRC mismatch! Calculated CRC is {crc_calculated}.') + print('-------------') + diff --git a/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/nrf24scan.c b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/nrf24scan.c new file mode 100644 index 000000000..ede3e3f48 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/nrf24scan.c @@ -0,0 +1,1387 @@ +// +// Written by vad7, 20.11.2022. +// +#include "nrf24scan.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TAG "nrf24scan" +#define VERSION "2.1" +#define MAX_CHANNEL 125 +#define MAX_ADDR 6 + +#define SCAN_APP_PATH_FOLDER "/ext/nrf24scan" +#define SETTINGS_FILENAME "addresses.txt"// Settings file format (1 parameter per line): + // SNIFF - if present then sniff mode + // Rate: 0/1/2 - rate in Mbps (=0.25/1/2) + // Ch: 0..125 - default channel + // ESB: 0/1 (1 - Enhanced ShockBurst) + // DPL: 0/1 (1 - Dynamic Payload Length) + // CRC: 0/1/2 (CRC length) + // Payload: 1..32 (bytes) + // P0: address P0 in hex (5 byte, LSB last) + // P1: address P1 in hex (5 byte, LSB last) + // P2: address P2, LSB in hex (1 byte) + // P3: address P3, LSB in hex (1 byte) + // P4: address P4, LSB in hex (1 byte) + // P5: address P5, LSB in hex (1 byte) + // captured data: + // first byte = { RAW packet flag (0x80/0x00) } + { channel number } + // second byte = { Payload len 5 bits, 0 = 32 } + {{ RAW packet: ESB flag 0x04/0x00 + address size-2 if RAW packet } or { pipe #(0..5) }}, + // ... up to MAX_LOG_RECORDS-1 +#define SNIFF_FILENAME "sniff.txt" // settings for sniff mode +#define LOG_FILENAME "log" +#define LOG_FILEEXT ".txt" +#define MAX_LOG_RECORDS 200 +#define MAX_FOUND_RECORDS 70 +#define LOG_REC_SIZE 34 // max packet size +#define VIEW_LOG_MAX_X 22 +#define VIEW_LOG_WIDTH_B 10 // bytes + +const char SettingsFld_Rate[] = "Rate:"; +const char SettingsFld_Ch[] = "Ch:"; +const char SettingsFld_ESB[] = "ESB:"; +const char SettingsFld_DPL[] = "DPL:"; +const char SettingsFld_CRC[] = "CRC:"; +const char SettingsFld_Payload[] = "Payload:"; +const char SettingsFld_Sniff[] = "SNIFF"; +char SettingsFld_Addr = 'P'; + +Nrf24Scan* APP; +uint8_t what_doing = 0; // 0 - setup, 1 - view log, 2 - view addresses +uint8_t what_to_do = 1; // 0 - view, 1 - view & sniff, 2 - view & read, 3 - view & read selected addr +uint8_t save_settings = 0; +char screen_buf[64]; +char addr_file_name[32]; +uint8_t NRF_rate = 2; // 0 - 250Kbps, 1 - 1Mbps, 2 - 2Mbps +uint8_t NRF_channel = 0;// 0..125 +uint8_t NRF_ESB = 1; // 0 - ShockBurst, 1 - Enhanced ShockBurst +uint8_t NRF_DPL = 0; // 1 - Dynamic Payload Length +uint8_t NRF_CRC = 2; // 1 - No, 1 - CRC 1byte, 2 - CRC 2byte +uint8_t NRF_Payload = 32;// Payload len in bytes or Minimum payload in sniff mode, 0..32 +uint8_t NRF_Payload_sniff_min = 0; +uint8_t NRF_AA_OFF = 0; // Disable Auto Acknowledgement +bool NRF_ERROR = 0; + +struct ADDRS { + uint8_t addr_P0[5]; // MSB first + uint8_t addr_P1[5]; // MSB first + uint8_t addr_P2; // LSB only, MSB bytes equal addr_P1 + uint8_t addr_P3; // LSB only, MSB bytes equal addr_P1 + uint8_t addr_P4; // LSB only, MSB bytes equal addr_P1 + uint8_t addr_P5; // LSB only, MSB bytes equal addr_P1 + uint8_t addr_len; // 2..5 + uint8_t addr_count; +}; + +struct ADDRS addrs; +struct ADDRS addrs_sniff; +bool sniff_loaded = 0; +int16_t found_total; +int16_t view_found; + +int8_t log_to_file = 0; // 0 - no, 1 - yes(new), 2 - append, -1 - only clear +uint16_t log_arr_idx; +uint16_t view_log_arr_idx = 0; +uint16_t view_log_arr_x = 0; +bool save_to_new_log = true; +uint16_t last_packet_send = -1; +uint8_t last_packet_send_st = 0; +int16_t find_channel_period = 0; // sec +uint8_t menu_selected = 0; +uint32_t start_time; +uint8_t view_log_decode_PCF = 0; // view log: 1 - decode packet control field (9b) when ESB off. After pipe # (hex): +uint8_t view_log_decode_CRC = 0; // CRC bytes - 1/2, 0 - none + +#define menu_selected_max 5 +enum { + Menu_open_file = 0, + Menu_enter_channel, + Menu_enter_rate, + Menu_enter_scan_period, + Menu_log, + Menu_ok +}; + +//#define MIN(a, b) ((a> 7)); + arr++; + out += 2; + } while(--bytes); +} + +void clear_log() +{ + log_arr_idx = 0; + view_log_arr_idx = 0; + last_packet_send = -1; + found_total = 0; + view_found = -1; +} + +void write_to_log_file(Storage* storage, bool f_settings) +{ + if(log_arr_idx == 0 && !f_settings) return; + Stream* file_stream = file_stream_alloc(storage); + FuriString* str = furi_string_alloc(); + furi_string_set(str, SCAN_APP_PATH_FOLDER); + furi_string_cat(str, "/"); + bool fl; + if(f_settings) { + furi_string_cat(str, SETTINGS_FILENAME); + fl = file_stream_open(file_stream, furi_string_get_cstr(str), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS); + if(!fl) file_stream_close(file_stream); + } else { + furi_string_cat(str, LOG_FILENAME); + furi_string_cat(str, LOG_FILEEXT); + if(save_to_new_log) { + int cnt = 1; + do { + fl = file_stream_open(file_stream, furi_string_get_cstr(str), FSAM_READ_WRITE, FSOM_CREATE_NEW); + if(fl) break; + file_stream_close(file_stream); + furi_string_set(str, SCAN_APP_PATH_FOLDER); + furi_string_cat(str, "/"); + furi_string_cat(str, LOG_FILENAME); + furi_string_cat_printf(str, "-%02d", cnt); + furi_string_cat(str, LOG_FILEEXT); + } while(++cnt < 100); + if(!fl) { + FURI_LOG_E(TAG, "Failed to create new log file"); + notification_message(APP->notification, &sequence_blink_red_100); + } + } else { + fl = file_stream_open(file_stream, furi_string_get_cstr(str), FSAM_READ_WRITE, FSOM_OPEN_APPEND); + if(fl) { + if(stream_size(file_stream) == 0) save_to_new_log = true; + } else file_stream_close(file_stream); + } + } + if(fl) { + FURI_LOG_D(TAG, "Save to %s", furi_string_get_cstr(str)); + if(save_to_new_log || f_settings) { + if(what_to_do == 1) furi_string_printf(str, "%s\n", SettingsFld_Sniff); else furi_string_reset(str); + furi_string_cat_printf(str, "%s %d\n%s %d\n%s %d\n", SettingsFld_Rate, NRF_rate, SettingsFld_Ch, NRF_channel, SettingsFld_ESB, NRF_ESB); + furi_string_cat_printf(str, "%s %d\n%s %d\n%s %d\n", SettingsFld_DPL, NRF_DPL, SettingsFld_CRC, NRF_CRC, SettingsFld_Payload, what_to_do == 1 ? NRF_Payload_sniff_min : NRF_Payload); + if(addrs.addr_count > 0) { furi_string_cat_printf(str, "P0: "); add_to_furi_str_hex_bytes(str, (char*)addrs.addr_P0, addrs.addr_len); furi_string_cat(str, "\n"); } + if(addrs.addr_count > 1) { furi_string_cat_printf(str, "P1: "); add_to_furi_str_hex_bytes(str, (char*)addrs.addr_P1, addrs.addr_len); furi_string_cat(str, "\n"); } + if(addrs.addr_count > 2) { furi_string_cat_printf(str, "P2: "); furi_string_cat_printf(str, "%02X\n", addrs.addr_P2); } + if(addrs.addr_count > 3) { furi_string_cat_printf(str, "P3: "); furi_string_cat_printf(str, "%02X\n", addrs.addr_P3); } + if(addrs.addr_count > 4) { furi_string_cat_printf(str, "P4: "); furi_string_cat_printf(str, "%02X\n", addrs.addr_P4); } + if(addrs.addr_count > 5) { furi_string_cat_printf(str, "P5: "); furi_string_cat_printf(str, "%02X\n", addrs.addr_P5); } + if(!(fl = stream_write_string(file_stream, str) == furi_string_size(str))) { + FURI_LOG_E(TAG, "Failed to write header to file!"); + notification_message(APP->notification, &sequence_blink_red_100); + } + } + if(fl) { + if(f_settings) { + save_settings = 0; + if(strcmp(addr_file_name, "NONE") == 0) strcpy(addr_file_name, SETTINGS_FILENAME); + } else { + int i = 0; + for(; i < log_arr_idx; i++) { + furi_string_reset(str); + uint8_t *ptr = APP->log_arr + i * LOG_REC_SIZE; + int len; + if(ptr[0] & 0x80) { // RAW + len = (ptr[1] & 0b11)+2 + ((ptr[1] & 0b100) ? 2 : 0) + (ptr[1] >> 3) + 2; // addr + PCF? + payload + crcmax + } else { + len = (ptr[1] >> 3); + if(len == 0) len = 32; + } + //if(len < NRF_Payload) len = NRF_Payload; + add_to_furi_str_hex_bytes(str, (char*)ptr, len + 2); + furi_string_cat(str, "\n"); + if(stream_write_string(file_stream, str) != furi_string_size(str)) { + FURI_LOG_E(TAG, "Failed to write to file!"); + break; + } + } + if(i == log_arr_idx) { + notification_message(APP->notification, &sequence_blink_yellow_100); + FURI_LOG_D(TAG, "File saved"); + } + save_to_new_log = false; + } + } + file_stream_close(file_stream); + } else { + FURI_LOG_E(TAG, "Failed to open file %s", furi_string_get_cstr(str)); + notification_message(APP->notification, &sequence_blink_red_100); + } + stream_free(file_stream); + furi_string_free(str); +} + +static bool select_settings_file(Stream* stream) { + DialogsApp* dialogs = furi_record_open("dialogs"); + bool result = false; + FuriString* path; + path = furi_string_alloc(); + furi_string_set(path, SCAN_APP_PATH_FOLDER); + + DialogsFileBrowserOptions browser_options; + dialog_file_browser_set_basic_options(&browser_options, ".txt", NULL); + browser_options.hide_ext = false; + + bool ret = dialog_file_browser_show(dialogs, path, path, &browser_options); + + furi_record_close("dialogs"); + if(ret) { + if(!file_stream_open(stream, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + FURI_LOG_D(TAG, "Cannot open file \"%s\"", furi_string_get_cstr(path)); + file_stream_close(stream); + } else { + FURI_LOG_D(TAG, "Open file \"%s\"", furi_string_get_cstr(path)); + strncpy(addr_file_name, furi_string_get_cstr(path) + sizeof(SCAN_APP_PATH_FOLDER), sizeof(addr_file_name)); + result = true; + } + } + furi_string_free(path); + return result; +} + +// 0 - success, otherwise an error +static uint8_t load_settings_file(Stream* file_stream) { + size_t file_size = 0; + char* file_buf; + uint8_t err = 5; + file_size = stream_size(file_stream); + if(file_size == (size_t)0) { + FURI_LOG_D(TAG, "load failed. file_size: %d", file_size); + return 1; + } + file_size = MIN(file_size, (size_t) LOG_REC_SIZE * MAX_LOG_RECORDS * 2 + 100); + file_buf = malloc(file_size + 1); + if(file_buf == NULL) { + FURI_LOG_D(TAG, "Memory low, need: %d", file_size); + return 2; + } + memset(file_buf, 0, file_size + 1); + if(stream_read(file_stream, (uint8_t*)file_buf, file_size) == file_size) { + FURI_LOG_D(TAG, "Loading settings file"); + char* line_ptr = file_buf; + int16_t line_num = 0; + what_to_do = 2; + sniff_loaded = 0; + bool log_loaded = false; + while(line_ptr && (size_t)(line_ptr - file_buf) < file_size) { + char* end_ptr = strstr((char*)line_ptr, "\n"); + if(end_ptr == NULL) end_ptr = file_buf + file_size; else *end_ptr = '\0'; + int line_len = end_ptr - line_ptr; + if(*line_ptr == '\r' || line_len == 0) { + line_ptr = end_ptr + 1; + continue; + } + if(*(end_ptr - 1) < '0') { + *(end_ptr - 1) = '\0'; + line_len--; + } + //FURI_LOG_D(TAG, " L#%d: [%d]%s", line_num, line_len, line_ptr); + if(strncmp(line_ptr, SettingsFld_Rate, sizeof(SettingsFld_Rate)-1) == 0) { + NRF_rate = atoi(line_ptr + sizeof(SettingsFld_Rate)); + } else if(strncmp(line_ptr, SettingsFld_Ch, sizeof(SettingsFld_Ch)-1) == 0) { + NRF_channel = atoi(line_ptr + sizeof(SettingsFld_Ch)); + } else if(strncmp(line_ptr, SettingsFld_ESB, sizeof(SettingsFld_ESB)-1) == 0) { + NRF_ESB = atoi(line_ptr + sizeof(SettingsFld_ESB)); + } else if(strncmp(line_ptr, SettingsFld_DPL, sizeof(SettingsFld_DPL)-1) == 0) { + NRF_DPL = atoi(line_ptr + sizeof(SettingsFld_DPL)); + } else if(strncmp(line_ptr, SettingsFld_CRC, sizeof(SettingsFld_CRC)-1) == 0) { + NRF_CRC = atoi(line_ptr + sizeof(SettingsFld_CRC)); + if(what_to_do == 1) view_log_decode_CRC = NRF_CRC; + } else if(strncmp(line_ptr, SettingsFld_Payload, sizeof(SettingsFld_Payload)-1) == 0) { + uint8_t pld = atoi(line_ptr + sizeof(SettingsFld_Payload)); + if(pld > 32) pld = 32; + if(sniff_loaded) { + NRF_Payload_sniff_min = pld; + } else { + if(pld == 0) pld = 32; + NRF_Payload = pld; + } + } else if(strncmp(line_ptr, SettingsFld_Sniff, sizeof(SettingsFld_Sniff)-1) == 0) { + what_to_do = 1; + sniff_loaded = 1; + } else if(*line_ptr == SettingsFld_Addr) { + char a = *(++line_ptr); + struct ADDRS *adr = sniff_loaded ? &addrs_sniff : &addrs; + line_ptr += 3; + switch(a) { + case '0': + memset(adr, 0, sizeof(addrs)); + adr->addr_len = ConvertHexToArray(line_ptr, adr->addr_P0, sniff_loaded ? 3 : 5); + if(adr->addr_len >= 2) err = 0; + break; + case '1': + ConvertHexToArray(line_ptr, adr->addr_P1, what_to_do == 1 ? 3 : 5); + break; + case '2': + ConvertHexToArray(line_ptr, &adr->addr_P2, 1); + break; + case '3': + ConvertHexToArray(line_ptr, &adr->addr_P3, 1); + break; + case '4': + ConvertHexToArray(line_ptr, &adr->addr_P4, 1); + break; + case '5': + ConvertHexToArray(line_ptr, &adr->addr_P5, 1); + break; + default: + a = 0; + break; + } + if(err == 0 && a) adr->addr_count = a - '0' + 1; + } else if(line_len >= 3 * 2) { // data + if(!log_loaded) { + log_loaded = true; + clear_log(); + what_to_do = 0; + } + if(log_arr_idx < MAX_LOG_RECORDS - 1) { + if(ConvertHexToArray(line_ptr, APP->log_arr + log_arr_idx * LOG_REC_SIZE, LOG_REC_SIZE) > 0) err = 0; + log_arr_idx++; + } + } + line_ptr = end_ptr + 1; + line_num++; + } + } else { + FURI_LOG_D(TAG, "load failed. file size: %d", file_size); + err = 4; + } + free(file_buf); + return err; +} + +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); +} + +void check_add_addr(uint8_t *pkt) +{ + if(addrs.addr_count > 0 && memcmp(addrs.addr_P0, pkt, addrs.addr_len) == 0) return; + if(addrs.addr_count > 1 && memcmp(addrs.addr_P1, pkt, addrs.addr_len - 1) == 0) { + if(addrs.addr_P1[addrs.addr_len - 1] == pkt[addrs.addr_len - 1]) return; + if(addrs.addr_count > 2 && addrs.addr_P2 == pkt[addrs.addr_len - 1]) return; + if(addrs.addr_count > 3 && addrs.addr_P3 == pkt[addrs.addr_len - 1]) return; + if(addrs.addr_count > 4 && addrs.addr_P4 == pkt[addrs.addr_len - 1]) return; + if(addrs.addr_count > 5 && addrs.addr_P5 == pkt[addrs.addr_len - 1]) return; + } + if(addrs.addr_count == 1) memcpy(addrs.addr_P1, pkt, addrs.addr_len); + else if(addrs.addr_count == 2) addrs.addr_P2 = pkt[addrs.addr_len - 1]; + else if(addrs.addr_count == 3) addrs.addr_P3 = pkt[addrs.addr_len - 1]; + else if(addrs.addr_count == 4) addrs.addr_P4 = pkt[addrs.addr_len - 1]; + else if(addrs.addr_count == 5) addrs.addr_P5 = pkt[addrs.addr_len - 1]; + addrs.addr_count++; +} + +static void prepare_nrf24(bool fsend_packet) +{ + nrf24_write_reg(nrf24_HANDLE, REG_STATUS, 0x70); // clear interrupts + nrf24_write_reg(nrf24_HANDLE, REG_RF_SETUP, NRF_rate); + uint8_t erx_addr = (1<<0); // Enable RX_P0 + struct ADDRS *adr = what_to_do == 1 ? &addrs_sniff : &addrs; + if(!fsend_packet) { + uint8_t payload = NRF_Payload; + uint8_t *rec = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE; + uint8_t addr_size = (*(rec + 1) & 0b11) + 2; + bool setup_from_log = false; + if(what_to_do >= 2) { + if(log_arr_idx && (*rec & 0x80)) { + setup_from_log = true; + memcpy(addrs.addr_P0, rec + 2, addr_size); + addrs.addr_count = 1; + addrs.addr_len = addr_size; + payload = *(rec + 1) >> 3; + if(what_to_do == 2) { + uint8_t *p = APP->log_arr + 2; + int16_t i = 0; + for(i = 0; i < log_arr_idx; i++, p += LOG_REC_SIZE) { + if((*(p - 2) & 0x80) && (*(p - 1) & 0b11) + 2 == addr_size && rec + 2 != p) { + if(memcmp(p, addrs.addr_P0, addr_size - 1) == 0) { + check_add_addr(p); + if(addrs.addr_count >= 6) break; + } + } + } + } + } + } + if(what_to_do == 1) { // SNIFF + payload = 32; + nrf24_write_reg(nrf24_HANDLE, REG_CONFIG, 0x70); // Mask all interrupts, NO CRC + nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0); // Automatic Retransmission + nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0); // Auto acknowledgement + nrf24_write_reg(nrf24_HANDLE, REG_FEATURE, 0); // Enables the W_TX_PAYLOAD_NOACK command, Disable Payload with ACK, set Dynamic Payload + nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, NRF_channel); + } else if(setup_from_log) { // Scan + nrf24_write_reg(nrf24_HANDLE, REG_CONFIG, 0x70 | ((NRF_CRC == 1 ? 0b1000 : NRF_CRC == 2 ? 0b1100 : 0))); // Mask all interrupts + nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, *rec & 0x7F); + nrf24_write_reg(nrf24_HANDLE, REG_FEATURE, *(rec + 2 + addr_size) >> 2 != 0x33 ? 4+1 : 1); // Enables the W_TX_PAYLOAD_NOACK command, Disable Payload with ACK, set Dynamic Payload + if(*(rec + 1) & 0b100) { // ESB + nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0x01); // Automatic Retransmission + nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0x3F); // Auto acknowledgement + } else { + nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0); // Automatic Retransmission + nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0); // Auto acknowledgement + } + } else { + nrf24_write_reg(nrf24_HANDLE, REG_CONFIG, 0x70 | ((NRF_CRC == 1 ? 0b1000 : NRF_CRC == 2 ? 0b1100 : 0))); // Mask all interrupts + nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, NRF_ESB ? 0x01 : 0); // Automatic Retransmission + nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, NRF_AA_OFF || !NRF_ESB ? 0 : 0x3F); // Auto acknowledgement + nrf24_write_reg(nrf24_HANDLE, REG_FEATURE, NRF_DPL ? 4+1 : 1); // Enables the W_TX_PAYLOAD_NOACK command, Disable Payload with ACK, set Dynamic Payload + nrf24_write_reg(nrf24_HANDLE, REG_DYNPD, NRF_DPL ? 0x3F : 0); // Enable dynamic payload reg + nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, NRF_channel); + } + if(adr->addr_count == 0) return; + nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, payload); + nrf24_set_maclen(nrf24_HANDLE, adr->addr_len); + nrf24_set_mac(REG_RX_ADDR_P0, adr->addr_P0, adr->addr_len); + uint8_t tmp[5] = { 0 }; + nrf24_read_reg(nrf24_HANDLE, REG_RX_ADDR_P0, tmp, adr->addr_len); + for(uint8_t i = 0; i < adr->addr_len / 2; i++) { + uint8_t tb = tmp[i]; + tmp[i] = tmp[adr->addr_len - i - 1]; + tmp[adr->addr_len - i - 1] = tb; + } + NRF_ERROR = memcmp(adr->addr_P0, tmp, adr->addr_len) != 0; + FURI_LOG_D(TAG, "Payload: %d", payload); + nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, payload); + if(adr->addr_count > 1) { + nrf24_set_mac(REG_RX_ADDR_P1, adr->addr_P1, adr->addr_len); + nrf24_write_reg(nrf24_HANDLE, RX_PW_P1, payload); + erx_addr |= (1<<1); // Enable RX_P1 + } else nrf24_write_reg(nrf24_HANDLE, RX_PW_P1, 0); + if(adr->addr_count > 2) { + nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P2, &adr->addr_P2, 1); + nrf24_write_reg(nrf24_HANDLE, RX_PW_P2, payload); + erx_addr |= (1<<2); // Enable RX_P2 + } else nrf24_write_reg(nrf24_HANDLE, RX_PW_P2, 0); + if(adr->addr_count > 3) { + nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P3, &adr->addr_P3, 1); + nrf24_write_reg(nrf24_HANDLE, RX_PW_P3, payload); + erx_addr |= (1<<3); // Enable RX_P3 + } else nrf24_write_reg(nrf24_HANDLE, RX_PW_P3, 0); + if(adr->addr_count > 4) { + nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P4, &adr->addr_P4, 1); + nrf24_write_reg(nrf24_HANDLE, RX_PW_P4, payload); + erx_addr |= (1<<4); // Enable RX_P4 + } else nrf24_write_reg(nrf24_HANDLE, RX_PW_P4, 0); + if(adr->addr_count > 5) { + nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P5, &adr->addr_P5, 1); + nrf24_write_reg(nrf24_HANDLE, RX_PW_P5, payload); + erx_addr |= (1<<5); // Enable RX_P5 + } else nrf24_write_reg(nrf24_HANDLE, RX_PW_P5, 0); + nrf24_write_reg(nrf24_HANDLE, REG_EN_RXADDR, erx_addr); + } + nrf24_flush_rx(nrf24_HANDLE); + nrf24_flush_tx(nrf24_HANDLE); + nrf24_set_idle(nrf24_HANDLE); +} + +void correct_NRF_Payload_sniff_min() +{ + uint8_t pld = 32 - 3 - (NRF_ESB ? 2 : 0) - NRF_CRC + (addrs_sniff.addr_len - 2); + if(NRF_Payload_sniff_min > pld) NRF_Payload_sniff_min = pld; +} + +static void start_scanning() +{ + FURI_LOG_D(TAG, "Start proc-%d: Ch=%d Rate=%d", what_to_do, NRF_channel, NRF_rate); + if(what_to_do == 1) { // SNIFF + correct_NRF_Payload_sniff_min(); + view_log_decode_CRC = NRF_CRC; + } else if(sniff_loaded) { // Switch from sniff to scan/view + // to do... + } + prepare_nrf24(false); + if(NRF_ERROR) { + FURI_LOG_E(TAG, "NRF R/W ERROR!"); + return; + } + nrf24_set_rx_mode(nrf24_HANDLE); + start_time = furi_get_tick(); +} + +// start bitnum = 7 +uint32_t calc_crc(uint32_t crc, uint8_t *ptr, uint8_t bitnum, uint16_t bits) +{ + //uint8_t bitnum = 7; + uint32_t crc_high, polynom; + if(view_log_decode_CRC == 2) { + crc_high = (1<<16); + polynom = 0x1021; // X^16+X^12+X^5+1 => 0x11021 & 0xFFFF = 0x1021 + } else { + crc_high = (1<<8); + polynom = 0x07; // x^8+x^2+x^1+1 => 0x107 & 0xFF = 0x07 + } + while(bits--) { + crc <<= 1; + if(((crc & crc_high) != 0) ^ ((*ptr >> bitnum) & 1)) crc ^= polynom; + if(bitnum == 0) { + ptr++; + bitnum = 7; + } else bitnum--; + } + return crc & (view_log_decode_CRC == 2 ? 0xFFFF : 0xFF); +} + +// shifted 1 bit right +uint32_t get_shifted_crc(uint8_t *pcrc) +{ + uint32_t crc = ((*pcrc << 1) & 0xFF) | (*(pcrc+1) >> 7); + if(view_log_decode_CRC == 2) { + crc = (crc << 8) | ((*(pcrc+1) << 1) & 0xFF) | (*(pcrc+2) >> 7); + } + return crc; +} + +bool check_packet(uint8_t *pkt, uint16_t size) +{ + if(size < 3 || size > 32) return false; + uint8_t b = *pkt; + if(b == 0x55 || b == 0xAA || b == 0x00 || b == 0xFF) return false; // skip pkt when address begin with + uint32_t prevcrc = 0xFFFFFFFF; + bool found = false; + uint8_t addr_size = 3; + for(; addr_size <= 5; addr_size++) { + if(NRF_ESB){ + uint8_t _payload = *(pkt + addr_size) >> 2; + if((_payload > size - addr_size - 2 - view_log_decode_CRC && _payload != 0x33)) continue; + uint8_t *p = pkt + addr_size; + if(prevcrc == 0xFFFFFFFF) { + prevcrc = calc_crc(view_log_decode_CRC == 2 ? 0xFFFF : 0xFF, pkt, 7, 3 * 8); // crc for smallest addr + } + uint32_t crc; + if(addr_size > 3) crc = calc_crc(prevcrc, p - (addr_size - 3), 7, 8 * (addr_size - 3)); else crc = prevcrc; + if(_payload != 0x33) { // DPL + crc = calc_crc(crc, p, 7, 9 + _payload * 8); + if(crc == get_shifted_crc(p + _payload + 1)) { + *(pkt - 1) = ((_payload & 0x1F) << 3) + 0b100 + (addr_size - 2); + FURI_LOG_D(TAG, "VALID CRC %X: dpl: %d, addr: %d", (uint16_t)crc, _payload, addr_size); + found = true; + break; + } + } else { + crc = calc_crc(crc, p++, 7, 9); // PCF + if(crc == get_shifted_crc(p)) { + _payload = 0; + found = true; + } else { + for(uint8_t i = 1; i < size - addr_size - view_log_decode_CRC; i++) { + crc = calc_crc(crc, p++, 6, 8); + if(crc == get_shifted_crc(p)) { + _payload = i; + found = true; + break; + } + } + } + if(found) { + *(pkt - 1) = ((_payload & 0x1F) << 3) + 0b100 + (addr_size - 2); + FURI_LOG_D(TAG, "VALID CRC %X: pl: %d, addr: %d", (uint16_t)crc, _payload, addr_size); + break; + } + } + } else { + uint8_t *p; + if(addr_size == 3) { + prevcrc = calc_crc(view_log_decode_CRC == 2 ? 0xFFFF : 0xFF, pkt, 7, 3 * 8); // crc for smallest addr + p = pkt + addr_size; + } else { + p = pkt + addr_size - 1; + prevcrc = calc_crc(prevcrc, p++, 7, 8); + } + uint32_t crc = prevcrc; + if((view_log_decode_CRC == 1 && crc == *p) || (view_log_decode_CRC == 2 && crc == (uint32_t)((*p<<8) | *(p+1)))) { + *(pkt - 1) = ((0 & 0x1F) << 3) + 0b000 + (addr_size - 2); + FURI_LOG_D(TAG, "VALID CRC %X: pl: %d, addr: %d", (uint16_t)crc, 0, addr_size); + found = true; + break; + } + for(uint8_t i = 1; i <= size - addr_size - view_log_decode_CRC; i++) { + crc = calc_crc(crc, p++, 7, 8); + if((view_log_decode_CRC == 1 && crc == *p) || (view_log_decode_CRC == 2 && crc == (uint32_t)((*p<<8) | *(p+1)))) { + *(pkt - 1) = ((i & 0x1F) << 3) + 0b000 + (addr_size - 2); + FURI_LOG_D(TAG, "VALID CRC %X: pl: %d, addr: %d", (uint16_t)crc, i, addr_size); + found = true; + break; + } + } + if(found) break; + } + } + if(found) { + if(furi_log_get_level() == FuriLogLevelDebug) { + char dbuf[65]; + dbuf[0] = 0; + add_to_str_hex_bytes(dbuf, (char*)pkt, size); + FURI_LOG_D(TAG, "PKT%02X: %s (%d)", *(pkt - 1), dbuf, size); + } + int16_t i = 0; + for(; i < found_total; i++) { + if(APP->found[i].addr_size != addr_size) continue; + if(memcmp(APP->found[i].addr, pkt, addr_size) == 0) break; + } + if(i != found_total) { // found + APP->found[i].total++; + } else { + uint8_t *p = APP->log_arr + 2; + for(i = 0; i < log_arr_idx; i++, p += LOG_REC_SIZE) { + if((*(p - 2) & 0x80) && (*(p - 1) & 0b11) + 2 == addr_size && pkt != p) { + if(memcmp(p, pkt, addr_size) == 0) break; + } + } + if(i != log_arr_idx && found_total < MAX_FOUND_RECORDS) { // found -> 2 + memset(&APP->found[found_total], 0, sizeof(struct FOUND)); + memcpy(APP->found[found_total].addr, pkt, addr_size); + APP->found[found_total].addr_size = addr_size; + APP->found[found_total].total = 2; + if(found_total == 0) view_found = 0; + found_total++; + } + } + } + + return found; +} + +bool nrf24_read_newpacket() { + if(APP->log_arr == NULL) return false; + bool found = false; + uint8_t packetsize; + uint8_t *ptr = APP->log_arr + log_arr_idx * LOG_REC_SIZE; + uint8_t st; +/* test pkts + static int iii = 0; + char ppp[][65] = { "54A545109411544BAAE50110A3282512A9A1152A565B22AAA48AB751A5", + "C8C8C0CE7A81018007202FFFFC", + "EAEC8C8C2CE3C0101006FB737A", + "BEBFFFEC8C8C1CC00542AF7CFF7DBEAFE3397FEAFEF1DDFA4AEF7FDBB7CDEABC", + "FEAAAABEAAFEAAC8C8C28E1C810080490ABAF7FEEB76B7FDFEF7DFFB47FB97FE", + "A8AAC8C8C1CE20163DF7DFFD00", + "AFFEEFEC8C8C2CE4001010062F037F9BFFDF1DAD5EDBEF55DD9AB535FCB67F55", + "AC8C8C1CE5F8102000D503D7ABF", + "EE03080B4712555555550E80", + "C8C8C41385818280127100", + "AAC8C8C3CE05818280119000" + "AC8C8C413858182801271000", + "AAC8C8C40B0305028542" + }; + if(iii < 13) { + ConvertHexToArray(ppp[iii], ptr + 2, 32); + st = RX_DR; + packetsize = 32; + iii++; + } else +//*/ + st = nrf24_rxpacket(nrf24_HANDLE, ptr + 2 + (what_to_do == 1 ? addrs_sniff.addr_len - 2 : 0), &packetsize, what_to_do == 1 ? 32 : !NRF_DPL); + if(st & RX_DR) { + st = (st >> 1) & 7; // pipe # + if(what_to_do == 1) { // SNIFF + *ptr++ = NRF_channel | 0x80; + *ptr++ = st; // pipe # + if(addrs_sniff.addr_len > 2) { + *ptr = st == 0 ? addrs_sniff.addr_P0[2] : st == 1 ? addrs_sniff.addr_P1[2] : st == 2 ? addrs_sniff.addr_P2 : st == 3 ? addrs_sniff.addr_P3 : st == 4 ? addrs_sniff.addr_P4 : addrs_sniff.addr_P5; + } + if(!check_packet(ptr, packetsize)) { + if(addrs_sniff.addr_len > 2) return false; // skip if mac MSB added to preamble + uint8_t shifted = 0; + uint8_t shift_max = (32 - 3 - NRF_Payload_sniff_min - NRF_CRC) * 8 - 1; + while(shifted++ < shift_max) { // Shift packet left by one bit if minimum payload fits + uint8_t i = 0; + for(; i < packetsize - 1; i++) ptr[i] = (ptr[i] << 1) | (ptr[i + 1] >> 7); + ptr[i] <<= 1; + if(check_packet(ptr, packetsize - (shifted >> 3) - 1)) goto x_valid; + } + return false; + } + } else { + *ptr++ = NRF_channel; + *ptr++ = ((packetsize & 0x1F) << 3) | st; // payload size + pipe # + } +x_valid: + if(packetsize < 32) memset(ptr + packetsize, 0, 32 - packetsize); + if(log_arr_idx < MAX_LOG_RECORDS - 1) { + log_arr_idx++; + } else { + if(log_to_file == 1 || log_to_file == 2) { + write_to_log_file(APP->storage, false); + clear_log(); + } else { + memmove(APP->log_arr, APP->log_arr + LOG_REC_SIZE, log_arr_idx * LOG_REC_SIZE); + } + } + FURI_LOG_D(TAG, "Found packet #%d pipe %d", log_arr_idx, st); + notification_message(APP->notification, &sequence_blink_white_100); + found = true; + } + return found; +} + +bool nrf24_send_packet() +{ + if(log_arr_idx == 0) return false; + prepare_nrf24(!what_to_do); + uint8_t *ptr = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE; + nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, *ptr & 0x7F); + if(*ptr & 0x80) { // RAW packet + //uint8_t pktinfo = *(ptr + 1); + //nrf24_set_maclen(nrf24_HANDLE, (pktinfo & 0b11) + 2); + //if(pktinfo & 0b100) { // ESB + nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0); // No Automatic Retransmission + nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0); // No Auto acknowledgement + //} + //uint8_t alen = (*(ptr + 2) & 0b11) + 2; + uint8_t adr[2]; + adr[0] = ptr[2]; + adr[1] = ptr[3]; + nrf24_set_maclen(nrf24_HANDLE, 2); + nrf24_set_mac(REG_RX_ADDR_P0, adr, 2); + nrf24_set_mac(REG_TX_ADDR, adr, 2); + last_packet_send_st = nrf24_txpacket(nrf24_HANDLE, ptr + 2 + 2, 32 - 2, false); + } else { + nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, NRF_ESB ? 0x11 : 0); // Automatic Retransmission + nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, NRF_AA_OFF || !NRF_ESB ? 0 : 0x3F); // Auto acknowledgement + uint8_t *adr; + uint8_t a = *(ptr + 1) & 0b111; + if(a < 2) { + if(a == 0) adr = addrs.addr_P0; else adr = addrs.addr_P1; + nrf24_set_mac(REG_RX_ADDR_P0, adr, addrs.addr_len); + nrf24_set_mac(REG_TX_ADDR, adr, addrs.addr_len); + } else { + uint8_t buf[5]; + memcpy(buf, addrs.addr_P1, addrs.addr_len - 1); + buf[addrs.addr_len - 1] = a == 2 ? addrs.addr_P2 : a == 3 ? addrs.addr_P3 : a == 4 ? addrs.addr_P4 : addrs.addr_P5; + nrf24_set_mac(REG_RX_ADDR_P0, buf, addrs.addr_len); + nrf24_set_mac(REG_TX_ADDR, buf, addrs.addr_len); + } + a = *(ptr + 1) >> 3; + if(a == 0) a = 32; + nrf24_write_reg(nrf24_HANDLE, REG_CONFIG, 0x70 | ((NRF_CRC == 1 ? 0b1000 : NRF_CRC == 2 ? 0b1100 : 0))); // Mask all interrupts + nrf24_write_reg(nrf24_HANDLE, REG_DYNPD, NRF_DPL ? 0x3F : 0); // Enable dynamic payload reg + last_packet_send_st = nrf24_txpacket(nrf24_HANDLE, ptr + 2, a, false); + } + last_packet_send = view_log_arr_idx; + notification_message(APP->notification, last_packet_send_st ? &sequence_blink_blue_100 : &sequence_blink_red_100); + if(what_to_do) start_scanning(); + return last_packet_send_st; +} + +static void render_callback(Canvas* const canvas, void* ctx) { + const PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25); + if(plugin_state == NULL) return; + //canvas_draw_frame(canvas, 0, 0, 128, 64); // border around the edge of the screen + if(what_doing == 0) { + canvas_set_font(canvas, FontSecondary); // 8x10 font, 6 lines + if(save_settings) snprintf(screen_buf, sizeof(screen_buf), "Save: %s", SETTINGS_FILENAME); // menu_selected = 0 + else snprintf(screen_buf, sizeof(screen_buf), "Load: %s", addr_file_name); + canvas_draw_str(canvas, 10, 10, screen_buf); + snprintf(screen_buf, sizeof(screen_buf), "Ch: %d", NRF_channel); // menu_selected = 1 + canvas_draw_str(canvas, 10, 20, screen_buf); + if(NRF_ESB) { + strcpy(screen_buf, "ESB"); + if(NRF_DPL) strcat(screen_buf, " DPL"); + canvas_draw_str(canvas, 78, 20, screen_buf); + } + if(NRF_AA_OFF) { canvas_draw_str(canvas, 61, 20, "AA"); canvas_draw_line(canvas, 60, 21, 72, 12); } + snprintf(screen_buf, sizeof(screen_buf), "Rate: %sbps", NRF_rate == 2 ? "2M" : NRF_rate == 1 ? "1M" : "250K"); // menu_selected = 2 + canvas_draw_str(canvas, 10, 30, screen_buf); + if(what_to_do == 1) snprintf(screen_buf, sizeof(screen_buf), "Min Payl: %d", NRF_Payload_sniff_min); + else if(what_to_do >= 2) { + uint8_t *p = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE; + snprintf(screen_buf, sizeof(screen_buf), "Payload: %d", log_arr_idx && (*p & 0x80) ? *(p + 1) >> 3 : NRF_Payload); + } else snprintf(screen_buf, sizeof(screen_buf), "Payload: %d", NRF_Payload); + canvas_draw_str(canvas, 78, 30, screen_buf); + strcpy(screen_buf, "Next Ch time: "); // menu_selected = 3 + if(find_channel_period == 0) strcat(screen_buf, "off"); else snprintf(screen_buf + strlen(screen_buf), sizeof(screen_buf), "%d s", find_channel_period); + canvas_draw_str(canvas, 10, 40, screen_buf); + if(NRF_CRC == 1) canvas_draw_str(canvas, 99, 40, "CRC1"); + else if(NRF_CRC == 2) canvas_draw_str(canvas, 99, 40, "CRC2"); + snprintf(screen_buf, sizeof(screen_buf), "Log: %s", log_to_file == 0 ? "No" : log_to_file == 1 ? "Yes" : log_to_file == 2 ? "Append" : "Clear");// menu_selected = 4 + canvas_draw_str(canvas, 10, 50, screen_buf); + if(what_to_do) { // menu_selected = 5 + if(NRF_ERROR) snprintf(screen_buf, sizeof(screen_buf), "nRF24L01+ r/w ERROR!"); + else { + if(what_to_do == 1) snprintf(screen_buf, sizeof(screen_buf), "Start sniff"); + else { + uint8_t *p = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE; + if(log_arr_idx && (*p & 0x80)) { // +RAW + snprintf(screen_buf, sizeof(screen_buf), "Start read: "); + add_to_str_hex_bytes(screen_buf, (char*)p + 2, (*(p + 1) & 0b11) + 2); + if(what_to_do == 2) strcpy(screen_buf + strlen(screen_buf) - 2, "* "); + } else snprintf(screen_buf, sizeof(screen_buf), "Start scan (pipes: %d)", addrs.addr_count); + } + } + } else snprintf(screen_buf, sizeof(screen_buf), "View log (pipes: %d)", addrs.addr_count); + canvas_draw_str(canvas, 10, 60, screen_buf); + canvas_draw_str(canvas, 0, menu_selected * 10 + 10, ">"); + } else if(what_doing == 1){ + canvas_set_font(canvas, FontBatteryPercent); // 5x7 font, 9 lines + bool ch2 = false; + screen_buf[0] = '\0'; + if(view_log_arr_x == 0) { strcat(screen_buf, " "); ch2 = true; + } else { + snprintf(screen_buf, sizeof(screen_buf), "<%d", view_log_arr_x); + if(view_log_arr_x < VIEW_LOG_MAX_X) ch2 = true; + } + snprintf(screen_buf + strlen(screen_buf), sizeof(screen_buf), " %s ch: %d - %d.", what_to_do == 1 ? "Sniff" : what_to_do == 0 ? "View" : "Read", NRF_channel, log_arr_idx); + canvas_draw_str(canvas, 0, 7, screen_buf); + if(ch2) canvas_draw_str(canvas, 121, 7, ">"); + if(log_arr_idx) { + if(view_log_arr_idx >= log_arr_idx) view_log_arr_idx = log_arr_idx - 1; + uint16_t page = view_log_arr_idx & ~7; + for(uint8_t i = 0; i < 8 && page + i < log_arr_idx; i++) { + screen_buf[0] = (view_log_arr_idx & 7) != i ? ' ' : last_packet_send != view_log_arr_idx ? '>' : last_packet_send_st ? '*' : '!'; + screen_buf[1] = '\0'; + uint8_t *ptr = APP->log_arr + (page + i) * LOG_REC_SIZE; + uint8_t channel = *ptr++; + uint8_t *crcptr = NULL; + uint8_t pre = 0; + int count = 0; + if(channel & 0x80) { // RAW packet: nn:>{.address..}-xxxxxxxx + uint8_t pktinfo = *ptr++; + bool _PCF = pktinfo & 0b100; + uint8_t plen = count = (pktinfo >> 3); + uint8_t adrsize = (pktinfo & 0b11) + 2; + plen += adrsize; + count += view_log_decode_CRC; + if(view_log_arr_x > 0) count -= view_log_arr_x - 1; + uint8_t max_width = VIEW_LOG_WIDTH_B; + if(view_log_arr_x == 0) max_width -= 5; + if(count > max_width) count = max_width; + if(count > 0) { + uint8_t *pcrc = ptr; + uint32_t crc; + crc = view_log_decode_CRC == 2 ? 0xFFFF : 0xFF; + crc = calc_crc(crc, pcrc, 7, (_PCF? 9 : 0) + plen * 8); + pcrc += plen; + if(_PCF) { //ESB + pcrc++; + if(crc == get_shifted_crc(pcrc)) crcptr = pcrc; + } else { + if((view_log_decode_CRC == 1 && crc == *pcrc) || (view_log_decode_CRC == 2 && crc == (uint32_t)((*pcrc<<8) | *(pcrc+1)))) { + crcptr = pcrc; + } + } + if(view_log_arr_x == 0) { + add_to_str_hex_bytes(screen_buf, (char*)ptr, adrsize); + for(int8_t j = 5 - adrsize; j > 0; j--) strcat(screen_buf, " "); + strcat(screen_buf, "-"); + pre += 5 * 2 + 1; + } else { + ptr += view_log_arr_x - 1; + } + ptr += adrsize; + if(_PCF) add_to_str_hex_bytes_shift_9b(screen_buf, (char*)ptr++, count); else add_to_str_hex_bytes(screen_buf, (char*)ptr, count); + } + } else { + uint8_t dpl = *ptr++; + uint8_t pipe = dpl & 0b111; + dpl >>= 3; + if(dpl == 0) dpl = 32; + count = dpl - view_log_arr_x; + if(view_log_decode_PCF) count--; + uint8_t max_width = VIEW_LOG_WIDTH_B; + if(view_log_arr_x == 0) { + if(addrs.addr_count > 1) max_width--; + if(view_log_decode_PCF) max_width -= 2; + } + if(count > max_width) count = max_width; + if(count > 0) { + if(view_log_decode_CRC) { + static uint16_t prev_addr_CRC; + static int8_t prev_pipe = -1; + uint8_t *pcrc = ptr; + uint32_t crc; + if(prev_pipe == pipe) { crc = prev_addr_CRC; + } else { + crc = view_log_decode_CRC == 2 ? 0xFFFF : 0xFF; + if(pipe <= 1) { crc = calc_crc(crc, pipe == 0 ? addrs.addr_P0 : addrs.addr_P1, 7, addrs.addr_len * 8); + } else { + crc = calc_crc(crc, addrs.addr_P1, 7, (addrs.addr_len - 1) * 8); + crc = calc_crc(crc, pipe == 2 ? &addrs.addr_P2 : pipe == 3 ? &addrs.addr_P3 : pipe == 4 ? &addrs.addr_P4 : &addrs.addr_P5, 7, 8); + } + prev_addr_CRC = crc; + prev_pipe = pipe; + } + if(view_log_decode_PCF) { + crc = calc_crc(crc, pcrc++, 7, 9); + if(crc == get_shifted_crc(pcrc)) crcptr = pcrc; + if(crcptr == NULL) { + for(int8_t j = 0; j < (int8_t)dpl - view_log_decode_CRC - 1; j++) { + crc = calc_crc(crc, pcrc++, 6, 8); + if(crc == get_shifted_crc(pcrc)) { + crcptr = pcrc; + break; + } + } + } + } else { + for(int8_t j = 0; j < (int8_t)dpl - view_log_decode_CRC; j++) { + crc = calc_crc(crc, pcrc++, 7, 8); + if((view_log_decode_CRC == 1 && crc == *pcrc) || (view_log_decode_CRC == 2 && crc == (uint32_t)((*pcrc<<8) | *(pcrc+1)))) { + crcptr = pcrc; + break; + } + } + } + } + } + ptr += view_log_arr_x; + if(max_width < VIEW_LOG_WIDTH_B) { + pre += snprintf(screen_buf + 1, 10, "%X-", pipe); + if(view_log_decode_PCF) { + pre += snprintf(screen_buf + strlen(screen_buf), 10, "%02X%01X-", *ptr >> 2, ((*ptr & 3) << 1) | (*(ptr+1) >> 7)); + } + } + if(view_log_decode_PCF) add_to_str_hex_bytes_shift_9b(screen_buf, (char*)ptr++, count); else add_to_str_hex_bytes(screen_buf, (char*)ptr, count); + } + uint16_t y = 14 + i * 7; + canvas_draw_str(canvas, 3 * 5, y, screen_buf); + uint16_t x = page + i + 1; + if(x > 99) { + snprintf(screen_buf, 16, "%d", x); + canvas_draw_str(canvas, 1, y, screen_buf + 1); + canvas_draw_frame(canvas, 0, y - 2, 1, 2); + x = 2; + } else { + x = snprintf(screen_buf, 16, "%d", x); + canvas_draw_str(canvas, 0, y, screen_buf); + } + if(crcptr) { // 5x7 font, 9 lines + canvas_draw_str(canvas, x * 5, y, "="); + int n = crcptr - (uint8_t*)ptr; + if(n > -view_log_decode_CRC && n < count) { + int len; + x = (4 + pre) * 5; + if(n < 0) { + len = view_log_decode_CRC + n; + n = 0; + } else { + len = MIN(view_log_decode_CRC, count - n); + x += n * 2 * 5; + canvas_draw_line(canvas, x - 1, y, x - 1, y - 1); + } + canvas_draw_line(canvas, x - 1, y, n = x + len * 2 * 5 - 1, y); + canvas_draw_line(canvas, n, y, n, y - 1); + } + } else canvas_draw_str(canvas, x * 5, y, ":"); + } + } + } else { + canvas_set_font(canvas, FontBatteryPercent); // 5x7 font, 9 lines + if(view_found >= 0) { + snprintf(screen_buf, 50, "Found > 1: %d", found_total); + canvas_draw_str(canvas, 0, 1 * 7, screen_buf); + int16_t idx = view_found * 7; + for(uint8_t i = 0; i < 7; i++, idx++) { + if(idx >= found_total) break; + snprintf(screen_buf, 16, "%d. ", idx + 1); + add_to_str_hex_bytes(screen_buf, (char*)APP->found[idx].addr, APP->found[idx].addr_size); + if(APP->found[idx].addr_size == 3) strcat(screen_buf, " "); else if(APP->found[idx].addr_size == 4) strcat(screen_buf, " "); + snprintf(screen_buf + strlen(screen_buf), 16, " - %d", APP->found[idx].total); + canvas_draw_str(canvas, 0, (2 + i) * 7, screen_buf); + } + } else { + struct ADDRS *a; + if(what_to_do == 1) { + a = &addrs_sniff; + canvas_draw_str(canvas, 0, 1 * 7, "Sniff prefix:"); + } else { + a = &addrs; + canvas_draw_str(canvas, 0, 1 * 7, "Addresses:"); + } + if(a->addr_count > 0) { + snprintf(screen_buf, sizeof(screen_buf), "P0: "); + add_to_str_hex_bytes(screen_buf, (char*)a->addr_P0, a->addr_len); + canvas_draw_str(canvas, 0, 2 * 7, screen_buf); + } + if(a->addr_count > 1) { + snprintf(screen_buf, sizeof(screen_buf), "P1: "); + add_to_str_hex_bytes(screen_buf, (char*)a->addr_P1, a->addr_len); + canvas_draw_str(canvas, 0, 3 * 7, screen_buf); + } + if(a->addr_count > 2) { + canvas_draw_str(canvas, 0, 4 * 7, "P2: "); + snprintf(screen_buf, sizeof(screen_buf), "%02X", a->addr_P2); + canvas_draw_str(canvas, (4 + (a->addr_len - 1) * 2) * 5, 4 * 7, screen_buf); + } + if(a->addr_count > 3) { + canvas_draw_str(canvas, 0, 5 * 7, "P3: "); + snprintf(screen_buf, sizeof(screen_buf), "%02X", a->addr_P3); + canvas_draw_str(canvas, (4 + (a->addr_len - 1) * 2) * 5, 5 * 7, screen_buf); + } + if(a->addr_count > 4) { + canvas_draw_str(canvas, 0, 6 * 7, "P4: "); + snprintf(screen_buf, sizeof(screen_buf), "%02X", a->addr_P4); + canvas_draw_str(canvas, (4 + (a->addr_len - 1) * 2) * 5, 6 * 7, screen_buf); + } + if(a->addr_count > 5) { + canvas_draw_str(canvas, 0, 7 * 7, "P5: "); + snprintf(screen_buf, sizeof(screen_buf), "%02X", a->addr_P5); + canvas_draw_str(canvas, (4 + (a->addr_len - 1) * 2) * 5, 7 * 7, screen_buf); + } + } + if(log_arr_idx) { + uint8_t *ptr = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE; + uint8_t pktinfo = *(ptr + 1); + snprintf(screen_buf, 32, ">Ch: %d L: %d", *ptr & 0x7F, pktinfo >> 3); + if(*ptr & 0x80) { + strcat(screen_buf, " RAW"); + if(pktinfo & 0b100) { + snprintf(screen_buf + strlen(screen_buf), 16, " ESB %s", *(ptr + 2 + (pktinfo & 0b11) + 2) >> 2 != 0x33 ? "DPL" : ""); + } + } + canvas_draw_str(canvas, 0, 8 * 7, screen_buf); + } + screen_buf[0] = 'v'; + strcpy(screen_buf + 1, VERSION); + canvas_draw_str(canvas, 105, 7, screen_buf); + if(view_log_decode_PCF || view_log_decode_CRC) { + strcpy(screen_buf, "Decode: "); + if(view_log_decode_PCF) strcat(screen_buf, "ESB "); + if(view_log_decode_CRC == 1) strcat(screen_buf, "CRC1"); + else if(view_log_decode_CRC == 2) strcat(screen_buf, "CRC2"); + canvas_draw_str(canvas, 0, 64, screen_buf); + } + } + release_mutex((ValueMutex*)ctx, plugin_state); +} + +int32_t nrf24scan_app(void* p) { + UNUSED(p); + APP = malloc(sizeof(Nrf24Scan)); + APP->event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); + APP->plugin_state = malloc(sizeof(PluginState)); + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, APP->plugin_state, sizeof(PluginState))) { + furi_message_queue_free(APP->event_queue); + FURI_LOG_E(TAG, "cannot create mutex"); + free(APP->plugin_state); + return 255; + } + APP->log_arr = malloc(LOG_REC_SIZE * MAX_LOG_RECORDS); + if(APP->log_arr == NULL) { + FURI_LOG_E(TAG, "Not enouch memory: %d", LOG_REC_SIZE * MAX_LOG_RECORDS); + strcpy(addr_file_name, "MEMORY LOW!"); + } + clear_log(); + APP->found = malloc(sizeof(struct FOUND) * MAX_FOUND_RECORDS); + if(APP->found == NULL) { + FURI_LOG_E(TAG, "Not enouch memory: %d", sizeof(struct FOUND) * MAX_FOUND_RECORDS); + strcpy(addr_file_name, "MEMORY LOW!!"); + } + + memset((uint8_t*)&addrs, 0, sizeof(addrs)); + memset((uint8_t*)&addrs_sniff, 0, sizeof(addrs_sniff)); + nrf24_init(); + + // Set system callbacks + APP->view_port = view_port_alloc(); + view_port_draw_callback_set(APP->view_port, render_callback, &state_mutex); + view_port_input_callback_set(APP->view_port, input_callback, APP->event_queue); + + // Open GUI and register view_port + APP->gui = furi_record_open(RECORD_GUI); + gui_add_view_port(APP->gui, APP->view_port, GuiLayerFullscreen); + APP->notification = furi_record_open(RECORD_NOTIFICATION); + APP->storage = furi_record_open(RECORD_STORAGE); + storage_common_mkdir(APP->storage, SCAN_APP_PATH_FOLDER); + Stream* file_stream = file_stream_alloc(APP->storage); + FuriString* path = furi_string_alloc(); + furi_string_set(path, SCAN_APP_PATH_FOLDER); + furi_string_cat(path, "/"); + furi_string_cat(path, SNIFF_FILENAME); + if(file_stream_open(file_stream, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + uint8_t err = load_settings_file(file_stream); + if(!err) strncpy(addr_file_name, furi_string_get_cstr(path) + sizeof(SCAN_APP_PATH_FOLDER), sizeof(addr_file_name)); + else snprintf(addr_file_name, sizeof(addr_file_name), "LOAD ERROR#%d", err); + } else { + strcpy(addr_file_name, "NONE"); + if(what_to_do == 1) { + addrs.addr_P0[0] = 0; + addrs.addr_P0[1] = 0x55; + addrs.addr_len = 2; + addrs.addr_count = 1; + view_log_decode_CRC = NRF_CRC = 2; + NRF_Payload_sniff_min = 0; // Min + } + } + file_stream_close(file_stream); + stream_free(file_stream); + furi_string_free(path); + + PluginEvent event; + for(bool processing = true; processing;) { + FuriStatus event_status = furi_message_queue_get(APP->event_queue, &event, 100); + PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex); + + if(event_status == FuriStatusOk) { + // press events + if(event.type == EventTypeKey) { + //FURI_LOG_D(TAG, "Key: %d Type: %d Sec: %u", event.input.key, event.input.type, event.input.sequence); + switch(event.input.key) { + case InputKeyUp: + if(event.input.type == InputTypeShort || event.input.type == InputTypeRepeat) { + if(what_doing == 0) { + if(menu_selected > 0) menu_selected--; else menu_selected = menu_selected_max; + } else if(what_doing == 1) { + view_log_arr_idx -= event.input.type == InputTypeRepeat ? 10 : 1; + if(view_log_arr_idx >= log_arr_idx) view_log_arr_idx = 0; + } else if(what_doing == 2) { + if(view_found > -1) view_found--; + } + } + break; + case InputKeyDown: + if(event.input.type == InputTypeShort || event.input.type == InputTypeRepeat) { + if(what_doing == 0) { + if(menu_selected < menu_selected_max) menu_selected++; else menu_selected = 0; + } else if(what_doing == 1) { + view_log_arr_idx += event.input.type == InputTypeRepeat ? 10 : 1; + if(view_log_arr_idx >= log_arr_idx) view_log_arr_idx = log_arr_idx - 1; + } else if(what_doing == 2) { + if(view_found < found_total / 7) view_found++; + } + } + break; + case InputKeyLeft: + if(event.input.type == InputTypeShort || event.input.type == InputTypeRepeat) { + if(what_doing == 0) { + switch(menu_selected) { + case Menu_enter_channel: + NRF_channel -= event.input.type == InputTypeRepeat ? 10 : 1; + if(NRF_channel > MAX_CHANNEL) NRF_channel = MAX_CHANNEL; + break; + case Menu_enter_rate: + if(what_to_do == 1) { // SNIFF + NRF_Payload_sniff_min -= event.input.type == InputTypeRepeat ? 10 : 1; + correct_NRF_Payload_sniff_min(); + } else { + NRF_Payload -= event.input.type == InputTypeRepeat ? 10 : 1; + if(NRF_Payload > 32) NRF_Payload = 0; + } + break; + case Menu_enter_scan_period: + find_channel_period -= event.input.type == InputTypeRepeat ? 10 : 1; + if(find_channel_period < 0) find_channel_period = 0; + break; + case Menu_log: + if(--log_to_file < -1) log_to_file = 2; + break; + case Menu_ok: + if(--what_to_do > 3) what_to_do = 3; + break; + } + } else if(what_doing == 1) { + if(view_log_arr_x > 0) view_log_arr_x--; + } else if(what_doing == 2) { + //if(NRF_ESB == 0) + view_log_decode_PCF ^= 1; + } + } + break; + case InputKeyRight: + if(event.input.type == InputTypeShort || event.input.type == InputTypeRepeat) { + if(what_doing == 0) { + switch(menu_selected) { + case Menu_open_file: + save_settings ^= 1; + break; + case Menu_enter_channel: + NRF_channel += event.input.type == InputTypeRepeat ? 10 : 1; + if(NRF_channel > MAX_CHANNEL) NRF_channel = 0; + break; + case Menu_enter_rate: + if(what_to_do == 1) { // SNIFF + NRF_Payload_sniff_min += event.input.type == InputTypeRepeat ? 10 : 1; + correct_NRF_Payload_sniff_min(); + } else { + NRF_Payload += event.input.type == InputTypeRepeat ? 10 : 1; + if(NRF_Payload > 32) NRF_Payload = 32; + } + break; + case Menu_enter_scan_period: + find_channel_period += event.input.type == InputTypeRepeat ? 10 : 1; + break; + case Menu_log: + if(++log_to_file > 2) log_to_file = -1; + break; + case Menu_ok: + if(++what_to_do > 3) what_to_do = 0; + break; + } + } else if(what_doing == 1) { + if(view_log_arr_x < VIEW_LOG_MAX_X) view_log_arr_x++; + } else if(what_doing == 2) { + if(++view_log_decode_CRC > 2) view_log_decode_CRC = 0; + } + } + break; + case InputKeyOk: + if(event.input.type == InputTypeShort) { + if(what_doing == 0) { + switch(menu_selected) { + case Menu_open_file: + if(save_settings) { + write_to_log_file(APP->storage, true); + } else { + file_stream = file_stream_alloc(APP->storage); + if(select_settings_file(file_stream)) { + uint8_t err = load_settings_file(file_stream); + if(!err) save_to_new_log = true; else snprintf(addr_file_name, sizeof(addr_file_name), "LOAD ERROR#%d", err); + file_stream_close(file_stream); + menu_selected = Menu_ok; + } + stream_free(file_stream); + } + break; + case Menu_enter_channel: + if(what_to_do == 1) { + if(NRF_ESB) NRF_DPL = NRF_ESB = 0; else NRF_ESB = 1; + } else { + if(NRF_ESB) { + if(NRF_DPL) NRF_DPL = NRF_ESB = 0; else NRF_DPL = 1; + } else NRF_ESB = 1; + } + break; + case Menu_enter_rate: + NRF_rate++; + if(NRF_rate > 2) NRF_rate = 0; + break; + case Menu_enter_scan_period: + if(++NRF_CRC > 2) NRF_CRC = what_to_do == 1 ? 1 : 0; + break; + case Menu_ok: + if(what_to_do) { + if((addrs.addr_count || (what_to_do >= 2 && log_arr_idx && *(APP->log_arr + view_log_arr_idx * LOG_REC_SIZE) & 0x80)) || what_to_do == 1) { + if(log_to_file == -1) { + log_to_file = 0; + clear_log(); + save_to_new_log = true; + } else if(log_to_file == 1) save_to_new_log = true; + start_scanning(); + if(!NRF_ERROR) what_doing = 1; + } + } else what_doing = 1; + break; + } + } else if(what_doing == 1) { + what_doing = 2; + } else if(what_doing == 2) { + what_doing = 1; + } + } else if(event.input.type == InputTypeLong) { + if(what_doing == 0) { + if(menu_selected == Menu_enter_channel) { + NRF_AA_OFF ^= 1; + } else if(menu_selected == Menu_log) { // Log + if(log_arr_idx && (log_to_file == 1 || log_to_file == 2)) { + write_to_log_file(APP->storage, false); + clear_log(); + } + } + } else if(what_doing == 1 || what_doing == 2) { + nrf24_send_packet(); + } + } + break; + case InputKeyBack: + if(event.input.type == InputTypeLong) processing = false; + else if(event.input.type == InputTypeShort) { + if(what_doing) what_doing--; + if(what_doing == 0) { + nrf24_set_idle(nrf24_HANDLE); + } + } + break; + default: + break; + } + } + } + if(what_doing && what_to_do) { + nrf24_read_newpacket(); + if(find_channel_period && furi_get_tick() - start_time >= (uint32_t)find_channel_period * 1000UL) { + if(++NRF_channel > MAX_CHANNEL) NRF_channel = 0; + start_scanning(); + } + } + + view_port_update(APP->view_port); + release_mutex(&state_mutex, plugin_state); + } + nrf24_set_idle(nrf24_HANDLE); + if(log_arr_idx && (log_to_file == 1 || log_to_file == 2)) { + write_to_log_file(APP->storage, false); + } + nrf24_deinit(); + + view_port_enabled_set(APP->view_port, false); + gui_remove_view_port(APP->gui, APP->view_port); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_STORAGE); + view_port_free(APP->view_port); + furi_message_queue_free(APP->event_queue); + free(APP->plugin_state); + if(APP->log_arr) free(APP->log_arr); + if(APP->found) free(APP->found); + free(APP); + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/nrf24scan.h b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/nrf24scan.h new file mode 100644 index 000000000..0fa7cbc63 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/nrf24scan.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +typedef enum { + EventTypeTick, + EventTypeKey, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} PluginEvent; + +typedef struct { + int x; + int y; +} PluginState; + +struct FOUND { + uint8_t addr_size; + uint8_t addr[5]; + uint16_t total; +}; + +typedef struct { + Gui* gui; + FuriMessageQueue* event_queue; + PluginState* plugin_state; + ViewPort* view_port; + Storage* storage; + NotificationApp* notification; + uint8_t* log_arr; + struct FOUND *found; +} Nrf24Scan; + diff --git a/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/nrf24scan_10px.png b/Applications/Official/DEV_FW/source/xMasterX/nrf24scan/nrf24scan_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..348b35eca7599d1c72a7b1efea9fd7f263e4606f GIT binary patch literal 1771 zcmcIlO>f*p7x-sRO- zS0zchJlO8D=?T@&96%@6B`l63J-Ivmxb=!1apOvRMP zOl`6P(2{h0y(uu+XSE!&ahiw9U%&jS$SDn#+fJlM#U`7i+s7rlb-Xhq$NR*m%K8oY zdJ_Oa#%e4#*)*?$CRFCU0gT0CO_Ar2dOuV)L_v8J?aG_HWU{B4i0Ha5d%kMKu7f@Q z9of`PQ`23|u#n*ewi_6>+%ZF;gS$|f)O8VP+H5vcXO_y#v1a(buj!^{ zng|f6I?8L@puAe^82YRtWm?oJ&t<`gV}4MF3P@e7AuE=&dDZ#^j%f`pG(*+JnmS+< zoej;hCAzA&4xvh`_p!v)@Tg$g9;^64N!ZpQ%j>nSSTW%>uO|En+LnL+MyFy@;}*Nuj;5(R4_$zX z$a<&{(PT!I_Hp_c_s*wtK|7l;AU&h`3s}XIdWK83F$Slf8ZPZg;wyZ3w)FEg{uxSd zZ6y<&j~VQonj#jXi7jT)6z%{0df4wSGaHa*(aoy0;U*q04Y|>U31f>wFfsDno`rl9 z!qiLj7!jJ7)btGECGMi`H0=~Dh_tgS&b2!ap z0w+mt(BBwd`-Gwau&+ngqv~uO^Yk#kNGO$cD{`nQ-o0Att`WFvA{_gdY i=ihk$!R+PXOVW$?Uc1=*arGZ@91XU1`aj;h``Nz$VJy}F literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/ocarina/README.md b/Applications/Official/DEV_FW/source/xMasterX/ocarina/README.md new file mode 100644 index 000000000..1fcfd00fa --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ocarina/README.md @@ -0,0 +1,4 @@ +# flipperzero-ocarina +A basic Ocarina (of Time) for the Flipper Zero. + +Controls are the same as the N64 version of the Ocarina of Time, the Ok button takes the place of the A button diff --git a/Applications/Official/DEV_FW/source/xMasterX/ocarina/application.fam b/Applications/Official/DEV_FW/source/xMasterX/ocarina/application.fam new file mode 100644 index 000000000..16a786701 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ocarina/application.fam @@ -0,0 +1,13 @@ +App( + appid="Ocarina", + name="Ocarina", + apptype=FlipperAppType.EXTERNAL, + entry_point="ocarina_app", + cdefines=["APP_OCARINA"], + requires=["gui"], + stack_size=1 * 1024, + order=30, + fap_icon="icons/music_10px.png", + fap_category="Music_Extra", + fap_icon_assets="icons", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/ocarina/icons/music_10px.png b/Applications/Official/DEV_FW/source/xMasterX/ocarina/icons/music_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..d41eb0db8c822c60be6c097393b3682680b81a6c GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xGmzZ=C-xtZVhivIasA%~WHIdey2}7aaTa() z7Bet#3xhBt!>l_x9Asc&(0a_=e)W&n8K5!-Pgg&ebxsLQ0Ao%f>i_@% literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/ocarina/music_10px.png b/Applications/Official/DEV_FW/source/xMasterX/ocarina/music_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..d41eb0db8c822c60be6c097393b3682680b81a6c GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xGmzZ=C-xtZVhivIasA%~WHIdey2}7aaTa() z7Bet#3xhBt!>l_x9Asc&(0a_=e)W&n8K5!-Pgg&ebxsLQ0Ao%f>i_@% literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/ocarina/ocarina.c b/Applications/Official/DEV_FW/source/xMasterX/ocarina/ocarina.c new file mode 100644 index 000000000..7fdfce74c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/ocarina/ocarina.c @@ -0,0 +1,134 @@ +#include +#include +#include +#include +#include + +#define NOTE_UP 587.33f +#define NOTE_LEFT 493.88f +#define NOTE_RIGHT 440.00f +#define NOTE_DOWN 349.23 +#define NOTE_OK 293.66f + +typedef struct { + FuriMutex* model_mutex; + + FuriMessageQueue* event_queue; + + ViewPort* view_port; + Gui* gui; +} Ocarina; + +void draw_callback(Canvas* canvas, void* ctx) { + Ocarina* ocarina = ctx; + furi_check(furi_mutex_acquire(ocarina->model_mutex, FuriWaitForever) == FuriStatusOk); + + //canvas_draw_box(canvas, ocarina->model->x, ocarina->model->y, 4, 4); + canvas_draw_frame(canvas, 0, 0, 128, 64); + canvas_draw_str(canvas, 50, 10, "Ocarina"); + canvas_draw_str(canvas, 30, 20, "OK button for A"); + + furi_mutex_release(ocarina->model_mutex); +} + +void input_callback(InputEvent* input, void* ctx) { + Ocarina* ocarina = ctx; + // Puts input onto event queue with priority 0, and waits until completion. + furi_message_queue_put(ocarina->event_queue, input, FuriWaitForever); +} + +Ocarina* ocarina_alloc() { + Ocarina* instance = malloc(sizeof(Ocarina)); + + instance->model_mutex = furi_mutex_alloc(FuriMutexTypeNormal); + + instance->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + instance->view_port = view_port_alloc(); + view_port_draw_callback_set(instance->view_port, draw_callback, instance); + view_port_input_callback_set(instance->view_port, input_callback, instance); + + instance->gui = furi_record_open("gui"); + gui_add_view_port(instance->gui, instance->view_port, GuiLayerFullscreen); + + return instance; +} + +void ocarina_free(Ocarina* instance) { + view_port_enabled_set(instance->view_port, false); // Disabsles our ViewPort + gui_remove_view_port(instance->gui, instance->view_port); // Removes our ViewPort from the Gui + furi_record_close("gui"); // Closes the gui record + view_port_free(instance->view_port); // Frees memory allocated by view_port_alloc + furi_message_queue_free(instance->event_queue); + + furi_mutex_free(instance->model_mutex); + + if(furi_hal_speaker_is_mine()) { + furi_hal_speaker_stop(); + furi_hal_speaker_release(); + } + + free(instance); +} + +int32_t ocarina_app(void* p) { + UNUSED(p); + + Ocarina* ocarina = ocarina_alloc(); + + InputEvent event; + for(bool processing = true; processing;) { + // Pops a message off the queue and stores it in `event`. + // No message priority denoted by NULL, and 100 ticks of timeout. + FuriStatus status = furi_message_queue_get(ocarina->event_queue, &event, 100); + furi_check(furi_mutex_acquire(ocarina->model_mutex, FuriWaitForever) == FuriStatusOk); + + float volume = 1.0f; + if(status == FuriStatusOk) { + if(event.type == InputTypePress) { + switch(event.key) { + case InputKeyUp: + if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { + furi_hal_speaker_start(NOTE_UP, volume); + } + break; + case InputKeyDown: + if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { + furi_hal_speaker_start(NOTE_DOWN, volume); + } + break; + case InputKeyLeft: + if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { + furi_hal_speaker_start(NOTE_LEFT, volume); + } + break; + case InputKeyRight: + if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { + furi_hal_speaker_start(NOTE_RIGHT, volume); + } + break; + case InputKeyOk: + if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { + furi_hal_speaker_start(NOTE_OK, volume); + } + break; + case InputKeyBack: + processing = false; + break; + default: + break; + } + } else if(event.type == InputTypeRelease) { + if(furi_hal_speaker_is_mine()) { + furi_hal_speaker_stop(); + furi_hal_speaker_release(); + } + } + } + + furi_mutex_release(ocarina->model_mutex); + view_port_update(ocarina->view_port); // signals our draw callback + } + ocarina_free(ocarina); + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/paint/application.fam b/Applications/Official/DEV_FW/source/xMasterX/paint/application.fam new file mode 100644 index 000000000..ad7f322b0 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/paint/application.fam @@ -0,0 +1,12 @@ +App( + appid="Paint", + name="Paint", + apptype=FlipperAppType.EXTERNAL, + entry_point="paint_app", + cdefines=["APP_PAINT"], + requires=["gui"], + stack_size=2 * 1024, + order=175, + fap_icon="paintIcon.png", + fap_category="Misc_Extra", +) \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/paint/paint.c b/Applications/Official/DEV_FW/source/xMasterX/paint/paint.c new file mode 100644 index 000000000..5cfe85155 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/paint/paint.c @@ -0,0 +1,148 @@ +#include +#include +#include +#include +#include +#include +#include // Header-file for boolean data-type. + +typedef struct selected_position { + int x; + int y; +} selected_position; + +typedef struct { + selected_position selected; + bool board[32][16]; + bool isDrawing; +} PaintData; + +void paint_draw_callback(Canvas* canvas, void* ctx) { + const PaintData* paint_state = acquire_mutex((ValueMutex*)ctx, 25); + UNUSED(ctx); + canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + //draw the canvas(32x16) on screen(144x64) using 4x4 tiles + for(int y = 0; y < 16; y++) { + for(int x = 0; x < 32; x++) { + if(paint_state->board[x][y]) { + canvas_draw_box(canvas, x * 4, y * 4, 4, 4); + } + } + } + + //draw cursor as a 4x4 black box with a 2x2 white box inside + canvas_set_color(canvas, ColorBlack); + canvas_draw_box(canvas, paint_state->selected.x * 4, paint_state->selected.y * 4, 4, 4); + canvas_set_color(canvas, ColorWhite); + canvas_draw_box( + canvas, paint_state->selected.x * 4 + 1, paint_state->selected.y * 4 + 1, 2, 2); + + //release the mutex + release_mutex((ValueMutex*)ctx, paint_state); +} + +void paint_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + furi_message_queue_put(event_queue, input_event, FuriWaitForever); +} + +int32_t paint_app(void* p) { + UNUSED(p); + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + PaintData* paint_state = malloc(sizeof(PaintData)); + ValueMutex paint_state_mutex; + if(!init_mutex(&paint_state_mutex, paint_state, sizeof(PaintData))) { + FURI_LOG_E("paint", "cannot create mutex\r\n"); + free(paint_state); + return -1; + } + + // Configure view port + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, paint_draw_callback, &paint_state_mutex); + view_port_input_callback_set(view_port, paint_input_callback, event_queue); + + // Register view port in GUI + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + //NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + + InputEvent event; + + while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) { + //break out of the loop if the back key is pressed + if(event.type == InputTypeShort && event.key == InputKeyBack) { + break; + } + + //check the key pressed and change x and y accordingly + if(event.type == InputTypeShort) { + switch(event.key) { + case InputKeyUp: + paint_state->selected.y -= 1; + break; + case InputKeyDown: + paint_state->selected.y += 1; + break; + case InputKeyLeft: + paint_state->selected.x -= 1; + break; + case InputKeyRight: + paint_state->selected.x += 1; + break; + case InputKeyOk: + paint_state->board[paint_state->selected.x][paint_state->selected.y] = + !paint_state->board[paint_state->selected.x][paint_state->selected.y]; + break; + + default: + break; + } + + //check if cursor position is out of bounds and reset it to the closest position + if(paint_state->selected.x < 0) { + paint_state->selected.x = 0; + } + if(paint_state->selected.x > 31) { + paint_state->selected.x = 31; + } + if(paint_state->selected.y < 0) { + paint_state->selected.y = 0; + } + if(paint_state->selected.y > 15) { + paint_state->selected.y = 15; + } + if(paint_state->isDrawing == true) { + paint_state->board[paint_state->selected.x][paint_state->selected.y] = true; + } + view_port_update(view_port); + } + if(event.key == InputKeyBack && event.type == InputTypeLong) { + paint_state->board[1][1] = true; + for(int y = 0; y < 16; y++) { + for(int x = 0; x < 32; x++) { + paint_state->board[x][y] = false; + } + } + view_port_update(view_port); + } + if(event.key == InputKeyOk && event.type == InputTypeLong) { + paint_state->isDrawing = !paint_state->isDrawing; + paint_state->board[paint_state->selected.x][paint_state->selected.y] = true; + view_port_update(view_port); + } + } + + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + furi_message_queue_free(event_queue); + free(paint_state); + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_GUI); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/paint/paintIcon.png b/Applications/Official/DEV_FW/source/xMasterX/paint/paintIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..cc0a8b7d8077a58e373a30f38a1ece7caffc8150 GIT binary patch literal 1911 zcmcIlO>g5w81`ye1V!Zl5-RKpEbnFcnAjf2pGvk$o3e>im(UGrxiOv@Cst#RvE3%^ z0iorDRB3+*(h9C{00DfEJbdYIas$@S_jda` z7Z(>W{piQvK7--KwDWN;Nj16rUiPXVYt%n14*gw^invCY2zYH0r+}8E#^xj? z^oSR7zz0#%RGxhIy&^}fsT`QT=BL|y7uZgP2MjSUh&+i$ zN$yRW%9PlHdAY4B@)S}WHI-IrQ9ks0^0vshY}YWNnx@INThjx}B)0pWj5Ul^%~Ev( z>9$w5JiRW@J_^{ANi%pRPgTd`acykWL^e=$*L775s~96dp!_r` z$OI+%?TTbZ)8;wNqO^!aBA2uz5XVJR0hg;-;&j2CeLBIRlTN_vCVF6Y z7wEj$IRPs(r!OVW`==>a_jxXkGs<^Pcv9S+8%u|x5cyF2hi{9&|K%a03xnx#Hk#&$ zQI(H)4BRLJZV zy4lw)PcuCOzpELZrd3cM1i?r_Rs#zbg{P}Pec$UQc|j7&yX~d|PSv7_d0J36aor)v zF@rjC+&V+9sTqhEdT8q=vuT}9{etstL66H!l;N~m94dG^ZI`NdrcHC7f4a0a zYk^TDPxa^#TDCz`p=JF!Q)b)IC5c@vgo<`NEr(lqvEDRk_wOQ#-UO&qmP_QMI*9-cXtxq2O1AHwv!2kdN literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/LICENSE new file mode 100644 index 000000000..0e259d42c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/LICENSE @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/README.md b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/README.md new file mode 100644 index 000000000..e8e7491f5 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/README.md @@ -0,0 +1,34 @@ +# flipperzero_pomodoro + +The Pomodoro Technique is a time management method developed by Francesco Cirillo in the late 1980s.[1] It uses a kitchen timer to break work into intervals, typically 25 minutes in length, separated by short breaks. Each interval is known as a pomodoro, from the Italian word for tomato, after the tomato-shaped kitchen timer Cirillo used as a university student. + +Flipper Zero is a portable Tamagotchi-like multi-functional device developed for interaction with access control systems. The device is able to read, copy, and emulate radio-frequency (RFID) tags, radio remotes, and digital access keys. + +## Pomodoro timer application for Flipper Zero + +Three timers available: + +- classic 25 min work, 5 min rest +- long 50 min work, 10 min rest +- sprint 10 min work, 2 min rest + +With tomato counter + +Plays sound alerts + +Has built-in clocks + +Screenshots: + +![](./misc/1.png) + +![](./misc/2.png) + +![](./misc/3.png) + +![](./misc/4.png) + +![](./misc/5.png) + + +Compatible with firmware v. F81999EA from 14 Oct. 2022 diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/application.fam b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/application.fam new file mode 100644 index 000000000..7a507a4fd --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/application.fam @@ -0,0 +1,15 @@ +App( + appid="Pomodoro_Timer", + name="Pomodoro Timer", + apptype=FlipperAppType.EXTERNAL, + entry_point="pomodoro_app", + stack_size=1 * 1024, + cdefines=["APP_POMODORO"], + requires=[ + "gui", + ], + order=10, + fap_icon="pomodoro_timer.png", + fap_category="Misc_Extra", + fap_icon_assets="icons", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/icons/ButtonLeft_4x7.png b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/icons/ButtonLeft_4x7.png new file mode 100644 index 0000000000000000000000000000000000000000..0b4655d43247083aa705620e9836ac415b42ca46 GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/icons/Ok_btn_9x9.png b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/icons/Ok_btn_9x9.png new file mode 100644 index 0000000000000000000000000000000000000000..9a1539da2049f12f7b25f96b11a9c40cd8227302 GIT binary patch literal 3605 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 TFC+3}9cE|kU{!4CefEC<&8td2 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/icons/Space_65x18.png b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/icons/Space_65x18.png new file mode 100644 index 0000000000000000000000000000000000000000..b60ae50970b8be827ae32ddbd9e1b0d28c8b3a9a GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/misc/1.png b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/misc/1.png new file mode 100644 index 0000000000000000000000000000000000000000..e8543a2551e298c5885ed3305a4e5baf48a75ec7 GIT binary patch literal 12663 zcmY*=Wmp_t6XoFU?(Xgcf)6lAa00XqotvYgGq@A003}QKtLS;01*ZNASj_Dyz@E&Zvik@fWcj2834c^t^$6H#7=C4}WE`#K4brp;{LYY1V90Vcbx*aQd*8TwC9?1TV#$_RFk3aPK`mLNnO7hV zkuDOI9H=jH!TU0#3$nm0(RPuUzCW<7HHDcc5!g2J@)-pQ$zV;Tas|0~1iib_e+pMK zprIi>9n11;(9ncm<%FTDqg8Q>$jBw2E(s$nj<9-mMa|w$OIr1A zkc#Rm|52l^hlI<(ETt@E2r<*K#Xa;X!Z=ERNv2O=7Z>f~97~}LiagtNNR4w#o+R;T z=5+dMl2);7)7o!*va~fDqw^xIacLIFzbW6mKO)NpPUvJpLpHhiSa@U`LHasRmgd`~ zVr@A}`AEE@UBhPIXfHOpoJqrfswS;Xu8jF_Ru?rfxU12C`Hams)D>p1m@k);q+}CO zMHf?VusMYFlQ!9$O}%F@7Nqqh;hxAbfotl<9CEpwG=5c4CKf^oDC5?gV}Y{HmVL%t zIIT`?e$olILOWe0uI*CykxyL|%$Q3FPtiZio_GgMY2}-9%Rc>GYr^*cm925IllsXf zSHdO92Mi-M((Yz&`sum~c!S)u_#)GA6BqGquh2ejSryRth_6H#wcsg$Bo*{lK2sx{ zr&e$oPUlQY1urh(w-YOztaNE{!O>G!3G_#F0X>fFhC=>9*TMYw?a2EwHE$}wFEKyy zw6)m~l5ayrKn^sB9=boZuxkR;bU5HR?lOuZN=n5al$#^%rqQqI8#5H_&C=vss%Xo{ z@iT6v=y#T=CN`0{6iixJlOZ!`@F?dAsXx6RZbW9V%I63&>O)k_n{5Q&%Pw^Zl|!&z zdS%+wPCqUyI1s_QHZ(NX+k261=#+Jb5}4 zAzeLr>cYL*zWcZpjM1yU=52rmj$mx+SQUT43#w}>?Op>6!p$oX9* zf>{nuuYJ1JLV&6@I)p{!B^`m~`*(TOPuCRN!g>F#Xo-bDd#JLO!{EeokQ zNThtQZ>X<+oR?{gY~dq<**lT-{^)3vJ?0LeFrwqa2*#Va3*EoqiLdWm3{Ec%y7o<7 zgiPDB;&qyR@wRucIEX^K)8#2G1H_@L69aP}k?T1W={y((DaTblkpqR5%?)l?gQuf^ zee7t^_ zf?Is<5k8|3bn#_|c4{c#uhX>1BENdoiGlrtEA2LpwD~P8^i&~i37;iLuZ~IKWGr

% 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/misc/2.png b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/misc/2.png new file mode 100644 index 0000000000000000000000000000000000000000..8b5f28476af84e6e11e7073715fd6b09b314dba6 GIT binary patch literal 12446 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 Tf1U8U;Q*lePD`;t-ZK1uGHKUp literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/misc/3.png b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/misc/3.png new file mode 100644 index 0000000000000000000000000000000000000000..32473be3cd88be74aa4910ddc84ede0274cc3117 GIT binary patch literal 12478 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/misc/4.png b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/misc/4.png new file mode 100644 index 0000000000000000000000000000000000000000..0b48b9fdc378d90cbb4c0889b71d656e49e72de2 GIT binary patch literal 12896 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 EKUuH0B>(^b literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/misc/5.png b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/misc/5.png new file mode 100644 index 0000000000000000000000000000000000000000..1a53bc074cd8d2a89bdd9b4bf7f171fab90c78a2 GIT binary patch literal 12592 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 O0-&LytNb!afBQe@_6_L( literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro.c b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro.c new file mode 100644 index 000000000..5b1db1984 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro.c @@ -0,0 +1,164 @@ +#include "pomodoro.h" +#include + +#define TAG "PomodoroApp" + +enum PomodoroDebugSubmenuIndex { + PomodoroSubmenuIndex10, + PomodoroSubmenuIndex25, + PomodoroSubmenuIndex50, +}; + +void pomodoro_submenu_callback(void* context, uint32_t index) { + furi_assert(context); + Pomodoro* app = context; + if(index == PomodoroSubmenuIndex10) { + app->view_id = PomodoroView10; + view_dispatcher_switch_to_view(app->view_dispatcher, PomodoroView10); + } + if(index == PomodoroSubmenuIndex25) { + app->view_id = PomodoroView25; + view_dispatcher_switch_to_view(app->view_dispatcher, PomodoroView25); + } + if(index == PomodoroSubmenuIndex50) { + app->view_id = PomodoroView50; + view_dispatcher_switch_to_view(app->view_dispatcher, PomodoroView50); + } +} + +void pomodoro_dialog_callback(DialogExResult result, void* context) { + furi_assert(context); + Pomodoro* 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, PomodoroViewSubmenu); + } +} + +uint32_t pomodoro_exit_confirm_view(void* context) { + UNUSED(context); + return PomodoroViewExitConfirm; +} + +uint32_t pomodoro_exit(void* context) { + UNUSED(context); + return VIEW_NONE; +} + +Pomodoro* pomodoro_app_alloc() { + Pomodoro* app = malloc(sizeof(Pomodoro)); + + // Gui + app->gui = furi_record_open(RECORD_GUI); + + // 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); + + // Submenu view + app->submenu = submenu_alloc(); + submenu_add_item( + app->submenu, + "Classic: 25 work 5 rest", + PomodoroSubmenuIndex25, + pomodoro_submenu_callback, + app); + submenu_add_item( + app->submenu, + "Long: 50 work 10 rest", + PomodoroSubmenuIndex50, + pomodoro_submenu_callback, + app); + submenu_add_item( + app->submenu, + "Sprint: 10 work 2 rest", + PomodoroSubmenuIndex10, + pomodoro_submenu_callback, + app); + view_set_previous_callback(submenu_get_view(app->submenu), pomodoro_exit); + view_dispatcher_add_view( + app->view_dispatcher, PomodoroViewSubmenu, submenu_get_view(app->submenu)); + + // Dialog view + app->dialog = dialog_ex_alloc(); + dialog_ex_set_result_callback(app->dialog, pomodoro_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, PomodoroViewExitConfirm, dialog_ex_get_view(app->dialog)); + + // 25 minutes view + app->pomodoro_25 = pomodoro_25_alloc(); + view_set_previous_callback(pomodoro_25_get_view(app->pomodoro_25), pomodoro_exit_confirm_view); + view_dispatcher_add_view( + app->view_dispatcher, PomodoroView25, pomodoro_25_get_view(app->pomodoro_25)); + + // 50 minutes view + app->pomodoro_50 = pomodoro_50_alloc(); + view_set_previous_callback(pomodoro_50_get_view(app->pomodoro_50), pomodoro_exit_confirm_view); + view_dispatcher_add_view( + app->view_dispatcher, PomodoroView50, pomodoro_50_get_view(app->pomodoro_50)); + + // 10 minutes view + app->pomodoro_10 = pomodoro_10_alloc(); + view_set_previous_callback(pomodoro_10_get_view(app->pomodoro_10), pomodoro_exit_confirm_view); + view_dispatcher_add_view( + app->view_dispatcher, PomodoroView10, pomodoro_10_get_view(app->pomodoro_10)); + + // TODO switch to menu after Media is done + app->view_id = PomodoroViewSubmenu; + view_dispatcher_switch_to_view(app->view_dispatcher, app->view_id); + + return app; +} + +void pomodoro_app_free(Pomodoro* app) { + furi_assert(app); + + // Reset notification + notification_internal_message(app->notifications, &sequence_reset_blue); + + // Free views + view_dispatcher_remove_view(app->view_dispatcher, PomodoroViewSubmenu); + submenu_free(app->submenu); + view_dispatcher_remove_view(app->view_dispatcher, PomodoroViewExitConfirm); + dialog_ex_free(app->dialog); + view_dispatcher_remove_view(app->view_dispatcher, PomodoroView25); + pomodoro_25_free(app->pomodoro_25); + view_dispatcher_remove_view(app->view_dispatcher, PomodoroView50); + pomodoro_50_free(app->pomodoro_50); + view_dispatcher_remove_view(app->view_dispatcher, PomodoroView10); + pomodoro_10_free(app->pomodoro_10); + view_dispatcher_free(app->view_dispatcher); + + // Close records + furi_record_close(RECORD_GUI); + app->gui = NULL; + furi_record_close(RECORD_NOTIFICATION); + app->notifications = NULL; + + // Free rest + free(app); +} + +int32_t pomodoro_app(void* p) { + UNUSED(p); + // Switch profile to Hid + Pomodoro* app = pomodoro_app_alloc(); + + view_dispatcher_run(app->view_dispatcher); + + pomodoro_app_free(app); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro.h b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro.h new file mode 100644 index 000000000..53dedb8e3 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include "pomodoro_timer.h" +#include "views/pomodoro_10.h" +#include "views/pomodoro_25.h" +#include "views/pomodoro_50.h" + +typedef struct { + Gui* gui; + NotificationApp* notifications; + ViewDispatcher* view_dispatcher; + Submenu* submenu; + DialogEx* dialog; + PomodoroTimer* pomodoro_10; + PomodoroTimer* pomodoro_25; + PomodoroTimer* pomodoro_50; + uint32_t view_id; +} Pomodoro; + +typedef enum { + PomodoroViewSubmenu, + PomodoroView10, + PomodoroView25, + PomodoroView50, + PomodoroViewExitConfirm, +} PomodoroView; diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro_timer.c b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro_timer.c new file mode 100644 index 000000000..0fba5db42 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro_timer.c @@ -0,0 +1,242 @@ +#include "pomodoro_timer.h" +#include +#include +#include +#include +#include + +const NotificationSequence sequence_finish = { + &message_display_backlight_on, + &message_green_255, + &message_vibro_on, + &message_note_c5, + &message_delay_100, + &message_vibro_off, + &message_vibro_on, + &message_note_e5, + &message_delay_100, + &message_vibro_off, + &message_vibro_on, + &message_note_g5, + &message_delay_100, + &message_vibro_off, + &message_vibro_on, + &message_note_b5, + &message_delay_250, + &message_vibro_off, + &message_vibro_on, + &message_note_c6, + &message_delay_250, + &message_vibro_off, + &message_sound_off, + NULL, +}; + +const NotificationSequence sequence_rest = { + &message_display_backlight_on, + &message_red_255, + &message_vibro_on, + &message_note_c6, + &message_delay_100, + &message_vibro_off, + &message_vibro_on, + &message_note_b5, + &message_delay_100, + &message_vibro_off, + &message_vibro_on, + &message_note_g5, + &message_delay_100, + &message_vibro_off, + &message_vibro_on, + &message_note_e5, + &message_delay_100, + &message_vibro_off, + &message_vibro_on, + &message_note_c5, + &message_delay_250, + &message_vibro_off, + &message_sound_off, + NULL, +}; + +void pomodoro_timer_process(PomodoroTimer* pomodoro_timer, InputEvent* event) { + with_view_model( + pomodoro_timer->view, + PomodoroTimerModel * model, + { + if(event->type == InputTypePress) { + if(event->key == InputKeyOk) { + model->ok_pressed = true; + } else if(event->key == InputKeyLeft) { + model->reset_pressed = true; + } else if(event->key == InputKeyBack) { + model->back_pressed = true; + } + } else if(event->type == InputTypeRelease) { + if(event->key == InputKeyOk) { + model->ok_pressed = false; + + // START/STOP TIMER + FuriHalRtcDateTime curr_dt; + furi_hal_rtc_get_datetime(&curr_dt); + uint32_t current_timestamp = furi_hal_rtc_datetime_to_timestamp(&curr_dt); + + // STARTED -> PAUSED + if(model->timer_running) { + // Update stopped seconds + model->timer_stopped_seconds = + current_timestamp - model->timer_start_timestamp; + } else if(!model->time_passed) { + // INITIAL -> STARTED + model->timer_start_timestamp = current_timestamp; + model->rest_running = false; + } else { + // PAUSED -> STARTED + model->timer_start_timestamp = + current_timestamp - model->timer_stopped_seconds; + } + model->timer_running = !model->timer_running; + } else if(event->key == InputKeyLeft) { + if(!model->timer_running) { + furi_record_close(RECORD_NOTIFICATION); + model->timer_stopped_seconds = 0; + model->timer_start_timestamp = 0; + model->time_passed = 0; + model->timer_running = false; + } + model->reset_pressed = false; + } else if(event->key == InputKeyBack) { + model->back_pressed = false; + } + } + }, + true); +} + +void pomodoro_draw_callback(Canvas* canvas, void* context, int max_seconds, int max_seconds_rest) { + furi_assert(context); + PomodoroTimerModel* model = context; + FuriHalRtcDateTime curr_dt; + furi_hal_rtc_get_datetime(&curr_dt); + uint32_t current_timestamp = furi_hal_rtc_datetime_to_timestamp(&curr_dt); + + // Header + canvas_set_font(canvas, FontPrimary); + elements_multiline_text_aligned(canvas, 0, 0, AlignLeft, AlignTop, "Pomodoro"); + + canvas_draw_icon(canvas, 68, 1, &I_Pin_back_arrow_10x8); + canvas_set_font(canvas, FontSecondary); + elements_multiline_text_aligned(canvas, 127, 1, AlignRight, AlignTop, "Hold to exit"); + + // Start/Pause/Continue + int txt_main_y = 34; + canvas_draw_icon(canvas, 63, 23, &I_Space_65x18); // button + if(model->ok_pressed) { + elements_slightly_rounded_box(canvas, 66, 25, 60, 13); + canvas_set_color(canvas, ColorWhite); + } + if(model->timer_running) { + model->time_passed = current_timestamp - model->timer_start_timestamp; + elements_multiline_text_aligned(canvas, 83, txt_main_y, AlignLeft, AlignBottom, "Pause"); + canvas_draw_box(canvas, 71, 27, 2, 8); + canvas_draw_box(canvas, 75, 27, 2, 8); + } else { + if(model->time_passed) { + elements_multiline_text_aligned( + canvas, 83, txt_main_y, AlignLeft, AlignBottom, "Continue"); + } else { + elements_multiline_text_aligned( + canvas, 83, txt_main_y, AlignLeft, AlignBottom, "Start"); + } + canvas_draw_icon(canvas, 70, 26, &I_Ok_btn_9x9); // OK icon + } + canvas_set_color(canvas, ColorBlack); + + // Reset + if(!model->timer_running && model->time_passed) { + canvas_draw_icon(canvas, 63, 46, &I_Space_65x18); + if(model->reset_pressed) { + elements_slightly_rounded_box(canvas, 66, 48, 60, 13); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_icon(canvas, 72, 50, &I_ButtonLeft_4x7); + elements_multiline_text_aligned(canvas, 83, 57, AlignLeft, AlignBottom, "Reset"); + canvas_set_color(canvas, ColorBlack); + } + + char buffer[64]; + + // Time to work + int total_time_left = (max_seconds - (uint32_t)model->time_passed); + int minutes_left = total_time_left / 60; + int seconds_left = total_time_left % 60; + canvas_set_font(canvas, FontBigNumbers); + + // Play sound + if(total_time_left == 0 && !model->sound_playing) { + model->sound_playing = true; + notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_finish); + } + if(total_time_left < 0) { + model->timer_running = false; + model->time_passed = 0; + model->sound_playing = false; + + model->rest_running = true; + model->rest_start_timestamp = current_timestamp; + seconds_left = 0; + model->counter += 1; + } + if(!model->rest_running) { + snprintf(buffer, sizeof(buffer), "%02d:%02d", minutes_left, seconds_left); + canvas_draw_str(canvas, 0, 39, buffer); + } + if(model->timer_running) { + canvas_set_font(canvas, FontPrimary); + elements_multiline_text_aligned(canvas, 0, 50, AlignLeft, AlignTop, "Time to work"); + } + + // Time to rest + if(model->rest_running && !model->timer_running) { + canvas_set_font(canvas, FontBigNumbers); + int rest_passed = current_timestamp - model->rest_start_timestamp; + int rest_total_time_left = (max_seconds_rest - rest_passed); + int rest_minutes_left = rest_total_time_left / 60; + int rest_seconds_left = rest_total_time_left % 60; + + // Play sound + if(rest_total_time_left == 0 && !model->sound_playing) { + model->sound_playing = true; + notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_rest); + } + if(rest_total_time_left < 0) { + rest_seconds_left = 0; + model->rest_running = false; + model->sound_playing = false; + } + snprintf(buffer, sizeof(buffer), "%02d:%02d", rest_minutes_left, rest_seconds_left); + canvas_draw_str(canvas, 0, 60, buffer); + + canvas_set_font(canvas, FontPrimary); + elements_multiline_text_aligned(canvas, 0, 27, AlignLeft, AlignTop, "Have a rest"); + } + + // Clocks + canvas_set_font(canvas, FontSecondary); + snprintf( + buffer, + sizeof(buffer), + "%02ld:%02ld:%02ld", + ((uint32_t)current_timestamp % (60 * 60 * 24)) / (60 * 60), + ((uint32_t)current_timestamp % (60 * 60)) / 60, + (uint32_t)current_timestamp % 60); + canvas_draw_str(canvas, 0, 20, buffer); + + // Tomato counter + if(model->counter > 5) { + model->counter = 1; + } + for(int i = 0; i < model->counter; ++i) { + canvas_draw_disc(canvas, 122 - i * 10, 15, 4); + } +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro_timer.h b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro_timer.h new file mode 100644 index 000000000..284f0a6c6 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro_timer.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include +#include + +typedef struct PomodoroTimer PomodoroTimer; + +struct PomodoroTimer { + View* view; +}; + +typedef struct PomodoroTimerModel PomodoroTimerModel; + +struct PomodoroTimerModel { + bool ok_pressed; + bool reset_pressed; + bool back_pressed; + bool connected; + bool timer_running; + bool rest_running; + bool sound_playing; + uint32_t timer_start_timestamp; + uint32_t timer_stopped_seconds; + uint32_t time_passed; + uint32_t rest_start_timestamp; + int counter; +}; + +void pomodoro_timer_process(PomodoroTimer* pomodoro_timer, InputEvent* event); + +void pomodoro_draw_callback(Canvas* canvas, void* context, int max_seconds, int max_seconds_rest); diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro_timer.png b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/pomodoro_timer.png new file mode 100644 index 0000000000000000000000000000000000000000..b25c2718e0e6e84fa1c074e48b432c16cd0215f9 GIT binary patch literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>aY>EvO!M_+ z&;qhK7#Q0#8CXC{fLIEM85o!sFfuR$X-1IP0w%aD*8*k)8>G;>V#ik?C6npm9|EMA zKw?0^3d9;v8pKX5;9)5Q(uSTcjv*SNNk95oBqSvMDJQF}{Lf>+=fP;@AjW)p5yyhe zhLen$A(JosRETy+a?u94>i_?)x=pWv40Dj?*gi%s1_KVJzyFs@d$Dg*I295!Y1!!= zx9>dC&JnI|v9S1ec~ORfMT2wLn$P8%C# +#include +#include +#include + +static void pomodoro_10_draw_callback(Canvas* canvas, void* context) { + int max_seconds = 60 * 10; + int max_seconds_rest = 60 * 2; + pomodoro_draw_callback(canvas, context, max_seconds, max_seconds_rest); +} + +static bool pomodoro_10_input_callback(InputEvent* event, void* context) { + furi_assert(context); + PomodoroTimer* pomodoro_10 = context; + + if(event->type == InputTypeLong && event->key == InputKeyBack) { + return false; + } else { + pomodoro_timer_process(pomodoro_10, event); + return true; + } +} + +PomodoroTimer* pomodoro_10_alloc() { + PomodoroTimer* pomodoro_10 = malloc(sizeof(PomodoroTimer)); + pomodoro_10->view = view_alloc(); + view_set_context(pomodoro_10->view, pomodoro_10); + view_allocate_model(pomodoro_10->view, ViewModelTypeLocking, sizeof(PomodoroTimerModel)); + view_set_draw_callback(pomodoro_10->view, pomodoro_10_draw_callback); + view_set_input_callback(pomodoro_10->view, pomodoro_10_input_callback); + + return pomodoro_10; +} + +void pomodoro_10_free(PomodoroTimer* pomodoro_10) { + furi_assert(pomodoro_10); + view_free(pomodoro_10->view); + free(pomodoro_10); +} + +View* pomodoro_10_get_view(PomodoroTimer* pomodoro_10) { + furi_assert(pomodoro_10); + return pomodoro_10->view; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_10.h b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_10.h new file mode 100644 index 000000000..8f27e6bd6 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_10.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include "../pomodoro_timer.h" + +PomodoroTimer* pomodoro_10_alloc(); + +void pomodoro_10_free(PomodoroTimer* pomodoro_10); + +View* pomodoro_10_get_view(PomodoroTimer* pomodoro_10); diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_25.c b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_25.c new file mode 100644 index 000000000..01c5a7125 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_25.c @@ -0,0 +1,46 @@ +#include "../pomodoro_timer.h" +#include "pomodoro_25.h" +#include +#include +#include +#include + +static void pomodoro_25_draw_callback(Canvas* canvas, void* context) { + int max_seconds = 60 * 25; + int max_seconds_rest = 60 * 5; + pomodoro_draw_callback(canvas, context, max_seconds, max_seconds_rest); +} + +static bool pomodoro_25_input_callback(InputEvent* event, void* context) { + furi_assert(context); + PomodoroTimer* pomodoro_25 = context; + + if(event->type == InputTypeLong && event->key == InputKeyBack) { + return false; + } else { + pomodoro_timer_process(pomodoro_25, event); + return true; + } +} + +PomodoroTimer* pomodoro_25_alloc() { + PomodoroTimer* pomodoro_25 = malloc(sizeof(PomodoroTimer)); + pomodoro_25->view = view_alloc(); + view_set_context(pomodoro_25->view, pomodoro_25); + view_allocate_model(pomodoro_25->view, ViewModelTypeLocking, sizeof(PomodoroTimerModel)); + view_set_draw_callback(pomodoro_25->view, pomodoro_25_draw_callback); + view_set_input_callback(pomodoro_25->view, pomodoro_25_input_callback); + + return pomodoro_25; +} + +void pomodoro_25_free(PomodoroTimer* pomodoro_25) { + furi_assert(pomodoro_25); + view_free(pomodoro_25->view); + free(pomodoro_25); +} + +View* pomodoro_25_get_view(PomodoroTimer* pomodoro_25) { + furi_assert(pomodoro_25); + return pomodoro_25->view; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_25.h b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_25.h new file mode 100644 index 000000000..c3eb43976 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_25.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include "../pomodoro_timer.h" + +PomodoroTimer* pomodoro_25_alloc(); + +void pomodoro_25_free(PomodoroTimer* pomodoro_25); + +View* pomodoro_25_get_view(PomodoroTimer* pomodoro_25); diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_50.c b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_50.c new file mode 100644 index 000000000..74f89122a --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_50.c @@ -0,0 +1,46 @@ +#include "../pomodoro_timer.h" +#include "pomodoro_50.h" +#include +#include +#include +#include + +static void pomodoro_50_draw_callback(Canvas* canvas, void* context) { + int max_seconds = 60 * 50; + int max_seconds_rest = 60 * 10; + pomodoro_draw_callback(canvas, context, max_seconds, max_seconds_rest); +} + +static bool pomodoro_50_input_callback(InputEvent* event, void* context) { + furi_assert(context); + PomodoroTimer* pomodoro_50 = context; + + if(event->type == InputTypeLong && event->key == InputKeyBack) { + return false; + } else { + pomodoro_timer_process(pomodoro_50, event); + return true; + } +} + +PomodoroTimer* pomodoro_50_alloc() { + PomodoroTimer* pomodoro_50 = malloc(sizeof(PomodoroTimer)); + pomodoro_50->view = view_alloc(); + view_set_context(pomodoro_50->view, pomodoro_50); + view_allocate_model(pomodoro_50->view, ViewModelTypeLocking, sizeof(PomodoroTimerModel)); + view_set_draw_callback(pomodoro_50->view, pomodoro_50_draw_callback); + view_set_input_callback(pomodoro_50->view, pomodoro_50_input_callback); + + return pomodoro_50; +} + +void pomodoro_50_free(PomodoroTimer* pomodoro_50) { + furi_assert(pomodoro_50); + view_free(pomodoro_50->view); + free(pomodoro_50); +} + +View* pomodoro_50_get_view(PomodoroTimer* pomodoro_50) { + furi_assert(pomodoro_50); + return pomodoro_50->view; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_50.h b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_50.h new file mode 100644 index 000000000..e0246d2d2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/pomodoro/views/pomodoro_50.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include "../pomodoro_timer.h" + +PomodoroTimer* pomodoro_50_alloc(); + +void pomodoro_50_free(PomodoroTimer* pomodoro_50); + +View* pomodoro_50_get_view(PomodoroTimer* pomodoro_50); diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/protoview/LICENSE new file mode 100644 index 000000000..2d8a8a74d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2022-2023 Salvatore Sanfilippo + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/README.md b/Applications/Official/DEV_FW/source/xMasterX/protoview/README.md new file mode 100644 index 000000000..e7209d7d6 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/README.md @@ -0,0 +1,103 @@ +ProtoView is a digital signal detection and visualization tool for the +[Flipper Zero](https://flipperzero.one/). The Flipper is able to identify +a great deal of RF protocols, however when the exact protocol is not +implemented (and there are many proprietary ones, such as the ones of +the car keys), the curious person is left wondering what the device is +sending at all. Using ProtoView she or he can visualize the high and low pulses +like in the example image below (showing a Volkswagen key in 2FSK): + +![ProtoView screenshot](/images/ProtoViewSignal.jpg) + +This is often enough to make an initial idea about the encoding used +and if the selected modulation is correct. + +The secondary goal of ProtoView is to provide a somewhat-documented application +for the Flipper (even if ProtoView is a pretty atypical application: doesn't make use of the standard widgets and other abstractions provded by the framework). +Many apps dealing with the *subghz subsystem* (the Flipper +abstraction to work with the [CC1101 chip](https://www.ti.com/product/CC1101)) +tend to be complicated and completely undocumented. This is unfortunately +true for the firmware of the device itself. It's a shame because especially +in the case of code that talks with hardware peripherals there are tons +of assumptions and hard-gained lessons that can [only be captured by comments and are in the code only implicitly](http://antirez.com/news/124). + +However, the Flipper firmware source code is well written even if it +lacks comments and documentation, so it is possible to make some ideas of +how things work just grepping inside. + +# Detection algorithm + +In order to show unknown signals, the application attempts to understand if +the samples obtained by the Flipper API (a series of pulses that are high +or low, and with different duration in microseconds) look like belonging to +a legitimate signal, and aren't just noise. + +We can't make assumptions about +the encoding and the data rate of the communication, so we use a simple +but relatively effective algorithm. As we check the signal, we try to detect +long parts of it that are composed of pulses roughly classifiable into +a maximum of three different classes of lengths, plus or minus 10%. Most +encodings are somewhat self-clocked, so they tend to have just two or +three classes of pulse lengths. + +However often pulses of the same theoretical +length have slightly different lenghts in the case of high and low level +(RF on or off), so we classify them separately for robustness. + +# Usage + +The application shows the longest coherent signal detected so far. + +* The OK button resets the current signal. +* The UP and DOWN buttons change the scale. Default is 100us per pixel. +* The LEFT and RIGHT buttons switch to settings. + +Under the detected sequence, you will see a small triangle marking a +specific sample. This mark means that the sequence looked coherent up +to that point, and starting from there it could be just noise. + +In the bottom-right corner the application displays an amount of time +in microseconds. This is the average length of the shortest pulse length +detected among the three classes. Usually the *data rate* of the protocol +is something like `1000000/this-number*2`, but it depends on the encoding +and could actually be `1000000/this-number*N` with `N > 2` (here 1000000 +is the number of microseconds in one second, and N is the number of clock +cycles needed to represent a bit). + +Things to investigate: + +* Many cheap remotes (gate openers, remotes, ...) are on the 433.92Mhz or nearby and use OOK modulation. +* Weather stations are often too in the 433.92Mhz OOK. +* For car keys, try 443.92 OOK650 and 868.35 Mhz in OOK or 2FSK. + +# Installing the app from source + +* Download the Flipper Zero dev kit and build it: +``` +mkdir -p ~/flipperZero/official/ +cd ~/flipperZero/official/ +git clone --recursive https://github.com/flipperdevices/flipperzero-firmware.git ./ +./fbt +``` +* Copy this application folder in `official/application_user`. +* Connect your Flipper via USB. +* Build and install with: `./fbt launch_app APPSRC=protoview`. + +# Installing the binary file (no build needed) + +Drop the `protoview.fap` file you can find in the `binaries` folder into the +following Flipper Zero location: + + /ext/apps/Tools + +The `ext` part means that we are in the SD card. So if you don't want +to use the Android (or other) application to upload the file, +you can just take out the SD card, insert it in your computer, +copy the fine into `apps/Tools`, and that's it. + +# License + +The code is released under the BSD license. + +# Disclaimer + +This application is only provided as an educational tool. The author is not liable in case the application is used to reverse engineer protocols protected by IP or for any other illegal purpose. diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/TODO b/Applications/Official/DEV_FW/source/xMasterX/protoview/TODO new file mode 100644 index 000000000..0003ccd38 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/TODO @@ -0,0 +1,20 @@ +Core improvements +================= + +- Detection of non Manchester and non RZ encoded signals. Not sure if there are any signals that are not self clocked widely used in RF. Note that the current approach already detects encodings using short high + long low and long high + short low to encode 0 and 1. In addition to the current classifier, it is possible to add one that checks for a sequence of pulses that are all multiples of some base length. This should detect, for instance, even NRZ encodings where 1 and 0 are just clocked as they are. + +- Views on-enter on-exit. + +Features +======== + +- Help screen (with press ok for next page). +- Detect the line code used and try to decode the message as hex dump. +- Pressing right/left you browse different modes: + * Current best signal pulse classes. + * Raw square wave display. Central button freezes and resumes (toggle). When frozen we display "paused" (inverted) on the low part of the screen. + +Screens sequence (user can navigate with <- and ->): + + (default) +[settings] <> [freq] <> [pulses view] <> [raw square view] <> [signal info] diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/app.c b/Applications/Official/DEV_FW/source/xMasterX/protoview/app.c new file mode 100644 index 000000000..6b88ce9d9 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/app.c @@ -0,0 +1,225 @@ +/* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved + * See the LICENSE file for information about the license. */ + +#include "app.h" + +RawSamplesBuffer *RawSamples, *DetectedSamples; +extern const SubGhzProtocolRegistry protoview_protocol_registry; + +/* Draw some text with a border. If the outside color is black and the inside + * color is white, it just writes the border of the text, but the function can + * also be used to write a bold variation of the font setting both the + * colors to black, or alternatively to write a black text with a white + * border so that it is visible if there are black stuff on the background. */ +/* The callback actually just passes the control to the actual active + * view callback, after setting up basic stuff like cleaning the screen + * and setting color to black. */ +static void render_callback(Canvas *const canvas, void *ctx) { + ProtoViewApp *app = ctx; + + /* Clear screen. */ + canvas_set_color(canvas, ColorWhite); + canvas_draw_box(canvas, 0, 0, 127, 63); + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontPrimary); + + /* Call who is in charge right now. */ + switch(app->current_view) { + case ViewRawPulses: render_view_raw_pulses(canvas,app); break; + case ViewInfo: render_view_info(canvas,app); break; + case ViewFrequencySettings: + case ViewModulationSettings: + render_view_settings(canvas,app); break; + case ViewLast: furi_crash(TAG " ViewLast selected"); break; + } +} + +/* Here all we do is putting the events into the queue that will be handled + * in the while() loop of the app entry point function. */ +static void input_callback(InputEvent* input_event, void* ctx) +{ + ProtoViewApp *app = ctx; + furi_message_queue_put(app->event_queue,input_event,FuriWaitForever); +} + +/* Allocate the application state and initialize a number of stuff. + * This is called in the entry point to create the application state. */ +ProtoViewApp* protoview_app_alloc() { + ProtoViewApp *app = malloc(sizeof(ProtoViewApp)); + + // Init shared data structures + RawSamples = raw_samples_alloc(); + DetectedSamples = raw_samples_alloc(); + + //init setting + app->setting = subghz_setting_alloc(); + subghz_setting_load(app->setting, EXT_PATH("subghz/assets/setting_user")); + + // GUI + app->gui = furi_record_open(RECORD_GUI); + app->view_port = view_port_alloc(); + view_port_draw_callback_set(app->view_port, render_callback, app); + view_port_input_callback_set(app->view_port, input_callback, app); + gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen); + app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + app->current_view = ViewRawPulses; + + // Signal found and visualization defaults + app->signal_bestlen = 0; + app->signal_decoded = false; + app->us_scale = PROTOVIEW_RAW_VIEW_DEFAULT_SCALE; + app->signal_offset = 0; + + //init Worker & Protocol + app->txrx = malloc(sizeof(ProtoViewTxRx)); + + /* Setup rx worker and environment. */ + app->txrx->worker = subghz_worker_alloc(); + app->txrx->environment = subghz_environment_alloc(); + subghz_environment_set_protocol_registry( + app->txrx->environment, (void*)&protoview_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); + + app->frequency = subghz_setting_get_default_frequency(app->setting); + app->modulation = 0; /* Defaults to ProtoViewModulations[0]. */ + + furi_hal_power_suppress_charge_enter(); + app->running = 1; + + return app; +} + +/* Free what the application allocated. It is not clear to me if the + * Flipper OS, once the application exits, will be able to reclaim space + * even if we forget to free something here. */ +void protoview_app_free(ProtoViewApp *app) { + furi_assert(app); + + // Put CC1101 on sleep. + radio_sleep(app); + + // View related. + view_port_enabled_set(app->view_port, false); + gui_remove_view_port(app->gui, app->view_port); + view_port_free(app->view_port); + furi_record_close(RECORD_GUI); + furi_message_queue_free(app->event_queue); + app->gui = NULL; + + // Frequency setting. + subghz_setting_free(app->setting); + + // Worker stuff. + subghz_receiver_free(app->txrx->receiver); + subghz_environment_free(app->txrx->environment); + subghz_worker_free(app->txrx->worker); + free(app->txrx); + + // Raw samples buffers. + raw_samples_free(RawSamples); + raw_samples_free(DetectedSamples); + furi_hal_power_suppress_charge_exit(); + + free(app); +} + +/* Called periodically. Do signal processing here. Data we process here + * will be later displayed by the render callback. The side effect of this + * function is to scan for signals and set DetectedSamples. */ +static void timer_callback(void *ctx) { + ProtoViewApp *app = ctx; + scan_for_signal(app); +} + +int32_t protoview_app_entry(void* p) { + UNUSED(p); + ProtoViewApp *app = protoview_app_alloc(); + + /* Create a timer. We do data analysis in the callback. */ + FuriTimer *timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, app); + furi_timer_start(timer, furi_kernel_get_tick_frequency() / 4); + + /* Start listening to signals immediately. */ + radio_begin(app); + radio_rx(app); + + /* This is the main event loop: here we get the events that are pushed + * in the queue by input_callback(), and process them one after the + * other. The timeout is 100 milliseconds, so if not input is received + * before such time, we exit the queue_get() function and call + * view_port_update() in order to refresh our screen content. */ + InputEvent input; + while(app->running) { + FuriStatus qstat = furi_message_queue_get(app->event_queue, &input, 100); + if (qstat == FuriStatusOk) { + if (DEBUG_MSG) FURI_LOG_E(TAG, "Main Loop - Input: type %d key %u", + input.type, input.key); + + /* Handle navigation here. Then handle view-specific inputs + * in the view specific handling function. */ + if (input.type == InputTypeShort && + input.key == InputKeyBack) + { + /* Exit the app. */ + app->running = 0; + } else if (input.type == InputTypeShort && + input.key == InputKeyRight) + { + /* Go to the next view. */ + app->current_view++; + if (app->current_view == ViewLast) app->current_view = 0; + } else if (input.type == InputTypeShort && + input.key == InputKeyLeft) + { + /* Go to the previous view. */ + if (app->current_view == 0) + app->current_view = ViewLast-1; + else + app->current_view--; + } else { + /* This is where we pass the control to the currently + * active view input processing. */ + switch(app->current_view) { + case ViewRawPulses: + process_input_raw_pulses(app,input); + break; + case ViewInfo: + process_input_info(app,input); + break; + case ViewFrequencySettings: + case ViewModulationSettings: + process_input_settings(app,input); + break; + case ViewLast: furi_crash(TAG " ViewLast selected"); break; + } + } + } else { + /* Useful to understand if the app is still alive when it + * does not respond because of bugs. */ + if (DEBUG_MSG) { + static int c = 0; c++; + if (!(c % 20)) FURI_LOG_E(TAG, "Loop timeout"); + } + } + view_port_update(app->view_port); + } + + /* App no longer running. Shut down and free. */ + if (app->txrx->txrx_state == TxRxStateRx) { + FURI_LOG_E(TAG, "Putting CC1101 to sleep before exiting."); + radio_rx_end(app); + radio_sleep(app); + } + + furi_timer_free(timer); + protoview_app_free(app); + return 0; +} + diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/app.h b/Applications/Official/DEV_FW/source/xMasterX/protoview/app.h new file mode 100644 index 000000000..38e90416e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/app.h @@ -0,0 +1,154 @@ +/* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved + * See the LICENSE file for information about the license. */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "app_buffer.h" + +#define TAG "ProtoView" +#define PROTOVIEW_RAW_VIEW_DEFAULT_SCALE 100 +#define BITMAP_SEEK_NOT_FOUND UINT32_MAX + +#define DEBUG_MSG 1 + +typedef struct ProtoViewApp ProtoViewApp; + +/* Subghz system state */ +typedef enum { + TxRxStateIDLE, + TxRxStateRx, + TxRxStateSleep, +} TxRxState; + +/* Currently active view. */ +typedef enum { + ViewRawPulses, + ViewInfo, + ViewFrequencySettings, + ViewModulationSettings, + ViewLast, /* Just a sentinel to wrap around. */ +} ProtoViewCurrentView; + +typedef struct { + const char *name; + FuriHalSubGhzPreset preset; + uint8_t *custom; +} ProtoViewModulation; + +extern ProtoViewModulation ProtoViewModulations[]; /* In app_subghz.c */ + +/* This is the context of our subghz worker and associated thread. + * It receives data and we get our protocol "feed" callback called + * with the level (1 or 0) and duration. */ +struct ProtoViewTxRx { + SubGhzWorker* worker; /* Our background worker. */ + SubGhzEnvironment* environment; + SubGhzReceiver* receiver; + TxRxState txrx_state; /* Receiving, idle or sleeping? */ +}; + +typedef struct ProtoViewTxRx ProtoViewTxRx; + +/* This stucture is filled by the decoder for specific protocols with the + * informations about the message. ProtoView will display such information + * in the message info view. */ +#define PROTOVIEW_MSG_STR_LEN 32 +typedef struct ProtoViewMsgInfo { + char name[PROTOVIEW_MSG_STR_LEN]; /* Protocol name and version. */ + char raw[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific raw representation.*/ + /* The following is what the decoder wants to show to user. Each decoder + * can use the number of fileds it needs. */ + char info1[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 1. */ + char info2[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 2. */ + char info3[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 3. */ + uint64_t len; /* Bits consumed from the stream. */ +} ProtoViewMsgInfo; + +struct ProtoViewApp { + /* GUI */ + Gui *gui; + ViewPort *view_port; /* We just use a raw viewport and we render + everything into the low level canvas. */ + ProtoViewCurrentView current_view; /* Active view ID. */ + FuriMessageQueue *event_queue; /* Keypress events go here. */ + + /* Radio related. */ + ProtoViewTxRx *txrx; /* Radio state. */ + SubGhzSetting *setting; /* A list of valid frequencies. */ + + /* Generic app state. */ + int running; /* Once false exists the app. */ + uint32_t signal_bestlen; /* Longest coherent signal observed so far. */ + bool signal_decoded; /* Was the current signal decoded? */ + ProtoViewMsgInfo signal_info; /* Decoded message, if signal_decoded true. */ + + /* Raw view apps state. */ + uint32_t us_scale; /* microseconds per pixel. */ + uint32_t signal_offset; /* Long press left/right panning in raw view. */ + + /* Configuration view app state. */ + uint32_t frequency; /* Current frequency. */ + uint8_t modulation; /* Current modulation ID, array index in the + ProtoViewModulations table. */ +}; + +typedef struct ProtoViewDecoder { + const char *name; /* Protocol name. */ + /* The decode function takes a buffer that is actually a bitmap, with + * high and low levels represented as 0 and 1. The number of high/low + * pulses represented by the bitmap is passed as the 'numbits' argument, + * while 'numbytes' represents the total size of the bitmap pointed by + * 'bits'. So 'numbytes' is mainly useful to pass as argument to other + * functions that perform bit extraction with bound checking, such as + * bitmap_get() and so forth. */ + bool (*decode)(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info); +} ProtoViewDecoder; + +extern RawSamplesBuffer *RawSamples, *DetectedSamples; + +/* app_radio.c */ +void radio_begin(ProtoViewApp* app); +uint32_t radio_rx(ProtoViewApp* app); +void radio_idle(ProtoViewApp* app); +void radio_rx_end(ProtoViewApp* app); +void radio_sleep(ProtoViewApp* app); + +/* signal.c */ +uint32_t duration_delta(uint32_t a, uint32_t b); +void reset_current_signal(ProtoViewApp *app); +void scan_for_signal(ProtoViewApp *app); +bool bitmap_get(uint8_t *b, uint32_t blen, uint32_t bitpos); +void bitmap_set(uint8_t *b, uint32_t blen, uint32_t bitpos, bool val); +void bitmap_set_pattern(uint8_t *b, uint32_t blen, const char *pat); +void bitmap_invert_bytes_bits(uint8_t *p, uint32_t len); +bool bitmap_match_bits(uint8_t *b, uint32_t blen, uint32_t bitpos, const char *bits); +uint32_t bitmap_seek_bits(uint8_t *b, uint32_t blen, uint32_t startpos, uint32_t maxbits, const char *bits); +uint32_t convert_from_line_code(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t offset, const char *zero_pattern, const char *one_pattern); + +/* view_*.c */ +void render_view_raw_pulses(Canvas *const canvas, ProtoViewApp *app); +void process_input_raw_pulses(ProtoViewApp *app, InputEvent input); +void render_view_settings(Canvas *const canvas, ProtoViewApp *app); +void process_input_settings(ProtoViewApp *app, InputEvent input); +void render_view_info(Canvas *const canvas, ProtoViewApp *app); +void process_input_info(ProtoViewApp *app, InputEvent input); + +/* ui.c */ +void canvas_draw_str_with_border(Canvas* canvas, uint8_t x, uint8_t y, const char* str, Color text_color, Color border_color); diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/app_buffer.c b/Applications/Official/DEV_FW/source/xMasterX/protoview/app_buffer.c new file mode 100644 index 000000000..df2e7074e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/app_buffer.c @@ -0,0 +1,73 @@ +/* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved + * See the LICENSE file for information about the license. */ + +#include +#include +#include +#include +#include "app_buffer.h" + +/* Allocate and initialize a samples buffer. */ +RawSamplesBuffer *raw_samples_alloc(void) { + RawSamplesBuffer *buf = malloc(sizeof(*buf)); + buf->mutex = furi_mutex_alloc(FuriMutexTypeNormal); + raw_samples_reset(buf); + return buf; +} + +/* Free a sample buffer. Should be called when the mutex is released. */ +void raw_samples_free(RawSamplesBuffer *s) { + furi_mutex_free(s->mutex); + free(s); +} + +/* This just set all the samples to zero and also resets the internal + * index. There is no need to call it after raw_samples_alloc(), but only + * when one wants to reset the whole buffer of samples. */ +void raw_samples_reset(RawSamplesBuffer *s) { + furi_mutex_acquire(s->mutex,FuriWaitForever); + s->total = RAW_SAMPLES_NUM; + s->idx = 0; + s->short_pulse_dur = 0; + memset(s->level,0,sizeof(s->level)); + memset(s->dur,0,sizeof(s->dur)); + furi_mutex_release(s->mutex); +} + +/* Set the raw sample internal index so that what is currently at + * offset 'offset', will appear to be at 0 index. */ +void raw_samples_center(RawSamplesBuffer *s, uint32_t offset) { + s->idx = (s->idx+offset) % RAW_SAMPLES_NUM; +} + +/* Add the specified sample in the circular buffer. */ +void raw_samples_add(RawSamplesBuffer *s, bool level, uint32_t dur) { + furi_mutex_acquire(s->mutex,FuriWaitForever); + s->level[s->idx] = level; + s->dur[s->idx] = dur; + s->idx = (s->idx+1) % RAW_SAMPLES_NUM; + furi_mutex_release(s->mutex); +} + +/* Get the sample from the buffer. It is possible to use out of range indexes + * as 'idx' because the modulo operation will rewind back from the start. */ +void raw_samples_get(RawSamplesBuffer *s, uint32_t idx, bool *level, uint32_t *dur) +{ + furi_mutex_acquire(s->mutex,FuriWaitForever); + idx = (s->idx + idx) % RAW_SAMPLES_NUM; + *level = s->level[idx]; + *dur = s->dur[idx]; + furi_mutex_release(s->mutex); +} + +/* Copy one buffer to the other, including current index. */ +void raw_samples_copy(RawSamplesBuffer *dst, RawSamplesBuffer *src) { + furi_mutex_acquire(src->mutex,FuriWaitForever); + furi_mutex_acquire(dst->mutex,FuriWaitForever); + dst->idx = src->idx; + dst->short_pulse_dur = src->short_pulse_dur; + memcpy(dst->level,src->level,sizeof(dst->level)); + memcpy(dst->dur,src->dur,sizeof(dst->dur)); + furi_mutex_release(src->mutex); + furi_mutex_release(dst->mutex); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/app_buffer.h b/Applications/Official/DEV_FW/source/xMasterX/protoview/app_buffer.h new file mode 100644 index 000000000..5d997d02e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/app_buffer.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved + * See the LICENSE file for information about the license. */ + +/* Our circular buffer of raw samples, used in order to display + * the signal. */ + +#define RAW_SAMPLES_NUM 2048 /* Use a power of two: we take the modulo + of the index quite often to normalize inside + the range, and division is slow. */ + +typedef struct RawSamplesBuffer { + FuriMutex *mutex; + uint8_t level[RAW_SAMPLES_NUM]; + uint32_t dur[RAW_SAMPLES_NUM]; + uint32_t idx; /* Current idx (next to write). */ + uint32_t total; /* Total samples: same as RAW_SAMPLES_NUM, we provide + this field for a cleaner interface with the user, but + we always use RAW_SAMPLES_NUM when taking the modulo so + the compiler can optimize % as bit masking. */ + /* Signal features. */ + uint32_t short_pulse_dur; /* Duration of the shortest pulse. */ +} RawSamplesBuffer; + +RawSamplesBuffer *raw_samples_alloc(void); +void raw_samples_reset(RawSamplesBuffer *s); +void raw_samples_center(RawSamplesBuffer *s, uint32_t offset); +void raw_samples_add(RawSamplesBuffer *s, bool level, uint32_t dur); +void raw_samples_get(RawSamplesBuffer *s, uint32_t idx, bool *level, uint32_t *dur); +void raw_samples_copy(RawSamplesBuffer *dst, RawSamplesBuffer *src); +void raw_samples_free(RawSamplesBuffer *s); diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/app_subghz.c b/Applications/Official/DEV_FW/source/xMasterX/protoview/app_subghz.c new file mode 100644 index 000000000..987dd1aac --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/app_subghz.c @@ -0,0 +1,85 @@ +/* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved + * See the LICENSE file for information about the license. */ + +#include "app.h" +#include "custom_presets.h" + +#include + +ProtoViewModulation ProtoViewModulations[] = { + {"OOK 650Khz", FuriHalSubGhzPresetOok650Async, NULL}, + {"OOK 270Khz", FuriHalSubGhzPresetOok270Async, NULL}, + {"2FSK 2.38Khz", FuriHalSubGhzPreset2FSKDev238Async, NULL}, + {"2FSK 47.6Khz", FuriHalSubGhzPreset2FSKDev476Async, NULL}, + {"MSK", FuriHalSubGhzPresetMSK99_97KbAsync, NULL}, + {"GFSK", FuriHalSubGhzPresetGFSK9_99KbAsync, NULL}, + {"FSK for TPMS", 0, (uint8_t*)protoview_subghz_tpms_async_regs}, + {NULL, 0, NULL} /* End of list sentinel. */ +}; + +/* Called after the application initialization in order to setup the + * subghz system and put it into idle state. If the user wants to start + * receiving we will call radio_rx() to start a receiving worker and + * associated thread. */ +void radio_begin(ProtoViewApp* app) { + furi_assert(app); + furi_hal_subghz_reset(); + furi_hal_subghz_idle(); + + /* The CC1101 preset can be either one of the standard presets, if + * the modulation "custom" field is NULL, or a custom preset we + * defined in custom_presets.h. */ + if (ProtoViewModulations[app->modulation].custom == NULL) + furi_hal_subghz_load_preset(ProtoViewModulations[app->modulation].preset); + else + furi_hal_subghz_load_custom_preset(ProtoViewModulations[app->modulation].custom); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + app->txrx->txrx_state = TxRxStateIDLE; +} + +/* Setup subghz to start receiving using a background worker. */ +uint32_t radio_rx(ProtoViewApp* app) { + furi_assert(app); + if(!furi_hal_subghz_is_frequency_valid(app->frequency)) { + furi_crash(TAG" Incorrect RX frequency."); + } + + if (app->txrx->txrx_state == TxRxStateRx) return app->frequency; + + furi_hal_subghz_idle(); /* Put it into idle state in case it is sleeping. */ + uint32_t value = furi_hal_subghz_set_frequency_and_path(app->frequency); + FURI_LOG_E(TAG, "Switched to frequency: %lu", value); + 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 = TxRxStateRx; + return value; +} + +/* Stop subghz worker (if active), put radio on idle state. */ +void radio_rx_end(ProtoViewApp* app) { + furi_assert(app); + if (app->txrx->txrx_state == TxRxStateRx) { + 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 = TxRxStateIDLE; +} + +/* Put radio on sleep. */ +void radio_sleep(ProtoViewApp* app) { + furi_assert(app); + if (app->txrx->txrx_state == TxRxStateRx) { + /* We can't go from having an active RX worker to sleeping. + * Stop the RX subsystems first. */ + radio_rx_end(app); + } + furi_hal_subghz_sleep(); + app->txrx->txrx_state = TxRxStateSleep; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/appicon.png b/Applications/Official/DEV_FW/source/xMasterX/protoview/appicon.png new file mode 100644 index 0000000000000000000000000000000000000000..7ce5c4effe68487f668016cee2623ec193cf832c GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>(ere14ABTq z{`3F;|9UnhhQ|ScCxC$AlW+$cql9!TTV + +static uint8_t protoview_subghz_tpms_async_regs[][2] = { + /* GPIO GD0 */ + {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input + + /* Frequency Synthesizer Control */ + {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + + /* Packet engine */ + {CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening + {CC1101_PKTCTRL1, 0x04}, + + // // Modem Configuration + {CC1101_MDMCFG0, 0x00}, + {CC1101_MDMCFG1, 0x02}, + {CC1101_MDMCFG2, 0x04}, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized). Other code reading TPMS uses GFSK, but should be the same when in RX mode. + {CC1101_MDMCFG3, 0x93}, // Data rate is 20kBaud + {CC1101_MDMCFG4, 0x59}, // Rx bandwidth filter is 325 kHz + {CC1101_DEVIATN, 0x41}, // Deviation 28.56 kHz + + /* Main Radio Control State Machine */ + {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + + /* Frequency Offset Compensation Configuration */ + {CC1101_FOCCFG, + 0x16}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + + /* Automatic Gain Control */ + {CC1101_AGCCTRL0, + 0x91}, //10 - Medium hysteresis, medium asymmetric dead zone, medium gain ; 01 - 16 samples agc; 00 - Normal AGC, 01 - 8dB boundary + {CC1101_AGCCTRL1, + 0x00}, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET + {CC1101_AGCCTRL2, 0x07}, // 00 - DVGA all; 000 - MAX LNA+LNA2; 111 - MAIN_TARGET 42 dB + + /* Wake on radio and timeouts control */ + {CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + + /* Frontend configuration */ + {CC1101_FREND0, 0x10}, // Adjusts current TX LO buffer + {CC1101_FREND1, 0x56}, + + /* End */ + {0, 0}, +}; + diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/images/ProtoViewSignal.jpg b/Applications/Official/DEV_FW/source/xMasterX/protoview/images/ProtoViewSignal.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2c1938e7bfdba2b3e353f3a34bc2e86cc4122706 GIT binary patch literal 85828 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℞3u9Qkpv-kz4iHG73F5o@is{R&` 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

  • VImKjmm}*rKaf(SZeU@1(lm^wQ&Fa?*9#LDtx zT=U-S2DitaxAG*NEe_wsCUJ&)yrfJu=NNC$?#hT~eC?gY})!`p-9X@RIn?!y1k!nlS?g#jiZ#*MA~X07qU_q&7YnrOG>H#ei~NVP*Wm%RG* zEIudNe2`|?=2)3>vMq0b*&vN(>c8?czSc+=nF*@oy{}BC8~4fZiC&>tf}rnnnO4jz zW`w%LdUVoJ6Kp~Ba;2V~#~sbeu_r7pI_lf=mI3K&i_tZ|&CL8Z6ILg`c&NtR{alpH z@kCgHbOw5IadaWm_$r-lgWgJNO63=Mw9#tlE$du2+6pix?891^$GZszP4gAP!6Eui z;+O-OUWD}1)-DMVldHSw9g!D*6p~~5nfrT879YK#yeJ-NGF80*FL=M@E>i` zH&feB^5&C?$0RFVYA(7R^$XGSfT$voycRPp!0?E|p7H6X053Z<%JYhhpLfuc)o2x= z$#vNXE9?jdH@)DK7QxwpsGg4E{kTLs8)ZoQr8xLxdIs1LQTrYoFIQ&&vLnSFDXESV zDL>}uk`QEqDGgk}wn^n9)crO65h&aB31n#RoSQE@SfOT}S zp&VxzTD<~zu6aE%h|a+-K~T&SB$^<>=8<&}(Cr#(%T%31TLGJ86^G9I80P%{!+$&m zeDjj`yqUhl@Gw2K2R0-s{c{<7wXePe%gEP2b(VCk|9wzmK@kMkvmhCpHDe4BEl)-h zw*Oa$zvoH6D^Di<$j%u32@8*F0_z;zVV(%I-ta2+uisD<^`~En77u`!1L?n5o$EmQ z4}DEskRP#M;Mhk)O%*P!CaI6P#~@(a&)nyhe=ey_P|yiiZ`3+5TDaXxH}nZX22LHj zP4i^gqryHeM}FSFC=KkK4w>@l0&>N7`XJaIJJv)TjFODdC4qVM2dK+QuYw1aYa)I< z-(!hY=x3U?iUy|a3QBsOfRPRvdX!%+X{NO3<2m()>$Cri>5W!tsq`Xhhz3ZKL`rk= zmV7;1vg4_Q^ZMr36uf|aY#gTtqU6{hDe3oHepPMf&yg~1jUSe-6(aOG|*CN-@sFiP7N!XR3WHE z-F5b~rUwa$lz#phz?&wtSFf6)kv-;xOJmFss2p04NZQ5Shd#%l)Ltx#g9&52CCjm+5_tB&SqF_NVmtq~SP9aooP=Rcx+AYMv;p55!3X zHL6Lp3)6s8d6r*a{dfMZb(CAKS{JU3Wr`QEkm1d#oNX2xFodqm`p3=@g665*c9t_nD_u|sqb0J?53cp=AR7eDyxJ6!J zFMUmR?}FL`+W%DJWyaoXWPG(zzwY_}oZx@V7^{MZBfcVnhA~w$Hi8b3xsmsdJlJq- zNK!o2gNk+oX-`yh7>}M)kUw-jP`+h{QF)}q!W)NcI4PC0x;72>y17tuHGm}uHPv2$5}8o2@lLM78(>Hyk&>8xL{10fG`#%}sx_<+0{?Zgl$q?tAY%?!jt z>)ut)9x(k0k|Ie11Ej=??i`Vy6O_C&doofkKoOE#B19@$mu)GBB#9R){`S7}1L?8n zoz~H}af#-koMjU8+WQ`A69lHj1$#-d$}AO7<4~@f7TkMgZG%5gS;1q||8_-q1;i!3sXJr{7Z)`@0- z9qKR-mluMC;wTsoQ$(i9Q@HA@rj)(}fm0#8G?~_!dO|Kru9Jdl3U^x%ktMO|F1Lx9q2^GdKE06xxM=SG;ax2#_DozwdUGm z%gQ4iNFfbfaoY{I*Y{kTfkGj?Q6GmiziqvK2waU}M4(8Pc~$^N+9j#v5kL*-k(@u~ F{~H}aQquqc literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/proto.c b/Applications/Official/DEV_FW/source/xMasterX/protoview/proto.c new file mode 100644 index 000000000..c3387fc4c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/proto.c @@ -0,0 +1,120 @@ +/* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved + * See the LICENSE file for information about the license. */ + +#include +#include +#include +#include +#include +#include "app_buffer.h" + +#define TAG "PROTOVIEW-protocol" + +const SubGhzProtocol subghz_protocol_protoview; + +/* The feed() method puts data in the RawSamples global (protected by + * a mutex). */ +extern RawSamplesBuffer *RawSamples; + +/* This is totally dummy: we just define the decoder base for the async + * system to work but we don't really use it if not to collect raw + * data via the feed() method. */ +typedef struct SubGhzProtocolDecoderprotoview { + SubGhzProtocolDecoderBase base; +} SubGhzProtocolDecoderprotoview; + +void* subghz_protocol_decoder_protoview_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + + SubGhzProtocolDecoderprotoview* instance = + malloc(sizeof(SubGhzProtocolDecoderprotoview)); + instance->base.protocol = &subghz_protocol_protoview; + return instance; +} + +void subghz_protocol_decoder_protoview_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderprotoview* instance = context; + free(instance); +} + +void subghz_protocol_decoder_protoview_reset(void* context) { + furi_assert(context); +} + +/* That's the only thig we really use of the protocol decoder + * implementation. We avoid the subghz provided abstractions and put + * the data in our simple abstraction: the RawSamples circular buffer. */ +void subghz_protocol_decoder_protoview_feed(void* context, bool level, uint32_t duration) { + furi_assert(context); + UNUSED(context); + + /* Add data to the circular buffer. */ + raw_samples_add(RawSamples, level, duration); + // FURI_LOG_E(TAG, "FEED: %d %d", (int)level, (int)duration); + return; +} + +/* The only scope of this method is to avoid duplicated messages in the + * Subghz history, which we don't use. */ +uint8_t subghz_protocol_decoder_protoview_get_hash_data(void* context) { + furi_assert(context); + return 123; +} + +/* Not used. */ +bool subghz_protocol_decoder_protoview_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) +{ + UNUSED(context); + UNUSED(flipper_format); + UNUSED(preset); + return false; +} + +/* Not used. */ +bool subghz_protocol_decoder_protoview_deserialize(void* context, FlipperFormat* flipper_format) +{ + UNUSED(context); + UNUSED(flipper_format); + return false; +} + +void subhz_protocol_decoder_protoview_get_string(void* context, FuriString* output) +{ + furi_assert(context); + furi_string_cat_printf(output, "Protoview"); +} + +const SubGhzProtocolDecoder subghz_protocol_protoview_decoder = { + .alloc = subghz_protocol_decoder_protoview_alloc, + .free = subghz_protocol_decoder_protoview_free, + .reset = subghz_protocol_decoder_protoview_reset, + .feed = subghz_protocol_decoder_protoview_feed, + .get_hash_data = subghz_protocol_decoder_protoview_get_hash_data, + .serialize = subghz_protocol_decoder_protoview_serialize, + .deserialize = subghz_protocol_decoder_protoview_deserialize, + .get_string = subhz_protocol_decoder_protoview_get_string, +}; + +/* Well, we don't really target a specific protocol. So let's put flags + * that make sense. */ +const SubGhzProtocol subghz_protocol_protoview = { + .name = "Protoview", + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_AM | SubGhzProtocolFlag_FM | SubGhzProtocolFlag_Decodable, + .decoder = &subghz_protocol_protoview_decoder, +}; + +/* Our table has just the single dummy protocol we defined for the + * sake of data collection. */ +const SubGhzProtocol* protoview_protocol_registry_items[] = { + &subghz_protocol_protoview, +}; + +const SubGhzProtocolRegistry protoview_protocol_registry = { + .items = protoview_protocol_registry_items, + .size = COUNT_OF(protoview_protocol_registry_items) +}; diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/protocols/b4b1.c b/Applications/Official/DEV_FW/source/xMasterX/protoview/protocols/b4b1.c new file mode 100644 index 000000000..6977c0eb3 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/protocols/b4b1.c @@ -0,0 +1,44 @@ +/* PT/SC remotes. Usually 443.92 Mhz OOK. + * + * This line code is used in many remotes such as Princeton chips + * named PT, Silian Microelectronics SC5262 and others. + * Basically every 4 pulsee represent a bit, where 1000 means 0, and + * 1110 means 1. Usually we can read 24 bits of data. + * In this specific implementation we check for a prelude that is + * 1 bit high, 31 bits low, but the check is relaxed. */ + +#include "../app.h" + +static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) { + if (numbits < 30) return false; + const char *sync_patterns[3] = { + "10000000000000000000000000000001", /* 30 zero bits. */ + "100000000000000000000000000000001", /* 31 zero bits. */ + "1000000000000000000000000000000001", /* 32 zero bits. */ + }; + + uint32_t off; + int j; + for (j = 0; j < 3; j++) { + off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_patterns[j]); + if (off != BITMAP_SEEK_NOT_FOUND) break; + } + if (off == BITMAP_SEEK_NOT_FOUND) return false; + if (DEBUG_MSG) FURI_LOG_E(TAG, "B4B1 preamble at: %lu",off); + off += strlen(sync_patterns[j])-1; + + uint8_t d[3]; /* 24 bits of data. */ + uint32_t decoded = + convert_from_line_code(d,sizeof(d),bits,numbytes,off,"1000","1110"); + + if (DEBUG_MSG) FURI_LOG_E(TAG, "B4B1 decoded: %lu",decoded); + if (decoded != 24) return false; + snprintf(info->name,PROTOVIEW_MSG_STR_LEN,"PT/SC remote"); + snprintf(info->raw,PROTOVIEW_MSG_STR_LEN,"%02X%02X%02X",d[0],d[1],d[2]); + info->len = off+(4*24); + return true; +} + +ProtoViewDecoder B4B1Decoder = { + "B4B1", decode +}; diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/protocols/oregon2.c b/Applications/Official/DEV_FW/source/xMasterX/protoview/protocols/oregon2.c new file mode 100644 index 000000000..3aa57c72d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/protocols/oregon2.c @@ -0,0 +1,65 @@ +/* Oregon remote termometers. Usually 443.92 Mhz OOK. + * + * The protocol is described here: + * https://wmrx00.sourceforge.net/Arduino/OregonScientific-RF-Protocols.pdf + * This implementation is not very complete. */ + +#include "../app.h" + +static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) { + if (numbits < 32) return false; + const char *sync_pattern = "01100110" "01100110" "10010110" "10010110"; + uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern); + if (off == BITMAP_SEEK_NOT_FOUND) return false; + FURI_LOG_E(TAG, "Oregon2 preamble+sync found"); + + off += 32; /* Skip preamble. */ + + uint8_t buffer[8], raw[8] = {0}; + uint32_t decoded = + convert_from_line_code(buffer,sizeof(buffer),bits,numbytes,off,"1001","0110"); + FURI_LOG_E(TAG, "Oregon2 decoded bits: %lu", decoded); + + if (decoded < 11*4) return false; /* Minimum len to extract some data. */ + + char temp[3] = {0}, deviceid[2] = {0}, hum[2] = {0}; + for (int j = 0; j < 64; j += 4) { + uint8_t nib[1]; + nib[0] = (bitmap_get(buffer,8,j+0) | + bitmap_get(buffer,8,j+1) << 1 | + bitmap_get(buffer,8,j+2) << 2 | + bitmap_get(buffer,8,j+3) << 3); + if (DEBUG_MSG) FURI_LOG_E(TAG, "Not inverted nibble[%d]: %x", j/4, (unsigned int)nib[0]); + raw[j/8] |= nib[0] << (4-(j%4)); + switch(j/4) { + case 1: deviceid[0] |= nib[0]; break; + case 0: deviceid[0] |= nib[0] << 4; break; + case 3: deviceid[1] |= nib[0]; break; + case 2: deviceid[1] |= nib[0] << 4; break; + case 10: temp[0] = nib[0]; break; + /* Fixme: take the temperature sign from nibble 11. */ + case 9: temp[1] = nib[0]; break; + case 8: temp[2] = nib[0]; break; + case 13: hum[0] = nib[0]; break; + case 12: hum[1] = nib[0]; break; + } + } + + snprintf(info->name,sizeof(info->name),"%s","Oregon v2.1"); + /* The following line crashes the Flipper because of broken + * snprintf() implementation. */ + snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X", + raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], + raw[6],raw[7]); + snprintf(info->info1,sizeof(info->info1),"Sensor ID %02X%02X", + deviceid[0], deviceid[1]); + snprintf(info->info2,sizeof(info->info2),"Temperature %d%d.%d", + temp[0],temp[1],temp[2]); + snprintf(info->info3,sizeof(info->info3),"Humidity %d%d", + hum[0],hum[1]); + return true; +} + +ProtoViewDecoder Oregon2Decoder = { + "Oregon2", decode +}; diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/protocols/oregon2.txt b/Applications/Official/DEV_FW/source/xMasterX/protoview/protocols/oregon2.txt new file mode 100644 index 000000000..362631431 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/protocols/oregon2.txt @@ -0,0 +1,6 @@ +11001100110011001100110011001100110011001100110011001100110 (Preamble) +10 01 01 10 10 01 01 10 (Sync) +01 10 10 01 10 01 10 01 01 10 10 01 01 10 01 10 10 01 01 10 10 01 10 01 10 01 10 01 10 01 10 01 01 10 10 01 10 01 10 01 01 10 01 10 01 10 01 10 01 10 01 10 10 01 01 10 01 10 10 01 10 01 10 01 10 01 10 01 01 10 10 01 10 01 01 10 01 10 10 01 01 10 10 01 10 01 10 01 10 01 10 01 10 01 11 0 + +We need to seek the following bytes: 01100110 01100110 10010110 10010110 + 0x66 0x66 96 96 diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/protocols/renault_tpms.c b/Applications/Official/DEV_FW/source/xMasterX/protoview/protocols/renault_tpms.c new file mode 100644 index 000000000..3022a5d4e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/protocols/renault_tpms.c @@ -0,0 +1,63 @@ +/* Renault tires TPMS. Usually 443.92 Mhz FSK. + * + * Preamble + marshal-encoded bits. 9 Bytes in total if we don't + * count the preamble. */ + +#include "../app.h" + +#define USE_TEST_VECTOR 0 +static const char *test_vector = + "10101010" "10101010" "10101010" "10101001" // Preamble + sync. + + /* The following is marshal encoded, so each two characters are + * actaully one bit. 01 = 1, 10 = 0. */ + "010110010110" // Flags. + "10011001101010011001" // Pressure, multiply by 0.75 to obtain kpa. + // 244 kpa here. + "1010010110011010" // Temperature, subtract 30 to obtain celsius. 22C here. + "1001010101101001" + "0101100110010101" + "1001010101100110" // Tire ID. 0x7AD779 here. + "0101010101010101" + "0101010101010101" // Two FF bytes (usually). Unknown. + "0110010101010101"; // CRC8 with (poly 7, initialization 0). + +static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) { + + if (USE_TEST_VECTOR) { /* Test vector to check that decoding works. */ + bitmap_set_pattern(bits,numbytes,test_vector); + numbits = strlen(test_vector); + } + + if (numbits < 13*8) return false; + + const char *sync_pattern = "10101010" "10101010" "10101010" "10101001"; + uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern); + if (off == BITMAP_SEEK_NOT_FOUND) return false; + FURI_LOG_E(TAG, "Renault TPMS preamble+sync found"); + + off += 32; /* Skip preamble. */ + + uint8_t raw[9]; + uint32_t decoded = + convert_from_line_code(raw,sizeof(raw),bits,numbytes,off, + "10","01"); /* Manchester. */ + FURI_LOG_E(TAG, "Renault TPMS decoded bits: %lu", decoded); + + if (decoded < 8*9) return false; /* Require the full 9 bytes. */ + + float kpa = 0.75 *((uint32_t)((raw[0]&3)<<8) | raw[1]); + int temp = raw[2]-30; + + snprintf(info->name,sizeof(info->name),"%s","Renault TPMS"); + snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X", + raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], + raw[6],raw[7],raw[8]); + snprintf(info->info1,sizeof(info->info1),"Pressure %.2f kpa", (double)kpa); + snprintf(info->info2,sizeof(info->info2),"Temperature %d C", temp); + return true; +} + +ProtoViewDecoder RenaultTPMSDecoder = { + "Renault TPMS", decode +}; diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/signal.c b/Applications/Official/DEV_FW/source/xMasterX/protoview/signal.c new file mode 100644 index 000000000..2ff632811 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/signal.c @@ -0,0 +1,420 @@ +/* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved + * See the LICENSE file for information about the license. */ + +#include "app.h" + +bool decode_signal(RawSamplesBuffer *s, uint64_t len, ProtoViewMsgInfo *info); +void initialize_msg_info(ProtoViewMsgInfo *i); + +/* ============================================================================= + * Raw signal detection + * ===========================================================================*/ + +/* Return the time difference between a and b, always >= 0 since + * the absolute value is returned. */ +uint32_t duration_delta(uint32_t a, uint32_t b) { + return a > b ? a - b : b - a; +} + +/* Reset the current signal, so that a new one can be detected. */ +void reset_current_signal(ProtoViewApp *app) { + app->signal_bestlen = 0; + app->signal_offset = 0; + app->signal_decoded = false; + raw_samples_reset(DetectedSamples); + raw_samples_reset(RawSamples); +} + +/* This function starts scanning samples at offset idx looking for the + * longest run of pulses, either high or low, that are not much different + * from each other, for a maximum of three duration classes. + * So for instance 50 successive pulses that are roughly long 340us or 670us + * will be sensed as a coherent signal (example: 312, 361, 700, 334, 667, ...) + * + * The classes are counted separtely for high and low signals (RF on / off) + * because many devices tend to have different pulse lenghts depending on + * the level of the pulse. + * + * For instance Oregon2 sensors, in the case of protocol 2.1 will send + * pulses of ~400us (RF on) VS ~580us (RF off). */ +#define SEARCH_CLASSES 3 +uint32_t search_coherent_signal(RawSamplesBuffer *s, uint32_t idx) { + struct { + uint32_t dur[2]; /* dur[0] = low, dur[1] = high */ + uint32_t count[2]; /* Associated observed frequency. */ + } classes[SEARCH_CLASSES]; + + memset(classes,0,sizeof(classes)); + uint32_t minlen = 30, maxlen = 4000; /* Depends on data rate, here we + allow for high and low. */ + uint32_t len = 0; /* Observed len of coherent samples. */ + s->short_pulse_dur = 0; + for (uint32_t j = idx; j < idx+500; j++) { + bool level; + uint32_t dur; + raw_samples_get(s, j, &level, &dur); + if (dur < minlen || dur > maxlen) break; /* return. */ + + /* Let's see if it matches a class we already have or if we + * can populate a new (yet empty) class. */ + uint32_t k; + for (k = 0; k < SEARCH_CLASSES; k++) { + if (classes[k].count[level] == 0) { + classes[k].dur[level] = dur; + classes[k].count[level] = 1; + break; /* Sample accepted. */ + } else { + uint32_t classavg = classes[k].dur[level]; + uint32_t count = classes[k].count[level]; + uint32_t delta = duration_delta(dur,classavg); + /* Is the difference in duration between this signal and + * the class we are inspecting less than a given percentage? + * If so, accept this signal. */ + if (delta < classavg/8) { /* 100%/8 = 12%. */ + /* It is useful to compute the average of the class + * we are observing. We know how many samples we got so + * far, so we can recompute the average easily. + * By always having a better estimate of the pulse len + * we can avoid missing next samples in case the first + * observed samples are too off. */ + classavg = ((classavg * count) + dur) / (count+1); + classes[k].dur[level] = classavg; + classes[k].count[level]++; + break; /* Sample accepted. */ + } + } + } + + if (k == SEARCH_CLASSES) break; /* No match, return. */ + + /* If we are here, we accepted this sample. Try with the next + * one. */ + len++; + } + + /* Update the buffer setting the shortest pulse we found + * among the three classes. This will be used when scaling + * for visualization. */ + uint32_t short_dur[2] = {0,0}; + for (int j = 0; j < SEARCH_CLASSES; j++) { + for (int level = 0; level < 2; level++) { + if (classes[j].dur[level] == 0) continue; + if (classes[j].count[level] < 3) continue; + if (short_dur[level] == 0 || + short_dur[level] > classes[j].dur[level]) + { + short_dur[level] = classes[j].dur[level]; + } + } + } + + /* Use the average between high and low short pulses duration. + * Often they are a bit different, and using the average is more robust + * when we do decoding sampling at short_pulse_dur intervals. */ + if (short_dur[0] == 0) short_dur[0] = short_dur[1]; + if (short_dur[1] == 0) short_dur[1] = short_dur[0]; + s->short_pulse_dur = (short_dur[0]+short_dur[1])/2; + + return len; +} + +/* Search the buffer with the stored signal (last N samples received) + * in order to find a coherent signal. If a signal that does not appear to + * be just noise is found, it is set in DetectedSamples global signal + * buffer, that is what is rendered on the screen. */ +void scan_for_signal(ProtoViewApp *app) { + /* We need to work on a copy: the RawSamples buffer is populated + * by the background thread receiving data. */ + RawSamplesBuffer *copy = raw_samples_alloc(); + raw_samples_copy(copy,RawSamples); + + /* Try to seek on data that looks to have a regular high low high low + * pattern. */ + uint32_t minlen = 13; /* Min run of coherent samples. Up to + 12 samples it's very easy to mistake + noise for signal. */ + + ProtoViewMsgInfo *info = malloc(sizeof(ProtoViewMsgInfo)); + uint32_t i = 0; + + while (i < copy->total-1) { + uint32_t thislen = search_coherent_signal(copy,i); + + /* For messages that are long enough, attempt decoding. */ + if (thislen > minlen) { + initialize_msg_info(info); + uint32_t saved_idx = copy->idx; /* Save index, see later. */ + /* decode_signal() expects the detected signal to start + * from index .*/ + raw_samples_center(copy,i); + bool decoded = decode_signal(copy,thislen,info); + copy->idx = saved_idx; /* Restore the index as we are scanning + the signal in the loop. */ + + /* Accept this signal as the new signal if either it's longer + * than the previous one, or the previous one was unknown and + * this is decoded. */ + if (thislen > app->signal_bestlen || + (app->signal_decoded == false && decoded)) + { + app->signal_info = *info; + app->signal_bestlen = thislen; + app->signal_decoded = decoded; + raw_samples_copy(DetectedSamples,copy); + raw_samples_center(DetectedSamples,i); + FURI_LOG_E(TAG, "Displayed sample updated (%d samples %lu us)", + (int)thislen, DetectedSamples->short_pulse_dur); + } + } + i += thislen ? thislen : 1; + } + raw_samples_free(copy); + free(info); +} + +/* ============================================================================= + * Decoding + * + * The following code will translates the raw singals as received by + * the CC1101 into logical signals: a bitmap of 0s and 1s sampled at + * the detected data clock interval. + * + * Then the converted signal is passed to the protocols decoders, that look + * for protocol-specific information. We stop at the first decoder that is + * able to decode the data, so protocols here should be registered in + * order of complexity and specificity, with the generic ones at the end. + * ===========================================================================*/ + +/* Set the 'bitpos' bit to value 'val', in the specified bitmap + * 'b' of len 'blen'. + * Out of range bits will silently be discarded. */ +void bitmap_set(uint8_t *b, uint32_t blen, uint32_t bitpos, bool val) { + uint32_t byte = bitpos/8; + uint32_t bit = 7-(bitpos&7); + if (byte >= blen) return; + if (val) + b[byte] |= 1<= blen) return 0; + return (b[byte] & (1< rate/2) numbits++; /* There is another one. */ + + /* Limit how much a single sample can spawn. There are likely no + * protocols doing such long pulses when the rate is low. */ + if (numbits > 1024) numbits = 1024; + + if (0) /* Super verbose, so not under the DEBUG_MSG define. */ + FURI_LOG_E(TAG, "%lu converted into %lu (%d) bits", + dur,numbits,(int)level); + + /* If the signal is too short, let's claim it an interference + * and ignore it completely. */ + if (numbits == 0) continue; + + while(numbits--) bitmap_set(b,blen,bitpos++,level); + } + return bitpos; +} + +/* This function converts the line code used to the final data representation. + * The representation is put inside 'buf', for up to 'buflen' bytes of total + * data. For instance in order to convert manchester I can use "10" and "01" + * as zero and one patterns. It is possible to use "?" inside patterns in + * order to skip certain bits. For instance certain devices encode data twice, + * with each bit encoded in manchester encoding and then in its reversed + * representation. In such a case I could use "10??" and "01??". + * + * The function returns the number of bits converted. It will stop as soon + * as it finds a pattern that does not match zero or one patterns, or when + * the end of the bitmap pointed by 'bits' is reached (the length is + * specified in bytes by the caller, via the 'len' parameters). + * + * The decoding starts at the specified offset (in bits) 'off'. */ +uint32_t convert_from_line_code(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t off, const char *zero_pattern, const char *one_pattern) +{ + uint32_t decoded = 0; /* Number of bits extracted. */ + len *= 8; /* Convert bytes to bits. */ + while(off < len) { + bool bitval; + if (bitmap_match_bits(bits,len,off,zero_pattern)) { + bitval = false; + off += strlen(zero_pattern); + } else if (bitmap_match_bits(bits,len,off,one_pattern)) { + bitval = true; + off += strlen(one_pattern); + } else { + break; + } + bitmap_set(buf,buflen,decoded++,bitval); + if (decoded/8 == buflen) break; /* No space left on target buffer. */ + } + return decoded; +} + +/* Supported protocols go here, with the relevant implementation inside + * protocols/.c */ + +extern ProtoViewDecoder Oregon2Decoder; +extern ProtoViewDecoder B4B1Decoder; +extern ProtoViewDecoder RenaultTPMSDecoder; + +ProtoViewDecoder *Decoders[] = { + &Oregon2Decoder, /* Oregon sensors v2.1 protocol. */ + &B4B1Decoder, /* PT, SC, ... 24 bits remotes. */ + &RenaultTPMSDecoder, /* Renault TPMS. */ + NULL +}; + +/* Reset the message info structure before passing it to the decoding + * functions. */ +void initialize_msg_info(ProtoViewMsgInfo *i) { + memset(i,0,sizeof(ProtoViewMsgInfo)); +} + +/* This function is called when a new signal is detected. It converts it + * to a bitstream, and the calls the protocol specific functions for + * decoding. If the signal was decoded correctly by some protocol, true + * is returned. Otherwise false is returned. */ +bool decode_signal(RawSamplesBuffer *s, uint64_t len, ProtoViewMsgInfo *info) { + uint32_t bitmap_bits_size = 4096*8; + uint32_t bitmap_size = bitmap_bits_size/8; + + /* We call the decoders with an offset a few bits before the actual + * signal detected and for a len of a few bits after its end. */ + uint32_t before_after_bits = 2; + + uint8_t *bitmap = malloc(bitmap_size); + uint32_t bits = convert_signal_to_bits(bitmap,bitmap_size,s,-before_after_bits,len+before_after_bits*2,s->short_pulse_dur); + + if (DEBUG_MSG) { /* Useful for debugging purposes. Don't remove. */ + char *str = malloc(1024); + uint32_t j; + for (j = 0; j < bits && j < 1023; j++) { + str[j] = bitmap_get(bitmap,bitmap_size,j) ? '1' : '0'; + } + str[j] = 0; + FURI_LOG_E(TAG, "%lu bits sampled: %s", bits, str); + free(str); + } + + /* Try all the decoders available. */ + int j = 0; + + bool decoded = false; + while(Decoders[j]) { + uint32_t start_time = furi_get_tick(); + decoded = Decoders[j]->decode(bitmap,bitmap_size,bits,info); + uint32_t delta = furi_get_tick() - start_time; + FURI_LOG_E(TAG, "Decoder %s took %lu ms", + Decoders[j]->name, (unsigned long)delta); + if (decoded) break; + j++; + } + + if (!decoded) { + FURI_LOG_E(TAG, "No decoding possible"); + } else { + FURI_LOG_E(TAG, "Decoded %s, raw=%s info=[%s,%s,%s]", info->name, info->raw, info->info1, info->info2, info->info3); + } + free(bitmap); + return decoded; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/ui.c b/Applications/Official/DEV_FW/source/xMasterX/protoview/ui.c new file mode 100644 index 000000000..e22e4d57e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/ui.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved + * See the LICENSE file for information about the license. */ + +#include "app.h" + +void canvas_draw_str_with_border(Canvas* canvas, uint8_t x, uint8_t y, const char* str, Color text_color, Color border_color) +{ + struct { + uint8_t x; uint8_t y; + } dir[8] = { + {-1,-1}, + {0,-1}, + {1,-1}, + {1,0}, + {1,1}, + {0,1}, + {-1,1}, + {-1,0} + }; + + /* Rotate in all the directions writing the same string to create a + * border, then write the actual string in the other color in the + * middle. */ + canvas_set_color(canvas, border_color); + for (int j = 0; j < 8; j++) + canvas_draw_str(canvas,x+dir[j].x,y+dir[j].y,str); + canvas_set_color(canvas, text_color); + canvas_draw_str(canvas,x,y,str); + canvas_set_color(canvas, ColorBlack); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/view_info.c b/Applications/Official/DEV_FW/source/xMasterX/protoview/view_info.c new file mode 100644 index 000000000..fff9c836e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/view_info.c @@ -0,0 +1,41 @@ +/* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved + * See the LICENSE file for information about the license. */ + +#include "app.h" + +/* Renders the view with the detected message information. */ +void render_view_info(Canvas *const canvas, ProtoViewApp *app) { + if (app->signal_decoded == false) { + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 30,36,"No signal decoded"); + return; + } + + /* Protocol name as title. */ + canvas_set_font(canvas, FontPrimary); + uint8_t y = 8, lineheight = 10; + canvas_draw_str(canvas, 0, y, app->signal_info.name); + y += lineheight; + + /* Info fields. */ + char buf[128]; + canvas_set_font(canvas, FontSecondary); + if (app->signal_info.raw[0]) { + snprintf(buf,sizeof(buf),"Raw: %s", app->signal_info.raw); + canvas_draw_str(canvas, 0, y, buf); + y += lineheight; + } + canvas_draw_str(canvas, 0, y, app->signal_info.info1); + y += lineheight; + canvas_draw_str(canvas, 0, y, app->signal_info.info2); + y += lineheight; + canvas_draw_str(canvas, 0, y, app->signal_info.info3); + y += lineheight; +} + +/* Handle input for the settings view. */ +void process_input_info(ProtoViewApp *app, InputEvent input) { + UNUSED(app); + UNUSED(input); + return; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/view_raw_signal.c b/Applications/Official/DEV_FW/source/xMasterX/protoview/view_raw_signal.c new file mode 100644 index 000000000..58d23e8ee --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/view_raw_signal.c @@ -0,0 +1,97 @@ +/* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved + * See the LICENSE file for information about the license. */ + +#include "app.h" + +/* Render the received signal. + * + * The screen of the flipper is 128 x 64. Even using 4 pixels per line + * (where low level signal is one pixel high, high level is 4 pixels + * high) and 4 pixels of spacing between the different lines, we can + * plot comfortably 8 lines. + * + * The 'idx' argument is the first sample to render in the circular + * buffer. */ +void render_signal(ProtoViewApp *app, Canvas *const canvas, RawSamplesBuffer *buf, uint32_t idx) { + canvas_set_color(canvas, ColorBlack); + + int rows = 8; + uint32_t time_per_pixel = app->us_scale; + uint32_t start_idx = idx; + bool level = 0; + uint32_t dur = 0, sample_num = 0; + for (int row = 0; row < rows ; row++) { + for (int x = 0; x < 128; x++) { + int y = 3 + row*8; + if (dur < time_per_pixel/2) { + /* Get more data. */ + raw_samples_get(buf, idx++, &level, &dur); + sample_num++; + } + + canvas_draw_line(canvas, x,y,x,y-(level*3)); + + /* Write a small triangle under the last sample detected. */ + if (app->signal_bestlen != 0 && + sample_num+start_idx == app->signal_bestlen+1) + { + canvas_draw_dot(canvas,x,y+2); + canvas_draw_dot(canvas,x-1,y+3); + canvas_draw_dot(canvas,x,y+3); + canvas_draw_dot(canvas,x+1,y+3); + sample_num++; /* Make sure we don't mark the next, too. */ + } + + /* Remove from the current level duration the time we + * just plot. */ + if (dur > time_per_pixel) + dur -= time_per_pixel; + else + dur = 0; + } + } +} + +/* Raw pulses rendering. This is our default view. */ +void render_view_raw_pulses(Canvas *const canvas, ProtoViewApp *app) { + /* Show signal. */ + render_signal(app, canvas, DetectedSamples, app->signal_offset); + + /* Show signal information. */ + char buf[64]; + snprintf(buf,sizeof(buf),"%luus", + (unsigned long)DetectedSamples->short_pulse_dur); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_with_border(canvas, 97, 63, buf, ColorWhite, ColorBlack); + if (app->signal_decoded) { + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_with_border(canvas, 1, 61, app->signal_info.name, ColorWhite, ColorBlack); + } +} + +/* Handle input for the raw pulses view. */ +void process_input_raw_pulses(ProtoViewApp *app, InputEvent input) { + if (input.type == InputTypeRepeat) { + /* Handle panning of the signal window. Long pressing + * right will show successive samples, long pressing left + * previous samples. */ + if (input.key == InputKeyRight) app->signal_offset++; + else if (input.key == InputKeyLeft) app->signal_offset--; + else if (input.key == InputKeyOk) { + app->signal_offset = 0; + app->us_scale = PROTOVIEW_RAW_VIEW_DEFAULT_SCALE; + } + } else if (input.type == InputTypeShort) { + if (input.key == InputKeyOk) { + /* Reset the current sample to capture the next. */ + reset_current_signal(app); + } else if (input.key == InputKeyDown) { + /* Rescaling. The set becomes finer under 50us per pixel. */ + uint32_t scale_step = app->us_scale >= 50 ? 50 : 10; + if (app->us_scale < 500) app->us_scale += scale_step; + } else if (input.key == InputKeyUp) { + uint32_t scale_step = app->us_scale > 50 ? 50 : 10; + if (app->us_scale > 10) app->us_scale -= scale_step; + } + } +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/protoview/view_settings.c b/Applications/Official/DEV_FW/source/xMasterX/protoview/view_settings.c new file mode 100644 index 000000000..3a06e61b3 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/protoview/view_settings.c @@ -0,0 +1,93 @@ +/* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved + * See the LICENSE file for information about the license. */ + +#include "app.h" + +/* Renders a single view with frequency and modulation setting. However + * this are logically two different views, and only one of the settings + * will be highlighted. */ +void render_view_settings(Canvas *const canvas, ProtoViewApp *app) { + canvas_set_font(canvas, FontPrimary); + if (app->current_view == ViewFrequencySettings) + canvas_draw_str_with_border(canvas,1,10,"Frequency",ColorWhite,ColorBlack); + else + canvas_draw_str(canvas,1,10,"Frequency"); + + if (app->current_view == ViewModulationSettings) + canvas_draw_str_with_border(canvas,70,10,"Modulation",ColorWhite,ColorBlack); + else + canvas_draw_str(canvas,70,10,"Modulation"); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas,10,61,"Use up and down to modify"); + + /* Show frequency. We can use big numbers font since it's just a number. */ + if (app->current_view == ViewFrequencySettings) { + char buf[16]; + snprintf(buf,sizeof(buf),"%.2f",(double)app->frequency/1000000); + canvas_set_font(canvas, FontBigNumbers); + canvas_draw_str(canvas, 30, 40, buf); + } else if (app->current_view == ViewModulationSettings) { + int current = app->modulation; + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 33, 39, ProtoViewModulations[current].name); + } +} + +/* Handle input for the settings view. */ +void process_input_settings(ProtoViewApp *app, InputEvent input) { + if (input.type == InputTypeLong && input.key == InputKeyOk) { + /* Long pressing to OK sets the default frequency and + * modulation. */ + app->frequency = subghz_setting_get_default_frequency(app->setting); + app->modulation = 0; + } else if (input.type == InputTypePress && + (input.key != InputKeyDown || input.key != InputKeyUp)) + { + /* Handle up and down to change frequency or modulation. */ + if (app->current_view == ViewFrequencySettings) { + size_t curidx = 0, i; + size_t count = subghz_setting_get_frequency_count(app->setting); + + /* Scan the list of frequencies to check for the index of the + * currently set frequency. */ + for(i = 0; i < count; i++) { + uint32_t freq = subghz_setting_get_frequency(app->setting,i); + if (freq == app->frequency) { + curidx = i; + break; + } + } + if (i == count) return; /* Should never happen. */ + + if (input.key == InputKeyUp) { + curidx = (curidx+1) % count; + } else if (input.key == InputKeyDown) { + curidx = curidx == 0 ? count-1 : curidx-1; + } else { + return; + } + app->frequency = subghz_setting_get_frequency(app->setting,curidx); + } else if (app->current_view == ViewModulationSettings) { + uint32_t count = 0; + uint32_t modid = app->modulation; + + while(ProtoViewModulations[count].name != NULL) count++; + if (input.key == InputKeyUp) { + modid = (modid+1) % count; + } else if (input.key == InputKeyDown) { + modid = modid == 0 ? count-1 : modid-1; + } else { + return; + } + app->modulation = modid; + } + } else { + return; + } + + /* Apply changes. */ + FURI_LOG_E(TAG, "Setting view, setting frequency/modulation to %lu %s", app->frequency, ProtoViewModulations[app->modulation].name); + radio_rx_end(app); + radio_begin(app); + radio_rx(app); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/.gitignore b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/.gitignore new file mode 100644 index 000000000..c6127b38c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/.gitignore @@ -0,0 +1,52 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/LICENSE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/README.md b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/README.md new file mode 100644 index 000000000..0667860e7 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/README.md @@ -0,0 +1,38 @@ +# RC2014 ColecoVision Controller for Flipper Zero + +A Flipper Zero application and [RC2014] module allowing the Flipper to be used as a controller for ColecoVision games on +the [RC2014]. + +![ui](ui.png) + +## Running ColecoVision Games on the RC2014 + +A full tutorial is out of scope here, but briefly, you will need a [RC2014] with J. B. Langston's [TMS9918A Video Card] +and [SN76489 Sound Card], as well as some way to launch ColecoVision ROMs. + +Note that if you're using the standard pageable ROM module (e.g. if you're using the stock Pro kit), you will need to +[modify it](https://github.com/jblang/TMS9918A/issues/12) in order for the TMS9918A module to work on the ColecoVision +port addresses. + +## Hardware Setup + +The [interface](interface) directory contains Eagle schematics for a RC2014 module that handles the controller port +addressing for two players, breaking out the 8 data line inputs as well as the mode select line. This can actually be +used for different controller implementations and is slightly more flexible than the actual [ColecoVision] spec. + +To use this with the Flipper Zero and this application, a GPIO board is needed to provide hardware multiplexing for the +data lines. A schematic for the GPIO board will be added to this repository soon. + +## Building the FAP + +1. Clone the [flipperzero-firmware] repository. +2. Create a symbolic link in `applications_user` named `coleco`, pointing to this repository. +3. Compile with `./fbt fap_coleco`. +4. Copy `build/f7-firmware-D/.extapps/coleco.fap` to `apps/Misc` on the SD card (directly or using [qFlipper]). + +[RC2014]: https://rc2014.co.uk/ +[TMS9918A Video Card]: https://github.com/jblang/TMS9918A +[SN76489 Sound Card]: https://github.com/jblang/SN76489 +[ColecoVision]: http://www.atarihq.com/danb/files/CV-Tech.txt +[flipperzero-firmware]: https://github.com/flipperdevices/flipperzero-firmware +[qFlipper]: https://flipperzero.one/update diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/application.fam b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/application.fam new file mode 100644 index 000000000..105797865 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/application.fam @@ -0,0 +1,13 @@ +App( + appid="coleco", + name="RC2014 ColecoVision", + apptype=FlipperAppType.EXTERNAL, + entry_point="coleco_app", + cdefines=["APP_COLECO"], + requires=["gui"], + stack_size=1 * 1024, + order=35, + fap_icon="coleco_10px.png", + fap_icon_assets="icons", + fap_category="GPIO_Extra", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/coleco.c b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/coleco.c new file mode 100644 index 000000000..2ba78858d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/coleco.c @@ -0,0 +1,366 @@ +#include +#include +#include +#include +#include "coleco_icons.h" + +#define CODE_0 0x0A +#define CODE_1 0x0D +#define CODE_2 0x07 +#define CODE_3 0x0C +#define CODE_4 0x02 +#define CODE_5 0x03 +#define CODE_6 0x0E +#define CODE_7 0x05 +#define CODE_8 0x01 +#define CODE_9 0x0B +#define CODE_H 0x06 +#define CODE_S 0x09 +#define CODE_N 0x0F + +const GpioPin* const pin_up = &gpio_ext_pa6; +const GpioPin* const pin_down = &gpio_ext_pc0; +const GpioPin* const pin_right = &gpio_ext_pb2; +const GpioPin* const pin_left = &gpio_ext_pc3; +const GpioPin* const pin_code0 = &gpio_ext_pa7; +const GpioPin* const pin_code1 = &gpio_ext_pa4; +const GpioPin* const pin_code2 = &ibutton_gpio; +const GpioPin* const pin_code3 = &gpio_ext_pc1; +const GpioPin* const pin_fire = &gpio_ext_pb3; +const GpioPin* const pin_alt = &gpio_usart_tx; + +typedef enum { + EventTypeTick, + EventTypeKey, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} PluginEvent; + +typedef struct { + bool dpad; + int row; + int column; +} Coleco; + +static void render_callback(Canvas* const canvas, void* context) { + Coleco* coleco = acquire_mutex((ValueMutex*)context, 25); + if(coleco == NULL) { + return; + } + + if(coleco->dpad) { + canvas_draw_icon(canvas, 4, 16, &I_ColecoJoystick_sel_33x33); + canvas_draw_icon(canvas, 27, 52, &I_ColecoFire_sel_18x9); + } else { + const bool hvr = coleco->row == 0 && coleco->column < 2; + canvas_draw_icon( + canvas, 4, 16, hvr ? &I_ColecoJoystick_hvr_33x33 : &I_ColecoJoystick_33x33); + canvas_draw_icon(canvas, 27, 52, hvr ? &I_ColecoFire_hvr_18x9 : &I_ColecoFire_18x9); + } + + canvas_draw_icon( + canvas, + 27, + 4, + (coleco->row == 0 && coleco->column == 2) ? &I_ColecoAlt_hvr_18x9 : &I_ColecoAlt_18x9); + canvas_draw_icon( + canvas, + 49, + 44, + (coleco->row == 1 && coleco->column == 0) ? &I_Coleco1_hvr_17x17 : &I_Coleco1_17x17); + canvas_draw_icon( + canvas, + 49, + 24, + (coleco->row == 1 && coleco->column == 1) ? &I_Coleco2_hvr_17x17 : &I_Coleco2_17x17); + canvas_draw_icon( + canvas, + 49, + 4, + (coleco->row == 1 && coleco->column == 2) ? &I_Coleco3_hvr_17x17 : &I_Coleco3_17x17); + canvas_draw_icon( + canvas, + 69, + 44, + (coleco->row == 2 && coleco->column == 0) ? &I_Coleco4_hvr_17x17 : &I_Coleco4_17x17); + canvas_draw_icon( + canvas, + 69, + 24, + (coleco->row == 2 && coleco->column == 1) ? &I_Coleco5_hvr_17x17 : &I_Coleco5_17x17); + canvas_draw_icon( + canvas, + 69, + 4, + (coleco->row == 2 && coleco->column == 2) ? &I_Coleco6_hvr_17x17 : &I_Coleco6_17x17); + canvas_draw_icon( + canvas, + 89, + 44, + (coleco->row == 3 && coleco->column == 0) ? &I_Coleco7_hvr_17x17 : &I_Coleco7_17x17); + canvas_draw_icon( + canvas, + 89, + 24, + (coleco->row == 3 && coleco->column == 1) ? &I_Coleco8_hvr_17x17 : &I_Coleco8_17x17); + canvas_draw_icon( + canvas, + 89, + 4, + (coleco->row == 3 && coleco->column == 2) ? &I_Coleco9_hvr_17x17 : &I_Coleco9_17x17); + canvas_draw_icon( + canvas, + 109, + 44, + (coleco->row == 4 && coleco->column == 0) ? &I_ColecoStar_hvr_17x17 : &I_ColecoStar_17x17); + canvas_draw_icon( + canvas, + 109, + 24, + (coleco->row == 4 && coleco->column == 1) ? &I_Coleco0_hvr_17x17 : &I_Coleco0_17x17); + canvas_draw_icon( + canvas, + 109, + 4, + (coleco->row == 4 && coleco->column == 2) ? &I_ColecoPound_hvr_17x17 : + &I_ColecoPound_17x17); + + release_mutex((ValueMutex*)context, coleco); +} + +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 coleco_write_code(uint8_t code) { + furi_hal_gpio_write(pin_code0, (code & 1)); + furi_hal_gpio_write(pin_code1, (code & 2)); + furi_hal_gpio_write(pin_code2, (code & 4)); + furi_hal_gpio_write(pin_code3, (code & 8)); +} + +static void coleco_gpio_init() { + // configure output pins + furi_hal_gpio_init(pin_up, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + furi_hal_gpio_init(pin_down, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + furi_hal_gpio_init(pin_right, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + furi_hal_gpio_init(pin_left, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + furi_hal_gpio_init(pin_code0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + furi_hal_gpio_init(pin_code1, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + furi_hal_gpio_init(pin_code2, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + furi_hal_gpio_init(pin_code3, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + furi_hal_gpio_init(pin_fire, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + furi_hal_gpio_init(pin_alt, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + + furi_hal_gpio_write(pin_up, true); + furi_hal_gpio_write(pin_down, true); + furi_hal_gpio_write(pin_right, true); + furi_hal_gpio_write(pin_left, true); + furi_hal_gpio_write(pin_fire, true); + furi_hal_gpio_write(pin_alt, true); + + coleco_write_code(CODE_N); +} + +static Coleco* coleco_alloc() { + Coleco* coleco = malloc(sizeof(Coleco)); + + coleco->dpad = false; + coleco->row = 0; + coleco->column = 1; + + return coleco; +} + +static void coleco_free(Coleco* coleco) { + furi_assert(coleco); + + free(coleco); +} + +int32_t coleco_app(void* p) { + UNUSED(p); + + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); + + Coleco* coleco = coleco_alloc(); + + ValueMutex coleco_mutex; + if(!init_mutex(&coleco_mutex, coleco, sizeof(Coleco))) { + FURI_LOG_E("Coleco", "cannot create mutex\r\n"); + coleco_free(coleco); + return 255; + } + + // set system callbacks + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, render_callback, &coleco_mutex); + view_port_input_callback_set(view_port, input_callback, event_queue); + + // open GUI and register view_port + Gui* gui = furi_record_open("gui"); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + coleco_gpio_init(); + furi_hal_power_enable_otg(); + + PluginEvent event; + for(bool processing = true; processing;) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); + + Coleco* coleco = (Coleco*)acquire_mutex_block(&coleco_mutex); + + if(event_status == FuriStatusOk) { + // press events + if(event.type == EventTypeKey) { + switch(event.input.key) { + case InputKeyUp: + if(coleco->dpad) { + if(event.input.type == InputTypePress) { + furi_hal_gpio_write(pin_up, false); + } else if(event.input.type == InputTypeRelease) { + furi_hal_gpio_write(pin_up, true); + } + } else { + if(event.input.type == InputTypePress && coleco->column < 2) { + coleco->column++; + coleco_write_code(CODE_N); + } + } + break; + case InputKeyDown: + if(coleco->dpad) { + if(event.input.type == InputTypePress) { + furi_hal_gpio_write(pin_down, false); + } else if(event.input.type == InputTypeRelease) { + furi_hal_gpio_write(pin_down, true); + } + } else { + if(event.input.type == InputTypePress && coleco->column > 0) { + coleco->column--; + coleco_write_code(CODE_N); + } + } + break; + case InputKeyRight: + if(coleco->dpad) { + if(event.input.type == InputTypePress) { + furi_hal_gpio_write(pin_right, false); + } else if(event.input.type == InputTypeRelease) { + furi_hal_gpio_write(pin_right, true); + } + } else { + if(event.input.type == InputTypePress && coleco->row < 4) { + coleco->row++; + coleco_write_code(CODE_N); + } + } + break; + case InputKeyLeft: + if(coleco->dpad) { + if(event.input.type == InputTypePress) { + furi_hal_gpio_write(pin_left, false); + } else if(event.input.type == InputTypeRelease) { + furi_hal_gpio_write(pin_left, true); + } + } else { + if(event.input.type == InputTypePress && coleco->row > 0) { + coleco->row--; + coleco_write_code(CODE_N); + } + } + break; + case InputKeyOk: + if(coleco->dpad) { + if(event.input.type == InputTypePress) { + furi_hal_gpio_write(pin_fire, false); + } else if(event.input.type == InputTypeRelease) { + furi_hal_gpio_write(pin_fire, true); + } + } else { + if(event.input.type == InputTypePress) { + if(coleco->row == 0) { + if(coleco->column == 2) { + furi_hal_gpio_write(pin_alt, false); + } else { + coleco->dpad = true; + } + } else if(coleco->row == 1) { + if(coleco->column == 0) { + coleco_write_code(CODE_1); + } else if(coleco->column == 1) { + coleco_write_code(CODE_2); + } else { + coleco_write_code(CODE_3); + } + } else if(coleco->row == 2) { + if(coleco->column == 0) { + coleco_write_code(CODE_4); + } else if(coleco->column == 1) { + coleco_write_code(CODE_5); + } else { + coleco_write_code(CODE_6); + } + } else if(coleco->row == 3) { + if(coleco->column == 0) { + coleco_write_code(CODE_7); + } else if(coleco->column == 1) { + coleco_write_code(CODE_8); + } else { + coleco_write_code(CODE_9); + } + } else if(coleco->row == 4) { + if(coleco->column == 0) { + coleco_write_code(CODE_S); + } else if(coleco->column == 1) { + coleco_write_code(CODE_0); + } else { + coleco_write_code(CODE_H); + } + } + } + if(event.input.type == InputTypeRelease) { + furi_hal_gpio_write(pin_alt, true); + coleco_write_code(CODE_N); + } + } + break; + case InputKeyBack: + if(event.input.type == InputTypePress) { + if(coleco->dpad) { + coleco->dpad = false; + } else { + processing = false; + } + } + break; + default: + break; + } + + view_port_update(view_port); + } + } else { + FURI_LOG_D("Coleco", "FuriMessageQueue: event timeout"); + } + + release_mutex(&coleco_mutex, coleco); + } + + furi_hal_power_disable_otg(); + + 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); + delete_mutex(&coleco_mutex); + coleco_free(coleco); + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/coleco_10px.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/coleco_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..d51652adc4d0fdd98b55940f3277af1b54cbd4e1 GIT binary patch literal 6667 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 N?QHLAS8fxM{BIwakD~wp literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco0_17x17.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco0_17x17.png new file mode 100644 index 0000000000000000000000000000000000000000..b53bc3b5fac13dad96596296cb434e670c9a7c2f GIT binary patch literal 628 zcmV-)0*n2LP)EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS^3Jy{fg8u*j02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002x$L_t(I%iWYQ4!|G`19KJs|MGR{0xXD>0q_!Ku%(=( zpbA7*YVb|dAwWE_K>LK0(Y-am=@6hX_WPbp4roXH-_FQ*GuR$r=AXPfs3RS=7bWfh O0000EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS^5g}0XbUXk602y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002u#L_t(I%VYfi|NnnRMn(p5!TEX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS@GcOXqp+W!v02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002ixL_t(I%iWZ*5da|!!>kB002ov JPDHLkV1hGr0oVWl literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco1_hvr_17x17.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco1_hvr_17x17.png new file mode 100644 index 0000000000000000000000000000000000000000..562c7e8db8e7f403098c43884f9ecceded2c2788 GIT binary patch literal 618 zcmV-w0+s!VP)EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS@G!_E;zl{I@02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002TsL_t(I%k9#^4Zt7}1HpCr?|Eq;%AJ5u5H4Uo-l!&F zb}9j6aSt2zGeliODxgGEI`@Af-F^EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS@G&P`{&i?=a02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{003G^L_t(I%hi-Y4uCKS1evD)|MGb7q8@~{#wZuUfk}3k zfGQBPr3QO<8UjR%2kJYJp6NXrI1B+!i`Tg%XC$#!jqwiJRskub0!WRmCe&Xu_D5&0 c#_B)W0E|m4Aj8#WegFUf07*qoM6N<$f|PL!ga7~l literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco2_hvr_17x17.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco2_hvr_17x17.png new file mode 100644 index 0000000000000000000000000000000000000000..cac46898140ffdcd3fec2160747761505e01df57 GIT binary patch literal 643 zcmV-}0(||6P)EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS@H4lG_CJX=o02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{003J_L_t(I%k7jg4!|G`#GHu#fB8C9LWm}zbYSRh8Da_N zgh`T_@ivk$Ky1eOAm>0@ChblnzlGMj#c?h@XXWf(?m__dT|f${0D$Ml_Ls>#{k5M! dW&&6LlMA#;B^hC|EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS@H8voQt^@!802y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{003P{L_t(I%iWT@4uDVyLn*oc|I5e0MeiVmI2gMS21@!6 zfTWlL2%VELiKNJQ0pB56mENm?Z4ybh!+p2pbP`)mgcWHzWdh=00000NkvXXu0mjfYUd6E literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco3_hvr_17x17.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco3_hvr_17x17.png new file mode 100644 index 0000000000000000000000000000000000000000..c0015312a9c51c525c24fd235c08bee3ee3be1e9 GIT binary patch literal 640 zcmV-`0)PF9P)EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS@HXWxQ1cv|s02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{003A?L_t(I%k7do4!|%BLZR~guS};(R+RdaX6TT&c`&j8 zN)kz|A_)W_eB{Cg{v%?UX%CV47P{^h$GP-QCw8m!AQLV3Wa%AmYDRcTHJwxYiAX1f aH}h}DvnCcIMF!mf00000)+jEP)EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS@Hy=<6RO$c#02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002`-L_t(I%iWYQ3cxT719c|<|FSZauCa+jA@$^ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco4_hvr_17x17.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco4_hvr_17x17.png new file mode 100644 index 0000000000000000000000000000000000000000..63e0862756c497ab552541f81062790396db47c7 GIT binary patch literal 627 zcmV-(0*w8MP)EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS@I19~4oLB$=02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002u#L_t(I%k7fE3BWK6#B|wzXLW%Dn>wFDZvbHEX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS@J2+Xju8jZy02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{003A?L_t(I%iWa03cxT3Lw%$F|I687momCAZ3m-XJozw* zh$I0~ElI)ERfYg@#De+{q&cl46H^d3l!ElzIAD9b1@H*^Hl55BTRGF7WYXE~?C%Cv a{>cd=uqhsj_4@z-0000EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS^02wPN@3H^@02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002=*L_t(I%jJ^64Zt7_#O_e`U)lXv1X2o8rFwuvu`z&c ztpdoB&`X*&@STwu3A>X8h|vqxYB9@K87wCT(xJ0;dSaK(+3w^=-@ZMmkjcLQ#EBpl T*Xu2B00000NkvXXu0mjfB?St7 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco6_17x17.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco6_17x17.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed3e239c278ad8c34c94c4b08a966143d6981d3 GIT binary patch literal 635 zcmV->0)+jEP)EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS^0USbEDtrI{02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002`-L_t(I%hi-I4uC)i1R3N1zdTpiD2=%dh0+iTHq1gm z6{s}S;>yM%Kpiy@-w`?Ac<%;oivW+tUPn05BqKPzaRevYjyjL?kBgl#wi}rIlLe*H VFB^E+hNA!g002ovPDHLkV1lz{1`q%M literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco6_hvr_17x17.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco6_hvr_17x17.png new file mode 100644 index 0000000000000000000000000000000000000000..4be93b365530e024b72675721821170fb539d703 GIT binary patch literal 634 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 P00000NkvXXu0mjfg8T+8 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco8_hvr_17x17.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco8_hvr_17x17.png new file mode 100644 index 0000000000000000000000000000000000000000..519ac1e9772504594b6b18410a25ea278dc92269 GIT binary patch literal 625 zcmV-%0*?KOP)EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS^1PM~}I?@0D02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002ozL_t(I%VYfi|NnnRMn(p5!TEX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS^1uzutgPQ;V02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{003G^L_t(I%gvHI3cxT7L#2}YU-@K2qj*O2MHuU z1K3t~0QuUqO>FDXg4xGpM0w`|%O896(uqMg-DZKj}CXiqmmg--(2K61#?z c3J+hsongQ!B<;Cv=l}o!07*qoM6N<$f?NCzM*si- literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco9_hvr_17x17.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/Coleco9_hvr_17x17.png new file mode 100644 index 0000000000000000000000000000000000000000..206e0acd9d1461ebf422ccbc94b35a6adf675ab3 GIT binary patch literal 639 zcmV-_0)YLAP)EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS^2Mh_cot^*y02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{0037>L_t(I%k7do4uCKWL!YbO|H@{nR4NGl2{GU;L#+5Y zvTaGs$~FSbq7obQ9h3Y7ttf(@L+aIHJHHo4(kad~lQzz9JH1x`@yGVI^S}Lt$w&)# Z@DH%PB^Scp-U$Ez002ovPDHLkV1i+n4YvRQ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoAlt_18x9.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoAlt_18x9.png new file mode 100644 index 0000000000000000000000000000000000000000..7e6853e52ed287cdb7ebaa1b7612ea7f260a4332 GIT binary patch literal 5677 zcmeHKX;>3i7ao+d$)+F(0>;p?2uUUhWRu7iHfxZwC~IX%CJSUE2_#aetRhfxX>mcZ zpe(iG4r);mst9f@3WAD)s0EQvv@HsX_)UWA^YxF<^Yx#}Gs(=k=e*~f_nv$2nY^Gt zKLb5WJpcd<0{j`l$p0MV($&#Ie%F9O*Y;B+H#N&IFOp~QyUNb^oj`jttbE}6#$N~yS6*0bFf(HGF`}{(*>_oovb57#tS6Hkf>5f?{V5_pS z;;=o-&TscQmHAUTP#*QeuFilzT*>BzyHdZ!Cpg@>#Y?TY8F6Rg%7lE7oV(9jB>UBD zQWPhG!={`UTu)Hw%TIxWlc_}6jpeCPqnnp@hql-Dp6+h1>NtdsFv3ofhQY)oWid9+ zt>4;gby)u7W_oU-PqfBgrsJVuUpQgzQRCM>i;0R!x*Bsl!Yl^pkg_~4M6bJ2t#9lo z&6vewHCHSy$g3;{1|6>DR^K%#*mdnZHKxNeEI4eBV}gEV)sJb)j(rB-El3D>)Ch-1 zYnX57(luS`J@rkgg=t6HkHdD2%}K8<>MR|G?5=2N*%k2(HkH&E|{O%l?)dFP9DLs04XIXl3p_9iE*Yn<1)rObXFWJovNj~-K z?6CD;IfsZfZ!&&FZK*Y!vL!X-ZYH+U22YuoN6RnFcVDsV`GB7?Fz#Hw2@aj{0Dj?mTYO(rS!F8+=((hbhmv@KTB@|}9URXqdwxL~im zufh&g#$~KrRk7AGA-=A$s91Pl!VXi@6P&v*>6%b+TTy0{GV(A~cuuMc(AoDp-lJ||V3#-EfwzOx zJ+}AuibBe(LeZDd@cF()e%^KFMKAZ>vh5mPr+^n7+j18bW>H;_Rf=i5ysn%+YA_H# z8o}-iGb~$Zg)Y#{eXhrhdcqp>ZG~L;zR?e@PZu22;nFot7ac#aS@Te?esI{BL7KEm z5Ix*+DCxKF<`d>SmQX8#P?aJx-|Q`$au;tooQ#Pj6bVGt_UNKV4vxhm&EB}6*?*lZ z+h4pcGhvVOVNQ5Q!|AI`8p$i*Ld#|SjY^iqb(5j_TlQpOb^qYcuLuv?T%+%Mu6u&y zQqIUbZByE*n~=G?9<_eEeR<;zty+}OBkL%4qw(%->G4^as}-f-!|X3C?7^CGjgfR8 z^SXLg0al*YY!);0q7YNpK4u;Dcgt@}paL6ex4odlcJM_uCgpzg&xd?A?0jT$Y^d$) zr%A_n?K!{hUXAvU`^_K8)bq_VJ8Tvkb9UaMi@;h?&Lw zuJK;y-H}eUwy$z~nNRnA+0$v<5*|$4n;$c9{|607Cpo#n+~UtR^QPma#+$;1%|2oULT5Vzm=la`n*E1)LIG+0etHel>MCX8)T*oY*57G5+hyy8C+iEw=B3;+axXTWT%T@UU4`RK-1DfKILlo= zqw?CTnl;=17$z|*`9==POB%ekvD%sKTKXAP-6*AQgBG|(>P zeBZ1w6cYc~I^9g8Z*jxlBYhI!#rmSxg3=9Eu{)ASfu3gr*?FP1P3JR{oG~~xGuNoRV}-)fbzf1% zP_o?>6N0T%hTwka)3m|Pjtt>VYVGx}IZ?L?x8GQI`;KB9?$(I^S?9Xpeah?+>lVx} z6K$HL$SZ+CtiGrEojn=V*jYV28P2iV)la#%8Kfiiw_X-5=HdSI>CR3&YaV0r%wUzA z*+Wk4aE1Dw__SG##MBRM&pLg{oGv@0nApuVe1={1_r=WA99#fp9lM#>r8o|(9(>Yx*D4zR%);G zG@b+!<O(V}KCA}LI&utW=K-r48;x4=vuTE%p505X2n45KQ$P@6eKM!*( zWSf6V9~`gC-EdIx&8`P&kJ~!-aWGorjDZNwHqukAr+-%pC3ox%k7icS`PpPcvD|aO z?|>8bOkyiJynj1HEZS*rXi_jiT5)sR+-2*P`IO!9vxxQ<>}HSglE z)1~MtYBt5}u%<5BG&G2zOWIvCTpsR!_4~_b-Fu#VeLuJ*Ow+b`#>I9Nd9r`alao0MO-Vxlgs>b!DTM-&jHaZc z)wnd|UM0q%QEC-=0v#RB3_^K}r7+3`>w*O_K1zNv0lh>IxA6%jOy)ayk?ai%2p>2lB*EdaAWkU6eP|(*`y?YEZvy&93t1@AiQ$4_ znK((xf_;)dd(f&-DM92Q7~ zFjNxW1>*ujEKD4pNWrivAcYL!NohyfkFj4w)3z8?tX3*itsq+%0KB9Tc13g`+F@nout>wBdYuvCUrq6!laVu{nZ zs%fDi$soi+syamg)D}oCG;b*k$;Hx8u~nO%@vifpH)PjsHt@PI2HvD zR`CQPYa5TpfUcn+fd+y!SHy!0a)ZXbNf@VE)o(L)!~G8@Zfb=OwgJR$T83;d$Zmyu zw_UyAOhx0r_<1uI|Dp#3`m>Wy;`cLMpXvG}20lsob9H^D>ysGxB<0W5^?##F@BIr8 zEJC^<1@b!cP_MiZc@@%%``V8IyjFcnPgnhjNOUFs5i$V4+Nv%MWrce(BGi@#FnzTD znDvDgKu9mC$08yNxlg#M^m&@h? zDC6`X$?Fn4CG+{RU|!#%q8*FeM)iUt^vB9_H+q<~YbEvS>rt}YtPndOz$cJ#z$-TM Ezi(x=HUIzs literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoAlt_hvr_18x9.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoAlt_hvr_18x9.png new file mode 100644 index 0000000000000000000000000000000000000000..6b15dcf7b4089e4a0f3b9706d1e10e7be486030d GIT binary patch literal 5037 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoFire_18x9.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoFire_18x9.png new file mode 100644 index 0000000000000000000000000000000000000000..8be499c21d1f0a2443de5ed18b200c3adbf5a8c2 GIT binary patch literal 5660 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoFire_hvr_18x9.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoFire_hvr_18x9.png new file mode 100644 index 0000000000000000000000000000000000000000..2b0d1d72cab82d36f37803f9c250ec6842a2fe3a GIT binary patch literal 5044 zcmeHKX;>5I79NX&tkwll++wg;3X@EBl1qe05K;jlAOxk>Niu-|Sx5#FXc5<9trhnw zDz#cbEuw61lbDw_(JeI1$-c6f!~GYj-{IGldBcaVxzRD}2uJBhm81*vZK$-iYo#vKDe8;tShAHXW?Ia zn3G~NRa2k)#a5*c9?z`1a_!M3k0(#k_7B`{O@GmFv?PuAbIxZcTOPSN{%|Z~oll8F z?~1z*%JUS{YL9J|Q7oh`o%n5+%`Z2a zT?yv+ebl()y#e|}kl2o+~74X}7p zjOglBq-fPbxz_xG$a3Q>k(tD=qdEc?wpBN_+uWOcf=F5Kf8ZeR00lX=%N%y?i!fAE(1ECrDL45|dus8>GyP5X1AuB(OcFR!S`PM7UwvJ4nBVH zWpi*mvRQN0THUqq(ND>~yh`yJ`_m5O{Am}?K09s;LE|>cy}g43-rg@~2#9bnWe3;q zoY(C0pN7QxxY{MYAAc$6kX!#I_Za&vLG$aaPIC4|zL*f;xO19=Z+UTZ^F?t(`T2-& zi*VligHSxK5#l?h3}2tNqC&53OxN|z)pbGNg^4p7DCW@yg>x%~awx)n!>Ri`$ZO#R zOg2-ybNAYN{f4ykQ@Y^Hwv^7=Yd^?f^M3x_2-!Ynk9p72Y=ydMpGVVXMY$H6v77oFCjzpy(p;DC?Bk2`t&=e5l;i*@nl2{BUh_NWS zl1uD5TS_FzrCee-BLE3ddt=dZzhn&-k{lQ+Nsg7Ur9{s~Rvvl|08n5!O3*9flv<9S zOElqfz_n3KCK600cr2GF3J4;2t27vaPNI_#*heo_-=lAt&gmjMSZ z(O<4i(7#rM$`x1$jvCpdFqteS)g7TRSS&U|9pfE_X|$jdjhGaKL>tiRX_98@wAM2jY3Qd1z{H=>e6qsk}@?C;TrdMTIx&012=X5tqT>m6Nh#lTw`zw5658(mhfA9ye&I0fmz{TLXBUuIs{JCg5JYk^e#YsuJQIP?0v81MShQPDFo&ET!kLXgG!yp` z;od5R@!SlVj&qolpp)a#1mkfoe4U*GFd_>0ywDG8CDPTa`)j=>lvQ|rfW%zgPQO2# gTDj}m@bK_VXkDCzwcmQ1YG4fsd;2NNWUCG( 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 MVI8GpO+ftr0oA05c>n+a literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoJoystick_33x33.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoJoystick_33x33.png new file mode 100644 index 0000000000000000000000000000000000000000..de4c574bc566ce45a127b5a8cd45f2a6e36e165e GIT binary patch literal 737 zcmV<70v`Q|P)EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv0RI600RN!9r;`8x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS^9xg}Jbz%Sj02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{006m3L_t(o!|j;S4uBvCMd7ah|7Ch=vnGlR$OnCD%kaR> zd67j#XmK#J`pyxKu84)Tc~+pyv-l`@JO6o}!SF~9Pgb7qRS0VqD==CtWCOHuwEqg( z02UBb0L(y81uy~uZ7@(-1+5zURO0W!L?o3`^mgNs<3Jn;6=HVGW^YdsIdZ%qswMdz zn0v`lRgIo)z=|Qwa@|;U#u>IB9*Z8`ckJDPMf9T91lW2t;E^V*EAIu2zMr@Ok9&(O Ty&Qfz00000NkvXXu0mjfWUxIm literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoJoystick_hvr_33x33.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoJoystick_hvr_33x33.png new file mode 100644 index 0000000000000000000000000000000000000000..fd653bfaf6567a37c890658371f6eb1f81c03b28 GIT binary patch literal 763 zcmVEX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv0RI600RN!9r;`8x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS^A2g$_y;%SN02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{007fTL_t(o!|j+s4#Xe`Md7FSzcO7lnK6LKpu?i9niSy) zNJJJ9p+#Y4^IyUoT@{Wky(rL?aqb!a)PKHbFzlrxv#ZQ{6T;iYYE8@{qC!}UqIKb| zRUtEX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iT97%B?IwT%D(02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{007`gL_t(o!_An%4#Xe`L}B9p|1x{pWaH9;15v%I!*f)m zRWmbLY^wU$N65+O2>diI3xtd)yYgsm3L+Bt0z@m0bWjDzTK}ep4uC3%&bK3b04r^V z#clvE4t4{0@gNs8oN!@wV{{#^%3{z3z`h$IBJk+n#G*i}b5-@Ui4DfH2inrccexRvn0{sZ}j>*je4q(Y3GT2W&nVhl*eK3OE|0g~>)|WicM|_X~0000EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS^5)Y>cDlh;502y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002r!L_t(I%hi-I4getx!;*^sf7uKtHUt&iK(l1?;8Zn$ zZJh>?zvdWXTcICP1Tuv0#77pe0>x^&Sr--imXi#i(8Xrc0NwtR4nn9Y8=T#oo&W#< M07*qoM6N<$f{<(i@Bjb+ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoPound_hvr_17x17.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoPound_hvr_17x17.png new file mode 100644 index 0000000000000000000000000000000000000000..784f3687c51039ae130df62e602bfc0c24c158f2 GIT binary patch literal 625 zcmV-%0*?KOP)EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS^5-D{Bugw4e02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002ozL_t(I%k7jg3IHGs0~7!M=W}vUEQ&fPcuS^)l9n34 zwpIaTNobR#13VG}R2mT$+cQR63@0guR_`wMo=*PRcS1%dJ@Zd8R@ogKiq(MA00000 LNkvXXu0mjfQ0D(g literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoStar_17x17.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoStar_17x17.png new file mode 100644 index 0000000000000000000000000000000000000000..3031c0baf46e20b92df9f208300532c59d2bcb70 GIT binary patch literal 638 zcmV-^0)hRBP)EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS^2^MNqNooK902y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{0034=L_t(I%VYfi|NnnRMn(p5!TWMpJu zVxR&TDTcse44o#)kpKVxqZoiM1_`07*qoM6N<$g7UZsumAu6 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoStar_hvr_17x17.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/icons/ColecoStar_hvr_17x17.png new file mode 100644 index 0000000000000000000000000000000000000000..5469229719694c3bbe03d59c13c8d8f6f33bf7a1 GIT binary patch literal 632 zcmV-;0*C#HP)EX>4Tx04R}tkv&MmKpe$iQ)@*l4t5Z6$WWau_=PxX6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMyc6k5c1aNLh~_a1le0HIc5n$}?$6PyW-SKzMB-Uym^SeS@${x` zaNZ{lvx2M=pA(OobV1@rt}8CTan3hb;F)1Fm7FII6N~vaR@#^qOpSPoIHGDgv}@Jr-U$W;U* z#{$aGAUFKrfAG6oD>pgeCWT@^;Kgx1hJoNNP_H`9_p#&DPXPZjaHY5W0Yqi@Op{kK5(n%i4*AEysMin>bN00)P_ zNS?CSJ>K2b-rK)tn*IF%AX;*UFjVJ-00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_iS^2{5==%$EQF02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002-)L_t(I%k7lG4!|G`Lc#z4=jUn3V!CRoH^-$XD50bV zu&pWpSrXbr(*fKf0)#U{dYv~ht3g{4m^t|r88?@mJVe{|O#ZTMh-9g+{*w+vT__2- SA)b%`0000 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/interface/flipper-coleco.brd b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/interface/flipper-coleco.brd new file mode 100644 index 000000000..47ed27322 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/interface/flipper-coleco.brd @@ -0,0 +1,2554 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +COLECOVISION +INTERFACE +PLAYER 1 +PLAYER 2 +74HCT138 +74HCT00 +74HCT541 +74HCT541 + + + +<b>TTL Devices, 74xx Series with US Symbols</b><p> +Based on the following sources: +<ul> +<li>Texas Instruments <i>TTL Data Book</i>&nbsp;&nbsp;&nbsp;Volume 1, 1996. +<li>TTL Data Book, Volume 2 , 1993 +<li>National Seminconductor Databook 1990, ALS/LS Logic +<li>ttl 74er digital data dictionary, ECA Electronic + Acustic GmbH, ISBN 3-88109-032-0 +<li>http://icmaster.com/ViewCompare.asp +</ul> +<author>Created by librarian@cadsoft.de</author> + + +<b>Dual In Line Package</b> + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>Dual In Line Package</b> + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>Dual In Line Package</b> + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Resistors, Capacitors, Inductors</b><p> +Based on the previous libraries: +<ul> +<li>r.lbr +<li>cap.lbr +<li>cap-fe.lbr +<li>captant.lbr +<li>polcap.lbr +<li>ipc-smd.lbr +</ul> +All SMD packages are defined according to the IPC specifications and CECC<p> +<author>Created by librarian@cadsoft.de</author><p> +<p> +for Electrolyt Capacitors see also :<p> +www.bccomponents.com <p> +www.panasonic.com<p> +www.kemet.com<p> +http://www.secc.co.jp/pdf/os_e/2004/e_os_all.pdf <b>(SANYO)</b> +<p> +for trimmer refence see : <u>www.electrospec-inc.com/cross_references/trimpotcrossref.asp</u><p> + +<table border=0 cellspacing=0 cellpadding=0 width="100%" cellpaddding=0> +<tr valign="top"> + +<! <td width="10">&nbsp;</td> +<td width="90%"> + +<b><font color="#0000FF" size="4">TRIM-POT CROSS REFERENCE</font></b> +<P> +<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2> + <TR> + <TD COLSPAN=8> + <FONT SIZE=3 FACE=ARIAL><B>RECTANGULAR MULTI-TURN</B></FONT> + </TD> + </TR> + <TR> + <TD ALIGN=CENTER> + <B> + <FONT SIZE=3 FACE=ARIAL color="#FF0000">BOURNS</FONT> + </B> + </TD> + <TD ALIGN=CENTER> + <B> + <FONT SIZE=3 FACE=ARIAL color="#FF0000">BI&nbsp;TECH</FONT> + </B> + </TD> + <TD ALIGN=CENTER> + <B> + <FONT SIZE=3 FACE=ARIAL color="#FF0000">DALE-VISHAY</FONT> + </B> + </TD> + <TD ALIGN=CENTER> + <B> + <FONT SIZE=3 FACE=ARIAL color="#FF0000">PHILIPS/MEPCO</FONT> + </B> + </TD> + <TD ALIGN=CENTER> + <B> + <FONT SIZE=3 FACE=ARIAL color="#FF0000">MURATA</FONT> + </B> + </TD> + <TD ALIGN=CENTER> + <B> + <FONT SIZE=3 FACE=ARIAL color="#FF0000">PANASONIC</FONT> + </B> + </TD> + <TD ALIGN=CENTER> + <B> + <FONT SIZE=3 FACE=ARIAL color="#FF0000">SPECTROL</FONT> + </B> + </TD> + <TD ALIGN=CENTER> + <B> + <FONT SIZE=3 FACE=ARIAL color="#FF0000">MILSPEC</FONT> + </B> + </TD><TD>&nbsp;</TD> + </TR> + <TR> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3 > + 3005P<BR> + 3006P<BR> + 3006W<BR> + 3006Y<BR> + 3009P<BR> + 3009W<BR> + 3009Y<BR> + 3057J<BR> + 3057L<BR> + 3057P<BR> + 3057Y<BR> + 3059J<BR> + 3059L<BR> + 3059P<BR> + 3059Y<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + 89P<BR> + 89W<BR> + 89X<BR> + 89PH<BR> + 76P<BR> + 89XH<BR> + 78SLT<BR> + 78L&nbsp;ALT<BR> + 56P&nbsp;ALT<BR> + 78P&nbsp;ALT<BR> + T8S<BR> + 78L<BR> + 56P<BR> + 78P<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + T18/784<BR> + 783<BR> + 781<BR> + -<BR> + -<BR> + -<BR> + 2199<BR> + 1697/1897<BR> + 1680/1880<BR> + 2187<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + 8035EKP/CT20/RJ-20P<BR> + -<BR> + RJ-20X<BR> + -<BR> + -<BR> + -<BR> + 1211L<BR> + 8012EKQ&nbsp;ALT<BR> + 8012EKR&nbsp;ALT<BR> + 1211P<BR> + 8012EKJ<BR> + 8012EKL<BR> + 8012EKQ<BR> + 8012EKR<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + 2101P<BR> + 2101W<BR> + 2101Y<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 2102L<BR> + 2102S<BR> + 2102Y<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + EVMCOG<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + 43P<BR> + 43W<BR> + 43Y<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 40L<BR> + 40P<BR> + 40Y<BR> + 70Y-T602<BR> + 70L<BR> + 70P<BR> + 70Y<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + RT/RTR12<BR> + RT/RTR12<BR> + RT/RTR12<BR> + -<BR> + RJ/RJR12<BR> + RJ/RJR12<BR> + RJ/RJR12<BR></FONT> + </TD> + </TR> + <TR> + <TD COLSPAN=8>&nbsp; + </TD> + </TR> + <TR> + <TD COLSPAN=8> + <FONT SIZE=4 FACE=ARIAL><B>SQUARE MULTI-TURN</B></FONT> + </TD> + </TR> + <TR> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>BOURN</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>BI&nbsp;TECH</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>MURATA</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>SPECTROL</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>MILSPEC</B></FONT> + </TD> + </TR> + <TR> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 3250L<BR> + 3250P<BR> + 3250W<BR> + 3250X<BR> + 3252P<BR> + 3252W<BR> + 3252X<BR> + 3260P<BR> + 3260W<BR> + 3260X<BR> + 3262P<BR> + 3262W<BR> + 3262X<BR> + 3266P<BR> + 3266W<BR> + 3266X<BR> + 3290H<BR> + 3290P<BR> + 3290W<BR> + 3292P<BR> + 3292W<BR> + 3292X<BR> + 3296P<BR> + 3296W<BR> + 3296X<BR> + 3296Y<BR> + 3296Z<BR> + 3299P<BR> + 3299W<BR> + 3299X<BR> + 3299Y<BR> + 3299Z<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + 66P&nbsp;ALT<BR> + 66W&nbsp;ALT<BR> + 66X&nbsp;ALT<BR> + 66P&nbsp;ALT<BR> + 66W&nbsp;ALT<BR> + 66X&nbsp;ALT<BR> + -<BR> + 64W&nbsp;ALT<BR> + -<BR> + 64P&nbsp;ALT<BR> + 64W&nbsp;ALT<BR> + 64X&nbsp;ALT<BR> + 64P<BR> + 64W<BR> + 64X<BR> + 66X&nbsp;ALT<BR> + 66P&nbsp;ALT<BR> + 66W&nbsp;ALT<BR> + 66P<BR> + 66W<BR> + 66X<BR> + 67P<BR> + 67W<BR> + 67X<BR> + 67Y<BR> + 67Z<BR> + 68P<BR> + 68W<BR> + 68X<BR> + 67Y&nbsp;ALT<BR> + 67Z&nbsp;ALT<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 5050<BR> + 5091<BR> + 5080<BR> + 5087<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + T63YB<BR> + T63XB<BR> + -<BR> + -<BR> + -<BR> + 5887<BR> + 5891<BR> + 5880<BR> + -<BR> + -<BR> + -<BR> + T93Z<BR> + T93YA<BR> + T93XA<BR> + T93YB<BR> + T93XB<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 8026EKP<BR> + 8026EKW<BR> + 8026EKM<BR> + 8026EKP<BR> + 8026EKB<BR> + 8026EKM<BR> + 1309X<BR> + 1309P<BR> + 1309W<BR> + 8024EKP<BR> + 8024EKW<BR> + 8024EKN<BR> + RJ-9P/CT9P<BR> + RJ-9W<BR> + RJ-9X<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 3103P<BR> + 3103Y<BR> + 3103Z<BR> + 3103P<BR> + 3103Y<BR> + 3103Z<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 3105P/3106P<BR> + 3105W/3106W<BR> + 3105X/3106X<BR> + 3105Y/3106Y<BR> + 3105Z/3105Z<BR> + 3102P<BR> + 3102W<BR> + 3102X<BR> + 3102Y<BR> + 3102Z<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + EVMCBG<BR> + EVMCCG<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 55-1-X<BR> + 55-4-X<BR> + 55-3-X<BR> + 55-2-X<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 50-2-X<BR> + 50-4-X<BR> + 50-3-X<BR> + -<BR> + -<BR> + -<BR> + 64P<BR> + 64W<BR> + 64X<BR> + 64Y<BR> + 64Z<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + RT/RTR22<BR> + RT/RTR22<BR> + RT/RTR22<BR> + RT/RTR22<BR> + RJ/RJR22<BR> + RJ/RJR22<BR> + RJ/RJR22<BR> + RT/RTR26<BR> + RT/RTR26<BR> + RT/RTR26<BR> + RJ/RJR26<BR> + RJ/RJR26<BR> + RJ/RJR26<BR> + RJ/RJR26<BR> + RJ/RJR26<BR> + RJ/RJR26<BR> + RT/RTR24<BR> + RT/RTR24<BR> + RT/RTR24<BR> + RJ/RJR24<BR> + RJ/RJR24<BR> + RJ/RJR24<BR> + RJ/RJR24<BR> + RJ/RJR24<BR> + RJ/RJR24<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + </TR> + <TR> + <TD COLSPAN=8>&nbsp; + </TD> + </TR> + <TR> + <TD COLSPAN=8> + <FONT SIZE=4 FACE=ARIAL><B>SINGLE TURN</B></FONT> + </TD> + </TR> + <TR> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>BOURN</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>BI&nbsp;TECH</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>MURATA</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>SPECTROL</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>MILSPEC</B></FONT> + </TD> + </TR> + <TR> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 3323P<BR> + 3323S<BR> + 3323W<BR> + 3329H<BR> + 3329P<BR> + 3329W<BR> + 3339H<BR> + 3339P<BR> + 3339W<BR> + 3352E<BR> + 3352H<BR> + 3352K<BR> + 3352P<BR> + 3352T<BR> + 3352V<BR> + 3352W<BR> + 3362H<BR> + 3362M<BR> + 3362P<BR> + 3362R<BR> + 3362S<BR> + 3362U<BR> + 3362W<BR> + 3362X<BR> + 3386B<BR> + 3386C<BR> + 3386F<BR> + 3386H<BR> + 3386K<BR> + 3386M<BR> + 3386P<BR> + 3386S<BR> + 3386W<BR> + 3386X<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 25P<BR> + 25S<BR> + 25RX<BR> + 82P<BR> + 82M<BR> + 82PA<BR> + -<BR> + -<BR> + -<BR> + 91E<BR> + 91X<BR> + 91T<BR> + 91B<BR> + 91A<BR> + 91V<BR> + 91W<BR> + 25W<BR> + 25V<BR> + 25P<BR> + -<BR> + 25S<BR> + 25U<BR> + 25RX<BR> + 25X<BR> + 72XW<BR> + 72XL<BR> + 72PM<BR> + 72RX<BR> + -<BR> + 72PX<BR> + 72P<BR> + 72RXW<BR> + 72RXL<BR> + 72X<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + T7YB<BR> + T7YA<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + TXD<BR> + TYA<BR> + TYP<BR> + -<BR> + TYD<BR> + TX<BR> + -<BR> + 150SX<BR> + 100SX<BR> + 102T<BR> + 101S<BR> + 190T<BR> + 150TX<BR> + 101<BR> + -<BR> + -<BR> + 101SX<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + ET6P<BR> + ET6S<BR> + ET6X<BR> + RJ-6W/8014EMW<BR> + RJ-6P/8014EMP<BR> + RJ-6X/8014EMX<BR> + TM7W<BR> + TM7P<BR> + TM7X<BR> + -<BR> + 8017SMS<BR> + -<BR> + 8017SMB<BR> + 8017SMA<BR> + -<BR> + -<BR> + CT-6W<BR> + CT-6H<BR> + CT-6P<BR> + CT-6R<BR> + -<BR> + CT-6V<BR> + CT-6X<BR> + -<BR> + -<BR> + 8038EKV<BR> + -<BR> + 8038EKX<BR> + -<BR> + -<BR> + 8038EKP<BR> + 8038EKZ<BR> + 8038EKW<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + 3321H<BR> + 3321P<BR> + 3321N<BR> + 1102H<BR> + 1102P<BR> + 1102T<BR> + RVA0911V304A<BR> + -<BR> + RVA0911H413A<BR> + RVG0707V100A<BR> + RVA0607V(H)306A<BR> + RVA1214H213A<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 3104B<BR> + 3104C<BR> + 3104F<BR> + 3104H<BR> + -<BR> + 3104M<BR> + 3104P<BR> + 3104S<BR> + 3104W<BR> + 3104X<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + EVMQ0G<BR> + EVMQIG<BR> + EVMQ3G<BR> + EVMS0G<BR> + EVMQ0G<BR> + EVMG0G<BR> + -<BR> + -<BR> + -<BR> + EVMK4GA00B<BR> + EVM30GA00B<BR> + EVMK0GA00B<BR> + EVM38GA00B<BR> + EVMB6<BR> + EVLQ0<BR> + -<BR> + EVMMSG<BR> + EVMMBG<BR> + EVMMAG<BR> + -<BR> + -<BR> + EVMMCS<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + EVMM1<BR> + -<BR> + -<BR> + EVMM0<BR> + -<BR> + -<BR> + EVMM3<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + 62-3-1<BR> + 62-1-2<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 67R<BR> + -<BR> + 67P<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 67X<BR> + 63V<BR> + 63S<BR> + 63M<BR> + -<BR> + -<BR> + 63H<BR> + 63P<BR> + -<BR> + -<BR> + 63X<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + RJ/RJR50<BR> + RJ/RJR50<BR> + RJ/RJR50<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + </TR> +</TABLE> +<P>&nbsp;<P> +<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=3> + <TR> + <TD COLSPAN=7> + <FONT color="#0000FF" SIZE=4 FACE=ARIAL><B>SMD TRIM-POT CROSS REFERENCE</B></FONT> + <P> + <FONT SIZE=4 FACE=ARIAL><B>MULTI-TURN</B></FONT> + </TD> + </TR> + <TR> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>BOURNS</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>BI&nbsp;TECH</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>TOCOS</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>AUX/KYOCERA</B></FONT> + </TD> + </TR> + <TR> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 3224G<BR> + 3224J<BR> + 3224W<BR> + 3269P<BR> + 3269W<BR> + 3269X<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 44G<BR> + 44J<BR> + 44W<BR> + 84P<BR> + 84W<BR> + 84X<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + ST63Z<BR> + ST63Y<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + ST5P<BR> + ST5W<BR> + ST5X<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + </TR> + <TR> + <TD COLSPAN=7>&nbsp; + </TD> + </TR> + <TR> + <TD COLSPAN=7> + <FONT SIZE=4 FACE=ARIAL><B>SINGLE TURN</B></FONT> + </TD> + </TR> + <TR> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>BOURNS</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>BI&nbsp;TECH</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>TOCOS</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>AUX/KYOCERA</B></FONT> + </TD> + </TR> + <TR> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 3314G<BR> + 3314J<BR> + 3364A/B<BR> + 3364C/D<BR> + 3364W/X<BR> + 3313G<BR> + 3313J<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 23B<BR> + 23A<BR> + 21X<BR> + 21W<BR> + -<BR> + 22B<BR> + 22A<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + ST5YL/ST53YL<BR> + ST5YJ/5T53YJ<BR> + ST-23A<BR> + ST-22B<BR> + ST-22<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + ST-4B<BR> + ST-4A<BR> + -<BR> + -<BR> + -<BR> + ST-3B<BR> + ST-3A<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + EVM-6YS<BR> + EVM-1E<BR> + EVM-1G<BR> + EVM-1D<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + G4B<BR> + G4A<BR> + TR04-3S1<BR> + TRG04-2S1<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + DVR-43A<BR> + CVR-42C<BR> + CVR-42A/C<BR> + -<BR> + -<BR></FONT> + </TD> + </TR> +</TABLE> +<P> +<FONT SIZE=4 FACE=ARIAL><B>ALT =&nbsp;ALTERNATE</B></FONT> +<P> + +&nbsp; +<P> +</td> +</tr> +</table> + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 2.4 x 4.4 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + +<b>Pin Header Connectors</b><p> +<author>Created by librarian@cadsoft.de</author> + + +<b>PIN HEADER</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + +<b>EAGLE Design Rules</b> +<p> +Die Standard-Design-Rules sind so gewählt, dass sie für +die meisten Anwendungen passen. Sollte ihre Platine +besondere Anforderungen haben, treffen Sie die erforderlichen +Einstellungen hier und speichern die Design Rules unter +einem neuen Namen ab. +<b>Laen's PCB Order Design Rules</b> +<p> +Please make sure your boards conform to these design rules. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Since Version 6.2.2 text objects can contain more than one line, +which will not be processed correctly with this version. + + + diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/interface/flipper-coleco.sch b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/interface/flipper-coleco.sch new file mode 100644 index 000000000..c29acd315 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/interface/flipper-coleco.sch @@ -0,0 +1,5482 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>TTL Devices, 74xx Series with US Symbols</b><p> +Based on the following sources: +<ul> +<li>Texas Instruments <i>TTL Data Book</i>&nbsp;&nbsp;&nbsp;Volume 1, 1996. +<li>TTL Data Book, Volume 2 , 1993 +<li>National Seminconductor Databook 1990, ALS/LS Logic +<li>ttl 74er digital data dictionary, ECA Electronic + Acustic GmbH, ISBN 3-88109-032-0 +<li>http://icmaster.com/ViewCompare.asp +</ul> +<author>Created by librarian@cadsoft.de</author> + + +<b>Dual In Line Package</b> + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>Wide Small Outline package</b> 300 mil + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Leadless Chip Carrier</b><p> Ceramic Package + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>Dual In Line Package</b> + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>Small Outline package</b> 150 mil + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + + + + + + + + + + + + + +<b>Dual In Line Package</b> + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>Small Outline package</b> 150 mil + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + +>NAME +GND +VCC + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + +Octal <b>BUFFER</b> and <b>LINE DRIVER</b>, 3-state + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +3-line to 8-line <b>DECODER/DEMULTIPLEXER</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Quad 2-input <b>NAND</b> gate + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +A15 +A0 +M1 +RST +CLK +INT +MREQ +WR +RO +IORQ +D0 +D7 +TX +RX + + +>NAME +GND +VCC + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Pin Header Connectors</b><p> +<author>Created by librarian@cadsoft.de</author> + + +<b>PIN HEADER</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + +<b>PIN HEADER</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + +<b>PIN HEADER</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Supply Symbols</b><p> + GND, VCC, 0V, +5V, -5V, etc.<p> + Please keep in mind, that these devices are necessary for the + automatic wiring of the supply signals.<p> + The pin name defined in the symbol is identical to the net which is to be wired automatically.<p> + In this library the device names are the same as the pin names of the symbols, therefore the correct signal names appear next to the supply symbols in the schematic.<p> + <author>Created by librarian@cadsoft.de</author> + + + + + +>VALUE + + + + + +>VALUE + + + + + +<b>SUPPLY SYMBOL</b> + + + + + + + + + + + + +<b>SUPPLY SYMBOL</b> + + + + + + + + + + + + + + +<b>Resistors, Capacitors, Inductors</b><p> +Based on the previous libraries: +<ul> +<li>r.lbr +<li>cap.lbr +<li>cap-fe.lbr +<li>captant.lbr +<li>polcap.lbr +<li>ipc-smd.lbr +</ul> +All SMD packages are defined according to the IPC specifications and CECC<p> +<author>Created by librarian@cadsoft.de</author><p> +<p> +for Electrolyt Capacitors see also :<p> +www.bccomponents.com <p> +www.panasonic.com<p> +www.kemet.com<p> +http://www.secc.co.jp/pdf/os_e/2004/e_os_all.pdf <b>(SANYO)</b> +<p> +for trimmer refence see : <u>www.electrospec-inc.com/cross_references/trimpotcrossref.asp</u><p> + +<table border=0 cellspacing=0 cellpadding=0 width="100%" cellpaddding=0> +<tr valign="top"> + +<! <td width="10">&nbsp;</td> +<td width="90%"> + +<b><font color="#0000FF" size="4">TRIM-POT CROSS REFERENCE</font></b> +<P> +<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2> + <TR> + <TD COLSPAN=8> + <FONT SIZE=3 FACE=ARIAL><B>RECTANGULAR MULTI-TURN</B></FONT> + </TD> + </TR> + <TR> + <TD ALIGN=CENTER> + <B> + <FONT SIZE=3 FACE=ARIAL color="#FF0000">BOURNS</FONT> + </B> + </TD> + <TD ALIGN=CENTER> + <B> + <FONT SIZE=3 FACE=ARIAL color="#FF0000">BI&nbsp;TECH</FONT> + </B> + </TD> + <TD ALIGN=CENTER> + <B> + <FONT SIZE=3 FACE=ARIAL color="#FF0000">DALE-VISHAY</FONT> + </B> + </TD> + <TD ALIGN=CENTER> + <B> + <FONT SIZE=3 FACE=ARIAL color="#FF0000">PHILIPS/MEPCO</FONT> + </B> + </TD> + <TD ALIGN=CENTER> + <B> + <FONT SIZE=3 FACE=ARIAL color="#FF0000">MURATA</FONT> + </B> + </TD> + <TD ALIGN=CENTER> + <B> + <FONT SIZE=3 FACE=ARIAL color="#FF0000">PANASONIC</FONT> + </B> + </TD> + <TD ALIGN=CENTER> + <B> + <FONT SIZE=3 FACE=ARIAL color="#FF0000">SPECTROL</FONT> + </B> + </TD> + <TD ALIGN=CENTER> + <B> + <FONT SIZE=3 FACE=ARIAL color="#FF0000">MILSPEC</FONT> + </B> + </TD><TD>&nbsp;</TD> + </TR> + <TR> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3 > + 3005P<BR> + 3006P<BR> + 3006W<BR> + 3006Y<BR> + 3009P<BR> + 3009W<BR> + 3009Y<BR> + 3057J<BR> + 3057L<BR> + 3057P<BR> + 3057Y<BR> + 3059J<BR> + 3059L<BR> + 3059P<BR> + 3059Y<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + 89P<BR> + 89W<BR> + 89X<BR> + 89PH<BR> + 76P<BR> + 89XH<BR> + 78SLT<BR> + 78L&nbsp;ALT<BR> + 56P&nbsp;ALT<BR> + 78P&nbsp;ALT<BR> + T8S<BR> + 78L<BR> + 56P<BR> + 78P<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + T18/784<BR> + 783<BR> + 781<BR> + -<BR> + -<BR> + -<BR> + 2199<BR> + 1697/1897<BR> + 1680/1880<BR> + 2187<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + 8035EKP/CT20/RJ-20P<BR> + -<BR> + RJ-20X<BR> + -<BR> + -<BR> + -<BR> + 1211L<BR> + 8012EKQ&nbsp;ALT<BR> + 8012EKR&nbsp;ALT<BR> + 1211P<BR> + 8012EKJ<BR> + 8012EKL<BR> + 8012EKQ<BR> + 8012EKR<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + 2101P<BR> + 2101W<BR> + 2101Y<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 2102L<BR> + 2102S<BR> + 2102Y<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + EVMCOG<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + 43P<BR> + 43W<BR> + 43Y<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 40L<BR> + 40P<BR> + 40Y<BR> + 70Y-T602<BR> + 70L<BR> + 70P<BR> + 70Y<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + RT/RTR12<BR> + RT/RTR12<BR> + RT/RTR12<BR> + -<BR> + RJ/RJR12<BR> + RJ/RJR12<BR> + RJ/RJR12<BR></FONT> + </TD> + </TR> + <TR> + <TD COLSPAN=8>&nbsp; + </TD> + </TR> + <TR> + <TD COLSPAN=8> + <FONT SIZE=4 FACE=ARIAL><B>SQUARE MULTI-TURN</B></FONT> + </TD> + </TR> + <TR> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>BOURN</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>BI&nbsp;TECH</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>MURATA</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>SPECTROL</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>MILSPEC</B></FONT> + </TD> + </TR> + <TR> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 3250L<BR> + 3250P<BR> + 3250W<BR> + 3250X<BR> + 3252P<BR> + 3252W<BR> + 3252X<BR> + 3260P<BR> + 3260W<BR> + 3260X<BR> + 3262P<BR> + 3262W<BR> + 3262X<BR> + 3266P<BR> + 3266W<BR> + 3266X<BR> + 3290H<BR> + 3290P<BR> + 3290W<BR> + 3292P<BR> + 3292W<BR> + 3292X<BR> + 3296P<BR> + 3296W<BR> + 3296X<BR> + 3296Y<BR> + 3296Z<BR> + 3299P<BR> + 3299W<BR> + 3299X<BR> + 3299Y<BR> + 3299Z<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + 66P&nbsp;ALT<BR> + 66W&nbsp;ALT<BR> + 66X&nbsp;ALT<BR> + 66P&nbsp;ALT<BR> + 66W&nbsp;ALT<BR> + 66X&nbsp;ALT<BR> + -<BR> + 64W&nbsp;ALT<BR> + -<BR> + 64P&nbsp;ALT<BR> + 64W&nbsp;ALT<BR> + 64X&nbsp;ALT<BR> + 64P<BR> + 64W<BR> + 64X<BR> + 66X&nbsp;ALT<BR> + 66P&nbsp;ALT<BR> + 66W&nbsp;ALT<BR> + 66P<BR> + 66W<BR> + 66X<BR> + 67P<BR> + 67W<BR> + 67X<BR> + 67Y<BR> + 67Z<BR> + 68P<BR> + 68W<BR> + 68X<BR> + 67Y&nbsp;ALT<BR> + 67Z&nbsp;ALT<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 5050<BR> + 5091<BR> + 5080<BR> + 5087<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + T63YB<BR> + T63XB<BR> + -<BR> + -<BR> + -<BR> + 5887<BR> + 5891<BR> + 5880<BR> + -<BR> + -<BR> + -<BR> + T93Z<BR> + T93YA<BR> + T93XA<BR> + T93YB<BR> + T93XB<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 8026EKP<BR> + 8026EKW<BR> + 8026EKM<BR> + 8026EKP<BR> + 8026EKB<BR> + 8026EKM<BR> + 1309X<BR> + 1309P<BR> + 1309W<BR> + 8024EKP<BR> + 8024EKW<BR> + 8024EKN<BR> + RJ-9P/CT9P<BR> + RJ-9W<BR> + RJ-9X<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 3103P<BR> + 3103Y<BR> + 3103Z<BR> + 3103P<BR> + 3103Y<BR> + 3103Z<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 3105P/3106P<BR> + 3105W/3106W<BR> + 3105X/3106X<BR> + 3105Y/3106Y<BR> + 3105Z/3105Z<BR> + 3102P<BR> + 3102W<BR> + 3102X<BR> + 3102Y<BR> + 3102Z<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + EVMCBG<BR> + EVMCCG<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 55-1-X<BR> + 55-4-X<BR> + 55-3-X<BR> + 55-2-X<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 50-2-X<BR> + 50-4-X<BR> + 50-3-X<BR> + -<BR> + -<BR> + -<BR> + 64P<BR> + 64W<BR> + 64X<BR> + 64Y<BR> + 64Z<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + RT/RTR22<BR> + RT/RTR22<BR> + RT/RTR22<BR> + RT/RTR22<BR> + RJ/RJR22<BR> + RJ/RJR22<BR> + RJ/RJR22<BR> + RT/RTR26<BR> + RT/RTR26<BR> + RT/RTR26<BR> + RJ/RJR26<BR> + RJ/RJR26<BR> + RJ/RJR26<BR> + RJ/RJR26<BR> + RJ/RJR26<BR> + RJ/RJR26<BR> + RT/RTR24<BR> + RT/RTR24<BR> + RT/RTR24<BR> + RJ/RJR24<BR> + RJ/RJR24<BR> + RJ/RJR24<BR> + RJ/RJR24<BR> + RJ/RJR24<BR> + RJ/RJR24<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + </TR> + <TR> + <TD COLSPAN=8>&nbsp; + </TD> + </TR> + <TR> + <TD COLSPAN=8> + <FONT SIZE=4 FACE=ARIAL><B>SINGLE TURN</B></FONT> + </TD> + </TR> + <TR> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>BOURN</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>BI&nbsp;TECH</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>MURATA</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>SPECTROL</B></FONT> + </TD> + <TD ALIGN=CENTER> + <FONT SIZE=3 FACE=ARIAL><B>MILSPEC</B></FONT> + </TD> + </TR> + <TR> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 3323P<BR> + 3323S<BR> + 3323W<BR> + 3329H<BR> + 3329P<BR> + 3329W<BR> + 3339H<BR> + 3339P<BR> + 3339W<BR> + 3352E<BR> + 3352H<BR> + 3352K<BR> + 3352P<BR> + 3352T<BR> + 3352V<BR> + 3352W<BR> + 3362H<BR> + 3362M<BR> + 3362P<BR> + 3362R<BR> + 3362S<BR> + 3362U<BR> + 3362W<BR> + 3362X<BR> + 3386B<BR> + 3386C<BR> + 3386F<BR> + 3386H<BR> + 3386K<BR> + 3386M<BR> + 3386P<BR> + 3386S<BR> + 3386W<BR> + 3386X<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 25P<BR> + 25S<BR> + 25RX<BR> + 82P<BR> + 82M<BR> + 82PA<BR> + -<BR> + -<BR> + -<BR> + 91E<BR> + 91X<BR> + 91T<BR> + 91B<BR> + 91A<BR> + 91V<BR> + 91W<BR> + 25W<BR> + 25V<BR> + 25P<BR> + -<BR> + 25S<BR> + 25U<BR> + 25RX<BR> + 25X<BR> + 72XW<BR> + 72XL<BR> + 72PM<BR> + 72RX<BR> + -<BR> + 72PX<BR> + 72P<BR> + 72RXW<BR> + 72RXL<BR> + 72X<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + T7YB<BR> + T7YA<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + TXD<BR> + TYA<BR> + TYP<BR> + -<BR> + TYD<BR> + TX<BR> + -<BR> + 150SX<BR> + 100SX<BR> + 102T<BR> + 101S<BR> + 190T<BR> + 150TX<BR> + 101<BR> + -<BR> + -<BR> + 101SX<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + ET6P<BR> + ET6S<BR> + ET6X<BR> + RJ-6W/8014EMW<BR> + RJ-6P/8014EMP<BR> + RJ-6X/8014EMX<BR> + TM7W<BR> + TM7P<BR> + TM7X<BR> + -<BR> + 8017SMS<BR> + -<BR> + 8017SMB<BR> + 8017SMA<BR> + -<BR> + -<BR> + CT-6W<BR> + CT-6H<BR> + CT-6P<BR> + CT-6R<BR> + -<BR> + CT-6V<BR> + CT-6X<BR> + -<BR> + -<BR> + 8038EKV<BR> + -<BR> + 8038EKX<BR> + -<BR> + -<BR> + 8038EKP<BR> + 8038EKZ<BR> + 8038EKW<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + 3321H<BR> + 3321P<BR> + 3321N<BR> + 1102H<BR> + 1102P<BR> + 1102T<BR> + RVA0911V304A<BR> + -<BR> + RVA0911H413A<BR> + RVG0707V100A<BR> + RVA0607V(H)306A<BR> + RVA1214H213A<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 3104B<BR> + 3104C<BR> + 3104F<BR> + 3104H<BR> + -<BR> + 3104M<BR> + 3104P<BR> + 3104S<BR> + 3104W<BR> + 3104X<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + EVMQ0G<BR> + EVMQIG<BR> + EVMQ3G<BR> + EVMS0G<BR> + EVMQ0G<BR> + EVMG0G<BR> + -<BR> + -<BR> + -<BR> + EVMK4GA00B<BR> + EVM30GA00B<BR> + EVMK0GA00B<BR> + EVM38GA00B<BR> + EVMB6<BR> + EVLQ0<BR> + -<BR> + EVMMSG<BR> + EVMMBG<BR> + EVMMAG<BR> + -<BR> + -<BR> + EVMMCS<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + EVMM1<BR> + -<BR> + -<BR> + EVMM0<BR> + -<BR> + -<BR> + EVMM3<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + 62-3-1<BR> + 62-1-2<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 67R<BR> + -<BR> + 67P<BR> + -<BR> + -<BR> + -<BR> + -<BR> + 67X<BR> + 63V<BR> + 63S<BR> + 63M<BR> + -<BR> + -<BR> + 63H<BR> + 63P<BR> + -<BR> + -<BR> + 63X<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + RJ/RJR50<BR> + RJ/RJR50<BR> + RJ/RJR50<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + </TR> +</TABLE> +<P>&nbsp;<P> +<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=3> + <TR> + <TD COLSPAN=7> + <FONT color="#0000FF" SIZE=4 FACE=ARIAL><B>SMD TRIM-POT CROSS REFERENCE</B></FONT> + <P> + <FONT SIZE=4 FACE=ARIAL><B>MULTI-TURN</B></FONT> + </TD> + </TR> + <TR> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>BOURNS</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>BI&nbsp;TECH</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>TOCOS</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>AUX/KYOCERA</B></FONT> + </TD> + </TR> + <TR> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 3224G<BR> + 3224J<BR> + 3224W<BR> + 3269P<BR> + 3269W<BR> + 3269X<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 44G<BR> + 44J<BR> + 44W<BR> + 84P<BR> + 84W<BR> + 84X<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + ST63Z<BR> + ST63Y<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + ST5P<BR> + ST5W<BR> + ST5X<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + </TR> + <TR> + <TD COLSPAN=7>&nbsp; + </TD> + </TR> + <TR> + <TD COLSPAN=7> + <FONT SIZE=4 FACE=ARIAL><B>SINGLE TURN</B></FONT> + </TD> + </TR> + <TR> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>BOURNS</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>BI&nbsp;TECH</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>TOCOS</B></FONT> + </TD> + <TD> + <FONT SIZE=3 FACE=ARIAL><B>AUX/KYOCERA</B></FONT> + </TD> + </TR> + <TR> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 3314G<BR> + 3314J<BR> + 3364A/B<BR> + 3364C/D<BR> + 3364W/X<BR> + 3313G<BR> + 3313J<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + 23B<BR> + 23A<BR> + 21X<BR> + 21W<BR> + -<BR> + 22B<BR> + 22A<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + ST5YL/ST53YL<BR> + ST5YJ/5T53YJ<BR> + ST-23A<BR> + ST-22B<BR> + ST-22<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + ST-4B<BR> + ST-4A<BR> + -<BR> + -<BR> + -<BR> + ST-3B<BR> + ST-3A<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + EVM-6YS<BR> + EVM-1E<BR> + EVM-1G<BR> + EVM-1D<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + G4B<BR> + G4A<BR> + TR04-3S1<BR> + TRG04-2S1<BR> + -<BR> + -<BR> + -<BR></FONT> + </TD> + <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> + -<BR> + -<BR> + DVR-43A<BR> + CVR-42C<BR> + CVR-42A/C<BR> + -<BR> + -<BR></FONT> + </TD> + </TR> +</TABLE> +<P> +<FONT SIZE=4 FACE=ARIAL><B>ALT =&nbsp;ALTERNATE</B></FONT> +<P> + +&nbsp; +<P> +</td> +</tr> +</table> + + +<b>CAPACITOR</b> + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b> + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b> + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b> + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b> + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b> + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b> + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b> + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b> + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b> + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b> + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b> + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b> + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b> + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 2.4 x 4.4 mm + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 2.5 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 3 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 4 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 5 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 6 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm + 5 mm, outline 2.4 x 7 mm + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 + 5 mm, outline 2.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 + 5 mm, outline 3.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 + 5 mm, outline 4.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 + 5 mm, outline 5.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 2.4 x 4.4 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 2.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 4.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 3 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 5.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 7.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +Horizontal, grid 5 mm, outline 7.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>CAPACITOR</b><p> +grid 7.5 mm, outline 3.2 x 10.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 7.5 mm, outline 4.2 x 10.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 7.5 mm, outline 5.2 x 10.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 10.2 mm, outline 4.3 x 13.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 10.2 mm, outline 5.4 x 13.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 10.2 mm, outline 6.4 x 13.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 10.2 mm + 15.2 mm, outline 6.2 x 18.4 mm + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 5.4 x 18.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 6.4 x 18.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 7.2 x 18.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 8.4 x 18.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 9.1 x 18.2 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 6.2 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 7.4 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 8.7 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 10.8 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 11.3 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 9.3 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 11.3 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 13.4 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 20.5 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 32.5 mm, outline 13.7 x 37.4 mm + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 32.5 mm, outline 16.2 x 37.4 mm + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 32.5 mm, outline 18.2 x 37.4 mm + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 37.5 mm, outline 19.2 x 41.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 37.5 mm, outline 20.3 x 41.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 3.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 37.5 mm, outline 15.5 x 41.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 7.5 mm, outline 6.3 x 10.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 15.4 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 17.3 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>Ceramic Chip Capacitor KEMET 0204 reflow solder</b><p> +Metric Code Size 1005 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 0603 reflow solder</b><p> +Metric Code Size 1608 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 0805 reflow solder</b><p> +Metric Code Size 2012 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 1206 reflow solder</b><p> +Metric Code Size 3216 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 1210 reflow solder</b><p> +Metric Code Size 3225 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 1812 reflow solder</b><p> +Metric Code Size 4532 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 1825 reflow solder</b><p> +Metric Code Size 4564 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 2220 reflow solder</b><p>Metric Code Size 5650 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 2225 reflow solder</b><p>Metric Code Size 5664 + + + + +>NAME +>VALUE + + + + +<b> </b><p> +Source: http://www.vishay.com/docs/10129/hpc0201a.pdf + + +>NAME +>VALUE + + + +Source: http://www.avxcorp.com/docs/catalogs/cx5r.pdf + + +>NAME +>VALUE + + + + + + +<b>CAPACITOR</b><p> +Source: AVX .. aphvc.pdf + + + + +>NAME +>VALUE + + + + +<b>CAPACITOR</b><p> +Source: AVX .. aphvc.pdf + + + + +>NAME +>VALUE + + + + +<b>CAPACITOR</b> + + + +>NAME +>VALUE + + + + + + + + + + +>NAME +>VALUE + + + + + + + + +<B>CAPACITOR</B>, European symbol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/ui.png b/Applications/Official/DEV_FW/source/xMasterX/rc2014_coleco/ui.png new file mode 100644 index 0000000000000000000000000000000000000000..97c0ddc2143afbaf898bedc2a37fd3adfbfe8188 GIT binary patch literal 92556 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

    ZOTCY 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%0D76x2D-S@0Eq_hvLTv=u4(AsL+=d0G*GZY z#SGyz&{9H8452jO)Bdzx11qZDw zaudV`8?AG5qsoUWZ#Z+Kj|W_=2icSAAP|Sd^%mMg=|Ii(T-lQ^Lvr<2oNC?@coQ9m zGW9&3lJG<72T5$OxD#|Bu7wbHA#YgR!tuWn3e)e2I>oi zI%NbG&qL9GBzhylOsaum4J!|c97y~|6qdXX#W|Q=1nYypqId}@J1Q@%Krm?!q+x8e z$UGSV$~Y``FkjEBji^%zW)#wJdmsiGR)W8zIDxP+NeyaqI5?0rALnf#cL2473i$yF z6{=jgDG)y&Vk%@$TnC6i!bo08CXQkh?$Afr=hG+J$G!>o4(Sa1bGUnudzi)>Z(uoT z2l+SDP82^BK1m$Vj7fl`fRYlcA>~PElLY&SqJ$wOAx*v$FD%;)gOnkG zQxfJQ+gHr}h|4!W$#I8Jj3HU^aN}e}ipbdF7lypINsU=*AT=Y)g};&fNGOgsi?&vnni4azaLx5Eriy?=%iv6oAYWxSNN;FvC4Cq3N=@*qg=!~ z3U(Fq%J-Q9+e2}N)k_hrfGrK4YLJu6)a6a-P+iqXEndZz=Ss@7e&ST6F&HA@?=o zHR(0WHLfe_JyvU^ZtqjqQ;+Qy3O9XhaKR?Gy*D>$7PmZJvA=S!#TJ5n5w}$q#5mM$ z#6>UEMvueiCJG%qMi@5~^=Q6;Pkpl+8TJ)TPEAD1fMeQYUR!WC;u~15sLa9kZiX$v zt&T0=-zMv!OS8Eq!ID*LzEb3(y%+hT0Jx(bRQBYWpF4E&~4F< z(TZRd;4Xr>f>nF4dw4gHQOVwgQ;@w%h>|3aL@kVn1iIuiP6eBbIg_-YwMPW>F~37# ziAZ}hMvjFVhe{W5)i>Sex(W48$RV6tyiG2PLXfnBq~moZ%3S!5J|T+mV9Eq3YYL+G zBvOGCGD@Tt2?$c(Dfqq$zQ-QU#gLACO_}gj%Ht#1R|h4^(tsJ+1CpzF#)MF*t&d(G zExxjSCEFL+N8g9Bh(btUF=kDV856}Kn;v#FR;@u=NVAr5C239Y8Gf@3>&Slx;0e=_ zWF%FO|1oSfM7T|KPU4ZqFW;e%Ln=ho`MN5;GoEW`34jyBW!-1SWz%HiVew$TV+&#JXD(zmVIef8H7ql*G_W+~9du6Eho8oo zCM=>U;wcg%q_h*J(s1^RL|sTaM1wYD1&1_0b z+<}~lB6(@V41%TL6>NQ$mV!-@tI~amdMQ`wO=(;yQ;Ez>+zj!I5Irmw_^Vg1kfWHR zFrv_+u%cL^IHK61uw_VOAZ5U1cx41fQBxdKpi{6?7*l*xtmwDsku`E^=&RezG>sMv z7EJo9l{9!XEXvW!&&vg8O{%!pDWA1?PF$dFut81@8rs`FHb53y$+hwaK4nKXcT& z)Lhjf*2+~27-t%J^*4-MXWK*(cFP-^nd};28>Jel8_k(D8n_wX7$6(O87LS}7z+*g zMz?3QN3;h$lHH@+%U#19DlA|xsLywPwsRoi4ksul@FsXi;7D*l08NlWAWxu2fDlU^ zYaDAGOBSmX>lup`dqI%OEzWanFYDB{?ml{!Zj^{_zsX&i#h*o%Rg-0z^)m}AD>h3n z3t^mk+<2T|yf@1v>nf`v3!58;XOR2ELGZiIy3Y59k>>u8bu!1#PH^^9%^1yfO|nha z&C5*>O+C$MO{~pG4%zEvJC@%MHe32QMqE;@LVr-sc~w^FXfMOsqH*zY#c03Rj?fNU zN?OWU3gYwUd(W577k1C=#&aWe%y~?7OnU5aEOpFt%(a}`G}r9rVb4#`@6Er-f6kx5 zKfvF>Z_EG0kIEmxugNdQZ^DnrZ^JLZFUr5gkL;0iMt|o0ePKJq9j?u~4ZO`+k5Z3N zk4+CoPeBjb4&elB)q53f)pB*ZExQe(ZO-H5OmIVYTX*MixV1NIr{MhTJmP}p)Z#4t zbm79|6zW{;qVRm@EcsORBK!M~&DK7*>=VH?<&HUT;=6BmU_v>$G5Y@c@AcF5Q`Z95 zBG$r$f`xK~f;!_nqdNmSvpZ9t@tzr;ES@}`OrB02{Ggb@RlxMX9KgiDY{1ySB*2&g z3<9_VoC8F`3&9b=ZNS^X=OArg$-ZjC&_KNop){x6BiW619gB8V);NNF?gVS_)Jt?)MZ3;_%eDrrY4#u`U09*l#%q? z&%3{;|9$^?e{9rjRDIM{L`>ugb|$(P-L6#7bvel@lrvVgO|v=Fu6vtZg++^5**-{1O5RX8Dq zEFCAKAj2f>m$Lf4d#HK@c4TPSd{kqoX$W$pZ^U>6V{~SyZbT=knURg=Lc~ln4rwjESyfH91uq^O%U_p;>2z7{aNH6>>dYI@@{3|D*DPO%0K3PEH*CKF2pEG%6C>Q z71@tgiu+pf_2bvJuM&l8BRD3mCa5NqCJ-ikCd50iJM24TJC-|YJH9*kBhw>QNuAVo zpHNhrRQG5tX^UvbX~Ae6XcuS)Rq#}JRYO&dOU6p+Kb3zXQ`J;~Qr%I#Qn68OSLszn zF2O2QD{Uyd{cv3O!+|Z>x!a6(+}T^u*y?Ds^zIwx{6n*AGItdE#@y~ zEH?1I&6dzr(iL6NSy2^`6nHD3-!A)D=Nb3Y<%;G??26;c1~DHxE;K2$C^RHAQ@mQd zX5dW>e2i&~U<^LqG+q@)hXuG?WRZVSc~NXpOi`+7lWE3x!!KH2YBPc|8ad23QaQNl zCbg`!^0h{^2DIe0z_c8+nzg9vGU{6D#p{deu}Qi&BS7HbvD?YcVx!>`CCc>1pX{>RIX8?MdSq;yLSi__oF_K&$AZU_3aetFMI&$UmnU<>|h!sEgdUE>Cw zZ=&DCcEbftL$^b7A($ep;ythfacgiRam(;Ba9i*~af)!TaKGWX;vnI!vSo2SSU1@K zInkKkvwh`qWIkt$WE)|l<+9{F;L2dm;LzgyX%fx$oil~?8*2mSHD@gAIIE!TvhlJN zzbU`b!#DR8NShu*GQ)hscNUu#Xol|%mEL_d|7zp7V!UWPyj@H)lGLlxqtZL`b!M8q zhrRbQZJ%bEXqsgjce=3%-xP;Uo~;)4U@0~4=T zi@J(NzL$Sd&6LVi=UlT%Xdq~C)@IPg*VbR+Uh-a&UaD;nZ9ulhw&`3VJ(@q-bJcQf zaJ@g;JcK_iJLEmAT$EdEZ@4#%YuK$zt(p7W*m%>ZP$y)pZ?$G3^iIg;`J3-F*lyPk zl3j!K^+S}y_yhaC4^tr6yr{Rlx2#uRBC;U9pr#A#$S!E z-F&!qI8IzFZk;eBHqsyI*z}>gxjMvO<7zzF>LA1}izKx4+<(wQ>8-8bIU}i*SrgpG)gLb-h<`QP3 zR3n$|k7I5(K{pRKBR8%a`y2Wj)*H?ny5q!SyJaqZdm?Wlc%s)t$3&<^3q(6aM?~rZ zMf|It59bu_@b0u886KXV;$Gi9)I4%72+p$3bgmz^#Lm#Jl`d+|7f+JcRrgd+W{+H^ zt;T;Oa&3S4E_d_o%=OgNo%odTOz=ox-DkpU>OKtlTiBe$>frp~3e{Jtx#F+Iy=Hx8 z17-`mRZNLhB~_tS6;+*fHFlp*Xx0SR_&S(;I!`1{b{Ci$*W5doo`xQq@9A!GmxOAb z&z@!|utWaA2BXfKb~|DlpDa(NJU1-tfWT3lN3iR}eQ)p-`q!YLKpwv5-L0hMr0+>RN$*8^L~2B7MaM&QkUj9uX)us>V3XlE;9XwD zz<)umfNMwLCHhHrX@$cZ%_Yk+#y`eKFIY}p&QdOPXgmL@I>!E8lVX!+la0HOOutjwZnZ1`iGo z?j5HiT_le*zcked4J|z_Um0r|-GTT_ZAsPCp82YIp?TEaTRrP7sbNv?~p z%aN7ElKLj?DvKmDE>$UiEZ>pb7T=a2B8@6HCGQ{)r!Xv6Dz`7yoOn*VqfSey%CE{b zOUXf7Pf|}>&vfN`pmdN6K@UTLj6-zFjpCKJCp;a{4WSI9_Ei{9B10!bGs8|xNlQx0 zYSDgix~|??g;&2tx-$(G#44OrhLX@wUhn$RDs6eoQY3t2EYxI$9 zgKWBNqU_07-&jF9Lwawz0^3~8q~?RBrKYQ9x2C41s^*GjW38UaZi$<{6z~odTVS<=|!VW`^e8W(B9t zZNqbO4?GVf4?_K=7R!ZIFNY>qq#NgPq({eV2Y6{i2{+&2$Tekov3d?-xrKlR?I=ur>R7NZyYDpn-cAx0xc6*-Q%La#-=$Uo++ab7)T zc+x8s7Dp)P<$iejuyOTH`ZMse;b$|4cMehxUS}F-QJYuf+vI2x2yyO2Qv8mGlJ^Op z$uA_n#VN&pjl(0l;>~cryq&6*up{vCaIOt*2A1_T^%YYTeysagYn;EWI{b|##fWuq zEcT92hEL7mu;(-1U`nhF@h*3z{qh0#mixD}#Vwyfs<^5we}&T=MFB%UvIk&y!~lA# z!dR9DU4IIEvSn&Z%0LQMYC}qFiXhXYrZ`PODsJjsQejeZvP<#`qnGk^V^)FAhvgRj z68_@0O7A@HvIirmvOu*Ds-LUKiZ<=VWctnfFCwp`r3;Ma5Q^=$=LEveW5SW;xlKcBZx|77ga6?7Qr_ z)*W9T>h8Q=HH+2sms93Zek!aqsorrIol|>9*FO7kwu+;+zQHBWrRYiq|ASoqmnIuO zZEK5)p>dY%L>@B_##^1$X64<=Y%gEi+QfS0j_D${@(V>Xr`@aZkZ~d1 zEL~dNSluaIiI#C!IcJ7!nBBW^s~k6hT>Fm8hmeb#i7Gu|eUy$ozwTX;#gKznkJzS+ z-bb%pWLz`d*jk)g@ms50giclu4S&2n{CpB|$g@1X%C=fN^UCwitKM_PE75b*%gdAa z+P5XVliGJ`JO8==Fp7!^N!Q!ep&+ha;qyc#Q%zMS-u4~F18N5^-CQ3cp))}Y$jlzkb;5R?>7D$Yk?W!&8 zjZb&hb4PVjXPH`c?QZpEs64rW{BE~N{M2M zVuukS`m{@T&^pZ?SkBM(e5z0%tYXv+s+y|Y*S+XS@vS&s+_7?+;|yI0O%5dtGYX4C z%q8|^esF*k5+P>6hr^@6u^__5_Yi;=hZ1*@XcwOrw~}Cr8;`NoGi$B%UfK6tzCxdC ztrBYM;1tJ8B&x-Gg-?fPMcm49{RDjwI)qq&|HS2Jo7KYNX>>L)F4vK{$R%J`v{K&g zarb@s%NK`OhuJfqt%$9iE$qSK!A=Ecg&~D`1)u^!Cb!U;!R7_SCd0nAT4RqLVaKe) zkMWAxrTHba#xJ%oYl7~rSJ$^kZf=Thz+;>>xVA*M-LY(Zx7Fp46ZjR5rXOxxySCFS zQ>|6U0bX@pKX1HGOjfMgxE$@yR*!uG?mcgOj?GquJp68-dLFZ39*~`hZ~2G3?a#YU zgF;~V62TKa6FU+$6Jrv|6QdGaku8v~h>!i!9#3a_e<15CyipER4pn|qZdNWXwv}ZN z5aCDjFn$O>D_MU#S`Z;|Qp_^FIc+*kIvp}?R(vAsm)1QY`9)&_I7X1YpOK!W=_Tty z|2+TXaJcn#uszO<=-IpHCvYcXG;y0sRRKDe->c>->Av)va#b;|f`TBSM+^5WQz$b; zGYHcQGi_5U)70H+r%RsE=F?_!CtasRC;c220cH2^xAae%cePJu3b~J-<5xNt&AS(u zyHvSx{C-#9o}`yOw@_RC-PlJ=$8ERF3Tdh7joEQILM&^1&+fjDl=m`MsmDyydfz$; ze4Cp946qD1Ow3qF40TM)y0>+bT1nb<`qA3-`iJ^ix(|<$_sQ3Ex$2r#8G0-3SH~Pb z>-(%m=TNKSIyz2&PW>RZn_n$yckpvsmwU|I;HpYlr%a%nE{reimC2S#l+j;PTBGfB z@yI-HxIUU~e07rN)^j4e3e`#H>2|yl+iUrxMi&)zR6ZS))(wpW@WHgzSALpVlu(cSSG4B9K23 z!x5VZ@p?x;Yuufk58lP`3jMxdB5>ous*mzeBrRXjKmohv6~_oSmq zRX$q5S4mYdSFW$^S0Av9vR1tqzDm7EM>*?#Gf{!x~;^yWj4E?VZo=O)*0e!wy4Z#bt%EHdmwC6Uy_@v%^#3dGXW4UT&k` zXTQSd#b>z(?TeemwYjAdo1YC|T$f#Uu9J^K2;C*T2Q8^Qi@nY4&3v&BBagKX#g9{t zkq$fNR~~OV-wTL7uw|t~b@31ae!u``X240X5CHu@p27Z%jyxK|o2h^zt`UNQCDQ)| zI>N^2WNv70@;3~I$;i&u85EU`(aF_pM^!Fvi4&#$q$;f@^_nE|V~1p~{ii8@U7fxnfVEjE>Wf$T9Hp|MZ@6i>>>e#;3xhFq^wTjblRxcOt5)-&K53E_p9tT zr!8y^Spnon30K`Vgfx&~o7wbjlGD2r!Tro*Q|L|L1Q52a<#HFN1Q~RNJsU|nU19D- z#|2?>&9je{I{T|)+=MzmuWU?QZ{6pHh3{S0DlYM)*lp?rb`1Ct^ z4~J`}zWW;GrV+&mwpqvV7%~9Cgbp$QtNV!XOpvMx(#x3Ks)2*3 zBe75u?t#!;Ceu1P1ksY*UV}2wH3oUqGMZU>)yyNT={XBH$sz;&z#bksR$LES#;!;D zDP@fPp@EgmH+Z{3o3#P2&%M8Kd`*aeW{}I` zu)I%)mQhO4LkRvJNIQt);2kkE1QiE)Oc|Lllr}=WRYDTWGb$_sgkmjficCdQ4x1R_ zG@KpUZ=SEF_NM0qbbneeiM=S)#zYqo8q7K^cs;>ok+bPg1*t9*o4%!Y6nvG1KIc9G zis5kKdtBJk2bYv;aK20~2y(BNa$IgfXVZDi-jF}*hm6MfU5)riG0isN48zK4kF?gO z%I=G$Q_D|=cGO_Ajhmvy3Q7YIfb-B$5x&d zYW5{b!;;Wpp*_V>yie?By08Z@*blHjlDEU{^4}v}+zTmrOE1kXKc+KOK0*Ka>O=*Tovhdy|3-#6nOK_`{fch-zv0tZ{ym=tD)1Q^^a~V}5y1SPmHua1 z4Gi$~{QTz@p)vcghJmyiK%%67rDaI-Jm>aI-Jm>) zFW|@vIPwCHynrJw;K&O&@&b;$fFm#9$O|~~0*<_ZBQM~{3pnxuj=X>)FW|@vIPwCH zynrJw;K&O&@&b;$fFm#9$O|~~0*?G&2#(M)Ke-}+Jifqy5;6!Ju`zKpGcmTXF*Gw_ zw6`?_g8{pJicpl7K!nGG2c1Tgk_0M&K7Vb)!~XKd6vH~v4*Gzzm(+9uNf`c0U?oDu z7NCR8QlLPCIO;a>Ebzh1C}LqIQ8S!@L~rQpFHv%a@VC*_;Lm8U8!Rb_x)&be5_DH! zAbOvL5{-chSx#CQA*PxGBFGFR<}H=eWo6DeX4yp%Aw*hhH)E`6yUmQFBHdb};IO?A zOlODpj8gCO9!cetJ=cA>ezag2jcuV&`A)OP^f^4hp2s}FcWiMZUBP{8u$c)QjChMN z+)~LJyTwszqkTsFQR4UqoY#FTQCcsvxn{~-&y?sZZvdIykPH?EVgaZTe-WM0P}qEv z800($50vmhx&9z-K%MssxM8xeH8yc)bhohv!vo)WMk+^~)H-gRykg+f_laZL% z8rd0J*qRBDsj7%GaFYoM!t;{?6+~4u6~#ylZT}&}U}NHJXl&?gNTR4JA}b|ILdC$u zBm)#d6}5p+}s$A46Us#%p46F?HtX1J?rvl3N zPtjjle%CZ{x3_b2W^gibb_R8z6Q~#xekT(L7f_d)h+9~jC>lDO|I_|o&HujMN{+{t}@G2!a9t>>W*9Elk{gtt7t}`+IcLf0PU|G)88e2cf9n6 zMEPGy{K*Z|?|T0gqQm{C*x%Z6^_O}esP1=}-+fsAQu_NyFgyJFmi?7S%iooM_rLeg zI#L9TJO7LFzw^fTyC6v5PcHTT5R`TKj|BhQ{`}p!-Y@mPcSPP_ssC43d%suqcQ1E; zRMyn>Un={ziNo=`#9z;tZI8c@_-|YI*E5E}^RM*&&5Zf4GQa4}f4(RJ%(MQG`HkiL zy=}kW$^Q`f(D5(#_1}$uznlGGyx93)Yw$1kHbohzUrzx5RM5K}6gil+=hxo<0qY71 A761SM literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/usb_hid_autofire.png b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/usb_hid_autofire.png new file mode 100644 index 0000000000000000000000000000000000000000..369bff02253d7473f33d23cb592132f35982d180 GIT binary patch literal 641 zcmV-{0)G98P)e zlG%+*k||Ai4%8=T%ML zhSPQEyt6Y-=3Am1!eYE_=-5_Wc>PxeO_zW@erXbqKn z*v9|>010qNS#tmY4`BcR4`BhQKc{H`006m3L_t&-S8b3n3WP8aMTcdJ)HZ@1K`gcO z5T3{z!CK1#2*U#}@$CC9Ns^%bAx%?y;C(mix)x*1;}9o)(=?65 zar_AKjs6P0<2VlW3D&l4)Pl!}Q54C#t}>3}HK}b|@gJl|?&}GA`@0^P!!T%Bme<13 bLkoNWB5%k`78DJm00000NkvXXu0mjfs(>Tu literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/usb_hid_autofire.svg b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/usb_hid_autofire.svg new file mode 100644 index 000000000..ed66f3cfd --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/usb_hid_autofire.svg @@ -0,0 +1,75 @@ + + + + + + + + + A + + diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/version.h b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/version.h new file mode 100644 index 000000000..ac1f5d0fa --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/version.h @@ -0,0 +1 @@ +#define VERSION "0.4" diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_midi/.gitattributes b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/.gitattributes new file mode 100644 index 000000000..dfe077042 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_midi/.gitignore b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/.gitignore new file mode 100644 index 000000000..c6127b38c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/.gitignore @@ -0,0 +1,52 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_midi/application.fam b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/application.fam new file mode 100644 index 000000000..cf2f0be6e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/application.fam @@ -0,0 +1,14 @@ +App( + appid="USB_Midi", + name="USB Midi", + apptype=FlipperAppType.PLUGIN, + entry_point="usb_midi_app", + requires=[ + "gui", + ], + stack_size=4 * 1024, + order=20, + fap_icon="usb_midi.png", + fap_category="Music_Extra", + # fap_icon_assets="icons", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/config.h b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/config.h new file mode 100644 index 000000000..c62c1b1ef --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/config.h @@ -0,0 +1,3 @@ +#include + +#define SYSEX_BUFFER_LEN 16 \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/message.c b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/message.c new file mode 100644 index 000000000..7bee9816a --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/message.c @@ -0,0 +1,144 @@ +#include "message.h" + +/** Returns the data within the MidiEvent as a NoteOffEvent struct */ +NoteOffEvent AsNoteOff(MidiEvent* event) { + NoteOffEvent m; + m.channel = event->channel; + m.note = event->data[0]; + m.velocity = event->data[1]; + return m; +} + +/** Returns the data within the MidiEvent as a NoteOnEvent struct */ +NoteOnEvent AsNoteOn(MidiEvent* event) { + NoteOnEvent m; + m.channel = event->channel; + m.note = event->data[0]; + m.velocity = event->data[1]; + return m; +} + +/** Returns the data within the MidiEvent as a PolyphonicKeyPressureEvent struct */ +PolyphonicKeyPressureEvent AsPolyphonicKeyPressure(MidiEvent* event) { + PolyphonicKeyPressureEvent m; + m.channel = event->channel; + m.note = event->data[0]; + m.pressure = event->data[1]; + return m; +} + +/** Returns the data within the MidiEvent as a ControlChangeEvent struct.*/ +ControlChangeEvent AsControlChange(MidiEvent* event) { + ControlChangeEvent m; + m.channel = event->channel; + m.control_number = event->data[0]; + m.value = event->data[1]; + return m; +} + +/** Returns the data within the MidiEvent as a ProgramChangeEvent struct.*/ +ProgramChangeEvent AsProgramChange(MidiEvent* event) { + ProgramChangeEvent m; + m.channel = event->channel; + m.program = event->data[0]; + return m; +} + +/** Returns the data within the MidiEvent as a ProgramChangeEvent struct.*/ +ChannelPressureEvent AsChannelPressure(MidiEvent* event) { + ChannelPressureEvent m; + m.channel = event->channel; + m.pressure = event->data[0]; + return m; +} + +/** Returns the data within the MidiEvent as a PitchBendEvent struct.*/ +PitchBendEvent AsPitchBend(MidiEvent* event) { + PitchBendEvent m; + m.channel = event->channel; + m.value = ((uint16_t)(event->data[1]) << 7) + (event->data[0] - 8192); + return m; +} + +SystemExclusiveEvent AsSystemExclusive(MidiEvent* event) { + SystemExclusiveEvent m; + m.length = event->sysex_message_len; + for(int i = 0; i < SYSEX_BUFFER_LEN; i++) { + m.data[i] = 0; + if(i < m.length) { + m.data[i] = event->sysex_data[i]; + } + } + return m; +} + +MTCQuarterFrameEvent AsMTCQuarterFrame(MidiEvent* event) { + MTCQuarterFrameEvent m; + m.message_type = (event->data[0] & 0x70) >> 4; + m.value = (event->data[0]) & 0x0f; + return m; +} + +SongPositionPointerEvent AsSongPositionPointer(MidiEvent* event) { + SongPositionPointerEvent m; + m.position = ((uint16_t)(event->data[1]) << 7) | (event->data[0]); + return m; +} + +SongSelectEvent AsSongSelect(MidiEvent* event) { + SongSelectEvent m; + m.song = event->data[0]; + return m; +} + +AllSoundOffEvent AsAllSoundOff(MidiEvent* event) { + AllSoundOffEvent m; + m.channel = event->channel; + return m; +} + +ResetAllControllersEvent AsResetAllControllers(MidiEvent* event) { + ResetAllControllersEvent m; + m.channel = event->channel; + m.value = event->data[1]; + return m; +} + +LocalControlEvent AsLocalControl(MidiEvent* event) { + LocalControlEvent m; + m.channel = event->channel; + m.local_control_off = (event->data[1] == 0); + m.local_control_on = (event->data[1] == 127); + return m; +} + +AllNotesOffEvent AsAllNotesOff(MidiEvent* event) { + AllNotesOffEvent m; + m.channel = event->channel; + return m; +} + +OmniModeOffEvent AsOmniModeOff(MidiEvent* event) { + OmniModeOffEvent m; + m.channel = event->channel; + return m; +} + +OmniModeOnEvent AsOmniModeOn(MidiEvent* event) { + OmniModeOnEvent m; + m.channel = event->channel; + return m; +} + +MonoModeOnEvent AsMonoModeOn(MidiEvent* event) { + MonoModeOnEvent m; + m.channel = event->channel; + m.num_channels = event->data[1]; + return m; +} + +PolyModeOnEvent AsPolyModeOn(MidiEvent* event) { + PolyModeOnEvent m; + m.channel = event->channel; + return m; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/message.h b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/message.h new file mode 100644 index 000000000..88402c4a4 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/message.h @@ -0,0 +1,251 @@ +#pragma once +#include +#include +#include "config.h" + +typedef enum { + NoteOff, /**< & */ + NoteOn, /**< & */ + PolyphonicKeyPressure, /**< & */ + ControlChange, /**< & */ + ProgramChange, /**< & */ + ChannelPressure, /**< & */ + PitchBend, /**< & */ + SystemCommon, /**< & */ + SystemRealTime, /**< & */ + ChannelMode, /**< & */ + MessageLast, /**< & */ +} MidiMessageType; + +typedef enum { + SystemExclusive, /**< & */ + MTCQuarterFrame, /**< & */ + SongPositionPointer, /**< & */ + SongSelect, /**< & */ + SCUndefined0, /**< & */ + SCUndefined1, /**< & */ + TuneRequest, /**< & */ + SysExEnd, /**< & */ + SystemCommonLast, /**< & */ +} SystemCommonType; + +typedef enum { + TimingClock, /**< & */ + SRTUndefined0, /**< & */ + Start, /**< & */ + Continue, /**< & */ + Stop, /**< & */ + SRTUndefined1, /**< & */ + ActiveSensing, /**< & */ + Reset, /**< & */ + SystemRealTimeLast, /**< & */ +} SystemRealTimeType; + +typedef enum { + AllSoundOff, /**< & */ + ResetAllControllers, /**< & */ + LocalControl, /**< & */ + AllNotesOff, /**< & */ + OmniModeOff, /**< & */ + OmniModeOn, /**< & */ + MonoModeOn, /**< & */ + PolyModeOn, /**< & */ + ChannelModeLast, /**< & */ +} ChannelModeType; + +/** Struct containing note, and velocity data for a given channel. +Can be made from MidiEvent +*/ +typedef struct { + int channel; /**< & */ + uint8_t note; /**< & */ + uint8_t velocity; /**< & */ +} NoteOffEvent; + +/** Struct containing note, and velocity data for a given channel. +Can be made from MidiEvent +*/ +typedef struct { + int channel; /**< & */ + uint8_t note; /**< & */ + uint8_t velocity; /**< & */ +} NoteOnEvent; + +/** Struct containing note, and pressure data for a given channel. +Can be made from MidiEvent +*/ +typedef struct { + int channel; + uint8_t note; + uint8_t pressure; +} PolyphonicKeyPressureEvent; + +/** Struct containing control number, and value for a given channel. +Can be made from MidiEvent +*/ +typedef struct { + int channel; /**< & */ + uint8_t control_number; /**< & */ + uint8_t value; /**< & */ +} ControlChangeEvent; + +/** Struct containing new program number, for a given channel. +Can be made from MidiEvent +*/ +typedef struct { + int channel; /**< & */ + uint8_t program; /**< & */ +} ProgramChangeEvent; + +/** Struct containing pressure (aftertouch), for a given channel. +Can be made from MidiEvent +*/ +typedef struct { + int channel; /**< & */ + uint8_t pressure; /**< & */ +} ChannelPressureEvent; + +/** Struct containing pitch bend value for a given channel. +Can be made from MidiEvent +*/ +typedef struct { + int channel; /**< & */ + int16_t value; /**< & */ +} PitchBendEvent; + +/** Struct containing sysex data. +Can be made from MidiEvent +*/ +typedef struct { + int length; + uint8_t data[SYSEX_BUFFER_LEN]; /**< & */ +} SystemExclusiveEvent; + +/** Struct containing QuarterFrame data. +Can be made from MidiEvent +*/ +typedef struct { + uint8_t message_type; /**< & */ + uint8_t value; /**< & */ +} MTCQuarterFrameEvent; + +/** Struct containing song position data. +Can be made from MidiEvent +*/ +typedef struct { + uint16_t position; /**< & */ +} SongPositionPointerEvent; + +/** Struct containing song select data. +Can be made from MidiEvent +*/ +typedef struct { + uint8_t song; /**< & */ +} SongSelectEvent; + +/** Struct containing sound off data. +Can be made from MidiEvent +*/ +typedef struct { + int channel; /**< & */ +} AllSoundOffEvent; + +/** Struct containing ResetAllControllersEvent data. +Can be made from MidiEvent +*/ +typedef struct { + int channel; /**< & */ + uint8_t value; /**< & */ +} ResetAllControllersEvent; + +/** Struct containing LocalControlEvent data. +Can be made from MidiEvent +*/ +typedef struct { + int channel; /**< & */ + bool local_control_off; /**< & */ + bool local_control_on; /**< & */ +} LocalControlEvent; + +/** Struct containing AllNotesOffEvent data. +Can be made from MidiEvent +*/ +typedef struct { + int channel; /**< & */ +} AllNotesOffEvent; + +/** Struct containing OmniModeOffEvent data. + * Can be made from MidiEvent +*/ +typedef struct { + int channel; /**< & */ +} OmniModeOffEvent; + +/** Struct containing OmniModeOnEvent data. +Can be made from MidiEvent +*/ +typedef struct { + int channel; /**< & */ +} OmniModeOnEvent; + +/** Struct containing MonoModeOnEvent data. +Can be made from MidiEvent +*/ +typedef struct { + int channel; /**< & */ + uint8_t num_channels; /**< & */ +} MonoModeOnEvent; + +/** Struct containing PolyModeOnEvent data. +Can be made from MidiEvent +*/ +typedef struct { + int channel; /**< & */ +} PolyModeOnEvent; + +/** Simple MidiEvent with message type, channel, and data[2] members. +*/ +typedef struct { + MidiMessageType type; + int channel; + uint8_t data[2]; + uint8_t sysex_data[SYSEX_BUFFER_LEN]; + uint8_t sysex_message_len; + SystemCommonType sc_type; + SystemRealTimeType srt_type; + ChannelModeType cm_type; +} MidiEvent; + +/** Returns the data within the MidiEvent as a NoteOffEvent struct */ +NoteOffEvent AsNoteOff(MidiEvent* event); + +/** Returns the data within the MidiEvent as a NoteOnEvent struct */ +NoteOnEvent AsNoteOn(MidiEvent* event); + +/** Returns the data within the MidiEvent as a PolyphonicKeyPressureEvent struct */ +PolyphonicKeyPressureEvent AsPolyphonicKeyPressure(MidiEvent* event); + +/** Returns the data within the MidiEvent as a ControlChangeEvent struct.*/ +ControlChangeEvent AsControlChange(MidiEvent* event); + +/** Returns the data within the MidiEvent as a ProgramChangeEvent struct.*/ +ProgramChangeEvent AsProgramChange(MidiEvent* event); + +/** Returns the data within the MidiEvent as a ProgramChangeEvent struct.*/ +ChannelPressureEvent AsChannelPressure(MidiEvent* event); + +/** Returns the data within the MidiEvent as a PitchBendEvent struct.*/ +PitchBendEvent AsPitchBend(MidiEvent* event); + +SystemExclusiveEvent AsSystemExclusive(MidiEvent* event); +MTCQuarterFrameEvent AsMTCQuarterFrame(MidiEvent* event); +SongPositionPointerEvent AsSongPositionPointer(MidiEvent* event); +SongSelectEvent AsSongSelect(MidiEvent* event); +AllSoundOffEvent AsAllSoundOff(MidiEvent* event); +ResetAllControllersEvent AsResetAllControllers(MidiEvent* event); +LocalControlEvent AsLocalControl(MidiEvent* event); +AllNotesOffEvent AsAllNotesOff(MidiEvent* event); +OmniModeOffEvent AsOmniModeOff(MidiEvent* event); +OmniModeOnEvent AsOmniModeOn(MidiEvent* event); +MonoModeOnEvent AsMonoModeOn(MidiEvent* event); +PolyModeOnEvent AsPolyModeOn(MidiEvent* event); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/parser.c b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/parser.c new file mode 100644 index 000000000..86120e007 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/parser.c @@ -0,0 +1,149 @@ +#include +#include "parser.h" + +typedef enum { + ParserEmpty, + ParserHasStatus, + ParserHasData0, + ParserSysEx, +} ParserState; + +const uint8_t kStatusByteMask = 0x80; +const uint8_t kMessageMask = 0x70; +const uint8_t kDataByteMask = 0x7F; +const uint8_t kSystemCommonMask = 0xF0; +const uint8_t kChannelMask = 0x0F; +const uint8_t kRealTimeMask = 0xF8; +const uint8_t kSystemRealTimeMask = 0x07; + +struct MidiParser { + MidiMessageType status; + ParserState state; + MidiEvent incoming_message; +}; + +MidiParser* midi_parser_alloc(void) { + MidiParser* parser = malloc(sizeof(MidiParser)); + parser->incoming_message.type = MessageLast; + parser->state = ParserEmpty; + return parser; +} + +void midi_parser_free(MidiParser* parser) { + free(parser); +} + +bool midi_parser_parse(MidiParser* parser, uint8_t byte) { + bool parsed = false; + MidiEvent* event = &parser->incoming_message; + + switch(parser->state) { + case ParserEmpty: + // check byte for valid Status Byte + if(byte & kStatusByteMask) { + // Get MessageType, and Channel + event->channel = byte & kChannelMask; + event->type = (MidiMessageType)((byte & kMessageMask) >> 4); + + // Validate, and move on. + if(event->type < MessageLast) { + parser->state = ParserHasStatus; + // Mark this status byte as running_status + parser->status = event->type; + + if(parser->status == SystemCommon) { + event->channel = 0; + //system real time = 1111 1xxx + if(byte & 0x08) { + event->type = SystemRealTime; + parser->status = SystemRealTime; + event->srt_type = (SystemRealTimeType)(byte & kSystemRealTimeMask); + + //short circuit to start + parser->state = ParserEmpty; + //queue_.push(incoming_message_); + parsed = true; + } + //system common + else { + event->sc_type = (SystemCommonType)(byte & 0x07); + //sysex + if(event->sc_type == SystemExclusive) { + parser->state = ParserSysEx; + event->sysex_message_len = 0; + } + //short circuit + else if(event->sc_type > SongSelect) { + parser->state = ParserEmpty; + //queue_.push(incoming_message_); + parsed = true; + } + } + } + } + // Else we'll keep waiting for a valid incoming status byte + } else { + // Handle as running status + event->type = parser->status; + event->data[0] = byte & kDataByteMask; + parser->state = ParserHasData0; + } + break; + case ParserHasStatus: + if((byte & kStatusByteMask) == 0) { + event->data[0] = byte & kDataByteMask; + if(parser->status == ChannelPressure || parser->status == ProgramChange || + event->sc_type == MTCQuarterFrame || event->sc_type == SongSelect) { + //these are just one data byte, so we short circuit back to start + parser->state = ParserEmpty; + //queue_.push(incoming_message_); + parsed = true; + } else { + parser->state = ParserHasData0; + } + + //ChannelModeMessages (reserved Control Changes) + if(parser->status == ControlChange && event->data[0] > 119) { + event->type = ChannelMode; + parser->status = ChannelMode; + event->cm_type = (ChannelModeType)(event->data[0] - 120); + } + } else { + // invalid message go back to start ;p + parser->state = ParserEmpty; + } + break; + case ParserHasData0: + if((byte & kStatusByteMask) == 0) { + event->data[1] = byte & kDataByteMask; + // At this point the message is valid, and we can add this MidiEvent to the queue + //queue_.push(incoming_message_); + parsed = true; + } + // Regardless, of whether the data was valid or not we go back to empty + // because either the message is queued for handling or its not. + parser->state = ParserEmpty; + break; + case ParserSysEx: + // end of sysex + if(byte == 0xf7) { + parser->state = ParserEmpty; + //queue_.push(incoming_message_); + parsed = true; + } else { + if(event->sysex_message_len < SYSEX_BUFFER_LEN) { + event->sysex_data[event->sysex_message_len] = byte; + event->sysex_message_len++; + } + } + break; + default: + break; + } + + return parsed; +} + +MidiEvent* midi_parser_get_message(MidiParser* parser) { + return &parser->incoming_message; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/parser.h b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/parser.h new file mode 100644 index 000000000..93630f026 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/parser.h @@ -0,0 +1,14 @@ +#pragma once +#include +#include +#include "message.h" + +typedef struct MidiParser MidiParser; + +MidiParser* midi_parser_alloc(void); + +void midi_parser_free(MidiParser* parser); + +bool midi_parser_parse(MidiParser* parser, uint8_t data); + +MidiEvent* midi_parser_get_message(MidiParser* parser); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/usb_message.c b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/usb_message.c new file mode 100644 index 000000000..b6844c5f4 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/usb_message.c @@ -0,0 +1,40 @@ +#include "usb_message.h" + +CodeIndex code_index_from_data(uint8_t data) { + return (CodeIndex)(data & 0b00001111); +} + +uint8_t cable_id_from_data(uint8_t data) { + return (data >> 4) & 0b00001111; +} + +uint8_t usb_message_data_size(CodeIndex code_index) { + uint8_t data_size = 0; + switch(code_index) { + case CodeIndexCommon1Byte: + /* case CodeIndexSysExEnd1Byte: */ + case CodeIndexSingleByte: + data_size = 1; + break; + case CodeIndexSysEx2Byte: + case CodeIndexSysExEnd2Byte: + case CodeIndexProgramChange: + case CodeIndexChannelPressure: + data_size = 2; + break; + case CodeIndexSysEx3Byte: + case CodeIndexSysExStart: + case CodeIndexSysExEnd3Byte: + case CodeIndexNoteOff: + case CodeIndexNoteOn: + case CodeIndexPolyKeyPress: + case CodeIndexControlChange: + case CodeIndexPitchBendChange: + data_size = 3; + break; + default: + break; + } + + return data_size; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/usb_message.h b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/usb_message.h new file mode 100644 index 000000000..852e9cb4f --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/midi/usb_message.h @@ -0,0 +1,28 @@ +#pragma once +#include + +typedef enum { + CodeIndexMisc = 0x0, /**< Reserved, MIDI Size: 1, 2, 3 */ + CodeIndexCableEvent = 0x1, /**< Reserved, MIDI Size: 1, 2, 3 */ + CodeIndexSysEx2Byte = 0x2, /**< MIDI Size: 2 */ + CodeIndexSysEx3Byte = 0x3, /**< MIDI Size: 3 */ + CodeIndexSysExStart = 0x4, /**< MIDI Size: 3 */ + CodeIndexCommon1Byte = 0x5, /**< MIDI Size: 1 */ + CodeIndexSysExEnd1Byte = 0x5, /**< MIDI Size: 1 */ + CodeIndexSysExEnd2Byte = 0x6, /**< MIDI Size: 2 */ + CodeIndexSysExEnd3Byte = 0x7, /**< MIDI Size: 3 */ + CodeIndexNoteOff = 0x8, /**< MIDI Size: 3 */ + CodeIndexNoteOn = 0x9, /**< MIDI Size: 3 */ + CodeIndexPolyKeyPress = 0xA, /**< MIDI Size: 3 */ + CodeIndexControlChange = 0xB, /**< MIDI Size: 3 */ + CodeIndexProgramChange = 0xC, /**< MIDI Size: 2 */ + CodeIndexChannelPressure = 0xD, /**< MIDI Size: 2 */ + CodeIndexPitchBendChange = 0xE, /**< MIDI Size: 3 */ + CodeIndexSingleByte = 0xF, /**< MIDI Size: 1 */ +} CodeIndex; + +CodeIndex code_index_from_data(uint8_t data); + +uint8_t cable_id_from_data(uint8_t data); + +uint8_t usb_message_data_size(CodeIndex code_index); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb/cm3_usb_audio.h b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb/cm3_usb_audio.h new file mode 100644 index 000000000..3c767f929 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb/cm3_usb_audio.h @@ -0,0 +1,234 @@ +/** @defgroup usb_audio_defines USB Audio Type Definitions + +@brief Defined Constants and Types for the USB Audio Type Definitions + +@ingroup USB_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2014 +Daniel Thompson +Seb Holzapfel + +@date 19 April 2014 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Daniel Thompson + * Copyright (C) 2018 Seb Holzapfel + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef LIBOPENCM3_USB_AUDIO_H +#define LIBOPENCM3_USB_AUDIO_H + +#include + +/* + * Definitions from the USB_AUDIO_ or usb_audio_ namespace come from: + * "Universal Serial Bus Class Definitions for Audio Devices, Revision 1.0" + */ + +/* Table A-1: Audio Interface Class Code */ +#define USB_CLASS_AUDIO 0x01 + +/* Table A-2: Audio Interface Subclass Codes */ +#define USB_AUDIO_SUBCLASS_UNDEFINED 0x00 +#define USB_AUDIO_SUBCLASS_CONTROL 0x01 +#define USB_AUDIO_SUBCLASS_AUDIOSTREAMING 0x02 +#define USB_AUDIO_SUBCLASS_MIDISTREAMING 0x03 + +/* Table A-4: Audio Class-specific Descriptor Types */ +#define USB_AUDIO_DT_CS_UNDEFINED 0x20 +#define USB_AUDIO_DT_CS_DEVICE 0x21 +#define USB_AUDIO_DT_CS_CONFIGURATION 0x22 +#define USB_AUDIO_DT_CS_STRING 0x23 +#define USB_AUDIO_DT_CS_INTERFACE 0x24 +#define USB_AUDIO_DT_CS_ENDPOINT 0x25 + +/* Table A-5: Audio Class-Specific AC Interface Descriptor Subtypes */ +#define USB_AUDIO_TYPE_AC_DESCRIPTOR_UNDEFINED 0x00 +#define USB_AUDIO_TYPE_HEADER 0x01 +#define USB_AUDIO_TYPE_INPUT_TERMINAL 0x02 +#define USB_AUDIO_TYPE_OUTPUT_TERMINAL 0x03 +#define USB_AUDIO_TYPE_MIXER_UNIT 0x04 +#define USB_AUDIO_TYPE_SELECTOR_UNIT 0x05 +#define USB_AUDIO_TYPE_FEATURE_UNIT 0x06 +#define USB_AUDIO_TYPE_PROCESSING_UNIT 0x07 +#define USB_AUDIO_TYPE_EXTENSION_UNIT 0x08 + +/* Table 4-2: Class-Specific AC Interface Header Descriptor (head) */ +struct usb_audio_header_descriptor_head { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint16_t bcdADC; + uint16_t wTotalLength; + uint8_t bInCollection; + /* ... */ +} __attribute__((packed)); + +/* Table 4-2: Class-Specific AC Interface Header Descriptor (body) */ +struct usb_audio_header_descriptor_body { + /* ... */ + uint8_t baInterfaceNr; +} __attribute__((packed)); + +/* Table 4-3: Input Terminal Descriptor */ +struct usb_audio_input_terminal_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t bNrChannels; + uint16_t wChannelConfig; + uint8_t iChannelNames; + uint8_t iTerminal; +} __attribute__((packed)); + +/* Table 4-3: Output Terminal Descriptor */ +struct usb_audio_output_terminal_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t bSourceID; + uint8_t iTerminal; +} __attribute__((packed)); + +/* Table 4-7: Feature Unit Descriptor (head) */ +struct usb_audio_feature_unit_descriptor_head { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bUnitID; + uint8_t bSourceID; + uint8_t bControlSize; + uint16_t bmaControlMaster; /* device can assume 16-bit, given highest + * defined bit in spec is bit #9. + * (it is thus required bControlSize=2) */ + /* ... */ +} __attribute__((packed)); + +/* Table 4-7: Feature Unit Descriptor (body) */ +struct usb_audio_feature_unit_descriptor_body { + /* ... */ + uint16_t bmaControl; + /* ... */ +} __attribute__((packed)); + +/* Table 4-7: Feature Unit Descriptor (tail) */ +struct usb_audio_feature_unit_descriptor_tail { + /* ... */ + uint8_t iFeature; +} __attribute__((packed)); + +/* Table 4-7: Feature Unit Descriptor (2-channel) + * + * This structure is a convenience covering the (common) case where + * there are 2 channels associated with the feature unit + */ +struct usb_audio_feature_unit_descriptor_2ch { + struct usb_audio_feature_unit_descriptor_head head; + struct usb_audio_feature_unit_descriptor_body channel_control[2]; + struct usb_audio_feature_unit_descriptor_tail tail; +} __attribute__((packed)); + +/* Table 4-19: Class-Specific AS Interface Descriptor */ +struct usb_audio_stream_interface_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bTerminalLink; + uint8_t bDelay; + uint16_t wFormatTag; +} __attribute__((packed)); + +/* Table 4-20: Standard AS Isochronous Audio Data Endpoint Descriptor */ +struct usb_audio_stream_endpoint_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; + uint8_t bRefresh; + uint8_t bSynchAddress; +} __attribute__((packed)); + +/* Table 4-21: Class-Specific AS Isochronous Audio Data Endpoint Descriptor */ +struct usb_audio_stream_audio_endpoint_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmAttributes; + uint8_t bLockDelayUnits; + uint16_t wLockDelay; +} __attribute__((packed)); + +/* + * Definitions from the USB_AUDIO_FORMAT_ or usb_audio_format_ namespace come from: + * "Universal Serial Bus Device Class Definition for Audio Data Formats, Revision 1.0" + */ + +/* Table 2-1: Type I Format Type Descriptor (head) */ +struct usb_audio_format_type1_descriptor_head { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bFormatType; + uint8_t bNrChannels; + uint8_t bSubFrameSize; + uint8_t bBitResolution; + uint8_t bSamFreqType; + /* ... */ +} __attribute__((packed)); + +/* Table 2-2: Continuous Sampling Frequency */ +struct usb_audio_format_continuous_sampling_frequency { + /* ... */ + uint32_t tLowerSamFreq : 24; + uint32_t tUpperSamFreq : 24; +} __attribute__((packed)); + +/* Table 2-3: Discrete Number of Sampling Frequencies */ +struct usb_audio_format_discrete_sampling_frequency { + /* ... */ + uint32_t tSamFreq : 24; +} __attribute__((packed)); + +/* Table 2-1: Type I Format Type Descriptor (1 sampling frequency) + * + * This structure is a convenience covering the (common) case where + * only 1 discrete sampling frequency is used + */ +struct usb_audio_format_type1_descriptor_1freq { + struct usb_audio_format_type1_descriptor_head head; + struct usb_audio_format_discrete_sampling_frequency freqs[1]; +} __attribute__((packed)); + +#endif + +/**@}*/ diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb/cm3_usb_midi.h b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb/cm3_usb_midi.h new file mode 100644 index 000000000..8435c883e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb/cm3_usb_midi.h @@ -0,0 +1,190 @@ +/** @defgroup usb_audio_defines USB MIDI Type Definitions + +@brief Defined Constants and Types for the USB MIDI Type Definitions + +@ingroup USB_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2014 +Daniel Thompson + +@date 19 April 2014 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2014 Daniel Thompson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef LIBOPENCM3_USB_MIDI_H +#define LIBOPENCM3_USB_MIDI_H + +#include + +/* + * Definitions from the USB_MIDI_ or usb_midi_ namespace come from: + * "Universal Serial Bus Class Definitions for MIDI Devices, Revision 1.0" + */ + +/* Appendix A.1: MS Class-Specific Interface Descriptor Subtypes */ +#define USB_MIDI_SUBTYPE_MS_DESCRIPTOR_UNDEFINED 0x00 +#define USB_MIDI_SUBTYPE_MS_HEADER 0x01 +#define USB_MIDI_SUBTYPE_MIDI_IN_JACK 0x02 +#define USB_MIDI_SUBTYPE_MIDI_OUT_JACK 0x03 +#define USB_MIDI_SUBTYPE_MIDI_ELEMENT 0x04 + +/* Appendix A.2: MS Class-Specific Endpoint Descriptor Subtypes */ +#define USB_MIDI_SUBTYPE_DESCRIPTOR_UNDEFINED 0x00 +#define USB_MIDI_SUBTYPE_MS_GENERAL 0x01 + +/* Appendix A.3: MS MIDI IN and OUT Jack types */ +#define USB_MIDI_JACK_TYPE_UNDEFINED 0x00 +#define USB_MIDI_JACK_TYPE_EMBEDDED 0x01 +#define USB_MIDI_JACK_TYPE_EXTERNAL 0x02 + +/* Appendix A.5.1 Endpoint Control Selectors */ +#define USB_MIDI_EP_CONTROL_UNDEFINED 0x00 +#define USB_MIDI_ASSOCIATION_CONTROL 0x01 + +/* Table 6-2: Class-Specific MS Interface Header Descriptor */ +struct usb_midi_header_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint16_t bcdMSC; + uint16_t wTotalLength; +} __attribute__((packed)); + +/* Table 6-3: MIDI IN Jack Descriptor */ +struct usb_midi_in_jack_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bJackType; + uint8_t bJackID; + uint8_t iJack; +} __attribute__((packed)); + +/* Table 6-4: MIDI OUT Jack Descriptor (head) */ +struct usb_midi_out_jack_descriptor_head { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bJackType; + uint8_t bJackID; + uint8_t bNrInputPins; + /* ... */ +} __attribute__((packed)); + +/* Table 6.4: MIDI OUT Jack Descriptor (body) */ +struct usb_midi_out_jack_descriptor_body { + /* ... */ + uint8_t baSourceID; + uint8_t baSourcePin; + /* ... */ +} __attribute__((packed)); + +/* Table 6.4: MIDI OUT Jack Descriptor (tail) */ +struct usb_midi_out_jack_descriptor_tail { + /* ... */ + uint8_t iJack; +} __attribute__((packed)); + +/* Table 6.4: MIDI OUT Jack Descriptor (single) + * + * This structure is a convenience covering the (normal) case where + * there is only one input pin. + */ +struct usb_midi_out_jack_descriptor { + struct usb_midi_out_jack_descriptor_head head; + struct usb_midi_out_jack_descriptor_body source[1]; + struct usb_midi_out_jack_descriptor_tail tail; +} __attribute__((packed)); + +/* Table 6-5: MIDI Element Descriptor (head) */ +struct usb_midi_element_descriptor_head { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bElementID; + uint8_t bNrInputPins; + /* ... */ +} __attribute__((packed)); + +/* Table 6-5: MIDI Element Descriptor (body) */ +struct usb_midi_element_descriptor_body { + /* ... */ + uint8_t baSourceID; + uint8_t baSourcePin; + /* ... */ +} __attribute__((packed)); + +/* Table 6-5: MIDI Element Descriptor (tail) */ +struct usb_midi_element_descriptor_tail { + /* ... */ + uint8_t bNrOutputPins; + uint8_t bInTerminalLink; + uint8_t bOutTerminalLink; + uint8_t bElCapsSize; + uint16_t bmElementCaps; /* host cannot assume this is 16-bit but device + can (since highest defined bitmap value in + v1.0 is bit 11) */ + uint8_t iElement; +} __attribute__((packed)); + +/* Table 6-5: MIDI Element Descriptor (single) + * + * This structure is a convenience covering the (common) case where + * there is only one input pin. + */ +struct usb_midi_element_descriptor { + struct usb_midi_element_descriptor_head head; + struct usb_midi_element_descriptor_body source[1]; + struct usb_midi_element_descriptor_tail tail; +} __attribute__((packed)); + +/* Table 6-7: Class-specific MS Bulk Data Endpoint Descriptor (head) */ +struct usb_midi_endpoint_descriptor_head { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bNumEmbMIDIJack; +} __attribute__((packed)); + +/* Table 6-7: Class-specific MS Bulk Data Endpoint Descriptor (body) */ +struct usb_midi_endpoint_descriptor_body { + uint8_t baAssocJackID; +} __attribute__((packed)); + +/* Table 6.7: Class-specific MS Bulk Data Endpoint Descriptor (single) + * + * This structure is a convenience covering the (normal) case where + * there is only one input pin. + */ +struct usb_midi_endpoint_descriptor { + struct usb_midi_endpoint_descriptor_head head; + struct usb_midi_endpoint_descriptor_body jack[1]; +} __attribute__((packed)); + +#endif + +/**@}*/ diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb/usb_midi_driver.c b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb/usb_midi_driver.c new file mode 100644 index 000000000..9abf77d12 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb/usb_midi_driver.c @@ -0,0 +1,428 @@ +#include +#include +#include +#include + +#include "usb_midi_driver.h" +#include "cm3_usb_audio.h" +#include "cm3_usb_midi.h" + +// Appendix B. "Example: Simple MIDI Adapter" from "Universal Serial Bus Device Class Definition for MIDI Devices", Revision 1.0 + +#define USB_VID 0x6666 +#define USB_PID 0x5119 + +#define USB_EP0_SIZE 8 + +#define USB_MIDI_EP_SIZE 64 +#define USB_MIDI_EP_IN 0x81 +#define USB_MIDI_EP_OUT 0x01 + +#define EP_CFG_DECONFIGURE 0 +#define EP_CFG_CONFIGURE 1 + +enum { + USB_STR_ZERO, + USB_STR_MANUFACTURER, + USB_STR_PRODUCT, + USB_STR_SERIAL_NUMBER, +}; + +/* + B.1 Device Descriptor +*/ +static const struct usb_device_descriptor device_descriptor = { + .bLength = sizeof(struct usb_device_descriptor), + .bDescriptorType = USB_DTYPE_DEVICE, + .bcdUSB = VERSION_BCD(2, 0, 0), // was 0x0110, 1.10 - current revision of USBspecification. + .bDeviceClass = USB_CLASS_PER_INTERFACE, + .bDeviceSubClass = USB_SUBCLASS_NONE, + .bDeviceProtocol = USB_PROTO_NONE, + .bMaxPacketSize0 = USB_EP0_SIZE, + .idVendor = USB_VID, + .idProduct = USB_PID, + .bcdDevice = VERSION_BCD(1, 0, 0), + .iManufacturer = USB_STR_MANUFACTURER, + .iProduct = USB_STR_PRODUCT, + .iSerialNumber = USB_STR_SERIAL_NUMBER, + .bNumConfigurations = 1, +}; + +struct usb_audio_header_descriptor { + struct usb_audio_header_descriptor_head head; + struct usb_audio_header_descriptor_body body; +} __attribute__((packed)); + +struct usb_midi_jacks_descriptor { + struct usb_midi_header_descriptor header; + struct usb_midi_in_jack_descriptor in_embedded; + struct usb_midi_in_jack_descriptor in_external; + struct usb_midi_out_jack_descriptor out_embedded; + struct usb_midi_out_jack_descriptor out_external; +} __attribute__((packed)); + +struct MidiConfigDescriptor { + /* + B.2 Configuration Descriptor + */ + struct usb_config_descriptor config; + + /* + B.3 AudioControl Interface Descriptors + + The AudioControl interface describes the device structure (audio function topology) + and is used to manipulate the Audio Controls. This device has no audio function incorporated. + However, the AudioControl interface is mandatory and therefore both the standard AC interface + descriptor and the classspecific AC interface descriptor must be present. + The class-specific AC interface descriptor only contains the header descriptor. + */ + // B.3.1 Standard AC Interface Descriptor + struct usb_interface_descriptor audio_control_iface; + // B.3.2 Class-specific AC Interface Descriptor + struct usb_audio_header_descriptor audio_control_header; + + /* + B.4 MIDIStreaming Interface Descriptors + */ + // B.4.1 Standard MS Interface Descriptor + struct usb_interface_descriptor midi_streaming_iface; + // B.4.2 Class-specific MS Interface Descriptor + // B.4.3 MIDI IN Jack Descriptor + // B.4.4 MIDI OUT Jack Descriptor + struct usb_midi_jacks_descriptor midi_jacks; + + /* + B.5 Bulk OUT Endpoint Descriptors + */ + // B.5.1 Standard Bulk OUT Endpoint Descriptor + struct usb_endpoint_descriptor bulk_out; + // B.5.2 Class-specific MS Bulk OUT Endpoint Descriptor + struct usb_midi_endpoint_descriptor midi_bulk_out; + + /* + B.6 Bulk IN Endpoint Descriptors + */ + // B.6.1 Standard Bulk IN Endpoint Descriptor + struct usb_endpoint_descriptor bulk_in; + // B.6.2 Class-specific MS Bulk IN Endpoint Descriptor + struct usb_midi_endpoint_descriptor midi_bulk_in; +} __attribute__((packed)); + +static const struct MidiConfigDescriptor config_descriptor = { + .config = + { + .bLength = sizeof(struct usb_config_descriptor), + .bDescriptorType = USB_DTYPE_CONFIGURATION, + .wTotalLength = sizeof(struct MidiConfigDescriptor), + .bNumInterfaces = 2, /* control and data */ + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = USB_CFG_ATTR_RESERVED, + .bMaxPower = USB_CFG_POWER_MA(100), + }, + .audio_control_iface = + { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DTYPE_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = USB_AUDIO_SUBCLASS_CONTROL, + .bInterfaceProtocol = USB_PROTO_NONE, + .iInterface = 0, + }, + .audio_control_header = + { + .head = + { + .bLength = sizeof(struct usb_audio_header_descriptor), + .bDescriptorType = USB_AUDIO_DT_CS_INTERFACE, + .bDescriptorSubtype = USB_AUDIO_TYPE_HEADER, + .bcdADC = VERSION_BCD(1, 0, 0), + .wTotalLength = sizeof(struct usb_audio_header_descriptor), + .bInCollection = 1, + }, + .body = + { + .baInterfaceNr = 1, + }, + }, + .midi_streaming_iface = + { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DTYPE_INTERFACE, + .bInterfaceNumber = 1, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = USB_AUDIO_SUBCLASS_MIDISTREAMING, + .bInterfaceProtocol = USB_PROTO_NONE, + .iInterface = 0, + }, + .midi_jacks = + { + .header = + { + .bLength = sizeof(struct usb_midi_header_descriptor), + .bDescriptorType = USB_AUDIO_DT_CS_INTERFACE, + .bDescriptorSubtype = USB_MIDI_SUBTYPE_MS_HEADER, + .bcdMSC = VERSION_BCD(1, 0, 0), + .wTotalLength = sizeof(struct usb_midi_jacks_descriptor), + }, + .in_embedded = + { + .bLength = sizeof(struct usb_midi_in_jack_descriptor), + .bDescriptorType = USB_AUDIO_DT_CS_INTERFACE, + .bDescriptorSubtype = USB_MIDI_SUBTYPE_MIDI_IN_JACK, + .bJackType = USB_MIDI_JACK_TYPE_EMBEDDED, + .bJackID = 0x01, + .iJack = 0x00, + }, + .in_external = + { + .bLength = sizeof(struct usb_midi_in_jack_descriptor), + .bDescriptorType = USB_AUDIO_DT_CS_INTERFACE, + .bDescriptorSubtype = USB_MIDI_SUBTYPE_MIDI_IN_JACK, + .bJackType = USB_MIDI_JACK_TYPE_EXTERNAL, + .bJackID = 0x02, + .iJack = 0x00, + }, + .out_embedded = + { + .head = + { + .bLength = sizeof(struct usb_midi_out_jack_descriptor), + .bDescriptorType = USB_AUDIO_DT_CS_INTERFACE, + .bDescriptorSubtype = USB_MIDI_SUBTYPE_MIDI_OUT_JACK, + .bJackType = USB_MIDI_JACK_TYPE_EMBEDDED, + .bJackID = 0x03, + .bNrInputPins = 1, + }, + .source[0] = + { + .baSourceID = 0x02, + .baSourcePin = 0x01, + }, + .tail = + { + .iJack = 0x00, + }, + }, + .out_external = + { + .head = + { + .bLength = sizeof(struct usb_midi_out_jack_descriptor), + .bDescriptorType = USB_AUDIO_DT_CS_INTERFACE, + .bDescriptorSubtype = USB_MIDI_SUBTYPE_MIDI_OUT_JACK, + .bJackType = USB_MIDI_JACK_TYPE_EXTERNAL, + .bJackID = 0x04, + .bNrInputPins = 1, + }, + .source[0] = + { + .baSourceID = 0x01, + .baSourcePin = 0x01, + }, + .tail = + { + .iJack = 0x00, + }, + }, + }, + .bulk_out = + { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = USB_MIDI_EP_OUT, + .bmAttributes = USB_EPTYPE_BULK, + .wMaxPacketSize = USB_MIDI_EP_SIZE, + .bInterval = 0, + }, + .midi_bulk_out = + { + .head = + { + .bLength = sizeof(struct usb_midi_endpoint_descriptor), + .bDescriptorType = USB_AUDIO_DT_CS_ENDPOINT, + .bDescriptorSubType = USB_MIDI_SUBTYPE_MS_GENERAL, + .bNumEmbMIDIJack = 1, + }, + .jack[0] = + { + .baAssocJackID = 0x01, + }, + }, + .bulk_in = + { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = USB_MIDI_EP_IN, + .bmAttributes = USB_EPTYPE_BULK, + .wMaxPacketSize = USB_MIDI_EP_SIZE, + .bInterval = 0, + }, + .midi_bulk_in = + { + .head = + { + .bLength = sizeof(struct usb_midi_endpoint_descriptor), + .bDescriptorType = USB_AUDIO_DT_CS_ENDPOINT, + .bDescriptorSubType = USB_MIDI_SUBTYPE_MS_GENERAL, + .bNumEmbMIDIJack = 1, + }, + .jack[0] = + { + .baAssocJackID = 0x03, + }, + }, +}; + +static const struct usb_string_descriptor dev_manufacturer_string = + USB_STRING_DESC("Flipper Devices Inc."); + +static const struct usb_string_descriptor dev_product_string = + USB_STRING_DESC("Flipper MIDI Device"); + +static const struct usb_string_descriptor dev_serial_number_string = + USB_STRING_DESC("Serial Number"); + +static void midi_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx); +static void midi_deinit(usbd_device* dev); +static void midi_on_wakeup(usbd_device* dev); +static void midi_on_suspend(usbd_device* dev); +static usbd_respond midi_ep_config(usbd_device* dev, uint8_t cfg); +static usbd_respond midi_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback); + +FuriHalUsbInterface midi_usb_interface = { + .init = midi_init, + .deinit = midi_deinit, + .wakeup = midi_on_wakeup, + .suspend = midi_on_suspend, + .dev_descr = (struct usb_device_descriptor*)&device_descriptor, + .cfg_descr = (void*)&config_descriptor, +}; + +typedef struct { + usbd_device* dev; + MidiRxCallback rx_callback; + void* context; + FuriSemaphore* semaphore_tx; + bool connected; +} MidiUsb; + +static MidiUsb midi_usb; + +void midi_usb_set_context(void* context) { + midi_usb.context = context; +} + +void midi_usb_set_rx_callback(MidiRxCallback callback) { + midi_usb.rx_callback = callback; +} + +size_t midi_usb_rx(uint8_t* buffer, size_t size) { + size_t len = usbd_ep_read(midi_usb.dev, USB_MIDI_EP_OUT, buffer, size); + return len; +} + +size_t midi_usb_tx(uint8_t* buffer, uint8_t size) { + if((midi_usb.semaphore_tx == NULL) || (midi_usb.connected == false)) return 0; + + furi_check(furi_semaphore_acquire(midi_usb.semaphore_tx, FuriWaitForever) == FuriStatusOk); + + if(midi_usb.connected) { + int32_t len = usbd_ep_write(midi_usb.dev, USB_MIDI_EP_IN, buffer, size); + return len; + } else { + return 0; + } +} + +static void midi_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) { + UNUSED(intf); + UNUSED(ctx); + + midi_usb_interface.str_manuf_descr = (void*)&dev_manufacturer_string; + midi_usb_interface.str_prod_descr = (void*)&dev_product_string; + midi_usb_interface.str_serial_descr = (void*)&dev_serial_number_string; + midi_usb_interface.dev_descr->idVendor = USB_VID; + midi_usb_interface.dev_descr->idProduct = USB_PID; + + midi_usb.dev = dev; + if(midi_usb.semaphore_tx == NULL) midi_usb.semaphore_tx = furi_semaphore_alloc(1, 1); + + usbd_reg_config(dev, midi_ep_config); + usbd_reg_control(dev, midi_control); + + usbd_connect(dev, true); +} + +static void midi_deinit(usbd_device* dev) { + midi_usb.connected = false; + midi_usb.dev = NULL; + furi_semaphore_free(midi_usb.semaphore_tx); + + usbd_reg_config(dev, NULL); + usbd_reg_control(dev, NULL); +} + +static void midi_on_wakeup(usbd_device* dev) { + UNUSED(dev); + if(!midi_usb.connected) { + midi_usb.connected = true; + } +} + +static void midi_on_suspend(usbd_device* dev) { + UNUSED(dev); + if(midi_usb.connected) { + midi_usb.connected = false; + } +} + +static void midi_tx_rx(usbd_device* dev, uint8_t event, uint8_t ep) { + UNUSED(dev); + UNUSED(ep); + + switch(event) { + case usbd_evt_eptx: + furi_semaphore_release(midi_usb.semaphore_tx); + break; + case usbd_evt_eprx: + if(midi_usb.rx_callback != NULL) { + midi_usb.rx_callback(midi_usb.context); + } + break; + default: + break; + } +} + +static usbd_respond midi_ep_config(usbd_device* dev, uint8_t cfg) { + switch(cfg) { + case EP_CFG_DECONFIGURE: + usbd_ep_deconfig(dev, USB_MIDI_EP_OUT); + usbd_ep_deconfig(dev, USB_MIDI_EP_IN); + usbd_reg_endpoint(dev, USB_MIDI_EP_OUT, NULL); + usbd_reg_endpoint(dev, USB_MIDI_EP_IN, NULL); + return usbd_ack; + case EP_CFG_CONFIGURE: + usbd_ep_config(dev, USB_MIDI_EP_OUT, USB_EPTYPE_BULK, USB_MIDI_EP_SIZE); + usbd_ep_config(dev, USB_MIDI_EP_IN, USB_EPTYPE_BULK, USB_MIDI_EP_SIZE); + usbd_reg_endpoint(dev, USB_MIDI_EP_OUT, midi_tx_rx); + usbd_reg_endpoint(dev, USB_MIDI_EP_IN, midi_tx_rx); + return usbd_ack; + default: + return usbd_fail; + } +} + +static usbd_respond midi_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback) { + UNUSED(dev); + UNUSED(req); + UNUSED(callback); + + return usbd_fail; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb/usb_midi_driver.h b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb/usb_midi_driver.h new file mode 100644 index 000000000..d385efcb5 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb/usb_midi_driver.h @@ -0,0 +1,14 @@ +#pragma once +#include + +extern FuriHalUsbInterface midi_usb_interface; + +typedef void (*MidiRxCallback)(void* context); + +void midi_usb_set_context(void* context); + +void midi_usb_set_rx_callback(MidiRxCallback callback); + +size_t midi_usb_rx(uint8_t* buffer, size_t size); + +size_t midi_usb_tx(uint8_t* buffer, uint8_t size); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb_midi.c b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb_midi.c new file mode 100644 index 000000000..ec8856301 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb_midi.c @@ -0,0 +1,86 @@ +#include +#include +#include "usb/usb_midi_driver.h" +#include "midi/parser.h" +#include "midi/usb_message.h" +#include + +float note_to_frequency(int note) { + float a = 440; + return (a / 32) * powf(2, ((note - 9) / 12.0)); +} + +typedef enum { + MidiThreadEventStop = (1 << 0), + MidiThreadEventRx = (1 << 1), + MidiThreadEventAll = MidiThreadEventStop | MidiThreadEventRx, +} MidiThreadEvent; + +static void midi_rx_callback(void* context) { + furi_assert(context); + FuriThreadId thread_id = (FuriThreadId)context; + furi_thread_flags_set(thread_id, MidiThreadEventRx); +} + +int32_t usb_midi_app(void* p) { + UNUSED(p); + + FuriHalUsbInterface* usb_config_prev; + usb_config_prev = furi_hal_usb_get_config(); + midi_usb_set_context(furi_thread_get_id(furi_thread_get_current())); + midi_usb_set_rx_callback(midi_rx_callback); + furi_hal_usb_set_config(&midi_usb_interface, NULL); + + MidiParser* parser = midi_parser_alloc(); + uint32_t events; + uint8_t current_note = 255; + + while(1) { + events = furi_thread_flags_wait(MidiThreadEventAll, FuriFlagWaitAny, FuriWaitForever); + + if(!(events & FuriFlagError)) { + if(events & MidiThreadEventRx) { + uint8_t buffer[64]; + size_t size = midi_usb_rx(buffer, sizeof(buffer)); + // loopback + // midi_usb_tx(buffer, size); + size_t start = 0; + while(start < size) { + CodeIndex code_index = code_index_from_data(buffer[start]); + uint8_t data_size = usb_message_data_size(code_index); + if(data_size == 0) break; + + start += 1; + for(size_t j = 0; j < data_size; j++) { + if(midi_parser_parse(parser, buffer[start + j])) { + MidiEvent* event = midi_parser_get_message(parser); + if(event->type == NoteOn) { + NoteOnEvent note_on = AsNoteOn(event); + current_note = note_on.note; + if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { + furi_hal_speaker_start( + note_to_frequency(note_on.note), + note_on.velocity / 127.0f); + } + } else if(event->type == NoteOff) { + NoteOffEvent note_off = AsNoteOff(event); + if(note_off.note == current_note) { + if(furi_hal_speaker_is_mine()) { + furi_hal_speaker_stop(); + furi_hal_speaker_release(); + } + } + } + } + } + start += data_size; + } + } + } + } + + midi_parser_free(parser); + furi_hal_usb_set_config(usb_config_prev, NULL); + + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb_midi.png b/Applications/Official/DEV_FW/source/xMasterX/usb_midi/usb_midi.png new file mode 100644 index 0000000000000000000000000000000000000000..6d0ac6fed3cdb934124017206bb67c83d0b0ed31 GIT binary patch literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>@$qzV43U^R zwa<|6fB^?{?v?-bKX;i-^*(VS+QBS=N5OO3*Dd-hXTFo$aV)o5dW}igTg3*Q%PPB literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/videopoker/application.fam b/Applications/Official/DEV_FW/source/xMasterX/videopoker/application.fam new file mode 100644 index 000000000..c7b46047b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/videopoker/application.fam @@ -0,0 +1,12 @@ +App( + appid="VideoPoker", + name="Video Poker", + apptype=FlipperAppType.EXTERNAL, + entry_point="video_poker_app", + cdefines=["APP_VIDEOPOKER_GAME"], + requires=["gui"], + stack_size=2 * 1024, + order=270, + fap_icon="pokerIcon.png", + fap_category="Games_Extra", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/videopoker/poker.c b/Applications/Official/DEV_FW/source/xMasterX/videopoker/poker.c new file mode 100644 index 000000000..0205d1319 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/videopoker/poker.c @@ -0,0 +1,820 @@ +#include +#include +#include +#include +#include +#include +#include +#include "assets_icons.h" +#include + +/* Core game logic from +https://github.com/Yaoir/VideoPoker-C +*/ + +/* KNOWN BUGS +This has been converted from a standalone PC console app to flipper +All of the original input/output handing code has been ripped out +Original code also used TONS of defines and everything was a global. +As is, it does what I wanted and doesn't seem to have major issues, so that's pretty good. +Game logic is handled during input and this is a bit of a mess of nested ifs. +Sometimes duplicate cards will show up. there is a function to test this. I should use it better. + +*/ + +#define TAG "Video Poker" + +static void Shake(void) { + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + notification_message(notification, &sequence_single_vibro); + furi_record_close(RECORD_NOTIFICATION); +} + +typedef struct { + int index; /* cards value, minus 1 */ + char* sym; /* text appearance */ + int suit; /* card's suit (see just below) */ + int gone; /* true if it's been dealt */ + int held; /* for hand */ +} PokerPlayer_card; + +typedef struct { + FuriMutex** model_mutex; + FuriMessageQueue* event_queue; + ViewPort* view_port; + Gui* gui; + PokerPlayer_card hand[5]; + PokerPlayer_card shand[5]; + PokerPlayer_card deck[52]; + int GameType; /* What rules are we using */ + int held[5]; + int score; + int highscore; + int pot; + int GameState; + int selected; + int bet; + int minbet; +} PokerPlayer; + +/* GameState +0=Splash/help, OK button (later on up/down for rules or settings) +1=cards down, betting enabled, left/right to change bet, OK to confirm +2=first hand, holding enabled, left/right to pick card, OK to hold/unhold card, down to confirm +3=second hand, only confirm to claim rewards +4=game over/won +5=WIP saving gamestate +*/ + +/* +#define AllAmerican 0 +#define TensOrBetter 1 +#define BonusPoker 2 +#define DoubleBonus 3 +#define DoubleBonusBonus 4 +#define JacksOrBetter 5 +#define JacksOrBetter95 6 +#define JacksOrBetter86 7 +#define JacksOrBetter85 8 +#define JacksOrBetter75 9 +#define JacksOrBetter65 10 +#define NUMGAMES 11 +*/ +/* + The game in play. Default is Jacks or Better, + which is coded into initialization of static data +*/ +const char* gamenames[11] = { + "All American", + "Tens or Better", + "Bonus Poker", + "Double Bonus", + "Double Bonus Bonus", + "Jacks or Better", + "9/5 Jacks or Better", + "8/6 Jacks or Better", + "8/5 Jacks or Better", + "7/5 Jacks or Better", + "6/5 Jacks or Better"}; + +PokerPlayer_card deck[52] = { + /* index, card name, suit, gone */ + /* Clubs:0 Diamonds:1 Hearts: 2 Spades: 3 */ + {1, "2", 0, 0, 0}, {2, "3", 0, 0, 0}, {3, "4", 0, 0, 0}, {4, "5", 0, 0, 0}, + {5, "6", 0, 0, 0}, {6, "7", 0, 0, 0}, {7, "8", 0, 0, 0}, {8, "9", 0, 0, 0}, + {9, "10", 0, 0, 0}, {10, "J", 0, 0, 0}, {11, "Q", 0, 0, 0}, {12, "K", 0, 0, 0}, + {13, "A", 0, 0, 0}, + + {1, "2", 1, 0, 0}, {2, "3", 1, 0, 0}, {3, "4", 1, 0, 0}, {4, "5", 1, 0, 0}, + {5, "6", 1, 0, 0}, {6, "7", 1, 0, 0}, {7, "8", 1, 0, 0}, {8, "9", 1, 0, 0}, + {9, "10", 1, 0, 0}, {10, "J", 1, 0, 0}, {11, "Q", 1, 0, 0}, {12, "K", 1, 0, 0}, + {13, "A", 1, 0, 0}, + + {1, "2", 2, 0, 0}, {2, "3", 2, 0, 0}, {3, "4", 2, 0, 0}, {4, "5", 2, 0, 0}, + {5, "6", 2, 0, 0}, {6, "7", 2, 0, 0}, {7, "8", 2, 0, 0}, {8, "9", 2, 0, 0}, + {9, "10", 2, 0, 0}, {10, "J", 2, 0, 0}, {11, "Q", 2, 0, 0}, {12, "K", 2, 0, 0}, + {13, "A", 2, 0, 0}, + + {1, "2", 3, 0, 0}, {2, "3", 3, 0, 0}, {3, "4", 3, 0, 0}, {4, "5", 3, 0, 0}, + {5, "6", 3, 0, 0}, {6, "7", 3, 0, 0}, {7, "8", 3, 0, 0}, {8, "9", 3, 0, 0}, + {9, "10", 3, 0, 0}, {10, "J", 3, 0, 0}, {11, "Q", 3, 0, 0}, {12, "K", 3, 0, 0}, + {13, "A", 3, 0, 0}, +}; + +/* +Image Format +0x01 = Compressed +0x00 = Reserved Section +0xa4,0x01 = 0x1a4, or, 420 - the size of the compressed array, minus this header. +Rest of the data is char array output from heatshrink of the original XBM char array. +Calculated Header: 0x01,0x00,0xa4,0x01 +from furi_hal_compress.c: +typedef struct { + uint8_t is_compressed; + uint8_t reserved; + uint16_t compressed_buff_size; +} FuriHalCompressHeader; +*/ + +const uint8_t _I_Splash_128x64_0[] = { + 0x01, 0x00, 0x8a, 0x02, 0x00, 0x78, 0x02, 0x60, 0xe0, 0x54, 0xc0, 0x03, 0x9f, 0xc0, 0x0f, 0x5a, + 0x04, 0x04, 0x1e, 0xdf, 0x08, 0x78, 0x0c, 0x60, 0xc0, 0x21, 0x90, 0x40, 0xa3, 0x00, 0xf5, 0xfe, + 0x61, 0xc1, 0xe9, 0x1e, 0x8e, 0x59, 0xf0, 0x02, 0x24, 0x9f, 0x70, 0xc0, 0x63, 0x03, 0x01, 0x0c, + 0x0b, 0xc1, 0x80, 0xbc, 0x83, 0xd3, 0x3f, 0x63, 0x98, 0x03, 0xcf, 0x88, 0x02, 0x1c, 0x31, 0x5d, + 0x38, 0xf6, 0x19, 0xc0, 0xa0, 0xfc, 0x93, 0x13, 0x12, 0xf0, 0x38, 0x76, 0x08, 0xc7, 0x00, 0x1e, + 0x5e, 0x8b, 0xcc, 0x32, 0x86, 0x0f, 0x4f, 0x0c, 0x80, 0x06, 0x20, 0x72, 0xe4, 0x5e, 0x33, 0xd4, + 0x73, 0xf2, 0x5d, 0xe2, 0x10, 0xef, 0xe6, 0x02, 0x0f, 0x07, 0x84, 0x4c, 0x33, 0xd2, 0x70, 0x79, + 0xd8, 0x2e, 0x11, 0x88, 0x3d, 0xff, 0xc1, 0xc7, 0x83, 0xc4, 0x20, 0x10, 0xc9, 0x18, 0x3d, 0x27, + 0x18, 0x8c, 0x3c, 0xde, 0xe1, 0xe6, 0x87, 0x7e, 0x0c, 0x62, 0x12, 0x10, 0x01, 0xce, 0x31, 0x9c, + 0x39, 0x9c, 0x62, 0x67, 0x0f, 0x83, 0x7f, 0x27, 0xe0, 0xf5, 0x8c, 0x71, 0xbc, 0x31, 0x8c, 0xc4, + 0xe2, 0x1e, 0x62, 0x1e, 0x02, 0xe0, 0x80, 0x05, 0x1c, 0xe1, 0xdc, 0x23, 0x97, 0xc8, 0xe4, 0x5c, + 0x12, 0x50, 0x40, 0x7a, 0x43, 0x38, 0x77, 0x88, 0xf4, 0x36, 0x3d, 0x1f, 0x04, 0x94, 0x20, 0x1e, + 0x98, 0xce, 0x0d, 0xbe, 0x37, 0x0d, 0xcd, 0xbd, 0x0c, 0x7e, 0xbe, 0xce, 0x07, 0x1f, 0xf3, 0xfc, + 0xf8, 0xb2, 0x8d, 0x30, 0x20, 0x53, 0xbe, 0x60, 0x06, 0x03, 0x78, 0xf0, 0x06, 0x4c, 0x1e, 0x34, + 0x10, 0x29, 0x5e, 0x05, 0x0f, 0x00, 0xa0, 0x40, 0x24, 0x20, 0x52, 0x76, 0x88, 0x01, 0xc1, 0xe3, + 0x11, 0x05, 0xc3, 0xe9, 0x20, 0x10, 0x97, 0x01, 0xcf, 0xc1, 0xf2, 0x81, 0x3f, 0xe7, 0xfc, 0x66, + 0xf4, 0x02, 0xf1, 0xc0, 0x3f, 0xdf, 0xf0, 0x30, 0xc6, 0x1e, 0xe5, 0xff, 0x81, 0xf0, 0x3f, 0xe5, + 0xb2, 0x80, 0x7f, 0xc1, 0xe5, 0x1c, 0x03, 0x0f, 0xe3, 0xff, 0x1f, 0xf8, 0x02, 0x48, 0x00, 0x31, + 0xfe, 0x0b, 0xa4, 0x61, 0xcc, 0x62, 0xfc, 0x4f, 0xe3, 0x0f, 0x31, 0x41, 0x0e, 0x02, 0x07, 0x01, + 0x07, 0x8a, 0xb4, 0xa3, 0x84, 0x71, 0x8f, 0xff, 0x20, 0x77, 0x00, 0x78, 0x95, 0x46, 0x06, 0x13, + 0x10, 0x78, 0xef, 0x3f, 0x5f, 0xfc, 0xff, 0xea, 0x07, 0xf0, 0x37, 0x90, 0x3c, 0x78, 0x00, 0xf2, + 0xae, 0x7f, 0x77, 0xf7, 0xaf, 0xec, 0x0f, 0x88, 0x41, 0x1b, 0x06, 0x02, 0x03, 0xc0, 0x02, 0x8c, + 0x08, 0x5c, 0x37, 0xff, 0xa9, 0x3c, 0x7b, 0xcc, 0x52, 0xe0, 0x70, 0x7c, 0x31, 0x89, 0xe4, 0xff, + 0xfb, 0xff, 0xdf, 0x8c, 0x46, 0x03, 0x1f, 0x34, 0x17, 0x83, 0xe1, 0x71, 0x8f, 0x6f, 0xe7, 0xe0, + 0xc1, 0x8f, 0xfd, 0x20, 0x18, 0x65, 0x59, 0x47, 0xaf, 0x9b, 0x8b, 0x9e, 0x6f, 0xe7, 0x1f, 0x16, + 0x0c, 0x3e, 0x3d, 0x00, 0xe4, 0x43, 0xd1, 0xe5, 0x3f, 0xe6, 0x6e, 0xfb, 0x39, 0x88, 0x67, 0xea, + 0xff, 0xc5, 0x22, 0x8f, 0xc0, 0xf0, 0x41, 0x71, 0xe7, 0x76, 0xf9, 0x98, 0x48, 0x64, 0x17, 0x59, + 0x38, 0x05, 0x8f, 0xc0, 0xd0, 0x5f, 0xe8, 0x0f, 0x1a, 0xdb, 0xe6, 0xb1, 0xd1, 0xa0, 0x50, 0x85, + 0x59, 0x7e, 0x16, 0x05, 0x06, 0x80, 0x71, 0xbf, 0xf7, 0x19, 0x85, 0x99, 0x74, 0x6d, 0x31, 0x02, + 0x10, 0x88, 0x7c, 0xdd, 0xdb, 0x84, 0x62, 0x7c, 0x0f, 0x38, 0xe5, 0xf0, 0x1e, 0x97, 0xce, 0x67, + 0xbc, 0xb6, 0x40, 0xa3, 0x98, 0x00, 0xc5, 0x76, 0x53, 0x8c, 0x67, 0x1e, 0x07, 0x0e, 0x63, 0x0a, + 0xe4, 0x9c, 0x62, 0x0f, 0x11, 0x41, 0x95, 0x88, 0x1e, 0x41, 0xd1, 0x8c, 0x49, 0x80, 0xe6, 0x00, + 0x50, 0xb8, 0xa3, 0x07, 0xf1, 0x7f, 0x06, 0xb8, 0x00, 0x61, 0xce, 0xb2, 0x9c, 0x53, 0x01, 0xf3, + 0xf0, 0x55, 0x97, 0xd0, 0x3f, 0x40, 0x03, 0xfd, 0x33, 0xc8, 0x01, 0x71, 0x92, 0x78, 0x80, 0x2f, + 0x80, 0x6f, 0x20, 0x03, 0xff, 0x23, 0xe7, 0x02, 0x02, 0x18, 0x01, 0xa3, 0x91, 0x00, 0x18, 0xc3, + 0x20, 0x91, 0xc0, 0x7c, 0x7f, 0x83, 0x42, 0xaa, 0x1f, 0xe0, 0xbe, 0x60, 0x46, 0xa2, 0x81, 0xe2, + 0x24, 0x21, 0xf9, 0x54, 0x14, 0x18, 0x9e, 0x3f, 0xe4, 0x29, 0x00, 0x12, 0x0e, 0xb0, 0x28, 0x50, + 0x3c, 0x60, 0x50, 0x85, 0xf4, 0x7f, 0xb8, 0x3f, 0xf3, 0xf8, 0x83, 0xe0, 0x00, 0x38, 0x6e, 0x0c, + 0xc3, 0xf2, 0x2f, 0x94, 0x09, 0x07, 0xc7, 0xf7, 0x3f, 0xfe, 0x0d, 0xc4, 0x00, 0xfc, 0x4c, 0x05, + 0x86, 0x15, 0x23, 0x92, 0x03, 0xe7, 0xf9, 0x80, 0x0f, 0x97, 0x52, 0x0c, 0x2f, 0xb1, 0xf8, 0xe3, + 0x01, 0xf3, 0x82, 0x27, 0x8d, 0xe6, 0x41, 0x1c, 0x17, 0xcf, 0xfc, 0x3e, 0x64, 0xf8, +}; +const uint8_t* _I_Splash_128x64[] = {_I_Splash_128x64_0}; +const Icon I_Splash_128x64 = + {.width = 128, .height = 64, .frame_count = 1, .frame_rate = 0, .frames = _I_Splash_128x64}; + +/* +const uint8_t _I_BadEnd_128x64_0[] = { + 0x01, 0x00, 0xDF, 0x01, 0x00, 0x2c, 0x12, 0x01, 0x02, 0x80, 0x40, 0x70, 0x10, 0x0a, 0x04, 0x02, + 0x41, 0x3e, 0xcf, 0x63, 0xfb, 0xfe, 0xc8, 0x18, 0x3e, 0x6f, 0xdb, 0xfc, 0xf8, 0x3c, 0x60, 0xe0, + 0xf9, 0xb3, 0x6c, 0xf3, 0x3c, 0x1b, 0x6c, 0x18, 0x5f, 0x40, 0xf1, 0xe7, 0xdb, 0xc1, 0xf4, 0x2f, + 0x10, 0x78, 0xdb, 0xbc, 0xdf, 0xf0, 0x04, 0x59, 0x81, 0xe3, 0xc1, 0xb6, 0x41, 0x83, 0xd1, 0x00, + 0xbf, 0x6c, 0xc9, 0xe6, 0x0f, 0x91, 0xf8, 0x9b, 0xcc, 0x1f, 0x20, 0x06, 0x07, 0xf8, 0x3e, 0x0b, + 0x32, 0x00, 0x50, 0x88, 0xc4, 0x20, 0x10, 0x85, 0xfd, 0x03, 0xfc, 0x1f, 0xe0, 0xff, 0x07, 0xf9, + 0x7f, 0xc3, 0xdc, 0x89, 0x10, 0x7d, 0x00, 0x04, 0x1f, 0xe0, 0xfd, 0xfc, 0x40, 0xc1, 0xfb, 0x07, + 0x8e, 0x2f, 0xf3, 0x9f, 0x00, 0xb0, 0x7f, 0x97, 0xf6, 0x0a, 0x11, 0x10, 0xa3, 0xec, 0x10, 0x21, + 0x32, 0x07, 0xd0, 0x18, 0x40, 0xa2, 0x0f, 0xb0, 0x20, 0x81, 0xc4, 0x1f, 0xeb, 0xfa, 0xbf, 0x84, + 0x86, 0x01, 0xc8, 0x5f, 0xd0, 0x0c, 0x81, 0xe2, 0x05, 0x10, 0x7e, 0xdc, 0xc1, 0xf5, 0x01, 0xe0, + 0x41, 0xf2, 0x17, 0xf0, 0x7d, 0xaf, 0x0a, 0x7e, 0x0f, 0xbf, 0x84, 0x7f, 0x21, 0x1f, 0x2b, 0x8e, + 0x3c, 0xbe, 0xd3, 0xf0, 0x78, 0xc4, 0xfa, 0x0b, 0xf2, 0x00, 0x08, 0x81, 0xa1, 0xf3, 0x08, 0x9f, + 0xc0, 0x1e, 0x57, 0x00, 0x7b, 0x60, 0x60, 0x3e, 0x08, 0x4f, 0x80, 0x1e, 0x59, 0x05, 0xc1, 0x03, + 0xce, 0xc3, 0x00, 0x2f, 0x88, 0x3c, 0xe2, 0x10, 0x20, 0x78, 0xbd, 0xc6, 0xff, 0x7c, 0x8c, 0x0e, + 0x48, 0x1e, 0x90, 0x48, 0x47, 0xe2, 0x06, 0x1b, 0x1e, 0x3c, 0x1c, 0x1e, 0x80, 0x01, 0x93, 0xad, + 0x06, 0x1e, 0x0a, 0x28, 0x04, 0x18, 0x1e, 0x81, 0xe1, 0x90, 0x20, 0x46, 0x49, 0xa9, 0x91, 0x3e, + 0x46, 0xf8, 0x0f, 0xac, 0x48, 0x3c, 0xb0, 0x82, 0x52, 0x07, 0xa1, 0x08, 0x43, 0xe5, 0x72, 0x93, + 0x41, 0x7e, 0x01, 0x01, 0x07, 0xc7, 0x8a, 0x97, 0xa9, 0x39, 0x88, 0xa0, 0x7f, 0x00, 0xf2, 0x08, + 0x0c, 0x03, 0x25, 0x54, 0x88, 0xe9, 0x66, 0x11, 0xc2, 0x99, 0x9e, 0x07, 0xff, 0x13, 0x90, 0x7f, + 0xb2, 0x60, 0xf2, 0xaa, 0x79, 0x1b, 0xe5, 0x01, 0xfe, 0x1f, 0xca, 0x41, 0x08, 0xb0, 0xd4, 0xe2, + 0x33, 0x9c, 0x9f, 0x13, 0xff, 0x07, 0xc0, 0x0c, 0x04, 0x1e, 0x54, 0x08, 0x40, 0x64, 0x80, 0x03, + 0x84, 0xff, 0xc0, 0x68, 0x10, 0x0f, 0x80, 0x3d, 0x13, 0xc2, 0x00, 0x28, 0x25, 0xfa, 0x00, 0x0f, + 0x76, 0x60, 0x83, 0xcc, 0x04, 0x20, 0xc1, 0x07, 0xaf, 0xc8, 0x52, 0x52, 0x00, 0x7a, 0x2f, 0xcc, + 0x16, 0x31, 0x30, 0x49, 0x48, 0x17, 0xe5, 0x20, 0xc0, 0x23, 0xce, 0x81, 0x80, 0x88, 0xe6, 0x24, + 0x7c, 0x69, 0xc0, 0xd0, 0xa2, 0x1c, 0x00, 0x79, 0x85, 0x07, 0xe3, 0xa4, 0xb0, 0x4a, 0x64, 0xa0, + 0xf3, 0x57, 0x9d, 0x82, 0x01, 0x80, 0x84, 0x54, 0xb2, 0x19, 0x48, 0x91, 0x90, 0xa2, 0x1f, 0x00, + 0x79, 0x0f, 0x87, 0x80, 0x0f, 0x44, 0x21, 0x03, 0xd0, 0x3e, 0x26, 0x01, 0xa6, 0x44, 0x2c, 0x79, + 0xc0, 0x79, 0xb3, 0xc4, 0xbe, 0x5e, 0x01, 0x08, 0x80, 0x09, 0x56, 0x20, 0x01, 0x98, 0x03, 0xc4, + 0xfe, 0x51, 0x0b, 0xf8, 0x3c, 0xf8, 0x00, 0x32, 0x9c, 0x7f, 0x01, 0xe8, 0x1f, 0x40, 0x21, 0xd7, + 0x81, 0xfb, 0x80, 0xcf, 0x8f, 0x44, 0x1e, 0x7c, 0x88, 0x38, 0x28, 0x70, 0xe4, 0x92, 0xff, 0xc7, + 0xef, 0x1f, 0x80, +}; +const uint8_t* _I_BadEnd_128x64[] = {_I_BadEnd_128x64_0}; +const Icon I_BadEnd_128x64 = + {.width = 128, .height = 64, .frame_count = 1, .frame_rate = 0, .frames = _I_BadEnd_128x64}; +*/ /* space savings until external apps are possible */ +const uint8_t _I_Hand_12x10_0[] = { + 0x01, 0x00, 0x11, 0x00, 0x8c, 0x40, 0x25, 0x00, 0x16, 0xb4, 0x40, + 0x35, 0x10, 0x1d, 0x5c, 0x1b, 0x5b, 0x0a, 0x84, 0xc2, 0x80, +}; +const uint8_t* _I_Hand_12x10[] = {_I_Hand_12x10_0}; +const Icon I_Hand_12x10 = + {.width = 12, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_Hand_12x10}; + +const uint8_t _I_CardBack_22x35_0[] = { + 0x01, 0x00, 0x23, 0x00, 0xfe, 0x7f, 0xe1, 0xf0, 0x28, 0x04, 0x43, 0xe3, 0xff, + 0x91, 0xea, 0x75, 0x52, 0x6a, 0xad, 0x56, 0x5b, 0xad, 0xd5, 0x4a, 0x80, 0xbe, + 0x05, 0xf0, 0x2f, 0x81, 0x7c, 0x0b, 0x45, 0x32, 0x2c, 0x91, 0x7c, 0x8c, 0xa4, +}; +const uint8_t* _I_CardBack_22x35[] = {_I_CardBack_22x35_0}; +const Icon I_CardBack_22x35 = + {.width = 22, .height = 35, .frame_count = 1, .frame_rate = 0, .frames = _I_CardBack_22x35}; + +//uncompressed but lol +const uint8_t _I_club_7x8_0[] = {0x00, 0x08, 0x1c, 0x1c, 0x6b, 0x7f, 0x36, 0x08, 0x1c}; +const uint8_t* _I_club_7x8[] = {_I_club_7x8_0}; +const Icon I_club_7x8 = + {.width = 7, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_club_7x8}; + +//uncompressed but lol +const uint8_t _I_diamond_7x8_0[] = {0x00, 0x00, 0x08, 0x1c, 0x3e, 0x7f, 0x3e, 0x1c, 0x08}; +const uint8_t* _I_diamond_7x8[] = {_I_diamond_7x8_0}; +const Icon I_diamond_7x8 = + {.width = 7, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_diamond_7x8}; + +//uncompressed +const uint8_t _I_hearts_7x8_0[] = {0x00, 0x00, 0x36, 0x7f, 0x7f, 0x7f, 0x3e, 0x1c, 0x08}; +const uint8_t* _I_hearts_7x8[] = {_I_hearts_7x8_0}; +const Icon I_hearts_7x8 = + {.width = 7, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_hearts_7x8}; + +//uncompressed +const uint8_t _I_spade_7x8_0[] = {0x00, 0x08, 0x1c, 0x3e, 0x7f, 0x7f, 0x36, 0x08, 0x1c}; +const uint8_t* _I_spade_7x8[] = {_I_spade_7x8_0}; +const Icon I_spade_7x8 = + {.width = 7, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_spade_7x8}; + +// They only included Numeric Profont22 glyphs and I don't want to fuck up the font embeds right now sooo.. + +const uint8_t _I_King_7x8_0[] = { + 0x01, 0x00, 0x1a, 0x00, 0xc1, 0xc0, 0xf8, 0x70, 0x1f, 0x1c, 0x02, 0xe7, 0x00, 0x9d, 0xc0, + 0x23, 0xf0, 0x08, 0x78, 0x0c, 0x80, 0xe2, 0x0b, 0x10, 0x78, 0x84, 0xc4, 0x2e, 0x20, 0x01, +}; +const uint8_t* _I_King_7x8[] = {_I_King_7x8_0}; +const Icon I_King_7x8 = + {.width = 10, .height = 14, .frame_count = 1, .frame_rate = 0, .frames = _I_King_7x8}; + +const uint8_t _I_Queen_7x8_0[] = { + 0x01, 0x00, 0x13, 0x00, 0xfe, 0x40, 0x3f, 0xd0, 0x1c, 0x3c, 0x0c, 0x01, + 0x76, 0x38, 0x1f, 0x8e, 0x07, 0xc7, 0x81, 0x85, 0x47, 0xf9, 0x01, +}; +const uint8_t* _I_Queen_7x8[] = {_I_Queen_7x8_0}; +const Icon I_Queen_7x8 = + {.width = 10, .height = 14, .frame_count = 1, .frame_rate = 0, .frames = _I_Queen_7x8}; + +const uint8_t _I_Jack_7x8_0[] = { + 0x01, + 0x00, + 0x0D, + 0x00, + 0x80, + 0x40, + 0xc0, + 0x3a, + 0x00, + 0x5c, + 0x3c, + 0x0f, + 0xfd, + 0x01, + 0xfe, + 0x40, + 0x00, +}; +const uint8_t* _I_Jack_7x8[] = {_I_Jack_7x8_0}; +const Icon I_Jack_7x8 = + {.width = 10, .height = 14, .frame_count = 1, .frame_rate = 0, .frames = _I_Jack_7x8}; + +const uint8_t _I_Ace_7x8_0[] = { + 0x01, 0x00, 0x13, 0x00, 0x98, 0x40, 0x2f, 0x00, 0x12, 0xe6, 0x00, 0x4b, + 0x0d, 0x01, 0x00, 0x8c, 0x0e, 0x07, 0xff, 0x00, 0x90, 0x01, 0xc0, +}; +const uint8_t* _I_Ace_7x8[] = {_I_Ace_7x8_0}; +const Icon I_Ace_7x8 = + {.width = 10, .height = 14, .frame_count = 1, .frame_rate = 0, .frames = _I_Ace_7x8}; + +const uint8_t _I_Ten_7x8_0[] = { + 0x01, 0x00, 0x29, 0x00, 0x86, 0x7f, 0x00, 0x43, 0xfe, 0x80, 0xc3, 0xf0, 0xf0, 0x38, 0x7e, + 0x0e, 0x07, 0x0c, 0xe1, 0x80, 0x87, 0xc6, 0x02, 0x1b, 0x98, 0x08, 0x67, 0x60, 0x21, 0x8f, + 0x80, 0x86, 0x1e, 0x02, 0x18, 0x38, 0x08, 0x43, 0x43, 0x7f, 0x10, 0x0d, 0xfc, 0x4c, 0x20, +}; +const uint8_t* _I_Ten_7x8[] = {_I_Ten_7x8_0}; +const Icon I_Ten_7x8 = + {.width = 18, .height = 14, .frame_count = 1, .frame_rate = 0, .frames = _I_Ten_7x8}; + +const Icon card_suit[4] = {I_diamond_7x8, I_club_7x8, I_hearts_7x8, I_spade_7x8}; + +const Icon card_face[5] = {I_Ten_7x8, I_Jack_7x8, I_Queen_7x8, I_King_7x8, I_Ace_7x8}; + +/* Sanity check: check that there are no duplicate cards in hand */ + +static void playcard(PokerPlayer* app) { + int i, c, crd; + + int hold[5]; + hold[5] = 2; + // int digit; + c = 1; + c++; + c = hold[5]; /* FIX for unused-but-set-variable */ + /* initialize deck */ + for(i = 0; i < 52; i++) deck[i].gone = 0; + + /* initialize hold[] */ + for(i = 0; i < 5; i++) hold[i] = 1; + + /* app->score -= bet; */ + if(app->score > app->highscore) { + app->highscore = app->score; + } /* record high water mark */ + + for(i = 0; i < 5; i++) { + /* find a card not already dealt */ + do crd = random() % 52; + while(deck[crd].gone); + hold[i] = 1; + deck[crd].gone = 1; + if(!app->held[i]) { + app->hand[i] = deck[crd]; + } + } +} + +static int check_for_dupes(PokerPlayer* app) { + int i, j; + + for(i = 0; i < 5; i++) { + for(j = i + 1; j < 5; j++) { + if(app->hand[i].index == app->hand[j].index && app->hand[i].suit == app->hand[j].suit) + return 0; + } + } + + return 1; +} + +/* Functions that recognize winning hands */ + +/* + Flush: + returns 1 if the sorted hand is a flush +*/ + +static int flush(PokerPlayer* app) { + if(app->shand[0].suit == app->shand[1].suit && app->shand[1].suit == app->shand[2].suit && + app->shand[2].suit == app->shand[3].suit && app->shand[3].suit == app->shand[4].suit) + return 1; + + return 0; +} + +/* + Straight: + returns 1 if the sorted hand is a straight +*/ + +static int straight(PokerPlayer* app) { + if(app->shand[1].index == app->shand[0].index + 1 && + app->shand[2].index == app->shand[1].index + 1 && + app->shand[3].index == app->shand[2].index + 1 && + app->shand[4].index == app->shand[3].index + 1) + return 1; + + /* Ace low straight: Ace, 2, 3, 4, 5 */ + + if(app->shand[4].index == 13 && app->shand[0].index == 1 && app->shand[1].index == 2 && + app->shand[2].index == 3 && app->shand[3].index == 4) + return 1; + + return 0; +} + +/* + Four of a kind: + the middle 3 all match, and the first or last matches those +*/ + +static int four(PokerPlayer* app) { + if((app->shand[1].index == app->shand[2].index && + app->shand[2].index == app->shand[3].index) && + (app->shand[0].index == app->shand[2].index || app->shand[4].index == app->shand[2].index)) + return 1; + + return 0; +} + +/* + Full house: + 3 of a kind and a pair +*/ + +static int full(PokerPlayer* app) { + if(app->shand[0].index == app->shand[1].index && + (app->shand[2].index == app->shand[3].index && app->shand[3].index == app->shand[4].index)) + return 1; + + if(app->shand[3].index == app->shand[4].index && + (app->shand[0].index == app->shand[1].index && app->shand[1].index == app->shand[2].index)) + return 1; + + return 0; +} + +/* + Three of a kind: + it can appear 3 ways +*/ + +static int three(PokerPlayer* app) { + if(app->shand[0].index == app->shand[1].index && app->shand[1].index == app->shand[2].index) + return 1; + + if(app->shand[1].index == app->shand[2].index && app->shand[2].index == app->shand[3].index) + return 1; + + if(app->shand[2].index == app->shand[3].index && app->shand[3].index == app->shand[4].index) + return 1; + + return 0; +} + +/* + Two pair: + it can appear in 3 ways +*/ + +static int twopair(PokerPlayer* app) { + if(((app->shand[0].index == app->shand[1].index) && + (app->shand[2].index == app->shand[3].index)) || + ((app->shand[0].index == app->shand[1].index) && + (app->shand[3].index == app->shand[4].index)) || + ((app->shand[1].index == app->shand[2].index) && + (app->shand[3].index == app->shand[4].index))) + return 1; + + return 0; +} + +/* + Two of a kind (pair), jacks or better + or if the game is Tens or Better, 10s or better. +*/ + +static int two(PokerPlayer* app) { + int min = 10; + + if(app->GameType == 1) min = 9; + + if(app->shand[0].index == app->shand[1].index && app->shand[1].index >= min) return 1; + if(app->shand[1].index == app->shand[2].index && app->shand[2].index >= min) return 1; + if(app->shand[2].index == app->shand[3].index && app->shand[3].index >= min) return 1; + if(app->shand[3].index == app->shand[4].index && app->shand[4].index >= min) return 1; + + return 0; +} + +static int paytable[10] = { + 800, /* royal flush: 800 */ + 50, /* straight flush: 50 */ + 25, /* 4 of a kind: 25 */ + 9, /* full house: 9 */ + 6, /* flush: 6 */ + 4, /* straight: 4 */ + 3, /* 3 of a kind: 3 */ + 2, /* two pair: 2 */ + 1, /* jacks or better: 1 */ + 0 /* nothing */ +}; + +static const char* poker_handname[10] = { + "Royal Flush", + "Straight Flush", + "Four of a Kind", + "Full House", + "Flush", + "Straight", + "Three of a Kind", + "Two Pair", + "Pair", + "Nothing", +}; + +static int recognize(PokerPlayer* app) { + int i, j, f = 0; + int min = 100; + PokerPlayer_card tmp[5]; + int st = 0, fl = 0; + + /* Sort hand into sorted hand (app->shand) */ + + /* make copy of hand */ + for(i = 0; i < 5; i++) tmp[i] = app->hand[i]; + + for(i = 0; i < 5; i++) { + /* put lowest card in hand into next place in app->shand */ + + for(j = 0; j < 5; j++) + if(tmp[j].index <= min) { + min = tmp[j].index; + f = j; + } + + app->shand[i] = tmp[f]; + tmp[f].index = 100; /* larger than any card */ + min = 100; + } + + /* royal and straight flushes, strait, and flush */ + + fl = flush(app); + st = straight(app); + + if(st && fl && app->shand[0].index == 9) return 0; + if(st && fl) return 1; + if(four(app)) return 2; + if(full(app)) return 3; + if(fl) return 4; + if(st) return 5; + if(three(app)) return 6; + if(twopair(app)) return 7; + if(two(app)) return 8; + + /* Nothing */ + + return 9; +} + +void poker_draw_callback(Canvas* canvas, void* ctx) { + PokerPlayer* poker_player = ctx; + furi_check(furi_mutex_acquire(poker_player->model_mutex, FuriWaitForever) == FuriStatusOk); + canvas_clear(canvas); + char buffer[30]; + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontSecondary); + + /* Magic Begins */ + + /* Status Info */ + if(poker_player->GameState != 0 && poker_player->GameState != 4) { + snprintf(buffer, sizeof(buffer), "%d", poker_player->score); + canvas_draw_str_aligned(canvas, 127, 0, AlignRight, AlignTop, buffer); + } + + /* Start of game. Cards are face down, bet can be changed */ + if(poker_player->GameState == 1) { + snprintf(buffer, sizeof(buffer), "Bet:%d", poker_player->bet); + canvas_draw_str_aligned(canvas, 0, 0, AlignLeft, AlignTop, buffer); + snprintf(buffer, sizeof(buffer), "<*> Place Bet"); + canvas_draw_str_aligned(canvas, 0, 9, AlignLeft, AlignTop, buffer); + + for(int i = 0; i < 5; ++i) { + canvas_draw_icon(canvas, 5 + (i * 24), 18, &I_CardBack_22x35); /* 5, 29, 53, 77, 101 */ + } + } + /* Cards are turned face up. Bet is deducted and put in th pot. Show the selector hand */ + else if(poker_player->GameState == 2 || poker_player->GameState == 3) { + snprintf(buffer, sizeof(buffer), "Pot:%d", poker_player->bet); + canvas_draw_str_aligned(canvas, 0, 0, AlignLeft, AlignTop, buffer); + snprintf(buffer, sizeof(buffer), "<*> Select Hold"); + canvas_draw_str_aligned(canvas, 0, 9, AlignLeft, AlignTop, buffer); + + /* Normal or inverse to indicate selection - cards*/ + for(int i = 0; i < 5; ++i) { + poker_player->held[i] ? canvas_draw_rbox(canvas, 5 + (i * 24), 18, 22, 35, 3) : + canvas_draw_rframe(canvas, 5 + (i * 24), 18, 22, 35, 3); + } + + /* Normal or inverse to indicate selection - card suit and value */ + + for(int i = 0; i < 5; ++i) { + poker_player->held[i] ? canvas_set_color(canvas, ColorWhite) : + canvas_set_color(canvas, ColorBlack); + + canvas_draw_icon(canvas, 18 + (i * 24), 43, &card_suit[poker_player->hand[i].suit]); + } + + /* Card Value. Profont_22 does not include letters (AJQK), and "10" is too big. These are bitmaps. */ + canvas_set_font(canvas, FontBigNumbers); + + for(int i = 0; i < 5; ++i) { + poker_player->held[i] ? canvas_set_color(canvas, ColorWhite) : + canvas_set_color(canvas, ColorBlack); + if(poker_player->hand[i].index >= 1 && poker_player->hand[i].index <= 8) { + snprintf(buffer, sizeof(buffer), "%s", poker_player->hand[i].sym); + canvas_draw_str_aligned(canvas, 8 + (i * 24), 21, AlignLeft, AlignTop, buffer); + } else { + if(poker_player->hand[i].index >= 9 && poker_player->hand[i].index <= 13) { + canvas_draw_icon( + canvas, 7 + (i * 24), 21, &card_face[poker_player->hand[i].index - 9]); + } + } + } + + /* Draw the Select hand */ + if(poker_player->GameState == 2) { + canvas_set_color(canvas, ColorBlack); + + canvas_draw_icon(canvas, 11 + (poker_player->selected * 24), 54, &I_Hand_12x10); + } + } // GameState 2 or 3 + + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontSecondary); + if(poker_player->GameState == 3) { + snprintf( + buffer, + sizeof(buffer), + "%s:%ix", + poker_handname[recognize(poker_player)], + paytable[recognize(poker_player)]); + canvas_draw_str_aligned(canvas, 63, 61, AlignCenter, AlignBottom, buffer); + } + if(poker_player->GameState == 0) { + canvas_draw_icon(canvas, 0, 0, &I_Splash_128x64); /* Initial launch */ + } + if(poker_player->GameState == 4) { + /* canvas_draw_icon(canvas, 0, 0, &I_BadEnd_128x64); Just Lost The Game - disabled for now :( */ + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontSecondary); + snprintf(buffer, sizeof(buffer), "%s", "You have run out of money!"); + canvas_draw_str_aligned(canvas, 63, 22, AlignCenter, AlignCenter, buffer); + snprintf(buffer, sizeof(buffer), "%s", "At one point, you had"); + canvas_draw_str_aligned(canvas, 63, 32, AlignCenter, AlignCenter, buffer); + snprintf(buffer, sizeof(buffer), "%d dollars", poker_player->highscore); + canvas_draw_str_aligned(canvas, 63, 42, AlignCenter, AlignCenter, buffer); + } + + furi_mutex_release(poker_player->model_mutex); +} + +void poker_input_callback(InputEvent* input, void* ctx) { + PokerPlayer* poker_player = ctx; + furi_message_queue_put(poker_player->event_queue, input, FuriWaitForever); +} + +PokerPlayer* poker_player_alloc() { + PokerPlayer* poker_player = malloc(sizeof(PokerPlayer)); + + poker_player->score = 1000; + poker_player->model_mutex = furi_mutex_alloc(FuriMutexTypeNormal); + poker_player->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + poker_player->view_port = view_port_alloc(); + poker_player->selected = 0; + poker_player->GameState = 0; + poker_player->bet = 10; + poker_player->minbet = 10; + poker_player->highscore = 1000; + + playcard( + poker_player); /* Get things rolling before the player gets into the game. This will preload the hand. */ + view_port_draw_callback_set(poker_player->view_port, poker_draw_callback, poker_player); + + view_port_input_callback_set(poker_player->view_port, poker_input_callback, poker_player); + + poker_player->gui = furi_record_open(RECORD_GUI); + gui_add_view_port(poker_player->gui, poker_player->view_port, GuiLayerFullscreen); + + return poker_player; +} + +void poker_player_free(PokerPlayer* poker_player) { + view_port_enabled_set(poker_player->view_port, false); + gui_remove_view_port(poker_player->gui, poker_player->view_port); + furi_record_close(RECORD_GUI); + view_port_free(poker_player->view_port); + furi_message_queue_free(poker_player->event_queue); + furi_mutex_free(poker_player->model_mutex); + + free(poker_player); +} + +int32_t video_poker_app(void* p) { + UNUSED(p); + PokerPlayer* poker_player = poker_player_alloc(); + + InputEvent event; + for(bool processing = true; processing;) { + FuriStatus status = furi_message_queue_get(poker_player->event_queue, &event, 100); + furi_check(furi_mutex_acquire(poker_player->model_mutex, FuriWaitForever) == FuriStatusOk); + if(status == FuriStatusOk) { + if(event.type == InputTypePress) { + switch(event.key) { + case InputKeyUp: + Shake(); + break; + case InputKeyDown: + if(poker_player->GameState == 2) { + playcard(poker_player); + if(check_for_dupes(poker_player) == 0) { + playcard(poker_player); + } + + poker_player->GameState = 3; + } + break; + case InputKeyLeft: + if(poker_player->GameState == 1) { + if(poker_player->bet >= poker_player->minbet + 10) { + poker_player->bet -= 10; + } + } else if(poker_player->selected > 0 && poker_player->GameState == 2) { + poker_player->selected--; + } // Move hand left/right + else if(poker_player->selected == 0 && poker_player->GameState == 2) { + poker_player->selected = 4; //wraparound + } + break; + case InputKeyRight: + if(poker_player->GameState == 1) { + if(poker_player->bet < poker_player->score + 10) { + poker_player->bet += 10; + } + } + if(poker_player->selected < 4 && poker_player->GameState == 2) { + poker_player->selected++; + } // Move hand left/right + else if(poker_player->selected == 4 && poker_player->GameState == 2) { + poker_player->selected = 0; //wraparound + } + break; + case InputKeyOk: + /* close splash screen */ + if(poker_player->GameState == 0) { + poker_player->GameState = 1; + } else if(poker_player->GameState == 1) { + /* Pledge bet. Bet is subtracted here. Original code subtracts it during playcard + but playcard is called multiple times which would otherwise subtract bet + multiple times */ + poker_player->score -= poker_player->bet; + poker_player->GameState = 2; + } else if(poker_player->GameState == 2) { + /* Select or un-select card to be held */ + poker_player->held[poker_player->selected] = + !poker_player + ->held[poker_player->selected]; //cursed and bad pls replace + } else if(poker_player->GameState == 3) { + /* accept your fate */ + if(recognize(poker_player) != 9) { + poker_player->score += + poker_player->bet * paytable[recognize(poker_player)]; + } + poker_player->GameState = 1; + if(poker_player->bet > poker_player->score) { + poker_player->bet = poker_player->score; + } + poker_player->held[0] = 0; + poker_player->held[1] = 0; + poker_player->held[2] = 0; + poker_player->held[3] = 0; + poker_player->held[4] = 0; + if(poker_player->score <= 0) { + /* lost the game */ + poker_player->GameState = 4; + } + playcard(poker_player); // shuffle shuffle + } else if(poker_player->GameState == 4) { + /* escape the summary, return to splash */ + Shake(); + poker_player->selected = 0; + poker_player->GameState = 0; + poker_player->bet = 10; + poker_player->minbet = 10; + poker_player->highscore = 1000; + poker_player->score = 1000; + poker_player->GameState = 0; + } + break; + case InputKeyBack: + /* if game is not over, we should store the game state. */ + processing = false; + break; + default: + break; + } + } + } + furi_mutex_release(poker_player->model_mutex); + view_port_update(poker_player->view_port); + } + + poker_player_free(poker_player); + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/videopoker/pokerIcon.png b/Applications/Official/DEV_FW/source/xMasterX/videopoker/pokerIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..db5507d0c1b9e939498cdc2deafe9131cb764965 GIT binary patch literal 1899 zcmcIlO>g5w81@2-*sglwg4or{crPFre~iDaWUI6(n@a0ab%R=NjAzD))!1Wfw@G{8 zz>U)$IPn{hR^kX8SS@!rAbtcA5@#f&^4do}w)FJpyT8NYwNWqZNz%7ZZvRbg!us`tN5kFA z%S)Jk{QTF?VYrnKJ}D(hmFw?~-|pVK1E^n;;c;~wJ_@KvRl-EX)mfSYT9P_jvz*Wq zUda(3C0SSb^M@Z5IbmJp$PV=|-{IqAa8dBb7yCncaYB8jY(3cA=*$9ONO?u%Svtwe zVAfR{;sECLwx-Apq&n#;z1pID93IF!qTsTtVnlUamt9{qBF84K|ACBkj5XcS3=k@XtFAJxsyxuN>2#`2O;r>l&G3C+)3Jsz0t710vx>}6 zR^D$(<}`g?(jv*LL}YSJOCoVvbro>AjU~;O+*vtK7^F^{kz6xWy^d`G48!Z8X}Uz0 z)$SQsnLB+YaXCECxpv4)aavHmd&aZs{=!&37L_Q+;y-*_{{1fx8C@F8Pm4*DBStko z;VE#JfHfNb@?fXnq!PtYh{>X22MdcbHdR}G_bADjn3nI=9?cK%KB;(DsjG){9~t)0 za01;9O#HrX2D;utLl6Wb6z?np1~V8| + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/README.md b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/README.md new file mode 100644 index 000000000..87a419f90 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/README.md @@ -0,0 +1,50 @@ +# flipperzero_esp8266_deautherv2 +Flipper Zero esp8266 deauther app. + + +Based off the WiFi Marauder App from 0xchocolate. + +https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion + +https://github.com/RogueMaster/flipperzero-firmware-wPlugins/tree/unleashed/applications/wifi_marauder_companion + +uses the Version 2 of the ESP8266 Deauther code. +https://github.com/SpacehuhnTech/esp8266_deauther/tree/v2/esp8266_deauther + +This is done so you can use the original deauther v2 firmware on the esp8266. +you can just flash the latest binary. + +also a shout out to https://github.com/SequoiaSan/FlipperZero-Wifi-ESP8266-Deauther-Module +This is already in the Roguemaster firmware and just needs to be enabled and compiled. unfortunatly I could not get this past the menu when I compiled his deauther source for the nodemcu. Nice menu though. + +I used a nodeMCU board. Wiring is simple. follow the wiring guide on https://github.com/SequoiaSan/FlipperZero-WiFi-Scanner_Module +On mine I connected one G to ground, VIN to 5V, RX to U_TX, TX to U_RX. + +NodeMCU---FlipperZero + +G---------GND + +VIN-------5V + +RX--------U_TX + +TX--------U_RX + + + +Video in action. +https://youtu.be/_RFzZyPkeR0 + +If you want to disable the built in WiFi access and web interface (only use flipper to serial send commands) then select "set webinterface false", "save settings" and "reboot". When it starts back up you wont see the pwned AP any more. + +I installed this into Roguemaster to test. + +git clone --recursive https://github.com/RogueMaster/flipperzero-firmware-wPlugins.git +cd flipperzero-firmware-wPlugins/ + +copy folder into applications. +add "APPS_wifi_deauther", to the meta/application.fam file. + +compile +./fbt resources icons +./fbt updater_package diff --git a/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/application.fam b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/application.fam new file mode 100644 index 000000000..1d352481b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/application.fam @@ -0,0 +1,12 @@ +App( + appid="ESP8266_Wifi_Deauther_v2", + name="[ESP8266] Deauther v2", + apptype=FlipperAppType.EXTERNAL, + entry_point="wifi_deauther_app", + cdefines=["APP_WIFI_deauther"], + requires=["gui"], + stack_size=1 * 1024, + order=30, + fap_icon="wifi_10px.png", + fap_category="GPIO_Extra", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene.c b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene.c new file mode 100644 index 000000000..a974beea9 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene.c @@ -0,0 +1,30 @@ +#include "wifi_deauther_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const wifi_deauther_scene_on_enter_handlers[])(void*) = { +#include "wifi_deauther_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 wifi_deauther_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "wifi_deauther_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 wifi_deauther_scene_on_exit_handlers[])(void* context) = { +#include "wifi_deauther_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers wifi_deauther_scene_handlers = { + .on_enter_handlers = wifi_deauther_scene_on_enter_handlers, + .on_event_handlers = wifi_deauther_scene_on_event_handlers, + .on_exit_handlers = wifi_deauther_scene_on_exit_handlers, + .scene_num = WifideautherSceneNum, +}; diff --git a/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene.h b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene.h new file mode 100644 index 000000000..a6ef08553 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) WifideautherScene##id, +typedef enum { +#include "wifi_deauther_scene_config.h" + WifideautherSceneNum, +} WifideautherScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers wifi_deauther_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "wifi_deauther_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 "wifi_deauther_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 "wifi_deauther_scene_config.h" +#undef ADD_SCENE diff --git a/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene_config.h b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene_config.h new file mode 100644 index 000000000..5f21cdc50 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene_config.h @@ -0,0 +1,3 @@ +ADD_SCENE(wifi_deauther, start, Start) +ADD_SCENE(wifi_deauther, console_output, ConsoleOutput) +ADD_SCENE(wifi_deauther, text_input, TextInput) diff --git a/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene_console_output.c b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene_console_output.c new file mode 100644 index 000000000..a3d03a0d1 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene_console_output.c @@ -0,0 +1,90 @@ +#include "../wifi_deauther_app_i.h" + +void wifi_deauther_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) { + furi_assert(context); + WifideautherApp* app = context; + + // If text box store gets too big, then truncate it + app->text_box_store_strlen += len; + if(app->text_box_store_strlen >= WIFI_deauther_TEXT_BOX_STORE_SIZE - 1) { + furi_string_right(app->text_box_store, app->text_box_store_strlen / 2); + app->text_box_store_strlen = furi_string_size(app->text_box_store); + } + + // Null-terminate buf and append to text box store + buf[len] = '\0'; + furi_string_cat_printf(app->text_box_store, "%s", buf); + + view_dispatcher_send_custom_event(app->view_dispatcher, WifideautherEventRefreshConsoleOutput); +} + +void wifi_deauther_scene_console_output_on_enter(void* context) { + WifideautherApp* app = context; + + TextBox* text_box = app->text_box; + text_box_reset(app->text_box); + text_box_set_font(text_box, TextBoxFontText); + if(app->focus_console_start) { + text_box_set_focus(text_box, TextBoxFocusStart); + } else { + text_box_set_focus(text_box, TextBoxFocusEnd); + } + if(app->is_command) { + furi_string_reset(app->text_box_store); + app->text_box_store_strlen = 0; + if(0 == strncmp("help", app->selected_tx_string, strlen("help"))) { + const char* help_msg = "For app support/feedback,\nreach out to\n"; + furi_string_cat_str(app->text_box_store, help_msg); + app->text_box_store_strlen += strlen(help_msg); + } + + if(app->show_stopscan_tip) { + const char* help_msg = "Press BACK to send stopscan\n"; + furi_string_cat_str(app->text_box_store, help_msg); + app->text_box_store_strlen += strlen(help_msg); + } + } else { // "View Log" menu action + text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store)); + } + + scene_manager_set_scene_state(app->scene_manager, WifideautherSceneConsoleOutput, 0); + view_dispatcher_switch_to_view(app->view_dispatcher, WifideautherAppViewConsoleOutput); + + // Register callback to receive data + wifi_deauther_uart_set_handle_rx_data_cb( + app->uart, wifi_deauther_console_output_handle_rx_data_cb); // setup callback for rx thread + + // Send command with newline '\n' + if(app->is_command && app->selected_tx_string) { + wifi_deauther_uart_tx( + (uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string)); + wifi_deauther_uart_tx((uint8_t*)("\n"), 1); + } +} + +bool wifi_deauther_scene_console_output_on_event(void* context, SceneManagerEvent event) { + WifideautherApp* app = context; + + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store)); + consumed = true; + } else if(event.type == SceneManagerEventTypeTick) { + consumed = true; + } + + return consumed; +} + +void wifi_deauther_scene_console_output_on_exit(void* context) { + WifideautherApp* app = context; + + // Unregister rx callback + wifi_deauther_uart_set_handle_rx_data_cb(app->uart, NULL); + + // Automatically stop the scan when exiting view + if(app->is_command) { + wifi_deauther_uart_tx((uint8_t*)("stopscan\n"), strlen("stopscan\n")); + } +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene_start.c b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene_start.c new file mode 100644 index 000000000..92b80b2cf --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene_start.c @@ -0,0 +1,172 @@ +#include "../wifi_deauther_app_i.h" + +// For each command, define whether additional arguments are needed +// (enabling text input to fill them out), and whether the console +// text box should focus at the start of the output or the end +typedef enum { NO_ARGS = 0, INPUT_ARGS, TOGGLE_ARGS } InputArgs; + +typedef enum { FOCUS_CONSOLE_END = 0, FOCUS_CONSOLE_START, FOCUS_CONSOLE_TOGGLE } FocusConsole; + +#define SHOW_STOPSCAN_TIP (true) +#define NO_TIP (false) + +#define MAX_OPTIONS (6) +typedef struct { + const char* item_string; + const char* options_menu[MAX_OPTIONS]; + int num_options_menu; + const char* actual_commands[MAX_OPTIONS]; + InputArgs needs_keyboard; + FocusConsole focus_console; + bool show_stopscan_tip; +} WifideautherItem; + +// NUM_MENU_ITEMS defined in wifi_deauther_app_i.h - if you add an entry here, increment it! +const WifideautherItem MenuItems[NUM_MENU_ITEMS] = { + {"View Log from", {"start", "end"}, 2, {}, NO_ARGS, FOCUS_CONSOLE_TOGGLE, NO_TIP}, + {"Help", {""}, 1, {"help"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP}, + {"Stop", {""}, 1, {"stop all"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP}, + {"Scan", + {"All", "SSIDs", "Stations"}, + 3, + {"scan", "scan aps", "scan stations"}, + NO_ARGS, + FOCUS_CONSOLE_END, + NO_TIP}, + {"Select", + {"All", "SSIDs", "Stations"}, + 3, + {"select all", "select aps", "select stations"}, + INPUT_ARGS, + FOCUS_CONSOLE_END, + NO_TIP}, + {"Deselect", + {"All", "SSIDs", "Stations"}, + 3, + {"deselect all", "deselect aps", "deselect stations"}, + INPUT_ARGS, + FOCUS_CONSOLE_END, + NO_TIP}, + {"Show", + {"SSIDs", "Stations", "All", "Selected"}, + 4, + {"show ap", "show station", "show all", "show selected"}, + NO_ARGS, + FOCUS_CONSOLE_END, + NO_TIP}, + {"Attack", + {"deauth", "deauthall", "beacon", "probe"}, + 4, + {"attack deauth", "attack deauthall", "attack beacon", "attack probe"}, + NO_ARGS, + FOCUS_CONSOLE_END, + SHOW_STOPSCAN_TIP}, + {"Settings", + {"Get", "Remove AP", "Set SSID", "Set Pass", "Save"}, + 5, + {"get settings", + "set webinterface false", + "set ssid: pwned", + "set password: deauther", + "save settings"}, + INPUT_ARGS, + FOCUS_CONSOLE_END, + NO_TIP}, + {"Sysinfo", {""}, 1, {"sysinfo"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP}, + {"Reboot", {""}, 1, {"reboot"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP}, +}; + +static void wifi_deauther_scene_start_var_list_enter_callback(void* context, uint32_t index) { + furi_assert(context); + WifideautherApp* app = context; + if(app->selected_option_index[index] < MenuItems[index].num_options_menu) { + app->selected_tx_string = + MenuItems[index].actual_commands[app->selected_option_index[index]]; + } + app->is_command = (1 <= index); + app->is_custom_tx_string = false; + app->selected_menu_index = index; + app->focus_console_start = (MenuItems[index].focus_console == FOCUS_CONSOLE_TOGGLE) ? + (app->selected_option_index[index] == 0) : + MenuItems[index].focus_console; + app->show_stopscan_tip = MenuItems[index].show_stopscan_tip; + + bool needs_keyboard = (MenuItems[index].needs_keyboard == TOGGLE_ARGS) ? + (app->selected_option_index[index] != 0) : + MenuItems[index].needs_keyboard; + if(needs_keyboard) { + view_dispatcher_send_custom_event(app->view_dispatcher, WifideautherEventStartKeyboard); + } else { + view_dispatcher_send_custom_event(app->view_dispatcher, WifideautherEventStartConsole); + } +} + +static void wifi_deauther_scene_start_var_list_change_callback(VariableItem* item) { + furi_assert(item); + + WifideautherApp* app = variable_item_get_context(item); + furi_assert(app); + + const WifideautherItem* menu_item = &MenuItems[app->selected_menu_index]; + uint8_t item_index = variable_item_get_current_value_index(item); + furi_assert(item_index < menu_item->num_options_menu); + variable_item_set_current_value_text(item, menu_item->options_menu[item_index]); + app->selected_option_index[app->selected_menu_index] = item_index; +} + +void wifi_deauther_scene_start_on_enter(void* context) { + WifideautherApp* app = context; + VariableItemList* var_item_list = app->var_item_list; + + variable_item_list_set_enter_callback( + var_item_list, wifi_deauther_scene_start_var_list_enter_callback, app); + + VariableItem* item; + for(int i = 0; i < NUM_MENU_ITEMS; ++i) { + item = variable_item_list_add( + var_item_list, + MenuItems[i].item_string, + MenuItems[i].num_options_menu, + wifi_deauther_scene_start_var_list_change_callback, + app); + if(MenuItems[i].num_options_menu) { + variable_item_set_current_value_index(item, app->selected_option_index[i]); + variable_item_set_current_value_text( + item, MenuItems[i].options_menu[app->selected_option_index[i]]); + } + } + + variable_item_list_set_selected_item( + var_item_list, scene_manager_get_scene_state(app->scene_manager, WifideautherSceneStart)); + + view_dispatcher_switch_to_view(app->view_dispatcher, WifideautherAppViewVarItemList); +} + +bool wifi_deauther_scene_start_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + WifideautherApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == WifideautherEventStartKeyboard) { + scene_manager_set_scene_state( + app->scene_manager, WifideautherSceneStart, app->selected_menu_index); + scene_manager_next_scene(app->scene_manager, WifideautherAppViewTextInput); + } else if(event.event == WifideautherEventStartConsole) { + scene_manager_set_scene_state( + app->scene_manager, WifideautherSceneStart, app->selected_menu_index); + scene_manager_next_scene(app->scene_manager, WifideautherAppViewConsoleOutput); + } + consumed = true; + } else if(event.type == SceneManagerEventTypeTick) { + app->selected_menu_index = variable_item_list_get_selected_item_index(app->var_item_list); + consumed = true; + } + + return consumed; +} + +void wifi_deauther_scene_start_on_exit(void* context) { + WifideautherApp* app = context; + variable_item_list_reset(app->var_item_list); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene_text_input.c b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene_text_input.c new file mode 100644 index 000000000..339b2f2a3 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/scenes/wifi_deauther_scene_text_input.c @@ -0,0 +1,72 @@ +#include "../wifi_deauther_app_i.h" + +void wifi_deauther_scene_text_input_callback(void* context) { + WifideautherApp* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, WifideautherEventStartConsole); +} + +void wifi_deauther_scene_text_input_on_enter(void* context) { + WifideautherApp* app = context; + + if(false == app->is_custom_tx_string) { + // Fill text input with selected string so that user can add to it + size_t length = strlen(app->selected_tx_string); + furi_assert(length < WIFI_deauther_TEXT_INPUT_STORE_SIZE); + bzero(app->text_input_store, WIFI_deauther_TEXT_INPUT_STORE_SIZE); + strncpy(app->text_input_store, app->selected_tx_string, length); + + // Add space - because flipper keyboard currently doesn't have a space + app->text_input_store[length] = ' '; + app->text_input_store[length + 1] = '\0'; + app->is_custom_tx_string = true; + } + + // Setup view + TextInput* text_input = app->text_input; + // Add help message to header + if(0 == strncmp("ssid -a -g", app->selected_tx_string, strlen("ssid -a -g"))) { + text_input_set_header_text(text_input, "Enter # SSIDs to generate"); + } else if(0 == strncmp("ssid -a -n", app->selected_tx_string, strlen("ssid -a -n"))) { + text_input_set_header_text(text_input, "Enter SSID name to add"); + } else if(0 == strncmp("ssid -r", app->selected_tx_string, strlen("ssid -r"))) { + text_input_set_header_text(text_input, "Remove target from SSID list"); + } else if(0 == strncmp("select -a", app->selected_tx_string, strlen("select -a"))) { + text_input_set_header_text(text_input, "Add target from AP list"); + } else if(0 == strncmp("select -s", app->selected_tx_string, strlen("select -s"))) { + text_input_set_header_text(text_input, "Add target from SSID list"); + } else { + text_input_set_header_text(text_input, "Add command arguments"); + } + text_input_set_result_callback( + text_input, + wifi_deauther_scene_text_input_callback, + app, + app->text_input_store, + WIFI_deauther_TEXT_INPUT_STORE_SIZE, + false); + + view_dispatcher_switch_to_view(app->view_dispatcher, WifideautherAppViewTextInput); +} + +bool wifi_deauther_scene_text_input_on_event(void* context, SceneManagerEvent event) { + WifideautherApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == WifideautherEventStartConsole) { + // Point to custom string to send + app->selected_tx_string = app->text_input_store; + scene_manager_next_scene(app->scene_manager, WifideautherAppViewConsoleOutput); + consumed = true; + } + } + + return consumed; +} + +void wifi_deauther_scene_text_input_on_exit(void* context) { + WifideautherApp* app = context; + + text_input_reset(app->text_input); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_10px.png b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..c13534660e188305fba6c5625ec1ce6841e238f0 GIT binary patch literal 1781 zcmcIl&u`pB6gH`Z%BmFygoHpsmU98Y_~+VQo4O&%2C@S^in|uYPoPg;=lp^061{vuK;mH0)!Ap1aEfjZ9#3COD(NEb)27p@I<-_@3^l{^ zJWV$>(?ozk<#ATw8OqAlhM~(!QY3km@JtqrIO0cDpn%lH9@2bCo0YXs;FvbUxn`)k z*i!=x!_%Q@x?Xi*{6@+a~SXQkz!SWHWcsb$^(6;>hKME;X z2F#C&@!TFtG&W`_aF>8J=K6AfvtYR5MW6F=ld0V%qHJ2KEx&Lj$ta(eFA7EV0@lS9 z3lxzxq6WkS3up+1Kyii72Ie%0kIw=PL%)}m70w9jbpr)NsYyb8 zJMsvNA`daU;~>vzcTnUo15vl_+OF=#%yQ$(Q&5MYCuiK3ViGt#NsF`|a;%_4zM2aoS%6{;vOnh}dV&+$;la51vmz|(PT2kC7> z4aZ`UqccUm8+VhBc@c67?plgWi68SK#ZW&o;wry~ZWrzC#?D|uW^alzJy;PgX_OM8&`5>HN- zezwFvLg}@wWQ4OJgU+cbVl$d(F^i;V|IgRmd^a_-4%IBOS=Kge;NjAc%S|z1Y*Ei7 z7`aZzLY~=nQ76_TL}+YM(=~`2JBzsEq*1US(oT;!*LqKTY!*Y$6~kq>hspB1U>R(+ zfYV^|L-!V(Bpbc%djFYEuYc5QN%Dnr&;9Yw)#snQ{?-RkcJOWM!}Gms%3q(obL%Er ziEn@L-j7dhz5Vr9H}KQ1Uj1|b*V}jgzWLMVKMy{+^U80llJ&7Tn0i|~-ETJDeg9wV C&oCwc literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_app.c b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_app.c new file mode 100644 index 000000000..28fb28d88 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_app.c @@ -0,0 +1,106 @@ +#include "wifi_deauther_app_i.h" + +#include +#include +#include + +static bool wifi_deauther_app_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + WifideautherApp* app = context; + return scene_manager_handle_custom_event(app->scene_manager, event); +} + +static bool wifi_deauther_app_back_event_callback(void* context) { + furi_assert(context); + WifideautherApp* app = context; + return scene_manager_handle_back_event(app->scene_manager); +} + +static void wifi_deauther_app_tick_event_callback(void* context) { + furi_assert(context); + WifideautherApp* app = context; + scene_manager_handle_tick_event(app->scene_manager); +} + +WifideautherApp* wifi_deauther_app_alloc() { + WifideautherApp* app = malloc(sizeof(WifideautherApp)); + + app->gui = furi_record_open(RECORD_GUI); + + app->view_dispatcher = view_dispatcher_alloc(); + app->scene_manager = scene_manager_alloc(&wifi_deauther_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, wifi_deauther_app_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + app->view_dispatcher, wifi_deauther_app_back_event_callback); + view_dispatcher_set_tick_event_callback( + app->view_dispatcher, wifi_deauther_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, + WifideautherAppViewVarItemList, + variable_item_list_get_view(app->var_item_list)); + + for(int i = 0; i < NUM_MENU_ITEMS; ++i) { + app->selected_option_index[i] = 0; + } + + app->text_box = text_box_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, WifideautherAppViewConsoleOutput, text_box_get_view(app->text_box)); + app->text_box_store = furi_string_alloc(); + furi_string_reserve(app->text_box_store, WIFI_deauther_TEXT_BOX_STORE_SIZE); + + app->text_input = text_input_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, WifideautherAppViewTextInput, text_input_get_view(app->text_input)); + + scene_manager_next_scene(app->scene_manager, WifideautherSceneStart); + + return app; +} + +void wifi_deauther_app_free(WifideautherApp* app) { + furi_assert(app); + + // Views + view_dispatcher_remove_view(app->view_dispatcher, WifideautherAppViewVarItemList); + view_dispatcher_remove_view(app->view_dispatcher, WifideautherAppViewConsoleOutput); + view_dispatcher_remove_view(app->view_dispatcher, WifideautherAppViewTextInput); + text_box_free(app->text_box); + furi_string_free(app->text_box_store); + text_input_free(app->text_input); + + // View dispatcher + view_dispatcher_free(app->view_dispatcher); + scene_manager_free(app->scene_manager); + + wifi_deauther_uart_free(app->uart); + + // Close records + furi_record_close(RECORD_GUI); + + free(app); +} + +int32_t wifi_deauther_app(void* p) { + furi_hal_power_enable_otg(); + furi_delay_ms(600); + UNUSED(p); + WifideautherApp* wifi_deauther_app = wifi_deauther_app_alloc(); + + wifi_deauther_app->uart = wifi_deauther_uart_init(wifi_deauther_app); + + view_dispatcher_run(wifi_deauther_app->view_dispatcher); + + wifi_deauther_app_free(wifi_deauther_app); + furi_hal_power_disable_otg(); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_app.h b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_app.h new file mode 100644 index 000000000..bb2f6fbfb --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_app.h @@ -0,0 +1,11 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct WifideautherApp WifideautherApp; + +#ifdef __cplusplus +} +#endif diff --git a/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_app_i.h b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_app_i.h new file mode 100644 index 000000000..bab52f385 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_app_i.h @@ -0,0 +1,69 @@ +#pragma once + +#include "wifi_deauther_app.h" +#include "scenes/wifi_deauther_scene.h" +#include "wifi_deauther_custom_event.h" +#include "wifi_deauther_uart.h" + +#include +#include +#include +#include +#include +#include + +#define NUM_MENU_ITEMS (11) + +#define WIFI_deauther_TEXT_BOX_STORE_SIZE (4096) +#define WIFI_deauther_TEXT_INPUT_STORE_SIZE (512) + +struct WifideautherApp { + Gui* gui; + ViewDispatcher* view_dispatcher; + SceneManager* scene_manager; + + char text_input_store[WIFI_deauther_TEXT_INPUT_STORE_SIZE + 1]; + FuriString* text_box_store; + size_t text_box_store_strlen; + TextBox* text_box; + TextInput* text_input; + //Widget* widget; + + VariableItemList* var_item_list; + + WifideautherUart* uart; + int selected_menu_index; + int selected_option_index[NUM_MENU_ITEMS]; + const char* selected_tx_string; + bool is_command; + bool is_custom_tx_string; + bool focus_console_start; + bool show_stopscan_tip; +}; + +// Supported commands: +// https://github.com/justcallmekoko/ESP32deauther/wiki/cli +// Scan +// -> If list is empty, then start a new scanap. (Tap any button to stop.) +// -> If there's a list, provide option to rescan and dump list of targets to select. +// -> Press BACK to go back to top-level. +// Attack +// -> Beacon +// -> Deauth +// -> Probe +// -> Rickroll +// Sniff +// -> Beacon +// -> Deauth +// -> ESP +// -> PMKID +// -> Pwnagotchi +// Channel +// Update +// Reboot + +typedef enum { + WifideautherAppViewVarItemList, + WifideautherAppViewConsoleOutput, + WifideautherAppViewTextInput, +} WifideautherAppView; diff --git a/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_custom_event.h b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_custom_event.h new file mode 100644 index 000000000..142961b1d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_custom_event.h @@ -0,0 +1,7 @@ +#pragma once + +typedef enum { + WifideautherEventRefreshConsoleOutput = 0, + WifideautherEventStartConsole, + WifideautherEventStartKeyboard, +} WifideautherCustomEvent; diff --git a/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_uart.c b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_uart.c new file mode 100644 index 000000000..434ccfd97 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_uart.c @@ -0,0 +1,98 @@ +#include "wifi_deauther_app_i.h" +#include "wifi_deauther_uart.h" + +#include + +#define UART_CH (FuriHalUartIdUSART1) +#define BAUDRATE (115200) + +struct WifideautherUart { + WifideautherApp* app; + FuriThread* rx_thread; + StreamBufferHandle_t rx_stream; + uint8_t rx_buf[RX_BUF_SIZE + 1]; + void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context); +}; + +typedef enum { + WorkerEvtStop = (1 << 0), + WorkerEvtRxDone = (1 << 1), +} WorkerEvtFlags; + +void wifi_deauther_uart_set_handle_rx_data_cb( + WifideautherUart* uart, + void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context)) { + furi_assert(uart); + uart->handle_rx_data_cb = handle_rx_data_cb; +} + +#define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone) + +void wifi_deauther_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) { + WifideautherUart* uart = (WifideautherUart*)context; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + if(ev == UartIrqEventRXNE) { + xStreamBufferSendFromISR(uart->rx_stream, &data, 1, &xHigherPriorityTaskWoken); + furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } +} + +static int32_t uart_worker(void* context) { + WifideautherUart* uart = (void*)context; + + while(1) { + uint32_t events = + furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever); + furi_check((events & FuriFlagError) == 0); + if(events & WorkerEvtStop) break; + if(events & WorkerEvtRxDone) { + size_t len = xStreamBufferReceive(uart->rx_stream, uart->rx_buf, RX_BUF_SIZE, 0); + if(len > 0) { + if(uart->handle_rx_data_cb) uart->handle_rx_data_cb(uart->rx_buf, len, uart->app); + } + } + } + + vStreamBufferDelete(uart->rx_stream); + + return 0; +} + +void wifi_deauther_uart_tx(uint8_t* data, size_t len) { + furi_hal_uart_tx(UART_CH, data, len); +} + +WifideautherUart* wifi_deauther_uart_init(WifideautherApp* app) { + WifideautherUart* uart = malloc(sizeof(WifideautherUart)); + + uart->app = app; + uart->rx_stream = xStreamBufferCreate(RX_BUF_SIZE, 1); + uart->rx_thread = furi_thread_alloc(); + furi_thread_set_name(uart->rx_thread, "WifideautherUartRxThread"); + furi_thread_set_stack_size(uart->rx_thread, 1024); + furi_thread_set_context(uart->rx_thread, uart); + furi_thread_set_callback(uart->rx_thread, uart_worker); + + furi_thread_start(uart->rx_thread); + + furi_hal_console_disable(); + furi_hal_uart_set_br(UART_CH, BAUDRATE); + furi_hal_uart_set_irq_cb(UART_CH, wifi_deauther_uart_on_irq_cb, uart); + + return uart; +} + +void wifi_deauther_uart_free(WifideautherUart* uart) { + furi_assert(uart); + + furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtStop); + furi_thread_join(uart->rx_thread); + furi_thread_free(uart->rx_thread); + + furi_hal_uart_set_irq_cb(UART_CH, NULL, NULL); + furi_hal_console_enable(); + + free(uart); +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_uart.h b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_uart.h new file mode 100644 index 000000000..534c2fdf7 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wifi_deauther/wifi_deauther_uart.h @@ -0,0 +1,14 @@ +#pragma once + +#include "furi_hal.h" + +#define RX_BUF_SIZE (320) + +typedef struct WifideautherUart WifideautherUart; + +void wifi_deauther_uart_set_handle_rx_data_cb( + WifideautherUart* uart, + void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context)); +void wifi_deauther_uart_tx(uint8_t* data, size_t len); +WifideautherUart* wifi_deauther_uart_init(WifideautherApp* app); +void wifi_deauther_uart_free(WifideautherUart* uart); diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/LICENSE new file mode 100644 index 000000000..95e544a06 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 BlueChip + +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/Official/DEV_FW/source/xMasterX/wii_ec_anal/README.md b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/README.md new file mode 100644 index 000000000..fed7a1493 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/README.md @@ -0,0 +1,233 @@ +# [FlipperZero] Wii Extension Controller Protocol Analyser +This Protocol Analyser offers a full Test and Calibrate system for Wii Extension Controllers. + +__Disclaimer:__ *Use of this plugin, and notably connecting an Extension Controller to the FlipperZero is performed entirely at your own risk.* + +# Notes +This plugin has (todate) only been tested with official Nintendo Nunchucks and Classic Controllers - namely Nunchucks and Classic Controllers. + +# Encryption +This plugin has SOME code to handle encryption, but it it unused, untested, and some of it is known to un-work. + +This plugin (currently) only works with Extension Controllers which implement the encryption-bypass strategy. IE. `i2c_write(0xf0, 0x55) ; i2c_write(0xfb, 0x00)` + +If you need this functionality, either raise an Issue or, better still, a Pull Request. + +# Screen: SPLASH +
    +The SPLASH Screen is displayed when the Plugin starts. It can be cleared by pressing any key, else it will auto-clear after 3.5 seconds. + +# Screen: WAIT +   

    +The WAIT screen will display which pins you need to connect between the flipper and the Wii Extension Controller. + +__Disclaimer:__ Use of this plugin, and notably connecting the Controller to the FlipperZero is performed entirely at your own risk. + +Looking in to the exposed side of the Extension Controller plug, with the notch on the bottom + +| EC Pin # | EC Position | EC Pin ID | Pin Function | FZ GPIO Pin Name | FZ GPIO Pin # | +| :---: | :---: | :---: | :---: | :---: | :---: | +| 1 | top-left | +3v3 | Power | 3v3 | 9 | +| 2 | bottom-left | SCL | i2c clock | C0 | 16 | +| 3 | top-centre | EN | ¿detect? | | | +| 4 | bottom-centre | -x- | -none- | | | +| 5 | top-right | SDA | i2c data | C1 | 15 | +| 6 | bottom-right | Gnd | Power | Gnd | 18 | + +Keys: +* Left - Show splash screen +* Back - exit plugin + +The easiest way to connect a Wii Extension Controller to a FlipperZero is arguably with a ["WiiChuck"](https://www.ebay.co.uk/sch/?_nkw=wiichuck) or a ["Nunchucky"](https://www.solarbotics.com/product/31040)

    + + + + + +
    WiiChuckNunchucky
    + +### ** WARNING ** +Neither the WiiChuck, nor the Nunchucky have a pin polarisation mechanism.
    +If you plug the adaptor in the wrong way around you WILL apply voltage to the Controller the wrong way round!!
    +I have no idea if THIS WILL PERMANENTLY KILL THE CONTROLLER ...Who wants to try it? + +On all the WiiChucks I have seen: +* The WiiChuck has THREE connectors on one side, and TWO connectors on the other. +* The side with TWO connectors should go against the side of the Controller plug with the big indent. +``` ++-------------+ +| _________ | +| | = = = | | +| |_=_____=_| | <-- notice missing pin +| ___ | +| | | | <-- notice indent ++----+ +----+ +``` +
    + +...BUT I *highly* recommend you check the pins on your adaptor to make sure everything goes well. + +I believe the unconnected pin on the top is a "presence detect" function, but I have not (yet) verified this.
    +This feature is NOT required by this plugin, as the detection is performed by means of an i2c handshake. + +When a device is connected it will be immediately recognised. If it is not, either: +* The Controller is not correctly connected
    +...This may be as simple as a broken wire. +* The controller board in the Controller is faulty.
    +...Repair of which is beyond the scope of this document. + +To get the list of "known" Controllers, run `./info.sh`
    +As of writing this, that returns: +```c +[PID_UNKNOWN ] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, "Unknown Perhipheral", SCENE_DUMP, +[PID_NUNCHUCK ] = { {0x00, 0x00, 0xA4, 0x20, 0x00, 0x00}, "Nunchuck", SCENE_NUNCHUCK, +[PID_CLASSIC ] = { {0x00, 0x00, 0xA4, 0x20, 0x01, 0x01}, "Classic Controller", SCENE_CLASSIC, +[PID_BALANCE ] = { {0x00, 0x00, 0xA4, 0x20, 0x04, 0x02}, "Balance Board", SCENE_DUMP, +[PID_GH_GUITAR ] = { {0x00, 0x00, 0xA4, 0x20, 0x01, 0x03}, "Guitar Hero Guitar", SCENE_DUMP, +[PID_GH_DRUMS ] = { {0x01, 0x00, 0xA4, 0x20, 0x01, 0x03}, "Guitar Hero World Tour Drums", SCENE_DUMP, +[PID_TURNTABLE ] = { {0x03, 0x00, 0xA4, 0x20, 0x01, 0x03}, "DJ Hero Turntable", SCENE_DUMP, +[PID_TAIKO_DRUMS] = { {0x00, 0x00, 0xA4, 0x20, 0x01, 0x11}, "Taiko Drum Controller)", SCENE_DUMP, + +``` + +You can see that there are EIGHT known devices. One is the default for an unknown controller; SEVEN devices are known by name; and TWO (of those seven) have bespoke "scenes" (ie. SCENE_NUNCHUCK & SCENE_CLASSIC). + +# Screen: NUNCHUCK - MAIN +
    +When you connect a Nunchuck, you will see a screen displaying: +* Accelerometer{X,Y,Z} values +* Joystick{X,Y} values +* Joystick graphic +* Button{C,Z} + +Keys: +* Left - Go to the DUMP screen +* Right - Go to the NUNCHUCK_ACC accelerometers screen +* Up/Down/OK - [qv. Peak Meters] +* Short-Back - Reset controller +* Long-Back - Exit plugin + +# Screen: NUNCHUCK - ACCELEROMETERS + +   
    + +| Axis | Movement | Lower | Higher | +| :---: | :---: | :---: | :---: | +| X | Left / Right | Left | Right | +| Y | Fwd / Bkwd | Fwd | Bkwd | +| Z | Down / Up | Down | Up | + +* Movement in the direction of an axis changes that axis reading +* Twisting/tilting around an axis changes the other two readings +* EG. + * Move left (along the X axis) will effect X + * Turn left (a rotation around the Y axis) will effect X and Z + +Keys: +* Left - go to the main NUNCHUCK screen +* Up + * Auto-Pause Disabled --> Enable Auto-Pause + * Paused at the end of a page --> Restart scanner + * Running with Auto-Pause Enabled --> Disable Auto-Pause +* Nunchuck-Z - Toggle pause +* Nunchuck-C - Toggle auto-pause +* Long-OK - Enter Software Calibration mode [qv. Calibration] + * Calibration mode on the Accelerometer screen will ONLY calibrate the accelerometer +* Short-OK - Leave Software Calibration mode *and* Calibrate CENTRE position(s) +* Short-Back - Reset controller +* Long-Back - Exit plugin + +NB. Code DOES exist to scroll the display, but the LCD refresh rate is too low, and it looks awful + +# Screen: CLASSIC +
    +When you connect a Classic Controller [Pro], you will see a screen displaying a Classic Controller +* The Classic Controller will animate in line with controller events +* The scan rate is set to 30fps, but in reality there is a bit of lag with the LCD screen, so YMMV. + +Keys: +* Left - go to the DUMP screen +* Right - show analogue readings (Left to hide them again) +* Up/Down/OK - [qv. Peak Meters] +* Short-Back - Reset controller +* Long-Back - Exit plugin + +# Screen: DUMP +
    +The Dump screen will show you the raw readings from the device.
    +If you connect a device which does not have a bespoke `_decode()` function (etc.), you will see (only) this screen. +* SID - String ID - human-readable name (from the `info` table) +* PID - Peripheral ID - The 6 bytes which identify the device. +* Cal - Calibration data - 16 bytes +* The bottom row of hex shows the SIX bytes of Controller data + * Below each hex digit is the binary representation of that digit + * By example. With a Nunchuck connected, click the Z button, and watch the bit on the far right + +Keys: +* Right - return to controller-specific screen (if there is one) +* Short-Back - Reset controller +* Long-Back - Exit plugin + +# Peak Meters (Calibration values) + +On any Controller-specific screen with a Peak/Trough menu displayed: +* Up - [toggle] only show peak values +* Down - [toggle] only show trough values +* Long-OK - Enter Software Calibration mode [qv. Calibration] +* Short-OK - Leave Software Calibration mode / Calibrate CENTRE position(s) + +# Calibration +
    + +Digital buttons do NOT require Calibration. + +Some controllers have Calibration data which is calculated at the factory, and stored in memory (¿OTP?) on the Controller. +EG. Classic Controller HAS Calibration data, but Classic Controller Pro does NOT! + +Each device has a different way to interpret the Calibration Data.
    +EG. A Nunchuck has one joystick, and an accelerometer ...whereas a Classic Controller has 2 joysticks and 2 analogue buttons. + +I have personally found the calibration data to be inaccurate (when compared to actual readings), I guess Controllers drift over the years‽ +If the factory-values LIMIT movement, this is easily resolved - by expanding them on-the-fly.
    +BUT, I have seen Controllers with factory calibration data that suggests the limits are FURTHER than the joystick can reach ...and this requires a full re-calibration of the Controller! + +Probably the best way to calibrate is to: +* Take a/some reading(s) while the Controller is 'at rest', IE. perfectly still and level. +* Move the Controller to all extremes and store the extreme {peak/trough} values. + +Nintendo (allegedly) take the 'at rest' reading immediately after the Controller is connected, and a 're-calibration' can be performed at any time by pressing {`A`, `B`, `+`, `-`} at the same time, for at least 3 seconds. Although I have no details on what this actually does. + +### This tool calibrates as such: +* When the Controller is first recognised + * The factory Calibration data is used to decide the Centre/Middle position and extreme values (eg. far-left & far-right) for each analogue Control +* Long-OK button press (on the FlipperZero) ...Do NOT touch ANY of the analogue controllers while you are pressing Long-OK + * Start the calibrate button flashing + * Take the current reading as the Centre position + * Set the range limits to "no range" + * You must now move the Control between its extremes, so the code can work out the new Calibration/range/peak+trough values + * When done, press Short-OK to end Software Calibration mode +* Short-OK button press (on the FlipperZero) ...Do NOT touch ANY of the analogue controllers while you are pressing Short-OK + * Stop the calibrate button flashing + * Calibrate the centre position of all analogue controls (accelerometers not supported (yet)) + +# Screen: DEBUG +
    +On any screen (except SPLASH) you may press Long-Down to enter Debug mode. + +You can (at any time) attach to the FlipperZero (via USB) with a serial console {`minicom`, `putty`, whatever} and start the `log` function to see the debug messages. + +When you enter the DEBUG screen, the real-time scanner will be stopped. And the following keys made available: +* Up - Attempt to initialise the attached Controller +* OK - Take a reading from the attached Controller +* Long-Down - Restart the real-time scanner and return to the WAIT screen + +You can limit the messages at compile-time [see `./info.sh`], or at runtime [FZ->Settings->System->LogLevel]
    + +[This is probably irrelevant since the introduction of FAP support]
    +If you have memory issues, limiting the messages at compile-time will make the plugin smaller.
    +But (¿obviously?) the more you limit the messsages, the less debug information will be sent to the logger. + +# TODO + +* FZ Bug: At the time of writing this, there are problems with the i2c FZ functions [qv `i2c_workaround.c`] + diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/README.txt b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/README.txt new file mode 100644 index 000000000..e7ebe7a4c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/README.txt @@ -0,0 +1,67 @@ + ,-------. +---( Files )--- + `-------' + + README.md - User Manual : Body [github markdown] + _images/ - User Manual : Images + _images/GIMP/ - User Manual : GIMP image masters + + LICENSE - Tech Docs : MIT Licence file + README.txt - Tech Docs : Dev notes + notes.txt - Tech Docs : Random dev notes + info.sh - Tech Docs : Retrieve info from source code + + application.fam - FAP : Header file + WiiEC.png - FAP : Icon {10x10} + + gfx/ - Analyser : Images [generated by bc_image_tool] + wii_anal.c|h - Analyser : Main application + wii_anal_ec.c|h - Analyser : Extension controller actions + wii_anal_keys.c|h - Analyser : Keyboard handling + wii_anal_lcd.c|h - Analyser : LCD handling + + i2c_workaround.h - Temporary workaround for i2c bug in FZ code + err.h - Errors + bc_logging.h - Logging macros - especially LOG_LEVEL + + wii_i2c.c|h - i2c functionality + + wii_ec.c|h - Extension Controller basic functions + wii_ec_macros.h - Bespoke Extension Controller handy-dandy MACROs + wii_ec_classic.c|h - EC: Classic Controller Pro scene + wii_ec_nunchuck.c|h - EC: Nunchuck scene + wii_ec_udraw.c|h - EC: UDraw scene - not written + + ,----------------------------------. +---( Adding a new Extension Controller )--- + `----------------------------------' + +//! I'll finish this when I write the UDraw code + +Create a new Extension Controller called "mydev" + +Create wii_ec_mydev.c and wii_ec_mydev.h + +In wii_ec_mydev.c|h + Create the functions [& prototypes] + bool mydev_init (wiiEC_t* const) ; // Additional initialisation code + void mydev_decode (wiiEC_t* const) ; // Decode controller input data + void mydev_msg (wiiEC_t* const, FuriMessageQueue* const) ; // Put event messages in the event queue + void mydev_calib (wiiEC_t* const, ecCalib_t) ; // Controller calibration function + void mydev_show (Canvas* const, state_t* const) ; // Scene LCD display + bool mydev_key (const eventMsg_t* const, state_t* const) ; // Scene key controls + +In wii_ec.h + Include the new header + #include "wii_ec_mydev.h" + Add a perhipheral id to enum ecPid + PID_MYDEV + +In wii_anal.h + As a scene name to enum scene + SCENE_MYDEV + +In wii_ec.c + Add the device definition to the ecId[] array + [PID_MYDEV] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, "My Device", SCENE_MYDEV, + mydev_init, mydev_decode, mydev_msg, mydev_calib, mydev_show, mydev_key }, diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/WiiEC.png b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/WiiEC.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1afcb0cdf4edb2b6ed8877a7f4abee7cc18eef GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V6Od#Ihsko;mLT)4~l} zNhv8QPR|xh! O7zR&QKbLh*2~7YOV Export As + filename: EXAMPLE.c + Type : "C source code" + [Export] + prefixed name: gimp_image + Comment : + [x] Use GLib types + [ ] <> + Opacity : 100% + [Export] + +2. Prepare conversion tool [stored in (eg.) /path/] + a. cp _convert*.* /path/ + b. cp EXAMPLE.c /path/ + +3. Run the conversion tool + a. cd /path/ + b. ./_convert.sh EXAMPLE.c + +4. All being well, you will see an ascii version of your image. + If not, then you're gonna have to submit a bug report + +5. You should now have a directory called img_/ + In that directory should be + img_EXAMPLE.c - The data for your new image + img_*.c - The data for other images + images.h - A header for ALL images that have been created in this directory + images.c - A sample FlipperZero show() function [not optimised] diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert.c b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert.c new file mode 100644 index 000000000..267985e8d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include + +int main (int argc, char* argv[]) +{ + const unsigned char* pp = NULL; + uint32_t pix = 0; + int bit = 0; + + uint8_t b = 0; + uint8_t bcnt = 0; + + unsigned int lcnt = 0; + static const int lmax = 16; // max hex values per line + + uint8_t* buf = NULL; + uint8_t* bp = NULL; + unsigned int blen = 0; + + uint8_t* cmp = NULL; + uint8_t* cp = NULL; + unsigned int clen = 0; + uint8_t ctag = 0xFF; + uint32_t tag[256] = {0}; + uint32_t tmax = UINT32_MAX; + + unsigned int x, y, z; + + const char* name = argv[1]; + FILE* fh = fopen(argv[2], "wb"); + + uint32_t white = 0xFF; + + int rv = 0; // assume success + + // allocate buffers + blen = ((img.w * img.h) +0x7) >>3; + bp = (buf = calloc(blen +1, 1)); + cp = (cmp = calloc(blen +4, 1)); + + // sanity check + if (!fh || !buf || !cmp) { + printf("! fopen() or malloc() fail.\n"); + rv = 255; + goto bail; + } + + // Find white value + for (x = 1; x < img.bpp; x++) + white = (white << 8) | 0xFF ; + + // build bit pattern + // create the comment as we go + for (pp = img.b, y = 0; y < img.h; y++) { + fprintf(fh, "// "); + for (x = 0; x < img.w; x++) { + // read pixel + for (pix = 0, z = 0; z < img.bpp; pix = (pix << 8) | *pp++, z++) ; + // get bit and draw + if (pix < white) { + b = (b << 1) | 1; + fprintf(fh, "##"); + } else { + b <<= 1; + fprintf(fh, ".."); + } + // got byte + if ((++bcnt) == 8) { + *bp++ = b; + tag[b]++; + bcnt = (b = 0); + } + } + fprintf(fh, "\n"); + } + fprintf(fh, "\n"); + // padding + if (bcnt) { + b <<= (bcnt = 8 - bcnt); + *bp++ = b; + tag[b]++; + } + // Kill the compression + *bp = ~bp[-1]; // https://youtube.com/clip/Ugkx-JZIr16hETy7hz_H6yIdKPtxVe8C5w_V + + // Byte run length compression + // Find a good tag + for (x = 0; tmax && (x < 256); x++) { + if (tag[x] < tmax) { + tmax = tag[x]; + ctag = x; + } + } + + // compress the data + for (bp = buf, x = 0; (clen < blen) && (x < blen); x++) { + // need at least 4 the same to be worth it + // must compress tag (if it occurs) + if ((bp[x] == bp[x+1]) && (bp[x] == bp[x+2]) && (bp[x] == bp[x+3]) || (bp[x] == ctag)) { + for (y = 1; (y < 255) && (bp[x] == bp[x+y]); y++) ; + *cp++ = ctag; // tag + *cp++ = y; // length + *cp++ = bp[x]; // byte + x += y -1; + clen += 3; + } else { + *cp++ = bp[x]; + clen++; + } + } + + // create struct + fprintf(fh, "#include \"images.h\"\n\n"); + fprintf(fh, "const image_t img_%s = { %d, %d, ", name, img.w, img.h); + + if (clen < blen) { // dump compressed? + fprintf(fh, "true, %d, 0x%02X, { // orig:%d, comp:%.2f%%\n\t", + clen, ctag, blen, 100.0-((clen*100.0)/blen)); + for (x = 0; x < clen; x++) + if (x == clen -1) fprintf(fh, "0x%02X\n}};\n", cmp[x]) ; + else fprintf(fh, "0x%02X%s", cmp[x], (!((x+1)%16)) ? ",\n\t" : ", ") ; + + } else { // dump UNcompressed + fprintf(fh, "false, %d, 0, {\n\t", blen); + for (x = 0; x < blen; x++) + if (x == blen -1) fprintf(fh, "0x%02X\n}};\n", buf[x]) ; + else fprintf(fh, "0x%02X%s", buf[x], (!((x+1)%16)) ? ",\n\t" : ", ") ; + } + +bail: + if (fh) fclose(fh) ; + if (buf) free(buf) ; + if (cmp) free(cmp) ; + + return rv; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert.sh b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert.sh new file mode 100644 index 000000000..aaa7977b5 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +[ -z $1 ] && { + echo "Specify an image" + echo "gimp -> export -> c source file -> [x] gunit names" + exit 2 +} + +echo $* + +for N in $* ; do + + [ ! -f $N ] && { + echo "!! File missing $N" + continue + } + + # filename (sans extension) + FN=$(basename -- "$N") + EXT="${FN##*.}" + NAME="${FN%.*}" + + OUTDIR=img_/ + mkdir -p ${OUTDIR} + + HDR=${OUTDIR}/images.h + SRC=${OUTDIR}/images.c + + OUT=${OUTDIR}/img_${NAME}.c + + echo -e "\n¦${N}¦ == ¦${NAME}¦ -> ¦${OUT}¦" + + TESTX=test_${NAME} + TESTC=test_${NAME}.c + + # compile name + CONV=${NAME}_ + + # clean up gimp output + sed -e "s/gimp_image/img/g" \ + -e 's/guint8/unsigned char/g' \ + -e 's/width/w/g' \ + -e 's/height/h/g' \ + -e 's/bytes_per_pixel/bpp/g' \ + -e 's/pixel_data/b/g' \ + -e 's/guint/unsigned int/g' \ + $N \ + | grep -v ^/ \ + | grep -v ^$ \ + > ${CONV}.c + + # append conversion code + cat _convert.c >> ${CONV}.c + + # compile & run converter + rm -f ${CONV} + gcc ${CONV}.c -DIMGTEST -o ${CONV} + ./${CONV} ${NAME} ${OUT} + rm -f ${CONV} ${CONV}.c + + # (create &) update header + [[ ! -f ${HDR} ]] && cp _convert_images.h ${HDR} + sed -i "/ img_${NAME};/d" ${HDR} + sed -i "s#//\[TAG\]#//\[TAG\]\nextern const image_t img_${NAME};#" ${HDR} + + # sample FZ code + [[ ! -f images.c ]] && cp _convert_images.c ${SRC} + + # test + ROOT=${PWD} + pushd ${OUTDIR} >/dev/null + sed "s/zzz/${NAME}/" ${ROOT}/_convert_test.c > ${TESTC} + rm -f ${TESTX} + gcc ${TESTC} ${OUT##*/} -DIMGTEST -o ${TESTX} + ./${TESTX} + rm -f ${TESTX} ${TESTC} + popd >/dev/null + +done diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert_images.c b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert_images.c new file mode 100644 index 000000000..57046e9a3 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert_images.c @@ -0,0 +1,141 @@ +#include // GUI (screen/keyboard) API + +#include "images.h" + +//----------------------------------------------------------------------------- ---------------------------------------- +static Canvas* _canvas; +static uint8_t _tlx; +static uint8_t _tly; + +static uint8_t _x; +static uint8_t _y; + +static const image_t* _img; + +static bool _blk; +static Color _set; +static Color _clr; + +//+============================================================================ +static +void _showByteSet (const uint8_t b) +{ + for (uint8_t m = 0x80; m; m >>= 1) { + if (b & m) // plot only SET bits + canvas_draw_dot(_canvas, (_tlx +_x), (_tly +_y)) ; + if ( ((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h) ) break ; + } +} + +//+============================================================================ +static +void _showByteClr (const uint8_t b) +{ + for (uint8_t m = 0x80; m; m >>= 1) { + if (!(b & m)) // plot only CLR bits + canvas_draw_dot(_canvas, (_tlx +_x), (_tly +_y)) ; + if ( ((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h) ) break ; + } +} + +//+============================================================================ +static +void _showByteAll (const uint8_t b) +{ + for (uint8_t m = 0x80; m; m >>= 1) { + if ((!!(b & m)) ^ _blk) { // Change colour only when required + canvas_set_color(_canvas, ((b & m) ? _set : _clr)); + _blk = !_blk; + } + canvas_draw_dot(_canvas, (_tlx +_x), (_tly +_y)) ; + if ( ((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h) ) break ; + } +} + +//+============================================================================ +// available modes are SHOW_SET_BLK - plot image pixels that are SET in BLACK +// SHOW_XOR - same as SET_BLACK +// SHOW_SET_WHT - plot image pixels that are SET in WHITE +// SHOW_CLR_BLK - plot image pixels that are CLEAR in BLACK +// SHOW_CLR_WHT - plot image pixels that are CLEAR in WHITE +// SHOW_ALL - plot all images pixels as they are +// SHOW_ALL_INV - plot all images pixels inverted +// +void show (Canvas* const canvas, const uint8_t tlx, const uint8_t tly, + const image_t* img, const showMode_t mode) +{ + void(*fnShow)(const uint8_t) = NULL; + + const uint8_t* bp = img->data; + + // code size optimisation + switch (mode & SHOW_INV_) { + case SHOW_NRM_: + _set = ColorBlack; + _clr = ColorWhite; + break; + + case SHOW_INV_: + _set = ColorWhite; + _clr = ColorBlack; + break; + + case SHOW_BLK_: + canvas_set_color(canvas, ColorBlack); + break; + + case SHOW_WHT_: + canvas_set_color(canvas, ColorWhite); + break; + + } + switch (mode & SHOW_INV_) { + case SHOW_NRM_: + case SHOW_INV_: + fnShow = _showByteAll; + canvas_set_color(canvas, ColorWhite); + _blk = 0; + break; + + case SHOW_BLK_: + case SHOW_WHT_: + switch (mode & SHOW_ALL_) { + case SHOW_SET_: + fnShow = _showByteSet; + break; + case SHOW_CLR_: + fnShow = _showByteClr; + break; + } + break; + } + furi_check(fnShow); + + // I want nested functions! + _canvas = canvas; + _img = img; + _tlx = tlx; + _tly = tly; + _x = 0; + _y = 0; + + // Compressed + if (img->c) { + for (unsigned int i = 0; i < img->len; i++, bp++) { + // Compressed data? {tag, length, value} + if (*bp == img->tag) { + for (uint16_t c = 0; c < bp[1]; c++) fnShow(bp[2]) ; + bp += 3 -1; + i += 3 -1; + + // Uncompressed byte + } else { + fnShow(*bp); + } + } + + // Not compressed + } else { + for (unsigned int i = 0; i < img->len; i++, bp++) fnShow(*bp) ; + } +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert_images.h b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert_images.h new file mode 100644 index 000000000..bfc44568e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert_images.h @@ -0,0 +1,53 @@ +#ifndef IMAGES_H_ +#define IMAGES_H_ + +#include +#include + +//----------------------------------------------------------------------------- ---------------------------------------- +typedef + enum showMode { + // {INV:--:WHT:BLK::--:--:CLR:SET} + SHOW_SET_ = 0x01, + SHOW_CLR_ = 0x02, + SHOW_ALL_ = SHOW_SET_ | SHOW_CLR_, + + SHOW_BLK_ = 0x10, + SHOW_WHT_ = 0x20, + SHOW_NRM_ = 0x00, + SHOW_INV_ = SHOW_BLK_ | SHOW_WHT_, + + SHOW_SET_BLK = SHOW_SET_ | SHOW_BLK_, + SHOW_SET_WHT = SHOW_SET_ | SHOW_WHT_, + + SHOW_CLR_BLK = SHOW_CLR_ | SHOW_BLK_, + SHOW_CLR_WHT = SHOW_CLR_ | SHOW_WHT_, + + SHOW_ALL = SHOW_ALL_ | SHOW_NRM_, + SHOW_ALL_INV = SHOW_ALL_ | SHOW_INV_, + } +showMode_t; + +//----------------------------------------------------------------------------- ---------------------------------------- +typedef + struct image { + uint8_t w; // width + uint8_t h; // height + bool c; // compressed? + uint16_t len; // image data length + uint8_t tag; // rle tag + uint8_t data[]; // image data + } +image_t; + +//----------------------------------------------------------------------------- ---------------------------------------- +//[TAG] + +//----------------------------------------------------------------------------- ---------------------------------------- +#ifndef IMGTEST +# include + void show (Canvas* const canvas, const uint8_t tlx, const uint8_t tly, + const image_t* img, const showMode_t mode) ; +#endif + +#endif //IMAGES_H_ diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert_test.c b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert_test.c new file mode 100644 index 000000000..4bdb531d5 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_image_tool/_convert_test.c @@ -0,0 +1,59 @@ +#include +#include + +#include "images.h" + +//----------------------------------------------------------------------------- +// This will be the plot function out of your graphics library +// +#define PLOT(x,y,c) do { \ + printf("%s", (c ? "#" : ".")); \ + if (x == img->w -1) printf("\n") ; \ +}while(0) + +//+============================================================================ +// The pain we endure to avoid code duplication cleanly +// +#define PLOTBYTE(b) do { \ + for (uint8_t m = 0x80; m; m>>=1) { \ + PLOT(x,y, (b & m)); \ + if ( ((++x) == img->w) && !(x = 0) && ((++y) == img->h) ) break ; \ + } \ +}while(0) + +void show (const image_t* img) +{ + // Some variables + const uint8_t* bp = img->data; + unsigned int x = 0; + unsigned int y = 0; + + // Compressed + if (img->c) { + for (unsigned int i = 0; i < img->len; i++, bp++) { + // Compressed data? {tag, length, value} + if (*bp == img->tag) { + for (uint16_t c = 0; c < bp[1]; c++) PLOTBYTE(bp[2]) ; + bp += 3 -1; + i += 3 -1; + + // Uncompressed byte + } else { + PLOTBYTE(*bp); + } + } + + // Not compressed + } else { + for (unsigned int i = 0; i < img->len; i++, bp++) PLOTBYTE(*bp) ; + } +} + +#undef PLOTBYTE + +//+============================================================================ +int main (void) +{ + show(&img_zzz); + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/CLASSIC.png b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/CLASSIC.png new file mode 100644 index 0000000000000000000000000000000000000000..aa5318b33cf0809a7b285485ab24423e24b569ab GIT binary patch literal 4373 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 Q8~_k-Fz5jL-{cGb3;$c><^TWy literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/CLASSIC_N.png b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/CLASSIC_N.png new file mode 100644 index 0000000000000000000000000000000000000000..24f4ac2255065b18de6bfba7bc150ffe747247a9 GIT binary patch literal 5147 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/DEBUG.png b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/DEBUG.png new file mode 100644 index 0000000000000000000000000000000000000000..bca35c6939d513db5fa232edcca1933c8294e18b GIT binary patch literal 3942 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 V+#0z=0MOs=te*>@k-AMod literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/DUMP.png b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/DUMP.png new file mode 100644 index 0000000000000000000000000000000000000000..dc9328aabd4d79a2b7feafef07c6a894a781143f GIT binary patch literal 4763 zcmb7Idsq`!`W~u_T`Ri1VTx$*(ssMGf>os461OVowl%h1Vud7BEeKSo1_iMCifxaW-^&%C)jHH-*5BGJWrmSGv9pY z``-6G@5#Y+YjfkKCQJnYAa2d-mG1$-6C?nLAw3yO{4(bw@nHaXX6u@jf89_$Mzf zBxf@{4>aFZseX+W`bA5-V&`YH%kqM$ZIn6W@6-}f%g#xi*#J-%^a zJUWXWQAsFQ&8_c~7@x1howYlJTiDFz(v%!Dna4QLKO`G{b74H_sd*abWp}-F{kcB^ zM<;5lW9+-fSU}gIMGB4=Kg^uDRpBc{SqtN(&k`Y()`!ipi~YA$kRt$YnhRd%z? z;b0W4BxcOY^{O+^HN5f+aFuA&W_XNq?BXR950tQd1D}2ip1>K=Fhvmovuw`=B1F4b z%2@w8clO~O;T$P!u1slnr*)}HUca%`RXSx#bLpb6%df9}V*)mc%%@%wRLi_t0X7tAO96We)>xIo(lsSwQF7u1q{*JIi zT!t(mxKOmPAlr5IH^2`*NVpFLdjf;7SpNG6`0$czClOBHkC;?$35gs z%79Wcg&#WpwfDlEQp%T>bYXeEfYM=*2`=L`74~2;eB1G?eD(}-fv3;aX-b0|C*7t9 z(NjBofek1NQ_~y}QN?_!BhM1LQIY~oVDWNS3(>rf+eH-aT7DI!P%8B?R$wP>ErORj zY3E}{6cd9cUdViEtB1b@UP2~N%QvM(Zej!$WiAodplgkX`$psSIn(>2C9>%2JUAJuNnYKCc(ChldPcuKeU_ zQ3>1={!294a6KUvN6RqIvGeNb-BzkjJrtH0BlNtq6_LB@6Zl3uW5MYM8goLuJw0S^ z{M=fZ;WVjDoW~BA~@(19IsB!KefaS|lNx<@{siX;L z*R9x9{l5(!x|>jsNK}Jj2o(*fxqW6=s9j9nDOyU^Vp5}8k6S#pv0O))9&)RIu4s6c3-cP*1`fc0iz@MA-UY+?(t^Yf|3F1zb4h2 z8uwcp4-A}o*B9VWq|RZcaF&8eM&r& ze_#@@eF@R2A5}KvwUX4QJH!nFp-dWmTOVYNKFld+Rbq5dC@TkpUc+mV>r+Ttc2EV| zc1lol`hQI6a;@$h*{Ie8^p4;vG28`Lm9r`^y-v|3XqF-zrBHi|EQ$R2k%Ab<66!Uu z&4CB(=~@k<$iwo%3+(e8*|p6(C9_kP`p?}Pas-Z2t{%_6HJeeJ#G78~Ii<6AdWsa~ z6{2B0*x9G>^MWd!oICw;2CT*9!7xb>8FmC6%oYEPB?R=y1RpLZ)SJV31i#d>-WrKX zt#`nVpw~p!NX2F4XrM-?>GZg_`fZ${u64wsWWBrO%Wf^>wTAl*il8#7kOk)IZPnXZ zpedA7dj6ak98zwolKpiM5B5@oz6{#C|6C31sUUXhEVa*ik!C~Ou}gXsHp zkI-6H9hXyznZrE4&M+sHq$7%q2V1MaA(L0x?>)(wznI7Patvtpw(T|hTG8xWKau6? zEw{+{qP_hkZ*vt?V!9A46eUx!2O9iCFta%r{unQjv%Ic6P%42Qw}lY)?H*-(J5=sZ zA7hrJI0g77kd=#YytXthPlpa!!$gfOW2)P?iL(~ z5_aMAoA>_b!3EvW4{y6i+}PcbP9NQ9GQ08!nlzbbW7p@z?$;CRgbgnAfSvk|)I z?MrXFB=8`5o!rmu?2~ti%u+Vif|WbMOOyf`EE*sL@6t9x)z7TocP#7HrJ*n#R{Ied zE22l_qCS<-Np%=%A|)yDQItni27jNW^9Vc?DZ!I7kaR306SIueO{i1`gG4wDt{A8p zR0(7b7O|s!n;6}AB?;5m!+qcwzY2<25Ka(R25}vaDjA@pl1fs9Cqwp5XEP=h;O$_8 zYD=W9iB=iej6djrcfM<+$_zTJ?4%Y22f{Ml1(H#1x6xH1LgudSj@qn>l9cH@|24a< zL2yMIWO?|7EU8uu@_KJtbnFUVRbI=PU?7`EgzSBgJIrMuH=N(_o41VmNOYcS1g5JdxQvrDe7F24bQ8+fwOl<^p3#O*(RqS zDMN3+LN55`+IKqT>Kv$8>RTi>LLxw~Be34iiyk#GOg!G)s$SI@R zIs&O9Ys*<)oYE!AIYHQwA73DlXt`VPHnUXy1#Aixm9vOC;qqmnYJI zmqPC;@~n7r!l^$3{YCY;@dxZ(3%{fV{y_^ocLzBXSV%6osGd1X(*MIiCbA3*eHG}T zM6Bs|%mHr`ttyhgb1lc?r8tBQ5RXdrLc^8Ga~{`gzph}z$!z26ln^?Z^c2$d!w4jl!4=`1+&B0IyR)hvj4k1~kLXbfOu?9}5`qm{s-r2@e zNgDTMLsy(qRkt#(TLpj7VZhbAxcvyCPo3F}`p09s&FOM;pojUEsG|3(6`hyf8auxc zwev5Pl%2y+qtkCJP06DA`w%;y6UlbXoemuBjh@|FVn@a}MLlIuaVkl6pY0)BfRMiL zbnLdTk*^c#d%>dNpBW4MZP(0SNWdMUMBG_#ME%ARA{KNTv2(J$uM@uK%*0mz8hzi> z+2LaLN173D6KV~@la%+}Wq2xAMN`5>Fttfq3Zuay@}q)E66&vy{z(SW z;=13*wHcGfEkYetc0`dM*KI9Tikq$vJ3_QOEn%*Y0Em-=yYC0;f49zE{>>9ySieyE z>Szal&tmQotn32+b_;QZz9+E%o9Sn-rPTgex^;pUvgr2-id^8IBecEj`-eTap7<62 z&;-BE#}eNsg5MlJOPG%D=KdQnSbvoNO59KO7T$AKo|CQO59 z_!4)hl{iK$gdVPO+qg?hNb&KSkkW_}J^&AG*r(xu4Kq^K<|#httemzbkdN~$oILsh zjE6MK{l7-*B|OfK~I?JvcJKTe4>ZnV&M;(F~m5o!f>G?Y#~Zf==+V=F?u-14*VjM zD=2>1C&e{vhVB+3k~XRNJIX#*q%VJX8cm+X&jM-pZIul8aSr#0#qD7&CirxB`m!?* zPdY?v0RjNgJ9>tX9)6;C{8+zXgOvUg@mJ8S0{$1%fu!pZn0WB$sA%lV{?cx0>T-bi OtXZ{oW!swtd;bgM!WHQN literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/Nunchuck_acc.xcf b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/Nunchuck_acc.xcf new file mode 100644 index 0000000000000000000000000000000000000000..67f70139e0875a2809b0426fa2c7593f5c4d016e GIT binary patch literal 555803 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%0A*F<2$791gKw)aCuPv=EJGgJp&h48w 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 z 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

    aGYj-YEOf2)73qj9)FJc=~4bDfBa|9PA< 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

    2;HQXz>Ag3 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 X{_m)c(ADgFFyhhpkJ}xj94Yx1BJeLD literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/Wiring.xcf b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/Wiring.xcf new file mode 100644 index 0000000000000000000000000000000000000000..aa8078db8aac0bbdeccae9c2dcd00e957cecf685 GIT binary patch literal 1519579 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�rLxfY5<3B~3zkX@U_a>Uu5ob0rO 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øKg!VZNtlHh{K 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

      lQ^;UpjmI(9RdOZCgqa4Esk0fA~8e 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 Y5ySE4JTd{gfwEMNJ#oHycB6T&{ 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 Pqy68<&ePnPzkvN8$bLMq literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/fonts.xcf b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/fonts.xcf new file mode 100644 index 0000000000000000000000000000000000000000..d05d03fc7fea3d6c4f50843c26989892c1b55b01 GIT binary patch literal 33845 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/port.xcf b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/port.xcf new file mode 100644 index 0000000000000000000000000000000000000000..10fcd2de2fcdbf293a75be6407da1e8f4cfb87d8 GIT binary patch literal 33732 zcmeHQYiwM{b)LJsd@WyE%F>cFC6P3#7at}mN|Y!%q^&AK(#o6$OgE(h30z6or}CNo-lS z-#3rFbMM~ez9@;Z_DW~Y%$YOKJ7;Fj%(=_cv*+IGygYrX^EZcvhXtPR0KQ5Op5F(g z0FDD^J)rggNCZ4j0TPH?2fR`F1^G6BwiUSXG_oF;zHsi`%=tNlWn{~Ni!&$YW=?j# zGduTY=b^70eu**bBUjdoV{?d zbGt+X7f-)&qH}0)-@ZLVV|z#U4UY^D?b|iB8>Bs>!Dk<6!($`6NB0eljE>;{-r-%t zox?kj=Nl1uB8vYQefiQ`C#Gl5pGGLT{arht{R3~GpPlQRJwN^C%q8+)ICbjM%v|RX z*)6~F2ASDR>v8^91ybKrxb=X-T{jf&>s0v2A1eIH*AzbfV}&pOx58I6U4?|Ww%7Q8 z&Fkfxs(v0X;}Rn`(ZN#A4v4j@8JP{#`5cNDLw;j3+Vv1)_P)0V;<8Zx=ryu6_NT~ zjpq#`u;GO_en!!24=dd86NT6PiN?B&)FBlX!gYQq#wKb4&@$0;yGBH~<2?(Ym*uuC zBuAM?5RZ+c24zBOyj|v<8~392sqq5biC(lnmDiPhH-MU3&@#|7jP_-_3q5B*FUxH^ zlU!mRK|F?5l?$nbcA0l>+>6?$77B0&deQz=URUl2;#A0s6m;KI@T`p&W(Ff`_!=l+*`e9e=4sl`wk;v%z~Dso{!MJYAiuGj)VJGSIM4Bp`3pH`^_+9l_S8hg%1>TF^AC`{`Et^=$!Ym`H+>-%a0YevMo! z;>F~TWPBJO>t^Z*cjQ*Xu_6I^qrTa0f$a#kKK**@t)|zqUENzt>5sMrpy6H;l>Bab zsd<@P#p90U?xi4%EHx|_2?f?NcT0lpZe40xPJa}34+;k>Ln(0oeIzW=DW$wp(?nGf zt;T+-6u3W(ge5wqlviq+s4Ak>*y)r4_g_Q85}i`YD>Y426%Pt;skSs&M!I64)N)Em z7pfO_Ll8$FT<5Al*wPBd1~kpu?T+2jG;0?(wnW+x)@cKi6OuB}G(4nXQsy;;S=Yd% z%xMU7jDbm+Pe}Tli34HjaRxvNjxXodfndik{R(x(g8(YJe5hczNT08KQkkv#wb}DC zq;Ce;+OpB$7eQAV{M2=3U^I9peq1#8&rw(FY56lNU^H>9wYU7Iifh%{d+S&PFG%az zCwMmKGnDjCRk$^-F;BVhwDLqjK5pz^M9-b}lA-NRa-?1OuA6vGw1d_b;r8BX6UBq9 zAhY_Te;3nSGK0_%zS6Qn}&Q^Yf(mp^M39?q1kfs)zONg)RT4nlK z)+!Uy{S+!q^=kgM%UXHhD;s33%FadA#Eo4Q#lW;s|1cdEvNToCPG2}LPnGSpiR(^G z&8V4E=D$Rk^KoMG;5S|XejL}RPj#C#YWsC799pB=zOCZA-qHAa1TRQ!>=!&8-&A|Yi(J4D z0(#X-o?FfT^4n+6lE>akaT{gS{3ZC+7V6OVdGY-?ZlQjLdRtF-)P=iN^Sghj82i{x zJbi4ldCYbT;b(OG)|)DF>!QLtU)A_~8teR`FX#PZCM>9dW2eV8>^j(b1rE#5k}q6X zwlZ-1hgN>!!m^cXew&A$FRPB6eBGug9L-9M16hf23@fo$`o&JE7cGw>UFjD&rCzK& zigcx4+?0Be@+i{bqNd=jOEKG=wZ$7=A$heDUTZWhFf(hKXU`j?(X2#cc`1Xiyov$# zNDoTofzYKV!YIWD+`9zcLBaPfwMX8bJFBl=!bX!c_)~kat8#b2JqY(LJo9>XupOk0WJ~q>JYBg;0OoR zjeB-nS14SIG#f11vzDLb^&xD^s6m+BQw3-R)FUoTGu=jdA0UBxDxNqR>3O}fj-)fp zI>%vNTL-@b9P>Uyp9!RJ@B(skH3Z`CG06r=Vh5OHl5F~-7WL>tR9fPgw^5c)Rt5c` za3A>!z?FEtIs992c%Hbt+ zd69)QfRArcff{CZT{if6sP3<`irMx%5`#v?8Y-hJ%_%jNDe_6jRy5mDBl( zoce2RWj*D(T3JuIa8+SR%&f_eemz~tC#N(!(#9x`_Z()CQSl42V~u(LmV5VVVp8H0 z!_U220V$eGNbxhji~>t(6s4qDw#zB7q6}suse+M+dOuj>ttDeek?niX46G8`K2?HH3zAQcdG|=J z3lJSeWQA=`sCe~~w1L`QgJ?!~Z^V#jhGmx$Ns6Tp%Hqov*F>v#QoMi{z7Gv$Vu1}^~f*=aw}S*NmWuAWmk9@r%*Q0@ESiw4EmursI;Zn zU;^oWscYPe%>8MFY8SeNin%L(8~(w}j3c9{pDEQ|rblR3rmfzDOg9E%OcG@ZZsM3~ zqa-uq7Wk_5Tj6e3?R4)!O_Gh`Vp9bMunzL|L#rCBNAiSx6&`4O#rHihZ6JzEI$u+r zxHl-oU>st`a$-orgAKgV!I*sKF_nyG67Ax1sAXG_N^7(jHG_Q586K_xYyti=ZVS`K zysaRn)WGsO;ok+|fZM2xgu8w06ZM0G)kg$Pkyh!RyOXF*Y2SV2@5Dxw+`Rp(!^3?~8Gu{75K`te?x0K{CDdB)6l zm4sn@HI`aq?+u_o(#2P|h{n*x^!uof67DDalq{Sj7Z3f6OSuy$&SyX0xnj zhITDH*MHrhas$HB8NUhf!*CYMAPDuXA(BJc+|`Cd{fCf2eFj4zg$sH6@#6 zTFho?Ep@$o6()jR5u;8wj(DIkB-@J)a>XBjkGDxfGNWo}JZ!B>M@1}#bRC+;8Yo)3 z9Ae~CP3AyjJqc#8MaK%UO%81iZ>8#Sz?2IVRF$8}S7E+Z!b8O_>8;z)JIQ2rqSSDy*%?Wr z6sdWOJbkFHA3i5i$Q!rs@_Kdc=jq~$GBpExuu12XXf$w!shwBj)T~2GT>__Qv@l5E zN_rA&9((aordG3{s)0Sq zfL>(+lhYQwnxA|JzN@2Q5g%g=jy3+VH$eJWwkYGg^hX)5{{g%{h!mre5oYr`o#+h%%UHqnD2C^<<{1adM^f$Mkmjvw?OFniyH!%$g zPn){~I4MupT9G39j5&8H&*?9YGxcU0V)%ksel_aG@ddE*Rc$xExbbZ(>U&U1dy(IS zR=qSE{3Mh^m+(azx)eX_IeO9xnBl00?os{Yg2(?_@f`oB2wsqmeyHe2|3l&96B_@9 z#^*J@t*|w0?ICRZ1#4zJTs7N1YAibe#b{*PFijc_jCOZM=W?A%ECxF;X&Uv2I-=2u zc0d%2BGhI1X<@WkhmGdL$(g*Ipouw&6B|{>gsI}hfcpbIedPV^)2G2}Jzx7jD_}Z9=k==Qz5KU|=kh;C@PhQ} z*A@Nr_Z6O7R`{L&QTXyHjsH|(A$W;K!JiUef?&{imp3${Qe=6jm2JSw;k_CLyz=4= zqRdOOXKC!oiy;OcfE6!wQ1175!lEpEyF%fL74NE9@!sPlp0fG1%yMZ3KttZ#u}@)^ zjE*hCq&GUlD68HO=R+_=;&K&b*vrMjr-u!DDWA%yR~hzF^Q3mlMUPm;J0h%+k{;G_ z<2Z||$iK4quUPTZMq(ALgF}K8GUU%4Tao|FMl&q`w!v^k{&`|o+*dr6_5UG$#gkjY zE9*a2ZqBk)yOsLtuk-$gJ=yC&j>wTpsiCVY|8D$<_&e+J)xV%!$=6s?njaNi4vjlY zOZ7J;ltufyQqz4sM@b$M(Ic*8i`pw~C#HM~Agv_Z0Oy!`kZ zD%%zc$9O|tiyL>FPGy|tmcD^;t-cGFbA~$F;!fYUFRsP6t#$JBx(W0; zWC$BvZC_jqOjiGUn**7$<1+)KA z1CGwg7-_v&hh7XB8b6I@MHm{>#yaV92aSwtkj6JMrp<`?b^&^*CvUlwo$d}a=|@l#AxQVj6OthqeOh7^jewEAg0oi1{;ArrpH( z>$FnN`Ql8;`S=)*w###9I!|ERMY0Nu=Urchv;;Qqx z&LZpo~o;rZBy`FtWLD-aBr5z^3`SyWhK};;waS+^?{74KD)k-B$E(X$!$`{jm!F))kHa zO5-0ZjMw5EygPnB@q_?cdt>~&i6;cm+Q#wz#1jH?a&e~ax=oAsv0~i-{w{DMa6jXQ z?z;m?gA(=Hvs*B zMp;gl%@_wAse01jQ%=Fysh4Y<Q zlCj1AnSxHFF?lv=Klc?dY{y47^4SWP+bjFwUk6|^vRcozPY^I`u8zCjtr)KB_4fLo zTL}y=NY~%ce5W+Ntnu$?tk>=9H&s|}n}pjuZ2hqg{_zMm_9}L;{D{m4ye$#_!xDb{ Si_GvKpjYS28uL#(ivI`bxhlQ@ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/social.xcf b/Applications/Official/DEV_FW/source/xMasterX/wii_ec_anal/_images/GIMP/social.xcf new file mode 100644 index 0000000000000000000000000000000000000000..377eaa63b4b353787a0b77e70d46b84ffb8872d0 GIT binary patch literal 5041256 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

      $&8dDw~(p|HW8qi2}vN|OGyMK3VcZZ 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

      ZR8*;yw`G-3(kMFm>(u9e{;G!Au8Y${8=9Hu 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
      bskYig;_1fVKP=KBLI+GBNR^2<&XU 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�s-_DY-scbo2m)dt zDP0PRf`#3f*ok6cV2gnwcA=u!0e0RtNOw2qP=~J5L4%60-)j!s@qEAE_s9GF^WD#b z8}?p%_L?FkF;Jrex%(9n~|pEO|xMG)l_=-QBhS@8+sMzCYQ0I8ZeD& zZom3kBt^Z-+rHtr$3%ynGZ2Edv>h|rez?7(j+&;4wS$4CYG0Lps;Vk#di%Hyd3kK9 zz|+Rm#AvL45%uDcWKWVJ3wYjmGwYiziXf&F&vHoC<{u=82`uFS8 zSHmGFuaKS9^w`?S2#G=>~cOe!vn$l%Sju&}W-A7<@zF~KoNLv< zetmoQ!LG`ohIexdN(#Sy7kCY~8ew5g*R9maBmbwa#jndF^`pT{@W{X}rn;Dx}Zv87Izcgo(B9*&hhO^@sJ2Mk&>(Lg2 zafX=Mfc_eqDq4dFVQyc0&``a}fuZTqmuJ|RT1`9^mRVWbi^{cioV{S4m9d${So0x+ zHHp;KRQn@$#*CRWCK%Y54H*QvPaR`pYCiu_a!zqsT`wwcu;G}QD;zA$?W_z24^Y=q z?}z^l(wh7{Dfm@LrmMBS<`7*&3u{vwxA%#8oZ8IZ6k|ZXu9=n5U`+5D>S(HIsG*Mx z>~9#r4oUm=mYZyEJaDjqiJ7(i-cLz|MVTIbsC=~n+5>g__aB0}-JzOleO1&nG*wl` zJUz+g^sGJn_R{mZSb)K z-gHYHbmaKueO1y5jv{626n}2XzF@KW`BM2O7I#>W-Nvu4UbG^ z)8+lBA~aKfE%mC&Y6AxkHo@pT3~PH#x1^+9pEcalbn@-Uq})PQf2u^KPw&1es?bt3^+7|d zj=%f*{P{^6eFI%nOb=R_S}b}NnORm*t3j2j^zEyng02dA46?jZfQi{0kq=hY8Cu)h zo7o(G6_Ht<^+}T|$BKDE*G=iPRHcr3pS~*U1GLoos0^5NGrv3| z?yqc5dt3V@lV;xy&B!Y&9Y|H_4G@??npb0JYGJOe+DEm&_E5~;n^=)t zS##%%zYw0DS6;%v+C39DGp@Ct+%0nefs`zWiZg@nGf$yUHt=G z8592L)7Q5cfWoM{^GqU0(UC|&ON^Lj1NQ^8~y#q_dAOh`r|CQ zt|~FmChy+4hv(iD;aOa4Sg_CZDK1y`18vr1TT6SNt3bH>=Q<0sFa|9mb%oAvzo1PPwMICJCLQ-U@RjB^@4cHER1 z^E`Ip^>@L41(x9Px3ic09ul-NC_1){ z#rw`vX1aKp0c~D7dHGTg+B|*t8PMh!M<>UzV<%3YF=x*L%19^#+PvU%)%)(>X!FPk z6ynh2IL2}O#7T2^FTY+%S5yLSo;`Kh>neepuMRKUy*Fi@2E`c7aBOxOJ7MAV*KU-k zqMXeE-1ND0*82?Q^y1K(*-l%x9asTWimCH4j^ow`B}99-$!fEbfl6hb=a28%Ne6FT zGIfg6yjhE<%vb`viTpmJC++{9k`Vv+drn^J_YVYbUiI9%)o=5hvCb1_jdPqZVdk7* zf;SyTkDhxuItlA8zs`%j@#fT3f;aab*|l}U(#ike&G9prEm{dw=rCs8^MsU?WSmdC zFa5ONfo{C%x#P%*8594(n`0+Uo-qx?wfm?bzV&H*Wsl zcoPjUdBZjk`-dl#=cgn@hP?FsmFRcwpd4?W-LUldsWG-ac++XD)1*b)2;Pj2&CJWo zihF;>m7>1i^gVj^F17B^YWD?WH_e|ix(9ELaF{rGnnynHW^7b0o0Af;)eLwu&ELoS zARV=1=?rJ!O*=cB>`d^ciS<|;YlrPwz?)IgrG@b!Axz-Ss*4AY?W;Swe1g+x=Q;Ms zsn(4*tw&lJTbOMRtOeeTj7fSQdIO-Sl0LER8>CkFgtR_BY-fX>Mksr#th= z{b=CL@GtS_u6v&+c=No^I`3oqkhp22o$c_E3rCuE<4t38BO{%mW;=WXqGiCFZ!fSf zUGnjX1m3)Ne$C1Ao}*kwPDH}MiT~nFV+*4pI>zhv`uN9v2Hy0Z7Jci?Dc>i+o9chO zmmzREZrT#K7uLi7#hb81Izz1%t=V(@%Ijv}O+=ZW9zS{H0!8iGw`#4^lI>G*RQ9U> z!JC7I=?&I17~!&f?UsYS?*MGG#V-yV-{CpGa`mEVjw2^H+1Z#|+WimS)YcxPt8X!U z{u;OS9>*>}%!a20yt(t(<_o}^Q^${*?*zPQKFkt$)7X5tC31-(t+>{Jf%;|^o8n3< zi+^}|UkpqMBY5+ZhqwF9JF~}(wgVRU8*dsLTUnUs4ALH;p)p{fj-lDqn5@|7@ap^n zzE=a|S_$3^+j(f)xz!WLj&iW?!JBrYfHzG{4PmwiY7f%U1#u>Zrpnj zola4&v$w1{w9#qQu30ur%TtU)a=baxNk_GxzVUF~0a}BG>g!`2rOiH0X;fGUtMbxb z?@RZdMO0Jod{3@exNExQXxn8|aZ>W%c(Y$WyNq*B@qP>pWxjfxxe?E_r&M zJaaX(yjrw*-ehN6TMJWL04@NzfAOaJ0IW0A)f=&R$)=-goRMt~d)?eN?!f1g%Xzij zxf3RhBY4x?8i}q5-n20>Kpt1Ln)X286g$5kQITJ3p3EUrNbB9V9yszKx4fF)N{#Qq zn|8?OIdQDE`Vg{2PfHU>b>L7P9liaZKg1`zjuxz6ynF@nTO2s_oLx~-`!C*foM4OD zDUQt{5FWz+7I-20k0jioq zO)Y^Q1`kEnQUgPa9hv#b(U0S6wyt*Dvh%>j_`(uSS~uPtIeNUU!x(}$4S+ZGh7Hyn zGyu!Pb@hzQtY&^s$xckJeebqmtH*%{nXJO{jEQo*ImyY<&dk&XcyrLe{($=A1rz;rg}iJ3UWD7Zf340K921%yIg12TLm?n;opJ(XVemEp05~pM2xvyBDvc zS50;vHyx?wwrt;XExmxvsmn!xQwu{Kq_H;`GC%{n6}9zD^o`GbzxLtr`Shg8 zQ=MnIuG_kE*OMF;M~*icLkkBF9IBx?M1LsyA?h$#&rna#$^Wlc$andsX8DYni#KfB zaX2JDzofPTcvDAr2oAl~(AGCJ7zAR-Xee^TUrbGkez7gMcEyq<8+Yuvl9bOX5dm)^ zuj$~yTI$;R#s&ih4AR#hjG@HT)bmH|v&WCQU)QbO;<5KlL3U0)T>-plh$Y@bwEJrf z9ipu{$Ut9bkPd-1)9!^wv&%zwZrZwI|BJjVPDL*8CTE!5kRgKz0@5BZ$izb5c!aHm z%^2j)^GM6RzkZE}=h4u-ypoDy;7xOo4%F7rz}nkk!>qOiJiT$_$kZuQoF>j$w#m(X z>#2n7+%j%G@TLXgQ#ykIb9GIIS^7jjfAi=s&e<8$r%YMmzH6(;^OQ_>MfP97n^?0B z0S(oI^JVP(;qAL`f1Qhrn=y0da<^kAwm&Y&Dy}AY(+0&2Ges=H%*uS`vxu;7@4X|F zUFNLZcK)2lo79}*iYnmEv9@qdZS0X@a=7i(GvToxUpz=X98?lXz`CB^0Tz?)NM&Ym&e3VCSlMvk90`(V)5 zcbLxc^7DL_UsO~U4!pU@b;*KpBZiN#A3b?CmI2I~h11l1PVaeNSi~+aAb4}t>P54s zjkX^(X6oE|^IVVtaMiZ6M-GP+6qgiN0B>$`#gc{zj*!{B`8ami)otI!16R^nC6yJx zoB8alu#1&n6_m{cY)nlI^a(ifVFi$+ATzBv2e;lGKXmxifp>r5R#9Hu$5h)4r_ zhc9w*_k{N@k6kBEozB7ClB?eS-nUDEDNmi)v+vl^9Y^01yjjc#-mLaNe%i3Z{W?s#Ehyspf$eDdiUT6_y?k!Xs%?8PeK!P%u&yX4yB>(}_R%Y+ zZ==y$ZyaB`&fUY~;IYVMz?&M?MW2JK@%+)zv!`wW5w?1`uGz3@`>y>*t{lPZk6%8x znyx_6@0rKCF8br~s&(r(xNY5a!0TiH9-rEG>_jx){&8f_(KA;xsTMNrzQKK)=fUH* zY=JjVczSug#`E-(TlSvE>kXJ8ciV)_Ap4H^Z=wt;Du6eS?>oNhGHS4u}Ai$3wQVUxBzc@9N4mI;etusc++;2-ROxfvljyu0(E*{x^(&CxzpFq zCu4zwcL9h`ZpCcr#2&mkdF)6BsN_Tt&)stQ{MpNw&R@KEJ2T7Md&}ii5MOhfwP)Xm z1wD9k+?df0V^_L?c>n3s37;RGKYQ`)p4Ol2x8wA6IO4w{TpwNbs9Zxt{cId zzQ-N}N52j9-9MkA-d{Sf>-cqQ^*)@>ZRIj<;+VhVn+_A5vAz;`^T^?s(W$|2Tn&IX zV=nIV+(n0PUFhsI(Z%Gb)3V< zNwaOtM%Z@aO)EPaQwx*r&!xbdM|}PYdgptb;LT$j4sE(OW3=4_r%@JG##Xl7@l87; z6B9kX1sC4s0dF2X{_Xhb-AA&3H_sejy4Q32CJ8Y=7(fISvpFGaW0p8p^ zHu$pFAuoj3OVrv9&sn@<>8Pp8#*Z0mW;yEb_@Yx^J6X zvTUBSou$JFz-p@zE>p}649!M$$2SLP>04NjnX+a3{u9?8zX`9c1Kw3(3tnV0Kl zIFA`V%K zvk*xdF2|cpvno4BBs9fFKHb3sVXlqr#*cG;{_Ok--^i?6VId)@m;}k__`Gq~2JfX~ zfj5!ao5VLQY)9y-X=1;V&Vc^fg8>K}Cyd(a=i#|?&9=;E4?cbTmefSzo6d!C>sD?% zJAL-l;UoTzZ(7-zsB7ry4AM~78am8;xZ|YBV-EQpIDTZy#`Mp3KVo@$Y$8QHOIkJ0 zeX)(z_8Hb#Ln_Ccc4LOBtLqt>56~KFI()R_lv%SUZ~gw_{PCl2^Pj!=9Fy=hw2XRj z;^?C3ZjSoHt(Hz5-h($SjPNO4{XyD8O@=$zIXSx^x$?7wZ|{Or-(G+I=|^l4x0c$w zc;;BAal@=lEzNA~dhn)>&Y=Dp+WoclhgsVrx45md>-Oz#hpz?RyL9^I+mCNb_&olq zsS}*-?5&1b*#KhbVArf=!fgC(|fQnLoM5%3t?>cqj*wLt4o0wkb&-p(Hdi^}C zq@uD~OpO{j*1-yP*V@#?V(jPv{RUtrXQ&RgSLj(dI@#N9J-czwo`vUfc6wjDc;)`n z_fMm0D$A;YH%E;aX>DL=HPR6&(ua@I@2gH=wDyo;7B-_NjvqJD`;zCrg9~@0T|9Or z;Qr(1uL`*pW!2@tn+`c6N7*`>&Dv;hW94A44Gd^trlq0|9|sw=gKLc^|v#3 zpS*VW<@1+$?)rU&bcu(Ppqbe`%w?e_gwfdNrZ zj@*3l`fWr}Ru(6l;LX)DCXBSVH8C`|9Brkmi-_C+Z5;#SQDf|^MvR|2YuUniH{M0P zym;{X%eQZngjkaWygABg#@v}^*ihw&eK>=(`t=*2V_<3TFb)fbr;T5>ZR5fPOWnQC z-hTNsD4ktcSy2SMX=FTRI^vs~|qsDYN2HtLKM76$8@0N7YLdAP0KwR*(Klx+u(oD6vR{6zteQ&`3U-ZU{a z($mw@(9#*IJ5YOwp}CzCM)L6b0Vz?&m&5M>+OUz40JU}|q?Z8>7h zq`3=cpLlfl$@llC{Q{pqiLOe^=VZ(P-gL6FG|?ZTp*e8SP*car!>y4we%dPcH46^J zh6i1~^5p4DR#^^qUjuJCkG3__AEKpYU}Wh$-e%E>^LzH~Ub_Y7T^E2 zCFLZ(IcXfSSP#?FwH`fT`nb(!Hf~yWF#5`lT{{jyr5`;>D9T|~XMYCXoIZJ?(v`Rv^^ z{(jiDlYZAfe7hZ;mz$Sg2)ya$x?s`br7M?^lPu=BUAVk|+rHo)HE+_F#-?L{R*J`Cv)F0I+zuiVr9aCtUXEc)Pm`2kbGe%PMG$u_i>bb7NbuRwi zX-&~gC5oPd-;ZM2-r<{$B1KQfUl%Q@jv>W#rVh~B6#RY1lAo=78&3Hu9f93$yjt6JU z#;|+SolUd)48eo@G~MN{Nd0yI3trhObk|eu!C2dO93S;oq`GWdkio%g2t_X?Rm2VR zdfd3&A0&#(6g?VuKjZF*2HbtzpX!|b)(8;O0Q_e#vB+UwsRrHkQ9+IBaK=((u-2ws zN7J=TO3VKzl0?K{M`6bfuryPV`l*^j(-JM`Je)?uwZ;9NxQ~6tznI}P-5S(9knZHp zW~fpfb0N%=sD7X>5^Z=YsZhTM{h{f5SfNMz=+T{j0@V6azg3!P`ilZ?9W|i4!u5c> z`&7|%x)PY`WiYgHhZ_ z`i~Datqhlz&7O_8)Xrl3v8Ow_lFcY23+en5*q=$+(VZ>(mE>7NYG$Dhw)jYjnKJT) zban)(_d<@4&gKJ3y^#~7vt|x5hggv3<|-7J`4gnBN}1vLL8X3_Dcw~wSDiAUyOPcO zQ>YC}*Px8#Pvtp0YUT}~Ad4h(ZHh=KP;(#!0k#}c8bl2x?+&4K@YF(w8Z3W0lo|x_ z9#qn$Ab5OPkCK^O%nrVGF4Yq!-C6FuwsG06tr`?N_1&>4mL}K}Jj%+{5=Ix3=9U)Z z7zT61UqW7-4!9b8(Qv%atuu4o_B&}%t@Pt9c#4Vgv^P~sy~_WB>2wR?}D1|^A3^xqRB6y~g+Y!8M}PZY0c&}E2183xTH z9mKGiw|!U5J?LqqNfmtYy~Jr~Xl_nhG13AvTX>2T4hCdrCxnULP!mI=i(7}U-oF7( zS^m6l-T^foKbxCc1xXw1%&{Mplqw-xLCJnl#JCKN^h|b5^*Cs)N!2$5dWG}r+uNHP zo13JpZPsRrhQHBHs3g;%Q(sq)ssBsY&}6~B&6bd$EbGCUjJiKf0&!Dw{qN?QlcOxb z0$NpHPtmZ&zz`8dU43KoQAZbRP;Kk!n9BiW(w1MX%tl#Lb2GLx_ z2rRSF!(LWhJ!6Xr(;cB+IrNK@pK8Uj#>S@RmgdIBNJjtg)q~N%F~Mav-<4fqQF=HFH=4xPp|huhz)KcB+HEKDOb- zg`M%s7dQQEYm&CKwKddSoxUVo+Sb1~+a(2&X`T4uGsj)%yb|PLtstf=Xcr%lXjVwnj??+`z!|xmm=Zj?x zO>J$>Ep1KlD<_{XlD2iUH`e1X;X_kHGgE97);F=9FwQ{V%;DgB_=E{@=X}zI_4SR+ zCQfrpi}=;NX)k!qP3=FMWR1VuTC?4)^>Ks@8p3A$DC|CS*#B3&3YE!ydF)QLw4te~ zrKw)lAgl46wjo8**eq@BXv1p_-n~dM`k7_Rtx>Vr)CSW$~Zgz+R?xhK8o2_dE-YOE2h6WkdyE zxKa$2X>Mt1YHVuY1x zX7)$lpjy#we#L;^qa{I7kBNX{#; z>qVv0*#W1rg!o3IoYkgam)Xzj+rf7;ZZx-7A9r3HC2gy3`SrU&*8VH!T|`QH4hLb| z{ITq?fIF4qmiC{m4U*=zHu2rrizDkh{^pvaBh;m(xuLPO?BwK~dD52lc4kX+8@?R8dh(UBrq;GLW@~G6i!dgF z#b)JFUwTtTtzo_~I2%bOZD?%%+13!ZVe*aIR(z|ev8D4@GymS)+3)yZrL~pW(*CO~ zCNrDGD#pQeKSkBa0h!X~7N)EgBB}qnV)iQtqphW}iEv+ZYW9j~G-EqnYi(_3Md#-i z6cnbw9%b@s*@@A$EzM|+rl#skv)tpGn%Y`1aLzAu6Dr%>E{xCTV9QC- z7*(pGSuCi`FL)IvX=;w&H2Z#a1HKEQU+vApJJaWU;x@N4NnM-U>LN4C^Yij=qQBBV z>&i=WBhUY+{IG0Zcw@b+9<2Rp``K3MJ$ZeykQC6;*4)%wl*!I#Atw?>ZFUu>yfiiZ zp6Qm>4BZCLtu1W@F}a1gx$Kf5 zRH-E$lU9-a>G)fIQ+sPm#!lz6l`R-=NFQ!%$z+$Z^9wlTx>O}QiN#6$7WBDRDhpjR z>sEDRLw!94l;$>RLTV8_kun3SDlsmr6tRuK4D9myE)4v7!Tl<(6(yOK z!Y;~6fBK|S($HR>oKwKzlvUbLvYgDc{Nl`KfrV0b8mF|du(EtO)i@=ARmjeH_aZTw z#VIZ>7)iC{(end*Wj;?b4I$u3HWQyvXRZhu(WOt=q75?XSv2mO_lnK? zUhTBKadyM%Lwm;o>~Q069NxNi^=1#xb=Y*Z)OFc%oMZ^_?<&O$OYGj<-LUn>wW;2> zCu}&pv=7u&l>7PoZuj-;-FEFb=S=r3Qf5?fxDFI%=8-*R1M?G+L9WY;|ZD~om? zpMml@xlg^ex^3LDV=uz|Yw*JARm_!LYgQ|*Y+SW$xwYNSE33CZII!%9rvqU={`SEw zYu9bszGuTS6pr0bsOu_hky?en)?$00t&QcF^S4%Q+rI!^rv4{C{6cVq$A-1rJl5in zFd`Y{HTA1kt-;R2HYcLGWzOnz&L=fVZ9%Lp4QnX4JAq-4hdwnAVZ!BW@7xAr-# z^V)=hOWdNbe5mHu2n1YV_AZx&uFDiwwyj#ddd(^@yk;eHO&j)vEnazO_HHj*O{%W_ z?b&1jkH_Wl5pXIwG7r1YaJD4&pJ5*ub9FPSxx#hv;*}eg9NK0LXz`~Y=xULmnk(Sd z)be>kfuGC5B{->a74~*1uW3U?7U2*i&yzqo+)Z@$-A7e8g{_`T*R1nAJQk3sfc|(fm?z|MxlEpvTPH}{G5=CU?X3k%uo(_=Mupp! zFLhnCe69P@BkssF@Qd}}e7Z;|K-pX_U&#Nkdf~HbfuQEWf<;SQm#tcbIxJnfc;U*m zTTdR`yd4lHEAiUhQbBEP9gkO6#}(AwT(mA)z^~&Ad2g2Eon_dIv25|eMJw0uKIyS} z`z{Qb`$eC9UkN0<>Z)2EzqU@4zklJOTnU#a5DG-%uPYZWneV!ksPW46dr!J=+P32? zAWmyipl^&oDCAaGlb6Iv8|PlD5}`g)F;^gzd~ziRWG-6dx@ObCgKk?qc0Wo}rCM`S zub$77i1=I{kI60N3*Rnx{mA8u1U!*c%tIp{#@^nAixw?gyY#|8Ro51~C-H>>0h$qFl!mTzITx~N(ZUsLJ-oK#IMU-^vRTD|IPot| zeC6`%YHPWu6JL^lz~xktfG>aw@cGrex`(S41=aFd$5*V`dC1*;^N!P@IUJ4%5T`8b zws)FP$g8QT-jYn zmsiJwmT)1)uj>~+su7a6m?Cgma(da8gt}TjzY0w$5T(9PVCUtQ)&Lq!tWACVu(FO@ zQ(MF5)>ZR)cU?EcKo&ePB*PO(vOVS>W`Q9Ao(hC@5iz;!oOA^L((38tTi@`-YVyT8 zt}x%nWq+9&6kF(pLd;um$=Y6zPKvnM}9#*i~81^64A*w(}k#eEtI*sMwaF= z`(_0+LBK%UDERZv)1lu8f|mtVg?w@H!DV+V#UfHHmn)F)@2^<)wVF@*JQx%fgrt?Q^73z} zQ4O6U%=qVLK1$?$-?1))h@uAl31sExTsNjdae3fCD3N9-YAvb|`&G+WS+@?d(JP@AU_mU7+_>~M z2jdCpc0x&YR0=Zj6qWeoQ%9& zR#x)skjf9+HvQm>F#_>LBC)hIJ_oIr&#^V6niJx3N^;YlU)gy$6A}?M^93SFBP*t; zIGQ=ipXF zIRH*(QDs5a$M@A30=Tlu$fSaz!ty!*oTY3|RWa+YcNIcmePMhS08VK+08U<7K}8Y! z`}=ZPUUE@cad8y@PV4kkR(WxL_~*0~7PEvd2EfT>m2rxq;tNX4O4)LNQ-XYl<>i%C za)47@Q&Wiyl?31vSJYJ2O#r}|>vezsin$jy%wIfz;l+2D``!hFK-Wb*d-w6t?YmF! z+_*_LQ2AYDUJ?3T_q*a3F#Fa%SA?4Py0|^~9O!!(|N5`jw=olN{pvM8?9Rf* zE~U%Tix)0moO@&Ul*t~4=3joj=Fr*YfH!rmW%2JHKYVyU;QsxqSFZW{-|)YA>(&i0 zb?y2!reD+5IlBXn99z5Q`Q1&vm*#0u{L+$;2QMGpxauEt-|yP>8#iwT+`b)fE8x~m zrhokne}6x}`7T?JV?)~6E$6%dw_53>hXFxPZePFt;0DvL<2p!gG6RIS?%c+y#{Q`O zwX47oOYT42<9)&v*&0ND1aW>52|nkqJ$Z2H!gYKB4BZS+x?O(@zxexKzp`+%--p}o zCyyFKlI5Haewo#UF~|JwUOju>|0c>~-u!thAmDbu?K=U?n=Sq~{I2Z!djHV2%g0SL zDQV90yV?242}#MvPT@S)o2ab6;w>p??*s(glsCnd*JoT0p56$lm+XxX2rfwr35|$J zi$8YA_o5$I@xO)Y-ntcV=k_ha%(ZKmubT}k0Y zpaCGibjAPf(;I}FO*H$(^MaJH_^3!^@%fRI?CW;w_EF!9{?{*G3AlI1{~B7E%(CCS z{rcks&`ar%%ShOol#mu19uXIx@_qkyzpR40`_Ep#b^YoM?As&ET)A+`@5alQ_XyzO zf4UZ%6Can75tk4f7M1&E>!x@4F=4THJEVN?&(x^$!=muJe-&nA zq@^W9g@u2Kj6SsPU}#Q!C{AGh5&d)zwm@HEUT8gk>H3YwpC3MX@%#$_51sbjFRVB# zE+H{FAu1|9@s<0gYbjCDapA$?Nk2kZ!QNLcpFMr{{1yK@FP`6f{_=5nnJSf4SN`g5 z7Aqk-F)lJ9Iw2|H$qx4ySs7`uKOz%if7@ceOLB0D_= zfG0it`e#mdd~AGdY)W!eV*JtNr!sPrVxnW?q9cQ&aPIiUz`q^^1wDD4 zRaDI4BE(Y3dK!?Dlbx27i0oFW87Yr8xdjxklVX_B+{F0MA5p$Lb_Zww2un%3dGGy$ zdx1~Bmca2U>rMSC$_;#2keS3xE{Kf^i%878w`#-p!tA6d+;vQ1)(emIL7a?Ov`j>JWI|^8 z3AgPbDWRW3LPNiNi%WieKQui(mn^JHpDba$c*sgmO^A*R508(ENV@5<<4bx|Fv{EgiLNrn4V@FGj-Oc<5MYM0&ze*Zm185onm` zsPNdt^dR@O*HaThzJ&&V3l52my!$*kB{h|Lhgcb%c`vOZH#ajiB`z{1IwkDH=1VaN z;Xk5Crn2zp6u&iYLAi1#;hx4`c);FUlgo`mxzlZB<%DM@iLNkv}|Zh4cJ z7#b2D8I9~|N#74|+8r7n6&>;Y^QX@tF|UIXGLXY9Rt|Z1Re3n2J2nB@oyvN!{j9rB zT2^9wTtad}ct~W*-7W6dqoSbpcqKL^`bk)7P9D3QU>v;xU3gYfUc|ADcW`uh zQbKGzG$Ag_-+gUROk8|;OjPLiu(*&XKeDp2+5YfQ+NukSN?DnY!&x7^_k7CBNQ_HN zNQ{q9PL4jY`{1V^(TVXBN$gC59)B(h56YT4}&gTiOb4LBSURMTuM&Z zPPdCG$)OR6iP14(QISvHW~QX47nEsHZS1Vv>Xi8R{+Zd#%-Zy{)a1B?+>bkUJV2JW z$hf4~(6E@$haV$SGO`PRd5SZ0*x7}zzh$Lmq^GB*revhv*tPFtPA24+k{lBf{pnFc z23SecK~QG|9i3a2lKeI_H#H?SIUTt~w;zaNCr3xdr==&y#l3kHo|&GJnTw!~DV>v^ z9M295%S=y7DTq3<%{M+LH9j;VITPP_9+r}tQ&7Y~P^Ubls4Oir{3}i;`*L{CqqLNy zn5g(@EKrGi{5d-jZA4mj zK|v`n4|dX36cr`CO;69sh7ee3uOpJP^EidTJjq$bWhI~Prevol$E3$T|CS24QUlC0 zKP8J@P!jSoEh91c%d60|JU}>Lp2YCnnwo<5PttNfeMn*F=9QNss531iyC^?D>_y1e zgnUju3z#P@n^VO85uU}$FC;-76jfN5S6EnF1kB@@mRrn0w5JG|M?IU(DXti2N||6A z_MMJFv@zx}52Z0dJotU5E{$aOWAgNAT|C|>HK2!5o&9e7 zGNg5=F5}2y^bo3RR+TY52pht^noQ_{ROf(Ke@tm@%z|c{(^}Z^y-H+3Yf_zkFa5Hl zHKXa4IJ8Q|VF7hGHoFt?AuE>S1cmzD4mmZpSa+ExfTHDy z5`LXuONyQk0tK%Y{F-8^LUpa^E?5h{+KKR1>k%bzao`UQDX5zd4wX*)CbOGXn9x=5 zY$sEV&$Lh>#)f80ine(vp{@(1#&l<`3u6$~HH~LPccofGJdTz6bZ6%?EnQ4q7h-m? z?XWUrX_&49e&;iAG=NUjV6ba#jLLuN8i0yE)52c&e$P8KL42r}IcDf@|LKpJ-uVpd zjaNGJTaA$0fQ|h>RpjK@QO|U5?L*4$We1j)H1wi7c`giWz-P=9V!k`wY7EsizKRJ( zo@+T#zeg0)ZC<^`QGbkMT$pAQ-wab9CWEyG>S4YPtAx!bxs3JsD>k>FT%Qski>j&F zAWe-SLop|2VK!stWdG23Br`Rjg!%@UJshI0K2Xod)Y5+5*d>8s3E5>8h7`jgcQBq!O70)nsMqJYkrz<&<-uld|&iEvaUk>7$HHt>y;?r)1}|tf)&?fl zbN!;zv+``HHfv)OJI|M4S@{{ZRJ)Oh!@l=XS$P%1sh`HvFT6=$mvKf=zZc&5n#wM* zr+z;OPs=asWl#M{$jB)~u7k{i5(li0%^ywCGklb3iobG!%e*%MabZe{0Ubb&NixGq|-aMAMh`wnmOK+4$M zth|C^NK?9O(E^vnOShl%-mr1gk%-J}?1G0hkr-{|x{ap}Y;yNF9*KIFR708z7q8s7 z>-6^RTee-p$XHYWX)ap5VW01oP22W7&&XvL*FlbpZnGw z=aRGXatjI}O`n}unC}~j)U*YV=4N*f&qoPqxdrKv<`$3rftl$!a%t{7^*t%Kpr{Da zJRO&f<`E?qoxGx)E7$BzOr8I@OD1ZiHrc=7tJfR7Izy?gN}qcA6@m`L-|h0Fd= zemuGT^i6Ozs9(!6->`jan@p1gPxRfK7t3P|(T?T_#8+za}i0Y|ko7t*}_{q5t& z_urKi=A>p9L7MLagI)%{VZ~;0iXqLQz@SIrNO6{13TeK49vE4k$I6FpcE0$K!(?}{ ziXqL{CB;aE1!<-hB29%dq{+_DD}XffOG}AvmO+}+h%~jaoWat7(!xLxsA))%5oW)# z5v74)YYt-=)gLP*EKMjij4FYerc^(Sg8O@!QK}fK<}l4Etb|Fiu%s~1bOvc!QCKk3 zdO+El!eGOl!?dB4G2&Sa$59`hf1YZNpcKej31vG9qYig26FgzqG6zq8o@s!m!^+@^ z;nT~J!haL+GmiX%15WI4nh3J3QVjg`S#ZeHog9Ngp6HQ(@Sie%$Z;SvevHWP|Nk9* zg0EAIN%-gg>(M7z6C*$Vgw%&r_}~Bf=pO#}kAH+h=pYu|ukvfZp=Wxo*L$uHd#kr_sehf8QuMUpJiCij{o{>4(q=9T<*R;NbA17FzLBE^jxR+T$grVQ(typ zdA9OvU&X@itM0z;>xBC5>vH$*>z1hQ>ml{-tFLpba`> z?_+u7d7sbX)he@>%zlz9zr+(>dRBz0-5;=DXiea*Pg6^BFp{=W5+^ z9p7`E*K=LdbKTic;ja0^zD##f1 ziZX_f7GtGTr~Fx$MA}QDF8w1B2*rcwj!v0ODpi*B6{|}ANQFZ20J`HRUX?I$Qw29W z#R73ZS`iD=6eV3^NiQ)|!W7dIC9wjoiV}vnOCaorkJCb?gvJN@{ttn&q)W)_M|X9# zC`o#Y8S)=RP;`hT5`-v)e-JKaPLNO755Mk%qS|vhQDUm4Pvtkib+<}i1#%V;1l>`jF zfNO{t=`0eFg2P8VUM~@iu8BhL}cO>O~T9T`3#u z3`+1?bv33?z&sw~BjAQ1R1`5lu8JQ;e6o>WQ;@@gfhW{ebv5`#{Z9ym%peGuLI#@m z4@4=|AjM0Vq6T42B`Y&02dJf_ys|XL4=;%1QWSK8Zv`oooal@?DpV&yM4n$!hME5y zWSHlaXPjNRh)7Z_5fbT0Wy(-%Rf!@h%MdaIHN3LYtn~Ektek@UH%nYLy@GZlq%B6f zq3xtfAXXtdDkm23N;z5Z1T)!jUM};_u&^qU3%N-oeLzS{6~He;qKq0Upk!HXX>nS3 zcy!{Y<@1(3E-NpiX$2^Wva~lyl+f}Fw7RUeq$u*QzrF`8nY%Wmq_m=vrkUbiAX0`# zDay-X@ayYJ3%<4|Dlocd9|f^G4Y8H=WY0!TUds3YVa`y zbaf@jL;?MQDN+(DU?PN9SDKfc7=LQX(|9%xh^nlDfYC@`87&EYkTT>#SCYTLgl?i5 zxdUl{KWiz0bJYHp1VrCr(h+1Be$-$F6rsFxb)mYhze~2?M3zem$o-bR^l_c zO|{&zr102OgkVZBdJ%H3y2K(S6i9l3qOgk(K{0p?l=!>0JUuuG9FjhP zfdDljRFEoKih*e)LdM|zuB)jjjzL)}qF(YgQWJIYK%>}QP~ER8nUu)6PtW82J`a5;PIfZ>Crs6v~3GhI%4kG=lJ#e6SItyW%@gIMiE!x~K>lvThOx6m{wlVy>u% zM1{1lj3}G}>aQT^5`r(Hi>mkpL#&KaX}M~3$Sc@Q)GCzEIb$kJ^dC9~X|IY7ArSF31SO1~JlNgy~_F(q)xfJ_;Z&f02p*luDx<|%Mn$!s|$6Zx3oL-&(YGSLUfV2FXDnv7a_ zp`8d0vwK3GB9wx`?ZgXAyr78U6!Fsky=8|XCjb9`T6TS6fja8znX;eIVL1g;#;jLp zP^j-j+jrY_nE5VQeJ`1M{T~_h;UBv$>nl~2{iz2X4l4Z3lwsJAD$7)Gvr{S(YtafI zKxtB1rUb0OlmaVAp>8lUpv5Qu_o=e1ODs^M={6-WCz+Nf~+hMB2WOZdjAFPg7 z1RpAL-e5W)`98uHd`2S0Dl=3|2qy(a^^z*dnu%IDSY}Np)DSit)lncL zwh*13APTUpAZd`w1T`fXQp+om@QN zuPmRao6#JL@q+uaWGO3EJ^f49o4CmNnoq1Dso`KVev~V zv(B$xLTVtDiHU6L8sxn2ny{!@ndn`D1ZWsJ*!C}3nXfiZgy%LC3h*F}@VYa@< zf@c>b9O<#(e1d{yeLzUp1LcBsWzYyPrv=sP8YeFRe z^@-$_>B1iSDA)j7$q;{jm^ zSyfh7RTD4<2nwwsXt)m<@dKZvYx{pMxM#gpt8P2iT z2Nu5;c04Ey=DxJNx<=m3po>gNCy*Apj_%s3DbSYn8NVxYnZ0B3|SAyos9y+l1moH!>K!Gweaf+s4@1Yjlx21dL$ z$^ia=cSo9m49KXf2#TR1#veq2sAva<4QbC~6+HPRB%?JHnJ|TM4HlAM42derW&psV zNTN`J9_uZql3Q=643y(PbPV!^zpXduNWUTwhyXV^nt-E81MdD~yZ@p21<*;5z`s-~ zlHWa+8!{nvl3Q+qHhT;)@n+x#D1k!;u=p>LL;}-|T6B{Go$`LdyW(Mm5mp0rLgmow zKJxmF0lIu-gs|FOjQaZxi9_;%?>SB!L3fXLa^9)%tSRX zy2!g8(OjrBOty%aapGS5_pvg(EIx6-Ta_R+A~^;s2@^<$2K3lJ#CwCy=HWYv|DotW z?;^O4Dfk0x+W?#0DS@q#Dam_1J})DsD0MrS%7S*%oHDEfuZPVRD}oUfId?!P(Dpup z7JNo5ku@}+S_0T?6x9pO(@fN!XgG1=;UBlaT0%-#LWMpBn_USbgAc+0!ht;l7gB~02n;=t}c1i8IUye8{Y-QM^h^R475Va#S(#tS5sZBP{XLBYhkp} zSDDf-35-82=mVYo4JPn{lAsm5!ZXIYrphX2bthKc!DypCa!*mvA9#VpFU0674H7B8 zn!~~|yEq598id4Xqf|MR=_`b$5g#79ijNUBAfAe(9)SmLX+A5jxD;<;i6u-ud5TXE zJPi0qjDRYBNPMMHP)m$EAgm4g4fYHXNsf=;4 z7sjG)Z(jx$v9 zhS==;KT_e4*ypaF&zg)-%_Gh(dC(61o3 zL`s4>c=X)lpf53L*-(LU7#g$^@%O~UZu~>s8~iE>n7pPsUP(e|baED}umt8^?tH@n zVbCIolh{m%pc6bWxy?B3H#R&TK7E7S{f2`e6!($zL*0o(N#b(dgpAtus>+42c+S3`5%l) z0Ro8_6`gRnyZe-4cLN|~LJI2*5C`xj?vOj%e^Wr1WC1P)(*Kgk9c=q>?x0@}pL0Ig|)2_(n{zDHxzpDsPRUH%stV-erL4@00V1mM8_%6bV5 zcQg7C9+EMM#M2O=CY~Wf@C#QN3LZ@V7Q*QfL)QJEIts$yB4YV!2OzlDDK}!MA$dZ8 z(r+;_c-5NpPohg?q|lc16)~iph}~$=zsOBk>VXI&bs!|o=kSdV?cRoOy>!DW$pjFAk~t(9}BSRAXan5U$Oe_}mDW;d7ueS(KzQC+pN z(Lr1-6;I`uR>J8yi{9^F&#s_mF6=&ceL=fmDW9{l(*+g_$~vD;gaea4Z@b+F?rdhO zA|#+~?{ck*LQls+lbl6$nH#fzV!$9HJx$q>`e)bK)e#K{{bVdSF*?+L;WlSk5^}wz z)mXtu?HK1)Wkxd>4^I-gboR^%9>0|@Nq>9T>)Jz@VxVZ{R6ODz8@hP*%sNT95a?B4FR3pD}B$xu*ez6@haj`9%Yyd z9yxd_f#$B)FZViDZke#Oyyz}z8n&sXr1cx2G(&};C z+4)QoKmz||7hFIpSB4#lF41ska@;$_A@WBL?c2Tg=x898&Op7PpBhzMDexc*8O8z= zZl_#HSHg-BnN9M7m*6MPg+Fp|=k`6@cJ4iR{E|N!k7iIN5J5vLw&`kR7Sf3bM=?!W zepg_Gv;fXQ9USNH<1Lsa2*|%%!i_bm%01jl+0wU%;j{ZIQaZu{=5HhB9<+(8JtHtn8L8$=DFjC_HN(&((^xh zoO4N@+O*@LuYBX1FYev7bMK*}$IcFp1){tmG-&p#pZxBrbRwREeLc^vpUcpn5vc#3 zom*ah{+Xwr{LynS?>hhdmp^*{*PqyPW7ZtY{&uYsr{84`_0f@+pyoIsP(Vz3l zn8h>44sm+SOV3%)mS5bmZ!#75;V1s>C%^jC+0*@(M#g}Zshpj^ngI(j746=xqCaPz zpCxeN)X{@`c5Z#;#Z521y#3%*f5itp2}gMQR&fEsMp-n5erLy@ zguQ3>L%RFfQ;dG+7T)*16TV0yjo1%;<1?T8tfD4`%#ugNh?Gzw@IWRUYCP8W;IYzF9mQ2HGh1?fB6FUi2zttw zWEYfT$hYniuolPRrN_pLH0Pp4J$Wv-Ht!VFTq$!|C|#Cl4^}@fyqFw(qEc$q$Z5=F zWq#e**rg5yyt??ia5of_m$p=jRdziD1`3q7hDltoxmquc?D85UfJ~Zr|3%3X+f*tS zj6uW}*6?*N&1~pk3(lpOEjQUSr)C?qV$K_gCRsQ%v5IoHlors4fE|1cHXv+KoZS>m zq^o|lO0o4w3}tJqUJ#_g*9P|DY!#V}TfWh>OzSJ-C;EJ-7o0xjI}N#_omU)Gt-huy z7OXLyOP)V7>Q82vYetOg3S7pP>T1l26NgrZhHK(m@HA%XsHDmB1O8YFSrt(ZZpX^1 zU6qXvFri8Vo90@$UG4BiSAHSjg{8~@?eGfWF%vwhTJ?FbM~#c#*jyeuCfZ$)0bm!q z5sEnmgiXMp8Wvzp*Ivhkoyt0{q{jw|33>Bxkw=%4fhOx4i&KI~rWFWP@Il@X?ar{? z%?*4H(63Z((_YAY_2>gp%y-KNf-g%S!>X7a{cbSIdU^cn@4!gackcQ-`3=ve*{9zQ z>Htzr>2FP&zH=IPwg*(Nzl}e8oLL}gi+{^Yl<@FeULqHMxpl8Wq##Vq0{>jo-7~If zXJ!?VUQ{p#Y^kiz>I|}Eo={2eLZpJk43KY`f6aoYx*$5`@^s^8oCQcioFInVlCgo8 zMF9)0iqK=TIRhYF0gy^mZo?X}tBZOYQ#s*LSzB;W`W#(WlV_v~7;W<#R{hP5-kNKw zjYZ|$r~O-?c9t4sk6nkN@@I&;h8CCChmm!ls64K`D8}xd!q>z1YwK4Lvz!)h8;LgN zf!(+FoMkwMKR*dBm$owBc&vgkiuN^-{YVv$%M&@eG)-gG7mt;R)mqv$@6$ z9-nk9TL!+hktisXvC&5IXBn~bAU9T%M{QIKY-8-?tj}vmbjmgDn({P}Y7ZUDdMN^f z8P*IlP$}l5tU;o@e;(PRH`#PgEf_ya5&bb;5@N4birG}OjYSEJkSVf(+qc;Q2y0%i zHFcS=5fC-#XUyvbjtblw$)E0-ai(nqMUUlTDQbv-VRpFT{{GuU_R&<}nl@@{HCLu* z_*s>(1B=^$RQuVvvj&hBSv*KC&$PBP43-TFOK>wV2JSg^>MVhQGuqR%9w4M}nAr7l z2V;Z3{Q;n>l7&*!29-9d*oD%+pwg5Ahd|=16JzIC~IdF8~wWyS?R&F749hE-+Q=n3|KK3_$f+_!7 zP-&ihHIo9Ee~({t3UparxJNwJQZN2V5ubJwWxIG!(aW=Z@s*K&+h$4j&)F}(x{91 zuYLM^r?aVK0k6V&Sv`zExcD`wba(#?U-`8MzVYO~V<*UmGpIBVVknmW_##FJ;MfE{ z)XC%(GJhQ^-5g{`>x5Gt6u_ z3WR5}JE%0@W)fZHNkQ_PQ7O}X;M905l_j(cRQmbPZ5a=QLQyl5bA3U^tsiKGs2{+AKh&28D^Wa@UJeATo)fLG>n+>iE$kN6wGOl2*o* zKPU8-?4VL`B?PxYeiT~(uZbs-`r`s<0?OEUM+Sv!&->+M6oMkEuaND)(wS)}=&}GF zoDkhXfF{lYR$s3!hFv%|N&-~W44N!xVNylzWX8X9-$TP0q5!xVet00Us{rT_fgVzB zcNWV|tb7WHY32pED98w6EEU4Xzwv6eJ`IOxdb$e^0Lu;A#CP04@RbQRsI*)`8S!>e za{$c?4;`;eW6VQ0m?7ugNS(*TnmC1?JgzPSV%)Tb=SU4bK2fH*ve)(Kg~HmR1DT}g z!B!zpND(lzr;3gxq98r|WUYdOM1-u6=8cUFT!ICqu?0#ir-!yz%b=GMGlz*HIFAi! zbG2R?2}D}rS&{<-k|s8-Od*`W+AXc&>t34K@UT{Wp<2#YXMm5>v&}}i;0?snEFGFy zW%&^+Fj~A^h%7dQHH}5+1*(#<<4s+ypBfCr64WVGz19-?QWh;aLKu82gi?UOu zHMsP`ctn@3R`29e+K#OzTpc)U%?ulDcXK+Q>_6uVrgO|SBd)K9hu8M%YR;;#*%VdT z08=wI*PEF_DFylmg9$*ayqzxiDZ&aGS3y^Du}xE0%9&oQ#yiuQx3qo36c%3p-G9s0kh$L?)Vve~Uai zIM+>+_07fU2GORbmFP6U1W=)+P1>Qw2EGSs*B}D%2rwZ%`TzoQ`tIfmAFnqb+f%(} zW4~KSSIpho&1KUUapj>w}U_cSkwAj)28p7=AG>UO-;RxKd9O1Fk5>8xEWg!hEybv36DWkkpc%fku=B>sN~bJ1W?%QfD>beCIt;kl;C7#9+n06 z#EzyDY4(jO)Fuqjgke-A2$H#OR^oynA+Hnp#sU zO|8W$vLMfFshCMdf&j#GCypP{Gzlv(O&+}C?O`aiOUMIYJR-<>aoSj{ie<4( zs6&}Xu(`qqljB1d#M>Ms9#n*By@LKU&V$}cO45KvC%{w4G&JcO?mv6{(5@XvBB;hT zVVYm&TXrS~%hkaujl)gAXhN@oO#N`57tS6(uzUB`6Y>0w&@?xniO1kt(pfyv88{9I z);M%XIN*m)8MttoJmVc(w-dZ`Ghs^eg>(u#A`-U~uDB~^MPfm}cuxTKIc~Lg+vXjw zY~8j0C}BU*NLsr}hcKn91=}iEVZ8Jak~|mMuH? z9lPX@g@QnvRl-zzECpypy+D+M3dNQkJ$wMR@6}DuJoVT=e(zg<`<(|Ld*$HK!#g)` z-n#qH=^=uLt@w0@FolIia+4VN$vojWAQM17WaEy_FFfl)_DK#v ze(ax~-~NLy|H>`0m3;PoKGPNrb7wnhM1~x)_be5?CkFVK8U(H`w~Z zsUrt=@7%KK8SClt3$N~-Ncw;H8=v^iuRcj;{ly^>rhv;r2b!W?)Z10^8(~F4rg&oHnj05_!Vd&t%3;m@=T09#yl)q?jkrui=%35x0*^fK z**0M+GyyaPz9D-G__wNAB5$}oeEaz5;Dx@^#~|$Y>^*R7Boc>LwQ{qWgb358#wX(1 zE}Rq|0&$kW2X_sFQ>>$q;rQslg>$D)9D$xc>y0L?v@3TG`OXTOesce*u_*#=R_Q|k z9a4v3F6Ae?Dj7$5M+PsRKXc;P*>Mwyfg=HSvLMFvf$y9OO*iqGm)h(jV+R+4CD_F# z%;*hc>m7kIjTqRDfYHXVl9};uf9k=(BpVqwBih73Op#r4iL_f-2 zG^i6YxR?(e`})hNN)uFI{ZwCD&f3UlIz5+P`ndue17(G7yF zmJ$~)N}5E|4*<5d?fn_t%cM%+o zv>IgGZNT$Y02aZm)Tp)CI@h-8Nf+S;xt!nUk8*#Zcf~mfC;Cp$^>*n3y%qq08J|=qH?Cf^~SxCL8x*P9+pwoBm z#yk0qpcG>fyd4Mvz-sDm&78h-rtWMHsL^;Ef6AHv&7Lk06WMPNn3b^A`q$1vngG=D zGQZ8|v51(`^2eMxxfXys<#OOx9pwouAeO~irSvO~EfSd;bvfc!uKuzktBD9sWF@T< zUab#1P*0^<%s^(2Vrq!bha82gh|pgsXHyujl@FLt6#0flUr6Q97mfGnQWyhtwB!Aj%h);n-FJLQeMw^B8qE&@J? zMIg+wnC^tP^x~3Pz#+pMt^T~zBnFKNdeS_yTl4bRlrb5V%~eR1kS71#`0^K7a;$7C zdzty69V$W(sD=co0JRA0Z8YBEz`Is6a=p@&T(X>Pyd%nB)2yLgQj{qxE#K)}DWODC ze89ylJe962kr!k+$V9eH8eO@ZVeabn*6j|l3*}t9Y#tg4-Ild8c!w;4=rPDKa?LA1 zQqc#Lj;rSZlJ%>^66jsZ-Lr&SD^I6c>~u6++g7(3)tq!U6J2RsUF#5RgQ8&l$z`JO zI@8CMcCy{v$HTJ{3s}gM0iA1j(t0^Vc!BZ)O{634b1Sn*&K(4ageH5=grFtnywa#vm~1p)5!PXajl|||gk)AroL9e;N+z>8x7LaFBI8mjHmhYkg<2Hm zGrqo7kmI~c@PB=hPmZ`aBnqNVGm1s}=00EaRw)Olhp0d2&p&Wzmd@IWrOKG_( zJ(&Af+cS+%xjS=(SCP#yrL=VCx`_`U><&+zhiLDs6_7_N39-Zdu+U1VZZ;b$4+7_c zb8PIi&9b$5Fz2jlzJhC)LU746qx{t8T2!@klo-H)HX;O6xnSt$t0l89gP4rjnb` zC_D{e$EAz{nNe*l-AV?6hd4r_duYa+6LvAq!0J5np1rQwq|6Bq&TEMh5Rd%IUx=?B zY*e~gvl+Nl2I`?XR**4wQIlqyydtLlCd~$mDsW|F76}9AaA9c=_G&Zz^6g$%Y%Jb% zS!@Tf#}K0mOrFh1feW~yABBJBz&x+jYlIf*r4Sl!`j8l$@8&Mr!WUPyniM4zH!fiC ziFgTQZBh7<@Dnl)wK=$Ot(e!3_A@#SyC1EnuxaA_rTI&qDQsgbKspjW!4gNe0|`r# z#2QZORh?GO7NHEPd_{_OAup&jCq<2ez;txUO|C7{g=XfZq*irW3Pi#Oq9d23bJoyv znNb*RmSrWa;NIv!o%vOjCR&ck!556@#RD9`GmE}mLV=)hafs;MYtx47K%=EZ5~8H^ z8DGPsddPiSsTb(Oo{&Quq0JBiUcWS2N=~eH&bEW9YUR?sAd*>4M3%Lh7Dgp9p}W}D zXu3E6i%09L$k=pmUt(rA@DLSH3$1Psmv=kUMKHeV9F z?S*d16G0#ilg>(`A+B0M+OpVutZY+}G$=r-{nk6K{9XX>bcvy$rWkNWvuGC=v{&&q znX=@P91kUUu&Fy6({M$FYzCGnlVcbJc2Wgd1C+7CTp&33K|yhCjaEgY0pr;SrO`6- z2O5p0_zvC}8jbV{==wadxfa`jn>F1-iQd5%GqT88d}RI8I`bIFFzMRkxWKMrDdrmESY3Eu{d}T zqL!5d0Kj8i`K=X)0#HJ1Wx*dScbPXW2q4o`&_>Trs!djitxja?U2V{Yz088jk%y2M zJH=|3A|XqG@K{t^y|CE2!=ZSsP@6W*lCX*^2fl&H()`(_%X}`~#yYRAv^F?X#I)p4 zZl<}sB`i-ZXp_3^0$-RnF{_1;EYK&r(&}aFxLPVC5l-fhss@;R=?jyRqgHLK=Ja+uRchMVFgO&?cAi`0d6s%c-$rEpr+0B%Iwq!?qF9A%SM3I%Fq z7qx^a@e8ChaK3nzXJqJXtXOpf|GKJ|*@N2;!}Oz~Jq59&Iair-8RZJht_-eXG07D0fh=2LzT6sm zF5^te+L;x=gw4xhA8H4|%%?Kg!=+40T8|kbF`Z@Yfi5Pa2h_9#Qpn}qpkGOX)Ew&> z2%eO^iHzzqzQ!n5ZsJNUFQkMXEQ2CtnTQ(u{1MfO-5nYCcN@?NGY9cZj014{G z0_t@am>XV@?nB%S*biA*#$jukU%@8=_F|zY0hg@|dxWbx#{wXdoU!2UY6*2NWdz7P zq=sB=&okJ%JA0*CXH#a>%(Oe-4NWQJoXvWOFS&}U;;Lk+azA!&YA7SsXcs%L_|ZAY zK-%VtihCmKxR#d^0zsuRC{2oKn?)rIi`KF-O+^_b(ORe??9?fEXo1vel5*2{LwN); zOv`9cg3_hB1QruZ(xXM9q8oSCr`d|Owwazb7yX{}k z^g6%P)p~Pez4PI&){jPSb3WL$@~%f&dLQU=zI2E4KFabHuHNC?+tvD$)LqVdyPP9$ zcHT{yy-ja%-qqFm#)_%f_s-wF$9YFr>%B!&uy5VluBc#N%YE?YouB8HJww01f1N*l zoAWUTf_=t4{ZW#C73l72e8ibkfICmgVzJ5}c9w9q)f7L5EPv3M$ESuG6rUou472-w z(u!IQRGSAwo?s<1tAO|DR{i~6lDf+Tl2>|a?{To|%6PSUYVXDXUM!-?S-WIGyo+xZ z@oX^tYx(mRovUf|d@h--!0vaGr}K->6@YoEl!}6w_{8MC{h~9Qz%_@C#BWlrZJ@^9 zls`rg8RAih6MBZJ4ga9<@pn2UDoG?VXidPMBEykM6bFxK(`|+T&oF)v9!Bvxu;i>L z);nKv=TXkzkPnbFFypb{;aSP*&9~G23QdhA0UC1j8IO_D1{mC#v;BkKNztMziA}j1 zjb@3Er3T+t&rseIikCbiT=Hmfb43N+@m(`{^vH>G{baxRNyI{f@wJe1?Hx`&3gc_*P1H*^EcdSLYE zULuQ+o;g1-G;9DJGbrGzLT5wo$ntUr749pW3hXj z2&DjUA;rUyL~!T?vCG@GA3E~#qmMrI(vJN{PoC=^7##79PfSo$K)$A|700rPjGR5P zcl*|@yN@0}y!r8mzWaCo<@=93{`7M%ZP~GR|DmIAau^;Fmc&W3oZ=G@{qeea>;=PnN4?)Y#}$$24{epXRb#6_Jsc4W^JU%&sOUw;1lu9u(t(UVU< z^Zd(OcJ5J+k#T4W(l#(;0CstVE!vLmJ$?46uYU61e&UCL)a1S`FIvyeKKIhL-Fpum zJ9BZ!=U<0yhfjeW$Wx4DlM!5JqeGWY{P`z7^~wL-Uq~j#4sL&$py*eKIXZas)CI&U z$Oc)ia>@XU)Wf+B`E-Ops8Qc5zkmPzpW7Wp6GeT8cW)*ZddrS|2alaPH=wMm9>%r+ z{~(npYB&rp8x9a^w)wX{_nB`DAtJ;b`A+QP^=u(#{Mf0px>qRbapq9Z+VRlO6fQy+ z#1i9yz~lEl@W8`?9EzHLlV=X^VJ7z+KsNjIRH2ydEW(7RvTQCQ%E-Qi(f3b2{W}l* z_M>ssc^N$&504x_NZ9j%!^g>mH(}y25)UgYxs(Y_Xm6rYKGZpwICJ3BpZ%>DL=FR} ztyCr+@tr$#=Uas9{RzjzdeRC4Ku?~09Lln&?)~qH0)&+M%Zj} zS)oACoiLV&mXf;?oT{c@`TEfy;0}h%knq}t1mU4C;?YQq96Jo|65Jjmg(9m@m5x2w z7eoEXUL-YHOI14&|Dz*YJvL3H0^f&~M-res5(Rn{#~-_tpe#S}2O0r|P>6MQu!&Yg zeJff-!6CvppaNt+M+5}HmX#+4lK_))J4>x-!>z#Rki|tqYM|(Kix6T0i|qC@;0-QU zEmpQ%q8kAy07Mui;12&Bm?e|MZGKx}%=E}{2!^q^F80S2NVtZ5!ltH{(1u$#Du@#z zq8_UQ`h1~LYhpkG&(_kA$ZK-wxxMCG;njINGcW&z;v|*IqhwhkR+RN7I5@>C*L3Om z5Dh;#fIW5B1?|2XWGvJU4SQ|c-JcIaxMI|)#NBU zc36epDxs5V09gB2NK(=Qv^TVz$3-xO_Ee;ZN&H&DthCdMT#(&!U45Ooo6J{0{c=s61YQhFg*6kcjb$q^s!f_XaFS}4W8+<;0d8n0I2vaFI~7em zbF)_}rCSYWSL&z8~LS$6|BbVhIQ%H!b z3K*GbHicBo=15tGDz)zbBU8LB5BIv)Stdu0L{rQBX|M>P#I>G=!6Fsnk$V~)EJ82_ zp#eROcRBM~Bst#XTK+UxgzWEh9+5#VdZr8(0Rd#*Vlj>b)bjhfUPFg{}d=mu%f{tx*F~r!l(!tYVvLM>?!t# zVX}h&8(OaBiVC#iyXn-iqbE`4W5Ob+-3~5tHQwQ5g+<~g4;(phrk{$irn(zi$|#RA zU?gS02o`Pn+`a<`j>;iEP9jc};r)AeZYLChc-dQm5z%BgpcM1l0VBtb z?BBg-|I6R{)2}|f^A=zPbyb*z{8Y4Sz5_aPb%>D0vGov*%p zD=L$eajctwlqj!1$KWeI77^ zuNYtb_^AU-;cLLiVl@vKk?Mke!QEYnB`1QxC+_>L2ObH6)6_3;?x;du_Z~c|{e76a zLI#XftC>9g*jkK>brp;}mc(So8%4aam+0>O2M!tZI^>-Q5glN_NTwuRDV|5JQCF2C zF*{%c?5{n?;?$Vf`1vD8jvhaK_5y&~6uoJK5$RgeV8rhd2uCHWnGP7q%7f$LTqha0 z{_{dH6jY!91Aw9`np$d_ijJnM3zb0es?6|1_kCyF*tIM*YtmNg*)RR21gCCp=z_>_dgfDy`#x*e?c)O6+eLl=M* z;y`)m5-vM+VQ&?0!>x&^rGy>W%&w3n#$WU)Pdq*ZZ%XYTbAO`j2yYcQP}Vk^E#t|F z6EIe!-~~HbqgkmvIh@A3WeSDT5$BZ%6xG^OuglB?T&4b!g+?L23=DsTYFgWe=teOI zoCT(yoLsjQa5KbQ`!{G4(8G+_8}0m+fq|qpdEo{k26&?+y6Q%R<-mXCmkVXZwJtOp zGgXCGQ+h`Mian5tLWaz^a<7VZZeFf3tX-4Iv5Yb%(zRV(z{P9;s+cT2pCR!x1a9Sv zz)&@}h~{j%QQ^y|eVpO=$?>uaWVj$!R=_WIZkg7!=*G4t)D_N*fK#QRP+kuw9JGC5 z5s(L`YUP&LUZzm@o~AwRBG6Q4t@1CbDbjyLV>SL zw#p{JtOM~@auv4AHBNy@v4Y+PY_ z+=RaB?>2foVbl_0{13SE~JYAPOc;g7a@N>g=lvRz3Ic*SQ3a(;B=8MX&57@>+BN9O%H-ojJlI z7$F6i&?tp`@~Xvv80f$d&h?X+5eDS|fK*IaF`pI~rG6Y@V~DfKk~mb+ZFFETONgov zO!fE?feliHBbY_-IOc+itKqvw^q@@33q#|RCRPk(067fN)DGs18cpMy}B!v0y0Xzr;y1TefUHaOlN{ zAO5FJ+x8kOcVKALH#T+yEs}_bhE5;ay>;{EorjMeeC4qRzw@`>qKy1g&un@Xmf*l) zXp!qkBo!U&J8@{|c56#z@BaMZpm94vl;|6bs7C~E@jgOQgArUgLP9HtI`|+>e z_mM9>*SF)vXP$iGsUJQ2;;Y+tsmG9Sy@M-JY%HDyq9p`GhAy5zb>_*h{^los3T{Lh!kaM4-Xnv7HY;KnY7guNfQO<5-mzB&M0Us6p`+eIyFf25y}E7BeuG;PwN+Mx9R_9P z2EdeZkzmk2w&k}4M6lgpxV*>rZrif?)$I)K#Oc0)5s-n$S;Vb}`78$^^;yvb9aiMC z4?Ggcp=pU!oZz)Gk-PRCK7Lx19$cbfMJjll+72nD$Iitk#-9=^k|64%jE^oJ898=< z*v9=F0M&P4aCDsdI&C15E*cmjzQCv+vJuBl?f)dKNYc<$IV(--koPQv*^v{c&RrN7 zh4_i39L38?ErBKkVpO}NQfp3!PJQPA!-~j?M`Qp3(ebm#PMkS^k)t5|)Cx-DW>eWe zk=^aCu8LnNq{+btKlSZ#6ByB^HUxZAsR*oyDmg;M2-m=Uii8nFXeUTigUw3n<*y$L zq1?a*Z4AQ}t-TEA07WC>6bl5wl<=W3Qc8d|8pWdzo{#JJN#o}$f{BDfphRTnYndw~ z0Kb}HUz9e3_GmN;V~<@*Vxy`!79&{U;~sn;HW551YGS4=l^vAZh@D!|%@}O;sdDv+ zA)=%JLIft#(Z+MZ_DL~r8sZUSE{I~)U&PN_IpT|P%HigzZX2W<<($DQisXW!X~%`j z>(~B`$Q$<-n>&sRc^p#Ip`LOapa+PtmeX0eHzR}=H^pBz4NwGS!OqSD$l$;+*Wn^m_Y+%Q%z{LOoFlLe6Ky7nRhy>h2D_*%P7haa zO`9sJB;Sb6Ako?2TedMA-YdKm8*+v{mpZG;mR&PVI05m6N;+_H59$YlnHJF-umm{X z*wn!o*7^(favKM;!u$3>budgS_vDK*F#xL)rAXKlRuvVBJcjN8mZ<0-Ds|q#m znA!+5c^iLqO?|A(u|2&X?OOh=FMjb6kHgtLCr+)b#W}R{!9ODf0`Jh;mu5CN@8|5K z$1ZP_U+CxmPJW@*hVq-7_jI*>A#MCa8#2Z}^mC=RI=|S}dQjE4ja1`UM>T z<@&S1w{h~*^8fhp`PSPx`>FN6Y>32v$1R0b7yu=hds5v z{Okvv^67gz|{0Ol}#29puPI@RoIe8l{z zFaXgUwc0Or3Bj>9@h4#dU29~vsMu2D1N=@gF&TWSj`#kq+Y||_wN=3EAQ!2;(NPdl1;WZ z!up;rgP2%Fy1l7MNc=jm)YVi)0>JuPyA)X~Z;`2>pnF4wQU!u1R$h%t^YU=*BOTUp zIg=v8Ag5G24|j8kilRMKMpUacTueoC<-=wKT!x^!UX$rYx*cC`Fkk36hxJqeCEcGm zga&k-seELyR*B7(D^S^fs!G;P8n{XV^qA?R$i%gVz!Fq*Srr4WHzO6Rrb2wo77=M; zH`;rfsd%W$UhU%_+C^(U3g0T4k|Z*nbwC2PZKu&%m_{5|=sRM5(T36yXg(9=X^N!b z!8PwvXE9Xqf3)+-i8so((+9X3<{Xz`4C1J%?u{vIqhXd%RyktZi6%xRC6gHs1)S%l za=B7@eetqbFLo?84MYM#kS8r^rxp@XDhZ}hqBj5LaTDsm2gn#P<@gv(tP#;`wK_Fs zEdRpfI2L>Y6=i1?6-n8Y)K%h40U2;U>&4`knmkgebo|5_<781|;zWr8%@b0Aot3(h zOvGY=NS3h>i^LHVGW5&rE|ua*Xg*Loh+nKz4uc;HQW-KSZM)=zgi-}YuV6YhO=?z` z<~a2_2rr1`VZp@b2OrsSK0vez>f0pikBv`6iDO}wbTWfU3*C@?@F z$UH?hcH%$$yT5#XFhiEQQvLnDajzelNld`8GzA#_zPX;SR)C?#V3fAqO8e|sn%4orASBIf8Z z#cyC<->&w09O?&k+Vdny7}{6=@PRLEne=-{Mh6E+qA>#sL@p6ust4$_cgf_&%a40` z{J(tWf&X-tBG*I1BjISLJ$3kM3%We>t77&ReiPh1dL!}Jv;W&?es?!Do{n7#MYFoQ z$!%o1Y>lc$r2++D^JF@Eqhw{_+6c@=fDZlM{a<+Dz|Nf~f)S1t$8`sn#E}xUMcoLX z!R!OjjAIERhns~bPki~l&+pv5ZJ$5d896luS)Oc8@+P~hILJCNX85sqoPclNAAIKN z^XE>FMLCdOgKKwanD&4bqOOb^20V~%5M2=uO`O~Gg}*&_zJDyryCScEfor82-#K8B z)k93sGLVoSuH+0o#xL&uyFbVN^F_sbnI7F$q8hn66Gnnbab7r(6-JjPF|gcZ@bII5 zb?D6bkt75XXE-n{Q@NO$jKs|;Ud4^{D}%1WpeVX_>Bx`%V(;l;B;2e>`H)cmTIe3! zTdR$0N}=yjp z+NCwcX-Jh+Ea<&>;*<{<48XkJ&S3&bm*^avfCjljMrkzQy>M_ap4A0i%o5PkZH$p# zp;r~l7R=7XB9nusPII=k%sc?I_&)_*sha4U`8T8N)R3?5#CS>pSvKks7+Wc9V8XSw zl?|gByky@c{iA2jLwkzM`3KHVYT*}q$S7G`xvffKGv5NFH(x5XMJM}+3S38U-8zP?z)vG_ zV&_x=clE1volmKiLb!xY{T|JNLIT?vJ*xU?mzPxs-kdoi>)@s@33)|$z@XIl=_T*2 zM;D}ps6|(vgz?vXPT)W2no|N0=C?9Y9_VF*9aOCoqa+WfhM6Mzh!%Hsg00ockhF>n z#`-e;TK1EB&^tN{!dOn7<4D|j*X0#ZFUUsaXea>G1lgcEcuG@&yZI*`WTDK{5i z!qOo7nUdjxG`K#g00qRSC6Gvv2B^|5y`!Z5Hl#7Sf&!llkf~miAXhIJ;2pFZEd$7y zOU|dM>H;^n@<3UdLl0ORkXb5_!$?grOA^3M#UqLo8#1nKcr8@QrmTem36xD;1wgL0 zQ=wb~Zm3$FC)xe-*x#6XW6jcs!OF2 zd+IlXn?y3}ApwW*5?NyP>Ut`wi*^@zt~ZQG+z4(6rL*%kkp}a)<#iAS%Sn1v6^(_S zSh$U;8^H|>hi$Z)4!ybxe*)`|g-Y@lPhx@*DmQ=|<7oi<6jZ*=%3MJsCqgj=)v~4u z@0C)}SvZw4;AUhM+@Pfhjbu^6`(whU$gK`eL^5Ql0L={QRmtP4kW3+pvk@X%CK0DN z^ysesP#)#Q4kX1tJ~0_9P!H8o0$!9Y%2H_h^;*Ry-$DbAJ4|w8I&;3QB&z0D+{ry z-_f`-)eu-C!$U6aY?)9e2$G9`{DuGh??>2j07D~#-h_hGYryc^)jkR)P(nz%eeMQu z;}4EeRnveQO&Rn6a(~r?pS9b&%6Vn4tb&`r?DLOyz)ib-H>U0aK44|7sn)+m%E1lb z=7BHmxzGVOs+7^Gr-ryNss;#6IT$=yTKWL20_GG{i5~vi1Hbd)!CkuqZZr;4*B66? z2nRghoDFByGk|sWECak%bn4VsKJz=f_wG0VxPgP=UT(~EcViJ*0fD>gX}}7boS+B6 zsmVlW{J{V5*=I;|2i)A)p<>$0`Ocbe(%&IO0_~sD!1|8O>_t0+qH~p^ zit~%g$dtnei>D*w7dilkAqz{kYNZX#w-&f+yHJq=o->yY`p)&MT0t9dax4dXgR!V} z>L1dTNdyP`16ulIFMCv)oDdtrRT=kHl?ld_Qr3455555jb|IiF7`!8t|qsl`6&5P)~e4Q|LehD1DF>E4)~AbHdkaKNlbZ<7+dkzm-{{uznjubYiHA zv%-Ry<*f92{Vrp&bSMT1-6uXP(3;?LtnBpYHiy&0M5(`p(<037~QN}Ab+>OdTgS?3@TGz!EqPuihwbaacPqeI>BfY+%TLYl5oH_SZS zJla#3rh{|%jDri=&Q*i(I?gc=M4ncyPXluRMC~drs_kfq8v~g*-iVunoNk43*zV=f zGG!)}Gj7011wShhQUrvV8b=HOgrg%qls@HZLJXSoGEnh7?C;uzK{ybyE)a$uz>qo> zg6eyXaDZ=!L27@&8J~#6I%3KUYXeDXh|Knv##N~uipu$rv+_gh91y~|Zf*xFRIGSj z*Gh*T@u*;b&Jbb`7gq-SGwn^HhdG%>*93r><2-74)!k~Rw2)?%VVhUVjw%2#)ca4m8Z5uSREE+ zZXVs9O2*knu z6ku%;O<{Agh?Ty=?i&w^QK^zNPG&MQ!aQ+wS?M@IRyrPwj1S5f=gHV5juT%355+yI@zO5!lH$WaL?@&jMNHtj1tLh>|geD|JDG^Vd{QFP+ z-a}_%Y}+d626vOnvSh{d+`+jw^^mDZCv{ZG5@C>OzwP*W&!5cGj zj&)**s`@f8!VU3Ecoyi!%2WlR;z8fu-@pGE%Ap9}+|VIp+RLHOnh@>~v7#j)M0ECr z&ws1$!bRYXcs2zX>3|>O;RoPoBXAYisc+~q*1zXlec zocAC=WM`THFYa>b&?CT`3!^C(t4snF0hX02jzZ)oA@Tw@u1rO^Gc-PM_$k2~GGEP_ zWJAK4W{xuP;D%dmT%&SyB;e~m^sL~GeEi&A#Ur#En8R?5Io(7~k)qK{r}w_luaG6h zbnANT(l<1_Oer477^f*8at$FL_7O%kL3q~~9J|+X|9Y40EI;?fFMj@G96{nbz4A|8u8(xB zb(UJoxsP`LQrB(H%FdVn)rY!ncUG>P==ng`9ZqZeH{RcMr?ay34cEP0oW=Qn>t}2E z&)?hi7RP!2d-U^O^K)81TgyMV?IGvCzP0N;4surisP(4Sn_cU=KH@C@`M>}7zpv<6Ygg|DnrmIQfrt zxvS7P_3E$ji}v!5b^&OC&h=mEk{Jj+DEL_WNEhA)-ZR~$*M7N6K$l;%;(w`2q5+G> z?;q}3!@ALNsC@OIF0+6TE$!DI>QX@-ps*%=fz6UjPkoTv2@Vqh&$O3RrMkjrZ0&}~ z0-V&U`nww*oynKGjS}o1=&}JlkVpvL2k^(K-h~b0CAi(g0N>9O>L4<=`Al|#1WcbJ zkVfZ-^E2&`8{;M9;osLKL3DG*jJ9$?_V;zIYyV{o!}oPbj9G6iUITK&1jf#0`Ytj0>T{`tgE*Jf# zvqPDsIv10@1x{vNE58~ep{dVwG!6Rzno>Q)57U%JC@1Yb5<* z)U__b$)w_pr7!fEOLtNcdL>n>tD&~ad|0^Y!&bfYzAmFFp}JRFw#tduen_f+s`$RH zWlHowDpOv;Ty&|HF4SvG5DujFr*2B7r?a(M<=(Cb?n8>vq6Wm;u&UA_ z+V$-QQp{7EtUjlX6r*5_bAqNwu>t8IBGppoa>P6$p$05NE3#-Rswh?CGePL~fiS2# z{oM^=0`UgaY_mu)27zjwBcuG*!vK+DtO=rR3`!&h{I z%)9m{vWCSBi}FK(y5MuY`mgfH6di~!&G(M{r8md;Vbo5c6}r#H$kCV}WRt486jo8*@V ztRug5ktWPUHD@Ygun#U zCC~8WoM*|+v6FdS$S;9AoJxggAivPvIwns#RypYwzlpilXGVVcFFd=X72z`SEUnB; zvhGX^!5x|X#5)-IWpj7y7*_@$76`NR1kr%ZyeyYJN{cJ%5$ufId<{2e!6 z^_wbG_s{)X&-XX{BTxwas?u^Y#*MXP6&Eq%_KX!^^QfuS|-~KYrZm{Bh^w} z$j8KHB9%bV{G=`td_r`O3^!xn(nG5ftDVA2NeZAq;J`TBM1s1-V5H|1^di~={SRgk z@R4Dp%2LGynfM5z8jBy9hR%j$k(0AT^_ZGm-#T7dgV!dwNUUTgnM3Yy+xDQH(@nb;Cu*;)Jg6JCTLflW-|2D#JQy7 z8C=a6ffi-RmSH;*+>3t;O0X=c=pnQnkE@Vf=?fj*x?G5bRlM@1K5>U$1#;p!$_YZ1 zd^wdi;GqQ7_(e4VAwF~A1nv!`k91?pF5_}Ytc_38EtzFDn&PswYGnlRjOwGemd%CIY96BhLRI$0as|4%>VSjR>qjZyG!W~}|qsDFumT8J~1qV03 z)+Q?6R8X>VSK->D!6Y94C_#K zd@G%7_i)E*WbYRpCznV{+0tH=g5LcC?WvN!+PWv^j=Ey5s4KF<;kE=V$F4|BnKDT( zQ3^D?l1&CiBa)dEBeG+?(e8*7MQNDfFHzL2-I5rn^c4!#Px|oFCE^L2wrgqY3e#2) zvHhUBs4HXPxuI|f@!oMR>WXpuST~K`;cipw2UUsiwfP3Mb)~0M$-u}&M5ULbG>)!~ zbcdY~=K&+MIz0S_=AIO_eVh*e2#FjczAT!7mZs?-EzCjN+=lgI15z#Qy-PpQ(Ty$!dyv< zxmY09$%l`sJ7R}DAxLR|O@c{Lr+bu!lnBqnd6+fogvr|@bSyiaJ zqjOw$;?h7c8e#VAkQ3~oq8tZn^IBG2UN^MwiC&E*Vv`pyj0L%RyE!6=32|)#opg6+ z$SwwZB^rwcE>Va-5;o0s0y8(zjGOFyhI3;FH}88IE;bq(=^ONiLSeE5IXsYUU6C!T zl0slFx6q5XqjsbfW#m@~|My-P@bLnI-DJ}!mrjA%tMa00bWujzO&6CL`dl~?jgDVB z;|qn{6iZNCBYWeGJ?x~Duwz`l-NhZUg0ArLc>nof&SGxalnhmNCQr_+>h-!(i$pR( z>$+oB)G`8Q2d%(zFf=)6lN6!DO0mCg)x%;Xt%UUoTp{&w`CFl|%}b`dKtZA33i;EU z({rGy;tsFQ*5U}cf_7lZKRM|SumC|fR4Ju&ft;e(d)TjOZ%;aYwFWB`XXFHL`zl2N zwr}BzTTGN>&0;*RfO}HSVeQ36W>QpK6Px||_7*SsdV8Yqb5`am%q{f=?uS$*ckPrZ?*0@>}$n%1~um71iUE^W~|M+cb8Yw}xb>ygCEYyKX;m$aFz4id3gax?>9ouFeCu z-*dYMT8DRFhnEr4fE8R0_yYmYBvnG2Xy=s8BhD*yN)+++Az7wNdsbb3*Q9&G?JPo) zQme*N56*GBWe+>#4%)QtcBaS%T?p6)$faCW}tZ`8DsW>9uijnrGEDA*g#5E>OxErnGrlmEhwj>y&`Nkb} z;yaFH0;aFOQK-nhS!>}VO z=o&3Oo0me({BhS9?b#Z+zSe(Bp}MSbBP%YR*~K(lw0G0q#noFrbzq@#2h$2FNK_-TVl#7d z#2YiAU=NmtW3D~#4+H}Nzu(M{J!X;W#hcahG8@aBB0zl!SF&|Ohd@vr zmKo*lvz&q`2a`fW7>@LS6<9HiTg(luIa1d=ZNx$BT)`_L&Q+C$eO-HJ+-;iAgE5IV z4kJ>nVAx8{B+SM6AQUFe3tg8jG5<8{4a`Ew1f& zH#k?XP|JnJA@km6m>ua7L`@&rtT)%>%EUMqw`tB9%jp84r=g%GY+_<;61~agJIy7P z_O<3+-i`^7hR~43s`Q|nOaM-QR8$t+yLcKIlFH&SCIBhU>H>pjOaM--6_!_s7FLCb zPwZFGQ#GnK8gsZ>NNIoUV0!ne0YD$}kV&S%NETTny8eo&%zxGd04c+9jj8oIaB_LEdcZ>R>r^J|9`>%uYvRb zg8$jluHkbTW05GiC78VrOep8<}vH{%W2g}%d14REi3&30! zVE6{@Z?*uY88`s-r?UX^z>c5J0^k%uP}Waq0RUJCKKUsufMqNIS>XTwF##6aCV)G( zXjq~jV*o4}1Hg{0#DU*G2LCU%@xK+l$_%MW%&lO38~;<(Hj`*K6!^YX!+*j5|Gn_P z6`A5-FhS6t0RFopGt}+;Nx{D-G8g@+pnr5Z0%!M=LVpYT57H*gSxgH*0r>Y|T3m@h zmi~mmpDRay3gGX?jtagZ^0&uauR;DIH(rDM-DGpFfbeBjIKCf)`?0gHHSY4Q692HK zLYZ=W-$488#CJi^PMkI_=w$^wi1w$JKpU3cg!x6_#Pd6ie zS7wPkS1L6&-0|?(2L% zr*D#tg#TJmReBbK`16rq_Lh8qz0LPmI3%6ogR-K8-r;&Xh#w6Xx&`0Q_M58Z%48iY zH3v?eKqvJPTPHej$?*O5br-=J_@yfIL3%LoeMZ%lZUy-RDBLWx-8IhNib0h}tmt$C zi>-;R@Osz}rI88y!`2P7zfG^6a48a1MW6c2EpdMaqWxy#--&v{R-_Uo3pZVQJ@mgK zc7=RE4x)lUYKhEu$CgF2tbGIazm?6{skwA~ayX>5o9Jc_gk$peZ!c4a3Bx~iPKqv69@&k4dCz=euB=xAbI8pPLAST7)7N)?JTRC6<&m! zfK#}&v!In^OSU5m(O6`(-wUr{2R$(8xAYe9yjSttghns9;PeNkCj$L9 z$A!l(_WNNxL>fANxeGXKR|ry6Bnw^~lbmpJ%S0kQ;j57txfp#MG-!8vyvAc7&lA(6 zal07tm2f0HdGY*!-*7OF{}wKTn|g=>pAH4X;lR+@fr)@9s>xgU4D_<&M)2UMTVaNO z1=@C`uYXh&&Fg&z<^3&$Zv2Rq@@AJ;@H5TsA}irjE= zSl(a*K;jxIubT;QF)SAh)Dnc%gdz7$1%&bf4!Ilqv=T6r4ln+C7kk{9=r|83xXeqx z*>u3KBs$MFve%|l-Q#LMV?vWL28j8^8_=fq7Y%Ulv=<*K`nBC&HGHgWqhmWDSHhTj zB{mZ!_O)BQzI-LPGqn5SJ|LyQFr2s#OcoiO@EdgzXKOng(nJ@rz_K3DrSffy7S<<5 z;?W(vKp066%^T=~tsu$17=0O6c*R7lgm#=q0+T}A@Ms6o9|MDcn zuxI>6CqjMIiEzWP+E!M3cE#Sh$8Pc>)K|R-uj^vNSKBo2cGB0}2vLgK8w<1|+t3DCzn!82tWmzpcO5{a7TBExaxj9Xm(x*>t$z>&avK||wnKse01 zQ)Bm}XROC*b{q+!Ua8J;tA={Rp0QO&g1l?Mg!By3aDBjLsX1H|@f=sf++2*E*Nm&IIwrp(v3Gb4XFUIg_!17SbZN zc{vs+(&fF`n*d&xM=~xqn9H!+E~L!D!6VOuTu78Hzb>nL8M%4ByaWo)tVc z#y^{z+~iFlMa8iF?Jn|e=pL@lBY1o_dlM*OrwmFl+VY)<|! zKRZagbwl$>SoBFARg>9iZafJVFv1SbQqh>}bM!7lw|G@@eu<2?##+n_mtXZIm|3`j zt3r#Itc};Sc6@Hrn4}HPPY!udF(E5417DyyVdD+@{S)YBO}foMRw%`K8!swH8HBJW z*a%EUq|sJevro&tvZV8uX>E@>BO9Dq{0Jls2hBciP0ncAwY!?@2dv5Y3AOf)j@l#k zurqYK!`k7>Xh} z%6T9dlSn;%W3t2e=I(X}1?YLq$Ls1pN8uH9TK)STqJmV6rNQ^zjoVFEr%WrX6pl+( z8K#X2^Q^BkbrzI7N(^EkLh_mfgDz}>xp_Vzu!#s(qsLq3) z1@XC7MdqWAjYwhly_flu*0t@-KA3) zi_{RnUx6Ejo!u3h#@wei*%UQXxkQO0d)JWUb2~BIG_is!!jW3tp_xdsP$8Lp5P*a?q_44bor~Pb<#+5JUwP)NlafQO5DeBE}+yoha zc6JSCMNv&Dw`k@j(1WI#l;$%Oz%<1{0}+DkICza+HMhnj3F62sPH4_OjLZ?jp@V}8 znH}TUmS}>ja|qU2bNRV)v9I4BWDb~w?unkx26B0HOl>0x9kZD4=6I~N*|~ClV(84p zac1?#rqe1qsv4zX!s95?ZPR#7cBYt%1j3=wzP^#Le}b)M4M0F!ljF0-<`{J-66XZ9 z0)FnSC$p35*}o_l$R&<|yE?%cyUf7s#{*19fMXRK6)|P0lgh!SVjH z7kmuJndmlm==QpOuCc3(hX-Xi-RVV=xZ~M$&*Z#+{L;w_V-u6z=HhC}SSBWeOd-OP zg(RYyWr%W-3Vvw%LzBa&`bN-$Xu|O^+B!au*X6Uk?0(~j3*~0>xTMp$6bClrm{uns zRcK=9>=~cju-7^{=wr99;bl&du@r~2Wx|RdjM~h(gl}$Q=>dT?y4+joc8@?D|YZ-iPB@)vjWUR-0doTfAB_w}9aXD^`1sO7zqPlsuveIn3q zWRG8Es=R%t2FH9GX>-|2Ns2%r71wpR5MsvNy2s{xV-pkJb7%T}V?Ey9(aVKwI7vAn z_MpI|*XAv$*&5#h_w=4WHsGO6GoOn_bcDK2jiFWrZy&EYqhITrN3=%Hp1Lq%dEKMs zkx}pH$Vich#rAUsCdWoDU2oote9ezd44*rBVU*_8kE5=u93p%h}SoGk~k56BE=~E z6BEAC!GTMchK89^o~p;&Guj#%wnrLVF_(%2^ek#Ma_ORV$u;aAM-myK<6Xlj-E8`< z(Gt5kQ8;77GK3i4*zn+miBU6)*g%fmzquIGO1xt}%Cq%Z@g8HIuq+@tfF=h03dhiN3pE9&C}r@*+6SKfc& z0$udtCjxB2c73DCDWIm2GqtfvEu|(0r%-#`R$v7wDI_9Mmq_2}Oc_-rzq{SR;#ZIP zc-_>`Q65H}R{y?7p&aHjH&u^rH(i}7tw^A8Q)yt@YHp+wrZu(BR7g;&fcR6BqhL4R z!igyQNdH8}0ugmO$Xlj5DRCx+K`bzAaD5|H1-hqzR+RTQ0VkAOppU*LM^HILD&!H9FjX3*d35Y|Mmw{l#nyA#-E3nIAd`YNts7$61P!~074FscBPML@kYj%l1 zkTO-%ddudKyBi${#&M05tY21^?Hcf;PS7OpkCagW^fd^Ut5V4y&?CE9%H8-2#Ipb5xLK zMpcXWXSvRe7))Vdkywt*xv3S3SN?2q6<@s;gOM->W_=UIU0~yHiNT80IjNQIGKJw@ zi@}0X$aBufEm76k&aa`evvRoK2!leEqu$Gz&YyLm>-UG^#?5y*Q7tds7`KqqA zYH!r)N_DH{0131VVn84H15Mq!7qDRaiT(>}7RV~e|IA@u|4jL^w%q&Li zqTOYXy1S~1C!@^(y zu$y48VWMPDvXhY-%3!G~Jhj}_O{vEExb)`ZAQ)K&GgE?K+y!IEo@x-109aF`^DqGG z67UoNV+kJ~rt&#p3wTg~sVml8AM6IDfd_@afKXta^ti$Z43-g?uglZ36K|^PNEGoG zVSYwrh6$M?Xa&n4Xccd&gkNAvM9|a+2PEU~+ypbnO5kfHK0cA|m94ET0(&v+HL%Jt z>n||7n>&^e*mwp6M(8F;g}%unGZzQ7aIq zGZqYoqBloiJtB8x!r2A3BC=T}0-HUEzy#E~5)r#2AC4VDV2c$9Oj7Z%w<8~kl|j`_ z5Lh30D$?E&0#3!t!p9&m2ETy7dKrSCTO@W<1V#+4+aoYSa&_Mhfu%<~VeM{>z%XPc zEf@oSO9ZBPouiObeciV}V7#FqFau5FH%DNpVKOH$WqP{eWdyb<1QrM0mLM2!pr-)B zJeg@1gwf%h1|^n3m?!Qz2*beY(mxCk1IQa7#z!D=1c=R@W8WP1i^L=g=WqsRmBQH= zKWbqa!kdAp05Q6vK$!B%zRxWnXX}7DeRAPJK#B?#|Gpm#BjB>gb^qd7Q`DJ33R26b zF!J`|Ik-1_;iQQ&uFMa3u7RC!;`J`xvv307qDU8bY_P*EY(cy3Sx}Gf$-MC`S}f2dH{x^GF=oK2a_f5L3#f!`RC!nv^8I>g0QXH zT%1O54=2T0qI=^f>>1i7njujrSM1e&T;c*V_e+S(H@ot7pSK6*$mZy&c; z@FM{km@raD!SD5X`?nyaiRB2cUEPJfo0__N`ULJqa9yN2>f2(|Z#YFQzU4jTKB%6) z3pR~_n#RMOhz}4&@K!L}*%=ZU;A^)?{K){ZTRf9z30MJDDbo$@yNCo@7Ed%wU@{_e z;%_unZNk2g6Jl!eIvXK zKRtOK$RZCT#jWv9RN<21>0W^a?;9KiJS}3UJbA7lf`Fcc22}O#KzkSXr9}=%)RC15 zwWz`I@wZTq{0|(qUD!A160JTs3?ByLJ3YZ=54UkxilF6Lj#!5gAn6!!MIp>4FDj1k zcu@v6MJx=9<7V$5ql2-@py?UHh!@uGZ;|!$pyn1PnxuLpCGFt4&N$MKSMGx5KY-SFt`aviHW;AY}R&FdSH? z#%oOV82OlCVf>RJ=@YNhCMM9Lni z28ZA;)o6sPNzRcOfM|*|Hir8lhJ2mX37@H1`Y)6T84Lj>i+x@Yo z8{q`fRSCb5_CQ&zLWzhLB25T8j((D3WQGZz)CH5(+Y5iz9HTuBpE}*Zk22|rZ$dl` zf+MGL{>;vJW@I>%u44ES?bn*)on3xYxg=>yC;T2$6DJ`%vptbb_G1mDO}wS9-p-Ee zjp0t58Tc=btb^L_K>_y0Jn%H!VGIu>JF_!32qiY^rTdl>os_D-5!D_;sf>eW?Tamt z&83_9n4CywQvLi7gC_c5J~bRmu|Oll?C-9Ls-J~Tw-bFeW9 zDu#VbK;g8ZOG|6N5M6?YVEteKo5L?rI2(P9R>cA^c}+hcKm>^xfaIy))D3ZE^Q z#gH)AiOtTgXhVGq%LWn=JGxF#Mnr_f`XysPNKd5kdN3Y4hr~)WmrHUx14IUT*d3)B z%`cmdXYO=z$GVnSyefJkvYJcvj|v~M$=3@L<2Rz!v27kA+Vomm02w%_!2xViVM~yS zb~5&C{m}ZF*cS5&{;4@^M}3iLc#lXpoJ$Y)f+r2Q0&}Yt3*uk=bx0 z914e1quuf=fwj_789G7T0R;DB5m=-381nVk+9EJE{xELTy)ax_puxHnt`zo1HyNLf z8*jA4qP{SJ&j$vCny9ynY)YXp-5p3&^ZbFRKjMkzV)5XOYwgiUC=3kiVLwa&t2+)E z1{8z5F=P?FT@%T|+6Av)rxCOjhf$V((R>DqB@!nXxvFSoz%A5biK4eF|URAg9R zPfsT}NIZ(oodbwfMe^a0H@rZNnX!Q$L+l|1tOK#pDG6pGO?09npnMT;*b|wGMk36I zIGd~DkGi6vHbZU2%EFL)QHK}HAIXFxk+29Trh7N(yu^lefj`<@0d1ff52{#XJ-w^W%F=>@TB@_xD!WHFb(joy;+qSHjJj$MC`B= z@`a~KJSAvEJ3AvCtu2xI?RSuNG+uZlg8b|dmd!NV)sY) zBhj#z-dTpQj-wz@6N6l2!*;}mMItA-Mt0Z7Yyso{%S!kA{7bEp<54zEskoPbcKz zJODMuR%X1TrI`e-rlg_9UaI&UcY-=C}9s+xbkD^Ij|ea=yxWkCi`JSIsZyS`8U<@-?j| z_~rcUN#~tb{=Vgt&hu9O*~L@*a$Y)3DjnyapK+eE^1rfwhI~5CJJ0Fo|9*~~I(gs! zbDm$$Ke^ysvht_LFDSpxqvLn+%lYg@vg|lNaJPQWE62{h?~n5O?fl`r&Qn&tYRgTv zlekamb-ev1z0P|da6I#OgAx~KNVPGQButrWGmn#PYCnmQ6xL^ZDLne+oaKrtMZ!4w zKv~-5tDVoJh=DM+lf?W__LIq<|b(jd9O-z!GenkFdeXHvWiiE6f}qOfab<=I5r;Ir>i?xGQqI zla0a<)@x(qUIlibd#YzoBI%jlnH(cplzG}^zJDW_G5`}tM#jb=xU`cjQ8%ElLOhI* z$w-P-n_YE2+4jJe{Lk4CGNDyutLmd-?`(EvIy;6*mGLs=ts5EW>&Nt=zmI5~Q&T5R zLsJY3>7wav)yG$r1%pkvL2M+(aQvQ{cE#*j3>86V>~0a4KpAw|qeKeEN`Zz>n7XiH zO^+%rqp|VUcc2f0vYnw6VPI(5X{N)ex#j63ZNhd(hCX~ya4Q_J2lK-jUqM7pd`vz< zYigqoi#C>3R9`aCAeB{^M6)B0qM>kY-dP4{GC6|ZwlTP-#@-%q5Dz+>tpZ;wt%Aly z2FCMq6T_pVl90g_z1$Dd!I^t+kT{dofNYYeBN`xp+bm%<)W%e5RLfisHhOqV4~$Ms zlH6WV0)_oGG$&`5XQsx|<2(*F5u<$7@Eh&(^zQ(9F=eYcDD9hFh4P%8S(u#|%`hz9 z232z=9E+uLx2; zED~ruaqe+_Okw6@CzlEH&XP;`SDq4^U?oCh942{GKLh3+pPEW0c}5~vAjy)`-KCvp z_RDP`Hn<;RwaSQka>NE7OVR|~_*WQv_A$E9LHhc~2(MpFbeF6# zuAa^=c7z8;GQRN|gsKrDH(Yj9R!E9licEs7XWG|Ch{>D}+^)*1=vOxa-%NHgGw6EC zur#yj!&au0fnk_Bd_Rf0KM|n62yHo&%?^>dLvN#r<%(cWcW>_yR@t)lQ`J7kPLk7o z+C##j&kUrqK5dcHOOj+5^yuVKnV!z!Ga`GWfu1hllMx?Cl2?GpH3fM; zh5*VVB1?~HaHZHZR%I|H`>BjAM&;QW*io4bpekb9P=h(gnt9n6&u&nq-MK|O2nZ`l zwZY_GDM-%hg<}?W#et+WpsQ;*l?Jj0&^7#%=k-a|$7O(+v@utrXBeZvEZ@AM$Oh;h z2?!)`lBaX8XCRF?xqF?^bxhUMgc`=JJIhC^55O2RV!e1^6vccpnP9pp7Yjy;U^F&2 zg@$)~v)a-x&?8u%`Ajv$cTuNgJgI8)Ge3f%yfb=gWDn7PENO>{mNAMwH8zIo zV?{p+q&;KUw!3nkXufwKfLo1!#H;W})aFZh(`Tn!$Zu67G)h7D7EV z)reK|(0hDVSo97^4Xo;2Ng%~rIy7`zzQ-6`ditvePGDH7_%Q|zC!!Ho#vVGUM^K~@ zyCk$J3{TYQaEP;mivBP>Oc!GFD%uI7KVSbD>f99eMyR9172DHIZ7dY~d-`gOD8U)} zPYrB{=47WCeU9De#k&{mdDtqUK9)9C358<;;_PEwtij$>noH6FKpRT5fch|TgYxm{ zE%gziX9s5yc2gy0FJ6G&TT>v$X|l;8$LD%S3p&QKIHT+*von4-Ft?HPENp`MFcU(M z^(VKJVY5N*4j@UOB;=Wbc>5O5EO_S$Q3vdU7b9tw0+T!V)9euji+mhp5<-L|g9i2y zu+BH0&ocY=F`cx>c9U>GAOTVeES`q*1N5b_H8TOud8#^C&=dp+ahnBiJc(8mn6irG6B#T)#NF`0C0L2 z$Tu?uk(FC!9Y9Uz{oNjBA!3-dyJkb5#*$DEuwY!7WI5v`~m_*LR7 zC`#o?dWPKI*)e-cDNF>yMzP}I^8kVw1~|{0G|fy=w~P2xADo1=Xyy{QGbPhNprf8< zlfCoQn6R~-l>q}$)d%zuApb29$d%thQZD2}h?cQAq{+|QzcWJ0Hzm$H&0ILSfTf-= zpP(>}0`y@4i;GZxG^be7lBs4|6)>M$lW;BOrUQ~1S5P=(0x+*Ui^_*UhT17LjvARz z)W{3gC&)ZHu6$Su>a1~5{zo=FM^nmlhgrSA9L8RH9fmOks|M?ltsc<;s2Fb%Tx>_&XY_M zg_a~<>b!u$&IDGPnD>Fr#|(u5ItKu!SZak;dHbqSn@}K_nl6yjLN|sn6RacMtQ~sQ z-k1a_COe&kZfiYaTv9tsjDxaS``4q5rE(_=*dcLgLM;Qi)S&0vf z%Hvz%cO8?mO)*nf0exUenScWiZDZos-#oYZOOEd1D5n?ML<5VF_n{P zV7$hpk1-a-CQdoIV9fi*fYJz8vY+fjl2o0p^SmOO+cUFz<(P&&My?BMCb=Z|#{+;! z|MdA8w);(J7T^=ccr>xMkF9Y~v9BaDhlQgow}cyoL^1LtY#umUb(k#>bTUkO3BJWL zX;7al*AEOW%K2ob!Hiqu9m3}V5DDzFWyIFi)hE0fpiwr!-I+Q)4R+2h4MI(WOH@@? z4{o`FXugRm^L&b5ziUGG+nFU0y+LaN$s^Qs0zB)ZCfR=kz~Jx%sLrs4pbDWw4As+B z*|Vd{Hz z)kyfp&oM~2uqu-?;0Htm@FQ`kog&m$LC8OTcETtJpdG+bYTbo$iLSvUz|3E`l``Zh zSDySfvh6u!J;Ah!C$D@@SOpCk*4! zbhzEfFbIAZYDA=@qHCWfv^Z&hCR3vQSe8W~j_t`E${r<4E}7Jn@Cqb>q<3zEv@@v; zJR+?#a0q8RX+-?eZDq3;Dk~a%ha$M1i{KZxjQ~e zK0m36EZZY;?7>lDRE(qWm10a+lZRb>4k0>~CG9T?x*!xw4Ngg0!vye@-4gC55Mcy( zr(W+|b_!>67D@xiAkQ!Z=4C>`Aj2TvansBcqcW8mW|UQ*QJYxUxjWg4l`REYOHZ>o zH$6RO2tAkTWbFhiAO=v>qNY6Dr{>uvPEwV?3Y?z7ZD=Pu!|7>i^39xPI-HzenwcCO zkwyVZ&Gv8C_j=_I#|glfgQGN;IeT&BjD8#i2bOO`H`Hs7-M_@NP_g^IdSzE zA01}xlDnkLg8F(fv*J-la#aS|$zW9MvzJZZaqRvL-#~wWz2GGU?MB88KPc#7^C)vu z)47o`S=IBk66+{zBzkaca_R(+OUwY-UTSbo&XLh%Bn37ivLvbR1_v;|$Aor=%}a>0 znuF55xz#E8x{!MZpA86&)D}P#hDhwA!b*@)mNGtU8HXr76MtE666<8IS8(s*a0yT$FmxWkgP2eliBf+ zQRxwKKLcMul!?p*u`z2+ZUd!Nkt|8XCy-^((8E@QoY>aK%cFlFNibq1z^wt_d6>kb zBO*W{{Nl`98Zc zp6bViOu$amq}{nDagZJ2n5BWTYiN8hy8FCJiq>#ar z~iF4M$!c1H?Wlyd@fA^p0-^<@q-dnl_qCTL2#B` zQ_Olb)0*Qkp z8-rexfN=-|v=KU&l=OV23<7lJ`anZPIfAc)rcWy9638nnJ2?@5vXx~Z zKqBIbl-U~ql(L;4hiGJ1HC@eh-*}aIJf)w;>XWaIonFG$9RMf{*x5ZyMJEjEl$|UN zU__A3g45C~-JRI}yHen-DuRIUlt@;O`>E2eNV8xk35gDiCHj-;RDc-0ate~vsR{g! z(yOtsOV-7^nD}stpcqN`a_1N#h1nE|nX3Is&a4Sa5Dm*3k2qcULbwKHq5IFv=qewaf7lgm$$0D8CmN z+C|wH!3V?}IdL4o>+iVB!TKV74 zKk7VS<)8c1*8cfV>^$w<#TIez zGtLDoe<5+nInT~>wAMLiuWo(TIc@EGzcT+Ezn#m^JEyGtALpNUNZRy; zcR434=RdyNskZX=AH0WO&j0dWCxG;q^ZM<4>AM{t+vI7SmPBZc)~R7tJ|gR3Dzg;(ug#cwz30 zIiu_z@*y_4&nr(-&78jCXW)T6cnSL{u5&Ur)M|gmBuG6+VUmfMY?_8BI6ZeCcU9(2 z_GE>J$U6s{bsushupu6gu~W3CtF<2t7{=3hR<6WV(>2=n<&2VZkOgYiB-GUf*UjaE z7(H&Zhg~F`fGi9Z>Ik11?xo1+#tqjN%)npd0;x9^lr;ydN4$XjoF*b#V3tg$a`7b< zJqwka-o9qKilnaClHy)WR`ALDr>bU2nQGDnpJ6epnUb%JhmCX7rW2DFIiWpPlTQR} z3v)>PZD-;x7VO;rG~b zvy+6mm17_u7`{X$8A8lLS5#-uivh@N5ZN_nHm0$^+!eS;5UjW>j}@XTL)wEJxljeA z74}#Txt@f~Fxef;-VN)q&W&g)_mL+mMu$}3blnHRvcb0a1kc!y`*GotzthWlu+93f zNG9I2s0cf=%5scfY!cMTCbriY)dh^-?><;Z>$hFl1ccTwTW@4zAgg)`f>GZ^A2w<7 zw3Vl@N}NicWbt0hOiVC}GV+mQsXS!m=<6h^*%zxKidSwjEqsW>#|0cRcH^*l-MVHr zyi#O@&zbInb2}f$47@WRswb@iG!GjPX_R0slN*`wEFc^sSQE$LJdeNI+1A*csFD$l zNj9*i?5a#dT1w|);dL&)g{Nm-bG*MtX&PK}8-H?*jou{lN=8ZXv$S@jGtt)26vr)C zO-^p6vT0*kNB^9U1>)PmH(I#ZMcisd4@z!f^TDoB!ni)}$?sL>nOo7;x<^k*CR23N6mc0jmq8PdQYrzDAWgaI(KRVqP-`0R5D*L>%)V+!+V?#I|XDc_%S$aOe({0CTFpj}MR-|ZW zdtH4H5j*OkdYQap2pQX>C6N;$4?@21T7+iRztN_aMXJMrXn>|+hZsJ?#f>Q0(OVb> zb7LM#m+8XrxsV;+js#@^8a=~VZ)`sr=ZYtMKC}@IwcV(X(2R&KseqhYy&W}NibU$K zcW@xtgd83`gxJaH0?}Omw9ibk$YoQ8HQ3qE~9}cJZ3gB>h z(VUaxsm^)0woiK6Q-BGeI5kaB|+>`baiTX%2=F$tZ)$D@#jW>ofuO+PtKLED) zIKxV{MCNRzl@2w4)}s4^l<*Sb`gOp|bBz&-1r(-;v^-0!sKzloF3&Oh`c^ zq;y*8zR6m0Qd=ipa<;IQGYLyFJ-e`?XI0wy=}Eu~n>K}uQ}_X_tezvG`8*}HmqRu% zL-?Pc+@4azlBLD-%2&?9rX3O2zf&6m=O#CmR0)>@R(G(IdPLdhdG@J?K^-LGm{Sg< zIabjAvH?eSsCc3=P>)? zTh5ovtnRal7FNwwFCLj|0EGEjR)hnqJF|fNN)O1uCASC!q5R?19h~D#Jt!QMn;*w% zGiLz8!PT8)v}`<9kDmw3*trb?KjuV&uu4>}?$cCZWU}iy_E(Qv-SL398#uDgjnp59 zR(Ey|HrN22N{JF`j> z>*=YCcFy=T9$DP8Cs9n-GE<-%dWhBgz~X)ytRO03jfC5iNEl0s!upPpe|3iSo${U| z>-%13qN7f&#fZpQsH~@sU)!7FRn$)!A#;yoSN2$6x5~DTyXMMf-!X9qEcJqb3{f#D!#ExIs!ytt_Uf2mllDOT{&d?_Any+FRQp^V*>#n2q zaN(jkr{ziKWIv?f4HsCQbw-J0>Kzc5d$ zSV>7=5->KuH8WU11m^B?Jrc>WjG2L(+PsFKTxaKr$FWeQRdwqA>8iPVp$??pX@$iC zmj-y){4#AiK}@h})<^A?D889lZA7(qoSoZ(rV{V5aEO11=Vou4r?j)1-WHb zMN-$yOZ6tMN{pC!k}@l6Y9=QYSlX$)5^?Y2rG(zj-JPw@tmmeH8SFaH5+8brhYFm;eUQT&Y;74B zgvCkWl0WWcn_!z2+EDV4?p3VRM9?N3q^cl-Aj+iNx8$HmJe-6qFYE$^Pe3q;V&vID zN}_&oOTfPu*|Pkp%xTv3Ndpz60^$HC-A3++PV6EEPwXj4X&(`AO5nEVjqReG#5?aU zF6Ra?*tp^Or3w zA#x7=F&@0$80qO0tL{rdppUJg*K3OL#L?(k8i?lHQrCdrT`X43&bW7UbBq*?#^lnD zo=1P%ZhNhX%c#hwNXiJ!&R!g}1L~suve3UHcq-Y^t#GsSW@1Glx5O?s0El=$QJM8d z!g7?_LwiCL?XCG*Lx@W}s8Q9WS$9kOJB1pF)`{-B-F6M#I!+&ZBE*4=8dV)6$SFH= zGMo>goo+^BEpHHUir`BHsj{k0n1UGYR-p(A=Q`%c?bmMLzsMbNP4kbe8B@bPf-}&z zyHRhq+pb>^q6YIsR0Y95v@K_Txb3^cD|oO)f^S?4qCul^S4W@#*sEe++jT08gsY6w zdLq0P3D#X}r5Y~{3|Ap&v~NHrhE1r^YuLJmV7ATw{_v)>$s4bu*G#KYan+nf%(9YKD zH`)+Efv5T^r0j4_1Wh>{IuT?c4f;CPc&N~g*ILxFP<017IZZ>o?>NK74VwOX6N6!H z%tPriQ?%n;(C*j{wZ7KS5e}c>tT(a`Z$Q6woDXhv1Y54%=%B)oE~$X0-4pb-*Kmn@ zz0oem%X1xj2tYmP`8?5WI)_M6NL2^dJKCFGYmJz=TIV|U!yzObBjq4XEKi4En9_Lp zz$rC!6f5<4j3I?zSF^jdQ zv3^L~?Ah7l_dv4BS`X%ZnXr+BQj`S(6k;kZ%GDmfk9)IFs6wx1Ze4?}goy@1r z)+WTR2{a&=Ei5hGW!;-wu$Q;7k(TQcG#@)+7@f!uLtA;S zSJKIuMV9wj2<(-`Mee9A-g83xc zl_$GBo*V1zOUYJaYNk-7B0AyLDsMU&;`@e4z&mQ>H?!%HKBO@q1mesSJ9NV+_k=(k z!TSD$*-~6LDL~RgvA(2~M#8r9bPG$XYQqAIyG)@8z>W#OJQ#3^z;0t8(IZO;G&)kq zk{*tlw?P(ou##F+p|bq4=pP{!CQaEM8|{qurZ6Is9|%0df^TVyF-~jeJwRUEnxRDm zX*=7XL*3CnvAnME65{}(VPRK%L$(QBasTl4*kB^gCN!JL)Va01xJVf4q_PF#<>dx4 zwW)cRyt{)+)H<>{G%^s1^ego7C|lDgk#=T%ndt!4OiWEenG$NdA0vO#{}M}I#W0`V z7#&VTVuO^xN=lvczbFpyhmlH6<|}h|W&M zeMXiL%0vB~t?fOe-_;ImrKlp9b`$oRHV{D_+i65YZ5@3qAaeR}TkB65=K}&o*acZn z|6-rXu-hAIjt&s^8k;EstC!^WfF50eZmR7ex^w>q9hC^S#xV-=DX#)49BGG4{jeFM zBNR_vaZsydSwlc(?9CGm9bK}iAig<|TJ~dc9e@;-LU~gNgF*G%-I12IE<8c{eFbUP zzXgLsSKQZC2+P@r(M(%&s0W9R!YGnF()E!^V&9h1oXWV;w4$%8y&>GqLP;1c0$`g? zCm{rGtN7HEZ(dK4$o=wuqUUE9p8gfA}#~oww#`|uDN8;P~mDjgmr%99% zqMjd+^_p?lKoT#As1X}|iPpxpF6JF!K?v24sgfp?x6lmt3H@DLptjZ<9bLVrj1U<* zj|eH!1jfhF=DJAF070gz7jQeSI@& zPi7Np06Zw>gA+&*91&S}Or`l8I zSYoah3g|uBX-=@at_Zo>)xvPbZwB2|zlU8FrMyFA$&h^nZ=gGZpaAaB*;(CnLKB=o zE^htgCM{JiW7aHDcRfam=wwWP)m16M^5^{tunOXj0q>;T5@IHCE<o1zWt7+=J_bY85vHCy&KLto)1mGwfs-LSl)gj_ zd!Z&444q1Vdh<>YLA}rytZ1zGGWXFI6{D30Q)_FKm^U_)!Nc3YB2nx&#x{=|tHMfX zbCjwv)neE%#ycvVCx;NW(8JXPD@T=KoA9J*@;;w9)vRxXmIt>7FhpeW(N0;Vv^xmfaWrXoj6g7dRK%1$Z`SC8oH#j7;5zzk#I(exs;LchXL+3^dsgvdDE z8*-f0mt2l2a;VuDVRdH@mB=RcKp=j;Am<@uu^d8}@2=dQjO#>--5nVEmo=4B_xxGqEp?;$88xO)U z7OPZ#klCZn*VCw`c2Q8D1P#`@v8&}lG9$fY!lpV;Jg?we4!RxjcFa@ls%m`~D6rvL zDbb^8cL-Hx2c(TI#GQAakYWoe#^lLldyH2x_JuG-I8te=N4!bZ9FAs& z0~sGL0awTgY>bVJwvUL|#F=$C1ju~BQx~|hwM0HzOd{46As>pyu?67D{=poUDDYFu z3*f|~z?FN;pkhUa5O5w7M}e!UTYhKjv-3pZ6vE484+2*>6d%SOP$Up5HbJ)L2rwX1 z?nAg0IX~toi`a4~3hCPNGT|IQpId2a$;(HKf~64upZEjOUySm4S=&ms|5Hx!zTAV)U`t_0NJ z;g(j`6)koN@O&HK3W%q>?6qx%7CZaV+XB~_Sz^0xEzLpx+#a|x5CG_fS!j)00N2%3 z)C?hEWc0baQ{=j}%7jqFB+{k43E(;nZ8i8E;QAfl`VR`Y;!h^v8t(1~irxaaE(^F~ zQXa1dxMJ39;NmTDYiFd%;MVG!qt@jhQP{c+Y88OK1K7IP6z?HZ!#jkqC^lp0 z2)9SANfXQAPEhMGT!V{Rl}@ApZ;PmPt&Cdxk+Ty!W}n8587o6el~B-28|_J`l>)M@ z7iuN%med2HAF{#WqSkHpFe*!V3t0C!&`Pvexw0uLs~0OHa;IWGgT+S~w8F&_56j4C zTa=tToLR?aRbi}3pw)Pw!w1gV3!6loblKDbW@TFp%m*%>*@OaI0JEB?3T3jDTjOrU zRvA%2F|k#M7#w2ILQ7;TmQJpt-1-bi2>xywlT(No+yVE*qsrX`9+k~hAEENG%Egvf z)LoHq^^fhB*;b_dc&Qm!CGK)*Y3Al^D;+~#C+?4f{fw-H1Z@_kbKLw0YBjR*y(9LI z0zrux1uhAQ;@~6?Co-cJfvY#Sfz2({EZ~lSv0|FZuPTT)JDwt|C5b$tODb4b`7US1 zh~6)pDS8&+;Axewl;9=2Eo4hYl{S>De{^R!9_=1ekPyflA`%cPcZ)lv2!TWZe%=(+ zXr*{pL3W%*M+ZB@JrKXf-gO>LnGwT`Y<`9fS4_6VbGn79AT_o}`eV`FQ4*pqKpSK- zE99G+mF1VQ+%81cl?F`CQ-U4z8x?Qzcq!e4mD^2rng?F!wiEII5P`$&R_ zS-7`XJS|H0jw#B)#_(VaW>>K~#JI>JmyO5F&SXjjt9pp2OXK`_^~Kv_LnAPh_AoDl zm>YOn_V2_f1qx#Jz~)d-q9Zl{ovswSMLu^|(RQJ#b|AR$q_5^vA-ZU5u(z$flS)P9 z?9x%9mJLyBXb(!ELrd7(zd6twZ*J|v|Fg=K{ z%Kt;aUh3cO3^lbRpeXnNyW+aZkXX`v7#72PV#F@)XaiccyQMMMrJP<~GIxoevfb)O zcSZ~!17T~VX-H3^wXUNRn_ajY<Eh-V#QeCw8ea(&?IZ zlw|#hE%uL_ueB$-PZ=q3O+_gZ7&5mR^;P&Td3U6*-vk*X`{-C{RDo=b<;e z!}FpUfxbw0MsL(3i-EWL`#9kxBb>>SO{d{TxU;*v8bVRDQ?H*cbBSOm+p#(GX0~Be zo{$}*qNu6XD)C7sMJ2YAkZDJcseg}9brkXrtTJg$ zq#Z~#y~KO$`(r3kZHPm0hHj^c#V%G&{2{z96MiE^2xIfYR0?bx0sJ9NtTQYlTxQV_ zkeUnH-Y8b4SJp}UW6)mEgaIG{c$!X?)aD?eDfv>E@C_+r;DAYe6}9<{jC!4B8CsuB z%v8EkM5CjMjtB*?M>)Zrh~;cHQ8f3LjQ^Q?FUF5`;25F#!$JU)YG_kO#+Rl#7)!3;k+M5$QX`0MlkEvO2|6*w# zu(Pxa;X<&hACUQ|r zC-ljnG0ML{OVk^rtrL0a#*|d-OR`NH0-4CwgMsMzf|$n;)4a^$UL=OUI#E!Q+bpWI zJyH`rjby%)?=3mQ=mou;>ah*vhI!S-h8b$d$jO4|u-H0YrdksSBFqggV)v3K=pP-s z=XUCf+@rOeLEMr{)E>(ZFimBBa{^lqak1`m?`!Sh=4K1c6&_8J6boVO8n7M6W62RA zRIkhmi2uut2;#>ptx^oKHtB%EypBn`XV=69Qn?+hAh5*nMYgeAC>Is~YaW)83o6Mp zN~OEva?`=(+E^bbln(!|Xs?)m#08th$m#soFHP5J4z6ID-H7mf5B^=RA{Jm`mjdFNUMIIS*E%ij9e3#YmFNyYUMbY@E7e z?er4@AcuuReggY=G9k#>M;IUdDQ{;i>*b_4^ZYS?%OiT* zz4ffF7yl+G6@L?RgQw7S?l@ok+pX`NNRzJ8JUrFwPfu>s?F^*fRk+zMg{P&9E^@oFa1UjCl;~)741+_f9`eV~iGOR)JWE6K z^ev9&m_d4{_4hV5e-Qrs&7+U0r|>Uif?&JC$w}GmJ=^1+T$>=5kKFRHjbC^+@17+3 zC8`k%P;O#sLnqY}>l10d8AP+d)cv{q%hnZ2ahEKwGhZIguI+B|Z+mBFyKu0pgYDhY z--iw|8I@1-Vb*JsomFX5-W=>~Z|@vBD3>=Eu-NDJW4@7=WGc6~xwFB)t?li?!InAL z+}_$U7dDF*iU$hOnj_zlccdkincUr>p)}R~b@X6ownae9ct)H4U=IqA-!6zI@1(ni3YrR~kF zt<7!b4hP#CrGuSy&J-?`4v;XSBZH=RGCj#mIovO|A3N!yE#UO*X2py-GH_crn>ucB z3_p36zvtbXiRHU+V7}_vX^p0hd%&|7W_0Pm%yCvVd$^TRTQhHr`Em4pIp$1ZVi~;O zmQ2rVGCz1-HBEG|;~p^Z`g?Pyc%gJqknj$*FyXUCrn0zOih6EV+^tZ>lj+4mv+ua| z#SepbsCi^8w^r;L_pLV*N1b*1&a;PJ_V`9qb8ct+Jw{J>XDqwv-ncYpN(Y5GbMv>J zFqC8Ixg(#O-JA5pkrtZr8(Z#2w)obYS4W>&zP5UUO0SMyfAhxd=+)5$MRUw;?f$Lz z>ydcHi(C4%(+>B=-TKe3@kKuT;tDz`5+UY;ig-Dju7FRobg}|Inb0<~8{;H3 z(#81#dRi%=C(h}l3!het@JaQ|9uJ?`UKUPTJpiA;V5a5*dQzlH_tY`q2|n(4@HG7$ z@T6E!|E<82GAsxzt+SE?rvxkECyVe2xI0CfFK}@seiEo9{{8T?FP6|#7GO(&@+suL zR6Hs4gi9gS*6F0s)0#m~n7@F`{{6FGItZU&DaI$harKJ%SNL`1>P`MGUZ{Xi5Y*#+ zUn$F9)}d-E9q5n3_2NMRK6yvx(1>!)ml5XQl`HOneP!1i*jF+KFBB!p_-P*(2m9*& zl~=ELukP~mxZk?!ySk=}W#rTbavHmG`N}K&yX^it?w}}f#R$G4Te^jFbL@89GTH9Nf|<>%fe9>EMcslV(TL9sjO4 z@TIBXy_!0H$`vI`Fe&r5beDSUDg#tHxXfI6#XQNO3k3-mCc&f*mqy5Un}OQVfR*sk ze<G@yK;AR(*S z<nw-f*25#{EGYPmaDz_t9)pN7!VV(uNEf3p>Id=8+K@l{8#tRz^6Yh zd?R&dUI2HFm^Yzt#x$w&-Ed!bLgUzRhb}0f zkUa%@fdQGFspO7aW@dJZIEf|hNZ^P4)^U>J0emwmQth= zDzZk}Tr{jvwtr~6z#6&d4DcDyY6l&oY?zAO0K>E=*2tTKrEy84y;&F%fKT85XV%EL zTb94awh*|>uRDd7Dso{!x0Q}_gFl|gJXW-c<2s5i- zm*W|54r4quJ@D+?*A=9ilZHFW?%{U&7tg+Zfs@1?Y^z4dC`I&ds?hzttkWI{yz0vgb z|KVM=WCi4VC&E9K`4d`ssG;TlOdafzg5dCgF^y)4=zmYGoK6gL@q%Oz)l`1un?1W6 zigvX!|DaoyXox?1=do24D?f6N!UaP^?2#1lx87T;)pIAA4pEWcbeq4{xl~p7zj(%U zCz&Z&DBoKlsM8X!6myTgLwhv!|NQP+LIDq;^`|~pXv@u-RBZB*j*$VvXzIrI)Oz}_ z6Ulb$pXiD8??_F>3peXPOw~tHb?>91y}^<6&)K!J$5vDx)9kU=l}D@Zr)nSc-se32 zP;LIchc47!beyN2vF`lmT~0ppmS?QH9Ou$Y2i;q5QopGGk-eH|a?m7K(cAwYJ-!?zrVSYaUymiXS{};c0Ie+p_>!g!ken`KZ z`F9=qncw`U@09S)`=3|EAAScv^BW&{PB;64{Vcb3{O0G>vtNFx>SgDp>X)tW?|I2; z$bYlUD8T5zB9DIk>wh}8yEXf#U;lct#6gq}N@RpY-J&oOm8^7!ZS9TkZl!E16e|@w zAhEkuX0o9wAxI1xTHr^6l+W&LQ2u3WCtBdHi?m8fxPrunDL%;1Mt|fvE4j9vwx0h` z_Yqp>peT<6pR&1mh@<`stNQ(`N$dY8kw~S3~5!-!SUk2-g5jlHn+re7ROIBIJ3Q; z)C|sskM4sU5H=emhg&f6)vtYZes_E3KYs12sXJ;xfp0xRR_~N2ZgD&0IMKuRKQL2n zHgigEoxSt2^^L=HHM63?W0ww!gm#&ccByG2diZ3S?mj|@mqpz>xT3tn=AT~XV-JcK z>>aw+{No9VqOU*m+{*QeuG#ot;5p~p&sZxrN{`7Deh1-ib@KI!&%lN`>9w{$_*Z}Z zSAYH2AN5;XSHAHL4*&9twzdAJfBlyn{uO`!XZvtvUTg2_H@@+0iv9v0!0qjqDB9{y z*d~fj8P-@V@jOM}P~!@O^2R&7)^c!b^V^nns-;Kt@a{`qYwB`n#{J+}>UET?-~8xDfAZz4S6=$bkAC#?hxDzI zu7Wl^_2qa{iOclCIc|Lv=nDZluum6~Oxl5Stw zM4o@BoMjSY8D02SpSWoK<`=Jg-n#qoU%xdAXJ4&9qLaV!)0X{~FMi&7;gu52QD9My zigKn*w5@XMSFir^habA5*Ku5b#(dnL7MHz<)XOf%3r$kLBn=nB2b%qrZ5MJZ>5q|l@?Ru%_U4ljInt-`muDNuJB&oHIL`LyrL zi_XuJWcw3#fsVJY=C54jW6sHyUnoglzWjyu8fcQhhF&EpQq@%c-SjfK1k7DQM<3c^2-$c-4ZMI1wQ7#s39}6lTp3M z$NW=QF8{n`dH>am8mp@x zzNLPBp?2*tzimBrsrIdw?SJCQ+Qzc7=4w=z?zb%8rKhY1$`@{~&edKzU%U0lT|V!V zk63ScYwcXQOrf&c+B19%@4T)jAFi^jng^eJru2L}rl$KDnDey5d&{T0Si5z<^~e(* z|HVhYTZd0yvMsf1tJp4YZHDR|3)t3MYv1;yBT-0_ENxe(X?n$1(?0_>_I`mPYoTd+&Yf$;#$Mi+3$lbfmuGSX5m2p<@VvN}}LI zq0d}K;ONgXN6>fZ$+$_yeF}%}uT!;~#il;=jJ@)3Ns>qQ2W;md-qVLq);cz?C&wEP zl{A0*l6%r?Iey;*PPN~1F4zz3-T%P-7i??y-Um3~^nJ`_Q=Wmp@W2BP@kX9B<8dDO zN9|fo`$u>qpDwlPZIpP(F3cOdHh;;c=%cll9wMW`BTx89oZz+gFFf`(f9>wmkDa&P zR$c2ndrl{TwCA+H+Cgs;~(#s<;$$4&uU#Qqd^?Kcn7J{$EPfE^6ErO0=;= zsL=O}P9Aqr^6u`(Eb9+ZCMo}MX=oLYxG161TsWvEbr+06bpL;kZle3kOrrul7bK2R zk|bEH^v&PD&=A*N=kIfWWAjtIf8GCO{mQjBuKlv_ZyL>Gx=<5jRoNiv7R26tG$s zG!_MtgPtx~gP|uChN(b_vw(t5reKfvTi79Yi)dz z-$teWlJ{^0UTgQeC1-!bd5%>;bF`ka|5S5z>noJ~UyCMKAKJNhr+o(;Q{q~{6)$3FVePXgCI`O%M};uvsu;8zLB9Xj}}V)=Ji)udAH7(VM!pG=`F<=4#A)zw|Gx@3Mb!`@Noz{W5hPeCDzti=Nzjb%md=mb&uy z1J=qH%wI*-#=bILx_a=yzOtnLcBQ47xf%U-@-)863y{tA)E8(}i-E z9U82{JXxa9XN!Zy2^XDt> ztg*k9_IyNCO{nPdO1-+MI2V5((z7>J&J3aVcIq#Z$1B){;&*P(vS426Qgv#5S$m!_ zPhY8Bn@7WPOuxOC*W9OfweQC+t~~ZdQ^0+1KY8}zV}S0^{M_ zTpIH~=6igvQKH|;_xL>=nLmDnPxpcHe2(uoS6+DGBA;^2w_l>@)0(1JK0?v|Nlnqj z{0yJ+d%svvpe6SS%3k7vu0PJFTtoD`pZNjnmwsK3a+SilA2&z*cx$nM5P#Ye(@4mOx);e$HOpRq-wK!*8)p*$?fVwBGW_vqm38A$lfY?LMQ5Z}*UTLnUHszAcHyzh)g8Y}t0$qv6DJDwJXgC~>V3DSc(DUZT4U)zCC$GB2algXtGnmk zd!Bx-w&AJc1S*RhC|P;IZPyQ&{weO8AHU)5uZ5RT(W02ER+m-jN;P}L6-E5Wor@21 z>C)*+UcnW7%wF+VKI_A0?Z-&ccZq&`n77nx#;#E3!@Q+ZozL^CdHMao11C_hPX->y z-+z}f`A#rWKUd>Ds!vOqDb~Lme(lMh_`AN622$DnN<{C~8WLdv%c7vsX zRCLdwZDCh_EA)py^k`?Y+`DvhasR(`z+Rvk9-epWo0j#o@sz6=ozgJrpa{aLf2-U2 z@H;Kb|6%V(lA+?}ZqX~rsAw*rmy(LO8T~sLCL`B+3m+2g+3uO)`RdpH(|`IJ`?FvB z>d5VfpT{ex9|e{9!0_N_<$A5Sx~1EFrBSIos2mlkPZh(@?q|g|s?pnSvg7L3Uy{G= z4lD9G+Fw-XjvUxKD;k>0_V9w<|J>rYjy{;v{eZRjt@1=GK7cv@w};*XI(og^vVPyy z`ChfH^jD=5^8a7|)t~z;>zH~ZU+=owu>GFSN)I%O-g32N{Vn}#2(AJ*;dVr5if&{U z&V;U77_4ZXF#%VR|GT1&S5W?t=fPgmcj(3Z$E;_+lz*|}N6kl*|HgocGN33Si^9RH z_LrO&`3`;R=5i{0xga;e#({x)2JM(bqm^;azOu*P$Zfu8J^thqPdxbqB(n3Vg5hp? z^H1owV303S7n1!B-=JS9?RL00PKc=zS5x)=ixy>9|IMeYXMglJO8ZkqMXP|}jr#MY zJymUA9=hAIehP3_(56a=`bgDlRDJd8XMW+#+dlrU3+?kC+OTvhMiAZTgO>Gv9`{yC zRG~Y%srb`B_SmV<{-!$8XvZa8sdP}hz%xo7R`J{y&4}E5SPVi$e(Oc+$$Koz^Q8UM z*pr`D*Oe^d4wrKl(h*iw{`N$4kyH?qt%*#eZ3v`0fFBTz}EB{&7JW zv90BwC~fckvJUBj z(q}$oVGdE4YM6ysA1|sNoYQIKc_j0Nc_RN7>)E&GpQ!jzbD#6n!?oVGJ5MmF9xWdg z_bd+YZ5c)5?fXwyes917>~hO&K4AgG_>X`PC$jR<&c%NLkDx?xsmL7_7ab=IvO*z|-~{dJG`-W_xS_SW>ooS>z{ zZbu#8P3EkAmcj5l7z@h!Tg_c{6Lz{bOLr^wEz*xY&32fu z`_pWPv0Lg^!_&VMc;0&M%g(Pp=Qv;fZ~wpb<(JNUzvT>kz{(Hx^P|6;AAMclXYCL4 zCcf9&BhgZfU%g$i$onlqYQ>|Wzh8kq>K*9iM{g%TdJ^2BuiLFU9^nq%iAab$bah6< zL34+Th&?vSkN?s6faP(J|1-xy@SZ{aaz1W5@3-=&^S1N2HJMG1b`K6KD^xt%(bm%1 z+SVQ1KniEv;>B zWP|C55RXX$k6QBtKkn&u^YBJHTAN#1Nl72v?T8bh+}r<%HJ&BcVYkT%9E*n9nvDRr zh!Vxi*Z;6JIYKD4uE7Bk^pK&ay}8M4V=&yU*hmjsTLeq*>LtCFomhzmo12u7Ck;sz3+{;Ix*tZDoTyLf!%3ktV26)p$EcF#WX;e34$ zTJssD03$b1f}B0U=EkO$mR7rMzawsfCVBfFux4{4VjhS~B&JTF79*1nclk|Bai{kI zYXMinfq1{^=t#J=kvrKfORa4k2?7-npN2#l{J7s*Stn^ocegSQ$7zw>xJ8TA^9bOn#|Iq@$&w zzOk{nnUU%sFp*7-+`Na>Q1>F3A%|LL54R>^QCnkOgL#nFwrBvs-5wGYAvHk^`TiLB zs5(jC%YEw`noJAH;OwV`I|+jGM5FguE9vB5f2YEJ@f@LMyTNI+n>?*sK?3~fk?pSS zM3_uZ(bzrK6anwMV@lN=iE!h3J&eXFsyO^M(Y<0O6;kA)wLC)`d*TFmV!Xn^M!Uh& z=xN?;X$_Icn>HaFB_EP6e9@ZBk%*LFLOcx})LdWJVEU-JJx*+`&U`c+2sz=qtV}LD z($^iLAJvg<4R!TKuDLauNRXX^M5s~Cc%KoT%#QZ=M7zj}6%NtR8}$-qd_u$&+e<_` zLS6(f&__IbPgE~eC=_g}bLCoE+G0d*+f8(|yMpJfZDpocj?kCT0=!CSXd&p0+m z%+n+i9Rc!7owvsDR_TjI$#NDA1zYRu>hvF7)IlIN9y;F9-tG;OBZ^#6qTb~cjUB2o&TGtUR$3{i<21Kt*b`wT z)$X7Nyf>EX)c37~PmRZ@vo+9Ww+Di!t<|xi-p+7@Z$*eoeK*!6*BCKkzSgQXPrE;O z(n_Xv?^uUAl=|wf-?+gbaq|#~&LizD&CPb}UR!%xTY$Env{s0P)sqPFc8BQdM(+(z z-71gO7LCRut$Y%ieXSlNdcvB+k*KdL8bXxf%~Z^PcKvo^n4SwZdz-fPGV`TX&4_E} z$H{ai@s_%4*In`5c9NR4`vgFM_F?QN~~*REYxyX)$k353-$H zB4b&DuhG-wZKeqY*`4H2Um_l~!#N(X>Dn7_@QjReBgx4c&Fj<1XNGT~zqPu}X%AR) zV%FFgr`caD(d4yOd1*T%?d`l`EiDc9Yo6EFH5r=Bx1rwO;BVY(YHs2tcB|cz zZ^p=bMN4cf)Dj9(qUoB7?C2g%^)_$3j}o3H4+T6Fm}g>Gmhwr*!>z#%CSY@&_ce!Z z+P_YV7!8kk4xcIEZMGXd)`~J*MmpMp%*-Zc#A|tVtEVo1ofmso->Zrud(F&NyK%xA z9t0(YSdZIi)b($F`?c3KKd#qZ*G)8Z>aN10c$%C>U&D$u)ZZ14bTo6HW*Yx(&ujY( zx7U>L)bF!ssf@!M^tJ3Zvlcgc82B8eIggQtF_ff6x3VC`+qjrBKln>|fM_de<{A5+TH;%VM(tzhNJ$C zzxx&~V(Px}hIyf`OWs@W@D%`aE*6(j{~>eTsHYb zL+$z$9|X56MR2Rco8fl5)pG#bE*G(FkC08UP1ikO-x9VZECtw>Z#u~{qwT`JYGDc6 zPO?gYZ3h5bd`^zRwyZV%VB6kq${&Mm3EM1etL&#Y!M5qK0fTJ?B9FzkL<%clTRXAI zn|eI9Rl*_{+mcwPjd%NaY&*FIjxpF4c)$Zm@OW%XzX;nZ`)HK8h2ZhncA0?H15vQ8 z&^^z{m#BI7SZtd~YY7M2g2{MP-dTb4ooy6}e+<%UaoUXV`Wk zi>h&F*fx7-*fyI1=G-Z^&Co-4fNfJ_Q`mN}KYmBpb^&bL z*8}d-B>E1vy&bltkJ{UtZiQ`0&NSHD84aN;cLYJr2HS$+nxf$7qu6!@&Atne7?pTi zgMDKixQaMh%Ta8b9OF}Lur0#vja2Po+ZNIt1oi$4H66gVp3w|2PS}>jy}=eRyeR^P z=i9=ve-PWIco7V??Py1TxD~b)B6qQ^pbV?)EwC-`YZ2SFwcNNZwp|8F7O*Ya4Jhea z{tmG1;6EsAJ3R2_u^FyP zeGN-*0@~X309#hJ&i)~=9k>TjCgj)#sZ^qElWS;{g9BuFMxj*_AK+bO2Z?9l&lOsceeNjY6rvun?iA=QRjtbV60POvJ(O#Ar zJGv8T6_sQ+Ej72a$K0smMb>s`E;ZQK*(n;CnB*{+YLc29Ez`S(wS{9D=m`t&LyERH zqN_Bl3u1;K8xOFyxfDEF7+?=OX4uPm@wQE{mq;F@ZBt3n8C{~VLmjORT4K$;!*;@3 zLEOTl_xFZHtwqC-I%wpma@?C+cbW`DCF*uzlq@jucsCCNqXTm)<#nUE^;qhb=jn{l ziP4bZj1AoeSU*bLrf0@j$s%NrpqZf{+90x00gj<=iJQ|Kk7;g&I@;h*MIX@GHbdRQ z@CKnpp>ESD_=6ziDSUN@5P*?uYz|jYx9#w34#Ff>=_Qr5_Bn#VmilXkIb)E5F+Y?n z)NO~2B;4)TNFRb|M6i-=4cA>k^p8l~*SQaOYa2nhTS(sC&h{9}mAJJ!@AYLvb%tVs z@Nl<5KddO^ExJN?*ie_jwq}78{$qYX@hOXiA#d9pI9dIF&PtI}wKp2%nP5{|8;rD` zzBv+u?RCjpxJD-kc}ofbFq2Kx{q2rm(+!vt`vx3HV+RQncEL?;?S7a&$Xn)8cPvP9 zE|=FpI9dAtH#91ff#5Q&kJDcMq-oQAEw;1o(24j%g&Sc{G&2MJ%lF9oeZ!+VFlbK`^ zuL7;DeFY=|!eGGI*k&<{gw%_=@B7v{_x7R%NZx#Y|GfD$s88QpXRE4HRi~=%xpg=? zjrSIJl?%(;b$Yk7x8kSN-dk}kif6B;8BpWBZNOX;pWbBkCWbf~hkyaLU1LpEmH6~% zI4rh#2addOV*poGPSa$?t9g35Tg83ag5L=<(16yo!}lEx{%|fHsz4JSTqKCNz@&S8 zG~&U9R1Bb{0}n3y)H*9XB0j<##)}7cx2%z7!V3(bu@) z1t4p;I3QcFD)IN#10)X8zCX#aMqc4uAKTngTK*f z%2U2K2E^VHZzwhDHd>YVdNvI)&Gxp&YH_F#SMi5!e499MSzuebT3YctHZ;~(S(Uy` zL)CCwBP+9}*20OBfZ+o;#_)uzBW@-Wak4;WeuH26cD{!h-5PGeV;T-uz4q#>;tbok zvA(6=p8@U*C+lSjVZ6Bb3s6pIC0zVDSRi@SXr zhHhJf)qE6J*rr!r5f5Nx<)+4lD*RyLZWHHqz^hS<7Z=w&>YIpYV|{(K^@{J+lQO1S zEhMS})q$E3oMv@7^;X!b$3uq~SNz;Wl;DN>`r6l}3QoYvO|>jli)n}t&qoDZhV@6_ z4yATrOl!|4Ojx(ce#HSziAqM~ZfuOln|X*Xa@%hvhKgIi`Zc_Hf>z%qA>PKg-eAep z#Yvu1KO$<*syU$g#Ul%yF|Kg^zKpL?_@i=DrF0^slREBHd^k1z)h84a=|lkvH!=8^ zeXk@Sx2rH(l6{kTif&G-S2Ly*q)<~r%8rux;F?3WV|QR?_MjUZ4q`Ss9j zjVf^hR-LHUy)@DdPTY;s%?OTJw;w^6pGAS=yABUEo<)E4k*(b@!?aYHZH+3stjURHaCgMS5re5mYzwVGNGOR%)Z*G%GIQ|YH}D+71M64 zWl_{tSG^)5iixXOSj*A=Vm~fZe6jvot2$8iR&`BPdkfQTgdA0`{qZG61na)`n#`h7 zdq3?ehgk&hS>tT4q0W)&O>NB$HISmZdeh4<=_=N%F{%n+QlY)Kyn))U$c@v%3<9yjjD|~!Z&oH zDi^5ar%%ju$SSuUpT(E6uE?3Ek`Ij(IdfGq|Fzl99F_ES&f&}XUvr(=D!KSQ`Enxj zoFbL{L2{lmQzd-2CFb+(DYL^QC+_zy1p+mvNquFXx{=?BuBA$D{J)BtPN=RPrZ$`Bid8_Z56OU-+m)p8Q1# z`EquA%&}B*W#VIwkLLb(C0|ba$DM?_=-9`dq+?k|Y(h>lY17 zSX=({8nTh?xE(Ekd0$jdK;C!83z2<&!)!ss0n{d7gtg@jYYE%|Ht#-~M8i%`e(#WM zQ!o)3n$_aN%H!?R>^+FZdoa1YMeVpao3VRZTG$Km-`^6ImmIOjvWV{IZJpLLtWyby z=(pJPWQi}Iw})--k=M87ZJpBN+Y*-?f;Nk&xw${WTZ^{JE2bu4i2HhnwL@FnRryr* zHAhG+=p#DHd${yVn0V_MU|WYJ%neYp3l;~gr#q+1&s(DM7_*P}sL2~a#X4^ZG&`7? z(pns4+{MeP0-0cXQ-FN(z~aoUp%Rl(Uh0&`tHuhp`0(tDN!?8F)M~bfs5*r5M_Ot& zwF#WO%&I`%*tLZh#7T1knMWYq*EB>pg&6B5BB>VdGcAx8aBZn!OCkcq{~=KxT>)o`Z!%Vo%!;@w62_PUl*Yztk~v8 zjJA9R7sbjII+8&|n7X4QK(D?IX5#OT(wuZTwQ0DyrK!4x9RVx>7;lRTbnqtkp)Ovx3OGh)js(^lhpE!k z%*&kH@>+7+9T#wrY!o0h)tV9zqPQ<*CMlTY($9?pT`=sn|$FYgXe0CEidZgMN@!vIBNkN`sNm^$)`6iK8O$?wZzxzZ%H;2L&qk>rqX{I zcf6qvtJZGv6Z5w~sl)+UYJgiU45Lv;p8YO30jzK4XjTBYt--D4m@tL(ZPgEJ#|OOIG@0#D zvXS;hQsBDR_)h?qL!?&vkJL4QVHQI{<46Mqt0~4zxnwsdn;1q+X9d*fy5J*?$O@7s zST{ogF6lvyOg;+X#6u-bV$fhRTJ9r zB$xtL4QN6;b%EME`f{2kH?S#@)!zX3Fl*6Bs8!G)N=-m&b~;fg_w>k5SD;Cb7V+hNuV*VbjJ~gRD9f zBua}67)Bt2m81-xq(0&2tFI@whV~`X#3z(*)Z-;#sYyIF$U#XJtWDIjI`uM|(Ey$` zOhDt>-^L!C&2n`u1J@8|>FL9SevnOS8%>a7QPbGy*S8DU+k+HlVvEe+KN`B#*EZBH zV`Fqp03u#s_HZ5<8f5;^HLM0CqhzfHS`n7Cny4ew49rZDIk>16UrY}7JKF8qWPPJ- z9w*U=tWo3;bTAEAZ37+c;=~fkh$ByAl+%z?AJB-9&W1EYqcg<2ziO%z#Hv)J#|5|Yz9eeX%MCmD?p@=+R^j=0VDco6yv26%BMo#-4#3$K1mj#4#=57`r9!)CM29e%cP#dn5Gf zsZBmGqpcDL<6|PDk0$^`&xGq++hv=RY|*CVICh`E5rHqu>l9XBpkc7Fsjflj4A}Ta zAJ$0?@|tYiu|^*&N?RUc^P!hfCgD0vGKU?7=z#(dgzgfPPwpn`@y*$;*@r0ugaw4% zIt0UF`bn~8LH&>ze~q;bShaqXBe>AI(XY+Fs08r7DJ=Ou*%QdRch4+De>LjH3mOxc5_VHmTRvFY z%_j*U0xhYco>3T%G*MlQw`{YJMHa=N8DkdKv2tt-uhE7flgw)!-!Pz?2+W?L&De&y*lQ!QrSPmn+~k<}KFn`SJ7Gn(ZrF%e$FztU z-dF&Q1&AbJ&r;N8i?I|FIuA3B0VpO(vJr)ksnIAKl!(~Ikd06kc7ZV$^XigeZYS6p zV6I{P(Ws13n?ydC(`rgK)4XLW)H04^wPENY);{23FiJSbhXs)XS>R%A6Ul(%HIR?M zkOh`<8kmpR^6b)td>ydcGJB{DOEF{?x_FT6HgWw9 zkRXbYPBOY!q+)Mj!D#abo+hHrsI|@5!|ss(ny6>;Ocpy<(AX$jJpq089&*8mOhLvZ&W$z5Isph>*E-VHj^n*9fpb^(|6;l4@!x731cQhQCJO_~ zQxaBdplzVNgUwZ4eI2O@VvGw@7^Bh{(PHt!AYz4KS&A>Fm0F2*US~}gvH;Ck3hD!t z4XlsW*?6|*0N2?edrIcw!sXY?h#7@gn$oC<7TK&~-wkwjFh8tlJy4-e+Sp7mXiIaR z9=5Oj1kdc$)`n#z%CrPJZE6~5z3J9%``TlGvp+T=wk8{5B6^94A@s!BjD*>sfff`* zjQEM@+jff=evfZ&Mu@lS2Ro35vZK%PE}q4U>#c3a&ErerYLI_To_}$=c2b_iz1So1 z@Ai&X8?l0oKY@p_$LYn}xJ@dEOA!B)VdbVV9!A`eJk8|aYHb_r>miLmg4XmcMl{=a z&&jx1UP{mZEwQbo@OnuFXKT(Dt2f!RB^OuT zad8>CLQDjizsYku+5*1CztzD3X>YNpmbV4hnl_6>C_!tO$#X$w!jABK6@B=+;}RH0 zBl=z7ls_`Lb&K&i4htFpYDPMX=(3tJjnqQ%OX416gg`W=U{WTke+%!A$DQZv&JpLJ z_MhT#5=WV|7H?{4?CQ+HC7F;UgEXkbGsVH>fm)5py4S?pSb$Mmfa7nNXSM_#vWi44 ziF2SKT=}|0yStLzT^28!xA9E|x*|F@3MeijS#XUJSg-n3lqmkYE?!3uqy?niHSEq5 zU!u6B8cxu9Ri&(9*tw&_YR~J))owpJ7e5&ia9>qr>^!)9%33-E4xUt6*r2VqqFc?@tWgF6=9xKYZq4IF6)fp!_9 z)s9;oub$O8fWbzyk`xjS6S^D@H`l!`&5A&15(m63K09hyZA0P%1)keE5;W#PIOKGr zJUPNrY{GJNK?jkkz-l5kP7V)A_u-BF(W--eH~wBWxUG5Z5n%-;grxHkYW1p^# zK$#cj`IZ!5PWupyC2m>S&udT~!fU7s%h2<}s2StbXe+=Z8WCYQg|-r5BG@85MT$0x zQ1fe>iOo0$9!SBAtIrARjF_4lw70Y^!C`!Stp%d|keY$;k$Pke|LWy0kvdTiR=o`* zk{-4a$dlSI)DX2ctrhY;<`FK5Lf4Z7P%TW$HAHLyAO$VQ zr3U>V)ulTExP##ap8bMrxB(XxG)``YaIE!J2BM<37)4FzFrYY0W^GI9I_c~_D%Fj56wB}$#B6H?@`L?W91=>w4` zK2M%`iSc+V;dq;haWGt`YhX{-=cneI*Fa;Erx75q?yq)gB&|R^rX(1MKM(o@!fZbn ziN(0l1q78H#%xz5s>yJmV;`_NSXh!R14bGfB>e%Vs0n}sNgo+ul63|3`TC(PoMd7R z_`-PCfRSi>f=m&f2djt5l0gv0yu%kLHk$^-O-wJ+WUL0JmM4Ko`>2Z4$T}d@ELJz9 zgT-(P+jV(RkXadE!PXJUNw1N70qLM#&k13JXBx*V$Y54_DK#}pEIR`9Mxxg|RVb_{ z0OT6LinI>TvVV($XrZ1w&}cW3w!#$UVXi8R@VpINpkAJ?!8A!lzFI=xzUo9RZEHTrsV&e}t$_?c z9a&czG$LtNo2tWMSsc|o2vtxI?r5~u4>_5zwh|8!3}Jc^!R+=j8IP$j zxi5?)1DvKY%JIl2cu>&Zl&sb>HzS|K`0Egjf)-hnG)<$pMO&KX*+%gqOA3>(CKuev z2G$l}*~_qn5KF?>bb{^Y#*NkRAPFPY8aPm!t6Ma{xIs;`zNQ$kmDTlD^$4(ar03L* zfHTRRVGm&uoM2TlkFZ}{+OphT(|XM`<>X;tM@g#MRNv7t4Gr$=Oo}ru)=4U97xBeB zbTmeCTm2@Iz;Y<&c|iWIC=WCksQlJpTu~kMHBFfR824;nw05TixYap{mWWzO`ugwh~P~r!AMc&L+Nz=*UoQHDr>=EREaB#{f8L|5?zibqSk!QeM(l*Ck76Wv{GV0>HSoL;fLpXb;$ zxR`!%qRisI75w)an=vq@kL=Yz!HyJ2poXm5@6(D;rWQzJxCAz`wsL&N_8tAx zls|P>FCM#VNHVau_A<6N&QiE|7 z2_TG-r!V_=Ojm+F@lN>lFfi^r2SrBcMz-zPevZ=7Q+!m?faDx-yS)Q8;uMt~edj2g z*>K$m%aDD6MiOg0$}szSx9=dUiQ6!`EYl8K_WFWkj^SVuJ9nQ44s<+>d;uSe6!8Po zu=p9E)iVOccAXCvv0%X?!p!BU2ovnxwxfU71qusOqu4L=ryf}#ps#m(fB#I-C($v9 zH_7G(!9#{f9M;+1U!?iKFDp+rKXSM0Bz=OnUIymg$9?A3mW+&H_x?6cei6^D_;J99 zRF$Tq42hO^%uymWN8OHaR0bp7`Nmw(t?zNB2ffPPP^!W&+xmCT(>JA2U*|D{D5xO3 zv}31xlU-da<3&6ma19wXCdgE4rD5S^nGGZoF4zJa@7TFeu@!S~X}QaB7!Y6^w~F;( z#Xp81)5DR$Y=v+;OSmPcl*p0;UPicM$09E3wZ)`|Na+@Y!OM&FWn4+XLVH=B5J0X9 z@^RR7k(kZ#D4_O@CGOP$JweUQ+xq*tiuBQ11iyo?$G1J%|3(=XxzwH%w$|;+$ohls zWsrbigVVsk_8k|>RhhgdlwN?_FH)9-GKJ*?k-gyfLkjOyhwz}evZMcEUzjk*9`Ua`ucsKv|Jb2entx0Rq$u5uz|N*hgqSS3fqsuN^Zs# zA~$30&FH=?ZEc~5^?jqVYie4@Q`v4Sa8D<>7wGJUjt)CZWsB^jDT~A?^mJ=gb=x>P z+lC`-5drA_0nypG9U5M5L@??!8F z5!ziE2qbizT5Urk^t;Y5^K~aWyTRG1)OH>{4{ky3^lUku%I*dhH8;|;wRaqKttBdm z@oyP{XM0bfuMtP0gG6O=l+!8nwXAgi=HwQ#2A!>^QrCLuOChKn7wlT_@=TH!kJmn$^bK7WTeH>+hF5RL5Sk^uO*@&Flm*obvg$ti9XvQ8e7uBJOEc~JD?MlzHQsil+w1v^uxLlk&U=V zprbjN{jlgDkuv+V?$$P|QC28X@pX3%iYW?n zqlLF`b5%H2f~O%I3~@j@I+1u{N%f+}88@mFO@S(J$IB=Ns|-kR2q$bumD5cQZHO{& z$8k7f%uon`_S%ImrwI}SJEQ?o<{bca#X++^8w-lQfijmgHcWNm33@J~lf{9(ea9QF zG6x@G56VPEPxba;rMS9W)GfF4CSr4Z%htXfJB=nMmZ{Mw>dMk4G?}VB3DlU}#|~%e zZdI|b;q9J2(bSlXM)iSQQ85;dWb{c7s*byQMVvqQ^i zKcTr1glyi@$7M7(!^42qwv8x4S^nrCIzn|*L6oW8jpd;!EUH^Jf*qo}hJ>hF<4Le~gm4#>7{Ys&~E7S*k<4#-fn^6%^0v4g9cV3x?ht-fu^9XnCn zf)+`RHFF#hW<_u7t6KhPJ3}lR^tPUY=6x+Ec8K1_QUniTa*0mf(U0El7~p^`eGNQs z-+|ul7|!(sCn6aCxQht}?}$<6JCKeul~Yimm_)+IMZYnz{9KD0h{ z`2$v`CVk(wuD@RToW!(AAZVzpZEKq*8By3E?SYP%oG+)H^~egc;aX}dIhiSkVx9-& z?}!p9Gf?@>!^n%a+A6XP5c6V#V{7Z}k8HWxC&5`bT*c|yJV>mnrRDW{@xap}nZO#3 z8UmRk3!-C4)VdCC;n9t@HrH-!?r6`)#Z3r@*gky(v>gsPu#JS@S%nf`9mXOEzuwGd z{2VqjA|qr^f+5GfSZgE7wB2gWXBzqLZDBc|?24MmsBNvPY9=+7fk~)Q_B13W=vFk# zVj97T#7J5iUaKeC){>*QSd-kQa2Mnun#k*Hs;q2k!;9Z6WnAU0Q|M8m1Ujfd{8EzS zIWz9%dc>W9Yb2Gl1vre}0ALO~2w&Tv0o+u@yqhNLP%on@Xpt2@LN-32?1x(8jqSul z3Y+7&zH#_ufS|<#Ob*9BW0eet0zqGMZp%sHzw#ll0p?gOVo|n{$KBourc5?Op@x-Q zZ7pFrBW-^337BY%j151ucT%PtenLI#?T4H&(*&Q)<0BAO}v?L1XuE~19vw?XJ_koQB z9Zy!wz`d;j0l<}l*le@7)=CyI62Pl)azb=ES_P5x+w!ATUan9Kt6ytjB*G18V9{N;KU^@)P#-1(Lip4sN@cT z?;6?MvuzLhx>0=1q=rdC3;!XS?8yWJSQDI6f|f&J3sxDJG{_7jv6@z`)~G%o-g9SR!3<7V`=_9pTiXfs|CNl}qFl_h-9IkLHXYai+w-**lT zp#G$d6XI)P$QU-FIZ@Zz-HJM9KBR(kewtS8!k}FvkaauS8o#iGdy{kuohR&0$JY@< zsv?9@*}}Zg#4ky=nlA)*AcS*ACkd^zK_ocvb;NnmD z6=YTP^r5(Q8a+&-dB9@+7;lc{S zYMM>Z-6ECf23G*+?nQMY&}86x-S=%nbMtVC3#wYvGl?4NRXQbs;OMTQy?&9U&A9hBP`#zEH zr{IKg)lw(1^L&4mN?09!E{yXIMwH<#ZI!a@Eo!SYQE!aEK>8FWOZSYn(H_XbJQH#E108Z)4FdiU(U37YL=5otg__WS+hXR zbey{vstX+FnPPQ5BP&toI?2S^MSM9AELJm|#K_;P-G z`488qwT_>iZvuaFZdXj3URb%Di`)CQ>}GgC4WssrH+JpXy?5XKed3vh1A2P>!~@tG zbP^h1Wr{}8+esY7y+=*8{{Ed*+fB87Hbz>ayS<%fsqks#!w+Ih^CXvkXzjSTVe#4k z{^p*&``#+R*OJqT>xgU$gs*Uz_-V9Be@NV}V(W@?Rfe_u%{}|}@r)xijN!mvVN|$M zq^P~+ND5xYvwP2;z5DkU(!)`ChD@?DSZ(kzye!%l<4;U;dyBIb5A`-{$MDWKc1xwV z_D@m~rb{LA@UaRB4j{Z(g$MXXDvDH>B`cQoPNvOF_Dxpu3>uwCj*Lh_Bhpxnu2B3y zXB?7PzZp5ZbJwmt`}R*!G3xM~msnxD#E8=I3PKj0lD9~Pg&dT^6aF-dXxi4lcN$i+ z=-)tVOw>zjJF8P)z+c^Y2}2NEfQ`-%GwnD@Lfu_gC`<|t`gZ!(6guity`M_jn;n-6 za&U>6{hTIGpVMn?^O29_>-W9k+jSy?4KT5#T8a@OV8Go7`bdPbc)ZiMeGvA^VuUzn zFca7if)b(07jKXuE*`3Oyu} z$+ey*tcb=vAZAIEM2|%Eh}&R$KfLPl1mx9OHL#B;LE@E!kQ+&Ikz4_NgyR6@#gfWKkM0v@Tuqgn1Hf1iNad46m6l_=C_g95*muj{br30(>20hMIE@8v0G3~@6Y_!8&42W| z80%PCEWrIJW@9Uf1~YYJU@Z7IMW*c2VnG(0&c%@!FgY0zR?sbv9N?D34?;q0I|NDtf&L-F%A9+_lm8?D z=rbuu%s3vFvx_*P1p8;l?mhcB1)C}ajU~KJESlKzacMrx^9pk04P_EtTseV|coTj= z7n3nGB=LC81|Y2oh7eR>J^GsA29ggMIlHY7D|}JN-PRVQ1Uv#aY}MSb@KYBqb)4^5 zUrF9Las{e{_tD4l3ksI+?7z%Oo>*FdqIKpM^5l84Hczx{vUAcT)NHcZH(B&-^z+lE zh?W|}g^+CXPYyT*xE3D_OhZeJJbu?**IlG?o#^m8@7{LS+14d0;3PUiH^Z7vJaY1h z;u#F)^%pN;Fa>K0Yvc{(D6UA~jyK+l#YetxtLJ{7@unm19bNj>Tyc3d+HmO;ynZV- z>YZtAeJ2vhKQ8Y-c;MiH>J@$F%}Ts8*ejTKEy)Y6he}uTJ}U2qS5Q4xGW;v`uDm&_ zR&9yL;>QP$^O7-MwnTyMbm0UA`j2s&fBGd;Zo#epw!G1-Ms-Doj^!296VfmK&JZu9pwSub20#_rH83dgTqA9sGoPTX)U7qsLDDtzW5kn`u}id-2`@9y*Pp7k=jVRzmKgwC~UGnFZH|9D^Q`r9b9|IItmE5F^hqj&qZ zf#K5ChVCv)n6DJwbp0*yTW_TBy4oK5!tFr+LA@FM#C@ik=9^5;;&MD9^#^{X-qx>Z zR$bAf?_0}yUjASx`oTL_FI%?pD208WU$(3zB6J((joaSq-C!uGqx=8EZ3l%JT5sPT zj}6?u{Eo1&$I)At-=SafcIcMncXaWNx$pk{M0^uXy>X2KjT-ilf_?>`Tj1q!;C0saC+J@e`e6AzxBQOfcT@>;WT}s< z&WL}yrFMzg z^XICMle}(Xzb9qW3dXzg-|9n){E6w8DRokE{FLG+tu;LE@U+I6iJvUvB1`I>y8m!m zIT-Q#XQ~gBMOwIfdLX@gMInrV(D-xJPuAT(Lw$HMN!z|=MV^`Z7#cV+pm!T7%Np*E z9UszYJ8|-K>cja}py0^wQZ$poA@!4?s5QLz6ZZ<2oNDp2=UMwBwi>VWAImW7kEoww ztHz>N-Y4tKU323y&jD;_5j{1k(=}o<`@iy@)Aiq*vF8fcG1Wbl2jjKBR}WO~jd#4h zJw=L9I)g z<)XH}EqgXmyRj_Ny{O)fNB67W#-#t~ZuOFfyT51rLORh3m>u*_LH3NW&Oe?M*3qP6 z&lo+qPyKr6m+GD9$v4#RJudqr^&5YsYH>YwSN?2Y{KbE!@RKq9xBskpb9d8EJIC}N zA-QDN&qB|B#8&@)OZIC=d0DIX-c~7;pY>_J^!rHVhFfTB`|aO6ciUwTt$A|I6Du!Y zHTuoORz+ODpxCN-Z^K!irbs(k?=DskSkDc8T|LQ5PAl$GKj8JX&#Zr@+zQ1iLZ)!S z6ha~T4|#7b_J?Bf3S+4p{<`92s}&pWQukGqud{6XcHY9eVXd<5JEicXvaRowmv1=h zQ~aQF0hPC~%GU;|zwPVl?uQ?G_@SHB4?>Twy87Cymp}AO=#d{>eeE@OKD0jc@ck6- zdT71w+zxp!>P_|Te4U;CeH9-n;dQUe)dLm97c;$E)x+f%e1yWy>aj5$>k&xDeP37K zxZ}1vZo5YP;Mt2ynav}&tqGM}${ZiMZEeM@(iJO~e_E}UjzbmZUCn_|+@18%uk*%O zI$+YFix&$MQwt7uH|fZMeGE$`;dDDWCz;gb|-ie0P} z4|u%bzVTW}BkVaM->2``aG~42`O54s)v+$ftnJWXCL-xU{~Y_xg2~2r#Ct8XUC}Lc z_kNBoP|v);*?V2HbevJW|J2n}4O$gZ>8Jcp8n=FRb114uFBL~o>Q6@4pG~Q72HnRe zP>NEiLZ(DX@xUm~I5Q4$UmMLAjf=EQzcyM+Pxp#h7e=1C>%tdm)X012tB+|8NOM7I z`Hhy|sT&&MZhcwTx*>BHstQ{OW4HzRA!YqBUxr}sX{u{UtT{!GU#?}Sf$SR|gyEDJ zYbR3)oOosfSIVEEC$qRb6v~UcGj)JVu`C_1=n@t!qF4mIFpsy$1atB`LkC!)ebPQ% zr&WNK#0WI6>xtI2$1T!#N)42pw(pE}{g&z4C;^eBqq~+_kJSNhx{H;LjTm39R#j*n zaI1R6U>U7DF}lOwS+-X03c0lo(OrugkopYKTw)rc2O)Q2{kl)v zC2hAL{Ij*dxzNn8yqRRRN|1m>R^$z*+*^`slt0Jk#lri6d0AT4A<@LSifcu#8q zqndP4w3vL(NDD;D*JJpz2k?hP%4?2(rd+k#8GOA>y4ivsQg+ zLxokox9AF4K&Mgw*wdfA7Tf>!ht`EK!1-WtKdo-C*@w*fsNQx=B>xYHDUJ-$x+k@O zy{>0X)OBh}??`WcLf^fMt{+{#CUn;=>dF<5h3;K`R_TgWp!x0<%kQy5(N!y!uULL> zMS34_X!JfnbU-n??mH{~ie2|t%R`}$EA=Ua`B&L>e~xdL7Fqy*U0r1_YrAdLy0rX% z@E-M7tJYRLy6W7ES3Objy=8Yl_`to(zE|;8^}PolxO>?>t|HKcPJUhatq)|+$nM2# z0xH(38!D{O9&pB$o7L)2#pCLm)J8BqqHgo}MLGvEWThmBHX7TRF3ef{8L~+S$QFElofCI9gJsvTfrF6LAjC8x1;*DT4-IEIA1O1>Rh$J3MQ76EeT}&wS!6NBPnnL=c`51 z^c=MyShmDcv7$2CE2S`}jLVBH_0HU2S(!CeS~jCd72JO2+r=^R@`5D`t?9AZ#Y;?K zPH|bVcmY?Wkm}AkpWX3-V15qG%~lJ8Ir$W3sp2ww5`~$nWa6F}=>@ZkW*1GTtNdK1 zUQ$#V%qgHyOu?UP&5liDE~&1LfdOx3`MIYkkOT~uqGPbVWU-agQ?#TkxMXo4CucT=(nS>J zf#r#@T~ttN2Z!br6a!UISTL74E#Z3}-=+D51rR$q=^U4|zF;G>)gSjOO+oL5(0Duu zA??Quhn%Vzk0Zvk@7~C0#;~YhBUly)I%T=;fA5NLwt#2DdC(q|`R&2}*N*U16ZOz^ zM)-Q)gC2#J^zwBfM%|a`=L8eQ=P$a%pq?Laq5H!Q4$`h(r&2H7Shh?UD+)|2Mhvj@ zmz2RIWlQFI)IF(3>#hGDS^s*O6v4-4BBO@MPjkhLS95-9?aP8p!1;5$<_!-@^XWw| ztME^1Uaxm=VP!OL2j8M8-MFl9Em2J4C1!|eER7M6b7!!WGM6pVD0}dU3q*!yf|!+^ zn3bAeqHM`DJ0~_vFJmj`gVcJqJ?z=RiHYqC#-02Tupz2PL`_ZPy)(xO?lrdz>huk_XugErGZ^WdxpNlHGxW_~t^d8M z1%WQkyn@KcCHu-^sB%7&Wf}YB&n!a+=YoJbGRx~yH(jdEMe&yH z^-msWP^r#kbZD@%?CFW3;w1&a1l4HRKiO^gK*~OtpE0jLscml!&7ErnkCx0X4bGjV zrpzu0&Yx}N&R%E*N9N6*J>LpC3+>s?{CqQ?L$2~RN|*`grHvUoCwP{vBIh&HDN0SH z*7=xCXZwR$me1Mtj9AgaC0c#&mYT)$)maNmF-+|Ig^PppX3Q^MIDf{x;Q4Bv6z1o; zNIXA)35IkOaT5`76ZEjb$Y)|)1Q)59)LI-2mZ&1P*1PAck|m`}O6TN=z2FYDOfX~z z4f3UC88yrFq)JqZPA>921f6lW=RmYf!en=wB0A<&M!&`Bev1sz=h_Qmv(H@=oO!;r zAad@g>CQiI-hu`5&Yhnz-A_5r2fShEhyNG-Z(E~koWWO>I{U;3aqC!Yjji7MS2ylT z(E8`vjm@qyej{b=p$7QA27KIx)%vA z$K(H_ocGmbcf-4?)@Jl`cyvFJ$nXbL%I=6tZ)ePB=r@&>?Rq}H3sjB}0R?-by0O*B z|MT*3-4U33szAk`B5UyHxoV^*syj%bEJlwP+p4c68UfdnyLR-xLpt)C+k2bTkH}Bu zq5Qp?RxR6m$ye<=7K<>x@Mv27xc7r-R7ic?kd*lP0rjuY+)Y?8v^JRvroKer`K@uU zX&uw`k4n^C=hwZXE?(AV((0O*1=V{xgOot=-Ji$7S4qK3K^lVMFGva!{ZD)Q@FDr| zuisLUP3G4tmKxe^iiZzhZ>xjZG*RmRJ9PN)p;wov6R!^sMO<*o&LkpvDQI7yP zNhTFmXx~eEdriH3IC@SOIIk_c;6bDlfUMYB-0xxTfKRRCQ}(Aslres`aO3_n*lmH zZcEYl$US-{v7v5&4r_+g?B;Q%z7oC1O|0p*)WMfK+d5l2d1$4*b>>}dQsDO={L+QV z&!H#H?Cx@i#dU4&N$ove>Rxnc!CD~ns@X~H52QBF2BgHITZrGos+FW7YQMKTl}dPW z!5T!P&IB1c@Ow+Wc|=C)f^s93>>0bq!vgjDb()Sm0x-1Ti4()nU_f#_H&Xvp2pSeb z(!Z1EFZdv@ad>!efmQHZFuY^Fb7BffWAky5|oDT(FF+>Vcp zOBo=bjLyB|$?*8EhN98?Z8apFF2D8+Iu(%4NzE^uS-K4FQ>`YAEHf6Oe#nU`kOaV9LF z|3zXpvvtU;(d(w5xzx^t5WzoeB(f`JGvsSzSn!Mx_oREOkYO)HPwo$>_K7ENI86FX zjl#o%6??I%_TPT<>)*WiqAQtQ8$lKxibIPz?~x~g&{r}+hc14YYocSkR5d~5zfAqb z=3g5D?HMZ4rIFN;iys9iB8&MWKuF?P^x~;%t$O+MZYB3}T0jq9{D=|YX>kz!$@lm3 z_}07czxSRz#YN%$ci&$53r|vK3ux-=8);oUJP`WwNuiFLPB}pCeQfZW|5rK4MlHPQ;LN`}Dcd2UgWJpWCYSVp2hc>FMp6)kU+s4L9^+}_HufO)v zK4W6ET58+B%A;GazI4F!xBKPF%E56vj>fInF?lBLkoqT)!>qfZ7L3&WQt(nE(Sv`d z#z^WEzO|%2q<-$HTlx>b?dfHg%zvlGNNbngQDKsJl=^}V1{sn1?+DXmFx=lMF$WB& zE@;GQR5Ey^)GK)YjuI~kCEEK*RJhEw}%ybkre*I?uNu$PI2jfLc)pU zrhm^?68yP)6K_!u|D75mzcYA-{*V8UKXkvJ>c6)}g!ks|!-jtEb^rU%2PW))@D8N{ z&q!uQDD;=Sy!R#|UneBM6sq{LB0-H@04tQNSZApZR%GPQl+RG=WdxH2(vx2z>h)!UW#x}v=3nYuf~m419W#wf&3X1x=MHq$m!(sTk-5bSuMIsL(j7j6 zpJQQhfVS?Gd;l4W3}6Q4zf`%A^hc@kxCv5zSv~1RE0?fOT%HP#k}T;}`7*&!svLhp z+S0w~0YU=cO;XGEOU@QbnCzC1EMVWaLI-IjJH;wL3eCSEzh(HV z*REN+#$KCT^AH=wJLSjPHMdjY5mQ{dc2PF%hbpN3l{IVEuDOHlUpC@}DVB^zthqRp zhP28Zc%k>PyYBi9X(oI|7w+<|a6`jnq@w)XRJ!XfFRM_k%eGOA#Hr}7MhXeL=< z{p0rP_~Wbj*sBx#4d}mIE0@)jPH4~>23BbJNw?ekW~&2hyfvyr&*|}0eAr|e-alK# z*JU?zOt1XVvsdW6sn7k1gG!hI|Z= z+ALfdY59gHzD;CWC#hxRjtsk?p(|VzSnBvgCTE03%O`(Y(#L)41)D3ZQ(;FFjLsd) zZ+~EY54ktlXMYPRd3g!grtUjyC&K;}k{|MH#r=rWi>`Sn^w_EbrM``@ysYFDy>cI# zm|oe^eVs{ulug4o`M#{!^mt(69^J`O5z+JP$Ec_~EcQB-)Uz}%4f6|4^z0QNZUj`` zr#lRVuB6_#$}2*b6?2g(rm*`izlA>T0<93*YLea0PVmxIPgZ>Qx+3Wl6nk~yi!6d> zQdal?u0rixNr`iW27Q*UTf$}fJ(0~*cIcRNCQRXRtyE=1QuR|$ZvaQ@oFy zJQY98xBR>BHvjm{XFAl`r?SGwr#SP~ZG%Hu;ewmA6mxL}aSgd>rdMc@CSQt@ofO@kbwf40SVZ{fgD;ezWDHJd=<)s_eV}WzsW~t4HNv zjmfVrN4i?8o6=%(wAfBR0iu^7B+i0Z9Z=~d$eCnwu<=GuwSiO{tu@pqw^c+r&(hlv@ zlBIn8=a*~{5#wg-ttUr2w7&QYB6~f=c_wJAV#X&)p|e6qQrNylJ)%YHhHvE9{pw!5 z&eU!6EUPYyC>y|!zJkQXx?cCtZCC4Oh1NZEU9LLDgC5UTtiJjV9@)`pdmi;<5Ynj~ zI_ma$pIRxsRBZTuzIx*xQ(U2bpt~EtL&^PHzxt=bxeKH8X+0`Ua2l0?@Ov@Ua>+4s4ll<)| zENlu4KXpYL6;^pfXeCvp*R|@)eh+amI)_>8(15Vav!Ux%md!GnTJ-FZ!FfJ{gg>j*i^@3%( zaUGBk=AvR|b62AL67ct`cx^k2NuHu%!qw-VZAR``?6S_vX!h{fW+ex3RJ&AKlsV{` zI&M$fvjVe6h>5#+aV)lD=M*iG_RnKr(>O_L8uL7ld6LK|xh5ItNR|mWS#O|mWI^%5 z#a3{jq{4g;62X_D zLYfZjs8VEP%atZnkQ72_TVloBFPgpR{NS);TFUhW*e|69K-$nB zuMnIBH~`L)^McM~J2=7(e#SL?IteCX;DeI|8dMkM%}>np73R)&iu`U}_f839FY}#6 zCSkF6$8FV8Q8xihQe=J8XwnY)%94v`Ve_53zi6?}uvsDt)i+I&<$U}nJ4*LGJefJk zv=-#6qw}Dl4;jFfLP=-^#+!T!duB2~=;`FDq5SE^MvU@9-86_qe45PYL-Ny(xT{+W+gNdMNY z$x=2;lv;~E{eQe5KN<`yYI3n4qfHHZ!h&~0Kor_z=u!3tB)cV?a+Oj=XVMu$yRPC)<24<2+|Id{?`No_A(tpAkSi$@j}oywUd2(91IG#-Da$!$$vM(XPVfV7L?maLpdHHV38Tq)nC4F03 zcGKnkU~%^BqD7E-9#(?RU!PrsLXMXd&7NI0O`6XKrc|BB)I=Zx7Il@en<%AXNk z`Kh{X<;s7iK=s7OS2kIZgAe?On3Yr?%m}wsF_PQ;D^D!n6&*gPK2dn}-x8YmsjcGA z6DRs{Kpm)|AAJx9HJ1{XBT8Tb1=aY-mtM6?!Wrt50}@u0YCj^;hHB0xYxtmhh=aOZ z-*w{?RaASGCzOkJgh@|)Za?37XJ>`5Hrc<0ZX0Sn}U3Ep*nH-iHrbq)up51x!`ew zjxJUar}bUsrC;fEta>l~DwUvBUsv0p19EQA?5#9}$>nlm_@k4jPJ4Wx$s}NnK|IMG zF~R>-dRD67-ALtmWrBY2_{+jLeB3V+S>wlqh4c*;#rx`K*-?2n=Sqk8Ok#uy(n{QZ z)InO2=RfqJpt?Y3VcGjzO*R(kSYCnbtRty$cneon@H-mf?I)GG=+PBL>iu7M0mZE3 zfUo4K#ERj~-2c_Mt=vSO@{=#V_?ut99@`JlFFmf((SG47IcQISUXwZTlj4s}*42O7 zYB&&PF>yo&vc;WS&FqO#BWmS;kE-Vvs2kUn{|g@MRdwmEVj-j&|mq_UOYG@ z7Nr?#|E*psvZgqP=iTEb`QYS%e^<@#%Xo-3AAav6O8u{ltSgh1Ao1v%zIfnhDlbc^ z^+-md`;v7fXWe*5vqrB}YCQCu9Qf+jgezQPE47Yg_tS!c8%V)$&${7gR%^JK`e1JK zF-gP!Sm67rWNWw?0!ppgc`&x|uYdT{=s^E3^jSB=-nDe5e=nY#lFsqiKPdGz5ou6+ z*UtW(VDCT38yb$C+|Djkj@m);)BWy=x>w5U{QiV+Zh^2OWou}sL z3DLb9?@_<4k;z*z=kwHlh6N_s7hqhD85%xJ-&Lq2`ZlO{GXRV@WmkR}P`xCj_Ig^X zdj9!;f{b!VQiQ%a3OTxu+S!B`iF&ASoqG0vQixem>3glJmij-<&v(ye6^UAq?~dKD zoiLs!Q4QkUD_0lf7bx}2aCCU!*awo6r4LDpaBLD9Y}jDV4f}h%A07TjFbAll3Vgr` zOG-U)Xu#lZ_|Si-_QUigWI1{W#v6}u{%!f3OvZt5|8DX?w!`*Ew5*80_Pc+1a-4(p zqBm)(nFOyWb^p#JXZ=CeTZ@kLZ>JvH+`=A%@j3@=t9rR%^C7!PgK^Go}Nf2 zpah9pdCIihf?m5Tf7kE+7U{qmbp>py5RD-n8Y*=P-Ef=?Ey>ABCufthRN=pI;uW7%-cLp$M&8WNNUo9uEB8x8ul}7b)HMrxrJ7C` zpv#FDI*m})xu=FhMFv7-Bc72D4~uz_CBJ298fsH;O^tCxwO%pt_`{cHnkVU14M8K4HjqriY1c}GUA5$7qcW&Bz8 zO$H)ezBbf}-kMj?Do3PxV*6w?0_Mi0oGZV*p1+-^TIFQxbe|&=_UUqp+vhELFvx3i zFzOlgijAia@6+5+t#h1MYoW~ zP|yA9e*O!A&RtpbroKn-EKo0-I*VUkSGm)UamB@*6i&f!+y%n$uE^+}S1(na$I!tZ zH_OSWhTl`>uue)$L%{D^R6~c@p?3AT+jfH>eZ}R5_{6kxA-vUm3`75wbXvWeS{H$9 zG7aX8g>N2k@cQo~(W~<(ycDCG6A90VcTE4s#OoibxIwMeh0roKlQ(dIf6o$5xf#DM z(HtHBkgq%0Og=4;WN{sqSj^I;gmcPoP?s!S`ZeIGo+w)SJ*(p2mDh4zs;`$Y4&e{^ zqPlabf9cR=k4PkCw!QE=E9BgO14_P^1=I&CiL>aVC8VaC2_kW(m23*no6i9}Yn7V4 zUP52gieJk&wMc|2Kd8@?(EaJ?m5F8DNwqs9n7Kx&FIKGQK)b7`b{%1GsvRBE8PN}! z+e)^Qi?6vqwEE$P?o}$Z;Su(Qr|*ib1oiufP`OvusOdUAYwdOFQ7=zx&7-pHXW1CojXK`-(@PtbWSaHC|qRf00UleQX=fh1jH@xtZL7<)PIy@ijeSFLgi| zNTi7X-641QNpYD;%en;{*7qHquyrp-ckcdLDzKYbxKOE2-1DS+h05*$pATX@uM?7n zLZ7u&HFY%&1($+s{RvU`I`>L>h%;oK^A z&5gEQ$}*5cHaXab(><;7W-5O*1Mjl@1pQyKRatt)R48@j!)rn-uDRw$(ia6a0zE5P~ zTXdC|OrUFDMb$f(E&H;rO~*3ml~%<*sm(3Zu%rY-MyY+HWtH-! zX|+~aR%+N8EFx8CL@?$S7h0B29TIY_U-z`+Yw599tbOL`4OV%d9y_>9$wpHUl!0Ga zmmCQ6j8dOoyB^t0ZpoT&t9#Z83((8DHLzO7Dsoc^zHwQhVHK06<5H_)gYdXXt*U^> zcW1JRoAM((>XAyg1xjCUGPiD(#l`VGeD41+Dm%?1-tv!MxZu7=p`7lNZC|>1;T6M$ zG|v*!2@%q~D+4@vHsE3mn5Ex-NU{|`B|?A%98a#M3Kb!QK*MsEUSm?XOb(Yx?pm9w zo+{8B)twL7pFZ}*@`p6ZbW3!2TJd`6jOp^p!Btv*uQ#pK{M>^1O0C0846HAIru>-= z8?NS&=owQ)VvZKC10qF{qdJc!C0|(*hUhnc>XRQ+WCv7o7L(~d)w%nd6+*fQ8Cddh zztRPBnZI{^U)ac#-w;mPw?k{y8x_xdgP9pwD>7E|p%gUbOrhcvqTofU(fv4}SxA*7 zVThY5gg%jFT8@Djr@lz%^g2Cd{c^Hi~#O+(l zWTNcnDng15Pk%V)5_Fx32r4TunH^+x9U&@OSSV>$=ci{z=j5uBI&Fw*=WsSyu^jwxieA{j832-RCFhN!k)yaMGpEj z*%X#7C{oV(RLFxzr`a%>tH*1=F>F z=DDMgFQujwmj-7~pMGwztoVF=(vGelbh{Z5crvLyZ0o(El&E<8(3KhNy~%*w>%tVVN~QU>hV`j*U@!Ndi-W!91bZ$LrL zQzGlm8_=7A!xWYg&?)3D;p8PwOevKdp3+%rerZlHwxm?ZP6rnh2=PFuWYN(8>=QAI zUJ`Y8kI%+=nRJ8C&LI;;5)bF`?Xu-aUSI*ahgkXJkvwS0S8;+$adWkK|iRYOW)VVQSGm&R9W z3>k&-Zs>%^vgycN%QtV4Q+8f3HgoFKDJo~4+U@32Wvp{)%ruD9oq55`3j#9}8GoG% z?3u~A^DYR!yX1liMq^Ixqmkg$EWs&Pblc`sx%t5a_dl-x7U{zeGXT8ov=i=N+?Kr4 z553!hGbBXWu*n(IN2f`vMUn|6pI||r>M77=b3uap>#WgC$;|mBW?ZE@FWp%}_LrXSAu~JX zP$mxq&qrSBmfvu%yZ9TI&cU(*R`z@qC@7icHYcKkk3KS%gy`T_^E<5;re-Ni4XSGx z5|hcfkPI>Gr3KDHGvHY|zpF15zKFb_BttKPLHjQe)^iL$y12Fz>A5Z`#*c_H9;KVuVh65<53UR zJ8?kC6Xb)@p`Qag`p5wfcCU#<=yoLlA+Qs+OLN39U(oGRI90nZR93cl<30L%W#t2I zyAtK_;v9MmIcn$!M4bc+!+Xh0e#s5~5o+=f(9@$h3X43dJ;az^;LT8xfu0?G9FDb_ zz5F=11wKU!FqS?Cz@vqUY3k^7gh2qmtigmzJC}V(?KgoUGO3P3yFco*opf*s_>(>!)xI66M5%XjxiKD5W@ZyWPJ|c{!g75=_;gT-Aa3-e8Rx{OTkZ8C^lkvs zz!O~ePEHvoNS~P(H3~i*mCwkD8Vf%}1Wr@bqiKq`={Tqvm}&n*A1c|c1DKf!2olgF z_L(~9z?-iy{*HE&^K`4}pM3O@`h7W8~O%&)h9S$EWJ<^LI+N$aY-1Rr{bbol82XPG8gS^wzEOu>r17fbmIhu`o7%)a_l-K_Vr=`2N7b43_rLU*`c1Wt6K9Nn zltdBu8gmFq3}K;`5)Mw|XI$Z;YRws6{m*|(h5I=fip&K!YCTqPGv9nO9yw%WUs||G zH7_rMG0A*|zQ7-0Rw7emzG>l-3P-03F?W%BYpGRTf2(;_W*UvDiF^3WqL=We7n#m3 zn1l7;e&9{}gI)ik&Vc>lPuQF|`#bRGnD)mmTKHem!;*ja1@K<`^q5Jel#l>FEH4r@ zW6{50c{QJ2Mxi(DCz7l2Z|rIEpeL44T7oRrxj+}T874~gJ&u6V;5&8d&j5K~qcG^L z0j&^RQa$?E!-nI>$+Q@cRA@CXMd0*;Dn%;B?D52@Bo*)(DL}DWr9~(p4C3I9w*xEp4-_C zMLcUgmwZ5RP|-3R+uz{z9_6d$prT93Qk93dwWHiUZ~{<=V+W7UDPDLL-hJKjYW#p_ z<14*A{fxMN#fyRTo(Na&^S)ok{JnLQ*Vt>77o17-fL2Wy0a)kuR8(i;M$1pt=r>j@ z|GqcWb<0<*xY8S{2_1N?Vts$ioBm_@@o4oe`lcTuShO4`0W+fpIpe!MwxM{#-E;hzET$6N-6Bq** zV_Sd`Ac8SbX%%*7B~SpNoU^pj<{Tz&(&i+Bv5m<=LRv{1CQpCwsp_7vK?q;p=l`GY zdjvZ@-E}IQ@YXq1XS(KZA{cG)GYKgl;EFF3U1)hpq!K7vJgj1(`@;ro76J^~wIvdvy&r z2zo`{IM~mVx}*lj9n5`(AJU5e+^DCBd0$9Hszll{Iql;< z1M4?Jz}XLOy+yoI1154VfDp(kSfyJKs@Itp`yk9bJsInpYS!KkGI(A@KkN}x+#rw> z78E*yjzdx;ESf0!lZY6j?(h;QAI2WC6^!rvuqS4q-v~WmTtD>g2R%Zw`*2RrV2A;p zD4U7Y9Ie>Vo8kRrLleNjutT$*uEWsJufB;Dv8;~f`M|IvM)++c2{quT6IK-HAE}_` zwS+ICP$xz*-wZkt2L4-=8-|Y8zl>+`SpCO~LDb7GGAmbvrZeLOJ+#$>2l(~;FoSs6 z3)aJ<_aBriaI^^v7)-`XWOFah6v8ngMw1EeU=h{O(@y<2>r@f_8*5~z`~GTORHWk9 z}X{??XB>P3-?;LKi#b$vdfnL|;3-@&-2GwjLZKWx~0 zsF*o<`V3{dcvpwU7S5}LXkG=TGZW5#!LRg_r(!og^3!mhuXQeBrzzzQ7gbGU;0Yy~75|6~XB&>J2MhF)vop`W)Gn(>K$_HawSe z^zNJfSnSlOsNFxEp_O={60-c)b8VVM?Sg3XoNA0$lO}^$oj#0x$P)p0A+4m?F`+No zU@;c#vGF$qO(8OT$6jeDS%G^9sh;4)__(90(K!p9#qmBe)->z{C$plAHV zLH-Ja^Py*W4~{SXvJu$Qo`?!aWv~&=cgoC23>7AB*A!!)sy&VglXc4+M~ayVJ(Aut0H8 z8y&v*;W>yk)fN)HY@9Aa{$16SA+l$TvGF&Q2z9<#s1LFo(1rdAO^{@g)u}=&74}!{ zr8s@H3S)>F9Isp+p(e}(OF0u_9`i5#?nIc71S+9{y5gPS4`Uml4N>YgZ;VJV;{KF+ z4ZLK3)g^)`DWOyS`W1U8+|0j56+5i+=v>U8=#;y2bg>UV&bNoW((t&@;CFDi)Bn5w zv)8`I{2lGh4Yl88zGLmpjrDZV(c08dS9=rlcC@!N*40$f6)tM4UASs%uCJ-7vfs$u zZTxAK(}C+&Dp*x%bJBHlV_j9H(`vtgNv)oy`r4|>3Ol~^Ha9gMt*&y|?6&Kf7p0EY zR5}&w^{l4_?Si<%W-Yspb+4(mcSl@6<|7(L0$QnKj|_0?KYTv}9^ zjXPH|spd2~XSJ3T7Z>JcW@Tq(<7OAwM8%4ViVJcx%_?5r#~Gsy3rrlRF#MTPlv7iHyaGm~7s zPJ2aJIf~|FDVYIkKbc8Yy_NQg^77I=)L=mSDsJ{vRigFsQqboZGW|zT2i>i7*&vq^ zs#H1RLl5vDYH+%3QLu1Cnp(Cg{nf0Pq#P__cBZkA$5h+v3N@6`u zdpYMwF5NX8Q8SZR7Z`$j1vxoKaG->8SUw^h#_Q#vCB;RBIoX-`5p+g|>9CrS$U1Fc zN^xOfW)_MbI+Sq;#X}i~5?L>lsJJjcKl4b2e5m)}p+g7o@X&$%iL8r8QIMZ=B;&w= zg9i);r31lzd-f!}%r+3(-CXV;D$iR`PgVsIz>FmCVLyMN!lJ-c^q z-?nwz_Cy?CRg{~J7WOH7dv@>IwSDX6&6_rD-V73F$&n+64<6XNYuC;l+qQ1mv|+>g zbsIL&6Ibbhy?b`=+OcKxmW}JyzxC#uYu|cn!^TbYq-@`g?VC1kShx1gHLF(Q-IQsw(zxUblAj>erXASf0Lo`HI)^XdTt&t|>mSan0+?EvfR79{gfy`D=Kxe&d!T zcD!K!rd8?77B8B=VBuo?4(YX(Yu?Zv9NN4pEoI??d9Tc0xMZ1S#mY5n*KgbkisJov zuxJ6jH+SKZ)O32VVe^J$cH+R6m6jz7=e_#MyoHNX(_dfx##`$*Z-eN!oP2Znl7$QB zzcN2%Y1)d{-+XNy29NSb_N{$w+2WLi^B1M0qW%?ct-~;IKj+ZORm+zwTe5Iz>cXYz zD^{;T%ee2iWxn;&U*wm&UV8qCzaSu6zH;>&>o%f8Rrb7HZ!CJ@nLo{b@~J=Kr&!Bh zTe*7eI`E^u##xfHXVdFAvHH=+XFrdKYWeG{-(2@SCUpb>HXPwvni}Y$1L#wKR6{tx zi$J*g+8RQ*_LhcP9pPG=>VX76IH}bOB&!w(*8v zML5~z2EYsmZ~(J^JHWY|R!j%60Ozy~0B|l$Km_^G00*`W1aN??0RRs8I55D0@dE-J z0ogzRSBg0%Zy;8> zO&izu1-Kqp>7EU5y|sn_PFd~|__mSot+HV6y4A0*;P{3$^A*6iwHr1OTIKFpzcLoz z-qarK->|X|zHQjF4HWr%H%8+ds(NeVmW{xr{hOolZ6#srmhHf|%`y14a_#HuH*eX3 z@`v|E;oEDgUR$?*{YJvQ?1L*;FJH>>ZNZZC*Ver8##kkbDjrA zuUMtwTcs^$_nRp%623k82P_(`cwNW0YDY=V-pwo1fp35MBTo4M_Zn&|=3Giqv4T#uXr~vdU!xrnPthJa86p?QWrhE@uUKcI5s6F3PR& z;F>(-Z#m1X_|n@@4_eIl)(UuVaMNIMcBLF19NMh{aal!q2|PG>SX6B(ER26e%T9-_ z1Rg;#Jh+A)K#$#4S_-|+hX+Tc;jomDg66`5tM4YGx0RKY6&2-Y!C?cORRU9r%E+;z z8-Qnr-BwnN8~NE;@Yia{LqruN#YF`gt6D4DU4uH5kyoikm$EC)_LseU{;{KLd5pUAV%KOA%G7Wcbhn{D&IsZaCQBf9!2? zpdf`DG-f;$%0SKV;0VdUclb_*LsEtWFAg3Ycgw($Y`Sa6P~ocu;bO^!-n^_VV8lV? zkeneMf(KVvM8K4lc^ID9!Goql>OpvLg$4MRpAVEdbdWqU6b~Id01vJpzW}_-J)Ch+ zKF|w~Y#$yT*tZuR99;LjyxgpegZuXF-)Gn_?F;VNwF@2``P4Z%hjDxF-hFV&{BYp5 zZG*#*O+(E*gxh;|@7=R!*Us%*0Z&`u!J#yO?BE_{chAlpJGO4#xN*aVjT=EylC^u! zzP)>JbNjX}n>TG(x9+XA>(&wJ&iR~O-@i|PCU`AbK(zp;GT zf_X2$^wKMf@VhtR+N}jJ?S3mgHD&%QFTeE4d{Csr7krZ(uM_LuT4hO@KmXO2UR}5t z=(@`C2A~Z0_iu-vwrJt}R~NulOJ9)&BwM=<_cQjSuSi|ABxU~MrSnpjrM>q0O1Of! zUvgme^UuA2mvB7yr|0ma_f&XrYuBSgw$j7fR?d6wsYm}XXU@Z^OVOtlE8kcPc2qmc z^A7J=w>)*}%d;Q-{jF^9tNGvNOH?xpJ>b7YO=h9EJ(uD`y<{Z)9l`(Z=6^ra|0c1} zyx>R`uhh1T(*7p0&;?ne)I=;3kEXxV&-*Vg9~z#g*MwSE&~<3&m%P2z{O`s5ujrGw z{*XEl`dRl#G#66Vj#AImI4c3Bc0^tP*pgzoL@AZZq;jP~wHjARL~u7 z2@=!sA9W{)7G%3@^Vn%P73CEMa3El}I;&)t1Bz9)`K&ZYgI2MgsQ_22FgZK%AEsv+gOG}3^hV{45Lp0ZXhs4%eS8$< z28;uJtdyN@h{EYC$E>9ks2IM?siZQ0IT0DrD`R=6LJZ30avB`6GgwxXFBb#>;KVHn zeG8VCK{=>!s2ptLHdPEM$BPfk zJs1yo=5Q*4!mc=^+%tK(h!Lo%q9SNY6vsGSH|B2QgSEmAN5~Oy;!UImM<^#(&hr)I z=NA+d#gVo^jAdv+E;B%5jOBi7x!vJV>;~SD$C;CxpPQEt4ulGejGSMcAOH_wDWqv2 zuP~K+Y^WV}V#8=KBEQ|?%+59BVPuetTqJ3IQ_2Hqu*Asq0Y+Kjw>fMMhsmzGIFTbK zR{@bypcJWGZ``~kqLE9bl29o)=dUQYqJyvm6AebmlhBA#6e3fRN_}N;>&p10ToOR% z!0;ftrr6@hGIOL{DNoLq3MA;61Y7i=G=id%Qm&=cO1b2K5!;O5fSeP=tQ{$CED4sD zl*q+rN{UNC0tNsnV0*INWHX>VRj=f$P<>H(5WbtS*jVBLqQGmiqgWhCE~c1L5&$mn za{khC2UrNh21g)jB~QWFh80m~O`P}s3MXI#rfCaV(Mc7x$@WOGP*GtV%DKydSOAHN zNI4lI4Q1yj7!8R8rcx*s7$F+DI9OV4H(G}i7CLND`t0mnK5CgWNhuVcL=z|}=8XeM zsd&g?lbuQqF;qcW6EE*BE(FvSmsqVv*whg4MRNF2XAas{^1b9CadlD((OJ1DR9qGZ z^YPp4KsSua4h}^Ki1ogFl+Pm>7y1jxJYa6z_Kb!kE8g|VNvM7gk>us(9A9ouc6QbgENp^f=w5**zX+-ZxFtwe!B)xIjWtB*0my6) zvQ!XuVR;lQr|=oGvdF}V5+GU{5R?F4Ag%-!)2t++Ne6TX`hzuCtc@PVl4*9foa4>Q z&ntw-PP2{|b`ImlG~mTwOeK6^FrqB1gC0>cD-TfNI4F$lkg-xKA9VAgv~aBCs8Cd;$N&Q@ zD;vW3AWBLZh6B=}?t>W_2tzQ0tfE3wQK%G_EpdKHV6~zP9j1pxQqKYMpV0?7Q_YbJ zjYUE3B@kE$7ISS0RcKTMxqA$IyY{2!8HW#NWFE;br9z};9=*t>WC0rc%KmU?r5xiU1~RP2UG2$^X9Br4*NZ1;f7>D;+(SDBQeGJGX7$xogj!eftg`MC_6a>C5>+D5g?$y11mU zq!7&ktIMf_Mo3@bl9!!lwrtx0vc3Bb9@>96H#r&809p;hRB0+LQcDb_ZU`Q1z@QXBsO)e%9jz1ReV_jAqx)ycU5-yl?H z7l?N4*|!T^<5UqE12h3fKs1U*A`xghy)N`>*PerNMh|Im4vY@QN_eXl88G(2h@WXRd-v~!?vTcD6XW9t zUKU|OCGU~EK?xoW$whV;oL}$U4Vhp){~+vyZ@K_?%Z(Nu(uW=Wc3=%U8%~j5>O4s)7yP%|8+ms`LOdvlHQS-qF0?51J zm}3jVDS-H0lJn%2tvg7b`$$D8M#Xd?=Rpz3@^Hgt0DzWs;r zPFPw?$d+@@0v0)l!a0U18A^kYlmR$JLz5lHF|bOPYcnXRMV(T~hDvaRlM4O)2o=l* zI^mYB+etAHileinPrht8H2Hbt&_QByiJ!YM9FRGr8tw2FoN}eKxtm)D>=!IOEMwK*{8ORD@<5r|~(cKq*#AX4?2Zxe#J{*@2}OK9IB1i@~ZtGW`)W>|9i z<`CpGW*&qfRYdSjAxHorh)b?Kj~E2;oE7*>M$~OT-w=cxFA4goSOYezz3Q6-5ON6s z)8U}PX0LReI||`WM1>(tfvE5s!Vt{Pm_o|ofG8DSjLHF9Gn_{x5&#vtrc?yrNmQOk zC}IK@bRh~6K}7{@T6p{9g?>XcLZku2g@Ae=;t`h}q~{xu*eaY(c&`!=SazIWKw>OE zLGc)mNI3X7Fd@6nDpy;Q0UVL?a~XNT6|!ctokOZEuqi;;Y!$o*JQZYQ&3dgwu6T}7-FBc&)kxCFj04KY*b`ID^!u#gh#9e!TfM|VgvZVH^nl76)QUu{H6iolMs0_J=)Al zOCfMcK)|Od5uXTvK)1pnN+>5^<`GH>)(ylmkkuBa#U~Dj(MeH8On4&ackw3ji(n0~ zZQ@nPh7n1$Yy@;6Pa_1|b%q?E{WLm4L7c&9i^XacM7F5V&WA_bjeY2v33Vf2<6F%8pfTdI2(e(4C#P;@HF-fxTlIC zWf#MNG3X%+LNs)Y2P}vO!8z%Gv|l=)9+VGxC}hdZ&dP;$f*>krF=_!WIDth+(76<+ zx<}qC?dyUQNnTn;W@ZjtN50_Y6(I`-K~XMvz@wIv+)IO>#-kRvxS*4d_%m_~3kr}gHz1cb%cdng>F=#@`Ah+TlnSoU)1u?u;}hY#n{ng9g`atZocWB}htt4K*OBXSS) zv`Y(I;MgJ6g_c@qX$}Tm+*wjuR9eIX7v4&RjeE%8i0Y7CdgQYIP{x5H*jhoj1NRea zbZ|bs#e#|=1f42mhx3XxPc3>maA0?)DH6NLfEsw8hEhMD+sKzwuvjF+;dfSw;03!j z+1VyNb|Ge%^w=d*y3$pt$1YF;3Xk;2Mdqu-6dh~Pixr^GJzPlG)deyhy})rNx=8dw z4M{v0=X7A7pyP9)%Uij1`_7$O2t#f-H|9tPqrybUdzWc7ng>0KtFv<3_U(EMlS%s5 zFNh&B5s^`Jp*TC?fmd$Xj;$pT#$;w21S7&hOo)t;uL5Ibfr2Z8>+2o6cJJ1r7>eMt z&{Rwm0~&=lV*m|BS0~`MelK!y_EeHun!*VRGL;HYiP+d}6 z4iV13!6B)1_6ufs+!-O|s|wMi6yJUXQv8SgznE|ae8obP7S3=}D-Ds0B@=rv`Os8C z=F%^i@eD|)2goW2;hZ_3nrEu8CSkW)vG7mJ%$OC$nz;ggVsRZK3)lb#acGj{-(68@ zb3!smX~{1z6?S9m77NqB3^+~1ej|KsKnL)HjJn)}TOLf6*p03zp|w6*Nr0`;S`W;N z27)H6Lj=A-?w!~rrtXx{`Zezo$Fx#!2^v7PL(vN(y!uXSxecy2TY_Lm?@+QEM7c&=41g47a@*;|3cyIWcrc&rFqCJ=r3ev?&1?EwYm4<`$I0IPF zMJ?IrKkTPt(hU|+Ktp>N%7fVHG4KWUxbo99;ZUdq>!*}Z5E#%W@^!GDY(!~H z00`6#WpU*}tJ8_S9y`{v3-eIWhXG?{6>|!&8vE67JrOOGD+ zOPA;!R?0BT1HOXD!oi{u)hr>yV^7!(UAn+HG-)cmiQkfTR zVN)MVmcWJ5V1)xtZx=Y_z~((ya=j5O>x0UG*}qHyoD-uu^&IZ9ZPRh3!difj(nbP8V zfEM))won#O6g~nihQ*Q2K$s=ykc>G+D#QO+;s*m1TGilq?6GELW5JCUPOx5WX9Lc{p5f4`uAH(9*L6zI$lL-$VqvIJq$t)Su``*Og&hShAf*6Cn5X21X#WChRTx$|U}HFdt;bdYt0VW4+*+}k zMH?4#ZV>vX6nKjYxRTQRL*+xZ3QWgY#9`VNh|4=e+6G?b7s5^A?y#|Z2%m2Js5T3I zP;$LkUV~24s$RZ_7ls2Y!{Geoln%vX0%92@HdCLaJhA(b4XNj=SS7<=TnY4x%$}B> z#d3AU5GbMT$Tmwu2 zRw>g%bUD})F&;tRvT_W${=5Rjiqt(n*=H#&+LO5W)~pS?0kp(NTPPVwf66*b=7~mt zx%iJyd$jqd0IT@MD)&m!Q3Y`oXx+$dg3}9UTc$o@3kJl6XipIP$)Y(iAvR5wm=-__ z?LrEbk|7;l?&$9^GAp?>Z@E0DE5{Yo0`;jWBBNEt_R61EG-&-Y~>Ih+r-yTFeQ7htfoHjiEF zvU1GqJi@ZcNPUv``H2R(QR-o=7t_`=-~?R_6`(y@{+6JvL_&+;(!tQaz4D$j`w#3# zE8q?OgFYGyLd5_FY}OV-LEx*)n20bkn)>#gMz+)LJy>()aZARbBQosWz+(crh>MLP zkunu{kHPSelaHxF-6ijqc6ROFi^X|tGU1@HT<9}x2EwR4v`j!U$E=Kr1M?bCMXC6V z^o*R5ojZ2!+PMn}Sk&&p14p23GSr2T$Uyto=qSMv&F5nO3ES~NrS02y$k?rs_6Lw> ze?$TL5nRgopoH3(zz~`(jeKMMw3YjAyO7Ma7dc(D6fI{5VE{^=KffRs^JuXfYDQX8 z%n67mh?uNrHqkmXoasILb|1(*e1v{nA&b4#JQN2Fc2YD7&H0nIxDilbn`Za6gYsby z?Fa&75Zimj(rCyppY{H z)Iox^Fdey>KoLL{_)XvgIvI-!8?h6xYrlN3hXQEYLg2ABrb1fIr{?5B&27h&$lW8w z+G#_I{|>%q1;v08@?9lD{V)~wxcM9^H1Q-HSlfopUmTlX2kZ||IKtRE{F6Vj)2%tyU8o}<3Xo!f26DMe5wr$?BZ5zcdTya5% zT}glbjgp=qFB08_3}~A= z6DC78)=R2PY9@j$Fb6&z{7(3D(#CFXGuUdPbqpCPp92#rq?_=2R8FXZMRcTf$W?7X zbf{LDDy6Cb#iVjou(GO3!KYens0mcp9zCkm%15O-rQXxf*x1~Rd}7)gQ!5RWSXGG( z7*_yU%r2$MTUk|IjsKJy2^4azbTm}oAlFL`p2nu;mKJPpVL`*Cpe2e&Ris%-l|k%u z7^;k%#$8i;v=;5v)ycfAre;vdXbnLu3ZoTD%|eqdQSN4RBfy=p`4*ESl`f~ zH2Ioa+YpKlMQ0V4&&h-KAtULFL1V*6?a#e2)38kh6|55dZIzLt2C^vVZ zc*nc%VZQ;{=FW>;!K!K$SJ302RyM*ecWe8xciv$LxlGOrTvC<4x(b3ef&0o)6{;aM z$c<97)Y9A9-hubJGKb3%2ex@2GOeUkYd}f4Ue-zm+B)8OPiD086mmJZ5<*la=$sf9 zigrQYni`vMwjOx!uA-M6g7!r@!%=U2Lp_GmD1-k24CieF8{!ONI7XKr(y!*4MUs~w zd1~4Nm1;w|ca1Cvg*1>tV%b2c^i)B6Nq=Q9z!;{G8r{4D?Z@8jFd~0daSnl|tJShD zGP%|W36QwZS4f~8CF2;aV+<91LZxzzg#SrX4RvSh$%-JWX0Y^K6s6p=I0#EZ%b_Y5 zLa4eH1n9x3`nvl1x;hYOig4_mp$w^vSfxNejNq=Tk_(p%PSq?yuJ1*8;u%IcjQNlb z28A$yDP#Y4A=QSC zLLyRKFIPBpwxewfqhu9AD6(Fz3v~*LxVfe^w{{#G%dlCGT|4wd=E$M<1c(lMfX$BM zEbL#v+t5gw)IJ`1hhLa-_QFu0s-#20tRz@|pasoLK%o%L4iJ^16_JnjLWv3gTRS=? zqJShsiD?G-ErTmGR{)YwNNx$WcU(q&b#a^zz#MCoYN6Ruo!sE3X{2Kk3pv0Lf0YZ* zjgXulEdT8ROdl~W>UP%!AyxT6qJUep}M2MEi~IUg?^O5 z|6wKonFKNqH$9AhD%8PG3&Xs_1P1cNEp!`V#7&tRpdPm*FfdcDBD<}vCj18CH8r8~ z1ja2IY^3|1qbT3d+|rT6ki1NAkM`&;y3*9znvA=hl~tIp$Rw(3sq&Uq{OY*UN5iFl zh_VpV73>s-3fx8=G#T@OUWp3GRNVTVmhZ42ijlTSM+5Z@EzMV>LzsAR!^er*u3_B- z|GXBAvgzn?HdVn{PzDH4s0|_SHk+jJPUI(*G)RrmeZVTA zBH0eA2LQt@@lm@ZPG}Z}h5^?>q!^J*ZVc=eL^5bXE)+-Y_yHtT9ut>b6R1T?ahMO> zq>yC4&3wWKpGdV_N@WjKjq+%GQoXQkOe}O!XrY_X!nF0N0ZVlx2o+l+ZjB5z>ri4-?6fa{7W)$)LkpQH)t1-vkh(&c`l;( z5O{^$6{Vtp@p=+IO$SsIt{c1;@EW=GE-%!C>n)6%oJZ0Ta-KX;Kbl_Nf&YSb4K5D2 zVFw1C21d!yK_XEb$TM>jvs>V9wZnnIOk)JI;jBXwF-qVo0kE;oNd0I4z`{FvC)R+@qOK^In`W-V1t+vQ(a24yjS=H4yRL3&^E|K@b#>2S^?a%`fDj$>=wL z0>hKr;ln_1C{?L@F@COYR8B%UKN)$8!plL)V6M6&BWer6ybTR*a?0A^?!A2>GYncv zZuYmdAL}?4{O6--h0H;z?*W6rf2d+dN5q%GEJH2^ z1jQAQ``I+yR=NEWcv=)gVHjlleC8(oGu6Y#Aaz2smlD2XVw6$B5H1l{?NR2)r7IJ9dCJa=<&(SKzqXCRloJKk& z8UYZu<7@}bpP@-ITtu!@p{70(L3_LI(Rg?X;6K?3fg>=8!jk4tTRZn?5LnZck6H|T z%oH_Z?g~&XlSpp?XI}DXP$G^`ZVhmQgUxO5XhKdrgeNSX!gWVPE^+S!kks0CIb=r> zIe8&u`v5oYB{oQCy>$vBLn8;1J1^8bG9L16NND8S@K8z2t%Mug!+_M`+d$f)%ctQs zV8X>Th+u&L2)<4DVGs|=!Z2o#&17+$hyosX0(HPm8Lo{9;-*_()ImNp9Ggn&ZdIrT z!8Go}(ST3Vp1@T2`Is|s*Mm0e>k(2UF{RQE&eT8~aPug7(b58^rm_>$BVj*&hg?Gy zH@Cp4sq$gOTwbCqc#L2DL7BR!3Yu5Ysg@S_G(70SvV*wO44($DOLipHVlr%Qf=`30 zXv*{PBCYUgxTL8T3Eao0nd;x zgwz0^1#9bh9ulQjqXBz}C$b|6fPQje

      hs8t@F#5Gabkn6@{O<4Fx64-ngs*atUZ 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�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 V3^Lh}tXF48XQ#r1SPiMb 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

      jBU?%ae^x&|KXd8a*|P++ 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 z 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

    _Ete?%y`u>cKxQ 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�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 JTZ;Aw|2NmVF(Lo} literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rgb_led/assets/Arr_up_7x9.png b/Applications/Official/DEV_FW/source/xMasterX/rgb_led/assets/Arr_up_7x9.png new file mode 100644 index 0000000000000000000000000000000000000000..28b4236a292708b412629ffafe30f6d011491505 GIT binary patch literal 3605 zcmaJ@c{r47|9>2^ZpP~Xl@BrVPMsS}}K`)IgU>xHk zuQ{^ZlqErKm`jmL$vXO)Qi=!THE;DRyVh>Cu@O^m&WRUIOpLs&>}nu;QTm<4xaRG| z^LOGewyt~#yA#k?we+cd{qb9i$>Mo_d8b5;q-?6ak*i6hYyoEX*7xU|8X7;0L#(2t zwb_88WI07MXiZB5SdK6^-v_Rdcn*jJ_sB>BHTbL=*siz@g)f+lqau+PL~6Ln`yC}C zl>n>IM9e+F%2p(jpRVH$QdDDFIb(FP#G03|=i1|;y#5P&&&`q={yo&Yr+iZW$@q$~h)jgQ$2h=l<@&01Q) zz=aGz$#%}u{EvO5ij(@nN@bLpS7;+`qP!&y10_5?A-nZD98~uynUa1XWm-Y%LNe44 zQN{}I=U)LpPO`Ev+xfNN4*AlK4%0+|{0YM^FT^*%zP@AY6P-nDD**Vwjp$l8fR^u! zJRly)SiikzM$G@XOwQ@0OMYbvR*!+4sR7S<_GWEtZe6M9@1GbSe|N9}<4tPy3}2_! zov86#JN0LT`RdZ*`{y6EqY%fU?8KJe*S%VB%H7p@RqBH8(5EE3)h99=s~SDv1_$2? zqQ26Y>$bo|T;}C@L@qc1b9L{_J>46WkD~@Fq86hjz=M+(B4Npf`Nznj-yC%niQJlx zO8_ue$*O&$Cn*}~fBr)!Z)4VS%`RsT5b5V|H4p%f?2-LmfsDBTb3i#qrr&9F5V7ZGWJl?*n~frD0s->K~iJmWR}N zJe5bY6~2=svupLLqNK#En)?ZviT(gwA}E4hLllTGa5 zZWjq44||O{H0Kv&+)>+S$p@MNMD%KGl^y(ARGBOKjqGD=MZVe23%0jqUQ@X6%p{eZ ztk;}JJJFX-Z%w`~@>dv0vcNXMYCi9fFlsmjgEZD-9_}}gN+GvB1Q*K|HSTvGJ3i8Rw)M}3 z9li*79MRrDt8ZJ>$ZH0mea$iB{PFs6qjB|d%{gyrzOPl_-DUTWdTy;J52{TlP8d&!Q_~UF9(OX` zhVyR`wwfdz!Iaz*xZQV+%inH%IuqG`Ud6#Nx8(Nqo}K=x{!8@xpSjPr4qxBxoc7wY zyKTzubJ}Oo1)i*2tn&G$c$%JC)((jsG&SCi`{_>i)Os$dH4$KD@UQ8U844LJ52C(6 z|EzLytMv7Q*LAL|>q7|zh4%_a3S~UzJ=zFK1;^dPOKm-j+{X%}-lP_J6!H&!bys(% z6&%QqE2QPK2$pvvyw(!Lz3QFnU9fjua~_@;t7-(vkk!hA4KxGfiegVknKbA;Z0|pN zM!zzBO{4M>y0G9D5^HqO$g|vS{+geq#8`UZ@(r%D)TCZs+I+;t5vAF^ANQ)?Gj^(g zQ;!A|rlzG5i|mVBi|oEuo0d-J@$XgJRC=vM$y+xa)IF+eM@#D1!k={ScOTA^&Qrmo zQH!OJ!hl@$Ta`H83ufL-diL|*U{8* z#DBrhWV+!i?(MyI!0CWfQ~Rs-+wFZBCRu3sTf}76WY*iP(I-Aff{z#o@&!++4rSv< z?s?4!s+ciHkY2e&k0Zy*ZAL2_eXb}`VQF}1)PJFOb zzz~F!XuhhnCofCuXHu$D!k>lzwuY9Fi|dy!(m0|K5%h?oggT5G$?Ui>V;TN(A$1B$ zBX%lwzB3vVY;W7!K_1Mu=X%#`|=i@IWI7YWY(kviZ>W#zA)#C@bi-E^Jgmy3T zv&ysTrt=5y&zR28XX1u#zB0bKH`~i7=yiQF_Py&wm!-_j>#%^);s_V4OBC(#q!yG6 zP4+B#``}3~uW*Spt7`Ghf^&1sV$9rZ1To@u;+0v=ljbLFF7>SJ6EUOMb6OjejnIuQ zATM%{2u(C0$~wyXmzCwvvzjjwEm4EiZ)N?{)|YcCtd*^kqD!JDYD+Zzn}5GjqPaAg z-jUovmybCV@wxA{1nCp$QhkK1ZcJQ^XRKu+JD#|+3!Y}e>l(rajpDxJQgI_$G`I`$ zzTrU=eTzcKN%H}-XU5Mg8zFvPuX>4mqQfc2T}X(2sVVc+^U>Am`M8h#k1}Ins_D?? zW9*Py9d!#ac`5~vZ3d`RE2ntp{n!3wt*D=`a(U0(cHW*u>5w{&IvN<-W!e@04trF8 zxAUC6K0fs7@5xmrA=)pEat$UbF6b6qsdAEY8qPvxt7M)5F%W1}HT?Y5i5-kDcSBkfI8A=N<_dXMj=)KjKD5Ft5{a&;uv?5cB zviG%5zbbDXykd4^_U6X)wz_Q}t_pHv9X$;-h@Yy9Pa@0A149O-$CS71i#;q}Z2t73 zK%dd;QZ((ERvJ;Q6N(RrI$qlvUHe!h;H!*>^h8Yf*P*x5$6Sa|uhGY(@3DM!3+051 zrAmXUY0Br`=?w)>sK>EdUt|njdsI-=P(kVR>-L-aG-8 z_YQhjEv;F!JRkHB@xb@`^-@oYq zy3qu;q`rM$?c|$&eZJ10~S zzMj(K(o}h)GPAVeXh6kGX!YYTzojYlY_pExh3b$$R5tp0vytfG>iJOC(#xgAQI+8c zj_z7VTV+2_cc!GurRv0j)wFd#b~vur(tCaA-R#i0lQq1Y`K}?mCGnW^o$JYqNeb94 zNf}9Pv2w9rv-evdksmENYg4Ov*iK5PPPXd$?e(@&RTXH&a_`r-9bM^Nx6(?43~sm+`Zpb9x*8e?DAvf1S6IqLz}f zAtstWzdCDjEn4_rsm8S-a@|>eTpo!-1*|D7UnJ$N^L?$d^i^GtuDL$`@b|oq`5?n&4r0HkRs7w-4n| z-9w!Tzk^;800GS7)gaQmImjnuCoMHx{g3;i=bWy_frWpzb{RQC$puztMiikf1 z!m>D2kQoGSNQS{+ATuO{N+BV9jr>St0}uj+fJ5QJ$IK9JhC&#j;7HKl11xmNq4=TP zaJGND6YkJpe=e7eftxd%|(NS!Tu);2KygbX3*c264neFOkzXf5ZGo`KY)1r|AsOc|Dc1o zZq)zA`~M0D5klBhs2eqib(%vKo}Hi8rYklI%b}9EEDnLiI`yNFhx}PwR**l74MG?} z;2=FbiA-m1TK4`$!Q)X5%pfj_Nv1mB&|skmgifcR%;2U*FcU1!2#Z0&;WoJaSgaY= z2xEf7?Z;qEk(eJ`9E*IKL1l7(a4G-g+WeHe*$@o2&@+z8p`W2rY&k3j=&!6%^q + +#include +#include +#include +#include + +#include +#include +#include + +#define TAG "LED_LL" + +#define LED_BPP 24 +#define ARR_TX 59 + +#define CCR_US_PERIOD 125 +#define CCR_US_0 40 +#define CCR_US_1 80 +#define CCR_0 (ARR_TX * CCR_US_0 / CCR_US_PERIOD) +#define CCR_1 (ARR_TX * CCR_US_1 / CCR_US_PERIOD) +#define CCR_RESET 0 +#define CCR_BUFFER_LEDS_HALF 8 +#define CCR_BUFFER_LEDS (CCR_BUFFER_LEDS_HALF * 2) +#define CCR_BUFFER_LEN (CCR_BUFFER_LEDS * LED_BPP) + + +static uint32_t rgb_buf[LED_COUNT]; +static uint32_t *rgb = rgb_buf; + +static uint32_t rgb_led_buf[LED_COUNT]; +static uint32_t *rgb_led = rgb_led_buf; + +static uint32_t rgb_offset = 0; +static uint8_t ccr_buffer[CCR_BUFFER_LEN]; + +static uint8_t brightness_i = 3; +static uint8_t is_transmitting = 0; + +static uint8_t apply_brightness(uint8_t v); +static uint8_t apply_gamma(uint8_t v); +static void fill_ccr_buffer(uint32_t ccr_led_offset, uint32_t ccr_led_count); + +const GpioPin gpio_led = {.port = GPIOA, .pin = LL_GPIO_PIN_4}; + +static void handle_dma() +{ + FURI_LOG_D("LED_LL", "HandleDMA Called"); + furi_crash("DMA ISR"); + + if(LL_DMA_IsActiveFlag_TE1(DMA1)) { + LL_DMA_ClearFlag_TE1(DMA1); + furi_crash("LED DMA Transfer did not work"); + } + else if (LL_DMA_IsActiveFlag_TC1(DMA1)) + { + if (rgb_offset > LED_COUNT) + { + LL_TIM_DisableCounter(TIM1); + is_transmitting = 0; + } + + fill_ccr_buffer(CCR_BUFFER_LEDS_HALF, CCR_BUFFER_LEDS_HALF); + rgb_offset += CCR_BUFFER_LEDS; + + LL_DMA_ClearFlag_TC1(DMA1); + } + else if (LL_DMA_IsActiveFlag_HT1(DMA1)) + { + fill_ccr_buffer(0, CCR_BUFFER_LEDS_HALF); + LL_DMA_ClearFlag_HT1(DMA1); + } +} + +void led_init() +{ + FURI_LOG_D(TAG, "Initializing"); + + furi_hal_gpio_init_ex(&gpio_led, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM1); + furi_hal_interrupt_set_isr_ex(FuriHalInterruptIdDma1Ch1, 4, handle_dma, NULL); + + FURI_CRITICAL_ENTER(); + LL_TIM_DeInit(TIM1); + FURI_CRITICAL_EXIT(); + + LL_TIM_InitTypeDef tim_init = {0}; + LL_TIM_OC_InitTypeDef tim_oc_init = {0}; + + tim_init.Prescaler = 0; + tim_init.CounterMode = LL_TIM_COUNTERMODE_UP; + tim_init.Autoreload = ARR_TX; + tim_init.RepetitionCounter = 0; + + LL_TIM_Init(TIM1, &tim_init); + LL_TIM_EnableAllOutputs(TIM1); + LL_TIM_EnableDMAReq_CC3(TIM1); + LL_TIM_EnableIT_CC3(TIM1); + + tim_oc_init.OCMode = LL_TIM_OCMODE_PWM1; + tim_oc_init.OCState = LL_TIM_OCSTATE_ENABLE; + tim_oc_init.CompareValue = 0; + + LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH1, &tim_oc_init); + LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1); + + LL_DMA_InitTypeDef dma_config = {0}; + dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->CCR3); + dma_config.MemoryOrM2MDstAddress = (uint32_t)NULL; + dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; + dma_config.Mode = LL_DMA_MODE_NORMAL; + dma_config.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; + dma_config.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; + dma_config.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_HALFWORD; + dma_config.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE; + dma_config.NbData = 0; + dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP; + dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH; //LL_DMA_PRIORITY_MEDIUM; // LL_DMA_PRIORITY_VERYHIGH + LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config); + LL_DMA_ClearFlag_TE1(DMA1); + LL_DMA_ClearFlag_TC1(DMA1); + LL_DMA_ClearFlag_HT1(DMA1); + LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1); + LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_1); + LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_1); +} + +void led_deinit() +{ + FURI_CRITICAL_ENTER(); + LL_TIM_DeInit(TIM1); + LL_DMA_DeInit(DMA1, LL_DMA_CHANNEL_1); + furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL); + FURI_CRITICAL_EXIT(); +} + +int8_t led_update() +{ + FURI_LOG_D(TAG, "LED UPDATE"); + FURI_LOG_D(TAG, "LL_DMA_IsEnabledChannel = %lu", LL_DMA_IsEnabledChannel(DMA1, LL_DMA_CHANNEL_1)); + + if(is_transmitting) { + // ONLY FOR DEBUGGING RIGHT NOW + FURI_LOG_D(TAG, "Led Update but still transmitting"); + return -1; + } + /*while (is_transmitting) + { + }*/ + is_transmitting = 1; + + for (uint8_t i = 0; i < LED_COUNT; i++) + { + uint32_t v = rgb[i]; + uint8_t r = RGB_R(v); + uint8_t g = RGB_G(v); + uint8_t b = RGB_B(v); + + r = apply_gamma(r); + r = apply_brightness(r); + + g = apply_gamma(g); + g = apply_brightness(g); + + b = apply_gamma(b); + b = apply_brightness(b); + + rgb_led[i] = RGB_UINT(r, g, b); + } + + rgb_offset = 0; + fill_ccr_buffer(0, CCR_BUFFER_LEDS); + rgb_offset += CCR_BUFFER_LEDS; + + FURI_LOG_D(TAG, "Led Update with buffer %d %d:%d:%d:%d:%d:%d", CCR_BUFFER_LEN, + ccr_buffer[0], + ccr_buffer[1], + ccr_buffer[2], + ccr_buffer[3], + ccr_buffer[4], + ccr_buffer[5] + ); + + FURI_CRITICAL_ENTER(); + LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1); + LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, (uint32_t)ccr_buffer); + LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, CCR_BUFFER_LEN); + LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_CIRCULAR); + LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); + LL_TIM_GenerateEvent_UPDATE(TIM1); + LL_TIM_EnableCounter(TIM1); + FURI_CRITICAL_EXIT(); + + FURI_LOG_D(TAG, "Led Update. Timer is %lu", LL_TIM_CC_IsEnabledChannel(TIM1, LL_TIM_CHANNEL_CH1)); + + return 0; +} + +uint8_t led_get_brightness() { return brightness_i; } + +uint32_t led_get(uint16_t i) { return rgb[i]; } + +void led_set(uint16_t i, uint32_t v) { rgb[i] = v; } + +void led_set_rgb(uint16_t i, uint32_t r, uint32_t g, uint32_t b) +{ + if (i >= LED_COUNT) + { + return; + } + + if (r > 255) + r = 255; + if (g > 255) + g = 255; + if (b > 255) + b = 255; + + led_set(i, RGB_UINT(r, g, b)); +} + +void led_set_rgbf(uint16_t i, float r, float g, float b) +{ + if (r < 0) + r = 0; + if (g < 0) + g = 0; + if (b < 0) + b = 0; + + if (r > 1) + r = 1; + if (g > 1) + g = 1; + if (b > 1) + b = 1; + + led_set_rgb(i, r * 255, g * 255, b * 255); +} + +void led_clear() +{ + for (uint32_t i = 0; i < LED_COUNT; i++) + { + led_set(i, 0); + } +} + +void led_set_brightness(uint8_t brightness) +{ + if (brightness > LED_BRIGHTNESS_MAX - 1) + brightness = LED_BRIGHTNESS_MAX - 1; + + brightness_i = brightness; +} + +static uint8_t apply_brightness(uint8_t v) +{ + static uint8_t brightness_table[LED_BRIGHTNESS_MAX] = {50, 25, 12}; + + return (uint16_t)v * + brightness_table[(LED_BRIGHTNESS_MAX - 1) - brightness_i] / 255; +} + +static uint8_t apply_gamma(uint8_t v) +{ + static uint8_t gamma_table[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, + 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, + 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, + 17, 17, 18, 18, 19, 19, 20, 21, 21, 22, 22, 23, 23, 24, 25, + 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 33, 34, 35, + 36, 36, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 78, + 79, 80, 81, 82, 84, 85, 86, 87, 88, 90, 91, 92, 93, 95, 96, + 97, 99, 100, 101, 103, 104, 105, 107, 108, 109, 111, 112, 114, 115, 117, + 118, 119, 121, 122, 124, 125, 127, 128, 130, 131, 133, 135, 136, 138, 139, + 141, 142, 144, 146, 147, 149, 151, 152, 154, 156, 157, 159, 161, 162, 164, + 166, 168, 169, 171, 173, 175, 176, 178, 180, 182, 184, 186, 187, 189, 191, + 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, + 223, 225, 227, 229, 231, 233, 235, 237, 239, 241, 244, 246, 248, 250, 252, + 255}; + + return gamma_table[v]; +} + +static void fill_ccr_buffer(uint32_t ccr_led_offset, uint32_t ccr_led_count) +{ + for (uint32_t ccr_led_i = 0; ccr_led_i < ccr_led_count; ccr_led_i++) + { + uint8_t rgb_i = rgb_offset + ccr_led_offset + ccr_led_i; + uint32_t rgb_value = rgb_led[rgb_i]; + + uint16_t buff_offset = (ccr_led_offset + ccr_led_i) * LED_BPP; + for (uint8_t bit_i = 0; bit_i < 24; bit_i++) + { + uint16_t buff_i = buff_offset + bit_i; + + if (rgb_i >= LED_COUNT) + { + ccr_buffer[buff_i] = CCR_RESET; + } + else + { + uint8_t rgb_bit_offset = 23 - bit_i; + uint8_t rgb_bit = (rgb_value >> rgb_bit_offset) & 1; + + ccr_buffer[buff_i] = rgb_bit ? CCR_1 : CCR_0; + } + } + } +} + diff --git a/Applications/Official/DEV_FW/source/xMasterX/rgb_led/led_ll.h b/Applications/Official/DEV_FW/source/xMasterX/rgb_led/led_ll.h new file mode 100644 index 000000000..c4a54211d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rgb_led/led_ll.h @@ -0,0 +1,28 @@ +#ifndef _LED_H +#define _LED_H + +#include + +#define LED_BRIGHTNESS_MAX 3 +#define LED_COUNT 100 + +#define RGB_UINT(R, G, B) (((G) << 16) | ((R) << 8) | (B)) +#define RGB_R(V) ((V >> 8) & 0xFF) +#define RGB_G(V) ((V >> 16) & 0xFF) +#define RGB_B(V) (V & 0xFF) + + +void led_init(); +void led_deinit(); +int8_t led_update(); +uint8_t led_get_brightness(); +uint32_t led_get(uint16_t i); + +void led_set(uint16_t i, uint32_t v); +void led_set_rgb(uint16_t i, uint32_t r, uint32_t g, uint32_t b); +void led_set_rgbf(uint16_t i, float r, float g, float b); +void led_clear(); + +void led_set_brightness(uint8_t brightness); + +#endif \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/rgb_led/rgb_led.c b/Applications/Official/DEV_FW/source/xMasterX/rgb_led/rgb_led.c new file mode 100644 index 000000000..2f0736426 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rgb_led/rgb_led.c @@ -0,0 +1,118 @@ +#include "rgb_led.h" +#include +#include +#include +#define TAG "RgbLedApp" + +enum RgbLedSubmenuIndex { + RgbLedSubmenuIndexDefault, +}; + +void rgb_led_submenu_callback(void* context, uint32_t index) { + furi_assert(context); + RgbLed* app = context; + if(index == RgbLedSubmenuIndexDefault) { + app->view_id = RgbLedViewDefault; + view_dispatcher_switch_to_view(app->view_dispatcher, RgbLedViewDefault); + } +} + +void rgb_led_dialog_callback(DialogExResult result, void* context) { + furi_assert(context); + RgbLed* 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, RgbLedViewSubmenu); + } +} + +uint32_t rgb_led_exit_confirm_view(void* context) { + UNUSED(context); + return RgbLedViewExitConfirm; +} + +uint32_t rgb_led_exit(void* context) { + UNUSED(context); + return VIEW_NONE; +} + +RgbLed* rgb_led_app_alloc() { + RgbLed* app = malloc(sizeof(RgbLed)); + + // Gui + app->gui = furi_record_open(RECORD_GUI); + + // 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); + + // Submenu view + app->submenu = submenu_alloc(); + submenu_add_item( + app->submenu, "Default", RgbLedSubmenuIndexDefault, rgb_led_submenu_callback, app); + view_set_previous_callback(submenu_get_view(app->submenu), rgb_led_exit); + view_dispatcher_add_view(app->view_dispatcher, RgbLedViewSubmenu, submenu_get_view(app->submenu)); + + // Dialog view + app->dialog = dialog_ex_alloc(); + dialog_ex_set_result_callback(app->dialog, rgb_led_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, RgbLedViewExitConfirm, dialog_ex_get_view(app->dialog)); + + // Default view + app->rgb_led_default = rgb_led_default_alloc(); + view_set_previous_callback( + rgb_led_default_get_view(app->rgb_led_default), rgb_led_exit_confirm_view); + view_dispatcher_add_view( + app->view_dispatcher, RgbLedViewDefault, rgb_led_default_get_view(app->rgb_led_default)); + + // TODO switch to menu after Media is done + app->view_id = RgbLedViewSubmenu; + view_dispatcher_switch_to_view(app->view_dispatcher, app->view_id); + + return app; +} + +void rgb_led_app_free(RgbLed* app) { + furi_assert(app); + + // Reset notification + notification_internal_message(app->notifications, &sequence_reset_blue); + + // Free views + view_dispatcher_remove_view(app->view_dispatcher, RgbLedViewSubmenu); + submenu_free(app->submenu); + view_dispatcher_remove_view(app->view_dispatcher, RgbLedViewExitConfirm); + dialog_ex_free(app->dialog); + view_dispatcher_remove_view(app->view_dispatcher, RgbLedViewDefault); + rgb_led_default_free(app->rgb_led_default); + view_dispatcher_free(app->view_dispatcher); + // Close records + furi_record_close(RECORD_GUI); + app->gui = NULL; + furi_record_close(RECORD_NOTIFICATION); + app->notifications = NULL; + + // Free rest + free(app); +} + +int32_t rgb_led_app(void* p) { + UNUSED(p); + RgbLed* app = rgb_led_app_alloc(); + view_dispatcher_run(app->view_dispatcher); + rgb_led_app_free(app); + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/rgb_led/rgb_led.h b/Applications/Official/DEV_FW/source/xMasterX/rgb_led/rgb_led.h new file mode 100644 index 000000000..e92b9f155 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rgb_led/rgb_led.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include "views/rgb_led_default.h" + +typedef struct { + Gui* gui; + NotificationApp* notifications; + ViewDispatcher* view_dispatcher; + Submenu* submenu; + DialogEx* dialog; + RgbLedDefault* rgb_led_default; + uint32_t view_id; +} RgbLed; + +typedef enum { + RgbLedViewSubmenu, + RgbLedViewDefault, + RgbLedViewExitConfirm, +} RgbLedViewView; diff --git a/Applications/Official/DEV_FW/source/xMasterX/rgb_led/rgb_led_10px.png b/Applications/Official/DEV_FW/source/xMasterX/rgb_led/rgb_led_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..713d79a8ea7536e8ee9671c62f9d606c11a8ed53 GIT binary patch literal 2378 zcmcIle{9rb814qj7%+wynIf(hA`t2I=k>022W)q@?G|o3#tGZdj9&Y7tGjDU+wE=( zW{dJeWPyMoqC$`uO$N#zCQ5M8jVOp>h@wC+CNutH)X0K}e?Sz!-Y*7@xtMs#-FR0w|yBTYXeNP$Q7`y-XI9s_7&O%=L? z;(6~<1X;3s@2;V`k0bYQ8=4zFx;HmGPEnHl4qVmf0O;b(|Jn!E;^PU|ezaJRkA3j^~M(pB&t*f_QZ93BR_3ooT zp1Cwn*;m+CzwgbiBb`X;;*Fn_jf@ucT?`LiW>4MdrOV%{o3e1j;C%4t3&md!og289 zn)=1-2cIdO-8WGGt-G{g<-p4~=0}Rnn@HW~*EW^5_Fb}k<^BBdOtZCM)q9`GT*%B%G4oO?~`Ruy!1=#Q{%ysQL!f~4|aS#cU>a=KC5Y$3>uxz4u$d3Apof=tuZXp`L(UL{C+!X-NSb)^ypL?cMWij*Nr z9l%CopiR|$*y!L8hN`j;TjvgwVZ#sF)!H5ttm&zbNETL`pOW%0)Vd$^paSiJ^%^ z9&OpdE*K@NcU)pC+HC-$5msGsd7j5~+w<(mRd_beqjHlBh zO9Y661mw0LmP+e01iuMHTQ{S+9?z93l8cDaw2MTStWz~vPg+YIMcEA?Alkr(!K%?X z$>S6orD=iY1=jmG$p|Ewfrg53+@l-Qm2y%XMe`HvMxc6 zd^QCcNEE3s9L~uShsPMm7L$M*r-55mBsNC5X-|%=!Bk=Ii1D$kjw%^4k__!(ScSuR zMwW1qVcj@SyA@obxR~ONNgSnc7qib#5O<}TASl$ z$PQ0Yt6H#h-P!(F12$$?aTQIQP7o!>>po0!iVS2dds`hRdy~_dp-r{}NIF6BGcZe6 z?4)Rd$~Ktke>E3zH}RI(HL-NYLn{&u6C2|IgDWDd;JgP~Kw??NodovZ4>LIzk6VX-_SIzT;2zuLnN4>bhH&1O8HW*fn(vl*a}7`lThpu +#include +#include +#include + +struct RgbLedDefault{ + View* view; +}; + +typedef struct { + bool left_pressed; + bool up_pressed; + bool right_pressed; + bool down_pressed; + bool ok_pressed; + bool back_pressed; + bool connected; +} RgbLedDefaultModel; + +uint8_t led_status = 0; + +void rgb_led_init() { + /// let's see it crashes + led_init(); +} + +#define COLORS_LEN 7 + +uint32_t colors[COLORS_LEN][3] = { + {255, 255, 255}, + {255, 0, 0}, + {0, 255, 0}, + {0, 0, 255}, + {255, 255, 0}, + {255, 0, 255}, + {0, 255, 255} +}; + +void rgb_led_fire() { + for (uint8_t i = 0; i < 15; i++) + { + uint8_t r = colors[3][0]; + uint8_t g = colors[3][1]; + uint8_t b = colors[3][2]; + + led_set_rgb(i, r, g, b); + } + + led_status = led_update(); + + +} + +static void rgb_led_default_draw_callback(Canvas* canvas, void* context) { + furi_assert(context); + RgbLedDefaultModel* model = context; + canvas_set_font(canvas, FontPrimary); + elements_multiline_text_aligned(canvas, 0, 20, AlignLeft, AlignTop, model->up_pressed ? "HIT" : "WAIT"); + elements_multiline_text_aligned(canvas, 0, 40, AlignLeft, AlignTop, led_status == 0 ? "LED OK" : "BUSY"); + return; +} + +static void rgb_led_default_process(RgbLedDefault* rgb_led_default, InputEvent* event) { + with_view_model( + rgb_led_default->view, + RgbLedDefaultModel * model, + { + if(event->type == InputTypePress) { + if(event->key == InputKeyUp) { + rgb_led_fire(); + model->up_pressed = true; + } + } else if(event->type == InputTypeRelease) { + if(event->key == InputKeyUp) { + model->up_pressed = false; + } + } + }, + true); +} + +static bool rgb_led_default_input_callback(InputEvent* event, void* context) { + furi_assert(context); + RgbLedDefault* rgb_led_default = context; + bool consumed = false; + + if(event->type == InputTypeLong && event->key == InputKeyBack) { +// furi_hal_hid_kb_release_all(); + } else { + rgb_led_default_process(rgb_led_default, event); + consumed = true; + } + + return consumed; +} + +RgbLedDefault* rgb_led_default_alloc() { + RgbLedDefault* rgb_led_default = malloc(sizeof(RgbLedDefault)); + rgb_led_default->view = view_alloc(); + view_set_context(rgb_led_default->view, rgb_led_default); + view_allocate_model(rgb_led_default->view, ViewModelTypeLocking, sizeof(RgbLedDefaultModel)); + view_set_draw_callback(rgb_led_default->view, rgb_led_default_draw_callback); + view_set_input_callback(rgb_led_default->view, rgb_led_default_input_callback); + + rgb_led_init(); + + return rgb_led_default; +} + +void rgb_led_default_free(RgbLedDefault* rgb_led_default) { + furi_assert(rgb_led_default); + view_free(rgb_led_default->view); + free(rgb_led_default); +} + +View* rgb_led_default_get_view(RgbLedDefault* rgb_led_default) { + furi_assert(rgb_led_default); + + return rgb_led_default->view; +} + +void rgb_led_default_set_connected_status(RgbLedDefault* rgb_led_default, bool connected) { + furi_assert(rgb_led_default); + with_view_model( + rgb_led_default->view, RgbLedDefaultModel * model, { model->connected = connected; }, true); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/rgb_led/views/rgb_led_default.h b/Applications/Official/DEV_FW/source/xMasterX/rgb_led/views/rgb_led_default.h new file mode 100644 index 000000000..c66c9d670 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rgb_led/views/rgb_led_default.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include "../led_ll.h" + + +void rgb_led_init(void); + +typedef struct RgbLedDefault RgbLedDefault; + +RgbLedDefault* rgb_led_default_alloc(); + +void rgb_led_default_free(RgbLedDefault* rgb_led_default); + +View* rgb_led_default_get_view(RgbLedDefault* rgb_led_default); + +void rgb_led_default_set_connected_status(RgbLedDefault* rgb_led_default, bool connected); diff --git a/Applications/Official/DEV_FW/source/xMasterX/rmdice/application.fam b/Applications/Official/DEV_FW/source/xMasterX/rmdice/application.fam new file mode 100644 index 000000000..3ce862cc8 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rmdice/application.fam @@ -0,0 +1,12 @@ +App( + appid="RM_Dice", + name="RM Dice", + apptype=FlipperAppType.EXTERNAL, + entry_point="dice_app", + cdefines=["APP_DICE"], + requires=["gui"], + stack_size=2 * 1024, + order=70, + fap_icon="dice.png", + fap_category="Games_Extra", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/rmdice/dice.c b/Applications/Official/DEV_FW/source/xMasterX/rmdice/dice.c new file mode 100644 index 000000000..66d7edca2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rmdice/dice.c @@ -0,0 +1,575 @@ +#include +#include +#include "furi_hal_random.h" +#include +#include +#include + +#define TAG "Dice Roller" + +typedef enum { + EventTypeTick, + EventTypeKey, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} PluginEvent; + +typedef struct { + FuriMutex* mutex; + FuriMessageQueue* event_queue; + //DesktopSettings* desktop_settings; + FuriHalRtcDateTime datetime; + uint8_t diceSelect; + uint8_t diceQty; + uint8_t diceRoll; + uint8_t playerOneScore; + uint8_t playerTwoScore; + char rollTime[1][15]; + char diceType[1][11]; + char strings[5][45]; + char theScores[1][45]; + bool letsRoll; +} DiceState; + +static void dice_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 dice_render_callback(Canvas* const canvas, void* ctx) { + DiceState* state = ctx; + if(furi_mutex_acquire(state->mutex, 200) != FuriStatusOk) { + // Can't obtain mutex, requeue render + PluginEvent event = {.type = EventTypeTick}; + furi_message_queue_put(state->event_queue, &event, 0); + return; + } + + canvas_set_font(canvas, FontSecondary); + if(state->diceSelect < 220) { + if(state->diceQty == 1) { + elements_button_left(canvas, "x1"); + } else if(state->diceQty == 2) { + elements_button_left(canvas, "x2"); + } else if(state->diceQty == 3) { + elements_button_left(canvas, "x3"); + } else if(state->diceQty == 4) { + elements_button_left(canvas, "x4"); + } else if(state->diceQty == 5) { + elements_button_left(canvas, "x5"); + } else if(state->diceQty == 6) { + elements_button_left(canvas, "x6"); + } + } + if(state->letsRoll) { + furi_hal_rtc_get_datetime(&state->datetime); + uint8_t hour = state->datetime.hour; + char strAMPM[3]; + snprintf(strAMPM, sizeof(strAMPM), "%s", "AM"); + if(hour > 12) { + hour -= 12; + snprintf(strAMPM, sizeof(strAMPM), "%s", "PM"); + } + snprintf( + state->rollTime[0], + sizeof(state->rollTime[0]), + "%.2d:%.2d:%.2d %s", + hour, + state->datetime.minute, + state->datetime.second, + strAMPM); + if(state->diceSelect == 229) { + const char* eightBall[] = { + "It is certain", + "Without a doubt", + "You may rely on it", + "Yes definitely", + "It is decidedly so", + "As I see it, yes", + "Most likely", + "Yes", + "Outlook good", + "Signs point to yes", + "Reply hazy try again", + "Better not tell you now", + "Ask again later", + "Cannot predict now", + "Concentrate and ask again", + "Don't count on it", + "Outlook not so good", + "My sources say no", + "Very doubtful", + "My reply is no"}; + state->diceRoll = + ((rand() % state->diceSelect) + 1); // JUST TO GET IT GOING? AND FIX BUG + snprintf(state->diceType[0], sizeof(state->diceType[0]), "%s", "8BALL"); + snprintf( + state->strings[0], + sizeof(state->strings[0]), + "%s at %s", + state->diceType[0], + state->rollTime[0]); + uint8_t d1_i = rand() % COUNT_OF(eightBall); + snprintf(state->strings[1], sizeof(state->strings[1]), "%s", eightBall[d1_i]); + } else if(state->diceSelect == 228) { + const char* eightBall[] = { + "I'd do it.", + "Hell, yeah!", + "You bet your life!", + "What are you waiting for?", + "You could do worse things.", + "Sure, I won't tell.", + "Yeah, you got this. Would I lie to you?", + "Looks like fun to me. ", + "Yeah, sure, why not?", + "DO IT!!!", + "Who's it gonna hurt?", + "Can you blame someone else?", + "Ask me again later.", + "Maybe, maybe not, I can't tell right now. ", + "Are you the betting type? ", + "Don't blame me if you get caught.", + "What have you got to lose?", + "I wouldn't if I were you.", + "My money's on the snowball.", + "Oh Hell no!"}; + state->diceRoll = + ((rand() % state->diceSelect) + 1); // JUST TO GET IT GOING? AND FIX BUG + snprintf(state->diceType[0], sizeof(state->diceType[0]), "%s", "Devil Ball"); + snprintf( + state->strings[0], + sizeof(state->strings[0]), + "%s at %s", + state->diceType[0], + state->rollTime[0]); + uint8_t d1_i = rand() % COUNT_OF(eightBall); + snprintf(state->strings[1], sizeof(state->strings[1]), "%s", eightBall[d1_i]); + } else if(state->diceSelect == 230) { + const char* diceOne[] = { + "Nibble", + "Massage", + "Touch", + "Caress", + "Pet", + "Fondle", + "Suck", + "Lick", + "Blow", + "Kiss", + "???"}; + const char* diceTwo[] = { + "Navel", + "Ears", + "Lips", + "Neck", + "Hand", + "Thigh", + "Nipple", + "Breasts", + "???", + "Genitals"}; + state->diceRoll = + ((rand() % state->diceSelect) + 1); // JUST TO GET IT GOING? AND FIX BUG + snprintf(state->diceType[0], sizeof(state->diceType[0]), "%s", "SEX?"); + snprintf( + state->strings[0], + sizeof(state->strings[0]), + "%s at %s", + state->diceType[0], + state->rollTime[0]); + uint8_t d1_i = rand() % COUNT_OF(diceOne); + uint8_t d2_i = rand() % COUNT_OF(diceTwo); + snprintf( + state->strings[1], + sizeof(state->strings[1]), + "%s %s", + diceOne[d1_i], + diceTwo[d2_i]); + } else if(state->diceSelect == 231) { + const char* deckOne[] = {"2H", "2C", "2D", "2S", "3H", "3C", "3D", "3S", "4H", + "4C", "4D", "4S", "5H", "5C", "5D", "5S", "6H", "6C", + "6D", "6S", "7H", "7C", "7D", "7S", "8H", "8C", "8D", + "8S", "9H", "9C", "9D", "9S", "10H", "10C", "10D", "10S", + "JH", "JC", "JD", "JS", "QH", "QC", "QD", "QS", "KH", + "KC", "KD", "KS", "AH", "AC", "AD", "AS"}; + char* deckTwo[] = {"2H", "2C", "2D", "2S", "3H", "3C", "3D", "3S", "4H", + "4C", "4D", "4S", "5H", "5C", "5D", "5S", "6H", "6C", + "6D", "6S", "7H", "7C", "7D", "7S", "8H", "8C", "8D", + "8S", "9H", "9C", "9D", "9S", "10H", "10C", "10D", "10S", + "JH", "JC", "JD", "JS", "QH", "QC", "QD", "QS", "KH", + "KC", "KD", "KS", "AH", "AC", "AD"}; // ONE LESS SINCE ONE WILL BE REMOVED + state->diceRoll = + ((rand() % state->diceSelect) + 1); // JUST TO GET IT GOING? AND FIX BUG + snprintf(state->diceType[0], sizeof(state->diceType[0]), "%s", "WAR!"); + snprintf( + state->strings[0], + sizeof(state->strings[0]), + "%s at %s", + state->diceType[0], + state->rollTime[0]); + uint8_t d1_i = rand() % COUNT_OF(deckOne); + // INITIALIZE WITH PLACEHOLDERS TO AVOID MAYBE UNINITIALIZED ERROR + for(uint8_t i = 0; i < COUNT_OF(deckOne); i++) { + if(i < d1_i) { + snprintf(deckTwo[i], 8, "%s", deckOne[i]); + } else if(i > d1_i) { + snprintf(deckTwo[i - 1], 8, "%s", deckOne[i]); + } + } + uint8_t d2_i = rand() % COUNT_OF(deckTwo); + if(d1_i > d2_i) { + state->playerOneScore++; + snprintf( + state->strings[1], + sizeof(state->strings[1]), + "%s > %s", + deckOne[d1_i], + deckTwo[d2_i]); + } else { + state->playerTwoScore++; + snprintf( + state->strings[1], + sizeof(state->strings[1]), + "%s < %s", + deckOne[d1_i], + deckTwo[d2_i]); + } + } else if(state->diceSelect == 232) { + const char* diceOne[] = { + "You", "You choose", "Nobody", "Everyone", "Nose goes", "Player to your right"}; + const char* diceTwo[] = { + "take a tiny toke", + "just chill", + "take 2 tokes", + "take a huge hit", + "bogart it", + "take a puff"}; + const char* diceThree[] = { + "while humming a tune", + "with your eyes closed", + "on your knees", + "while holding your nose", + "while spinning in a circle", + "in slow motion"}; + const char* diceFour[] = { + "twice", + "then tell a joke", + "then laugh as hard as you can", + "with the player to your left", + "then sing a song", + "then do a dance"}; + state->diceRoll = + ((rand() % state->diceSelect) + 1); // JUST TO GET IT GOING? AND FIX BUG + snprintf(state->diceType[0], sizeof(state->diceType[0]), "%s", "WEED!"); + snprintf( + state->strings[0], + sizeof(state->strings[0]), + "%s at %s", + state->diceType[0], + state->rollTime[0]); + uint8_t d1_i = rand() % COUNT_OF(diceOne); + uint8_t d2_i = rand() % COUNT_OF(diceTwo); + uint8_t d3_i = rand() % COUNT_OF(diceThree); + uint8_t d4_i = rand() % COUNT_OF(diceFour); + snprintf(state->strings[1], sizeof(state->strings[1]), "%s", diceOne[d1_i]); + snprintf(state->strings[2], sizeof(state->strings[2]), "%s", diceTwo[d2_i]); + snprintf(state->strings[3], sizeof(state->strings[3]), "%s", diceThree[d3_i]); + snprintf(state->strings[4], sizeof(state->strings[4]), "%s", diceFour[d4_i]); + } else { + state->diceRoll = ((rand() % state->diceSelect) + 1); + snprintf( + state->diceType[0], sizeof(state->diceType[0]), "%s%d", "d", state->diceSelect); + snprintf( + state->strings[0], + sizeof(state->strings[0]), + "%d%s at %s", + state->diceQty, + state->diceType[0], + state->rollTime[0]); + /*if(state->diceSelect >= 20 && state->diceRoll == state->diceSelect) + DOLPHIN_DEED(getRandomDeed()); + if(state->diceSelect >= 20 && state->diceRoll == state->diceSelect - 1) + DOLPHIN_DEED(getRandomDeed());*/ + if(state->diceQty == 1) { + snprintf(state->strings[1], sizeof(state->strings[1]), "%d", state->diceRoll); + } else if(state->diceQty == 2) { + snprintf( + state->strings[1], + sizeof(state->strings[1]), + "%d %d", + state->diceRoll, + ((rand() % state->diceSelect) + 1)); + } else if(state->diceQty == 3) { + snprintf( + state->strings[1], + sizeof(state->strings[1]), + "%d %d %d", + state->diceRoll, + ((rand() % state->diceSelect) + 1), + ((rand() % state->diceSelect) + 1)); + } else if(state->diceQty == 4) { + snprintf( + state->strings[1], + sizeof(state->strings[1]), + "%d %d %d %d", + state->diceRoll, + ((rand() % state->diceSelect) + 1), + ((rand() % state->diceSelect) + 1), + ((rand() % state->diceSelect) + 1)); + } else if(state->diceQty == 5) { + snprintf( + state->strings[1], + sizeof(state->strings[1]), + "%d %d %d %d %d", + state->diceRoll, + ((rand() % state->diceSelect) + 1), + ((rand() % state->diceSelect) + 1), + ((rand() % state->diceSelect) + 1), + ((rand() % state->diceSelect) + 1)); + } else if(state->diceQty == 6) { + snprintf( + state->strings[1], + sizeof(state->strings[1]), + "%d %d %d %d %d %d", + state->diceRoll, + ((rand() % state->diceSelect) + 1), + ((rand() % state->diceSelect) + 1), + ((rand() % state->diceSelect) + 1), + ((rand() % state->diceSelect) + 1), + ((rand() % state->diceSelect) + 1)); + } + } + state->letsRoll = false; + } + furi_mutex_release(state->mutex); + if(state->diceRoll != 0) { + if(state->diceSelect == 232) { + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned(canvas, 64, 8, AlignCenter, AlignCenter, state->strings[0]); + canvas_draw_str_aligned(canvas, 64, 18, AlignCenter, AlignCenter, state->strings[1]); + canvas_draw_str_aligned(canvas, 64, 26, AlignCenter, AlignCenter, state->strings[2]); + canvas_draw_str_aligned(canvas, 64, 34, AlignCenter, AlignCenter, state->strings[3]); + canvas_draw_str_aligned(canvas, 64, 42, AlignCenter, AlignCenter, state->strings[4]); + } else if(state->diceSelect == 228 || state->diceSelect == 229) { + canvas_set_font(canvas, FontBatteryPercent); + canvas_draw_str_aligned(canvas, 64, 20, AlignCenter, AlignCenter, state->strings[1]); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned(canvas, 64, 8, AlignCenter, AlignCenter, state->strings[0]); + } else { + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned(canvas, 64, 20, AlignCenter, AlignCenter, state->strings[1]); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned(canvas, 64, 8, AlignCenter, AlignCenter, state->strings[0]); + } + if(state->diceSelect == 231 && + !(state->playerOneScore == 0 && state->playerTwoScore == 0)) { + canvas_set_font(canvas, FontSecondary); + snprintf( + state->theScores[0], + sizeof(state->theScores[0]), + "%d %d", + state->playerOneScore, + state->playerTwoScore); + canvas_draw_str_aligned(canvas, 64, 34, AlignCenter, AlignCenter, state->theScores[0]); + } + } + if(state->diceSelect == 229 || state->diceSelect == 228) { + elements_button_center(canvas, "Shake"); + } else if(state->diceSelect == 231) { + elements_button_center(canvas, "Draw"); + } else { + elements_button_center(canvas, "Roll"); + } + if(state->diceSelect == 2) { + elements_button_right(canvas, "d2"); + } else if(state->diceSelect == 3) { + elements_button_right(canvas, "d3"); + } else if(state->diceSelect == 4) { + elements_button_right(canvas, "d4"); + } else if(state->diceSelect == 6) { + elements_button_right(canvas, "d6"); + } else if(state->diceSelect == 8) { + elements_button_right(canvas, "d8"); + } else if(state->diceSelect == 10) { + elements_button_right(canvas, "d10"); + } else if(state->diceSelect == 12) { + elements_button_right(canvas, "d12"); + } else if(state->diceSelect == 20) { + elements_button_right(canvas, "d20"); + } else if(state->diceSelect == 59) { + elements_button_right(canvas, "d59"); + } else if(state->diceSelect == 69) { + elements_button_right(canvas, "d69"); + } else if(state->diceSelect == 100) { + elements_button_right(canvas, "d100"); + } else if(state->diceSelect == 229) { + elements_button_right(canvas, "8BALL"); + } else if(state->diceSelect == 228) { + elements_button_right(canvas, "DBALL"); + } else if(state->diceSelect == 230) { + elements_button_right(canvas, "SEX"); + } else if(state->diceSelect == 231) { + elements_button_right(canvas, "WAR"); + } else if(state->diceSelect == 232) { + elements_button_right(canvas, "WEED"); + } +} + +static void dice_state_init(DiceState* const state) { + memset(state, 0, sizeof(DiceState)); + furi_hal_rtc_get_datetime(&state->datetime); + state->diceSelect = 20; + state->diceQty = 1; + state->diceRoll = 0; + state->playerOneScore = 0; + state->playerTwoScore = 0; + state->letsRoll = false; + //state->desktop_settings = malloc(sizeof(DesktopSettings)); +} + +static void dice_tick(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + PluginEvent event = {.type = EventTypeTick}; + // It's OK to lose this event if system overloaded + furi_message_queue_put(event_queue, &event, 0); +} + +int32_t dice_app(void* p) { + UNUSED(p); + DiceState* plugin_state = malloc(sizeof(DiceState)); + dice_state_init(plugin_state); + plugin_state->event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); + if(plugin_state->event_queue == NULL) { + FURI_LOG_E(TAG, "cannot create event queue\n"); + free(plugin_state); + return 255; + } + + plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); + if(plugin_state->mutex == NULL) { + FURI_LOG_E(TAG, "cannot create mutex\n"); + furi_message_queue_free(plugin_state->event_queue); + free(plugin_state); + return 255; + } + + FuriTimer* timer = + furi_timer_alloc(dice_tick, FuriTimerTypePeriodic, plugin_state->event_queue); + if(timer == NULL) { + FURI_LOG_E(TAG, "cannot create timer\n"); + furi_mutex_free(plugin_state->mutex); + furi_message_queue_free(plugin_state->event_queue); + free(plugin_state); + return 255; + } + + //DESKTOP_SETTINGS_LOAD(plugin_state->desktop_settings); + + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, dice_render_callback, plugin_state); + view_port_input_callback_set(view_port, dice_input_callback, plugin_state->event_queue); + + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + furi_timer_start(timer, furi_kernel_get_tick_frequency()); + + // Main loop + PluginEvent event; + for(bool processing = true; processing;) { + FuriStatus event_status = furi_message_queue_get(plugin_state->event_queue, &event, 100); + if(event_status == FuriStatusOk) { + if(event.type == EventTypeKey) { + if(event.input.type == InputTypeShort || event.input.type == InputTypeRepeat) { + switch(event.input.key) { + case InputKeyUp: + break; + case InputKeyDown: + break; + case InputKeyRight: + if(plugin_state->diceSelect == 2) { + plugin_state->diceSelect = 3; + } else if(plugin_state->diceSelect == 3) { + plugin_state->diceSelect = 4; + } else if(plugin_state->diceSelect == 4) { + plugin_state->diceSelect = 6; + } else if(plugin_state->diceSelect == 6) { + plugin_state->diceSelect = 8; + } else if(plugin_state->diceSelect == 8) { + plugin_state->diceSelect = 10; + } else if(plugin_state->diceSelect == 10) { + plugin_state->diceSelect = 12; + } else if(plugin_state->diceSelect == 12) { + plugin_state->diceSelect = 20; + } else if(plugin_state->diceSelect == 20) { + plugin_state->diceSelect = 100; + } else if(plugin_state->diceSelect == 100) { + /*if(plugin_state->desktop_settings->is_dumbmode) { + plugin_state->diceSelect = 231; + } else {*/ + plugin_state->diceSelect = 230; + //} + } else if(plugin_state->diceSelect == 230) { + plugin_state->playerOneScore = 0; + plugin_state->playerTwoScore = 0; + plugin_state->diceSelect = 231; + } else if(plugin_state->diceSelect == 231) { + plugin_state->diceSelect = 229; + } else if(plugin_state->diceSelect == 229) { + plugin_state->diceSelect = 228; + } else if(plugin_state->diceSelect == 228) { + /*if(plugin_state->desktop_settings->is_dumbmode) { + plugin_state->diceSelect = 59; + } else {*/ + plugin_state->diceSelect = 232; + //} + } else if(plugin_state->diceSelect == 232) { + plugin_state->diceSelect = 59; + } else if(plugin_state->diceSelect == 59) { + plugin_state->diceSelect = 69; + } else { + plugin_state->diceSelect = 2; + } + break; + case InputKeyLeft: + if(plugin_state->diceQty <= 5) { + plugin_state->diceQty = plugin_state->diceQty + 1; + } else { + plugin_state->diceQty = 1; + } + break; + case InputKeyOk: + plugin_state->letsRoll = true; + break; + case InputKeyBack: + processing = false; + break; + default: + break; + } + } + } else if(event.type == EventTypeTick) { + // furi_hal_rtc_get_datetime(&plugin_state->datetime); + } + view_port_update(view_port); + furi_mutex_release(plugin_state->mutex); + } else { + // FURI_LOG_D(TAG, "osMessageQueue: event timeout"); + } + } + // Cleanup + furi_timer_free(timer); + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + furi_record_close(RECORD_GUI); + view_port_free(view_port); + furi_message_queue_free(plugin_state->event_queue); + furi_mutex_free(plugin_state->mutex); + //free(plugin_state->desktop_settings); + free(plugin_state); + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/rmdice/dice.png b/Applications/Official/DEV_FW/source/xMasterX/rmdice/dice.png new file mode 100644 index 0000000000000000000000000000000000000000..64928b1de6ba75241f6ef15d5a1638b83167981c GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2VGmzZ%#=aj&F%}28J29*~C-V}>VM%xNb!1@J z*w6hZkrl|72=EDU{r~?zkoouT-$#!g{r>&?)2C10zkdgcBxP$>0V$4>AirRs8W3Q( z*St3pD8^af5n0T@z;_sg8IR|$NC67!c)B=-NQ5Ulu=NBmBssaxaPU!J_c`Etai)V% oFr$cpfr0Uc4MqkV3=Ir`rY19(zQ5-u0o2Ff>FVdQ&MBb@0KxY|@&Et; literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/LICENSE new file mode 100644 index 000000000..4a6de25cb --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 RaZe + +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/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/README.md b/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/README.md new file mode 100644 index 000000000..feddf06d6 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/README.md @@ -0,0 +1,13 @@ +# Rubik's Cube Scrambler FAP + +## Where to start? +Install the .fap file and put it in your apps folder + +## What does what? +The On/Off button toggles the vibration notification on and off. The "New" button generates a new scramble. The scramble letters correspond with the following moves: R = Right, L = Left, U = Up, D = Down, F = Front, B = Back. The number after the letter indicates how many times to turn that face. For example, R2 means to turn the right face twice. The ' symbol indicates a counter-clockwise turn. For example, R' means to turn the right face counter-clockwise once. + + + +# A special thanks to Tanish for their c scrambler example 🙠+https://github.com/TanishBhongade/RubiksCubeScrambler-C/ + diff --git a/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/application.fam b/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/application.fam new file mode 100644 index 000000000..56da69378 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/application.fam @@ -0,0 +1,20 @@ +# COMPILE ISTRUCTIONS: + +# Clean the code and remove old binaries/compilation artefact +# ./fbt -c fap_rubiks_cube_scrambler + +# Compile FAP +# ./fbt fap_rubiks_cube_scrambler + +# Run application directly inside the Flip.x0 +# ./fbt launch_app APPSRC=rubiks_cube_scrambler + +App( + appid="rubiks_cube_scrambler", + name="Rubik's Cube Scrambler", + apptype=FlipperAppType.EXTERNAL, + entry_point="rubiks_cube_scrambler_main", + stack_size=1 * 1024, + fap_category="Misc_Extra", + fap_icon="cube.png", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/cube.png b/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/cube.png new file mode 100644 index 0000000000000000000000000000000000000000..3178a29d6f2fa7762c7478f243b42b12b3d71ea5 GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4se8IOhDd}brz9l&;6K8`sO+IA t&>(7LWYlC4adU~LN{0T4ZGxGm4Eb^njH~-D1pu`$c)I$ztaD0e0szja7u)~< literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/rubiks_cube_scrambler.c b/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/rubiks_cube_scrambler.c new file mode 100644 index 000000000..8857c6b80 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/rubiks_cube_scrambler.c @@ -0,0 +1,129 @@ +#include +#include +#include +#include +#include +#include + +#include "scrambler.h" +#include "furi_hal_random.h" + +int scrambleStarted = 0; +char scramble_str[100] = {0}; +char scramble_start[100] = {0}; +char scramble_end[100] = {0}; +int notifications_enabled = 0; + +static void success_vibration() +{ + furi_hal_vibro_on(false); + furi_hal_vibro_on(true); + furi_delay_ms(50); + furi_hal_vibro_on(false); + return; +} +void split_array(char original[], int size, char first[], char second[]) { + int mid = size / 2; + if (size % 2 != 0) { + mid++; + } + int first_index = 0, second_index = 0; + for (int i = 0; i < size; i++) { + if (i < mid) { + first[first_index++] = original[i]; + } else { + if (i == mid && (original[i] == '2' || original[i] == '\'')) { + continue; + } + second[second_index++] = original[i]; + } + } + first[first_index] = '\0'; + second[second_index] = '\0'; +} + + +static void draw_callback(Canvas *canvas, void *ctx) +{ + UNUSED(ctx); + canvas_clear(canvas); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 4, 13, "Rubik's Cube Scrambler"); + + if (scrambleStarted) + { + genScramble(); + scrambleReplace(); + strcpy(scramble_str, printData()); + if (notifications_enabled) + { + success_vibration(); + } + split_array(scramble_str, strlen(scramble_str), scramble_start, scramble_end); + scrambleStarted = 0; + } + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned(canvas, 64, 28, AlignCenter, AlignCenter, scramble_start); + canvas_draw_str_aligned(canvas, 64, 38, AlignCenter, AlignCenter, scramble_end); + elements_button_center(canvas, "New"); + + elements_button_left(canvas, notifications_enabled ? "On" : "Off"); +}; + +static void input_callback(InputEvent *input_event, void *ctx) +{ + furi_assert(ctx); + FuriMessageQueue *event_queue = ctx; + furi_message_queue_put(event_queue, input_event, FuriWaitForever); +} + +int32_t rubiks_cube_scrambler_main(void *p) +{ + UNUSED(p); + InputEvent event; + + FuriMessageQueue *event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + ViewPort *view_port = view_port_alloc(); + + view_port_draw_callback_set(view_port, draw_callback, NULL); + + view_port_input_callback_set(view_port, input_callback, event_queue); + + Gui *gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + while (true) + { + furi_check(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk); + + if (event.key == InputKeyOk && event.type == InputTypeShort) + { + scrambleStarted = 1; + } + if (event.key == InputKeyLeft && event.type == InputTypeShort) + { + if (notifications_enabled) + { + notifications_enabled = 0; + } + else + { + notifications_enabled = 1; + success_vibration(); + } + } + if (event.key == InputKeyBack) + { + break; + } + } + + furi_message_queue_free(event_queue); + + gui_remove_view_port(gui, view_port); + + view_port_free(view_port); + furi_record_close(RECORD_GUI); + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/scrambler.c b/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/scrambler.c new file mode 100644 index 000000000..98ebaed40 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/scrambler.c @@ -0,0 +1,118 @@ +/* +Authors: Tanish Bhongade and RaZe +*/ + +#include +#include +#include +#include "furi_hal_random.h" +#include +#include +#include "scrambler.h" + +// 6 moves along with direction +char moves[6] = {'R', 'U', 'F', 'B', 'L', 'D'}; +char dir[4] = {' ', '\'', '2'}; +const int SLEN = 20; +#define RESULT_SIZE 100 +// Structure which holds main scramble +struct GetScramble +{ + char mainScramble[25][3]; +}; +struct GetScramble a; // Its object + +// Function prototypes to avoid bugs +void scrambleReplace(); +void genScramble(); +void valid(); +int getRand(int upr, int lwr); +char *printData(); +void writeToFile(); + +// Main function +/* int main(){ + genScramble ();//Calling genScramble + scrambleReplace();//Calling scrambleReplace + valid();//Calling valid to validate the scramble + printData ();//Printing the final scramble + //writeToFile();//If you want to write to a file, please uncomment this + + return 0; +} */ + +void genScramble() +{ + // Stage 1 + for (int i = 0; i < SLEN; i++) + { + strcpy(a.mainScramble[i], "00"); + } + // This makes array like this 00 00 00....... +} + +void scrambleReplace() +{ + // Stage 2 + // Actual process begins here + + // Initialize the mainScramble array with all the possible moves + for (int i = 0; i < SLEN; i++) + { + a.mainScramble[i][0] = moves[furi_hal_random_get() % 6]; + a.mainScramble[i][1] = dir[furi_hal_random_get() % 3]; + } + + // Perform the Fisher-Yates shuffle + for (int i = 6 - 1; i > 0; i--) + { + int j = rand() % (i + 1); + char temp[3]; + strcpy(temp, a.mainScramble[i]); + strcpy(a.mainScramble[i], a.mainScramble[j]); + strcpy(a.mainScramble[j], temp); + } + + // Select the first 10 elements as the scramble, using only the first three elements of the dir array + for (int i = 0; i < SLEN; i++) + { + a.mainScramble[i][1] = dir[furi_hal_random_get() % 3]; + } + for (int i = 1; i < SLEN; i++) { + while ( a.mainScramble[i][0] == a.mainScramble[i - 2][0] || a.mainScramble[i][0] == a.mainScramble[i - 1][0]) { + a.mainScramble[i][0] = moves[furi_hal_random_get()%5]; + } + } +} + + + + + + + +// Let this function be here for now till I find out what is causing the extra space bug in the scrambles +void remove_double_spaces(char *str) { + int i, j; + int len = strlen(str); + for (i = 0, j = 0; i < len; i++, j++) { + if (str[i] == ' ' && str[i + 1] == ' ') { + i++; + } + str[j] = str[i]; + } + str[j] = '\0'; +} +char *printData() +{ + static char result[RESULT_SIZE]; + int offset = 0; + for (int loop = 0; loop < SLEN; loop++) + { + offset += snprintf(result + offset, RESULT_SIZE - offset, "%s ", a.mainScramble[loop]); + } + remove_double_spaces(result); + return result; +} + + diff --git a/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/scrambler.h b/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/scrambler.h new file mode 100644 index 000000000..66f6b221d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/rubiks_cube_scrambler/scrambler.h @@ -0,0 +1,3 @@ +void scrambleReplace (); +void genScramble (); +char *printData (); diff --git a/Applications/Official/DEV_FW/source/xMasterX/sam/application.fam b/Applications/Official/DEV_FW/source/xMasterX/sam/application.fam new file mode 100644 index 000000000..c9fc7943d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/sam/application.fam @@ -0,0 +1,45 @@ +App( + appid="SAM", + name="SAM WTF", + apptype=FlipperAppType.PLUGIN, + entry_point="sam_app", + requires=[ + "gui", + "dialogs", + ], + stack_size=4 * 1024, + order=20, + fap_icon="icons/music_10px.png", + fap_category="Music_Extra", + fap_icon_assets="icons", +) +App( + appid="SAM_YES", + name="SAM YES", + apptype=FlipperAppType.PLUGIN, + entry_point="sam_app_yes", + requires=[ + "gui", + "dialogs", + ], + stack_size=4 * 1024, + order=20, + fap_icon="music_10px.png", + fap_category="Music_Extra", + fap_icon_assets="icons", +) +App( + appid="SAM_NO", + name="SAM NO", + apptype=FlipperAppType.PLUGIN, + entry_point="sam_app_no", + requires=[ + "gui", + "dialogs", + ], + stack_size=4 * 1024, + order=20, + fap_icon="music_10px.png", + fap_category="Music_Extra", + fap_icon_assets="icons", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/sam/icons/music_10px.png b/Applications/Official/DEV_FW/source/xMasterX/sam/icons/music_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..d41eb0db8c822c60be6c097393b3682680b81a6c GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xGmzZ=C-xtZVhivIasA%~WHIdey2}7aaTa() z7Bet#3xhBt!>l_x9Asc&(0a_=e)W&n8K5!-Pgg&ebxsLQ0Ao%f>i_@% literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/sam/music_10px.png b/Applications/Official/DEV_FW/source/xMasterX/sam/music_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..d41eb0db8c822c60be6c097393b3682680b81a6c GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xGmzZ=C-xtZVhivIasA%~WHIdey2}7aaTa() z7Bet#3xhBt!>l_x9Asc&(0a_=e)W&n8K5!-Pgg&ebxsLQ0Ao%f>i_@% literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/sam/sam_app.cpp b/Applications/Official/DEV_FW/source/xMasterX/sam/sam_app.cpp new file mode 100644 index 000000000..d9b319475 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/sam/sam_app.cpp @@ -0,0 +1,36 @@ +#include +#include +#include "stm32_sam.h" +// WOULD BE COOL IF SOMEONE MADE A TEXT ENTRY SCREEN TO HAVE IT READ WHAT IS ENTERED TO TEXT +STM32SAM voice; + +extern "C" int32_t sam_app(void* p) { + UNUSED(p); + if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { + voice.begin(); + voice.say( + "All your base are belong to us. You have no chance to survive make your time. ha. ha. ha. GOOD BYE. "); + furi_hal_speaker_release(); + } + return 0; +} + +extern "C" int32_t sam_app_yes(void* p) { + UNUSED(p); + if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { + voice.begin(); + voice.say("Yes"); + furi_hal_speaker_release(); + } + return 0; +} + +extern "C" int32_t sam_app_no(void* p) { + UNUSED(p); + if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { + voice.begin(); + voice.say("No"); + furi_hal_speaker_release(); + } + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/sam/stm32_sam.cpp b/Applications/Official/DEV_FW/source/xMasterX/sam/stm32_sam.cpp new file mode 100644 index 000000000..16f6fcaab --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/sam/stm32_sam.cpp @@ -0,0 +1,5704 @@ + +#include "stm32_sam.h" +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// All +// +//////////////////////////////////////////////////////////////////////////////////////////// + +char input[256 + 1] = {0}; //tab39445 +//standard sam sound + +unsigned char wait1 = 7; +unsigned char wait2 = 6; + +unsigned char A, X, Y; +unsigned char mem44; +unsigned char mem47; +unsigned char mem49; +unsigned char mem39; +unsigned char mem50; +unsigned char mem51; +unsigned char mem53; +unsigned char mem56; +unsigned char mem59 = 0; + +unsigned char phonemeIndexOutput[60]; //tab47296 +unsigned char stressOutput[60]; //tab47365 +unsigned char phonemeLengthOutput[60]; //tab47416 + +// contains the soundbuffer position +int bufferpos; + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// Sam Tabs +// +//////////////////////////////////////////////////////////////////////////////////////////// + +//tab40672 +const unsigned char stressInputTable[] = {'*', '1', '2', '3', '4', '5', '6', '7', '8'}; + +//tab40682 +const unsigned char signInputTable1[] = { + ' ', '.', '?', ',', '-', 'I', 'I', 'E', 'A', 'A', 'A', 'A', 'U', 'A', 'I', 'E', 'U', + 'O', 'R', 'L', 'W', 'Y', 'W', 'R', 'L', 'W', 'Y', 'M', 'N', 'N', 'D', 'Q', 'S', 'S', + 'F', 'T', '/', '/', 'Z', 'Z', 'V', 'D', 'C', '*', 'J', '*', '*', '*', 'E', 'A', 'O', + 'A', 'O', 'U', 'B', '*', '*', 'D', '*', '*', 'G', '*', '*', 'G', '*', '*', 'P', '*', + '*', 'T', '*', '*', 'K', '*', '*', 'K', '*', '*', 'U', 'U', 'U'}; + +//tab40763 +const unsigned char signInputTable2[] = { + '*', '*', '*', '*', '*', 'Y', 'H', 'H', 'E', 'A', 'H', 'O', 'H', 'X', 'X', 'R', 'X', + 'H', 'X', 'X', 'X', 'X', 'H', '*', '*', '*', '*', '*', '*', 'X', 'X', '*', '*', 'H', + '*', 'H', 'H', 'X', '*', 'H', '*', 'H', 'H', '*', '*', '*', '*', '*', 'Y', 'Y', 'Y', + 'W', 'W', 'W', '*', '*', '*', '*', '*', '*', '*', '*', '*', 'X', '*', '*', '*', '*', + '*', '*', '*', '*', '*', '*', '*', 'X', '*', '*', 'L', 'M', 'N'}; + +//loc_9F8C +const unsigned char flags[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0x84, 0x84, 0xA4, + 0xA4, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x44, 0x44, 0x44, 0x44, 0x44, 0x4C, + 0x4C, 0x4C, 0x48, 0x4C, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x44, 0x44, 0x44, 0x44, + 0x48, 0x40, 0x4C, 0x44, 0x00, 0x00, 0xB4, 0xB4, 0xB4, 0x94, 0x94, 0x94, 0x4E, 0x4E, + 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4B, 0x4B, 0x4B, 0x4B, + 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x80, 0xC1, 0xC1 + +}; + +//??? flags overlap flags2 +//loc_9FDA +const unsigned char flags2[] = { + 0x80, 0xC1, 0xC1, 0xC1, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0C, 0x08, 0x04, 0x40, + 0x24, 0x20, 0x20, 0x24, 0x00, 0x00, 0x24, 0x20, 0x20, 0x24, 0x20, 0x20, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +//tab45616??? +const unsigned char phonemeStressedLengthTable[] = { + 0x00, 0x12, 0x12, 0x12, 8, 0xB, 9, 0xB, 0xE, 0xF, 0xB, 0x10, 0xC, 6, 6, 0xE, + 0xC, 0xE, 0xC, 0xB, 8, 8, 0xB, 0xA, 9, 8, 8, 8, 8, 8, 3, 5, + 2, 2, 2, 2, 2, 2, 6, 6, 8, 6, 6, 2, 9, 4, 2, 1, + 0xE, 0xF, 0xF, 0xF, 0xE, 0xE, 8, 2, 2, 7, 2, 1, 7, 2, 2, 7, + 2, 2, 8, 2, 2, 6, 2, 2, 7, 2, 4, 7, 1, 4, 5, 5}; + +//tab45536??? +const unsigned char phonemeLengthTable[] = { + 0, 0x12, 0x12, 0x12, 8, 8, 8, 8, 8, 0xB, 6, 0xC, 0xA, 5, 5, 0xB, 0xA, 0xA, 0xA, 9, + 8, 7, 9, 7, 6, 8, 6, 7, 7, 7, 2, 5, 2, 2, 2, 2, 2, 2, 6, 6, + 7, 6, 6, 2, 8, 3, 1, 0x1E, 0xD, 0xC, 0xC, 0xC, 0xE, 9, 6, 1, 2, 5, 1, 1, + 6, 1, 2, 6, 1, 2, 8, 2, 2, 4, 2, 2, 6, 1, 4, 6, 1, 4, 0xC7, 0xFF}; + +/* + + Ind | phoneme | flags | + -----|---------|----------| + 0 | * | 00000000 | + 1 | .* | 00000000 | + 2 | ?* | 00000000 | + 3 | ,* | 00000000 | + 4 | -* | 00000000 | + + VOWELS + 5 | IY | 10100100 | + 6 | IH | 10100100 | + 7 | EH | 10100100 | + 8 | AE | 10100100 | + 9 | AA | 10100100 | + 10 | AH | 10100100 | + 11 | AO | 10000100 | + 17 | OH | 10000100 | + 12 | UH | 10000100 | + 16 | UX | 10000100 | + 15 | ER | 10000100 | + 13 | AX | 10100100 | + 14 | IX | 10100100 | + + DIPHTONGS + 48 | EY | 10110100 | + 49 | AY | 10110100 | + 50 | OY | 10110100 | + 51 | AW | 10010100 | + 52 | OW | 10010100 | + 53 | UW | 10010100 | + + + 21 | YX | 10000100 | + 20 | WX | 10000100 | + 18 | RX | 10000100 | + 19 | LX | 10000100 | + 37 | /X | 01000000 | + 30 | DX | 01001000 | + + + 22 | WH | 01000100 | + + + VOICED CONSONANTS + 23 | R* | 01000100 | + 24 | L* | 01000100 | + 25 | W* | 01000100 | + 26 | Y* | 01000100 | + 27 | M* | 01001100 | + 28 | N* | 01001100 | + 29 | NX | 01001100 | + 54 | B* | 01001110 | + 57 | D* | 01001110 | + 60 | G* | 01001110 | + 44 | J* | 01001100 | + 38 | Z* | 01000100 | + 39 | ZH | 01000100 | + 40 | V* | 01000100 | + 41 | DH | 01000100 | + + unvoiced CONSONANTS + 32 | S* | 01000000 | + 33 | SH | 01000000 | + 34 | F* | 01000000 | + 35 | TH | 01000000 | + 66 | P* | 01001011 | + 69 | T* | 01001011 | + 72 | K* | 01001011 | + 42 | CH | 01001000 | + 36 | /H | 01000000 | + + 43 | ** | 01000000 | + 45 | ** | 01000100 | + 46 | ** | 00000000 | + 47 | ** | 00000000 | + + + 55 | ** | 01001110 | + 56 | ** | 01001110 | + 58 | ** | 01001110 | + 59 | ** | 01001110 | + 61 | ** | 01001110 | + 62 | ** | 01001110 | + 63 | GX | 01001110 | + 64 | ** | 01001110 | + 65 | ** | 01001110 | + 67 | ** | 01001011 | + 68 | ** | 01001011 | + 70 | ** | 01001011 | + 71 | ** | 01001011 | + 73 | ** | 01001011 | + 74 | ** | 01001011 | + 75 | KX | 01001011 | + 76 | ** | 01001011 | + 77 | ** | 01001011 | + + + SPECIAL + 78 | UL | 10000000 | + 79 | UM | 11000001 | + 80 | UN | 11000001 | + 31 | Q* | 01001100 | + +*/ + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// RenderTabs +// +//////////////////////////////////////////////////////////////////////////////////////////// + +const unsigned char tab48426[5] = {0x18, 0x1A, 0x17, 0x17, 0x17}; + +const unsigned char tab47492[] = {0, 0, 0xE0, 0xE6, 0xEC, 0xF3, 0xF9, 0, 6, 0xC, 6}; + +const unsigned char amplitudeRescale[] = { + 0, + 1, + 2, + 2, + 2, + 3, + 3, + 4, + 4, + 5, + 6, + 8, + 9, + 0xB, + 0xD, + 0xF, + 0 //17 elements? +}; + +// Used to decide which phoneme's blend lengths. The candidate with the lower score is selected. +// tab45856 +const unsigned char blendRank[] = {0, 0x1F, 0x1F, 0x1F, 0x1F, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 5, 5, 2, 0xA, 2, 8, + 5, 5, 0xB, 0xA, 9, 8, 8, 0xA0, 8, 8, + 0x17, 0x1F, 0x12, 0x12, 0x12, 0x12, 0x1E, 0x1E, 0x14, 0x14, + 0x14, 0x14, 0x17, 0x17, 0x1A, 0x1A, 0x1D, 0x1D, 2, 2, + 2, 2, 2, 2, 0x1A, 0x1D, 0x1B, 0x1A, 0x1D, 0x1B, + 0x1A, 0x1D, 0x1B, 0x1A, 0x1D, 0x1B, 0x17, 0x1D, 0x17, 0x17, + 0x1D, 0x17, 0x17, 0x1D, 0x17, 0x17, 0x1D, 0x17, 0x17, 0x17}; + +// Number of frames at the end of a phoneme devoted to interpolating to next phoneme's final value +//tab45696 +const unsigned char outBlendLength[] = {0, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 3, 2, 4, 4, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 0, 1, 0, 1, 0, 5, + 5, 5, 5, 5, 4, 4, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, + 0, 1, 2, 0, 2, 2, 0, 1, 3, 0, 2, 3, 0, 2, 0xA0, 0xA0}; + +// Number of frames at beginning of a phoneme devoted to interpolating to phoneme's final value +// tab45776 +const unsigned char inBlendLength[] = {0, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 3, 3, 4, 4, 3, 3, 3, 3, 3, 1, 2, 3, 2, 1, + 3, 3, 3, 3, 1, 1, 3, 3, 3, 2, 2, 3, 2, 3, 0, 0, + 5, 5, 5, 5, 4, 4, 2, 0, 2, 2, 0, 3, 2, 0, 4, 2, + 0, 3, 2, 0, 2, 2, 0, 2, 3, 0, 3, 3, 0, 3, 0xB0, 0xA0}; + +// Looks like it's used as bit flags +// High bits masked by 248 (11111000) +// +// 32: S* 241 11110001 +// 33: SH 226 11100010 +// 34: F* 211 11010011 +// 35: TH 187 10111011 +// 36: /H 124 01111100 +// 37: /X 149 10010101 +// 38: Z* 1 00000001 +// 39: ZH 2 00000010 +// 40: V* 3 00000011 +// 41: DH 3 00000011 +// 43: ** 114 01110010 +// 45: ** 2 00000010 +// 67: ** 27 00011011 +// 70: ** 25 00011001 +// tab45936 +const unsigned char sampledConsonantFlags[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xF1, 0xE2, 0xD3, 0xBB, 0x7C, 0x95, 1, 2, + 3, 3, 0, 0x72, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x1B, 0, 0, 0x19, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +//tab45056 +unsigned char freq1data[] = { + 0x00, 0x13, 0x13, 0x13, 0x13, 0xA, 0xE, 0x12, 0x18, 0x1A, 0x16, 0x14, 0x10, 0x14, 0xE, 0x12, + 0xE, 0x12, 0x12, 0x10, 0xC, 0xE, 0xA, 0x12, 0xE, 0xA, 8, 6, 6, 6, 6, 0x11, + 6, 6, 6, 6, 0xE, 0x10, 9, 0xA, 8, 0xA, 6, 6, 6, 5, 6, 0, + 0x12, 0x1A, 0x14, 0x1A, 0x12, 0xC, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 0xA, 0xA, 6, 6, 6, 0x2C, 0x13}; + +//tab451356 +unsigned char freq2data[] = {0x00, 0x43, 0x43, 0x43, 0x43, 0x54, 0x48, 0x42, 0x3E, 0x28, + 0x2C, 0x1E, 0x24, 0x2C, 0x48, 0x30, 0x24, 0x1E, 0x32, 0x24, + 0x1C, 0x44, 0x18, 0x32, 0x1E, 0x18, 0x52, 0x2E, 0x36, 0x56, + 0x36, 0x43, 0x49, 0x4F, 0x1A, 0x42, 0x49, 0x25, 0x33, 0x42, + 0x28, 0x2F, 0x4F, 0x4F, 0x42, 0x4F, 0x6E, 0x00, 0x48, 0x26, + 0x1E, 0x2A, 0x1E, 0x22, 0x1A, 0x1A, 0x1A, 0x42, 0x42, 0x42, + 0x6E, 0x6E, 0x6E, 0x54, 0x54, 0x54, 0x1A, 0x1A, 0x1A, 0x42, + 0x42, 0x42, 0x6D, 0x56, 0x6D, 0x54, 0x54, 0x54, 0x7F, 0x7F}; +//tab45216 +unsigned char freq3data[] = {0x00, 0x5B, 0x5B, 0x5B, 0x5B, 0x6E, 0x5D, 0x5B, 0x58, 0x59, + 0x57, 0x58, 0x52, 0x59, 0x5D, 0x3E, 0x52, 0x58, 0x3E, 0x6E, + 0x50, 0x5D, 0x5A, 0x3C, 0x6E, 0x5A, 0x6E, 0x51, 0x79, 0x65, + 0x79, 0x5B, 0x63, 0x6A, 0x51, 0x79, 0x5D, 0x52, 0x5D, 0x67, + 0x4C, 0x5D, 0x65, 0x65, 0x79, 0x65, 0x79, 0x00, 0x5A, 0x58, + 0x58, 0x58, 0x58, 0x52, 0x51, 0x51, 0x51, 0x79, 0x79, 0x79, + 0x70, 0x6E, 0x6E, 0x5E, 0x5E, 0x5E, 0x51, 0x51, 0x51, 0x79, + 0x79, 0x79, 0x65, 0x65, 0x70, 0x5E, 0x5E, 0x5E, 0x08, 0x01}; + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// Reciter +// +//////////////////////////////////////////////////////////////////////////////////////////// + +unsigned char inputtemp[256]; // secure copy of input tab36096 + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// Render +// +//////////////////////////////////////////////////////////////////////////////////////////// + +//timetable for more accurate c64 simulation +int timetable[5][5] = { + {162, 167, 167, 127, 128}, + {226, 60, 60, 0, 0}, + {225, 60, 59, 0, 0}, + {200, 0, 0, 54, 55}, + {199, 0, 0, 54, 54}}; + +unsigned oldtimetableindex; + +const unsigned char ampl1data[] = {0, 0, 0, 0, 0, 0xD, 0xD, 0xE, 0xF, 0xF, 0xF, 0xF, + 0xF, 0xC, 0xD, 0xC, 0xF, 0xF, 0xD, 0xD, 0xD, 0xE, 0xD, 0xC, + 0xD, 0xD, 0xD, 0xC, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0xB, 0xB, 0xB, 0xB, 0, 0, 1, 0xB, 0, 2, + 0xE, 0xF, 0xF, 0xF, 0xF, 0xD, 2, 4, 0, 2, 4, 0, + 1, 4, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0xC, 0, 0, 0, 0, 0xF, 0xF}; + +const unsigned char ampl2data[] = { + 0, 0, 0, 0, 0, 0xA, 0xB, 0xD, 0xE, 0xD, 0xC, 0xC, 0xB, 9, 0xB, 0xB, 0xC, 0xC, 0xC, 8, + 8, 0xC, 8, 0xA, 8, 8, 0xA, 3, 9, 6, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, + 3, 4, 0, 0, 0, 5, 0xA, 2, 0xE, 0xD, 0xC, 0xD, 0xC, 8, 0, 1, 0, 0, 1, 0, + 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0xA, 0, 0, 0xA, 0, 0, 0}; + +const unsigned char ampl3data[] = {0, 0, 0, 0, 0, 8, 7, 8, 8, 1, 1, 0, 1, 0, 7, 5, + 1, 0, 6, 1, 0, 7, 0, 5, 1, 0, 8, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0xE, 1, + 9, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 5, 0, 0x13, 0x10}; + +//tab42240 +const signed char sinus[256] = { + 0, 3, 6, 9, 12, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, + 49, 51, 54, 57, 60, 63, 65, 68, 71, 73, 76, 78, 81, 83, 85, 88, + 90, 92, 94, 96, 98, 100, 102, 104, 106, 107, 109, 111, 112, 113, 115, 116, + 117, 118, 120, 121, 122, 122, 123, 124, 125, 125, 126, 126, 126, 127, 127, 127, + 127, 127, 127, 127, 126, 126, 126, 125, 125, 124, 123, 122, 122, 121, 120, 118, + 117, 116, 115, 113, 112, 111, 109, 107, 106, 104, 102, 100, 98, 96, 94, 92, + 90, 88, 85, 83, 81, 78, 76, 73, 71, 68, 65, 63, 60, 57, 54, 51, + 49, 46, 43, 40, 37, 34, 31, 28, 25, 22, 19, 16, 12, 9, 6, 3, + 0, -3, -6, -9, -12, -16, -19, -22, -25, -28, -31, -34, -37, -40, -43, -46, + -49, -51, -54, -57, -60, -63, -65, -68, -71, -73, -76, -78, -81, -83, -85, -88, + -90, -92, -94, -96, -98, -100, -102, -104, -106, -107, -109, -111, -112, -113, -115, -116, + -117, -118, -120, -121, -122, -122, -123, -124, -125, -125, -126, -126, -126, -127, -127, -127, + -127, -127, -127, -127, -126, -126, -126, -125, -125, -124, -123, -122, -122, -121, -120, -118, + -117, -116, -115, -113, -112, -111, -109, -107, -106, -104, -102, -100, -98, -96, -94, -92, + -90, -88, -85, -83, -81, -78, -76, -73, -71, -68, -65, -63, -60, -57, -54, -51, + -49, -46, -43, -40, -37, -34, -31, -28, -25, -22, -19, -16, -12, -9, -6, -3}; + +//tab42496 +const unsigned char rectangle[] = { + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, + 0x70}; + +//random data ? +const unsigned char sampleTable[0x500] = { + //00 + + 0x38, + 0x84, + 0x6B, + 0x19, + 0xC6, + 0x63, + 0x18, + 0x86, + 0x73, + 0x98, + 0xC6, + 0xB1, + 0x1C, + 0xCA, + 0x31, + 0x8C, + 0xC7, + 0x31, + 0x88, + 0xC2, + 0x30, + 0x98, + 0x46, + 0x31, + 0x18, + 0xC6, + 0x35, + 0xC, + 0xCA, + 0x31, + 0xC, + 0xC6 + //20 + , + 0x21, + 0x10, + 0x24, + 0x69, + 0x12, + 0xC2, + 0x31, + 0x14, + 0xC4, + 0x71, + 8, + 0x4A, + 0x22, + 0x49, + 0xAB, + 0x6A, + 0xA8, + 0xAC, + 0x49, + 0x51, + 0x32, + 0xD5, + 0x52, + 0x88, + 0x93, + 0x6C, + 0x94, + 0x22, + 0x15, + 0x54, + 0xD2, + 0x25 + //40 + , + 0x96, + 0xD4, + 0x50, + 0xA5, + 0x46, + 0x21, + 8, + 0x85, + 0x6B, + 0x18, + 0xC4, + 0x63, + 0x10, + 0xCE, + 0x6B, + 0x18, + 0x8C, + 0x71, + 0x19, + 0x8C, + 0x63, + 0x35, + 0xC, + 0xC6, + 0x33, + 0x99, + 0xCC, + 0x6C, + 0xB5, + 0x4E, + 0xA2, + 0x99 + //60 + , + 0x46, + 0x21, + 0x28, + 0x82, + 0x95, + 0x2E, + 0xE3, + 0x30, + 0x9C, + 0xC5, + 0x30, + 0x9C, + 0xA2, + 0xB1, + 0x9C, + 0x67, + 0x31, + 0x88, + 0x66, + 0x59, + 0x2C, + 0x53, + 0x18, + 0x84, + 0x67, + 0x50, + 0xCA, + 0xE3, + 0xA, + 0xAC, + 0xAB, + 0x30 + //80 + , + 0xAC, + 0x62, + 0x30, + 0x8C, + 0x63, + 0x10, + 0x94, + 0x62, + 0xB1, + 0x8C, + 0x82, + 0x28, + 0x96, + 0x33, + 0x98, + 0xD6, + 0xB5, + 0x4C, + 0x62, + 0x29, + 0xA5, + 0x4A, + 0xB5, + 0x9C, + 0xC6, + 0x31, + 0x14, + 0xD6, + 0x38, + 0x9C, + 0x4B, + 0xB4 + //A0 + , + 0x86, + 0x65, + 0x18, + 0xAE, + 0x67, + 0x1C, + 0xA6, + 0x63, + 0x19, + 0x96, + 0x23, + 0x19, + 0x84, + 0x13, + 8, + 0xA6, + 0x52, + 0xAC, + 0xCA, + 0x22, + 0x89, + 0x6E, + 0xAB, + 0x19, + 0x8C, + 0x62, + 0x34, + 0xC4, + 0x62, + 0x19, + 0x86, + 0x63 + //C0 + , + 0x18, + 0xC4, + 0x23, + 0x58, + 0xD6, + 0xA3, + 0x50, + 0x42, + 0x54, + 0x4A, + 0xAD, + 0x4A, + 0x25, + 0x11, + 0x6B, + 0x64, + 0x89, + 0x4A, + 0x63, + 0x39, + 0x8A, + 0x23, + 0x31, + 0x2A, + 0xEA, + 0xA2, + 0xA9, + 0x44, + 0xC5, + 0x12, + 0xCD, + 0x42 + //E0 + , + 0x34, + 0x8C, + 0x62, + 0x18, + 0x8C, + 0x63, + 0x11, + 0x48, + 0x66, + 0x31, + 0x9D, + 0x44, + 0x33, + 0x1D, + 0x46, + 0x31, + 0x9C, + 0xC6, + 0xB1, + 0xC, + 0xCD, + 0x32, + 0x88, + 0xC4, + 0x73, + 0x18, + 0x86, + 0x73, + 8, + 0xD6, + 0x63, + 0x58 + //100 + , + 7, + 0x81, + 0xE0, + 0xF0, + 0x3C, + 7, + 0x87, + 0x90, + 0x3C, + 0x7C, + 0xF, + 0xC7, + 0xC0, + 0xC0, + 0xF0, + 0x7C, + 0x1E, + 7, + 0x80, + 0x80, + 0, + 0x1C, + 0x78, + 0x70, + 0xF1, + 0xC7, + 0x1F, + 0xC0, + 0xC, + 0xFE, + 0x1C, + 0x1F + //120 + , + 0x1F, + 0xE, + 0xA, + 0x7A, + 0xC0, + 0x71, + 0xF2, + 0x83, + 0x8F, + 3, + 0xF, + 0xF, + 0xC, + 0, + 0x79, + 0xF8, + 0x61, + 0xE0, + 0x43, + 0xF, + 0x83, + 0xE7, + 0x18, + 0xF9, + 0xC1, + 0x13, + 0xDA, + 0xE9, + 0x63, + 0x8F, + 0xF, + 0x83 + //140 + , + 0x83, + 0x87, + 0xC3, + 0x1F, + 0x3C, + 0x70, + 0xF0, + 0xE1, + 0xE1, + 0xE3, + 0x87, + 0xB8, + 0x71, + 0xE, + 0x20, + 0xE3, + 0x8D, + 0x48, + 0x78, + 0x1C, + 0x93, + 0x87, + 0x30, + 0xE1, + 0xC1, + 0xC1, + 0xE4, + 0x78, + 0x21, + 0x83, + 0x83, + 0xC3 + //160 + , + 0x87, + 6, + 0x39, + 0xE5, + 0xC3, + 0x87, + 7, + 0xE, + 0x1C, + 0x1C, + 0x70, + 0xF4, + 0x71, + 0x9C, + 0x60, + 0x36, + 0x32, + 0xC3, + 0x1E, + 0x3C, + 0xF3, + 0x8F, + 0xE, + 0x3C, + 0x70, + 0xE3, + 0xC7, + 0x8F, + 0xF, + 0xF, + 0xE, + 0x3C + //180 + , + 0x78, + 0xF0, + 0xE3, + 0x87, + 6, + 0xF0, + 0xE3, + 7, + 0xC1, + 0x99, + 0x87, + 0xF, + 0x18, + 0x78, + 0x70, + 0x70, + 0xFC, + 0xF3, + 0x10, + 0xB1, + 0x8C, + 0x8C, + 0x31, + 0x7C, + 0x70, + 0xE1, + 0x86, + 0x3C, + 0x64, + 0x6C, + 0xB0, + 0xE1 + //1A0 + , + 0xE3, + 0xF, + 0x23, + 0x8F, + 0xF, + 0x1E, + 0x3E, + 0x38, + 0x3C, + 0x38, + 0x7B, + 0x8F, + 7, + 0xE, + 0x3C, + 0xF4, + 0x17, + 0x1E, + 0x3C, + 0x78, + 0xF2, + 0x9E, + 0x72, + 0x49, + 0xE3, + 0x25, + 0x36, + 0x38, + 0x58, + 0x39, + 0xE2, + 0xDE + //1C0 + , + 0x3C, + 0x78, + 0x78, + 0xE1, + 0xC7, + 0x61, + 0xE1, + 0xE1, + 0xB0, + 0xF0, + 0xF0, + 0xC3, + 0xC7, + 0xE, + 0x38, + 0xC0, + 0xF0, + 0xCE, + 0x73, + 0x73, + 0x18, + 0x34, + 0xB0, + 0xE1, + 0xC7, + 0x8E, + 0x1C, + 0x3C, + 0xF8, + 0x38, + 0xF0, + 0xE1 + //1E0 + , + 0xC1, + 0x8B, + 0x86, + 0x8F, + 0x1C, + 0x78, + 0x70, + 0xF0, + 0x78, + 0xAC, + 0xB1, + 0x8F, + 0x39, + 0x31, + 0xDB, + 0x38, + 0x61, + 0xC3, + 0xE, + 0xE, + 0x38, + 0x78, + 0x73, + 0x17, + 0x1E, + 0x39, + 0x1E, + 0x38, + 0x64, + 0xE1, + 0xF1, + 0xC1 + //200 + , + 0x4E, + 0xF, + 0x40, + 0xA2, + 2, + 0xC5, + 0x8F, + 0x81, + 0xA1, + 0xFC, + 0x12, + 8, + 0x64, + 0xE0, + 0x3C, + 0x22, + 0xE0, + 0x45, + 7, + 0x8E, + 0xC, + 0x32, + 0x90, + 0xF0, + 0x1F, + 0x20, + 0x49, + 0xE0, + 0xF8, + 0xC, + 0x60, + 0xF0 + //220 + , + 0x17, + 0x1A, + 0x41, + 0xAA, + 0xA4, + 0xD0, + 0x8D, + 0x12, + 0x82, + 0x1E, + 0x1E, + 3, + 0xF8, + 0x3E, + 3, + 0xC, + 0x73, + 0x80, + 0x70, + 0x44, + 0x26, + 3, + 0x24, + 0xE1, + 0x3E, + 4, + 0x4E, + 4, + 0x1C, + 0xC1, + 9, + 0xCC + //240 + , + 0x9E, + 0x90, + 0x21, + 7, + 0x90, + 0x43, + 0x64, + 0xC0, + 0xF, + 0xC6, + 0x90, + 0x9C, + 0xC1, + 0x5B, + 3, + 0xE2, + 0x1D, + 0x81, + 0xE0, + 0x5E, + 0x1D, + 3, + 0x84, + 0xB8, + 0x2C, + 0xF, + 0x80, + 0xB1, + 0x83, + 0xE0, + 0x30, + 0x41 + //260 + , + 0x1E, + 0x43, + 0x89, + 0x83, + 0x50, + 0xFC, + 0x24, + 0x2E, + 0x13, + 0x83, + 0xF1, + 0x7C, + 0x4C, + 0x2C, + 0xC9, + 0xD, + 0x83, + 0xB0, + 0xB5, + 0x82, + 0xE4, + 0xE8, + 6, + 0x9C, + 7, + 0xA0, + 0x99, + 0x1D, + 7, + 0x3E, + 0x82, + 0x8F + //280 + , + 0x70, + 0x30, + 0x74, + 0x40, + 0xCA, + 0x10, + 0xE4, + 0xE8, + 0xF, + 0x92, + 0x14, + 0x3F, + 6, + 0xF8, + 0x84, + 0x88, + 0x43, + 0x81, + 0xA, + 0x34, + 0x39, + 0x41, + 0xC6, + 0xE3, + 0x1C, + 0x47, + 3, + 0xB0, + 0xB8, + 0x13, + 0xA, + 0xC2 + //2A0 + , + 0x64, + 0xF8, + 0x18, + 0xF9, + 0x60, + 0xB3, + 0xC0, + 0x65, + 0x20, + 0x60, + 0xA6, + 0x8C, + 0xC3, + 0x81, + 0x20, + 0x30, + 0x26, + 0x1E, + 0x1C, + 0x38, + 0xD3, + 1, + 0xB0, + 0x26, + 0x40, + 0xF4, + 0xB, + 0xC3, + 0x42, + 0x1F, + 0x85, + 0x32 + //2C0 + , + 0x26, + 0x60, + 0x40, + 0xC9, + 0xCB, + 1, + 0xEC, + 0x11, + 0x28, + 0x40, + 0xFA, + 4, + 0x34, + 0xE0, + 0x70, + 0x4C, + 0x8C, + 0x1D, + 7, + 0x69, + 3, + 0x16, + 0xC8, + 4, + 0x23, + 0xE8, + 0xC6, + 0x9A, + 0xB, + 0x1A, + 3, + 0xE0 + //2E0 + , + 0x76, + 6, + 5, + 0xCF, + 0x1E, + 0xBC, + 0x58, + 0x31, + 0x71, + 0x66, + 0, + 0xF8, + 0x3F, + 4, + 0xFC, + 0xC, + 0x74, + 0x27, + 0x8A, + 0x80, + 0x71, + 0xC2, + 0x3A, + 0x26, + 6, + 0xC0, + 0x1F, + 5, + 0xF, + 0x98, + 0x40, + 0xAE + //300 + , + 1, + 0x7F, + 0xC0, + 7, + 0xFF, + 0, + 0xE, + 0xFE, + 0, + 3, + 0xDF, + 0x80, + 3, + 0xEF, + 0x80, + 0x1B, + 0xF1, + 0xC2, + 0, + 0xE7, + 0xE0, + 0x18, + 0xFC, + 0xE0, + 0x21, + 0xFC, + 0x80, + 0x3C, + 0xFC, + 0x40, + 0xE, + 0x7E + //320 + , + 0, + 0x3F, + 0x3E, + 0, + 0xF, + 0xFE, + 0, + 0x1F, + 0xFF, + 0, + 0x3E, + 0xF0, + 7, + 0xFC, + 0, + 0x7E, + 0x10, + 0x3F, + 0xFF, + 0, + 0x3F, + 0x38, + 0xE, + 0x7C, + 1, + 0x87, + 0xC, + 0xFC, + 0xC7, + 0, + 0x3E, + 4 + //340 + , + 0xF, + 0x3E, + 0x1F, + 0xF, + 0xF, + 0x1F, + 0xF, + 2, + 0x83, + 0x87, + 0xCF, + 3, + 0x87, + 0xF, + 0x3F, + 0xC0, + 7, + 0x9E, + 0x60, + 0x3F, + 0xC0, + 3, + 0xFE, + 0, + 0x3F, + 0xE0, + 0x77, + 0xE1, + 0xC0, + 0xFE, + 0xE0, + 0xC3 + //360 + , + 0xE0, + 1, + 0xDF, + 0xF8, + 3, + 7, + 0, + 0x7E, + 0x70, + 0, + 0x7C, + 0x38, + 0x18, + 0xFE, + 0xC, + 0x1E, + 0x78, + 0x1C, + 0x7C, + 0x3E, + 0xE, + 0x1F, + 0x1E, + 0x1E, + 0x3E, + 0, + 0x7F, + 0x83, + 7, + 0xDB, + 0x87, + 0x83 + //380 + , + 7, + 0xC7, + 7, + 0x10, + 0x71, + 0xFF, + 0, + 0x3F, + 0xE2, + 1, + 0xE0, + 0xC1, + 0xC3, + 0xE1, + 0, + 0x7F, + 0xC0, + 5, + 0xF0, + 0x20, + 0xF8, + 0xF0, + 0x70, + 0xFE, + 0x78, + 0x79, + 0xF8, + 2, + 0x3F, + 0xC, + 0x8F, + 3 + //3a0 + , + 0xF, + 0x9F, + 0xE0, + 0xC1, + 0xC7, + 0x87, + 3, + 0xC3, + 0xC3, + 0xB0, + 0xE1, + 0xE1, + 0xC1, + 0xE3, + 0xE0, + 0x71, + 0xF0, + 0, + 0xFC, + 0x70, + 0x7C, + 0xC, + 0x3E, + 0x38, + 0xE, + 0x1C, + 0x70, + 0xC3, + 0xC7, + 3, + 0x81, + 0xC1 + //3c0 + , + 0xC7, + 0xE7, + 0, + 0xF, + 0xC7, + 0x87, + 0x19, + 9, + 0xEF, + 0xC4, + 0x33, + 0xE0, + 0xC1, + 0xFC, + 0xF8, + 0x70, + 0xF0, + 0x78, + 0xF8, + 0xF0, + 0x61, + 0xC7, + 0, + 0x1F, + 0xF8, + 1, + 0x7C, + 0xF8, + 0xF0, + 0x78, + 0x70, + 0x3C + //3e0 + , + 0x7C, + 0xCE, + 0xE, + 0x21, + 0x83, + 0xCF, + 8, + 7, + 0x8F, + 8, + 0xC1, + 0x87, + 0x8F, + 0x80, + 0xC7, + 0xE3, + 0, + 7, + 0xF8, + 0xE0, + 0xEF, + 0, + 0x39, + 0xF7, + 0x80, + 0xE, + 0xF8, + 0xE1, + 0xE3, + 0xF8, + 0x21, + 0x9F + //400 + , + 0xC0, + 0xFF, + 3, + 0xF8, + 7, + 0xC0, + 0x1F, + 0xF8, + 0xC4, + 4, + 0xFC, + 0xC4, + 0xC1, + 0xBC, + 0x87, + 0xF0, + 0xF, + 0xC0, + 0x7F, + 5, + 0xE0, + 0x25, + 0xEC, + 0xC0, + 0x3E, + 0x84, + 0x47, + 0xF0, + 0x8E, + 3, + 0xF8, + 3 + //420 + , + 0xFB, + 0xC0, + 0x19, + 0xF8, + 7, + 0x9C, + 0xC, + 0x17, + 0xF8, + 7, + 0xE0, + 0x1F, + 0xA1, + 0xFC, + 0xF, + 0xFC, + 1, + 0xF0, + 0x3F, + 0, + 0xFE, + 3, + 0xF0, + 0x1F, + 0, + 0xFD, + 0, + 0xFF, + 0x88, + 0xD, + 0xF9, + 1 + //440 + , + 0xFF, + 0, + 0x70, + 7, + 0xC0, + 0x3E, + 0x42, + 0xF3, + 0xD, + 0xC4, + 0x7F, + 0x80, + 0xFC, + 7, + 0xF0, + 0x5E, + 0xC0, + 0x3F, + 0, + 0x78, + 0x3F, + 0x81, + 0xFF, + 1, + 0xF8, + 1, + 0xC3, + 0xE8, + 0xC, + 0xE4, + 0x64, + 0x8F + ////460 + , + 0xE4, + 0xF, + 0xF0, + 7, + 0xF0, + 0xC2, + 0x1F, + 0, + 0x7F, + 0xC0, + 0x6F, + 0x80, + 0x7E, + 3, + 0xF8, + 7, + 0xF0, + 0x3F, + 0xC0, + 0x78, + 0xF, + 0x82, + 7, + 0xFE, + 0x22, + 0x77, + 0x70, + 2, + 0x76, + 3, + 0xFE, + 0 + //480 + , + 0xFE, + 0x67, + 0, + 0x7C, + 0xC7, + 0xF1, + 0x8E, + 0xC6, + 0x3B, + 0xE0, + 0x3F, + 0x84, + 0xF3, + 0x19, + 0xD8, + 3, + 0x99, + 0xFC, + 9, + 0xB8, + 0xF, + 0xF8, + 0, + 0x9D, + 0x24, + 0x61, + 0xF9, + 0xD, + 0, + 0xFD, + 3, + 0xF0 + //4a0 + , + 0x1F, + 0x90, + 0x3F, + 1, + 0xF8, + 0x1F, + 0xD0, + 0xF, + 0xF8, + 0x37, + 1, + 0xF8, + 7, + 0xF0, + 0xF, + 0xC0, + 0x3F, + 0, + 0xFE, + 3, + 0xF8, + 0xF, + 0xC0, + 0x3F, + 0, + 0xFA, + 3, + 0xF0, + 0xF, + 0x80, + 0xFF, + 1 + //4c0 + , + 0xB8, + 7, + 0xF0, + 1, + 0xFC, + 1, + 0xBC, + 0x80, + 0x13, + 0x1E, + 0, + 0x7F, + 0xE1, + 0x40, + 0x7F, + 0xA0, + 0x7F, + 0xB0, + 0, + 0x3F, + 0xC0, + 0x1F, + 0xC0, + 0x38, + 0xF, + 0xF0, + 0x1F, + 0x80, + 0xFF, + 1, + 0xFC, + 3 + //4e0 + , + 0xF1, + 0x7E, + 1, + 0xFE, + 1, + 0xF0, + 0xFF, + 0, + 0x7F, + 0xC0, + 0x1D, + 7, + 0xF0, + 0xF, + 0xC0, + 0x7E, + 6, + 0xE0, + 7, + 0xE0, + 0xF, + 0xF8, + 6, + 0xC1, + 0xFE, + 1, + 0xFC, + 3, + 0xE0, + 0xF, + 0, + 0xFC}; + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// Render +// +//////////////////////////////////////////////////////////////////////////////////////////// + +unsigned char pitches[256]; // tab43008 + +unsigned char frequency1[256]; +unsigned char frequency2[256]; +unsigned char frequency3[256]; + +unsigned char amplitude1[256]; +unsigned char amplitude2[256]; +unsigned char amplitude3[256]; + +unsigned char sampledConsonantFlag[256]; // tab44800 + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// Sam +// +//////////////////////////////////////////////////////////////////////////////////////////// + +unsigned char stress[256]; //numbers from 0 to 8 +unsigned char phonemeLength[256]; //tab40160 +unsigned char phonemeindex[256]; + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// ReciterTabs +// +//////////////////////////////////////////////////////////////////////////////////////////// + +//some flags +const unsigned char tab36376[] = { + 0, 0, 0, 0, 0, 0, 0, 0, // 0-7 + 0, 0, 0, 0, 0, 0, 0, 0, // 8-15 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 130, // ' ', '!' + 0, 0, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 2, 2, 2, 2, 2, 2, 192, 168, 176, 172, 192, 160, 184, // '@', 'A' + 160, 192, 188, 160, 172, 168, 172, 192, 160, 160, 172, 180, 164, 192, 168, 168, + 176, 192, 188, 0, 0, 0, 2, 0, // 'X', 'Y', 'Z', '[', + 32, 32, 155, 32, 192, 185, 32, 205, 163, 76, 138, 142}; + +const unsigned char rules[] = { + ']', 'A' | 0x80, ' ', '(', 'A', '.', ')', '=', + 'E', 'H', '4', 'Y', '.', ' ' | 0x80, '(', 'A', + ')', ' ', '=', 'A', 'H' | 0x80, ' ', '(', 'A', + 'R', 'E', ')', ' ', '=', 'A', 'A', 'R' | 0x80, + ' ', '(', 'A', 'R', ')', 'O', '=', 'A', + 'X', 'R' | 0x80, '(', 'A', 'R', ')', '#', '=', + 'E', 'H', '4', 'R' | 0x80, ' ', '^', '(', 'A', + 'S', ')', '#', '=', 'E', 'Y', '4', 'S' | 0x80, + '(', 'A', ')', 'W', 'A', '=', 'A', 'X' | 0x80, + '(', 'A', 'W', ')', '=', 'A', 'O', '5' | 0x80, + ' ', ':', '(', 'A', 'N', 'Y', ')', '=', + 'E', 'H', '4', 'N', 'I', 'Y' | 0x80, '(', 'A', + ')', '^', '+', '#', '=', 'E', 'Y', '5' | 0x80, + '#', ':', '(', 'A', 'L', 'L', 'Y', ')', + '=', 'U', 'L', 'I', 'Y' | 0x80, ' ', '(', 'A', + 'L', ')', '#', '=', 'U', 'L' | 0x80, '(', 'A', + 'G', 'A', 'I', 'N', ')', '=', 'A', 'X', + 'G', 'E', 'H', '4', 'N' | 0x80, '#', ':', '(', + 'A', 'G', ')', 'E', '=', 'I', 'H', 'J' | 0x80, + '(', 'A', ')', '^', '%', '=', 'E', 'Y' | 0x80, + '(', 'A', ')', '^', '+', ':', '#', '=', + 'A', 'E' | 0x80, ' ', ':', '(', 'A', ')', '^', + '+', ' ', '=', 'E', 'Y', '4' | 0x80, ' ', '(', + 'A', 'R', 'R', ')', '=', 'A', 'X', 'R' | 0x80, + '(', 'A', 'R', 'R', ')', '=', 'A', 'E', + '4', 'R' | 0x80, ' ', '^', '(', 'A', 'R', ')', + ' ', '=', 'A', 'A', '5', 'R' | 0x80, '(', 'A', + 'R', ')', '=', 'A', 'A', '5', 'R' | 0x80, '(', + 'A', 'I', 'R', ')', '=', 'E', 'H', '4', + 'R' | 0x80, '(', 'A', 'I', ')', '=', 'E', 'Y', + '4' | 0x80, '(', 'A', 'Y', ')', '=', 'E', 'Y', + '5' | 0x80, '(', 'A', 'U', ')', '=', 'A', 'O', + '4' | 0x80, '#', ':', '(', 'A', 'L', ')', ' ', + '=', 'U', 'L' | 0x80, '#', ':', '(', 'A', 'L', + 'S', ')', ' ', '=', 'U', 'L', 'Z' | 0x80, '(', + 'A', 'L', 'K', ')', '=', 'A', 'O', '4', + 'K' | 0x80, '(', 'A', 'L', ')', '^', '=', 'A', + 'O', 'L' | 0x80, ' ', ':', '(', 'A', 'B', 'L', + 'E', ')', '=', 'E', 'Y', '4', 'B', 'U', + 'L' | 0x80, '(', 'A', 'B', 'L', 'E', ')', '=', + 'A', 'X', 'B', 'U', 'L' | 0x80, '(', 'A', ')', + 'V', 'O', '=', 'E', 'Y', '4' | 0x80, '(', 'A', + 'N', 'G', ')', '+', '=', 'E', 'Y', '4', + 'N', 'J' | 0x80, '(', 'A', 'T', 'A', 'R', 'I', + ')', '=', 'A', 'H', 'T', 'A', 'A', '4', + 'R', 'I', 'Y' | 0x80, '(', 'A', ')', 'T', 'O', + 'M', '=', 'A', 'E' | 0x80, '(', 'A', ')', 'T', + 'T', 'I', '=', 'A', 'E' | 0x80, ' ', '(', 'A', + 'T', ')', ' ', '=', 'A', 'E', 'T' | 0x80, ' ', + '(', 'A', ')', 'T', '=', 'A', 'H' | 0x80, '(', + 'A', ')', '=', 'A', 'E' | 0x80, + + ']', 'B' | 0x80, ' ', '(', 'B', ')', ' ', '=', + 'B', 'I', 'Y', '4' | 0x80, ' ', '(', 'B', 'E', + ')', '^', '#', '=', 'B', 'I', 'H' | 0x80, '(', + 'B', 'E', 'I', 'N', 'G', ')', '=', 'B', + 'I', 'Y', '4', 'I', 'H', 'N', 'X' | 0x80, ' ', + '(', 'B', 'O', 'T', 'H', ')', ' ', '=', + 'B', 'O', 'W', '4', 'T', 'H' | 0x80, ' ', '(', + 'B', 'U', 'S', ')', '#', '=', 'B', 'I', + 'H', '4', 'Z' | 0x80, '(', 'B', 'R', 'E', 'A', + 'K', ')', '=', 'B', 'R', 'E', 'Y', '5', + 'K' | 0x80, '(', 'B', 'U', 'I', 'L', ')', '=', + 'B', 'I', 'H', '4', 'L' | 0x80, '(', 'B', ')', + '=', 'B' | 0x80, + + ']', 'C' | 0x80, ' ', '(', 'C', ')', ' ', '=', + 'S', 'I', 'Y', '4' | 0x80, ' ', '(', 'C', 'H', + ')', '^', '=', 'K' | 0x80, '^', 'E', '(', 'C', + 'H', ')', '=', 'K' | 0x80, '(', 'C', 'H', 'A', + ')', 'R', '#', '=', 'K', 'E', 'H', '5' | 0x80, + '(', 'C', 'H', ')', '=', 'C', 'H' | 0x80, ' ', + 'S', '(', 'C', 'I', ')', '#', '=', 'S', + 'A', 'Y', '4' | 0x80, '(', 'C', 'I', ')', 'A', + '=', 'S', 'H' | 0x80, '(', 'C', 'I', ')', 'O', + '=', 'S', 'H' | 0x80, '(', 'C', 'I', ')', 'E', + 'N', '=', 'S', 'H' | 0x80, '(', 'C', 'I', 'T', + 'Y', ')', '=', 'S', 'I', 'H', 'T', 'I', + 'Y' | 0x80, '(', 'C', ')', '+', '=', 'S' | 0x80, '(', + 'C', 'K', ')', '=', 'K' | 0x80, '(', 'C', 'O', + 'M', 'M', 'O', 'D', 'O', 'R', 'E', ')', + '=', 'K', 'A', 'A', '4', 'M', 'A', 'H', + 'D', 'O', 'H', 'R' | 0x80, '(', 'C', 'O', 'M', + ')', '=', 'K', 'A', 'H', 'M' | 0x80, '(', 'C', + 'U', 'I', 'T', ')', '=', 'K', 'I', 'H', + 'T' | 0x80, '(', 'C', 'R', 'E', 'A', ')', '=', + 'K', 'R', 'I', 'Y', 'E', 'Y' | 0x80, '(', 'C', + ')', '=', 'K' | 0x80, + + ']', 'D' | 0x80, ' ', '(', 'D', ')', ' ', '=', + 'D', 'I', 'Y', '4' | 0x80, ' ', '(', 'D', 'R', + '.', ')', ' ', '=', 'D', 'A', 'A', '4', + 'K', 'T', 'E', 'R' | 0x80, '#', ':', '(', 'D', + 'E', 'D', ')', ' ', '=', 'D', 'I', 'H', + 'D' | 0x80, '.', 'E', '(', 'D', ')', ' ', '=', + 'D' | 0x80, '#', ':', '^', 'E', '(', 'D', ')', + ' ', '=', 'T' | 0x80, ' ', '(', 'D', 'E', ')', + '^', '#', '=', 'D', 'I', 'H' | 0x80, ' ', '(', + 'D', 'O', ')', ' ', '=', 'D', 'U', 'W' | 0x80, + ' ', '(', 'D', 'O', 'E', 'S', ')', '=', + 'D', 'A', 'H', 'Z' | 0x80, '(', 'D', 'O', 'N', + 'E', ')', ' ', '=', 'D', 'A', 'H', '5', + 'N' | 0x80, '(', 'D', 'O', 'I', 'N', 'G', ')', + '=', 'D', 'U', 'W', '4', 'I', 'H', 'N', + 'X' | 0x80, ' ', '(', 'D', 'O', 'W', ')', '=', + 'D', 'A', 'W' | 0x80, '#', '(', 'D', 'U', ')', + 'A', '=', 'J', 'U', 'W' | 0x80, '#', '(', 'D', + 'U', ')', '^', '#', '=', 'J', 'A', 'X' | 0x80, + '(', 'D', ')', '=', 'D' | 0x80, + + ']', 'E' | 0x80, ' ', '(', 'E', ')', ' ', '=', + 'I', 'Y', 'I', 'Y', '4' | 0x80, '#', ':', '(', + 'E', ')', ' ', '=' | 0x80, '\'', ':', '^', '(', + 'E', ')', ' ', '=' | 0x80, ' ', ':', '(', 'E', + ')', ' ', '=', 'I', 'Y' | 0x80, '#', '(', 'E', + 'D', ')', ' ', '=', 'D' | 0x80, '#', ':', '(', + 'E', ')', 'D', ' ', '=' | 0x80, '(', 'E', 'V', + ')', 'E', 'R', '=', 'E', 'H', '4', 'V' | 0x80, + '(', 'E', ')', '^', '%', '=', 'I', 'Y', + '4' | 0x80, '(', 'E', 'R', 'I', ')', '#', '=', + 'I', 'Y', '4', 'R', 'I', 'Y' | 0x80, '(', 'E', + 'R', 'I', ')', '=', 'E', 'H', '4', 'R', + 'I', 'H' | 0x80, '#', ':', '(', 'E', 'R', ')', + '#', '=', 'E', 'R' | 0x80, '(', 'E', 'R', 'R', + 'O', 'R', ')', '=', 'E', 'H', '4', 'R', + 'O', 'H', 'R' | 0x80, '(', 'E', 'R', 'A', 'S', + 'E', ')', '=', 'I', 'H', 'R', 'E', 'Y', + '5', 'S' | 0x80, '(', 'E', 'R', ')', '#', '=', + 'E', 'H', 'R' | 0x80, '(', 'E', 'R', ')', '=', + 'E', 'R' | 0x80, ' ', '(', 'E', 'V', 'E', 'N', + ')', '=', 'I', 'Y', 'V', 'E', 'H', 'N' | 0x80, + '#', ':', '(', 'E', ')', 'W', '=' | 0x80, '@', + '(', 'E', 'W', ')', '=', 'U', 'W' | 0x80, '(', + 'E', 'W', ')', '=', 'Y', 'U', 'W' | 0x80, '(', + 'E', ')', 'O', '=', 'I', 'Y' | 0x80, '#', ':', + '&', '(', 'E', 'S', ')', ' ', '=', 'I', + 'H', 'Z' | 0x80, '#', ':', '(', 'E', ')', 'S', + ' ', '=' | 0x80, '#', ':', '(', 'E', 'L', 'Y', + ')', ' ', '=', 'L', 'I', 'Y' | 0x80, '#', ':', + '(', 'E', 'M', 'E', 'N', 'T', ')', '=', + 'M', 'E', 'H', 'N', 'T' | 0x80, '(', 'E', 'F', + 'U', 'L', ')', '=', 'F', 'U', 'H', 'L' | 0x80, + '(', 'E', 'E', ')', '=', 'I', 'Y', '4' | 0x80, + '(', 'E', 'A', 'R', 'N', ')', '=', 'E', + 'R', '5', 'N' | 0x80, ' ', '(', 'E', 'A', 'R', + ')', '^', '=', 'E', 'R', '5' | 0x80, '(', 'E', + 'A', 'D', ')', '=', 'E', 'H', 'D' | 0x80, '#', + ':', '(', 'E', 'A', ')', ' ', '=', 'I', + 'Y', 'A', 'X' | 0x80, '(', 'E', 'A', ')', 'S', + 'U', '=', 'E', 'H', '5' | 0x80, '(', 'E', 'A', + ')', '=', 'I', 'Y', '5' | 0x80, '(', 'E', 'I', + 'G', 'H', ')', '=', 'E', 'Y', '4' | 0x80, '(', + 'E', 'I', ')', '=', 'I', 'Y', '4' | 0x80, ' ', + '(', 'E', 'Y', 'E', ')', '=', 'A', 'Y', + '4' | 0x80, '(', 'E', 'Y', ')', '=', 'I', 'Y' | 0x80, + '(', 'E', 'U', ')', '=', 'Y', 'U', 'W', + '5' | 0x80, '(', 'E', 'Q', 'U', 'A', 'L', ')', + '=', 'I', 'Y', '4', 'K', 'W', 'U', 'L' | 0x80, + '(', 'E', ')', '=', 'E', 'H' | 0x80, + + ']', 'F' | 0x80, ' ', '(', 'F', ')', ' ', '=', + 'E', 'H', '4', 'F' | 0x80, '(', 'F', 'U', 'L', + ')', '=', 'F', 'U', 'H', 'L' | 0x80, '(', 'F', + 'R', 'I', 'E', 'N', 'D', ')', '=', 'F', + 'R', 'E', 'H', '5', 'N', 'D' | 0x80, '(', 'F', + 'A', 'T', 'H', 'E', 'R', ')', '=', 'F', + 'A', 'A', '4', 'D', 'H', 'E', 'R' | 0x80, '(', + 'F', ')', 'F', '=' | 0x80, '(', 'F', ')', '=', + 'F' | 0x80, + + ']', 'G' | 0x80, ' ', '(', 'G', ')', ' ', '=', + 'J', 'I', 'Y', '4' | 0x80, '(', 'G', 'I', 'V', + ')', '=', 'G', 'I', 'H', '5', 'V' | 0x80, ' ', + '(', 'G', ')', 'I', '^', '=', 'G' | 0x80, '(', + 'G', 'E', ')', 'T', '=', 'G', 'E', 'H', + '5' | 0x80, 'S', 'U', '(', 'G', 'G', 'E', 'S', + ')', '=', 'G', 'J', 'E', 'H', '4', 'S' | 0x80, + '(', 'G', 'G', ')', '=', 'G' | 0x80, ' ', 'B', + '#', '(', 'G', ')', '=', 'G' | 0x80, '(', 'G', + ')', '+', '=', 'J' | 0x80, '(', 'G', 'R', 'E', + 'A', 'T', ')', '=', 'G', 'R', 'E', 'Y', + '4', 'T' | 0x80, '(', 'G', 'O', 'N', ')', 'E', + '=', 'G', 'A', 'O', '5', 'N' | 0x80, '#', '(', + 'G', 'H', ')', '=' | 0x80, ' ', '(', 'G', 'N', + ')', '=', 'N' | 0x80, '(', 'G', ')', '=', 'G' | 0x80, + + ']', 'H' | 0x80, ' ', '(', 'H', ')', ' ', '=', + 'E', 'Y', '4', 'C', 'H' | 0x80, ' ', '(', 'H', + 'A', 'V', ')', '=', '/', 'H', 'A', 'E', + '6', 'V' | 0x80, ' ', '(', 'H', 'E', 'R', 'E', + ')', '=', '/', 'H', 'I', 'Y', 'R' | 0x80, ' ', + '(', 'H', 'O', 'U', 'R', ')', '=', 'A', + 'W', '5', 'E', 'R' | 0x80, '(', 'H', 'O', 'W', + ')', '=', '/', 'H', 'A', 'W' | 0x80, '(', 'H', + ')', '#', '=', '/', 'H' | 0x80, '(', 'H', ')', + '=' | 0x80, + + ']', 'I' | 0x80, ' ', '(', 'I', 'N', ')', '=', + 'I', 'H', 'N' | 0x80, ' ', '(', 'I', ')', ' ', + '=', 'A', 'Y', '4' | 0x80, '(', 'I', ')', ' ', + '=', 'A', 'Y' | 0x80, '(', 'I', 'N', ')', 'D', + '=', 'A', 'Y', '5', 'N' | 0x80, 'S', 'E', 'M', + '(', 'I', ')', '=', 'I', 'Y' | 0x80, ' ', 'A', + 'N', 'T', '(', 'I', ')', '=', 'A', 'Y' | 0x80, + '(', 'I', 'E', 'R', ')', '=', 'I', 'Y', + 'E', 'R' | 0x80, '#', ':', 'R', '(', 'I', 'E', + 'D', ')', ' ', '=', 'I', 'Y', 'D' | 0x80, '(', + 'I', 'E', 'D', ')', ' ', '=', 'A', 'Y', + '5', 'D' | 0x80, '(', 'I', 'E', 'N', ')', '=', + 'I', 'Y', 'E', 'H', 'N' | 0x80, '(', 'I', 'E', + ')', 'T', '=', 'A', 'Y', '4', 'E', 'H' | 0x80, + '(', 'I', '\'', ')', '=', 'A', 'Y', '5' | 0x80, + ' ', ':', '(', 'I', ')', '^', '%', '=', + 'A', 'Y', '5' | 0x80, ' ', ':', '(', 'I', 'E', + ')', ' ', '=', 'A', 'Y', '4' | 0x80, '(', 'I', + ')', '%', '=', 'I', 'Y' | 0x80, '(', 'I', 'E', + ')', '=', 'I', 'Y', '4' | 0x80, ' ', '(', 'I', + 'D', 'E', 'A', ')', '=', 'A', 'Y', 'D', + 'I', 'Y', '5', 'A', 'H' | 0x80, '(', 'I', ')', + '^', '+', ':', '#', '=', 'I', 'H' | 0x80, '(', + 'I', 'R', ')', '#', '=', 'A', 'Y', 'R' | 0x80, + '(', 'I', 'Z', ')', '%', '=', 'A', 'Y', + 'Z' | 0x80, '(', 'I', 'S', ')', '%', '=', 'A', + 'Y', 'Z' | 0x80, 'I', '^', '(', 'I', ')', '^', + '#', '=', 'I', 'H' | 0x80, '+', '^', '(', 'I', + ')', '^', '+', '=', 'A', 'Y' | 0x80, '#', ':', + '^', '(', 'I', ')', '^', '+', '=', 'I', + 'H' | 0x80, '(', 'I', ')', '^', '+', '=', 'A', + 'Y' | 0x80, '(', 'I', 'R', ')', '=', 'E', 'R' | 0x80, + '(', 'I', 'G', 'H', ')', '=', 'A', 'Y', + '4' | 0x80, '(', 'I', 'L', 'D', ')', '=', 'A', + 'Y', '5', 'L', 'D' | 0x80, ' ', '(', 'I', 'G', + 'N', ')', '=', 'I', 'H', 'G', 'N' | 0x80, '(', + 'I', 'G', 'N', ')', ' ', '=', 'A', 'Y', + '4', 'N' | 0x80, '(', 'I', 'G', 'N', ')', '^', + '=', 'A', 'Y', '4', 'N' | 0x80, '(', 'I', 'G', + 'N', ')', '%', '=', 'A', 'Y', '4', 'N' | 0x80, + '(', 'I', 'C', 'R', 'O', ')', '=', 'A', + 'Y', '4', 'K', 'R', 'O', 'H' | 0x80, '(', 'I', + 'Q', 'U', 'E', ')', '=', 'I', 'Y', '4', + 'K' | 0x80, '(', 'I', ')', '=', 'I', 'H' | 0x80, + + ']', 'J' | 0x80, ' ', '(', 'J', ')', ' ', '=', + 'J', 'E', 'Y', '4' | 0x80, '(', 'J', ')', '=', + 'J' | 0x80, + + ']', 'K' | 0x80, ' ', '(', 'K', ')', ' ', '=', + 'K', 'E', 'Y', '4' | 0x80, ' ', '(', 'K', ')', + 'N', '=' | 0x80, '(', 'K', ')', '=', 'K' | 0x80, + + ']', 'L' | 0x80, ' ', '(', 'L', ')', ' ', '=', + 'E', 'H', '4', 'L' | 0x80, '(', 'L', 'O', ')', + 'C', '#', '=', 'L', 'O', 'W' | 0x80, 'L', '(', + 'L', ')', '=' | 0x80, '#', ':', '^', '(', 'L', + ')', '%', '=', 'U', 'L' | 0x80, '(', 'L', 'E', + 'A', 'D', ')', '=', 'L', 'I', 'Y', 'D' | 0x80, + ' ', '(', 'L', 'A', 'U', 'G', 'H', ')', + '=', 'L', 'A', 'E', '4', 'F' | 0x80, '(', 'L', + ')', '=', 'L' | 0x80, + + ']', 'M' | 0x80, ' ', '(', 'M', ')', ' ', '=', + 'E', 'H', '4', 'M' | 0x80, ' ', '(', 'M', 'R', + '.', ')', ' ', '=', 'M', 'I', 'H', '4', + 'S', 'T', 'E', 'R' | 0x80, ' ', '(', 'M', 'S', + '.', ')', '=', 'M', 'I', 'H', '5', 'Z' | 0x80, + ' ', '(', 'M', 'R', 'S', '.', ')', ' ', + '=', 'M', 'I', 'H', '4', 'S', 'I', 'X', + 'Z' | 0x80, '(', 'M', 'O', 'V', ')', '=', 'M', + 'U', 'W', '4', 'V' | 0x80, '(', 'M', 'A', 'C', + 'H', 'I', 'N', ')', '=', 'M', 'A', 'H', + 'S', 'H', 'I', 'Y', '5', 'N' | 0x80, 'M', '(', + 'M', ')', '=' | 0x80, '(', 'M', ')', '=', 'M' | 0x80, + + ']', 'N' | 0x80, ' ', '(', 'N', ')', ' ', '=', + 'E', 'H', '4', 'N' | 0x80, 'E', '(', 'N', 'G', + ')', '+', '=', 'N', 'J' | 0x80, '(', 'N', 'G', + ')', 'R', '=', 'N', 'X', 'G' | 0x80, '(', 'N', + 'G', ')', '#', '=', 'N', 'X', 'G' | 0x80, '(', + 'N', 'G', 'L', ')', '%', '=', 'N', 'X', + 'G', 'U', 'L' | 0x80, '(', 'N', 'G', ')', '=', + 'N', 'X' | 0x80, '(', 'N', 'K', ')', '=', 'N', + 'X', 'K' | 0x80, ' ', '(', 'N', 'O', 'W', ')', + ' ', '=', 'N', 'A', 'W', '4' | 0x80, 'N', '(', + 'N', ')', '=' | 0x80, '(', 'N', 'O', 'N', ')', + 'E', '=', 'N', 'A', 'H', '4', 'N' | 0x80, '(', + 'N', ')', '=', 'N' | 0x80, + + ']', 'O' | 0x80, ' ', '(', 'O', ')', ' ', '=', + 'O', 'H', '4', 'W' | 0x80, '(', 'O', 'F', ')', + ' ', '=', 'A', 'H', 'V' | 0x80, ' ', '(', 'O', + 'H', ')', ' ', '=', 'O', 'W', '5' | 0x80, '(', + 'O', 'R', 'O', 'U', 'G', 'H', ')', '=', + 'E', 'R', '4', 'O', 'W' | 0x80, '#', ':', '(', + 'O', 'R', ')', ' ', '=', 'E', 'R' | 0x80, '#', + ':', '(', 'O', 'R', 'S', ')', ' ', '=', + 'E', 'R', 'Z' | 0x80, '(', 'O', 'R', ')', '=', + 'A', 'O', 'R' | 0x80, ' ', '(', 'O', 'N', 'E', + ')', '=', 'W', 'A', 'H', 'N' | 0x80, '#', '(', + 'O', 'N', 'E', ')', ' ', '=', 'W', 'A', + 'H', 'N' | 0x80, '(', 'O', 'W', ')', '=', 'O', + 'W' | 0x80, ' ', '(', 'O', 'V', 'E', 'R', ')', + '=', 'O', 'W', '5', 'V', 'E', 'R' | 0x80, 'P', + 'R', '(', 'O', ')', 'V', '=', 'U', 'W', + '4' | 0x80, '(', 'O', 'V', ')', '=', 'A', 'H', + '4', 'V' | 0x80, '(', 'O', ')', '^', '%', '=', + 'O', 'W', '5' | 0x80, '(', 'O', ')', '^', 'E', + 'N', '=', 'O', 'W' | 0x80, '(', 'O', ')', '^', + 'I', '#', '=', 'O', 'W', '5' | 0x80, '(', 'O', + 'L', ')', 'D', '=', 'O', 'W', '4', 'L' | 0x80, + '(', 'O', 'U', 'G', 'H', 'T', ')', '=', + 'A', 'O', '5', 'T' | 0x80, '(', 'O', 'U', 'G', + 'H', ')', '=', 'A', 'H', '5', 'F' | 0x80, ' ', + '(', 'O', 'U', ')', '=', 'A', 'W' | 0x80, 'H', + '(', 'O', 'U', ')', 'S', '#', '=', 'A', + 'W', '4' | 0x80, '(', 'O', 'U', 'S', ')', '=', + 'A', 'X', 'S' | 0x80, '(', 'O', 'U', 'R', ')', + '=', 'O', 'H', 'R' | 0x80, '(', 'O', 'U', 'L', + 'D', ')', '=', 'U', 'H', '5', 'D' | 0x80, '(', + 'O', 'U', ')', '^', 'L', '=', 'A', 'H', + '5' | 0x80, '(', 'O', 'U', 'P', ')', '=', 'U', + 'W', '5', 'P' | 0x80, '(', 'O', 'U', ')', '=', + 'A', 'W' | 0x80, '(', 'O', 'Y', ')', '=', 'O', + 'Y' | 0x80, '(', 'O', 'I', 'N', 'G', ')', '=', + 'O', 'W', '4', 'I', 'H', 'N', 'X' | 0x80, '(', + 'O', 'I', ')', '=', 'O', 'Y', '5' | 0x80, '(', + 'O', 'O', 'R', ')', '=', 'O', 'H', '5', + 'R' | 0x80, '(', 'O', 'O', 'K', ')', '=', 'U', + 'H', '5', 'K' | 0x80, 'F', '(', 'O', 'O', 'D', + ')', '=', 'U', 'W', '5', 'D' | 0x80, 'L', '(', + 'O', 'O', 'D', ')', '=', 'A', 'H', '5', + 'D' | 0x80, 'M', '(', 'O', 'O', 'D', ')', '=', + 'U', 'W', '5', 'D' | 0x80, '(', 'O', 'O', 'D', + ')', '=', 'U', 'H', '5', 'D' | 0x80, 'F', '(', + 'O', 'O', 'T', ')', '=', 'U', 'H', '5', + 'T' | 0x80, '(', 'O', 'O', ')', '=', 'U', 'W', + '5' | 0x80, '(', 'O', '\'', ')', '=', 'O', 'H' | 0x80, + '(', 'O', ')', 'E', '=', 'O', 'W' | 0x80, '(', + 'O', ')', ' ', '=', 'O', 'W' | 0x80, '(', 'O', + 'A', ')', '=', 'O', 'W', '4' | 0x80, ' ', '(', + 'O', 'N', 'L', 'Y', ')', '=', 'O', 'W', + '4', 'N', 'L', 'I', 'Y' | 0x80, ' ', '(', 'O', + 'N', 'C', 'E', ')', '=', 'W', 'A', 'H', + '4', 'N', 'S' | 0x80, '(', 'O', 'N', '\'', 'T', + ')', '=', 'O', 'W', '4', 'N', 'T' | 0x80, 'C', + '(', 'O', ')', 'N', '=', 'A', 'A' | 0x80, '(', + 'O', ')', 'N', 'G', '=', 'A', 'O' | 0x80, ' ', + ':', '^', '(', 'O', ')', 'N', '=', 'A', + 'H' | 0x80, 'I', '(', 'O', 'N', ')', '=', 'U', + 'N' | 0x80, '#', ':', '(', 'O', 'N', ')', '=', + 'U', 'N' | 0x80, '#', '^', '(', 'O', 'N', ')', + '=', 'U', 'N' | 0x80, '(', 'O', ')', 'S', 'T', + '=', 'O', 'W' | 0x80, '(', 'O', 'F', ')', '^', + '=', 'A', 'O', '4', 'F' | 0x80, '(', 'O', 'T', + 'H', 'E', 'R', ')', '=', 'A', 'H', '5', + 'D', 'H', 'E', 'R' | 0x80, 'R', '(', 'O', ')', + 'B', '=', 'R', 'A', 'A' | 0x80, '^', 'R', '(', + 'O', ')', ':', '#', '=', 'O', 'W', '5' | 0x80, + '(', 'O', 'S', 'S', ')', ' ', '=', 'A', + 'O', '5', 'S' | 0x80, '#', ':', '^', '(', 'O', + 'M', ')', '=', 'A', 'H', 'M' | 0x80, '(', 'O', + ')', '=', 'A', 'A' | 0x80, + + ']', 'P' | 0x80, ' ', '(', 'P', ')', ' ', '=', + 'P', 'I', 'Y', '4' | 0x80, '(', 'P', 'H', ')', + '=', 'F' | 0x80, '(', 'P', 'E', 'O', 'P', 'L', + ')', '=', 'P', 'I', 'Y', '5', 'P', 'U', + 'L' | 0x80, '(', 'P', 'O', 'W', ')', '=', 'P', + 'A', 'W', '4' | 0x80, '(', 'P', 'U', 'T', ')', + ' ', '=', 'P', 'U', 'H', 'T' | 0x80, '(', 'P', + ')', 'P', '=' | 0x80, '(', 'P', ')', 'S', '=' | 0x80, + '(', 'P', ')', 'N', '=' | 0x80, '(', 'P', 'R', + 'O', 'F', '.', ')', '=', 'P', 'R', 'O', + 'H', 'F', 'E', 'H', '4', 'S', 'E', 'R' | 0x80, + '(', 'P', ')', '=', 'P' | 0x80, + + ']', 'Q' | 0x80, ' ', '(', 'Q', ')', ' ', '=', + 'K', 'Y', 'U', 'W', '4' | 0x80, '(', 'Q', 'U', + 'A', 'R', ')', '=', 'K', 'W', 'O', 'H', + '5', 'R' | 0x80, '(', 'Q', 'U', ')', '=', 'K', + 'W' | 0x80, '(', 'Q', ')', '=', 'K' | 0x80, ']', 'R' | 0x80, + ' ', '(', 'R', ')', ' ', '=', 'A', 'A', + '5', 'R' | 0x80, ' ', '(', 'R', 'E', ')', '^', + '#', '=', 'R', 'I', 'Y' | 0x80, '(', 'R', ')', + 'R', '=' | 0x80, '(', 'R', ')', '=', 'R' | 0x80, + + ']', 'S' | 0x80, ' ', '(', 'S', ')', ' ', '=', + 'E', 'H', '4', 'S' | 0x80, '(', 'S', 'H', ')', + '=', 'S', 'H' | 0x80, '#', '(', 'S', 'I', 'O', + 'N', ')', '=', 'Z', 'H', 'U', 'N' | 0x80, '(', + 'S', 'O', 'M', 'E', ')', '=', 'S', 'A', + 'H', 'M' | 0x80, '#', '(', 'S', 'U', 'R', ')', + '#', '=', 'Z', 'H', 'E', 'R' | 0x80, '(', 'S', + 'U', 'R', ')', '#', '=', 'S', 'H', 'E', + 'R' | 0x80, '#', '(', 'S', 'U', ')', '#', '=', + 'Z', 'H', 'U', 'W' | 0x80, '#', '(', 'S', 'S', + 'U', ')', '#', '=', 'S', 'H', 'U', 'W' | 0x80, + '#', '(', 'S', 'E', 'D', ')', '=', 'Z', + 'D' | 0x80, '#', '(', 'S', ')', '#', '=', 'Z' | 0x80, + '(', 'S', 'A', 'I', 'D', ')', '=', 'S', + 'E', 'H', 'D' | 0x80, '^', '(', 'S', 'I', 'O', + 'N', ')', '=', 'S', 'H', 'U', 'N' | 0x80, '(', + 'S', ')', 'S', '=' | 0x80, '.', '(', 'S', ')', + ' ', '=', 'Z' | 0x80, '#', ':', '.', 'E', '(', + 'S', ')', ' ', '=', 'Z' | 0x80, '#', ':', '^', + '#', '(', 'S', ')', ' ', '=', 'S' | 0x80, 'U', + '(', 'S', ')', ' ', '=', 'S' | 0x80, ' ', ':', + '#', '(', 'S', ')', ' ', '=', 'Z' | 0x80, '#', + '#', '(', 'S', ')', ' ', '=', 'Z' | 0x80, ' ', + '(', 'S', 'C', 'H', ')', '=', 'S', 'K' | 0x80, + '(', 'S', ')', 'C', '+', '=' | 0x80, '#', '(', + 'S', 'M', ')', '=', 'Z', 'U', 'M' | 0x80, '#', + '(', 'S', 'N', ')', '\'', '=', 'Z', 'U', + 'M' | 0x80, '(', 'S', 'T', 'L', 'E', ')', '=', + 'S', 'U', 'L' | 0x80, '(', 'S', ')', '=', 'S' | 0x80, + + ']', 'T' | 0x80, ' ', '(', 'T', ')', ' ', '=', + 'T', 'I', 'Y', '4' | 0x80, ' ', '(', 'T', 'H', + 'E', ')', ' ', '#', '=', 'D', 'H', 'I', + 'Y' | 0x80, ' ', '(', 'T', 'H', 'E', ')', ' ', + '=', 'D', 'H', 'A', 'X' | 0x80, '(', 'T', 'O', + ')', ' ', '=', 'T', 'U', 'X' | 0x80, ' ', '(', + 'T', 'H', 'A', 'T', ')', '=', 'D', 'H', + 'A', 'E', 'T' | 0x80, ' ', '(', 'T', 'H', 'I', + 'S', ')', ' ', '=', 'D', 'H', 'I', 'H', + 'S' | 0x80, ' ', '(', 'T', 'H', 'E', 'Y', ')', + '=', 'D', 'H', 'E', 'Y' | 0x80, ' ', '(', 'T', + 'H', 'E', 'R', 'E', ')', '=', 'D', 'H', + 'E', 'H', 'R' | 0x80, '(', 'T', 'H', 'E', 'R', + ')', '=', 'D', 'H', 'E', 'R' | 0x80, '(', 'T', + 'H', 'E', 'I', 'R', ')', '=', 'D', 'H', + 'E', 'H', 'R' | 0x80, ' ', '(', 'T', 'H', 'A', + 'N', ')', ' ', '=', 'D', 'H', 'A', 'E', + 'N' | 0x80, ' ', '(', 'T', 'H', 'E', 'M', ')', + ' ', '=', 'D', 'H', 'A', 'E', 'N' | 0x80, '(', + 'T', 'H', 'E', 'S', 'E', ')', ' ', '=', + 'D', 'H', 'I', 'Y', 'Z' | 0x80, ' ', '(', 'T', + 'H', 'E', 'N', ')', '=', 'D', 'H', 'E', + 'H', 'N' | 0x80, '(', 'T', 'H', 'R', 'O', 'U', + 'G', 'H', ')', '=', 'T', 'H', 'R', 'U', + 'W', '4' | 0x80, '(', 'T', 'H', 'O', 'S', 'E', + ')', '=', 'D', 'H', 'O', 'H', 'Z' | 0x80, '(', + 'T', 'H', 'O', 'U', 'G', 'H', ')', ' ', + '=', 'D', 'H', 'O', 'W' | 0x80, '(', 'T', 'O', + 'D', 'A', 'Y', ')', '=', 'T', 'U', 'X', + 'D', 'E', 'Y' | 0x80, '(', 'T', 'O', 'M', 'O', + ')', 'R', 'R', 'O', 'W', '=', 'T', 'U', + 'M', 'A', 'A', '5' | 0x80, '(', 'T', 'O', ')', + 'T', 'A', 'L', '=', 'T', 'O', 'W', '5' | 0x80, + ' ', '(', 'T', 'H', 'U', 'S', ')', '=', + 'D', 'H', 'A', 'H', '4', 'S' | 0x80, '(', 'T', + 'H', ')', '=', 'T', 'H' | 0x80, '#', ':', '(', + 'T', 'E', 'D', ')', '=', 'T', 'I', 'X', + 'D' | 0x80, 'S', '(', 'T', 'I', ')', '#', 'N', + '=', 'C', 'H' | 0x80, '(', 'T', 'I', ')', 'O', + '=', 'S', 'H' | 0x80, '(', 'T', 'I', ')', 'A', + '=', 'S', 'H' | 0x80, '(', 'T', 'I', 'E', 'N', + ')', '=', 'S', 'H', 'U', 'N' | 0x80, '(', 'T', + 'U', 'R', ')', '#', '=', 'C', 'H', 'E', + 'R' | 0x80, '(', 'T', 'U', ')', 'A', '=', 'C', + 'H', 'U', 'W' | 0x80, ' ', '(', 'T', 'W', 'O', + ')', '=', 'T', 'U', 'W' | 0x80, '&', '(', 'T', + ')', 'E', 'N', ' ', '=' | 0x80, '(', 'T', ')', + '=', 'T' | 0x80, + + ']', 'U' | 0x80, ' ', '(', 'U', ')', ' ', '=', + 'Y', 'U', 'W', '4' | 0x80, ' ', '(', 'U', 'N', + ')', 'I', '=', 'Y', 'U', 'W', 'N' | 0x80, ' ', + '(', 'U', 'N', ')', '=', 'A', 'H', 'N' | 0x80, + ' ', '(', 'U', 'P', 'O', 'N', ')', '=', + 'A', 'X', 'P', 'A', 'O', 'N' | 0x80, '@', '(', + 'U', 'R', ')', '#', '=', 'U', 'H', '4', + 'R' | 0x80, '(', 'U', 'R', ')', '#', '=', 'Y', + 'U', 'H', '4', 'R' | 0x80, '(', 'U', 'R', ')', + '=', 'E', 'R' | 0x80, '(', 'U', ')', '^', ' ', + '=', 'A', 'H' | 0x80, '(', 'U', ')', '^', '^', + '=', 'A', 'H', '5' | 0x80, '(', 'U', 'Y', ')', + '=', 'A', 'Y', '5' | 0x80, ' ', 'G', '(', 'U', + ')', '#', '=' | 0x80, 'G', '(', 'U', ')', '%', + '=' | 0x80, 'G', '(', 'U', ')', '#', '=', 'W' | 0x80, + '#', 'N', '(', 'U', ')', '=', 'Y', 'U', + 'W' | 0x80, '@', '(', 'U', ')', '=', 'U', 'W' | 0x80, + '(', 'U', ')', '=', 'Y', 'U', 'W' | 0x80, + + ']', 'V' | 0x80, ' ', '(', 'V', ')', ' ', '=', + 'V', 'I', 'Y', '4' | 0x80, '(', 'V', 'I', 'E', + 'W', ')', '=', 'V', 'Y', 'U', 'W', '5' | 0x80, + '(', 'V', ')', '=', 'V' | 0x80, + + ']', 'W' | 0x80, ' ', '(', 'W', ')', ' ', '=', + 'D', 'A', 'H', '4', 'B', 'U', 'L', 'Y', + 'U', 'W' | 0x80, ' ', '(', 'W', 'E', 'R', 'E', + ')', '=', 'W', 'E', 'R' | 0x80, '(', 'W', 'A', + ')', 'S', 'H', '=', 'W', 'A', 'A' | 0x80, '(', + 'W', 'A', ')', 'S', 'T', '=', 'W', 'E', + 'Y' | 0x80, '(', 'W', 'A', ')', 'S', '=', 'W', + 'A', 'H' | 0x80, '(', 'W', 'A', ')', 'T', '=', + 'W', 'A', 'A' | 0x80, '(', 'W', 'H', 'E', 'R', + 'E', ')', '=', 'W', 'H', 'E', 'H', 'R' | 0x80, + '(', 'W', 'H', 'A', 'T', ')', '=', 'W', + 'H', 'A', 'H', 'T' | 0x80, '(', 'W', 'H', 'O', + 'L', ')', '=', '/', 'H', 'O', 'W', 'L' | 0x80, + '(', 'W', 'H', 'O', ')', '=', '/', 'H', + 'U', 'W' | 0x80, '(', 'W', 'H', ')', '=', 'W', + 'H' | 0x80, '(', 'W', 'A', 'R', ')', '#', '=', + 'W', 'E', 'H', 'R' | 0x80, '(', 'W', 'A', 'R', + ')', '=', 'W', 'A', 'O', 'R' | 0x80, '(', 'W', + 'O', 'R', ')', '^', '=', 'W', 'E', 'R' | 0x80, + '(', 'W', 'R', ')', '=', 'R' | 0x80, '(', 'W', + 'O', 'M', ')', 'A', '=', 'W', 'U', 'H', + 'M' | 0x80, '(', 'W', 'O', 'M', ')', 'E', '=', + 'W', 'I', 'H', 'M' | 0x80, '(', 'W', 'E', 'A', + ')', 'R', '=', 'W', 'E', 'H' | 0x80, '(', 'W', + 'A', 'N', 'T', ')', '=', 'W', 'A', 'A', + '5', 'N', 'T' | 0x80, 'A', 'N', 'S', '(', 'W', + 'E', 'R', ')', '=', 'E', 'R' | 0x80, '(', 'W', + ')', '=', 'W' | 0x80, + + ']', 'X' | 0x80, ' ', '(', 'X', ')', ' ', '=', + 'E', 'H', '4', 'K', 'R' | 0x80, ' ', '(', 'X', + ')', '=', 'Z' | 0x80, '(', 'X', ')', '=', 'K', + 'S' | 0x80, + + ']', 'Y' | 0x80, ' ', '(', 'Y', ')', ' ', '=', + 'W', 'A', 'Y', '4' | 0x80, '(', 'Y', 'O', 'U', + 'N', 'G', ')', '=', 'Y', 'A', 'H', 'N', + 'X' | 0x80, ' ', '(', 'Y', 'O', 'U', 'R', ')', + '=', 'Y', 'O', 'H', 'R' | 0x80, ' ', '(', 'Y', + 'O', 'U', ')', '=', 'Y', 'U', 'W' | 0x80, ' ', + '(', 'Y', 'E', 'S', ')', '=', 'Y', 'E', + 'H', 'S' | 0x80, ' ', '(', 'Y', ')', '=', 'Y' | 0x80, + 'F', '(', 'Y', ')', '=', 'A', 'Y' | 0x80, 'P', + 'S', '(', 'Y', 'C', 'H', ')', '=', 'A', + 'Y', 'K' | 0x80, '#', ':', '^', '(', 'Y', ')', + '=', 'I', 'Y' | 0x80, '#', ':', '^', '(', 'Y', + ')', 'I', '=', 'I', 'Y' | 0x80, ' ', ':', '(', + 'Y', ')', ' ', '=', 'A', 'Y' | 0x80, ' ', ':', + '(', 'Y', ')', '#', '=', 'A', 'Y' | 0x80, ' ', + ':', '(', 'Y', ')', '^', '+', ':', '#', + '=', 'I', 'H' | 0x80, ' ', ':', '(', 'Y', ')', + '^', '#', '=', 'A', 'Y' | 0x80, '(', 'Y', ')', + '=', 'I', 'H' | 0x80, + + ']', 'Z' | 0x80, ' ', '(', 'Z', ')', ' ', '=', + 'Z', 'I', 'Y', '4' | 0x80, '(', 'Z', ')', '=', + 'Z' | 0x80, 'j' | 0x80}; + +const unsigned char rules2[] = { + '(', 'A', ')', '=' | 0x80, '(', '!', ')', '=', + '.' | 0x80, '(', '"', ')', ' ', '=', '-', 'A', + 'H', '5', 'N', 'K', 'W', 'O', 'W', 'T', + '-' | 0x80, '(', '"', ')', '=', 'K', 'W', 'O', + 'W', '4', 'T', '-' | 0x80, '(', '#', ')', '=', + ' ', 'N', 'A', 'H', '4', 'M', 'B', 'E', + 'R' | 0x80, '(', '$', ')', '=', ' ', 'D', 'A', + 'A', '4', 'L', 'E', 'R' | 0x80, '(', '%', ')', + '=', ' ', 'P', 'E', 'R', 'S', 'E', 'H', + '4', 'N', 'T' | 0x80, '(', '&', ')', '=', ' ', + 'A', 'E', 'N', 'D' | 0x80, '(', '\'', ')', '=' | 0x80, + '(', '*', ')', '=', ' ', 'A', 'E', '4', + 'S', 'T', 'E', 'R', 'I', 'H', 'S', 'K' | 0x80, + '(', '+', ')', '=', ' ', 'P', 'L', 'A', + 'H', '4', 'S' | 0x80, '(', ',', ')', '=', ',' | 0x80, + ' ', '(', '-', ')', ' ', '=', '-' | 0x80, '(', + '-', ')', '=' | 0x80, '(', '.', ')', '=', ' ', + 'P', 'O', 'Y', 'N', 'T' | 0x80, '(', '/', ')', + '=', ' ', 'S', 'L', 'A', 'E', '4', 'S', + 'H' | 0x80, '(', '0', ')', '=', ' ', 'Z', 'I', + 'Y', '4', 'R', 'O', 'W' | 0x80, ' ', '(', '1', + 'S', 'T', ')', '=', 'F', 'E', 'R', '4', + 'S', 'T' | 0x80, ' ', '(', '1', '0', 'T', 'H', + ')', '=', 'T', 'E', 'H', '4', 'N', 'T', + 'H' | 0x80, '(', '1', ')', '=', ' ', 'W', 'A', + 'H', '4', 'N' | 0x80, ' ', '(', '2', 'N', 'D', + ')', '=', 'S', 'E', 'H', '4', 'K', 'U', + 'N', 'D' | 0x80, '(', '2', ')', '=', ' ', 'T', + 'U', 'W', '4' | 0x80, ' ', '(', '3', 'R', 'D', + ')', '=', 'T', 'H', 'E', 'R', '4', 'D' | 0x80, + '(', '3', ')', '=', ' ', 'T', 'H', 'R', + 'I', 'Y', '4' | 0x80, '(', '4', ')', '=', ' ', + 'F', 'O', 'H', '4', 'R' | 0x80, ' ', '(', '5', + 'T', 'H', ')', '=', 'F', 'I', 'H', '4', + 'F', 'T', 'H' | 0x80, '(', '5', ')', '=', ' ', + 'F', 'A', 'Y', '4', 'V' | 0x80, ' ', '(', '6', + '4', ')', ' ', '=', 'S', 'I', 'H', '4', + 'K', 'S', 'T', 'I', 'Y', ' ', 'F', 'O', + 'H', 'R' | 0x80, '(', '6', ')', '=', ' ', 'S', + 'I', 'H', '4', 'K', 'S' | 0x80, '(', '7', ')', + '=', ' ', 'S', 'E', 'H', '4', 'V', 'U', + 'N' | 0x80, ' ', '(', '8', 'T', 'H', ')', '=', + 'E', 'Y', '4', 'T', 'H' | 0x80, '(', '8', ')', + '=', ' ', 'E', 'Y', '4', 'T' | 0x80, '(', '9', + ')', '=', ' ', 'N', 'A', 'Y', '4', 'N' | 0x80, + '(', ':', ')', '=', '.' | 0x80, '(', ';', ')', + '=', '.' | 0x80, '(', '<', ')', '=', ' ', 'L', + 'E', 'H', '4', 'S', ' ', 'D', 'H', 'A', + 'E', 'N' | 0x80, '(', '=', ')', '=', ' ', 'I', + 'Y', '4', 'K', 'W', 'U', 'L', 'Z' | 0x80, '(', + '>', ')', '=', ' ', 'G', 'R', 'E', 'Y', + '4', 'T', 'E', 'R', ' ', 'D', 'H', 'A', + 'E', 'N' | 0x80, '(', '?', ')', '=', '?' | 0x80, '(', + '@', ')', '=', ' ', 'A', 'E', '6', 'T' | 0x80, + '(', '^', ')', '=', ' ', 'K', 'A', 'E', + '4', 'R', 'I', 'X', 'T' | 0x80, ']', 'A' | 0x80}; + +//26 items. From 'A' to 'Z' +// positions for mem62 and mem63 for each character +const unsigned char tab37489[] = {0, 149, 247, 162, 57, 197, 6, 126, 199, 38, 55, 78, 145, + 241, 85, 161, 254, 36, 69, 45, 167, 54, 83, 46, 71, 218}; + +const unsigned char tab37515[] = {125, 126, 126, 127, 128, 129, 130, 130, 130, 132, 132, 132, 132, + 132, 133, 135, 135, 136, 136, 137, 138, 139, 139, 140, 140, 140}; + +void STM32SAM::Output8BitAry(int index, unsigned char ary[5]) { + int k; + + uint32_t bufferposOld = bufferpos; + + bufferpos += timetable[oldtimetableindex][index]; + oldtimetableindex = index; + + int sample_uS = bufferpos - bufferposOld; + + uint32_t f = 0; + + // write a little bit in advance + for(k = 0; k < 5; k++) { + // buffer[bufferpos / 50 + k] = ary[k]; + + // f = micros() + sample_uS / (_STM32SAM_SPEED + 1); + // while(micros() < f) { + // }; + f = sample_uS / (_STM32SAM_SPEED + 1); + furi_delay_us(f); + SetAUDIO(ary[k]); + // delayMicroseconds(sample_uS / 5 ); + } + + // SetAUDIO(ary[0]); +} + +void STM32SAM::Output8Bit(int index, unsigned char A) { + unsigned char ary[5] = {A, A, A, A, A}; + Output8BitAry(index, ary); +} + +//written by me because of different table positions. +// mem[47] = ... +// 168=pitches +// 169=frequency1 +// 170=frequency2 +// 171=frequency3 +// 172=amplitude1 +// 173=amplitude2 +// 174=amplitude3 +unsigned char STM32SAM::Read(unsigned char p, unsigned char Y) { + switch(p) { + case 168: + return pitches[Y]; + case 169: + return frequency1[Y]; + case 170: + return frequency2[Y]; + case 171: + return frequency3[Y]; + case 172: + return amplitude1[Y]; + case 173: + return amplitude2[Y]; + case 174: + return amplitude3[Y]; + } + // Serial1.println("Error reading to tables"); + return 0; +} + +void STM32SAM::Write(unsigned char p, unsigned char Y, unsigned char value) { + switch(p) { + case 168: + pitches[Y] = value; + return; + case 169: + frequency1[Y] = value; + return; + case 170: + frequency2[Y] = value; + return; + case 171: + frequency3[Y] = value; + return; + case 172: + amplitude1[Y] = value; + return; + case 173: + amplitude2[Y] = value; + return; + case 174: + amplitude3[Y] = value; + return; + } + //Serial1.println("Error writing to tables\n"); +} + +// ------------------------------------------------------------------------- +//Code48227 +// Render a sampled sound from the sampleTable. +// +// Phoneme Sample Start Sample End +// 32: S* 15 255 +// 33: SH 257 511 +// 34: F* 559 767 +// 35: TH 583 767 +// 36: /H 903 1023 +// 37: /X 1135 1279 +// 38: Z* 84 119 +// 39: ZH 340 375 +// 40: V* 596 639 +// 41: DH 596 631 +// +// 42: CH +// 43: ** 399 511 +// +// 44: J* +// 45: ** 257 276 +// 46: ** +// +// 66: P* +// 67: ** 743 767 +// 68: ** +// +// 69: T* +// 70: ** 231 255 +// 71: ** +// +// The SampledPhonemesTable[] holds flags indicating if a phoneme is +// voiced or not. If the upper 5 bits are zero, the sample is voiced. +// +// Samples in the sampleTable are compressed, with bits being converted to +// bytes from high bit to low, as follows: +// +// unvoiced 0 bit -> X +// unvoiced 1 bit -> 5 +// +// voiced 0 bit -> 6 +// voiced 1 bit -> 24 +// +// Where X is a value from the table: +// +// { 0x18, 0x1A, 0x17, 0x17, 0x17 }; +// +// The index into this table is determined by masking off the lower +// 3 bits from the SampledPhonemesTable: +// +// index = (SampledPhonemesTable[i] & 7) - 1; +// +// For voices samples, samples are interleaved between voiced output. + +// Code48227() +void STM32SAM::RenderSample(unsigned char* mem66) { + int tempA; + // current phoneme's index + mem49 = Y; + + // mask low three bits and subtract 1 get value to + // convert 0 bits on unvoiced samples. + A = mem39 & 7; + X = A - 1; + + // store the result + mem56 = X; + + // determine which offset to use from table { 0x18, 0x1A, 0x17, 0x17, 0x17 } + // T, S, Z 0 0x18 + // CH, J, SH, ZH 1 0x1A + // P, F*, V, TH, DH 2 0x17 + // /H 3 0x17 + // /X 4 0x17 + + // get value from the table + mem53 = tab48426[X]; + mem47 = X; //46016+mem[56]*256 + + // voiced sample? + A = mem39 & 248; + if(A == 0) { + // voiced phoneme: Z*, ZH, V*, DH + Y = mem49; + A = pitches[mem49] >> 4; + + // jump to voiced portion + goto pos48315; + } + + Y = A ^ 255; +pos48274: + + // step through the 8 bits in the sample + mem56 = 8; + + // get the next sample from the table + // mem47*256 = offset to start of samples + A = sampleTable[mem47 * 256 + Y]; +pos48280: + + // left shift to get the high bit + tempA = A; + A = A << 1; + //48281: BCC 48290 + + // bit not set? + if((tempA & 128) == 0) { + // convert the bit to value from table + X = mem53; + //mem[54296] = X; + // output the byte + Output8Bit(1, (X & 0x0f) * 16); + // if X != 0, exit loop + if(X != 0) goto pos48296; + } + + // output a 5 for the on bit + Output8Bit(2, 5 * 16); + + //48295: NOP +pos48296: + + X = 0; + + // decrement counter + mem56--; + + // if not done, jump to top of loop + if(mem56 != 0) goto pos48280; + + // increment position + Y++; + if(Y != 0) goto pos48274; + + // restore values and return + mem44 = 1; + Y = mem49; + return; + + unsigned char phase1; + +pos48315: + // handle voiced samples here + + // number of samples? + phase1 = A ^ 255; + + Y = *mem66; + do { + //pos48321: + + // shift through all 8 bits + mem56 = 8; + //A = Read(mem47, Y); + + // fetch value from table + A = sampleTable[mem47 * 256 + Y]; + + // loop 8 times + //pos48327: + do { + //48327: ASL A + //48328: BCC 48337 + + // left shift and check high bit + tempA = A; + A = A << 1; + if((tempA & 128) != 0) { + // if bit set, output 26 + X = 26; + Output8Bit(3, (X & 0xf) * 16); + } else { + //timetable 4 + // bit is not set, output a 6 + X = 6; + Output8Bit(4, (X & 0xf) * 16); + } + + mem56--; + } while(mem56 != 0); + + // move ahead in the table + Y++; + + // continue until counter done + phase1++; + + } while(phase1 != 0); + // if (phase1 != 0) goto pos48321; + + // restore values and return + A = 1; + mem44 = 1; + *mem66 = Y; + Y = mem49; + return; +} + +// RENDER THE PHONEMES IN THE LIST +// +// The phoneme list is converted into sound through the steps: +// +// 1. Copy each phoneme number of times into the frames list, +// where each frame represents 10 milliseconds of sound. +// +// 2. Determine the transitions lengths between phonemes, and linearly +// interpolate the values across the frames. +// +// 3. Offset the pitches by the fundamental frequency. +// +// 4. Render the each frame. + +//void Code47574() +void STM32SAM::Render() { + unsigned char phase1 = 0; //mem43 + unsigned char phase2 = 0; + unsigned char phase3 = 0; + unsigned char mem66 = 0; + unsigned char mem38 = 0; + unsigned char mem40 = 0; + unsigned char speedcounter = 0; //mem45 + unsigned char mem48 = 0; + int i; + if(phonemeIndexOutput[0] == 255) return; //exit if no data + + A = 0; + X = 0; + mem44 = 0; + + // CREATE FRAMES + // + // The length parameter in the list corresponds to the number of frames + // to expand the phoneme to. Each frame represents 10 milliseconds of time. + // So a phoneme with a length of 7 = 7 frames = 70 milliseconds duration. + // + // The parameters are copied from the phoneme to the frame verbatim. + + // pos47587: + do { + // get the index + Y = mem44; + // get the phoneme at the index + A = phonemeIndexOutput[mem44]; + mem56 = A; + + // if terminal phoneme, exit the loop + if(A == 255) break; + + // period phoneme *. + if(A == 1) { + // add rising inflection + A = 1; + mem48 = 1; + //goto pos48376; + AddInflection(mem48, phase1); + } + /* + if (A == 2) goto pos48372; + */ + + // question mark phoneme? + if(A == 2) { + // create falling inflection + mem48 = 255; + AddInflection(mem48, phase1); + } + // pos47615: + + // get the stress amount (more stress = higher pitch) + phase1 = tab47492[stressOutput[Y] + 1]; + + // get number of frames to write + phase2 = phonemeLengthOutput[Y]; + Y = mem56; + + // copy from the source to the frames list + do { + frequency1[X] = freq1data[Y]; // F1 frequency + frequency2[X] = freq2data[Y]; // F2 frequency + frequency3[X] = freq3data[Y]; // F3 frequency + amplitude1[X] = ampl1data[Y]; // F1 amplitude + amplitude2[X] = ampl2data[Y]; // F2 amplitude + amplitude3[X] = ampl3data[Y]; // F3 amplitude + sampledConsonantFlag[X] = + sampledConsonantFlags[Y]; // phoneme data for sampled consonants + pitches[X] = pitch + phase1; // pitch + X++; + phase2--; + } while(phase2 != 0); + mem44++; + } while(mem44 != 0); + // ------------------- + //pos47694: + + // CREATE TRANSITIONS + // + // Linear transitions are now created to smoothly connect the + // end of one sustained portion of a phoneme to the following + // phoneme. + // + // To do this, three tables are used: + // + // Table Purpose + // ========= ================================================== + // blendRank Determines which phoneme's blend values are used. + // + // blendOut The number of frames at the end of the phoneme that + // will be used to transition to the following phoneme. + // + // blendIn The number of frames of the following phoneme that + // will be used to transition into that phoneme. + // + // In creating a transition between two phonemes, the phoneme + // with the HIGHEST rank is used. Phonemes are ranked on how much + // their identity is based on their transitions. For example, + // vowels are and diphthongs are identified by their sustained portion, + // rather than the transitions, so they are given low values. In contrast, + // stop consonants (P, B, T, K) and glides (Y, L) are almost entirely + // defined by their transitions, and are given high rank values. + // + // Here are the rankings used by SAM: + // + // Rank Type Phonemes + // 2 All vowels IY, IH, etc. + // 5 Diphthong endings YX, WX, ER + // 8 Terminal liquid consonants LX, WX, YX, N, NX + // 9 Liquid consonants L, RX, W + // 10 Glide R, OH + // 11 Glide WH + // 18 Voiceless fricatives S, SH, F, TH + // 20 Voiced fricatives Z, ZH, V, DH + // 23 Plosives, stop consonants P, T, K, KX, DX, CH + // 26 Stop consonants J, GX, B, D, G + // 27-29 Stop consonants (internal) ** + // 30 Unvoiced consonants /H, /X and Q* + // 160 Nasal M + // + // To determine how many frames to use, the two phonemes are + // compared using the blendRank[] table. The phoneme with the + // higher rank is selected. In case of a tie, a blend of each is used: + // + // if blendRank[phoneme1] == blendRank[phomneme2] + // // use lengths from each phoneme + // outBlendFrames = outBlend[phoneme1] + // inBlendFrames = outBlend[phoneme2] + // else if blendRank[phoneme1] > blendRank[phoneme2] + // // use lengths from first phoneme + // outBlendFrames = outBlendLength[phoneme1] + // inBlendFrames = inBlendLength[phoneme1] + // else + // // use lengths from the second phoneme + // // note that in and out are SWAPPED! + // outBlendFrames = inBlendLength[phoneme2] + // inBlendFrames = outBlendLength[phoneme2] + // + // Blend lengths can't be less than zero. + // + // Transitions are assumed to be symetrical, so if the transition + // values for the second phoneme are used, the inBlendLength and + // outBlendLength values are SWAPPED. + // + // For most of the parameters, SAM interpolates over the range of the last + // outBlendFrames-1 and the first inBlendFrames. + // + // The exception to this is the Pitch[] parameter, which is interpolates the + // pitch from the CENTER of the current phoneme to the CENTER of the next + // phoneme. + // + // Here are two examples. First, For example, consider the word "SUN" (S AH N) + // + // Phoneme Duration BlendWeight OutBlendFrames InBlendFrames + // S 2 18 1 3 + // AH 8 2 4 4 + // N 7 8 1 2 + // + // The formant transitions for the output frames are calculated as follows: + // + // flags ampl1 freq1 ampl2 freq2 ampl3 freq3 pitch + // ------------------------------------------------ + // S + // 241 0 6 0 73 0 99 61 Use S (weight 18) for transition instead of AH (weight 2) + // 241 0 6 0 73 0 99 61 <-- (OutBlendFrames-1) = (1-1) = 0 frames + // AH + // 0 2 10 2 66 0 96 59 * <-- InBlendFrames = 3 frames + // 0 4 14 3 59 0 93 57 * + // 0 8 18 5 52 0 90 55 * + // 0 15 22 9 44 1 87 53 + // 0 15 22 9 44 1 87 53 + // 0 15 22 9 44 1 87 53 Use N (weight 8) for transition instead of AH (weight 2). + // 0 15 22 9 44 1 87 53 Since N is second phoneme, reverse the IN and OUT values. + // 0 11 17 8 47 1 98 56 * <-- (InBlendFrames-1) = (2-1) = 1 frames + // N + // 0 8 12 6 50 1 109 58 * <-- OutBlendFrames = 1 + // 0 5 6 5 54 0 121 61 + // 0 5 6 5 54 0 121 61 + // 0 5 6 5 54 0 121 61 + // 0 5 6 5 54 0 121 61 + // 0 5 6 5 54 0 121 61 + // 0 5 6 5 54 0 121 61 + // + // Now, consider the reverse "NUS" (N AH S): + // + // flags ampl1 freq1 ampl2 freq2 ampl3 freq3 pitch + // ------------------------------------------------ + // N + // 0 5 6 5 54 0 121 61 + // 0 5 6 5 54 0 121 61 + // 0 5 6 5 54 0 121 61 + // 0 5 6 5 54 0 121 61 + // 0 5 6 5 54 0 121 61 + // 0 5 6 5 54 0 121 61 Use N (weight 8) for transition instead of AH (weight 2) + // 0 5 6 5 54 0 121 61 <-- (OutBlendFrames-1) = (1-1) = 0 frames + // AH + // 0 8 11 6 51 0 110 59 * <-- InBlendFrames = 2 + // 0 11 16 8 48 0 99 56 * + // 0 15 22 9 44 1 87 53 Use S (weight 18) for transition instead of AH (weight 2) + // 0 15 22 9 44 1 87 53 Since S is second phoneme, reverse the IN and OUT values. + // 0 9 18 5 51 1 90 55 * <-- (InBlendFrames-1) = (3-1) = 2 + // 0 4 14 3 58 1 93 57 * + // S + // 241 2 10 2 65 1 96 59 * <-- OutBlendFrames = 1 + // 241 0 6 0 73 0 99 61 + + A = 0; + mem44 = 0; + mem49 = 0; // mem49 starts at as 0 + X = 0; + while(1) //while No. 1 + { + // get the current and following phoneme + Y = phonemeIndexOutput[X]; + A = phonemeIndexOutput[X + 1]; + X++; + + // exit loop at end token + if(A == 255) break; //goto pos47970; + + // get the ranking of each phoneme + X = A; + mem56 = blendRank[A]; + A = blendRank[Y]; + + // compare the rank - lower rank value is stronger + if(A == mem56) { + // same rank, so use out blend lengths from each phoneme + phase1 = outBlendLength[Y]; + phase2 = outBlendLength[X]; + } else if(A < mem56) { + // first phoneme is stronger, so us it's blend lengths + phase1 = inBlendLength[X]; + phase2 = outBlendLength[X]; + } else { + // second phoneme is stronger, so use it's blend lengths + // note the out/in are swapped + phase1 = outBlendLength[Y]; + phase2 = inBlendLength[Y]; + } + + Y = mem44; + A = mem49 + phonemeLengthOutput[mem44]; // A is mem49 + length + mem49 = A; // mem49 now holds length + position + A = A + phase2; //Maybe Problem because of carry flag + + //47776: ADC 42 + speedcounter = A; + mem47 = 168; + phase3 = mem49 - phase1; // what is mem49 + A = phase1 + phase2; // total transition? + mem38 = A; + + X = A; + X -= 2; + if((X & 128) == 0) + do //while No. 2 + { + //pos47810: + + // mem47 is used to index the tables: + // 168 pitches[] + // 169 frequency1 + // 170 frequency2 + // 171 frequency3 + // 172 amplitude1 + // 173 amplitude2 + // 174 amplitude3 + + mem40 = mem38; + + if(mem47 == 168) // pitch + { + // unlike the other values, the pitches[] interpolates from + // the middle of the current phoneme to the middle of the + // next phoneme + + unsigned char mem36, mem37; + // half the width of the current phoneme + mem36 = phonemeLengthOutput[mem44] >> 1; + // half the width of the next phoneme + mem37 = phonemeLengthOutput[mem44 + 1] >> 1; + // sum the values + mem40 = mem36 + mem37; // length of both halves + mem37 += mem49; // center of next phoneme + mem36 = mem49 - mem36; // center index of current phoneme + A = Read( + mem47, mem37); // value at center of next phoneme - end interpolation value + //A = mem[address]; + + Y = mem36; // start index of interpolation + mem53 = A - Read(mem47, mem36); // value to center of current phoneme + } else { + // value to interpolate to + A = Read(mem47, speedcounter); + // position to start interpolation from + Y = phase3; + // value to interpolate from + mem53 = A - Read(mem47, phase3); + } + + //Code47503(mem40); + // ML : Code47503 is division with remainder, and mem50 gets the sign + + // calculate change per frame + signed char m53 = (signed char)mem53; + mem50 = mem53 & 128; + unsigned char m53abs = abs(m53); + mem51 = m53abs % mem40; //abs((char)m53) % mem40; + mem53 = (unsigned char)((signed char)(m53) / mem40); + + // interpolation range + X = mem40; // number of frames to interpolate over + Y = phase3; // starting frame + + // linearly interpolate values + + mem56 = 0; + //47907: CLC + //pos47908: + while(1) //while No. 3 + { + A = Read(mem47, Y) + mem53; //carry alway cleared + + mem48 = A; + Y++; + X--; + if(X == 0) break; + + mem56 += mem51; + if(mem56 >= mem40) //??? + { + mem56 -= mem40; //carry? is set + //if ((mem56 & 128)==0) + if((mem50 & 128) == 0) { + //47935: BIT 50 + //47937: BMI 47943 + if(mem48 != 0) mem48++; + } else + mem48--; + } + //pos47945: + Write(mem47, Y, mem48); + } //while No. 3 + + //pos47952: + mem47++; + //if (mem47 != 175) goto pos47810; + } while(mem47 != 175); //while No. 2 + //pos47963: + mem44++; + X = mem44; + } //while No. 1 + + //goto pos47701; + //pos47970: + + // add the length of this phoneme + mem48 = mem49 + phonemeLengthOutput[mem44]; + + // ASSIGN PITCH CONTOUR + // + // This subtracts the F1 frequency from the pitch to create a + // pitch contour. Without this, the output would be at a single + // pitch level (monotone). + + // don't adjust pitch if in sing mode + if(!singmode) { + // iterate through the buffer + for(i = 0; i < 256; i++) { + // subtract half the frequency of the formant 1. + // this adds variety to the voice + pitches[i] -= (frequency1[i] >> 1); + } + } + + phase1 = 0; + phase2 = 0; + phase3 = 0; + mem49 = 0; + speedcounter = 72; //sam standard speed + + // RESCALE AMPLITUDE + // + // Rescale volume from a linear scale to decibels. + // + + //amplitude rescaling + for(i = 255; i >= 0; i--) { + amplitude1[i] = amplitudeRescale[amplitude1[i]]; + amplitude2[i] = amplitudeRescale[amplitude2[i]]; + amplitude3[i] = amplitudeRescale[amplitude3[i]]; + } + + Y = 0; + A = pitches[0]; + mem44 = A; + X = A; + mem38 = A - (A >> 2); // 3/4*A ??? + + // PROCESS THE FRAMES + // + // In traditional vocal synthesis, the glottal pulse drives filters, which + // are attenuated to the frequencies of the formants. + // + // SAM generates these formants directly with sin and rectangular waves. + // To simulate them being driven by the glottal pulse, the waveforms are + // reset at the beginning of each glottal pulse. + + //finally the loop for sound output + //pos48078: + while(1) { + // get the sampled information on the phoneme + A = sampledConsonantFlag[Y]; + mem39 = A; + + // unvoiced sampled phoneme? + A = A & 248; + if(A != 0) { + // render the sample for the phoneme + RenderSample(&mem66); + + // skip ahead two in the phoneme buffer + Y += 2; + mem48 -= 2; + } else { + // simulate the glottal pulse and formants + unsigned char ary[5]; + unsigned int p1 = + phase1 * 256; // Fixed point integers because we need to divide later on + unsigned int p2 = phase2 * 256; + unsigned int p3 = phase3 * 256; + int k; + for(k = 0; k < 5; k++) { + signed char sp1 = (signed char)sinus[0xff & (p1 >> 8)]; + signed char sp2 = (signed char)sinus[0xff & (p2 >> 8)]; + signed char rp3 = (signed char)rectangle[0xff & (p3 >> 8)]; + signed int sin1 = sp1 * ((unsigned char)amplitude1[Y] & 0x0f); + signed int sin2 = sp2 * ((unsigned char)amplitude2[Y] & 0x0f); + signed int rect = rp3 * ((unsigned char)amplitude3[Y] & 0x0f); + signed int mux = sin1 + sin2 + rect; + mux /= 32; + mux += 128; // Go from signed to unsigned amplitude + ary[k] = mux; + p1 += frequency1[Y] * 256 / 4; // Compromise, this becomes a shift and works well + p2 += frequency2[Y] * 256 / 4; + p3 += frequency3[Y] * 256 / 4; + } + // output the accumulated value + Output8BitAry(0, ary); + speedcounter--; + if(speedcounter != 0) goto pos48155; + Y++; //go to next amplitude + + // decrement the frame count + mem48--; + } + + // if the frame count is zero, exit the loop + if(mem48 == 0) return; + speedcounter = speed; + pos48155: + + // decrement the remaining length of the glottal pulse + mem44--; + + // finished with a glottal pulse? + if(mem44 == 0) { + pos48159: + // fetch the next glottal pulse length + A = pitches[Y]; + mem44 = A; + A = A - (A >> 2); + mem38 = A; + + // reset the formant wave generators to keep them in + // sync with the glottal pulse + phase1 = 0; + phase2 = 0; + phase3 = 0; + continue; + } + + // decrement the count + mem38--; + + // is the count non-zero and the sampled flag is zero? + if((mem38 != 0) || (mem39 == 0)) { + // reset the phase of the formants to match the pulse + phase1 += frequency1[Y]; + phase2 += frequency2[Y]; + phase3 += frequency3[Y]; + continue; + } + + // voiced sampled phonemes interleave the sample with the + // glottal pulse. The sample flag is non-zero, so render + // the sample for the phoneme. + RenderSample(&mem66); + goto pos48159; + } //while + + // The following code is never reached. It's left over from when + // the voiced sample code was part of this loop, instead of part + // of RenderSample(); + + //pos48315: + int tempA; + phase1 = A ^ 255; + Y = mem66; + do { + //pos48321: + + mem56 = 8; + A = Read(mem47, Y); + + //pos48327: + do { + //48327: ASL A + //48328: BCC 48337 + tempA = A; + A = A << 1; + if((tempA & 128) != 0) { + X = 26; + // mem[54296] = X; + bufferpos += 150; + // + // + // buffer[bufferpos / 50] = (X & 15) * 16; + // + // + + } else { + //mem[54296] = 6; + X = 6; + bufferpos += 150; + // + // buffer[bufferpos / 50] = (X & 15) * 16; + // + // + } + + for(X = wait2; X > 0; X--) + ; //wait + mem56--; + } while(mem56 != 0); + + Y++; + phase1++; + + } while(phase1 != 0); + // if (phase1 != 0) goto pos48321; + A = 1; + mem44 = 1; + mem66 = Y; + Y = mem49; + return; +} + +// Create a rising or falling inflection 30 frames prior to +// index X. A rising inflection is used for questions, and +// a falling inflection is used for statements. + +void STM32SAM::AddInflection(unsigned char mem48, unsigned char phase1) { + //pos48372: + // mem48 = 255; + //pos48376: + + // store the location of the punctuation + mem49 = X; + A = X; + int Atemp = A; + + // backup 30 frames + A = A - 30; + // if index is before buffer, point to start of buffer + if(Atemp <= 30) A = 0; + X = A; + + // FIXME: Explain this fix better, it's not obvious + // ML : A =, fixes a problem with invalid pitch with '.' + while((A = pitches[X]) == 127) X++; + +pos48398: + //48398: CLC + //48399: ADC 48 + + // add the inflection direction + A += mem48; + phase1 = A; + + // set the inflection + pitches[X] = A; +pos48406: + + // increment the position + X++; + + // exit if the punctuation has been reached + if(X == mem49) return; //goto pos47615; + if(pitches[X] == 255) goto pos48406; + A = phase1; + goto pos48398; +} + +/* + SAM's voice can be altered by changing the frequencies of the + mouth formant (F1) and the throat formant (F2). Only the voiced + phonemes (5-29 and 48-53) are altered. +*/ +void STM32SAM::SetMouthThroat() { + unsigned char initialFrequency; + unsigned char newFrequency = 0; + //unsigned char mouth; //mem38880 + //unsigned char throat; //mem38881 + + // mouth formants (F1) 5..29 + unsigned char mouthFormants5_29[30] = {0, 0, 0, 0, 0, 10, 14, 19, 24, 27, + 23, 21, 16, 20, 14, 18, 14, 18, 18, 16, + 13, 15, 11, 18, 14, 11, 9, 6, 6, 6}; + + // throat formants (F2) 5..29 + unsigned char throatFormants5_29[30] = {255, 255, 255, 255, 255, 84, 73, 67, 63, 40, + 44, 31, 37, 45, 73, 49, 36, 30, 51, 37, + 29, 69, 24, 50, 30, 24, 83, 46, 54, 86}; + + // there must be no zeros in this 2 tables + // formant 1 frequencies (mouth) 48..53 + unsigned char mouthFormants48_53[6] = {19, 27, 21, 27, 18, 13}; + + // formant 2 frequencies (throat) 48..53 + unsigned char throatFormants48_53[6] = {72, 39, 31, 43, 30, 34}; + + unsigned char pos = 5; //mem39216 + //pos38942: + // recalculate formant frequencies 5..29 for the mouth (F1) and throat (F2) + while(pos != 30) { + // recalculate mouth frequency + initialFrequency = mouthFormants5_29[pos]; + if(initialFrequency != 0) newFrequency = trans(mouth, initialFrequency); + freq1data[pos] = newFrequency; + + // recalculate throat frequency + initialFrequency = throatFormants5_29[pos]; + if(initialFrequency != 0) newFrequency = trans(throat, initialFrequency); + freq2data[pos] = newFrequency; + pos++; + } + + //pos39059: + // recalculate formant frequencies 48..53 + pos = 48; + Y = 0; + while(pos != 54) { + // recalculate F1 (mouth formant) + initialFrequency = mouthFormants48_53[Y]; + newFrequency = trans(mouth, initialFrequency); + freq1data[pos] = newFrequency; + + // recalculate F2 (throat formant) + initialFrequency = throatFormants48_53[Y]; + newFrequency = trans(throat, initialFrequency); + freq2data[pos] = newFrequency; + Y++; + pos++; + } +} + +//return = (mem39212*mem39213) >> 1 +unsigned char STM32SAM::trans(unsigned char mem39212, unsigned char mem39213) { + //pos39008: + unsigned char carry; + int temp; + unsigned char mem39214, mem39215; + A = 0; + mem39215 = 0; + mem39214 = 0; + X = 8; + do { + carry = mem39212 & 1; + mem39212 = mem39212 >> 1; + if(carry != 0) { + /* + 39018: LSR 39212 + 39021: BCC 39033 + */ + carry = 0; + A = mem39215; + temp = (int)A + (int)mem39213; + A = A + mem39213; + if(temp > 255) carry = 1; + mem39215 = A; + } + temp = mem39215 & 1; + mem39215 = (mem39215 >> 1) | (carry ? 128 : 0); + carry = temp; + //39033: ROR 39215 + X--; + } while(X != 0); + temp = mem39214 & 128; + mem39214 = (mem39214 << 1) | (carry ? 1 : 0); + carry = temp; + temp = mem39215 & 128; + mem39215 = (mem39215 << 1) | (carry ? 1 : 0); + carry = temp; + + return mem39215; +} + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// Sam +// +//////////////////////////////////////////////////////////////////////////////////////////// + +//char input[]={"/HAALAOAO MAYN NAAMAEAE IHSTT SAEBAASTTIHAAN \x9b\x9b\0"}; +//unsigned char input[]={"/HAALAOAO \x9b\0"}; +//unsigned char input[]={"AA \x9b\0"}; +//unsigned char input[] = {"GUH5DEHN TAEG\x9b\0"}; + +//unsigned char input[]={"AY5 AEM EY TAO4LXKIHNX KAX4MPYUX4TAH. GOW4 AH/HEH3D PAHNK.MEYK MAY8 DEY.\x9b\0"}; +//unsigned char input[]={"/HEH3LOW2, /HAW AH YUX2 TUXDEY. AY /HOH3P YUX AH FIYLIHNX OW4 KEY.\x9b\0"}; +//unsigned char input[]={"/HEY2, DHIHS IH3Z GREY2T. /HAH /HAH /HAH.AYL BIY5 BAEK.\x9b\0"}; +//unsigned char input[]={"/HAH /HAH /HAH \x9b\0"}; +//unsigned char input[]={"/HAH /HAH /HAH.\x9b\0"}; +//unsigned char input[]={".TUW BIY5Y3,, OHR NAA3T - TUW BIY5IYIY., DHAE4T IHZ DHAH KWEH4SCHAHN.\x9b\0"}; +//unsigned char input[]={"/HEY2, DHIHS \x9b\0"}; + +//unsigned char input[]={" IYIHEHAEAAAHAOOHUHUXERAXIX \x9b\0"}; +//unsigned char input[]={" RLWWYMNNXBDGJZZHVDH \x9b\0"}; +//unsigned char input[]={" SSHFTHPTKCH/H \x9b\0"}; + +//unsigned char input[]={" EYAYOYAWOWUW ULUMUNQ YXWXRXLX/XDX\x9b\0"}; + +void STM32SAM::SetInput(char* _input) { + int i, l; + l = strlen(_input); + if(l > 254) l = 254; + for(i = 0; i < l; i++) { + input[i] = _input[i]; + } + input[l] = 0; +} + +// 168=pitches +// 169=frequency1 +// 170=frequency2 +// 171=frequency3 +// 172=amplitude1 +// 173=amplitude2 +// 174=amplitude3 + +void STM32SAM::Init() { + bufferpos = 0; + int i; + SetMouthThroat(); + + bufferpos = 0; + // TODO, check for free the memory, 10 seconds of output should be more than enough + //buffer = malloc(22050*10); + + // buffer = (char*) calloc(1, sizeof(char)); + + /* + freq2data = &mem[45136]; + freq1data = &mem[45056]; + freq3data = &mem[45216]; + */ + //pitches = &mem[43008]; + /* + frequency1 = &mem[43264]; + frequency2 = &mem[43520]; + frequency3 = &mem[43776]; + */ + /* + amplitude1 = &mem[44032]; + amplitude2 = &mem[44288]; + amplitude3 = &mem[44544]; + */ + //phoneme = &mem[39904]; + /* + ampl1data = &mem[45296]; + ampl2data = &mem[45376]; + ampl3data = &mem[45456]; + */ + + for(i = 0; i < 256; i++) { + stress[i] = 0; + phonemeLength[i] = 0; + } + + for(i = 0; i < 60; i++) { + phonemeIndexOutput[i] = 0; + stressOutput[i] = 0; + phonemeLengthOutput[i] = 0; + } + phonemeindex[255] = + 255; //to prevent buffer overflow // ML : changed from 32 to 255 to stop freezing with long inputs +} + +//int Code39771() +int STM32SAM::SAMMain() { + Init(); + phonemeindex[255] = 32; //to prevent buffer overflow + + if(!Parser1()) { + return 0; + } + + Parser2(); + CopyStress(); + SetPhonemeLength(); + AdjustLengths(); + Code41240(); + do { + A = phonemeindex[X]; + if(A > 80) { + phonemeindex[X] = 255; + break; // error: delete all behind it + } + X++; + } while(X != 0); + + //pos39848: + InsertBreath(); + + //mem[40158] = 255; + + PrepareOutput(); + + return 1; +} + +//void Code48547() +void STM32SAM::PrepareOutput() { + A = 0; + X = 0; + Y = 0; + + //pos48551: + while(1) { + A = phonemeindex[X]; + if(A == 255) { + A = 255; + phonemeIndexOutput[Y] = 255; + Render(); + return; + } + if(A == 254) { + X++; + int temp = X; + //mem[48546] = X; + phonemeIndexOutput[Y] = 255; + Render(); + //X = mem[48546]; + X = temp; + Y = 0; + continue; + } + + if(A == 0) { + X++; + continue; + } + + phonemeIndexOutput[Y] = A; + phonemeLengthOutput[Y] = phonemeLength[X]; + stressOutput[Y] = stress[X]; + X++; + Y++; + } +} + +//void Code41014() +void STM32SAM::Insert( + unsigned char position /*var57*/, + unsigned char mem60, + unsigned char mem59, + unsigned char mem58) { + int i; + for(i = 253; i >= position; i--) // ML : always keep last safe-guarding 255 + { + phonemeindex[i + 1] = phonemeindex[i]; + phonemeLength[i + 1] = phonemeLength[i]; + stress[i + 1] = stress[i]; + } + + phonemeindex[position] = mem60; + phonemeLength[position] = mem59; + stress[position] = mem58; + return; +} + +//void Code48431() +void STM32SAM::InsertBreath() { + unsigned char mem54; + unsigned char mem55; + unsigned char index; //variable Y + mem54 = 255; + X++; + mem55 = 0; + unsigned char mem66 = 0; + while(1) { + //pos48440: + X = mem66; + index = phonemeindex[X]; + if(index == 255) return; + mem55 += phonemeLength[X]; + + if(mem55 < 232) { + if(index != 254) // ML : Prevents an index out of bounds problem + { + A = flags2[index] & 1; + if(A != 0) { + X++; + mem55 = 0; + Insert(X, 254, mem59, 0); + mem66++; + mem66++; + continue; + } + } + if(index == 0) mem54 = X; + mem66++; + continue; + } + X = mem54; + phonemeindex[X] = 31; // 'Q*' glottal stop + phonemeLength[X] = 4; + stress[X] = 0; + X++; + mem55 = 0; + Insert(X, 254, mem59, 0); + X++; + mem66 = X; + } +} + +// Iterates through the phoneme buffer, copying the stress value from +// the following phoneme under the following circumstance: + +// 1. The current phoneme is voiced, excluding plosives and fricatives +// 2. The following phoneme is voiced, excluding plosives and fricatives, and +// 3. The following phoneme is stressed +// +// In those cases, the stress value+1 from the following phoneme is copied. +// +// For example, the word LOITER is represented as LOY5TER, with as stress +// of 5 on the diphtong OY. This routine will copy the stress value of 6 (5+1) +// to the L that precedes it. + +//void Code41883() +void STM32SAM::CopyStress() { + // loop thought all the phonemes to be output + unsigned char pos = 0; //mem66 + while(1) { + // get the phomene + Y = phonemeindex[pos]; + + // exit at end of buffer + if(Y == 255) return; + + // if CONSONANT_FLAG set, skip - only vowels get stress + if((flags[Y] & 64) == 0) { + pos++; + continue; + } + // get the next phoneme + Y = phonemeindex[pos + 1]; + if(Y == 255) //prevent buffer overflow + { + pos++; + continue; + } else + // if the following phoneme is a vowel, skip + if((flags[Y] & 128) == 0) { + pos++; + continue; + } + + // get the stress value at the next position + Y = stress[pos + 1]; + + // if next phoneme is not stressed, skip + if(Y == 0) { + pos++; + continue; + } + + // if next phoneme is not a VOWEL OR ER, skip + if((Y & 128) != 0) { + pos++; + continue; + } + + // copy stress from prior phoneme to this one + stress[pos] = Y + 1; + + // advance pointer + pos++; + } +} + +// The input[] buffer contains a string of phonemes and stress markers along +// the lines of: +// +// DHAX KAET IHZ AH5GLIY. <0x9B> +// +// The byte 0x9B marks the end of the buffer. Some phonemes are 2 bytes +// long, such as "DH" and "AX". Others are 1 byte long, such as "T" and "Z". +// There are also stress markers, such as "5" and ".". +// +// The first character of the phonemes are stored in the table signInputTable1[]. +// The second character of the phonemes are stored in the table signInputTable2[]. +// The stress characters are arranged in low to high stress order in stressInputTable[]. +// +// The following process is used to parse the input[] buffer: +// +// Repeat until the <0x9B> character is reached: +// +// First, a search is made for a 2 character match for phonemes that do not +// end with the '*' (wildcard) character. On a match, the index of the phoneme +// is added to phonemeIndex[] and the buffer position is advanced 2 bytes. +// +// If this fails, a search is made for a 1 character match against all +// phoneme names ending with a '*' (wildcard). If this succeeds, the +// phoneme is added to phonemeIndex[] and the buffer position is advanced +// 1 byte. +// +// If this fails, search for a 1 character match in the stressInputTable[]. +// If this succeeds, the stress value is placed in the last stress[] table +// at the same index of the last added phoneme, and the buffer position is +// advanced by 1 byte. +// +// If this fails, return a 0. +// +// On success: +// +// 1. phonemeIndex[] will contain the index of all the phonemes. +// 2. The last index in phonemeIndex[] will be 255. +// 3. stress[] will contain the stress value for each phoneme + +// input[] holds the string of phonemes, each two bytes wide +// signInputTable1[] holds the first character of each phoneme +// signInputTable2[] holds te second character of each phoneme +// phonemeIndex[] holds the indexes of the phonemes after parsing input[] +// +// The parser scans through the input[], finding the names of the phonemes +// by searching signInputTable1[] and signInputTable2[]. On a match, it +// copies the index of the phoneme into the phonemeIndexTable[]. +// +// The character <0x9B> marks the end of text in input[]. When it is reached, +// the index 255 is placed at the end of the phonemeIndexTable[], and the +// function returns with a 1 indicating success. +int STM32SAM::Parser1() { + int i; + unsigned char sign1; + unsigned char sign2; + unsigned char position = 0; + X = 0; + A = 0; + Y = 0; + + // CLEAR THE STRESS TABLE + for(i = 0; i < 256; i++) stress[i] = 0; + + // THIS CODE MATCHES THE PHONEME LETTERS TO THE TABLE + // pos41078: + while(1) { + // GET THE FIRST CHARACTER FROM THE PHONEME BUFFER + sign1 = input[X]; + // TEST FOR 155 (�) END OF LINE MARKER + if(sign1 == 155) { + // MARK ENDPOINT AND RETURN + phonemeindex[position] = 255; //mark endpoint + // REACHED END OF PHONEMES, SO EXIT + return 1; //all ok + } + + // GET THE NEXT CHARACTER FROM THE BUFFER + X++; + sign2 = input[X]; + + // NOW sign1 = FIRST CHARACTER OF PHONEME, AND sign2 = SECOND CHARACTER OF PHONEME + + // TRY TO MATCH PHONEMES ON TWO TWO-CHARACTER NAME + // IGNORE PHONEMES IN TABLE ENDING WITH WILDCARDS + + // SET INDEX TO 0 + Y = 0; + pos41095: + + // GET FIRST CHARACTER AT POSITION Y IN signInputTable + // --> should change name to PhonemeNameTable1 + A = signInputTable1[Y]; + + // FIRST CHARACTER MATCHES? + if(A == sign1) { + // GET THE CHARACTER FROM THE PhonemeSecondLetterTable + A = signInputTable2[Y]; + // NOT A SPECIAL AND MATCHES SECOND CHARACTER? + if((A != '*') && (A == sign2)) { + // STORE THE INDEX OF THE PHONEME INTO THE phomeneIndexTable + phonemeindex[position] = Y; + + // ADVANCE THE POINTER TO THE phonemeIndexTable + position++; + // ADVANCE THE POINTER TO THE phonemeInputBuffer + X++; + + // CONTINUE PARSING + continue; + } + } + + // NO MATCH, TRY TO MATCH ON FIRST CHARACTER TO WILDCARD NAMES (ENDING WITH '*') + + // ADVANCE TO THE NEXT POSITION + Y++; + // IF NOT END OF TABLE, CONTINUE + if(Y != 81) goto pos41095; + + // REACHED END OF TABLE WITHOUT AN EXACT (2 CHARACTER) MATCH. + // THIS TIME, SEARCH FOR A 1 CHARACTER MATCH AGAINST THE WILDCARDS + + // RESET THE INDEX TO POINT TO THE START OF THE PHONEME NAME TABLE + Y = 0; + pos41134: + // DOES THE PHONEME IN THE TABLE END WITH '*'? + if(signInputTable2[Y] == '*') { + // DOES THE FIRST CHARACTER MATCH THE FIRST LETTER OF THE PHONEME + if(signInputTable1[Y] == sign1) { + // SAVE THE POSITION AND MOVE AHEAD + phonemeindex[position] = Y; + + // ADVANCE THE POINTER + position++; + + // CONTINUE THROUGH THE LOOP + continue; + } + } + Y++; + if(Y != 81) goto pos41134; //81 is size of PHONEME NAME table + + // FAILED TO MATCH WITH A WILDCARD. ASSUME THIS IS A STRESS + // CHARACTER. SEARCH THROUGH THE STRESS TABLE + + // SET INDEX TO POSITION 8 (END OF STRESS TABLE) + Y = 8; + + // WALK BACK THROUGH TABLE LOOKING FOR A MATCH + while((sign1 != stressInputTable[Y]) && (Y > 0)) { + // DECREMENT INDEX + Y--; + } + + // REACHED THE END OF THE SEARCH WITHOUT BREAKING OUT OF LOOP? + if(Y == 0) { + //mem[39444] = X; + //41181: JSR 42043 //Error + // FAILED TO MATCH ANYTHING, RETURN 0 ON FAILURE + return 0; + } + // SET THE STRESS FOR THE PRIOR PHONEME + stress[position - 1] = Y; + } //while +} + +//change phonemelength depedendent on stress +//void Code41203() +void STM32SAM::SetPhonemeLength() { + unsigned char A; + int position = 0; + while(phonemeindex[position] != 255) { + A = stress[position]; + //41218: BMI 41229 + if((A == 0) || ((A & 128) != 0)) { + phonemeLength[position] = phonemeLengthTable[phonemeindex[position]]; + } else { + phonemeLength[position] = phonemeStressedLengthTable[phonemeindex[position]]; + } + position++; + } +} + +void STM32SAM::Code41240() { + unsigned char pos = 0; + + while(phonemeindex[pos] != 255) { + unsigned char index; //register AC + X = pos; + index = phonemeindex[pos]; + if((flags[index] & 2) == 0) { + pos++; + continue; + } else if((flags[index] & 1) == 0) { + Insert(pos + 1, index + 1, phonemeLengthTable[index + 1], stress[pos]); + Insert(pos + 2, index + 2, phonemeLengthTable[index + 2], stress[pos]); + pos += 3; + continue; + } + + do { + X++; + A = phonemeindex[X]; + } while(A == 0); + + if(A != 255) { + if((flags[A] & 8) != 0) { + pos++; + continue; + } + if((A == 36) || (A == 37)) { + pos++; // '/H' '/X' + continue; + } + } + + Insert(pos + 1, index + 1, phonemeLengthTable[index + 1], stress[pos]); + Insert(pos + 2, index + 2, phonemeLengthTable[index + 2], stress[pos]); + pos += 3; + }; +} + +// Rewrites the phonemes using the following rules: +// +// -> WX +// -> YX +// UL -> AX L +// UM -> AX M +// -> Q +// T R -> CH R +// D R -> J R +// R -> RX +// L -> LX +// G S -> G Z +// K -> KX +// G -> GX +// S P -> S B +// S T -> S D +// S K -> S G +// S KX -> S GX +// UW -> UX +// CH -> CH CH' (CH requires two phonemes to represent it) +// J -> J J' (J requires two phonemes to represent it) +// T -> DX +// D -> DX + +//void Code41397() +void STM32SAM::Parser2() { + unsigned char pos = 0; //mem66; + unsigned char mem58 = 0; + + // Loop through phonemes + while(1) { + // SET X TO THE CURRENT POSITION + X = pos; + // GET THE PHONEME AT THE CURRENT POSITION + A = phonemeindex[pos]; + + // Is phoneme pause? + if(A == 0) { + // Move ahead to the + pos++; + continue; + } + + // If end of phonemes flag reached, exit routine + if(A == 255) return; + + // Copy the current phoneme index to Y + Y = A; + + // RULE: + // -> WX + // -> YX + // Example: OIL, COW + + // Check for DIPHTONG + if((flags[A] & 16) == 0) goto pos41457; + + // Not a diphthong. Get the stress + mem58 = stress[pos]; + + // End in IY sound? + A = flags[Y] & 32; + + // If ends with IY, use YX, else use WX + if(A == 0) + A = 20; + else + A = 21; // 'WX' = 20 'YX' = 21 + //pos41443: + // Insert at WX or YX following, copying the stress + + Insert(pos + 1, A, mem59, mem58); + X = pos; + // Jump to ??? + goto pos41749; + + pos41457: + + // RULE: + // UL -> AX L + // Example: MEDDLE + + // Get phoneme + A = phonemeindex[X]; + // Skip this rule if phoneme is not UL + if(A != 78) goto pos41487; // 'UL' + A = 24; // 'L' //change 'UL' to 'AX L' + + pos41466: + // Get current phoneme stress + mem58 = stress[X]; + + // Change UL to AX + phonemeindex[X] = 13; // 'AX' + // Perform insert. Note code below may jump up here with different values + Insert(X + 1, A, mem59, mem58); + pos++; + // Move to next phoneme + continue; + + pos41487: + + // RULE: + // UM -> AX M + // Example: ASTRONOMY + + // Skip rule if phoneme != UM + if(A != 79) goto pos41495; // 'UM' + // Jump up to branch - replaces current phoneme with AX and continues + A = 27; // 'M' //change 'UM' to 'AX M' + + goto pos41466; + pos41495: + + // RULE: + // UN -> AX N + // Example: FUNCTION + + // Skip rule if phoneme != UN + if(A != 80) goto pos41503; // 'UN' + + // Jump up to branch - replaces current phoneme with AX and continues + A = 28; // 'N' //change UN to 'AX N' + + goto pos41466; + pos41503: + + // RULE: + // -> Q + // EXAMPLE: AWAY EIGHT + + Y = A; + // VOWEL set? + A = flags[A] & 128; + + // Skip if not a vowel + if(A != 0) { + // Get the stress + A = stress[X]; + + // If stressed... + if(A != 0) { + // Get the following phoneme + X++; + A = phonemeindex[X]; + // If following phoneme is a pause + + if(A == 0) { + // Get the phoneme following pause + X++; + Y = phonemeindex[X]; + + // Check for end of buffer flag + if(Y == 255) //buffer overflow + // ??? Not sure about these flags + A = 65 & 128; + else + // And VOWEL flag to current phoneme's flags + A = flags[Y] & 128; + + // If following phonemes is not a pause + if(A != 0) { + // If the following phoneme is not stressed + A = stress[X]; + if(A != 0) { + // 31 = 'Q' + Insert(X, 31, mem59, 0); + pos++; + continue; + } + } + } + } + } + + // RULES FOR PHONEMES BEFORE R + // T R -> CH R + // Example: TRACK + + // Get current position and phoneme + X = pos; + A = phonemeindex[pos]; + if(A != 23) goto pos41611; // 'R' + + // Look at prior phoneme + X--; + A = phonemeindex[pos - 1]; + //pos41567: + if(A == 69) // 'T' + { + phonemeindex[pos - 1] = 42; + goto pos41779; + } + + // RULES FOR PHONEMES BEFORE R + // D R -> J R + // Example: DRY + + // Prior phonemes D? + if(A == 57) // 'D' + { + // Change D to J + phonemeindex[pos - 1] = 44; + + goto pos41788; + } + + // RULES FOR PHONEMES BEFORE R + // R -> RX + // Example: ART + + // If vowel flag is set change R to RX + A = flags[A] & 128; + + if(A != 0) phonemeindex[pos] = 18; // 'RX' + + // continue to next phoneme + pos++; + continue; + + pos41611: + + // RULE: + // L -> LX + // Example: ALL + + // Is phoneme L? + if(A == 24) // 'L' + { + // If prior phoneme does not have VOWEL flag set, move to next phoneme + if((flags[phonemeindex[pos - 1]] & 128) == 0) { + pos++; + continue; + } + // Prior phoneme has VOWEL flag set, so change L to LX and move to next phoneme + + phonemeindex[X] = 19; // 'LX' + pos++; + continue; + } + + // RULE: + // G S -> G Z + // + // Can't get to fire - + // 1. The G -> GX rule intervenes + // 2. Reciter already replaces GS -> GZ + + // Is current phoneme S? + if(A == 32) // 'S' + { + // If prior phoneme is not G, move to next phoneme + if(phonemeindex[pos - 1] != 60) { + pos++; + continue; + } + // Replace S with Z and move on + + phonemeindex[pos] = 38; // 'Z' + pos++; + continue; + } + + // RULE: + // K -> KX + // Example: COW + + // Is current phoneme K? + if(A == 72) // 'K' + { + // Get next phoneme + Y = phonemeindex[pos + 1]; + // If at end, replace current phoneme with KX + if(Y == 255) + phonemeindex[pos] = 75; // ML : prevents an index out of bounds problem + else { + // VOWELS AND DIPHTONGS ENDING WITH IY SOUND flag set? + A = flags[Y] & 32; + + // Replace with KX + if(A == 0) phonemeindex[pos] = 75; // 'KX' + } + } else + + // RULE: + // G -> GX + // Example: GO + + // Is character a G? + if(A == 60) // 'G' + { + // Get the following character + unsigned char index = phonemeindex[pos + 1]; + + // At end of buffer? + if(index == 255) //prevent buffer overflow + { + pos++; + continue; + } else + // If diphtong ending with YX, move continue processing next phoneme + if((flags[index] & 32) != 0) { + pos++; + continue; + } + // replace G with GX and continue processing next phoneme + + phonemeindex[pos] = 63; // 'GX' + pos++; + continue; + } + + // RULE: + // S P -> S B + // S T -> S D + // S K -> S G + // S KX -> S GX + // Examples: SPY, STY, SKY, SCOWL + + Y = phonemeindex[pos]; + //pos41719: + // Replace with softer version? + A = flags[Y] & 1; + if(A == 0) goto pos41749; + A = phonemeindex[pos - 1]; + if(A != 32) // 'S' + { + A = Y; + goto pos41812; + } + // Replace with softer version + + phonemeindex[pos] = Y - 12; + pos++; + continue; + + pos41749: + + // RULE: + // UW -> UX + // + // Example: NEW, DEW, SUE, ZOO, THOO, TOO + + // UW -> UX + + A = phonemeindex[X]; + if(A == 53) // 'UW' + { + // ALVEOLAR flag set? + Y = phonemeindex[X - 1]; + A = flags2[Y] & 4; + // If not set, continue processing next phoneme + if(A == 0) { + pos++; + continue; + } + + phonemeindex[X] = 16; + pos++; + continue; + } + pos41779: + + // RULE: + // CH -> CH CH' (CH requires two phonemes to represent it) + // Example: CHEW + + if(A == 42) // 'CH' + { + // pos41783: + + Insert(X + 1, A + 1, mem59, stress[X]); + pos++; + continue; + } + + pos41788: + + // RULE: + // J -> J J' (J requires two phonemes to represent it) + // Example: JAY + + if(A == 44) // 'J' + { + Insert(X + 1, A + 1, mem59, stress[X]); + pos++; + continue; + } + + // Jump here to continue + pos41812: + + // RULE: Soften T following vowel + // NOTE: This rule fails for cases such as "ODD" + // T -> DX + // D -> DX + // Example: PARTY, TARDY + + // Past this point, only process if phoneme is T or D + + if(A != 69) // 'T' + if(A != 57) { + pos++; // 'D' + continue; + } + //pos41825: + + // If prior phoneme is not a vowel, continue processing phonemes + if((flags[phonemeindex[X - 1]] & 128) == 0) { + pos++; + continue; + } + + // Get next phoneme + X++; + A = phonemeindex[X]; + //pos41841 + // Is the next phoneme a pause? + if(A != 0) { + // If next phoneme is not a pause, continue processing phonemes + if((flags[A] & 128) == 0) { + pos++; + continue; + } + // If next phoneme is stressed, continue processing phonemes + // FIXME: How does a pause get stressed? + if(stress[X] != 0) { + pos++; + continue; + } + //pos41856: + // Set phonemes to DX + + phonemeindex[pos] = 30; // 'DX' + } else { + A = phonemeindex[X + 1]; + if(A == 255) //prevent buffer overflow + A = 65 & 128; + else + // Is next phoneme a vowel or ER? + A = flags[A] & 128; + + if(A != 0) phonemeindex[pos] = 30; // 'DX' + } + + pos++; + + } // while +} // parser 2 + +// Applies various rules that adjust the lengths of phonemes +// +// Lengthen or between and by 1.5 +// - decrease length by 1 +// - decrease vowel by 1/8th +// - increase vowel by 1/2 + 1 +// - set nasal = 5, consonant = 6 +// {optional silence} - shorten both to 1/2 + 1 +// - decrease by 2 + +//void Code48619() +void STM32SAM::AdjustLengths() { + // LENGTHEN VOWELS PRECEDING PUNCTUATION + // + // Search for punctuation. If found, back up to the first vowel, then + // process all phonemes between there and up to (but not including) the punctuation. + // If any phoneme is found that is a either a fricative or voiced, the duration is + // increased by (length * 1.5) + 1 + + // loop index + X = 0; + unsigned char index; + + // iterate through the phoneme list + unsigned char loopIndex = 0; + while(1) { + // get a phoneme + index = phonemeindex[X]; + + // exit loop if end on buffer token + if(index == 255) break; + + // not punctuation? + if((flags2[index] & 1) == 0) { + // skip + X++; + continue; + } + + // hold index + loopIndex = X; + + // Loop backwards from this point + pos48644: + + // back up one phoneme + X--; + + // stop once the beginning is reached + if(X == 0) break; + + // get the preceding phoneme + index = phonemeindex[X]; + + if(index != 255) //inserted to prevent access overrun + if((flags[index] & 128) == 0) goto pos48644; // if not a vowel, continue looping + + //pos48657: + do { + // test for vowel + index = phonemeindex[X]; + + if(index != 255) //inserted to prevent access overrun + // test for fricative/unvoiced or not voiced + if(((flags2[index] & 32) == 0) || ((flags[index] & 4) != 0)) //nochmal �berpr�fen + { + //A = flags[Y] & 4; + //if(A == 0) goto pos48688; + + // get the phoneme length + A = phonemeLength[X]; + + // change phoneme length to (length * 1.5) + 1 + A = (A >> 1) + A + 1; + + phonemeLength[X] = A; + } + // keep moving forward + X++; + } while(X != loopIndex); + // if (X != loopIndex) goto pos48657; + X++; + } // while + + // Similar to the above routine, but shorten vowels under some circumstances + + // Loop throught all phonemes + loopIndex = 0; + //pos48697 + + while(1) { + // get a phoneme + X = loopIndex; + index = phonemeindex[X]; + + // exit routine at end token + if(index == 255) return; + + // vowel? + A = flags[index] & 128; + if(A != 0) { + // get next phoneme + X++; + index = phonemeindex[X]; + + // get flags + if(index == 255) + mem56 = 65; // use if end marker + else + mem56 = flags[index]; + + // not a consonant + if((flags[index] & 64) == 0) { + // RX or LX? + if((index == 18) || (index == 19)) // 'RX' & 'LX' + { + // get the next phoneme + X++; + index = phonemeindex[X]; + + // next phoneme a consonant? + if((flags[index] & 64) != 0) { + // RULE: RX | LX + + // decrease length of vowel by 1 frame + phonemeLength[loopIndex]--; + } + // move ahead + loopIndex++; + continue; + } + // move ahead + loopIndex++; + continue; + } + + // Got here if not + + // not voiced + if((mem56 & 4) == 0) { + // Unvoiced + // *, .*, ?*, ,*, -*, DX, S*, SH, F*, TH, /H, /X, CH, P*, T*, K*, KX + + // not an unvoiced plosive? + if((mem56 & 1) == 0) { + // move ahead + loopIndex++; + continue; + } + + // P*, T*, K*, KX + + // RULE: + // + + // move back + X--; + + // decrease length by 1/8th + mem56 = phonemeLength[X] >> 3; + phonemeLength[X] -= mem56; + + // move ahead + loopIndex++; + continue; + } + + // RULE: + // + + // decrease length + A = phonemeLength[X - 1]; + phonemeLength[X - 1] = (A >> 2) + A + 1; // 5/4*A + 1 + + // move ahead + loopIndex++; + continue; + } + + // WH, R*, L*, W*, Y*, M*, N*, NX, Q*, Z*, ZH, V*, DH, J*, B*, D*, G*, GX + + //pos48821: + + // RULE: + // Set punctuation length to 6 + // Set stop consonant length to 5 + + // nasal? + if((flags2[index] & 8) != 0) { + // M*, N*, NX, + + // get the next phoneme + X++; + index = phonemeindex[X]; + + // end of buffer? + if(index == 255) + A = 65 & 2; //prevent buffer overflow + else + A = flags[index] & 2; // check for stop consonant + + // is next phoneme a stop consonant? + if(A != 0) + + // B*, D*, G*, GX, P*, T*, K*, KX + + { + // set stop consonant length to 6 + phonemeLength[X] = 6; + + // set nasal length to 5 + phonemeLength[X - 1] = 5; + } + // move to next phoneme + loopIndex++; + continue; + } + + // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, B*, D*, G*, GX + + // RULE: {optional silence} + // Shorten both to (length/2 + 1) + + // (voiced) stop consonant? + if((flags[index] & 2) != 0) { + // B*, D*, G*, GX + + // move past silence + do { + // move ahead + X++; + index = phonemeindex[X]; + } while(index == 0); + + // check for end of buffer + if(index == 255) //buffer overflow + { + // ignore, overflow code + if((65 & 2) == 0) { + loopIndex++; + continue; + } + } else if((flags[index] & 2) == 0) { + // if another stop consonant, move ahead + loopIndex++; + continue; + } + + // RULE: {optional silence} + + // X gets overwritten, so hold prior X value for debug statement + // int debugX = X; + // shorten the prior phoneme length to (length/2 + 1) + phonemeLength[X] = (phonemeLength[X] >> 1) + 1; + X = loopIndex; + + // also shorten this phoneme length to (length/2 +1) + phonemeLength[loopIndex] = (phonemeLength[loopIndex] >> 1) + 1; + + // move ahead + loopIndex++; + continue; + } + + // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, **, + + // RULE: + // Decrease by 2 + + // liquic consonant? + if((flags2[index] & 16) != 0) { + // R*, L*, W*, Y* + + // get the prior phoneme + index = phonemeindex[X - 1]; + + // prior phoneme a stop consonant> + if((flags[index] & 2) != 0) { + // Rule: + + // decrease the phoneme length by 2 frames (20 ms) + phonemeLength[X] -= 2; + } + } + + // move to next phoneme + loopIndex++; + continue; + } + // goto pos48701; +} + +// ------------------------------------------------------------------------- +// ML : Code47503 is division with remainder, and mem50 gets the sign +void STM32SAM::Code47503(unsigned char mem52) { + Y = 0; + if((mem53 & 128) != 0) { + mem53 = -mem53; + Y = 128; + } + mem50 = Y; + A = 0; + for(X = 8; X > 0; X--) { + int temp = mem53; + mem53 = mem53 << 1; + A = A << 1; + if(temp >= 128) A++; + if(A >= mem52) { + A = A - mem52; + mem53++; + } + } + + mem51 = A; + if((mem50 & 128) != 0) mem53 = -mem53; +} + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// Reciter +// +//////////////////////////////////////////////////////////////////////////////////////////// + +void STM32SAM::Code37055(unsigned char mem59) { + X = mem59; + X--; + A = inputtemp[X]; + Y = A; + A = tab36376[Y]; + return; +} + +void STM32SAM::Code37066(unsigned char mem58) { + X = mem58; + X++; + A = inputtemp[X]; + Y = A; + A = tab36376[Y]; +} + +unsigned char STM32SAM::GetRuleByte(unsigned short mem62, unsigned char Y) { + unsigned int address = mem62; + + if(mem62 >= 37541) { + address -= 37541; + return rules2[address + Y]; + } + address -= 32000; + return rules[address + Y]; +} + +int STM32SAM::TextToPhonemes(unsigned char* input) // Code36484 +{ + //unsigned char *tab39445 = &mem[39445]; //input and output + //unsigned char mem29; + unsigned char mem56; //output position for phonemes + unsigned char mem57; + unsigned char mem58; + unsigned char mem59; + unsigned char mem60; + unsigned char mem61; + unsigned short mem62; // memory position of current rule + + unsigned char mem64; // position of '=' or current character + unsigned char mem65; // position of ')' + unsigned char mem66; // position of '(' + unsigned char mem36653; + + inputtemp[0] = 32; + + // secure copy of input + // because input will be overwritten by phonemes + X = 1; + Y = 0; + do { + //pos36499: + A = input[Y] & 127; + if(A >= 112) + A = A & 95; + else if(A >= 96) + A = A & 79; + + inputtemp[X] = A; + X++; + Y++; + } while(Y != 255); + + X = 255; + inputtemp[X] = 27; + mem61 = 255; + +pos36550: + A = 255; + mem56 = 255; + +pos36554: + while(1) { + mem61++; + X = mem61; + A = inputtemp[X]; + mem64 = A; + if(A == '[') { + mem56++; + X = mem56; + A = 155; + input[X] = 155; + //goto pos36542; + // Code39771(); //Code39777(); + return 1; + } + + //pos36579: + if(A != '.') break; + X++; + Y = inputtemp[X]; + A = tab36376[Y] & 1; + if(A != 0) break; + mem56++; + X = mem56; + A = '.'; + input[X] = '.'; + } //while + + //pos36607: + A = mem64; + Y = A; + A = tab36376[A]; + mem57 = A; + if((A & 2) != 0) { + mem62 = 37541; + goto pos36700; + } + + //pos36630: + A = mem57; + if(A != 0) goto pos36677; + A = 32; + inputtemp[X] = ' '; + mem56++; + X = mem56; + if(X > 120) goto pos36654; + input[X] = A; + goto pos36554; + + // ----- + + //36653 is unknown. Contains position + +pos36654: + input[X] = 155; + A = mem61; + mem36653 = A; + // mem29 = A; // not used + // Code36538(); das ist eigentlich + return 1; + //Code39771(); + //go on if there is more input ??? + mem61 = mem36653; + goto pos36550; + +pos36677: + A = mem57 & 128; + if(A == 0) { + //36683: BRK + return 0; + } + + // go to the right rules for this character. + X = mem64 - 'A'; + mem62 = tab37489[X] | (tab37515[X] << 8); + + // ------------------------------------- + // go to next rule + // ------------------------------------- + +pos36700: + + // find next rule + Y = 0; + do { + mem62 += 1; + A = GetRuleByte(mem62, Y); + } while((A & 128) == 0); + Y++; + + //pos36720: + // find '(' + while(1) { + A = GetRuleByte(mem62, Y); + if(A == '(') break; + Y++; + } + mem66 = Y; + + //pos36732: + // find ')' + do { + Y++; + A = GetRuleByte(mem62, Y); + } while(A != ')'); + mem65 = Y; + + //pos36741: + // find '=' + do { + Y++; + A = GetRuleByte(mem62, Y); + A = A & 127; + } while(A != '='); + mem64 = Y; + + X = mem61; + mem60 = X; + + // compare the string within the bracket + Y = mem66; + Y++; + //pos36759: + while(1) { + mem57 = inputtemp[X]; + A = GetRuleByte(mem62, Y); + if(A != mem57) goto pos36700; + Y++; + if(Y == mem65) break; + X++; + mem60 = X; + } + + // the string in the bracket is correct + + //pos36787: + A = mem61; + mem59 = mem61; + +pos36791: + while(1) { + mem66--; + Y = mem66; + A = GetRuleByte(mem62, Y); + mem57 = A; + //36800: BPL 36805 + if((A & 128) != 0) goto pos37180; + X = A & 127; + A = tab36376[X] & 128; + if(A == 0) break; + X = mem59 - 1; + A = inputtemp[X]; + if(A != mem57) goto pos36700; + mem59 = X; + } + + //pos36833: + A = mem57; + if(A == ' ') goto pos36895; + if(A == '#') goto pos36910; + if(A == '.') goto pos36920; + if(A == '&') goto pos36935; + if(A == '@') goto pos36967; + if(A == '^') goto pos37004; + if(A == '+') goto pos37019; + if(A == ':') goto pos37040; + // Code42041(); //Error + //36894: BRK + return 0; + + // -------------- + +pos36895: + Code37055(mem59); + A = A & 128; + if(A != 0) goto pos36700; +pos36905: + mem59 = X; + goto pos36791; + + // -------------- + +pos36910: + Code37055(mem59); + A = A & 64; + if(A != 0) goto pos36905; + goto pos36700; + + // -------------- + +pos36920: + Code37055(mem59); + A = A & 8; + if(A == 0) goto pos36700; +pos36930: + mem59 = X; + goto pos36791; + + // -------------- + +pos36935: + Code37055(mem59); + A = A & 16; + if(A != 0) goto pos36930; + A = inputtemp[X]; + if(A != 72) goto pos36700; + X--; + A = inputtemp[X]; + if((A == 67) || (A == 83)) goto pos36930; + goto pos36700; + + // -------------- + +pos36967: + Code37055(mem59); + A = A & 4; + if(A != 0) goto pos36930; + A = inputtemp[X]; + if(A != 72) goto pos36700; + if((A != 84) && (A != 67) && (A != 83)) goto pos36700; + mem59 = X; + goto pos36791; + + // -------------- + +pos37004: + Code37055(mem59); + A = A & 32; + if(A == 0) goto pos36700; + +pos37014: + mem59 = X; + goto pos36791; + + // -------------- + +pos37019: + X = mem59; + X--; + A = inputtemp[X]; + if((A == 'E') || (A == 'I') || (A == 'Y')) goto pos37014; + goto pos36700; + // -------------- + +pos37040: + Code37055(mem59); + A = A & 32; + if(A == 0) goto pos36791; + mem59 = X; + goto pos37040; + + //--------------------------------------- + +pos37077: + X = mem58 + 1; + A = inputtemp[X]; + if(A != 'E') goto pos37157; + X++; + Y = inputtemp[X]; + X--; + A = tab36376[Y] & 128; + if(A == 0) goto pos37108; + X++; + A = inputtemp[X]; + if(A != 'R') goto pos37113; +pos37108: + mem58 = X; + goto pos37184; +pos37113: + if((A == 83) || (A == 68)) goto pos37108; // 'S' 'D' + if(A != 76) goto pos37135; // 'L' + X++; + A = inputtemp[X]; + if(A != 89) goto pos36700; + goto pos37108; + +pos37135: + if(A != 70) goto pos36700; + X++; + A = inputtemp[X]; + if(A != 85) goto pos36700; + X++; + A = inputtemp[X]; + if(A == 76) goto pos37108; + goto pos36700; + +pos37157: + if(A != 73) goto pos36700; + X++; + A = inputtemp[X]; + if(A != 78) goto pos36700; + X++; + A = inputtemp[X]; + if(A == 71) goto pos37108; + //pos37177: + goto pos36700; + + // ----------------------------------------- + +pos37180: + + A = mem60; + mem58 = A; + +pos37184: + Y = mem65 + 1; + + //37187: CPY 64 + // if(? != 0) goto pos37194; + if(Y == mem64) goto pos37455; + mem65 = Y; + //37196: LDA (62),y + A = GetRuleByte(mem62, Y); + mem57 = A; + X = A; + A = tab36376[X] & 128; + if(A == 0) goto pos37226; + X = mem58 + 1; + A = inputtemp[X]; + if(A != mem57) goto pos36700; + mem58 = X; + goto pos37184; +pos37226: + A = mem57; + if(A == 32) goto pos37295; // ' ' + if(A == 35) goto pos37310; // '#' + if(A == 46) goto pos37320; // '.' + if(A == 38) goto pos37335; // '&' + if(A == 64) goto pos37367; // '' + if(A == 94) goto pos37404; // '' + if(A == 43) goto pos37419; // '+' + if(A == 58) goto pos37440; // ':' + if(A == 37) goto pos37077; // '%' + //pos37291: + // Code42041(); //Error + //37294: BRK + return 0; + + // -------------- +pos37295: + Code37066(mem58); + A = A & 128; + if(A != 0) goto pos36700; +pos37305: + mem58 = X; + goto pos37184; + + // -------------- + +pos37310: + Code37066(mem58); + A = A & 64; + if(A != 0) goto pos37305; + goto pos36700; + + // -------------- + +pos37320: + Code37066(mem58); + A = A & 8; + if(A == 0) goto pos36700; + +pos37330: + mem58 = X; + goto pos37184; + + // -------------- + +pos37335: + Code37066(mem58); + A = A & 16; + if(A != 0) goto pos37330; + A = inputtemp[X]; + if(A != 72) goto pos36700; + X++; + A = inputtemp[X]; + if((A == 67) || (A == 83)) goto pos37330; + goto pos36700; + + // -------------- + +pos37367: + Code37066(mem58); + A = A & 4; + if(A != 0) goto pos37330; + A = inputtemp[X]; + if(A != 72) goto pos36700; + if((A != 84) && (A != 67) && (A != 83)) goto pos36700; + mem58 = X; + goto pos37184; + + // -------------- + +pos37404: + Code37066(mem58); + A = A & 32; + if(A == 0) goto pos36700; +pos37414: + mem58 = X; + goto pos37184; + + // -------------- + +pos37419: + X = mem58; + X++; + A = inputtemp[X]; + if((A == 69) || (A == 73) || (A == 89)) goto pos37414; + goto pos36700; + + // ---------------------- + +pos37440: + + Code37066(mem58); + A = A & 32; + if(A == 0) goto pos37184; + mem58 = X; + goto pos37440; +pos37455: + Y = mem64; + mem61 = mem60; + +pos37461: + //37461: LDA (62),y + A = GetRuleByte(mem62, Y); + mem57 = A; + A = A & 127; + if(A != '=') { + mem56++; + X = mem56; + input[X] = A; + } + + //37478: BIT 57 + //37480: BPL 37485 //not negative flag + if((mem57 & 128) == 0) goto pos37485; //??? + goto pos36554; +pos37485: + Y++; + goto pos37461; +} + +// Constructor + +STM32SAM::STM32SAM(uint32_t STM32SAM_SPEED /* = 5 */) { + STM32SAM_SPEED = STM32SAM_SPEED & 0x1f; // limit it from 0 to 31 + + _STM32SAM_SPEED = STM32SAM_SPEED; + + // set default voice + + speed = 72; + pitch = 64; + mouth = 128; + throat = 128; + + phonetic = 0; + singmode = 0; + + wait1 = 7; + wait2 = 6; + + mem59 = 0; + + oldtimetableindex = 0; +} + +STM32SAM::STM32SAM() { + _STM32SAM_SPEED = 7; + + // set default voice + + speed = 72; + pitch = 64; + mouth = 128; + throat = 128; + + phonetic = 0; + singmode = 0; + + wait1 = 7; + wait2 = 6; + + mem59 = 0; + + oldtimetableindex = 0; +} + +/* + STM32SAM::~STM32SAM() { + { + // TODO: end(); + } +*/ + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// STM32SAM sam (variable string, phonetic, sing, pitch, speed, mouth, throat) +// STM32SAM say (sing off, phonetic off) (const string) +// STM32SAM say (sing off, phonetic off) (variable string) +// STM32SAM sing (sing on, phonetic off) (const string) +// STM32SAM sing (sing on, phonetic off) (variable string) +// STM32SAM sayPhonetic (sing off, phonetic on) (const string) +// STM32SAM sayPhonetic (sing off, phonetic on) (variable string) +// STM32SAM singPhonetic (sing on, phonetic on) (const string) +// STM32SAM singPhonetic (sing on, phonetic on) (variable string) +// STM32SAM voice (pitch, speed, mouth, throat) +// STM32SAM setPitch (pitch) +// STM32SAM setSpeed (speed) +// STM32SAM setMouth (mouth) +// STM32SAM setThroat (throat) +// +// +//////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// STM32SAM sam (const string, phonetic, sing, pitch, speed, mouth, throat) +// +//////////////////////////////////////////////////////////////////////////////////////////// + +char to_upper_case(char c) { + if(c >= 'a' && c <= 'z') { + return c - 'a' + 'A'; + } + return c; +} + +void STM32SAM::sam( + const char* argv, + unsigned char _phonetic, + unsigned char _singmode, + unsigned char _pitch, + unsigned char _speed, + unsigned char _mouth, + unsigned char _throat) { + phonetic = _phonetic; + singmode = _singmode; + pitch = _pitch; + speed = _speed; + mouth = _mouth; + throat = _throat; + + int i; + + for(i = 0; i < 256; i++) { + input[i] = argv[i]; + } + + for(i = 0; input[i] != 0; i++) { + if(i != 0) { + input[i] = to_upper_case((int)argv[i]); + } + } + + if(!phonetic) { + strncat(input, "[", 256); + if(!TextToPhonemes((unsigned char*)input)) { + // PrintUsage(); + return; + } + + } else { + strncat(input, "\x9b", 256); + } + + SetInput(input); + + if(!SAMMain()) { + return; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// STM32SAM sam (variable string, phonetic, sing, pitch, speed, mouth, throat) +// +//////////////////////////////////////////////////////////////////////////////////////////// + +void STM32SAM::sam( + char* argv, + unsigned char _phonetic, + unsigned char _singmode, + unsigned char _pitch, + unsigned char _speed, + unsigned char _mouth, + unsigned char _throat) { + phonetic = _phonetic; + singmode = _singmode; + pitch = _pitch; + speed = _speed; + mouth = _mouth; + throat = _throat; + + int i; + + for(i = 0; i < 256; i++) { + input[i] = argv[i]; + } + + for(i = 0; input[i] != 0; i++) { + if(i != 0) { + input[i] = to_upper_case((int)argv[i]); + } + } + + if(!phonetic) { + strncat(input, "[", 256); + if(!TextToPhonemes((unsigned char*)input)) { + // PrintUsage(); + return; + } + + } else { + strncat(input, "\x9b", 256); + } + + SetInput(input); + + if(!SAMMain()) { + return; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// STM32SAM say(sing off, phonetic off) (const string) +// +//////////////////////////////////////////////////////////////////////////////////////////// + +void STM32SAM::say(const char* argv) { + int i; + + phonetic = 0; + singmode = 0; + + char const_input[256]; + + for(i = 0; i < 256; i++) { + const_input[i] = argv[i]; + } + + sam(const_input, phonetic, singmode, pitch, speed, mouth, throat); +} + +void STM32SAM::say(char* argv) { + int i; + + phonetic = 0; + singmode = 0; + + char const_input[256]; + + for(i = 0; i < 256; i++) { + const_input[i] = argv[i]; + } + + sam(const_input, phonetic, singmode, pitch, speed, mouth, throat); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// STM32SAM sing (sing on, phonetic off) +// +//////////////////////////////////////////////////////////////////////////////////////////// + +void STM32SAM::sing(const char* argv) { + int i; + + phonetic = 0; + singmode = 1; + + char const_input[256]; + + for(i = 0; i < 256; i++) { + const_input[i] = argv[i]; + } + + sam(const_input, phonetic, singmode, pitch, speed, mouth, throat); +} + +void STM32SAM::sing(char* argv) { + int i; + + phonetic = 0; + singmode = 1; + + char const_input[256]; + + for(i = 0; i < 256; i++) { + const_input[i] = argv[i]; + } + + sam(const_input, phonetic, singmode, pitch, speed, mouth, throat); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// STM32SAM sayPhonetic (sing off, phonetic on) +// +//////////////////////////////////////////////////////////////////////////////////////////// + +void STM32SAM::sayPhonetic(const char* argv) { + int i; + + phonetic = 1; + singmode = 0; + + char const_input[256]; + + for(i = 0; i < 256; i++) { + const_input[i] = argv[i]; + } + + sam(const_input, phonetic, singmode, pitch, speed, mouth, throat); +} + +void STM32SAM::sayPhonetic(char* argv) { + int i; + + phonetic = 1; + singmode = 0; + + char const_input[256]; + + for(i = 0; i < 256; i++) { + const_input[i] = argv[i]; + } + + sam(const_input, phonetic, singmode, pitch, speed, mouth, throat); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// STM32SAM singPhonetic (sing on, phonetic on) +// +//////////////////////////////////////////////////////////////////////////////////////////// + +void STM32SAM::singPhonetic(const char* argv) { + int i; + + phonetic = 1; + singmode = 1; + + char const_input[256]; + + for(i = 0; i < 256; i++) { + const_input[i] = argv[i]; + } + + sam(const_input, phonetic, singmode, pitch, speed, mouth, throat); +} + +void STM32SAM::singPhonetic(char* argv) { + int i; + + phonetic = 1; + singmode = 0; + + char const_input[256]; + + for(i = 0; i < 256; i++) { + const_input[i] = argv[i]; + } + + sam(const_input, phonetic, singmode, pitch, speed, mouth, throat); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// STM32SAM voice (pitch, speed, mouth, throat) +// +//////////////////////////////////////////////////////////////////////////////////////////// + +void STM32SAM::setVoice( + unsigned char _pitch /* = 64 */, + unsigned char _speed /* = 72 */, + unsigned char _mouth /* = 128 */, + unsigned char _throat /* = 128 */) { + pitch = _pitch; + speed = _speed; + mouth = _mouth; + throat = _throat; +} + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// STM32SAM setPitch (pitch) +// +//////////////////////////////////////////////////////////////////////////////////////////// + +void STM32SAM::setPitch(unsigned char _pitch /* = 64 */) { + pitch = _pitch; +} +//////////////////////////////////////////////////////////////////////////////////////////// +// +// STM32SAM setSpeed (speed) +// +//////////////////////////////////////////////////////////////////////////////////////////// + +void STM32SAM::setSpeed(unsigned char _speed /* = 72 */) { + speed = _speed; +} +//////////////////////////////////////////////////////////////////////////////////////////// +// +// STM32SAM setMouth (mouth) +// +//////////////////////////////////////////////////////////////////////////////////////////// + +void STM32SAM::setMouth(unsigned char _mouth /* = 128 */) { + mouth = _mouth; +} + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// STM32SAM setThroat (throat) +// +//////////////////////////////////////////////////////////////////////////////////////////// + +void STM32SAM::setThroat(unsigned char _throat /* = 128 */) { + throat = _throat; +} +//////////////////////////////////////////////////////////////////////////////////////////// +// +// Hardware +// +//////////////////////////////////////////////////////////////////////////////////////////// +// Hardware specifics, for easier porting to other microcontrollers + +// +// Set PA8 pin as PWM, at 256 timer ticks overflow (8bit resolution) + +#include +#include + +#define FURI_HAL_SPEAKER_TIMER TIM16 +#define FURI_HAL_SPEAKER_CHANNEL LL_TIM_CHANNEL_CH1 + +void STM32SAM::begin(void) { +#ifdef USE_ROGER_CORE + + pinMode(PA8, PWM); // audio output pin + + Timer1.setPeriod( + 4); // Can't set at 256 ticks, only in uS. First nearest uS is 4 (Roger core is only for bluepill, that means 72*4=288 ticks, or 128*4=512 ticks when overclocked. It's ok, just overall volume will be lower, because maximum volume will be 256/288 or 256/512) + +#endif + +#ifdef USE_STM32duino_CORE + pinMode(PA8, OUTPUT); + + PWM->pause(); + PWM->setMode(1, TIMER_OUTPUT_COMPARE_PWM1, PA8); // TIM1 CH1 (PA8) + PWM->setPrescaleFactor(1); + PWM->setOverflow(256, TICK_FORMAT); // 256 ticks overflow, no matter the CPU (timer) speed + PWM->resume(); + +#endif + + LL_TIM_InitTypeDef TIM_InitStruct; + memset(&TIM_InitStruct, 0, sizeof(LL_TIM_InitTypeDef)); + TIM_InitStruct.Prescaler = 4; + TIM_InitStruct.Autoreload = 255; + LL_TIM_Init(FURI_HAL_SPEAKER_TIMER, &TIM_InitStruct); + + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct; + memset(&TIM_OC_InitStruct, 0, sizeof(LL_TIM_OC_InitTypeDef)); + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE; + TIM_OC_InitStruct.CompareValue = 127; + LL_TIM_OC_Init(FURI_HAL_SPEAKER_TIMER, FURI_HAL_SPEAKER_CHANNEL, &TIM_OC_InitStruct); + + LL_TIM_EnableAllOutputs(FURI_HAL_SPEAKER_TIMER); + LL_TIM_EnableCounter(FURI_HAL_SPEAKER_TIMER); +} // begin + +inline void STM32SAM::SetAUDIO(unsigned char main_volume) { +#ifdef USE_ROGER_CORE + Timer1.setCompare(TIMER_CH1, main_volume); +#endif + +#ifdef USE_STM32duino_CORE + PWM->setCaptureCompare(1, main_volume, TICK_COMPARE_FORMAT); +#endif + + // if(main_volume > 64) { + // LL_TIM_OC_SetCompareCH1(FURI_HAL_SPEAKER_TIMER, 127); + // } else { + // LL_TIM_OC_SetCompareCH1(FURI_HAL_SPEAKER_TIMER, main_volume); + // } + + float data = main_volume; + data /= 255.0f; + data -= 0.5f; + data *= 4.0f; + data = tanhf(data); + + data += 0.5f; + data *= 255.0f; + + if(data < 0) { + data = 0; + } else if(data > 255) { + data = 255; + } + + LL_TIM_OC_SetCompareCH1(FURI_HAL_SPEAKER_TIMER, data); +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/sam/stm32_sam.h b/Applications/Official/DEV_FW/source/xMasterX/sam/stm32_sam.h new file mode 100644 index 000000000..910227ac3 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/sam/stm32_sam.h @@ -0,0 +1,96 @@ +#include + +#ifndef __STM32SAM__ +#define __STM32SAM__ + +// SAM Text-To-Speech (TTS), ported from https://github.com/s-macke/SAM + +class STM32SAM { +public: + STM32SAM(uint32_t STM32SAM_SPEED); + STM32SAM(); + + void begin(void); + + void + sam(const char* argv, + unsigned char phonetic, + unsigned char singmode, + unsigned char pitch, + unsigned char speed, + unsigned char mouth, + unsigned char throat); + void + sam(char* argv, + unsigned char phonetic, + unsigned char singmode, + unsigned char pitch, + unsigned char speed, + unsigned char mouth, + unsigned char throat); + + void say(const char* argv); + void say(char* argv); + void sing(const char* argv); + void sing(char* argv); + void sayPhonetic(const char* argv); + void sayPhonetic(char* argv); + void singPhonetic(const char* argv); + void singPhonetic(char* argv); + void setVoice( + unsigned char _pitch = 64, + unsigned char _speed = 72, + unsigned char _mouth = 128, + unsigned char _throat = 128); + void setPitch(unsigned char _pitch = 64); + void setSpeed(unsigned char _speed = 72); + void setMouth(unsigned char _mouth = 128); + void setThroat(unsigned char _throat = 128); + +private: + void SetAUDIO(unsigned char main_volume); + + void Output8BitAry(int index, unsigned char ary[5]); + void Output8Bit(int index, unsigned char A); + unsigned char Read(unsigned char p, unsigned char Y); + void Write(unsigned char p, unsigned char Y, unsigned char value); + void RenderSample(unsigned char* mem66); + void Render(); + void AddInflection(unsigned char mem48, unsigned char phase1); + void SetMouthThroat(); + unsigned char trans(unsigned char mem39212, unsigned char mem39213); + void SetInput(char* _input); + void Init(); + int SAMMain(); + void PrepareOutput(); + void Insert( + unsigned char position /*var57*/, + unsigned char mem60, + unsigned char mem59, + unsigned char mem58); + void InsertBreath(); + void CopyStress(); + int Parser1(); + void SetPhonemeLength(); + void Code41240(); + void Parser2(); + void AdjustLengths(); + void Code47503(unsigned char mem52); + void Code37055(unsigned char mem59); + void Code37066(unsigned char mem58); + unsigned char GetRuleByte(unsigned short mem62, unsigned char Y); + int TextToPhonemes(unsigned char* input); // Code36484 + + uint32_t _STM32SAM_SPEED; + + unsigned char speed; + unsigned char pitch; + unsigned char mouth; + unsigned char throat; + + unsigned char phonetic; + unsigned char singmode; + +}; // STM32SAM class + +#endif \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/LICENSE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/README.md b/Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/README.md new file mode 100644 index 000000000..1c1970c19 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/README.md @@ -0,0 +1,35 @@ +# Scorched tanks - flipper zero game +A flipper zero game inspired by scorched earth. + +Current state is shown below: + +![input](scorched_tanks_v1.gif) + +## How to do: +Do not hesitate to create PRs. If you start working on sth, please start branch name with TODO id (e.g. `feature/2-change-tank-icon`) + +If you see an improvement, modify this readme and add suggestions via PR. Bugs can be reported via Issues + +## What to do next (it's not in the priority order): +5. flatten surface beneath tanks +7. explosion animation +9. sub-ghz multi-player +11. add other types of weapons +12. code AI +13. add terain destruction +14. add terain gravity (fall down after hitting the middle of the mountain) +18. Add menu with settings (vibartion on/off, difficulty) +20. add more ground modifiers (currently there is only one hill in the middle, maybe 2 hills, skew map, etc) + +## What have been done: +1. ~~remove movement~~ +2. ~~change tank icon~~ +3. ~~power as variable not constant~~ +4. ~~better map generation: high, low regions~~ (continuation in point 20.) +6. ~~collision with the enemy~~ +8. ~~local multi-player~~ +10. ~~improve projectile trace draw on angles > 80~~ +15. ~~FIX: firing stops when bullet fly above the screen~~ +16. ~~Slightly randomize player and enemy spawn locations~~ +17. ~~Shooting vibration~~ +19. ~~Add wind~~ diff --git a/Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/application.fam b/Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/application.fam new file mode 100644 index 000000000..58f8863d4 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/application.fam @@ -0,0 +1,12 @@ +App( + appid="Scorched_Tanks", + name="Scorched Tanks", + apptype=FlipperAppType.EXTERNAL, + entry_point="scorched_tanks_game_app", + cdefines=["APP_SCORCHED_TANKS_GAME"], + requires=["gui"], + stack_size=1 * 1024, + order=100, + fap_icon="scorchedTanks_10px.png", + fap_category="Games_Extra", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/scorchedTanks_10px.png b/Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/scorchedTanks_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1ae4c04b973c4015b6c4bb84ee6e806c4cde04 GIT binary patch literal 614 zcmV-s0-61ZP)EX>4Tx04R}tkv&MmKpe$iQ$;Bi5j%)DWT;LSM5Q`P6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<`9$B7gyeFoUSXOg)ia%)oPe-NVP%y9m$nKKJM7Q}QMQd?N82(+!JwgE+cr z>74h8L#!kz#OK8023?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6NeR5qkJLj zvch?bvs$UK);;+PgL!Qw&2^e1h+_!}Bq2gZ4P{hdAwsK0iis5M$2|PQjz38*nOtQs zax9<<6_Voz|AXJ%nuV!JHz^ncx?gPjV-)Dw1)6o+{yw(t<_X|`2ClTWzuEw1KS{5* zweS(pzYSbmw>5bWxZDATo^;8O9LY~pC=`JAGy0|+Fn9|D*4*A&`#607GSt=b4RCM> zj1?(+-Q(T8oxS~grq$mM6zy{8hfi!q00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_Z!C4+Jw!Hq!tA02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002HoL_t&-(~Xcx3IH$+0yXsiU!I-{g>=zVz(I@#P@qa6 z+pYuxs05OvaWdDv_pck&lzjc|*yeeqF3;)U6GWsW10ayR(*OVf07*qoM6N<$g4ARE A`Tzg` literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/scorched_tanks_game_app.c b/Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/scorched_tanks_game_app.c new file mode 100644 index 000000000..fd4c73ee7 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/scorched_tanks_game_app.c @@ -0,0 +1,540 @@ +#include +#include +#include +#include +#include +#include +#include + +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 64 +#define PLAYER_INIT_LOCATION_X 20 +#define PLAYER_INIT_AIM 45 +#define PLAYER_INIT_POWER 50 +#define ENEMY_INIT_LOCATION_X 108 +#define TANK_BARREL_LENGTH 8 +#define GRAVITY_FORCE (double)0.5 +#define MIN_GROUND_HEIGHT 35 +#define MAX_GROUND_HEIGHT 55 +#define MAX_FIRE_POWER 100 +#define MIN_FIRE_POWER 0 +#define TANK_COLLIDER_SIZE 3 +#define MAX_WIND 10 +#define MAX_PLAYER_DIFF_X 20 +#define MAX_ENEMY_DIFF_X 20 + +// That's a filthy workaround but sin(player.aimAngle) breaks it all... If you're able to fix it, please do create a PR! +double scorched_tanks_sin[91] = { + 0.000, -0.017, -0.035, -0.052, -0.070, -0.087, -0.105, -0.122, -0.139, -0.156, -0.174, -0.191, + -0.208, -0.225, -0.242, -0.259, -0.276, -0.292, -0.309, -0.326, -0.342, -0.358, -0.375, -0.391, + -0.407, -0.423, -0.438, -0.454, -0.469, -0.485, -0.500, -0.515, -0.530, -0.545, -0.559, -0.574, + -0.588, -0.602, -0.616, -0.629, -0.643, -0.656, -0.669, -0.682, -0.695, -0.707, -0.719, -0.731, + -0.743, -0.755, -0.766, -0.777, -0.788, -0.799, -0.809, -0.819, -0.829, -0.839, -0.848, -0.857, + -0.866, -0.875, -0.883, -0.891, -0.899, -0.906, -0.914, -0.921, -0.927, -0.934, -0.940, -0.946, + -0.951, -0.956, -0.961, -0.966, -0.970, -0.974, -0.978, -0.982, -0.985, -0.988, -0.990, -0.993, + -0.995, -0.996, -0.998, -0.999, -0.999, -1.000, -1.000}; +double scorched_tanks_cos[91] = { + 1.000, 1.000, 0.999, 0.999, 0.998, 0.996, 0.995, 0.993, 0.990, 0.988, 0.985, 0.982, 0.978, + 0.974, 0.970, 0.966, 0.961, 0.956, 0.951, 0.946, 0.940, 0.934, 0.927, 0.921, 0.914, 0.906, + 0.899, 0.891, 0.883, 0.875, 0.866, 0.857, 0.848, 0.839, 0.829, 0.819, 0.809, 0.799, 0.788, + 0.777, 0.766, 0.755, 0.743, 0.731, 0.719, 0.707, 0.695, 0.682, 0.669, 0.656, 0.643, 0.629, + 0.616, 0.602, 0.588, 0.574, 0.559, 0.545, 0.530, 0.515, 0.500, 0.485, 0.469, 0.454, 0.438, + 0.423, 0.407, 0.391, 0.375, 0.358, 0.342, 0.326, 0.309, 0.292, 0.276, 0.259, 0.242, 0.225, + 0.208, 0.191, 0.174, 0.156, 0.139, 0.122, 0.105, 0.087, 0.070, 0.052, 0.035, 0.017, 0.000}; +double scorched_tanks_tan[91] = { + 0.000, -0.017, -0.035, -0.052, -0.070, -0.087, -0.105, -0.123, -0.141, -0.158, -0.176, + -0.194, -0.213, -0.231, -0.249, -0.268, -0.287, -0.306, -0.325, -0.344, -0.364, -0.384, + -0.404, -0.424, -0.445, -0.466, -0.488, -0.510, -0.532, -0.554, -0.577, -0.601, -0.625, + -0.649, -0.674, -0.700, -0.727, -0.754, -0.781, -0.810, -0.839, -0.869, -0.900, -0.932, + -0.966, -1.000, -1.036, -1.072, -1.111, -1.150, -1.192, -1.235, -1.280, -1.327, -1.376, + -1.428, -1.483, -1.540, -1.600, -1.664, -1.732, -1.804, -1.881, -1.963, -2.050, -2.144, + -2.246, -2.356, -2.475, -2.605, -2.747, -2.904, -3.078, -3.271, -3.487, -3.732, -4.011, + -4.331, -4.704, -5.144, -5.671, -6.313, -7.115, -8.144, -9.513, -11.429, -14.298, -19.077, + -28.627, -57.254, -90747.269}; +unsigned char scorched_tanks_ground_modifiers[SCREEN_WIDTH] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 28, 26, 24, 22, 20, + 18, 16, 14, 12, 10, 8, 6, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +typedef struct { + // +-----x + // | + // | + // y + uint8_t x; + uint8_t y; +} Point; + +typedef struct { + // +-----x + // | + // | + // y + double x; + double y; +} PointDetailed; + +typedef struct { + unsigned char locationX; + unsigned char hp; + int aimAngle; + unsigned char firePower; +} Tank; + +typedef struct { + Point ground[SCREEN_WIDTH]; + Tank player; + Tank enemy; + bool isPlayerTurn; + bool isShooting; + int windSpeed; + Point trajectory[SCREEN_WIDTH]; + unsigned char trajectoryAnimationStep; + PointDetailed bulletPosition; + PointDetailed bulletVector; +} Game; + +typedef enum { + EventTypeTick, + EventTypeKey, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} ScorchedTanksEvent; + +int scorched_tanks_random(int min, int max) { + return min + rand() % ((max + 1) - min); +} + +void scorched_tanks_generate_ground(Game* game_state) { + int lastHeight = 45; + + for(unsigned char a = 0; a < SCREEN_WIDTH; a++) { + int diffHeight = scorched_tanks_random(-2, 3); + int changeLength = scorched_tanks_random(1, 6); + + if(diffHeight == 0) { + changeLength = 1; + } + + for(int b = 0; b < changeLength; b++) { + if(a + b < SCREEN_WIDTH) { + int index = a + b; + int newPoint = lastHeight + diffHeight; + newPoint = newPoint < MIN_GROUND_HEIGHT ? MIN_GROUND_HEIGHT : newPoint; + newPoint = newPoint > MAX_GROUND_HEIGHT ? MAX_GROUND_HEIGHT : newPoint; + game_state->ground[index].x = index; + game_state->ground[index].y = newPoint - scorched_tanks_ground_modifiers[a]; + lastHeight = newPoint; + } else { + a += b; + break; + } + } + + a += changeLength - 1; + } +} + +void scorched_tanks_init_game(Game* game_state) { + game_state->player.locationX = PLAYER_INIT_LOCATION_X + + scorched_tanks_random(0, MAX_PLAYER_DIFF_X) - + MAX_PLAYER_DIFF_X / 2; + game_state->player.aimAngle = PLAYER_INIT_AIM; + game_state->player.firePower = PLAYER_INIT_POWER; + game_state->enemy.aimAngle = PLAYER_INIT_AIM; + game_state->enemy.firePower = PLAYER_INIT_POWER; + game_state->enemy.locationX = + ENEMY_INIT_LOCATION_X + scorched_tanks_random(0, MAX_ENEMY_DIFF_X) - MAX_ENEMY_DIFF_X / 2; + game_state->isPlayerTurn = true; + + game_state->windSpeed = scorched_tanks_random(0, MAX_WIND); + + for(int x = 0; x < SCREEN_WIDTH; x++) { + game_state->trajectory[x].x = 0; + game_state->trajectory[x].y = 0; + } + + scorched_tanks_generate_ground(game_state); +} + +void scorched_tanks_calculate_trajectory(Game* game_state) { + if(game_state->isShooting) { + game_state->bulletVector.x += ((double)game_state->windSpeed - MAX_WIND / 2) / 40; + game_state->bulletVector.y += GRAVITY_FORCE; + + game_state->bulletPosition.x += game_state->bulletVector.x; + game_state->bulletPosition.y += game_state->bulletVector.y; + + int totalDistanceToEnemy = 100; + + if(game_state->isPlayerTurn) { + double distanceToEnemyX = game_state->enemy.locationX - game_state->bulletPosition.x; + double distanceToEnemyY = game_state->ground[game_state->enemy.locationX].y - + TANK_COLLIDER_SIZE - game_state->bulletPosition.y; + totalDistanceToEnemy = + sqrt(distanceToEnemyX * distanceToEnemyX + distanceToEnemyY * distanceToEnemyY); + } else { + double distanceToEnemyX = game_state->player.locationX - game_state->bulletPosition.x; + double distanceToEnemyY = game_state->ground[game_state->player.locationX].y - + TANK_COLLIDER_SIZE - game_state->bulletPosition.y; + totalDistanceToEnemy = + sqrt(distanceToEnemyX * distanceToEnemyX + distanceToEnemyY * distanceToEnemyY); + } + + if(totalDistanceToEnemy <= TANK_COLLIDER_SIZE) { + game_state->isShooting = false; + scorched_tanks_init_game(game_state); + game_state->isPlayerTurn = !game_state->isPlayerTurn; + return; + } + + if(game_state->bulletPosition.x > SCREEN_WIDTH || + game_state->bulletPosition.y > + game_state->ground[(int)round(game_state->bulletPosition.x)].y) { + game_state->isShooting = false; + game_state->bulletPosition.x = 0; + game_state->bulletPosition.y = 0; + game_state->windSpeed = scorched_tanks_random(0, MAX_WIND); + game_state->isPlayerTurn = !game_state->isPlayerTurn; + return; + } + + if(game_state->bulletPosition.y > 0) { + game_state->trajectory[game_state->trajectoryAnimationStep].x = + round(game_state->bulletPosition.x); + game_state->trajectory[game_state->trajectoryAnimationStep].y = + round(game_state->bulletPosition.y); + game_state->trajectoryAnimationStep++; + } + } +} + +static void scorched_tanks_draw_tank( + Canvas* const canvas, + unsigned char x, + unsigned char y, + bool isPlayer) { + unsigned char lineIndex = 0; + + if(isPlayer) { + // Draw tank base + canvas_draw_line(canvas, x - 3, y - lineIndex, x + 3, y - lineIndex++); + canvas_draw_line(canvas, x - 4, y - lineIndex, x + 4, y - lineIndex++); + canvas_draw_line(canvas, x - 4, y - lineIndex, x + 4, y - lineIndex++); + + // draw turret + canvas_draw_line(canvas, x - 2, y - lineIndex, x + 1, y - lineIndex++); + canvas_draw_line(canvas, x - 2, y - lineIndex, x, y - lineIndex++); + } else { + // Draw tank base + canvas_draw_line(canvas, x - 3, y - lineIndex, x + 3, y - lineIndex++); + canvas_draw_line(canvas, x - 4, y - lineIndex, x + 4, y - lineIndex++); + canvas_draw_line(canvas, x - 4, y - lineIndex, x + 4, y - lineIndex++); + + // draw turret + canvas_draw_line(canvas, x - 1, y - lineIndex, x + 2, y - lineIndex++); + canvas_draw_line(canvas, x, y - lineIndex, x + 2, y - lineIndex++); + } +} + +static void scorched_tanks_render_callback(Canvas* const canvas, void* ctx) { + const Game* game_state = acquire_mutex((ValueMutex*)ctx, 25); + + if(game_state == NULL) { + return; + } + + canvas_draw_frame(canvas, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + + canvas_set_color(canvas, ColorBlack); + + if(game_state->isShooting) { + canvas_draw_dot(canvas, game_state->bulletPosition.x, game_state->bulletPosition.y); + } + + for(int a = 1; a < SCREEN_WIDTH; a++) { + canvas_draw_line( + canvas, + game_state->ground[a - 1].x, + game_state->ground[a - 1].y, + game_state->ground[a].x, + game_state->ground[a].y); + + if(game_state->trajectory[a].y != 0) { + canvas_draw_dot(canvas, game_state->trajectory[a].x, game_state->trajectory[a].y); + } + } + + scorched_tanks_draw_tank( + canvas, + game_state->enemy.locationX, + game_state->ground[game_state->enemy.locationX].y - TANK_COLLIDER_SIZE, + true); + + scorched_tanks_draw_tank( + canvas, + game_state->player.locationX, + game_state->ground[game_state->player.locationX].y - TANK_COLLIDER_SIZE, + false); + + int aimX1 = 0; + int aimY1 = 0; + int aimX2 = 0; + int aimY2 = 0; + + if(game_state->isPlayerTurn) { + aimX1 = game_state->player.locationX; + aimY1 = game_state->ground[game_state->player.locationX].y - TANK_COLLIDER_SIZE; + + double sinFromAngle = scorched_tanks_sin[game_state->player.aimAngle]; + double cosFromAngle = scorched_tanks_cos[game_state->player.aimAngle]; + aimX2 = aimX1 + TANK_BARREL_LENGTH * cosFromAngle; + aimY2 = aimY1 + TANK_BARREL_LENGTH * sinFromAngle; + + aimX1 += 1; + aimX2 += 1; + } else { + aimX1 = game_state->enemy.locationX; + aimY1 = game_state->ground[game_state->enemy.locationX].y - TANK_COLLIDER_SIZE; + + double sinFromAngle = scorched_tanks_sin[game_state->enemy.aimAngle]; + double cosFromAngle = scorched_tanks_cos[game_state->enemy.aimAngle]; + aimX2 = aimX1 + TANK_BARREL_LENGTH * cosFromAngle; + aimY2 = aimY1 + TANK_BARREL_LENGTH * sinFromAngle; + + aimX2 = aimX1 - (aimX2 - aimX1); + + aimX1 -= 1; + aimX2 -= 1; + } + + canvas_draw_line(canvas, aimX1, aimY1 - 3, aimX2, aimY2 - 3); + + canvas_set_font(canvas, FontSecondary); + + char buffer2[12]; + snprintf(buffer2, sizeof(buffer2), "wind: %i", game_state->windSpeed - MAX_WIND / 2); + canvas_draw_str(canvas, 55, 10, buffer2); + + if(game_state->isPlayerTurn) { + canvas_draw_str(canvas, 93, 10, "player1"); + + char buffer[12]; + snprintf(buffer, sizeof(buffer), "a: %u", game_state->player.aimAngle); + canvas_draw_str(canvas, 2, 10, buffer); + + snprintf(buffer, sizeof(buffer), "p: %u", game_state->player.firePower); + canvas_draw_str(canvas, 27, 10, buffer); + } else { + canvas_draw_str(canvas, 93, 10, "player2"); + + char buffer[12]; + snprintf(buffer, sizeof(buffer), "a: %u", game_state->enemy.aimAngle); + canvas_draw_str(canvas, 2, 10, buffer); + + snprintf(buffer, sizeof(buffer), "p: %u", game_state->enemy.firePower); + canvas_draw_str(canvas, 27, 10, buffer); + } + + release_mutex((ValueMutex*)ctx, game_state); +} + +static void scorched_tanks_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { + furi_assert(event_queue); + + ScorchedTanksEvent event = {.type = EventTypeKey, .input = *input_event}; + furi_message_queue_put(event_queue, &event, FuriWaitForever); +} + +static void scorched_tanks_update_timer_callback(FuriMessageQueue* event_queue) { + furi_assert(event_queue); + + ScorchedTanksEvent event = {.type = EventTypeTick}; + furi_message_queue_put(event_queue, &event, 0); +} + +static void scorched_tanks_increase_power(Game* game_state) { + if(game_state->player.firePower < MAX_FIRE_POWER && !game_state->isShooting) { + if(game_state->isPlayerTurn && game_state->player.firePower < MAX_FIRE_POWER) { + game_state->player.firePower++; + } + + if(!game_state->isPlayerTurn && game_state->enemy.firePower < MAX_FIRE_POWER) { + game_state->enemy.firePower++; + } + } +} + +static void scorched_tanks_decrease_power(Game* game_state) { + if(game_state->player.firePower > MIN_FIRE_POWER && !game_state->isShooting) { + if(game_state->isPlayerTurn && game_state->player.firePower > MIN_FIRE_POWER) { + game_state->player.firePower--; + } + + if(!game_state->isPlayerTurn && game_state->enemy.firePower > MIN_FIRE_POWER) { + game_state->enemy.firePower--; + } + } +} + +static void scorched_tanks_aim_up(Game* game_state) { + if(!game_state->isShooting) { + if(game_state->isPlayerTurn && game_state->player.aimAngle < 90) { + game_state->player.aimAngle++; + } + + if(!game_state->isPlayerTurn && game_state->enemy.aimAngle < 90) { + game_state->enemy.aimAngle++; + } + } +} + +static void scorched_tanks_aim_down(Game* game_state) { + if(game_state->player.aimAngle > 0 && !game_state->isShooting) { + if(game_state->isPlayerTurn) { + game_state->player.aimAngle--; + } else { + game_state->enemy.aimAngle--; + } + } +} + +const NotificationSequence sequence_long_vibro = { + &message_vibro_on, + &message_delay_500, + &message_vibro_off, + NULL, +}; + +static void scorched_tanks_fire(Game* game_state) { + if(!game_state->isShooting) { + if(game_state->isPlayerTurn) { + double sinFromAngle = scorched_tanks_sin[game_state->player.aimAngle]; + double cosFromAngle = scorched_tanks_cos[game_state->player.aimAngle]; + unsigned char aimX1 = game_state->player.locationX; + unsigned char aimY1 = + game_state->ground[game_state->player.locationX].y - TANK_COLLIDER_SIZE; + int aimX2 = aimX1 + TANK_BARREL_LENGTH * cosFromAngle; + int aimY2 = aimY1 + TANK_BARREL_LENGTH * sinFromAngle; + game_state->bulletPosition.x = aimX2; + game_state->bulletPosition.y = aimY2; + game_state->bulletVector.x = scorched_tanks_cos[game_state->player.aimAngle] * + ((double)game_state->player.firePower / 10); + game_state->bulletVector.y = scorched_tanks_sin[game_state->player.aimAngle] * + ((double)game_state->player.firePower / 10); + } else { + double sinFromAngle = scorched_tanks_sin[game_state->enemy.aimAngle]; + double cosFromAngle = scorched_tanks_cos[game_state->enemy.aimAngle]; + unsigned char aimX1 = game_state->enemy.locationX; + unsigned char aimY1 = + game_state->ground[game_state->enemy.locationX].y - TANK_COLLIDER_SIZE; + int aimX2 = aimX1 + TANK_BARREL_LENGTH * cosFromAngle; + int aimY2 = aimY1 + TANK_BARREL_LENGTH * sinFromAngle; + aimX2 = aimX1 - (aimX2 - aimX1); + + game_state->bulletPosition.x = aimX2; + game_state->bulletPosition.y = aimY2; + game_state->bulletVector.x = -scorched_tanks_cos[game_state->enemy.aimAngle] * + ((double)game_state->enemy.firePower / 10); + game_state->bulletVector.y = scorched_tanks_sin[game_state->enemy.aimAngle] * + ((double)game_state->enemy.firePower / 10); + } + + game_state->trajectoryAnimationStep = 0; + + for(int x = 0; x < SCREEN_WIDTH; x++) { + game_state->trajectory[x].x = 0; + game_state->trajectory[x].y = 0; + } + + game_state->isShooting = true; + + NotificationApp* notification = furi_record_open("notification"); + notification_message(notification, &sequence_long_vibro); + notification_message(notification, &sequence_blink_white_100); + furi_record_close("notification"); + } +} + +int32_t scorched_tanks_game_app(void* p) { + UNUSED(p); + srand(DWT->CYCCNT); + + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(ScorchedTanksEvent)); + + Game* game_state = malloc(sizeof(Game)); + scorched_tanks_init_game(game_state); + + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, game_state, sizeof(ScorchedTanksEvent))) { + FURI_LOG_E("ScorchedTanks", "cannot create mutex\r\n"); + free(game_state); + return 255; + } + + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, scorched_tanks_render_callback, &state_mutex); + view_port_input_callback_set(view_port, scorched_tanks_input_callback, event_queue); + + FuriTimer* timer = + furi_timer_alloc(scorched_tanks_update_timer_callback, FuriTimerTypePeriodic, event_queue); + furi_timer_start(timer, 2000); + + // Open GUI and register view_port + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + ScorchedTanksEvent event; + for(bool processing = true; processing;) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 50); + + if(event.type == EventTypeKey) { // && game->isPlayerTurn + if(event.input.type == InputTypeRepeat || event.input.type == InputTypeShort) { + switch(event.input.key) { + case InputKeyUp: + scorched_tanks_aim_up(game_state); + break; + case InputKeyDown: + scorched_tanks_aim_down(game_state); + break; + case InputKeyRight: + scorched_tanks_increase_power(game_state); + break; + case InputKeyLeft: + scorched_tanks_decrease_power(game_state); + break; + case InputKeyOk: + scorched_tanks_fire(game_state); + break; + case InputKeyBack: + processing = false; + break; + default: + break; + } + } + } else if(event.type == EventTypeTick) { + scorched_tanks_calculate_trajectory(game_state); + } + + view_port_update(view_port); + release_mutex(&state_mutex, game_state); + } + + furi_timer_free(timer); + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + furi_record_close(RECORD_GUI); + view_port_free(view_port); + furi_message_queue_free(event_queue); + delete_mutex(&state_mutex); + free(game_state); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/scorched_tanks_v1.gif b/Applications/Official/DEV_FW/source/xMasterX/scorched_tanks/scorched_tanks_v1.gif new file mode 100644 index 0000000000000000000000000000000000000000..45b2ce117a4e9c56705397c95873c0416cf5e5bd GIT binary patch literal 139343 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/README.md b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/README.md new file mode 100644 index 000000000..2e95d1e76 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/README.md @@ -0,0 +1,55 @@ +Tama P1 Emulator for Flipper Zero +======================================= + +This is a tama P1 Emulator app for Flipper Zero, based on [TamaLIB](https://github.com/jcrona/tamalib/). + +![Alt Text](tama.gif) + +How to play +----------- +Create a `tama_p1` folder in your microSD card, and put the ROM as `rom.bin`. +Use a search engine to find the Tamagotchi ROM. There is a file named `a`. +Rename this to `rom.bin`. + +Left button is A, OK is B, and right button is C. Hold the back button to exit. +There is currently no saving, so your progress will be reset when you exit the +app. + +Building +-------- +Move this folder into flippers applications/plugins/tama_p1. + + +Launching the app, directly from console to flipper: +`./fbt launch_app APPSRC=applications\plugins\tama_p1` + +Run the following to compile icons: +``` +scripts/assets.py icons applications/tama_p1/icons applications/tama_p1/compiled +``` + +Note: you may also need to add `-Wno-unused-parameter` to `CCFLAGS` in +`site_cons/cc.scons` to suppress unused parameter errors in TamaLIB. + +Debugging +--------- +Using the serial script from [FlipperScripts](https://github.com/DroomOne/FlipperScripts/blob/main/serial_logger.py) +it is easy to add direct logging after running the appliation: +`python .\serial_logger.py` + +`./fbt launch_app APPSRC=applications\plugins\tama_p1; python .\serial_logger.py` + + +Implemented +----------- +- Basic emulation +- Input +- Sound +- Saving/Loading emaulator state (stored in `/ext/tama_p1/save.bin`) + +To-do +----- +- Slots +- In-game reset +- Test mode? +- Volume adjustment diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/application.fam b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/application.fam new file mode 100644 index 000000000..4e3c2d9af --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/application.fam @@ -0,0 +1,12 @@ +App( + appid="TAMA_P1", + name="TAMA P1", + apptype=FlipperAppType.EXTERNAL, + entry_point="tama_p1_app", + cdefines=["APP_TAMA_P1"], + requires=["gui", "storage"], + stack_size=1 * 1024, + order=215, + fap_icon="tamaIcon.png", + fap_category="Games_Extra", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/compiled/assets_icons.h b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/compiled/assets_icons.h new file mode 100644 index 000000000..aa2735b72 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/compiled/assets_icons.h @@ -0,0 +1,66 @@ +#include + +const uint8_t _I_icon_0_0[] = { + 0x01, 0x00, 0x1a, 0x00, 0x00, 0x0d, 0xaa, 0x1d, 0x7e, 0x00, 0x9c, 0x3e, 0xf9, 0x0f, 0x9e, + 0x43, 0xe3, 0x00, 0x12, 0x9c, 0x43, 0xa7, 0x10, 0xc9, 0xe4, 0x30, 0x0a, 0x31, 0x08, 0x60, +}; +const uint8_t* const _I_icon_0[] = {_I_icon_0_0}; + +const uint8_t _I_icon_1_0[] = { + 0x00, 0x00, 0x00, 0x40, 0x04, 0x04, 0x04, 0xf0, 0x11, 0xf9, 0x1b, 0xf8, 0x07, 0x8c, 0x06, + 0xed, 0x36, 0xac, 0x26, 0xe8, 0x02, 0x52, 0x0b, 0x02, 0x18, 0xe0, 0x01, 0xe0, 0x01, +}; +const uint8_t* const _I_icon_1[] = {_I_icon_1_0}; + +const uint8_t _I_icon_2_0[] = { + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x13, 0x00, 0x21, 0x3c, 0x21, 0x3e, 0x23, 0x3f, 0x9f, 0x1f, + 0xc0, 0x0f, 0xe0, 0x07, 0xf0, 0x01, 0x7c, 0x00, 0x1f, 0x00, 0x06, 0x00, 0x06, 0x00, +}; +const uint8_t* const _I_icon_2[] = {_I_icon_2_0}; + +const uint8_t _I_icon_3_0[] = { + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x1c, 0x40, 0x3a, 0xc0, 0x36, 0xf0, 0x37, 0x18, 0x2d, + 0x0c, 0x2b, 0x0e, 0x02, 0x1f, 0x06, 0x3e, 0x07, 0xfe, 0x00, 0x7f, 0x00, 0x18, 0x00, +}; +const uint8_t* const _I_icon_3[] = {_I_icon_3_0}; + +const uint8_t _I_icon_4_0[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0xc7, 0x3c, 0x82, 0x2f, 0xf2, 0x26, 0xc7, 0x2c, + 0x69, 0x28, 0x2f, 0x2c, 0xe7, 0x27, 0x02, 0x20, 0x02, 0x30, 0x06, 0x1c, 0xfc, 0x0f, +}; +const uint8_t* const _I_icon_4[] = {_I_icon_4_0}; + +const uint8_t _I_icon_5_0[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xfe, 0x0f, 0x03, 0x38, 0xc9, 0x22, 0x9a, 0x32, + 0xa2, 0x28, 0x24, 0x2c, 0x21, 0x20, 0x61, 0x30, 0x21, 0x10, 0xf3, 0x11, 0x1e, 0x0f, +}; +const uint8_t* const _I_icon_5[] = {_I_icon_5_0}; + +const uint8_t _I_icon_6_0[] = { + 0x01, 0x00, 0x17, 0x00, 0x00, 0x44, 0x62, 0xfd, 0x38, 0xbf, 0xcf, 0xb7, 0xf3, 0xf8, + 0xfc, 0x6e, 0x3f, 0x1a, 0xff, 0xc0, 0x3f, 0xf0, 0x1f, 0xf4, 0x02, 0x71, 0x00, +}; +const uint8_t* const _I_icon_6[] = {_I_icon_6_0}; + +const uint8_t _I_icon_7_0[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x41, 0x0e, 0xc4, 0x1f, 0x94, 0x20, + 0x00, 0x21, 0x22, 0x1f, 0x1d, 0x0a, 0x63, 0x20, 0xde, 0x20, 0x80, 0x1f, 0x00, 0x0e, +}; +const uint8_t* const _I_icon_7[] = {_I_icon_7_0}; + +const Icon I_icon_0 = + {.width = 14, .height = 14, .frame_count = 1, .frame_rate = 0, .frames = _I_icon_0}; +const Icon I_icon_1 = + {.width = 14, .height = 14, .frame_count = 1, .frame_rate = 0, .frames = _I_icon_1}; +const Icon I_icon_2 = + {.width = 14, .height = 14, .frame_count = 1, .frame_rate = 0, .frames = _I_icon_2}; +const Icon I_icon_3 = + {.width = 14, .height = 14, .frame_count = 1, .frame_rate = 0, .frames = _I_icon_3}; +const Icon I_icon_4 = + {.width = 14, .height = 14, .frame_count = 1, .frame_rate = 0, .frames = _I_icon_4}; +const Icon I_icon_5 = + {.width = 14, .height = 14, .frame_count = 1, .frame_rate = 0, .frames = _I_icon_5}; +const Icon I_icon_6 = + {.width = 14, .height = 14, .frame_count = 1, .frame_rate = 0, .frames = _I_icon_6}; +const Icon I_icon_7 = + {.width = 14, .height = 14, .frame_count = 1, .frame_rate = 0, .frames = _I_icon_7}; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/hal.c b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/hal.c new file mode 100644 index 000000000..211457803 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/hal.c @@ -0,0 +1,146 @@ +#include +#include +#include +#include +#include "tama.h" + +#define TAG_HAL "TamaLIB" + +static void* tama_p1_hal_malloc(u32_t size) { + return malloc(size); +} + +static void tama_p1_hal_free(void* ptr) { + free(ptr); +} + +static void tama_p1_hal_halt(void) { + g_ctx->halted = true; +} + +static bool_t tama_p1_hal_is_log_enabled(log_level_t level) { + switch(level) { + case LOG_ERROR: + return true; + case LOG_INFO: + return true; + case LOG_MEMORY: + return false; + case LOG_CPU: + return false; + default: + return false; + } +} + +static void tama_p1_hal_log(log_level_t level, char* buff, ...) { + if(!tama_p1_hal_is_log_enabled(level)) return; + + FuriString* string = furi_string_alloc(); + va_list args; + va_start(args, buff); + furi_string_cat_vprintf(string, buff, args); + va_end(args); + + switch(level) { + case LOG_ERROR: + FURI_LOG_E(TAG_HAL, "%s", furi_string_get_cstr(string)); + break; + case LOG_INFO: + FURI_LOG_I(TAG_HAL, "%s", furi_string_get_cstr(string)); + break; + case LOG_MEMORY: + break; + case LOG_CPU: + FURI_LOG_D(TAG_HAL, "%s", furi_string_get_cstr(string)); + break; + default: + FURI_LOG_D(TAG_HAL, "%s", furi_string_get_cstr(string)); + break; + } + + furi_string_free(string); +} + +static void tama_p1_hal_sleep_until(timestamp_t ts) { + while(true) { + uint32_t count = LL_TIM_GetCounter(TIM2); + uint32_t delay = ts - count; + // FURI_LOG_D(TAG, "delay: %x", delay); + // Stolen from furi_delay_until_tick + if(delay != 0 && 0 == (delay >> (8 * sizeof(uint32_t) - 1))) { + // Not the best place to release mutex, but this is the only place we know whether + // we're ahead or behind, otherwise around the step call we'll always have to + // delay a tick and run more and more behind. + furi_mutex_release(g_state_mutex); + furi_delay_tick(1); + while(furi_mutex_acquire(g_state_mutex, FuriWaitForever) != FuriStatusOk) + furi_delay_tick(1); + } else { + break; + } + } +} + +static timestamp_t tama_p1_hal_get_timestamp(void) { + return LL_TIM_GetCounter(TIM2); +} + +static void tama_p1_hal_update_screen(void) { + // Do nothing, covered by main loop +} + +static void tama_p1_hal_set_lcd_matrix(u8_t x, u8_t y, bool_t val) { + if(val) + g_ctx->framebuffer[y] |= 1 << x; + else + g_ctx->framebuffer[y] &= ~(1 << x); +} + +static void tama_p1_hal_set_lcd_icon(u8_t icon, bool_t val) { + if(val) + g_ctx->icons |= 1 << icon; + else + g_ctx->icons &= ~(1 << icon); +} + +static void tama_p1_hal_play_frequency(bool_t en) { + if(en) { + if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) { + furi_hal_speaker_start(g_ctx->frequency, 0.5f); + } + } else { + if(furi_hal_speaker_is_mine()) { + furi_hal_speaker_stop(); + furi_hal_speaker_release(); + } + } + + g_ctx->buzzer_on = en; +} + +static void tama_p1_hal_set_frequency(u32_t freq) { + g_ctx->frequency = freq / 10.0F; + if(g_ctx->buzzer_on) tama_p1_hal_play_frequency(true); +} + +static int tama_p1_hal_handler(void) { + // Do nothing + return 0; +} + +void tama_p1_hal_init(hal_t* hal) { + hal->malloc = tama_p1_hal_malloc; + hal->free = tama_p1_hal_free; + hal->halt = tama_p1_hal_halt; + hal->is_log_enabled = tama_p1_hal_is_log_enabled; + hal->log = tama_p1_hal_log; + hal->sleep_until = tama_p1_hal_sleep_until; + hal->get_timestamp = tama_p1_hal_get_timestamp; + hal->update_screen = tama_p1_hal_update_screen; + hal->set_lcd_matrix = tama_p1_hal_set_lcd_matrix; + hal->set_lcd_icon = tama_p1_hal_set_lcd_icon; + hal->set_frequency = tama_p1_hal_set_frequency; + hal->play_frequency = tama_p1_hal_play_frequency; + hal->handler = tama_p1_hal_handler; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/hal_types.h b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/hal_types.h new file mode 100644 index 000000000..d27e6dfbe --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/hal_types.h @@ -0,0 +1,35 @@ +/* + * TamaLIB - A hardware agnostic tama P1 emulation library + * + * Copyright (C) 2021 Jean-Christophe Rona + * + * 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 2 + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _HAL_TYPES_H_ +#define _HAL_TYPES_H_ + +#include + +typedef bool bool_t; +typedef uint8_t u4_t; +typedef uint8_t u5_t; +typedef uint8_t u8_t; +typedef uint16_t u12_t; +typedef uint16_t u13_t; +typedef uint32_t u32_t; +typedef uint32_t + timestamp_t; // WARNING: Must be an unsigned type to properly handle wrapping (u32 wraps in around 1h11m when expressed in us) + +#endif /* _HAL_TYPES_H_ */ diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/icons/icon_0.png b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/icons/icon_0.png new file mode 100644 index 0000000000000000000000000000000000000000..7b94d3511b0d0880983be8ea1018c6c213daa10f GIT binary patch literal 641 zcmV-{0)G98P)EX>4Tx04R}tkv&MmP!xqvQ%j3f9PA+CkfAzR5EbbtRV;#q(pG5I!Q`cX(4-+r zad8w}3l9D)RvlcNb#-tR1i>E=M<*vm7b)?+q|hS93y=44-aVK1&I5#2jj3keB%o@R zkx3@Rd|_1#z9Ix40uT|Gn5n0-i#d4K*FE)8-NpDU@4i24Kq;CG@QK88OgAjz4dU5N zOXs{#9AOnnAwDObFzABBk6f2se&bwrSl}}wMlLf?93d9VJuLSys~9Tr3~^LZHJUHv zT~;`6aaL;$*10EtVYsNRWVudj6iF;0g*0U(qk$@Fun?nNBgI69&J!N~5yzhUyL|%qpMfi_>#w(f_$TSj zt`#ip60hc?#@RKeXk|X(P38fP7en#I^0ETXX{xvtZ&N)sWfE;DDd;=UD z0^?y{D4^000SaNLh0L z02PP;02PP<#MeNe00007bV*G`2j&O?1uYD#QmV87000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}00013NklHNafyg%!YNt{tHg$FO@~w bMKaL^NQ@#O_FW8V00000NkvXXu0mjfZXE#k literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/icons/icon_1.png b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/icons/icon_1.png new file mode 100644 index 0000000000000000000000000000000000000000..934cf7187c8d9fc3c03f14ae59b76c1a37e9e13e GIT binary patch literal 658 zcmV;D0&V??P)EX>4Tx04R}tkv&MmP!xqvQ%j3f9PA+CkfAzR5EbbtRV;#q(pG5I!Q`cX(4-+r zad8w}3l9D)RvlcNb#-tR1i>E=M<*vm7b)?+q|hS93y=44-aVK1&I5#2jj3keB%o@R zkx3@Rd|_1#z9Ix40uT|Gn5n0-i#d4K*FE)8-NpDU@4i24Kq;CG@QK88OgAjz4dU5N zOXs{#9AOnnAwDObFzABBk6f2se&bwrSl}}wMlLf?93d9VJuLSys~9Tr3~^LZHJUHv zT~;`6aaL;$*10EtVYsNRWVudj6iF;0g*0U(qk$@Fun?nNBgI69&J!N~5yzhUyL|%qpMfi_>#w(f_$TSj zt`#ip60hc?#@RKeXk|X(P38fP7en#I^0ETXX{xvtZ&N)sWfE;DDd;=UD z0^?y{D4^000SaNLh0L z02PP;02PP<#MeNe00007bV*G`2j&O?1uYXMTBkt(000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}0001KNkl(V|K;7oQ4C3ogb1CknL?7{ z!B_zRTAvkg5`ru>6J!zqAt~sIyCRP}K5qYJzEt)oX`Qauk(oNlj}17K%V3A$Ti^8f$<07*qoM6N<$f?lc!Y5)KL literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/icons/icon_2.png b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/icons/icon_2.png new file mode 100644 index 0000000000000000000000000000000000000000..b83e449d92cad47c353224f00f5798d3f3d2279b GIT binary patch literal 652 zcmV;70(1R|P)EX>4Tx04R}tkv&MmP!xqvQ%j3f9PA+CkfAzR5EbbtRV;#q(pG5I!Q`cX(4-+r zad8w}3l9D)RvlcNb#-tR1i>E=M<*vm7b)?+q|hS93y=44-aVK1&I5#2jj3keB%o@R zkx3@Rd|_1#z9Ix40uT|Gn5n0-i#d4K*FE)8-NpDU@4i24Kq;CG@QK88OgAjz4dU5N zOXs{#9AOnnAwDObFzABBk6f2se&bwrSl}}wMlLf?93d9VJuLSys~9Tr3~^LZHJUHv zT~;`6aaL;$*10EtVYsNRWVudj6iF;0g*0U(qk$@Fun?nNBgI69&J!N~5yzhUyL|%qpMfi_>#w(f_$TSj zt`#ip60hc?#@RKeXk|X(P38fP7en#I^0ETXX{xvtZ&N)sWfE;DDd;=UD z0^?y{D4^000SaNLh0L z02PP;02PP<#MeNe00007bV*G`2j&O?1uY<%ipEy}000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}0001ENklR2m`0a|9`oA*u>xlm9EX>4Tx04R}tkv&MmP!xqvQ%j3f9PA+CkfAzR5EbbtRV;#q(pG5I!Q`cX(4-+r zad8w}3l9D)RvlcNb#-tR1i>E=M<*vm7b)?+q|hS93y=44-aVK1&I5#2jj3keB%o@R zkx3@Rd|_1#z9Ix40uT|Gn5n0-i#d4K*FE)8-NpDU@4i24Kq;CG@QK88OgAjz4dU5N zOXs{#9AOnnAwDObFzABBk6f2se&bwrSl}}wMlLf?93d9VJuLSys~9Tr3~^LZHJUHv zT~;`6aaL;$*10EtVYsNRWVudj6iF;0g*0U(qk$@Fun?nNBgI69&J!N~5yzhUyL|%qpMfi_>#w(f_$TSj zt`#ip60hc?#@RKeXk|X(P38fP7en#I^0ETXX{xvtZ&N)sWfE;DDd;=UD z0^?y{D4^000SaNLh0L z02PP;02PP<#MeNe00007bV*G`2j&O?1uZ8B?o;#t000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}0001INklEX>4Tx04R}tkv&MmP!xqvQ%j3f9PA+CkfAzR5EbbtRV;#q(pG5I!Q`cX(4-+r zad8w}3l9D)RvlcNb#-tR1i>E=M<*vm7b)?+q|hS93y=44-aVK1&I5#2jj3keB%o@R zkx3@Rd|_1#z9Ix40uT|Gn5n0-i#d4K*FE)8-NpDU@4i24Kq;CG@QK88OgAjz4dU5N zOXs{#9AOnnAwDObFzABBk6f2se&bwrSl}}wMlLf?93d9VJuLSys~9Tr3~^LZHJUHv zT~;`6aaL;$*10EtVYsNRWVudj6iF;0g*0U(qk$@Fun?nNBgI69&J!N~5yzhUyL|%qpMfi_>#w(f_$TSj zt`#ip60hc?#@RKeXk|X(P38fP7en#I^0ETXX{xvtZ&N)sWfE;DDd;=UD z0^?y{D4^000SaNLh0L z02PP;02PP<#MeNe00007bV*G`2j&O?1uZayJ=QY-000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}0001NNklG}Dovi1ix}Mk-MfG{!JO00000NkvXXu0mjfdoTlh literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/icons/icon_5.png b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/icons/icon_5.png new file mode 100644 index 0000000000000000000000000000000000000000..889acd50eef9156801ed8455ad0240587ee17199 GIT binary patch literal 664 zcmV;J0%!e+P)EX>4Tx04R}tkv&MmP!xqvQ%j3f9PA+CkfAzR5EbbtRV;#q(pG5I!Q`cX(4-+r zad8w}3l9D)RvlcNb#-tR1i>E=M<*vm7b)?+q|hS93y=44-aVK1&I5#2jj3keB%o@R zkx3@Rd|_1#z9Ix40uT|Gn5n0-i#d4K*FE)8-NpDU@4i24Kq;CG@QK88OgAjz4dU5N zOXs{#9AOnnAwDObFzABBk6f2se&bwrSl}}wMlLf?93d9VJuLSys~9Tr3~^LZHJUHv zT~;`6aaL;$*10EtVYsNRWVudj6iF;0g*0U(qk$@Fun?nNBgI69&J!N~5yzhUyL|%qpMfi_>#w(f_$TSj zt`#ip60hc?#@RKeXk|X(P38fP7en#I^0ETXX{xvtZ&N)sWfE;DDd;=UD z0^?y{D4^000SaNLh0L z02PP;02PP<#MeNe00007bV*G`2j&O?1uZukSwoNj000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}0001QNklR2m>kc|6iUxVO#`F9oR0M6a?=BpmVX39M}gSl1L%@J{z9^0000EX>4Tx04R}tkv&MmP!xqvQ%j3f9PA+CkfAzR5EbbtRV;#q(pG5I!Q`cX(4-+r zad8w}3l9D)RvlcNb#-tR1i>E=M<*vm7b)?+q|hS93y=44-aVK1&I5#2jj3keB%o@R zkx3@Rd|_1#z9Ix40uT|Gn5n0-i#d4K*FE)8-NpDU@4i24Kq;CG@QK88OgAjz4dU5N zOXs{#9AOnnAwDObFzABBk6f2se&bwrSl}}wMlLf?93d9VJuLSys~9Tr3~^LZHJUHv zT~;`6aaL;$*10EtVYsNRWVudj6iF;0g*0U(qk$@Fun?nNBgI69&J!N~5yzhUyL|%qpMfi_>#w(f_$TSj zt`#ip60hc?#@RKeXk|X(P38fP7en#I^0ETXX{xvtZ&N)sWfE;DDd;=UD z0^?y{D4^000SaNLh0L z02PP;02PP<#MeNe00007bV*G`2j&O?1ug>+z~trt000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}00012NkleL|G%7`3Luy^KPO5;5&-!&zA)t`iJVA%u_LEt+nhw>WU*T9^);OFPQV*tY=QxZ+pA9Vti!5) a6MO(f*eMmVIZP)20000EX>4Tx04R}tkv&MmP!xqvQ%j3f9PA+CkfAzR5EbbtRV;#q(pG5I!Q`cX(4-+r zad8w}3l9D)RvlcNb#-tR1i>E=M<*vm7b)?+q|hS93y=44-aVK1&I5#2jj3keB%o@R zkx3@Rd|_1#z9Ix40uT|Gn5n0-i#d4K*FE)8-NpDU@4i24Kq;CG@QK88OgAjz4dU5N zOXs{#9AOnnAwDObFzABBk6f2se&bwrSl}}wMlLf?93d9VJuLSys~9Tr3~^LZHJUHv zT~;`6aaL;$*10EtVYsNRWVudj6iF;0g*0U(qk$@Fun?nNBgI69&J!N~5yzhUyL|%qpMfi_>#w(f_$TSj zt`#ip60hc?#@RKeXk|X(P38fP7en#I^0ETXX{xvtZ&N)sWfE;DDd;=UD z0^?y{D4^000SaNLh0L z02PP;02PP<#MeNe00007bV*G`2j&O?1uhZed6ljJ000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}0001QNkl +#include "tamalib/tamalib.h" + +#define TAG "TamaP1" +#define TAMA_ROM_PATH EXT_PATH("tama_p1/rom.bin") +#define TAMA_SCREEN_SCALE_FACTOR 2 +#define TAMA_LCD_ICON_SIZE 14 +#define TAMA_LCD_ICON_MARGIN 1 + +#define STATE_FILE_MAGIC "TLST" +#define STATE_FILE_VERSION 2 +#define TAMA_SAVE_PATH EXT_PATH("tama_p1/save.bin") + + +typedef struct { + FuriThread* thread; + hal_t hal; + uint8_t* rom; + // 32x16 screen, perfectly represented through uint32_t + uint32_t framebuffer[16]; + uint8_t icons; + bool halted; + bool fast_forward_done; + bool buzzer_on; + float frequency; +} TamaApp; + +typedef enum { + EventTypeInput, + EventTypeTick, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} TamaEvent; + +extern TamaApp* g_ctx; +extern FuriMutex* g_state_mutex; + +void tama_p1_hal_init(hal_t* hal); diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamaIcon.png b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamaIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..1962b68aecb344c3cf50c1826d8bd72fa221e411 GIT binary patch literal 1924 zcmcIlPjBNy6!*5Jbc-q>!~p>ZulE9MCmv5?JGPQ7Y13{Z)un2KTEwN}nQ>w@@fh1} z(n@eZT#%6VgCMQM6%I(tfg2q76i7&XftAX0oMeMky18J#-gvCm?;WZTHho^76ps&Gt^>Dwl zdvkLG(@&rO@f8gBRM-Cg>1Rz1d0jg(J?zChq8GNV6LEZf&|%l-%;DPBQm2n-tQ#eq$2L{;yt`Eg zgPC@k?OuYFiPN_Nr=6=<=tm-z7YP%)mmL7;luM@i!ATf#IZQvyJ(_F~O`3_imRAp9 z2N`C^uv~1qW%3A@U5pD=4+z0&Mi*0-JPfWDQT05x9iRX%Qm>d ziKf1^yCeHD@g#@rmNk_#H;~DI0)N5*?Fv1Px>HI6slf;Y(+X3l;MKTYiryJF&9V4m zPBdwOeyEQ5=u(!qL0w~c{RP)1;_#NlE*3%oJM0Mny@MBpS}KEVNE6ZMLJ?lgJAHvb zQhIrJ7>n`a{|uwRW<45p1)Q|df%AdY^!!YkuUbvNy}-4XbeU4F0nL!JAf3z9m<8Lk zJ13g4;PI57l$NKEhC3iY*Y=fj~EXKC$_=tz$!fJhjT!MXdb+#zuK!}*W58Y zMl7Uo#={Cip58F|YIaMB2ojdS9rVlh@3r9m+H5x)op(;y+1bkSDpro)Tsl}X*0y_V sALGW`9lN>GdcME>(b9u&-rCz!?i1zFcVGUxnO}VE-Gk<{?X$1{0R&<;i~s-t literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tama_p1.c b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tama_p1.c new file mode 100644 index 000000000..7184638d7 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tama_p1.c @@ -0,0 +1,530 @@ +#include +#include +#include +#include +#include +#include +#include "tamalib/tamalib.h" +#include "tama.h" +#include "compiled/assets_icons.h" + +TamaApp* g_ctx; +FuriMutex* g_state_mutex; + +static const Icon* icons_list[] = { + &I_icon_0, + &I_icon_1, + &I_icon_2, + &I_icon_3, + &I_icon_4, + &I_icon_5, + &I_icon_6, + &I_icon_7, +}; + +static void tama_p1_draw_callback(Canvas* const canvas, void* cb_ctx) { + furi_assert(cb_ctx); + + FuriMutex* const mutex = cb_ctx; + if(furi_mutex_acquire(mutex, 25) != FuriStatusOk) return; + + if(g_ctx->rom == NULL) { + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 30, 30, "No ROM"); + } else if(g_ctx->halted) { + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 30, 30, "Halted"); + } else { + // FURI_LOG_D(TAG, "Drawing frame"); + // Calculate positioning + uint16_t canv_width = canvas_width(canvas); + uint16_t canv_height = canvas_height(canvas); + uint16_t lcd_matrix_scaled_width = 32 * TAMA_SCREEN_SCALE_FACTOR; + uint16_t lcd_matrix_scaled_height = 16 * TAMA_SCREEN_SCALE_FACTOR; + // uint16_t lcd_matrix_top = 0; + uint16_t lcd_matrix_top = (canv_height - lcd_matrix_scaled_height) / 2; + uint16_t lcd_matrix_left = (canv_width - lcd_matrix_scaled_width) / 2; + + uint16_t lcd_icon_upper_top = lcd_matrix_top - TAMA_LCD_ICON_SIZE - TAMA_LCD_ICON_MARGIN; + uint16_t lcd_icon_upper_left = lcd_matrix_left; + uint16_t lcd_icon_lower_top = + lcd_matrix_top + lcd_matrix_scaled_height + TAMA_LCD_ICON_MARGIN; + uint16_t lcd_icon_lower_left = lcd_matrix_left; + uint16_t lcd_icon_spacing_horiz = + (lcd_matrix_scaled_width - (4 * TAMA_LCD_ICON_SIZE)) / 3 + TAMA_LCD_ICON_SIZE; + + + uint16_t y = lcd_matrix_top; + for(uint8_t row = 0; row < 16; ++row) { + uint16_t x = lcd_matrix_left; + uint32_t row_pixels = g_ctx->framebuffer[row]; + for(uint8_t col = 0; col < 32; ++col) { + if(row_pixels & 1) { + canvas_draw_box( + canvas, x, y, TAMA_SCREEN_SCALE_FACTOR, TAMA_SCREEN_SCALE_FACTOR); + } + x += TAMA_SCREEN_SCALE_FACTOR; + row_pixels >>= 1; + } + y += TAMA_SCREEN_SCALE_FACTOR; + } + + // Start drawing icons + uint8_t lcd_icons = g_ctx->icons; + + // Draw top icons + y = lcd_icon_upper_top; + // y = 64 - TAMA_LCD_ICON_SIZE; + uint16_t x_ic = lcd_icon_upper_left; + for(uint8_t i = 0; i < 4; ++i) { + if(lcd_icons & 1) { + canvas_draw_icon(canvas, x_ic, y, icons_list[i]); + } + // x_ic += TAMA_LCD_ICON_SIZE + 4; + x_ic += lcd_icon_spacing_horiz; + lcd_icons >>= 1; + } + + // Draw bottom icons + y = lcd_icon_lower_top; + x_ic = lcd_icon_lower_left; + for(uint8_t i = 4; i < 8; ++i) { + // canvas_draw_frame(canvas, x_ic, y, TAMA_LCD_ICON_SIZE, TAMA_LCD_ICON_SIZE); + if(lcd_icons & 1) { + canvas_draw_icon(canvas, x_ic, y, icons_list[i]); + } + x_ic += lcd_icon_spacing_horiz; + lcd_icons >>= 1; + } + } + + furi_mutex_release(mutex); +} + +static void tama_p1_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { + furi_assert(event_queue); + + TamaEvent event = {.type = EventTypeInput, .input = *input_event}; + furi_message_queue_put(event_queue, &event, FuriWaitForever); +} + +static void tama_p1_update_timer_callback(FuriMessageQueue* event_queue) { + furi_assert(event_queue); + + TamaEvent event = {.type = EventTypeTick}; + furi_message_queue_put(event_queue, &event, 0); +} + +static void tama_p1_load_state() { + state_t *state; + uint8_t buf[4]; + bool error = false; + state = tamalib_get_state(); + + Storage* storage = furi_record_open(RECORD_STORAGE); + File* file = storage_file_alloc(storage); + if(storage_file_open(file, TAMA_SAVE_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) { + + storage_file_read(file, &buf, 4); + if (buf[0] != (uint8_t) STATE_FILE_MAGIC[0] || buf[1] != (uint8_t) STATE_FILE_MAGIC[1] || + buf[2] != (uint8_t) STATE_FILE_MAGIC[2] || buf[3] != (uint8_t) STATE_FILE_MAGIC[3]) { + FURI_LOG_E(TAG, "FATAL: Wrong state file magic in \"%s\" !\n", TAMA_SAVE_PATH); + error = true; + } + + storage_file_read(file, &buf, 1); + if (buf[0] != STATE_FILE_VERSION) { + FURI_LOG_E(TAG, "FATAL: Unsupported version"); + error = true; + } + if (!error) { + FURI_LOG_D(TAG, "Reading save.bin"); + + storage_file_read(file, &buf, 2); + *(state->pc) = buf[0] | ((buf[1] & 0x1F) << 8); + + storage_file_read(file, &buf, 2); + *(state->x) = buf[0] | ((buf[1] & 0xF) << 8); + + storage_file_read(file, &buf, 2); + *(state->y) = buf[0] | ((buf[1] & 0xF) << 8); + + storage_file_read(file, &buf, 1); + *(state->a) = buf[0] & 0xF; + + storage_file_read(file, &buf, 1); + *(state->b) = buf[0] & 0xF; + + storage_file_read(file, &buf, 1); + *(state->np) = buf[0] & 0x1F; + + storage_file_read(file, &buf, 1); + *(state->sp) = buf[0]; + + storage_file_read(file, &buf, 1); + *(state->flags) = buf[0] & 0xF; + + storage_file_read(file, &buf, 4); + *(state->tick_counter) = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + + storage_file_read(file, &buf, 4); + *(state->clk_timer_timestamp) = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + + storage_file_read(file, &buf, 4); + *(state->prog_timer_timestamp) = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + + storage_file_read(file, &buf, 1); + *(state->prog_timer_enabled) = buf[0] & 0x1; + + storage_file_read(file, &buf, 1); + *(state->prog_timer_data) = buf[0]; + + storage_file_read(file, &buf, 1); + *(state->prog_timer_rld) = buf[0]; + + storage_file_read(file, &buf, 4); + *(state->call_depth) = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + + FURI_LOG_D(TAG, "Restoring Interupts"); + for (uint32_t i = 0; i < INT_SLOT_NUM; i++) { + storage_file_read(file, &buf, 1); + state->interrupts[i].factor_flag_reg = buf[0] & 0xF; + + storage_file_read(file, &buf, 1); + state->interrupts[i].mask_reg = buf[0] & 0xF; + + storage_file_read(file, &buf, 1); + state->interrupts[i].triggered = buf[0] & 0x1; + } + + /* First 640 half bytes correspond to the RAM */ + FURI_LOG_D(TAG, "Restoring RAM"); + for (uint32_t i = 0; i < MEM_RAM_SIZE; i++) { + storage_file_read(file, &buf, 1); + SET_RAM_MEMORY(state->memory, i + MEM_RAM_ADDR, buf[0] & 0xF); + } + + /* I/Os are from 0xF00 to 0xF7F */ + FURI_LOG_D(TAG, "Restoring I/O"); + for (uint32_t i = 0; i < MEM_IO_SIZE; i++) { + storage_file_read(file, &buf, 1); + SET_IO_MEMORY(state->memory, i + MEM_IO_ADDR, buf[0] & 0xF); + } + FURI_LOG_D(TAG, "Refreshing Hardware"); + tamalib_refresh_hw(); + } + } + + storage_file_close(file); + storage_file_free(file); + furi_record_close(RECORD_STORAGE); +} + + +static void tama_p1_save_state() { + + // Saving state + FURI_LOG_D(TAG, "Saving Gamestate"); + uint8_t buf[4]; + state_t *state; + uint32_t offset = 0; + state = tamalib_get_state(); + + Storage* storage = furi_record_open(RECORD_STORAGE); + File* file = storage_file_alloc(storage); + + if(storage_file_open(file, TAMA_SAVE_PATH, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + buf[0] = (uint8_t) STATE_FILE_MAGIC[0]; + buf[1] = (uint8_t) STATE_FILE_MAGIC[1]; + buf[2] = (uint8_t) STATE_FILE_MAGIC[2]; + buf[3] = (uint8_t) STATE_FILE_MAGIC[3]; + offset += storage_file_write(file, &buf, sizeof(buf)); + + buf[0] = STATE_FILE_VERSION & 0xFF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->pc) & 0xFF; + buf[1] = (*(state->pc) >> 8) & 0x1F; + offset += storage_file_write(file, &buf, 2); + + buf[0] = *(state->x) & 0xFF; + buf[1] = (*(state->x) >> 8) & 0xF; + offset += storage_file_write(file, &buf, 2); + + buf[0] = *(state->y) & 0xFF; + buf[1] = (*(state->y) >> 8) & 0xF; + offset += storage_file_write(file, &buf, 2); + + buf[0] = *(state->a) & 0xF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->b) & 0xF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->np) & 0x1F; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->sp) & 0xFF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->flags) & 0xF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->tick_counter) & 0xFF; + buf[1] = (*(state->tick_counter) >> 8) & 0xFF; + buf[2] = (*(state->tick_counter) >> 16) & 0xFF; + buf[3] = (*(state->tick_counter) >> 24) & 0xFF; + offset += storage_file_write(file, &buf, sizeof(buf)); + + buf[0] = *(state->clk_timer_timestamp) & 0xFF; + buf[1] = (*(state->clk_timer_timestamp) >> 8) & 0xFF; + buf[2] = (*(state->clk_timer_timestamp) >> 16) & 0xFF; + buf[3] = (*(state->clk_timer_timestamp) >> 24) & 0xFF; + offset += storage_file_write(file, &buf, sizeof(buf)); + + buf[0] = *(state->prog_timer_timestamp) & 0xFF; + buf[1] = (*(state->prog_timer_timestamp) >> 8) & 0xFF; + buf[2] = (*(state->prog_timer_timestamp) >> 16) & 0xFF; + buf[3] = (*(state->prog_timer_timestamp) >> 24) & 0xFF; + offset += storage_file_write(file, &buf, sizeof(buf)); + + buf[0] = *(state->prog_timer_enabled) & 0x1; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->prog_timer_data) & 0xFF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->prog_timer_rld) & 0xFF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->call_depth) & 0xFF; + buf[1] = (*(state->call_depth) >> 8) & 0xFF; + buf[2] = (*(state->call_depth) >> 16) & 0xFF; + buf[3] = (*(state->call_depth) >> 24) & 0xFF; + offset += storage_file_write(file, &buf, sizeof(buf)); + + for (uint32_t i = 0; i < INT_SLOT_NUM; i++) { + buf[0] = state->interrupts[i].factor_flag_reg & 0xF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = state->interrupts[i].mask_reg & 0xF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = state->interrupts[i].triggered & 0x1; + offset += storage_file_write(file, &buf, 1); + } + + /* First 640 half bytes correspond to the RAM */ + for (uint32_t i = 0; i < MEM_RAM_SIZE; i++) { + buf[0] = GET_RAM_MEMORY(state->memory, i + MEM_RAM_ADDR) & 0xF; + offset += storage_file_write(file, &buf, 1); + } + + /* I/Os are from 0xF00 to 0xF7F */ + for (uint32_t i = 0; i < MEM_IO_SIZE; i++) { + buf[0] = GET_IO_MEMORY(state->memory, i + MEM_IO_ADDR) & 0xF; + offset += storage_file_write(file, &buf, 1); + } + } + storage_file_close(file); + storage_file_free(file); + furi_record_close(RECORD_STORAGE); + + FURI_LOG_D(TAG, "Finished Writing %lu", offset); +} + + +static int32_t tama_p1_worker(void* context) { + bool running = true; + FuriMutex* mutex = context; + while(furi_mutex_acquire(mutex, FuriWaitForever) != FuriStatusOk) furi_delay_tick(1); + + cpu_sync_ref_timestamp(); + LL_TIM_EnableCounter(TIM2); + + tama_p1_load_state(); + + while(running) { + if(furi_thread_flags_get()) { + running = false; + } else { + // FURI_LOG_D(TAG, "Stepping"); + // for (int i = 0; i < 100; ++i) + tamalib_step(); + } + } + LL_TIM_DisableCounter(TIM2); + furi_mutex_release(mutex); + return 0; +} + + + +static void tama_p1_init(TamaApp* const ctx) { + g_ctx = ctx; + memset(ctx, 0, sizeof(TamaApp)); + tama_p1_hal_init(&ctx->hal); + + // Load ROM + Storage* storage = furi_record_open(RECORD_STORAGE); + FileInfo fi; + if(storage_common_stat(storage, TAMA_ROM_PATH, &fi) == FSE_OK) { + File* rom_file = storage_file_alloc(storage); + if(storage_file_open(rom_file, TAMA_ROM_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) { + ctx->rom = malloc((size_t)fi.size); + uint8_t* buf_ptr = ctx->rom; + size_t read = 0; + while(read < fi.size) { + size_t to_read = fi.size - read; + if(to_read > UINT16_MAX) to_read = UINT16_MAX; + uint16_t now_read = storage_file_read(rom_file, buf_ptr, (uint16_t)to_read); + read += now_read; + buf_ptr += now_read; + } + + // Reorder endianess of ROM + for(size_t i = 0; i < fi.size; i += 2) { + uint8_t b = ctx->rom[i]; + ctx->rom[i] = ctx->rom[i + 1]; + ctx->rom[i + 1] = b & 0xF; + } + } + + storage_file_close(rom_file); + storage_file_free(rom_file); + } + furi_record_close(RECORD_STORAGE); + + if(ctx->rom != NULL) { + // Init TIM2 + // 64KHz + LL_TIM_InitTypeDef tim_init = { + .Prescaler = 999, + .CounterMode = LL_TIM_COUNTERMODE_UP, + .Autoreload = 0xFFFFFFFF, + }; + LL_TIM_Init(TIM2, &tim_init); + LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); + LL_TIM_DisableCounter(TIM2); + LL_TIM_SetCounter(TIM2, 0); + + // Init TamaLIB + tamalib_register_hal(&ctx->hal); + tamalib_init((u12_t*)ctx->rom, NULL, 64000); + tamalib_set_speed(1); + + // TODO: implement fast forwarding + ctx->fast_forward_done = true; + + // Start stepping thread + ctx->thread = furi_thread_alloc(); + furi_thread_set_name(ctx->thread, "TamaLIB"); + furi_thread_set_stack_size(ctx->thread, 1024); + furi_thread_set_callback(ctx->thread, tama_p1_worker); + furi_thread_set_context(ctx->thread, g_state_mutex); + furi_thread_start(ctx->thread); + } +} + +static void tama_p1_deinit(TamaApp* const ctx) { + if(ctx->rom != NULL) { + tamalib_release(); + furi_thread_free(ctx->thread); + free(ctx->rom); + } +} + +int32_t tama_p1_app(void* p) { + UNUSED(p); + + TamaApp* ctx = malloc(sizeof(TamaApp)); + g_state_mutex = furi_mutex_alloc(FuriMutexTypeRecursive); + tama_p1_init(ctx); + + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(TamaEvent)); + + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, tama_p1_draw_callback, g_state_mutex); + view_port_input_callback_set(view_port, tama_p1_input_callback, event_queue); + + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + FuriTimer* timer = + furi_timer_alloc(tama_p1_update_timer_callback, FuriTimerTypePeriodic, event_queue); + furi_timer_start(timer, furi_kernel_get_tick_frequency() / 30); + + for(bool running = true; running;) { + TamaEvent event; + FuriStatus event_status = furi_message_queue_get(event_queue, &event, FuriWaitForever); + if(event_status == FuriStatusOk) { + // Local override with acquired context + if(furi_mutex_acquire(g_state_mutex, FuriWaitForever) != FuriStatusOk) continue; + + if(event.type == EventTypeTick) { + // FURI_LOG_D(TAG, "EventTypeTick"); + view_port_update(view_port); + } else if(event.type == EventTypeInput) { + FURI_LOG_D( + TAG, + "EventTypeInput: %ld %d %d", + event.input.sequence, + event.input.key, + event.input.type); + InputType input_type = event.input.type; + if(input_type == InputTypePress || input_type == InputTypeRelease) { + btn_state_t tama_btn_state = 0; + if(input_type == InputTypePress) + tama_btn_state = BTN_STATE_PRESSED; + else if(input_type == InputTypeRelease) + tama_btn_state = BTN_STATE_RELEASED; + + if(event.input.key == InputKeyLeft) { + tamalib_set_button(BTN_LEFT, tama_btn_state); + } else if(event.input.key == InputKeyOk) { + tamalib_set_button(BTN_MIDDLE, tama_btn_state); + } else if(event.input.key == InputKeyRight) { + tamalib_set_button(BTN_RIGHT, tama_btn_state); + } else if(event.input.key == InputKeyDown && event.input.type == InputTypeShort) { + // TODO: pause or fast-forward tamagotchi + tama_p1_save_state(); + } else if(event.input.key == InputKeyUp) { // mute tamagotchi + tamalib_set_button(BTN_LEFT, tama_btn_state); + tamalib_set_button(BTN_RIGHT, tama_btn_state); + } else if(event.input.key == InputKeyBack && event.input.type == InputTypeShort) { + tama_p1_save_state(); + } + } + + if(event.input.key == InputKeyBack && event.input.type == InputTypeLong) { + furi_timer_stop(timer); + running = false; + + tama_p1_save_state(); + } + } + + furi_mutex_release(g_state_mutex); + } else { + // Timeout + // FURI_LOG_D(TAG, "Timed out"); + } + } + + if(ctx->rom != NULL) { + furi_thread_flags_set(furi_thread_get_id(ctx->thread), 1); + furi_thread_join(ctx->thread); + } + + furi_timer_free(timer); + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + furi_record_close(RECORD_GUI); + view_port_free(view_port); + furi_message_queue_free(event_queue); + furi_mutex_free(g_state_mutex); + tama_p1_deinit(ctx); + free(ctx); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/LICENSE new file mode 100644 index 000000000..d159169d1 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 2 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. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/README.md b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/README.md new file mode 100644 index 000000000..add42da1a --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/README.md @@ -0,0 +1,64 @@ +# TamaLIB - A hardware agnostic Tamagotchi P1 emulation library + + +## Synopsis + +TamaLib is a hardware agnostic Tamagotchi P1 emulation library built from scratch. It is self-contained and aims at running on any platform powerful enough, from microcontrollers (MCUs) to desktop computers, thus spreading virtual life across the digital world. + +So far, it has been successfully implemented on different platforms: +- Desktop computers (check out [TamaTool](https://github.com/jcrona/tamatool/) for more information) +- STM32F072 MCU based board (check out [MCUGotchi](https://github.com/jcrona/mcugotchi/) for more information). +- OpenTama which is an STM32L072 MCU based board (check out [OpenTama](https://github.com/Sparkr-tech/opentama) and [MCUGotchi](https://github.com/jcrona/mcugotchi/) for more information). +- Arduino UNO (check out [ArduinoGotchi](https://github.com/GaryZ88/ArduinoGotchi/) for more information). + +## Importing TamaLIB + +TamaLIB cannot be used as is. In order to create life on a specific target, you need to import all TamaLIB related __.c__ and __.h__ files in your project (for instance in a __lib__ subfolder), to create a __hal_types.h__ file using the template provided and to implement the __hal_t__ structure, that will act as an abstraction layer between TamaLIB and your OS or SDK (detailed information can be found in __hal.h__). This abstraction layer basically connects TamaLIB to your target's buttons, clock, audio and screen, while also defining the C types that TamaLIB should use to represent 4-bit, 5-bit, 8-bit, 12-bit, 13-bit and 32-bit variables. Once done, you will be able to call the TamaLIB API from your project. + + +## Using the TamaLIB API + +Basically: +``` +/* ... */ + +/* Register the HAL */ +tamalib_register_hal(&my_hal); + +/* ... */ + +/* Initialize TamaLIB */ +tamalib_init(my_program, my_breakpoints, 1000000); // my_breakpoints can be NULL, 1000000 means that timestamps will be expressed in us + +/* ... */ + +/* Enter TamaLIB's loop */ +tamalib_mainloop(); + +/* ... */ + +/* Release TamaLIB */ +tamalib_release(); + +/* ... */ +``` +Your main project should then forward any button input to TamaLIB using the `tamalib_set_button()` function. + +As an alternative to `tamalib_mainloop()`, you can call `tamalib_step()` directly if your execution flow requires something more complex than a simple mainloop. In that case, TamaLIB will neither call the HAL `handler()` function, nor the HAL `update_screen()` function by itslef. + + +## License + +TamaLIB is distributed under the GPLv2 license. See the LICENSE file for more information. + + +## Hardware information + +The Tamagotchi P1 is based on an +[E0C6S46 Epson MCU](https://download.epson-europe.com/pub/electronics-de/asmic/4bit/62family/technicalmanual/tm_6s46.pdf), +and runs at 32,768 kHz. Its LCD is 32x16 B/W pixels, with 8 icons. +To my knowledge, the ROM available online has been extracted from a high-res picture of a die. The ROM mask was clear enough to be optically read. The pictures can be seen [there](https://siliconpr0n.org/map/bandai/tamagotchi-v1/) (thx asterick for the link !). +I would love to see the same work done on a P2 and add support for it in TamaLIB/TamaTool ! + +__ +Copyright (C) 2021 Jean-Christophe Rona diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/cpu.c b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/cpu.c new file mode 100644 index 000000000..3f422c2d6 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/cpu.c @@ -0,0 +1,2033 @@ +/* + * TamaLIB - A hardware agnostic Tamagotchi P1 emulation library + * + * Copyright (C) 2021 Jean-Christophe Rona + * + * 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 2 + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "cpu.h" +#include "hw.h" +#include "hal.h" + +#define TICK_FREQUENCY 32768 // Hz + +#define TIMER_1HZ_PERIOD 32768 // in ticks +#define TIMER_256HZ_PERIOD 128 // in ticks + +#define MASK_4B 0xF00 +#define MASK_6B 0xFC0 +#define MASK_7B 0xFE0 +#define MASK_8B 0xFF0 +#define MASK_10B 0xFFC +#define MASK_12B 0xFFF + +#define PCS (pc & 0xFF) +#define PCSL (pc & 0xF) +#define PCSH ((pc >> 4) & 0xF) +#define PCP ((pc >> 8) & 0xF) +#define PCB ((pc >> 12) & 0x1) +#define TO_PC(bank, page, step) ((step & 0xFF) | ((page & 0xF) << 8) | (bank & 0x1) << 12) +#define NBP ((np >> 4) & 0x1) +#define NPP (np & 0xF) +#define TO_NP(bank, page) ((page & 0xF) | (bank & 0x1) << 4) +#define XHL (x & 0xFF) +#define XL (x & 0xF) +#define XH ((x >> 4) & 0xF) +#define XP ((x >> 8) & 0xF) +#define YHL (y & 0xFF) +#define YL (y & 0xF) +#define YH ((y >> 4) & 0xF) +#define YP ((y >> 8) & 0xF) +#define M(n) get_memory(n) +#define SET_M(n, v) set_memory(n, v) +#define RQ(i) get_rq(i) +#define SET_RQ(i, v) set_rq(i, v) +#define SPL (sp & 0xF) +#define SPH ((sp >> 4) & 0xF) + +#define FLAG_C (0x1 << 0) +#define FLAG_Z (0x1 << 1) +#define FLAG_D (0x1 << 2) +#define FLAG_I (0x1 << 3) + +#define C !!(flags & FLAG_C) +#define Z !!(flags & FLAG_Z) +#define D !!(flags & FLAG_D) +#define I !!(flags & FLAG_I) + +#define SET_C() \ + { flags |= FLAG_C; } +#define CLEAR_C() \ + { flags &= ~FLAG_C; } +#define SET_Z() \ + { flags |= FLAG_Z; } +#define CLEAR_Z() \ + { flags &= ~FLAG_Z; } +#define SET_D() \ + { flags |= FLAG_D; } +#define CLEAR_D() \ + { flags &= ~FLAG_D; } +#define SET_I() \ + { flags |= FLAG_I; } +#define CLEAR_I() \ + { flags &= ~FLAG_I; } + +#define REG_CLK_INT_FACTOR_FLAGS 0xF00 +#define REG_SW_INT_FACTOR_FLAGS 0xF01 +#define REG_PROG_INT_FACTOR_FLAGS 0xF02 +#define REG_SERIAL_INT_FACTOR_FLAGS 0xF03 +#define REG_K00_K03_INT_FACTOR_FLAGS 0xF04 +#define REG_K10_K13_INT_FACTOR_FLAGS 0xF05 +#define REG_CLOCK_INT_MASKS 0xF10 +#define REG_SW_INT_MASKS 0xF11 +#define REG_PROG_INT_MASKS 0xF12 +#define REG_SERIAL_INT_MASKS 0xF13 +#define REG_K00_K03_INT_MASKS 0xF14 +#define REG_K10_K13_INT_MASKS 0xF15 +#define REG_PROG_TIMER_DATA_L 0xF24 +#define REG_PROG_TIMER_DATA_H 0xF25 +#define REG_PROG_TIMER_RELOAD_DATA_L 0xF26 +#define REG_PROG_TIMER_RELOAD_DATA_H 0xF27 +#define REG_K00_K03_INPUT_PORT 0xF40 +#define REG_K10_K13_INPUT_PORT 0xF42 +#define REG_K40_K43_BZ_OUTPUT_PORT 0xF54 +#define REG_CPU_OSC3_CTRL 0xF70 +#define REG_LCD_CTRL 0xF71 +#define REG_LCD_CONTRAST 0xF72 +#define REG_SVD_CTRL 0xF73 +#define REG_BUZZER_CTRL1 0xF74 +#define REG_BUZZER_CTRL2 0xF75 +#define REG_CLK_WD_TIMER_CTRL 0xF76 +#define REG_SW_TIMER_CTRL 0xF77 +#define REG_PROG_TIMER_CTRL 0xF78 +#define REG_PROG_TIMER_CLK_SEL 0xF79 + +#define INPUT_PORT_NUM 2 + +typedef struct { + char* log; + u12_t code; + u12_t mask; + u12_t shift_arg0; + u12_t mask_arg0; // != 0 only if there are two arguments + u8_t cycles; + void (*cb)(u8_t arg0, u8_t arg1); +} op_t; + +typedef struct { + u4_t states; +} input_port_t; + +/* Registers */ +static u13_t pc, next_pc; +static u12_t x, y; +static u4_t a, b; +static u5_t np; +static u8_t sp; + +/* Flags */ +static u4_t flags; + +static const u12_t* g_program = NULL; +static MEM_BUFFER_TYPE memory[MEM_BUFFER_SIZE]; + +static input_port_t inputs[INPUT_PORT_NUM] = {{0}}; + +/* Interrupts (in priority order) */ +static interrupt_t interrupts[INT_SLOT_NUM] = { + {0x0, 0x0, 0, 0x0C}, // Prog timer + {0x0, 0x0, 0, 0x0A}, // Serial interface + {0x0, 0x0, 0, 0x08}, // Input (K10-K13) + {0x0, 0x0, 0, 0x06}, // Input (K00-K03) + {0x0, 0x0, 0, 0x04}, // Stopwatch timer + {0x0, 0x0, 0, 0x02}, // Clock timer +}; + +static breakpoint_t* g_breakpoints = NULL; + +static u32_t call_depth = 0; + +static u32_t clk_timer_timestamp = 0; // in ticks +static u32_t prog_timer_timestamp = 0; // in ticks +static bool_t prog_timer_enabled = 0; +static u8_t prog_timer_data = 0; +static u8_t prog_timer_rld = 0; + +static u32_t tick_counter = 0; +static u32_t ts_freq; +static u8_t speed_ratio = 1; +static timestamp_t ref_ts; + +static state_t cpu_state = { + .pc = &pc, + .x = &x, + .y = &y, + .a = &a, + .b = &b, + .np = &np, + .sp = &sp, + .flags = &flags, + + .tick_counter = &tick_counter, + .clk_timer_timestamp = &clk_timer_timestamp, + .prog_timer_timestamp = &prog_timer_timestamp, + .prog_timer_enabled = &prog_timer_enabled, + .prog_timer_data = &prog_timer_data, + .prog_timer_rld = &prog_timer_rld, + + .call_depth = &call_depth, + + .interrupts = interrupts, + + .memory = memory, +}; + +void cpu_add_bp(breakpoint_t** list, u13_t addr) { + breakpoint_t* bp; + + bp = (breakpoint_t*)g_hal->malloc(sizeof(breakpoint_t)); + if(!bp) { + g_hal->log(LOG_ERROR, "Cannot allocate memory for breakpoint 0x%04X!\n", addr); + return; + } + + bp->addr = addr; + + if(*list != NULL) { + bp->next = *list; + } else { + /* List is empty */ + bp->next = NULL; + } + + *list = bp; +} + +void cpu_free_bp(breakpoint_t** list) { + breakpoint_t *bp = *list, *tmp; + + while(bp != NULL) { + tmp = bp->next; + g_hal->free(bp); + bp = tmp; + } + + *list = NULL; +} + +void cpu_set_speed(u8_t speed) { + speed_ratio = speed; +} + +state_t* cpu_get_state(void) { + return &cpu_state; +} + +u32_t cpu_get_depth(void) { + return call_depth; +} + +static void generate_interrupt(int_slot_t slot, u8_t bit) { + /* Set the factor flag no matter what */ + interrupts[slot].factor_flag_reg = interrupts[slot].factor_flag_reg | (0x1 << bit); + + /* Trigger the INT only if not masked */ + if(interrupts[slot].mask_reg & (0x1 << bit)) { + interrupts[slot].triggered = 1; + } +} + +void cpu_set_input_pin(pin_t pin, pin_state_t state) { + /* Set the I/O */ + inputs[pin & 0x4].states = (inputs[pin & 0x4].states & ~(0x1 << (pin & 0x3))) | + (state << (pin & 0x3)); + + /* Trigger the interrupt (TODO: handle relation register) */ + if(state == PIN_STATE_LOW) { + switch((pin & 0x4) >> 2) { + case 0: + generate_interrupt(INT_K00_K03_SLOT, pin & 0x3); + break; + + case 1: + generate_interrupt(INT_K10_K13_SLOT, pin & 0x3); + break; + } + } +} + +void cpu_sync_ref_timestamp(void) { + ref_ts = g_hal->get_timestamp(); +} + +static u4_t get_io(u12_t n) { + u4_t tmp; + + switch(n) { + case REG_CLK_INT_FACTOR_FLAGS: + /* Interrupt factor flags (clock timer) */ + tmp = interrupts[INT_CLOCK_TIMER_SLOT].factor_flag_reg; + interrupts[INT_CLOCK_TIMER_SLOT].factor_flag_reg = 0; + return tmp; + + case REG_SW_INT_FACTOR_FLAGS: + /* Interrupt factor flags (stopwatch) */ + tmp = interrupts[INT_STOPWATCH_SLOT].factor_flag_reg; + interrupts[INT_STOPWATCH_SLOT].factor_flag_reg = 0; + return tmp; + + case REG_PROG_INT_FACTOR_FLAGS: + /* Interrupt factor flags (prog timer) */ + tmp = interrupts[INT_PROG_TIMER_SLOT].factor_flag_reg; + interrupts[INT_PROG_TIMER_SLOT].factor_flag_reg = 0; + return tmp; + + case REG_SERIAL_INT_FACTOR_FLAGS: + /* Interrupt factor flags (serial) */ + tmp = interrupts[INT_SERIAL_SLOT].factor_flag_reg; + interrupts[INT_SERIAL_SLOT].factor_flag_reg = 0; + return tmp; + + case REG_K00_K03_INT_FACTOR_FLAGS: + /* Interrupt factor flags (K00-K03) */ + tmp = interrupts[INT_K00_K03_SLOT].factor_flag_reg; + interrupts[INT_K00_K03_SLOT].factor_flag_reg = 0; + return tmp; + + case REG_K10_K13_INT_FACTOR_FLAGS: + /* Interrupt factor flags (K10-K13) */ + tmp = interrupts[INT_K10_K13_SLOT].factor_flag_reg; + interrupts[INT_K10_K13_SLOT].factor_flag_reg = 0; + return tmp; + + case REG_CLOCK_INT_MASKS: + /* Clock timer interrupt masks */ + return interrupts[INT_CLOCK_TIMER_SLOT].mask_reg; + + case REG_SW_INT_MASKS: + /* Stopwatch interrupt masks */ + return interrupts[INT_STOPWATCH_SLOT].mask_reg & 0x3; + + case REG_PROG_INT_MASKS: + /* Prog timer interrupt masks */ + return interrupts[INT_PROG_TIMER_SLOT].mask_reg & 0x1; + + case REG_SERIAL_INT_MASKS: + /* Serial interface interrupt masks */ + return interrupts[INT_SERIAL_SLOT].mask_reg & 0x1; + + case REG_K00_K03_INT_MASKS: + /* Input (K00-K03) interrupt masks */ + return interrupts[INT_K00_K03_SLOT].mask_reg; + + case REG_K10_K13_INT_MASKS: + /* Input (K10-K13) interrupt masks */ + return interrupts[INT_K10_K13_SLOT].mask_reg; + + case REG_PROG_TIMER_DATA_L: + /* Prog timer data (low) */ + return prog_timer_data & 0xF; + + case REG_PROG_TIMER_DATA_H: + /* Prog timer data (high) */ + return (prog_timer_data >> 4) & 0xF; + + case REG_PROG_TIMER_RELOAD_DATA_L: + /* Prog timer reload data (low) */ + return prog_timer_rld & 0xF; + + case REG_PROG_TIMER_RELOAD_DATA_H: + /* Prog timer reload data (high) */ + return (prog_timer_rld >> 4) & 0xF; + + case REG_K00_K03_INPUT_PORT: + /* Input port (K00-K03) */ + return inputs[0].states; + + case REG_K10_K13_INPUT_PORT: + /* Input port (K10-K13) */ + return inputs[1].states; + + case REG_K40_K43_BZ_OUTPUT_PORT: + /* Output port (R40-R43) */ + return GET_IO_MEMORY(memory, n); + + case REG_CPU_OSC3_CTRL: + /* CPU/OSC3 clocks switch, CPU voltage switch */ + return GET_IO_MEMORY(memory, n); + + case REG_LCD_CTRL: + /* LCD control */ + return GET_IO_MEMORY(memory, n); + + case REG_LCD_CONTRAST: + /* LCD contrast */ + break; + + case REG_SVD_CTRL: + /* SVD */ + return GET_IO_MEMORY(memory, n) & 0x7; // Voltage always OK + + case REG_BUZZER_CTRL1: + /* Buzzer config 1 */ + return GET_IO_MEMORY(memory, n); + + case REG_BUZZER_CTRL2: + /* Buzzer config 2 */ + return GET_IO_MEMORY(memory, n) & 0x3; // Buzzer ready + + case REG_CLK_WD_TIMER_CTRL: + /* Clock/Watchdog timer reset */ + break; + + case REG_SW_TIMER_CTRL: + /* Stopwatch stop/run/reset */ + break; + + case REG_PROG_TIMER_CTRL: + /* Prog timer stop/run/reset */ + return !!prog_timer_enabled; + + case REG_PROG_TIMER_CLK_SEL: + /* Prog timer clock selection */ + break; + + default: + g_hal->log(LOG_ERROR, "Read from unimplemented I/O 0x%03X - PC = 0x%04X\n", n, pc); + } + + return 0; +} + +static void set_io(u12_t n, u4_t v) { + switch(n) { + case REG_CLOCK_INT_MASKS: + /* Clock timer interrupt masks */ + /* Assume 1Hz timer INT enabled (0x8) */ + interrupts[INT_CLOCK_TIMER_SLOT].mask_reg = v; + break; + + case REG_SW_INT_MASKS: + /* Stopwatch interrupt masks */ + /* Assume all INT disabled */ + interrupts[INT_STOPWATCH_SLOT].mask_reg = v; + break; + + case REG_PROG_INT_MASKS: + /* Prog timer interrupt masks */ + /* Assume Prog timer INT enabled (0x1) */ + interrupts[INT_PROG_TIMER_SLOT].mask_reg = v; + break; + + case REG_SERIAL_INT_MASKS: + /* Serial interface interrupt masks */ + /* Assume all INT disabled */ + interrupts[INT_K10_K13_SLOT].mask_reg = v; + break; + + case REG_K00_K03_INT_MASKS: + /* Input (K00-K03) interrupt masks */ + /* Assume all INT disabled */ + interrupts[INT_SERIAL_SLOT].mask_reg = v; + break; + + case REG_K10_K13_INT_MASKS: + /* Input (K10-K13) interrupt masks */ + /* Assume all INT disabled */ + interrupts[INT_K10_K13_SLOT].mask_reg = v; + break; + + case REG_PROG_TIMER_RELOAD_DATA_L: + /* Prog timer reload data (low) */ + prog_timer_rld = v | (prog_timer_rld & 0xF0); + break; + + case REG_PROG_TIMER_RELOAD_DATA_H: + /* Prog timer reload data (high) */ + prog_timer_rld = (prog_timer_rld & 0xF) | (v << 4); + break; + + case REG_K00_K03_INPUT_PORT: + /* Input port (K00-K03) */ + /* Write not allowed */ + break; + + case REG_K40_K43_BZ_OUTPUT_PORT: + /* Output port (R40-R43) */ + //g_hal->log(LOG_INFO, "Output/Buzzer: 0x%X\n", v); + hw_enable_buzzer(!(v & 0x8)); + break; + + case REG_CPU_OSC3_CTRL: + /* CPU/OSC3 clocks switch, CPU voltage switch */ + /* Assume 32,768 OSC1 selected, OSC3 off, battery >= 3,1V (0x1) */ + break; + + case REG_LCD_CTRL: + /* LCD control */ + break; + + case REG_LCD_CONTRAST: + /* LCD contrast */ + /* Assume medium contrast (0x8) */ + break; + + case REG_SVD_CTRL: + /* SVD */ + /* Assume battery voltage always OK (0x6) */ + break; + + case REG_BUZZER_CTRL1: + /* Buzzer config 1 */ + hw_set_buzzer_freq(v & 0x7); + break; + + case REG_BUZZER_CTRL2: + /* Buzzer config 2 */ + break; + + case REG_CLK_WD_TIMER_CTRL: + /* Clock/Watchdog timer reset */ + /* Ignore watchdog */ + break; + + case REG_SW_TIMER_CTRL: + /* Stopwatch stop/run/reset */ + break; + + case REG_PROG_TIMER_CTRL: + /* Prog timer stop/run/reset */ + if(v & 0x2) { + prog_timer_data = prog_timer_rld; + } + + if((v & 0x1) && !prog_timer_enabled) { + prog_timer_timestamp = tick_counter; + } + + prog_timer_enabled = v & 0x1; + break; + + case REG_PROG_TIMER_CLK_SEL: + /* Prog timer clock selection */ + /* Assume 256Hz, output disabled */ + break; + + default: + g_hal->log(LOG_ERROR, "Write 0x%X to unimplemented I/O 0x%03X - PC = 0x%04X\n", v, n, pc); + } +} + +static void set_lcd(u12_t n, u4_t v) { + u8_t i; + u8_t seg, com0; + + seg = ((n & 0x7F) >> 1); + com0 = (((n & 0x80) >> 7) * 8 + (n & 0x1) * 4); + + for(i = 0; i < 4; i++) { + hw_set_lcd_pin(seg, com0 + i, (v >> i) & 0x1); + } +} + +static u4_t get_memory(u12_t n) { + u4_t res = 0; + + if(n < MEM_RAM_SIZE) { + /* RAM */ + g_hal->log(LOG_MEMORY, "RAM - "); + res = GET_RAM_MEMORY(memory, n); + } else if(n >= MEM_DISPLAY1_ADDR && n < (MEM_DISPLAY1_ADDR + MEM_DISPLAY1_SIZE)) { + /* Display Memory 1 */ + g_hal->log(LOG_MEMORY, "Display Memory 1 - "); + res = GET_DISP1_MEMORY(memory, n); + } else if(n >= MEM_DISPLAY2_ADDR && n < (MEM_DISPLAY2_ADDR + MEM_DISPLAY2_SIZE)) { + /* Display Memory 2 */ + g_hal->log(LOG_MEMORY, "Display Memory 2 - "); + res = GET_DISP2_MEMORY(memory, n); + } else if(n >= MEM_IO_ADDR && n < (MEM_IO_ADDR + MEM_IO_SIZE)) { + /* I/O Memory */ + g_hal->log(LOG_MEMORY, "I/O - "); + res = get_io(n); + } else { + g_hal->log(LOG_ERROR, "Read from invalid memory address 0x%03X - PC = 0x%04X\n", n, pc); + return 0; + } + + g_hal->log(LOG_MEMORY, "Read 0x%X - Address 0x%03X - PC = 0x%04X\n", res, n, pc); + + return res; +} + +static void set_memory(u12_t n, u4_t v) { + /* Cache any data written to a valid address, and process it */ + if(n < MEM_RAM_SIZE) { + /* RAM */ + SET_RAM_MEMORY(memory, n, v); + g_hal->log(LOG_MEMORY, "RAM - "); + } else if(n >= MEM_DISPLAY1_ADDR && n < (MEM_DISPLAY1_ADDR + MEM_DISPLAY1_SIZE)) { + /* Display Memory 1 */ + SET_DISP1_MEMORY(memory, n, v); + set_lcd(n, v); + g_hal->log(LOG_MEMORY, "Display Memory 1 - "); + } else if(n >= MEM_DISPLAY2_ADDR && n < (MEM_DISPLAY2_ADDR + MEM_DISPLAY2_SIZE)) { + /* Display Memory 2 */ + SET_DISP2_MEMORY(memory, n, v); + set_lcd(n, v); + g_hal->log(LOG_MEMORY, "Display Memory 2 - "); + } else if(n >= MEM_IO_ADDR && n < (MEM_IO_ADDR + MEM_IO_SIZE)) { + /* I/O Memory */ + SET_IO_MEMORY(memory, n, v); + set_io(n, v); + g_hal->log(LOG_MEMORY, "I/O - "); + } else { + g_hal->log( + LOG_ERROR, "Write 0x%X to invalid memory address 0x%03X - PC = 0x%04X\n", v, n, pc); + return; + } + + g_hal->log(LOG_MEMORY, "Write 0x%X - Address 0x%03X - PC = 0x%04X\n", v, n, pc); +} + +void cpu_refresh_hw(void) { + static const struct range { + u12_t addr; + u12_t size; + } refresh_locs[] = { + {MEM_DISPLAY1_ADDR, MEM_DISPLAY1_SIZE}, /* Display Memory 1 */ + {MEM_DISPLAY2_ADDR, MEM_DISPLAY2_SIZE}, /* Display Memory 2 */ + {REG_BUZZER_CTRL1, 1}, /* Buzzer frequency */ + {REG_K40_K43_BZ_OUTPUT_PORT, 1}, /* Buzzer enabled */ + + {0, 0}, // end of list + }; + + for(int i = 0; refresh_locs[i].size != 0; i++) { + for(u12_t n = refresh_locs[i].addr; n < (refresh_locs[i].addr + refresh_locs[i].size); + n++) { + set_memory(n, GET_MEMORY(memory, n)); + } + } +} + +static u4_t get_rq(u12_t rq) { + switch(rq & 0x3) { + case 0x0: + return a; + + case 0x1: + return b; + + case 0x2: + return M(x); + + case 0x3: + return M(y); + } + + return 0; +} + +static void set_rq(u12_t rq, u4_t v) { + switch(rq & 0x3) { + case 0x0: + a = v; + break; + + case 0x1: + b = v; + break; + + case 0x2: + SET_M(x, v); + break; + + case 0x3: + SET_M(y, v); + break; + } +} + +/* Instructions */ +static void op_pset_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + np = arg0; +} + +static void op_jp_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + next_pc = arg0 | (np << 8); +} + +static void op_jp_c_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + if(flags & FLAG_C) { + next_pc = arg0 | (np << 8); + } +} + +static void op_jp_nc_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + if(!(flags & FLAG_C)) { + next_pc = arg0 | (np << 8); + } +} + +static void op_jp_z_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + if(flags & FLAG_Z) { + next_pc = arg0 | (np << 8); + } +} + +static void op_jp_nz_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + if(!(flags & FLAG_Z)) { + next_pc = arg0 | (np << 8); + } +} + +static void op_jpba_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + next_pc = a | (b << 4) | (np << 8); +} + +static void op_call_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + pc = (pc + 1) & 0x1FFF; // This does not actually change the PC register + SET_M(sp - 1, PCP); + SET_M(sp - 2, PCSH); + SET_M(sp - 3, PCSL); + sp = (sp - 3) & 0xFF; + next_pc = TO_PC(PCB, NPP, arg0); + call_depth++; +} + +static void op_calz_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + pc = (pc + 1) & 0x1FFF; // This does not actually change the PC register + SET_M(sp - 1, PCP); + SET_M(sp - 2, PCSH); + SET_M(sp - 3, PCSL); + sp = (sp - 3) & 0xFF; + next_pc = TO_PC(PCB, 0, arg0); + call_depth++; +} + +static void op_ret_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + next_pc = M(sp) | (M(sp + 1) << 4) | (M(sp + 2) << 8) | (PCB << 12); + sp = (sp + 3) & 0xFF; + call_depth--; +} + +static void op_rets_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + next_pc = M(sp) | (M(sp + 1) << 4) | (M(sp + 2) << 8) | (PCB << 12); + sp = (sp + 3) & 0xFF; + next_pc = (pc + 1) & 0x1FFF; + call_depth--; +} + +static void op_retd_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + next_pc = M(sp) | (M(sp + 1) << 4) | (M(sp + 2) << 8) | (PCB << 12); + sp = (sp + 3) & 0xFF; + SET_M(x, arg0 & 0xF); + SET_M(x + 1, (arg0 >> 4) & 0xF); + x = ((x + 2) & 0xFF) | (XP << 8); + call_depth--; +} + +static void op_nop5_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); +} + +static void op_nop7_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); +} + +static void op_halt_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + g_hal->halt(); +} + +static void op_inc_x_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + x = ((x + 1) & 0xFF) | (XP << 8); +} + +static void op_inc_y_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + y = ((y + 1) & 0xFF) | (YP << 8); +} + +static void op_ld_x_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + x = arg0 | (XP << 8); +} + +static void op_ld_y_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + y = arg0 | (YP << 8); +} + +static void op_ld_xp_r_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + x = XHL | (RQ(arg0) << 8); +} + +static void op_ld_xh_r_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + x = XL | (RQ(arg0) << 4) | (XP << 8); +} + +static void op_ld_xl_r_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + x = RQ(arg0) | (XH << 4) | (XP << 8); +} + +static void op_ld_yp_r_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + y = YHL | (RQ(arg0) << 8); +} + +static void op_ld_yh_r_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + y = YL | (RQ(arg0) << 4) | (YP << 8); +} + +static void op_ld_yl_r_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + y = RQ(arg0) | (YH << 4) | (YP << 8); +} + +static void op_ld_r_xp_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + SET_RQ(arg0, XP); +} + +static void op_ld_r_xh_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + SET_RQ(arg0, XH); +} + +static void op_ld_r_xl_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + SET_RQ(arg0, XL); +} + +static void op_ld_r_yp_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + SET_RQ(arg0, YP); +} + +static void op_ld_r_yh_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + SET_RQ(arg0, YH); +} + +static void op_ld_r_yl_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + SET_RQ(arg0, YL); +} + +static void op_adc_xh_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + u8_t tmp; + + tmp = XH + arg0 + C; + x = XL | ((tmp & 0xF) << 4) | (XP << 8); + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + if(!(tmp & 0xF)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_adc_xl_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + u8_t tmp; + + tmp = XL + arg0 + C; + x = (tmp & 0xF) | (XH << 4) | (XP << 8); + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + if(!(tmp & 0xF)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_adc_yh_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + u8_t tmp; + + tmp = YH + arg0 + C; + y = YL | ((tmp & 0xF) << 4) | (YP << 8); + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + if(!(tmp & 0xF)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_adc_yl_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + u8_t tmp; + + tmp = YL + arg0 + C; + y = (tmp & 0xF) | (YH << 4) | (YP << 8); + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + if(!(tmp & 0xF)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_cp_xh_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + if(XH < arg0) { + SET_C(); + } else { + CLEAR_C(); + } + if(XH == arg0) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_cp_xl_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + if(XL < arg0) { + SET_C(); + } else { + CLEAR_C(); + } + if(XL == arg0) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_cp_yh_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + if(YH < arg0) { + SET_C(); + } else { + CLEAR_C(); + } + if(YH == arg0) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_cp_yl_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + if(YL < arg0) { + SET_C(); + } else { + CLEAR_C(); + } + if(YL == arg0) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_ld_r_i_cb(u8_t arg0, u8_t arg1) { + SET_RQ(arg0, arg1); +} + +static void op_ld_r_q_cb(u8_t arg0, u8_t arg1) { + SET_RQ(arg0, RQ(arg1)); +} + +static void op_ld_a_mn_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + a = M(arg0); +} + +static void op_ld_b_mn_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + b = M(arg0); +} + +static void op_ld_mn_a_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + SET_M(arg0, a); +} + +static void op_ld_mn_b_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + SET_M(arg0, b); +} + +static void op_ldpx_mx_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + SET_M(x, arg0); + x = ((x + 1) & 0xFF) | (XP << 8); +} + +static void op_ldpx_r_cb(u8_t arg0, u8_t arg1) { + SET_RQ(arg0, RQ(arg1)); + x = ((x + 1) & 0xFF) | (XP << 8); +} + +static void op_ldpy_my_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + SET_M(y, arg0); + y = ((y + 1) & 0xFF) | (YP << 8); +} + +static void op_ldpy_r_cb(u8_t arg0, u8_t arg1) { + SET_RQ(arg0, RQ(arg1)); + y = ((y + 1) & 0xFF) | (YP << 8); +} + +static void op_lbpx_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + SET_M(x, arg0 & 0xF); + SET_M(x + 1, (arg0 >> 4) & 0xF); + x = ((x + 2) & 0xFF) | (XP << 8); +} + +static void op_set_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + flags |= arg0; +} + +static void op_rst_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + flags &= arg0; +} + +static void op_scf_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + SET_C(); +} + +static void op_rcf_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + CLEAR_C(); +} + +static void op_szf_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + SET_Z(); +} + +static void op_rzf_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + CLEAR_Z(); +} + +static void op_sdf_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + SET_D(); +} + +static void op_rdf_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + CLEAR_D(); +} + +static void op_ei_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + SET_I(); +} + +static void op_di_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + CLEAR_I(); +} + +static void op_inc_sp_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + sp = (sp + 1) & 0xFF; +} + +static void op_dec_sp_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + sp = (sp - 1) & 0xFF; +} + +static void op_push_r_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + sp = (sp - 1) & 0xFF; + SET_M(sp, RQ(arg0)); +} + +static void op_push_xp_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + sp = (sp - 1) & 0xFF; + SET_M(sp, XP); +} + +static void op_push_xh_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + sp = (sp - 1) & 0xFF; + SET_M(sp, XH); +} + +static void op_push_xl_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + sp = (sp - 1) & 0xFF; + SET_M(sp, XL); +} + +static void op_push_yp_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + sp = (sp - 1) & 0xFF; + SET_M(sp, YP); +} + +static void op_push_yh_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + sp = (sp - 1) & 0xFF; + SET_M(sp, YH); +} + +static void op_push_yl_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + sp = (sp - 1) & 0xFF; + SET_M(sp, YL); +} + +static void op_push_f_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + sp = (sp - 1) & 0xFF; + SET_M(sp, flags); +} + +static void op_pop_r_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + SET_RQ(arg0, M(sp)); + sp = (sp + 1) & 0xFF; +} + +static void op_pop_xp_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + x = XL | (XH << 4) | (M(sp) << 8); + sp = (sp + 1) & 0xFF; +} + +static void op_pop_xh_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + x = XL | (M(sp) << 4) | (XP << 8); + sp = (sp + 1) & 0xFF; +} + +static void op_pop_xl_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + x = M(sp) | (XH << 4) | (XP << 8); + sp = (sp + 1) & 0xFF; +} + +static void op_pop_yp_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + y = YL | (YH << 4) | (M(sp) << 8); + sp = (sp + 1) & 0xFF; +} + +static void op_pop_yh_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + y = YL | (M(sp) << 4) | (YP << 8); + sp = (sp + 1) & 0xFF; +} + +static void op_pop_yl_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + y = M(sp) | (YH << 4) | (YP << 8); + sp = (sp + 1) & 0xFF; +} + +static void op_pop_f_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg0); + UNUSED(arg1); + flags = M(sp); + sp = (sp + 1) & 0xFF; +} + +static void op_ld_sph_r_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + sp = SPL | (RQ(arg0) << 4); +} + +static void op_ld_spl_r_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + sp = RQ(arg0) | (SPH << 4); +} + +static void op_ld_r_sph_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + SET_RQ(arg0, SPH); +} + +static void op_ld_r_spl_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + SET_RQ(arg0, SPL); +} + +static void op_add_r_i_cb(u8_t arg0, u8_t arg1) { + u8_t tmp; + + tmp = RQ(arg0) + arg1; + if(D) { + if(tmp >= 10) { + SET_RQ(arg0, (tmp - 10) & 0xF); + SET_C(); + } else { + SET_RQ(arg0, tmp); + CLEAR_C(); + } + } else { + SET_RQ(arg0, tmp & 0xF); + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + } + if(!RQ(arg0)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_add_r_q_cb(u8_t arg0, u8_t arg1) { + u8_t tmp; + + tmp = RQ(arg0) + RQ(arg1); + if(D) { + if(tmp >= 10) { + SET_RQ(arg0, (tmp - 10) & 0xF); + SET_C(); + } else { + SET_RQ(arg0, tmp); + CLEAR_C(); + } + } else { + SET_RQ(arg0, tmp & 0xF); + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + } + if(!RQ(arg0)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_adc_r_i_cb(u8_t arg0, u8_t arg1) { + u8_t tmp; + + tmp = RQ(arg0) + arg1 + C; + if(D) { + if(tmp >= 10) { + SET_RQ(arg0, (tmp - 10) & 0xF); + SET_C(); + } else { + SET_RQ(arg0, tmp); + CLEAR_C(); + } + } else { + SET_RQ(arg0, tmp & 0xF); + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + } + if(!RQ(arg0)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_adc_r_q_cb(u8_t arg0, u8_t arg1) { + u8_t tmp; + + tmp = RQ(arg0) + RQ(arg1) + C; + if(D) { + if(tmp >= 10) { + SET_RQ(arg0, (tmp - 10) & 0xF); + SET_C(); + } else { + SET_RQ(arg0, tmp); + CLEAR_C(); + } + } else { + SET_RQ(arg0, tmp & 0xF); + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + } + if(!RQ(arg0)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_sub_cb(u8_t arg0, u8_t arg1) { + u8_t tmp; + + tmp = RQ(arg0) - RQ(arg1); + if(D) { + if(tmp >> 4) { + SET_RQ(arg0, (tmp - 6) & 0xF); + } else { + SET_RQ(arg0, tmp); + } + } else { + SET_RQ(arg0, tmp & 0xF); + } + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + if(!RQ(arg0)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_sbc_r_i_cb(u8_t arg0, u8_t arg1) { + u8_t tmp; + + tmp = RQ(arg0) - arg1 - C; + if(D) { + if(tmp >> 4) { + SET_RQ(arg0, (tmp - 6) & 0xF); + } else { + SET_RQ(arg0, tmp); + } + } else { + SET_RQ(arg0, tmp & 0xF); + } + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + if(!RQ(arg0)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_sbc_r_q_cb(u8_t arg0, u8_t arg1) { + u8_t tmp; + + tmp = RQ(arg0) - RQ(arg1) - C; + if(D) { + if(tmp >> 4) { + SET_RQ(arg0, (tmp - 6) & 0xF); + } else { + SET_RQ(arg0, tmp); + } + } else { + SET_RQ(arg0, tmp & 0xF); + } + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + if(!RQ(arg0)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_and_r_i_cb(u8_t arg0, u8_t arg1) { + SET_RQ(arg0, RQ(arg0) & arg1); + if(!RQ(arg0)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_and_r_q_cb(u8_t arg0, u8_t arg1) { + SET_RQ(arg0, RQ(arg0) & RQ(arg1)); + if(!RQ(arg0)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_or_r_i_cb(u8_t arg0, u8_t arg1) { + SET_RQ(arg0, RQ(arg0) | arg1); + if(!RQ(arg0)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_or_r_q_cb(u8_t arg0, u8_t arg1) { + SET_RQ(arg0, RQ(arg0) | RQ(arg1)); + if(!RQ(arg0)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_xor_r_i_cb(u8_t arg0, u8_t arg1) { + SET_RQ(arg0, RQ(arg0) ^ arg1); + if(!RQ(arg0)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_xor_r_q_cb(u8_t arg0, u8_t arg1) { + SET_RQ(arg0, RQ(arg0) ^ RQ(arg1)); + if(!RQ(arg0)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_cp_r_i_cb(u8_t arg0, u8_t arg1) { + if(RQ(arg0) < arg1) { + SET_C(); + } else { + CLEAR_C(); + } + if(RQ(arg0) == arg1) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_cp_r_q_cb(u8_t arg0, u8_t arg1) { + if(RQ(arg0) < RQ(arg1)) { + SET_C(); + } else { + CLEAR_C(); + } + if(RQ(arg0) == RQ(arg1)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_fan_r_i_cb(u8_t arg0, u8_t arg1) { + if(!(RQ(arg0) & arg1)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_fan_r_q_cb(u8_t arg0, u8_t arg1) { + if(!(RQ(arg0) & RQ(arg1))) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_rlc_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + u8_t tmp; + + tmp = (RQ(arg0) << 1) | C; + if(RQ(arg0) & 0x8) { + SET_C(); + } else { + CLEAR_C(); + } + SET_RQ(arg0, tmp & 0xF); + /* No need to set Z (issue in DS) */ +} + +static void op_rrc_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + u8_t tmp; + + tmp = (RQ(arg0) >> 1) | (C << 3); + if(RQ(arg0) & 0x1) { + SET_C(); + } else { + CLEAR_C(); + } + SET_RQ(arg0, tmp & 0xF); + /* No need to set Z (issue in DS) */ +} + +static void op_inc_mn_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + u8_t tmp; + + tmp = M(arg0) + 1; + SET_M(arg0, tmp & 0xF); + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + if(!M(arg0)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_dec_mn_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + u8_t tmp; + + tmp = M(arg0) - 1; + SET_M(arg0, tmp & 0xF); + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + if(!M(arg0)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +static void op_acpx_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + u8_t tmp; + + tmp = M(x) + RQ(arg0) + C; + if(D) { + if(tmp >= 10) { + SET_M(x, (tmp - 10) & 0xF); + SET_C(); + } else { + SET_M(x, tmp); + CLEAR_C(); + } + } else { + SET_M(x, tmp & 0xF); + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + } + if(!M(x)) { + SET_Z(); + } else { + CLEAR_Z(); + } + x = ((x + 1) & 0xFF) | (XP << 8); +} + +static void op_acpy_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + u8_t tmp; + + tmp = M(y) + RQ(arg0) + C; + if(D) { + if(tmp >= 10) { + SET_M(y, (tmp - 10) & 0xF); + SET_C(); + } else { + SET_M(y, tmp); + CLEAR_C(); + } + } else { + SET_M(y, tmp & 0xF); + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + } + if(!M(y)) { + SET_Z(); + } else { + CLEAR_Z(); + } + y = ((y + 1) & 0xFF) | (YP << 8); +} + +static void op_scpx_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + u8_t tmp; + + tmp = M(x) - RQ(arg0) - C; + if(D) { + if(tmp >> 4) { + SET_M(x, (tmp - 6) & 0xF); + } else { + SET_M(x, tmp); + } + } else { + SET_M(x, tmp & 0xF); + } + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + if(!M(x)) { + SET_Z(); + } else { + CLEAR_Z(); + } + x = ((x + 1) & 0xFF) | (XP << 8); +} + +static void op_scpy_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + u8_t tmp; + + tmp = M(y) - RQ(arg0) - C; + if(D) { + if(tmp >> 4) { + SET_M(y, (tmp - 6) & 0xF); + } else { + SET_M(y, tmp); + } + } else { + SET_M(y, tmp & 0xF); + } + if(tmp >> 4) { + SET_C(); + } else { + CLEAR_C(); + } + if(!M(y)) { + SET_Z(); + } else { + CLEAR_Z(); + } + y = ((y + 1) & 0xFF) | (YP << 8); +} + +static void op_not_cb(u8_t arg0, u8_t arg1) { + UNUSED(arg1); + SET_RQ(arg0, ~RQ(arg0) & 0xF); + if(!RQ(arg0)) { + SET_Z(); + } else { + CLEAR_Z(); + } +} + +/* The E0C6S46 supported instructions */ +static const op_t ops[] = { + {"PSET #0x%02X ", 0xE40, MASK_7B, 0, 0, 5, &op_pset_cb}, // PSET + {"JP #0x%02X ", 0x000, MASK_4B, 0, 0, 5, &op_jp_cb}, // JP + {"JP C #0x%02X ", 0x200, MASK_4B, 0, 0, 5, &op_jp_c_cb}, // JP_C + {"JP NC #0x%02X ", 0x300, MASK_4B, 0, 0, 5, &op_jp_nc_cb}, // JP_NC + {"JP Z #0x%02X ", 0x600, MASK_4B, 0, 0, 5, &op_jp_z_cb}, // JP_Z + {"JP NZ #0x%02X ", 0x700, MASK_4B, 0, 0, 5, &op_jp_nz_cb}, // JP_NZ + {"JPBA ", 0xFE8, MASK_12B, 0, 0, 5, &op_jpba_cb}, // JPBA + {"CALL #0x%02X ", 0x400, MASK_4B, 0, 0, 7, &op_call_cb}, // CALL + {"CALZ #0x%02X ", 0x500, MASK_4B, 0, 0, 7, &op_calz_cb}, // CALZ + {"RET ", 0xFDF, MASK_12B, 0, 0, 7, &op_ret_cb}, // RET + {"RETS ", 0xFDE, MASK_12B, 0, 0, 12, &op_rets_cb}, // RETS + {"RETD #0x%02X ", 0x100, MASK_4B, 0, 0, 12, &op_retd_cb}, // RETD + {"NOP5 ", 0xFFB, MASK_12B, 0, 0, 5, &op_nop5_cb}, // NOP5 + {"NOP7 ", 0xFFF, MASK_12B, 0, 0, 7, &op_nop7_cb}, // NOP7 + {"HALT ", 0xFF8, MASK_12B, 0, 0, 5, &op_halt_cb}, // HALT + {"INC X #0x%02X ", 0xEE0, MASK_12B, 0, 0, 5, &op_inc_x_cb}, // INC_X + {"INC Y #0x%02X ", 0xEF0, MASK_12B, 0, 0, 5, &op_inc_y_cb}, // INC_Y + {"LD X #0x%02X ", 0xB00, MASK_4B, 0, 0, 5, &op_ld_x_cb}, // LD_X + {"LD Y #0x%02X ", 0x800, MASK_4B, 0, 0, 5, &op_ld_y_cb}, // LD_Y + {"LD XP R(#0x%02X) ", 0xE80, MASK_10B, 0, 0, 5, &op_ld_xp_r_cb}, // LD_XP_R + {"LD XH R(#0x%02X) ", 0xE84, MASK_10B, 0, 0, 5, &op_ld_xh_r_cb}, // LD_XH_R + {"LD XL R(#0x%02X) ", 0xE88, MASK_10B, 0, 0, 5, &op_ld_xl_r_cb}, // LD_XL_R + {"LD YP R(#0x%02X) ", 0xE90, MASK_10B, 0, 0, 5, &op_ld_yp_r_cb}, // LD_YP_R + {"LD YH R(#0x%02X) ", 0xE94, MASK_10B, 0, 0, 5, &op_ld_yh_r_cb}, // LD_YH_R + {"LD YL R(#0x%02X) ", 0xE98, MASK_10B, 0, 0, 5, &op_ld_yl_r_cb}, // LD_YL_R + {"LD R(#0x%02X) XP ", 0xEA0, MASK_10B, 0, 0, 5, &op_ld_r_xp_cb}, // LD_R_XP + {"LD R(#0x%02X) XH ", 0xEA4, MASK_10B, 0, 0, 5, &op_ld_r_xh_cb}, // LD_R_XH + {"LD R(#0x%02X) XL ", 0xEA8, MASK_10B, 0, 0, 5, &op_ld_r_xl_cb}, // LD_R_XL + {"LD R(#0x%02X) YP ", 0xEB0, MASK_10B, 0, 0, 5, &op_ld_r_yp_cb}, // LD_R_YP + {"LD R(#0x%02X) YH ", 0xEB4, MASK_10B, 0, 0, 5, &op_ld_r_yh_cb}, // LD_R_YH + {"LD R(#0x%02X) YL ", 0xEB8, MASK_10B, 0, 0, 5, &op_ld_r_yl_cb}, // LD_R_YL + {"ADC XH #0x%02X ", 0xA00, MASK_8B, 0, 0, 7, &op_adc_xh_cb}, // ADC_XH + {"ADC XL #0x%02X ", 0xA10, MASK_8B, 0, 0, 7, &op_adc_xl_cb}, // ADC_XL + {"ADC YH #0x%02X ", 0xA20, MASK_8B, 0, 0, 7, &op_adc_yh_cb}, // ADC_YH + {"ADC YL #0x%02X ", 0xA30, MASK_8B, 0, 0, 7, &op_adc_yl_cb}, // ADC_YL + {"CP XH #0x%02X ", 0xA40, MASK_8B, 0, 0, 7, &op_cp_xh_cb}, // CP_XH + {"CP XL #0x%02X ", 0xA50, MASK_8B, 0, 0, 7, &op_cp_xl_cb}, // CP_XL + {"CP YH #0x%02X ", 0xA60, MASK_8B, 0, 0, 7, &op_cp_yh_cb}, // CP_YH + {"CP YL #0x%02X ", 0xA70, MASK_8B, 0, 0, 7, &op_cp_yl_cb}, // CP_YL + {"LD R(#0x%02X) #0x%02X ", 0xE00, MASK_6B, 4, 0x030, 5, &op_ld_r_i_cb}, // LD_R_I + {"LD R(#0x%02X) Q(#0x%02X)", 0xEC0, MASK_8B, 2, 0x00C, 5, &op_ld_r_q_cb}, // LD_R_Q + {"LD A M(#0x%02X) ", 0xFA0, MASK_8B, 0, 0, 5, &op_ld_a_mn_cb}, // LD_A_MN + {"LD B M(#0x%02X) ", 0xFB0, MASK_8B, 0, 0, 5, &op_ld_b_mn_cb}, // LD_B_MN + {"LD M(#0x%02X) A ", 0xF80, MASK_8B, 0, 0, 5, &op_ld_mn_a_cb}, // LD_MN_A + {"LD M(#0x%02X) B ", 0xF90, MASK_8B, 0, 0, 5, &op_ld_mn_b_cb}, // LD_MN_B + {"LDPX MX #0x%02X ", 0xE60, MASK_8B, 0, 0, 5, &op_ldpx_mx_cb}, // LDPX_MX + {"LDPX R(#0x%02X) Q(#0x%02X)", 0xEE0, MASK_8B, 2, 0x00C, 5, &op_ldpx_r_cb}, // LDPX_R + {"LDPY MY #0x%02X ", 0xE70, MASK_8B, 0, 0, 5, &op_ldpy_my_cb}, // LDPY_MY + {"LDPY R(#0x%02X) Q(#0x%02X)", 0xEF0, MASK_8B, 2, 0x00C, 5, &op_ldpy_r_cb}, // LDPY_R + {"LBPX #0x%02X ", 0x900, MASK_4B, 0, 0, 5, &op_lbpx_cb}, // LBPX + {"SET #0x%02X ", 0xF40, MASK_8B, 0, 0, 7, &op_set_cb}, // SET + {"RST #0x%02X ", 0xF50, MASK_8B, 0, 0, 7, &op_rst_cb}, // RST + {"SCF ", 0xF41, MASK_12B, 0, 0, 7, &op_scf_cb}, // SCF + {"RCF ", 0xF5E, MASK_12B, 0, 0, 7, &op_rcf_cb}, // RCF + {"SZF ", 0xF42, MASK_12B, 0, 0, 7, &op_szf_cb}, // SZF + {"RZF ", 0xF5D, MASK_12B, 0, 0, 7, &op_rzf_cb}, // RZF + {"SDF ", 0xF44, MASK_12B, 0, 0, 7, &op_sdf_cb}, // SDF + {"RDF ", 0xF5B, MASK_12B, 0, 0, 7, &op_rdf_cb}, // RDF + {"EI ", 0xF48, MASK_12B, 0, 0, 7, &op_ei_cb}, // EI + {"DI ", 0xF57, MASK_12B, 0, 0, 7, &op_di_cb}, // DI + {"INC SP ", 0xFDB, MASK_12B, 0, 0, 5, &op_inc_sp_cb}, // INC_SP + {"DEC SP ", 0xFCB, MASK_12B, 0, 0, 5, &op_dec_sp_cb}, // DEC_SP + {"PUSH R(#0x%02X) ", 0xFC0, MASK_10B, 0, 0, 5, &op_push_r_cb}, // PUSH_R + {"PUSH XP ", 0xFC4, MASK_12B, 0, 0, 5, &op_push_xp_cb}, // PUSH_XP + {"PUSH XH ", 0xFC5, MASK_12B, 0, 0, 5, &op_push_xh_cb}, // PUSH_XH + {"PUSH XL ", 0xFC6, MASK_12B, 0, 0, 5, &op_push_xl_cb}, // PUSH_XL + {"PUSH YP ", 0xFC7, MASK_12B, 0, 0, 5, &op_push_yp_cb}, // PUSH_YP + {"PUSH YH ", 0xFC8, MASK_12B, 0, 0, 5, &op_push_yh_cb}, // PUSH_YH + {"PUSH YL ", 0xFC9, MASK_12B, 0, 0, 5, &op_push_yl_cb}, // PUSH_YL + {"PUSH F ", 0xFCA, MASK_12B, 0, 0, 5, &op_push_f_cb}, // PUSH_F + {"POP R(#0x%02X) ", 0xFD0, MASK_10B, 0, 0, 5, &op_pop_r_cb}, // POP_R + {"POP XP ", 0xFD4, MASK_12B, 0, 0, 5, &op_pop_xp_cb}, // POP_XP + {"POP XH ", 0xFD5, MASK_12B, 0, 0, 5, &op_pop_xh_cb}, // POP_XH + {"POP XL ", 0xFD6, MASK_12B, 0, 0, 5, &op_pop_xl_cb}, // POP_XL + {"POP YP ", 0xFD7, MASK_12B, 0, 0, 5, &op_pop_yp_cb}, // POP_YP + {"POP YH ", 0xFD8, MASK_12B, 0, 0, 5, &op_pop_yh_cb}, // POP_YH + {"POP YL ", 0xFD9, MASK_12B, 0, 0, 5, &op_pop_yl_cb}, // POP_YL + {"POP F ", 0xFDA, MASK_12B, 0, 0, 5, &op_pop_f_cb}, // POP_F + {"LD SPH R(#0x%02X) ", 0xFE0, MASK_10B, 0, 0, 5, &op_ld_sph_r_cb}, // LD_SPH_R + {"LD SPL R(#0x%02X) ", 0xFF0, MASK_10B, 0, 0, 5, &op_ld_spl_r_cb}, // LD_SPL_R + {"LD R(#0x%02X) SPH ", 0xFE4, MASK_10B, 0, 0, 5, &op_ld_r_sph_cb}, // LD_R_SPH + {"LD R(#0x%02X) SPL ", 0xFF4, MASK_10B, 0, 0, 5, &op_ld_r_spl_cb}, // LD_R_SPL + {"ADD R(#0x%02X) #0x%02X ", 0xC00, MASK_6B, 4, 0x030, 7, &op_add_r_i_cb}, // ADD_R_I + {"ADD R(#0x%02X) Q(#0x%02X)", 0xA80, MASK_8B, 2, 0x00C, 7, &op_add_r_q_cb}, // ADD_R_Q + {"ADC R(#0x%02X) #0x%02X ", 0xC40, MASK_6B, 4, 0x030, 7, &op_adc_r_i_cb}, // ADC_R_I + {"ADC R(#0x%02X) Q(#0x%02X)", 0xA90, MASK_8B, 2, 0x00C, 7, &op_adc_r_q_cb}, // ADC_R_Q + {"SUB R(#0x%02X) Q(#0x%02X)", 0xAA0, MASK_8B, 2, 0x00C, 7, &op_sub_cb}, // SUB + {"SBC R(#0x%02X) #0x%02X ", 0xB40, MASK_6B, 4, 0x030, 7, &op_sbc_r_i_cb}, // SBC_R_I + {"SBC R(#0x%02X) Q(#0x%02X)", 0xAB0, MASK_8B, 2, 0x00C, 7, &op_sbc_r_q_cb}, // SBC_R_Q + {"AND R(#0x%02X) #0x%02X ", 0xC80, MASK_6B, 4, 0x030, 7, &op_and_r_i_cb}, // AND_R_I + {"AND R(#0x%02X) Q(#0x%02X)", 0xAC0, MASK_8B, 2, 0x00C, 7, &op_and_r_q_cb}, // AND_R_Q + {"OR R(#0x%02X) #0x%02X ", 0xCC0, MASK_6B, 4, 0x030, 7, &op_or_r_i_cb}, // OR_R_I + {"OR R(#0x%02X) Q(#0x%02X)", 0xAD0, MASK_8B, 2, 0x00C, 7, &op_or_r_q_cb}, // OR_R_Q + {"XOR R(#0x%02X) #0x%02X ", 0xD00, MASK_6B, 4, 0x030, 7, &op_xor_r_i_cb}, // XOR_R_I + {"XOR R(#0x%02X) Q(#0x%02X)", 0xAE0, MASK_8B, 2, 0x00C, 7, &op_xor_r_q_cb}, // XOR_R_Q + {"CP R(#0x%02X) #0x%02X ", 0xDC0, MASK_6B, 4, 0x030, 7, &op_cp_r_i_cb}, // CP_R_I + {"CP R(#0x%02X) Q(#0x%02X)", 0xF00, MASK_8B, 2, 0x00C, 7, &op_cp_r_q_cb}, // CP_R_Q + {"FAN R(#0x%02X) #0x%02X ", 0xD80, MASK_6B, 4, 0x030, 7, &op_fan_r_i_cb}, // FAN_R_I + {"FAN R(#0x%02X) Q(#0x%02X)", 0xF10, MASK_8B, 2, 0x00C, 7, &op_fan_r_q_cb}, // FAN_R_Q + {"RLC R(#0x%02X) ", 0xAF0, MASK_8B, 0, 0, 7, &op_rlc_cb}, // RLC + {"RRC R(#0x%02X) ", 0xE8C, MASK_10B, 0, 0, 5, &op_rrc_cb}, // RRC + {"INC M(#0x%02X) ", 0xF60, MASK_8B, 0, 0, 7, &op_inc_mn_cb}, // INC_MN + {"DEC M(#0x%02X) ", 0xF70, MASK_8B, 0, 0, 7, &op_dec_mn_cb}, // DEC_MN + {"ACPX R(#0x%02X) ", 0xF28, MASK_10B, 0, 0, 7, &op_acpx_cb}, // ACPX + {"ACPY R(#0x%02X) ", 0xF2C, MASK_10B, 0, 0, 7, &op_acpy_cb}, // ACPY + {"SCPX R(#0x%02X) ", 0xF38, MASK_10B, 0, 0, 7, &op_scpx_cb}, // SCPX + {"SCPY R(#0x%02X) ", 0xF3C, MASK_10B, 0, 0, 7, &op_scpy_cb}, // SCPY + {"NOT R(#0x%02X) ", 0xD0F, 0xFCF, 4, 0, 7, &op_not_cb}, // NOT + + {NULL, 0, 0, 0, 0, 0, NULL}, +}; + +static timestamp_t wait_for_cycles(timestamp_t since, u8_t cycles) { + timestamp_t deadline; + + tick_counter += cycles; + + if(speed_ratio == 0) { + /* Emulation will be as fast as possible */ + return g_hal->get_timestamp(); + } + + deadline = since + (cycles * ts_freq) / (TICK_FREQUENCY * speed_ratio); + g_hal->sleep_until(deadline); + + return deadline; +} + +static void process_interrupts(void) { + u8_t i; + + /* Process interrupts in priority order */ + for(i = 0; i < INT_SLOT_NUM; i++) { + if(interrupts[i].triggered) { + //printf("IT %u !\n", i); + SET_M(sp - 1, PCP); + SET_M(sp - 2, PCSH); + SET_M(sp - 3, PCSL); + sp = (sp - 3) & 0xFF; + CLEAR_I(); + np = TO_NP(NBP, 1); + pc = TO_PC(PCB, 1, interrupts[i].vector); + call_depth++; + + ref_ts = wait_for_cycles(ref_ts, 12); + interrupts[i].triggered = 0; + } + } +} + +static void print_state(u8_t op_num, u12_t op, u13_t addr) { + u8_t i; + + if(!g_hal->is_log_enabled(LOG_CPU)) { + return; + } + + g_hal->log(LOG_CPU, "0x%04X: ", addr); + + for(i = 0; i < call_depth; i++) { + g_hal->log(LOG_CPU, " "); + } + + if(ops[op_num].mask_arg0 != 0) { + /* Two arguments */ + g_hal->log( + LOG_CPU, + ops[op_num].log, + (op & ops[op_num].mask_arg0) >> ops[op_num].shift_arg0, + op & ~(ops[op_num].mask | ops[op_num].mask_arg0)); + } else { + /* One argument */ + g_hal->log(LOG_CPU, ops[op_num].log, (op & ~ops[op_num].mask) >> ops[op_num].shift_arg0); + } + + if(call_depth < 10) { + for(i = 0; i < (10 - call_depth); i++) { + g_hal->log(LOG_CPU, " "); + } + } + + g_hal->log(LOG_CPU, " ; 0x%03X - ", op); + for(i = 0; i < 12; i++) { + g_hal->log(LOG_CPU, "%s", ((op >> (11 - i)) & 0x1) ? "1" : "0"); + } + g_hal->log( + LOG_CPU, + " - PC = 0x%04X, SP = 0x%02X, NP = 0x%02X, X = 0x%03X, Y = 0x%03X, A = 0x%X, B = 0x%X, F = 0x%X\n", + pc, + sp, + np, + x, + y, + a, + b, + flags); +} + +void cpu_reset(void) { + u13_t i; + + /* Registers and variables init */ + pc = TO_PC(0, 1, 0x00); // PC starts at bank 0, page 1, step 0 + np = TO_NP(0, 1); // NP starts at page 1 + a = 0; // undef + b = 0; // undef + x = 0; // undef + y = 0; // undef + sp = 0; // undef + flags = 0; + + /* Init RAM to zeros */ + for(i = 0; i < MEM_BUFFER_SIZE; i++) { + memory[i] = 0; + } + + SET_IO_MEMORY(memory, REG_K40_K43_BZ_OUTPUT_PORT, 0xF); // Output port (R40-R43) + SET_IO_MEMORY(memory, REG_LCD_CTRL, 0x8); // LCD control + /* TODO: Input relation register */ + + cpu_sync_ref_timestamp(); +} + +bool_t cpu_init(const u12_t* program, breakpoint_t* breakpoints, u32_t freq) { + g_program = program; + g_breakpoints = breakpoints; + ts_freq = freq; + + cpu_reset(); + + return 0; +} + +void cpu_release(void) { +} + +int cpu_step(void) { + u12_t op; + u8_t i; + breakpoint_t* bp = g_breakpoints; + static u8_t previous_cycles = 0; + + op = g_program[pc]; + + /* Lookup the OP code */ + for(i = 0; ops[i].log != NULL; i++) { + if((op & ops[i].mask) == ops[i].code) { + break; + } + } + + if(ops[i].log == NULL) { + g_hal->log(LOG_ERROR, "Unknown op-code 0x%X (pc = 0x%04X)\n", op, pc); + return 1; + } + + next_pc = (pc + 1) & 0x1FFF; + + /* Display the operation along with the current state of the processor */ + print_state(i, op, pc); + + /* Match the speed of the real processor + * NOTE: For better accuracy, the final wait should happen here, however + * the downside is that all interrupts will likely be delayed by one OP + */ + ref_ts = wait_for_cycles(ref_ts, previous_cycles); + + /* Process the OP code */ + if(ops[i].cb != NULL) { + if(ops[i].mask_arg0 != 0) { + /* Two arguments */ + ops[i].cb( + (op & ops[i].mask_arg0) >> ops[i].shift_arg0, + op & ~(ops[i].mask | ops[i].mask_arg0)); + } else { + /* One arguments */ + ops[i].cb((op & ~ops[i].mask) >> ops[i].shift_arg0, 0); + } + } + + /* Prepare for the next instruction */ + pc = next_pc; + previous_cycles = ops[i].cycles; + + if(i > 0) { + /* OP code is not PSET, reset NP */ + np = (pc >> 8) & 0x1F; + } + + /* Handle timers using the internal tick counter */ + if(tick_counter - clk_timer_timestamp >= TIMER_1HZ_PERIOD) { + do { + clk_timer_timestamp += TIMER_1HZ_PERIOD; + } while(tick_counter - clk_timer_timestamp >= TIMER_1HZ_PERIOD); + + generate_interrupt(INT_CLOCK_TIMER_SLOT, 3); + } + + if(prog_timer_enabled && tick_counter - prog_timer_timestamp >= TIMER_256HZ_PERIOD) { + do { + prog_timer_timestamp += TIMER_256HZ_PERIOD; + prog_timer_data--; + + if(prog_timer_data == 0) { + prog_timer_data = prog_timer_rld; + generate_interrupt(INT_PROG_TIMER_SLOT, 0); + } + } while(tick_counter - prog_timer_timestamp >= TIMER_256HZ_PERIOD); + } + + /* Check if there is any pending interrupt */ + if(I && i > 0) { // Do not process interrupts after a PSET operation + process_interrupts(); + } + + /* Check if we could pause the execution */ + while(bp != NULL) { + if(bp->addr == pc) { + return 1; + } + + bp = bp->next; + } + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/cpu.h b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/cpu.h new file mode 100644 index 000000000..4405103b2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/cpu.h @@ -0,0 +1,215 @@ +/* + * TamaLIB - A hardware agnostic Tamagotchi P1 emulation library + * + * Copyright (C) 2021 Jean-Christophe Rona + * + * 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 2 + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _CPU_H_ +#define _CPU_H_ + +#include "hal.h" + +#define MEMORY_SIZE 4096 // 4096 x 4 bits (640 x 4 bits of RAM) + +#define MEM_RAM_ADDR 0x000 +#define MEM_RAM_SIZE 0x280 +#define MEM_DISPLAY1_ADDR 0xE00 +#define MEM_DISPLAY1_SIZE 0x050 +#define MEM_DISPLAY2_ADDR 0xE80 +#define MEM_DISPLAY2_SIZE 0x050 +#define MEM_IO_ADDR 0xF00 +#define MEM_IO_SIZE 0x080 + +/* Define this if you want to reduce the footprint of the memory buffer from 4096 u4_t (most likely bytes) + * to 464 u8_t (bytes for sure), while increasing slightly the number of operations needed to read/write from/to it. + */ +#define LOW_FOOTPRINT + +#ifdef LOW_FOOTPRINT +/* Invalid memory areas are not buffered to reduce the footprint of the library in memory */ +#define MEM_BUFFER_SIZE (MEM_RAM_SIZE + MEM_DISPLAY1_SIZE + MEM_DISPLAY2_SIZE + MEM_IO_SIZE) / 2 + +/* Maps the CPU memory to the memory buffer */ +#define RAM_TO_MEMORY(n) ((n - MEM_RAM_ADDR) / 2) +#define DISP1_TO_MEMORY(n) ((n - MEM_DISPLAY1_ADDR + MEM_RAM_SIZE) / 2) +#define DISP2_TO_MEMORY(n) ((n - MEM_DISPLAY2_ADDR + MEM_RAM_SIZE + MEM_DISPLAY1_SIZE) / 2) +#define IO_TO_MEMORY(n) \ + ((n - MEM_IO_ADDR + MEM_RAM_SIZE + MEM_DISPLAY1_SIZE + MEM_DISPLAY2_SIZE) / 2) + +#define SET_RAM_MEMORY(buffer, n, v) \ + { \ + buffer[RAM_TO_MEMORY(n)] = (buffer[RAM_TO_MEMORY(n)] & ~(0xF << (((n) % 2) << 2))) | \ + ((v)&0xF) << (((n) % 2) << 2); \ + } +#define SET_DISP1_MEMORY(buffer, n, v) \ + { \ + buffer[DISP1_TO_MEMORY(n)] = (buffer[DISP1_TO_MEMORY(n)] & ~(0xF << (((n) % 2) << 2))) | \ + ((v)&0xF) << (((n) % 2) << 2); \ + } +#define SET_DISP2_MEMORY(buffer, n, v) \ + { \ + buffer[DISP2_TO_MEMORY(n)] = (buffer[DISP2_TO_MEMORY(n)] & ~(0xF << (((n) % 2) << 2))) | \ + ((v)&0xF) << (((n) % 2) << 2); \ + } +#define SET_IO_MEMORY(buffer, n, v) \ + { \ + buffer[IO_TO_MEMORY(n)] = (buffer[IO_TO_MEMORY(n)] & ~(0xF << (((n) % 2) << 2))) | \ + ((v)&0xF) << (((n) % 2) << 2); \ + } +#define SET_MEMORY(buffer, n, v) \ + { \ + if((n) < (MEM_RAM_ADDR + MEM_RAM_SIZE)) { \ + SET_RAM_MEMORY(buffer, n, v); \ + } else if((n) < MEM_DISPLAY1_ADDR) { \ + /* INVALID_MEMORY */ \ + } else if((n) < (MEM_DISPLAY1_ADDR + MEM_DISPLAY1_SIZE)) { \ + SET_DISP1_MEMORY(buffer, n, v); \ + } else if((n) < MEM_DISPLAY2_ADDR) { \ + /* INVALID_MEMORY */ \ + } else if((n) < (MEM_DISPLAY2_ADDR + MEM_DISPLAY2_SIZE)) { \ + SET_DISP2_MEMORY(buffer, n, v); \ + } else if((n) < MEM_IO_ADDR) { \ + /* INVALID_MEMORY */ \ + } else if((n) < (MEM_IO_ADDR + MEM_IO_SIZE)) { \ + SET_IO_MEMORY(buffer, n, v); \ + } else { \ + /* INVALID_MEMORY */ \ + } \ + } + +#define GET_RAM_MEMORY(buffer, n) ((buffer[RAM_TO_MEMORY(n)] >> (((n) % 2) << 2)) & 0xF) +#define GET_DISP1_MEMORY(buffer, n) ((buffer[DISP1_TO_MEMORY(n)] >> (((n) % 2) << 2)) & 0xF) +#define GET_DISP2_MEMORY(buffer, n) ((buffer[DISP2_TO_MEMORY(n)] >> (((n) % 2) << 2)) & 0xF) +#define GET_IO_MEMORY(buffer, n) ((buffer[IO_TO_MEMORY(n)] >> (((n) % 2) << 2)) & 0xF) +#define GET_MEMORY(buffer, n) \ + ((buffer \ + [((n) < (MEM_RAM_ADDR + MEM_RAM_SIZE)) ? RAM_TO_MEMORY(n) : \ + ((n) < MEM_DISPLAY1_ADDR) ? 0 : \ + ((n) < (MEM_DISPLAY1_ADDR + MEM_DISPLAY1_SIZE)) ? DISP1_TO_MEMORY(n) : \ + ((n) < MEM_DISPLAY2_ADDR) ? 0 : \ + ((n) < (MEM_DISPLAY2_ADDR + MEM_DISPLAY2_SIZE)) ? DISP2_TO_MEMORY(n) : \ + ((n) < MEM_IO_ADDR) ? 0 : \ + ((n) < (MEM_IO_ADDR + MEM_IO_SIZE)) ? IO_TO_MEMORY(n) : \ + 0] >> \ + (((n) % 2) << 2)) & \ + 0xF) + +#define MEM_BUFFER_TYPE u8_t +#else +#define MEM_BUFFER_SIZE MEMORY_SIZE + +#define SET_MEMORY(buffer, n, v) \ + { buffer[n] = v; } +#define SET_RAM_MEMORY(buffer, n, v) SET_MEMORY(buffer, n, v) +#define SET_DISP1_MEMORY(buffer, n, v) SET_MEMORY(buffer, n, v) +#define SET_DISP2_MEMORY(buffer, n, v) SET_MEMORY(buffer, n, v) +#define SET_IO_MEMORY(buffer, n, v) SET_MEMORY(buffer, n, v) + +#define GET_MEMORY(buffer, n) (buffer[n]) +#define GET_RAM_MEMORY(buffer, n) GET_MEMORY(buffer, n) +#define GET_DISP1_MEMORY(buffer, n) GET_MEMORY(buffer, n) +#define GET_DISP2_MEMORY(buffer, n) GET_MEMORY(buffer, n) +#define GET_IO_MEMORY(buffer, n) GET_MEMORY(buffer, n) + +#define MEM_BUFFER_TYPE u4_t +#endif + +typedef struct breakpoint { + u13_t addr; + struct breakpoint* next; +} breakpoint_t; + +/* Pins (TODO: add other pins) */ +typedef enum { + PIN_K00 = 0x0, + PIN_K01 = 0x1, + PIN_K02 = 0x2, + PIN_K03 = 0x3, + PIN_K10 = 0X4, + PIN_K11 = 0X5, + PIN_K12 = 0X6, + PIN_K13 = 0X7, +} pin_t; + +typedef enum { + PIN_STATE_LOW = 0, + PIN_STATE_HIGH = 1, +} pin_state_t; + +typedef enum { + INT_PROG_TIMER_SLOT = 0, + INT_SERIAL_SLOT = 1, + INT_K10_K13_SLOT = 2, + INT_K00_K03_SLOT = 3, + INT_STOPWATCH_SLOT = 4, + INT_CLOCK_TIMER_SLOT = 5, + INT_SLOT_NUM, +} int_slot_t; + +typedef struct { + u4_t factor_flag_reg; + u4_t mask_reg; + bool_t triggered; /* 1 if triggered, 0 otherwise */ + u8_t vector; +} interrupt_t; + +typedef struct { + u13_t* pc; + u12_t* x; + u12_t* y; + u4_t* a; + u4_t* b; + u5_t* np; + u8_t* sp; + u4_t* flags; + + u32_t* tick_counter; + u32_t* clk_timer_timestamp; + u32_t* prog_timer_timestamp; + bool_t* prog_timer_enabled; + u8_t* prog_timer_data; + u8_t* prog_timer_rld; + + u32_t* call_depth; + + interrupt_t* interrupts; + + MEM_BUFFER_TYPE* memory; +} state_t; + +void cpu_add_bp(breakpoint_t** list, u13_t addr); +void cpu_free_bp(breakpoint_t** list); + +void cpu_set_speed(u8_t speed); + +state_t* cpu_get_state(void); + +u32_t cpu_get_depth(void); + +void cpu_set_input_pin(pin_t pin, pin_state_t state); + +void cpu_sync_ref_timestamp(void); + +void cpu_refresh_hw(void); + +void cpu_reset(void); + +bool_t cpu_init(const u12_t* program, breakpoint_t* breakpoints, u32_t freq); +void cpu_release(void); + +int cpu_step(void); + +#endif /* _CPU_H_ */ diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/hal.h b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/hal.h new file mode 100644 index 000000000..84140befb --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/hal.h @@ -0,0 +1,89 @@ +/* + * TamaLIB - A hardware agnostic Tamagotchi P1 emulation library + * + * Copyright (C) 2021 Jean-Christophe Rona + * + * 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 2 + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _HAL_H_ +#define _HAL_H_ + +#include "../hal_types.h" + +#ifndef NULL +#define NULL 0 +#endif + +typedef enum { + LOG_ERROR = 0x1, + LOG_INFO = (0x1 << 1), + LOG_MEMORY = (0x1 << 2), + LOG_CPU = (0x1 << 3), +} log_level_t; + +/* The Hardware Abstraction Layer + * NOTE: This structure acts as an abstraction layer between TamaLIB and the OS/SDK. + * All pointers MUST be implemented, but some implementations can be left empty. + */ +typedef struct { + /* Memory allocation functions + * NOTE: Needed only if breakpoints support is required. + */ + void* (*malloc)(u32_t size); + void (*free)(void* ptr); + + /* What to do if the CPU has halted + */ + void (*halt)(void); + + /* Log related function + * NOTE: Needed only if log messages are required. + */ + bool_t (*is_log_enabled)(log_level_t level); + void (*log)(log_level_t level, char* buff, ...); + + /* Clock related functions + * NOTE: Timestamps granularity is configured with tamalib_init(), an accuracy + * of ~30 us (1/32768) is required for a cycle accurate emulation. + */ + void (*sleep_until)(timestamp_t ts); + timestamp_t (*get_timestamp)(void); + + /* Screen related functions + * NOTE: In case of direct hardware access to pixels, the set_XXXX() functions + * (called for each pixel/icon update) can directly drive them, otherwise they + * should just store the data in a buffer and let update_screen() do the actual + * rendering (at 30 fps). + */ + void (*update_screen)(void); + void (*set_lcd_matrix)(u8_t x, u8_t y, bool_t val); + void (*set_lcd_icon)(u8_t icon, bool_t val); + + /* Sound related functions + * NOTE: set_frequency() changes the output frequency of the sound, while + * play_frequency() decides whether the sound should be heard or not. + */ + void (*set_frequency)(u32_t freq); + void (*play_frequency)(bool_t en); + + /* Event handler from the main app (if any) + * NOTE: This function usually handles button related events, states loading/saving ... + */ + int (*handler)(void); +} hal_t; + +extern hal_t* g_hal; + +#endif /* _HAL_H_ */ diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/hal_types.h.template b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/hal_types.h.template new file mode 100644 index 000000000..38c4d212c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/hal_types.h.template @@ -0,0 +1,32 @@ +/* + * TamaLIB - A hardware agnostic Tamagotchi P1 emulation library + * + * Copyright (C) 2021 Jean-Christophe Rona + * + * 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 2 + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _HAL_TYPES_H_ +#define _HAL_TYPES_H_ + +typedef unsigned char bool_t; +typedef unsigned char u4_t; +typedef unsigned char u5_t; +typedef unsigned char u8_t; +typedef unsigned short u12_t; +typedef unsigned short u13_t; +typedef unsigned int u32_t; +typedef unsigned int timestamp_t; // WARNING: Must be an unsigned type to properly handle wrapping (u32 wraps in around 1h11m when expressed in us) + +#endif /* _HAL_TYPES_H_ */ diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/hw.c b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/hw.c new file mode 100644 index 000000000..0a91f2a78 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/hw.c @@ -0,0 +1,134 @@ +/* + * TamaLIB - A hardware agnostic Tamagotchi P1 emulation library + * + * Copyright (C) 2021 Jean-Christophe Rona + * + * 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 2 + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "hw.h" +#include "cpu.h" +#include "hal.h" + +/* SEG -> LCD mapping */ +static u8_t seg_pos[40] = {0, 1, 2, 3, 4, 5, 6, 7, 32, 8, 9, 10, 11, 12, + 13, 14, 15, 33, 34, 35, 31, 30, 29, 28, 27, 26, 25, 24, + 36, 23, 22, 21, 20, 19, 18, 17, 16, 37, 38, 39}; + +bool_t hw_init(void) { + /* Buttons are active LOW */ + cpu_set_input_pin(PIN_K00, PIN_STATE_HIGH); + cpu_set_input_pin(PIN_K01, PIN_STATE_HIGH); + cpu_set_input_pin(PIN_K02, PIN_STATE_HIGH); + + return 0; +} + +void hw_release(void) { +} + +void hw_set_lcd_pin(u8_t seg, u8_t com, u8_t val) { + if(seg_pos[seg] < LCD_WIDTH) { + g_hal->set_lcd_matrix(seg_pos[seg], com, val); + } else { + /* + * IC n -> seg-com|... + * IC 0 -> 8-0 |18-3 |19-2 + * IC 1 -> 8-1 |17-0 |19-3 + * IC 2 -> 8-2 |17-1 |37-12|38-13|39-14 + * IC 3 -> 8-3 |17-2 |18-1 |19-0 + * IC 4 -> 28-12|37-13|38-14|39-15 + * IC 5 -> 28-13|37-14|38-15 + * IC 6 -> 28-14|37-15|39-12 + * IC 7 -> 28-15|38-12|39-13 + */ + if(seg == 8 && com < 4) { + g_hal->set_lcd_icon(com, val); + } else if(seg == 28 && com >= 12) { + g_hal->set_lcd_icon(com - 8, val); + } + } +} + +void hw_set_button(button_t btn, btn_state_t state) { + pin_state_t pin_state = (state == BTN_STATE_PRESSED) ? PIN_STATE_LOW : PIN_STATE_HIGH; + + switch(btn) { + case BTN_LEFT: + cpu_set_input_pin(PIN_K02, pin_state); + break; + + case BTN_MIDDLE: + cpu_set_input_pin(PIN_K01, pin_state); + break; + + case BTN_RIGHT: + cpu_set_input_pin(PIN_K00, pin_state); + break; + } +} + +void hw_set_buzzer_freq(u4_t freq) { + u32_t snd_freq = 0; + + switch(freq) { + case 0: + /* 4096.0 Hz */ + snd_freq = 40960; + break; + + case 1: + /* 3276.8 Hz */ + snd_freq = 32768; + break; + + case 2: + /* 2730.7 Hz */ + snd_freq = 27307; + break; + + case 3: + /* 2340.6 Hz */ + snd_freq = 23406; + break; + + case 4: + /* 2048.0 Hz */ + snd_freq = 20480; + break; + + case 5: + /* 1638.4 Hz */ + snd_freq = 16384; + break; + + case 6: + /* 1365.3 Hz */ + snd_freq = 13653; + break; + + case 7: + /* 1170.3 Hz */ + snd_freq = 11703; + break; + } + + if(snd_freq != 0) { + g_hal->set_frequency(snd_freq); + } +} + +void hw_enable_buzzer(bool_t en) { + g_hal->play_frequency(en); +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/hw.h b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/hw.h new file mode 100644 index 000000000..853515b39 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/hw.h @@ -0,0 +1,50 @@ +/* + * TamaLIB - A hardware agnostic Tamagotchi P1 emulation library + * + * Copyright (C) 2021 Jean-Christophe Rona + * + * 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 2 + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _HW_H_ +#define _HW_H_ + +#include "hal.h" + +#define LCD_WIDTH 32 +#define LCD_HEIGHT 16 + +#define ICON_NUM 8 + +typedef enum { + BTN_STATE_RELEASED = 0, + BTN_STATE_PRESSED, +} btn_state_t; + +typedef enum { + BTN_LEFT = 0, + BTN_MIDDLE, + BTN_RIGHT, +} button_t; + +bool_t hw_init(void); +void hw_release(void); + +void hw_set_lcd_pin(u8_t seg, u8_t com, u8_t val); +void hw_set_button(button_t btn, btn_state_t state); + +void hw_set_buzzer_freq(u4_t freq); +void hw_enable_buzzer(bool_t en); + +#endif /* _HW_H_ */ diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/tamalib.c b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/tamalib.c new file mode 100644 index 000000000..92a19678c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/tamalib.c @@ -0,0 +1,128 @@ +/* + * TamaLIB - A hardware agnostic Tamagotchi P1 emulation library + * + * Copyright (C) 2021 Jean-Christophe Rona + * + * 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 2 + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "tamalib.h" +#include "hw.h" +#include "cpu.h" +#include "hal.h" + +#define DEFAULT_FRAMERATE 30 // fps + +static exec_mode_t exec_mode = EXEC_MODE_RUN; + +static u32_t step_depth = 0; + +static timestamp_t screen_ts = 0; + +static u32_t ts_freq; + +static u8_t g_framerate = DEFAULT_FRAMERATE; + +hal_t* g_hal; + +bool_t tamalib_init(const u12_t* program, breakpoint_t* breakpoints, u32_t freq) { + bool_t res = 0; + + res |= cpu_init(program, breakpoints, freq); + res |= hw_init(); + + ts_freq = freq; + + return res; +} + +void tamalib_release(void) { + hw_release(); + cpu_release(); +} + +void tamalib_set_framerate(u8_t framerate) { + g_framerate = framerate; +} + +u8_t tamalib_get_framerate(void) { + return g_framerate; +} + +void tamalib_register_hal(hal_t* hal) { + g_hal = hal; +} + +void tamalib_set_exec_mode(exec_mode_t mode) { + exec_mode = mode; + step_depth = cpu_get_depth(); + cpu_sync_ref_timestamp(); +} + +void tamalib_step(void) { + if(exec_mode == EXEC_MODE_PAUSE) { + return; + } + + if(cpu_step()) { + exec_mode = EXEC_MODE_PAUSE; + step_depth = cpu_get_depth(); + } else { + switch(exec_mode) { + case EXEC_MODE_PAUSE: + case EXEC_MODE_RUN: + break; + + case EXEC_MODE_STEP: + exec_mode = EXEC_MODE_PAUSE; + break; + + case EXEC_MODE_NEXT: + if(cpu_get_depth() <= step_depth) { + exec_mode = EXEC_MODE_PAUSE; + step_depth = cpu_get_depth(); + } + break; + + case EXEC_MODE_TO_CALL: + if(cpu_get_depth() > step_depth) { + exec_mode = EXEC_MODE_PAUSE; + step_depth = cpu_get_depth(); + } + break; + + case EXEC_MODE_TO_RET: + if(cpu_get_depth() < step_depth) { + exec_mode = EXEC_MODE_PAUSE; + step_depth = cpu_get_depth(); + } + break; + } + } +} + +void tamalib_mainloop(void) { + timestamp_t ts; + + while(!g_hal->handler()) { + tamalib_step(); + + /* Update the screen @ g_framerate fps */ + ts = g_hal->get_timestamp(); + if(ts - screen_ts >= ts_freq / g_framerate) { + screen_ts = ts; + g_hal->update_screen(); + } + } +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/tamalib.h b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/tamalib.h new file mode 100644 index 000000000..570f845eb --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tama_p1/tamalib/tamalib.h @@ -0,0 +1,65 @@ +/* + * TamaLIB - A hardware agnostic Tamagotchi P1 emulation library + * + * Copyright (C) 2021 Jean-Christophe Rona + * + * 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 2 + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _TAMALIB_H_ +#define _TAMALIB_H_ + +#include "cpu.h" +#include "hw.h" +#include "hal.h" + +#define tamalib_set_button(btn, state) hw_set_button(btn, state) + +#define tamalib_set_speed(speed) cpu_set_speed(speed) + +#define tamalib_get_state() cpu_get_state() +#define tamalib_refresh_hw() cpu_refresh_hw() + +#define tamalib_reset() cpu_reset() + +#define tamalib_add_bp(list, addr) cpu_add_bp(list, addr) +#define tamalib_free_bp(list) cpu_free_bp(list) + +typedef enum { + EXEC_MODE_PAUSE, + EXEC_MODE_RUN, + EXEC_MODE_STEP, + EXEC_MODE_NEXT, + EXEC_MODE_TO_CALL, + EXEC_MODE_TO_RET, +} exec_mode_t; + +void tamalib_release(void); +bool_t tamalib_init(const u12_t* program, breakpoint_t* breakpoints, u32_t freq); + +void tamalib_set_framerate(u8_t framerate); +u8_t tamalib_get_framerate(void); + +void tamalib_register_hal(hal_t* hal); + +void tamalib_set_exec_mode(exec_mode_t mode); + +/* NOTE: Only one of these two functions must be used in the main application + * (tamalib_step() should be used only if tamalib_mainloop() does not fit the + * main application execution flow). + */ +void tamalib_step(void); +void tamalib_mainloop(void); + +#endif /* _TAMALIB_H_ */ diff --git a/Applications/Official/DEV_FW/source/xMasterX/tanksgame/application.fam b/Applications/Official/DEV_FW/source/xMasterX/tanksgame/application.fam new file mode 100644 index 000000000..d25d634d4 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tanksgame/application.fam @@ -0,0 +1,13 @@ +App( + appid="Tanks", + name="Tanks", + apptype=FlipperAppType.EXTERNAL, + entry_point="tanks_game_app", + cdefines=["APP_TANKS_GAME"], + requires=["gui", "subghz"], + stack_size=4 * 1024, + order=730, + fap_icon="tanksIcon.png", + fap_category="Games_Extra", + fap_icon_assets="images", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/tanksgame/constants.h b/Applications/Official/DEV_FW/source/xMasterX/tanksgame/constants.h new file mode 100644 index 000000000..d65dd32ea --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/tanksgame/constants.h @@ -0,0 +1,19 @@ +#ifndef FLIPPERZERO_FIRMWARE_CONSTANTS_H +#define FLIPPERZERO_FIRMWARE_CONSTANTS_H + +const uint8_t SCREEN_WIDTH_TANKS = 128; +const uint8_t SCREEN_HEIGHT_TANKS = 64; + +const uint8_t FIELD_WIDTH = 16; +const uint8_t FIELD_HEIGHT = 11; + +const uint16_t TURN_LENGTH = 300; +const uint16_t LONG_PRESS_LENGTH = 10; + +const uint8_t SHOT_COOLDOWN = 5; +const uint8_t RESPAWN_COOLDOWN = 8; +const uint8_t PLAYER_RESPAWN_COOLDOWN = 1; + +const uint8_t CELL_LENGTH_PIXELS = 6; + +#endif diff --git a/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/HappyFlipper_128x64.png b/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/HappyFlipper_128x64.png new file mode 100644 index 0000000000000000000000000000000000000000..d95412f3fc948ab35488bfb2863d5e99c1549b5b GIT binary patch literal 633 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`2qYMOt#!Htq*&4&eH|GXHuiJ>Nn{1`6_P!I zd>I(3)PQPRfU1B(4KElNN(~qoUL`OvSj}Ky5HFasE6@fg!Ib3f?!v&Zs#nFUg#aNWqT?B^gg;;v2;nhMNKJLf3T*3IsVgV7dR_e+i&DK>CL@b;;?HY7${s#- z^dG;E#QH-VU$wqW2z=4(?9Q_9+nE^x9`X#O9tr=re1e%iv1a@cxUihJjh`vffYB`D z!U2}t={q+)5&UtD#qRq}KMtlziQ z;92-;WxFTKS-nj4a(Sg%#a_AzPXy z-$k)A9y!psp>mFix#BU^lr>xVG-b}bndkmd_{k!c87VtUrWPbDi*0<)#qn^~<)a1* z`V2oO1iLm=@|AtxcRH#v!i-&Cft%}vsDM6y#hZqoySijVKL1UfoZgwTug8jgg7&6d z&x1C97}srF_~*_f^-5s;sFt`!l%ynNn{1`6_P!I zd>I(3)PQPRfU1B(4KElNN(~qoUL`OvSj}Ky5HFasE6@fg!Ib3f?!v&Zs#nc$C93Y zeX@v*%x>qE6Z^g7T+aJ{S)JhwPn5hKZX%YYRdd3GW14FgMqKS)=4`_G<P}pY7HK!7(1s9z{6!B^^Dy_QLOoG6AL8?^-lpamao#FwmRvp9Qt&?;-4$LS3#+Pb|YeY#(Vo9o1a#1RfVlXl= zGSW3P)HN^(F*39=HnK9c&^9ozGBB7oWAh&r4Y~O#nQ4`{HM~E{?Euuk;OXk;vd$@? F2>|m+_4)t+ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/enemy_down.png b/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/enemy_down.png new file mode 100644 index 0000000000000000000000000000000000000000..84d64ed44d7a46e8438d789c73258f7f48b6f9f7 GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^Y#_`5A|IT2?*XJ3i-X*q7}lMWc?smOq&xaLGB9lH z=l+w(3gmMZctjR6Fz_7#VaBQ2e9}NcBTpB{5Q*^Ql!SyI{45S!j1rQPk_UtY^t2M1 wE-BFVdQ&MBb@0P}AtS^xk5 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/enemy_left.png b/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/enemy_left.png new file mode 100644 index 0000000000000000000000000000000000000000..e118d03a88a35f189f7e9d64be46dc975a331ab7 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^Y#_`5A|IT2?*XJ3i-X*q7}lMWc?smOq&xaLGB9lH z=l+w(3gmMZctjR6Fz_7#VaBQ2e9}Nc6Hgb%5Q*^IUPmql1CGNz|Nn2^%<7n8$#HZ_ z5U;@WD=+6CUNC3V@{O$KbxYP5exD{?F4Muzpe)S2)$X1wP(OpGtDnm{r-UW|6qPM^ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/enemy_right.png b/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/enemy_right.png new file mode 100644 index 0000000000000000000000000000000000000000..8c5f0603b7b1a85df0e552a9688476f9e2e22d62 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^Y#_`5A|IT2?*XJ3i-X*q7}lMWc?smOq&xaLGB9lH z=l+w(3gmMZctjR6Fz_7#VaBQ2e9}Nc6Hgb%5Q*^8UPdkk0}iIG|Nq}i4cKy!Pvn#e zQ@|@Hp+nnVTArF5H$lhugHhx9p4r!)?<`V&n88y~tIWJ%b?kTQ*z$8GBNPe82zopr0N&Lc Az5oCK literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/projectile_left.png b/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/projectile_left.png new file mode 100644 index 0000000000000000000000000000000000000000..c8c54786d99cb80a5c434adefcd22148164f24af GIT binary patch literal 106 zcmeAS@N?(olHy`uVBq!ia0vp^Y#_`5A|IT2?*XI?JzX3_IAoLm@U!qlFmU_yOq?iq zEQMiZD$~actd2FVdQ&MBb@ E0RPGx3;+NC literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/projectile_up.png b/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/projectile_up.png new file mode 100644 index 0000000000000000000000000000000000000000..5324466572c019530b09851a69d82dc8d9ccfa96 GIT binary patch literal 102 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/tank_down.png b/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/tank_down.png new file mode 100644 index 0000000000000000000000000000000000000000..d4e2c8786011e5d8e0c2227b748afd672521cbde GIT binary patch literal 3040 zcmYLLc|6pQ7X8}Bm_hdJLMS^CAz4aXBodSKH&-lN^LAz zOwJTV=WuYWyyIaEZlbD2Lsm!9tkS`CZc_Eai z)70td=H0<(PifP15yJhPNuQ8Xfa+DdbiZ&VBea7Kg9g|bU|Wp*sjO0|RK3%Kb0t zX^OdIWHM{I9v4T-U9H;i-H)nKOY%2v^Q(3l%;IP~P3Qs9*xucZ zyq$#f!=%@3OU>QiiUPvJS~{l{2U4C;1`OC&)~4b6qGbW}hMxS44B>A8x;M zbCvfCN))_9a!8q`jf5GeyNd05?Ba!S3F3%DY-N2V8<4RZa$wxXR?w2oakTwPAy6p* z_eCAw4Z5KS&=4Ky4Ua9o{T$dK zQsx&^23tLUv&wj$}DR55v5klW2nYU|Q$I zR~e$_r1+VrBuz$r&3INzaW>=Asu=k*_VFyuh8=Ka9`+vn1UTd@#(n6<-OC8pO#P7| z(F)N60WG?`7)8UGp?@mG1Y>9Q3XnWz7_aJ!XjV$pQ)MVSMsmK#57Ndu7zLdh@RM?Y zieYl+U;nzbr#Q{r8Qlv9N+XI1+wiP&(tSd_n8fQ+gtHYR6%q)h7kne}_Y8xIeFz6| z$qI|R^7urLLWN=CDsZ0%pX3zlgq@8h8j0y?5GVv+!r?Gs)t6t@2A|$ zFXOO^oQS)W(j3v8B+%W~>soXF70W1#Pz1KC%+< zaR@VK$H;ZxnrELMob#Cn`HO8p9yqos%$^cUJw3m*!Mhi=_i4|5Z)MLP!$pdpGXRVK z0yjr&7Wng=1DD8mrac#fI)v~I+Lma9}v+Jnfw_&sZVeSK$=ow%8PMYVO&&H4DZ zQZZpM7H4_WFOhR`dg*BwGk#}Gn(UhRlHF@nCNhLA1|@u@$1*5s1y8QX-sG+1nMl;> zQBPD)97t^Bakd2WNJ5foqtmZHFBB$B7bc(M#3g68Woq7dnRyQfJGUc?J#UrijWfhu zz-gQpLv*~-DZyB&SZ~~#f6i0!`S~*|fx_Yn5W-hByCuIRJ2XQhsSg+5Je-w$OuI@ca|Y-etdEq!M*RWVu-Y`PwGARJ^7 z)DfB%nsMN`LlItf z=Ro^W{l2zu_)_=`lJfXw0#yR@RuY#-2iNP*+SSUxRuGautX#DwS?^mbSXV6z3?>!W zXjKKyYM_{Z-2c%&ddeGtruW|ToI_JIzOzs{D1o{UP@ZOMUoS@j;B3 zMf4&vJH{>N_ODRBXotTs|AJj?=&hvW&F8Nk6CM@BIva1q(alZ9b?koRv@^peaEyI~izK30pHNpgF4{PlM>^9+v_I;x` zWMo{SfwIIlpEcCE98~fXcJzcVz2SD4)p=`4b8a9H$cx zvzq0n8qf%?vlB8gB}t`~c4{S-Ez%b<|B?AY38oOq$2r`2f#~MVfZ<>Dq**0YTmh+lklYaW7Mfvl0;Mckjr1RI^}6I2RS?5 zOp{C~D5ztLMl6EYz;BMXl7hN^Qis1lJE@a*8*A<@HcB`RXS)7aNL*0LZOSG7aoIBb zdWt(YLn9XJ#2BV>!j-KMQ-iDc6ONS*|XH%u+_%S8?wati2lAb zJ$ZMcsXSp8@t9FKP2}N5-~#3H^{A9!VK-6KpPtohk>2OMN%*4W>E&TQeN$(Y18O(n z4Y!Cl(YrUi{ve2E(w?DSj!U5^z)%^WI{XV{{esN5MC`JufyVo&)pRiN5HPG;L zf2Q2`;k4GHsg>V7+H2Z2RK>Qb8Sat5DvhE>swj1K=xF<}O3eKVe|Xbx&SlGCx6)o- zi@N;J#~#1!tqR<}JP#{4Mp;Pa>k7}YxBYQEILsztJeNFqDM1BerzY6*gntWl?7I#p zk+K)E7bRn8@Z;VTo3g5~{jRN46rqL?RV7s=Gm8#=xe-j$J`53YD{`}#^=uQP!M80J z7b7kDE%FN7bgzg}_A!Sy_ea)HQ;mhbsnV*_(%r%=o-cUy#2H{P(A+>+$(0m_h)`}| zq4?Wz=#9c}8YG@bTKA{RdpJ#c_!v}g2?AiM7~r?Cb#=y%A)AWe(lfy}z|;h}xAQ6< z?Wrx2v=mtHr}W12&K>+XIq)7?F$RWcq2)UCjFcQT5j+EfBQ0|yoMl#y-h zoUiK47R?JAKIT$O|L9l9kwvYuu+sJw>DZH(7k$Up#KYVikUi00fRRoRU^-EBC(xx6 z`kywUI|nfQ+ouPBI4^+lzZuvG|1Fmj{GIs^(-+eJF99lK_`g0$0NIYIv=d_SGqwu^ z0QT;`pv#nF7dkN&O|I%Az#?w$E-rhg81*1@`~m_3{E-d_%L*NC0})whCu6OM@*|4JNifdZ$|SDyMts+o8@p5sJ<%>V&rvnbV{YK>6V)I1J3 zox88Z3I#NaeH^UXw>S6qON)N6tyKXms1B<%Kf zD_z`5Y`b#KuWBSk<74`^$;S$L4aY3yD>FSWT$0_iU%^$(Zy)>db&VYo-I*cYD`uib za`CiBe=2)iJFc1%+r7j{+-dY!-=+;`o!lL`8|%F_4mWg*3R@<9-QJQN^0x3SYtTM1 z)p2J?!F)xnckL}U zF0B0llKAeNmp@`MbH*`2-T27|=ab0fKIcU0WrBFkP>nWVF*&s$x2hes=w$SBpt|N` zW9Oxa$K#p(R~)Q$0F_vvNI&C^_zEb>8ZaR6+QMjAHDrZI^(e4n6pv<pSBSZ~OWiu7eKZ8C@STl*up1DL*JakK|1dP8|Vyu-jihWr$ zR-`uwUKEi?EXWbRdEvG4SwK2=J|~@Qn~Nlue&+qu!(3;MF(ZB|Zc9E$`rK;g?5OT- z0f%v?-aqvo=e*&Pd|lOf#gzxasjkjGJFy4 zOpY&xd~I3;6YFNR27^9v%j?P8%?s)e?{_$z>20wg-;r9~Nu>SyM);=i?eRmLv9fWE z>_xvvu8&-+XH-7eih@4Gx8}gf-!3UBb|@kh<;=OD*P%Yp9{0(7(Q5uTPaY9f#WGsEaCVJUuH-vq3-(uNibxQjn=2Pc z7X*Gb!Q*ku_*{H?=}=LY^>S`5vpqoj{7WYzeRCE$^76pt>&2^Iv`e%~CaiyF>zPj2 zynN-9H<=eDV=gva9*wR-x!P%4~6Ji4BEdf5R@lWQn3Ys4{#$_jfe8%Nfxx zo|d$pbm_cGBXB-*@0#}>4L69wHCUY4v3m!1p{PY>Om+b`PY z1?NHQ66=y;6|uRopIi%#HyuAZGU{^b-Vj1nFwf!L-rYRi5z24z75FB6;+N8p2kSG8 zwB9AsX3uEL*@?TaexW3f5)Fu9L~SCnX1>O8Okzwo$W2$jUMr|P=+&~y_pOck?<^gx zwAdMMU#2g6k@-#0&pSXW=yZU2!07Z~cOC+jNz6zmA$py9y+{|&M*8~&(EN24*Wya^ zys#xay)wQ7cV?-}eoKTKRE4+u%t;2B(Xv|fD|pe9PFo*mY?0jC&E2J4 z8`r8fo(4;AZqt`%8oTNzc;{wWHs1#3N@pbJ9F~8-zc{7#;Z=*z;8aUwY-A_^gD7Te zW~Z0;%vUXa&An%JuN2hBn-VP>U2;E*hsb*&dQ7aDA9T$7>W`b`&qkkHp9>4O3VxMX zJ2NOBaE1BGWu)R$#fyp?)7sO@ZMt$r|GFS2XwvZb=Rd8R>Uw5#A}RoWBxzM5K=JiQE+{yZ3;<+SfWonT8Bmc&_u{yPotOox{^{GeK+9R{RKX-h7?%B-q zDlKkK#~7ck<{R=JB;n%tel$ZP@O1i(phT7T zu`^BXs@*jzl4)F+4a~^}S5Gf70ncX?nuYrmZM%A++N(-`9?g()pfotX-m#~IthA3a zLLx%+%MD)9DNMWKTK|czJ$xBH^fIb6_41uEgq=-=hj01*DCbiAQvcA^zS>^3?#Nm_ zk8p>3K`o=v_gFjcycBWpXQCUoeJ3h@hyL7bWz}ns{#7>0E|0ej$RBx2&0%-LRtl8$ zM|QAVZSUv5^<0G}L+fjtYvXHvKD+zugrbdVx3c8OTW2qVPHscd&O}ZAn5ylF?e|Hm zan-R&TXDy)_U?9X@)s|>$=<&G$kuW|uv}X5PS^--EW|6FL1~{DtxvoYxp#>@+jxF2 z^o7?WFXhFGz^{RQ8z!vforEo$UA><055JpMjxDovg(K);jW*%ChUNF60>1alT-exF zGBGY(uvXh%d&M&cc~pkO)Xmgshr}lIea_C6?#Sqnh(v6=cla%?=6Dq8)P}q^{?tD# zF+3VB`vYxC^cq{eRvs}CY0Yx$IrYT`T9{DCZ*`GG)72PKy)C0d^bg9u?%B~ssAQ~= zgmk9@PcmEc6C;lG1y-HybM&tdSgY!u6S2*(wWpkQ`m1T)cbOd+x71NDRsX{0%*4&c zg|O=K(1^_ihZD8ElN)v6tAf9Kztr=yf;Q2=#+NLa%k>@g$N>G_y(QkSLhUk?@R$(X zPrC)b4~k;Ucttk8Y?i$8r;r5)L6uTQhHQV>_c#Q#pdGWfmUK z0@;&XQPi7n-(?-SxoxR#OxIrx5YmGt1B1Un!gZi1`VxS{%c-aw`FC^!ztO4qiKERy zL2IjODX_7xRvoe-kaF5=LPBi;KsV=L+n+@soREmsH-e`&P6Eqy1L3=QOo&gClvb49 z;t)YAT#ik&*xZSea4aDH*dl?e&WhiF)5cC9;Yl@ q=-vv0=3zL-1Gr)wzcK} literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/tank_hedgehog.png b/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/tank_hedgehog.png new file mode 100644 index 0000000000000000000000000000000000000000..fdd804be97d5abda446013eb1c58999ca516a62e GIT binary patch literal 3049 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/tank_wall.png b/Applications/Official/DEV_FW/source/xMasterX/tanksgame/images/tank_wall.png new file mode 100644 index 0000000000000000000000000000000000000000..88d537cdb70009c0f3a4e82df66b5729d4938f65 GIT binary patch literal 3039 zcmYLLc{tRK8vPkNHQdN9vW&r4#+sCE#xg<^CPG3e@nsoAwn+(*5<)Y%#=cILVr0ou z7(yXr9mEV`LNR2y`tE(c`##Tk&w0*s-uLg5h_*35&LhSH0KjpS1=9A2IsSm_&!&E4 zSO5UetPcW#Mj;T==pcV@A3rYuut?0v(L%x&+CCzagMRSC>A_S3 z2+Zd$r{EAGmNe`*mvZrGE7XI;dgBc#%oh8~YWTr-N z_i;jgs(4aAshS$syFyFaYxdsUrHtmB-XFRf=eIKnGxo$qt`ffP?#PVzS@~2n>71JB zx-+6+xu({?@r-t&IKF3pXXzlQQA^*%K$lmKP>V$@L}c}FAA9M}e{7G1l?{;MPoazO z>wJ(-dUwt@2tJ)X=aQ&y`t*a_Y2B0ow(>Iu(x0xj7yg0?H2MdS$nD`cq|SPh?YqQB}$9FKHCtG;8+tg;^f<}tDbm;kX`A3NxW^uW5mncx~TiRt@n0sZW+Ii#Xmn9P= z2E$y-0%A!;d7?KjyjDI7NX9MZWfC3ob&2JlIY0H$H|Z1f=%3JC@rTKu+a29p)cver z5cahDitp{+w%k*$tGcauaKIVWjxb5z*pPM(xB05lv6ExgV=u=be)@Id`Z&ps*#NOK zyaaJowyrj>S)M=)89~-0JCltk&6_~3!v0Cy9bNOL%*aUg1L*^;1EB-GXhJShU53nW z!gbC>mH414^OG6bSVS&aAR`fi)b)^qXOL4IQGRl+(grdu7&Q8mL%?M&JAS1KOo{!O zyZ{vO+N=O7&eLWCBLCF0ps!%RAapQl&{-qf&uUAqE3LL0PxOuFo(Cg-yQBo|g6cwLE!pI+%lpfx4BjdfD-^J7w!GeB?^VxHWh`ItJ%yy=wL;fi@L-jefEfO{rE-yE zQOIXA490#HlaI+PA1TSPUCqy@cLwX6f9YysXvrYPTpqf7y>$JHPMLPulv19S*YA`S$sy^VJZiAs0<6O>=DKB70w|-fKM)mW+M0DDiUBh<8L| zlxNh5h$#-S_O)_0pSb2+akVhYCIT5xnlDW&vm;@hZa8L^t&o(5RYuR}|Bfa0xWNZS zGm1;*rvEpRa}1DCy!#&ZI_QOw1&KfH`oXj)N@#`UoS^*wDMa_6{ZD~^rbxf;pQAI zqko04-8bHLcIxh{UkLG&cq4oyUI(vRw^-*gAvU2O>Zxzos2y4v`f63>`_5M5cZMEX zQs|6d06l=YO#cQA^b3{<)d;o>9-kfVEr27k@mZM!c)x4EFX7_Zn4rL5N|4_2Mtpgp z?~4`VQQ{6{b7ynAUn*ee&OCWFa0PpVtnl`bK20Oi+SW^cg)RF~DVvkD9fDVA&IDz)kg=G2av{1RnLCp;l4Qk;zO+nM@Gmo!z#^ii|?(+Ox`rPvx zZ7)aa=@R~AuI9Ke?W3hErHyum1#tzd7x5NPQ2srwH{`qt{G|zlNSbDdM&^ysB$fAZ zb1hz~y>%+$8EmL6)afM;A77#4KItTimDdbqw|1)5x5jW0Nt19UHMzXrb0USWbxzX4 zqr(j=jb2enbjQ;ApsAh%Oa&(5GNL@~@|_B}qg|DEK;_{$>q^4P;K6 zDCc{jZR4@`7<=!0q4uzJ!L8c?Q&qnser~rj8g<71su*WhCO8Baj=d%4F?%6vMaqU_ zd+42x_lw{9uF9v#H`ck;C)E8+zngvvYNy((EI#(u%@?be-&C?URaZEn>M-W;ecEPH zbz<5<)a9#_m*bnlXLcgvdaDnp+?ni|<`7qxF(d0+l`!2Jq$Cc2%7 zkBp1DG`Q+)IlwvXWGSCTqIERHAhr$OX=Z*LUXVCbah~>X=?;N z{h5%{^!CD}XyJj7nzI8gL5;y1HN6W04p|OPq_eJnwJZj#GDG55x*8=KU-+Myy4k!G zSz8$qy}jgos=j}Et08I~{JZ~4BQGO#8~JN;#hSj_*wv^TY`A~0!ugf2Q;HPzAl&|^ z<5J)Ufl7rp@3QwthG}DW%4UiW$A=P%`8dg}YB8Ay2VPZF(VZ(Fuv4^Oh&qHq{Qg7# z7RR3+KMI)(Op95=^uy};jHU8x2S4`a$8Ub8Q++8biMsgdTTN4k{RdaO9O+|e+oFsv zL&2zFW*Ajq(~d^V8W`xpwoqH_qqTpJZ>i8H@)MI2x#8yR*|*ry-MF+gmatl>r6==1 z?lc>YeDm$QoD(;9t<_DbhU>w62J$Ju@GlU50|-Z50qildDk>-b9oxifqL?ssvNbex zV_hv3GV#@>OD0^pk}{u|SYHHCEm@dOXW?*HUHJMNu;SKfV6|Z=YQKOk?Vl{6jWbvt z!D>gzGVxa1dofP)Gul}dt*7>`9tz;9CBiWoZR?1ofQ>~AU_VkU zM=)R!|3{m#KmpdjeGmY|`v7eJ%h(+8pE;_{f8YFBN5maq zaRmziyaIo~0=yuI9GNf_(%7C$^17#+8g5w81}MkS-Psku>yp=UW7m}{)|7BY)PB4iL@?JH>h3hh4IWdu^M}f?KWu- z96&-ss8pOa!$wi}EMpJO_6Fqah`3bRy1TL7oO*x|vjU6L zc%0CtQh>)?X5q_TQQ zb&+NcG|N*>&(Pmh4Np~TRUZgJae-G;<}?aVS5ftSub1QnP6+FDS`s)VM-lbZpke9_ z2P4M}8pv@Q6uG8qAZ%!%t(nv&4O009`#YQ*mzgN{*ZifN0LCJlo~7x57U%(TEQ=x2 z1~kVEO{D8?z)TH;F>8+YVHQCT;qfwR=@kV;raQK!F^p8rvQfwyDslrSL{_Leu4QXf zqq-zMv%AB`Jo7n)>>83ti5K!L#=xH_#zUs0$#70-AT=0)V7gHb6+ErlrS6@oX&$go zmPE4_7)N5oM-P*-4O$W@>(8h(6GxXMcC`>{*vW_i=oP%E)p8yd6P&U35Q^}8-YF{t zlH-%B!&r?U|7RFAHW}e$$l#=f4qOhbsg!5Za@Cs3vpfx9&8?v_phIy_t(C +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "constants.h" + +typedef struct { + // +-----x + // | + // | + // y + uint8_t x; + uint8_t y; +} Point; + +typedef enum { + CellEmpty = 1, + CellWall, + CellExplosion, + CellTankUp, + CellTankRight, + CellTankDown, + CellTankLeft, + CellEnemyUp, + CellEnemyRight, + CellEnemyDown, + CellEnemyLeft, + CellProjectileUp, + CellProjectileRight, + CellProjectileDown, + CellProjectileLeft, +} GameCellState; + +typedef enum { + MenuStateSingleMode, + MenuStateCooperativeServerMode, + MenuStateCooperativeClientMode, +} MenuState; + +typedef enum { + GameStateMenu, + GameStateSingle, + GameStateCooperativeServer, + GameStateCooperativeClient, + GameStateGameOver, +} GameState; + +typedef enum { + DirectionUp, + DirectionRight, + DirectionDown, + DirectionLeft, +} Direction; + +typedef enum { + ModeSingle, + ModeCooperative, +} Mode; + +typedef struct { + Point coordinates; + Direction direction; + bool explosion; + bool is_p1; + bool is_p2; +} ProjectileState; + +typedef struct { + Point coordinates; + uint16_t score; + uint8_t lives; + Direction direction; + bool moving; + bool shooting; + bool live; + uint8_t cooldown; + uint8_t respawn_cooldown; +} PlayerState; + +typedef struct { + // char map[FIELD_WIDTH][FIELD_HEIGHT]; + char thisMap[16][11]; + Point team_one_respawn_points[3]; + Point team_two_respawn_points[3]; + Mode mode; + bool server; + GameState state; + MenuState menu_state; + ProjectileState* projectiles[100]; + PlayerState* bots[6]; + uint8_t enemies_left; + uint8_t enemies_live; + uint8_t enemies_respawn_cooldown; + uint8_t received; + uint8_t sent; + PlayerState* p1; + PlayerState* p2; +} TanksState; + +typedef enum { + EventTypeTick, + EventTypeKey, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} TanksEvent; + +typedef enum { + GoesUp, + GoesRight, + GoesDown, + GoesLeft, + Shoots, +} ClientAction; + +//char map[FIELD_HEIGHT][FIELD_WIDTH + 1] = { +char thisMap[11][16 + 1] = { + "* - * -", + " - - = ", + " - - 2", + "1 = - -- ", + "-- = - -- ", + "a-1 = - = 2", + "-- = - -- ", + "1 = - -- ", + " - - 2", + " - - = ", + "* - * -", +}; + +static void tanks_game_write_cell(unsigned char* data, int8_t x, int8_t y, GameCellState cell) { + uint8_t index = y * 16 + x; + data[index] = cell; + // if (x % 2) { + // data[index] = (data[index] & 0b00001111) + (cell << 4); + // } else { + // data[index] = (data[index] & 0b0000) + cell; + // } +} + +// Enum with < 16 items => 4 bits in cell, 2 cells in byte +unsigned char* tanks_game_serialize(const TanksState* const tanks_state) { + static unsigned char result[11 * 16 + 1]; + + for(int8_t x = 0; x < FIELD_WIDTH; x++) { + for(int8_t y = 0; y < FIELD_HEIGHT; y++) { + result[(y * FIELD_WIDTH + x)] = 0; + + GameCellState cell = CellEmpty; + + if(tanks_state->thisMap[x][y] == '-') { + cell = CellWall; + + tanks_game_write_cell(result, x, y, cell); + } + } + } + + for(uint8_t i = 0; i < 6; i++) { + if(tanks_state->bots[i] != NULL) { + GameCellState cell = CellEmpty; + + switch(tanks_state->bots[i]->direction) { + case DirectionUp: + cell = CellEnemyUp; + break; + case DirectionDown: + cell = CellEnemyDown; + break; + case DirectionRight: + cell = CellEnemyRight; + break; + case DirectionLeft: + cell = CellEnemyLeft; + break; + default: + break; + } + + tanks_game_write_cell( + result, + tanks_state->bots[i]->coordinates.x, + tanks_state->bots[i]->coordinates.y, + cell); + } + } + + for(int8_t x = 0; x < 100; x++) { + if(tanks_state->projectiles[x] != NULL) { + GameCellState cell = CellEmpty; + + switch(tanks_state->projectiles[x]->direction) { + case DirectionUp: + cell = CellProjectileUp; + break; + case DirectionDown: + cell = CellProjectileDown; + break; + case DirectionRight: + cell = CellProjectileRight; + break; + case DirectionLeft: + cell = CellProjectileLeft; + break; + default: + break; + } + + tanks_game_write_cell( + result, + tanks_state->projectiles[x]->coordinates.x, + tanks_state->projectiles[x]->coordinates.y, + cell); + } + } + + if(tanks_state->p1 != NULL && tanks_state->p1->live) { + GameCellState cell = CellEmpty; + + switch(tanks_state->p1->direction) { + case DirectionUp: + cell = CellTankUp; + break; + case DirectionDown: + cell = CellTankDown; + break; + case DirectionRight: + cell = CellTankRight; + break; + case DirectionLeft: + cell = CellTankLeft; + break; + default: + break; + } + + tanks_game_write_cell( + result, tanks_state->p1->coordinates.x, tanks_state->p1->coordinates.y, cell); + } + + if(tanks_state->p2 != NULL && tanks_state->p2->live) { + GameCellState cell = CellEmpty; + + switch(tanks_state->p2->direction) { + case DirectionUp: + cell = CellTankUp; + break; + case DirectionDown: + cell = CellTankDown; + break; + case DirectionRight: + cell = CellTankRight; + break; + case DirectionLeft: + cell = CellTankLeft; + break; + default: + break; + } + + tanks_game_write_cell( + result, tanks_state->p2->coordinates.x, tanks_state->p2->coordinates.y, cell); + } + + return result; +} + +static void + tanks_game_render_cell(GameCellState cell, uint8_t x, uint8_t y, Canvas* const canvas) { + const Icon* icon; + + if(cell == CellEmpty) { + return; + } + + switch(cell) { + case CellWall: + icon = &I_tank_wall; + break; + case CellExplosion: + icon = &I_tank_explosion; + break; + case CellTankUp: + icon = &I_tank_up; + break; + case CellTankRight: + icon = &I_tank_right; + break; + case CellTankDown: + icon = &I_tank_down; + break; + case CellTankLeft: + icon = &I_tank_left; + break; + case CellEnemyUp: + icon = &I_enemy_up; + break; + case CellEnemyRight: + icon = &I_enemy_right; + break; + case CellEnemyDown: + icon = &I_enemy_down; + break; + case CellEnemyLeft: + icon = &I_enemy_left; + break; + case CellProjectileUp: + icon = &I_projectile_up; + break; + case CellProjectileRight: + icon = &I_projectile_right; + break; + case CellProjectileDown: + icon = &I_projectile_down; + break; + case CellProjectileLeft: + icon = &I_projectile_left; + break; + default: + return; + break; + } + + canvas_draw_icon(canvas, x * CELL_LENGTH_PIXELS, y * CELL_LENGTH_PIXELS - 1, icon); +} + +static void tanks_game_render_constant_cells(Canvas* const canvas) { + for(int8_t x = 0; x < FIELD_WIDTH; x++) { + for(int8_t y = 0; y < FIELD_HEIGHT; y++) { + char cell = thisMap[y][x]; + + if(cell == '=') { + canvas_draw_icon( + canvas, x * CELL_LENGTH_PIXELS, y * CELL_LENGTH_PIXELS - 1, &I_tank_stone); + continue; + } + + if(cell == '*') { + canvas_draw_icon( + canvas, x * CELL_LENGTH_PIXELS, y * CELL_LENGTH_PIXELS - 1, &I_tank_hedgehog); + continue; + } + + if(cell == 'a') { + canvas_draw_icon( + canvas, x * CELL_LENGTH_PIXELS, y * CELL_LENGTH_PIXELS - 1, &I_tank_base); + continue; + } + } + } +} + +void tanks_game_deserialize_and_write_to_state(unsigned char* data, TanksState* const tanks_state) { + for(uint8_t i = 0; i < 11 * 16; i++) { + uint8_t x = i % 16; + uint8_t y = i / 16; + tanks_state->thisMap[x][y] = data[i]; + } +} + +void tanks_game_deserialize_and_render(unsigned char* data, Canvas* const canvas) { + //for (uint8_t i = 0; i < 11 * 16 / 2; i++) { + for(uint8_t i = 0; i < 11 * 16; i++) { + char cell = data[i]; + uint8_t x = i % 16; // One line (16 cells) = 8 bytes + uint8_t y = i / 16; + + // GameCellState first = cell >> 4; + // GameCellState second = cell & 0b00001111; + + tanks_game_render_cell(cell, x, y, canvas); + // tanks_game_render_cell(second, x + 1, y, canvas); + } + + tanks_game_render_constant_cells(canvas); +} + +static void tanks_game_render_callback(Canvas* const canvas, void* ctx) { + const TanksState* tanks_state = acquire_mutex((ValueMutex*)ctx, 25); + if(tanks_state == NULL) { + return; + } + + // Before the function is called, the state is set with the canvas_reset(canvas) + if(tanks_state->state == GameStateMenu) { + canvas_draw_icon(canvas, 0, 0, &I_TanksSplashScreen_128x64); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned(canvas, 124, 10, AlignRight, AlignBottom, "Single"); + canvas_draw_str_aligned(canvas, 124, 25, AlignRight, AlignBottom, "Co-op S"); + canvas_draw_str_aligned(canvas, 124, 40, AlignRight, AlignBottom, "Co-op C"); + + switch(tanks_state->menu_state) { + case MenuStateSingleMode: + canvas_draw_icon(canvas, 74, 3, &I_tank_right); + break; + case MenuStateCooperativeServerMode: + canvas_draw_icon(canvas, 74, 18, &I_tank_right); + break; + case MenuStateCooperativeClientMode: + canvas_draw_icon(canvas, 74, 33, &I_tank_right); + break; + } + + canvas_draw_frame(canvas, 0, 0, 128, 64); + + release_mutex((ValueMutex*)ctx, tanks_state); + return; + } + + // Field right border + canvas_draw_box(canvas, FIELD_WIDTH * CELL_LENGTH_PIXELS, 0, 2, SCREEN_HEIGHT_TANKS); + + // Cooperative client + if(tanks_state->mode == ModeCooperative && !tanks_state->server) { + for(int8_t x = 0; x < FIELD_WIDTH; x++) { + for(int8_t y = 0; y < FIELD_HEIGHT; y++) { + tanks_game_render_cell(tanks_state->thisMap[x][y], x, y, canvas); + } + } + + tanks_game_render_constant_cells(canvas); + + release_mutex((ValueMutex*)ctx, tanks_state); + return; + } + + // Player + // Point coordinates = tanks_state->p1->coordinates; + // const Icon *icon; + // switch (tanks_state->p1->direction) { + // case DirectionUp: + // icon = &I_tank_up; + // break; + // case DirectionDown: + // icon = &I_tank_down; + // break; + // case DirectionRight: + // icon = &I_tank_right; + // break; + // case DirectionLeft: + // icon = &I_tank_left; + // break; + // default: + // icon = &I_tank_explosion; + // } + + // if (tanks_state->p1->live) { + // canvas_draw_icon(canvas, coordinates.x * CELL_LENGTH_PIXELS, coordinates.y * CELL_LENGTH_PIXELS - 1, icon); + // } + // + // for(int8_t x = 0; x < FIELD_WIDTH; x++) { + // for(int8_t y = 0; y < FIELD_HEIGHT; y++) { + // switch (tanks_state->thisMap[x][y]) { + // case '-': + // canvas_draw_icon(canvas, x * CELL_LENGTH_PIXELS, y * CELL_LENGTH_PIXELS - 1, &I_tank_wall); + // break; + // + // case '=': + // canvas_draw_icon(canvas, x * CELL_LENGTH_PIXELS, y * CELL_LENGTH_PIXELS - 1, &I_tank_stone); + // break; + // + // case '*': + // canvas_draw_icon(canvas, x * CELL_LENGTH_PIXELS, y * CELL_LENGTH_PIXELS - 1, &I_tank_hedgehog); + // break; + // + // case 'a': + // canvas_draw_icon(canvas, x * CELL_LENGTH_PIXELS, y * CELL_LENGTH_PIXELS - 1, &I_tank_base); + // break; + // } + // } + // } + + // for ( + // uint8_t i = 0; + // i < 6; + // i++ + // ) { + // if (tanks_state->bots[i] != NULL) { + // const Icon *icon; + // + // switch(tanks_state->bots[i]->direction) { + // case DirectionUp: + // icon = &I_enemy_up; + // break; + // case DirectionDown: + // icon = &I_enemy_down; + // break; + // case DirectionRight: + // icon = &I_enemy_right; + // break; + // case DirectionLeft: + // icon = &I_enemy_left; + // break; + // default: + // icon = &I_tank_explosion; + // } + // + // canvas_draw_icon( + // canvas, + // tanks_state->bots[i]->coordinates.x * CELL_LENGTH_PIXELS, + // tanks_state->bots[i]->coordinates.y * CELL_LENGTH_PIXELS - 1, + // icon); + // } + // } + + // for(int8_t x = 0; x < 100; x++) { + // if (tanks_state->projectiles[x] != NULL) { + // ProjectileState *projectile = tanks_state->projectiles[x]; + // + // if (projectile->explosion) { + // canvas_draw_icon( + // canvas, + // projectile->coordinates.x * CELL_LENGTH_PIXELS, + // projectile->coordinates.y * CELL_LENGTH_PIXELS - 1, + // &I_tank_explosion); + // continue; + // } + // + // const Icon *icon; + // + // switch(projectile->direction) { + // case DirectionUp: + // icon = &I_projectile_up; + // break; + // case DirectionDown: + // icon = &I_projectile_down; + // break; + // case DirectionRight: + // icon = &I_projectile_right; + // break; + // case DirectionLeft: + // icon = &I_projectile_left; + // break; + // default: + // icon = &I_tank_explosion; + // } + // + // canvas_draw_icon( + // canvas, + // projectile->coordinates.x * CELL_LENGTH_PIXELS, + // projectile->coordinates.y * CELL_LENGTH_PIXELS - 1, + // icon); + // } + // } + + // Info + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontSecondary); + char buffer1[13]; + snprintf(buffer1, sizeof(buffer1), "live: %u", tanks_state->enemies_live); + canvas_draw_str_aligned(canvas, 127, 8, AlignRight, AlignBottom, buffer1); + + snprintf(buffer1, sizeof(buffer1), "left: %u", tanks_state->enemies_left); + canvas_draw_str_aligned(canvas, 127, 18, AlignRight, AlignBottom, buffer1); + + snprintf(buffer1, sizeof(buffer1), "p1 l: %u", tanks_state->p1->lives); + canvas_draw_str_aligned(canvas, 127, 28, AlignRight, AlignBottom, buffer1); + + snprintf(buffer1, sizeof(buffer1), "p1 s: %u", tanks_state->p1->score); + canvas_draw_str_aligned(canvas, 127, 38, AlignRight, AlignBottom, buffer1); + + if(tanks_state->state == GameStateCooperativeServer && tanks_state->p2) { + snprintf(buffer1, sizeof(buffer1), "rec: %u", tanks_state->received); + canvas_draw_str_aligned(canvas, 127, 48, AlignRight, AlignBottom, buffer1); + + snprintf(buffer1, sizeof(buffer1), "snt: %u", tanks_state->sent); + canvas_draw_str_aligned(canvas, 127, 58, AlignRight, AlignBottom, buffer1); + // snprintf(buffer1, sizeof(buffer1), "p2 l: %u", tanks_state->p2->lives); + // canvas_draw_str_aligned(canvas, 127, 48, AlignRight, AlignBottom, buffer1); + // + // snprintf(buffer1, sizeof(buffer1), "p2 s: %u", tanks_state->p2->score); + // canvas_draw_str_aligned(canvas, 127, 58, AlignRight, AlignBottom, buffer1); + } + + if(tanks_state->state == GameStateCooperativeClient) { + snprintf(buffer1, sizeof(buffer1), "rec: %u", tanks_state->received); + canvas_draw_str_aligned(canvas, 127, 48, AlignRight, AlignBottom, buffer1); + } + + // Game Over banner + if(tanks_state->state == GameStateGameOver) { + canvas_set_color(canvas, ColorWhite); + canvas_draw_box(canvas, 34, 20, 62, 24); + + canvas_set_color(canvas, ColorBlack); + canvas_draw_frame(canvas, 34, 20, 62, 24); + canvas_set_font(canvas, FontPrimary); + + if(tanks_state->enemies_left == 0 && tanks_state->enemies_live == 0) { + canvas_draw_str(canvas, 37, 31, "You win!"); + } else { + canvas_draw_str(canvas, 37, 31, "Game Over"); + } + + canvas_set_font(canvas, FontSecondary); + char buffer[13]; + snprintf(buffer, sizeof(buffer), "Score: %u", tanks_state->p1->score); + canvas_draw_str_aligned(canvas, 64, 41, AlignCenter, AlignBottom, buffer); + } + + // TEST start + unsigned char* data = tanks_game_serialize(tanks_state); + tanks_game_deserialize_and_render(data, canvas); + // TEST enf + + release_mutex((ValueMutex*)ctx, tanks_state); +} + +static void tanks_game_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { + furi_assert(event_queue); + + TanksEvent event = {.type = EventTypeKey, .input = *input_event}; + furi_message_queue_put(event_queue, &event, FuriWaitForever); +} + +static void tanks_game_update_timer_callback(FuriMessageQueue* event_queue) { + furi_assert(event_queue); + + TanksEvent event = {.type = EventTypeTick}; + furi_message_queue_put(event_queue, &event, 0); +} + +static bool tanks_get_cell_is_free(TanksState* const tanks_state, Point point) { + // Tiles + if(tanks_state->thisMap[point.x][point.y] != ' ') { + return false; + } + + // Projectiles + for(int8_t x = 0; x < 100; x++) { + if(tanks_state->projectiles[x] != NULL) { + if(tanks_state->projectiles[x]->coordinates.x == point.x && + tanks_state->projectiles[x]->coordinates.y == point.y) { + return false; + } + } + } + + // Player 1 + if(tanks_state->p1 != NULL) { + if(tanks_state->p1->coordinates.x == point.x && + tanks_state->p1->coordinates.y == point.y) { + return false; + } + } + + // Player 2 + if(tanks_state->p2 != NULL) { + if(tanks_state->p2->coordinates.x == point.x && + tanks_state->p2->coordinates.y == point.y) { + return false; + } + } + + // Bots + for(int8_t x = 0; x < 6; x++) { + if(tanks_state->bots[x] != NULL) { + if(tanks_state->bots[x]->coordinates.x == point.x && + tanks_state->bots[x]->coordinates.y == point.y) { + return false; + } + } + } + + return true; +} + +static uint8_t tanks_get_random_free_respawn_point_index( + TanksState* const tanks_state, + Point respawn_points[3]) { + uint8_t first = rand() % 3; + int8_t add = rand() % 2 ? +1 : -1; + int8_t second = first + add; + uint8_t third; + + if(second == 4) { + second = 0; + } else if(second == -1) { + second = 3; + } + + for(uint8_t i = 0; i < 3; i++) { + if(i != first && i != second) { + third = i; + } + } + + if(tanks_get_cell_is_free(tanks_state, respawn_points[first])) { + return first; + } + + if(tanks_get_cell_is_free(tanks_state, respawn_points[second])) { + return second; + } + + if(tanks_get_cell_is_free(tanks_state, respawn_points[third])) { + return third; + } + + return -1; +} + +static void tanks_game_init_game(TanksState* const tanks_state, GameState type) { + srand(DWT->CYCCNT); + + tanks_state->state = type; + + for(int8_t x = 0; x < 100; x++) { + if(tanks_state->projectiles[x] != NULL) { + free(tanks_state->projectiles[x]); + tanks_state->projectiles[x] = NULL; + } + } + + int8_t team_one_respawn_points_counter = 0; + int8_t team_two_respawn_points_counter = 0; + + for(int8_t x = 0; x < FIELD_WIDTH; x++) { + for(int8_t y = 0; y < FIELD_HEIGHT; y++) { + tanks_state->thisMap[x][y] = ' '; + + if(thisMap[y][x] == '1') { + Point respawn = {x, y}; + tanks_state->team_one_respawn_points[team_one_respawn_points_counter++] = respawn; + } + + if(thisMap[y][x] == '2') { + Point respawn = {x, y}; + tanks_state->team_two_respawn_points[team_two_respawn_points_counter++] = respawn; + } + + if(thisMap[y][x] == '-') { + tanks_state->thisMap[x][y] = '-'; + } + + if(thisMap[y][x] == '=') { + tanks_state->thisMap[x][y] = '='; + } + + if(thisMap[y][x] == '*') { + tanks_state->thisMap[x][y] = '*'; + } + + if(thisMap[y][x] == 'a') { + tanks_state->thisMap[x][y] = 'a'; + } + } + } + + uint8_t index1 = tanks_get_random_free_respawn_point_index( + tanks_state, tanks_state->team_one_respawn_points); + Point c = { + tanks_state->team_one_respawn_points[index1].x, + tanks_state->team_one_respawn_points[index1].y}; + + PlayerState p1 = { + c, + 0, + 4, + DirectionRight, + 0, + 0, + 1, + SHOT_COOLDOWN, + PLAYER_RESPAWN_COOLDOWN, + }; + + PlayerState* p1_state = malloc(sizeof(PlayerState)); + *p1_state = p1; + + tanks_state->p1 = p1_state; + + if(type == GameStateCooperativeServer) { + int8_t index2 = tanks_get_random_free_respawn_point_index( + tanks_state, tanks_state->team_one_respawn_points); + Point c = { + tanks_state->team_one_respawn_points[index2].x, + tanks_state->team_one_respawn_points[index2].y}; + + PlayerState p2 = { + c, + 0, + 4, + DirectionRight, + 0, + 0, + 1, + SHOT_COOLDOWN, + PLAYER_RESPAWN_COOLDOWN, + }; + + PlayerState* p2_state = malloc(sizeof(PlayerState)); + *p2_state = p2; + + tanks_state->p2 = p2_state; + } + + tanks_state->enemies_left = 5; + tanks_state->enemies_live = 0; + tanks_state->enemies_respawn_cooldown = RESPAWN_COOLDOWN; + tanks_state->received = 0; + tanks_state->sent = 0; + + if(type == GameStateCooperativeClient) { + for(int8_t x = 0; x < FIELD_WIDTH; x++) { + for(int8_t y = 0; y < FIELD_HEIGHT; y++) { + tanks_state->thisMap[x][y] = CellEmpty; + } + } + } +} + +static bool + tanks_game_collision(Point const next_step, bool shoot, TanksState const* const tanks_state) { + if((int8_t)next_step.x < 0 || (int8_t)next_step.y < 0) { + return true; + } + + if(next_step.x >= FIELD_WIDTH || next_step.y >= FIELD_HEIGHT) { + return true; + } + + char tile = tanks_state->thisMap[next_step.x][next_step.y]; + + if(tile == '*' && !shoot) { + return true; + } + + if(tile == '-' || tile == '=' || tile == 'a') { + return true; + } + + for(uint8_t i = 0; i < 6; i++) { + if(tanks_state->bots[i] != NULL) { + if(tanks_state->bots[i]->coordinates.x == next_step.x && + tanks_state->bots[i]->coordinates.y == next_step.y) { + return true; + } + } + } + + if(tanks_state->p1 != NULL && tanks_state->p1->live && + tanks_state->p1->coordinates.x == next_step.x && + tanks_state->p1->coordinates.y == next_step.y) { + return true; + } + + if(tanks_state->p2 != NULL && tanks_state->p2->live && + tanks_state->p2->coordinates.x == next_step.x && + tanks_state->p2->coordinates.y == next_step.y) { + return true; + } + + return false; +} + +static Point tanks_game_get_next_step(Point coordinates, Direction direction) { + Point next_step = {coordinates.x, coordinates.y}; + + switch(direction) { + // +-----x + // | + // | + // y + case DirectionUp: + next_step.y--; + break; + case DirectionRight: + next_step.x++; + break; + case DirectionDown: + next_step.y++; + break; + case DirectionLeft: + next_step.x--; + break; + default: + break; + } + return next_step; +} + +static uint8_t tanks_game_get_free_projectile_index(TanksState* const tanks_state) { + uint8_t freeProjectileIndex; + for(freeProjectileIndex = 0; freeProjectileIndex < 100; freeProjectileIndex++) { + if(tanks_state->projectiles[freeProjectileIndex] == NULL) { + return freeProjectileIndex; + } + } + + return 0; +} + +static void tanks_game_shoot( + TanksState* const tanks_state, + PlayerState* tank_state, + bool is_p1, + bool is_p2) { + tank_state->cooldown = SHOT_COOLDOWN; + + uint8_t freeProjectileIndex = tanks_game_get_free_projectile_index(tanks_state); + + ProjectileState* projectile_state = malloc(sizeof(ProjectileState)); + Point next_step = tanks_game_get_next_step(tank_state->coordinates, tank_state->direction); + + projectile_state->direction = tank_state->direction; + projectile_state->coordinates = next_step; + projectile_state->is_p1 = is_p1; + projectile_state->is_p2 = is_p2; + + bool crush = tanks_game_collision(projectile_state->coordinates, true, tanks_state); + projectile_state->explosion = crush; + + tanks_state->projectiles[freeProjectileIndex] = projectile_state; +} + +static void tanks_game_process_game_step(TanksState* const tanks_state) { + if(tanks_state->state == GameStateMenu) { + return; + } + + if(tanks_state->enemies_left == 0 && tanks_state->enemies_live == 0) { + tanks_state->state = GameStateGameOver; + } + + if(!tanks_state->p1->live && tanks_state->p1->lives == 0) { + tanks_state->state = GameStateGameOver; + } + + if(tanks_state->state == GameStateGameOver) { + return; + } + + if(tanks_state->p1 != NULL) { + if(!tanks_state->p1->live && tanks_state->p1->respawn_cooldown > 0) { + tanks_state->p1->respawn_cooldown--; + } + } + + // Player 1 spawn + if(tanks_state->p1 && !tanks_state->p1->live && tanks_state->p1->lives > 0) { + int8_t index = tanks_get_random_free_respawn_point_index( + tanks_state, tanks_state->team_one_respawn_points); + + if(index != -1) { + Point point = tanks_state->team_one_respawn_points[index]; + Point c = {point.x, point.y}; + tanks_state->p1->coordinates = c; + tanks_state->p1->live = true; + tanks_state->p1->direction = DirectionRight; + tanks_state->p1->cooldown = SHOT_COOLDOWN; + tanks_state->p1->respawn_cooldown = SHOT_COOLDOWN; + } + } + + // Player 2 spawn + if(tanks_state->state == GameStateCooperativeServer && tanks_state->p2 && + !tanks_state->p2->live && tanks_state->p2->lives > 0) { + int8_t index = tanks_get_random_free_respawn_point_index( + tanks_state, tanks_state->team_one_respawn_points); + + if(index != -1) { + Point point = tanks_state->team_one_respawn_points[index]; + Point c = {point.x, point.y}; + tanks_state->p2->coordinates = c; + tanks_state->p2->live = true; + tanks_state->p2->direction = DirectionRight; + tanks_state->p2->cooldown = SHOT_COOLDOWN; + tanks_state->p2->respawn_cooldown = SHOT_COOLDOWN; + } + } + + // Bot turn + for(uint8_t i = 0; i < 6; i++) { + if(tanks_state->bots[i] != NULL) { + PlayerState* bot = tanks_state->bots[i]; + if(bot->cooldown) { + bot->cooldown--; + } + + // Rotate + if(rand() % 3 == 0) { + bot->direction = (rand() % 4); + } + + // Move + if(rand() % 2 == 0) { + Point next_step = tanks_game_get_next_step(bot->coordinates, bot->direction); + bool crush = tanks_game_collision(next_step, false, tanks_state); + + if(!crush) { + bot->coordinates = next_step; + } + } + + // Shoot + if(bot->cooldown == 0 && rand() % 3 != 0) { + tanks_game_shoot(tanks_state, bot, false, false); + } + } + } + + // Bot spawn + if(tanks_state->enemies_respawn_cooldown) { + tanks_state->enemies_respawn_cooldown--; + } + + if(tanks_state->enemies_left > 0 && tanks_state->enemies_live <= 4 && + tanks_state->enemies_respawn_cooldown == 0) { + int8_t index = tanks_get_random_free_respawn_point_index( + tanks_state, tanks_state->team_two_respawn_points); + + if(index != -1) { + tanks_state->enemies_left--; + tanks_state->enemies_live++; + tanks_state->enemies_respawn_cooldown = RESPAWN_COOLDOWN; + Point point = tanks_state->team_two_respawn_points[index]; + + Point c = {point.x, point.y}; + + PlayerState bot = { + c, + 0, + 0, + DirectionLeft, + 0, + 0, + 1, + SHOT_COOLDOWN, + PLAYER_RESPAWN_COOLDOWN, + }; + + uint8_t freeEnemyIndex; + for(freeEnemyIndex = 0; freeEnemyIndex < 6; freeEnemyIndex++) { + if(tanks_state->bots[freeEnemyIndex] == NULL) { + break; + } + } + + PlayerState* bot_state = malloc(sizeof(PlayerState)); + *bot_state = bot; + + tanks_state->bots[freeEnemyIndex] = bot_state; + } + } + + if(tanks_state->p1 != NULL && tanks_state->p1->live && tanks_state->p1->moving) { + Point next_step = + tanks_game_get_next_step(tanks_state->p1->coordinates, tanks_state->p1->direction); + bool crush = tanks_game_collision(next_step, false, tanks_state); + + if(!crush) { + tanks_state->p1->coordinates = next_step; + } + } + + // Player 2 spawn + if(tanks_state->state == GameStateCooperativeServer && tanks_state->p2 && + tanks_state->p2->live && tanks_state->p2->moving) { + Point next_step = + tanks_game_get_next_step(tanks_state->p2->coordinates, tanks_state->p2->direction); + bool crush = tanks_game_collision(next_step, false, tanks_state); + + if(!crush) { + tanks_state->p2->coordinates = next_step; + } + } + + for(int8_t x = 0; x < 100; x++) { + if(tanks_state->projectiles[x] != NULL) { + ProjectileState* projectile = tanks_state->projectiles[x]; + Point c = projectile->coordinates; + + if(projectile->explosion) { + // Break a wall + if(tanks_state->thisMap[c.x][c.y] == '-') { + tanks_state->thisMap[c.x][c.y] = ' '; + } + + // Kill a bot + for(uint8_t i = 0; i < 6; i++) { + if(tanks_state->bots[i] != NULL) { + if(tanks_state->bots[i]->coordinates.x == c.x && + tanks_state->bots[i]->coordinates.y == c.y) { + if(projectile->is_p1) { + tanks_state->p1->score++; + } + + if(projectile->is_p2) { + tanks_state->p2->score++; + } + + // No friendly fire + if(projectile->is_p1 || projectile->is_p2) { + tanks_state->enemies_live--; + free(tanks_state->bots[i]); + tanks_state->bots[i] = NULL; + } + } + } + } + + // Destroy the flag + if(tanks_state->thisMap[c.x][c.y] == 'a') { + tanks_state->state = GameStateGameOver; + return; + } + + // Kill a player 1 + if(tanks_state->p1 != NULL) { + if(tanks_state->p1->live && tanks_state->p1->coordinates.x == c.x && + tanks_state->p1->coordinates.y == c.y) { + tanks_state->p1->live = false; + tanks_state->p1->lives--; + tanks_state->p1->respawn_cooldown = PLAYER_RESPAWN_COOLDOWN; + } + } + + // Kill a player 2 + if(tanks_state->p2 != NULL) { + if(tanks_state->p2->live && tanks_state->p2->coordinates.x == c.x && + tanks_state->p2->coordinates.y == c.y) { + tanks_state->p2->live = false; + tanks_state->p2->lives--; + tanks_state->p2->respawn_cooldown = PLAYER_RESPAWN_COOLDOWN; + } + } + + // Delete projectile + free(tanks_state->projectiles[x]); + tanks_state->projectiles[x] = NULL; + continue; + } + + Point next_step = + tanks_game_get_next_step(projectile->coordinates, projectile->direction); + bool crush = tanks_game_collision(next_step, true, tanks_state); + projectile->coordinates = next_step; + + if(crush) { + projectile->explosion = true; + } + } + } + + if(tanks_state->p1->cooldown > 0) { + tanks_state->p1->cooldown--; + } + + if(tanks_state->p2 != NULL && tanks_state->p2->cooldown > 0) { + tanks_state->p2->cooldown--; + } + + if(tanks_state->p1 != NULL && tanks_state->p1->live && tanks_state->p1->shooting && + tanks_state->p1->cooldown == 0) { + tanks_game_shoot(tanks_state, tanks_state->p1, true, false); + } + + tanks_state->p1->moving = false; + tanks_state->p1->shooting = false; + + if(tanks_state->p2 != NULL) { + tanks_state->p2->moving = false; + tanks_state->p2->shooting = false; + } +} + +int32_t tanks_game_app(void* p) { + UNUSED(p); + srand(DWT->CYCCNT); + + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(TanksEvent)); + + TanksState* tanks_state = malloc(sizeof(TanksState)); + + tanks_state->state = GameStateMenu; + tanks_state->menu_state = MenuStateSingleMode; + + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, tanks_state, sizeof(TanksState))) { + FURI_LOG_E("Tanks", "cannot create mutex\r\n"); + furi_message_queue_free(event_queue); + free(tanks_state); + return 255; + } + + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, tanks_game_render_callback, &state_mutex); + view_port_input_callback_set(view_port, tanks_game_input_callback, event_queue); + + FuriTimer* timer = + furi_timer_alloc(tanks_game_update_timer_callback, FuriTimerTypePeriodic, event_queue); + furi_timer_start(timer, furi_kernel_get_tick_frequency() / 4); + + // Open GUI and register view_port + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + TanksEvent event; + + // Initialize network thing. + uint32_t frequency = 433920000; + size_t message_max_len = 180; + uint8_t incomingMessage[180] = {0}; + SubGhzTxRxWorker* subghz_txrx = subghz_tx_rx_worker_alloc(); + subghz_tx_rx_worker_start(subghz_txrx, frequency); + furi_hal_power_suppress_charge_enter(); + + for(bool processing = true; processing;) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); + + TanksState* tanks_state = (TanksState*)acquire_mutex_block(&state_mutex); + + if(event_status == FuriStatusOk) { + // press events + if(event.type == EventTypeKey) { + if(event.input.type == InputTypePress) { + switch(event.input.key) { + case InputKeyUp: + if(tanks_state->state == GameStateMenu) { + if(tanks_state->menu_state == MenuStateCooperativeServerMode) { + tanks_state->menu_state = MenuStateSingleMode; + } else if(tanks_state->menu_state == MenuStateCooperativeClientMode) { + tanks_state->menu_state = MenuStateCooperativeServerMode; + } + } else if(tanks_state->state == GameStateCooperativeClient) { + FuriString* goesUp = NULL; + char arr[2]; + arr[0] = GoesUp; + arr[1] = 0; + furi_string_set(goesUp, (char*)&arr); + + subghz_tx_rx_worker_write( + subghz_txrx, + (uint8_t*)furi_string_get_cstr(goesUp), + strlen(furi_string_get_cstr(goesUp))); + + } else { + tanks_state->p1->moving = true; + tanks_state->p1->direction = DirectionUp; + } + break; + case InputKeyDown: + if(tanks_state->state == GameStateMenu) { + if(tanks_state->menu_state == MenuStateSingleMode) { + tanks_state->menu_state = MenuStateCooperativeServerMode; + } else if(tanks_state->menu_state == MenuStateCooperativeServerMode) { + tanks_state->menu_state = MenuStateCooperativeClientMode; + } + } else if(tanks_state->state == GameStateCooperativeClient) { + FuriString* goesDown = NULL; + char arr[2]; + arr[0] = GoesDown; + arr[1] = 0; + furi_string_set(goesDown, (char*)&arr); + + subghz_tx_rx_worker_write( + subghz_txrx, + (uint8_t*)furi_string_get_cstr(goesDown), + strlen(furi_string_get_cstr(goesDown))); + } else { + tanks_state->p1->moving = true; + tanks_state->p1->direction = DirectionDown; + } + break; + case InputKeyRight: + if(tanks_state->state == GameStateCooperativeClient) { + FuriString* goesRight = NULL; + char arr[2]; + arr[0] = GoesRight; + arr[1] = 0; + furi_string_set(goesRight, (char*)&arr); + + subghz_tx_rx_worker_write( + subghz_txrx, + (uint8_t*)furi_string_get_cstr(goesRight), + strlen(furi_string_get_cstr(goesRight))); + } else { + tanks_state->p1->moving = true; + tanks_state->p1->direction = DirectionRight; + } + break; + case InputKeyLeft: + if(tanks_state->state == GameStateCooperativeClient) { + FuriString* goesLeft = NULL; + char arr[2]; + arr[0] = GoesLeft; + arr[1] = 0; + furi_string_set(goesLeft, (char*)&arr); + + subghz_tx_rx_worker_write( + subghz_txrx, + (uint8_t*)furi_string_get_cstr(goesLeft), + strlen(furi_string_get_cstr(goesLeft))); + } else { + tanks_state->p1->moving = true; + tanks_state->p1->direction = DirectionLeft; + } + break; + case InputKeyOk: + if(tanks_state->state == GameStateMenu) { + if(tanks_state->menu_state == MenuStateSingleMode) { + tanks_state->server = true; + tanks_game_init_game(tanks_state, GameStateSingle); + break; + } else if(tanks_state->menu_state == MenuStateCooperativeServerMode) { + tanks_state->server = true; + tanks_game_init_game(tanks_state, GameStateCooperativeServer); + break; + } else if(tanks_state->menu_state == MenuStateCooperativeClientMode) { + tanks_state->server = false; + tanks_game_init_game(tanks_state, GameStateCooperativeClient); + break; + } + } else if(tanks_state->state == GameStateGameOver) { + tanks_game_init_game(tanks_state, tanks_state->state); + } else if(tanks_state->state == GameStateCooperativeClient) { + FuriString* shoots = NULL; + char arr[2]; + arr[0] = Shoots; + arr[1] = 0; + furi_string_set(shoots, (char*)&arr); + + subghz_tx_rx_worker_write( + subghz_txrx, + (uint8_t*)furi_string_get_cstr(shoots), + strlen(furi_string_get_cstr(shoots))); + } else { + tanks_state->p1->shooting = true; + } + break; + case InputKeyBack: + processing = false; + break; + default: + break; + } + } + } else if(event.type == EventTypeTick) { + if(tanks_state->state == GameStateCooperativeServer) { + if(subghz_tx_rx_worker_available(subghz_txrx)) { + memset(incomingMessage, 0x00, message_max_len); + subghz_tx_rx_worker_read(subghz_txrx, incomingMessage, message_max_len); + + if(incomingMessage != NULL) { + tanks_state->received++; + + switch(incomingMessage[0]) { + case GoesUp: + tanks_state->p2->moving = true; + tanks_state->p2->direction = DirectionUp; + break; + case GoesRight: + tanks_state->p2->moving = true; + tanks_state->p2->direction = DirectionRight; + break; + case GoesDown: + tanks_state->p2->moving = true; + tanks_state->p2->direction = DirectionDown; + break; + case GoesLeft: + tanks_state->p2->moving = true; + tanks_state->p2->direction = DirectionLeft; + break; + case Shoots: + tanks_state->p2->shooting = true; + break; + default: + break; + } + } + } + + tanks_game_process_game_step(tanks_state); + + FuriString* serializedData = NULL; + unsigned char* data = tanks_game_serialize(tanks_state); + char arr[11 * 16 + 1]; + + for(uint8_t i = 0; i < 11 * 16; i++) { + arr[i] = data[i]; + } + + arr[11 * 16] = 0; + + furi_string_set(serializedData, (char*)&arr); + + subghz_tx_rx_worker_write( + subghz_txrx, + (uint8_t*)furi_string_get_cstr(serializedData), + strlen(furi_string_get_cstr(serializedData))); + + tanks_state->sent++; + } else if(tanks_state->state == GameStateSingle) { + tanks_game_process_game_step(tanks_state); + } else if(tanks_state->state == GameStateCooperativeClient) { + if(subghz_tx_rx_worker_available(subghz_txrx)) { + memset(incomingMessage, 0x00, message_max_len); + subghz_tx_rx_worker_read(subghz_txrx, incomingMessage, message_max_len); + + tanks_state->received++; + + tanks_game_deserialize_and_write_to_state( + (unsigned char*)incomingMessage, tanks_state); + } + } + } + } else { + // event timeout + } + + view_port_update(view_port); + release_mutex(&state_mutex, tanks_state); + furi_delay_ms(1); + } + + furi_delay_ms(10); + furi_hal_power_suppress_charge_exit(); + + if(subghz_tx_rx_worker_is_running(subghz_txrx)) { + subghz_tx_rx_worker_stop(subghz_txrx); + subghz_tx_rx_worker_free(subghz_txrx); + } + + furi_timer_free(timer); + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + furi_record_close(RECORD_GUI); + view_port_free(view_port); + furi_message_queue_free(event_queue); + delete_mutex(&state_mutex); + + if(tanks_state->p1 != NULL) { + free(tanks_state->p1); + } + + if(tanks_state->p2 != NULL) { + free(tanks_state->p2); + } + + free(tanks_state); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/timelapse/.gitattributes b/Applications/Official/DEV_FW/source/xMasterX/timelapse/.gitattributes new file mode 100644 index 000000000..cd63b2f7b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/timelapse/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +#* text=auto diff --git a/Applications/Official/DEV_FW/source/xMasterX/timelapse/.gitignore b/Applications/Official/DEV_FW/source/xMasterX/timelapse/.gitignore new file mode 100644 index 000000000..722d5e71d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/timelapse/.gitignore @@ -0,0 +1 @@ +.vscode diff --git a/Applications/Official/DEV_FW/source/xMasterX/timelapse/README.md b/Applications/Official/DEV_FW/source/xMasterX/timelapse/README.md new file mode 100644 index 000000000..b10955ea1 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/timelapse/README.md @@ -0,0 +1,78 @@ + +# zeitraffer + +[![Build FAP](https://github.com/theageoflove/flipperzero-zeitraffer/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/theageoflove/flipperzero-zeitraffer/actions/workflows/build.yml) + +english version [below](#eng) + + +Blog: [theageoflove.ru](https://theageoflove.ru) + +TG: [t.me/scuko_bled](https://t.me/scuko_bled) + + +![zeitraffer for flipper zero](https://theageoflove.ru/uploads/2022/11/photo_2022-11-10_15-54-25.jpg) +Видео работы: https://youtu.be/VPSpRLJXYAc + +Готовый фап под поÑледнюю релизную прошивку [можно Ñкачать здеÑÑŒ](https://nightly.link/theageoflove/flipperzero-zeitraffer/workflows/build/main/zeitraffer.fap.zip). + +Я ненаÑтоÑщий Ñварщик, не обеÑÑудьте. Делал Ð´Ð»Ñ Ñвоей Sony DSLR A100, подходит Ð´Ð»Ñ Ð»ÑŽÐ±Ñ‹Ñ… камер, поддерживающих проводной пульт Ñ Ñ‚Ñ€ÐµÐ¼Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð°Ð¼Ð¸. + +ОÑновано на хелловорлде https://github.com/zmactep/flipperzero-hello-world + +### Управление: + + - **вверх-вниз** - времÑ. + - **влево-вправо** - количеÑтво кадров + + 0 кадров - беÑконечный режим, -1 кадров - BULB + - **зажатие Ñтрелок** - ±10 кадров/Ñекунд + - **ОК** - пуÑк/пауза + - Длинное нажатие **ОК** - включить/выключить подÑветку + - **назад** - ÑÐ±Ñ€Ð¾Ñ + - длинное нажатие **назад** - выход + +При работающем таймере блокируютÑÑ Ð²Ñе кнопки кроме ОК. + +При запуÑке даётÑÑ Ñ‚Ñ€Ð¸ Ñекунды на отÑкочить. + +## Чо надо + - две оптопары типа EL817C + - куÑок гребёнки на три пина + - немного провода + - термоуÑадка + - разъём пульта от камеры. Где взÑÑ‚ÑŒ или из чего Ñделать - думайте + +## Как Ñобрать +Берём оптопары, ÑоединÑем по Ñхеме. +![](https://theageoflove.ru/uploads/2022/11/camera_cable.jpg) +Где какой пин у камеры, можно узнать например тут: https://www.doc-diy.net/photo/remote_pinout/ + +# English +Simple timelapse app for Flipper Zero. + +[Get latest release](https://nightly.link/theageoflove/flipperzero-zeitraffer/workflows/build/main/zeitraffer.fap.zip) + +based on https://github.com/zmactep/flipperzero-hello-world + +### Control: + - Up and down - time. + - Left and right - number of frames + - Long press arrows - ±10 frames/seconds + - OK - start/pause + - Long press OK - turn on/off the backlight + - Back - reset + - Long press back - exit + +When the timer is running, all buttons are blocked except OK. + +## What you need: + - two EL817C optocouplers + - pin header connector 1x3 2,54mm male + - some wire + - heat shrink + - camera remote connector +## How to assemble +Take optocouplers, connect according to the scheme. +![](https://theageoflove.ru/uploads/2022/11/camera_cable_en.jpg) +Camera pinout can be found here: https://www.doc-diy.net/photo/remote_pinout/ diff --git a/Applications/Official/DEV_FW/source/xMasterX/timelapse/application.fam b/Applications/Official/DEV_FW/source/xMasterX/timelapse/application.fam new file mode 100644 index 000000000..12ed589ff --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/timelapse/application.fam @@ -0,0 +1,21 @@ +App( + appid="GPIO_Timelapse", + name="[GPIO] Timelapse", + apptype=FlipperAppType.EXTERNAL, + entry_point="zeitraffer_app", + cdefines=["APP_ZEITRAFFER"], + requires=[ + "gui", + "input", + "notification", + "gpio" + ], + stack_size=2 * 1024, + order=90, + fap_icon_assets="icons", + fap_icon="zeitraffer.png", + fap_category="GPIO_Extra", + fap_description="Simple intervalometer app", + fap_author="Aurelius Rosenbaum", + fap_weburl="https://github.com/theageoflove/flipperzero-zeitraffer", +) \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/timelapse/gpio_item.c b/Applications/Official/DEV_FW/source/xMasterX/timelapse/gpio_item.c new file mode 100644 index 000000000..2d0f5f676 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/timelapse/gpio_item.c @@ -0,0 +1,51 @@ +#include "gpio_item.h" + +#include + +typedef struct { + const char* name; + const GpioPin* pin; +} GpioItem; + +static const GpioItem gpio_item[GPIO_ITEM_COUNT] = { + {"1.2: PA7", &gpio_ext_pa7}, + {"1.3: PA6", &gpio_ext_pa6}, + {"1.4: PA4", &gpio_ext_pa4}, + {"1.5: PB3", &gpio_ext_pb3}, + {"1.6: PB2", &gpio_ext_pb2}, + {"1.7: PC3", &gpio_ext_pc3}, + {"2.7: PC1", &gpio_ext_pc1}, + {"2.8: PC0", &gpio_ext_pc0}, +}; + +void gpio_item_configure_pin(uint8_t index, GpioMode mode) { + furi_assert(index < GPIO_ITEM_COUNT); + furi_hal_gpio_write(gpio_item[index].pin, false); + furi_hal_gpio_init(gpio_item[index].pin, mode, GpioPullNo, GpioSpeedVeryHigh); +} + +void gpio_item_configure_all_pins(GpioMode mode) { + for(uint8_t i = 0; i < GPIO_ITEM_COUNT; i++) { + gpio_item_configure_pin(i, mode); + } +} + +void gpio_item_set_pin(uint8_t index, bool level) { + furi_assert(index < GPIO_ITEM_COUNT); + furi_hal_gpio_write(gpio_item[index].pin, level); +} + +void gpio_item_set_all_pins(bool level) { + for(uint8_t i = 0; i < GPIO_ITEM_COUNT; i++) { + gpio_item_set_pin(i, level); + } +} + +const char* gpio_item_get_pin_name(uint8_t index) { + furi_assert(index < GPIO_ITEM_COUNT + 1); + if(index == GPIO_ITEM_COUNT) { + return "ALL"; + } else { + return gpio_item[index].name; + } +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/timelapse/gpio_item.h b/Applications/Official/DEV_FW/source/xMasterX/timelapse/gpio_item.h new file mode 100644 index 000000000..5cb2b86c1 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/timelapse/gpio_item.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#define GPIO_ITEM_COUNT 8 + +void gpio_item_configure_pin(uint8_t index, GpioMode mode); + +void gpio_item_configure_all_pins(GpioMode mode); + +void gpio_item_set_pin(uint8_t index, bool level); + +void gpio_item_set_all_pins(bool level); + +const char* gpio_item_get_pin_name(uint8_t index); diff --git a/Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/ButtonDown_7x4.png b/Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/ButtonDown_7x4.png new file mode 100644 index 0000000000000000000000000000000000000000..2954bb6a67d1c23c0bb5d765e8d2aa04b9b5adec GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)I!3HFqj;YoHDIHH2#}J9|(o>FH3<^BV2haYO z-y5_sM4;GPjq%Ck6>60csmUj6EiNa>ORduPH4*)h!w|e3sE@(Z)z4*}Q$iC10Gods AV*mgE literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/ButtonLeft_4x7.png b/Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/ButtonLeft_4x7.png new file mode 100644 index 0000000000000000000000000000000000000000..0b4655d43247083aa705620e9836ac415b42ca46 GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/ButtonRight_4x7.png b/Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/ButtonRight_4x7.png new file mode 100644 index 0000000000000000000000000000000000000000..8e1c74c1c0038ea55172f19ac875003fc80c2d06 GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/ButtonUp_7x4.png b/Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/ButtonUp_7x4.png new file mode 100644 index 0000000000000000000000000000000000000000..1be79328b40a93297a5609756328406565c437c0 GIT binary patch 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- literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/Pin_star_7x7.png b/Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/Pin_star_7x7.png new file mode 100644 index 0000000000000000000000000000000000000000..42fdea86e489e278376e797b1110114697a0ad98 GIT binary patch literal 3600 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 LwKgd=cDwXHDN#*w literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/loading_10px.png b/Applications/Official/DEV_FW/source/xMasterX/timelapse/icons/loading_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..4f626b3d58c1800c375ebbfd358db6c72374dbcf GIT binary patch literal 4349 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 rrz))zzTsgFa-)vR)4GM +#include +#include +#include +#include +#include +#include "gpio_item.h" +#include "GPIO_Timelapse_icons.h" + +#define CONFIG_FILE_DIRECTORY_PATH "/ext/apps/GPIO" +#define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/zeitraffer.conf" + +// ЧаÑÑ‚ÑŒ кода покрадена из https://github.com/zmactep/flipperzero-hello-world + +int32_t Time = 10; // Таймер +int32_t Count = 10; // КоличеÑтво кадров +int32_t WorkTime = 0; // Счётчик таймера +int32_t WorkCount = 0; // Счётчик кадров +bool InfiniteShot = false; // БеÑÐºÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ñъёмка +bool Bulb = false; // Режим BULB +int32_t Backlight = 0; // ПодÑветка: вкл/выкл/авто +int32_t Delay = 3; // Задержка на отÑкочить +bool Work = false; + +const NotificationSequence sequence_click = { + &message_note_c7, + &message_delay_50, + &message_sound_off, + NULL, +}; + +typedef enum { + EventTypeTick, + EventTypeInput, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} ZeitrafferEvent; + +static void draw_callback(Canvas* canvas, void* ctx) { + UNUSED(ctx); + char temp_str[36]; + canvas_clear(canvas); + canvas_set_font(canvas, FontPrimary); + switch(Count) { + case -1: + snprintf(temp_str, sizeof(temp_str), "Set: BULB %li sec", Time); + break; + case 0: + snprintf(temp_str, sizeof(temp_str), "Set: infinite, %li sec", Time); + break; + default: + snprintf(temp_str, sizeof(temp_str), "Set: %li frames, %li sec", Count, Time); + } + canvas_draw_str(canvas, 3, 15, temp_str); + snprintf(temp_str, sizeof(temp_str), "Left: %li frames, %li sec", WorkCount, WorkTime); + canvas_draw_str(canvas, 3, 35, temp_str); + + switch(Backlight) { + case 1: + canvas_draw_str(canvas, 13, 55, "ON"); + break; + case 2: + canvas_draw_str(canvas, 13, 55, "OFF"); + break; + default: + canvas_draw_str(canvas, 13, 55, "AUTO"); + } + + //canvas_draw_icon(canvas, 90, 17, &I_ButtonUp_7x4); + //canvas_draw_icon(canvas, 100, 17, &I_ButtonDown_7x4); + //canvas_draw_icon(canvas, 27, 17, &I_ButtonLeftSmall_3x5); + //canvas_draw_icon(canvas, 37, 17, &I_ButtonRightSmall_3x5); + //canvas_draw_icon(canvas, 3, 48, &I_Pin_star_7x7); + + canvas_draw_icon(canvas, 85, 41, &I_ButtonUp_7x4); + canvas_draw_icon(canvas, 85, 57, &I_ButtonDown_7x4); + canvas_draw_icon(canvas, 59, 48, &I_ButtonLeft_4x7); + canvas_draw_icon(canvas, 72, 48, &I_ButtonRight_4x7); + canvas_draw_icon(canvas, 3, 48, &I_Pin_star_7x7); + + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 65, 55, "F"); + + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 85, 55, "S"); + + canvas_draw_icon(canvas, 59, 48, &I_ButtonLeft_4x7); + canvas_draw_icon(canvas, 72, 48, &I_ButtonRight_4x7); + + if(Work) { + canvas_draw_icon(canvas, 106, 46, &I_loading_10px); + } +} + +static void input_callback(InputEvent* input_event, void* ctx) { + // ПроверÑем, что контекÑÑ‚ не нулевой + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + + ZeitrafferEvent event = {.type = EventTypeInput, .input = *input_event}; + furi_message_queue_put(event_queue, &event, FuriWaitForever); +} + +static void timer_callback(FuriMessageQueue* event_queue) { + // ПроверÑем, что контекÑÑ‚ не нулевой + furi_assert(event_queue); + + ZeitrafferEvent event = {.type = EventTypeTick}; + furi_message_queue_put(event_queue, &event, 0); +} + +int32_t zeitraffer_app(void* p) { + UNUSED(p); + + // Текущее Ñобытие типа каÑтомного типа ZeitrafferEvent + ZeitrafferEvent event; + // Очередь Ñобытий на 8 Ñлементов размера ZeitrafferEvent + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(ZeitrafferEvent)); + + // Создаем новый view port + ViewPort* view_port = view_port_alloc(); + // Создаем callback отриÑовки, без контекÑта + view_port_draw_callback_set(view_port, draw_callback, NULL); + // Создаем callback нажатий на клавиши, в качеÑтве контекÑта передаем + // нашу очередь Ñообщений, чтоб запихивать в неё Ñти ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ + view_port_input_callback_set(view_port, input_callback, event_queue); + + // Создаем GUI Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ + Gui* gui = furi_record_open(RECORD_GUI); + // Подключаем view port к GUI в полноÑкранном режиме + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + // Конфигурим пины + gpio_item_configure_all_pins(GpioModeOutputPushPull); + + // Создаем периодичеÑкий таймер Ñ ÐºÐ¾Ð»Ð»Ð±Ñком, куда в качеÑтве + // контекÑта будет передаватьÑÑ Ð½Ð°ÑˆÐ° очередь Ñобытий + FuriTimer* timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, event_queue); + // ЗапуÑкаем таймер + //furi_timer_start(timer, 1500); + + // Включаем нотификации + NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION); + + Storage* storage = furi_record_open(RECORD_STORAGE); + + // Загружаем наÑтройки + FlipperFormat* load = flipper_format_file_alloc(storage); + + do { + if(!flipper_format_file_open_existing(load, CONFIG_FILE_PATH)) { + notification_message(notifications, &sequence_error); + break; + } + if(!flipper_format_read_int32(load, "Time", &Time, 1)) { + notification_message(notifications, &sequence_error); + break; + } + if(!flipper_format_read_int32(load, "Count", &Count, 1)) { + notification_message(notifications, &sequence_error); + break; + } + if(!flipper_format_read_int32(load, "Backlight", &Backlight, 1)) { + notification_message(notifications, &sequence_error); + break; + } + if(!flipper_format_read_int32(load, "Delay", &Delay, 1)) { + notification_message(notifications, &sequence_error); + break; + } + notification_message(notifications, &sequence_success); + + } while(0); + + flipper_format_free(load); + + // БеÑконечный цикл обработки очереди Ñобытий + while(1) { + // Выбираем Ñобытие из очереди в переменную event (ждем беÑконечно долго, еÑли очередь пуÑта) + // и проверÑем, что у Ð½Ð°Ñ Ð¿Ð¾Ð»ÑƒÑ‡Ð¸Ð»Ð¾ÑÑŒ Ñто Ñделать + furi_check(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk); + + // Ðаше Ñобытие — Ñто нажатие кнопки + if(event.type == EventTypeInput) { + if(event.input.type == InputTypeShort) { // Короткие Ð½Ð°Ð¶Ð°Ñ‚Ð¸Ñ + + if(event.input.key == InputKeyBack) { + if(Work) { // ЕÑли таймер запущен - нефиг мацать кнопки! + notification_message(notifications, &sequence_error); + } else { + WorkCount = Count; + WorkTime = 3; + if(Count == 0) { + InfiniteShot = true; + WorkCount = 1; + } else + InfiniteShot = false; + + notification_message(notifications, &sequence_success); + } + } + if(event.input.key == InputKeyRight) { + if(furi_timer_is_running(timer)) { + notification_message(notifications, &sequence_error); + } else { + Count++; + notification_message(notifications, &sequence_click); + } + } + if(event.input.key == InputKeyLeft) { + if(furi_timer_is_running(timer)) { + notification_message(notifications, &sequence_error); + } else { + Count--; + notification_message(notifications, &sequence_click); + } + } + if(event.input.key == InputKeyUp) { + if(furi_timer_is_running(timer)) { + notification_message(notifications, &sequence_error); + } else { + Time++; + notification_message(notifications, &sequence_click); + } + } + if(event.input.key == InputKeyDown) { + if(furi_timer_is_running(timer)) { + notification_message(notifications, &sequence_error); + } else { + Time--; + notification_message(notifications, &sequence_click); + } + } + if(event.input.key == InputKeyOk) { + if(furi_timer_is_running(timer)) { + notification_message(notifications, &sequence_click); + furi_timer_stop(timer); + Work = false; + } else { + furi_timer_start(timer, 1000); + Work = true; + + if(WorkCount == 0) WorkCount = Count; + + if(WorkTime == 0) WorkTime = Delay; + + if(Count == 0) { + InfiniteShot = true; + WorkCount = 1; + } else + InfiniteShot = false; + + if(Count == -1) { + gpio_item_set_pin(4, true); + gpio_item_set_pin(5, true); + Bulb = true; + WorkCount = 1; + WorkTime = Time; + } else + Bulb = false; + + notification_message(notifications, &sequence_success); + } + } + } + if(event.input.type == InputTypeLong) { // Длинные Ð½Ð°Ð¶Ð°Ñ‚Ð¸Ñ + // ЕÑли нажата кнопка "назад", то выходим из цикла, а Ñледовательно и из Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ + if(event.input.key == InputKeyBack) { + if(furi_timer_is_running(timer)) { // РеÑли работает таймер - не выходим :D + notification_message(notifications, &sequence_error); + } else { + notification_message(notifications, &sequence_click); + gpio_item_set_all_pins(false); + furi_timer_stop(timer); + notification_message( + notifications, &sequence_display_backlight_enforce_auto); + break; + } + } + if(event.input.key == InputKeyOk) { + // Ðам ваша подÑветка и нахой не нужна! Или нужна? + Backlight++; + if(Backlight > 2) Backlight = 0; + } + } + + if(event.input.type == InputTypeRepeat) { // Зажатые кнопки + if(event.input.key == InputKeyRight) { + if(furi_timer_is_running(timer)) { + notification_message(notifications, &sequence_error); + } else { + Count = Count + 10; + } + } + if(event.input.key == InputKeyLeft) { + if(furi_timer_is_running(timer)) { + notification_message(notifications, &sequence_error); + } else { + Count = Count - 10; + } + } + if(event.input.key == InputKeyUp) { + if(furi_timer_is_running(timer)) { + notification_message(notifications, &sequence_error); + } else { + Time = Time + 10; + } + } + if(event.input.key == InputKeyDown) { + if(furi_timer_is_running(timer)) { + notification_message(notifications, &sequence_error); + } else { + Time = Time - 10; + } + } + } + } + + // Ðаше Ñобытие — Ñто Ñработавший таймер + else if(event.type == EventTypeTick) { + WorkTime--; + + if(WorkTime < 1) { // фоткаем + notification_message(notifications, &sequence_blink_white_100); + if(Bulb) { + gpio_item_set_all_pins(false); + WorkCount = 0; + } else { + WorkCount--; + view_port_update(view_port); + notification_message(notifications, &sequence_click); + // Дрыгаем ногами + //gpio_item_set_all_pins(true); + gpio_item_set_pin(4, true); + gpio_item_set_pin(5, true); + furi_delay_ms(400); // Ðа короткие Ð½Ð°Ð¶Ð°Ñ‚Ð¸Ñ Ñ„Ð¾Ñ‚Ð¸Ðº плохо реагирует + gpio_item_set_pin(4, false); + gpio_item_set_pin(5, false); + //gpio_item_set_all_pins(false); + + if(InfiniteShot) WorkCount++; + + WorkTime = Time; + view_port_update(view_port); + } + } else { + // ОтправлÑем нотификацию Ð¼Ð¸Ð³Ð°Ð½Ð¸Ñ Ñиним Ñветодиодом + notification_message(notifications, &sequence_blink_blue_100); + } + + if(WorkCount < 1) { // закончили + Work = false; + gpio_item_set_all_pins(false); + furi_timer_stop(timer); + notification_message(notifications, &sequence_audiovisual_alert); + WorkTime = 3; + WorkCount = 0; + } + + switch(Backlight) { // чо по подÑветке? + case 1: + notification_message(notifications, &sequence_display_backlight_on); + break; + case 2: + notification_message(notifications, &sequence_display_backlight_off); + break; + default: + notification_message(notifications, &sequence_display_backlight_enforce_auto); + } + } + if(Time < 1) Time = 1; // Ðе даём открутить таймер меньше единицы + if(Count < -1) + Count = 0; // Ртут даём, бо 0 кадров Ñто беÑÐºÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ñъёмка, а -1 кадров - BULB + } + + // СхоронÑем наÑтройки + FlipperFormat* save = flipper_format_file_alloc(storage); + + do { + if(!flipper_format_file_open_always(save, CONFIG_FILE_PATH)) { + notification_message(notifications, &sequence_error); + break; + } + if(!flipper_format_write_header_cstr(save, "Zeitraffer", 1)) { + notification_message(notifications, &sequence_error); + break; + } + if(!flipper_format_write_comment_cstr( + save, + "Zeitraffer app settings: n of frames, interval time, backlight type, Delay")) { + notification_message(notifications, &sequence_error); + break; + } + if(!flipper_format_write_int32(save, "Time", &Time, 1)) { + notification_message(notifications, &sequence_error); + break; + } + if(!flipper_format_write_int32(save, "Count", &Count, 1)) { + notification_message(notifications, &sequence_error); + break; + } + if(!flipper_format_write_int32(save, "Backlight", &Backlight, 1)) { + notification_message(notifications, &sequence_error); + break; + } + if(!flipper_format_write_int32(save, "Delay", &Delay, 1)) { + notification_message(notifications, &sequence_error); + break; + } + + } while(0); + + flipper_format_free(save); + + furi_record_close(RECORD_STORAGE); + + // Очищаем таймер + furi_timer_free(timer); + + // Ð¡Ð¿ÐµÑ†Ð¸Ð°Ð»ÑŒÐ½Ð°Ñ Ð¾Ñ‡Ð¸Ñтка памÑти, занимаемой очередью + furi_message_queue_free(event_queue); + + // ЧиÑтим Ñозданные объекты, ÑвÑзанные Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñом + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + furi_record_close(RECORD_GUI); + + // Очищаем нотификации + furi_record_close(RECORD_NOTIFICATION); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/timelapse/zeitraffer.png b/Applications/Official/DEV_FW/source/xMasterX/timelapse/zeitraffer.png new file mode 100644 index 0000000000000000000000000000000000000000..3a42e406d179a5649f29c3d07e42935612819217 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V6Od#Ihk44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`0h7I;J!GcfQS24TkI`72U@f-#;hjv*Ssx&4-W2NZZ%HfI0-zqEv7qGGp& z&@zW_a??DPPAQvY_GWYQ%#U8*!zC}V_;;OuV`_NIK-fxq8t;GUcHU~yKUKm4fmP9* qtu58-4cF8syR$f-i%eSkmGND+`}5~>MdkwSVeoYIb6Mw<&;$SgDL|+I literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/.gitignore b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/.gitignore new file mode 100644 index 000000000..e4e5f6c8b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/.gitignore @@ -0,0 +1 @@ +*~ \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/CHANGELOG.md b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/CHANGELOG.md new file mode 100644 index 000000000..d0924edd3 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/CHANGELOG.md @@ -0,0 +1,13 @@ +# Changelog + +## 0.4 +- Show active/inactive state in primary font (bold) + +## 0.3 +- Add a delay between key-presses (with left/right buttons) + +## 0.2 +- Update icon + +## 0.1 +- Initial release of the USB HID Autofire application diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/LICENSE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/README.md b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/README.md new file mode 100644 index 000000000..b2cbd7606 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/README.md @@ -0,0 +1,32 @@ +# USB HID Autofire + +[GitHub](https://github.com/pbek/usb_hid_autofire) | +[Latest release](https://github.com/pbek/usb_hid_autofire/releases/latest) | +[Changelog](CHANGELOG.md) | +[License](LICENSE.md) + +[![Build](https://github.com/pbek/usb_hid_autofire/actions/workflows/build-test.yml/badge.svg)](https://github.com/pbek/usb_hid_autofire/actions/workflows/build-test.yml) + +This is a simple Flipper Zero application to send left-clicks as a USB HID device. + +![Screenshot](screenshot.png) + +## Installation + +Download the [latest release](https://github.com/pbek/usb_hid_autofire/releases/latest) +of the *fap* file and put it into the `apps` folder on your SD card of your Flipper Zero. + +## Building + +```shell +cd applications_user +git clone https://github.com/pbek/usb_hid_autofire.git + +cd .. + +# Build the application +./fbt fap_usb_hid_autofire + +# Build and launch the application +./fbt launch_app APPSRC=usb_hid_autofire +``` diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/application.fam b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/application.fam new file mode 100644 index 000000000..56762838a --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/application.fam @@ -0,0 +1,13 @@ +App( + appid="usb_hid_autofire", + name="USB HID Autofire", + apptype=FlipperAppType.EXTERNAL, + entry_point="usb_hid_autofire_app", + cdefines=["APP_USB_HID_AUTOFIRE"], + requires=[ + "gui", + ], + stack_size=1 * 1024, + fap_icon="usb_hid_autofire.png", + fap_category="Misc_Extra", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/screenshot.png b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..b5547e1ba807aefb3245fc480d1a2efc8ae1de4c GIT binary patch literal 2176 zcmb7Ge^8TU9DfEXLJdmelEmn)h_pNu50cFRl?E6BItIBZa{geBso?CEG z{cz}5u@pBQWMin|HVlmv*jW1kf-uBjYiz#6%Qn~;HOtON>%8la_n!B8?|r||=ll75 zzMp#!XJ@8jLtY300ASP8R&M|xz<-MYbMG%}$2TtXFTo{g8yNtEUb}x`zIZ)!ApmpZ z(pSHgv+tCnpHknK@Z9V!+*nDR>gn3Mqx(MM{+jwch7$Mdu{1=Xs-zIoZfWL(McbSx zg77e(TKe=@Fc=X4Ui#c$CK`aZgF$)rgRQg3$2XxEGk03P-Al3v6ASqypK?#KeBFCa zG?L)Bj0!%}X@@ll6Jyg@{IY*NjLOo#6Bmo~4PGS4=- z;>g4Pa;6wS9Dj>w3XtwA#%v;Wd@S7hL1^K~WFCz%=Uo84ne{h5=`;t(s>y3M^Gn5} z0~5QB=jL&4{?ARI4T+S)_ z$O)Fqw>oRH$cDNic^6e)$HWTg$SpO2R!Np)lXmM;5%Y{b+1=lJg~G0fxHWvQC@(aL zXbwCsW<94qBHYq1%WbyFt+!Z>SlKqsZOZ_z+q#^xn{wLI-0ks7we>?PFP_I2n?*WT zhOf`7W(SNNd!T@=J+ehwZID`mb7js8edK6yU&k)>%?_$gzRtNRP0M2ETxY)ToXWjO zHTL3T@{d$5r3@d(4xpMAa_ZWU{^IWf545Hv@g z@ytO1`%VL|_%{hr8(F77tS%Xc?MXtPzPi(!$`31njW`glxGR`Cpz};-_&AN&@Z8QQ zd)M=WZ$M|+gxUC{)3F3?^n{(gmiMUPVv)c}!&EuZ6W7~B^vt&3fcS|w2k)n@E1ggV zh`qV)9cQrTT(cLzhv(aV1_H=#|B+n(IR4*E<)Ffr>0i*QA)#4PQs%9|L6D{N&_Qx) zJ}I_-Wub!DTWTy~Xm7VHA&3;0LoSIRvc@ApbXk!{jHbkB7GBjrSPWk!mJ8Ue6tBim zl!{=Zl;$h7Rjc$PrUbEt%Gf?o7ofw_=kCBQ4Ucz|Mt`ywj8r!^Norbq?#y^< zRDmd5**{bUDzewIzeSiNi7g3v`C(8ic7>+&ySU*fCd)X);SF-3rfdYc>86zFNab(5 zfGl1zfXUu_O2;^=O2wR@LLSSfF^vNE{6_nJY*uk{b{ixJ#~zvD^o@f$I0d5cL7;^P zKlwM;|4W!By!=;g6(`S3nRjz%e7-|p+HW{3?ah&r>a^y}P{smL)k z*=Vlu2Uoipb?X>!eFAyG6BqPd5y4H;&Oc&Gr)o&DTK>7B;pWY)g3%HxkEMFGs}1#4q*S}rx(Vv>!Z!rJ> literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/tools.c b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/tools.c new file mode 100644 index 000000000..2b452b55b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/tools.c @@ -0,0 +1,56 @@ +// +// Tools for USB HID Autofire +// + +void strrev(char* arr, int start, int end) { + char temp; + + if (start >= end) + return; + + temp = *(arr + start); + *(arr + start) = *(arr + end); + *(arr + end) = temp; + + start++; + end--; + strrev(arr, start, end); +} + +char *itoa(int number, char *arr, int base) +{ + int i = 0, r, negative = 0; + + if (number == 0) + { + arr[i] = '0'; + arr[i + 1] = '\0'; + return arr; + } + + if (number < 0 && base == 10) + { + number *= -1; + negative = 1; + } + + while (number != 0) + { + r = number % base; + arr[i] = (r > 9) ? (r - 10) + 'a' : r + '0'; + i++; + number /= base; + } + + if (negative) + { + arr[i] = '-'; + i++; + } + + strrev(arr, 0, i - 1); + + arr[i] = '\0'; + + return arr; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/tools.h b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/tools.h new file mode 100644 index 000000000..9c71ea6ca --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/tools.h @@ -0,0 +1,7 @@ +#ifndef FLIPPERZERO_FIRMWARE_TOOLS_H +#define FLIPPERZERO_FIRMWARE_TOOLS_H + +void strrev(char *arr, int start, int end); +char *itoa(int number, char *arr, int base); + +#endif //FLIPPERZERO_FIRMWARE_TOOLS_H diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/usb_hid_autofire.c b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/usb_hid_autofire.c new file mode 100644 index 000000000..1333ba94a --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/usb_hid_autofire.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include +#include +#include "version.h" +#include "tools.h" + +// Uncomment to be able to make a screenshot +//#define USB_HID_AUTOFIRE_SCREENSHOT + +typedef enum { + EventTypeInput, +} EventType; + +typedef struct { + union { + InputEvent input; + }; + EventType type; +} UsbMouseEvent; + +bool btn_left_autofire = false; +uint32_t autofire_delay = 10; + +static void usb_hid_autofire_render_callback(Canvas* canvas, void* ctx) { + UNUSED(ctx); + char autofire_delay_str[12]; + //std::string pi = "pi is " + std::to_string(3.1415926); + itoa(autofire_delay, autofire_delay_str, 10); + //sprintf(autofire_delay_str, "%lu", autofire_delay); + + canvas_clear(canvas); + + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 0, 10, "USB HID Autofire"); + canvas_draw_str(canvas, 0, 34, btn_left_autofire ? "" : ""); + + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 90, 10, "v"); + canvas_draw_str(canvas, 96, 10, VERSION); + canvas_draw_str(canvas, 0, 22, "Press [ok] for auto left clicking"); + canvas_draw_str(canvas, 0, 46, "delay [ms]:"); + canvas_draw_str(canvas, 50, 46, autofire_delay_str); + canvas_draw_str(canvas, 0, 63, "Press [back] to exit"); +} + +static void usb_hid_autofire_input_callback(InputEvent* input_event, void* ctx) { + FuriMessageQueue* event_queue = ctx; + + UsbMouseEvent event; + event.type = EventTypeInput; + event.input = *input_event; + furi_message_queue_put(event_queue, &event, FuriWaitForever); +} + +int32_t usb_hid_autofire_app(void* p) { + UNUSED(p); + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(UsbMouseEvent)); + furi_check(event_queue); + ViewPort* view_port = view_port_alloc(); + + FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config(); +#ifndef USB_HID_AUTOFIRE_SCREENSHOT + furi_hal_usb_unlock(); + furi_check(furi_hal_usb_set_config(&usb_hid, NULL) == true); +#endif + + view_port_draw_callback_set(view_port, usb_hid_autofire_render_callback, NULL); + view_port_input_callback_set(view_port, usb_hid_autofire_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); + + UsbMouseEvent event; + while(1) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 50); + + if(event_status == FuriStatusOk) { + if(event.type == EventTypeInput) { + if(event.input.key == InputKeyBack) { + break; + } + + if(event.input.type != InputTypeRelease) { + continue; + } + + switch(event.input.key) { + case InputKeyOk: + btn_left_autofire = !btn_left_autofire; + break; + case InputKeyLeft: + if(autofire_delay > 0) { + autofire_delay -= 10; + } + break; + case InputKeyRight: + autofire_delay += 10; + break; + default: + break; + } + } + } + + if(btn_left_autofire) { + furi_hal_hid_mouse_press(HID_MOUSE_BTN_LEFT); + // TODO: Don't wait, but use the timer directly to just don't send the release event (see furi_hal_cortex_delay_us) + furi_delay_us(autofire_delay * 500); + furi_hal_hid_mouse_release(HID_MOUSE_BTN_LEFT); + furi_delay_us(autofire_delay * 500); + } + + view_port_update(view_port); + } + + furi_hal_usb_set_config(usb_mode_prev, NULL); + + // remove & free all stuff created by app + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + furi_message_queue_free(event_queue); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/usb_hid_autofire.kra b/Applications/Official/DEV_FW/source/xMasterX/usb_hid_autofire/usb_hid_autofire.kra new file mode 100644 index 0000000000000000000000000000000000000000..21d41654829152f856c81b842ab51642a698c97b GIT binary patch literal 50949 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

  • &lZMP0o;ht2SJ@vHc6c;m%^iATiYje!0|<*d)-84jbhS;s(yJ(~H(Ss?}<-V&qsX5^h zkUz)0$8Ohz&5?SiPD?SCo=CIb4_I=q%pGnx+lQ;BABFj@&nxGe^iHfchWw$xeKVAcKuv{`6%Eb}r&i4uEJm;saYJTa+v9JS#xI<1;^eLLk6W(`#$4>%PF_or!tP4S zOzMu6i2ag#$P|J2V8+^-|6YXcBll_KDsJE2?ygi+fJST#eHrfU&*;xjUrtYXMn7M$ z^||Sb(!H_vmiGNmyMhg1Cs&VdE;Mt-IVwwcrlg!_&Vw#!asB>$u;%uvXfs7AC50=% zpRw|N$>>J(&L1Y*lE8Lj__8@f76q^%Gkho@TRM?SaitK+A%R^K6aesR(eMN|!O;Op zV$dPP9Un+AoykK30LmoFV#N-gJ@(l*u%(C-;s%>_|a@aSroTW zCp;H~Ce~ThG9syw) zEDFd30@EYu>+6F|5D*HP2=_7YC6aVOaD6xo3gg`-dN30t+yDtffd0O~ynrmSFVYof z^>;Yl2@UpRvzbUJl*8dbI0g^~iwcDy5D2I~914f)@jUc`LIT*tV7-7KwI2*PN)U-f zW3p+C0MHI2(T8!CjRy0?{yPgg^B>xPpua1{s~I$y$b`Zm`a4!7}Ki)xX zSIU3%{#W84d#E-#d1o<(TAh-bp z2GVjQl4t=t7VWg260t78WKZ zhY%(hgaHm?Wra2PfyFUMXX%sx_75!iKUl<1u{#4nXYwNBC@k7J3fYRqpo9L(8cF-P z7UQ4t{f#C6T#Lz1u~42E=uU6{U$1|dcmuSv{bzW2hkwSO62O~z7H_!8UA2pOjBYOr6$rKCie3z7@InH%mQJ`zjCb_^0Yo%bT>t<8 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/CoolLo_hvr_25x27.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/CoolLo_hvr_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..ae5316e4d49992b01a39a4298e36cac1fd365388 GIT binary patch literal 3657 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 P_yK!sCtMlE=iI*m`3F!x literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Cry_dolph_55x52.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Cry_dolph_55x52.png new file mode 100644 index 0000000000000000000000000000000000000000..86d9db1b497cd9e49bb62987cb35075b4bc7a410 GIT binary patch literal 3898 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 Y0_*BPx59$cJUb46GqS>#p?%qL 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 Tfe|}@hk%WR1FiydCgT49&LB(v literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Detailed_chip_17x13.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Detailed_chip_17x13.png new file mode 100644 index 0000000000000000000000000000000000000000..9aaa1c5552a2d115b7042a4bee7a0c636ed00f01 GIT binary patch literal 981 zcmaJ=J#W)M7(OYeLKPj#QkCg&D-;Cr*-rCeE2g-1LL=2tNCOR99Q)c>t$oJ65VuGu zVnF3@kLJTyAbTF)X)*fzP%Q<}b4VM5&U3Hr++A_Bkn|QpH zVEEVz7#o1ndK_5xKBlmP_gr7)PCtF&pzEmIPR=O80g2g+ASyy$$;xp2aV%Qs>?#eTGLFSgD%YhnP!Q_(`+PsklW-4-vMeJ(LXwnW zh)i_oQ!CE+(aJ=@z>yug0dBsWU6DwL#6tZhZF{^J#+JtKm zyXRq_PPooFSDVRAHo*&6WCMrpBkWW{;=xhHiaR@(!c4s}*O{G5aV8hBWKc5Kzveu- zV#|}b)2(HP>E2_XEqlne`s3TXUG^g8>RZk7a5!Y{y|3S&FjK4=S~LF9X}8eNYr-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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/DolphinMafia_115x62.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/DolphinMafia_115x62.png new file mode 100644 index 0000000000000000000000000000000000000000..66fdb40ff2651916faed4a2ae1d564cafdbf7bcb GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/DolphinNice_96x59.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/DolphinNice_96x59.png new file mode 100644 index 0000000000000000000000000000000000000000..a299d3630239b4486e249cc501872bed5996df3b GIT binary patch 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!QDSr z1<%~X^wgl##FWaylc_cg49qH-ArU1JzCKpT`MG+DAT@dwxdlMo3=B5*6$OdO*{LN8 zNvY|XdA3ULckfqH$V{%1*XSQL?vFu&J;D8jzb> zlBiITo0C^;Rbi_HHrEQs1_|pcDS(xfWZNo192Makpx~Tel&WB+XP}#GU|^lpi<;HsXMd|v6mX? zCgqow*eU^?3h_g30o>TUVrV!4LrlLSu|VHY&j92nm_lD){7Q3k;i`*Ef>IIg#cFVI zNM%8)eo$(0erZuMFy_*fK~@!5ITxiSmgEfrKz*2sj;DkpMZknD6wv4b%oJ<^ zJ|V9E|NjRvLl0f915!UdT^vIyZe6(^E!Jef<9czm0A z3tiQZTzK79dS605C-KUauQq03?HktYO@Gah6}dWL!K=tEQF6i?wpZ6>D42{4Kw06Cgbx4xeweJDDGS}F({`j)7X?o}J zyX`DecdFHnf1Yl!OLgg{#J>1HY(M3>ay__X{YpODaR^Nc-<&V5lUuWQxzBn#x3aK( p%=f=fPd;t;X_5T?htnCD8BU8cnRk73T?7mS22WQ%mvv4FO#oZ0m5TrX literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/DolphinWait_61x59.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/DolphinWait_61x59.png new file mode 100644 index 0000000000000000000000000000000000000000..423e079199b00df0d910981caf8944cbaf8ee67e GIT binary patch literal 2023 zcmbVN2~ZPP7!Hc#RVu|&R6N!I%3-nxkdW1AfgnT)&=3`rikr>mC`oqNT?mIZ73u(L zrQQXsTAVP$bgCRqVL%3}R4ZPzma(V>JPRlyt(Mwx+HOKfI~`kFcXs!^eeZkUfB##O zlo0DNW!4lPkLMwelPS4T$~}uGjpN?2soqDpVKNn$%J6tor`sPlUipC;Jl=#i45}11 zMG=qUq)CWrNHrnMF;N_v$6K;2hr;j-f(6us&R~}EhnidYfI%bWuL)N`3M!h=8{+b4 zA~`QXh39495)FUZQea6A$`P0d76WojMl*xvNcj$4l$+a^K|bJsuo+T*q+KA8qDTUw zNtyseLP&r^5CVuLLRb_QCW00L2!uc&6b{0O02ZN87z&F4=f&rw(HbqPlr4A4;=ZJO zJE3n9Bn4xk2i;ixRy=n$^KLBdFw2s6uYSlET-yrfXL z;LoKsnOtawjmhRTa@zJ>G^5I;2vA8dWEPDRG1;6%zcIxqJ;{=cp8N+pT-z>dC^VWT zFqWiMBxxKARMHp=fWSfo2wY<@Ye)+dWS8PRK*%tbkn*{x!2$^3ZWV%{P&f+1AuxnO z&?r>F<$(rcvHu1pH3n_&3!xeu)snOc(Gwi$zvRUzj3KqG1*3^b z9p~;B<{ii>584ZM)DH0PCOY>1Qru&3u4CAzu2#i;xSAbd<~khBwX$#Sj?d@u##!XD zNR@tb=h}6&`}|35K||KN=gwBmj&-Xj(w;uMx-L?`(_*_ZqL8ard_B`EtMjXyZhc;> zZF)8CG-7Mu_=mE#!jz);z6%T5S~mVv@At*=X|?Ol?+v-67}*3~ z(I*yd*!+Hl{6bH0ad%YF(4l>;^=h9m2|jf9+!^TVd3?C0_k*j|7SExD#fc+65!1f++)=)#z9VKCyt!)o1FiS^CqLF68$Nlu@R-*F`KK+GldJrn z-6KW!*!*?i?t>eHLo#YCZFefNm-}Sy+HzW#(kJAQ% zu3Sm`#Ai<6U{7oT)is=0nUQ{99C7-Y$5MCXl>F$xVZhye@tt~FtDW0WISrk6aF6fm zc|x z#r8!%cqXJshqsp~m3WISwlJh}Z|BwFsa3Puno2spY&@ROyQ9E+zRBvfE9A|~$kXqv z6B}Ob_YXK*dq(uIvE9}XXM5*fnIhFsF*9M3Y+v$?f)8s}ZTskiwP8;Zmba>-dq;Q2 swOjp-{igh?qWDbj&x1Zp}@CP3WTf1pBX89+MzD8nvO|4+g31aR2}S literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/DoorLeft_70x55.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/DoorLeft_70x55.png new file mode 100644 index 0000000000000000000000000000000000000000..5df87ba3ce60e52f01ca93ef6c0a576e160890c7 GIT binary patch literal 564 zcmeAS@N?(olHy`uVBq!ia0vp^Za{3##0(_Q*j*_GQY`6?zK#qG8~eHcB(ehe3dtTp zz6=aiY77hwEes65fIEak-ak_VsVc!u29#>zM zpe>@TFN4o(&Pl3vi+VSCalkpl<1-|z7e;zZcA9_tzMb)a%YyZXbT9S%slVv8B4(m! zQB<4odqHhcAcx1J*v z3=wN2`Z?28g|9oToszWvZ1Q%gU-3CQ&KexiQY$8Ov6r}C)7kWdtBQTr){lx(Ec=bC zJ~Q&3s$W>TMdNE9^TewT`{taq@-NsUbT#V5YvZir8#@}yYWbQ@gq^dQV=c1uO85p% zu7&!iM0PFS&CylzUF;;Uq{{b<33t9ZYoGO4a?5z)chwiB7d+mdKXNQ! zC8<`)MX5lF!N|bKP}jgj*T_7?z}(8z#LC1#+rYrez#wW)@(&aZx%nxXX_e?2jIB&e WAR26gp6CHJFnGH9xvXIqW5#zOL*~S)|zwMEwOP0bRhT=jq}YVsW~6vh}*d3IeXN zN31)4cfL?;Xp|4q@cp7B0AV+D3);<=5C+e>7`V7w%P2TFhy5iBW=eV*l|y0v``5 z7c}!;@?t5zz%zM8QuBkHi+-}31P=zw=en49-z^IZJ@Z9q)`F9UPbWS1RzI#F$spI2 z;icic(P-C974aXl^rIX@_2%)r-MJP0RY5XW^wsR|9a_Obu2*mWV~~Fy8TzMR-x3&@ zswJ)wB`Jv|saDBFsX&Us$iT=@*T6*A$UMZr+{(n<%G6TZz`)ADKvUeQ3`Ik3eoAIq bC8h=w6NrYd=Ch{&H86O(`njxgN@xNAhg#0O literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Down_25x27.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Down_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..c1309777866dac996abc353bb81b6313e40b78a5 GIT binary patch literal 3650 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Error_62x31.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Error_62x31.png new file mode 100644 index 0000000000000000000000000000000000000000..bb280e75121e12eae045d87a33f61b1713af6f85 GIT binary patch literal 3751 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 V0A_Pz|1^geur#waEi!h!{2vr@XiES9 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/EviSmile2_18x21.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/EviSmile2_18x21.png new file mode 100644 index 0000000000000000000000000000000000000000..7e28c9f018a0f2cb572e5f5ce1db2e5c71511dd9 GIT binary patch literal 3649 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 NjisGMnc1oH{{vTjXlVcd literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/EviWaiting1_18x21.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/EviWaiting1_18x21.png new file mode 100644 index 0000000000000000000000000000000000000000..d39d2173329d5317fc2cdfb18738922a5eeec6fe GIT binary patch literal 13020 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%0DogpcYr`$ z++qJ}>3@a%wq1X@`yto-TOabSio8kl{&AQ7JzRfg^#9`P_cZuloB>JwpGp2Leg7lZ zf8_eN6!^Em|B0^u$n|e2@Na?t6J7t`SN77L~l0$9an+)c;9a+DZRZZS8{^eP~v1|B4dJsqoRU?V`GD5l`ss3 nQ0V!FVYmG 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 M>FVdQ&MBb@0ME-_z5oCK literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/FaceConfused_29x14.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/FaceConfused_29x14.png new file mode 100644 index 0000000000000000000000000000000000000000..dcd2e3c6736144ddc292178f4d7fae7fcc962f30 GIT binary patch literal 317 zcmeAS@N?(olHy`uVBq!ia0vp^vOvto2qYMOuhNNn{1`6_P!I zd>I(3)EF2VS{N990fib~Fff!FFfhDIU|_JC!N4G1FlSew4N!t9$=lt9f$?sa@Dd=8 zy~NYkmHjER5QmDqt6arCppdJli(?4K_2eJl|I4!3*zvvWJ#Sn4_SZTR|Nj5~&+H}hfL)09jl-hRdP`(kYX@0Ff!CNFxEA+2r;m*GB&X?G|)CMure_4`hHX%MMG|WN@iLm WZVlF}Y8L}FFnGH9xvXNn{1`6_P!I zd>I(3)EF2VS{N990fib~Fff!FFfhDIU|_JC!N4G1FlSew4N!t9$=lt9f$?sa@Dd=8 zy~NYkmHjER5QmC(%Bmi2ppcoTi(?4K_2eJ_|NrN2v;SZ3)G7bJ{!c>2pa1R63xEE% z=VRNT(^8SZuX64@yAbamgGKx0mADzU|I)V!JIr|=Xo6~qYeY#(Vo9o1a#1RfVlXl= zGSoFN)-|*UF|e>QHnB1>&^9ozGB98gKV6NYAvZrIGp!Q0hGMVc<3J4zp00i_>zopr E04(EH4gdfE literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/FaceNormal_29x14.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/FaceNormal_29x14.png new file mode 100644 index 0000000000000000000000000000000000000000..52d78c08698f3cb1c70d1b39d44f950664c1b6c6 GIT binary patch literal 295 zcmeAS@N?(olHy`uVBq!ia0vp^vOvto2qYMOuhNNn{1`6_P!I zd>I(3)EF2VS{N990fib~Fff!FFfhDIU|_JC!N4G1FlSew4N!t9$=lt9f$?sa@Dd=8 zy~NYkmHjER5QhrG39(Xdppd?&i(?4K_2eJ_|NrN2JN*B@r@@wg{}&&;@Z&!}yAb0v z2JJ?H_um%_+<)D8r2oG?!(RbCK3(x2*+8wTC9V-ADTyViR>?)FK#IZ0z{pV7z*yJN yBE-PL%GlJ(#8lhBz{nC}Q!>*kacelY!8{JAfx*+&&t;ucLK6VES60IS literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/GameMode_11x8.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/GameMode_11x8.png new file mode 100644 index 0000000000000000000000000000000000000000..49f2e25bf32025b68f659fb354abe59d61ba2235 GIT binary patch literal 3610 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Health_16x16.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Health_16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..af343c520587f373d41b35cdf8c9b50345fc0286 GIT binary patch literal 282 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/HeatHi_hvr_25x27.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/HeatHi_hvr_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..b92108d68de2ab09bed6b451e36396881e5611ea GIT binary patch literal 3661 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 T-|@M}j{(?QJ7Y`Hry~9hE1FGt literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/HeatLo_25x27.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/HeatLo_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..af2e59d4940aefa657c280acb8073800408dabba GIT binary patch literal 3670 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 O0dr$(Y#G`u;{O0;Ay2me literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Hidden_window_9x8.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Hidden_window_9x8.png new file mode 100644 index 0000000000000000000000000000000000000000..d6fc2b326d03d5b6a3dbabb1d5ed3a8a0140d35f GIT binary patch literal 3604 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 M%FN!h6ytIA-_)%w8UO$Q literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/InfraredArrowDown_4x8.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/InfraredArrowDown_4x8.png new file mode 100644 index 0000000000000000000000000000000000000000..2ac7bcdbef24ccececa268c20e92946b4f8eed15 GIT binary patch literal 3589 zcmaJ^c{o)4-#)fNS+Xz581Yn=F?N%&FQaUYZB$~6!C;nV1~ZaGO39WjYeGp4ZOSBD zB4mpqS+bMRSVGp`>G?f9zxR)~_gvRG-|fEd&*%I3-sif`x$0>G}TX>ui zbP)h6GI*PX-3x?o0O(7?A|{P7vHY%L;`?$CE)7vV{D|DxvHU|!KhtZmC*xdB>wl9U zEPi%Aj5R;M`Ej#qI%j&TgWf3=xlcqnd8!})FhIr_!usSB9S{vI)sdXyh!Jj(@KkHP zA5S9yEO60j5!6SV3FxP97#x^S>3r=3}}`D z9yvYr;RjLyAc!7r1_tg60CV4MjCg>)l9WM7ps!$m2`>=O0c0MsKFDeE67X`lh*agQ zs|WHKCSY~$x-yPP_vf0{oRQT$Ku7{ANyx+th|DxoZ3961oPhZO(RMD7EmyuqckM`t zCn<)B-~j4c)7mqRcWa3;)85I1E-j3VDU8(zJvKv29v1fHn*irzWGjjyrnzi8_5y&+ zde^HRedDC*sfp1k-{~OM_r`*qzy%`MNMUh!r|LQ_X z1@yZD{=@4YS_6FfC;8unt;f;zw@eP?-F9p?l-tk0XV1Kn_w8zp@i?QOTBF2~xQJEu z>drve0&q6VB(t=xFnaqenh;WkOqg!vHiHt@rWJRZVlHea9PS#^etcS0{MsVwD$@~c z*F=ATOtw&HNgETHxuCfypT5nP5-I>NE<4oOKi~bVHK;D)8wY2cAgVhAFo{@JyDqaQ z84&i<)}*fiKuYa;qKOIz(4J8=4gghOq)y*Um9%}sHkw8L#UqbQckg{A#;6m_c_mj> zC&`K4Wnr@SV4b0`*{+Gm{rtD3(oLnE>tKD{&mM8f7T&V#Q8?8=J{RoF!%f$sP#B zB{i~`LHucxjiiBQkmj|mYgN|J)Qe9}aDCtmHhFPRUgp}Hd`cHpTgW3ay&$klru+ar z@_9jV*YPjGRN(xz1WaTXRM7YOC-mv-S1i4*qGXhtBruaG9oIx1j2ucYL|nEm56$8| z$Qc(YI>&qFl5l-cR8o>P$`)mQPiaoET%?lMjW7BVwEiz}$~}j2r7)582AVhQaT3ak zq5MtZfI^PSij2C2aXGfivq|`t&l9{) zA{n5JXC5qp^D6(rthVi!?ny<}IeS=GRscHXC+tk2no@NCM4 zK+f4ZnN#ljGJKPLbEnR>a|ph9JhEW$Dd$*+LWe-dIW;adW3|V<0j0jB5v6+lVf{7z z-t**niTT-nRxl~oBv&II{A%~+@9k^#uS{<6FYK}@{EMml?TX*H z4o%X?mqFa`&Cvdg9Sk%?d*d_*iW-U4#xbmVxzb%%Tt6~wdQZ=)&f;c1R?Uatned7$CcNOkKuFPIS=yU{VjW%R~~^H$icD>Zj(z{Btw#faXB z%!u7vd7DQ!TDKE_)Q-}ZBo^&?yf|KQOmb9Tl)3nnE09Z`JCpm)ZXKR@o|n5IdyT}+ z_VNk1%ac=xb&^Z6>lm#;Kh>-*@wdFW;wNP{G}@GH5A^O!xZKG*EF3|+yKXzv_MA6% z#5yRJDUXxRlw3bAcKC?qef6&=%AKfZscWjej0yKmzv_g=#FFbTjt&GoCx`ek0)mi1 zn7M3bB=bJ=BJIi#%f$>4s^~$!`KuEReGTxd;}p*6pe(JNi7e-IDyD35u;7K{)J#Wf zUZ|nFj(bwLe#}jgj3>sE(I7KNh?K)*F~Lqwbm>xdjDuxOL43i9#}&+DhBu~iUDH%4^DBhzZ&5>uGTyS4wNnv8OzTjG#=OLHch2ozwPei(P>Df<4{K|m@ZpiV z@dpqv(qwidu|Io0EA$!Z55HZ_`f|N6SMH3Qbxp<32o`i46WpYe=$4nCdkDU`J`t5NUhGqxmuqhf|ByLI zU$foH4D>kRQSE2mnP)6X{bpO?xz@7$c{eLU zphs9D?cr8U|Mu728$w?%lo^#b(?jMqLpHN zVy?Wrtbk1Ql21p$G~|OlT|s~R4t!*Xv<{Bak*;)(^UMJt(m-h+ z`>Rr#YKfvc5q+tlXfhTs^&xs=K{j}_9~Oy4`_Rv}U=0C)O9AJMqN40L+C6lU*?2@Av+ z_<)U#K!!9JTL6!xqCqr#5P<@t!NGs)!r1*^(-1J|ZwNII4*pM4C_6`xIgyM7>8R_f zVW8TYAUy+hsIG>ArnV|bQv<38(a?iHwbV4AFb!RpmI3IW3(Ss2_VI-wEv){D#U8=I z{!}Un27!czhN_2ZsT0Y55U7EH0YpO+qN%CIMyOHf1S*=QMxZGERaMnfAjr6 zg(=Q-5*C8QQi#E14Ex}G6@P^y!OY26G?hqpCK7{wSJBa*NF`GIi6jvF58{v;j^INK zr5yenZf6IxAyBAj0tRbi0SB`M)Nwc;n2xrEnHIaeW_nOlDAdx-)C_8BV5z5VYOblP zqoJ+$n`=SD1mm#;>Tj;kf4Ta9k9tbL$504M+iA}n@Iu|a^1rM*R&nOD^R E0BFES!TdSQr#iT4Nm<}!zq}(lg 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 Kv@WysIr~3bh)e$f literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/InfraredLearnShort_128x31.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/InfraredLearnShort_128x31.png new file mode 100644 index 0000000000000000000000000000000000000000..783ad0877c4281ffc9373ab39c2db754eae3083f GIT binary patch literal 3952 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/KeyBackspaceSelected_16x9.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/KeyBackspaceSelected_16x9.png new file mode 100644 index 0000000000000000000000000000000000000000..7cc0759a8ca6acdb9b9c2e3dc00edde2f0e93a67 GIT binary patch literal 1812 zcmcIl&x_()N{W z-JN@vFI~T+Y1-v}FWiIo6?k5J;aT|qw)dv2CwcE-scA1=t)FMK&%d~)Y0rO}4EC%2 z=aK4R$F?2(hE6fX7H(UFBH{$t4v4EaKLer_Vi@d&Z#A)C)-lFal?RqJo6XEw%T&e4 zBEIiim|Bz~ut4QeR$2KDgeVQ)Gl9#&Q7)}LS*mHl<@TY>s++4|`B+t|9IGdATYvr+ zL&4Vp^Jy_zlt*w&PGkz$CD@V$zdYy`l2xi0C^cC%YIhY;r^KZCtp`aa)U15HX4E*y zkX5o{K-UPu6k#$T&@w-;?b`$g7%xpD(1BnTyO^;O$?)hRrco61v$A3tm;JC~04Xy` zM9{K5&YYn{cI-;z+O~({*abcDHnS;pNXu(4c!7VY__VG>?Z1?*P#iGU)eM+zGa?B_ zvgI?>CU%T`*JH?wZ6SP@IW~7zXzvsW>>M^Zjasu3fJoi8ARJ`vf+uoa+eOUrBobcB zw>cJ!4w<1pj@wleRYXcabz7&```zwtp@zu>K9qa+w)FmX*CD>+AZijr7d#lMB4r@7 zBxNIM<=Lo~JFR)Z8qvz(k!=8Gk?gq@8g zfS#k0rCF(l)r=K#a|A8Qr4h!%R?w1c= z{pq*skHW8}pZxgsP>68$^3NZ9>0PQ& Cw>kg- literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/KeyBackspace_16x9.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/KeyBackspace_16x9.png new file mode 100644 index 0000000000000000000000000000000000000000..9946232d953ef1cbfbf0e6754be6645e5ea2747b GIT binary patch literal 1829 zcmcIl&u`pB6gEEvMG+BPN`-{wNT>+Lo*8@XwOcpZ?1t{5I;81J4Y!WR<6SFjkFlNX zCgRjnK|!3jpo$Y0E}Xb=;LeTzpnm{T)f-4i;dy_hpfu#tmAsxAzxTcGz4y(`m)l!6 zS1w(-q$tWtuiM#y_bNQEzxE>h|J=PM>Pg=HtW=aY-mae)lh*~S0I8^$I!Q-a=}mlXitE9+UN$s!YEtd_TB{DI?graxTNXmKb&NR1RCQdP z*p_AEk5q~&HgLlr6cO9QmPZ_Q{?i~@5yjq4=i_-SnEBeUs&daT#^bR*Hg#DH4C1=3 zfvG_$0t-|gW)+*DtXx|lbVSLEB(D;gsWl=C<$mRBz;u>EnlE9qa$Y7Vm@#3wL3CWF zv@i^U^G(xqX_e|ijf0zqnN0f5E;9~PYWYyXtSU!}MEQj(L+?JpJ#W3Q_ zfcbtgnwBTxh8T$yuuHHdQ+~PEE(EJ&(U)?xXw>#1qDqNQ)vI@tERy5$gPPIYL3CIp zd=0ur5T*!|K7p3G9x*>8*u!{c8h{QWRntB?yEl08lWCYa({L}SbyS-h=I2pl*a_8oT+S_c~#IXiq#zs}!z^4spCcOR_0+*o_q`N6;X{rjK1`QsBs`Gcx|z4v#k QTVG_o&8^N)8~5)21Ktij=l}o! literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/KeySaveSelected_24x11.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/KeySaveSelected_24x11.png new file mode 100644 index 0000000000000000000000000000000000000000..eeb3569d3accc5a5c56829b12c85079172b56729 GIT binary patch literal 1853 zcmcIlPiW*+7#}^zw%YZuf+B)3d$6*;fxiXAXK-X$#&ks`?Z1FR>QX z26aVbT~%`&N5w=X1OWo&yGcQZD9KMx7+O3JvM4Pgkw_&Y^~HA4kU?pcLYz)%lYCqz zD405=sj4ZsOlbo2yrZFUJVocl(hfu!>phe>@9d^rUFW&j&H}!)!;|9lBv{%Lg~)s2 z4%()#|Dlit(}3xA)*qFJ1uF0J7`Su5Y9oEA+srsEMAi|aKWWt3B%(w#g-G)oQNqL^ zf1*@0Ucg(l;0+nNrXfra);gN*63r#X84bG_S5Oapz-U2_2No;}caH=0Jhz?X1x*6p zZZ%{Or9=^P?a(oNj2+}NPLO5lb>xS(hK#yzQ(Fto(z;~|u)ZaN?XnW(`pULU1i&$^ zrW-ON3~kFtm|7MJL)}ES1tUU3N-T@l>$)*vdoGLM%c1>)tfeXjj8tQ`U&jXGx~+pC zJw&zve}0HDBg6^Jz?Y@lahswqGEXq5ZvEhVyV+dJL>TqqMZUhgD7BZGrskL?B8nzU zEO0}S#T1Md#k9-SH0hSMuhLzKa_I5y_(QtDUmB14ku-9rOM~*GXvjh71`cJarlUj3 ze7uCJ^@AP<(j#0_!EzB61Df%LF0|x7U8vqkd`@?cmVP{k{EyPdWes{X>2la%Rk=(? zE%&0TDeAxbb=w#db1i`F%Wmf5GAz>Wv>@jW_p)ho-#0CeC9cGbyZ*s9Cn^o)Rq=_$h#NIZix%+wt GFa8a7)lmol literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/KeySave_24x11.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/KeySave_24x11.png new file mode 100644 index 0000000000000000000000000000000000000000..e7dba987a04dad7dd96001913c55566dbde96c8e GIT binary patch literal 1863 zcmcIlO^6&t6dpxnjjSF75f9pQJZy|LUDdzSZ6$n-*6-2D5s-9_fx~uK( zotfQBVDX?Q(UXLzXF6aX)%U*l z-d9y`w^q+Do_PF3p-@5qOL5h2N9RU z^i-~BIziNECdw*wjUcQeOxncsbnKa>(*%1MPoPck0jC)~9$50g-#!ks+4LGwn$d`f zMy;%ZsA3Rsk2!`#ELuW>2#g3fF>;CFBHMCo-El0(@X1&g%&$qdl~*F4Kd~*B3^?Z1 z^bEmDf}0)Wn??sYC6l9$X;6esLO7#_ZCmDy?ZqU3l|%anS#wn!7%f39-Qp(l9fyJ- z(?=x}n~2%2PcX9#VmYdECvH{tWzv)!s%sn^Z&a(TMEXG=KBQ~smzBm!)h4cOBfSV| zapw6l2`LyY2x(Vnan#Li4>BO#dXPeox2Fr~f_P*4)DM)gJ3Y$sMNw8+?gqit>2PpJ znU9yygm%~yKzf8rCa_fc*^nlp(uJ1%rwg^aiBIX^Xz9mu$p0vPT2|JhQCGkYtEqW1 zTD})enxg%?Uw4c#Ggk#{pLa8zmSLH8=LI=?xR>pc=yYsHAgcQUxz^arx`9fR>e$sw zj@}Uy75!kQXF{tT9e=F+z^*!*3|n>nI6oucWq!(t2og`=40-O!tAE1z^ID@;X)nEd zVK7xqj`wg%Ed2Op{k=a*YZpKHX787$ zzhKuN9(?M5ojmn%xcU1}OP>$^`ZD?cW@lIaTn=x3xBtP#z16o~{qVMZ>hecsD?jQQ ME3387mS5lf8`39Il>h($ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Keychain_39x36.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Keychain_39x36.png new file mode 100644 index 0000000000000000000000000000000000000000..d15850b5b7f70672f90ff6c67a3e12341071fc61 GIT binary patch literal 3775 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Lock_7x8.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Lock_7x8.png new file mode 100644 index 0000000000000000000000000000000000000000..f7c9ca2c702f1b93d7d06bd12ae708655c79d7c8 GIT binary patch literal 3597 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 a9|QyVQ~@!E@+ey_4zMz}H7hmoyzn0`d`!~- literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Lock_8x8.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Lock_8x8.png new file mode 100644 index 0000000000000000000000000000000000000000..01fb0eb6bf7506d19f5c6e039df0ef0d3272e424 GIT binary patch literal 303 zcmeAS@N?(olHy`uVBq!ia0vp^93afZ3?z3ZhDiV^mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5l;8~T332`ZAIM?=k_T^V zeFCx=OM?7@862M7NCR<_yxm zF*LUVA`?Sx0|P4qgWh8dPf;}F=BH$)Rbpx|Hi2kZk~Z%-Py>UftDnm{r-UW|;$Ka1 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/MHz_25x11.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/MHz_25x11.png new file mode 100644 index 0000000000000000000000000000000000000000..b9955495667452b611dc2934fbd53a5271d140be GIT binary patch literal 1660 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Modern_reader_18x34.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Modern_reader_18x34.png new file mode 100644 index 0000000000000000000000000000000000000000..b19c0f30c9f3928d3129acc9da92d5a9e962d084 GIT binary patch literal 3670 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Move_flipper_26x39.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Move_flipper_26x39.png new file mode 100644 index 0000000000000000000000000000000000000000..ff4af9ff05989e5ff04d3888971b7f7801c59ed4 GIT binary patch literal 3698 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Mute_hvr_25x27.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Mute_hvr_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..155bd900438c969a4703694eb743a321ba4c8aa4 GIT binary patch literal 3657 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 YaFqjKH6{atc#Z%YOM8nVbI%L^0xlYDPyhe` literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/NFC_manual_60x50.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/NFC_manual_60x50.png new file mode 100644 index 0000000000000000000000000000000000000000..787c0bcfe01755f4dcadcdce004a1a0fcfb06f41 GIT binary patch literal 3804 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 IrsqTc1+$%)k^lez literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Nfc_10px.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Nfc_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..6bc027111a7517a8cd53bb511c064b834027c5a9 GIT binary patch literal 304 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xkYHHq`AGmsv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpafHrx4R1i<>&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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Off_25x27.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Off_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..c15100606ac9b2c46fec8d5ed290d72345fb22e2 GIT binary patch literal 9530 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 T&A>rCE`gSso@%+Wb;y4K-_9ky literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Off_hvr_25x27.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Off_hvr_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..d5e5e6f45d78e070d06e033bd529d0067de94301 GIT binary patch literal 8460 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Ok_btn_9x9.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Ok_btn_9x9.png new file mode 100644 index 0000000000000000000000000000000000000000..9a1539da2049f12f7b25f96b11a9c40cd8227302 GIT binary patch literal 3605 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Percent_10x14.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Percent_10x14.png new file mode 100644 index 0000000000000000000000000000000000000000..677911fd44de133b01a90321930f770c5d76a3a3 GIT binary patch literal 3624 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_arrow_down_7x9.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_arrow_down_7x9.png new file mode 100644 index 0000000000000000000000000000000000000000..9687397afa81c92fb727bd40542830392fabdccb GIT binary patch literal 3607 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 QX&eA7&1_6djNPvM5BL~PlmGw# literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_arrow_left_9x7.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_arrow_left_9x7.png new file mode 100644 index 0000000000000000000000000000000000000000..fb4ded78fde8d1bf4f053ba0b353e7acf14f031a GIT binary patch literal 3603 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_arrow_up_7x9.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_arrow_up_7x9.png new file mode 100644 index 0000000000000000000000000000000000000000..a91a6fd5e99a72112e28865cd8a004c7d1933fff GIT binary patch literal 3603 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 TFC+3}9cE|kU{!4CefEC<&8td2 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_back_full_40x8.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_back_full_40x8.png new file mode 100644 index 0000000000000000000000000000000000000000..cd1301512db1c06700fec26d03231c63b9be75d3 GIT binary patch literal 3641 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 Cv0zgG literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_pointer_5x3.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Pin_pointer_5x3.png new file mode 100644 index 0000000000000000000000000000000000000000..edf3d41bb59c5defdb613ef66b07de069277a524 GIT binary patch literal 3592 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 LwKgd=cDwXHDN#*w literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Power_25x27.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Power_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..5ae493fbedf1af1b65a5b852f90b7c573e9fab0f GIT binary patch literal 3669 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 XT$mAK7+<@!3WGwj`RwPpe literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/RFIDDolphinReceive_97x61.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/RFIDDolphinReceive_97x61.png new file mode 100644 index 0000000000000000000000000000000000000000..e1f5f9f8017b49ab1ea78a9394ed8ea7684e3083 GIT binary patch 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_ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/RFIDDolphinSend_97x61.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/RFIDDolphinSend_97x61.png new file mode 100644 index 0000000000000000000000000000000000000000..380a970d9004cba5520560fd9aa24aa42924e2a1 GIT binary patch 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@~ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/RFIDDolphinSuccess_108x57.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/RFIDDolphinSuccess_108x57.png new file mode 100644 index 0000000000000000000000000000000000000000..34199910945376f054daa0c1738d7e64dc410421 GIT binary patch literal 2681 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Restoring_38x32.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Restoring_38x32.png new file mode 100644 index 0000000000000000000000000000000000000000..9e058869f103361416a78a8a8ba614fe12cbfbb5 GIT binary patch literal 3794 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/SDcardFail_11x8.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/SDcardFail_11x8.png new file mode 100644 index 0000000000000000000000000000000000000000..876cfa2290d5ad202938fffad0b6661d85840d2e GIT binary patch literal 81 zcmeAS@N?(olHy`uVBq!ia0vp^+(6912qYNToh?*>l!T{?V+hCf*?y}vd$@?2>=5<54!*W literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/SDcardMounted_11x8.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/SDcardMounted_11x8.png new file mode 100644 index 0000000000000000000000000000000000000000..68bc619216b65e89a8f97d2269c134163c2119f0 GIT binary patch literal 74 zcmeAS@N?(olHy`uVBq!ia0vp^+(6912qYNToh?*>l%S`JV+hCf)>*yJ)S*p|h?~Q6$-f1d>2NNH}5%Lt|z{KrzQc(y-YyStJQ+g^C9Q zSWv-YttjHfh@wyt@GLFhMTjB}M;LSv6%;{^;@J%X_DAW??0&~Q&+|U-`@P@n?x@Hx zJ8Nfa0)b%14d?LjF%^HQmS*_Zy;Prz4^CJ}G`0p!z*2-Nm=GjEMKHicgo!X87D}`~ zG{XJ_!fZF0AR3G2MKHxELKK=XL=B?E*#v@rphhVa%V7)_o@3{?OoMWF~y##kV3^-~Ura#~iQo~#pIF_K28B$0`bDW@qQkN5vj1er#wF+Tj+ z?|%xb1zIIc;=^h*StZ6#E@7!Dl#l0+R;G}k zDeC1D1RjscRj4tcLJV^`ED)C<%48Czw=bJb<4}SjatMt~4q?;jbe~|z8=_EsXfzI; zGR5Vf;$#F?U{hSlXD)k2uBjOiB_5drt7MyCNvH}%fQg)$vYEXwX4ISHN@n&FG$WUU zn<1G__FpGGwS~8jX*%7w_+q;CVFljrD!j4V;}c)t_r;dW2@+`9`eU1O>Hy1H=Z_x? z#)vXQ4`HsunYK6jxY4-M*|zlR`rg;$+V*St8!R`}`J(H(M(Fn4S4n;$pnW-UN$QA` z?fY?KM*pGHedF?8-QC`CtG>sHp2-iZetB?^`cj>4f5g#9o;N06J$3^rWaoX6Zp!iN6AS8ml(v%micb;q2O2KuEfM&;;GfOLnbEbQ;Xh2MB~uUb$O z=Tf34Z;Mngv^s8}xvK?|Q)X5xaeMf&yLz=D);7(;s_;xKaAkeDy_0K?%Yn2|k9C6T z^kdg4x7}!2l%F~e-2N&yKK{I*<bm{PN1M%~EqIS+ z#{g%nih7mt;>v=&E{mA(e4W(c;<>|5`bM6gWBHY@vRSt9LE+^Uhns6zS!2UzZw(cU zoUfWE)n;PLGTwze=xNtR#E5s54 z?u4@P3{ljfm#4cr?==i}&Q~nx+6o_SALMl>7g+8+b*EGr+g0b>QusCdoqSG@XTkT} zJKW>*p7M7!ScsC+I$SWe`PeH**g7LKd+2^e4BT{9(i5Fx*_t#~^L&3q*^<`Bg8SLL zJr^&8Wvz+nlWyNPFyz7qEt>zJmbmY7f19~I|Kz}R|I(kU_SSdG*|X+`TiP_=YR)O9 z%>w2`t#*GaxqGd${KiVYrAK$bi$_|DyT^Fr>F$>+;8w9Tw&Z$d+!FWSfdT)vdK%bz zZxc14Zjp1X%kW^EaVRy?Y1r_3XHB46)J>z~?!08J+0&8}hNJx?^62efuWTu{t@zFL zVZ4jin2pbcGJ}2f!HjR`wC}%p=#A$7DVOR4RjdwPz~ZWrAMHE3V&KiltB9(rl{Yu) zpLzA}yq2xqYW6IxKLj-^F^5Q^3s;lX5 N!3~Mzlm%~0{|8*@s)qmo literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/SmallArrowDown_3x5.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/SmallArrowDown_3x5.png new file mode 100644 index 0000000000000000000000000000000000000000..1912e5d246268d75a20984bdc8b996d503f3d166 GIT binary patch literal 3592 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 BDRuw= literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/SmallArrowDown_4x7.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/SmallArrowDown_4x7.png new file mode 100644 index 0000000000000000000000000000000000000000..5c5252b167d2f9f9a1ce5e7b9f9c99123879c1b4 GIT binary patch literal 8340 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Smile_18x18.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Smile_18x18.png new file mode 100644 index 0000000000000000000000000000000000000000..d2aae0dc37f4fd3453e3254e4a9cd33e753019b9 GIT binary patch literal 1080 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Tap_reader_36x38.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Tap_reader_36x38.png new file mode 100644 index 0000000000000000000000000000000000000000..4e0ba8f05921ccbfbaa4390ad07e98fd454df00a GIT binary patch literal 3748 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Unlock_7x8.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Unlock_7x8.png new file mode 100644 index 0000000000000000000000000000000000000000..9d82b4daf3c722a5244f537f18b147833c2fb4ee GIT binary patch literal 3598 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 MrJY5ondim-0h+K&wEzGB literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Unplug_bg_bottom_128x10.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Unplug_bg_bottom_128x10.png new file mode 100644 index 0000000000000000000000000000000000000000..35d73ba76ea10724f02119ac7c7413c6ec7d6d3f GIT binary patch literal 5355 zcmeHKc~lcu7mtVn0nv(}RVp#iD%HuJkPL)HK#3X%i!3VWWHJdMD@ib66O0>+h>BVf z5L8qU3M!y1qV_|<6^pyLp;8wV#08humTwYV@U-WA$8)~^XU>`A&0T))-ru|LzPxmv z|I88C@mLH7GlJvi6NLVzq7T-5IQpGr8ybhfn06`%;K>r=54XZr4WH9YZMGWU71>&*+nu8nyi+sUR&&B)^ZK2foU zl6Q8~thtiLn$A_nJ;I`} z6rSL5JlW&$!{6Ezg=5$@C-4ZdEA7Y6jVY};u;)@t*jLW70nUr7fkoaT5v}ilQ&ys$cxLF?%V?j5acfjUzR8I#-?9BFqD2uUK~HMH}aa z&99gC(eoqi`-*Q54yBg#TV2Zy~7HOOFCHJ$J4j0n>oZPsMw@% zZ}zUcu)oxaQKQgHI>=yZy{XBpQA2X?=7gSb}8IQc5cey&_v)JU#y$&qVI^e)$J70JDHvIKu$J~8(09GFep1%gW z(w$nK72ZiM+&z7JetFw7*A8upxiUNZfs0u<@K_iVFVNB{!jyV4_}I=K99i+SuXbW=5f5eKQunH-Q_2*WBWCE+8n5( zEHjNMDDk)R@wKnP`j(7}SrPi(9KxUaA4YI8GIw;$Q})99x;pNbmn|#9nJ-CYf-L8H zzx4juSb*=w>}hF8%x=)8@`%*4UE|DXHyOd{wVO{?WJFe)Lzv{WNmHn&H|G>PCAC~( znO3RZi{Suldn5dY&qIP75VHRW07`3ZLM50QwIuHerAsPs$lS$=jP{+m_aY1x!5EJn@ zqlres#)orxIB$gt!O;jb0txWdi5FAw?pU0gN+1M-d}h3dK;PK-XpKe*5{X)^mY}5) z6eTw_9 zlPS5}kMMH!dlpbWh&o6~BojzPnT$BtL#^>$jDoxm=pQ}QA?SHd3_{e3I2DZeE=J@U z$H5Q+_@lovP9-&_BY=sB6p^8(YIIieXH(APaCsj+3>1jOGNsWACHpf=jac}Jtj}UI zXpHF$4g_`oi2IrKhun?Es1=tB`Y7NyLwFn?Hr_BlC{Vy+0cadTLOzv2MQ8xTr|7BUfu6IgA*fP;i16#X$rV7G1~?0tku$(3nCxz#<9A z0H4I5@kw-s3xx~~f(THF(W-=`gQGG)2~a2si%O@!LIwaagj9egAn^efnMDC$ghh3M zUcy?7ipo-a(*#!a^OcEWS@gWAl=aXT8BA^R}Ofn1$Tn4J? zBf454)Mz0U;w3_PM7cuC)5sNWigBTwKaWKljTlw|B@7@jfxi<*e4jAU&@(<{>_+?> zCvHZAK}`nr8<3&R3+;u(kInEsXK1|t=I8xd{F_tYa9=0+B7VQp^_8wKV&IF6zgE{* zy1s~kFEajGUH><_u%E6|h#dVFq(v`F?Ryu+q8F{<{Mj>oj8`tqTknPxbY!9Qi%?@Q zmNtfG2xd$EI8x<`S?WZWr_iqttv6Yg$&cd4(I zGg~J*H#IwP$FfzI1I&{q>hC?}>v?~e;f5-yLH|iSALd>;oc*e{=<= G^#294V-(;3 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Unplug_bg_top_128x14.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Unplug_bg_top_128x14.png new file mode 100644 index 0000000000000000000000000000000000000000..bafa2c4947082eff8f59d48d119e9ca01ece9729 GIT binary patch literal 5945 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Up_hvr_25x27.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Up_hvr_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..cf71e59655a8b2a480f3809cdc10853d3bb62b78 GIT binary patch literal 3630 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/UsbTree_48x22.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/UsbTree_48x22.png new file mode 100644 index 0000000000000000000000000000000000000000..cc41b5b9a915f5fbc0bc7ddf3803c130a8b9dcca GIT binary patch literal 3653 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Vol_down_hvr_25x27.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Vol_down_hvr_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..c556a037af9fe0cb97f337404326aab7cdf0bfbe GIT binary patch literal 3611 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Vol_up_hvr_25x27.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Vol_up_hvr_25x27.png new file mode 100644 index 0000000000000000000000000000000000000000..90c2df47d250c730774ba289f3a8175cb39479a0 GIT binary patch literal 3617 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Volup_8x6.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Volup_8x6.png new file mode 100644 index 0000000000000000000000000000000000000000..4b7ec66d65178e808c672576150f5773b04c31a4 GIT binary patch literal 3595 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 XX6*+%8gHC`h)Tl}u@-r>vFqE{F~5F& literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Warning_30x23.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/Warning_30x23.png new file mode 100644 index 0000000000000000000000000000000000000000..5f7e02dd857e172635a87dd5a1493609d8b95c3d GIT binary patch literal 347 zcmeAS@N?(olHy`uVBq!ia0vp^azHH32qYLxTn-%vQY`6?zK#qG8~eHcB(ehe3dtTp zz6=aiY77hwEes65fIU-u|8QZ1q1V3bmoi89ep|OVeVylC|H+AqrXO_` za@X$aW$-@D&A#aKgSs<^wA?1|{?Pz5S+&G9q9i4;B-JXpC>2OC7#SED>Ka(+8XATe wnpqiGSQ(jX8yHv_7)(lGI*FnoH$NpatrE9}$CkTFff^V*UHx3vIVCg!01Vw{tN;K2 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/_FaceNormal_29x14.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/_FaceNormal_29x14.png new file mode 100644 index 0000000000000000000000000000000000000000..52d78c08698f3cb1c70d1b39d44f950664c1b6c6 GIT binary patch literal 295 zcmeAS@N?(olHy`uVBq!ia0vp^vOvto2qYMOuhNNn{1`6_P!I zd>I(3)EF2VS{N990fib~Fff!FFfhDIU|_JC!N4G1FlSew4N!t9$=lt9f$?sa@Dd=8 zy~NYkmHjER5QhrG39(Xdppd?&i(?4K_2eJ_|NrN2JN*B@r@@wg{}&&;@Z&!}yAb0v z2JJ?H_um%_+<)D8r2oG?!(RbCK3(x2*+8wTC9V-ADTyViR>?)FK#IZ0z{pV7z*yJN yBE-PL%GlJ(#8lhBz{nC}Q!>*kacelY!8{JAfx*+&&t;ucLK6VES60IS literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/back_10px.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/back_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..f9c615a99e69c0100b03a9ae7b2df903da4ecd66 GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xGmzZ=C-xtZVk{1FcVbv~PUa<$!;&U>c zv7h@-A}f&37T^=&`v3obAT#vPO>_%)r1c48n{Iv*t(u1!X;5977~7Co?ed rv9U?Av01aVRT(gMJdt+jXk=uN>R^g!*w%ImsF1AxEX>4Tx04R}tkv&MmKpe$i(`rSk4t5Z6$WWau6cusQDionYs1;guFuC*#nlvOW zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yan9G%FATG`(u3 z5^*t;T@{0`5D-8=V(6BcWz0!Z5}xDh9zMR_MR}I@xj#prnzI<-6NzV;VOEJZh^IHJ z2Iqa^Fe}O`@j3ChNf#u3C`-Nm{=@yu+qV-Xlle$#1U1~DPPFA zta9Gstd(o5bx;1nP)=W2<~q$0B(R7jND!f*h7!uCB1)@HiiH&I$36VRj$a~|Laq`R zITlcX2HEk0|H1EWt^DMKn-q!zT`#u%F$x5Cfo9#dzmILZc>?&Kfh)c3uQY&}Ptxmc zEph}5Yy%h9ZB5w&E_Z;TCqp)6NAlAY@_FF>jJ_!g4Bi60Yi@6?eVjf3Y3eF@0~{Oz zV+G1y_jq?tXK(+WY4!I5C=YUpXXIhH00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^lu`HWXkp{t5s906j@WK~xyijZi@f05Awj>HlAL zr$MwDdI>{Qf+U53tOUR#xOeyy)jcQo#JNRv)7r6DVVK|+*(cmT+R+EbO(O#X#REG4 O0000=T3-0%kIwEBzxs9jH>Z#5JNMC9x#cD!C{XNHG{0 z7#ZpsnCcpuh8P-I8ChDHnra&uSQ!}1Hm=h^(U6;;l9^VCslmhoqQPBw`6-|V22WQ% Jmvv4FO#mLQPFnx~ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/iButtonDolphinVerySuccess_108x52.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/iButtonDolphinVerySuccess_108x52.png new file mode 100644 index 0000000000000000000000000000000000000000..2b4bec7c6f14f53e7362da75f95b83bf387eee54 GIT binary patch literal 2157 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 Qy~)7f>FVdQ&MBb@0C$~I0{{R3 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ir_10px.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/ir_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..22c986180a2bed76dbe4ff439df1cf9177533c32 GIT binary patch literal 305 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xkYHHq`AGmsv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpafHrx4R1i<>&pI=m5)bWC*+s&X`qmbr;B3<$Ms~3f`-KX%+5*7 zhxan`%;z`w!#>%c-@wM^z<~n{3>VXQv+hhNs0FH5Epd$~Nl7e8wMs5Z1yT$~21bUu z2Bx}(CLxAKR>lTa#unNJ237_J>nn=CplHa=PsvQHglaGb>IpG01*)?$HiBr_e$xf$ PHwFezS3j3^P6 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_bad1_46x49.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_bad1_46x49.png new file mode 100644 index 0000000000000000000000000000000000000000..9b0e7c74ef20cfdf8b046d7597bd857ff786e56d GIT binary patch literal 1237 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_bottom_128x18.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_bottom_128x18.png new file mode 100644 index 0000000000000000000000000000000000000000..691ed8b4ad994daeacf0ac0d3966affc2a30fce7 GIT binary patch literal 1149 zcmaJ=PiP!f7@ss!N@y;g+S0;f0-}&N^XA{q&X6@GJG*wFo2Hu;bLgRO-n>bs$^3EV z#oYu=q822Iw1@U0cqr|mrO-d8f<4r>f)olZ6-4Vnu@y0*f*$mg_$Hf;J%kL*eD8hp z{l4$_{aYCyd%eH!K%XE8{k6kRgUe<9zPP8Ce=m-`bc2iitTM?aVxP5eN`(EK}^Fc zAeVIgY=<`;O|5DLMK6wyC`zSV)Qzg6jhJOat5&M&Xct?HGKM2UyRicvdlQRx#M(IG*i}!T5B{;%qujfT~Fdyj;g5h;q#in2(&EEfTmZVJ}T;}=JWJBc<;ILb>@_7cp6EUjZGBOHwvTxu|j>QSh@y_ zE};;c$SC@T>FF90WlmAfC+E3I>ZTWl0n7@o3$UJ?Q+4_XB?PI-XR*}2c`OuAyb(`{GTw%Km&hNQ*0oN34HT$q{C zZ6Q8TQ^1fkv059z0vhqf*nm-M)D$&qFfnR0)`Utz;zQ8{1>vC}F{@a{rYiZhC@mK|dAe$4-atf|t_)=vd_NP9j)I2c94*x7`zGVrY;#IP&rQ3aTU-4&N8Bg zD;&w;oUU=2z==GmYDGKi;W=L91*U;!BMtQw)fkJgTwG@Ag&4=g8{>3C5u336K(RGY z^ld`lt61uxSSjWKC2+j7N!wabnwk_vyvVjgzCV{_?}o(;wDa zlZQTir*r$psSP*X>iJU_zweoT?c<+zz4>qD^{bTQRNT6@=jPUuIiq#zcnzPbyfb_} z^yS~u`T4HJ#L}Z@k9CM!4t7@kzWec+*{)k3{Bxl^^KCm@_f>x6*Zd!Ul}`R#``rot zvzGCA$KfNUf4ckRm5J`Wxnu5j^X!u&$>B$uYitx%6rNHagjluO2sA~8L5mM&=dm-pJCklnyW7Xw?z-8ow1|+-+_|%zwDWLg z*4=JQ4T2E_{h_2)G0`ZMkTi{u5Qw0Lw#J|dQHh8c!L(6Iq@h|9+oV|Uw%y7P!Xz{I z-gD1)&Uaq3Cmw4kSy8?M!?2P_V>p3U4|IFeIR98utqxMUo{T%Nuc)W*Lg+D25|xTJ#Dc$Ki_)f!x`O zDkj49i_Xv~NOZWaB~nx-lksG{9@9=yj35XU%~C8&A`Q~%He4x78qWHHg)nr0ty!*S z8hGBKB%5hBNFb^UG3Zt_x@6dJ7Bhu%Mr9?7VmvgZ>-oUuwH-GB|EFWHw{0D zm3rIM@%c21+AS#f6e!CaDz?C?EXi>^AO%6;Nx$NQDjnchuZqH7z$-VUZ=p|-1chN0 z*oc7ftGo~RNQr?e$q1a649EbIlAq=SD(_b~FHKO0B9-r)n>wi=LhYH~E)51cER7a4 z&^*~_aK^uDI){etu6T2@Zfd*YjtfxXp%eGRQg&lXYD z>C^k^p0%q=)2sVF6f4_;?|fQ5nD}e+WMi(s`rs$KPR)#LId=cV_R~+^*cMxxJJdgV zw0&8_+g)6A`PQ$~Hy$Y)&plLe;h6CKop*03e)#I^J9|&;h*gA2hyRHmn118qjZ-DT zYs5z{4S%Iqzp~Og+&k7g_(c1f%Bs?t%uxEZ{r1o=vmcyD_N6DLe{8kRrvkelywvq; z`Q^g{dk0@NX5Y;``_suk`^t}iYXe6{)aRPFZu@fLk9C(o@0F3?Ce_;EL2>Mdvm3V0 z_HUjky{>&ex-K?+CR4f6soHSh^7(%sEv3pv->1q>-LVRrpo*u*!||g0KP*xg3lG+| Gzx*E~RoOxS literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_happy3_46x49.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_happy3_46x49.png new file mode 100644 index 0000000000000000000000000000000000000000..7aef17674336e71cb1cdf323c1fb039e0e627d33 GIT binary patch literal 1348 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 MT&7n)()IlKe@XVQIsgCw literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_okay2_46x49.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_okay2_46x49.png new file mode 100644 index 0000000000000000000000000000000000000000..34fd3767b92bc334f15e4e13811020c1e0211078 GIT binary patch literal 1281 zcmaJ>eP|nH7{9gXN~Cj8-Povj-o(x6YJvi`=jjO?tS0q zeSXjLd%kXOXGd$jZ>*tz1;sM_Qd!4eFl>lMknpC0Ehz)QLuJsfn-T2l$x|4r zs}byJHc2M!D9Gwv^_75cz!GpAYygr=OsBo+n6}plKXx;O?;LNd??=*HtZuz*QXG_H@fc z%N8Zs8uB6-q*{r=u#?F}!=}5CDVQ^&AlU@vCkewS2R5(mdMWTfjU~0+^so(x6mYE} zM}Y;=)>XkUd3SbHR)lPXryLztMaqemGGqYLONbE+-uP8r6*LmaEGw(H3}_B#0=$At zEXm@ms;~;j@5raV{)DohoSTw}2aWT-$McF_+7N=XP*o5hNlBs~I zZyowxz_NG53Q-40p5>%1D_3oU&aCBGZq~9;ARjzSX5S z@A;>FOUxLP5U06J+c1lS4&rqjjy=>tKRJ^ds_R>{c8{$}HYhrX*>`{7SxW0ObGYd=rz{>|;) zcDd&GWRr6A;8aunL+7upZ+znLY-x|L5bAlUr}giN1Mc~myY_rmr*V6W_KxGvY}@kA zrz^ML*p=RQVps7>VtDoM@An>K4i85A-!0{Cta)91@|#yO%V&g!>02KZH?Da5R9nNw zM=qSXxay1X?wu!p9KG=E>G9bk|C)onm&TrzuNNN}x&Gpx4SmR=iQ4_OTeDx5e@cm1 KhdAESxAQ++sKGP< literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_okay3_46x49.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/passport_okay3_46x49.png new file mode 100644 index 0000000000000000000000000000000000000000..e65da5b0e586ab706b40263b637f0fd3647ac5d6 GIT binary patch literal 1304 zcmaJ=eQ4Zd7*FY#?Xc({wr<5?O#hgI`A#mEaJRF)-1W}xYPsFqxo)2Mc+-pRC25j+ z*P{+~I(14dBFvRBN2hbJDTpFM)qUugbz-}TilX~M+(1Ul>R)5DzSs8Z{wND1@AE!+ ze$VrJzFzO@Y;Rc8yaqv#hGarc!;^q7T~`agZ(r^0fX6yNmi0H=hF?@%fVAqi3eaRh z=>ch==!5+eAcP>bFPoXHpG|F&G`m136&s>da3C5%LXncAXuZHkRnTKvVQhN*IEI>f z7~9IHsFV{0c{5RV!RB&jMl1JfqK-v2qM?!m9Tb4Cprt~eP5w%}KSaz#yI=z@vg z8^#t%Wm8>f)OGRp)0DQsp_LBLoqZ-aU{**6eY2u#Bu1-gTZjFZb)f4 zz7!1J!dTw-9f>51#UfE;3ES-;YGU z4KZ4(U|7662dWrCHqsNW3A>{7$+k970G6MW!x;QS=%y|i6i|6y)o~Rt0?x6bhATY9 zCt(kQeA6&js6BX*w1Sa(rB7TZJgk#$$1&t%^-rp08LMsKz#7 z>?JIBN30Zef#Tb4#lx?BI(#Kl}VE zr>*Xj7oPuOCYk$s)Y#tsK*%~np8RyS?!L1%zI<}}!MWYx!_m5O^Oebw6XCJ(_ObK- zTzE2ZDn{m<55rd*dxnMr?}ze}_QjcOWc_;&d9i~N9qGpsZ_J!4w`@NTS~`yv?;ke? zhv>V?2d>v2-`~IQ&nd6F)duN|MblK>4PVZ`*vyPb!yT5yrS%35K zA7@kco=YdXx2-A%Zb=_}`+d*RzhdRBuUsVFjp#>D|NZ4t)}y$rkd*-G80G55pQ2+n{ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/sub1_10px.png b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/assets/sub1_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..5a25fdf4ef1c6cf53634aa74675001a3e8c85b7b GIT binary patch literal 299 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xkYHHq`AGmsv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpafHrx4R1i<>&pI=m5)cB{fFDGZlI8yr;B3<$MxhJ?+;A4eL&#) z0Ra}bue?07WhLz78x$BO|L3mq-MMxdP^D^#YeY#(Vo9o1a#1RfVlXl=GSoFN)ipE; zF*LF=Hn1|b&^9ozGB8+QQTzo(LvDUbW?CgwgE3G~h=HkEX>4Tx04R}tkv&MmKpe$i(`rSk4t5Z6$WWau6cusQDionYs1;guFuC*#nlvOW zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_3;J6>}?mh0_0Yan9G%FATG`(u3 z5^*t;T@{0`5D-8=V(6BcWz0!Z5}xDh9zMR_MR}I@xj#prnzI<-6NzV;VOEJZh^IHJ z2Iqa^Fe}O`@j3ChNf#u3C`-Nm{=@yu+qV-Xlle$#1U1~DPPFA zta9Gstd(o5bx;1nP)=W2<~q$0B(R7jND!f*h7!uCB1)@HiiH&I$36VRj$a~|Laq`R zITlcX2HEk0|H1EWt^DMKn-q!zT`#u%F$x5Cfo9#dzmILZc>?&Kfh)c3uQY&}Ptxmc zEph}5Yy%h9ZB5w&E_Z;TCqp)6NAlAY@_FF>jJ_!g4Bi60Yi@6?eVjf3Y3eF@0~{Oz zV+G1y_jq?tXK(+WY4!I5C=YUpXXIhH00006VoOIv00000008+zyMF)x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^lu{1uVUoNs|Bo07OYdK~xyijgYww05Avx?TGzX zz7!EC4G1?heldU+2uZR%k^uSL+0?e2taR-}6`h2x#_2kxune}*>oEbW-V;;Yj|0n+kgYg_2gKP=oK5i+EYe1!{C9V-ADTyViR>?)FK#IZ0 zz{pV7z*N`JG{nHd%Gl7##6sJ^z{&U>c zv7h@-A}f&37T^=&`v3obAT#vPO>_%)r2R7=#&*=dVZs3d(!BIEF}EPF|6p ukWrBEqn^R#n}xxd;)EOgX$%+tGc!!f|i8+1xw6(SMoH=v0ZQIt?*4EI_P*70d<>l4c**SOaTn`VAzkmOl zo13SlrA0+W<>%*TW@g&i*&XIpr~?|#S>O>_%)r2R1cVurPy zctC-N<-p_?hZJ_1-}+aKO&-+hI@kz0JW^BKaQWoN`q~XEq;xBm#Q0qG@>{W1|Mj-b iAw6YtuK(RrS`#;$>9mph#iu~?7(8A5T-G@yGywokYFp+2 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/etch-a-sketch.c b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/etch-a-sketch.c new file mode 100644 index 000000000..ae8337da0 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/etch-a-sketch.c @@ -0,0 +1,271 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // Header-file for boolean data-type. +#include +#include + +#define WIDTH 64 +#define HEIGHT 32 + +const int brush_size = 2; + +typedef struct selected_position { + int x; + int y; +} selected_position; + +typedef struct { + selected_position selected; + bool board[64][32]; + bool isDrawing; + bool showWelcome; +} EtchData; + +// Sequence to indicate that drawing is enabled. +const NotificationSequence sequence_begin_draw = { + &message_display_backlight_on, + + // Vibrate to indicate that drawing is enabled. + &message_vibro_on, + &message_note_g5, + &message_delay_50, + &message_note_c6, + &message_delay_50, + &message_note_e5, + &message_vibro_off, + &message_sound_off, + NULL, +}; + +// sequence to indicate that drawing is disabled +const NotificationSequence sequence_end_draw = { + &message_red_0, + // Indicate that drawing is disabled. + &message_vibro_on, + &message_note_g5, + &message_delay_50, + &message_note_e5, + &message_delay_50, + &message_vibro_off, + &message_sound_off, + &message_do_not_reset, + NULL, +}; + +// Indicate that drawing is enabled. +const NotificationSequence sequence_draw_enabled = { + &message_red_255, + &message_do_not_reset, + NULL, +}; + +// Indicate that drawing is disabled. +const NotificationSequence sequence_draw_disabled = { + &message_red_0, + &message_do_not_reset, + NULL, +}; + +const NotificationSequence sequence_cleanup = { + &message_red_0, + &message_green_0, + &message_blue_0, + &message_sound_off, + &message_vibro_off, + NULL, +}; + +void etch_draw_callback(Canvas* canvas, void* ctx) { + const EtchData* etch_state = acquire_mutex((ValueMutex*)ctx, 25); + UNUSED(ctx); + + canvas_clear(canvas); + + // Show Welcome Message + if(etch_state->showWelcome) { + // Draw Etch A Sketch frame + canvas_draw_frame(canvas, 5, 3, 119, 55); // Border + canvas_draw_icon(canvas, 8, 50, &I_Ok_btn_pressed_13x13); // Left Knob + canvas_draw_icon(canvas, 107, 50, &I_Ok_btn_pressed_13x13); // Right Knob + + // Draw Etch A Sketch text banner + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 36, 15, "Etch A Sketch"); + + // Draw Etch A Sketch instructions "Hold Back to clear" + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 31, 26, "* Hold "); + canvas_draw_icon(canvas, 59, 18, &I_Pin_back_arrow_10x8); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 72, 26, "to clear"); + + // Draw Etch A Sketch instructions "Hold OK button to draw" + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 31, 37, "* Hold"); + canvas_draw_icon(canvas, 61, 30, &I_ButtonCenter_7x7); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 72, 37, "to draw"); + } + + canvas_set_color(canvas, ColorBlack); + //draw the canvas(64x32) on screen(144x64) using brush_size*brush_size tiles + for(int y = 0; y < 32; y++) { + for(int x = 0; x < 64; x++) { + if(etch_state->board[x][y]) { + canvas_draw_box(canvas, x * brush_size, y * brush_size, 2, 2); + } + } + } + + //draw cursor as a brush_size by brush_size black box + canvas_set_color(canvas, ColorBlack); + canvas_draw_box( + canvas, + etch_state->selected.x * brush_size, + etch_state->selected.y * brush_size, + brush_size, + brush_size); + + //release the mutex + release_mutex((ValueMutex*)ctx, etch_state); +} + +void etch_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + furi_message_queue_put(event_queue, input_event, FuriWaitForever); +} + +int32_t etch_a_sketch_app(void* p) { + UNUSED(p); + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + EtchData* etch_state = malloc(sizeof(EtchData)); + ValueMutex etch_state_mutex; + if(!init_mutex(&etch_state_mutex, etch_state, sizeof(EtchData))) { + FURI_LOG_E("etch", "cannot create mutex\r\n"); + free(etch_state); + return -1; + } + + // Configure view port + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, etch_draw_callback, &etch_state_mutex); + view_port_input_callback_set(view_port, etch_input_callback, event_queue); + + // Register view port in GUI + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + + InputEvent event; + + // Show Welcome Banner + etch_state->showWelcome = true; + + while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) { + //break out of the loop if the back key is pressed + if(event.key == InputKeyBack && event.type == InputTypeShort) { + break; + } + + // Clear + // TODO: Do animation of shaking board + if(event.key == InputKeyBack && event.type == InputTypeLong) { + etch_state->showWelcome = false; + etch_state->board[1][1] = true; + for(int y = 0; y < 32; y++) { + for(int x = 0; x < 64; x++) { + etch_state->board[x][y] = false; + } + } + view_port_update(view_port); + } + + // Keep LED on while drawing + if(etch_state->isDrawing) { + notification_message(notification, &sequence_draw_enabled); + } else { + notification_message(notification, &sequence_draw_disabled); + } + + // Single Dot Select + if(event.key == InputKeyOk && event.type == InputTypeShort) { + etch_state->board[etch_state->selected.x][etch_state->selected.y] = + !etch_state->board[etch_state->selected.x][etch_state->selected.y]; + } + + // Start Drawing + if(event.key == InputKeyOk && event.type == InputTypeLong) { + // notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_begin_draw); + notification_message(notification, &sequence_begin_draw); + + if(etch_state->isDrawing) { + // We're ending the drawing + notification_message(notification, &sequence_end_draw); + } + + etch_state->isDrawing = !etch_state->isDrawing; + etch_state->board[etch_state->selected.x][etch_state->selected.y] = true; + + view_port_update(view_port); + } + + //check the key pressed and change x and y accordingly + if(event.type == InputTypeShort || event.type == InputTypeRepeat || + event.type == InputTypeLong) { + switch(event.key) { + case InputKeyUp: + etch_state->selected.y -= 1; + break; + case InputKeyDown: + etch_state->selected.y += 1; + break; + case InputKeyLeft: + etch_state->selected.x -= 1; + break; + case InputKeyRight: + etch_state->selected.x += 1; + break; + default: + break; + } + + //check if cursor position is out of bounds and reset it to the closest position + if(etch_state->selected.x < 0) { + etch_state->selected.x = 0; + } + if(etch_state->selected.x > 61) { + etch_state->selected.x = 61; + } + if(etch_state->selected.y < 0) { + etch_state->selected.y = 0; + } + if(etch_state->selected.y > 31) { + etch_state->selected.y = 31; + } + if(etch_state->isDrawing == true) { + etch_state->board[etch_state->selected.x][etch_state->selected.y] = true; + } + view_port_update(view_port); + } + } + + notification_message(notification, &sequence_cleanup); + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + furi_message_queue_free(event_queue); + free(etch_state); + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_GUI); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/etch-a-sketch_icons.c b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/etch-a-sketch_icons.c new file mode 100644 index 000000000..94ddf376b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/etch-a-sketch/etch-a-sketch_icons.c @@ -0,0 +1,4324 @@ +#include "assets_icons.h" + +#include + +const uint8_t _I_Certification1_103x56_0[] = { + 0x01, 0x00, 0x97, 0x01, 0x9f, 0xff, 0xbe, 0x30, 0x38, 0x04, 0xf2, 0x01, 0xe0, 0x80, 0x82, 0x87, + 0xf9, 0x01, 0x06, 0x24, 0xfe, 0x01, 0xf8, 0x80, 0xfe, 0x21, 0xff, 0xf8, 0x3c, 0xff, 0x9c, 0x0c, + 0x1e, 0x00, 0x30, 0x7f, 0xc0, 0xc1, 0xe3, 0xc0, 0xe3, 0xd0, 0x7e, 0x75, 0xc4, 0x46, 0x30, 0x70, + 0xd9, 0x46, 0x3c, 0x10, 0x09, 0xc0, 0x30, 0xfe, 0x10, 0x1c, 0x04, 0x3c, 0x18, 0x37, 0x08, 0x05, + 0xc0, 0x18, 0x77, 0x88, 0x07, 0x00, 0x6e, 0x31, 0x89, 0x87, 0xe2, 0x00, 0x0c, 0x39, 0xc0, 0x30, + 0x49, 0x83, 0x18, 0x8c, 0x7f, 0xa0, 0x60, 0xc3, 0x2c, 0xa0, 0x30, 0x60, 0xe0, 0x01, 0x06, 0x14, + 0x70, 0x18, 0x26, 0x51, 0x8c, 0x43, 0x20, 0x70, 0x20, 0x64, 0xe3, 0x03, 0xa2, 0x74, 0x10, 0x62, + 0x5f, 0xce, 0xc3, 0x8f, 0x06, 0x78, 0x31, 0xc4, 0xc6, 0x33, 0xc2, 0x6f, 0x99, 0xf5, 0x03, 0x89, + 0xb7, 0xb0, 0x2d, 0x7d, 0x9f, 0x2e, 0x98, 0x8c, 0x0a, 0x86, 0x3c, 0x0c, 0x30, 0xb9, 0x7e, 0x20, + 0x30, 0x88, 0x07, 0xfe, 0x0e, 0x0c, 0x42, 0xda, 0x40, 0x3f, 0x80, 0x32, 0x00, 0x78, 0x03, 0xc0, + 0x0b, 0x0c, 0xe6, 0x14, 0xc4, 0x58, 0x34, 0x00, 0x40, 0xa7, 0xc8, 0x18, 0x46, 0xd1, 0xc1, 0x7f, + 0xe4, 0x00, 0x81, 0x3d, 0x08, 0x30, 0xc9, 0x63, 0x64, 0x80, 0x44, 0xc1, 0x03, 0xf8, 0x2a, 0x88, + 0x30, 0xa1, 0xc7, 0xd1, 0x02, 0x88, 0x20, 0x63, 0x88, 0x71, 0x06, 0x10, 0x10, 0x7e, 0x06, 0xf1, + 0x04, 0x14, 0x18, 0x18, 0xa3, 0x11, 0x81, 0x02, 0x06, 0x1c, 0x21, 0x11, 0x32, 0x58, 0x20, 0x02, + 0xf2, 0x83, 0xbc, 0x04, 0x80, 0x9a, 0x0c, 0x00, 0x64, 0x70, 0x1f, 0x39, 0xca, 0x44, 0xb9, 0xe5, + 0xa1, 0x90, 0x5f, 0x41, 0x85, 0x09, 0x99, 0x14, 0x4b, 0x8e, 0x6d, 0x19, 0x04, 0x88, 0x18, 0x3c, + 0x08, 0x28, 0x50, 0x40, 0x09, 0x40, 0x8a, 0x1c, 0x07, 0xc1, 0x02, 0xf4, 0x03, 0x1a, 0x10, 0x0c, + 0x1b, 0x84, 0x07, 0xa8, 0x04, 0x1f, 0xc6, 0x3e, 0xfe, 0x19, 0x49, 0x84, 0x47, 0x24, 0x04, 0x12, + 0x00, 0xff, 0xc1, 0x83, 0x22, 0x03, 0x8c, 0xe2, 0x23, 0x91, 0x2f, 0x8c, 0x33, 0x81, 0xc0, 0x06, + 0x0d, 0x04, 0x18, 0x31, 0xcd, 0x0c, 0x40, 0xfa, 0x20, 0xc3, 0xc0, 0x60, 0x10, 0x05, 0x61, 0x88, + 0x1f, 0x44, 0x18, 0x7c, 0x0c, 0x00, 0x64, 0x60, 0xd0, 0x28, 0x42, 0xb4, 0x41, 0x82, 0x33, 0x1d, + 0x07, 0x00, 0x5c, 0x30, 0x78, 0x24, 0x11, 0x1e, 0x20, 0xc3, 0xc8, 0x48, 0x20, 0xd8, 0x08, 0x1c, + 0x22, 0x05, 0x38, 0x13, 0x26, 0x23, 0x41, 0x0a, 0x14, 0x0b, 0xa4, 0x66, 0x05, 0xa2, 0x06, 0x0c, + 0x12, 0x7f, 0x12, 0x0c, 0x89, 0x0c, 0x43, 0x23, 0xf8, 0x06, 0x14, 0x0b, 0x81, 0x21, 0x80, 0x7f, + 0xc0, 0x03, 0x1f, 0x47, 0x21, 0x2c, 0x68, 0x10, 0x0f, 0xf0, 0x30, 0x61, 0xe9, 0xc5, 0x00, 0x78, + 0x03, 0xc0, 0x0b, 0xfc, 0x1d, 0xb0, 0x33, 0xc1, 0x9e, 0x0c, 0x60, +}; +const uint8_t* const _I_Certification1_103x56[] = {_I_Certification1_103x56_0}; + +const uint8_t _I_Certification2_98x33_0[] = { + 0x01, 0x00, 0xd6, 0x00, 0x80, 0x78, 0x21, 0xe0, 0xca, 0xfe, 0x5f, 0xc1, 0x95, 0x1f, 0xf8, 0x40, + 0x41, 0x71, 0x80, 0x81, 0x80, 0x44, 0x19, 0x1c, 0x00, 0x10, 0xc1, 0x81, 0x91, 0x60, 0x01, 0x0c, + 0x30, 0x19, 0x13, 0x00, 0x10, 0xc6, 0x01, 0x90, 0x09, 0x20, 0x79, 0x00, 0x18, 0x46, 0x42, 0x92, + 0x06, 0x57, 0xf2, 0x7e, 0x0c, 0x68, 0x37, 0x82, 0x07, 0xc0, 0x82, 0x48, 0x01, 0x8f, 0xfe, 0x81, + 0xfc, 0x01, 0x91, 0xe6, 0x8f, 0xc0, 0xff, 0xfe, 0x49, 0x08, 0x31, 0xbf, 0xf0, 0x1f, 0x9c, 0x3e, + 0xc9, 0x26, 0xc7, 0x47, 0x28, 0x1d, 0xff, 0x3c, 0xe2, 0x05, 0x1f, 0x07, 0x0c, 0x00, 0x18, 0x3d, + 0x19, 0x15, 0x82, 0xa1, 0x10, 0xa2, 0xc0, 0xd3, 0x02, 0xc2, 0x10, 0x60, 0xe4, 0x26, 0x54, 0x0e, + 0x84, 0x4e, 0x8b, 0x02, 0x52, 0x9f, 0x92, 0x47, 0x88, 0xd5, 0x53, 0xe1, 0x1e, 0x4b, 0xc8, 0x31, + 0x03, 0x23, 0x84, 0x93, 0x50, 0x21, 0x10, 0x4a, 0x08, 0x30, 0x7f, 0xe4, 0x21, 0x06, 0x0e, 0x0a, + 0x45, 0x40, 0xa2, 0x45, 0x04, 0xc4, 0x0c, 0x4c, 0xf9, 0x34, 0x70, 0x9e, 0x32, 0x68, 0xb3, 0x09, + 0x03, 0x40, 0xcc, 0x13, 0x0f, 0x05, 0x51, 0x10, 0xc0, 0x60, 0xd8, 0x58, 0x53, 0x80, 0x81, 0xb3, + 0xe6, 0x30, 0x0c, 0x17, 0x4c, 0xcc, 0x01, 0x82, 0xf9, 0x20, 0x03, 0x58, 0x01, 0x82, 0xec, 0x20, + 0x03, 0x70, 0x0b, 0xa8, 0x00, 0x60, 0xc0, 0x80, 0x44, 0x19, 0x10, 0x08, 0xff, 0xc2, 0x02, 0x0c, + 0x9f, 0xe5, 0xfc, 0x17, 0x30, 0x0f, 0x03, 0x70, 0x40, 0x10, +}; +const uint8_t* const _I_Certification2_98x33[] = {_I_Certification2_98x33_0}; + +const uint8_t _A_Levelup1_128x64_0[] = { + 0x01, 0x00, 0x22, 0x01, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, + 0xf0, 0x07, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, 0x38, 0x1f, 0xe0, + 0x1d, 0x97, 0xff, 0xe7, 0x1c, 0x1f, 0x99, 0xf8, 0x1c, 0xe0, 0x1f, 0x96, 0x78, 0x07, 0x03, 0xf8, + 0x0f, 0xb8, 0xdc, 0x02, 0x01, 0xfb, 0x07, 0xdc, 0x14, 0x1e, 0x3f, 0x40, 0x7d, 0xc0, 0x81, 0xe3, + 0xe8, 0x2f, 0x5c, 0x04, 0x1e, 0x3d, 0x00, 0x7d, 0x6f, 0xc1, 0xc3, 0x00, 0xd0, 0x03, 0xea, 0xbe, + 0x0f, 0xf0, 0x79, 0x50, 0x01, 0xf5, 0x2f, 0x07, 0xf8, 0x38, 0x63, 0xf8, 0x0f, 0xf1, 0x7a, 0x62, + 0x10, 0x0c, 0x04, 0x80, 0x1f, 0x59, 0xf8, 0xf8, 0xb4, 0x6f, 0x80, 0xfa, 0xb7, 0xcc, 0x20, 0x12, + 0x0f, 0x34, 0x03, 0xfa, 0x0f, 0x88, 0xbd, 0x00, 0x1e, 0x3e, 0x30, 0x7d, 0x42, 0xf0, 0x10, 0x18, + 0x87, 0x9c, 0x1f, 0x70, 0x08, 0x16, 0x43, 0xfe, 0x0f, 0xaf, 0x5c, 0x02, 0x18, 0x0f, 0xc8, 0xdc, + 0x0e, 0x20, 0x0f, 0xc8, 0x5c, 0x31, 0x7a, 0x37, 0xf0, 0x7d, 0xa3, 0xc6, 0x81, 0x3f, 0x37, 0xdc, + 0x82, 0x01, 0xc0, 0x49, 0x09, 0xff, 0x61, 0x00, 0xfa, 0x97, 0x9f, 0xc6, 0x00, 0x32, 0x10, 0x7d, + 0x40, 0x20, 0xc0, 0xfc, 0xaf, 0xc0, 0x23, 0x0f, 0x01, 0x07, 0xd6, 0xfe, 0x01, 0xe0, 0x07, 0xe5, + 0xfc, 0x7c, 0x30, 0xf0, 0x7d, 0xff, 0xe0, 0x41, 0xe2, 0x07, 0xdc, 0x14, 0x1f, 0xd0, 0xd0, 0x7f, + 0x45, 0x45, 0xfe, 0x0f, 0xf0, 0x7f, 0x17, 0xd3, 0xf4, 0x7f, 0x98, 0x18, 0x3f, 0xc1, 0xe7, 0xf4, + 0x57, 0xc8, 0xbd, 0x01, 0xff, 0xe8, 0x6f, 0xc8, 0x3d, 0x3a, 0x0f, 0xf9, 0x67, 0x88, 0x00, 0xb4, + 0x00, 0xf8, 0x8b, 0x83, 0xd2, 0x80, 0x0f, 0x88, 0x48, 0x3d, 0x30, 0x1f, 0xc0, 0x6a, 0xe3, 0xef, + 0xf0, 0x60, 0x7a, 0x40, 0x3e, 0x60, 0xf5, 0xbb, 0xe0, 0x20, 0x20, 0xf4, 0x80, 0xf3, 0x01, 0xeb, + 0x8b, 0xbf, 0x82, 0x84, 0x1e, 0x93, 0x0c, 0x00, 0x3d, 0x21, 0x60, 0xa2, 0x07, 0xa7, 0x02, 0xfe, + 0x0f, 0xd2, 0x88, 0xff, 0x81, 0xe6, +}; +const uint8_t _A_Levelup1_128x64_1[] = { + 0x01, 0x00, 0x02, 0x02, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, + 0xf0, 0x07, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x2f, 0xf8, 0x17, 0x59, 0xfe, 0xf8, 0x6b, 0x37, + 0xf9, 0xf0, 0x32, 0x7e, 0xc1, 0xac, 0x02, 0x19, 0xff, 0xfe, 0x03, 0xfc, 0x11, 0x5c, 0xfe, 0x7f, + 0xfe, 0xf1, 0x8c, 0x2e, 0x3d, 0xce, 0x80, 0xe7, 0x3e, 0xff, 0x90, 0x7c, 0xc3, 0xe6, 0x10, 0x0b, + 0x07, 0xfb, 0xf0, 0x61, 0x8c, 0x7c, 0x3e, 0x19, 0x00, 0xc0, 0x43, 0x6f, 0xc1, 0xe8, 0xbf, 0xe3, + 0xa0, 0x50, 0x08, 0x04, 0x0a, 0xfe, 0x83, 0x7f, 0xdf, 0xf6, 0x09, 0x01, 0x07, 0x8e, 0x11, 0x25, + 0x1f, 0x7f, 0x7e, 0x00, 0x1c, 0x30, 0x09, 0x41, 0xfd, 0xc0, 0x03, 0x1f, 0xa0, 0x03, 0xca, 0x21, + 0xfe, 0x30, 0x45, 0xfe, 0x90, 0x0f, 0x3f, 0xe7, 0xf4, 0x1e, 0xff, 0x79, 0x00, 0x3c, 0xa4, 0x1b, + 0xc4, 0xf4, 0xca, 0x01, 0xe5, 0xa0, 0xfc, 0x03, 0xe6, 0x20, 0x0f, 0x2a, 0x00, 0x3c, 0x7c, 0xef, + 0x96, 0xbf, 0xcc, 0x81, 0xc3, 0xf8, 0x07, 0x93, 0x0d, 0xaf, 0xbf, 0xf5, 0x70, 0xc0, 0x20, 0x94, + 0x1d, 0xc4, 0x3f, 0xf9, 0xef, 0x08, 0x2f, 0xf0, 0x7e, 0x5e, 0x2c, 0x17, 0xf3, 0xee, 0x6f, 0x89, + 0xc0, 0x3c, 0xb0, 0x7f, 0xc7, 0x93, 0x83, 0x87, 0xf1, 0x07, 0x80, 0x79, 0x70, 0xbf, 0x80, 0x7b, + 0xc9, 0xe0, 0x13, 0x86, 0xf8, 0xff, 0x70, 0xbc, 0x0f, 0x80, 0x3d, 0xb0, 0xfa, 0x18, 0xe1, 0x40, + 0x7f, 0xb0, 0x58, 0x4f, 0xf3, 0xff, 0xdf, 0x08, 0x2c, 0x0e, 0x18, 0xc0, 0x10, 0x78, 0xc0, 0x7f, + 0xdb, 0xfd, 0xf8, 0x3d, 0x74, 0x70, 0x4c, 0x04, 0x07, 0xfb, 0x03, 0x84, 0xe3, 0xfe, 0xe0, 0xf6, + 0x87, 0xf9, 0x20, 0x10, 0x6f, 0xd4, 0x0b, 0x03, 0xe7, 0xf9, 0xf7, 0xce, 0x47, 0x7b, 0xbf, 0x67, + 0xe2, 0x90, 0x38, 0x05, 0xfe, 0x03, 0xc9, 0xff, 0xfe, 0xfd, 0xee, 0x23, 0x9f, 0xff, 0x27, 0xd0, + 0xc2, 0xf8, 0xfc, 0x20, 0x18, 0x16, 0x6b, 0xff, 0xf3, 0xf0, 0xe6, 0x81, 0xca, 0x7c, 0x00, 0xf5, + 0x22, 0x0c, 0x02, 0x15, 0x20, 0x07, 0x94, 0x04, 0x1e, 0xd7, 0xf8, 0xfe, 0x82, 0x14, 0x6f, 0x10, + 0x00, 0xea, 0x51, 0xe3, 0xf3, 0x08, 0x26, 0x7a, 0x03, 0x12, 0x37, 0x88, 0x7c, 0x91, 0xe3, 0xe7, + 0x3f, 0xb4, 0x48, 0xde, 0x21, 0xf2, 0xff, 0x7f, 0xf9, 0xe7, 0xf6, 0x91, 0x40, 0x2f, 0x01, 0xf2, + 0x07, 0xba, 0x58, 0x68, 0x43, 0xe2, 0x0f, 0x88, 0xbc, 0x7d, 0xff, 0xb0, 0x79, 0xf3, 0xe1, 0x78, + 0x20, 0x79, 0xc0, 0x47, 0xc2, 0x8f, 0x43, 0xf0, 0xe8, 0xe0, 0x44, 0xe2, 0x0f, 0x8f, 0xdf, 0xc6, + 0xae, 0x35, 0x28, 0xb7, 0xc6, 0x05, 0x02, 0x07, 0x97, 0x07, 0xff, 0xf1, 0x17, 0x20, 0x10, 0x74, + 0xe0, 0xe3, 0x80, 0x72, 0x67, 0xff, 0x82, 0xf2, 0xfc, 0xe1, 0xec, 0xe1, 0x00, 0x15, 0x0a, 0x1e, + 0x60, 0x12, 0x72, 0x70, 0xe5, 0xe0, 0xf4, 0x85, 0x41, 0x83, 0xcb, 0x37, 0x83, 0xe1, 0xc5, 0xe9, + 0x04, 0x81, 0x07, 0xc7, 0xde, 0x0f, 0x2a, 0x5c, 0x3b, 0x40, 0x0f, 0x4d, 0x24, 0x83, 0x3d, 0xbf, + 0x30, 0x1e, 0x2e, 0x39, 0x40, 0x07, 0xa4, 0x22, 0x01, 0x67, 0xcf, 0x8b, 0xce, 0x17, 0x83, 0x91, + 0x03, 0xd2, 0x61, 0x2a, 0xcc, 0xf3, 0x81, 0xe9, 0x1c, 0x8c, 0x03, 0xd3, 0x81, 0x00, 0xc3, 0x18, + 0x12, 0x2f, 0xe0, 0x83, 0x83, 0xd2, 0x01, 0xff, 0xc0, 0x83, 0xd4, 0x12, 0x20, 0xf5, 0x80, 0x60, + 0x01, 0xe2, 0x50, 0x29, 0x78, 0x3d, 0x98, 0x63, 0x40, 0x48, 0xa0, 0x3e, 0xac, 0xc0, 0xf3, 0xa0, + 0x83, 0xe2, 0x41, 0xc0, 0x3f, 0x9e, 0x04, 0x1f, 0x3e, 0x0f, 0xc8, 0x80, 0xa0, 0x60, 0x81, 0x07, + 0xb6, 0x42, 0x85, 0xfc, 0x0f, 0x90, +}; +const uint8_t _A_Levelup1_128x64_2[] = { + 0x01, 0x00, 0xc1, 0x02, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x3f, 0xe4, 0x1f, 0xdf, 0x40, + 0x43, 0xf3, 0xc0, 0xa9, 0x7f, 0xfb, 0x03, 0xdf, 0x66, 0x05, 0x4d, 0xff, 0xbc, 0x1e, 0xf3, 0xbf, + 0xf0, 0x14, 0xe3, 0xf7, 0x8f, 0xf7, 0xc4, 0x1e, 0xb1, 0x3f, 0xe0, 0x14, 0xe1, 0xf9, 0x02, 0x0b, + 0xc5, 0xc1, 0xeb, 0xcc, 0xff, 0x03, 0xda, 0x1e, 0x0f, 0x48, 0x3f, 0xbf, 0xfd, 0xf8, 0x07, 0xad, + 0xfc, 0x1e, 0x57, 0xff, 0xf4, 0x0f, 0xe7, 0xff, 0x07, 0xaf, 0x8e, 0xff, 0xf8, 0xed, 0xc7, 0xee, + 0x1f, 0xc8, 0x18, 0x34, 0x41, 0xeb, 0xc3, 0x9f, 0xfc, 0x3f, 0x70, 0xfe, 0x07, 0xfe, 0x01, 0x9c, + 0x0b, 0x88, 0x88, 0x41, 0xe7, 0x1f, 0xc8, 0x5f, 0xe0, 0x7c, 0x08, 0x7c, 0x03, 0xf9, 0x7f, 0x9e, + 0x07, 0xd3, 0x8f, 0x17, 0x80, 0x7e, 0xe0, 0x2f, 0x71, 0x85, 0x7f, 0xa7, 0xf1, 0xe0, 0x7a, 0x63, + 0xe7, 0xf0, 0x09, 0x99, 0x34, 0x42, 0x03, 0xfb, 0x9f, 0xa5, 0xd3, 0xf1, 0x3f, 0xbf, 0xc1, 0x38, + 0x10, 0x1c, 0xe6, 0xaa, 0x04, 0x1f, 0x10, 0xf2, 0x7e, 0x26, 0xff, 0x88, 0x74, 0xc2, 0x01, 0x60, + 0x0f, 0x8d, 0xfc, 0x5c, 0x2c, 0x23, 0xff, 0x4c, 0xed, 0x18, 0xe8, 0x64, 0x03, 0x01, 0xa9, 0xc1, + 0x5e, 0xf3, 0xc1, 0xf4, 0x9f, 0xcc, 0xf8, 0x10, 0x48, 0x10, 0x74, 0x60, 0x58, 0x0b, 0xfe, 0x32, + 0xfe, 0xbe, 0x50, 0x78, 0x97, 0x8b, 0x49, 0xc0, 0xf7, 0xe0, 0x14, 0xc4, 0xbe, 0x3c, 0x06, 0x00, + 0x1c, 0x30, 0x08, 0x46, 0x02, 0x78, 0x0f, 0x20, 0x01, 0xdf, 0xb0, 0x14, 0x00, 0x79, 0x64, 0x21, + 0x41, 0x11, 0x07, 0x23, 0x30, 0x60, 0x00, 0xf3, 0x88, 0x00, 0x87, 0x81, 0xbf, 0x07, 0x9e, 0x73, + 0xdf, 0x01, 0x90, 0x03, 0xcb, 0x40, 0x53, 0x19, 0x02, 0x3d, 0x23, 0x3f, 0xf0, 0x7a, 0x00, 0xc8, + 0x1e, 0x5c, 0x70, 0x78, 0xc6, 0xb9, 0xd0, 0x11, 0x59, 0x0c, 0xc7, 0x51, 0x0a, 0x80, 0x03, 0x07, + 0x16, 0x02, 0x13, 0xc0, 0x83, 0xd4, 0x04, 0x38, 0xef, 0xff, 0x8f, 0xfa, 0x0f, 0x18, 0x3a, 0x6c, + 0x43, 0x22, 0x00, 0x1c, 0x06, 0xaa, 0x14, 0xd9, 0x1f, 0x38, 0xfc, 0xa1, 0xa4, 0x81, 0x84, 0x03, + 0xcc, 0x02, 0x3f, 0xf0, 0x71, 0x80, 0x06, 0x02, 0x1f, 0x5d, 0x14, 0x2b, 0xf0, 0x0f, 0x51, 0x80, + 0xc1, 0x01, 0xe5, 0x00, 0x0b, 0x0f, 0xe7, 0xf6, 0x0f, 0x5c, 0x50, 0x3d, 0x35, 0x3e, 0x07, 0x59, + 0x03, 0x8a, 0xff, 0x0f, 0x80, 0x51, 0x13, 0xe7, 0x01, 0xf8, 0x7b, 0xff, 0xa0, 0xf2, 0x87, 0xff, + 0xe3, 0xd2, 0x8e, 0x20, 0x3c, 0xa3, 0x1a, 0x9f, 0x87, 0x1e, 0xff, 0xde, 0xc7, 0x8b, 0x47, 0xd2, + 0x1f, 0x10, 0x7a, 0x07, 0xc7, 0x8f, 0x3f, 0xff, 0x61, 0xff, 0xff, 0x7e, 0xfc, 0x1f, 0x40, 0x1f, + 0x5f, 0x07, 0x9d, 0xfa, 0x3e, 0x37, 0xf9, 0x87, 0xc6, 0x02, 0x0f, 0x18, 0xe4, 0x07, 0x80, 0x0c, + 0x24, 0xf9, 0x14, 0x04, 0x3e, 0x31, 0xf7, 0x58, 0xc7, 0xf5, 0x38, 0x0f, 0x1b, 0xbd, 0x00, 0x03, + 0x00, 0xc2, 0x03, 0xca, 0x1e, 0x23, 0x1f, 0x80, 0x28, 0x73, 0xe0, 0x21, 0xf9, 0xff, 0x70, 0x30, + 0x41, 0x90, 0xe0, 0x20, 0xfa, 0x98, 0x17, 0xf3, 0xee, 0x0f, 0x2f, 0xe7, 0x83, 0xdf, 0x01, 0x4f, + 0xac, 0x03, 0xfc, 0x0f, 0x10, 0xe8, 0xa4, 0xc9, 0x5e, 0xba, 0x96, 0xf8, 0x87, 0x87, 0xcf, 0xf1, + 0xff, 0xf1, 0xe7, 0x80, 0xf1, 0x88, 0x3f, 0x88, 0x3e, 0x3f, 0xfe, 0x7f, 0x7f, 0xcf, 0xf9, 0xff, + 0xc0, 0xa3, 0x1a, 0x08, 0x24, 0x82, 0x00, 0x01, 0x1d, 0x4e, 0x0b, 0x3f, 0xc7, 0xf3, 0xfc, 0xff, + 0x9f, 0xf9, 0x08, 0xa8, 0x41, 0xe8, 0xdf, 0x18, 0x7f, 0x07, 0xcf, 0x78, 0x1e, 0x8d, 0xfe, 0x00, + 0x1f, 0x5c, 0x0c, 0x2a, 0x0f, 0xe0, 0xbb, 0xc7, 0x0f, 0xc7, 0x00, 0x83, 0x0f, 0x44, 0x82, 0x30, + 0x30, 0x38, 0xf8, 0x22, 0x78, 0x00, 0x70, 0xf3, 0xf0, 0x1a, 0xa0, 0x7a, 0x60, 0xe1, 0x50, 0xaf, + 0x84, 0x07, 0xc0, 0x0f, 0x1d, 0xb8, 0x5c, 0x60, 0xbc, 0x06, 0x70, 0x81, 0x06, 0x01, 0x60, 0xf0, + 0x28, 0x85, 0x64, 0x34, 0xad, 0x46, 0x2a, 0x09, 0x80, 0xfc, 0xc3, 0x20, 0x18, 0x9d, 0x56, 0x48, + 0x32, 0x3f, 0x80, 0xf8, 0xe2, 0xa0, 0x36, 0x00, 0x78, 0xc1, 0xd6, 0x23, 0x31, 0x80, 0x63, 0x01, + 0xe3, 0xb8, 0xfd, 0xff, 0xe1, 0x10, 0xe8, 0xc2, 0x7c, 0x56, 0x45, 0xc1, 0xc0, 0x60, 0xe0, 0x52, + 0xae, 0x41, 0xb8, 0x61, 0x1f, 0x08, 0x38, 0x30, 0x60, 0xc5, 0xd1, 0x80, 0xdf, 0xf0, 0x06, 0x12, + 0x17, 0x89, 0x64, 0x57, 0xe5, 0xf8, 0x60, 0x9d, 0x03, 0x44, 0x61, 0x10, 0x7b, 0x00, 0x10, 0xea, + 0x25, 0xf1, 0x07, 0x8a, 0xbc, 0xc1, 0xeb, 0xa0, 0xd5, 0x42, 0x97, 0xc3, 0xff, 0x54, 0x88, 0x3d, + 0xc1, 0x25, 0xfe, 0x5f, 0x88, 0x94, 0x80, 0x0d, 0x90, 0xd5, 0x4a, 0x81, 0xc3, 0xfe, 0xce, 0x03, + 0xe2, 0x10, 0x1f, 0x2f, 0xff, 0xe2, 0x7f, 0x01, 0x06, 0xa8, 0x18, 0x74, 0x83, 0xf1, 0xfb, 0x7f, + 0xff, 0x33, 0xf8, 0x30, 0xfd, 0x41, 0xe2, 0xe1, 0x25, 0x79, 0x41, 0xcf, 0x62, 0x0f, 0x5f, 0xc6, + 0xa3, 0x55, 0x8a, 0x07, 0x90, +}; +const uint8_t _A_Levelup1_128x64_3[] = { + 0x01, 0x00, 0x0a, 0x03, 0x8f, 0xc0, 0xb8, 0x1f, 0xfb, 0xfd, 0xe2, 0x7f, 0xf8, 0x02, 0x0f, 0xff, + 0xff, 0x03, 0xff, 0x00, 0xc6, 0xff, 0x36, 0xe0, 0x47, 0xfd, 0xff, 0x08, 0xff, 0xf3, 0xff, 0x3f, + 0x05, 0x8f, 0xf0, 0x1e, 0x5f, 0xf8, 0xfe, 0x02, 0xfb, 0xff, 0xf8, 0x43, 0xff, 0x99, 0xfd, 0xf8, + 0x44, 0x81, 0xe7, 0x17, 0x88, 0x7d, 0x37, 0xe0, 0xf2, 0x87, 0xe7, 0xff, 0xe0, 0x11, 0xfe, 0x83, + 0xca, 0x1f, 0x20, 0xf8, 0x0f, 0x46, 0x0f, 0xfe, 0x83, 0xf6, 0xff, 0xfc, 0xf0, 0xfa, 0x47, 0xec, + 0x1e, 0x08, 0xf8, 0x3c, 0xa0, 0x7c, 0x3f, 0xff, 0x9c, 0x1e, 0x93, 0xf8, 0x06, 0x02, 0x1f, 0xf8, + 0x2c, 0x8c, 0x07, 0xc1, 0xff, 0xfd, 0x83, 0xdb, 0xc1, 0x07, 0xfc, 0x40, 0x6f, 0xda, 0x0d, 0x47, + 0xff, 0xf2, 0x0f, 0x4b, 0xf8, 0x7c, 0x60, 0xda, 0x88, 0x0c, 0x72, 0x01, 0xb0, 0xff, 0xe0, 0x01, + 0xe9, 0xff, 0x80, 0x68, 0x21, 0xff, 0xa9, 0x06, 0x02, 0x01, 0xf2, 0xbf, 0x40, 0x12, 0x44, 0x1f, + 0x2b, 0x82, 0xa1, 0x7d, 0x11, 0xf8, 0x05, 0xf8, 0x1e, 0x74, 0x7f, 0x80, 0xc0, 0x75, 0x50, 0xa8, + 0x04, 0x83, 0xf0, 0x0f, 0x1b, 0xe1, 0x48, 0x6f, 0xfb, 0x78, 0x38, 0x3c, 0x40, 0x09, 0xfc, 0x81, + 0x83, 0xcb, 0xfb, 0xbf, 0xbf, 0xcb, 0xbe, 0x1a, 0x8d, 0x56, 0xaa, 0x55, 0x80, 0x85, 0x18, 0xc4, + 0x5e, 0xb3, 0xce, 0x00, 0x7d, 0x7b, 0x80, 0x21, 0xdf, 0xcf, 0xef, 0xee, 0x72, 0x2f, 0x8e, 0xaa, + 0x01, 0xa8, 0xd1, 0x62, 0xa7, 0xfa, 0x0c, 0x06, 0x7d, 0x82, 0x33, 0x8f, 0x3d, 0xfe, 0x04, 0x18, + 0x15, 0x68, 0xc0, 0x1e, 0xa2, 0x02, 0x1f, 0x0f, 0xff, 0xbf, 0x3f, 0xe3, 0xcf, 0xc7, 0x63, 0xca, + 0xd5, 0xe7, 0xb5, 0x58, 0xa8, 0x3e, 0xa3, 0x80, 0x8e, 0x29, 0xfe, 0x3c, 0x2e, 0x30, 0x0b, 0x85, + 0x56, 0xea, 0x73, 0x11, 0x10, 0xd8, 0x01, 0xe5, 0xcf, 0x9f, 0xcf, 0xf5, 0x50, 0x2d, 0x61, 0x80, + 0x75, 0x38, 0xa2, 0x28, 0xda, 0x09, 0x63, 0x9f, 0x1f, 0x0c, 0xf8, 0x3e, 0x35, 0x6a, 0xad, 0x54, + 0x3a, 0x20, 0x01, 0xba, 0x7f, 0xf7, 0xf9, 0xff, 0xbc, 0xfe, 0x7c, 0x9c, 0x1d, 0x58, 0x7c, 0x74, + 0xd0, 0xad, 0x16, 0xab, 0x71, 0xbf, 0xef, 0xfb, 0xc1, 0xe3, 0x0c, 0x1d, 0x08, 0x78, 0x6a, 0xb0, + 0xd0, 0xf9, 0x66, 0x3f, 0xbf, 0xff, 0x3f, 0x9c, 0x9c, 0x3a, 0x8e, 0x50, 0x78, 0x75, 0x59, 0xa8, + 0x50, 0x0c, 0x7c, 0x9f, 0xff, 0xcf, 0x9f, 0xe3, 0x07, 0x0b, 0x8d, 0x00, 0x3e, 0x51, 0x50, 0xf9, + 0x7c, 0x3e, 0x7f, 0x99, 0x3f, 0xe2, 0x0f, 0x2a, 0x5f, 0x10, 0x00, 0xb1, 0x4c, 0x31, 0xf8, 0x7c, + 0x77, 0x10, 0x3f, 0xe4, 0x3c, 0x2e, 0x36, 0x00, 0xf9, 0x4d, 0x43, 0xe5, 0xe0, 0x9c, 0xfb, 0xa0, + 0x7e, 0x88, 0x78, 0x68, 0x76, 0x41, 0xe2, 0xb5, 0x17, 0x86, 0x05, 0xf8, 0xcc, 0x7f, 0xe0, 0x3f, + 0xc8, 0x30, 0x5c, 0x6a, 0x01, 0xf2, 0xaa, 0x87, 0xcb, 0xf1, 0xc2, 0xff, 0xc0, 0x00, 0x22, 0x3e, + 0x50, 0x01, 0x42, 0xaf, 0x1d, 0x09, 0xfe, 0x00, 0x1e, 0x20, 0x01, 0xac, 0x07, 0x8b, 0xaa, 0x07, + 0x29, 0xe7, 0x0a, 0x1e, 0x0f, 0x20, 0xfc, 0x4a, 0xa7, 0x9e, 0x85, 0xa8, 0xf0, 0xc2, 0xe5, 0x54, + 0x1f, 0x9c, 0x04, 0x3e, 0x5e, 0x00, 0x18, 0xf1, 0xe0, 0x3a, 0x06, 0xf1, 0xb8, 0x08, 0x7e, 0x33, + 0x8a, 0x04, 0x02, 0x51, 0xe3, 0x4f, 0x90, 0x7d, 0xc0, 0x07, 0xfa, 0x80, 0x68, 0xe1, 0x5e, 0xc0, + 0xf1, 0x6e, 0x83, 0xe4, 0x0e, 0x28, 0x57, 0xe3, 0xce, 0x18, 0x1e, 0xa0, 0x78, 0xab, 0xa1, 0xf6, + 0xfc, 0x7f, 0xf0, 0x72, 0xa0, 0xfa, 0xca, 0xa5, 0x50, 0x08, 0x46, 0x01, 0x46, 0x3f, 0xf3, 0x18, + 0x87, 0xf3, 0xbf, 0x00, 0xd5, 0x7b, 0x37, 0xfa, 0xaf, 0x56, 0xff, 0x53, 0x82, 0x0f, 0x8c, 0x83, + 0x51, 0x02, 0xff, 0x5f, 0xc2, 0x63, 0xd4, 0xaf, 0xa7, 0x86, 0xbe, 0x1f, 0x6d, 0xf5, 0xff, 0x51, + 0x2a, 0xd6, 0x6b, 0xc7, 0xe3, 0xaf, 0xd4, 0xe0, 0x03, 0xe2, 0x06, 0x18, 0x17, 0xf2, 0xf6, 0x7f, + 0xd2, 0x78, 0xea, 0x21, 0x49, 0xf4, 0x80, 0xe0, 0x35, 0x40, 0x11, 0x0f, 0x97, 0xfc, 0x30, 0x21, + 0xfb, 0xbf, 0x43, 0xc3, 0xed, 0x81, 0x0e, 0x90, 0x7c, 0xa7, 0xd1, 0xf1, 0xf9, 0x5d, 0x6a, 0xa0, + 0x11, 0x0f, 0xb4, 0xf2, 0x7c, 0x57, 0x16, 0xfa, 0xe2, 0x80, 0xa7, 0x00, 0x9c, 0x07, 0xca, 0xac, + 0x3f, 0x35, 0x30, 0x80, 0x19, 0x6e, 0x3a, 0xef, 0x52, 0xf8, 0x75, 0x5a, 0xbd, 0x10, 0x80, 0x90, + 0x43, 0xe0, 0x98, 0x04, 0x45, 0x3a, 0x2b, 0xe1, 0xaa, 0xc1, 0x60, 0x16, 0x00, 0xe9, 0xfd, 0x2d, + 0x1a, 0xac, 0x56, 0xbb, 0x55, 0xfb, 0x01, 0x0e, 0x2f, 0x45, 0xb2, 0x0f, 0x8c, 0x2a, 0x01, 0xfc, + 0xec, 0x40, 0x6c, 0x01, 0xf1, 0xab, 0xb0, 0x46, 0x6b, 0x00, 0xee, 0x27, 0xd3, 0x51, 0x0e, 0xdc, + 0x07, 0x07, 0x56, 0x02, 0x1f, 0x5e, 0x03, 0x56, 0x1f, 0x1d, 0x04, 0x2b, 0xfd, 0x59, 0xfa, 0xd5, + 0xcb, 0x83, 0x57, 0x01, 0x95, 0xff, 0xaa, 0x1f, 0x3f, 0xfe, 0xdc, 0x2a, 0x21, 0xc1, 0xfd, 0x1e, + 0xce, 0xd5, 0x0a, 0x85, 0x10, 0x06, 0x7b, 0x53, 0x3e, 0x18, 0x01, 0x43, 0xe7, 0xc0, 0x7d, 0x90, + 0x7c, 0x40, 0x09, 0x2a, 0x94, 0x4a, 0x17, 0xe3, 0xe3, 0xb5, 0x87, 0xa0, 0xc2, 0x20, 0x01, 0xc0, + 0x78, 0x7b, 0xe1, 0xc5, 0x00, 0x16, 0x68, 0x42, 0x3a, 0xae, 0x17, 0xc7, 0x3e, 0x1f, 0x88, 0x68, + 0xf8, 0xfe, 0x10, 0x13, 0xb1, 0x00, 0x0c, 0x0c, 0x3a, 0x65, 0x48, 0x8f, 0xc7, 0xf0, 0xdd, 0x57, + 0x0c, 0x7f, 0x14, 0x22, 0x5f, 0x5d, 0x5f, 0xeb, 0x51, 0xaa, 0xd1, 0x07, 0xc7, 0xf8, +}; +const uint8_t _A_Levelup1_128x64_4[] = { + 0x01, 0x00, 0x7e, 0x02, 0xff, 0x80, 0x3c, 0x01, 0xf1, 0xff, 0xe0, 0x3f, 0x7d, 0xff, 0xd1, 0x0f, + 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x2d, 0xff, 0xee, 0x0f, 0xef, 0x47, 0xff, 0xfc, 0x06, 0x2d, + 0xf8, 0x3d, 0xe0, 0x3e, 0x49, 0x3f, 0xc0, 0xfc, 0x7f, 0x8f, 0xfc, 0xed, 0x02, 0x37, 0xff, 0xc5, + 0xbe, 0x01, 0xf0, 0xaf, 0xe0, 0xc1, 0xe7, 0xe0, 0xff, 0xc0, 0xc2, 0xe3, 0x1f, 0xf8, 0x4f, 0xe0, + 0x17, 0x0b, 0xf5, 0x81, 0x34, 0x40, 0xf1, 0xb8, 0xc1, 0x38, 0x1f, 0xd8, 0x3f, 0xe2, 0x73, 0x00, + 0xf7, 0xc7, 0xe4, 0x02, 0xb1, 0xff, 0xcf, 0xf0, 0x02, 0x81, 0xc0, 0x77, 0xe0, 0x37, 0xf8, 0x47, + 0x82, 0xff, 0x0e, 0x6e, 0x1c, 0x1d, 0xc4, 0x3e, 0x08, 0x0d, 0xfb, 0x80, 0x2e, 0x1f, 0x00, 0x08, + 0x60, 0x06, 0x02, 0xc3, 0xc0, 0x41, 0x23, 0x81, 0x04, 0x89, 0x38, 0x6c, 0x11, 0xfc, 0x04, 0x3c, + 0x1e, 0x3f, 0x78, 0x3c, 0x0e, 0x01, 0xc0, 0x83, 0xff, 0xa0, 0x60, 0x52, 0x8c, 0x88, 0x45, 0x00, + 0x63, 0x02, 0xe2, 0x6a, 0xe3, 0xc0, 0x41, 0x00, 0x09, 0xf8, 0xd2, 0x63, 0x4f, 0x04, 0x1d, 0xfc, + 0x1e, 0x65, 0xd2, 0x01, 0x09, 0xc8, 0x60, 0xd0, 0x0d, 0x66, 0xab, 0x54, 0x45, 0x10, 0x00, 0xfb, + 0x3f, 0xff, 0x3f, 0x8f, 0xcf, 0xd9, 0xf9, 0x87, 0xd4, 0x06, 0xc5, 0x03, 0x8a, 0x03, 0xc7, 0xf9, + 0xcf, 0xf3, 0xdf, 0xfc, 0xfc, 0x4f, 0xfc, 0x2e, 0x01, 0xab, 0x0f, 0x88, 0x90, 0x45, 0xe5, 0x87, + 0x1f, 0x94, 0x02, 0x9f, 0x08, 0xca, 0x01, 0x8a, 0x9f, 0x15, 0x07, 0x8d, 0xe3, 0x80, 0x0f, 0x30, + 0xc8, 0xf0, 0x03, 0xc3, 0xaa, 0x8d, 0x14, 0x13, 0x9f, 0xfb, 0x07, 0x8c, 0x02, 0x21, 0xd0, 0x0b, + 0x15, 0x7e, 0x2a, 0x51, 0x1b, 0x07, 0xfb, 0xcd, 0xff, 0xe1, 0x9f, 0x8b, 0x40, 0x1f, 0x29, 0x50, + 0x78, 0xa7, 0x93, 0x9c, 0x87, 0xfe, 0x03, 0x1f, 0x5f, 0x90, 0x7c, 0xa7, 0xf5, 0x5a, 0x84, 0x07, + 0x7c, 0x95, 0x1f, 0xbb, 0x48, 0x41, 0xe3, 0xb0, 0x0f, 0x95, 0xa8, 0x3e, 0x51, 0xe7, 0x00, 0xdf, + 0xe6, 0x0a, 0xf1, 0x82, 0x29, 0xce, 0xff, 0x55, 0xaa, 0xc0, 0x60, 0x90, 0x0c, 0x04, 0x7f, 0xfd, + 0xfd, 0x20, 0x0e, 0xa0, 0x3e, 0x5a, 0xa2, 0xf9, 0x9a, 0x47, 0x8e, 0x19, 0x14, 0xf0, 0xfe, 0x58, + 0xe7, 0x54, 0xaa, 0x84, 0x13, 0xdf, 0xfb, 0x12, 0x88, 0x7e, 0x4b, 0x43, 0xe3, 0xb7, 0xc0, 0x2a, + 0x9f, 0xd0, 0xf9, 0x8f, 0xc5, 0xe4, 0x9c, 0x38, 0x18, 0x10, 0x5b, 0xc4, 0xe0, 0x50, 0x79, 0x60, + 0x40, 0x63, 0x40, 0x0f, 0xbd, 0x50, 0x26, 0xaf, 0x71, 0x0f, 0x16, 0xe8, 0x16, 0xd1, 0xfb, 0x85, + 0xc2, 0x00, 0x1f, 0x50, 0x80, 0xd5, 0x22, 0x20, 0xf1, 0xff, 0x7e, 0x3f, 0x01, 0xfb, 0xec, 0x7f, + 0xef, 0x12, 0x08, 0x07, 0xf0, 0x3e, 0x71, 0x58, 0x24, 0x16, 0x28, 0x1e, 0x20, 0x40, 0xf8, 0xe0, + 0x3e, 0xcd, 0xfe, 0xab, 0xd5, 0xbf, 0x0f, 0xad, 0x6d, 0x3e, 0x41, 0xf5, 0xa8, 0xd5, 0x60, 0xa0, + 0x11, 0x67, 0x8e, 0xfa, 0xfe, 0x0f, 0x1d, 0x66, 0xbc, 0x7e, 0x3a, 0xf0, 0xfa, 0xff, 0xe3, 0xe0, + 0x11, 0x0f, 0xad, 0x56, 0x8b, 0x41, 0xaa, 0xc5, 0x60, 0x1f, 0xb8, 0x4e, 0x5c, 0x1e, 0x29, 0xf9, + 0xe0, 0x7f, 0xe1, 0xb1, 0xf8, 0x7a, 0xfd, 0xc3, 0xe3, 0x05, 0xb0, 0x43, 0xf8, 0x17, 0xf6, 0xf8, + 0x87, 0xe6, 0x61, 0x04, 0xf0, 0x46, 0x20, 0x15, 0x50, 0xfc, 0x04, 0xca, 0xe4, 0x15, 0x26, 0xfd, + 0x40, 0x22, 0x00, 0x21, 0xa8, 0xa5, 0x08, 0x00, 0x35, 0x3a, 0xad, 0x50, 0xbc, 0x20, 0x01, 0xb0, + 0x00, 0xcb, 0x5d, 0xea, 0x5f, 0x0e, 0xaa, 0x06, 0x1f, 0x5f, 0xc4, 0xc2, 0x01, 0x15, 0x0f, 0x1f, + 0xfe, 0xaf, 0x55, 0xb2, 0x9f, 0xc8, 0x1e, 0x36, 0x88, 0x06, 0x03, 0x5d, 0xaa, 0xfd, 0x80, 0x86, + 0x17, 0x00, 0xd8, 0x07, 0xcf, 0xdd, 0xf9, 0xa8, 0xf9, 0x43, 0xe9, 0x3f, 0xaa, 0xff, 0x08, 0x02, + 0x61, 0x1f, 0xf6, 0xae, 0x1d, 0xb8, 0x0e, 0x0e, 0xac, 0x04, 0x3e, 0xbc, 0x06, 0xac, 0x3c, 0x58, + 0x0f, 0xff, 0xec, 0x3a, 0x80, 0x04, 0xaa, 0x20, 0xc7, 0xc1, 0x4f, 0xd9, 0x9e, 0x84, 0x38, 0x3f, + 0xa4, 0x09, 0xda, 0x87, 0xe7, 0x08, 0xfb, 0x87, 0xa2, 0xff, 0x55, 0xa8, 0x18, 0x0b, 0x4e, 0x1f, + 0x30, 0x02, 0x4a, 0x90, 0x09, 0xef, 0x0f, 0xc1, 0x84, 0x60, 0xb4, 0x16, 0xe0, 0xf7, 0x43, 0x8a, + 0x00, 0x28, 0xd0, 0x7d, 0x0c, 0x22, 0x00, 0x7a, 0x79, 0x78, 0x55, 0x62, 0x10, 0x1d, 0x58, 0x75, + 0x40, 0xc3, 0x06, 0x60, 0xab, 0x75, 0x1c, 0x2b, 0x55, 0xa0, 0xb0, 0x4c, 0xbe, 0xba, 0xbf, 0xd0, + 0x79, 0x40, +}; +const uint8_t _A_Levelup1_128x64_5[] = { + 0x01, 0x00, 0x79, 0x02, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, + 0xf0, 0x07, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1f, 0xff, 0xfb, 0xcf, 0xc0, + 0xc9, 0xf0, 0xf1, 0x84, 0x1e, 0xff, 0xfe, 0x80, 0xff, 0x3f, 0xb7, 0xbf, 0xe7, 0x3c, 0x1c, 0xdb, + 0xff, 0xfc, 0xff, 0xfc, 0x1b, 0x80, 0x02, 0x73, 0xf5, 0xf9, 0xf8, 0xff, 0xff, 0x8f, 0x9f, 0xfc, + 0x0b, 0xde, 0xe5, 0xdd, 0xba, 0xf3, 0xbe, 0x3c, 0x78, 0x08, 0xf5, 0xe6, 0x3a, 0xcd, 0x56, 0xaa, + 0xc3, 0xf0, 0xa7, 0xe0, 0x3f, 0xff, 0xe1, 0xf2, 0x5f, 0x20, 0x15, 0x6a, 0xad, 0x57, 0x07, 0xf3, + 0x87, 0xf8, 0x3f, 0xfe, 0x11, 0x02, 0x4d, 0xe0, 0x1a, 0xbd, 0x76, 0xaf, 0x0d, 0xff, 0x80, 0x7c, + 0x3f, 0xbc, 0x70, 0x7a, 0x4f, 0xf0, 0x41, 0xe1, 0xaa, 0xfb, 0x67, 0xf0, 0x02, 0x70, 0x9c, 0x4c, + 0x7c, 0x33, 0xfe, 0x3e, 0xa8, 0x3e, 0x31, 0xa8, 0x78, 0x3c, 0x89, 0xc9, 0xd0, 0xff, 0xd1, 0xea, + 0xb5, 0x7a, 0xbc, 0x56, 0x01, 0x00, 0xfe, 0x03, 0xd4, 0x2c, 0x3a, 0xf2, 0xf0, 0xea, 0xa5, 0x40, + 0xf1, 0x9c, 0x1f, 0xdb, 0x1f, 0x67, 0x0f, 0x94, 0xd6, 0x01, 0x04, 0x80, 0x18, 0x07, 0x7f, 0xef, + 0x07, 0x94, 0x3f, 0x64, 0x1f, 0x2b, 0x50, 0x7c, 0x46, 0x25, 0xfd, 0xef, 0xb7, 0x47, 0x3f, 0x0c, + 0xa8, 0x07, 0xc8, 0xc2, 0x30, 0x10, 0x78, 0xfc, 0x08, 0x09, 0x18, 0xd4, 0x6a, 0x90, 0x03, 0xaa, + 0x06, 0x8c, 0x70, 0x60, 0x47, 0xd2, 0xff, 0xcc, 0xfb, 0x01, 0xd2, 0xef, 0xd5, 0x20, 0x37, 0xf0, + 0x78, 0xfe, 0xc2, 0x05, 0xc7, 0x83, 0xfa, 0x35, 0x46, 0x21, 0xdd, 0x40, 0x30, 0x10, 0xfc, 0x63, + 0xd4, 0x5f, 0x03, 0xef, 0x07, 0x8d, 0xd7, 0xab, 0x55, 0xae, 0xdd, 0x6a, 0xb8, 0x58, 0x7e, 0xff, + 0xce, 0x1d, 0x12, 0x10, 0xfc, 0xe0, 0xfa, 0xcf, 0xd6, 0xa8, 0x02, 0x24, 0xe1, 0x81, 0xb7, 0x84, + 0xdc, 0x57, 0xf9, 0x7c, 0x02, 0xab, 0x75, 0x00, 0x0d, 0x56, 0x82, 0x10, 0x10, 0x78, 0xc3, 0xde, + 0x25, 0x06, 0x3b, 0x0e, 0xeb, 0x55, 0xea, 0xfd, 0x1b, 0x8a, 0xff, 0x7f, 0xbf, 0x2c, 0xc7, 0xe7, + 0x0e, 0x80, 0x75, 0x2a, 0xb7, 0x7a, 0xbd, 0x76, 0x8b, 0x05, 0x80, 0x06, 0xc6, 0xf8, 0xb2, 0x1b, + 0x1a, 0x58, 0x83, 0xec, 0x6e, 0x41, 0x70, 0xd5, 0x0b, 0xc2, 0x00, 0x10, 0xf9, 0x08, 0x04, 0x7a, + 0x5f, 0xf8, 0x60, 0x7c, 0xb7, 0xe1, 0xf1, 0xff, 0x87, 0xca, 0x01, 0xfd, 0x07, 0x96, 0x26, 0x07, + 0x40, 0xfa, 0xb1, 0x47, 0xbf, 0x7f, 0xa2, 0xb0, 0x0b, 0xf1, 0x7f, 0x10, 0x8f, 0x82, 0x0f, 0x00, + 0xd6, 0x7b, 0xcf, 0xe3, 0xaf, 0x0f, 0x96, 0x03, 0xff, 0x39, 0xff, 0x63, 0x7f, 0xf1, 0xf3, 0xf9, + 0x00, 0x4a, 0x82, 0x01, 0x1c, 0x07, 0x7c, 0xc4, 0x38, 0x71, 0x88, 0xc0, 0x75, 0x83, 0xf2, 0x0f, + 0x9c, 0x02, 0x0c, 0x21, 0x17, 0x01, 0x41, 0xea, 0x85, 0xf2, 0x00, 0x12, 0x84, 0xb0, 0x0d, 0x11, + 0xff, 0xcf, 0xa0, 0xba, 0xcd, 0x50, 0x00, 0x83, 0xe7, 0x00, 0xe0, 0x7c, 0x57, 0xe3, 0x78, 0x9c, + 0x55, 0x07, 0xe7, 0x55, 0x8a, 0xd0, 0x02, 0x43, 0xe0, 0xfe, 0x7d, 0xff, 0xfe, 0x9b, 0xc0, 0x7e, + 0x60, 0x13, 0x07, 0x01, 0x5e, 0x2a, 0xc3, 0xd3, 0x43, 0x0a, 0x04, 0x42, 0x05, 0x8c, 0xc1, 0xc7, + 0xfe, 0x1a, 0xef, 0x56, 0xa9, 0x82, 0x30, 0x30, 0xfa, 0x08, 0x4a, 0x1d, 0x40, 0xaa, 0xb0, 0x06, + 0xbb, 0x55, 0x82, 0xd4, 0x2c, 0xa4, 0x21, 0x80, 0x7c, 0x20, 0x76, 0x83, 0x20, 0xeb, 0xb5, 0x5f, + 0xb0, 0x10, 0xc2, 0xe0, 0x1b, 0x00, 0xe9, 0x2c, 0x47, 0xb1, 0x01, 0x0b, 0x8f, 0x56, 0xaf, 0x5f, + 0xaa, 0xcd, 0x6a, 0x9d, 0xca, 0xa3, 0x84, 0xf5, 0x10, 0xed, 0xc0, 0x70, 0x75, 0x60, 0x21, 0xf5, + 0xe0, 0x35, 0x6c, 0x13, 0xbf, 0x56, 0xfe, 0xb5, 0x72, 0xe0, 0xd5, 0xc0, 0x65, 0x7f, 0xea, 0xd1, + 0x20, 0x14, 0x0f, 0x84, 0xff, 0x6e, 0x7a, 0x10, 0xe0, 0xfe, 0x90, 0x27, 0x6a, 0x1f, 0x97, 0x82, + 0x7e, 0x19, 0x20, 0x03, 0x8f, 0x86, 0x01, 0xe7, 0xbf, 0xeb, 0x43, 0xe6, 0x00, 0x49, 0x50, 0x38, + 0x7f, 0x9c, 0xff, 0xfd, 0xbc, 0x3d, 0x13, 0x5a, 0xa9, 0x38, 0x78, 0xf9, 0xce, 0xf0, 0x71, 0x40, + 0x05, 0x1a, 0x2f, 0x0f, 0x7f, 0xff, 0xf9, 0xd8, 0x07, 0xe2, 0x9b, 0x50, 0x80, 0x33, 0x47, 0xc7, + 0x00, 0xd5, 0x87, 0x54, 0x0c, 0x30, 0x61, 0xf8, 0xdf, 0xfe, 0xc0, 0xf1, 0x6e, 0xa3, 0x85, 0x0c, + 0x03, 0x1c, 0x10, 0x0a, 0xc8, 0x4b, 0xeb, 0xab, 0xfd, 0x37, 0x4e, 0x77, 0xfe, +}; +const uint8_t _A_Levelup1_128x64_6[] = { + 0x01, 0x00, 0x38, 0x02, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, + 0xf0, 0x07, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, 0x5f, 0x78, 0x37, + 0x20, 0x3f, 0xc0, 0x7e, 0x4f, 0xff, 0xde, 0x3e, 0x38, 0xae, 0xf9, 0xf0, 0x5c, 0xe8, 0x7e, 0xf8, + 0xf3, 0x3c, 0x45, 0x83, 0xdc, 0x1f, 0xb8, 0x6e, 0x23, 0x01, 0xfd, 0x1f, 0xdc, 0x0a, 0x09, 0x01, + 0xfd, 0x03, 0xaa, 0xff, 0x01, 0x07, 0x8f, 0xd0, 0x1f, 0x5b, 0xf8, 0x00, 0x3c, 0x7d, 0x00, 0xfa, + 0xaf, 0x83, 0xcb, 0xa0, 0x0e, 0x9f, 0xb8, 0x3c, 0x60, 0x50, 0x20, 0x7d, 0xcb, 0xc1, 0xe5, 0xa0, + 0xdb, 0x83, 0xe3, 0xc6, 0x0f, 0x4d, 0xff, 0xdc, 0x3f, 0x11, 0x70, 0x79, 0x50, 0x23, 0xe0, 0xe7, + 0xfe, 0x83, 0xd7, 0x7e, 0x2f, 0x8f, 0xe4, 0x2e, 0x00, 0x80, 0x1c, 0x06, 0xf9, 0x1b, 0x1f, 0xcc, + 0x5c, 0x1c, 0x1e, 0x38, 0xfd, 0xf6, 0x0f, 0xbe, 0xb3, 0x5b, 0xfd, 0xf2, 0x97, 0x08, 0xff, 0xe1, + 0xf2, 0x1e, 0xec, 0x38, 0xfd, 0xff, 0x12, 0x5c, 0x84, 0x06, 0x99, 0x20, 0xfa, 0xff, 0x81, 0xed, + 0xfb, 0xfd, 0xc9, 0x6a, 0x10, 0x0a, 0x84, 0x80, 0x58, 0x9e, 0xf3, 0x7a, 0x55, 0x66, 0x12, 0x0b, + 0x05, 0x40, 0x1e, 0x5f, 0x11, 0x0b, 0x75, 0x66, 0x12, 0x2b, 0x15, 0x63, 0x7a, 0x07, 0x1f, 0x80, + 0xf4, 0xca, 0x05, 0xd5, 0x88, 0x48, 0xa8, 0x55, 0x80, 0x40, 0xdf, 0x3e, 0x1f, 0x30, 0x60, 0xff, + 0xb0, 0xfe, 0x3f, 0xf0, 0x3d, 0x6e, 0xf1, 0xef, 0xc7, 0xec, 0x40, 0x58, 0x7e, 0x1f, 0xbf, 0xab, + 0x11, 0x80, 0x50, 0x2b, 0x81, 0xf1, 0x87, 0xff, 0x0c, 0x49, 0x07, 0xc1, 0xf5, 0x63, 0xf0, 0x0e, + 0x05, 0x7c, 0x7e, 0x30, 0x70, 0x71, 0x35, 0x0a, 0x7f, 0x02, 0xd2, 0xe7, 0xff, 0xfc, 0xf9, 0x78, + 0x7c, 0x7c, 0x7f, 0xf8, 0xf8, 0x44, 0xaf, 0xb7, 0xeb, 0x14, 0x92, 0x9f, 0x00, 0xe8, 0x49, 0xf9, + 0xb3, 0xdf, 0x01, 0x64, 0x40, 0x42, 0x1e, 0x1f, 0xe5, 0xda, 0x89, 0x30, 0x80, 0x58, 0x22, 0x1f, + 0x58, 0xff, 0xe2, 0xf7, 0xfc, 0xf0, 0x83, 0xca, 0x01, 0x78, 0xc2, 0x0f, 0xca, 0x1f, 0xfd, 0x87, + 0xff, 0xaf, 0xbf, 0xc1, 0x90, 0xff, 0xe3, 0xb0, 0x0f, 0x84, 0x12, 0x20, 0x5f, 0x18, 0x07, 0xf5, + 0x56, 0x5f, 0xcf, 0xfe, 0xff, 0xbf, 0x18, 0x07, 0x94, 0x82, 0x00, 0x01, 0x1f, 0xe8, 0x30, 0x7f, + 0xbe, 0xcf, 0xf5, 0xef, 0xfd, 0x38, 0x83, 0x70, 0xa0, 0xa0, 0xf3, 0x80, 0xfe, 0x38, 0x56, 0xf0, + 0x90, 0xff, 0xff, 0x31, 0x08, 0x7c, 0x10, 0x3e, 0x80, 0xf1, 0xa1, 0x9b, 0x87, 0xef, 0xfd, 0xf9, + 0xc0, 0x20, 0xf1, 0x88, 0x30, 0xf4, 0x48, 0x23, 0x03, 0xbf, 0x79, 0xe0, 0x7f, 0xe2, 0x18, 0xfc, + 0xf8, 0x10, 0x3f, 0x80, 0x3d, 0x67, 0x90, 0x18, 0x04, 0x73, 0xf8, 0x10, 0x1d, 0x9c, 0x0e, 0xe1, + 0x05, 0xe0, 0x40, 0x0a, 0xa3, 0x05, 0x41, 0x8c, 0x00, 0x04, 0x2f, 0x21, 0xa5, 0xc3, 0xb2, 0x10, + 0x4c, 0x07, 0xe6, 0x19, 0x00, 0x84, 0xc0, 0x32, 0x00, 0xf1, 0x80, 0x78, 0x3d, 0xf8, 0xb8, 0x0d, + 0x80, 0x1e, 0x30, 0x78, 0x7c, 0x02, 0x63, 0x00, 0xc6, 0x29, 0x87, 0xe0, 0xb0, 0x18, 0x5c, 0x3a, + 0x31, 0x04, 0x2e, 0x08, 0x08, 0x78, 0x38, 0x0c, 0x1e, 0xe2, 0x01, 0xfe, 0xf8, 0x83, 0xc7, 0xe1, + 0x07, 0x06, 0x0c, 0x1a, 0x06, 0x12, 0x1b, 0xfe, 0x03, 0x01, 0x0f, 0xf7, 0x7f, 0xfd, 0x91, 0x71, + 0xa0, 0x83, 0xc7, 0xf0, 0x3a, 0x25, 0x98, 0xf0, 0x21, 0x69, 0x01, 0xe0, 0x83, 0xd0, 0x00, 0x80, + 0xf1, 0x88, 0xf6, 0x3f, 0x18, 0x79, 0x78, 0x3e, 0x14, 0x62, 0x6e, 0x1b, 0xc4, 0x7e, 0x4e, 0x0f, + 0xaf, 0x85, 0xc7, 0xf1, 0x3f, 0xa1, 0x83, 0x14, 0x00, 0x4a, 0x31, 0xf0, 0x40, 0xc1, 0xe3, 0x87, + 0x07, 0xc7, 0x20, 0x04, 0x30, 0xee, 0x7c, 0xbe, 0x06, 0xb6, 0x10, 0x02, 0x01, 0x87, 0xe9, 0xc3, + 0x87, 0xfe, 0x23, 0x77, 0xc8, 0x2c, 0x18, 0x7e, 0xa0, 0xf1, 0xfd, 0xf9, 0xe3, 0xf7, 0x0b, 0xdf, + 0xf0, 0xf6, 0x40, 0xf5, 0xfc, 0x5c, 0x27, 0x93, 0xc5, 0x70, 0xff, 0xc0, +}; +const uint8_t _A_Levelup1_128x64_7[] = { + 0x01, 0x00, 0xd0, 0x01, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, + 0xf0, 0x07, 0x80, 0x3c, 0x01, 0xe0, 0x05, 0xfd, 0x83, 0xfb, 0xbe, 0x20, 0xf0, 0xff, 0x83, 0x72, + 0x01, 0xfe, 0x07, 0xdf, 0xf6, 0x3f, 0xff, 0xf8, 0x83, 0xf3, 0xcf, 0x03, 0xe7, 0x40, 0xff, 0xc0, + 0xf9, 0xfc, 0x46, 0x61, 0x93, 0x00, 0xfe, 0x41, 0xa2, 0x1c, 0x0e, 0xf0, 0x3e, 0xaf, 0xb0, 0x19, + 0x06, 0x03, 0xba, 0x0f, 0xad, 0xfc, 0x02, 0x81, 0x00, 0xed, 0x83, 0xea, 0xbe, 0x0f, 0x2f, 0xa8, + 0x3e, 0xa5, 0xf0, 0x0c, 0x04, 0x03, 0xd4, 0x0f, 0xdf, 0xc7, 0xad, 0xb5, 0x51, 0x70, 0x78, 0xc1, + 0xfa, 0xdb, 0xf0, 0x84, 0xc5, 0xff, 0xdc, 0x08, 0x07, 0x60, 0x3f, 0x50, 0xb8, 0x0c, 0x86, 0x81, + 0xb0, 0x0f, 0xcf, 0xef, 0x17, 0x7c, 0x89, 0x50, 0x37, 0x00, 0xfa, 0xa5, 0xe0, 0xa1, 0x98, 0x20, + 0x7d, 0x78, 0x28, 0xb1, 0xd8, 0x2e, 0x0a, 0xa0, 0xe3, 0x10, 0xfc, 0x49, 0x63, 0xf0, 0x9c, 0x25, + 0xc2, 0x17, 0xfa, 0x07, 0xc6, 0x97, 0x3d, 0x0a, 0x82, 0x5f, 0xc3, 0xf3, 0xff, 0xd2, 0xff, 0xa1, + 0x5c, 0x0b, 0x81, 0x3e, 0xb4, 0x40, 0xf1, 0x98, 0x78, 0x37, 0xc1, 0xf9, 0x07, 0x94, 0x23, 0x81, + 0xbe, 0xff, 0x03, 0xe2, 0x85, 0xff, 0x85, 0x41, 0xb0, 0x00, 0xe1, 0xfe, 0x83, 0x56, 0x7e, 0x0f, + 0x1b, 0xef, 0x36, 0x03, 0x9c, 0x17, 0xc5, 0xff, 0xdd, 0x82, 0xfd, 0x4f, 0xe0, 0x1a, 0x3e, 0xf0, + 0xfe, 0x70, 0x51, 0xc8, 0x07, 0x03, 0x80, 0x3e, 0x9f, 0xfc, 0x0a, 0x17, 0x00, 0x90, 0x70, 0x3f, + 0xbf, 0x70, 0x7c, 0xc1, 0x20, 0x11, 0x0a, 0x01, 0x34, 0x7d, 0xe3, 0xe5, 0x03, 0x88, 0x3c, 0xa1, + 0x00, 0xf2, 0xf1, 0x87, 0xe6, 0x03, 0x06, 0x90, 0x03, 0xc7, 0xf7, 0xe7, 0x07, 0xbc, 0x03, 0x0d, + 0x01, 0x07, 0x90, 0x81, 0x7f, 0x00, 0xf3, 0xbc, 0x10, 0x04, 0x1e, 0x5f, 0x10, 0x79, 0xfc, 0x11, + 0xe2, 0x0f, 0x10, 0x00, 0xc2, 0x01, 0xe3, 0x7f, 0x50, 0x27, 0x82, 0x7f, 0xdc, 0x07, 0x9c, 0x10, + 0x18, 0x84, 0x12, 0x07, 0x8f, 0xf0, 0x1e, 0x70, 0x2f, 0xec, 0xfd, 0x22, 0x5e, 0x00, 0x10, 0xf0, + 0x7f, 0x82, 0xf4, 0x80, 0xef, 0x63, 0xe0, 0xf1, 0xdf, 0x94, 0x4a, 0x0f, 0xf0, 0x07, 0xa4, 0x03, + 0xfb, 0xc7, 0xff, 0xfd, 0xe1, 0xe2, 0x22, 0x8f, 0xf2, 0x2f, 0xf0, 0x10, 0x79, 0xfe, 0xc7, 0xc5, + 0x71, 0xe0, 0x28, 0x0c, 0x1e, 0xfc, 0xf0, 0x58, 0xe0, 0x4a, 0x87, 0xbe, 0x07, 0x1c, 0x03, 0xeb, + 0xff, 0xdb, 0x8f, 0x08, 0xc4, 0x7b, 0xf0, 0x7b, 0x52, 0xc1, 0x83, 0x0f, 0xff, 0xfc, 0xf3, 0x7f, + 0xfa, 0x78, 0x3d, 0x3d, 0x3f, 0xfa, 0x20, 0x3c, 0x71, 0xea, 0x31, 0xb2, 0xff, 0xa6, 0x60, 0xf4, + 0xc8, 0xc7, 0xe8, 0x7d, 0x01, 0xe9, 0xe1, 0x60, 0x30, 0xc0, 0x7a, 0x58, 0x7c, 0x14, 0x0f, 0x07, + 0x84, 0xc8, 0x50, 0x5f, 0xf4, 0x0c, 0x1e, 0x98, 0x18, 0xfc, 0x82, 0x00, 0x6e, 0x38, 0x28, 0x35, + 0x14, 0x05, 0x00, 0x90, 0x7c, 0x20, 0x7f, 0xe4, 0x80, 0xc2, 0xd7, 0x64, 0x0f, 0x58, 0x87, 0xc1, + 0x64, 0x39, 0xff, 0xfc, 0x20, 0x1f, 0x31, 0x8b, 0xf6, 0x78, 0xe0, 0x31, 0x70, 0x7c, 0x5a, 0x26, + 0x1f, 0x8c, 0x7a, 0x40, 0x41, 0xf3, 0xf4, 0xf0, 0x40, 0x70, 0x04, 0xf1, 0x97, 0x83, 0xe3, 0xf5, + 0xe1, 0x83, 0x98, 0x08, +}; +const uint8_t _A_Levelup1_128x64_8[] = { + 0x01, 0x00, 0xe6, 0x01, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, + 0xf0, 0x07, 0x80, 0x3c, 0x00, 0xbf, 0xb0, 0x7f, 0x88, 0x3c, 0x3f, 0xe1, 0x0f, 0x00, 0x5c, 0x3f, + 0xc0, 0x1f, 0xdf, 0x8c, 0x7c, 0x1f, 0x97, 0xfb, 0xf7, 0x83, 0xf8, 0x21, 0x10, 0x04, 0xe7, 0xf0, + 0x30, 0x7f, 0x98, 0x7e, 0xed, 0xf0, 0x08, 0x47, 0xb0, 0x1e, 0x7c, 0xf8, 0x4c, 0xcb, 0xe6, 0x0f, + 0x38, 0xbc, 0x02, 0x21, 0xd0, 0x03, 0x9e, 0x3f, 0x93, 0x33, 0x07, 0xa4, 0x2e, 0x01, 0x20, 0xdc, + 0x07, 0xcc, 0x1e, 0xf0, 0x50, 0x78, 0xd1, 0x80, 0xe7, 0x4f, 0x84, 0xc9, 0xbf, 0x20, 0x62, 0xff, + 0x40, 0xa0, 0x14, 0x0c, 0x0f, 0xfb, 0xde, 0x0f, 0x2e, 0x4c, 0x9c, 0x1e, 0xdc, 0x08, 0x07, 0xf4, + 0x1e, 0x5c, 0xfe, 0x44, 0x1f, 0xf0, 0x7e, 0x38, 0x0f, 0xfa, 0x81, 0x10, 0xfe, 0xf1, 0xc1, 0xe7, + 0xcf, 0xfe, 0x03, 0xca, 0xfd, 0x01, 0x80, 0xc8, 0x64, 0x1f, 0xa0, 0xf9, 0xc2, 0x79, 0xc0, 0xf2, + 0xbf, 0xff, 0x30, 0x17, 0xc8, 0x95, 0x00, 0x1e, 0x60, 0x06, 0xdf, 0x50, 0x30, 0x51, 0x4a, 0x0c, + 0x11, 0x3d, 0x3b, 0xe9, 0x04, 0x7e, 0x13, 0x42, 0xfe, 0x0e, 0x4c, 0x00, 0xb5, 0xfd, 0x04, 0xce, + 0x15, 0x04, 0x83, 0x24, 0x07, 0x9f, 0x83, 0xce, 0x48, 0x29, 0xff, 0x20, 0x78, 0xd7, 0xb4, 0x16, + 0x38, 0x94, 0x12, 0x03, 0xf4, 0x07, 0x8f, 0xcf, 0x39, 0x3c, 0x07, 0x98, 0x7c, 0x6e, 0x71, 0x44, + 0x00, 0xfa, 0x01, 0xe5, 0xc9, 0x07, 0xb7, 0xfe, 0x29, 0x20, 0x07, 0x9e, 0x0f, 0x92, 0x2f, 0x40, + 0x79, 0xc6, 0x30, 0x1e, 0xb0, 0xfa, 0x5b, 0xda, 0xe4, 0x0f, 0x38, 0x3d, 0x83, 0xd8, 0x0f, 0x2f, + 0x18, 0x3d, 0x64, 0x1f, 0xfe, 0x94, 0x02, 0x30, 0x3f, 0x30, 0x78, 0x9b, 0xd2, 0x81, 0xfe, 0x9d, + 0xc0, 0x20, 0x80, 0xf1, 0x87, 0xe0, 0xbe, 0xf2, 0x0a, 0x40, 0xfc, 0xf0, 0x11, 0xc8, 0x64, 0x02, + 0x04, 0x6f, 0x14, 0x7c, 0x40, 0x20, 0xb0, 0x88, 0x01, 0xfc, 0x81, 0xf3, 0x02, 0x80, 0x1f, 0xc7, + 0xf4, 0x0f, 0xc9, 0x80, 0x3f, 0x30, 0x10, 0x02, 0x00, 0xff, 0x41, 0xf5, 0x00, 0xc1, 0xc0, 0xf0, + 0x1f, 0xe0, 0x7d, 0xdf, 0x20, 0x14, 0x00, 0x41, 0x43, 0xc1, 0x03, 0x80, 0x07, 0xa8, 0x00, 0x54, + 0x62, 0x00, 0x1f, 0x98, 0x08, 0x6f, 0xe0, 0xf7, 0xe8, 0x02, 0x0a, 0x1a, 0x1f, 0x21, 0xb1, 0x03, + 0xd3, 0xb0, 0x0f, 0x28, 0x30, 0x1c, 0x8a, 0xc4, 0x0f, 0x4e, 0xa0, 0x3f, 0x85, 0xe7, 0x06, 0xce, + 0x62, 0x01, 0xe7, 0x4f, 0x07, 0xc6, 0x8b, 0x09, 0x01, 0x07, 0x8e, 0xfe, 0x5e, 0x5f, 0x70, 0x78, + 0xe0, 0xa0, 0x61, 0xf2, 0x07, 0xa5, 0x80, 0x1e, 0x98, 0x18, 0x38, 0x3c, 0xa2, 0xe0, 0xf4, 0xef, + 0xef, 0xc3, 0xee, 0x0f, 0x4d, 0x01, 0xe0, 0x7f, 0xc3, 0xf5, 0xff, 0xc2, 0xc1, 0xed, 0xfc, 0x2f, + 0xaf, 0x7e, 0x0a, 0x0f, 0x39, 0x00, 0x60, 0x8f, 0xe9, 0xf7, 0xf8, 0xbf, 0x44, 0x00, 0x54, 0x0f, + 0xd0, 0x40, 0x51, 0xeb, 0x78, 0x80, 0x83, 0xd3, 0xe8, 0x1f, 0x18, 0x72, 0xfd, 0x33, 0xe0, 0xe3, + 0x07, 0x8f, 0x20, 0x1e, 0x23, 0x22, 0x6f, 0x95, 0x9c, 0x1e, 0xb3, 0x0f, 0xff, 0xe3, 0xf6, 0x0c, + 0x13, 0xa0, 0xff, 0xe3, 0x34, 0x00, 0x7a, 0x70, 0x20, 0x1f, 0x78, 0x38, 0x18, 0x78, 0x1f, 0xf8, + 0x0c, 0x18, 0x1e, 0xb0, 0x0f, 0xff, 0xa1, 0x44, 0x40, 0x01, 0xff, 0x40, 0x41, 0xed, 0x00, 0xf4, + 0x7f, 0x7b, 0xe0, 0xf2, 0x2e, 0x88, 0x3e, 0x3c, 0x61, 0xf3, +}; +const uint8_t _A_Levelup1_128x64_9[] = { + 0x01, 0x00, 0xd6, 0x01, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, + 0xf0, 0x07, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x01, 0x3d, 0xe0, 0xff, 0x06, 0xe4, 0x0f, + 0xf0, 0x0f, 0xab, 0xf8, 0x04, 0x7f, 0x9c, 0x7c, 0x18, 0x7a, 0xf3, 0xf0, 0xf9, 0xc0, 0x7f, 0x2c, + 0xff, 0x0e, 0x07, 0xb8, 0x1f, 0x71, 0xb8, 0x04, 0x0f, 0xda, 0x09, 0x3e, 0x7c, 0x26, 0x65, 0xf3, + 0x07, 0x9c, 0x16, 0x01, 0x0c, 0xfd, 0x03, 0xcf, 0x1f, 0xc9, 0x99, 0x83, 0xd2, 0x05, 0x00, 0x88, + 0x71, 0x0e, 0x26, 0x0f, 0x59, 0x7d, 0xea, 0x03, 0x00, 0x90, 0x6f, 0x81, 0xe7, 0x4f, 0x84, 0xc9, + 0xbf, 0x21, 0xf2, 0xdf, 0xc0, 0x20, 0x14, 0x0a, 0x08, 0x3d, 0x39, 0x32, 0x70, 0x7b, 0x60, 0x30, + 0x1f, 0xee, 0x39, 0x3c, 0xb9, 0x10, 0x7f, 0xc0, 0x3c, 0xab, 0xf0, 0x09, 0xfd, 0x03, 0x21, 0xfe, + 0x80, 0x83, 0xcf, 0x9f, 0xfc, 0x2b, 0x15, 0x7f, 0x81, 0xc0, 0x90, 0x48, 0x3f, 0xa1, 0xf3, 0x84, + 0xf3, 0x81, 0xe5, 0x7f, 0x97, 0xc8, 0x23, 0xd1, 0x10, 0x78, 0xa8, 0x66, 0x5f, 0x90, 0xb0, 0xc2, + 0xa4, 0x3c, 0x20, 0x7d, 0x54, 0x33, 0xf0, 0x68, 0x14, 0xe8, 0x1f, 0x31, 0x7e, 0x46, 0xce, 0x09, + 0x02, 0xe3, 0x7f, 0x87, 0xc3, 0x83, 0xce, 0x48, 0x29, 0xff, 0x20, 0x79, 0x7a, 0x2c, 0x70, 0x5c, + 0x14, 0x07, 0xfa, 0x0f, 0x1f, 0x9e, 0x72, 0x78, 0x0f, 0x5b, 0x9c, 0x16, 0x81, 0x00, 0x60, 0x88, + 0x3c, 0x79, 0x20, 0xf6, 0xbf, 0xc1, 0x66, 0x00, 0xf3, 0xc1, 0xf2, 0x45, 0xec, 0x0f, 0x18, 0x67, + 0x03, 0xf6, 0x1f, 0x4b, 0x78, 0x18, 0x7f, 0xf0, 0xbe, 0x47, 0xfe, 0x09, 0x03, 0xf8, 0x03, 0xcf, + 0xc6, 0x0f, 0x5e, 0x87, 0xff, 0x85, 0x00, 0xfc, 0x5f, 0x41, 0xe8, 0x6f, 0x38, 0x5e, 0x42, 0x1f, + 0x3f, 0x80, 0x7f, 0x27, 0xdf, 0xe8, 0x7e, 0x0b, 0xef, 0x20, 0xa4, 0x0f, 0xca, 0x17, 0x20, 0x81, + 0x41, 0x20, 0x17, 0xfb, 0xfa, 0x3e, 0x21, 0x7c, 0x08, 0x0b, 0xc0, 0x77, 0xe0, 0xe8, 0x07, 0x8c, + 0x00, 0x1e, 0x3e, 0x0e, 0xf8, 0x3a, 0x3e, 0xe0, 0xf3, 0xfc, 0x2f, 0xa4, 0x1e, 0x49, 0xd1, 0xe7, + 0x40, 0xd7, 0xe2, 0x00, 0x6f, 0x18, 0x3c, 0x70, 0x1c, 0x18, 0x1f, 0xfd, 0x7e, 0x21, 0xf9, 0x80, + 0x7f, 0xa0, 0x28, 0xf2, 0xff, 0xc3, 0xc1, 0x03, 0x80, 0x07, 0xa8, 0x40, 0x61, 0xeb, 0xf1, 0xff, + 0xfc, 0xc0, 0x42, 0x75, 0x30, 0x79, 0x80, 0x04, 0x1e, 0x50, 0xd0, 0xf9, 0x11, 0x88, 0x1e, 0xa2, + 0xf2, 0x83, 0x01, 0x88, 0x8c, 0x40, 0xf4, 0xe0, 0x7f, 0x01, 0xfb, 0x30, 0x1c, 0x14, 0x1b, 0x39, + 0x88, 0x07, 0xc7, 0x38, 0x1e, 0x7a, 0x2c, 0x24, 0x04, 0x1e, 0xdc, 0x01, 0xf1, 0x03, 0xcb, 0x05, + 0x03, 0x07, 0xb7, 0xf0, 0x1e, 0xb8, 0x18, 0x38, 0x3c, 0xa0, 0xa0, 0xf2, 0xfc, 0x07, 0xe8, 0x1e, + 0x7e, 0x0f, 0xa8, 0xfe, 0x41, 0xe7, 0x00, 0xfa, 0x17, 0xe6, 0x04, 0x0f, 0x3f, 0x60, 0x3c, 0xcf, + 0xea, 0x0f, 0xeb, 0xfc, 0x04, 0x1e, 0x7d, 0x80, 0x79, 0x43, 0x97, 0xe8, 0x0f, 0x91, 0x59, 0x37, + 0xcb, 0x7e, 0xce, 0x4d, 0x40, 0x3c, 0x8e, 0x65, 0xbf, 0x07, 0x9d, 0x00, 0x1e, 0xd0, 0x75, 0x39, + 0x01, 0x46, 0xbe, 0x0f, 0x4a, 0x40, 0x3c, 0x80, 0x0b, 0x2f, 0x80, 0x48, 0x01, 0xe5, 0x88, 0x24, + 0x08, 0x01, 0xa2, 0xe0, 0xf4, 0x84, 0x13, 0x08, 0x00, 0x80, +}; +const uint8_t _A_Levelup1_128x64_10[] = { + 0x01, 0x00, 0xde, 0x01, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, + 0xf0, 0x07, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x09, 0xef, 0x06, 0xe4, 0x0f, + 0xf0, 0x0f, 0xcb, 0xff, 0xf3, 0x8f, 0xc7, 0x07, 0xde, 0x7e, 0x1f, 0x38, 0x0f, 0xe5, 0x9f, 0xe1, + 0xc0, 0xf7, 0x03, 0xee, 0x37, 0x00, 0x81, 0xff, 0x4a, 0x27, 0xcf, 0x84, 0xcc, 0xbe, 0x63, 0xd2, + 0xff, 0xc1, 0x60, 0x10, 0xcf, 0xd0, 0x5c, 0xf1, 0xfc, 0x99, 0x98, 0x3d, 0x20, 0x50, 0x08, 0x87, + 0x10, 0x3e, 0x60, 0xf5, 0x9f, 0xdf, 0xa0, 0x30, 0x09, 0x06, 0xf8, 0x1e, 0x74, 0xf8, 0x4c, 0x9b, + 0xf2, 0x1f, 0x2d, 0xfc, 0x02, 0x01, 0x40, 0xa0, 0xff, 0xce, 0x25, 0x4f, 0xe4, 0xc9, 0xc1, 0xed, + 0x80, 0xc0, 0x7f, 0xb5, 0x64, 0xf2, 0xe4, 0x41, 0xff, 0x04, 0x62, 0xaf, 0xc0, 0x27, 0xf4, 0x0c, + 0x85, 0xfa, 0x22, 0x62, 0x10, 0x78, 0xf3, 0xff, 0x80, 0xf3, 0xe0, 0x70, 0x24, 0x12, 0x0f, 0xe8, + 0x7c, 0xe1, 0x3c, 0xe0, 0x79, 0xcb, 0xe4, 0x11, 0xe8, 0x88, 0x3c, 0x56, 0x33, 0x2f, 0xc8, 0x58, + 0x61, 0x52, 0x1e, 0x12, 0xc6, 0x3f, 0xd2, 0xfa, 0x86, 0x7e, 0x0d, 0x02, 0x9d, 0x2b, 0xa6, 0x2f, + 0xc8, 0xd9, 0xc1, 0x20, 0x5c, 0x66, 0x08, 0xf3, 0xf0, 0x79, 0xc9, 0x05, 0x3f, 0xe4, 0x1f, 0x18, + 0xbf, 0xa2, 0xc7, 0x05, 0xc1, 0x40, 0x4b, 0xc5, 0xf3, 0xce, 0x4f, 0x01, 0xeb, 0x73, 0x82, 0xd0, + 0x20, 0x0c, 0x11, 0x07, 0x8f, 0x24, 0x1e, 0xd7, 0xf8, 0x2c, 0xc0, 0x1e, 0x78, 0x3e, 0x48, 0xbc, + 0xab, 0xff, 0x40, 0x79, 0xc3, 0x38, 0x1f, 0xb0, 0xfa, 0x5b, 0xc0, 0xc3, 0xfe, 0x85, 0xf2, 0x3f, + 0xf0, 0x48, 0x1f, 0xc0, 0x1e, 0x7e, 0x30, 0x7a, 0xf4, 0x3f, 0xfc, 0x28, 0x07, 0xe0, 0x9e, 0x60, + 0xf1, 0x37, 0x9c, 0x2f, 0x21, 0x0f, 0x9f, 0xc0, 0x3f, 0x9f, 0xef, 0xfc, 0x3f, 0x05, 0xf7, 0x90, + 0x52, 0x09, 0xe5, 0x0b, 0x90, 0x40, 0xa0, 0x90, 0x0b, 0xfa, 0x3e, 0x61, 0x7c, 0x08, 0x0b, 0xc0, + 0x77, 0xe0, 0xfa, 0x80, 0x03, 0xc7, 0xc1, 0xdf, 0x07, 0xef, 0xe1, 0x9d, 0x00, 0xf3, 0x4e, 0x8f, + 0x3a, 0x06, 0x4f, 0x10, 0x03, 0x7d, 0xc1, 0xe3, 0x80, 0xe0, 0xc0, 0xff, 0xe6, 0xf1, 0x0f, 0xcc, + 0x03, 0xfd, 0x01, 0x47, 0x91, 0xc0, 0x41, 0x03, 0x80, 0x07, 0xa8, 0x40, 0x61, 0xeb, 0xf1, 0xff, + 0xfc, 0xc0, 0x42, 0x76, 0x30, 0x79, 0x80, 0x04, 0x1e, 0x50, 0xd0, 0xf9, 0x11, 0x88, 0x1e, 0xa2, + 0xf2, 0x83, 0x01, 0x88, 0x8c, 0x40, 0xf4, 0xe0, 0x7f, 0x01, 0xfb, 0x30, 0x1c, 0x94, 0x1b, 0x39, + 0x88, 0x07, 0xc7, 0x38, 0x1e, 0x7a, 0x2c, 0x24, 0x04, 0x1e, 0xdc, 0x0f, 0xdc, 0xfc, 0x92, 0x20, + 0xf1, 0xc1, 0x40, 0xc1, 0xed, 0xfc, 0xfd, 0x87, 0xd3, 0x03, 0x07, 0x07, 0x94, 0x14, 0x1e, 0x5f, + 0x80, 0x7a, 0x87, 0xd0, 0x1e, 0x7e, 0x0f, 0xaa, 0x20, 0x87, 0xec, 0x0f, 0x38, 0x07, 0xd0, 0x1e, + 0x65, 0xf5, 0x81, 0x03, 0xcf, 0xd8, 0x0f, 0x33, 0xfa, 0x83, 0xfa, 0xff, 0x01, 0x07, 0x9f, 0x60, + 0x1e, 0x50, 0xe5, 0xfa, 0x03, 0xe4, 0x56, 0x46, 0x52, 0xdf, 0xb3, 0x93, 0x50, 0x0f, 0x26, 0x91, + 0x6f, 0xc1, 0xe7, 0x40, 0x07, 0xb4, 0x1d, 0x4e, 0x40, 0x51, 0xaf, 0x83, 0xd2, 0x90, 0x0f, 0x20, + 0x02, 0xcb, 0xe0, 0x12, 0x00, 0x79, 0x62, 0x09, 0x02, 0x00, 0x68, 0xb8, 0x3d, 0x21, 0x04, 0xc2, + 0x00, 0x20, +}; +const uint8_t* const _A_Levelup1_128x64[] = { + _A_Levelup1_128x64_0, + _A_Levelup1_128x64_1, + _A_Levelup1_128x64_2, + _A_Levelup1_128x64_3, + _A_Levelup1_128x64_4, + _A_Levelup1_128x64_5, + _A_Levelup1_128x64_6, + _A_Levelup1_128x64_7, + _A_Levelup1_128x64_8, + _A_Levelup1_128x64_9, + _A_Levelup1_128x64_10}; + +const uint8_t _A_Levelup2_128x64_0[] = { + 0x01, 0x00, 0x34, 0x01, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, + 0xf0, 0x07, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, 0x38, 0x1f, 0xe0, + 0x1d, 0x97, 0xff, 0xe7, 0x1c, 0x1f, 0x99, 0xf8, 0x1c, 0xfc, 0x1f, 0x96, 0x7f, 0x87, 0x03, 0xf8, + 0x0f, 0xb8, 0xdc, 0x22, 0x01, 0xfb, 0x07, 0xdc, 0x16, 0x09, 0x00, 0xfa, 0x03, 0xee, 0x1d, 0x02, + 0x80, 0x7a, 0x0b, 0xd7, 0x31, 0x07, 0x8f, 0x40, 0x1f, 0x5b, 0xfa, 0x04, 0x06, 0x01, 0xa0, 0x07, + 0xd5, 0x7f, 0x00, 0x0f, 0xe8, 0x26, 0x06, 0x7f, 0x40, 0x07, 0xd4, 0xbe, 0x05, 0x42, 0xa0, 0x03, + 0xf2, 0x03, 0x24, 0xcf, 0xe0, 0x3f, 0xc5, 0xe9, 0x88, 0x50, 0x72, 0x92, 0x0c, 0x08, 0x3e, 0x73, + 0xf1, 0xf9, 0x0d, 0x22, 0xf9, 0x82, 0x07, 0xcd, 0xbe, 0x61, 0x10, 0x94, 0x79, 0xa0, 0x5f, 0xd0, + 0x7c, 0x45, 0xe8, 0x11, 0x09, 0x27, 0x8c, 0x1f, 0x50, 0xb3, 0xf0, 0xc5, 0x3c, 0xe0, 0xfb, 0x80, + 0x40, 0xb2, 0x9f, 0xf0, 0x7d, 0x7a, 0xe0, 0x10, 0xc0, 0x7e, 0x46, 0xe0, 0x77, 0x00, 0x7e, 0x42, + 0xe1, 0x98, 0x0d, 0x2d, 0xfc, 0x1f, 0x71, 0x08, 0x05, 0x3a, 0x7f, 0x01, 0x37, 0xd4, 0x81, 0xfa, + 0x39, 0xf8, 0x01, 0xfe, 0xe0, 0x12, 0x0a, 0x40, 0x3e, 0xa5, 0xef, 0xe2, 0x98, 0x03, 0xee, 0x01, + 0x06, 0x80, 0x10, 0x84, 0x1f, 0x35, 0xf8, 0x04, 0x62, 0x00, 0x00, 0x10, 0x7c, 0xef, 0xe0, 0x1e, + 0x00, 0x7e, 0x5f, 0xc7, 0xc3, 0x0f, 0x07, 0xda, 0x6c, 0x43, 0xc4, 0x0f, 0xb8, 0x28, 0x3f, 0xa1, + 0xa0, 0xfe, 0x8a, 0x8b, 0xfc, 0x1f, 0xe0, 0xfe, 0x2f, 0xa7, 0xe8, 0xff, 0x30, 0x30, 0x7f, 0x83, + 0xcf, 0xe8, 0xaf, 0x91, 0x7a, 0x03, 0xff, 0xd0, 0xdf, 0x90, 0x7a, 0x74, 0x1f, 0xf2, 0xcf, 0x10, + 0x01, 0x68, 0x01, 0xf1, 0x17, 0x07, 0xa5, 0x00, 0x1f, 0x10, 0x90, 0x7a, 0x60, 0x3f, 0x80, 0xd5, + 0xc7, 0xdf, 0xe0, 0xc0, 0xf4, 0x80, 0x7c, 0xc1, 0xeb, 0x77, 0xc0, 0x40, 0x41, 0xe9, 0x01, 0xe6, + 0x03, 0xd7, 0x17, 0x7f, 0x05, 0x08, 0x3d, 0x26, 0x18, 0x00, 0x7a, 0x42, 0xc1, 0x44, 0x0f, 0x4e, + 0x05, 0xfc, 0x1f, 0xa5, 0x11, 0xff, 0x03, 0xcc, +}; +const uint8_t _A_Levelup2_128x64_1[] = { + 0x01, 0x00, 0x17, 0x02, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, + 0xf0, 0x07, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x2f, 0xf8, 0x17, 0x59, 0xfe, 0xf8, 0x6b, 0x37, + 0xf9, 0xf0, 0x32, 0x7e, 0xc1, 0xac, 0x02, 0x19, 0xff, 0xfe, 0x03, 0xfc, 0x11, 0x5c, 0xfe, 0x7f, + 0xfe, 0xf1, 0x8c, 0x2e, 0x3d, 0xce, 0x80, 0xe7, 0xbe, 0xff, 0x90, 0x7c, 0xc3, 0xe6, 0x18, 0x0b, + 0x0f, 0xfb, 0xf0, 0x61, 0x8c, 0x7c, 0x3e, 0x19, 0x40, 0xc0, 0x43, 0x6f, 0xc1, 0xe8, 0xbf, 0xe3, + 0xa1, 0x52, 0x08, 0x04, 0x0a, 0xfe, 0x83, 0x7f, 0xdf, 0xf6, 0x09, 0x05, 0x88, 0x40, 0x30, 0x89, + 0x28, 0xfb, 0xfb, 0xf0, 0x10, 0x40, 0x78, 0xca, 0x0f, 0xee, 0x00, 0x18, 0xfd, 0x02, 0x05, 0x08, + 0x80, 0x44, 0x3f, 0xc6, 0x08, 0xbf, 0xd2, 0x3f, 0xc0, 0xf2, 0xfe, 0x7f, 0x41, 0xef, 0xf7, 0x90, + 0x40, 0xe1, 0xf0, 0x09, 0x06, 0xf1, 0x3d, 0x3a, 0x88, 0x04, 0x63, 0xf1, 0xa3, 0xfc, 0x03, 0xe6, + 0xa1, 0x10, 0x90, 0x41, 0x28, 0x80, 0xf1, 0xf3, 0xbe, 0x5a, 0xff, 0xb2, 0x88, 0x50, 0x3f, 0x54, + 0x80, 0x78, 0xb0, 0xda, 0xfb, 0xff, 0xd8, 0x42, 0x30, 0x50, 0x5a, 0x8e, 0xe2, 0x1f, 0xfc, 0xf7, + 0x84, 0x17, 0xf9, 0x68, 0x84, 0x40, 0xbc, 0x79, 0x2f, 0xe7, 0xdc, 0xdf, 0x17, 0x88, 0x46, 0x07, + 0xc5, 0xa3, 0xfe, 0x3c, 0x9e, 0xff, 0x38, 0xfc, 0x41, 0xf0, 0x3e, 0x5d, 0x2f, 0xe0, 0x1e, 0xf2, + 0x78, 0x04, 0xe2, 0x19, 0x80, 0xfe, 0xe9, 0x78, 0x1f, 0x00, 0x7b, 0x61, 0xf4, 0x31, 0xc7, 0xf8, + 0xff, 0x64, 0xb0, 0x9f, 0xe7, 0xff, 0xbe, 0x10, 0x58, 0x1b, 0xf8, 0x81, 0xe3, 0x01, 0xff, 0x6f, + 0xf7, 0xe0, 0xf5, 0xd1, 0xc1, 0x30, 0x18, 0x1f, 0xec, 0x4e, 0x13, 0x8f, 0xfb, 0x83, 0xda, 0x1f, + 0xe4, 0x80, 0x65, 0xbf, 0x71, 0x2c, 0x0f, 0x9f, 0xe7, 0xdf, 0x39, 0x1d, 0xee, 0xfd, 0x9f, 0x8a, + 0x40, 0xfc, 0x17, 0xf8, 0x4f, 0x27, 0xff, 0xfb, 0xf7, 0xb8, 0x8e, 0x7f, 0xfc, 0x9f, 0x43, 0x21, + 0x90, 0x0f, 0x82, 0x08, 0x59, 0xaf, 0xff, 0xcf, 0xc3, 0xa2, 0x10, 0x0c, 0x04, 0x1a, 0x53, 0xe0, + 0x07, 0xa9, 0x10, 0x60, 0x10, 0xa9, 0x04, 0x02, 0x01, 0x01, 0x80, 0x83, 0xda, 0xff, 0x1f, 0xd0, + 0x42, 0xa8, 0x00, 0xf1, 0x80, 0x6a, 0x51, 0xe3, 0xf3, 0x08, 0x26, 0x7a, 0x03, 0x12, 0xc0, 0x40, + 0x44, 0x04, 0x8f, 0x1f, 0x39, 0xfd, 0xa2, 0x50, 0x08, 0x30, 0x7c, 0xbf, 0xdf, 0xfe, 0x79, 0xfd, + 0xa4, 0x50, 0x0b, 0xc0, 0x7c, 0x81, 0xee, 0x96, 0x1a, 0x10, 0xf8, 0x83, 0xe2, 0x2f, 0x1f, 0x7f, + 0xec, 0x1e, 0x7c, 0xf8, 0x5e, 0x08, 0x1e, 0x70, 0x11, 0xf0, 0xa3, 0xd0, 0xfc, 0x3a, 0x38, 0x11, + 0x38, 0x83, 0xe3, 0xf7, 0xf1, 0xab, 0x8d, 0x4a, 0x2d, 0xf1, 0x81, 0x40, 0x81, 0xe5, 0xc1, 0xff, + 0xfc, 0x45, 0xc8, 0x04, 0x1d, 0x38, 0x38, 0xe0, 0x1c, 0x99, 0xff, 0xe0, 0xbc, 0xbf, 0x38, 0x7c, + 0x0c, 0x1e, 0x74, 0x28, 0x79, 0x80, 0x49, 0xc9, 0xc3, 0x97, 0x83, 0xd2, 0x15, 0x06, 0x0f, 0x2c, + 0xde, 0x0f, 0x87, 0x17, 0xa4, 0x12, 0x04, 0x1f, 0x1f, 0x78, 0x3c, 0xa9, 0x70, 0xed, 0x00, 0x3d, + 0x34, 0x92, 0x0c, 0xf6, 0xfc, 0xc0, 0x78, 0xb8, 0xe5, 0x00, 0x1e, 0x90, 0x88, 0x05, 0x9f, 0x3e, + 0x2f, 0x38, 0x5e, 0x0e, 0x44, 0x0f, 0x49, 0x84, 0xab, 0x33, 0xce, 0x07, 0xa4, 0x72, 0x30, 0x0f, + 0x4e, 0x04, 0x03, 0x0c, 0x60, 0x48, 0xbf, 0x82, 0x0e, 0x0f, 0x48, 0x07, 0xff, 0x02, 0x0f, 0x50, + 0x48, 0x83, 0xd6, 0x01, 0x80, 0x07, 0x89, 0x40, 0xa5, 0xe0, 0xf6, 0x61, 0x8d, 0x01, 0x22, 0x80, + 0xfa, 0xb3, 0x03, 0xce, 0x82, 0x0f, 0x89, 0x07, 0x00, 0xfe, 0x78, 0x10, 0x7c, 0xf8, 0x3f, 0x22, + 0x02, 0x81, 0x82, 0x04, 0x1e, 0xd9, 0x0a, 0x17, 0xf0, 0x3e, 0x40, +}; +const uint8_t _A_Levelup2_128x64_2[] = { + 0x01, 0x00, 0xed, 0x02, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x3f, 0xe4, 0x1f, 0xdf, 0x40, + 0x43, 0xf3, 0xc0, 0xa9, 0x7f, 0xfb, 0x03, 0xdf, 0x66, 0x05, 0x4d, 0xff, 0xbc, 0x1e, 0xf3, 0xbf, + 0xf0, 0x14, 0xe3, 0xf7, 0x8f, 0xf7, 0xc4, 0x1e, 0xb1, 0x3f, 0xe0, 0x14, 0xe1, 0xf9, 0x02, 0x0b, + 0xc5, 0xc1, 0xeb, 0xcc, 0xff, 0x03, 0xda, 0x1e, 0x0f, 0x48, 0x3f, 0xbf, 0xfd, 0xf8, 0x07, 0xad, + 0xfc, 0x1e, 0x57, 0xff, 0xf4, 0x0f, 0xe7, 0xff, 0x07, 0xaf, 0x8e, 0xff, 0xf8, 0xed, 0xc7, 0xee, + 0x1f, 0xc8, 0x18, 0x34, 0x41, 0xeb, 0xc3, 0x9f, 0xfc, 0x3f, 0x70, 0xfe, 0x07, 0xfe, 0x01, 0x9c, + 0x0b, 0x88, 0x88, 0x41, 0xe7, 0x1f, 0xc8, 0x5f, 0xe0, 0x7c, 0x08, 0x7c, 0x03, 0xf9, 0x7f, 0x9e, + 0x07, 0xd3, 0x8f, 0x17, 0x80, 0x5e, 0xde, 0xe5, 0x0a, 0xff, 0x4f, 0xe3, 0xc0, 0xf4, 0xc7, 0xcf, + 0xe0, 0x11, 0x32, 0x68, 0x84, 0x07, 0xf7, 0x3f, 0x4b, 0xa7, 0xe2, 0x7f, 0x7f, 0x82, 0x70, 0x20, + 0xb9, 0xdd, 0x54, 0x08, 0x3e, 0x21, 0xe4, 0xfc, 0x4d, 0xff, 0x10, 0xe9, 0x86, 0x22, 0xc0, 0x1f, + 0x1b, 0xf8, 0xb8, 0x58, 0x47, 0xfe, 0x99, 0xda, 0x31, 0xd0, 0xcc, 0x46, 0x03, 0x53, 0x82, 0xbd, + 0xe7, 0x83, 0xe9, 0x3f, 0x99, 0xf0, 0x20, 0x90, 0x28, 0x24, 0x06, 0x05, 0x80, 0xbf, 0xe3, 0x2f, + 0xeb, 0xe5, 0x07, 0x8c, 0x04, 0x02, 0x3a, 0x4e, 0x07, 0xbf, 0x00, 0xa6, 0x25, 0xf1, 0xe0, 0x30, + 0x10, 0x00, 0x78, 0xc2, 0x30, 0x13, 0xc0, 0x79, 0x00, 0x0e, 0xfd, 0x80, 0xa0, 0x03, 0xcb, 0x21, + 0x0a, 0x08, 0x88, 0x39, 0x19, 0x83, 0x00, 0x07, 0x8c, 0x0a, 0x05, 0x10, 0x30, 0x0f, 0x03, 0x7e, + 0x0f, 0x3c, 0xe7, 0xbe, 0x03, 0x20, 0x07, 0x96, 0x82, 0x05, 0x00, 0x90, 0x23, 0xd2, 0x33, 0xff, + 0x07, 0xa0, 0x0c, 0x41, 0xe7, 0xc7, 0x07, 0x8c, 0x6b, 0x9d, 0x01, 0x15, 0x88, 0x3c, 0x68, 0x1a, + 0x88, 0x54, 0x00, 0x18, 0x38, 0xb0, 0x10, 0x9e, 0x04, 0x1e, 0xa1, 0xf1, 0xc7, 0x7f, 0xfc, 0x7f, + 0xd0, 0x78, 0xc1, 0xe0, 0x18, 0x00, 0xc8, 0xa0, 0x07, 0x01, 0xaa, 0x85, 0x36, 0x47, 0xce, 0x3f, + 0x28, 0x69, 0x20, 0x71, 0x10, 0x70, 0x78, 0xe3, 0xc2, 0xc3, 0xff, 0x07, 0x18, 0x00, 0x60, 0x38, + 0x0a, 0x54, 0x23, 0xff, 0x87, 0xc8, 0x68, 0xa1, 0x5f, 0x80, 0x7a, 0x8c, 0x06, 0x49, 0x90, 0x80, + 0xd3, 0x24, 0x01, 0x61, 0xfc, 0xfe, 0xc1, 0xeb, 0x8a, 0x92, 0x54, 0x20, 0x15, 0x09, 0x06, 0xa7, + 0xc0, 0xeb, 0x20, 0x71, 0x5f, 0xe1, 0xf0, 0x0a, 0xa4, 0xc2, 0x41, 0x60, 0xa8, 0x40, 0x7e, 0x1e, + 0xff, 0xe8, 0x3c, 0xa1, 0xff, 0xf8, 0xf4, 0xa3, 0xa9, 0x30, 0x91, 0x58, 0xab, 0x1a, 0x9f, 0x87, + 0x1e, 0xff, 0xde, 0xc7, 0x8b, 0x47, 0xd2, 0x1f, 0x1e, 0xa4, 0x42, 0x45, 0x42, 0xac, 0x07, 0xc7, + 0x8f, 0x3f, 0xff, 0x61, 0xff, 0xff, 0x7e, 0xfc, 0x1f, 0x40, 0x0f, 0x41, 0xf8, 0xf9, 0xdf, 0xa3, + 0xe3, 0x7f, 0x98, 0x7c, 0x62, 0x2e, 0x21, 0xae, 0x40, 0x78, 0x00, 0xc2, 0x4f, 0x91, 0x40, 0x43, + 0xe3, 0x1f, 0x75, 0x8d, 0x7f, 0x53, 0x80, 0xf1, 0xbb, 0xd0, 0x00, 0x30, 0x0d, 0x26, 0x7f, 0xff, + 0xcf, 0x97, 0xc0, 0x60, 0x1f, 0x00, 0x50, 0x82, 0x07, 0xff, 0xf3, 0xfe, 0xe0, 0x64, 0x94, 0xf8, + 0x07, 0x42, 0x4f, 0xa9, 0x81, 0x7f, 0x3e, 0xe0, 0xf2, 0xfe, 0x78, 0x3d, 0xf0, 0x1a, 0x24, 0xc2, + 0x01, 0x60, 0x88, 0x07, 0xc7, 0xfc, 0x0f, 0x10, 0xe8, 0xa4, 0xca, 0x01, 0x84, 0x1f, 0x94, 0x3f, + 0x52, 0xdf, 0x10, 0xf0, 0xf9, 0xfe, 0x3f, 0xfe, 0x3c, 0xf2, 0x01, 0x04, 0x88, 0x17, 0xc5, 0xe4, + 0x30, 0x02, 0x20, 0xf7, 0xfc, 0xff, 0x9f, 0xfc, 0x0a, 0x31, 0xa0, 0x82, 0x48, 0x20, 0x00, 0x11, + 0xd4, 0xe0, 0xb3, 0xfc, 0x7f, 0x3f, 0xcf, 0xf9, 0xff, 0x90, 0xc0, 0x03, 0xe2, 0x0f, 0x36, 0xf8, + 0xc3, 0xf8, 0x3e, 0x7b, 0xc0, 0xf4, 0x6f, 0xf0, 0x00, 0xfa, 0xe0, 0x61, 0x50, 0x7f, 0x05, 0xde, + 0x38, 0x7e, 0x38, 0x04, 0x18, 0x7a, 0x24, 0x11, 0x81, 0x81, 0xc7, 0xc1, 0x13, 0xc0, 0x03, 0x87, + 0x9f, 0x80, 0xd5, 0x03, 0xd3, 0x07, 0x0a, 0x85, 0x7c, 0x20, 0x3e, 0x00, 0x78, 0xed, 0xc2, 0xe3, + 0x05, 0xe0, 0x40, 0x23, 0x00, 0x41, 0x41, 0x8f, 0x81, 0x44, 0x2b, 0x21, 0xa5, 0x6a, 0x31, 0x50, + 0x4c, 0x07, 0xe6, 0x19, 0x00, 0xc4, 0xea, 0xb2, 0x41, 0x91, 0xfc, 0x07, 0xc7, 0x15, 0x01, 0xb0, + 0x03, 0xc6, 0x0e, 0xe4, 0x19, 0x8c, 0x03, 0x18, 0x0f, 0x1d, 0xc7, 0xef, 0xff, 0x08, 0x87, 0x46, + 0x20, 0x86, 0xc1, 0x01, 0x0f, 0x07, 0x01, 0x83, 0x81, 0x4a, 0xb9, 0x06, 0xe1, 0x84, 0x7c, 0x20, + 0xe0, 0xc1, 0x83, 0x17, 0x46, 0x03, 0x7f, 0xc0, 0x18, 0x48, 0x5e, 0x25, 0x91, 0x47, 0x88, 0xdc, + 0x40, 0x82, 0x00, 0x1a, 0x06, 0x88, 0xc2, 0x20, 0xf6, 0x00, 0x21, 0xd4, 0x4b, 0xe2, 0x0f, 0x15, + 0x79, 0x83, 0xd7, 0x41, 0xaa, 0x85, 0x2f, 0x87, 0xfe, 0xa9, 0x10, 0x7b, 0x82, 0x4b, 0xfc, 0xbf, + 0x11, 0x29, 0x00, 0x1b, 0x21, 0xaa, 0x95, 0x03, 0x87, 0xfd, 0x94, 0x07, 0xc4, 0x20, 0x3e, 0x5f, + 0xff, 0xc4, 0x2e, 0x02, 0x0d, 0x50, 0x30, 0xe9, 0x07, 0xe3, 0xf6, 0xff, 0xfe, 0x61, 0x70, 0x61, + 0xfa, 0x83, 0xc5, 0xc2, 0x4a, 0xf2, 0x81, 0x9e, 0xc4, 0x1e, 0xbf, 0x8d, 0x46, 0xab, 0x14, 0x0f, + 0x20, +}; +const uint8_t _A_Levelup2_128x64_3[] = { + 0x01, 0x00, 0x2d, 0x03, 0x8f, 0xc0, 0xb8, 0x1f, 0xfb, 0xfd, 0xe2, 0x7f, 0xf8, 0x02, 0x0f, 0xff, + 0xff, 0x03, 0xff, 0x00, 0xc6, 0xff, 0x36, 0xe0, 0x47, 0xfd, 0xff, 0x08, 0xff, 0xf3, 0xff, 0x3f, + 0x05, 0x8f, 0xf0, 0x1e, 0x5f, 0xf8, 0xfe, 0x02, 0xfb, 0xff, 0xf8, 0x43, 0xff, 0x99, 0xfd, 0xf8, + 0x44, 0x81, 0xe7, 0x17, 0x88, 0x7d, 0x37, 0xe0, 0xf2, 0x87, 0xe7, 0xff, 0xe0, 0x11, 0xfe, 0x83, + 0xca, 0x1f, 0x20, 0xf8, 0x0f, 0x46, 0x0f, 0xfe, 0x83, 0xf6, 0xff, 0xfc, 0xf0, 0xfa, 0x47, 0xec, + 0x1e, 0x08, 0xf8, 0x3c, 0xa0, 0x7c, 0x3f, 0xff, 0x9c, 0x1e, 0x93, 0xf8, 0x06, 0x02, 0x1f, 0xf8, + 0x2c, 0x8c, 0x07, 0xc1, 0xff, 0xfd, 0x83, 0xdb, 0xc1, 0x07, 0xfc, 0x40, 0x6f, 0xda, 0x0d, 0x47, + 0xff, 0xf2, 0x0f, 0x4b, 0xf8, 0x7c, 0x60, 0xda, 0x88, 0x0c, 0x72, 0x01, 0xb0, 0xff, 0xe0, 0x01, + 0xe9, 0xff, 0x80, 0x68, 0x21, 0xff, 0xa9, 0x06, 0x02, 0x01, 0xf2, 0xbf, 0x40, 0x12, 0x44, 0x1f, + 0x2b, 0x82, 0xa1, 0x7d, 0x11, 0xf8, 0x05, 0xf8, 0x1e, 0x74, 0x7f, 0x80, 0xc0, 0x75, 0x50, 0xa8, + 0x04, 0x83, 0xf0, 0x0f, 0x1b, 0xe1, 0x48, 0x6f, 0xfb, 0x78, 0x38, 0x3c, 0x40, 0x09, 0xfc, 0x81, + 0x83, 0xcb, 0xfb, 0xbf, 0xbf, 0xcb, 0xbe, 0x1a, 0x8d, 0x56, 0xaa, 0x55, 0x80, 0x85, 0x18, 0xc4, + 0x5e, 0xb3, 0xce, 0x00, 0x7d, 0x7b, 0x80, 0x21, 0xdf, 0xcf, 0xef, 0xee, 0x72, 0x2f, 0x8e, 0xaa, + 0x01, 0xa8, 0xd1, 0x62, 0xa7, 0xfa, 0x0c, 0x06, 0x7d, 0x82, 0x33, 0x8f, 0x3d, 0xfe, 0x04, 0x18, + 0x15, 0x68, 0xc0, 0x1e, 0xa2, 0x02, 0x1f, 0x0f, 0xff, 0xbf, 0x3f, 0xe3, 0xcf, 0xc7, 0x63, 0xca, + 0xd7, 0xe7, 0xf5, 0x58, 0xa8, 0x3e, 0xa3, 0x80, 0x8e, 0x29, 0xfe, 0x3c, 0x2e, 0x30, 0x0b, 0x87, + 0x76, 0xea, 0x73, 0x11, 0x10, 0xd8, 0x01, 0xe5, 0xcf, 0x9f, 0xcf, 0xf5, 0x50, 0x2d, 0x61, 0x80, + 0x75, 0x38, 0xa2, 0x28, 0xda, 0x09, 0x63, 0x9f, 0x1f, 0x0c, 0xf8, 0x3e, 0x35, 0x6a, 0xad, 0x54, + 0x3a, 0x20, 0x01, 0xba, 0x7f, 0xf7, 0xf9, 0xff, 0xbc, 0xfe, 0x7c, 0x9c, 0x1d, 0x5e, 0xbb, 0x57, + 0xa6, 0x85, 0x68, 0xb5, 0x5b, 0x8d, 0xff, 0x7f, 0xde, 0x0f, 0x18, 0x60, 0xe8, 0x43, 0xc3, 0x55, + 0x86, 0x87, 0xcb, 0x31, 0xfd, 0xff, 0xf9, 0xfc, 0xe4, 0xe1, 0xd4, 0x72, 0xb5, 0x41, 0xf1, 0xcd, + 0x42, 0x88, 0x63, 0xe4, 0xff, 0xfe, 0x7c, 0xff, 0x18, 0x38, 0x5c, 0x68, 0x15, 0x5a, 0xbd, 0x5e, + 0x2a, 0x1f, 0x2f, 0x87, 0xcf, 0xf3, 0x27, 0xfc, 0x41, 0xe5, 0x4b, 0xe2, 0x00, 0x16, 0x29, 0x86, + 0x3f, 0x0f, 0x8e, 0xe2, 0x07, 0xfc, 0x87, 0x85, 0xc6, 0xc0, 0x1f, 0x29, 0xa8, 0x7c, 0xbc, 0x13, + 0x9f, 0x74, 0x0f, 0xd1, 0x0f, 0x0d, 0x0e, 0xc8, 0x3c, 0x56, 0xa2, 0xf0, 0xc0, 0xbf, 0x19, 0x8f, + 0xfc, 0x07, 0xf9, 0x06, 0x0b, 0x8d, 0x40, 0x3e, 0x55, 0x50, 0xf9, 0x7e, 0x38, 0x5f, 0xf8, 0x00, + 0x04, 0x47, 0xc6, 0x80, 0x10, 0x21, 0x42, 0xaf, 0x1d, 0x09, 0xfe, 0x00, 0x1e, 0x20, 0x01, 0xec, + 0x07, 0x46, 0xab, 0xdf, 0x03, 0x94, 0xf3, 0x85, 0x0f, 0x07, 0x90, 0x7c, 0x7d, 0x5a, 0xaf, 0xfe, + 0xbf, 0x74, 0x1f, 0x19, 0x54, 0xf3, 0xd0, 0xb5, 0x1e, 0x1a, 0xdc, 0xfa, 0xb5, 0x5a, 0xed, 0xd6, + 0x02, 0x1f, 0x2f, 0x00, 0x0c, 0x78, 0xf0, 0x1d, 0x03, 0x78, 0x7f, 0x5a, 0xa0, 0x08, 0xea, 0x47, + 0xe3, 0x38, 0xa0, 0x40, 0x25, 0x1e, 0x34, 0xf9, 0x55, 0x2e, 0xa0, 0x01, 0xaa, 0x87, 0xc8, 0x00, + 0x7f, 0xa8, 0x06, 0x8e, 0x15, 0xfc, 0x1e, 0x0f, 0xab, 0xf4, 0x1f, 0x20, 0x71, 0x42, 0xbf, 0x1e, + 0x70, 0xc0, 0xf5, 0x2a, 0xb7, 0x7a, 0xbd, 0x74, 0x3e, 0xdf, 0x8f, 0xfe, 0x0e, 0x54, 0x1f, 0x59, + 0x54, 0xaa, 0x01, 0x08, 0xc0, 0x28, 0xc7, 0xfe, 0x63, 0x10, 0xf8, 0x80, 0x04, 0x3f, 0x08, 0x81, + 0xd5, 0x7f, 0x37, 0xe1, 0xf1, 0xff, 0xea, 0x70, 0x41, 0xf1, 0x90, 0x6a, 0x20, 0x5f, 0xeb, 0xf8, + 0x4c, 0x7e, 0x9d, 0xff, 0xff, 0x7e, 0xfe, 0x1f, 0x6d, 0xf5, 0xff, 0x51, 0x2a, 0xd6, 0x7b, 0xcf, + 0xe3, 0xaf, 0xd4, 0xe0, 0x03, 0xe2, 0xa3, 0x18, 0x17, 0xf2, 0xf6, 0x7f, 0x3a, 0xa9, 0xfe, 0x09, + 0xe3, 0xa8, 0x85, 0x6b, 0x07, 0xe5, 0xaf, 0x80, 0xe0, 0x35, 0x40, 0x11, 0x0f, 0x97, 0xfc, 0x30, + 0x35, 0x42, 0xf9, 0x07, 0xde, 0xfd, 0x0f, 0x0f, 0x93, 0xf0, 0xb5, 0x58, 0x10, 0xe9, 0x07, 0xca, + 0x7d, 0x1f, 0x1f, 0xec, 0xf2, 0x7c, 0x57, 0x10, 0xfa, 0x6a, 0x71, 0x40, 0x53, 0x80, 0x4e, 0x03, + 0xe5, 0x56, 0x1f, 0x9a, 0x98, 0x40, 0x0c, 0xb7, 0x1d, 0x77, 0xab, 0x54, 0xc1, 0x1d, 0x5e, 0x88, + 0x40, 0x48, 0x21, 0xf0, 0x4c, 0x02, 0x23, 0x55, 0xea, 0xaf, 0x86, 0xab, 0x05, 0x80, 0x58, 0x03, + 0xa7, 0xf4, 0xb4, 0x6a, 0xb1, 0x5a, 0xed, 0x57, 0xec, 0x04, 0x38, 0xbd, 0x16, 0xc8, 0x3e, 0x30, + 0xa8, 0x07, 0xf3, 0xb1, 0x01, 0xb0, 0x07, 0xc6, 0xaf, 0x5f, 0xaa, 0xcd, 0x60, 0x1d, 0xc4, 0xfa, + 0x6a, 0x21, 0xdb, 0x80, 0xe0, 0xea, 0xc0, 0x43, 0xeb, 0xc0, 0x6a, 0xc3, 0xe3, 0xa0, 0x85, 0x7f, + 0xab, 0x3f, 0x5a, 0xb9, 0x70, 0x6a, 0xe0, 0x32, 0xbf, 0xf5, 0x43, 0xe7, 0xff, 0xdb, 0x85, 0x44, + 0x38, 0x3f, 0xa3, 0xd9, 0xda, 0xa1, 0x50, 0xa2, 0x00, 0xcf, 0x6a, 0x67, 0xc3, 0x00, 0x28, 0x7c, + 0xf8, 0x1a, 0xf0, 0xf9, 0x80, 0x12, 0x55, 0x28, 0x94, 0x2f, 0xc7, 0xc7, 0x6b, 0x0f, 0x41, 0x84, + 0x40, 0x03, 0x80, 0xf0, 0xf7, 0xc3, 0x8a, 0x00, 0x2c, 0xd0, 0x84, 0x75, 0x5c, 0x2f, 0x8e, 0x7c, + 0x3f, 0x10, 0xd1, 0xf1, 0xfc, 0x20, 0x27, 0x62, 0x00, 0x18, 0x18, 0x74, 0xca, 0x91, 0x1f, 0x8f, + 0xe1, 0xba, 0xae, 0x18, 0xfe, 0x28, 0x44, 0xbe, 0xba, 0xbf, 0xd6, 0xa3, 0x55, 0xa2, 0x0f, 0x8f, + 0xf0, +}; +const uint8_t _A_Levelup2_128x64_4[] = { + 0x01, 0x00, 0x90, 0x02, 0xff, 0x80, 0x3c, 0x01, 0xf1, 0xff, 0xe0, 0x3f, 0x7d, 0xff, 0xd1, 0x0f, + 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x2d, 0xff, 0xee, 0x0f, 0xef, 0x47, 0xff, 0xfc, 0x06, 0x2d, + 0xf8, 0x3d, 0xe0, 0x3e, 0x49, 0x3f, 0xc0, 0xfc, 0x7f, 0x8f, 0xfc, 0xed, 0x02, 0x37, 0xff, 0xc5, + 0xbe, 0x01, 0xf0, 0xaf, 0xe0, 0xc1, 0xe7, 0xe0, 0xff, 0xc0, 0xc2, 0xe3, 0x1f, 0xf8, 0x4f, 0xe0, + 0x17, 0x0b, 0xf5, 0x81, 0x34, 0x40, 0xf1, 0xb8, 0xc1, 0x38, 0x1f, 0xd8, 0x3f, 0xe2, 0x73, 0x00, + 0xf7, 0xc7, 0xe4, 0x02, 0xb1, 0xff, 0xcf, 0xf0, 0x02, 0x81, 0xc0, 0x77, 0xe0, 0x37, 0xf8, 0x47, + 0x82, 0xff, 0x0e, 0x6e, 0x1c, 0x1d, 0xc4, 0x3e, 0x08, 0x0c, 0x0b, 0x80, 0x2e, 0x1f, 0x00, 0x08, + 0x60, 0x06, 0x02, 0xc3, 0xc0, 0x41, 0xe4, 0x09, 0x12, 0x70, 0xd8, 0x23, 0xf8, 0x08, 0x78, 0x3c, + 0x7e, 0xf0, 0x78, 0x1c, 0x03, 0x81, 0x07, 0xff, 0x40, 0xc0, 0xa5, 0x19, 0x10, 0x8a, 0x00, 0xc6, + 0x05, 0xc4, 0xd7, 0xc7, 0xc0, 0x82, 0x00, 0x13, 0xf1, 0xa4, 0xc6, 0x9e, 0x08, 0x3b, 0xf8, 0x3c, + 0xcb, 0xa4, 0x02, 0x13, 0x90, 0xc1, 0xa0, 0x1a, 0xcd, 0x56, 0xa8, 0x84, 0x50, 0x0f, 0x67, 0xff, + 0xe7, 0xf1, 0xf9, 0xfb, 0x3f, 0x30, 0xfa, 0x80, 0xd8, 0xa0, 0x71, 0x40, 0x78, 0xff, 0x39, 0xfe, + 0x7b, 0xff, 0x9f, 0x89, 0xff, 0x85, 0xc0, 0x35, 0x7a, 0xed, 0x58, 0x90, 0x45, 0xe5, 0x87, 0x1f, + 0x94, 0x02, 0x9f, 0x08, 0xca, 0x01, 0x8a, 0x9f, 0x15, 0x07, 0x8d, 0xe3, 0x80, 0x0f, 0x30, 0xc8, + 0xf0, 0x35, 0x41, 0xf1, 0x8d, 0x14, 0x13, 0x9f, 0xfb, 0x07, 0x8c, 0x02, 0x21, 0xd0, 0x0b, 0x15, + 0x7e, 0x2a, 0x51, 0x1b, 0x07, 0xfb, 0xcd, 0xff, 0xe1, 0x9f, 0x8b, 0x40, 0x5e, 0x1d, 0x54, 0xa8, + 0x3c, 0x53, 0xc9, 0xce, 0x43, 0xff, 0x01, 0x44, 0x93, 0xc4, 0x5a, 0xc5, 0x55, 0xa8, 0x40, 0x77, + 0xd1, 0xe8, 0x07, 0xdd, 0xa4, 0x20, 0xf1, 0xd8, 0x07, 0xca, 0xd4, 0x1f, 0x28, 0xf3, 0x80, 0x6f, + 0xf3, 0x05, 0x78, 0xc1, 0x14, 0xe7, 0x7f, 0xaa, 0xd5, 0x60, 0x30, 0x48, 0x06, 0x02, 0x3f, 0xfe, + 0xfe, 0x90, 0x07, 0x51, 0xaa, 0x40, 0x0e, 0xa8, 0xbe, 0x66, 0x91, 0xe3, 0x86, 0x45, 0x3c, 0x3f, + 0x96, 0x39, 0xd5, 0x2a, 0xa1, 0x04, 0xf7, 0xfe, 0xc4, 0xa3, 0xe8, 0xd5, 0x7f, 0xf5, 0xfb, 0xa0, + 0xfa, 0x16, 0x87, 0xc7, 0x6f, 0x80, 0x55, 0x3f, 0xa1, 0xf3, 0x1f, 0x8b, 0xc9, 0x38, 0x70, 0x30, + 0x20, 0xeb, 0x3f, 0x5a, 0xa0, 0x08, 0xb8, 0x0c, 0x1e, 0x58, 0x10, 0x18, 0xd0, 0x03, 0xef, 0x54, + 0x09, 0xab, 0x9c, 0x77, 0x5a, 0xaf, 0x57, 0xe8, 0x16, 0xd1, 0xfb, 0x85, 0xc2, 0x00, 0x1f, 0x50, + 0x80, 0xd5, 0x22, 0x20, 0xf1, 0xff, 0x7e, 0x3f, 0x01, 0xfb, 0xec, 0x7f, 0xef, 0x12, 0x00, 0x78, + 0x87, 0xce, 0x2b, 0x04, 0x82, 0xc5, 0x03, 0xc4, 0x08, 0x1f, 0x1c, 0x07, 0xf9, 0xbf, 0x0f, 0x8b, + 0x60, 0x43, 0xe9, 0x5b, 0x4f, 0x90, 0x7d, 0x6a, 0x35, 0x58, 0x28, 0x04, 0x59, 0xe3, 0xbe, 0xbf, + 0x83, 0xc7, 0x59, 0xef, 0x3f, 0x8e, 0xbc, 0x3e, 0xbf, 0xf8, 0xf8, 0x04, 0x43, 0xeb, 0x55, 0xa2, + 0xd0, 0x6a, 0xb1, 0x58, 0x07, 0xee, 0x13, 0x97, 0x07, 0x8e, 0xb0, 0x7e, 0x41, 0xf5, 0xe0, 0x7f, + 0xe1, 0xb1, 0xf8, 0x7a, 0xfd, 0xc3, 0xe3, 0x05, 0xb0, 0x43, 0xf8, 0x17, 0xf6, 0xf8, 0xeb, 0x35, + 0x40, 0x02, 0x0f, 0xa4, 0xc2, 0x09, 0xe0, 0x8c, 0x40, 0x2a, 0xa1, 0xf8, 0x09, 0x95, 0xc8, 0x2a, + 0x41, 0xf9, 0x00, 0x0c, 0x40, 0x04, 0x35, 0x14, 0xa1, 0x00, 0x06, 0xa7, 0x55, 0xaa, 0x17, 0x84, + 0x00, 0x36, 0x00, 0x19, 0x6b, 0xbd, 0x5a, 0xa6, 0x08, 0xc0, 0xc3, 0xeb, 0xf8, 0x98, 0x40, 0x22, + 0xa1, 0xe3, 0xff, 0xd5, 0xea, 0xb6, 0x53, 0xf9, 0x03, 0xc6, 0xd1, 0x00, 0xc0, 0x6b, 0xb5, 0x5f, + 0xb0, 0x10, 0xc2, 0xe0, 0x1b, 0x00, 0xf9, 0xfb, 0xbf, 0x35, 0x1f, 0x28, 0x7d, 0x27, 0xf5, 0x5f, + 0xe1, 0x00, 0x4c, 0x23, 0xfe, 0xd5, 0xc3, 0xb7, 0x01, 0xc1, 0xd5, 0x80, 0x87, 0xd7, 0x80, 0xd5, + 0x87, 0x8b, 0x01, 0xff, 0xfd, 0x87, 0x50, 0x00, 0x95, 0x44, 0x18, 0xf8, 0x29, 0xfb, 0x33, 0xd0, + 0x87, 0x07, 0xf4, 0x81, 0x3b, 0x50, 0xfc, 0xe1, 0x1f, 0x70, 0xf4, 0x5f, 0xea, 0xb5, 0x03, 0x01, + 0x69, 0xc3, 0xe6, 0x00, 0x49, 0x52, 0x01, 0x3d, 0xe1, 0xf8, 0x30, 0x8c, 0x16, 0x82, 0xdc, 0x1e, + 0x68, 0x71, 0x40, 0x05, 0x1a, 0x0f, 0xa1, 0x84, 0x40, 0x0f, 0x4f, 0x2f, 0x0a, 0xac, 0x42, 0x03, + 0xab, 0x0e, 0xa8, 0x18, 0x60, 0xcc, 0x15, 0x6e, 0xa3, 0x85, 0x6a, 0xb4, 0x16, 0x09, 0x97, 0xd7, + 0x57, 0xfa, 0x0f, 0x28, +}; +const uint8_t _A_Levelup2_128x64_5[] = { + 0x01, 0x00, 0x9c, 0x02, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, + 0xf0, 0x07, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1f, 0xff, 0xfb, 0xcf, 0xff, + 0xf0, 0x3f, 0xc0, 0x18, 0x7e, 0x1e, 0x30, 0x83, 0xdf, 0xef, 0xd0, 0x0e, 0x27, 0xf6, 0xf7, 0xfc, + 0xe7, 0x83, 0x9b, 0x7f, 0xff, 0x8f, 0xff, 0xa4, 0x63, 0x1c, 0xe3, 0xea, 0xf3, 0xd1, 0xc0, 0x20, + 0xe7, 0xc6, 0x84, 0x2f, 0x5b, 0x97, 0xfe, 0xef, 0xca, 0xf8, 0xf1, 0xe0, 0x20, 0xd6, 0xff, 0x4c, + 0x7d, 0x9a, 0xad, 0xd5, 0x87, 0xe1, 0x4f, 0xc0, 0x7f, 0xff, 0xc3, 0xe4, 0xbe, 0x40, 0x2e, 0xd5, + 0x5b, 0xae, 0x0f, 0xe7, 0x0f, 0xf0, 0x7f, 0xfc, 0x22, 0x04, 0x9b, 0xc0, 0x35, 0x7a, 0xad, 0x56, + 0x1b, 0xff, 0x00, 0xf8, 0x7f, 0x78, 0xe0, 0xf4, 0x9f, 0xe0, 0xaa, 0xa0, 0x01, 0xd6, 0xcf, 0xe0, + 0x04, 0xe1, 0x38, 0x98, 0xf8, 0x67, 0xfc, 0x70, 0xf0, 0xea, 0xa3, 0x50, 0xf0, 0x79, 0x13, 0x93, + 0xa1, 0xff, 0xa3, 0xd5, 0xc3, 0xe3, 0x17, 0x80, 0x40, 0x3f, 0x80, 0xf5, 0x0b, 0x0e, 0xbf, 0x56, + 0x02, 0x19, 0x70, 0x3c, 0x67, 0x07, 0xf6, 0xc7, 0xd9, 0xee, 0xa5, 0xf1, 0x9a, 0xc0, 0x20, 0x90, + 0x03, 0x00, 0xef, 0xfd, 0xe0, 0xf2, 0x87, 0xec, 0x37, 0x5a, 0xaf, 0x55, 0xa8, 0x3e, 0x23, 0x12, + 0xfe, 0xf7, 0xdb, 0xa3, 0x9f, 0x86, 0x74, 0x2b, 0xb5, 0x5e, 0xa8, 0x08, 0x60, 0x20, 0xf1, 0xf8, + 0x10, 0x12, 0x11, 0xa8, 0xd7, 0x17, 0xc7, 0x56, 0x0d, 0x18, 0xe0, 0xc0, 0x8f, 0xa5, 0xff, 0x89, + 0xf6, 0x0b, 0xe5, 0xdf, 0xaa, 0x40, 0x6f, 0xe0, 0xf1, 0xfd, 0xb7, 0x0e, 0x07, 0xe8, 0xd5, 0x7f, + 0xb5, 0x7b, 0xa8, 0x06, 0x02, 0x1f, 0x8c, 0xf1, 0xb0, 0x47, 0xc7, 0xef, 0x07, 0x8f, 0xd7, 0xaf, + 0x57, 0xaf, 0xdf, 0xea, 0xb8, 0x58, 0x7e, 0xff, 0xce, 0x1d, 0x12, 0x10, 0xfc, 0xe0, 0x7e, 0xcf, + 0xd6, 0xab, 0xf5, 0xba, 0x27, 0x0c, 0x0d, 0xbc, 0x26, 0xe2, 0xbf, 0xcb, 0xe0, 0x15, 0x5b, 0xed, + 0x5f, 0xef, 0x55, 0xa0, 0x84, 0x04, 0x1e, 0x30, 0xf7, 0x89, 0x41, 0x8e, 0xc2, 0x7f, 0x2f, 0xd1, + 0xb8, 0xaf, 0xf7, 0xfb, 0xf2, 0xcc, 0x7e, 0x70, 0xe8, 0x07, 0x52, 0xab, 0x57, 0xab, 0xd7, 0x68, + 0xb0, 0x58, 0x00, 0x6c, 0x6f, 0x8b, 0x21, 0xb1, 0xa5, 0x88, 0x3e, 0xc6, 0xe4, 0x17, 0x0d, 0x53, + 0xaa, 0x1f, 0x51, 0x00, 0x8f, 0x4b, 0xff, 0x0c, 0x0f, 0x96, 0xfc, 0x3e, 0x3f, 0xf0, 0xf9, 0x40, + 0x3f, 0xa0, 0xf2, 0xc4, 0xc0, 0xe8, 0x1f, 0x5e, 0xef, 0xff, 0xbf, 0x7d, 0xa2, 0xb0, 0x0b, 0xf1, + 0x7f, 0x10, 0x8f, 0x82, 0x0f, 0x00, 0xd7, 0x7f, 0xf5, 0x7f, 0xed, 0x7c, 0x0c, 0x3c, 0x38, 0x0f, + 0xfc, 0xe7, 0xfd, 0x8d, 0xff, 0xc7, 0xcf, 0xe2, 0xff, 0x2a, 0xa8, 0x7c, 0x68, 0x38, 0x0e, 0xf9, + 0x88, 0x70, 0xe3, 0x11, 0x80, 0xeb, 0xf7, 0xfa, 0xbf, 0x76, 0xbc, 0x4c, 0x20, 0x01, 0x83, 0x08, + 0x45, 0xc0, 0x50, 0x76, 0xe8, 0x80, 0x11, 0x42, 0x58, 0x06, 0x88, 0xff, 0xe7, 0xd0, 0x5d, 0x5b, + 0xf8, 0x40, 0x02, 0x77, 0x10, 0x01, 0x70, 0x3e, 0x2b, 0xf1, 0xbc, 0x4e, 0x2b, 0xb7, 0x5a, 0xbd, + 0xdd, 0x06, 0x31, 0x5a, 0x00, 0x7c, 0x7c, 0x1f, 0xcf, 0xbf, 0xff, 0xd3, 0x78, 0xdd, 0x87, 0x8b, + 0xd4, 0x1f, 0x48, 0x04, 0xc1, 0xc0, 0x57, 0x81, 0xd0, 0xa7, 0xc6, 0xab, 0x05, 0xa0, 0x18, 0x44, + 0x20, 0x58, 0xcc, 0x1c, 0x7f, 0xe1, 0xab, 0xf5, 0x6b, 0x84, 0x42, 0x1f, 0x51, 0x09, 0x43, 0xa8, + 0x17, 0x51, 0xe0, 0x90, 0x86, 0x0b, 0x50, 0xb2, 0x90, 0x86, 0x01, 0xf0, 0x81, 0xda, 0x0c, 0x82, + 0x5f, 0x1f, 0xfe, 0xbf, 0x54, 0xf6, 0x1d, 0x80, 0x74, 0x96, 0x23, 0xd8, 0x80, 0x85, 0xc7, 0xab, + 0x57, 0xaf, 0xd5, 0x66, 0xb5, 0x4e, 0xe5, 0x51, 0xc2, 0x7a, 0x88, 0x76, 0xe0, 0x78, 0x3a, 0xbd, + 0x77, 0xab, 0xdc, 0x26, 0x16, 0x09, 0xdf, 0xab, 0x7f, 0x52, 0xd8, 0x97, 0xce, 0xab, 0x7f, 0xea, + 0xd1, 0x20, 0x14, 0x0f, 0x84, 0xff, 0x6e, 0x7b, 0x11, 0xf8, 0xfe, 0x80, 0x83, 0xae, 0xd5, 0x5a, + 0x87, 0xe5, 0xe0, 0x9f, 0xd5, 0xdb, 0x43, 0x5d, 0x5e, 0x11, 0x88, 0x40, 0xe2, 0x3e, 0x18, 0x07, + 0x9e, 0xff, 0xad, 0x5e, 0x18, 0x00, 0x83, 0xe3, 0x2a, 0x07, 0x0f, 0xf3, 0x9f, 0xff, 0xb7, 0x85, + 0xc4, 0xb8, 0x21, 0xf2, 0x13, 0x8c, 0xd6, 0xaa, 0x4e, 0x1e, 0x3e, 0x73, 0x9d, 0xba, 0x10, 0x37, + 0xaa, 0x34, 0x5e, 0x1e, 0xff, 0xff, 0xf3, 0xb0, 0x1e, 0x88, 0x7d, 0x7a, 0xb4, 0xda, 0x84, 0x01, + 0x9a, 0x3e, 0x38, 0x02, 0x68, 0x40, 0x0d, 0x07, 0x1f, 0x8d, 0xff, 0xec, 0x0f, 0x1a, 0xb0, 0x7d, + 0xaa, 0xb0, 0x33, 0x00, 0xc7, 0x04, 0x02, 0xb2, 0x10, 0xf3, 0x7e, 0x9b, 0xa7, 0x3b, 0xff, 0x00, +}; +const uint8_t _A_Levelup2_128x64_6[] = { + 0x01, 0x00, 0x54, 0x02, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, + 0xf0, 0x07, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, 0x5f, 0x78, 0x37, + 0x20, 0x3f, 0xc0, 0x7e, 0x4f, 0xff, 0xde, 0x3e, 0x38, 0xae, 0xf9, 0xf0, 0x1c, 0xe0, 0x7e, 0xf8, + 0xf3, 0x3f, 0xfd, 0x9f, 0xdc, 0x1f, 0xbe, 0x6c, 0x03, 0x31, 0xfd, 0x1f, 0xdc, 0xca, 0x01, 0x60, + 0xfd, 0x03, 0xaa, 0xff, 0x09, 0x80, 0x60, 0x3e, 0x80, 0xfa, 0xdf, 0xc1, 0x20, 0x10, 0x0f, 0x48, + 0x3e, 0xab, 0xf0, 0x20, 0x78, 0xf4, 0x81, 0xd3, 0xf7, 0x07, 0xfc, 0xbf, 0x03, 0xff, 0x87, 0xe9, + 0x36, 0xe0, 0xf8, 0xf1, 0xcb, 0xec, 0x30, 0x09, 0x86, 0x93, 0x7f, 0xf7, 0x0f, 0xc6, 0x5e, 0x21, + 0x00, 0xa0, 0x52, 0x23, 0xe0, 0xe7, 0xfe, 0x83, 0xc6, 0x10, 0x6f, 0x1a, 0x46, 0xfc, 0x5f, 0x1f, + 0xcc, 0x59, 0xbc, 0xb1, 0x3b, 0xe4, 0x6c, 0x03, 0xc6, 0x0e, 0x0f, 0x1c, 0x7e, 0xfb, 0x07, 0xdf, + 0x59, 0xad, 0xfe, 0xf9, 0x4b, 0x84, 0x7f, 0xb0, 0x79, 0x0f, 0x76, 0x1c, 0x7e, 0xff, 0x8d, 0x2e, + 0x5e, 0x07, 0x4e, 0x97, 0xfd, 0x7f, 0xc0, 0xf6, 0xfd, 0xfe, 0xec, 0xb5, 0x88, 0x17, 0x4a, 0x60, + 0x2c, 0x4f, 0x79, 0xbd, 0x2a, 0xb3, 0x88, 0x17, 0x8a, 0xa0, 0x0f, 0x2f, 0x88, 0x85, 0xaa, 0xb3, + 0x08, 0x15, 0x8a, 0xa1, 0xbd, 0x03, 0x8f, 0xc0, 0x7a, 0x65, 0x02, 0xea, 0xc4, 0x20, 0x54, 0x2a, + 0xc0, 0x20, 0x6f, 0x9f, 0x0f, 0x98, 0x30, 0x7f, 0xd8, 0x7f, 0x1f, 0xf8, 0x1e, 0xb7, 0x78, 0xf7, + 0xe3, 0xf6, 0x20, 0x2c, 0x3f, 0x0f, 0xdf, 0xd5, 0x88, 0x83, 0xc6, 0xb8, 0x1f, 0x18, 0x7f, 0xf0, + 0xc4, 0x90, 0x7c, 0x1d, 0x56, 0x3f, 0x02, 0xe1, 0x55, 0xc7, 0xe3, 0x07, 0x07, 0x13, 0x50, 0xa7, + 0xf0, 0x2d, 0x2e, 0x63, 0xff, 0xcf, 0x94, 0x07, 0xc7, 0xc7, 0xff, 0x8f, 0x84, 0x4a, 0xfb, 0x7e, + 0xb1, 0x49, 0xab, 0xf0, 0x1e, 0xa4, 0x9f, 0x97, 0x3d, 0xf0, 0x16, 0x44, 0x04, 0x21, 0xe1, 0xfe, + 0x5d, 0xa8, 0xb3, 0x08, 0x0d, 0x92, 0x21, 0xf5, 0x8f, 0xfe, 0x2f, 0x7f, 0xcf, 0x08, 0x3c, 0xa0, + 0x17, 0x8c, 0x2c, 0x7e, 0x03, 0xc4, 0x87, 0xfd, 0x61, 0xff, 0xeb, 0xef, 0xf0, 0x64, 0x3f, 0xf8, + 0xec, 0x02, 0xe1, 0x05, 0x88, 0x40, 0x68, 0x90, 0x0f, 0xaa, 0xac, 0xbf, 0x9f, 0xfd, 0xff, 0x7e, + 0x30, 0x0f, 0x18, 0x4c, 0x82, 0x05, 0x22, 0xc0, 0x7d, 0x01, 0x83, 0xfd, 0xf6, 0x7f, 0xaf, 0x7f, + 0xe9, 0xc4, 0x1a, 0x84, 0x0f, 0x48, 0x27, 0xe3, 0x85, 0x6f, 0x09, 0x0f, 0xff, 0xf3, 0x10, 0x87, + 0xc1, 0x22, 0x20, 0xf2, 0xa0, 0x03, 0xc6, 0x86, 0x6e, 0x1f, 0xbf, 0xf7, 0xe7, 0x00, 0x83, 0xc6, + 0x22, 0x34, 0x08, 0x14, 0x48, 0x1e, 0x37, 0xef, 0x3c, 0x0f, 0xfc, 0x43, 0x1f, 0x9f, 0x02, 0x07, + 0xf0, 0x90, 0x83, 0x04, 0x44, 0x30, 0x49, 0xe4, 0x06, 0x01, 0x1c, 0xfe, 0x04, 0x07, 0x67, 0x03, + 0xb8, 0x48, 0x78, 0x10, 0x48, 0xc8, 0x3c, 0x60, 0x16, 0x08, 0x00, 0x08, 0x5e, 0x43, 0x4b, 0x87, + 0x64, 0x24, 0x38, 0x0f, 0xec, 0x36, 0x41, 0x0c, 0x80, 0x64, 0x01, 0xe3, 0x00, 0xf0, 0x7b, 0xf1, + 0x70, 0x1b, 0x04, 0x47, 0x01, 0x07, 0x87, 0xd0, 0x26, 0x90, 0x0c, 0x64, 0xc2, 0x01, 0xf0, 0x58, + 0x0c, 0x2e, 0x1c, 0x4f, 0x18, 0x04, 0x06, 0x09, 0x40, 0xe2, 0x60, 0x30, 0x7b, 0x88, 0x07, 0xfb, + 0xe2, 0x0f, 0x1f, 0x84, 0x1c, 0x1e, 0x30, 0x68, 0x19, 0x48, 0x6f, 0xf8, 0x0c, 0x04, 0x3f, 0xdd, + 0xff, 0xf6, 0x45, 0xe4, 0x10, 0x08, 0x4c, 0x03, 0xf1, 0x00, 0x47, 0x8c, 0x82, 0x81, 0xc0, 0x85, + 0xa4, 0x07, 0x82, 0x0f, 0x40, 0x00, 0x83, 0xd2, 0x23, 0xd8, 0xfc, 0x61, 0xe5, 0xe0, 0xf1, 0x85, + 0x03, 0xd4, 0x10, 0x26, 0xe1, 0xbc, 0x47, 0xe4, 0xe0, 0xf6, 0x81, 0x03, 0xcb, 0xe1, 0x71, 0xfc, + 0x4f, 0xe8, 0x71, 0x00, 0x7b, 0x50, 0x01, 0x03, 0xe0, 0x81, 0x83, 0xc7, 0x0f, 0x08, 0x07, 0xb6, + 0x03, 0x90, 0x05, 0x18, 0x77, 0x3e, 0x5f, 0x03, 0x83, 0x83, 0xda, 0x01, 0xf7, 0xe1, 0xc3, 0xff, + 0x11, 0xbb, 0xe4, 0x16, 0x0c, 0x0f, 0x7f, 0xdf, 0x9e, 0x3f, 0x70, 0xbd, 0xff, 0x0f, 0x64, 0x0f, + 0x5f, 0xc5, 0xc2, 0x79, 0x3c, 0x57, 0x0f, 0xfc, +}; +const uint8_t _A_Levelup2_128x64_7[] = { + 0x01, 0x00, 0xf7, 0x01, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, + 0xf0, 0x07, 0x80, 0x3c, 0x01, 0xe0, 0x05, 0xfd, 0x83, 0xfb, 0xbe, 0x20, 0xf0, 0xff, 0x83, 0x72, + 0x01, 0xfe, 0x07, 0xdf, 0xf6, 0x3f, 0xff, 0xf8, 0x83, 0xf3, 0xcf, 0xf8, 0xe7, 0xc0, 0xff, 0xc0, + 0xf9, 0xfc, 0x46, 0x60, 0xd3, 0x00, 0xfe, 0x41, 0xa0, 0x3c, 0x0e, 0xf0, 0x3e, 0xaf, 0xb8, 0x18, + 0x06, 0x03, 0xba, 0x0f, 0xad, 0xfd, 0x06, 0x01, 0x00, 0xed, 0x9e, 0xee, 0x80, 0x0f, 0x1f, 0xa8, + 0x3e, 0xb5, 0xf2, 0x00, 0x78, 0xfa, 0x81, 0xfb, 0xf8, 0xf5, 0xb6, 0xab, 0x2e, 0x0f, 0x18, 0x3f, + 0x5b, 0x7e, 0x10, 0x9c, 0xbf, 0xfb, 0x01, 0x00, 0xec, 0x07, 0xeb, 0x17, 0x01, 0xa0, 0xc0, 0x76, + 0x01, 0xf9, 0x07, 0x8d, 0xf2, 0x45, 0x02, 0x07, 0xdd, 0x2f, 0x05, 0x14, 0x82, 0x68, 0x01, 0xf3, + 0xe0, 0xa2, 0xe0, 0xe1, 0xb0, 0x4b, 0x03, 0x8c, 0x43, 0xf1, 0x25, 0xa1, 0xc2, 0x61, 0x16, 0x08, + 0x5f, 0xe8, 0x1f, 0x1a, 0x59, 0xe4, 0x2b, 0x11, 0x6f, 0x0f, 0xcf, 0xff, 0x4b, 0x24, 0x85, 0x5a, + 0x2e, 0x04, 0xfa, 0xd1, 0x03, 0xc6, 0x31, 0xa0, 0xdf, 0x07, 0xe7, 0x44, 0x2f, 0x18, 0x67, 0x03, + 0x7d, 0xfe, 0x07, 0xc5, 0x0a, 0x87, 0x0a, 0x89, 0x60, 0x01, 0xc3, 0xfd, 0x06, 0xac, 0xff, 0xff, + 0x46, 0xc1, 0xf3, 0x64, 0xf9, 0xc1, 0x7c, 0x5f, 0xfd, 0xd8, 0x6f, 0x14, 0xfe, 0x51, 0xa3, 0xef, + 0x0f, 0xe7, 0x15, 0x1c, 0x80, 0x7a, 0x38, 0x03, 0xe9, 0xff, 0xc2, 0xa1, 0x70, 0x09, 0x47, 0x03, + 0xfb, 0xf7, 0x07, 0xc4, 0x4a, 0x09, 0x00, 0x8c, 0x50, 0x09, 0xa3, 0xef, 0x1f, 0x28, 0x1c, 0x41, + 0xe5, 0x08, 0x07, 0x97, 0x8c, 0x3f, 0x30, 0x18, 0x34, 0x80, 0x1e, 0x3f, 0xbf, 0x38, 0x3d, 0xe0, + 0x18, 0x68, 0x08, 0x3c, 0x84, 0x0b, 0xf8, 0x18, 0x89, 0x38, 0x6f, 0x10, 0x08, 0x80, 0x3c, 0xbe, + 0x20, 0xf3, 0xf8, 0x4f, 0xf7, 0xf0, 0x68, 0x00, 0x00, 0x61, 0x00, 0xf1, 0xbf, 0xa8, 0x13, 0xc1, + 0x3f, 0xce, 0x40, 0x81, 0xe5, 0x04, 0x06, 0x21, 0x04, 0x81, 0xe3, 0xbc, 0x2f, 0x08, 0x00, 0x60, + 0x5f, 0x99, 0xfa, 0x44, 0xbc, 0x00, 0x21, 0xe0, 0xff, 0x37, 0xf1, 0x80, 0x79, 0x40, 0x76, 0xf1, + 0xf0, 0x78, 0xef, 0xca, 0x25, 0x07, 0xf8, 0x6f, 0xec, 0x00, 0xf2, 0x80, 0x7a, 0x78, 0xff, 0xff, + 0xbc, 0x3c, 0x44, 0x51, 0xfe, 0x46, 0xff, 0x81, 0x01, 0x07, 0x98, 0xf8, 0xae, 0x3c, 0x05, 0x01, + 0xef, 0xe8, 0x05, 0x03, 0x07, 0x8f, 0x3c, 0x16, 0x38, 0x12, 0xa1, 0xef, 0x81, 0xed, 0xb7, 0x1e, + 0x11, 0x88, 0xc3, 0xeb, 0xed, 0xff, 0xd2, 0xc1, 0x83, 0x0f, 0xff, 0xfc, 0xf3, 0x7f, 0xfa, 0x7c, + 0x84, 0x7e, 0x60, 0xf1, 0xa2, 0x03, 0xc7, 0x1e, 0xa3, 0x1b, 0x2f, 0xfa, 0x66, 0x0f, 0x4c, 0xac, + 0x7e, 0x87, 0xd0, 0x1e, 0x9e, 0x16, 0x03, 0x0c, 0xd0, 0x9b, 0xce, 0xc7, 0xe0, 0xa0, 0x78, 0x3c, + 0x3f, 0xb0, 0x78, 0xc1, 0x7f, 0xd0, 0x3c, 0x88, 0x3c, 0xf0, 0x71, 0xf9, 0x04, 0x00, 0xdc, 0x70, + 0x58, 0x44, 0x02, 0xa2, 0x0f, 0x38, 0x1c, 0x22, 0x41, 0xf0, 0x81, 0xff, 0x92, 0x03, 0x0b, 0x07, + 0x8d, 0x28, 0x1e, 0x70, 0x18, 0x44, 0x43, 0xe0, 0xb2, 0x1c, 0xff, 0xfe, 0x10, 0x0f, 0x19, 0x50, + 0x3d, 0x22, 0x11, 0x08, 0xc5, 0xfb, 0x3c, 0x70, 0x18, 0xbb, 0x74, 0x64, 0xc0, 0xf5, 0xb4, 0x4c, + 0x3f, 0x18, 0xf4, 0x80, 0x83, 0xca, 0x2c, 0x0f, 0x49, 0x07, 0xd3, 0xc1, 0x01, 0xc0, 0x13, 0xc6, + 0x5e, 0x9c, 0x10, 0x7a, 0xd0, 0x3f, 0x5e, 0x18, 0x39, 0x80, 0x80, +}; +const uint8_t _A_Levelup2_128x64_8[] = { + 0x01, 0x00, 0x02, 0x02, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, + 0xf0, 0x07, 0x80, 0x3c, 0x00, 0xbf, 0xb0, 0x7f, 0x88, 0x3c, 0x3f, 0xe1, 0x0f, 0x00, 0x5c, 0x3f, + 0xc0, 0x1f, 0xdf, 0x8c, 0x7c, 0x1f, 0x97, 0xf8, 0x77, 0xf3, 0xf8, 0x21, 0x10, 0x04, 0xe7, 0xe0, + 0x30, 0x2f, 0x98, 0x7e, 0xed, 0xf0, 0x18, 0x0f, 0xb0, 0x1e, 0x7c, 0xf8, 0x4c, 0xcb, 0xe6, 0x0f, + 0x38, 0xb8, 0x3c, 0x7a, 0x00, 0x73, 0xc7, 0xf2, 0x66, 0x60, 0xf4, 0x85, 0xe0, 0x60, 0x1a, 0x00, + 0xf9, 0x83, 0xde, 0x0b, 0x82, 0x80, 0x50, 0x00, 0xe7, 0x4f, 0x84, 0xc9, 0xbf, 0x20, 0x62, 0xff, + 0x40, 0xa8, 0x50, 0x0f, 0xc7, 0xfb, 0xde, 0x0f, 0x2e, 0x4c, 0x9c, 0x1e, 0xf0, 0x6f, 0xe8, 0x3c, + 0xb9, 0xfc, 0x88, 0x3f, 0xe0, 0xfc, 0x70, 0x1f, 0xf4, 0x02, 0x03, 0xfd, 0xe3, 0x83, 0xcf, 0x9f, + 0xfc, 0x07, 0x95, 0xf8, 0xbc, 0x25, 0x01, 0xfd, 0x07, 0xce, 0x13, 0xce, 0x07, 0x95, 0xff, 0xf9, + 0x80, 0xbe, 0x0c, 0x04, 0x1e, 0x60, 0x06, 0xdf, 0x50, 0x30, 0x52, 0x48, 0x04, 0x11, 0x3d, 0x3b, + 0xe9, 0x06, 0x0e, 0x53, 0x00, 0x60, 0x88, 0x3e, 0x2b, 0xfa, 0x0a, 0x14, 0x68, 0xc0, 0x29, 0x01, + 0xe7, 0xe0, 0xf3, 0x92, 0x0a, 0x7f, 0xc8, 0x1e, 0x35, 0xed, 0x04, 0xf0, 0x1e, 0x30, 0x1f, 0xa0, + 0x3c, 0x7e, 0x79, 0xc9, 0xe0, 0x3c, 0xc3, 0xe3, 0x24, 0x85, 0x70, 0x20, 0x1e, 0x80, 0x79, 0x72, + 0x41, 0xf1, 0x30, 0x80, 0x83, 0xcb, 0x07, 0xc9, 0x17, 0xa7, 0x7c, 0x5e, 0x30, 0xaf, 0xc6, 0x0b, + 0xd6, 0x1f, 0x4b, 0x7b, 0x5c, 0x81, 0xe3, 0xc2, 0x85, 0x43, 0xac, 0xbe, 0xc0, 0x79, 0x78, 0xc1, + 0xeb, 0x20, 0x81, 0xe2, 0xe0, 0x31, 0xa1, 0xf9, 0x83, 0xc4, 0xde, 0x94, 0x1f, 0x15, 0xed, 0x1e, + 0x20, 0xf1, 0x87, 0xe0, 0xbe, 0xf2, 0x0a, 0x41, 0x3c, 0xf0, 0x31, 0xc8, 0x64, 0x02, 0x04, 0x6f, + 0x14, 0x7c, 0x40, 0xa0, 0xb0, 0x83, 0xf9, 0x83, 0xe2, 0x09, 0x02, 0x80, 0x1f, 0xc7, 0xf4, 0x0f, + 0x98, 0x40, 0x3c, 0x66, 0x00, 0xfb, 0x88, 0x60, 0x20, 0x04, 0x01, 0xfe, 0x83, 0xe6, 0x41, 0x00, + 0xc1, 0xc0, 0xf0, 0x1f, 0xe0, 0x7d, 0xdf, 0x20, 0x14, 0x00, 0x41, 0x43, 0xe0, 0x10, 0x0c, 0x00, + 0x18, 0xad, 0xe0, 0xf1, 0x00, 0x0e, 0x80, 0x10, 0x5f, 0x30, 0x10, 0xdf, 0xc0, 0xc5, 0x97, 0x8c, + 0x03, 0xcb, 0xa0, 0x08, 0x28, 0x68, 0x7c, 0x86, 0xc5, 0x17, 0x83, 0x83, 0xcb, 0x30, 0x0f, 0x28, + 0x30, 0x1c, 0x8a, 0xc5, 0x17, 0x37, 0x08, 0x00, 0x6e, 0x80, 0xfa, 0x82, 0x01, 0xcb, 0x20, 0x28, + 0x28, 0x36, 0x73, 0x10, 0x0f, 0x45, 0x68, 0x83, 0xdb, 0x45, 0x84, 0x80, 0x83, 0xc7, 0x7f, 0x17, + 0x4e, 0x09, 0x7c, 0x81, 0xe9, 0x82, 0x81, 0x87, 0xcd, 0x78, 0x20, 0xf7, 0xc0, 0xc1, 0xc1, 0xe7, + 0x40, 0x80, 0x83, 0xcb, 0xbd, 0xbf, 0x0f, 0xc5, 0x00, 0xc0, 0x41, 0xf2, 0xff, 0x0f, 0xd7, 0xff, + 0x1b, 0x07, 0xb7, 0xf0, 0xbe, 0xbd, 0xf9, 0x28, 0x3c, 0xfc, 0x01, 0x82, 0x3f, 0xa7, 0xdf, 0xe3, + 0x22, 0x07, 0x9f, 0x03, 0xf4, 0x10, 0x14, 0x7a, 0xde, 0x24, 0x20, 0xf4, 0xfa, 0x07, 0xc6, 0x1c, + 0xbf, 0x4c, 0xfc, 0x82, 0x40, 0x5f, 0x2e, 0x07, 0x20, 0x1e, 0x23, 0x22, 0x6f, 0x95, 0x9c, 0x1e, + 0xb3, 0x0f, 0xff, 0xe3, 0xf6, 0x0c, 0x13, 0xa0, 0xff, 0xe3, 0x20, 0xf5, 0x4a, 0x0f, 0xdd, 0xce, + 0x5c, 0x0f, 0xfc, 0x06, 0x0d, 0x40, 0xc8, 0x11, 0xca, 0x81, 0x00, 0xff, 0xfa, 0x1c, 0x44, 0x00, + 0x1f, 0xf4, 0x24, 0x1e, 0xd0, 0x4f, 0x47, 0xf7, 0xbe, 0x0f, 0x28, 0x0c, 0x22, 0x81, 0x50, 0x07, + 0xa4, 0x0b, 0xd1, 0xe3, 0x0f, 0x98, +}; +const uint8_t _A_Levelup2_128x64_9[] = { + 0x01, 0x00, 0xfb, 0x01, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, + 0xf0, 0x07, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x01, 0x3d, 0xe0, 0xff, 0x06, 0xe4, 0x07, + 0xe0, 0x0f, 0xab, 0xff, 0xfe, 0x7f, 0xfe, 0xe7, 0xe0, 0xc3, 0xd7, 0xdf, 0x80, 0xce, 0x03, 0xf9, + 0x67, 0x80, 0x71, 0xbd, 0xc0, 0xfb, 0xad, 0xc0, 0x20, 0x3e, 0xd0, 0x49, 0xf3, 0xe1, 0x33, 0x2f, + 0x98, 0x3c, 0xe8, 0xb8, 0x08, 0x07, 0xe8, 0x1e, 0x78, 0xfe, 0x4c, 0xcc, 0x1e, 0x98, 0x2a, 0x04, + 0x03, 0x88, 0x71, 0x30, 0x7a, 0xcb, 0xef, 0x58, 0x10, 0x78, 0xee, 0x01, 0xe7, 0x4f, 0x84, 0xc9, + 0xbf, 0x21, 0xf2, 0xdf, 0xe0, 0x24, 0x10, 0x0a, 0x30, 0x3d, 0x39, 0x32, 0x70, 0x7a, 0x40, 0x24, + 0x30, 0x0c, 0x0f, 0xfb, 0x8e, 0x4f, 0x2e, 0x44, 0x1f, 0xf0, 0x0f, 0x2a, 0xfc, 0x02, 0x7f, 0x80, + 0xc0, 0x7f, 0xa0, 0x20, 0xf3, 0xe7, 0xff, 0x0a, 0xc5, 0x5f, 0xe0, 0x00, 0x06, 0x01, 0xfd, 0x0f, + 0x9c, 0x27, 0x9c, 0x0f, 0x2b, 0xfc, 0xbe, 0x41, 0x1e, 0x90, 0xc0, 0x7f, 0xaa, 0x19, 0x97, 0xe4, + 0x2c, 0x31, 0x28, 0x17, 0x08, 0x1f, 0x5d, 0x0e, 0x04, 0x3a, 0x05, 0x3a, 0x07, 0xcc, 0x5e, 0x91, + 0xa1, 0x86, 0x41, 0x38, 0xdf, 0xe1, 0xf0, 0xe0, 0xf3, 0x92, 0x0a, 0x7f, 0xc8, 0x1e, 0x52, 0x88, + 0xf4, 0x17, 0x08, 0x40, 0x10, 0x78, 0xfc, 0xf3, 0x93, 0xc0, 0x7a, 0xc4, 0xa0, 0xb4, 0x86, 0x09, + 0x03, 0xc7, 0x92, 0x0f, 0x8f, 0xc0, 0x3c, 0xf0, 0x7c, 0x91, 0x7c, 0x43, 0x38, 0x3f, 0xb0, 0xfa, + 0x5b, 0xc0, 0xc3, 0xff, 0x9d, 0x93, 0xc6, 0x09, 0x7f, 0xf9, 0x03, 0xcf, 0xc6, 0x0f, 0x4a, 0x5f, + 0x43, 0xe1, 0xc2, 0xc0, 0x7f, 0x2f, 0xa0, 0xf4, 0x37, 0x9e, 0x2f, 0x21, 0x0d, 0x9f, 0xc0, 0x3f, + 0xf3, 0xef, 0xf4, 0x3f, 0x05, 0xf7, 0x90, 0x52, 0x07, 0xe5, 0x0b, 0x90, 0xc0, 0xa0, 0x90, 0x0b, + 0xfd, 0xfd, 0x1f, 0x10, 0xbe, 0x14, 0x06, 0x01, 0x80, 0xdf, 0x83, 0xa0, 0x1e, 0x30, 0x40, 0x78, + 0xf8, 0x3b, 0xe0, 0xe8, 0xfb, 0xc2, 0xe1, 0x00, 0xf1, 0xfc, 0x2f, 0xa4, 0x1e, 0x54, 0x08, 0x07, + 0x3a, 0x06, 0xbf, 0x10, 0x03, 0x78, 0xc1, 0xe3, 0x80, 0xe0, 0xc0, 0xff, 0xeb, 0xf1, 0x0f, 0xbc, + 0x34, 0xba, 0x3f, 0xe8, 0x0f, 0xc1, 0x10, 0x50, 0xf8, 0x01, 0x5c, 0x41, 0xe5, 0x12, 0x81, 0x01, + 0xc4, 0xf8, 0x2b, 0xf1, 0xff, 0xfc, 0xc0, 0x42, 0x75, 0x39, 0x11, 0x38, 0x40, 0x04, 0x0f, 0x28, + 0x68, 0x7c, 0x88, 0xc5, 0xc2, 0x07, 0x1c, 0x00, 0x5e, 0x50, 0x60, 0x31, 0x11, 0x8a, 0x05, 0x03, + 0x03, 0x97, 0x03, 0xf8, 0x0f, 0x98, 0x60, 0x1c, 0xa6, 0x03, 0x82, 0x83, 0x67, 0x31, 0x00, 0xf4, + 0x98, 0x03, 0xcb, 0x9c, 0x0f, 0x3d, 0x16, 0x12, 0x02, 0x0f, 0x3e, 0x00, 0xb8, 0x87, 0xc4, 0x0f, + 0x2c, 0x14, 0x0c, 0x1e, 0x70, 0x02, 0x00, 0xff, 0x01, 0xeb, 0x81, 0x83, 0x83, 0xd2, 0x1c, 0xbf, + 0x10, 0xfe, 0x44, 0x9b, 0xe3, 0xf5, 0x1f, 0xd0, 0x3c, 0xa0, 0x1f, 0x42, 0xfc, 0xce, 0xa0, 0x10, + 0x90, 0x78, 0xfb, 0x01, 0xe6, 0x7f, 0x5a, 0x30, 0x3f, 0x6f, 0xf8, 0x18, 0x04, 0x14, 0x0e, 0x3d, + 0x80, 0x79, 0x15, 0x85, 0x7e, 0x77, 0xf8, 0x0e, 0x05, 0xe0, 0x20, 0xf4, 0x15, 0x93, 0x7c, 0xb7, + 0xf0, 0x0c, 0x13, 0xc0, 0xb5, 0x00, 0xf2, 0x39, 0x96, 0xfc, 0x1e, 0x74, 0x40, 0x7b, 0x41, 0xd4, + 0xe4, 0x05, 0x1a, 0xf8, 0x3c, 0x60, 0x20, 0x81, 0xa4, 0x03, 0xc8, 0x00, 0xb2, 0xf8, 0x04, 0xa0, + 0x1e, 0x58, 0x82, 0x40, 0x80, 0x1a, 0x2e, 0x2b, 0x13, 0x39, 0x42, 0x09, 0x84, 0x00, 0x40, +}; +const uint8_t _A_Levelup2_128x64_10[] = { + 0x01, 0x00, 0x06, 0x02, 0xff, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x1e, 0x00, + 0xf0, 0x07, 0x80, 0x3c, 0x01, 0xe0, 0x0f, 0x00, 0x78, 0x03, 0xc0, 0x09, 0xef, 0x06, 0xe4, 0x07, + 0xe0, 0x0f, 0xc9, 0xff, 0xfb, 0x9f, 0xc7, 0x07, 0xdf, 0x7e, 0x03, 0x38, 0x0f, 0xe5, 0x9e, 0x01, + 0xc6, 0xf7, 0x03, 0xee, 0xb7, 0x00, 0x80, 0xff, 0x4a, 0x27, 0xcf, 0x84, 0xcc, 0xbe, 0x60, 0x51, + 0xbf, 0xff, 0xe8, 0xb8, 0x08, 0x07, 0xe8, 0x2e, 0x78, 0xfe, 0x4c, 0xcc, 0x1e, 0x98, 0x2a, 0x04, + 0x03, 0x88, 0x1f, 0x30, 0x7a, 0xcf, 0xef, 0xd8, 0x10, 0x78, 0xee, 0x01, 0xe7, 0x4f, 0x84, 0xc9, + 0xbf, 0x21, 0xf2, 0xdf, 0xe0, 0x24, 0x10, 0x0a, 0x37, 0xfc, 0xe2, 0x54, 0xfe, 0x4c, 0x9c, 0x1e, + 0x90, 0x09, 0x0c, 0x03, 0x03, 0xfe, 0xd5, 0x93, 0xcb, 0x91, 0x07, 0xfc, 0x11, 0x8a, 0xbf, 0x00, + 0x9f, 0xe0, 0x30, 0x17, 0xe8, 0x89, 0x88, 0x41, 0xe3, 0xcf, 0xfe, 0x03, 0xcf, 0x80, 0x00, 0x18, + 0x07, 0xf4, 0x3e, 0x70, 0x9e, 0x70, 0x3c, 0xe5, 0xf2, 0x08, 0xf4, 0x85, 0x00, 0x2b, 0x19, 0x97, + 0xe4, 0x2c, 0x31, 0x28, 0x17, 0x09, 0x63, 0x1f, 0xe9, 0x7f, 0x43, 0x81, 0x0e, 0x81, 0x4e, 0x95, + 0xd3, 0x17, 0xa4, 0x68, 0x61, 0x90, 0x46, 0x09, 0x73, 0xf0, 0x79, 0xc9, 0x05, 0x3f, 0xe4, 0x1f, + 0x18, 0xbc, 0xa2, 0x3d, 0x05, 0xc2, 0x30, 0x4b, 0x9f, 0xf3, 0xce, 0x4f, 0x01, 0xeb, 0x12, 0x82, + 0xd2, 0x18, 0x24, 0x0f, 0x1e, 0x48, 0x3e, 0x3f, 0x00, 0xf3, 0xc1, 0xf2, 0x45, 0xe5, 0x5f, 0xfa, + 0x0b, 0xce, 0x19, 0xc1, 0xfd, 0x87, 0xd2, 0xde, 0x06, 0x1f, 0xf4, 0xec, 0x9e, 0x30, 0x4b, 0xff, + 0xc8, 0x1e, 0x7e, 0x30, 0x7a, 0x52, 0xfa, 0x1f, 0x0e, 0x16, 0x03, 0xf8, 0x4f, 0x30, 0x78, 0x9b, + 0xcf, 0x17, 0x90, 0x86, 0xcf, 0xe0, 0x01, 0x61, 0xff, 0xc3, 0xf0, 0x5f, 0x79, 0x05, 0x20, 0x9e, + 0x50, 0xb9, 0x0c, 0x0a, 0x09, 0x00, 0xbf, 0xa3, 0xe6, 0x17, 0xc2, 0x80, 0xc0, 0x30, 0x1b, 0xf0, + 0x7d, 0x41, 0x01, 0xe3, 0xe0, 0xef, 0x83, 0xea, 0x10, 0x0f, 0x1f, 0xc3, 0x3a, 0x01, 0xe7, 0x40, + 0x80, 0x73, 0xa0, 0x64, 0xf1, 0x00, 0x37, 0xdc, 0x1e, 0x38, 0x0e, 0x0c, 0x0f, 0xfe, 0x6f, 0x10, + 0x03, 0xc3, 0x4b, 0xa3, 0xfe, 0x80, 0xfc, 0x11, 0x02, 0x70, 0x18, 0x01, 0x5c, 0x41, 0xe5, 0x12, + 0x81, 0x01, 0xc7, 0xfd, 0x0f, 0x5f, 0x8f, 0xff, 0xe6, 0x02, 0x13, 0xb1, 0xc8, 0x89, 0xc2, 0x00, + 0x20, 0x79, 0x43, 0x43, 0xe4, 0x46, 0x2e, 0x10, 0x38, 0xe0, 0x02, 0xf2, 0x83, 0x01, 0x88, 0x8c, + 0x50, 0x28, 0x18, 0x1c, 0xb8, 0x1f, 0xc0, 0x7c, 0xc3, 0x00, 0xe5, 0x30, 0x1c, 0x94, 0x1b, 0x39, + 0x88, 0x07, 0xa4, 0xc0, 0x1e, 0x5c, 0xe0, 0x79, 0xe8, 0xb0, 0x90, 0x10, 0x79, 0xf0, 0x05, 0xc5, + 0xfb, 0x9f, 0x92, 0x44, 0x1e, 0x38, 0x28, 0x18, 0x3c, 0xe0, 0x04, 0x01, 0xfe, 0x7e, 0xc3, 0xe9, + 0x81, 0x83, 0x83, 0xd2, 0x1c, 0xbf, 0x10, 0x7a, 0x87, 0xda, 0x24, 0xdf, 0x1f, 0xaa, 0x20, 0x87, + 0xee, 0x0f, 0x28, 0x07, 0xd0, 0x1e, 0x65, 0xf5, 0x9d, 0x40, 0x21, 0x20, 0xf1, 0xf6, 0x03, 0xcc, + 0xfe, 0xb4, 0x60, 0x7e, 0xdf, 0xf0, 0x30, 0x08, 0x28, 0x1c, 0x7b, 0x00, 0xf2, 0x2b, 0x0a, 0xfc, + 0xef, 0xf0, 0x1c, 0x0b, 0xc0, 0x41, 0xe8, 0x2b, 0x23, 0x29, 0x6f, 0xe0, 0x18, 0x27, 0x81, 0x6a, + 0x01, 0xe4, 0xd2, 0x2d, 0xf8, 0x3c, 0xe8, 0x80, 0xf6, 0x83, 0xa9, 0xc8, 0x0a, 0x35, 0xf0, 0x78, + 0xc0, 0x41, 0x03, 0x48, 0x07, 0x90, 0x01, 0x65, 0xf0, 0x09, 0x40, 0x3c, 0xb1, 0x04, 0x81, 0x00, + 0x34, 0x5c, 0x56, 0x26, 0x72, 0x84, 0x13, 0x08, 0x00, 0x80, +}; +const uint8_t* const _A_Levelup2_128x64[] = { + _A_Levelup2_128x64_0, + _A_Levelup2_128x64_1, + _A_Levelup2_128x64_2, + _A_Levelup2_128x64_3, + _A_Levelup2_128x64_4, + _A_Levelup2_128x64_5, + _A_Levelup2_128x64_6, + _A_Levelup2_128x64_7, + _A_Levelup2_128x64_8, + _A_Levelup2_128x64_9, + _A_Levelup2_128x64_10}; + +const uint8_t _I_125_10px_0[] = { + 0x00, 0xe0, 0x00, 0x00, 0x01, 0x0e, 0x02, 0x31, 0x02, 0x45, 0x02, + 0x91, 0x00, 0xaa, 0x00, 0x92, 0x00, 0x44, 0x00, 0x38, 0x00, +}; +const uint8_t* const _I_125_10px[] = {_I_125_10px_0}; + +const uint8_t _I_Apps_10px_0[] = { + 0x01, 0x00, 0x12, 0x00, 0x00, 0x0c, 0x82, 0x01, 0x88, 0x80, 0x6a, + 0xa0, 0x5a, 0x80, 0x19, 0x00, 0x46, 0x44, 0x07, 0x20, 0x78, 0x80, +}; +const uint8_t* const _I_Apps_10px[] = {_I_Apps_10px_0}; + +const uint8_t _I_Nfc_10px_0[] = { + 0x00, 0x80, 0x00, 0x00, 0x01, 0x22, 0x02, 0x43, 0x02, 0x45, 0x02, + 0x49, 0x02, 0x31, 0x02, 0x22, 0x02, 0x00, 0x01, 0x80, 0x00, +}; +const uint8_t* const _I_Nfc_10px[] = {_I_Nfc_10px_0}; + +const uint8_t _I_back_10px_0[] = { + 0x00, 0x00, 0x00, 0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, + 0x38, 0x00, 0x38, 0x00, 0xf8, 0x01, 0xf8, 0x01, 0x00, 0x00, +}; +const uint8_t* const _I_back_10px[] = {_I_back_10px_0}; + +const uint8_t _I_badusb_10px_0[] = { + 0x01, 0x00, 0x11, 0x00, 0x00, 0x0f, 0xe2, 0x01, 0xfc, 0x80, 0xdd, + 0x20, 0x32, 0x48, 0x08, 0x14, 0x40, 0x23, 0xa8, 0x08, 0xa0, +}; +const uint8_t* const _I_badusb_10px[] = {_I_badusb_10px_0}; + +const uint8_t _I_dir_10px_0[] = { + 0x01, 0x00, 0x11, 0x00, 0x00, 0x0c, 0xfe, 0x01, 0x41, 0x80, 0x7f, + 0xe0, 0x70, 0x18, 0x10, 0x05, 0x7f, 0xd0, 0x10, 0x88, 0x80, +}; +const uint8_t* const _I_dir_10px[] = {_I_dir_10px_0}; + +const uint8_t _I_ibutt_10px_0[] = { + 0x00, 0x80, 0x03, 0x40, 0x02, 0x20, 0x02, 0x10, 0x01, 0x8e, 0x00, + 0x41, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x21, 0x00, 0x1e, 0x00, +}; +const uint8_t* const _I_ibutt_10px[] = {_I_ibutt_10px_0}; + +const uint8_t _I_ir_10px_0[] = { + 0x00, 0xfc, 0x00, 0x02, 0x01, 0x79, 0x02, 0x84, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x30, 0x00, 0x58, 0x00, 0x78, 0x00, 0xff, 0x03, +}; +const uint8_t* const _I_ir_10px[] = {_I_ir_10px_0}; + +const uint8_t _I_keyboard_10px_0[] = { + 0x00, 0x00, 0x00, 0xff, 0x03, 0x01, 0x02, 0x55, 0x02, 0xa9, 0x02, + 0x55, 0x02, 0x01, 0x02, 0xfd, 0x02, 0xff, 0x03, 0x00, 0x00, +}; +const uint8_t* const _I_keyboard_10px[] = {_I_keyboard_10px_0}; + +const uint8_t _I_loading_10px_0[] = { + 0x00, 0xfe, 0x00, 0x82, 0x00, 0xba, 0x00, 0x54, 0x00, 0x28, 0x00, + 0x28, 0x00, 0x44, 0x00, 0x92, 0x00, 0xba, 0x00, 0xfe, 0x00, +}; +const uint8_t* const _I_loading_10px[] = {_I_loading_10px_0}; + +const uint8_t _I_music_10px_0[] = { + 0x01, 0x00, 0x10, 0x00, 0xf0, 0x00, 0x46, 0x03, 0x20, 0x80, + 0x00, 0x4e, 0x7d, 0x00, 0x9f, 0x80, 0x4a, 0x3c, 0x13, 0x20, +}; +const uint8_t* const _I_music_10px[] = {_I_music_10px_0}; + +const uint8_t _I_sub1_10px_0[] = { + 0x01, 0x00, 0x12, 0x00, 0x81, 0x40, 0x69, 0x30, 0x2c, 0x2c, 0x0b, + 0x6a, 0x01, 0x28, 0x0c, 0x0a, 0x65, 0x01, 0x98, 0x40, 0x00, 0x26, +}; +const uint8_t* const _I_sub1_10px[] = {_I_sub1_10px_0}; + +const uint8_t _I_u2f_10px_0[] = { + 0x00, 0x00, 0x00, 0xfe, 0x01, 0x01, 0x02, 0x0c, 0x00, 0xf2, 0x03, + 0x92, 0x02, 0x0c, 0x00, 0x01, 0x02, 0xfe, 0x01, 0x00, 0x00, +}; +const uint8_t* const _I_u2f_10px[] = {_I_u2f_10px_0}; + +const uint8_t _I_unknown_10px_0[] = { + 0x01, 0x00, 0x12, 0x00, 0xbc, 0x40, 0x39, 0x90, 0x0c, 0x24, 0x03, + 0x81, 0x00, 0xb0, 0x40, 0x26, 0x00, 0x12, 0x00, 0x08, 0x14, 0xc0, +}; +const uint8_t* const _I_unknown_10px[] = {_I_unknown_10px_0}; + +const uint8_t _I_update_10px_0[] = { + 0x00, 0xfe, 0x01, 0x01, 0x02, 0xff, 0x03, 0x01, 0x02, 0x31, 0x02, + 0x79, 0x02, 0xfd, 0x02, 0x31, 0x02, 0x31, 0x02, 0xff, 0x03, +}; +const uint8_t* const _I_update_10px[] = {_I_update_10px_0}; + +const uint8_t _I_BLE_Pairing_128x64_0[] = { + 0x01, 0x00, 0xb7, 0x01, 0x00, 0x6c, 0x38, 0x1f, 0xd0, 0x10, 0x76, 0xe0, 0x03, 0xdd, 0x40, 0x07, + 0xf4, 0x82, 0x01, 0x08, 0x07, 0xf4, 0xc0, 0x1f, 0x91, 0x08, 0x07, 0x00, 0x1f, 0xc0, 0x0d, 0x1e, + 0xe8, 0x3f, 0xc0, 0x03, 0x58, 0x80, 0xcf, 0x11, 0xd9, 0xaf, 0x85, 0x77, 0x01, 0xf7, 0x60, 0xf8, + 0x45, 0xff, 0x05, 0xed, 0x9e, 0x7c, 0x09, 0xdb, 0xe0, 0x2f, 0x78, 0x03, 0x3c, 0x8e, 0xee, 0x8a, + 0x43, 0x81, 0xfb, 0x0c, 0x66, 0xe8, 0xfc, 0x59, 0xba, 0x6f, 0x28, 0x1b, 0xfb, 0xa3, 0x80, 0xfc, + 0xa0, 0x1f, 0xc6, 0x86, 0xbf, 0xc3, 0x78, 0xce, 0x04, 0x19, 0x26, 0x77, 0xfa, 0x43, 0xbe, 0x12, + 0xa0, 0x7e, 0xf8, 0x2a, 0xa2, 0x02, 0xff, 0x89, 0x27, 0x01, 0xbf, 0x99, 0x38, 0x8a, 0xfc, 0x0f, + 0x8e, 0x07, 0xfe, 0x0e, 0x94, 0x2c, 0x07, 0xfc, 0x7f, 0x1f, 0xf5, 0x00, 0xc3, 0x00, 0xe4, 0x31, + 0x13, 0xd1, 0x00, 0x0a, 0xb8, 0x19, 0x25, 0x91, 0xc0, 0x81, 0xe2, 0xb9, 0x4d, 0x5d, 0x78, 0x64, + 0x2e, 0x84, 0x80, 0x61, 0x07, 0x02, 0x3e, 0x2a, 0xa4, 0xa2, 0x00, 0xf2, 0x40, 0x20, 0xe3, 0x21, + 0xa0, 0x62, 0x9f, 0x60, 0x05, 0x02, 0x3e, 0x36, 0x41, 0x66, 0x23, 0x20, 0x51, 0xfc, 0x40, 0x68, + 0x0f, 0x15, 0x90, 0x60, 0x20, 0x1b, 0x09, 0x89, 0x70, 0x46, 0x42, 0x07, 0x14, 0x99, 0x41, 0xe8, + 0x1f, 0x18, 0x0c, 0x07, 0xc1, 0x19, 0xff, 0xc3, 0xce, 0x6b, 0x54, 0x8f, 0xe0, 0x3f, 0x90, 0x78, + 0x17, 0x02, 0x1a, 0x70, 0x39, 0x01, 0xa0, 0xb1, 0x53, 0xb5, 0x88, 0xc7, 0xe0, 0x98, 0x08, 0x3a, + 0xd5, 0xe8, 0x97, 0xd0, 0x78, 0xcf, 0xe1, 0x07, 0xf1, 0x0d, 0x08, 0x00, 0x74, 0x10, 0x80, 0x18, + 0xe8, 0x97, 0xc3, 0xf2, 0xff, 0xc4, 0x03, 0xe3, 0x04, 0x8c, 0x19, 0xcc, 0x00, 0x35, 0x0c, 0x3c, + 0x03, 0xf9, 0x3f, 0xb0, 0x8f, 0xc6, 0x31, 0x0e, 0x0f, 0x90, 0x90, 0xb5, 0x45, 0xc1, 0xf8, 0x4f, + 0xf0, 0xde, 0x18, 0xcc, 0x82, 0x08, 0x1f, 0x22, 0x20, 0xd0, 0x3a, 0xab, 0xd1, 0xe0, 0x5f, 0xa1, + 0x1b, 0x19, 0x8d, 0x02, 0x04, 0x9a, 0x1d, 0x04, 0x28, 0x26, 0x36, 0xa8, 0x05, 0xf0, 0xe0, 0x3f, + 0x04, 0xf8, 0xd0, 0x30, 0x55, 0xfa, 0xad, 0x54, 0x3e, 0x35, 0x09, 0xab, 0xac, 0xbf, 0x2b, 0xf2, + 0x0a, 0x0e, 0xfb, 0x55, 0xaa, 0x0f, 0x94, 0x68, 0x04, 0x30, 0x6f, 0xd3, 0x7c, 0xb0, 0x15, 0x0f, + 0xfd, 0x7f, 0xeb, 0x05, 0x4f, 0x0b, 0x60, 0xa3, 0x1f, 0x28, 0x0b, 0xfc, 0xbc, 0x30, 0x1f, 0xf7, + 0xfe, 0x54, 0x2c, 0x18, 0x30, 0x3c, 0x6f, 0x00, 0xf2, 0x1c, 0x8c, 0xf8, 0x10, 0x3c, 0x00, 0xf8, + 0xd5, 0x5c, 0x05, 0xb8, 0xb0, 0xaa, 0xdb, 0x01, 0x2b, 0x31, 0x0a, 0xdc, 0xa7, 0x00, 0xe6, 0x00, + 0x0c, 0x56, 0x00, 0x7e, 0x10, 0x00, 0xcc, 0x01, 0xf0, 0x1f, 0x1b, 0x40, 0x2e, 0x00, 0x07, 0x16, + 0x10, 0x90, 0x02, 0xe5, 0x90, 0x06, 0x29, 0x00, 0x2a, 0xa9, 0x00, 0x2f, 0x10, 0x02, 0xa5, 0x10, + 0x02, 0xf1, 0x00, 0x2a, 0xa0, 0x0d, 0xc0, 0x00, 0xec, 0x01, 0xfd, 0x60, 0x17, 0x6a, 0xc0, 0x60, + 0x40, 0xfd, 0xc0, 0x30, 0x04, 0x01, 0xb0, 0xb0, 0x7f, 0x45, 0x80, +}; +const uint8_t* const _I_BLE_Pairing_128x64[] = {_I_BLE_Pairing_128x64_0}; + +const uint8_t _I_Ble_connected_15x15_0[] = { + 0x00, 0xe0, 0x03, 0xf8, 0x0f, 0x7c, 0x1f, 0x7e, 0x3e, 0x6e, 0x3d, 0x5f, 0x7b, 0x3f, 0x7d, 0x7f, + 0x7e, 0x3f, 0x7d, 0x5f, 0x7b, 0x6e, 0x3d, 0x7e, 0x3e, 0x7c, 0x1f, 0xf8, 0x0f, 0xe0, 0x03, +}; +const uint8_t* const _I_Ble_connected_15x15[] = {_I_Ble_connected_15x15_0}; + +const uint8_t _I_Ble_disconnected_15x15_0[] = { + 0x00, 0xe0, 0x03, 0x18, 0x0c, 0x84, 0x10, 0x82, 0x21, 0x92, 0x22, 0xa1, 0x44, 0xc1, 0x42, 0x81, + 0x41, 0xc1, 0x42, 0xa1, 0x44, 0x92, 0x02, 0x82, 0x21, 0x84, 0x10, 0x18, 0x0c, 0xe0, 0x03, +}; +const uint8_t* const _I_Ble_disconnected_15x15[] = {_I_Ble_disconnected_15x15_0}; + +const uint8_t _I_Button_18x18_0[] = { + 0x01, 0x00, 0x19, 0x00, 0xfc, 0x7f, 0xe0, 0x10, 0x68, 0x04, 0x06, 0x07, 0x00, 0x81, 0x00, + 0xbc, 0x05, 0xe0, 0x23, 0x83, 0xc0, 0x20, 0x7f, 0xef, 0xfc, 0x07, 0xf8, 0x32, 0x10, +}; +const uint8_t* const _I_Button_18x18[] = {_I_Button_18x18_0}; + +const uint8_t _I_Circles_47x47_0[] = { + 0x01, 0x00, 0x7e, 0x00, 0x00, 0x0f, 0xe2, 0x3e, 0x04, 0x2c, 0x04, 0x1f, 0xc0, 0x05, 0x2b, + 0x00, 0x08, 0x60, 0x60, 0x21, 0x8c, 0x00, 0x86, 0x18, 0x02, 0x18, 0x20, 0x08, 0x62, 0x00, + 0xe4, 0x0a, 0x0e, 0x00, 0x40, 0x70, 0x0a, 0x00, 0xb0, 0xe0, 0x32, 0x00, 0x29, 0xc0, 0x80, + 0xaa, 0x1f, 0x21, 0x39, 0x42, 0x00, 0xa7, 0x08, 0x02, 0xa8, 0xd0, 0x86, 0xc4, 0x05, 0x1f, + 0x84, 0x1c, 0x0a, 0x30, 0x22, 0x28, 0x92, 0x46, 0x40, 0x05, 0x11, 0x61, 0x01, 0x4a, 0x02, + 0x3e, 0x10, 0x28, 0x91, 0x04, 0x02, 0x32, 0x08, 0x08, 0x14, 0xe8, 0x00, 0xf2, 0x09, 0x90, + 0x17, 0xc0, 0xbe, 0x05, 0x41, 0x7a, 0x0e, 0xd4, 0x8e, 0xc5, 0x36, 0x2f, 0x99, 0xad, 0x4e, + 0xea, 0x89, 0xb4, 0xda, 0xab, 0x6d, 0x7e, 0xac, 0xb5, 0x6b, 0xab, 0x8d, 0x9d, 0xea, 0xfb, + 0x5c, 0x04, 0x1f, 0xe0, 0x26, 0x3f, 0xc4, 0x3c, 0x06, 0x20, +}; +const uint8_t* const _I_Circles_47x47[] = {_I_Circles_47x47_0}; + +const uint8_t _I_Left_mouse_icon_9x9_0[] = { + 0x01, 0x00, 0x0f, 0x00, 0xbe, 0x40, 0x35, 0xd0, 0x09, 0x7c, + 0x04, 0x02, 0x7e, 0xf8, 0x08, 0x00, 0x70, 0x40, 0xf2, +}; +const uint8_t* const _I_Left_mouse_icon_9x9[] = {_I_Left_mouse_icon_9x9_0}; + +const uint8_t _I_Ok_btn_9x9_0[] = { + 0x01, 0x00, 0x0f, 0x00, 0xbe, 0x40, 0x30, 0x50, 0x09, 0xcc, + 0x06, 0xfa, 0x01, 0x40, 0x38, 0x82, 0xc4, 0x1e, 0x20, +}; +const uint8_t* const _I_Ok_btn_9x9[] = {_I_Ok_btn_9x9_0}; + +const uint8_t _I_Ok_btn_pressed_13x13_0[] = { + 0x01, 0x00, 0x14, 0x00, 0xfc, 0x40, 0xff, 0x90, 0x78, 0x74, 0x3b, 0xef, + 0x1d, 0xfd, 0xc6, 0xc0, 0x2e, 0x0b, 0x10, 0x78, 0x84, 0xc4, 0x2e, 0x20, +}; +const uint8_t* const _I_Ok_btn_pressed_13x13[] = {_I_Ok_btn_pressed_13x13_0}; + +const uint8_t _I_Pressed_Button_13x13_0[] = { + 0x01, 0x00, 0x12, 0x00, 0xf8, 0x40, 0x7f, 0x90, 0x7f, 0xf4, 0x3c, + 0x02, 0x3f, 0xf8, 0xf8, 0x05, 0xc1, 0xa6, 0x13, 0x10, 0xb8, 0x80, +}; +const uint8_t* const _I_Pressed_Button_13x13[] = {_I_Pressed_Button_13x13_0}; + +const uint8_t _I_Right_mouse_icon_9x9_0[] = { + 0x01, 0x00, 0x0f, 0x00, 0xbe, 0x40, 0x3d, 0x50, 0x0f, 0x4c, + 0x04, 0x02, 0x7e, 0xf8, 0x08, 0x00, 0x70, 0x40, 0xf2, +}; +const uint8_t* const _I_Right_mouse_icon_9x9[] = {_I_Right_mouse_icon_9x9_0}; + +const uint8_t _I_Space_65x18_0[] = { + 0x01, 0x00, 0x26, 0x00, 0xfc, 0x7f, 0xc0, 0x09, 0x7f, 0x80, 0x41, 0x81, 0xeb, 0x80, + 0x80, 0x40, 0xc3, 0x2d, 0x01, 0x04, 0x78, 0x23, 0xc1, 0x1e, 0x08, 0xf0, 0x47, 0x82, + 0x3c, 0x11, 0x70, 0x73, 0xeb, 0x40, 0x7f, 0xc8, 0xf5, 0xff, 0xc0, 0x3f, 0x89, 0x87, +}; +const uint8_t* const _I_Space_65x18[] = {_I_Space_65x18_0}; + +const uint8_t _I_Voldwn_6x6_0[] = { + 0x00, + 0x08, + 0x0c, + 0x2f, + 0x2f, + 0x0c, + 0x08, +}; +const uint8_t* const _I_Voldwn_6x6[] = {_I_Voldwn_6x6_0}; + +const uint8_t _I_Volup_8x6_0[] = { + 0x00, + 0x48, + 0x8c, + 0xaf, + 0xaf, + 0x8c, + 0x48, +}; +const uint8_t* const _I_Volup_8x6[] = {_I_Volup_8x6_0}; + +const uint8_t _I_Clock_18x18_0[] = { + 0x01, 0x00, 0x31, 0x00, 0xe0, 0x43, 0xe0, 0x1f, 0x09, 0xfc, 0x03, 0xf1, 0x7f, 0x80, + 0x47, 0x3c, 0x10, 0x0d, 0xf7, 0xde, 0x02, 0x02, 0x2d, 0xff, 0xde, 0x07, 0x7f, 0xfd, + 0xc0, 0xff, 0xff, 0xc0, 0x11, 0xdf, 0xff, 0x30, 0x3d, 0xff, 0xca, 0x07, 0x3e, 0xfa, + 0x85, 0xc7, 0xe5, 0x01, 0x10, 0x10, 0x98, 0x85, 0x84, 0x32, 0x20, +}; +const uint8_t* const _I_Clock_18x18[] = {_I_Clock_18x18_0}; + +const uint8_t _I_Error_18x18_0[] = { + 0x01, 0x00, 0x2c, 0x00, 0xe0, 0x43, 0xe0, 0x1f, 0x09, 0xfc, 0x03, 0xf1, 0x7f, 0x80, 0x7f, 0x3f, + 0xf0, 0x0e, 0x77, 0x3e, 0x03, 0x8e, 0xe3, 0xc0, 0x63, 0xfe, 0x38, 0x1c, 0xff, 0xe1, 0x03, 0xbf, + 0xfe, 0x00, 0x46, 0x08, 0x20, 0x71, 0x05, 0x08, 0x34, 0x42, 0x02, 0x13, 0x10, 0xb0, 0x86, 0x44, +}; +const uint8_t* const _I_Error_18x18[] = {_I_Error_18x18_0}; + +const uint8_t _I_EviSmile1_18x21_0[] = { + 0x01, 0x00, 0x39, 0x00, 0x86, 0x70, 0x20, 0x10, 0x6c, 0x04, 0x06, 0x0f, 0x80, 0x81, 0xf3, 0xf9, + 0xf0, 0x3f, 0xff, 0xfc, 0x04, 0x7f, 0xef, 0xfc, 0x04, 0x04, 0xbf, 0x7d, 0xfc, 0x0f, 0xcf, 0x9f, + 0x81, 0xf1, 0xf1, 0xf0, 0x3c, 0x3e, 0x1e, 0x07, 0x8f, 0xe3, 0x86, 0x9b, 0xbd, 0xef, 0x80, 0xef, + 0x3e, 0x90, 0x0b, 0xc5, 0xe2, 0x01, 0xf0, 0x9f, 0xc0, 0x38, 0x10, 0xf8, 0x00, +}; +const uint8_t* const _I_EviSmile1_18x21[] = {_I_EviSmile1_18x21_0}; + +const uint8_t _I_EviSmile2_18x21_0[] = { + 0x01, 0x00, 0x37, 0x00, 0x00, 0x14, 0x3b, 0x81, 0x01, 0x83, 0xe0, 0x20, 0x7c, 0xfe, 0x7c, + 0x0f, 0xff, 0xff, 0x01, 0x1f, 0xfb, 0xff, 0x01, 0x01, 0x2f, 0x9f, 0x3f, 0x03, 0xe3, 0xe3, + 0xe0, 0x78, 0x7c, 0x3c, 0x0f, 0x1f, 0xc7, 0x0d, 0x37, 0x3b, 0x99, 0x01, 0xcf, 0x79, 0x20, + 0x33, 0xcf, 0x84, 0x03, 0xf1, 0x7f, 0x80, 0x7c, 0x27, 0xf0, 0x0e, 0x04, 0x3e, 0x00, +}; +const uint8_t* const _I_EviSmile2_18x21[] = {_I_EviSmile2_18x21_0}; + +const uint8_t _I_EviWaiting1_18x21_0[] = { + 0x01, 0x00, 0x34, 0x00, 0x86, 0x70, 0x20, 0x10, 0x6c, 0x04, 0x06, 0x0f, 0x80, 0x81, + 0xf3, 0xf9, 0xf0, 0x3f, 0xff, 0xfc, 0x04, 0x7f, 0xef, 0xfc, 0x04, 0x04, 0xa0, 0xb2, + 0xdb, 0xeb, 0xe0, 0x7b, 0xfd, 0xfc, 0x0f, 0x3f, 0x9f, 0x81, 0xf1, 0xf8, 0xe1, 0xa9, + 0xfe, 0x7f, 0xe0, 0x1f, 0x8b, 0xfc, 0x03, 0xe1, 0x3f, 0x80, 0x70, 0x21, 0xf0, 0x00, +}; +const uint8_t* const _I_EviWaiting1_18x21[] = {_I_EviWaiting1_18x21_0}; + +const uint8_t _I_EviWaiting2_18x21_0[] = { + 0x01, 0x00, 0x31, 0x00, 0x86, 0x70, 0x20, 0x10, 0x6c, 0x04, 0x06, 0x0f, 0x80, 0x81, + 0xf3, 0xf9, 0xf0, 0x3f, 0xff, 0xfc, 0x04, 0x7f, 0xef, 0xfc, 0x04, 0x04, 0xa0, 0xb2, + 0xeb, 0xed, 0xe0, 0x7f, 0x7f, 0xb8, 0x08, 0xf1, 0xf8, 0xf0, 0xd4, 0xff, 0x3f, 0xf0, + 0x0f, 0xc5, 0xfe, 0x01, 0xf0, 0x9f, 0xc0, 0x38, 0x10, 0xf8, 0x00, +}; +const uint8_t* const _I_EviWaiting2_18x21[] = {_I_EviWaiting2_18x21_0}; + +const uint8_t _I_Percent_10x14_0[] = { + 0x00, 0x0c, 0x03, 0x1e, 0x03, 0x33, 0x03, 0xb3, 0x03, 0xde, 0x01, 0xec, 0x00, 0x70, 0x00, + 0x38, 0x00, 0xdc, 0x00, 0xee, 0x01, 0x37, 0x03, 0x33, 0x03, 0xe3, 0x01, 0xc3, 0x00, +}; +const uint8_t* const _I_Percent_10x14[] = {_I_Percent_10x14_0}; + +const uint8_t _I_Smile_18x18_0[] = { + 0x01, 0x00, 0x2d, 0x00, 0xe0, 0x43, 0xe0, 0x1f, 0x09, 0xfc, 0x03, 0xf1, 0x7f, + 0x80, 0x7f, 0x3f, 0xf0, 0x0f, 0xf7, 0xfe, 0x02, 0x02, 0x2f, 0xff, 0xfe, 0x07, + 0xcf, 0xe7, 0xc0, 0xf0, 0xf8, 0x70, 0x11, 0x82, 0x08, 0x1c, 0x41, 0x42, 0xdf, + 0x7d, 0xe0, 0x37, 0xcf, 0xc0, 0x98, 0xc5, 0x84, 0x32, 0x20, +}; +const uint8_t* const _I_Smile_18x18[] = {_I_Smile_18x18_0}; + +const uint8_t _I_UsbTree_48x22_0[] = { + 0x01, 0x00, 0x3c, 0x00, 0x00, 0x14, 0x3c, 0x08, 0x78, 0x08, 0xf8, 0x10, 0xff, 0xe0, 0x59, 0xb0, + 0x04, 0x52, 0xc0, 0x1d, 0x48, 0xc0, 0x9d, 0x00, 0xa7, 0x02, 0x80, 0x41, 0x80, 0xa5, 0x0e, 0x02, + 0xa4, 0xfb, 0xfe, 0x00, 0xa1, 0x49, 0x04, 0x48, 0x0a, 0x81, 0xd1, 0xc0, 0x40, 0x45, 0x26, 0x05, + 0x30, 0x01, 0x41, 0xbe, 0x10, 0x30, 0x2c, 0x7e, 0x3f, 0xe0, 0x59, 0x80, 0x04, 0x50, 0x0a, 0x60, +}; +const uint8_t* const _I_UsbTree_48x22[] = {_I_UsbTree_48x22_0}; + +const uint8_t _I_ActiveConnection_50x64_0[] = { + 0x01, 0x00, 0xf4, 0x00, 0xff, 0x40, 0xc0, 0x43, 0xff, 0xff, 0xc0, 0x3f, 0x30, 0x48, 0x04, 0x0a, + 0x01, 0x80, 0x80, 0x40, 0x40, 0xc3, 0xfa, 0xff, 0xef, 0xc0, 0xc7, 0xaa, 0x8f, 0xec, 0x01, 0xa9, + 0xcf, 0xd6, 0x81, 0x8e, 0x95, 0xc4, 0x03, 0x0c, 0x84, 0x1a, 0x50, 0xfd, 0x04, 0x02, 0xd2, 0x0d, + 0x2f, 0xe0, 0x88, 0x76, 0x20, 0xd2, 0x11, 0x15, 0x84, 0x0c, 0x36, 0xa8, 0xf0, 0x19, 0x06, 0xe6, + 0x14, 0x22, 0x29, 0x88, 0x88, 0xa6, 0x63, 0x02, 0xd5, 0x00, 0x04, 0x7c, 0x7f, 0xdf, 0xfd, 0xfe, + 0x02, 0x06, 0x2a, 0xac, 0x04, 0x02, 0x20, 0x61, 0xc0, 0x7f, 0x01, 0xa3, 0x02, 0x03, 0x11, 0xf0, + 0x80, 0xc6, 0x28, 0x1f, 0xfc, 0x0d, 0x08, 0x40, 0x62, 0x80, 0xa4, 0x9a, 0x80, 0x03, 0x28, 0x82, + 0x86, 0x42, 0xc4, 0x3a, 0x10, 0x04, 0x02, 0x88, 0x4e, 0xe2, 0x64, 0x16, 0x18, 0x01, 0xe8, 0x10, + 0x78, 0xb8, 0x1d, 0x31, 0xb0, 0x50, 0x32, 0x76, 0xe0, 0xc0, 0x64, 0xbb, 0x17, 0x04, 0x00, 0x7a, + 0xc1, 0xb2, 0xf6, 0x05, 0x4a, 0x0d, 0x60, 0xdb, 0x0a, 0x58, 0x6e, 0xd2, 0x78, 0x39, 0x4e, 0xa0, + 0x12, 0x00, 0x65, 0x83, 0x7c, 0x19, 0x7f, 0x86, 0x12, 0xaa, 0xce, 0x04, 0x02, 0x1e, 0x17, 0xfe, + 0x3e, 0x0a, 0x39, 0x08, 0x8c, 0x67, 0x90, 0x88, 0x06, 0x02, 0x41, 0x07, 0x93, 0xdf, 0x95, 0x65, + 0xa0, 0xc5, 0x4a, 0x3f, 0xe3, 0x31, 0x90, 0x68, 0x31, 0xd2, 0xb0, 0x31, 0x44, 0x34, 0x18, 0x89, + 0x50, 0x18, 0xc3, 0x64, 0x06, 0x4b, 0x84, 0x82, 0xfd, 0x26, 0x03, 0x10, 0xc0, 0x80, 0xc3, 0x20, + 0xe0, 0x7f, 0xf3, 0xe5, 0xd2, 0x6e, 0x20, 0x18, 0x70, 0x06, 0xb6, 0x59, 0x98, 0x18, 0x8b, 0xa4, + 0xf8, 0x28, 0x07, 0xf0, 0xde, 0x50, 0xf8, 0x00, +}; +const uint8_t* const _I_ActiveConnection_50x64[] = {_I_ActiveConnection_50x64_0}; + +const uint8_t _I_ButtonCenter_7x7_0[] = { + 0x00, + 0x1c, + 0x22, + 0x5d, + 0x5d, + 0x5d, + 0x22, + 0x1c, +}; +const uint8_t* const _I_ButtonCenter_7x7[] = {_I_ButtonCenter_7x7_0}; + +const uint8_t _I_ButtonDown_7x4_0[] = { + 0x00, + 0x7f, + 0x3e, + 0x1c, + 0x08, +}; +const uint8_t* const _I_ButtonDown_7x4[] = {_I_ButtonDown_7x4_0}; + +const uint8_t _I_ButtonLeftSmall_3x5_0[] = { + 0x00, + 0x04, + 0x06, + 0x07, + 0x06, + 0x04, +}; +const uint8_t* const _I_ButtonLeftSmall_3x5[] = {_I_ButtonLeftSmall_3x5_0}; + +const uint8_t _I_ButtonLeft_4x7_0[] = { + 0x00, + 0x08, + 0x0c, + 0x0e, + 0x0f, + 0x0e, + 0x0c, + 0x08, +}; +const uint8_t* const _I_ButtonLeft_4x7[] = {_I_ButtonLeft_4x7_0}; + +const uint8_t _I_ButtonRightSmall_3x5_0[] = { + 0x00, + 0x01, + 0x03, + 0x07, + 0x03, + 0x01, +}; +const uint8_t* const _I_ButtonRightSmall_3x5[] = {_I_ButtonRightSmall_3x5_0}; + +const uint8_t _I_ButtonRight_4x7_0[] = { + 0x00, + 0x01, + 0x03, + 0x07, + 0x0f, + 0x07, + 0x03, + 0x01, +}; +const uint8_t* const _I_ButtonRight_4x7[] = {_I_ButtonRight_4x7_0}; + +const uint8_t _I_ButtonUp_7x4_0[] = { + 0x00, + 0x08, + 0x1c, + 0x3e, + 0x7f, +}; +const uint8_t* const _I_ButtonUp_7x4[] = {_I_ButtonUp_7x4_0}; + +const uint8_t _I_DFU_128x50_0[] = { + 0x01, 0x00, 0x2e, 0x02, 0x00, 0x57, 0xfe, 0x0e, 0x0e, 0xcf, 0x84, 0x02, 0x70, 0x0f, 0xc8, 0x74, + 0x03, 0x80, 0x0e, 0xbc, 0x7c, 0x04, 0x06, 0x30, 0x30, 0x74, 0xe0, 0x2f, 0xe0, 0x42, 0x82, 0x03, + 0xe7, 0x81, 0xff, 0x02, 0x14, 0x20, 0x1f, 0x3e, 0x00, 0x79, 0xc4, 0x01, 0xfd, 0x20, 0x07, 0xd5, + 0xd4, 0xe2, 0x53, 0xf2, 0x74, 0xff, 0xe1, 0x40, 0x41, 0x87, 0xd8, 0x01, 0xf1, 0x60, 0xf0, 0x43, + 0xca, 0x43, 0xe0, 0xa7, 0x83, 0xe2, 0x30, 0x01, 0x29, 0x84, 0x7b, 0x20, 0x0f, 0x88, 0x30, 0x3c, + 0xb1, 0x90, 0x1d, 0x00, 0xfa, 0x30, 0x3f, 0xf8, 0xcc, 0x02, 0xc6, 0x31, 0x1f, 0x83, 0x49, 0xa8, + 0x16, 0x0a, 0xf4, 0x7f, 0x00, 0x21, 0x1f, 0x04, 0x38, 0x06, 0x20, 0x04, 0x90, 0x46, 0x35, 0xf0, + 0xfa, 0x00, 0xcc, 0x7f, 0x10, 0x14, 0x0b, 0x46, 0x20, 0xd5, 0x70, 0x50, 0xb4, 0x06, 0xf1, 0x00, + 0x9f, 0x03, 0xd7, 0x09, 0x81, 0xd7, 0xc0, 0x8b, 0x85, 0x38, 0xc0, 0x50, 0x41, 0xeb, 0x63, 0xc0, + 0x07, 0xc6, 0x90, 0xbf, 0x2b, 0x05, 0x01, 0xb8, 0xb1, 0x0c, 0x06, 0xae, 0x01, 0x24, 0x6f, 0x94, + 0x42, 0x80, 0xb2, 0x49, 0xc4, 0x33, 0x80, 0x1f, 0x18, 0x93, 0xfc, 0xa1, 0x14, 0x0e, 0x02, 0x9c, + 0x43, 0xc3, 0x07, 0x81, 0xfc, 0x03, 0xe2, 0xc0, 0x28, 0x14, 0x10, 0x5e, 0x3f, 0x03, 0xc0, 0xcf, + 0xf8, 0x10, 0x0f, 0xe5, 0x56, 0x03, 0x05, 0xf0, 0x40, 0x20, 0x20, 0xf2, 0x42, 0x0d, 0xfd, 0x72, + 0x30, 0x0f, 0xf8, 0x7c, 0x41, 0xe3, 0x80, 0x10, 0x0d, 0x00, 0x5c, 0x4a, 0xd1, 0x87, 0xf8, 0x39, + 0xf5, 0x5c, 0x0c, 0x0b, 0xe0, 0x1c, 0x10, 0x78, 0xfc, 0x02, 0x04, 0x20, 0x1f, 0xf7, 0x0f, 0x57, + 0x80, 0x81, 0x5e, 0x13, 0x83, 0x01, 0x1f, 0x97, 0xff, 0xfe, 0x03, 0x2e, 0x07, 0x57, 0x03, 0x01, + 0xbf, 0x1d, 0x45, 0x70, 0x27, 0xe4, 0xff, 0x8c, 0x07, 0xf5, 0x83, 0xe0, 0xcf, 0xe1, 0x00, 0xf6, + 0x10, 0x8c, 0x07, 0xb1, 0x07, 0xc1, 0xfc, 0x63, 0xe5, 0xd2, 0x07, 0x8f, 0x80, 0x1a, 0x21, 0xe1, + 0xc0, 0x71, 0xe0, 0x20, 0xf1, 0x24, 0x88, 0x34, 0x62, 0x00, 0xe3, 0x3f, 0x8d, 0xfe, 0x81, 0x80, + 0xc1, 0xf8, 0x5b, 0xe2, 0x0f, 0x18, 0xc7, 0xf0, 0x1e, 0x50, 0x35, 0xa0, 0xc8, 0x3f, 0x98, 0x30, + 0x70, 0x87, 0x44, 0x1e, 0x21, 0xe3, 0xf8, 0x02, 0x4b, 0xaf, 0x01, 0x81, 0xb3, 0xca, 0x01, 0x1c, + 0x25, 0x94, 0x01, 0x04, 0x58, 0x8d, 0x5c, 0x0b, 0xc6, 0x08, 0x10, 0x78, 0xc3, 0x3f, 0xf0, 0x72, + 0x88, 0x98, 0x8b, 0x89, 0x55, 0x82, 0xc7, 0x9b, 0xe5, 0x00, 0x87, 0x26, 0xc4, 0x46, 0x20, 0xf2, + 0xd1, 0x87, 0xc6, 0x0c, 0xdf, 0x21, 0x50, 0x8a, 0xc7, 0x00, 0x38, 0x2e, 0x04, 0x42, 0xaf, 0x05, + 0x06, 0x0a, 0xb8, 0x70, 0x0f, 0x91, 0x80, 0x5c, 0x03, 0xc5, 0x30, 0x84, 0x6a, 0xe1, 0x40, 0xf1, + 0x7b, 0x0f, 0x00, 0x7a, 0x24, 0x21, 0x07, 0x94, 0x33, 0x09, 0x57, 0x8a, 0x93, 0x85, 0xec, 0x3e, + 0x00, 0x79, 0x0b, 0x88, 0x06, 0x3c, 0x3f, 0xfc, 0xa8, 0x1e, 0x21, 0x91, 0x76, 0x90, 0x90, 0x40, + 0x03, 0xe0, 0xe0, 0x78, 0x3f, 0xd5, 0x58, 0x0e, 0x08, 0x32, 0x3f, 0x88, 0xa8, 0x90, 0x8c, 0x25, + 0x30, 0xbc, 0x7f, 0xb5, 0x50, 0x1b, 0xe0, 0x20, 0x7f, 0x92, 0x33, 0x88, 0x97, 0x4a, 0x07, 0x0c, + 0x9e, 0x5f, 0xeb, 0xaa, 0xf2, 0x74, 0x8d, 0x17, 0x80, 0x06, 0x29, 0xf1, 0xe0, 0x71, 0xfb, 0xfd, + 0x71, 0xd8, 0xff, 0xf8, 0x21, 0x71, 0x04, 0x87, 0x01, 0xc1, 0xa1, 0xff, 0x83, 0xe7, 0xf0, 0xff, + 0xc1, 0x51, 0xe4, 0xdd, 0x1b, 0x07, 0xc2, 0x63, 0xf6, 0x0f, 0x9f, 0xeb, 0x5f, 0x02, 0x77, 0x8a, + 0xc4, 0xa3, 0x17, 0xc8, 0x44, 0x8c, 0x34, 0x20, 0x71, 0xfe, 0x99, 0x04, 0x88, 0x40, 0x01, 0xc3, + 0x47, 0xf0, 0x93, 0x0f, 0xf4, 0x28, 0x0e, 0x3a, 0xad, 0x50, 0x39, 0x30, 0x1f, 0x18, 0x3d, 0x0e, + 0x31, 0xff, 0x3d, 0x0c, 0x02, 0xa8, 0x03, 0x20, 0x01, 0x7e, 0x3f, 0xf8, 0x09, 0x06, 0x33, 0xfe, + 0x1b, 0x50, +}; +const uint8_t* const _I_DFU_128x50[] = {_I_DFU_128x50_0}; + +const uint8_t _I_Warning_30x23_0[] = { + 0x01, 0x00, 0x47, 0x00, 0x80, 0x70, 0x00, 0x65, 0xe0, 0x80, 0x80, 0xc7, 0xe1, 0x03, 0x01, + 0xaf, 0xe2, 0x0e, 0x03, 0x19, 0xe4, 0x3c, 0x06, 0xb3, 0xe8, 0xf8, 0x0c, 0x67, 0xf3, 0xf0, + 0x1a, 0x60, 0x27, 0xf7, 0xf1, 0x50, 0xcf, 0xff, 0xe0, 0x34, 0xf0, 0x00, 0xc6, 0x03, 0xf0, + 0x01, 0x8c, 0x0c, 0x06, 0x7f, 0x80, 0x18, 0xc1, 0xff, 0x9f, 0xff, 0xfc, 0x3c, 0x06, 0x7f, + 0xe0, 0x58, 0xc7, 0xff, 0xe0, 0x31, 0x00, 0x88, 0x00, 0x67, 0xff, 0xe0, 0x18, 0xc7, 0xc0, +}; +const uint8_t* const _I_Warning_30x23[] = {_I_Warning_30x23_0}; + +const uint8_t _A_Loading_24_0[] = { + 0x01, 0x00, 0x37, 0x00, 0x00, 0x17, 0x83, 0xff, 0x0f, 0x90, 0x40, 0x21, 0x1c, 0x0f, 0xfc, + 0x1f, 0x01, 0x00, 0x81, 0x60, 0x35, 0x40, 0x21, 0xaa, 0x00, 0x86, 0x51, 0x02, 0x80, 0x44, + 0x60, 0x30, 0x0c, 0x10, 0x6c, 0x6a, 0x80, 0x21, 0x94, 0x00, 0x92, 0x88, 0x02, 0x1c, 0x90, + 0x08, 0x60, 0x30, 0x11, 0x19, 0x80, 0x9c, 0x64, 0x43, 0x82, 0x1f, 0x11, 0x10, 0x80, +}; +const uint8_t _A_Loading_24_1[] = { + 0x01, 0x00, 0x38, 0x00, 0x00, 0x17, 0x83, 0xff, 0x0f, 0x90, 0x40, 0x21, 0x1c, 0x0f, 0xfc, + 0x1f, 0x01, 0x00, 0x81, 0x00, 0x8e, 0xa8, 0x02, 0x19, 0x44, 0x0a, 0x01, 0x11, 0x80, 0xc0, + 0x30, 0x41, 0xb1, 0xa2, 0x00, 0x86, 0x50, 0x02, 0x40, 0x41, 0x64, 0x80, 0x43, 0x01, 0x80, + 0xe0, 0x22, 0x02, 0x34, 0x01, 0x16, 0xaa, 0x04, 0x32, 0x21, 0xc1, 0x0f, 0x88, 0x88, 0x40, +}; +const uint8_t _A_Loading_24_2[] = { + 0x01, 0x00, 0x36, 0x00, 0x00, 0x17, 0x83, 0xff, 0x0f, 0x90, 0x40, 0x21, 0x1c, 0x0f, 0xfc, + 0x1f, 0x01, 0x00, 0x81, 0x00, 0x9a, 0x51, 0x02, 0x80, 0x44, 0x60, 0x30, 0x0c, 0x10, 0x6c, + 0x68, 0x80, 0x21, 0x94, 0x00, 0x92, 0xa8, 0x02, 0x10, 0x71, 0x05, 0x04, 0x3a, 0x70, 0x80, + 0x10, 0xd5, 0x00, 0x43, 0xaa, 0x81, 0x0c, 0x88, 0x70, 0x43, 0xe2, 0x22, 0x10, +}; +const uint8_t _A_Loading_24_3[] = { + 0x01, 0x00, 0x33, 0x00, 0x00, 0x17, 0x83, 0xff, 0x0f, 0x90, 0x40, 0x21, 0x1c, 0x0f, + 0xfc, 0x1f, 0x01, 0x00, 0x81, 0x00, 0xa2, 0x01, 0x01, 0x80, 0xc0, 0x30, 0x41, 0xb1, + 0xa2, 0x00, 0x86, 0x50, 0x02, 0x40, 0x41, 0x64, 0x80, 0x43, 0x29, 0x80, 0xe0, 0x2a, + 0x81, 0xd1, 0xd5, 0x00, 0x84, 0x0a, 0x83, 0x22, 0x1c, 0x10, 0xf8, 0x88, 0x84, +}; +const uint8_t _A_Loading_24_4[] = { + 0x01, 0x00, 0x45, 0x00, 0x80, 0x50, 0x00, 0x43, 0xe0, 0x02, 0x94, 0x06, 0x01, 0xa0, 0x81, + 0x40, 0x22, 0x10, 0x58, 0x04, 0x22, 0x14, 0x02, 0x18, 0xa0, 0x08, 0x65, 0x00, 0x21, 0xa8, + 0x00, 0x84, 0x30, 0x20, 0x51, 0xf0, 0x41, 0xe1, 0x11, 0x00, 0x18, 0xc2, 0x82, 0x63, 0xa7, + 0x89, 0x40, 0x29, 0x51, 0x58, 0x06, 0x50, 0x0a, 0x32, 0x80, 0x28, 0xd4, 0x00, 0xa3, 0xa0, + 0x84, 0x0d, 0x04, 0x5c, 0x38, 0x01, 0xa0, 0xc0, 0x20, 0xe0, 0x21, 0x02, 0x88, +}; +const uint8_t _A_Loading_24_5[] = { + 0x01, 0x00, 0x2b, 0x00, 0x00, 0x74, 0x1a, 0x01, 0x60, 0x85, 0x40, 0x2a, 0x1f, 0xa8, 0x05, 0x7e, + 0x15, 0x81, 0xa8, 0x42, 0xa8, 0x40, 0x21, 0x92, 0x54, 0x2b, 0x51, 0x8a, 0x86, 0xaa, 0x04, 0x05, + 0x18, 0xc8, 0x14, 0x41, 0x64, 0x11, 0x20, 0xb8, 0x87, 0x4c, 0x46, 0x22, 0x92, 0x1c, 0x58, +}; +const uint8_t _A_Loading_24_6[] = { + 0x01, 0x00, 0x3f, 0x00, 0x80, 0x40, 0x80, 0x43, 0x07, 0x80, 0x60, 0x00, 0xa3, 0x40, + 0x82, 0xc0, 0x34, 0x10, 0x88, 0x05, 0x42, 0x21, 0x00, 0x94, 0x00, 0x87, 0x29, 0x12, + 0x80, 0x52, 0xa2, 0xb0, 0x0d, 0x38, 0x15, 0x22, 0x1e, 0x08, 0x38, 0x04, 0x43, 0x03, + 0x08, 0xa8, 0x00, 0x87, 0xc0, 0x05, 0x49, 0x40, 0x08, 0x62, 0x80, 0x21, 0x85, 0x06, + 0x04, 0x60, 0x43, 0x62, 0x80, 0xc0, 0x02, 0xc2, 0x05, 0x18, 0x00, +}; +const uint8_t* const _A_Loading_24[] = { + _A_Loading_24_0, + _A_Loading_24_1, + _A_Loading_24_2, + _A_Loading_24_3, + _A_Loading_24_4, + _A_Loading_24_5, + _A_Loading_24_6}; + +const uint8_t _A_Round_loader_8x8_0[] = { + 0x00, + 0x3c, + 0x42, + 0x81, + 0x81, + 0x81, + 0x81, + 0x42, + 0x3c, +}; +const uint8_t _A_Round_loader_8x8_1[] = { + 0x00, + 0x3c, + 0x72, + 0xf1, + 0xf1, + 0x81, + 0x81, + 0x42, + 0x3c, +}; +const uint8_t _A_Round_loader_8x8_2[] = { + 0x00, + 0x3c, + 0x72, + 0xf1, + 0xf1, + 0xf1, + 0xf1, + 0x72, + 0x3c, +}; +const uint8_t _A_Round_loader_8x8_3[] = { + 0x00, + 0x3c, + 0x72, + 0xf1, + 0xf1, + 0xff, + 0xff, + 0x7e, + 0x3c, +}; +const uint8_t _A_Round_loader_8x8_4[] = { + 0x00, + 0x3c, + 0x7e, + 0xff, + 0xff, + 0xff, + 0xff, + 0x7e, + 0x3c, +}; +const uint8_t* const _A_Round_loader_8x8[] = { + _A_Round_loader_8x8_0, + _A_Round_loader_8x8_1, + _A_Round_loader_8x8_2, + _A_Round_loader_8x8_3, + _A_Round_loader_8x8_4}; + +const uint8_t _I_DolphinCommon_56x48_0[] = { + 0x01, 0x00, 0xdf, 0x00, 0x00, 0x1f, 0xfe, 0x0e, 0x05, 0x3f, 0x04, 0x06, 0x78, 0x06, 0x30, 0x20, + 0xf8, 0x00, 0xc6, 0x12, 0x1c, 0x04, 0x0c, 0x0a, 0x38, 0x08, 0x08, 0x0c, 0x60, 0xc0, 0x21, 0xe0, + 0x04, 0x0a, 0x18, 0x02, 0x1b, 0x00, 0x18, 0xa3, 0x00, 0x21, 0x90, 0x01, 0x8a, 0x20, 0x02, 0x19, + 0x80, 0x18, 0x80, 0x64, 0x09, 0x20, 0x89, 0x81, 0x8c, 0x3e, 0x41, 0xe2, 0x80, 0x50, 0x00, 0x43, + 0x08, 0x01, 0x0c, 0xfc, 0x68, 0x40, 0x61, 0xc0, 0x50, 0x30, 0x00, 0x63, 0xa0, 0x7f, 0x80, 0xc4, + 0x41, 0x19, 0x07, 0xff, 0x02, 0x06, 0x18, 0x24, 0x03, 0x41, 0xf3, 0x2b, 0x10, 0x19, 0x38, 0x10, + 0x30, 0x31, 0x7f, 0xe0, 0x34, 0x08, 0x30, 0x19, 0x60, 0x80, 0x65, 0x86, 0x0a, 0x4c, 0x0c, 0x30, + 0x81, 0xb9, 0x41, 0xa0, 0x54, 0x08, 0xc7, 0xe2, 0x06, 0x8a, 0x18, 0x25, 0x02, 0x21, 0x0f, 0x19, + 0x88, 0xd8, 0x6e, 0x1b, 0x01, 0xd1, 0x1b, 0x86, 0x39, 0x66, 0x3a, 0xa4, 0x1a, 0x50, 0x06, 0x48, + 0x18, 0x18, 0xd0, 0x03, 0x01, 0x41, 0x98, 0xcc, 0x60, 0x39, 0x01, 0x49, 0x2d, 0x06, 0x03, 0x50, + 0xf8, 0x40, 0x3e, 0x02, 0xc1, 0x82, 0x86, 0xc7, 0xfe, 0x0f, 0x28, 0x2c, 0x91, 0xd2, 0x90, 0x9a, + 0x18, 0x19, 0x3e, 0x6d, 0x73, 0x12, 0x16, 0x00, 0x32, 0x49, 0x72, 0xc0, 0x7e, 0x5d, 0x44, 0xba, + 0x2c, 0x08, 0xa4, 0xc8, 0x82, 0x06, 0x17, 0xe0, 0x81, 0x90, 0x2a, 0x40, 0x61, 0xe1, 0xa2, 0x44, + 0x0c, 0x76, 0x2b, 0xe8, 0x89, 0x26, 0x43, 0x83, 0x31, 0x8c, 0x78, 0x0c, 0xb0, 0x48, 0x10, 0x1a, + 0xe0, 0x00, 0x63, +}; +const uint8_t* const _I_DolphinCommon_56x48[] = {_I_DolphinCommon_56x48_0}; + +const uint8_t _I_ArrowDownEmpty_14x15_0[] = { + 0x01, 0x00, 0x17, 0x00, 0xfc, 0x41, 0xe1, 0x10, 0x40, 0x0c, 0xc3, 0xe7, 0x90, 0x19, + 0x04, 0x0a, 0x20, 0x08, 0x10, 0x48, 0xc4, 0x20, 0x52, 0x08, 0x0f, 0x02, 0x00, +}; +const uint8_t* const _I_ArrowDownEmpty_14x15[] = {_I_ArrowDownEmpty_14x15_0}; + +const uint8_t _I_ArrowDownFilled_14x15_0[] = { + 0x00, 0xf8, 0x07, 0x08, 0x04, 0xe8, 0x05, 0x68, 0x05, 0xa8, 0x05, 0x68, 0x05, 0xa8, 0x05, 0x6f, + 0x3d, 0xa1, 0x21, 0xfa, 0x17, 0xf4, 0x0b, 0xe8, 0x05, 0xd0, 0x02, 0x20, 0x01, 0xc0, 0x00, +}; +const uint8_t* const _I_ArrowDownFilled_14x15[] = {_I_ArrowDownFilled_14x15_0}; + +const uint8_t _I_ArrowUpEmpty_14x15_0[] = { + 0x01, 0x00, 0x18, 0x00, 0xe0, 0x40, 0x24, 0x10, 0x18, 0x84, 0x0a, 0x11, 0x04, 0x82, + 0x42, 0x20, 0x51, 0x08, 0x0c, 0x82, 0x1f, 0x3c, 0x04, 0x88, 0x06, 0x7f, 0x10, 0x70, +}; +const uint8_t* const _I_ArrowUpEmpty_14x15[] = {_I_ArrowUpEmpty_14x15_0}; + +const uint8_t _I_ArrowUpFilled_14x15_0[] = { + 0x00, 0xc0, 0x00, 0x20, 0x01, 0xd0, 0x02, 0xe8, 0x05, 0xf4, 0x0b, 0xfa, 0x17, 0x61, 0x21, 0xaf, + 0x3d, 0x68, 0x05, 0xa8, 0x05, 0x68, 0x05, 0xa8, 0x05, 0xe8, 0x05, 0x08, 0x04, 0xf8, 0x07, +}; +const uint8_t* const _I_ArrowUpFilled_14x15[] = {_I_ArrowUpFilled_14x15_0}; + +const uint8_t _I_DolphinReadingSuccess_59x63_0[] = { + 0x01, 0x00, 0x19, 0x01, 0x00, 0x1d, 0x00, 0x0f, 0xd2, 0x00, 0x21, 0xe0, 0x3f, 0xf0, 0xf9, 0x00, + 0x40, 0xee, 0x00, 0x11, 0x88, 0x04, 0x0e, 0x18, 0x11, 0x18, 0x8c, 0x40, 0x0e, 0x50, 0x30, 0x10, + 0xc0, 0xa1, 0x01, 0xe2, 0x05, 0x14, 0x12, 0x08, 0x33, 0x58, 0x44, 0x08, 0x66, 0xa1, 0xe3, 0x01, + 0x9c, 0x83, 0x00, 0x24, 0x11, 0x11, 0x06, 0xc4, 0x76, 0x20, 0x75, 0x15, 0x99, 0x48, 0xc0, 0xe9, + 0x0f, 0x03, 0x95, 0xfc, 0x86, 0x3c, 0x09, 0x80, 0x1c, 0x7c, 0x00, 0x91, 0x81, 0x48, 0x2f, 0xc1, + 0x41, 0x8c, 0xc0, 0x20, 0x30, 0x1c, 0x87, 0xfc, 0x0e, 0x30, 0x70, 0x70, 0x81, 0xc7, 0xe6, 0x07, + 0x18, 0x08, 0x1c, 0xb9, 0x1e, 0x38, 0x0f, 0x02, 0x01, 0xf0, 0x03, 0xa0, 0xa4, 0x7f, 0x90, 0x30, + 0x38, 0xff, 0xe0, 0x28, 0x21, 0xff, 0x06, 0x44, 0x0e, 0x46, 0xe1, 0x01, 0x8c, 0x03, 0x34, 0x2f, + 0x25, 0x18, 0x80, 0xc7, 0x2a, 0x03, 0x2e, 0x01, 0x3c, 0x70, 0x12, 0xa2, 0x39, 0x78, 0x27, 0xe0, + 0x31, 0xea, 0x82, 0xc4, 0x6c, 0x31, 0xf0, 0x78, 0xea, 0xb0, 0x22, 0x31, 0xfc, 0x1a, 0xc6, 0x01, + 0x55, 0x25, 0x88, 0xf8, 0x4b, 0x02, 0x1f, 0x13, 0xe1, 0x7f, 0x97, 0x85, 0x15, 0x03, 0x90, 0xf8, + 0xa0, 0x10, 0xa1, 0xb1, 0x0e, 0x88, 0x00, 0x7f, 0x0f, 0xc0, 0x7c, 0x57, 0x27, 0x3c, 0xb0, 0x7f, + 0x5f, 0xa9, 0x1f, 0xc0, 0x6a, 0xc5, 0x05, 0xc0, 0xf0, 0x11, 0x46, 0xac, 0x18, 0x3f, 0xf9, 0x54, + 0x75, 0x00, 0x73, 0x1f, 0x0f, 0xfe, 0xfe, 0xc6, 0x30, 0x01, 0xbc, 0x48, 0x00, 0x84, 0x82, 0x00, + 0x1b, 0x64, 0xc0, 0x07, 0x60, 0x03, 0xb4, 0x70, 0x0c, 0xbf, 0x82, 0x31, 0x01, 0x8d, 0x0c, 0x40, + 0x02, 0x37, 0x08, 0x1d, 0x74, 0x00, 0x76, 0xa0, 0x01, 0xdb, 0x01, 0xfe, 0x85, 0x8b, 0x96, 0xaa, + 0x9b, 0x30, 0x01, 0x6a, 0xa3, 0x40, 0x75, 0xaa, 0x03, 0xdb, 0x50, 0xbb, 0x30, 0x01, 0x54, 0x24, + 0x25, 0xe6, 0x51, 0x08, 0x1f, 0x68, 0x00, 0x7f, 0x03, 0xf2, 0x79, 0xc0, 0xf4, +}; +const uint8_t* const _I_DolphinReadingSuccess_59x63[] = {_I_DolphinReadingSuccess_59x63_0}; + +const uint8_t _I_Down_25x27_0[] = { + 0x01, 0x00, 0x46, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x08, 0x24, 0x02, 0x81, 0x00, 0x81, 0x40, + 0x30, 0x10, 0x08, 0x08, 0x38, 0x60, 0x20, 0x3f, 0x01, 0x9f, 0xc7, 0xff, 0x1f, 0x01, 0xa7, + 0x87, 0xff, 0x0f, 0x80, 0xf0, 0x7f, 0xf0, 0x78, 0x0e, 0x07, 0xff, 0x03, 0x0b, 0x8f, 0xfc, + 0x04, 0x30, 0x1f, 0xf0, 0x7c, 0xaf, 0x80, 0x32, 0x9c, 0x00, 0xca, 0x20, 0x37, 0xf0, 0x18, + 0xc0, 0xca, 0x63, 0x01, 0x83, 0x40, 0x38, 0x10, 0x0f, 0xe7, 0xfe, 0xfe, 0x67, 0x40, +}; +const uint8_t* const _I_Down_25x27[] = {_I_Down_25x27_0}; + +const uint8_t _I_Down_hvr_25x27_0[] = { + 0x01, 0x00, 0x3a, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x0f, 0xe7, 0xfe, 0xff, 0x00, 0xff, 0x7f, 0xff, + 0xf0, 0x00, 0x10, 0xff, 0xe0, 0x20, 0x3f, 0x01, 0x9c, 0x3e, 0x01, 0xe0, 0x01, 0xa4, 0x7e, 0x01, + 0xf0, 0x80, 0x8b, 0x47, 0xf1, 0x01, 0x16, 0x8f, 0xf0, 0x2e, 0x23, 0x11, 0x01, 0x88, 0x04, 0xf0, + 0x60, 0x32, 0xe3, 0x80, 0xcb, 0xde, 0x37, 0xf0, 0x1a, 0x95, 0xcc, 0xbe, 0x66, 0x73, +}; +const uint8_t* const _I_Down_hvr_25x27[] = {_I_Down_hvr_25x27_0}; + +const uint8_t _I_InfraredArrowDown_4x8_0[] = { + 0x00, + 0xff, + 0x7e, + 0x3c, + 0x18, +}; +const uint8_t* const _I_InfraredArrowDown_4x8[] = {_I_InfraredArrowDown_4x8_0}; + +const uint8_t _I_InfraredArrowUp_4x8_0[] = { + 0x00, + 0x18, + 0x3c, + 0x7e, + 0xff, +}; +const uint8_t* const _I_InfraredArrowUp_4x8[] = {_I_InfraredArrowUp_4x8_0}; + +const uint8_t _I_InfraredLearnShort_128x31_0[] = { + 0x01, 0x00, 0x10, 0x01, 0x00, 0x47, 0xfb, 0xfe, 0x00, 0x38, 0x38, 0x3e, 0x20, 0x20, 0x54, 0x84, + 0x03, 0x9f, 0xc0, 0x06, 0x58, 0x80, 0x3d, 0xf2, 0x00, 0x65, 0x90, 0x03, 0xde, 0x90, 0x06, 0x5a, + 0x07, 0xc0, 0x8a, 0x70, 0x1a, 0x04, 0x02, 0x51, 0x80, 0x03, 0x94, 0x02, 0x3f, 0x40, 0x20, 0x24, + 0x0b, 0x01, 0x00, 0x92, 0x70, 0x35, 0x40, 0x01, 0xe0, 0xdf, 0xf0, 0x10, 0x40, 0x71, 0x58, 0x20, + 0x90, 0x88, 0x0c, 0x4a, 0x81, 0x55, 0x00, 0x0f, 0x87, 0xf7, 0x00, 0x82, 0x43, 0x36, 0x16, 0xdc, + 0x9c, 0x12, 0x21, 0x01, 0x85, 0x70, 0x3f, 0xc1, 0xf1, 0xf8, 0xfc, 0x60, 0x20, 0xf5, 0x90, 0x40, + 0xa1, 0x34, 0x08, 0x18, 0x7c, 0x7e, 0x24, 0x91, 0x07, 0x8c, 0xc0, 0x5e, 0x52, 0x28, 0x14, 0x17, + 0x81, 0x01, 0x0f, 0x8f, 0xe7, 0xe3, 0x03, 0x1f, 0x8e, 0x02, 0xdb, 0x03, 0x8e, 0x49, 0x20, 0x50, + 0x2e, 0x04, 0x72, 0xbd, 0x55, 0xdc, 0xeb, 0xa0, 0x7c, 0x4f, 0x68, 0xbc, 0x60, 0x72, 0x40, 0x79, + 0x50, 0x23, 0x9a, 0x6d, 0x56, 0x66, 0x5c, 0x0f, 0x21, 0x78, 0x9b, 0x04, 0x1e, 0x28, 0x21, 0x8e, + 0x5c, 0x43, 0xe6, 0x2f, 0x10, 0xf9, 0x0b, 0xc7, 0x04, 0x99, 0x18, 0x06, 0xe0, 0x7e, 0x56, 0x32, + 0x78, 0x8f, 0xc4, 0x08, 0x32, 0x20, 0x79, 0x48, 0x2b, 0x85, 0xf2, 0xf8, 0x83, 0xc4, 0x5c, 0x3f, + 0x03, 0x78, 0xd0, 0x81, 0xe3, 0xc0, 0xdf, 0x9f, 0xcb, 0xf3, 0x04, 0xc6, 0x7d, 0xfb, 0xdf, 0x34, + 0x78, 0xd0, 0x45, 0xe5, 0x7e, 0x4f, 0x97, 0xe2, 0x09, 0x80, 0x07, 0x88, 0xbc, 0x61, 0x00, 0xf3, + 0xd8, 0x2f, 0xcb, 0xe0, 0xcf, 0x60, 0x68, 0xd0, 0x30, 0x15, 0xfa, 0xac, 0x36, 0x3f, 0x60, 0x77, + 0xb3, 0x80, 0x5d, 0xe6, 0x4b, 0x20, 0x03, 0x03, 0xc4, 0x01, 0xd0, 0x10, 0x7f, 0x40, 0x81, 0xfc, + 0xa7, 0x10, 0x06, 0x99, 0xd0, 0x01, 0x51, 0x00, 0x7f, 0x48, 0x01, 0xfd, 0xc0, 0x43, 0x98, 0x00, + 0x8e, 0xfe, 0x00, 0xf0, +}; +const uint8_t* const _I_InfraredLearnShort_128x31[] = {_I_InfraredLearnShort_128x31_0}; + +const uint8_t _I_Mode_25x27_0[] = { + 0x01, 0x00, 0x56, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x08, 0x24, 0x02, 0x81, 0x00, 0x81, 0x40, + 0x30, 0x10, 0x08, 0x08, 0x38, 0x60, 0x20, 0x33, 0xb0, 0xc0, 0x21, 0x90, 0x1f, 0x0c, 0x02, + 0x1c, 0x03, 0x18, 0x0c, 0x3c, 0x06, 0x38, 0x30, 0x19, 0x71, 0xc0, 0x65, 0xef, 0x01, 0x97, + 0xfc, 0x06, 0x5f, 0xe0, 0xb9, 0x5f, 0x00, 0x65, 0x38, 0x01, 0x94, 0x40, 0x06, 0x42, 0xb2, + 0xd0, 0xc0, 0x21, 0x50, 0x1a, 0x09, 0x14, 0x40, 0xe4, 0x0f, 0x10, 0x18, 0xc2, 0x01, 0x68, + 0x47, 0x38, 0x19, 0x4c, 0x60, 0x30, 0x68, 0x07, 0x02, 0x01, 0xfc, 0xff, 0xdf, 0xcc, 0xe8, +}; +const uint8_t* const _I_Mode_25x27[] = {_I_Mode_25x27_0}; + +const uint8_t _I_Mode_hvr_25x27_0[] = { + 0x01, 0x00, 0x51, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x0f, 0xe7, 0xfe, 0xff, 0x00, 0xff, 0x7f, + 0xff, 0xf0, 0x00, 0x10, 0xff, 0xe0, 0x20, 0x33, 0xcf, 0xff, 0xfe, 0x70, 0x18, 0xff, 0xff, + 0xe2, 0x03, 0x1f, 0xf7, 0xc0, 0x06, 0x37, 0xc0, 0x19, 0x4e, 0x00, 0x65, 0x10, 0x01, 0x94, + 0x00, 0x06, 0x50, 0x10, 0xb9, 0x60, 0xc0, 0x65, 0xc7, 0x01, 0x97, 0xbc, 0x06, 0x42, 0xb2, + 0xef, 0xff, 0xfe, 0xb0, 0x19, 0xff, 0xff, 0xf6, 0x37, 0x20, 0x78, 0xd7, 0xff, 0xff, 0x78, + 0x0e, 0xfc, 0x16, 0x44, 0xb7, 0x2b, 0x99, 0x7c, 0xcc, 0xe6, +}; +const uint8_t* const _I_Mode_hvr_25x27[] = {_I_Mode_hvr_25x27_0}; + +const uint8_t _I_Mute_25x27_0[] = { + 0x01, 0x00, 0x51, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x08, 0x24, 0x02, 0x81, 0x00, 0x81, 0x40, + 0x30, 0x10, 0x08, 0x08, 0x38, 0x60, 0x20, 0x31, 0x81, 0xc0, 0x64, 0x38, 0x08, 0xa4, 0x06, + 0x83, 0x40, 0x86, 0x40, 0x70, 0x32, 0x08, 0x20, 0x3c, 0x63, 0xf0, 0x60, 0x38, 0xc0, 0xa0, + 0xa0, 0x31, 0xc2, 0x02, 0xc7, 0x03, 0x48, 0x01, 0x94, 0xc0, 0x06, 0xc0, 0xb3, 0x09, 0x98, + 0x6c, 0x84, 0x68, 0x2b, 0x21, 0x99, 0x8e, 0xcc, 0x86, 0x64, 0xb3, 0x81, 0x94, 0xc6, 0x03, + 0x06, 0x80, 0x70, 0x20, 0x1f, 0xcf, 0xfd, 0xfc, 0xce, 0x80, +}; +const uint8_t* const _I_Mute_25x27[] = {_I_Mute_25x27_0}; + +const uint8_t _I_Mute_hvr_25x27_0[] = { + 0x01, 0x00, 0x4a, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x0f, 0xe7, 0xfe, 0xff, 0x00, 0xff, 0x7f, 0xff, + 0xf0, 0x00, 0x10, 0xff, 0xe0, 0x20, 0x21, 0xfe, 0x40, 0x7b, 0xf7, 0xff, 0x5c, 0x07, 0x7f, 0xbf, + 0xf9, 0xc0, 0x6f, 0xfd, 0xff, 0xd8, 0x3c, 0x7c, 0x1f, 0x90, 0x38, 0xff, 0x7f, 0x40, 0x31, 0xbd, + 0x82, 0xc6, 0xff, 0xb7, 0x01, 0x97, 0x3c, 0x06, 0xc0, 0xb3, 0x09, 0x98, 0x6c, 0x84, 0x68, 0x2b, + 0x21, 0x99, 0x8e, 0xcc, 0x86, 0x64, 0xb5, 0x01, 0x89, 0x5c, 0xcb, 0xe6, 0x67, 0x30, +}; +const uint8_t* const _I_Mute_hvr_25x27[] = {_I_Mute_hvr_25x27_0}; + +const uint8_t _I_Power_25x27_0[] = { + 0x01, 0x00, 0x54, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x08, 0x24, 0x02, 0x81, 0x00, 0x81, 0x40, + 0x30, 0x10, 0x08, 0x08, 0x38, 0x60, 0x30, 0x18, 0x80, 0x0c, 0xa7, 0x00, 0x35, 0xc0, 0xce, + 0x60, 0x70, 0x1e, 0x0c, 0xe6, 0x0f, 0x01, 0xf0, 0xce, 0x21, 0xd0, 0x1b, 0x0c, 0xe2, 0x18, + 0x03, 0x58, 0x80, 0x0c, 0xa0, 0x00, 0x39, 0xf0, 0xc0, 0x03, 0x63, 0xc1, 0x80, 0x88, 0xc7, + 0x03, 0x83, 0x15, 0x8c, 0x07, 0xfe, 0x02, 0x18, 0x0d, 0xf0, 0x76, 0x44, 0x73, 0x01, 0x94, + 0x0c, 0xa6, 0x30, 0x18, 0x34, 0x03, 0x81, 0x00, 0xfe, 0x7f, 0xef, 0xe6, 0x74, +}; +const uint8_t* const _I_Power_25x27[] = {_I_Power_25x27_0}; + +const uint8_t _I_Power_hvr_25x27_0[] = { + 0x01, 0x00, 0x4b, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x0f, 0xe7, 0xfe, 0xff, 0x00, 0xff, 0x7f, 0xff, + 0xf0, 0x00, 0x10, 0xff, 0xe0, 0x3f, 0xff, 0x78, 0x0c, 0xb8, 0xe0, 0x35, 0xbf, 0xf1, 0xbf, 0x90, + 0x19, 0xff, 0x1b, 0xf1, 0x01, 0x8f, 0xf1, 0xfe, 0x30, 0x1c, 0xff, 0x1f, 0xe6, 0x03, 0x5f, 0x78, + 0x0c, 0xbf, 0xe0, 0x39, 0x8f, 0xff, 0xc3, 0x63, 0x3f, 0xff, 0x08, 0xc6, 0xff, 0x7c, 0x15, 0x89, + 0x04, 0x7f, 0xc0, 0x31, 0xc1, 0x8e, 0xc8, 0x8e, 0x60, 0x36, 0x2b, 0x99, 0x7c, 0xcc, 0xe6, +}; +const uint8_t* const _I_Power_hvr_25x27[] = {_I_Power_hvr_25x27_0}; + +const uint8_t _I_Rotate_25x27_0[] = { + 0x01, 0x00, 0x4f, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x08, 0x24, 0x02, 0x81, 0x00, 0x81, + 0x40, 0x30, 0x10, 0x08, 0x08, 0x38, 0x60, 0x20, 0x37, 0xb0, 0xdc, 0x00, 0x63, 0xe1, + 0xfe, 0x02, 0x87, 0xc3, 0x8f, 0x81, 0x80, 0xc6, 0x0f, 0x07, 0x01, 0x94, 0x18, 0x06, + 0x30, 0xf8, 0x60, 0x0c, 0x63, 0xe0, 0x35, 0x11, 0x88, 0x0d, 0xc2, 0xe3, 0x81, 0x80, + 0x87, 0xc7, 0x03, 0x83, 0x13, 0x8c, 0x07, 0xfe, 0x02, 0x18, 0x0d, 0xf0, 0x87, 0x30, + 0x32, 0x98, 0xc0, 0x60, 0xd0, 0x0e, 0x04, 0x03, 0xf9, 0xff, 0xbf, 0x99, 0xd0, +}; +const uint8_t* const _I_Rotate_25x27[] = {_I_Rotate_25x27_0}; + +const uint8_t _I_Rotate_hvr_25x27_0[] = { + 0x01, 0x00, 0x48, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x0f, 0xe7, 0xfe, 0xff, 0x00, 0xff, 0x7f, 0xff, + 0xf0, 0x00, 0x10, 0xff, 0xe0, 0x20, 0x37, 0xcf, 0xe3, 0xc0, 0x63, 0x1f, 0x81, 0xff, 0x80, 0x63, + 0x70, 0xfe, 0x00, 0xc7, 0xf1, 0xf8, 0x01, 0x97, 0xe4, 0x06, 0x3f, 0x0f, 0x98, 0x0c, 0x7c, 0x00, + 0x35, 0x11, 0x08, 0x0d, 0xc2, 0xe3, 0x7f, 0xff, 0x07, 0xc6, 0xff, 0x7c, 0x13, 0x89, 0x04, 0x45, + 0xe3, 0xff, 0xc1, 0x90, 0xe4, 0x06, 0x65, 0x73, 0x2f, 0x99, 0x9c, 0xc0, +}; +const uint8_t* const _I_Rotate_hvr_25x27[] = {_I_Rotate_hvr_25x27_0}; + +const uint8_t _I_Swing_25x27_0[] = { + 0x01, 0x00, 0x5a, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x08, 0x24, 0x02, 0x81, 0x00, 0x81, 0x40, 0x30, + 0x10, 0x09, 0x0c, 0x02, 0x11, 0x01, 0x01, 0xa7, 0xfe, 0x12, 0x07, 0x4e, 0x0f, 0xfe, 0x0f, 0x01, + 0x80, 0x88, 0x84, 0x16, 0x39, 0x20, 0x58, 0xc4, 0x40, 0x03, 0x01, 0x84, 0xc4, 0x64, 0x30, 0x1c, + 0x2c, 0x42, 0x84, 0x13, 0x40, 0x1a, 0x48, 0x00, 0xeb, 0xb1, 0xd5, 0x4c, 0x60, 0x38, 0x9d, 0x55, + 0x2a, 0x03, 0x91, 0xd5, 0x42, 0xa0, 0x3a, 0x1d, 0x55, 0xaa, 0x03, 0x19, 0xd2, 0xcc, 0x82, 0xe9, + 0x03, 0x29, 0x8c, 0x06, 0x0d, 0x00, 0xe0, 0x40, 0x3f, 0x9f, 0xfb, 0xf9, 0x9d, 0x00, +}; +const uint8_t* const _I_Swing_25x27[] = {_I_Swing_25x27_0}; + +const uint8_t _I_Swing_hvr_25x27_0[] = { + 0x01, 0x00, 0x52, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x0f, 0xe7, 0xfe, 0xff, 0x00, 0xff, 0x7f, + 0xff, 0xf0, 0x0e, 0xff, 0xff, 0xef, 0x01, 0x01, 0xa4, 0x03, 0xec, 0x07, 0x40, 0xc8, 0xfe, + 0x20, 0x21, 0x61, 0xff, 0x82, 0xc6, 0xda, 0x0b, 0x1f, 0x7f, 0xbb, 0xdd, 0x01, 0xfb, 0xfb, + 0xbb, 0xd0, 0x1b, 0xdf, 0xbf, 0x7a, 0x13, 0x40, 0x1a, 0x09, 0x04, 0x0e, 0x94, 0xfa, 0xaf, + 0x3a, 0x03, 0x77, 0xaa, 0xed, 0x60, 0x36, 0xfa, 0xaf, 0xd6, 0x03, 0x5f, 0xaa, 0xe5, 0x60, + 0x3e, 0x7a, 0xd7, 0x34, 0x47, 0x05, 0x73, 0x2f, 0x99, 0x9c, 0xc0, +}; +const uint8_t* const _I_Swing_hvr_25x27[] = {_I_Swing_hvr_25x27_0}; + +const uint8_t _I_Timer_25x27_0[] = { + 0x01, 0x00, 0x60, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x08, 0x24, 0x02, 0x81, 0x00, 0x81, 0x5f, + 0x30, 0x10, 0x08, 0x0d, 0x10, 0x04, 0x30, 0x19, 0x44, 0x78, 0x06, 0x36, 0xc8, 0x90, 0x0c, + 0x72, 0x70, 0xd8, 0x0f, 0x06, 0x21, 0x06, 0x80, 0xd8, 0x62, 0x10, 0xc8, 0x0e, 0x86, 0x01, + 0x0a, 0x80, 0xc4, 0x60, 0x11, 0x00, 0x18, 0xc0, 0xc0, 0x63, 0x09, 0xc3, 0x48, 0x40, 0x63, + 0xcc, 0x90, 0x40, 0x6f, 0x37, 0x89, 0xe0, 0x1c, 0x66, 0x00, 0x71, 0x84, 0xc0, 0x00, 0x62, + 0x1b, 0x40, 0x19, 0x09, 0xcc, 0x5e, 0x63, 0x73, 0x1f, 0x88, 0x08, 0x60, 0x65, 0x31, 0x80, + 0xc1, 0xa0, 0x1c, 0x08, 0x07, 0xf3, 0xff, 0x7f, 0x33, 0xa0, +}; +const uint8_t* const _I_Timer_25x27[] = {_I_Timer_25x27_0}; + +const uint8_t _I_Timer_hvr_25x27_0[] = { + 0x01, 0x00, 0x5e, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x0f, 0xe7, 0xfe, 0xff, 0x00, 0xff, + 0x60, 0xff, 0xf0, 0x0f, 0xfe, 0xef, 0xff, 0x01, 0xff, 0xf5, 0xfc, 0x20, 0x31, 0xc9, + 0xfb, 0x40, 0x63, 0x6c, 0xf9, 0x40, 0x67, 0xfe, 0xff, 0xcc, 0x07, 0x3f, 0xef, 0xf9, + 0xc0, 0x6b, 0xff, 0xff, 0xac, 0x07, 0xdf, 0xff, 0xf7, 0x80, 0xc7, 0xf8, 0x03, 0x1f, + 0xbd, 0xe7, 0xbc, 0x03, 0x19, 0x9f, 0x7e, 0x03, 0x87, 0xc3, 0xf0, 0xc0, 0xe3, 0xcf, + 0x03, 0x8f, 0xdf, 0xfe, 0x03, 0x10, 0xda, 0x00, 0xc8, 0x4e, 0x62, 0xf3, 0x1b, 0x98, + 0xfc, 0x7f, 0xc0, 0x31, 0x29, 0x8c, 0x07, 0xfd, 0xff, 0x2b, 0x89, 0x7c, 0xcc, 0xe6, +}; +const uint8_t* const _I_Timer_hvr_25x27[] = {_I_Timer_hvr_25x27_0}; + +const uint8_t _I_Up_25x27_0[] = { + 0x01, 0x00, 0x44, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x08, 0x24, 0x02, 0x81, 0x00, 0x81, 0x40, + 0x30, 0x10, 0x08, 0x08, 0x38, 0x60, 0x20, 0x3c, 0x88, 0x00, 0xca, 0x70, 0x03, 0x2b, 0xe0, + 0x0c, 0xbf, 0xc0, 0x32, 0xff, 0x80, 0x87, 0x03, 0xff, 0x81, 0xc0, 0x78, 0x3f, 0xf8, 0x3c, + 0x07, 0xc3, 0xff, 0x87, 0xc0, 0x7e, 0x3f, 0xf8, 0xf8, 0x0d, 0x06, 0xfe, 0x03, 0x78, 0x19, + 0x4c, 0x60, 0x30, 0x68, 0x07, 0x02, 0x01, 0xfc, 0xff, 0xdf, 0xcc, 0xe8, +}; +const uint8_t* const _I_Up_25x27[] = {_I_Up_25x27_0}; + +const uint8_t _I_Up_hvr_25x27_0[] = { + 0x01, 0x00, 0x39, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x0f, 0xe7, 0xfe, 0xff, 0x00, 0xff, 0x7f, 0xff, + 0xf0, 0x00, 0x10, 0xff, 0xe0, 0x20, 0x3c, 0xf7, 0x80, 0xcb, 0x8e, 0x03, 0x2c, 0x18, 0x0c, 0x80, + 0x26, 0x25, 0x18, 0x08, 0xa4, 0x7f, 0x90, 0x11, 0x88, 0xfe, 0x20, 0x31, 0xf8, 0x07, 0xc2, 0x03, + 0x0f, 0x80, 0x78, 0x00, 0x68, 0x37, 0xf0, 0x1d, 0x95, 0xcc, 0xbe, 0x66, 0x73, +}; +const uint8_t* const _I_Up_hvr_25x27[] = {_I_Up_hvr_25x27_0}; + +const uint8_t _I_Vol_down_25x27_0[] = { + 0x01, 0x00, 0x2c, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x08, 0x24, 0x02, 0x81, 0x00, 0x81, 0x40, 0x30, + 0x10, 0x08, 0x08, 0x38, 0x60, 0x20, 0x3f, 0x01, 0xff, 0x07, 0xff, 0x07, 0x01, 0xa0, 0x5f, 0xc0, + 0x7e, 0x03, 0x38, 0x19, 0x4c, 0x60, 0x30, 0x68, 0x07, 0x02, 0x01, 0xfc, 0xff, 0xdf, 0xcc, 0xe8, +}; +const uint8_t* const _I_Vol_down_25x27[] = {_I_Vol_down_25x27_0}; + +const uint8_t _I_Vol_down_hvr_25x27_0[] = { + 0x01, 0x00, 0x23, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x0f, 0xe7, 0xfe, 0xff, 0x00, + 0xff, 0x7f, 0xff, 0xf0, 0x00, 0x10, 0xff, 0xe0, 0x20, 0x3f, 0x01, 0xf8, 0xb4, + 0x7f, 0x00, 0x34, 0x0b, 0xf8, 0x0f, 0xc0, 0x6e, 0x57, 0x32, 0xf9, 0x99, 0xcc, +}; +const uint8_t* const _I_Vol_down_hvr_25x27[] = {_I_Vol_down_hvr_25x27_0}; + +const uint8_t _I_Vol_up_25x27_0[] = { + 0x01, 0x00, 0x2f, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x08, 0x24, 0x02, 0x81, 0x00, + 0x81, 0x40, 0x30, 0x10, 0x08, 0x08, 0x38, 0x60, 0x20, 0x38, 0x88, 0x00, 0xfc, + 0x06, 0xbc, 0x1f, 0xfc, 0x1c, 0x06, 0x81, 0x7f, 0x01, 0xc1, 0x0e, 0xa0, 0x65, + 0x31, 0x80, 0xc1, 0xa0, 0x1c, 0x08, 0x07, 0xf3, 0xff, 0x7f, 0x33, 0xa0, +}; +const uint8_t* const _I_Vol_up_25x27[] = {_I_Vol_up_25x27_0}; + +const uint8_t _I_Vol_up_hvr_25x27_0[] = { + 0x01, 0x00, 0x28, 0x00, 0xfc, 0x7f, 0xe7, 0xf0, 0x0f, 0xe7, 0xfe, 0xff, 0x00, 0xff, 0x7f, + 0xff, 0xf0, 0x00, 0x10, 0xff, 0xe0, 0x20, 0x38, 0xf7, 0x80, 0xfc, 0x06, 0xa2, 0xd1, 0xfc, + 0x00, 0xd0, 0x2f, 0xe0, 0x38, 0x21, 0xd8, 0x0c, 0x8a, 0xe6, 0x5f, 0x33, 0x39, 0x80, +}; +const uint8_t* const _I_Vol_up_hvr_25x27[] = {_I_Vol_up_hvr_25x27_0}; + +const uint8_t _I_DoorLeft_70x55_0[] = { + 0x01, 0x00, 0x19, 0x01, 0x00, 0x2c, 0x32, 0x01, 0x03, 0x04, 0x2c, 0x18, 0x10, 0xf0, 0x40, 0x47, + 0x82, 0x06, 0x81, 0x03, 0xff, 0x80, 0x08, 0x1a, 0x20, 0x82, 0x15, 0x28, 0x21, 0x87, 0x82, 0x08, + 0x6f, 0xc0, 0xb1, 0xe6, 0x10, 0x10, 0x8b, 0x46, 0x20, 0x43, 0x55, 0x8f, 0x82, 0x10, 0x32, 0x73, + 0x0a, 0x09, 0x89, 0x6c, 0x1e, 0x09, 0x00, 0x18, 0x60, 0xf0, 0x0c, 0x84, 0x93, 0x82, 0x03, 0x18, + 0x0c, 0x02, 0x1d, 0x00, 0x90, 0x52, 0x70, 0x50, 0x1e, 0x00, 0x58, 0x63, 0x90, 0x0a, 0x06, 0x4a, + 0x09, 0x03, 0xb0, 0x02, 0x06, 0x70, 0x62, 0x49, 0xf8, 0x0c, 0x66, 0x3f, 0xf0, 0x41, 0x63, 0x04, + 0x43, 0x00, 0x99, 0x60, 0x00, 0x85, 0xc8, 0x06, 0x14, 0xd0, 0x80, 0x3f, 0xc8, 0x0d, 0xb8, 0x10, + 0x70, 0xf8, 0x34, 0x13, 0x03, 0x39, 0x04, 0x1c, 0x42, 0x19, 0xf8, 0xa0, 0xc2, 0x01, 0x07, 0xef, + 0x02, 0x8c, 0x80, 0x10, 0x9d, 0x00, 0x43, 0xec, 0x00, 0xa3, 0x10, 0x04, 0x25, 0xce, 0x19, 0xfc, + 0x88, 0x82, 0x12, 0x0c, 0x35, 0x10, 0x42, 0x4c, 0xa1, 0x90, 0x3f, 0xc0, 0x21, 0x22, 0x39, 0x82, + 0xc8, 0x88, 0xd2, 0x11, 0xf0, 0x01, 0x88, 0xd5, 0x18, 0xe2, 0x08, 0x68, 0x10, 0x0c, 0xa8, 0x00, + 0x83, 0x81, 0xcc, 0xd5, 0xc3, 0x80, 0x84, 0x82, 0x0e, 0xcc, 0xc0, 0x15, 0x79, 0x02, 0x0b, 0x98, + 0xf8, 0x11, 0x88, 0x82, 0x0f, 0x31, 0x19, 0x02, 0x08, 0x2c, 0x9f, 0x6a, 0x1d, 0x20, 0x41, 0x31, + 0x4c, 0x10, 0x8d, 0x73, 0x04, 0x23, 0xa4, 0xc4, 0x6c, 0xde, 0x20, 0x42, 0xcc, 0x01, 0x07, 0x07, + 0xff, 0x80, 0x06, 0x3e, 0x08, 0x38, 0x70, 0x20, 0xa1, 0xe0, 0x83, 0x8e, 0x01, 0x0c, 0xf0, 0x73, + 0x80, 0x43, 0x70, 0x05, 0x08, 0x00, 0x2c, 0x04, 0xc4, 0x46, 0x53, 0x09, 0x98, 0x24, 0x80, 0x65, + 0x80, 0xb0, 0xd9, 0x84, 0x65, 0x32, 0x06, 0x17, 0x0f, 0x98, 0x23, 0x63, 0xe1, 0x88, 0xc4, 0x08, + 0x5f, 0xc1, 0x30, 0x9d, 0x84, 0x4e, 0x66, 0x94, 0x11, 0x98, 0x75, 0x26, 0x00, +}; +const uint8_t* const _I_DoorLeft_70x55[] = {_I_DoorLeft_70x55_0}; + +const uint8_t _I_DoorRight_70x55_0[] = { + 0x01, 0x00, 0x16, 0x01, 0x81, 0xcc, 0x01, 0x0f, 0x60, 0x04, 0x3f, 0x00, 0x10, 0xf8, 0x08, 0x0c, + 0x02, 0x05, 0x01, 0x84, 0x02, 0x06, 0x26, 0x0a, 0x10, 0x8a, 0xcc, 0xe0, 0x1d, 0x68, 0xe0, 0x18, + 0xab, 0xd0, 0x0b, 0x18, 0x10, 0x46, 0xe6, 0x16, 0x1e, 0x18, 0x10, 0x46, 0xe4, 0x28, 0x2c, 0x98, + 0x14, 0x68, 0x00, 0x21, 0x1d, 0x10, 0x8c, 0x40, 0x02, 0x0e, 0x10, 0xa1, 0x08, 0xc8, 0x40, 0x42, + 0x62, 0x11, 0x94, 0x03, 0xfd, 0xff, 0x00, 0x0c, 0xff, 0x0c, 0x08, 0x28, 0x60, 0xe4, 0xc0, 0x85, + 0x00, 0x83, 0x00, 0x87, 0xf1, 0x00, 0x8c, 0x02, 0x0b, 0x07, 0x24, 0x84, 0xff, 0x04, 0xc7, 0x80, + 0xa0, 0xe4, 0xa0, 0x81, 0x41, 0x04, 0x17, 0x02, 0x41, 0x49, 0x81, 0x0e, 0x10, 0xb2, 0xa0, 0x82, + 0x0e, 0x9f, 0xfc, 0x0a, 0x62, 0xf2, 0xc0, 0x03, 0x92, 0xf0, 0x08, 0x2d, 0x78, 0x20, 0xff, 0x02, + 0x01, 0x08, 0xae, 0x60, 0x64, 0x38, 0x0d, 0xb0, 0x8d, 0x08, 0x82, 0x11, 0x58, 0xc4, 0x13, 0xc0, + 0x35, 0x68, 0x62, 0x68, 0x81, 0x09, 0x08, 0x84, 0x40, 0x81, 0x0d, 0x18, 0x69, 0x10, 0x47, 0x44, + 0x66, 0x5f, 0x21, 0xa9, 0x29, 0x94, 0x10, 0x2f, 0x23, 0x53, 0x14, 0x60, 0x42, 0x3c, 0x08, 0xfc, + 0x02, 0x2c, 0x62, 0x23, 0x58, 0xd0, 0x22, 0x00, 0x83, 0x3e, 0x98, 0x44, 0x43, 0x46, 0x22, 0x30, + 0x89, 0xce, 0x01, 0x0f, 0x70, 0x04, 0x3f, 0x81, 0x8a, 0x3c, 0x21, 0xaa, 0x70, 0x1a, 0xe3, 0x44, + 0x1a, 0xa6, 0x01, 0xd2, 0x38, 0x90, 0x8a, 0x40, 0x20, 0xe5, 0x96, 0x80, 0x43, 0x81, 0x06, 0x6b, + 0x28, 0x07, 0xf3, 0xfe, 0x00, 0x19, 0xf9, 0x34, 0xc1, 0x08, 0x8f, 0x20, 0xf1, 0x3e, 0x16, 0x00, + 0xa8, 0x19, 0x00, 0x10, 0x76, 0x03, 0xe2, 0x3e, 0x90, 0x45, 0x38, 0x01, 0x42, 0x05, 0x88, 0x44, + 0x67, 0x15, 0x70, 0x41, 0x38, 0x04, 0x10, 0x24, 0x03, 0x00, 0x10, 0x20, 0x4a, 0x46, 0xe9, 0x46, + 0xe1, 0x04, 0x50, 0x66, 0x40, 0x85, 0x19, 0x98, 0x00, 0xc0, +}; +const uint8_t* const _I_DoorRight_70x55[] = {_I_DoorRight_70x55_0}; + +const uint8_t _I_SmallArrowDown_3x5_0[] = { + 0x00, + 0x1f, + 0x0e, + 0x04, +}; +const uint8_t* const _I_SmallArrowDown_3x5[] = {_I_SmallArrowDown_3x5_0}; + +const uint8_t _I_SmallArrowDown_4x7_0[] = { + 0x00, + 0x7f, + 0x3e, + 0x1c, + 0x08, +}; +const uint8_t* const _I_SmallArrowDown_4x7[] = {_I_SmallArrowDown_4x7_0}; + +const uint8_t _I_SmallArrowUp_3x5_0[] = { + 0x00, + 0x04, + 0x0e, + 0x1f, +}; +const uint8_t* const _I_SmallArrowUp_3x5[] = {_I_SmallArrowUp_3x5_0}; + +const uint8_t _I_SmallArrowUp_4x7_0[] = { + 0x00, + 0x08, + 0x1c, + 0x3e, + 0x7f, +}; +const uint8_t* const _I_SmallArrowUp_4x7[] = {_I_SmallArrowUp_4x7_0}; + +const uint8_t _I_WarningDolphin_45x42_0[] = { + 0x01, 0x00, 0xc6, 0x00, 0x00, 0x1c, 0x22, 0x04, 0x05, 0x7f, 0xfc, 0x1e, 0x20, 0x05, 0x1e, 0x04, + 0x02, 0x30, 0x05, 0x29, 0x84, 0x02, 0xc1, 0x20, 0x02, 0x8c, 0x22, 0x01, 0x80, 0x02, 0x94, 0x10, + 0x32, 0x30, 0x10, 0x10, 0x87, 0xca, 0x84, 0x03, 0x10, 0x42, 0x81, 0x48, 0x28, 0x38, 0x08, 0x04, + 0x3e, 0x01, 0x84, 0x83, 0xe0, 0x30, 0x11, 0x08, 0x05, 0xa2, 0x11, 0x40, 0xa0, 0x4b, 0xc6, 0xc5, + 0x40, 0xd0, 0x56, 0xe0, 0x10, 0x60, 0x29, 0x54, 0xf0, 0x10, 0x18, 0xf0, 0x14, 0x6b, 0xf6, 0x0c, + 0x04, 0x3e, 0x40, 0x05, 0x12, 0x80, 0xc1, 0xe4, 0x01, 0xd2, 0xf8, 0x40, 0xe4, 0x18, 0x09, 0xf4, + 0x03, 0xf1, 0x01, 0x90, 0x40, 0x28, 0x30, 0x0f, 0xe4, 0x00, 0x16, 0x24, 0x11, 0xbf, 0x01, 0x44, + 0xee, 0x53, 0xf0, 0x29, 0xf0, 0x3e, 0x02, 0x91, 0x3b, 0x8c, 0xc3, 0x81, 0x13, 0x90, 0x48, 0x20, + 0x3f, 0xf9, 0xfc, 0x42, 0x60, 0x05, 0x10, 0x98, 0x81, 0x56, 0x11, 0x38, 0x02, 0x9c, 0x1a, 0x31, + 0x1e, 0x02, 0x8f, 0x02, 0x03, 0x1c, 0x90, 0xc0, 0x7c, 0x02, 0xf1, 0xce, 0x02, 0x07, 0x01, 0x1f, + 0x80, 0x63, 0xa8, 0x08, 0x71, 0x3c, 0x8e, 0x39, 0x24, 0x40, 0x51, 0xc7, 0x81, 0x53, 0x0f, 0x3c, + 0x02, 0x9d, 0x1e, 0x38, 0x29, 0x10, 0x29, 0x17, 0xc8, 0x0a, 0x32, 0x3a, 0x00, 0x14, 0x4b, 0xa2, + 0x05, 0x58, 0x98, 0x15, 0x22, 0x20, 0x54, 0x84, 0x81, 0x50, +}; +const uint8_t* const _I_WarningDolphin_45x42[] = {_I_WarningDolphin_45x42_0}; + +const uint8_t _I_KeyBackspaceSelected_16x9_0[] = { + 0x00, 0xfe, 0x7f, 0xff, 0xff, 0xef, 0xff, 0xe7, 0xff, 0x03, + 0xc0, 0xe7, 0xff, 0xef, 0xff, 0xff, 0xff, 0xfe, 0x7f, +}; +const uint8_t* const _I_KeyBackspaceSelected_16x9[] = {_I_KeyBackspaceSelected_16x9_0}; + +const uint8_t _I_KeyBackspace_16x9_0[] = { + 0x00, 0xfe, 0x7f, 0x01, 0x80, 0x11, 0x80, 0x19, 0x80, 0xfd, + 0xbf, 0x19, 0x80, 0x11, 0x80, 0x01, 0x80, 0xfe, 0x7f, +}; +const uint8_t* const _I_KeyBackspace_16x9[] = {_I_KeyBackspace_16x9_0}; + +const uint8_t _I_KeySaveSelected_24x11_0[] = { + 0x01, 0x00, 0x1a, 0x00, 0xff, 0x7f, 0xc0, 0x0d, 0xcf, 0xb4, 0x7c, 0xee, 0xf6, 0xbf, 0x6d, + 0xbe, 0xd7, 0xe1, 0xaf, 0xda, 0xff, 0xbe, 0x7c, 0xc7, 0xcc, 0x28, 0xa1, 0xd1, 0xbf, 0x80, +}; +const uint8_t* const _I_KeySaveSelected_24x11[] = {_I_KeySaveSelected_24x11_0}; + +const uint8_t _I_KeySave_24x11_0[] = { + 0x01, 0x00, 0x1e, 0x00, 0xff, 0x7f, 0xff, 0xf0, 0x18, 0x06, 0x00, 0x04, + 0x53, 0x1c, 0xbe, 0x33, 0x13, 0x94, 0xc9, 0x64, 0x72, 0x99, 0xed, 0x0e, + 0x53, 0x05, 0x19, 0xb3, 0xe3, 0x02, 0x8a, 0x1d, 0x1b, 0xf8, +}; +const uint8_t* const _I_KeySave_24x11[] = {_I_KeySave_24x11_0}; + +const uint8_t _A_125khz_14_0[] = { + 0x00, 0x80, 0x07, 0x00, 0x08, 0x00, 0x13, 0x00, 0x24, 0x0e, 0x28, 0x71, 0x28, 0x85, 0x21, + 0x01, 0x02, 0x62, 0x02, 0x92, 0x02, 0x92, 0x02, 0x64, 0x02, 0x04, 0x01, 0xf8, 0x00, +}; +const uint8_t _A_125khz_14_1[] = { + 0x00, 0x80, 0x07, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x0e, 0x20, 0x71, 0x20, 0x85, 0x21, + 0x01, 0x02, 0x62, 0x02, 0x92, 0x02, 0x92, 0x02, 0x64, 0x02, 0x04, 0x01, 0xf8, 0x00, +}; +const uint8_t _A_125khz_14_2[] = { + 0x01, 0x00, 0x17, 0x00, 0x00, 0x3c, 0x3a, 0x01, 0x71, 0x80, 0x61, 0x60, 0x30, 0x18, + 0x15, 0x8a, 0x05, 0x92, 0x00, 0x95, 0x92, 0x05, 0x04, 0x80, 0xfe, 0x20, 0x00, +}; +const uint8_t _A_125khz_14_3[] = { + 0x01, 0x00, 0x1a, 0x00, 0x00, 0x24, 0x0e, 0x01, 0x04, 0x87, 0x42, 0x2e, 0x30, 0x8c, 0x2c, + 0x06, 0x03, 0x02, 0xb1, 0x40, 0xb2, 0x40, 0x12, 0xb2, 0x40, 0xa0, 0x90, 0x1f, 0xc4, 0x00, +}; +const uint8_t* const _A_125khz_14[] = + {_A_125khz_14_0, _A_125khz_14_1, _A_125khz_14_2, _A_125khz_14_3}; + +const uint8_t _A_BadUsb_14_0[] = { + 0x00, 0xff, 0x1f, 0x01, 0x10, 0x01, 0x10, 0xf1, 0x11, 0xf9, 0x13, 0xe9, 0x12, 0x49, 0x12, + 0xf9, 0x13, 0xf1, 0x11, 0x51, 0x11, 0x01, 0x10, 0xff, 0x1f, 0xfe, 0x0f, 0xfe, 0x0f, +}; +const uint8_t _A_BadUsb_14_1[] = { + 0x00, 0x01, 0x10, 0x01, 0x10, 0xe1, 0x13, 0xfd, 0x10, 0xf9, 0x13, 0x01, 0x17, 0xf9, 0x13, + 0x3d, 0x10, 0xf1, 0x11, 0x01, 0x10, 0xff, 0x1f, 0x06, 0x0c, 0xfe, 0x0f, 0xfe, 0x0f, +}; +const uint8_t _A_BadUsb_14_2[] = { + 0x00, 0x01, 0x10, 0xf1, 0x11, 0xf9, 0x13, 0x59, 0x13, 0xf9, 0x13, 0xe9, 0x12, 0x19, 0x13, + 0xf1, 0x11, 0x01, 0x10, 0xff, 0x1f, 0x04, 0x04, 0xb6, 0x0d, 0xfe, 0x0f, 0xfe, 0x0f, +}; +const uint8_t _A_BadUsb_14_3[] = { + 0x00, 0xf1, 0x11, 0xf9, 0x13, 0x59, 0x13, 0xf9, 0x13, 0xe9, 0x12, 0x19, 0x13, 0xf1, 0x11, + 0x01, 0x10, 0xff, 0x1f, 0x04, 0x04, 0xb4, 0x05, 0x06, 0x0c, 0xfe, 0x0f, 0xfe, 0x0f, +}; +const uint8_t _A_BadUsb_14_4[] = { + 0x00, 0xf9, 0x13, 0xe9, 0x12, 0x19, 0x13, 0xf1, 0x11, 0x01, 0x10, 0xff, 0x1f, 0x04, 0x04, + 0xb4, 0x05, 0x04, 0x04, 0xfc, 0x07, 0xfc, 0x07, 0xfe, 0x0f, 0xfe, 0x0f, 0x02, 0x08, +}; +const uint8_t _A_BadUsb_14_5[] = { + 0x00, 0xf1, 0x11, 0x01, 0x10, 0xff, 0x1f, 0x04, 0x04, 0xb4, 0x05, 0x04, 0x04, 0xfc, 0x07, + 0xfc, 0x07, 0x04, 0x04, 0xfc, 0x07, 0x00, 0x00, 0xfe, 0x0f, 0xfe, 0x0f, 0x02, 0x08, +}; +const uint8_t _A_BadUsb_14_6[] = { + 0x00, 0xf9, 0x13, 0xe9, 0x12, 0x19, 0x13, 0xf1, 0x11, 0x01, 0x10, 0xff, 0x1f, 0x04, 0x04, + 0xb4, 0x05, 0x04, 0x04, 0xfc, 0x07, 0xfc, 0x07, 0xfe, 0x0f, 0xfe, 0x0f, 0x02, 0x08, +}; +const uint8_t _A_BadUsb_14_7[] = { + 0x00, 0xf1, 0x11, 0xf9, 0x13, 0x59, 0x13, 0xf9, 0x13, 0xe9, 0x12, 0x19, 0x13, 0xf1, 0x11, + 0x01, 0x10, 0xff, 0x1f, 0x04, 0x04, 0xb4, 0x05, 0x06, 0x0c, 0xfe, 0x0f, 0xfe, 0x0f, +}; +const uint8_t _A_BadUsb_14_8[] = { + 0x00, 0x01, 0x10, 0xf1, 0x11, 0xf9, 0x13, 0x59, 0x13, 0xf9, 0x13, 0xe9, 0x12, 0x19, 0x13, + 0xf1, 0x11, 0x01, 0x10, 0xff, 0x1f, 0x04, 0x04, 0xb6, 0x0d, 0xfe, 0x0f, 0xfe, 0x0f, +}; +const uint8_t _A_BadUsb_14_9[] = { + 0x00, 0x01, 0x10, 0x01, 0x10, 0xe1, 0x13, 0xfd, 0x10, 0xf9, 0x13, 0x01, 0x17, 0xf9, 0x13, + 0x3d, 0x10, 0xf1, 0x11, 0x01, 0x10, 0xff, 0x1f, 0x06, 0x0c, 0xfe, 0x0f, 0xfe, 0x0f, +}; +const uint8_t _A_BadUsb_14_10[] = { + 0x00, 0xff, 0x1f, 0x01, 0x10, 0x01, 0x10, 0xf1, 0x11, 0xf9, 0x13, 0xe9, 0x12, 0x49, 0x12, + 0xf9, 0x13, 0xf1, 0x11, 0x51, 0x11, 0x01, 0x10, 0xff, 0x1f, 0xfe, 0x0f, 0xfe, 0x0f, +}; +const uint8_t* const _A_BadUsb_14[] = { + _A_BadUsb_14_0, + _A_BadUsb_14_1, + _A_BadUsb_14_2, + _A_BadUsb_14_3, + _A_BadUsb_14_4, + _A_BadUsb_14_5, + _A_BadUsb_14_6, + _A_BadUsb_14_7, + _A_BadUsb_14_8, + _A_BadUsb_14_9, + _A_BadUsb_14_10}; + +const uint8_t _A_Clock_14_0[] = { + 0x00, 0xf0, 0x01, 0x0e, 0x0e, 0x47, 0x1c, 0x03, 0x18, 0x49, 0x12, 0x41, 0x10, 0x41, 0x10, + 0x01, 0x10, 0x09, 0x12, 0x02, 0x08, 0x46, 0x0c, 0x0e, 0x0e, 0xf6, 0x0d, 0x02, 0x08, +}; +const uint8_t _A_Clock_14_1[] = { + 0x00, 0xf0, 0x01, 0x0e, 0x0e, 0x47, 0x1c, 0x03, 0x18, 0x09, 0x13, 0x81, 0x10, 0x41, 0x10, + 0x01, 0x10, 0x09, 0x12, 0x02, 0x08, 0x46, 0x0c, 0x0e, 0x0e, 0xf6, 0x0d, 0x02, 0x08, +}; +const uint8_t _A_Clock_14_2[] = { + 0x00, 0xf0, 0x01, 0x0e, 0x0e, 0x47, 0x1c, 0x03, 0x18, 0x09, 0x12, 0x01, 0x10, 0xc1, 0x11, + 0x01, 0x10, 0x09, 0x12, 0x02, 0x08, 0x46, 0x0c, 0x0e, 0x0e, 0xf6, 0x0d, 0x02, 0x08, +}; +const uint8_t _A_Clock_14_3[] = { + 0x00, 0xf0, 0x01, 0x0e, 0x0e, 0x47, 0x1c, 0x03, 0x18, 0x09, 0x12, 0x01, 0x10, 0x41, 0x10, + 0x81, 0x10, 0x09, 0x13, 0x02, 0x08, 0x46, 0x0c, 0x0e, 0x0e, 0xf6, 0x0d, 0x02, 0x08, +}; +const uint8_t _A_Clock_14_4[] = { + 0x00, 0xf0, 0x01, 0x0e, 0x0e, 0x47, 0x1c, 0x03, 0x18, 0x09, 0x12, 0x01, 0x10, 0x41, 0x10, + 0x41, 0x10, 0x49, 0x12, 0x02, 0x08, 0x46, 0x0c, 0x0e, 0x0e, 0xf6, 0x0d, 0x02, 0x08, +}; +const uint8_t _A_Clock_14_5[] = { + 0x00, 0xf0, 0x01, 0x0e, 0x0e, 0x47, 0x1c, 0x03, 0x18, 0x09, 0x12, 0x01, 0x10, 0x41, 0x10, + 0x21, 0x10, 0x19, 0x12, 0x02, 0x08, 0x46, 0x0c, 0x0e, 0x0e, 0xf6, 0x0d, 0x02, 0x08, +}; +const uint8_t _A_Clock_14_6[] = { + 0x00, 0xf0, 0x01, 0x0e, 0x0e, 0x47, 0x1c, 0x03, 0x18, 0x09, 0x12, 0x01, 0x10, 0x71, 0x10, + 0x01, 0x10, 0x09, 0x12, 0x02, 0x08, 0x46, 0x0c, 0x0e, 0x0e, 0xf6, 0x0d, 0x02, 0x08, +}; +const uint8_t _A_Clock_14_7[] = { + 0x00, 0xf0, 0x01, 0x0e, 0x0e, 0x47, 0x1c, 0x03, 0x18, 0x19, 0x12, 0x21, 0x10, 0x41, 0x10, + 0x01, 0x10, 0x09, 0x12, 0x02, 0x08, 0x46, 0x0c, 0x0e, 0x0e, 0xf6, 0x0d, 0x02, 0x08, +}; +const uint8_t* const _A_Clock_14[] = { + _A_Clock_14_0, + _A_Clock_14_1, + _A_Clock_14_2, + _A_Clock_14_3, + _A_Clock_14_4, + _A_Clock_14_5, + _A_Clock_14_6, + _A_Clock_14_7}; + +const uint8_t _A_Debug_14_0[] = { + 0x00, 0x20, 0x01, 0xc1, 0x20, 0x22, 0x11, 0x24, 0x09, 0xd9, 0x26, 0x16, 0x1a, 0xd8, 0x06, + 0xd8, 0x06, 0xd6, 0x1a, 0x19, 0x26, 0xe4, 0x09, 0xc2, 0x10, 0x01, 0x20, 0x00, 0x00, +}; +const uint8_t _A_Debug_14_1[] = { + 0x00, 0x20, 0x01, 0xc0, 0x00, 0x22, 0x11, 0x25, 0x29, 0xd8, 0x06, 0x16, 0x1a, 0xd9, 0x26, + 0xd8, 0x06, 0xd4, 0x0a, 0x12, 0x12, 0xea, 0x15, 0xc5, 0x28, 0x02, 0x10, 0x02, 0x10, +}; +const uint8_t _A_Debug_14_2[] = { + 0x00, 0x20, 0x01, 0xc0, 0x00, 0x20, 0x01, 0x24, 0x09, 0xda, 0x16, 0x11, 0x22, 0xdc, 0x0e, + 0xda, 0x16, 0xd9, 0x26, 0x14, 0x0a, 0xf2, 0x13, 0xd1, 0x22, 0x08, 0x04, 0x06, 0x18, +}; +const uint8_t _A_Debug_14_3[] = { + 0x00, 0x22, 0x11, 0xc4, 0x08, 0x24, 0x09, 0x25, 0x29, 0xd9, 0x26, 0x12, 0x12, 0xdc, 0x0e, + 0xd8, 0x06, 0xd8, 0x06, 0x14, 0x0a, 0xf4, 0x0b, 0xd2, 0x12, 0x19, 0x26, 0x06, 0x18, +}; +const uint8_t* const _A_Debug_14[] = {_A_Debug_14_0, _A_Debug_14_1, _A_Debug_14_2, _A_Debug_14_3}; + +const uint8_t _A_FileManager_14_0[] = { + 0x00, 0xfc, 0x07, 0x04, 0x04, 0xf4, 0x05, 0x04, 0x04, 0xf7, 0x05, 0x05, 0x04, 0xf5, 0x3f, + 0x15, 0x20, 0x0d, 0x20, 0x0d, 0x10, 0x05, 0x10, 0x05, 0x08, 0x03, 0x08, 0xfe, 0x07, +}; +const uint8_t _A_FileManager_14_1[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x04, 0x04, 0xf7, 0x05, 0x05, 0x04, 0xf5, 0x3f, + 0x15, 0x20, 0x0d, 0x20, 0x0d, 0x10, 0x05, 0x10, 0x05, 0x08, 0x03, 0x08, 0xfe, 0x07, +}; +const uint8_t _A_FileManager_14_2[] = { + 0x01, 0x00, 0x17, 0x00, 0x00, 0x3f, 0xfe, 0x0f, 0x05, 0x82, 0x7d, 0x67, 0xf1, 0x59, + 0x04, 0x34, 0x02, 0x31, 0x08, 0x28, 0x04, 0x61, 0x10, 0x38, 0x47, 0xfa, 0x0e, +}; +const uint8_t _A_FileManager_14_3[] = { + 0x01, 0x00, 0x17, 0x00, 0x00, 0x3c, 0x3e, 0x01, 0x11, 0x80, 0x7f, 0x67, 0xf1, 0x59, + 0x04, 0x34, 0x02, 0x31, 0x08, 0x28, 0x04, 0x61, 0x10, 0x38, 0x47, 0xfa, 0x0e, +}; +const uint8_t _A_FileManager_14_4[] = { + 0x01, 0x00, 0x17, 0x00, 0x00, 0x3c, 0x3e, 0x01, 0x11, 0x80, 0x7c, 0x67, 0xf1, 0x19, + 0x04, 0x34, 0x02, 0x31, 0x08, 0x28, 0x04, 0x61, 0x10, 0x38, 0x47, 0xfa, 0x0e, +}; +const uint8_t _A_FileManager_14_5[] = { + 0x01, 0x00, 0x0f, 0x00, 0x00, 0x3c, 0x3e, 0x01, 0x11, 0x80, + 0x7f, 0xe0, 0xf0, 0x18, 0x40, 0x06, 0x7f, 0xd0, 0x70, +}; +const uint8_t _A_FileManager_14_6[] = { + 0x01, 0x00, 0x17, 0x00, 0x00, 0x3c, 0x3e, 0x01, 0x11, 0x80, 0x7c, 0x67, 0xf1, 0x19, + 0x04, 0x34, 0x02, 0x31, 0x08, 0x28, 0x04, 0x61, 0x10, 0x38, 0x47, 0xfa, 0x0e, +}; +const uint8_t _A_FileManager_14_7[] = { + 0x01, 0x00, 0x17, 0x00, 0x00, 0x3c, 0x3e, 0x01, 0x11, 0x80, 0x7f, 0x67, 0xf1, 0x59, + 0x04, 0x34, 0x02, 0x31, 0x08, 0x28, 0x04, 0x61, 0x10, 0x38, 0x47, 0xfa, 0x0e, +}; +const uint8_t _A_FileManager_14_8[] = { + 0x01, 0x00, 0x17, 0x00, 0x00, 0x3f, 0xfe, 0x0f, 0x05, 0x82, 0x7d, 0x67, 0xf1, 0x59, + 0x04, 0x34, 0x02, 0x31, 0x08, 0x28, 0x04, 0x61, 0x10, 0x38, 0x47, 0xfa, 0x0e, +}; +const uint8_t _A_FileManager_14_9[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x04, 0x04, 0xf7, 0x05, 0x05, 0x04, 0xf5, 0x3f, + 0x15, 0x20, 0x0d, 0x20, 0x0d, 0x10, 0x05, 0x10, 0x05, 0x08, 0x03, 0x08, 0xfe, 0x07, +}; +const uint8_t* const _A_FileManager_14[] = { + _A_FileManager_14_0, + _A_FileManager_14_1, + _A_FileManager_14_2, + _A_FileManager_14_3, + _A_FileManager_14_4, + _A_FileManager_14_5, + _A_FileManager_14_6, + _A_FileManager_14_7, + _A_FileManager_14_8, + _A_FileManager_14_9}; + +const uint8_t _A_GPIO_14_0[] = { + 0x01, 0x00, 0x15, 0x00, 0xa2, 0x41, 0x00, 0x23, 0xee, 0x87, 0x00, 0x54, 0x16, + 0x60, 0x11, 0x09, 0x8f, 0xfe, 0x3f, 0x11, 0x88, 0xd5, 0x62, 0xa0, 0x31, +}; +const uint8_t _A_GPIO_14_1[] = { + 0x01, 0x00, 0x12, 0x00, 0xa2, 0x41, 0x00, 0x27, 0xee, 0x87, 0x00, + 0x54, 0x1a, 0xbf, 0xf8, 0xfc, 0x46, 0x23, 0x55, 0x8a, 0x80, 0xc4, +}; +const uint8_t _A_GPIO_14_2[] = { + 0x01, 0x00, 0x12, 0x00, 0xa2, 0x41, 0x00, 0x2f, 0xee, 0x87, 0x00, + 0x54, 0x12, 0x3f, 0xf8, 0xfd, 0x56, 0x2a, 0x01, 0x18, 0x8c, 0x44, +}; +const uint8_t _A_GPIO_14_3[] = { + 0x01, 0x00, 0x11, 0x00, 0xa2, 0x41, 0x00, 0x37, 0xee, 0x87, 0x00, + 0x4f, 0xff, 0x1f, 0xaa, 0xc5, 0x40, 0x23, 0x11, 0x88, 0x80, +}; +const uint8_t _A_GPIO_14_4[] = { + 0x01, + 0x00, + 0x0d, + 0x00, + 0xa2, + 0x41, + 0x00, + 0x3f, + 0xee, + 0x87, + 0x7f, + 0xe3, + 0xe0, + 0x13, + 0x88, + 0xc4, + 0x40, +}; +const uint8_t _A_GPIO_14_5[] = { + 0x01, 0x00, 0x11, 0x00, 0xa2, 0x41, 0x00, 0x3b, 0xee, 0x87, 0x00, + 0x47, 0xff, 0x1f, 0x00, 0x8d, 0x56, 0x2b, 0x11, 0x88, 0x80, +}; +const uint8_t _A_GPIO_14_6[] = { + 0x01, 0x00, 0x11, 0x00, 0xa2, 0x41, 0x00, 0x33, 0xee, 0x87, 0x00, + 0x57, 0xff, 0x1f, 0xaa, 0xc5, 0x40, 0x23, 0x11, 0x88, 0x80, +}; +const uint8_t _A_GPIO_14_7[] = { + 0x01, 0x00, 0x12, 0x00, 0xa2, 0x41, 0x00, 0x2b, 0xee, 0x87, 0x00, + 0x54, 0x16, 0x7f, 0xf8, 0xfc, 0x46, 0x23, 0x55, 0x8a, 0x80, 0xc4, +}; +const uint8_t* const _A_GPIO_14[] = { + _A_GPIO_14_0, + _A_GPIO_14_1, + _A_GPIO_14_2, + _A_GPIO_14_3, + _A_GPIO_14_4, + _A_GPIO_14_5, + _A_GPIO_14_6, + _A_GPIO_14_7}; + +const uint8_t _A_Infrared_14_0[] = { + 0x01, 0x00, 0x1a, 0x00, 0xfc, 0x41, 0xe0, 0xd1, 0x88, 0x0c, 0x83, 0xe1, 0x03, 0x84, 0x41, + 0x01, 0x63, 0xe0, 0x80, 0x84, 0x4c, 0x0a, 0x20, 0xd1, 0x0a, 0x88, 0x04, 0x7f, 0xf3, 0xf0, +}; +const uint8_t _A_Infrared_14_1[] = { + 0x01, 0x00, 0x17, 0x00, 0xfc, 0x41, 0xe0, 0xd1, 0x88, 0x0c, 0x83, 0xe1, 0x03, 0x84, + 0x41, 0x02, 0x2f, 0xe0, 0x80, 0x83, 0x44, 0x2a, 0x20, 0x11, 0xff, 0xcf, 0xc0, +}; +const uint8_t _A_Infrared_14_2[] = { + 0x01, 0x00, 0x13, 0x00, 0xfc, 0x41, 0xe0, 0xd1, 0x88, 0x0c, 0x80, 0x23, + 0x7e, 0x08, 0x0f, 0xc2, 0x06, 0x15, 0x10, 0x08, 0xff, 0xe7, 0xe0, +}; +const uint8_t _A_Infrared_14_3[] = { + 0x01, + 0x00, + 0x0e, + 0x00, + 0x00, + 0x78, + 0x00, + 0x7c, + 0x10, + 0x1f, + 0x84, + 0x0f, + 0xf1, + 0x07, + 0x00, + 0x8f, + 0xfe, + 0x7e, +}; +const uint8_t _A_Infrared_14_4[] = { + 0x01, + 0x00, + 0x0e, + 0x00, + 0x00, + 0x5f, + 0x82, + 0x02, + 0x05, + 0x5f, + 0x84, + 0x0f, + 0xf1, + 0x07, + 0x00, + 0x8f, + 0xfe, + 0x7e, +}; +const uint8_t _A_Infrared_14_5[] = { + 0x01, 0x00, 0x15, 0x00, 0x00, 0x2f, 0xc2, 0x07, 0x08, 0x82, 0x01, 0x47, 0xc1, + 0x01, 0x05, 0x98, 0x14, 0x41, 0xa3, 0xf8, 0x83, 0x80, 0x47, 0xff, 0x3f, +}; +const uint8_t* const _A_Infrared_14[] = { + _A_Infrared_14_0, + _A_Infrared_14_1, + _A_Infrared_14_2, + _A_Infrared_14_3, + _A_Infrared_14_4, + _A_Infrared_14_5}; + +const uint8_t _A_NFC_14_0[] = { + 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x12, 0x00, 0x22, 0x42, 0x24, 0x87, 0x24, 0x8d, 0x24, + 0x99, 0x24, 0xf1, 0x24, 0x62, 0x24, 0x00, 0x22, 0x00, 0x12, 0x00, 0x10, 0x00, 0x08, +}; +const uint8_t _A_NFC_14_1[] = { + 0x01, 0x00, 0x1a, 0x00, 0x80, 0x42, 0x20, 0x11, 0x00, 0x09, 0x48, 0x28, 0x52, 0x0c, 0x3c, + 0x83, 0x1b, 0x20, 0xcc, 0xc8, 0x3e, 0x32, 0x0b, 0x14, 0x80, 0x1a, 0x21, 0x34, 0x84, 0x00, +}; +const uint8_t _A_NFC_14_2[] = { + 0x01, 0x00, 0x10, 0x00, 0x00, 0x3d, 0x0a, 0x01, 0x87, 0x80, + 0x63, 0x60, 0x19, 0x98, 0x07, 0xc6, 0x01, 0x62, 0x09, 0xc0, +}; +const uint8_t _A_NFC_14_3[] = { + 0x01, 0x00, 0x16, 0x00, 0x00, 0x24, 0x08, 0x02, 0x34, 0x28, 0x26, 0x1e, 0x09, + 0x8d, 0x82, 0x66, 0x60, 0x9f, 0x18, 0x25, 0x8a, 0x08, 0x0f, 0x30, 0xb1, 0x80, +}; +const uint8_t* const _A_NFC_14[] = {_A_NFC_14_0, _A_NFC_14_1, _A_NFC_14_2, _A_NFC_14_3}; + +const uint8_t _A_Plugins_14_0[] = { + 0x00, 0xe7, 0x00, 0xa5, 0x00, 0x99, 0x01, 0x01, 0x02, 0x01, 0x02, 0x81, 0x01, 0x81, 0x0e, + 0xe7, 0x08, 0x24, 0x18, 0x58, 0x20, 0x40, 0x20, 0x30, 0x18, 0x10, 0x08, 0xf0, 0x0f, +}; +const uint8_t _A_Plugins_14_1[] = { + 0x00, 0x70, 0x0e, 0x50, 0x0a, 0x90, 0x19, 0x10, 0x20, 0x10, 0x20, 0x18, 0x18, 0x1e, 0x08, + 0x72, 0x0e, 0x46, 0x02, 0x88, 0x05, 0x08, 0x04, 0x06, 0x03, 0x02, 0x01, 0xfe, 0x01, +}; +const uint8_t _A_Plugins_14_2[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xe4, 0x1c, 0xa7, 0x14, 0x21, 0x33, 0x23, 0x00, + 0x24, 0x00, 0x24, 0x30, 0x23, 0x10, 0xe1, 0x1c, 0xff, 0x04, 0x00, 0x03, 0x00, 0x00, +}; +const uint8_t _A_Plugins_14_3[] = { + 0x00, 0x30, 0x00, 0x48, 0x00, 0xce, 0x01, 0x02, 0x01, 0x3e, 0x07, 0x28, 0x05, 0xc8, 0x0c, + 0x0e, 0x10, 0x0a, 0x10, 0x0e, 0x0c, 0x08, 0x04, 0x38, 0x07, 0x20, 0x01, 0xc0, 0x00, +}; +const uint8_t _A_Plugins_14_4[] = { + 0x00, 0x40, 0x02, 0x70, 0x0e, 0x10, 0x08, 0x30, 0x18, 0xce, 0x21, 0x4a, 0x21, 0x32, 0x1b, + 0x02, 0x0c, 0x02, 0x0c, 0x02, 0x03, 0x02, 0x01, 0xce, 0x01, 0x48, 0x00, 0x30, 0x00, +}; +const uint8_t _A_Plugins_14_5[] = { + 0x00, 0x00, 0x0c, 0x00, 0x12, 0x80, 0x33, 0x80, 0x00, 0xb9, 0x01, 0x29, 0x02, 0x66, 0x02, + 0x80, 0x01, 0x80, 0x00, 0x60, 0x3f, 0x20, 0x00, 0x39, 0x00, 0x09, 0x00, 0x06, 0x00, +}; +const uint8_t _A_Plugins_14_6[] = { + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x09, 0xf3, 0x39, 0x52, 0x20, 0xcc, 0x20, 0x00, 0x01, + 0x00, 0x01, 0xc0, 0x20, 0x40, 0x20, 0xf3, 0x3f, 0x12, 0x00, 0x0c, 0x00, 0x00, 0x00, +}; +const uint8_t _A_Plugins_14_7[] = { + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x12, 0xb9, 0x33, 0xa9, 0x00, 0x66, 0x01, 0x80, 0x02, + 0x80, 0x02, 0x60, 0x01, 0xa0, 0x00, 0xb9, 0x3f, 0x09, 0x00, 0x06, 0x00, 0x00, 0x00, +}; +const uint8_t _A_Plugins_14_8[] = { + 0x00, 0x00, 0x00, 0x39, 0x00, 0x29, 0x00, 0x66, 0x06, 0x80, 0x09, 0x80, 0x39, 0x60, 0x20, + 0xe0, 0x20, 0x39, 0x01, 0x09, 0x01, 0xc6, 0x20, 0x40, 0x20, 0xc0, 0x3f, 0x00, 0x00, +}; +const uint8_t* const _A_Plugins_14[] = { + _A_Plugins_14_0, + _A_Plugins_14_1, + _A_Plugins_14_2, + _A_Plugins_14_3, + _A_Plugins_14_4, + _A_Plugins_14_5, + _A_Plugins_14_6, + _A_Plugins_14_7, + _A_Plugins_14_8}; + +const uint8_t _A_Settings_14_0[] = { + 0x00, 0x03, 0x07, 0x87, 0x04, 0x8e, 0x02, 0x9c, 0x32, 0xf8, 0x2c, 0x50, 0x20, 0x30, 0x1e, + 0x1e, 0x03, 0x81, 0x04, 0xcd, 0x09, 0x53, 0x13, 0x50, 0x26, 0x48, 0x2c, 0x38, 0x18, +}; +const uint8_t _A_Settings_14_1[] = { + 0x00, 0x03, 0x00, 0x87, 0x03, 0x4e, 0x02, 0x7c, 0x01, 0x48, 0x19, 0x58, 0x16, 0x30, 0x10, + 0x10, 0x0f, 0x8f, 0x04, 0xc0, 0x09, 0x26, 0x13, 0x29, 0x16, 0x28, 0x0c, 0x24, 0x00, +}; +const uint8_t _A_Settings_14_2[] = { + 0x00, 0x03, 0x00, 0x07, 0x00, 0xde, 0x01, 0x24, 0x01, 0xac, 0x00, 0xb8, 0x0c, 0x30, 0x0b, + 0x10, 0x08, 0x88, 0x07, 0xc7, 0x09, 0x20, 0x0b, 0x13, 0x06, 0x14, 0x00, 0x14, 0x00, +}; +const uint8_t _A_Settings_14_3[] = { + 0x00, 0x04, 0x0c, 0x09, 0x00, 0x13, 0x20, 0x26, 0x20, 0x4c, 0x00, 0xb8, 0x00, 0xa4, 0x00, + 0x74, 0x00, 0x94, 0x01, 0x64, 0x01, 0x02, 0x01, 0xf1, 0x18, 0x08, 0x38, 0x04, 0x30, +}; +const uint8_t _A_Settings_14_4[] = { + 0x00, 0x04, 0x0f, 0x89, 0x00, 0x93, 0x26, 0xa6, 0x29, 0x2c, 0x28, 0x18, 0x24, 0x00, 0x1c, + 0x0e, 0x00, 0x09, 0x00, 0x05, 0x06, 0x65, 0x0e, 0x59, 0x1c, 0x40, 0x38, 0x3c, 0x30, +}; +const uint8_t _A_Settings_14_5[] = { + 0x00, 0x04, 0x08, 0x05, 0x04, 0xc3, 0x23, 0x20, 0x10, 0xa0, 0x09, 0x60, 0x0a, 0x00, 0x0a, + 0x80, 0x09, 0x80, 0x07, 0x03, 0x07, 0x02, 0x0e, 0x01, 0x3c, 0x19, 0x08, 0x16, 0x18, +}; +const uint8_t _A_Settings_14_6[] = { + 0x00, 0x00, 0x14, 0x00, 0x24, 0x00, 0x02, 0x18, 0x31, 0xf8, 0x08, 0x08, 0x04, 0x68, 0x02, + 0xd8, 0x02, 0x80, 0x06, 0xc0, 0x0a, 0xc0, 0x13, 0x00, 0x26, 0x00, 0x0c, 0x00, 0x18, +}; +const uint8_t _A_Settings_14_7[] = { + 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x0c, 0x32, 0x1c, 0x01, 0xb8, 0x38, 0x78, 0x04, 0x04, 0x02, + 0x34, 0x03, 0x4c, 0x05, 0x40, 0x09, 0x20, 0x13, 0xe0, 0x26, 0x00, 0x0c, 0x00, 0x18, +}; +const uint8_t _A_Settings_14_8[] = { + 0x00, 0x00, 0x09, 0x06, 0x05, 0x0e, 0x25, 0x1c, 0x19, 0xb8, 0x00, 0x70, 0x3c, 0x3c, 0x02, + 0x02, 0x03, 0x9a, 0x04, 0xa6, 0x09, 0xa0, 0x13, 0x90, 0x26, 0x70, 0x0c, 0x00, 0x18, +}; +const uint8_t _A_Settings_14_9[] = { + 0x00, 0x03, 0x07, 0x87, 0x04, 0x8e, 0x02, 0x9c, 0x32, 0xf8, 0x2c, 0x50, 0x20, 0x30, 0x1e, + 0x1e, 0x03, 0x81, 0x04, 0xcd, 0x09, 0x53, 0x13, 0x50, 0x26, 0x48, 0x2c, 0x38, 0x18, +}; +const uint8_t* const _A_Settings_14[] = { + _A_Settings_14_0, + _A_Settings_14_1, + _A_Settings_14_2, + _A_Settings_14_3, + _A_Settings_14_4, + _A_Settings_14_5, + _A_Settings_14_6, + _A_Settings_14_7, + _A_Settings_14_8, + _A_Settings_14_9}; + +const uint8_t _A_Sub1ghz_14_0[] = { + 0x01, 0x00, 0x1a, 0x00, 0x82, 0x42, 0x20, 0x51, 0x08, 0x4c, 0x92, 0x0b, 0x28, 0xea, 0xca, + 0x80, 0x22, 0x05, 0x1e, 0x4c, 0x93, 0x85, 0x10, 0xe2, 0x42, 0x38, 0x10, 0x00, 0x0a, 0x80, +}; +const uint8_t _A_Sub1ghz_14_1[] = { + 0x01, 0x00, 0x18, 0x00, 0x82, 0x42, 0x20, 0x51, 0x08, 0x4c, 0x92, 0x0b, 0x28, 0xe2, + 0x80, 0x48, 0x0a, 0x3c, 0x99, 0x27, 0x0a, 0x21, 0xc4, 0x84, 0x70, 0x20, 0x00, 0x15, +}; +const uint8_t _A_Sub1ghz_14_2[] = { + 0x01, 0x00, 0x16, 0x00, 0x82, 0x42, 0x20, 0x51, 0x08, 0x0c, 0x80, 0x02, 0x3c, + 0x10, 0x09, 0x01, 0x4f, 0x85, 0x10, 0xe2, 0x42, 0x38, 0x10, 0x00, 0x0a, 0x80, +}; +const uint8_t _A_Sub1ghz_14_3[] = { + 0x01, + 0x00, + 0x08, + 0x00, + 0x00, + 0x3f, + 0x00, + 0x02, + 0x40, + 0x55, + 0x00, + 0xc8, +}; +const uint8_t _A_Sub1ghz_14_4[] = { + 0x01, + 0x00, + 0x0a, + 0x00, + 0x00, + 0x3f, + 0x42, + 0x04, + 0x01, + 0x10, + 0x28, + 0xf0, + 0x00, + 0x38, +}; +const uint8_t _A_Sub1ghz_14_5[] = { + 0x01, 0x00, 0x12, 0x00, 0x00, 0x1c, 0x22, 0x09, 0x04, 0x84, 0x75, + 0x21, 0x40, 0x11, 0x02, 0x8f, 0x22, 0x09, 0xc0, 0x80, 0x00, 0x64, +}; +const uint8_t* const _A_Sub1ghz_14[] = { + _A_Sub1ghz_14_0, + _A_Sub1ghz_14_1, + _A_Sub1ghz_14_2, + _A_Sub1ghz_14_3, + _A_Sub1ghz_14_4, + _A_Sub1ghz_14_5}; + +const uint8_t _A_U2F_14_0[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x10, 0x02, 0x08, 0x04, 0xfe, 0x1f, 0x01, 0x20, + 0xd5, 0x2d, 0x55, 0x25, 0x15, 0x2d, 0x95, 0x24, 0xdd, 0x25, 0x01, 0x20, 0xfe, 0x1f, +}; +const uint8_t _A_U2F_14_1[] = { + 0x00, 0x00, 0x00, 0xe0, 0x01, 0x10, 0x02, 0x08, 0x04, 0x08, 0x04, 0xfe, 0x1f, 0x01, 0x20, + 0xd5, 0x2d, 0x55, 0x25, 0x15, 0x2d, 0x95, 0x24, 0xdd, 0x25, 0x01, 0x20, 0xfe, 0x1f, +}; +const uint8_t _A_U2F_14_2[] = { + 0x00, 0xe0, 0x01, 0x10, 0x02, 0x08, 0x04, 0x08, 0x04, 0x08, 0x00, 0xfe, 0x1f, 0x01, 0x20, + 0xd5, 0x2d, 0x55, 0x25, 0x15, 0x2d, 0x95, 0x24, 0xdd, 0x25, 0x01, 0x20, 0xfe, 0x1f, +}; +const uint8_t _A_U2F_14_3[] = { + 0x00, 0x00, 0x00, 0xe0, 0x01, 0x10, 0x02, 0x08, 0x04, 0x08, 0x04, 0xfe, 0x1f, 0x01, 0x20, + 0xd5, 0x2d, 0x55, 0x25, 0x15, 0x2d, 0x95, 0x24, 0xdd, 0x25, 0x01, 0x20, 0xfe, 0x1f, +}; +const uint8_t* const _A_U2F_14[] = {_A_U2F_14_0, _A_U2F_14_1, _A_U2F_14_2, _A_U2F_14_3}; + +const uint8_t _A_UniRFRemix_14_0[] = { + 0x01, 0x00, 0x14, 0x00, 0xfc, 0x41, 0xe0, 0x90, 0x8e, 0x14, 0x43, 0xc5, + 0x11, 0x00, 0x88, 0x14, 0x60, 0x40, 0x12, 0x05, 0xb8, 0x54, 0x43, 0x22, +}; +const uint8_t _A_UniRFRemix_14_1[] = { + 0x01, 0x00, 0x12, 0x00, 0xf8, 0x40, 0x61, 0x10, 0x2a, 0x24, 0x13, + 0xc8, 0x01, 0x20, 0x28, 0x80, 0x0c, 0x16, 0xe1, 0x51, 0x0c, 0x88, +}; +const uint8_t _A_UniRFRemix_14_2[] = { + 0x01, + 0x00, + 0x05, + 0x00, + 0xe0, + 0x00, + 0x7c, + 0x03, + 0x40, +}; +const uint8_t _A_UniRFRemix_14_3[] = { + 0x01, + 0x00, + 0x0d, + 0x00, + 0xf8, + 0x40, + 0x61, + 0x10, + 0x28, + 0x20, + 0x03, + 0xc0, + 0x04, + 0x15, + 0x10, + 0xc8, + 0x80, +}; +const uint8_t _A_UniRFRemix_14_4[] = { + 0x01, + 0x00, + 0x0e, + 0x00, + 0xfc, + 0x41, + 0xe0, + 0x90, + 0x88, + 0x14, + 0x40, + 0x03, + 0xe0, + 0x11, + 0x0a, + 0x88, + 0x64, + 0x40, +}; +const uint8_t _A_UniRFRemix_14_5[] = { + 0x01, + 0x00, + 0x0d, + 0x00, + 0xf8, + 0x40, + 0x61, + 0x10, + 0x28, + 0x20, + 0x03, + 0xc0, + 0x04, + 0x15, + 0x10, + 0xc8, + 0x80, +}; +const uint8_t _A_UniRFRemix_14_6[] = { + 0x01, + 0x00, + 0x05, + 0x00, + 0xe0, + 0x00, + 0x7c, + 0x03, + 0x40, +}; +const uint8_t _A_UniRFRemix_14_7[] = { + 0x01, 0x00, 0x12, 0x00, 0xf8, 0x40, 0x61, 0x10, 0x2a, 0x24, 0x13, + 0xc8, 0x01, 0x20, 0x28, 0x80, 0x0c, 0x16, 0xe1, 0x51, 0x0c, 0x88, +}; +const uint8_t* const _A_UniRFRemix_14[] = { + _A_UniRFRemix_14_0, + _A_UniRFRemix_14_1, + _A_UniRFRemix_14_2, + _A_UniRFRemix_14_3, + _A_UniRFRemix_14_4, + _A_UniRFRemix_14_5, + _A_UniRFRemix_14_6, + _A_UniRFRemix_14_7}; + +const uint8_t _A_iButton_14_0[] = { + 0x00, 0x00, 0x1c, 0x00, 0x3e, 0x00, 0x35, 0x80, 0x3a, 0x78, 0x15, 0x84, 0x0a, 0x32, 0x05, + 0x49, 0x02, 0x85, 0x02, 0x85, 0x02, 0x49, 0x02, 0x32, 0x01, 0x84, 0x00, 0x78, 0x00, +}; +const uint8_t _A_iButton_14_1[] = { + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x26, 0x80, 0x21, 0xe0, 0x10, 0x38, 0x0d, 0x6c, 0x03, + 0x56, 0x01, 0x2b, 0x01, 0x97, 0x00, 0x4d, 0x00, 0x21, 0x00, 0x1e, 0x00, 0x00, 0x00, +}; +const uint8_t _A_iButton_14_2[] = { + 0x01, 0x00, 0x1a, 0x00, 0x00, 0x24, 0xc2, 0x01, 0x2c, 0x80, 0x48, 0xfb, 0x11, 0x89, 0x64, + 0x1b, 0x2d, 0x01, 0xa5, 0xc0, 0x24, 0xb0, 0x08, 0x94, 0x02, 0x13, 0x00, 0x83, 0x85, 0x88, +}; +const uint8_t _A_iButton_14_3[] = { + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x26, 0x80, 0x21, 0x60, 0x18, 0x98, 0x06, 0x04, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x81, 0x00, 0x41, 0x00, 0x21, 0x00, 0x1e, 0x00, 0x00, 0x00, +}; +const uint8_t _A_iButton_14_4[] = { + 0x01, 0x00, 0x1a, 0x00, 0x80, 0x47, 0x20, 0x13, 0xe8, 0x04, 0xd7, 0x01, 0x3a, 0xbc, 0x45, + 0x70, 0x90, 0xa8, 0x14, 0x16, 0x03, 0x02, 0x00, 0xa8, 0x08, 0x70, 0x90, 0x0b, 0xc4, 0x00, +}; +const uint8_t _A_iButton_14_5[] = { + 0x01, 0x00, 0x1a, 0x00, 0x00, 0x14, 0xe2, 0x01, 0x24, 0x80, 0x48, 0xb0, 0x11, 0x1f, 0x04, + 0x22, 0x31, 0x05, 0x83, 0x40, 0xa0, 0x20, 0x13, 0x80, 0xf0, 0x60, 0x13, 0xe0, 0xc1, 0x00, +}; +const uint8_t _A_iButton_14_6[] = { + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x24, 0x00, 0x23, 0x80, 0x20, 0xf0, 0x10, 0x0c, 0x0d, + 0xe2, 0x02, 0x91, 0x01, 0x69, 0x01, 0x15, 0x01, 0x8d, 0x00, 0x4d, 0x00, 0x3e, 0x00, +}; +const uint8_t* const _A_iButton_14[] = { + _A_iButton_14_0, + _A_iButton_14_1, + _A_iButton_14_2, + _A_iButton_14_3, + _A_iButton_14_4, + _A_iButton_14_5, + _A_iButton_14_6}; + +const uint8_t _I_ArrowC_1_36x36_0[] = { + 0x01, 0x00, 0x7a, 0x00, 0x00, 0x78, 0x01, 0x30, 0x13, 0xf0, 0x21, 0x5c, 0x38, 0x00, 0x42, 0x86, + 0x40, 0x20, 0x20, 0x41, 0x81, 0x4f, 0xc0, 0x85, 0xe1, 0x07, 0x16, 0x02, 0x20, 0x1c, 0x38, 0x44, + 0x02, 0x41, 0x00, 0xa0, 0x41, 0x20, 0x15, 0x00, 0x21, 0xe2, 0x01, 0x63, 0x02, 0x80, 0x41, 0x20, + 0x20, 0x42, 0x81, 0x40, 0xa2, 0x02, 0x51, 0x80, 0xc1, 0x00, 0x83, 0x80, 0x80, 0x42, 0x00, 0x85, + 0x8f, 0x87, 0xc7, 0xe3, 0xe1, 0xd2, 0x80, 0x8c, 0x44, 0x08, 0x30, 0x21, 0x88, 0x81, 0x06, 0x08, + 0x2c, 0x1a, 0x20, 0x64, 0x44, 0xe2, 0x04, 0x11, 0x39, 0x48, 0xa0, 0x1a, 0x02, 0x40, 0x81, 0x06, + 0x80, 0x04, 0x18, 0x89, 0x44, 0xca, 0xc5, 0x30, 0xb8, 0x09, 0x06, 0x01, 0xc8, 0x87, 0x89, 0x04, + 0x46, 0x30, 0x08, 0x18, 0x38, 0xbc, 0x01, 0x72, 0xe0, 0x10, 0x44, 0x01, 0xe0, 0x04, +}; +const uint8_t* const _I_ArrowC_1_36x36[] = {_I_ArrowC_1_36x36_0}; + +const uint8_t _I_Detailed_chip_17x13_0[] = { + 0x01, 0x00, 0x1e, 0x00, 0xfe, 0x5f, 0xe0, 0x10, 0x2c, 0x04, 0x02, 0x23, + 0x11, 0x80, 0xe4, 0x62, 0x50, 0x1a, 0xff, 0xc2, 0x03, 0x21, 0x84, 0x00, + 0x9a, 0xbf, 0xf4, 0x08, 0x98, 0x5c, 0x83, 0xa4, 0x23, 0x20, +}; +const uint8_t* const _I_Detailed_chip_17x13[] = {_I_Detailed_chip_17x13_0}; + +const uint8_t _I_Keychain_39x36_0[] = { + 0x01, 0x00, 0x82, 0x00, 0x00, 0x0c, 0x3c, 0x06, 0x5c, 0x09, 0x80, 0x10, 0xa4, 0x14, 0x00, + 0x21, 0x44, 0x30, 0x00, 0x42, 0x84, 0x40, 0x20, 0x20, 0x46, 0x82, 0x40, 0x20, 0x40, 0x4b, + 0x0c, 0x4d, 0xf8, 0x4e, 0x7e, 0x7f, 0x84, 0x0e, 0x01, 0x80, 0xe0, 0xff, 0xc8, 0x22, 0x04, + 0x18, 0xfc, 0x70, 0x08, 0x36, 0x09, 0xec, 0x60, 0x08, 0x33, 0x0b, 0x68, 0x10, 0xb6, 0x20, + 0x47, 0xe0, 0x7d, 0xed, 0x80, 0x41, 0xf0, 0x5f, 0xed, 0x81, 0xd1, 0xf8, 0x58, 0x7f, 0x13, + 0xf8, 0x07, 0xe3, 0x81, 0xff, 0xbf, 0xc0, 0x2f, 0x98, 0x08, 0x7f, 0xe2, 0x19, 0xfe, 0x80, + 0x41, 0xfe, 0x10, 0xfa, 0x78, 0x10, 0x7c, 0x10, 0x78, 0xf8, 0x10, 0x78, 0x16, 0x38, 0xd8, + 0x10, 0x70, 0x17, 0x72, 0x80, 0xc1, 0xe0, 0x02, 0x31, 0x02, 0x14, 0x78, 0x08, 0x21, 0x51, + 0x86, 0x10, 0x45, 0x34, 0x78, 0x00, 0x70, 0x81, 0x08, 0x1c, 0x20, 0x46, 0x57, 0x18, +}; +const uint8_t* const _I_Keychain_39x36[] = {_I_Keychain_39x36_0}; + +const uint8_t _I_Medium_chip_22x21_0[] = { + 0x01, 0x00, 0x35, 0x00, 0xfe, 0x7f, 0xe1, 0xf0, 0x28, 0x04, 0x43, 0xf3, 0xff, 0x93, 0xe1, + 0x6a, 0x52, 0x8e, 0x2f, 0xfe, 0x51, 0x25, 0x80, 0x4a, 0x72, 0xb6, 0x79, 0x55, 0x76, 0xc1, + 0x2e, 0xaa, 0xc0, 0x25, 0x51, 0xdc, 0x00, 0x14, 0x70, 0x00, 0x56, 0xae, 0x81, 0x47, 0x2b, + 0x7d, 0x95, 0x07, 0x48, 0x46, 0x42, 0x92, 0x17, 0x90, 0xd4, 0x87, 0x64, +}; +const uint8_t* const _I_Medium_chip_22x21[] = {_I_Medium_chip_22x21_0}; + +const uint8_t _I_Modern_reader_18x34_0[] = { + 0x01, 0x00, 0x41, 0x00, 0xff, 0x5f, 0xe0, 0x10, 0x7c, 0x04, 0x02, 0x97, 0x20, 0x80, + 0xc4, 0xe0, 0x10, 0x2e, 0x9f, 0xfe, 0x05, 0xe3, 0xff, 0xc0, 0xfe, 0x7c, 0x00, 0x10, + 0x81, 0x48, 0x05, 0x00, 0xe1, 0xb9, 0xef, 0xe0, 0x7b, 0x3b, 0x08, 0x20, 0x7b, 0xc0, + 0xe4, 0xf9, 0x80, 0x90, 0x10, 0x40, 0xe1, 0x0a, 0x10, 0x68, 0x85, 0xfc, 0x41, 0x22, + 0x39, 0x13, 0x48, 0xa6, 0x45, 0x92, 0xff, 0x97, 0xc7, 0xfd, 0x3f, 0x80, 0x00, +}; +const uint8_t* const _I_Modern_reader_18x34[] = {_I_Modern_reader_18x34_0}; + +const uint8_t _I_Move_flipper_26x39_0[] = { + 0x01, 0x00, 0x67, 0x00, 0x80, 0x78, 0x20, 0xe0, 0x31, 0x88, 0x42, 0x40, 0x63, 0x88, 0x88, 0x00, + 0xc6, 0x89, 0x20, 0x01, 0x8c, 0x8a, 0x80, 0x03, 0x18, 0x96, 0x00, 0x06, 0x21, 0x21, 0x80, 0x80, + 0xd6, 0x7f, 0x02, 0x80, 0x62, 0x68, 0x00, 0x3f, 0x01, 0xa4, 0x40, 0x06, 0x51, 0x80, 0x19, 0x7f, + 0x00, 0x65, 0xfe, 0x01, 0x97, 0xfc, 0x06, 0xdf, 0xe1, 0x99, 0x7f, 0x07, 0x62, 0x1b, 0x10, 0x19, + 0x08, 0xc6, 0x38, 0x2b, 0x18, 0x4c, 0x88, 0x06, 0x54, 0x10, 0x19, 0x52, 0x40, 0x63, 0x0d, 0x01, + 0x98, 0x2c, 0xa1, 0xa1, 0x32, 0x86, 0x86, 0xcc, 0xc6, 0x70, 0x10, 0x18, 0xe2, 0x70, 0x47, 0x32, + 0xa0, 0x80, 0xc9, 0x06, 0x51, 0x24, 0x59, 0x7f, 0x21, 0xf0, 0x00, +}; +const uint8_t* const _I_Move_flipper_26x39[] = {_I_Move_flipper_26x39_0}; + +const uint8_t _I_NFC_dolphin_emulation_47x61_0[] = { + 0x01, 0x00, 0x20, 0x01, 0x00, 0x0f, 0xfa, 0x3e, 0x04, 0x2e, 0x04, 0x07, 0xc1, 0x01, 0x02, 0x8c, + 0xc0, 0x04, 0x30, 0x60, 0x10, 0xc3, 0x00, 0x43, 0x18, 0x01, 0x0c, 0x08, 0x04, 0x32, 0x00, 0x10, + 0x85, 0x0a, 0x81, 0x00, 0xc0, 0x08, 0x08, 0x06, 0x20, 0x71, 0x00, 0x14, 0x04, 0x26, 0x41, 0xb2, + 0x02, 0x9c, 0xf2, 0x09, 0x10, 0x02, 0x95, 0x08, 0x0a, 0x98, 0x18, 0x44, 0x20, 0x70, 0x38, 0x08, + 0xc4, 0x26, 0x10, 0x01, 0x1c, 0x04, 0x92, 0x13, 0x84, 0x88, 0x01, 0x4a, 0x23, 0xc4, 0x88, 0x44, + 0x00, 0xa5, 0x44, 0x02, 0xa5, 0x1a, 0x41, 0x20, 0x02, 0x94, 0xa8, 0x0a, 0x93, 0x69, 0x05, 0x00, + 0x52, 0x31, 0x18, 0xdf, 0x80, 0xa2, 0x38, 0x18, 0x84, 0x37, 0xc0, 0x51, 0x1a, 0x14, 0x42, 0x0e, + 0x7b, 0x29, 0xe4, 0x62, 0x07, 0xf0, 0x36, 0x14, 0x52, 0x03, 0xf0, 0x81, 0x81, 0x46, 0x15, 0x00, + 0xe8, 0x7f, 0xc1, 0x83, 0x08, 0x02, 0xa2, 0x34, 0x63, 0x1f, 0xf0, 0x88, 0xc3, 0x81, 0xa3, 0x3c, + 0x80, 0x47, 0xc0, 0xa2, 0x98, 0x1b, 0x06, 0x00, 0xd2, 0x21, 0x31, 0x0d, 0x8c, 0x14, 0x56, 0x2a, + 0x32, 0x83, 0xab, 0x4d, 0x68, 0x4b, 0x62, 0x80, 0x41, 0x06, 0xe4, 0x05, 0x30, 0xc8, 0x80, 0x04, + 0x3e, 0x30, 0xb0, 0x29, 0xe0, 0x20, 0xac, 0x92, 0x88, 0x70, 0x15, 0xe7, 0x10, 0xa0, 0x41, 0x78, + 0x0d, 0x22, 0xd0, 0x0c, 0xc4, 0xa6, 0x32, 0x0a, 0x80, 0x0c, 0x46, 0x23, 0x40, 0xd8, 0x10, 0x84, + 0x4e, 0x34, 0x0a, 0xc4, 0x02, 0xd4, 0xf7, 0x1a, 0x06, 0xb2, 0x01, 0xd4, 0xa0, 0x81, 0x46, 0xa9, + 0x00, 0xd4, 0x60, 0xe0, 0x34, 0x09, 0x54, 0x02, 0xa1, 0x0f, 0x81, 0x50, 0x22, 0xb0, 0x0d, 0x04, + 0x7b, 0xf9, 0x5f, 0x23, 0x0d, 0x02, 0xfb, 0x00, 0x98, 0x0b, 0x87, 0x41, 0xfa, 0x80, 0xba, 0x0f, + 0xeb, 0x07, 0x18, 0x88, 0x00, 0x7d, 0x5f, 0xf3, 0xb8, 0x80, 0x07, 0xa1, 0x5f, 0x02, 0x10, 0x60, + 0x73, 0xc0, 0x53, 0xa0, 0x65, 0x40, 0xa7, 0x00, 0xcd, 0x01, 0x52, 0x20, 0xc8, 0x23, 0xe1, 0x01, + 0x6c, 0xea, 0x20, 0x54, +}; +const uint8_t* const _I_NFC_dolphin_emulation_47x61[] = {_I_NFC_dolphin_emulation_47x61_0}; + +const uint8_t _I_NFC_manual_60x50_0[] = { + 0x01, 0x00, 0xd1, 0x00, 0x80, 0x7c, 0x3f, 0xe0, 0x02, 0x83, 0x81, 0xc6, 0x18, 0x0c, 0x38, 0xc0, + 0x08, 0x62, 0x40, 0xd1, 0x8f, 0xfc, 0x24, 0x00, 0x71, 0xc4, 0x80, 0x86, 0x41, 0x0c, 0xa1, 0xc0, + 0x30, 0x18, 0x00, 0x39, 0x40, 0xb0, 0x90, 0x0a, 0x06, 0x08, 0x0e, 0x56, 0x18, 0x44, 0x06, 0x41, + 0x81, 0x03, 0x96, 0x46, 0x11, 0x02, 0x88, 0x05, 0xcc, 0x0e, 0x30, 0x4a, 0x40, 0x1c, 0xec, 0x3c, + 0x80, 0x40, 0x89, 0xd2, 0x49, 0x09, 0xa1, 0x01, 0xce, 0x19, 0x23, 0x84, 0xe0, 0x40, 0xe7, 0xf0, + 0xe0, 0x0c, 0x06, 0x02, 0x4f, 0x1c, 0xf8, 0x28, 0x61, 0x10, 0x38, 0x11, 0xb5, 0x21, 0x10, 0x58, + 0x20, 0x1d, 0x21, 0x50, 0x9e, 0x87, 0x02, 0x73, 0x08, 0xde, 0x63, 0x61, 0x31, 0x14, 0x2a, 0xc2, + 0x24, 0x20, 0x76, 0xa1, 0x01, 0xdb, 0x09, 0x01, 0x03, 0xa4, 0x32, 0x11, 0xfe, 0x4f, 0x9f, 0xfe, + 0x17, 0x10, 0x0b, 0xac, 0x31, 0x32, 0x4b, 0x32, 0x83, 0xc3, 0xa8, 0x00, 0xf5, 0x87, 0x60, 0x04, + 0xea, 0x55, 0x11, 0x3a, 0xc0, 0xc1, 0x65, 0xe0, 0x02, 0x18, 0x1e, 0x3f, 0x8d, 0xf6, 0x3f, 0x88, + 0x3c, 0xa1, 0x00, 0x7f, 0x03, 0xf8, 0x1c, 0xff, 0x91, 0xff, 0xe0, 0x1d, 0x3f, 0x10, 0xf9, 0x94, + 0x24, 0x0e, 0x66, 0xd1, 0xa5, 0x01, 0xd0, 0x3e, 0x20, 0x75, 0xe0, 0x40, 0x42, 0xea, 0xe1, 0x11, + 0x3a, 0xab, 0x8c, 0x0f, 0xe0, 0x21, 0xf9, 0x5f, 0xff, 0xd7, 0xf0, 0x7e, 0x7e, 0x44, 0xfe, 0x07, + 0x55, 0xba, 0x43, 0xd4, 0xf0, +}; +const uint8_t* const _I_NFC_manual_60x50[] = {_I_NFC_manual_60x50_0}; + +const uint8_t _I_Release_arrow_18x15_0[] = { + 0x01, 0x00, 0x25, 0x00, 0x80, 0x41, 0x80, 0x43, 0x0a, 0x01, 0x0c, 0x48, 0x04, 0x32, + 0x28, 0x07, 0xfa, 0x97, 0x00, 0x80, 0xe6, 0x20, 0x1f, 0xd9, 0xfc, 0x07, 0xfb, 0x7f, + 0x81, 0x01, 0x48, 0x16, 0x41, 0x12, 0x0b, 0x90, 0x74, 0xc4, 0x64, 0x29, 0x10, +}; +const uint8_t* const _I_Release_arrow_18x15[] = {_I_Release_arrow_18x15_0}; + +const uint8_t _I_Restoring_38x32_0[] = { + 0x01, 0x00, 0x82, 0x00, 0x00, 0x5d, 0xfc, 0x06, 0x5e, 0x0c, 0x04, 0x04, 0x08, 0x31, 0x88, + 0x04, 0x08, 0x08, 0x30, 0x4b, 0xf0, 0x10, 0xb8, 0x5f, 0xf8, 0x18, 0x10, 0x7c, 0x38, 0x10, + 0x99, 0x4c, 0x60, 0x14, 0x08, 0x06, 0x02, 0x11, 0x00, 0xd0, 0x01, 0x0e, 0x21, 0x01, 0xa0, + 0x41, 0x20, 0x10, 0x88, 0x10, 0x10, 0xa0, 0x90, 0x49, 0x00, 0x94, 0x60, 0x50, 0x80, 0x21, + 0x40, 0x62, 0x00, 0x42, 0x8f, 0xc7, 0xe7, 0xd3, 0xe0, 0x21, 0x40, 0xa4, 0x02, 0x22, 0x83, + 0x4c, 0x00, 0x85, 0x0e, 0x9c, 0x40, 0x31, 0x10, 0x08, 0xe4, 0x70, 0x08, 0x53, 0x88, 0x74, + 0x02, 0x89, 0x00, 0xb8, 0x41, 0xc0, 0x85, 0xe0, 0x29, 0x0c, 0x8e, 0x01, 0xc0, 0x29, 0x0c, + 0x84, 0xa8, 0x36, 0x0f, 0x04, 0x40, 0x08, 0x39, 0x08, 0xf9, 0x44, 0x45, 0x43, 0x00, 0x0f, + 0x88, 0x78, 0x78, 0x01, 0xf1, 0x0f, 0x0f, 0xfc, 0xda, 0x58, 0x09, 0xfa, 0x4d, 0x80, +}; +const uint8_t* const _I_Restoring_38x32[] = {_I_Restoring_38x32_0}; + +const uint8_t _I_Tap_reader_36x38_0[] = { + 0x01, 0x00, 0x90, 0x00, 0xfe, 0x4f, 0xc0, 0x85, 0x06, 0xa0, 0x60, 0x00, 0x83, 0x27, 0xa8, + 0x70, 0x00, 0x83, 0x0b, 0xc0, 0x78, 0x21, 0xe0, 0x42, 0x04, 0x94, 0x4e, 0x01, 0x81, 0x02, + 0x0e, 0x4e, 0xff, 0x01, 0x02, 0x0f, 0x8f, 0xff, 0x01, 0xb8, 0x01, 0x07, 0x81, 0x01, 0xe4, + 0x40, 0x3e, 0x7f, 0xf8, 0x1c, 0x92, 0x02, 0x04, 0x28, 0x94, 0x08, 0x08, 0x70, 0x40, 0x21, + 0xc2, 0x3e, 0x7c, 0x08, 0x1f, 0x4a, 0x17, 0x73, 0xdf, 0x81, 0x0b, 0x67, 0x61, 0x02, 0x17, + 0xcf, 0xbc, 0x04, 0x30, 0xc0, 0x81, 0x0b, 0xe6, 0x04, 0x81, 0x3a, 0x06, 0x04, 0x08, 0x22, + 0x22, 0xc9, 0x42, 0x45, 0x85, 0x52, 0x85, 0x0d, 0x8a, 0xb4, 0x04, 0x10, 0xc0, 0xe6, 0xa1, + 0x20, 0x42, 0x8d, 0x07, 0x44, 0x08, 0x35, 0x28, 0x21, 0xa0, 0x8b, 0x22, 0x04, 0x2f, 0xe4, + 0x04, 0xee, 0x88, 0x11, 0x02, 0x12, 0x2c, 0x60, 0x10, 0x20, 0x21, 0xc1, 0x93, 0xe4, 0x9a, + 0x28, 0x3d, 0x00, 0x12, 0x5f, 0xe5, 0x98, 0x84, 0xc7, 0xf9, 0x1f, 0x5c, 0x10, +}; +const uint8_t* const _I_Tap_reader_36x38[] = {_I_Tap_reader_36x38_0}; + +const uint8_t _I_Pin_arrow_down_7x9_0[] = { + 0x00, + 0x1c, + 0x1c, + 0x1c, + 0x1c, + 0x1c, + 0x7f, + 0x3e, + 0x1c, + 0x08, +}; +const uint8_t* const _I_Pin_arrow_down_7x9[] = {_I_Pin_arrow_down_7x9_0}; + +const uint8_t _I_Pin_arrow_left_9x7_0[] = { + 0x00, + 0x08, + 0x00, + 0x0c, + 0x00, + 0xfe, + 0x01, + 0xff, + 0x01, + 0xfe, + 0x01, + 0x0c, + 0x00, + 0x08, + 0x00, +}; +const uint8_t* const _I_Pin_arrow_left_9x7[] = {_I_Pin_arrow_left_9x7_0}; + +const uint8_t _I_Pin_arrow_right_9x7_0[] = { + 0x00, + 0x20, + 0x00, + 0x60, + 0x00, + 0xff, + 0x00, + 0xff, + 0x01, + 0xff, + 0x00, + 0x60, + 0x00, + 0x20, + 0x00, +}; +const uint8_t* const _I_Pin_arrow_right_9x7[] = {_I_Pin_arrow_right_9x7_0}; + +const uint8_t _I_Pin_arrow_up_7x9_0[] = { + 0x00, + 0x08, + 0x1c, + 0x3e, + 0x7f, + 0x1c, + 0x1c, + 0x1c, + 0x1c, + 0x1c, +}; +const uint8_t* const _I_Pin_arrow_up_7x9[] = {_I_Pin_arrow_up_7x9_0}; + +const uint8_t _I_Pin_attention_dpad_29x29_0[] = { + 0x01, 0x00, 0x56, 0x00, 0x80, 0x7f, 0x20, 0xe0, 0x31, 0x81, 0xc6, 0x20, 0x1c, 0x08, 0x05, + 0x82, 0x01, 0x20, 0xa0, 0x60, 0x20, 0x11, 0x0f, 0x04, 0x02, 0x03, 0x08, 0xf8, 0x40, 0x60, + 0x50, 0x4f, 0xc4, 0x0e, 0x09, 0x04, 0x05, 0x8c, 0x12, 0x04, 0x03, 0x18, 0x44, 0x08, 0x42, + 0x30, 0x88, 0x08, 0x0c, 0x62, 0x14, 0x18, 0x05, 0x02, 0x21, 0x61, 0x14, 0x8c, 0x43, 0xe3, + 0x01, 0xf8, 0x44, 0x7f, 0x20, 0x31, 0x89, 0x81, 0xcc, 0x1e, 0x61, 0x73, 0x0f, 0x98, 0x9c, + 0xc5, 0xe6, 0x37, 0x31, 0xf9, 0x91, 0xcc, 0x9e, 0x65, 0x73, 0x2f, 0x99, 0x9c, 0xcd, 0xe6, +}; +const uint8_t* const _I_Pin_attention_dpad_29x29[] = {_I_Pin_attention_dpad_29x29_0}; + +const uint8_t _I_Pin_back_arrow_10x8_0[] = { + 0x00, + 0x04, + 0x00, + 0x06, + 0x00, + 0xff, + 0x00, + 0x06, + 0x01, + 0x04, + 0x02, + 0x00, + 0x02, + 0x00, + 0x01, + 0xf8, + 0x00, +}; +const uint8_t* const _I_Pin_back_arrow_10x8[] = {_I_Pin_back_arrow_10x8_0}; + +const uint8_t _I_Pin_back_full_40x8_0[] = { + 0x01, 0x00, 0x26, 0x00, 0x82, 0x01, 0x0e, 0x0c, 0x02, 0x18, 0x14, 0x03, 0xfe, 0x04, + 0x38, 0x37, 0xc6, 0xc3, 0x32, 0xf7, 0x41, 0x20, 0x59, 0x0a, 0x54, 0xa6, 0x01, 0xf2, + 0x88, 0xde, 0x80, 0x83, 0x01, 0xc8, 0x42, 0xa5, 0x3f, 0x88, 0x05, 0x82, 0x65, 0x2e, +}; +const uint8_t* const _I_Pin_back_full_40x8[] = {_I_Pin_back_full_40x8_0}; + +const uint8_t _I_Pin_cell_13x13_0[] = { + 0x01, + 0x00, + 0x0a, + 0x00, + 0xff, + 0xc7, + 0xe0, + 0x31, + 0x00, + 0x0f, + 0x80, + 0x4c, + 0x2e, + 0x20, +}; +const uint8_t* const _I_Pin_cell_13x13[] = {_I_Pin_cell_13x13_0}; + +const uint8_t _I_Pin_pointer_5x3_0[] = { + 0x00, + 0x04, + 0x0e, + 0x1f, +}; +const uint8_t* const _I_Pin_pointer_5x3[] = {_I_Pin_pointer_5x3_0}; + +const uint8_t _I_Pin_star_7x7_0[] = { + 0x00, + 0x49, + 0x2a, + 0x1c, + 0x7f, + 0x1c, + 0x2a, + 0x49, +}; +const uint8_t* const _I_Pin_star_7x7[] = {_I_Pin_star_7x7_0}; + +const uint8_t _I_passport_bad1_46x49_0[] = { + 0x01, 0x00, 0xd2, 0x00, 0xff, 0x7f, 0xc0, 0x05, 0x1f, 0x02, 0x1f, 0xfe, 0x7e, 0x02, 0x18, 0x0f, + 0xe0, 0x0a, 0x57, 0xff, 0xf7, 0x9c, 0x0a, 0x59, 0xf8, 0x0e, 0x60, 0x0a, 0x56, 0xf8, 0x05, 0x83, + 0xfc, 0x05, 0x18, 0xbc, 0x03, 0x01, 0xfd, 0x02, 0x8c, 0x2c, 0x5a, 0x3f, 0xa0, 0x28, 0xc1, 0x40, + 0xa3, 0xf4, 0x02, 0x8c, 0x08, 0x0a, 0x77, 0xf8, 0x08, 0x14, 0x7d, 0x13, 0xfd, 0xf9, 0x14, 0x80, + 0xab, 0xd0, 0x9f, 0xd7, 0xe0, 0x10, 0x60, 0x2a, 0x42, 0x20, 0x1a, 0x09, 0xfc, 0xbe, 0x01, 0x10, + 0x02, 0xa5, 0x9c, 0x0a, 0x78, 0x0e, 0x74, 0x04, 0x0a, 0x31, 0x7a, 0x06, 0x7a, 0x06, 0x05, 0x39, + 0xb0, 0x44, 0x80, 0xa3, 0x7e, 0x02, 0xa5, 0xf0, 0x0a, 0x78, 0x0a, 0x00, 0x14, 0xf8, 0x13, 0xf0, + 0x29, 0xc8, 0x07, 0x66, 0x70, 0x11, 0xd8, 0xea, 0xa7, 0xf1, 0xb2, 0x99, 0x4c, 0x00, 0xa9, 0xc0, + 0x9f, 0x01, 0x4e, 0x01, 0x3d, 0x02, 0x8c, 0x38, 0x0a, 0x33, 0xa8, 0x6c, 0x02, 0x62, 0x05, 0x19, + 0xa0, 0x14, 0x78, 0x00, 0x51, 0x94, 0x01, 0x46, 0x01, 0x03, 0x02, 0xa4, 0x30, 0x0a, 0x2a, 0x02, + 0x98, 0x7c, 0x25, 0x60, 0x52, 0xe0, 0x43, 0xe5, 0x80, 0x51, 0xc0, 0x27, 0x46, 0x51, 0x09, 0x05, + 0x88, 0xc0, 0x66, 0x80, 0x52, 0xfe, 0x40, 0x27, 0x60, 0x52, 0xf8, 0x7f, 0xe7, 0xa0, 0x52, 0xe0, + 0x5f, 0xe7, 0xc0, 0x52, 0x80, 0x6f, 0xe7, 0xe0, 0x53, 0xde, 0x01, 0x50, 0xe2, 0x20, 0x5f, 0x02, + 0xbf, 0xfb, 0xfe, 0x00, 0x28, 0xf8, +}; +const uint8_t* const _I_passport_bad1_46x49[] = {_I_passport_bad1_46x49_0}; + +const uint8_t _I_passport_bad2_46x49_0[] = { + 0x01, 0x00, 0xee, 0x00, 0xff, 0x7f, 0xc0, 0x05, 0x1f, 0x02, 0x1f, 0xfe, 0x7e, 0x02, 0x18, 0x0f, + 0xe0, 0x0a, 0x57, 0xff, 0xf7, 0x9c, 0x0a, 0x59, 0xf8, 0x0e, 0x60, 0x0a, 0x5e, 0xf8, 0xfd, 0x83, + 0xfc, 0x05, 0x18, 0xbd, 0x83, 0x01, 0xfd, 0x02, 0x8c, 0x2f, 0x01, 0x01, 0xfd, 0x01, 0x46, 0x0b, + 0x00, 0x81, 0x7d, 0x00, 0xa3, 0x02, 0x80, 0x41, 0x3d, 0x13, 0xfb, 0xfc, 0x04, 0x0a, 0x3d, 0x09, + 0xfe, 0xfc, 0x88, 0x30, 0x80, 0x2a, 0xea, 0xa7, 0xf5, 0xf8, 0x04, 0x7e, 0xa1, 0xb5, 0x02, 0x8f, + 0x02, 0xc1, 0xb8, 0xbf, 0x4f, 0xe5, 0xf2, 0x0e, 0x07, 0x53, 0x03, 0x3e, 0x02, 0x8e, 0x9e, 0x75, + 0x80, 0x02, 0x8e, 0x42, 0x9d, 0x05, 0xd1, 0x4f, 0xa2, 0xf5, 0x08, 0xf4, 0x0c, 0x0a, 0x73, 0x69, + 0x08, 0x14, 0xab, 0x17, 0xe0, 0x29, 0xd4, 0x2f, 0x80, 0x53, 0xcc, 0x50, 0x24, 0x22, 0x31, 0x8b, + 0xfc, 0x08, 0x62, 0x05, 0x29, 0x07, 0x32, 0x0f, 0x40, 0x9f, 0xc5, 0xe2, 0x13, 0x8f, 0xc5, 0xfe, + 0x7f, 0x1b, 0x4f, 0x90, 0x44, 0x40, 0xa7, 0x00, 0x9e, 0x81, 0x52, 0x75, 0x1d, 0x80, 0x43, 0x80, + 0xa3, 0x34, 0x86, 0xc0, 0x26, 0x20, 0x54, 0xe0, 0x01, 0x46, 0x51, 0x0b, 0x01, 0x8c, 0x0c, 0x0a, + 0x90, 0xc0, 0x2a, 0x4c, 0x3e, 0x12, 0xb0, 0x28, 0xcc, 0x38, 0x10, 0xf9, 0x64, 0x24, 0x3a, 0x29, + 0xd1, 0x94, 0x01, 0x47, 0x00, 0x30, 0x19, 0xa0, 0x14, 0x60, 0x1f, 0xd8, 0x04, 0xec, 0x0a, 0x5f, + 0xaf, 0xfc, 0xf4, 0x0a, 0x5f, 0x4b, 0xfc, 0xf8, 0x0a, 0x5a, 0x8d, 0xfc, 0xfc, 0x0a, 0x54, 0x00, + 0x2a, 0x60, 0x37, 0x40, 0x53, 0x80, 0x2e, 0x44, 0x0a, 0x7a, 0x00, 0x2e, 0x7f, 0xbf, 0xe0, 0x02, + 0x8f, 0x80, +}; +const uint8_t* const _I_passport_bad2_46x49[] = {_I_passport_bad2_46x49_0}; + +const uint8_t _I_passport_bad3_46x49_0[] = { + 0x01, 0x00, 0x07, 0x01, 0xff, 0x7f, 0xc0, 0x05, 0x1f, 0x02, 0x1f, 0xfe, 0x7e, 0x02, 0x18, 0x0f, + 0xc0, 0x0a, 0x57, 0xff, 0xf7, 0xbc, 0x0a, 0x59, 0xf8, 0x0f, 0x40, 0x0a, 0x56, 0xf8, 0x04, 0xe0, + 0x0a, 0x51, 0x78, 0x07, 0x1b, 0xfc, 0x05, 0x18, 0x5c, 0x02, 0x03, 0xfd, 0x02, 0x8c, 0x37, 0x01, + 0x00, 0xfd, 0x01, 0x46, 0x15, 0x40, 0x80, 0x7d, 0x27, 0xf7, 0xf8, 0x48, 0x14, 0xf7, 0xf0, 0x80, + 0x28, 0xfa, 0x00, 0xa5, 0x20, 0x80, 0x72, 0x27, 0xf5, 0xf8, 0x80, 0x14, 0x76, 0x00, 0x52, 0x9f, + 0xc0, 0x2f, 0xd3, 0xf9, 0x7e, 0x82, 0x81, 0xc0, 0xc8, 0xcf, 0xa5, 0xf6, 0x0d, 0x3c, 0xe3, 0x20, + 0x05, 0x1d, 0x05, 0x32, 0x4b, 0xa0, 0x9f, 0x45, 0xec, 0x11, 0xc9, 0x18, 0x14, 0xe6, 0x94, 0x10, + 0x29, 0xd7, 0x00, 0xa9, 0x62, 0x02, 0x9f, 0x02, 0x83, 0x41, 0x11, 0x88, 0x14, 0x77, 0xf2, 0x00, + 0x29, 0x48, 0x39, 0x92, 0x7a, 0x84, 0xfe, 0x27, 0x10, 0x9c, 0x7e, 0x2f, 0xf3, 0xf8, 0xea, 0x78, + 0x68, 0x18, 0x09, 0xf4, 0x7c, 0x0a, 0x27, 0x21, 0x9e, 0xc6, 0xd5, 0x65, 0x01, 0x9d, 0x44, 0xe0, + 0x10, 0xe8, 0x04, 0x0a, 0x69, 0x63, 0x80, 0x4c, 0x60, 0x10, 0x49, 0xa6, 0x0e, 0x03, 0xc0, 0x80, + 0x42, 0x25, 0x10, 0x38, 0x34, 0x02, 0x06, 0x05, 0x28, 0x44, 0x02, 0x19, 0x10, 0x02, 0x8c, 0x42, + 0x01, 0x30, 0xf8, 0x4b, 0xe0, 0x71, 0x48, 0x07, 0x02, 0x3f, 0x2c, 0x05, 0x8e, 0x02, 0x03, 0x00, + 0x94, 0x43, 0xc2, 0x22, 0x30, 0x19, 0xa5, 0xc4, 0x0a, 0x3f, 0xc8, 0x04, 0xef, 0x02, 0x3c, 0x16, + 0xe8, 0xcf, 0x60, 0x31, 0xc0, 0xe8, 0xdf, 0xe7, 0xd0, 0x1b, 0x01, 0x34, 0x77, 0xf3, 0xf8, 0x08, + 0x88, 0xb7, 0x80, 0x51, 0x80, 0x10, 0x87, 0x40, 0x05, 0x22, 0x10, 0xd8, 0x00, 0xa5, 0x0a, 0x05, + 0x88, 0x74, 0x41, 0x64, 0x05, 0x7f, 0xf7, 0xfc, 0x00, 0x51, 0xf0, +}; +const uint8_t* const _I_passport_bad3_46x49[] = {_I_passport_bad3_46x49_0}; + +const uint8_t _I_passport_bottom_128x18_0[] = { + 0x01, 0x00, 0x54, 0x00, 0x99, 0x01, 0x97, 0xf1, 0xff, 0x00, 0x2e, 0x1c, 0x1e, 0xdf, 0xc0, + 0x7b, 0x63, 0xe6, 0xc0, 0xfe, 0x9e, 0x03, 0xfa, 0x70, 0x0f, 0xe9, 0x80, 0x7f, 0xc1, 0xfd, + 0x04, 0x37, 0xf7, 0xc9, 0x1d, 0xb8, 0x08, 0x4c, 0x04, 0x1f, 0xb0, 0x58, 0x10, 0x3f, 0x38, + 0x00, 0xfe, 0xb0, 0x41, 0x7e, 0x44, 0x96, 0x00, 0x2c, 0xfe, 0x0b, 0xfa, 0x07, 0xe4, 0x7e, + 0x13, 0x79, 0x1d, 0xce, 0x02, 0x03, 0xc0, 0x80, 0x7c, 0xf9, 0x83, 0xb9, 0x80, 0x40, 0xc0, + 0x43, 0x06, 0xc3, 0x0e, 0xe6, 0x01, 0xfe, 0x01, 0x0f, 0xf2, 0x06, 0x90, 0xd0, +}; +const uint8_t* const _I_passport_bottom_128x18[] = {_I_passport_bottom_128x18_0}; + +const uint8_t _I_passport_happy1_46x49_0[] = { + 0x01, 0x00, 0x09, 0x01, 0xff, 0x7f, 0xc0, 0x05, 0x1f, 0x02, 0x1f, 0xfe, 0x7f, 0xff, 0x87, 0xe0, + 0x00, 0xa7, 0xf1, 0xbf, 0x85, 0x04, 0x0a, 0x30, 0xec, 0x07, 0xe4, 0x0a, 0x37, 0xf8, 0x0c, 0x03, + 0xec, 0x05, 0x1d, 0xf8, 0x98, 0x7d, 0x00, 0x51, 0xaf, 0x81, 0x47, 0xa0, 0x05, 0x19, 0x78, 0x14, + 0xa0, 0x73, 0xf8, 0xb8, 0x14, 0x74, 0x1f, 0xc9, 0xf0, 0x14, 0xa4, 0x10, 0x39, 0xec, 0x2c, 0x0a, + 0x3c, 0x08, 0x04, 0xe8, 0x0a, 0x52, 0x00, 0x28, 0xc1, 0x7c, 0x10, 0x08, 0x87, 0x82, 0x77, 0x05, + 0xfc, 0x40, 0xe1, 0x1f, 0x80, 0x28, 0xff, 0x20, 0x70, 0x4f, 0xe4, 0xf6, 0x07, 0xfe, 0x80, 0xc0, + 0xbf, 0xd3, 0xe8, 0x1e, 0x7a, 0x0f, 0x00, 0xbf, 0xcf, 0xe0, 0x74, 0xe8, 0x46, 0x03, 0x7e, 0x05, + 0x19, 0x70, 0xbc, 0x7b, 0xe0, 0x51, 0x8a, 0x40, 0x3c, 0x1e, 0xf0, 0x28, 0xc4, 0x20, 0x1f, 0x0f, + 0xb8, 0x14, 0xff, 0x1f, 0xb9, 0xf9, 0xa8, 0x60, 0x3f, 0xcf, 0xc8, 0x14, 0xff, 0xde, 0x70, 0x29, + 0x61, 0xb0, 0xf9, 0xf0, 0x29, 0x12, 0x06, 0xfd, 0x3e, 0x02, 0x8f, 0x82, 0x0f, 0xf8, 0x9c, 0x81, + 0x44, 0x80, 0x3e, 0x09, 0xb8, 0x14, 0x94, 0x43, 0x2b, 0x80, 0xcc, 0x20, 0xc0, 0x71, 0x94, 0x40, + 0x69, 0x10, 0x90, 0x29, 0xe2, 0x21, 0x00, 0x51, 0x9b, 0x01, 0x4f, 0xc0, 0x23, 0x1c, 0x24, 0x43, + 0xf5, 0x1f, 0x17, 0x88, 0x14, 0x7e, 0x1e, 0x31, 0xd8, 0xe0, 0xa4, 0x18, 0x02, 0x99, 0x01, 0x46, + 0x01, 0xfa, 0x02, 0x8e, 0x06, 0x80, 0x05, 0x6f, 0xa4, 0xff, 0x03, 0x80, 0xc0, 0x01, 0x4a, 0x82, + 0x04, 0x18, 0x08, 0x14, 0xb8, 0x10, 0x18, 0x0f, 0xa2, 0x7f, 0x21, 0x02, 0x8c, 0x08, 0x0a, 0x31, + 0x10, 0x28, 0xc1, 0x3a, 0x13, 0xf8, 0x6f, 0x82, 0x07, 0x18, 0x02, 0x8c, 0x0c, 0x0a, 0x3e, 0x0d, + 0x00, 0xbc, 0x7e, 0x0b, 0x31, 0xb3, 0xcf, 0xff, 0xdf, 0xf0, 0x01, 0x47, 0xc0, +}; +const uint8_t* const _I_passport_happy1_46x49[] = {_I_passport_happy1_46x49_0}; + +const uint8_t _I_passport_happy2_46x49_0[] = { + 0x01, 0x00, 0x16, 0x01, 0xff, 0x7f, 0xc0, 0x05, 0x1f, 0x02, 0x1f, 0xfe, 0x7f, 0xff, 0x87, 0xe0, + 0x00, 0xa7, 0xf1, 0xbf, 0x85, 0x04, 0x0a, 0x30, 0xec, 0x07, 0x84, 0x0a, 0x37, 0xf8, 0x0c, 0x03, + 0xbe, 0x05, 0x1d, 0xfc, 0xfb, 0x81, 0xa0, 0x02, 0x8f, 0x7f, 0x83, 0x21, 0xa4, 0x43, 0xe7, 0xf2, + 0xf8, 0x06, 0x4a, 0xa1, 0xf3, 0x9f, 0x45, 0xe0, 0x10, 0xcc, 0x8c, 0x32, 0x7b, 0x17, 0xb8, 0x42, + 0x30, 0x50, 0x39, 0xd4, 0x2f, 0x19, 0x25, 0xe1, 0x40, 0x26, 0x90, 0xb8, 0x15, 0x1a, 0x40, 0x05, + 0x18, 0x2f, 0x86, 0x89, 0x18, 0xf0, 0x4d, 0xe0, 0xbf, 0x98, 0x2c, 0x13, 0xf1, 0x3b, 0xc2, 0xff, + 0x20, 0xb0, 0x2f, 0xe4, 0xf7, 0x07, 0xfe, 0x82, 0xc0, 0x7f, 0xd3, 0xec, 0x1e, 0x7b, 0x8f, 0x00, + 0xbf, 0xcf, 0xf0, 0x74, 0xc9, 0xc6, 0x03, 0x7f, 0x3f, 0x81, 0xc8, 0x60, 0x1c, 0x0e, 0xf8, 0x14, + 0x62, 0xd0, 0x0f, 0x07, 0xbc, 0x0a, 0x31, 0x88, 0x07, 0xc3, 0xee, 0x05, 0x18, 0x84, 0x03, 0xf1, + 0xfb, 0x9f, 0x9a, 0x86, 0x03, 0xfc, 0xfc, 0x81, 0x4f, 0xfd, 0xe7, 0x02, 0x96, 0x1b, 0x0f, 0x9f, + 0x02, 0x97, 0xe2, 0x07, 0x7e, 0x9f, 0x01, 0x47, 0xc1, 0x07, 0xfc, 0x4c, 0x40, 0xa2, 0x40, 0x1f, + 0x04, 0xbc, 0x0a, 0x4a, 0x21, 0x95, 0xc0, 0x66, 0x10, 0x60, 0x38, 0xca, 0x20, 0x34, 0x88, 0x48, + 0x14, 0xf1, 0x10, 0x80, 0x28, 0xcd, 0x80, 0xa7, 0xe0, 0x9c, 0xc0, 0x70, 0x91, 0x0f, 0xd4, 0x7c, + 0x5e, 0x20, 0x51, 0xf8, 0x78, 0xc7, 0x63, 0x82, 0x90, 0x60, 0x0a, 0x64, 0x05, 0x18, 0x07, 0xe8, + 0x0a, 0x38, 0x1a, 0x00, 0x15, 0xbe, 0x93, 0xfc, 0x0e, 0x03, 0x00, 0x05, 0x2a, 0x08, 0x10, 0x60, + 0x20, 0x52, 0xe0, 0x40, 0x60, 0x3e, 0x89, 0xfc, 0x84, 0x0a, 0x30, 0x20, 0x28, 0xc4, 0x40, 0xa3, + 0x04, 0xe8, 0x4f, 0xe1, 0xbe, 0x04, 0x88, 0x81, 0x46, 0x06, 0x05, 0x1f, 0x06, 0x80, 0x5e, 0x3f, + 0x08, 0x3c, 0x02, 0xcf, 0x3f, 0xff, 0x7f, 0xc0, 0x05, 0x1f, +}; +const uint8_t* const _I_passport_happy2_46x49[] = {_I_passport_happy2_46x49_0}; + +const uint8_t _I_passport_happy3_46x49_0[] = { + 0x01, 0x00, 0x23, 0x01, 0xff, 0x7f, 0xc0, 0x05, 0x1f, 0x02, 0x1f, 0xfe, 0x7f, 0xff, 0x81, 0xe0, + 0x00, 0xa7, 0xfc, 0xbf, 0xff, 0x00, 0xa3, 0x7f, 0x85, 0xe0, 0x3e, 0x60, 0x51, 0xdf, 0xc1, 0x38, + 0x1e, 0xc0, 0x28, 0xd7, 0xe0, 0x52, 0x0e, 0x98, 0x14, 0x65, 0xf0, 0x28, 0x86, 0x92, 0x1f, 0x3f, + 0x8b, 0xc0, 0xa1, 0x14, 0x8f, 0x9c, 0xfa, 0x2f, 0x04, 0x84, 0x64, 0x21, 0x93, 0xd8, 0x5f, 0xf2, + 0x6b, 0xa0, 0x81, 0xce, 0xa1, 0x70, 0x2a, 0x37, 0x82, 0x05, 0x34, 0x82, 0xfe, 0x70, 0x92, 0x08, + 0x24, 0xd3, 0x1b, 0x04, 0x82, 0xc4, 0x7d, 0x13, 0x7c, 0xbf, 0xca, 0x0b, 0x0d, 0xfc, 0x4e, 0xf4, + 0x7f, 0xa8, 0x2c, 0x0f, 0xf9, 0x3d, 0xe1, 0xe7, 0xa0, 0xf0, 0x1f, 0xf4, 0xfb, 0x07, 0x8e, 0xe3, + 0xc0, 0x2f, 0xf3, 0xfc, 0x0d, 0xd2, 0x71, 0x80, 0xdf, 0x81, 0x46, 0x73, 0x00, 0xe0, 0x77, 0xe7, + 0xf0, 0x18, 0x9c, 0x03, 0xc1, 0xef, 0x02, 0x8c, 0x7a, 0x01, 0xf0, 0xfb, 0x81, 0x46, 0x21, 0x00, + 0xfc, 0x7e, 0xe7, 0xf0, 0x38, 0x04, 0x07, 0xf9, 0xf9, 0x9f, 0xc1, 0x40, 0xa3, 0xfe, 0xf3, 0xcf, + 0xe1, 0x30, 0x0c, 0x36, 0x1f, 0x3f, 0x3f, 0x88, 0x85, 0x86, 0x07, 0x7e, 0x9f, 0x48, 0x45, 0x03, + 0x07, 0xfc, 0x4c, 0x68, 0x2a, 0xa1, 0xbf, 0xf8, 0x25, 0xf4, 0x30, 0x28, 0xa8, 0x86, 0x57, 0x47, + 0x98, 0x41, 0x80, 0xe3, 0x28, 0x96, 0xd2, 0x04, 0xa2, 0x05, 0x18, 0xce, 0x22, 0x10, 0x05, 0x19, + 0xb4, 0xc4, 0x0a, 0x5e, 0x09, 0xcd, 0x87, 0x09, 0x10, 0xfd, 0x47, 0xe7, 0xdc, 0x10, 0x28, 0xfc, + 0x3c, 0x66, 0x51, 0xc1, 0x48, 0x30, 0x05, 0x31, 0x02, 0x94, 0x03, 0xf4, 0x05, 0x1c, 0x0d, 0x00, + 0x0a, 0xdf, 0x40, 0x28, 0xe0, 0x30, 0x00, 0x52, 0xa0, 0x81, 0x06, 0x02, 0x05, 0x2e, 0x04, 0x06, + 0x03, 0xe8, 0x9f, 0xc8, 0x40, 0xa3, 0x02, 0x02, 0x8c, 0x44, 0x0a, 0x30, 0x4e, 0x84, 0xfe, 0x1b, + 0xe0, 0x81, 0xc6, 0x00, 0xa3, 0x03, 0x02, 0x8f, 0x83, 0x40, 0x95, 0x1f, 0x84, 0x1e, 0x01, 0x67, + 0x9f, 0xff, 0xbf, 0xe0, 0x02, 0x8f, 0x80, +}; +const uint8_t* const _I_passport_happy3_46x49[] = {_I_passport_happy3_46x49_0}; + +const uint8_t _I_passport_left_6x46_0[] = { + 0x01, 0x00, 0x1b, 0x00, 0x9e, 0x40, 0xa3, 0x32, 0x59, 0x2c, 0x66, 0x03, 0x01, 0x82, 0xc2, 0x62, + 0x32, 0x50, 0x16, 0xc8, 0x60, 0x30, 0x28, 0x34, 0x3a, 0x3d, 0x3e, 0x9d, 0x4c, 0x80, 0x14, +}; +const uint8_t* const _I_passport_left_6x46[] = {_I_passport_left_6x46_0}; + +const uint8_t _I_passport_okay1_46x49_0[] = { + 0x01, 0x00, 0xcc, 0x00, 0xff, 0x7f, 0xc0, 0x05, 0x1f, 0x02, 0x1f, 0xfe, 0x7e, 0x02, 0x1b, 0xfc, + 0x00, 0x0a, 0x78, 0xff, 0xff, 0xe0, 0x0a, 0x57, 0x38, 0x07, 0x9c, 0x0a, 0x50, 0xc8, 0x06, 0x60, + 0x0a, 0x37, 0xf8, 0x1c, 0x02, 0xc0, 0x05, 0x1d, 0xf8, 0xb4, 0x70, 0x13, 0xef, 0xfd, 0x7c, 0x68, + 0x53, 0xdf, 0xfc, 0xbc, 0x0a, 0x53, 0xaf, 0xfc, 0x5c, 0x0b, 0x13, 0x4f, 0xfc, 0x2c, 0x0b, 0x12, + 0x8f, 0xfc, 0x14, 0x0a, 0xdf, 0x08, 0x0c, 0xc3, 0xff, 0x02, 0x80, 0x7a, 0x20, 0x60, 0x53, 0xfa, + 0x41, 0xc0, 0xa7, 0x12, 0x87, 0xc8, 0x00, 0xa5, 0x92, 0x02, 0xa7, 0xc8, 0x0b, 0x5e, 0x28, 0x58, + 0x14, 0xe0, 0x90, 0xc0, 0x29, 0xfa, 0x20, 0xe0, 0x51, 0x1d, 0x8c, 0x42, 0x10, 0x05, 0x38, 0x44, + 0x40, 0x0a, 0x38, 0x58, 0x78, 0x30, 0x40, 0xa3, 0x7d, 0x29, 0x94, 0x82, 0xff, 0x06, 0x02, 0x9e, + 0x7e, 0x02, 0x88, 0x10, 0x28, 0xdb, 0xd1, 0xc4, 0x05, 0x13, 0xe1, 0x50, 0x00, 0xa2, 0x76, 0x29, + 0x00, 0x15, 0x22, 0x00, 0x51, 0x3e, 0x14, 0x38, 0x0a, 0x7c, 0x01, 0x28, 0xc8, 0x3c, 0xb0, 0xf9, + 0xe0, 0x64, 0xa3, 0x7f, 0x05, 0xf8, 0x8a, 0x50, 0x0a, 0x4b, 0x83, 0x02, 0x8f, 0x7e, 0x01, 0xe0, + 0x2a, 0x0c, 0x81, 0xbc, 0x41, 0x81, 0x2c, 0x8f, 0x83, 0xfe, 0x11, 0x2f, 0xff, 0xbe, 0x3e, 0x05, + 0x40, 0xb0, 0x81, 0x4c, 0x74, 0x20, 0x52, 0x15, 0x1c, 0x83, 0xfc, 0x23, 0x10, 0x00, 0xc7, 0xc0, +}; +const uint8_t* const _I_passport_okay1_46x49[] = {_I_passport_okay1_46x49_0}; + +const uint8_t _I_passport_okay2_46x49_0[] = { + 0x01, 0x00, 0xe5, 0x00, 0xff, 0x7f, 0xc0, 0x05, 0x1f, 0x02, 0x1f, 0xfe, 0x7e, 0x02, 0x1b, 0xfe, + 0x00, 0x0a, 0x78, 0x7b, 0xff, 0xf0, 0x0a, 0x57, 0x9c, 0x77, 0x8c, 0x0a, 0x37, 0xfc, 0x34, 0x07, + 0x38, 0x05, 0x1d, 0xfd, 0x06, 0x01, 0x60, 0x02, 0x8d, 0x7e, 0x41, 0x00, 0xc0, 0x4f, 0xbf, 0xf2, + 0xf8, 0x80, 0xd0, 0x67, 0xbf, 0xf8, 0xb8, 0x14, 0xa7, 0x40, 0x51, 0x84, 0x01, 0x4e, 0x17, 0x0c, + 0x02, 0x8c, 0xd3, 0xff, 0x05, 0x82, 0x01, 0x5e, 0x51, 0xff, 0x81, 0x40, 0xbf, 0x10, 0x30, 0x29, + 0xc1, 0x20, 0x93, 0x00, 0x29, 0x7c, 0xa1, 0x20, 0x51, 0xff, 0x40, 0xfd, 0x31, 0x39, 0x85, 0xfe, + 0x03, 0x1c, 0x8a, 0xc4, 0xe4, 0x17, 0xf8, 0x2f, 0x83, 0x2b, 0x17, 0x90, 0x6f, 0xf0, 0x90, 0x0f, + 0xa8, 0x16, 0xbc, 0xa0, 0x52, 0x84, 0x40, 0x61, 0x51, 0x20, 0x29, 0xfd, 0xa3, 0xe0, 0x52, 0x80, + 0x46, 0xa1, 0x02, 0x91, 0x80, 0xf8, 0x21, 0x31, 0x00, 0x28, 0xe0, 0x63, 0xf0, 0x80, 0x28, 0xff, + 0xef, 0xca, 0xc2, 0x90, 0x4f, 0xe0, 0x68, 0x21, 0x02, 0x8f, 0x7c, 0x12, 0x20, 0x52, 0x97, 0x81, + 0x52, 0x2e, 0x05, 0x1a, 0x00, 0x14, 0x61, 0x61, 0xb2, 0x00, 0x8c, 0x14, 0x0a, 0x31, 0x80, 0x2a, + 0x41, 0x80, 0xa7, 0xc0, 0x80, 0x81, 0x47, 0xcb, 0x03, 0x9e, 0x06, 0x4a, 0x37, 0xfc, 0x1b, 0x08, + 0xa5, 0x00, 0xa4, 0x35, 0x20, 0x29, 0x10, 0x47, 0xc1, 0x0f, 0x26, 0x93, 0x90, 0x43, 0x02, 0x59, + 0x1f, 0x07, 0xfc, 0x22, 0x5f, 0xff, 0x7c, 0x7c, 0x0a, 0x81, 0x61, 0x02, 0x98, 0xe8, 0x40, 0xa4, + 0x2a, 0x39, 0x07, 0xf8, 0x46, 0x20, 0x01, 0x8f, 0x80, +}; +const uint8_t* const _I_passport_okay2_46x49[] = {_I_passport_okay2_46x49_0}; + +const uint8_t _I_passport_okay3_46x49_0[] = { + 0x01, 0x00, 0x06, 0x01, 0xff, 0x7f, 0xc0, 0x05, 0x1f, 0x02, 0x1f, 0xfe, 0x7e, 0x02, 0x2c, 0x00, + 0x14, 0xfb, 0xf7, 0xff, 0xe0, 0x14, 0xa4, 0xf8, 0x0f, 0x18, 0x14, 0xaf, 0x30, 0x0c, 0xe0, 0x14, + 0x6f, 0xf8, 0x68, 0x05, 0xa0, 0x0a, 0x3b, 0xf8, 0x0c, 0x07, 0x11, 0x3e, 0xff, 0xd7, 0xe0, 0x10, + 0x28, 0x44, 0xf7, 0xff, 0x2f, 0x02, 0x8c, 0x12, 0x75, 0xff, 0x8b, 0xc0, 0x20, 0x80, 0x52, 0x85, + 0x81, 0x4a, 0x68, 0x05, 0x28, 0x44, 0x08, 0x0a, 0x30, 0x50, 0x29, 0x4a, 0x00, 0xa5, 0xfc, 0x81, + 0x81, 0x4e, 0x05, 0x06, 0x98, 0x01, 0x4b, 0xf3, 0x04, 0x02, 0x8f, 0xfb, 0x07, 0x04, 0x84, 0xcc, + 0x2f, 0xf0, 0x1c, 0xee, 0x2a, 0x15, 0x28, 0x02, 0x8f, 0x86, 0xe4, 0x05, 0x1d, 0xfe, 0x03, 0x01, + 0x52, 0x02, 0xa0, 0x2c, 0x64, 0x80, 0x52, 0xc5, 0x43, 0x80, 0xa7, 0x07, 0x87, 0x81, 0x4a, 0x01, + 0xff, 0x83, 0xc8, 0xb7, 0xf0, 0x08, 0x0c, 0x3a, 0x09, 0x22, 0x14, 0x94, 0x16, 0x11, 0x21, 0xbf, + 0xe0, 0x6f, 0xf0, 0x40, 0x28, 0xff, 0xef, 0xd1, 0x45, 0x60, 0xc8, 0x67, 0xf0, 0x38, 0x58, 0x7c, + 0x64, 0x5d, 0xfe, 0x04, 0x18, 0x0a, 0x33, 0xc9, 0x7e, 0x82, 0x03, 0x40, 0x80, 0x48, 0x22, 0xf5, + 0x08, 0x00, 0x14, 0xa1, 0x60, 0x51, 0x90, 0x40, 0x26, 0x10, 0x59, 0x44, 0x02, 0x21, 0x00, 0x94, + 0x01, 0x4a, 0x1d, 0x00, 0x92, 0x01, 0x47, 0x81, 0x01, 0x02, 0x8f, 0x96, 0x57, 0x3c, 0x1a, 0x8c, + 0x8a, 0x36, 0x8d, 0x10, 0x29, 0x2b, 0x04, 0x00, 0x52, 0x15, 0xc0, 0x80, 0x07, 0x00, 0x41, 0x18, + 0x07, 0x82, 0x1f, 0x80, 0x92, 0x37, 0x88, 0x30, 0x32, 0x9f, 0xff, 0x83, 0xfe, 0x12, 0x19, 0x97, + 0xff, 0xdf, 0x1f, 0x02, 0x8c, 0x90, 0x0a, 0x30, 0xf0, 0x28, 0xae, 0x47, 0xde, 0x3a, 0x12, 0x68, + 0xb8, 0xc8, 0x00, 0x32, 0x0f, 0xf0, 0x8c, 0x40, 0x03, 0x1f, +}; +const uint8_t* const _I_passport_okay3_46x49[] = {_I_passport_okay3_46x49_0}; + +const uint8_t _I_BatteryBody_52x28_0[] = { + 0x01, 0x00, 0x45, 0x00, 0xe0, 0x7f, 0x3f, 0xe0, 0x02, 0x87, 0xf0, 0x21, 0xe0, 0xc3, 0x84, + 0x50, 0x39, 0xbf, 0xff, 0x27, 0xfe, 0xf3, 0x09, 0xe0, 0x42, 0x81, 0xab, 0x0d, 0x03, 0x1c, + 0x2b, 0xfc, 0x0d, 0x48, 0x55, 0xdc, 0x1a, 0x90, 0x8f, 0x18, 0x6d, 0x41, 0xaa, 0x1b, 0x71, + 0x4b, 0x0d, 0xd4, 0x1b, 0xe0, 0xdf, 0x1b, 0xd5, 0xfc, 0x1a, 0xa5, 0x36, 0x06, 0xac, 0x20, + 0xa7, 0xe0, 0xdc, 0xa5, 0x7c, 0x7c, 0xb7, 0xff, 0xb4, 0x21, 0x5c, 0xcb, 0xc6, +}; +const uint8_t* const _I_BatteryBody_52x28[] = {_I_BatteryBody_52x28_0}; + +const uint8_t _I_Battery_16x16_0[] = { + 0x01, 0x00, 0x12, 0x00, 0x00, 0x1e, 0x02, 0x03, 0xc0, 0x81, 0xc8, + 0x20, 0x80, 0x11, 0xd0, 0x41, 0x40, 0x72, 0x11, 0x10, 0xda, 0x80, +}; +const uint8_t* const _I_Battery_16x16[] = {_I_Battery_16x16_0}; + +const uint8_t _I_FaceCharging_29x14_0[] = { + 0x01, 0x00, 0x28, 0x00, 0xa0, 0x00, 0x86, 0x05, 0x60, 0x01, 0x8c, 0x0e, 0x61, 0x00, 0xc0, + 0x40, 0x63, 0x10, 0x0e, 0x04, 0x03, 0xf9, 0x00, 0xf0, 0x41, 0xc0, 0x66, 0x13, 0xb8, 0x40, + 0x94, 0xc0, 0x07, 0x04, 0x82, 0x00, 0xc6, 0x11, 0x02, 0x01, 0x8f, 0xc2, 0x03, 0x00, +}; +const uint8_t* const _I_FaceCharging_29x14[] = {_I_FaceCharging_29x14_0}; + +const uint8_t _I_FaceConfused_29x14_0[] = { + 0x01, 0x00, 0x30, 0x00, 0xc0, 0x00, 0x46, 0x1f, 0x38, 0x80, 0xd0, 0x22, 0x14, + 0x48, 0x0c, 0x82, 0x0f, 0x52, 0x80, 0xe8, 0x21, 0x14, 0xa0, 0x18, 0xc2, 0xa6, + 0x59, 0x19, 0x24, 0x27, 0x09, 0x48, 0xa1, 0x41, 0x2f, 0x12, 0x4c, 0x0c, 0x0c, + 0x51, 0x1f, 0xc8, 0x78, 0x0c, 0x7f, 0xd1, 0xf0, 0x18, 0xc3, 0xa3, 0x00, 0x74, +}; +const uint8_t* const _I_FaceConfused_29x14[] = {_I_FaceConfused_29x14_0}; + +const uint8_t _I_FaceNopower_29x14_0[] = { + 0x01, 0x00, 0x24, 0x00, 0x00, 0x1f, 0x02, 0x01, 0x60, 0x01, 0xa7, 0x80, 0x02, 0x57, + 0xe0, 0x48, 0xc3, 0xe7, 0xd0, 0x0c, 0x04, 0x3c, 0x39, 0x1f, 0x88, 0x18, 0x0c, 0x61, + 0x90, 0x60, 0x18, 0xff, 0x82, 0x44, 0x03, 0x38, 0x74, 0x38, 0x2c, 0x80, +}; +const uint8_t* const _I_FaceNopower_29x14[] = {_I_FaceNopower_29x14_0}; + +const uint8_t _I_FaceNormal_29x14_0[] = { + 0x01, 0x00, 0x1e, 0x00, 0x00, 0x1c, 0xf2, 0x01, 0x80, 0x83, 0xd7, 0xa0, + 0x1c, 0x08, 0x5d, 0xf8, 0x06, 0x30, 0xf0, 0x1b, 0x84, 0xcc, 0x41, 0x10, + 0x88, 0x10, 0x0e, 0x62, 0x10, 0x10, 0x18, 0xf8, 0x00, 0x42, +}; +const uint8_t* const _I_FaceNormal_29x14[] = {_I_FaceNormal_29x14_0}; + +const uint8_t _I_Health_16x16_0[] = { + 0x01, 0x00, 0x12, 0x00, 0x00, 0x2f, 0x02, 0x03, 0x40, 0x00, 0x95, + 0xe2, 0x1f, 0x08, 0x84, 0x00, 0xc4, 0x12, 0x60, 0xf1, 0x0c, 0xb8, +}; +const uint8_t* const _I_Health_16x16[] = {_I_Health_16x16_0}; + +const uint8_t _I_Temperature_16x16_0[] = { + 0x01, 0x00, 0x12, 0x00, 0x00, 0x1e, 0x02, 0x01, 0x40, 0x80, 0x80, + 0x66, 0x41, 0x02, 0xf0, 0x40, 0xc0, 0x23, 0xc0, 0x80, 0x86, 0xd4, +}; +const uint8_t* const _I_Temperature_16x16[] = {_I_Temperature_16x16_0}; + +const uint8_t _I_Unplug_bg_bottom_128x10_0[] = { + 0x01, 0x00, 0x27, 0x00, 0xff, 0x7f, 0xc0, 0x19, 0x7f, 0x07, 0xf8, 0x3f, 0xaf, 0x7f, 0xc0, + 0x7e, 0xcf, 0x41, 0xfd, 0x3e, 0xfc, 0x03, 0xb2, 0x7f, 0x1f, 0xf8, 0x03, 0xf3, 0x8f, 0x0f, + 0xf0, 0x0b, 0xf6, 0x0f, 0x80, 0x07, 0xec, 0x06, 0x00, 0x50, 0xc9, 0xfc, 0x00, +}; +const uint8_t* const _I_Unplug_bg_bottom_128x10[] = {_I_Unplug_bg_bottom_128x10_0}; + +const uint8_t _I_Unplug_bg_top_128x14_0[] = { + 0x01, 0x00, 0x4f, 0x00, 0x80, 0x7f, 0x3f, 0xe0, 0x0a, 0x9f, 0xc0, 0x30, 0x00, 0xeb, + 0x00, 0x0c, 0x07, 0xc0, 0x0f, 0xd8, 0x3f, 0xc3, 0x8e, 0x0f, 0xc8, 0x7f, 0xe3, 0xf2, + 0x0f, 0xc8, 0xff, 0xf3, 0xfc, 0x0d, 0xa8, 0x1f, 0xfa, 0x7f, 0x7c, 0x0e, 0xdf, 0xf3, + 0xf3, 0x3f, 0xdf, 0x03, 0xaa, 0xff, 0xff, 0xfb, 0xdf, 0xfb, 0xc0, 0xfa, 0xdf, 0xff, + 0xfc, 0x60, 0xfc, 0xef, 0xf3, 0xb0, 0x17, 0xff, 0x78, 0x3e, 0xab, 0xfa, 0x1e, 0x0f, + 0xfc, 0x1f, 0x71, 0xf8, 0x27, 0x89, 0x3b, 0xbd, 0x7e, 0x4a, 0x33, 0x59, 0xa4, +}; +const uint8_t* const _I_Unplug_bg_top_128x14[] = {_I_Unplug_bg_top_128x14_0}; + +const uint8_t _I_Voltage_16x16_0[] = { + 0x01, 0x00, 0x1a, 0x00, 0x00, 0x24, 0x0a, 0x01, 0x03, 0xc0, 0x40, 0x78, 0x10, 0x1f, 0x04, + 0x03, 0xe1, 0x07, 0xc0, 0x40, 0xc0, 0xe3, 0xc0, 0x80, 0x58, 0x20, 0x12, 0x00, 0xd3, 0x00, +}; +const uint8_t* const _I_Voltage_16x16[] = {_I_Voltage_16x16_0}; + +const uint8_t _I_RFIDDolphinReceive_97x61_0[] = { + 0x01, 0x00, 0x87, 0x01, 0x00, 0x0f, 0xfa, 0x3e, 0x04, 0x28, 0x08, 0x2d, 0x78, 0x10, 0x1f, 0x00, + 0x24, 0x70, 0x01, 0x86, 0x98, 0x00, 0x86, 0x0c, 0x0c, 0x88, 0x60, 0x08, 0x63, 0x10, 0x0a, 0x00, + 0x31, 0xa0, 0x40, 0x21, 0x90, 0x03, 0x04, 0x1a, 0x5a, 0x08, 0x50, 0xe9, 0x01, 0x23, 0x20, 0x07, + 0x88, 0x30, 0xc5, 0xa6, 0x03, 0x10, 0x61, 0xfc, 0x0a, 0xa2, 0x2d, 0x48, 0x0c, 0x82, 0x20, 0x04, + 0x18, 0x40, 0x40, 0x42, 0x44, 0x37, 0x28, 0x80, 0x30, 0xbc, 0x94, 0xd0, 0x62, 0x4f, 0x20, 0x91, + 0x08, 0x44, 0x12, 0x01, 0x17, 0xe6, 0x40, 0x42, 0x45, 0x00, 0xa1, 0x03, 0x08, 0xa8, 0x31, 0x41, + 0x88, 0x83, 0x0f, 0x03, 0x08, 0x06, 0x1c, 0x1f, 0xa1, 0x01, 0x84, 0x1f, 0x8a, 0x31, 0x09, 0x0c, + 0xa5, 0x40, 0x86, 0x30, 0x98, 0x46, 0x02, 0x48, 0x0c, 0x40, 0xc9, 0x61, 0x00, 0xe2, 0x0c, 0x18, + 0x88, 0x65, 0xb8, 0x85, 0x51, 0x06, 0x21, 0x34, 0x83, 0x23, 0x44, 0x06, 0x29, 0x1c, 0xb4, 0x94, + 0xf8, 0x05, 0x19, 0x12, 0x20, 0xc2, 0x40, 0xb4, 0xa8, 0x18, 0xa9, 0xb5, 0x9b, 0x48, 0x28, 0x05, + 0xa1, 0x06, 0x22, 0xd4, 0xa3, 0x7e, 0x05, 0x98, 0xe0, 0x62, 0x0c, 0xf6, 0x86, 0xf8, 0x16, 0x63, + 0x42, 0x06, 0x0b, 0xa1, 0x60, 0xfe, 0x06, 0xe8, 0xcf, 0x23, 0x0d, 0x53, 0x00, 0x14, 0x0f, 0xe0, + 0xea, 0x28, 0xa0, 0x31, 0xa0, 0x3f, 0x08, 0x18, 0x10, 0x45, 0xa2, 0x11, 0x20, 0x01, 0xf4, 0x3f, + 0xe0, 0x81, 0x84, 0x02, 0x94, 0x18, 0xb0, 0xc0, 0x63, 0xc6, 0x3f, 0xe0, 0x31, 0x87, 0x03, 0x1e, + 0x11, 0x3c, 0x80, 0x47, 0xc1, 0x91, 0x18, 0x80, 0x58, 0x30, 0x0e, 0x01, 0x00, 0x30, 0xbc, 0x47, + 0xc3, 0x05, 0x06, 0x3c, 0x52, 0x00, 0xe4, 0x20, 0xcc, 0x80, 0x04, 0x4d, 0x00, 0x83, 0x73, 0x08, + 0x01, 0x8f, 0xa2, 0x0c, 0xa1, 0xe1, 0xa0, 0x62, 0x16, 0x0c, 0xac, 0x04, 0x14, 0xd0, 0x30, 0x08, + 0x80, 0x31, 0xb8, 0x10, 0x27, 0x89, 0x03, 0x1e, 0x81, 0x05, 0xe0, 0x01, 0x04, 0x1e, 0x40, 0x04, + 0xd0, 0x1c, 0x85, 0x6a, 0x20, 0xc7, 0xa8, 0x02, 0x84, 0xd2, 0x34, 0x00, 0x63, 0x6c, 0x11, 0xe2, + 0x4b, 0x10, 0x63, 0xd6, 0x20, 0x16, 0xa9, 0x80, 0x32, 0x35, 0x90, 0x0e, 0xa5, 0x04, 0x19, 0x15, + 0x48, 0x06, 0xa3, 0x07, 0x01, 0x06, 0x3c, 0xa8, 0x84, 0x30, 0xf8, 0x10, 0x31, 0xe2, 0xa5, 0xc1, + 0x8f, 0x7f, 0x2b, 0xe9, 0xa8, 0xa0, 0x5f, 0x60, 0x04, 0x21, 0x00, 0x29, 0x98, 0x74, 0x1f, 0xa8, + 0x0a, 0x39, 0xc0, 0x05, 0xf5, 0x83, 0xb0, 0xa0, 0x00, 0x3e, 0xaf, 0xfc, 0x1c, 0x19, 0x3d, 0x01, + 0xfb, 0xaa, 0xd3, 0x3c, 0x0c, 0xaa, 0x06, 0x54, 0x19, 0x50, 0x0c, 0xd0, 0x32, 0xe2, 0x05, 0xf1, + 0x00, 0x4c, 0x20, 0x19, 0xe0, 0xc9, 0x7d, 0x08, 0x33, 0xc0, 0x04, +}; +const uint8_t* const _I_RFIDDolphinReceive_97x61[] = {_I_RFIDDolphinReceive_97x61_0}; + +const uint8_t _I_RFIDDolphinSend_97x61_0[] = { + 0x01, 0x00, 0x8d, 0x01, 0x00, 0x0f, 0xfa, 0x3e, 0x04, 0x2a, 0x00, 0x2d, 0x78, 0x10, 0x1f, 0x04, + 0x04, 0x0a, 0x38, 0x00, 0x62, 0xcc, 0x00, 0x43, 0x06, 0x06, 0x44, 0x30, 0x04, 0x31, 0x80, 0x31, + 0x07, 0x48, 0x00, 0x50, 0x20, 0x10, 0xc8, 0x01, 0x64, 0x0c, 0x1d, 0x04, 0x28, 0x24, 0x83, 0xd2, + 0x81, 0x04, 0xc4, 0x18, 0x42, 0xc3, 0x01, 0x90, 0x30, 0xbe, 0x05, 0x51, 0x29, 0xa0, 0x74, 0x60, + 0x80, 0xc1, 0x84, 0x0b, 0x44, 0x5e, 0x43, 0x73, 0x82, 0x41, 0x20, 0x1e, 0x4a, 0x68, 0x31, 0x27, + 0x90, 0x48, 0x84, 0x20, 0x18, 0x31, 0x7e, 0x64, 0x06, 0x20, 0x0c, 0x2a, 0x14, 0x12, 0x40, 0x0c, + 0x28, 0xa0, 0xc4, 0x41, 0x87, 0x81, 0x17, 0x08, 0x30, 0xa0, 0xfd, 0x08, 0x0c, 0x20, 0xfc, 0x38, + 0x08, 0xc4, 0x24, 0x32, 0x95, 0x02, 0x18, 0xc2, 0x61, 0x18, 0x09, 0x20, 0x31, 0x03, 0x25, 0x84, + 0x1d, 0x88, 0x30, 0x62, 0x21, 0x96, 0xe2, 0x44, 0x22, 0x00, 0xc2, 0x26, 0xa0, 0x64, 0x68, 0x80, + 0xc4, 0x33, 0x9e, 0x92, 0x9f, 0x00, 0xa3, 0x48, 0x24, 0x00, 0xc4, 0x40, 0xa4, 0xa8, 0x18, 0xa9, + 0xb5, 0x9b, 0x48, 0x28, 0x05, 0xa1, 0x06, 0x22, 0xd4, 0xa3, 0x7e, 0x05, 0x98, 0xe0, 0x4f, 0x22, + 0xcf, 0x58, 0x6f, 0x80, 0x10, 0x34, 0x24, 0x31, 0x3a, 0x52, 0x0f, 0xe0, 0x03, 0x0c, 0xf1, 0xee, + 0x2d, 0x63, 0x00, 0x0c, 0x0f, 0xe0, 0x13, 0x28, 0xa0, 0x31, 0xa0, 0x3f, 0x08, 0x18, 0x10, 0x45, + 0xa2, 0xe3, 0x40, 0x00, 0xf4, 0x3f, 0xe1, 0xa1, 0x84, 0x02, 0x94, 0x18, 0xb0, 0xc0, 0x63, 0xc6, + 0x3f, 0xe0, 0x31, 0x87, 0x03, 0x1e, 0x11, 0x3c, 0x80, 0x47, 0xc1, 0x90, 0x56, 0x1b, 0x06, 0x01, + 0xc0, 0x20, 0x06, 0x17, 0x88, 0xf8, 0x60, 0xa0, 0xc7, 0x31, 0x8a, 0x58, 0x60, 0xe1, 0x99, 0x00, + 0x08, 0x9a, 0x01, 0x06, 0xd9, 0x10, 0x03, 0x1f, 0x44, 0x19, 0x43, 0xc3, 0x40, 0xc4, 0x2c, 0x19, + 0x58, 0x08, 0x29, 0xa0, 0x60, 0x0c, 0xf2, 0x00, 0x27, 0x02, 0x05, 0x20, 0x06, 0x4d, 0x02, 0x0b, + 0xc0, 0x02, 0x08, 0x3c, 0x80, 0x09, 0xa0, 0x39, 0x0a, 0xd4, 0x41, 0x8f, 0x50, 0x05, 0x09, 0xa4, + 0x5b, 0x4d, 0x00, 0xd8, 0x23, 0xc4, 0x96, 0x20, 0xc7, 0xac, 0x40, 0x2d, 0x53, 0x00, 0x64, 0x6b, + 0x20, 0x1d, 0x4a, 0x08, 0x32, 0x2a, 0x90, 0x0d, 0x46, 0x0e, 0x02, 0x0c, 0x79, 0x51, 0x08, 0x61, + 0xf0, 0x20, 0x63, 0xc5, 0x4b, 0x83, 0x1e, 0xfe, 0x57, 0xd3, 0x51, 0x40, 0xbe, 0xc0, 0x08, 0x42, + 0x00, 0x53, 0x30, 0xe8, 0x3f, 0x50, 0x14, 0x73, 0x80, 0x0b, 0xeb, 0x07, 0x61, 0x40, 0x00, 0x7d, + 0x5f, 0xf8, 0x38, 0x32, 0x7a, 0x03, 0xf7, 0x55, 0xa6, 0x78, 0x19, 0x54, 0x0c, 0xa8, 0x32, 0xa0, + 0x19, 0xa0, 0x65, 0xc4, 0x0b, 0xe2, 0x00, 0x98, 0x40, 0x33, 0xc1, 0x92, 0xfa, 0x10, 0x67, 0x80, + 0x08, +}; +const uint8_t* const _I_RFIDDolphinSend_97x61[] = {_I_RFIDDolphinSend_97x61_0}; + +const uint8_t _I_RFIDDolphinSuccess_108x57_0[] = { + 0x01, 0x00, 0xe7, 0x01, 0x00, 0x0f, 0x03, 0xff, 0x1f, 0x06, 0xd4, 0xe2, 0x01, 0xe0, 0x06, 0xd4, + 0x18, 0x04, 0x30, 0x30, 0x64, 0x60, 0x20, 0x20, 0x31, 0x86, 0x03, 0x62, 0x80, 0x03, 0x28, 0x80, + 0x36, 0x24, 0x00, 0x36, 0x00, 0x28, 0x5c, 0xc3, 0xe6, 0x00, 0x58, 0x40, 0xec, 0xc1, 0xb1, 0x04, + 0x02, 0x19, 0x24, 0x80, 0x0b, 0x02, 0x02, 0x40, 0x37, 0xc4, 0x8c, 0x2e, 0x40, 0x6f, 0x93, 0x8b, + 0x81, 0x07, 0x06, 0xdc, 0xc2, 0x38, 0x66, 0x50, 0x6a, 0xe2, 0x27, 0xe0, 0xd2, 0xfc, 0x08, 0x09, + 0x0c, 0x9c, 0x4b, 0x98, 0x34, 0xa0, 0xe1, 0xd5, 0x06, 0x8f, 0x92, 0xc2, 0x05, 0x1e, 0x42, 0xe1, + 0x81, 0xa3, 0xe2, 0xf0, 0xbc, 0x4c, 0x1a, 0xff, 0x2f, 0x9b, 0x80, 0xd8, 0xca, 0x05, 0x1f, 0x97, + 0xfd, 0xf8, 0x60, 0xd2, 0x01, 0x1e, 0x00, 0x1a, 0x5c, 0x00, 0x08, 0xc9, 0xc1, 0xab, 0x40, 0xf9, + 0x83, 0x46, 0x61, 0x00, 0xd8, 0x4a, 0x81, 0xab, 0xa0, 0xf3, 0x5f, 0xc6, 0x05, 0x58, 0x8a, 0xa4, + 0x09, 0x76, 0x21, 0xb1, 0xf2, 0x83, 0x4f, 0x5d, 0x1a, 0x01, 0x8c, 0x90, 0x1a, 0x31, 0x0d, 0x07, + 0xa9, 0x16, 0x50, 0x0a, 0xac, 0x34, 0xba, 0x42, 0xa1, 0x88, 0x50, 0x23, 0xaa, 0x72, 0xe0, 0x6a, + 0xa1, 0x4a, 0x32, 0x39, 0x88, 0x6c, 0x60, 0xc7, 0x82, 0xb0, 0x55, 0x60, 0xa2, 0x92, 0x80, 0xc0, + 0x43, 0x63, 0x03, 0x25, 0x96, 0xe3, 0x54, 0x33, 0x18, 0xc4, 0x90, 0x22, 0x21, 0x81, 0x81, 0x03, + 0x4a, 0xa9, 0x55, 0x7a, 0x17, 0xf3, 0x82, 0x9f, 0x6d, 0x5e, 0xa9, 0xb6, 0x50, 0x38, 0x70, 0x35, + 0x70, 0x15, 0x5a, 0xa9, 0xb8, 0xa3, 0x46, 0x12, 0x06, 0x9f, 0x83, 0x54, 0x8a, 0x28, 0x80, 0x34, + 0xfc, 0x08, 0x93, 0xaa, 0xc7, 0x40, 0x83, 0x83, 0x81, 0xd3, 0xa1, 0xd1, 0x08, 0x84, 0x0c, 0x24, + 0x3f, 0xed, 0x54, 0x18, 0x26, 0x50, 0x20, 0xd9, 0x42, 0x21, 0x90, 0x4c, 0x07, 0xff, 0xae, 0x52, + 0x20, 0x6a, 0xc4, 0x23, 0x1f, 0x88, 0x3f, 0xf0, 0x1a, 0x45, 0x31, 0xe7, 0x03, 0x4a, 0x41, 0xe0, + 0x69, 0x0f, 0xc2, 0x1e, 0x0d, 0x19, 0x80, 0x48, 0xa2, 0x10, 0xc5, 0x68, 0xdf, 0x0a, 0x82, 0xb9, + 0x28, 0x22, 0x2c, 0xe3, 0x0a, 0xd1, 0x2b, 0x0f, 0x00, 0x3c, 0x22, 0x91, 0x53, 0x9c, 0x50, 0x1a, + 0x30, 0x08, 0x39, 0x1c, 0x60, 0x6d, 0x12, 0x3d, 0x8c, 0xc2, 0x51, 0x00, 0x17, 0x0c, 0xe2, 0x01, + 0xff, 0x83, 0x84, 0xc6, 0x40, 0xb0, 0x19, 0x84, 0xd0, 0x1a, 0x5c, 0x08, 0x1f, 0xf8, 0x8c, 0x50, + 0x43, 0x08, 0xce, 0x2d, 0x06, 0x71, 0x5f, 0x17, 0xfe, 0x12, 0xdf, 0x20, 0x69, 0x55, 0x01, 0xa6, + 0x00, 0x18, 0x40, 0xa4, 0x80, 0x63, 0x3c, 0xb5, 0x03, 0x56, 0x08, 0x8b, 0x20, 0x10, 0xcf, 0x03, + 0x62, 0x08, 0x20, 0x00, 0x94, 0xc6, 0x01, 0x70, 0x01, 0x0c, 0xe8, 0x36, 0x20, 0xd3, 0xe0, 0x00, + 0xcb, 0x10, 0x02, 0x19, 0xf3, 0x9c, 0x41, 0xa3, 0x15, 0x31, 0x90, 0x00, 0x70, 0xc0, 0x21, 0xdd, + 0x86, 0xc4, 0x78, 0x3e, 0xa3, 0x71, 0xe0, 0x30, 0x20, 0x31, 0xbe, 0x86, 0xc4, 0x1a, 0x35, 0x40, + 0x20, 0x8d, 0x89, 0x28, 0x5b, 0xa0, 0xd9, 0xea, 0x3d, 0x44, 0x42, 0x87, 0x83, 0x48, 0x36, 0x49, + 0xe1, 0xa0, 0x75, 0x67, 0x8d, 0x41, 0x54, 0x14, 0x03, 0xf5, 0x2a, 0x06, 0x96, 0x03, 0x54, 0xc4, + 0x14, 0xd0, 0x83, 0x4a, 0xfb, 0x35, 0x06, 0x90, 0x38, 0x4e, 0x46, 0xb4, 0x10, 0xd9, 0x81, 0x49, + 0x72, 0x40, 0x01, 0x0a, 0x95, 0xd4, 0x36, 0x20, 0xd7, 0x55, 0x10, +}; +const uint8_t* const _I_RFIDDolphinSuccess_108x57[] = {_I_RFIDDolphinSuccess_108x57_0}; + +const uint8_t _I_RFIDSmallChip_14x14_0[] = { + 0x00, 0xfe, 0x0d, 0xb7, 0x1d, 0x07, 0x1c, 0xf9, 0x13, 0xcb, 0x1b, 0xcb, 0x1b, 0xf8, + 0x13, 0xfb, 0x1b, 0xfb, 0x1b, 0xf9, 0x03, 0x07, 0x1c, 0xb7, 0x1d, 0xf6, 0x0f, +}; +const uint8_t* const _I_RFIDSmallChip_14x14[] = {_I_RFIDSmallChip_14x14_0}; + +const uint8_t _I_SDQuestion_35x43_0[] = { + 0x01, 0x00, 0x67, 0x00, 0xf8, 0x7f, 0xc0, 0x03, 0x03, 0xfc, 0x01, 0x0a, 0x0f, 0x38, 0xa4, 0xe4, + 0xa4, 0x80, 0x4f, 0x0c, 0x20, 0x13, 0xc0, 0x9f, 0x80, 0x02, 0x15, 0xfe, 0x00, 0x04, 0x29, 0xfc, + 0x03, 0xfd, 0x07, 0xfa, 0x47, 0xe7, 0xdf, 0xc8, 0x3f, 0xea, 0x1f, 0x7f, 0xfc, 0x41, 0xff, 0xb8, + 0xff, 0xf8, 0x10, 0x7f, 0xe0, 0x4e, 0xef, 0x86, 0x08, 0x68, 0x33, 0xf1, 0x10, 0xff, 0x3f, 0xf1, + 0xf1, 0x60, 0x81, 0x06, 0x1e, 0x36, 0x10, 0x20, 0xe1, 0xc0, 0x87, 0xc7, 0x02, 0x0f, 0xd3, 0xff, + 0xe3, 0x02, 0x0f, 0xe8, 0x08, 0x7f, 0xd0, 0x21, 0x89, 0xc4, 0x08, 0x9f, 0x70, 0x21, 0x9a, 0x08, + 0x08, 0xc1, 0x89, 0x02, 0x20, 0x62, 0x40, 0x8f, 0xfe, 0x68, 0x98, +}; +const uint8_t* const _I_SDQuestion_35x43[] = {_I_SDQuestion_35x43_0}; + +const uint8_t _I_Cry_dolph_55x52_0[] = { + 0x01, 0x00, 0xe8, 0x00, 0x00, 0x0f, 0xe3, 0xff, 0x01, 0x03, 0x1f, 0xfb, 0xff, 0x0f, 0x02, 0x96, + 0x02, 0x0f, 0x00, 0x9f, 0x01, 0x8b, 0xc0, 0x12, 0x1f, 0x80, 0x18, 0xae, 0x00, 0x21, 0xe0, 0x07, + 0x0a, 0x30, 0x0a, 0x28, 0x18, 0x08, 0x61, 0x80, 0x62, 0x83, 0x00, 0x90, 0x14, 0x61, 0x02, 0x0c, + 0x16, 0x00, 0x76, 0x60, 0x66, 0x98, 0x0b, 0x04, 0x90, 0x60, 0x66, 0xb0, 0x00, 0x48, 0x0d, 0x21, + 0x21, 0x03, 0x30, 0x74, 0x40, 0xd3, 0x80, 0x03, 0x34, 0x04, 0xc0, 0x52, 0x00, 0x32, 0xc7, 0xa0, + 0x18, 0x80, 0x31, 0x80, 0x07, 0xe1, 0x01, 0x37, 0x18, 0x50, 0x80, 0xc2, 0x92, 0x10, 0x31, 0xe8, + 0x23, 0xe9, 0x63, 0x86, 0x54, 0x3f, 0xe0, 0xe1, 0x0d, 0x96, 0x83, 0xfc, 0x06, 0x40, 0x69, 0x6c, + 0x3c, 0x60, 0xd2, 0xfc, 0xc0, 0x60, 0x58, 0x48, 0x0c, 0x1b, 0x81, 0x08, 0x14, 0x9c, 0x1a, 0x81, + 0x04, 0x03, 0x46, 0x80, 0x0c, 0x50, 0x26, 0x21, 0xc1, 0x94, 0x26, 0x14, 0x27, 0x8a, 0x40, 0xc0, + 0xc2, 0xe7, 0x26, 0x40, 0x81, 0x86, 0xc0, 0x6b, 0x28, 0x64, 0x0f, 0x01, 0x10, 0x4e, 0x14, 0x60, + 0x0c, 0x29, 0x02, 0x48, 0x8b, 0x5c, 0x45, 0x22, 0x01, 0x10, 0x31, 0x3a, 0x4c, 0x0c, 0x34, 0x06, + 0xf1, 0xd8, 0x00, 0xc5, 0x1a, 0x64, 0x94, 0x0c, 0xc0, 0x37, 0x52, 0x20, 0x81, 0x84, 0x26, 0x3e, + 0x88, 0x0c, 0x38, 0x28, 0x54, 0x0e, 0xac, 0x1f, 0xe1, 0x3f, 0x06, 0x96, 0x82, 0x7e, 0x29, 0x4a, + 0xaf, 0xfd, 0x76, 0x30, 0x3a, 0x41, 0x14, 0x7f, 0xd0, 0xf8, 0x78, 0x18, 0xaa, 0x9f, 0xd4, 0xe0, + 0x83, 0x4f, 0xf5, 0xf7, 0x38, 0x0b, 0x9c, 0x6a, 0x1f, 0x5b, 0x5c, 0x00, +}; +const uint8_t* const _I_Cry_dolph_55x52[] = {_I_Cry_dolph_55x52_0}; + +const uint8_t _I_Alert_9x8_0[] = { + 0x00, + 0x10, + 0x00, + 0x38, + 0x00, + 0x28, + 0x00, + 0x6c, + 0x00, + 0x6c, + 0x00, + 0xfe, + 0x00, + 0xee, + 0x00, + 0xff, + 0x01, +}; +const uint8_t* const _I_Alert_9x8[] = {_I_Alert_9x8_0}; + +const uint8_t _I_Attention_5x8_0[] = { + 0x00, + 0x0e, + 0x0a, + 0x0a, + 0x0a, + 0x0e, + 0x04, + 0x00, + 0x0e, +}; +const uint8_t* const _I_Attention_5x8[] = {_I_Attention_5x8_0}; + +const uint8_t _I_Background_128x11_0[] = { + 0x01, 0x00, 0x70, 0x00, 0xff, 0x40, 0x40, 0xc9, 0xe0, 0xff, 0x80, 0x06, 0x1e, 0x08, 0x38, + 0x0c, 0x0c, 0x1e, 0x93, 0x00, 0x19, 0x46, 0x01, 0x07, 0x7d, 0x83, 0x03, 0xd2, 0x31, 0xff, + 0xdb, 0xd5, 0x66, 0x20, 0x83, 0xc0, 0xff, 0x05, 0x24, 0x00, 0x1c, 0x78, 0x28, 0xbc, 0x40, + 0x72, 0xbf, 0xcf, 0x47, 0xeb, 0x40, 0xdb, 0x7a, 0xbf, 0xf0, 0x40, 0x39, 0x60, 0x28, 0x3f, + 0xe0, 0xa0, 0xea, 0x80, 0x63, 0x3f, 0x0b, 0x17, 0xe4, 0x3e, 0x5a, 0xbc, 0xf9, 0x99, 0x70, + 0x1f, 0x81, 0x50, 0xc0, 0x80, 0xe7, 0x3e, 0x1e, 0x9d, 0x57, 0xfb, 0x7f, 0x23, 0x15, 0xb0, + 0x12, 0x5b, 0x5b, 0x02, 0x1d, 0x8c, 0xc3, 0x80, 0x24, 0x9e, 0x03, 0x80, 0x5e, 0x40, 0x00, + 0xa1, 0x88, 0x0e, 0x98, 0x00, 0x7b, 0x07, 0x08, 0xb2, 0x44, 0x41, +}; +const uint8_t* const _I_Background_128x11[] = {_I_Background_128x11_0}; + +const uint8_t _I_Battery_26x8_0[] = { + 0x01, 0x00, 0x13, 0x00, 0xff, 0x7f, 0xef, 0xf0, 0x08, 0x0c, 0x03, 0x00, + 0x03, 0x38, 0x18, 0x0c, 0xa0, 0x40, 0x36, 0x05, 0x98, 0x6d, 0x00, +}; +const uint8_t* const _I_Battery_26x8[] = {_I_Battery_26x8_0}; + +const uint8_t _I_Bluetooth_Connected_16x8_0[] = { + 0x00, + 0x04, + 0x00, + 0x0d, + 0x00, + 0x16, + 0x60, + 0x4c, + 0x97, + 0x4c, + 0x97, + 0x16, + 0x60, + 0x0d, + 0x00, + 0x04, + 0x00, +}; +const uint8_t* const _I_Bluetooth_Connected_16x8[] = {_I_Bluetooth_Connected_16x8_0}; + +const uint8_t _I_Bluetooth_Idle_5x8_0[] = { + 0x00, + 0x04, + 0x0d, + 0x16, + 0x0c, + 0x0c, + 0x16, + 0x0d, + 0x04, +}; +const uint8_t* const _I_Bluetooth_Idle_5x8[] = {_I_Bluetooth_Idle_5x8_0}; + +const uint8_t _I_Charging_lightning_9x10_0[] = { + 0x00, 0x40, 0x01, 0xa0, 0x00, 0x50, 0x00, 0xe8, 0x01, 0x84, 0x00, + 0x42, 0x00, 0x2f, 0x00, 0x14, 0x00, 0x0a, 0x00, 0x05, 0x00, +}; +const uint8_t* const _I_Charging_lightning_9x10[] = {_I_Charging_lightning_9x10_0}; + +const uint8_t _I_Charging_lightning_mask_9x10_0[] = { + 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x78, 0x00, + 0x3c, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, +}; +const uint8_t* const _I_Charging_lightning_mask_9x10[] = {_I_Charging_lightning_mask_9x10_0}; + +const uint8_t _I_GameMode_11x8_0[] = { + 0x00, + 0x20, + 0x00, + 0xfe, + 0x03, + 0xfb, + 0x07, + 0x71, + 0x05, + 0xfb, + 0x07, + 0x8f, + 0x07, + 0x07, + 0x07, + 0x03, + 0x06, +}; +const uint8_t* const _I_GameMode_11x8[] = {_I_GameMode_11x8_0}; + +const uint8_t _I_Hidden_window_9x8_0[] = { + 0x00, + 0xfe, + 0x01, + 0x7e, + 0x01, + 0xfe, + 0x01, + 0x02, + 0x01, + 0x7f, + 0x01, + 0x41, + 0x01, + 0xc1, + 0x01, + 0x7f, + 0x00, +}; +const uint8_t* const _I_Hidden_window_9x8[] = {_I_Hidden_window_9x8_0}; + +const uint8_t _I_Lock_8x8_0[] = { + 0x00, + 0x3c, + 0x42, + 0x42, + 0xff, + 0xff, + 0xe7, + 0xff, + 0xff, +}; +const uint8_t* const _I_Lock_8x8[] = {_I_Lock_8x8_0}; + +const uint8_t _I_SDcardFail_11x8_0[] = { + 0x00, + 0xff, + 0x07, + 0xb7, + 0x07, + 0xff, + 0x07, + 0x87, + 0x07, + 0x7b, + 0x07, + 0xff, + 0x07, + 0xff, + 0x07, + 0x67, + 0x00, +}; +const uint8_t* const _I_SDcardFail_11x8[] = {_I_SDcardFail_11x8_0}; + +const uint8_t _I_SDcardMounted_11x8_0[] = { + 0x01, + 0x00, + 0x09, + 0x00, + 0xff, + 0xc1, + 0xff, + 0xf0, + 0x40, + 0x1c, + 0xd9, + 0xe0, + 0x00, +}; +const uint8_t* const _I_SDcardMounted_11x8[] = {_I_SDcardMounted_11x8_0}; + +const uint8_t _I_Dynamic_9x7_0[] = { + 0x00, + 0x00, + 0x00, + 0x0c, + 0x01, + 0x92, + 0x00, + 0x92, + 0x00, + 0x61, + 0x00, + 0x00, + 0x00, + 0xff, + 0x01, +}; +const uint8_t* const _I_Dynamic_9x7[] = {_I_Dynamic_9x7_0}; + +const uint8_t _I_Lock_7x8_0[] = { + 0x00, + 0x1c, + 0x22, + 0x22, + 0x7f, + 0x7f, + 0x77, + 0x7f, + 0x3e, +}; +const uint8_t* const _I_Lock_7x8[] = {_I_Lock_7x8_0}; + +const uint8_t _I_MHz_25x11_0[] = { + 0x01, 0x00, 0x21, 0x00, 0xe1, 0xe1, 0xa0, 0x30, 0x0f, 0x38, 0x0c, 0xbf, 0xe0, + 0x34, 0xfe, 0xc0, 0x7b, 0x7f, 0xe0, 0x19, 0xf0, 0x60, 0x1d, 0xbc, 0x35, 0x84, + 0x36, 0x53, 0x10, 0x19, 0x46, 0x40, 0x64, 0x13, 0x10, 0x19, 0x80, +}; +const uint8_t* const _I_MHz_25x11[] = {_I_MHz_25x11_0}; + +const uint8_t _I_Quest_7x8_0[] = { + 0x00, + 0x1e, + 0x33, + 0x33, + 0x30, + 0x18, + 0x0c, + 0x00, + 0x0c, +}; +const uint8_t* const _I_Quest_7x8[] = {_I_Quest_7x8_0}; + +const uint8_t _I_Raw_9x7_0[] = { + 0x00, + 0x08, + 0x00, + 0x4c, + 0x00, + 0xdc, + 0x00, + 0xfe, + 0x00, + 0xff, + 0x01, + 0x00, + 0x00, + 0xff, + 0x01, +}; +const uint8_t* const _I_Raw_9x7[] = {_I_Raw_9x7_0}; + +const uint8_t _I_Scanning_123x52_0[] = { + 0x01, 0x00, 0xd9, 0x01, 0x00, 0x78, 0x03, 0xc0, 0x1f, 0x00, 0xe0, 0x7f, 0xc1, 0xfb, 0xf0, 0x80, + 0x41, 0xc0, 0xc7, 0x03, 0x07, 0xbe, 0xb2, 0x07, 0x18, 0x07, 0xe5, 0x5a, 0x0b, 0x60, 0x02, 0x96, + 0x02, 0x04, 0x0f, 0x7c, 0x0c, 0x2b, 0x00, 0x0f, 0xb0, 0x60, 0xc5, 0x60, 0x10, 0x10, 0x30, 0xd0, + 0x01, 0xef, 0x40, 0x80, 0x4e, 0x20, 0x00, 0xb2, 0x07, 0xac, 0x40, 0x04, 0x32, 0x08, 0x05, 0xd2, + 0x01, 0x04, 0x07, 0x96, 0x08, 0x48, 0x50, 0x08, 0x40, 0x3c, 0xed, 0x00, 0xf3, 0x90, 0x60, 0xa0, + 0x50, 0x60, 0x28, 0x82, 0x08, 0x44, 0x3d, 0x0f, 0x04, 0x3c, 0x1e, 0x90, 0xa8, 0x60, 0xe0, 0xc1, + 0xe3, 0xa0, 0x8e, 0x0d, 0x8c, 0x1e, 0x51, 0x48, 0x06, 0x08, 0x64, 0x5e, 0x0e, 0x9c, 0x0c, 0x1e, + 0x51, 0x00, 0x7a, 0x50, 0x41, 0xe5, 0x90, 0xd3, 0xd0, 0x24, 0x80, 0xf7, 0x90, 0x83, 0xcb, 0x91, + 0x7f, 0xc2, 0x4a, 0x01, 0xe5, 0x84, 0x07, 0x8f, 0xff, 0x01, 0x20, 0x30, 0x0e, 0x22, 0xcf, 0x3e, + 0xc4, 0x03, 0xd3, 0xf5, 0xff, 0x07, 0x8c, 0x40, 0xc0, 0x34, 0x4b, 0x24, 0xb8, 0x1e, 0x9f, 0xcd, + 0x7f, 0xfe, 0x2a, 0x0f, 0x13, 0x00, 0xd1, 0x3c, 0x92, 0xfc, 0x44, 0xa8, 0x1e, 0x31, 0x8e, 0xa7, + 0x7e, 0x3f, 0x14, 0x07, 0xb5, 0x43, 0xff, 0x00, 0xff, 0x47, 0xfd, 0x93, 0xf2, 0x78, 0x83, 0xd3, + 0x89, 0x2f, 0xf5, 0x34, 0x06, 0x03, 0x1a, 0xfe, 0x17, 0xc8, 0x1e, 0x78, 0x4c, 0x44, 0xbe, 0x3a, + 0x87, 0x1b, 0xec, 0x78, 0xbe, 0x51, 0x82, 0x79, 0xe1, 0xa3, 0xfc, 0x65, 0xc0, 0xe1, 0x2f, 0xb1, + 0x60, 0x79, 0x3e, 0xc4, 0xde, 0x54, 0x6f, 0xaf, 0x0d, 0xb2, 0x34, 0x48, 0x0c, 0x88, 0x1e, 0x2b, + 0xe1, 0x47, 0x9e, 0x1e, 0x15, 0x7c, 0x02, 0x0d, 0x12, 0x07, 0x22, 0xc4, 0x32, 0xc9, 0x5e, 0x74, + 0x58, 0x28, 0x8c, 0x6f, 0xda, 0x48, 0x1d, 0x08, 0x1e, 0x8c, 0xf2, 0xc3, 0x0f, 0x47, 0x81, 0x81, + 0xd2, 0xc1, 0xe8, 0x50, 0x88, 0x18, 0x3c, 0x82, 0x65, 0x05, 0x01, 0x0c, 0xc2, 0x01, 0xd2, 0xff, + 0xe0, 0x44, 0xa2, 0x00, 0x22, 0xf0, 0xc0, 0x03, 0xc3, 0x00, 0x24, 0x0f, 0x4a, 0x3f, 0x80, 0x07, + 0xa0, 0x10, 0xa0, 0xb8, 0x08, 0x00, 0xa4, 0x7a, 0x31, 0xf8, 0x04, 0x24, 0x1e, 0x71, 0x00, 0xf9, + 0xf8, 0x4e, 0xe3, 0xe9, 0x87, 0xc0, 0x22, 0x40, 0xf3, 0x00, 0x10, 0xfc, 0x63, 0xc5, 0x01, 0xf4, + 0x03, 0xc6, 0x28, 0x0f, 0x61, 0xf9, 0x40, 0x2e, 0x1e, 0xe0, 0x78, 0xc6, 0x01, 0xed, 0x07, 0x01, + 0x94, 0xf3, 0xf2, 0x0f, 0x10, 0x03, 0x9d, 0x8b, 0x55, 0x9f, 0xf8, 0x03, 0xe6, 0x03, 0x40, 0xaa, + 0xff, 0x6b, 0xff, 0x08, 0xb8, 0x7e, 0x70, 0x1e, 0xaf, 0xfc, 0xff, 0xc0, 0x0f, 0x90, 0xf8, 0xf5, + 0x7f, 0xf1, 0xf0, 0x7d, 0x40, 0xb0, 0x1a, 0xaf, 0xfc, 0x3f, 0xc1, 0x13, 0x0f, 0xcc, 0x02, 0xab, + 0x55, 0x81, 0xfc, 0x22, 0xa1, 0xf9, 0x2f, 0x0e, 0xaa, 0x01, 0xb0, 0x85, 0x07, 0xea, 0xa9, 0x75, + 0x80, 0x56, 0x21, 0xa1, 0xfa, 0xd4, 0x1f, 0x07, 0x50, 0xa5, 0x35, 0xfb, 0xdf, 0x00, 0x83, 0x5c, + 0x4a, 0x90, 0x7e, 0x00, 0x05, 0xae, 0x1a, 0x88, 0x7e, 0x40, 0x05, 0xd7, 0x07, 0x44, 0x00, 0xb2, + 0x78, 0x0b, 0xd8, 0x3e, 0x4f, 0x27, 0xc0, 0x8f, 0x83, 0xe6, 0x54, 0x03, 0x2f, 0x83, 0xd0, 0xc0, + 0x0d, 0x55, 0x01, 0x97, 0xf0, 0x9d, 0x29, 0xd1, 0x01, 0x90, 0xba, 0xa0, 0x00, +}; +const uint8_t* const _I_Scanning_123x52[] = {_I_Scanning_123x52_0}; + +const uint8_t _I_Static_9x7_0[] = { + 0x01, + 0x00, + 0x0c, + 0x00, + 0xbe, + 0x40, + 0x28, + 0x80, + 0x14, + 0xe3, + 0xc0, + 0x41, + 0x63, + 0xff, + 0x80, + 0x80, +}; +const uint8_t* const _I_Static_9x7[] = {_I_Static_9x7_0}; + +const uint8_t _I_Unlock_7x8_0[] = { + 0x00, + 0x1c, + 0x22, + 0x02, + 0x4f, + 0x67, + 0x73, + 0x79, + 0x3c, +}; +const uint8_t* const _I_Unlock_7x8[] = {_I_Unlock_7x8_0}; + +const uint8_t _I_Auth_62x31_0[] = { + 0x01, 0x00, 0xaf, 0x00, 0x00, 0x47, 0xc2, 0xfe, 0x07, 0x58, 0x66, 0x02, 0x02, 0x07, 0x48, + 0x1c, 0x02, 0x0c, 0x06, 0x3c, 0x00, 0x08, 0x61, 0x00, 0x73, 0xa0, 0x00, 0x86, 0x20, 0x02, + 0x1b, 0x04, 0x02, 0x40, 0x04, 0x10, 0x11, 0x01, 0xc4, 0x18, 0x40, 0x72, 0xf0, 0x40, 0x40, + 0xe4, 0x1a, 0x20, 0x38, 0xc2, 0x3e, 0x00, 0x71, 0xbc, 0x05, 0xca, 0x11, 0x08, 0x80, 0xe0, + 0x30, 0xc0, 0x72, 0x82, 0x7d, 0x20, 0x44, 0x81, 0x80, 0x81, 0xcb, 0x75, 0x05, 0x02, 0x08, + 0x1c, 0xe7, 0x50, 0x58, 0xc0, 0x94, 0x40, 0xe5, 0xfa, 0x82, 0xc1, 0xbf, 0x06, 0xc1, 0x80, + 0x40, 0x80, 0xe3, 0x00, 0xbe, 0x40, 0x3f, 0x10, 0x18, 0x17, 0xd0, 0xd0, 0x33, 0xf3, 0xa0, + 0xc0, 0xe0, 0x52, 0x88, 0x26, 0x02, 0x3e, 0x1d, 0x18, 0x14, 0x08, 0xa0, 0x3c, 0x08, 0x78, + 0x3c, 0xc0, 0xe3, 0xe0, 0x83, 0x87, 0xcd, 0x32, 0x42, 0x11, 0x17, 0x90, 0x04, 0x61, 0x9f, + 0xf8, 0x06, 0x20, 0x0e, 0x41, 0xb1, 0x9e, 0x1b, 0x44, 0x2e, 0x5f, 0x0f, 0xfc, 0x0c, 0x0e, + 0x80, 0x02, 0x80, 0xc1, 0x00, 0xe8, 0xab, 0x11, 0xf9, 0x01, 0xca, 0xe0, 0x07, 0x68, 0x60, + 0xb4, 0x40, 0xe7, 0xfe, 0x1f, 0x88, 0x1d, 0x09, 0x82, 0x28, 0x10, 0xba, 0x01, 0xcc, +}; +const uint8_t* const _I_Auth_62x31[] = {_I_Auth_62x31_0}; + +const uint8_t _I_Connect_me_62x31_0[] = { + 0x01, 0x00, 0xb7, 0x00, 0x00, 0x47, 0xc2, 0xfe, 0x07, 0x58, 0x66, 0x02, 0x02, 0x07, 0x48, 0x1c, + 0x02, 0x0c, 0x06, 0x3c, 0x00, 0x08, 0x61, 0x00, 0x73, 0xa0, 0x00, 0x86, 0x20, 0x02, 0x1b, 0xe4, + 0x02, 0x40, 0x04, 0x10, 0x11, 0x51, 0x01, 0x86, 0x07, 0x2b, 0x60, 0x1c, 0xc3, 0x44, 0x0f, 0x18, + 0x47, 0xc0, 0x0e, 0x37, 0x80, 0xf9, 0x42, 0x21, 0x10, 0x1c, 0x06, 0x1a, 0x01, 0x82, 0x80, 0x41, + 0x3e, 0x90, 0x22, 0x40, 0xc0, 0x40, 0xe5, 0xba, 0x82, 0xd8, 0x20, 0x00, 0x73, 0x9d, 0x41, 0x63, + 0x1e, 0x00, 0x39, 0xfe, 0xa0, 0xb0, 0x6f, 0xc0, 0x7c, 0xa0, 0x40, 0x71, 0x16, 0x90, 0x1c, 0xbe, + 0x86, 0x81, 0x9f, 0x81, 0xce, 0x51, 0x04, 0xc0, 0x47, 0xe0, 0x1f, 0xe0, 0x38, 0x94, 0x07, 0x81, + 0x0f, 0x80, 0x4a, 0x00, 0xe7, 0xe0, 0x83, 0x81, 0xcd, 0x32, 0x42, 0x11, 0x03, 0x9c, 0x0a, 0x19, + 0xff, 0x80, 0x4e, 0x00, 0xe5, 0x0c, 0x81, 0xcf, 0x20, 0x21, 0xc1, 0x03, 0x8f, 0xc3, 0xff, 0x03, + 0x80, 0x92, 0x44, 0x3e, 0x40, 0x01, 0x80, 0xc1, 0x20, 0x60, 0x73, 0x55, 0x8c, 0x0a, 0x08, 0x07, + 0x3b, 0x80, 0x1c, 0x61, 0x00, 0x73, 0x86, 0x11, 0x48, 0x0e, 0x5f, 0xe1, 0xf8, 0xc3, 0x00, 0xe7, + 0xf8, 0x6c, 0x0c, 0x42, 0x40, 0x17, 0x30, 0x38, 0xcc, 0x24, 0x00, +}; +const uint8_t* const _I_Connect_me_62x31[] = {_I_Connect_me_62x31_0}; + +const uint8_t _I_Connected_62x31_0[] = { + 0x01, 0x00, 0xaa, 0x00, 0x00, 0x47, 0xc2, 0xfe, 0x07, 0x58, 0x66, 0x02, 0x02, 0x07, 0x48, 0x1c, + 0x02, 0x0c, 0x06, 0x3c, 0x00, 0x08, 0x61, 0x00, 0x73, 0xa0, 0x00, 0x86, 0x20, 0x07, 0x39, 0x00, + 0x09, 0x01, 0x88, 0x07, 0x70, 0xd1, 0x09, 0x0b, 0xe0, 0x07, 0x1b, 0xc0, 0x1c, 0xe1, 0x10, 0x1c, + 0x06, 0x18, 0x0e, 0x50, 0x4f, 0xa4, 0x08, 0x90, 0x24, 0x92, 0x82, 0x6e, 0xa0, 0xb6, 0x08, 0x07, + 0x04, 0x10, 0x30, 0x49, 0xd4, 0x16, 0x31, 0xe0, 0xa0, 0xfc, 0x80, 0xe3, 0xfa, 0x82, 0xc1, 0xbf, + 0x14, 0x08, 0x64, 0x06, 0x04, 0x07, 0x18, 0x05, 0xf2, 0x81, 0x04, 0x81, 0x40, 0xbe, 0x86, 0x81, + 0x9f, 0xe0, 0x20, 0x80, 0x81, 0x94, 0x41, 0x30, 0x11, 0xf0, 0x39, 0x94, 0x07, 0x81, 0x0f, 0x03, + 0xaf, 0x82, 0x0f, 0x00, 0x84, 0x81, 0xc5, 0x32, 0x42, 0x11, 0x98, 0x89, 0xc6, 0x01, 0x02, 0x86, + 0x7f, 0xc9, 0x03, 0x03, 0x03, 0x8c, 0x32, 0x07, 0x3c, 0x2c, 0x08, 0x3c, 0xbe, 0x1f, 0xf8, 0x18, + 0x1d, 0x00, 0x05, 0x81, 0x0e, 0x08, 0x1c, 0xf0, 0x0a, 0xc1, 0x03, 0xa5, 0xc0, 0x0e, 0xd0, 0xc4, + 0xc8, 0x81, 0xcf, 0xfd, 0x03, 0x03, 0xaf, 0xe2, 0x02, 0xb1, 0x10, 0xba, 0x01, 0xcc, +}; +const uint8_t* const _I_Connected_62x31[] = {_I_Connected_62x31_0}; + +const uint8_t _I_Drive_112x35_0[] = { + 0x01, 0x00, 0x72, 0x00, 0xf0, 0x7f, 0xc0, 0x0f, 0x1f, 0x06, 0x94, 0x40, 0x2f, 0x12, 0x00, + 0x19, 0x42, 0x01, 0xb1, 0x40, 0x01, 0x94, 0x10, 0x1b, 0x18, 0x00, 0x19, 0x41, 0x81, 0xb9, + 0x07, 0x06, 0xc9, 0x24, 0x81, 0xb4, 0x02, 0x20, 0x6f, 0x83, 0x66, 0x7c, 0x0d, 0xc9, 0x10, + 0x6f, 0xc1, 0xbe, 0x0d, 0xf2, 0x9f, 0x83, 0x7c, 0x14, 0x3f, 0x8f, 0xff, 0xe4, 0x1b, 0x4c, + 0xe1, 0xc4, 0x83, 0x6a, 0x1f, 0x00, 0xc7, 0x8d, 0xfc, 0xc3, 0xe0, 0xdf, 0x06, 0xfa, 0xd7, + 0xc3, 0x7e, 0x99, 0xf0, 0x6d, 0x7f, 0xc0, 0x02, 0x0d, 0xcb, 0xf8, 0x37, 0x27, 0xe3, 0x7c, + 0x80, 0x2a, 0x84, 0x00, 0xf4, 0x00, 0x19, 0x47, 0xc1, 0xb1, 0x20, 0x01, 0x97, 0xf8, 0x92, + 0x40, 0x05, 0x0b, 0x9f, 0xf0, 0x1b, 0x03, 0x33, 0x7f, 0x08, 0x01, 0xc9, 0xe6, +}; +const uint8_t* const _I_Drive_112x35[] = {_I_Drive_112x35_0}; + +const uint8_t _I_Error_62x31_0[] = { + 0x01, 0x00, 0x9e, 0x00, 0x00, 0x47, 0xc2, 0xfe, 0x07, 0x58, 0x66, 0x02, 0x02, 0x07, 0x48, + 0x1c, 0x02, 0x0c, 0x06, 0x3c, 0x00, 0x08, 0x61, 0x00, 0x73, 0xa0, 0x00, 0x86, 0x20, 0x07, + 0x39, 0x00, 0x09, 0x01, 0x88, 0x07, 0x70, 0xd1, 0x09, 0x0b, 0xe0, 0x07, 0x38, 0x1c, 0x62, + 0x11, 0x08, 0x80, 0x8c, 0x8a, 0x0f, 0x1c, 0x82, 0x7d, 0x20, 0x58, 0x0b, 0xe4, 0x02, 0x1d, + 0x0e, 0x82, 0x6e, 0xa0, 0xb8, 0x0c, 0x1c, 0x02, 0x39, 0x07, 0x82, 0x4e, 0xa0, 0xb7, 0x08, + 0x04, 0x07, 0x71, 0x03, 0x82, 0x7e, 0xa0, 0xb0, 0xe8, 0x04, 0x0b, 0xe1, 0x01, 0x81, 0x01, + 0xc6, 0x01, 0xc0, 0x81, 0xf8, 0x01, 0x42, 0x27, 0x18, 0x04, 0xc0, 0x1e, 0x63, 0x71, 0x3d, + 0x0c, 0x08, 0x3e, 0x20, 0xa1, 0x22, 0x94, 0x08, 0x5e, 0x21, 0x51, 0x0f, 0x08, 0xbc, 0x47, + 0xe2, 0x07, 0x29, 0x81, 0x40, 0x49, 0xe2, 0x07, 0x28, 0x61, 0x80, 0x4b, 0xe2, 0x07, 0x28, + 0x19, 0xe0, 0xc0, 0xe2, 0x0d, 0x18, 0xc0, 0x1d, 0x00, 0x02, 0xa8, 0x30, 0x39, 0x2e, 0x10, + 0x0e, 0x5e, 0x00, 0x3b, 0x7e, 0x00, 0xec, 0x46, 0x10, 0x3f, 0x80, 0xc8, +}; +const uint8_t* const _I_Error_62x31[] = {_I_Error_62x31_0}; + +const uint8_t _I_Updating_32x40_0[] = { + 0x01, 0x00, 0x56, 0x00, 0xc0, 0x7f, 0xc0, 0x03, 0xc0, 0x01, 0x97, 0x82, 0x07, 0x00, 0xe0, + 0x5c, 0x00, 0x65, 0x38, 0x01, 0x94, 0x70, 0x06, 0x50, 0xe0, 0x19, 0x41, 0xc0, 0x65, 0xff, + 0x01, 0xb4, 0x0c, 0x02, 0x7e, 0x08, 0x38, 0x0c, 0x7c, 0xd6, 0x70, 0x18, 0xfb, 0xfe, 0xfc, + 0x0c, 0x18, 0xc8, 0x78, 0x20, 0x33, 0x81, 0x8f, 0x8a, 0x07, 0x3e, 0xbe, 0x70, 0x38, 0x71, + 0xff, 0xc7, 0x0f, 0xc7, 0x0f, 0xf8, 0x71, 0xc0, 0x76, 0x13, 0x30, 0xd9, 0x88, 0xcc, 0x5f, + 0x03, 0xb2, 0x21, 0xa1, 0x2c, 0xc0, 0x26, 0x82, 0x10, 0x1f, 0x80, 0xd1, 0x24, 0x40, 0x04, +}; +const uint8_t* const _I_Updating_32x40[] = {_I_Updating_32x40_0}; + +const uint8_t _I_DolphinMafia_115x62_0[] = { + 0x01, 0x00, 0x21, 0x02, 0x00, 0x1e, 0x02, 0x06, 0x0e, 0xcb, 0x04, 0x10, 0x1d, 0x91, 0x88, 0x40, + 0x3b, 0x20, 0xc0, 0xec, 0xc0, 0x40, 0x62, 0x03, 0xac, 0x80, 0x03, 0xb2, 0x31, 0x00, 0x90, 0x03, + 0xae, 0x5e, 0x0e, 0xcf, 0xc4, 0x56, 0x01, 0x40, 0x07, 0x56, 0xbe, 0x14, 0x0e, 0x2f, 0xf1, 0x5e, + 0x2a, 0xa1, 0xd1, 0xc0, 0x7c, 0x3f, 0xf0, 0x70, 0x73, 0x70, 0x35, 0x41, 0xd1, 0xc0, 0x7f, 0xff, + 0xf0, 0xf0, 0x73, 0x50, 0x03, 0xa4, 0x0d, 0x10, 0x74, 0x07, 0x46, 0x55, 0xe0, 0x07, 0x10, 0xb1, + 0xc3, 0xa3, 0x55, 0xfe, 0x03, 0x88, 0x94, 0xe1, 0xd1, 0xd5, 0x03, 0x4a, 0x3e, 0x59, 0x9e, 0xaf, + 0xfe, 0xff, 0x05, 0x60, 0x4e, 0xab, 0xf5, 0xff, 0x95, 0xb4, 0xa4, 0x3a, 0x3f, 0xd0, 0xe0, 0xfa, + 0x20, 0x20, 0xf8, 0xd5, 0xff, 0xb5, 0xf0, 0x0f, 0x88, 0x3a, 0x6a, 0xbf, 0xf8, 0xaf, 0x82, 0x6f, + 0x03, 0x07, 0x47, 0xaf, 0xff, 0x0a, 0xfe, 0x5f, 0xc1, 0xd3, 0xf6, 0xbf, 0xe0, 0x7f, 0xfe, 0xf0, + 0x73, 0x41, 0x00, 0x43, 0xfa, 0xd7, 0xf8, 0x27, 0xfe, 0xe0, 0x73, 0x40, 0x80, 0x43, 0xfe, 0xab, + 0xfe, 0x21, 0xfc, 0xe5, 0x9b, 0x05, 0x48, 0xea, 0x3f, 0xc8, 0xfa, 0xc4, 0x66, 0x07, 0x44, 0x0e, + 0x8f, 0x00, 0xb0, 0x2b, 0x31, 0x07, 0x0f, 0x00, 0x1c, 0x72, 0x00, 0x70, 0xf8, 0x37, 0xe5, 0x81, + 0xff, 0x89, 0x08, 0xf2, 0x71, 0x80, 0x20, 0xfe, 0x2b, 0xf0, 0x5f, 0xc0, 0x38, 0xc8, 0xa5, 0x60, + 0xc3, 0x00, 0xc7, 0xf9, 0xaf, 0x81, 0x2d, 0x04, 0x34, 0x40, 0xe1, 0x98, 0x47, 0x68, 0x04, 0x92, + 0xab, 0xc0, 0x7e, 0xb7, 0xf7, 0x39, 0x03, 0x85, 0x8e, 0x24, 0xf1, 0xc0, 0x7f, 0xf5, 0x78, 0x0f, + 0x53, 0xb4, 0xbc, 0x1f, 0xb8, 0x1a, 0x0c, 0x61, 0xc5, 0x82, 0xab, 0xc0, 0x3e, 0xa3, 0xa2, 0xfc, + 0x07, 0x46, 0x09, 0x60, 0x19, 0x8f, 0x80, 0xec, 0x38, 0x08, 0x52, 0x6c, 0xb8, 0xdc, 0x28, 0x7c, + 0x10, 0x2a, 0x5f, 0x0f, 0xfc, 0x5a, 0x01, 0x05, 0x1a, 0x8e, 0x02, 0x02, 0x1d, 0x1f, 0x81, 0xa8, + 0xbe, 0x13, 0xf8, 0x52, 0x2c, 0x8c, 0x62, 0x77, 0x42, 0x11, 0x40, 0xe0, 0xca, 0x93, 0x8e, 0x03, + 0x8a, 0x30, 0x10, 0x48, 0x54, 0x03, 0x04, 0xbb, 0x2c, 0x00, 0x0c, 0x64, 0x80, 0xe4, 0x0e, 0x88, + 0x38, 0x7c, 0x10, 0x04, 0x09, 0x48, 0x83, 0xac, 0x1b, 0x18, 0xf3, 0x44, 0xc1, 0xca, 0x1d, 0x15, + 0x40, 0x8e, 0x05, 0x02, 0x20, 0xe6, 0x24, 0x12, 0x8c, 0x8b, 0x05, 0x21, 0x07, 0x24, 0x14, 0x08, + 0x73, 0x80, 0x19, 0x78, 0x43, 0xb2, 0xff, 0x15, 0x30, 0xc4, 0x01, 0x26, 0x8f, 0x14, 0x61, 0xa9, + 0x8a, 0x09, 0x10, 0x02, 0x12, 0x1c, 0x80, 0x84, 0xaf, 0x10, 0x71, 0xaa, 0xc4, 0x00, 0x3b, 0x04, + 0xea, 0x24, 0x48, 0x1c, 0xbd, 0x8f, 0xf8, 0x00, 0x67, 0xf0, 0x09, 0x40, 0x20, 0x61, 0x00, 0xe4, + 0xf6, 0x07, 0x4b, 0xc1, 0x1f, 0x07, 0x14, 0x40, 0x1c, 0x9d, 0x66, 0x79, 0x24, 0xc6, 0xa0, 0x0e, + 0x32, 0x51, 0xfa, 0xce, 0xe7, 0x50, 0x07, 0x1c, 0x80, 0x30, 0x58, 0x0e, 0xa2, 0xcc, 0xa0, 0x19, + 0x00, 0x71, 0x42, 0x13, 0x27, 0x40, 0xf5, 0x45, 0x41, 0xc5, 0x08, 0xb0, 0x80, 0xc6, 0x18, 0xf2, + 0x28, 0x04, 0x83, 0xe8, 0x58, 0x10, 0x30, 0xc2, 0x2c, 0x40, 0x91, 0x89, 0x3c, 0x88, 0x62, 0x21, + 0xd2, 0xff, 0x03, 0x87, 0xc8, 0x12, 0x19, 0x08, 0x39, 0x3e, 0x83, 0xb2, 0x4a, 0x0e, 0xa2, 0x0d, + 0xc0, 0xe0, 0x50, 0x06, 0xa7, 0xe8, 0x2c, 0x94, 0xc2, 0x09, 0x50, 0x8c, 0xce, 0x20, 0x34, 0x70, + 0x71, 0x41, 0x3e, 0x85, 0xe2, 0xe0, 0x41, 0x38, 0x1e, 0x28, 0x3c, 0x19, 0xc8, 0x70, 0x4f, 0xc1, + 0xdc, 0xe0, 0x74, 0x01, 0xd8, 0xc6, 0x24, 0x00, 0x82, 0x81, 0x7c, 0x12, 0xa6, 0x7e, 0x10, 0x28, + 0xd8, 0x22, 0x00, 0xe3, 0xfc, 0x34, 0x53, 0x00, 0x23, 0x1c, 0x04, 0x44, 0x0e, 0x50, 0x10, 0xeb, + 0x17, 0xca, 0x1c, 0x07, 0x20, +}; +const uint8_t* const _I_DolphinMafia_115x62[] = {_I_DolphinMafia_115x62_0}; + +const uint8_t _I_DolphinNice_96x59_0[] = { + 0x01, 0x00, 0x8a, 0x01, 0x00, 0x37, 0xfa, 0x3e, 0x0a, 0x8f, 0x04, 0x04, 0x02, 0x20, 0xb7, 0x8c, + 0x00, 0x86, 0x1c, 0x0b, 0x78, 0x20, 0x08, 0x66, 0x00, 0xb7, 0x81, 0x00, 0x86, 0x80, 0x0b, 0x71, + 0x61, 0x60, 0x01, 0x4c, 0x07, 0x41, 0xe3, 0x07, 0xd0, 0x4e, 0x40, 0xb8, 0x1f, 0x90, 0x00, 0xe4, + 0x00, 0xba, 0x88, 0x01, 0x0e, 0x10, 0x0a, 0x48, 0xf9, 0x6c, 0xbe, 0x10, 0x70, 0x82, 0x78, 0x3c, + 0x15, 0x82, 0x18, 0xc2, 0x21, 0x00, 0xb4, 0x02, 0x0e, 0xbc, 0x86, 0x30, 0x48, 0x80, 0xd1, 0x05, + 0x03, 0x78, 0x82, 0xc0, 0x3e, 0x52, 0x32, 0x63, 0x70, 0x20, 0x70, 0x09, 0xd4, 0x98, 0xb0, 0xf0, + 0x60, 0x58, 0xc9, 0xce, 0x12, 0x0b, 0xbf, 0xd4, 0x9d, 0x28, 0x9e, 0x24, 0xa9, 0x82, 0xda, 0x24, + 0x2d, 0x10, 0x00, 0xfd, 0x2a, 0x60, 0xb4, 0x85, 0x4e, 0x00, 0x85, 0xf8, 0xd4, 0x82, 0xd2, 0x09, + 0xc0, 0x12, 0x14, 0x12, 0xad, 0x81, 0x29, 0xa8, 0x90, 0xf5, 0x01, 0x75, 0x80, 0x46, 0x00, 0xa5, + 0x50, 0x0b, 0x90, 0x1c, 0x41, 0x63, 0x60, 0x05, 0x96, 0xc0, 0x2e, 0x52, 0x44, 0x79, 0x60, 0x06, + 0x05, 0x50, 0x05, 0x94, 0x89, 0x88, 0x63, 0x02, 0x98, 0x02, 0xc7, 0xc1, 0x21, 0x6a, 0x98, 0xa0, + 0x62, 0x11, 0x00, 0x58, 0xc6, 0x02, 0xe2, 0xb8, 0x21, 0x80, 0xc3, 0x05, 0x02, 0x38, 0x11, 0x78, + 0xa5, 0x0b, 0x01, 0x81, 0x5a, 0x88, 0x2c, 0x60, 0x40, 0xb1, 0xc0, 0x27, 0x0a, 0xfc, 0x0f, 0x28, + 0x04, 0x06, 0x50, 0x05, 0x18, 0xa9, 0x94, 0xc1, 0x67, 0x48, 0x02, 0x8c, 0xb8, 0x16, 0xf8, 0x80, + 0x28, 0xd6, 0x16, 0x86, 0x0b, 0x38, 0x40, 0xd4, 0x76, 0x0c, 0xd4, 0x05, 0x94, 0x10, 0x9a, 0x34, + 0x01, 0x82, 0x1f, 0x06, 0x05, 0x02, 0x98, 0x01, 0x47, 0x54, 0x18, 0x35, 0xc8, 0xff, 0x20, 0x3c, + 0x00, 0x58, 0xd5, 0x6a, 0xa0, 0xb3, 0x81, 0xa3, 0x0a, 0x0f, 0x80, 0xd5, 0xea, 0x81, 0x67, 0x07, + 0x46, 0x14, 0xe3, 0xe1, 0x55, 0x18, 0x18, 0x2c, 0x51, 0x85, 0xc0, 0xef, 0x85, 0x8c, 0x0c, 0x30, + 0xf4, 0x61, 0x40, 0x2d, 0x46, 0xb4, 0x05, 0x8b, 0x04, 0xb0, 0x15, 0x40, 0x5a, 0x50, 0x23, 0xe6, + 0x01, 0x02, 0x8c, 0xa8, 0x2e, 0xb1, 0xe5, 0x40, 0x81, 0x46, 0x6a, 0x17, 0x59, 0xeb, 0xe4, 0xa8, + 0x11, 0xa0, 0x5a, 0x68, 0x27, 0x4e, 0xd3, 0x59, 0xad, 0x82, 0xfa, 0xed, 0x2a, 0x04, 0x28, 0x2e, + 0xb7, 0xa7, 0x69, 0xc3, 0x42, 0xeb, 0xf5, 0x1f, 0x09, 0x4c, 0x42, 0xed, 0xea, 0x01, 0x8c, 0x06, + 0x41, 0x05, 0x0b, 0xbc, 0x02, 0x0d, 0x80, 0x83, 0x05, 0xe2, 0x11, 0x40, 0x0b, 0xb7, 0x14, 0x06, + 0x33, 0x0c, 0x83, 0x89, 0x02, 0xe3, 0xca, 0x3d, 0x95, 0x01, 0xe2, 0x21, 0x74, 0xc2, 0x81, 0x0b, + 0x0e, 0x17, 0x6c, 0x10, 0x10, 0xaf, 0x09, 0xe2, 0x0b, 0xbb, 0xd0, 0x42, 0xeb, 0x02, +}; +const uint8_t* const _I_DolphinNice_96x59[] = {_I_DolphinNice_96x59_0}; + +const uint8_t _I_DolphinWait_61x59_0[] = { + 0x01, 0x00, 0x56, 0x01, 0x00, 0x17, 0xfa, 0x1e, 0x06, 0x4f, 0x84, 0x06, 0xe0, 0x07, 0x48, 0x64, + 0x03, 0x01, 0x01, 0x03, 0x9c, 0x0c, 0x04, 0x30, 0x60, 0x31, 0x70, 0x00, 0x65, 0x08, 0x01, 0x94, + 0xc0, 0x06, 0x51, 0x00, 0x5b, 0x48, 0x00, 0x65, 0x04, 0x01, 0x95, 0x00, 0x82, 0xd8, 0x00, 0x19, + 0x40, 0x7e, 0x00, 0x75, 0x1f, 0x88, 0xe0, 0x88, 0x02, 0x1a, 0x1f, 0x94, 0x14, 0x0e, 0xbf, 0x98, + 0x58, 0x5c, 0x42, 0x45, 0x00, 0x9e, 0x99, 0x87, 0x01, 0x02, 0x11, 0x94, 0xf2, 0x2e, 0x03, 0x18, + 0x39, 0x28, 0x70, 0x1f, 0xc0, 0x3e, 0x42, 0x00, 0xe5, 0x80, 0xff, 0xdf, 0xc0, 0xe5, 0xf8, 0x85, + 0xd8, 0x10, 0x27, 0x40, 0xf9, 0xc2, 0x63, 0x88, 0x12, 0x82, 0x6a, 0x20, 0x50, 0x41, 0xe9, 0x42, + 0x20, 0x95, 0x48, 0x6e, 0x0c, 0xfa, 0x9a, 0xaf, 0xf9, 0x90, 0xe2, 0x10, 0x2e, 0xac, 0xe0, 0x0e, + 0x98, 0x29, 0x52, 0x11, 0x13, 0x23, 0x15, 0x3e, 0x20, 0x3c, 0x61, 0x40, 0x52, 0xfc, 0x4f, 0xe2, + 0x10, 0x38, 0x68, 0x1c, 0xa0, 0xfc, 0x08, 0xbe, 0x04, 0x1e, 0x5e, 0x01, 0xb9, 0x03, 0xc5, 0x60, + 0x24, 0xf2, 0x84, 0x60, 0x63, 0x40, 0x71, 0x27, 0x9c, 0x0e, 0x2b, 0x04, 0x6c, 0xa4, 0x06, 0x15, + 0x08, 0x6c, 0x99, 0x8c, 0xa6, 0x0f, 0x81, 0x00, 0x0c, 0x08, 0xf0, 0x3c, 0x05, 0x61, 0xc0, 0x40, + 0x86, 0xd0, 0x30, 0x78, 0x80, 0x0c, 0xc6, 0x2b, 0x92, 0x00, 0x0d, 0x51, 0xf0, 0x2d, 0x42, 0x0a, + 0x8e, 0xaa, 0x34, 0x0f, 0x4a, 0x85, 0x55, 0x6e, 0x20, 0xf3, 0xd5, 0x6a, 0x84, 0xa2, 0x66, 0x2a, + 0x05, 0xf7, 0xaa, 0x07, 0x18, 0xaf, 0xfb, 0x7f, 0xea, 0xc1, 0xef, 0xc0, 0xe3, 0xea, 0x80, 0xf8, + 0x27, 0xf0, 0x0a, 0xc0, 0x1c, 0x67, 0xa2, 0xd1, 0xb1, 0xc0, 0x34, 0x00, 0x71, 0x14, 0x8f, 0x00, + 0x98, 0x34, 0x02, 0x69, 0xd0, 0x37, 0x90, 0x16, 0xf1, 0x00, 0x06, 0xe1, 0x84, 0x31, 0x89, 0x14, + 0xe9, 0xdc, 0x40, 0x38, 0xa4, 0xc4, 0x4c, 0x3c, 0x1f, 0x88, 0x8c, 0x5b, 0xc3, 0x01, 0xbc, 0x40, + 0x3f, 0xf0, 0xf6, 0x71, 0x0c, 0x0b, 0xe0, 0x07, 0x3c, 0x0a, 0xf8, 0xa3, 0xf0, 0x03, 0xb8, 0xd8, + 0x80, 0xe8, 0x87, 0x1b, 0xa8, 0x1c, 0x78, 0x1f, 0xf8, 0x0e, 0x7e, 0x01, 0x6a, 0x03, 0x94, 0x0f, + 0xfd, 0xa0, 0x80, 0x7d, 0x49, 0x04, 0x4d, 0x12, 0xc0, 0xfa, 0x83, 0x83, 0xbe, 0x26, 0x8d, 0x02, + 0x05, 0xd5, 0xff, 0xff, 0xeb, 0xe9, 0x31, 0x90, 0x40, 0x80, +}; +const uint8_t* const _I_DolphinWait_61x59[] = {_I_DolphinWait_61x59_0}; + +const uint8_t _I_iButtonDolphinVerySuccess_108x52_0[] = { + 0x01, 0x00, 0xc2, 0x01, 0x00, 0x0f, 0xe2, 0xfe, 0x0d, 0xb8, 0x3e, 0x02, 0x06, 0x0c, 0x9f, 0x00, + 0x08, 0x61, 0x80, 0xd9, 0x8c, 0x00, 0x86, 0x60, 0x0d, 0x98, 0x30, 0x08, 0x6a, 0x00, 0xd9, 0x80, + 0x80, 0x87, 0x40, 0x0c, 0x8c, 0x00, 0x0c, 0xa8, 0x01, 0x12, 0x00, 0x2d, 0x00, 0x22, 0x70, 0x20, + 0x6b, 0xc8, 0x02, 0x26, 0x62, 0x88, 0x80, 0x6c, 0xc9, 0x24, 0x0d, 0x9a, 0x07, 0x17, 0xfe, 0x1d, + 0x68, 0x40, 0x6c, 0xe7, 0x48, 0x04, 0x28, 0x10, 0x34, 0xe8, 0x10, 0xd1, 0x11, 0xc4, 0x01, 0xa5, + 0x04, 0x06, 0x96, 0xa0, 0xa6, 0x24, 0xc2, 0x88, 0x17, 0x88, 0x1a, 0x7d, 0x43, 0x78, 0x82, 0x4a, + 0x40, 0x03, 0x20, 0xb0, 0xff, 0x20, 0x16, 0xa3, 0xb2, 0x48, 0x03, 0xe4, 0x0d, 0x1f, 0xfc, 0x06, + 0x3a, 0x0d, 0x4a, 0x00, 0x34, 0xf8, 0x00, 0xd1, 0x37, 0x0f, 0x82, 0x9e, 0x95, 0x58, 0x17, 0x83, + 0xff, 0x81, 0x1b, 0x0f, 0xf1, 0xfe, 0x71, 0xe0, 0x69, 0x7c, 0x3f, 0xe0, 0x82, 0xff, 0xcf, 0xc0, + 0x85, 0x61, 0x80, 0x43, 0xb0, 0x5f, 0xa8, 0x79, 0xdc, 0x81, 0xa5, 0x70, 0xc0, 0x68, 0x3c, 0x10, + 0x1a, 0x17, 0xd5, 0x28, 0x42, 0xd1, 0x8f, 0x84, 0x46, 0x83, 0xb0, 0x8e, 0x40, 0x34, 0x5f, 0xa8, + 0x38, 0x34, 0x45, 0xa2, 0x0d, 0x18, 0x04, 0x9b, 0x50, 0x03, 0x1a, 0x14, 0x35, 0x36, 0x5f, 0x8f, + 0xf8, 0xb8, 0xa4, 0x19, 0x40, 0x18, 0xe8, 0xa0, 0xca, 0x22, 0xfe, 0x7f, 0xc4, 0x05, 0x20, 0xa5, + 0x80, 0xc6, 0x82, 0xcb, 0x3f, 0xf3, 0x44, 0xfc, 0x12, 0x40, 0x18, 0xe8, 0x51, 0x82, 0x52, 0x28, + 0xfc, 0x38, 0x0a, 0x3e, 0x48, 0x98, 0x6c, 0x8f, 0x43, 0x00, 0xe0, 0x63, 0xe0, 0x62, 0xe2, 0x91, + 0x90, 0x0a, 0x02, 0x0d, 0x2f, 0x82, 0x50, 0x41, 0xa3, 0x80, 0x90, 0x41, 0x04, 0xc3, 0x01, 0xc0, + 0x83, 0x46, 0x71, 0x30, 0x06, 0x95, 0x82, 0x21, 0x02, 0x6e, 0x88, 0x6c, 0x43, 0x83, 0x1f, 0x2f, + 0x88, 0x34, 0x62, 0x00, 0xd1, 0x15, 0x08, 0x2c, 0x60, 0xcc, 0x51, 0x0f, 0x08, 0xcc, 0x81, 0xa2, + 0x12, 0x10, 0x68, 0xc6, 0x3f, 0x06, 0xc2, 0x06, 0x8e, 0x02, 0x16, 0x41, 0x20, 0x10, 0xf8, 0x01, + 0x85, 0x00, 0x19, 0x0d, 0x82, 0x18, 0x07, 0x20, 0x81, 0x00, 0x0c, 0x9c, 0x31, 0x08, 0x42, 0x74, + 0x81, 0xab, 0x80, 0x03, 0x0c, 0x32, 0x11, 0x0b, 0x06, 0xb9, 0xc0, 0x43, 0xa3, 0x10, 0x8b, 0x83, + 0x5c, 0xe0, 0x20, 0x81, 0xc8, 0x26, 0x49, 0x4c, 0x40, 0x02, 0x86, 0x0a, 0xc5, 0x22, 0x32, 0x50, + 0x6b, 0x93, 0x86, 0xc0, 0x0d, 0x19, 0x18, 0x35, 0x8c, 0x84, 0x79, 0x1a, 0x84, 0x84, 0x1a, 0xdf, + 0xc2, 0xe0, 0x8a, 0xc7, 0x51, 0x22, 0x06, 0xb5, 0x5e, 0x3f, 0x00, 0x77, 0x0d, 0x60, 0x36, 0xfa, + 0xa9, 0xd7, 0x00, 0x08, 0x3a, 0xc9, 0x02, 0x48, 0xc0, 0x05, 0x54, 0xba, 0x98, 0x8a, 0xa8, 0xf1, + 0x20, 0x6a, 0x6a, 0x3d, 0x43, 0x61, 0x80, 0x4a, 0x81, 0xaf, 0x40, 0xea, 0x8d, 0x86, 0x01, 0x56, + 0x06, 0x93, 0x60, 0x80, 0x05, 0xea, 0x01, 0x94, 0xac, 0x1b, 0x11, 0x80, 0x19, 0x45, 0x41, 0x44, + 0x0d, 0x58, 0x33, 0x18, 0xa1, 0x4f, 0xf3, 0x06, 0x1f, 0x01, 0x76, 0x58, 0x00, 0xd9, 0x83, 0x52, + 0x7c, 0x11, 0x38, 0x51, 0x40, 0x80, +}; +const uint8_t* const _I_iButtonDolphinVerySuccess_108x52[] = { + _I_iButtonDolphinVerySuccess_108x52_0}; + +const uint8_t _I_iButtonKey_49x44_0[] = { + 0x01, 0x00, 0xb4, 0x00, 0x00, 0x24, 0xfc, 0x0a, 0x9c, 0x0e, 0x00, 0x19, 0x26, 0x18, 0x00, 0x32, + 0x43, 0x20, 0x10, 0x10, 0x31, 0xc0, 0x80, 0xc9, 0x80, 0x02, 0x08, 0x18, 0xec, 0x00, 0x21, 0x03, + 0x1c, 0x40, 0x1e, 0x22, 0x15, 0xa0, 0x08, 0x56, 0x40, 0x06, 0x30, 0xc0, 0x85, 0x84, 0x86, 0x40, + 0x21, 0x84, 0x10, 0xcc, 0x04, 0x30, 0x40, 0x31, 0x02, 0x88, 0x3a, 0x20, 0x01, 0x83, 0x0d, 0x94, + 0x06, 0x26, 0x03, 0xf8, 0x43, 0xc5, 0xe9, 0x0c, 0x11, 0x08, 0xbc, 0xe0, 0x64, 0x21, 0x23, 0x09, + 0x38, 0x80, 0x22, 0x28, 0x20, 0x58, 0x99, 0xc4, 0x50, 0x41, 0xe1, 0xc0, 0x60, 0xcc, 0xab, 0x47, + 0x21, 0xa6, 0x02, 0x9e, 0x06, 0x22, 0x70, 0xf0, 0x00, 0xcb, 0x40, 0x03, 0x18, 0xb0, 0x78, 0x14, + 0xe0, 0x32, 0x58, 0x28, 0xa5, 0x84, 0xd0, 0x51, 0x80, 0xc9, 0x30, 0x06, 0xae, 0x62, 0x84, 0x06, + 0x48, 0x64, 0x88, 0x0c, 0x90, 0x29, 0x08, 0x19, 0x30, 0x31, 0x13, 0x71, 0xb8, 0xc4, 0xea, 0x70, + 0x6b, 0xc5, 0x01, 0x4a, 0x7f, 0xc8, 0x7c, 0x81, 0x4a, 0x77, 0x8a, 0xac, 0x45, 0x4a, 0x7f, 0x08, + 0x54, 0x39, 0x4a, 0x7e, 0x0e, 0xa9, 0xf0, 0xcb, 0xe3, 0x7f, 0x6e, 0x22, 0x5c, 0x59, 0x44, 0x00, + 0x28, 0x7a, 0xd4, 0x40, 0x07, 0xf0, 0x02, 0xa0, +}; +const uint8_t* const _I_iButtonKey_49x44[] = {_I_iButtonKey_49x44_0}; + +const Icon I_Certification1_103x56 = { + .width = 103, + .height = 56, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Certification1_103x56}; +const Icon I_Certification2_98x33 = { + .width = 98, + .height = 33, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Certification2_98x33}; +const Icon A_Levelup1_128x64 = + {.width = 128, .height = 64, .frame_count = 11, .frame_rate = 2, .frames = _A_Levelup1_128x64}; +const Icon A_Levelup2_128x64 = + {.width = 128, .height = 64, .frame_count = 11, .frame_rate = 2, .frames = _A_Levelup2_128x64}; +const Icon I_125_10px = + {.width = 10, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_125_10px}; +const Icon I_Apps_10px = + {.width = 10, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_Apps_10px}; +const Icon I_Nfc_10px = + {.width = 10, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_Nfc_10px}; +const Icon I_back_10px = + {.width = 10, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_back_10px}; +const Icon I_badusb_10px = + {.width = 10, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_badusb_10px}; +const Icon I_dir_10px = + {.width = 10, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_dir_10px}; +const Icon I_ibutt_10px = + {.width = 10, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_ibutt_10px}; +const Icon I_ir_10px = + {.width = 10, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_ir_10px}; +const Icon I_keyboard_10px = + {.width = 10, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_keyboard_10px}; +const Icon I_loading_10px = + {.width = 10, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_loading_10px}; +const Icon I_music_10px = + {.width = 10, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_music_10px}; +const Icon I_sub1_10px = + {.width = 10, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_sub1_10px}; +const Icon I_u2f_10px = + {.width = 10, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_u2f_10px}; +const Icon I_unknown_10px = + {.width = 10, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_unknown_10px}; +const Icon I_update_10px = + {.width = 10, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_update_10px}; +const Icon I_BLE_Pairing_128x64 = { + .width = 128, + .height = 64, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_BLE_Pairing_128x64}; +const Icon I_Ble_connected_15x15 = { + .width = 15, + .height = 15, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Ble_connected_15x15}; +const Icon I_Ble_disconnected_15x15 = { + .width = 15, + .height = 15, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Ble_disconnected_15x15}; +const Icon I_Button_18x18 = + {.width = 18, .height = 18, .frame_count = 1, .frame_rate = 0, .frames = _I_Button_18x18}; +const Icon I_Circles_47x47 = + {.width = 47, .height = 47, .frame_count = 1, .frame_rate = 0, .frames = _I_Circles_47x47}; +const Icon I_Left_mouse_icon_9x9 = + {.width = 9, .height = 9, .frame_count = 1, .frame_rate = 0, .frames = _I_Left_mouse_icon_9x9}; +const Icon I_Ok_btn_9x9 = + {.width = 9, .height = 9, .frame_count = 1, .frame_rate = 0, .frames = _I_Ok_btn_9x9}; +const Icon I_Ok_btn_pressed_13x13 = { + .width = 13, + .height = 13, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Ok_btn_pressed_13x13}; +const Icon I_Pressed_Button_13x13 = { + .width = 13, + .height = 13, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Pressed_Button_13x13}; +const Icon I_Right_mouse_icon_9x9 = { + .width = 9, + .height = 9, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Right_mouse_icon_9x9}; +const Icon I_Space_65x18 = + {.width = 65, .height = 18, .frame_count = 1, .frame_rate = 0, .frames = _I_Space_65x18}; +const Icon I_Voldwn_6x6 = + {.width = 6, .height = 6, .frame_count = 1, .frame_rate = 0, .frames = _I_Voldwn_6x6}; +const Icon I_Volup_8x6 = + {.width = 8, .height = 6, .frame_count = 1, .frame_rate = 0, .frames = _I_Volup_8x6}; +const Icon I_Clock_18x18 = + {.width = 18, .height = 18, .frame_count = 1, .frame_rate = 0, .frames = _I_Clock_18x18}; +const Icon I_Error_18x18 = + {.width = 18, .height = 18, .frame_count = 1, .frame_rate = 0, .frames = _I_Error_18x18}; +const Icon I_EviSmile1_18x21 = + {.width = 18, .height = 21, .frame_count = 1, .frame_rate = 0, .frames = _I_EviSmile1_18x21}; +const Icon I_EviSmile2_18x21 = + {.width = 18, .height = 21, .frame_count = 1, .frame_rate = 0, .frames = _I_EviSmile2_18x21}; +const Icon I_EviWaiting1_18x21 = + {.width = 18, .height = 21, .frame_count = 1, .frame_rate = 0, .frames = _I_EviWaiting1_18x21}; +const Icon I_EviWaiting2_18x21 = + {.width = 18, .height = 21, .frame_count = 1, .frame_rate = 0, .frames = _I_EviWaiting2_18x21}; +const Icon I_Percent_10x14 = + {.width = 10, .height = 14, .frame_count = 1, .frame_rate = 0, .frames = _I_Percent_10x14}; +const Icon I_Smile_18x18 = + {.width = 18, .height = 18, .frame_count = 1, .frame_rate = 0, .frames = _I_Smile_18x18}; +const Icon I_UsbTree_48x22 = + {.width = 48, .height = 22, .frame_count = 1, .frame_rate = 0, .frames = _I_UsbTree_48x22}; +const Icon I_ActiveConnection_50x64 = { + .width = 50, + .height = 64, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_ActiveConnection_50x64}; +const Icon I_ButtonCenter_7x7 = + {.width = 7, .height = 7, .frame_count = 1, .frame_rate = 0, .frames = _I_ButtonCenter_7x7}; +const Icon I_ButtonDown_7x4 = + {.width = 7, .height = 4, .frame_count = 1, .frame_rate = 0, .frames = _I_ButtonDown_7x4}; +const Icon I_ButtonLeftSmall_3x5 = + {.width = 3, .height = 5, .frame_count = 1, .frame_rate = 0, .frames = _I_ButtonLeftSmall_3x5}; +const Icon I_ButtonLeft_4x7 = + {.width = 4, .height = 7, .frame_count = 1, .frame_rate = 0, .frames = _I_ButtonLeft_4x7}; +const Icon I_ButtonRightSmall_3x5 = { + .width = 3, + .height = 5, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_ButtonRightSmall_3x5}; +const Icon I_ButtonRight_4x7 = + {.width = 4, .height = 7, .frame_count = 1, .frame_rate = 0, .frames = _I_ButtonRight_4x7}; +const Icon I_ButtonUp_7x4 = + {.width = 7, .height = 4, .frame_count = 1, .frame_rate = 0, .frames = _I_ButtonUp_7x4}; +const Icon I_DFU_128x50 = + {.width = 128, .height = 50, .frame_count = 1, .frame_rate = 0, .frames = _I_DFU_128x50}; +const Icon I_Warning_30x23 = + {.width = 30, .height = 23, .frame_count = 1, .frame_rate = 0, .frames = _I_Warning_30x23}; +const Icon A_Loading_24 = + {.width = 24, .height = 24, .frame_count = 7, .frame_rate = 5, .frames = _A_Loading_24}; +const Icon A_Round_loader_8x8 = + {.width = 8, .height = 8, .frame_count = 5, .frame_rate = 2, .frames = _A_Round_loader_8x8}; +const Icon I_DolphinCommon_56x48 = { + .width = 56, + .height = 48, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_DolphinCommon_56x48}; +const Icon I_ArrowDownEmpty_14x15 = { + .width = 14, + .height = 15, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_ArrowDownEmpty_14x15}; +const Icon I_ArrowDownFilled_14x15 = { + .width = 14, + .height = 15, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_ArrowDownFilled_14x15}; +const Icon I_ArrowUpEmpty_14x15 = { + .width = 14, + .height = 15, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_ArrowUpEmpty_14x15}; +const Icon I_ArrowUpFilled_14x15 = { + .width = 14, + .height = 15, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_ArrowUpFilled_14x15}; +const Icon I_DolphinReadingSuccess_59x63 = { + .width = 59, + .height = 63, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_DolphinReadingSuccess_59x63}; +const Icon I_Down_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Down_25x27}; +const Icon I_Down_hvr_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Down_hvr_25x27}; +const Icon I_InfraredArrowDown_4x8 = { + .width = 8, + .height = 4, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_InfraredArrowDown_4x8}; +const Icon I_InfraredArrowUp_4x8 = + {.width = 8, .height = 4, .frame_count = 1, .frame_rate = 0, .frames = _I_InfraredArrowUp_4x8}; +const Icon I_InfraredLearnShort_128x31 = { + .width = 128, + .height = 31, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_InfraredLearnShort_128x31}; +const Icon I_Mode_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Mode_25x27}; +const Icon I_Mode_hvr_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Mode_hvr_25x27}; +const Icon I_Mute_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Mute_25x27}; +const Icon I_Mute_hvr_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Mute_hvr_25x27}; +const Icon I_Power_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Power_25x27}; +const Icon I_Power_hvr_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Power_hvr_25x27}; +const Icon I_Rotate_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Rotate_25x27}; +const Icon I_Rotate_hvr_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Rotate_hvr_25x27}; +const Icon I_Swing_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Swing_25x27}; +const Icon I_Swing_hvr_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Swing_hvr_25x27}; +const Icon I_Timer_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Timer_25x27}; +const Icon I_Timer_hvr_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Timer_hvr_25x27}; +const Icon I_Up_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Up_25x27}; +const Icon I_Up_hvr_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Up_hvr_25x27}; +const Icon I_Vol_down_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Vol_down_25x27}; +const Icon I_Vol_down_hvr_25x27 = { + .width = 25, + .height = 27, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Vol_down_hvr_25x27}; +const Icon I_Vol_up_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Vol_up_25x27}; +const Icon I_Vol_up_hvr_25x27 = + {.width = 25, .height = 27, .frame_count = 1, .frame_rate = 0, .frames = _I_Vol_up_hvr_25x27}; +const Icon I_DoorLeft_70x55 = + {.width = 70, .height = 55, .frame_count = 1, .frame_rate = 0, .frames = _I_DoorLeft_70x55}; +const Icon I_DoorRight_70x55 = + {.width = 70, .height = 55, .frame_count = 1, .frame_rate = 0, .frames = _I_DoorRight_70x55}; +const Icon I_SmallArrowDown_3x5 = + {.width = 5, .height = 3, .frame_count = 1, .frame_rate = 0, .frames = _I_SmallArrowDown_3x5}; +const Icon I_SmallArrowDown_4x7 = + {.width = 7, .height = 4, .frame_count = 1, .frame_rate = 0, .frames = _I_SmallArrowDown_4x7}; +const Icon I_SmallArrowUp_3x5 = + {.width = 5, .height = 3, .frame_count = 1, .frame_rate = 0, .frames = _I_SmallArrowUp_3x5}; +const Icon I_SmallArrowUp_4x7 = + {.width = 7, .height = 4, .frame_count = 1, .frame_rate = 0, .frames = _I_SmallArrowUp_4x7}; +const Icon I_WarningDolphin_45x42 = { + .width = 45, + .height = 42, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_WarningDolphin_45x42}; +const Icon I_KeyBackspaceSelected_16x9 = { + .width = 16, + .height = 9, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_KeyBackspaceSelected_16x9}; +const Icon I_KeyBackspace_16x9 = + {.width = 16, .height = 9, .frame_count = 1, .frame_rate = 0, .frames = _I_KeyBackspace_16x9}; +const Icon I_KeySaveSelected_24x11 = { + .width = 24, + .height = 11, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_KeySaveSelected_24x11}; +const Icon I_KeySave_24x11 = + {.width = 24, .height = 11, .frame_count = 1, .frame_rate = 0, .frames = _I_KeySave_24x11}; +const Icon A_125khz_14 = + {.width = 14, .height = 14, .frame_count = 4, .frame_rate = 3, .frames = _A_125khz_14}; +const Icon A_BadUsb_14 = + {.width = 14, .height = 14, .frame_count = 11, .frame_rate = 3, .frames = _A_BadUsb_14}; +const Icon A_Clock_14 = + {.width = 14, .height = 14, .frame_count = 8, .frame_rate = 3, .frames = _A_Clock_14}; +const Icon A_Debug_14 = + {.width = 14, .height = 14, .frame_count = 4, .frame_rate = 3, .frames = _A_Debug_14}; +const Icon A_FileManager_14 = + {.width = 14, .height = 14, .frame_count = 10, .frame_rate = 3, .frames = _A_FileManager_14}; +const Icon A_GPIO_14 = + {.width = 14, .height = 14, .frame_count = 8, .frame_rate = 3, .frames = _A_GPIO_14}; +const Icon A_Infrared_14 = + {.width = 14, .height = 14, .frame_count = 6, .frame_rate = 3, .frames = _A_Infrared_14}; +const Icon A_NFC_14 = + {.width = 14, .height = 14, .frame_count = 4, .frame_rate = 3, .frames = _A_NFC_14}; +const Icon A_Plugins_14 = + {.width = 14, .height = 14, .frame_count = 9, .frame_rate = 3, .frames = _A_Plugins_14}; +const Icon A_Settings_14 = + {.width = 14, .height = 14, .frame_count = 10, .frame_rate = 3, .frames = _A_Settings_14}; +const Icon A_Sub1ghz_14 = + {.width = 14, .height = 14, .frame_count = 6, .frame_rate = 3, .frames = _A_Sub1ghz_14}; +const Icon A_U2F_14 = + {.width = 14, .height = 14, .frame_count = 4, .frame_rate = 3, .frames = _A_U2F_14}; +const Icon A_UniRFRemix_14 = + {.width = 14, .height = 14, .frame_count = 8, .frame_rate = 4, .frames = _A_UniRFRemix_14}; +const Icon A_iButton_14 = + {.width = 14, .height = 14, .frame_count = 7, .frame_rate = 3, .frames = _A_iButton_14}; +const Icon I_ArrowC_1_36x36 = + {.width = 36, .height = 36, .frame_count = 1, .frame_rate = 0, .frames = _I_ArrowC_1_36x36}; +const Icon I_Detailed_chip_17x13 = { + .width = 17, + .height = 13, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Detailed_chip_17x13}; +const Icon I_Keychain_39x36 = + {.width = 39, .height = 36, .frame_count = 1, .frame_rate = 0, .frames = _I_Keychain_39x36}; +const Icon I_Medium_chip_22x21 = + {.width = 22, .height = 21, .frame_count = 1, .frame_rate = 0, .frames = _I_Medium_chip_22x21}; +const Icon I_Modern_reader_18x34 = { + .width = 18, + .height = 34, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Modern_reader_18x34}; +const Icon I_Move_flipper_26x39 = { + .width = 26, + .height = 39, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Move_flipper_26x39}; +const Icon I_NFC_dolphin_emulation_47x61 = { + .width = 47, + .height = 61, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_NFC_dolphin_emulation_47x61}; +const Icon I_NFC_manual_60x50 = + {.width = 60, .height = 50, .frame_count = 1, .frame_rate = 0, .frames = _I_NFC_manual_60x50}; +const Icon I_Release_arrow_18x15 = { + .width = 18, + .height = 15, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Release_arrow_18x15}; +const Icon I_Restoring_38x32 = + {.width = 38, .height = 32, .frame_count = 1, .frame_rate = 0, .frames = _I_Restoring_38x32}; +const Icon I_Tap_reader_36x38 = + {.width = 36, .height = 38, .frame_count = 1, .frame_rate = 0, .frames = _I_Tap_reader_36x38}; +const Icon I_Pin_arrow_down_7x9 = + {.width = 7, .height = 9, .frame_count = 1, .frame_rate = 0, .frames = _I_Pin_arrow_down_7x9}; +const Icon I_Pin_arrow_left_9x7 = + {.width = 9, .height = 7, .frame_count = 1, .frame_rate = 0, .frames = _I_Pin_arrow_left_9x7}; +const Icon I_Pin_arrow_right_9x7 = + {.width = 9, .height = 7, .frame_count = 1, .frame_rate = 0, .frames = _I_Pin_arrow_right_9x7}; +const Icon I_Pin_arrow_up_7x9 = + {.width = 7, .height = 9, .frame_count = 1, .frame_rate = 0, .frames = _I_Pin_arrow_up_7x9}; +const Icon I_Pin_attention_dpad_29x29 = { + .width = 29, + .height = 29, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Pin_attention_dpad_29x29}; +const Icon I_Pin_back_arrow_10x8 = { + .width = 10, + .height = 8, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Pin_back_arrow_10x8}; +const Icon I_Pin_back_full_40x8 = + {.width = 40, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_Pin_back_full_40x8}; +const Icon I_Pin_cell_13x13 = + {.width = 13, .height = 13, .frame_count = 1, .frame_rate = 0, .frames = _I_Pin_cell_13x13}; +const Icon I_Pin_pointer_5x3 = + {.width = 5, .height = 3, .frame_count = 1, .frame_rate = 0, .frames = _I_Pin_pointer_5x3}; +const Icon I_Pin_star_7x7 = + {.width = 7, .height = 7, .frame_count = 1, .frame_rate = 0, .frames = _I_Pin_star_7x7}; +const Icon I_passport_bad1_46x49 = { + .width = 46, + .height = 49, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_passport_bad1_46x49}; +const Icon I_passport_bad2_46x49 = { + .width = 46, + .height = 49, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_passport_bad2_46x49}; +const Icon I_passport_bad3_46x49 = { + .width = 46, + .height = 49, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_passport_bad3_46x49}; +const Icon I_passport_bottom_128x18 = { + .width = 128, + .height = 18, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_passport_bottom_128x18}; +const Icon I_passport_happy1_46x49 = { + .width = 46, + .height = 49, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_passport_happy1_46x49}; +const Icon I_passport_happy2_46x49 = { + .width = 46, + .height = 49, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_passport_happy2_46x49}; +const Icon I_passport_happy3_46x49 = { + .width = 46, + .height = 49, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_passport_happy3_46x49}; +const Icon I_passport_left_6x46 = + {.width = 6, .height = 46, .frame_count = 1, .frame_rate = 0, .frames = _I_passport_left_6x46}; +const Icon I_passport_okay1_46x49 = { + .width = 46, + .height = 49, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_passport_okay1_46x49}; +const Icon I_passport_okay2_46x49 = { + .width = 46, + .height = 49, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_passport_okay2_46x49}; +const Icon I_passport_okay3_46x49 = { + .width = 46, + .height = 49, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_passport_okay3_46x49}; +const Icon I_BatteryBody_52x28 = + {.width = 52, .height = 28, .frame_count = 1, .frame_rate = 0, .frames = _I_BatteryBody_52x28}; +const Icon I_Battery_16x16 = + {.width = 16, .height = 16, .frame_count = 1, .frame_rate = 0, .frames = _I_Battery_16x16}; +const Icon I_FaceCharging_29x14 = { + .width = 29, + .height = 14, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_FaceCharging_29x14}; +const Icon I_FaceConfused_29x14 = { + .width = 29, + .height = 14, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_FaceConfused_29x14}; +const Icon I_FaceNopower_29x14 = + {.width = 29, .height = 14, .frame_count = 1, .frame_rate = 0, .frames = _I_FaceNopower_29x14}; +const Icon I_FaceNormal_29x14 = + {.width = 29, .height = 14, .frame_count = 1, .frame_rate = 0, .frames = _I_FaceNormal_29x14}; +const Icon I_Health_16x16 = + {.width = 16, .height = 16, .frame_count = 1, .frame_rate = 0, .frames = _I_Health_16x16}; +const Icon I_Temperature_16x16 = + {.width = 16, .height = 16, .frame_count = 1, .frame_rate = 0, .frames = _I_Temperature_16x16}; +const Icon I_Unplug_bg_bottom_128x10 = { + .width = 128, + .height = 10, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Unplug_bg_bottom_128x10}; +const Icon I_Unplug_bg_top_128x14 = { + .width = 128, + .height = 14, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Unplug_bg_top_128x14}; +const Icon I_Voltage_16x16 = + {.width = 16, .height = 16, .frame_count = 1, .frame_rate = 0, .frames = _I_Voltage_16x16}; +const Icon I_RFIDDolphinReceive_97x61 = { + .width = 97, + .height = 61, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_RFIDDolphinReceive_97x61}; +const Icon I_RFIDDolphinSend_97x61 = { + .width = 97, + .height = 61, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_RFIDDolphinSend_97x61}; +const Icon I_RFIDDolphinSuccess_108x57 = { + .width = 108, + .height = 57, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_RFIDDolphinSuccess_108x57}; +const Icon I_RFIDSmallChip_14x14 = { + .width = 13, + .height = 13, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_RFIDSmallChip_14x14}; +const Icon I_SDQuestion_35x43 = + {.width = 35, .height = 43, .frame_count = 1, .frame_rate = 0, .frames = _I_SDQuestion_35x43}; +const Icon I_Cry_dolph_55x52 = + {.width = 55, .height = 52, .frame_count = 1, .frame_rate = 0, .frames = _I_Cry_dolph_55x52}; +const Icon I_Alert_9x8 = + {.width = 9, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_Alert_9x8}; +const Icon I_Attention_5x8 = + {.width = 5, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_Attention_5x8}; +const Icon I_Background_128x11 = { + .width = 128, + .height = 11, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Background_128x11}; +const Icon I_Battery_26x8 = + {.width = 26, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_Battery_26x8}; +const Icon I_Bluetooth_Connected_16x8 = { + .width = 16, + .height = 8, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Bluetooth_Connected_16x8}; +const Icon I_Bluetooth_Idle_5x8 = + {.width = 5, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_Bluetooth_Idle_5x8}; +const Icon I_Charging_lightning_9x10 = { + .width = 9, + .height = 10, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Charging_lightning_9x10}; +const Icon I_Charging_lightning_mask_9x10 = { + .width = 9, + .height = 10, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_Charging_lightning_mask_9x10}; +const Icon I_GameMode_11x8 = + {.width = 11, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_GameMode_11x8}; +const Icon I_Hidden_window_9x8 = + {.width = 9, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_Hidden_window_9x8}; +const Icon I_Lock_8x8 = + {.width = 8, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_Lock_8x8}; +const Icon I_SDcardFail_11x8 = + {.width = 11, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_SDcardFail_11x8}; +const Icon I_SDcardMounted_11x8 = + {.width = 11, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_SDcardMounted_11x8}; +const Icon I_Dynamic_9x7 = + {.width = 9, .height = 7, .frame_count = 1, .frame_rate = 0, .frames = _I_Dynamic_9x7}; +const Icon I_Lock_7x8 = + {.width = 7, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_Lock_7x8}; +const Icon I_MHz_25x11 = + {.width = 25, .height = 11, .frame_count = 1, .frame_rate = 0, .frames = _I_MHz_25x11}; +const Icon I_Quest_7x8 = + {.width = 7, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_Quest_7x8}; +const Icon I_Raw_9x7 = + {.width = 9, .height = 7, .frame_count = 1, .frame_rate = 0, .frames = _I_Raw_9x7}; +const Icon I_Scanning_123x52 = + {.width = 123, .height = 52, .frame_count = 1, .frame_rate = 0, .frames = _I_Scanning_123x52}; +const Icon I_Static_9x7 = + {.width = 9, .height = 7, .frame_count = 1, .frame_rate = 0, .frames = _I_Static_9x7}; +const Icon I_Unlock_7x8 = + {.width = 7, .height = 8, .frame_count = 1, .frame_rate = 0, .frames = _I_Unlock_7x8}; +const Icon I_Auth_62x31 = + {.width = 62, .height = 31, .frame_count = 1, .frame_rate = 0, .frames = _I_Auth_62x31}; +const Icon I_Connect_me_62x31 = + {.width = 62, .height = 31, .frame_count = 1, .frame_rate = 0, .frames = _I_Connect_me_62x31}; +const Icon I_Connected_62x31 = + {.width = 62, .height = 31, .frame_count = 1, .frame_rate = 0, .frames = _I_Connected_62x31}; +const Icon I_Drive_112x35 = + {.width = 112, .height = 35, .frame_count = 1, .frame_rate = 0, .frames = _I_Drive_112x35}; +const Icon I_Error_62x31 = + {.width = 62, .height = 31, .frame_count = 1, .frame_rate = 0, .frames = _I_Error_62x31}; +const Icon I_Updating_32x40 = + {.width = 32, .height = 40, .frame_count = 1, .frame_rate = 0, .frames = _I_Updating_32x40}; +const Icon I_DolphinMafia_115x62 = { + .width = 115, + .height = 62, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_DolphinMafia_115x62}; +const Icon I_DolphinNice_96x59 = + {.width = 96, .height = 59, .frame_count = 1, .frame_rate = 0, .frames = _I_DolphinNice_96x59}; +const Icon I_DolphinWait_61x59 = + {.width = 61, .height = 59, .frame_count = 1, .frame_rate = 0, .frames = _I_DolphinWait_61x59}; +const Icon I_iButtonDolphinVerySuccess_108x52 = { + .width = 108, + .height = 52, + .frame_count = 1, + .frame_rate = 0, + .frames = _I_iButtonDolphinVerySuccess_108x52}; +const Icon I_iButtonKey_49x44 = + {.width = 49, .height = 44, .frame_count = 1, .frame_rate = 0, .frames = _I_iButtonKey_49x44}; diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/LICENSE.md b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/LICENSE.md new file mode 100644 index 000000000..aff89d831 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/LICENSE.md @@ -0,0 +1,21 @@ +License + +Copyright (c) 2022 Mikhail Gubenko + +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/Official/DEV_FW/source/xMasterX/flipp_pomodoro/README.md b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/README.md new file mode 100644 index 000000000..aaaadad9b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/README.md @@ -0,0 +1,36 @@ +![Banner Image](docs/generic-screenshot.png) +# Flipp Pomodoro + +Your productivity best friend. Don't let your flipper get borred, let him help you instead. + +## Development + +### Current state and plans + +At the moment following functionality implemented: +![Working Screen](docs/working.png) +![Resting Screen](docs/resting.png) +* Generic pomodoro cycle with two stages (Work: 25 min and rest 5 minutes) +* Automatic and manual phases switch +* Notification(sound, vibration, backlight, led) on stage change. +* Energy Saving workflow + +Will do(if I've got time): +* ~~Publish a .fap package to let anyone download and install the app.~~ +* * Done, now you can [DOWNLOAD application from releases](https://github.com/Th3Un1q3/flipp_pomodoro/releases) +* Configure CI pipeline for automatic releases +* Stats on exit(how many pomodoros complete) +* Background work or restore from last state +* Integration with passport to develop your flipper profile by completing pomodoros +* Configuration of notifications +* Blind mode(no timer updates, just background and notification) for more energy saving + +### Build and Package +Build application +```shell +# For standard(official) firmware +bash tools/build.sh + +# For unleashed firmware +bash tools/build.sh -f unleashed +``` diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/application.fam b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/application.fam new file mode 100644 index 000000000..21e54748b --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/application.fam @@ -0,0 +1,11 @@ +App( + appid="flipp_pomodoro", + name="Flipp Pomodoro", + apptype=FlipperAppType.EXTERNAL, + entry_point="flipp_pomodoro_app", + requires=["gui", "notification", "dolphin"], + stack_size=1 * 1024, + fap_category="Misc_Extra", + fap_icon_assets="images", + fap_icon="flipp_pomodoro_10.png", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/flipp_pomodoro_10.png b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/flipp_pomodoro_10.png new file mode 100644 index 0000000000000000000000000000000000000000..977d16a584f63307ceb028a48f57713402abc520 GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>3HNky4ABT~ zo#4oKK!Jm0_y2m6v$J|4wU)(+%sJ4oYSlc8Nnua6+`q%bGDG3H*bnyJge())*BAQu z?-*^XlzwJ?r0uexhV_H}+Gscene_manager); +}; + +static void flipp_pomodoro_app_tick_event_callback(void *ctx) +{ + furi_assert(ctx); + FlippPomodoroApp *app = ctx; + + scene_manager_handle_custom_event(app->scene_manager, FlippPomodoroAppCustomEventTimerTick); +}; + +static bool flipp_pomodoro_app_custom_event_callback(void *ctx, uint32_t event) +{ + furi_assert(ctx); + FlippPomodoroApp *app = ctx; + + switch (event) + { + case FlippPomodoroAppCustomEventStageSkip: + flipp_pomodoro__toggle_stage(app->state); + return CustomEventConsumed; + case FlippPomodoroAppCustomEventStageComplete: + if (app->state->stage == Work) + { + // REGISTER a deed on work stage complete to get an acheivement + DOLPHIN_DEED(DolphinDeedPluginGameWin); + }; + + flipp_pomodoro__toggle_stage(app->state); + notification_message(app->notification_app, stage_start_notification_sequence_map[app->state->stage]); + return CustomEventConsumed; + default: + break; + } + return scene_manager_handle_custom_event(app->scene_manager, event); +}; + +FlippPomodoroApp *flipp_pomodoro_app_alloc() +{ + FlippPomodoroApp *app = malloc(sizeof(FlippPomodoroApp)); + app->state = flipp_pomodoro__new(); + + app->scene_manager = scene_manager_alloc(&flipp_pomodoro_scene_handlers, app); + app->gui = furi_record_open(RECORD_GUI); + app->notification_app = furi_record_open(RECORD_NOTIFICATION); + + app->view_dispatcher = view_dispatcher_alloc(); + 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, flipp_pomodoro_app_custom_event_callback); + view_dispatcher_set_tick_event_callback(app->view_dispatcher, flipp_pomodoro_app_tick_event_callback, 1000); + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + view_dispatcher_set_navigation_event_callback(app->view_dispatcher, flipp_pomodoro_app_back_event_callback); + + app->timer_view = flipp_pomodoro_view_timer_alloc(); + + view_dispatcher_add_view( + app->view_dispatcher, + FlippPomodoroAppViewTimer, + flipp_pomodoro_view_timer_get_view(app->timer_view)); + + scene_manager_next_scene(app->scene_manager, FlippPomodoroSceneTimer); + + return app; +}; + +void flipp_pomodoro_app_free(FlippPomodoroApp *app) +{ + view_dispatcher_remove_view(app->view_dispatcher, FlippPomodoroAppViewTimer); + view_dispatcher_free(app->view_dispatcher); + scene_manager_free(app->scene_manager); + flipp_pomodoro_view_timer_free(app->timer_view); + flipp_pomodoro__destroy(app->state); + free(app); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); +}; + +int32_t flipp_pomodoro_app(void *p) +{ + UNUSED(p); + FlippPomodoroApp *app = flipp_pomodoro_app_alloc(); + + view_dispatcher_run(app->view_dispatcher); + + flipp_pomodoro_app_free(app); + + return 0; +}; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/flipp_pomodoro_app.h b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/flipp_pomodoro_app.h new file mode 100644 index 000000000..b3e4e9601 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/flipp_pomodoro_app.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include "views/flipp_pomodoro_timer_view.h" + +#include "modules/flipp_pomodoro.h" + +typedef enum +{ + // Reserve first 100 events for button types and indexes, starting from 0 + FlippPomodoroAppCustomEventStageSkip = 100, + FlippPomodoroAppCustomEventStageComplete, // By Expiration + FlippPomodoroAppCustomEventTimerTick, +} FlippPomodoroAppCustomEvent; + +typedef struct +{ + SceneManager *scene_manager; + ViewDispatcher *view_dispatcher; + Gui *gui; + NotificationApp *notification_app; + FlippPomodoroTimerView *timer_view; + FlippPomodoroState *state; +} FlippPomodoroApp; + +typedef enum +{ + FlippPomodoroAppViewTimer, +} FlippPomodoroAppView; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/flipp_pomodoro_app_i.h b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/flipp_pomodoro_app_i.h new file mode 100644 index 000000000..492ef9c2d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/flipp_pomodoro_app_i.h @@ -0,0 +1,31 @@ +#pragma once + +#define FURI_DEBUG 1 + +/** + * Index of dependencies for the main app + */ + +// Platform Imports + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// App resource imports + +#include "helpers/time.h" +#include "helpers/notifications.h" +#include "modules/flipp_pomodoro.h" +#include "flipp_pomodoro_app.h" +#include "scenes/flipp_pomodoro_scene.h" +#include "views/flipp_pomodoro_timer_view.h" + +// Auto-compiled icons +#include "flipp_pomodoro_icons.h" diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/debug.h b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/debug.h new file mode 100644 index 000000000..13b8f2998 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/debug.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +#define TAG "FlippPomodoro" \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/notifications.c b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/notifications.c new file mode 100644 index 000000000..388a3f11d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/notifications.c @@ -0,0 +1,49 @@ +#include + +const NotificationSequence work_start_notification = { + &message_display_backlight_on, + + &message_vibro_on, + + &message_note_b5, + &message_delay_250, + + &message_note_d5, + &message_delay_250, + + &message_sound_off, + &message_vibro_off, + + &message_green_255, + &message_delay_1000, + &message_green_0, + &message_delay_250, + &message_green_255, + &message_delay_1000, + + NULL, +}; + +const NotificationSequence rest_start_notification = { + &message_display_backlight_on, + + &message_vibro_on, + + &message_note_d5, + &message_delay_250, + + &message_note_b5, + &message_delay_250, + + &message_sound_off, + &message_vibro_off, + + &message_red_255, + &message_delay_1000, + &message_red_0, + &message_delay_250, + &message_red_255, + &message_delay_1000, + + NULL, +}; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/notifications.h b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/notifications.h new file mode 100644 index 000000000..a66536bb5 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/notifications.h @@ -0,0 +1,13 @@ +#pragma once + +#include "../modules/flipp_pomodoro.h" +#include + +extern const NotificationSequence work_start_notification; +extern const NotificationSequence rest_start_notification; + +/// @brief Defines a notification sequence that should indicate start of specific pomodoro stage. +const NotificationSequence *stage_start_notification_sequence_map[] = { + [Work] = &work_start_notification, + [Rest] = &rest_start_notification, +}; diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/time.c b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/time.c new file mode 100644 index 000000000..eb8de0024 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/time.c @@ -0,0 +1,21 @@ +#include +#include +#include "time.h" + +const int TIME_SECONDS_IN_MINUTE = 60; +const int TIME_MINUTES_IN_HOUR = 60; + +uint32_t time_now() +{ + return furi_hal_rtc_get_timestamp(); +}; + +TimeDifference time_difference_seconds(uint32_t begin, uint32_t end) +{ + const uint32_t duration_seconds = end - begin; + + uint32_t minutes = (duration_seconds / TIME_MINUTES_IN_HOUR) % TIME_MINUTES_IN_HOUR; + uint32_t seconds = duration_seconds % TIME_SECONDS_IN_MINUTE; + + return (TimeDifference){.total_seconds = duration_seconds, .minutes = minutes, .seconds = seconds}; +}; diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/time.h b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/time.h new file mode 100644 index 000000000..65b7056f9 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/helpers/time.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include + +extern const int TIME_SECONDS_IN_MINUTE; +extern const int TIME_MINUTES_IN_HOUR; + +/// @brief Container for a time period +typedef struct +{ + uint8_t seconds; + uint8_t minutes; + uint32_t total_seconds; +} TimeDifference; + +/// @brief Time by the moment of calling +/// @return A timestamp(seconds percision) +uint32_t time_now(); + +/// @brief Calculates difference between two provided timestamps +/// @param begin - start timestamp of the period +/// @param end - end timestamp of the period to measure +/// @return TimeDifference struct +TimeDifference time_difference_seconds(uint32_t begin, uint32_t end); diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/images/flipp_pomodoro_rest_64.png b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/images/flipp_pomodoro_rest_64.png new file mode 100644 index 0000000000000000000000000000000000000000..072affef3992c9fd662748f5a8cd7363afdfa2e9 GIT binary patch literal 1083 zcmV-B1jPG^P)Px&^+`lQRCr$9TFY|7KnSb<|D)4Mrt85Nki@Rzq`CCqeIbO9~JfI#>N0A^{7XkV>=I{+v{C^+@`sci1l02DlW zt_B~Czl{MXxU0(IqZr^bk_C;xVwn)FQ!?N=A^NSf4yx*}0%OFr0}ut91?tDH1jGW4 z`h1pog-Op8zntJq5Cf3eHLRmU8i1IyXZX)4reLk?0;}oigUHrb!8)*PB>;@`Vg(D) z8$D;8<0WnIDkfyKM!{C+xdecBG69tZV%*mPU_nL4 z^);)2;InSoz-j^O_0@4cjuQYQQ;~`3fZ$8P9(WcER1RMKqw}W>m<5380xF;uFlBD# zNe(YWR%(GQ1I7b%#;}4}f%WPFZ2MzSw`(yJKhnZ06lS2sr1Em|o9IVQ| zcaK@iWA-V_ay0-<)+=M;4V2dm-vMTYu=PG5qb++FCTs5!#1;T3OQ;hdt+6bMbYSM9 z7Pi4giNkMiBD2FV1hu?K3m8UaF}4_>Za6z0fznCfZsb;rU^nx2UL|x{H|T=UVgS1t z+Yx;5mGavTqB83iAD|x6kIzJK6%&>+U>w$FumixqU;r{ZsVY04Uol{;f!gX@onR(r ztZqcWWo5y%RkZJtZ-hc|nY^)8PH;u$Pi;`GRfueH1x9lR3r2?D<^wuy3uQkNMizkT ztFcSFz$_cG`3MaAoB_#>=?Y=m24~p702r;$%*zKy61+zuuiz10d#O3R^B7Y-aw+38Dit|1e=Qmr)0kM1UiHm#yyU~9b_Y0vbRh0}1N>=~?002ovPDHLkV1jt$ BPx(c}YY;RCr$PThVgdFbKT+|Bt?ooskD~yRaZj?R1itCT9u5vMfkV-mll|^Lps( z^Z7CLe!trmyEcw}$9toHkyD4K(*Q81$L9(f9<&Y+9T27g7%x47^Z{3x!1h}E3Xo%s z%7haD1vy49>lDgjMoYzRx2zNp-beH^PCgm5wS|~fVU)^*G6RNTy8i0aVf{kcvor*vjHqiP?SwK)31AGlBS&UjNE z*{~e~fuVrF-hX2N6AmSKv_=h@?M3w-fsy$M{dr;#ieB99K6Y!K=O?&~|V<3VBB zXP_W0upNXkVeGp!piBEKK(#FV`%!C)n1R|Y1LyX+XFwKE=Q*lRBy^~*Gxd)c@YV9n z+2JY?I|_G#Q}$%%0pA6(aW~5>6gzfZHW;7;GU};XE=&-!y9Aa&R4#TcYn_N;=Y@zG zJZgK&cE$j;ZjquR@kI7KFxJ+&zRG|M1b?xS4K;|)QNU4oL;x`MPB8%0Zd4u_uiMqsD0XfAp=$d5VbG=%m<2u zaES)60mjxoa!wUOTZd?mIxR+>L1n;A6NUyv3}EV-jlnEakznp*z~LX&07bkI0M(#T zt5xb9bq$pPbP`m0wleT2Wr0e|?^EmFgU$va*wNHEU^cTX)1F0kR^x^J_^_qu&2kM`nSC~4 zA|M$U?K?p=TdM$2j_%$^IFb5WVU;=x0IPzxCp+}L68P1cE5~6a=-oY^-5=PKU`qtE zc|HSUW%jdodsd*ILk7$qTy_K>y(7C-y2Yo=0Tnjv2;P>Nr#iYtYLx)mq)b~o0T|S_ z!o3s#1r%lYP-?ic1|?=%1S<~gR(>TBYCFIEvh+;$c2mETAP5{9gzUoXe}A&IPdU2E z4*Ug)>}3^DB3m +#include +#include "../helpers/time.h" +#include "flipp_pomodoro.h" + +char *next_stage_label[] = { + [Work] = "Get Rest", + [Rest] = "Start Work", +}; + +const PomodoroStage stage_rotaion_map[] = { + [Work] = Rest, + [Rest] = Work, +}; + +const PomodoroStage default_stage = Work; + +void flipp_pomodoro__toggle_stage(FlippPomodoroState *state) +{ + furi_assert(state); + state->stage = stage_rotaion_map[state->stage]; + state->started_at_timestamp = time_now(); +}; + +char *flipp_pomodoro__next_stage_label(FlippPomodoroState *state) +{ + furi_assert(state); + return next_stage_label[state->stage]; +}; + +void flipp_pomodoro__destroy(FlippPomodoroState *state) +{ + furi_assert(state); + free(state); +}; + +uint32_t flipp_pomodoro__current_stage_total_duration(FlippPomodoroState *state) +{ + const int32_t stage_duration_seconds_map[] = { + [Work] = 25 * TIME_SECONDS_IN_MINUTE, + [Rest] = 5 * TIME_SECONDS_IN_MINUTE, + }; + + return stage_duration_seconds_map[state->stage]; +}; + +uint32_t flipp_pomodoro__stage_expires_timestamp(FlippPomodoroState *state) +{ + return state->started_at_timestamp + flipp_pomodoro__current_stage_total_duration(state); +}; + +TimeDifference flipp_pomodoro__stage_remaining_duration(FlippPomodoroState *state) +{ + const uint32_t stage_ends_at = flipp_pomodoro__stage_expires_timestamp(state); + return time_difference_seconds(time_now(), stage_ends_at); +}; + +bool flipp_pomodoro__is_stage_expired(FlippPomodoroState *state) +{ + const uint32_t expired_by = flipp_pomodoro__stage_expires_timestamp(state); + const uint8_t seamless_change_span_seconds = 1; + return (time_now() - seamless_change_span_seconds) >= expired_by; +}; + +FlippPomodoroState *flipp_pomodoro__new() +{ + FlippPomodoroState *state = malloc(sizeof(FlippPomodoroState)); + const uint32_t now = time_now(); + state->started_at_timestamp = now; + state->stage = default_stage; + return state; +}; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/modules/flipp_pomodoro.h b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/modules/flipp_pomodoro.h new file mode 100644 index 000000000..3eb67d074 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/modules/flipp_pomodoro.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include "../helpers/time.h" + +/// @brief Options of pomodoro stages +typedef enum +{ + Work, + Rest, +} PomodoroStage; + +/// @brief State of the pomodoro timer +typedef struct +{ + PomodoroStage stage; + uint32_t started_at_timestamp; +} FlippPomodoroState; + +/// @brief Generates initial state +/// @param state - pointer to the state of pomorodo. +/// @returns A new pre-populated state for pomodoro timer +FlippPomodoroState *flipp_pomodoro__new(); + +/// @brief Destroys state of timer and it's dependencies +void flipp_pomodoro__destroy(FlippPomodoroState *state); + +/// @brief Get remaining stage time. +/// @param state - pointer to the state of pomorodo. +/// @returns Time difference to the end of current stage +TimeDifference flipp_pomodoro__stage_remaining_duration(FlippPomodoroState *state); + +/// @brief Label of transition to the next stage +/// @param state - pointer to the state of pomorodo. +/// @returns string with the label of the "skipp" button +char *flipp_pomodoro__next_stage_label(FlippPomodoroState *state); + +/// @brief Check if current stage is expired +/// @param state - pointer to the state of pomorodo. +/// @returns expriations status - true means stage is expired +bool flipp_pomodoro__is_stage_expired(FlippPomodoroState *state); + +/// @brief Rotate stage of the timer +/// @param state - pointer to the state of pomorodo. +void flipp_pomodoro__toggle_stage(FlippPomodoroState *state); diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/.keep b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/config/flipp_pomodoro_scene_config.h b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/config/flipp_pomodoro_scene_config.h new file mode 100644 index 000000000..f95daeb30 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/config/flipp_pomodoro_scene_config.h @@ -0,0 +1 @@ +ADD_SCENE(flipp_pomodoro, timer, Timer) \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/flipp_pomodoro_scene.c b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/flipp_pomodoro_scene.c new file mode 100644 index 000000000..4c611672e --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/flipp_pomodoro_scene.c @@ -0,0 +1,30 @@ +#include "flipp_pomodoro_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const flipp_pomodoro_scene_on_enter_handlers[])(void*) = { +#include "config/flipp_pomodoro_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 flipp_pomodoro_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "config/flipp_pomodoro_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 flipp_pomodoro_scene_on_exit_handlers[])(void* context) = { +#include "config/flipp_pomodoro_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers flipp_pomodoro_scene_handlers = { + .on_enter_handlers = flipp_pomodoro_scene_on_enter_handlers, + .on_event_handlers = flipp_pomodoro_scene_on_event_handlers, + .on_exit_handlers = flipp_pomodoro_scene_on_exit_handlers, + .scene_num = FlippPomodoroSceneNum, +}; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/flipp_pomodoro_scene.h b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/flipp_pomodoro_scene.h new file mode 100644 index 000000000..fe4bf35e2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/flipp_pomodoro_scene.h @@ -0,0 +1,28 @@ +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) FlippPomodoroScene##id, +typedef enum +{ +#include "config/flipp_pomodoro_scene_config.h" + FlippPomodoroSceneNum, +} FlippPomodoroScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers flipp_pomodoro_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void *); +#include "config/flipp_pomodoro_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 "config/flipp_pomodoro_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 "config/flipp_pomodoro_scene_config.h" +#undef ADD_SCENE diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/flipp_pomodoro_scene_timer.c b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/flipp_pomodoro_scene_timer.c new file mode 100644 index 000000000..9e1e03266 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/scenes/flipp_pomodoro_scene_timer.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include "../flipp_pomodoro_app.h" +#include "../views/flipp_pomodoro_timer_view.h" + +enum +{ + SceneEventConusmed = true, + SceneEventNotConusmed = false +}; + +uint8_t ExitSignal = 0; + +void flipp_pomodoro_scene_timer_on_next_stage(void *ctx) +{ + furi_assert(ctx); + + FlippPomodoroApp *app = ctx; + + view_dispatcher_send_custom_event( + app->view_dispatcher, + FlippPomodoroAppCustomEventStageSkip); +}; + +void flipp_pomodoro_scene_timer_on_enter(void *context) +{ + furi_assert(context); + + FlippPomodoroApp *app = context; + + view_dispatcher_switch_to_view(app->view_dispatcher, FlippPomodoroAppViewTimer); + flipp_pomodoro_view_timer_set_state( + flipp_pomodoro_view_timer_get_view(app->timer_view), + app->state); + flipp_pomodoro_view_timer_set_on_right_cb( + app->timer_view, + flipp_pomodoro_scene_timer_on_next_stage, + app); +}; + +void flipp_pomodoro_scene_timer_handle_custom_event(FlippPomodoroApp *app, FlippPomodoroAppCustomEvent custom_event) +{ + if (custom_event == FlippPomodoroAppCustomEventTimerTick && flipp_pomodoro__is_stage_expired(app->state)) + { + view_dispatcher_send_custom_event( + app->view_dispatcher, + FlippPomodoroAppCustomEventStageComplete); + } +}; + +bool flipp_pomodoro_scene_timer_on_event(void *ctx, SceneManagerEvent event) +{ + furi_assert(ctx); + FlippPomodoroApp *app = ctx; + + switch (event.type) + { + case SceneManagerEventTypeCustom: + flipp_pomodoro_scene_timer_handle_custom_event( + app, + event.event); + return SceneEventConusmed; + case SceneManagerEventTypeBack: + return ExitSignal; + default: + break; + }; + return SceneEventNotConusmed; +}; + +void flipp_pomodoro_scene_timer_on_exit(void *context) +{ + UNUSED(context); +}; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/views/.keep b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/views/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/views/flipp_pomodoro_timer_view.c b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/views/flipp_pomodoro_timer_view.c new file mode 100644 index 000000000..826e9e36c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/views/flipp_pomodoro_timer_view.c @@ -0,0 +1,151 @@ +#include "flipp_pomodoro_timer_view.h" +#include +#include +#include +#include +#include "../helpers/debug.h" +#include "../flipp_pomodoro_app.h" +#include "../modules/flipp_pomodoro.h" + +// Auto-compiled icons +#include "flipp_pomodoro_icons.h" + +enum +{ + ViewInputConsumed = true, + ViewInputNotConusmed = false, +}; + +struct FlippPomodoroTimerView +{ + View *view; + FlippPomodoroTimerViewInputCb right_cb; + void *right_cb_ctx; +}; + +typedef struct +{ + FlippPomodoroState *state; +} FlippPomodoroTimerViewModel; + +static const Icon *stage_background_image[] = { + [Work] = &I_flipp_pomodoro_work_64, + [Rest] = &I_flipp_pomodoro_rest_64, +}; + +static void flipp_pomodoro_view_timer_draw_countdown(Canvas *canvas, TimeDifference remaining_time) +{ + canvas_set_font(canvas, FontBigNumbers); + const uint8_t right_border_margin = 1; + + const uint8_t countdown_box_height = canvas_height(canvas) * 0.4; + const uint8_t countdown_box_width = canvas_width(canvas) * 0.5; + const uint8_t countdown_box_x = canvas_width(canvas) - countdown_box_width - right_border_margin; + const uint8_t countdown_box_y = 0; + + elements_bold_rounded_frame(canvas, + countdown_box_x, + countdown_box_y, + countdown_box_width, + countdown_box_height); + + FuriString *timer_string = furi_string_alloc(); + furi_string_printf(timer_string, "%02u:%02u", remaining_time.minutes, remaining_time.seconds); + const char *remaining_stage_time_string = furi_string_get_cstr(timer_string); + canvas_draw_str_aligned( + canvas, + countdown_box_x + (countdown_box_width / 2), + countdown_box_y + (countdown_box_height / 2), + AlignCenter, + AlignCenter, + remaining_stage_time_string); + + furi_string_free(timer_string); +}; + +static void flipp_pomodoro_view_timer_draw_callback(Canvas *canvas, void *_model) +{ + if (!_model) + { + return; + }; + + FlippPomodoroTimerViewModel *model = _model; + + canvas_clear(canvas); + canvas_draw_icon(canvas, 0, 0, stage_background_image[model->state->stage]); + flipp_pomodoro_view_timer_draw_countdown( + canvas, + flipp_pomodoro__stage_remaining_duration(model->state)); + + canvas_set_font(canvas, FontSecondary); + elements_button_right(canvas, flipp_pomodoro__next_stage_label(model->state)); +}; + +bool flipp_pomodoro_view_timer_input_callback(InputEvent *event, void *ctx) +{ + furi_assert(ctx); + furi_assert(event); + FlippPomodoroTimerView *timer = ctx; + + const bool should_trigger_right_event_cb = (event->type == InputTypePress) && + (event->key == InputKeyRight) && + (timer->right_cb != NULL); + + if (should_trigger_right_event_cb) + { + furi_assert(timer->right_cb); + furi_assert(timer->right_cb_ctx); + timer->right_cb(timer->right_cb_ctx); + return ViewInputConsumed; + }; + + return ViewInputNotConusmed; +}; + +View *flipp_pomodoro_view_timer_get_view(FlippPomodoroTimerView *timer) +{ + furi_assert(timer); + return timer->view; +}; + +FlippPomodoroTimerView *flipp_pomodoro_view_timer_alloc() +{ + FlippPomodoroTimerView *timer = malloc(sizeof(FlippPomodoroTimerView)); + timer->view = view_alloc(); + + view_allocate_model(timer->view, ViewModelTypeLockFree, sizeof(FlippPomodoroTimerViewModel)); + view_set_context(flipp_pomodoro_view_timer_get_view(timer), timer); + view_set_draw_callback(timer->view, flipp_pomodoro_view_timer_draw_callback); + view_set_input_callback(timer->view, flipp_pomodoro_view_timer_input_callback); + + return timer; +}; + +void flipp_pomodoro_view_timer_set_on_right_cb(FlippPomodoroTimerView *timer, FlippPomodoroTimerViewInputCb right_cb, void *right_cb_ctx) +{ + furi_assert(right_cb); + furi_assert(right_cb_ctx); + timer->right_cb = right_cb; + timer->right_cb_ctx = right_cb_ctx; +}; + +void flipp_pomodoro_view_timer_set_state(View *view, FlippPomodoroState *state) +{ + furi_assert(view); + furi_assert(state); + with_view_model( + view, + FlippPomodoroTimerViewModel * model, + { + model->state = state; + }, + false); +}; + +void flipp_pomodoro_view_timer_free(FlippPomodoroTimerView *timer) +{ + furi_assert(timer); + view_free(timer->view); + free(timer); +}; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/views/flipp_pomodoro_timer_view.h b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/views/flipp_pomodoro_timer_view.h new file mode 100644 index 000000000..7553d9c27 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipp_pomodoro/views/flipp_pomodoro_timer_view.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include "../modules/flipp_pomodoro.h" + +typedef struct FlippPomodoroTimerView FlippPomodoroTimerView; + +typedef void (*FlippPomodoroTimerViewInputCb)(void *context); + +FlippPomodoroTimerView *flipp_pomodoro_view_timer_alloc(); + +View *flipp_pomodoro_view_timer_get_view(FlippPomodoroTimerView *timer); + +void flipp_pomodoro_view_timer_free(FlippPomodoroTimerView *timer); + +void flipp_pomodoro_view_timer_set_state(View *view, FlippPomodoroState *state); + +void flipp_pomodoro_view_timer_set_on_right_cb(FlippPomodoroTimerView *timer, FlippPomodoroTimerViewInputCb right_cb, void *right_cb_ctx); diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/LICENSE new file mode 100644 index 000000000..2d8a8a74d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2022-2023 Salvatore Sanfilippo + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/README.md b/Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/README.md new file mode 100644 index 000000000..7899ff0e2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/README.md @@ -0,0 +1,60 @@ +This is an implementation of the classic Asteroids game for the [Flipper Zero](https://flipperzero.one/). Inside you will find a simple 2D engine that can be reused to implement other games. Note: This one is SimplyMinimal's fork of Antirez's version with several modifications. + +# What's New +* Auto rapid fire (less wear on the buttons this way too) +* Up button applies thrusters +* Haptic feedback and LED effects +* High Score system +* Automatic save and load of high score +* Some modifications to certain game play elements + +## What's coming next +* Settings screen +* Enabling sound effects (configurable on/off option) +* Power Ups + +--- + +This is a screenshot, but the game looks a lot better in the device itself: + +![Asteroids for Flipper Zero screenshot](/images/Asteroids.jpg) + +# Controls: +* Left/Right: rotate ship in the two directions. +* Ok, short press: Short burst bullets +* Ok, long press: Auto-fire bullets +* Up: Accelerate +* Down: Decelerate +* Back (Long Press): Exit game. It will automatically save the high scoore too. + +Your high scores will automatically be saved. Go forth and compete! + +--- +## Installing the binary file (no build needed) + +Go to the releases and drop the `asteroids.fap` file into the +following Flipper Zero location: + + /ext/apps/Games + +The `ext` part means that we are in the SD card. So if you don't want +to use the Android (or other) application to upload the file, +you can just take out the SD card, insert it in your computer, +copy the fine into `apps/Games`, and that's it. + +## Installing the app from source + +* Download the Flipper Zero dev kit and build it: +``` +mkdir -p ~/flipperZero/official/ +cd ~/flipperZero/official/ +git clone --recursive https://github.com/flipperdevices/flipperzero-firmware.git ./ +./fbt +``` +* Copy this application folder in `official/application_user`. +* Connect your Flipper via USB. +* Build and install with: `./fbt launch_app APPSRC=asteroids`. + +## License + +BSD licensed. Enjoy. diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/app.c b/Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/app.c new file mode 100644 index 000000000..27a44db52 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/app.c @@ -0,0 +1,789 @@ +/* Copyright (C) 2023 Salvatore Sanfilippo -- All Rights Reserved + * See the LICENSE file for information about the license. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TAG "Asteroids" // Used for logging +#define DEBUG_MSG 1 +#define SCREEN_XRES 128 +#define SCREEN_YRES 64 +#define GAME_START_LIVES 3 +#define TTLBUL 30 /* Bullet time to live, in ticks. */ +#define MAXBUL 5 /* Max bullets on the screen. */ +#define MAXAST 32 /* Max asteroids on the screen. */ +#define SHIP_HIT_ANIMATION_LEN 15 +#define SAVING_DIRECTORY "/ext/apps/Games" +#define SAVING_FILENAME SAVING_DIRECTORY "/game_asteroids.save" +#ifndef PI +#define PI 3.14159265358979f +#endif + +/* ============================ Data structures ============================= */ + +typedef struct Ship { + float x, /* Ship x position. */ + y, /* Ship y position. */ + vx, /* x velocity. */ + vy, /* y velocity. */ + rot; /* Current rotation. 2*PI full ortation. */ +} Ship; + +typedef struct Bullet { + float x, y, vx, vy; /* Fields like in ship. */ + uint32_t ttl; /* Time to live, in ticks. */ +} Bullet; + +typedef struct Asteroid { + float x, y, vx, vy, rot, /* Fields like ship. */ + rot_speed, /* Angular velocity (rot speed and sense). */ + size; /* Asteroid size. */ + uint8_t shape_seed; /* Seed to give random shape. */ +} Asteroid; + +typedef struct AsteroidsApp { + /* GUI */ + Gui* gui; + ViewPort* view_port; /* We just use a raw viewport and we render + everything into the low level canvas. */ + FuriMessageQueue* event_queue; /* Keypress events go here. */ + + /* Game state. */ + int running; /* Once false exists the app. */ + bool gameover; /* Gameover status. */ + uint32_t ticks; /* Game ticks. Increments at each refresh. */ + uint32_t score; /* Game score. */ + uint32_t highscore; /* Highscore. Shown on Game Over Screen */ + bool is_new_highscore; /* Is the last score a new highscore? */ + uint32_t lives; /* Number of lives in the current game. */ + uint32_t ship_hit; /* When non zero, the ship was hit by an asteroid + and we need to show an animation as long as + its value is non-zero (and decrease it's value + at each tick of animation). */ + + /* Ship state. */ + struct Ship ship; + + /* Bullets state. */ + struct Bullet bullets[MAXBUL]; /* Each bullet state. */ + int bullets_num; /* Active bullets. */ + uint32_t last_bullet_tick; /* Tick the last bullet was fired. */ + + /* Asteroids state. */ + Asteroid asteroids[MAXAST]; /* Each asteroid state. */ + int asteroids_num; /* Active asteroids. */ + + uint32_t pressed[InputKeyMAX]; /* pressed[id] is true if pressed. + Each array item contains the time + in milliseconds the key was pressed. */ + bool fire; /* Short press detected: fire a bullet. */ +} AsteroidsApp; + +const NotificationSequence sequence_thrusters = { + &message_vibro_on, + &message_delay_10, + &message_vibro_off, + NULL, +}; + +const NotificationSequence sequence_brake = { + &message_vibro_on, + &message_delay_10, + &message_delay_1, + &message_delay_1, + &message_vibro_off, + NULL, +}; + +const NotificationSequence sequence_crash = { + &message_red_255, + + &message_vibro_on, + // &message_note_g5, // Play sound but currently disabled + &message_delay_25, + // &message_note_e5, + &message_vibro_off, + &message_sound_off, + NULL, +}; + +const NotificationSequence sequence_bullet_fired = { + &message_vibro_on, + // &message_note_g5, // Play sound but currently disabled. Need On/Off menu setting + &message_delay_10, + &message_delay_1, + &message_delay_1, + &message_delay_1, + &message_delay_1, + &message_delay_1, + + // &message_note_e5, + &message_vibro_off, + &message_sound_off, + NULL, +}; + +/* ============================== Prototyeps ================================ */ + +// Only functions called before their definition are here. +bool load_game(AsteroidsApp* app); +void save_game(AsteroidsApp* app); +void restart_game_after_gameover(AsteroidsApp* app); +uint32_t key_pressed_time(AsteroidsApp* app, InputKey key); + +/* ============================ 2D drawing ================================== */ + +/* This structure represents a polygon of at most POLY_MAX points. + * The function draw_poly() is able to render it on the screen, rotated + * by the amount specified. */ +#define POLY_MAX 8 +typedef struct Poly { + float x[POLY_MAX]; + float y[POLY_MAX]; + uint32_t points; /* Number of points actually populated. */ +} Poly; + +/* Define the polygons we use. */ +Poly ShipPoly = {{-3, 0, 3}, {-3, 6, -3}, 3}; + +Poly ShipFirePoly = {{-1.5, 0, 1.5}, {-3, -6, -3}, 3}; + +/* Rotate the point of the poligon 'poly' and store the new rotated + * polygon in 'rot'. The polygon is rotated by an angle 'a', with + * center at 0,0. */ +void rotate_poly(Poly* rot, Poly* poly, float a) { + /* We want to compute sin(a) and cos(a) only one time + * for every point to rotate. It's a slow operation. */ + float sin_a = (float)sin(a); + float cos_a = (float)cos(a); + for(uint32_t j = 0; j < poly->points; j++) { + rot->x[j] = poly->x[j] * cos_a - poly->y[j] * sin_a; + rot->y[j] = poly->y[j] * cos_a + poly->x[j] * sin_a; + } + rot->points = poly->points; +} + +/* This is an 8 bit LFSR we use to generate a predictable and fast + * pseudorandom sequence of numbers, to give a different shape to + * each asteroid. */ +void lfsr_next(unsigned char* prev) { + unsigned char lsb = *prev & 1; + *prev = *prev >> 1; + if(lsb == 1) *prev ^= 0b11000111; + *prev ^= *prev << 7; /* Mix things a bit more. */ +} + +/* Render the polygon 'poly' at x,y, rotated by the specified angle. */ +void draw_poly(Canvas* const canvas, Poly* poly, uint8_t x, uint8_t y, float a) { + Poly rot; + rotate_poly(&rot, poly, a); + canvas_set_color(canvas, ColorBlack); + for(uint32_t j = 0; j < rot.points; j++) { + uint32_t a = j; + uint32_t b = j + 1; + if(b == rot.points) b = 0; + canvas_draw_line(canvas, x + rot.x[a], y + rot.y[a], x + rot.x[b], y + rot.y[b]); + } +} + +/* A bullet is just a + pixels pattern. A single pixel is not + * visible enough. */ +void draw_bullet(Canvas* const canvas, Bullet* b) { + canvas_draw_dot(canvas, b->x - 1, b->y); + canvas_draw_dot(canvas, b->x + 1, b->y); + canvas_draw_dot(canvas, b->x, b->y); + canvas_draw_dot(canvas, b->x, b->y - 1); + canvas_draw_dot(canvas, b->x, b->y + 1); +} + +/* Draw an asteroid. The asteroid shapes is computed on the fly and + * is not stored in a permanent shape structure. In order to generate + * the shape, we use an initial fixed shape that we resize according + * to the asteroid size, perturbate according to the asteroid shape + * seed, and finally draw it rotated of the right amount. */ +void draw_asteroid(Canvas* const canvas, Asteroid* ast) { + Poly ap; + + /* Start with what is kinda of a circle. Note that this could be + * stored into a template and copied here, to avoid computing + * sin() / cos(). But the Flipper can handle it without problems. */ + uint8_t r = ast->shape_seed; + for(int j = 0; j < 8; j++) { + float a = (PI * 2) / 8 * j; + + /* Before generating the point, to make the shape unique generate + * a random factor between .7 and 1.3 to scale the distance from + * the center. However this asteroid should have its unique shape + * that remains always the same, so we use a predictable PRNG + * implemented by an 8 bit shift register. */ + lfsr_next(&r); + float scaling = .7 + ((float)r / 255 * .6); + + ap.x[j] = (float)sin(a) * ast->size * scaling; + ap.y[j] = (float)cos(a) * ast->size * scaling; + } + ap.points = 8; + draw_poly(canvas, &ap, ast->x, ast->y, ast->rot); +} + +/* Draw small ships in the top-right part of the screen, one for + * each left live. */ +void draw_left_lives(Canvas* const canvas, AsteroidsApp* app) { + int lives = app->lives; + int x = SCREEN_XRES - 5; + + Poly mini_ship = {{-2, 0, 2}, {-2, 4, -2}, 3}; + while(lives--) { + draw_poly(canvas, &mini_ship, x, 6, PI); + x -= 6; + } +} + +/* Given the current position, update it according to the velocity and + * wrap it back to the other side if the object went over the screen. */ +void update_pos_by_velocity(float* x, float* y, float vx, float vy) { + /* Return back from one side to the other of the screen. */ + *x += vx; + *y += vy; + if(*x >= SCREEN_XRES) + *x = 0; + else if(*x < 0) + *x = SCREEN_XRES - 1; + if(*y >= SCREEN_YRES) + *y = 0; + else if(*y < 0) + *y = SCREEN_YRES - 1; +} + +/* Render the current game screen. */ +void render_callback(Canvas* const canvas, void* ctx) { + AsteroidsApp* app = ctx; + + /* Clear screen. */ + canvas_set_color(canvas, ColorWhite); + canvas_draw_box(canvas, 0, 0, SCREEN_XRES - 1, SCREEN_YRES - 1); + + /* Draw score. */ + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontSecondary); + char score[32]; + snprintf(score, sizeof(score), "%lu", app->score); + canvas_draw_str(canvas, 0, 8, score); + + /* Draw left ships. */ + draw_left_lives(canvas, app); + + /* Draw ship, asteroids, bullets. */ + draw_poly(canvas, &ShipPoly, app->ship.x, app->ship.y, app->ship.rot); + + if(key_pressed_time(app, InputKeyUp) > 0) { + notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_thrusters); + draw_poly(canvas, &ShipFirePoly, app->ship.x, app->ship.y, app->ship.rot); + } + + for(int j = 0; j < app->bullets_num; j++) draw_bullet(canvas, &app->bullets[j]); + + for(int j = 0; j < app->asteroids_num; j++) draw_asteroid(canvas, &app->asteroids[j]); + + /* Game over text. */ + if(app->gameover) { + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontPrimary); + + // TODO: if new highscore, display blinking "New High Score" + // Display High Score + if(app->is_new_highscore) { + canvas_draw_str(canvas, 22, 9, "New High Score!"); + } else { + canvas_draw_str(canvas, 36, 9, "High Score"); + } + + // Convert highscore to string + int length = snprintf(NULL, 0, "%lu", app->highscore); + char* str_high_score = malloc(length + 1); + snprintf(str_high_score, length + 1, "%lu", app->highscore); + + // Get length to center on screen + int nDigits = 0; + if(app->highscore > 0) { + nDigits = floor(log10(app->highscore)) + 1; + } + + // Draw highscore centered + canvas_draw_str(canvas, (SCREEN_XRES / 2) - (nDigits * 2), 20, str_high_score); + free(str_high_score); + + canvas_draw_str(canvas, 28, 35, "GAME OVER"); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 25, 50, "Press OK to restart"); + } +} + +/* ============================ Game logic ================================== */ + +float distance(float x1, float y1, float x2, float y2) { + float dx = x1 - x2; + float dy = y1 - y2; + return sqrt(dx * dx + dy * dy); +} + +/* Detect a collision between the object at x1,y1 of radius r1 and + * the object at x2, y2 of radius r2. A factor < 1 will make the + * function detect the collision even if the objects are yet not + * relly touching, while a factor > 1 will make it detect the collision + * only after they are a bit overlapping. It basically is used to + * rescale the distance. + * + * Note that in this simplified 2D world, objects are all considered + * spheres (this is why this function only takes the radius). This + * is, after all, kinda accurate for asteroids, for bullets, and + * even for the ship "core" itself. */ +bool objects_are_colliding(float x1, float y1, float r1, float x2, float y2, float r2, float factor) { + /* The objects are colliding if the distance between object 1 and 2 + * is smaller than the sum of the two radiuses r1 and r2. + * So it would be like: sqrt((x1-x2)^2+(y1-y2)^2) < r1+r2. + * However we can avoid computing the sqrt (which is slow) by + * squaring the second term and removing the square root, making + * the comparison like this: + * + * (x1-x2)^2+(y1-y2)^2 < (r1+r2)^2. */ + float dx = (x1 - x2) * factor; + float dy = (y1 - y2) * factor; + float rsum = r1 + r2; + return dx * dx + dy * dy < rsum * rsum; +} + +/* Create a new bullet headed in the same direction of the ship. */ +void ship_fire_bullet(AsteroidsApp* app) { + if(app->bullets_num == MAXBUL) return; + notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_bullet_fired); + Bullet* b = &app->bullets[app->bullets_num]; + b->x = app->ship.x; + b->y = app->ship.y; + b->vx = -sin(app->ship.rot); + b->vy = cos(app->ship.rot); + + /* Ship should fire from its head, not in the middle. */ + b->x += b->vx * 5; + b->y += b->vy * 5; + + /* Give the bullet some velocity (for now the vector is just + * normalized to 1). */ + b->vx *= 3; + b->vy *= 3; + + /* It's more realistic if we add the velocity vector of the + * ship, too. Otherwise if the ship is going fast the bullets + * will be slower, which is not how the world works. */ + b->vx += app->ship.vx; + b->vy += app->ship.vy; + + b->ttl = TTLBUL; /* The bullet will disappear after N ticks. */ + app->bullets_num++; +} + +/* Remove the specified bullet by id (index in the array). */ +void remove_bullet(AsteroidsApp* app, int bid) { + /* Replace the top bullet with the empty space left + * by the removal of this bullet. This way we always take the + * array dense, which is an advantage when looping. */ + int n = --app->bullets_num; + if(n && bid != n) app->bullets[bid] = app->bullets[n]; +} + +/* Create a new asteroid, away from the ship. Return the + * pointer to the asteroid object, so that the caller can change + * certain things of the asteroid if needed. */ +Asteroid* add_asteroid(AsteroidsApp* app) { + if(app->asteroids_num == MAXAST) return NULL; + float size = 4 + rand() % 15; + float min_distance = 20; + float x, y; + do { + x = rand() % SCREEN_XRES; + y = rand() % SCREEN_YRES; + } while(distance(app->ship.x, app->ship.y, x, y) < min_distance + size); + Asteroid* a = &app->asteroids[app->asteroids_num++]; + a->x = x; + a->y = y; + a->vx = 2 * (-.5 + ((float)rand() / RAND_MAX)); + a->vy = 2 * (-.5 + ((float)rand() / RAND_MAX)); + a->size = size; + a->rot = 0; + a->rot_speed = ((float)rand() / RAND_MAX) / 10; + if(app->ticks & 1) a->rot_speed = -(a->rot_speed); + a->shape_seed = rand() & 255; + return a; +} + +/* Remove the specified asteroid by id (index in the array). */ +void remove_asteroid(AsteroidsApp* app, int id) { + /* Replace the top asteroid with the empty space left + * by the removal of this one. This way we always take the + * array dense, which is an advantage when looping. */ + int n = --app->asteroids_num; + if(n && id != n) app->asteroids[id] = app->asteroids[n]; +} + +/* Called when an asteroid was reached by a bullet. The asteroid + * hit is the one with the specified 'id'. */ +void asteroid_was_hit(AsteroidsApp* app, int id) { + float sizelimit = 6; // Smaller than that polverize in one shot. + Asteroid* a = &app->asteroids[id]; + + /* Asteroid is large enough to break into fragments. */ + float size = a->size; + float x = a->x, y = a->y; + remove_asteroid(app, id); + if(size > sizelimit) { + int max_fragments = size / sizelimit; + int fragments = 2 + rand() % max_fragments; + float newsize = size / fragments; + if(newsize < 2) newsize = 2; + for(int j = 0; j < fragments; j++) { + a = add_asteroid(app); + if(a == NULL) break; // Too many asteroids on screen. + a->x = x + -(size / 2) + rand() % (int)newsize; + a->y = y + -(size / 2) + rand() % (int)newsize; + a->size = newsize; + } + } else { + app->score++; + if(app->score > app->highscore) { + app->is_new_highscore = true; + app->highscore = app->score; // Show on Game Over Screen and future main menu + } + } +} + +/* Set gameover state. When in game-over mode, the game displays a gameover + * text with a background of many asteroids floating around. */ +void game_over(AsteroidsApp* app) { + if(app->is_new_highscore) save_game(app); // Save highscore but only on change + app->gameover = true; + app->lives = GAME_START_LIVES; // Show 3 lives in game over screen to match new game start +} + +/* Function called when a collision between the asteroid and the + * ship is detected. */ +void ship_was_hit(AsteroidsApp* app) { + app->ship_hit = SHIP_HIT_ANIMATION_LEN; + if(app->lives) { + app->lives--; + } else { + game_over(app); + } +} + +/* Restart game after the ship is hit. Will reset the ship position, bullets + * and asteroids to restart the game. */ +void restart_game(AsteroidsApp* app) { + app->ship.x = SCREEN_XRES / 2; + app->ship.y = SCREEN_YRES / 2; + app->ship.rot = PI; /* Start headed towards top. */ + app->ship.vx = 0; + app->ship.vy = 0; + app->bullets_num = 0; + app->last_bullet_tick = 0; + app->asteroids_num = 0; + app->ship_hit = 0; +} + +/* Called after gameover to restart the game. This function + * also calls restart_game(). */ +void restart_game_after_gameover(AsteroidsApp* app) { + app->gameover = false; + app->ticks = 0; + app->score = 0; + app->is_new_highscore = false; + app->lives = GAME_START_LIVES - 1; + restart_game(app); +} + +/* Move bullets. */ +void update_bullets_position(AsteroidsApp* app) { + for(int j = 0; j < app->bullets_num; j++) { + update_pos_by_velocity( + &app->bullets[j].x, &app->bullets[j].y, app->bullets[j].vx, app->bullets[j].vy); + if(--app->bullets[j].ttl == 0) { + remove_bullet(app, j); + j--; /* Process this bullet index again: the removal will + fill it with the top bullet to take the array dense. */ + } + } +} + +/* Move asteroids. */ +void update_asteroids_position(AsteroidsApp* app) { + for(int j = 0; j < app->asteroids_num; j++) { + update_pos_by_velocity( + &app->asteroids[j].x, &app->asteroids[j].y, app->asteroids[j].vx, app->asteroids[j].vy); + app->asteroids[j].rot += app->asteroids[j].rot_speed; + if(app->asteroids[j].rot < 0) + app->asteroids[j].rot = 2 * PI; + else if(app->asteroids[j].rot > 2 * PI) + app->asteroids[j].rot = 0; + } +} + +/* Collision detection and game state update based on collisions. */ +void detect_collisions(AsteroidsApp* app) { + /* Detect collision between bullet and asteroid. */ + for(int j = 0; j < app->bullets_num; j++) { + Bullet* b = &app->bullets[j]; + for(int i = 0; i < app->asteroids_num; i++) { + Asteroid* a = &app->asteroids[i]; + if(objects_are_colliding(a->x, a->y, a->size, b->x, b->y, 1.5, 1)) { + asteroid_was_hit(app, i); + remove_bullet(app, j); + /* The bullet no longer exist. Break the loop. + * However we want to start processing from the + * same bullet index, since now it is used by + * another bullet (see remove_bullet()). */ + j--; /* Scan this j value again. */ + break; + } + } + } + + /* Detect collision between ship and asteroid. */ + for(int j = 0; j < app->asteroids_num; j++) { + Asteroid* a = &app->asteroids[j]; + if(objects_are_colliding(a->x, a->y, a->size, app->ship.x, app->ship.y, 4, 1)) { + ship_was_hit(app); + break; + } + } +} + +/* This is the main game execution function, called 10 times for + * second (with the Flipper screen latency, an higher FPS does not + * make sense). In this function we update the position of objects based + * on velocity. Detect collisions. Update the score and so forth. + * + * Each time this function is called, app->tick is incremented. */ +void game_tick(void* ctx) { + AsteroidsApp* app = ctx; + + /* There are two special screens: + * + * 1. Ship was hit, we frozen the game as long as ship_hit isn't zero + * again, and show an animation of a rotating ship. */ + if(app->ship_hit) { + notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_crash); + app->ship.rot += 0.5; + app->ship_hit--; + view_port_update(app->view_port); + if(app->ship_hit == 0) { + restart_game(app); + } + return; + } else if(app->gameover) { + /* 2. Game over. We need to update only background asteroids. In this + * state the game just displays a GAME OVER text with the floating + * asteroids in backgroud. */ + + if(key_pressed_time(app, InputKeyOk) > 100) { + restart_game_after_gameover(app); + } + update_asteroids_position(app); + view_port_update(app->view_port); + return; + } + + /* Handle keypresses. */ + if(app->pressed[InputKeyLeft]) app->ship.rot -= .35; + if(app->pressed[InputKeyRight]) app->ship.rot += .35; + if(app->pressed[InputKeyUp]) { + app->ship.vx -= 0.5 * (float)sin(app->ship.rot); + app->ship.vy += 0.5 * (float)cos(app->ship.rot); + } else if(app->pressed[InputKeyDown]) { + notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_brake); + app->ship.vx *= 0.75; + app->ship.vy *= 0.75; + } + + /* Fire a bullet if needed. app->fire is set in + * asteroids_update_keypress_state() since depends on exact + * pressure timing. */ + if(app->fire) { + uint32_t bullet_min_period = 200; // In milliseconds + uint32_t now = furi_get_tick(); + if(now - app->last_bullet_tick >= bullet_min_period) { + ship_fire_bullet(app); + app->last_bullet_tick = now; + } + app->fire = false; + } + + /* Update positions and detect collisions. */ + update_pos_by_velocity(&app->ship.x, &app->ship.y, app->ship.vx, app->ship.vy); + update_bullets_position(app); + update_asteroids_position(app); + detect_collisions(app); + + /* From time to time, create a new asteroid. The more asteroids + * already on the screen, the smaller probability of creating + * a new one. */ + if(app->asteroids_num == 0 || (random() % 5000) < (30 / (1 + app->asteroids_num))) { + add_asteroid(app); + } + + app->ticks++; + view_port_update(app->view_port); +} + +/* ======================== Flipper specific code =========================== */ + +bool load_game(AsteroidsApp* app) { + Storage* storage = furi_record_open(RECORD_STORAGE); + + File* file = storage_file_alloc(storage); + uint16_t bytes_readed = 0; + if(storage_file_open(file, SAVING_FILENAME, FSAM_READ, FSOM_OPEN_EXISTING)) { + bytes_readed = storage_file_read(file, app, sizeof(AsteroidsApp)); + } + storage_file_close(file); + storage_file_free(file); + + furi_record_close(RECORD_STORAGE); + + return bytes_readed == sizeof(AsteroidsApp); +} + +void save_game(AsteroidsApp* app) { + Storage* storage = furi_record_open(RECORD_STORAGE); + + if(storage_common_stat(storage, SAVING_DIRECTORY, NULL) == FSE_NOT_EXIST) { + if(!storage_simply_mkdir(storage, SAVING_DIRECTORY)) { + return; + } + } + + File* file = storage_file_alloc(storage); + if(storage_file_open(file, SAVING_FILENAME, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + storage_file_write(file, app, sizeof(AsteroidsApp)); + } + storage_file_close(file); + storage_file_free(file); + + furi_record_close(RECORD_STORAGE); +} + +/* Here all we do is putting the events into the queue that will be handled + * in the while() loop of the app entry point function. */ +void input_callback(InputEvent* input_event, void* ctx) { + AsteroidsApp* app = ctx; + furi_message_queue_put(app->event_queue, input_event, FuriWaitForever); +} + +/* Allocate the application state and initialize a number of stuff. + * This is called in the entry point to create the application state. */ +AsteroidsApp* asteroids_app_alloc() { + AsteroidsApp* app = malloc(sizeof(AsteroidsApp)); + + load_game(app); + + app->gui = furi_record_open(RECORD_GUI); + app->view_port = view_port_alloc(); + view_port_draw_callback_set(app->view_port, render_callback, app); + view_port_input_callback_set(app->view_port, input_callback, app); + gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen); + app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + app->running = 1; /* Turns 0 when back is pressed. */ + + restart_game_after_gameover(app); + memset(app->pressed, 0, sizeof(app->pressed)); + return app; +} + +/* Free what the application allocated. It is not clear to me if the + * Flipper OS, once the application exits, will be able to reclaim space + * even if we forget to free something here. */ +void asteroids_app_free(AsteroidsApp* app) { + furi_assert(app); + + // View related. + view_port_enabled_set(app->view_port, false); + gui_remove_view_port(app->gui, app->view_port); + view_port_free(app->view_port); + furi_record_close(RECORD_GUI); + furi_message_queue_free(app->event_queue); + app->gui = NULL; + + free(app); +} + +/* Return the time in milliseconds the specified key is continuously + * pressed. Or 0 if it is not pressed. */ +uint32_t key_pressed_time(AsteroidsApp* app, InputKey key) { + return app->pressed[key] == 0 ? 0 : furi_get_tick() - app->pressed[key]; +} + +/* Handle keys interaction. */ +void asteroids_update_keypress_state(AsteroidsApp* app, InputEvent input) { + // Allow Rapid fire + if(input.key == InputKeyOk) { + app->fire = true; + } + + if(input.type == InputTypePress) { + app->pressed[input.key] = furi_get_tick(); + } else if(input.type == InputTypeRelease) { + app->pressed[input.key] = 0; + } +} + +int32_t asteroids_app_entry(void* p) { + UNUSED(p); + AsteroidsApp* app = asteroids_app_alloc(); + + /* Create a timer. We do data analysis in the callback. */ + FuriTimer* timer = furi_timer_alloc(game_tick, FuriTimerTypePeriodic, app); + furi_timer_start(timer, furi_kernel_get_tick_frequency() / 10); + + /* This is the main event loop: here we get the events that are pushed + * in the queue by input_callback(), and process them one after the + * other. */ + InputEvent input; + while(app->running) { + FuriStatus qstat = furi_message_queue_get(app->event_queue, &input, 100); + if(qstat == FuriStatusOk) { + if(DEBUG_MSG) + FURI_LOG_E(TAG, "Main Loop - Input: type %d key %u", input.type, input.key); + + /* Handle navigation here. Then handle view-specific inputs + * in the view specific handling function. */ + if(input.type == InputTypeLong && input.key == InputKeyBack) { + // Save High Score even if player didn't finish game + if(app->is_new_highscore) save_game(app); // Save highscore but only on change + app->running = 0; + } else { + asteroids_update_keypress_state(app, input); + } + } else { + /* Useful to understand if the app is still alive when it + * does not respond because of bugs. */ + if(DEBUG_MSG) { + static int c = 0; + c++; + if(!(c % 20)) FURI_LOG_E(TAG, "Loop timeout"); + } + } + } + + furi_timer_free(timer); + asteroids_app_free(app); + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/appicon.png b/Applications/Official/DEV_FW/source/xMasterX/flipper-asteroids/appicon.png new file mode 100644 index 0000000000000000000000000000000000000000..45da095afff23ff1fc2bef96fbcf7f1aef080b1d GIT binary patch literal 145 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 literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/README.md b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/README.md new file mode 100644 index 000000000..75c27eadb --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/README.md @@ -0,0 +1,3 @@ +# Flipper BP + +Custom implementation of T-Code protocol for Flipper Zero devices. \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/application.fam b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/application.fam new file mode 100644 index 000000000..bddfbf022 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/application.fam @@ -0,0 +1,13 @@ +App( + appid="fbp", + name="Flipper BP", + apptype=FlipperAppType.EXTERNAL, + entry_point="fbp_app", + stack_size=1 * 1024, + requires=[ + "bt", + "gui", + ], + fap_category="Misc_Extra", + fap_icon="uart_10px.png", +) \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/fbp.c b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/fbp.c new file mode 100644 index 000000000..60083a4a6 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/fbp.c @@ -0,0 +1,103 @@ +#include "fbp.h" + +enum FBPSubmenuIndex { + FBPSubmenuIndexInternal, + FBPSubmenuIndexGPIOSimpleMotor, +}; + +uint32_t fbp_start_view(void* context) { + UNUSED(context); + return FBPAppViewSubmenu; +} + +uint32_t fbp_exit(void* context) { + UNUSED(context); + return VIEW_NONE; +} + +void fbp_submenu_callback(void* context, uint32_t index) { + furi_assert(context); + FBP* app = context; + if(index == FBPSubmenuIndexInternal) { + view_dispatcher_switch_to_view(app->view_dispatcher, FBPAppViewInternal); + } else if (index == FBPSubmenuIndexGPIOSimpleMotor) { + view_dispatcher_switch_to_view(app->view_dispatcher, FBPAppViewGPIOSimpleMotor); + } +} + +FBP* fbp_alloc() { + FBP* app = malloc(sizeof(FBP)); + app->app_mutex = furi_mutex_alloc(FuriMutexTypeNormal); + app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + app->bt_connected = false; + app->bt = furi_record_open(RECORD_BT); + + app->gui = furi_record_open(RECORD_GUI); + app->view_dispatcher = view_dispatcher_alloc(); + view_dispatcher_enable_queue(app->view_dispatcher); + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + // set submenu + app->submenu = submenu_alloc(); + view_set_previous_callback(submenu_get_view(app->submenu), fbp_exit); + view_dispatcher_add_view(app->view_dispatcher, FBPAppViewSubmenu, submenu_get_view(app->submenu)); + + // add Flipper Internal View + app->flipper_vibrator = flipper_vibrator_alloc(app); + submenu_add_item(app->submenu, "Flipper Internal Vibrator", FBPSubmenuIndexInternal, fbp_submenu_callback, app); + view_set_previous_callback(flipper_vibrator_get_view(app->flipper_vibrator), fbp_start_view); + view_dispatcher_add_view(app->view_dispatcher, FBPAppViewInternal, flipper_vibrator_get_view(app->flipper_vibrator)); + + // add GPIO Simple Motor View + app->gpio_simple_motor = gpio_simple_motor_alloc(app); + submenu_add_item(app->submenu, "Flipper GPIO Simple Motor", FBPSubmenuIndexGPIOSimpleMotor, fbp_submenu_callback, app); + view_set_previous_callback(gpio_simple_motor_get_view(app->gpio_simple_motor), fbp_start_view); + view_dispatcher_add_view(app->view_dispatcher, FBPAppViewGPIOSimpleMotor, gpio_simple_motor_get_view(app->gpio_simple_motor)); + + view_dispatcher_switch_to_view(app->view_dispatcher, FBPAppViewSubmenu); + return app; +} + +void fbs_free(FBP* app) { + furi_assert(app); + + // Free views + view_dispatcher_remove_view(app->view_dispatcher, FBPAppViewSubmenu); + submenu_free(app->submenu); + + // free Flipper Internal Vibrator + view_dispatcher_remove_view(app->view_dispatcher, FBPAppViewInternal); + flipper_vibrator_free(app->flipper_vibrator); + + // free GPIO Simple Motor + view_dispatcher_remove_view(app->view_dispatcher, FBPAppViewGPIOSimpleMotor); + gpio_simple_motor_free(app->gpio_simple_motor); + + // Other deallocations + view_dispatcher_free(app->view_dispatcher); + + + furi_record_close(RECORD_GUI); + app->gui = NULL; + + furi_mutex_free(app->app_mutex); + furi_message_queue_free(app->event_queue); + + furi_record_close(RECORD_BT); + app->bt = NULL; + + free(app); +} + +int32_t fbp_app(void* p) { + UNUSED(p); + FBP* app = fbp_alloc(); + + view_dispatcher_run(app->view_dispatcher); + + furi_hal_bt_serial_set_event_callback(0, NULL, NULL); + + fbs_free(app); + return 0; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/fbp.h b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/fbp.h new file mode 100644 index 000000000..bd669ad03 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/fbp.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include "tcode.h" +#include "views/internal.h" +#include "views/gpio_simple_motor.h" + +#define TAG "Flipper BP" + +typedef struct FBP FBP; + +struct FBP { + Submenu* submenu; + ViewDispatcher* view_dispatcher; + Gui* gui; + + Bt* bt; + bool bt_connected; + + FuriMutex* app_mutex; + FuriMessageQueue* event_queue; + + FlipperVibrator* flipper_vibrator; + GPIOSimpleMotor* gpio_simple_motor; +}; + +typedef enum { + FBPAppViewSubmenu, + FBPAppViewInternal, + FBPAppViewGPIOSimpleMotor, +} FBPAppView; \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/tcode.c b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/tcode.c new file mode 100644 index 000000000..d0699e201 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/tcode.c @@ -0,0 +1,183 @@ +#include "tcode.h" + +static TCodeCommandArray decode_device_command(const uint8_t *buffer, uint16_t size) { + TCodeCommandArray command_array; + if (size < 2) { + command_array.size = 0; + FURI_LOG_W("TCode Parser", "Unexpected code length for device command"); + return command_array; + } + + command_array.size = 1; + command_array.commands = malloc(sizeof(TCodeCommand)); + command_array.commands[0].command_type = Device; + + switch (buffer[1]) { + case '0': + FURI_LOG_T("TCode Parser", "Device Identification requested"); + command_array.commands[0].data.device_command = DeviceIdentification; + break; + case '1': + FURI_LOG_T("TCode Parser", "TCode version requested"); + command_array.commands[0].data.device_command = TCodeVersion; + break; + case '2': + FURI_LOG_T("TCode Parser", "Preferences list requested"); + command_array.commands[0].data.device_command = ListAxesAndUserRangePreferences; + break; + case 'S': + FURI_LOG_T("TCode Parser", "Stop requested"); + command_array.commands[0].data.device_command = Stop; + break; + default: + command_array.size = 0; + break; + } + + return command_array; +} + +static TCodeCommandArray decode_general_command(const uint8_t *buffer, uint16_t size) { + // size of the array = amount of spaces + 1 + uint16_t counter = 1; + for (uint16_t i = 0; i < size; i++) { + if (buffer[i] == 32) { + counter++; + } + } + + FURI_LOG_T("TCode Parser", "Found %u commands in the message", counter); + + TCodeCommandArray commands_array; + commands_array.size = counter; + commands_array.commands = malloc(commands_array.size * sizeof(TCodeCommand)); + + uint16_t position = 0; + for (uint16_t i = 0; i < counter; i++) { + TCodeCommand command; + command.command_type = Unknown; + + TCodeCommandMotionType motion_type; + switch (buffer[position]) { + case 'L': + case 'l': + motion_type = Linear; + break; + case 'R': + case 'r': + motion_type = Rotate; + break; + case 'V': + case 'v': + motion_type = Vibrate; + break; + case 'A': + case 'a': + motion_type = Auxiliary; + break; + default: // error + FURI_LOG_W("TCode Parser", "Unexpected motion type: %u", buffer[position]); + return commands_array; + } + FURI_LOG_T("TCode Parser", "Parsed motion_type: %u", motion_type); + position++; + + uint16_t channel = buffer[position] - 48; // single ascii character 0-9 + FURI_LOG_T("TCode Parser", "Parsed channel: %u", channel); + position++; + + // X characters that are digits + uint16_t current_position = position; + while (buffer[position] >= 48 && buffer[position] <= 57 && position < size) { + position++; + } + + uint8_t *magnitude = malloc(2 + (position - current_position) + 1); // "0.XXXX\0" + magnitude[0] = '0'; + magnitude[1] = '.'; + for (uint16_t x = 0; x < (position - current_position); x++) { + magnitude[x + 2] = buffer[current_position + x]; + } + magnitude[position - current_position + 2] = '\0'; + float magnitude_float = strtof((char *) magnitude, NULL); + free(magnitude); + FURI_LOG_T("TCode Parser", "Parsed magnitude: %f", (double) magnitude_float); + + FURI_LOG_T("TCode Parser REMOVE ME", "Current position: %u, size: %u", position, size); + FURI_LOG_T("TCode Parser REMOVE ME", "%u", buffer[position]); + if (position == size || buffer[position] == ' ' || buffer[position] == '\n') { + FURI_LOG_T("TCode Parser", "Command type: Magnitude"); + command.command_type = Magnitude; + command.data.magnitude_command.motion_type = motion_type; + command.data.magnitude_command.channel_id = channel; + command.data.magnitude_command.magnitude = magnitude_float; + commands_array.commands[i] = command; + position++; + continue; + } + + uint8_t current_step = buffer[position]; + position++; + + uint16_t int_value = 0; + while (buffer[position] >= 48 && buffer[position] <= 57 && position < size) { + int_value *= 10; + int_value += buffer[position] - 48; + position++; + } + + command.data.magnitude_time_interval_command.motion_type = motion_type; + command.data.magnitude_time_interval_command.channel_id = channel; + command.data.magnitude_time_interval_command.magnitude = magnitude_float; + + if (current_step == 'I' || current_step == 'i') { + FURI_LOG_T("TCode Parser", "Command type: MagnitudeTimeInterval"); + command.command_type = MagnitudeTimeInterval; + command.data.magnitude_time_interval_command.time_interval_milliseconds = int_value; + } + + if (current_step == 'S' || current_step == 's') { + FURI_LOG_T("TCode Parser", "Command type: MagnitudeSpeed"); + command.command_type = MagnitudeSpeed; + command.data.magnitude_speed_command.speed_per_hundred_milliseconds = int_value; + } + + if (command.command_type == Unknown) { + FURI_LOG_W("TCode Parser", "Unknown command type!"); + } + + commands_array.commands[i] = command; + position++; + if (position >= size) { + break; + } + } + + return commands_array; +} + +TCodeCommandArray tcode_decode(uint8_t *buffer, uint16_t size) { + switch (buffer[0]) { + case 'd': + case 'D': + FURI_LOG_T("TCode Parser", "Parsing device command..."); + return decode_device_command(buffer, size); + case 'l': + case 'L': + case 'r': + case 'R': + case 'v': + case 'V': + case 'a': + case 'A': + FURI_LOG_T("TCode Parser", "Parsing general command..."); + return decode_general_command(buffer, size); + default: // error + { + TCodeCommandArray error; + error.size = 0; + error.commands = NULL; + return error; + } + } +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/tcode.h b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/tcode.h new file mode 100644 index 000000000..7174965fe --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/tcode.h @@ -0,0 +1,63 @@ +#pragma once +#include + +typedef enum { + Device, + Magnitude, + MagnitudeTimeInterval, + MagnitudeSpeed, + Unknown, +} TCodeCommandType; + +typedef enum { + DeviceIdentification, + TCodeVersion, + ListAxesAndUserRangePreferences, + Stop, +} DeviceCommand; + +typedef enum { + Linear, + Rotate, + Vibrate, + Auxiliary, +} TCodeCommandMotionType; + +typedef struct { + TCodeCommandMotionType motion_type; + uint8_t channel_id; + float magnitude; +} TCodeMagnitudeCommand; + +typedef struct { + TCodeCommandMotionType motion_type; + uint8_t channel_id; + float magnitude; + uint16_t time_interval_milliseconds; +} TCodeMagnitudeTimeIntervalCommand; + +typedef struct { + TCodeCommandMotionType motion_type; + uint8_t channel_id; + float magnitude; + uint16_t speed_per_hundred_milliseconds; +} TCodeMagnitudeSpeedCommand; + + +typedef struct { + TCodeCommandType command_type; + union { + DeviceCommand device_command; + TCodeMagnitudeCommand magnitude_command; + TCodeMagnitudeTimeIntervalCommand magnitude_time_interval_command; + TCodeMagnitudeSpeedCommand magnitude_speed_command; + } data; +} TCodeCommand; + +typedef struct { + uint16_t size; + TCodeCommand *commands; +} TCodeCommandArray; + + +TCodeCommandArray tcode_decode(uint8_t *buffer, uint16_t size); \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/uart_10px.png b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/uart_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..8420f569279aa5ca170da19d080fd27f61b4339c GIT binary patch literal 1883 zcmcIlO^72!6z&~VbYxWUvIs(N?;25X-v&lFK*fSv$c1OHesj5zzNxFKv zJCn?y7xCgj5JVAKyom@RBB%$!MGu}mdJw#O5l?~_eVxA@b#@#U3?yBt{_1<*d+)2N zH(J|UYpYMJDvGk!Y}DKEEXS)4uE6g~Yws6$Jd`$G%oXL~$II^p<^5Y173G0%;?7>N z7rqcMIn*haU7=5gDWDbQ+WI7=Y+n>=SM=hfs{Q))ZB31NRlDhgI81AzA2*IOv3tDT zVaNN-=i2&n>a|G#1Vd3!but_zc`&JJQ{Di^<+P!xQ%JF2)i%n2>R#AVYcdn6t7F74 zCThjkP1m+P?^%^#f(=|TOpFK#up2m*I{#=8E#pzpu0KDI1^=pAzbMkcFvjDtKDKn3 z^$gSZeFGDN5CjO6A0-8ypd`P%V5p0nWpP@>GEqxL+LfcCs)5p33d3|so8*gS+NbG@e$=bfWe7;TZuQO3mPp-76$i(s5B*QTRvFwK-R zLkz?aU^xggm!Z&a9i0an zhCwsQ3z{&|tXDMxWcW%fMZ#qz^S;DR2+ePhg0PHwvD=;VFxyI|ItfO;OcY z=?1~I`E-0rna`KdjCR}?KzfEtX0TjF#h7MdqX#YdPZt_@6Q9$=v!&aNVrpY(gJ2Gd zh)oggMlOnQ{^`kgKYR1w(jV=$#&;iGIr!?vQ?dEQ>mTlH{W$vgv8!)?a%u2`GV#_g{QmvU em*#svf3EDVT)F?1TY9Cu{+gTH^-r(A{Muh4WJ_-V literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/views/gpio_simple_motor.c b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/views/gpio_simple_motor.c new file mode 100644 index 000000000..5fef098dc --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/views/gpio_simple_motor.c @@ -0,0 +1,149 @@ +#include "gpio_simple_motor.h" +#include "../fbp.h" + +static const uint16_t BT_SERIAL_BUFFER_SIZE = 128; +static const uint32_t DEFAULT_FREQ = 1000; +static const FuriHalPwmOutputId DEFAULT_PWM_OUTPUT_ID = FuriHalPwmOutputIdTim1PA7; + +struct GPIOSimpleMotor { + View* view; + FBP* fbp; + + uint8_t current_pwm_duty; +}; + +typedef struct { + char* display_text_1; + char* display_text_2; + char* display_text_3; +} GPIOSimpleMotorModel; + + +static void process_general_command(TCodeCommand command, GPIOSimpleMotor* motor) { + if (command.command_type == Magnitude && command.data.magnitude_command.motion_type == Vibrate && command.data.magnitude_command.channel_id == 0) { + // just enable vibration on X + uint8_t new_duty = (uint8_t) (command.data.magnitude_command.magnitude * 100); + if (new_duty > 100) { + new_duty = 100; + } + FURI_LOG_D(TAG, "Setting vibration power on %u", new_duty); + + // using Pulse-Widht Modulation to control a motor via a transistor + // just google for a typical arduino + PWM + motor scheme + if (new_duty == 0) { + furi_hal_pwm_stop(DEFAULT_PWM_OUTPUT_ID); + } else if (motor->current_pwm_duty == 0) { + furi_hal_pwm_start(DEFAULT_PWM_OUTPUT_ID, DEFAULT_FREQ, new_duty); + } else { + furi_hal_pwm_set_params(DEFAULT_PWM_OUTPUT_ID, DEFAULT_FREQ, new_duty); + } + motor->current_pwm_duty = new_duty; + return; + } +} + +static uint16_t bt_serial_event_callback(SerialServiceEvent event, void* context) { + furi_assert(context); + GPIOSimpleMotor* motor = context; + + if(event.event == SerialServiceEventTypeDataReceived) { + TCodeCommandArray commands = tcode_decode(event.data.buffer, event.data.size); + FURI_LOG_D(TAG, "Decoded commands array size: %u", commands.size); + for (uint16_t i = 0; i < commands.size; i++) { + FURI_LOG_D(TAG, "Command #%u, type: %u\n", i, commands.commands[i].command_type); + } + for (uint16_t i = 0; i < commands.size; i++) { + // looking for first vibro command to execute + TCodeCommand current_command = commands.commands[i]; + TCodeCommandType type = current_command.command_type; + if ((type == Magnitude || type == MagnitudeSpeed || type == MagnitudeTimeInterval)) { + process_general_command(current_command, motor); + } + } + } + return 0; +} + +static bool input_callback(InputEvent* event, void* ctx) { + furi_assert(ctx); + GPIOSimpleMotor* motor = ctx; + if(event->key == InputKeyBack) { + furi_hal_bt_serial_set_event_callback(0, NULL, NULL); + return false; + } + + if (event->key == InputKeyOk) { + if (furi_hal_bt_is_active()) { + FURI_LOG_D(TAG, "BT is working, hijacking the serial connection..."); + furi_hal_bt_start_advertising(); + furi_hal_bt_serial_set_event_callback(BT_SERIAL_BUFFER_SIZE, bt_serial_event_callback, motor); + + with_view_model( + motor->view, + GPIOSimpleMotorModel * model, + { + model->display_text_1 = ""; + model->display_text_2 = "Ready ^_^"; + model->display_text_3 = ""; + }, + true); + + } else { + FURI_LOG_E(TAG, "Please, enable the Bluetooth and restart the app"); + + with_view_model( + motor->view, + GPIOSimpleMotorModel * model, + { + model->display_text_1 = "Error:"; + model->display_text_2 = "Bluetooth is not enabled"; + model->display_text_3 = ""; + }, + true); + } + } + return true; +} + +static void draw_callback(Canvas* canvas, void* ctx) { + furi_assert(ctx); + GPIOSimpleMotorModel* app = ctx; + canvas_draw_str_aligned(canvas, 64, 24, AlignCenter, AlignCenter, (char*)app->display_text_1); + canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignCenter, (char*)app->display_text_2); + canvas_draw_str_aligned(canvas, 64, 40, AlignCenter, AlignCenter, (char*)app->display_text_3); +} + +GPIOSimpleMotor* gpio_simple_motor_alloc(FBP* fbp) { + furi_assert(fbp); + GPIOSimpleMotor* motor = malloc(sizeof(GPIOSimpleMotor)); + motor->view = view_alloc(); + motor->fbp = fbp; + view_set_context(motor->view, motor); + view_allocate_model(motor->view, ViewModelTypeLocking, sizeof(GPIOSimpleMotorModel)); + view_set_draw_callback(motor->view, draw_callback); + view_set_input_callback(motor->view, input_callback); + + with_view_model( + motor->view, + GPIOSimpleMotorModel * model, + { + model->display_text_1 = "Please, connect the"; + model->display_text_2 = "transistor base to pin A7!"; + model->display_text_3 = "Press OK to start"; + }, + true); + + return motor; +} + +void gpio_simple_motor_free(GPIOSimpleMotor* motor) { + furi_assert(motor); + furi_hal_pwm_stop(DEFAULT_PWM_OUTPUT_ID); + view_free(motor->view); + free(motor); +} + +View* gpio_simple_motor_get_view(GPIOSimpleMotor* motor) { + furi_assert(motor); + return motor->view; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/views/gpio_simple_motor.h b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/views/gpio_simple_motor.h new file mode 100644 index 000000000..e2668a45d --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/views/gpio_simple_motor.h @@ -0,0 +1,13 @@ +#pragma once +#include +#include +#include + +typedef struct FBP FBP; +typedef struct GPIOSimpleMotor GPIOSimpleMotor; + +GPIOSimpleMotor* gpio_simple_motor_alloc(FBP* fbp); + +void gpio_simple_motor_free(GPIOSimpleMotor* motor_app); + +View* gpio_simple_motor_get_view(GPIOSimpleMotor* motor_app); diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/views/internal.c b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/views/internal.c new file mode 100644 index 000000000..8d458d920 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/views/internal.c @@ -0,0 +1,133 @@ +#include "internal.h" +#include "../fbp.h" + +static const uint16_t BT_SERIAL_BUFFER_SIZE = 128; + +struct FlipperVibrator { + View* view; + FBP* fbp; +}; + +typedef struct { + char* display_text; +} FlipperVibratorModel; + + +static void process_general_command(TCodeCommand command) { + if (command.command_type == Magnitude && command.data.magnitude_command.motion_type == Vibrate && command.data.magnitude_command.channel_id == 0) { + furi_hal_vibro_on(command.data.magnitude_command.magnitude > 0.1f); + return; + } + + if (command.command_type == MagnitudeSpeed && command.data.magnitude_speed_command.motion_type == Vibrate && command.data.magnitude_speed_command.channel_id == 0) { + furi_hal_vibro_on(command.data.magnitude_speed_command.magnitude > 0.1f); + return; + } + + if (command.command_type == MagnitudeTimeInterval && command.data.magnitude_time_interval_command.motion_type == Vibrate && command.data.magnitude_time_interval_command.channel_id == 0) { + furi_hal_vibro_on(command.data.magnitude_time_interval_command.magnitude > 0.1f); + return; + } +} + + +static uint16_t bt_serial_event_callback(SerialServiceEvent event, void* context) { + furi_assert(context); + FlipperVibrator* flipper_vibrator = context; + UNUSED(flipper_vibrator); + + if(event.event == SerialServiceEventTypeDataReceived) { + FURI_LOG_D(TAG, "SerialServiceEventTypeDataReceived"); + FURI_LOG_D(TAG, "Size: %u", event.data.size); + FURI_LOG_D(TAG, "Data: "); + for (size_t i = 0; i < event.data.size; i++) + { + printf("%X ", event.data.buffer[i]); + } + printf("\r\n"); + + TCodeCommandArray commands = tcode_decode(event.data.buffer, event.data.size); + FURI_LOG_D(TAG, "Decoded commands array size: %u", commands.size); + for (uint16_t i = 0; i < commands.size; i++) { + FURI_LOG_D(TAG, "Command #%u, type: %u\n", i, commands.commands[i].command_type); + } + for (uint16_t i = 0; i < commands.size; i++) { + // looking for first vibro command to execute + TCodeCommand current_command = commands.commands[i]; + TCodeCommandType type = current_command.command_type; + if ((type == Magnitude || type == MagnitudeSpeed || type == MagnitudeTimeInterval)) { + process_general_command(current_command); + } + } + } + return 0; +} + +static bool input_callback(InputEvent* event, void* ctx) { + furi_assert(ctx); + FlipperVibrator* flipper_vibrator = ctx; + if(event->key == InputKeyBack) { + furi_hal_bt_serial_set_event_callback(0, NULL, NULL); + return false; + } + + if (event->key == InputKeyOk) { + if (furi_hal_bt_is_active()) { + FURI_LOG_D(TAG, "BT is working, hijacking the serial connection..."); + furi_hal_bt_start_advertising(); + furi_hal_bt_serial_set_event_callback(BT_SERIAL_BUFFER_SIZE, bt_serial_event_callback, flipper_vibrator); + + with_view_model( + flipper_vibrator->view, + FlipperVibratorModel * model, + { model->display_text = "Ready ^_^"; }, + true); + + } else { + FURI_LOG_E(TAG, "Please, enable the Bluetooth and restart the app"); + + with_view_model( + flipper_vibrator->view, + FlipperVibratorModel * model, + { model->display_text = "Error: Bluetooth not enabled"; }, + true); + } + } + return true; +} + +static void draw_callback(Canvas* canvas, void* ctx) { + furi_assert(ctx); + FlipperVibratorModel* app = ctx; + canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignCenter, (char*)app->display_text); +} + +FlipperVibrator* flipper_vibrator_alloc(FBP* fbp) { + furi_assert(fbp); + FlipperVibrator* flipper_vibrator = malloc(sizeof(FlipperVibrator)); + flipper_vibrator->view = view_alloc(); + flipper_vibrator->fbp = fbp; + view_set_context(flipper_vibrator->view, flipper_vibrator); + view_allocate_model(flipper_vibrator->view, ViewModelTypeLocking, sizeof(FlipperVibratorModel)); + view_set_draw_callback(flipper_vibrator->view, draw_callback); + view_set_input_callback(flipper_vibrator->view, input_callback); + + with_view_model( + flipper_vibrator->view, + FlipperVibratorModel * model, + { model->display_text = "Press OK to start"; }, + true); + + return flipper_vibrator; +} + +void flipper_vibrator_free(FlipperVibrator* flipper_vibrator) { + furi_assert(flipper_vibrator); + view_free(flipper_vibrator->view); + free(flipper_vibrator); +} + +View* flipper_vibrator_get_view(FlipperVibrator* flipper_vibrator) { + furi_assert(flipper_vibrator); + return flipper_vibrator->view; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/views/internal.h b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/views/internal.h new file mode 100644 index 000000000..40206bbff --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-bp/views/internal.h @@ -0,0 +1,12 @@ +#pragma once +#include +#include + +typedef struct FBP FBP; +typedef struct FlipperVibrator FlipperVibrator; + +FlipperVibrator* flipper_vibrator_alloc(FBP* fbp); + +void flipper_vibrator_free(FlipperVibrator* flipper_vibrator); + +View* flipper_vibrator_get_view(FlipperVibrator* flipper_vibrator); diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/.gitignore b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/.gitignore new file mode 100644 index 000000000..c6127b38c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/.gitignore @@ -0,0 +1,52 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/LICENSE.txt b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/LICENSE.txt new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/README.md b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/README.md new file mode 100644 index 000000000..138826184 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/README.md @@ -0,0 +1,22 @@ +# Flipper DCF77 +Sends the DCF77 time signal (badly) on the 125khz LFRFID antenna. This should allow you to update [radio clocks](https://en.wikipedia.org/wiki/Radio_clock). You can send it at the original 77.5kHz, but I've had better range using 155kHz. The baseband signal is output on C3. + +Building a portable antenna for the LF/VLF band is left as an exercise for the reader. + +# technical details + +* It works on every clock I own _eventually_. DCF77 is slow, it sends a complete update once per minute. Sometimes it works on the first try, sometimes I have to wait more than 5 attempts +* Implementation is using a software kernel timer (`furi_timer_start`) to generate the signal +* Implementation is wonky and although FZ is FreeRTOS, this software timer is hit and miss. 30Hz seems to work best for generating the baseband signal. More interrupts seem to overlap and are significantly delayed. Less interrupts are sometimes (still!) delayed or missed, but less interrupts means the baseband signal gets distorted more during a miss +* The baseband signal encodes 0 as an 800ms mark, 1 as a 900ms mark and second 59 of each minute is marked with the carrier being on continuously - this is the ASK modulation. There's also a PSK modulation which FZ is not doing. +* The transmitter is not off between marks, but is still transmitting at reduced power. This is rarely visible outside Germany +* The antenna is highly mistuned for this purpose (sending 77500Hz on a 125000Hz aerial is about 33% off). You can try the 155k harmonic, which is only 20% off. I have seen working attempts using speaker generated EMF at 15500 Hz. +* Combine the slow signal, wonky software timer and very mistuned antenna and YMMV + +# todo + +* menus! make it more flipper! +* configurable simulated data (encoding the time `25:69` is possible) +* simulate it just as a timezone offset (for changing clocks around your house according to your country's choice of DST madness) +* RBU, ALS162, WWVB, other time signals + diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/application.fam b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/application.fam new file mode 100644 index 000000000..52ddf1e00 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/application.fam @@ -0,0 +1,12 @@ +App( + appid="dcf77", + name="DCF77 Transmitter", + apptype=FlipperAppType.PLUGIN, + entry_point="dcf77_app_main", + cdefines=["APP_DCF77"], + requires=["gui"], + stack_size=1 * 1024, + order=10, + fap_icon="icons/app.png", + fap_category="Misc_Extra", +) diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/dcf77_app.c b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/dcf77_app.c new file mode 100644 index 000000000..86381de91 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/dcf77_app.c @@ -0,0 +1,445 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "dcf77_app.h" + +uint8_t get_dcf_message_bit(uint8_t* message, uint8_t bit) +{ + if (bit == 59 || bit == 0) + { + return 0; + } + + uint8_t byte_ = bit / 8; + uint8_t bit_ = bit % 8; + + uint8_t bit_value = *(message+byte_) & (1 << (7-bit_)); + + if (!!bit_value) + { + return 1; + } + return 0; +} + +// should it still be const? +static void update_dcf77_message_from_rtc(AppFSM* app_fsm) +{ + FuriHalRtcDateTime dt; + furi_hal_rtc_get_datetime(&dt); + app_fsm->bit_number = dt.second; + app_fsm->next_message = malloc(8); + /* + set_dcf_message(app_fsm->next_message, dt.minute, dt.hour, + dt.day, dt.month, (uint8_t)(dt.year % 100), dt.weekday, + false, false, false, false, 0x0000); + */ + + //set_dcf_message(app_fsm->next_message, 41, 17, 27, 12, 22, 2, false, false, false, false, 0x0000); + + app_fsm->tx_hour = 17; + app_fsm->tx_minute = 41; + app_fsm->tx_day = 27; + app_fsm->tx_month = 12; + app_fsm->tx_year = 22; + app_fsm->tx_dow = 2; + + + app_fsm->tx_hour = dt.hour; + app_fsm->tx_minute = dt.minute; + app_fsm->tx_day = dt.day; + app_fsm->tx_month = dt.month; + app_fsm->tx_year = dt.year % 100; + app_fsm->tx_dow = dt.weekday; + + set_dcf_message(app_fsm->next_message, app_fsm->tx_minute, app_fsm->tx_hour, app_fsm->tx_day, app_fsm->tx_month, + app_fsm->tx_year, app_fsm->tx_dow, false, false, false, false, 0x0000); + app_fsm->buffer_swap_pending = true; +} + +static void set_outputs(bool status, AppFSM* app_fsm) +{ + UNUSED(app_fsm); + static bool last; + if (last != status) + { + if (status) + { + furi_hal_light_set(LightRed, 0xFF); + furi_hal_light_set(LightGreen, 0x1F); + // furi_hal_speaker_start(50, 1); + + } + else + { + furi_hal_light_set(LightRed | LightGreen | LightBlue, 0); + // furi_hal_speaker_stop(); + } + } + last = status; +} + +static void comparator_trigger_callback(bool level, void *comp_ctx) { + UNUSED(comp_ctx); + furi_hal_gpio_write(&gpio_ext_pa7, !level); +} + + +void gpio_init() +{ + furi_hal_gpio_write(OUTPUT_PIN, false); + furi_hal_gpio_init(OUTPUT_PIN, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); +} + +void gpio_mark() +{ + furi_hal_gpio_write(OUTPUT_PIN, true); +} + + +void gpio_space() +{ + furi_hal_gpio_write(OUTPUT_PIN, false); +} + +void gpio_deinit() +{ + furi_hal_gpio_init(OUTPUT_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedVeryHigh); +} + +void dcf77_lf_init(int freq, AppFSM* app_fsm) +{ + /* // this ends up doing + // LL_TIM_SetAutoReload(FURI_HAL_RFID_READ_TIMER, period); + // LL_TIM_OC_SetCompareCH1(FURI_HAL_RFID_READ_TIMER, period*duty_cycle); + */ + + furi_hal_rfid_tim_reset(); + furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull); + furi_hal_rfid_comp_set_callback(comparator_trigger_callback, app_fsm); + furi_hal_rfid_pins_read(); + furi_hal_rfid_tim_read(freq, 0.5); +} + +void dcf77_mark(int freq) +{ + furi_hal_rfid_tim_reset(); + furi_hal_rfid_tim_read(freq, 0.5); + furi_hal_rfid_comp_start(); + furi_hal_rfid_tim_read_start(); + /* --- */ + furi_hal_rfid_comp_stop(); + furi_hal_rfid_tim_read_stop(); +} + +void dcf77_space() +{ + furi_hal_rfid_comp_stop(); + furi_hal_rfid_tim_read_stop(); +} + +void dcf77_deinit() +{ + dcf77_space(); + furi_hal_rfid_comp_stop(); + furi_hal_rfid_comp_set_callback(NULL, NULL); + furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog); + furi_hal_rfid_tim_read_stop(); + furi_hal_rfid_tim_reset(); + furi_hal_rfid_pins_reset(); +} + +static void render_callback(Canvas* const canvas, void* ctx) +{ + // const AppFSM* app_fsm = acquire_mutex((ValueMutex*)ctx, 25); + AppFSM* app_fsm = acquire_mutex((ValueMutex*)ctx, 25); + if(app_fsm == NULL) { + return; + } + + char buffer[64]; + uint8_t yoffset = 9; + uint8_t bit_number = app_fsm->bit_number; + uint8_t bit_value = app_fsm->bit_value; + uint8_t underline_x = (bit_number/8) * 12 + 16; + uint8_t byte_ = app_fsm->dcf77_message[bit_number/8]; + char display_bits[9] = "00000000"; + + if (app_fsm->buffer_swap_pending) + { + memcpy(app_fsm->dcf77_message, app_fsm->next_message, 8); + canvas_draw_str_aligned(canvas, 112, 10, AlignCenter, AlignBottom, "*"); + app_fsm->buffer_swap_pending = false; + } + + + canvas_draw_frame(canvas, 0, 0, 128, 64); + canvas_set_font(canvas, FontPrimary); + snprintf(buffer, 64, "%1x.%1x=%01x", bit_number/8, (bit_number%8), bit_value); + FuriHalRtcDateTime dt; + furi_hal_rtc_get_datetime(&dt); + //canvas_draw_str_aligned(canvas, 64, 10, AlignCenter, AlignBottom, "DCF77 emulator"); + snprintf(buffer, 64, "%02d:%02d %02d.%02d.%02d", app_fsm->tx_hour, app_fsm->tx_minute, app_fsm->tx_day, app_fsm->tx_month, + app_fsm->tx_year); + canvas_draw_str_aligned(canvas, 64, 10, AlignCenter, AlignBottom, buffer); + + if (app_fsm->debug_flag) + { + canvas_draw_str_aligned(canvas, 8, 10, AlignCenter, AlignBottom, "D"); + } + + snprintf(buffer, 64, "%1x.%1x=%01x", bit_number/8, (bit_number%8), bit_value); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned(canvas, 64, 24 + (9 - yoffset), AlignCenter, AlignBottom, buffer); + + snprintf(buffer, 64, "%s (bit %d)", dcf77_bitnames[bit_number], bit_value); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str_aligned(canvas, 64, 34 + (9 - yoffset), AlignCenter, AlignBottom, buffer); + + + + snprintf(buffer, 64, "%02x%02x%02x%02x%02x%02x%02x%02x", + app_fsm->dcf77_message[0], app_fsm->dcf77_message[1], app_fsm->dcf77_message[2], app_fsm->dcf77_message[3], + app_fsm->dcf77_message[4], app_fsm->dcf77_message[5], app_fsm->dcf77_message[6], app_fsm->dcf77_message[7] ); + canvas_set_font(canvas, FontKeyboard); + canvas_draw_str_aligned(canvas, 64, 44 + (9 - yoffset), AlignCenter, AlignBottom, buffer); + + + canvas_draw_line(canvas, underline_x, 45, underline_x+10, 45); + for(int i = 0; i < 8; i++) + { + if ((byte_ & (1 << (7-i))) != 0) + { + display_bits[i] = '1'; + } + } + + canvas_set_font(canvas, FontKeyboard); + snprintf(buffer, 64, "%02x=%s", byte_, display_bits); + canvas_draw_str_aligned(canvas, 64, 54 + (9 - yoffset), AlignCenter, AlignBottom, buffer); // whole message + underline_x = (bit_number%8) * 6 + 49; + canvas_draw_line(canvas, underline_x, 55, underline_x+4, 55); // current byte + + release_mutex((ValueMutex*)ctx, app_fsm); +} + +static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { + furi_assert(event_queue); + + AppEvent event = {.type = EventKeyPress, .input = *input_event}; + furi_message_queue_put(event_queue, &event, FuriWaitForever); +} + +static void timer_tick_callback(FuriMessageQueue* event_queue) { + furi_assert(event_queue); + + AppEvent event = {.type = EventTimerTick}; + furi_message_queue_put(event_queue, &event, 0); +} + +static void app_init(AppFSM* const app_fsm, FuriMessageQueue* event_queue) { + + app_fsm->counter = 0; + app_fsm->dcf77_message = &dcf77_message_buffer[0]; + app_fsm->next_message = &dcf77_next_buffer[0]; + + dcf77_lf_init(LF_FREQ, app_fsm); + gpio_init(); + + app_fsm->dcf77_message = malloc(8); // message had 60 bits since 1959 and is unlikely to change + // app_fsm->next_message = malloc(8); + update_dcf77_message_from_rtc(app_fsm); + app_fsm->baseband_counter = 0; + + app_fsm->_event_queue = event_queue; + FuriTimer* timer = furi_timer_alloc(timer_tick_callback, FuriTimerTypePeriodic, app_fsm->_event_queue); + furi_timer_start(timer, furi_kernel_get_tick_frequency() / TIMER_HZ); + app_fsm->_timer = timer; +} + +static void app_deinit(AppFSM* const app_fsm) { + dcf77_deinit(); + gpio_deinit(); + app_fsm->buffer_swap_pending = false; + free(app_fsm->dcf77_message); + furi_timer_free(app_fsm->_timer); +} + +static void on_timer_tick(AppFSM* app_fsm) +{ + static uint8_t last_second = 61; + static bool last_output = false; + bool output = true; + + FuriHalRtcDateTime dt; + furi_hal_rtc_get_datetime(&dt); + app_fsm->bit_number = dt.second; + app_fsm->bit_value = get_dcf_message_bit(app_fsm->dcf77_message, app_fsm->bit_number); + + if (dt.second != last_second) + { + app_fsm->baseband_counter = 0; + output = true; + } + else + { + app_fsm->baseband_counter++; + } + + /* + if (app_fsm->baseband_counter < 8) + { + app_fsm->debug_flag = true; + } + else + { + app_fsm->debug_flag = false; + }*/ + + if (dt.second == 0 && app_fsm->baseband_counter == 3) + { + update_dcf77_message_from_rtc(app_fsm); + } + + if (dt.second == 59) + { + output = true; + } + else + { + if (app_fsm->baseband_counter > TIME_ZERO && app_fsm->bit_value == 0) + { + output = false; + + } + else if (app_fsm->baseband_counter > TIME_ONE && app_fsm->bit_value == 1) + { + output = false; + } + } + + + if (last_output != output) + { + set_outputs(output, app_fsm); + if (!output) + { + dcf77_space(); + gpio_space(); + } + else + { + dcf77_mark(LF_FREQ); + gpio_mark(); + } + } + + last_second = dt.second; + last_output = output; +} + + +int32_t dcf77_app_main(void* p) { + UNUSED(p); + + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(AppEvent)); + AppFSM* app_fsm = malloc(sizeof(AppFSM)); + app_init(app_fsm, event_queue); + + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, app_fsm, sizeof(AppFSM))) { + FURI_LOG_E(TAG, "cannot create mutex\r\n"); + free(app_fsm); + return 255; + } + + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, render_callback, &state_mutex); + view_port_input_callback_set(view_port, input_callback, event_queue); + + // Open GUI and register view_port + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + notification_message_block(notification, &sequence_display_backlight_enforce_on); + + + if (furi_hal_speaker_acquire(500)) + { + ; + } + + + DOLPHIN_DEED(DolphinDeedPluginGameStart); + + AppEvent event; + for(bool processing = true; processing;) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); + + AppFSM* app_fsm = (AppFSM*)acquire_mutex_block(&state_mutex); + + if(event_status == FuriStatusOk) { + // kepress events + if(event.type == EventKeyPress) { + if(event.input.type == InputTypePress) { + switch(event.input.key) { + case InputKeyUp: + app_fsm->last_key = KeyUp; + break; + case InputKeyDown: + app_fsm->last_key = KeyDown; + break; + case InputKeyRight: + app_fsm->last_key = KeyRight; + break; + case InputKeyLeft: + app_fsm->last_key = KeyLeft; + break; + case InputKeyOk: + app_fsm->last_key = KeyOK; + app_fsm->counter = -5; + break; + case InputKeyBack: + processing = false; + break; + default: + break; + } + } + // user events + } else if(event.type == EventTimerTick) { + FURI_CRITICAL_ENTER(); + on_timer_tick(app_fsm); + FURI_CRITICAL_EXIT(); + } + } else { + // event timeout + } + + view_port_update(view_port); + release_mutex(&state_mutex, app_fsm); + } + furi_hal_speaker_release(); + notification_message_block(notification, &seq_c_minor); + + // Wait for all notifications to be played and return backlight to normal state + app_deinit(app_fsm); + + notification_message_block(notification, &sequence_display_backlight_enforce_auto); + + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); + view_port_free(view_port); + furi_message_queue_free(event_queue); + delete_mutex(&state_mutex); + free(app_fsm); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/dcf77_app.h b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/dcf77_app.h new file mode 100644 index 000000000..94e06495a --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/dcf77_app.h @@ -0,0 +1,168 @@ +#ifndef __ARHA_FLIPPERAPP_DEMO +#define __ARHA_FLIPPERAPP_DEMO + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "dcf77_util.h" + +// the TAG is used for displaying a relevant prefix in logs. update it. +#define TAG "__ARHA_FLIPPERAPP" +#define TIMER_HZ 30 +#define TIME_ZERO 24 +#define TIME_ONE 27 +#define LF_FREQ 77500 * 2 +#define OUTPUT_PIN &gpio_ext_pc3 +// #define TIME_ZERO 15 +// #define TIME_ONE 5 + + +uint8_t dcf77_message_buffer[8]; +uint8_t dcf77_next_buffer[8]; + +typedef enum { + KeyNone, + KeyUp, + KeyRight, + KeyDown, + KeyLeft, + KeyOK +} KeyCode; + + +typedef enum { + EventTimerTick, + EventKeyPress, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} AppEvent; + +typedef struct { + uint16_t len; + KeyCode last_key; + + FuriTimer* _timer; + FuriMessageQueue* _event_queue; + + int counter; + + uint8_t bit_number; // 0 - 59 + uint8_t bit_value; // 0 or 1 for actual bits, 2 for end-of-minute marker + uint8_t baseband_counter; // 0 - 20, so we can generate 800 and 900 ms wide pulses (bit0 = 800ms = 16; bit1 = 900ms = 18; bit2 = 1000ms = 20) + uint8_t* dcf77_message; // these are 8 bytes which encode, LSB, every bit in the DCF77 message. see set_dcf_message() + uint8_t* next_message; + + bool buffer_swap_pending; + bool debug_flag; + + uint8_t tx_minute; + uint8_t tx_hour; + uint8_t tx_day; + uint8_t tx_month; + uint8_t tx_year; + uint8_t tx_dow; +} AppFSM; + + +const NotificationSequence seq_c_minor = { + &message_note_c4, + &message_delay_100, + &message_sound_off, + &message_delay_10, + + &message_note_ds4, + &message_delay_100, + &message_sound_off, + &message_delay_10, + + &message_note_g4, + &message_delay_100, + &message_sound_off, + &message_delay_10, + + &message_vibro_on, + &message_delay_50, + &message_vibro_off, + NULL, +}; + +const char *dcf77_bitnames[] = { + "Start minute", + "Civil 1", + "Civil 2", + "Civil 3", + "Civil 4", + "Civil 5", + "Civil 6", + "Civil 7", + "Civil 8", + "Civil 9", + "Civil 10", + "Civil 11", + "Civil 12", + "Civil 13", + "Civil 14", + "Abnormal", + "DST change", + "UTC+02", + "UTC+01", + "Leap sec", + "Start time", + "Minutes 1", + "Minutes 2", + "Minutes 3", + "Minutes 4", + "Minutes 5", + "Minutes 6", + "Minutes 7", + "Minutes P", + "Hours 1", + "Hours 2", + "Hours 3", + "Hours 4", + "Hours 5", + "Hours 6", + "Hours P", + "Day 1", + "Day 2", + "Day 3", + "Day 4", + "Day 5", + "Day 6", + "Weekday 1", + "Weekday 2", + "Weekday 4", + "Month 1", + "Month 2", + "Month 3", + "Month 4", + "Month 5", + "Year 1", + "Year 2", + "Year 3", + "Year 4", + "Year 5", + "Year 6", + "Year 7", + "Year 8", + "Date P", + "End" +}; + +#endif \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/dcf77_util.c b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/dcf77_util.c new file mode 100644 index 000000000..3ed2dd1cf --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/dcf77_util.c @@ -0,0 +1,135 @@ +#include "dcf77_util.h" + +void set_dcf_message(uint8_t* dest, uint8_t minute, uint8_t hour, + uint8_t day, uint8_t month, uint8_t year, uint8_t dow, + bool dst, bool predst, bool abnormal, bool leap, uint16_t civbits) +{ + uint8_t bcd_minute = 0; + uint8_t bcd_hour = 0; + uint8_t bcd_day = 0; + uint8_t bcd_month = 0; + uint8_t bcd_year = 0; + + /* converting binary to bcd (which looks like hex, without the a-f digits) + this is very common in old-school electronics */ + bcd_minute = ((minute / 10) << 4) | (minute % 10); + bcd_hour = ((hour / 10) << 4) | (hour % 10); + bcd_day = ((day / 10) << 4) | (day % 10); + bcd_month = ((month / 10) << 4) | (month % 10); + bcd_year = ((year / 10) << 4) | (year % 10); + + /* parity bits */ + bool p_minute = 1; + bool p_hour = 1; + bool p_date = 1; + + for (int i = 0; i < 8; i++) + { + p_minute ^= !!(bcd_minute & (1 << i)); + p_hour ^= !!(bcd_hour & (1 << i)); + + p_date = !!(bcd_day & (1 << i)); + p_date = !!(bcd_month & (1 << i)); + p_date = !!(bcd_year & (1 << i)); + p_date = !!((dow & 0x07) & (1 << i)); + } + + dest[0] = (uint8_t)(civbits >> 7); + dest[1] = ((civbits & 0x7F) << 1) | abnormal; + + // d2: 16-23; 16=adst, 17=dst, 18=!dsst, 19=leap, 20=1, 21-22-23 are minute lsb 1, 2, 3 + dest[2] = (predst << 7) | (dst << 6) | (!dst << 5) | (leap << 4) | (1 << 3); + dest[2]|= BBIT(bcd_minute, 0) << 2; + dest[2]|= BBIT(bcd_minute, 1) << 1; + dest[2]|= BBIT(bcd_minute, 2) << 0; + //dest[2]|= (bcd_minute & (1 << 2)); + + dest[3] =0; + // DCF bit 24 is byte 3, bit 7 + dest[3]|= BBIT(bcd_minute, 3) << 7; + // DCF bit 25 is byte 3, bit 6 + dest[3]|= BBIT(bcd_minute, 4) << 6; + // DCF bit 26 is byte 3, bit 5 + dest[3]|= BBIT(bcd_minute, 5) << 5; + // DCF bit 27 is byte 3, bit 4 + dest[3]|= BBIT(bcd_minute, 6) << 4; + // DCF bit 28 is byte 3, bit 3 (E parity, minutes) + dest[3]|= p_minute << 3; + // DCF bit 29 is byte 3, bit 2 + dest[3]|= BBIT(bcd_hour, 0) << 2; + // DCF bit 30 is byte 3, bit 1 + dest[3]|= BBIT(bcd_hour, 1) << 1; + // DCF bit 31 is byte 3, bit 0 + dest[3]|= BBIT(bcd_hour, 2) << 0; + + // d3: 24-31, 24-27 min lsb 3-6; 28=p, 29-31: hours lsb 0-2 + //dest[3] = bcd_minute << 3 | (p_minute << 3); + + // d4: 32-39 + dest[4] =0; + // DCF bit 32 is byte 4, bit 7 + dest[4]|= BBIT(bcd_hour, 3) << 7; + // DCF bit 33 is byte 4, bit 6 + dest[4]|= BBIT(bcd_hour, 4) << 6; + // DCF bit 34 is byte 4, bit 5 + dest[4]|= BBIT(bcd_hour, 5) << 5; + // DCF bit 35 is byte 4, bit 4 + dest[4]|= p_hour << 4; + // DCF bit 36 is byte 4, bit 3 + dest[4]|= BBIT(bcd_day, 0) << 3; + // DCF bit 37 is byte 4, bit 2 + dest[4]|= BBIT(bcd_day, 1) << 2; + // DCF bit 38 is byte 4, bit 1 + dest[4]|= BBIT(bcd_day, 2) << 1; + // DCF bit 39 is byte 4, bit 0 + dest[4]|= BBIT(bcd_day, 3) << 0; + + // d5: 40-47, 40-41: day lsb 4-5, 42-44: dow; 45-47: month lsb 0-2 + dest[5] =0; + // DCF bit 40 is byte 5, bit 7 + dest[5]|= BBIT(bcd_day, 4) << 7; + // DCF bit 41 is byte 5, bit 6 + dest[5]|= BBIT(bcd_day, 5) << 6; + // DCF bit 42 is byte 5, bit 5 + dest[5]|= BBIT(dow, 0) << 5; + // DCF bit 43 is byte 5, bit 4 + dest[5]|= BBIT(dow, 1) << 4; + // DCF bit 44 is byte 5, bit 3 + dest[5]|= BBIT(dow, 2) << 3; + // DCF bit 45 is byte 5, bit 2 + dest[5]|= BBIT(bcd_month, 0) << 2; + // DCF bit 46 is byte 5, bit 1 + dest[5]|= BBIT(bcd_month, 1) << 1; + // DCF bit 47 is byte 5, bit 0 + dest[5]|= BBIT(bcd_month, 2) << 0; + + + // d6: 48-55; 48-49 month lsb 3-4; 50-55: year lsb 0-5 + dest[6] =0; + // DCF bit 48 is byte 6, bit 7 + dest[6]|= BBIT(bcd_month, 3) << 7; + // DCF bit 49 is byte 6, bit 6 + dest[6]|= BBIT(bcd_month, 4) << 6; + // DCF bit 50 is byte 6, bit 5 + dest[6]|= BBIT(bcd_year, 0) << 5; + // DCF bit 51 is byte 6, bit 4 + dest[6]|= BBIT(bcd_year, 1) << 4; + // DCF bit 52 is byte 6, bit 3 + dest[6]|= BBIT(bcd_year, 2) << 3; + // DCF bit 53 is byte 6, bit 2 + dest[6]|= BBIT(bcd_year, 3) << 2; + // DCF bit 54 is byte 6, bit 1 + dest[6]|= BBIT(bcd_year, 4) << 1; + // DCF bit 55 is byte 6, bit 0 + dest[6]|= BBIT(bcd_year, 5) << 0; + + + // d7: 56-63; 56-57: year lsb 6-7; 58: date parity; 59: special minute marker + dest[7] =0; + // DCF bit 56 is byte 7, bit 7 + dest[7]|= BBIT(bcd_year, 6) << 7; + // DCF bit 57 is byte 7, bit 6 + dest[7]|= BBIT(bcd_year, 7) << 6; + // DCF bit 58 is byte 7, bit 5 + dest[7]|= p_date << 5; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/dcf77_util.h b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/dcf77_util.h new file mode 100644 index 000000000..31fda0ebb --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/dcf77_util.h @@ -0,0 +1,18 @@ +#ifndef __arha_dcf77util_h +#define __arha_dcf77util_h + +#include +#include +#include + +void set_dcf_message(uint8_t* dest, uint8_t minute, uint8_t hour, + uint8_t day, uint8_t month, uint8_t year, uint8_t dow, + bool dst, bool predst, bool abnormal, bool leap, uint16_t civbits); + +#ifndef BBIT +#define BBIT(B,shift) (!!(B & (1 << shift))) +#endif + + + +#endif \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/icons/app.png b/Applications/Official/DEV_FW/source/xMasterX/flipper-dcf77/icons/app.png new file mode 100644 index 0000000000000000000000000000000000000000..db6dcf7fb0c4374f57c6c010a2edc90833da76fb GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>VM%xNb!1@J z*w6hZkrl}2EbxddW?X?_wfUrhg0dy95hcO-X(i=}MX3x9Ii-1t1&Nt?CHe(< z>AK1JDXGa{oh9Xf3jI7?978mMd;0^q7!)|1ul~NjbCyMrVrKl|d&^#0O;QQvEoVJ) zXg5RR2_4&KtaD77e)g!J_}X&(Sk3$I>t&xLpB9l+V3_BXyZ7hLU45=*((}xIA2hIY Q0h-L<>FVdQ&MBb@06+XnQ2+n{ literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/LICENSE b/Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/LICENSE new file mode 100644 index 000000000..28d693a7c --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 MX + +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/Official/DEV_FW/source/xMasterX/flipper-flashlight/README.md b/Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/README.md new file mode 100644 index 000000000..a40cb2d5a --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/README.md @@ -0,0 +1,7 @@ +# Flashlight Plugin for Flipper Zero + +Simple Flashlight special for @Svaarich by @xMasterX + +Enables 3.3v on pin 7/C3 and leaves it on when you exit app + +**Connect LED to (+ -> 7/C3) | (GND -> GND)** diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/application.fam b/Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/application.fam new file mode 100644 index 000000000..633b76a1f --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/application.fam @@ -0,0 +1,14 @@ +App( + appid="flashlight", + name="Flashlight", + apptype=FlipperAppType.EXTERNAL, + entry_point="flashlight_app", + cdefines=["APP_FLASHLIGHT"], + requires=[ + "gui", + ], + stack_size=2 * 1024, + order=20, + fap_icon="flash10px.png", + fap_category="GPIO_Extra", +) \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/flash10px.png b/Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/flash10px.png new file mode 100644 index 0000000000000000000000000000000000000000..963a9ab5fc0bde61515c25ee9860f7522e7b7547 GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>@$+gTe~DWM4fVB0fn literal 0 HcmV?d00001 diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/flashlight.c b/Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/flashlight.c new file mode 100644 index 000000000..534d48fdb --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper-flashlight/flashlight.c @@ -0,0 +1,130 @@ +// by @xMasterX + +#include +#include +#include +#include +#include +#include + +typedef enum { + EventTypeTick, + EventTypeKey, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} PluginEvent; + +typedef struct { + bool is_on; +} PluginState; + +static void render_callback(Canvas* const canvas, void* ctx) { + const PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25); + if(plugin_state == NULL) { + return; + } + + canvas_set_font(canvas, FontPrimary); + elements_multiline_text_aligned(canvas, 64, 2, AlignCenter, AlignTop, "Flashlight"); + + canvas_set_font(canvas, FontSecondary); + + if(!plugin_state->is_on) { + elements_multiline_text_aligned( + canvas, 64, 28, AlignCenter, AlignTop, "Press OK button turn on"); + } else { + elements_multiline_text_aligned(canvas, 64, 28, AlignCenter, AlignTop, "Light is on!"); + elements_multiline_text_aligned( + canvas, 64, 40, AlignCenter, AlignTop, "Press OK button to off"); + } + + release_mutex((ValueMutex*)ctx, plugin_state); +} + +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 flash_toggle(PluginState* const plugin_state) { + furi_hal_gpio_write(&gpio_ext_pc3, false); + furi_hal_gpio_init(&gpio_ext_pc3, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + + if(plugin_state->is_on) { + furi_hal_gpio_write(&gpio_ext_pc3, false); + plugin_state->is_on = false; + } else { + furi_hal_gpio_write(&gpio_ext_pc3, true); + plugin_state->is_on = true; + } +} + +int32_t flashlight_app() { + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); + + PluginState* plugin_state = malloc(sizeof(PluginState)); + + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) { + FURI_LOG_E("flashlight", "cannot create mutex\r\n"); + furi_message_queue_free(event_queue); + free(plugin_state); + return 255; + } + + // Set system callbacks + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, render_callback, &state_mutex); + view_port_input_callback_set(view_port, input_callback, event_queue); + + // Open GUI and register view_port + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + PluginEvent event; + for(bool processing = true; processing;) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); + + PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex); + + if(event_status == FuriStatusOk) { + // press events + if(event.type == EventTypeKey) { + if(event.input.type == InputTypePress) { + switch(event.input.key) { + case InputKeyUp: + case InputKeyDown: + case InputKeyRight: + case InputKeyLeft: + break; + case InputKeyOk: + flash_toggle(plugin_state); + break; + case InputKeyBack: + processing = false; + break; + default: + break; + } + } + } + } + + view_port_update(view_port); + release_mutex(&state_mutex, plugin_state); + } + + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + furi_record_close(RECORD_GUI); + view_port_free(view_port); + furi_message_queue_free(event_queue); + delete_mutex(&state_mutex); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_analog_clock/README.md b/Applications/Official/DEV_FW/source/xMasterX/flipper_analog_clock/README.md new file mode 100644 index 000000000..7c83f35cc --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper_analog_clock/README.md @@ -0,0 +1 @@ +# Analog Clock app for Flipper Zero diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_analog_clock/analog_clock.c b/Applications/Official/DEV_FW/source/xMasterX/flipper_analog_clock/analog_clock.c new file mode 100644 index 000000000..531dadd52 --- /dev/null +++ b/Applications/Official/DEV_FW/source/xMasterX/flipper_analog_clock/analog_clock.c @@ -0,0 +1,154 @@ +#include +#include +#include +#include +#include +#include + +#define PI 3.14 + +typedef struct { + uint8_t x; + uint8_t y; +} Vector2; + +typedef enum { + EventTypeTick, + EventTypeInput, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} AppEvent; + +typedef struct { + FuriMutex* mutex; + FuriHalRtcDateTime date_time; +} ClockApp; + +static Vector2 angle_to_vector2(float angle_in_degrees, uint8_t distance, Vector2 center) { + float radians = (angle_in_degrees - 90) * (PI / 180); + + Vector2 vec = { + .x = center.x + cos(radians) * distance, + .y = center.y + sin(radians) * distance, + }; + + return vec; +} + +static void analog_clock_app_draw_callback(Canvas* canvas, void* context) { + furi_assert(context); + ClockApp* app = context; + furi_mutex_acquire(app->mutex, FuriWaitForever); + + uint8_t width = canvas_width(canvas); + uint8_t height = canvas_height(canvas); + Vector2 clock_center = { + .x = 28 + width / 2, + .y = height / 2, + }; + uint8_t radius = MIN(width, height) / 2 - 2; + + canvas_draw_circle(canvas, clock_center.x, clock_center.y, radius); + + FuriString* str = furi_string_alloc(); + + for(uint8_t i = 3; i <= 12; i += 3) { + Vector2 pos = angle_to_vector2(360 / 12 * i, radius - 4, clock_center); + + furi_string_printf(str, "%i", i); + + canvas_draw_str_aligned( + canvas, pos.x, pos.y, AlignCenter, AlignCenter, furi_string_get_cstr(str)); + } + + Vector2 hour_vec = + angle_to_vector2(((app->date_time.hour % 12) / 12.f * 360.f), radius - 8, clock_center); + canvas_draw_line(canvas, clock_center.x, clock_center.y, hour_vec.x, hour_vec.y); + + Vector2 minute_vec = + angle_to_vector2((app->date_time.minute / 60.f * 360.f), radius - 4, clock_center); + canvas_draw_line(canvas, clock_center.x, clock_center.y, minute_vec.x, minute_vec.y); + + Vector2 second_vec = + angle_to_vector2((app->date_time.second / 60.f * 360.f), radius - 2, clock_center); + canvas_draw_line(canvas, clock_center.x, clock_center.y, second_vec.x, second_vec.y); + + canvas_set_font(canvas, FontSecondary); + + locale_format_date(str, &app->date_time, locale_get_date_format(), "."); + uint16_t date_str_width = canvas_string_width(canvas, furi_string_get_cstr(str)); + canvas_draw_frame(canvas, 0, 51, date_str_width + 6, 13); + canvas_draw_str(canvas, 3, 61, furi_string_get_cstr(str)); + + furi_string_free(str); + furi_mutex_release(app->mutex); +} + +static void analog_clock_app_input_callback(InputEvent* event, void* context) { + furi_assert(context); + FuriMessageQueue* event_queue = context; + AppEvent app_event = {.type = EventTypeInput, .input = *event}; + furi_message_queue_put(event_queue, &app_event, FuriWaitForever); +} + +static void analog_clock_app_tick(void* context) { + furi_assert(context); + FuriMessageQueue* event_queue = context; + AppEvent app_event = {.type = EventTypeTick}; + furi_message_queue_put(event_queue, &app_event, 0); +} + +int32_t analog_clock_app(void* p) { + UNUSED(p); + + ClockApp* app = malloc(sizeof(ClockApp)); + furi_hal_rtc_get_datetime(&app->date_time); + + app->mutex = furi_mutex_alloc(FuriMutexTypeNormal); + + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(AppEvent)); + + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, analog_clock_app_draw_callback, app); + view_port_input_callback_set(view_port, analog_clock_app_input_callback, event_queue); + + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + FuriTimer* timer = furi_timer_alloc(analog_clock_app_tick, FuriTimerTypePeriodic, event_queue); + furi_timer_start(timer, furi_kernel_get_tick_frequency() / 10); // 10 times per second + + AppEvent event; + for(bool running = true; running;) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); + if(event_status == FuriStatusOk) { + if(event.type == EventTypeInput) { + if(event.input.type == InputTypeShort && event.input.key == InputKeyBack) { + running = false; + } + } else if(event.type == EventTypeTick) { + furi_mutex_acquire(app->mutex, FuriWaitForever); + + furi_hal_rtc_get_datetime(&app->date_time); + + furi_mutex_release(app->mutex); + view_port_update(view_port); + } + } + } + + furi_timer_free(timer); + + gui_remove_view_port(gui, view_port); + furi_record_close(RECORD_GUI); + view_port_free(view_port); + furi_message_queue_free(event_queue); + + furi_mutex_free(app->mutex); + free(app); + + return 0; +} diff --git a/Applications/Official/DEV_FW/source/xMasterX/flipper_analog_clock/analog_clock.png b/Applications/Official/DEV_FW/source/xMasterX/flipper_analog_clock/analog_clock.png new file mode 100644 index 0000000000000000000000000000000000000000..8a5406e6ce5bf26a43d916c16d14bd43fb0d7cdf GIT binary patch literal 7920 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