From 9056ab4fe8c480ace6431593c0b40ad904c1d489 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 31 Oct 2023 03:51:54 +0000 Subject: [PATCH] 12 more apps gone, 44 to go --- .../external/gpioreader_a/GPIO_reader.c | 152 - .../external/gpioreader_a/GPIO_reader_item.c | 27 - .../external/gpioreader_a/GPIO_reader_item.h | 42 - .../external/gpioreader_a/application.fam | 14 - applications/external/gpioreader_a/icon.png | Bin 135 -> 0 bytes applications/external/gpioreader_b/LICENSE | 674 -- .../external/gpioreader_b/application.fam | 11 - applications/external/gpioreader_b/gpio_app.c | 111 - applications/external/gpioreader_b/gpio_app.h | 11 - .../external/gpioreader_b/gpio_app_i.h | 45 - .../external/gpioreader_b/gpio_custom_event.h | 14 - .../external/gpioreader_b/gpio_item.c | 60 - .../external/gpioreader_b/gpio_item.h | 17 - applications/external/gpioreader_b/icon.png | Bin 135 -> 0 bytes .../external/gpioreader_b/scenes/gpio_scene.c | 30 - .../external/gpioreader_b/scenes/gpio_scene.h | 29 - .../gpioreader_b/scenes/gpio_scene_config.h | 6 - .../gpioreader_b/scenes/gpio_scene_reader.c | 30 - .../gpioreader_b/scenes/gpio_scene_start.c | 114 - .../gpioreader_b/scenes/gpio_scene_test.c | 30 - .../gpioreader_b/scenes/gpio_scene_usb_uart.c | 67 - .../scenes/gpio_scene_usb_uart_close_rpc.c | 41 - .../scenes/gpio_scene_usb_uart_config.c | 169 - .../external/gpioreader_b/usb_uart_bridge.c | 375 -- .../external/gpioreader_b/usb_uart_bridge.h | 30 - .../external/gpioreader_b/views/gpio_reader.c | 160 - .../external/gpioreader_b/views/gpio_reader.h | 17 - .../external/gpioreader_b/views/gpio_test.c | 139 - .../external/gpioreader_b/views/gpio_test.h | 14 - .../gpioreader_b/views/gpio_usb_uart.c | 161 - .../gpioreader_b/views/gpio_usb_uart.h | 18 - applications/external/gps_nmea_uart/LICENSE | 674 -- .../external/gps_nmea_uart/application.fam | 13 - applications/external/gps_nmea_uart/gps.c | 199 - .../external/gps_nmea_uart/gps_10px.png | Bin 6750 -> 0 bytes .../external/gps_nmea_uart/gps_uart.c | 226 - .../external/gps_nmea_uart/gps_uart.h | 50 - applications/external/gps_nmea_uart/minmea.c | 640 -- applications/external/gps_nmea_uart/minmea.h | 295 - .../external/metronome/application.fam | 16 - .../external/metronome/gui_extensions.c | 57 - .../external/metronome/gui_extensions.h | 3 - applications/external/metronome/metronome.c | 398 -- .../external/metronome/metronome_icon.png | Bin 170 -> 0 bytes applications/external/passgen/LICENSE | 21 - applications/external/passgen/application.fam | 15 - .../passgen/icons/Horizontal_arrow_9x7.png | Bin 1479 -> 0 bytes .../passgen/icons/Vertical_arrow_7x9.png | Bin 1482 -> 0 bytes .../external/passgen/icons/passgen_icon.png | Bin 173 -> 0 bytes .../external/passgen/images/preview.png | Bin 980 -> 0 bytes applications/external/passgen/passgen.c | 264 - .../external/pomodoro/application.fam | 15 - .../external/pomodoro/flipp_pomodoro_10.png | Bin 157 -> 0 bytes .../external/pomodoro/flipp_pomodoro_app.c | 121 - .../external/pomodoro/flipp_pomodoro_app.h | 39 - .../external/pomodoro/flipp_pomodoro_app_i.h | 32 - .../external/pomodoro/helpers/debug.h | 5 - .../external/pomodoro/helpers/notifications.c | 49 - .../external/pomodoro/helpers/notifications.h | 14 - applications/external/pomodoro/helpers/time.c | 20 - applications/external/pomodoro/helpers/time.h | 24 - .../flipp_pomodoro_focus_64/frame_00.png | Bin 1242 -> 0 bytes .../flipp_pomodoro_focus_64/frame_01.png | Bin 1215 -> 0 bytes .../images/flipp_pomodoro_focus_64/frame_rate | 1 - .../images/flipp_pomodoro_learn_50x128.png | Bin 1234 -> 0 bytes .../flipp_pomodoro_rest_64/frame_00.png | Bin 1083 -> 0 bytes .../flipp_pomodoro_rest_64/frame_01.png | Bin 1080 -> 0 bytes .../images/flipp_pomodoro_rest_64/frame_rate | 1 - .../pomodoro/modules/flipp_pomodoro.c | 94 - .../pomodoro/modules/flipp_pomodoro.h | 53 - .../modules/flipp_pomodoro_statistics.c | 26 - .../modules/flipp_pomodoro_statistics.h | 45 - applications/external/pomodoro/scenes/.keep | 0 .../config/flipp_pomodoro_scene_config.h | 2 - .../pomodoro/scenes/flipp_pomodoro_scene.c | 30 - .../pomodoro/scenes/flipp_pomodoro_scene.h | 28 - .../scenes/flipp_pomodoro_scene_info.c | 59 - .../scenes/flipp_pomodoro_scene_timer.c | 154 - applications/external/pomodoro/views/.keep | 0 .../pomodoro/views/flipp_pomodoro_info_view.c | 153 - .../pomodoro/views/flipp_pomodoro_info_view.h | 71 - .../views/flipp_pomodoro_timer_view.c | 294 - .../views/flipp_pomodoro_timer_view.h | 30 - applications/external/qrcode/LICENSE | 21 - applications/external/qrcode/application.fam | 19 - .../external/qrcode/icons/qrcode_10px.png | Bin 1758 -> 0 bytes applications/external/qrcode/qrcode.c | 967 --- applications/external/qrcode/qrcode.h | 100 - applications/external/qrcode/qrcode_app.c | 643 -- applications/external/radar_scanner/LICENSE | 674 -- .../external/radar_scanner/application.fam | 14 - applications/external/radar_scanner/icon.png | Bin 137 -> 0 bytes .../external/radar_scanner/radar_scanner.c | 203 - applications/external/rc2014_coleco/LICENSE | 674 -- .../external/rc2014_coleco/application.fam | 12 - applications/external/rc2014_coleco/coleco.c | 365 -- .../external/rc2014_coleco/coleco_10px.png | Bin 6667 -> 0 bytes .../rc2014_coleco/icons/Coleco0_17x17.png | Bin 628 -> 0 bytes .../rc2014_coleco/icons/Coleco0_hvr_17x17.png | Bin 627 -> 0 bytes .../rc2014_coleco/icons/Coleco1_17x17.png | Bin 623 -> 0 bytes .../rc2014_coleco/icons/Coleco1_hvr_17x17.png | Bin 618 -> 0 bytes .../rc2014_coleco/icons/Coleco2_17x17.png | Bin 642 -> 0 bytes .../rc2014_coleco/icons/Coleco2_hvr_17x17.png | Bin 643 -> 0 bytes .../rc2014_coleco/icons/Coleco3_17x17.png | Bin 645 -> 0 bytes .../rc2014_coleco/icons/Coleco3_hvr_17x17.png | Bin 640 -> 0 bytes .../rc2014_coleco/icons/Coleco4_17x17.png | Bin 635 -> 0 bytes .../rc2014_coleco/icons/Coleco4_hvr_17x17.png | Bin 627 -> 0 bytes .../rc2014_coleco/icons/Coleco5_17x17.png | Bin 640 -> 0 bytes .../rc2014_coleco/icons/Coleco5_hvr_17x17.png | Bin 633 -> 0 bytes .../rc2014_coleco/icons/Coleco6_17x17.png | Bin 635 -> 0 bytes .../rc2014_coleco/icons/Coleco6_hvr_17x17.png | Bin 634 -> 0 bytes .../rc2014_coleco/icons/Coleco7_17x17.png | Bin 636 -> 0 bytes .../rc2014_coleco/icons/Coleco7_hvr_17x17.png | Bin 628 -> 0 bytes .../rc2014_coleco/icons/Coleco8_17x17.png | Bin 629 -> 0 bytes .../rc2014_coleco/icons/Coleco8_hvr_17x17.png | Bin 625 -> 0 bytes .../rc2014_coleco/icons/Coleco9_17x17.png | Bin 642 -> 0 bytes .../rc2014_coleco/icons/Coleco9_hvr_17x17.png | Bin 639 -> 0 bytes .../rc2014_coleco/icons/ColecoAlt_18x9.png | Bin 5677 -> 0 bytes .../icons/ColecoAlt_hvr_18x9.png | Bin 5037 -> 0 bytes .../rc2014_coleco/icons/ColecoFire_18x9.png | Bin 5660 -> 0 bytes .../icons/ColecoFire_hvr_18x9.png | Bin 5044 -> 0 bytes .../icons/ColecoFire_sel_18x9.png | Bin 6111 -> 0 bytes .../icons/ColecoJoystick_33x33.png | Bin 737 -> 0 bytes .../icons/ColecoJoystick_hvr_33x33.png | Bin 763 -> 0 bytes .../icons/ColecoJoystick_sel_33x33.png | Bin 776 -> 0 bytes .../rc2014_coleco/icons/ColecoPound_17x17.png | Bin 626 -> 0 bytes .../icons/ColecoPound_hvr_17x17.png | Bin 625 -> 0 bytes .../rc2014_coleco/icons/ColecoStar_17x17.png | Bin 638 -> 0 bytes .../icons/ColecoStar_hvr_17x17.png | Bin 632 -> 0 bytes .../interface/flipper-coleco.brd | 2554 -------- .../interface/flipper-coleco.sch | 5482 ----------------- applications/external/reversi/LICENSE | 21 - applications/external/reversi/application.fam | 18 - applications/external/reversi/game_reversi.c | 351 -- .../external/reversi/game_reversi.png | Bin 235 -> 0 bytes applications/external/reversi/reversi.c | 168 - applications/external/reversi/reversi.h | 21 - applications/external/swd_probe/LICENSE.txt | 674 -- applications/external/swd_probe/adi.c | 1016 --- applications/external/swd_probe/adi.h | 34 - .../external/swd_probe/application.fam | 14 - applications/external/swd_probe/icons/app.png | Bin 179 -> 0 bytes applications/external/swd_probe/icons/swd.png | Bin 169 -> 0 bytes applications/external/swd_probe/jep106.c | 26 - applications/external/swd_probe/jep106.h | 26 - applications/external/swd_probe/jep106.inc | 1791 ------ .../external/swd_probe/model/chip.ply | 216 - .../external/swd_probe/model/convert.py | 39 - .../external/swd_probe/model/model_chip.h | 108 - .../external/swd_probe/swd_probe_app.c | 3189 ---------- .../external/swd_probe/swd_probe_app.h | 244 - applications/external/swd_probe/usb_uart.c | 229 - applications/external/swd_probe/usb_uart.h | 29 - .../external/timelapse/application.fam | 16 - applications/external/timelapse/gpio_item.c | 51 - applications/external/timelapse/gpio_item.h | 15 - .../timelapse/icons/ButtonDownHollow_7x4.png | Bin 173 -> 0 bytes .../timelapse/icons/ButtonLeftHollow_4x7.png | Bin 149 -> 0 bytes .../timelapse/icons/ButtonRightHollow_4x7.png | Bin 147 -> 0 bytes .../timelapse/icons/ButtonUpHollow_7x4.png | Bin 143 -> 0 bytes applications/external/timelapse/zeitraffer.c | 447 -- .../external/timelapse/zeitraffer.png | Bin 199 -> 0 bytes 162 files changed, 27310 deletions(-) delete mode 100644 applications/external/gpioreader_a/GPIO_reader.c delete mode 100644 applications/external/gpioreader_a/GPIO_reader_item.c delete mode 100644 applications/external/gpioreader_a/GPIO_reader_item.h delete mode 100644 applications/external/gpioreader_a/application.fam delete mode 100644 applications/external/gpioreader_a/icon.png delete mode 100644 applications/external/gpioreader_b/LICENSE delete mode 100644 applications/external/gpioreader_b/application.fam delete mode 100644 applications/external/gpioreader_b/gpio_app.c delete mode 100644 applications/external/gpioreader_b/gpio_app.h delete mode 100644 applications/external/gpioreader_b/gpio_app_i.h delete mode 100644 applications/external/gpioreader_b/gpio_custom_event.h delete mode 100644 applications/external/gpioreader_b/gpio_item.c delete mode 100644 applications/external/gpioreader_b/gpio_item.h delete mode 100644 applications/external/gpioreader_b/icon.png delete mode 100644 applications/external/gpioreader_b/scenes/gpio_scene.c delete mode 100644 applications/external/gpioreader_b/scenes/gpio_scene.h delete mode 100644 applications/external/gpioreader_b/scenes/gpio_scene_config.h delete mode 100644 applications/external/gpioreader_b/scenes/gpio_scene_reader.c delete mode 100644 applications/external/gpioreader_b/scenes/gpio_scene_start.c delete mode 100644 applications/external/gpioreader_b/scenes/gpio_scene_test.c delete mode 100644 applications/external/gpioreader_b/scenes/gpio_scene_usb_uart.c delete mode 100644 applications/external/gpioreader_b/scenes/gpio_scene_usb_uart_close_rpc.c delete mode 100644 applications/external/gpioreader_b/scenes/gpio_scene_usb_uart_config.c delete mode 100644 applications/external/gpioreader_b/usb_uart_bridge.c delete mode 100644 applications/external/gpioreader_b/usb_uart_bridge.h delete mode 100644 applications/external/gpioreader_b/views/gpio_reader.c delete mode 100644 applications/external/gpioreader_b/views/gpio_reader.h delete mode 100644 applications/external/gpioreader_b/views/gpio_test.c delete mode 100644 applications/external/gpioreader_b/views/gpio_test.h delete mode 100644 applications/external/gpioreader_b/views/gpio_usb_uart.c delete mode 100644 applications/external/gpioreader_b/views/gpio_usb_uart.h delete mode 100644 applications/external/gps_nmea_uart/LICENSE delete mode 100644 applications/external/gps_nmea_uart/application.fam delete mode 100644 applications/external/gps_nmea_uart/gps.c delete mode 100644 applications/external/gps_nmea_uart/gps_10px.png delete mode 100644 applications/external/gps_nmea_uart/gps_uart.c delete mode 100644 applications/external/gps_nmea_uart/gps_uart.h delete mode 100644 applications/external/gps_nmea_uart/minmea.c delete mode 100644 applications/external/gps_nmea_uart/minmea.h delete mode 100644 applications/external/metronome/application.fam delete mode 100644 applications/external/metronome/gui_extensions.c delete mode 100644 applications/external/metronome/gui_extensions.h delete mode 100644 applications/external/metronome/metronome.c delete mode 100644 applications/external/metronome/metronome_icon.png delete mode 100644 applications/external/passgen/LICENSE delete mode 100644 applications/external/passgen/application.fam delete mode 100644 applications/external/passgen/icons/Horizontal_arrow_9x7.png delete mode 100644 applications/external/passgen/icons/Vertical_arrow_7x9.png delete mode 100644 applications/external/passgen/icons/passgen_icon.png delete mode 100644 applications/external/passgen/images/preview.png delete mode 100644 applications/external/passgen/passgen.c delete mode 100644 applications/external/pomodoro/application.fam delete mode 100644 applications/external/pomodoro/flipp_pomodoro_10.png delete mode 100644 applications/external/pomodoro/flipp_pomodoro_app.c delete mode 100644 applications/external/pomodoro/flipp_pomodoro_app.h delete mode 100644 applications/external/pomodoro/flipp_pomodoro_app_i.h delete mode 100644 applications/external/pomodoro/helpers/debug.h delete mode 100644 applications/external/pomodoro/helpers/notifications.c delete mode 100644 applications/external/pomodoro/helpers/notifications.h delete mode 100644 applications/external/pomodoro/helpers/time.c delete mode 100644 applications/external/pomodoro/helpers/time.h delete mode 100644 applications/external/pomodoro/images/flipp_pomodoro_focus_64/frame_00.png delete mode 100644 applications/external/pomodoro/images/flipp_pomodoro_focus_64/frame_01.png delete mode 100644 applications/external/pomodoro/images/flipp_pomodoro_focus_64/frame_rate delete mode 100644 applications/external/pomodoro/images/flipp_pomodoro_learn_50x128.png delete mode 100644 applications/external/pomodoro/images/flipp_pomodoro_rest_64/frame_00.png delete mode 100644 applications/external/pomodoro/images/flipp_pomodoro_rest_64/frame_01.png delete mode 100644 applications/external/pomodoro/images/flipp_pomodoro_rest_64/frame_rate delete mode 100644 applications/external/pomodoro/modules/flipp_pomodoro.c delete mode 100644 applications/external/pomodoro/modules/flipp_pomodoro.h delete mode 100644 applications/external/pomodoro/modules/flipp_pomodoro_statistics.c delete mode 100644 applications/external/pomodoro/modules/flipp_pomodoro_statistics.h delete mode 100644 applications/external/pomodoro/scenes/.keep delete mode 100644 applications/external/pomodoro/scenes/config/flipp_pomodoro_scene_config.h delete mode 100644 applications/external/pomodoro/scenes/flipp_pomodoro_scene.c delete mode 100644 applications/external/pomodoro/scenes/flipp_pomodoro_scene.h delete mode 100644 applications/external/pomodoro/scenes/flipp_pomodoro_scene_info.c delete mode 100644 applications/external/pomodoro/scenes/flipp_pomodoro_scene_timer.c delete mode 100644 applications/external/pomodoro/views/.keep delete mode 100644 applications/external/pomodoro/views/flipp_pomodoro_info_view.c delete mode 100644 applications/external/pomodoro/views/flipp_pomodoro_info_view.h delete mode 100644 applications/external/pomodoro/views/flipp_pomodoro_timer_view.c delete mode 100644 applications/external/pomodoro/views/flipp_pomodoro_timer_view.h delete mode 100644 applications/external/qrcode/LICENSE delete mode 100644 applications/external/qrcode/application.fam delete mode 100644 applications/external/qrcode/icons/qrcode_10px.png delete mode 100644 applications/external/qrcode/qrcode.c delete mode 100644 applications/external/qrcode/qrcode.h delete mode 100644 applications/external/qrcode/qrcode_app.c delete mode 100644 applications/external/radar_scanner/LICENSE delete mode 100644 applications/external/radar_scanner/application.fam delete mode 100644 applications/external/radar_scanner/icon.png delete mode 100644 applications/external/radar_scanner/radar_scanner.c delete mode 100644 applications/external/rc2014_coleco/LICENSE delete mode 100644 applications/external/rc2014_coleco/application.fam delete mode 100644 applications/external/rc2014_coleco/coleco.c delete mode 100644 applications/external/rc2014_coleco/coleco_10px.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco0_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco0_hvr_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco1_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco1_hvr_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco2_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco2_hvr_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco3_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco3_hvr_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco4_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco4_hvr_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco5_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco5_hvr_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco6_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco6_hvr_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco7_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco7_hvr_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco8_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco8_hvr_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco9_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/Coleco9_hvr_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/ColecoAlt_18x9.png delete mode 100644 applications/external/rc2014_coleco/icons/ColecoAlt_hvr_18x9.png delete mode 100644 applications/external/rc2014_coleco/icons/ColecoFire_18x9.png delete mode 100644 applications/external/rc2014_coleco/icons/ColecoFire_hvr_18x9.png delete mode 100644 applications/external/rc2014_coleco/icons/ColecoFire_sel_18x9.png delete mode 100644 applications/external/rc2014_coleco/icons/ColecoJoystick_33x33.png delete mode 100644 applications/external/rc2014_coleco/icons/ColecoJoystick_hvr_33x33.png delete mode 100644 applications/external/rc2014_coleco/icons/ColecoJoystick_sel_33x33.png delete mode 100644 applications/external/rc2014_coleco/icons/ColecoPound_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/ColecoPound_hvr_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/ColecoStar_17x17.png delete mode 100644 applications/external/rc2014_coleco/icons/ColecoStar_hvr_17x17.png delete mode 100644 applications/external/rc2014_coleco/interface/flipper-coleco.brd delete mode 100644 applications/external/rc2014_coleco/interface/flipper-coleco.sch delete mode 100644 applications/external/reversi/LICENSE delete mode 100644 applications/external/reversi/application.fam delete mode 100644 applications/external/reversi/game_reversi.c delete mode 100644 applications/external/reversi/game_reversi.png delete mode 100644 applications/external/reversi/reversi.c delete mode 100644 applications/external/reversi/reversi.h delete mode 100644 applications/external/swd_probe/LICENSE.txt delete mode 100644 applications/external/swd_probe/adi.c delete mode 100644 applications/external/swd_probe/adi.h delete mode 100644 applications/external/swd_probe/application.fam delete mode 100644 applications/external/swd_probe/icons/app.png delete mode 100644 applications/external/swd_probe/icons/swd.png delete mode 100644 applications/external/swd_probe/jep106.c delete mode 100644 applications/external/swd_probe/jep106.h delete mode 100644 applications/external/swd_probe/jep106.inc delete mode 100644 applications/external/swd_probe/model/chip.ply delete mode 100644 applications/external/swd_probe/model/convert.py delete mode 100644 applications/external/swd_probe/model/model_chip.h delete mode 100644 applications/external/swd_probe/swd_probe_app.c delete mode 100644 applications/external/swd_probe/swd_probe_app.h delete mode 100644 applications/external/swd_probe/usb_uart.c delete mode 100644 applications/external/swd_probe/usb_uart.h delete mode 100644 applications/external/timelapse/application.fam delete mode 100644 applications/external/timelapse/gpio_item.c delete mode 100644 applications/external/timelapse/gpio_item.h delete mode 100644 applications/external/timelapse/icons/ButtonDownHollow_7x4.png delete mode 100644 applications/external/timelapse/icons/ButtonLeftHollow_4x7.png delete mode 100644 applications/external/timelapse/icons/ButtonRightHollow_4x7.png delete mode 100644 applications/external/timelapse/icons/ButtonUpHollow_7x4.png delete mode 100644 applications/external/timelapse/zeitraffer.c delete mode 100644 applications/external/timelapse/zeitraffer.png diff --git a/applications/external/gpioreader_a/GPIO_reader.c b/applications/external/gpioreader_a/GPIO_reader.c deleted file mode 100644 index eb5f95e67..000000000 --- a/applications/external/gpioreader_a/GPIO_reader.c +++ /dev/null @@ -1,152 +0,0 @@ -#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; - FuriMutex* mutex; -} PluginState; - -static void render_callback(Canvas* const canvas, void* ctx) { - furi_assert(ctx); - const PluginState* plugin_state = ctx; - furi_mutex_acquire(plugin_state->mutex, FuriWaitForever); - - 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)); - - furi_mutex_release(plugin_state->mutex); -} - -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - PluginEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void 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); - plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!plugin_state->mutex) { - 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, plugin_state); - 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); - furi_mutex_acquire(plugin_state->mutex, FuriWaitForever); - - 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; - } - } - } - } - - view_port_update(view_port); - furi_mutex_release(plugin_state->mutex); - } - - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - furi_record_close("gui"); - view_port_free(view_port); - furi_mutex_free(plugin_state->mutex); - furi_message_queue_free(event_queue); - free(plugin_state); - - return 0; -} \ No newline at end of file diff --git a/applications/external/gpioreader_a/GPIO_reader_item.c b/applications/external/gpioreader_a/GPIO_reader_item.c deleted file mode 100644 index 19a730ad0..000000000 --- a/applications/external/gpioreader_a/GPIO_reader_item.c +++ /dev/null @@ -1,27 +0,0 @@ -#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/external/gpioreader_a/GPIO_reader_item.h b/applications/external/gpioreader_a/GPIO_reader_item.h deleted file mode 100644 index da6bcc89f..000000000 --- a/applications/external/gpioreader_a/GPIO_reader_item.h +++ /dev/null @@ -1,42 +0,0 @@ -#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/external/gpioreader_a/application.fam b/applications/external/gpioreader_a/application.fam deleted file mode 100644 index 04bde0f14..000000000 --- a/applications/external/gpioreader_a/application.fam +++ /dev/null @@ -1,14 +0,0 @@ -App( - appid="gpio_reader", - name="[GPIO] Reader (aureli1c)", - apptype=FlipperAppType.EXTERNAL, - entry_point="GPIO_reader_app", - requires=["gui"], - stack_size=1 * 1024, - fap_category="GPIO", - fap_icon="icon.png", - fap_author="@aureli1c", - fap_weburl="https://github.com/aureli1c/flipperzero_GPIO_read", - fap_version="1.0", - fap_description="Read GPIO pins states, and display them on the screen", -) diff --git a/applications/external/gpioreader_a/icon.png b/applications/external/gpioreader_a/icon.png deleted file mode 100644 index 201d033e74e36c5488a571920b3fee257c3e03ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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| diff --git a/applications/external/gpioreader_b/LICENSE b/applications/external/gpioreader_b/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/applications/external/gpioreader_b/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - 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/external/gpioreader_b/application.fam b/applications/external/gpioreader_b/application.fam deleted file mode 100644 index 3e38301ba..000000000 --- a/applications/external/gpioreader_b/application.fam +++ /dev/null @@ -1,11 +0,0 @@ -App( - appid="gpioreader2", - name="[GPIO] Reader (biotinker)", - apptype=FlipperAppType.EXTERNAL, - entry_point="gpio_app", - requires=["gui"], - stack_size=1 * 1024, - fap_category="GPIO", - fap_icon="icon.png", - fap_icon_assets="icons", -) diff --git a/applications/external/gpioreader_b/gpio_app.c b/applications/external/gpioreader_b/gpio_app.c deleted file mode 100644 index 07a79cb89..000000000 --- a/applications/external/gpioreader_b/gpio_app.c +++ /dev/null @@ -1,111 +0,0 @@ -#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/external/gpioreader_b/gpio_app.h b/applications/external/gpioreader_b/gpio_app.h deleted file mode 100644 index 156ddc922..000000000 --- a/applications/external/gpioreader_b/gpio_app.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct GpioApp GpioApp; - -#ifdef __cplusplus -} -#endif diff --git a/applications/external/gpioreader_b/gpio_app_i.h b/applications/external/gpioreader_b/gpio_app_i.h deleted file mode 100644 index 00f269e9a..000000000 --- a/applications/external/gpioreader_b/gpio_app_i.h +++ /dev/null @@ -1,45 +0,0 @@ -#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 "gpioreader2_icons.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/external/gpioreader_b/gpio_custom_event.h b/applications/external/gpioreader_b/gpio_custom_event.h deleted file mode 100644 index f5648e10c..000000000 --- a/applications/external/gpioreader_b/gpio_custom_event.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -typedef enum { - GpioStartEventOtgOff = 0, - GpioStartEventOtgOn, - GpioStartEventManualControl, - GpioStartEventReader, - GpioStartEventUsbUart, - - GpioCustomEventErrorBack, - - GpioUsbUartEventConfig, - GpioUsbUartEventConfigSet, -} GpioCustomEvent; diff --git a/applications/external/gpioreader_b/gpio_item.c b/applications/external/gpioreader_b/gpio_item.c deleted file mode 100644 index 4d7f056ba..000000000 --- a/applications/external/gpioreader_b/gpio_item.c +++ /dev/null @@ -1,60 +0,0 @@ -#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/external/gpioreader_b/gpio_item.h b/applications/external/gpioreader_b/gpio_item.h deleted file mode 100644 index fe73e3851..000000000 --- a/applications/external/gpioreader_b/gpio_item.h +++ /dev/null @@ -1,17 +0,0 @@ -#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/external/gpioreader_b/icon.png b/applications/external/gpioreader_b/icon.png deleted file mode 100644 index 201d033e74e36c5488a571920b3fee257c3e03ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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| diff --git a/applications/external/gpioreader_b/scenes/gpio_scene.c b/applications/external/gpioreader_b/scenes/gpio_scene.c deleted file mode 100644 index d5aa4cbe8..000000000 --- a/applications/external/gpioreader_b/scenes/gpio_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#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/external/gpioreader_b/scenes/gpio_scene.h b/applications/external/gpioreader_b/scenes/gpio_scene.h deleted file mode 100644 index 15556c8d5..000000000 --- a/applications/external/gpioreader_b/scenes/gpio_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#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/external/gpioreader_b/scenes/gpio_scene_config.h b/applications/external/gpioreader_b/scenes/gpio_scene_config.h deleted file mode 100644 index 269c32aaf..000000000 --- a/applications/external/gpioreader_b/scenes/gpio_scene_config.h +++ /dev/null @@ -1,6 +0,0 @@ -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/external/gpioreader_b/scenes/gpio_scene_reader.c b/applications/external/gpioreader_b/scenes/gpio_scene_reader.c deleted file mode 100644 index 5995ff253..000000000 --- a/applications/external/gpioreader_b/scenes/gpio_scene_reader.c +++ /dev/null @@ -1,30 +0,0 @@ -#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/external/gpioreader_b/scenes/gpio_scene_start.c b/applications/external/gpioreader_b/scenes/gpio_scene_start.c deleted file mode 100644 index 19d0173fa..000000000 --- a/applications/external/gpioreader_b/scenes/gpio_scene_start.c +++ /dev/null @@ -1,114 +0,0 @@ -#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/external/gpioreader_b/scenes/gpio_scene_test.c b/applications/external/gpioreader_b/scenes/gpio_scene_test.c deleted file mode 100644 index b015d8090..000000000 --- a/applications/external/gpioreader_b/scenes/gpio_scene_test.c +++ /dev/null @@ -1,30 +0,0 @@ -#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/external/gpioreader_b/scenes/gpio_scene_usb_uart.c b/applications/external/gpioreader_b/scenes/gpio_scene_usb_uart.c deleted file mode 100644 index aa41aaf98..000000000 --- a/applications/external/gpioreader_b/scenes/gpio_scene_usb_uart.c +++ /dev/null @@ -1,67 +0,0 @@ -#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/external/gpioreader_b/scenes/gpio_scene_usb_uart_close_rpc.c b/applications/external/gpioreader_b/scenes/gpio_scene_usb_uart_close_rpc.c deleted file mode 100644 index 2cb53cab2..000000000 --- a/applications/external/gpioreader_b/scenes/gpio_scene_usb_uart_close_rpc.c +++ /dev/null @@ -1,41 +0,0 @@ -#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/external/gpioreader_b/scenes/gpio_scene_usb_uart_config.c b/applications/external/gpioreader_b/scenes/gpio_scene_usb_uart_config.c deleted file mode 100644 index 55b04ed67..000000000 --- a/applications/external/gpioreader_b/scenes/gpio_scene_usb_uart_config.c +++ /dev/null @@ -1,169 +0,0 @@ -#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/external/gpioreader_b/usb_uart_bridge.c b/applications/external/gpioreader_b/usb_uart_bridge.c deleted file mode 100644 index 1a82dbdc2..000000000 --- a/applications/external/gpioreader_b/usb_uart_bridge.c +++ /dev/null @@ -1,375 +0,0 @@ -#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/external/gpioreader_b/usb_uart_bridge.h b/applications/external/gpioreader_b/usb_uart_bridge.h deleted file mode 100644 index b456c3cc4..000000000 --- a/applications/external/gpioreader_b/usb_uart_bridge.h +++ /dev/null @@ -1,30 +0,0 @@ -#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/external/gpioreader_b/views/gpio_reader.c b/applications/external/gpioreader_b/views/gpio_reader.c deleted file mode 100644 index 4b3a18f8e..000000000 --- a/applications/external/gpioreader_b/views/gpio_reader.c +++ /dev/null @@ -1,160 +0,0 @@ -#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/external/gpioreader_b/views/gpio_reader.h b/applications/external/gpioreader_b/views/gpio_reader.h deleted file mode 100644 index a59618d57..000000000 --- a/applications/external/gpioreader_b/views/gpio_reader.h +++ /dev/null @@ -1,17 +0,0 @@ -#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/external/gpioreader_b/views/gpio_test.c b/applications/external/gpioreader_b/views/gpio_test.c deleted file mode 100644 index 69dc0f67b..000000000 --- a/applications/external/gpioreader_b/views/gpio_test.c +++ /dev/null @@ -1,139 +0,0 @@ -#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/external/gpioreader_b/views/gpio_test.h b/applications/external/gpioreader_b/views/gpio_test.h deleted file mode 100644 index 5cbd11e82..000000000 --- a/applications/external/gpioreader_b/views/gpio_test.h +++ /dev/null @@ -1,14 +0,0 @@ -#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/external/gpioreader_b/views/gpio_usb_uart.c b/applications/external/gpioreader_b/views/gpio_usb_uart.c deleted file mode 100644 index 14f8c12fe..000000000 --- a/applications/external/gpioreader_b/views/gpio_usb_uart.c +++ /dev/null @@ -1,161 +0,0 @@ -#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_ex(canvas, 48, 34, &I_ArrowUpFilled_14x15, IconRotation180); - else - canvas_draw_icon_ex(canvas, 48, 34, &I_ArrowUpEmpty_14x15, IconRotation180); -} - -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/external/gpioreader_b/views/gpio_usb_uart.h b/applications/external/gpioreader_b/views/gpio_usb_uart.h deleted file mode 100644 index 854b51f8d..000000000 --- a/applications/external/gpioreader_b/views/gpio_usb_uart.h +++ /dev/null @@ -1,18 +0,0 @@ -#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/external/gps_nmea_uart/LICENSE b/applications/external/gps_nmea_uart/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/applications/external/gps_nmea_uart/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - 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/external/gps_nmea_uart/application.fam b/applications/external/gps_nmea_uart/application.fam deleted file mode 100644 index 1bc46d535..000000000 --- a/applications/external/gps_nmea_uart/application.fam +++ /dev/null @@ -1,13 +0,0 @@ -App( - appid="gps_nmea", - name="[NMEA] GPS", - apptype=FlipperAppType.EXTERNAL, - entry_point="gps_app", - requires=["gui"], - stack_size=1 * 1024, - fap_icon="gps_10px.png", - fap_category="GPIO", - fap_author="@ezod & @xMasterX", - fap_version="1.0", - fap_description="Works with GPS modules via UART, using NMEA protocol.", -) diff --git a/applications/external/gps_nmea_uart/gps.c b/applications/external/gps_nmea_uart/gps.c deleted file mode 100644 index c7d882d20..000000000 --- a/applications/external/gps_nmea_uart/gps.c +++ /dev/null @@ -1,199 +0,0 @@ -#include "gps_uart.h" - -#include -#include -#include - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} PluginEvent; - -static void render_callback(Canvas* const canvas, void* context) { - furi_assert(context); - GpsUart* gps_uart = context; - furi_mutex_acquire(gps_uart->mutex, FuriWaitForever); - - if(!gps_uart->changing_baudrate) { - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 32, 8, AlignCenter, AlignBottom, "Latitude"); - canvas_draw_str_aligned(canvas, 96, 8, AlignCenter, AlignBottom, "Longitude"); - canvas_draw_str_aligned(canvas, 21, 30, AlignCenter, AlignBottom, "Course"); - canvas_draw_str_aligned(canvas, 64, 30, AlignCenter, AlignBottom, "Speed"); - canvas_draw_str_aligned(canvas, 107, 30, AlignCenter, AlignBottom, "Altitude"); - canvas_draw_str_aligned(canvas, 32, 52, AlignCenter, AlignBottom, "Satellites"); - canvas_draw_str_aligned(canvas, 96, 52, AlignCenter, AlignBottom, "Last Fix"); - - canvas_set_font(canvas, FontSecondary); - char buffer[64]; - snprintf(buffer, 64, "%f", (double)gps_uart->status.latitude); - canvas_draw_str_aligned(canvas, 32, 18, AlignCenter, AlignBottom, buffer); - snprintf(buffer, 64, "%f", (double)gps_uart->status.longitude); - canvas_draw_str_aligned(canvas, 96, 18, AlignCenter, AlignBottom, buffer); - snprintf(buffer, 64, "%.1f", (double)gps_uart->status.course); - canvas_draw_str_aligned(canvas, 21, 40, AlignCenter, AlignBottom, buffer); - if(!gps_uart->speed_in_kms) { - snprintf(buffer, 64, "%.2f kn", (double)gps_uart->status.speed); - } else { - snprintf(buffer, 64, "%.2f km", (double)(gps_uart->status.speed * 1.852)); - } - canvas_draw_str_aligned(canvas, 64, 40, AlignCenter, AlignBottom, buffer); - snprintf( - buffer, - 64, - "%.1f %c", - (double)gps_uart->status.altitude, - tolower(gps_uart->status.altitude_units)); - canvas_draw_str_aligned(canvas, 107, 40, AlignCenter, AlignBottom, buffer); - snprintf(buffer, 64, "%d", gps_uart->status.satellites_tracked); - canvas_draw_str_aligned(canvas, 32, 62, AlignCenter, AlignBottom, buffer); - snprintf( - buffer, - 64, - "%02d:%02d:%02d UTC", - gps_uart->status.time_hours, - gps_uart->status.time_minutes, - gps_uart->status.time_seconds); - canvas_draw_str_aligned(canvas, 96, 62, AlignCenter, AlignBottom, buffer); - } else { - char buffer[64]; - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignBottom, "Baudrate set to:"); - - snprintf(buffer, 64, "%ld baud", gps_uart->baudrate); - canvas_draw_str_aligned(canvas, 64, 47, AlignCenter, AlignBottom, buffer); - } - - furi_mutex_release(gps_uart->mutex); -} - -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - PluginEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -int32_t gps_app(void* p) { - UNUSED(p); - - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); - - GpsUart* gps_uart = gps_uart_enable(); - - gps_uart->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!gps_uart->mutex) { - FURI_LOG_E("GPS", "cannot create mutex\r\n"); - free(gps_uart); - return 255; - } - - uint8_t attempts = 0; - bool otg_was_enabled = furi_hal_power_is_otg_enabled(); - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - furi_delay_ms(10); - } - furi_delay_ms(200); - - // set system callbacks - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, render_callback, gps_uart); - 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); - - furi_mutex_acquire(gps_uart->mutex, FuriWaitForever); - - if(event_status == FuriStatusOk) { - // press events - if(event.type == EventTypeKey) { - if(event.input.type == InputTypeShort) { - switch(event.input.key) { - case InputKeyBack: - processing = false; - break; - case InputKeyOk: - if(!gps_uart->backlight_on) { - notification_message_block( - gps_uart->notifications, &sequence_display_backlight_enforce_on); - gps_uart->backlight_on = true; - } else { - notification_message_block( - gps_uart->notifications, &sequence_display_backlight_enforce_auto); - notification_message( - gps_uart->notifications, &sequence_display_backlight_off); - gps_uart->backlight_on = false; - } - break; - default: - break; - } - } else if(event.input.type == InputTypeLong) { - switch(event.input.key) { - case InputKeyUp: - gps_uart_deinit_thread(gps_uart); - const int baudrate_length = - sizeof(gps_baudrates) / sizeof(gps_baudrates[0]); - current_gps_baudrate++; - if(current_gps_baudrate >= baudrate_length) { - current_gps_baudrate = 0; - } - gps_uart->baudrate = gps_baudrates[current_gps_baudrate]; - - gps_uart_init_thread(gps_uart); - gps_uart->changing_baudrate = true; - view_port_update(view_port); - furi_mutex_release(gps_uart->mutex); - break; - case InputKeyRight: - if(gps_uart->speed_in_kms) { - gps_uart->speed_in_kms = false; - } else { - gps_uart->speed_in_kms = true; - } - break; - case InputKeyBack: - processing = false; - break; - default: - break; - } - } - } - } - if(!gps_uart->changing_baudrate) { - view_port_update(view_port); - furi_mutex_release(gps_uart->mutex); - } else { - furi_delay_ms(1000); - gps_uart->changing_baudrate = false; - } - } - - notification_message_block(gps_uart->notifications, &sequence_display_backlight_enforce_auto); - 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(gps_uart->mutex); - gps_uart_disable(gps_uart); - - if(furi_hal_power_is_otg_enabled() && !otg_was_enabled) { - furi_hal_power_disable_otg(); - } - - return 0; -} diff --git a/applications/external/gps_nmea_uart/gps_10px.png b/applications/external/gps_nmea_uart/gps_10px.png deleted file mode 100644 index 841787a2a6131015634e906ff1cd4f189e0855aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6750 zcmeHKc{r5q_a9lZ6D`&nqa=*k#~Aw>N|wkjvoe;MF*6t>YsfwoWiOSKt%RtA>a`R~ zi9#VI6{3=Q72k(?dwZ|n_n-H=e&7F^>ze1epL3t{Ip=)tbKlo}4%_e9DIuyL3Ic&7 ztgXx)f%nQ-RCo>WTx0M01{lvoIJt5h31MI+i$SFYQox*WCIw94(x@O1cd*;dBS%%G z>Z|XD%L3BEtt@Ubo4Pjai)>u&P!-GhczJZy)0ex?p-jvt*Oe45jYJ<`l=40dX}s;o z>V7hw?SG+<>G(Cg?wkC9!Q#w;sl|sOVau`19na{{E^_wjwHZ#~_2 zY(8XxS7|-~o#XHLa_~U-Q^AAXcM_Kf6HZmAh#Q;p_qUfwO%9E?U#@7PR+O9-FZ)ne zHstt8e&+3oo2A;4r4-m_lDNvE*PJ%9kI&`A!Os~B!Wd~+Ha!3lh_vgcJ> zMS4#*z;e``XffA(D*jl%Q3O|TDW>-l&5k!ypI{I)e{1@QD7A?1iermU>(}Q`uS71y z)@iLboqd_HVG4r0NJvEZ7B@(wC4|J@Q5+pw9KXv=_sNo=i19>y7UfIWpO1<>SHnNI zY@567lNBxjN`_-@osez?xr*`3B)yZj3V_^(ce@%vqmrZoS8~CVBn& z2R2&gnVl9kJL+m}Fc2E6+u8qoU45diq9vVsbu6(TKmT~I?*RL_cf@p1OO&O8{`)Kk zOXZ*kX|i8P6FV+<;q!$KY0@0~D@rWN>jhmrdMj(WFSnIfTpcW|OYOINr{gNNDWEpD zM)75jLRHFeqHxZh$2fjM8H6t_)d7^GHr{nSOGcjEmRp@r<`c&YEa>)0i)}p<%RQtR zmLYk%ZP;jTVynTNWizEmK7@f>$i3oHVXJ9ILWP#xH=bYDn-r`63gyqx5;8~0Ya zYX)v0^Xle{kb604MMEzP=&7Gx?3n2kvD@G?>>I8y*yPKf5tVS3H`YuOw94Jep8?js zHCH>I9c!9S+Xhz(0e22)@azx0nUt{B+v@OGL(z8Rn)=xKKlpN7h{ts*RLh}_)y1tv zQ>8<$YU)Ch?IJ>5i`cZaLY5bp-*9lF*9pRt2W`mSg}#c(@$O&bBw+QX$-BAs-R;raxg(2>eEEW=5ZArjH#tLYx(NfaK#C`U?nD-Ik?j?W4T!(1V*6QOL zdVdY<&<$hHY@McIH*!U45ZCGHl#1&eZ>u|}^E30St2J-OJjmc|J{;q5mi+h(_r(#C_j)Nr$E+_>k;jnNM}j-$f2URbjnI8mx_GPM+< zo9L$Hiww>Wa)wW@zi7Js@EIp3;bL!GyNK@tGbUeCs;lvaVJWzqeavn)|Ktsdm#M=Q z({-OkQ>wyWiw2L#ftDYDBoo7hjtvcGs*B%Znt@>V1)D{adc01L=Q1nn5kxb5b&-SV zXnFG0w2CYb`AUTLDSFw2(%5z9MGUZJgdX#q#` zUIohboWk^_I3B)^5%rXRRBoD5m0LOLdZF;8WK3i_r~@ld3^M<$EX)V4>9-#I+ysht z8no3s-m%>$X}@0^R5 zw4;4hmpI!S!dYV<{5FbiX?q(we>?7))Q)9pK5Bew>(=2jVty*kma`eBKtgAq8QWuw zI&OPo5NHLH^(EmvaYz=sQYq@(y3v$3mdpCV*zPK6dHNo%W z(Q@?5Ou*v3c>R0vHCwc{Z1ky{)oPu_D1oBu6Ja@{-t1XJ!I{+COIX1f=wkD!mZpi( zDAC~n$!F(Unq-AW97dms#J^K#zDsBgTi+0Nb5u`sSdTEPEI2cQ>UE1-T-eRoIJ#sY zTX=f0iFLrcc`-^O5_l3cP|ky=-d`)J6y|HPbLwa>y6f4ikA*EQTWJ;n4H6e!f}l((xwh4!Sp}fp~=CjU+#PL<(-V>bIY4g zQI1lmc>HHQQozJAShhBO<`hH8-kgU%_r|QkzM((VWYKhcce94cf@)`neQf`@ac!-- zV9hoXmviaPhO)^nE7f5CiCT!$Qn66`rt*$mf^xJ(3Q|Yr?v*}F*`uW!*5@yIyP25O!jaDvRn( zNZs?=n`3$l@0!#w`1W1VL(7ssx;*%z4LZ-AUVM{8C+ZhZ#|32_)|5-oC1ljyJ+3>> zEkMO{1JEep&0_2+Be#91>`$lwy4?9`r4~wnUAI$knS?`@1SKj>D2vHi*Zt1+iiXT4O0Esw5;xvwW4hDpl{&vft~uI@`Q#wYKl+Hi zX+rzi3p(vPKQNZdI`X@N7Dfv)nj!Zkyhg*Y(lh${7h|;Q*6OHb75AnnUZkr=zEcT7 z7+`o3{WXlVi~=G(At%wm{&v~h&RnIY@sOdHcK%I7>C{0)hxUGx4)SJ3QFExY_SOz= zYHR3bdf#V(53gv$3m;(l?=}aYSduyuW^8vh^vX#TKOHfU_=nP1&?45zqkd6hbM+{* zxpn+e?>C`L7iPoA=-ivh&9f&WrRrU$rs#STr|S1VK0V#jO;((xi4UpmiObPTYg!id z>htMUNGV#h`LwjJ$?i(T8yz*?0ko_}L*=mlP!M~5-&4rB=^7Rqvd;ub_tW`!h^^!8*$;%6FG_ZsVnSox?l#$5{ z$j)LWCNx0{Q?Q@66=-}L%v@r5?raUJEKJd-O|Loi`lPvz>%L?4gF^c<{jWLH(x1{h2f4&8@m6HQF>>&xTPZR}wwc+c>rM8c~>|X?xFo_*nGeVAMz?*uLXLj>mvhP9dAfyNGSR zScbWN-&|R`#7pPtlq(u<@n}ALXF8s-=v4XU-I6DCE+N1)T}|JgT39ffGCLcgUCy<` z`IXK$%;qwyRV74?)Ss%qFModQ9-lL6va7A_Q2b5z3vub9*oPV0^v{&0dDQnwb#2nE z;+kE`?#w@H_$Z-UB$D1{CwMg(-idZVi@&cpqO!BNpk7@Y(J19I7xw2;S%Y|RB{78* zhtcAUWd0dH^5kk~Yb^2X1ia5E@>!$~da7li{#BH6__GB>pJD4+uTRw*d|sG+oUYl3 zPw2PBHERU4X?q5mw3GIQarR%xR<=?bn|8WE;~S)(q@6$E@w(_}fC+GuS!)PhS3MM4Zk!TKyR z74K+n`2zy@GJyDTI7~bY78Vw!9fs0ouzX<%U0q!m90@}rp@0UI9Zu&ExKKJR;jo|}*sm6B zjzuT{@*|-CYQc5_x;dC5h0O?Ikti0S6go%sR|qocr#&--6}XxXnFON*Qi1?gHsBTU z50^WwZS8+rtWe-f3u3NX0c8I}lS8BaP1ZkRTbWr+=hr|0^Pjl?(Ecm;Rb@cS))sHh zAcd@iXKii(S@Dl2Ge|TteszdI6H#ak3JoRdlBiHL0f~a*5Lg_POeLXF1R_e8L?-?M zWld*u2y_x<1quMyrU5uOA_Aw2#*v{!0ul{HQ*Z<*j*7%Wb+H&Uk&4xYlMvKjAnaH) zpehN0zecqJMFyadIyeGZ2abedbqR1N8biQ9aTF{HO2r}ofex93A?mC`kx6(<1}lgF zEGI39;7frq>AtHID}>`s?5zzTNNxDv68k^`hYA=NKz7sUA>6+woM=Imy&S>{n+Plx zjYFe!acDFO36S!)(mo1{4OHR^CIYUF`i{G@EO;OpfLOvxodN)>7CwjMqD;gWn2w$oAA2q+168!z^`xXeKtxkc#t7VHPkiI)%6GAEE zRY!o`_bHMef$mEI_VZ?@l_-8C(ev}oS;K1HSz@c!I6B3R`>Eh97 zC>)K4!y&LA3By))^v2~ulW5<*KfN16$AfD`FC~wrt4oZ@UN7ASJ(d=U7~+CJQO-`3kn0;nLR4E=s+tZ zMBKI0e6=Y8eKETh4U9yXR&Hz%Nb=UopRb)!Mh1jyIo7roYbQhnK-;xcg!t_Mk)gG@ ziId#JC_58L5LkFk|8n#0q#VtdI_7nTOM{9kWsWx^X#T`-*RCi#_I5rap210ZsbrQ~&?~ diff --git a/applications/external/gps_nmea_uart/gps_uart.c b/applications/external/gps_nmea_uart/gps_uart.c deleted file mode 100644 index c7220da51..000000000 --- a/applications/external/gps_nmea_uart/gps_uart.c +++ /dev/null @@ -1,226 +0,0 @@ -#include - -#include "minmea.h" -#include "gps_uart.h" - -typedef enum { - WorkerEvtStop = (1 << 0), - WorkerEvtRxDone = (1 << 1), -} WorkerEvtFlags; - -#define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone) - -static void gps_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) { - GpsUart* gps_uart = (GpsUart*)context; - - if(ev == UartIrqEventRXNE) { - furi_stream_buffer_send(gps_uart->rx_stream, &data, 1, 0); - furi_thread_flags_set(furi_thread_get_id(gps_uart->thread), WorkerEvtRxDone); - } -} - -static void gps_uart_serial_init(GpsUart* gps_uart) { - if(UART_CH == FuriHalUartIdUSART1) { - furi_hal_console_disable(); - } else if(UART_CH == FuriHalUartIdLPUART1) { - furi_hal_uart_init(UART_CH, gps_uart->baudrate); - } - - furi_hal_uart_set_irq_cb(UART_CH, gps_uart_on_irq_cb, gps_uart); - furi_hal_uart_set_br(UART_CH, gps_uart->baudrate); -} - -static void gps_uart_serial_deinit(GpsUart* gps_uart) { - UNUSED(gps_uart); - furi_hal_uart_set_irq_cb(UART_CH, NULL, NULL); - if(UART_CH == FuriHalUartIdLPUART1) { - furi_hal_uart_deinit(UART_CH); - } else { - furi_hal_console_enable(); - } -} - -static void gps_uart_parse_nmea(GpsUart* gps_uart, char* line) { - switch(minmea_sentence_id(line, false)) { - case MINMEA_SENTENCE_RMC: { - struct minmea_sentence_rmc frame; - if(minmea_parse_rmc(&frame, line)) { - gps_uart->status.valid = frame.valid; - gps_uart->status.latitude = minmea_tocoord(&frame.latitude); - gps_uart->status.longitude = minmea_tocoord(&frame.longitude); - gps_uart->status.speed = minmea_tofloat(&frame.speed); - gps_uart->status.course = minmea_tofloat(&frame.course); - gps_uart->status.time_hours = frame.time.hours; - gps_uart->status.time_minutes = frame.time.minutes; - gps_uart->status.time_seconds = frame.time.seconds; - - notification_message_block(gps_uart->notifications, &sequence_blink_green_10); - } - } break; - - case MINMEA_SENTENCE_GGA: { - struct minmea_sentence_gga frame; - if(minmea_parse_gga(&frame, line)) { - gps_uart->status.latitude = minmea_tocoord(&frame.latitude); - gps_uart->status.longitude = minmea_tocoord(&frame.longitude); - gps_uart->status.altitude = minmea_tofloat(&frame.altitude); - gps_uart->status.altitude_units = frame.altitude_units; - gps_uart->status.fix_quality = frame.fix_quality; - gps_uart->status.satellites_tracked = frame.satellites_tracked; - gps_uart->status.time_hours = frame.time.hours; - gps_uart->status.time_minutes = frame.time.minutes; - gps_uart->status.time_seconds = frame.time.seconds; - - notification_message_block(gps_uart->notifications, &sequence_blink_magenta_10); - } - } break; - - case MINMEA_SENTENCE_GLL: { - struct minmea_sentence_gll frame; - if(minmea_parse_gll(&frame, line)) { - gps_uart->status.latitude = minmea_tocoord(&frame.latitude); - gps_uart->status.longitude = minmea_tocoord(&frame.longitude); - gps_uart->status.time_hours = frame.time.hours; - gps_uart->status.time_minutes = frame.time.minutes; - gps_uart->status.time_seconds = frame.time.seconds; - - notification_message_block(gps_uart->notifications, &sequence_blink_red_10); - } - } break; - - default: - break; - } -} - -static int32_t gps_uart_worker(void* context) { - GpsUart* gps_uart = (GpsUart*)context; - - size_t rx_offset = 0; - - 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 = 0; - do { - // receive serial bytes into rx_buf, starting at rx_offset from the start of the buffer - // the maximum we can receive is RX_BUF_SIZE - 1 - rx_offset - len = furi_stream_buffer_receive( - gps_uart->rx_stream, - gps_uart->rx_buf + rx_offset, - RX_BUF_SIZE - 1 - rx_offset, - 0); - if(len > 0) { - // increase rx_offset by the number of bytes received, and null-terminate rx_buf - rx_offset += len; - gps_uart->rx_buf[rx_offset] = '\0'; - - // look for strings ending in newlines, starting at the start of rx_buf - char* line_current = (char*)gps_uart->rx_buf; - while(1) { - // skip null characters - while(*line_current == '\0' && - line_current < (char*)gps_uart->rx_buf + rx_offset - 1) { - line_current++; - } - - // find the next newline - char* newline = strchr(line_current, '\n'); - if(newline) // newline found - { - // put a null terminator in place of the newline, to delimit the line string - *newline = '\0'; - - // attempt to parse the line as a NMEA sentence - gps_uart_parse_nmea(gps_uart, line_current); - - // move the cursor to the character after the newline - line_current = newline + 1; - } else // no more newlines found - { - if(line_current > - (char*)gps_uart->rx_buf) // at least one line was found - { - // clear parsed lines, and move any leftover bytes to the start of rx_buf - rx_offset = 0; - while( - *line_current) // stop when the original rx_offset terminator is reached - { - gps_uart->rx_buf[rx_offset++] = *(line_current++); - } - } - break; // go back to receiving bytes from the serial stream - } - } - } - } while(len > 0); - } - } - - gps_uart_serial_deinit(gps_uart); - furi_stream_buffer_free(gps_uart->rx_stream); - - return 0; -} - -void gps_uart_init_thread(GpsUart* gps_uart) { - furi_assert(gps_uart); - gps_uart->status.valid = false; - gps_uart->status.latitude = 0.0; - gps_uart->status.longitude = 0.0; - gps_uart->status.speed = 0.0; - gps_uart->status.course = 0.0; - gps_uart->status.altitude = 0.0; - gps_uart->status.altitude_units = ' '; - gps_uart->status.fix_quality = 0; - gps_uart->status.satellites_tracked = 0; - gps_uart->status.time_hours = 0; - gps_uart->status.time_minutes = 0; - gps_uart->status.time_seconds = 0; - - gps_uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE * 5, 1); - - gps_uart->thread = furi_thread_alloc(); - furi_thread_set_name(gps_uart->thread, "GpsUartWorker"); - furi_thread_set_stack_size(gps_uart->thread, 1024); - furi_thread_set_context(gps_uart->thread, gps_uart); - furi_thread_set_callback(gps_uart->thread, gps_uart_worker); - - furi_thread_start(gps_uart->thread); - - gps_uart_serial_init(gps_uart); -} - -void gps_uart_deinit_thread(GpsUart* gps_uart) { - furi_assert(gps_uart); - furi_thread_flags_set(furi_thread_get_id(gps_uart->thread), WorkerEvtStop); - furi_thread_join(gps_uart->thread); - furi_thread_free(gps_uart->thread); -} - -GpsUart* gps_uart_enable() { - GpsUart* gps_uart = malloc(sizeof(GpsUart)); - - gps_uart->notifications = furi_record_open(RECORD_NOTIFICATION); - - gps_uart->baudrate = gps_baudrates[current_gps_baudrate]; - - gps_uart_init_thread(gps_uart); - - return gps_uart; -} - -void gps_uart_disable(GpsUart* gps_uart) { - furi_assert(gps_uart); - gps_uart_deinit_thread(gps_uart); - furi_record_close(RECORD_NOTIFICATION); - - free(gps_uart); -} diff --git a/applications/external/gps_nmea_uart/gps_uart.h b/applications/external/gps_nmea_uart/gps_uart.h deleted file mode 100644 index 428168a2d..000000000 --- a/applications/external/gps_nmea_uart/gps_uart.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include -#include -#include - -#define UART_CH \ - (xtreme_settings.uart_nmea_channel == UARTDefault ? FuriHalUartIdUSART1 : FuriHalUartIdLPUART1) - -#define RX_BUF_SIZE 1024 - -static const int gps_baudrates[5] = {9600, 19200, 38400, 57600, 115200}; -static int current_gps_baudrate = 0; - -typedef struct { - bool valid; - float latitude; - float longitude; - float speed; - float course; - float altitude; - char altitude_units; - int fix_quality; - int satellites_tracked; - int time_hours; - int time_minutes; - int time_seconds; -} GpsStatus; - -typedef struct { - FuriMutex* mutex; - FuriThread* thread; - FuriStreamBuffer* rx_stream; - uint8_t rx_buf[RX_BUF_SIZE]; - - NotificationApp* notifications; - uint32_t baudrate; - bool changing_baudrate; - bool backlight_on; - bool speed_in_kms; - - GpsStatus status; -} GpsUart; - -void gps_uart_init_thread(GpsUart* gps_uart); -void gps_uart_deinit_thread(GpsUart* gps_uart); - -GpsUart* gps_uart_enable(); - -void gps_uart_disable(GpsUart* gps_uart); diff --git a/applications/external/gps_nmea_uart/minmea.c b/applications/external/gps_nmea_uart/minmea.c deleted file mode 100644 index 1b7a84b1c..000000000 --- a/applications/external/gps_nmea_uart/minmea.c +++ /dev/null @@ -1,640 +0,0 @@ -/* - * Copyright © 2014 Kosma Moczek - * This program is free software. It comes without any warranty, to the extent - * permitted by applicable law. You can redistribute it and/or modify it under - * the terms of the Do What The Fuck You Want To Public License, Version 2, as - * published by Sam Hocevar. See the COPYING file for more details. - */ - -#include "minmea.h" - -#include -#include -#include - -#define boolstr(s) ((s) ? "true" : "false") - -static int hex2int(char c) { - if(c >= '0' && c <= '9') return c - '0'; - if(c >= 'A' && c <= 'F') return c - 'A' + 10; - if(c >= 'a' && c <= 'f') return c - 'a' + 10; - return -1; -} - -uint8_t minmea_checksum(const char* sentence) { - // Support senteces with or without the starting dollar sign. - if(*sentence == '$') sentence++; - - uint8_t checksum = 0x00; - - // The optional checksum is an XOR of all bytes between "$" and "*". - while(*sentence && *sentence != '*') checksum ^= *sentence++; - - return checksum; -} - -bool minmea_check(const char* sentence, bool strict) { - uint8_t checksum = 0x00; - - // A valid sentence starts with "$". - if(*sentence++ != '$') return false; - - // The optional checksum is an XOR of all bytes between "$" and "*". - while(*sentence && *sentence != '*' && isprint((unsigned char)*sentence)) - checksum ^= *sentence++; - - // If checksum is present... - if(*sentence == '*') { - // Extract checksum. - sentence++; - int upper = hex2int(*sentence++); - if(upper == -1) return false; - int lower = hex2int(*sentence++); - if(lower == -1) return false; - int expected = upper << 4 | lower; - - // Check for checksum mismatch. - if(checksum != expected) return false; - } else if(strict) { - // Discard non-checksummed frames in strict mode. - return false; - } - - // The only stuff allowed at this point is a newline. - while(*sentence == '\r' || *sentence == '\n') { - sentence++; - } - - if(*sentence) { - return false; - } - - return true; -} - -bool minmea_scan(const char* sentence, const char* format, ...) { - bool result = false; - bool optional = false; - - if(sentence == NULL) return false; - - va_list ap; - va_start(ap, format); - - const char* field = sentence; -#define next_field() \ - do { \ - /* Progress to the next field. */ \ - while(minmea_isfield(*sentence)) sentence++; \ - /* Make sure there is a field there. */ \ - if(*sentence == ',') { \ - sentence++; \ - field = sentence; \ - } else { \ - field = NULL; \ - } \ - } while(0) - - while(*format) { - char type = *format++; - - if(type == ';') { - // All further fields are optional. - optional = true; - continue; - } - - if(!field && !optional) { - // Field requested but we ran out if input. Bail out. - goto parse_error; - } - - switch(type) { - case 'c': { // Single character field (char). - char value = '\0'; - - if(field && minmea_isfield(*field)) value = *field; - - *va_arg(ap, char*) = value; - } break; - - case 'd': { // Single character direction field (int). - int value = 0; - - if(field && minmea_isfield(*field)) { - switch(*field) { - case 'N': - case 'E': - value = 1; - break; - case 'S': - case 'W': - value = -1; - break; - default: - goto parse_error; - } - } - - *va_arg(ap, int*) = value; - } break; - - case 'f': { // Fractional value with scale (struct minmea_float). - int sign = 0; - int_least32_t value = -1; - int_least32_t scale = 0; - - if(field) { - while(minmea_isfield(*field)) { - if(*field == '+' && !sign && value == -1) { - sign = 1; - } else if(*field == '-' && !sign && value == -1) { - sign = -1; - } else if(isdigit((unsigned char)*field)) { - int digit = *field - '0'; - if(value == -1) value = 0; - if(value > (INT_LEAST32_MAX - digit) / 10) { - /* we ran out of bits, what do we do? */ - if(scale) { - /* truncate extra precision */ - break; - } else { - /* integer overflow. bail out. */ - goto parse_error; - } - } - value = (10 * value) + digit; - if(scale) scale *= 10; - } else if(*field == '.' && scale == 0) { - scale = 1; - } else if(*field == ' ') { - /* Allow spaces at the start of the field. Not NMEA - * conformant, but some modules do this. */ - if(sign != 0 || value != -1 || scale != 0) goto parse_error; - } else { - goto parse_error; - } - field++; - } - } - - if((sign || scale) && value == -1) goto parse_error; - - if(value == -1) { - /* No digits were scanned. */ - value = 0; - scale = 0; - } else if(scale == 0) { - /* No decimal point. */ - scale = 1; - } - if(sign) value *= sign; - - *va_arg(ap, struct minmea_float*) = (struct minmea_float){value, scale}; - } break; - - case 'i': { // Integer value, default 0 (int). - int value = 0; - - if(field) { - char* endptr; - value = strtol(field, &endptr, 10); - if(minmea_isfield(*endptr)) goto parse_error; - } - - *va_arg(ap, int*) = value; - } break; - - case 's': { // String value (char *). - char* buf = va_arg(ap, char*); - - if(field) { - while(minmea_isfield(*field)) *buf++ = *field++; - } - - *buf = '\0'; - } break; - - case 't': { // NMEA talker+sentence identifier (char *). - // This field is always mandatory. - if(!field) goto parse_error; - - if(field[0] != '$') goto parse_error; - for(int f = 0; f < 5; f++) - if(!minmea_isfield(field[1 + f])) goto parse_error; - - char* buf = va_arg(ap, char*); - memcpy(buf, field + 1, 5); - buf[5] = '\0'; - } break; - - case 'D': { // Date (int, int, int), -1 if empty. - struct minmea_date* date = va_arg(ap, struct minmea_date*); - - int d = -1, m = -1, y = -1; - - if(field && minmea_isfield(*field)) { - // Always six digits. - for(int f = 0; f < 6; f++) - if(!isdigit((unsigned char)field[f])) goto parse_error; - - char dArr[] = {field[0], field[1], '\0'}; - char mArr[] = {field[2], field[3], '\0'}; - char yArr[] = {field[4], field[5], '\0'}; - d = strtol(dArr, NULL, 10); - m = strtol(mArr, NULL, 10); - y = strtol(yArr, NULL, 10); - } - - date->day = d; - date->month = m; - date->year = y; - } break; - - case 'T': { // Time (int, int, int, int), -1 if empty. - struct minmea_time* time_ = va_arg(ap, struct minmea_time*); - - int h = -1, i = -1, s = -1, u = -1; - - if(field && minmea_isfield(*field)) { - // Minimum required: integer time. - for(int f = 0; f < 6; f++) - if(!isdigit((unsigned char)field[f])) goto parse_error; - - char hArr[] = {field[0], field[1], '\0'}; - char iArr[] = {field[2], field[3], '\0'}; - char sArr[] = {field[4], field[5], '\0'}; - h = strtol(hArr, NULL, 10); - i = strtol(iArr, NULL, 10); - s = strtol(sArr, NULL, 10); - field += 6; - - // Extra: fractional time. Saved as microseconds. - if(*field++ == '.') { - uint32_t value = 0; - uint32_t scale = 1000000LU; - while(isdigit((unsigned char)*field) && scale > 1) { - value = (value * 10) + (*field++ - '0'); - scale /= 10; - } - u = value * scale; - } else { - u = 0; - } - } - - time_->hours = h; - time_->minutes = i; - time_->seconds = s; - time_->microseconds = u; - } break; - - case '_': { // Ignore the field. - } break; - - default: { // Unknown. - goto parse_error; - } - } - - next_field(); - } - - result = true; - -parse_error: - va_end(ap); - return result; -} - -bool minmea_talker_id(char talker[3], const char* sentence) { - char type[6]; - if(!minmea_scan(sentence, "t", type)) return false; - - talker[0] = type[0]; - talker[1] = type[1]; - talker[2] = '\0'; - - return true; -} - -enum minmea_sentence_id minmea_sentence_id(const char* sentence, bool strict) { - if(!minmea_check(sentence, strict)) return MINMEA_INVALID; - - char type[6]; - if(!minmea_scan(sentence, "t", type)) return MINMEA_INVALID; - - if(!strcmp(type + 2, "GBS")) return MINMEA_SENTENCE_GBS; - if(!strcmp(type + 2, "GGA")) return MINMEA_SENTENCE_GGA; - if(!strcmp(type + 2, "GLL")) return MINMEA_SENTENCE_GLL; - if(!strcmp(type + 2, "GSA")) return MINMEA_SENTENCE_GSA; - if(!strcmp(type + 2, "GST")) return MINMEA_SENTENCE_GST; - if(!strcmp(type + 2, "GSV")) return MINMEA_SENTENCE_GSV; - if(!strcmp(type + 2, "RMC")) return MINMEA_SENTENCE_RMC; - if(!strcmp(type + 2, "VTG")) return MINMEA_SENTENCE_VTG; - if(!strcmp(type + 2, "ZDA")) return MINMEA_SENTENCE_ZDA; - - return MINMEA_UNKNOWN; -} - -bool minmea_parse_gbs(struct minmea_sentence_gbs* frame, const char* sentence) { - // $GNGBS,170556.00,3.0,2.9,8.3,,,,*5C - char type[6]; - if(!minmea_scan( - sentence, - "tTfffifff", - type, - &frame->time, - &frame->err_latitude, - &frame->err_longitude, - &frame->err_altitude, - &frame->svid, - &frame->prob, - &frame->bias, - &frame->stddev)) - return false; - if(strcmp(type + 2, "GBS")) return false; - - return true; -} - -bool minmea_parse_rmc(struct minmea_sentence_rmc* frame, const char* sentence) { - // $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62 - char type[6]; - char validity; - int latitude_direction; - int longitude_direction; - int variation_direction; - if(!minmea_scan( - sentence, - "tTcfdfdffDfd", - type, - &frame->time, - &validity, - &frame->latitude, - &latitude_direction, - &frame->longitude, - &longitude_direction, - &frame->speed, - &frame->course, - &frame->date, - &frame->variation, - &variation_direction)) - return false; - if(strcmp(type + 2, "RMC")) return false; - - frame->valid = (validity == 'A'); - frame->latitude.value *= latitude_direction; - frame->longitude.value *= longitude_direction; - frame->variation.value *= variation_direction; - - return true; -} - -bool minmea_parse_gga(struct minmea_sentence_gga* frame, const char* sentence) { - // $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47 - char type[6]; - int latitude_direction; - int longitude_direction; - - if(!minmea_scan( - sentence, - "tTfdfdiiffcfcf_", - type, - &frame->time, - &frame->latitude, - &latitude_direction, - &frame->longitude, - &longitude_direction, - &frame->fix_quality, - &frame->satellites_tracked, - &frame->hdop, - &frame->altitude, - &frame->altitude_units, - &frame->height, - &frame->height_units, - &frame->dgps_age)) - return false; - if(strcmp(type + 2, "GGA")) return false; - - frame->latitude.value *= latitude_direction; - frame->longitude.value *= longitude_direction; - - return true; -} - -bool minmea_parse_gsa(struct minmea_sentence_gsa* frame, const char* sentence) { - // $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39 - char type[6]; - - if(!minmea_scan( - sentence, - "tciiiiiiiiiiiiifff", - type, - &frame->mode, - &frame->fix_type, - &frame->sats[0], - &frame->sats[1], - &frame->sats[2], - &frame->sats[3], - &frame->sats[4], - &frame->sats[5], - &frame->sats[6], - &frame->sats[7], - &frame->sats[8], - &frame->sats[9], - &frame->sats[10], - &frame->sats[11], - &frame->pdop, - &frame->hdop, - &frame->vdop)) - return false; - if(strcmp(type + 2, "GSA")) return false; - - return true; -} - -bool minmea_parse_gll(struct minmea_sentence_gll* frame, const char* sentence) { - // $GPGLL,3723.2475,N,12158.3416,W,161229.487,A,A*41$; - char type[6]; - int latitude_direction; - int longitude_direction; - - if(!minmea_scan( - sentence, - "tfdfdTc;c", - type, - &frame->latitude, - &latitude_direction, - &frame->longitude, - &longitude_direction, - &frame->time, - &frame->status, - &frame->mode)) - return false; - if(strcmp(type + 2, "GLL")) return false; - - frame->latitude.value *= latitude_direction; - frame->longitude.value *= longitude_direction; - - return true; -} - -bool minmea_parse_gst(struct minmea_sentence_gst* frame, const char* sentence) { - // $GPGST,024603.00,3.2,6.6,4.7,47.3,5.8,5.6,22.0*58 - char type[6]; - - if(!minmea_scan( - sentence, - "tTfffffff", - type, - &frame->time, - &frame->rms_deviation, - &frame->semi_major_deviation, - &frame->semi_minor_deviation, - &frame->semi_major_orientation, - &frame->latitude_error_deviation, - &frame->longitude_error_deviation, - &frame->altitude_error_deviation)) - return false; - if(strcmp(type + 2, "GST")) return false; - - return true; -} - -bool minmea_parse_gsv(struct minmea_sentence_gsv* frame, const char* sentence) { - // $GPGSV,3,1,11,03,03,111,00,04,15,270,00,06,01,010,00,13,06,292,00*74 - // $GPGSV,3,3,11,22,42,067,42,24,14,311,43,27,05,244,00,,,,*4D - // $GPGSV,4,2,11,08,51,203,30,09,45,215,28*75 - // $GPGSV,4,4,13,39,31,170,27*40 - // $GPGSV,4,4,13*7B - char type[6]; - - if(!minmea_scan( - sentence, - "tiii;iiiiiiiiiiiiiiii", - type, - &frame->total_msgs, - &frame->msg_nr, - &frame->total_sats, - &frame->sats[0].nr, - &frame->sats[0].elevation, - &frame->sats[0].azimuth, - &frame->sats[0].snr, - &frame->sats[1].nr, - &frame->sats[1].elevation, - &frame->sats[1].azimuth, - &frame->sats[1].snr, - &frame->sats[2].nr, - &frame->sats[2].elevation, - &frame->sats[2].azimuth, - &frame->sats[2].snr, - &frame->sats[3].nr, - &frame->sats[3].elevation, - &frame->sats[3].azimuth, - &frame->sats[3].snr)) { - return false; - } - if(strcmp(type + 2, "GSV")) return false; - - return true; -} - -bool minmea_parse_vtg(struct minmea_sentence_vtg* frame, const char* sentence) { - // $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K*48 - // $GPVTG,156.1,T,140.9,M,0.0,N,0.0,K*41 - // $GPVTG,096.5,T,083.5,M,0.0,N,0.0,K,D*22 - // $GPVTG,188.36,T,,M,0.820,N,1.519,K,A*3F - char type[6]; - char c_true, c_magnetic, c_knots, c_kph, c_faa_mode; - - if(!minmea_scan( - sentence, - "t;fcfcfcfcc", - type, - &frame->true_track_degrees, - &c_true, - &frame->magnetic_track_degrees, - &c_magnetic, - &frame->speed_knots, - &c_knots, - &frame->speed_kph, - &c_kph, - &c_faa_mode)) - return false; - if(strcmp(type + 2, "VTG")) return false; - // values are only valid with the accompanying characters - if(c_true != 'T') frame->true_track_degrees.scale = 0; - if(c_magnetic != 'M') frame->magnetic_track_degrees.scale = 0; - if(c_knots != 'N') frame->speed_knots.scale = 0; - if(c_kph != 'K') frame->speed_kph.scale = 0; - frame->faa_mode = (enum minmea_faa_mode)c_faa_mode; - - return true; -} - -bool minmea_parse_zda(struct minmea_sentence_zda* frame, const char* sentence) { - // $GPZDA,201530.00,04,07,2002,00,00*60 - char type[6]; - - if(!minmea_scan( - sentence, - "tTiiiii", - type, - &frame->time, - &frame->date.day, - &frame->date.month, - &frame->date.year, - &frame->hour_offset, - &frame->minute_offset)) - return false; - if(strcmp(type + 2, "ZDA")) return false; - - // check offsets - if(abs(frame->hour_offset) > 13 || frame->minute_offset > 59 || frame->minute_offset < 0) - return false; - - return true; -} - -int minmea_getdatetime( - struct tm* tm, - const struct minmea_date* date, - const struct minmea_time* time_) { - if(date->year == -1 || time_->hours == -1) return -1; - - memset(tm, 0, sizeof(*tm)); - if(date->year < 80) { - tm->tm_year = 2000 + date->year - 1900; // 2000-2079 - } else if(date->year >= 1900) { - tm->tm_year = date->year - 1900; // 4 digit year, use directly - } else { - tm->tm_year = date->year; // 1980-1999 - } - tm->tm_mon = date->month - 1; - tm->tm_mday = date->day; - tm->tm_hour = time_->hours; - tm->tm_min = time_->minutes; - tm->tm_sec = time_->seconds; - - return 0; -} - -int minmea_gettime( - struct timespec* ts, - const struct minmea_date* date, - const struct minmea_time* time_) { - struct tm tm; - if(minmea_getdatetime(&tm, date, time_)) return -1; - - time_t timestamp = mktime(&tm); /* See README.md if your system lacks timegm(). */ - if(timestamp != (time_t)-1) { - ts->tv_sec = timestamp; - ts->tv_nsec = time_->microseconds * 1000; - return 0; - } else { - return -1; - } -} - -/* vim: set ts=4 sw=4 et: */ diff --git a/applications/external/gps_nmea_uart/minmea.h b/applications/external/gps_nmea_uart/minmea.h deleted file mode 100644 index 88eec4ae9..000000000 --- a/applications/external/gps_nmea_uart/minmea.h +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright © 2014 Kosma Moczek - * This program is free software. It comes without any warranty, to the extent - * permitted by applicable law. You can redistribute it and/or modify it under - * the terms of the Do What The Fuck You Want To Public License, Version 2, as - * published by Sam Hocevar. See the COPYING file for more details. - */ - -#ifndef MINMEA_H -#define MINMEA_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include -#include -#ifdef MINMEA_INCLUDE_COMPAT -#include -#endif - -#ifndef MINMEA_MAX_SENTENCE_LENGTH -#define MINMEA_MAX_SENTENCE_LENGTH 80 -#endif - -enum minmea_sentence_id { - MINMEA_INVALID = -1, - MINMEA_UNKNOWN = 0, - MINMEA_SENTENCE_GBS, - MINMEA_SENTENCE_GGA, - MINMEA_SENTENCE_GLL, - MINMEA_SENTENCE_GSA, - MINMEA_SENTENCE_GST, - MINMEA_SENTENCE_GSV, - MINMEA_SENTENCE_RMC, - MINMEA_SENTENCE_VTG, - MINMEA_SENTENCE_ZDA, -}; - -struct minmea_float { - int_least32_t value; - int_least32_t scale; -}; - -struct minmea_date { - int day; - int month; - int year; -}; - -struct minmea_time { - int hours; - int minutes; - int seconds; - int microseconds; -}; - -struct minmea_sentence_gbs { - struct minmea_time time; - struct minmea_float err_latitude; - struct minmea_float err_longitude; - struct minmea_float err_altitude; - int svid; - struct minmea_float prob; - struct minmea_float bias; - struct minmea_float stddev; -}; - -struct minmea_sentence_rmc { - struct minmea_time time; - bool valid; - struct minmea_float latitude; - struct minmea_float longitude; - struct minmea_float speed; - struct minmea_float course; - struct minmea_date date; - struct minmea_float variation; -}; - -struct minmea_sentence_gga { - struct minmea_time time; - struct minmea_float latitude; - struct minmea_float longitude; - int fix_quality; - int satellites_tracked; - struct minmea_float hdop; - struct minmea_float altitude; - char altitude_units; - struct minmea_float height; - char height_units; - struct minmea_float dgps_age; -}; - -enum minmea_gll_status { - MINMEA_GLL_STATUS_DATA_VALID = 'A', - MINMEA_GLL_STATUS_DATA_NOT_VALID = 'V', -}; - -// FAA mode added to some fields in NMEA 2.3. -enum minmea_faa_mode { - MINMEA_FAA_MODE_AUTONOMOUS = 'A', - MINMEA_FAA_MODE_DIFFERENTIAL = 'D', - MINMEA_FAA_MODE_ESTIMATED = 'E', - MINMEA_FAA_MODE_MANUAL = 'M', - MINMEA_FAA_MODE_SIMULATED = 'S', - MINMEA_FAA_MODE_NOT_VALID = 'N', - MINMEA_FAA_MODE_PRECISE = 'P', -}; - -struct minmea_sentence_gll { - struct minmea_float latitude; - struct minmea_float longitude; - struct minmea_time time; - char status; - char mode; -}; - -struct minmea_sentence_gst { - struct minmea_time time; - struct minmea_float rms_deviation; - struct minmea_float semi_major_deviation; - struct minmea_float semi_minor_deviation; - struct minmea_float semi_major_orientation; - struct minmea_float latitude_error_deviation; - struct minmea_float longitude_error_deviation; - struct minmea_float altitude_error_deviation; -}; - -enum minmea_gsa_mode { - MINMEA_GPGSA_MODE_AUTO = 'A', - MINMEA_GPGSA_MODE_FORCED = 'M', -}; - -enum minmea_gsa_fix_type { - MINMEA_GPGSA_FIX_NONE = 1, - MINMEA_GPGSA_FIX_2D = 2, - MINMEA_GPGSA_FIX_3D = 3, -}; - -struct minmea_sentence_gsa { - char mode; - int fix_type; - int sats[12]; - struct minmea_float pdop; - struct minmea_float hdop; - struct minmea_float vdop; -}; - -struct minmea_sat_info { - int nr; - int elevation; - int azimuth; - int snr; -}; - -struct minmea_sentence_gsv { - int total_msgs; - int msg_nr; - int total_sats; - struct minmea_sat_info sats[4]; -}; - -struct minmea_sentence_vtg { - struct minmea_float true_track_degrees; - struct minmea_float magnetic_track_degrees; - struct minmea_float speed_knots; - struct minmea_float speed_kph; - enum minmea_faa_mode faa_mode; -}; - -struct minmea_sentence_zda { - struct minmea_time time; - struct minmea_date date; - int hour_offset; - int minute_offset; -}; - -/** - * Calculate raw sentence checksum. Does not check sentence integrity. - */ -uint8_t minmea_checksum(const char* sentence); - -/** - * Check sentence validity and checksum. Returns true for valid sentences. - */ -bool minmea_check(const char* sentence, bool strict); - -/** - * Determine talker identifier. - */ -bool minmea_talker_id(char talker[3], const char* sentence); - -/** - * Determine sentence identifier. - */ -enum minmea_sentence_id minmea_sentence_id(const char* sentence, bool strict); - -/** - * Scanf-like processor for NMEA sentences. Supports the following formats: - * c - single character (char *) - * d - direction, returned as 1/-1, default 0 (int *) - * f - fractional, returned as value + scale (struct minmea_float *) - * i - decimal, default zero (int *) - * s - string (char *) - * t - talker identifier and type (char *) - * D - date (struct minmea_date *) - * T - time stamp (struct minmea_time *) - * _ - ignore this field - * ; - following fields are optional - * Returns true on success. See library source code for details. - */ -bool minmea_scan(const char* sentence, const char* format, ...); - -/* - * Parse a specific type of sentence. Return true on success. - */ -bool minmea_parse_gbs(struct minmea_sentence_gbs* frame, const char* sentence); -bool minmea_parse_rmc(struct minmea_sentence_rmc* frame, const char* sentence); -bool minmea_parse_gga(struct minmea_sentence_gga* frame, const char* sentence); -bool minmea_parse_gsa(struct minmea_sentence_gsa* frame, const char* sentence); -bool minmea_parse_gll(struct minmea_sentence_gll* frame, const char* sentence); -bool minmea_parse_gst(struct minmea_sentence_gst* frame, const char* sentence); -bool minmea_parse_gsv(struct minmea_sentence_gsv* frame, const char* sentence); -bool minmea_parse_vtg(struct minmea_sentence_vtg* frame, const char* sentence); -bool minmea_parse_zda(struct minmea_sentence_zda* frame, const char* sentence); - -/** - * Convert GPS UTC date/time representation to a UNIX calendar time. - */ -int minmea_getdatetime( - struct tm* tm, - const struct minmea_date* date, - const struct minmea_time* time_); - -/** - * Convert GPS UTC date/time representation to a UNIX timestamp. - */ -int minmea_gettime( - struct timespec* ts, - const struct minmea_date* date, - const struct minmea_time* time_); - -/** - * Rescale a fixed-point value to a different scale. Rounds towards zero. - */ -static inline int_least32_t minmea_rescale(const struct minmea_float* f, int_least32_t new_scale) { - if(f->scale == 0) return 0; - if(f->scale == new_scale) return f->value; - if(f->scale > new_scale) - return (f->value + ((f->value > 0) - (f->value < 0)) * f->scale / new_scale / 2) / - (f->scale / new_scale); - else - return f->value * (new_scale / f->scale); -} - -/** - * Convert a fixed-point value to a floating-point value. - * Returns NaN for "unknown" values. - */ -static inline float minmea_tofloat(const struct minmea_float* f) { - if(f->scale == 0) return NAN; - return (float)f->value / (float)f->scale; -} - -/** - * Convert a raw coordinate to a floating point DD.DDD... value. - * Returns NaN for "unknown" values. - */ -static inline float minmea_tocoord(const struct minmea_float* f) { - if(f->scale == 0) return NAN; - if(f->scale > (INT_LEAST32_MAX / 100)) return NAN; - if(f->scale < (INT_LEAST32_MIN / 100)) return NAN; - int_least32_t degrees = f->value / (f->scale * 100); - int_least32_t minutes = f->value % (f->scale * 100); - return (float)degrees + (float)minutes / (60 * f->scale); -} - -/** - * Check whether a character belongs to the set of characters allowed in a - * sentence data field. - */ -static inline bool minmea_isfield(char c) { - return isprint((unsigned char)c) && c != ',' && c != '*'; -} - -#ifdef __cplusplus -} -#endif - -#endif /* MINMEA_H */ - -/* vim: set ts=4 sw=4 et: */ diff --git a/applications/external/metronome/application.fam b/applications/external/metronome/application.fam deleted file mode 100644 index b5a87a236..000000000 --- a/applications/external/metronome/application.fam +++ /dev/null @@ -1,16 +0,0 @@ -App( - appid="metronome", - name="Metronome", - apptype=FlipperAppType.EXTERNAL, - entry_point="metronome_app", - requires=[ - "gui", - ], - fap_icon="metronome_icon.png", - fap_category="Media", - fap_icon_assets="images", - stack_size=2 * 1024, - fap_author="@panki27 & @xMasterX", - fap_version="1.0", - fap_description="Metronome app", -) diff --git a/applications/external/metronome/gui_extensions.c b/applications/external/metronome/gui_extensions.c deleted file mode 100644 index 4c7ad2252..000000000 --- a/applications/external/metronome/gui_extensions.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include "metronome_icons.h" -#include - -//lib can only do bottom left/right -void elements_button_top_left(Canvas* canvas, const char* str) { - const uint8_t button_height = 12; - const uint8_t vertical_offset = 3; - const uint8_t horizontal_offset = 3; - const uint8_t string_width = canvas_string_width(canvas, str); - const Icon* icon = &I_ButtonUp_7x4; - const uint8_t icon_h_offset = 3; - const uint8_t icon_width_with_offset = icon->width + icon_h_offset; - const uint8_t icon_v_offset = icon->height + vertical_offset; - const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset; - - const uint8_t x = 0; - const uint8_t y = 0 + button_height; - - canvas_draw_box(canvas, x, y - button_height, button_width, button_height); - canvas_draw_line(canvas, x + button_width + 0, y - button_height, x + button_width + 0, y - 1); - canvas_draw_line(canvas, x + button_width + 1, y - button_height, x + button_width + 1, y - 2); - canvas_draw_line(canvas, x + button_width + 2, y - button_height, x + button_width + 2, y - 3); - - canvas_invert_color(canvas); - canvas_draw_icon(canvas, x + horizontal_offset, y - icon_v_offset, &I_ButtonUp_7x4); - canvas_draw_str( - canvas, x + horizontal_offset + icon_width_with_offset, y - vertical_offset, str); - canvas_invert_color(canvas); -} - -void elements_button_top_right(Canvas* canvas, const char* str) { - const uint8_t button_height = 12; - const uint8_t vertical_offset = 3; - const uint8_t horizontal_offset = 3; - const uint8_t string_width = canvas_string_width(canvas, str); - const Icon* icon = &I_ButtonUp_7x4; - const uint8_t icon_h_offset = 3; - const uint8_t icon_width_with_offset = icon->width + icon_h_offset; - const uint8_t icon_v_offset = icon->height + vertical_offset; - const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset; - - const uint8_t x = canvas_width(canvas); - const uint8_t y = 0 + button_height; - - canvas_draw_box(canvas, x - button_width, y - button_height, button_width, button_height); - canvas_draw_line(canvas, x - button_width - 1, y - button_height, x - button_width - 1, y - 1); - canvas_draw_line(canvas, x - button_width - 2, y - button_height, x - button_width - 2, y - 2); - canvas_draw_line(canvas, x - button_width - 3, y - button_height, x - button_width - 3, y - 3); - - canvas_invert_color(canvas); - canvas_draw_str(canvas, x - button_width + horizontal_offset, y - vertical_offset, str); - canvas_draw_icon( - canvas, x - horizontal_offset - icon->width, y - icon_v_offset, &I_ButtonUp_7x4); - canvas_invert_color(canvas); -} diff --git a/applications/external/metronome/gui_extensions.h b/applications/external/metronome/gui_extensions.h deleted file mode 100644 index 97df1952c..000000000 --- a/applications/external/metronome/gui_extensions.h +++ /dev/null @@ -1,3 +0,0 @@ -void elements_button_top_right(Canvas* canvas, const char* str); - -void elements_button_top_left(Canvas* canvas, const char* str); diff --git a/applications/external/metronome/metronome.c b/applications/external/metronome/metronome.c deleted file mode 100644 index a01f4418d..000000000 --- a/applications/external/metronome/metronome.c +++ /dev/null @@ -1,398 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include "gui_extensions.h" - -#define BPM_STEP_SIZE_FINE 0.5d -#define BPM_STEP_SIZE_COARSE 10.0d -#define BPM_BOUNDARY_LOW 10.0d -#define BPM_BOUNDARY_HIGH 300.0d -#define BEEP_DELAY_MS 50 - -#define wave_bitmap_left_width 4 -#define wave_bitmap_left_height 14 -static uint8_t wave_bitmap_left_bits[] = - {0x08, 0x0C, 0x06, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x06, 0x06, 0x0C, 0x08}; - -#define wave_bitmap_right_width 4 -#define wave_bitmap_right_height 14 -static uint8_t wave_bitmap_right_bits[] = - {0x01, 0x03, 0x06, 0x06, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x06, 0x06, 0x03, 0x01}; - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} PluginEvent; - -enum OutputMode { Loud, Vibro, Silent }; - -typedef struct { - double bpm; - bool playing; - int beats_per_bar; - int note_length; - int current_beat; - enum OutputMode output_mode; - FuriTimer* timer; - NotificationApp* notifications; - FuriMutex* mutex; -} MetronomeState; - -static void render_callback(Canvas* const canvas, void* ctx) { - furi_assert(ctx); - const MetronomeState* metronome_state = ctx; - furi_mutex_acquire(metronome_state->mutex, FuriWaitForever); - - FuriString* tempStr = furi_string_alloc(); - - canvas_draw_frame(canvas, 0, 0, 128, 64); - - canvas_set_font(canvas, FontPrimary); - - // draw bars/beat - furi_string_printf( - tempStr, "%d/%d", metronome_state->beats_per_bar, metronome_state->note_length); - canvas_draw_str_aligned( - canvas, 64, 8, AlignCenter, AlignCenter, furi_string_get_cstr(tempStr)); - furi_string_reset(tempStr); - - // draw BPM value - furi_string_printf(tempStr, "%.2f", metronome_state->bpm); - canvas_set_font(canvas, FontBigNumbers); - canvas_draw_str_aligned( - canvas, 64, 24, AlignCenter, AlignCenter, furi_string_get_cstr(tempStr)); - furi_string_reset(tempStr); - - // draw volume indicator - // always draw first waves - canvas_draw_xbm( - canvas, 20, 17, wave_bitmap_left_width, wave_bitmap_left_height, wave_bitmap_left_bits); - canvas_draw_xbm( - canvas, - canvas_width(canvas) - 20 - wave_bitmap_right_width, - 17, - wave_bitmap_right_width, - wave_bitmap_right_height, - wave_bitmap_right_bits); - if(metronome_state->output_mode < Silent) { - canvas_draw_xbm( - canvas, 16, 17, wave_bitmap_left_width, wave_bitmap_left_height, wave_bitmap_left_bits); - canvas_draw_xbm( - canvas, - canvas_width(canvas) - 16 - wave_bitmap_right_width, - 17, - wave_bitmap_right_width, - wave_bitmap_right_height, - wave_bitmap_right_bits); - } - if(metronome_state->output_mode < Vibro) { - canvas_draw_xbm( - canvas, 12, 17, wave_bitmap_left_width, wave_bitmap_left_height, wave_bitmap_left_bits); - canvas_draw_xbm( - canvas, - canvas_width(canvas) - 12 - wave_bitmap_right_width, - 17, - wave_bitmap_right_width, - wave_bitmap_right_height, - wave_bitmap_right_bits); - } - // draw button prompts - canvas_set_font(canvas, FontSecondary); - elements_button_left(canvas, "Slow"); - elements_button_right(canvas, "Fast"); - if(metronome_state->playing) { - elements_button_center(canvas, "Stop "); - } else { - elements_button_center(canvas, "Start"); - } - elements_button_top_left(canvas, "Push"); - elements_button_top_right(canvas, "Hold"); - - // draw progress bar - elements_progress_bar( - canvas, 8, 36, 112, (float)metronome_state->current_beat / metronome_state->beats_per_bar); - - // cleanup - furi_string_free(tempStr); - furi_mutex_release(metronome_state->mutex); -} - -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - PluginEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void timer_callback(void* ctx) { - // this is where we go BEEP! - furi_assert(ctx); - MetronomeState* metronome_state = ctx; - furi_mutex_acquire(metronome_state->mutex, FuriWaitForever); - - metronome_state->current_beat++; - if(metronome_state->current_beat > metronome_state->beats_per_bar) { - metronome_state->current_beat = 1; - } - if(metronome_state->current_beat == 1) { - // pronounced beat - notification_message(metronome_state->notifications, &sequence_set_only_red_255); - switch(metronome_state->output_mode) { - case Loud: - if(furi_hal_speaker_acquire(1000)) { - furi_hal_speaker_start(440.0f, 1.0f); - } - break; - case Vibro: - notification_message(metronome_state->notifications, &sequence_set_vibro_on); - break; - case Silent: - break; - } - } else { - // unpronounced beat - notification_message(metronome_state->notifications, &sequence_set_only_green_255); - switch(metronome_state->output_mode) { - case Loud: - if(furi_hal_speaker_acquire(1000)) { - furi_hal_speaker_start(220.0f, 1.0f); - } - break; - case Vibro: - notification_message(metronome_state->notifications, &sequence_set_vibro_on); - break; - case Silent: - break; - } - }; - - // this is a bit of a kludge... if we are on vibro and unpronounced, stop vibro after half the usual duration - switch(metronome_state->output_mode) { - case Loud: - furi_delay_ms(BEEP_DELAY_MS); - if(furi_hal_speaker_is_mine()) { - furi_hal_speaker_stop(); - furi_hal_speaker_release(); - } - break; - case Vibro: - if(metronome_state->current_beat == 1) { - furi_delay_ms(BEEP_DELAY_MS); - notification_message(metronome_state->notifications, &sequence_reset_vibro); - } else { - furi_delay_ms((int)BEEP_DELAY_MS / 2); - notification_message(metronome_state->notifications, &sequence_reset_vibro); - furi_delay_ms((int)BEEP_DELAY_MS / 2); - } - break; - case Silent: - break; - } - notification_message(metronome_state->notifications, &sequence_reset_rgb); - - furi_mutex_release(metronome_state->mutex); -} - -static uint32_t state_to_sleep_ticks(MetronomeState* metronome_state) { - // calculate time between beeps - uint32_t tps = furi_kernel_get_tick_frequency(); - double multiplier = 4.0d / metronome_state->note_length; - double bps = (double)metronome_state->bpm / 60; - return (uint32_t)(round(tps / bps) - ((BEEP_DELAY_MS / 1000) * tps)) * multiplier; -} - -static void update_timer(MetronomeState* metronome_state) { - if(furi_timer_is_running(metronome_state->timer)) { - furi_timer_stop(metronome_state->timer); - furi_timer_start(metronome_state->timer, state_to_sleep_ticks(metronome_state)); - } -} - -static void increase_bpm(MetronomeState* metronome_state, double amount) { - metronome_state->bpm += amount; - if(metronome_state->bpm > (double)BPM_BOUNDARY_HIGH) { - metronome_state->bpm = BPM_BOUNDARY_HIGH; - } - update_timer(metronome_state); -} - -static void decrease_bpm(MetronomeState* metronome_state, double amount) { - metronome_state->bpm -= amount; - if(metronome_state->bpm < (double)BPM_BOUNDARY_LOW) { - metronome_state->bpm = BPM_BOUNDARY_LOW; - } - update_timer(metronome_state); -} - -static void cycle_beats_per_bar(MetronomeState* metronome_state) { - metronome_state->beats_per_bar++; - if(metronome_state->beats_per_bar > metronome_state->note_length) { - metronome_state->beats_per_bar = 1; - } -} - -static void cycle_note_length(MetronomeState* metronome_state) { - metronome_state->note_length *= 2; - if(metronome_state->note_length > 16) { - metronome_state->note_length = 2; - metronome_state->beats_per_bar = 1; - } - update_timer(metronome_state); -} - -static void cycle_output_mode(MetronomeState* metronome_state) { - metronome_state->output_mode++; - if(metronome_state->output_mode > Silent) { - metronome_state->output_mode = Loud; - } -} - -static void metronome_state_init(MetronomeState* const metronome_state) { - metronome_state->bpm = 120.0; - metronome_state->playing = false; - metronome_state->beats_per_bar = 4; - metronome_state->note_length = 4; - metronome_state->current_beat = 0; - metronome_state->output_mode = Loud; - metronome_state->notifications = furi_record_open(RECORD_NOTIFICATION); -} - -int32_t metronome_app() { - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); - - MetronomeState* metronome_state = malloc(sizeof(MetronomeState)); - metronome_state_init(metronome_state); - - metronome_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!metronome_state->mutex) { - FURI_LOG_E("Metronome", "cannot create mutex\r\n"); - free(metronome_state); - return 255; - } - - // Set system callbacks - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, render_callback, metronome_state); - view_port_input_callback_set(view_port, input_callback, event_queue); - metronome_state->timer = - furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, metronome_state); - - // 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); - - furi_mutex_acquire(metronome_state->mutex, FuriWaitForever); - - if(event_status == FuriStatusOk) { - if(event.type == EventTypeKey) { - if(event.input.type == InputTypeShort) { - // push events - switch(event.input.key) { - case InputKeyUp: - cycle_beats_per_bar(metronome_state); - break; - case InputKeyDown: - cycle_output_mode(metronome_state); - break; - case InputKeyRight: - increase_bpm(metronome_state, BPM_STEP_SIZE_FINE); - break; - case InputKeyLeft: - decrease_bpm(metronome_state, BPM_STEP_SIZE_FINE); - break; - case InputKeyOk: - metronome_state->playing = !metronome_state->playing; - if(metronome_state->playing) { - furi_timer_start( - metronome_state->timer, state_to_sleep_ticks(metronome_state)); - } else { - furi_timer_stop(metronome_state->timer); - } - break; - case InputKeyBack: - processing = false; - break; - default: - break; - } - } else if(event.input.type == InputTypeLong) { - // hold events - switch(event.input.key) { - case InputKeyUp: - cycle_note_length(metronome_state); - break; - case InputKeyDown: - break; - case InputKeyRight: - increase_bpm(metronome_state, BPM_STEP_SIZE_COARSE); - break; - case InputKeyLeft: - decrease_bpm(metronome_state, BPM_STEP_SIZE_COARSE); - break; - case InputKeyOk: - break; - case InputKeyBack: - processing = false; - break; - default: - break; - } - } else if(event.input.type == InputTypeRepeat) { - // repeat events - switch(event.input.key) { - case InputKeyUp: - break; - case InputKeyDown: - break; - case InputKeyRight: - increase_bpm(metronome_state, BPM_STEP_SIZE_COARSE); - break; - case InputKeyLeft: - decrease_bpm(metronome_state, BPM_STEP_SIZE_COARSE); - break; - case InputKeyOk: - break; - case InputKeyBack: - processing = false; - break; - default: - break; - } - } - } - } - - view_port_update(view_port); - furi_mutex_release(metronome_state->mutex); - } - - 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(metronome_state->mutex); - furi_timer_free(metronome_state->timer); - furi_record_close(RECORD_NOTIFICATION); - free(metronome_state); - - return 0; -} diff --git a/applications/external/metronome/metronome_icon.png b/applications/external/metronome/metronome_icon.png deleted file mode 100644 index 64d0ddbe9466604facc5a3642c7be6d0dc172fac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V6Od#Ihk44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`0h7I;J!GcfQS24TkI`72U@g7%&+jv*SswcU$y;(nnzwBQ1s_>nGsd&Au*G7W~FZa)`x2%NTv2S41RNmv#pRAz{G>XB~ L)z4*}Q$iB}fw#Uw9H#@>a%R0?&h0`cmi6HfmS$n)YitRD> zEW62p1DC2TfKijo`!Mo&;j^Az0ui%X)0S^IiuYA>G-d(d8<=%Yl`yywYUGG z`(ZzwG|p#=a^%N+OkJNl@}8pXKgwI1a??FaJQ3;C7j32wq6E;2a%yRiP;Z+_)MgzX z+v;yW?5T+Rwt8;C#con(UEbJD*~ac_%iG=ds=m5(8l4&tAc&ZxXb^>QMh3PzzQ>8_!=NEs^YSo1KpP^GGyIj$u}-RRddwWodxWvYlAcffi>cCkzhDyp$)B zix}mMv@LqlRzcH|2~kqe#@X0S;4ouA6T{STZqg9wdj&4(rQuMx?-?v)5sPI8ShK)_ zmt41izmPVH3UnryFM>v6+g^yyT003d)>$TcsmGQtg2a;(#geX&BI}Bm*il>;)+D5! zGAc#d5+a-gYHh-TEK|48>^UC$qMv=3OBp|44wcMSA!??EO>N$6;R;!>h-uE5m|#4D zx{wDxmGr-Xh0lYX*Ft@d1R{+nc!@`}!;B>E45hg)X~vnPvB#Q@t%9mL=RN@yOBF9z z)T-F0T2LwZTD!8is0HO;x(G$; z3Lm^|s_5_YX1%_aihzf3;RuOVD376fKFD)?m}{iLGYII;xN0`oh4CunXqaAvdU*xd zs+WhJ`Re$Xzp?j5wEZpv(pRL!2$qRJ_G!v$9q{yPQ_cY8jl5Pzb{PLQad`KSx}LzH zS>(&2OTnh-b1a7DmO>YM_}O}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 diff --git a/applications/external/passgen/icons/passgen_icon.png b/applications/external/passgen/icons/passgen_icon.png deleted file mode 100644 index 1ed4f77fc1a13b05214e2840b8e34f95ef1de27c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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( diff --git a/applications/external/passgen/images/preview.png b/applications/external/passgen/images/preview.png deleted file mode 100644 index 3224b0a8d4209a9fe33daa8596965944ed0bd25a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/applications/external/passgen/passgen.c b/applications/external/passgen/passgen.c deleted file mode 100644 index a09abead0..000000000 --- a/applications/external/passgen/passgen.c +++ /dev/null @@ -1,264 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "passgen_icons.h" -#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 char* const PassGen_AlphabetChars[16] = { - "0", // invalid value - /* PASSGEN_SPECIAL PASSGEN_LETTERS_UP PASSGEN_LETTERS_LOW */ PASSGEN_DIGITS, - /* PASSGEN_SPECIAL PASSGEN_LETTERS_UP */ PASSGEN_LETTERS_LOW /* PASSGEN_DIGITS */, - /* PASSGEN_SPECIAL PASSGEN_LETTERS_UP */ PASSGEN_LETTERS_LOW PASSGEN_DIGITS, - /* PASSGEN_SPECIAL */ PASSGEN_LETTERS_UP /* PASSGEN_LETTERS_LOW PASSGEN_DIGITS */, - /* PASSGEN_SPECIAL */ PASSGEN_LETTERS_UP /* PASSGEN_LETTERS_LOW */ PASSGEN_DIGITS, - /* PASSGEN_SPECIAL */ PASSGEN_LETTERS_UP PASSGEN_LETTERS_LOW /* PASSGEN_DIGITS */, - /* PASSGEN_SPECIAL */ PASSGEN_LETTERS_UP PASSGEN_LETTERS_LOW PASSGEN_DIGITS, - PASSGEN_SPECIAL /* PASSGEN_LETTERS_UP PASSGEN_LETTERS_LOW PASSGEN_DIGITS */, - PASSGEN_SPECIAL /* PASSGEN_LETTERS_UP PASSGEN_LETTERS_LOW */ PASSGEN_DIGITS, - PASSGEN_SPECIAL /* PASSGEN_LETTERS_UP */ PASSGEN_LETTERS_LOW /* PASSGEN_DIGITS */, - PASSGEN_SPECIAL /* PASSGEN_LETTERS_UP */ PASSGEN_LETTERS_LOW PASSGEN_DIGITS, - PASSGEN_SPECIAL PASSGEN_LETTERS_UP /* PASSGEN_LETTERS_LOW PASSGEN_DIGITS */, - PASSGEN_SPECIAL PASSGEN_LETTERS_UP /* PASSGEN_LETTERS_LOW */ PASSGEN_DIGITS, - PASSGEN_SPECIAL PASSGEN_LETTERS_UP PASSGEN_LETTERS_LOW /* PASSGEN_DIGITS */, - PASSGEN_SPECIAL PASSGEN_LETTERS_UP PASSGEN_LETTERS_LOW PASSGEN_DIGITS, -}; - -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; - const char* alphabet; - char password[PASSGEN_MAX_LENGTH + 1]; - int length; // must be <= PASSGEN_MAX_LENGTH - int level; -} PassGen; - -void state_free(PassGen* app) { - // NOTE: would have preferred if a "safe" memset() was available... - // but, since cannot prevent optimization from removing - // memset(), fill with random data instead. - furi_hal_random_fill_buf((void*)(app->password), PASSGEN_MAX_LENGTH); - - 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]; - if(mode > 0 && mode < 16) { - app->alphabet = PassGen_AlphabetChars[mode]; - } else { - app->alphabet = - PassGen_AlphabetChars[0]; // Invalid mode ... password will be all zero digits - } -} - -PassGen* state_init() { - PassGen* app = malloc(sizeof(PassGen)); - _Static_assert(8 <= PASSGEN_MAX_LENGTH, "app->length must be set <= PASSGEN_MAX_LENGTH"); - 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) { - memset(app->password, 0, PASSGEN_MAX_LENGTH + 1); - - int char_option_count = strlen(app->alphabet); - if(char_option_count < 0) { - return; - } - - // determine largest character value that avoids bias - char ceil = CHAR_MAX - (CHAR_MAX % char_option_count) - 1; - - // iteratively fill the password buffer with random values - // then keep only values that are in-range (no bias) - void* remaining_buffer = app->password; - size_t remaining_length = (app->length * sizeof(char)); - - while(remaining_length != 0) { - // fewer calls to hardware TRNG is more efficient - furi_hal_random_fill_buf(remaining_buffer, remaining_length); - - // keep only values that are in-range (no bias) - char* target = remaining_buffer; - char* source = remaining_buffer; - size_t valid_count = 0; - - for(size_t i = 0; i < remaining_length; i++) { - int v = *source; - // if the generated random value is in range, keep it - if(v < ceil) { - v %= char_option_count; - *target = app->alphabet[v]; - // increment target pointer and count of valid items found - target++; - valid_count++; - } - // always increment the source pointer - source++; - } - remaining_length -= valid_count; - remaining_buffer = target; - } -} - -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/external/pomodoro/application.fam b/applications/external/pomodoro/application.fam deleted file mode 100644 index bd78edd5b..000000000 --- a/applications/external/pomodoro/application.fam +++ /dev/null @@ -1,15 +0,0 @@ -App( - appid="flipp_pomodoro", - name="Pomodoro Timer", - apptype=FlipperAppType.EXTERNAL, - entry_point="flipp_pomodoro_app", - requires=["gui", "notification", "dolphin"], - stack_size=1 * 1024, - fap_category="Tools", - fap_icon_assets="images", - fap_icon="flipp_pomodoro_10.png", - fap_author="@Th3Un1q3", - fap_weburl="https://github.com/Th3Un1q3/flipp_pomodoro", - fap_version="1.2", - fap_description="Boost Your Productivity with the Pomodoro Timer", -) diff --git a/applications/external/pomodoro/flipp_pomodoro_10.png b/applications/external/pomodoro/flipp_pomodoro_10.png deleted file mode 100644 index 977d16a584f63307ceb028a48f57713402abc520..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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); - view_dispatcher_send_custom_event( - app->view_dispatcher, FlippPomodoroAppCustomEventStateUpdated); - return CustomEventConsumed; - case FlippPomodoroAppCustomEventStageComplete: - if(flipp_pomodoro__get_stage(app->state) == FlippPomodoroStageFocus) { - // REGISTER a deed on work stage complete to get an acheivement - dolphin_deed(DolphinDeedPluginGameWin); - FURI_LOG_I(TAG, "Focus stage reward added"); - - flipp_pomodoro_statistics__increase_focus_stages_completed(app->statistics); - }; - - flipp_pomodoro__toggle_stage(app->state); - notification_message( - app->notification_app, - stage_start_notification_sequence_map[flipp_pomodoro__get_stage(app->state)]); - view_dispatcher_send_custom_event( - app->view_dispatcher, FlippPomodoroAppCustomEventStateUpdated); - 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(); - app->statistics = flipp_pomodoro_statistics__new(); - - 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(); - app->info_view = flipp_pomodoro_info_view_alloc(); - - view_dispatcher_add_view( - app->view_dispatcher, - FlippPomodoroAppViewTimer, - flipp_pomodoro_view_timer_get_view(app->timer_view)); - - view_dispatcher_add_view( - app->view_dispatcher, - FlippPomodoroAppViewInfo, - flipp_pomodoro_info_view_get_view(app->info_view)); - - scene_manager_next_scene(app->scene_manager, FlippPomodoroSceneTimer); - FURI_LOG_I(TAG, "Alloc complete"); - return app; -}; - -void flipp_pomodoro_app_free(FlippPomodoroApp* app) { - view_dispatcher_remove_view(app->view_dispatcher, FlippPomodoroAppViewTimer); - view_dispatcher_remove_view(app->view_dispatcher, FlippPomodoroAppViewInfo); - view_dispatcher_free(app->view_dispatcher); - scene_manager_free(app->scene_manager); - flipp_pomodoro_view_timer_free(app->timer_view); - flipp_pomodoro_info_view_free(app->info_view); - flipp_pomodoro_statistics__destroy(app->statistics); - 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); - FURI_LOG_I(TAG, "Initial"); - FlippPomodoroApp* app = flipp_pomodoro_app_alloc(); - - FURI_LOG_I(TAG, "Run deed added"); - dolphin_deed(DolphinDeedPluginGameStart); - - view_dispatcher_run(app->view_dispatcher); - - flipp_pomodoro_app_free(app); - - return 0; -}; \ No newline at end of file diff --git a/applications/external/pomodoro/flipp_pomodoro_app.h b/applications/external/pomodoro/flipp_pomodoro_app.h deleted file mode 100644 index de3812805..000000000 --- a/applications/external/pomodoro/flipp_pomodoro_app.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include "views/flipp_pomodoro_timer_view.h" -#include "views/flipp_pomodoro_info_view.h" - -#include "modules/flipp_pomodoro.h" -#include "modules/flipp_pomodoro_statistics.h" - -typedef enum { - // Reserve first 100 events for button types and indexes, starting from 0 - FlippPomodoroAppCustomEventStageSkip = 100, - FlippPomodoroAppCustomEventStageComplete, // By Expiration - FlippPomodoroAppCustomEventTimerTick, - FlippPomodoroAppCustomEventTimerAskHint, - FlippPomodoroAppCustomEventStateUpdated, - FlippPomodoroAppCustomEventResumeTimer, -} FlippPomodoroAppCustomEvent; - -typedef struct { - SceneManager* scene_manager; - ViewDispatcher* view_dispatcher; - Gui* gui; - NotificationApp* notification_app; - FlippPomodoroTimerView* timer_view; - FlippPomodoroInfoView* info_view; - FlippPomodoroState* state; - FlippPomodoroStatistics* statistics; -} FlippPomodoroApp; - -typedef enum { - FlippPomodoroAppViewTimer, - FlippPomodoroAppViewInfo, -} FlippPomodoroAppView; \ No newline at end of file diff --git a/applications/external/pomodoro/flipp_pomodoro_app_i.h b/applications/external/pomodoro/flipp_pomodoro_app_i.h deleted file mode 100644 index 8b8650776..000000000 --- a/applications/external/pomodoro/flipp_pomodoro_app_i.h +++ /dev/null @@ -1,32 +0,0 @@ -#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" -#include diff --git a/applications/external/pomodoro/helpers/debug.h b/applications/external/pomodoro/helpers/debug.h deleted file mode 100644 index 13b8f2998..000000000 --- a/applications/external/pomodoro/helpers/debug.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include - -#define TAG "FlippPomodoro" \ No newline at end of file diff --git a/applications/external/pomodoro/helpers/notifications.c b/applications/external/pomodoro/helpers/notifications.c deleted file mode 100644 index 388a3f11d..000000000 --- a/applications/external/pomodoro/helpers/notifications.c +++ /dev/null @@ -1,49 +0,0 @@ -#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/external/pomodoro/helpers/notifications.h b/applications/external/pomodoro/helpers/notifications.h deleted file mode 100644 index c6cd0428f..000000000 --- a/applications/external/pomodoro/helpers/notifications.h +++ /dev/null @@ -1,14 +0,0 @@ -#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[] = { - [FlippPomodoroStageFocus] = &work_start_notification, - [FlippPomodoroStageRest] = &rest_start_notification, - [FlippPomodoroStageLongBreak] = &rest_start_notification, -}; diff --git a/applications/external/pomodoro/helpers/time.c b/applications/external/pomodoro/helpers/time.c deleted file mode 100644 index 7fb0d13c2..000000000 --- a/applications/external/pomodoro/helpers/time.c +++ /dev/null @@ -1,20 +0,0 @@ -#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/external/pomodoro/helpers/time.h b/applications/external/pomodoro/helpers/time.h deleted file mode 100644 index 7a7d90bf2..000000000 --- a/applications/external/pomodoro/helpers/time.h +++ /dev/null @@ -1,24 +0,0 @@ -#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/external/pomodoro/images/flipp_pomodoro_focus_64/frame_00.png b/applications/external/pomodoro/images/flipp_pomodoro_focus_64/frame_00.png deleted file mode 100644 index 7ead27c4e2d36b8155c088954b50e87cfc2a7e0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1242 zcmV<01SR{4P)Px(lu1NERCr$9TjA21Fbr$o|DnGf?7|sWvg8oxx9!hvB?McRWQTU|*X#B3TJY!R z=kGS}_j`J`**&)Vw&zxVv!J$UF9E=U9-ljCWYA`Sm<8by0OO%sk~!fH6WG0Re+S61 zro#jZKo?O|MMX;O1P z3~E)$ATQ`>cON!#t#s#j>6ps#`V!VDre6XW|C9g0fOlQKs96>eo(;7XjwJy z0AU9V0nnKXG6NW;l}@wqq4ky7jyRZs#yH~|YZ6p6N7va2PXQJaXKhh+mkI>v0ae9k zl1DUV70sT2IuZkgNh`_=G4gcZkO0&86#%j+F&Uut#59kRbLEoflfwhS5bna)vFBN&lf>H~CCmMCAw$0$?QOv_4dA z#EhIrY>CKhcMq6No+X_}+{*MA^>e}%3#yZ$YVpTmXch!C&m&CPV8n)+stqDKBV&xd z!{Ve2U;_jKN*SY*B&!rN&&o7gGC&fjDBM+yk^|CZu3YtRBtrxMD$@4Z2Lo8Z%=DCW z;(ki2*(*9Sh+RZ6;M74P0~ktZf^(UG0AQfyuHgcJx=DOSWrPOe+;Z_l3(=z$Gp_QqX4RAiXk(14(NEmDL2#wkl`_7$y)9vjRr2%(hwUENNj*Z z3~$W=$|GDeM7^GYn7xBZs$#1=3*0>kGB#E6QPoCCWi}w`Krq;8kWr~y>8j$4{_Zo} z<8U>NE;$aXfSLZfe&KkNiY5BX4&aLS0Zv;(!CwWyNjCe-M;t2v$Q4$DPj~9lTc@Er;@X4modNz;I}2ex6TzF;3Pl#^wY+tVtWjLyQ@Dtw>$#C6Upc4 zF;9ZDRo^9nT#>t|&sy*pc)l)yJFCwoOq4V$!0CmEi<&}}o$fmKskIE)>U;qYU|9lc zic^6-k$mnb>g7!(KkJ*J8U5Z#eKg;*H$p0Qs|(Dq;wb>CgBbdr;nHEqo%f$ezIq0G zlVo{-t8v!mo=ASghzjBs>DXh{9MFBR3$$9ts_k|(%L7ypu_DTJ+`T&Mx~=bIqN^D2 z?ZeLWSs?ya_)7Jj)P9E@YVAn^E{cqDR{&Ij-gO=RKterCeI=&uAJ=~aU>`r1pABk8 z0+o5WAa)KuXzguXz)5ZvYz2<Px(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^DB3mPx(j7da6RCr$PT+x!_APj5&|D(H;yP-oJ%Mu3K3}Ih(HU$H=EDJ*S`FK2DkHpXG z^}pNm`TY00{EbYNcI9)_-?mey=8a$5isozAaQt1juWe`6!F;2xaYnl%dP@SJ4q|bf z7g+SHfZE#Wu{$Gxy*A$fP*Lh-OJ)*iJe5)Epdto}GTZjAnW+TXn+swU%NSm}+E0;f zH5M7a+dfMJz-E3614Jdj1}L)YF-9q!sBHZd0H_ADnxE}=LZs0YS-U6$m3q%KK%_T3 z;2;oqrD;S~x7au_zzB!e6JWrZ1%MVO{IYFbZoZlMZ}1fnXai-P!c;q}>B!zp0I1n+ z>p$A5c+W=!jWNVbfOazg6K#x9W&uD|>$V;Mnzo z7Ej5e+RmOwdZGsacK5=PX$AMH|x$DwAvm$pLu- zAm_JbdQkw_Z5!K%tLFqLv)Oa?^JOA5c_AABlO23@^QUc~ciG`sgt~8M?U4P^y8?Ei zcg(|kFQH!2u*bvE%O`KAgxc4Buyd^E7QHix+MO8O-U(a@0P5uocGl0{EFMmc0HO4+ z1H;}~c%Q4!AOKo3w^ik%_UgFoya8#Gn!UV0p=T%{_PM8#JTTaH2y_aNP_Uyh;CSdl z$f&bK{c zialU3&7f!iHHgugTeJXTkFq|b6%fl%FEvXkX^NALwF;I9pIqMM0;jcQ)Jz|?*rsK zw*ipz+cLd|-wCwLz|?(fjYmwf86bzr4S<~AmgzO@S~$vl!Iwg$*SYy%+YH`oikhGzEz22Vpa*L*3o^#st)M7`6C5XbHzYza^Ui`tdIme0NNX#r+! zZ2)wKRX5-Ppze*%3L>B=LH7jc8#J^3T|C<*AoqE+8M*pu>e`#@Xa-WR=ASiAA07WKR+Ei@cY5)KL07*qoM6N<$f-LDlVE_OC diff --git a/applications/external/pomodoro/images/flipp_pomodoro_rest_64/frame_00.png b/applications/external/pomodoro/images/flipp_pomodoro_rest_64/frame_00.png deleted file mode 100644 index 072affef3992c9fd662748f5a8cd7363afdfa2e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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&@<~KNRCr$1TG5W=FbLcE|Bs$ktIdc~z&1&GH}kS9H6>t-A#Gpp_xt_x;P3T% z{XDtl*f0J2GyqRv?SswsJl4IQ24EKh*q}Waj{|Tx&~^6a{9ieBLH#ETKtUjI(DjP$ zR(n2no-Too1|T6rL1*`$Z2SfQD$u&%44YpMK!;KGo)Ulq-RSpZAD;~n-Twg~3N{PW zul;5~jufAh;7kw$kQo~&Q@gG&)d000&kER#`fn3K76i18?e|rSivaTbE@i+6RdC=@ zGq0{kwdXTI zrZ=w~LYRSz0mUW+t%q~K03mX2CcFMLr-*CD0MrE}c8v5hqNNyS0=K8SNJ}baGX5g{ zIrq0BI8zFt!u|;&3M3l35bKr#z#yfrVc1fN6X*tvea2_`IE*%CGouFYgRzq$@~NCd zs21QXWD{K0Ce`}R)<@u0t#S(khEX&%cBV3`#c1%MGv4;Z?~XSv(one2bM z0K0f5coev8iKzdp{w~!3m1e9cM&L5{s{Y*cr6YoD2ABY{x{sa*L=zw@ys0Mb0$^61 zM@iTKBYhaxyG&?{V5QjJX{P?!u3XcL&Ny#vSf8Z*JCmSy z+S6KbAOaf!%p{2QVd)$&JN~NoX9BB~?@|D4%TluF%Yk_%Zo%?Hk_15Xa#V3XD+eTG z)yEh#eUsO45&&5nL;=|A)dR{7Kph5T{-8K+C4dC38hhEyc^e&&qRymh$XT+{2NDRi zXzJ?*&+eswB$e=vHpm9GdL0AO?JblCpku_UzY>&^DaCHJ*2gzp0@*aiILv^}*ik3d yO9^*MAaly<02ACU1~7Yn5?6gB)j|K;?)e3CDgm3;8 -#include -#include "../helpers/time.h" -#include "flipp_pomodoro.h" - -PomodoroStage stages_sequence[] = { - FlippPomodoroStageFocus, - FlippPomodoroStageRest, - - FlippPomodoroStageFocus, - FlippPomodoroStageRest, - - FlippPomodoroStageFocus, - FlippPomodoroStageRest, - - FlippPomodoroStageFocus, - FlippPomodoroStageLongBreak, -}; - -char* current_stage_label[] = { - [FlippPomodoroStageFocus] = "Focusing...", - [FlippPomodoroStageRest] = "Short Break...", - [FlippPomodoroStageLongBreak] = "Long Break...", -}; - -char* next_stage_label[] = { - [FlippPomodoroStageFocus] = "Focus", - [FlippPomodoroStageRest] = "Short Break", - [FlippPomodoroStageLongBreak] = "Long Break", -}; - -PomodoroStage flipp_pomodoro__stage_by_index(int index) { - const int one_loop_size = sizeof(stages_sequence); - return stages_sequence[index % one_loop_size]; -} - -void flipp_pomodoro__toggle_stage(FlippPomodoroState* state) { - furi_assert(state); - state->current_stage_index = state->current_stage_index + 1; - state->started_at_timestamp = time_now(); -}; - -PomodoroStage flipp_pomodoro__get_stage(FlippPomodoroState* state) { - furi_assert(state); - return flipp_pomodoro__stage_by_index(state->current_stage_index); -}; - -char* flipp_pomodoro__current_stage_label(FlippPomodoroState* state) { - furi_assert(state); - return current_stage_label[flipp_pomodoro__get_stage(state)]; -}; - -char* flipp_pomodoro__next_stage_label(FlippPomodoroState* state) { - furi_assert(state); - return next_stage_label[flipp_pomodoro__stage_by_index(state->current_stage_index + 1)]; -}; - -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[] = { - [FlippPomodoroStageFocus] = 25 * TIME_SECONDS_IN_MINUTE, - [FlippPomodoroStageRest] = 5 * TIME_SECONDS_IN_MINUTE, - [FlippPomodoroStageLongBreak] = 30 * TIME_SECONDS_IN_MINUTE, - }; - - return stage_duration_seconds_map[flipp_pomodoro__get_stage(state)]; -}; - -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->current_stage_index = 0; - return state; -}; \ No newline at end of file diff --git a/applications/external/pomodoro/modules/flipp_pomodoro.h b/applications/external/pomodoro/modules/flipp_pomodoro.h deleted file mode 100644 index a1e50cb6e..000000000 --- a/applications/external/pomodoro/modules/flipp_pomodoro.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include -#include "../helpers/time.h" - -/// @brief Options of pomodoro stages -typedef enum { - FlippPomodoroStageFocus, - FlippPomodoroStageRest, - FlippPomodoroStageLongBreak, -} PomodoroStage; - -/// @brief State of the pomodoro timer -typedef struct { - uint8_t current_stage_index; - uint32_t started_at_timestamp; -} FlippPomodoroState; - -/// @brief Generates initial state -/// @returns A new pre-populated state for pomodoro timer -FlippPomodoroState* flipp_pomodoro__new(); - -/// @brief Extract current stage of pomodoro -/// @param state - pointer to the state of pomorodo -/// @returns Current stage value -PomodoroStage flipp_pomodoro__get_stage(FlippPomodoroState* state); - -/// @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 currently active stage -/// @param state - pointer to the state of pomorodo -/// @returns A string that explains current stage -char* flipp_pomodoro__current_stage_label(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/external/pomodoro/modules/flipp_pomodoro_statistics.c b/applications/external/pomodoro/modules/flipp_pomodoro_statistics.c deleted file mode 100644 index 4bc5bf56f..000000000 --- a/applications/external/pomodoro/modules/flipp_pomodoro_statistics.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "flipp_pomodoro_statistics.h" - -FlippPomodoroStatistics* flipp_pomodoro_statistics__new() { - FlippPomodoroStatistics* statistics = malloc(sizeof(FlippPomodoroStatistics)); - - statistics->focus_stages_completed = 0; - - return statistics; -} - -// Return the number of completed focus stages -uint8_t - flipp_pomodoro_statistics__get_focus_stages_completed(FlippPomodoroStatistics* statistics) { - return statistics->focus_stages_completed; -} - -// Increase the number of completed focus stages by one -void flipp_pomodoro_statistics__increase_focus_stages_completed( - FlippPomodoroStatistics* statistics) { - statistics->focus_stages_completed++; -} - -void flipp_pomodoro_statistics__destroy(FlippPomodoroStatistics* statistics) { - furi_assert(statistics); - free(statistics); -}; diff --git a/applications/external/pomodoro/modules/flipp_pomodoro_statistics.h b/applications/external/pomodoro/modules/flipp_pomodoro_statistics.h deleted file mode 100644 index cfc843147..000000000 --- a/applications/external/pomodoro/modules/flipp_pomodoro_statistics.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once -#include - -/** @brief FlippPomodoroStatistics structure - * - * This structure is used to keep track of completed focus stages. - */ -typedef struct { - uint8_t focus_stages_completed; -} FlippPomodoroStatistics; - -/** @brief Allocate and initialize a new FlippPomodoroStatistics - * - * This function allocates a new FlippPomodoroStatistics structure, initializes its members - * and returns a pointer to it. - * - * @return A pointer to a new FlippPomodoroStatistics structure - */ -FlippPomodoroStatistics* flipp_pomodoro_statistics__new(); - -/** @brief Get the number of completed focus stages - * - * This function retrieves the number of completed focus stages in a FlippPomodoroStatistics structure. - * - * @param statistics A pointer to a FlippPomodoroStatistics structure - * @return The number of completed focus stages - */ -uint8_t flipp_pomodoro_statistics__get_focus_stages_completed(FlippPomodoroStatistics* statistics); - -/** @brief Increase the number of completed focus stages - * - * This function increases the count of the completed focus stages by one in a FlippPomodoroStatistics structure. - * - * @param statistics A pointer to a FlippPomodoroStatistics structure - */ -void flipp_pomodoro_statistics__increase_focus_stages_completed( - FlippPomodoroStatistics* statistics); - -/** @brief Free a FlippPomodoroStatistics structure - * - * This function frees the memory used by a FlippPomodoroStatistics structure. - * - * @param statistics A pointer to a FlippPomodoroStatistics structure - */ -void flipp_pomodoro_statistics__destroy(FlippPomodoroStatistics* state); \ No newline at end of file diff --git a/applications/external/pomodoro/scenes/.keep b/applications/external/pomodoro/scenes/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/applications/external/pomodoro/scenes/config/flipp_pomodoro_scene_config.h b/applications/external/pomodoro/scenes/config/flipp_pomodoro_scene_config.h deleted file mode 100644 index 5a83fb021..000000000 --- a/applications/external/pomodoro/scenes/config/flipp_pomodoro_scene_config.h +++ /dev/null @@ -1,2 +0,0 @@ -ADD_SCENE(flipp_pomodoro, info, Info) -ADD_SCENE(flipp_pomodoro, timer, Timer) \ No newline at end of file diff --git a/applications/external/pomodoro/scenes/flipp_pomodoro_scene.c b/applications/external/pomodoro/scenes/flipp_pomodoro_scene.c deleted file mode 100644 index 5856ac947..000000000 --- a/applications/external/pomodoro/scenes/flipp_pomodoro_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#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* ctx, 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* ctx) = { -#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/external/pomodoro/scenes/flipp_pomodoro_scene.h b/applications/external/pomodoro/scenes/flipp_pomodoro_scene.h deleted file mode 100644 index 708d8f8e4..000000000 --- a/applications/external/pomodoro/scenes/flipp_pomodoro_scene.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once -#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* ctx, 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* ctx); -#include "config/flipp_pomodoro_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/pomodoro/scenes/flipp_pomodoro_scene_info.c b/applications/external/pomodoro/scenes/flipp_pomodoro_scene_info.c deleted file mode 100644 index 9d73108f8..000000000 --- a/applications/external/pomodoro/scenes/flipp_pomodoro_scene_info.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include -#include "flipp_pomodoro_scene.h" -#include "../flipp_pomodoro_app.h" -#include "../views/flipp_pomodoro_info_view.h" - -enum { SceneEventConusmed = true, SceneEventNotConusmed = false }; - -void flipp_pomodoro_scene_info_on_back_to_timer(void* ctx) { - furi_assert(ctx); - FlippPomodoroApp* app = ctx; - - view_dispatcher_send_custom_event( - app->view_dispatcher, FlippPomodoroAppCustomEventResumeTimer); -}; - -void flipp_pomodoro_scene_info_on_enter(void* ctx) { - furi_assert(ctx); - FlippPomodoroApp* app = ctx; - - view_dispatcher_switch_to_view(app->view_dispatcher, FlippPomodoroAppViewInfo); - flipp_pomodoro_info_view_set_pomodoros_completed( - flipp_pomodoro_info_view_get_view(app->info_view), - flipp_pomodoro_statistics__get_focus_stages_completed(app->statistics)); - flipp_pomodoro_info_view_set_mode( - flipp_pomodoro_info_view_get_view(app->info_view), FlippPomodoroInfoViewModeStats); - flipp_pomodoro_info_view_set_resume_timer_cb( - app->info_view, flipp_pomodoro_scene_info_on_back_to_timer, app); -}; - -void flipp_pomodoro_scene_info_handle_custom_event( - FlippPomodoroApp* app, - FlippPomodoroAppCustomEvent custom_event) { - if(custom_event == FlippPomodoroAppCustomEventResumeTimer) { - scene_manager_next_scene(app->scene_manager, FlippPomodoroSceneTimer); - } -}; - -bool flipp_pomodoro_scene_info_on_event(void* ctx, SceneManagerEvent event) { - furi_assert(ctx); - FlippPomodoroApp* app = ctx; - - switch(event.type) { - case SceneManagerEventTypeBack: - view_dispatcher_stop(app->view_dispatcher); - return SceneEventConusmed; - case SceneManagerEventTypeCustom: - flipp_pomodoro_scene_info_handle_custom_event(app, event.event); - return SceneEventConusmed; - default: - break; - }; - return SceneEventNotConusmed; -}; - -void flipp_pomodoro_scene_info_on_exit(void* ctx) { - UNUSED(ctx); -}; \ No newline at end of file diff --git a/applications/external/pomodoro/scenes/flipp_pomodoro_scene_timer.c b/applications/external/pomodoro/scenes/flipp_pomodoro_scene_timer.c deleted file mode 100644 index 3f9511f70..000000000 --- a/applications/external/pomodoro/scenes/flipp_pomodoro_scene_timer.c +++ /dev/null @@ -1,154 +0,0 @@ -#include -#include -#include -#include -#include "flipp_pomodoro_scene.h" -#include "../flipp_pomodoro_app.h" -#include "../views/flipp_pomodoro_timer_view.h" - -enum { SceneEventConusmed = true, SceneEventNotConusmed = false }; - -static char* work_hints[] = { - "Can you explain the problem as if I'm five?", - "Expected output vs. reality: what's the difference?", - "Ever thought of slicing the problem into bite-sized pieces?", - "What's the story when you walk through the code?", - "Any error messages gossiping about the issue?", - "What tricks have you tried to fix this?", - "Did you test the code, or just hoping for the best?", - "How's this code mingling with the rest of the app?", - "Any sneaky side effects causing mischief?", - "What are you assuming, and is it safe to do so?", - "Did you remember to invite all the edge cases to the party?", - "What happens in the isolation chamber (running code separately)?", - "Can you make the issue appear on command?", - "What's the scene at the crime spot when the error occurs?", - "Did you seek wisdom from the grand oracle (Google)?", - "What if you take a different path to solve this?", - "Did you take a coffee break to reboot your brain?"}; - -static char* break_hints[] = { - "Time to stretch! Remember, your body isn't made of code.", - "Hydrate or diedrate! Grab a glass of water.", - "Blink! Your eyes need a break too.", - "How about a quick dance-off with your shadow?", - "Ever tried chair yoga? Now's the time!", - "Time for a quick peek out the window. The outside world still exists!", - "Quick, think about kittens! Or puppies! Or baby turtles!", - "Time for a laugh. Look up a joke or two!", - "Sing a song. Bonus points for making up your own lyrics.", - "Do a quick tidy-up. A clean space is a happy space!", - "Time to play 'air' musical instrument for a minute.", - "How about a quick doodle? Unleash your inner Picasso!", - "Practice your superhero pose. Feel the power surge!", - "Quick, tell yourself a joke. Don't worry, I won't judge.", - "Time to practice your mime skills. Stuck in a box, anyone?", - "Ever tried juggling? Now's your chance!", - "Do a quick self high-five, you're doing great!"}; - -static char* random_string_of_list(char** hints, size_t num_hints) { - int random_index = rand() % num_hints; - return hints[random_index]; -} - -void flipp_pomodoro_scene_timer_sync_view_state(void* ctx) { - furi_assert(ctx); - - FlippPomodoroApp* app = ctx; - - flipp_pomodoro_view_timer_set_state( - flipp_pomodoro_view_timer_get_view(app->timer_view), app->state); -}; - -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_ask_hint(void* ctx) { - FlippPomodoroApp* app = ctx; - view_dispatcher_send_custom_event( - app->view_dispatcher, FlippPomodoroAppCustomEventTimerAskHint); -} - -void flipp_pomodoro_scene_timer_on_enter(void* ctx) { - furi_assert(ctx); - - FlippPomodoroApp* app = ctx; - - if(flipp_pomodoro__is_stage_expired(app->state)) { - flipp_pomodoro__destroy(app->state); - app->state = flipp_pomodoro__new(); - } - - view_dispatcher_switch_to_view(app->view_dispatcher, FlippPomodoroAppViewTimer); - flipp_pomodoro_scene_timer_sync_view_state(app); - - flipp_pomodoro_view_timer_set_callback_context(app->timer_view, app); - - flipp_pomodoro_view_timer_set_on_ok_cb( - app->timer_view, flipp_pomodoro_scene_timer_on_ask_hint); - - flipp_pomodoro_view_timer_set_on_right_cb( - app->timer_view, flipp_pomodoro_scene_timer_on_next_stage); -}; - -char* flipp_pomodoro_scene_timer_get_contextual_hint(FlippPomodoroApp* app) { - switch(flipp_pomodoro__get_stage(app->state)) { - case FlippPomodoroStageFocus: - return random_string_of_list(work_hints, sizeof(work_hints) / sizeof(work_hints[0])); - case FlippPomodoroStageRest: - case FlippPomodoroStageLongBreak: - return random_string_of_list(break_hints, sizeof(break_hints) / sizeof(break_hints[0])); - default: - return "What's up?"; - } -} - -void flipp_pomodoro_scene_timer_handle_custom_event( - FlippPomodoroApp* app, - FlippPomodoroAppCustomEvent custom_event) { - switch(custom_event) { - case FlippPomodoroAppCustomEventTimerTick: - if(flipp_pomodoro__is_stage_expired(app->state)) { - view_dispatcher_send_custom_event( - app->view_dispatcher, FlippPomodoroAppCustomEventStageComplete); - } - break; - case FlippPomodoroAppCustomEventStateUpdated: - flipp_pomodoro_scene_timer_sync_view_state(app); - break; - case FlippPomodoroAppCustomEventTimerAskHint: - flipp_pomodoro_view_timer_display_hint( - flipp_pomodoro_view_timer_get_view(app->timer_view), - flipp_pomodoro_scene_timer_get_contextual_hint(app)); - break; - default: - // optional: code to be executed if custom_event doesn't match any cases - break; - } -}; - -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: - scene_manager_next_scene(app->scene_manager, FlippPomodoroSceneInfo); - return SceneEventConusmed; - default: - break; - }; - return SceneEventNotConusmed; -}; - -void flipp_pomodoro_scene_timer_on_exit(void* ctx) { - UNUSED(ctx); -}; \ No newline at end of file diff --git a/applications/external/pomodoro/views/.keep b/applications/external/pomodoro/views/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/applications/external/pomodoro/views/flipp_pomodoro_info_view.c b/applications/external/pomodoro/views/flipp_pomodoro_info_view.c deleted file mode 100644 index d42f1c2c1..000000000 --- a/applications/external/pomodoro/views/flipp_pomodoro_info_view.c +++ /dev/null @@ -1,153 +0,0 @@ - -#include -#include -#include -#include -#include "flipp_pomodoro_info_view.h" -// Auto-compiled icons -#include "flipp_pomodoro_icons.h" -#include - -enum { - ViewInputConsumed = true, - ViewInputNotConusmed = false, -}; - -struct FlippPomodoroInfoView { - View* view; - FlippPomodoroInfoViewUserActionCb resume_timer_cb; - void* user_action_cb_ctx; -}; - -typedef struct { - uint8_t pomodoros_completed; - FlippPomodoroInfoViewMode mode; -} FlippPomodoroInfoViewModel; - -static void - flipp_pomodoro_info_view_draw_statistics(Canvas* canvas, FlippPomodoroInfoViewModel* model) { - FuriString* stats_string = furi_string_alloc(); - - furi_string_printf( - stats_string, - "So Long,\nand Thanks for All the Focus...\nand for completing\n\e#%i\e# pomodoro(s)", - model->pomodoros_completed); - const char* stats_string_formatted = furi_string_get_cstr(stats_string); - - elements_text_box( - canvas, - 0, - 0, - canvas_width(canvas), - canvas_height(canvas) - 10, - AlignCenter, - AlignCenter, - stats_string_formatted, - true); - - furi_string_free(stats_string); - - elements_button_left(canvas, "Guide"); -} - -static void - flipp_pomodoro_info_view_draw_about(Canvas* canvas, FlippPomodoroInfoViewModel* model) { - UNUSED(model); - canvas_draw_icon(canvas, 0, 0, &I_flipp_pomodoro_learn_50x128); - elements_button_left(canvas, "Stats"); -} - -static void flipp_pomodoro_info_view_draw_callback(Canvas* canvas, void* _model) { - if(!_model) { - return; - }; - - FlippPomodoroInfoViewModel* model = _model; - - canvas_clear(canvas); - - if(model->mode == FlippPomodoroInfoViewModeStats) { - flipp_pomodoro_info_view_draw_statistics(canvas, model); - } else { - flipp_pomodoro_info_view_draw_about(canvas, model); - } - - elements_button_right(canvas, "Resume"); -} - -void flipp_pomodoro_info_view_set_mode(View* view, FlippPomodoroInfoViewMode desired_mode) { - with_view_model( - view, FlippPomodoroInfoViewModel * model, { model->mode = desired_mode; }, false); -} - -void flipp_pomodoro_info_view_toggle_mode(FlippPomodoroInfoView* info_view) { - with_view_model( - flipp_pomodoro_info_view_get_view(info_view), - FlippPomodoroInfoViewModel * model, - { - flipp_pomodoro_info_view_set_mode( - flipp_pomodoro_info_view_get_view(info_view), - (model->mode == FlippPomodoroInfoViewModeStats) ? FlippPomodoroInfoViewModeAbout : - FlippPomodoroInfoViewModeStats); - }, - true); -} - -bool flipp_pomodoro_info_view_input_callback(InputEvent* event, void* ctx) { - FlippPomodoroInfoView* info_view = ctx; - - if(event->type == InputTypePress) { - if(event->key == InputKeyRight && info_view->resume_timer_cb != NULL) { - info_view->resume_timer_cb(info_view->user_action_cb_ctx); - return ViewInputConsumed; - } else if(event->key == InputKeyLeft) { - flipp_pomodoro_info_view_toggle_mode(info_view); - return ViewInputConsumed; - } - } - - return ViewInputNotConusmed; -} - -FlippPomodoroInfoView* flipp_pomodoro_info_view_alloc() { - FlippPomodoroInfoView* info_view = malloc(sizeof(FlippPomodoroInfoView)); - info_view->view = view_alloc(); - - view_allocate_model( - flipp_pomodoro_info_view_get_view(info_view), - ViewModelTypeLockFree, - sizeof(FlippPomodoroInfoViewModel)); - view_set_context(flipp_pomodoro_info_view_get_view(info_view), info_view); - view_set_draw_callback( - flipp_pomodoro_info_view_get_view(info_view), flipp_pomodoro_info_view_draw_callback); - view_set_input_callback( - flipp_pomodoro_info_view_get_view(info_view), flipp_pomodoro_info_view_input_callback); - - return info_view; -} - -View* flipp_pomodoro_info_view_get_view(FlippPomodoroInfoView* info_view) { - return info_view->view; -} - -void flipp_pomodoro_info_view_free(FlippPomodoroInfoView* info_view) { - furi_assert(info_view); - view_free(info_view->view); - free(info_view); -} - -void flipp_pomodoro_info_view_set_pomodoros_completed(View* view, uint8_t pomodoros_completed) { - with_view_model( - view, - FlippPomodoroInfoViewModel * model, - { model->pomodoros_completed = pomodoros_completed; }, - false); -} - -void flipp_pomodoro_info_view_set_resume_timer_cb( - FlippPomodoroInfoView* info_view, - FlippPomodoroInfoViewUserActionCb user_action_cb, - void* user_action_cb_ctx) { - info_view->resume_timer_cb = user_action_cb; - info_view->user_action_cb_ctx = user_action_cb_ctx; -} diff --git a/applications/external/pomodoro/views/flipp_pomodoro_info_view.h b/applications/external/pomodoro/views/flipp_pomodoro_info_view.h deleted file mode 100644 index dd289a4d8..000000000 --- a/applications/external/pomodoro/views/flipp_pomodoro_info_view.h +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once - -#include - -/** @brief Mode types for FlippPomodoroInfoView - * - * These are the modes that can be used in the FlippPomodoroInfoView - */ -typedef enum { - FlippPomodoroInfoViewModeStats, - FlippPomodoroInfoViewModeAbout, -} FlippPomodoroInfoViewMode; - -/** @brief Forward declaration of the FlippPomodoroInfoView struct */ -typedef struct FlippPomodoroInfoView FlippPomodoroInfoView; - -/** @brief User action callback function type - * - * Callback functions of this type are called when a user action is performed. - */ -typedef void (*FlippPomodoroInfoViewUserActionCb)(void* ctx); - -/** @brief Allocate a new FlippPomodoroInfoView - * - * Allocates a new FlippPomodoroInfoView and returns a pointer to it. - * @return A pointer to a new FlippPomodoroInfoView - */ -FlippPomodoroInfoView* flipp_pomodoro_info_view_alloc(); - -/** @brief Get the view from a FlippPomodoroInfoView - * - * Returns a pointer to the view associated with a FlippPomodoroInfoView. - * @param info_view A pointer to a FlippPomodoroInfoView - * @return A pointer to the view of the FlippPomodoroInfoView - */ -View* flipp_pomodoro_info_view_get_view(FlippPomodoroInfoView* info_view); - -/** @brief Free a FlippPomodoroInfoView - * - * Frees the memory used by a FlippPomodoroInfoView. - * @param info_view A pointer to a FlippPomodoroInfoView - */ -void flipp_pomodoro_info_view_free(FlippPomodoroInfoView* info_view); - -/** @brief Set the number of completed pomodoros in the view - * - * Sets the number of completed pomodoros that should be displayed in the view. - * @param info_view A pointer to the view - * @param pomodoros_completed The number of completed pomodoros - */ -void flipp_pomodoro_info_view_set_pomodoros_completed(View* info_view, uint8_t pomodoros_completed); - -/** @brief Set the callback function to be called when the timer should be resumed - * - * Sets the callback function that will be called when the timer should be resumed. - * @param info_view A pointer to the FlippPomodoroInfoView - * @param user_action_cb The callback function - * @param user_action_cb_ctx The context to be passed to the callback function - */ -void flipp_pomodoro_info_view_set_resume_timer_cb( - FlippPomodoroInfoView* info_view, - FlippPomodoroInfoViewUserActionCb user_action_cb, - void* user_action_cb_ctx); - -/** @brief Set the mode of the view - * - * Sets the mode that should be used in the view. - * @param view A pointer to the view - * @param desired_mode The desired mode - */ -void flipp_pomodoro_info_view_set_mode(View* view, FlippPomodoroInfoViewMode desired_mode); diff --git a/applications/external/pomodoro/views/flipp_pomodoro_timer_view.c b/applications/external/pomodoro/views/flipp_pomodoro_timer_view.c deleted file mode 100644 index b01bd5fe2..000000000 --- a/applications/external/pomodoro/views/flipp_pomodoro_timer_view.c +++ /dev/null @@ -1,294 +0,0 @@ -#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" -#include - -enum { - ViewInputConsumed = true, - ViewInputNotConusmed = false, -}; - -struct FlippPomodoroTimerView { - View* view; - FlippPomodoroTimerViewInputCb right_cb; - FlippPomodoroTimerViewInputCb ok_cb; - void* callback_context; -}; - -typedef struct { - IconAnimation* icon; - FlippPomodoroState* state; - size_t scroll_counter; - char* current_hint; -} FlippPomodoroTimerViewModel; - -static const Icon* stage_background_image[] = { - [FlippPomodoroStageFocus] = &A_flipp_pomodoro_focus_64, - [FlippPomodoroStageRest] = &A_flipp_pomodoro_rest_64, - [FlippPomodoroStageLongBreak] = &A_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 = 15; - - 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 draw_str_with_drop_shadow( - Canvas* canvas, - uint8_t x, - uint8_t y, - Align horizontal, - Align vertical, - const char* str) { - canvas_set_color(canvas, ColorWhite); - for(int x_off = -2; x_off <= 2; x_off++) { - for(int y_off = -2; y_off <= 2; y_off++) { - canvas_draw_str_aligned(canvas, x + x_off, y + y_off, horizontal, vertical, str); - } - } - canvas_set_color(canvas, ColorBlack); - canvas_draw_str_aligned(canvas, x, y, horizontal, vertical, str); -} - -static void - flipp_pomodoro_view_timer_draw_current_stage_label(Canvas* canvas, FlippPomodoroState* state) { - canvas_set_font(canvas, FontPrimary); - draw_str_with_drop_shadow( - canvas, - canvas_width(canvas), - 0, - AlignRight, - AlignTop, - flipp_pomodoro__current_stage_label(state)); -} - -static void - flipp_pomodoro_view_timer_draw_hint(Canvas* canvas, FlippPomodoroTimerViewModel* model) { - size_t MAX_SCROLL_COUNTER = 300; - uint8_t SCROLL_DELAY_FRAMES = 3; - - if(model->scroll_counter >= MAX_SCROLL_COUNTER || model->current_hint == NULL) { - return; - } - - uint8_t hint_width = 90; - uint8_t hint_height = 18; - - uint8_t hint_x = canvas_width(canvas) - hint_width - 6; - uint8_t hint_y = 35; - - FuriString* displayed_hint_string = furi_string_alloc(); - - furi_string_printf(displayed_hint_string, "%s", model->current_hint); - - size_t perfect_duration = furi_string_size(displayed_hint_string) * 1.5; - - if(model->scroll_counter > perfect_duration) { - model->scroll_counter = MAX_SCROLL_COUNTER; - furi_string_free(displayed_hint_string); - return; - } - - size_t scroll_offset = (model->scroll_counter < SCROLL_DELAY_FRAMES) ? - 0 : - model->scroll_counter - SCROLL_DELAY_FRAMES; - - canvas_set_color(canvas, ColorWhite); - canvas_draw_box(canvas, hint_x, hint_y, hint_width + 3, hint_height); - canvas_set_color(canvas, ColorBlack); - - elements_bubble(canvas, hint_x, hint_y, hint_width, hint_height); - - elements_scrollable_text_line( - canvas, - hint_x + 6, - hint_y + 12, - hint_width - 4, - displayed_hint_string, - scroll_offset, - true); - furi_string_free(displayed_hint_string); - model->scroll_counter++; -} - -static void flipp_pomodoro_view_timer_draw_callback(Canvas* canvas, void* _model) { - if(!_model) { - return; - }; - - FlippPomodoroTimerViewModel* model = _model; - - canvas_clear(canvas); - if(model->icon) { - canvas_draw_icon_animation(canvas, 0, 0, model->icon); - } - - flipp_pomodoro_view_timer_draw_countdown( - canvas, flipp_pomodoro__stage_remaining_duration(model->state)); - - flipp_pomodoro_view_timer_draw_current_stage_label(canvas, model->state); - - canvas_set_color(canvas, ColorBlack); - - canvas_set_font(canvas, FontSecondary); - elements_button_right(canvas, flipp_pomodoro__next_stage_label(model->state)); - flipp_pomodoro_view_timer_draw_hint(canvas, model); -}; - -bool flipp_pomodoro_view_timer_input_callback(InputEvent* event, void* ctx) { - furi_assert(ctx); - furi_assert(event); - FlippPomodoroTimerView* timer = ctx; - - const bool is_press_event = event->type == InputTypePress; - - if(!is_press_event) { - return ViewInputNotConusmed; - } - - switch(event->key) { - case InputKeyRight: - timer->right_cb(timer->callback_context); - return ViewInputConsumed; - case InputKeyOk: - timer->ok_cb(timer->callback_context); - return ViewInputConsumed; - default: - return ViewInputNotConusmed; - } -}; - -View* flipp_pomodoro_view_timer_get_view(FlippPomodoroTimerView* timer) { - furi_assert(timer); - return timer->view; -}; - -void flipp_pomodoro_view_timer_display_hint(View* view, char* hint) { - with_view_model( - view, - FlippPomodoroTimerViewModel * model, - { - model->scroll_counter = 0; - model->current_hint = hint; - }, - true); -} - -void flipp_pomodoro_view_timer_assign_animation(View* view) { - with_view_model( - view, - FlippPomodoroTimerViewModel * model, - { - if(model->icon) { - icon_animation_free(model->icon); - } - model->icon = icon_animation_alloc( - stage_background_image[flipp_pomodoro__get_stage(model->state)]); - view_tie_icon_animation(view, model->icon); - icon_animation_start(model->icon); - }, - true); -} - -FlippPomodoroTimerView* flipp_pomodoro_view_timer_alloc() { - FlippPomodoroTimerView* timer = malloc(sizeof(FlippPomodoroTimerView)); - timer->view = view_alloc(); - - view_allocate_model( - flipp_pomodoro_view_timer_get_view(timer), - 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); - - with_view_model( - flipp_pomodoro_view_timer_get_view(timer), - FlippPomodoroTimerViewModel * model, - { model->scroll_counter = 0; }, - false); - - return timer; -}; - -void flipp_pomodoro_view_timer_set_callback_context( - FlippPomodoroTimerView* timer, - void* callback_ctx) { - furi_assert(timer); - furi_assert(callback_ctx); - timer->callback_context = callback_ctx; -} - -void flipp_pomodoro_view_timer_set_on_right_cb( - FlippPomodoroTimerView* timer, - FlippPomodoroTimerViewInputCb right_cb) { - furi_assert(timer); - furi_assert(right_cb); - timer->right_cb = right_cb; -}; - -void flipp_pomodoro_view_timer_set_on_ok_cb( - FlippPomodoroTimerView* timer, - FlippPomodoroTimerViewInputCb ok_kb) { - furi_assert(ok_kb); - furi_assert(timer); - timer->ok_cb = ok_kb; -} - -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; - model->current_hint = NULL; - }, - false); - flipp_pomodoro_view_timer_assign_animation(view); -}; - -void flipp_pomodoro_view_timer_free(FlippPomodoroTimerView* timer) { - furi_assert(timer); - with_view_model( - timer->view, - FlippPomodoroTimerViewModel * model, - { icon_animation_free(model->icon); }, - false); - view_free(timer->view); - - free(timer); -}; \ No newline at end of file diff --git a/applications/external/pomodoro/views/flipp_pomodoro_timer_view.h b/applications/external/pomodoro/views/flipp_pomodoro_timer_view.h deleted file mode 100644 index d5b0ac2a6..000000000 --- a/applications/external/pomodoro/views/flipp_pomodoro_timer_view.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include "../modules/flipp_pomodoro.h" - -typedef struct FlippPomodoroTimerView FlippPomodoroTimerView; - -typedef void (*FlippPomodoroTimerViewInputCb)(void* ctx); - -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_callback_context( - FlippPomodoroTimerView* timer, - void* callback_ctx); - -void flipp_pomodoro_view_timer_set_on_right_cb( - FlippPomodoroTimerView* timer, - FlippPomodoroTimerViewInputCb right_cb); - -void flipp_pomodoro_view_timer_set_on_ok_cb( - FlippPomodoroTimerView* timer, - FlippPomodoroTimerViewInputCb ok_cb); - -void flipp_pomodoro_view_timer_display_hint(View* view, char* hint); diff --git a/applications/external/qrcode/LICENSE b/applications/external/qrcode/LICENSE deleted file mode 100644 index 85e7f6b40..000000000 --- a/applications/external/qrcode/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -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/external/qrcode/application.fam b/applications/external/qrcode/application.fam deleted file mode 100644 index 3aac3f18d..000000000 --- a/applications/external/qrcode/application.fam +++ /dev/null @@ -1,19 +0,0 @@ -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="Tools", - fap_icon="icons/qrcode_10px.png", - fap_icon_assets="icons", -) diff --git a/applications/external/qrcode/icons/qrcode_10px.png b/applications/external/qrcode/icons/qrcode_10px.png deleted file mode 100644 index cb31f09559d63b5bac586e22bd87fd6734b85628..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/applications/external/qrcode/qrcode.c b/applications/external/qrcode/qrcode.c deleted file mode 100644 index aed1869cf..000000000 --- a/applications/external/qrcode/qrcode.c +++ /dev/null @@ -1,967 +0,0 @@ -/** - * 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/external/qrcode/qrcode.h b/applications/external/qrcode/qrcode.h deleted file mode 100644 index 12f2d9ab3..000000000 --- a/applications/external/qrcode/qrcode.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * 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/external/qrcode/qrcode_app.c b/applications/external/qrcode/qrcode_app.c deleted file mode 100644 index c0c27af16..000000000 --- a/applications/external/qrcode/qrcode_app.c +++ /dev/null @@ -1,643 +0,0 @@ -#include - -#include -#include -#include - -#include - -// this file is generated by the build script -#include "qrcode_icons.h" -#include -#include "qrcode.h" - -#define TAG "qrcode" -#define QRCODE_FOLDER STORAGE_APP_DATA_PATH_PREFIX -#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(); - Storage* storage = furi_record_open(RECORD_STORAGE); - storage_common_migrate(storage, EXT_PATH("qrcodes"), QRCODE_FOLDER); - furi_record_close(RECORD_STORAGE); - - 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(1) { - if(furi_message_queue_get(instance->input_queue, &input, 100) == 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/external/radar_scanner/LICENSE b/applications/external/radar_scanner/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/applications/external/radar_scanner/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - 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/external/radar_scanner/application.fam b/applications/external/radar_scanner/application.fam deleted file mode 100644 index 4c6d40047..000000000 --- a/applications/external/radar_scanner/application.fam +++ /dev/null @@ -1,14 +0,0 @@ -App( - appid="radar_scanner", - name="[RCWL0516] Radar Scan", - apptype=FlipperAppType.EXTERNAL, - entry_point="app_radar_scanner", - requires=["gui"], - stack_size=1 * 1024, - fap_icon="icon.png", - fap_category="GPIO", - fap_author="@MatthewKuKanich", - fap_weburl="https://github.com/MatthewKuKanich/flipper-radar", - fap_version="2.0", - fap_description="Detects the movement of living things using radar", -) diff --git a/applications/external/radar_scanner/icon.png b/applications/external/radar_scanner/icon.png deleted file mode 100644 index f951d0c06c4ce050417c7bce9204b2dcfba5fa9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f41$eqRhDe0BP6*^;P~dRB{g*#h zOLv(D@1p*=V&U6cd>H;@J>}r=6W|q!h<(3dhMCo;;GVS$?2O8}vox6&C$kEzP>pcd k{=w+qfsPb)v458tZCO2j-=DT*JCUnE(I) diff --git a/applications/external/radar_scanner/radar_scanner.c b/applications/external/radar_scanner/radar_scanner.c deleted file mode 100644 index ec9971de3..000000000 --- a/applications/external/radar_scanner/radar_scanner.c +++ /dev/null @@ -1,203 +0,0 @@ -// Created by @MatthewKuKanich for use with the RCWL-0516 -// Design inspired from @unixispower Wire Tester - -#include -#include -#include -#include - -static const uint32_t EVENT_PERIOD_MS = 10; -static const float BEEP_FREQ = 1000.0f; -static const float BEEP_VOL = 0.9f; -static const GpioPin* const radarPin = &gpio_ext_pc3; // Pin 7 -static const GpioPin* const altRadarPin = &gpio_ext_pa7; // Pin 2 -static const GpioPin* const altGroundPin = &gpio_ext_pa6; // Pin 3 - -bool presenceDetected = false; -bool muted = false; -bool active = false; -bool continuous = false; // Start with no signal from OUT -bool altPinout; // Sets which GPIO pinout config to use - -static void start_feedback(NotificationApp* notifications) { - // Set LED to red for detection - notification_message_block(notifications, &sequence_set_only_red_255); - - // Set vibration - notification_message_block(notifications, &sequence_double_vibro); - - if(!muted) { - // Start beep if not muted - if(furi_hal_speaker_acquire(1000)) { - furi_hal_speaker_start(BEEP_FREQ, BEEP_VOL); - } - } -} - -static void stop_feedback(NotificationApp* notifications) { - // Clear LED - notification_message_block(notifications, &sequence_reset_rgb); - - // Reset vibration - notification_message_block(notifications, &sequence_reset_vibro); - - // Stop beeping - if(furi_hal_speaker_is_mine()) { - furi_hal_speaker_stop(); - furi_hal_speaker_release(); - } -} - -static void draw_callback(Canvas* canvas, void* ctx) { - furi_assert(ctx); - - canvas_clear(canvas); - canvas_set_font(canvas, FontPrimary); - elements_multiline_text_aligned(canvas, 64, 2, AlignCenter, AlignTop, "Microwave Radar"); - canvas_set_font(canvas, FontSecondary); - if(active) { - elements_multiline_text_aligned(canvas, 64, 12, AlignCenter, AlignTop, "Active"); - } else { - elements_multiline_text_aligned(canvas, 64, 12, AlignCenter, AlignTop, "On Standby"); - } - - // Display presence status - canvas_set_font(canvas, FontPrimary); - if(presenceDetected) { - elements_multiline_text_aligned( - canvas, 64, 20, AlignCenter, AlignTop, "Presence Detected"); - } else { - elements_multiline_text_aligned(canvas, 64, 20, AlignCenter, AlignTop, "No Presence"); - } - - canvas_set_font(canvas, FontSecondary); - if(muted) { - elements_multiline_text_aligned(canvas, 64, 32, AlignCenter, AlignTop, "Muted"); - } - - canvas_set_font(canvas, FontBatteryPercent); - - if(altPinout) { - elements_multiline_text_aligned( - canvas, 64, 42, AlignCenter, AlignTop, "Alt-Pinout Enabled"); - elements_multiline_text_aligned( - canvas, 64, 49, AlignCenter, AlignTop, "VIN -> 5v :: GND -> Pin 3"); - elements_multiline_text_aligned( - canvas, 64, 56, AlignCenter, AlignTop, "OUT -> Pin 2 (A7)"); - } else if(!altPinout) { - elements_multiline_text_aligned( - canvas, 64, 42, AlignCenter, AlignTop, "Alt-Pinout Disabled"); - elements_multiline_text_aligned( - canvas, 64, 49, AlignCenter, AlignTop, "VIN -> 5v :: GND -> GND"); - elements_multiline_text_aligned( - canvas, 64, 56, AlignCenter, AlignTop, "OUT -> Pin 7 (C3)"); - } -} - -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); -} - -static void get_reading() { - if(altPinout) { - continuous = furi_hal_gpio_read(altRadarPin); - } else { - continuous = furi_hal_gpio_read(radarPin); - } -} - -int32_t app_radar_scanner(void* p) { - UNUSED(p); - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); - - // I'm keeping the forced backlight as you will likely be away from Flipper - NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION); - notification_message_block(notifications, &sequence_display_backlight_enforce_on); - - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, draw_callback, view_port); - 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); - view_port_update(view_port); - - stop_feedback(notifications); - - // set input to be low; RCWL-0516 outputs High (3v) on detection - furi_hal_gpio_init(radarPin, GpioModeInput, GpioPullDown, GpioSpeedVeryHigh); - furi_hal_gpio_init(altRadarPin, GpioModeInput, GpioPullDown, GpioSpeedVeryHigh); - furi_hal_gpio_init(altGroundPin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_gpio_write(altGroundPin, false); - - // Auto 5v power - uint8_t attempts = 0; - bool otg_was_enabled = furi_hal_power_is_otg_enabled(); - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - furi_delay_ms(10); - } - - bool alarming = false; // Sensor begins in-active until user starts - bool running = true; // to prevent unwanted false positives - - while(running) { - if(active) { - // start and stop feedback if sensor state is active - get_reading(); - - if(continuous && !alarming) { - presenceDetected = true; - start_feedback(notifications); - - } else if(!continuous && alarming) { - presenceDetected = false; - stop_feedback(notifications); // Green LED if clear/no presence - notification_message_block(notifications, &sequence_set_only_green_255); - } - alarming = continuous; - } - - // Exit on back key - InputEvent event; - if(furi_message_queue_get(event_queue, &event, EVENT_PERIOD_MS) == FuriStatusOk) { - if(event.type == InputTypePress) { - if(event.key == InputKeyBack) { - break; - } - if(event.key == InputKeyOk) { - active = !active; // Toggle the value of 'active' - stop_feedback(notifications); - } - if(event.key == InputKeyDown) { - muted = !muted; // Toggle the value of 'muted' - stop_feedback(notifications); - } - if(event.key == InputKeyRight) { - altPinout = !altPinout; // Toggle alternate pinout - } - } - } - } - - // return control of the LED, beeper, backlight, and stop vibration - stop_feedback(notifications); - notification_message_block(notifications, &sequence_display_backlight_enforce_auto); - - // Disable 5v power - if(furi_hal_power_is_otg_enabled() && !otg_was_enabled) { - furi_hal_power_disable_otg(); - } - - 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); - furi_record_close(RECORD_NOTIFICATION); - - return 0; -} diff --git a/applications/external/rc2014_coleco/LICENSE b/applications/external/rc2014_coleco/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/applications/external/rc2014_coleco/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - 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/external/rc2014_coleco/application.fam b/applications/external/rc2014_coleco/application.fam deleted file mode 100644 index d9b3aa727..000000000 --- a/applications/external/rc2014_coleco/application.fam +++ /dev/null @@ -1,12 +0,0 @@ -App( - appid="coleco", - name="[RC2014] ColecoVision", - apptype=FlipperAppType.EXTERNAL, - entry_point="coleco_app", - cdefines=["APP_COLECO"], - requires=["gui"], - stack_size=1 * 1024, - fap_icon="coleco_10px.png", - fap_icon_assets="icons", - fap_category="GPIO", -) diff --git a/applications/external/rc2014_coleco/coleco.c b/applications/external/rc2014_coleco/coleco.c deleted file mode 100644 index 2d32777d3..000000000 --- a/applications/external/rc2014_coleco/coleco.c +++ /dev/null @@ -1,365 +0,0 @@ -#include -#include -#include -#include -#include "coleco_icons.h" -#include - -#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 = &gpio_ibutton; -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 { - FuriMutex* mutex; - bool dpad; - int row; - int column; -} Coleco; - -static void render_callback(Canvas* const canvas, void* context) { - furi_assert(context); - Coleco* coleco = context; - furi_mutex_acquire(coleco->mutex, FuriWaitForever); - - 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); - - furi_mutex_release(coleco->mutex); -} - -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - PluginEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void 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(); - - coleco->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!coleco->mutex) { - 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); - 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); - - furi_mutex_acquire(coleco->mutex, FuriWaitForever); - - 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); - } - } - - furi_mutex_release(coleco->mutex); - } - - 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); - furi_mutex_free(coleco->mutex); - coleco_free(coleco); - return 0; -} diff --git a/applications/external/rc2014_coleco/coleco_10px.png b/applications/external/rc2014_coleco/coleco_10px.png deleted file mode 100644 index d51652adc4d0fdd98b55940f3277af1b54cbd4e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6667 zcmeHKXH-+!77o1#4#F@ZD8|r{^hP26~uyqG6MQ2Vh1A%IPV4=N7s9QX1zE6%vwp#-DmG_@BN+co^{SHcUMPMWo=~; z2&C%lWVZqMmyDGa<$>S5sO}~ZNU1i~%U8I85(DP(xlC3#11#LaV}KbV783*#^_TjO zM@=FY&+a#^m3;@2%4wZ!dKGf>sg%jgOQ5KU!9|EjKwI z)@iarG_+MLXB7L=$FJb^&WTC!k@)6D*M~Z~xzhV6i4TOe&4DpKGBfVHHhk)ZWB3VoHdQ(kp66EWGq@IIkh(}+?Y*YkLm&C$Eca)*dtX0j$g8iY zxL54oQ$W5d(=i@9`<_Vn;-76lNAC9MMkgkcTw*@=$jpe>gg&fq+vAaS$SR7c5Vfq6 zXxo?$JIgk(TAwzUOR?!)^Xwe&zP!(v;~LZ7Z!<=VI)yz^K2LfbIl+;%K}aP;`->pSfYR?^W%ev`2c53J0;{*Zv~<*}#HLVs%+fBnD2XOs0ghK$Wvz2dU%1!t+PM?? zB$!6I-XUwH#U_duI*P2$YAySs=P_ivL&lNmYIZiSz9fS>oOM8dQM!GyoqCQw#MCcc zesAXyFE1>+!%{((+-0)9H&0+PR(*xva!*cmUD@SS?bV)S@6)}3>$lHbcvM$vNDknX z&gc?{9o>Q}PWWXdtagPEx+E4E}Q`5fKG%(J+cRfg{7d%w#1Fg};M`L)+=cmX=`h>$ZhPQ|xDp@y@1%sy zr*L@3kZG5^#s88y;UqJY(Ol>8!X?Bk&0Nn{wRlzKh*^u?`_YYyq)T_B4yAzyef!U$ zEL@jlnA|!{I?2NOYsaQ|wAim$QWaG1Lsx3VW6q@oh`lqGA>0^{DREi)o6M^m`E3)Z z5z|NV6Sg;Rfw!1DYgtupz21ku1J2>Jmo*)Yl5t4*AQOIOTt3avZ7?Ge_7+#Cp>1Wx zoBCy-Q#q`*rR5Qur_(Rb3<7D94v0-cr=0pv=Jn{Y3iuBDOX541Ef^0L&*h*$cl0E* z9v)P(afEGjsT-29x}~lF(T8{)az1mjdhaeRi`B|Gfo$nVzoGO}i}yr6v&!OYyvuuJ zUwdHsde3d%jWN!u4{_kQK0lI{$}M&E0HP_nXPf(PrWabKy3cqJ(_z!dnohl24+ows zA3rJoaXJ+;di??1p-ZDGD$*B1?!GHG)VuO-9=?hVcXdC2Jv?}Z(Kf(gOQT~1&#Qj5 z*R|bQToyJF>A&?XvT)PXz|xzFl|i1BgD0M}-Fex+Grd19%P_kX=a6iLRl2w=6I6B8 z_U<8_Vc}TdaI{N?#jVUvsTyn8rB#P3yeDhaGFt~VwK&kN;?_^7J>z4?t96zR?2fjh zr1%6X@5xrxGx}8QKt5iow%W#UZI?BmFo}`ChhG#7K|FeigOkzHD;9QJ3J7q7Uv)g0*@f^>3UtP4-vn z2Hf-8I-slKy>WYb?LEcn!wM@I9~Mm zz^AZM8(rp#DLTKcDWX0qDp^i=WxQ=k=?dk( zODhg4?#!uoWV3ziUx&0mJ_-8`F0QRP18uOHS&drwSvFFTA&~>5*zvBVy+g(GxTVXQ z4on8or}}%enOQqr*4qTjlY5f(nT`l`PtA^QgSGEz+Fd|fXUB@D;Z4NTuZ6zR2VVg9 zj%S9SDb}UEKlID0W8x0-Eel)2^BumEv2wQ)DWngp+oGBSXoV$)ZM$xb-q_brBR?>1 zaXd`H?RJ%8Xn##eR&lfn?A6t*^FC&>hy?o^X)xc8EBmJ2(m&7W&D9R6_QKPga*?>c zbrzW)GJ?-D(q^8s5>Ti7L^UP*3RotjiuTHU%Y#IIEa$wSfuN3x-IT3_YS^N5S_)0( z>c8af57zmdko55~@2*`nx55uI_gv}ewA8VEZwKXa&OM!!A^!gGkG@|J7XBRGnoCPJ z@zyf(=aS0zRnCUw#>547HeTv%^vSP0y=GEQBt1}fwZI}NVe{L^bygKJty?3vZBj`6 zI4u2c`Zo#v4f`B^FR;BnQcVk z(hlR}9_vOi=Wh}|=b2+)m1<`7ELmNeAH6JIR**YXX?C2s=!R(OvQN6NinQlJ*~EJ( z*I4YU356R2&8U$}GqQq$rUJScF=>^bo4;S|6(?X@c(^ve>8WV3a8kGvhtL#>(I z(orLh4BKU_;klb8OQha24p-%Ix%qL;cV?)WJ5P=UmIUR5vA5Og-m7|;X6)gO&Y=&j zyn2;U`CiK>#pOZK8KI4rX5yoKq+pD_)IOYbahI)HO;%o^GJsd<;dK{!ueihpZSNa3@Fwb5V)+A0J2TOL)D% zmYSej9T*c{TE3$oSNPg;AL&wQ(d!+|T_2w4oy#HGl0G^Om2GVn%i_Z*?D}9aJJ_aC zj;S%KtCg#LzH=LdS^CS>hDX2o}D4S0$PG@)DH=$;-DqX6wN zZ;T(Mzd<-WCG_F<$YqZpAJr z%*9nNizg#z_FFzyh__4#Q@r-5Sv0%y#Itp6szP}q5J)P8Wozs1Y-{`H2@W{7<;7=` zoLb#~-Qnh0y1_L06?izKi0G%L8F}CI*CLx!n*LFUE#oUONPQF7zGQYwOTqQi+jm!& zFD_38Ps>Qa$R}lq zJ!np`;}(i(V50i;bHhp3(~Yv-@88T+$395Do|NQd(W-LKaFbDf{{_{qnQO?6Io`v9 zVUL3_r`a1(*Pr3L407f2m!Yc<6Na^_d|!l=ZujfEztd>fv(qO$FK0~p{_E0pzcanQ z6Zx|{GLtV~x)$Yc>qL>-odLG7R@L;P=vg237$Z5fRMRr?5FhDo z+)5l3bKTepYp0*_qnGg0M}U*|91A#6`;uLVG;RcpLg!K$Fi`{#IB|nO7HdU33XRPW zf~ky97Ka3R)7T6Fv*;v<50;D|^K2PmET>pL!!y>^ix$hK5$KS$mdX|)A^;G<5K_RR zh;WX8C?Y}Taf!fKVunM&^DaU*3F1q32itP_3@`?UfgzywB33jCVyO(a;M1AJ4R#J+ zA%G_mBupse5#jKdm>5_L8ph>^!jS|50ggbyQ79ACA0-=300P?k< z{~96i0xl--4GaM{ice$MM>9A=z3(CDv~TgeD1P{SJ9HYH5zdGJTm?W@9PSE{#Pe&JU3oDjI`DW1v(5jS0n2P-v(*5@!yjGiew!g^DK7=+y6^oH+s^g+pUV zpa5_f3&5e{u_zjrhK1s>XcQEKBG8}|EFKGhA?SDvgMi0V8Q(#;@mYW>DdFE&C4r&? zP$;}Pg^ov{pf~~r0mWb`Sg1JzhlVn7NWg%n)38+hJQSTqbl~zMD8O>EA}FB@IFA!L zKOrHUXzlJyf}miCzbx+I6d@A`AVFMMoG8&>6JD$chNqAsVH1hN;gA?K4udhrnq%+_ ziRSS(GWY^Oi4sgC0)}3|l`IPpXa*pbBGD-TFb@m#LbT;GC_*mZi^~lsK_n1hN#wk| z!4?aP;=~dF9$O@e|EhUUM&!cN!YdHYnx6uL=VeQz&=!&iDA5f1d?FxjVTu+;;e;}P z_xr1${rkLmpc_Cy^WA`r=czRLv6h%HhJ+^s@NOd!Pz2fwg&?8{L<|Oszz`7#2>hRKk%>YP z5O_2aiX>o>Pz-{AgHp{=2q>0@L@_B043);9{aEz>(jwB_3xy?C|8=KhaDane3~*z+=&|<*aNCoou6MMXzxRPY*)}EuBPE`b zp8y0}+$#A>wR2C=0i%M@nQX5xqO2ihY_|D;b|zpVIonx#Y27=Qfm{qiC`z|X{{g?( zVMw;^bT>?E6>T`6RuT$kt#UrKR2Y$WV*RRHiErzAoFgWlXCKp&xgvcnMnhdRG&v_p N?QHLAS8fxM{BIwakD~wp diff --git a/applications/external/rc2014_coleco/icons/Coleco0_17x17.png b/applications/external/rc2014_coleco/icons/Coleco0_17x17.png deleted file mode 100644 index b53bc3b5fac13dad96596296cb434e670c9a7c2f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/applications/external/rc2014_coleco/icons/Coleco1_hvr_17x17.png b/applications/external/rc2014_coleco/icons/Coleco1_hvr_17x17.png deleted file mode 100644 index 562c7e8db8e7f403098c43884f9ecceded2c2788..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/applications/external/rc2014_coleco/icons/Coleco2_hvr_17x17.png b/applications/external/rc2014_coleco/icons/Coleco2_hvr_17x17.png deleted file mode 100644 index cac46898140ffdcd3fec2160747761505e01df57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/applications/external/rc2014_coleco/icons/Coleco3_hvr_17x17.png b/applications/external/rc2014_coleco/icons/Coleco3_hvr_17x17.png deleted file mode 100644 index c0015312a9c51c525c24fd235c08bee3ee3be1e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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@$^ diff --git a/applications/external/rc2014_coleco/icons/Coleco4_hvr_17x17.png b/applications/external/rc2014_coleco/icons/Coleco4_hvr_17x17.png deleted file mode 100644 index 63e0862756c497ab552541f81062790396db47c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/applications/external/rc2014_coleco/icons/Coleco6_17x17.png b/applications/external/rc2014_coleco/icons/Coleco6_17x17.png deleted file mode 100644 index 6ed3e239c278ad8c34c94c4b08a966143d6981d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/applications/external/rc2014_coleco/icons/Coleco6_hvr_17x17.png b/applications/external/rc2014_coleco/icons/Coleco6_hvr_17x17.png deleted file mode 100644 index 4be93b365530e024b72675721821170fb539d703..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 634 zcmV-=0)_pFP)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^0t9*(;pqSX02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002@+L_t(I%k5M_3IHGo+rs~Ud7T1@urLoD+RekJ8$(JG zNn{}j1Rz|Zp#blQ*eEX>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^0v?BY7?S`102y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002};L_t(I%hi-I4!|%718vm*fB7P45=3;P68VY zU|YKaEX>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^0y?{S{6YW#02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002x$L_t(I%k7f64FDhv#O@ILuWWh*;Vmd|A4^GW0NdIH zkR_o*k}mL$Bu59U={=w;sRvrprF8&B8KhIeP%%~9&h9oL+HpBvJavm7mFgoD? 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^12U|+MKJ&X02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002!%L_t(I%k7jw3cw%?1T)3|e|bFgqJl_+6bs!;$RPu} zEI}2BtkmG1rXfIFu|elR%F1sW;A05T9gh2ZcGTa_1oW-O?g@4bF!N6;4Vy0>#miM1 P00000NkvXXu0mjfg8T+8 diff --git a/applications/external/rc2014_coleco/icons/Coleco8_hvr_17x17.png b/applications/external/rc2014_coleco/icons/Coleco8_hvr_17x17.png deleted file mode 100644 index 519ac1e9772504594b6b18410a25ea278dc92269..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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- diff --git a/applications/external/rc2014_coleco/icons/Coleco9_hvr_17x17.png b/applications/external/rc2014_coleco/icons/Coleco9_hvr_17x17.png deleted file mode 100644 index 206e0acd9d1461ebf422ccbc94b35a6adf675ab3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/applications/external/rc2014_coleco/icons/ColecoAlt_18x9.png b/applications/external/rc2014_coleco/icons/ColecoAlt_18x9.png deleted file mode 100644 index 7e6853e52ed287cdb7ebaa1b7612ea7f260a4332..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/applications/external/rc2014_coleco/icons/ColecoAlt_hvr_18x9.png b/applications/external/rc2014_coleco/icons/ColecoAlt_hvr_18x9.png deleted file mode 100644 index 6b15dcf7b4089e4a0f3b9706d1e10e7be486030d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5037 zcmeHKc~n#95)X@@$S#ObE4QIVizK-TAtX6O2!TSB0EH+ZxZET+AwU+AO9)z(s<_k# zh+;uhR8TpB)a8jhSwy8&1jMC?R;aQ_>w*eTPh~CdOF+fb{^L2X|CyX5_s%!-o0;D? zGx_fJu#i9tGbb|~4rjp)@(%~Uw%{{kx(WF9dGL)D4rg>}4L=GCM^YfAN+Fgeq7as< zL?Kiw72|N)d(W1|eE-nZd`w~=ZMe(Ywy7&MM6FljU4yahMdpm^i~p1nz}w5 z6(1TD_TSoIUZW|=d))3|Fx>wM|ypGO<}w-@j9e}%8eJu~iZ zukv#aFtY2hsgLnD9h~mgW$0aVHOh0*>I+wXvnbl|p9{8a;%}~%jb@fhMsvKb_eI>V z4u7_XW|dH&upbIaXudue!Fb$sBY|BoHdNO#Rxl7a-0r77D6^ zTtBHW@ZDTy-*TwMwm!Hprz@NMiA@@2&F^9^={7M5+GD!^;pe;9mL*1OdmM|38XI%x z6qg)<+@j4p?2bbVzXo>CGc0(YzHq+T2qkSN>#Ell6PN;A-ocy{V@Jx9fM8 zO1x4?D`z@f8Yr8Vyu3Omd?BsuRO|qj?pKzv?`-SYUh%b<8D*Lyp`k0*K5whZU1@6N zxS&6KtA#V#%AIwb`g7~vV%|ZtEu9~8=GLt}x#_*7Cx%aHejetGIGnh7&B^)LxkAKcHk7%@8|OFX zFo4W@c?? zTc-J%8@^bV9(pLOXZX`92gTa{@zc^mYunX*D?{(KndN^4x8!a6FX>>xq0ADFom)=s z;TrDj^TUC)^8F8t`=*iN>@N45+SZQ48ElqvIAL54=gr^%9`>)xW(C#x&aGb+kr1%Z zQe&Oe5O%#ATaV(BFjY8~ zZ99I)ZuyT|Wk*)Z>v<_JaEF%(@^6z(;wojXJ!JBMX!}hkAF*-1^M69cj_O@GX}=Fv zZp}KG@^wM)y64w#mWl}`gZ|yo;yl`b$-t{)GUfgGmjB*(!uH^-tbB~!9r(jSVr^23 zS5)U-#ADC?`IfVG4AGX|%d-#8(0)fRjA!=Fl;$pNiP>Ksp6>bL>Z&=7PZl=C7Be=} zXP-8nfw$v_`Olygo_%s8D(Kew<~pCd{YxH(H!L-FxnkIO1M(W}+|XYYv(Sst<(e+= z?W|8)wB_4QV%SM$%j?rUt)aMa59QH{(OxI`C3j8v(SXdf3$o7c%A;Sdz1V9B_lp{i zb?h9arpH=peTo!~xUmY~*ZJ)+YUg4r-|s3Hci>F7UJNQYbBA^R*W35oYbE((V>oEJ zYD;F3MFSY{PEs()qjv5UjS|=vq zA-xKgz`{rI!XS=9g+f#!l?W38v{DTPzsL;oR*A&SaR09+A;29AABSN|CW(}il0r=J zASzT65}CnZkYEalLLmSRf;v@>AzFf5?V^L2!0<=aLKUcFsX`9vFcE$lB zpG?W)y@i*nCs_b|khF-BL?*%{nT#~mLX8Dz0LWxOe`}%Uga1QPII318tAuEP29;wj zQz1mcxAw|pRiZu}k&uKYqB5YW242bUxeVm;!rofwD3C~HO1%{z`#nueDt<@Sd$H+O z^yy3u1em|YeNX#M?s{dQ#p5yk6~bg)cwB!LUgw`FQV69Yrv8#jp?V5nss};fMHLgM zR0Ji^$qXt%fFNFE8cmE)1hgqoT)7%U=vh zn1;~B0+Aj{BxHW2P{|Omol+ShK}kxvM8BXToXHO3vhWll{7w>|bkPX^D8B*R3H30&Q_FhMeaSVUK+06=d6 za$#~*D1s?ee1#&Bh1Z1y=`8i-4S7#&N|00yG*WdHKUwn;Xwt;pL<=NJ^-B<>FIy%e zoN%H>H0T5ez;0qm7>CFuDCqCWf_fvD{>^5IgfLwsrg;%OV8n|+MJRLvLV+0sGFeO( z(5N&zics`vyhT?l#8?WVLfI0KDaZyCkUkq|fu71Q-`7rwLv=jCpts3n0_@3$DNLBm zgee4=%7kG&X)`nR$C*FF6DPsWGO~}A_0n>`~c3e$zrlav6d`<4fKj;BK ze{}Le{C=eCBV8ZFzy~RRtgerAeGmg5r2MhE{%>@dy?fw6<=_;Q0v>02n=?h=QOHEF zB+wr>u6rMU{mx&Cbag6q$k*)}-H{NkzE;{`jW|MAPGHrA#5 kmHg>Hrq%6qmi>#EaA~^vZ@pFKzyik&2=V{HZ}rCi0WhPNH~;_u diff --git a/applications/external/rc2014_coleco/icons/ColecoFire_18x9.png b/applications/external/rc2014_coleco/icons/ColecoFire_18x9.png deleted file mode 100644 index 8be499c21d1f0a2443de5ed18b200c3adbf5a8c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5660 zcmeHKc{r478-FQ;EGM$HO{20ktJyPy5Xv&4tjRkw?=YCf%rKMFf@7&vv?`@dXglJ> zDI8j)O(l_}l9CpRNTE2scZRm_JO6ZD-}$e(uJ@hieV+UN-S_>w?`PY<^m5hFGSdP8 zK*!z9*$4ig0zaCQ)Zw@NrLh)N(i<3JQf$!yjAi2hWDjx^nGVyE^;oq1aF1j9DfoFCM5;S7>(+-CJ0Y zmlS&Tk!6R;sf_mb0htZ=QgkQY64d6;(wnYLW#|u$RLoe<^6F~~5~e}xCg(jkAiIcj zwwd{O|7N!vFD*!+=fnLEp6*4aU7Xi%Mp<{j*L1g>(lxm%X91Ho!uH1sdify;4?>h% zaOD%@UUeT;)y$c!8!R-wr>rcd|K^LSXZ(7p(!QKX|4(xTg{@g?@i5FUSGHC&`3#ZT=44>cIi!$L%&_XZ9JKEM%}>q`a^xy zNkHXmPR#w-EdA;HnoQYhu(&ol^m(>t{`OZ!zV}(Uiloe!3W)ESfVp17LCTy-)f_xHYgctiR$Q8R zqLKaKY3@Pgy%pEDE*>~6Uf21-qqK0S5LNSmP zr+Q)2n$%NPP4v^QRg3zqC9|>B*v&1<;;0U9LiW*;m9u9*d6=lWPw4pQvr`ta21osd8K1dsXClh{~^T(Y{ zro}ZZ0Wa4t$C@Q-+cbpoRONpup1wxH+Fbt@)WnH~JoOUq{d@e>I)=NIQDJ@43^ z-W*kndpK=Pl-j+A;y2<^y`J|syHAXk@U7G$ZBW79mV7!LKU1S2&ImD-WKT5}bf z!fuo1TXd`gJh%+F{psSllG|M>4l!%z0WVA53xM0MmZ}q^%(rpCZC|amzX1Ikaz^hg zJf#kxR2lj}kPBl9&_8=)TlT0M;9(sVF-wDaXlB>mZHb-pjwS?LAKc@d%C}8SZBhML zg{eB8YZ^(UU^ANLPVU`PzgIrGXeZ}Dkd0;11n8=psZY6|!5qx$AXnQ^Yb`CXp!{UU z>)xg?W>LwJCTo8_zn1k})YwGXX5^O{W7K$->r?xe&GDyu7$yOvpkP<~$P*9r+G3v` zEi8>F&Z1;YSbvMv*Fj0_*S)l2w3v8@k-qOd>7-6%8Q~5iae9%FCCYX6eut_FrGF13 zXpk)F>2^szi4oq<)I7WqD-$cP8$UAmpu1A)-MnCRJss?M>oSmBS#7+=ILy8yy-K_2 zK%dKFwPx?3!#%363s%?LOzWFk^>U}qP%`GPyj(B$YOChX$edK-R7@M#*#(@8Ysjsd zP!d?lxMy0>Zn~!P&jfOC*^$eersrL=(Bs@y+tNR$%HVFSkwzey*yBBH#{Wbg@^@o8Nsn|!lb;{^H!=OuY(ZdYcz)V>WaA-Lz z`z}sBqMSdk9f!*aoci0TmyUpg#bt72OKskpQSuir+HhuhY@tq8UuQ=iOBVL7zb#4u75+tAEYv|9tk?Ty~RsI4gP z%y5Sp_MLltX`aiLgerd9)ABs4U(a{wV&8JE=0D6FCZvSu%I$N7*MX5U4g=W_f+e#G z^c*&pFMbGUq@8!$|HnOg>!Z7^56*>WkBk6_AaUxJT%D`%Ny3Z=pBMr>J!otp9}RMZ zEC?;3D2!lgo zF?>GeTMdcSB@PA|cjzBAB!2M03*!Sxgt1~a$c|OG=k82LD(urZLN<>>Q#Oel0>>7|BBStlEQBI($W#;y3lUHp5(@+&3YSX& z$=^V^3nWrdz=jl1FgThA<4`%acz7kpqevXGEsB7nfGChf;h^wr7K=>8l88hW^&1Fp zF%PavF#21s6i^%(3eTmoI1r19B5_GL6ai1gp+LMX9))8=1PY5p;@FZQB@~BETO<_o zK{%Z}J{S&RM1pYTfP!$EBh#IZ#G|oadzjInlnX1+ksdrjto-YMACC|DNT^HuACkqvv+)!vM1&JeCd0|XQc)Bfk%S_!@GLTpizAZB|Aj6Q za-}j*3^|6wk;2iy1*D7yVX36j>U&>g5s-o>EIhYyI24xXhsD#dSQ?Ii!V=&H5;Gn! zMlq{DM{I}rA5QF)0^ckHu-;f7yu84x73RxwHO`rW#((iQo{N9c0u24r$Pe-Rldhk1 z{SX5`B>c0we$w?r4E&Jr&+7WW(WUkE!UGB5Q;-b4&b-r%jfby7>Z~QM&dN&>FyvIR z4sL0R+yW&4fHqe=D)K!0IJi?o>h9^H@myO?9nd}1ckvk9Wh!+EkU9zZigPodJkCKJ zgp4PRKq!uL{)xKAu+V&WXGcHFx;Hl*bpV9^`J&BjkNfm5q!>?SCYltfbawj$P9CbS fj_^O~?_Q(g3205}O*nl9)&tyKyqpUch9&(6;*+Qp diff --git a/applications/external/rc2014_coleco/icons/ColecoFire_hvr_18x9.png b/applications/external/rc2014_coleco/icons/ColecoFire_hvr_18x9.png deleted file mode 100644 index 2b0d1d72cab82d36f37803f9c250ec6842a2fe3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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( zl%>Tfg;KOwqGha=Bu-yaas1w)_4=KEy1w7@UvpjWyzl!w_x-u=`}2IB=Y5{N9_ySm z)C|=i5Qv70GsP3U>wuT4iZb|b^E6ru0#W`u(tDHGlO}-*gnSk!1b~Vo1OOC}a##?E zw6h{B_|T&jI*HT4dS!~x?c4iDRPMa^x#_QGbIr>9c@jy*E0-$8HQI`yeCxhje}Aa2 z{`(rjd4;c=pYZm>(PYcEmgl;X>GxGp2F+8kD$Q2Y5tG8Ph@Tef_*I#_4Bmk#i z4OdyY7%aF%F^*q0yrBnmajvVk?frQvt&h60o^}pgbBr7PaI+NGb8Ebh?-6z3>FB`Y z5Bu_ZeHC`dFVvAFhu6vvUo5TjuG?0p;wYJQ*h^c1&UD@c!8M1BWl%*R=6K zDbIIZe6=z@`_DPfmg-fFwf(*xC(-$~DWL@2UoM7?vb!SBFTPwEQT5`8q4m|tB@fqc zZTDSXQW4YmfqP5XrFQA+__}g|@r2|WR(td%Du|>UyXEOLu4GR9i>xX^?ZEr6mqd>%fEW7AWv7X_`W)NmUO1FmPu_TQMZ+wXv`mn)I8@?^oGU--?psBbiz-5pMt z-ah4LQQVo7vB|U1VXaw3x#218%U;*l2cN7sf1^O7F|{>SwRo&0zy8D_>OLW)wYevaE@8EF!^GA5O(p&|5p>gVy@^bNch!SDr2zcYL*DY<>F` z+uJrpi3tyWE#f~|xG`q$h*fr8>Y_b~&lUXbH0q$^H=6WJ7#$7VrUoaegW8HCIKq8? zoh|aH7Uvy4TuW%+GYPNU;-|^$_D!$BiMLUPn=7YODyqur2zws$DpLm)U-w?h)OYQA zF^1@RnQIzdF*OzM6MoAfe%&^sLQ05U^r7>)4Och#9%?<fA9Jn6h-`-a+(m@R%Fzx5Sq8p(g6vJbpo%LzdFrTSEi)jBWRGo`fB{xI3yS zJvEa4chZBC0a z6m8kyV`{8&N-~%ckiFPgt1RR2kutxtxvllM@SS)0B?GaJr3+BGL3Ja`pB3Kkz81S- zv}qty9hc>`G?sq7@ap8nN7-SSMfM{(1Ivxg=BB?J{MmoELR1d6U`OSW;;3UMUq@=y zX{kh%gpHrg`9VV^1DBW^&sC7GGcBW#D{{Tqp~^y~nd}S6kBU%4@Ri zKM}fi#O=x0s93bt`8MJ1lD=-oBSmv%f{G%3{BK9_XCD_;R*&-6b>X%crJ~hy>(j|K zxQ=toQ%ycbkdDJKeea3S{G58J=7PSIpFZS|s#i49P(!pEgTj%;jGMHZj#mnI#Sc5( zv#PIAp;Rr^Z#%owsKWl>#r)yYJr~s1JnmE&GH(1J%U!nhidj;$e))r9>XPSmsxbBw zajzTM&J4C&y!gJ(%EiM*rgy{GsYH5Pa>ls?(Y<|b3I7=rDuDA<|95ED+5L6Y6Z>^L zNE-UR!JUJD*jEf+bTrH^OTDSBWTLm5{l?j|vBq@SqEoM$+O*UMYB}C(G!$A2O6@|H zoO>1)5Eye{K4D`q)xNW{x!c8GnzW)Lb<0qmU4Cxpyww!?=={q%)c%5DCD)XoIR{Jd zR%^^;t8PEGYi}Fbt-E2wyg+wU>&@a!MOJ=?d;9s|$ewcg!{hbm_V^y7Tak9<w`=;r&vX8eYq96%u~f!QN?>|-}3&f zL(#Bkk~G5X(16dXa9xoT%C0oo_4oqVyS4`1b!DbDtMo5x?tv!Jv&Po?RL4GUnl`Z$ za2`jTSH3!k;;1WXsKIoG{9?6B8(De&*{y)--gH)12-$0}QK>rx5jcU5OiXauX={Db z{Pa6gQd(Z#fw577RrGkwtuuGRS2jv4TUr`ktI;w}P&=p7M?|m2_y)2CMJ-|MwU_nh zjcG2YwWS9zn~S{{5js)^kG_KROdfX%M4O=WGN{Y?dNUvPk%og* zeFLV5k;H!Y8&*EO!7Djk)0-0__F#;<;}lfm)gqwFvETTGmgj7c&LHPM z^DZ1;Qs@w;ch&&eq}v5I*FFJ(DD33e+k3d!+kg7%f)TP~(#g)(Y>lpO^9pt_*9_MV zZScrhHIYaN(o6DK@<6Sal;!_k$=&dPu7T5^6*5^pz4g!QRNr~NcG{DWP_fWcoUSw7 zuIpDP6+GH6d21|r4f)N7ezX;(99YdY?M0z-sCo%!p4&lem)`(bi$n)9wm+Mw-o5{f zWW%rhF~iMwPqX046OdWf_MOmZ z0Cz`I9B>!3$=!{_;Bzf#OgxWC2nNJZI>6@e$gtNnS71;MlMM5< zbVs@i?14azbEFXPid^T-hzw>BnJ}BxYSvN`2*3rzG^mst!V{6CWY`QY34E3}BVf=O z6LByZw#nTCYR?w}P^<;k0tt7Ja>CKD)oM^{A(KV&q&R+r0N=>4K(SarLLej(iG>7X z!56X-C?b)FK%x<7G#s>miz0YpniS3xEtNyeVo(4PLkKFF!{A6tIFnN3ulh5EVNi&ZuB8`B>Fz9fa zB?f?FF?bA|h@+w5Xc`_zXJN5u8k6-ElnYNJrtuhn90~-t;D9(-CcpsjfF+zj$Kl{u zBpnB*qiF;V!e<9s*)D+byjjHrW}ezWD;0(0vwAXV&PZ@3(Sj- z0aK#k&=?k)fW}x7XP}r2k|STprGdlA;nLUuLcn9sbjS%O*?G8-VQ35Fmllr@nwSMT zkYR2dUYPVthc|}{c!_CpHc>bn9*0Ncu{ab8%pCK@$OjOLKqbmCQAi8SEUtW5NMJD_ zu{60(L4X+#uojZN5TJ?qLT^4lgbb6X1eJTv$Qx=sJ1EW^5oi%1SNuoKdjX-dZ?jV% zgfr6xh0e&9L}Sbb5z)c{=1d^aZ?=mONaL{qaDIOj)TegNKMWR=#jr%;7%Vt|VPQa; z(HJ<5hyvgMfCB&~5r@X3@ZX|~_$;x6CIsx*V5ML+pnztofv%XL((GGnNgyES2?@?^ z6bg>C^hTmdNF)hk2}feV2N>etFA+^ZqKSAM0nWhSKuOb(1UTK&5)ZdTvMd<@9nWIo zW+nZZ!2hyD6qbaxBw=yimS~NTFI=An)f(~thJDuHtCbFiVD2rS|1a2k^j+o&-Fx znRsMw2Tyy-^tDbD`LPcId1qe}2i{Z#&QuWuVzE?yDM<5e!okLQVi$LZc?0v6bQW3Y zmf5y~O^d`1o5c2fuKZ{Knc1-dOsIq-4ur~gtiC%m4L~D;3&qZRMKgmL5HQhft5jQO z`-^SM@#*Pl%;fZRE;=Di1Ik<&bMZz)!=B94jjv?MmUQ~gtSlu+J6m_I+3AEeAO^(6 MVI8GpO+ftr0oA05c>n+a diff --git a/applications/external/rc2014_coleco/icons/ColecoJoystick_33x33.png b/applications/external/rc2014_coleco/icons/ColecoJoystick_33x33.png deleted file mode 100644 index de4c574bc566ce45a127b5a8cd45f2a6e36e165e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/applications/external/rc2014_coleco/icons/ColecoJoystick_hvr_33x33.png b/applications/external/rc2014_coleco/icons/ColecoJoystick_hvr_33x33.png deleted file mode 100644 index fd653bfaf6567a37c890658371f6eb1f81c03b28..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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+ diff --git a/applications/external/rc2014_coleco/icons/ColecoPound_hvr_17x17.png b/applications/external/rc2014_coleco/icons/ColecoPound_hvr_17x17.png deleted file mode 100644 index 784f3687c51039ae130df62e602bfc0c24c158f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/applications/external/rc2014_coleco/icons/ColecoStar_17x17.png b/applications/external/rc2014_coleco/icons/ColecoStar_17x17.png deleted file mode 100644 index 3031c0baf46e20b92df9f208300532c59d2bcb70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/applications/external/rc2014_coleco/icons/ColecoStar_hvr_17x17.png b/applications/external/rc2014_coleco/icons/ColecoStar_hvr_17x17.png deleted file mode 100644 index 5469229719694c3bbe03d59c13c8d8f6f33bf7a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/applications/external/rc2014_coleco/interface/flipper-coleco.brd b/applications/external/rc2014_coleco/interface/flipper-coleco.brd deleted file mode 100644 index 47ed27322..000000000 --- a/applications/external/rc2014_coleco/interface/flipper-coleco.brd +++ /dev/null @@ -1,2554 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -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/external/rc2014_coleco/interface/flipper-coleco.sch b/applications/external/rc2014_coleco/interface/flipper-coleco.sch deleted file mode 100644 index c29acd315..000000000 --- a/applications/external/rc2014_coleco/interface/flipper-coleco.sch +++ /dev/null @@ -1,5482 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<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/external/reversi/LICENSE b/applications/external/reversi/LICENSE deleted file mode 100644 index 70a4dd1b3..000000000 --- a/applications/external/reversi/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Eugene Kirzhanov - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/applications/external/reversi/application.fam b/applications/external/reversi/application.fam deleted file mode 100644 index 87091e91a..000000000 --- a/applications/external/reversi/application.fam +++ /dev/null @@ -1,18 +0,0 @@ -App( - appid="reversi", - name="Reversi", - apptype=FlipperAppType.EXTERNAL, - entry_point="game_reversi_app", - cdefines=["APP_GAME_REVERSI"], - requires=[ - "gui", - ], - stack_size=1 * 1024, - fap_icon="game_reversi.png", - fap_category="Games", - fap_icon_assets_symbol="game_reversi", - fap_author="@dimat", - fap_weburl="https://github.com/zyuhel/flipperzero-racegame", - fap_version="1.1", - fap_description="Reversi game, the game controls should be intuitive. Longs press on OK opens the menu to start a new game.", -) diff --git a/applications/external/reversi/game_reversi.c b/applications/external/reversi/game_reversi.c deleted file mode 100644 index 407f80f8b..000000000 --- a/applications/external/reversi/game_reversi.c +++ /dev/null @@ -1,351 +0,0 @@ -// Game "Reversi" for Flipper Zero -// Copyright 2023 Dmitry Matyukhin - -#include -#include -#include -#include -#include -#include "reversi.h" - -#define FRAME_LEFT 3 -#define FRAME_TOP 3 -#define FRAME_CELL_SIZE 7 - -#define SAVING_FILENAME APP_DATA_PATH("game_reversi.save") - -typedef enum { AppScreenGame, AppScreenMenu } AppScreen; - -typedef struct { - GameState game; - AppScreen screen; - uint8_t selected_menu_item; - FuriMutex* mutex; -} AppState; - -#define MENU_ITEMS_COUNT 2 -static const char* popup_menu_strings[] = {"Resume", "New Game"}; - -static void draw_menu(Canvas* const canvas, const AppState* app_state); -static void gray_canvas(Canvas* const canvas); - -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); -} - -static void draw_callback(Canvas* const canvas, void* ctx) { - furi_assert(ctx); - const AppState* app_state = ctx; - furi_mutex_acquire(app_state->mutex, FuriWaitForever); - - const GameState* game_state = &app_state->game; - - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - - for(uint8_t i = 0; i <= BOARD_SIZE; i++) { - canvas_draw_line( - canvas, - FRAME_LEFT + FRAME_CELL_SIZE * i, - FRAME_TOP, - FRAME_LEFT + FRAME_CELL_SIZE * i, - FRAME_TOP + FRAME_CELL_SIZE * BOARD_SIZE); - canvas_draw_line( - canvas, - FRAME_LEFT, - FRAME_TOP + FRAME_CELL_SIZE * i, - FRAME_LEFT + FRAME_CELL_SIZE * BOARD_SIZE, - FRAME_TOP + FRAME_CELL_SIZE * i); - } - // - // draw cursor - canvas_set_color(canvas, ColorWhite); - canvas_draw_frame( - canvas, - FRAME_LEFT + FRAME_CELL_SIZE * game_state->cursor_x, - FRAME_TOP + FRAME_CELL_SIZE * game_state->cursor_y, - FRAME_CELL_SIZE + 1, - FRAME_CELL_SIZE + 1); - - canvas_set_color(canvas, ColorBlack); - // draw pieces - int blacks = 0, whites = 0; - const int radius = FRAME_CELL_SIZE >> 1; - for(uint8_t i = 0; i < BOARD_SIZE; i++) { - for(uint8_t j = 0; j < BOARD_SIZE; j++) { - if(!game_state->board[i][j]) { - continue; - } - if(game_state->board[i][j] == BLACK) { - canvas_draw_disc( - canvas, - FRAME_LEFT + FRAME_CELL_SIZE * i + radius + 1, - FRAME_TOP + FRAME_CELL_SIZE * j + radius + 1, - radius); - blacks++; - } else { - canvas_draw_circle( - canvas, - FRAME_LEFT + FRAME_CELL_SIZE * i + radius + 1, - FRAME_TOP + FRAME_CELL_SIZE * j + radius + 1, - radius); - whites++; - } - } - } - - canvas_set_font(canvas, FontPrimary); - // draw score - char score_str[25]; - memset(score_str, 0, sizeof(score_str)); - snprintf(score_str, sizeof(score_str), "%d - %d", whites, blacks); - - canvas_draw_str_aligned(canvas, 70, 3, AlignLeft, AlignTop, score_str); - - canvas_set_font(canvas, FontSecondary); - if(game_state->is_game_over) { - canvas_draw_str_aligned(canvas, 70, 20, AlignLeft, AlignTop, "Game over"); - - canvas_draw_str_aligned( - canvas, - 70, - FRAME_TOP + FRAME_CELL_SIZE * BOARD_SIZE, - AlignLeft, - AlignBottom, - "Press OK"); - - canvas_set_font(canvas, FontPrimary); - - if(whites == blacks) { - canvas_draw_str_aligned(canvas, 70, 30, AlignLeft, AlignTop, "DRAW"); - } else if( - ((game_state->human_color == WHITE) && whites > blacks) || - ((game_state->human_color == BLACK) && blacks > whites)) { - canvas_draw_str_aligned(canvas, 70, 30, AlignLeft, AlignTop, "YOU WIN"); - } else { - canvas_draw_str_aligned(canvas, 70, 30, AlignLeft, AlignTop, "YOU LOSE"); - } - } else if(game_state->current_player == game_state->human_color) { - canvas_draw_str_aligned(canvas, 70, 12, AlignLeft, AlignTop, "Your turn"); - } else { - canvas_draw_str_aligned(canvas, 70, 12, AlignLeft, AlignTop, "Computer turn"); - } - - if(app_state->screen == AppScreenMenu) { - draw_menu(canvas, app_state); - } - - furi_mutex_release(app_state->mutex); -} - -static void draw_menu(Canvas* const canvas, const AppState* app_state) { - gray_canvas(canvas); - canvas_set_color(canvas, ColorWhite); - canvas_draw_rbox(canvas, 28, 16, 72, 32, 4); - canvas_set_color(canvas, ColorBlack); - canvas_draw_rframe(canvas, 28, 16, 72, 32, 4); - - for(int i = 0; i < MENU_ITEMS_COUNT; i++) { - if(i == app_state->selected_menu_item) { - canvas_set_color(canvas, ColorBlack); - canvas_draw_box(canvas, 34, 20 + 12 * i, 60, 12); - } - - canvas_set_color(canvas, i == app_state->selected_menu_item ? ColorWhite : ColorBlack); - canvas_draw_str_aligned( - canvas, 64, 26 + 12 * i, AlignCenter, AlignCenter, popup_menu_strings[i]); - } -} - -static void gray_canvas(Canvas* const canvas) { - canvas_set_color(canvas, ColorWhite); - for(int x = 0; x < 128; x += 2) { - for(int y = 0; y < 64; y++) { - canvas_draw_dot(canvas, x + (y % 2 == 1 ? 0 : 1), y); - } - } -} - -bool load_game(GameState* game_state) { - Storage* storage = furi_record_open(RECORD_STORAGE); - storage_common_migrate(storage, EXT_PATH("apps/Games/game_reversi.save"), SAVING_FILENAME); - - 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, game_state, sizeof(GameState)); - } - storage_file_close(file); - storage_file_free(file); - - furi_record_close(RECORD_STORAGE); - - return bytes_readed == sizeof(GameState); -} - -void save_game(const GameState* game_state) { - Storage* storage = furi_record_open(RECORD_STORAGE); - - File* file = storage_file_alloc(storage); - if(storage_file_open(file, SAVING_FILENAME, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { - storage_file_write(file, game_state, sizeof(GameState)); - } - storage_file_close(file); - storage_file_free(file); - - furi_record_close(RECORD_STORAGE); -} - -bool handle_key_game(GameState* game_state, InputKey key) { - switch(key) { - case InputKeyBack: - save_game(game_state); - return false; - break; - case InputKeyOk: - if(game_state->is_game_over) { - init_game(game_state); - save_game(game_state); - } else { - human_move(game_state); - } - break; - case InputKeyUp: - if(game_state->cursor_y > 0) { - game_state->cursor_y--; - } else { - game_state->cursor_y = BOARD_SIZE - 1; - } - break; - case InputKeyDown: - if(game_state->cursor_y < BOARD_SIZE - 1) { - game_state->cursor_y++; - } else { - game_state->cursor_y = 0; - } - break; - case InputKeyLeft: - if(game_state->cursor_x > 0) { - game_state->cursor_x--; - } else { - game_state->cursor_x = BOARD_SIZE - 1; - } - break; - case InputKeyRight: - if(game_state->cursor_x < BOARD_SIZE - 1) { - game_state->cursor_x++; - } else { - game_state->cursor_x = 0; - } - break; - default: - break; - } - return true; -} - -bool handle_key_menu(AppState* app_state, InputKey key) { - switch(key) { - case InputKeyUp: - if(app_state->selected_menu_item > 0) { - app_state->selected_menu_item--; - } - break; - case InputKeyDown: - if(app_state->selected_menu_item < MENU_ITEMS_COUNT - 1) { - app_state->selected_menu_item++; - } - break; - case InputKeyOk: - if(app_state->selected_menu_item == 1) { - // new game - init_game(&app_state->game); - save_game(&app_state->game); - } - app_state->screen = AppScreenGame; - break; - default: - break; - } - return true; -} - -// returns `true` if the event loop should keep going -bool handle_key(AppState* app_state, InputKey key) { - GameState* game_state = &app_state->game; - - switch(app_state->screen) { - case AppScreenGame: - return handle_key_game(game_state, key); - break; - case AppScreenMenu: - return handle_key_menu(app_state, key); - break; - } - return true; -} - -int32_t game_reversi_app() { - AppState app_state; - app_state.screen = AppScreenGame; - if(!load_game(&app_state.game)) { - init_game(&app_state.game); - } - - app_state.mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!app_state.mutex) { - return 255; - } - InputEvent input; - 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, &app_state); - 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); - bool is_finished = false; - - while(!is_finished) { - // check if it's computer's turn - if(!app_state.game.is_game_over && - (app_state.game.current_player != app_state.game.human_color)) { - computer_move(&app_state.game); - } - FuriStatus event_status = furi_message_queue_get(event_queue, &input, 100); - if(event_status == FuriStatusOk) { - // handle only press event, ignore repeat/release events - - if(input.type == InputTypeLong && input.key == InputKeyOk && - app_state.screen == AppScreenGame) { - furi_mutex_acquire(app_state.mutex, FuriWaitForever); - app_state.selected_menu_item = 0; - app_state.screen = AppScreenMenu; - view_port_update(view_port); - furi_mutex_release(app_state.mutex); - continue; - } - if(input.type != InputTypePress) continue; - - furi_mutex_acquire(app_state.mutex, FuriWaitForever); - is_finished = !handle_key(&app_state, input.key); - view_port_update(view_port); - furi_mutex_release(app_state.mutex); - } - view_port_update(view_port); - } - - 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_state.mutex); - - return 0; -} diff --git a/applications/external/reversi/game_reversi.png b/applications/external/reversi/game_reversi.png deleted file mode 100644 index 3a321471b96c16186e80b43c8659d1b26b5d5bd5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4v7|ftIx;Y9?C1WI$O`0Jq(*qA z`T8 zhmtY(m4zHeNhYV)vz~NWa`wf$W0ST$_|x(0y3*^~dgFLrS=B#57F+v3HhQ}HxvX= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE && board[r][c] == opponent) { - int k = 2; - while(true) { - r += i; - c += j; - if(r < 0 || r >= BOARD_SIZE || c < 0 || c >= BOARD_SIZE) break; - if(board[r][c] == player) return true; - if(board[r][c] == 0) break; - k++; - } - } - } - } - return false; -} - -// Check if the game is over by checking if there are no more moves left for -// either player -bool is_game_over(int8_t board[BOARD_SIZE][BOARD_SIZE]) { - for(int i = 0; i < BOARD_SIZE; i++) { - for(int j = 0; j < BOARD_SIZE; j++) { - if(is_legal_move(board, i, j, BLACK) || is_legal_move(board, i, j, WHITE)) { - return false; - } - } - } - return true; -} - -bool has_legal_moves(int8_t board[BOARD_SIZE][BOARD_SIZE], int8_t player_color) { - for(int i = 0; i < BOARD_SIZE; i++) { - for(int j = 0; j < BOARD_SIZE; j++) { - if(is_legal_move(board, i, j, player_color)) { - return true; - } - } - } - return false; -} - -// Calculate the heuristic value of the current board. This function can -// be replaced with a more complex evaluation function that takes into -// account factors such as mobility, piece square tables, etc. -int heuristic(int8_t board[BOARD_SIZE][BOARD_SIZE]) { - int white = 0, black = 0; - for(int i = 0; i < BOARD_SIZE; i++) { - for(int j = 0; j < BOARD_SIZE; j++) { - if(board[i][j] == 1) white++; - if(board[i][j] == -1) black++; - } - } - return white - black; -} - -// Make a move on the board and capture any opponent pieces -void make_move(GameState* state, int x, int y, int player) { - state->board[x][y] = player; - int opponent = -player; - for(int i = -1; i <= 1; i++) { - for(int j = -1; j <= 1; j++) { - if(i == 0 && j == 0) continue; - int r = x + i, c = y + j; - if(r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE && - state->board[r][c] == opponent) { - int k = 2; - while(true) { - r += i; - c += j; - if(r < 0 || r >= BOARD_SIZE || c < 0 || c >= BOARD_SIZE) break; - if(state->board[r][c] == player) { - r -= i; - c -= j; - while(r != x || c != y) { - state->board[r][c] = player; - r -= i; - c -= j; - } - break; - } - if(state->board[r][c] == 0) break; - k++; - } - } - } - } - state->is_game_over = is_game_over(state->board); -} - -void init_game(GameState* state) { - for(int i = 0; i < BOARD_SIZE; i++) { - for(int j = 0; j < BOARD_SIZE; j++) { - state->board[i][j] = 0; - } - } - - // Place the initial pieces - int mid = BOARD_SIZE / 2; - state->board[mid - 1][mid - 1] = WHITE; - state->board[mid][mid] = WHITE; - state->board[mid - 1][mid] = BLACK; - state->board[mid][mid - 1] = BLACK; - - state->cursor_x = mid - 1; - state->cursor_y = mid + 1; - - // Set up turn order - state->human_color = WHITE; - state->current_player = WHITE; - - state->is_game_over = false; -} - -void human_move(GameState* game_state) { - if(game_state->current_player != game_state->human_color) { - return; - } - - if(is_legal_move( - game_state->board, - game_state->cursor_x, - game_state->cursor_y, - game_state->current_player)) { - make_move( - game_state, game_state->cursor_x, game_state->cursor_y, game_state->current_player); - game_state->current_player = -game_state->current_player; - } -} - -void computer_move(GameState* game_state) { - if(game_state->current_player == game_state->human_color) { - return; - } - int best_row = -1, best_col = -1, best_score = -1000000; - for(int i = 0; i < BOARD_SIZE; i++) { - for(int j = 0; j < BOARD_SIZE; j++) { - if(!is_legal_move(game_state->board, i, j, game_state->current_player)) { - continue; - } - int score = heuristic(game_state->board); - if(score > best_score) { - best_score = score; - best_row = i; - best_col = j; - } - } - } - if(best_row != -1) { - make_move(game_state, best_row, best_col, game_state->current_player); - } - if(has_legal_moves(game_state->board, game_state->human_color)) { - game_state->current_player = -game_state->current_player; - } -} diff --git a/applications/external/reversi/reversi.h b/applications/external/reversi/reversi.h deleted file mode 100644 index ee4588838..000000000 --- a/applications/external/reversi/reversi.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include -#include - -#define BLACK 1 -#define WHITE -1 -#define BOARD_SIZE 8 - -typedef struct { - int8_t board[BOARD_SIZE][BOARD_SIZE]; - int8_t current_player; - int8_t human_color; - uint8_t cursor_x; - uint8_t cursor_y; - uint8_t is_game_over; -} GameState; - -void init_game(GameState* state); -void computer_move(GameState* game_state); -void human_move(GameState* game_state); diff --git a/applications/external/swd_probe/LICENSE.txt b/applications/external/swd_probe/LICENSE.txt deleted file mode 100644 index f288702d2..000000000 --- a/applications/external/swd_probe/LICENSE.txt +++ /dev/null @@ -1,674 +0,0 @@ - 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/external/swd_probe/adi.c b/applications/external/swd_probe/adi.c deleted file mode 100644 index 95456fcd0..000000000 --- a/applications/external/swd_probe/adi.c +++ /dev/null @@ -1,1016 +0,0 @@ - -#include -#include - -#include "adi.h" -#include "swd_probe_app.h" - -/* https://github.com/openocd-org/openocd/blob/master/src/target/arm_adi_v5.c */ - -/* -static const char* class_description[16] = { - [0x0] = "Generic verification component", - [0x1] = "(ROM Table)", - [0x2] = "Reserved", - [0x3] = "Reserved", - [0x4] = "Reserved", - [0x5] = "Reserved", - [0x6] = "Reserved", - [0x7] = "Reserved", - [0x8] = "Reserved", - [0x9] = "CoreSight component", - [0xA] = "Reserved", - [0xB] = "Peripheral Test Block", - [0xC] = "Reserved", - [0xD] = "OptimoDE DESS", - [0xE] = "Generic IP component", - [0xF] = "CoreLink, PrimeCell or System component", -}; -*/ - -static const struct { - uint32_t arch_id; - const char* description; -} class0x9_devarch[] = { - /* keep same unsorted order as in ARM IHI0029E */ - {ARCH_ID(ARM_ID, 0x0A00), "RAS architecture"}, - {ARCH_ID(ARM_ID, 0x1A01), "Instrumentation Trace Macrocell (ITM) architecture"}, - {ARCH_ID(ARM_ID, 0x1A02), "DWT architecture"}, - {ARCH_ID(ARM_ID, 0x1A03), "Flash Patch and Breakpoint unit (FPB) architecture"}, - {ARCH_ID(ARM_ID, 0x2A04), "Processor debug architecture (ARMv8-M)"}, - {ARCH_ID(ARM_ID, 0x6A05), "Processor debug architecture (ARMv8-R)"}, - {ARCH_ID(ARM_ID, 0x0A10), "PC sample-based profiling"}, - {ARCH_ID(ARM_ID, 0x4A13), "Embedded Trace Macrocell (ETM) architecture"}, - {ARCH_ID(ARM_ID, 0x1A14), "Cross Trigger Interface (CTI) architecture"}, - {ARCH_ID(ARM_ID, 0x6A15), "Processor debug architecture (v8.0-A)"}, - {ARCH_ID(ARM_ID, 0x7A15), "Processor debug architecture (v8.1-A)"}, - {ARCH_ID(ARM_ID, 0x8A15), "Processor debug architecture (v8.2-A)"}, - {ARCH_ID(ARM_ID, 0x2A16), "Processor Performance Monitor (PMU) architecture"}, - {ARCH_ID(ARM_ID, 0x0A17), "Memory Access Port v2 architecture"}, - {ARCH_ID(ARM_ID, 0x0A27), "JTAG Access Port v2 architecture"}, - {ARCH_ID(ARM_ID, 0x0A31), "Basic trace router"}, - {ARCH_ID(ARM_ID, 0x0A37), "Power requestor"}, - {ARCH_ID(ARM_ID, 0x0A47), "Unknown Access Port v2 architecture"}, - {ARCH_ID(ARM_ID, 0x0A50), "HSSTP architecture"}, - {ARCH_ID(ARM_ID, 0x0A63), "System Trace Macrocell (STM) architecture"}, - {ARCH_ID(ARM_ID, 0x0A75), "CoreSight ELA architecture"}, - {ARCH_ID(ARM_ID, 0x0AF7), "CoreSight ROM architecture"}, -}; - -/* Part number interpretations are from Cortex - * core specs, the CoreSight components TRM - * (ARM DDI 0314H), CoreSight System Design - * Guide (ARM DGI 0012D) and ETM specs; also - * from chip observation (e.g. TI SDTI). - */ - -static const struct dap_part_nums { - uint16_t designer_id; - uint16_t part_num; - const char* type; - const char* full; -} dap_part_nums[] = { - { - ARM_ID, - 0x000, - "Cortex-M3 SCS", - "(System Control Space)", - }, - { - ARM_ID, - 0x001, - "Cortex-M3 ITM", - "(Instrumentation Trace Module)", - }, - { - ARM_ID, - 0x002, - "Cortex-M3 DWT", - "(Data Watchpoint and Trace)", - }, - { - ARM_ID, - 0x003, - "Cortex-M3 FPB", - "(Flash Patch and Breakpoint)", - }, - { - ARM_ID, - 0x008, - "Cortex-M0 SCS", - "(System Control Space)", - }, - { - ARM_ID, - 0x00a, - "Cortex-M0 DWT", - "(Data Watchpoint and Trace)", - }, - { - ARM_ID, - 0x00b, - "Cortex-M0 BPU", - "(Breakpoint Unit)", - }, - { - ARM_ID, - 0x00c, - "Cortex-M4 SCS", - "(System Control Space)", - }, - { - ARM_ID, - 0x00d, - "CoreSight ETM11", - "(Embedded Trace)", - }, - { - ARM_ID, - 0x00e, - "Cortex-M7 FPB", - "(Flash Patch and Breakpoint)", - }, - { - ARM_ID, - 0x193, - "SoC-600 TSGEN", - "(Timestamp Generator)", - }, - { - ARM_ID, - 0x470, - "Cortex-M1 ROM", - "(ROM Table)", - }, - { - ARM_ID, - 0x471, - "Cortex-M0 ROM", - "(ROM Table)", - }, - { - ARM_ID, - 0x490, - "Cortex-A15 GIC", - "(Generic Interrupt Controller)", - }, - { - ARM_ID, - 0x492, - "Cortex-R52 GICD", - "(Distributor)", - }, - { - ARM_ID, - 0x493, - "Cortex-R52 GICR", - "(Redistributor)", - }, - { - ARM_ID, - 0x4a1, - "Cortex-A53 ROM", - "(v8 Memory Map ROM Table)", - }, - { - ARM_ID, - 0x4a2, - "Cortex-A57 ROM", - "(ROM Table)", - }, - { - ARM_ID, - 0x4a3, - "Cortex-A53 ROM", - "(v7 Memory Map ROM Table)", - }, - { - ARM_ID, - 0x4a4, - "Cortex-A72 ROM", - "(ROM Table)", - }, - { - ARM_ID, - 0x4a9, - "Cortex-A9 ROM", - "(ROM Table)", - }, - { - ARM_ID, - 0x4aa, - "Cortex-A35 ROM", - "(v8 Memory Map ROM Table)", - }, - { - ARM_ID, - 0x4af, - "Cortex-A15 ROM", - "(ROM Table)", - }, - { - ARM_ID, - 0x4b5, - "Cortex-R5 ROM", - "(ROM Table)", - }, - { - ARM_ID, - 0x4b8, - "Cortex-R52 ROM", - "(ROM Table)", - }, - { - ARM_ID, - 0x4c0, - "Cortex-M0+ ROM", - "(ROM Table)", - }, - { - ARM_ID, - 0x4c3, - "Cortex-M3 ROM", - "(ROM Table)", - }, - { - ARM_ID, - 0x4c4, - "Cortex-M4 ROM", - "(ROM Table)", - }, - { - ARM_ID, - 0x4c7, - "Cortex-M7 PPB ROM", - "(Private Peripheral Bus ROM Table)", - }, - { - ARM_ID, - 0x4c8, - "Cortex-M7 ROM", - "(ROM Table)", - }, - { - ARM_ID, - 0x4e0, - "Cortex-A35 ROM", - "(v7 Memory Map ROM Table)", - }, - { - ARM_ID, - 0x4e4, - "Cortex-A76 ROM", - "(ROM Table)", - }, - { - ARM_ID, - 0x906, - "CoreSight CTI", - "(Cross Trigger)", - }, - { - ARM_ID, - 0x907, - "CoreSight ETB", - "(Trace Buffer)", - }, - { - ARM_ID, - 0x908, - "CoreSight CSTF", - "(Trace Funnel)", - }, - { - ARM_ID, - 0x909, - "CoreSight ATBR", - "(Advanced Trace Bus Replicator)", - }, - { - ARM_ID, - 0x910, - "CoreSight ETM9", - "(Embedded Trace)", - }, - { - ARM_ID, - 0x912, - "CoreSight TPIU", - "(Trace Port Interface Unit)", - }, - { - ARM_ID, - 0x913, - "CoreSight ITM", - "(Instrumentation Trace Macrocell)", - }, - { - ARM_ID, - 0x914, - "CoreSight SWO", - "(Single Wire Output)", - }, - { - ARM_ID, - 0x917, - "CoreSight HTM", - "(AHB Trace Macrocell)", - }, - { - ARM_ID, - 0x920, - "CoreSight ETM11", - "(Embedded Trace)", - }, - { - ARM_ID, - 0x921, - "Cortex-A8 ETM", - "(Embedded Trace)", - }, - { - ARM_ID, - 0x922, - "Cortex-A8 CTI", - "(Cross Trigger)", - }, - { - ARM_ID, - 0x923, - "Cortex-M3 TPIU", - "(Trace Port Interface Unit)", - }, - { - ARM_ID, - 0x924, - "Cortex-M3 ETM", - "(Embedded Trace)", - }, - { - ARM_ID, - 0x925, - "Cortex-M4 ETM", - "(Embedded Trace)", - }, - { - ARM_ID, - 0x930, - "Cortex-R4 ETM", - "(Embedded Trace)", - }, - { - ARM_ID, - 0x931, - "Cortex-R5 ETM", - "(Embedded Trace)", - }, - { - ARM_ID, - 0x932, - "CoreSight MTB-M0+", - "(Micro Trace Buffer)", - }, - { - ARM_ID, - 0x941, - "CoreSight TPIU-Lite", - "(Trace Port Interface Unit)", - }, - { - ARM_ID, - 0x950, - "Cortex-A9 PTM", - "(Program Trace Macrocell)", - }, - { - ARM_ID, - 0x955, - "Cortex-A5 ETM", - "(Embedded Trace)", - }, - { - ARM_ID, - 0x95a, - "Cortex-A72 ETM", - "(Embedded Trace)", - }, - { - ARM_ID, - 0x95b, - "Cortex-A17 PTM", - "(Program Trace Macrocell)", - }, - { - ARM_ID, - 0x95d, - "Cortex-A53 ETM", - "(Embedded Trace)", - }, - { - ARM_ID, - 0x95e, - "Cortex-A57 ETM", - "(Embedded Trace)", - }, - { - ARM_ID, - 0x95f, - "Cortex-A15 PTM", - "(Program Trace Macrocell)", - }, - { - ARM_ID, - 0x961, - "CoreSight TMC", - "(Trace Memory Controller)", - }, - { - ARM_ID, - 0x962, - "CoreSight STM", - "(System Trace Macrocell)", - }, - { - ARM_ID, - 0x975, - "Cortex-M7 ETM", - "(Embedded Trace)", - }, - { - ARM_ID, - 0x9a0, - "CoreSight PMU", - "(Performance Monitoring Unit)", - }, - { - ARM_ID, - 0x9a1, - "Cortex-M4 TPIU", - "(Trace Port Interface Unit)", - }, - { - ARM_ID, - 0x9a4, - "CoreSight GPR", - "(Granular Power Requester)", - }, - { - ARM_ID, - 0x9a5, - "Cortex-A5 PMU", - "(Performance Monitor Unit)", - }, - { - ARM_ID, - 0x9a7, - "Cortex-A7 PMU", - "(Performance Monitor Unit)", - }, - { - ARM_ID, - 0x9a8, - "Cortex-A53 CTI", - "(Cross Trigger)", - }, - { - ARM_ID, - 0x9a9, - "Cortex-M7 TPIU", - "(Trace Port Interface Unit)", - }, - { - ARM_ID, - 0x9ae, - "Cortex-A17 PMU", - "(Performance Monitor Unit)", - }, - { - ARM_ID, - 0x9af, - "Cortex-A15 PMU", - "(Performance Monitor Unit)", - }, - { - ARM_ID, - 0x9b6, - "Cortex-R52 PMU/CTI/ETM", - "(Performance Monitor Unit/Cross Trigger/ETM)", - }, - { - ARM_ID, - 0x9b7, - "Cortex-R7 PMU", - "(Performance Monitor Unit)", - }, - { - ARM_ID, - 0x9d3, - "Cortex-A53 PMU", - "(Performance Monitor Unit)", - }, - { - ARM_ID, - 0x9d7, - "Cortex-A57 PMU", - "(Performance Monitor Unit)", - }, - { - ARM_ID, - 0x9d8, - "Cortex-A72 PMU", - "(Performance Monitor Unit)", - }, - { - ARM_ID, - 0x9da, - "Cortex-A35 PMU/CTI/ETM", - "(Performance Monitor Unit/Cross Trigger/ETM)", - }, - { - ARM_ID, - 0x9e2, - "SoC-600 APB-AP", - "(APB4 Memory Access Port)", - }, - { - ARM_ID, - 0x9e3, - "SoC-600 AHB-AP", - "(AHB5 Memory Access Port)", - }, - { - ARM_ID, - 0x9e4, - "SoC-600 AXI-AP", - "(AXI Memory Access Port)", - }, - { - ARM_ID, - 0x9e5, - "SoC-600 APv1 Adapter", - "(Access Port v1 Adapter)", - }, - { - ARM_ID, - 0x9e6, - "SoC-600 JTAG-AP", - "(JTAG Access Port)", - }, - { - ARM_ID, - 0x9e7, - "SoC-600 TPIU", - "(Trace Port Interface Unit)", - }, - { - ARM_ID, - 0x9e8, - "SoC-600 TMC ETR/ETS", - "(Embedded Trace Router/Streamer)", - }, - { - ARM_ID, - 0x9e9, - "SoC-600 TMC ETB", - "(Embedded Trace Buffer)", - }, - { - ARM_ID, - 0x9ea, - "SoC-600 TMC ETF", - "(Embedded Trace FIFO)", - }, - { - ARM_ID, - 0x9eb, - "SoC-600 ATB Funnel", - "(Trace Funnel)", - }, - { - ARM_ID, - 0x9ec, - "SoC-600 ATB Replicator", - "(Trace Replicator)", - }, - { - ARM_ID, - 0x9ed, - "SoC-600 CTI", - "(Cross Trigger)", - }, - { - ARM_ID, - 0x9ee, - "SoC-600 CATU", - "(Address Translation Unit)", - }, - { - ARM_ID, - 0xc05, - "Cortex-A5 Debug", - "(Debug Unit)", - }, - { - ARM_ID, - 0xc07, - "Cortex-A7 Debug", - "(Debug Unit)", - }, - { - ARM_ID, - 0xc08, - "Cortex-A8 Debug", - "(Debug Unit)", - }, - { - ARM_ID, - 0xc09, - "Cortex-A9 Debug", - "(Debug Unit)", - }, - { - ARM_ID, - 0xc0e, - "Cortex-A17 Debug", - "(Debug Unit)", - }, - { - ARM_ID, - 0xc0f, - "Cortex-A15 Debug", - "(Debug Unit)", - }, - { - ARM_ID, - 0xc14, - "Cortex-R4 Debug", - "(Debug Unit)", - }, - { - ARM_ID, - 0xc15, - "Cortex-R5 Debug", - "(Debug Unit)", - }, - { - ARM_ID, - 0xc17, - "Cortex-R7 Debug", - "(Debug Unit)", - }, - { - ARM_ID, - 0xd03, - "Cortex-A53 Debug", - "(Debug Unit)", - }, - { - ARM_ID, - 0xd04, - "Cortex-A35 Debug", - "(Debug Unit)", - }, - { - ARM_ID, - 0xd07, - "Cortex-A57 Debug", - "(Debug Unit)", - }, - { - ARM_ID, - 0xd08, - "Cortex-A72 Debug", - "(Debug Unit)", - }, - { - ARM_ID, - 0xd0b, - "Cortex-A76 Debug", - "(Debug Unit)", - }, - { - ARM_ID, - 0xd0c, - "Neoverse N1", - "(Debug Unit)", - }, - { - ARM_ID, - 0xd13, - "Cortex-R52 Debug", - "(Debug Unit)", - }, - { - ARM_ID, - 0xd49, - "Neoverse N2", - "(Debug Unit)", - }, - { - 0x017, - 0x120, - "TI SDTI", - "(System Debug Trace Interface)", - }, /* from OMAP3 memmap */ - { - 0x017, - 0x343, - "TI DAPCTL", - "", - }, /* from OMAP3 memmap */ - {0x017, 0x9af, "MSP432 ROM", "(ROM Table)"}, - {0x01f, 0xcd0, "Atmel CPU with DSU", "(CPU)"}, - {0x041, 0x1db, "XMC4500 ROM", "(ROM Table)"}, - {0x041, 0x1df, "XMC4700/4800 ROM", "(ROM Table)"}, - {0x041, 0x1ed, "XMC1000 ROM", "(ROM Table)"}, - { - 0x065, - 0x000, - "SHARC+/Blackfin+", - "", - }, - { - 0x070, - 0x440, - "Qualcomm QDSS Component v1", - "(Qualcomm Designed CoreSight Component v1)", - }, - { - 0x0bf, - 0x100, - "Brahma-B53 Debug", - "(Debug Unit)", - }, - { - 0x0bf, - 0x9d3, - "Brahma-B53 PMU", - "(Performance Monitor Unit)", - }, - { - 0x0bf, - 0x4a1, - "Brahma-B53 ROM", - "(ROM Table)", - }, - { - 0x0bf, - 0x721, - "Brahma-B53 ROM", - "(ROM Table)", - }, - { - 0x1eb, - 0x181, - "Tegra 186 ROM", - "(ROM Table)", - }, - { - 0x1eb, - 0x202, - "Denver ETM", - "(Denver Embedded Trace)", - }, - { - 0x1eb, - 0x211, - "Tegra 210 ROM", - "(ROM Table)", - }, - { - 0x1eb, - 0x302, - "Denver Debug", - "(Debug Unit)", - }, - { - 0x1eb, - 0x402, - "Denver PMU", - "(Performance Monitor Unit)", - }, - {0x20, 0x410, "STM32F10 (med)", "(ROM Table)"}, - {0x20, 0x411, "STM32F2", "(ROM Table)"}, - {0x20, 0x412, "STM32F10 (low)", "(ROM Table)"}, - {0x20, 0x413, "STM32F40/41", "(ROM Table)"}, - {0x20, 0x414, "STM32F10 (high)", "(ROM Table)"}, - {0x20, 0x415, "STM32L47/48", "(ROM Table)"}, - {0x20, 0x416, "STM32L1xxx6/8/B", "(ROM Table)"}, - {0x20, 0x417, "STM32L05/06", "(ROM Table)"}, - {0x20, 0x418, "STM32F105xx/107", "(ROM Table)"}, - {0x20, 0x419, "STM32F42/43", "(ROM Table)"}, - {0x20, 0x420, "STM32F10 (med)", "(ROM Table)"}, - {0x20, 0x421, "STM32F446xx", "(ROM Table)"}, - {0x20, 0x422, "STM32FF358/02/03", "(ROM Table)"}, - {0x20, 0x423, "STM32F401xB/C", "(ROM Table)"}, - {0x20, 0x425, "STM32L031/41", "(ROM Table)"}, - {0x20, 0x427, "STM32L1xxxC", "(ROM Table)"}, - {0x20, 0x428, "STM32F10 (high)", "(ROM Table)"}, - {0x20, 0x429, "STM32L1xxx6A/8A/BA", "(ROM Table)"}, - {0x20, 0x430, "STM32F10 (xl)", "(ROM Table)"}, - {0x20, 0x431, "STM32F411xx", "(ROM Table)"}, - {0x20, 0x432, "STM32F373/8", "(ROM Table)"}, - {0x20, 0x433, "STM32F401xD/E", "(ROM Table)"}, - {0x20, 0x434, "STM32F469/79", "(ROM Table)"}, - {0x20, 0x435, "STM32L43/44", "(ROM Table)"}, - {0x20, 0x436, "STM32L1xxxD", "(ROM Table)"}, - {0x20, 0x437, "STM32L1xxxE", "(ROM Table)"}, - {0x20, 0x438, "STM32F303/34/28", "(ROM Table)"}, - {0x20, 0x439, "STM32F301/02/18 ", "(ROM Table)"}, - {0x20, 0x440, "STM32F03/5", "(ROM Table)"}, - {0x20, 0x441, "STM32F412xx", "(ROM Table)"}, - {0x20, 0x442, "STM32F03/9", "(ROM Table)"}, - {0x20, 0x444, "STM32F03xx4", "(ROM Table)"}, - {0x20, 0x445, "STM32F04/7", "(ROM Table)"}, - {0x20, 0x446, "STM32F302/03/98", "(ROM Table)"}, - {0x20, 0x447, "STM32L07/08", "(ROM Table)"}, - {0x20, 0x448, "STM32F070/1/2", "(ROM Table)"}, - {0x20, 0x449, "STM32F74/5", "(ROM Table)"}, - {0x20, 0x450, "STM32H74/5", "(ROM Table)"}, - {0x20, 0x451, "STM32F76/7", "(ROM Table)"}, - {0x20, 0x452, "STM32F72/3", "(ROM Table)"}, - {0x20, 0x457, "STM32L01/2", "(ROM Table)"}, - {0x20, 0x458, "STM32F410xx", "(ROM Table)"}, - {0x20, 0x460, "STM32G07/8", "(ROM Table)"}, - {0x20, 0x461, "STM32L496/A6", "(ROM Table)"}, - {0x20, 0x462, "STM32L45/46", "(ROM Table)"}, - {0x20, 0x463, "STM32F413/23", "(ROM Table)"}, - {0x20, 0x464, "STM32L412/22", "(ROM Table)"}, - {0x20, 0x466, "STM32G03/04", "(ROM Table)"}, - {0x20, 0x468, "STM32G431/41", "(ROM Table)"}, - {0x20, 0x469, "STM32G47/48", "(ROM Table)"}, - {0x20, 0x470, "STM32L4R/S", "(ROM Table)"}, - {0x20, 0x471, "STM32L4P5/Q5", "(ROM Table)"}, - {0x20, 0x479, "STM32G491xx", "(ROM Table)"}, - {0x20, 0x480, "STM32H7A/B", "(ROM Table)"}, - {0x20, 0x495, "STM32WB50/55", "(ROM Table)"}, - {0x20, 0x497, "STM32WLE5xx", "(ROM Table)"}}; - -const char* adi_devarch_desc(uint32_t devarch) { - if(!(devarch & ARM_CS_C9_DEVARCH_PRESENT)) { - return "not present"; - } - - for(unsigned int i = 0; i < ARRAY_SIZE(class0x9_devarch); i++) { - if((devarch & DEVARCH_ID_MASK) == class0x9_devarch[i].arch_id) { - return class0x9_devarch[i].description; - } - } - - return "unknown"; -} - -const struct dap_part_nums* adi_part_num(unsigned int des, unsigned int part) { - static char buf[32]; - static struct dap_part_nums unknown = { - .type = "Unrecognized", - .full = "", - }; - - for(unsigned int i = 0; i < ARRAY_SIZE(dap_part_nums); i++) { - if(dap_part_nums[i].designer_id == des && dap_part_nums[i].part_num == part) { - return &dap_part_nums[i]; - } - } - - snprintf(buf, sizeof(buf), "D:%x P:%x", des, part); - unknown.full = buf; - - return &unknown; -} - -bool adi_get_pidr(AppFSM* const ctx, uint32_t base, pidr_data_t* data) { - uint32_t pidrs[7]; - uint32_t offsets[] = {0xFE0, 0xFE4, 0xFE8, 0xFEC, 0xFD0, 0xFD4, 0xFD8, 0xFDC}; - - furi_mutex_acquire(ctx->swd_mutex, FuriWaitForever); - for(size_t pos = 0; pos < COUNT(pidrs); pos++) { - uint8_t ret = swd_read_memory(ctx, ctx->ap_pos, base + offsets[pos], &pidrs[pos]); - if(ret != 1) { - DBGS("Read failed"); - furi_mutex_release(ctx->swd_mutex); - return false; - } - } - furi_mutex_release(ctx->swd_mutex); - - data->designer = ((pidrs[4] & 0x0F) << 7) | ((pidrs[2] & 0x07) << 4) | - ((pidrs[1] >> 4) & 0x0F); - data->part = (pidrs[0] & 0xFF) | ((pidrs[1] & 0x0F) << 8); - data->revand = ((pidrs[3] >> 4) & 0x0F); - data->cmod = (pidrs[3] & 0x0F); - data->revision = ((pidrs[2] >> 4) & 0x0F); - data->size = ((pidrs[2] >> 4) & 0x0F); - - return true; -} - -bool adi_get_class(AppFSM* const ctx, uint32_t base, uint8_t* class) { - uint32_t cidrs[4]; - uint32_t offsets[] = {0xFF0, 0xFF4, 0xFF8, 0xFFC}; - - furi_mutex_acquire(ctx->swd_mutex, FuriWaitForever); - for(size_t pos = 0; pos < COUNT(cidrs); pos++) { - uint8_t ret = swd_read_memory(ctx, ctx->ap_pos, base + offsets[pos], &cidrs[pos]); - if(ret != 1) { - DBGS("Read failed"); - furi_mutex_release(ctx->swd_mutex); - return false; - } - } - furi_mutex_release(ctx->swd_mutex); - - if((cidrs[0] & 0xFF) != 0x0D) { - return false; - } - if((cidrs[1] & 0x0F) != 0x00) { - return false; - } - if((cidrs[2] & 0xFF) != 0x05) { - return false; - } - if((cidrs[3] & 0xFF) != 0xB1) { - return false; - } - - *class = ((cidrs[1] >> 4) & 0x0F); - - return true; -} - -const char* adi_romtable_type(AppFSM* const ctx, uint32_t base) { - pidr_data_t data; - - if(!adi_get_pidr(ctx, base, &data)) { - return "fail"; - } - const struct dap_part_nums* info = adi_part_num(data.designer, data.part); - - return info->type; -} - -const char* adi_romtable_full(AppFSM* const ctx, uint32_t base) { - pidr_data_t data; - - if(!adi_get_pidr(ctx, base, &data)) { - return "fail"; - } - const struct dap_part_nums* info = adi_part_num(data.designer, data.part); - - return info->full; -} - -uint32_t adi_romtable_entry_count(AppFSM* const ctx, uint32_t base) { - uint32_t count = 0; - uint32_t entry = 0; - - furi_mutex_acquire(ctx->swd_mutex, FuriWaitForever); - for(size_t pos = 0; pos < 960; pos++) { - uint8_t ret = 0; - for(int tries = 0; tries < 10 && ret != 1; tries++) { - ret = swd_read_memory(ctx, ctx->ap_pos, base + pos * 4, &entry); - } - if(ret != 1) { - DBGS("Read failed"); - break; - } - if(!(entry & 1)) { - break; - } - if(entry & 0x00000FFC) { - break; - } - count++; - } - furi_mutex_release(ctx->swd_mutex); - return count; -} - -uint32_t adi_romtable_get(AppFSM* const ctx, uint32_t base, uint32_t pos) { - uint32_t entry = 0; - - furi_mutex_acquire(ctx->swd_mutex, FuriWaitForever); - uint8_t ret = swd_read_memory(ctx, ctx->ap_pos, base + pos * 4, &entry); - if(ret != 1) { - DBGS("Read failed"); - furi_mutex_release(ctx->swd_mutex); - return 0; - } - furi_mutex_release(ctx->swd_mutex); - - return base + (entry & 0xFFFFF000); -} - -bool adi_is_romtable(AppFSM* const ctx, uint32_t base) { - uint8_t class = 0; - - if(!adi_get_class(ctx, base, &class)) { - return false; - } - - if(class != CIDR_CLASS_ROMTABLE) { - return false; - } - - return true; -} diff --git a/applications/external/swd_probe/adi.h b/applications/external/swd_probe/adi.h deleted file mode 100644 index bade7736a..000000000 --- a/applications/external/swd_probe/adi.h +++ /dev/null @@ -1,34 +0,0 @@ - -#ifndef __ADI_H__ -#define __ADI_H__ - -#include "swd_probe_app.h" - -#define ARM_ID 0x23B - -#define ARCH_ID(architect, archid) ((architect) << 21) | (archid) - -#define BIT(nr) (1UL << (nr)) -#define ARM_CS_C9_DEVARCH_PRESENT BIT(20) -#define ARM_CS_C9_DEVARCH_ARCHITECT_MASK (0xFFE00000) -#define ARM_CS_C9_DEVARCH_ARCHID_MASK (0x0000FFFF) -#define DEVARCH_ID_MASK (ARM_CS_C9_DEVARCH_ARCHITECT_MASK | ARM_CS_C9_DEVARCH_ARCHID_MASK) - -typedef struct { - uint16_t designer; - uint16_t part; - uint8_t revision; - uint8_t cmod; - uint8_t revand; - uint8_t size; -} pidr_data_t; - -typedef enum { CIDR_CLASS_ROMTABLE = 0x01, CIDR_CLASS_CORESIGHT = 0x09 } cidr_classes_t; - -uint32_t adi_romtable_entry_count(AppFSM* const ctx, uint32_t base); -uint32_t adi_romtable_get(AppFSM* const ctx, uint32_t base, uint32_t pos); -bool adi_is_romtable(AppFSM* const ctx, uint32_t base); -const char* adi_romtable_type(AppFSM* const ctx, uint32_t base); -const char* adi_romtable_full(AppFSM* const ctx, uint32_t base); - -#endif diff --git a/applications/external/swd_probe/application.fam b/applications/external/swd_probe/application.fam deleted file mode 100644 index 998dcc7b6..000000000 --- a/applications/external/swd_probe/application.fam +++ /dev/null @@ -1,14 +0,0 @@ -App( - appid="swd_probe", - name="[SWD] SWD Probe", - apptype=FlipperAppType.EXTERNAL, - entry_point="swd_probe_app_main", - requires=["notification", "gui", "storage", "dialogs", "cli"], - stack_size=2 * 1024, - fap_icon="icons/app.png", - fap_category="GPIO", - fap_icon_assets="icons", - fap_author="@g3gg0 & (fixes by @xMasterX)", - fap_version="1.0", - fap_description="ARM SWD (Single Wire Debug) Probe", -) diff --git a/applications/external/swd_probe/icons/app.png b/applications/external/swd_probe/icons/app.png deleted file mode 100644 index 6949ce78d11d5aa0a40b3cf5253e0e297aab47ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4u_bxCy8vk*`02d69!PN(ctjR6 zFz_7#VaBQ2e9}Nc_7YEDSN7*jtc=XO_pYWl0)-qrT^vIsE^qBKf4aTa()7BevL9RXp+soH$fK*4BF z7sn8Z%f0;vc^eFPm~)Q^Wqy}moBgCBgtd|Diu`fUl$SgUSaXvl{^#fIx+ax-f7<3f z-a(qKYfZ04oquest;Ep5VKn*7oHXV&CRGz^7;nBaIKXL8{2=SkWkwE#2tRl4D<^=~ OFnGH9xvX 126) { - return ""; - } - - /* index is zero based */ - id--; - - if(bank >= 14 || jep106[bank][id] == 0) return ""; - - return jep106[bank][id]; -} diff --git a/applications/external/swd_probe/jep106.h b/applications/external/swd_probe/jep106.h deleted file mode 100644 index 17c87feaa..000000000 --- a/applications/external/swd_probe/jep106.h +++ /dev/null @@ -1,26 +0,0 @@ -/* https://github.com/openocd-org/openocd/blob/master/src/helper/ */ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2015 Andreas Fritiofson * - * andreas.fritiofson@gmail.com * - ***************************************************************************/ - -#ifndef OPENOCD_HELPER_JEP106_H -#define OPENOCD_HELPER_JEP106_H - -/** - * Get the manufacturer name associated with a JEP106 ID. - * @param bank The bank (number of continuation codes) of the manufacturer ID. - * @param id The 7-bit manufacturer ID (i.e. with parity stripped). - * @return A pointer to static const storage containing the name of the - * manufacturer associated with bank and id, or one of the strings - * "" and "". - */ -const char* jep106_table_manufacturer(unsigned int bank, unsigned int id); - -static inline const char* jep106_manufacturer(unsigned int manufacturer) { - return jep106_table_manufacturer(manufacturer >> 7, manufacturer & 0x7f); -} - -#endif /* OPENOCD_HELPER_JEP106_H */ diff --git a/applications/external/swd_probe/jep106.inc b/applications/external/swd_probe/jep106.inc deleted file mode 100644 index 3adc131be..000000000 --- a/applications/external/swd_probe/jep106.inc +++ /dev/null @@ -1,1791 +0,0 @@ -/* https://github.com/openocd-org/openocd/blob/master/src/helper/ */ - -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/* - * The manufacturer's standard identification code list appears in JEP106. - * Copyright (c) 2022 JEDEC. All rights reserved. - * - * JEP106 is regularly updated. For the current manufacturer's standard - * identification code list, please visit the JEDEC website at www.jedec.org . - */ - -/* This file is aligned to revision JEP106BF.01 October 2022. */ - -[0][0x01 - 1] = "AMD", -[0][0x02 - 1] = "AMI", -[0][0x03 - 1] = "Fairchild", -[0][0x04 - 1] = "Fujitsu", -[0][0x05 - 1] = "GTE", -[0][0x06 - 1] = "Harris", -[0][0x07 - 1] = "Hitachi", -[0][0x08 - 1] = "Inmos", -[0][0x09 - 1] = "Intel", -[0][0x0a - 1] = "I.T.T.", -[0][0x0b - 1] = "Intersil", -[0][0x0c - 1] = "Monolithic Memories", -[0][0x0d - 1] = "Mostek", -[0][0x0e - 1] = "Freescale (Motorola)", -[0][0x0f - 1] = "National", -[0][0x10 - 1] = "NEC", -[0][0x11 - 1] = "RCA", -[0][0x12 - 1] = "Raytheon", -[0][0x13 - 1] = "Conexant (Rockwell)", -[0][0x14 - 1] = "Seeq", -[0][0x15 - 1] = "NXP (Philips)", -[0][0x16 - 1] = "Synertek", -[0][0x17 - 1] = "Texas Instruments", -[0][0x18 - 1] = "Kioxia Corporation", -[0][0x19 - 1] = "Xicor", -[0][0x1a - 1] = "Zilog", -[0][0x1b - 1] = "Eurotechnique", -[0][0x1c - 1] = "Mitsubishi", -[0][0x1d - 1] = "Lucent (AT&T)", -[0][0x1e - 1] = "Exel", -[0][0x1f - 1] = "Atmel", -[0][0x20 - 1] = "STMicroelectronics", -[0][0x21 - 1] = "Lattice Semi.", -[0][0x22 - 1] = "NCR", -[0][0x23 - 1] = "Wafer Scale Integration", -[0][0x24 - 1] = "IBM", -[0][0x25 - 1] = "Tristar", -[0][0x26 - 1] = "Visic", -[0][0x27 - 1] = "Intl. CMOS Technology", -[0][0x28 - 1] = "SSSI", -[0][0x29 - 1] = "Microchip Technology", -[0][0x2a - 1] = "Ricoh Ltd", -[0][0x2b - 1] = "VLSI", -[0][0x2c - 1] = "Micron Technology", -[0][0x2d - 1] = "SK Hynix", -[0][0x2e - 1] = "OKI Semiconductor", -[0][0x2f - 1] = "ACTEL", -[0][0x30 - 1] = "Sharp", -[0][0x31 - 1] = "Catalyst", -[0][0x32 - 1] = "Panasonic", -[0][0x33 - 1] = "IDT", -[0][0x34 - 1] = "Cypress", -[0][0x35 - 1] = "DEC", -[0][0x36 - 1] = "LSI Logic", -[0][0x37 - 1] = "Zarlink (Plessey)", -[0][0x38 - 1] = "UTMC", -[0][0x39 - 1] = "Thinking Machine", -[0][0x3a - 1] = "Thomson CSF", -[0][0x3b - 1] = "Integrated CMOS (Vertex)", -[0][0x3c - 1] = "Honeywell", -[0][0x3d - 1] = "Tektronix", -[0][0x3e - 1] = "Oracle Corporation", -[0][0x3f - 1] = "Silicon Storage Technology", -[0][0x40 - 1] = "ProMos/Mosel Vitelic", -[0][0x41 - 1] = "Infineon (Siemens)", -[0][0x42 - 1] = "Macronix", -[0][0x43 - 1] = "Xerox", -[0][0x44 - 1] = "Plus Logic", -[0][0x45 - 1] = "Western Digital Technologies Inc", -[0][0x46 - 1] = "Elan Circuit Tech.", -[0][0x47 - 1] = "European Silicon Str.", -[0][0x48 - 1] = "Apple Computer", -[0][0x49 - 1] = "Xilinx", -[0][0x4a - 1] = "Compaq", -[0][0x4b - 1] = "Protocol Engines", -[0][0x4c - 1] = "SCI", -[0][0x4d - 1] = "Seiko Instruments", -[0][0x4e - 1] = "Samsung", -[0][0x4f - 1] = "I3 Design System", -[0][0x50 - 1] = "Klic", -[0][0x51 - 1] = "Crosspoint Solutions", -[0][0x52 - 1] = "Alliance Memory Inc", -[0][0x53 - 1] = "Tandem", -[0][0x54 - 1] = "Hewlett-Packard", -[0][0x55 - 1] = "Integrated Silicon Solutions", -[0][0x56 - 1] = "Brooktree", -[0][0x57 - 1] = "New Media", -[0][0x58 - 1] = "MHS Electronic", -[0][0x59 - 1] = "Performance Semi.", -[0][0x5a - 1] = "Winbond Electronic", -[0][0x5b - 1] = "Kawasaki Steel", -[0][0x5c - 1] = "Bright Micro", -[0][0x5d - 1] = "TECMAR", -[0][0x5e - 1] = "Exar", -[0][0x5f - 1] = "PCMCIA", -[0][0x60 - 1] = "LG Semi (Goldstar)", -[0][0x61 - 1] = "Northern Telecom", -[0][0x62 - 1] = "Sanyo", -[0][0x63 - 1] = "Array Microsystems", -[0][0x64 - 1] = "Crystal Semiconductor", -[0][0x65 - 1] = "Analog Devices", -[0][0x66 - 1] = "PMC-Sierra", -[0][0x67 - 1] = "Asparix", -[0][0x68 - 1] = "Convex Computer", -[0][0x69 - 1] = "Quality Semiconductor", -[0][0x6a - 1] = "Nimbus Technology", -[0][0x6b - 1] = "Transwitch", -[0][0x6c - 1] = "Micronas (ITT Intermetall)", -[0][0x6d - 1] = "Cannon", -[0][0x6e - 1] = "Altera", -[0][0x6f - 1] = "NEXCOM", -[0][0x70 - 1] = "Qualcomm", -[0][0x71 - 1] = "Sony", -[0][0x72 - 1] = "Cray Research", -[0][0x73 - 1] = "AMS(Austria Micro)", -[0][0x74 - 1] = "Vitesse", -[0][0x75 - 1] = "Aster Electronics", -[0][0x76 - 1] = "Bay Networks (Synoptic)", -[0][0x77 - 1] = "Zentrum/ZMD", -[0][0x78 - 1] = "TRW", -[0][0x79 - 1] = "Thesys", -[0][0x7a - 1] = "Solbourne Computer", -[0][0x7b - 1] = "Allied-Signal", -[0][0x7c - 1] = "Dialog Semiconductor", -[0][0x7d - 1] = "Media Vision", -[0][0x7e - 1] = "Numonyx Corporation", -[1][0x01 - 1] = "Cirrus Logic", -[1][0x02 - 1] = "National Instruments", -[1][0x03 - 1] = "ILC Data Device", -[1][0x04 - 1] = "Alcatel Mietec", -[1][0x05 - 1] = "Micro Linear", -[1][0x06 - 1] = "Univ. of NC", -[1][0x07 - 1] = "JTAG Technologies", -[1][0x08 - 1] = "BAE Systems (Loral)", -[1][0x09 - 1] = "Nchip", -[1][0x0a - 1] = "Galileo Tech", -[1][0x0b - 1] = "Bestlink Systems", -[1][0x0c - 1] = "Graychip", -[1][0x0d - 1] = "GENNUM", -[1][0x0e - 1] = "Imagination Technologies Limited", -[1][0x0f - 1] = "Robert Bosch", -[1][0x10 - 1] = "Chip Express", -[1][0x11 - 1] = "DATARAM", -[1][0x12 - 1] = "United Microelectronics Corp", -[1][0x13 - 1] = "TCSI", -[1][0x14 - 1] = "Smart Modular", -[1][0x15 - 1] = "Hughes Aircraft", -[1][0x16 - 1] = "Lanstar Semiconductor", -[1][0x17 - 1] = "Qlogic", -[1][0x18 - 1] = "Kingston", -[1][0x19 - 1] = "Music Semi", -[1][0x1a - 1] = "Ericsson Components", -[1][0x1b - 1] = "SpaSE", -[1][0x1c - 1] = "Eon Silicon Devices", -[1][0x1d - 1] = "Integrated Silicon Solution (ISSI)", -[1][0x1e - 1] = "DoD", -[1][0x1f - 1] = "Integ. Memories Tech.", -[1][0x20 - 1] = "Corollary Inc", -[1][0x21 - 1] = "Dallas Semiconductor", -[1][0x22 - 1] = "Omnivision", -[1][0x23 - 1] = "EIV(Switzerland)", -[1][0x24 - 1] = "Novatel Wireless", -[1][0x25 - 1] = "Zarlink (Mitel)", -[1][0x26 - 1] = "Clearpoint", -[1][0x27 - 1] = "Cabletron", -[1][0x28 - 1] = "STEC (Silicon Tech)", -[1][0x29 - 1] = "Vanguard", -[1][0x2a - 1] = "Hagiwara Sys-Com", -[1][0x2b - 1] = "Vantis", -[1][0x2c - 1] = "Celestica", -[1][0x2d - 1] = "Century", -[1][0x2e - 1] = "Hal Computers", -[1][0x2f - 1] = "Rohm Company Ltd", -[1][0x30 - 1] = "Juniper Networks", -[1][0x31 - 1] = "Libit Signal Processing", -[1][0x32 - 1] = "Mushkin Enhanced Memory", -[1][0x33 - 1] = "Tundra Semiconductor", -[1][0x34 - 1] = "Adaptec Inc", -[1][0x35 - 1] = "LightSpeed Semi.", -[1][0x36 - 1] = "ZSP Corp", -[1][0x37 - 1] = "AMIC Technology", -[1][0x38 - 1] = "Adobe Systems", -[1][0x39 - 1] = "Dynachip", -[1][0x3a - 1] = "PNY Technologies Inc", -[1][0x3b - 1] = "Newport Digital", -[1][0x3c - 1] = "MMC Networks", -[1][0x3d - 1] = "T Square", -[1][0x3e - 1] = "Seiko Epson", -[1][0x3f - 1] = "Broadcom", -[1][0x40 - 1] = "Viking Components", -[1][0x41 - 1] = "V3 Semiconductor", -[1][0x42 - 1] = "Flextronics (Orbit Semiconductor)", -[1][0x43 - 1] = "Suwa Electronics", -[1][0x44 - 1] = "Transmeta", -[1][0x45 - 1] = "Micron CMS", -[1][0x46 - 1] = "American Computer & Digital Components Inc", -[1][0x47 - 1] = "Enhance 3000 Inc", -[1][0x48 - 1] = "Tower Semiconductor", -[1][0x49 - 1] = "CPU Design", -[1][0x4a - 1] = "Price Point", -[1][0x4b - 1] = "Maxim Integrated Product", -[1][0x4c - 1] = "Tellabs", -[1][0x4d - 1] = "Centaur Technology", -[1][0x4e - 1] = "Unigen Corporation", -[1][0x4f - 1] = "Transcend Information", -[1][0x50 - 1] = "Memory Card Technology", -[1][0x51 - 1] = "CKD Corporation Ltd", -[1][0x52 - 1] = "Capital Instruments Inc", -[1][0x53 - 1] = "Aica Kogyo Ltd", -[1][0x54 - 1] = "Linvex Technology", -[1][0x55 - 1] = "MSC Vertriebs GmbH", -[1][0x56 - 1] = "AKM Company Ltd", -[1][0x57 - 1] = "Dynamem Inc", -[1][0x58 - 1] = "NERA ASA", -[1][0x59 - 1] = "GSI Technology", -[1][0x5a - 1] = "Dane-Elec (C Memory)", -[1][0x5b - 1] = "Acorn Computers", -[1][0x5c - 1] = "Lara Technology", -[1][0x5d - 1] = "Oak Technology Inc", -[1][0x5e - 1] = "Itec Memory", -[1][0x5f - 1] = "Tanisys Technology", -[1][0x60 - 1] = "Truevision", -[1][0x61 - 1] = "Wintec Industries", -[1][0x62 - 1] = "Super PC Memory", -[1][0x63 - 1] = "MGV Memory", -[1][0x64 - 1] = "Galvantech", -[1][0x65 - 1] = "Gadzoox Networks", -[1][0x66 - 1] = "Multi Dimensional Cons.", -[1][0x67 - 1] = "GateField", -[1][0x68 - 1] = "Integrated Memory System", -[1][0x69 - 1] = "Triscend", -[1][0x6a - 1] = "XaQti", -[1][0x6b - 1] = "Goldenram", -[1][0x6c - 1] = "Clear Logic", -[1][0x6d - 1] = "Cimaron Communications", -[1][0x6e - 1] = "Nippon Steel Semi. Corp", -[1][0x6f - 1] = "Advantage Memory", -[1][0x70 - 1] = "AMCC", -[1][0x71 - 1] = "LeCroy", -[1][0x72 - 1] = "Yamaha Corporation", -[1][0x73 - 1] = "Digital Microwave", -[1][0x74 - 1] = "NetLogic Microsystems", -[1][0x75 - 1] = "MIMOS Semiconductor", -[1][0x76 - 1] = "Advanced Fibre", -[1][0x77 - 1] = "BF Goodrich Data.", -[1][0x78 - 1] = "Epigram", -[1][0x79 - 1] = "Acbel Polytech Inc", -[1][0x7a - 1] = "Apacer Technology", -[1][0x7b - 1] = "Admor Memory", -[1][0x7c - 1] = "FOXCONN", -[1][0x7d - 1] = "Quadratics Superconductor", -[1][0x7e - 1] = "3COM", -[2][0x01 - 1] = "Camintonn Corporation", -[2][0x02 - 1] = "ISOA Incorporated", -[2][0x03 - 1] = "Agate Semiconductor", -[2][0x04 - 1] = "ADMtek Incorporated", -[2][0x05 - 1] = "HYPERTEC", -[2][0x06 - 1] = "Adhoc Technologies", -[2][0x07 - 1] = "MOSAID Technologies", -[2][0x08 - 1] = "Ardent Technologies", -[2][0x09 - 1] = "Switchcore", -[2][0x0a - 1] = "Cisco Systems Inc", -[2][0x0b - 1] = "Allayer Technologies", -[2][0x0c - 1] = "WorkX AG (Wichman)", -[2][0x0d - 1] = "Oasis Semiconductor", -[2][0x0e - 1] = "Novanet Semiconductor", -[2][0x0f - 1] = "E-M Solutions", -[2][0x10 - 1] = "Power General", -[2][0x11 - 1] = "Advanced Hardware Arch.", -[2][0x12 - 1] = "Inova Semiconductors GmbH", -[2][0x13 - 1] = "Telocity", -[2][0x14 - 1] = "Delkin Devices", -[2][0x15 - 1] = "Symagery Microsystems", -[2][0x16 - 1] = "C-Port Corporation", -[2][0x17 - 1] = "SiberCore Technologies", -[2][0x18 - 1] = "Southland Microsystems", -[2][0x19 - 1] = "Malleable Technologies", -[2][0x1a - 1] = "Kendin Communications", -[2][0x1b - 1] = "Great Technology Microcomputer", -[2][0x1c - 1] = "Sanmina Corporation", -[2][0x1d - 1] = "HADCO Corporation", -[2][0x1e - 1] = "Corsair", -[2][0x1f - 1] = "Actrans System Inc", -[2][0x20 - 1] = "ALPHA Technologies", -[2][0x21 - 1] = "Silicon Laboratories Inc (Cygnal)", -[2][0x22 - 1] = "Artesyn Technologies", -[2][0x23 - 1] = "Align Manufacturing", -[2][0x24 - 1] = "Peregrine Semiconductor", -[2][0x25 - 1] = "Chameleon Systems", -[2][0x26 - 1] = "Aplus Flash Technology", -[2][0x27 - 1] = "MIPS Technologies", -[2][0x28 - 1] = "Chrysalis ITS", -[2][0x29 - 1] = "ADTEC Corporation", -[2][0x2a - 1] = "Kentron Technologies", -[2][0x2b - 1] = "Win Technologies", -[2][0x2c - 1] = "Tezzaron Semiconductor", -[2][0x2d - 1] = "Extreme Packet Devices", -[2][0x2e - 1] = "RF Micro Devices", -[2][0x2f - 1] = "Siemens AG", -[2][0x30 - 1] = "Sarnoff Corporation", -[2][0x31 - 1] = "Itautec SA", -[2][0x32 - 1] = "Radiata Inc", -[2][0x33 - 1] = "Benchmark Elect. (AVEX)", -[2][0x34 - 1] = "Legend", -[2][0x35 - 1] = "SpecTek Incorporated", -[2][0x36 - 1] = "Hi/fn", -[2][0x37 - 1] = "Enikia Incorporated", -[2][0x38 - 1] = "SwitchOn Networks", -[2][0x39 - 1] = "AANetcom Incorporated", -[2][0x3a - 1] = "Micro Memory Bank", -[2][0x3b - 1] = "ESS Technology", -[2][0x3c - 1] = "Virata Corporation", -[2][0x3d - 1] = "Excess Bandwidth", -[2][0x3e - 1] = "West Bay Semiconductor", -[2][0x3f - 1] = "DSP Group", -[2][0x40 - 1] = "Newport Communications", -[2][0x41 - 1] = "Chip2Chip Incorporated", -[2][0x42 - 1] = "Phobos Corporation", -[2][0x43 - 1] = "Intellitech Corporation", -[2][0x44 - 1] = "Nordic VLSI ASA", -[2][0x45 - 1] = "Ishoni Networks", -[2][0x46 - 1] = "Silicon Spice", -[2][0x47 - 1] = "Alchemy Semiconductor", -[2][0x48 - 1] = "Agilent Technologies", -[2][0x49 - 1] = "Centillium Communications", -[2][0x4a - 1] = "W.L. Gore", -[2][0x4b - 1] = "HanBit Electronics", -[2][0x4c - 1] = "GlobeSpan", -[2][0x4d - 1] = "Element 14", -[2][0x4e - 1] = "Pycon", -[2][0x4f - 1] = "Saifun Semiconductors", -[2][0x50 - 1] = "Sibyte Incorporated", -[2][0x51 - 1] = "MetaLink Technologies", -[2][0x52 - 1] = "Feiya Technology", -[2][0x53 - 1] = "I & C Technology", -[2][0x54 - 1] = "Shikatronics", -[2][0x55 - 1] = "Elektrobit", -[2][0x56 - 1] = "Megic", -[2][0x57 - 1] = "Com-Tier", -[2][0x58 - 1] = "Malaysia Micro Solutions", -[2][0x59 - 1] = "Hyperchip", -[2][0x5a - 1] = "Gemstone Communications", -[2][0x5b - 1] = "Anadigm (Anadyne)", -[2][0x5c - 1] = "3ParData", -[2][0x5d - 1] = "Mellanox Technologies", -[2][0x5e - 1] = "Tenx Technologies", -[2][0x5f - 1] = "Helix AG", -[2][0x60 - 1] = "Domosys", -[2][0x61 - 1] = "Skyup Technology", -[2][0x62 - 1] = "HiNT Corporation", -[2][0x63 - 1] = "Chiaro", -[2][0x64 - 1] = "MDT Technologies GmbH", -[2][0x65 - 1] = "Exbit Technology A/S", -[2][0x66 - 1] = "Integrated Technology Express", -[2][0x67 - 1] = "AVED Memory", -[2][0x68 - 1] = "Legerity", -[2][0x69 - 1] = "Jasmine Networks", -[2][0x6a - 1] = "Caspian Networks", -[2][0x6b - 1] = "nCUBE", -[2][0x6c - 1] = "Silicon Access Networks", -[2][0x6d - 1] = "FDK Corporation", -[2][0x6e - 1] = "High Bandwidth Access", -[2][0x6f - 1] = "MultiLink Technology", -[2][0x70 - 1] = "BRECIS", -[2][0x71 - 1] = "World Wide Packets", -[2][0x72 - 1] = "APW", -[2][0x73 - 1] = "Chicory Systems", -[2][0x74 - 1] = "Xstream Logic", -[2][0x75 - 1] = "Fast-Chip", -[2][0x76 - 1] = "Zucotto Wireless", -[2][0x77 - 1] = "Realchip", -[2][0x78 - 1] = "Galaxy Power", -[2][0x79 - 1] = "eSilicon", -[2][0x7a - 1] = "Morphics Technology", -[2][0x7b - 1] = "Accelerant Networks", -[2][0x7c - 1] = "Silicon Wave", -[2][0x7d - 1] = "SandCraft", -[2][0x7e - 1] = "Elpida", -[3][0x01 - 1] = "Solectron", -[3][0x02 - 1] = "Optosys Technologies", -[3][0x03 - 1] = "Buffalo (Formerly Melco)", -[3][0x04 - 1] = "TriMedia Technologies", -[3][0x05 - 1] = "Cyan Technologies", -[3][0x06 - 1] = "Global Locate", -[3][0x07 - 1] = "Optillion", -[3][0x08 - 1] = "Terago Communications", -[3][0x09 - 1] = "Ikanos Communications", -[3][0x0a - 1] = "Princeton Technology", -[3][0x0b - 1] = "Nanya Technology", -[3][0x0c - 1] = "Elite Flash Storage", -[3][0x0d - 1] = "Mysticom", -[3][0x0e - 1] = "LightSand Communications", -[3][0x0f - 1] = "ATI Technologies", -[3][0x10 - 1] = "Agere Systems", -[3][0x11 - 1] = "NeoMagic", -[3][0x12 - 1] = "AuroraNetics", -[3][0x13 - 1] = "Golden Empire", -[3][0x14 - 1] = "Mushkin", -[3][0x15 - 1] = "Tioga Technologies", -[3][0x16 - 1] = "Netlist", -[3][0x17 - 1] = "TeraLogic", -[3][0x18 - 1] = "Cicada Semiconductor", -[3][0x19 - 1] = "Centon Electronics", -[3][0x1a - 1] = "Tyco Electronics", -[3][0x1b - 1] = "Magis Works", -[3][0x1c - 1] = "Zettacom", -[3][0x1d - 1] = "Cogency Semiconductor", -[3][0x1e - 1] = "Chipcon AS", -[3][0x1f - 1] = "Aspex Technology", -[3][0x20 - 1] = "F5 Networks", -[3][0x21 - 1] = "Programmable Silicon Solutions", -[3][0x22 - 1] = "ChipWrights", -[3][0x23 - 1] = "Acorn Networks", -[3][0x24 - 1] = "Quicklogic", -[3][0x25 - 1] = "Kingmax Semiconductor", -[3][0x26 - 1] = "BOPS", -[3][0x27 - 1] = "Flasys", -[3][0x28 - 1] = "BitBlitz Communications", -[3][0x29 - 1] = "eMemory Technology", -[3][0x2a - 1] = "Procket Networks", -[3][0x2b - 1] = "Purple Ray", -[3][0x2c - 1] = "Trebia Networks", -[3][0x2d - 1] = "Delta Electronics", -[3][0x2e - 1] = "Onex Communications", -[3][0x2f - 1] = "Ample Communications", -[3][0x30 - 1] = "Memory Experts Intl", -[3][0x31 - 1] = "Astute Networks", -[3][0x32 - 1] = "Azanda Network Devices", -[3][0x33 - 1] = "Dibcom", -[3][0x34 - 1] = "Tekmos", -[3][0x35 - 1] = "API NetWorks", -[3][0x36 - 1] = "Bay Microsystems", -[3][0x37 - 1] = "Firecron Ltd", -[3][0x38 - 1] = "Resonext Communications", -[3][0x39 - 1] = "Tachys Technologies", -[3][0x3a - 1] = "Equator Technology", -[3][0x3b - 1] = "Concept Computer", -[3][0x3c - 1] = "SILCOM", -[3][0x3d - 1] = "3Dlabs", -[3][0x3e - 1] = "c't Magazine", -[3][0x3f - 1] = "Sanera Systems", -[3][0x40 - 1] = "Silicon Packets", -[3][0x41 - 1] = "Viasystems Group", -[3][0x42 - 1] = "Simtek", -[3][0x43 - 1] = "Semicon Devices Singapore", -[3][0x44 - 1] = "Satron Handelsges", -[3][0x45 - 1] = "Improv Systems", -[3][0x46 - 1] = "INDUSYS GmbH", -[3][0x47 - 1] = "Corrent", -[3][0x48 - 1] = "Infrant Technologies", -[3][0x49 - 1] = "Ritek Corp", -[3][0x4a - 1] = "empowerTel Networks", -[3][0x4b - 1] = "Hypertec", -[3][0x4c - 1] = "Cavium Networks", -[3][0x4d - 1] = "PLX Technology", -[3][0x4e - 1] = "Massana Design", -[3][0x4f - 1] = "Intrinsity", -[3][0x50 - 1] = "Valence Semiconductor", -[3][0x51 - 1] = "Terawave Communications", -[3][0x52 - 1] = "IceFyre Semiconductor", -[3][0x53 - 1] = "Primarion", -[3][0x54 - 1] = "Picochip Designs Ltd", -[3][0x55 - 1] = "Silverback Systems", -[3][0x56 - 1] = "Jade Star Technologies", -[3][0x57 - 1] = "Pijnenburg Securealink", -[3][0x58 - 1] = "takeMS - Ultron AG", -[3][0x59 - 1] = "Cambridge Silicon Radio", -[3][0x5a - 1] = "Swissbit", -[3][0x5b - 1] = "Nazomi Communications", -[3][0x5c - 1] = "eWave System", -[3][0x5d - 1] = "Rockwell Collins", -[3][0x5e - 1] = "Picocel Co Ltd (Paion)", -[3][0x5f - 1] = "Alphamosaic Ltd", -[3][0x60 - 1] = "Sandburst", -[3][0x61 - 1] = "SiCon Video", -[3][0x62 - 1] = "NanoAmp Solutions", -[3][0x63 - 1] = "Ericsson Technology", -[3][0x64 - 1] = "PrairieComm", -[3][0x65 - 1] = "Mitac International", -[3][0x66 - 1] = "Layer N Networks", -[3][0x67 - 1] = "MtekVision (Atsana)", -[3][0x68 - 1] = "Allegro Networks", -[3][0x69 - 1] = "Marvell Semiconductors", -[3][0x6a - 1] = "Netergy Microelectronic", -[3][0x6b - 1] = "NVIDIA", -[3][0x6c - 1] = "Internet Machines", -[3][0x6d - 1] = "Memorysolution GmbH", -[3][0x6e - 1] = "Litchfield Communication", -[3][0x6f - 1] = "Accton Technology", -[3][0x70 - 1] = "Teradiant Networks", -[3][0x71 - 1] = "Scaleo Chip", -[3][0x72 - 1] = "Cortina Systems", -[3][0x73 - 1] = "RAM Components", -[3][0x74 - 1] = "Raqia Networks", -[3][0x75 - 1] = "ClearSpeed", -[3][0x76 - 1] = "Matsushita Battery", -[3][0x77 - 1] = "Xelerated", -[3][0x78 - 1] = "SimpleTech", -[3][0x79 - 1] = "Utron Technology", -[3][0x7a - 1] = "Astec International", -[3][0x7b - 1] = "AVM gmbH", -[3][0x7c - 1] = "Redux Communications", -[3][0x7d - 1] = "Dot Hill Systems", -[3][0x7e - 1] = "TeraChip", -[4][0x01 - 1] = "T-RAM Incorporated", -[4][0x02 - 1] = "Innovics Wireless", -[4][0x03 - 1] = "Teknovus", -[4][0x04 - 1] = "KeyEye Communications", -[4][0x05 - 1] = "Runcom Technologies", -[4][0x06 - 1] = "RedSwitch", -[4][0x07 - 1] = "Dotcast", -[4][0x08 - 1] = "Silicon Mountain Memory", -[4][0x09 - 1] = "Signia Technologies", -[4][0x0a - 1] = "Pixim", -[4][0x0b - 1] = "Galazar Networks", -[4][0x0c - 1] = "White Electronic Designs", -[4][0x0d - 1] = "Patriot Scientific", -[4][0x0e - 1] = "Neoaxiom Corporation", -[4][0x0f - 1] = "3Y Power Technology", -[4][0x10 - 1] = "Scaleo Chip", -[4][0x11 - 1] = "Potentia Power Systems", -[4][0x12 - 1] = "C-guys Incorporated", -[4][0x13 - 1] = "Digital Communications Technology Inc", -[4][0x14 - 1] = "Silicon-Based Technology", -[4][0x15 - 1] = "Fulcrum Microsystems", -[4][0x16 - 1] = "Positivo Informatica Ltd", -[4][0x17 - 1] = "XIOtech Corporation", -[4][0x18 - 1] = "PortalPlayer", -[4][0x19 - 1] = "Zhiying Software", -[4][0x1a - 1] = "ParkerVision Inc", -[4][0x1b - 1] = "Phonex Broadband", -[4][0x1c - 1] = "Skyworks Solutions", -[4][0x1d - 1] = "Entropic Communications", -[4][0x1e - 1] = "I'M Intelligent Memory Ltd", -[4][0x1f - 1] = "Zensys A/S", -[4][0x20 - 1] = "Legend Silicon Corp", -[4][0x21 - 1] = "Sci-worx GmbH", -[4][0x22 - 1] = "SMSC (Standard Microsystems)", -[4][0x23 - 1] = "Renesas Electronics", -[4][0x24 - 1] = "Raza Microelectronics", -[4][0x25 - 1] = "Phyworks", -[4][0x26 - 1] = "MediaTek", -[4][0x27 - 1] = "Non-cents Productions", -[4][0x28 - 1] = "US Modular", -[4][0x29 - 1] = "Wintegra Ltd", -[4][0x2a - 1] = "Mathstar", -[4][0x2b - 1] = "StarCore", -[4][0x2c - 1] = "Oplus Technologies", -[4][0x2d - 1] = "Mindspeed", -[4][0x2e - 1] = "Just Young Computer", -[4][0x2f - 1] = "Radia Communications", -[4][0x30 - 1] = "OCZ", -[4][0x31 - 1] = "Emuzed", -[4][0x32 - 1] = "LOGIC Devices", -[4][0x33 - 1] = "Inphi Corporation", -[4][0x34 - 1] = "Quake Technologies", -[4][0x35 - 1] = "Vixel", -[4][0x36 - 1] = "SolusTek", -[4][0x37 - 1] = "Kongsberg Maritime", -[4][0x38 - 1] = "Faraday Technology", -[4][0x39 - 1] = "Altium Ltd", -[4][0x3a - 1] = "Insyte", -[4][0x3b - 1] = "ARM Ltd", -[4][0x3c - 1] = "DigiVision", -[4][0x3d - 1] = "Vativ Technologies", -[4][0x3e - 1] = "Endicott Interconnect Technologies", -[4][0x3f - 1] = "Pericom", -[4][0x40 - 1] = "Bandspeed", -[4][0x41 - 1] = "LeWiz Communications", -[4][0x42 - 1] = "CPU Technology", -[4][0x43 - 1] = "Ramaxel Technology", -[4][0x44 - 1] = "DSP Group", -[4][0x45 - 1] = "Axis Communications", -[4][0x46 - 1] = "Legacy Electronics", -[4][0x47 - 1] = "Chrontel", -[4][0x48 - 1] = "Powerchip Semiconductor", -[4][0x49 - 1] = "MobilEye Technologies", -[4][0x4a - 1] = "Excel Semiconductor", -[4][0x4b - 1] = "A-DATA Technology", -[4][0x4c - 1] = "VirtualDigm", -[4][0x4d - 1] = "G Skill Intl", -[4][0x4e - 1] = "Quanta Computer", -[4][0x4f - 1] = "Yield Microelectronics", -[4][0x50 - 1] = "Afa Technologies", -[4][0x51 - 1] = "KINGBOX Technology Co Ltd", -[4][0x52 - 1] = "Ceva", -[4][0x53 - 1] = "iStor Networks", -[4][0x54 - 1] = "Advance Modules", -[4][0x55 - 1] = "Microsoft", -[4][0x56 - 1] = "Open-Silicon", -[4][0x57 - 1] = "Goal Semiconductor", -[4][0x58 - 1] = "ARC International", -[4][0x59 - 1] = "Simmtec", -[4][0x5a - 1] = "Metanoia", -[4][0x5b - 1] = "Key Stream", -[4][0x5c - 1] = "Lowrance Electronics", -[4][0x5d - 1] = "Adimos", -[4][0x5e - 1] = "SiGe Semiconductor", -[4][0x5f - 1] = "Fodus Communications", -[4][0x60 - 1] = "Credence Systems Corp", -[4][0x61 - 1] = "Genesis Microchip Inc", -[4][0x62 - 1] = "Vihana Inc", -[4][0x63 - 1] = "WIS Technologies", -[4][0x64 - 1] = "GateChange Technologies", -[4][0x65 - 1] = "High Density Devices AS", -[4][0x66 - 1] = "Synopsys", -[4][0x67 - 1] = "Gigaram", -[4][0x68 - 1] = "Enigma Semiconductor Inc", -[4][0x69 - 1] = "Century Micro Inc", -[4][0x6a - 1] = "Icera Semiconductor", -[4][0x6b - 1] = "Mediaworks Integrated Systems", -[4][0x6c - 1] = "O'Neil Product Development", -[4][0x6d - 1] = "Supreme Top Technology Ltd", -[4][0x6e - 1] = "MicroDisplay Corporation", -[4][0x6f - 1] = "Team Group Inc", -[4][0x70 - 1] = "Sinett Corporation", -[4][0x71 - 1] = "Toshiba Corporation", -[4][0x72 - 1] = "Tensilica", -[4][0x73 - 1] = "SiRF Technology", -[4][0x74 - 1] = "Bacoc Inc", -[4][0x75 - 1] = "SMaL Camera Technologies", -[4][0x76 - 1] = "Thomson SC", -[4][0x77 - 1] = "Airgo Networks", -[4][0x78 - 1] = "Wisair Ltd", -[4][0x79 - 1] = "SigmaTel", -[4][0x7a - 1] = "Arkados", -[4][0x7b - 1] = "Compete IT gmbH Co KG", -[4][0x7c - 1] = "Eudar Technology Inc", -[4][0x7d - 1] = "Focus Enhancements", -[4][0x7e - 1] = "Xyratex", -[5][0x01 - 1] = "Specular Networks", -[5][0x02 - 1] = "Patriot Memory (PDP Systems)", -[5][0x03 - 1] = "U-Chip Technology Corp", -[5][0x04 - 1] = "Silicon Optix", -[5][0x05 - 1] = "Greenfield Networks", -[5][0x06 - 1] = "CompuRAM GmbH", -[5][0x07 - 1] = "Stargen Inc", -[5][0x08 - 1] = "NetCell Corporation", -[5][0x09 - 1] = "Excalibrus Technologies Ltd", -[5][0x0a - 1] = "SCM Microsystems", -[5][0x0b - 1] = "Xsigo Systems Inc", -[5][0x0c - 1] = "CHIPS & Systems Inc", -[5][0x0d - 1] = "Tier 1 Multichip Solutions", -[5][0x0e - 1] = "CWRL Labs", -[5][0x0f - 1] = "Teradici", -[5][0x10 - 1] = "Gigaram Inc", -[5][0x11 - 1] = "g2 Microsystems", -[5][0x12 - 1] = "PowerFlash Semiconductor", -[5][0x13 - 1] = "P.A. Semi Inc", -[5][0x14 - 1] = "NovaTech Solutions S.A.", -[5][0x15 - 1] = "c2 Microsystems Inc", -[5][0x16 - 1] = "Level5 Networks", -[5][0x17 - 1] = "COS Memory AG", -[5][0x18 - 1] = "Innovasic Semiconductor", -[5][0x19 - 1] = "02IC Co Ltd", -[5][0x1a - 1] = "Tabula Inc", -[5][0x1b - 1] = "Crucial Technology", -[5][0x1c - 1] = "Chelsio Communications", -[5][0x1d - 1] = "Solarflare Communications", -[5][0x1e - 1] = "Xambala Inc", -[5][0x1f - 1] = "EADS Astrium", -[5][0x20 - 1] = "Terra Semiconductor Inc", -[5][0x21 - 1] = "Imaging Works Inc", -[5][0x22 - 1] = "Astute Networks Inc", -[5][0x23 - 1] = "Tzero", -[5][0x24 - 1] = "Emulex", -[5][0x25 - 1] = "Power-One", -[5][0x26 - 1] = "Pulse~LINK Inc", -[5][0x27 - 1] = "Hon Hai Precision Industry", -[5][0x28 - 1] = "White Rock Networks Inc", -[5][0x29 - 1] = "Telegent Systems USA Inc", -[5][0x2a - 1] = "Atrua Technologies Inc", -[5][0x2b - 1] = "Acbel Polytech Inc", -[5][0x2c - 1] = "eRide Inc", -[5][0x2d - 1] = "ULi Electronics Inc", -[5][0x2e - 1] = "Magnum Semiconductor Inc", -[5][0x2f - 1] = "neoOne Technology Inc", -[5][0x30 - 1] = "Connex Technology Inc", -[5][0x31 - 1] = "Stream Processors Inc", -[5][0x32 - 1] = "Focus Enhancements", -[5][0x33 - 1] = "Telecis Wireless Inc", -[5][0x34 - 1] = "uNav Microelectronics", -[5][0x35 - 1] = "Tarari Inc", -[5][0x36 - 1] = "Ambric Inc", -[5][0x37 - 1] = "Newport Media Inc", -[5][0x38 - 1] = "VMTS", -[5][0x39 - 1] = "Enuclia Semiconductor Inc", -[5][0x3a - 1] = "Virtium Technology Inc", -[5][0x3b - 1] = "Solid State System Co Ltd", -[5][0x3c - 1] = "Kian Tech LLC", -[5][0x3d - 1] = "Artimi", -[5][0x3e - 1] = "Power Quotient International", -[5][0x3f - 1] = "Avago Technologies", -[5][0x40 - 1] = "ADTechnology", -[5][0x41 - 1] = "Sigma Designs", -[5][0x42 - 1] = "SiCortex Inc", -[5][0x43 - 1] = "Ventura Technology Group", -[5][0x44 - 1] = "eASIC", -[5][0x45 - 1] = "M.H.S. SAS", -[5][0x46 - 1] = "Micro Star International", -[5][0x47 - 1] = "Rapport Inc", -[5][0x48 - 1] = "Makway International", -[5][0x49 - 1] = "Broad Reach Engineering Co", -[5][0x4a - 1] = "Semiconductor Mfg Intl Corp", -[5][0x4b - 1] = "SiConnect", -[5][0x4c - 1] = "FCI USA Inc", -[5][0x4d - 1] = "Validity Sensors", -[5][0x4e - 1] = "Coney Technology Co Ltd", -[5][0x4f - 1] = "Spans Logic", -[5][0x50 - 1] = "Neterion Inc", -[5][0x51 - 1] = "Qimonda", -[5][0x52 - 1] = "New Japan Radio Co Ltd", -[5][0x53 - 1] = "Velogix", -[5][0x54 - 1] = "Montalvo Systems", -[5][0x55 - 1] = "iVivity Inc", -[5][0x56 - 1] = "Walton Chaintech", -[5][0x57 - 1] = "AENEON", -[5][0x58 - 1] = "Lorom Industrial Co Ltd", -[5][0x59 - 1] = "Radiospire Networks", -[5][0x5a - 1] = "Sensio Technologies Inc", -[5][0x5b - 1] = "Nethra Imaging", -[5][0x5c - 1] = "Hexon Technology Pte Ltd", -[5][0x5d - 1] = "CompuStocx (CSX)", -[5][0x5e - 1] = "Methode Electronics Inc", -[5][0x5f - 1] = "Connect One Ltd", -[5][0x60 - 1] = "Opulan Technologies", -[5][0x61 - 1] = "Septentrio NV", -[5][0x62 - 1] = "Goldenmars Technology Inc", -[5][0x63 - 1] = "Kreton Corporation", -[5][0x64 - 1] = "Cochlear Ltd", -[5][0x65 - 1] = "Altair Semiconductor", -[5][0x66 - 1] = "NetEffect Inc", -[5][0x67 - 1] = "Spansion Inc", -[5][0x68 - 1] = "Taiwan Semiconductor Mfg", -[5][0x69 - 1] = "Emphany Systems Inc", -[5][0x6a - 1] = "ApaceWave Technologies", -[5][0x6b - 1] = "Mobilygen Corporation", -[5][0x6c - 1] = "Tego", -[5][0x6d - 1] = "Cswitch Corporation", -[5][0x6e - 1] = "Haier (Beijing) IC Design Co", -[5][0x6f - 1] = "MetaRAM", -[5][0x70 - 1] = "Axel Electronics Co Ltd", -[5][0x71 - 1] = "Tilera Corporation", -[5][0x72 - 1] = "Aquantia", -[5][0x73 - 1] = "Vivace Semiconductor", -[5][0x74 - 1] = "Redpine Signals", -[5][0x75 - 1] = "Octalica", -[5][0x76 - 1] = "InterDigital Communications", -[5][0x77 - 1] = "Avant Technology", -[5][0x78 - 1] = "Asrock Inc", -[5][0x79 - 1] = "Availink", -[5][0x7a - 1] = "Quartics Inc", -[5][0x7b - 1] = "Element CXI", -[5][0x7c - 1] = "Innovaciones Microelectronicas", -[5][0x7d - 1] = "VeriSilicon Microelectronics", -[5][0x7e - 1] = "W5 Networks", -[6][0x01 - 1] = "MOVEKING", -[6][0x02 - 1] = "Mavrix Technology Inc", -[6][0x03 - 1] = "CellGuide Ltd", -[6][0x04 - 1] = "Faraday Technology", -[6][0x05 - 1] = "Diablo Technologies Inc", -[6][0x06 - 1] = "Jennic", -[6][0x07 - 1] = "Octasic", -[6][0x08 - 1] = "Molex Incorporated", -[6][0x09 - 1] = "3Leaf Networks", -[6][0x0a - 1] = "Bright Micron Technology", -[6][0x0b - 1] = "Netxen", -[6][0x0c - 1] = "NextWave Broadband Inc", -[6][0x0d - 1] = "DisplayLink", -[6][0x0e - 1] = "ZMOS Technology", -[6][0x0f - 1] = "Tec-Hill", -[6][0x10 - 1] = "Multigig Inc", -[6][0x11 - 1] = "Amimon", -[6][0x12 - 1] = "Euphonic Technologies Inc", -[6][0x13 - 1] = "BRN Phoenix", -[6][0x14 - 1] = "InSilica", -[6][0x15 - 1] = "Ember Corporation", -[6][0x16 - 1] = "Avexir Technologies Corporation", -[6][0x17 - 1] = "Echelon Corporation", -[6][0x18 - 1] = "Edgewater Computer Systems", -[6][0x19 - 1] = "XMOS Semiconductor Ltd", -[6][0x1a - 1] = "GENUSION Inc", -[6][0x1b - 1] = "Memory Corp NV", -[6][0x1c - 1] = "SiliconBlue Technologies", -[6][0x1d - 1] = "Rambus Inc", -[6][0x1e - 1] = "Andes Technology Corporation", -[6][0x1f - 1] = "Coronis Systems", -[6][0x20 - 1] = "Achronix Semiconductor", -[6][0x21 - 1] = "Siano Mobile Silicon Ltd", -[6][0x22 - 1] = "Semtech Corporation", -[6][0x23 - 1] = "Pixelworks Inc", -[6][0x24 - 1] = "Gaisler Research AB", -[6][0x25 - 1] = "Teranetics", -[6][0x26 - 1] = "Toppan Printing Co Ltd", -[6][0x27 - 1] = "Kingxcon", -[6][0x28 - 1] = "Silicon Integrated Systems", -[6][0x29 - 1] = "I-O Data Device Inc", -[6][0x2a - 1] = "NDS Americas Inc", -[6][0x2b - 1] = "Solomon Systech Limited", -[6][0x2c - 1] = "On Demand Microelectronics", -[6][0x2d - 1] = "Amicus Wireless Inc", -[6][0x2e - 1] = "SMARDTV SNC", -[6][0x2f - 1] = "Comsys Communication Ltd", -[6][0x30 - 1] = "Movidia Ltd", -[6][0x31 - 1] = "Javad GNSS Inc", -[6][0x32 - 1] = "Montage Technology Group", -[6][0x33 - 1] = "Trident Microsystems", -[6][0x34 - 1] = "Super Talent", -[6][0x35 - 1] = "Optichron Inc", -[6][0x36 - 1] = "Future Waves UK Ltd", -[6][0x37 - 1] = "SiBEAM Inc", -[6][0x38 - 1] = "InicoreInc", -[6][0x39 - 1] = "Virident Systems", -[6][0x3a - 1] = "M2000 Inc", -[6][0x3b - 1] = "ZeroG Wireless Inc", -[6][0x3c - 1] = "Gingle Technology Co Ltd", -[6][0x3d - 1] = "Space Micro Inc", -[6][0x3e - 1] = "Wilocity", -[6][0x3f - 1] = "Novafora Inc", -[6][0x40 - 1] = "iKoa Corporation", -[6][0x41 - 1] = "ASint Technology", -[6][0x42 - 1] = "Ramtron", -[6][0x43 - 1] = "Plato Networks Inc", -[6][0x44 - 1] = "IPtronics AS", -[6][0x45 - 1] = "Infinite-Memories", -[6][0x46 - 1] = "Parade Technologies Inc", -[6][0x47 - 1] = "Dune Networks", -[6][0x48 - 1] = "GigaDevice Semiconductor", -[6][0x49 - 1] = "Modu Ltd", -[6][0x4a - 1] = "CEITEC", -[6][0x4b - 1] = "Northrop Grumman", -[6][0x4c - 1] = "XRONET Corporation", -[6][0x4d - 1] = "Sicon Semiconductor AB", -[6][0x4e - 1] = "Atla Electronics Co Ltd", -[6][0x4f - 1] = "TOPRAM Technology", -[6][0x50 - 1] = "Silego Technology Inc", -[6][0x51 - 1] = "Kinglife", -[6][0x52 - 1] = "Ability Industries Ltd", -[6][0x53 - 1] = "Silicon Power Computer & Communications", -[6][0x54 - 1] = "Augusta Technology Inc", -[6][0x55 - 1] = "Nantronics Semiconductors", -[6][0x56 - 1] = "Hilscher Gesellschaft", -[6][0x57 - 1] = "Quixant Ltd", -[6][0x58 - 1] = "Percello Ltd", -[6][0x59 - 1] = "NextIO Inc", -[6][0x5a - 1] = "Scanimetrics Inc", -[6][0x5b - 1] = "FS-Semi Company Ltd", -[6][0x5c - 1] = "Infinera Corporation", -[6][0x5d - 1] = "SandForce Inc", -[6][0x5e - 1] = "Lexar Media", -[6][0x5f - 1] = "Teradyne Inc", -[6][0x60 - 1] = "Memory Exchange Corp", -[6][0x61 - 1] = "Suzhou Smartek Electronics", -[6][0x62 - 1] = "Avantium Corporation", -[6][0x63 - 1] = "ATP Electronics Inc", -[6][0x64 - 1] = "Valens Semiconductor Ltd", -[6][0x65 - 1] = "Agate Logic Inc", -[6][0x66 - 1] = "Netronome", -[6][0x67 - 1] = "Zenverge Inc", -[6][0x68 - 1] = "N-trig Ltd", -[6][0x69 - 1] = "SanMax Technologies Inc", -[6][0x6a - 1] = "Contour Semiconductor Inc", -[6][0x6b - 1] = "TwinMOS", -[6][0x6c - 1] = "Silicon Systems Inc", -[6][0x6d - 1] = "V-Color Technology Inc", -[6][0x6e - 1] = "Certicom Corporation", -[6][0x6f - 1] = "JSC ICC Milandr", -[6][0x70 - 1] = "PhotoFast Global Inc", -[6][0x71 - 1] = "InnoDisk Corporation", -[6][0x72 - 1] = "Muscle Power", -[6][0x73 - 1] = "Energy Micro", -[6][0x74 - 1] = "Innofidei", -[6][0x75 - 1] = "CopperGate Communications", -[6][0x76 - 1] = "Holtek Semiconductor Inc", -[6][0x77 - 1] = "Myson Century Inc", -[6][0x78 - 1] = "FIDELIX", -[6][0x79 - 1] = "Red Digital Cinema", -[6][0x7a - 1] = "Densbits Technology", -[6][0x7b - 1] = "Zempro", -[6][0x7c - 1] = "MoSys", -[6][0x7d - 1] = "Provigent", -[6][0x7e - 1] = "Triad Semiconductor Inc", -[7][0x01 - 1] = "Siklu Communication Ltd", -[7][0x02 - 1] = "A Force Manufacturing Ltd", -[7][0x03 - 1] = "Strontium", -[7][0x04 - 1] = "ALi Corp (Abilis Systems)", -[7][0x05 - 1] = "Siglead Inc", -[7][0x06 - 1] = "Ubicom Inc", -[7][0x07 - 1] = "Unifosa Corporation", -[7][0x08 - 1] = "Stretch Inc", -[7][0x09 - 1] = "Lantiq Deutschland GmbH", -[7][0x0a - 1] = "Visipro.", -[7][0x0b - 1] = "EKMemory", -[7][0x0c - 1] = "Microelectronics Institute ZTE", -[7][0x0d - 1] = "u-blox AG", -[7][0x0e - 1] = "Carry Technology Co Ltd", -[7][0x0f - 1] = "Nokia", -[7][0x10 - 1] = "King Tiger Technology", -[7][0x11 - 1] = "Sierra Wireless", -[7][0x12 - 1] = "HT Micron", -[7][0x13 - 1] = "Albatron Technology Co Ltd", -[7][0x14 - 1] = "Leica Geosystems AG", -[7][0x15 - 1] = "BroadLight", -[7][0x16 - 1] = "AEXEA", -[7][0x17 - 1] = "ClariPhy Communications Inc", -[7][0x18 - 1] = "Green Plug", -[7][0x19 - 1] = "Design Art Networks", -[7][0x1a - 1] = "Mach Xtreme Technology Ltd", -[7][0x1b - 1] = "ATO Solutions Co Ltd", -[7][0x1c - 1] = "Ramsta", -[7][0x1d - 1] = "Greenliant Systems Ltd", -[7][0x1e - 1] = "Teikon", -[7][0x1f - 1] = "Antec Hadron", -[7][0x20 - 1] = "NavCom Technology Inc", -[7][0x21 - 1] = "Shanghai Fudan Microelectronics", -[7][0x22 - 1] = "Calxeda Inc", -[7][0x23 - 1] = "JSC EDC Electronics", -[7][0x24 - 1] = "Kandit Technology Co Ltd", -[7][0x25 - 1] = "Ramos Technology", -[7][0x26 - 1] = "Goldenmars Technology", -[7][0x27 - 1] = "XeL Technology Inc", -[7][0x28 - 1] = "Newzone Corporation", -[7][0x29 - 1] = "ShenZhen MercyPower Tech", -[7][0x2a - 1] = "Nanjing Yihuo Technology", -[7][0x2b - 1] = "Nethra Imaging Inc", -[7][0x2c - 1] = "SiTel Semiconductor BV", -[7][0x2d - 1] = "SolidGear Corporation", -[7][0x2e - 1] = "Topower Computer Ind Co Ltd", -[7][0x2f - 1] = "Wilocity", -[7][0x30 - 1] = "Profichip GmbH", -[7][0x31 - 1] = "Gerad Technologies", -[7][0x32 - 1] = "Ritek Corporation", -[7][0x33 - 1] = "Gomos Technology Limited", -[7][0x34 - 1] = "Memoright Corporation", -[7][0x35 - 1] = "D-Broad Inc", -[7][0x36 - 1] = "HiSilicon Technologies", -[7][0x37 - 1] = "Syndiant Inc.", -[7][0x38 - 1] = "Enverv Inc", -[7][0x39 - 1] = "Cognex", -[7][0x3a - 1] = "Xinnova Technology Inc", -[7][0x3b - 1] = "Ultron AG", -[7][0x3c - 1] = "Concord Idea Corporation", -[7][0x3d - 1] = "AIM Corporation", -[7][0x3e - 1] = "Lifetime Memory Products", -[7][0x3f - 1] = "Ramsway", -[7][0x40 - 1] = "Recore Systems B.V.", -[7][0x41 - 1] = "Haotian Jinshibo Science Tech", -[7][0x42 - 1] = "Being Advanced Memory", -[7][0x43 - 1] = "Adesto Technologies", -[7][0x44 - 1] = "Giantec Semiconductor Inc", -[7][0x45 - 1] = "HMD Electronics AG", -[7][0x46 - 1] = "Gloway International (HK)", -[7][0x47 - 1] = "Kingcore", -[7][0x48 - 1] = "Anucell Technology Holding", -[7][0x49 - 1] = "Accord Software & Systems Pvt. Ltd", -[7][0x4a - 1] = "Active-Semi Inc", -[7][0x4b - 1] = "Denso Corporation", -[7][0x4c - 1] = "TLSI Inc", -[7][0x4d - 1] = "Qidan", -[7][0x4e - 1] = "Mustang", -[7][0x4f - 1] = "Orca Systems", -[7][0x50 - 1] = "Passif Semiconductor", -[7][0x51 - 1] = "GigaDevice Semiconductor (Beijing) Inc", -[7][0x52 - 1] = "Memphis Electronic", -[7][0x53 - 1] = "Beckhoff Automation GmbH", -[7][0x54 - 1] = "Harmony Semiconductor Corp", -[7][0x55 - 1] = "Air Computers SRL", -[7][0x56 - 1] = "TMT Memory", -[7][0x57 - 1] = "Eorex Corporation", -[7][0x58 - 1] = "Xingtera", -[7][0x59 - 1] = "Netsol", -[7][0x5a - 1] = "Bestdon Technology Co Ltd", -[7][0x5b - 1] = "Baysand Inc", -[7][0x5c - 1] = "Uroad Technology Co Ltd", -[7][0x5d - 1] = "Wilk Elektronik S.A.", -[7][0x5e - 1] = "AAI", -[7][0x5f - 1] = "Harman", -[7][0x60 - 1] = "Berg Microelectronics Inc", -[7][0x61 - 1] = "ASSIA Inc", -[7][0x62 - 1] = "Visiontek Products LLC", -[7][0x63 - 1] = "OCMEMORY", -[7][0x64 - 1] = "Welink Solution Inc", -[7][0x65 - 1] = "Shark Gaming", -[7][0x66 - 1] = "Avalanche Technology", -[7][0x67 - 1] = "R&D Center ELVEES OJSC", -[7][0x68 - 1] = "KingboMars Technology Co Ltd", -[7][0x69 - 1] = "High Bridge Solutions Industria Eletronica", -[7][0x6a - 1] = "Transcend Technology Co Ltd", -[7][0x6b - 1] = "Everspin Technologies", -[7][0x6c - 1] = "Hon-Hai Precision", -[7][0x6d - 1] = "Smart Storage Systems", -[7][0x6e - 1] = "Toumaz Group", -[7][0x6f - 1] = "Zentel Electronics Corporation", -[7][0x70 - 1] = "Panram International Corporation", -[7][0x71 - 1] = "Silicon Space Technology", -[7][0x72 - 1] = "LITE-ON IT Corporation", -[7][0x73 - 1] = "Inuitive", -[7][0x74 - 1] = "HMicro", -[7][0x75 - 1] = "BittWare Inc", -[7][0x76 - 1] = "GLOBALFOUNDRIES", -[7][0x77 - 1] = "ACPI Digital Co Ltd", -[7][0x78 - 1] = "Annapurna Labs", -[7][0x79 - 1] = "AcSiP Technology Corporation", -[7][0x7a - 1] = "Idea! Electronic Systems", -[7][0x7b - 1] = "Gowe Technology Co Ltd", -[7][0x7c - 1] = "Hermes Testing Solutions Inc", -[7][0x7d - 1] = "Positivo BGH", -[7][0x7e - 1] = "Intelligence Silicon Technology", -[8][0x01 - 1] = "3D PLUS", -[8][0x02 - 1] = "Diehl Aerospace", -[8][0x03 - 1] = "Fairchild", -[8][0x04 - 1] = "Mercury Systems", -[8][0x05 - 1] = "Sonics Inc", -[8][0x06 - 1] = "Emerson Automation Solutions", -[8][0x07 - 1] = "Shenzhen Jinge Information Co Ltd", -[8][0x08 - 1] = "SCWW", -[8][0x09 - 1] = "Silicon Motion Inc", -[8][0x0a - 1] = "Anurag", -[8][0x0b - 1] = "King Kong", -[8][0x0c - 1] = "FROM30 Co Ltd", -[8][0x0d - 1] = "Gowin Semiconductor Corp", -[8][0x0e - 1] = "Fremont Micro Devices Ltd", -[8][0x0f - 1] = "Ericsson Modems", -[8][0x10 - 1] = "Exelis", -[8][0x11 - 1] = "Satixfy Ltd", -[8][0x12 - 1] = "Galaxy Microsystems Ltd", -[8][0x13 - 1] = "Gloway International Co Ltd", -[8][0x14 - 1] = "Lab", -[8][0x15 - 1] = "Smart Energy Instruments", -[8][0x16 - 1] = "Approved Memory Corporation", -[8][0x17 - 1] = "Axell Corporation", -[8][0x18 - 1] = "Essencore Limited", -[8][0x19 - 1] = "Phytium", -[8][0x1a - 1] = "Xi'an UniIC Semiconductors Co Ltd", -[8][0x1b - 1] = "Ambiq Micro", -[8][0x1c - 1] = "eveRAM Technology Inc", -[8][0x1d - 1] = "Infomax", -[8][0x1e - 1] = "Butterfly Network Inc", -[8][0x1f - 1] = "Shenzhen City Gcai Electronics", -[8][0x20 - 1] = "Stack Devices Corporation", -[8][0x21 - 1] = "ADK Media Group", -[8][0x22 - 1] = "TSP Global Co Ltd", -[8][0x23 - 1] = "HighX", -[8][0x24 - 1] = "Shenzhen Elicks Technology", -[8][0x25 - 1] = "XinKai/Silicon Kaiser", -[8][0x26 - 1] = "Google Inc", -[8][0x27 - 1] = "Dasima International Development", -[8][0x28 - 1] = "Leahkinn Technology Limited", -[8][0x29 - 1] = "HIMA Paul Hildebrandt GmbH Co KG", -[8][0x2a - 1] = "Keysight Technologies", -[8][0x2b - 1] = "Techcomp International (Fastable)", -[8][0x2c - 1] = "Ancore Technology Corporation", -[8][0x2d - 1] = "Nuvoton", -[8][0x2e - 1] = "Korea Uhbele International Group Ltd", -[8][0x2f - 1] = "Ikegami Tsushinki Co Ltd", -[8][0x30 - 1] = "RelChip Inc", -[8][0x31 - 1] = "Baikal Electronics", -[8][0x32 - 1] = "Nemostech Inc", -[8][0x33 - 1] = "Memorysolution GmbH", -[8][0x34 - 1] = "Silicon Integrated Systems Corporation", -[8][0x35 - 1] = "Xiede", -[8][0x36 - 1] = "BRC", -[8][0x37 - 1] = "Flash Chi", -[8][0x38 - 1] = "Jone", -[8][0x39 - 1] = "GCT Semiconductor Inc", -[8][0x3a - 1] = "Hong Kong Zetta Device Technology", -[8][0x3b - 1] = "Unimemory Technology(s) Pte Ltd", -[8][0x3c - 1] = "Cuso", -[8][0x3d - 1] = "Kuso", -[8][0x3e - 1] = "Uniquify Inc", -[8][0x3f - 1] = "Skymedi Corporation", -[8][0x40 - 1] = "Core Chance Co Ltd", -[8][0x41 - 1] = "Tekism Co Ltd", -[8][0x42 - 1] = "Seagate Technology PLC", -[8][0x43 - 1] = "Hong Kong Gaia Group Co Limited", -[8][0x44 - 1] = "Gigacom Semiconductor LLC", -[8][0x45 - 1] = "V2 Technologies", -[8][0x46 - 1] = "TLi", -[8][0x47 - 1] = "Neotion", -[8][0x48 - 1] = "Lenovo", -[8][0x49 - 1] = "Shenzhen Zhongteng Electronic Corp Ltd", -[8][0x4a - 1] = "Compound Photonics", -[8][0x4b - 1] = "in2H2 inc", -[8][0x4c - 1] = "Shenzhen Pango Microsystems Co Ltd", -[8][0x4d - 1] = "Vasekey", -[8][0x4e - 1] = "Cal-Comp Industria de Semicondutores", -[8][0x4f - 1] = "Eyenix Co Ltd", -[8][0x50 - 1] = "Heoriady", -[8][0x51 - 1] = "Accelerated Memory Production Inc", -[8][0x52 - 1] = "INVECAS Inc", -[8][0x53 - 1] = "AP Memory", -[8][0x54 - 1] = "Douqi Technology", -[8][0x55 - 1] = "Etron Technology Inc", -[8][0x56 - 1] = "Indie Semiconductor", -[8][0x57 - 1] = "Socionext Inc", -[8][0x58 - 1] = "HGST", -[8][0x59 - 1] = "EVGA", -[8][0x5a - 1] = "Audience Inc", -[8][0x5b - 1] = "EpicGear", -[8][0x5c - 1] = "Vitesse Enterprise Co", -[8][0x5d - 1] = "Foxtronn International Corporation", -[8][0x5e - 1] = "Bretelon Inc", -[8][0x5f - 1] = "Graphcore", -[8][0x60 - 1] = "Eoplex Inc", -[8][0x61 - 1] = "MaxLinear Inc", -[8][0x62 - 1] = "ETA Devices", -[8][0x63 - 1] = "LOKI", -[8][0x64 - 1] = "IMS Electronics Co Ltd", -[8][0x65 - 1] = "Dosilicon Co Ltd", -[8][0x66 - 1] = "Dolphin Integration", -[8][0x67 - 1] = "Shenzhen Mic Electronics Technolog", -[8][0x68 - 1] = "Boya Microelectronics Inc", -[8][0x69 - 1] = "Geniachip (Roche)", -[8][0x6a - 1] = "Axign", -[8][0x6b - 1] = "Kingred Electronic Technology Ltd", -[8][0x6c - 1] = "Chao Yue Zhuo Computer Business Dept.", -[8][0x6d - 1] = "Guangzhou Si Nuo Electronic Technology.", -[8][0x6e - 1] = "Crocus Technology Inc", -[8][0x6f - 1] = "Creative Chips GmbH", -[8][0x70 - 1] = "GE Aviation Systems LLC.", -[8][0x71 - 1] = "Asgard", -[8][0x72 - 1] = "Good Wealth Technology Ltd", -[8][0x73 - 1] = "TriCor Technologies", -[8][0x74 - 1] = "Nova-Systems GmbH", -[8][0x75 - 1] = "JUHOR", -[8][0x76 - 1] = "Zhuhai Douke Commerce Co Ltd", -[8][0x77 - 1] = "DSL Memory", -[8][0x78 - 1] = "Anvo-Systems Dresden GmbH", -[8][0x79 - 1] = "Realtek", -[8][0x7a - 1] = "AltoBeam", -[8][0x7b - 1] = "Wave Computing", -[8][0x7c - 1] = "Beijing TrustNet Technology Co Ltd", -[8][0x7d - 1] = "Innovium Inc", -[8][0x7e - 1] = "Starsway Technology Limited", -[9][0x01 - 1] = "Weltronics Co LTD", -[9][0x02 - 1] = "VMware Inc", -[9][0x03 - 1] = "Hewlett Packard Enterprise", -[9][0x04 - 1] = "INTENSO", -[9][0x05 - 1] = "Puya Semiconductor", -[9][0x06 - 1] = "MEMORFI", -[9][0x07 - 1] = "MSC Technologies GmbH", -[9][0x08 - 1] = "Txrui", -[9][0x09 - 1] = "SiFive Inc", -[9][0x0a - 1] = "Spreadtrum Communications", -[9][0x0b - 1] = "XTX Technology Limited", -[9][0x0c - 1] = "UMAX Technology", -[9][0x0d - 1] = "Shenzhen Yong Sheng Technology", -[9][0x0e - 1] = "SNOAMOO (Shenzhen Kai Zhuo Yue)", -[9][0x0f - 1] = "Daten Tecnologia LTDA", -[9][0x10 - 1] = "Shenzhen XinRuiYan Electronics", -[9][0x11 - 1] = "Eta Compute", -[9][0x12 - 1] = "Energous", -[9][0x13 - 1] = "Raspberry Pi Trading Ltd", -[9][0x14 - 1] = "Shenzhen Chixingzhe Tech Co Ltd", -[9][0x15 - 1] = "Silicon Mobility", -[9][0x16 - 1] = "IQ-Analog Corporation", -[9][0x17 - 1] = "Uhnder Inc", -[9][0x18 - 1] = "Impinj", -[9][0x19 - 1] = "DEPO Computers", -[9][0x1a - 1] = "Nespeed Sysems", -[9][0x1b - 1] = "Yangtze Memory Technologies Co Ltd", -[9][0x1c - 1] = "MemxPro Inc", -[9][0x1d - 1] = "Tammuz Co Ltd", -[9][0x1e - 1] = "Allwinner Technology", -[9][0x1f - 1] = "Shenzhen City Futian District Qing Xuan Tong Computer Trading Firm", -[9][0x20 - 1] = "XMC", -[9][0x21 - 1] = "Teclast", -[9][0x22 - 1] = "Maxsun", -[9][0x23 - 1] = "Haiguang Integrated Circuit Design", -[9][0x24 - 1] = "RamCENTER Technology", -[9][0x25 - 1] = "Phison Electronics Corporation", -[9][0x26 - 1] = "Guizhou Huaxintong Semi-Conductor", -[9][0x27 - 1] = "Network Intelligence", -[9][0x28 - 1] = "Continental Technology (Holdings)", -[9][0x29 - 1] = "Guangzhou Huayan Suning Electronic", -[9][0x2a - 1] = "Guangzhou Zhouji Electronic Co Ltd", -[9][0x2b - 1] = "Shenzhen Giant Hui Kang Tech Co Ltd", -[9][0x2c - 1] = "Shenzhen Yilong Innovative Co Ltd", -[9][0x2d - 1] = "Neo Forza", -[9][0x2e - 1] = "Lyontek Inc", -[9][0x2f - 1] = "Shanghai Kuxin Microelectronics Ltd", -[9][0x30 - 1] = "Shenzhen Larix Technology Co Ltd", -[9][0x31 - 1] = "Qbit Semiconductor Ltd", -[9][0x32 - 1] = "Insignis Technology Corporation", -[9][0x33 - 1] = "Lanson Memory Co Ltd", -[9][0x34 - 1] = "Shenzhen Superway Electronics Co Ltd", -[9][0x35 - 1] = "Canaan-Creative Co Ltd", -[9][0x36 - 1] = "Black Diamond Memory", -[9][0x37 - 1] = "Shenzhen City Parker Baking Electronics", -[9][0x38 - 1] = "Shenzhen Baihong Technology Co Ltd", -[9][0x39 - 1] = "GEO Semiconductors", -[9][0x3a - 1] = "OCPC", -[9][0x3b - 1] = "Artery Technology Co Ltd", -[9][0x3c - 1] = "Jinyu", -[9][0x3d - 1] = "ShenzhenYing Chi Technology Development", -[9][0x3e - 1] = "Shenzhen Pengcheng Xin Technology", -[9][0x3f - 1] = "Pegasus Semiconductor (Shanghai) Co", -[9][0x40 - 1] = "Mythic Inc", -[9][0x41 - 1] = "Elmos Semiconductor AG", -[9][0x42 - 1] = "Kllisre", -[9][0x43 - 1] = "Shenzhen Winconway Technology", -[9][0x44 - 1] = "Shenzhen Xingmem Technology Corp", -[9][0x45 - 1] = "Gold Key Technology Co Ltd", -[9][0x46 - 1] = "Habana Labs Ltd", -[9][0x47 - 1] = "Hoodisk Electronics Co Ltd", -[9][0x48 - 1] = "SemsoTai (SZ) Technology Co Ltd", -[9][0x49 - 1] = "OM Nanotech Pvt. Ltd", -[9][0x4a - 1] = "Shenzhen Zhifeng Weiye Technology", -[9][0x4b - 1] = "Xinshirui (Shenzhen) Electronics Co", -[9][0x4c - 1] = "Guangzhou Zhong Hao Tian Electronic", -[9][0x4d - 1] = "Shenzhen Longsys Electronics Co Ltd", -[9][0x4e - 1] = "Deciso B.V.", -[9][0x4f - 1] = "Puya Semiconductor (Shenzhen)", -[9][0x50 - 1] = "Shenzhen Veineda Technology Co Ltd", -[9][0x51 - 1] = "Antec Memory", -[9][0x52 - 1] = "Cortus SAS", -[9][0x53 - 1] = "Dust Leopard", -[9][0x54 - 1] = "MyWo AS", -[9][0x55 - 1] = "J&A Information Inc", -[9][0x56 - 1] = "Shenzhen JIEPEI Technology Co Ltd", -[9][0x57 - 1] = "Heidelberg University", -[9][0x58 - 1] = "Flexxon PTE Ltd", -[9][0x59 - 1] = "Wiliot", -[9][0x5a - 1] = "Raysun Electronics International Ltd", -[9][0x5b - 1] = "Aquarius Production Company LLC", -[9][0x5c - 1] = "MACNICA DHW LTDA", -[9][0x5d - 1] = "Intelimem", -[9][0x5e - 1] = "Zbit Semiconductor Inc", -[9][0x5f - 1] = "Shenzhen Technology Co Ltd", -[9][0x60 - 1] = "Signalchip", -[9][0x61 - 1] = "Shenzen Recadata Storage Technology", -[9][0x62 - 1] = "Hyundai Technology", -[9][0x63 - 1] = "Shanghai Fudi Investment Development", -[9][0x64 - 1] = "Aixi Technology", -[9][0x65 - 1] = "Tecon MT", -[9][0x66 - 1] = "Onda Electric Co Ltd", -[9][0x67 - 1] = "Jinshen", -[9][0x68 - 1] = "Kimtigo Semiconductor (HK) Limited", -[9][0x69 - 1] = "IIT Madras", -[9][0x6a - 1] = "Shenshan (Shenzhen) Electronic", -[9][0x6b - 1] = "Hefei Core Storage Electronic Limited", -[9][0x6c - 1] = "Colorful Technology Ltd", -[9][0x6d - 1] = "Visenta (Xiamen) Technology Co Ltd", -[9][0x6e - 1] = "Roa Logic BV", -[9][0x6f - 1] = "NSITEXE Inc", -[9][0x70 - 1] = "Hong Kong Hyunion Electronics", -[9][0x71 - 1] = "ASK Technology Group Limited", -[9][0x72 - 1] = "GIGA-BYTE Technology Co Ltd", -[9][0x73 - 1] = "Terabyte Co Ltd", -[9][0x74 - 1] = "Hyundai Inc", -[9][0x75 - 1] = "EXCELERAM", -[9][0x76 - 1] = "PsiKick", -[9][0x77 - 1] = "Netac Technology Co Ltd", -[9][0x78 - 1] = "PCCOOLER", -[9][0x79 - 1] = "Jiangsu Huacun Electronic Technology", -[9][0x7a - 1] = "Shenzhen Micro Innovation Industry", -[9][0x7b - 1] = "Beijing Tongfang Microelectronics Co", -[9][0x7c - 1] = "XZN Storage Technology", -[9][0x7d - 1] = "ChipCraft Sp. z.o.o.", -[9][0x7e - 1] = "ALLFLASH Technology Limited", -[10][0x01 - 1] = "Foerd Technology Co Ltd", -[10][0x02 - 1] = "KingSpec", -[10][0x03 - 1] = "Codasip GmbH", -[10][0x04 - 1] = "SL Link Co Ltd", -[10][0x05 - 1] = "Shenzhen Kefu Technology Co Limited", -[10][0x06 - 1] = "Shenzhen ZST Electronics Technology", -[10][0x07 - 1] = "Kyokuto Electronic Inc", -[10][0x08 - 1] = "Warrior Technology", -[10][0x09 - 1] = "TRINAMIC Motion Control GmbH & Co", -[10][0x0a - 1] = "PixelDisplay Inc", -[10][0x0b - 1] = "Shenzhen Futian District Bo Yueda Elec", -[10][0x0c - 1] = "Richtek Power", -[10][0x0d - 1] = "Shenzhen LianTeng Electronics Co Ltd", -[10][0x0e - 1] = "AITC Memory", -[10][0x0f - 1] = "UNIC Memory Technology Co Ltd", -[10][0x10 - 1] = "Shenzhen Huafeng Science Technology", -[10][0x11 - 1] = "CXMT", -[10][0x12 - 1] = "Guangzhou Xinyi Heng Computer Trading Firm", -[10][0x13 - 1] = "SambaNova Systems", -[10][0x14 - 1] = "V-GEN", -[10][0x15 - 1] = "Jump Trading", -[10][0x16 - 1] = "Ampere Computing", -[10][0x17 - 1] = "Shenzhen Zhongshi Technology Co Ltd", -[10][0x18 - 1] = "Shenzhen Zhongtian Bozhong Technology", -[10][0x19 - 1] = "Tri-Tech International", -[10][0x1a - 1] = "Silicon Intergrated Systems Corporation", -[10][0x1b - 1] = "Shenzhen HongDingChen Information", -[10][0x1c - 1] = "Plexton Holdings Limited", -[10][0x1d - 1] = "AMS (Jiangsu Advanced Memory Semi)", -[10][0x1e - 1] = "Wuhan Jing Tian Interconnected Tech Co", -[10][0x1f - 1] = "Axia Memory Technology", -[10][0x20 - 1] = "Chipset Technology Holding Limited", -[10][0x21 - 1] = "Shenzhen Xinshida Technology Co Ltd", -[10][0x22 - 1] = "Shenzhen Chuangshifeida Technology", -[10][0x23 - 1] = "Guangzhou MiaoYuanJi Technology", -[10][0x24 - 1] = "ADVAN Inc", -[10][0x25 - 1] = "Shenzhen Qianhai Weishengda Electronic Commerce Company Ltd", -[10][0x26 - 1] = "Guangzhou Guang Xie Cheng Trading", -[10][0x27 - 1] = "StarRam International Co Ltd", -[10][0x28 - 1] = "Shen Zhen XinShenHua Tech Co Ltd", -[10][0x29 - 1] = "UltraMemory Inc", -[10][0x2a - 1] = "New Coastline Global Tech Industry Co", -[10][0x2b - 1] = "Sinker", -[10][0x2c - 1] = "Diamond", -[10][0x2d - 1] = "PUSKILL", -[10][0x2e - 1] = "Guangzhou Hao Jia Ye Technology Co", -[10][0x2f - 1] = "Ming Xin Limited", -[10][0x30 - 1] = "Barefoot Networks", -[10][0x31 - 1] = "Biwin Semiconductor (HK) Co Ltd", -[10][0x32 - 1] = "UD INFO Corporation", -[10][0x33 - 1] = "Trek Technology (S) PTE Ltd", -[10][0x34 - 1] = "Xiamen Kingblaze Technology Co Ltd", -[10][0x35 - 1] = "Shenzhen Lomica Technology Co Ltd", -[10][0x36 - 1] = "Nuclei System Technology Co Ltd", -[10][0x37 - 1] = "Wuhan Xun Zhan Electronic Technology", -[10][0x38 - 1] = "Shenzhen Ingacom Semiconductor Ltd", -[10][0x39 - 1] = "Zotac Technology Ltd", -[10][0x3a - 1] = "Foxline", -[10][0x3b - 1] = "Shenzhen Farasia Science Technology", -[10][0x3c - 1] = "Efinix Inc", -[10][0x3d - 1] = "Hua Nan San Xian Technology Co Ltd", -[10][0x3e - 1] = "Goldtech Electronics Co Ltd", -[10][0x3f - 1] = "Shanghai Han Rong Microelectronics Co", -[10][0x40 - 1] = "Shenzhen Zhongguang Yunhe Trading", -[10][0x41 - 1] = "Smart Shine(QingDao) Microelectronics", -[10][0x42 - 1] = "Thermaltake Technology Co Ltd", -[10][0x43 - 1] = "Shenzhen O'Yang Maile Technology Ltd", -[10][0x44 - 1] = "UPMEM", -[10][0x45 - 1] = "Chun Well Technology Holding Limited", -[10][0x46 - 1] = "Astera Labs Inc", -[10][0x47 - 1] = "Winconway", -[10][0x48 - 1] = "Advantech Co Ltd", -[10][0x49 - 1] = "Chengdu Fengcai Electronic Technology", -[10][0x4a - 1] = "The Boeing Company", -[10][0x4b - 1] = "Blaize Inc", -[10][0x4c - 1] = "Ramonster Technology Co Ltd", -[10][0x4d - 1] = "Wuhan Naonongmai Technology Co Ltd", -[10][0x4e - 1] = "Shenzhen Hui ShingTong Technology", -[10][0x4f - 1] = "Yourlyon", -[10][0x50 - 1] = "Fabu Technology", -[10][0x51 - 1] = "Shenzhen Yikesheng Technology Co Ltd", -[10][0x52 - 1] = "NOR-MEM", -[10][0x53 - 1] = "Cervoz Co Ltd", -[10][0x54 - 1] = "Bitmain Technologies Inc.", -[10][0x55 - 1] = "Facebook Inc", -[10][0x56 - 1] = "Shenzhen Longsys Electronics Co Ltd", -[10][0x57 - 1] = "Guangzhou Siye Electronic Technology", -[10][0x58 - 1] = "Silergy", -[10][0x59 - 1] = "Adamway", -[10][0x5a - 1] = "PZG", -[10][0x5b - 1] = "Shenzhen King Power Electronics", -[10][0x5c - 1] = "Guangzhou ZiaoFu Tranding Co Ltd", -[10][0x5d - 1] = "Shenzhen SKIHOTAR Semiconductor", -[10][0x5e - 1] = "PulseRain Technology", -[10][0x5f - 1] = "Seeker Technology Limited", -[10][0x60 - 1] = "Shenzhen OSCOO Tech Co Ltd", -[10][0x61 - 1] = "Shenzhen Yze Technology Co Ltd", -[10][0x62 - 1] = "Shenzhen Jieshuo Electronic Commerce", -[10][0x63 - 1] = "Gazda", -[10][0x64 - 1] = "Hua Wei Technology Co Ltd", -[10][0x65 - 1] = "Esperanto Technologies", -[10][0x66 - 1] = "JinSheng Electronic (Shenzhen) Co Ltd", -[10][0x67 - 1] = "Shenzhen Shi Bolunshuai Technology", -[10][0x68 - 1] = "Shanghai Rei Zuan Information Tech", -[10][0x69 - 1] = "Fraunhofer IIS", -[10][0x6a - 1] = "Kandou Bus SA", -[10][0x6b - 1] = "Acer", -[10][0x6c - 1] = "Artmem Technology Co Ltd", -[10][0x6d - 1] = "Gstar Semiconductor Co Ltd", -[10][0x6e - 1] = "ShineDisk", -[10][0x6f - 1] = "Shenzhen CHN Technology Co Ltd", -[10][0x70 - 1] = "UnionChip Semiconductor Co Ltd", -[10][0x71 - 1] = "Tanbassh", -[10][0x72 - 1] = "Shenzhen Tianyu Jieyun Intl Logistics", -[10][0x73 - 1] = "MCLogic Inc", -[10][0x74 - 1] = "Eorex Corporation", -[10][0x75 - 1] = "Arm Technology (China) Co Ltd", -[10][0x76 - 1] = "Lexar Co Limited", -[10][0x77 - 1] = "QinetiQ Group plc", -[10][0x78 - 1] = "Exascend", -[10][0x79 - 1] = "Hong Kong Hyunion Electronics Co Ltd", -[10][0x7a - 1] = "Shenzhen Banghong Electronics Co Ltd", -[10][0x7b - 1] = "MBit Wireless Inc", -[10][0x7c - 1] = "Hex Five Security Inc", -[10][0x7d - 1] = "ShenZhen Juhor Precision Tech Co Ltd", -[10][0x7e - 1] = "Shenzhen Reeinno Technology Co Ltd", -[11][0x01 - 1] = "ABIT Electronics (Shenzhen) Co Ltd", -[11][0x02 - 1] = "Semidrive", -[11][0x03 - 1] = "MyTek Electronics Corp", -[11][0x04 - 1] = "Wxilicon Technology Co Ltd", -[11][0x05 - 1] = "Shenzhen Meixin Electronics Ltd", -[11][0x06 - 1] = "Ghost Wolf", -[11][0x07 - 1] = "LiSion Technologies Inc", -[11][0x08 - 1] = "Power Active Co Ltd", -[11][0x09 - 1] = "Pioneer High Fidelity Taiwan Co. Ltd", -[11][0x0a - 1] = "LuoSilk", -[11][0x0b - 1] = "Shenzhen Chuangshifeida Technology", -[11][0x0c - 1] = "Black Sesame Technologies Inc", -[11][0x0d - 1] = "Jiangsu Xinsheng Intelligent Technology", -[11][0x0e - 1] = "MLOONG", -[11][0x0f - 1] = "Quadratica LLC", -[11][0x10 - 1] = "Anpec Electronics", -[11][0x11 - 1] = "Xi'an Morebeck Semiconductor Tech Co", -[11][0x12 - 1] = "Kingbank Technology Co Ltd", -[11][0x13 - 1] = "ITRenew Inc", -[11][0x14 - 1] = "Shenzhen Eaget Innovation Tech Ltd", -[11][0x15 - 1] = "Jazer", -[11][0x16 - 1] = "Xiamen Semiconductor Investment Group", -[11][0x17 - 1] = "Guangzhou Longdao Network Tech Co", -[11][0x18 - 1] = "Shenzhen Futian SEC Electronic Market", -[11][0x19 - 1] = "Allegro Microsystems LLC", -[11][0x1a - 1] = "Hunan RunCore Innovation Technology", -[11][0x1b - 1] = "C-Corsa Technology", -[11][0x1c - 1] = "Zhuhai Chuangfeixin Technology Co Ltd", -[11][0x1d - 1] = "Beijing InnoMem Technologies Co Ltd", -[11][0x1e - 1] = "YooTin", -[11][0x1f - 1] = "Shenzhen Pengxiong Technology Co Ltd", -[11][0x20 - 1] = "Dongguan Yingbang Commercial Trading Co", -[11][0x21 - 1] = "Shenzhen Ronisys Electronics Co Ltd", -[11][0x22 - 1] = "Hongkong Xinlan Guangke Co Ltd", -[11][0x23 - 1] = "Apex Microelectronics Co Ltd", -[11][0x24 - 1] = "Beijing Hongda Jinming Technology Co Ltd", -[11][0x25 - 1] = "Ling Rui Technology (Shenzhen) Co Ltd", -[11][0x26 - 1] = "Hongkong Hyunion Electronics Co Ltd", -[11][0x27 - 1] = "Starsystems Inc", -[11][0x28 - 1] = "Shenzhen Yingjiaxun Industrial Co Ltd", -[11][0x29 - 1] = "Dongguan Crown Code Electronic Commerce", -[11][0x2a - 1] = "Monolithic Power Systems Inc", -[11][0x2b - 1] = "WuHan SenNaiBo E-Commerce Co Ltd", -[11][0x2c - 1] = "Hangzhou Hikstorage Technology Co", -[11][0x2d - 1] = "Shenzhen Goodix Technology Co Ltd", -[11][0x2e - 1] = "Aigo Electronic Technology Co Ltd", -[11][0x2f - 1] = "Hefei Konsemi Storage Technology Co Ltd", -[11][0x30 - 1] = "Cactus Technologies Limited", -[11][0x31 - 1] = "DSIN", -[11][0x32 - 1] = "Blu Wireless Technology", -[11][0x33 - 1] = "Nanjing UCUN Technology Inc", -[11][0x34 - 1] = "Acacia Communications", -[11][0x35 - 1] = "Beijinjinshengyihe Technology Co Ltd", -[11][0x36 - 1] = "Zyzyx", -[11][0x37 - 1] = "T-HEAD Semiconductor Co Ltd", -[11][0x38 - 1] = "Shenzhen Hystou Technology Co Ltd", -[11][0x39 - 1] = "Syzexion", -[11][0x3a - 1] = "Kembona", -[11][0x3b - 1] = "Qingdao Thunderobot Technology Co Ltd", -[11][0x3c - 1] = "Morse Micro", -[11][0x3d - 1] = "Shenzhen Envida Technology Co Ltd", -[11][0x3e - 1] = "UDStore Solution Limited", -[11][0x3f - 1] = "Shunlie", -[11][0x40 - 1] = "Shenzhen Xin Hong Rui Tech Ltd", -[11][0x41 - 1] = "Shenzhen Yze Technology Co Ltd", -[11][0x42 - 1] = "Shenzhen Huang Pu He Xin Technology", -[11][0x43 - 1] = "Xiamen Pengpai Microelectronics Co Ltd", -[11][0x44 - 1] = "JISHUN", -[11][0x45 - 1] = "Shenzhen WODPOSIT Technology Co", -[11][0x46 - 1] = "Unistar", -[11][0x47 - 1] = "UNICORE Electronic (Suzhou) Co Ltd", -[11][0x48 - 1] = "Axonne Inc", -[11][0x49 - 1] = "Shenzhen SOVERECA Technology Co", -[11][0x4a - 1] = "Dire Wolf", -[11][0x4b - 1] = "Whampoa Core Technology Co Ltd", -[11][0x4c - 1] = "CSI Halbleiter GmbH", -[11][0x4d - 1] = "ONE Semiconductor", -[11][0x4e - 1] = "SimpleMachines Inc", -[11][0x4f - 1] = "Shenzhen Chengyi Qingdian Electronic", -[11][0x50 - 1] = "Shenzhen Xinlianxin Network Technology", -[11][0x51 - 1] = "Vayyar Imaging Ltd", -[11][0x52 - 1] = "Paisen Network Technology Co Ltd", -[11][0x53 - 1] = "Shenzhen Fengwensi Technology Co Ltd", -[11][0x54 - 1] = "Caplink Technology Limited", -[11][0x55 - 1] = "JJT Solution Co Ltd", -[11][0x56 - 1] = "HOSIN Global Electronics Co Ltd", -[11][0x57 - 1] = "Shenzhen KingDisk Century Technology", -[11][0x58 - 1] = "SOYO", -[11][0x59 - 1] = "DIT Technology Co Ltd", -[11][0x5a - 1] = "iFound", -[11][0x5b - 1] = "Aril Computer Company", -[11][0x5c - 1] = "ASUS", -[11][0x5d - 1] = "Shenzhen Ruiyingtong Technology Co", -[11][0x5e - 1] = "HANA Micron", -[11][0x5f - 1] = "RANSOR", -[11][0x60 - 1] = "Axiado Corporation", -[11][0x61 - 1] = "Tesla Corporation", -[11][0x62 - 1] = "Pingtouge (Shanghai) Semiconductor Co", -[11][0x63 - 1] = "S3Plus Technologies SA", -[11][0x64 - 1] = "Integrated Silicon Solution Israel Ltd", -[11][0x65 - 1] = "GreenWaves Technologies", -[11][0x66 - 1] = "NUVIA Inc", -[11][0x67 - 1] = "Guangzhou Shuvrwine Technology Co", -[11][0x68 - 1] = "Shenzhen Hangshun Chip Technology", -[11][0x69 - 1] = "Chengboliwei Electronic Business", -[11][0x6a - 1] = "Kowin Technology HK Limited", -[11][0x6b - 1] = "Euronet Technology Inc", -[11][0x6c - 1] = "SCY", -[11][0x6d - 1] = "Shenzhen Xinhongyusheng Electrical", -[11][0x6e - 1] = "PICOCOM", -[11][0x6f - 1] = "Shenzhen Toooogo Memory Technology", -[11][0x70 - 1] = "VLSI Solution", -[11][0x71 - 1] = "Costar Electronics Inc", -[11][0x72 - 1] = "Shenzhen Huatop Technology Co Ltd", -[11][0x73 - 1] = "Inspur Electronic Information Industry", -[11][0x74 - 1] = "Shenzhen Boyuan Computer Technology", -[11][0x75 - 1] = "Beijing Welldisk Electronics Co Ltd", -[11][0x76 - 1] = "Suzhou EP Semicon Co Ltd", -[11][0x77 - 1] = "Zhejiang Dahua Memory Technology", -[11][0x78 - 1] = "Virtu Financial", -[11][0x79 - 1] = "Datotek International Co Ltd", -[11][0x7a - 1] = "Telecom and Microelectronics Industries", -[11][0x7b - 1] = "Echow Technology Ltd", -[11][0x7c - 1] = "APEX-INFO", -[11][0x7d - 1] = "Yingpark", -[11][0x7e - 1] = "Shenzhen Bigway Tech Co Ltd", -[12][0x01 - 1] = "Beijing Haawking Technology Co Ltd", -[12][0x02 - 1] = "Open HW Group", -[12][0x03 - 1] = "JHICC", -[12][0x04 - 1] = "ncoder AG", -[12][0x05 - 1] = "ThinkTech Information Technology Co", -[12][0x06 - 1] = "Shenzhen Chixingzhe Technology Co Ltd", -[12][0x07 - 1] = "Biao Ram Technology Co Ltd", -[12][0x08 - 1] = "Shenzhen Kaizhuoyue Electronics Co Ltd", -[12][0x09 - 1] = "Shenzhen YC Storage Technology Co Ltd", -[12][0x0a - 1] = "Shenzhen Chixingzhe Technology Co", -[12][0x0b - 1] = "Wink Semiconductor (Shenzhen) Co Ltd", -[12][0x0c - 1] = "AISTOR", -[12][0x0d - 1] = "Palma Ceia SemiDesign", -[12][0x0e - 1] = "EM Microelectronic-Marin SA", -[12][0x0f - 1] = "Shenzhen Monarch Memory Technology", -[12][0x10 - 1] = "Reliance Memory Inc", -[12][0x11 - 1] = "Jesis", -[12][0x12 - 1] = "Espressif Systems (Shanghai) Co Ltd", -[12][0x13 - 1] = "Shenzhen Sati Smart Technology Co Ltd", -[12][0x14 - 1] = "NeuMem Co Ltd", -[12][0x15 - 1] = "Lifelong", -[12][0x16 - 1] = "Beijing Oitech Technology Co Ltd", -[12][0x17 - 1] = "Groupe LDLC", -[12][0x18 - 1] = "Semidynamics Technology Services SLU", -[12][0x19 - 1] = "swordbill", -[12][0x1a - 1] = "YIREN", -[12][0x1b - 1] = "Shenzhen Yinxiang Technology Co Ltd", -[12][0x1c - 1] = "PoweV Electronic Technology Co Ltd", -[12][0x1d - 1] = "LEORICE", -[12][0x1e - 1] = "Waymo LLC", -[12][0x1f - 1] = "Ventana Micro Systems", -[12][0x20 - 1] = "Hefei Guangxin Microelectronics Co Ltd", -[12][0x21 - 1] = "Shenzhen Sooner Industrial Co Ltd", -[12][0x22 - 1] = "Horizon Robotics", -[12][0x23 - 1] = "Tangem AG", -[12][0x24 - 1] = "FuturePath Technology (Shenzhen) Co", -[12][0x25 - 1] = "RC Module", -[12][0x26 - 1] = "Timetec International Inc", -[12][0x27 - 1] = "ICMAX Technologies Co Limited", -[12][0x28 - 1] = "Lynxi Technologies Ltd Co", -[12][0x29 - 1] = "Guangzhou Taisupanke Computer Equipment", -[12][0x2a - 1] = "Ceremorphic Inc", -[12][0x2b - 1] = "Biwin Storage Technology Co Ltd", -[12][0x2c - 1] = "Beijing ESWIN Computing Technology", -[12][0x2d - 1] = "WeForce Co Ltd", -[12][0x2e - 1] = "Shenzhen Fanxiang Information Technology", -[12][0x2f - 1] = "Unisoc", -[12][0x30 - 1] = "YingChu", -[12][0x31 - 1] = "GUANCUN", -[12][0x32 - 1] = "IPASON", -[12][0x33 - 1] = "Ayar Labs", -[12][0x34 - 1] = "Amazon", -[12][0x35 - 1] = "Shenzhen Xinxinshun Technology Co", -[12][0x36 - 1] = "Galois Inc", -[12][0x37 - 1] = "Ubilite Inc", -[12][0x38 - 1] = "Shenzhen Quanxing Technology Co Ltd", -[12][0x39 - 1] = "Group RZX Technology LTDA", -[12][0x3a - 1] = "Yottac Technology (XI'AN) Cooperation", -[12][0x3b - 1] = "Shenzhen RuiRen Technology Co Ltd", -[12][0x3c - 1] = "Group Star Technology Co Ltd", -[12][0x3d - 1] = "RWA (Hong Kong) Ltd", -[12][0x3e - 1] = "Genesys Logic Inc", -[12][0x3f - 1] = "T3 Robotics Inc.", -[12][0x40 - 1] = "Biostar Microtech International Corp", -[12][0x41 - 1] = "Shenzhen SXmicro Technology Co Ltd", -[12][0x42 - 1] = "Shanghai Yili Computer Technology Co", -[12][0x43 - 1] = "Zhixin Semicoducotor Co Ltd", -[12][0x44 - 1] = "uFound", -[12][0x45 - 1] = "Aigo Data Security Technology Co. Ltd", -[12][0x46 - 1] = ".GXore Technologies", -[12][0x47 - 1] = "Shenzhen Pradeon Intelligent Technology", -[12][0x48 - 1] = "Power LSI", -[12][0x49 - 1] = "PRIME", -[12][0x4a - 1] = "Shenzhen Juyang Innovative Technology", -[12][0x4b - 1] = "CERVO", -[12][0x4c - 1] = "SiEngine Technology Co., Ltd.", -[12][0x4d - 1] = "Beijing Unigroup Tsingteng MicroSystem", -[12][0x4e - 1] = "Brainsao GmbH", -[12][0x4f - 1] = "Credo Technology Group Ltd", -[12][0x50 - 1] = "Shanghai Biren Technology Co Ltd", -[12][0x51 - 1] = "Nucleu Semiconductor", -[12][0x52 - 1] = "Shenzhen Guangshuo Electronics Co Ltd", -[12][0x53 - 1] = "ZhongsihangTechnology Co Ltd", -[12][0x54 - 1] = "Suzhou Mainshine Electronic Co Ltd.", -[12][0x55 - 1] = "Guangzhou Riss Electronic Technology", -[12][0x56 - 1] = "Shenzhen Cloud Security Storage Co", -[12][0x57 - 1] = "ROG", -[12][0x58 - 1] = "Perceive", -[12][0x59 - 1] = "e-peas", -[12][0x5a - 1] = "Fraunhofer IPMS", -[12][0x5b - 1] = "Shenzhen Daxinlang Electronic Tech Co", -[12][0x5c - 1] = "Abacus Peripherals Private Limited", -[12][0x5d - 1] = "OLOy Technology", -[12][0x5e - 1] = "Wuhan P&S Semiconductor Co Ltd", -[12][0x5f - 1] = "Sitrus Technology", -[12][0x60 - 1] = "AnHui Conner Storage Co Ltd", -[12][0x61 - 1] = "Rochester Electronics", -[12][0x62 - 1] = "Wuxi Petabyte Technologies Co Ltd", -[12][0x63 - 1] = "Star Memory", -[12][0x64 - 1] = "Agile Memory Technology Co Ltd", -[12][0x65 - 1] = "MEJEC", -[12][0x66 - 1] = "Rockchip Electronics Co Ltd", -[12][0x67 - 1] = "Dongguan Guanma e-commerce Co Ltd", -[12][0x68 - 1] = "Rayson Hi-Tech (SZ) Limited", -[12][0x69 - 1] = "MINRES Technologies GmbH", -[12][0x6a - 1] = "Himax Technologies Inc", -[12][0x6b - 1] = "Shenzhen Cwinner Technology Co Ltd", -[12][0x6c - 1] = "Tecmiyo", -[12][0x6d - 1] = "Shenzhen Suhuicun Technology Co Ltd", -[12][0x6e - 1] = "Vickter Electronics Co. Ltd.", -[12][0x6f - 1] = "lowRISC", -[12][0x70 - 1] = "EXEGate FZE", -[12][0x71 - 1] = "Shenzhen 9 Chapter Technologies Co", -[12][0x72 - 1] = "Addlink", -[12][0x73 - 1] = "Starsway", -[12][0x74 - 1] = "Pensando Systems Inc.", -[12][0x75 - 1] = "AirDisk", -[12][0x76 - 1] = "Shenzhen Speedmobile Technology Co", -[12][0x77 - 1] = "PEZY Computing", -[12][0x78 - 1] = "Extreme Engineering Solutions Inc", -[12][0x79 - 1] = "Shangxin Technology Co Ltd", -[12][0x7a - 1] = "Shanghai Zhaoxin Semiconductor Co", -[12][0x7b - 1] = "Xsight Labs Ltd", -[12][0x7c - 1] = "Hangzhou Hikstorage Technology Co", -[12][0x7d - 1] = "Dell Technologies", -[12][0x7e - 1] = "Guangdong StarFive Technology Co", -[13][0x01 - 1] = "TECOTON", -[13][0x02 - 1] = "Abko Co Ltd", -[13][0x03 - 1] = "Shenzhen Feisrike Technology Co Ltd", -[13][0x04 - 1] = "Shenzhen Sunhome Electronics Co Ltd", -[13][0x05 - 1] = "Global Mixed-mode Technology Inc", -[13][0x06 - 1] = "Shenzhen Weien Electronics Co. Ltd.", -[13][0x07 - 1] = "Shenzhen Cooyes Technology Co Ltd", -[13][0x08 - 1] = "Keymos Electronics Co., Limited", -[13][0x09 - 1] = "E-Rockic Technology Company Limited", -[13][0x0a - 1] = "Aerospace Science Memory Shenzhen", -[13][0x0b - 1] = "Shenzhen Quanji Technology Co Ltd", -[13][0x0c - 1] = "Dukosi", -[13][0x0d - 1] = "Maxell Corporation of America", -[13][0x0e - 1] = "Shenshen Xinxintao Electronics Co Ltd", -[13][0x0f - 1] = "Zhuhai Sanxia Semiconductor Co Ltd", -[13][0x10 - 1] = "Groq Inc", -[13][0x11 - 1] = "AstraTek", -[13][0x12 - 1] = "Shenzhen Xinyuze Technology Co Ltd", -[13][0x13 - 1] = "All Bit Semiconductor", -[13][0x14 - 1] = "ACFlow", -[13][0x15 - 1] = "Shenzhen Sipeed Technology Co Ltd", -[13][0x16 - 1] = "Linzhi Hong Kong Co Limited", -[13][0x17 - 1] = "Supreme Wise Limited", -[13][0x18 - 1] = "Blue Cheetah Analog Design Inc", -[13][0x19 - 1] = "Hefei Laiku Technology Co Ltd", -[13][0x1a - 1] = "Zord", -[13][0x1b - 1] = "SBO Hearing A/S", -[13][0x1c - 1] = "Regent Sharp International Limited", -[13][0x1d - 1] = "Permanent Potential Limited", -[13][0x1e - 1] = "Creative World International Limited", -[13][0x1f - 1] = "Base Creation International Limited", -[13][0x20 - 1] = "Shenzhen Zhixin Chuanglian Technology", -[13][0x21 - 1] = "Protected Logic Corporation", -[13][0x22 - 1] = "Sabrent", -[13][0x23 - 1] = "Union Memory", -[13][0x24 - 1] = "NEUCHIPS Corporation", -[13][0x25 - 1] = "Ingenic Semiconductor Co Ltd", -[13][0x26 - 1] = "SiPearl", -[13][0x27 - 1] = "Shenzhen Actseno Information Technology", -[13][0x28 - 1] = "RIVAI Technologies (Shenzhen) Co Ltd", -[13][0x29 - 1] = "Shenzhen Sunny Technology Co Ltd", -[13][0x2a - 1] = "Cott Electronics Ltd", -[13][0x2b - 1] = "Shanghai Synsense Technologies Co Ltd", -[13][0x2c - 1] = "Shenzhen Jintang Fuming Optoelectronics", -[13][0x2d - 1] = "CloudBEAR LLC", -[13][0x2e - 1] = "Emzior, LLC", -[13][0x2f - 1] = "Ehiway Microelectronic Science Tech Co", -[13][0x30 - 1] = "UNIM Innovation Technology (Wu XI)", -[13][0x31 - 1] = "GDRAMARS", -[13][0x32 - 1] = "Meminsights Technology", -[13][0x33 - 1] = "Zhuzhou Hongda Electronics Corp Ltd", -[13][0x34 - 1] = "Luminous Computing Inc", -[13][0x35 - 1] = "PROXMEM", -[13][0x36 - 1] = "Draper Labs", -[13][0x37 - 1] = "ORICO Technologies Co. Ltd.", -[13][0x38 - 1] = "Space Exploration Technologies Corp", -[13][0x39 - 1] = "AONDEVICES Inc", -[13][0x3a - 1] = "Shenzhen Netforward Micro Electronic", -[13][0x3b - 1] = "Syntacore Ltd", -[13][0x3c - 1] = "Shenzhen Secmem Microelectronics Co", -[13][0x3d - 1] = "ONiO As", -[13][0x3e - 1] = "Shenzhen Peladn Technology Co Ltd", -[13][0x3f - 1] = "O-Cubes Shanghai Microelectronics", -[13][0x40 - 1] = "ASTC", -[13][0x41 - 1] = "UMIS", -[13][0x42 - 1] = "Paradromics", -[13][0x43 - 1] = "Sinh Micro Co Ltd", -[13][0x44 - 1] = "Metorage Semiconductor Technology Co", -[13][0x45 - 1] = "Aeva Inc", -[13][0x46 - 1] = "HongKong Hyunion Electronics Co Ltd", -[13][0x47 - 1] = "China Flash Co Ltd", -[13][0x48 - 1] = "Sunplus Technology Co Ltd", -[13][0x49 - 1] = "Idaho Scientific", -[13][0x4a - 1] = "Suzhou SF Micro Electronics Co Ltd", -[13][0x4b - 1] = "IMEX Cap AG", -[13][0x4c - 1] = "Fitipower Integrated Technology Co Ltd", -[13][0x4d - 1] = "ShenzhenWooacme Technology Co Ltd", -[13][0x4e - 1] = "KeepData Original Chips", -[13][0x4f - 1] = "Rivos Inc", -[13][0x50 - 1] = "Big Innovation Company Limited", -[13][0x51 - 1] = "Wuhan YuXin Semiconductor Co Ltd", -[13][0x52 - 1] = "United Memory Technology (Jiangsu)", -[13][0x53 - 1] = "PQShield Ltd", -[13][0x54 - 1] = "ArchiTek Corporation", -[13][0x55 - 1] = "ShenZhen AZW Technology Co Ltd", -[13][0x56 - 1] = "Hengchi Zhixin (Dongguan) Technology", -[13][0x57 - 1] = "Eggtronic Engineering Spa", -[13][0x58 - 1] = "Fusontai Technology", -[13][0x59 - 1] = "PULP Platform", -[13][0x5a - 1] = "Koitek Electronic Technology (Shenzhen) Co", -[13][0x5b - 1] = "Shenzhen Jiteng Network Technology Co", -[13][0x5c - 1] = "Aviva Links Inc", -[13][0x5d - 1] = "Trilinear Technologies Inc", -[13][0x5e - 1] = "Shenzhen Developer Microelectronics Co", -[13][0x5f - 1] = "Guangdong OPPO Mobile Telecommunication", -[13][0x60 - 1] = "Akeana", -[13][0x61 - 1] = "Lyczar", -[13][0x62 - 1] = "Shenzhen Qiji Technology Co Ltd", -[13][0x63 - 1] = "Shenzhen Shangzhaoyuan Technology", -[13][0x64 - 1] = "Han Stor", -[13][0x65 - 1] = "China Micro Semicon Co., Ltd.", -[13][0x66 - 1] = "Shenzhen Zhuqin Technology Co Ltd", -[13][0x67 - 1] = "Shanghai Ningyuan Electronic Technology", -[13][0x68 - 1] = "Auradine", -[13][0x69 - 1] = "Suzhou Yishuo Electronics Co Ltd", -[13][0x6a - 1] = "Faurecia Clarion Electronics", -[13][0x6b - 1] = "SiMa Technologies", -[13][0x6c - 1] = "CFD Sales Inc", -[13][0x6d - 1] = "Suzhou Comay Information Co Ltd", -[13][0x6e - 1] = "Yentek", -[13][0x6f - 1] = "Qorvo Inc", -[13][0x70 - 1] = "Shenzhen Youzhi Computer Technology", -[13][0x71 - 1] = "Sychw Technology (Shenzhen) Co Ltd", -[13][0x72 - 1] = "MK Founder Technology Co Ltd", -[13][0x73 - 1] = "Siliconwaves Technologies Co Ltd", -[13][0x74 - 1] = "Hongkong Hyunion Electronics Co Ltd", -[13][0x75 - 1] = "Shenzhen Xinxinzhitao Electronics Business", -[13][0x76 - 1] = "Shenzhen HenQi Electronic Commerce Co", -[13][0x77 - 1] = "Shenzhen Jingyi Technology Co Ltd", -[13][0x78 - 1] = "Xiaohua Semiconductor Co. Ltd.", -[13][0x79 - 1] = "Shenzhen Dalu Semiconductor Technology", -[13][0x7a - 1] = "Shenzhen Ninespeed Electronics Co Ltd", -[13][0x7b - 1] = "ICYC Semiconductor Co Ltd", -[13][0x7c - 1] = "Shenzhen Jaguar Microsystems Co Ltd", -[13][0x7d - 1] = "Beijing EC-Founder Co Ltd", -[13][0x7e - 1] = "Shenzhen Taike Industrial Automation Co", -[14][0x01 - 1] = "Kalray SA", -[14][0x02 - 1] = "Shanghai Iluvatar CoreX Semiconductor Co", -[14][0x03 - 1] = "Fungible Inc", -[14][0x04 - 1] = "Song Industria E Comercio de Eletronicos", -[14][0x05 - 1] = "DreamBig Semiconductor Inc", -[14][0x06 - 1] = "ChampTek Electronics Corp", -[14][0x07 - 1] = "Fusontai Technology", -[14][0x08 - 1] = "Endress Hauser AG", -[14][0x09 - 1] = "altec ComputerSysteme GmbH", -[14][0x0a - 1] = "UltraRISC Technology (Shanghai) Co Ltd", -[14][0x0b - 1] = "Shenzhen Jing Da Kang Technology Co Ltd", -[14][0x0c - 1] = "Hangzhou Hongjun Microelectronics Co Ltd", -/* EOF */ diff --git a/applications/external/swd_probe/model/chip.ply b/applications/external/swd_probe/model/chip.ply deleted file mode 100644 index 7dc20abfa..000000000 --- a/applications/external/swd_probe/model/chip.ply +++ /dev/null @@ -1,216 +0,0 @@ -ply -format ascii 1.0 -comment Created by Blender 3.3.1 - www.blender.org -element vertex 136 -property float x -property float y -property float z -element face 70 -property list uchar uint vertex_indices -end_header -1.000000 1.000000 0.152153 --1.000000 1.000000 0.152153 --1.000000 -1.000000 0.152153 -1.000000 -1.000000 0.152153 -1.000000 -1.000000 -0.185787 --1.000000 -1.000000 -0.185787 --1.000000 1.000000 -0.185787 -1.000000 1.000000 -0.185787 --1.000043 -0.785071 -0.015780 --1.155724 -0.785071 -0.015780 --1.155724 -0.918718 -0.015780 --1.000043 -0.918718 -0.015780 --1.155724 -0.785071 0.127052 --1.000043 -0.785071 0.127052 --1.000043 -0.918718 0.127052 --1.155724 -0.918718 0.127052 --1.234192 -0.918846 -0.087021 --1.234397 -0.785201 -0.086336 --1.235319 -0.784943 -0.229143 --1.235114 -0.918588 -0.229828 --1.388133 -0.919573 -0.078673 --1.389056 -0.919314 -0.221479 --1.389261 -0.785669 -0.220795 --1.388338 -0.785927 -0.077988 --1.000043 -0.219627 -0.015780 --1.155724 -0.219627 -0.015780 --1.155724 -0.353273 -0.015780 --1.000043 -0.353273 -0.015780 --1.155724 -0.219627 0.127052 --1.000043 -0.219627 0.127052 --1.000043 -0.353273 0.127052 --1.155724 -0.353273 0.127052 --1.234192 -0.353402 -0.087021 --1.234397 -0.219756 -0.086336 --1.235319 -0.219498 -0.229143 --1.235114 -0.353143 -0.229828 --1.388133 -0.354128 -0.078673 --1.389056 -0.353870 -0.221479 --1.389261 -0.220224 -0.220795 --1.388338 -0.220482 -0.077988 --1.000043 0.345818 -0.015780 --1.155724 0.345818 -0.015780 --1.155724 0.212172 -0.015780 --1.000043 0.212172 -0.015780 --1.155724 0.345818 0.127052 --1.000043 0.345818 0.127052 --1.000043 0.212172 0.127052 --1.155724 0.212172 0.127052 --1.234192 0.212043 -0.087021 --1.234397 0.345689 -0.086336 --1.235319 0.345947 -0.229143 --1.235114 0.212301 -0.229828 --1.388133 0.211317 -0.078673 --1.389056 0.211575 -0.221479 --1.389261 0.345221 -0.220795 --1.388338 0.344962 -0.077988 --1.000043 0.911263 -0.015780 --1.155724 0.911263 -0.015780 --1.155724 0.777617 -0.015780 --1.000043 0.777617 -0.015780 --1.155724 0.911263 0.127052 --1.000043 0.911263 0.127052 --1.000043 0.777617 0.127052 --1.155724 0.777617 0.127052 --1.234192 0.777488 -0.087021 --1.234397 0.911133 -0.086336 --1.235319 0.911392 -0.229143 --1.235114 0.777746 -0.229828 --1.388133 0.776762 -0.078673 --1.389056 0.777020 -0.221479 --1.389261 0.910665 -0.220795 --1.388338 0.910407 -0.077988 -1.000043 -0.785071 -0.015780 -1.000043 -0.918718 -0.015780 -1.155723 -0.918718 -0.015780 -1.155723 -0.785071 -0.015780 -1.155723 -0.785071 0.127052 -1.155723 -0.918718 0.127052 -1.000043 -0.918718 0.127052 -1.000043 -0.785071 0.127052 -1.234397 -0.785201 -0.086336 -1.234192 -0.918846 -0.087021 -1.235114 -0.918588 -0.229828 -1.235319 -0.784943 -0.229143 -1.388133 -0.919573 -0.078673 -1.388338 -0.785927 -0.077988 -1.389260 -0.785669 -0.220795 -1.389056 -0.919314 -0.221479 -1.000043 -0.219627 -0.015780 -1.000043 -0.353273 -0.015780 -1.155723 -0.353273 -0.015780 -1.155723 -0.219627 -0.015780 -1.155723 -0.219627 0.127052 -1.155723 -0.353273 0.127052 -1.000043 -0.353273 0.127052 -1.000043 -0.219627 0.127052 -1.234397 -0.219756 -0.086336 -1.234192 -0.353402 -0.087021 -1.235114 -0.353143 -0.229828 -1.235319 -0.219498 -0.229143 -1.388133 -0.354128 -0.078673 -1.388338 -0.220482 -0.077988 -1.389260 -0.220224 -0.220795 -1.389056 -0.353870 -0.221479 -1.000043 0.345818 -0.015780 -1.000043 0.212172 -0.015780 -1.155723 0.212172 -0.015780 -1.155723 0.345818 -0.015780 -1.155723 0.345818 0.127052 -1.155723 0.212172 0.127052 -1.000043 0.212172 0.127052 -1.000043 0.345818 0.127052 -1.234397 0.345689 -0.086336 -1.234192 0.212043 -0.087021 -1.235114 0.212301 -0.229828 -1.235319 0.345947 -0.229143 -1.388133 0.211317 -0.078673 -1.388338 0.344962 -0.077988 -1.389260 0.345221 -0.220795 -1.389056 0.211575 -0.221479 -1.000043 0.911263 -0.015780 -1.000043 0.777616 -0.015780 -1.155723 0.777616 -0.015780 -1.155723 0.911263 -0.015780 -1.155723 0.911263 0.127052 -1.155723 0.777616 0.127052 -1.000043 0.777616 0.127052 -1.000043 0.911263 0.127052 -1.234397 0.911133 -0.086336 -1.234192 0.777488 -0.087021 -1.235114 0.777746 -0.229828 -1.235319 0.911392 -0.229143 -1.388133 0.776762 -0.078673 -1.388338 0.910407 -0.077988 -1.389260 0.910665 -0.220795 -1.389056 0.777020 -0.221479 -4 0 1 2 3 -4 4 3 2 5 -4 5 2 1 6 -4 6 7 4 5 -4 7 0 3 4 -4 6 1 0 7 -4 8 9 10 11 -4 12 13 14 15 -4 13 8 11 14 -4 12 15 16 17 -4 10 9 18 19 -4 20 21 22 23 -4 17 16 20 23 -4 19 18 22 21 -4 24 25 26 27 -4 28 29 30 31 -4 29 24 27 30 -4 28 31 32 33 -4 26 25 34 35 -4 36 37 38 39 -4 33 32 36 39 -4 35 34 38 37 -4 40 41 42 43 -4 44 45 46 47 -4 45 40 43 46 -4 44 47 48 49 -4 42 41 50 51 -4 52 53 54 55 -4 49 48 52 55 -4 51 50 54 53 -4 56 57 58 59 -4 60 61 62 63 -4 61 56 59 62 -4 60 63 64 65 -4 58 57 66 67 -4 68 69 70 71 -4 65 64 68 71 -4 67 66 70 69 -4 72 73 74 75 -4 76 77 78 79 -4 79 78 73 72 -4 76 80 81 77 -4 74 82 83 75 -4 84 85 86 87 -4 80 85 84 81 -4 82 87 86 83 -4 88 89 90 91 -4 92 93 94 95 -4 95 94 89 88 -4 92 96 97 93 -4 90 98 99 91 -4 100 101 102 103 -4 96 101 100 97 -4 98 103 102 99 -4 104 105 106 107 -4 108 109 110 111 -4 111 110 105 104 -4 108 112 113 109 -4 106 114 115 107 -4 116 117 118 119 -4 112 117 116 113 -4 114 119 118 115 -4 120 121 122 123 -4 124 125 126 127 -4 127 126 121 120 -4 124 128 129 125 -4 122 130 131 123 -4 132 133 134 135 -4 128 133 132 129 -4 130 135 134 131 diff --git a/applications/external/swd_probe/model/convert.py b/applications/external/swd_probe/model/convert.py deleted file mode 100644 index 7c99ca215..000000000 --- a/applications/external/swd_probe/model/convert.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/python - -import plyfile -import argparse - -parser = argparse.ArgumentParser(description='Convert a PLY file to C arrays.') -parser.add_argument('input_file', help='the input PLY file') -parser.add_argument('output_file', help='the output C file') -args = parser.parse_args() - -# Open the PLY file -plydata = plyfile.PlyData.read(args.input_file) - -# Extract the vertices -vertices = plydata['vertex'].data -num_vertices = len(vertices) - -with open(args.output_file, 'w') as f: - f.write('#define NUM_VERTICES %d\n' % num_vertices) - f.write('float vertexCoords[NUM_VERTICES][3] = {\n') - for i in range(num_vertices): - x, y, z = vertices[i][0], vertices[i][1], vertices[i][2] - f.write(' {%f, %f, %f},\n' % (x, y, z)) - f.write('};') - - # Extract the faces - faces = plydata['face'].data - num_faces = len(faces) - f.write('int edgeIndices[][3] = {\n') - for i in range(num_faces): - face = faces[i][0] - if len(face) == 3: - f.write(' {%d, %d, %d},\n' % (face[0], face[1], face[2])) - elif len(face) == 4: - # Convert 4-index face to 2-index edges - edges = [(face[0], face[1]), (face[1], face[2]), (face[2], face[3]), (face[3], face[0])] - for edge in edges: - f.write(' {%d, %d},\n' % (edge[0], edge[1])) - f.write('};\n') diff --git a/applications/external/swd_probe/model/model_chip.h b/applications/external/swd_probe/model/model_chip.h deleted file mode 100644 index 4061b8522..000000000 --- a/applications/external/swd_probe/model/model_chip.h +++ /dev/null @@ -1,108 +0,0 @@ -#define NUM_VERTICES 136 -float vertexCoords[NUM_VERTICES][3] = { - {1.000000, 1.000000, 0.152153}, {-1.000000, 1.000000, 0.152153}, - {-1.000000, -1.000000, 0.152153}, {1.000000, -1.000000, 0.152153}, - {1.000000, -1.000000, -0.185787}, {-1.000000, -1.000000, -0.185787}, - {-1.000000, 1.000000, -0.185787}, {1.000000, 1.000000, -0.185787}, - {-1.000043, -0.785071, -0.015780}, {-1.155724, -0.785071, -0.015780}, - {-1.155724, -0.918718, -0.015780}, {-1.000043, -0.918718, -0.015780}, - {-1.155724, -0.785071, 0.127052}, {-1.000043, -0.785071, 0.127052}, - {-1.000043, -0.918718, 0.127052}, {-1.155724, -0.918718, 0.127052}, - {-1.234192, -0.918846, -0.087021}, {-1.234397, -0.785201, -0.086336}, - {-1.235319, -0.784943, -0.229143}, {-1.235114, -0.918588, -0.229828}, - {-1.388133, -0.919573, -0.078673}, {-1.389056, -0.919314, -0.221479}, - {-1.389261, -0.785669, -0.220795}, {-1.388338, -0.785927, -0.077988}, - {-1.000043, -0.219627, -0.015780}, {-1.155724, -0.219627, -0.015780}, - {-1.155724, -0.353273, -0.015780}, {-1.000043, -0.353273, -0.015780}, - {-1.155724, -0.219627, 0.127052}, {-1.000043, -0.219627, 0.127052}, - {-1.000043, -0.353273, 0.127052}, {-1.155724, -0.353273, 0.127052}, - {-1.234192, -0.353402, -0.087021}, {-1.234397, -0.219756, -0.086336}, - {-1.235319, -0.219498, -0.229143}, {-1.235114, -0.353143, -0.229828}, - {-1.388133, -0.354128, -0.078673}, {-1.389056, -0.353870, -0.221479}, - {-1.389261, -0.220224, -0.220795}, {-1.388338, -0.220482, -0.077988}, - {-1.000043, 0.345818, -0.015780}, {-1.155724, 0.345818, -0.015780}, - {-1.155724, 0.212172, -0.015780}, {-1.000043, 0.212172, -0.015780}, - {-1.155724, 0.345818, 0.127052}, {-1.000043, 0.345818, 0.127052}, - {-1.000043, 0.212172, 0.127052}, {-1.155724, 0.212172, 0.127052}, - {-1.234192, 0.212043, -0.087021}, {-1.234397, 0.345689, -0.086336}, - {-1.235319, 0.345947, -0.229143}, {-1.235114, 0.212301, -0.229828}, - {-1.388133, 0.211317, -0.078673}, {-1.389056, 0.211575, -0.221479}, - {-1.389261, 0.345221, -0.220795}, {-1.388338, 0.344962, -0.077988}, - {-1.000043, 0.911263, -0.015780}, {-1.155724, 0.911263, -0.015780}, - {-1.155724, 0.777617, -0.015780}, {-1.000043, 0.777617, -0.015780}, - {-1.155724, 0.911263, 0.127052}, {-1.000043, 0.911263, 0.127052}, - {-1.000043, 0.777617, 0.127052}, {-1.155724, 0.777617, 0.127052}, - {-1.234192, 0.777488, -0.087021}, {-1.234397, 0.911133, -0.086336}, - {-1.235319, 0.911392, -0.229143}, {-1.235114, 0.777746, -0.229828}, - {-1.388133, 0.776762, -0.078673}, {-1.389056, 0.777020, -0.221479}, - {-1.389261, 0.910665, -0.220795}, {-1.388338, 0.910407, -0.077988}, - {1.000043, -0.785071, -0.015780}, {1.000043, -0.918718, -0.015780}, - {1.155723, -0.918718, -0.015780}, {1.155723, -0.785071, -0.015780}, - {1.155723, -0.785071, 0.127052}, {1.155723, -0.918718, 0.127052}, - {1.000043, -0.918718, 0.127052}, {1.000043, -0.785071, 0.127052}, - {1.234397, -0.785201, -0.086336}, {1.234192, -0.918846, -0.087021}, - {1.235114, -0.918588, -0.229828}, {1.235319, -0.784943, -0.229143}, - {1.388133, -0.919573, -0.078673}, {1.388338, -0.785927, -0.077988}, - {1.389260, -0.785669, -0.220795}, {1.389056, -0.919314, -0.221479}, - {1.000043, -0.219627, -0.015780}, {1.000043, -0.353273, -0.015780}, - {1.155723, -0.353273, -0.015780}, {1.155723, -0.219627, -0.015780}, - {1.155723, -0.219627, 0.127052}, {1.155723, -0.353273, 0.127052}, - {1.000043, -0.353273, 0.127052}, {1.000043, -0.219627, 0.127052}, - {1.234397, -0.219756, -0.086336}, {1.234192, -0.353402, -0.087021}, - {1.235114, -0.353143, -0.229828}, {1.235319, -0.219498, -0.229143}, - {1.388133, -0.354128, -0.078673}, {1.388338, -0.220482, -0.077988}, - {1.389260, -0.220224, -0.220795}, {1.389056, -0.353870, -0.221479}, - {1.000043, 0.345818, -0.015780}, {1.000043, 0.212172, -0.015780}, - {1.155723, 0.212172, -0.015780}, {1.155723, 0.345818, -0.015780}, - {1.155723, 0.345818, 0.127052}, {1.155723, 0.212172, 0.127052}, - {1.000043, 0.212172, 0.127052}, {1.000043, 0.345818, 0.127052}, - {1.234397, 0.345689, -0.086336}, {1.234192, 0.212043, -0.087021}, - {1.235114, 0.212301, -0.229828}, {1.235319, 0.345947, -0.229143}, - {1.388133, 0.211317, -0.078673}, {1.388338, 0.344962, -0.077988}, - {1.389260, 0.345221, -0.220795}, {1.389056, 0.211575, -0.221479}, - {1.000043, 0.911263, -0.015780}, {1.000043, 0.777616, -0.015780}, - {1.155723, 0.777616, -0.015780}, {1.155723, 0.911263, -0.015780}, - {1.155723, 0.911263, 0.127052}, {1.155723, 0.777616, 0.127052}, - {1.000043, 0.777616, 0.127052}, {1.000043, 0.911263, 0.127052}, - {1.234397, 0.911133, -0.086336}, {1.234192, 0.777488, -0.087021}, - {1.235114, 0.777746, -0.229828}, {1.235319, 0.911392, -0.229143}, - {1.388133, 0.776762, -0.078673}, {1.388338, 0.910407, -0.077988}, - {1.389260, 0.910665, -0.220795}, {1.389056, 0.777020, -0.221479}, -}; -int edgeIndices[][3] = { - {0, 1}, {1, 2}, {2, 3}, {3, 0}, {4, 3}, {3, 2}, {2, 5}, {5, 4}, - {5, 2}, {2, 1}, {1, 6}, {6, 5}, {6, 7}, {7, 4}, {4, 5}, {5, 6}, - {7, 0}, {0, 3}, {3, 4}, {4, 7}, {6, 1}, {1, 0}, {0, 7}, {7, 6}, - {8, 9}, {9, 10}, {10, 11}, {11, 8}, {12, 13}, {13, 14}, {14, 15}, {15, 12}, - {13, 8}, {8, 11}, {11, 14}, {14, 13}, {12, 15}, {15, 16}, {16, 17}, {17, 12}, - {10, 9}, {9, 18}, {18, 19}, {19, 10}, {20, 21}, {21, 22}, {22, 23}, {23, 20}, - {17, 16}, {16, 20}, {20, 23}, {23, 17}, {19, 18}, {18, 22}, {22, 21}, {21, 19}, - {24, 25}, {25, 26}, {26, 27}, {27, 24}, {28, 29}, {29, 30}, {30, 31}, {31, 28}, - {29, 24}, {24, 27}, {27, 30}, {30, 29}, {28, 31}, {31, 32}, {32, 33}, {33, 28}, - {26, 25}, {25, 34}, {34, 35}, {35, 26}, {36, 37}, {37, 38}, {38, 39}, {39, 36}, - {33, 32}, {32, 36}, {36, 39}, {39, 33}, {35, 34}, {34, 38}, {38, 37}, {37, 35}, - {40, 41}, {41, 42}, {42, 43}, {43, 40}, {44, 45}, {45, 46}, {46, 47}, {47, 44}, - {45, 40}, {40, 43}, {43, 46}, {46, 45}, {44, 47}, {47, 48}, {48, 49}, {49, 44}, - {42, 41}, {41, 50}, {50, 51}, {51, 42}, {52, 53}, {53, 54}, {54, 55}, {55, 52}, - {49, 48}, {48, 52}, {52, 55}, {55, 49}, {51, 50}, {50, 54}, {54, 53}, {53, 51}, - {56, 57}, {57, 58}, {58, 59}, {59, 56}, {60, 61}, {61, 62}, {62, 63}, {63, 60}, - {61, 56}, {56, 59}, {59, 62}, {62, 61}, {60, 63}, {63, 64}, {64, 65}, {65, 60}, - {58, 57}, {57, 66}, {66, 67}, {67, 58}, {68, 69}, {69, 70}, {70, 71}, {71, 68}, - {65, 64}, {64, 68}, {68, 71}, {71, 65}, {67, 66}, {66, 70}, {70, 69}, {69, 67}, - {72, 73}, {73, 74}, {74, 75}, {75, 72}, {76, 77}, {77, 78}, {78, 79}, {79, 76}, - {79, 78}, {78, 73}, {73, 72}, {72, 79}, {76, 80}, {80, 81}, {81, 77}, {77, 76}, - {74, 82}, {82, 83}, {83, 75}, {75, 74}, {84, 85}, {85, 86}, {86, 87}, {87, 84}, - {80, 85}, {85, 84}, {84, 81}, {81, 80}, {82, 87}, {87, 86}, {86, 83}, {83, 82}, - {88, 89}, {89, 90}, {90, 91}, {91, 88}, {92, 93}, {93, 94}, {94, 95}, {95, 92}, - {95, 94}, {94, 89}, {89, 88}, {88, 95}, {92, 96}, {96, 97}, {97, 93}, {93, 92}, - {90, 98}, {98, 99}, {99, 91}, {91, 90}, {100, 101}, {101, 102}, {102, 103}, {103, 100}, - {96, 101}, {101, 100}, {100, 97}, {97, 96}, {98, 103}, {103, 102}, {102, 99}, {99, 98}, - {104, 105}, {105, 106}, {106, 107}, {107, 104}, {108, 109}, {109, 110}, {110, 111}, {111, 108}, - {111, 110}, {110, 105}, {105, 104}, {104, 111}, {108, 112}, {112, 113}, {113, 109}, {109, 108}, - {106, 114}, {114, 115}, {115, 107}, {107, 106}, {116, 117}, {117, 118}, {118, 119}, {119, 116}, - {112, 117}, {117, 116}, {116, 113}, {113, 112}, {114, 119}, {119, 118}, {118, 115}, {115, 114}, - {120, 121}, {121, 122}, {122, 123}, {123, 120}, {124, 125}, {125, 126}, {126, 127}, {127, 124}, - {127, 126}, {126, 121}, {121, 120}, {120, 127}, {124, 128}, {128, 129}, {129, 125}, {125, 124}, - {122, 130}, {130, 131}, {131, 123}, {123, 122}, {132, 133}, {133, 134}, {134, 135}, {135, 132}, - {128, 133}, {133, 132}, {132, 129}, {129, 128}, {130, 135}, {135, 134}, {134, 131}, {131, 130}, -}; diff --git a/applications/external/swd_probe/swd_probe_app.c b/applications/external/swd_probe/swd_probe_app.c deleted file mode 100644 index b43b9c1c8..000000000 --- a/applications/external/swd_probe/swd_probe_app.c +++ /dev/null @@ -1,3189 +0,0 @@ - - -#include "swd_probe_app.h" -#include "swd_probe_icons.h" -#include -#include "jep106.h" -#include "adi.h" - -#define SWD_PATH EXT_PATH("apps_data/swd") - -static void render_callback(Canvas* const canvas, void* cb_ctx); -static bool swd_message_process(AppFSM* ctx); -static uint8_t swd_transfer(AppFSM* const ctx, bool ap, bool write, uint8_t a23, uint32_t* data); -static bool swd_execute_script(AppFSM* const ctx, const char* filename); - -static const GpioPin* gpios[] = { - &gpio_ext_pc0, - &gpio_ext_pc1, - &gpio_ext_pc3, - &gpio_ext_pb2, - &gpio_ext_pb3, - &gpio_ext_pa4, - &gpio_ext_pa6, - &gpio_ext_pa7}; - -static const char* gpio_names[] = {"PC0", "PC1", "PC3", "PB2", "PB3", "PA4", "PA6", "PA7"}; - -/* bit set: clock, else data */ -static const uint8_t gpio_direction_mask[6] = - {0b10101010, 0b01010101, 0b11001100, 0b00110011, 0b11110000, 0b00001111}; - -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 NotificationSequence seq_error = { - - &message_vibro_on, - &message_delay_50, - &message_vibro_off, - - &message_note_g4, - &message_delay_100, - &message_sound_off, - &message_delay_10, - - &message_note_c4, - &message_delay_500, - &message_sound_off, - &message_delay_10, - NULL, -}; - -const NotificationSequence* seq_sounds[] = {&seq_c_minor, &seq_error}; - -static bool has_multiple_bits(uint8_t x) { - return (x & (x - 1)) != 0; -} - -static uint8_t get_bit_num(uint8_t x) { - return (uint8_t)__builtin_ctz(x); -} - -static const char* gpio_name(uint8_t mask) { - if(has_multiple_bits(mask)) { - return "Pxx"; - } - uint8_t io = get_bit_num(mask); - if(io >= COUNT(gpio_names)) { - return "Pxx"; - } - - return gpio_names[io]; -} - -static void swd_configure_pins(AppFSM* const ctx, bool output) { - if(ctx->mode_page > ModePageFound && ctx->io_num_swc < 8 && ctx->io_num_swd < 8) { - furi_hal_gpio_init( - gpios[ctx->io_num_swc], GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - if(!output) { - furi_hal_gpio_init( - gpios[ctx->io_num_swd], GpioModeInput, GpioPullUp, GpioSpeedVeryHigh); - } else { - furi_hal_gpio_init( - gpios[ctx->io_num_swd], GpioModeOutputOpenDrain, GpioPullUp, GpioSpeedVeryHigh); - } - return; - } - - for(int io = 0; io < 8; io++) { - uint8_t bitmask = 1 << io; - - /* if neither candidate for SWC nor SWD then skip */ - if(!(ctx->io_swc & bitmask) && !(ctx->io_swd & bitmask)) { - furi_hal_gpio_init(gpios[io], GpioModeInput, GpioPullUp, GpioSpeedVeryHigh); - continue; - } - - if(ctx->current_mask & bitmask) { - /* set for clock */ - furi_hal_gpio_init(gpios[io], GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - } else { - /* set for data */ - if(!output) { - furi_hal_gpio_init(gpios[io], GpioModeInput, GpioPullUp, GpioSpeedVeryHigh); - } else { - furi_hal_gpio_init( - gpios[io], GpioModeOutputOpenDrain, GpioPullUp, GpioSpeedVeryHigh); - } - } - } -} - -static void swd_set_clock(AppFSM* const ctx, const uint8_t level) { - if(ctx->mode_page > ModePageFound && ctx->io_num_swc < 8) { - furi_hal_gpio_write(gpios[ctx->io_num_swc], level); - return; - } - - for(int io = 0; io < 8; io++) { - uint8_t bitmask = 1 << io; - - /* if no candidate for SWC then skip */ - if(!(ctx->io_swc & bitmask)) { - continue; - } - - if(ctx->current_mask & bitmask) { - furi_hal_gpio_write(gpios[io], level); - } - } -} - -static void swd_set_data(AppFSM* const ctx, const uint8_t level) { - if(ctx->mode_page > ModePageFound && ctx->io_num_swd < 8) { - furi_hal_gpio_write(gpios[ctx->io_num_swd], level); - return; - } - - for(int io = 0; io < 8; io++) { - uint8_t bitmask = 1 << io; - - /* if no candidate for SWD then skip */ - if(!(ctx->io_swd & bitmask)) { - continue; - } - - if(!(ctx->current_mask & bitmask)) { - furi_hal_gpio_write(gpios[io], level); - } - } -} - -static uint8_t swd_get_data(AppFSM* const ctx) { - if(ctx->mode_page > ModePageFound && ctx->io_num_swd < 8) { - return furi_hal_gpio_read(gpios[ctx->io_num_swd]); - } - - uint8_t bits = 0; - for(int io = 0; io < 8; io++) { - uint8_t bitmask = 1 << io; - - /* if no candidate for SWD then skip */ - if(!(ctx->io_swd & bitmask)) { - continue; - } - bits |= furi_hal_gpio_read(gpios[io]) ? bitmask : 0; - } - return bits; -} - -static void swd_clock_delay(AppFSM* const ctx) { - if(ctx->swd_clock_delay) { - furi_delay_us(ctx->swd_clock_delay); - } -} - -static void swd_write_bit(AppFSM* const ctx, bool level) { - swd_set_clock(ctx, 0); - swd_set_data(ctx, level); - swd_clock_delay(ctx); - swd_set_clock(ctx, 1); - swd_clock_delay(ctx); - swd_set_clock(ctx, 0); -} - -static uint8_t swd_read_bit(AppFSM* const ctx) { - swd_set_clock(ctx, 1); - swd_clock_delay(ctx); - swd_set_clock(ctx, 0); - uint8_t bits = swd_get_data(ctx); - swd_clock_delay(ctx); - swd_set_clock(ctx, 1); - - return bits; -} - -/* send a byte or less LSB-first */ -static void swd_write_byte(AppFSM* const ctx, const uint8_t data, size_t bits) { - for(size_t pos = 0; pos < bits; pos++) { - swd_write_bit(ctx, data & (1 << pos)); - } -} - -/* send a sequence of bytes LSB-first */ -static void swd_write(AppFSM* const ctx, const uint8_t* data, size_t bits) { - size_t byte_pos = 0; - while(bits > 0) { - size_t remain = (bits > 8) ? 8 : bits; - swd_write_byte(ctx, data[byte_pos++], remain); - bits -= remain; - } -} - -static uint8_t swd_transfer(AppFSM* const ctx, bool ap, bool write, uint8_t a23, uint32_t* data) { - //notification_message(ctx->notification, &sequence_set_blue_255); - //notification_message(ctx->notification, &sequence_reset_red); - - swd_set_data(ctx, false); - swd_configure_pins(ctx, true); - - uint32_t idle = 0; - swd_write(ctx, (uint8_t*)&idle, ctx->swd_idle_bits); - - uint8_t request[] = {0}; - - request[0] |= 0x01; /* start bit*/ - request[0] |= ap ? 0x02 : 0; /* APnDP */ - request[0] |= write ? 0 : 0x04; /* operation */ - request[0] |= (a23 & 0x01) ? 0x08 : 0; /* A[2:3] */ - request[0] |= (a23 & 0x02) ? 0x10 : 0; /* A[2:3] */ - request[0] |= 0x80; /* park bit */ - request[0] |= __builtin_parity(request[0]) ? 0x20 : 0; /* parity */ - - swd_write(ctx, request, sizeof(request) * 8); - - /* turnaround cycle */ - swd_configure_pins(ctx, false); - - uint8_t ack = 0; - - /* receive 3 ACK bits */ - for(int pos = 0; pos < 3; pos++) { - ack >>= 1; - ack |= swd_read_bit(ctx) ? 0x04 : 0; - } - - /* force ABORT/CTRL to always work */ - if(!ap && a23 == 0) { - ack = 1; - } - - if(ack != 0x01) { - //notification_message(ctx->notification, &sequence_reset_blue); - //notification_message(ctx->notification, &sequence_set_red_255); - return ack; - } - - if(write) { - swd_write_bit(ctx, 0); - swd_configure_pins(ctx, true); - - /* send 32 WDATA bits */ - for(int pos = 0; pos < 32; pos++) { - swd_write_bit(ctx, *data & (1 << pos)); - } - - /* send parity bit */ - swd_write_bit(ctx, __builtin_parity(*data)); - } else { - *data = 0; - /* receive 32 RDATA bits */ - for(int pos = 0; pos < 32; pos++) { - *data >>= 1; - *data |= swd_read_bit(ctx) ? 0x80000000 : 0; - } - - /* receive parity bit */ - bool parity = swd_read_bit(ctx); - - if(parity != __builtin_parity(*data)) { - //notification_message(ctx->notification, &sequence_reset_blue); - //notification_message(ctx->notification, &sequence_set_red_255); - return 8; - } - } - swd_set_data(ctx, false); - swd_configure_pins(ctx, true); - //notification_message(ctx->notification, &sequence_reset_blue); - - return ack; -} - -/* A line reset is achieved by holding the data signal HIGH for at least 50 clock cycles, followed by at least two idle cycles. */ -static void swd_line_reset(AppFSM* const ctx) { - //notification_message(ctx->notification, &sequence_set_red_255); - for(int bitcount = 0; bitcount < 50; bitcount += 8) { - swd_write_byte(ctx, 0xFF, 8); - } - swd_write_byte(ctx, 0, 8); - ctx->dp_regs.select_ok = false; - //notification_message(ctx->notification, &sequence_reset_red); -} - -static void swd_abort(AppFSM* const ctx) { - uint32_t dpidr; - - /* first reset the line */ - swd_line_reset(ctx); - swd_transfer(ctx, false, false, 0, &dpidr); - uint32_t abort = 0x0E; - swd_transfer(ctx, false, true, 0, &abort); -} - -static void swd_abort_simple(AppFSM* const ctx) { - uint32_t abort = 0x0E; - swd_transfer(ctx, false, true, 0, &abort); - - uint32_t dpidr; - if(swd_transfer(ctx, false, false, 0, &dpidr) != 1) { - swd_abort(ctx); - } -} - -static uint8_t swd_select(AppFSM* const ctx, uint8_t ap_sel, uint8_t ap_bank, uint8_t dp_bank) { - uint32_t bank_reg = (ap_sel << 24) | ((ap_bank & 0x0F) << 4) | (dp_bank & 0x0F); - - if(ctx->dp_regs.select_ok && bank_reg == ctx->dp_regs.select) { - return 1; - } - - uint8_t ret = swd_transfer(ctx, false, true, REG_SELECT, &bank_reg); - if(ret != 1) { - ctx->dp_regs.select_ok = false; - DBG("failed: %d", ret); - return ret; - } - - ctx->dp_regs.select = bank_reg; - ctx->dp_regs.select_ok = true; - return ret; -} - -static uint8_t - swd_read_dpbank(AppFSM* const ctx, uint8_t dp_off, uint8_t dp_bank, uint32_t* data) { - uint8_t ret = 0; - - /* select target bank */ - if(dp_bank < 0x10) { - uint8_t ret = swd_select(ctx, 0, 0, dp_bank); - if(ret != 1) { - DBGS("swd_select failed"); - return ret; - } - } - - /* read data from it */ - *data = 0; - ret = swd_transfer(ctx, false, false, dp_off, data); - if(ret != 1) { - DBG("failed: %d", ret); - return ret; - } - return ret; -} - -static uint8_t - swd_write_dpbank(AppFSM* const ctx, uint8_t dp_off, uint8_t dp_bank, uint32_t* data) { - uint8_t ret = 0; - - /* select target bank */ - if(dp_bank < 0x10) { - ret = swd_select(ctx, 0, 0, dp_bank); - if(ret != 1) { - DBGS("swd_select failed"); - return ret; - } - } - - /* write it */ - ret = swd_transfer(ctx, false, true, dp_off, data); - if(ret != 1) { - DBG("failed: %d", ret); - return ret; - } - return ret; -} - -static uint8_t swd_read_ap(AppFSM* const ctx, uint8_t ap, uint8_t ap_off, uint32_t* data) { - /* select target bank */ - uint8_t ret = swd_select(ctx, ap, (ap_off >> 4) & 0x0F, 0); - if(ret != 1) { - DBGS("swd_select failed"); - return ret; - } - ret = swd_transfer(ctx, true, false, (ap_off >> 2) & 3, data); - *data = 0; - ret = swd_transfer(ctx, true, false, (ap_off >> 2) & 3, data); - if(ret != 1) { - DBG("failed: %d", ret); - return ret; - } - return ret; -} - -static uint8_t swd_read_ap_single(AppFSM* const ctx, uint8_t ap, uint8_t ap_off, uint32_t* data) { - uint8_t ret = swd_select(ctx, ap, (ap_off >> 4) & 0x0F, 0); - if(ret != 1) { - DBGS("swd_select failed"); - return ret; - } - *data = 0; - ret = swd_transfer(ctx, true, false, (ap_off >> 2) & 3, data); - if(ret != 1) { - DBG("failed: %d", ret); - return ret; - } - return ret; -} - -static uint8_t swd_write_ap(AppFSM* const ctx, uint8_t ap, uint8_t ap_off, uint32_t data) { - uint8_t ret = swd_select(ctx, ap, (ap_off >> 4) & 0x0F, 0); - if(ret != 1) { - DBGS("swd_select failed"); - return ret; - } - ret = swd_transfer(ctx, true, true, (ap_off >> 2) & 3, &data); - if(ret != 1) { - DBG("failed: %d", ret); - return ret; - } - return ret; -} - -static uint8_t swd_write_memory(AppFSM* const ctx, uint8_t ap, uint32_t address, uint32_t data) { - uint8_t ret = 0; - uint32_t csw = 0x23000002; - - ret |= swd_write_ap(ctx, ap, MEMAP_CSW, csw); - ret |= swd_write_ap(ctx, ap, MEMAP_TAR, address); - ret |= swd_write_ap(ctx, ap, MEMAP_DRW, data); - DBG("write 0x%08lX to 0x%08lX", data, address); - - if(ret != 1) { - swd_abort(ctx); - } - return ret; -} - -uint8_t swd_read_memory(AppFSM* const ctx, uint8_t ap, uint32_t address, uint32_t* data) { - uint8_t ret = 0; - uint32_t csw = 0x23000002; - - ret |= swd_write_ap(ctx, ap, MEMAP_CSW, csw); - ret |= swd_write_ap(ctx, ap, MEMAP_TAR, address); - ret |= swd_read_ap(ctx, ap, MEMAP_DRW, data); - - if(ret != 1) { - DBG("read from 0x%08lX failed", address); - swd_abort(ctx); - } else { - DBG("read 0x%08lX from 0x%08lX", *data, address); - } - return ret; -} - -static uint8_t swd_read_memory_block( - AppFSM* const ctx, - uint8_t ap, - uint32_t address, - uint8_t* buf, - uint32_t len) { - uint8_t ret = 0; - uint32_t data = 0; - uint32_t csw = 0x23000012; - - ret |= swd_write_ap(ctx, ap, MEMAP_CSW, csw); - ret |= swd_write_ap(ctx, ap, MEMAP_TAR, address); - ret |= swd_read_ap_single(ctx, ap, MEMAP_DRW, &data); - - for(size_t pos = 0; pos < len; pos += 4) { - data = 0xDEADBEEF; - ret |= swd_read_ap_single(ctx, ap, MEMAP_DRW, &data); - DBG("read %lX", data); - - memcpy(&buf[pos], &data, 4); - - if(ret != 1) { - swd_abort(ctx); - return ret; - } - } - return ret; -} - -static uint32_t swd_detect(AppFSM* const ctx) { - swd_set_data(ctx, false); - swd_configure_pins(ctx, true); - - uint8_t data[] = {0xA5}; - swd_write(ctx, data, sizeof(data) * 8); - - /* turnaround cycle */ - swd_configure_pins(ctx, false); - - uint8_t ack_bits[3]; - uint8_t rdata[32]; - - /* receive 3 ACK bits */ - for(int pos = 0; pos < 3; pos++) { - ack_bits[pos] = swd_read_bit(ctx); - } - - /* receive 32 RDATA bits */ - for(int pos = 0; pos < 32; pos++) { - rdata[pos] = swd_read_bit(ctx); - } - - /* receive parity bit */ - uint8_t parity = swd_read_bit(ctx); - - for(int io = 0; io < 8; io++) { - uint8_t bitmask = 1 << io; - - /* skip if it's a clock */ - if(ctx->current_mask & bitmask) { - continue; - } - - uint8_t ack = 0; - for(int pos = 0; pos < 3; pos++) { - ack >>= 1; - ack |= (ack_bits[pos] & bitmask) ? 4 : 0; - } - - uint32_t dpidr = 0; - for(int pos = 0; pos < 32; pos++) { - dpidr >>= 1; - dpidr |= (rdata[pos] & bitmask) ? 0x80000000 : 0; - } - - if(ack == 1 && dpidr != 0 && dpidr != 0xFFFFFFFF) { - bool received_parity = (parity & bitmask); - if(__builtin_parity(dpidr) == received_parity) { - ctx->dp_regs.dpidr = dpidr; - ctx->dp_regs.dpidr_ok = true; - ctx->detected = true; - ctx->io_swd = bitmask; - ctx->io_swc &= ctx->current_mask; - LOG("swd_detect: data: %08lX, io_swd %02X, io_swc %02X", - dpidr, - ctx->io_swd, - ctx->io_swc); - - if(!has_multiple_bits(ctx->io_swc)) { - ctx->io_num_swd = get_bit_num(ctx->io_swd); - ctx->io_num_swc = get_bit_num(ctx->io_swc); - } - } - } - } - swd_set_data(ctx, false); - swd_configure_pins(ctx, true); - - return 0; -} - -static void swd_scan(AppFSM* const ctx) { - /* To switch SWJ-DP from JTAG to SWD operation: - 1. Send at least 50 SWCLKTCK cycles with SWDIOTMS HIGH. This ensures that the current interface is in its reset state. The JTAG interface only detects the 16-bit JTAG-to-SWD sequence starting from the Test-Logic-Reset state. - 2. Send the 16-bit JTAG-to-SWD select sequence 0x79e7 on SWDIOTMS. - 3. Send at least 50 SWCLKTCK cycles with SWDIOTMS HIGH. This ensures that if SWJ-DP was already in SWD operation before sending the select sequence, the SWD interface enters line reset state. - */ - swd_configure_pins(ctx, true); - - /* reset JTAG interface */ - for(int bitcount = 0; bitcount < 50; bitcount += 8) { - swd_write_byte(ctx, 0xFF, 8); - } - - /* Send the 16-bit JTAG-to-SWD select sequence */ - swd_write_byte(ctx, 0x9E, 8); - swd_write_byte(ctx, 0xE7, 8); - - /* resynchronize SWD */ - swd_line_reset(ctx); - - swd_detect(ctx); -} - -static bool swd_ensure_powerup(AppFSM* const ctx) { - bool ret = true; - - if(!(ctx->dp_regs.ctrlstat & (CSYSPWRUPREQ | CDBGPWRUPREQ))) { - DBGS("no (CSYSPWRUPREQ | CDBGPWRUPREQ)"); - - /* fetch current CTRL/STAT */ - DBGS(" - Fetch CTRL/STAT"); - ctx->dp_regs.ctrlstat_ok = - swd_read_dpbank(ctx, REG_CTRLSTAT, REG_CTRLSTAT_BANK, &ctx->dp_regs.ctrlstat) == 1; - DBG(" %08lX %s", ctx->dp_regs.ctrlstat, ctx->dp_regs.ctrlstat_ok ? "OK" : "FAIL"); - /* enable requests */ - ctx->dp_regs.ctrlstat |= (CSYSPWRUPREQ | CDBGPWRUPREQ); - - swd_write_dpbank(ctx, REG_CTRLSTAT, REG_CTRLSTAT_BANK, &ctx->dp_regs.ctrlstat); - - ret = false; - } - if(!(ctx->dp_regs.ctrlstat & CDBGPWRUPACK)) { - DBGS("no CDBGPWRUPACK"); - /* fetch current CTRL/STAT */ - swd_read_dpbank(ctx, REG_CTRLSTAT, REG_CTRLSTAT_BANK, &ctx->dp_regs.ctrlstat); - ret = false; - } - - if(!ret) { - DBGS(" - Fetch CTRL/STAT"); - ctx->dp_regs.ctrlstat_ok = - swd_read_dpbank(ctx, REG_CTRLSTAT, REG_CTRLSTAT_BANK, &ctx->dp_regs.ctrlstat) == 1; - DBG(" %08lX %s", ctx->dp_regs.ctrlstat, ctx->dp_regs.ctrlstat_ok ? "OK" : "FAIL"); - } - - return ret; -} - -static void swd_apscan_reset(AppFSM* const ctx) { - for(size_t reset_ap = 0; reset_ap < COUNT(ctx->apidr_info); reset_ap++) { - ctx->apidr_info[reset_ap].tested = false; - } -} - -static bool swd_apscan_test(AppFSM* const ctx, uint32_t ap) { - furi_assert(ctx); - furi_assert(ap < sizeof(ctx->apidr_info)); - bool ret = true; - - ctx->apidr_info[ap].tested = true; - - uint32_t data = 0; - if(swd_read_ap(ctx, ap, AP_IDR, &data) != 1) { - swd_abort(ctx); - return false; - } - if(data == 0) { - return false; - } - DBG("AP%lu detected", ap); - ctx->apidr_info[ap].ok = true; - ctx->apidr_info[ap].revision = (data >> 24) & 0x0F; - ctx->apidr_info[ap].designer = (data >> 17) & 0x3FF; - ctx->apidr_info[ap].class = (data >> 13) & 0x0F; - ctx->apidr_info[ap].variant = (data >> 4) & 0x0F; - ctx->apidr_info[ap].type = (data >> 0) & 0x0F; - - if(swd_read_ap(ctx, ap, AP_BASE, &ctx->apidr_info[ap].base) != 1) { - swd_abort(ctx); - ret = false; - } - return ret; -} - -/************************** script helpers **************************/ - -static void swd_script_log(ScriptContext* ctx, FuriLogLevel level, const char* format, ...) { - bool commandline = false; - ScriptContext* cur = ctx; - FuriString* buffer = furi_string_alloc(); - va_list argp; - va_start(argp, format); - - do { - if(cur == ctx->app->commandline) { - commandline = true; - } - cur = cur->parent; - } while(cur); - - if(commandline) { - const char* prefix = ""; - - switch(level) { - case FuriLogLevelWarn: - prefix = "Warning: "; - break; - case FuriLogLevelError: - prefix = "ERROR: "; - break; - default: - break; - } - - furi_string_cat_str(buffer, prefix); - furi_string_cat_printf(buffer, format, argp); - furi_string_cat_str(buffer, "\n"); - - if(!usb_uart_tx_data( - ctx->app->uart, (uint8_t*)furi_string_get_cstr(buffer), furi_string_size(buffer))) { - DBGS("Sending via USB failed"); - } - } else { - LOG(furi_string_get_cstr(buffer)); - } - va_end(argp); - furi_string_free(buffer); -} - -/* read characters until newline was read */ -static bool swd_script_seek_newline(ScriptContext* ctx) { - while(true) { - uint8_t ch = 0; - - if(ctx->script_file) { - if(storage_file_read(ctx->script_file, &ch, 1) != 1) { - return false; - } - } else { - ch = ctx->line_data[ctx->line_pos]; - if(ch == 0) { - return false; - } - ctx->line_pos++; - } - if(ch == '\n') { - return true; - } - } -} - -/* read whitespaces until the next character is read. - returns false if EOF or newline was read */ -static bool swd_script_skip_whitespace(ScriptContext* ctx) { - while(true) { - uint8_t ch = 0; - uint64_t start_pos = 0; - - if(ctx->script_file) { - start_pos = storage_file_tell(ctx->script_file); - - if(storage_file_read(ctx->script_file, &ch, 1) != 1) { - return false; - } - } else { - start_pos = ctx->line_pos; - ch = ctx->line_data[ctx->line_pos]; - - if(ch == 0) { - return false; - } - ctx->line_pos++; - } - if(ch == '\n') { - return false; - } - if(ch != ' ') { - if(ctx->script_file) { - storage_file_seek(ctx->script_file, start_pos, true); - } else { - ctx->line_pos = start_pos; - } - return true; - } - } -} - -static bool swd_script_get_string(ScriptContext* ctx, char* str, size_t max_length) { - bool quot = false; - size_t pos = 0; - - str[pos] = '\000'; - - while(true) { - char ch = 0; - uint64_t start_pos = 0; - - if(ctx->script_file) { - start_pos = storage_file_tell(ctx->script_file); - - if(storage_file_read(ctx->script_file, &ch, 1) != 1) { - DBGS("end reached"); - return false; - } - } else { - start_pos = ctx->line_pos; - ch = ctx->line_data[ctx->line_pos]; - - if(ch == 0) { - DBGS("end reached"); - return false; - } - ctx->line_pos++; - } - - if(ch == '"') { - quot = !quot; - continue; - } - if(!quot) { - if(ch == ' ') { - break; - } - if(ch == '\r' || ch == '\n') { - if(ctx->script_file) { - storage_file_seek(ctx->script_file, start_pos, true); - } else { - ctx->line_pos = start_pos; - } - break; - } - } - if(pos + 2 > max_length) { - DBGS("too long"); - return false; - } - str[pos++] = ch; - str[pos] = '\000'; - } - DBG("got '%s'", str); - - return true; -} - -static bool swd_script_get_number(ScriptContext* ctx, uint32_t* number) { - char str[16]; - - if(!swd_script_get_string(ctx, str, sizeof(str))) { - DBGS("could not get string"); - return false; - } - DBG("got '%s'", str); - - size_t pos = 0; - *number = 0; - - /* hex number? */ - if(!strncmp(str, "0x", 2)) { - pos += 2; - while(str[pos]) { - uint8_t ch = str[pos++]; - uint8_t ch_num = ch - '0'; - uint8_t ch_hex = (ch & ~0x20) - 'A'; - - *number <<= 4; - - if(ch_num <= 10) { - *number += ch_num; - } else if(ch_hex <= 5) { - *number += 10 + ch_hex; - } else { - return false; - } - } - } else { - while(str[pos]) { - uint8_t ch = str[pos++]; - uint8_t ch_num = ch - '0'; - - *number *= 10; - - if(ch_num < 10) { - *number += ch_num; - } else { - return false; - } - } - } - - return true; -} - -static void swd_script_gui_refresh(ScriptContext* ctx) { - if(furi_message_queue_get_count(ctx->app->event_queue) > 0) { - swd_message_process(ctx->app); - } - if(!ctx->status_ignore) { - DBG("Status: %s", ctx->app->state_string); - view_port_update(ctx->app->view_port); - } -} - -/************************** script functions **************************/ - -static bool swd_scriptfunc_comment(ScriptContext* ctx) { - DBGS("comment"); - - swd_script_seek_newline(ctx); - - return true; -} - -static bool swd_scriptfunc_label(ScriptContext* ctx) { - char label[256]; - DBGS("label"); - - swd_script_skip_whitespace(ctx); - if(!swd_script_get_string(ctx, label, sizeof(label))) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse label"); - return false; - } - - if(!strcmp(label, ctx->goto_label)) { - ctx->goto_active = false; - DBG("matches '%s'", ctx->goto_label); - } - - swd_script_seek_newline(ctx); - - return true; -} - -static bool swd_scriptfunc_goto(ScriptContext* ctx) { - DBGS("goto"); - - swd_script_skip_whitespace(ctx); - - if(!swd_script_get_string(ctx, ctx->goto_label, sizeof(ctx->goto_label))) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse target label"); - return false; - } - - /* start from beginning and rerun starting from label */ - ctx->goto_active = true; - ctx->restart = true; - - swd_script_seek_newline(ctx); - - return true; -} - -#include - -static bool swd_scriptfunc_call(ScriptContext* ctx) { - DBGS("call"); - - swd_script_skip_whitespace(ctx); - - /* fetch previous file directory */ - FuriString* filepath = furi_string_alloc(); - path_extract_dirname(ctx->filename, filepath); - // strncpy(filename, ctx->filename, sizeof(filename)); - - char filename[MAX_FILE_LENGTH] = {}; - bool success = false; - do { - /* append filename */ - if(!swd_script_get_string(ctx, filename, sizeof(filename))) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse filename"); - break; - } - - swd_script_seek_newline(ctx); - /* append extension */ - furi_string_cat_str(filepath, ".swd"); - - bool ret = swd_execute_script(ctx->app, furi_string_get_cstr(filepath)); - - if(!ret) { - swd_script_log( - ctx, FuriLogLevelError, "failed to exec '%s'", furi_string_get_cstr(filepath)); - break; - } - - success = true; - } while(false); - furi_string_free(filepath); - - return success; -} - -static bool swd_scriptfunc_status(ScriptContext* ctx) { - uint32_t status = 1; - DBGS("status"); - - swd_script_skip_whitespace(ctx); - swd_script_get_number(ctx, &status); - - ctx->status_ignore = (status == 0); - - swd_script_seek_newline(ctx); - - return true; -} - -static bool swd_scriptfunc_errors(ScriptContext* ctx) { - char type[32]; - DBGS("errors"); - - swd_script_skip_whitespace(ctx); - - if(!swd_script_get_string(ctx, type, sizeof(type))) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse"); - return false; - } - - if(!strcmp(type, "ignore")) { - ctx->errors_ignore = true; - } - if(!strcmp(type, "fail")) { - ctx->errors_ignore = false; - } - swd_script_seek_newline(ctx); - - return true; -} - -static bool swd_scriptfunc_beep(ScriptContext* ctx) { - uint32_t sound = 0; - DBGS("beep"); - - swd_script_skip_whitespace(ctx); - swd_script_get_number(ctx, &sound); - - notification_message_block(ctx->app->notification, seq_sounds[sound]); - - swd_script_seek_newline(ctx); - - return true; -} - -static bool swd_scriptfunc_message(ScriptContext* ctx) { - uint32_t wait_time = 0; - char message[256]; - char type[256]; - bool success = true; - bool show_dialog = false; - - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - - if(!swd_script_get_number(ctx, &wait_time)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse wait_time"); - return false; - } - - if(!swd_script_get_string(ctx, message, sizeof(message))) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse message"); - return false; - } - - if(swd_script_get_string(ctx, type, sizeof(type))) { - if(!strcmp(type, "dialog")) { - show_dialog = true; - } - } - - if(wait_time <= 60 * 1000) { - strncpy(ctx->app->state_string, message, sizeof(ctx->app->state_string)); - swd_script_gui_refresh(ctx); - furi_delay_ms(wait_time); - if(show_dialog) { - DialogMessage* message = dialog_message_alloc(); - dialog_message_set_header(message, "SWD Probe", 16, 2, AlignLeft, AlignTop); - dialog_message_set_icon(message, &I_app, 3, 2); - dialog_message_set_text(message, ctx->app->state_string, 3, 16, AlignLeft, AlignTop); - dialog_message_set_buttons(message, "Abort", "Ok", NULL); - success = dialog_message_show(ctx->app->dialogs, message) == DialogMessageButtonCenter; - dialog_message_free(message); - } - } - - swd_script_seek_newline(ctx); - - return success; -} - -static bool swd_scriptfunc_swd_idle_bits(ScriptContext* ctx) { - uint32_t swd_idle_bits = 0; - - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - - if(!swd_script_get_number(ctx, &swd_idle_bits)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse"); - return false; - } - - if(swd_idle_bits <= 32) { - ctx->app->swd_idle_bits = swd_idle_bits; - } else { - swd_script_log(ctx, FuriLogLevelError, "value must be between 1 and 32"); - } - - swd_script_seek_newline(ctx); - - return true; -} - -static bool swd_scriptfunc_swd_clock_delay(ScriptContext* ctx) { - uint32_t swd_clock_delay = 0; - - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - - if(!swd_script_get_number(ctx, &swd_clock_delay)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse"); - return false; - } - - if(swd_clock_delay <= 1000000) { - ctx->app->swd_clock_delay = swd_clock_delay; - } else { - swd_script_log(ctx, FuriLogLevelError, "value must be between 1 and 1000000"); - } - - swd_script_seek_newline(ctx); - - return true; -} - -static bool swd_scriptfunc_maxtries(ScriptContext* ctx) { - uint32_t max_tries = 0; - - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - - if(!swd_script_get_number(ctx, &max_tries)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse"); - return false; - } - - if(max_tries >= 1 && max_tries <= 1024) { - ctx->max_tries = max_tries; - } else { - DBGS("value must be between 1 and 1024"); - } - - swd_script_seek_newline(ctx); - - return true; -} - -static bool swd_scriptfunc_blocksize(ScriptContext* ctx) { - uint32_t block_size = 0; - - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - - if(!swd_script_get_number(ctx, &block_size)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse"); - return false; - } - - if(block_size >= 4 && block_size <= 0x1000) { - ctx->block_size = block_size; - } else { - swd_script_log(ctx, FuriLogLevelError, "value must be between 4 and 4096"); - } - - swd_script_seek_newline(ctx); - - return true; -} - -static bool swd_scriptfunc_apselect(ScriptContext* ctx) { - uint32_t ap = 0; - - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - - if(!swd_script_get_number(ctx, &ap)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse AP"); - return false; - } - - if(!swd_apscan_test(ctx->app, ap)) { - swd_script_log(ctx, FuriLogLevelError, "no selected AP"); - return false; - } - - ctx->selected_ap = ap; - - swd_script_seek_newline(ctx); - - return true; -} - -static bool swd_scriptfunc_apscan(ScriptContext* ctx) { - DBGS("Scanning APs"); - for(uint32_t ap = 0; ap < 255; ap++) { - snprintf(ctx->app->state_string, sizeof(ctx->app->state_string), "Scan AP %lu", ap); - swd_script_gui_refresh(ctx); - if(swd_apscan_test(ctx->app, ap)) { - DBG(" AP%lu detected", ap); - } - } - swd_script_seek_newline(ctx); - - return true; -} - -static bool swd_scriptfunc_abort(ScriptContext* ctx) { - DBGS("Aborting"); - swd_abort(ctx->app); - swd_script_seek_newline(ctx); - - return true; -} - -static bool swd_scriptfunc_mem_dump(ScriptContext* ctx) { - char filename[MAX_FILE_LENGTH]; - uint32_t address = 0; - uint32_t length = 0; - uint32_t flags = 0; - bool success = true; - - /* get file */ - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - - if(!swd_script_get_string(ctx, filename, sizeof(filename))) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse filename"); - return false; - } - /* get address */ - if(!swd_script_get_number(ctx, &address)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse address"); - return false; - } - - /* get length */ - if(!swd_script_get_number(ctx, &length)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse length"); - return false; - } - - /* get flags */ - if(swd_script_get_number(ctx, &flags)) { - DBGS("found extra flags"); - } - - LOG("would dump %08lX, len %08lX into %s", address, length, filename); - - File* dump = storage_file_alloc(ctx->app->storage); - - if(!storage_file_open(dump, filename, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { - storage_file_free(dump); - snprintf(ctx->app->state_string, sizeof(ctx->app->state_string), "Failed to create file"); - swd_script_gui_refresh(ctx); - notification_message_block(ctx->app->notification, &seq_error); - return false; - } - - if(ctx->block_size == 0) { - ctx->block_size = 0x100; - } - if(ctx->block_size > 0x1000) { - ctx->block_size = 0x1000; - } - - uint8_t* buffer = malloc(ctx->block_size); - - furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever); - - for(uint32_t pos = 0; pos < length; pos += ctx->block_size) { - if((pos & 0xFF) == 0) { - int pct = pos * 100 / length; - snprintf( - ctx->app->state_string, - sizeof(ctx->app->state_string), - "Dump %08lX (%d%%)", - pos, - pct); - swd_script_gui_refresh(ctx); - } - - bool read_ok = false; - - for(uint32_t tries = 0; tries < ctx->max_tries; tries++) { - if(ctx->abort) { - DBGS("aborting read"); - break; - } - uint32_t ret = 0; - - if(ctx->block_size > 4) { - ret = swd_read_memory_block( - ctx->app, ctx->selected_ap, address + pos, buffer, ctx->block_size); - } else { - ret = - swd_read_memory(ctx->app, ctx->selected_ap, address + pos, (uint32_t*)buffer); - } - read_ok = (ret == 1); - - if(!read_ok) { - snprintf( - ctx->app->state_string, - sizeof(ctx->app->state_string), - "Failed at 0x%08lX", - address + pos); - swd_script_gui_refresh(ctx); - furi_delay_ms(100); - } else { - break; - } - } - if(ctx->abort) { - DBGS("aborting"); - break; - } - - if(!read_ok) { - /* flags == 1: "continue reading even if it fails" */ - /* flags == 2: "its okay if cannot dump fully" */ - if(flags & 1) { - /* set all content to a known value as indication */ - for(size_t fill_pos = 0; fill_pos < ctx->block_size; fill_pos += 4) { - *((uint32_t*)&buffer[fill_pos]) = 0xDEADFACE; - } - } else if(flags & 2) { - success = (pos > 0); - break; - } else { - notification_message_block(ctx->app->notification, &seq_error); - success = false; - break; - } - } - storage_file_write(dump, buffer, ctx->block_size); - } - - furi_mutex_release(ctx->app->swd_mutex); - - storage_file_close(dump); - swd_script_seek_newline(ctx); - free(buffer); - - return success; -} - -static bool swd_scriptfunc_mem_write(ScriptContext* ctx) { - uint32_t address = 0; - uint32_t data = 0; - bool success = true; - - /* get file */ - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - - /* get address */ - if(!swd_script_get_number(ctx, &address)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse address"); - return false; - } - - /* get data */ - if(!swd_script_get_number(ctx, &data)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse data"); - return false; - } - - DBG("write %08lX to %08lX", data, address); - - bool access_ok = false; - for(uint32_t tries = 0; tries < ctx->max_tries; tries++) { - if(ctx->abort) { - DBGS("aborting"); - break; - } - - furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever); - access_ok = swd_write_memory(ctx->app, ctx->selected_ap, address, data) == 1; - access_ok |= ctx->errors_ignore; - swd_read_memory(ctx->app, ctx->selected_ap, address, &data); - furi_mutex_release(ctx->app->swd_mutex); - - DBG("read %08lX from %08lX", data, address); - - if(!access_ok) { - snprintf( - ctx->app->state_string, - sizeof(ctx->app->state_string), - "Failed write 0x%08lX", - address); - swd_script_gui_refresh(ctx); - } else { - break; - } - } - - if(!access_ok) { - notification_message_block(ctx->app->notification, &seq_error); - success = false; - } - - swd_script_seek_newline(ctx); - - return success; -} - -static bool swd_scriptfunc_mem_read(ScriptContext* ctx) { - uint32_t address = 0; - bool success = true; - - /* get file */ - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - - /* get address */ - if(!swd_script_get_number(ctx, &address)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse address"); - return false; - } - - DBG("read from %08lX", address); - - uint32_t data = 0; - bool access_ok = false; - for(uint32_t tries = 0; tries < ctx->max_tries; tries++) { - if(ctx->abort) { - DBGS("aborting"); - break; - } - - furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever); - access_ok = swd_read_memory(ctx->app, ctx->selected_ap, address, &data) == 1; - furi_mutex_release(ctx->app->swd_mutex); - - if(!access_ok) { - swd_script_log(ctx, FuriLogLevelError, "Failed to read from %08lX", address); - snprintf( - ctx->app->state_string, - sizeof(ctx->app->state_string), - "Failed read 0x%08lX", - address); - swd_script_gui_refresh(ctx); - } else { - swd_script_log(ctx, FuriLogLevelDefault, "%08lX", data); - break; - } - } - - if(!access_ok) { - notification_message_block(ctx->app->notification, &seq_error); - success = false; - } - - swd_script_seek_newline(ctx); - - return success; -} - -static bool swd_scriptfunc_mem_ldmst(ScriptContext* ctx) { - uint32_t address = 0; - uint32_t data = 0; - uint32_t mask = 0; - bool success = true; - - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - - /* get address */ - if(!swd_script_get_number(ctx, &address)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse address"); - return false; - } - - /* get data */ - if(!swd_script_get_number(ctx, &data)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse data"); - return false; - } - - /* get mask */ - if(!swd_script_get_number(ctx, &mask)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse mask"); - return false; - } - - LOG("write %08lX to %08lX, mask %08lX", data, address, mask); - - bool access_ok = false; - uint32_t modified = 0; - for(uint32_t tries = 0; tries < ctx->max_tries; tries++) { - if(ctx->abort) { - DBGS("aborting"); - break; - } - furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever); - - access_ok = swd_read_memory(ctx->app, ctx->selected_ap, address, &modified) == 1; - modified = (modified & mask) | data; - access_ok &= swd_write_memory(ctx->app, ctx->selected_ap, address, modified) == 1; - - furi_mutex_release(ctx->app->swd_mutex); - access_ok |= ctx->errors_ignore; - - if(!access_ok) { - snprintf( - ctx->app->state_string, - sizeof(ctx->app->state_string), - "Failed access 0x%08lX", - address); - swd_script_gui_refresh(ctx); - } else { - break; - } - } - - if(!access_ok) { - notification_message_block(ctx->app->notification, &seq_error); - success = false; - } - - swd_script_seek_newline(ctx); - - return success; -} - -static bool swd_scriptfunc_dp_write(ScriptContext* ctx) { - uint32_t dp_bank = 0; - uint32_t dp_off = 0; - uint32_t data = 0; - bool success = true; - - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - - /* get data */ - if(!swd_script_get_number(ctx, &data)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse data"); - return false; - } - - /* get dp_off */ - if(!swd_script_get_number(ctx, &dp_off)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse DP offset"); - return false; - } - - /* get dp_bank */ - if(!swd_script_get_number(ctx, &dp_bank)) { - dp_bank = 0xFF; - } - - swd_script_log( - ctx, FuriLogLevelDefault, "write %08lX to reg %08lX / bank %08lX", data, dp_off, dp_bank); - - furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever); - - uint8_t ret = swd_write_dpbank(ctx->app, dp_off, dp_bank, &data); - if(ret != 1) { - swd_script_log(ctx, FuriLogLevelError, "swd_write_dpbank failed"); - success = false; - } - - furi_mutex_release(ctx->app->swd_mutex); - - swd_script_seek_newline(ctx); - - return success; -} - -static bool swd_scriptfunc_dp_read(ScriptContext* ctx) { - uint32_t dp_bank = 0; - uint32_t dp_off = 0; - uint32_t data = 0; - bool success = true; - - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - - /* get dp_off */ - if(!swd_script_get_number(ctx, &dp_off)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse DP offset"); - return false; - } - - /* get dp_bank */ - if(!swd_script_get_number(ctx, &dp_bank)) { - dp_bank = 0xFF; - } - - swd_script_log(ctx, FuriLogLevelDefault, "read reg %02lX / bank %02lX", dp_off, dp_bank); - - furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever); - - uint8_t ret = swd_read_dpbank(ctx->app, dp_off, dp_bank, &data); - if(ret != 1) { - swd_script_log(ctx, FuriLogLevelError, "swd_read_dpbank failed"); - success = false; - } else { - swd_script_log(ctx, FuriLogLevelDefault, "result: 0x%08lX", data); - } - furi_mutex_release(ctx->app->swd_mutex); - - swd_script_seek_newline(ctx); - - return success; -} - -static bool swd_scriptfunc_ap_write(ScriptContext* ctx) { - uint32_t ap_reg = 0; - uint32_t data = 0; - bool success = true; - - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - - /* get data */ - if(!swd_script_get_number(ctx, &data)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse data"); - return false; - } - - /* get ap_reg */ - if(!swd_script_get_number(ctx, &ap_reg)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse AP register"); - return false; - } - - swd_script_log( - ctx, FuriLogLevelDefault, "AP%d %08lX -> %02lX", ctx->selected_ap, data, ap_reg); - - furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever); - - uint8_t ret = swd_write_ap(ctx->app, ctx->selected_ap, ap_reg, data); - if(ret != 1) { - swd_script_log(ctx, FuriLogLevelError, "swd_write_ap failed"); - success = false; - } - furi_mutex_release(ctx->app->swd_mutex); - - swd_script_seek_newline(ctx); - - return success; -} - -static bool swd_scriptfunc_ap_read(ScriptContext* ctx) { - uint32_t ap_reg = 0; - uint32_t data = 0; - bool success = true; - - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - - /* get ap_reg */ - if(!swd_script_get_number(ctx, &ap_reg)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse AP register"); - return false; - } - - furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever); - - uint8_t ret = swd_read_ap(ctx->app, ctx->selected_ap, ap_reg, &data); - if(ret != 1) { - swd_script_log(ctx, FuriLogLevelError, "swd_read_ap failed"); - success = false; - } else { - swd_script_log( - ctx, FuriLogLevelDefault, "AP%d %02lX: %08lX", ctx->selected_ap, ap_reg, data); - } - furi_mutex_release(ctx->app->swd_mutex); - - swd_script_seek_newline(ctx); - - return success; -} - -static bool swd_scriptfunc_core_halt(ScriptContext* ctx) { - bool succ = false; - - furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever); - uint32_t reg_dhcsr = SCS_DHCSR_KEY | SCS_DHCSR_C_HALT | SCS_DHCSR_C_DEBUGEN; - - succ = swd_write_memory(ctx->app, ctx->selected_ap, SCS_DHCSR, reg_dhcsr) == 1; - - if(!succ) { - swd_script_log(ctx, FuriLogLevelError, "swd_write_memory failed"); - } else { - swd_read_memory(ctx->app, ctx->selected_ap, SCS_DHCSR, ®_dhcsr); - - if(!(reg_dhcsr & SCS_DHCSR_S_HALT)) { - swd_script_log(ctx, FuriLogLevelError, "Core did not halt"); - succ = false; - } else { - swd_script_log(ctx, FuriLogLevelDefault, "Core halted"); - } - } - - furi_mutex_release(ctx->app->swd_mutex); - swd_script_seek_newline(ctx); - - return succ; -} - -static bool swd_scriptfunc_core_continue(ScriptContext* ctx) { - bool succ = false; - uint32_t data = 0; - - furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever); - succ = swd_read_memory(ctx->app, ctx->selected_ap, SCS_DHCSR, &data) == 1; - - if(!(data & SCS_DHCSR_S_HALT)) { - swd_script_log(ctx, FuriLogLevelError, "Core is not in debug state"); - succ = false; - } else { - succ = swd_write_memory(ctx->app, ctx->selected_ap, SCS_DHCSR, SCS_DHCSR_KEY) == 1; - furi_mutex_release(ctx->app->swd_mutex); - } - - if(!succ) { - swd_script_log(ctx, FuriLogLevelError, "swd_write_memory failed"); - } else { - swd_script_log(ctx, FuriLogLevelDefault, "Core continued"); - } - - swd_script_seek_newline(ctx); - - return succ; -} - -static bool swd_scriptfunc_core_step(ScriptContext* ctx) { - bool succ = false; - uint32_t data = 0; - - furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever); - succ = swd_read_memory(ctx->app, ctx->selected_ap, SCS_DHCSR, &data) == 1; - - if(!(data & SCS_DHCSR_S_HALT)) { - swd_script_log(ctx, FuriLogLevelError, "Core is not in debug state"); - succ = false; - } else { - succ = swd_write_memory( - ctx->app, - ctx->selected_ap, - SCS_DHCSR, - SCS_DHCSR_KEY | SCS_DHCSR_C_STEP | SCS_DHCSR_C_MASKINTS | - SCS_DHCSR_C_DEBUGEN) == 1; - } - furi_mutex_release(ctx->app->swd_mutex); - - if(!succ) { - swd_script_log(ctx, FuriLogLevelError, "swd_write_memory failed"); - } else { - swd_script_log(ctx, FuriLogLevelDefault, "Core stepped"); - } - - swd_script_seek_newline(ctx); - - return succ; -} - -static struct cpu_regs_type { - uint8_t regsel; - const char* desc; -} cpu_regs[] = { - {0x00, "R00"}, {0x01, "R01"}, {0x02, "R02"}, {0x03, "R03"}, {0x04, "R04"}, - {0x05, "R05"}, {0x06, "R06"}, {0x07, "R07"}, {0x08, "R08"}, {0x09, "R09"}, - {0x0A, "R10"}, {0x0B, "R11"}, {0x0C, "R12"}, {0x0D, "SP/R13"}, {0x0E, "LR/R14"}, - {0x0F, "PC/R15"}, {0x10, "xPSR"}, {0x11, "MSP"}, {0x12, "PSP"}, {0x14, "Flags"}, - {0x21, "FPCSR"}, {0x40, "FP S00"}, {0x41, "FP S01"}, {0x42, "FP S02"}, {0x43, "FP S03"}, - {0x44, "FP S04"}, {0x45, "FP S05"}, {0x46, "FP S06"}, {0x47, "FP S07"}, {0x48, "FP S08"}, - {0x49, "FP S09"}, {0x4A, "FP S10"}, {0x4B, "FP S11"}, {0x4C, "FP S12"}, {0x4D, "FP S13"}, - {0x4E, "FP S14"}, {0x4F, "FP S15"}, {0x50, "FP S16"}, {0x51, "FP S17"}, {0x52, "FP S18"}, - {0x53, "FP S19"}, {0x54, "FP S20"}, {0x55, "FP S21"}, {0x56, "FP S22"}, {0x57, "FP S23"}, - {0x58, "FP S24"}, {0x59, "FP S25"}, {0x5A, "FP S26"}, {0x5B, "FP S27"}, {0x5C, "FP S28"}, - {0x5D, "FP S29"}, {0x5E, "FP S30"}, {0x5F, "FP S31"}}; - -static bool swd_scriptfunc_core_regs(ScriptContext* ctx) { - bool succ = false; - - furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever); - - uint32_t reg_dhcsr = 0; - uint32_t reg_cpacr = 0; - swd_read_memory(ctx->app, ctx->selected_ap, SCS_DHCSR, ®_dhcsr); - swd_read_memory(ctx->app, ctx->selected_ap, SCS_CPACR, ®_cpacr); - - /* when FPU is enabled/available, CP10 and CP11 are implemented */ - bool has_fpu = ((reg_cpacr >> 20) & 0x0F) != 0; - - if(!(reg_dhcsr & SCS_DHCSR_S_HALT)) { - swd_script_log(ctx, FuriLogLevelError, "Core is not in debug state"); - succ = false; - } else { - for(size_t pos = 0; pos < COUNT(cpu_regs); pos++) { - if(!has_fpu && (cpu_regs[pos].regsel >= 0x20)) { - continue; - } - uint32_t core_data = 0; - succ = - swd_write_memory( - ctx->app, ctx->selected_ap, SCS_DCRSR, SCS_DCRSR_RD | cpu_regs[pos].regsel) == - 1; - succ &= swd_read_memory(ctx->app, ctx->selected_ap, SCS_DCRDR, &core_data) == 1; - - if(!succ) { - swd_script_log(ctx, FuriLogLevelDefault, "%08s ----------", cpu_regs[pos].desc); - } else { - swd_script_log( - ctx, FuriLogLevelDefault, "%06s 0x%08X", cpu_regs[pos].desc, core_data); - } - } - } - furi_mutex_release(ctx->app->swd_mutex); - - swd_script_seek_newline(ctx); - - return true; -} - -static bool swd_scriptfunc_core_reg_get(ScriptContext* ctx) { - uint32_t core_reg = 0; - uint32_t core_data = 0; - bool succ = false; - - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - - if(!swd_script_get_number(ctx, &core_reg)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse register"); - return false; - } - - furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever); - uint32_t reg_dhcsr = 0; - uint32_t reg_cpacr = 0; - swd_read_memory(ctx->app, ctx->selected_ap, SCS_DHCSR, ®_dhcsr); - swd_read_memory(ctx->app, ctx->selected_ap, SCS_CPACR, ®_cpacr); - - /* when FPU is enabled/available, CP10 and CP11 are implemented */ - bool has_fpu = ((reg_cpacr >> 20) & 0x0F) != 0; - - if(!(reg_dhcsr & SCS_DHCSR_S_HALT)) { - swd_script_log(ctx, FuriLogLevelError, "Core is not in debug state"); - succ = false; - } else { - if(!has_fpu && (core_reg >= 0x20)) { - swd_script_log(ctx, FuriLogLevelError, "Core has no FP extensions"); - succ = false; - } else { - succ = swd_write_memory( - ctx->app, ctx->selected_ap, SCS_DCRSR, SCS_DCRSR_RD | core_reg) == 1; - succ &= swd_read_memory(ctx->app, ctx->selected_ap, SCS_DCRDR, &core_data) == 1; - if(!succ) { - swd_script_log(ctx, FuriLogLevelError, "swd_write_memory failed"); - } - } - } - furi_mutex_release(ctx->app->swd_mutex); - - if(succ) { - swd_script_log(ctx, FuriLogLevelDefault, "0x%08X", core_data); - } - - swd_script_seek_newline(ctx); - - return succ; -} - -static bool swd_scriptfunc_core_reg_set(ScriptContext* ctx) { - uint32_t core_reg = 0; - uint32_t core_data = 0; - bool succ = false; - - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - - if(!swd_script_get_number(ctx, &core_reg)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse register"); - return false; - } - if(!swd_script_skip_whitespace(ctx)) { - swd_script_log(ctx, FuriLogLevelError, "missing whitespace"); - return false; - } - if(!swd_script_get_number(ctx, &core_data)) { - swd_script_log(ctx, FuriLogLevelError, "failed to parse data"); - return false; - } - - furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever); - uint32_t reg_dhcsr = 0; - uint32_t reg_cpacr = 0; - - swd_read_memory(ctx->app, ctx->selected_ap, SCS_DHCSR, ®_dhcsr); - swd_read_memory(ctx->app, ctx->selected_ap, SCS_CPACR, ®_cpacr); - - /* when FPU is enabled/available, CP10 and CP11 are implemented */ - bool has_fpu = ((reg_cpacr >> 20) & 0x0F) != 0; - - if(!(reg_dhcsr & SCS_DHCSR_S_HALT)) { - swd_script_log(ctx, FuriLogLevelError, "Core is not in debug state"); - succ = false; - } else { - if(!has_fpu && (core_reg >= 0x20)) { - swd_script_log(ctx, FuriLogLevelError, "Core has no FP extensions"); - succ = false; - } else { - succ = swd_write_memory(ctx->app, ctx->selected_ap, SCS_DCRDR, core_data) == 1; - succ &= swd_write_memory( - ctx->app, ctx->selected_ap, SCS_DCRSR, SCS_DCRSR_WR | core_reg) == 1; - if(!succ) { - swd_script_log(ctx, FuriLogLevelError, "swd_write_memory failed"); - } - } - } - furi_mutex_release(ctx->app->swd_mutex); - - swd_script_seek_newline(ctx); - - return succ; -} - -static bool swd_scriptfunc_core_cpuid(ScriptContext* ctx) { - bool succ = false; - uint32_t reg_cpuid = 0; - - furi_mutex_acquire(ctx->app->swd_mutex, FuriWaitForever); - succ = swd_read_memory(ctx->app, ctx->selected_ap, SCS_CPUID, ®_cpuid) == 1; - furi_mutex_release(ctx->app->swd_mutex); - - if(!succ) { - swd_script_log(ctx, FuriLogLevelError, "swd_read_memory failed"); - } else { - swd_script_log(ctx, FuriLogLevelDefault, "0x%08X", reg_cpuid); - } - - swd_script_seek_newline(ctx); - - return succ; -} - -static const ScriptFunctionInfo script_funcs[] = { - {"#", &swd_scriptfunc_comment}, - {".label", &swd_scriptfunc_label}, - {"goto", &swd_scriptfunc_goto}, - {"call", &swd_scriptfunc_call}, - {"status", &swd_scriptfunc_status}, - {"errors", &swd_scriptfunc_errors}, - {"message", &swd_scriptfunc_message}, - {"beep", &swd_scriptfunc_beep}, - {"max_tries", &swd_scriptfunc_maxtries}, - {"swd_clock_delay", &swd_scriptfunc_swd_clock_delay}, - {"swd_idle_bits", &swd_scriptfunc_swd_idle_bits}, - {"block_size", &swd_scriptfunc_blocksize}, - {"abort", &swd_scriptfunc_abort}, - {"mem_dump", &swd_scriptfunc_mem_dump}, - {"mem_ldmst", &swd_scriptfunc_mem_ldmst}, - {"mem_write", &swd_scriptfunc_mem_write}, - {"mem_read", &swd_scriptfunc_mem_read}, - {"dp_write", &swd_scriptfunc_dp_write}, - {"dp_read", &swd_scriptfunc_dp_read}, - {"ap_scan", &swd_scriptfunc_apscan}, - {"ap_select", &swd_scriptfunc_apselect}, - {"ap_read", &swd_scriptfunc_ap_read}, - {"ap_write", &swd_scriptfunc_ap_write}, - {"core_halt", &swd_scriptfunc_core_halt}, - {"core_step", &swd_scriptfunc_core_step}, - {"core_continue", &swd_scriptfunc_core_continue}, - {"core_regs", &swd_scriptfunc_core_regs}, - {"core_reg_get", &swd_scriptfunc_core_reg_get}, - {"core_reg_set", &swd_scriptfunc_core_reg_set}, - {"core_cpuid", &swd_scriptfunc_core_cpuid}}; - -/************************** script main code **************************/ - -static bool swd_execute_script_line(ScriptContext* const ctx) { - char buffer[64]; - uint64_t start_pos = 0; - - if(ctx->script_file) { - start_pos = storage_file_tell(ctx->script_file); - uint16_t ret = storage_file_read(ctx->script_file, buffer, 2); - storage_file_seek(ctx->script_file, start_pos, true); - - if(ret < 2) { - return true; - } - } else { - start_pos = ctx->line_pos; - strncpy(buffer, ctx->line_data, 2); - - if(buffer[0] == 0 || buffer[1] == 0) { - return true; - } - } - - if(buffer[0] == '\n' || (buffer[0] == '\r' && buffer[1] == '\n')) { - swd_script_seek_newline(ctx); - return true; - } - - for(size_t entry = 0; entry < COUNT(script_funcs); entry++) { - if(ctx->abort) { - DBGS("aborting"); - break; - } - size_t expected = strlen(script_funcs[entry].prefix); - - if(ctx->script_file) { - storage_file_seek(ctx->script_file, start_pos, true); - - if(storage_file_read(ctx->script_file, buffer, expected) != expected) { - continue; - } - } else { - ctx->line_pos = start_pos; - - if(strlen(ctx->line_data) < expected) { - continue; - } - strncpy(buffer, ctx->line_data, expected); - ctx->line_pos += expected; - } - - buffer[expected] = '\000'; - if(strncmp(buffer, script_funcs[entry].prefix, expected)) { - continue; - } - bool success = true; - - if(ctx->goto_active) { - DBG("ignore: '%s'", script_funcs[entry].prefix); - - /* only execute label handlers */ - if(buffer[0] == '.') { - success = script_funcs[entry].func(ctx); - } else { - swd_script_seek_newline(ctx); - } - } else { - DBG("command: '%s'", script_funcs[entry].prefix); - - if(!ctx->status_ignore) { - snprintf( - ctx->app->state_string, - sizeof(ctx->app->state_string), - "CMD: %s", - script_funcs[entry].prefix); - } - swd_script_gui_refresh(ctx); - - /* function, execute */ - success = script_funcs[entry].func(ctx); - - if(!success && !ctx->errors_ignore) { - swd_script_log( - ctx, FuriLogLevelError, "Command failed: %s", script_funcs[entry].prefix); - snprintf( - ctx->app->state_string, - sizeof(ctx->app->state_string), - "Command failed: %s", - script_funcs[entry].prefix); - return false; - } - } - - return true; - } - swd_script_log(ctx, FuriLogLevelError, "unknown command '%s'", buffer); - - return false; -} - -static bool swd_execute_script(AppFSM* const ctx, const char* filename) { - bool success = true; - - /* fetch current script and set as parent */ - ScriptContext* parent = ctx->script; - - ctx->script = malloc(sizeof(ScriptContext)); - ctx->script->app = ctx; - ctx->script->max_tries = 1; - ctx->script->parent = parent; - strcpy(ctx->script->filename, filename); - - if(!storage_file_exists(ctx->storage, filename)) { - DBG("Does not exist '%s'", filename); - parent = ctx->script->parent; - free(ctx->script); - ctx->script = parent; - return false; - } - - /* first allocate a file object */ - ctx->script->script_file = storage_file_alloc(ctx->storage); - - /* then get our script opened */ - if(!storage_file_open(ctx->script->script_file, filename, FSAM_READ, FSOM_OPEN_EXISTING)) { - FURI_LOG_E(TAG, "open, %s", storage_file_get_error_desc(ctx->script->script_file)); - DBG("Failed to open '%s'", filename); - storage_file_free(ctx->script->script_file); - parent = ctx->script->parent; - free(ctx->script); - ctx->script = parent; - return false; - } - - do { - success = true; - ctx->script->restart = false; - - storage_file_seek(ctx->script->script_file, 0, true); - - uint32_t line = 1; - while(line < SCRIPT_MAX_LINES) { - if(ctx->script->abort) { - DBGS("Abort requested"); - break; - } - if(storage_file_eof(ctx->script->script_file)) { - break; - } - DBG("line %lu", line); - if(!swd_execute_script_line(ctx->script)) { - success = false; - break; - } - if(ctx->script->restart) { - break; - } - line++; - } - - if(ctx->script->restart) { - DBGS("Restarting"); - } else { - DBGS("Finished"); - } - - if(line >= SCRIPT_MAX_LINES) { - success = true; - char text_buf[128]; - - snprintf(text_buf, sizeof(text_buf), "aborting after %d lines", SCRIPT_MAX_LINES); - DialogMessage* message = dialog_message_alloc(); - dialog_message_set_header(message, "SWD Probe", 16, 2, AlignLeft, AlignTop); - dialog_message_set_icon(message, &I_app, 3, 2); - dialog_message_set_text(message, text_buf, 3, 16, AlignLeft, AlignTop); - dialog_message_set_buttons(message, "Back", NULL, NULL); - dialog_message_free(message); - - ctx->script->restart = false; - } - - if(!success) { - char text_buf[128]; - - snprintf(text_buf, sizeof(text_buf), "Line %lu failed:\n%s", line, ctx->state_string); - DialogMessage* message = dialog_message_alloc(); - dialog_message_set_header(message, "SWD Probe", 16, 2, AlignLeft, AlignTop); - dialog_message_set_icon(message, &I_app, 3, 2); - dialog_message_set_text(message, text_buf, 3, 16, AlignLeft, AlignTop); - dialog_message_set_buttons(message, "Back", "Retry", NULL); - if(dialog_message_show(ctx->dialogs, message) == DialogMessageButtonCenter) { - ctx->script->restart = true; - } - dialog_message_free(message); - } - } while(ctx->script->restart); - - storage_file_close(ctx->script->script_file); - storage_file_free(ctx->script->script_file); - - parent = ctx->script->parent; - free(ctx->script); - ctx->script = parent; - - return success; -} - -/************************** UI functions **************************/ - -#define CANVAS_WIDTH 128 -#define CANVAS_HEIGHT 64 - -#define COERCE(d, min, max) \ - do { \ - if(d < (min)) { \ - d = (min); \ - } \ - if(d > (max)) { \ - d = (max); \ - } \ - } while(0) - -#define COERCE_COORDS(x1, y1, x2, y2) \ - do { \ - COERCE(x1, 0, CANVAS_WIDTH); \ - COERCE(x2, 0, CANVAS_WIDTH); \ - COERCE(y1, 0, CANVAS_HEIGHT); \ - COERCE(y1, 0, CANVAS_HEIGHT); \ - } while(0) - -#include "model/model_chip.h" - -static int rotatedVertexCoords[NUM_VERTICES][3]; - -static void draw_model(Canvas* const canvas) { - static float xAngle = 0; - static float yAngle = 0; - static float zAngle = 0; - static float zoom = 0; - static float speed = 0.6f; - - float cosXAngle = cosf(xAngle); - float sinXAngle = sinf(xAngle); - float cosYAngle = cosf(yAngle); - float sinYAngle = sinf(yAngle); - float cosZAngle = cosf(zAngle); - float sinZAngle = sinf(zAngle); - float sinZoom = 1.2f + sinf(zoom) * 0.25f; - - int centerX = CANVAS_WIDTH / 2; - int centerY = CANVAS_HEIGHT / 2 + 5; - - for(int i = 0; i < NUM_VERTICES; i++) { - int x = vertexCoords[i][0] * sinZoom * 16; - int y = vertexCoords[i][1] * sinZoom * 16; - int z = vertexCoords[i][2] * sinZoom * 16; - - int y1 = y * cosXAngle - z * sinXAngle; - int z1 = y * sinXAngle + z * cosXAngle; - - int x2 = x * cosYAngle + z1 * sinYAngle; - int z2 = -x * sinYAngle + z1 * cosYAngle; - - int x3 = x2 * cosZAngle - y1 * sinZAngle; - int y3 = x2 * sinZAngle + y1 * cosZAngle; - - rotatedVertexCoords[i][0] = x3 + centerX; - rotatedVertexCoords[i][1] = y3 + centerY; - rotatedVertexCoords[i][2] = z2; - } - - for(size_t i = 0; i < COUNT(edgeIndices); i++) { - int v1Index = edgeIndices[i][0]; - int v2Index = edgeIndices[i][1]; - int x1 = rotatedVertexCoords[v1Index][0]; - int y1 = rotatedVertexCoords[v1Index][1]; - int x2 = rotatedVertexCoords[v2Index][0]; - int y2 = rotatedVertexCoords[v2Index][1]; - - COERCE_COORDS(x1, y1, x2, y2); - canvas_draw_line(canvas, x1, y1, x2, y2); - } - - xAngle += speed * 0.02 / sinZoom; - yAngle += speed * 0.023 / sinZoom; - zAngle += speed * 0.029 * sinZoom; - zoom += speed * 0.005; -} - -static void render_callback(Canvas* const canvas, void* ctx_in) { - furi_assert(canvas); - furi_assert(ctx_in); - - AppFSM* ctx = ctx_in; - furi_mutex_acquire(ctx->gui_mutex, FuriWaitForever); - - char buffer[64]; - int y = 10; - - canvas_draw_frame(canvas, 0, 0, 128, 64); - canvas_set_font(canvas, FontPrimary); - - if(!ctx->detected_device) { - ctx->mode_page = ModePageScan; - } else if(ctx->mode_page == ModePageScan) { - ctx->mode_page = ModePageFound; - } - - /* if seen less than a quarter second ago */ - switch(ctx->mode_page) { - case ModePageScan: { - draw_model(canvas); - - canvas_draw_str_aligned(canvas, 64, y, AlignCenter, AlignBottom, "Searching"); - y += 14; - - canvas_set_font(canvas, FontSecondary); - - bool info_page = (ctx->loop_count % 500) >= 250; - if(info_page) { - canvas_draw_str(canvas, 2, y, "Connect GND with target GND"); - y += 10; - canvas_draw_str(canvas, 2, y, "and any two GPIOs with pads"); - y += 10; - canvas_draw_str(canvas, 2, y, "you want to check for SWD"); - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 111, 62, "2/2"); - } else { - const char* filename = ""; - if(strlen(ctx->script_detected) > 0) { - const char* slash = strrchr(ctx->script_detected, '/'); - if(slash) { - filename = &slash[1]; - } else { - filename = ctx->script_detected; - } - } - - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 64, y, AlignCenter, AlignBottom, "Autoexec Script"); - y += 10; - canvas_set_font(canvas, FontKeyboard); - canvas_draw_str_aligned(canvas, 64, y, AlignCenter, AlignBottom, filename); - y += 16; - - canvas_set_font(canvas, FontSecondary); - canvas_draw_icon(canvas, 14, y - 5, &I_ButtonUp_7x4); - canvas_draw_icon(canvas, 78, y - 5, &I_ButtonDown_7x4); - canvas_draw_str(canvas, 23, y, "Clear"); - canvas_draw_str(canvas, 87, y, "Choose"); - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 111, 62, "1/2"); - } - canvas_set_font(canvas, FontSecondary); - elements_button_left(canvas, "Script"); - break; - } - case ModePageFound: { - if((ctx->detected_timeout + TIMER_HZ / 4) >= TIMER_HZ * TIMEOUT) { - snprintf(buffer, sizeof(buffer), "FOUND!"); - } else { - /* if it was seen more than a quarter second ago, show countdown */ - snprintf( - buffer, sizeof(buffer), "FOUND! (%lus)", (ctx->detected_timeout / TIMER_HZ) + 1); - } - canvas_draw_str_aligned(canvas, 64, y, AlignCenter, AlignBottom, buffer); - y += 10; - canvas_set_font(canvas, FontKeyboard); - - snprintf( - buffer, - sizeof(buffer), - "SWC/SWD: %s/%s", - gpio_name(ctx->io_swc), - gpio_name(ctx->io_swd)); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - y += 10; - snprintf(buffer, sizeof(buffer), "DPIDR 0x%08lX", ctx->dp_regs.dpidr); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - y += 10; - - snprintf( - buffer, - sizeof(buffer), - "Part %02X Rev %X DAPv%d", - ctx->dpidr_info.partno, - ctx->dpidr_info.revision, - ctx->dpidr_info.version); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - y += 10; - - canvas_set_font(canvas, FontSecondary); - snprintf(buffer, sizeof(buffer), "%s", jep106_manufacturer(ctx->dpidr_info.designer)); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - y += 10; - - canvas_set_font(canvas, FontSecondary); - elements_button_left(canvas, "Script"); - elements_button_right(canvas, "DP Regs"); - - break; - } - case ModePageDPRegs: { - canvas_draw_str_aligned(canvas, 64, y, AlignCenter, AlignBottom, "DP Registers"); - y += 10; - canvas_set_font(canvas, FontKeyboard); - if(ctx->dp_regs.dpidr_ok) { - snprintf(buffer, sizeof(buffer), "DPIDR %08lX", ctx->dp_regs.dpidr); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - } - y += 10; - - if(ctx->dp_regs.ctrlstat_ok) { - snprintf(buffer, sizeof(buffer), "CTRL %08lX", ctx->dp_regs.ctrlstat); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - } - y += 10; - - if(ctx->dp_regs.targetid_ok) { - snprintf(buffer, sizeof(buffer), "TGTID %08lX", ctx->dp_regs.targetid); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - } - y += 10; - - if(ctx->dp_regs.eventstat_ok) { - snprintf(buffer, sizeof(buffer), "EVTST %08lX", ctx->dp_regs.eventstat); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - } - y += 10; - canvas_set_font(canvas, FontSecondary); - elements_button_left(canvas, "Scan"); - elements_button_right(canvas, "DPID"); - - break; - } - - case ModePageDPID: { - canvas_draw_str_aligned(canvas, 64, y, AlignCenter, AlignBottom, "DP ID Register"); - y += 10; - canvas_set_font(canvas, FontKeyboard); - if(ctx->dpidr_info.version != 2) { - snprintf(buffer, sizeof(buffer), "TARGETID not supported"); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - y += 10; - } else { - if(ctx->dp_regs.targetid_ok) { - snprintf(buffer, sizeof(buffer), "TGTID %08lX", ctx->dp_regs.targetid); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - y += 10; - - snprintf(buffer, sizeof(buffer), "Part No. %04X", ctx->targetid_info.partno); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - y += 10; - snprintf( - buffer, sizeof(buffer), "%s", jep106_manufacturer(ctx->targetid_info.designer)); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - y += 10; - } - } - canvas_set_font(canvas, FontSecondary); - elements_button_left(canvas, "DP Regs"); - elements_button_right(canvas, "APs"); - break; - } - - case ModePageAPID: { - canvas_draw_str_aligned(canvas, 64, y, AlignCenter, AlignBottom, "AP Menu"); - y += 10; - canvas_set_font(canvas, FontKeyboard); - - char state = ' '; - if(ctx->ap_pos >= ctx->ap_scanned && ctx->ap_pos <= ctx->ap_scanned + 10) { - state = '*'; - } - - if(!ctx->apidr_info[ctx->ap_pos].ok) { - snprintf(buffer, sizeof(buffer), "[%d]%c", ctx->ap_pos, state); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - y += 10; - - if(ctx->ap_pos == 0) { - for(size_t pos = 0; pos < COUNT(ctx->apidr_info); pos++) { - if(ctx->apidr_info[pos].ok) { - ctx->ap_pos = pos; - } - } - } - } else { - const char* class = ""; - - switch(ctx->apidr_info[ctx->ap_pos].class) { - case 0: - class = "und"; - break; - case 1: - class = "COM"; - break; - case 8: - class = "MEM"; - break; - default: - class = "unk"; - break; - } - - const char* types[] = { - "COM-AP", - "AHB3", - "APB2 or APB3", - "Type unknown", - "AXI3 or AXI4", - "AHB5", - "APB4 and APB5", - "AXI5", - "AHB5 enh.", - }; - const char* type = "Type unk"; - - if(ctx->apidr_info[ctx->ap_pos].type < COUNT(types)) { - type = types[ctx->apidr_info[ctx->ap_pos].type]; - } - - snprintf(buffer, sizeof(buffer), "[%d]%c%s, %s", ctx->ap_pos, state, class, type); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - y += 10; - - snprintf(buffer, sizeof(buffer), "Base 0x%08lX", ctx->apidr_info[ctx->ap_pos].base); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - y += 10; - - snprintf( - buffer, - sizeof(buffer), - "Rev %d Var %d", - ctx->apidr_info[ctx->ap_pos].revision, - ctx->apidr_info[ctx->ap_pos].variant); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - y += 10; - - snprintf( - buffer, - sizeof(buffer), - "%s", - jep106_manufacturer(ctx->apidr_info[ctx->ap_pos].designer)); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - y += 10; - - elements_button_center(canvas, "Show"); - } - canvas_set_font(canvas, FontSecondary); - elements_button_left(canvas, "DPID"); - elements_button_right(canvas, "CoreS."); - elements_scrollbar_pos(canvas, 4, 10, 40, ctx->ap_pos / 32, COUNT(ctx->apidr_info) / 32); - break; - } - - /* hex dump view */ - case ModePageHexDump: { - canvas_draw_str_aligned(canvas, 64, y, AlignCenter, AlignBottom, "Hex dump"); - y += 10; - canvas_set_font(canvas, FontKeyboard); - - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, "Addr:"); - - snprintf(buffer, sizeof(buffer), "%08lX", ctx->hex_addr); - canvas_draw_str_aligned(canvas, 38, y, AlignLeft, AlignBottom, buffer); - uint32_t font_width = canvas_glyph_width(canvas, '0'); - uint32_t x = 37 + (7 - ctx->hex_select) * font_width; - - /* draw selection */ - canvas_draw_line(canvas, x, y + 1, x + font_width, y + 1); - y += 10; - - uint32_t byte_num = 0; - for(int line = 0; line < 4; line++) { - uint32_t x_pos = 5; - - for(int byte_pos = 0; byte_pos < 8; byte_pos++) { - if(ctx->hex_buffer_valid[byte_num / 4]) { - snprintf(buffer, sizeof(buffer), "%02X", ctx->hex_buffer[byte_num]); - } else { - snprintf(buffer, sizeof(buffer), "--"); - } - byte_num++; - canvas_draw_str_aligned(canvas, x_pos, y, AlignLeft, AlignBottom, buffer); - x_pos += font_width * 2 + font_width / 2; - } - y += 10; - } - break; - } - - case ModePageCoresight: { - canvas_draw_str_aligned(canvas, 64, y, AlignCenter, AlignBottom, "Coresight"); - y += 10; - canvas_set_font(canvas, FontSecondary); - - uint32_t base = ctx->coresight_bases[ctx->coresight_level]; - uint32_t base_next = adi_romtable_get(ctx, base, ctx->coresight_pos[ctx->coresight_level]); - - snprintf(buffer, sizeof(buffer), "Base: %08lX", base); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - y += 10; - snprintf(buffer, sizeof(buffer), "Type: %s", adi_romtable_type(ctx, base)); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - y += 10; - snprintf(buffer, sizeof(buffer), "Full: %s", adi_romtable_full(ctx, base)); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - y += 10; - - if(adi_is_romtable(ctx, base)) { - snprintf( - buffer, - sizeof(buffer), - "[%lu/%lu] -> %08lX", - ctx->coresight_pos[ctx->coresight_level] + 1, - ctx->coresight_count[ctx->coresight_level], - base_next); - canvas_draw_str_aligned(canvas, 5, y, AlignLeft, AlignBottom, buffer); - canvas_set_font(canvas, FontSecondary); - elements_button_center(canvas, "Enter"); - } - y += 10; - - canvas_set_font(canvas, FontSecondary); - - if(ctx->coresight_level) { - elements_button_left(canvas, "Prev"); - } else { - elements_button_left(canvas, "APs"); - } - elements_scrollbar_pos( - canvas, - 4, - 10, - 40, - ctx->coresight_pos[ctx->coresight_level], - ctx->coresight_count[ctx->coresight_level]); - - break; - } - - /* hex dump view */ - case ModePageScript: { - canvas_draw_str_aligned(canvas, 64, y, AlignCenter, AlignBottom, "Script"); - y += 10; - y += 10; - canvas_draw_str_aligned(canvas, 10, y, AlignLeft, AlignBottom, "Status:"); - y += 10; - canvas_set_font(canvas, FontKeyboard); - canvas_draw_str_aligned(canvas, 64, y, AlignCenter, AlignBottom, ctx->state_string); - y += 10; - break; - } - } - - furi_mutex_release(ctx->gui_mutex); -} - -static void input_callback(InputEvent* input_event, void* ctx_in) { - furi_assert(input_event); - furi_assert(ctx_in); - AppFSM* ctx = ctx_in; - - int entries = furi_message_queue_get_count(ctx->event_queue); - - /* better skip than sorry */ - if(entries < QUEUE_SIZE) { - AppEvent event = {.type = EventKeyPress, .input = *input_event}; - furi_message_queue_put(ctx->event_queue, &event, 0); - } -} - -static void app_init(AppFSM* const app) { - furi_assert(app); - - app->loop_count = 0; - app->current_mask_id = 0; - app->current_mask = gpio_direction_mask[app->current_mask_id]; - app->io_swd = 0xFF; - app->io_swc = 0xFF; - app->hex_addr = 0x40002800; - app->hex_addr = 0xE000EDF0; - app->swd_clock_delay = CLOCK_DELAY; - app->swd_idle_bits = IDLE_BITS; - - strcpy(app->state_string, "none"); - strcpy(app->script_detected, ""); -} - -static void app_deinit(AppFSM* const app) { - furi_assert(app); - - strcpy(app->state_string, "exiting"); -} - -static void swd_main_loop(AppFSM* ctx) { - furi_assert(ctx); - - ctx->loop_count++; - - switch(ctx->mode_page) { - case ModePageScan: - case ModePageFound: { - /* reset after timeout */ - if(ctx->detected_timeout > 0) { - ctx->detected_timeout--; - } else { - DBGS("Reset detected flag"); - ctx->detected_device = false; - ctx->io_swd = 0xFF; - ctx->io_swc = 0xFF; - ctx->io_num_swd = 0xFF; - ctx->io_num_swc = 0xFF; - ctx->ap_scanned = 0; - memset(&ctx->dp_regs, 0x00, sizeof(ctx->dp_regs)); - memset(&ctx->targetid_info, 0x00, sizeof(ctx->targetid_info)); - memset(&ctx->apidr_info, 0x00, sizeof(ctx->apidr_info)); - ctx->script_detected_executed = false; - } - - ctx->detected = false; - ctx->current_mask = gpio_direction_mask[ctx->current_mask_id]; - - /* when SWD was already detected, set it to data pin regardless of the mask */ - if(ctx->detected_device) { - ctx->current_mask &= ~ctx->io_swd; - } - - /* do the scan */ - furi_mutex_acquire(ctx->swd_mutex, FuriWaitForever); - swd_scan(ctx); - furi_mutex_release(ctx->swd_mutex); - - /* now when detected a device, set the timeout */ - if(ctx->detected) { - DBGS("Set detected flag"); - ctx->detected_device = true; - ctx->detected_timeout = TIMER_HZ * TIMEOUT; - - /* update DPIDR fields */ - ctx->dpidr_info.revision = (ctx->dp_regs.dpidr >> 28) & 0x0F; - ctx->dpidr_info.partno = (ctx->dp_regs.dpidr >> 20) & 0xFF; - ctx->dpidr_info.version = (ctx->dp_regs.dpidr >> 12) & 0x0F; - ctx->dpidr_info.designer = (ctx->dp_regs.dpidr >> 1) & 0x3FF; - - if(!has_multiple_bits(ctx->io_swc)) { - DBGS(" - Detected pins"); - DBGS(" - Resetting error"); - - furi_mutex_acquire(ctx->swd_mutex, FuriWaitForever); - /* reset error */ - /* first make sure we have the correct bank by invalidating the current select cache */ - ctx->dp_regs.select_ok = false; - uint8_t ack = - swd_read_dpbank(ctx, REG_CTRLSTAT, REG_CTRLSTAT_BANK, &ctx->dp_regs.ctrlstat); - - if(ack != 1 || (ctx->dp_regs.ctrlstat & STAT_ERROR_FLAGS)) { - DBGS(" - send ABORT"); - swd_abort(ctx); - } - DBGS(" - Fetch CTRL/STAT"); - ctx->dp_regs.ctrlstat_ok = - swd_read_dpbank( - ctx, REG_CTRLSTAT, REG_CTRLSTAT_BANK, &ctx->dp_regs.ctrlstat) == 1; - DBG(" %08lX %s", - ctx->dp_regs.ctrlstat, - ctx->dp_regs.ctrlstat_ok ? "OK" : "FAIL"); - - if(ctx->dpidr_info.version >= 1) { - DBGS(" - DAPv1, read DLCR"); - ctx->dp_regs.dlcr_ok = - swd_read_dpbank(ctx, REG_DLCR, REG_DLCR_BANK, &ctx->dp_regs.dlcr) == 1; - DBG(" %08lX %s", ctx->dp_regs.dlcr, ctx->dp_regs.dlcr_ok ? "OK" : "FAIL"); - } - - if(ctx->dpidr_info.version >= 2) { - DBGS(" - DAPv2, read TARGETID"); - ctx->dp_regs.targetid_ok = - swd_read_dpbank( - ctx, REG_TARGETID, REG_TARGETID_BANK, &ctx->dp_regs.targetid) == 1; - DBG(" %08lX %s", - ctx->dp_regs.targetid, - ctx->dp_regs.targetid_ok ? "OK" : "FAIL"); - DBGS(" - DAPv2, read EVENTSTAT"); - ctx->dp_regs.eventstat_ok = - swd_read_dpbank( - ctx, REG_EVENTSTAT, REG_EVENTSTAT_BANK, &ctx->dp_regs.eventstat) == 1; - DBG(" %08lX %s", - ctx->dp_regs.eventstat, - ctx->dp_regs.eventstat_ok ? "OK" : "FAIL"); - DBGS(" - DAPv2, read DLPIDR"); - ctx->dp_regs.dlpidr_ok = - swd_read_dpbank(ctx, REG_DLPIDR, REG_DLPIDR_BANK, &ctx->dp_regs.dlpidr) == - 1; - DBG(" %08lX %s", - ctx->dp_regs.dlpidr, - ctx->dp_regs.dlpidr_ok ? "OK" : "FAIL"); - } - - if(ctx->dp_regs.targetid_ok) { - ctx->targetid_info.revision = (ctx->dp_regs.targetid >> 28) & 0x0F; - ctx->targetid_info.partno = (ctx->dp_regs.targetid >> 12) & 0xFFFF; - ctx->targetid_info.designer = (ctx->dp_regs.targetid >> 1) & 0x3FF; - } - - if(!ctx->script_detected_executed && strlen(ctx->script_detected) > 0) { - DBG(" - Run script '%s'", ctx->script_detected); - - ctx->script_detected_executed = true; - - ctx->mode_page = ModePageScript; - swd_execute_script(ctx, ctx->script_detected); - ctx->mode_page = ModePageFound; - } - furi_mutex_release(ctx->swd_mutex); - } - } else { - if(!has_multiple_bits(ctx->io_swc)) { - DBGS(" - Lost device"); - } - } - - ctx->current_mask_id = (ctx->current_mask_id + 1) % COUNT(gpio_direction_mask); - break; - } - - case ModePageDPRegs: - case ModePageAPID: { - furi_mutex_acquire(ctx->swd_mutex, FuriWaitForever); - /* set debug enable request */ - if(!swd_ensure_powerup(ctx)) { - furi_mutex_release(ctx->swd_mutex); - break; - } - - /* only scan a few APs at once to stay responsive */ - for(int pos = 0; pos < 8; pos++) { - if(ctx->ap_scanned == 0) { - swd_apscan_reset(ctx); - } - - uint8_t ap = ctx->ap_scanned++; - - if(ctx->apidr_info[ap].tested) { - continue; - } - if(swd_apscan_test(ctx, ap)) { - break; - } - } - furi_mutex_release(ctx->swd_mutex); - break; - } - - case ModePageHexDump: { - furi_mutex_acquire(ctx->swd_mutex, FuriWaitForever); - - for(size_t byte_pos = 0; byte_pos < sizeof(ctx->hex_buffer); byte_pos += 4) { - uint32_t* data = (uint32_t*)&ctx->hex_buffer[byte_pos]; - bool ret = swd_read_memory(ctx, ctx->ap_pos, ctx->hex_addr + byte_pos, data) == 1; - - ctx->hex_buffer_valid[byte_pos / 4] = ret; - - if(!ret) { - swd_abort_simple(ctx); - } - } - furi_mutex_release(ctx->swd_mutex); - break; - } - - case ModePageDPID: - case ModePageCoresight: - furi_delay_ms(50); - break; - } -} - -static bool swd_message_process(AppFSM* ctx) { - bool processing = true; - AppEvent event; - - /* wait to make sure the OS can do its stuff */ - FuriStatus event_status = furi_message_queue_get(ctx->event_queue, &event, 1000 / TIMER_HZ); - - if(event_status != FuriStatusOk) { - return processing; - } - - if(event.type == EventKeyPress) { - if(event.input.type == InputTypePress) { - switch(event.input.key) { - case InputKeyUp: - switch(ctx->mode_page) { - default: - break; - - case ModePageScan: - case ModePageFound: { - strcpy(ctx->script_detected, ""); - break; - } - - case ModePageAPID: - if(ctx->ap_pos > 0) { - ctx->ap_pos--; - } - break; - - case ModePageHexDump: { - ctx->hex_addr += ((ctx->hex_select) ? 1 : 8) * (1 << (4 * ctx->hex_select)); - break; - } - - case ModePageCoresight: { - if(ctx->coresight_pos[ctx->coresight_level] > 0) { - ctx->coresight_pos[ctx->coresight_level]--; - } - break; - } - } - break; - - case InputKeyDown: { - switch(ctx->mode_page) { - default: - break; - - case ModePageScan: { - FuriString* result_path = furi_string_alloc_printf(SWD_PATH); - FuriString* preselected = furi_string_alloc_printf( - (strlen(ctx->script_detected) > 0) ? ctx->script_detected : SWD_PATH); - DialogsFileBrowserOptions options; - - dialog_file_browser_set_basic_options(&options, "swd", &I_swd); - - if(dialog_file_browser_show(ctx->dialogs, result_path, preselected, &options)) { - const char* path = furi_string_get_cstr(result_path); - strcpy(ctx->script_detected, path); - } - - furi_string_free(result_path); - furi_string_free(preselected); - break; - } - - case ModePageAPID: - if(ctx->ap_pos + 1U < COUNT(ctx->apidr_info)) { - ctx->ap_pos++; - } - break; - - case ModePageHexDump: { - ctx->hex_addr -= ((ctx->hex_select) ? 1 : 8) * (1 << (4 * ctx->hex_select)); - break; - } - - case ModePageCoresight: { - if(ctx->coresight_pos[ctx->coresight_level] + 1 < - ctx->coresight_count[ctx->coresight_level]) { - ctx->coresight_pos[ctx->coresight_level]++; - } - break; - } - } - break; - } - - case InputKeyRight: - if(ctx->mode_page == ModePageHexDump) { - if(ctx->hex_select > 0) { - ctx->hex_select--; - } - } else if(ctx->mode_page == ModePageAPID && ctx->apidr_info[ctx->ap_pos].ok) { - ctx->mode_page = ModePageCoresight; - uint32_t base = ctx->apidr_info[ctx->ap_pos].base & 0xFFFFF000; - ctx->coresight_level = 0; - ctx->coresight_bases[ctx->coresight_level] = base; - ctx->coresight_pos[ctx->coresight_level] = 0; - ctx->coresight_count[ctx->coresight_level] = - adi_romtable_entry_count(ctx, base); - } else if(ctx->detected) { - if(ctx->mode_page + 1 < ModePageCount) { - ctx->mode_page++; - } - } - break; - - case InputKeyLeft: - if(ctx->mode_page == ModePageHexDump) { - if(ctx->hex_select < 7) { - ctx->hex_select++; - } - } else if(ctx->mode_page == ModePageCoresight) { - if(ctx->coresight_level > 0) { - ctx->coresight_level--; - } else { - ctx->mode_page = ModePageAPID; - } - } else if((ctx->mode_page == ModePageScan) || (ctx->mode_page == ModePageFound)) { - uint32_t mode_page = ctx->mode_page; - FuriString* result_path = furi_string_alloc_printf(SWD_PATH); - FuriString* preselected = furi_string_alloc_printf( - (strlen(ctx->script_detected) > 0) ? ctx->script_detected : SWD_PATH); - DialogsFileBrowserOptions options; - - dialog_file_browser_set_basic_options(&options, "swd", &I_swd); - - if(dialog_file_browser_show(ctx->dialogs, result_path, preselected, &options)) { - const char* path = furi_string_get_cstr(result_path); - ctx->mode_page = ModePageScript; - swd_execute_script(ctx, path); - ctx->mode_page = mode_page; - } - - furi_string_free(result_path); - furi_string_free(preselected); - break; - } else { - if(ctx->mode_page > 0) { - ctx->mode_page--; - } - } - break; - - case InputKeyOk: - if(ctx->mode_page == ModePageAPID && ctx->apidr_info[ctx->ap_pos].ok) { - ctx->mode_page = ModePageHexDump; - } else if(ctx->mode_page == ModePageCoresight) { - uint32_t base = ctx->coresight_bases[ctx->coresight_level]; - - if(!adi_is_romtable(ctx, base)) { - break; - } - - uint32_t cur_pos = ctx->coresight_pos[ctx->coresight_level]; - uint32_t base_next = adi_romtable_get(ctx, base, cur_pos); - uint32_t new_count = adi_romtable_entry_count(ctx, base_next); - - ctx->coresight_level++; - ctx->coresight_pos[ctx->coresight_level] = 0; - ctx->coresight_count[ctx->coresight_level] = new_count; - ctx->coresight_bases[ctx->coresight_level] = base_next; - } - break; - - case InputKeyBack: - if(ctx->mode_page == ModePageHexDump) { - ctx->mode_page = ModePageAPID; - } else if(ctx->mode_page == ModePageScript) { - ctx->script->abort = true; - } else if(ctx->mode_page > ModePageFound) { - ctx->mode_page = ModePageScan; - } else if(ctx->mode_page == ModePageScan) { - processing = false; - } else if(ctx->mode_page == ModePageFound) { - processing = false; - } - break; - - default: - break; - } - } - } - return processing; -} - -size_t data_received(void* ctx, uint8_t* data, size_t length) { - AppFSM* app = (AppFSM*)ctx; - - strncpy(app->commandline->line_data, (const char*)data, length); - app->commandline->line_pos = 0; - - for(size_t pos = 0; pos < length; pos++) { - uint8_t ch = app->commandline->line_data[pos]; - - if((ch == '\r') || (ch == '\n')) { - app->commandline->line_data[pos++] = '\n'; - app->commandline->line_data[pos] = 0; - LOG("direct command '%s'", app->commandline->line_data); - swd_execute_script_line(app->commandline); - return pos; - } - } - - return 0; -} - -int32_t swd_probe_app_main(void* p) { - UNUSED(p); - - AppFSM* app = malloc(sizeof(AppFSM)); - - DBGS("App init"); - app_init(app); - - DBGS("furi_record_open"); - app->notification = furi_record_open(RECORD_NOTIFICATION); - app->gui = furi_record_open(RECORD_GUI); - app->dialogs = furi_record_open(RECORD_DIALOGS); - app->storage = furi_record_open(RECORD_STORAGE); - storage_common_migrate(app->storage, EXT_PATH("swd_scripts"), SWD_PATH); - - DBGS("furi_mutex_alloc"); - app->swd_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - app->gui_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - app->event_queue = furi_message_queue_alloc(QUEUE_SIZE, sizeof(AppEvent)); - - DBGS("usb_uart_enable"); - UsbUartConfig uart_config; - uart_config.vcp_ch = 1; - uart_config.rx_data = &data_received; - uart_config.rx_data_ctx = app; - app->uart = usb_uart_enable(&uart_config); - - app->commandline = malloc(sizeof(ScriptContext)); - app->commandline->max_tries = 1; - app->commandline->app = app; - - DBGS("view_port_alloc"); - 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); - - DBGS("notification_message_block"); - notification_message(app->notification, &sequence_display_backlight_enforce_on); - - DBGS("swd_execute_script"); - swd_execute_script(app, SWD_PATH "/startup.swd"); - - dolphin_deed(DolphinDeedPluginGameStart); - - DBGS("processing"); - for(bool processing = true; processing;) { - swd_main_loop(app); - view_port_update(app->view_port); - - processing = swd_message_process(app); - - bool beep = false; - - if(app->detected_device && !app->detected_notified) { - app->detected_notified = true; - beep = true; - } - if(!app->detected_device && app->detected_notified) { - app->detected_notified = false; - } - if(beep) { - notification_message_block(app->notification, &seq_c_minor); - } - } - - view_port_enabled_set(app->view_port, false); - gui_remove_view_port(app->gui, app->view_port); - view_port_free(app->view_port); - - app_deinit(app); - - notification_message(app->notification, &sequence_display_backlight_enforce_auto); - - usb_uart_disable(app->uart); - - furi_message_queue_free(app->event_queue); - furi_mutex_free(app->gui_mutex); - furi_mutex_free(app->swd_mutex); - - // Reset GPIO pins to default state - for(int io = 0; io < 8; io++) { - furi_hal_gpio_init(gpios[io], GpioModeAnalog, GpioPullNo, GpioSpeedLow); - } - free(app); - - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_NOTIFICATION); - furi_record_close(RECORD_DIALOGS); - furi_record_close(RECORD_STORAGE); - - return 0; -} diff --git a/applications/external/swd_probe/swd_probe_app.h b/applications/external/swd_probe/swd_probe_app.h deleted file mode 100644 index 5a45a4fd9..000000000 --- a/applications/external/swd_probe/swd_probe_app.h +++ /dev/null @@ -1,244 +0,0 @@ -#ifndef __SWD_PROBE_APP_H -#define __SWD_PROBE_APP_H - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "usb_uart.h" - -#define TAG "SWD" - -/* short debug message */ -#define DBGS(format) furi_log_print_format(FuriLogLevelDebug, TAG, "%s: " format, __FUNCTION__) -/* formatted debug message */ -#define DBG(format, ...) \ - furi_log_print_format(FuriLogLevelDebug, TAG, "%s: " format, __FUNCTION__, __VA_ARGS__) -/* log message*/ -#define LOG(...) furi_log_print_format(FuriLogLevelDefault, TAG, __VA_ARGS__) - -#define COUNT(x) ((size_t)(sizeof(x) / sizeof((x)[0]))) -#define ARRAY_SIZE(x) COUNT(x) - -#define SWD_DELAY_US 0 -#define TIMER_HZ 25 -#define TIMEOUT 3 -#define QUEUE_SIZE 8 -#define IDLE_BITS 8 -#define CLOCK_DELAY 0 - -#define MAX_FILE_LENGTH 128 -#define SCRIPT_MAX_LINES 1000 - -typedef enum { - ModePageScan = 0, - ModePageFound = 1, - ModePageDPRegs = 2, - ModePageDPID = 3, - ModePageAPID = 4, - ModePageCount = 5, - ModePageHexDump = 0x100, - ModePageScript = 0x101, - ModePageCoresight = 0x102, -} ModePages; - -#define CDBGPWRUPREQ (1 << 28) -#define CDBGPWRUPACK (1 << 29) -#define CSYSPWRUPREQ (1 << 30) -#define CSYSPWRUPACK (1 << 31) -#define WDATAERR (1 << 7) -#define STICKYERR (1 << 5) -#define STAT_ERROR_FLAGS (WDATAERR | STICKYERR) - -#define REG_IDCODE 0x00 -#define REG_CTRLSTAT 0x01 -#define REG_CTRLSTAT_BANK 0x00 -#define REG_DLCR 0x01 -#define REG_DLCR_BANK 0x01 -#define REG_TARGETID 0x01 -#define REG_TARGETID_BANK 0x02 -#define REG_DLPIDR 0x01 -#define REG_DLPIDR_BANK 0x03 -#define REG_EVENTSTAT 0x01 -#define REG_EVENTSTAT_BANK 0x04 - -#define REG_SELECT 0x02 - -#define MEMAP_CSW 0x00 -#define MEMAP_TAR 0x04 -#define MEMAP_DRW 0x0C -#define AP_IDR 0xFC -#define AP_BASE 0xF8 - -#define SCS_CPUID 0xE000ED00u -#define SCS_CPACR 0xE000ED88u -#define SCS_DHCSR 0xE000EDF0u -#define SCS_DHCSR_S_HALT (1u << 17) -#define SCS_DHCSR_C_MASKINTS (1u << 3) -#define SCS_DHCSR_C_STEP (1u << 2) -#define SCS_DHCSR_C_HALT (1u << 1) -#define SCS_DHCSR_C_DEBUGEN (1u << 0) -#define SCS_DHCSR_KEY 0xA05F0000u -#define SCS_DCRSR 0xE000EDF4u -#define SCS_DCRSR_RD 0x00000000u -#define SCS_DCRSR_WR 0x00010000u -#define SCS_DCRDR 0xE000EDF8u -#define SCS_DEMCR 0xE000EDFCu - -typedef enum { KeyNone, KeyUp, KeyRight, KeyDown, KeyLeft, KeyOK } KeyCode; - -typedef enum { - EventTimerTick, - EventKeyPress, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} AppEvent; - -typedef struct { - uint32_t ctrlstat; - bool ctrlstat_ok; - uint32_t dlcr; - bool dlcr_ok; - uint32_t dlpidr; - bool dlpidr_ok; - uint32_t dpidr; - bool dpidr_ok; - uint32_t eventstat; - bool eventstat_ok; - uint32_t select; - bool select_ok; - uint32_t targetid; - bool targetid_ok; -} swd_dpreg_t; - -typedef struct { - bool ok; - bool tested; - uint8_t revision; - uint16_t designer; - uint8_t class; - uint8_t variant; - uint8_t type; - uint32_t base; -} swd_apidr_info_t; - -typedef struct { - uint8_t revision; - uint8_t partno; - uint8_t version; - uint16_t designer; -} swd_dpidr_info_t; - -typedef struct { - uint8_t revision; - uint16_t partno; - uint16_t designer; -} swd_targetid_info_t; - -typedef struct sScriptContext ScriptContext; - -typedef struct { - Storage* storage; - Gui* gui; - DialogsApp* dialogs; - NotificationApp* notification; - - FuriTimer* timer; - UsbUart* uart; - ViewPort* view_port; - - FuriMessageQueue* event_queue; - FuriMutex* swd_mutex; - FuriMutex* gui_mutex; - - swd_targetid_info_t targetid_info; - swd_dpidr_info_t dpidr_info; - swd_dpreg_t dp_regs; - swd_apidr_info_t apidr_info[256]; - - ScriptContext* script; - ScriptContext* commandline; - - uint8_t timeout_overdue; - uint32_t loop_count; - uint8_t current_mask_id; - uint32_t current_mask; - uint8_t io_swc; - uint8_t io_swd; - uint8_t io_num_swc; - uint8_t io_num_swd; - int32_t detected_timeout; - uint32_t swd_clock_delay; - uint32_t swd_idle_bits; - bool detected; - bool detected_device; - bool detected_notified; - uint32_t mode_page; - uint8_t ap_pos; - uint8_t ap_scanned; - - uint32_t coresight_pos[16]; - uint32_t coresight_count[16]; - uint8_t coresight_level; - uint32_t coresight_bases[16]; - - uint32_t hex_addr; - uint8_t hex_select; - uint8_t hex_buffer[32]; - uint8_t hex_buffer_valid[8]; - - char state_string[64]; - char script_detected[MAX_FILE_LENGTH]; - bool script_detected_executed; -} AppFSM; - -struct sScriptContext { - AppFSM* app; - ScriptContext* parent; - char filename[MAX_FILE_LENGTH]; - - /* when used with string input */ - char line_data[128]; - uint64_t line_pos; - - /* when used with file input */ - File* script_file; - - uint64_t position; - uint32_t selected_ap; - uint32_t max_tries; - uint32_t block_size; - - bool abort; - bool restart; - bool errors_ignore; - bool status_ignore; - bool goto_active; - char goto_label[64]; -}; - -typedef struct { - const char* prefix; - bool (*func)(ScriptContext* ctx); -} ScriptFunctionInfo; - -uint8_t swd_read_memory(AppFSM* const ctx, uint8_t ap, uint32_t address, uint32_t* data); - -#endif \ No newline at end of file diff --git a/applications/external/swd_probe/usb_uart.c b/applications/external/swd_probe/usb_uart.c deleted file mode 100644 index 9674541ec..000000000 --- a/applications/external/swd_probe/usb_uart.c +++ /dev/null @@ -1,229 +0,0 @@ - -#include - -#include "usb_uart.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) - -typedef enum { - WorkerEvtStop = (1 << 0), - WorkerEvtCdcRx = (1 << 1), - WorkerEvtCfgChange = (1 << 2) - -} WorkerEvtFlags; - -#define WORKER_ALL_EVENTS (WorkerEvtStop | WorkerEvtCfgChange | WorkerEvtCdcRx) - -struct UsbUart { - UsbUartConfig cfg; - UsbUartConfig cfg_new; - - FuriThread* thread; - 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 = { - .tx_ep_callback = &vcp_on_cdc_tx_complete, - .rx_ep_callback = &vcp_on_cdc_rx, - .state_callback = &vcp_state_callback, - .ctrl_line_callback = &vcp_on_cdc_control_line, - .config_callback = &vcp_on_line_config}; - -static void usb_uart_vcp_init(UsbUart* usb_uart, uint8_t vcp_ch) { - furi_hal_usb_unlock(); - - Cli* cli = furi_record_open(RECORD_CLI); - cli_session_close(cli); - - if(vcp_ch == 0) { - 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_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(UsbUart* 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); - } -} - -bool usb_uart_tx_data(UsbUart* usb_uart, uint8_t* data, size_t length) { - uint32_t pos = 0; - while(pos < length) { - size_t pkt_size = length - pos; - - if(pkt_size > USB_CDC_PKT_LEN) { - pkt_size = USB_CDC_PKT_LEN; - } - - if(furi_semaphore_acquire(usb_uart->tx_sem, 100) != FuriStatusOk) { - return false; - } - if(furi_mutex_acquire(usb_uart->usb_mutex, 100) != FuriStatusOk) { - furi_semaphore_release(usb_uart->tx_sem); - return false; - } - furi_hal_cdc_send(usb_uart->cfg.vcp_ch, &data[pos], pkt_size); - furi_mutex_release(usb_uart->usb_mutex); - usb_uart->st.tx_cnt += pkt_size; - pos += pkt_size; - } - return true; -} - -static int32_t usb_uart_worker(void* context) { - UsbUart* usb_uart = (UsbUart*)context; - - memcpy(&usb_uart->cfg, &usb_uart->cfg_new, sizeof(UsbUartConfig)); - - usb_uart->tx_sem = furi_semaphore_alloc(1, 1); - usb_uart->usb_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - - usb_uart_vcp_init(usb_uart, usb_uart->cfg.vcp_ch); - - uint8_t data[2 * USB_CDC_PKT_LEN]; - size_t remain = 0; - - while(1) { - uint32_t events = - furi_thread_flags_wait(WORKER_ALL_EVENTS, FuriFlagWaitAny, FuriWaitForever); - furi_check(!(events & FuriFlagError)); - - if(events & WorkerEvtStop) { - break; - } - - if(events & WorkerEvtCdcRx) { - size_t len = 0; - if(furi_mutex_acquire(usb_uart->usb_mutex, 100) == FuriStatusOk) { - len = furi_hal_cdc_receive(usb_uart->cfg.vcp_ch, &data[remain], USB_CDC_PKT_LEN); - furi_mutex_release(usb_uart->usb_mutex); - } - - if(len > 0) { - usb_uart->st.rx_cnt += len; - remain += len; - - size_t handled = usb_uart->cfg.rx_data(usb_uart->cfg.rx_data_ctx, data, remain); - - memcpy(data, &data[handled], remain - handled); - remain -= handled; - } - } - - if(events & WorkerEvtCfgChange) { - if(usb_uart->cfg.vcp_ch != usb_uart->cfg_new.vcp_ch) { - 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; - } - api_lock_unlock(usb_uart->cfg_lock); - } - } - usb_uart_vcp_deinit(usb_uart, usb_uart->cfg.vcp_ch); - - 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; -} - -/* VCP callbacks */ -static void vcp_on_cdc_tx_complete(void* context) { - UsbUart* usb_uart = (UsbUart*)context; - furi_semaphore_release(usb_uart->tx_sem); -} - -static void vcp_on_cdc_rx(void* context) { - UsbUart* usb_uart = (UsbUart*)context; - furi_thread_flags_set(furi_thread_get_id(usb_uart->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(context); - UNUSED(state); -} - -static void vcp_on_line_config(void* context, struct usb_cdc_line_coding* config) { - UNUSED(context); - UNUSED(config); -} - -UsbUart* usb_uart_enable(UsbUartConfig* cfg) { - UsbUart* usb_uart = malloc(sizeof(UsbUart)); - 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(UsbUart* 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(UsbUart* 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(UsbUart* usb_uart, UsbUartConfig* cfg) { - furi_assert(usb_uart); - furi_assert(cfg); - memcpy(cfg, &(usb_uart->cfg_new), sizeof(UsbUartConfig)); -} - -void usb_uart_get_state(UsbUart* usb_uart, UsbUartState* st) { - furi_assert(usb_uart); - furi_assert(st); - memcpy(st, &(usb_uart->st), sizeof(UsbUartState)); -} diff --git a/applications/external/swd_probe/usb_uart.h b/applications/external/swd_probe/usb_uart.h deleted file mode 100644 index 325a4db98..000000000 --- a/applications/external/swd_probe/usb_uart.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include -#include - -typedef struct UsbUart UsbUart; - -typedef struct { - uint8_t vcp_ch; - size_t (*rx_data)(void* ctx, uint8_t* data, size_t length); - void* rx_data_ctx; -} UsbUartConfig; - -typedef struct { - uint32_t rx_cnt; - uint32_t tx_cnt; -} UsbUartState; - -UsbUart* usb_uart_enable(UsbUartConfig* cfg); - -void usb_uart_disable(UsbUart* usb_uart); - -void usb_uart_set_config(UsbUart* usb_uart, UsbUartConfig* cfg); - -void usb_uart_get_config(UsbUart* usb_uart, UsbUartConfig* cfg); - -void usb_uart_get_state(UsbUart* usb_uart, UsbUartState* st); - -bool usb_uart_tx_data(UsbUart* usb_uart, uint8_t* data, size_t length); diff --git a/applications/external/timelapse/application.fam b/applications/external/timelapse/application.fam deleted file mode 100644 index e59dc9722..000000000 --- a/applications/external/timelapse/application.fam +++ /dev/null @@ -1,16 +0,0 @@ -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, - fap_icon_assets="icons", - fap_icon="zeitraffer.png", - fap_category="GPIO", - fap_version="1.1", - fap_description="Simple intervalometer app, works via GPIO pins.", - fap_author="Aurelius Rosenbaum", - fap_weburl="https://github.com/theageoflove/flipperzero-zeitraffer", -) diff --git a/applications/external/timelapse/gpio_item.c b/applications/external/timelapse/gpio_item.c deleted file mode 100644 index 2d0f5f676..000000000 --- a/applications/external/timelapse/gpio_item.c +++ /dev/null @@ -1,51 +0,0 @@ -#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/external/timelapse/gpio_item.h b/applications/external/timelapse/gpio_item.h deleted file mode 100644 index 5cb2b86c1..000000000 --- a/applications/external/timelapse/gpio_item.h +++ /dev/null @@ -1,15 +0,0 @@ -#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/external/timelapse/icons/ButtonDownHollow_7x4.png b/applications/external/timelapse/icons/ButtonDownHollow_7x4.png deleted file mode 100644 index 2b87c43647d56c78a2c5ff5ecee6b3c9641c57fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)I!2~4FF4?37q!^2X+?^QKos)S9l1X>;b!1@J z*w6hZkrl}2EbxddW?{W77j*6W#z~B_y7O*=kMVYCpZ{Ri)wIhc380j PXc~j3tDnm{r-UW|ZJjr; diff --git a/applications/external/timelapse/icons/ButtonLeftHollow_4x7.png b/applications/external/timelapse/icons/ButtonLeftHollow_4x7.png deleted file mode 100644 index 374dc7d1ac7aa9c4725681c145ef2f61b7869b77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^EI`c8!2~21uvfPODaPU;cPEB*=VV@jWYZme9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucK`l=g#}J9|v pae)j+>jQ^K9-aVZhZ;6Eh9@nu@2ZLtD}cHfJYD@<);T3K0RWG@CDZ@_ diff --git a/applications/external/timelapse/icons/ButtonRightHollow_4x7.png b/applications/external/timelapse/icons/ButtonRightHollow_4x7.png deleted file mode 100644 index acbb0859267d431885e1998146e04f2cdfdb46b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^EI`c8!2~21uvfPODaPU;cPEB*=VV@jWYZme9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucK@CqA#}J9|gTe~DWM4fbu1?j diff --git a/applications/external/timelapse/icons/ButtonUpHollow_7x4.png b/applications/external/timelapse/icons/ButtonUpHollow_7x4.png deleted file mode 100644 index e88ee332230e98938ba769e8813a671040140987..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 143 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)I!2~4FF4?37q!^2X+?^QKos)S9l1X>;b!1@J z*w6hZkrl}2EbxddW? -#include -#include -#include -#include -#include -#include "gpio_item.h" -#include "gpio_timelapse_icons.h" -#include - -#define CONFIG_FILE_DIRECTORY_PATH "/ext/apps_data/timelapse" -#define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/timelapse.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"); - } - - if(Work) { - canvas_draw_icon(canvas, 85, 41, &I_ButtonUpHollow_7x4); - canvas_draw_icon(canvas, 85, 57, &I_ButtonDownHollow_7x4); - canvas_draw_icon(canvas, 59, 48, &I_ButtonLeftHollow_4x7); - canvas_draw_icon(canvas, 72, 48, &I_ButtonRightHollow_4x7); - } else { - 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(!storage_simply_mkdir(storage, CONFIG_FILE_DIRECTORY_PATH)) { - notification_message(notifications, &sequence_error); - break; - } - 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 == 1) WorkTime = Time; - - 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; - } - } - } - view_port_update(view_port); - } - - // Наше событие — это сработавший таймер - 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); - } - - view_port_update(view_port); - } - 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/external/timelapse/zeitraffer.png b/applications/external/timelapse/zeitraffer.png deleted file mode 100644 index 3a42e406d179a5649f29c3d07e42935612819217..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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