diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/MAYHEM_Camera.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/MAYHEM_Camera.fap new file mode 100644 index 00000000..44d82967 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/MAYHEM_Camera.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/MAYHEM_Marauder.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/MAYHEM_Marauder.fap new file mode 100644 index 00000000..92eb87ec Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/MAYHEM_Marauder.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/MAYHEM_Motion.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/MAYHEM_Motion.fap new file mode 100644 index 00000000..21072c77 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/MAYHEM_Motion.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/MAYHEM_QRcode.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/MAYHEM_QRcode.fap new file mode 100644 index 00000000..1e808d33 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/MAYHEM_QRcode.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/RCWL_0516.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/RCWL_0516.fap new file mode 100644 index 00000000..476eeff4 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/RCWL_0516.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/logic_analyzer.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/logic_analyzer.fap new file mode 100644 index 00000000..ae250aa8 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/logic_analyzer.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/rad_sens.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/rad_sens.fap new file mode 100644 index 00000000..b2717061 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/rad_sens.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/servotester.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/servotester.fap new file mode 100644 index 00000000..5391ee1e Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/GPIO/servotester.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/BPM_Tapper.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/BPM_Tapper.fap new file mode 100644 index 00000000..d1e9d1c1 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/BPM_Tapper.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/Music_Beeper.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/Music_Beeper.fap new file mode 100644 index 00000000..1b57015f Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/Music_Beeper.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/Ocarina.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/Ocarina.fap new file mode 100644 index 00000000..585a1a35 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/Ocarina.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/SAM.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/SAM.fap new file mode 100644 index 00000000..ac92acbb Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/SAM.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/SAM_NO.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/SAM_NO.fap new file mode 100644 index 00000000..6a28812a Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/SAM_NO.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/SAM_YES.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/SAM_YES.fap new file mode 100644 index 00000000..22b1921f Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/SAM_YES.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/USB_Midi.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/USB_Midi.fap new file mode 100644 index 00000000..19841d75 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/USB_Midi.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/flizzer_tracker.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/flizzer_tracker.fap new file mode 100644 index 00000000..d913f160 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/flizzer_tracker.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/text2sam.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/text2sam.fap new file mode 100644 index 00000000..c87063dc Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/text2sam.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/tuning_fork.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/tuning_fork.fap new file mode 100644 index 00000000..2a6e1e63 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/tuning_fork.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/video_player.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/video_player.fap new file mode 100644 index 00000000..0d0e2400 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/video_player.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/zero_tracker.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/zero_tracker.fap new file mode 100644 index 00000000..614405b7 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Media/zero_tracker.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/FlipBIP.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/FlipBIP.fap new file mode 100644 index 00000000..630c7b22 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/FlipBIP.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/bt_trigger.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/bt_trigger.fap new file mode 100644 index 00000000..89694316 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/bt_trigger.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/cli_gui.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/cli_gui.fap new file mode 100644 index 00000000..f9493c50 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/cli_gui.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/dcf77.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/dcf77.fap new file mode 100644 index 00000000..b888d023 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/dcf77.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/hex_editor.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/hex_editor.fap new file mode 100644 index 00000000..e104a627 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/hex_editor.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/ir_remote.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/ir_remote.fap new file mode 100644 index 00000000..2cd48d86 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/ir_remote.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/key_generator.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/key_generator.fap new file mode 100644 index 00000000..9e113b85 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/key_generator.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/mag.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/mag.fap new file mode 100644 index 00000000..396c5748 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/mag.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/mfkey32.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/mfkey32.fap new file mode 100644 index 00000000..95105375 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/mfkey32.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/mifare_fuzzer.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/mifare_fuzzer.fap new file mode 100644 index 00000000..42ce291d Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/mifare_fuzzer.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/nfc_magic_g4.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/nfc_magic_g4.fap new file mode 100644 index 00000000..efc55718 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/nfc_magic_g4.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/usb_hid_autofire.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/usb_hid_autofire.fap new file mode 100644 index 00000000..9b5962f9 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/usb_hid_autofire.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/xbox_controller.fap b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/xbox_controller.fap new file mode 100644 index 00000000..fc79b2c0 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/Tools/xbox_controller.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/apps_api_18.x_src.zip b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/apps_api_18.x_src.zip new file mode 100644 index 00000000..27b3e2bc Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Unleashed (Extras)/apps_api_18.x_src.zip differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/.Main/xtreme_app.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/.Main/xtreme_app.fap new file mode 100644 index 00000000..59533f69 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/.Main/xtreme_app.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/Air_Mouse.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/Air_Mouse.fap new file mode 100644 index 00000000..319de111 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/Air_Mouse.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/GPIO_Timelapse.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/GPIO_Timelapse.fap new file mode 100644 index 00000000..f6bcb7b0 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/GPIO_Timelapse.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/UART_Echo.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/UART_Echo.fap new file mode 100644 index 00000000..cf9c1dc4 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/UART_Echo.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/coleco.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/coleco.fap new file mode 100644 index 00000000..e41e1e3d Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/coleco.fap differ diff --git a/Applications/Official/DEV_FW/Tools/dap_link.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/dap_link.fap similarity index 73% rename from Applications/Official/DEV_FW/Tools/dap_link.fap rename to Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/dap_link.fap index 418bbb5c..e636b18f 100644 Binary files a/Applications/Official/DEV_FW/Tools/dap_link.fap and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/dap_link.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/flipper_geiger.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/flipper_geiger.fap new file mode 100644 index 00000000..c147240e Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/flipper_geiger.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/gps_nmea.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/gps_nmea.fap new file mode 100644 index 00000000..663d1aae Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/gps_nmea.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/hc_sr04.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/hc_sr04.fap new file mode 100644 index 00000000..262b348b Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/hc_sr04.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/i2cTools.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/i2cTools.fap new file mode 100644 index 00000000..463930c6 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/i2cTools.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/lightmeter.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/lightmeter.fap new file mode 100644 index 00000000..e8bbcf5f Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/lightmeter.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/spi_mem_manager.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/spi_mem_manager.fap new file mode 100644 index 00000000..1c2e6785 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/spi_mem_manager.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/swd_probe.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/swd_probe.fap new file mode 100644 index 00000000..d73d932b Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/swd_probe.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/uart_terminal.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/uart_terminal.fap new file mode 100644 index 00000000..5a7eb282 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/uart_terminal.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/unitemp.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/unitemp.fap new file mode 100644 index 00000000..48e85293 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/unitemp.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/wii_ec_anal.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/wii_ec_anal.fap new file mode 100644 index 00000000..36f7ebbf Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/GPIO/wii_ec_anal.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Games/asteroids.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Games/asteroids.fap new file mode 100644 index 00000000..740dfc69 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Games/asteroids.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Games/flipper_pong.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Games/flipper_pong.fap new file mode 100644 index 00000000..1116887a Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Games/flipper_pong.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Games/game_2048.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Games/game_2048.fap new file mode 100644 index 00000000..57efc67c Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Games/game_2048.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Games/multi_dice.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Games/multi_dice.fap new file mode 100644 index 00000000..b0756c2e Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Games/multi_dice.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/Brainfuck.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/Brainfuck.fap new file mode 100644 index 00000000..7d332539 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/Brainfuck.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/cntdown_tim.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/cntdown_tim.fap new file mode 100644 index 00000000..2f40c88a Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/cntdown_tim.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/morse_code.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/morse_code.fap new file mode 100644 index 00000000..d41508cc Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/morse_code.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/nightstand.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/nightstand.fap new file mode 100644 index 00000000..edd4b1bb Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/nightstand.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/rubiks_cube_scrambler.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/rubiks_cube_scrambler.fap new file mode 100644 index 00000000..bc5e19ba Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/rubiks_cube_scrambler.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/text_viewer.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/text_viewer.fap new file mode 100644 index 00000000..31369112 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/text_viewer.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/totp.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/totp.fap new file mode 100644 index 00000000..706f2956 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Misc/totp.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/Spectrum_Analyzer.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/Spectrum_Analyzer.fap new file mode 100644 index 00000000..e06bef60 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/Spectrum_Analyzer.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/SubGHz_Bruteforcer.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/SubGHz_Bruteforcer.fap new file mode 100644 index 00000000..b2409557 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/SubGHz_Bruteforcer.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/SubGHz_Playlist.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/SubGHz_Playlist.fap new file mode 100644 index 00000000..bc2e537d Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/SubGHz_Playlist.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/pocsag_pager.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/pocsag_pager.fap new file mode 100644 index 00000000..2bf77e42 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/pocsag_pager.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/protoview.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/protoview.fap new file mode 100644 index 00000000..48a6b560 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/protoview.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/weather_station.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/weather_station.fap new file mode 100644 index 00000000..3d919b08 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Sub-GHz/weather_station.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/cli_gui.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/cli_gui.fap new file mode 100644 index 00000000..3a3fbb83 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/cli_gui.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/flipp_pomodoro.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/flipp_pomodoro.fap new file mode 100644 index 00000000..83911de1 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/flipp_pomodoro.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/hid_ble.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/hid_ble.fap new file mode 100644 index 00000000..931260ea Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/hid_ble.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/hid_usb.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/hid_usb.fap new file mode 100644 index 00000000..2bd0eda7 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/hid_usb.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/passgen.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/passgen.fap new file mode 100644 index 00000000..9b8282a2 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/passgen.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/qrcode.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/qrcode.fap new file mode 100644 index 00000000..72f78ee4 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/Tools/qrcode.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/WiFi/ESP32_WiFi_Marauder.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/WiFi/ESP32_WiFi_Marauder.fap new file mode 100644 index 00000000..cfe5b562 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/WiFi/ESP32_WiFi_Marauder.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/WiFi/ESP8266_Deauther.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/WiFi/ESP8266_Deauther.fap new file mode 100644 index 00000000..9732c72a Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/WiFi/ESP8266_Deauther.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/WiFi/ESP8266_IFTTT_Virtual_Button.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/WiFi/ESP8266_IFTTT_Virtual_Button.fap new file mode 100644 index 00000000..a5c0bd7c Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/WiFi/ESP8266_IFTTT_Virtual_Button.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/WiFi/ESP8266_Wifi_Deauther_v2.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/WiFi/ESP8266_Wifi_Deauther_v2.fap new file mode 100644 index 00000000..806b69f4 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/WiFi/ESP8266_Wifi_Deauther_v2.fap differ diff --git a/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/WiFi/WiFi_Scanner.fap b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/WiFi/WiFi_Scanner.fap new file mode 100644 index 00000000..867fd201 Binary files /dev/null and b/Applications/Custom (UL, RM, XFW)/Xtreme (ClaraCrazy)/WiFi/WiFi_Scanner.fap differ diff --git a/Applications/Official/DEV_FW/GPIO/Flashlight.fap b/Applications/Official/DEV_FW/GPIO/Flashlight.fap index 9c7d5502..60cf34d8 100644 Binary files a/Applications/Official/DEV_FW/GPIO/Flashlight.fap and b/Applications/Official/DEV_FW/GPIO/Flashlight.fap differ diff --git a/Applications/Official/DEV_FW/GPIO/GPIO_Sentry_Safe.fap b/Applications/Official/DEV_FW/GPIO/GPIO_Sentry_Safe.fap index 1cc531ec..f6cda9bf 100644 Binary files a/Applications/Official/DEV_FW/GPIO/GPIO_Sentry_Safe.fap and b/Applications/Official/DEV_FW/GPIO/GPIO_Sentry_Safe.fap differ diff --git a/Applications/Official/DEV_FW/GPIO/Sentry_Safe.fap b/Applications/Official/DEV_FW/GPIO/Sentry_Safe.fap deleted file mode 100644 index 179ca185..00000000 Binary files a/Applications/Official/DEV_FW/GPIO/Sentry_Safe.fap and /dev/null differ diff --git a/Applications/Official/DEV_FW/GPIO/dap_link.fap b/Applications/Official/DEV_FW/GPIO/dap_link.fap index 2255d2ca..d0e0a235 100644 Binary files a/Applications/Official/DEV_FW/GPIO/dap_link.fap and b/Applications/Official/DEV_FW/GPIO/dap_link.fap differ diff --git a/Applications/Official/DEV_FW/GPIO/hc_sr04.fap b/Applications/Official/DEV_FW/GPIO/hc_sr04.fap index 58aa65bc..0735edc1 100644 Binary files a/Applications/Official/DEV_FW/GPIO/hc_sr04.fap and b/Applications/Official/DEV_FW/GPIO/hc_sr04.fap differ diff --git a/Applications/Official/DEV_FW/GPIO/i2cTools.fap b/Applications/Official/DEV_FW/GPIO/i2cTools.fap index 2103cc57..d55f0571 100644 Binary files a/Applications/Official/DEV_FW/GPIO/i2cTools.fap and b/Applications/Official/DEV_FW/GPIO/i2cTools.fap differ diff --git a/Applications/Official/DEV_FW/Games/2048.fap b/Applications/Official/DEV_FW/Games/2048.fap index 8821617a..958135c0 100644 Binary files a/Applications/Official/DEV_FW/Games/2048.fap and b/Applications/Official/DEV_FW/Games/2048.fap differ diff --git a/Applications/Official/DEV_FW/Games/Arkanoid.fap b/Applications/Official/DEV_FW/Games/Arkanoid.fap index 043de3ee..75813df0 100644 Binary files a/Applications/Official/DEV_FW/Games/Arkanoid.fap and b/Applications/Official/DEV_FW/Games/Arkanoid.fap differ diff --git a/Applications/Official/DEV_FW/Games/BlackJack.fap b/Applications/Official/DEV_FW/Games/BlackJack.fap index d287d85a..aeb17937 100644 Binary files a/Applications/Official/DEV_FW/Games/BlackJack.fap and b/Applications/Official/DEV_FW/Games/BlackJack.fap differ diff --git a/Applications/Official/DEV_FW/Games/Blackjack.fap b/Applications/Official/DEV_FW/Games/Blackjack.fap index d287d85a..aeb17937 100644 Binary files a/Applications/Official/DEV_FW/Games/Blackjack.fap and b/Applications/Official/DEV_FW/Games/Blackjack.fap differ diff --git a/Applications/Official/DEV_FW/Games/DND_Dice_app.fap b/Applications/Official/DEV_FW/Games/DND_Dice_app.fap index bcdabbd1..de0b3af9 100644 Binary files a/Applications/Official/DEV_FW/Games/DND_Dice_app.fap and b/Applications/Official/DEV_FW/Games/DND_Dice_app.fap differ diff --git a/Applications/Official/DEV_FW/Games/Dice.fap b/Applications/Official/DEV_FW/Games/Dice.fap index 511fe3ba..f0a99027 100644 Binary files a/Applications/Official/DEV_FW/Games/Dice.fap and b/Applications/Official/DEV_FW/Games/Dice.fap differ diff --git a/Applications/Official/DEV_FW/Games/FlappyBird.fap b/Applications/Official/DEV_FW/Games/FlappyBird.fap index 7cf94082..50d10319 100644 Binary files a/Applications/Official/DEV_FW/Games/FlappyBird.fap and b/Applications/Official/DEV_FW/Games/FlappyBird.fap differ diff --git a/Applications/Official/DEV_FW/Games/Game15.fap b/Applications/Official/DEV_FW/Games/Game15.fap index 2b0ff265..bc51b9f2 100644 Binary files a/Applications/Official/DEV_FW/Games/Game15.fap and b/Applications/Official/DEV_FW/Games/Game15.fap differ diff --git a/Applications/Official/DEV_FW/Games/GameOfLife.fap b/Applications/Official/DEV_FW/Games/GameOfLife.fap index 489b64af..ef13a61c 100644 Binary files a/Applications/Official/DEV_FW/Games/GameOfLife.fap and b/Applications/Official/DEV_FW/Games/GameOfLife.fap differ diff --git a/Applications/Official/DEV_FW/Games/Heap_Defence.fap b/Applications/Official/DEV_FW/Games/Heap_Defence.fap index 3a7be745..8ab6a8bc 100644 Binary files a/Applications/Official/DEV_FW/Games/Heap_Defence.fap and b/Applications/Official/DEV_FW/Games/Heap_Defence.fap differ diff --git a/Applications/Official/DEV_FW/Games/MandelbrotSet.fap b/Applications/Official/DEV_FW/Games/MandelbrotSet.fap index b1acc453..89c7ebe7 100644 Binary files a/Applications/Official/DEV_FW/Games/MandelbrotSet.fap and b/Applications/Official/DEV_FW/Games/MandelbrotSet.fap differ diff --git a/Applications/Official/DEV_FW/Games/Minesweeper.fap b/Applications/Official/DEV_FW/Games/Minesweeper.fap index 040f7cc8..bbd34b22 100644 Binary files a/Applications/Official/DEV_FW/Games/Minesweeper.fap and b/Applications/Official/DEV_FW/Games/Minesweeper.fap differ diff --git a/Applications/Official/DEV_FW/Games/MontyHall.fap b/Applications/Official/DEV_FW/Games/MontyHall.fap index 0f4d7786..f12878b7 100644 Binary files a/Applications/Official/DEV_FW/Games/MontyHall.fap and b/Applications/Official/DEV_FW/Games/MontyHall.fap differ diff --git a/Applications/Official/DEV_FW/Games/Scorched_Tanks.fap b/Applications/Official/DEV_FW/Games/Scorched_Tanks.fap index 8e67ec65..9cf05cbf 100644 Binary files a/Applications/Official/DEV_FW/Games/Scorched_Tanks.fap and b/Applications/Official/DEV_FW/Games/Scorched_Tanks.fap differ diff --git a/Applications/Official/DEV_FW/Games/Tanks.fap b/Applications/Official/DEV_FW/Games/Tanks.fap index 8bef29f8..f931549c 100644 Binary files a/Applications/Official/DEV_FW/Games/Tanks.fap and b/Applications/Official/DEV_FW/Games/Tanks.fap differ diff --git a/Applications/Official/DEV_FW/Games/Tetris.fap b/Applications/Official/DEV_FW/Games/Tetris.fap index 232c98d0..a33f1048 100644 Binary files a/Applications/Official/DEV_FW/Games/Tetris.fap and b/Applications/Official/DEV_FW/Games/Tetris.fap differ diff --git a/Applications/Official/DEV_FW/Games/TicTacToe.fap b/Applications/Official/DEV_FW/Games/TicTacToe.fap index 5ab7f03b..98e2b8ed 100644 Binary files a/Applications/Official/DEV_FW/Games/TicTacToe.fap and b/Applications/Official/DEV_FW/Games/TicTacToe.fap differ diff --git a/Applications/Official/DEV_FW/Games/Zombiez.fap b/Applications/Official/DEV_FW/Games/Zombiez.fap index 914f33d8..07918594 100644 Binary files a/Applications/Official/DEV_FW/Games/Zombiez.fap and b/Applications/Official/DEV_FW/Games/Zombiez.fap differ diff --git a/Applications/Official/DEV_FW/Games/scorched_tanks.fap b/Applications/Official/DEV_FW/Games/scorched_tanks.fap index 8e67ec65..9cf05cbf 100644 Binary files a/Applications/Official/DEV_FW/Games/scorched_tanks.fap and b/Applications/Official/DEV_FW/Games/scorched_tanks.fap differ diff --git a/Applications/Official/DEV_FW/Games/snake_game.fap b/Applications/Official/DEV_FW/Games/snake_game.fap index 8355ffac..6a369bcc 100644 Binary files a/Applications/Official/DEV_FW/Games/snake_game.fap and b/Applications/Official/DEV_FW/Games/snake_game.fap differ diff --git a/Applications/Official/DEV_FW/Games/zBroken_Chess.fap b/Applications/Official/DEV_FW/Games/zBroken_Chess.fap index d422c2b2..f154eb93 100644 Binary files a/Applications/Official/DEV_FW/Games/zBroken_Chess.fap and b/Applications/Official/DEV_FW/Games/zBroken_Chess.fap differ diff --git a/Applications/Official/DEV_FW/Misc/Barcode_Generator.fap b/Applications/Official/DEV_FW/Misc/Barcode_Generator.fap index 75e9e361..54b351fc 100644 Binary files a/Applications/Official/DEV_FW/Misc/Barcode_Generator.fap and b/Applications/Official/DEV_FW/Misc/Barcode_Generator.fap differ diff --git a/Applications/Official/DEV_FW/Misc/Morse_Code.fap b/Applications/Official/DEV_FW/Misc/Morse_Code.fap index 755e3fca..711705c4 100644 Binary files a/Applications/Official/DEV_FW/Misc/Morse_Code.fap and b/Applications/Official/DEV_FW/Misc/Morse_Code.fap differ diff --git a/Applications/Official/DEV_FW/Misc/Paint.fap b/Applications/Official/DEV_FW/Misc/Paint.fap index 279afaf5..11157c4e 100644 Binary files a/Applications/Official/DEV_FW/Misc/Paint.fap and b/Applications/Official/DEV_FW/Misc/Paint.fap differ diff --git a/Applications/Official/DEV_FW/Misc/counter.fap b/Applications/Official/DEV_FW/Misc/counter.fap index bdf95937..6d88595a 100644 Binary files a/Applications/Official/DEV_FW/Misc/counter.fap and b/Applications/Official/DEV_FW/Misc/counter.fap differ diff --git a/Applications/Official/DEV_FW/Misc/pocsag_pager.fap b/Applications/Official/DEV_FW/Misc/pocsag_pager.fap index 2324e14f..87c7f3a2 100644 Binary files a/Applications/Official/DEV_FW/Misc/pocsag_pager.fap and b/Applications/Official/DEV_FW/Misc/pocsag_pager.fap differ diff --git a/Applications/Official/DEV_FW/Misc/text_viewer.fap b/Applications/Official/DEV_FW/Misc/text_viewer.fap index f298698d..8ae434ff 100644 Binary files a/Applications/Official/DEV_FW/Misc/text_viewer.fap and b/Applications/Official/DEV_FW/Misc/text_viewer.fap differ diff --git a/Applications/Official/DEV_FW/Misc/totp.fap b/Applications/Official/DEV_FW/Misc/totp.fap index 4bf1f7b9..42595643 100644 Binary files a/Applications/Official/DEV_FW/Misc/totp.fap and b/Applications/Official/DEV_FW/Misc/totp.fap differ diff --git a/Applications/Official/DEV_FW/Misc/usb_hid_autofire.fap b/Applications/Official/DEV_FW/Misc/usb_hid_autofire.fap index fde8bb22..eee3c66a 100644 Binary files a/Applications/Official/DEV_FW/Misc/usb_hid_autofire.fap and b/Applications/Official/DEV_FW/Misc/usb_hid_autofire.fap differ diff --git a/Applications/Official/DEV_FW/Misc/usb_mouse.fap b/Applications/Official/DEV_FW/Misc/usb_mouse.fap new file mode 100644 index 00000000..fce78ae3 Binary files /dev/null and b/Applications/Official/DEV_FW/Misc/usb_mouse.fap differ diff --git a/Applications/Official/DEV_FW/Music/Ocarina.fap b/Applications/Official/DEV_FW/Music/Ocarina.fap index 7cb29622..b9650931 100644 Binary files a/Applications/Official/DEV_FW/Music/Ocarina.fap and b/Applications/Official/DEV_FW/Music/Ocarina.fap differ diff --git a/Applications/Official/DEV_FW/Music/WAV_Player.fap b/Applications/Official/DEV_FW/Music/WAV_Player.fap index 5b0a3ca4..7bf223f3 100644 Binary files a/Applications/Official/DEV_FW/Music/WAV_Player.fap and b/Applications/Official/DEV_FW/Music/WAV_Player.fap differ diff --git a/Applications/Official/DEV_FW/Music/music_player.fap b/Applications/Official/DEV_FW/Music/music_player.fap index 9235b5d0..e2103d31 100644 Binary files a/Applications/Official/DEV_FW/Music/music_player.fap and b/Applications/Official/DEV_FW/Music/music_player.fap differ diff --git a/Applications/Official/DEV_FW/Music/ocarina.fap b/Applications/Official/DEV_FW/Music/ocarina.fap index 7cb29622..b9650931 100644 Binary files a/Applications/Official/DEV_FW/Music/ocarina.fap and b/Applications/Official/DEV_FW/Music/ocarina.fap differ diff --git a/Applications/Official/DEV_FW/Tools/Caesar_Cipher.fap b/Applications/Official/DEV_FW/Tools/Caesar_Cipher.fap index 334fadeb..49fef1c5 100644 Binary files a/Applications/Official/DEV_FW/Tools/Caesar_Cipher.fap and b/Applications/Official/DEV_FW/Tools/Caesar_Cipher.fap differ diff --git a/Applications/Official/DEV_FW/Tools/Calculator.fap b/Applications/Official/DEV_FW/Tools/Calculator.fap index 3271fe76..989d82fe 100644 Binary files a/Applications/Official/DEV_FW/Tools/Calculator.fap and b/Applications/Official/DEV_FW/Tools/Calculator.fap differ diff --git a/Applications/Official/DEV_FW/Tools/DTMF_Dolphin.fap b/Applications/Official/DEV_FW/Tools/DTMF_Dolphin.fap index 5e0e19ce..269419ac 100644 Binary files a/Applications/Official/DEV_FW/Tools/DTMF_Dolphin.fap and b/Applications/Official/DEV_FW/Tools/DTMF_Dolphin.fap differ diff --git a/Applications/Official/DEV_FW/Tools/HEX_Viewer.fap b/Applications/Official/DEV_FW/Tools/HEX_Viewer.fap index f4baa2b8..542a52e2 100644 Binary files a/Applications/Official/DEV_FW/Tools/HEX_Viewer.fap and b/Applications/Official/DEV_FW/Tools/HEX_Viewer.fap differ diff --git a/Applications/Official/DEV_FW/Tools/Spectrum_Analyzer.fap b/Applications/Official/DEV_FW/Tools/Spectrum_Analyzer.fap index cadc392c..4aa6c1b0 100644 Binary files a/Applications/Official/DEV_FW/Tools/Spectrum_Analyzer.fap and b/Applications/Official/DEV_FW/Tools/Spectrum_Analyzer.fap differ diff --git a/Applications/Official/DEV_FW/Tools/USB_Keyboard.fap b/Applications/Official/DEV_FW/Tools/USB_Keyboard.fap deleted file mode 100644 index dce64f4f..00000000 Binary files a/Applications/Official/DEV_FW/Tools/USB_Keyboard.fap and /dev/null differ diff --git a/Applications/Official/DEV_FW/Tools/clock.fap b/Applications/Official/DEV_FW/Tools/clock.fap index 15f7e359..26eedfbd 100644 Binary files a/Applications/Official/DEV_FW/Tools/clock.fap and b/Applications/Official/DEV_FW/Tools/clock.fap differ diff --git a/Applications/Official/DEV_FW/Tools/hid_ble.fap b/Applications/Official/DEV_FW/Tools/hid_ble.fap index 2b625e16..23b091a2 100644 Binary files a/Applications/Official/DEV_FW/Tools/hid_ble.fap and b/Applications/Official/DEV_FW/Tools/hid_ble.fap differ diff --git a/Applications/Official/DEV_FW/Tools/hid_usb.fap b/Applications/Official/DEV_FW/Tools/hid_usb.fap index 5ad7799c..48a3b001 100644 Binary files a/Applications/Official/DEV_FW/Tools/hid_usb.fap and b/Applications/Official/DEV_FW/Tools/hid_usb.fap differ diff --git a/Applications/Official/DEV_FW/Tools/i2cTools.fap b/Applications/Official/DEV_FW/Tools/i2cTools.fap deleted file mode 100644 index 3f43efae..00000000 Binary files a/Applications/Official/DEV_FW/Tools/i2cTools.fap and /dev/null differ diff --git a/Applications/Official/DEV_FW/Tools/nfc_magic.fap b/Applications/Official/DEV_FW/Tools/nfc_magic.fap index 0abd236d..6a92a0bf 100644 Binary files a/Applications/Official/DEV_FW/Tools/nfc_magic.fap and b/Applications/Official/DEV_FW/Tools/nfc_magic.fap differ diff --git a/Applications/Official/DEV_FW/Tools/signal_generator.fap b/Applications/Official/DEV_FW/Tools/signal_generator.fap index e7d0f4c3..8087ce92 100644 Binary files a/Applications/Official/DEV_FW/Tools/signal_generator.fap and b/Applications/Official/DEV_FW/Tools/signal_generator.fap differ diff --git a/Applications/Official/DEV_FW/Tools/usb_hid_autofire.fap b/Applications/Official/DEV_FW/Tools/usb_hid_autofire.fap deleted file mode 100644 index 633b5b70..00000000 Binary files a/Applications/Official/DEV_FW/Tools/usb_hid_autofire.fap and /dev/null differ diff --git a/Applications/Official/DEV_FW/Tools/weather_station.fap b/Applications/Official/DEV_FW/Tools/weather_station.fap index b2b981c5..e32d52e7 100644 Binary files a/Applications/Official/DEV_FW/Tools/weather_station.fap and b/Applications/Official/DEV_FW/Tools/weather_station.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/accessor.fap b/Applications/Official/DEV_FW/Unsorted/accessor.fap new file mode 100644 index 00000000..ff4dfe03 Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/accessor.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/battery_test.fap b/Applications/Official/DEV_FW/Unsorted/battery_test.fap new file mode 100644 index 00000000..83c94c8a Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/battery_test.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/bc_demo.fap b/Applications/Official/DEV_FW/Unsorted/bc_demo.fap new file mode 100644 index 00000000..562350fd Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/bc_demo.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/blink_test.fap b/Applications/Official/DEV_FW/Unsorted/blink_test.fap new file mode 100644 index 00000000..0e164191 Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/blink_test.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/bt_debug.fap b/Applications/Official/DEV_FW/Unsorted/bt_debug.fap new file mode 100644 index 00000000..1257a616 Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/bt_debug.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/direct_draw.fap b/Applications/Official/DEV_FW/Unsorted/direct_draw.fap new file mode 100644 index 00000000..b8b42e5d Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/direct_draw.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/display_test.fap b/Applications/Official/DEV_FW/Unsorted/display_test.fap new file mode 100644 index 00000000..cda3168d Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/display_test.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/example_custom_font.fap b/Applications/Official/DEV_FW/Unsorted/example_custom_font.fap new file mode 100644 index 00000000..e94ce556 Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/example_custom_font.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/example_images.fap b/Applications/Official/DEV_FW/Unsorted/example_images.fap new file mode 100644 index 00000000..8ea88b4f Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/example_images.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/example_thermo.fap b/Applications/Official/DEV_FW/Unsorted/example_thermo.fap new file mode 100644 index 00000000..2f35a8db Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/example_thermo.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/file_browser_test.fap b/Applications/Official/DEV_FW/Unsorted/file_browser_test.fap new file mode 100644 index 00000000..27881585 Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/file_browser_test.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/keypad_test.fap b/Applications/Official/DEV_FW/Unsorted/keypad_test.fap new file mode 100644 index 00000000..76a25d03 Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/keypad_test.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/lfrfid_debug.fap b/Applications/Official/DEV_FW/Unsorted/lfrfid_debug.fap new file mode 100644 index 00000000..5c01303f Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/lfrfid_debug.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/locale_test.fap b/Applications/Official/DEV_FW/Unsorted/locale_test.fap new file mode 100644 index 00000000..125243aa Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/locale_test.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/picopass.fap b/Applications/Official/DEV_FW/Unsorted/picopass.fap new file mode 100644 index 00000000..270468e8 Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/picopass.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/rpc_debug.fap b/Applications/Official/DEV_FW/Unsorted/rpc_debug.fap new file mode 100644 index 00000000..b07047f5 Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/rpc_debug.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/spi_mem_manager.fap b/Applications/Official/DEV_FW/Unsorted/spi_mem_manager.fap new file mode 100644 index 00000000..3d9c3154 Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/spi_mem_manager.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/text_box_test.fap b/Applications/Official/DEV_FW/Unsorted/text_box_test.fap new file mode 100644 index 00000000..72bf6daa Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/text_box_test.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/uart_echo.fap b/Applications/Official/DEV_FW/Unsorted/uart_echo.fap new file mode 100644 index 00000000..aa93b51c Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/uart_echo.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/usb_test.fap b/Applications/Official/DEV_FW/Unsorted/usb_test.fap new file mode 100644 index 00000000..a999b494 Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/usb_test.fap differ diff --git a/Applications/Official/DEV_FW/Unsorted/vibro_test.fap b/Applications/Official/DEV_FW/Unsorted/vibro_test.fap new file mode 100644 index 00000000..c67131fc Binary files /dev/null and b/Applications/Official/DEV_FW/Unsorted/vibro_test.fap differ diff --git a/Applications/Official/DEV_FW/source/kyhwana/wav_player/application.fam b/Applications/Official/DEV_FW/source/kyhwana/wav_player/application.fam new file mode 100644 index 00000000..ec0c7629 --- /dev/null +++ b/Applications/Official/DEV_FW/source/kyhwana/wav_player/application.fam @@ -0,0 +1,12 @@ +App( + appid="WAV_Player", + name="WAV Player", + apptype=FlipperAppType.EXTERNAL, + entry_point="wav_player_app", + cdefines=["APP_WAV_PLAYER"], + stack_size=4 * 1024, + order=60, + fap_icon="wav_10px.png", + fap_category="Music", + fap_icon_assets="images", +) diff --git a/Applications/Official/DEV_FW/source/kyhwana/wav_player/images/music_10px.png b/Applications/Official/DEV_FW/source/kyhwana/wav_player/images/music_10px.png new file mode 100644 index 00000000..d41eb0db Binary files /dev/null and b/Applications/Official/DEV_FW/source/kyhwana/wav_player/images/music_10px.png differ diff --git a/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_10px.png b/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_10px.png new file mode 100644 index 00000000..54ff554a Binary files /dev/null and b/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_10px.png differ diff --git a/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_parser.c b/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_parser.c new file mode 100644 index 00000000..c2897706 --- /dev/null +++ b/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_parser.c @@ -0,0 +1,84 @@ +#include "wav_parser.h" + +#define TAG "WavParser" + +const char* format_text(FormatTag tag) { + switch(tag) { + case FormatTagPCM: + return "PCM"; + case FormatTagIEEE_FLOAT: + return "IEEE FLOAT"; + default: + return "Unknown"; + } +}; + +struct WavParser { + WavHeaderChunk header; + WavFormatChunk format; + WavDataChunk data; + size_t wav_data_start; + size_t wav_data_end; +}; + +WavParser* wav_parser_alloc() { + return malloc(sizeof(WavParser)); +} + +void wav_parser_free(WavParser* parser) { + free(parser); +} + +bool wav_parser_parse(WavParser* parser, Stream* stream) { + stream_read(stream, (uint8_t*)&parser->header, sizeof(WavHeaderChunk)); + stream_read(stream, (uint8_t*)&parser->format, sizeof(WavFormatChunk)); + stream_read(stream, (uint8_t*)&parser->data, sizeof(WavDataChunk)); + + if(memcmp(parser->header.riff, "RIFF", 4) != 0 || + memcmp(parser->header.wave, "WAVE", 4) != 0) { + FURI_LOG_E(TAG, "WAV: wrong header"); + return false; + } + + if(memcmp(parser->format.fmt, "fmt ", 4) != 0) { + FURI_LOG_E(TAG, "WAV: wrong format"); + return false; + } + + if(parser->format.tag != FormatTagPCM || memcmp(parser->data.data, "data", 4) != 0) { + FURI_LOG_E( + TAG, + "WAV: non-PCM format %u, next '%lu'", + parser->format.tag, + (uint32_t)parser->data.data); + return false; + } + + FURI_LOG_I( + TAG, + "Format tag: %s, ch: %u, smplrate: %lu, bps: %lu, bits: %u", + format_text(parser->format.tag), + parser->format.channels, + parser->format.sample_rate, + parser->format.byte_per_sec, + parser->format.bits_per_sample); + + parser->wav_data_start = stream_tell(stream); + parser->wav_data_end = parser->wav_data_start + parser->data.size; + + FURI_LOG_I(TAG, "data: %u - %u", parser->wav_data_start, parser->wav_data_end); + + return true; +} + +size_t wav_parser_get_data_start(WavParser* parser) { + return parser->wav_data_start; +} + +size_t wav_parser_get_data_end(WavParser* parser) { + return parser->wav_data_end; +} + +size_t wav_parser_get_data_len(WavParser* parser) { + return parser->wav_data_end - parser->wav_data_start; +} diff --git a/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_parser.h b/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_parser.h new file mode 100644 index 00000000..f50c48b3 --- /dev/null +++ b/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_parser.h @@ -0,0 +1,51 @@ +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + FormatTagPCM = 0x0001, + FormatTagIEEE_FLOAT = 0x0003, +} FormatTag; + +typedef struct { + uint8_t riff[4]; + uint32_t size; + uint8_t wave[4]; +} WavHeaderChunk; + +typedef struct { + uint8_t fmt[4]; + uint32_t size; + uint16_t tag; + uint16_t channels; + uint32_t sample_rate; + uint32_t byte_per_sec; + uint16_t block_align; + uint16_t bits_per_sample; +} WavFormatChunk; + +typedef struct { + uint8_t data[4]; + uint32_t size; +} WavDataChunk; + +typedef struct WavParser WavParser; + +WavParser* wav_parser_alloc(); + +void wav_parser_free(WavParser* parser); + +bool wav_parser_parse(WavParser* parser, Stream* stream); + +size_t wav_parser_get_data_start(WavParser* parser); + +size_t wav_parser_get_data_end(WavParser* parser); + +size_t wav_parser_get_data_len(WavParser* parser); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_player.c b/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_player.c new file mode 100644 index 00000000..0a57162f --- /dev/null +++ b/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_player.c @@ -0,0 +1,323 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wav_player_hal.h" +#include "wav_parser.h" +#include "wav_player_view.h" +#include +#include + +#include + +#define TAG "WavPlayer" + +#define WAVPLAYER_FOLDER "/ext/wav_player" + +static bool open_wav_stream(Stream* stream) { + DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); + bool result = false; + FuriString* path; + path = furi_string_alloc(); + furi_string_set(path, WAVPLAYER_FOLDER); + + DialogsFileBrowserOptions browser_options; + dialog_file_browser_set_basic_options(&browser_options, ".wav", &I_music_10px); + browser_options.base_path = WAVPLAYER_FOLDER; + browser_options.hide_ext = false; + + bool ret = dialog_file_browser_show(dialogs, path, path, &browser_options); + + furi_record_close(RECORD_DIALOGS); + if(ret) { + if(!file_stream_open(stream, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + FURI_LOG_E(TAG, "Cannot open file \"%s\"", furi_string_get_cstr(path)); + } else { + result = true; + } + } + furi_string_free(path); + return result; +} + +typedef enum { + WavPlayerEventHalfTransfer, + WavPlayerEventFullTransfer, + WavPlayerEventCtrlVolUp, + WavPlayerEventCtrlVolDn, + WavPlayerEventCtrlMoveL, + WavPlayerEventCtrlMoveR, + WavPlayerEventCtrlOk, + WavPlayerEventCtrlBack, +} WavPlayerEventType; + +typedef struct { + WavPlayerEventType type; +} WavPlayerEvent; + +static void wav_player_dma_isr(void* ctx) { + FuriMessageQueue* event_queue = ctx; + + // half of transfer + if(LL_DMA_IsActiveFlag_HT1(DMA1)) { + LL_DMA_ClearFlag_HT1(DMA1); + // fill first half of buffer + WavPlayerEvent event = {.type = WavPlayerEventHalfTransfer}; + furi_message_queue_put(event_queue, &event, 0); + } + + // transfer complete + if(LL_DMA_IsActiveFlag_TC1(DMA1)) { + LL_DMA_ClearFlag_TC1(DMA1); + // fill second half of buffer + WavPlayerEvent event = {.type = WavPlayerEventFullTransfer}; + furi_message_queue_put(event_queue, &event, 0); + } +} + +typedef struct { + Storage* storage; + Stream* stream; + WavParser* parser; + uint16_t* sample_buffer; + uint8_t* tmp_buffer; + + size_t samples_count_half; + size_t samples_count; + + FuriMessageQueue* queue; + + float volume; + bool play; + + WavPlayerView* view; + ViewDispatcher* view_dispatcher; + Gui* gui; + NotificationApp* notification; +} WavPlayerApp; + +static WavPlayerApp* app_alloc() { + WavPlayerApp* app = malloc(sizeof(WavPlayerApp)); + app->samples_count_half = 1024 * 4; + app->samples_count = app->samples_count_half * 2; + app->storage = furi_record_open(RECORD_STORAGE); + app->stream = file_stream_alloc(app->storage); + app->parser = wav_parser_alloc(); + app->sample_buffer = malloc(sizeof(uint16_t) * app->samples_count); + app->tmp_buffer = malloc(sizeof(uint8_t) * app->samples_count); + app->queue = furi_message_queue_alloc(10, sizeof(WavPlayerEvent)); + + app->volume = 10.0f; + app->play = true; + + app->gui = furi_record_open(RECORD_GUI); + app->view_dispatcher = view_dispatcher_alloc(); + app->view = wav_player_view_alloc(); + + view_dispatcher_add_view(app->view_dispatcher, 0, wav_player_view_get_view(app->view)); + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + view_dispatcher_switch_to_view(app->view_dispatcher, 0); + + app->notification = furi_record_open(RECORD_NOTIFICATION); + notification_message(app->notification, &sequence_display_backlight_enforce_on); + + return app; +} + +static void app_free(WavPlayerApp* app) { + view_dispatcher_remove_view(app->view_dispatcher, 0); + view_dispatcher_free(app->view_dispatcher); + wav_player_view_free(app->view); + furi_record_close(RECORD_GUI); + + furi_message_queue_free(app->queue); + free(app->tmp_buffer); + free(app->sample_buffer); + wav_parser_free(app->parser); + stream_free(app->stream); + furi_record_close(RECORD_STORAGE); + + notification_message(app->notification, &sequence_display_backlight_enforce_auto); + furi_record_close(RECORD_NOTIFICATION); + free(app); +} + +// TODO: that works only with 8-bit 2ch audio +static bool fill_data(WavPlayerApp* app, size_t index) { + uint16_t* sample_buffer_start = &app->sample_buffer[index]; + size_t count = stream_read(app->stream, app->tmp_buffer, app->samples_count); + + for(size_t i = count; i < app->samples_count; i++) { + app->tmp_buffer[i] = 0; + } + + for(size_t i = 0; i < app->samples_count; i += 2) { + float data = app->tmp_buffer[i]; + data -= UINT8_MAX / 2; // to signed + data /= UINT8_MAX / 2; // scale -1..1 + + data *= app->volume; // volume + data = tanhf(data); // hyperbolic tangent limiter + + data *= UINT8_MAX / 2; // scale -128..127 + data += UINT8_MAX / 2; // to unsigned + + if(data < 0) { + data = 0; + } + + if(data > 255) { + data = 255; + } + + sample_buffer_start[i / 2] = data; + } + + wav_player_view_set_data(app->view, sample_buffer_start, app->samples_count_half); + + return count != app->samples_count; +} + +static void ctrl_callback(WavPlayerCtrl ctrl, void* ctx) { + FuriMessageQueue* event_queue = ctx; + WavPlayerEvent event; + + switch(ctrl) { + case WavPlayerCtrlVolUp: + event.type = WavPlayerEventCtrlVolUp; + furi_message_queue_put(event_queue, &event, 0); + break; + case WavPlayerCtrlVolDn: + event.type = WavPlayerEventCtrlVolDn; + furi_message_queue_put(event_queue, &event, 0); + break; + case WavPlayerCtrlMoveL: + event.type = WavPlayerEventCtrlMoveL; + furi_message_queue_put(event_queue, &event, 0); + break; + case WavPlayerCtrlMoveR: + event.type = WavPlayerEventCtrlMoveR; + furi_message_queue_put(event_queue, &event, 0); + break; + case WavPlayerCtrlOk: + event.type = WavPlayerEventCtrlOk; + furi_message_queue_put(event_queue, &event, 0); + break; + case WavPlayerCtrlBack: + event.type = WavPlayerEventCtrlBack; + furi_message_queue_put(event_queue, &event, 0); + break; + default: + break; + } +} + +static void app_run(WavPlayerApp* app) { + if(!open_wav_stream(app->stream)) return; + if(!wav_parser_parse(app->parser, app->stream)) return; + + wav_player_view_set_volume(app->view, app->volume); + wav_player_view_set_start(app->view, wav_parser_get_data_start(app->parser)); + wav_player_view_set_current(app->view, stream_tell(app->stream)); + wav_player_view_set_end(app->view, wav_parser_get_data_end(app->parser)); + wav_player_view_set_play(app->view, app->play); + + wav_player_view_set_context(app->view, app->queue); + wav_player_view_set_ctrl_callback(app->view, ctrl_callback); + + bool eof = fill_data(app, 0); + eof = fill_data(app, app->samples_count_half); + + wav_player_speaker_init(); + wav_player_dma_init((uint32_t)app->sample_buffer, app->samples_count); + + furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, wav_player_dma_isr, app->queue); + + if(furi_hal_speaker_acquire(1000)) { + wav_player_dma_start(); + wav_player_speaker_start(); + + WavPlayerEvent event; + + while(1) { + if(furi_message_queue_get(app->queue, &event, FuriWaitForever) == FuriStatusOk) { + if(event.type == WavPlayerEventHalfTransfer) { + eof = fill_data(app, 0); + wav_player_view_set_current(app->view, stream_tell(app->stream)); + if(eof) { + stream_seek( + app->stream, + wav_parser_get_data_start(app->parser), + StreamOffsetFromStart); + } + + } else if(event.type == WavPlayerEventFullTransfer) { + eof = fill_data(app, app->samples_count_half); + wav_player_view_set_current(app->view, stream_tell(app->stream)); + if(eof) { + stream_seek( + app->stream, + wav_parser_get_data_start(app->parser), + StreamOffsetFromStart); + } + } else if(event.type == WavPlayerEventCtrlVolUp) { + if(app->volume < 9.9) app->volume += 0.4; + wav_player_view_set_volume(app->view, app->volume); + } else if(event.type == WavPlayerEventCtrlVolDn) { + if(app->volume > 0.01) app->volume -= 0.4; + wav_player_view_set_volume(app->view, app->volume); + } else if(event.type == WavPlayerEventCtrlMoveL) { + int32_t seek = + stream_tell(app->stream) - wav_parser_get_data_start(app->parser); + seek = + MIN(seek, (int32_t)(wav_parser_get_data_len(app->parser) / (size_t)100)); + stream_seek(app->stream, -seek, StreamOffsetFromCurrent); + wav_player_view_set_current(app->view, stream_tell(app->stream)); + } else if(event.type == WavPlayerEventCtrlMoveR) { + int32_t seek = wav_parser_get_data_end(app->parser) - stream_tell(app->stream); + seek = + MIN(seek, (int32_t)(wav_parser_get_data_len(app->parser) / (size_t)100)); + stream_seek(app->stream, seek, StreamOffsetFromCurrent); + wav_player_view_set_current(app->view, stream_tell(app->stream)); + } else if(event.type == WavPlayerEventCtrlOk) { + app->play = !app->play; + wav_player_view_set_play(app->view, app->play); + + if(!app->play) { + wav_player_speaker_stop(); + } else { + wav_player_speaker_start(); + } + } else if(event.type == WavPlayerEventCtrlBack) { + break; + } + } + } + + wav_player_speaker_stop(); + wav_player_dma_stop(); + furi_hal_speaker_release(); + } + + furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL); +} + +int32_t wav_player_app(void* p) { + UNUSED(p); + WavPlayerApp* app = app_alloc(); + + Storage* storage = furi_record_open(RECORD_STORAGE); + if(!storage_simply_mkdir(storage, WAVPLAYER_FOLDER)) { + FURI_LOG_E(TAG, "Could not create folder %s", WAVPLAYER_FOLDER); + } + furi_record_close(RECORD_STORAGE); + + app_run(app); + app_free(app); + return 0; +} diff --git a/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_player_hal.c b/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_player_hal.c new file mode 100644 index 00000000..ad0c019b --- /dev/null +++ b/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_player_hal.c @@ -0,0 +1,58 @@ +#include "wav_player_hal.h" +#include +#include + +#define FURI_HAL_SPEAKER_TIMER TIM16 +#define FURI_HAL_SPEAKER_CHANNEL LL_TIM_CHANNEL_CH1 +#define DMA_INSTANCE DMA1, LL_DMA_CHANNEL_1 + +void wav_player_speaker_init() { + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + TIM_InitStruct.Prescaler = 4; + TIM_InitStruct.Autoreload = 255; + LL_TIM_Init(FURI_HAL_SPEAKER_TIMER, &TIM_InitStruct); + + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; + 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); +} + +void wav_player_speaker_start() { + LL_TIM_EnableAllOutputs(FURI_HAL_SPEAKER_TIMER); + LL_TIM_EnableCounter(FURI_HAL_SPEAKER_TIMER); +} + +void wav_player_speaker_stop() { + LL_TIM_DisableAllOutputs(FURI_HAL_SPEAKER_TIMER); + LL_TIM_DisableCounter(FURI_HAL_SPEAKER_TIMER); +} + +void wav_player_dma_init(uint32_t address, size_t size) { + uint32_t dma_dst = (uint32_t) & (FURI_HAL_SPEAKER_TIMER->CCR1); + + LL_DMA_ConfigAddresses(DMA_INSTANCE, address, dma_dst, LL_DMA_DIRECTION_MEMORY_TO_PERIPH); + LL_DMA_SetDataLength(DMA_INSTANCE, size); + + LL_DMA_SetPeriphRequest(DMA_INSTANCE, LL_DMAMUX_REQ_TIM16_UP); + LL_DMA_SetDataTransferDirection(DMA_INSTANCE, LL_DMA_DIRECTION_MEMORY_TO_PERIPH); + LL_DMA_SetChannelPriorityLevel(DMA_INSTANCE, LL_DMA_PRIORITY_VERYHIGH); + LL_DMA_SetMode(DMA_INSTANCE, LL_DMA_MODE_CIRCULAR); + LL_DMA_SetPeriphIncMode(DMA_INSTANCE, LL_DMA_PERIPH_NOINCREMENT); + LL_DMA_SetMemoryIncMode(DMA_INSTANCE, LL_DMA_MEMORY_INCREMENT); + LL_DMA_SetPeriphSize(DMA_INSTANCE, LL_DMA_PDATAALIGN_HALFWORD); + LL_DMA_SetMemorySize(DMA_INSTANCE, LL_DMA_MDATAALIGN_HALFWORD); + + LL_DMA_EnableIT_TC(DMA_INSTANCE); + LL_DMA_EnableIT_HT(DMA_INSTANCE); +} + +void wav_player_dma_start() { + LL_DMA_EnableChannel(DMA_INSTANCE); + LL_TIM_EnableDMAReq_UPDATE(FURI_HAL_SPEAKER_TIMER); +} + +void wav_player_dma_stop() { + LL_DMA_DisableChannel(DMA_INSTANCE); +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_player_hal.h b/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_player_hal.h new file mode 100644 index 00000000..124f5140 --- /dev/null +++ b/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_player_hal.h @@ -0,0 +1,23 @@ +#pragma once +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void wav_player_speaker_init(); + +void wav_player_speaker_start(); + +void wav_player_speaker_stop(); + +void wav_player_dma_init(uint32_t address, size_t size); + +void wav_player_dma_start(); + +void wav_player_dma_stop(); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_player_view.c b/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_player_view.c new file mode 100644 index 00000000..fdf08cb2 --- /dev/null +++ b/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_player_view.c @@ -0,0 +1,201 @@ +#include "wav_player_view.h" + +#define DATA_COUNT 116 + +struct WavPlayerView { + View* view; + WavPlayerCtrlCallback callback; + void* context; +}; + +typedef struct { + bool play; + float volume; + size_t start; + size_t end; + size_t current; + uint8_t data[DATA_COUNT]; +} WavPlayerViewModel; + +float map(float x, float in_min, float in_max, float out_min, float out_max) { + return (x - in_min) * (out_max - out_min + 1) / (in_max - in_min + 1) + out_min; +} + +static void wav_player_view_draw_callback(Canvas* canvas, void* _model) { + WavPlayerViewModel* model = _model; + + canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + uint8_t x_pos = 0; + uint8_t y_pos = 0; + + // volume + x_pos = 124; + y_pos = 0; + const float volume = (64 / 10.0f) * model->volume; + canvas_draw_frame(canvas, x_pos, y_pos, 4, 64); + canvas_draw_box(canvas, x_pos, y_pos + (64 - volume), 4, volume); + + // play / pause + x_pos = 58; + y_pos = 55; + if(!model->play) { + canvas_draw_line(canvas, x_pos, y_pos, x_pos + 8, y_pos + 4); + canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos + 8, y_pos + 4); + canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos, y_pos); + } else { + canvas_draw_box(canvas, x_pos, y_pos, 3, 9); + canvas_draw_box(canvas, x_pos + 4, y_pos, 3, 9); + } + + x_pos = 78; + y_pos = 55; + canvas_draw_line(canvas, x_pos, y_pos, x_pos + 4, y_pos + 4); + canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos + 4, y_pos + 4); + canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos, y_pos); + + x_pos = 82; + y_pos = 55; + canvas_draw_line(canvas, x_pos, y_pos, x_pos + 4, y_pos + 4); + canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos + 4, y_pos + 4); + canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos, y_pos); + + x_pos = 40; + y_pos = 55; + canvas_draw_line(canvas, x_pos, y_pos, x_pos - 4, y_pos + 4); + canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos - 4, y_pos + 4); + canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos, y_pos); + + x_pos = 44; + y_pos = 55; + canvas_draw_line(canvas, x_pos, y_pos, x_pos - 4, y_pos + 4); + canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos - 4, y_pos + 4); + canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos, y_pos); + + // len + x_pos = 4; + y_pos = 47; + const uint8_t play_len = 116; + uint8_t play_pos = map(model->current, model->start, model->end, 0, play_len - 4); + + canvas_draw_frame(canvas, x_pos, y_pos, play_len, 4); + canvas_draw_box(canvas, x_pos + play_pos, y_pos - 2, 4, 8); + canvas_draw_box(canvas, x_pos, y_pos, play_pos, 4); + + // osc + x_pos = 4; + y_pos = 0; + for(size_t i = 1; i < DATA_COUNT; i++) { + canvas_draw_line(canvas, x_pos + i - 1, model->data[i - 1], x_pos + i, model->data[i]); + } +} + +static bool wav_player_view_input_callback(InputEvent* event, void* context) { + WavPlayerView* wav_player_view = context; + bool consumed = false; + + if(wav_player_view->callback) { + if(event->type == InputTypeShort || event->type == InputTypeRepeat) { + if(event->key == InputKeyUp) { + wav_player_view->callback(WavPlayerCtrlVolUp, wav_player_view->context); + consumed = true; + } else if(event->key == InputKeyDown) { + wav_player_view->callback(WavPlayerCtrlVolDn, wav_player_view->context); + consumed = true; + } else if(event->key == InputKeyLeft) { + wav_player_view->callback(WavPlayerCtrlMoveL, wav_player_view->context); + consumed = true; + } else if(event->key == InputKeyRight) { + wav_player_view->callback(WavPlayerCtrlMoveR, wav_player_view->context); + consumed = true; + } else if(event->key == InputKeyOk) { + wav_player_view->callback(WavPlayerCtrlOk, wav_player_view->context); + consumed = true; + } else if(event->key == InputKeyBack) { + wav_player_view->callback(WavPlayerCtrlBack, wav_player_view->context); + consumed = true; + } + } + } + + return consumed; +} + +WavPlayerView* wav_player_view_alloc() { + WavPlayerView* wav_view = malloc(sizeof(WavPlayerView)); + wav_view->view = view_alloc(); + view_set_context(wav_view->view, wav_view); + view_allocate_model(wav_view->view, ViewModelTypeLocking, sizeof(WavPlayerViewModel)); + view_set_draw_callback(wav_view->view, wav_player_view_draw_callback); + view_set_input_callback(wav_view->view, wav_player_view_input_callback); + + return wav_view; +} + +void wav_player_view_free(WavPlayerView* wav_view) { + furi_assert(wav_view); + view_free(wav_view->view); + free(wav_view); +} + +View* wav_player_view_get_view(WavPlayerView* wav_view) { + furi_assert(wav_view); + return wav_view->view; +} + +void wav_player_view_set_volume(WavPlayerView* wav_view, float volume) { + furi_assert(wav_view); + with_view_model( + wav_view->view, WavPlayerViewModel * model, { model->volume = volume; }, true); +} + +void wav_player_view_set_start(WavPlayerView* wav_view, size_t start) { + furi_assert(wav_view); + with_view_model( + wav_view->view, WavPlayerViewModel * model, { model->start = start; }, true); +} + +void wav_player_view_set_end(WavPlayerView* wav_view, size_t end) { + furi_assert(wav_view); + with_view_model( + wav_view->view, WavPlayerViewModel * model, { model->end = end; }, true); +} + +void wav_player_view_set_current(WavPlayerView* wav_view, size_t current) { + furi_assert(wav_view); + with_view_model( + wav_view->view, WavPlayerViewModel * model, { model->current = current; }, true); +} + +void wav_player_view_set_play(WavPlayerView* wav_view, bool play) { + furi_assert(wav_view); + with_view_model( + wav_view->view, WavPlayerViewModel * model, { model->play = play; }, true); +} + +void wav_player_view_set_data(WavPlayerView* wav_view, uint16_t* data, size_t data_count) { + furi_assert(wav_view); + with_view_model( + wav_view->view, + WavPlayerViewModel * model, + { + size_t inc = (data_count / DATA_COUNT) - 1; + + for(size_t i = 0; i < DATA_COUNT; i++) { + model->data[i] = *data / 6; + if(model->data[i] > 42) model->data[i] = 42; + data += inc; + } + }, + true); +} + +void wav_player_view_set_ctrl_callback(WavPlayerView* wav_view, WavPlayerCtrlCallback callback) { + furi_assert(wav_view); + wav_view->callback = callback; +} + +void wav_player_view_set_context(WavPlayerView* wav_view, void* context) { + furi_assert(wav_view); + wav_view->context = context; +} \ No newline at end of file diff --git a/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_player_view.h b/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_player_view.h new file mode 100644 index 00000000..246aeaf3 --- /dev/null +++ b/Applications/Official/DEV_FW/source/kyhwana/wav_player/wav_player_view.h @@ -0,0 +1,45 @@ +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct WavPlayerView WavPlayerView; + +typedef enum { + WavPlayerCtrlVolUp, + WavPlayerCtrlVolDn, + WavPlayerCtrlMoveL, + WavPlayerCtrlMoveR, + WavPlayerCtrlOk, + WavPlayerCtrlBack, +} WavPlayerCtrl; + +typedef void (*WavPlayerCtrlCallback)(WavPlayerCtrl ctrl, void* context); + +WavPlayerView* wav_player_view_alloc(); + +void wav_player_view_free(WavPlayerView* wav_view); + +View* wav_player_view_get_view(WavPlayerView* wav_view); + +void wav_player_view_set_volume(WavPlayerView* wav_view, float volume); + +void wav_player_view_set_start(WavPlayerView* wav_view, size_t start); + +void wav_player_view_set_end(WavPlayerView* wav_view, size_t end); + +void wav_player_view_set_current(WavPlayerView* wav_view, size_t current); + +void wav_player_view_set_play(WavPlayerView* wav_view, bool play); + +void wav_player_view_set_data(WavPlayerView* wav_view, uint16_t* data, size_t data_count); + +void wav_player_view_set_ctrl_callback(WavPlayerView* wav_view, WavPlayerCtrlCallback callback); + +void wav_player_view_set_context(WavPlayerView* wav_view, void* context); + +#ifdef __cplusplus +} +#endif \ No newline at end of file