Просмотр исходного кода

Move apps from flipperzero firmware into separate repository

Aleksandr Kutuzov 2 лет назад
Сommit
881d9be39f
100 измененных файлов с 19314 добавлено и 0 удалено
  1. 3 0
      ReadMe.md
  2. 17 0
      avr_isp_programmer/application.fam
  3. BIN
      avr_isp_programmer/avr_app_icon_10x10.png
  4. 179 0
      avr_isp_programmer/avr_isp_app.c
  5. 31 0
      avr_isp_programmer/avr_isp_app_i.c
  6. 44 0
      avr_isp_programmer/avr_isp_app_i.h
  7. 496 0
      avr_isp_programmer/helpers/avr_isp.c
  8. 70 0
      avr_isp_programmer/helpers/avr_isp.h
  9. 23 0
      avr_isp_programmer/helpers/avr_isp_event.h
  10. 32 0
      avr_isp_programmer/helpers/avr_isp_types.h
  11. 266 0
      avr_isp_programmer/helpers/avr_isp_worker.c
  12. 49 0
      avr_isp_programmer/helpers/avr_isp_worker.h
  13. 1157 0
      avr_isp_programmer/helpers/avr_isp_worker_rw.c
  14. 99 0
      avr_isp_programmer/helpers/avr_isp_worker_rw.h
  15. 321 0
      avr_isp_programmer/helpers/flipper_i32hex_file.c
  16. 55 0
      avr_isp_programmer/helpers/flipper_i32hex_file.h
  17. BIN
      avr_isp_programmer/images/avr_app_icon_10x10.png
  18. BIN
      avr_isp_programmer/images/avr_wiring.png
  19. BIN
      avr_isp_programmer/images/chif_not_found_83x37.png
  20. BIN
      avr_isp_programmer/images/chip_error_70x22.png
  21. BIN
      avr_isp_programmer/images/chip_long_70x22.png
  22. BIN
      avr_isp_programmer/images/chip_not_found_83x37.png
  23. BIN
      avr_isp_programmer/images/dolphin_nice_96x59.png
  24. BIN
      avr_isp_programmer/images/isp_active_128x53.png
  25. BIN
      avr_isp_programmer/images/link_waiting_77x56.png
  26. 386 0
      avr_isp_programmer/lib/driver/avr_isp_chip_arr.c
  27. 33 0
      avr_isp_programmer/lib/driver/avr_isp_chip_arr.h
  28. 639 0
      avr_isp_programmer/lib/driver/avr_isp_prog.c
  29. 16 0
      avr_isp_programmer/lib/driver/avr_isp_prog.h
  30. 97 0
      avr_isp_programmer/lib/driver/avr_isp_prog_cmd.h
  31. 71 0
      avr_isp_programmer/lib/driver/avr_isp_spi_sw.c
  32. 24 0
      avr_isp_programmer/lib/driver/avr_isp_spi_sw.h
  33. BIN
      avr_isp_programmer/lib/driver/clock.png
  34. 30 0
      avr_isp_programmer/scenes/avr_isp_scene.c
  35. 29 0
      avr_isp_programmer/scenes/avr_isp_scene.h
  36. 99 0
      avr_isp_programmer/scenes/avr_isp_scene_about.c
  37. 72 0
      avr_isp_programmer/scenes/avr_isp_scene_chip_detect.c
  38. 10 0
      avr_isp_programmer/scenes/avr_isp_scene_config.h
  39. 89 0
      avr_isp_programmer/scenes/avr_isp_scene_input_name.c
  40. 22 0
      avr_isp_programmer/scenes/avr_isp_scene_load.c
  41. 28 0
      avr_isp_programmer/scenes/avr_isp_scene_programmer.c
  42. 64 0
      avr_isp_programmer/scenes/avr_isp_scene_reader.c
  43. 75 0
      avr_isp_programmer/scenes/avr_isp_scene_start.c
  44. 44 0
      avr_isp_programmer/scenes/avr_isp_scene_success.c
  45. 21 0
      avr_isp_programmer/scenes/avr_isp_scene_wiring.c
  46. 69 0
      avr_isp_programmer/scenes/avr_isp_scene_writer.c
  47. 213 0
      avr_isp_programmer/views/avr_isp_view_chip_detect.c
  48. 32 0
      avr_isp_programmer/views/avr_isp_view_chip_detect.h
  49. 134 0
      avr_isp_programmer/views/avr_isp_view_programmer.c
  50. 27 0
      avr_isp_programmer/views/avr_isp_view_programmer.h
  51. 215 0
      avr_isp_programmer/views/avr_isp_view_reader.c
  52. 35 0
      avr_isp_programmer/views/avr_isp_view_reader.h
  53. 268 0
      avr_isp_programmer/views/avr_isp_view_writer.c
  54. 37 0
      avr_isp_programmer/views/avr_isp_view_writer.h
  55. 10 0
      clock/application.fam
  56. BIN
      clock/clock.png
  57. 136 0
      clock/clock_app.c
  58. 105 0
      dap_link/README.md
  59. 24 0
      dap_link/application.fam
  60. 234 0
      dap_link/dap_config.h
  61. 527 0
      dap_link/dap_link.c
  62. 55 0
      dap_link/dap_link.h
  63. BIN
      dap_link/dap_link.png
  64. 92 0
      dap_link/gui/dap_gui.c
  65. 4 0
      dap_link/gui/dap_gui.h
  66. 7 0
      dap_link/gui/dap_gui_custom_event.h
  67. 34 0
      dap_link/gui/dap_gui_i.h
  68. 30 0
      dap_link/gui/scenes/config/dap_scene.c
  69. 29 0
      dap_link/gui/scenes/config/dap_scene.h
  70. 4 0
      dap_link/gui/scenes/config/dap_scene_config.h
  71. 68 0
      dap_link/gui/scenes/dap_scene_about.c
  72. 107 0
      dap_link/gui/scenes/dap_scene_config.c
  73. 102 0
      dap_link/gui/scenes/dap_scene_help.c
  74. 154 0
      dap_link/gui/scenes/dap_scene_main.c
  75. 189 0
      dap_link/gui/views/dap_main_view.c
  76. 45 0
      dap_link/gui/views/dap_main_view.h
  77. BIN
      dap_link/icons/ActiveConnection_50x64.png
  78. BIN
      dap_link/icons/ArrowUpEmpty_12x18.png
  79. BIN
      dap_link/icons/ArrowUpFilled_12x18.png
  80. 27 0
      dap_link/lib/free-dap/LICENSE
  81. 100 0
      dap_link/lib/free-dap/README.md
  82. BIN
      dap_link/lib/free-dap/bin/free_dap_rp2040.uf2
  83. 1509 0
      dap_link/lib/free-dap/dap.c
  84. 50 0
      dap_link/lib/free-dap/dap.h
  85. 3 0
      dap_link/lib/free-dap/hardware/d11-nano-dbg/.gitignore
  86. BIN
      dap_link/lib/free-dap/hardware/d11-nano-dbg/d11-nano-dbg-gerbers.zip
  87. 4933 0
      dap_link/lib/free-dap/hardware/d11-nano-dbg/d11-nano-dbg.kicad_pcb
  88. 75 0
      dap_link/lib/free-dap/hardware/d11-nano-dbg/d11-nano-dbg.kicad_prl
  89. 435 0
      dap_link/lib/free-dap/hardware/d11-nano-dbg/d11-nano-dbg.kicad_pro
  90. 1673 0
      dap_link/lib/free-dap/hardware/d11-nano-dbg/d11-nano-dbg.kicad_sch
  91. BIN
      dap_link/lib/free-dap/hardware/d11-nano-dbg/d11-nano-dbg.pdf
  92. 5 0
      dap_link/lib/free-dap/hardware/d11-nano-dbg/pcb.kicad_wks
  93. 15 0
      dap_link/lib/free-dap/hardware/d11-nano-dbg/sch.kicad_wks
  94. 700 0
      dap_link/lib/free-dap/hardware/d11_micro_std_vcp/d11_micro_std_vcp.brd
  95. BIN
      dap_link/lib/free-dap/hardware/d11_micro_std_vcp/d11_micro_std_vcp.pdf
  96. 1314 0
      dap_link/lib/free-dap/hardware/d11_micro_std_vcp/d11_micro_std_vcp.sch
  97. BIN
      dap_link/lib/free-dap/hardware/d11_micro_std_vcp/d11_micro_std_vcp_gerber.zip
  98. BIN
      dap_link/lib/free-dap/hardware/d11_micro_std_vcp_v2/d11_micro_std_vcp_v2-gerbers.zip
  99. 798 0
      dap_link/lib/free-dap/hardware/d11_micro_std_vcp_v2/d11_micro_std_vcp_v2.brd
  100. BIN
      dap_link/lib/free-dap/hardware/d11_micro_std_vcp_v2/d11_micro_std_vcp_v2.pdf

+ 3 - 0
ReadMe.md

@@ -0,0 +1,3 @@
+# About
+
+Flipper Application Collection, previously Flipper External apps

+ 17 - 0
avr_isp_programmer/application.fam

@@ -0,0 +1,17 @@
+App(
+    appid="avr_isp",
+    name="AVR Flasher",
+    apptype=FlipperAppType.EXTERNAL,
+    entry_point="avr_isp_app",
+    requires=["gui"],
+    stack_size=4 * 1024,
+    order=20,
+    fap_icon="avr_app_icon_10x10.png",
+    fap_category="GPIO",
+    fap_icon_assets="images",
+    fap_private_libs=[
+        Lib(
+            name="driver",
+        ),
+    ],
+)

BIN
avr_isp_programmer/avr_app_icon_10x10.png


+ 179 - 0
avr_isp_programmer/avr_isp_app.c

@@ -0,0 +1,179 @@
+#include "avr_isp_app_i.h"
+
+static bool avr_isp_app_custom_event_callback(void* context, uint32_t event) {
+    furi_assert(context);
+    AvrIspApp* app = context;
+    return scene_manager_handle_custom_event(app->scene_manager, event);
+}
+
+static bool avr_isp_app_back_event_callback(void* context) {
+    furi_assert(context);
+    AvrIspApp* app = context;
+    return scene_manager_handle_back_event(app->scene_manager);
+}
+
+static void avr_isp_app_tick_event_callback(void* context) {
+    furi_assert(context);
+    AvrIspApp* app = context;
+    scene_manager_handle_tick_event(app->scene_manager);
+}
+
+AvrIspApp* avr_isp_app_alloc() {
+    AvrIspApp* app = malloc(sizeof(AvrIspApp));
+
+    app->file_path = furi_string_alloc();
+    furi_string_set(app->file_path, STORAGE_APP_DATA_PATH_PREFIX);
+    app->error = AvrIspErrorNoError;
+
+    // GUI
+    app->gui = furi_record_open(RECORD_GUI);
+
+    // View Dispatcher
+    app->view_dispatcher = view_dispatcher_alloc();
+    app->scene_manager = scene_manager_alloc(&avr_isp_scene_handlers, app);
+    view_dispatcher_enable_queue(app->view_dispatcher);
+
+    view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
+    view_dispatcher_set_custom_event_callback(
+        app->view_dispatcher, avr_isp_app_custom_event_callback);
+    view_dispatcher_set_navigation_event_callback(
+        app->view_dispatcher, avr_isp_app_back_event_callback);
+    view_dispatcher_set_tick_event_callback(
+        app->view_dispatcher, avr_isp_app_tick_event_callback, 100);
+
+    view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
+
+    // Open Notification record
+    app->notifications = furi_record_open(RECORD_NOTIFICATION);
+
+    // SubMenu
+    app->submenu = submenu_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher, AvrIspViewSubmenu, submenu_get_view(app->submenu));
+
+    // Widget
+    app->widget = widget_alloc();
+    view_dispatcher_add_view(app->view_dispatcher, AvrIspViewWidget, widget_get_view(app->widget));
+
+    // Text Input
+    app->text_input = text_input_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher, AvrIspViewTextInput, text_input_get_view(app->text_input));
+
+    // Popup
+    app->popup = popup_alloc();
+    view_dispatcher_add_view(app->view_dispatcher, AvrIspViewPopup, popup_get_view(app->popup));
+
+    //Dialog
+    app->dialogs = furi_record_open(RECORD_DIALOGS);
+
+    // Programmer view
+    app->avr_isp_programmer_view = avr_isp_programmer_view_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher,
+        AvrIspViewProgrammer,
+        avr_isp_programmer_view_get_view(app->avr_isp_programmer_view));
+
+    // Reader view
+    app->avr_isp_reader_view = avr_isp_reader_view_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher,
+        AvrIspViewReader,
+        avr_isp_reader_view_get_view(app->avr_isp_reader_view));
+
+    // Writer view
+    app->avr_isp_writer_view = avr_isp_writer_view_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher,
+        AvrIspViewWriter,
+        avr_isp_writer_view_get_view(app->avr_isp_writer_view));
+
+    // Chip detect view
+    app->avr_isp_chip_detect_view = avr_isp_chip_detect_view_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher,
+        AvrIspViewChipDetect,
+        avr_isp_chip_detect_view_get_view(app->avr_isp_chip_detect_view));
+
+    // Enable 5v power, multiple attempts to avoid issues with power chip protection false triggering
+    uint8_t attempts = 0;
+    while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
+        furi_hal_power_enable_otg();
+        furi_delay_ms(10);
+    }
+
+    scene_manager_next_scene(app->scene_manager, AvrIspSceneStart);
+
+    return app;
+} //-V773
+
+void avr_isp_app_free(AvrIspApp* app) {
+    furi_assert(app);
+
+    // Disable 5v power
+    if(furi_hal_power_is_otg_enabled()) {
+        furi_hal_power_disable_otg();
+    }
+
+    // Submenu
+    view_dispatcher_remove_view(app->view_dispatcher, AvrIspViewSubmenu);
+    submenu_free(app->submenu);
+
+    //  Widget
+    view_dispatcher_remove_view(app->view_dispatcher, AvrIspViewWidget);
+    widget_free(app->widget);
+
+    // TextInput
+    view_dispatcher_remove_view(app->view_dispatcher, AvrIspViewTextInput);
+    text_input_free(app->text_input);
+
+    // Popup
+    view_dispatcher_remove_view(app->view_dispatcher, AvrIspViewPopup);
+    popup_free(app->popup);
+
+    //Dialog
+    furi_record_close(RECORD_DIALOGS);
+
+    // Programmer view
+    view_dispatcher_remove_view(app->view_dispatcher, AvrIspViewProgrammer);
+    avr_isp_programmer_view_free(app->avr_isp_programmer_view);
+
+    // Reader view
+    view_dispatcher_remove_view(app->view_dispatcher, AvrIspViewReader);
+    avr_isp_reader_view_free(app->avr_isp_reader_view);
+
+    // Writer view
+    view_dispatcher_remove_view(app->view_dispatcher, AvrIspViewWriter);
+    avr_isp_writer_view_free(app->avr_isp_writer_view);
+
+    // Chip detect view
+    view_dispatcher_remove_view(app->view_dispatcher, AvrIspViewChipDetect);
+    avr_isp_chip_detect_view_free(app->avr_isp_chip_detect_view);
+
+    // View dispatcher
+    view_dispatcher_free(app->view_dispatcher);
+    scene_manager_free(app->scene_manager);
+
+    // Notifications
+    furi_record_close(RECORD_NOTIFICATION);
+    app->notifications = NULL;
+
+    // Close records
+    furi_record_close(RECORD_GUI);
+
+    // Path strings
+    furi_string_free(app->file_path);
+
+    free(app);
+}
+
+int32_t avr_isp_app(void* p) {
+    UNUSED(p);
+    AvrIspApp* avr_isp_app = avr_isp_app_alloc();
+
+    view_dispatcher_run(avr_isp_app->view_dispatcher);
+
+    avr_isp_app_free(avr_isp_app);
+
+    return 0;
+}

+ 31 - 0
avr_isp_programmer/avr_isp_app_i.c

@@ -0,0 +1,31 @@
+#include "avr_isp_app_i.h"
+#include <lib/toolbox/path.h>
+#include <flipper_format/flipper_format_i.h>
+
+#define TAG "AvrIsp"
+
+bool avr_isp_load_from_file(AvrIspApp* app) {
+    furi_assert(app);
+
+    FuriString* file_path = furi_string_alloc();
+    FuriString* file_name = furi_string_alloc();
+
+    DialogsFileBrowserOptions browser_options;
+    dialog_file_browser_set_basic_options(
+        &browser_options, AVR_ISP_APP_EXTENSION, &I_avr_app_icon_10x10);
+    browser_options.base_path = STORAGE_APP_DATA_PATH_PREFIX;
+
+    // Input events and views are managed by file_select
+    bool res = dialog_file_browser_show(app->dialogs, file_path, app->file_path, &browser_options);
+
+    if(res) {
+        path_extract_dirname(furi_string_get_cstr(file_path), app->file_path);
+        path_extract_filename(file_path, file_name, true);
+        strncpy(app->file_name_tmp, furi_string_get_cstr(file_name), AVR_ISP_MAX_LEN_NAME);
+    }
+
+    furi_string_free(file_name);
+    furi_string_free(file_path);
+
+    return res;
+}

+ 44 - 0
avr_isp_programmer/avr_isp_app_i.h

@@ -0,0 +1,44 @@
+#pragma once
+
+#include "helpers/avr_isp_types.h"
+#include <avr_isp_icons.h>
+
+#include "scenes/avr_isp_scene.h"
+#include <gui/gui.h>
+#include <gui/view_dispatcher.h>
+#include <gui/scene_manager.h>
+#include <gui/modules/submenu.h>
+#include <gui/modules/widget.h>
+#include <notification/notification_messages.h>
+#include <gui/modules/text_input.h>
+#include <dialogs/dialogs.h>
+#include <storage/storage.h>
+#include <gui/modules/popup.h>
+
+#include "views/avr_isp_view_programmer.h"
+#include "views/avr_isp_view_reader.h"
+#include "views/avr_isp_view_writer.h"
+#include "views/avr_isp_view_chip_detect.h"
+
+#define AVR_ISP_MAX_LEN_NAME 64
+
+typedef struct {
+    Gui* gui;
+    ViewDispatcher* view_dispatcher;
+    SceneManager* scene_manager;
+    NotificationApp* notifications;
+    DialogsApp* dialogs;
+    Popup* popup;
+    Submenu* submenu;
+    Widget* widget;
+    TextInput* text_input;
+    FuriString* file_path;
+    char file_name_tmp[AVR_ISP_MAX_LEN_NAME];
+    AvrIspProgrammerView* avr_isp_programmer_view;
+    AvrIspReaderView* avr_isp_reader_view;
+    AvrIspWriterView* avr_isp_writer_view;
+    AvrIspChipDetectView* avr_isp_chip_detect_view;
+    AvrIspError error;
+} AvrIspApp;
+
+bool avr_isp_load_from_file(AvrIspApp* app);

+ 496 - 0
avr_isp_programmer/helpers/avr_isp.c

@@ -0,0 +1,496 @@
+#include "avr_isp.h"
+#include "../lib/driver/avr_isp_prog_cmd.h"
+#include "../lib/driver/avr_isp_spi_sw.h"
+
+#include <furi.h>
+
+#define AVR_ISP_PROG_TX_RX_BUF_SIZE 320
+#define TAG "AvrIsp"
+
+struct AvrIsp {
+    AvrIspSpiSw* spi;
+    bool pmode;
+    AvrIspCallback callback;
+    void* context;
+};
+
+AvrIsp* avr_isp_alloc(void) {
+    AvrIsp* instance = malloc(sizeof(AvrIsp));
+    return instance;
+}
+
+void avr_isp_free(AvrIsp* instance) {
+    furi_assert(instance);
+
+    if(instance->spi) avr_isp_end_pmode(instance);
+    free(instance);
+}
+
+void avr_isp_set_tx_callback(AvrIsp* instance, AvrIspCallback callback, void* context) {
+    furi_assert(instance);
+    furi_assert(context);
+
+    instance->callback = callback;
+    instance->context = context;
+}
+
+uint8_t avr_isp_spi_transaction(
+    AvrIsp* instance,
+    uint8_t cmd,
+    uint8_t addr_hi,
+    uint8_t addr_lo,
+    uint8_t data) {
+    furi_assert(instance);
+
+    avr_isp_spi_sw_txrx(instance->spi, cmd);
+    avr_isp_spi_sw_txrx(instance->spi, addr_hi);
+    avr_isp_spi_sw_txrx(instance->spi, addr_lo);
+    return avr_isp_spi_sw_txrx(instance->spi, data);
+}
+
+static bool avr_isp_set_pmode(AvrIsp* instance, uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
+    furi_assert(instance);
+
+    uint8_t res = 0;
+    avr_isp_spi_sw_txrx(instance->spi, a);
+    avr_isp_spi_sw_txrx(instance->spi, b);
+    res = avr_isp_spi_sw_txrx(instance->spi, c);
+    avr_isp_spi_sw_txrx(instance->spi, d);
+    return res == 0x53;
+}
+
+void avr_isp_end_pmode(AvrIsp* instance) {
+    furi_assert(instance);
+
+    if(instance->pmode) {
+        avr_isp_spi_sw_res_set(instance->spi, true);
+        // We're about to take the target out of reset
+        // so configure SPI pins as input
+        if(instance->spi) avr_isp_spi_sw_free(instance->spi);
+        instance->spi = NULL;
+    }
+
+    instance->pmode = false;
+}
+
+static bool avr_isp_start_pmode(AvrIsp* instance, AvrIspSpiSwSpeed spi_speed) {
+    furi_assert(instance);
+
+    // Reset target before driving PIN_SCK or PIN_MOSI
+
+    // SPI.begin() will configure SS as output,
+    // so SPI master mode is selected.
+    // We have defined RESET as pin 10,
+    // which for many arduino's is not the SS pin.
+    // So we have to configure RESET as output here,
+    // (reset_target() first sets the correct level)
+    if(instance->spi) avr_isp_spi_sw_free(instance->spi);
+    instance->spi = avr_isp_spi_sw_init(spi_speed);
+
+    avr_isp_spi_sw_res_set(instance->spi, false);
+    // See avr datasheets, chapter "SERIAL_PRG Programming Algorithm":
+
+    // Pulse RESET after PIN_SCK is low:
+    avr_isp_spi_sw_sck_set(instance->spi, false);
+
+    // discharge PIN_SCK, value arbitrally chosen
+    furi_delay_ms(20);
+    avr_isp_spi_sw_res_set(instance->spi, true);
+
+    // Pulse must be minimum 2 target CPU speed cycles
+    // so 100 usec is ok for CPU speeds above 20KHz
+    furi_delay_ms(1);
+
+    avr_isp_spi_sw_res_set(instance->spi, false);
+
+    // Send the enable programming command:
+    // datasheet: must be > 20 msec
+    furi_delay_ms(50);
+    if(avr_isp_set_pmode(instance, AVR_ISP_SET_PMODE)) {
+        instance->pmode = true;
+        return true;
+    }
+    return false;
+}
+
+bool avr_isp_auto_set_spi_speed_start_pmode(AvrIsp* instance) {
+    furi_assert(instance);
+
+    AvrIspSpiSwSpeed spi_speed[] = {
+        AvrIspSpiSwSpeed1Mhz,
+        AvrIspSpiSwSpeed400Khz,
+        AvrIspSpiSwSpeed250Khz,
+        AvrIspSpiSwSpeed125Khz,
+        AvrIspSpiSwSpeed60Khz,
+        AvrIspSpiSwSpeed40Khz,
+        AvrIspSpiSwSpeed20Khz,
+        AvrIspSpiSwSpeed10Khz,
+        AvrIspSpiSwSpeed5Khz,
+        AvrIspSpiSwSpeed1Khz,
+    };
+    for(uint8_t i = 0; i < COUNT_OF(spi_speed); i++) {
+        if(avr_isp_start_pmode(instance, spi_speed[i])) {
+            AvrIspSignature sig = avr_isp_read_signature(instance);
+            AvrIspSignature sig_examination = avr_isp_read_signature(instance); //-V656
+            uint8_t y = 0;
+            while(y < 8) {
+                if(memcmp((uint8_t*)&sig, (uint8_t*)&sig_examination, sizeof(AvrIspSignature)) !=
+                   0)
+                    break;
+                sig_examination = avr_isp_read_signature(instance);
+                y++;
+            }
+            if(y == 8) {
+                if(spi_speed[i] > AvrIspSpiSwSpeed1Mhz) {
+                    if(i < (COUNT_OF(spi_speed) - 1)) {
+                        avr_isp_end_pmode(instance);
+                        i++;
+                        return avr_isp_start_pmode(instance, spi_speed[i]);
+                    }
+                }
+                return true;
+            }
+        }
+    }
+
+    if(instance->spi) {
+        avr_isp_spi_sw_free(instance->spi);
+        instance->spi = NULL;
+    }
+
+    return false;
+}
+
+static void avr_isp_commit(AvrIsp* instance, uint16_t addr, uint8_t data) {
+    furi_assert(instance);
+
+    avr_isp_spi_transaction(instance, AVR_ISP_COMMIT(addr));
+    /* polling flash */
+    if(data == 0xFF) {
+        furi_delay_ms(5);
+    } else {
+        /* polling flash */
+        uint32_t starttime = furi_get_tick();
+        while((furi_get_tick() - starttime) < 30) {
+            if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FLASH_HI(addr)) != 0xFF) {
+                break;
+            };
+        }
+    }
+}
+
+static uint16_t avr_isp_current_page(AvrIsp* instance, uint32_t addr, uint16_t page_size) {
+    furi_assert(instance);
+
+    uint16_t page = 0;
+    switch(page_size) {
+    case 32:
+        page = addr & 0xFFFFFFF0;
+        break;
+    case 64:
+        page = addr & 0xFFFFFFE0;
+        break;
+    case 128:
+        page = addr & 0xFFFFFFC0;
+        break;
+    case 256:
+        page = addr & 0xFFFFFF80;
+        break;
+
+    default:
+        page = addr;
+        break;
+    }
+
+    return page;
+}
+
+static bool avr_isp_flash_write_pages(
+    AvrIsp* instance,
+    uint16_t addr,
+    uint16_t page_size,
+    uint8_t* data,
+    uint32_t data_size) {
+    furi_assert(instance);
+
+    size_t x = 0;
+    uint16_t page = avr_isp_current_page(instance, addr, page_size);
+
+    while(x < data_size) {
+        if(page != avr_isp_current_page(instance, addr, page_size)) {
+            avr_isp_commit(instance, page, data[x - 1]);
+            page = avr_isp_current_page(instance, addr, page_size);
+        }
+        avr_isp_spi_transaction(instance, AVR_ISP_WRITE_FLASH_LO(addr, data[x++]));
+        avr_isp_spi_transaction(instance, AVR_ISP_WRITE_FLASH_HI(addr, data[x++]));
+        addr++;
+    }
+    avr_isp_commit(instance, page, data[x - 1]);
+    return true;
+}
+
+bool avr_isp_erase_chip(AvrIsp* instance) {
+    furi_assert(instance);
+
+    bool ret = false;
+    if(!instance->pmode) avr_isp_auto_set_spi_speed_start_pmode(instance);
+    if(instance->pmode) {
+        avr_isp_spi_transaction(instance, AVR_ISP_ERASE_CHIP);
+        furi_delay_ms(100);
+        avr_isp_end_pmode(instance);
+        ret = true;
+    }
+    return ret;
+}
+
+static bool
+    avr_isp_eeprom_write(AvrIsp* instance, uint16_t addr, uint8_t* data, uint32_t data_size) {
+    furi_assert(instance);
+
+    for(uint16_t i = 0; i < data_size; i++) {
+        avr_isp_spi_transaction(instance, AVR_ISP_WRITE_EEPROM(addr, data[i]));
+        furi_delay_ms(10);
+        addr++;
+    }
+    return true;
+}
+
+bool avr_isp_write_page(
+    AvrIsp* instance,
+    uint32_t mem_type,
+    uint32_t mem_size,
+    uint16_t addr,
+    uint16_t page_size,
+    uint8_t* data,
+    uint32_t data_size) {
+    furi_assert(instance);
+
+    bool ret = false;
+    switch(mem_type) {
+    case STK_SET_FLASH_TYPE:
+        if((addr + data_size / 2) <= mem_size) {
+            ret = avr_isp_flash_write_pages(instance, addr, page_size, data, data_size);
+        }
+        break;
+
+    case STK_SET_EEPROM_TYPE:
+        if((addr + data_size) <= mem_size) {
+            ret = avr_isp_eeprom_write(instance, addr, data, data_size);
+        }
+        break;
+
+    default:
+        furi_crash(TAG " Incorrect mem type.");
+        break;
+    }
+
+    return ret;
+}
+
+static bool avr_isp_flash_read_page(
+    AvrIsp* instance,
+    uint16_t addr,
+    uint16_t page_size,
+    uint8_t* data,
+    uint32_t data_size) {
+    furi_assert(instance);
+
+    if(page_size > data_size) return false;
+    for(uint16_t i = 0; i < page_size; i += 2) {
+        data[i] = avr_isp_spi_transaction(instance, AVR_ISP_READ_FLASH_LO(addr));
+        data[i + 1] = avr_isp_spi_transaction(instance, AVR_ISP_READ_FLASH_HI(addr));
+        addr++;
+    }
+    return true;
+}
+
+static bool avr_isp_eeprom_read_page(
+    AvrIsp* instance,
+    uint16_t addr,
+    uint16_t page_size,
+    uint8_t* data,
+    uint32_t data_size) {
+    furi_assert(instance);
+
+    if(page_size > data_size) return false;
+    for(uint16_t i = 0; i < page_size; i++) {
+        data[i] = avr_isp_spi_transaction(instance, AVR_ISP_READ_EEPROM(addr));
+        addr++;
+    }
+    return true;
+}
+
+bool avr_isp_read_page(
+    AvrIsp* instance,
+    uint32_t mem_type,
+    uint16_t addr,
+    uint16_t page_size,
+    uint8_t* data,
+    uint32_t data_size) {
+    furi_assert(instance);
+
+    bool res = false;
+    if(mem_type == STK_SET_FLASH_TYPE)
+        res = avr_isp_flash_read_page(instance, addr, page_size, data, data_size);
+    if(mem_type == STK_SET_EEPROM_TYPE)
+        res = avr_isp_eeprom_read_page(instance, addr, page_size, data, data_size);
+
+    return res;
+}
+
+AvrIspSignature avr_isp_read_signature(AvrIsp* instance) {
+    furi_assert(instance);
+
+    AvrIspSignature signature;
+    signature.vendor = avr_isp_spi_transaction(instance, AVR_ISP_READ_VENDOR);
+    signature.part_family = avr_isp_spi_transaction(instance, AVR_ISP_READ_PART_FAMILY);
+    signature.part_number = avr_isp_spi_transaction(instance, AVR_ISP_READ_PART_NUMBER);
+    return signature;
+}
+
+uint8_t avr_isp_read_lock_byte(AvrIsp* instance) {
+    furi_assert(instance);
+
+    uint8_t data = 0;
+    uint32_t starttime = furi_get_tick();
+    while((furi_get_tick() - starttime) < 300) {
+        data = avr_isp_spi_transaction(instance, AVR_ISP_READ_LOCK_BYTE);
+        if(avr_isp_spi_transaction(instance, AVR_ISP_READ_LOCK_BYTE) == data) {
+            break;
+        };
+        data = 0x00;
+    }
+    return data;
+}
+
+bool avr_isp_write_lock_byte(AvrIsp* instance, uint8_t lock) {
+    furi_assert(instance);
+
+    bool ret = false;
+    if(avr_isp_read_lock_byte(instance) == lock) {
+        ret = true;
+    } else {
+        avr_isp_spi_transaction(instance, AVR_ISP_WRITE_LOCK_BYTE(lock));
+        /* polling lock byte */
+        uint32_t starttime = furi_get_tick();
+        while((furi_get_tick() - starttime) < 30) {
+            if(avr_isp_spi_transaction(instance, AVR_ISP_READ_LOCK_BYTE) == lock) {
+                ret = true;
+                break;
+            };
+        }
+    }
+    return ret;
+}
+
+uint8_t avr_isp_read_fuse_low(AvrIsp* instance) {
+    furi_assert(instance);
+
+    uint8_t data = 0;
+    uint32_t starttime = furi_get_tick();
+    while((furi_get_tick() - starttime) < 300) {
+        data = avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_LOW);
+        if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_LOW) == data) {
+            break;
+        };
+        data = 0x00;
+    }
+    return data;
+}
+
+bool avr_isp_write_fuse_low(AvrIsp* instance, uint8_t lfuse) {
+    furi_assert(instance);
+
+    bool ret = false;
+    if(avr_isp_read_fuse_low(instance) == lfuse) {
+        ret = true;
+    } else {
+        avr_isp_spi_transaction(instance, AVR_ISP_WRITE_FUSE_LOW(lfuse));
+        /* polling fuse */
+        uint32_t starttime = furi_get_tick();
+        while((furi_get_tick() - starttime) < 30) {
+            if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_LOW) == lfuse) {
+                ret = true;
+                break;
+            };
+        }
+    }
+    return ret;
+}
+
+uint8_t avr_isp_read_fuse_high(AvrIsp* instance) {
+    furi_assert(instance);
+
+    uint8_t data = 0;
+    uint32_t starttime = furi_get_tick();
+    while((furi_get_tick() - starttime) < 300) {
+        data = avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_HIGH);
+        if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_HIGH) == data) {
+            break;
+        };
+        data = 0x00;
+    }
+    return data;
+}
+
+bool avr_isp_write_fuse_high(AvrIsp* instance, uint8_t hfuse) {
+    furi_assert(instance);
+
+    bool ret = false;
+    if(avr_isp_read_fuse_high(instance) == hfuse) {
+        ret = true;
+    } else {
+        avr_isp_spi_transaction(instance, AVR_ISP_WRITE_FUSE_HIGH(hfuse));
+        /* polling fuse */
+        uint32_t starttime = furi_get_tick();
+        while((furi_get_tick() - starttime) < 30) {
+            if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_HIGH) == hfuse) {
+                ret = true;
+                break;
+            };
+        }
+    }
+    return ret;
+}
+
+uint8_t avr_isp_read_fuse_extended(AvrIsp* instance) {
+    furi_assert(instance);
+
+    uint8_t data = 0;
+    uint32_t starttime = furi_get_tick();
+    while((furi_get_tick() - starttime) < 300) {
+        data = avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_EXTENDED);
+        if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_EXTENDED) == data) {
+            break;
+        };
+        data = 0x00;
+    }
+    return data;
+}
+
+bool avr_isp_write_fuse_extended(AvrIsp* instance, uint8_t efuse) {
+    furi_assert(instance);
+
+    bool ret = false;
+    if(avr_isp_read_fuse_extended(instance) == efuse) {
+        ret = true;
+    } else {
+        avr_isp_spi_transaction(instance, AVR_ISP_WRITE_FUSE_EXTENDED(efuse));
+        /* polling fuse */
+        uint32_t starttime = furi_get_tick();
+        while((furi_get_tick() - starttime) < 30) {
+            if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_EXTENDED) == efuse) {
+                ret = true;
+                break;
+            };
+        }
+    }
+    return ret;
+}
+
+void avr_isp_write_extended_addr(AvrIsp* instance, uint8_t extended_addr) {
+    furi_assert(instance);
+
+    avr_isp_spi_transaction(instance, AVR_ISP_EXTENDED_ADDR(extended_addr));
+    furi_delay_ms(10);
+}

+ 70 - 0
avr_isp_programmer/helpers/avr_isp.h

@@ -0,0 +1,70 @@
+#pragma once
+
+#include <furi_hal.h>
+
+typedef struct AvrIsp AvrIsp;
+typedef void (*AvrIspCallback)(void* context);
+
+struct AvrIspSignature {
+    uint8_t vendor;
+    uint8_t part_family;
+    uint8_t part_number;
+};
+
+typedef struct AvrIspSignature AvrIspSignature;
+
+AvrIsp* avr_isp_alloc(void);
+
+void avr_isp_free(AvrIsp* instance);
+
+void avr_isp_set_tx_callback(AvrIsp* instance, AvrIspCallback callback, void* context);
+
+bool avr_isp_auto_set_spi_speed_start_pmode(AvrIsp* instance);
+
+AvrIspSignature avr_isp_read_signature(AvrIsp* instance);
+
+void avr_isp_end_pmode(AvrIsp* instance);
+
+bool avr_isp_erase_chip(AvrIsp* instance);
+
+uint8_t avr_isp_spi_transaction(
+    AvrIsp* instance,
+    uint8_t cmd,
+    uint8_t addr_hi,
+    uint8_t addr_lo,
+    uint8_t data);
+
+bool avr_isp_read_page(
+    AvrIsp* instance,
+    uint32_t memtype,
+    uint16_t addr,
+    uint16_t page_size,
+    uint8_t* data,
+    uint32_t data_size);
+
+bool avr_isp_write_page(
+    AvrIsp* instance,
+    uint32_t mem_type,
+    uint32_t mem_size,
+    uint16_t addr,
+    uint16_t page_size,
+    uint8_t* data,
+    uint32_t data_size);
+
+uint8_t avr_isp_read_lock_byte(AvrIsp* instance);
+
+bool avr_isp_write_lock_byte(AvrIsp* instance, uint8_t lock);
+
+uint8_t avr_isp_read_fuse_low(AvrIsp* instance);
+
+bool avr_isp_write_fuse_low(AvrIsp* instance, uint8_t lfuse);
+
+uint8_t avr_isp_read_fuse_high(AvrIsp* instance);
+
+bool avr_isp_write_fuse_high(AvrIsp* instance, uint8_t hfuse);
+
+uint8_t avr_isp_read_fuse_extended(AvrIsp* instance);
+
+bool avr_isp_write_fuse_extended(AvrIsp* instance, uint8_t efuse);
+
+void avr_isp_write_extended_addr(AvrIsp* instance, uint8_t extended_addr);

+ 23 - 0
avr_isp_programmer/helpers/avr_isp_event.h

@@ -0,0 +1,23 @@
+#pragma once
+
+typedef enum {
+    //SubmenuIndex
+    SubmenuIndexAvrIspProgrammer = 10,
+    SubmenuIndexAvrIspReader,
+    SubmenuIndexAvrIspWriter,
+    SubmenuIndexAvrIsWiring,
+    SubmenuIndexAvrIspAbout,
+
+    //AvrIspCustomEvent
+    AvrIspCustomEventSceneChipDetectOk = 100,
+    AvrIspCustomEventSceneReadingOk,
+    AvrIspCustomEventSceneWritingOk,
+    AvrIspCustomEventSceneErrorVerification,
+    AvrIspCustomEventSceneErrorReading,
+    AvrIspCustomEventSceneErrorWriting,
+    AvrIspCustomEventSceneErrorWritingFuse,
+    AvrIspCustomEventSceneInputName,
+    AvrIspCustomEventSceneSuccess,
+    AvrIspCustomEventSceneExit,
+    AvrIspCustomEventSceneExitStartMenu,
+} AvrIspCustomEvent;

+ 32 - 0
avr_isp_programmer/helpers/avr_isp_types.h

@@ -0,0 +1,32 @@
+#pragma once
+
+#include <furi.h>
+#include <furi_hal.h>
+
+#define AVR_ISP_VERSION_APP "0.1"
+#define AVR_ISP_DEVELOPED "SkorP"
+#define AVR_ISP_GITHUB "https://github.com/flipperdevices/flipperzero-firmware"
+
+#define AVR_ISP_APP_FILE_VERSION 1
+#define AVR_ISP_APP_FILE_TYPE "Flipper Dump AVR"
+#define AVR_ISP_APP_EXTENSION ".avr"
+
+typedef enum {
+    //AvrIspViewVariableItemList,
+    AvrIspViewSubmenu,
+    AvrIspViewProgrammer,
+    AvrIspViewReader,
+    AvrIspViewWriter,
+    AvrIspViewWidget,
+    AvrIspViewPopup,
+    AvrIspViewTextInput,
+    AvrIspViewChipDetect,
+} AvrIspView;
+
+typedef enum {
+    AvrIspErrorNoError,
+    AvrIspErrorReading,
+    AvrIspErrorWriting,
+    AvrIspErrorVerification,
+    AvrIspErrorWritingFuse,
+} AvrIspError;

+ 266 - 0
avr_isp_programmer/helpers/avr_isp_worker.c

@@ -0,0 +1,266 @@
+#include "avr_isp_worker.h"
+#include <furi_hal_pwm.h>
+#include "../lib/driver/avr_isp_prog.h"
+#include "../lib/driver/avr_isp_prog_cmd.h"
+#include "../lib/driver/avr_isp_chip_arr.h"
+
+#include <furi.h>
+
+#define TAG "AvrIspWorker"
+
+typedef enum {
+    AvrIspWorkerEvtStop = (1 << 0),
+
+    AvrIspWorkerEvtRx = (1 << 1),
+    AvrIspWorkerEvtTxCoplete = (1 << 2),
+    AvrIspWorkerEvtTx = (1 << 3),
+    AvrIspWorkerEvtState = (1 << 4),
+
+    //AvrIspWorkerEvtCfg = (1 << 5),
+
+} AvrIspWorkerEvt;
+
+struct AvrIspWorker {
+    FuriThread* thread;
+    volatile bool worker_running;
+    uint8_t connect_usb;
+    AvrIspWorkerCallback callback;
+    void* context;
+};
+
+#define AVR_ISP_WORKER_PROG_ALL_EVENTS (AvrIspWorkerEvtStop)
+#define AVR_ISP_WORKER_ALL_EVENTS                                                             \
+    (AvrIspWorkerEvtTx | AvrIspWorkerEvtTxCoplete | AvrIspWorkerEvtRx | AvrIspWorkerEvtStop | \
+     AvrIspWorkerEvtState)
+
+//########################/* VCP CDC */#############################################
+#include "usb_cdc.h"
+#include <cli/cli_vcp.h>
+#include <cli/cli.h>
+#include <furi_hal_usb_cdc.h>
+
+#define AVR_ISP_VCP_CDC_CH 1
+#define AVR_ISP_VCP_CDC_PKT_LEN CDC_DATA_SZ
+#define AVR_ISP_VCP_UART_RX_BUF_SIZE (AVR_ISP_VCP_CDC_PKT_LEN * 5)
+
+static void vcp_on_cdc_tx_complete(void* context);
+static void vcp_on_cdc_rx(void* context);
+static void vcp_state_callback(void* context, uint8_t state);
+static void vcp_on_cdc_control_line(void* context, uint8_t state);
+static void vcp_on_line_config(void* context, struct usb_cdc_line_coding* config);
+
+static const CdcCallbacks cdc_cb = {
+    vcp_on_cdc_tx_complete,
+    vcp_on_cdc_rx,
+    vcp_state_callback,
+    vcp_on_cdc_control_line,
+    vcp_on_line_config,
+};
+
+/* VCP callbacks */
+
+static void vcp_on_cdc_tx_complete(void* context) {
+    furi_assert(context);
+    AvrIspWorker* instance = context;
+    furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerEvtTxCoplete);
+}
+
+static void vcp_on_cdc_rx(void* context) {
+    furi_assert(context);
+    AvrIspWorker* instance = context;
+    furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerEvtRx);
+}
+
+static void vcp_state_callback(void* context, uint8_t state) {
+    UNUSED(context);
+
+    AvrIspWorker* instance = context;
+    instance->connect_usb = state;
+    furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerEvtState);
+}
+
+static void vcp_on_cdc_control_line(void* context, uint8_t state) {
+    UNUSED(context);
+    UNUSED(state);
+}
+
+static void vcp_on_line_config(void* context, struct usb_cdc_line_coding* config) {
+    UNUSED(context);
+    UNUSED(config);
+}
+
+static void avr_isp_worker_vcp_cdc_init(void* context) {
+    furi_hal_usb_unlock();
+    Cli* cli = furi_record_open(RECORD_CLI);
+    //close cli
+    cli_session_close(cli);
+    //disable callbacks VCP_CDC=0
+    furi_hal_cdc_set_callbacks(0, NULL, NULL);
+    //set 2 cdc
+    furi_check(furi_hal_usb_set_config(&usb_cdc_dual, NULL) == true);
+    //open cli VCP_CDC=0
+    cli_session_open(cli, &cli_vcp);
+    furi_record_close(RECORD_CLI);
+
+    furi_hal_cdc_set_callbacks(AVR_ISP_VCP_CDC_CH, (CdcCallbacks*)&cdc_cb, context);
+}
+
+static void avr_isp_worker_vcp_cdc_deinit(void) {
+    //disable callbacks AVR_ISP_VCP_CDC_CH
+    furi_hal_cdc_set_callbacks(AVR_ISP_VCP_CDC_CH, NULL, NULL);
+
+    Cli* cli = furi_record_open(RECORD_CLI);
+    //close cli
+    cli_session_close(cli);
+    furi_hal_usb_unlock();
+    //set 1 cdc
+    furi_check(furi_hal_usb_set_config(&usb_cdc_single, NULL) == true);
+    //open cli VCP_CDC=0
+    cli_session_open(cli, &cli_vcp);
+    furi_record_close(RECORD_CLI);
+}
+
+//#################################################################################
+
+static int32_t avr_isp_worker_prog_thread(void* context) {
+    AvrIspProg* prog = context;
+    FURI_LOG_D(TAG, "AvrIspProgWorker Start");
+    while(1) {
+        if(furi_thread_flags_get() & AvrIspWorkerEvtStop) break;
+        avr_isp_prog_avrisp(prog);
+    }
+    FURI_LOG_D(TAG, "AvrIspProgWorker Stop");
+    return 0;
+}
+
+static void avr_isp_worker_prog_tx_data(void* context) {
+    furi_assert(context);
+    AvrIspWorker* instance = context;
+    furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerEvtTx);
+}
+
+/** Worker thread
+ * 
+ * @param context 
+ * @return exit code 
+ */
+static int32_t avr_isp_worker_thread(void* context) {
+    AvrIspWorker* instance = context;
+    avr_isp_worker_vcp_cdc_init(instance);
+
+    /* start PWM on &gpio_ext_pa4 */
+    furi_hal_pwm_start(FuriHalPwmOutputIdLptim2PA4, 4000000, 50);
+
+    AvrIspProg* prog = avr_isp_prog_init();
+    avr_isp_prog_set_tx_callback(prog, avr_isp_worker_prog_tx_data, instance);
+
+    uint8_t buf[AVR_ISP_VCP_UART_RX_BUF_SIZE];
+    size_t len = 0;
+
+    FuriThread* prog_thread =
+        furi_thread_alloc_ex("AvrIspProgWorker", 1024, avr_isp_worker_prog_thread, prog);
+    furi_thread_start(prog_thread);
+
+    FURI_LOG_D(TAG, "Start");
+
+    while(instance->worker_running) {
+        uint32_t events =
+            furi_thread_flags_wait(AVR_ISP_WORKER_ALL_EVENTS, FuriFlagWaitAny, FuriWaitForever);
+
+        if(events & AvrIspWorkerEvtRx) {
+            if(avr_isp_prog_spaces_rx(prog) >= AVR_ISP_VCP_CDC_PKT_LEN) {
+                len = furi_hal_cdc_receive(AVR_ISP_VCP_CDC_CH, buf, AVR_ISP_VCP_CDC_PKT_LEN);
+                // for(uint8_t i = 0; i < len; i++) {
+                //     FURI_LOG_I(TAG, "--> %X", buf[i]);
+                // }
+                avr_isp_prog_rx(prog, buf, len);
+            } else {
+                furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerEvtRx);
+            }
+        }
+
+        if((events & AvrIspWorkerEvtTxCoplete) || (events & AvrIspWorkerEvtTx)) {
+            len = avr_isp_prog_tx(prog, buf, AVR_ISP_VCP_CDC_PKT_LEN);
+
+            // for(uint8_t i = 0; i < len; i++) {
+            //     FURI_LOG_I(TAG, "<-- %X", buf[i]);
+            // }
+
+            if(len > 0) furi_hal_cdc_send(AVR_ISP_VCP_CDC_CH, buf, len);
+        }
+
+        if(events & AvrIspWorkerEvtStop) {
+            break;
+        }
+
+        if(events & AvrIspWorkerEvtState) {
+            if(instance->callback)
+                instance->callback(instance->context, (bool)instance->connect_usb);
+        }
+    }
+
+    FURI_LOG_D(TAG, "Stop");
+
+    furi_thread_flags_set(furi_thread_get_id(prog_thread), AvrIspWorkerEvtStop);
+    avr_isp_prog_exit(prog);
+    furi_delay_ms(10);
+    furi_thread_join(prog_thread);
+    furi_thread_free(prog_thread);
+
+    avr_isp_prog_free(prog);
+    furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4);
+    avr_isp_worker_vcp_cdc_deinit();
+    return 0;
+}
+
+AvrIspWorker* avr_isp_worker_alloc(void* context) {
+    furi_assert(context);
+    UNUSED(context);
+    AvrIspWorker* instance = malloc(sizeof(AvrIspWorker));
+
+    instance->thread = furi_thread_alloc_ex("AvrIspWorker", 2048, avr_isp_worker_thread, instance);
+    return instance;
+}
+
+void avr_isp_worker_free(AvrIspWorker* instance) {
+    furi_assert(instance);
+
+    furi_check(!instance->worker_running);
+    furi_thread_free(instance->thread);
+    free(instance);
+}
+
+void avr_isp_worker_set_callback(
+    AvrIspWorker* instance,
+    AvrIspWorkerCallback callback,
+    void* context) {
+    furi_assert(instance);
+
+    instance->callback = callback;
+    instance->context = context;
+}
+
+void avr_isp_worker_start(AvrIspWorker* instance) {
+    furi_assert(instance);
+    furi_assert(!instance->worker_running);
+
+    instance->worker_running = true;
+
+    furi_thread_start(instance->thread);
+}
+
+void avr_isp_worker_stop(AvrIspWorker* instance) {
+    furi_assert(instance);
+    furi_assert(instance->worker_running);
+
+    instance->worker_running = false;
+    furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerEvtStop);
+
+    furi_thread_join(instance->thread);
+}
+
+bool avr_isp_worker_is_running(AvrIspWorker* instance) {
+    furi_assert(instance);
+
+    return instance->worker_running;
+}

+ 49 - 0
avr_isp_programmer/helpers/avr_isp_worker.h

@@ -0,0 +1,49 @@
+#pragma once
+
+#include <furi_hal.h>
+
+typedef struct AvrIspWorker AvrIspWorker;
+
+typedef void (*AvrIspWorkerCallback)(void* context, bool connect_usb);
+
+/** Allocate AvrIspWorker
+ * 
+ * @param context AvrIsp* context
+ * @return AvrIspWorker* 
+ */
+AvrIspWorker* avr_isp_worker_alloc(void* context);
+
+/** Free AvrIspWorker
+ * 
+ * @param instance AvrIspWorker instance
+ */
+void avr_isp_worker_free(AvrIspWorker* instance);
+
+/** Callback AvrIspWorker
+ *
+ * @param instance AvrIspWorker instance
+ * @param callback AvrIspWorkerOverrunCallback callback
+ * @param context
+ */
+void avr_isp_worker_set_callback(
+    AvrIspWorker* instance,
+    AvrIspWorkerCallback callback,
+    void* context);
+
+/** Start AvrIspWorker
+ * 
+ * @param instance AvrIspWorker instance
+ */
+void avr_isp_worker_start(AvrIspWorker* instance);
+
+/** Stop AvrIspWorker
+ * 
+ * @param instance AvrIspWorker instance
+ */
+void avr_isp_worker_stop(AvrIspWorker* instance);
+
+/** Check if worker is running
+ * @param instance AvrIspWorker instance
+ * @return bool - true if running
+ */
+bool avr_isp_worker_is_running(AvrIspWorker* instance);

+ 1157 - 0
avr_isp_programmer/helpers/avr_isp_worker_rw.c

@@ -0,0 +1,1157 @@
+#include "avr_isp_worker_rw.h"
+#include <furi_hal_pwm.h>
+#include "avr_isp_types.h"
+#include "avr_isp.h"
+#include "../lib/driver/avr_isp_prog_cmd.h"
+#include "../lib/driver/avr_isp_chip_arr.h"
+
+#include "flipper_i32hex_file.h"
+#include <flipper_format/flipper_format.h>
+
+#include <furi.h>
+
+#define TAG "AvrIspWorkerRW"
+
+#define NAME_PATERN_FLASH_FILE "flash.hex"
+#define NAME_PATERN_EEPROM_FILE "eeprom.hex"
+
+struct AvrIspWorkerRW {
+    AvrIsp* avr_isp;
+    FuriThread* thread;
+    volatile bool worker_running;
+
+    uint32_t chip_arr_ind;
+    bool chip_detect;
+    uint8_t lfuse;
+    uint8_t hfuse;
+    uint8_t efuse;
+    uint8_t lock;
+    float progress_flash;
+    float progress_eeprom;
+    const char* file_path;
+    const char* file_name;
+    AvrIspSignature signature;
+    AvrIspWorkerRWCallback callback;
+    void* context;
+
+    AvrIspWorkerRWStatusCallback callback_status;
+    void* context_status;
+};
+
+typedef enum {
+    AvrIspWorkerRWEvtStop = (1 << 0),
+
+    AvrIspWorkerRWEvtReading = (1 << 1),
+    AvrIspWorkerRWEvtVerification = (1 << 2),
+    AvrIspWorkerRWEvtWriting = (1 << 3),
+    AvrIspWorkerRWEvtWritingFuse = (1 << 4),
+
+} AvrIspWorkerRWEvt;
+#define AVR_ISP_WORKER_ALL_EVENTS                                                              \
+    (AvrIspWorkerRWEvtWritingFuse | AvrIspWorkerRWEvtWriting | AvrIspWorkerRWEvtVerification | \
+     AvrIspWorkerRWEvtReading | AvrIspWorkerRWEvtStop)
+
+/** Worker thread
+ * 
+ * @param context 
+ * @return exit code 
+ */
+static int32_t avr_isp_worker_rw_thread(void* context) {
+    AvrIspWorkerRW* instance = context;
+
+    /* start PWM on &gpio_ext_pa4 */
+    if(!furi_hal_pwm_is_running(FuriHalPwmOutputIdLptim2PA4)) {
+        furi_hal_pwm_start(FuriHalPwmOutputIdLptim2PA4, 4000000, 50);
+    }
+
+    FURI_LOG_D(TAG, "Start");
+
+    while(1) {
+        uint32_t events =
+            furi_thread_flags_wait(AVR_ISP_WORKER_ALL_EVENTS, FuriFlagWaitAny, FuriWaitForever);
+
+        if(events & AvrIspWorkerRWEvtStop) {
+            break;
+        }
+
+        if(events & AvrIspWorkerRWEvtWritingFuse) {
+            if(avr_isp_worker_rw_write_fuse(instance, instance->file_path, instance->file_name)) {
+                if(instance->callback_status)
+                    instance->callback_status(
+                        instance->context_status, AvrIspWorkerRWStatusEndWritingFuse);
+            } else {
+                if(instance->callback_status)
+                    instance->callback_status(
+                        instance->context_status, AvrIspWorkerRWStatusErrorWritingFuse);
+            }
+        }
+
+        if(events & AvrIspWorkerRWEvtWriting) {
+            if(avr_isp_worker_rw_write_dump(instance, instance->file_path, instance->file_name)) {
+                if(instance->callback_status)
+                    instance->callback_status(
+                        instance->context_status, AvrIspWorkerRWStatusEndWriting);
+            } else {
+                if(instance->callback_status)
+                    instance->callback_status(
+                        instance->context_status, AvrIspWorkerRWStatusErrorWriting);
+            }
+        }
+
+        if(events & AvrIspWorkerRWEvtVerification) {
+            if(avr_isp_worker_rw_verification(instance, instance->file_path, instance->file_name)) {
+                if(instance->callback_status)
+                    instance->callback_status(
+                        instance->context_status, AvrIspWorkerRWStatusEndVerification);
+            } else {
+                if(instance->callback_status)
+                    instance->callback_status(
+                        instance->context_status, AvrIspWorkerRWStatusErrorVerification);
+            }
+        }
+
+        if(events & AvrIspWorkerRWEvtReading) {
+            if(avr_isp_worker_rw_read_dump(instance, instance->file_path, instance->file_name)) {
+                if(instance->callback_status)
+                    instance->callback_status(
+                        instance->context_status, AvrIspWorkerRWStatusEndReading);
+            } else {
+                if(instance->callback_status)
+                    instance->callback_status(
+                        instance->context_status, AvrIspWorkerRWStatusErrorReading);
+            }
+        }
+    }
+    FURI_LOG_D(TAG, "Stop");
+
+    if(furi_hal_pwm_is_running(FuriHalPwmOutputIdLptim2PA4)) {
+        furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4);
+    }
+
+    return 0;
+}
+
+bool avr_isp_worker_rw_detect_chip(AvrIspWorkerRW* instance) {
+    furi_assert(instance);
+
+    FURI_LOG_D(TAG, "Detecting AVR chip");
+
+    instance->chip_detect = false;
+    instance->chip_arr_ind = avr_isp_chip_arr_size + 1;
+
+    /* start PWM on &gpio_ext_pa4 */
+    bool was_pwm_enabled = false;
+    if(!furi_hal_pwm_is_running(FuriHalPwmOutputIdLptim2PA4)) {
+        furi_hal_pwm_start(FuriHalPwmOutputIdLptim2PA4, 4000000, 50);
+    } else {
+        was_pwm_enabled = true;
+    }
+
+    do {
+        if(!avr_isp_auto_set_spi_speed_start_pmode(instance->avr_isp)) {
+            FURI_LOG_E(TAG, "Well, I managed to enter the mod program");
+            break;
+        }
+        instance->signature = avr_isp_read_signature(instance->avr_isp);
+
+        if(instance->signature.vendor != 0x1E) {
+            //No detect chip
+        } else {
+            for(uint32_t ind = 0; ind < avr_isp_chip_arr_size; ind++) {
+                if(avr_isp_chip_arr[ind].avrarch != F_AVR8) continue;
+                if(avr_isp_chip_arr[ind].sigs[1] == instance->signature.part_family) {
+                    if(avr_isp_chip_arr[ind].sigs[2] == instance->signature.part_number) {
+                        FURI_LOG_D(TAG, "Detect AVR chip = \"%s\"", avr_isp_chip_arr[ind].name);
+                        FURI_LOG_D(
+                            TAG,
+                            "Signature = 0x%02X 0x%02X 0x%02X",
+                            instance->signature.vendor,
+                            instance->signature.part_family,
+                            instance->signature.part_number);
+
+                        switch(avr_isp_chip_arr[ind].nfuses) {
+                        case 1:
+                            instance->lfuse = avr_isp_read_fuse_low(instance->avr_isp);
+                            FURI_LOG_D(TAG, "Lfuse = %02X", instance->lfuse);
+                            break;
+                        case 2:
+                            instance->lfuse = avr_isp_read_fuse_low(instance->avr_isp);
+                            instance->hfuse = avr_isp_read_fuse_high(instance->avr_isp);
+                            FURI_LOG_D(
+                                TAG, "Lfuse = %02X Hfuse = %02X", instance->lfuse, instance->hfuse);
+                            break;
+                        case 3:
+                            instance->lfuse = avr_isp_read_fuse_low(instance->avr_isp);
+                            instance->hfuse = avr_isp_read_fuse_high(instance->avr_isp);
+                            instance->efuse = avr_isp_read_fuse_extended(instance->avr_isp);
+                            FURI_LOG_D(
+                                TAG,
+                                "Lfuse = %02X Hfuse = %02X Efuse = %02X",
+                                instance->lfuse,
+                                instance->hfuse,
+                                instance->efuse);
+                            break;
+                        default:
+                            break;
+                        }
+                        if(avr_isp_chip_arr[ind].nlocks == 1) {
+                            instance->lock = avr_isp_read_lock_byte(instance->avr_isp);
+                            FURI_LOG_D(TAG, "Lock = %02X", instance->lock);
+                        }
+                        instance->chip_detect = true;
+                        instance->chip_arr_ind = ind;
+                        break;
+                    }
+                }
+            }
+        }
+        avr_isp_end_pmode(instance->avr_isp);
+
+    } while(0);
+
+    if(furi_hal_pwm_is_running(FuriHalPwmOutputIdLptim2PA4) && !was_pwm_enabled) {
+        furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4);
+    }
+
+    if(instance->callback) {
+        if(instance->chip_arr_ind > avr_isp_chip_arr_size) {
+            instance->callback(instance->context, "No detect", instance->chip_detect, 0);
+        } else if(instance->chip_arr_ind < avr_isp_chip_arr_size) {
+            instance->callback(
+                instance->context,
+                avr_isp_chip_arr[instance->chip_arr_ind].name,
+                instance->chip_detect,
+                avr_isp_chip_arr[instance->chip_arr_ind].flashsize);
+        } else {
+            instance->callback(instance->context, "Unknown", instance->chip_detect, 0);
+        }
+    }
+
+    return instance->chip_detect;
+}
+
+AvrIspWorkerRW* avr_isp_worker_rw_alloc(void* context) {
+    furi_assert(context);
+    UNUSED(context);
+
+    AvrIspWorkerRW* instance = malloc(sizeof(AvrIspWorkerRW));
+    instance->avr_isp = avr_isp_alloc();
+
+    instance->thread =
+        furi_thread_alloc_ex("AvrIspWorkerRW", 4096, avr_isp_worker_rw_thread, instance);
+
+    instance->chip_detect = false;
+    instance->lfuse = 0;
+    instance->hfuse = 0;
+    instance->efuse = 0;
+    instance->lock = 0;
+    instance->progress_flash = 0.0f;
+    instance->progress_eeprom = 0.0f;
+
+    return instance;
+}
+
+void avr_isp_worker_rw_free(AvrIspWorkerRW* instance) {
+    furi_assert(instance);
+
+    avr_isp_free(instance->avr_isp);
+
+    furi_check(!instance->worker_running);
+    furi_thread_free(instance->thread);
+
+    free(instance);
+}
+
+void avr_isp_worker_rw_start(AvrIspWorkerRW* instance) {
+    furi_assert(instance);
+    furi_assert(!instance->worker_running);
+
+    instance->worker_running = true;
+
+    furi_thread_start(instance->thread);
+}
+
+void avr_isp_worker_rw_stop(AvrIspWorkerRW* instance) {
+    furi_assert(instance);
+    furi_assert(instance->worker_running);
+
+    instance->worker_running = false;
+    furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerRWEvtStop);
+
+    furi_thread_join(instance->thread);
+}
+
+bool avr_isp_worker_rw_is_running(AvrIspWorkerRW* instance) {
+    furi_assert(instance);
+
+    return instance->worker_running;
+}
+
+void avr_isp_worker_rw_set_callback(
+    AvrIspWorkerRW* instance,
+    AvrIspWorkerRWCallback callback,
+    void* context) {
+    furi_assert(instance);
+
+    instance->callback = callback;
+    instance->context = context;
+}
+
+void avr_isp_worker_rw_set_callback_status(
+    AvrIspWorkerRW* instance,
+    AvrIspWorkerRWStatusCallback callback_status,
+    void* context_status) {
+    furi_assert(instance);
+
+    instance->callback_status = callback_status;
+    instance->context_status = context_status;
+}
+
+float avr_isp_worker_rw_get_progress_flash(AvrIspWorkerRW* instance) {
+    furi_assert(instance);
+
+    return instance->progress_flash;
+}
+
+float avr_isp_worker_rw_get_progress_eeprom(AvrIspWorkerRW* instance) {
+    furi_assert(instance);
+
+    return instance->progress_eeprom;
+}
+
+static void avr_isp_worker_rw_get_dump_flash(AvrIspWorkerRW* instance, const char* file_path) {
+    furi_assert(instance);
+    furi_check(instance->avr_isp);
+
+    FURI_LOG_D(TAG, "Dump FLASH %s", file_path);
+
+    FlipperI32HexFile* flipper_hex_flash = flipper_i32hex_file_open_write(
+        file_path, avr_isp_chip_arr[instance->chip_arr_ind].flashoffset);
+
+    uint8_t data[272] = {0};
+    bool send_extended_addr = ((avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2) > 0x10000);
+    uint8_t extended_addr = 0;
+
+    for(int32_t i = avr_isp_chip_arr[instance->chip_arr_ind].flashoffset;
+        i < avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2;
+        i += avr_isp_chip_arr[instance->chip_arr_ind].pagesize / 2) {
+        if(send_extended_addr) {
+            if(extended_addr <= ((i >> 16) & 0xFF)) {
+                avr_isp_write_extended_addr(instance->avr_isp, extended_addr);
+                extended_addr = ((i >> 16) & 0xFF) + 1;
+            }
+        }
+        avr_isp_read_page(
+            instance->avr_isp,
+            STK_SET_FLASH_TYPE,
+            (uint16_t)i,
+            avr_isp_chip_arr[instance->chip_arr_ind].pagesize,
+            data,
+            sizeof(data));
+        flipper_i32hex_file_bin_to_i32hex_set_data(
+            flipper_hex_flash, data, avr_isp_chip_arr[instance->chip_arr_ind].pagesize);
+        FURI_LOG_D(TAG, "%s", flipper_i32hex_file_get_string(flipper_hex_flash));
+        instance->progress_flash =
+            (float)(i) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2.0f);
+    }
+    flipper_i32hex_file_bin_to_i32hex_set_end_line(flipper_hex_flash);
+    FURI_LOG_D(TAG, "%s", flipper_i32hex_file_get_string(flipper_hex_flash));
+    flipper_i32hex_file_close(flipper_hex_flash);
+    instance->progress_flash = 1.0f;
+}
+
+static void avr_isp_worker_rw_get_dump_eeprom(AvrIspWorkerRW* instance, const char* file_path) {
+    furi_assert(instance);
+    furi_check(instance->avr_isp);
+
+    FURI_LOG_D(TAG, "Dump EEPROM %s", file_path);
+
+    FlipperI32HexFile* flipper_hex_eeprom = flipper_i32hex_file_open_write(
+        file_path, avr_isp_chip_arr[instance->chip_arr_ind].eepromoffset);
+
+    int32_t size_data = 32;
+    uint8_t data[256] = {0};
+
+    if(size_data > avr_isp_chip_arr[instance->chip_arr_ind].eepromsize)
+        size_data = avr_isp_chip_arr[instance->chip_arr_ind].eepromsize;
+
+    for(int32_t i = avr_isp_chip_arr[instance->chip_arr_ind].eepromoffset;
+        i < avr_isp_chip_arr[instance->chip_arr_ind].eepromsize;
+        i += size_data) {
+        avr_isp_read_page(
+            instance->avr_isp, STK_SET_EEPROM_TYPE, (uint16_t)i, size_data, data, sizeof(data));
+        flipper_i32hex_file_bin_to_i32hex_set_data(flipper_hex_eeprom, data, size_data);
+        FURI_LOG_D(TAG, "%s", flipper_i32hex_file_get_string(flipper_hex_eeprom));
+        instance->progress_eeprom =
+            (float)(i) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].eepromsize);
+    }
+    flipper_i32hex_file_bin_to_i32hex_set_end_line(flipper_hex_eeprom);
+    FURI_LOG_D(TAG, "%s", flipper_i32hex_file_get_string(flipper_hex_eeprom));
+    flipper_i32hex_file_close(flipper_hex_eeprom);
+    instance->progress_eeprom = 1.0f;
+}
+
+bool avr_isp_worker_rw_read_dump(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name) {
+    furi_assert(instance);
+    furi_assert(file_path);
+    furi_assert(file_name);
+
+    FURI_LOG_D(TAG, "Read dump chip");
+
+    instance->progress_flash = 0.0f;
+    instance->progress_eeprom = 0.0f;
+    bool ret = false;
+    Storage* storage = furi_record_open(RECORD_STORAGE);
+    FlipperFormat* flipper_format = flipper_format_file_alloc(storage);
+    FuriString* file_path_name = furi_string_alloc();
+
+    if(!avr_isp_worker_rw_detect_chip(instance)) {
+        FURI_LOG_E(TAG, "No detect AVR chip");
+    } else {
+        do {
+            furi_string_printf(
+                file_path_name, "%s/%s%s", file_path, file_name, AVR_ISP_APP_EXTENSION);
+            if(!flipper_format_file_open_always(
+                   flipper_format, furi_string_get_cstr(file_path_name))) {
+                FURI_LOG_E(TAG, "flipper_format_file_open_always");
+                break;
+            }
+            if(!flipper_format_write_header_cstr(
+                   flipper_format, AVR_ISP_APP_FILE_TYPE, AVR_ISP_APP_FILE_VERSION)) {
+                FURI_LOG_E(TAG, "flipper_format_write_header_cstr");
+                break;
+            }
+            if(!flipper_format_write_string_cstr(
+                   flipper_format, "Chip name", avr_isp_chip_arr[instance->chip_arr_ind].name)) {
+                FURI_LOG_E(TAG, "Chip name");
+                break;
+            }
+            if(!flipper_format_write_hex(
+                   flipper_format,
+                   "Signature",
+                   (uint8_t*)&instance->signature,
+                   sizeof(AvrIspSignature))) {
+                FURI_LOG_E(TAG, "Unable to add Signature");
+                break;
+            }
+            if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 0) {
+                if(!flipper_format_write_hex(flipper_format, "Lfuse", &instance->lfuse, 1)) {
+                    FURI_LOG_E(TAG, "Unable to add Lfuse");
+                    break;
+                }
+            }
+            if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 1) {
+                if(!flipper_format_write_hex(flipper_format, "Hfuse", &instance->hfuse, 1)) {
+                    FURI_LOG_E(TAG, "Unable to add Hfuse");
+                    break;
+                }
+            }
+            if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 2) {
+                if(!flipper_format_write_hex(flipper_format, "Efuse", &instance->efuse, 1)) {
+                    FURI_LOG_E(TAG, "Unable to add Efuse");
+                    break;
+                }
+            }
+            if(avr_isp_chip_arr[instance->chip_arr_ind].nlocks == 1) {
+                if(!flipper_format_write_hex(flipper_format, "Lock", &instance->lock, 1)) {
+                    FURI_LOG_E(TAG, "Unable to add Lock");
+                    break;
+                }
+            }
+            furi_string_printf(file_path_name, "%s_%s", file_name, NAME_PATERN_FLASH_FILE);
+            if(!flipper_format_write_string_cstr(
+                   flipper_format, "Dump_flash", furi_string_get_cstr(file_path_name))) {
+                FURI_LOG_E(TAG, "Unable to add Dump_flash");
+                break;
+            }
+
+            if(avr_isp_chip_arr[instance->chip_arr_ind].eepromsize > 0) {
+                furi_string_printf(file_path_name, "%s_%s", file_name, NAME_PATERN_EEPROM_FILE);
+                if(avr_isp_chip_arr[instance->chip_arr_ind].eepromsize > 0) {
+                    if(!flipper_format_write_string_cstr(
+                           flipper_format, "Dump_eeprom", furi_string_get_cstr(file_path_name))) {
+                        FURI_LOG_E(TAG, "Unable to add Dump_eeprom");
+                        break;
+                    }
+                }
+            }
+            ret = true;
+        } while(false);
+    }
+
+    flipper_format_free(flipper_format);
+    furi_record_close(RECORD_STORAGE);
+
+    if(ret) {
+        if(avr_isp_auto_set_spi_speed_start_pmode(instance->avr_isp)) {
+            //Dump flash
+            furi_string_printf(
+                file_path_name, "%s/%s_%s", file_path, file_name, NAME_PATERN_FLASH_FILE);
+            avr_isp_worker_rw_get_dump_flash(instance, furi_string_get_cstr(file_path_name));
+            //Dump eeprom
+            if(avr_isp_chip_arr[instance->chip_arr_ind].eepromsize > 0) {
+                furi_string_printf(
+                    file_path_name, "%s/%s_%s", file_path, file_name, NAME_PATERN_EEPROM_FILE);
+                avr_isp_worker_rw_get_dump_eeprom(instance, furi_string_get_cstr(file_path_name));
+            }
+
+            avr_isp_end_pmode(instance->avr_isp);
+        }
+    }
+
+    furi_string_free(file_path_name);
+
+    return true;
+}
+
+void avr_isp_worker_rw_read_dump_start(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name) {
+    furi_assert(instance);
+
+    instance->file_path = file_path;
+    instance->file_name = file_name;
+    furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerRWEvtReading);
+}
+
+static bool avr_isp_worker_rw_verification_flash(AvrIspWorkerRW* instance, const char* file_path) {
+    furi_assert(instance);
+    furi_assert(file_path);
+
+    FURI_LOG_D(TAG, "Verification flash %s", file_path);
+
+    instance->progress_flash = 0.0;
+    bool ret = true;
+
+    FlipperI32HexFile* flipper_hex_flash = flipper_i32hex_file_open_read(file_path);
+
+    uint8_t data_read_flash[272] = {0};
+    uint8_t data_read_hex[272] = {0};
+
+    uint32_t addr = avr_isp_chip_arr[instance->chip_arr_ind].flashoffset;
+    bool send_extended_addr = ((avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2) > 0x10000);
+    uint8_t extended_addr = 0;
+
+    FlipperI32HexFileRet flipper_hex_ret = flipper_i32hex_file_i32hex_to_bin_get_data(
+        flipper_hex_flash, data_read_hex, sizeof(data_read_hex));
+
+    while(((flipper_hex_ret.status == FlipperI32HexFileStatusData) ||
+           (flipper_hex_ret.status == FlipperI32HexFileStatusUdateAddr)) &&
+          ret) {
+        switch(flipper_hex_ret.status) {
+        case FlipperI32HexFileStatusData:
+
+            if(send_extended_addr) {
+                if(extended_addr <= ((addr >> 16) & 0xFF)) {
+                    avr_isp_write_extended_addr(instance->avr_isp, extended_addr);
+                    extended_addr = ((addr >> 16) & 0xFF) + 1;
+                }
+            }
+
+            avr_isp_read_page(
+                instance->avr_isp,
+                STK_SET_FLASH_TYPE,
+                (uint16_t)addr,
+                flipper_hex_ret.data_size,
+                data_read_flash,
+                sizeof(data_read_flash));
+
+            if(memcmp(data_read_hex, data_read_flash, flipper_hex_ret.data_size) != 0) {
+                ret = false;
+
+                FURI_LOG_E(TAG, "Verification flash error");
+                FURI_LOG_E(TAG, "Addr: 0x%04lX", addr);
+                for(uint32_t i = 0; i < flipper_hex_ret.data_size; i++) {
+                    FURI_LOG_RAW_E("%02X ", data_read_hex[i]);
+                }
+                FURI_LOG_RAW_E("\r\n");
+                for(uint32_t i = 0; i < flipper_hex_ret.data_size; i++) {
+                    FURI_LOG_RAW_E("%02X ", data_read_flash[i]);
+                }
+                FURI_LOG_RAW_E("\r\n");
+            }
+
+            addr += flipper_hex_ret.data_size / 2;
+            instance->progress_flash =
+                (float)(addr) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2.0f);
+            break;
+
+        case FlipperI32HexFileStatusUdateAddr:
+            addr = (data_read_hex[0] << 24 | data_read_hex[1] << 16) / 2;
+            break;
+
+        default:
+            furi_crash(TAG " Incorrect status.");
+            break;
+        }
+
+        flipper_hex_ret = flipper_i32hex_file_i32hex_to_bin_get_data(
+            flipper_hex_flash, data_read_hex, sizeof(data_read_hex));
+    }
+
+    flipper_i32hex_file_close(flipper_hex_flash);
+    instance->progress_flash = 1.0f;
+
+    return ret;
+}
+
+static bool
+    avr_isp_worker_rw_verification_eeprom(AvrIspWorkerRW* instance, const char* file_path) {
+    furi_assert(instance);
+    furi_assert(file_path);
+
+    FURI_LOG_D(TAG, "Verification eeprom %s", file_path);
+
+    instance->progress_eeprom = 0.0;
+    bool ret = true;
+
+    FlipperI32HexFile* flipper_hex_eeprom = flipper_i32hex_file_open_read(file_path);
+
+    uint8_t data_read_eeprom[272] = {0};
+    uint8_t data_read_hex[272] = {0};
+
+    uint32_t addr = avr_isp_chip_arr[instance->chip_arr_ind].eepromoffset;
+
+    FlipperI32HexFileRet flipper_hex_ret = flipper_i32hex_file_i32hex_to_bin_get_data(
+        flipper_hex_eeprom, data_read_hex, sizeof(data_read_hex));
+
+    while(((flipper_hex_ret.status == FlipperI32HexFileStatusData) ||
+           (flipper_hex_ret.status == FlipperI32HexFileStatusUdateAddr)) &&
+          ret) {
+        switch(flipper_hex_ret.status) {
+        case FlipperI32HexFileStatusData:
+            avr_isp_read_page(
+                instance->avr_isp,
+                STK_SET_EEPROM_TYPE,
+                (uint16_t)addr,
+                flipper_hex_ret.data_size,
+                data_read_eeprom,
+                sizeof(data_read_eeprom));
+
+            if(memcmp(data_read_hex, data_read_eeprom, flipper_hex_ret.data_size) != 0) {
+                ret = false;
+                FURI_LOG_E(TAG, "Verification eeprom error");
+                FURI_LOG_E(TAG, "Addr: 0x%04lX", addr);
+                for(uint32_t i = 0; i < flipper_hex_ret.data_size; i++) {
+                    FURI_LOG_RAW_E("%02X ", data_read_hex[i]);
+                }
+                FURI_LOG_RAW_E("\r\n");
+                for(uint32_t i = 0; i < flipper_hex_ret.data_size; i++) {
+                    FURI_LOG_RAW_E("%02X ", data_read_eeprom[i]);
+                }
+                FURI_LOG_RAW_E("\r\n");
+            }
+
+            addr += flipper_hex_ret.data_size;
+            instance->progress_eeprom =
+                (float)(addr) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].eepromsize);
+            break;
+
+        case FlipperI32HexFileStatusUdateAddr:
+            addr = (data_read_hex[0] << 24 | data_read_hex[1] << 16);
+            break;
+
+        default:
+            furi_crash(TAG " Incorrect status.");
+            break;
+        }
+
+        flipper_hex_ret = flipper_i32hex_file_i32hex_to_bin_get_data(
+            flipper_hex_eeprom, data_read_hex, sizeof(data_read_hex));
+    }
+
+    flipper_i32hex_file_close(flipper_hex_eeprom);
+    instance->progress_eeprom = 1.0f;
+
+    return ret;
+}
+
+bool avr_isp_worker_rw_verification(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name) {
+    furi_assert(instance);
+    furi_assert(file_path);
+    furi_assert(file_name);
+
+    FURI_LOG_D(TAG, "Verification chip");
+
+    instance->progress_flash = 0.0f;
+    instance->progress_eeprom = 0.0f;
+    FuriString* file_path_name = furi_string_alloc();
+
+    bool ret = false;
+
+    if(avr_isp_auto_set_spi_speed_start_pmode(instance->avr_isp)) {
+        do {
+            furi_string_printf(
+                file_path_name, "%s/%s_%s", file_path, file_name, NAME_PATERN_FLASH_FILE);
+            if(!avr_isp_worker_rw_verification_flash(
+                   instance, furi_string_get_cstr(file_path_name)))
+                break;
+
+            if(avr_isp_chip_arr[instance->chip_arr_ind].eepromsize > 0) {
+                furi_string_printf(
+                    file_path_name, "%s/%s_%s", file_path, file_name, NAME_PATERN_EEPROM_FILE);
+
+                if(!avr_isp_worker_rw_verification_eeprom(
+                       instance, furi_string_get_cstr(file_path_name)))
+                    break;
+            }
+            ret = true;
+        } while(false);
+        avr_isp_end_pmode(instance->avr_isp);
+        furi_string_free(file_path_name);
+    }
+    return ret;
+}
+
+void avr_isp_worker_rw_verification_start(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name) {
+    furi_assert(instance);
+
+    instance->file_path = file_path;
+    instance->file_name = file_name;
+    furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerRWEvtVerification);
+}
+
+static void avr_isp_worker_rw_write_flash(AvrIspWorkerRW* instance, const char* file_path) {
+    furi_assert(instance);
+    furi_check(instance->avr_isp);
+
+    instance->progress_flash = 0.0;
+
+    FURI_LOG_D(TAG, "Write Flash %s", file_path);
+
+    uint8_t data[288] = {0};
+
+    FlipperI32HexFile* flipper_hex_flash = flipper_i32hex_file_open_read(file_path);
+
+    uint32_t addr = avr_isp_chip_arr[instance->chip_arr_ind].flashoffset;
+    bool send_extended_addr = ((avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2) > 0x10000);
+    uint8_t extended_addr = 0;
+
+    FlipperI32HexFileRet flipper_hex_ret =
+        flipper_i32hex_file_i32hex_to_bin_get_data(flipper_hex_flash, data, sizeof(data));
+
+    while((flipper_hex_ret.status == FlipperI32HexFileStatusData) ||
+          (flipper_hex_ret.status == FlipperI32HexFileStatusUdateAddr)) {
+        switch(flipper_hex_ret.status) {
+        case FlipperI32HexFileStatusData:
+
+            if(send_extended_addr) {
+                if(extended_addr <= ((addr >> 16) & 0xFF)) {
+                    avr_isp_write_extended_addr(instance->avr_isp, extended_addr);
+                    extended_addr = ((addr >> 16) & 0xFF) + 1;
+                }
+            }
+
+            if(!avr_isp_write_page(
+                   instance->avr_isp,
+                   STK_SET_FLASH_TYPE,
+                   avr_isp_chip_arr[instance->chip_arr_ind].flashsize,
+                   (uint16_t)addr,
+                   avr_isp_chip_arr[instance->chip_arr_ind].pagesize,
+                   data,
+                   flipper_hex_ret.data_size)) {
+                break;
+            }
+            addr += flipper_hex_ret.data_size / 2;
+            instance->progress_flash =
+                (float)(addr) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2.0f);
+            break;
+
+        case FlipperI32HexFileStatusUdateAddr:
+            addr = (data[0] << 24 | data[1] << 16) / 2;
+            break;
+
+        default:
+            furi_crash(TAG " Incorrect status.");
+            break;
+        }
+
+        flipper_hex_ret =
+            flipper_i32hex_file_i32hex_to_bin_get_data(flipper_hex_flash, data, sizeof(data));
+    }
+
+    flipper_i32hex_file_close(flipper_hex_flash);
+    instance->progress_flash = 1.0f;
+}
+
+static void avr_isp_worker_rw_write_eeprom(AvrIspWorkerRW* instance, const char* file_path) {
+    furi_assert(instance);
+    furi_check(instance->avr_isp);
+
+    instance->progress_eeprom = 0.0;
+    uint8_t data[288] = {0};
+
+    FURI_LOG_D(TAG, "Write EEPROM %s", file_path);
+
+    FlipperI32HexFile* flipper_hex_eeprom_read = flipper_i32hex_file_open_read(file_path);
+
+    uint32_t addr = avr_isp_chip_arr[instance->chip_arr_ind].eepromoffset;
+    FlipperI32HexFileRet flipper_hex_ret =
+        flipper_i32hex_file_i32hex_to_bin_get_data(flipper_hex_eeprom_read, data, sizeof(data));
+
+    while((flipper_hex_ret.status == FlipperI32HexFileStatusData) ||
+          (flipper_hex_ret.status == FlipperI32HexFileStatusUdateAddr)) {
+        switch(flipper_hex_ret.status) {
+        case FlipperI32HexFileStatusData:
+            if(!avr_isp_write_page(
+                   instance->avr_isp,
+                   STK_SET_EEPROM_TYPE,
+                   avr_isp_chip_arr[instance->chip_arr_ind].eepromsize,
+                   (uint16_t)addr,
+                   avr_isp_chip_arr[instance->chip_arr_ind].eeprompagesize,
+                   data,
+                   flipper_hex_ret.data_size)) {
+                break;
+            }
+            addr += flipper_hex_ret.data_size;
+            instance->progress_eeprom =
+                (float)(addr) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].eepromsize);
+            break;
+
+        case FlipperI32HexFileStatusUdateAddr:
+            addr = data[0] << 24 | data[1] << 16;
+            break;
+
+        default:
+            furi_crash(TAG " Incorrect status.");
+            break;
+        }
+
+        flipper_hex_ret = flipper_i32hex_file_i32hex_to_bin_get_data(
+            flipper_hex_eeprom_read, data, sizeof(data));
+    }
+
+    flipper_i32hex_file_close(flipper_hex_eeprom_read);
+    instance->progress_eeprom = 1.0f;
+}
+
+bool avr_isp_worker_rw_write_dump(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name) {
+    furi_assert(instance);
+    furi_assert(file_path);
+    furi_assert(file_name);
+
+    FURI_LOG_D(TAG, "Write dump chip");
+
+    instance->progress_flash = 0.0f;
+    instance->progress_eeprom = 0.0f;
+    bool ret = false;
+
+    Storage* storage = furi_record_open(RECORD_STORAGE);
+    FlipperFormat* flipper_format = flipper_format_file_alloc(storage);
+    FuriString* file_path_name = furi_string_alloc();
+
+    FuriString* temp_str_1 = furi_string_alloc();
+    FuriString* temp_str_2 = furi_string_alloc();
+    uint32_t temp_data32;
+
+    if(!avr_isp_worker_rw_detect_chip(instance)) {
+        FURI_LOG_E(TAG, "No detect AVR chip");
+    } else {
+        //upload file with description
+        do {
+            furi_string_printf(
+                file_path_name, "%s/%s%s", file_path, file_name, AVR_ISP_APP_EXTENSION);
+            if(!flipper_format_file_open_existing(
+                   flipper_format, furi_string_get_cstr(file_path_name))) {
+                FURI_LOG_E(TAG, "Error open file %s", furi_string_get_cstr(file_path_name));
+                break;
+            }
+
+            if(!flipper_format_read_header(flipper_format, temp_str_1, &temp_data32)) {
+                FURI_LOG_E(TAG, "Missing or incorrect header");
+                break;
+            }
+
+            if((!strcmp(furi_string_get_cstr(temp_str_1), AVR_ISP_APP_FILE_TYPE)) &&
+               temp_data32 == AVR_ISP_APP_FILE_VERSION) {
+            } else {
+                FURI_LOG_E(TAG, "Type or version mismatch");
+                break;
+            }
+
+            AvrIspSignature sig_read = {0};
+
+            if(!flipper_format_read_hex(
+                   flipper_format, "Signature", (uint8_t*)&sig_read, sizeof(AvrIspSignature))) {
+                FURI_LOG_E(TAG, "Missing Signature");
+                break;
+            }
+
+            if(memcmp(
+                   (uint8_t*)&instance->signature, (uint8_t*)&sig_read, sizeof(AvrIspSignature)) !=
+               0) {
+                FURI_LOG_E(
+                    TAG,
+                    "Wrong chip. Connected (%02X %02X %02X), read from file (%02X %02X %02X)",
+                    instance->signature.vendor,
+                    instance->signature.part_family,
+                    instance->signature.part_number,
+                    sig_read.vendor,
+                    sig_read.part_family,
+                    sig_read.part_number);
+                break;
+            }
+
+            if(!flipper_format_read_string(flipper_format, "Dump_flash", temp_str_1)) {
+                FURI_LOG_E(TAG, "Missing Dump_flash");
+                break;
+            }
+
+            //may not be
+            flipper_format_read_string(flipper_format, "Dump_eeprom", temp_str_2);
+            ret = true;
+        } while(false);
+    }
+    flipper_format_free(flipper_format);
+    furi_record_close(RECORD_STORAGE);
+
+    if(ret) {
+        do {
+            //checking .hex files for errors
+
+            furi_string_printf(
+                file_path_name, "%s/%s", file_path, furi_string_get_cstr(temp_str_1));
+
+            FURI_LOG_D(TAG, "Check flash file");
+            FlipperI32HexFile* flipper_hex_flash_read =
+                flipper_i32hex_file_open_read(furi_string_get_cstr(file_path_name));
+            if(flipper_i32hex_file_check(flipper_hex_flash_read)) {
+                FURI_LOG_D(TAG, "Check flash file: OK");
+            } else {
+                FURI_LOG_E(TAG, "Check flash file: Error");
+                ret = false;
+            }
+            flipper_i32hex_file_close(flipper_hex_flash_read);
+
+            if(furi_string_size(temp_str_2) > 4) {
+                furi_string_printf(
+                    file_path_name, "%s/%s", file_path, furi_string_get_cstr(temp_str_2));
+
+                FURI_LOG_D(TAG, "Check eeprom file");
+                FlipperI32HexFile* flipper_hex_eeprom_read =
+                    flipper_i32hex_file_open_read(furi_string_get_cstr(file_path_name));
+                if(flipper_i32hex_file_check(flipper_hex_eeprom_read)) {
+                    FURI_LOG_D(TAG, "Check eeprom file: OK");
+                } else {
+                    FURI_LOG_E(TAG, "Check eeprom file: Error");
+                    ret = false;
+                }
+                flipper_i32hex_file_close(flipper_hex_eeprom_read);
+            }
+
+            if(!ret) break;
+            ret = false;
+
+            //erase chip
+            FURI_LOG_D(TAG, "Erase chip");
+            if(!avr_isp_erase_chip(instance->avr_isp)) {
+                FURI_LOG_E(TAG, "Erase chip: Error");
+                break;
+            }
+
+            if(!avr_isp_auto_set_spi_speed_start_pmode(instance->avr_isp)) {
+                FURI_LOG_E(TAG, "Well, I managed to enter the mod program");
+                break;
+            }
+
+            //write flash
+            furi_string_printf(
+                file_path_name, "%s/%s", file_path, furi_string_get_cstr(temp_str_1));
+            avr_isp_worker_rw_write_flash(instance, furi_string_get_cstr(file_path_name));
+
+            //write eeprom
+            if(furi_string_size(temp_str_2) > 4) {
+                furi_string_printf(
+                    file_path_name, "%s/%s", file_path, furi_string_get_cstr(temp_str_2));
+                avr_isp_worker_rw_write_eeprom(instance, furi_string_get_cstr(file_path_name));
+            }
+            ret = true;
+            avr_isp_end_pmode(instance->avr_isp);
+        } while(false);
+    }
+
+    furi_string_free(file_path_name);
+    furi_string_free(temp_str_1);
+    furi_string_free(temp_str_2);
+
+    return ret;
+}
+
+void avr_isp_worker_rw_write_dump_start(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name) {
+    furi_assert(instance);
+
+    instance->file_path = file_path;
+    instance->file_name = file_name;
+    furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerRWEvtWriting);
+}
+
+bool avr_isp_worker_rw_write_fuse(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name) {
+    furi_assert(instance);
+    furi_assert(file_path);
+    furi_assert(file_name);
+
+    FURI_LOG_D(TAG, "Write fuse chip");
+
+    bool ret = false;
+    uint8_t lfuse;
+    uint8_t hfuse;
+    uint8_t efuse;
+    uint8_t lock;
+
+    Storage* storage = furi_record_open(RECORD_STORAGE);
+    FlipperFormat* flipper_format = flipper_format_file_alloc(storage);
+    FuriString* temp_str = furi_string_alloc();
+
+    uint32_t temp_data32;
+
+    if(!avr_isp_worker_rw_detect_chip(instance)) {
+        FURI_LOG_E(TAG, "No detect AVR chip");
+    } else {
+        //upload file with description
+        do {
+            furi_string_printf(temp_str, "%s/%s%s", file_path, file_name, AVR_ISP_APP_EXTENSION);
+            if(!flipper_format_file_open_existing(flipper_format, furi_string_get_cstr(temp_str))) {
+                FURI_LOG_E(TAG, "Error open file %s", furi_string_get_cstr(temp_str));
+                break;
+            }
+
+            if(!flipper_format_read_header(flipper_format, temp_str, &temp_data32)) {
+                FURI_LOG_E(TAG, "Missing or incorrect header");
+                break;
+            }
+
+            if((!strcmp(furi_string_get_cstr(temp_str), AVR_ISP_APP_FILE_TYPE)) &&
+               temp_data32 == AVR_ISP_APP_FILE_VERSION) {
+            } else {
+                FURI_LOG_E(TAG, "Type or version mismatch");
+                break;
+            }
+
+            AvrIspSignature sig_read = {0};
+
+            if(!flipper_format_read_hex(
+                   flipper_format, "Signature", (uint8_t*)&sig_read, sizeof(AvrIspSignature))) {
+                FURI_LOG_E(TAG, "Missing Signature");
+                break;
+            }
+
+            if(memcmp(
+                   (uint8_t*)&instance->signature, (uint8_t*)&sig_read, sizeof(AvrIspSignature)) !=
+               0) {
+                FURI_LOG_E(
+                    TAG,
+                    "Wrong chip. Connected (%02X %02X %02X), read from file (%02X %02X %02X)",
+                    instance->signature.vendor,
+                    instance->signature.part_family,
+                    instance->signature.part_number,
+                    sig_read.vendor,
+                    sig_read.part_family,
+                    sig_read.part_number);
+                break;
+            }
+
+            if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 0) {
+                if(!flipper_format_read_hex(flipper_format, "Lfuse", &lfuse, 1)) {
+                    FURI_LOG_E(TAG, "Missing Lfuse");
+                    break;
+                }
+            }
+            if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 1) {
+                if(!flipper_format_read_hex(flipper_format, "Hfuse", &hfuse, 1)) {
+                    FURI_LOG_E(TAG, "Missing Hfuse");
+                    break;
+                }
+            }
+            if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 2) {
+                if(!flipper_format_read_hex(flipper_format, "Efuse", &efuse, 1)) {
+                    FURI_LOG_E(TAG, "Missing Efuse");
+                    break;
+                }
+            }
+            if(avr_isp_chip_arr[instance->chip_arr_ind].nlocks == 1) {
+                if(!flipper_format_read_hex(flipper_format, "Lock", &lock, 1)) {
+                    FURI_LOG_E(TAG, "Missing Lock");
+                    break;
+                }
+            }
+
+            if(!avr_isp_auto_set_spi_speed_start_pmode(instance->avr_isp)) {
+                FURI_LOG_E(TAG, "Well, I managed to enter the mod program");
+                break;
+            }
+
+            ret = true;
+
+            if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 0) {
+                if(instance->lfuse != lfuse) {
+                    if(!avr_isp_write_fuse_low(instance->avr_isp, lfuse)) {
+                        FURI_LOG_E(TAG, "Write Lfuse: error");
+                        ret = false;
+                    }
+                }
+            }
+            if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 1) {
+                if(instance->hfuse != hfuse) {
+                    if(!avr_isp_write_fuse_high(instance->avr_isp, hfuse)) {
+                        FURI_LOG_E(TAG, "Write Hfuse: error");
+                        ret = false;
+                    }
+                }
+            }
+            if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 2) {
+                if(instance->efuse != efuse) {
+                    if(!avr_isp_write_fuse_extended(instance->avr_isp, efuse)) {
+                        FURI_LOG_E(TAG, "Write Efuse: error");
+                        ret = false;
+                    }
+                }
+            }
+
+            if(avr_isp_chip_arr[instance->chip_arr_ind].nlocks == 1) {
+                FURI_LOG_D(TAG, "Write lock byte");
+                if(instance->lock != lock) {
+                    if(!avr_isp_write_lock_byte(instance->avr_isp, lock)) {
+                        FURI_LOG_E(TAG, "Write Lock byte: error");
+                        ret = false;
+                    }
+                }
+            }
+            avr_isp_end_pmode(instance->avr_isp);
+        } while(false);
+    }
+
+    flipper_format_free(flipper_format);
+    furi_record_close(RECORD_STORAGE);
+    furi_string_free(temp_str);
+    return ret;
+}
+
+void avr_isp_worker_rw_write_fuse_start(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name) {
+    furi_assert(instance);
+
+    instance->file_path = file_path;
+    instance->file_name = file_name;
+    furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerRWEvtWritingFuse);
+}

+ 99 - 0
avr_isp_programmer/helpers/avr_isp_worker_rw.h

@@ -0,0 +1,99 @@
+#pragma once
+
+#include <furi_hal.h>
+
+typedef struct AvrIspWorkerRW AvrIspWorkerRW;
+
+typedef void (*AvrIspWorkerRWCallback)(
+    void* context,
+    const char* name,
+    bool detect_chip,
+    uint32_t flash_size);
+
+typedef enum {
+    AvrIspWorkerRWStatusILDE = 0,
+    AvrIspWorkerRWStatusEndReading = 1,
+    AvrIspWorkerRWStatusEndVerification = 2,
+    AvrIspWorkerRWStatusEndWriting = 3,
+    AvrIspWorkerRWStatusEndWritingFuse = 4,
+
+    AvrIspWorkerRWStatusErrorReading = (-1),
+    AvrIspWorkerRWStatusErrorVerification = (-2),
+    AvrIspWorkerRWStatusErrorWriting = (-3),
+    AvrIspWorkerRWStatusErrorWritingFuse = (-4),
+
+    AvrIspWorkerRWStatusReserved = 0x7FFFFFFF, ///< Prevents enum down-size compiler optimization.
+} AvrIspWorkerRWStatus;
+
+typedef void (*AvrIspWorkerRWStatusCallback)(void* context, AvrIspWorkerRWStatus status);
+
+AvrIspWorkerRW* avr_isp_worker_rw_alloc(void* context);
+
+void avr_isp_worker_rw_free(AvrIspWorkerRW* instance);
+
+void avr_isp_worker_rw_start(AvrIspWorkerRW* instance);
+
+void avr_isp_worker_rw_stop(AvrIspWorkerRW* instance);
+
+bool avr_isp_worker_rw_is_running(AvrIspWorkerRW* instance);
+
+void avr_isp_worker_rw_set_callback(
+    AvrIspWorkerRW* instance,
+    AvrIspWorkerRWCallback callback,
+    void* context);
+
+void avr_isp_worker_rw_set_callback_status(
+    AvrIspWorkerRW* instance,
+    AvrIspWorkerRWStatusCallback callback_status,
+    void* context_status);
+
+bool avr_isp_worker_rw_detect_chip(AvrIspWorkerRW* instance);
+
+float avr_isp_worker_rw_get_progress_flash(AvrIspWorkerRW* instance);
+
+float avr_isp_worker_rw_get_progress_eeprom(AvrIspWorkerRW* instance);
+
+bool avr_isp_worker_rw_read_dump(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name);
+
+void avr_isp_worker_rw_read_dump_start(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name);
+
+bool avr_isp_worker_rw_verification(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name);
+
+void avr_isp_worker_rw_verification_start(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name);
+
+bool avr_isp_worker_rw_check_hex(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name);
+
+bool avr_isp_worker_rw_write_dump(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name);
+
+void avr_isp_worker_rw_write_dump_start(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name);
+
+bool avr_isp_worker_rw_write_fuse(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name);
+
+void avr_isp_worker_rw_write_fuse_start(
+    AvrIspWorkerRW* instance,
+    const char* file_path,
+    const char* file_name);

+ 321 - 0
avr_isp_programmer/helpers/flipper_i32hex_file.c

@@ -0,0 +1,321 @@
+#include "flipper_i32hex_file.h"
+#include <string.h>
+#include <storage/storage.h>
+#include <toolbox/stream/stream.h>
+#include <toolbox/stream/file_stream.h>
+#include <toolbox/hex.h>
+
+//https://en.wikipedia.org/wiki/Intel_HEX
+
+#define TAG "FlipperI32HexFile"
+
+#define COUNT_BYTE_PAYLOAD 32 //how much payload will be used
+
+#define I32HEX_TYPE_DATA 0x00
+#define I32HEX_TYPE_END_OF_FILE 0x01
+#define I32HEX_TYPE_EXT_LINEAR_ADDR 0x04
+#define I32HEX_TYPE_START_LINEAR_ADDR 0x05
+
+struct FlipperI32HexFile {
+    uint32_t addr;
+    uint32_t addr_last;
+    Storage* storage;
+    Stream* stream;
+    FuriString* str_data;
+    FlipperI32HexFileStatus file_open;
+};
+
+FlipperI32HexFile* flipper_i32hex_file_open_write(const char* name, uint32_t start_addr) {
+    furi_assert(name);
+
+    FlipperI32HexFile* instance = malloc(sizeof(FlipperI32HexFile));
+    instance->addr = start_addr;
+    instance->addr_last = 0;
+    instance->storage = furi_record_open(RECORD_STORAGE);
+    instance->stream = file_stream_alloc(instance->storage);
+
+    if(file_stream_open(instance->stream, name, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
+        instance->file_open = FlipperI32HexFileStatusOpenFileWrite;
+        FURI_LOG_D(TAG, "Open write file %s", name);
+    } else {
+        FURI_LOG_E(TAG, "Failed to open file %s", name);
+        instance->file_open = FlipperI32HexFileStatusErrorNoOpenFile;
+    }
+    instance->str_data = furi_string_alloc(instance->storage);
+
+    return instance;
+}
+
+FlipperI32HexFile* flipper_i32hex_file_open_read(const char* name) {
+    furi_assert(name);
+
+    FlipperI32HexFile* instance = malloc(sizeof(FlipperI32HexFile));
+    instance->addr = 0;
+    instance->addr_last = 0;
+    instance->storage = furi_record_open(RECORD_STORAGE);
+    instance->stream = file_stream_alloc(instance->storage);
+
+    if(file_stream_open(instance->stream, name, FSAM_READ, FSOM_OPEN_EXISTING)) {
+        instance->file_open = FlipperI32HexFileStatusOpenFileRead;
+        FURI_LOG_D(TAG, "Open read file %s", name);
+    } else {
+        FURI_LOG_E(TAG, "Failed to open file %s", name);
+        instance->file_open = FlipperI32HexFileStatusErrorNoOpenFile;
+    }
+    instance->str_data = furi_string_alloc(instance->storage);
+
+    return instance;
+}
+
+void flipper_i32hex_file_close(FlipperI32HexFile* instance) {
+    furi_assert(instance);
+
+    furi_string_free(instance->str_data);
+    file_stream_close(instance->stream);
+    stream_free(instance->stream);
+    furi_record_close(RECORD_STORAGE);
+}
+
+FlipperI32HexFileRet flipper_i32hex_file_bin_to_i32hex_set_data(
+    FlipperI32HexFile* instance,
+    uint8_t* data,
+    uint32_t data_size) {
+    furi_assert(instance);
+    furi_assert(data);
+
+    FlipperI32HexFileRet ret = {.status = FlipperI32HexFileStatusOK, .data_size = 0};
+    if(instance->file_open != FlipperI32HexFileStatusOpenFileWrite) {
+        ret.status = FlipperI32HexFileStatusErrorFileWrite;
+    }
+    uint8_t count_byte = 0;
+    uint32_t ind = 0;
+    uint8_t crc = 0;
+
+    furi_string_reset(instance->str_data);
+
+    if((instance->addr_last & 0xFF0000) < (instance->addr & 0xFF0000)) {
+        crc = 0x02 + 0x04 + ((instance->addr >> 24) & 0xFF) + ((instance->addr >> 16) & 0xFF);
+        crc = 0x01 + ~crc;
+        //I32HEX_TYPE_EXT_LINEAR_ADDR
+        furi_string_cat_printf(
+            instance->str_data, ":02000004%04lX%02X\r\n", (instance->addr >> 16), crc);
+        instance->addr_last = instance->addr;
+    }
+
+    while(ind < data_size) {
+        if((ind + COUNT_BYTE_PAYLOAD) > data_size) {
+            count_byte = data_size - ind;
+        } else {
+            count_byte = COUNT_BYTE_PAYLOAD;
+        }
+        //I32HEX_TYPE_DATA
+        furi_string_cat_printf(
+            instance->str_data, ":%02X%04lX00", count_byte, (instance->addr & 0xFFFF));
+        crc = count_byte + ((instance->addr >> 8) & 0xFF) + (instance->addr & 0xFF);
+
+        for(uint32_t i = 0; i < count_byte; i++) {
+            furi_string_cat_printf(instance->str_data, "%02X", *data);
+            crc += *data++;
+        }
+        crc = 0x01 + ~crc;
+        furi_string_cat_printf(instance->str_data, "%02X\r\n", crc);
+
+        ind += count_byte;
+        instance->addr += count_byte;
+    }
+    if(instance->file_open) stream_write_string(instance->stream, instance->str_data);
+    return ret;
+}
+
+FlipperI32HexFileRet flipper_i32hex_file_bin_to_i32hex_set_end_line(FlipperI32HexFile* instance) {
+    furi_assert(instance);
+
+    FlipperI32HexFileRet ret = {.status = FlipperI32HexFileStatusOK, .data_size = 0};
+    if(instance->file_open != FlipperI32HexFileStatusOpenFileWrite) {
+        ret.status = FlipperI32HexFileStatusErrorFileWrite;
+    }
+    furi_string_reset(instance->str_data);
+    //I32HEX_TYPE_END_OF_FILE
+    furi_string_cat_printf(instance->str_data, ":00000001FF\r\n");
+    if(instance->file_open) stream_write_string(instance->stream, instance->str_data);
+    return ret;
+}
+
+void flipper_i32hex_file_bin_to_i32hex_set_addr(FlipperI32HexFile* instance, uint32_t addr) {
+    furi_assert(instance);
+
+    instance->addr = addr;
+}
+
+const char* flipper_i32hex_file_get_string(FlipperI32HexFile* instance) {
+    furi_assert(instance);
+
+    return furi_string_get_cstr(instance->str_data);
+}
+
+static FlipperI32HexFileRet flipper_i32hex_file_parse_line(
+    FlipperI32HexFile* instance,
+    const char* str,
+    uint8_t* data,
+    uint32_t data_size) {
+    furi_assert(instance);
+    furi_assert(data);
+
+    char* str1;
+    uint32_t data_wrire_ind = 0;
+    uint32_t data_len = 0;
+    FlipperI32HexFileRet ret = {.status = FlipperI32HexFileStatusErrorData, .data_size = 0};
+
+    //Search for start of data I32HEX
+    str1 = strstr(str, ":");
+    do {
+        if(str1 == NULL) {
+            ret.status = FlipperI32HexFileStatusErrorData;
+            break;
+        }
+        str1++;
+        if(!hex_char_to_uint8(*str1, str1[1], data + data_wrire_ind)) {
+            ret.status = FlipperI32HexFileStatusErrorData;
+            break;
+        }
+        str1++;
+        if(++data_wrire_ind > data_size) {
+            ret.status = FlipperI32HexFileStatusErrorOverflow;
+            break;
+        }
+        data_len = 5 + data[0]; // +5 bytes per header and crc
+        while(data_len > data_wrire_ind) {
+            str1++;
+            if(!hex_char_to_uint8(*str1, str1[1], data + data_wrire_ind)) {
+                ret.status = FlipperI32HexFileStatusErrorData;
+                break;
+            }
+            str1++;
+            if(++data_wrire_ind > data_size) {
+                ret.status = FlipperI32HexFileStatusErrorOverflow;
+                break;
+            }
+        }
+        ret.status = FlipperI32HexFileStatusOK;
+        ret.data_size = data_wrire_ind;
+
+    } while(0);
+    return ret;
+}
+
+static bool flipper_i32hex_file_check_data(uint8_t* data, uint32_t data_size) {
+    furi_assert(data);
+
+    uint8_t crc = 0;
+    uint32_t data_read_ind = 0;
+    if(data[0] > data_size) return false;
+    while(data_read_ind < data_size - 1) {
+        crc += data[data_read_ind++];
+    }
+    return data[data_size - 1] == ((1 + ~crc) & 0xFF);
+}
+
+static FlipperI32HexFileRet flipper_i32hex_file_parse(
+    FlipperI32HexFile* instance,
+    const char* str,
+    uint8_t* data,
+    uint32_t data_size) {
+    furi_assert(instance);
+    furi_assert(data);
+
+    FlipperI32HexFileRet ret = flipper_i32hex_file_parse_line(instance, str, data, data_size);
+
+    if((ret.status == FlipperI32HexFileStatusOK) && (ret.data_size > 4)) {
+        switch(data[3]) {
+        case I32HEX_TYPE_DATA:
+            if(flipper_i32hex_file_check_data(data, ret.data_size)) {
+                ret.data_size -= 5;
+                memcpy(data, data + 4, ret.data_size);
+                ret.status = FlipperI32HexFileStatusData;
+            } else {
+                ret.status = FlipperI32HexFileStatusErrorCrc;
+                ret.data_size = 0;
+            }
+            break;
+        case I32HEX_TYPE_END_OF_FILE:
+            if(flipper_i32hex_file_check_data(data, ret.data_size)) {
+                ret.status = FlipperI32HexFileStatusEofFile;
+                ret.data_size = 0;
+            } else {
+                ret.status = FlipperI32HexFileStatusErrorCrc;
+                ret.data_size = 0;
+            }
+            break;
+        case I32HEX_TYPE_EXT_LINEAR_ADDR:
+            if(flipper_i32hex_file_check_data(data, ret.data_size)) {
+                data[0] = data[4];
+                data[1] = data[5];
+                data[3] = 0;
+                data[4] = 0;
+                ret.status = FlipperI32HexFileStatusUdateAddr;
+                ret.data_size = 4;
+            } else {
+                ret.status = FlipperI32HexFileStatusErrorCrc;
+                ret.data_size = 0;
+            }
+            break;
+        case I32HEX_TYPE_START_LINEAR_ADDR:
+            ret.status = FlipperI32HexFileStatusErrorUnsupportedCommand;
+            ret.data_size = 0;
+            break;
+        default:
+            ret.status = FlipperI32HexFileStatusErrorUnsupportedCommand;
+            ret.data_size = 0;
+            break;
+        }
+    } else {
+        ret.status = FlipperI32HexFileStatusErrorData;
+        ret.data_size = 0;
+    }
+    return ret;
+}
+
+bool flipper_i32hex_file_check(FlipperI32HexFile* instance) {
+    furi_assert(instance);
+
+    uint32_t data_size = 280;
+    uint8_t data[280] = {0};
+    bool ret = true;
+
+    if(instance->file_open != FlipperI32HexFileStatusOpenFileRead) {
+        FURI_LOG_E(TAG, "File is not open");
+        ret = false;
+    } else {
+        stream_rewind(instance->stream);
+
+        while(stream_read_line(instance->stream, instance->str_data)) {
+            FlipperI32HexFileRet parse_ret = flipper_i32hex_file_parse(
+                instance, furi_string_get_cstr(instance->str_data), data, data_size);
+
+            if(parse_ret.status < 0) {
+                ret = false;
+            }
+        }
+        stream_rewind(instance->stream);
+    }
+    return ret;
+}
+
+FlipperI32HexFileRet flipper_i32hex_file_i32hex_to_bin_get_data(
+    FlipperI32HexFile* instance,
+    uint8_t* data,
+    uint32_t data_size) {
+    furi_assert(instance);
+    furi_assert(data);
+
+    FlipperI32HexFileRet ret = {.status = FlipperI32HexFileStatusOK, .data_size = 0};
+    if(instance->file_open != FlipperI32HexFileStatusOpenFileRead) {
+        ret.status = FlipperI32HexFileStatusErrorFileRead;
+    } else {
+        stream_read_line(instance->stream, instance->str_data);
+        ret = flipper_i32hex_file_parse(
+            instance, furi_string_get_cstr(instance->str_data), data, data_size);
+    }
+
+    return ret;
+}

+ 55 - 0
avr_isp_programmer/helpers/flipper_i32hex_file.h

@@ -0,0 +1,55 @@
+#pragma once
+
+#include <furi_hal.h>
+
+typedef struct FlipperI32HexFile FlipperI32HexFile;
+
+typedef enum {
+    FlipperI32HexFileStatusOK = 0,
+    FlipperI32HexFileStatusData = 2,
+    FlipperI32HexFileStatusUdateAddr = 3,
+    FlipperI32HexFileStatusEofFile = 4,
+    FlipperI32HexFileStatusOpenFileWrite = 5,
+    FlipperI32HexFileStatusOpenFileRead = 6,
+
+    // Errors
+    FlipperI32HexFileStatusErrorCrc = (-1),
+    FlipperI32HexFileStatusErrorOverflow = (-2),
+    FlipperI32HexFileStatusErrorData = (-3),
+    FlipperI32HexFileStatusErrorUnsupportedCommand = (-4),
+    FlipperI32HexFileStatusErrorNoOpenFile = (-5),
+    FlipperI32HexFileStatusErrorFileWrite = (-6),
+    FlipperI32HexFileStatusErrorFileRead = (-7),
+
+    FlipperI32HexFileStatusReserved =
+        0x7FFFFFFF, ///< Prevents enum down-size compiler optimization.
+} FlipperI32HexFileStatus;
+
+typedef struct {
+    FlipperI32HexFileStatus status;
+    uint32_t data_size;
+} FlipperI32HexFileRet;
+
+FlipperI32HexFile* flipper_i32hex_file_open_write(const char* name, uint32_t start_addr);
+
+FlipperI32HexFile* flipper_i32hex_file_open_read(const char* name);
+
+void flipper_i32hex_file_close(FlipperI32HexFile* instance);
+
+FlipperI32HexFileRet flipper_i32hex_file_bin_to_i32hex_set_data(
+    FlipperI32HexFile* instance,
+    uint8_t* data,
+    uint32_t data_size);
+
+FlipperI32HexFileRet flipper_i32hex_file_bin_to_i32hex_set_end_line(FlipperI32HexFile* instance);
+
+const char* flipper_i32hex_file_get_string(FlipperI32HexFile* instance);
+
+void flipper_i32hex_file_bin_to_i32hex_set_addr(FlipperI32HexFile* instance, uint32_t addr);
+
+bool flipper_i32hex_file_check(FlipperI32HexFile* instance);
+
+FlipperI32HexFileRet flipper_i32hex_file_i32hex_to_bin_get_data(
+    FlipperI32HexFile* instance,
+    uint8_t* data,
+    uint32_t data_size);

BIN
avr_isp_programmer/images/avr_app_icon_10x10.png


BIN
avr_isp_programmer/images/avr_wiring.png


BIN
avr_isp_programmer/images/chif_not_found_83x37.png


BIN
avr_isp_programmer/images/chip_error_70x22.png


BIN
avr_isp_programmer/images/chip_long_70x22.png


BIN
avr_isp_programmer/images/chip_not_found_83x37.png


BIN
avr_isp_programmer/images/dolphin_nice_96x59.png


BIN
avr_isp_programmer/images/isp_active_128x53.png


BIN
avr_isp_programmer/images/link_waiting_77x56.png


+ 386 - 0
avr_isp_programmer/lib/driver/avr_isp_chip_arr.c

@@ -0,0 +1,386 @@
+#include "avr_isp_chip_arr.h"
+
+#include <furi.h>
+
+//https://github.com/avrdudes/avrdude/blob/master/src/avrintel.c
+
+const AvrIspChipArr avr_isp_chip_arr[] = {   // Value of -1 typically means unknown
+  //{mcu_name,       mcuid,  family, {sig,    na, ture}, flstart,  flsize, pgsiz, nb, bootsz, eestart, eesize, ep, rambeg, ramsiz, nf, nl,  ni}, // Source
+  {"ATtiny4",            0, F_AVR8L, {0x1E, 0x8F, 0x0A},       0, 0x00200, 0x010,  0,      0,       0,      0,  0, 0x0040, 0x0020,  1,  1,  10}, // atdf, avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"ATtiny5",            1, F_AVR8L, {0x1E, 0x8F, 0x09},       0, 0x00200, 0x010,  0,      0,       0,      0,  0, 0x0040, 0x0020,  1,  1,  11}, // atdf, avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"ATtiny9",            2, F_AVR8L, {0x1E, 0x90, 0x08},       0, 0x00400, 0x010,  0,      0,       0,      0,  0, 0x0040, 0x0020,  1,  1,  10}, // atdf, avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"ATtiny10",           3, F_AVR8L, {0x1E, 0x90, 0x03},       0, 0x00400, 0x010,  0,      0,       0,      0,  0, 0x0040, 0x0020,  1,  1,  11}, // atdf, avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"ATtiny20",           4, F_AVR8L, {0x1E, 0x91, 0x0F},       0, 0x00800, 0x020,  0,      0,       0,      0,  0, 0x0040, 0x0080,  1,  1,  17}, // atdf, avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"ATtiny40",           5, F_AVR8L, {0x1E, 0x92, 0x0E},       0, 0x01000, 0x040,  0,      0,       0,      0,  0, 0x0040, 0x0100,  1,  1,  18}, // atdf, avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"ATtiny102",          6, F_AVR8L, {0x1E, 0x90, 0x0C},       0, 0x00400, 0x010,  0,      0,       0,      0,  0, 0x0040, 0x0020,  1,  1,  16}, // atdf, avrdude, boot size (manual)
+  {"ATtiny104",          7, F_AVR8L, {0x1E, 0x90, 0x0B},       0, 0x00400, 0x010,  0,      0,       0,      0,  0, 0x0040, 0x0020,  1,  1,  16}, // atdf, avrdude, boot size (manual)
+
+  {"ATtiny11",           8,  F_AVR8, {0x1E, 0x90, 0x04},       0, 0x00400, 0x001,  0,      0,       0, 0x0040,  1, 0x0060, 0x0020,  1,  1,   5}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny12",           9,  F_AVR8, {0x1E, 0x90, 0x05},       0, 0x00400, 0x001,  0,      0,       0, 0x0040,  2, 0x0060, 0x0020,  1,  1,   6}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny13",          10,  F_AVR8, {0x1E, 0x90, 0x07},       0, 0x00400, 0x020,  0,      0,       0, 0x0040,  4, 0x0060, 0x0040,  2,  1,  10}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny13A",         11,  F_AVR8, {0x1E, 0x90, 0x07},       0, 0x00400, 0x020,  0,      0,       0, 0x0040,  4, 0x0060, 0x0040,  2,  1,  10}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny15",          12,  F_AVR8, {0x1E, 0x90, 0x06},       0, 0x00400, 0x001,  0,      0,       0, 0x0040,  2, 0x0060, 0x0020,  1,  1,   9}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny22",          13,  F_AVR8, {0x1E, 0x91, 0x06},       0, 0x00800,    -1,  0,      0,      -1,     -1, -1, 0x0060, 0x0080,  1,  1,   3}, // avr-gcc 12.2.0, boot size (manual)
+  {"ATtiny24",          14,  F_AVR8, {0x1E, 0x91, 0x0B},       0, 0x00800, 0x020,  0,      0,       0, 0x0080,  4, 0x0060, 0x0080,  3,  1,  17}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny24A",         15,  F_AVR8, {0x1E, 0x91, 0x0B},       0, 0x00800, 0x020,  0,      0,       0, 0x0080,  4, 0x0060, 0x0080,  3,  1,  17}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny25",          16,  F_AVR8, {0x1E, 0x91, 0x08},       0, 0x00800, 0x020,  0,      0,       0, 0x0080,  4, 0x0060, 0x0080,  3,  1,  15}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny26",          17,  F_AVR8, {0x1E, 0x91, 0x09},       0, 0x00800, 0x020,  0,      0,       0, 0x0080,  4, 0x0060, 0x0080,  2,  1,  12}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny28",          18,  F_AVR8, {0x1E, 0x91, 0x07},       0, 0x00800, 0x002,  0,      0,       0,      0,  0, 0x0060, 0x0020,  1,  1,   6}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny43U",         19,  F_AVR8, {0x1E, 0x92, 0x0C},       0, 0x01000, 0x040,  0,      0,       0, 0x0040,  4, 0x0060, 0x0100,  3,  1,  16}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny44",          20,  F_AVR8, {0x1E, 0x92, 0x07},       0, 0x01000, 0x040,  0,      0,       0, 0x0100,  4, 0x0060, 0x0100,  3,  1,  17}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny44A",         21,  F_AVR8, {0x1E, 0x92, 0x07},       0, 0x01000, 0x040,  0,      0,       0, 0x0100,  4, 0x0060, 0x0100,  3,  1,  17}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny45",          22,  F_AVR8, {0x1E, 0x92, 0x06},       0, 0x01000, 0x040,  0,      0,       0, 0x0100,  4, 0x0060, 0x0100,  3,  1,  15}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny48",          23,  F_AVR8, {0x1E, 0x92, 0x09},       0, 0x01000, 0x040,  0,      0,       0, 0x0040,  4, 0x0100, 0x0100,  3,  1,  20}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny84",          24,  F_AVR8, {0x1E, 0x93, 0x0C},       0, 0x02000, 0x040,  0,      0,       0, 0x0200,  4, 0x0060, 0x0200,  3,  1,  17}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny84A",         25,  F_AVR8, {0x1E, 0x93, 0x0C},       0, 0x02000, 0x040,  0,      0,       0, 0x0200,  4, 0x0060, 0x0200,  3,  1,  17}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny85",          26,  F_AVR8, {0x1E, 0x93, 0x0B},       0, 0x02000, 0x040,  0,      0,       0, 0x0200,  4, 0x0060, 0x0200,  3,  1,  15}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny87",          27,  F_AVR8, {0x1E, 0x93, 0x87},       0, 0x02000, 0x080,  0,      0,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  20}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny88",          28,  F_AVR8, {0x1E, 0x93, 0x11},       0, 0x02000, 0x040,  0,      0,       0, 0x0040,  4, 0x0100, 0x0200,  3,  1,  20}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny167",         29,  F_AVR8, {0x1E, 0x94, 0x87},       0, 0x04000, 0x080,  0,      0,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  20}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny261",         30,  F_AVR8, {0x1E, 0x91, 0x0C},       0, 0x00800, 0x020,  0,      0,       0, 0x0080,  4, 0x0060, 0x0080,  3,  1,  19}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny261A",        31,  F_AVR8, {0x1E, 0x91, 0x0C},       0, 0x00800, 0x020,  0,      0,       0, 0x0080,  4, 0x0060, 0x0080,  3,  1,  19}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny441",         32,  F_AVR8, {0x1E, 0x92, 0x15},       0, 0x01000, 0x010,  0,      0,       0, 0x0100,  4, 0x0100, 0x0100,  3,  1,  30}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny461",         33,  F_AVR8, {0x1E, 0x92, 0x08},       0, 0x01000, 0x040,  0,      0,       0, 0x0100,  4, 0x0060, 0x0100,  3,  1,  19}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny461A",        34,  F_AVR8, {0x1E, 0x92, 0x08},       0, 0x01000, 0x040,  0,      0,       0, 0x0100,  4, 0x0060, 0x0100,  3,  1,  19}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny828",         35,  F_AVR8, {0x1E, 0x93, 0x14},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0100,  4, 0x0100, 0x0200,  3,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny828R",        36,  F_AVR8, {0x1E, 0x93, 0x14},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0100,  4, 0x0100, 0x0200,  3,  1,  26}, // avrdude, from ATtiny828
+  {"ATtiny841",         37,  F_AVR8, {0x1E, 0x93, 0x15},       0, 0x02000, 0x010,  0,      0,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  30}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny861",         38,  F_AVR8, {0x1E, 0x93, 0x0D},       0, 0x02000, 0x040,  0,      0,       0, 0x0200,  4, 0x0060, 0x0200,  3,  1,  19}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny861A",        39,  F_AVR8, {0x1E, 0x93, 0x0D},       0, 0x02000, 0x040,  0,      0,       0, 0x0200,  4, 0x0060, 0x0200,  3,  1,  19}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny1634",        40,  F_AVR8, {0x1E, 0x94, 0x12},       0, 0x04000, 0x020,  0,      0,       0, 0x0100,  4, 0x0100, 0x0400,  3,  1,  28}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny1634R",       41,  F_AVR8, {0x1E, 0x94, 0x12},       0, 0x04000, 0x020,  0,      0,       0, 0x0100,  4, 0x0100, 0x0400,  3,  1,  28}, // avrdude, from ATtiny1634
+  {"ATtiny2313",        42,  F_AVR8, {0x1E, 0x91, 0x0A},       0, 0x00800, 0x020,  0,      0,       0, 0x0080,  4, 0x0060, 0x0080,  3,  1,  19}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny2313A",       43,  F_AVR8, {0x1E, 0x91, 0x0A},       0, 0x00800, 0x020,  0,      0,       0, 0x0080,  4, 0x0060, 0x0080,  3,  1,  21}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny4313",        44,  F_AVR8, {0x1E, 0x92, 0x0D},       0, 0x01000, 0x040,  0,      0,       0, 0x0100,  4, 0x0060, 0x0100,  3,  1,  21}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega8",           45,  F_AVR8, {0x1E, 0x93, 0x07},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0060, 0x0400,  2,  1,  19}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega8A",          46,  F_AVR8, {0x1E, 0x93, 0x07},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0060, 0x0400,  2,  1,  19}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega8HVA",        47,  F_AVR8, {0x1E, 0x93, 0x10},       0, 0x02000, 0x080,  0,      0,       0, 0x0100,  4, 0x0100, 0x0200,  1,  1,  21}, // atdf, avr-gcc 12.2.0
+  {"ATmega8U2",         48,  F_AVR8, {0x1E, 0x93, 0x89},       0, 0x02000, 0x080,  4, 0x0200,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  29}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega16",          49,  F_AVR8, {0x1E, 0x94, 0x03},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0060, 0x0400,  2,  1,  21}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega16A",         50,  F_AVR8, {0x1E, 0x94, 0x03},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0060, 0x0400,  2,  1,  21}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega16HVA",       51,  F_AVR8, {0x1E, 0x94, 0x0C},       0, 0x04000, 0x080,  0,      0,       0, 0x0100,  4, 0x0100, 0x0200,  1,  1,  21}, // atdf, avr-gcc 12.2.0
+  {"ATmega16HVB",       52,  F_AVR8, {0x1E, 0x94, 0x0D},       0, 0x04000, 0x080,  4, 0x0200,       0, 0x0200,  4, 0x0100, 0x0400,  2,  1,  29}, // atdf, avr-gcc 12.2.0
+  {"ATmega16HVBrevB",   53,  F_AVR8, {0x1E, 0x94, 0x0D},       0, 0x04000, 0x080,  4, 0x0200,       0, 0x0200,  4, 0x0100, 0x0400,  2,  1,  29}, // atdf, avr-gcc 12.2.0
+  {"ATmega16M1",        54,  F_AVR8, {0x1E, 0x94, 0x84},       0, 0x04000, 0x080,  4, 0x0200,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  31}, // atdf, avr-gcc 12.2.0
+  {"ATmega16HVA2",      55,  F_AVR8, {0x1E, 0x94, 0x0E},       0, 0x04000, 0x080, -1,     -1,      -1,     -1, -1, 0x0100, 0x0400,  2,  1,  22}, // avr-gcc 12.2.0
+  {"ATmega16U2",        56,  F_AVR8, {0x1E, 0x94, 0x89},       0, 0x04000, 0x080,  4, 0x0200,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  29}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega16U4",        57,  F_AVR8, {0x1E, 0x94, 0x88},       0, 0x04000, 0x080,  4, 0x0200,       0, 0x0200,  4, 0x0100, 0x0500,  3,  1,  43}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega32",          58,  F_AVR8, {0x1E, 0x95, 0x02},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0060, 0x0800,  2,  1,  21}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega32A",         59,  F_AVR8, {0x1E, 0x95, 0x02},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0060, 0x0800,  2,  1,  21}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega32HVB",       60,  F_AVR8, {0x1E, 0x95, 0x10},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  2,  1,  29}, // atdf, avr-gcc 12.2.0
+  {"ATmega32HVBrevB",   61,  F_AVR8, {0x1E, 0x95, 0x10},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  2,  1,  29}, // atdf, avr-gcc 12.2.0
+  {"ATmega32C1",        62,  F_AVR8, {0x1E, 0x95, 0x86},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  31}, // atdf, avr-gcc 12.2.0
+  {"ATmega32M1",        63,  F_AVR8, {0x1E, 0x95, 0x84},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega32U2",        64,  F_AVR8, {0x1E, 0x95, 0x8A},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0400,  3,  1,  29}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega32U4",        65,  F_AVR8, {0x1E, 0x95, 0x87},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0a00,  3,  1,  43}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega32U6",        66,  F_AVR8, {0x1E, 0x95, 0x88},       0, 0x08000, 0x080,  4, 0x0200,      -1,     -1, -1, 0x0100, 0x0a00,  3,  1,  38}, // avr-gcc 12.2.0, boot size (manual)
+  {"ATmega48",          67,  F_AVR8, {0x1E, 0x92, 0x05},       0, 0x01000, 0x040,  0,      0,       0, 0x0100,  4, 0x0100, 0x0200,  3,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega48A",         68,  F_AVR8, {0x1E, 0x92, 0x05},       0, 0x01000, 0x040,  0,      0,       0, 0x0100,  4, 0x0100, 0x0200,  3,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega48P",         69,  F_AVR8, {0x1E, 0x92, 0x0A},       0, 0x01000, 0x040,  0,      0,       0, 0x0100,  4, 0x0100, 0x0200,  3,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega48PA",        70,  F_AVR8, {0x1E, 0x92, 0x0A},       0, 0x01000, 0x040,  0,      0,       0, 0x0100,  4, 0x0100, 0x0200,  3,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega48PB",        71,  F_AVR8, {0x1E, 0x92, 0x10},       0, 0x01000, 0x040,  0,      0,       0, 0x0100,  4, 0x0100, 0x0200,  3,  1,  27}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega64",          72,  F_AVR8, {0x1E, 0x96, 0x02},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  35}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega64A",         73,  F_AVR8, {0x1E, 0x96, 0x02},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  35}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega64HVE",       74,  F_AVR8, {0x1E, 0x96, 0x10},       0, 0x10000, 0x080,  4, 0x0400,      -1,     -1, -1, 0x0100, 0x1000,  2,  1,  25}, // avr-gcc 12.2.0, boot size (manual)
+  {"ATmega64C1",        75,  F_AVR8, {0x1E, 0x96, 0x86},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  31}, // atdf, avr-gcc 12.2.0
+  {"ATmega64M1",        76,  F_AVR8, {0x1E, 0x96, 0x84},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega64HVE2",      77,  F_AVR8, {0x1E, 0x96, 0x10},       0, 0x10000, 0x080,  4, 0x0400,       0, 0x0400,  4, 0x0100, 0x1000,  2,  1,  25}, // atdf, avr-gcc 12.2.0
+  {"ATmega64RFR2",      78,  F_AVR8, {0x1E, 0xA6, 0x02},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0200, 0x2000,  3,  1,  77}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega88",          79,  F_AVR8, {0x1E, 0x93, 0x0A},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega88A",         80,  F_AVR8, {0x1E, 0x93, 0x0A},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega88P",         81,  F_AVR8, {0x1E, 0x93, 0x0F},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega88PA",        82,  F_AVR8, {0x1E, 0x93, 0x0F},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega88PB",        83,  F_AVR8, {0x1E, 0x93, 0x16},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  27}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega103",         84,  F_AVR8, {0x1E, 0x97, 0x01},       0, 0x20000, 0x100,  0,      0,       0, 0x1000,  1, 0x0060, 0x0fa0,  1,  1,  24}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"ATmega128",         85,  F_AVR8, {0x1E, 0x97, 0x02},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0100, 0x1000,  3,  1,  35}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega128A",        86,  F_AVR8, {0x1E, 0x97, 0x02},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0100, 0x1000,  3,  1,  35}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega128RFA1",     87,  F_AVR8, {0x1E, 0xA7, 0x01},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0200, 0x4000,  3,  1,  72}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega128RFR2",     88,  F_AVR8, {0x1E, 0xA7, 0x02},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0200, 0x4000,  3,  1,  77}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega161",         89,  F_AVR8, {0x1E, 0x94, 0x01},       0, 0x04000, 0x080,  1, 0x0400,       0, 0x0200,  1, 0x0060, 0x0400,  1,  1,  21}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"ATmega162",         90,  F_AVR8, {0x1E, 0x94, 0x04},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  28}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega163",         91,  F_AVR8, {0x1E, 0x94, 0x02},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  1, 0x0060, 0x0400,  2,  1,  18}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"ATmega164A",        92,  F_AVR8, {0x1E, 0x94, 0x0F},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega164P",        93,  F_AVR8, {0x1E, 0x94, 0x0A},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega164PA",       94,  F_AVR8, {0x1E, 0x94, 0x0A},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega165",         95,  F_AVR8, {0x1E, 0x94, 0x10},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  22}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"ATmega165A",        96,  F_AVR8, {0x1E, 0x94, 0x10},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  22}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega165P",        97,  F_AVR8, {0x1E, 0x94, 0x07},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  22}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega165PA",       98,  F_AVR8, {0x1E, 0x94, 0x07},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  22}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega168",         99,  F_AVR8, {0x1E, 0x94, 0x06},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega168A",       100,  F_AVR8, {0x1E, 0x94, 0x06},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega168P",       101,  F_AVR8, {0x1E, 0x94, 0x0B},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega168PA",      102,  F_AVR8, {0x1E, 0x94, 0x0B},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega168PB",      103,  F_AVR8, {0x1E, 0x94, 0x15},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  27}, // atdf, avr-gcc 7.3.0, avrdude
+  {"ATmega169",        104,  F_AVR8, {0x1E, 0x94, 0x05},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  23}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"ATmega169A",       105,  F_AVR8, {0x1E, 0x94, 0x11},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  23}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega169P",       106,  F_AVR8, {0x1E, 0x94, 0x05},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  23}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega169PA",      107,  F_AVR8, {0x1E, 0x94, 0x05},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  23}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega256RFR2",    108,  F_AVR8, {0x1E, 0xA8, 0x02},       0, 0x40000, 0x100,  4, 0x0400,       0, 0x2000,  8, 0x0200, 0x8000,  3,  1,  77}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega323",        109,  F_AVR8, {0x1E, 0x95, 0x01},       0, 0x08000, 0x080,  4, 0x0200,      -1,     -1, -1, 0x0060, 0x0800,  2,  1,  21}, // avr-gcc 12.2.0, boot size (manual)
+  {"ATmega324A",       110,  F_AVR8, {0x1E, 0x95, 0x15},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega324P",       111,  F_AVR8, {0x1E, 0x95, 0x08},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega324PA",      112,  F_AVR8, {0x1E, 0x95, 0x11},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega324PB",      113,  F_AVR8, {0x1E, 0x95, 0x17},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  51}, // atdf, avrdude
+  {"ATmega325",        114,  F_AVR8, {0x1E, 0x95, 0x05},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  22}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega325A",       115,  F_AVR8, {0x1E, 0x95, 0x05},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  22}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega325P",       116,  F_AVR8, {0x1E, 0x95, 0x0D},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  22}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega325PA",      117,  F_AVR8, {0x1E, 0x95, 0x0D},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  22}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega328",        118,  F_AVR8, {0x1E, 0x95, 0x14},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega328P",       119,  F_AVR8, {0x1E, 0x95, 0x0F},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega328PB",      120,  F_AVR8, {0x1E, 0x95, 0x16},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  45}, // atdf, avr-gcc 7.3.0, avrdude
+  {"ATmega329",        121,  F_AVR8, {0x1E, 0x95, 0x03},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  23}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega329A",       122,  F_AVR8, {0x1E, 0x95, 0x03},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  23}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega329P",       123,  F_AVR8, {0x1E, 0x95, 0x0B},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  23}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega329PA",      124,  F_AVR8, {0x1E, 0x95, 0x0B},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  23}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega406",        125,  F_AVR8, {0x1E, 0x95, 0x07},       0, 0x0a000, 0x080,  4, 0x0200,       0, 0x0200,  4, 0x0100, 0x0800,  2,  1,  23}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega640",        126,  F_AVR8, {0x1E, 0x96, 0x08},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0200, 0x2000,  3,  1,  57}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega644",        127,  F_AVR8, {0x1E, 0x96, 0x09},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  28}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega644A",       128,  F_AVR8, {0x1E, 0x96, 0x09},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega644P",       129,  F_AVR8, {0x1E, 0x96, 0x0A},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega644PA",      130,  F_AVR8, {0x1E, 0x96, 0x0A},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega644RFR2",    131,  F_AVR8, {0x1E, 0xA6, 0x03},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0200, 0x2000,  3,  1,  77}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega645",        132,  F_AVR8, {0x1E, 0x96, 0x05},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  22}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega645A",       133,  F_AVR8, {0x1E, 0x96, 0x05},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  22}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega645P",       134,  F_AVR8, {0x1E, 0x96, 0x0D},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  22}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega649",        135,  F_AVR8, {0x1E, 0x96, 0x03},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  23}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega649A",       136,  F_AVR8, {0x1E, 0x96, 0x03},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  23}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega649P",       137,  F_AVR8, {0x1E, 0x96, 0x0B},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  23}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega1280",       138,  F_AVR8, {0x1E, 0x97, 0x03},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0200, 0x2000,  3,  1,  57}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega1281",       139,  F_AVR8, {0x1E, 0x97, 0x04},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0200, 0x2000,  3,  1,  57}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega1284",       140,  F_AVR8, {0x1E, 0x97, 0x06},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0100, 0x4000,  3,  1,  35}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega1284P",      141,  F_AVR8, {0x1E, 0x97, 0x05},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0100, 0x4000,  3,  1,  35}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega1284RFR2",   142,  F_AVR8, {0x1E, 0xA7, 0x03},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0200, 0x4000,  3,  1,  77}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega2560",       143,  F_AVR8, {0x1E, 0x98, 0x01},       0, 0x40000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0200, 0x2000,  3,  1,  57}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega2561",       144,  F_AVR8, {0x1E, 0x98, 0x02},       0, 0x40000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0200, 0x2000,  3,  1,  57}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega2564RFR2",   145,  F_AVR8, {0x1E, 0xA8, 0x03},       0, 0x40000, 0x100,  4, 0x0400,       0, 0x2000,  8, 0x0200, 0x8000,  3,  1,  77}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega3250",       146,  F_AVR8, {0x1E, 0x95, 0x06},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  25}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega3250A",      147,  F_AVR8, {0x1E, 0x95, 0x06},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  25}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega3250P",      148,  F_AVR8, {0x1E, 0x95, 0x0E},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  25}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega3250PA",     149,  F_AVR8, {0x1E, 0x95, 0x0E},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  25}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega3290",       150,  F_AVR8, {0x1E, 0x95, 0x04},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  25}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega3290A",      151,  F_AVR8, {0x1E, 0x95, 0x04},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  25}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega3290P",      152,  F_AVR8, {0x1E, 0x95, 0x0C},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  25}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega3290PA",     153,  F_AVR8, {0x1E, 0x95, 0x0C},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  25}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega6450",       154,  F_AVR8, {0x1E, 0x96, 0x06},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  25}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega6450A",      155,  F_AVR8, {0x1E, 0x96, 0x06},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  25}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega6450P",      156,  F_AVR8, {0x1E, 0x96, 0x0E},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  25}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega6490",       157,  F_AVR8, {0x1E, 0x96, 0x04},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  25}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega6490A",      158,  F_AVR8, {0x1E, 0x96, 0x04},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  25}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega6490P",      159,  F_AVR8, {0x1E, 0x96, 0x0C},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  25}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega8515",       160,  F_AVR8, {0x1E, 0x93, 0x06},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0060, 0x0200,  2,  1,  17}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega8535",       161,  F_AVR8, {0x1E, 0x93, 0x08},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0060, 0x0200,  2,  1,  21}, // atdf, avr-gcc 12.2.0, avrdude
+  {"AT43USB320",       162,  F_AVR8, {0xff,   -1,   -1},       0, 0x10000,    -1, -1,     -1,      -1,     -1, -1, 0x0060, 0x0200, -1, -1,   0}, // avr-gcc 12.2.0
+  {"AT43USB355",       163,  F_AVR8, {0xff,   -1,   -1},       0, 0x06000,    -1, -1,     -1,      -1,     -1, -1, 0x0060, 0x0400, -1, -1,   0}, // avr-gcc 12.2.0
+  {"AT76C711",         164,  F_AVR8, {0xff,   -1,   -1},       0, 0x04000,    -1, -1,     -1,      -1,     -1, -1, 0x0060, 0x07a0, -1, -1,   0}, // avr-gcc 12.2.0
+  {"AT86RF401",        165,  F_AVR8, {0x1E, 0x91, 0x81},       0, 0x00800,    -1, -1,     -1,      -1,     -1, -1, 0x0060, 0x0080,  0,  1,   3}, // avr-gcc 12.2.0
+  {"AT90PWM1",         166,  F_AVR8, {0x1E, 0x93, 0x83},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  32}, // atdf, avr-gcc 12.2.0
+  {"AT90PWM2",         167,  F_AVR8, {0x1E, 0x93, 0x81},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  32}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"AT90PWM2B",        168,  F_AVR8, {0x1E, 0x93, 0x83},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  32}, // atdf, avr-gcc 12.2.0, avrdude
+  {"AT90PWM3",         169,  F_AVR8, {0x1E, 0x93, 0x81},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  32}, // atdf, avr-gcc 12.2.0, avrdude
+  {"AT90PWM3B",        170,  F_AVR8, {0x1E, 0x93, 0x83},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  32}, // atdf, avr-gcc 12.2.0, avrdude
+  {"AT90CAN32",        171,  F_AVR8, {0x1E, 0x95, 0x81},       0, 0x08000, 0x100,  4, 0x0400,       0, 0x0400,  8, 0x0100, 0x0800,  3,  1,  37}, // atdf, avr-gcc 12.2.0, avrdude
+  {"AT90CAN64",        172,  F_AVR8, {0x1E, 0x96, 0x81},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  37}, // atdf, avr-gcc 12.2.0, avrdude
+  {"AT90PWM81",        173,  F_AVR8, {0x1E, 0x93, 0x88},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0100,  3,  1,  20}, // atdf, avr-gcc 12.2.0
+  {"AT90USB82",        174,  F_AVR8, {0x1E, 0x93, 0x82},       0, 0x02000, 0x080,  4, 0x0200,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  29}, // atdf, avr-gcc 12.2.0, avrdude
+  {"AT90SCR100",       175,  F_AVR8, {0x1E, 0x96, 0xC1},       0, 0x10000, 0x100,  4, 0x0200,      -1,     -1, -1, 0x0100, 0x1000,  3,  1,  38}, // avr-gcc 12.2.0, boot size (manual)
+  {"AT90CAN128",       176,  F_AVR8, {0x1E, 0x97, 0x81},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0100, 0x1000,  3,  1,  37}, // atdf, avr-gcc 12.2.0, avrdude
+  {"AT90PWM161",       177,  F_AVR8, {0x1E, 0x94, 0x8B},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  20}, // atdf, avr-gcc 12.2.0
+  {"AT90USB162",       178,  F_AVR8, {0x1E, 0x94, 0x82},       0, 0x04000, 0x080,  4, 0x0200,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  29}, // atdf, avr-gcc 12.2.0, avrdude
+  {"AT90PWM216",       179,  F_AVR8, {0x1E, 0x94, 0x83},       0, 0x04000, 0x080,  4, 0x0200,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  32}, // atdf, avr-gcc 12.2.0, avrdude
+  {"AT90PWM316",       180,  F_AVR8, {0x1E, 0x94, 0x83},       0, 0x04000, 0x080,  4, 0x0200,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  32}, // atdf, avr-gcc 12.2.0, avrdude
+  {"AT90USB646",       181,  F_AVR8, {0x1E, 0x96, 0x82},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  38}, // atdf, avr-gcc 12.2.0, avrdude
+  {"AT90USB647",       182,  F_AVR8, {0x1E, 0x96, 0x82},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  38}, // atdf, avr-gcc 12.2.0, avrdude
+  {"AT90S1200",        183,  F_AVR8, {0x1E, 0x90, 0x01},       0, 0x00400, 0x001,  0,      0,       0, 0x0040,  1, 0x0060, 0x0020,  1,  1,   4}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"AT90USB1286",      184,  F_AVR8, {0x1E, 0x97, 0x82},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0100, 0x2000,  3,  1,  38}, // atdf, avr-gcc 12.2.0, avrdude
+  {"AT90USB1287",      185,  F_AVR8, {0x1E, 0x97, 0x82},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0100, 0x2000,  3,  1,  38}, // atdf, avr-gcc 12.2.0, avrdude
+  {"AT90S2313",        186,  F_AVR8, {0x1E, 0x91, 0x01},       0, 0x00800, 0x001,  0,      0,       0, 0x0080,  1, 0x0060, 0x0080,  1,  1,  11}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"AT90S2323",        187,  F_AVR8, {0x1E, 0x91, 0x02},       0, 0x00800,    -1,  0,      0,      -1,     -1, -1, 0x0060, 0x0080,  1,  1,   3}, // avr-gcc 12.2.0, boot size (manual)
+  {"AT90S2333",        188,  F_AVR8, {0x1E, 0x91, 0x05},       0, 0x00800, 0x001,  0,      0,       0, 0x0080,  1, 0x0060, 0x0080, -1, -1,  14}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"AT90S2343",        189,  F_AVR8, {0x1E, 0x91, 0x03},       0, 0x00800, 0x001,  0,      0,       0, 0x0080,  1, 0x0060, 0x0080,  1,  1,   3}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"AT90S4414",        190,  F_AVR8, {0x1E, 0x92, 0x01},       0, 0x01000, 0x001,  0,      0,       0, 0x0100,  1, 0x0060, 0x0100,  1,  1,  13}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"AT90S4433",        191,  F_AVR8, {0x1E, 0x92, 0x03},       0, 0x01000, 0x001,  0,      0,       0, 0x0100,  1, 0x0060, 0x0080,  1,  1,  14}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"AT90S4434",        192,  F_AVR8, {0x1E, 0x92, 0x02},       0, 0x01000, 0x001,  0,      0,       0, 0x0100,  1, 0x0060, 0x0100,  1,  1,  17}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"AT90S8515",        193,  F_AVR8, {0x1E, 0x93, 0x01},       0, 0x02000, 0x001,  0,      0,       0, 0x0200,  1, 0x0060, 0x0200,  1,  1,  13}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"AT90C8534",        194,  F_AVR8, {0xff,   -1,   -1},       0, 0x02000,    -1, -1,     -1,      -1,     -1, -1, 0x0060, 0x0100, -1, -1,   0}, // avr-gcc 12.2.0
+  {"AT90S8535",        195,  F_AVR8, {0x1E, 0x93, 0x03},       0, 0x02000, 0x001,  0,      0,       0, 0x0200,  1, 0x0060, 0x0200,  1,  1,  17}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"AT94K",            196,  F_AVR8, {0xff,   -1,   -1},       0, 0x08000,    -1, -1,     -1,      -1,     -1, -1, 0x0060, 0x0fa0, -1, -1,   0}, // avr-gcc 12.2.0
+  {"ATA5272",          197,  F_AVR8, {0x1E, 0x93, 0x87},       0, 0x02000, 0x080,  0,      0,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  37}, // atdf, avr-gcc 12.2.0
+  {"ATA5505",          198,  F_AVR8, {0x1E, 0x94, 0x87},       0, 0x04000, 0x080,  0,      0,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  20}, // atdf, avr-gcc 12.2.0
+  {"ATA5700M322",      199,  F_AVR8, {0x1E, 0x95, 0x67}, 0x08000, 0x08000, 0x040,  0,      0,       0, 0x0880, 16, 0x0200, 0x0400,  1,  1,  51}, // atdf
+  {"ATA5702M322",      200,  F_AVR8, {0x1E, 0x95, 0x69}, 0x08000, 0x08000, 0x040,  0,      0,       0, 0x0880, 16, 0x0200, 0x0400,  1,  1,  51}, // atdf, avr-gcc 12.2.0
+  {"ATA5781",          201,  F_AVR8, {0x1E, 0x95, 0x64},      -1,      -1,    -1,  0,      0,       0, 0x0400, 16, 0x0200, 0x0400,  1,  1,  42}, // atdf
+  {"ATA5782",          202,  F_AVR8, {0x1E, 0x95, 0x65}, 0x08000, 0x05000, 0x040,  1, 0x5000,       0, 0x0400, 16, 0x0200, 0x0400,  1,  1,  42}, // atdf, avr-gcc 12.2.0
+  {"ATA5783",          203,  F_AVR8, {0x1E, 0x95, 0x66},      -1,      -1,    -1,  0,      0,       0, 0x0400, 16, 0x0200, 0x0400,  1,  1,  42}, // atdf
+  {"ATA5787",          204,  F_AVR8, {0x1E, 0x94, 0x6C}, 0x08000, 0x05200, 0x040,  0,      0,       0, 0x0400, 16, 0x0200, 0x0800,  1,  1,  44}, // atdf
+  {"ATA5790",          205,  F_AVR8, {0x1E, 0x94, 0x61},       0, 0x04000, 0x080,  1, 0x0800,       0, 0x0800, 16, 0x0100, 0x0200,  1,  1,  30}, // atdf, avr-gcc 12.2.0
+  {"ATA5790N",         206,  F_AVR8, {0x1E, 0x94, 0x62},       0, 0x04000, 0x080,  1, 0x0800,       0, 0x0800, 16, 0x0100, 0x0200,  1,  1,  31}, // atdf, avr-gcc 12.2.0
+  {"ATA5791",          207,  F_AVR8, {0x1E, 0x94, 0x62},       0, 0x04000, 0x080,  1, 0x0800,       0, 0x0800, 16, 0x0100, 0x0200,  1,  1,  31}, // atdf, avr-gcc 7.3.0
+  {"ATA5795",          208,  F_AVR8, {0x1E, 0x93, 0x61},       0, 0x02000, 0x040,  1, 0x0800,       0, 0x0800, 16, 0x0100, 0x0200,  1,  1,  23}, // atdf, avr-gcc 12.2.0
+  {"ATA5831",          209,  F_AVR8, {0x1E, 0x95, 0x61}, 0x08000, 0x05000, 0x040,  1, 0x5000,       0, 0x0400, 16, 0x0200, 0x0400,  1,  1,  42}, // atdf, avr-gcc 12.2.0
+  {"ATA5832",          210,  F_AVR8, {0x1E, 0x95, 0x62},      -1,      -1,    -1,  0,      0,       0, 0x0400, 16, 0x0200, 0x0400,  1,  1,  42}, // atdf
+  {"ATA5833",          211,  F_AVR8, {0x1E, 0x95, 0x63},      -1,      -1,    -1,  0,      0,       0, 0x0400, 16, 0x0200, 0x0400,  1,  1,  42}, // atdf
+  {"ATA5835",          212,  F_AVR8, {0x1E, 0x94, 0x6B}, 0x08000, 0x05200, 0x040,  0,      0,       0, 0x0400, 16, 0x0200, 0x0800,  1,  1,  44}, // atdf
+  {"ATA6285",          213,  F_AVR8, {0x1E, 0x93, 0x82},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0140,  4, 0x0100, 0x0200,  2,  1,  27}, // atdf, avr-gcc 12.2.0
+  {"ATA6286",          214,  F_AVR8, {0x1E, 0x93, 0x82},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0140,  4, 0x0100, 0x0200,  2,  1,  27}, // atdf, avr-gcc 12.2.0
+  {"ATA6289",          215,  F_AVR8, {0x1E, 0x93, 0x82},       0, 0x02000, 0x040,  4, 0x0100,      -1,     -1, -1, 0x0100, 0x0200,  2,  1,  27}, // avr-gcc 12.2.0, boot size (manual)
+  {"ATA6612C",         216,  F_AVR8, {0x1E, 0x93, 0x0A},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  26}, // atdf, avr-gcc 12.2.0
+  {"ATA6613C",         217,  F_AVR8, {0x1E, 0x94, 0x06},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  26}, // atdf, avr-gcc 12.2.0
+  {"ATA6614Q",         218,  F_AVR8, {0x1E, 0x95, 0x0F},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  26}, // atdf, avr-gcc 12.2.0
+  {"ATA6616C",         219,  F_AVR8, {0x1E, 0x93, 0x87},       0, 0x02000, 0x080,  0,      0,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  20}, // atdf, avr-gcc 12.2.0
+  {"ATA6617C",         220,  F_AVR8, {0x1E, 0x94, 0x87},       0, 0x04000, 0x080,  0,      0,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  20}, // atdf, avr-gcc 12.2.0
+  {"ATA8210",          221,  F_AVR8, {0x1E, 0x95, 0x65}, 0x08000, 0x05000, 0x040,  1, 0x5000,       0, 0x0400, 16, 0x0200, 0x0400,  1,  1,  42}, // atdf, avr-gcc 7.3.0
+  {"ATA8215",          222,  F_AVR8, {0x1E, 0x95, 0x64},      -1,      -1,    -1,  0,      0,       0, 0x0400, 16, 0x0200, 0x0400,  1,  1,  42}, // atdf
+  {"ATA8510",          223,  F_AVR8, {0x1E, 0x95, 0x61}, 0x08000, 0x05000, 0x040,  1, 0x5000,       0, 0x0400, 16, 0x0200, 0x0400,  1,  1,  42}, // atdf, avr-gcc 7.3.0
+  {"ATA8515",          224,  F_AVR8, {0x1E, 0x95, 0x63},      -1,      -1,    -1,  0,      0,       0, 0x0400, 16, 0x0200, 0x0400,  1,  1,  42}, // atdf
+  {"ATA664251",        225,  F_AVR8, {0x1E, 0x94, 0x87},       0, 0x04000, 0x080,  0,      0,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  20}, // atdf, avr-gcc 12.2.0
+  {"M3000",            226,  F_AVR8, {0xff,   -1,   -1},       0, 0x10000,    -1, -1,     -1,      -1,     -1, -1, 0x1000, 0x1000, -1, -1,   0}, // avr-gcc 12.2.0
+  {"LGT8F88P",         227,  F_AVR8, {0x1E, 0x93, 0x0F},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  26}, // avrdude, from ATmega88
+  {"LGT8F168P",        228,  F_AVR8, {0x1E, 0x94, 0x0B},       0, 0x04000, 0x080,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  26}, // avrdude, from ATmega168P
+  {"LGT8F328P",        229,  F_AVR8, {0x1E, 0x95, 0x0F},       0, 0x08000, 0x080,  4, 0x0200,       0, 0x0400,  4, 0x0100, 0x0800,  3,  1,  26}, // avrdude, from ATmega328P
+
+  {"ATxmega8E5",       230, F_XMEGA, {0x1E, 0x93, 0x41},       0, 0x02800, 0x080,  1, 0x0800,       0, 0x0200, 32, 0x2000, 0x0400,  7,  1,  43}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega16A4",      231, F_XMEGA, {0x1E, 0x94, 0x41},       0, 0x05000, 0x100,  1, 0x1000,       0, 0x0400, 32, 0x2000, 0x0800,  6,  1,  94}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega16A4U",     232, F_XMEGA, {0x1E, 0x94, 0x41},       0, 0x05000, 0x100,  1, 0x1000,       0, 0x0400, 32, 0x2000, 0x0800,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega16C4",      233, F_XMEGA, {0x1E, 0x94, 0x43},       0, 0x05000, 0x100,  1, 0x1000,       0, 0x0400, 32, 0x2000, 0x0800,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega16D4",      234, F_XMEGA, {0x1E, 0x94, 0x42},       0, 0x05000, 0x100,  1, 0x1000,       0, 0x0400, 32, 0x2000, 0x0800,  6,  1,  91}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega16E5",      235, F_XMEGA, {0x1E, 0x94, 0x45},       0, 0x05000, 0x080,  1, 0x1000,       0, 0x0200, 32, 0x2000, 0x0800,  7,  1,  43}, // atdf, avr-gcc 7.3.0, avrdude
+  {"ATxmega32C3",      236, F_XMEGA, {0x1E, 0x95, 0x49},       0, 0x09000, 0x100,  1, 0x1000,       0, 0x0400, 32, 0x2000, 0x1000,  6,  1, 127}, // atdf, avr-gcc 12.2.0
+  {"ATxmega32D3",      237, F_XMEGA, {0x1E, 0x95, 0x4A},       0, 0x09000, 0x100,  1, 0x1000,       0, 0x0400, 32, 0x2000, 0x1000,  6,  1, 114}, // atdf, avr-gcc 12.2.0
+  {"ATxmega32A4",      238, F_XMEGA, {0x1E, 0x95, 0x41},       0, 0x09000, 0x100,  1, 0x1000,       0, 0x0400, 32, 0x2000, 0x1000,  6,  1,  94}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega32A4U",     239, F_XMEGA, {0x1E, 0x95, 0x41},       0, 0x09000, 0x100,  1, 0x1000,       0, 0x0400, 32, 0x2000, 0x1000,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega32C4",      240, F_XMEGA, {0x1E, 0x95, 0x44},       0, 0x09000, 0x100,  1, 0x1000,       0, 0x0400, 32, 0x2000, 0x1000,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega32D4",      241, F_XMEGA, {0x1E, 0x95, 0x42},       0, 0x09000, 0x100,  1, 0x1000,       0, 0x0400, 32, 0x2000, 0x1000,  6,  1,  91}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega32E5",      242, F_XMEGA, {0x1E, 0x95, 0x4C},       0, 0x09000, 0x080,  1, 0x1000,       0, 0x0400, 32, 0x2000, 0x1000,  7,  1,  43}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega64A1",      243, F_XMEGA, {0x1E, 0x96, 0x4E},       0, 0x11000, 0x100,  1, 0x1000,       0, 0x0800, 32, 0x2000, 0x1000,  6,  1, 125}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega64A1U",     244, F_XMEGA, {0x1E, 0x96, 0x4E},       0, 0x11000, 0x100,  1, 0x1000,       0, 0x0800, 32, 0x2000, 0x1000,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega64B1",      245, F_XMEGA, {0x1E, 0x96, 0x52},       0, 0x11000, 0x100,  1, 0x1000,       0, 0x0800, 32, 0x2000, 0x1000,  6,  1,  81}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega64A3",      246, F_XMEGA, {0x1E, 0x96, 0x42},       0, 0x11000, 0x100,  1, 0x1000,       0, 0x0800, 32, 0x2000, 0x1000,  6,  1, 122}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega64A3U",     247, F_XMEGA, {0x1E, 0x96, 0x42},       0, 0x11000, 0x100,  1, 0x1000,       0, 0x0800, 32, 0x2000, 0x1000,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega64B3",      248, F_XMEGA, {0x1E, 0x96, 0x51},       0, 0x11000, 0x100,  1, 0x1000,       0, 0x0800, 32, 0x2000, 0x1000,  6,  1,  54}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega64C3",      249, F_XMEGA, {0x1E, 0x96, 0x49},       0, 0x11000, 0x100,  1, 0x1000,       0, 0x0800, 32, 0x2000, 0x1000,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega64D3",      250, F_XMEGA, {0x1E, 0x96, 0x4A},       0, 0x11000, 0x100,  1, 0x1000,       0, 0x0800, 32, 0x2000, 0x1000,  6,  1, 114}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega64A4",      251, F_XMEGA, {0x1E, 0x96, 0x46},       0, 0x11000, 0x100, -1,     -1,       0, 0x0800, 32,     -1,     -1, -1, -1,   0}, // avrdude
+  {"ATxmega64A4U",     252, F_XMEGA, {0x1E, 0x96, 0x46},       0, 0x11000, 0x100,  1, 0x1000,       0, 0x0800, 32, 0x2000, 0x1000,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega64D4",      253, F_XMEGA, {0x1E, 0x96, 0x47},       0, 0x11000, 0x100,  1, 0x1000,       0, 0x0800, 32, 0x2000, 0x1000,  6,  1,  91}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega128A1",     254, F_XMEGA, {0x1E, 0x97, 0x4C},       0, 0x22000, 0x200,  1, 0x2000,       0, 0x0800, 32, 0x2000, 0x2000,  6,  1, 125}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega128A1revD", 255, F_XMEGA, {0x1E, 0x97, 0x41},       0, 0x22000, 0x200, -1,     -1,       0, 0x0800, 32,     -1,     -1, -1, -1,   0}, // avrdude
+  {"ATxmega128A1U",    256, F_XMEGA, {0x1E, 0x97, 0x4C},       0, 0x22000, 0x200,  1, 0x2000,       0, 0x0800, 32, 0x2000, 0x2000,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega128B1",     257, F_XMEGA, {0x1E, 0x97, 0x4D},       0, 0x22000, 0x100,  1, 0x2000,       0, 0x0800, 32, 0x2000, 0x2000,  6,  1,  81}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega128A3",     258, F_XMEGA, {0x1E, 0x97, 0x42},       0, 0x22000, 0x200,  1, 0x2000,       0, 0x0800, 32, 0x2000, 0x2000,  6,  1, 122}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega128A3U",    259, F_XMEGA, {0x1E, 0x97, 0x42},       0, 0x22000, 0x200,  1, 0x2000,       0, 0x0800, 32, 0x2000, 0x2000,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega128B3",     260, F_XMEGA, {0x1E, 0x97, 0x4B},       0, 0x22000, 0x100,  1, 0x2000,       0, 0x0800, 32, 0x2000, 0x2000,  6,  1,  54}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega128C3",     261, F_XMEGA, {0x1E, 0x97, 0x52},       0, 0x22000, 0x200,  1, 0x2000,       0, 0x0800, 32, 0x2000, 0x2000,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega128D3",     262, F_XMEGA, {0x1E, 0x97, 0x48},       0, 0x22000, 0x200,  1, 0x2000,       0, 0x0800, 32, 0x2000, 0x2000,  6,  1, 114}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega128A4",     263, F_XMEGA, {0x1E, 0x97, 0x46},       0, 0x22000, 0x200, -1,     -1,       0, 0x0800, 32,     -1,     -1, -1, -1,   0}, // avrdude
+  {"ATxmega128A4U",    264, F_XMEGA, {0x1E, 0x97, 0x46},       0, 0x22000, 0x100,  1, 0x2000,       0, 0x0800, 32, 0x2000, 0x2000,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega128D4",     265, F_XMEGA, {0x1E, 0x97, 0x47},       0, 0x22000, 0x100,  1, 0x2000,       0, 0x0800, 32, 0x2000, 0x2000,  6,  1,  91}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega192A1",     266, F_XMEGA, {0x1E, 0x97, 0x4E},       0, 0x32000, 0x200, -1,     -1,       0, 0x0800, 32,     -1,     -1, -1, -1,   0}, // avrdude
+  {"ATxmega192A3",     267, F_XMEGA, {0x1E, 0x97, 0x44},       0, 0x32000, 0x200,  1, 0x2000,       0, 0x0800, 32, 0x2000, 0x4000,  6,  1, 122}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega192A3U",    268, F_XMEGA, {0x1E, 0x97, 0x44},       0, 0x32000, 0x200,  1, 0x2000,       0, 0x0800, 32, 0x2000, 0x4000,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega192C3",     269, F_XMEGA, {0x1E, 0x97, 0x51},       0, 0x32000, 0x200,  1, 0x2000,       0, 0x0800, 32, 0x2000, 0x4000,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega192D3",     270, F_XMEGA, {0x1E, 0x97, 0x49},       0, 0x32000, 0x200,  1, 0x2000,       0, 0x0800, 32, 0x2000, 0x4000,  6,  1, 114}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega256A1",     271, F_XMEGA, {0x1E, 0x98, 0x46},       0, 0x42000, 0x200, -1,     -1,       0, 0x1000, 32,     -1,     -1, -1, -1,   0}, // avrdude
+  {"ATxmega256A3",     272, F_XMEGA, {0x1E, 0x98, 0x42},       0, 0x42000, 0x200,  1, 0x2000,       0, 0x1000, 32, 0x2000, 0x4000,  6,  1, 122}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega256A3B",    273, F_XMEGA, {0x1E, 0x98, 0x43},       0, 0x42000, 0x200,  1, 0x2000,       0, 0x1000, 32, 0x2000, 0x4000,  6,  1, 122}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega256A3BU",   274, F_XMEGA, {0x1E, 0x98, 0x43},       0, 0x42000, 0x200,  1, 0x2000,       0, 0x1000, 32, 0x2000, 0x4000,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega256A3U",    275, F_XMEGA, {0x1E, 0x98, 0x42},       0, 0x42000, 0x200,  1, 0x2000,       0, 0x1000, 32, 0x2000, 0x4000,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega256C3",     276, F_XMEGA, {0x1E, 0x98, 0x46},       0, 0x42000, 0x200,  1, 0x2000,       0, 0x1000, 32, 0x2000, 0x4000,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega256D3",     277, F_XMEGA, {0x1E, 0x98, 0x44},       0, 0x42000, 0x200,  1, 0x2000,       0, 0x1000, 32, 0x2000, 0x4000,  6,  1, 114}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega384C3",     278, F_XMEGA, {0x1E, 0x98, 0x45},       0, 0x62000, 0x200,  1, 0x2000,       0, 0x1000, 32, 0x2000, 0x8000,  6,  1, 127}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATxmega384D3",     279, F_XMEGA, {0x1E, 0x98, 0x47},       0, 0x62000, 0x200,  1, 0x2000,       0, 0x1000, 32, 0x2000, 0x8000,  6,  1, 114}, // atdf, avr-gcc 12.2.0, avrdude
+
+  {"ATtiny202",        280, F_AVR8X, {0x1E, 0x91, 0x23},       0, 0x00800, 0x040,  1,      0, 0x01400, 0x0040, 32, 0x3f80, 0x0080, 10,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny204",        281, F_AVR8X, {0x1E, 0x91, 0x22},       0, 0x00800, 0x040,  1,      0, 0x01400, 0x0040, 32, 0x3f80, 0x0080, 10,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny212",        282, F_AVR8X, {0x1E, 0x91, 0x21},       0, 0x00800, 0x040,  1,      0, 0x01400, 0x0040, 32, 0x3f80, 0x0080, 10,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny214",        283, F_AVR8X, {0x1E, 0x91, 0x20},       0, 0x00800, 0x040,  1,      0, 0x01400, 0x0040, 32, 0x3f80, 0x0080, 10,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny402",        284, F_AVR8X, {0x1E, 0x92, 0x27},       0, 0x01000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3f00, 0x0100, 10,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny404",        285, F_AVR8X, {0x1E, 0x92, 0x26},       0, 0x01000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3f00, 0x0100, 10,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny406",        286, F_AVR8X, {0x1E, 0x92, 0x25},       0, 0x01000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3f00, 0x0100, 10,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny412",        287, F_AVR8X, {0x1E, 0x92, 0x23},       0, 0x01000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3f00, 0x0100, 10,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny414",        288, F_AVR8X, {0x1E, 0x92, 0x22},       0, 0x01000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3f00, 0x0100, 10,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny416",        289, F_AVR8X, {0x1E, 0x92, 0x21},       0, 0x01000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3f00, 0x0100, 10,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny416auto",    290, F_AVR8X, {0x1E, 0x92, 0x28},       0, 0x01000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3f00, 0x0100, 10,  1,  26}, // atdf
+  {"ATtiny417",        291, F_AVR8X, {0x1E, 0x92, 0x20},       0, 0x01000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3f00, 0x0100, 10,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny424",        292, F_AVR8X, {0x1E, 0x92, 0x2C},       0, 0x01000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10,  1,  30}, // atdf, avrdude
+  {"ATtiny426",        293, F_AVR8X, {0x1E, 0x92, 0x2B},       0, 0x01000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10,  1,  30}, // atdf, avrdude
+  {"ATtiny427",        294, F_AVR8X, {0x1E, 0x92, 0x2A},       0, 0x01000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10,  1,  30}, // atdf, avrdude
+  {"ATtiny804",        295, F_AVR8X, {0x1E, 0x93, 0x25},       0, 0x02000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny806",        296, F_AVR8X, {0x1E, 0x93, 0x24},       0, 0x02000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny807",        297, F_AVR8X, {0x1E, 0x93, 0x23},       0, 0x02000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny814",        298, F_AVR8X, {0x1E, 0x93, 0x22},       0, 0x02000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny816",        299, F_AVR8X, {0x1E, 0x93, 0x21},       0, 0x02000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny817",        300, F_AVR8X, {0x1E, 0x93, 0x20},       0, 0x02000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3e00, 0x0200, 10,  1,  26}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny824",        301, F_AVR8X, {0x1E, 0x93, 0x29},       0, 0x02000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3c00, 0x0400, 10,  1,  30}, // atdf, avrdude
+  {"ATtiny826",        302, F_AVR8X, {0x1E, 0x93, 0x28},       0, 0x02000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3c00, 0x0400, 10,  1,  30}, // atdf, avrdude
+  {"ATtiny827",        303, F_AVR8X, {0x1E, 0x93, 0x27},       0, 0x02000, 0x040,  1,      0, 0x01400, 0x0080, 32, 0x3c00, 0x0400, 10,  1,  30}, // atdf, avrdude
+  {"ATtiny1604",       304, F_AVR8X, {0x1E, 0x94, 0x25},       0, 0x04000, 0x040,  1,      0, 0x01400, 0x0100, 32, 0x3c00, 0x0400, 10,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny1606",       305, F_AVR8X, {0x1E, 0x94, 0x24},       0, 0x04000, 0x040,  1,      0, 0x01400, 0x0100, 32, 0x3c00, 0x0400, 10,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny1607",       306, F_AVR8X, {0x1E, 0x94, 0x23},       0, 0x04000, 0x040,  1,      0, 0x01400, 0x0100, 32, 0x3c00, 0x0400, 10,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny1614",       307, F_AVR8X, {0x1E, 0x94, 0x22},       0, 0x04000, 0x040,  1,      0, 0x01400, 0x0100, 32, 0x3800, 0x0800, 10,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny1616",       308, F_AVR8X, {0x1E, 0x94, 0x21},       0, 0x04000, 0x040,  1,      0, 0x01400, 0x0100, 32, 0x3800, 0x0800, 10,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny1617",       309, F_AVR8X, {0x1E, 0x94, 0x20},       0, 0x04000, 0x040,  1,      0, 0x01400, 0x0100, 32, 0x3800, 0x0800, 10,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny1624",       310, F_AVR8X, {0x1E, 0x94, 0x2A},       0, 0x04000, 0x040,  1,      0, 0x01400, 0x0100, 32, 0x3800, 0x0800, 10,  1,  30}, // atdf, avrdude
+  {"ATtiny1626",       311, F_AVR8X, {0x1E, 0x94, 0x29},       0, 0x04000, 0x040,  1,      0, 0x01400, 0x0100, 32, 0x3800, 0x0800, 10,  1,  30}, // atdf, avrdude
+  {"ATtiny1627",       312, F_AVR8X, {0x1E, 0x94, 0x28},       0, 0x04000, 0x040,  1,      0, 0x01400, 0x0100, 32, 0x3800, 0x0800, 10,  1,  30}, // atdf, avrdude
+  {"ATtiny3214",       313, F_AVR8X, {0x1E, 0x95, 0x20},       0, 0x08000, 0x080,  1,      0, 0x01400, 0x0100, 64, 0x3800, 0x0800, 10,  1,  31}, // avr-gcc 12.2.0
+  {"ATtiny3216",       314, F_AVR8X, {0x1E, 0x95, 0x21},       0, 0x08000, 0x080,  1,      0, 0x01400, 0x0100, 64, 0x3800, 0x0800, 10,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny3217",       315, F_AVR8X, {0x1E, 0x95, 0x22},       0, 0x08000, 0x080,  1,      0, 0x01400, 0x0100, 64, 0x3800, 0x0800, 10,  1,  31}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATtiny3224",       316, F_AVR8X, {0x1E, 0x95, 0x28},       0, 0x08000, 0x080,  1,      0, 0x01400, 0x0100, 64, 0x3400, 0x0c00, 10,  1,  30}, // atdf, avrdude
+  {"ATtiny3226",       317, F_AVR8X, {0x1E, 0x95, 0x27},       0, 0x08000, 0x080,  1,      0, 0x01400, 0x0100, 64, 0x3400, 0x0c00, 10,  1,  30}, // atdf, avrdude
+  {"ATtiny3227",       318, F_AVR8X, {0x1E, 0x95, 0x26},       0, 0x08000, 0x080,  1,      0, 0x01400, 0x0100, 64, 0x3400, 0x0c00, 10,  1,  30}, // atdf, avrdude
+  {"ATmega808",        319, F_AVR8X, {0x1E, 0x93, 0x26},       0, 0x02000, 0x040,  1,      0, 0x01400, 0x0100, 32, 0x3c00, 0x0400, 10,  1,  36}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega809",        320, F_AVR8X, {0x1E, 0x93, 0x2A},       0, 0x02000, 0x040,  1,      0, 0x01400, 0x0100, 32, 0x3c00, 0x0400, 10,  1,  40}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega1608",       321, F_AVR8X, {0x1E, 0x94, 0x27},       0, 0x04000, 0x040,  1,      0, 0x01400, 0x0100, 32, 0x3800, 0x0800, 10,  1,  36}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega1609",       322, F_AVR8X, {0x1E, 0x94, 0x26},       0, 0x04000, 0x040,  1,      0, 0x01400, 0x0100, 32, 0x3800, 0x0800, 10,  1,  40}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega3208",       323, F_AVR8X, {0x1E, 0x95, 0x30},       0, 0x08000, 0x080,  1,      0, 0x01400, 0x0100, 64, 0x3000, 0x1000, 10,  1,  36}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega3209",       324, F_AVR8X, {0x1E, 0x95, 0x31},       0, 0x08000, 0x080,  1,      0, 0x01400, 0x0100, 64, 0x3000, 0x1000, 10,  1,  40}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega4808",       325, F_AVR8X, {0x1E, 0x96, 0x50},       0, 0x0c000, 0x080,  1,      0, 0x01400, 0x0100, 64, 0x2800, 0x1800, 10,  1,  36}, // atdf, avr-gcc 12.2.0, avrdude
+  {"ATmega4809",       326, F_AVR8X, {0x1E, 0x96, 0x51},       0, 0x0c000, 0x080,  1,      0, 0x01400, 0x0100, 64, 0x2800, 0x1800, 10,  1,  40}, // atdf, avr-gcc 12.2.0, avrdude
+  {"AVR8EA28",         327, F_AVR8X, {0x1E, 0x93, 0x2C},       0, 0x02000, 0x040,  1,      0, 0x01400, 0x0200,  8,     -1,     -1, -1, -1,   0}, // avrdude
+  {"AVR8EA32",         328, F_AVR8X, {0x1E, 0x93, 0x2B},       0, 0x02000, 0x040,  1,      0, 0x01400, 0x0200,  8,     -1,     -1, -1, -1,   0}, // avrdude
+  {"AVR16DD14",        329, F_AVR8X, {0x1E, 0x94, 0x34},       0, 0x04000, 0x200,  1,      0, 0x01400, 0x0100,  1, 0x7800, 0x0800, 16,  4,  36}, // atdf, avrdude
+  {"AVR16DD20",        330, F_AVR8X, {0x1E, 0x94, 0x33},       0, 0x04000, 0x200,  1,      0, 0x01400, 0x0100,  1, 0x7800, 0x0800, 16,  4,  36}, // atdf, avrdude
+  {"AVR16DD28",        331, F_AVR8X, {0x1E, 0x94, 0x32},       0, 0x04000, 0x200,  1,      0, 0x01400, 0x0100,  1, 0x7800, 0x0800, 16,  4,  36}, // atdf, avrdude
+  {"AVR16EA28",        332, F_AVR8X, {0x1E, 0x94, 0x37},       0, 0x04000, 0x040,  1,      0, 0x01400, 0x0200,  8,     -1,     -1, -1, -1,   0}, // avrdude
+  {"AVR16DD32",        333, F_AVR8X, {0x1E, 0x94, 0x31},       0, 0x04000, 0x200,  1,      0, 0x01400, 0x0100,  1, 0x7800, 0x0800, 16,  4,  36}, // atdf, avrdude
+  {"AVR16EA32",        334, F_AVR8X, {0x1E, 0x94, 0x36},       0, 0x04000, 0x040,  1,      0, 0x01400, 0x0200,  8,     -1,     -1, -1, -1,   0}, // avrdude
+  {"AVR16EA48",        335, F_AVR8X, {0x1E, 0x94, 0x35},       0, 0x04000, 0x040,  1,      0, 0x01400, 0x0200,  8,     -1,     -1, -1, -1,   0}, // avrdude
+  {"AVR32DD14",        336, F_AVR8X, {0x1E, 0x95, 0x3B},       0, 0x08000, 0x200,  1,      0, 0x01400, 0x0100,  1, 0x7000, 0x1000, 16,  4,  36}, // atdf, avrdude
+  {"AVR32DD20",        337, F_AVR8X, {0x1E, 0x95, 0x3A},       0, 0x08000, 0x200,  1,      0, 0x01400, 0x0100,  1, 0x7000, 0x1000, 16,  4,  36}, // atdf, avrdude
+  {"AVR32DA28",        338, F_AVR8X, {0x1E, 0x95, 0x34},       0, 0x08000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x7000, 0x1000, 16,  4,  41}, // atdf, avrdude
+  {"AVR32DB28",        339, F_AVR8X, {0x1E, 0x95, 0x37},       0, 0x08000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x7000, 0x1000, 16,  4,  42}, // atdf, avrdude
+  {"AVR32DD28",        340, F_AVR8X, {0x1E, 0x95, 0x39},       0, 0x08000, 0x200,  1,      0, 0x01400, 0x0100,  1, 0x7000, 0x1000, 16,  4,  36}, // atdf, avrdude
+  {"AVR32EA28",        341, F_AVR8X, {0x1E, 0x95, 0x3E},       0, 0x08000, 0x040,  1,      0, 0x01400, 0x0200,  8,     -1,     -1, -1, -1,   0}, // avrdude
+  {"AVR32DA32",        342, F_AVR8X, {0x1E, 0x95, 0x33},       0, 0x08000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x7000, 0x1000, 16,  4,  44}, // atdf, avrdude
+  {"AVR32DB32",        343, F_AVR8X, {0x1E, 0x95, 0x36},       0, 0x08000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x7000, 0x1000, 16,  4,  44}, // atdf, avrdude
+  {"AVR32DD32",        344, F_AVR8X, {0x1E, 0x95, 0x38},       0, 0x08000, 0x200,  1,      0, 0x01400, 0x0100,  1, 0x7000, 0x1000, 16,  4,  36}, // atdf, avrdude
+  {"AVR32EA32",        345, F_AVR8X, {0x1E, 0x95, 0x3D},       0, 0x08000, 0x040,  1,      0, 0x01400, 0x0200,  8,     -1,     -1, -1, -1,   0}, // avrdude
+  {"AVR32DA48",        346, F_AVR8X, {0x1E, 0x95, 0x32},       0, 0x08000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x7000, 0x1000, 16,  4,  58}, // atdf, avrdude
+  {"AVR32DB48",        347, F_AVR8X, {0x1E, 0x95, 0x35},       0, 0x08000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x7000, 0x1000, 16,  4,  61}, // atdf, avrdude
+  {"AVR32EA48",        348, F_AVR8X, {0x1E, 0x95, 0x3C},       0, 0x08000, 0x040,  1,      0, 0x01400, 0x0200,  8,     -1,     -1, -1, -1,   0}, // avrdude
+  {"AVR64DD14",        349, F_AVR8X, {0x1E, 0x96, 0x1D},       0, 0x10000, 0x200,  1,      0, 0x01400, 0x0100,  1, 0x6000, 0x2000, 16,  4,  36}, // atdf, avrdude
+  {"AVR64DD20",        350, F_AVR8X, {0x1E, 0x96, 0x1C},       0, 0x10000, 0x200,  1,      0, 0x01400, 0x0100,  1, 0x6000, 0x2000, 16,  4,  36}, // atdf, avrdude
+  {"AVR64DA28",        351, F_AVR8X, {0x1E, 0x96, 0x15},       0, 0x10000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x6000, 0x2000, 16,  4,  41}, // atdf, avrdude
+  {"AVR64DB28",        352, F_AVR8X, {0x1E, 0x96, 0x19},       0, 0x10000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x6000, 0x2000, 16,  4,  42}, // atdf, avrdude
+  {"AVR64DD28",        353, F_AVR8X, {0x1E, 0x96, 0x1B},       0, 0x10000, 0x200,  1,      0, 0x01400, 0x0100,  1, 0x6000, 0x2000, 16,  4,  36}, // atdf, avrdude
+  {"AVR64EA28",        354, F_AVR8X, {0x1E, 0x96, 0x20},       0, 0x10000, 0x080,  1,      0, 0x01400, 0x0200,  8, 0x6800, 0x1800, 16,  4,  37}, // atdf, avrdude
+  {"AVR64DA32",        355, F_AVR8X, {0x1E, 0x96, 0x14},       0, 0x10000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x6000, 0x2000, 16,  4,  44}, // atdf, avrdude
+  {"AVR64DB32",        356, F_AVR8X, {0x1E, 0x96, 0x18},       0, 0x10000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x6000, 0x2000, 16,  4,  44}, // atdf, avrdude
+  {"AVR64DD32",        357, F_AVR8X, {0x1E, 0x96, 0x1A},       0, 0x10000, 0x200,  1,      0, 0x01400, 0x0100,  1, 0x6000, 0x2000, 16,  4,  36}, // atdf, avrdude
+  {"AVR64EA32",        358, F_AVR8X, {0x1E, 0x96, 0x1F},       0, 0x10000, 0x080,  1,      0, 0x01400, 0x0200,  8, 0x6800, 0x1800, 16,  4,  37}, // atdf, avrdude
+  {"AVR64DA48",        359, F_AVR8X, {0x1E, 0x96, 0x13},       0, 0x10000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x6000, 0x2000, 16,  4,  58}, // atdf, avrdude
+  {"AVR64DB48",        360, F_AVR8X, {0x1E, 0x96, 0x17},       0, 0x10000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x6000, 0x2000, 16,  4,  61}, // atdf, avrdude
+  {"AVR64EA48",        361, F_AVR8X, {0x1E, 0x96, 0x1E},       0, 0x10000, 0x080,  1,      0, 0x01400, 0x0200,  8, 0x6800, 0x1800, 16,  4,  45}, // atdf, avrdude
+  {"AVR64DA64",        362, F_AVR8X, {0x1E, 0x96, 0x12},       0, 0x10000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x6000, 0x2000, 16,  4,  64}, // atdf, avrdude
+  {"AVR64DB64",        363, F_AVR8X, {0x1E, 0x96, 0x16},       0, 0x10000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x6000, 0x2000, 16,  4,  65}, // atdf, avrdude
+  {"AVR128DA28",       364, F_AVR8X, {0x1E, 0x97, 0x0A},       0, 0x20000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x4000, 0x4000, 16,  4,  41}, // atdf, avrdude
+  {"AVR128DB28",       365, F_AVR8X, {0x1E, 0x97, 0x0E},       0, 0x20000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x4000, 0x4000, 16,  4,  42}, // atdf, avrdude
+  {"AVR128DA32",       366, F_AVR8X, {0x1E, 0x97, 0x09},       0, 0x20000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x4000, 0x4000, 16,  4,  44}, // atdf, avrdude
+  {"AVR128DB32",       367, F_AVR8X, {0x1E, 0x97, 0x0D},       0, 0x20000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x4000, 0x4000, 16,  4,  44}, // atdf, avrdude
+  {"AVR128DA48",       368, F_AVR8X, {0x1E, 0x97, 0x08},       0, 0x20000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x4000, 0x4000, 16,  4,  58}, // atdf, avrdude
+  {"AVR128DB48",       369, F_AVR8X, {0x1E, 0x97, 0x0C},       0, 0x20000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x4000, 0x4000, 16,  4,  61}, // atdf, avrdude
+  {"AVR128DA64",       370, F_AVR8X, {0x1E, 0x97, 0x07},       0, 0x20000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x4000, 0x4000, 16,  4,  64}, // atdf, avrdude
+  {"AVR128DB64",       371, F_AVR8X, {0x1E, 0x97, 0x0B},       0, 0x20000, 0x200,  1,      0, 0x01400, 0x0200,  1, 0x4000, 0x4000, 16,  4,  65}, // atdf, avrdude
+};
+
+const size_t avr_isp_chip_arr_size = COUNT_OF(avr_isp_chip_arr);

+ 33 - 0
avr_isp_programmer/lib/driver/avr_isp_chip_arr.h

@@ -0,0 +1,33 @@
+#pragma once
+
+#include <furi_hal.h>
+
+#define F_AVR8L 1 // TPI programming, ATtiny(4|5|9|10|20|40|102|104)
+#define F_AVR8 2 // ISP programming with SPI, "classic" AVRs
+#define F_XMEGA 4 // PDI programming, ATxmega family
+#define F_AVR8X 8 // UPDI programming, newer 8-bit MCUs
+
+struct AvrIspChipArr { // Value of -1 typically means unknown
+    const char* name; // Name of part
+    uint16_t mcuid; // ID of MCU in 0..2039
+    uint8_t avrarch; // F_AVR8L, F_AVR8, F_XMEGA or F_AVR8X
+    uint8_t sigs[3]; // Signature bytes
+    int32_t flashoffset; // Flash offset
+    int32_t flashsize; // Flash size
+    int16_t pagesize; // Flash page size
+    int8_t nboots; // Number of supported boot sectors
+    int16_t bootsize; // Size of (smallest) boot sector
+    int32_t eepromoffset; // EEPROM offset
+    int32_t eepromsize; // EEPROM size
+    int32_t eeprompagesize; // EEPROM page size
+    int32_t sramstart; // SRAM offset
+    int32_t sramsize; // SRAM size
+    int8_t nfuses; // Number of fuse bytes
+    int8_t nlocks; // Number of lock bytes
+    uint8_t ninterrupts; // Number of vectors in interrupt vector table
+};
+
+typedef struct AvrIspChipArr AvrIspChipArr;
+
+extern const AvrIspChipArr avr_isp_chip_arr[];
+extern const size_t avr_isp_chip_arr_size;

+ 639 - 0
avr_isp_programmer/lib/driver/avr_isp_prog.c

@@ -0,0 +1,639 @@
+#include "avr_isp_prog.h"
+#include "avr_isp_prog_cmd.h"
+
+#include <furi.h>
+
+#define AVR_ISP_PROG_TX_RX_BUF_SIZE 320
+#define TAG "AvrIspProg"
+
+struct AvrIspProgSignature {
+    uint8_t vendor;
+    uint8_t part_family;
+    uint8_t part_number;
+};
+
+typedef struct AvrIspProgSignature AvrIspProgSignature;
+
+struct AvrIspProgCfgDevice {
+    uint8_t devicecode;
+    uint8_t revision;
+    uint8_t progtype;
+    uint8_t parmode;
+    uint8_t polling;
+    uint8_t selftimed;
+    uint8_t lockbytes;
+    uint8_t fusebytes;
+    uint8_t flashpoll;
+    uint16_t eeprompoll;
+    uint16_t pagesize;
+    uint16_t eepromsize;
+    uint32_t flashsize;
+};
+
+typedef struct AvrIspProgCfgDevice AvrIspProgCfgDevice;
+
+struct AvrIspProg {
+    AvrIspSpiSw* spi;
+    AvrIspProgCfgDevice* cfg;
+    FuriStreamBuffer* stream_rx;
+    FuriStreamBuffer* stream_tx;
+
+    uint16_t error;
+    uint16_t addr;
+    bool pmode;
+    bool exit;
+    bool rst_active_high;
+    uint8_t buff[AVR_ISP_PROG_TX_RX_BUF_SIZE];
+
+    AvrIspProgCallback callback;
+    void* context;
+};
+
+static void avr_isp_prog_end_pmode(AvrIspProg* instance);
+
+AvrIspProg* avr_isp_prog_init(void) {
+    AvrIspProg* instance = malloc(sizeof(AvrIspProg));
+    instance->cfg = malloc(sizeof(AvrIspProgCfgDevice));
+    instance->stream_rx =
+        furi_stream_buffer_alloc(sizeof(int8_t) * AVR_ISP_PROG_TX_RX_BUF_SIZE, sizeof(int8_t));
+    instance->stream_tx =
+        furi_stream_buffer_alloc(sizeof(int8_t) * AVR_ISP_PROG_TX_RX_BUF_SIZE, sizeof(int8_t));
+    instance->rst_active_high = false;
+    instance->exit = false;
+    return instance;
+}
+
+void avr_isp_prog_free(AvrIspProg* instance) {
+    furi_assert(instance);
+    if(instance->spi) avr_isp_prog_end_pmode(instance);
+    furi_stream_buffer_free(instance->stream_tx);
+    furi_stream_buffer_free(instance->stream_rx);
+    free(instance->cfg);
+    free(instance);
+}
+
+size_t avr_isp_prog_spaces_rx(AvrIspProg* instance) {
+    return furi_stream_buffer_spaces_available(instance->stream_rx);
+}
+
+bool avr_isp_prog_rx(AvrIspProg* instance, uint8_t* data, size_t len) {
+    furi_assert(instance);
+    furi_assert(data);
+    furi_assert(len != 0);
+    size_t ret = furi_stream_buffer_send(instance->stream_rx, data, sizeof(uint8_t) * len, 0);
+    return ret == sizeof(uint8_t) * len;
+}
+
+size_t avr_isp_prog_tx(AvrIspProg* instance, uint8_t* data, size_t max_len) {
+    furi_assert(instance);
+    return furi_stream_buffer_receive(instance->stream_tx, data, sizeof(int8_t) * max_len, 0);
+}
+
+void avr_isp_prog_exit(AvrIspProg* instance) {
+    furi_assert(instance);
+    instance->exit = true;
+}
+
+void avr_isp_prog_set_tx_callback(AvrIspProg* instance, AvrIspProgCallback callback, void* context) {
+    furi_assert(instance);
+    furi_assert(context);
+    instance->callback = callback;
+    instance->context = context;
+}
+
+static void avr_isp_prog_tx_ch(AvrIspProg* instance, uint8_t data) {
+    furi_assert(instance);
+    furi_stream_buffer_send(instance->stream_tx, &data, sizeof(uint8_t), FuriWaitForever);
+}
+
+static uint8_t avr_isp_prog_getch(AvrIspProg* instance) {
+    furi_assert(instance);
+    uint8_t data[1] = {0};
+    while(furi_stream_buffer_receive(instance->stream_rx, &data, sizeof(int8_t), 30) == 0) {
+        if(instance->exit) break;
+    };
+    return data[0];
+}
+
+static void avr_isp_prog_fill(AvrIspProg* instance, size_t len) {
+    furi_assert(instance);
+    for(size_t x = 0; x < len; x++) {
+        instance->buff[x] = avr_isp_prog_getch(instance);
+    }
+}
+
+static void avr_isp_prog_reset_target(AvrIspProg* instance, bool reset) {
+    furi_assert(instance);
+    avr_isp_spi_sw_res_set(instance->spi, (reset == instance->rst_active_high) ? true : false);
+}
+
+static uint8_t avr_isp_prog_spi_transaction(
+    AvrIspProg* instance,
+    uint8_t cmd,
+    uint8_t addr_hi,
+    uint8_t addr_lo,
+    uint8_t data) {
+    furi_assert(instance);
+
+    avr_isp_spi_sw_txrx(instance->spi, cmd);
+    avr_isp_spi_sw_txrx(instance->spi, addr_hi);
+    avr_isp_spi_sw_txrx(instance->spi, addr_lo);
+    return avr_isp_spi_sw_txrx(instance->spi, data);
+}
+
+static void avr_isp_prog_empty_reply(AvrIspProg* instance) {
+    furi_assert(instance);
+    if(avr_isp_prog_getch(instance) == CRC_EOP) {
+        avr_isp_prog_tx_ch(instance, STK_INSYNC);
+        avr_isp_prog_tx_ch(instance, STK_OK);
+    } else {
+        instance->error++;
+        avr_isp_prog_tx_ch(instance, STK_NOSYNC);
+    }
+}
+
+static void avr_isp_prog_breply(AvrIspProg* instance, uint8_t data) {
+    furi_assert(instance);
+    if(avr_isp_prog_getch(instance) == CRC_EOP) {
+        avr_isp_prog_tx_ch(instance, STK_INSYNC);
+        avr_isp_prog_tx_ch(instance, data);
+        avr_isp_prog_tx_ch(instance, STK_OK);
+    } else {
+        instance->error++;
+        avr_isp_prog_tx_ch(instance, STK_NOSYNC);
+    }
+}
+
+static void avr_isp_prog_get_version(AvrIspProg* instance, uint8_t data) {
+    furi_assert(instance);
+    switch(data) {
+    case STK_HW_VER:
+        avr_isp_prog_breply(instance, AVR_ISP_HWVER);
+        break;
+    case STK_SW_MAJOR:
+        avr_isp_prog_breply(instance, AVR_ISP_SWMAJ);
+        break;
+    case STK_SW_MINOR:
+        avr_isp_prog_breply(instance, AVR_ISP_SWMIN);
+        break;
+    case AVP_ISP_CONNECT_TYPE:
+        avr_isp_prog_breply(instance, AVP_ISP_SERIAL_CONNECT_TYPE);
+        break;
+    default:
+        avr_isp_prog_breply(instance, AVR_ISP_RESP_0);
+    }
+}
+
+static void avr_isp_prog_set_cfg(AvrIspProg* instance) {
+    furi_assert(instance);
+    // call this after reading cfg packet into buff[]
+    instance->cfg->devicecode = instance->buff[0];
+    instance->cfg->revision = instance->buff[1];
+    instance->cfg->progtype = instance->buff[2];
+    instance->cfg->parmode = instance->buff[3];
+    instance->cfg->polling = instance->buff[4];
+    instance->cfg->selftimed = instance->buff[5];
+    instance->cfg->lockbytes = instance->buff[6];
+    instance->cfg->fusebytes = instance->buff[7];
+    instance->cfg->flashpoll = instance->buff[8];
+    // ignore (instance->buff[9] == instance->buff[8]) //FLASH polling value. Same as “flashpoll”
+    instance->cfg->eeprompoll = instance->buff[10] << 8 | instance->buff[11];
+    instance->cfg->pagesize = instance->buff[12] << 8 | instance->buff[13];
+    instance->cfg->eepromsize = instance->buff[14] << 8 | instance->buff[15];
+    instance->cfg->flashsize = instance->buff[16] << 24 | instance->buff[17] << 16 |
+                               instance->buff[18] << 8 | instance->buff[19];
+
+    // avr devices have active low reset, at89sx are active high
+    instance->rst_active_high = (instance->cfg->devicecode >= 0xe0);
+}
+static bool
+    avr_isp_prog_set_pmode(AvrIspProg* instance, uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
+    furi_assert(instance);
+    uint8_t res = 0;
+    avr_isp_spi_sw_txrx(instance->spi, a);
+    avr_isp_spi_sw_txrx(instance->spi, b);
+    res = avr_isp_spi_sw_txrx(instance->spi, c);
+    avr_isp_spi_sw_txrx(instance->spi, d);
+    return res == 0x53;
+}
+
+static void avr_isp_prog_end_pmode(AvrIspProg* instance) {
+    furi_assert(instance);
+    if(instance->pmode) {
+        avr_isp_prog_reset_target(instance, false);
+        // We're about to take the target out of reset
+        // so configure SPI pins as input
+
+        if(instance->spi) avr_isp_spi_sw_free(instance->spi);
+        instance->spi = NULL;
+    }
+
+    instance->pmode = false;
+}
+
+static bool avr_isp_prog_start_pmode(AvrIspProg* instance, AvrIspSpiSwSpeed spi_speed) {
+    furi_assert(instance);
+    // Reset target before driving PIN_SCK or PIN_MOSI
+
+    // SPI.begin() will configure SS as output,
+    // so SPI master mode is selected.
+    // We have defined RESET as pin 10,
+    // which for many arduino's is not the SS pin.
+    // So we have to configure RESET as output here,
+    // (reset_target() first sets the correct level)
+    if(instance->spi) avr_isp_spi_sw_free(instance->spi);
+    instance->spi = avr_isp_spi_sw_init(spi_speed);
+
+    avr_isp_prog_reset_target(instance, true);
+    // See avr datasheets, chapter "SERIAL_PRG Programming Algorithm":
+
+    // Pulse RESET after PIN_SCK is low:
+    avr_isp_spi_sw_sck_set(instance->spi, false);
+
+    // discharge PIN_SCK, value arbitrally chosen
+    furi_delay_ms(20);
+    avr_isp_prog_reset_target(instance, false);
+
+    // Pulse must be minimum 2 target CPU speed cycles
+    // so 100 usec is ok for CPU speeds above 20KHz
+    furi_delay_ms(1);
+
+    avr_isp_prog_reset_target(instance, true);
+
+    // Send the enable programming command:
+    // datasheet: must be > 20 msec
+    furi_delay_ms(50);
+    if(avr_isp_prog_set_pmode(instance, AVR_ISP_SET_PMODE)) {
+        instance->pmode = true;
+        return true;
+    }
+    return false;
+}
+
+static AvrIspProgSignature avr_isp_prog_check_signature(AvrIspProg* instance) {
+    furi_assert(instance);
+    AvrIspProgSignature signature;
+    signature.vendor = avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_VENDOR);
+    signature.part_family = avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_PART_FAMILY);
+    signature.part_number = avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_PART_NUMBER);
+    return signature;
+}
+
+static bool avr_isp_prog_auto_set_spi_speed_start_pmode(AvrIspProg* instance) {
+    AvrIspSpiSwSpeed spi_speed[] = {
+        AvrIspSpiSwSpeed1Mhz,
+        AvrIspSpiSwSpeed400Khz,
+        AvrIspSpiSwSpeed250Khz,
+        AvrIspSpiSwSpeed125Khz,
+        AvrIspSpiSwSpeed60Khz,
+        AvrIspSpiSwSpeed40Khz,
+        AvrIspSpiSwSpeed20Khz,
+        AvrIspSpiSwSpeed10Khz,
+        AvrIspSpiSwSpeed5Khz,
+        AvrIspSpiSwSpeed1Khz,
+    };
+    for(uint8_t i = 0; i < COUNT_OF(spi_speed); i++) {
+        if(avr_isp_prog_start_pmode(instance, spi_speed[i])) {
+            AvrIspProgSignature sig = avr_isp_prog_check_signature(instance);
+            AvrIspProgSignature sig_examination = avr_isp_prog_check_signature(instance); //-V656
+            uint8_t y = 0;
+            while(y < 8) {
+                if(memcmp(
+                       (uint8_t*)&sig, (uint8_t*)&sig_examination, sizeof(AvrIspProgSignature)) !=
+                   0)
+                    break;
+                sig_examination = avr_isp_prog_check_signature(instance);
+                y++;
+            }
+            if(y == 8) {
+                if(spi_speed[i] > AvrIspSpiSwSpeed1Mhz) {
+                    if(i < (COUNT_OF(spi_speed) - 1)) {
+                        avr_isp_prog_end_pmode(instance);
+                        i++;
+                        return avr_isp_prog_start_pmode(instance, spi_speed[i]);
+                    }
+                }
+                return true;
+            }
+        }
+    }
+
+    if(instance->spi) {
+        avr_isp_spi_sw_free(instance->spi);
+        instance->spi = NULL;
+    }
+
+    return false;
+}
+
+static void avr_isp_prog_universal(AvrIspProg* instance) {
+    furi_assert(instance);
+    uint8_t data;
+
+    avr_isp_prog_fill(instance, 4);
+    data = avr_isp_prog_spi_transaction(
+        instance, instance->buff[0], instance->buff[1], instance->buff[2], instance->buff[3]);
+    avr_isp_prog_breply(instance, data);
+}
+
+static void avr_isp_prog_commit(AvrIspProg* instance, uint16_t addr, uint8_t data) {
+    furi_assert(instance);
+    avr_isp_prog_spi_transaction(instance, AVR_ISP_COMMIT(addr));
+    /* polling flash */
+    if(data == 0xFF) {
+        furi_delay_ms(5);
+    } else {
+        /* polling flash */
+        uint32_t starttime = furi_get_tick();
+        while((furi_get_tick() - starttime) < 30) {
+            if(avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_FLASH_HI(addr)) != 0xFF) {
+                break;
+            };
+        }
+    }
+}
+
+static uint16_t avr_isp_prog_current_page(AvrIspProg* instance) {
+    furi_assert(instance);
+    uint16_t page = 0;
+    switch(instance->cfg->pagesize) {
+    case 32:
+        page = instance->addr & 0xFFFFFFF0;
+        break;
+    case 64:
+        page = instance->addr & 0xFFFFFFE0;
+        break;
+    case 128:
+        page = instance->addr & 0xFFFFFFC0;
+        break;
+    case 256:
+        page = instance->addr & 0xFFFFFF80;
+        break;
+
+    default:
+        page = instance->addr;
+        break;
+    }
+
+    return page;
+}
+
+static uint8_t avr_isp_prog_write_flash_pages(AvrIspProg* instance, size_t length) {
+    furi_assert(instance);
+    size_t x = 0;
+    uint16_t page = avr_isp_prog_current_page(instance);
+    while(x < length) {
+        if(page != avr_isp_prog_current_page(instance)) {
+            --x;
+            avr_isp_prog_commit(instance, page, instance->buff[x++]);
+            page = avr_isp_prog_current_page(instance);
+        }
+        avr_isp_prog_spi_transaction(
+            instance, AVR_ISP_WRITE_FLASH_LO(instance->addr, instance->buff[x++]));
+
+        avr_isp_prog_spi_transaction(
+            instance, AVR_ISP_WRITE_FLASH_HI(instance->addr, instance->buff[x++]));
+        instance->addr++;
+    }
+
+    avr_isp_prog_commit(instance, page, instance->buff[--x]);
+    return STK_OK;
+}
+
+static void avr_isp_prog_write_flash(AvrIspProg* instance, size_t length) {
+    furi_assert(instance);
+    avr_isp_prog_fill(instance, length);
+    if(avr_isp_prog_getch(instance) == CRC_EOP) {
+        avr_isp_prog_tx_ch(instance, STK_INSYNC);
+        avr_isp_prog_tx_ch(instance, avr_isp_prog_write_flash_pages(instance, length));
+    } else {
+        instance->error++;
+        avr_isp_prog_tx_ch(instance, STK_NOSYNC);
+    }
+}
+
+// write (length) bytes, (start) is a byte address
+static uint8_t
+    avr_isp_prog_write_eeprom_chunk(AvrIspProg* instance, uint16_t start, uint16_t length) {
+    furi_assert(instance);
+    // this writes byte-by-byte,
+    // page writing may be faster (4 bytes at a time)
+    avr_isp_prog_fill(instance, length);
+    for(uint16_t x = 0; x < length; x++) {
+        uint16_t addr = start + x;
+        avr_isp_prog_spi_transaction(instance, AVR_ISP_WRITE_EEPROM(addr, instance->buff[x]));
+        furi_delay_ms(10);
+    }
+    return STK_OK;
+}
+
+static uint8_t avr_isp_prog_write_eeprom(AvrIspProg* instance, size_t length) {
+    furi_assert(instance);
+    // here is a word address, get the byte address
+    uint16_t start = instance->addr * 2;
+    uint16_t remaining = length;
+    if(length > instance->cfg->eepromsize) {
+        instance->error++;
+        return STK_FAILED;
+    }
+    while(remaining > AVR_ISP_EECHUNK) {
+        avr_isp_prog_write_eeprom_chunk(instance, start, AVR_ISP_EECHUNK);
+        start += AVR_ISP_EECHUNK;
+        remaining -= AVR_ISP_EECHUNK;
+    }
+    avr_isp_prog_write_eeprom_chunk(instance, start, remaining);
+    return STK_OK;
+}
+
+static void avr_isp_prog_program_page(AvrIspProg* instance) {
+    furi_assert(instance);
+    uint8_t result = STK_FAILED;
+    uint16_t length = avr_isp_prog_getch(instance) << 8 | avr_isp_prog_getch(instance);
+    uint8_t memtype = avr_isp_prog_getch(instance);
+    // flash memory @addr, (length) bytes
+    if(memtype == STK_SET_FLASH_TYPE) {
+        avr_isp_prog_write_flash(instance, length);
+        return;
+    }
+    if(memtype == STK_SET_EEPROM_TYPE) {
+        result = avr_isp_prog_write_eeprom(instance, length);
+        if(avr_isp_prog_getch(instance) == CRC_EOP) {
+            avr_isp_prog_tx_ch(instance, STK_INSYNC);
+            avr_isp_prog_tx_ch(instance, result);
+
+        } else {
+            instance->error++;
+            avr_isp_prog_tx_ch(instance, STK_NOSYNC);
+        }
+        return;
+    }
+    avr_isp_prog_tx_ch(instance, STK_FAILED);
+    return;
+}
+
+static uint8_t avr_isp_prog_flash_read_page(AvrIspProg* instance, uint16_t length) {
+    furi_assert(instance);
+    for(uint16_t x = 0; x < length; x += 2) {
+        avr_isp_prog_tx_ch(
+            instance,
+            avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_FLASH_LO(instance->addr)));
+        avr_isp_prog_tx_ch(
+            instance,
+            avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_FLASH_HI(instance->addr)));
+        instance->addr++;
+    }
+    return STK_OK;
+}
+
+static uint8_t avr_isp_prog_eeprom_read_page(AvrIspProg* instance, uint16_t length) {
+    furi_assert(instance);
+    // here again we have a word address
+    uint16_t start = instance->addr * 2;
+    for(uint16_t x = 0; x < length; x++) {
+        uint16_t addr = start + x;
+        avr_isp_prog_tx_ch(
+            instance, avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_EEPROM(addr)));
+    }
+    return STK_OK;
+}
+
+static void avr_isp_prog_read_page(AvrIspProg* instance) {
+    furi_assert(instance);
+    uint8_t result = STK_FAILED;
+    uint16_t length = avr_isp_prog_getch(instance) << 8 | avr_isp_prog_getch(instance);
+    uint8_t memtype = avr_isp_prog_getch(instance);
+    if(avr_isp_prog_getch(instance) != CRC_EOP) {
+        instance->error++;
+        avr_isp_prog_tx_ch(instance, STK_NOSYNC);
+        return;
+    }
+    avr_isp_prog_tx_ch(instance, STK_INSYNC);
+    if(memtype == STK_SET_FLASH_TYPE) result = avr_isp_prog_flash_read_page(instance, length);
+    if(memtype == STK_SET_EEPROM_TYPE) result = avr_isp_prog_eeprom_read_page(instance, length);
+    avr_isp_prog_tx_ch(instance, result);
+}
+
+static void avr_isp_prog_read_signature(AvrIspProg* instance) {
+    furi_assert(instance);
+    if(avr_isp_prog_getch(instance) != CRC_EOP) {
+        instance->error++;
+        avr_isp_prog_tx_ch(instance, STK_NOSYNC);
+        return;
+    }
+    avr_isp_prog_tx_ch(instance, STK_INSYNC);
+
+    avr_isp_prog_tx_ch(instance, avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_VENDOR));
+    avr_isp_prog_tx_ch(instance, avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_PART_FAMILY));
+    avr_isp_prog_tx_ch(instance, avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_PART_NUMBER));
+
+    avr_isp_prog_tx_ch(instance, STK_OK);
+}
+
+void avr_isp_prog_avrisp(AvrIspProg* instance) {
+    furi_assert(instance);
+    uint8_t ch = avr_isp_prog_getch(instance);
+
+    switch(ch) {
+    case STK_GET_SYNC:
+        FURI_LOG_D(TAG, "cmd STK_GET_SYNC");
+        instance->error = 0;
+        avr_isp_prog_empty_reply(instance);
+        break;
+    case STK_GET_SIGN_ON:
+        FURI_LOG_D(TAG, "cmd STK_GET_SIGN_ON");
+        if(avr_isp_prog_getch(instance) == CRC_EOP) {
+            avr_isp_prog_tx_ch(instance, STK_INSYNC);
+
+            avr_isp_prog_tx_ch(instance, 'A');
+            avr_isp_prog_tx_ch(instance, 'V');
+            avr_isp_prog_tx_ch(instance, 'R');
+            avr_isp_prog_tx_ch(instance, ' ');
+            avr_isp_prog_tx_ch(instance, 'I');
+            avr_isp_prog_tx_ch(instance, 'S');
+            avr_isp_prog_tx_ch(instance, 'P');
+
+            avr_isp_prog_tx_ch(instance, STK_OK);
+        } else {
+            instance->error++;
+            avr_isp_prog_tx_ch(instance, STK_NOSYNC);
+        }
+        break;
+    case STK_GET_PARAMETER:
+        FURI_LOG_D(TAG, "cmd STK_GET_PARAMETER");
+        avr_isp_prog_get_version(instance, avr_isp_prog_getch(instance));
+        break;
+    case STK_SET_DEVICE:
+        FURI_LOG_D(TAG, "cmd STK_SET_DEVICE");
+        avr_isp_prog_fill(instance, 20);
+        avr_isp_prog_set_cfg(instance);
+        avr_isp_prog_empty_reply(instance);
+        break;
+    case STK_SET_DEVICE_EXT: // ignore for now
+        FURI_LOG_D(TAG, "cmd STK_SET_DEVICE_EXT");
+        avr_isp_prog_fill(instance, 5);
+        avr_isp_prog_empty_reply(instance);
+        break;
+    case STK_ENTER_PROGMODE:
+        FURI_LOG_D(TAG, "cmd STK_ENTER_PROGMODE");
+        if(!instance->pmode) avr_isp_prog_auto_set_spi_speed_start_pmode(instance);
+        avr_isp_prog_empty_reply(instance);
+        break;
+    case STK_LOAD_ADDRESS:
+        FURI_LOG_D(TAG, "cmd STK_LOAD_ADDRESS");
+        instance->addr = avr_isp_prog_getch(instance) | avr_isp_prog_getch(instance) << 8;
+        avr_isp_prog_empty_reply(instance);
+        break;
+    case STK_PROG_FLASH: // ignore for now
+        FURI_LOG_D(TAG, "cmd STK_PROG_FLASH");
+        avr_isp_prog_getch(instance);
+        avr_isp_prog_getch(instance);
+        avr_isp_prog_empty_reply(instance);
+        break;
+    case STK_PROG_DATA: // ignore for now
+        FURI_LOG_D(TAG, "cmd STK_PROG_DATA");
+        avr_isp_prog_getch(instance);
+        avr_isp_prog_empty_reply(instance);
+        break;
+    case STK_PROG_PAGE:
+        FURI_LOG_D(TAG, "cmd STK_PROG_PAGE");
+        avr_isp_prog_program_page(instance);
+        break;
+    case STK_READ_PAGE:
+        FURI_LOG_D(TAG, "cmd STK_READ_PAGE");
+        avr_isp_prog_read_page(instance);
+        break;
+    case STK_UNIVERSAL:
+        FURI_LOG_D(TAG, "cmd STK_UNIVERSAL");
+        avr_isp_prog_universal(instance);
+        break;
+    case STK_LEAVE_PROGMODE:
+        FURI_LOG_D(TAG, "cmd STK_LEAVE_PROGMODE");
+        instance->error = 0;
+        if(instance->pmode) avr_isp_prog_end_pmode(instance);
+        avr_isp_prog_empty_reply(instance);
+        break;
+    case STK_READ_SIGN:
+        FURI_LOG_D(TAG, "cmd STK_READ_SIGN");
+        avr_isp_prog_read_signature(instance);
+        break;
+    // expecting a command, not CRC_EOP
+    // this is how we can get back in sync
+    case CRC_EOP:
+        FURI_LOG_D(TAG, "cmd CRC_EOP");
+        instance->error++;
+        avr_isp_prog_tx_ch(instance, STK_NOSYNC);
+        break;
+    // anything else we will return STK_UNKNOWN
+    default:
+        FURI_LOG_D(TAG, "cmd STK_ERROR_CMD");
+        instance->error++;
+        if(avr_isp_prog_getch(instance) == CRC_EOP)
+            avr_isp_prog_tx_ch(instance, STK_UNKNOWN);
+        else
+            avr_isp_prog_tx_ch(instance, STK_NOSYNC);
+    }
+
+    if(instance->callback) {
+        instance->callback(instance->context);
+    }
+}

+ 16 - 0
avr_isp_programmer/lib/driver/avr_isp_prog.h

@@ -0,0 +1,16 @@
+#pragma once
+
+#include "avr_isp_spi_sw.h"
+#include <furi_hal.h>
+
+typedef struct AvrIspProg AvrIspProg;
+typedef void (*AvrIspProgCallback)(void* context);
+
+AvrIspProg* avr_isp_prog_init(void);
+void avr_isp_prog_free(AvrIspProg* instance);
+size_t avr_isp_prog_spaces_rx(AvrIspProg* instance) ;
+bool avr_isp_prog_rx(AvrIspProg* instance, uint8_t* data, size_t len);
+size_t avr_isp_prog_tx(AvrIspProg* instance, uint8_t* data, size_t max_len);
+void avr_isp_prog_avrisp(AvrIspProg* instance);
+void avr_isp_prog_exit(AvrIspProg* instance);
+void avr_isp_prog_set_tx_callback(AvrIspProg* instance, AvrIspProgCallback callback, void* context);

+ 97 - 0
avr_isp_programmer/lib/driver/avr_isp_prog_cmd.h

@@ -0,0 +1,97 @@
+#pragma once
+
+// http://ww1.microchip.com/downloads/en/appnotes/atmel-0943-in-system-programming_applicationnote_avr910.pdf
+// AVR ISP Definitions
+#define AVR_ISP_HWVER 0X02
+#define AVR_ISP_SWMAJ 0X01
+#define AVR_ISP_SWMIN 0X12
+#define AVP_ISP_SERIAL_CONNECT_TYPE 0X53
+#define AVP_ISP_CONNECT_TYPE 0x93
+#define AVR_ISP_RESP_0 0X00
+
+#define AVR_ISP_SET_PMODE 0xAC, 0x53, 0x00, 0x00
+#define AVR_ISP_READ_VENDOR 0x30, 0x00, 0x00, 0x00
+#define AVR_ISP_READ_PART_FAMILY 0x30, 0x00, 0x01, 0x00
+#define AVR_ISP_READ_PART_NUMBER 0x30, 0x00, 0x02, 0x00
+#define AVR_ISP_ERASE_CHIP \
+    0xAC, 0x80, 0x00, 0x00 //Erase Chip, Wait N ms, Release RESET to end the erase.
+//The only way to end a Chip Erase cycle is by temporarily releasing the Reset line
+
+#define AVR_ISP_EXTENDED_ADDR(data) 0x4D, 0x00, data, 0x00
+#define AVR_ISP_WRITE_FLASH_LO(add, data) 0x40, (add >> 8) & 0xFF, add & 0xFF, data
+#define AVR_ISP_WRITE_FLASH_HI(add, data) 0x48, (add >> 8) & 0xFF, add & 0xFF, data
+#define AVR_ISP_READ_FLASH_LO(add) 0x20, (add >> 8) & 0xFF, add & 0xFF, 0x00
+#define AVR_ISP_READ_FLASH_HI(add) 0x28, (add >> 8) & 0xFF, add & 0xFF, 0x00
+
+#define AVR_ISP_WRITE_EEPROM(add, data) \
+    0xC0, (add >> 8) & 0xFF, add & 0xFF, data //Send cmd, Wait N ms
+#define AVR_ISP_READ_EEPROM(add) 0xA0, (add >> 8) & 0xFF, add & 0xFF, 0xFF
+
+#define AVR_ISP_COMMIT(add) \
+    0x4C, (add >> 8) & 0xFF, add & 0xFF, 0x00 //Send cmd, polling read last addr page
+
+#define AVR_ISP_OSCCAL(add) 0x38, 0x00, add, 0x00
+
+#define AVR_ISP_WRITE_LOCK_BYTE(data) 0xAC, 0xE0, 0x00, data //Send cmd, Wait N ms
+#define AVR_ISP_READ_LOCK_BYTE 0x58, 0x00, 0x00, 0x00
+#define AVR_ISP_WRITE_FUSE_LOW(data) 0xAC, 0xA0, 0x00, data //Send cmd, Wait N ms
+#define AVR_ISP_READ_FUSE_LOW 0x50, 0x00, 0x00, 0x00
+#define AVR_ISP_WRITE_FUSE_HIGH(data) 0xAC, 0xA8, 0x00, data //Send cmd, Wait N ms
+#define AVR_ISP_READ_FUSE_HIGH 0x58, 0x08, 0x00, 0x00
+#define AVR_ISP_WRITE_FUSE_EXTENDED(data) 0xAC, 0xA4, 0x00, data //Send cmd, Wait N ms (~write)
+#define AVR_ISP_READ_FUSE_EXTENDED 0x50, 0x08, 0x00, 0x00
+
+#define AVR_ISP_EECHUNK 0x20
+
+// https://www.microchip.com/content/dam/mchp/documents/OTH/ApplicationNotes/ApplicationNotes/doc2525.pdf
+// STK Definitions
+#define STK_OK 0x10
+#define STK_FAILED 0x11
+#define STK_UNKNOWN 0x12
+#define STK_INSYNC 0x14
+#define STK_NOSYNC 0x15
+#define CRC_EOP 0x20
+
+#define STK_GET_SYNC 0x30
+#define STK_GET_SIGN_ON 0x31
+#define STK_SET_PARAMETER 0x40
+#define STK_GET_PARAMETER 0x41
+#define STK_SET_DEVICE 0x42
+#define STK_SET_DEVICE_EXT 0x45
+#define STK_ENTER_PROGMODE 0x50
+#define STK_LEAVE_PROGMODE 0x51
+#define STK_CHIP_ERASE 0x52
+#define STK_CHECK_AUTOINC 0x53
+#define STK_LOAD_ADDRESS 0x55
+#define STK_UNIVERSAL 0x56
+#define STK_UNIVERSAL_MULTI 0x57
+#define STK_PROG_FLASH 0x60
+#define STK_PROG_DATA 0x61
+#define STK_PROG_FUSE 0x62
+#define STK_PROG_FUSE_EXT 0x65
+#define STK_PROG_LOCK 0x63
+#define STK_PROG_PAGE 0x64
+#define STK_READ_FLASH 0x70
+#define STK_READ_DATA 0x71
+#define STK_READ_FUSE 0x72
+#define STK_READ_LOCK 0x73
+#define STK_READ_PAGE 0x74
+#define STK_READ_SIGN 0x75
+#define STK_READ_OSCCAL 0x76
+#define STK_READ_FUSE_EXT 0x77
+#define STK_READ_OSCCAL_EXT 0x78
+#define STK_HW_VER 0x80
+#define STK_SW_MAJOR 0x81
+#define STK_SW_MINOR 0x82
+#define STK_LEDS 0x83
+#define STK_VTARGET 0x84
+#define STK_VADJUST 0x85
+#define STK_OSC_PSCALE 0x86
+#define STK_OSC_CMATCH 0x87
+#define STK_SCK_DURATION 0x89
+#define STK_BUFSIZEL 0x90
+#define STK_BUFSIZEH 0x91
+#define STK_STK500_TOPCARD_DETECT 0x98
+
+#define STK_SET_EEPROM_TYPE 0X45
+#define STK_SET_FLASH_TYPE 0X46

+ 71 - 0
avr_isp_programmer/lib/driver/avr_isp_spi_sw.c

@@ -0,0 +1,71 @@
+#include "avr_isp_spi_sw.h"
+
+#include <furi.h>
+
+#define AVR_ISP_SPI_SW_MISO &gpio_ext_pa6
+#define AVR_ISP_SPI_SW_MOSI &gpio_ext_pa7
+#define AVR_ISP_SPI_SW_SCK &gpio_ext_pb3
+#define AVR_ISP_RESET &gpio_ext_pb2
+
+struct AvrIspSpiSw {
+    AvrIspSpiSwSpeed speed_wait_time;
+    const GpioPin* miso;
+    const GpioPin* mosi;
+    const GpioPin* sck;
+    const GpioPin* res;
+};
+
+AvrIspSpiSw* avr_isp_spi_sw_init(AvrIspSpiSwSpeed speed) {
+    AvrIspSpiSw* instance = malloc(sizeof(AvrIspSpiSw));
+    instance->speed_wait_time = speed;
+    instance->miso = AVR_ISP_SPI_SW_MISO;
+    instance->mosi = AVR_ISP_SPI_SW_MOSI;
+    instance->sck = AVR_ISP_SPI_SW_SCK;
+    instance->res = AVR_ISP_RESET;
+
+    furi_hal_gpio_init(instance->miso, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_write(instance->mosi, false);
+    furi_hal_gpio_init(instance->mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_write(instance->sck, false);
+    furi_hal_gpio_init(instance->sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_init(instance->res, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
+
+    return instance;
+}
+
+void avr_isp_spi_sw_free(AvrIspSpiSw* instance) {
+    furi_assert(instance);
+    furi_hal_gpio_init(instance->res, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
+    furi_hal_gpio_init(instance->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
+    furi_hal_gpio_init(instance->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
+    furi_hal_gpio_init(instance->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
+    free(instance);
+}
+
+uint8_t avr_isp_spi_sw_txrx(AvrIspSpiSw* instance, uint8_t data) {
+    furi_assert(instance);
+    for(uint8_t i = 0; i < 8; ++i) {
+        furi_hal_gpio_write(instance->mosi, (data & 0x80) ? true : false);
+
+        furi_hal_gpio_write(instance->sck, true);
+        if(instance->speed_wait_time != AvrIspSpiSwSpeed1Mhz)
+            furi_delay_us(instance->speed_wait_time - 1);
+
+        data = (data << 1) | furi_hal_gpio_read(instance->miso); //-V792
+
+        furi_hal_gpio_write(instance->sck, false);
+        if(instance->speed_wait_time != AvrIspSpiSwSpeed1Mhz)
+            furi_delay_us(instance->speed_wait_time - 1);
+    }
+    return data;
+}
+
+void avr_isp_spi_sw_res_set(AvrIspSpiSw* instance, bool state) {
+    furi_assert(instance);
+    furi_hal_gpio_write(instance->res, state);
+}
+
+void avr_isp_spi_sw_sck_set(AvrIspSpiSw* instance, bool state) {
+    furi_assert(instance);
+    furi_hal_gpio_write(instance->sck, state);
+}

+ 24 - 0
avr_isp_programmer/lib/driver/avr_isp_spi_sw.h

@@ -0,0 +1,24 @@
+#pragma once
+
+#include <furi_hal.h>
+
+typedef enum {
+    AvrIspSpiSwSpeed1Mhz = 0,
+    AvrIspSpiSwSpeed400Khz = 1,
+    AvrIspSpiSwSpeed250Khz = 2,
+    AvrIspSpiSwSpeed125Khz = 4,
+    AvrIspSpiSwSpeed60Khz = 8,
+    AvrIspSpiSwSpeed40Khz = 12,
+    AvrIspSpiSwSpeed20Khz = 24,
+    AvrIspSpiSwSpeed10Khz = 48,
+    AvrIspSpiSwSpeed5Khz = 96,
+    AvrIspSpiSwSpeed1Khz = 480,
+} AvrIspSpiSwSpeed;
+
+typedef struct AvrIspSpiSw AvrIspSpiSw;
+
+AvrIspSpiSw* avr_isp_spi_sw_init(AvrIspSpiSwSpeed speed);
+void avr_isp_spi_sw_free(AvrIspSpiSw* instance);
+uint8_t avr_isp_spi_sw_txrx(AvrIspSpiSw* instance, uint8_t data);
+void avr_isp_spi_sw_res_set(AvrIspSpiSw* instance, bool state);
+void avr_isp_spi_sw_sck_set(AvrIspSpiSw* instance, bool state);

BIN
avr_isp_programmer/lib/driver/clock.png


+ 30 - 0
avr_isp_programmer/scenes/avr_isp_scene.c

@@ -0,0 +1,30 @@
+#include "../avr_isp_app_i.h"
+
+// Generate scene on_enter handlers array
+#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
+void (*const avr_isp_scene_on_enter_handlers[])(void*) = {
+#include "avr_isp_scene_config.h"
+};
+#undef ADD_SCENE
+
+// Generate scene on_event handlers array
+#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
+bool (*const avr_isp_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = {
+#include "avr_isp_scene_config.h"
+};
+#undef ADD_SCENE
+
+// Generate scene on_exit handlers array
+#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
+void (*const avr_isp_scene_on_exit_handlers[])(void* context) = {
+#include "avr_isp_scene_config.h"
+};
+#undef ADD_SCENE
+
+// Initialize scene handlers configuration structure
+const SceneManagerHandlers avr_isp_scene_handlers = {
+    .on_enter_handlers = avr_isp_scene_on_enter_handlers,
+    .on_event_handlers = avr_isp_scene_on_event_handlers,
+    .on_exit_handlers = avr_isp_scene_on_exit_handlers,
+    .scene_num = AvrIspSceneNum,
+};

+ 29 - 0
avr_isp_programmer/scenes/avr_isp_scene.h

@@ -0,0 +1,29 @@
+#pragma once
+
+#include <gui/scene_manager.h>
+
+// Generate scene id and total number
+#define ADD_SCENE(prefix, name, id) AvrIspScene##id,
+typedef enum {
+#include "avr_isp_scene_config.h"
+    AvrIspSceneNum,
+} AvrIspScene;
+#undef ADD_SCENE
+
+extern const SceneManagerHandlers avr_isp_scene_handlers;
+
+// Generate scene on_enter handlers declaration
+#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
+#include "avr_isp_scene_config.h"
+#undef ADD_SCENE
+
+// Generate scene on_event handlers declaration
+#define ADD_SCENE(prefix, name, id) \
+    bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
+#include "avr_isp_scene_config.h"
+#undef ADD_SCENE
+
+// Generate scene on_exit handlers declaration
+#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
+#include "avr_isp_scene_config.h"
+#undef ADD_SCENE

+ 99 - 0
avr_isp_programmer/scenes/avr_isp_scene_about.c

@@ -0,0 +1,99 @@
+#include "../avr_isp_app_i.h"
+#include "../helpers/avr_isp_types.h"
+
+void avr_isp_scene_about_widget_callback(GuiButtonType result, InputType type, void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    if(type == InputTypeShort) {
+        view_dispatcher_send_custom_event(app->view_dispatcher, result);
+    }
+}
+
+void avr_isp_scene_about_on_enter(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    FuriString* temp_str = furi_string_alloc();
+    furi_string_printf(temp_str, "\e#%s\n", "Information");
+
+    furi_string_cat_printf(temp_str, "Version: %s\n", AVR_ISP_VERSION_APP);
+    furi_string_cat_printf(temp_str, "Developed by: %s\n", AVR_ISP_DEVELOPED);
+    furi_string_cat_printf(temp_str, "Github: %s\n\n", AVR_ISP_GITHUB);
+
+    furi_string_cat_printf(temp_str, "\e#%s\n", "Description");
+    furi_string_cat_printf(
+        temp_str,
+        "This application is an AVR in-system programmer based on stk500mk1. It is compatible with AVR-based"
+        " microcontrollers including Arduino. You can also use it to repair the chip if you accidentally"
+        " corrupt the bootloader.\n\n");
+
+    furi_string_cat_printf(temp_str, "\e#%s\n", "What it can do:");
+    furi_string_cat_printf(temp_str, "- Create a dump of your chip on an SD card\n");
+    furi_string_cat_printf(temp_str, "- Flash your chip firmware from the SD card\n");
+    furi_string_cat_printf(temp_str, "- Act as a wired USB ISP using avrdude software\n\n");
+
+    furi_string_cat_printf(temp_str, "\e#%s\n", "Supported chip series:");
+    furi_string_cat_printf(
+        temp_str,
+        "Example command for avrdude flashing: avrdude.exe -p m328p -c stk500v1 -P COMxx -U flash:r:"
+        "X:\\sketch_sample.hex"
+        ":i\n");
+    furi_string_cat_printf(
+        temp_str,
+        "Where: "
+        "-p m328p"
+        " brand of your chip, "
+        "-P COMxx"
+        " com port number in the system when "
+        "ISP Programmer"
+        " is enabled\n\n");
+
+    furi_string_cat_printf(temp_str, "\e#%s\n", "Info");
+    furi_string_cat_printf(
+        temp_str,
+        "ATtinyXXXX\nATmegaXXXX\nAT43Uxxx\nAT76C711\nAT86RF401\nAT90xxxxx\nAT94K\n"
+        "ATAxxxxx\nATA664251\nM3000\nLGT8F88P\nLGT8F168P\nLGT8F328P\n");
+
+    furi_string_cat_printf(
+        temp_str, "For a more detailed list of supported chips, see AVRDude help\n");
+
+    widget_add_text_box_element(
+        app->widget,
+        0,
+        0,
+        128,
+        14,
+        AlignCenter,
+        AlignBottom,
+        "\e#\e!                                                      \e!\n",
+        false);
+    widget_add_text_box_element(
+        app->widget,
+        0,
+        2,
+        128,
+        14,
+        AlignCenter,
+        AlignBottom,
+        "\e#\e!        ISP Programmer       \e!\n",
+        false);
+    widget_add_text_scroll_element(app->widget, 0, 16, 128, 50, furi_string_get_cstr(temp_str));
+    furi_string_free(temp_str);
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewWidget);
+}
+
+bool avr_isp_scene_about_on_event(void* context, SceneManagerEvent event) {
+    UNUSED(context);
+    UNUSED(event);
+    return false;
+}
+
+void avr_isp_scene_about_on_exit(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    // Clear views
+    widget_reset(app->widget);
+}

+ 72 - 0
avr_isp_programmer/scenes/avr_isp_scene_chip_detect.c

@@ -0,0 +1,72 @@
+#include "../avr_isp_app_i.h"
+
+void avr_isp_scene_chip_detect_callback(AvrIspCustomEvent event, void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    view_dispatcher_send_custom_event(app->view_dispatcher, event);
+}
+
+void avr_isp_scene_chip_detect_on_enter(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    switch(app->error) {
+    case AvrIspErrorReading:
+    case AvrIspErrorWriting:
+    case AvrIspErrorWritingFuse:
+        avr_isp_chip_detect_set_state(
+            app->avr_isp_chip_detect_view, AvrIspChipDetectViewStateErrorOccured);
+        break;
+    case AvrIspErrorVerification:
+        avr_isp_chip_detect_set_state(
+            app->avr_isp_chip_detect_view, AvrIspChipDetectViewStateErrorVerification);
+        break;
+
+    default:
+        avr_isp_chip_detect_set_state(
+            app->avr_isp_chip_detect_view, AvrIspChipDetectViewStateNoDetect);
+        break;
+    }
+    app->error = AvrIspErrorNoError;
+    avr_isp_chip_detect_view_set_callback(
+        app->avr_isp_chip_detect_view, avr_isp_scene_chip_detect_callback, app);
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewChipDetect);
+}
+
+bool avr_isp_scene_chip_detect_on_event(void* context, SceneManagerEvent event) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    bool consumed = false;
+    if(event.type == SceneManagerEventTypeCustom) {
+        switch(event.event) {
+        case AvrIspCustomEventSceneChipDetectOk:
+
+            if(scene_manager_get_scene_state(app->scene_manager, AvrIspSceneChipDetect) ==
+               AvrIspViewProgrammer) {
+                scene_manager_next_scene(app->scene_manager, AvrIspSceneProgrammer);
+            } else if(
+                scene_manager_get_scene_state(app->scene_manager, AvrIspSceneChipDetect) ==
+                AvrIspViewReader) {
+                scene_manager_next_scene(app->scene_manager, AvrIspSceneInputName);
+            } else if(
+                scene_manager_get_scene_state(app->scene_manager, AvrIspSceneChipDetect) ==
+                AvrIspViewWriter) {
+                scene_manager_next_scene(app->scene_manager, AvrIspSceneLoad);
+            }
+
+            consumed = true;
+            break;
+        default:
+            break;
+        }
+    } else if(event.type == SceneManagerEventTypeTick) {
+    }
+    return consumed;
+}
+
+void avr_isp_scene_chip_detect_on_exit(void* context) {
+    UNUSED(context);
+}

+ 10 - 0
avr_isp_programmer/scenes/avr_isp_scene_config.h

@@ -0,0 +1,10 @@
+ADD_SCENE(avr_isp, start, Start)
+ADD_SCENE(avr_isp, about, About)
+ADD_SCENE(avr_isp, programmer, Programmer)
+ADD_SCENE(avr_isp, reader, Reader)
+ADD_SCENE(avr_isp, input_name, InputName)
+ADD_SCENE(avr_isp, load, Load)
+ADD_SCENE(avr_isp, writer, Writer)
+ADD_SCENE(avr_isp, wiring, Wiring)
+ADD_SCENE(avr_isp, chip_detect, ChipDetect)
+ADD_SCENE(avr_isp, success, Success)

+ 89 - 0
avr_isp_programmer/scenes/avr_isp_scene_input_name.c

@@ -0,0 +1,89 @@
+#include "../avr_isp_app_i.h"
+#include <gui/modules/validators.h>
+
+#define MAX_TEXT_INPUT_LEN 22
+
+void avr_isp_scene_input_name_text_callback(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    view_dispatcher_send_custom_event(app->view_dispatcher, AvrIspCustomEventSceneInputName);
+}
+
+void avr_isp_scene_input_name_get_timefilename(FuriString* name) {
+    FuriHalRtcDateTime datetime = {0};
+    furi_hal_rtc_get_datetime(&datetime);
+    furi_string_printf(
+        name,
+        "AVR_dump-%.4d%.2d%.2d-%.2d%.2d%.2d",
+        datetime.year,
+        datetime.month,
+        datetime.day,
+        datetime.hour,
+        datetime.minute,
+        datetime.second);
+}
+
+void avr_isp_scene_input_name_on_enter(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    // Setup view
+    TextInput* text_input = app->text_input;
+    bool dev_name_empty = false;
+
+    FuriString* file_name = furi_string_alloc();
+
+    avr_isp_scene_input_name_get_timefilename(file_name);
+    furi_string_set(app->file_path, STORAGE_APP_DATA_PATH_PREFIX);
+    //highlighting the entire filename by default
+    dev_name_empty = true;
+
+    strncpy(app->file_name_tmp, furi_string_get_cstr(file_name), AVR_ISP_MAX_LEN_NAME);
+    text_input_set_header_text(text_input, "Name dump");
+    text_input_set_result_callback(
+        text_input,
+        avr_isp_scene_input_name_text_callback,
+        app,
+        app->file_name_tmp,
+        MAX_TEXT_INPUT_LEN, // buffer size
+        dev_name_empty);
+
+    ValidatorIsFile* validator_is_file =
+        validator_is_file_alloc_init(STORAGE_APP_DATA_PATH_PREFIX, AVR_ISP_APP_EXTENSION, "");
+    text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
+
+    furi_string_free(file_name);
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewTextInput);
+}
+
+bool avr_isp_scene_input_name_on_event(void* context, SceneManagerEvent event) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    if(event.type == SceneManagerEventTypeBack) {
+        scene_manager_previous_scene(app->scene_manager);
+        return true;
+    } else if(event.type == SceneManagerEventTypeCustom) {
+        if(event.event == AvrIspCustomEventSceneInputName) {
+            if(strcmp(app->file_name_tmp, "") != 0) {
+                scene_manager_next_scene(app->scene_manager, AvrIspSceneReader);
+            } else {
+            }
+        }
+    }
+    return false;
+}
+
+void avr_isp_scene_input_name_on_exit(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    // Clear validator
+    void* validator_context = text_input_get_validator_callback_context(app->text_input);
+    text_input_set_validator(app->text_input, NULL, NULL);
+    validator_is_file_free(validator_context);
+    // Clear view
+    text_input_reset(app->text_input);
+}

+ 22 - 0
avr_isp_programmer/scenes/avr_isp_scene_load.c

@@ -0,0 +1,22 @@
+#include "../avr_isp_app_i.h"
+
+void avr_isp_scene_load_on_enter(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    if(avr_isp_load_from_file(app)) {
+        scene_manager_next_scene(app->scene_manager, AvrIspSceneWriter);
+    } else {
+        scene_manager_previous_scene(app->scene_manager);
+    }
+}
+
+bool avr_isp_scene_load_on_event(void* context, SceneManagerEvent event) {
+    UNUSED(context);
+    UNUSED(event);
+    return false;
+}
+
+void avr_isp_scene_load_on_exit(void* context) {
+    UNUSED(context);
+}

+ 28 - 0
avr_isp_programmer/scenes/avr_isp_scene_programmer.c

@@ -0,0 +1,28 @@
+#include "../avr_isp_app_i.h"
+
+void avr_isp_scene_programmer_callback(AvrIspCustomEvent event, void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    view_dispatcher_send_custom_event(app->view_dispatcher, event);
+}
+
+void avr_isp_scene_programmer_on_enter(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    avr_isp_programmer_view_set_callback(
+        app->avr_isp_programmer_view, avr_isp_scene_programmer_callback, app);
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewProgrammer);
+}
+
+bool avr_isp_scene_programmer_on_event(void* context, SceneManagerEvent event) {
+    UNUSED(context);
+    UNUSED(event);
+    return false;
+}
+
+void avr_isp_scene_programmer_on_exit(void* context) {
+    UNUSED(context);
+}

+ 64 - 0
avr_isp_programmer/scenes/avr_isp_scene_reader.c

@@ -0,0 +1,64 @@
+#include "../avr_isp_app_i.h"
+
+void avr_isp_scene_reader_callback(AvrIspCustomEvent event, void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    view_dispatcher_send_custom_event(app->view_dispatcher, event);
+}
+
+void avr_isp_scene_reader_on_enter(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    avr_isp_reader_set_file_path(
+        app->avr_isp_reader_view, furi_string_get_cstr(app->file_path), app->file_name_tmp);
+    avr_isp_reader_view_set_callback(app->avr_isp_reader_view, avr_isp_scene_reader_callback, app);
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewReader);
+}
+
+bool avr_isp_scene_reader_on_event(void* context, SceneManagerEvent event) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    UNUSED(app);
+    bool consumed = false;
+    if(event.type == SceneManagerEventTypeBack) {
+        //do not handle exit on "Back"
+        consumed = true;
+    } else if(event.type == SceneManagerEventTypeCustom) {
+        switch(event.event) {
+        case AvrIspCustomEventSceneReadingOk:
+            scene_manager_next_scene(app->scene_manager, AvrIspSceneSuccess);
+            consumed = true;
+            break;
+        case AvrIspCustomEventSceneExit:
+            scene_manager_search_and_switch_to_previous_scene(
+                app->scene_manager, AvrIspSceneChipDetect);
+            consumed = true;
+            break;
+        case AvrIspCustomEventSceneErrorVerification:
+            app->error = AvrIspErrorVerification;
+            scene_manager_search_and_switch_to_previous_scene(
+                app->scene_manager, AvrIspSceneChipDetect);
+            consumed = true;
+            break;
+        case AvrIspCustomEventSceneErrorReading:
+            app->error = AvrIspErrorReading;
+            scene_manager_search_and_switch_to_previous_scene(
+                app->scene_manager, AvrIspSceneChipDetect);
+            consumed = true;
+            break;
+        default:
+            break;
+        }
+    } else if(event.type == SceneManagerEventTypeTick) {
+        avr_isp_reader_update_progress(app->avr_isp_reader_view);
+    }
+    return consumed;
+}
+
+void avr_isp_scene_reader_on_exit(void* context) {
+    UNUSED(context);
+}

+ 75 - 0
avr_isp_programmer/scenes/avr_isp_scene_start.c

@@ -0,0 +1,75 @@
+#include "../avr_isp_app_i.h"
+
+void avr_isp_scene_start_submenu_callback(void* context, uint32_t index) {
+    furi_assert(context);
+    AvrIspApp* app = context;
+
+    view_dispatcher_send_custom_event(app->view_dispatcher, index);
+}
+
+void avr_isp_scene_start_on_enter(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    Submenu* submenu = app->submenu;
+    submenu_add_item(
+        submenu, "Dump AVR", SubmenuIndexAvrIspReader, avr_isp_scene_start_submenu_callback, app);
+    submenu_add_item(
+        submenu, "Flash AVR", SubmenuIndexAvrIspWriter, avr_isp_scene_start_submenu_callback, app);
+    submenu_add_item(
+        submenu,
+        "ISP Programmer",
+        SubmenuIndexAvrIspProgrammer,
+        avr_isp_scene_start_submenu_callback,
+        app);
+    submenu_add_item(
+        submenu, "Wiring", SubmenuIndexAvrIsWiring, avr_isp_scene_start_submenu_callback, app);
+    submenu_add_item(
+        submenu, "About", SubmenuIndexAvrIspAbout, avr_isp_scene_start_submenu_callback, app);
+
+    submenu_set_selected_item(
+        submenu, scene_manager_get_scene_state(app->scene_manager, AvrIspSceneStart));
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewSubmenu);
+}
+
+bool avr_isp_scene_start_on_event(void* context, SceneManagerEvent event) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    bool consumed = false;
+    if(event.type == SceneManagerEventTypeCustom) {
+        if(event.event == SubmenuIndexAvrIspAbout) {
+            scene_manager_next_scene(app->scene_manager, AvrIspSceneAbout);
+            consumed = true;
+        } else if(event.event == SubmenuIndexAvrIspProgrammer) {
+            scene_manager_set_scene_state(
+                app->scene_manager, AvrIspSceneChipDetect, AvrIspViewProgrammer);
+            scene_manager_next_scene(app->scene_manager, AvrIspSceneChipDetect);
+            consumed = true;
+        } else if(event.event == SubmenuIndexAvrIspReader) {
+            scene_manager_set_scene_state(
+                app->scene_manager, AvrIspSceneChipDetect, AvrIspViewReader);
+            scene_manager_next_scene(app->scene_manager, AvrIspSceneChipDetect);
+            consumed = true;
+        } else if(event.event == SubmenuIndexAvrIspWriter) {
+            scene_manager_set_scene_state(
+                app->scene_manager, AvrIspSceneChipDetect, AvrIspViewWriter);
+            scene_manager_next_scene(app->scene_manager, AvrIspSceneChipDetect);
+            consumed = true;
+        } else if(event.event == SubmenuIndexAvrIsWiring) {
+            scene_manager_next_scene(app->scene_manager, AvrIspSceneWiring);
+            consumed = true;
+        }
+        scene_manager_set_scene_state(app->scene_manager, AvrIspSceneStart, event.event);
+    }
+
+    return consumed;
+}
+
+void avr_isp_scene_start_on_exit(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    submenu_reset(app->submenu);
+}

+ 44 - 0
avr_isp_programmer/scenes/avr_isp_scene_success.c

@@ -0,0 +1,44 @@
+#include "../avr_isp_app_i.h"
+
+void avr_isp_scene_success_popup_callback(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    view_dispatcher_send_custom_event(app->view_dispatcher, AvrIspCustomEventSceneSuccess);
+}
+
+void avr_isp_scene_success_on_enter(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    Popup* popup = app->popup;
+    popup_set_icon(popup, 32, 5, &I_dolphin_nice_96x59);
+    popup_set_header(popup, "Success!", 8, 22, AlignLeft, AlignBottom);
+    popup_set_timeout(popup, 1500);
+    popup_set_context(popup, app);
+    popup_set_callback(popup, avr_isp_scene_success_popup_callback);
+    popup_enable_timeout(popup);
+    view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewPopup);
+}
+
+bool avr_isp_scene_success_on_event(void* context, SceneManagerEvent event) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    if(event.type == SceneManagerEventTypeCustom) {
+        if(event.event == AvrIspCustomEventSceneSuccess) {
+            scene_manager_search_and_switch_to_previous_scene(
+                app->scene_manager, AvrIspSceneStart);
+            return true;
+        }
+    }
+    return false;
+}
+
+void avr_isp_scene_success_on_exit(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    Popup* popup = app->popup;
+    popup_reset(popup);
+}

+ 21 - 0
avr_isp_programmer/scenes/avr_isp_scene_wiring.c

@@ -0,0 +1,21 @@
+#include "../avr_isp_app_i.h"
+
+void avr_isp_scene_wiring_on_enter(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    widget_add_icon_element(app->widget, 0, 0, &I_avr_wiring);
+    view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewWidget);
+}
+
+bool avr_isp_scene_wiring_on_event(void* context, SceneManagerEvent event) {
+    UNUSED(context);
+    UNUSED(event);
+    return false;
+}
+void avr_isp_scene_wiring_on_exit(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    widget_reset(app->widget);
+}

+ 69 - 0
avr_isp_programmer/scenes/avr_isp_scene_writer.c

@@ -0,0 +1,69 @@
+#include "../avr_isp_app_i.h"
+
+void avr_isp_scene_writer_callback(AvrIspCustomEvent event, void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    view_dispatcher_send_custom_event(app->view_dispatcher, event);
+}
+
+void avr_isp_scene_writer_on_enter(void* context) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    avr_isp_writer_set_file_path(
+        app->avr_isp_writer_view, furi_string_get_cstr(app->file_path), app->file_name_tmp);
+    avr_isp_writer_view_set_callback(app->avr_isp_writer_view, avr_isp_scene_writer_callback, app);
+    view_dispatcher_switch_to_view(app->view_dispatcher, AvrIspViewWriter);
+}
+
+bool avr_isp_scene_writer_on_event(void* context, SceneManagerEvent event) {
+    furi_assert(context);
+
+    AvrIspApp* app = context;
+    bool consumed = false;
+    if(event.type == SceneManagerEventTypeBack) {
+        //do not handle exit on "Back"
+        consumed = true;
+    } else if(event.type == SceneManagerEventTypeCustom) {
+        switch(event.event) {
+        case AvrIspCustomEventSceneExitStartMenu:
+            scene_manager_search_and_switch_to_previous_scene(
+                app->scene_manager, AvrIspSceneStart);
+            consumed = true;
+            break;
+        case AvrIspCustomEventSceneExit:
+            scene_manager_search_and_switch_to_previous_scene(
+                app->scene_manager, AvrIspSceneChipDetect);
+            consumed = true;
+            break;
+        case AvrIspCustomEventSceneErrorVerification:
+            app->error = AvrIspErrorVerification;
+            scene_manager_search_and_switch_to_previous_scene(
+                app->scene_manager, AvrIspSceneChipDetect);
+            consumed = true;
+            break;
+        case AvrIspCustomEventSceneErrorWriting:
+            app->error = AvrIspErrorWriting;
+            scene_manager_search_and_switch_to_previous_scene(
+                app->scene_manager, AvrIspSceneChipDetect);
+            consumed = true;
+            break;
+        case AvrIspCustomEventSceneErrorWritingFuse:
+            app->error = AvrIspErrorWritingFuse;
+            scene_manager_search_and_switch_to_previous_scene(
+                app->scene_manager, AvrIspSceneChipDetect);
+            consumed = true;
+            break;
+        default:
+            break;
+        }
+    } else if(event.type == SceneManagerEventTypeTick) {
+        avr_isp_writer_update_progress(app->avr_isp_writer_view);
+    }
+    return consumed;
+}
+
+void avr_isp_scene_writer_on_exit(void* context) {
+    UNUSED(context);
+}

+ 213 - 0
avr_isp_programmer/views/avr_isp_view_chip_detect.c

@@ -0,0 +1,213 @@
+#include "avr_isp_view_chip_detect.h"
+#include <avr_isp_icons.h>
+#include <gui/elements.h>
+
+#include "../helpers/avr_isp_worker_rw.h"
+
+struct AvrIspChipDetectView {
+    View* view;
+    AvrIspWorkerRW* avr_isp_worker_rw;
+    AvrIspChipDetectViewCallback callback;
+    void* context;
+};
+
+typedef struct {
+    uint16_t idx;
+    const char* name_chip;
+    uint32_t flash_size;
+    AvrIspChipDetectViewState state;
+} AvrIspChipDetectViewModel;
+
+void avr_isp_chip_detect_view_set_callback(
+    AvrIspChipDetectView* instance,
+    AvrIspChipDetectViewCallback callback,
+    void* context) {
+    furi_assert(instance);
+    furi_assert(callback);
+
+    instance->callback = callback;
+    instance->context = context;
+}
+
+void avr_isp_chip_detect_set_state(AvrIspChipDetectView* instance, AvrIspChipDetectViewState state) {
+    furi_assert(instance);
+
+    with_view_model(
+        instance->view, AvrIspChipDetectViewModel * model, { model->state = state; }, true);
+}
+
+void avr_isp_chip_detect_view_draw(Canvas* canvas, AvrIspChipDetectViewModel* model) {
+    canvas_clear(canvas);
+
+    char str_buf[64] = {0};
+    canvas_set_font(canvas, FontPrimary);
+
+    switch(model->state) {
+    case AvrIspChipDetectViewStateDetected:
+        canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "AVR chip detected!");
+        canvas_draw_icon(canvas, 29, 14, &I_chip_long_70x22);
+        canvas_set_font(canvas, FontSecondary);
+        snprintf(str_buf, sizeof(str_buf), "%ld Kb", model->flash_size / 1024);
+        canvas_draw_str_aligned(canvas, 64, 25, AlignCenter, AlignCenter, str_buf);
+        canvas_draw_str_aligned(canvas, 64, 45, AlignCenter, AlignCenter, model->name_chip);
+        elements_button_right(canvas, "Next");
+        break;
+    case AvrIspChipDetectViewStateErrorOccured:
+        canvas_draw_str_aligned(
+            canvas, 64, 5, AlignCenter, AlignCenter, "Error occured, try again!");
+        canvas_draw_icon(canvas, 29, 14, &I_chip_error_70x22);
+        canvas_set_font(canvas, FontSecondary);
+        canvas_draw_str_aligned(
+            canvas, 64, 45, AlignCenter, AlignCenter, "Check the wiring and retry");
+        break;
+    case AvrIspChipDetectViewStateErrorVerification:
+        canvas_draw_str_aligned(
+            canvas, 64, 5, AlignCenter, AlignCenter, "Data verification failed");
+        canvas_draw_icon(canvas, 29, 14, &I_chip_error_70x22);
+        canvas_set_font(canvas, FontSecondary);
+        canvas_draw_str_aligned(
+            canvas, 64, 45, AlignCenter, AlignCenter, "Try to restart the process");
+        break;
+
+    default:
+        //AvrIspChipDetectViewStateNoDetect
+        canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "AVR chip not found!");
+        canvas_draw_icon(canvas, 29, 12, &I_chif_not_found_83x37);
+
+        break;
+    }
+    canvas_set_font(canvas, FontSecondary);
+    elements_button_left(canvas, "Retry");
+}
+
+bool avr_isp_chip_detect_view_input(InputEvent* event, void* context) {
+    furi_assert(context);
+
+    AvrIspChipDetectView* instance = context;
+
+    if(event->type == InputTypeShort) {
+        if(event->key == InputKeyBack) {
+            return false;
+        } else if(event->key == InputKeyRight) {
+            with_view_model(
+                instance->view,
+                AvrIspChipDetectViewModel * model,
+                {
+                    if(model->state == AvrIspChipDetectViewStateDetected) {
+                        if(instance->callback)
+                            instance->callback(
+                                AvrIspCustomEventSceneChipDetectOk, instance->context);
+                    }
+                },
+                false);
+
+        } else if(event->key == InputKeyLeft) {
+            bool detect_chip = false;
+            with_view_model(
+                instance->view,
+                AvrIspChipDetectViewModel * model,
+                {
+                    if(model->state != AvrIspChipDetectViewStateDetecting) {
+                        model->state = AvrIspChipDetectViewStateDetecting;
+                        detect_chip = true;
+                    }
+                },
+                false);
+            if(detect_chip) avr_isp_worker_rw_detect_chip(instance->avr_isp_worker_rw);
+        }
+    } else {
+        return false;
+    }
+
+    return true;
+}
+
+static void avr_isp_chip_detect_detect_chip_callback(
+    void* context,
+    const char* name,
+    bool detect_chip,
+    uint32_t flash_size) {
+    furi_assert(context);
+
+    AvrIspChipDetectView* instance = context;
+    with_view_model(
+        instance->view,
+        AvrIspChipDetectViewModel * model,
+        {
+            model->name_chip = name;
+            model->flash_size = flash_size;
+            if(detect_chip) {
+                model->state = AvrIspChipDetectViewStateDetected;
+            } else {
+                model->state = AvrIspChipDetectViewStateNoDetect;
+            }
+        },
+        true);
+}
+void avr_isp_chip_detect_view_enter(void* context) {
+    furi_assert(context);
+
+    AvrIspChipDetectView* instance = context;
+    bool detect_chip = false;
+    with_view_model(
+        instance->view,
+        AvrIspChipDetectViewModel * model,
+        {
+            if(model->state == AvrIspChipDetectViewStateNoDetect ||
+               model->state == AvrIspChipDetectViewStateDetected) {
+                detect_chip = true;
+            }
+        },
+        false);
+
+    //Start avr_isp_worker_rw
+    instance->avr_isp_worker_rw = avr_isp_worker_rw_alloc(instance->context);
+
+    avr_isp_worker_rw_set_callback(
+        instance->avr_isp_worker_rw, avr_isp_chip_detect_detect_chip_callback, instance);
+
+    if(detect_chip) avr_isp_worker_rw_detect_chip(instance->avr_isp_worker_rw);
+}
+
+void avr_isp_chip_detect_view_exit(void* context) {
+    furi_assert(context);
+
+    AvrIspChipDetectView* instance = context;
+
+    avr_isp_worker_rw_set_callback(instance->avr_isp_worker_rw, NULL, NULL);
+    avr_isp_worker_rw_free(instance->avr_isp_worker_rw);
+}
+
+AvrIspChipDetectView* avr_isp_chip_detect_view_alloc() {
+    AvrIspChipDetectView* instance = malloc(sizeof(AvrIspChipDetectView));
+
+    // View allocation and configuration
+    instance->view = view_alloc();
+
+    view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(AvrIspChipDetectViewModel));
+    view_set_context(instance->view, instance);
+    view_set_draw_callback(instance->view, (ViewDrawCallback)avr_isp_chip_detect_view_draw);
+    view_set_input_callback(instance->view, avr_isp_chip_detect_view_input);
+    view_set_enter_callback(instance->view, avr_isp_chip_detect_view_enter);
+    view_set_exit_callback(instance->view, avr_isp_chip_detect_view_exit);
+
+    with_view_model(
+        instance->view,
+        AvrIspChipDetectViewModel * model,
+        { model->state = AvrIspChipDetectViewStateNoDetect; },
+        false);
+    return instance;
+}
+
+void avr_isp_chip_detect_view_free(AvrIspChipDetectView* instance) {
+    furi_assert(instance);
+
+    view_free(instance->view);
+    free(instance);
+}
+
+View* avr_isp_chip_detect_view_get_view(AvrIspChipDetectView* instance) {
+    furi_assert(instance);
+
+    return instance->view;
+}

+ 32 - 0
avr_isp_programmer/views/avr_isp_view_chip_detect.h

@@ -0,0 +1,32 @@
+#pragma once
+
+#include <gui/view.h>
+#include "../helpers/avr_isp_types.h"
+#include "../helpers/avr_isp_event.h"
+
+typedef struct AvrIspChipDetectView AvrIspChipDetectView;
+
+typedef void (*AvrIspChipDetectViewCallback)(AvrIspCustomEvent event, void* context);
+
+typedef enum {
+    AvrIspChipDetectViewStateNoDetect,
+    AvrIspChipDetectViewStateDetecting,
+    AvrIspChipDetectViewStateDetected,
+    AvrIspChipDetectViewStateErrorOccured,
+    AvrIspChipDetectViewStateErrorVerification,
+} AvrIspChipDetectViewState;
+
+void avr_isp_chip_detect_view_set_callback(
+    AvrIspChipDetectView* instance,
+    AvrIspChipDetectViewCallback callback,
+    void* context);
+
+void avr_isp_chip_detect_set_state(AvrIspChipDetectView* instance, AvrIspChipDetectViewState state);
+
+AvrIspChipDetectView* avr_isp_chip_detect_view_alloc();
+
+void avr_isp_chip_detect_view_free(AvrIspChipDetectView* instance);
+
+View* avr_isp_chip_detect_view_get_view(AvrIspChipDetectView* instance);
+
+void avr_isp_chip_detect_view_exit(void* context);

+ 134 - 0
avr_isp_programmer/views/avr_isp_view_programmer.c

@@ -0,0 +1,134 @@
+#include "avr_isp_view_programmer.h"
+#include <avr_isp_icons.h>
+
+#include "../helpers/avr_isp_worker.h"
+#include <gui/elements.h>
+
+struct AvrIspProgrammerView {
+    View* view;
+    AvrIspWorker* worker;
+    AvrIspProgrammerViewCallback callback;
+    void* context;
+};
+
+typedef struct {
+    AvrIspProgrammerViewStatus status;
+} AvrIspProgrammerViewModel;
+
+void avr_isp_programmer_view_set_callback(
+    AvrIspProgrammerView* instance,
+    AvrIspProgrammerViewCallback callback,
+    void* context) {
+    furi_assert(instance);
+    furi_assert(callback);
+
+    instance->callback = callback;
+    instance->context = context;
+}
+
+void avr_isp_programmer_view_draw(Canvas* canvas, AvrIspProgrammerViewModel* model) {
+    canvas_clear(canvas);
+
+    if(model->status == AvrIspProgrammerViewStatusUSBConnect) {
+        canvas_set_font(canvas, FontPrimary);
+        canvas_draw_icon(canvas, 0, 0, &I_isp_active_128x53);
+        elements_multiline_text(canvas, 45, 10, "ISP mode active");
+    } else {
+        canvas_set_font(canvas, FontSecondary);
+        canvas_draw_icon(canvas, 51, 6, &I_link_waiting_77x56);
+        elements_multiline_text(canvas, 0, 25, "Waiting for\nsoftware\nconnection");
+    }
+}
+
+bool avr_isp_programmer_view_input(InputEvent* event, void* context) {
+    furi_assert(context);
+    UNUSED(context);
+
+    if(event->key == InputKeyBack || event->type != InputTypeShort) {
+        return false;
+    }
+
+    return true;
+}
+
+static void avr_isp_programmer_usb_connect_callback(void* context, bool status_connect) {
+    furi_assert(context);
+    AvrIspProgrammerView* instance = context;
+
+    with_view_model(
+        instance->view,
+        AvrIspProgrammerViewModel * model,
+        {
+            if(status_connect) {
+                model->status = AvrIspProgrammerViewStatusUSBConnect;
+            } else {
+                model->status = AvrIspProgrammerViewStatusNoUSBConnect;
+            }
+        },
+        true);
+}
+
+void avr_isp_programmer_view_enter(void* context) {
+    furi_assert(context);
+
+    AvrIspProgrammerView* instance = context;
+    with_view_model(
+        instance->view,
+        AvrIspProgrammerViewModel * model,
+        { model->status = AvrIspProgrammerViewStatusNoUSBConnect; },
+        true);
+
+    //Start worker
+    instance->worker = avr_isp_worker_alloc(instance->context);
+
+    avr_isp_worker_set_callback(
+        instance->worker, avr_isp_programmer_usb_connect_callback, instance);
+
+    avr_isp_worker_start(instance->worker);
+}
+
+void avr_isp_programmer_view_exit(void* context) {
+    furi_assert(context);
+
+    AvrIspProgrammerView* instance = context;
+    //Stop worker
+    if(avr_isp_worker_is_running(instance->worker)) {
+        avr_isp_worker_stop(instance->worker);
+    }
+    avr_isp_worker_set_callback(instance->worker, NULL, NULL);
+    avr_isp_worker_free(instance->worker);
+}
+
+AvrIspProgrammerView* avr_isp_programmer_view_alloc() {
+    AvrIspProgrammerView* instance = malloc(sizeof(AvrIspProgrammerView));
+
+    // View allocation and configuration
+    instance->view = view_alloc();
+
+    view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(AvrIspProgrammerViewModel));
+    view_set_context(instance->view, instance);
+    view_set_draw_callback(instance->view, (ViewDrawCallback)avr_isp_programmer_view_draw);
+    view_set_input_callback(instance->view, avr_isp_programmer_view_input);
+    view_set_enter_callback(instance->view, avr_isp_programmer_view_enter);
+    view_set_exit_callback(instance->view, avr_isp_programmer_view_exit);
+
+    with_view_model(
+        instance->view,
+        AvrIspProgrammerViewModel * model,
+        { model->status = AvrIspProgrammerViewStatusNoUSBConnect; },
+        false);
+    return instance;
+}
+
+void avr_isp_programmer_view_free(AvrIspProgrammerView* instance) {
+    furi_assert(instance);
+
+    view_free(instance->view);
+    free(instance);
+}
+
+View* avr_isp_programmer_view_get_view(AvrIspProgrammerView* instance) {
+    furi_assert(instance);
+
+    return instance->view;
+}

+ 27 - 0
avr_isp_programmer/views/avr_isp_view_programmer.h

@@ -0,0 +1,27 @@
+#pragma once
+
+#include <gui/view.h>
+#include "../helpers/avr_isp_types.h"
+#include "../helpers/avr_isp_event.h"
+
+typedef struct AvrIspProgrammerView AvrIspProgrammerView;
+
+typedef void (*AvrIspProgrammerViewCallback)(AvrIspCustomEvent event, void* context);
+
+typedef enum {
+    AvrIspProgrammerViewStatusNoUSBConnect,
+    AvrIspProgrammerViewStatusUSBConnect,
+} AvrIspProgrammerViewStatus;
+
+void avr_isp_programmer_view_set_callback(
+    AvrIspProgrammerView* instance,
+    AvrIspProgrammerViewCallback callback,
+    void* context);
+
+AvrIspProgrammerView* avr_isp_programmer_view_alloc();
+
+void avr_isp_programmer_view_free(AvrIspProgrammerView* instance);
+
+View* avr_isp_programmer_view_get_view(AvrIspProgrammerView* instance);
+
+void avr_isp_programmer_view_exit(void* context);

+ 215 - 0
avr_isp_programmer/views/avr_isp_view_reader.c

@@ -0,0 +1,215 @@
+#include "avr_isp_view_reader.h"
+#include <gui/elements.h>
+
+#include "../helpers/avr_isp_worker_rw.h"
+
+struct AvrIspReaderView {
+    View* view;
+    AvrIspWorkerRW* avr_isp_worker_rw;
+    const char* file_path;
+    const char* file_name;
+    AvrIspReaderViewCallback callback;
+    void* context;
+};
+
+typedef struct {
+    AvrIspReaderViewStatus status;
+    float progress_flash;
+    float progress_eeprom;
+} AvrIspReaderViewModel;
+
+void avr_isp_reader_update_progress(AvrIspReaderView* instance) {
+    with_view_model(
+        instance->view,
+        AvrIspReaderViewModel * model,
+        {
+            model->progress_flash =
+                avr_isp_worker_rw_get_progress_flash(instance->avr_isp_worker_rw);
+            model->progress_eeprom =
+                avr_isp_worker_rw_get_progress_eeprom(instance->avr_isp_worker_rw);
+        },
+        true);
+}
+
+void avr_isp_reader_view_set_callback(
+    AvrIspReaderView* instance,
+    AvrIspReaderViewCallback callback,
+    void* context) {
+    furi_assert(instance);
+    furi_assert(callback);
+
+    instance->callback = callback;
+    instance->context = context;
+}
+
+void avr_isp_reader_set_file_path(
+    AvrIspReaderView* instance,
+    const char* file_path,
+    const char* file_name) {
+    furi_assert(instance);
+
+    instance->file_path = file_path;
+    instance->file_name = file_name;
+}
+
+void avr_isp_reader_view_draw(Canvas* canvas, AvrIspReaderViewModel* model) {
+    canvas_clear(canvas);
+    char str_buf[64] = {0};
+
+    canvas_set_font(canvas, FontPrimary);
+    switch(model->status) {
+    case AvrIspReaderViewStatusIDLE:
+        canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Press start to dump");
+        canvas_set_font(canvas, FontSecondary);
+        elements_button_center(canvas, "Start");
+        break;
+    case AvrIspReaderViewStatusReading:
+        canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Reading dump");
+        break;
+    case AvrIspReaderViewStatusVerification:
+        canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Verifyng dump");
+        break;
+
+    default:
+        break;
+    }
+
+    canvas_set_font(canvas, FontSecondary);
+    canvas_draw_str(canvas, 0, 27, "Flash");
+    snprintf(str_buf, sizeof(str_buf), "%d%%", (uint8_t)(model->progress_flash * 100));
+    elements_progress_bar_with_text(canvas, 44, 17, 84, model->progress_flash, str_buf);
+    canvas_draw_str(canvas, 0, 43, "EEPROM");
+    snprintf(str_buf, sizeof(str_buf), "%d%%", (uint8_t)(model->progress_eeprom * 100));
+    elements_progress_bar_with_text(canvas, 44, 34, 84, model->progress_eeprom, str_buf);
+}
+
+bool avr_isp_reader_view_input(InputEvent* event, void* context) {
+    furi_assert(context);
+    AvrIspReaderView* instance = context;
+
+    bool ret = true;
+    if(event->key == InputKeyBack && event->type == InputTypeShort) {
+        with_view_model(
+            instance->view,
+            AvrIspReaderViewModel * model,
+            {
+                if(model->status == AvrIspReaderViewStatusIDLE) {
+                    if(instance->callback)
+                        instance->callback(AvrIspCustomEventSceneExit, instance->context);
+                    ret = false;
+                }
+            },
+            false);
+    } else if(event->key == InputKeyOk && event->type == InputTypeShort) {
+        with_view_model(
+            instance->view,
+            AvrIspReaderViewModel * model,
+            {
+                if(model->status == AvrIspReaderViewStatusIDLE) {
+                    model->status = AvrIspReaderViewStatusReading;
+                    avr_isp_worker_rw_read_dump_start(
+                        instance->avr_isp_worker_rw, instance->file_path, instance->file_name);
+                }
+            },
+            false);
+    }
+    return ret;
+}
+
+static void avr_isp_reader_callback_status(void* context, AvrIspWorkerRWStatus status) {
+    furi_assert(context);
+    AvrIspReaderView* instance = context;
+
+    with_view_model(
+        instance->view,
+        AvrIspReaderViewModel * model,
+        {
+            switch(status) {
+            case AvrIspWorkerRWStatusEndReading:
+                model->status = AvrIspReaderViewStatusVerification;
+                avr_isp_worker_rw_verification_start(
+                    instance->avr_isp_worker_rw, instance->file_path, instance->file_name);
+                model->status = AvrIspReaderViewStatusVerification;
+                break;
+            case AvrIspWorkerRWStatusEndVerification:
+                if(instance->callback)
+                    instance->callback(AvrIspCustomEventSceneReadingOk, instance->context);
+                break;
+            case AvrIspWorkerRWStatusErrorVerification:
+                if(instance->callback)
+                    instance->callback(AvrIspCustomEventSceneErrorVerification, instance->context);
+                break;
+
+            default:
+                //AvrIspWorkerRWStatusErrorReading;
+                if(instance->callback)
+                    instance->callback(AvrIspCustomEventSceneErrorReading, instance->context);
+                break;
+            }
+        },
+        true);
+}
+
+void avr_isp_reader_view_enter(void* context) {
+    furi_assert(context);
+    AvrIspReaderView* instance = context;
+
+    with_view_model(
+        instance->view,
+        AvrIspReaderViewModel * model,
+        {
+            model->status = AvrIspReaderViewStatusIDLE;
+            model->progress_flash = 0.0f;
+            model->progress_eeprom = 0.0f;
+        },
+        true);
+
+    //Start avr_isp_worker_rw
+    instance->avr_isp_worker_rw = avr_isp_worker_rw_alloc(instance->context);
+
+    avr_isp_worker_rw_set_callback_status(
+        instance->avr_isp_worker_rw, avr_isp_reader_callback_status, instance);
+
+    avr_isp_worker_rw_start(instance->avr_isp_worker_rw);
+}
+
+void avr_isp_reader_view_exit(void* context) {
+    furi_assert(context);
+
+    AvrIspReaderView* instance = context;
+    //Stop avr_isp_worker_rw
+    if(avr_isp_worker_rw_is_running(instance->avr_isp_worker_rw)) {
+        avr_isp_worker_rw_stop(instance->avr_isp_worker_rw);
+    }
+
+    avr_isp_worker_rw_free(instance->avr_isp_worker_rw);
+}
+
+AvrIspReaderView* avr_isp_reader_view_alloc() {
+    AvrIspReaderView* instance = malloc(sizeof(AvrIspReaderView));
+
+    // View allocation and configuration
+    instance->view = view_alloc();
+
+    view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(AvrIspReaderViewModel));
+    view_set_context(instance->view, instance);
+    view_set_draw_callback(instance->view, (ViewDrawCallback)avr_isp_reader_view_draw);
+    view_set_input_callback(instance->view, avr_isp_reader_view_input);
+    view_set_enter_callback(instance->view, avr_isp_reader_view_enter);
+    view_set_exit_callback(instance->view, avr_isp_reader_view_exit);
+
+    return instance;
+}
+
+void avr_isp_reader_view_free(AvrIspReaderView* instance) {
+    furi_assert(instance);
+
+    view_free(instance->view);
+    free(instance);
+}
+
+View* avr_isp_reader_view_get_view(AvrIspReaderView* instance) {
+    furi_assert(instance);
+
+    return instance->view;
+}

+ 35 - 0
avr_isp_programmer/views/avr_isp_view_reader.h

@@ -0,0 +1,35 @@
+#pragma once
+
+#include <gui/view.h>
+#include "../helpers/avr_isp_types.h"
+#include "../helpers/avr_isp_event.h"
+
+typedef struct AvrIspReaderView AvrIspReaderView;
+
+typedef void (*AvrIspReaderViewCallback)(AvrIspCustomEvent event, void* context);
+
+typedef enum {
+    AvrIspReaderViewStatusIDLE,
+    AvrIspReaderViewStatusReading,
+    AvrIspReaderViewStatusVerification,
+} AvrIspReaderViewStatus;
+
+void avr_isp_reader_update_progress(AvrIspReaderView* instance);
+
+void avr_isp_reader_set_file_path(
+    AvrIspReaderView* instance,
+    const char* file_path,
+    const char* file_name);
+
+void avr_isp_reader_view_set_callback(
+    AvrIspReaderView* instance,
+    AvrIspReaderViewCallback callback,
+    void* context);
+
+AvrIspReaderView* avr_isp_reader_view_alloc();
+
+void avr_isp_reader_view_free(AvrIspReaderView* instance);
+
+View* avr_isp_reader_view_get_view(AvrIspReaderView* instance);
+
+void avr_isp_reader_view_exit(void* context);

+ 268 - 0
avr_isp_programmer/views/avr_isp_view_writer.c

@@ -0,0 +1,268 @@
+#include "avr_isp_view_writer.h"
+#include <gui/elements.h>
+
+#include "../helpers/avr_isp_worker_rw.h"
+#include <float_tools.h>
+
+struct AvrIspWriterView {
+    View* view;
+    AvrIspWorkerRW* avr_isp_worker_rw;
+    const char* file_path;
+    const char* file_name;
+    AvrIspWriterViewCallback callback;
+    void* context;
+};
+
+typedef struct {
+    AvrIspWriterViewStatus status;
+    float progress_flash;
+    float progress_eeprom;
+} AvrIspWriterViewModel;
+
+void avr_isp_writer_update_progress(AvrIspWriterView* instance) {
+    with_view_model(
+        instance->view,
+        AvrIspWriterViewModel * model,
+        {
+            model->progress_flash =
+                avr_isp_worker_rw_get_progress_flash(instance->avr_isp_worker_rw);
+            model->progress_eeprom =
+                avr_isp_worker_rw_get_progress_eeprom(instance->avr_isp_worker_rw);
+        },
+        true);
+}
+
+void avr_isp_writer_view_set_callback(
+    AvrIspWriterView* instance,
+    AvrIspWriterViewCallback callback,
+    void* context) {
+    furi_assert(instance);
+    furi_assert(callback);
+
+    instance->callback = callback;
+    instance->context = context;
+}
+
+void avr_isp_writer_set_file_path(
+    AvrIspWriterView* instance,
+    const char* file_path,
+    const char* file_name) {
+    furi_assert(instance);
+
+    instance->file_path = file_path;
+    instance->file_name = file_name;
+}
+
+void avr_isp_writer_view_draw(Canvas* canvas, AvrIspWriterViewModel* model) {
+    canvas_clear(canvas);
+    char str_flash[32] = {0};
+    char str_eeprom[32] = {0};
+
+    canvas_set_font(canvas, FontPrimary);
+
+    switch(model->status) {
+    case AvrIspWriterViewStatusIDLE:
+        canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Press start to write");
+        canvas_set_font(canvas, FontSecondary);
+        elements_button_center(canvas, "Start");
+        snprintf(str_flash, sizeof(str_flash), "%d%%", (uint8_t)(model->progress_flash * 100));
+        snprintf(str_eeprom, sizeof(str_eeprom), "%d%%", (uint8_t)(model->progress_eeprom * 100));
+        break;
+    case AvrIspWriterViewStatusWriting:
+        if(float_is_equal(model->progress_flash, 0.f)) {
+            canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Verifying firmware");
+            snprintf(str_flash, sizeof(str_flash), "***");
+            snprintf(str_eeprom, sizeof(str_eeprom), "***");
+        } else {
+            canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Writing dump");
+            snprintf(str_flash, sizeof(str_flash), "%d%%", (uint8_t)(model->progress_flash * 100));
+            snprintf(
+                str_eeprom, sizeof(str_eeprom), "%d%%", (uint8_t)(model->progress_eeprom * 100));
+        }
+        break;
+    case AvrIspWriterViewStatusVerification:
+        canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Verifying dump");
+        snprintf(str_flash, sizeof(str_flash), "%d%%", (uint8_t)(model->progress_flash * 100));
+        snprintf(str_eeprom, sizeof(str_eeprom), "%d%%", (uint8_t)(model->progress_eeprom * 100));
+        break;
+    case AvrIspWriterViewStatusWritingFuse:
+        canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Writing fuse");
+        snprintf(str_flash, sizeof(str_flash), "%d%%", (uint8_t)(model->progress_flash * 100));
+        snprintf(str_eeprom, sizeof(str_eeprom), "%d%%", (uint8_t)(model->progress_eeprom * 100));
+        break;
+    case AvrIspWriterViewStatusWritingFuseOk:
+        canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, "Done!");
+        snprintf(str_flash, sizeof(str_flash), "%d%%", (uint8_t)(model->progress_flash * 100));
+        snprintf(str_eeprom, sizeof(str_eeprom), "%d%%", (uint8_t)(model->progress_eeprom * 100));
+        canvas_set_font(canvas, FontSecondary);
+        elements_button_center(canvas, "Reflash");
+        elements_button_right(canvas, "Exit");
+        break;
+
+    default:
+        break;
+    }
+
+    canvas_set_font(canvas, FontSecondary);
+    canvas_draw_str(canvas, 0, 27, "Flash");
+    // snprintf(str_buf, sizeof(str_buf), "%d%%", (uint8_t)(model->progress_flash * 100));
+    elements_progress_bar_with_text(canvas, 44, 17, 84, model->progress_flash, str_flash);
+    canvas_draw_str(canvas, 0, 43, "EEPROM");
+    // snprintf(str_buf, sizeof(str_buf), "%d%%", (uint8_t)(model->progress_eeprom * 100));
+    elements_progress_bar_with_text(canvas, 44, 34, 84, model->progress_eeprom, str_eeprom);
+}
+
+bool avr_isp_writer_view_input(InputEvent* event, void* context) {
+    furi_assert(context);
+    AvrIspWriterView* instance = context;
+
+    bool ret = true;
+    if(event->key == InputKeyBack && event->type == InputTypeShort) {
+        with_view_model(
+            instance->view,
+            AvrIspWriterViewModel * model,
+            {
+                if((model->status == AvrIspWriterViewStatusIDLE) ||
+                   (model->status == AvrIspWriterViewStatusWritingFuseOk)) {
+                    if(instance->callback)
+                        instance->callback(AvrIspCustomEventSceneExit, instance->context);
+                    ret = false;
+                }
+            },
+            false);
+    } else if(event->key == InputKeyOk && event->type == InputTypeShort) {
+        with_view_model(
+            instance->view,
+            AvrIspWriterViewModel * model,
+            {
+                if((model->status == AvrIspWriterViewStatusIDLE) ||
+                   (model->status == AvrIspWriterViewStatusWritingFuseOk)) {
+                    model->status = AvrIspWriterViewStatusWriting;
+
+                    avr_isp_worker_rw_write_dump_start(
+                        instance->avr_isp_worker_rw, instance->file_path, instance->file_name);
+                }
+            },
+            false);
+    } else if(event->key == InputKeyRight && event->type == InputTypeShort) {
+        with_view_model(
+            instance->view,
+            AvrIspWriterViewModel * model,
+            {
+                if((model->status == AvrIspWriterViewStatusIDLE) ||
+                   (model->status == AvrIspWriterViewStatusWritingFuseOk)) {
+                    if(instance->callback)
+                        instance->callback(AvrIspCustomEventSceneExitStartMenu, instance->context);
+                    ret = false;
+                }
+            },
+            false);
+    }
+    return ret;
+}
+
+static void avr_isp_writer_callback_status(void* context, AvrIspWorkerRWStatus status) {
+    furi_assert(context);
+
+    AvrIspWriterView* instance = context;
+    with_view_model(
+        instance->view,
+        AvrIspWriterViewModel * model,
+        {
+            switch(status) {
+            case AvrIspWorkerRWStatusEndWriting:
+                model->status = AvrIspWriterViewStatusVerification;
+                avr_isp_worker_rw_verification_start(
+                    instance->avr_isp_worker_rw, instance->file_path, instance->file_name);
+                model->status = AvrIspWriterViewStatusVerification;
+                break;
+            case AvrIspWorkerRWStatusErrorVerification:
+                if(instance->callback)
+                    instance->callback(AvrIspCustomEventSceneErrorVerification, instance->context);
+                break;
+            case AvrIspWorkerRWStatusEndVerification:
+                avr_isp_worker_rw_write_fuse_start(
+                    instance->avr_isp_worker_rw, instance->file_path, instance->file_name);
+                model->status = AvrIspWriterViewStatusWritingFuse;
+                break;
+            case AvrIspWorkerRWStatusErrorWritingFuse:
+                if(instance->callback)
+                    instance->callback(AvrIspCustomEventSceneErrorWritingFuse, instance->context);
+                break;
+            case AvrIspWorkerRWStatusEndWritingFuse:
+                model->status = AvrIspWriterViewStatusWritingFuseOk;
+                break;
+
+            default:
+                //AvrIspWorkerRWStatusErrorWriting;
+                if(instance->callback)
+                    instance->callback(AvrIspCustomEventSceneErrorWriting, instance->context);
+                break;
+            }
+        },
+        true);
+}
+
+void avr_isp_writer_view_enter(void* context) {
+    furi_assert(context);
+
+    AvrIspWriterView* instance = context;
+    with_view_model(
+        instance->view,
+        AvrIspWriterViewModel * model,
+        {
+            model->status = AvrIspWriterViewStatusIDLE;
+            model->progress_flash = 0.0f;
+            model->progress_eeprom = 0.0f;
+        },
+        true);
+
+    //Start avr_isp_worker_rw
+    instance->avr_isp_worker_rw = avr_isp_worker_rw_alloc(instance->context);
+
+    avr_isp_worker_rw_set_callback_status(
+        instance->avr_isp_worker_rw, avr_isp_writer_callback_status, instance);
+
+    avr_isp_worker_rw_start(instance->avr_isp_worker_rw);
+}
+
+void avr_isp_writer_view_exit(void* context) {
+    furi_assert(context);
+    AvrIspWriterView* instance = context;
+
+    //Stop avr_isp_worker_rw
+    if(avr_isp_worker_rw_is_running(instance->avr_isp_worker_rw)) {
+        avr_isp_worker_rw_stop(instance->avr_isp_worker_rw);
+    }
+
+    avr_isp_worker_rw_free(instance->avr_isp_worker_rw);
+}
+
+AvrIspWriterView* avr_isp_writer_view_alloc() {
+    AvrIspWriterView* instance = malloc(sizeof(AvrIspWriterView));
+
+    // View allocation and configuration
+    instance->view = view_alloc();
+
+    view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(AvrIspWriterViewModel));
+    view_set_context(instance->view, instance);
+    view_set_draw_callback(instance->view, (ViewDrawCallback)avr_isp_writer_view_draw);
+    view_set_input_callback(instance->view, avr_isp_writer_view_input);
+    view_set_enter_callback(instance->view, avr_isp_writer_view_enter);
+    view_set_exit_callback(instance->view, avr_isp_writer_view_exit);
+
+    return instance;
+}
+
+void avr_isp_writer_view_free(AvrIspWriterView* instance) {
+    furi_assert(instance);
+
+    view_free(instance->view);
+    free(instance);
+}
+
+View* avr_isp_writer_view_get_view(AvrIspWriterView* instance) {
+    furi_assert(instance);
+
+    return instance->view;
+}

+ 37 - 0
avr_isp_programmer/views/avr_isp_view_writer.h

@@ -0,0 +1,37 @@
+#pragma once
+
+#include <gui/view.h>
+#include "../helpers/avr_isp_types.h"
+#include "../helpers/avr_isp_event.h"
+
+typedef struct AvrIspWriterView AvrIspWriterView;
+
+typedef void (*AvrIspWriterViewCallback)(AvrIspCustomEvent event, void* context);
+
+typedef enum {
+    AvrIspWriterViewStatusIDLE,
+    AvrIspWriterViewStatusWriting,
+    AvrIspWriterViewStatusVerification,
+    AvrIspWriterViewStatusWritingFuse,
+    AvrIspWriterViewStatusWritingFuseOk,
+} AvrIspWriterViewStatus;
+
+void avr_isp_writer_update_progress(AvrIspWriterView* instance);
+
+void avr_isp_writer_set_file_path(
+    AvrIspWriterView* instance,
+    const char* file_path,
+    const char* file_name);
+
+void avr_isp_writer_view_set_callback(
+    AvrIspWriterView* instance,
+    AvrIspWriterViewCallback callback,
+    void* context);
+
+AvrIspWriterView* avr_isp_writer_view_alloc();
+
+void avr_isp_writer_view_free(AvrIspWriterView* instance);
+
+View* avr_isp_writer_view_get_view(AvrIspWriterView* instance);
+
+void avr_isp_writer_view_exit(void* context);

+ 10 - 0
clock/application.fam

@@ -0,0 +1,10 @@
+App(
+    appid="clock",
+    name="Clock",
+    apptype=FlipperAppType.EXTERNAL,
+    entry_point="clock_app",
+    requires=["gui"],
+    stack_size=2 * 1024,
+    fap_icon="clock.png",
+    fap_category="Tools",
+)

BIN
clock/clock.png


+ 136 - 0
clock/clock_app.c

@@ -0,0 +1,136 @@
+#include <furi.h>
+#include <furi_hal.h>
+
+#include <gui/gui.h>
+#include <locale/locale.h>
+
+typedef enum {
+    ClockEventTypeTick,
+    ClockEventTypeKey,
+} ClockEventType;
+
+typedef struct {
+    ClockEventType type;
+    InputEvent input;
+} ClockEvent;
+
+typedef struct {
+    FuriString* buffer;
+    FuriHalRtcDateTime datetime;
+    LocaleTimeFormat timeformat;
+    LocaleDateFormat dateformat;
+} ClockData;
+
+typedef struct {
+    FuriMutex* mutex;
+    FuriMessageQueue* queue;
+    ClockData* data;
+} Clock;
+
+static void clock_input_callback(InputEvent* input_event, FuriMessageQueue* queue) {
+    furi_assert(queue);
+    ClockEvent event = {.type = ClockEventTypeKey, .input = *input_event};
+    furi_message_queue_put(queue, &event, FuriWaitForever);
+}
+
+static void clock_render_callback(Canvas* canvas, void* ctx) {
+    Clock* clock = ctx;
+    if(furi_mutex_acquire(clock->mutex, 200) != FuriStatusOk) {
+        return;
+    }
+
+    ClockData* data = clock->data;
+
+    canvas_set_font(canvas, FontBigNumbers);
+    locale_format_time(data->buffer, &data->datetime, data->timeformat, true);
+    canvas_draw_str_aligned(
+        canvas, 64, 28, AlignCenter, AlignCenter, furi_string_get_cstr(data->buffer));
+
+    // Special case to cover missing glyphs in FontBigNumbers
+    if(data->timeformat == LocaleTimeFormat12h) {
+        size_t time_width = canvas_string_width(canvas, furi_string_get_cstr(data->buffer));
+        canvas_set_font(canvas, FontPrimary);
+        canvas_draw_str_aligned(
+            canvas,
+            64 + (time_width / 2) - 10,
+            31,
+            AlignLeft,
+            AlignCenter,
+            (data->datetime.hour > 11) ? "PM" : "AM");
+    }
+
+    canvas_set_font(canvas, FontSecondary);
+    locale_format_date(data->buffer, &data->datetime, data->dateformat, "/");
+    canvas_draw_str_aligned(
+        canvas, 64, 42, AlignCenter, AlignTop, furi_string_get_cstr(data->buffer));
+
+    furi_mutex_release(clock->mutex);
+}
+
+static void clock_tick(void* ctx) {
+    furi_assert(ctx);
+    FuriMessageQueue* queue = ctx;
+    ClockEvent event = {.type = ClockEventTypeTick};
+    // It's OK to loose this event if system overloaded
+    furi_message_queue_put(queue, &event, 0);
+}
+
+int32_t clock_app(void* p) {
+    UNUSED(p);
+    Clock* clock = malloc(sizeof(Clock));
+    clock->data = malloc(sizeof(ClockData));
+    clock->data->buffer = furi_string_alloc();
+
+    clock->queue = furi_message_queue_alloc(8, sizeof(ClockEvent));
+    clock->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
+
+    furi_hal_rtc_get_datetime(&clock->data->datetime);
+    clock->data->timeformat = locale_get_time_format();
+    clock->data->dateformat = locale_get_date_format();
+
+    // Set ViewPort callbacks
+    ViewPort* view_port = view_port_alloc();
+    view_port_draw_callback_set(view_port, clock_render_callback, clock);
+    view_port_input_callback_set(view_port, clock_input_callback, clock->queue);
+
+    FuriTimer* timer = furi_timer_alloc(clock_tick, FuriTimerTypePeriodic, clock->queue);
+
+    // Open GUI and register view_port
+    Gui* gui = furi_record_open(RECORD_GUI);
+    gui_add_view_port(gui, view_port, GuiLayerFullscreen);
+
+    furi_timer_start(timer, 100);
+
+    // Main loop
+    ClockEvent event;
+    for(bool processing = true; processing;) {
+        furi_check(furi_message_queue_get(clock->queue, &event, FuriWaitForever) == FuriStatusOk);
+        furi_mutex_acquire(clock->mutex, FuriWaitForever);
+        if(event.type == ClockEventTypeKey) {
+            if(event.input.type == InputTypeShort && event.input.key == InputKeyBack) {
+                processing = false;
+            }
+        } else if(event.type == ClockEventTypeTick) {
+            furi_hal_rtc_get_datetime(&clock->data->datetime);
+        }
+
+        furi_mutex_release(clock->mutex);
+        view_port_update(view_port);
+    }
+
+    furi_timer_free(timer);
+    view_port_enabled_set(view_port, false);
+    gui_remove_view_port(gui, view_port);
+    view_port_free(view_port);
+    furi_record_close(RECORD_GUI);
+
+    furi_message_queue_free(clock->queue);
+    furi_mutex_free(clock->mutex);
+
+    furi_string_free(clock->data->buffer);
+
+    free(clock->data);
+    free(clock);
+
+    return 0;
+}

+ 105 - 0
dap_link/README.md

@@ -0,0 +1,105 @@
+# Flipper Zero as CMSIS DAP/DAP Link
+Flipper Zero as a [Free-DAP](https://github.com/ataradov/free-dap) based SWD\JTAG debugger. Free-DAP is a free and open source firmware implementation of the [CMSIS-DAP](https://www.keil.com/pack/doc/CMSIS_Dev/DAP/html/index.html) debugger.
+
+## Protocols
+SWD, JTAG , CMSIS-DAP v1 (18 KiB/s), CMSIS-DAP v2 (46 KiB/s), VCP (USB-UART).
+
+WinUSB for driverless installation for Windows 8 and above.
+
+## Usage
+
+### VSCode + Cortex-Debug
+  Set `"device": "cmsis-dap"`
+  
+<details>
+  <summary>BluePill configuration example</summary>
+  
+  ```json
+{
+    "name": "Attach (DAP)",
+    "cwd": "${workspaceFolder}",
+    "executable": "./build/firmware.elf",
+    "request": "attach",
+    "type": "cortex-debug",
+    "servertype": "openocd",
+    "device": "cmsis-dap",
+    "configFiles": [
+        "interface/cmsis-dap.cfg",
+        "target/stm32f1x.cfg",
+    ],
+},
+  ```
+</details>
+
+<details>
+  <summary>Flipper Zero configuration example</summary>
+  
+  ```json
+{
+    "name": "Attach (DAP)",
+    "cwd": "${workspaceFolder}",
+    "executable": "./build/latest/firmware.elf",
+    "request": "attach",
+    "type": "cortex-debug",
+    "servertype": "openocd",
+    "device": "cmsis-dap",
+    "svdFile": "./debug/STM32WB55_CM4.svd",
+    "rtos": "FreeRTOS",
+    "configFiles": [
+        "interface/cmsis-dap.cfg",
+        "./debug/stm32wbx.cfg",
+    ],
+    "postAttachCommands": [
+        "source debug/flipperapps.py",
+    ],
+},
+  ```
+</details>
+
+### OpenOCD
+Use `interface/cmsis-dap.cfg`. You will need OpenOCD v0.11.0.
+
+Additional commands: 
+* `cmsis_dap_backend hid` for CMSIS-DAP v1 protocol.
+* `cmsis_dap_backend usb_bulk` for CMSIS-DAP v2 protocol.
+* `cmsis_dap_serial DAP_Oyevoxo` use DAP-Link running on Flipper named `Oyevoxo`.
+* `cmsis-dap cmd 81` - reboot connected DAP-Link.
+
+<details>
+  <summary>Flash BluePill</summary>
+  
+  ```
+openocd -f interface/cmsis-dap.cfg -f target/stm32f1x.cfg -c init -c "program build/firmware.bin reset exit 0x8000000"
+  ```
+</details>
+
+<details>
+  <summary>Flash Flipper Zero using DAP v2 protocol</summary>
+  
+  ```
+openocd -f interface/cmsis-dap.cfg -c "cmsis_dap_backend usb_bulk" -f debug/stm32wbx.cfg -c init -c "program build/latest/firmware.bin reset exit 0x8000000"
+  ```
+</details>
+
+<details>
+  <summary>Reboot connected DAP-Link on Flipper named Oyevoxo</summary>
+  
+  ```
+openocd -f interface/cmsis-dap.cfg -c "cmsis_dap_serial DAP_Oyevoxo" -c "transport select swd" -c "adapter speed 4000000" -c init -c "cmsis-dap cmd 81" -c "exit"
+  ```
+</details>
+
+### PlatformIO
+Use `debug_tool = cmsis-dap` and `upload_protocol = cmsis-dap`. [Documentation](https://docs.platformio.org/en/latest/plus/debug-tools/cmsis-dap.html#debugging-tool-cmsis-dap). Remember that Windows 8 and above do not require drivers.
+
+<details>
+  <summary>BluePill platformio.ini example</summary>
+  
+  ```
+[env:bluepill_f103c8]
+platform = ststm32
+board = bluepill_f103c8
+debug_tool = cmsis-dap
+upload_protocol = cmsis-dap
+  ```
+</details>

+ 24 - 0
dap_link/application.fam

@@ -0,0 +1,24 @@
+App(
+    appid="dap_link",
+    name="DAP Link",
+    apptype=FlipperAppType.EXTERNAL,
+    entry_point="dap_link_app",
+    requires=[
+        "gui",
+        "dialogs",
+    ],
+    stack_size=4 * 1024,
+    order=20,
+    fap_icon="dap_link.png",
+    fap_category="GPIO",
+    fap_private_libs=[
+        Lib(
+            name="free-dap",
+            cincludes=["."],
+            sources=[
+                "dap.c",
+            ],
+        ),
+    ],
+    fap_icon_assets="icons",
+)

+ 234 - 0
dap_link/dap_config.h

@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: BSD-3-Clause
+// Copyright (c) 2022, Alex Taradov <alex@taradov.com>. All rights reserved.
+
+#ifndef _DAP_CONFIG_H_
+#define _DAP_CONFIG_H_
+
+/*- Includes ----------------------------------------------------------------*/
+#include <furi_hal_gpio.h>
+
+/*- Definitions -------------------------------------------------------------*/
+#define DAP_CONFIG_ENABLE_JTAG
+
+#define DAP_CONFIG_DEFAULT_PORT DAP_PORT_SWD
+#define DAP_CONFIG_DEFAULT_CLOCK 4200000 // Hz
+
+#define DAP_CONFIG_PACKET_SIZE 64
+#define DAP_CONFIG_PACKET_COUNT 1
+
+#define DAP_CONFIG_JTAG_DEV_COUNT 8
+
+// DAP_CONFIG_PRODUCT_STR must contain "CMSIS-DAP" to be compatible with the standard
+#define DAP_CONFIG_VENDOR_STR "Flipper Zero"
+#define DAP_CONFIG_PRODUCT_STR "Generic CMSIS-DAP Adapter"
+#define DAP_CONFIG_SER_NUM_STR usb_serial_number
+#define DAP_CONFIG_CMSIS_DAP_VER_STR "2.0.0"
+
+#define DAP_CONFIG_RESET_TARGET_FN dap_app_target_reset
+#define DAP_CONFIG_VENDOR_FN dap_app_vendor_cmd
+
+// Attribute to use for performance-critical functions
+#define DAP_CONFIG_PERFORMANCE_ATTR
+
+// A value at which dap_clock_test() produces 1 kHz output on the SWCLK pin
+// #define DAP_CONFIG_DELAY_CONSTANT 19000
+#define DAP_CONFIG_DELAY_CONSTANT 6290
+
+// A threshold for switching to fast clock (no added delays)
+// This is the frequency produced by dap_clock_test(1) on the SWCLK pin
+#define DAP_CONFIG_FAST_CLOCK 2400000 // Hz
+
+/*- Prototypes --------------------------------------------------------------*/
+extern char usb_serial_number[16];
+
+/*- Implementations ---------------------------------------------------------*/
+extern GpioPin flipper_dap_swclk_pin;
+extern GpioPin flipper_dap_swdio_pin;
+extern GpioPin flipper_dap_reset_pin;
+extern GpioPin flipper_dap_tdo_pin;
+extern GpioPin flipper_dap_tdi_pin;
+
+extern void dap_app_vendor_cmd(uint8_t cmd);
+extern void dap_app_target_reset();
+extern void dap_app_disconnect();
+extern void dap_app_connect_swd();
+extern void dap_app_connect_jtag();
+
+//-----------------------------------------------------------------------------
+static inline void DAP_CONFIG_SWCLK_TCK_write(int value) {
+    furi_hal_gpio_write(&flipper_dap_swclk_pin, value);
+}
+
+//-----------------------------------------------------------------------------
+static inline void DAP_CONFIG_SWDIO_TMS_write(int value) {
+    furi_hal_gpio_write(&flipper_dap_swdio_pin, value);
+}
+
+//-----------------------------------------------------------------------------
+static inline void DAP_CONFIG_TDI_write(int value) {
+#ifdef DAP_CONFIG_ENABLE_JTAG
+    furi_hal_gpio_write(&flipper_dap_tdi_pin, value);
+#else
+    (void)value;
+#endif
+}
+
+//-----------------------------------------------------------------------------
+static inline void DAP_CONFIG_TDO_write(int value) {
+#ifdef DAP_CONFIG_ENABLE_JTAG
+    furi_hal_gpio_write(&flipper_dap_tdo_pin, value);
+#else
+    (void)value;
+#endif
+}
+
+//-----------------------------------------------------------------------------
+static inline void DAP_CONFIG_nTRST_write(int value) {
+    (void)value;
+}
+
+//-----------------------------------------------------------------------------
+static inline void DAP_CONFIG_nRESET_write(int value) {
+    furi_hal_gpio_write(&flipper_dap_reset_pin, value);
+}
+
+//-----------------------------------------------------------------------------
+static inline int DAP_CONFIG_SWCLK_TCK_read(void) {
+    return furi_hal_gpio_read(&flipper_dap_swclk_pin);
+}
+
+//-----------------------------------------------------------------------------
+static inline int DAP_CONFIG_SWDIO_TMS_read(void) {
+    return furi_hal_gpio_read(&flipper_dap_swdio_pin);
+}
+
+//-----------------------------------------------------------------------------
+static inline int DAP_CONFIG_TDO_read(void) {
+#ifdef DAP_CONFIG_ENABLE_JTAG
+    return furi_hal_gpio_read(&flipper_dap_tdo_pin);
+#else
+    return 0;
+#endif
+}
+
+//-----------------------------------------------------------------------------
+static inline int DAP_CONFIG_TDI_read(void) {
+#ifdef DAP_CONFIG_ENABLE_JTAG
+    return furi_hal_gpio_read(&flipper_dap_tdi_pin);
+#else
+    return 0;
+#endif
+}
+
+//-----------------------------------------------------------------------------
+static inline int DAP_CONFIG_nTRST_read(void) {
+    return 0;
+}
+
+//-----------------------------------------------------------------------------
+static inline int DAP_CONFIG_nRESET_read(void) {
+    return furi_hal_gpio_read(&flipper_dap_reset_pin);
+}
+
+//-----------------------------------------------------------------------------
+static inline void DAP_CONFIG_SWCLK_TCK_set(void) {
+    LL_GPIO_SetOutputPin(flipper_dap_swclk_pin.port, flipper_dap_swclk_pin.pin);
+}
+
+//-----------------------------------------------------------------------------
+static inline void DAP_CONFIG_SWCLK_TCK_clr(void) {
+    LL_GPIO_ResetOutputPin(flipper_dap_swclk_pin.port, flipper_dap_swclk_pin.pin);
+}
+
+//-----------------------------------------------------------------------------
+static inline void DAP_CONFIG_SWDIO_TMS_in(void) {
+    LL_GPIO_SetPinMode(flipper_dap_swdio_pin.port, flipper_dap_swdio_pin.pin, LL_GPIO_MODE_INPUT);
+}
+
+//-----------------------------------------------------------------------------
+static inline void DAP_CONFIG_SWDIO_TMS_out(void) {
+    LL_GPIO_SetPinMode(flipper_dap_swdio_pin.port, flipper_dap_swdio_pin.pin, LL_GPIO_MODE_OUTPUT);
+}
+
+//-----------------------------------------------------------------------------
+static inline void DAP_CONFIG_SETUP(void) {
+    furi_hal_gpio_init(&flipper_dap_swdio_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_init(&flipper_dap_swclk_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_init(&flipper_dap_reset_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh);
+#ifdef DAP_CONFIG_ENABLE_JTAG
+    furi_hal_gpio_init(&flipper_dap_tdo_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_init(&flipper_dap_tdi_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+static inline void DAP_CONFIG_DISCONNECT(void) {
+    furi_hal_gpio_init(&flipper_dap_swdio_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_init(&flipper_dap_swclk_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_init(&flipper_dap_reset_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh);
+#ifdef DAP_CONFIG_ENABLE_JTAG
+    furi_hal_gpio_init(&flipper_dap_tdo_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_init(&flipper_dap_tdi_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh);
+#endif
+    dap_app_disconnect();
+}
+
+//-----------------------------------------------------------------------------
+static inline void DAP_CONFIG_CONNECT_SWD(void) {
+    furi_hal_gpio_init(
+        &flipper_dap_swdio_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_write(&flipper_dap_swdio_pin, true);
+
+    furi_hal_gpio_init(
+        &flipper_dap_swclk_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_write(&flipper_dap_swclk_pin, true);
+
+    furi_hal_gpio_init(
+        &flipper_dap_reset_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_write(&flipper_dap_reset_pin, true);
+
+#ifdef DAP_CONFIG_ENABLE_JTAG
+    furi_hal_gpio_init(&flipper_dap_tdo_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_init(&flipper_dap_tdi_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh);
+#endif
+    dap_app_connect_swd();
+}
+
+//-----------------------------------------------------------------------------
+static inline void DAP_CONFIG_CONNECT_JTAG(void) {
+    furi_hal_gpio_init(
+        &flipper_dap_swdio_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_write(&flipper_dap_swdio_pin, true);
+
+    furi_hal_gpio_init(
+        &flipper_dap_swclk_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_write(&flipper_dap_swclk_pin, true);
+
+    furi_hal_gpio_init(
+        &flipper_dap_reset_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_write(&flipper_dap_reset_pin, true);
+
+#ifdef DAP_CONFIG_ENABLE_JTAG
+    furi_hal_gpio_init(&flipper_dap_tdo_pin, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh);
+
+    furi_hal_gpio_init(
+        &flipper_dap_tdi_pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_gpio_write(&flipper_dap_tdi_pin, true);
+#endif
+    dap_app_connect_jtag();
+}
+
+//-----------------------------------------------------------------------------
+static inline void DAP_CONFIG_LED(int index, int state) {
+    (void)index;
+    (void)state;
+}
+
+//-----------------------------------------------------------------------------
+__attribute__((always_inline)) static inline void DAP_CONFIG_DELAY(uint32_t cycles) {
+    asm volatile("1: subs %[cycles], %[cycles], #1 \n"
+                 "   bne 1b \n"
+                 : [cycles] "+l"(cycles));
+}
+
+#endif // _DAP_CONFIG_H_

+ 527 - 0
dap_link/dap_link.c

@@ -0,0 +1,527 @@
+#include <dap.h>
+#include <furi.h>
+#include <furi_hal_version.h>
+#include <furi_hal_gpio.h>
+#include <furi_hal_uart.h>
+#include <furi_hal_console.h>
+#include <furi_hal_resources.h>
+#include <furi_hal_power.h>
+#include <stm32wbxx_ll_usart.h>
+#include <stm32wbxx_ll_lpuart.h>
+
+#include "dap_link.h"
+#include "dap_config.h"
+#include "gui/dap_gui.h"
+#include "usb/dap_v2_usb.h"
+#include <dialogs/dialogs.h>
+#include "dap_link_icons.h"
+
+/***************************************************************************/
+/****************************** DAP COMMON *********************************/
+/***************************************************************************/
+
+struct DapApp {
+    FuriThread* dap_thread;
+    FuriThread* cdc_thread;
+    FuriThread* gui_thread;
+
+    DapState state;
+    DapConfig config;
+};
+
+void dap_app_get_state(DapApp* app, DapState* state) {
+    *state = app->state;
+}
+
+#define DAP_PROCESS_THREAD_TICK 500
+
+typedef enum {
+    DapThreadEventStop = (1 << 0),
+} DapThreadEvent;
+
+void dap_thread_send_stop(FuriThread* thread) {
+    furi_thread_flags_set(furi_thread_get_id(thread), DapThreadEventStop);
+}
+
+GpioPin flipper_dap_swclk_pin;
+GpioPin flipper_dap_swdio_pin;
+GpioPin flipper_dap_reset_pin;
+GpioPin flipper_dap_tdo_pin;
+GpioPin flipper_dap_tdi_pin;
+
+/***************************************************************************/
+/****************************** DAP PROCESS ********************************/
+/***************************************************************************/
+
+typedef struct {
+    uint8_t data[DAP_CONFIG_PACKET_SIZE];
+    uint8_t size;
+} DapPacket;
+
+typedef enum {
+    DAPThreadEventStop = DapThreadEventStop,
+    DAPThreadEventRxV1 = (1 << 1),
+    DAPThreadEventRxV2 = (1 << 2),
+    DAPThreadEventUSBConnect = (1 << 3),
+    DAPThreadEventUSBDisconnect = (1 << 4),
+    DAPThreadEventApplyConfig = (1 << 5),
+    DAPThreadEventAll = DAPThreadEventStop | DAPThreadEventRxV1 | DAPThreadEventRxV2 |
+                        DAPThreadEventUSBConnect | DAPThreadEventUSBDisconnect |
+                        DAPThreadEventApplyConfig,
+} DAPThreadEvent;
+
+#define USB_SERIAL_NUMBER_LEN 16
+char usb_serial_number[USB_SERIAL_NUMBER_LEN] = {0};
+
+const char* dap_app_get_serial(DapApp* app) {
+    UNUSED(app);
+    return usb_serial_number;
+}
+
+static void dap_app_rx1_callback(void* context) {
+    furi_assert(context);
+    FuriThreadId thread_id = (FuriThreadId)context;
+    furi_thread_flags_set(thread_id, DAPThreadEventRxV1);
+}
+
+static void dap_app_rx2_callback(void* context) {
+    furi_assert(context);
+    FuriThreadId thread_id = (FuriThreadId)context;
+    furi_thread_flags_set(thread_id, DAPThreadEventRxV2);
+}
+
+static void dap_app_usb_state_callback(bool state, void* context) {
+    furi_assert(context);
+    FuriThreadId thread_id = (FuriThreadId)context;
+    if(state) {
+        furi_thread_flags_set(thread_id, DAPThreadEventUSBConnect);
+    } else {
+        furi_thread_flags_set(thread_id, DAPThreadEventUSBDisconnect);
+    }
+}
+
+static void dap_app_process_v1() {
+    DapPacket tx_packet;
+    DapPacket rx_packet;
+    memset(&tx_packet, 0, sizeof(DapPacket));
+    rx_packet.size = dap_v1_usb_rx(rx_packet.data, DAP_CONFIG_PACKET_SIZE);
+    dap_process_request(rx_packet.data, rx_packet.size, tx_packet.data, DAP_CONFIG_PACKET_SIZE);
+    dap_v1_usb_tx(tx_packet.data, DAP_CONFIG_PACKET_SIZE);
+}
+
+static void dap_app_process_v2() {
+    DapPacket tx_packet;
+    DapPacket rx_packet;
+    memset(&tx_packet, 0, sizeof(DapPacket));
+    rx_packet.size = dap_v2_usb_rx(rx_packet.data, DAP_CONFIG_PACKET_SIZE);
+    size_t len = dap_process_request(
+        rx_packet.data, rx_packet.size, tx_packet.data, DAP_CONFIG_PACKET_SIZE);
+    dap_v2_usb_tx(tx_packet.data, len);
+}
+
+void dap_app_vendor_cmd(uint8_t cmd) {
+    // openocd -c "cmsis-dap cmd 81"
+    if(cmd == 0x01) {
+        furi_hal_power_reset();
+    }
+}
+
+void dap_app_target_reset() {
+    FURI_LOG_I("DAP", "Target reset");
+}
+
+static void dap_init_gpio(DapSwdPins swd_pins) {
+    switch(swd_pins) {
+    case DapSwdPinsPA7PA6:
+        flipper_dap_swclk_pin = gpio_ext_pa7;
+        flipper_dap_swdio_pin = gpio_ext_pa6;
+        break;
+    case DapSwdPinsPA14PA13:
+        flipper_dap_swclk_pin = (GpioPin){.port = GPIOA, .pin = LL_GPIO_PIN_14};
+        flipper_dap_swdio_pin = (GpioPin){.port = GPIOA, .pin = LL_GPIO_PIN_13};
+        break;
+    }
+
+    flipper_dap_reset_pin = gpio_ext_pa4;
+    flipper_dap_tdo_pin = gpio_ext_pb3;
+    flipper_dap_tdi_pin = gpio_ext_pb2;
+}
+
+static void dap_deinit_gpio(DapSwdPins swd_pins) {
+    // setup gpio pins to default state
+    furi_hal_gpio_init(&flipper_dap_reset_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
+    furi_hal_gpio_init(&flipper_dap_tdo_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
+    furi_hal_gpio_init(&flipper_dap_tdi_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
+
+    if(DapSwdPinsPA14PA13 == swd_pins) {
+        // PA14 and PA13 are used by SWD
+        furi_hal_gpio_init_ex(
+            &flipper_dap_swclk_pin,
+            GpioModeAltFunctionPushPull,
+            GpioPullDown,
+            GpioSpeedLow,
+            GpioAltFn0JTCK_SWCLK);
+        furi_hal_gpio_init_ex(
+            &flipper_dap_swdio_pin,
+            GpioModeAltFunctionPushPull,
+            GpioPullUp,
+            GpioSpeedVeryHigh,
+            GpioAltFn0JTMS_SWDIO);
+    } else {
+        furi_hal_gpio_init(&flipper_dap_swclk_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
+        furi_hal_gpio_init(&flipper_dap_swdio_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
+    }
+}
+
+static int32_t dap_process(void* p) {
+    DapApp* app = p;
+    DapState* dap_state = &(app->state);
+
+    // allocate resources
+    FuriHalUsbInterface* usb_config_prev;
+    app->config.swd_pins = DapSwdPinsPA7PA6;
+    DapSwdPins swd_pins_prev = app->config.swd_pins;
+
+    // init pins
+    dap_init_gpio(swd_pins_prev);
+
+    // init dap
+    dap_init();
+
+    // get name
+    const char* name = furi_hal_version_get_name_ptr();
+    if(!name) {
+        name = "Flipper";
+    }
+    snprintf(usb_serial_number, USB_SERIAL_NUMBER_LEN, "DAP_%s", name);
+
+    // init usb
+    usb_config_prev = furi_hal_usb_get_config();
+    dap_common_usb_alloc_name(usb_serial_number);
+    dap_common_usb_set_context(furi_thread_get_id(furi_thread_get_current()));
+    dap_v1_usb_set_rx_callback(dap_app_rx1_callback);
+    dap_v2_usb_set_rx_callback(dap_app_rx2_callback);
+    dap_common_usb_set_state_callback(dap_app_usb_state_callback);
+    furi_hal_usb_set_config(&dap_v2_usb_hid, NULL);
+
+    // work
+    uint32_t events;
+    while(1) {
+        events = furi_thread_flags_wait(DAPThreadEventAll, FuriFlagWaitAny, FuriWaitForever);
+
+        if(!(events & FuriFlagError)) {
+            if(events & DAPThreadEventRxV1) {
+                dap_app_process_v1();
+                dap_state->dap_counter++;
+                dap_state->dap_version = DapVersionV1;
+            }
+
+            if(events & DAPThreadEventRxV2) {
+                dap_app_process_v2();
+                dap_state->dap_counter++;
+                dap_state->dap_version = DapVersionV2;
+            }
+
+            if(events & DAPThreadEventUSBConnect) {
+                dap_state->usb_connected = true;
+            }
+
+            if(events & DAPThreadEventUSBDisconnect) {
+                dap_state->usb_connected = false;
+                dap_state->dap_version = DapVersionUnknown;
+            }
+
+            if(events & DAPThreadEventApplyConfig) {
+                if(swd_pins_prev != app->config.swd_pins) {
+                    dap_deinit_gpio(swd_pins_prev);
+                    swd_pins_prev = app->config.swd_pins;
+                    dap_init_gpio(swd_pins_prev);
+                }
+            }
+
+            if(events & DAPThreadEventStop) {
+                break;
+            }
+        }
+    }
+
+    // deinit usb
+    furi_hal_usb_set_config(usb_config_prev, NULL);
+    dap_common_usb_free_name();
+    dap_deinit_gpio(swd_pins_prev);
+    return 0;
+}
+
+/***************************************************************************/
+/****************************** CDC PROCESS ********************************/
+/***************************************************************************/
+
+typedef enum {
+    CDCThreadEventStop = DapThreadEventStop,
+    CDCThreadEventUARTRx = (1 << 1),
+    CDCThreadEventCDCRx = (1 << 2),
+    CDCThreadEventCDCConfig = (1 << 3),
+    CDCThreadEventApplyConfig = (1 << 4),
+    CDCThreadEventAll = CDCThreadEventStop | CDCThreadEventUARTRx | CDCThreadEventCDCRx |
+                        CDCThreadEventCDCConfig | CDCThreadEventApplyConfig,
+} CDCThreadEvent;
+
+typedef struct {
+    FuriStreamBuffer* rx_stream;
+    FuriThreadId thread_id;
+    FuriHalUartId uart_id;
+    struct usb_cdc_line_coding line_coding;
+} CDCProcess;
+
+static void cdc_uart_irq_cb(UartIrqEvent ev, uint8_t data, void* ctx) {
+    CDCProcess* app = ctx;
+
+    if(ev == UartIrqEventRXNE) {
+        furi_stream_buffer_send(app->rx_stream, &data, 1, 0);
+        furi_thread_flags_set(app->thread_id, CDCThreadEventUARTRx);
+    }
+}
+
+static void cdc_usb_rx_callback(void* context) {
+    CDCProcess* app = context;
+    furi_thread_flags_set(app->thread_id, CDCThreadEventCDCRx);
+}
+
+static void cdc_usb_control_line_callback(uint8_t state, void* context) {
+    UNUSED(context);
+    UNUSED(state);
+}
+
+static void cdc_usb_config_callback(struct usb_cdc_line_coding* config, void* context) {
+    CDCProcess* app = context;
+    app->line_coding = *config;
+    furi_thread_flags_set(app->thread_id, CDCThreadEventCDCConfig);
+}
+
+static FuriHalUartId cdc_init_uart(
+    DapUartType type,
+    DapUartTXRX swap,
+    uint32_t baudrate,
+    void (*cb)(UartIrqEvent ev, uint8_t data, void* ctx),
+    void* ctx) {
+    FuriHalUartId uart_id = FuriHalUartIdUSART1;
+    if(baudrate == 0) baudrate = 115200;
+
+    switch(type) {
+    case DapUartTypeUSART1:
+        uart_id = FuriHalUartIdUSART1;
+        furi_hal_console_disable();
+        furi_hal_uart_deinit(uart_id);
+        if(swap == DapUartTXRXSwap) {
+            LL_USART_SetTXRXSwap(USART1, LL_USART_TXRX_SWAPPED);
+        } else {
+            LL_USART_SetTXRXSwap(USART1, LL_USART_TXRX_STANDARD);
+        }
+        furi_hal_uart_init(uart_id, baudrate);
+        furi_hal_uart_set_irq_cb(uart_id, cb, ctx);
+        break;
+    case DapUartTypeLPUART1:
+        uart_id = FuriHalUartIdLPUART1;
+        furi_hal_uart_deinit(uart_id);
+        if(swap == DapUartTXRXSwap) {
+            LL_LPUART_SetTXRXSwap(LPUART1, LL_LPUART_TXRX_SWAPPED);
+        } else {
+            LL_LPUART_SetTXRXSwap(LPUART1, LL_LPUART_TXRX_STANDARD);
+        }
+        furi_hal_uart_init(uart_id, baudrate);
+        furi_hal_uart_set_irq_cb(uart_id, cb, ctx);
+        break;
+    }
+
+    return uart_id;
+}
+
+static void cdc_deinit_uart(DapUartType type) {
+    switch(type) {
+    case DapUartTypeUSART1:
+        furi_hal_uart_deinit(FuriHalUartIdUSART1);
+        LL_USART_SetTXRXSwap(USART1, LL_USART_TXRX_STANDARD);
+        furi_hal_console_init();
+        break;
+    case DapUartTypeLPUART1:
+        furi_hal_uart_deinit(FuriHalUartIdLPUART1);
+        LL_LPUART_SetTXRXSwap(LPUART1, LL_LPUART_TXRX_STANDARD);
+        break;
+    }
+}
+
+static int32_t cdc_process(void* p) {
+    DapApp* dap_app = p;
+    DapState* dap_state = &(dap_app->state);
+
+    dap_app->config.uart_pins = DapUartTypeLPUART1;
+    dap_app->config.uart_swap = DapUartTXRXNormal;
+
+    DapUartType uart_pins_prev = dap_app->config.uart_pins;
+    DapUartTXRX uart_swap_prev = dap_app->config.uart_swap;
+
+    CDCProcess* app = malloc(sizeof(CDCProcess));
+    app->thread_id = furi_thread_get_id(furi_thread_get_current());
+    app->rx_stream = furi_stream_buffer_alloc(512, 1);
+
+    const uint8_t rx_buffer_size = 64;
+    uint8_t* rx_buffer = malloc(rx_buffer_size);
+
+    app->uart_id = cdc_init_uart(
+        uart_pins_prev, uart_swap_prev, dap_state->cdc_baudrate, cdc_uart_irq_cb, app);
+
+    dap_cdc_usb_set_context(app);
+    dap_cdc_usb_set_rx_callback(cdc_usb_rx_callback);
+    dap_cdc_usb_set_control_line_callback(cdc_usb_control_line_callback);
+    dap_cdc_usb_set_config_callback(cdc_usb_config_callback);
+
+    uint32_t events;
+    while(1) {
+        events = furi_thread_flags_wait(CDCThreadEventAll, FuriFlagWaitAny, FuriWaitForever);
+
+        if(!(events & FuriFlagError)) {
+            if(events & CDCThreadEventCDCConfig) {
+                if(dap_state->cdc_baudrate != app->line_coding.dwDTERate) {
+                    dap_state->cdc_baudrate = app->line_coding.dwDTERate;
+                    if(dap_state->cdc_baudrate > 0) {
+                        furi_hal_uart_set_br(app->uart_id, dap_state->cdc_baudrate);
+                    }
+                }
+            }
+
+            if(events & CDCThreadEventUARTRx) {
+                size_t len =
+                    furi_stream_buffer_receive(app->rx_stream, rx_buffer, rx_buffer_size, 0);
+
+                if(len > 0) {
+                    dap_cdc_usb_tx(rx_buffer, len);
+                }
+                dap_state->cdc_rx_counter += len;
+            }
+
+            if(events & CDCThreadEventCDCRx) {
+                size_t len = dap_cdc_usb_rx(rx_buffer, rx_buffer_size);
+                if(len > 0) {
+                    furi_hal_uart_tx(app->uart_id, rx_buffer, len);
+                }
+                dap_state->cdc_tx_counter += len;
+            }
+
+            if(events & CDCThreadEventApplyConfig) {
+                if(uart_pins_prev != dap_app->config.uart_pins ||
+                   uart_swap_prev != dap_app->config.uart_swap) {
+                    cdc_deinit_uart(uart_pins_prev);
+                    uart_pins_prev = dap_app->config.uart_pins;
+                    uart_swap_prev = dap_app->config.uart_swap;
+                    app->uart_id = cdc_init_uart(
+                        uart_pins_prev,
+                        uart_swap_prev,
+                        dap_state->cdc_baudrate,
+                        cdc_uart_irq_cb,
+                        app);
+                }
+            }
+
+            if(events & CDCThreadEventStop) {
+                break;
+            }
+        }
+    }
+
+    cdc_deinit_uart(uart_pins_prev);
+    free(rx_buffer);
+    furi_stream_buffer_free(app->rx_stream);
+    free(app);
+
+    return 0;
+}
+
+/***************************************************************************/
+/******************************* MAIN APP **********************************/
+/***************************************************************************/
+
+static DapApp* dap_app_alloc() {
+    DapApp* dap_app = malloc(sizeof(DapApp));
+    dap_app->dap_thread = furi_thread_alloc_ex("DAP Process", 1024, dap_process, dap_app);
+    dap_app->cdc_thread = furi_thread_alloc_ex("DAP CDC", 1024, cdc_process, dap_app);
+    dap_app->gui_thread = furi_thread_alloc_ex("DAP GUI", 1024, dap_gui_thread, dap_app);
+    return dap_app;
+}
+
+static void dap_app_free(DapApp* dap_app) {
+    furi_assert(dap_app);
+    furi_thread_free(dap_app->dap_thread);
+    furi_thread_free(dap_app->cdc_thread);
+    furi_thread_free(dap_app->gui_thread);
+    free(dap_app);
+}
+
+static DapApp* app_handle = NULL;
+
+void dap_app_disconnect() {
+    app_handle->state.dap_mode = DapModeDisconnected;
+}
+
+void dap_app_connect_swd() {
+    app_handle->state.dap_mode = DapModeSWD;
+}
+
+void dap_app_connect_jtag() {
+    app_handle->state.dap_mode = DapModeJTAG;
+}
+
+void dap_app_set_config(DapApp* app, DapConfig* config) {
+    app->config = *config;
+    furi_thread_flags_set(furi_thread_get_id(app->dap_thread), DAPThreadEventApplyConfig);
+    furi_thread_flags_set(furi_thread_get_id(app->cdc_thread), CDCThreadEventApplyConfig);
+}
+
+DapConfig* dap_app_get_config(DapApp* app) {
+    return &app->config;
+}
+
+int32_t dap_link_app(void* p) {
+    UNUSED(p);
+
+    if(furi_hal_usb_is_locked()) {
+        DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
+        DialogMessage* message = dialog_message_alloc();
+        dialog_message_set_header(message, "Connection\nis active!", 3, 2, AlignLeft, AlignTop);
+        dialog_message_set_text(
+            message,
+            "Disconnect from\nPC or phone to\nuse this function.",
+            3,
+            30,
+            AlignLeft,
+            AlignTop);
+        dialog_message_set_icon(message, &I_ActiveConnection_50x64, 78, 0);
+        dialog_message_show(dialogs, message);
+        dialog_message_free(message);
+        furi_record_close(RECORD_DIALOGS);
+        return -1;
+    }
+
+    // alloc app
+    DapApp* app = dap_app_alloc();
+    app_handle = app;
+
+    furi_thread_start(app->dap_thread);
+    furi_thread_start(app->cdc_thread);
+    furi_thread_start(app->gui_thread);
+
+    // wait until gui thread is finished
+    furi_thread_join(app->gui_thread);
+
+    // send stop event to threads
+    dap_thread_send_stop(app->dap_thread);
+    dap_thread_send_stop(app->cdc_thread);
+
+    // wait for threads to stop
+    furi_thread_join(app->dap_thread);
+    furi_thread_join(app->cdc_thread);
+
+    // free app
+    dap_app_free(app);
+
+    return 0;
+}

+ 55 - 0
dap_link/dap_link.h

@@ -0,0 +1,55 @@
+#pragma once
+#include <stdint.h>
+
+typedef enum {
+    DapModeDisconnected,
+    DapModeSWD,
+    DapModeJTAG,
+} DapMode;
+
+typedef enum {
+    DapVersionUnknown,
+    DapVersionV1,
+    DapVersionV2,
+} DapVersion;
+
+typedef struct {
+    bool usb_connected;
+    DapMode dap_mode;
+    DapVersion dap_version;
+    uint32_t dap_counter;
+    uint32_t cdc_baudrate;
+    uint32_t cdc_tx_counter;
+    uint32_t cdc_rx_counter;
+} DapState;
+
+typedef enum {
+    DapSwdPinsPA7PA6, // Pins 2, 3
+    DapSwdPinsPA14PA13, // Pins 10, 12
+} DapSwdPins;
+
+typedef enum {
+    DapUartTypeUSART1, // Pins 13, 14
+    DapUartTypeLPUART1, // Pins 15, 16
+} DapUartType;
+
+typedef enum {
+    DapUartTXRXNormal,
+    DapUartTXRXSwap,
+} DapUartTXRX;
+
+typedef struct {
+    DapSwdPins swd_pins;
+    DapUartType uart_pins;
+    DapUartTXRX uart_swap;
+} DapConfig;
+
+typedef struct DapApp DapApp;
+
+void dap_app_get_state(DapApp* app, DapState* state);
+
+const char* dap_app_get_serial(DapApp* app);
+
+void dap_app_set_config(DapApp* app, DapConfig* config);
+
+DapConfig* dap_app_get_config(DapApp* app);

BIN
dap_link/dap_link.png


+ 92 - 0
dap_link/gui/dap_gui.c

@@ -0,0 +1,92 @@
+#include "dap_gui.h"
+#include "dap_gui_i.h"
+
+#define DAP_GUI_TICK 250
+
+static bool dap_gui_custom_event_callback(void* context, uint32_t event) {
+    furi_assert(context);
+    DapGuiApp* app = context;
+    return scene_manager_handle_custom_event(app->scene_manager, event);
+}
+
+static bool dap_gui_back_event_callback(void* context) {
+    furi_assert(context);
+    DapGuiApp* app = context;
+    return scene_manager_handle_back_event(app->scene_manager);
+}
+
+static void dap_gui_tick_event_callback(void* context) {
+    furi_assert(context);
+    DapGuiApp* app = context;
+    scene_manager_handle_tick_event(app->scene_manager);
+}
+
+DapGuiApp* dap_gui_alloc() {
+    DapGuiApp* app = malloc(sizeof(DapGuiApp));
+    app->gui = furi_record_open(RECORD_GUI);
+    app->view_dispatcher = view_dispatcher_alloc();
+    app->scene_manager = scene_manager_alloc(&dap_scene_handlers, app);
+    view_dispatcher_enable_queue(app->view_dispatcher);
+    view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
+
+    view_dispatcher_set_custom_event_callback(app->view_dispatcher, dap_gui_custom_event_callback);
+    view_dispatcher_set_navigation_event_callback(
+        app->view_dispatcher, dap_gui_back_event_callback);
+    view_dispatcher_set_tick_event_callback(
+        app->view_dispatcher, dap_gui_tick_event_callback, DAP_GUI_TICK);
+
+    view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
+
+    app->notifications = furi_record_open(RECORD_NOTIFICATION);
+
+    app->var_item_list = variable_item_list_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher,
+        DapGuiAppViewVarItemList,
+        variable_item_list_get_view(app->var_item_list));
+
+    app->main_view = dap_main_view_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher, DapGuiAppViewMainView, dap_main_view_get_view(app->main_view));
+
+    app->widget = widget_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher, DapGuiAppViewWidget, widget_get_view(app->widget));
+
+    scene_manager_next_scene(app->scene_manager, DapSceneMain);
+
+    return app;
+}
+
+void dap_gui_free(DapGuiApp* app) {
+    view_dispatcher_remove_view(app->view_dispatcher, DapGuiAppViewVarItemList);
+    variable_item_list_free(app->var_item_list);
+
+    view_dispatcher_remove_view(app->view_dispatcher, DapGuiAppViewMainView);
+    dap_main_view_free(app->main_view);
+
+    view_dispatcher_remove_view(app->view_dispatcher, DapGuiAppViewWidget);
+    widget_free(app->widget);
+
+    // View dispatcher
+    view_dispatcher_free(app->view_dispatcher);
+    scene_manager_free(app->scene_manager);
+
+    // Close records
+    furi_record_close(RECORD_GUI);
+    furi_record_close(RECORD_NOTIFICATION);
+
+    free(app);
+}
+
+int32_t dap_gui_thread(void* arg) {
+    DapGuiApp* app = dap_gui_alloc();
+    app->dap_app = arg;
+
+    notification_message_block(app->notifications, &sequence_display_backlight_enforce_on);
+    view_dispatcher_run(app->view_dispatcher);
+    notification_message_block(app->notifications, &sequence_display_backlight_enforce_auto);
+
+    dap_gui_free(app);
+    return 0;
+}

+ 4 - 0
dap_link/gui/dap_gui.h

@@ -0,0 +1,4 @@
+#pragma once
+#include <stdint.h>
+
+int32_t dap_gui_thread(void* arg);

+ 7 - 0
dap_link/gui/dap_gui_custom_event.h

@@ -0,0 +1,7 @@
+#pragma once
+
+typedef enum {
+    DapAppCustomEventConfig,
+    DapAppCustomEventHelp,
+    DapAppCustomEventAbout,
+} DapAppCustomEvent;

+ 34 - 0
dap_link/gui/dap_gui_i.h

@@ -0,0 +1,34 @@
+#pragma once
+
+#include <gui/gui.h>
+#include <gui/view_dispatcher.h>
+#include <gui/scene_manager.h>
+#include <gui/modules/submenu.h>
+#include <notification/notification_messages.h>
+#include <gui/modules/variable_item_list.h>
+#include <gui/modules/widget.h>
+
+#include "dap_gui.h"
+#include "../dap_link.h"
+#include "scenes/config/dap_scene.h"
+#include "dap_gui_custom_event.h"
+#include "views/dap_main_view.h"
+
+typedef struct {
+    DapApp* dap_app;
+
+    Gui* gui;
+    NotificationApp* notifications;
+    ViewDispatcher* view_dispatcher;
+    SceneManager* scene_manager;
+
+    VariableItemList* var_item_list;
+    DapMainView* main_view;
+    Widget* widget;
+} DapGuiApp;
+
+typedef enum {
+    DapGuiAppViewVarItemList,
+    DapGuiAppViewMainView,
+    DapGuiAppViewWidget,
+} DapGuiAppView;

+ 30 - 0
dap_link/gui/scenes/config/dap_scene.c

@@ -0,0 +1,30 @@
+#include "dap_scene.h"
+
+// Generate scene on_enter handlers array
+#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
+void (*const dap_scene_on_enter_handlers[])(void*) = {
+#include "dap_scene_config.h"
+};
+#undef ADD_SCENE
+
+// Generate scene on_event handlers array
+#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
+bool (*const dap_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = {
+#include "dap_scene_config.h"
+};
+#undef ADD_SCENE
+
+// Generate scene on_exit handlers array
+#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
+void (*const dap_scene_on_exit_handlers[])(void* context) = {
+#include "dap_scene_config.h"
+};
+#undef ADD_SCENE
+
+// Initialize scene handlers configuration structure
+const SceneManagerHandlers dap_scene_handlers = {
+    .on_enter_handlers = dap_scene_on_enter_handlers,
+    .on_event_handlers = dap_scene_on_event_handlers,
+    .on_exit_handlers = dap_scene_on_exit_handlers,
+    .scene_num = DapSceneNum,
+};

+ 29 - 0
dap_link/gui/scenes/config/dap_scene.h

@@ -0,0 +1,29 @@
+#pragma once
+
+#include <gui/scene_manager.h>
+
+// Generate scene id and total number
+#define ADD_SCENE(prefix, name, id) DapScene##id,
+typedef enum {
+#include "dap_scene_config.h"
+    DapSceneNum,
+} DapScene;
+#undef ADD_SCENE
+
+extern const SceneManagerHandlers dap_scene_handlers;
+
+// Generate scene on_enter handlers declaration
+#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
+#include "dap_scene_config.h"
+#undef ADD_SCENE
+
+// Generate scene on_event handlers declaration
+#define ADD_SCENE(prefix, name, id) \
+    bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
+#include "dap_scene_config.h"
+#undef ADD_SCENE
+
+// Generate scene on_exit handlers declaration
+#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
+#include "dap_scene_config.h"
+#undef ADD_SCENE

+ 4 - 0
dap_link/gui/scenes/config/dap_scene_config.h

@@ -0,0 +1,4 @@
+ADD_SCENE(dap, main, Main)
+ADD_SCENE(dap, config, Config)
+ADD_SCENE(dap, help, Help)
+ADD_SCENE(dap, about, About)

+ 68 - 0
dap_link/gui/scenes/dap_scene_about.c

@@ -0,0 +1,68 @@
+#include "../dap_gui_i.h"
+
+#define DAP_VERSION_APP "0.1.0"
+#define DAP_DEVELOPED "Dr_Zlo"
+#define DAP_GITHUB "https://github.com/flipperdevices/flipperzero-firmware"
+
+void dap_scene_about_on_enter(void* context) {
+    DapGuiApp* app = context;
+
+    FuriString* temp_str;
+    temp_str = furi_string_alloc();
+    furi_string_printf(temp_str, "\e#%s\n", "Information");
+
+    furi_string_cat_printf(temp_str, "Version: %s\n", DAP_VERSION_APP);
+    furi_string_cat_printf(temp_str, "Developed by: %s\n", DAP_DEVELOPED);
+    furi_string_cat_printf(temp_str, "Github: %s\n\n", DAP_GITHUB);
+
+    furi_string_cat_printf(temp_str, "\e#%s\n", "Description");
+    furi_string_cat_printf(
+        temp_str, "CMSIS-DAP debugger\nbased on Free-DAP\nThanks to Alex Taradov\n\n");
+
+    furi_string_cat_printf(
+        temp_str,
+        "Supported protocols:\n"
+        "SWD, JTAG, UART\n"
+        "DAP v1 (cmsis_backend hid), DAP v2 (cmsis_backend usb_bulk), VCP\n");
+
+    widget_add_text_box_element(
+        app->widget,
+        0,
+        0,
+        128,
+        14,
+        AlignCenter,
+        AlignBottom,
+        "\e#\e!                                                      \e!\n",
+        false);
+    widget_add_text_box_element(
+        app->widget,
+        0,
+        2,
+        128,
+        14,
+        AlignCenter,
+        AlignBottom,
+        "\e#\e!              DAP Link              \e!\n",
+        false);
+    widget_add_text_scroll_element(app->widget, 0, 16, 128, 50, furi_string_get_cstr(temp_str));
+    furi_string_free(temp_str);
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, DapGuiAppViewWidget);
+}
+
+bool dap_scene_about_on_event(void* context, SceneManagerEvent event) {
+    DapGuiApp* app = context;
+    bool consumed = false;
+    UNUSED(app);
+    UNUSED(event);
+
+    return consumed;
+}
+
+void dap_scene_about_on_exit(void* context) {
+    DapGuiApp* app = context;
+
+    // Clear views
+    widget_reset(app->widget);
+}

+ 107 - 0
dap_link/gui/scenes/dap_scene_config.c

@@ -0,0 +1,107 @@
+#include "../dap_gui_i.h"
+
+static const char* swd_pins[] = {[DapSwdPinsPA7PA6] = "2,3", [DapSwdPinsPA14PA13] = "10,12"};
+static const char* uart_pins[] = {[DapUartTypeUSART1] = "13,14", [DapUartTypeLPUART1] = "15,16"};
+static const char* uart_swap[] = {[DapUartTXRXNormal] = "No", [DapUartTXRXSwap] = "Yes"};
+
+static void swd_pins_cb(VariableItem* item) {
+    DapGuiApp* app = variable_item_get_context(item);
+    uint8_t index = variable_item_get_current_value_index(item);
+
+    variable_item_set_current_value_text(item, swd_pins[index]);
+
+    DapConfig* config = dap_app_get_config(app->dap_app);
+    config->swd_pins = index;
+    dap_app_set_config(app->dap_app, config);
+}
+
+static void uart_pins_cb(VariableItem* item) {
+    DapGuiApp* app = variable_item_get_context(item);
+    uint8_t index = variable_item_get_current_value_index(item);
+
+    variable_item_set_current_value_text(item, uart_pins[index]);
+
+    DapConfig* config = dap_app_get_config(app->dap_app);
+    config->uart_pins = index;
+    dap_app_set_config(app->dap_app, config);
+}
+
+static void uart_swap_cb(VariableItem* item) {
+    DapGuiApp* app = variable_item_get_context(item);
+    uint8_t index = variable_item_get_current_value_index(item);
+
+    variable_item_set_current_value_text(item, uart_swap[index]);
+
+    DapConfig* config = dap_app_get_config(app->dap_app);
+    config->uart_swap = index;
+    dap_app_set_config(app->dap_app, config);
+}
+
+static void ok_cb(void* context, uint32_t index) {
+    DapGuiApp* app = context;
+    switch(index) {
+    case 3:
+        view_dispatcher_send_custom_event(app->view_dispatcher, DapAppCustomEventHelp);
+        break;
+    case 4:
+        view_dispatcher_send_custom_event(app->view_dispatcher, DapAppCustomEventAbout);
+        break;
+    default:
+        break;
+    }
+}
+
+void dap_scene_config_on_enter(void* context) {
+    DapGuiApp* app = context;
+    VariableItemList* var_item_list = app->var_item_list;
+    VariableItem* item;
+    DapConfig* config = dap_app_get_config(app->dap_app);
+
+    item = variable_item_list_add(
+        var_item_list, "SWC SWD Pins", COUNT_OF(swd_pins), swd_pins_cb, app);
+    variable_item_set_current_value_index(item, config->swd_pins);
+    variable_item_set_current_value_text(item, swd_pins[config->swd_pins]);
+
+    item =
+        variable_item_list_add(var_item_list, "UART Pins", COUNT_OF(uart_pins), uart_pins_cb, app);
+    variable_item_set_current_value_index(item, config->uart_pins);
+    variable_item_set_current_value_text(item, uart_pins[config->uart_pins]);
+
+    item = variable_item_list_add(
+        var_item_list, "Swap TX RX", COUNT_OF(uart_swap), uart_swap_cb, app);
+    variable_item_set_current_value_index(item, config->uart_swap);
+    variable_item_set_current_value_text(item, uart_swap[config->uart_swap]);
+
+    variable_item_list_add(var_item_list, "Help and Pinout", 0, NULL, NULL);
+    variable_item_list_add(var_item_list, "About", 0, NULL, NULL);
+
+    variable_item_list_set_selected_item(
+        var_item_list, scene_manager_get_scene_state(app->scene_manager, DapSceneConfig));
+
+    variable_item_list_set_enter_callback(var_item_list, ok_cb, app);
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, DapGuiAppViewVarItemList);
+}
+
+bool dap_scene_config_on_event(void* context, SceneManagerEvent event) {
+    DapGuiApp* app = context;
+    if(event.type == SceneManagerEventTypeCustom) {
+        if(event.event == DapAppCustomEventHelp) {
+            scene_manager_next_scene(app->scene_manager, DapSceneHelp);
+            return true;
+        } else if(event.event == DapAppCustomEventAbout) {
+            scene_manager_next_scene(app->scene_manager, DapSceneAbout);
+            return true;
+        }
+    }
+    return false;
+}
+
+void dap_scene_config_on_exit(void* context) {
+    DapGuiApp* app = context;
+    scene_manager_set_scene_state(
+        app->scene_manager,
+        DapSceneConfig,
+        variable_item_list_get_selected_item_index(app->var_item_list));
+    variable_item_list_reset(app->var_item_list);
+}

+ 102 - 0
dap_link/gui/scenes/dap_scene_help.c

@@ -0,0 +1,102 @@
+#include "../dap_gui_i.h"
+
+void dap_scene_help_on_enter(void* context) {
+    DapGuiApp* app = context;
+    DapConfig* config = dap_app_get_config(app->dap_app);
+    FuriString* string = furi_string_alloc();
+
+    furi_string_cat(string, "CMSIS DAP/DAP Link v2\r\n");
+    furi_string_cat_printf(string, "Serial: %s\r\n", dap_app_get_serial(app->dap_app));
+    furi_string_cat(
+        string,
+        "Pinout:\r\n"
+        "\e#SWD:\r\n");
+
+    switch(config->swd_pins) {
+    case DapSwdPinsPA7PA6:
+        furi_string_cat(
+            string,
+            "    SWC: 2 [A7]\r\n"
+            "    SWD: 3 [A6]\r\n");
+        break;
+    case DapSwdPinsPA14PA13:
+        furi_string_cat(
+            string,
+            "    SWC: 10 [SWC]\r\n"
+            "    SWD: 12 [SIO]\r\n");
+        break;
+    default:
+        break;
+    }
+
+    furi_string_cat(string, "\e#JTAG:\r\n");
+    switch(config->swd_pins) {
+    case DapSwdPinsPA7PA6:
+        furi_string_cat(
+            string,
+            "    TCK: 2 [A7]\r\n"
+            "    TMS: 3 [A6]\r\n"
+            "    RST: 4 [A4]\r\n"
+            "    TDO: 5 [B3]\r\n"
+            "    TDI: 6 [B2]\r\n");
+        break;
+    case DapSwdPinsPA14PA13:
+        furi_string_cat(
+            string,
+            "    RST: 4 [A4]\r\n"
+            "    TDO: 5 [B3]\r\n"
+            "    TDI: 6 [B2]\r\n"
+            "    TCK: 10 [SWC]\r\n"
+            "    TMS: 12 [SIO]\r\n");
+        break;
+    default:
+        break;
+    }
+
+    furi_string_cat(string, "\e#UART:\r\n");
+    switch(config->uart_pins) {
+    case DapUartTypeUSART1:
+        if(config->uart_swap == DapUartTXRXNormal) {
+            furi_string_cat(
+                string,
+                "    TX: 13 [TX]\r\n"
+                "    RX: 14 [RX]\r\n");
+        } else {
+            furi_string_cat(
+                string,
+                "    RX: 13 [TX]\r\n"
+                "    TX: 14 [RX]\r\n");
+        }
+        break;
+    case DapUartTypeLPUART1:
+        if(config->uart_swap == DapUartTXRXNormal) {
+            furi_string_cat(
+                string,
+                "    TX: 15 [C1]\r\n"
+                "    RX: 16 [C0]\r\n");
+        } else {
+            furi_string_cat(
+                string,
+                "    RX: 15 [C1]\r\n"
+                "    TX: 16 [C0]\r\n");
+        }
+        break;
+    default:
+        break;
+    }
+
+    widget_add_text_scroll_element(app->widget, 0, 0, 128, 64, furi_string_get_cstr(string));
+    furi_string_free(string);
+    view_dispatcher_switch_to_view(app->view_dispatcher, DapGuiAppViewWidget);
+}
+
+bool dap_scene_help_on_event(void* context, SceneManagerEvent event) {
+    UNUSED(context);
+    UNUSED(event);
+    return false;
+}
+
+void dap_scene_help_on_exit(void* context) {
+    DapGuiApp* app = context;
+    widget_reset(app->widget);
+}

+ 154 - 0
dap_link/gui/scenes/dap_scene_main.c

@@ -0,0 +1,154 @@
+#include "../dap_gui_i.h"
+#include "../../dap_link.h"
+
+typedef struct {
+    DapState dap_state;
+    bool dap_active;
+    bool tx_active;
+    bool rx_active;
+} DapSceneMainState;
+
+static bool process_dap_state(DapGuiApp* app) {
+    DapSceneMainState* state =
+        (DapSceneMainState*)scene_manager_get_scene_state(app->scene_manager, DapSceneMain);
+    if(state == NULL) return true;
+
+    DapState* prev_state = &state->dap_state;
+    DapState next_state;
+    dap_app_get_state(app->dap_app, &next_state);
+    bool need_to_update = false;
+
+    if(prev_state->dap_mode != next_state.dap_mode) {
+        switch(next_state.dap_mode) {
+        case DapModeDisconnected:
+            dap_main_view_set_mode(app->main_view, DapMainViewModeDisconnected);
+            notification_message(app->notifications, &sequence_blink_stop);
+            break;
+        case DapModeSWD:
+            dap_main_view_set_mode(app->main_view, DapMainViewModeSWD);
+            notification_message(app->notifications, &sequence_blink_start_blue);
+            break;
+        case DapModeJTAG:
+            dap_main_view_set_mode(app->main_view, DapMainViewModeJTAG);
+            notification_message(app->notifications, &sequence_blink_start_magenta);
+            break;
+        }
+        need_to_update = true;
+    }
+
+    if(prev_state->dap_version != next_state.dap_version) {
+        switch(next_state.dap_version) {
+        case DapVersionUnknown:
+            dap_main_view_set_version(app->main_view, DapMainViewVersionUnknown);
+            break;
+        case DapVersionV1:
+            dap_main_view_set_version(app->main_view, DapMainViewVersionV1);
+            break;
+        case DapVersionV2:
+            dap_main_view_set_version(app->main_view, DapMainViewVersionV2);
+            break;
+        }
+        need_to_update = true;
+    }
+
+    if(prev_state->usb_connected != next_state.usb_connected) {
+        dap_main_view_set_usb_connected(app->main_view, next_state.usb_connected);
+        need_to_update = true;
+    }
+
+    if(prev_state->dap_counter != next_state.dap_counter) {
+        if(!state->dap_active) {
+            state->dap_active = true;
+            dap_main_view_set_dap(app->main_view, state->dap_active);
+            need_to_update = true;
+        }
+    } else {
+        if(state->dap_active) {
+            state->dap_active = false;
+            dap_main_view_set_dap(app->main_view, state->dap_active);
+            need_to_update = true;
+        }
+    }
+
+    if(prev_state->cdc_baudrate != next_state.cdc_baudrate) {
+        dap_main_view_set_baudrate(app->main_view, next_state.cdc_baudrate);
+        need_to_update = true;
+    }
+
+    if(prev_state->cdc_tx_counter != next_state.cdc_tx_counter) {
+        if(!state->tx_active) {
+            state->tx_active = true;
+            dap_main_view_set_tx(app->main_view, state->tx_active);
+            need_to_update = true;
+            notification_message(app->notifications, &sequence_blink_start_red);
+        }
+    } else {
+        if(state->tx_active) {
+            state->tx_active = false;
+            dap_main_view_set_tx(app->main_view, state->tx_active);
+            need_to_update = true;
+            notification_message(app->notifications, &sequence_blink_stop);
+        }
+    }
+
+    if(prev_state->cdc_rx_counter != next_state.cdc_rx_counter) {
+        if(!state->rx_active) {
+            state->rx_active = true;
+            dap_main_view_set_rx(app->main_view, state->rx_active);
+            need_to_update = true;
+            notification_message(app->notifications, &sequence_blink_start_green);
+        }
+    } else {
+        if(state->rx_active) {
+            state->rx_active = false;
+            dap_main_view_set_rx(app->main_view, state->rx_active);
+            need_to_update = true;
+            notification_message(app->notifications, &sequence_blink_stop);
+        }
+    }
+
+    if(need_to_update) {
+        dap_main_view_update(app->main_view);
+    }
+
+    *prev_state = next_state;
+    return true;
+}
+
+static void dap_scene_main_on_left(void* context) {
+    DapGuiApp* app = (DapGuiApp*)context;
+    view_dispatcher_send_custom_event(app->view_dispatcher, DapAppCustomEventConfig);
+}
+
+void dap_scene_main_on_enter(void* context) {
+    DapGuiApp* app = context;
+    DapSceneMainState* state = malloc(sizeof(DapSceneMainState));
+    dap_main_view_set_left_callback(app->main_view, dap_scene_main_on_left, app);
+    view_dispatcher_switch_to_view(app->view_dispatcher, DapGuiAppViewMainView);
+    scene_manager_set_scene_state(app->scene_manager, DapSceneMain, (uint32_t)state);
+}
+
+bool dap_scene_main_on_event(void* context, SceneManagerEvent event) {
+    DapGuiApp* app = context;
+
+    if(event.type == SceneManagerEventTypeCustom) {
+        if(event.event == DapAppCustomEventConfig) {
+            scene_manager_next_scene(app->scene_manager, DapSceneConfig);
+            return true;
+        }
+    } else if(event.type == SceneManagerEventTypeTick) {
+        return process_dap_state(app);
+    }
+
+    return false;
+}
+
+void dap_scene_main_on_exit(void* context) {
+    DapGuiApp* app = context;
+    DapSceneMainState* state =
+        (DapSceneMainState*)scene_manager_get_scene_state(app->scene_manager, DapSceneMain);
+    scene_manager_set_scene_state(app->scene_manager, DapSceneMain, (uint32_t)NULL);
+    FURI_SW_MEMBARRIER();
+    free(state);
+    notification_message(app->notifications, &sequence_blink_stop);
+}

+ 189 - 0
dap_link/gui/views/dap_main_view.c

@@ -0,0 +1,189 @@
+#include "dap_main_view.h"
+#include "dap_link_icons.h"
+#include <gui/elements.h>
+
+// extern const Icon I_ArrowDownEmpty_12x18;
+// extern const Icon I_ArrowDownFilled_12x18;
+// extern const Icon I_ArrowUpEmpty_12x18;
+// extern const Icon I_ArrowUpFilled_12x18;
+
+struct DapMainView {
+    View* view;
+    DapMainViewButtonCallback cb_left;
+    void* cb_context;
+};
+
+typedef struct {
+    DapMainViewMode mode;
+    DapMainViewVersion version;
+    bool usb_connected;
+    uint32_t baudrate;
+    bool dap_active;
+    bool tx_active;
+    bool rx_active;
+} DapMainViewModel;
+
+static void dap_main_view_draw_callback(Canvas* canvas, void* _model) {
+    DapMainViewModel* model = _model;
+    UNUSED(model);
+    canvas_clear(canvas);
+    elements_button_left(canvas, "Config");
+
+    canvas_set_color(canvas, ColorBlack);
+    canvas_draw_box(canvas, 0, 0, 127, 11);
+    canvas_set_color(canvas, ColorWhite);
+
+    const char* header_string;
+    if(model->usb_connected) {
+        if(model->version == DapMainViewVersionV1) {
+            header_string = "DAP Link V1 Connected";
+        } else if(model->version == DapMainViewVersionV2) {
+            header_string = "DAP Link V2 Connected";
+        } else {
+            header_string = "DAP Link Connected";
+        }
+    } else {
+        header_string = "DAP Link";
+    }
+
+    canvas_draw_str_aligned(canvas, 64, 9, AlignCenter, AlignBottom, header_string);
+
+    canvas_set_color(canvas, ColorBlack);
+    if(model->dap_active) {
+        canvas_draw_icon(canvas, 14, 16, &I_ArrowUpFilled_12x18);
+        canvas_draw_icon_ex(canvas, 28, 16, &I_ArrowUpFilled_12x18, IconRotation180);
+    } else {
+        canvas_draw_icon(canvas, 14, 16, &I_ArrowUpEmpty_12x18);
+        canvas_draw_icon_ex(canvas, 28, 16, &I_ArrowUpEmpty_12x18, IconRotation180);
+    }
+
+    switch(model->mode) {
+    case DapMainViewModeDisconnected:
+        canvas_draw_str_aligned(canvas, 26, 38, AlignCenter, AlignTop, "----");
+        break;
+    case DapMainViewModeSWD:
+        canvas_draw_str_aligned(canvas, 26, 38, AlignCenter, AlignTop, "SWD");
+        break;
+    case DapMainViewModeJTAG:
+        canvas_draw_str_aligned(canvas, 26, 38, AlignCenter, AlignTop, "JTAG");
+        break;
+    }
+
+    if(model->tx_active) {
+        canvas_draw_icon(canvas, 87, 16, &I_ArrowUpFilled_12x18);
+    } else {
+        canvas_draw_icon(canvas, 87, 16, &I_ArrowUpEmpty_12x18);
+    }
+
+    if(model->rx_active) {
+        canvas_draw_icon_ex(canvas, 101, 16, &I_ArrowUpFilled_12x18, IconRotation180);
+    } else {
+        canvas_draw_icon_ex(canvas, 101, 16, &I_ArrowUpEmpty_12x18, IconRotation180);
+    }
+
+    canvas_draw_str_aligned(canvas, 100, 38, AlignCenter, AlignTop, "UART");
+
+    canvas_draw_line(canvas, 44, 52, 123, 52);
+    if(model->baudrate == 0) {
+        canvas_draw_str(canvas, 45, 62, "Baud: ????");
+    } else {
+        char baudrate_str[18];
+        snprintf(baudrate_str, 18, "Baud: %lu", model->baudrate);
+        canvas_draw_str(canvas, 45, 62, baudrate_str);
+    }
+}
+
+static bool dap_main_view_input_callback(InputEvent* event, void* context) {
+    furi_assert(context);
+    DapMainView* dap_main_view = context;
+    bool consumed = false;
+
+    if(event->type == InputTypeShort) {
+        if(event->key == InputKeyLeft) {
+            if(dap_main_view->cb_left) {
+                dap_main_view->cb_left(dap_main_view->cb_context);
+            }
+            consumed = true;
+        }
+    }
+
+    return consumed;
+}
+
+DapMainView* dap_main_view_alloc() {
+    DapMainView* dap_main_view = malloc(sizeof(DapMainView));
+
+    dap_main_view->view = view_alloc();
+    view_allocate_model(dap_main_view->view, ViewModelTypeLocking, sizeof(DapMainViewModel));
+    view_set_context(dap_main_view->view, dap_main_view);
+    view_set_draw_callback(dap_main_view->view, dap_main_view_draw_callback);
+    view_set_input_callback(dap_main_view->view, dap_main_view_input_callback);
+    return dap_main_view;
+}
+
+void dap_main_view_free(DapMainView* dap_main_view) {
+    view_free(dap_main_view->view);
+    free(dap_main_view);
+}
+
+View* dap_main_view_get_view(DapMainView* dap_main_view) {
+    return dap_main_view->view;
+}
+
+void dap_main_view_set_left_callback(
+    DapMainView* dap_main_view,
+    DapMainViewButtonCallback callback,
+    void* context) {
+    with_view_model(
+        dap_main_view->view,
+        DapMainViewModel * model,
+        {
+            UNUSED(model);
+            dap_main_view->cb_left = callback;
+            dap_main_view->cb_context = context;
+        },
+        true);
+}
+
+void dap_main_view_set_mode(DapMainView* dap_main_view, DapMainViewMode mode) {
+    with_view_model(
+        dap_main_view->view, DapMainViewModel * model, { model->mode = mode; }, false);
+}
+
+void dap_main_view_set_dap(DapMainView* dap_main_view, bool active) {
+    with_view_model(
+        dap_main_view->view, DapMainViewModel * model, { model->dap_active = active; }, false);
+}
+
+void dap_main_view_set_tx(DapMainView* dap_main_view, bool active) {
+    with_view_model(
+        dap_main_view->view, DapMainViewModel * model, { model->tx_active = active; }, false);
+}
+
+void dap_main_view_set_rx(DapMainView* dap_main_view, bool active) {
+    with_view_model(
+        dap_main_view->view, DapMainViewModel * model, { model->rx_active = active; }, false);
+}
+
+void dap_main_view_set_baudrate(DapMainView* dap_main_view, uint32_t baudrate) {
+    with_view_model(
+        dap_main_view->view, DapMainViewModel * model, { model->baudrate = baudrate; }, false);
+}
+
+void dap_main_view_update(DapMainView* dap_main_view) {
+    with_view_model(
+        dap_main_view->view, DapMainViewModel * model, { UNUSED(model); }, true);
+}
+
+void dap_main_view_set_version(DapMainView* dap_main_view, DapMainViewVersion version) {
+    with_view_model(
+        dap_main_view->view, DapMainViewModel * model, { model->version = version; }, false);
+}
+
+void dap_main_view_set_usb_connected(DapMainView* dap_main_view, bool connected) {
+    with_view_model(
+        dap_main_view->view,
+        DapMainViewModel * model,
+        { model->usb_connected = connected; },
+        false);
+}

+ 45 - 0
dap_link/gui/views/dap_main_view.h

@@ -0,0 +1,45 @@
+#pragma once
+#include <gui/view.h>
+
+typedef struct DapMainView DapMainView;
+
+typedef void (*DapMainViewButtonCallback)(void* context);
+
+typedef enum {
+    DapMainViewVersionUnknown,
+    DapMainViewVersionV1,
+    DapMainViewVersionV2,
+} DapMainViewVersion;
+
+typedef enum {
+    DapMainViewModeDisconnected,
+    DapMainViewModeSWD,
+    DapMainViewModeJTAG,
+} DapMainViewMode;
+
+DapMainView* dap_main_view_alloc();
+
+void dap_main_view_free(DapMainView* dap_main_view);
+
+View* dap_main_view_get_view(DapMainView* dap_main_view);
+
+void dap_main_view_set_left_callback(
+    DapMainView* dap_main_view,
+    DapMainViewButtonCallback callback,
+    void* context);
+
+void dap_main_view_set_mode(DapMainView* dap_main_view, DapMainViewMode mode);
+
+void dap_main_view_set_version(DapMainView* dap_main_view, DapMainViewVersion version);
+
+void dap_main_view_set_dap(DapMainView* dap_main_view, bool active);
+
+void dap_main_view_set_tx(DapMainView* dap_main_view, bool active);
+
+void dap_main_view_set_rx(DapMainView* dap_main_view, bool active);
+
+void dap_main_view_set_usb_connected(DapMainView* dap_main_view, bool connected);
+
+void dap_main_view_set_baudrate(DapMainView* dap_main_view, uint32_t baudrate);
+
+void dap_main_view_update(DapMainView* dap_main_view);

BIN
dap_link/icons/ActiveConnection_50x64.png


BIN
dap_link/icons/ArrowUpEmpty_12x18.png


BIN
dap_link/icons/ArrowUpFilled_12x18.png


+ 27 - 0
dap_link/lib/free-dap/LICENSE

@@ -0,0 +1,27 @@
+Copyright (c) 2016, Alex Taradov <alex@taradov.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+* Neither the name of free-dap nor the names of its
+  contributors may be used to endorse or promote products derived from
+  this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 100 - 0
dap_link/lib/free-dap/README.md

@@ -0,0 +1,100 @@
+# Free-DAP
+
+This is a free and open implementation of the CMSIS-DAP debugger firmware.
+
+Both SWD and JTAG protocols are supported. However JTAG was not well tested due to lack of
+good targets. If you have any issues with it - let me know and I'll try to help.
+
+## Platform requirements
+
+To create a CMSIS-DAP compliant debugger, your platform must:
+ * Implement USB HID (and raw bulk for CMSIS-DAP v2) device able to receive and send arbitrary payloads
+ * Provide configuration file dap_config.h with definitions for hardware-dependent calls
+ * Call dap_init() at the initialization time
+ * Call dap_process_request() for every received request and send the response back
+
+## CMSIS-DAP version support
+
+Free-DAP library itself is protocol agnostic and implementation of the specific version
+of the CMSIS-DAP protocol (v1 or v2) is up to the individual platforms.
+
+Currently RP2040 and SAM D11 implementaitons were updated to support CMSIS-DAP v2.
+Other platforms would be updated if requested or needed by me.
+
+## Configuration
+
+For complete list of settings see one of the existing configuration file, they are
+pretty obvious.
+
+To configure clock frequency you need to specify two parameters:
+  * DAP_CONFIG_DELAY_CONSTANT - clock timing constant. This constant can be determined
+    by calling dap_clock_test() with varying parameter value and measuring the frequency
+    on the SWCLK pin. Delay constant value is the value of the parameter at which
+    output frequency equals to 1 kHz.
+  * DAP_CONFIG_FAST_CLOCK - threshold for switching to fast clock routines. This value
+    defines the frequency, at which more optimal pin manipulation functions are used.
+    This is the frequency produced by dap_clock_test(1) on the SWCLK pin.
+    You can also measure maximum achievable frequency on your platform by calling dap_clock_test(0).
+
+Your configuration file will need to define the following pin manipulation functions:
+
+ * DAP_CONFIG_SWCLK_TCK_write()
+ * DAP_CONFIG_SWDIO_TMS_write()
+ * DAP_CONFIG_TDO_write()
+ * DAP_CONFIG_nTRST_write()
+ * DAP_CONFIG_nRESET_write()
+ * DAP_CONFIG_SWCLK_TCK_read()
+ * DAP_CONFIG_SWDIO_TMS_read()
+ * DAP_CONFIG_TDI_read()
+ * DAP_CONFIG_TDO_read()
+ * DAP_CONFIG_nTRST_read()
+ * DAP_CONFIG_nRESET_read()
+ * DAP_CONFIG_SWCLK_TCK_set()
+ * DAP_CONFIG_SWCLK_TCK_clr()
+ * DAP_CONFIG_SWDIO_TMS_in()
+ * DAP_CONFIG_SWDIO_TMS_out()
+
+Note that all pin manipulation functions are required even if one of the interfaces (JTAG or SWD) is not enabled.
+
+Additionally configuration file must provide basic initialization and control functions:
+
+ * DAP_CONFIG_SETUP()
+ * DAP_CONFIG_DISCONNECT()
+ * DAP_CONFIG_CONNECT_SWD()
+ * DAP_CONFIG_CONNECT_JTAG()
+ * DAP_CONFIG_LED()
+ * DAP_CONFIG_DELAY()
+
+## Tools
+
+A complete RP2040 build requres bin2uf2 utility to generate UF2 file suitable for the RP2040 MSC bootloader.
+This utility can be downloded [here](https://github.com/ataradov/tools/tree/master/bin2uf2).
+
+## Binaries
+
+Generally there are no pre-built binaries due to effort required to maintain
+them and low potential benefit because of custom hardware requirement.
+
+For RP2040 and Raspberry Pi Pico board specifically there is a binary, since
+it is a standard and a widely available board that has a nonvolatile bootloader.
+
+The UF2 file is located [here](bin/free_dap_rp2040.uf2). Simply boot into
+a BootROM MSC mode and copy that file to the drive.
+
+I will try to do my best to keep this binary in sync with the code updates, but
+it is a manual process, so I may forget. Let me know if you have any issues.
+
+The pins used are as follows:
+
+| GPIO | Function |
+|:---:|:---|
+| 11 | SWCLK/TCK |
+| 12 | SWDIO/TMS |
+| 13 | TDI |
+| 14 | TDO |
+| 15 | nRESET |
+| 0 | VCP TX |
+| 1 | VCP RX |
+| 2 | VCP Status |
+| 25 (LED) | DAP Status |
+

BIN
dap_link/lib/free-dap/bin/free_dap_rp2040.uf2


+ 1509 - 0
dap_link/lib/free-dap/dap.c

@@ -0,0 +1,1509 @@
+/*
+ * Copyright (c) 2016-2021, Alex Taradov <alex@taradov.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*- Includes ----------------------------------------------------------------*/
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include "dap_config.h"
+#include "dap.h"
+
+/*- Definitions -------------------------------------------------------------*/
+#define ARRAY_SIZE(x)  ((int)(sizeof(x) / sizeof(0[x])))
+
+enum
+{
+  ID_DAP_INFO               = 0x00,
+  ID_DAP_HOST_STATUS        = 0x01,
+  ID_DAP_CONNECT            = 0x02,
+  ID_DAP_DISCONNECT         = 0x03,
+  ID_DAP_TRANSFER_CONFIGURE = 0x04,
+  ID_DAP_TRANSFER           = 0x05,
+  ID_DAP_TRANSFER_BLOCK     = 0x06,
+  ID_DAP_TRANSFER_ABORT     = 0x07,
+  ID_DAP_WRITE_ABORT        = 0x08,
+  ID_DAP_DELAY              = 0x09,
+  ID_DAP_RESET_TARGET       = 0x0a,
+
+  ID_DAP_SWJ_PINS           = 0x10,
+  ID_DAP_SWJ_CLOCK          = 0x11,
+  ID_DAP_SWJ_SEQUENCE       = 0x12,
+
+  ID_DAP_SWD_CONFIGURE      = 0x13,
+  ID_DAP_SWD_SEQUENCE       = 0x1d,
+
+  ID_DAP_JTAG_SEQUENCE      = 0x14,
+  ID_DAP_JTAG_CONFIGURE     = 0x15,
+  ID_DAP_JTAG_IDCODE        = 0x16,
+
+  ID_DAP_SWO_TRANSPORT      = 0x17,
+  ID_DAP_SWO_MODE           = 0x18,
+  ID_DAP_SWO_BAUDRATE       = 0x19,
+  ID_DAP_SWO_CONTROL        = 0x1a,
+  ID_DAP_SWO_STATUS         = 0x1b,
+  ID_DAP_SWO_EXT_STATUS     = 0x1e,
+  ID_DAP_SWO_DATA           = 0x1c,
+
+  ID_DAP_QUEUE_COMMANDS     = 0x7e,
+  ID_DAP_EXECUTE_COMMANDS   = 0x7f,
+
+  ID_DAP_VENDOR_0           = 0x80,
+  ID_DAP_VENDOR_31          = 0x9f,
+  ID_DAP_VENDOR_EX_FIRS     = 0xa0,
+  ID_DAP_VENDOR_EX_LAST     = 0xfe,
+
+  ID_DAP_INVALID            = 0xff,
+};
+
+enum
+{
+  DAP_INFO_VENDOR           = 0x01,
+  DAP_INFO_PRODUCT          = 0x02,
+  DAP_INFO_SER_NUM          = 0x03,
+  DAP_INFO_CMSIS_DAP_VER    = 0x04,
+  DAP_INFO_DEVICE_VENDOR    = 0x05,
+  DAP_INFO_DEVICE_NAME      = 0x06,
+  DAP_INFO_BOARD_VENDOR     = 0x07,
+  DAP_INFO_BOARD_NAME       = 0x08,
+  DAP_INFO_FW_VER           = 0x09,
+  DAP_INFO_CAPABILITIES     = 0xf0,
+  DAP_INFO_TDT              = 0xf1,
+  DAP_INFO_UART_RX_SIZE     = 0xfb,
+  DAP_INFO_UART_TX_SIZE     = 0xfc,
+  DAP_INFO_SWO_BUF_SIZE     = 0xfd,
+  DAP_INFO_PACKET_COUNT     = 0xfe,
+  DAP_INFO_PACKET_SIZE      = 0xff,
+};
+
+enum
+{
+  DAP_CAP_SWD               = (1 << 0),
+  DAP_CAP_JTAG              = (1 << 1),
+  DAP_CAP_SWO_UART          = (1 << 2),
+  DAP_CAP_SWO_MANCHESTER    = (1 << 3),
+  DAP_CAP_ATOMIC_CMD        = (1 << 4),
+  DAP_CAP_TDT               = (1 << 5),
+  DAP_CAP_SWO_STREAMING     = (1 << 6),
+  DAP_CAP_UART_COM_PORT     = (1 << 7),
+};
+
+enum
+{
+  DAP_TRANSFER_APnDP        = 1 << 0,
+  DAP_TRANSFER_RnW          = 1 << 1,
+  DAP_TRANSFER_A2           = 1 << 2,
+  DAP_TRANSFER_A3           = 1 << 3,
+  DAP_TRANSFER_MATCH_VALUE  = 1 << 4,
+  DAP_TRANSFER_MATCH_MASK   = 1 << 5,
+  DAP_TRANSFER_JTAG_ABORT   = 1 << 16,
+};
+
+enum
+{
+  DAP_TRANSFER_INVALID      = 0,
+  DAP_TRANSFER_OK           = 1 << 0,
+  DAP_TRANSFER_WAIT         = 1 << 1,
+  DAP_TRANSFER_FAULT        = 1 << 2,
+  DAP_TRANSFER_ERROR        = 1 << 3,
+  DAP_TRANSFER_MISMATCH     = 1 << 4,
+};
+
+enum
+{
+  DAP_PORT_DISABLED         = 0,
+  DAP_PORT_AUTODETECT       = 0,
+  DAP_PORT_SWD              = 1,
+  DAP_PORT_JTAG             = 2,
+};
+
+enum
+{
+  DAP_SWJ_SWCLK_TCK         = 1 << 0,
+  DAP_SWJ_SWDIO_TMS         = 1 << 1,
+  DAP_SWJ_TDI               = 1 << 2,
+  DAP_SWJ_TDO               = 1 << 3,
+  DAP_SWJ_nTRST             = 1 << 5,
+  DAP_SWJ_nRESET            = 1 << 7,
+};
+
+enum
+{
+  DAP_OK                    = 0x00,
+  DAP_ERROR                 = 0xff,
+};
+
+enum
+{
+  SWD_DP_R_IDCODE           = 0x00,
+  SWD_DP_W_ABORT            = 0x00,
+  SWD_DP_R_RDBUFF           = 0x0c,
+};
+
+enum
+{
+  JTAG_ABORT                = 0x08,
+  JTAG_DPACC                = 0x0a,
+  JTAG_APACC                = 0x0b,
+  JTAG_IDCODE               = 0x0e,
+  JTAG_BYPASS               = 0x0f,
+  JTAG_INVALID              = 0xff,
+};
+
+enum
+{
+  JTAG_SEQUENCE_COUNT       = 0x3f,
+  JTAG_SEQUENCE_TMS         = 0x40,
+  JTAG_SEQUENCE_TDO         = 0x80,
+};
+
+enum
+{
+  SWD_SEQUENCE_COUNT        = 0x3f,
+  SWD_SEQUENCE_DIN          = 0x80,
+};
+
+#define ARM_JTAG_IR_LENGTH  4
+
+/*- Constants ---------------------------------------------------------------*/
+static const struct
+{
+  int    id;
+  char   * const str;
+} dap_info_strings[] =
+{
+#ifdef DAP_CONFIG_VENDOR_STR
+  { DAP_INFO_VENDOR,        DAP_CONFIG_VENDOR_STR },
+#endif
+#ifdef DAP_CONFIG_PRODUCT_STR
+  { DAP_INFO_PRODUCT,       DAP_CONFIG_PRODUCT_STR },
+#endif
+#ifdef DAP_CONFIG_SER_NUM_STR
+  { DAP_INFO_SER_NUM,       DAP_CONFIG_SER_NUM_STR },
+#endif
+#ifdef DAP_CONFIG_CMSIS_DAP_VER_STR
+  { DAP_INFO_CMSIS_DAP_VER, DAP_CONFIG_CMSIS_DAP_VER_STR },
+#endif
+#ifdef DAP_CONFIG_DEVICE_VENDOR_STR
+  { DAP_INFO_DEVICE_VENDOR, DAP_CONFIG_DEVICE_VENDOR_STR },
+#endif
+#ifdef DAP_CONFIG_DEVICE_NAME_STR
+  { DAP_INFO_DEVICE_NAME,   DAP_CONFIG_DEVICE_NAME_STR },
+#endif
+#ifdef DAP_CONFIG_BOARD_VENDOR_STR
+  { DAP_INFO_BOARD_VENDOR,  DAP_CONFIG_BOARD_VENDOR_STR },
+#endif
+#ifdef DAP_CONFIG_BOARD_NAME_STR
+  { DAP_INFO_BOARD_NAME,    DAP_CONFIG_BOARD_NAME_STR },
+#endif
+#ifdef DAP_CONFIG_FW_VER_STR
+  { DAP_INFO_FW_VER,        DAP_CONFIG_FW_VER_STR },
+#endif
+};
+
+/*- Variables ---------------------------------------------------------------*/
+static int dap_port;
+static volatile bool dap_abort;
+static uint32_t dap_match_mask;
+static int dap_idle_cycles;
+static int dap_retry_count;
+static int dap_match_retry_count;
+static int dap_clock_delay;
+
+static void (*dap_swj_run)(int);
+static void (*dap_swd_write)(uint32_t, int);
+static uint32_t (*dap_swd_read)(int);
+
+#ifdef DAP_CONFIG_ENABLE_JTAG
+static uint32_t (*dap_jtag_write)(uint32_t, int);
+static uint32_t (*dap_jtag_read)(int);
+static uint32_t (*dap_jtag_rdwr)(uint32_t, int);
+#endif
+
+static uint8_t *dap_req_buf;
+static int dap_req_size;
+static int dap_req_ptr;
+
+static uint8_t *dap_resp_buf;
+static int dap_resp_size;
+static int dap_resp_ptr;
+
+static bool dap_buf_error;
+
+static int dap_swd_turnaround;
+static bool dap_swd_data_phase;
+
+#ifdef DAP_CONFIG_ENABLE_JTAG
+static int dap_jtag_dev_count;
+static int dap_jtag_dev_index;
+static int dap_jtag_ir_length[DAP_CONFIG_JTAG_DEV_COUNT];
+static int dap_jtag_ir_before[DAP_CONFIG_JTAG_DEV_COUNT];
+static int dap_jtag_ir_after[DAP_CONFIG_JTAG_DEV_COUNT];
+static int dap_jtag_ir;
+#endif
+
+/*- Implementations ---------------------------------------------------------*/
+
+//-----------------------------------------------------------------------------
+static void dap_delay_us(int delay)
+{
+  while (delay)
+  {
+    int del = (delay > 100000) ? 100000 : delay;
+    DAP_CONFIG_DELAY((DAP_CONFIG_DELAY_CONSTANT * 2 * del) / 1000);
+    delay -= del;
+  }
+}
+
+//-----------------------------------------------------------------------------
+#define DAP_SWJ_FN(ver, delay) \
+  DAP_CONFIG_PERFORMANCE_ATTR						\
+  static void dap_swj_run_##ver(int cycles)				\
+  {									\
+    while (cycles--)							\
+    {									\
+      DAP_CONFIG_SWCLK_TCK_clr();					\
+      delay(dap_clock_delay);						\
+      DAP_CONFIG_SWCLK_TCK_set();					\
+      delay(dap_clock_delay);						\
+    }									\
+  }
+DAP_SWJ_FN(slow, DAP_CONFIG_DELAY)
+DAP_SWJ_FN(fast, (void))
+
+//-----------------------------------------------------------------------------
+#define DAP_SWD_FN(ver, delay) \
+  DAP_CONFIG_PERFORMANCE_ATTR						\
+  static void dap_swd_write_##ver(uint32_t value, int size)		\
+  {									\
+    for (int i = 0; i < size; i++)					\
+    {									\
+      DAP_CONFIG_SWDIO_TMS_write(value & 1);				\
+      DAP_CONFIG_SWCLK_TCK_clr();					\
+      delay(dap_clock_delay);						\
+      DAP_CONFIG_SWCLK_TCK_set();					\
+      delay(dap_clock_delay);						\
+      value >>= 1;							\
+    }									\
+  }									\
+									\
+  DAP_CONFIG_PERFORMANCE_ATTR						\
+  static uint32_t dap_swd_read_##ver(int size)				\
+  {									\
+    uint32_t value = 0;							\
+    uint32_t bit;							\
+    for (int i = 0; i < size; i++)					\
+    {									\
+      DAP_CONFIG_SWCLK_TCK_clr();					\
+      delay(dap_clock_delay);						\
+      bit = DAP_CONFIG_SWDIO_TMS_read();				\
+      DAP_CONFIG_SWCLK_TCK_set();					\
+      delay(dap_clock_delay);						\
+      value |= (bit << i);						\
+    }									\
+    return value;							\
+  }
+
+DAP_SWD_FN(slow, DAP_CONFIG_DELAY)
+DAP_SWD_FN(fast, (void))
+
+//-----------------------------------------------------------------------------
+static inline uint32_t dap_parity(uint32_t value)
+{
+  value ^= value >> 16;
+  value ^= value >> 8;
+  value ^= value >> 4;
+  value &= 0x0f;
+
+  return (0x6996 >> value) & 1;
+}
+
+//-----------------------------------------------------------------------------
+static int dap_swd_operation(int req, uint32_t *data)
+{
+  uint32_t value;
+  int ack = 0;
+
+  req &= (DAP_TRANSFER_APnDP | DAP_TRANSFER_RnW | DAP_TRANSFER_A2 | DAP_TRANSFER_A3);
+
+  dap_swd_write(0x81 | (dap_parity(req) << 5) | (req << 1), 8);
+
+  DAP_CONFIG_SWDIO_TMS_in();
+
+  dap_swj_run(dap_swd_turnaround);
+
+  ack = dap_swd_read(3);
+
+  if (DAP_TRANSFER_OK == ack)
+  {
+    if (req & DAP_TRANSFER_RnW)
+    {
+      value = dap_swd_read(32);
+
+      if (dap_parity(value) != dap_swd_read(1))
+        ack = DAP_TRANSFER_ERROR;
+
+      if (data)
+        *data = value;
+
+      dap_swj_run(dap_swd_turnaround);
+
+      DAP_CONFIG_SWDIO_TMS_out();
+    }
+    else
+    {
+      dap_swj_run(dap_swd_turnaround);
+
+      DAP_CONFIG_SWDIO_TMS_out();
+
+      dap_swd_write(*data, 32);
+      dap_swd_write(dap_parity(*data), 1);
+    }
+
+    DAP_CONFIG_SWDIO_TMS_write(0);
+    dap_swj_run(dap_idle_cycles);
+  }
+
+  else if (DAP_TRANSFER_WAIT == ack || DAP_TRANSFER_FAULT == ack)
+  {
+    if (dap_swd_data_phase && (req & DAP_TRANSFER_RnW))
+      dap_swj_run(32 + 1);
+
+    dap_swj_run(dap_swd_turnaround);
+
+    DAP_CONFIG_SWDIO_TMS_out();
+
+    if (dap_swd_data_phase && (0 == (req & DAP_TRANSFER_RnW)))
+    {
+      DAP_CONFIG_SWDIO_TMS_write(0);
+      dap_swj_run(32 + 1);
+    }
+  }
+
+  else
+  {
+    dap_swj_run(dap_swd_turnaround + 32 + 1);
+  }
+
+  DAP_CONFIG_SWDIO_TMS_write(1);
+
+  return ack;
+}
+
+#ifdef DAP_CONFIG_ENABLE_JTAG
+//-----------------------------------------------------------------------------
+#define DAP_JTAG_FN(ver, delay) \
+  DAP_CONFIG_PERFORMANCE_ATTR						\
+  static uint32_t dap_jtag_write_##ver(uint32_t value, int size)	\
+  {									\
+    for (int i = 0; i < size; i++)					\
+    {									\
+      DAP_CONFIG_TDI_write(value & 1);					\
+      DAP_CONFIG_SWCLK_TCK_clr();					\
+      delay(dap_clock_delay);						\
+      DAP_CONFIG_SWCLK_TCK_set();					\
+      delay(dap_clock_delay);						\
+      value >>= 1;							\
+    }									\
+    return value;							\
+  }									\
+									\
+  DAP_CONFIG_PERFORMANCE_ATTR						\
+  static uint32_t dap_jtag_read_##ver(int size)				\
+  {									\
+    uint32_t value = 0;							\
+    uint32_t bit;							\
+    for (int i = 0; i < size; i++)					\
+    {									\
+      DAP_CONFIG_SWCLK_TCK_clr();					\
+      delay(dap_clock_delay);						\
+      bit = DAP_CONFIG_TDO_read();					\
+      DAP_CONFIG_SWCLK_TCK_set();					\
+      delay(dap_clock_delay);						\
+      value |= (bit << i);						\
+    }									\
+    return value;							\
+  }									\
+									\
+  DAP_CONFIG_PERFORMANCE_ATTR						\
+  static uint32_t dap_jtag_rdwr_##ver(uint32_t value, int size)		\
+  {									\
+    uint32_t rvalue = 0;						\
+    uint32_t bit;							\
+    for (int i = 0; i < size; i++)					\
+    {									\
+      DAP_CONFIG_TDI_write(value & 1);					\
+      DAP_CONFIG_SWCLK_TCK_clr();					\
+      delay(dap_clock_delay);						\
+      bit = DAP_CONFIG_TDO_read();					\
+      DAP_CONFIG_SWCLK_TCK_set();					\
+      delay(dap_clock_delay);						\
+      value >>= 1;							\
+      rvalue |= (bit << i);						\
+    }									\
+    return rvalue;							\
+  }
+
+DAP_JTAG_FN(slow, DAP_CONFIG_DELAY)
+DAP_JTAG_FN(fast, (void))
+
+//-----------------------------------------------------------------------------
+static void dap_jtag_write_ir(int ir)
+{
+  int len = dap_jtag_ir_length[dap_jtag_dev_index];
+
+  DAP_CONFIG_SWDIO_TMS_write(1);
+  dap_swj_run(2); // -> Select-IR-Scan
+  DAP_CONFIG_SWDIO_TMS_write(0);
+  dap_swj_run(2); // -> Shift-IR
+
+  DAP_CONFIG_TDI_write(1);
+  dap_swj_run(dap_jtag_ir_before[dap_jtag_dev_index]);
+
+  ir = dap_jtag_write(ir, len-1);
+
+  if (dap_jtag_ir_after[dap_jtag_dev_index])
+  {
+    dap_jtag_write(ir, 1);
+
+    DAP_CONFIG_TDI_write(1);
+    dap_swj_run(dap_jtag_ir_after[dap_jtag_dev_index]-1);
+
+    DAP_CONFIG_SWDIO_TMS_write(1);
+    dap_swj_run(1); // -> Exit1-IR
+  }
+  else
+  {
+    DAP_CONFIG_SWDIO_TMS_write(1);
+    dap_jtag_write(ir, 1); // -> Exit1-IR
+  }
+
+  dap_swj_run(1); // -> Update-IR
+  DAP_CONFIG_SWDIO_TMS_write(0);
+  dap_swj_run(1); // -> Idle
+  DAP_CONFIG_TDI_write(1);
+}
+
+//-----------------------------------------------------------------------------
+static int dap_jtag_operation(int req, uint32_t *data)
+{
+  int ack, ir;
+
+  if (DAP_TRANSFER_JTAG_ABORT == req)
+    ir = JTAG_ABORT;
+  else
+    ir = (req & DAP_TRANSFER_APnDP) ? JTAG_APACC : JTAG_DPACC;
+
+  if (ir != dap_jtag_ir)
+  {
+    dap_jtag_ir = ir;
+    dap_jtag_write_ir(ir);
+  }
+
+  DAP_CONFIG_SWDIO_TMS_write(1);
+  dap_swj_run(1); // -> Select-DR-Scan
+  DAP_CONFIG_SWDIO_TMS_write(0);
+  dap_swj_run(2 + dap_jtag_dev_index); // -> Shift-DR
+
+  ack = dap_jtag_rdwr(req >> 1, 3);
+
+  if (ack == 0x2)
+    ack = DAP_TRANSFER_OK; // or FAULT
+  else if (ack == 0x1)
+    ack = DAP_TRANSFER_WAIT;
+  else
+    ack = DAP_TRANSFER_INVALID;
+
+  if (DAP_TRANSFER_OK == ack)
+  {
+    int cnt = dap_jtag_dev_count - dap_jtag_dev_index - 1;
+    uint32_t value;
+
+    if (req & DAP_TRANSFER_RnW)
+    {
+      if (cnt)
+      {
+        value = dap_jtag_read(32);
+        dap_swj_run(cnt-1);
+        DAP_CONFIG_SWDIO_TMS_write(1);
+        dap_swj_run(1); // -> Exit1-DR
+      }
+      else
+      {
+        value = dap_jtag_read(31);
+        DAP_CONFIG_SWDIO_TMS_write(1);
+        value |= (dap_jtag_read(1) << 31); // -> Exit1-DR
+      }
+
+      if (data)
+        *data = value;
+    }
+    else
+    {
+      value = *data;
+
+      if (cnt)
+      {
+        dap_jtag_write(value, 32);
+        dap_swj_run(cnt-1);
+        DAP_CONFIG_SWDIO_TMS_write(1);
+        dap_swj_run(1); // -> Exit1-DR
+      }
+      else
+      {
+        value = dap_jtag_write(value, 31);
+        DAP_CONFIG_SWDIO_TMS_write(1);
+        dap_jtag_write(value, 1); // -> Exit1-DR
+      }
+    }
+  }
+  else // Not OK
+  {
+    DAP_CONFIG_SWDIO_TMS_write(1);
+    dap_swj_run(1); // -> Exit1-DR
+  }
+
+  dap_swj_run(1); // -> Update-DR
+  DAP_CONFIG_SWDIO_TMS_write(0);
+  dap_swj_run(1); // -> Idle
+  DAP_CONFIG_TDI_write(1);
+
+  dap_swj_run(dap_idle_cycles);
+
+  return ack;
+}
+#endif // DAP_CONFIG_ENABLE_JTAG
+
+//-----------------------------------------------------------------------------
+static void dap_setup_clock(int freq)
+{
+  if (freq > DAP_CONFIG_FAST_CLOCK)
+  {
+    dap_clock_delay = 0;
+    dap_swj_run     = dap_swj_run_fast;
+    dap_swd_write   = dap_swd_write_fast;
+    dap_swd_read    = dap_swd_read_fast;
+#ifdef DAP_CONFIG_ENABLE_JTAG
+    dap_jtag_write  = dap_jtag_write_fast;
+    dap_jtag_read   = dap_jtag_read_fast;
+    dap_jtag_rdwr   = dap_jtag_rdwr_fast;
+#endif
+  }
+  else
+  {
+    dap_clock_delay = (DAP_CONFIG_DELAY_CONSTANT * 1000) / freq;
+    dap_swj_run     = dap_swj_run_slow;
+    dap_swd_write   = dap_swd_write_slow;
+    dap_swd_read    = dap_swd_read_slow;
+#ifdef DAP_CONFIG_ENABLE_JTAG
+    dap_jtag_write  = dap_jtag_write_slow;
+    dap_jtag_read   = dap_jtag_read_slow;
+    dap_jtag_rdwr   = dap_jtag_rdwr_slow;
+#endif
+  }
+}
+
+//-----------------------------------------------------------------------------
+static bool dap_select_device(int index)
+{
+  if (DAP_PORT_SWD == dap_port)
+    return true;
+
+#ifdef DAP_CONFIG_ENABLE_JTAG
+  if (DAP_PORT_JTAG == dap_port)
+  {
+    if (index >= dap_jtag_dev_count || dap_jtag_ir_length[index] != ARM_JTAG_IR_LENGTH)
+      return false;
+
+    dap_jtag_dev_index = index;
+
+    return true;
+  }
+#endif
+
+  (void)index;
+  return false;
+}
+
+//-----------------------------------------------------------------------------
+static int dap_transfer_word(int req, uint32_t *data)
+{
+  int ack = DAP_TRANSFER_INVALID;
+
+  for (int i = 0; i < dap_retry_count; i++)
+  {
+    if (DAP_PORT_SWD == dap_port)
+      ack = dap_swd_operation(req, data);
+
+#ifdef DAP_CONFIG_ENABLE_JTAG
+    else if (DAP_PORT_JTAG == dap_port)
+      ack = dap_jtag_operation(req, data);
+#endif
+
+    if (DAP_TRANSFER_WAIT != ack || dap_abort)
+      break;
+  }
+
+  return ack;
+}
+
+//-----------------------------------------------------------------------------
+static bool dap_needs_posted_read(int request)
+{
+  if (0 == (request & DAP_TRANSFER_RnW))
+    return false;
+
+  if (DAP_PORT_SWD == dap_port)
+    return (request & DAP_TRANSFER_APnDP);
+
+#ifdef DAP_CONFIG_ENABLE_JTAG
+  if (DAP_PORT_JTAG == dap_port)
+    return true;
+#endif
+
+  return false;
+}
+
+//-----------------------------------------------------------------------------
+static void dap_buf_init(uint8_t *req, int req_size, uint8_t *resp, int resp_size)
+{
+  dap_req_buf  = req;
+  dap_req_size = req_size;
+  dap_req_ptr  = 0;
+
+  dap_resp_buf  = resp;
+  dap_resp_size = resp_size;
+  dap_resp_ptr  = 0;
+
+  dap_buf_error = false;
+}
+
+//-----------------------------------------------------------------------------
+uint8_t dap_req_get_byte(void)
+{
+  if (dap_buf_error || ((dap_req_size - dap_req_ptr) < (int)sizeof(uint8_t)))
+  {
+    dap_buf_error = true;
+    return 0;
+  }
+
+  return dap_req_buf[dap_req_ptr++];
+}
+
+//-----------------------------------------------------------------------------
+uint16_t dap_req_get_half(void)
+{
+  if (dap_buf_error || ((dap_req_size - dap_req_ptr) < (int)sizeof(uint16_t)))
+  {
+    dap_buf_error = true;
+    return 0;
+  }
+
+  uint16_t value =
+      ((uint16_t)dap_req_buf[dap_req_ptr + 1] << 8) |
+       (uint16_t)dap_req_buf[dap_req_ptr];
+  dap_req_ptr += sizeof(uint16_t);
+
+  return value;
+}
+
+//-----------------------------------------------------------------------------
+uint32_t dap_req_get_word(void)
+{
+  if (dap_buf_error || ((dap_req_size - dap_req_ptr) < (int)sizeof(uint32_t)))
+  {
+    dap_buf_error = true;
+    return 0;
+  }
+
+  uint32_t value =
+      ((uint32_t)dap_req_buf[dap_req_ptr + 3] << 24) |
+      ((uint32_t)dap_req_buf[dap_req_ptr + 2] << 16) |
+      ((uint32_t)dap_req_buf[dap_req_ptr + 1] << 8) |
+       (uint32_t)dap_req_buf[dap_req_ptr];
+  dap_req_ptr += sizeof(uint32_t);
+
+  return value;
+}
+
+//-----------------------------------------------------------------------------
+void dap_resp_add_byte(uint8_t value)
+{
+  if (dap_buf_error || ((dap_resp_size - dap_resp_ptr) < (int)sizeof(uint8_t)))
+  {
+    dap_buf_error = true;
+    return;
+  }
+
+  dap_resp_buf[dap_resp_ptr++] = value;
+}
+
+//-----------------------------------------------------------------------------
+void dap_resp_add_word(uint32_t value)
+{
+  if (dap_buf_error || ((dap_resp_size - dap_resp_ptr) < (int)sizeof(uint32_t)))
+  {
+    dap_buf_error = true;
+    return;
+  }
+
+  dap_resp_buf[dap_resp_ptr + 0] = value;
+  dap_resp_buf[dap_resp_ptr + 1] = value >> 8;
+  dap_resp_buf[dap_resp_ptr + 2] = value >> 16;
+  dap_resp_buf[dap_resp_ptr + 3] = value >> 24;
+  dap_resp_ptr += sizeof(uint32_t);
+}
+
+//-----------------------------------------------------------------------------
+void dap_resp_set_byte(int index, uint8_t value)
+{
+  if (index < dap_resp_ptr)
+    dap_resp_buf[index] = value;
+}
+
+//-----------------------------------------------------------------------------
+bool dap_is_buf_error(void)
+{
+  return dap_buf_error;
+}
+
+//-----------------------------------------------------------------------------
+static void dap_info(void)
+{
+  int index = dap_req_get_byte();
+
+  if (DAP_INFO_CAPABILITIES == index)
+  {
+    int cap = DAP_CAP_SWD;
+#ifdef DAP_CONFIG_ENABLE_JTAG
+    cap |= DAP_CAP_JTAG;
+#endif
+    dap_resp_add_byte(1);
+    dap_resp_add_byte(cap);
+  }
+  else if (DAP_INFO_PACKET_COUNT == index)
+  {
+    dap_resp_add_byte(1);
+    dap_resp_add_byte(DAP_CONFIG_PACKET_COUNT);
+  }
+  else if (DAP_INFO_PACKET_SIZE == index)
+  {
+    dap_resp_add_byte(2);
+    dap_resp_add_byte(DAP_CONFIG_PACKET_SIZE & 0xff);
+    dap_resp_add_byte((DAP_CONFIG_PACKET_SIZE >> 8) & 0xff);
+  }
+  else
+  {
+    dap_resp_add_byte(0); // Size placeholder
+
+    for (int i = 0; i < ARRAY_SIZE(dap_info_strings); i++)
+    {
+      if (dap_info_strings[i].id == index)
+      {
+        const char *str = dap_info_strings[i].str;
+
+        while (*str)
+          dap_resp_add_byte(*str++);
+        dap_resp_add_byte(0);
+
+        dap_resp_set_byte(1, dap_resp_ptr-2);
+
+        break;
+      }
+    }
+  }
+}
+
+//-----------------------------------------------------------------------------
+static void dap_host_status(void)
+{
+  int index = dap_req_get_byte();
+  int state = dap_req_get_byte();
+
+  DAP_CONFIG_LED(index, state);
+
+  dap_resp_add_byte(DAP_OK);
+}
+
+//-----------------------------------------------------------------------------
+static void dap_connect(void)
+{
+  int port = dap_req_get_byte();
+
+  if (DAP_PORT_AUTODETECT == port)
+    port = DAP_CONFIG_DEFAULT_PORT;
+
+  dap_port = DAP_PORT_DISABLED;
+
+  if (DAP_PORT_SWD == port)
+  {
+    DAP_CONFIG_CONNECT_SWD();
+    dap_port = DAP_PORT_SWD;
+  }
+
+#ifdef DAP_CONFIG_ENABLE_JTAG
+  else if (DAP_PORT_JTAG == port)
+  {
+    DAP_CONFIG_CONNECT_JTAG();
+    dap_port = DAP_PORT_JTAG;
+  }
+#endif
+
+  dap_resp_add_byte(dap_port);
+}
+
+//-----------------------------------------------------------------------------
+static void dap_disconnect(void)
+{
+  DAP_CONFIG_DISCONNECT();
+
+  dap_port = DAP_PORT_DISABLED;
+
+  dap_resp_add_byte(DAP_OK);
+}
+
+//-----------------------------------------------------------------------------
+static void dap_transfer_configure(void)
+{
+  dap_idle_cycles = dap_req_get_byte();
+  dap_retry_count = dap_req_get_half();
+  dap_match_retry_count = dap_req_get_half();
+
+  dap_resp_add_byte(DAP_OK);
+}
+
+//-----------------------------------------------------------------------------
+static void dap_transfer(void)
+{
+  int req_count, resp_count, request, ack;
+  bool posted_read, verify_write;
+  uint32_t data, match_value;
+
+  dap_resp_add_byte(0); // Count
+  dap_resp_add_byte(DAP_TRANSFER_INVALID);
+
+  if (!dap_select_device(dap_req_get_byte()))
+    return;
+
+  req_count  = dap_req_get_byte();
+  resp_count = 0;
+
+  posted_read = false;
+  verify_write = false;
+  ack = DAP_TRANSFER_INVALID;
+
+  for (; req_count && !dap_abort && !dap_buf_error; req_count--, resp_count++)
+  {
+    request = dap_req_get_byte();
+    verify_write = false;
+
+    if (posted_read)
+    {
+      if (dap_needs_posted_read(request))
+      {
+        ack = dap_transfer_word(request, &data);
+      }
+      else
+      {
+        ack = dap_transfer_word(SWD_DP_R_RDBUFF | DAP_TRANSFER_RnW, &data);
+        posted_read = false;
+      }
+
+      if (ack != DAP_TRANSFER_OK)
+        break;
+
+      dap_resp_add_word(data);
+
+      if (posted_read)
+        continue;
+    }
+
+    if (request & DAP_TRANSFER_RnW)
+    {
+      if (request & DAP_TRANSFER_MATCH_VALUE)
+      {
+        match_value = dap_req_get_word();
+
+        if (dap_needs_posted_read(request))
+          dap_transfer_word(request, NULL);
+
+        for (int i = 0; i < dap_match_retry_count; i++)
+        {
+          ack = dap_transfer_word(request, &data);
+
+          if (DAP_TRANSFER_OK != ack || (data & dap_match_mask) == match_value || dap_abort)
+            break;
+        };
+
+        if ((data & dap_match_mask) != match_value)
+          ack |= DAP_TRANSFER_MISMATCH;
+
+        if (ack != DAP_TRANSFER_OK)
+          break;
+      }
+      else if (dap_needs_posted_read(request))
+      {
+        ack = dap_transfer_word(request, NULL);
+
+        if (ack != DAP_TRANSFER_OK)
+          break;
+
+        posted_read = true;
+      }
+      else
+      {
+        ack = dap_transfer_word(request, &data);
+
+        if (DAP_TRANSFER_OK != ack)
+          break;
+
+        dap_resp_add_word(data);
+      }
+    }
+    else // Write
+    {
+      data = dap_req_get_word();
+
+      if (request & DAP_TRANSFER_MATCH_MASK)
+      {
+        ack = DAP_TRANSFER_OK;
+        dap_match_mask = data;
+      }
+      else
+      {
+        ack = dap_transfer_word(request, &data);
+
+        if (ack != DAP_TRANSFER_OK)
+          break;
+
+        verify_write = true;
+      }
+    }
+  }
+
+  if (DAP_TRANSFER_OK == ack)
+  {
+    if (posted_read)
+    {
+      ack = dap_transfer_word(SWD_DP_R_RDBUFF | DAP_TRANSFER_RnW, &data);
+      dap_resp_add_word(data);
+    }
+    else if (verify_write)
+    {
+      ack = dap_transfer_word(SWD_DP_R_RDBUFF | DAP_TRANSFER_RnW, NULL);
+    }
+  }
+
+  dap_resp_set_byte(1, resp_count);
+  dap_resp_set_byte(2, ack);
+}
+
+//-----------------------------------------------------------------------------
+static void dap_transfer_block(void)
+{
+  int req_count, resp_count, request, ack;
+  uint32_t data;
+
+  dap_resp_add_byte(0); // Count
+  dap_resp_add_byte(0); // Count
+  dap_resp_add_byte(DAP_TRANSFER_INVALID);
+
+  if (!dap_select_device(dap_req_get_byte()))
+    return;
+
+  req_count  = dap_req_get_half();
+  resp_count = 0;
+
+  if (0 == req_count)
+    return;
+
+  request = dap_req_get_byte();
+  ack = DAP_TRANSFER_INVALID;
+
+  if (request & DAP_TRANSFER_RnW)
+  {
+    bool needs_posted = dap_needs_posted_read(request);
+    int transfers = needs_posted ? (req_count + 1) : req_count;
+
+    for (int i = 0; i < transfers; i++)
+    {
+      if (i == req_count)
+        request = SWD_DP_R_RDBUFF | DAP_TRANSFER_RnW;
+
+      ack = dap_transfer_word(request, &data);
+
+      if (DAP_TRANSFER_OK != ack)
+        break;
+
+      if (needs_posted && i == 0)
+        continue;
+
+      dap_resp_add_word(data);
+      resp_count++;
+    }
+  }
+  else // Write
+  {
+    for (int i = 0; i < req_count; i++)
+    {
+      data = dap_req_get_word();
+
+      ack = dap_transfer_word(request, &data);
+
+      if (DAP_TRANSFER_OK != ack)
+        break;
+
+      resp_count++;
+    }
+
+    if (DAP_TRANSFER_OK == ack)
+      ack = dap_transfer_word(SWD_DP_R_RDBUFF | DAP_TRANSFER_RnW, NULL);
+  }
+
+  dap_resp_set_byte(1, resp_count);
+  dap_resp_set_byte(2, resp_count >> 8);
+  dap_resp_set_byte(3, ack);
+}
+
+//-----------------------------------------------------------------------------
+static void dap_transfer_abort(void)
+{
+  // This request is handled outside of the normal queue.
+  // We should never get here.
+  dap_resp_add_byte(DAP_OK);
+}
+
+//-----------------------------------------------------------------------------
+static void dap_write_abort(void)
+{
+  int status = DAP_ERROR;
+  uint32_t data;
+
+  if (!dap_select_device(dap_req_get_byte()))
+  {
+    dap_resp_add_byte(DAP_ERROR);
+    return;
+  }
+
+  data = dap_req_get_word();
+
+  if (DAP_PORT_SWD == dap_port)
+  {
+    dap_swd_operation(SWD_DP_W_ABORT, &data);
+    status = DAP_OK;
+  }
+
+#ifdef DAP_CONFIG_ENABLE_JTAG
+  else if (DAP_PORT_JTAG == dap_port)
+  {
+    dap_jtag_operation(DAP_TRANSFER_JTAG_ABORT, &data);
+    status = DAP_OK;
+  }
+#endif
+
+  dap_resp_add_byte(status);
+}
+
+//-----------------------------------------------------------------------------
+static void dap_delay(void)
+{
+  int delay = dap_req_get_half();
+  dap_delay_us(delay);
+  dap_resp_add_byte(DAP_OK);
+}
+
+//-----------------------------------------------------------------------------
+static void dap_reset_target(void)
+{
+  dap_resp_add_byte(DAP_OK);
+
+#ifdef DAP_CONFIG_RESET_TARGET_FN
+  DAP_CONFIG_RESET_TARGET_FN();
+  dap_resp_add_byte(1);
+#else
+  dap_resp_add_byte(0);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+static void dap_swj_pins(void)
+{
+  int value  = dap_req_get_byte();
+  int select = dap_req_get_byte();
+  int wait   = dap_req_get_word();
+
+  if (select & DAP_SWJ_SWCLK_TCK)
+    DAP_CONFIG_SWCLK_TCK_write(value & DAP_SWJ_SWCLK_TCK);
+
+  if (select & DAP_SWJ_SWDIO_TMS)
+    DAP_CONFIG_SWDIO_TMS_write(value & DAP_SWJ_SWDIO_TMS);
+
+  if (select & DAP_SWJ_TDI)
+    DAP_CONFIG_TDI_write(value & DAP_SWJ_TDI);
+
+  if (select & DAP_SWJ_nTRST)
+    DAP_CONFIG_nTRST_write(value & DAP_SWJ_nTRST);
+
+  if (select & DAP_SWJ_nRESET)
+    DAP_CONFIG_nRESET_write(value & DAP_SWJ_nRESET);
+
+  dap_delay_us(wait * 1000);
+
+  value =
+    (DAP_CONFIG_SWCLK_TCK_read() ? DAP_SWJ_SWCLK_TCK : 0) |
+    (DAP_CONFIG_SWDIO_TMS_read() ? DAP_SWJ_SWDIO_TMS : 0) |
+    (DAP_CONFIG_TDI_read()       ? DAP_SWJ_TDI       : 0) |
+    (DAP_CONFIG_TDO_read()       ? DAP_SWJ_TDO       : 0) |
+    (DAP_CONFIG_nTRST_read()     ? DAP_SWJ_nTRST     : 0) |
+    (DAP_CONFIG_nRESET_read()    ? DAP_SWJ_nRESET    : 0);
+
+  dap_resp_add_byte(value);
+}
+
+//-----------------------------------------------------------------------------
+static void dap_swj_clock(void)
+{
+  int freq = dap_req_get_word();
+  dap_setup_clock(freq);
+  dap_resp_add_byte(DAP_OK);
+}
+
+//-----------------------------------------------------------------------------
+static void dap_swj_sequence(void)
+{
+  int size = dap_req_get_byte();
+
+  while (size)
+  {
+    int sz = (size > 8) ? 8 : size;
+    dap_swd_write(dap_req_get_byte(), sz);
+    size -= sz;
+  }
+
+  dap_resp_add_byte(DAP_OK);
+}
+
+//-----------------------------------------------------------------------------
+static void dap_swd_configure(void)
+{
+  int data = dap_req_get_byte();
+
+  dap_swd_turnaround = (data & 3) + 1;
+  dap_swd_data_phase = (data & 4) ? 1 : 0;
+
+  dap_resp_add_byte(DAP_OK);
+}
+
+//-----------------------------------------------------------------------------
+static void dap_swd_sequence(void)
+{
+  int req_count;
+
+  if (DAP_PORT_SWD != dap_port)
+  {
+    dap_resp_add_byte(DAP_ERROR);
+    return;
+  }
+
+  dap_resp_add_byte(DAP_OK);
+
+  req_count = dap_req_get_byte();
+
+  for (int i = 0; i < req_count; i++)
+  {
+    int info  = dap_req_get_byte();
+    int count = info & SWD_SEQUENCE_COUNT;
+    int din   = info & SWD_SEQUENCE_DIN;
+
+    if (count == 0)
+      count = 64U;
+
+    if (din)
+    {
+      DAP_CONFIG_SWDIO_TMS_in();
+
+      while (count)
+      {
+        int sz = (count > 8) ? 8 : count;
+        int value = dap_swd_read(sz);
+        dap_resp_add_byte(value);
+        count -= sz;
+      }
+    }
+    else
+    {
+      DAP_CONFIG_SWDIO_TMS_out();
+
+      while (count)
+      {
+        int sz = (count > 8) ? 8 : count;
+        dap_swd_write(dap_req_get_byte(), sz);
+        count -= sz;
+      }
+    }
+  }
+
+  DAP_CONFIG_SWDIO_TMS_out();
+}
+
+//-----------------------------------------------------------------------------
+static void dap_jtag_sequence(void)
+{
+#ifdef DAP_CONFIG_ENABLE_JTAG
+  int req_count;
+
+  if (DAP_PORT_JTAG != dap_port)
+  {
+    dap_resp_add_byte(DAP_ERROR);
+    return;
+  }
+
+  dap_resp_add_byte(DAP_OK);
+
+  req_count = dap_req_get_byte();
+
+  for (int i = 0; i < req_count; i++)
+  {
+    int info  = dap_req_get_byte();
+    int count = info & JTAG_SEQUENCE_COUNT;
+    int tms   = info & JTAG_SEQUENCE_TMS;
+    int tdo   = info & JTAG_SEQUENCE_TDO;
+
+    if (count == 0)
+      count = 64;
+
+    DAP_CONFIG_SWDIO_TMS_write(tms);
+
+    while (count)
+    {
+      int sz = (count > 8) ? 8 : count;
+
+      if (tdo)
+      {
+        int value = dap_jtag_rdwr(dap_req_get_byte(), sz);
+        dap_resp_add_byte(value);
+      }
+      else
+      {
+        dap_jtag_write(dap_req_get_byte(), sz);
+      }
+
+      count -= sz;
+    }
+  }
+#else
+  dap_resp_add_byte(DAP_ERROR);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+static void dap_jtag_configure(void)
+{
+#ifdef DAP_CONFIG_ENABLE_JTAG
+  int count = dap_req_get_byte();
+  int bits = 0;
+
+  if (count > DAP_CONFIG_JTAG_DEV_COUNT)
+  {
+    dap_resp_add_byte(DAP_ERROR);
+    return;
+  }
+
+  dap_jtag_dev_count = count;
+  dap_jtag_dev_index = 0;
+
+  for (int i = 0; i < dap_jtag_dev_count; i++)
+  {
+    dap_jtag_ir_length[i] = dap_req_get_byte();
+    dap_jtag_ir_before[i] = bits;
+    bits += dap_jtag_ir_length[i];
+  }
+
+  for (int i = 0; i < dap_jtag_dev_count; i++)
+  {
+    bits -= dap_jtag_ir_length[i];
+    dap_jtag_ir_after[i] = bits;
+  }
+
+  dap_resp_add_byte(DAP_OK);
+#else
+  dap_resp_add_byte(DAP_ERROR);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+static void dap_jtag_idcode(void)
+{
+#ifdef DAP_CONFIG_ENABLE_JTAG
+  uint32_t data;
+
+  if (DAP_PORT_JTAG != dap_port || !dap_select_device(dap_req_get_byte()))
+  {
+    dap_resp_add_byte(DAP_ERROR);
+    return;
+  }
+
+  dap_jtag_write_ir(JTAG_IDCODE);
+
+  DAP_CONFIG_SWDIO_TMS_write(1);
+  dap_swj_run(1); // -> Select-DR-Scan
+  DAP_CONFIG_SWDIO_TMS_write(0);
+  dap_swj_run(2 + dap_jtag_dev_index); // -> Shift-DR
+
+  data = dap_jtag_read(31);
+
+  DAP_CONFIG_SWDIO_TMS_write(1);
+  data |= (dap_jtag_read(1) << 31); // -> Exit1-DR
+
+  dap_swj_run(1); // -> Update-DR
+  DAP_CONFIG_SWDIO_TMS_write(0);
+  dap_swj_run(1); // -> Idle
+  DAP_CONFIG_TDI_write(1);
+
+  dap_resp_add_byte(DAP_OK);
+  dap_resp_add_word(data);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+void dap_init(void)
+{
+  dap_port              = DAP_PORT_DISABLED;
+  dap_abort             = false;
+  dap_match_mask        = 0;
+  dap_idle_cycles       = 0;
+  dap_retry_count       = 100;
+  dap_match_retry_count = 100;
+  dap_swd_turnaround    = 1;
+  dap_swd_data_phase    = false;
+#ifdef DAP_CONFIG_ENABLE_JTAG
+  dap_jtag_dev_count = 0;
+#endif
+
+  dap_setup_clock(DAP_CONFIG_DEFAULT_CLOCK);
+
+  DAP_CONFIG_SETUP();
+}
+
+//-----------------------------------------------------------------------------
+bool dap_filter_request(uint8_t *req)
+{
+  int cmd = req[0];
+
+  if (ID_DAP_TRANSFER_ABORT == cmd)
+  {
+    dap_abort = true;
+    return false;
+  }
+
+  return true;
+}
+
+//-----------------------------------------------------------------------------
+int dap_process_request(uint8_t *req, int req_size, uint8_t *resp, int resp_size)
+{
+  static const struct
+  {
+    int    cmd;
+    void   (*handler)(void);
+  } handlers[] =
+  {
+    { ID_DAP_INFO,			dap_info },
+    { ID_DAP_HOST_STATUS,		dap_host_status },
+    { ID_DAP_CONNECT,			dap_connect },
+    { ID_DAP_DISCONNECT,		dap_disconnect },
+    { ID_DAP_TRANSFER_CONFIGURE,	dap_transfer_configure },
+    { ID_DAP_TRANSFER,			dap_transfer },
+    { ID_DAP_TRANSFER_BLOCK,		dap_transfer_block },
+    { ID_DAP_TRANSFER_ABORT,		dap_transfer_abort },
+    { ID_DAP_WRITE_ABORT,		dap_write_abort },
+    { ID_DAP_DELAY,			dap_delay },
+    { ID_DAP_RESET_TARGET,		dap_reset_target },
+    { ID_DAP_SWJ_PINS,			dap_swj_pins },
+    { ID_DAP_SWJ_CLOCK,			dap_swj_clock },
+    { ID_DAP_SWJ_SEQUENCE,		dap_swj_sequence },
+    { ID_DAP_SWD_CONFIGURE,		dap_swd_configure },
+    { ID_DAP_SWD_SEQUENCE,		dap_swd_sequence },
+    { ID_DAP_JTAG_SEQUENCE,		dap_jtag_sequence },
+    { ID_DAP_JTAG_CONFIGURE,		dap_jtag_configure },
+    { ID_DAP_JTAG_IDCODE,		dap_jtag_idcode },
+  };
+  int cmd;
+
+  dap_buf_init(req, req_size, resp, resp_size);
+
+  dap_abort = false;
+
+#ifdef DAP_CONFIG_ENABLE_JTAG
+  dap_jtag_ir = JTAG_INVALID;
+#endif
+
+  cmd = dap_req_get_byte();
+  dap_resp_add_byte(cmd);
+
+  for (int i = 0; i < ARRAY_SIZE(handlers); i++)
+  {
+    if (cmd == handlers[i].cmd)
+    {
+      handlers[i].handler();
+      return dap_resp_ptr;
+    }
+  }
+
+  if (ID_DAP_VENDOR_0 <= cmd && cmd <= ID_DAP_VENDOR_31)
+  {
+#ifdef DAP_CONFIG_VENDOR_FN
+    DAP_CONFIG_VENDOR_FN(cmd - ID_DAP_VENDOR_0);
+#else
+    dap_resp_add_byte(DAP_ERROR);
+#endif
+    return dap_resp_ptr;
+  }
+
+  dap_resp_set_byte(0, ID_DAP_INVALID);
+
+  return dap_resp_ptr;
+}
+
+//-----------------------------------------------------------------------------
+void dap_clock_test(int delay)
+{
+  DAP_CONFIG_CONNECT_SWD();
+
+  if (delay)
+  {
+    dap_clock_delay = delay;
+
+    while (1)
+      dap_swj_run_slow(1<<30);
+  }
+  else
+  {
+    while (1)
+      dap_swj_run_fast(1<<30);
+  }
+}

+ 50 - 0
dap_link/lib/free-dap/dap.h

@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016, Alex Taradov <alex@taradov.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DAP_H_
+#define _DAP_H_
+
+/*- Includes ----------------------------------------------------------------*/
+#include <stdint.h>
+#include <stdbool.h>
+
+/*- Prototypes --------------------------------------------------------------*/
+void dap_init(void);
+uint8_t dap_req_get_byte(void);
+uint16_t dap_req_get_half(void);
+uint32_t dap_req_get_word(void);
+void dap_resp_add_byte(uint8_t value);
+void dap_resp_add_word(uint32_t value);
+void dap_resp_set_byte(int index, uint8_t value);
+bool dap_is_buf_error(void);
+bool dap_filter_request(uint8_t *req);
+int dap_process_request(uint8_t *req, int req_size, uint8_t *resp, int resp_size);
+void dap_clock_test(int delay);
+
+#endif // _DAP_H_
+

+ 3 - 0
dap_link/lib/free-dap/hardware/d11-nano-dbg/.gitignore

@@ -0,0 +1,3 @@
+output/
+fp-info-cache
+

BIN
dap_link/lib/free-dap/hardware/d11-nano-dbg/d11-nano-dbg-gerbers.zip


+ 4933 - 0
dap_link/lib/free-dap/hardware/d11-nano-dbg/d11-nano-dbg.kicad_pcb

@@ -0,0 +1,4933 @@
+(kicad_pcb (version 20211014) (generator pcbnew)
+
+  (general
+    (thickness 1.6)
+  )
+
+  (paper "User" 99.9998 99.9998)
+  (layers
+    (0 "F.Cu" signal)
+    (31 "B.Cu" signal)
+    (32 "B.Adhes" user "B.Adhesive")
+    (33 "F.Adhes" user "F.Adhesive")
+    (34 "B.Paste" user)
+    (35 "F.Paste" user)
+    (36 "B.SilkS" user "B.Silkscreen")
+    (37 "F.SilkS" user "F.Silkscreen")
+    (38 "B.Mask" user)
+    (39 "F.Mask" user)
+    (40 "Dwgs.User" user "User.Drawings")
+    (41 "Cmts.User" user "User.Comments")
+    (42 "Eco1.User" user "User.Eco1")
+    (43 "Eco2.User" user "User.Eco2")
+    (44 "Edge.Cuts" user)
+    (45 "Margin" user)
+    (46 "B.CrtYd" user "B.Courtyard")
+    (47 "F.CrtYd" user "F.Courtyard")
+    (48 "B.Fab" user)
+    (49 "F.Fab" user)
+    (50 "User.1" user)
+    (51 "User.2" user)
+    (52 "User.3" user)
+    (53 "User.4" user)
+    (54 "User.5" user)
+    (55 "User.6" user)
+    (56 "User.7" user)
+    (57 "User.8" user)
+    (58 "User.9" user)
+  )
+
+  (setup
+    (stackup
+      (layer "F.SilkS" (type "Top Silk Screen"))
+      (layer "F.Paste" (type "Top Solder Paste"))
+      (layer "F.Mask" (type "Top Solder Mask") (thickness 0.01))
+      (layer "F.Cu" (type "copper") (thickness 0.035))
+      (layer "dielectric 1" (type "core") (thickness 1.51) (material "FR4") (epsilon_r 4.5) (loss_tangent 0.02))
+      (layer "B.Cu" (type "copper") (thickness 0.035))
+      (layer "B.Mask" (type "Bottom Solder Mask") (thickness 0.01))
+      (layer "B.Paste" (type "Bottom Solder Paste"))
+      (layer "B.SilkS" (type "Bottom Silk Screen"))
+      (copper_finish "None")
+      (dielectric_constraints no)
+    )
+    (pad_to_mask_clearance 0)
+    (pcbplotparams
+      (layerselection 0x00010f0_ffffffff)
+      (disableapertmacros true)
+      (usegerberextensions true)
+      (usegerberattributes false)
+      (usegerberadvancedattributes false)
+      (creategerberjobfile false)
+      (svguseinch false)
+      (svgprecision 6)
+      (excludeedgelayer true)
+      (plotframeref false)
+      (viasonmask false)
+      (mode 1)
+      (useauxorigin false)
+      (hpglpennumber 1)
+      (hpglpenspeed 20)
+      (hpglpendiameter 15.000000)
+      (dxfpolygonmode true)
+      (dxfimperialunits true)
+      (dxfusepcbnewfont true)
+      (psnegative false)
+      (psa4output false)
+      (plotreference true)
+      (plotvalue true)
+      (plotinvisibletext false)
+      (sketchpadsonfab false)
+      (subtractmaskfromsilk true)
+      (outputformat 1)
+      (mirror false)
+      (drillshape 0)
+      (scaleselection 1)
+      (outputdirectory "output/")
+    )
+  )
+
+  (net 0 "")
+  (net 1 "+3V3")
+  (net 2 "VBUS")
+  (net 3 "/USB_DP")
+  (net 4 "/USB_DM")
+  (net 5 "/DBG_RESET")
+  (net 6 "/DBG_SWCLK")
+  (net 7 "/DBG_SWDIO")
+  (net 8 "/RESET")
+  (net 9 "unconnected-(IC2-Pad13)")
+  (net 10 "/DAP_STATUS")
+  (net 11 "GND")
+  (net 12 "Net-(LED1-Pad2)")
+  (net 13 "/SWDIO{slash}TMS")
+  (net 14 "/SWCLK{slash}TCK")
+  (net 15 "/TDI")
+  (net 16 "/TDO")
+  (net 17 "Net-(J1-PadCC1)")
+  (net 18 "Net-(J1-PadCC2)")
+  (net 19 "unconnected-(J1-PadSBU1)")
+  (net 20 "unconnected-(J1-PadSBU2)")
+  (net 21 "unconnected-(J2-Pad1)")
+  (net 22 "unconnected-(J2-Pad7)")
+
+  (footprint "ataradov_smd:0603" (layer "F.Cu")
+    (tedit 619DC0BD) (tstamp 32e1aed6-e06d-402f-b13b-cddeae58cd61)
+    (at 39.624 44.323)
+    (property "Sheetfile" "d11-nano-dbg.kicad_sch")
+    (property "Sheetname" "")
+    (path "/c594dcf2-f562-4ebf-9380-711463f31929")
+    (attr smd)
+    (fp_text reference "R3" (at 0 -1.905) (layer "F.SilkS")
+      (effects (font (size 1 1) (thickness 0.127)))
+      (tstamp a668461f-2467-4c7c-b09b-d27c45a5dab4)
+    )
+    (fp_text value "20K" (at 0 -0.016 unlocked) (layer "F.Fab")
+      (effects (font (size 0.5 0.5) (thickness 0.05)))
+      (tstamp 4362e285-ed61-4b80-8026-78eb23805bf7)
+    )
+    (fp_rect (start -1.55 -0.75) (end 1.55 0.75) (layer "F.SilkS") (width 0.127) (fill none) (tstamp ce03023a-ec3d-46b0-9a45-d078469826e8))
+    (pad "1" smd roundrect (at 0.8 0 90) (size 0.9 0.9) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25)
+      (net 11 "GND") (pinfunction "1") (pintype "passive") (tstamp ae545ba3-9447-46ee-95c9-5c85b1932c57))
+    (pad "2" smd roundrect (at -0.8 0 90) (size 0.9 0.9) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25)
+      (net 12 "Net-(LED1-Pad2)") (pinfunction "2") (pintype "passive") (tstamp 53c27afa-f7df-4f37-82a2-3dd3ba22a7ec))
+  )
+
+  (footprint "ataradov_conn:Header-5x2-1.27mm-SMD" (layer "F.Cu")
+    (tedit 61AE8C8C) (tstamp 7a194d1a-1282-4094-9dcc-620cb8f217b0)
+    (at 38.354 48.768 90)
+    (property "Sheetfile" "d11-nano-dbg.kicad_sch")
+    (property "Sheetname" "")
+    (path "/906df0a0-5839-47c0-b332-cec00bfc8d50")
+    (attr smd)
+    (fp_text reference "J2" (at 0 0 90) (layer "F.SilkS")
+      (effects (font (size 1 1) (thickness 0.127)))
+      (tstamp 6df354e5-0ed8-486f-aaba-922f1d8df851)
+    )
+    (fp_text value "Conn-5x2" (at 0 3.048 90) (layer "F.SilkS") hide
+      (effects (font (size 1 1) (thickness 0.127)))
+      (tstamp 70baef17-e834-4128-ab71-7a0e5bb0e8be)
+    )
+    (fp_line (start -3.175 -1.7) (end -3.175 1.7) (layer "F.SilkS") (width 0.127) (tstamp 29247d4e-2970-4492-af98-cbe5a7c43fda))
+    (fp_line (start -3.302 -0.0372) (end -3.302 1.6256) (layer "F.SilkS") (width 0.3) (tstamp 66d971b9-10a0-41f4-91b7-1d6842ea0b4d))
+    (fp_line (start 3.175 -1.7) (end 3.175 1.7) (layer "F.SilkS") (width 0.127) (tstamp 9e7cb52f-3bca-40b3-a79f-340d11cdb039))
+    (fp_line (start -3.175 -1.7) (end 3.175 -1.7) (layer "F.Fab") (width 0.127) (tstamp 75e89c98-f890-426a-8fa1-7783981e0a3c))
+    (fp_line (start -3.175 1.7) (end 3.175 1.7) (layer "F.Fab") (width 0.127) (tstamp ed9fa7f1-c410-42e5-9bc1-ad6bd344391f))
+    (pad "1" smd roundrect (at -2.54 1.95 90) (size 0.74 2.4) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25)
+      (net 21 "unconnected-(J2-Pad1)") (pinfunction "1") (pintype "passive") (tstamp cb7a5af0-8d51-414d-8e4c-5f9db1141b2f))
+    (pad "2" smd roundrect (at -2.54 -1.95 90) (size 0.74 2.4) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25)
+      (net 13 "/SWDIO{slash}TMS") (pinfunction "2") (pintype "passive") (tstamp 37fcecfd-ba35-4df5-a71d-0e7a66bc74fb))
+    (pad "3" smd roundrect (at -1.27 1.95 90) (size 0.74 2.4) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25)
+      (net 11 "GND") (pinfunction "3") (pintype "passive") (tstamp 4c728ffb-f86b-4b12-90f5-72928eba4635))
+    (pad "4" smd roundrect (at -1.27 -1.95 90) (size 0.74 2.4) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25)
+      (net 14 "/SWCLK{slash}TCK") (pinfunction "4") (pintype "passive") (tstamp 1aec843b-19a3-464f-95d8-f41d1700a83b))
+    (pad "5" smd roundrect (at 0 1.95 90) (size 0.74 2.4) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25)
+      (net 11 "GND") (pinfunction "5") (pintype "passive") (tstamp 11596021-3101-4865-a32f-e8bda3438fc6))
+    (pad "6" smd roundrect (at 0 -1.95 90) (size 0.74 2.4) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25)
+      (net 16 "/TDO") (pinfunction "6") (pintype "passive") (tstamp 9e7f6823-c792-4b1a-9c33-e92f86382381))
+    (pad "7" smd roundrect (at 1.27 1.95 90) (size 0.74 2.4) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25)
+      (net 22 "unconnected-(J2-Pad7)") (pinfunction "7") (pintype "passive") (tstamp f66e7f65-5501-4321-8ccd-03563508f0c3))
+    (pad "8" smd roundrect (at 1.27 -1.95 90) (size 0.74 2.4) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25)
+      (net 15 "/TDI") (pinfunction "8") (pintype "passive") (tstamp 6f8b6e75-4ad5-4b67-aeaa-581ac81efbdc))
+    (pad "9" smd roundrect (at 2.54 1.95 90) (size 0.74 2.4) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25)
+      (net 11 "GND") (pinfunction "9") (pintype "passive") (tstamp 36c4a32b-9a7b-41a6-9eb3-32a4e05cd500))
+    (pad "10" smd roundrect (at 2.54 -1.95 90) (size 0.74 2.4) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25)
+      (net 8 "/RESET") (pinfunction "10") (pintype "passive") (tstamp 3c8fa5c9-e85d-47eb-8ff6-525f12f1e0f8))
+  )
+
+  (footprint "ataradov_smd:0603" (layer "F.Cu")
+    (tedit 619DC0BD) (tstamp c1f62b01-cc0f-415e-a367-df007384a88c)
+    (at 36.449 44.323 180)
+    (property "Sheetfile" "d11-nano-dbg.kicad_sch")
+    (property "Sheetname" "")
+    (path "/6bc6f722-72ae-42d6-be95-2b8bf65cd61e")
+    (attr smd)
+    (fp_text reference "LED1" (at 0 1.905) (layer "F.SilkS")
+      (effects (font (size 1 1) (thickness 0.127)))
+      (tstamp 1907133f-48e1-4150-ab89-51c67883bf1a)
+    )
+    (fp_text value "Orange" (at 0 -0.016 180 unlocked) (layer "F.Fab")
+      (effects (font (size 0.5 0.5) (thickness 0.05)))
+      (tstamp 0445f7f3-026b-411c-ba1f-e7f7c086fe91)
+    )
+    (fp_rect (start -1.55 -0.75) (end 1.55 0.75) (layer "F.SilkS") (width 0.127) (fill none) (tstamp 37c085bb-79cf-44f4-a2c8-c1cd7a688918))
+    (pad "1" smd roundrect (at 0.8 0 270) (size 0.9 0.9) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25)
+      (net 10 "/DAP_STATUS") (pinfunction "A") (pintype "passive") (tstamp 7d4de8de-c0e7-4646-9ebb-1666506598eb))
+    (pad "2" smd roundrect (at -0.8 0 270) (size 0.9 0.9) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25)
+      (net 12 "Net-(LED1-Pad2)") (pinfunction "K") (pintype "passive") (tstamp 39a794f4-e7f9-49b7-86a7-6fc707cb176d))
+  )
+
+  (footprint "ataradov_conn:USB-C" (layer "F.Cu")
+    (tedit 61AC89AC) (tstamp f47134a4-be82-4ad4-a1ad-bf72ff4ae546)
+    (at 28.702 48.768 -90)
+    (property "Sheetfile" "d11-nano-dbg.kicad_sch")
+    (property "Sheetname" "")
+    (path "/9b533e2a-a396-4b85-abf3-b4e562338c74")
+    (attr smd)
+    (fp_text reference "J1" (at 0 4.064 90) (layer "F.SilkS")
+      (effects (font (size 1 1) (thickness 0.127)))
+      (tstamp 735ca608-844b-43da-824c-192e28c319d3)
+    )
+    (fp_text value "USB-C" (at 0 0 90) (layer "F.Fab")
+      (effects (font (size 1 1) (thickness 0.127)))
+      (tstamp b7bb8bee-8b45-4682-ba4f-3c97e6c96b19)
+    )
+    (fp_line (start 4.7 -2.945) (end 4.7 -1.143) (layer "F.SilkS") (width 0.127) (tstamp 074bd178-4b8d-4443-a5fb-cfcbc87a942c))
+    (fp_line (start -4.7 1.143) (end -4.7 2.667) (layer "F.SilkS") (width 0.127) (tstamp 4bcce46c-d9ae-4ab2-a9c8-5cc8f50b0e43))
+    (fp_line (start 4.699 1.143) (end 4.699 2.667) (layer "F.SilkS") (width 0.127) (tstamp 5c9a0412-4fb3-44e0-8564-dd1f1d19974f))
+    (fp_line (start -4.699 2.667) (end 4.699 2.667) (layer "F.SilkS") (width 0.127) (tstamp 616d2ae0-660e-4201-aead-18acef1aaa51))
+    (fp_line (start -4.7 -2.945) (end -4.7 -1.27) (layer "F.SilkS") (width 0.127) (tstamp de4ed296-9fb5-4bc2-9de6-dd78d5bf94a9))
+    (pad "" np_thru_hole circle (at 2.89 -3.68 270) (size 0.6858 0.6858) (drill 0.6858) (layers F&B.Cu *.Mask) (tstamp 66da1b23-6a31-4d09-b903-23246835c884))
+    (pad "" np_thru_hole circle (at -2.89 -3.68 270) (size 0.6858 0.6858) (drill 0.6858) (layers F&B.Cu *.Mask) (tstamp cb658bfb-bb44-442b-af68-cdf8168ed728))
+    (pad "CC1" smd rect (at -1.25 -5.131 270) (size 0.3 1.45) (layers "F.Cu" "F.Paste" "F.Mask")
+      (net 17 "Net-(J1-PadCC1)") (pinfunction "CC1") (pintype "bidirectional") (tstamp e7e6cb6d-7647-4949-b7bd-8bc1e899dd19))
+    (pad "CC2" smd rect (at 1.75 -5.131 270) (size 0.3 1.45) (layers "F.Cu" "F.Paste" "F.Mask")
+      (net 18 "Net-(J1-PadCC2)") (pinfunction "CC2") (pintype "bidirectional") (tstamp ffcbff8e-ab26-41db-bf1a-b4c132bdb8a6))
+    (pad "D+1" smd rect (at -0.25 -5.131 270) (size 0.3 1.45) (layers "F.Cu" "F.Paste" "F.Mask")
+      (net 3 "/USB_DP") (pinfunction "D+") (pintype "bidirectional") (tstamp 32e6d5f9-b73a-409b-a341-b80aa666fbb4))
+    (pad "D+2" smd rect (at 0.75 -5.131 270) (size 0.3 1.45) (layers "F.Cu" "F.Paste" "F.Mask")
+      (net 3 "/USB_DP") (pinfunction "D+") (pintype "bidirectional") (tstamp 9d5ddb59-1e9e-4537-9599-057acace239b))
+    (pad "D-1" smd rect (at 0.25 -5.131 270) (size 0.3 1.45) (layers "F.Cu" "F.Paste" "F.Mask")
+      (net 4 "/USB_DM") (pinfunction "D-") (pintype "bidirectional") (tstamp cd8fc82c-2372-4ab9-b58f-1c5bd1ca2b34))
+    (pad "D-2" smd rect (at -0.75 -5.131 270) (size 0.3 1.45) (layers "F.Cu" "F.Paste" "F.Mask")
+      (net 4 "/USB_DM") (pinfunction "D-") (pintype "bidirectional") (tstamp 31bc72e3-7b37-4039-ae03-b411f4438425))
+    (pad "GND1" smd rect (at -3.25 -5.131 270) (size 0.6 1.45) (layers "F.Cu" "F.Paste" "F.Mask")
+      (net 11 "GND") (pinfunction "GND") (pintype "passive") (tstamp b84bbe17-09c8-4aea-bd95-af34a96a069c))
+    (pad "GND2" smd rect (at 3.25 -5.131 270) (size 0.6 1.45) (layers "F.Cu" "F.Paste" "F.Mask")
+      (net 11 "GND") (pinfunction "GND") (pintype "passive") (tstamp 2eae7d9d-0d7d-4755-80a4-ff458c263895))
+    (pad "S1" thru_hole oval (at -4.32 0 270) (size 1 2.1) (drill oval 0.6 1.7) (layers *.Cu *.Mask)
+      (net 11 "GND") (pinfunction "S1") (pintype "passive") (tstamp b3dc6ebf-2791-42b3-a514-444efd66de71))
+    (pad "S2" thru_hole oval (at 4.32 0 270) (size 1 2.1) (drill oval 0.6 1.7) (layers *.Cu *.Mask)
+      (net 11 "GND") (pinfunction "S2") (pintype "passive") (tstamp 6f29f4c3-a661-4405-981e-bd400129444f))
+    (pad "S3" thru_hole oval (at -4.32 -4.18 270) (size 1 2.1) (drill oval 0.6 1.7) (layers *.Cu *.Mask)
+      (net 11 "GND") (pinfunction "S3") (pintype "passive") (tstamp e9b3c7ab-9a7d-41ab-b41f-c521c2f31bd3))
+    (pad "S4" thru_hole oval (at 4.32 -4.18 270) (size 1 2.1) (drill oval 0.6 1.7) (layers *.Cu *.Mask)
+      (net 11 "GND") (pinfunction "S4") (pintype "passive") (tstamp 414c44f1-6dc8-47ac-8734-d071cba6d2ba))
+    (pad "SBU1" smd rect (at 1.25 -5.131 270) (size 0.3 1.45) (layers "F.Cu" "F.Paste" "F.Mask")
+      (net 19 "unconnected-(J1-PadSBU1)") (pinfunction "SBU1") (pintype "bidirectional") (tstamp 3a95a55b-8a78-4e07-8313-782b4be21acd))
+    (pad "SBU2" smd rect (at -1.75 -5.131 270) (size 0.3 1.45) (layers "F.Cu" "F.Paste" "F.Mask")
+      (net 20 "unconnected-(J1-PadSBU2)") (pinfunction "SBU2") (pintype "bidirectional") (tstamp 6551c37f-9afc-4b25-9b2a-c1739b8edf17))
+    (pad "VBUS1" smd rect (at -2.45 -5.131 270) (size 0.6 1.45) (layers "F.Cu" "F.Paste" "F.Mask")
+      (net 2 "VBUS") (pinfunction "VBUS") (pintype "passive") (tstamp ce87f310-f0ba-406a-b736-4ce38509611a))
+    (pad "VBUS2" smd rect (at 2.45 -5.131 270) (size 0.6 1.45) (layers "F.Cu" "F.Paste" "F.Mask")
+      (net 2 "VBUS") (pinfunction "VBUS") (pintype "passive") (tstamp 5a8a64e8-0b04-48e4-b608-5cc887a127c8))
+  )
+
+  (footprint "ataradov_misc:TestPoint-1.27mm-SMD" (layer "B.Cu")
+    (tedit 619EF0AB) (tstamp 05dfa5dc-1e0b-48cf-837a-6693f652862f)
+    (at 40.386 53.213 180)
+    (property "Sheetfile" "d11-nano-dbg.kicad_sch")
+    (property "Sheetname" "")
+    (path "/bc214495-6305-49a3-bba3-3efe658c8dd7")
+    (attr through_hole)
+    (fp_text reference "TP1" (at 0 -1.778) (layer "B.SilkS") hide
+      (effects (font (size 1 1) (thickness 0.127)) (justify mirror))
+      (tstamp 9ba406a6-8a27-446b-ae89-6a25c468570c)
+    )
+    (fp_text value "SCK" (at -1.016 -2.159) (layer "B.SilkS")
+      (effects (font (size 1 1) (thickness 0.127)) (justify mirror))
+      (tstamp b509ccd3-18dc-4c38-9fda-b8d8cf2968f2)
+    )
+    (pad "1" smd circle (at 0 0 180) (size 1.27 1.27) (layers "B.Cu" "B.Paste" "B.Mask")
+      (net 6 "/DBG_SWCLK") (pinfunction "1") (pintype "passive") (tstamp 01f0f991-952f-4d5a-8ed6-4b7f3d0ef9a0))
+  )
+
+  (footprint "ataradov_ic:SOT-23" (layer "B.Cu")
+    (tedit 619F301D) (tstamp 19e98346-9ff5-4780-a0ff-39b8bda9823d)
+    (at 28.575 48.768 -90)
+    (property "Sheetfile" "d11-nano-dbg.kicad_sch")
+    (property "Sheetname" "")
+    (path "/e254f06c-00a2-4056-b804-b955996fa3d5")
+    (attr smd)
+    (fp_text reference "IC1" (at 0 6.35 90) (layer "B.SilkS")
+      (effects (font (size 1 1) (thickness 0.127)) (justify mirror))
+      (tstamp d40915c2-c548-4bfc-94d9-2378da8c19d2)
+    )
+    (fp_text value "SC662K-3.3" (at 0 0) (layer "B.Fab")
+      (effects (font (size 0.5 0.5) (thickness 0.1)) (justify mirror))
+      (tstamp a5cfabe5-76eb-4120-b957-2d4f7e1af535)
+    )
+    (fp_line (start 0.762 -1.45) (end -0.762 -1.45) (layer "B.SilkS") (width 0.127) (tstamp 0bb4f49e-d828-42b0-8fc4-d38e89c3245c))
+    (fp_line (start -0.762 0.471) (end -0.762 -0.471) (layer "B.SilkS") (width 0.127) (tstamp 32891493-b291-4664-9651-04dc091e0447))
+    (fp_line (start 0.762 1.45) (end -0.762 1.45) (layer "B.SilkS") (width 0.127) (tstamp 33285669-0d82-4e54-9717-2ad79c755fef))
+    (fp_line (start 0.762 -1.45) (end 0.762 -0.508) (layer "B.SilkS") (width 0.127) (tstamp db5015a7-9785-48ef-97f4-5bc6b0f4f5d7))
+    (fp_line (start 0.762 1.45) (end 0.762 0.508) (layer "B.SilkS") (width 0.127) (tstamp e940abae-4b03-4d64-833d-2c2a8f4b7ce6))
+    (pad "1" smd roundrect (at -0.9375 0.95 270) (size 1.475 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 11 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 28958724-af64-44ab-b76c-76f4c4f868dd))
+    (pad "2" smd roundrect (at -0.9375 -0.95 270) (size 1.475 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 1 "+3V3") (pinfunction "OUT") (pintype "power_out") (tstamp 82ba3ef4-94c4-43fb-89d1-698770c63ae8))
+    (pad "3" smd roundrect (at 0.9375 0 270) (size 1.475 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 2 "VBUS") (pinfunction "IN") (pintype "power_in") (tstamp cb1a83f5-6f2a-4777-9b4a-c17977214c7d))
+  )
+
+  (footprint "ataradov_smd:0603" (layer "B.Cu")
+    (tedit 619DC0BD) (tstamp 3afdb8be-29c7-445a-af42-1a3dd57fe4d6)
+    (at 28.575 51.308)
+    (property "Sheetfile" "d11-nano-dbg.kicad_sch")
+    (property "Sheetname" "")
+    (path "/e06501c8-2845-4054-9787-05ce88080176")
+    (attr smd)
+    (fp_text reference "C1" (at -6.312 0) (layer "B.SilkS")
+      (effects (font (size 1 1) (thickness 0.127)) (justify mirror))
+      (tstamp 997ca21c-d5a6-4b13-99d9-65b16ac4ad4d)
+    )
+    (fp_text value "1uF" (at 0 0.016 180 unlocked) (layer "B.Fab")
+      (effects (font (size 0.5 0.5) (thickness 0.05)) (justify mirror))
+      (tstamp 616bbbfc-aca8-4a03-9e9c-2e9f24259012)
+    )
+    (fp_rect (start -1.55 0.75) (end 1.55 -0.75) (layer "B.SilkS") (width 0.127) (fill none) (tstamp b882554c-74d3-47ed-aa5e-bff025add75c))
+    (pad "1" smd roundrect (at 0.8 0 270) (size 0.9 0.9) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 11 "GND") (pinfunction "1") (pintype "passive") (tstamp 55a1a58d-3641-458b-9f6f-6e3e3b99d4c3))
+    (pad "2" smd roundrect (at -0.8 0 270) (size 0.9 0.9) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 2 "VBUS") (pinfunction "2") (pintype "passive") (tstamp dd8157be-a2ed-43e3-bae5-e3b2dd871542))
+  )
+
+  (footprint "ataradov_smd:0603" (layer "B.Cu")
+    (tedit 619DC0BD) (tstamp 6b52c9e8-9a62-4da1-9af3-2229dd721180)
+    (at 30.988 51.181 -90)
+    (property "Sheetfile" "d11-nano-dbg.kicad_sch")
+    (property "Sheetname" "")
+    (path "/35477d2d-d398-4f18-becb-e7baa5331236")
+    (attr smd)
+    (fp_text reference "R1" (at 0 6.35 90) (layer "B.SilkS")
+      (effects (font (size 1 1) (thickness 0.127)) (justify mirror))
+      (tstamp b84e5c3c-d5ba-45dc-a996-457d3d15ea34)
+    )
+    (fp_text value "5.1K" (at 0 0.016 90 unlocked) (layer "B.Fab")
+      (effects (font (size 0.5 0.5) (thickness 0.05)) (justify mirror))
+      (tstamp 9f9a1dc2-1e64-4561-84e9-c59e56eccfbe)
+    )
+    (fp_rect (start -1.55 0.75) (end 1.55 -0.75) (layer "B.SilkS") (width 0.127) (fill none) (tstamp 06c3c04c-6c4b-4c5d-8552-dca1efe1a3db))
+    (pad "1" smd roundrect (at 0.8 0 180) (size 0.9 0.9) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 11 "GND") (pinfunction "1") (pintype "passive") (tstamp 1427eabc-18a4-411d-bd11-428ec8bd285d))
+    (pad "2" smd roundrect (at -0.8 0 180) (size 0.9 0.9) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 18 "Net-(J1-PadCC2)") (pinfunction "2") (pintype "passive") (tstamp a55e1730-9cc6-449f-95c7-a4b048ce6ae3))
+  )
+
+  (footprint "ataradov_smd:0603" (layer "B.Cu")
+    (tedit 619DC0BD) (tstamp 6f0cedfe-c86d-4e25-b64a-6c2635e4efb5)
+    (at 30.988 46.609 90)
+    (property "Sheetfile" "d11-nano-dbg.kicad_sch")
+    (property "Sheetname" "")
+    (path "/6e18622d-ab16-46d3-8547-8e9d6c8c3481")
+    (attr smd)
+    (fp_text reference "R2" (at 0 -6.35 90) (layer "B.SilkS")
+      (effects (font (size 1 1) (thickness 0.127)) (justify mirror))
+      (tstamp 8d83e328-7f8e-4ff2-9f4c-9b7ab1a82636)
+    )
+    (fp_text value "5.1K" (at 0 0.016 270 unlocked) (layer "B.Fab")
+      (effects (font (size 0.5 0.5) (thickness 0.05)) (justify mirror))
+      (tstamp de13e0f2-e58c-4cc2-84c5-b6bd1aedd8ac)
+    )
+    (fp_rect (start -1.55 0.75) (end 1.55 -0.75) (layer "B.SilkS") (width 0.127) (fill none) (tstamp 0bb237b7-3c36-4dd2-83be-cd2c222b4c4e))
+    (pad "1" smd roundrect (at 0.8 0) (size 0.9 0.9) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 11 "GND") (pinfunction "1") (pintype "passive") (tstamp e7165906-145f-4c8c-8c9a-48e9112ef2d2))
+    (pad "2" smd roundrect (at -0.8 0) (size 0.9 0.9) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 17 "Net-(J1-PadCC1)") (pinfunction "2") (pintype "passive") (tstamp 4629e325-a0a2-4fa0-9b82-0617c92179cc))
+  )
+
+  (footprint "ataradov_misc:TestPoint-1.27mm-SMD" (layer "B.Cu")
+    (tedit 619EF0AB) (tstamp 7b836b8f-e2f7-4a02-aaea-5f5f23bb6c5e)
+    (at 35.306 53.213 180)
+    (property "Sheetfile" "d11-nano-dbg.kicad_sch")
+    (property "Sheetname" "")
+    (path "/87a0447f-dae7-4542-8125-f968e31d4a91")
+    (attr through_hole)
+    (fp_text reference "TP3" (at 0 -1.778) (layer "B.SilkS") hide
+      (effects (font (size 1 1) (thickness 0.127)) (justify mirror))
+      (tstamp ac58d217-7773-40c4-9e1b-a9e653b34666)
+    )
+    (fp_text value "SIO" (at 0.254 -2.159) (layer "B.SilkS")
+      (effects (font (size 1 1) (thickness 0.127)) (justify mirror))
+      (tstamp 256c2c4a-be75-489c-bc59-8ced96c0005c)
+    )
+    (pad "1" smd circle (at 0 0 180) (size 1.27 1.27) (layers "B.Cu" "B.Paste" "B.Mask")
+      (net 7 "/DBG_SWDIO") (pinfunction "1") (pintype "passive") (tstamp b4164dff-a67d-4a09-89cd-16ff1d75beb6))
+  )
+
+  (footprint "ataradov_smd:0603" (layer "B.Cu")
+    (tedit 619DC0BD) (tstamp 97485eee-4c91-4308-83e7-1477047e7584)
+    (at 28.575 46.101 180)
+    (property "Sheetfile" "d11-nano-dbg.kicad_sch")
+    (property "Sheetname" "")
+    (path "/03c058db-b9f4-404f-9c24-1f1dab858e28")
+    (attr smd)
+    (fp_text reference "C2" (at 6.223 0) (layer "B.SilkS")
+      (effects (font (size 1 1) (thickness 0.127)) (justify mirror))
+      (tstamp cb559ad4-d4c9-4967-80f0-1721719cbbf5)
+    )
+    (fp_text value "1uF" (at 0 0.016 unlocked) (layer "B.Fab")
+      (effects (font (size 0.5 0.5) (thickness 0.05)) (justify mirror))
+      (tstamp bcda320e-74b3-4653-8282-0c5ff42ec64e)
+    )
+    (fp_rect (start -1.55 0.75) (end 1.55 -0.75) (layer "B.SilkS") (width 0.127) (fill none) (tstamp ec55ebe1-2c41-4a8f-a5d4-712c2c0634fb))
+    (pad "1" smd roundrect (at 0.8 0 90) (size 0.9 0.9) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 11 "GND") (pinfunction "1") (pintype "passive") (tstamp 15ae40eb-6838-4ed2-9b40-dae8638bca84))
+    (pad "2" smd roundrect (at -0.8 0 90) (size 0.9 0.9) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 1 "+3V3") (pinfunction "2") (pintype "passive") (tstamp 37b60c7b-11d8-4a12-81bb-66d528948c72))
+  )
+
+  (footprint "ataradov_misc:TestPoint-1.27mm-SMD" (layer "B.Cu")
+    (tedit 619EF0AB) (tstamp a151a7e9-3daa-41e5-bcfb-1516700dbccb)
+    (at 37.846 53.213 180)
+    (property "Sheetfile" "d11-nano-dbg.kicad_sch")
+    (property "Sheetname" "")
+    (path "/6173c660-2127-4241-96b1-bfeb7449ff5f")
+    (attr through_hole)
+    (fp_text reference "TP2" (at 0 -1.778) (layer "B.SilkS") hide
+      (effects (font (size 1 1) (thickness 0.127)) (justify mirror))
+      (tstamp 3e0dffa9-b3d3-4400-957b-783269ff3979)
+    )
+    (fp_text value "RST" (at -0.381 -2.159) (layer "B.SilkS")
+      (effects (font (size 1 1) (thickness 0.127)) (justify mirror))
+      (tstamp 3d41e5bb-4455-4993-ae39-bd6ab836a81d)
+    )
+    (pad "1" smd circle (at 0 0 180) (size 1.27 1.27) (layers "B.Cu" "B.Paste" "B.Mask")
+      (net 5 "/DBG_RESET") (pinfunction "1") (pintype "passive") (tstamp aa77a0ad-aac3-4734-9015-ed94cd1af9fe))
+  )
+
+  (footprint "ataradov_ic:SOIC-14" (layer "B.Cu")
+    (tedit 619ED1E9) (tstamp c834efbe-45e0-42bb-931e-de0f2ded443b)
+    (at 37.846 48.514 180)
+    (property "Sheetfile" "d11-nano-dbg.kicad_sch")
+    (property "Sheetname" "")
+    (path "/e9485002-0b5c-4f78-8d49-67004f0e4d8e")
+    (attr smd)
+    (fp_text reference "IC2" (at 0 0 90) (layer "B.SilkS")
+      (effects (font (size 1 1) (thickness 0.127)) (justify mirror))
+      (tstamp 19cfaf16-515c-47a4-b16a-e069a7b08a45)
+    )
+    (fp_text value "ATSAMD11C" (at 0 0 90) (layer "B.Fab")
+      (effects (font (size 0.7 0.7) (thickness 0.1)) (justify mirror))
+      (tstamp de940fc7-dcb5-4581-b230-bd0f5b624a23)
+    )
+    (fp_line (start 1.27 -4.318) (end 1.27 4.318) (layer "B.SilkS") (width 0.127) (tstamp 1e3a8c0c-535a-4b1b-b1f2-82ddbee34aa4))
+    (fp_line (start 1.27 -4.318) (end -1.27 -4.318) (layer "B.SilkS") (width 0.127) (tstamp 548b70f9-8a40-41fa-8b4c-4a7e34d04793))
+    (fp_line (start -1.27 -4.318) (end -1.27 4.318) (layer "B.SilkS") (width 0.127) (tstamp 59231daa-dec1-4466-a546-ca69ed3fb153))
+    (fp_line (start 1.27 4.318) (end -1.27 4.318) (layer "B.SilkS") (width 0.127) (tstamp 880d85f4-3f8c-47ce-823a-f81a45ffeaf8))
+    (fp_line (start -0.508 4.318) (end -1.27 3.556) (layer "B.SilkS") (width 0.127) (tstamp f82a4d55-22b8-4003-846f-f1565d9a2c2c))
+    (pad "1" smd roundrect (at -2.6 3.81 180) (size 1.778 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 8 "/RESET") (pinfunction "PA5") (pintype "bidirectional") (tstamp fe45c4a1-51cd-4239-8a94-676cbced478b))
+    (pad "2" smd roundrect (at -2.6 2.54 180) (size 1.778 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 15 "/TDI") (pinfunction "PA8") (pintype "bidirectional") (tstamp d1a68b06-c7bc-4fbc-a5a3-0fdf88d1465c))
+    (pad "3" smd roundrect (at -2.6 1.27 180) (size 1.778 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 16 "/TDO") (pinfunction "PA9") (pintype "bidirectional") (tstamp af682c9c-0ba6-4624-abc2-85dc01025aad))
+    (pad "4" smd roundrect (at -2.6 0 180) (size 1.778 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 14 "/SWCLK{slash}TCK") (pinfunction "PA14") (pintype "bidirectional") (tstamp 116b9c9a-ed97-48be-b153-90023f79c98b))
+    (pad "5" smd roundrect (at -2.6 -1.27 180) (size 1.778 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 13 "/SWDIO{slash}TMS") (pinfunction "PA15") (pintype "bidirectional") (tstamp 0d425d1f-2ee5-4166-941f-6a874a702f21))
+    (pad "6" smd roundrect (at -2.6 -2.54 180) (size 1.778 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 5 "/DBG_RESET") (pinfunction "PA28/RST") (pintype "bidirectional") (tstamp d0404e6e-fadf-4e24-ace6-2688ac39aaf8))
+    (pad "7" smd roundrect (at -2.6 -3.81 180) (size 1.778 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 6 "/DBG_SWCLK") (pinfunction "PA30/SCK") (pintype "bidirectional") (tstamp 160bb068-3826-422e-ae99-8ad8874c92fe))
+    (pad "8" smd roundrect (at 2.6 -3.81 180) (size 1.778 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 7 "/DBG_SWDIO") (pinfunction "PA31/SIO") (pintype "bidirectional") (tstamp 2a7c9c83-7c2e-42c0-8c82-c9cb0db11e29))
+    (pad "9" smd roundrect (at 2.6 -2.54 180) (size 1.778 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 4 "/USB_DM") (pinfunction "PA24/DM") (pintype "bidirectional") (tstamp 2cad5409-3aa7-4aa4-b71f-96948b556eae))
+    (pad "10" smd roundrect (at 2.6 -1.27 180) (size 1.778 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 3 "/USB_DP") (pinfunction "PA25/DP") (pintype "bidirectional") (tstamp 983f632b-be87-4f0a-b131-1b9b12b7b95f))
+    (pad "11" smd roundrect (at 2.6 0 180) (size 1.778 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 11 "GND") (pinfunction "GND") (pintype "power_in") (tstamp 47e80c4e-c13e-4143-a6de-eb9ab8b3b46b))
+    (pad "12" smd roundrect (at 2.6 1.27 180) (size 1.778 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 1 "+3V3") (pinfunction "VDD") (pintype "power_in") (tstamp bfafc0f2-d551-4984-a1aa-a611aa64c019))
+    (pad "13" smd roundrect (at 2.6 2.54 180) (size 1.778 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 9 "unconnected-(IC2-Pad13)") (pinfunction "PA2") (pintype "bidirectional") (tstamp 54c01e80-6e93-4dbc-b14b-f15d9363c545))
+    (pad "14" smd roundrect (at 2.6 3.81 180) (size 1.778 0.6) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25)
+      (net 10 "/DAP_STATUS") (pinfunction "PA4") (pintype "bidirectional") (tstamp 97e3cd55-b42b-42ff-9d40-a035e64ab35d))
+  )
+
+  (gr_rect (start 26.924 43.307) (end 42.1386 54.229) (layer "Edge.Cuts") (width 0.127) (fill none) (tstamp 6991a980-01b5-4b07-b4ba-4e70322165c8))
+  (gr_text "2022-04-07" (at 30.861 48.514 90) (layer "F.SilkS") (tstamp 26801cfb-b53b-4a6a-a2f4-5f4986565765)
+    (effects (font (size 0.8 0.8) (thickness 0.1)))
+  )
+  (gr_text "1" (at 40.767 53.086 90) (layer "F.SilkS") (tstamp 47365df8-1aaa-451c-a591-086776031635)
+    (effects (font (size 1 1) (thickness 0.127)))
+  )
+  (gr_text "AT" (at 28.702 48.768 -270) (layer "F.SilkS") (tstamp 7e8ac3d0-7727-403e-81e8-73e25aba4564)
+    (effects (font (size 1.5 1.5) (thickness 0.254)))
+  )
+
+  (segment (start 29.906 46.802) (end 29.525 46.802) (width 0.254) (layer "B.Cu") (net 1) (tstamp 0c0b82a0-19b3-45c0-a98f-0104b6ac7cfa))
+  (segment (start 29.525 46.251) (end 29.525 46.802) (width 0.254) (layer "B.Cu") (net 1) (tstamp 19a450e3-949c-4268-b3cd-05ce76ff367a))
+  (segment (start 34.163 47.244) (end 33.528 46.609) (width 0.254) (layer "B.Cu") (net 1) (tstamp 336b67ea-1a3c-40d5-9f02-73b08e7cd48e))
+  (segment (start 29.375 46.101) (end 29.525 46.251) (width 0.254) (layer "B.Cu") (net 1) (tstamp 64f83893-6f01-4d18-8094-b778d70558a9))
+  (segment (start 29.525 46.802) (end 29.525 47.8305) (width 0.254) (layer "B.Cu") (net 1) (tstamp 95355da9-c29c-4fac-8a19-041a9a083a58))
+  (segment (start 33.528 46.609) (end 30.099 46.609) (width 0.254) (layer "B.Cu") (net 1) (tstamp 97c6c8ef-1604-40a2-9645-7a107204de21))
+  (segment (start 30.099 46.609) (end 29.906 46.802) (width 0.254) (layer "B.Cu") (net 1) (tstamp af073fa6-a783-40f2-9751-692984a62ffc))
+  (segment (start 35.246 47.244) (end 34.163 47.244) (width 0.254) (layer "B.Cu") (net 1) (tstamp ea483516-4820-43a6-9a84-96ab16c456d0))
+  (segment (start 31.496 46.609) (end 30.607 47.498) (width 0.254) (layer "F.Cu") (net 2) (tstamp 045c9dcb-1c2f-437e-b741-c898c0bc151a))
+  (segment (start 29.613128 49.679128) (end 30.607 49.679128) (width 0.254) (layer "F.Cu") (net 2) (tstamp 0ea29eea-ed68-49b2-9e22-6c18bf8d49ad))
+  (segment (start 33.833 46.318) (end 33.018 46.318) (width 0.254) (layer "F.Cu") (net 2) (tstamp 12027d9c-0f1e-4c18-a1b8-f862f8c90f0f))
+  (segment (start 32.93 51.218) (end 33.833 51.218) (width 0.254) (layer "F.Cu") (net 2) (tstamp 31adb287-7375-4740-9ce3-47dc0189625e))
+  (segment (start 30.607 49.679128) (end 30.607 50.165) (width 0.254) (layer "F.Cu") (net 2) (tstamp 46d70e75-ef7c-4bd6-834d-3952b67e9190))
+  (segment (start 32.727 46.609) (end 31.496 46.609) (width 0.254) (layer "F.Cu") (net 2) (tstamp 8415fb44-de71-4cbc-9133-9df37162e986))
+  (segment (start 33.018 46.318) (end 32.727 46.609) (width 0.254) (layer "F.Cu") (net 2) (tstamp a1c4e8cd-207e-42eb-a8c2-7d09a891d7e5))
+  (segment (start 32.67402 50.96202) (end 32.93 51.218) (width 0.254) (layer "F.Cu") (net 2) (tstamp af6d04d8-fb55-44a6-8d61-46b5fe0d57ed))
+  (segment (start 30.607 47.498) (end 30.607 49.679128) (width 0.254) (layer "F.Cu") (net 2) (tstamp c61318d9-11c6-4932-9e6d-03ca4bb14172))
+  (segment (start 30.607 50.165) (end 31.40402 50.96202) (width 0.254) (layer "F.Cu") (net 2) (tstamp df60abce-5d8f-47b1-8a1e-e84467d2708f))
+  (segment (start 29.591 49.657) (end 29.613128 49.679128) (width 0.254) (layer "F.Cu") (net 2) (tstamp e1885d11-e8fd-45e1-9237-1f5c33816018))
+  (segment (start 31.40402 50.96202) (end 32.67402 50.96202) (width 0.254) (layer "F.Cu") (net 2) (tstamp f767c241-0d2a-4a60-af21-e950fbb9f412))
+  (via (at 29.591 49.657) (size 0.6858) (drill 0.3302) (layers "F.Cu" "B.Cu") (net 2) (tstamp f26d4370-ccd0-4f31-9650-b7d3e2ea7fbc))
+  (segment (start 29.5425 49.7055) (end 28.575 49.7055) (width 0.254) (layer "B.Cu") (net 2) (tstamp 67f1aadd-abbf-42af-b69d-c0bc8ff3c54d))
+  (segment (start 27.775 50.076) (end 28.1455 49.7055) (width 0.254) (layer "B.Cu") (net 2) (tstamp 7c7098b7-90fc-49ab-8ca6-e8b355725702))
+  (segment (start 27.775 51.308) (end 27.775 50.076) (width 0.254) (layer "B.Cu") (net 2) (tstamp a035d06a-59fd-4fbe-82f6-0a506f9568d5))
+  (segment (start 28.1455 49.7055) (end 28.575 49.7055) (width 0.254) (layer "B.Cu") (net 2) (tstamp b960b425-3db8-465d-a51c-191ba88204d8))
+  (segment (start 29.591 49.657) (end 29.5425 49.7055) (width 0.254) (layer "B.Cu") (net 2) (tstamp ca0f9c33-78f8-41d7-980d-db7b0aa19e57))
+  (segment (start 32.823978 49.518) (end 33.833 49.518) (width 0.254) (layer "F.Cu") (net 3) (tstamp 0b8acda2-e6d4-4de7-b591-ea0c9b51fcec))
+  (segment (start 32.790989 49.485011) (end 32.823978 49.518) (width 0.254) (layer "F.Cu") (net 3) (tstamp 0f015f70-b9be-4792-8502-9235baab7ad3))
+  (segment (start 32.790989 48.550989) (end 32.790989 49.485011) (width 0.254) (layer "F.Cu") (net 3) (tstamp 7ef98de2-0407-484c-b75f-d3f0938f17b0))
+  (segment (start 31.451011 49.485011) (end 32.790989 49.485011) (width 0.254) (layer "F.Cu") (net 3) (tstamp 9e78a024-04b9-4495-9b00-70110a769581))
+  (segment (start 33.833 48.518) (end 32.823978 48.518) (width 0.254) (layer "F.Cu") (net 3) (tstamp c3c02496-b038-43f1-99b8-409718a4222c))
+  (segment (start 32.823978 48.518) (end 32.790989 48.550989) (width 0.254) (layer "F.Cu") (net 3) (tstamp cf9b593f-7152-4b36-a501-419aa3f30746))
+  (segment (start 31.369 49.403) (end 31.451011 49.485011) (width 0.254) (layer "F.Cu") (net 3) (tstamp e146d015-6705-4cde-abb1-6357687c3398))
+  (via (at 31.369 49.403) (size 0.6858) (drill 0.3302) (layers "F.Cu" "B.Cu") (net 3) (tstamp 50d814c8-1fd5-4a17-9c0f-8be9586b07ae))
+  (segment (start 31.774911 48.108089) (end 32.614089 48.108089) (width 0.254) (layer "B.Cu") (net 3) (tstamp 082ecb16-bdc7-404f-9607-610400050981))
+  (segment (start 31.369 49.403) (end 31.369 48.514) (width 0.254) (layer "B.Cu") (net 3) (tstamp 6a91511d-b6b1-48b1-b832-9887de6e1d0a))
+  (segment (start 34.29 49.784) (end 35.246 49.784) (width 0.254) (layer "B.Cu") (net 3) (tstamp 8bca586c-ecb9-400d-98df-9f7b166628e3))
+  (segment (start 32.614089 48.108089) (end 34.29 49.784) (width 0.254) (layer "B.Cu") (net 3) (tstamp ded7d347-52c5-4a97-9650-e86590ab5e28))
+  (segment (start 31.369 48.514) (end 31.774911 48.108089) (width 0.254) (layer "B.Cu") (net 3) (tstamp f6c1fb05-f81c-446b-a20c-531c1a6bc16f))
+  (segment (start 32.131 48.768) (end 32.131 48.583038) (width 0.254) (layer "F.Cu") (net 4) (tstamp 10139ec9-5972-4c3e-9672-4814ee8cc191))
+  (segment (start 34.875011 48.985011) (end 34.875011 48.050989) (width 0.254) (layer "F.Cu") (net 4) (tstamp 2a961c79-236b-4c50-8af0-de45bbb3d124))
+  (segment (start 34.842022 49.018) (end 34.875011 48.985011) (width 0.254) (layer "F.Cu") (net 4) (tstamp 3ae45cde-2f66-4648-86af-fdbb3e733a45))
+  (segment (start 32.131 48.583038) (end 32.696038 48.018) (width 0.254) (layer "F.Cu") (net 4) (tstamp 49a15ec4-1ee2-441c-9620-bd8ce61cfd12))
+  (segment (start 34.875011 48.050989) (end 34.842022 48.018) (width 0.254) (layer "F.Cu") (net 4) (tstamp 5af25360-2780-44b0-bb33-51b7ffc33c8f))
+  (segment (start 32.696038 48.018) (end 33.833 48.018) (width 0.254) (layer "F.Cu") (net 4) (tstamp 812d64fc-5b6c-4013-ace7-40b1d6d957a7))
+  (segment (start 34.842022 48.018) (end 33.833 48.018) (width 0.254) (layer "F.Cu") (net 4) (tstamp 9498f1ae-3386-4d83-87c2-ea53dadab262))
+  (segment (start 33.833 49.018) (end 34.842022 49.018) (width 0.254) (layer "F.Cu") (net 4) (tstamp b3a1c996-2760-4a5d-a32d-31af1edb675a))
+  (via (at 32.131 48.768) (size 0.6858) (drill 0.3302) (layers "F.Cu" "B.Cu") (net 4) (tstamp 53db68a7-14e8-4baa-ac45-daadd65513d1))
+  (segment (start 32.131 48.768) (end 32.131 48.895) (width 0.254) (layer "B.Cu") (net 4) (tstamp a164207d-01bf-42fe-b8da-a52533a5de36))
+  (segment (start 32.131 48.895) (end 34.29 51.054) (width 0.254) (layer "B.Cu") (net 4) (tstamp a41f4944-f406-4570-bdd5-bd77844d2b14))
+  (segment (start 34.29 51.054) (end 35.246 51.054) (width 0.254) (layer "B.Cu") (net 4) (tstamp c878c2eb-9c7e-4340-9d79-e0098685d083))
+  (segment (start 39.243 51.054) (end 37.846 52.451) (width 0.254) (layer "B.Cu") (net 5) (tstamp 5a370285-3fca-48a0-ac23-6c35c61a476f))
+  (segment (start 40.446 51.054) (end 39.243 51.054) (width 0.254) (layer "B.Cu") (net 5) (tstamp 606d6437-7700-447e-b2c2-8432f8e0d1cc))
+  (segment (start 37.846 52.451) (end 37.846 53.213) (width 0.254) (layer "B.Cu") (net 5) (tstamp b6e5dda2-21c6-4b02-b7ec-d845d81507f8))
+  (segment (start 36.404 46.228) (end 37.719 46.228) (width 0.254) (layer "F.Cu") (net 8) (tstamp 02972456-a240-42eb-9d6a-d7b3e3d8a5bf))
+  (segment (start 37.719 46.228) (end 38.354 45.593) (width 0.254) (layer "F.Cu") (net 8) (tstamp 11527c6f-6046-48b9-94b7-0dc450aea666))
+  (via (at 38.354 45.593) (size 0.6858) (drill 0.3302) (layers "F.Cu" "B.Cu") (net 8) (tstamp 8e6e0abc-c8ef-49f0-bfaf-3db59d43de39))
+  (segment (start 38.354 45.593) (end 39.243 44.704) (width 0.254) (layer "B.Cu") (net 8) (tstamp 78141789-e4fe-43ce-bdd6-304785c67c69))
+  (segment (start 39.243 44.704) (end 40.446 44.704) (width 0.254) (layer "B.Cu") (net 8) (tstamp fdc069c5-d742-4791-b7ae-e387baba433b))
+  (via (at 34.925 44.45) (size 0.6858) (drill 0.3302) (layers "F.Cu" "B.Cu") (net 10) (tstamp a9047d2b-6209-45c2-8fe6-b2987725d674))
+  (segment (start 33.833 52.018) (end 33.833 52.137) (width 0.254) (layer "F.Cu") (net 11) (tstamp 74b4bc2b-6fd1-4944-93b1-54d0f94622c2))
+  (segment (start 33.833 45.518) (end 33.833 45.399) (width 0.254) (layer "F.Cu") (net 11) (tstamp 7879eef7-0cd6-4b28-a2a3-4b84c2150254))
+  (segment (start 33.833 52.137) (end 32.882 53.088) (width 0.254) (layer "F.Cu") (net 11) (tstamp 7bb456e2-7bbc-4e01-ac2e-b307b9041d17))
+  (segment (start 33.833 45.399) (end 32.882 44.448) (width 0.254) (layer "F.Cu") (net 11) (tstamp b87a01ba-9438-409e-8ee0-7b599746cffd))
+  (via (at 28.575 47.879) (size 0.6858) (drill 0.3302) (layers "F.Cu" "B.Cu") (free) (net 11) (tstamp 41dfb0e8-c668-4288-b549-95d038dba148))
+  (via (at 30.734 53.086) (size 0.6858) (drill 0.3302) (layers "F.Cu" "B.Cu") (free) (net 11) (tstamp 458513e8-47cf-4f71-9c1e-98e47f11581e))
+  (via (at 30.734 44.45) (size 0.6858) (drill 0.3302) (layers "F.Cu" "B.Cu") (free) (net 11) (tstamp c35c0822-5f46-49b7-8c5f-b08edd39cc53))
+  (via (at 36.576 53.213) (size 0.6858) (drill 0.3302) (layers "F.Cu" "B.Cu") (free) (net 11) (tstamp f921b4a8-3d66-4012-86a4-64b811ee458c))
+  (via (at 39.116 53.213) (size 0.6858) (drill 0.3302) (layers "F.Cu" "B.Cu") (free) (net 11) (tstamp fc4ead07-2c75-4f81-b5b2-9b940d5c0fbf))
+  (segment (start 27.625 46.251) (end 27.775 46.101) (width 0.254) (layer "B.Cu") (net 11) (tstamp 64c3b56e-9893-49f5-8367-6228bbe40788))
+  (segment (start 27.625 47.8305) (end 27.625 46.251) (width 0.254) (layer "B.Cu") (net 11) (tstamp 83ae7dbf-fe84-437d-ab57-38fb182aa005))
+  (segment (start 37.249 44.323) (end 38.824 44.323) (width 0.254) (layer "F.Cu") (net 12) (tstamp c30b6f51-5bc9-4a76-8a03-fc4a35281769))
+  (segment (start 36.404 51.308) (end 37.719 51.308) (width 0.254) (layer "F.Cu") (net 13) (tstamp cdf0a73c-2149-4713-a240-7d3f0dffbe2b))
+  (segment (start 37.719 51.308) (end 38.354 50.673) (width 0.254) (layer "F.Cu") (net 13) (tstamp d189afac-1499-463a-9424-ef880030190b))
+  (via (at 38.354 50.673) (size 0.6858) (drill 0.3302) (layers "F.Cu" "B.Cu") (net 13) (tstamp e1f6b4b4-e611-4235-8ed9-ebcf3807e5bf))
+  (segment (start 39.243 49.784) (end 40.446 49.784) (width 0.254) (layer "B.Cu") (net 13) (tstamp 5215b5ac-69ed-4877-b041-72656f57d8b8))
+  (segment (start 38.354 50.673) (end 39.243 49.784) (width 0.254) (layer "B.Cu") (net 13) (tstamp 84c82ab9-c335-4ed3-a706-f084ed5f2df9))
+  (segment (start 37.719 50.038) (end 38.354 49.403) (width 0.254) (layer "F.Cu") (net 14) (tstamp ae07aabc-f388-4baf-9b4a-d079f3ff38a2))
+  (segment (start 36.404 50.038) (end 37.719 50.038) (width 0.254) (layer "F.Cu") (net 14) (tstamp d48cb7c3-a93f-413e-b649-468db69b5710))
+  (via (at 38.354 49.403) (size 0.6858) (drill 0.3302) (layers "F.Cu" "B.Cu") (net 14) (tstamp 13dac8eb-146e-4e11-9e0d-936621b9b5eb))
+  (segment (start 39.243 48.514) (end 40.446 48.514) (width 0.254) (layer "B.Cu") (net 14) (tstamp 9efea54c-6552-48d1-ad1e-d118f0d36a6f))
+  (segment (start 38.354 49.403) (end 39.243 48.514) (width 0.254) (layer "B.Cu") (net 14) (tstamp a0c46f22-ba50-421e-b7a3-c6b1ae8e37a8))
+  (segment (start 37.719 47.498) (end 38.354 46.863) (width 0.254) (layer "F.Cu") (net 15) (tstamp 4548c354-c53c-4839-99fd-fdbdc95a2e94))
+  (segment (start 36.404 47.498) (end 37.719 47.498) (width 0.254) (layer "F.Cu") (net 15) (tstamp ddb40f0f-682e-4693-902c-e2770b5b6bd2))
+  (via (at 38.354 46.863) (size 0.6858) (drill 0.3302) (layers "F.Cu" "B.Cu") (net 15) (tstamp f73ff09a-5938-442b-8d3b-2177bfcca7fb))
+  (segment (start 39.243 45.974) (end 40.446 45.974) (width 0.254) (layer "B.Cu") (net 15) (tstamp 165a8d59-db7c-455b-a822-c194b8892552))
+  (segment (start 38.354 46.863) (end 39.243 45.974) (width 0.254) (layer "B.Cu") (net 15) (tstamp f0e7f4f2-d17c-4f4d-89a6-d4b4aa2539d6))
+  (segment (start 36.404 48.768) (end 37.719 48.768) (width 0.254) (layer "F.Cu") (net 16) (tstamp 8361b332-84eb-42bf-bffc-78986790c93a))
+  (segment (start 37.719 48.768) (end 38.354 48.133) (width 0.254) (layer "F.Cu") (net 16) (tstamp abc6ec6d-0135-4b01-8924-d4e17e5636e2))
+  (via (at 38.354 48.133) (size 0.6858) (drill 0.3302) (layers "F.Cu" "B.Cu") (net 16) (tstamp 39359626-337e-4b41-b424-df5574ba1763))
+  (segment (start 38.354 48.133) (end 39.243 47.244) (width 0.254) (layer "B.Cu") (net 16) (tstamp 4dcf5e69-3d8c-4956-a93f-8c013d06fa46))
+  (segment (start 39.243 47.244) (end 40.446 47.244) (width 0.254) (layer "B.Cu") (net 16) (tstamp a6918b51-d418-4595-8d8a-fdf5f123b58e))
+  (segment (start 32.532 47.518) (end 32.385 47.371) (width 0.254) (layer "F.Cu") (net 17) (tstamp bab293be-84e7-44d3-8bb3-d23ed8a48dea))
+  (segment (start 33.833 47.518) (end 32.532 47.518) (width 0.254) (layer "F.Cu") (net 17) (tstamp eae73756-f3a0-4116-b3bb-77202bc0f2c1))
+  (via (at 32.385 47.371) (size 0.6858) (drill 0.3302) (layers "F.Cu" "B.Cu") (net 17) (tstamp 55af291b-bf11-4f0a-b1ae-ccff728b3536))
+  (segment (start 32.347 47.409) (end 32.385 47.371) (width 0.254) (layer "B.Cu") (net 17) (tstamp 8a39c3ef-cbb2-438b-8fd2-d01d12a4eac3))
+  (segment (start 30.988 47.409) (end 32.347 47.409) (width 0.254) (layer "B.Cu") (net 17) (tstamp dccfd5a0-cc29-408a-828c-ae13728c8284))
+  (segment (start 32.611 50.518) (end 33.833 50.518) (width 0.254) (layer "F.Cu") (net 18) (tstamp 859e81f7-b1fb-45ab-ab27-e556921da9d1))
+  (segment (start 32.385 50.292) (end 32.611 50.518) (width 0.254) (layer "F.Cu") (net 18) (tstamp b9890ce2-de52-430e-938c-895f6f5da64e))
+  (via (at 32.385 50.292) (size 0.6858) (drill 0.3302) (layers "F.Cu" "B.Cu") (net 18) (tstamp c9eca091-1eea-443e-97ed-24518ab35e5f))
+  (segment (start 32.296 50.381) (end 32.385 50.292) (width 0.254) (layer "B.Cu") (net 18) (tstamp 12838ac1-bc65-4c88-9043-ac30158b837e))
+  (segment (start 30.988 50.381) (end 32.296 50.381) (width 0.254) (layer "B.Cu") (net 18) (tstamp bc3b7428-fb05-40df-a03c-3bd36c4098d5))
+
+  (zone (net 11) (net_name "GND") (layer "F.Cu") (tstamp ff0cc134-7c76-46f5-8168-386778db5317) (hatch edge 0.508)
+    (connect_pads (clearance 0.2032))
+    (min_thickness 0.2032) (filled_areas_thickness no)
+    (fill yes (thermal_gap 0.2032) (thermal_bridge_width 0.254))
+    (polygon
+      (pts
+        (xy 42.1386 54.229)
+        (xy 26.924 54.229)
+        (xy 26.924 43.307)
+        (xy 42.1386 43.307)
+      )
+    )
+    (filled_polygon
+      (layer "F.Cu")
+      (pts
+        (xy 35.272451 43.529913)
+        (xy 35.308996 43.580213)
+        (xy 35.308996 43.642387)
+        (xy 35.272451 43.692687)
+        (xy 35.258991 43.700935)
+        (xy 35.168875 43.746851)
+        (xy 35.072851 43.842875)
+        (xy 35.069256 43.849931)
+        (xy 35.069186 43.850068)
+        (xy 35.069078 43.850176)
+        (xy 35.064604 43.856334)
+        (xy 35.063629 43.855625)
+        (xy 35.025223 43.894032)
+        (xy 34.96642 43.904136)
+        (xy 34.925 43.898683)
+        (xy 34.91846 43.899544)
+        (xy 34.788847 43.916608)
+        (xy 34.788845 43.916608)
+        (xy 34.782309 43.917469)
+        (xy 34.649342 43.972545)
+        (xy 34.53516 44.06016)
+        (xy 34.447545 44.174342)
+        (xy 34.392469 44.307309)
+        (xy 34.391608 44.313845)
+        (xy 34.391608 44.313847)
+        (xy 34.374544 44.44346)
+        (xy 34.373683 44.45)
+        (xy 34.374544 44.45654)
+        (xy 34.391538 44.585616)
+        (xy 34.392469 44.592691)
+        (xy 34.447545 44.725658)
+        (xy 34.451563 44.730894)
+        (xy 34.531144 44.834607)
+        (xy 34.531146 44.834609)
+        (xy 34.53516 44.83984)
+        (xy 34.539758 44.843368)
+        (xy 34.567829 44.898466)
+        (xy 34.558101 44.959875)
+        (xy 34.514135 45.003837)
+        (xy 34.468467 45.0148)
+        (xy 34.092257 45.0148)
+        (xy 34.033126 44.995587)
+        (xy 33.996581 44.945287)
+        (xy 33.996581 44.883113)
+        (xy 34.009651 44.856784)
+        (xy 34.01651 44.846915)
+        (xy 34.090479 44.707212)
+        (xy 34.094793 44.695974)
+        (xy 34.121297 44.590454)
+        (xy 34.120429 44.577714)
+        (xy 34.110996 44.575)
+        (xy 33.024933 44.575)
+        (xy 33.012043 44.579188)
+        (xy 33.009 44.583377)
+        (xy 33.009 45.0906)
+        (xy 32.989787 45.149731)
+        (xy 32.939487 45.186276)
+        (xy 32.935099 45.186971)
+        (xy 32.893339 45.20054)
+        (xy 32.9048 45.235814)
+        (xy 32.9048 45.381853)
+        (xy 32.885587 45.440984)
+        (xy 32.835287 45.477529)
+        (xy 32.773113 45.477529)
+        (xy 32.740075 45.459367)
+        (xy 32.738336 45.457929)
+        (xy 32.733692 45.452878)
+        (xy 32.606412 45.373961)
+        (xy 32.599829 45.372049)
+        (xy 32.599828 45.372048)
+        (xy 32.518451 45.348406)
+        (xy 32.467027 45.313458)
+        (xy 32.445967 45.25496)
+        (xy 32.463313 45.195254)
+        (xy 32.51244 45.157147)
+        (xy 32.546517 45.1512)
+        (xy 32.739068 45.1512)
+        (xy 32.766461 45.142299)
+        (xy 32.755 45.107025)
+        (xy 32.755 44.590933)
+        (xy 32.750812 44.578043)
+        (xy 32.746623 44.575)
+        (xy 31.655206 44.575)
+        (xy 31.642896 44.579)
+        (xy 31.642521 44.58853)
+        (xy 31.666644 44.689011)
+        (xy 31.670846 44.70031)
+        (xy 31.743345 44.840774)
+        (xy 31.750108 44.850726)
+        (xy 31.854024 44.969848)
+        (xy 31.862975 44.977907)
+        (xy 31.992299 45.068797)
+        (xy 32.002914 45.074489)
+        (xy 32.150181 45.131905)
+        (xy 32.161855 45.134902)
+        (xy 32.243883 45.145702)
+        (xy 32.3 45.172469)
+        (xy 32.329667 45.227109)
+        (xy 32.321551 45.288751)
+        (xy 32.278753 45.33385)
+        (xy 32.244405 45.345109)
+        (xy 32.233626 45.346586)
+        (xy 32.096184 45.406062)
+        (xy 31.9798 45.500309)
+        (xy 31.893047 45.622382)
+        (xy 31.890726 45.62883)
+        (xy 31.890724 45.628833)
+        (xy 31.874401 45.674172)
+        (xy 31.842318 45.763287)
+        (xy 31.83135 45.912644)
+        (xy 31.832705 45.919364)
+        (xy 31.832705 45.919365)
+        (xy 31.849478 46.002547)
+        (xy 31.860951 46.059449)
+        (xy 31.864065 46.06556)
+        (xy 31.864065 46.065561)
+        (xy 31.897932 46.132029)
+        (xy 31.907658 46.193438)
+        (xy 31.879432 46.248835)
+        (xy 31.824034 46.277062)
+        (xy 31.808297 46.2783)
+        (xy 31.514833 46.2783)
+        (xy 31.506065 46.277917)
+        (xy 31.475501 46.275243)
+        (xy 31.466733 46.274476)
+        (xy 31.458231 46.276754)
+        (xy 31.428608 46.284691)
+        (xy 31.420042 46.286591)
+        (xy 31.389813 46.291921)
+        (xy 31.389811 46.291922)
+        (xy 31.381149 46.293449)
+        (xy 31.373531 46.297847)
+        (xy 31.367957 46.299876)
+        (xy 31.362582 46.302383)
+        (xy 31.354084 46.30466)
+        (xy 31.346874 46.309709)
+        (xy 31.346873 46.309709)
+        (xy 31.321742 46.327305)
+        (xy 31.314343 46.332019)
+        (xy 31.287775 46.347359)
+        (xy 31.280151 46.351761)
+        (xy 31.274494 46.358503)
+        (xy 31.254768 46.382011)
+        (xy 31.248839 46.388481)
+        (xy 30.386481 47.250839)
+        (xy 30.380011 47.256768)
+        (xy 30.349761 47.282151)
+        (xy 30.34536 47.289774)
+        (xy 30.345359 47.289775)
+        (xy 30.330019 47.316343)
+        (xy 30.325305 47.323742)
+        (xy 30.311761 47.343086)
+        (xy 30.30266 47.356084)
+        (xy 30.300383 47.364582)
+        (xy 30.297876 47.369957)
+        (xy 30.295847 47.375531)
+        (xy 30.291449 47.383149)
+        (xy 30.289922 47.391811)
+        (xy 30.289921 47.391813)
+        (xy 30.284591 47.422042)
+        (xy 30.282691 47.430608)
+        (xy 30.272476 47.468733)
+        (xy 30.273243 47.477501)
+        (xy 30.275917 47.508065)
+        (xy 30.2763 47.516833)
+        (xy 30.2763 49.247828)
+        (xy 30.257087 49.306959)
+        (xy 30.206787 49.343504)
+        (xy 30.1757 49.348428)
+        (xy 30.092809 49.348428)
+        (xy 30.033678 49.329215)
+        (xy 30.013 49.309072)
+        (xy 29.98084 49.26716)
+        (xy 29.973407 49.261456)
+        (xy 29.871889 49.183558)
+        (xy 29.871888 49.183558)
+        (xy 29.866659 49.179545)
+        (xy 29.733691 49.124469)
+        (xy 29.727155 49.123608)
+        (xy 29.727153 49.123608)
+        (xy 29.59754 49.106544)
+        (xy 29.591 49.105683)
+        (xy 29.58446 49.106544)
+        (xy 29.454847 49.123608)
+        (xy 29.454845 49.123608)
+        (xy 29.448309 49.124469)
+        (xy 29.315342 49.179545)
+        (xy 29.26072 49.221458)
+        (xy 29.210502 49.259992)
+        (xy 29.20116 49.26716)
+        (xy 29.113545 49.381342)
+        (xy 29.058469 49.514309)
+        (xy 29.057608 49.520845)
+        (xy 29.057608 49.520847)
+        (xy 29.055489 49.536941)
+        (xy 29.039683 49.657)
+        (xy 29.040544 49.66354)
+        (xy 29.056897 49.787748)
+        (xy 29.058469 49.799691)
+        (xy 29.113545 49.932658)
+        (xy 29.20116 50.04684)
+        (xy 29.206391 50.050854)
+        (xy 29.206392 50.050855)
+        (xy 29.29307 50.117366)
+        (xy 29.315341 50.134455)
+        (xy 29.448309 50.189531)
+        (xy 29.454845 50.190392)
+        (xy 29.454847 50.190392)
+        (xy 29.58446 50.207456)
+        (xy 29.591 50.208317)
+        (xy 29.59754 50.207456)
+        (xy 29.727153 50.190392)
+        (xy 29.727155 50.190392)
+        (xy 29.733691 50.189531)
+        (xy 29.866659 50.134455)
+        (xy 29.897263 50.110972)
+        (xy 29.975609 50.050854)
+        (xy 29.98084 50.04684)
+        (xy 29.984853 50.04161)
+        (xy 29.98717 50.039293)
+        (xy 30.042568 50.011067)
+        (xy 30.058305 50.009828)
+        (xy 30.1757 50.009828)
+        (xy 30.234831 50.029041)
+        (xy 30.271376 50.079341)
+        (xy 30.2763 50.110428)
+        (xy 30.2763 50.146167)
+        (xy 30.275917 50.154935)
+        (xy 30.273643 50.180933)
+        (xy 30.272476 50.194267)
+        (xy 30.274754 50.202769)
+        (xy 30.282691 50.232392)
+        (xy 30.284591 50.240958)
+        (xy 30.288236 50.261627)
+        (xy 30.291449 50.279851)
+        (xy 30.295847 50.287469)
+        (xy 30.297876 50.293043)
+        (xy 30.300383 50.298418)
+        (xy 30.30266 50.306916)
+        (xy 30.307709 50.314126)
+        (xy 30.307709 50.314127)
+        (xy 30.325305 50.339258)
+        (xy 30.330019 50.346657)
+        (xy 30.334 50.353551)
+        (xy 30.349761 50.380849)
+        (xy 30.374737 50.401807)
+        (xy 30.380011 50.406232)
+        (xy 30.386481 50.412161)
+        (xy 31.156859 51.182539)
+        (xy 31.162788 51.189009)
+        (xy 31.188171 51.219259)
+        (xy 31.195791 51.223658)
+        (xy 31.195794 51.223661)
+        (xy 31.222361 51.238999)
+        (xy 31.229756 51.24371)
+        (xy 31.262103 51.26636)
+        (xy 31.270601 51.268637)
+        (xy 31.275977 51.271144)
+        (xy 31.28155 51.273172)
+        (xy 31.289169 51.277571)
+        (xy 31.297833 51.279099)
+        (xy 31.297834 51.279099)
+        (xy 31.328057 51.284428)
+        (xy 31.336623 51.286327)
+        (xy 31.374753 51.296543)
+        (xy 31.414075 51.293103)
+        (xy 31.422841 51.29272)
+        (xy 31.789388 51.29272)
+        (xy 31.848519 51.311933)
+        (xy 31.885064 51.362233)
+        (xy 31.884041 51.427397)
+        (xy 31.842318 51.543287)
+        (xy 31.83135 51.692644)
+        (xy 31.832705 51.699364)
+        (xy 31.832705 51.699365)
+        (xy 31.854517 51.807538)
+        (xy 31.860951 51.839449)
+        (xy 31.864065 51.84556)
+        (xy 31.864065 51.845561)
+        (xy 31.889726 51.895924)
+        (xy 31.92894 51.972885)
+        (xy 32.030308 52.083122)
+        (xy 32.157588 52.162039)
+        (xy 32.164171 52.163951)
+        (xy 32.164172 52.163952)
+        (xy 32.26489 52.193213)
+        (xy 32.316314 52.22816)
+        (xy 32.337374 52.286659)
+        (xy 32.320028 52.346365)
+        (xy 32.270901 52.384472)
+        (xy 32.248909 52.38969)
+        (xy 32.169053 52.399353)
+        (xy 32.157361 52.402225)
+        (xy 32.009485 52.458102)
+        (xy 31.998823 52.463676)
+        (xy 31.868546 52.553215)
+        (xy 31.859517 52.561175)
+        (xy 31.754362 52.679197)
+        (xy 31.747489 52.689086)
+        (xy 31.673521 52.828788)
+        (xy 31.669207 52.840026)
+        (xy 31.642703 52.945546)
+        (xy 31.643571 52.958286)
+        (xy 31.653004 52.961)
+        (xy 32.739067 52.961)
+        (xy 32.751957 52.956812)
+        (xy 32.755 52.952623)
+        (xy 32.755 52.42685)
+        (xy 32.765626 52.394146)
+        (xy 32.747374 52.384846)
+        (xy 32.747084 52.3848)
+        (xy 32.561516 52.3848)
+        (xy 32.502385 52.365587)
+        (xy 32.46584 52.315287)
+        (xy 32.46584 52.253113)
+        (xy 32.502385 52.202813)
+        (xy 32.529995 52.189466)
+        (xy 32.530374 52.189414)
+        (xy 32.667816 52.129938)
+        (xy 32.673142 52.125625)
+        (xy 32.673147 52.125622)
+        (xy 32.74089 52.070764)
+        (xy 32.798934 52.048482)
+        (xy 32.85899 52.064573)
+        (xy 32.898118 52.112892)
+        (xy 32.9048 52.148944)
+        (xy 32.9048 52.302284)
+        (xy 32.894429 52.334204)
+        (xy 32.897716 52.33549)
+        (xy 32.936444 52.353343)
+        (xy 32.936216 52.353838)
+        (xy 32.967531 52.364013)
+        (xy 33.004076 52.414313)
+        (xy 33.009 52.4454)
+        (xy 33.009 52.945067)
+        (xy 33.013188 52.957957)
+        (xy 33.017377 52.961)
+        (xy 34.108794 52.961)
+        (xy 34.121104 52.957)
+        (xy 34.121479 52.94747)
+        (xy 34.097356 52.846989)
+        (xy 34.093154 52.83569)
+        (xy 34.020655 52.695226)
+        (xy 34.010479 52.680252)
+        (xy 34.012381 52.678959)
+        (xy 33.991817 52.630729)
+        (xy 34.005706 52.570126)
+        (xy 34.052563 52.529261)
+        (xy 34.09202 52.5212)
+        (xy 34.573068 52.5212)
+        (xy 34.582864 52.520235)
+        (xy 34.627568 52.511343)
+        (xy 34.645524 52.503905)
+        (xy 34.69626 52.470004)
+        (xy 34.710004 52.45626)
+        (xy 34.743905 52.405524)
+        (xy 34.751343 52.387568)
+        (xy 34.760235 52.342864)
+        (xy 34.7612 52.333068)
+        (xy 34.7612 52.160933)
+        (xy 34.757012 52.148043)
+        (xy 34.752823 52.145)
+        (xy 33.8066 52.145)
+        (xy 33.747469 52.125787)
+        (xy 33.710924 52.075487)
+        (xy 33.706 52.0444)
+        (xy 33.706 51.9916)
+        (xy 33.725213 51.932469)
+        (xy 33.775513 51.895924)
+        (xy 33.8066 51.891)
+        (xy 34.745267 51.891)
+        (xy 34.758157 51.886812)
+        (xy 34.7612 51.882623)
+        (xy 34.7612 51.702932)
+        (xy 34.760235 51.693136)
+        (xy 34.74941 51.638715)
+        (xy 34.753449 51.637912)
+        (xy 34.750257 51.597555)
+        (xy 34.749881 51.59748)
+        (xy 34.750146 51.59615)
+        (xy 34.750146 51.596148)
+        (xy 34.7617 51.538064)
+        (xy 34.7617 50.897936)
+        (xy 34.749881 50.83852)
+        (xy 34.744839 50.830974)
+        (xy 34.740003 50.769515)
+        (xy 34.744588 50.755402)
+        (xy 34.749881 50.74748)
+        (xy 34.7617 50.688064)
+        (xy 34.7617 50.347936)
+        (xy 34.749881 50.28852)
+        (xy 34.753762 50.287748)
+        (xy 34.750599 50.247623)
+        (xy 34.749881 50.24748)
+        (xy 34.750387 50.244935)
+        (xy 34.7617 50.188064)
+        (xy 34.7617 49.847936)
+        (xy 34.749881 49.78852)
+        (xy 34.753762 49.787748)
+        (xy 34.750599 49.747623)
+        (xy 34.749881 49.74748)
+        (xy 34.750387 49.744935)
+        (xy 34.7617 49.688064)
+        (xy 34.7617 49.452722)
+        (xy 34.780913 49.393591)
+        (xy 34.831213 49.357046)
+        (xy 34.853921 49.354441)
+        (xy 34.853753 49.352524)
+        (xy 34.862521 49.351757)
+        (xy 34.871289 49.352524)
+        (xy 34.886576 49.348428)
+        (xy 34.909414 49.342309)
+        (xy 34.91798 49.340409)
+        (xy 34.948209 49.335079)
+        (xy 34.948211 49.335078)
+        (xy 34.956873 49.333551)
+        (xy 34.964491 49.329153)
+        (xy 34.970065 49.327124)
+        (xy 34.97544 49.324617)
+        (xy 34.983938 49.32234)
+        (xy 34.991149 49.317291)
+        (xy 35.01628 49.299695)
+        (xy 35.023679 49.294981)
+        (xy 35.05787 49.27524)
+        (xy 35.059373 49.277844)
+        (xy 35.103548 49.259992)
+        (xy 35.159242 49.275698)
+        (xy 35.160158 49.273823)
+        (xy 35.23948 49.312596)
+        (xy 35.284167 49.355824)
+        (xy 35.294911 49.417063)
+        (xy 35.267607 49.472921)
+        (xy 35.239639 49.493279)
+        (xy 35.183491 49.520847)
+        (xy 35.1596 49.532577)
+        (xy 35.153726 49.538461)
+        (xy 35.153725 49.538462)
+        (xy 35.074049 49.618276)
+        (xy 35.074047 49.618279)
+        (xy 35.068177 49.624159)
+        (xy 35.064528 49.631624)
+        (xy 35.064526 49.631627)
+        (xy 35.034569 49.692914)
+        (xy 35.011349 49.740417)
+        (xy 35.010222 49.748144)
+        (xy 35.003607 49.79349)
+        (xy 35.0003 49.816156)
+        (xy 35.0003 50.259844)
+        (xy 35.005129 50.292646)
+        (xy 35.008291 50.314127)
+        (xy 35.011546 50.336242)
+        (xy 35.014991 50.343258)
+        (xy 35.014991 50.343259)
+        (xy 35.048821 50.412161)
+        (xy 35.068577 50.4524)
+        (xy 35.074461 50.458274)
+        (xy 35.074462 50.458275)
+        (xy 35.154276 50.537951)
+        (xy 35.154279 50.537953)
+        (xy 35.160159 50.543823)
+        (xy 35.167626 50.547473)
+        (xy 35.167629 50.547475)
+        (xy 35.23948 50.582596)
+        (xy 35.284167 50.625824)
+        (xy 35.294911 50.687063)
+        (xy 35.267607 50.742921)
+        (xy 35.239639 50.763279)
+        (xy 35.181018 50.792061)
+        (xy 35.1596 50.802577)
+        (xy 35.153726 50.808461)
+        (xy 35.153725 50.808462)
+        (xy 35.074049 50.888276)
+        (xy 35.074047 50.888279)
+        (xy 35.068177 50.894159)
+        (xy 35.064528 50.901624)
+        (xy 35.064526 50.901627)
+        (xy 35.063913 50.902882)
+        (xy 35.011349 51.010417)
+        (xy 35.010222 51.018144)
+        (xy 35.000831 51.082517)
+        (xy 35.0003 51.086156)
+        (xy 35.0003 51.529844)
+        (xy 35.00151 51.538064)
+        (xy 35.010312 51.597856)
+        (xy 35.011546 51.606242)
+        (xy 35.014991 51.613258)
+        (xy 35.014991 51.613259)
+        (xy 35.059019 51.702932)
+        (xy 35.068577 51.7224)
+        (xy 35.074461 51.728274)
+        (xy 35.074462 51.728275)
+        (xy 35.154276 51.807951)
+        (xy 35.154279 51.807953)
+        (xy 35.160159 51.813823)
+        (xy 35.167624 51.817472)
+        (xy 35.167627 51.817474)
+        (xy 35.198828 51.832725)
+        (xy 35.276417 51.870651)
+        (xy 35.304991 51.874819)
+        (xy 35.348547 51.881174)
+        (xy 35.348554 51.881174)
+        (xy 35.352156 51.8817)
+        (xy 37.455844 51.8817)
+        (xy 37.497139 51.875621)
+        (xy 37.524506 51.871593)
+        (xy 37.524507 51.871593)
+        (xy 37.532242 51.870454)
+        (xy 37.582943 51.845561)
+        (xy 37.640936 51.817088)
+        (xy 37.640938 51.817087)
+        (xy 37.6484 51.813423)
+        (xy 37.654275 51.807538)
+        (xy 37.733951 51.727724)
+        (xy 37.733953 51.727721)
+        (xy 37.739823 51.721841)
+        (xy 37.761057 51.678401)
+        (xy 37.804286 51.633715)
+        (xy 37.817029 51.628048)
+        (xy 37.825186 51.625079)
+        (xy 37.833851 51.623551)
+        (xy 37.841473 51.619151)
+        (xy 37.847046 51.617122)
+        (xy 37.852416 51.614618)
+        (xy 37.860916 51.61234)
+        (xy 37.870566 51.605583)
+        (xy 37.893258 51.589695)
+        (xy 37.900657 51.584981)
+        (xy 37.927225 51.569641)
+        (xy 37.927226 51.56964)
+        (xy 37.934849 51.565239)
+        (xy 37.941966 51.556757)
+        (xy 37.960233 51.534989)
+        (xy 37.966161 51.52852)
+        (xy 38.245014 51.249667)
+        (xy 38.300412 51.221441)
+        (xy 38.329276 51.221062)
+        (xy 38.354 51.224317)
+        (xy 38.36054 51.223456)
+        (xy 38.490153 51.206392)
+        (xy 38.490155 51.206392)
+        (xy 38.496691 51.205531)
+        (xy 38.629659 51.150455)
+        (xy 38.708704 51.089801)
+        (xy 38.738458 51.06697)
+        (xy 38.797066 51.046215)
+        (xy 38.85668 51.063874)
+        (xy 38.89453 51.1132)
+        (xy 38.9003 51.146781)
+        (xy 38.9003 51.529844)
+        (xy 38.90151 51.538064)
+        (xy 38.910312 51.597856)
+        (xy 38.911546 51.606242)
+        (xy 38.914991 51.613258)
+        (xy 38.914991 51.613259)
+        (xy 38.959019 51.702932)
+        (xy 38.968577 51.7224)
+        (xy 38.974461 51.728274)
+        (xy 38.974462 51.728275)
+        (xy 39.054276 51.807951)
+        (xy 39.054279 51.807953)
+        (xy 39.060159 51.813823)
+        (xy 39.067624 51.817472)
+        (xy 39.067627 51.817474)
+        (xy 39.098828 51.832725)
+        (xy 39.176417 51.870651)
+        (xy 39.204991 51.874819)
+        (xy 39.248547 51.881174)
+        (xy 39.248554 51.881174)
+        (xy 39.252156 51.8817)
+        (xy 41.355844 51.8817)
+        (xy 41.397139 51.875621)
+        (xy 41.424506 51.871593)
+        (xy 41.424507 51.871593)
+        (xy 41.432242 51.870454)
+        (xy 41.482943 51.845561)
+        (xy 41.540936 51.817088)
+        (xy 41.540938 51.817087)
+        (xy 41.5484 51.813423)
+        (xy 41.554275 51.807538)
+        (xy 41.633951 51.727724)
+        (xy 41.633953 51.727721)
+        (xy 41.639823 51.721841)
+        (xy 41.643473 51.714374)
+        (xy 41.643474 51.714373)
+        (xy 41.693222 51.612598)
+        (xy 41.696651 51.605583)
+        (xy 41.701894 51.569641)
+        (xy 41.707174 51.533453)
+        (xy 41.707174 51.533446)
+        (xy 41.7077 51.529844)
+        (xy 41.7077 51.086156)
+        (xy 41.701621 51.044861)
+        (xy 41.697593 51.017494)
+        (xy 41.697593 51.017493)
+        (xy 41.696454 51.009758)
+        (xy 41.693009 51.002741)
+        (xy 41.643088 50.901064)
+        (xy 41.643087 50.901062)
+        (xy 41.639423 50.8936)
+        (xy 41.602539 50.85678)
+        (xy 41.553724 50.808049)
+        (xy 41.553721 50.808047)
+        (xy 41.547841 50.802177)
+        (xy 41.540376 50.798528)
+        (xy 41.540373 50.798526)
+        (xy 41.467949 50.763125)
+        (xy 41.423262 50.719897)
+        (xy 41.412519 50.658658)
+        (xy 41.439823 50.602799)
+        (xy 41.467792 50.582442)
+        (xy 41.540639 50.546676)
+        (xy 41.55398 50.537125)
+        (xy 41.633538 50.457429)
+        (xy 41.643061 50.444078)
+        (xy 41.692736 50.342453)
+        (xy 41.697292 50.327711)
+        (xy 41.706674 50.263405)
+        (xy 41.7072 50.256151)
+        (xy 41.7072 50.180933)
+        (xy 41.703012 50.168043)
+        (xy 41.698823 50.165)
+        (xy 38.916733 50.165)
+        (xy 38.903843 50.169188)
+        (xy 38.9008 50.173377)
+        (xy 38.9008 50.199603)
+        (xy 38.881587 50.258734)
+        (xy 38.831287 50.295279)
+        (xy 38.769113 50.295279)
+        (xy 38.738958 50.279414)
+        (xy 38.708642 50.256151)
+        (xy 38.683217 50.236642)
+        (xy 38.634889 50.199558)
+        (xy 38.634888 50.199558)
+        (xy 38.629659 50.195545)
+        (xy 38.496691 50.140469)
+        (xy 38.490155 50.139608)
+        (xy 38.490153 50.139608)
+        (xy 38.475955 50.137739)
+        (xy 38.419837 50.110972)
+        (xy 38.390171 50.056333)
+        (xy 38.398286 49.99469)
+        (xy 38.441084 49.949591)
+        (xy 38.475955 49.938261)
+        (xy 38.490153 49.936392)
+        (xy 38.490155 49.936392)
+        (xy 38.496691 49.935531)
+        (xy 38.629659 49.880455)
+        (xy 38.634948 49.876397)
+        (xy 38.718134 49.812565)
+        (xy 38.738958 49.796586)
+        (xy 38.797566 49.775831)
+        (xy 38.85718 49.79349)
+        (xy 38.89503 49.842816)
+        (xy 38.9008 49.876397)
+        (xy 38.9008 49.895067)
+        (xy 38.904988 49.907957)
+        (xy 38.909177 49.911)
+        (xy 41.691267 49.911)
+        (xy 41.704157 49.906812)
+        (xy 41.7072 49.902623)
+        (xy 41.7072 49.819879)
+        (xy 41.706664 49.812565)
+        (xy 41.697107 49.74764)
+        (xy 41.692523 49.732887)
+        (xy 41.642675 49.631359)
+        (xy 41.633125 49.61802)
+        (xy 41.553429 49.538462)
+        (xy 41.540077 49.528939)
+        (xy 41.467381 49.493404)
+        (xy 41.422694 49.450175)
+        (xy 41.411951 49.388936)
+        (xy 41.439256 49.333078)
+        (xy 41.467224 49.312721)
+        (xy 41.540639 49.276676)
+        (xy 41.55398 49.267125)
+        (xy 41.633538 49.187429)
+        (xy 41.643061 49.174078)
+        (xy 41.692736 49.072453)
+        (xy 41.697292 49.057711)
+        (xy 41.706674 48.993405)
+        (xy 41.7072 48.986151)
+        (xy 41.7072 48.910933)
+        (xy 41.703012 48.898043)
+        (xy 41.698823 48.895)
+        (xy 38.916733 48.895)
+        (xy 38.903843 48.899188)
+        (xy 38.9008 48.903377)
+        (xy 38.9008 48.929603)
+        (xy 38.881587 48.988734)
+        (xy 38.831287 49.025279)
+        (xy 38.769113 49.025279)
+        (xy 38.738958 49.009414)
+        (xy 38.708642 48.986151)
+        (xy 38.651369 48.942204)
+        (xy 38.634889 48.929558)
+        (xy 38.634888 48.929558)
+        (xy 38.629659 48.925545)
+        (xy 38.496691 48.870469)
+        (xy 38.490155 48.869608)
+        (xy 38.490153 48.869608)
+        (xy 38.475955 48.867739)
+        (xy 38.419837 48.840972)
+        (xy 38.390171 48.786333)
+        (xy 38.398286 48.72469)
+        (xy 38.441084 48.679591)
+        (xy 38.475955 48.668261)
+        (xy 38.490153 48.666392)
+        (xy 38.490155 48.666392)
+        (xy 38.496691 48.665531)
+        (xy 38.629659 48.610455)
+        (xy 38.634948 48.606397)
+        (xy 38.738958 48.526586)
+        (xy 38.797566 48.505831)
+        (xy 38.85718 48.52349)
+        (xy 38.89503 48.572816)
+        (xy 38.9008 48.606397)
+        (xy 38.9008 48.625067)
+        (xy 38.904988 48.637957)
+        (xy 38.909177 48.641)
+        (xy 41.691267 48.641)
+        (xy 41.704157 48.636812)
+        (xy 41.7072 48.632623)
+        (xy 41.7072 48.549879)
+        (xy 41.706664 48.542565)
+        (xy 41.697107 48.47764)
+        (xy 41.692523 48.462887)
+        (xy 41.642675 48.361359)
+        (xy 41.633125 48.34802)
+        (xy 41.553429 48.268462)
+        (xy 41.540076 48.258938)
+        (xy 41.467951 48.223683)
+        (xy 41.423264 48.180455)
+        (xy 41.41252 48.119216)
+        (xy 41.439824 48.063358)
+        (xy 41.467792 48.043)
+        (xy 41.540935 48.007088)
+        (xy 41.540934 48.007088)
+        (xy 41.5484 48.003423)
+        (xy 41.554275 47.997538)
+        (xy 41.633951 47.917724)
+        (xy 41.633953 47.917721)
+        (xy 41.639823 47.911841)
+        (xy 41.643472 47.904376)
+        (xy 41.643474 47.904373)
+        (xy 41.693222 47.802598)
+        (xy 41.696651 47.795583)
+        (xy 41.702483 47.755606)
+        (xy 41.707174 47.723453)
+        (xy 41.707174 47.723446)
+        (xy 41.7077 47.719844)
+        (xy 41.7077 47.276156)
+        (xy 41.69976 47.222216)
+        (xy 41.697593 47.207494)
+        (xy 41.697593 47.207493)
+        (xy 41.696454 47.199758)
+        (xy 41.690713 47.188064)
+        (xy 41.643088 47.091064)
+        (xy 41.643087 47.091062)
+        (xy 41.639423 47.0836)
+        (xy 41.602539 47.04678)
+        (xy 41.553724 46.998049)
+        (xy 41.553721 46.998047)
+        (xy 41.547841 46.992177)
+        (xy 41.540376 46.988528)
+        (xy 41.540373 46.988526)
+        (xy 41.467949 46.953125)
+        (xy 41.423262 46.909897)
+        (xy 41.412519 46.848658)
+        (xy 41.439823 46.792799)
+        (xy 41.467792 46.772442)
+        (xy 41.540639 46.736676)
+        (xy 41.55398 46.727125)
+        (xy 41.633538 46.647429)
+        (xy 41.643061 46.634078)
+        (xy 41.692736 46.532453)
+        (xy 41.697292 46.517711)
+        (xy 41.706674 46.453405)
+        (xy 41.7072 46.446151)
+        (xy 41.7072 46.370933)
+        (xy 41.703012 46.358043)
+        (xy 41.698823 46.355)
+        (xy 38.916733 46.355)
+        (xy 38.903843 46.359188)
+        (xy 38.9008 46.363377)
+        (xy 38.9008 46.389603)
+        (xy 38.881587 46.448734)
+        (xy 38.831287 46.485279)
+        (xy 38.769113 46.485279)
+        (xy 38.738958 46.469414)
+        (xy 38.708642 46.446151)
+        (xy 38.692836 46.434023)
+        (xy 38.634889 46.389558)
+        (xy 38.634888 46.389558)
+        (xy 38.629659 46.385545)
+        (xy 38.496691 46.330469)
+        (xy 38.490155 46.329608)
+        (xy 38.490153 46.329608)
+        (xy 38.475955 46.327739)
+        (xy 38.419837 46.300972)
+        (xy 38.390171 46.246333)
+        (xy 38.398286 46.18469)
+        (xy 38.441084 46.139591)
+        (xy 38.475955 46.128261)
+        (xy 38.490153 46.126392)
+        (xy 38.490155 46.126392)
+        (xy 38.496691 46.125531)
+        (xy 38.629659 46.070455)
+        (xy 38.634948 46.066397)
+        (xy 38.718134 46.002565)
+        (xy 38.738958 45.986586)
+        (xy 38.797566 45.965831)
+        (xy 38.85718 45.98349)
+        (xy 38.89503 46.032816)
+        (xy 38.9008 46.066397)
+        (xy 38.9008 46.085067)
+        (xy 38.904988 46.097957)
+        (xy 38.909177 46.101)
+        (xy 40.161067 46.101)
+        (xy 40.173957 46.096812)
+        (xy 40.177 46.092623)
+        (xy 40.177 46.085067)
+        (xy 40.431 46.085067)
+        (xy 40.435188 46.097957)
+        (xy 40.439377 46.101)
+        (xy 41.691267 46.101)
+        (xy 41.704157 46.096812)
+        (xy 41.7072 46.092623)
+        (xy 41.7072 46.009879)
+        (xy 41.706664 46.002565)
+        (xy 41.697107 45.93764)
+        (xy 41.692523 45.922887)
+        (xy 41.642675 45.821359)
+        (xy 41.633125 45.80802)
+        (xy 41.553429 45.728462)
+        (xy 41.540078 45.718939)
+        (xy 41.438453 45.669264)
+        (xy 41.423711 45.664708)
+        (xy 41.359405 45.655326)
+        (xy 41.352151 45.6548)
+        (xy 40.446933 45.6548)
+        (xy 40.434043 45.658988)
+        (xy 40.431 45.663177)
+        (xy 40.431 46.085067)
+        (xy 40.177 46.085067)
+        (xy 40.177 45.670733)
+        (xy 40.172812 45.657843)
+        (xy 40.168623 45.6548)
+        (xy 39.255879 45.6548)
+        (xy 39.248565 45.655336)
+        (xy 39.18364 45.664893)
+        (xy 39.168887 45.669477)
+        (xy 39.067359 45.719326)
+        (xy 39.058666 45.725549)
+        (xy 38.999402 45.74435)
+        (xy 38.940406 45.724725)
+        (xy 38.904212 45.674172)
+        (xy 38.900364 45.630621)
+        (xy 38.904456 45.59954)
+        (xy 38.905317 45.593)
+        (xy 38.903011 45.575487)
+        (xy 38.887392 45.456847)
+        (xy 38.887392 45.456845)
+        (xy 38.886531 45.450309)
+        (xy 38.831455 45.317342)
+        (xy 38.74384 45.20316)
+        (xy 38.683828 45.15711)
+        (xy 38.648613 45.105872)
+        (xy 38.65024 45.043719)
+        (xy 38.68809 44.994393)
+        (xy 38.74507 44.9767)
+        (xy 39.08274 44.9767)
+        (xy 39.086645 44.976081)
+        (xy 39.086651 44.976081)
+        (xy 39.175305 44.962039)
+        (xy 39.175306 44.962039)
+        (xy 39.183127 44.9608)
+        (xy 39.19018 44.957206)
+        (xy 39.190184 44.957205)
+        (xy 39.297069 44.902744)
+        (xy 39.304125 44.899149)
+        (xy 39.400149 44.803125)
+        (xy 39.414977 44.774022)
+        (xy 39.458205 44.689184)
+        (xy 39.458206 44.68918)
+        (xy 39.4618 44.682127)
+        (xy 39.463039 44.674305)
+        (xy 39.477081 44.585651)
+        (xy 39.477081 44.585645)
+        (xy 39.4777 44.58174)
+        (xy 39.4777 44.577752)
+        (xy 39.770801 44.577752)
+        (xy 39.771418 44.585601)
+        (xy 39.785442 44.67415)
+        (xy 39.790277 44.689029)
+        (xy 39.844665 44.795771)
+        (xy 39.853859 44.808426)
+        (xy 39.938574 44.893141)
+        (xy 39.951229 44.902335)
+        (xy 40.057974 44.956724)
+        (xy 40.07285 44.961558)
+        (xy 40.161384 44.97558)
+        (xy 40.169256 44.9762)
+        (xy 40.281067 44.9762)
+        (xy 40.293957 44.972012)
+        (xy 40.297 44.967823)
+        (xy 40.297 44.960266)
+        (xy 40.551 44.960266)
+        (xy 40.555188 44.973156)
+        (xy 40.559377 44.976199)
+        (xy 40.678752 44.976199)
+        (xy 40.686601 44.975582)
+        (xy 40.77515 44.961558)
+        (xy 40.790029 44.956723)
+        (xy 40.896771 44.902335)
+        (xy 40.909426 44.893141)
+        (xy 40.994141 44.808426)
+        (xy 41.003335 44.795771)
+        (xy 41.057724 44.689026)
+        (xy 41.062558 44.67415)
+        (xy 41.07658 44.585616)
+        (xy 41.0772 44.577744)
+        (xy 41.0772 44.465933)
+        (xy 41.073012 44.453043)
+        (xy 41.068823 44.45)
+        (xy 40.566933 44.45)
+        (xy 40.554043 44.454188)
+        (xy 40.551 44.458377)
+        (xy 40.551 44.960266)
+        (xy 40.297 44.960266)
+        (xy 40.297 44.465933)
+        (xy 40.292812 44.453043)
+        (xy 40.288623 44.45)
+        (xy 39.786734 44.45)
+        (xy 39.773844 44.454188)
+        (xy 39.770801 44.458377)
+        (xy 39.770801 44.577752)
+        (xy 39.4777 44.577752)
+        (xy 39.4777 44.06426)
+        (xy 39.476415 44.056143)
+        (xy 39.463039 43.971695)
+        (xy 39.463039 43.971694)
+        (xy 39.4618 43.963873)
+        (xy 39.458206 43.95682)
+        (xy 39.458205 43.956816)
+        (xy 39.403744 43.849931)
+        (xy 39.400149 43.842875)
+        (xy 39.304125 43.746851)
+        (xy 39.214009 43.700935)
+        (xy 39.170045 43.656972)
+        (xy 39.160318 43.595563)
+        (xy 39.188545 43.540165)
+        (xy 39.243942 43.511939)
+        (xy 39.25968 43.5107)
+        (xy 39.98942 43.5107)
+        (xy 40.048551 43.529913)
+        (xy 40.085096 43.580213)
+        (xy 40.085096 43.642387)
+        (xy 40.048551 43.692687)
+        (xy 40.035091 43.700935)
+        (xy 39.951229 43.743665)
+        (xy 39.938574 43.752859)
+        (xy 39.853859 43.837574)
+        (xy 39.844665 43.850229)
+        (xy 39.790276 43.956974)
+        (xy 39.785442 43.97185)
+        (xy 39.77142 44.060384)
+        (xy 39.7708 44.068256)
+        (xy 39.7708 44.180067)
+        (xy 39.774988 44.192957)
+        (xy 39.779177 44.196)
+        (xy 41.061266 44.196)
+        (xy 41.074156 44.191812)
+        (xy 41.077199 44.187623)
+        (xy 41.077199 44.068248)
+        (xy 41.076582 44.060399)
+        (xy 41.062558 43.97185)
+        (xy 41.057723 43.956971)
+        (xy 41.003335 43.850229)
+        (xy 40.994141 43.837574)
+        (xy 40.909426 43.752859)
+        (xy 40.896771 43.743665)
+        (xy 40.812909 43.700935)
+        (xy 40.768945 43.656971)
+        (xy 40.759219 43.595563)
+        (xy 40.787445 43.540165)
+        (xy 40.842843 43.511939)
+        (xy 40.85858 43.5107)
+        (xy 41.8343 43.5107)
+        (xy 41.893431 43.529913)
+        (xy 41.929976 43.580213)
+        (xy 41.9349 43.6113)
+        (xy 41.9349 53.9247)
+        (xy 41.915687 53.983831)
+        (xy 41.865387 54.020376)
+        (xy 41.8343 54.0253)
+        (xy 27.2283 54.0253)
+        (xy 27.169169 54.006087)
+        (xy 27.132624 53.955787)
+        (xy 27.1277 53.9247)
+        (xy 27.1277 53.22853)
+        (xy 27.462521 53.22853)
+        (xy 27.486644 53.329011)
+        (xy 27.490846 53.34031)
+        (xy 27.563345 53.480774)
+        (xy 27.570108 53.490726)
+        (xy 27.674024 53.609848)
+        (xy 27.682975 53.617907)
+        (xy 27.812299 53.708797)
+        (xy 27.822914 53.714489)
+        (xy 27.970181 53.771905)
+        (xy 27.981856 53.774902)
+        (xy 28.102385 53.790771)
+        (xy 28.108935 53.7912)
+        (xy 28.559067 53.7912)
+        (xy 28.571957 53.787012)
+        (xy 28.575 53.782823)
+        (xy 28.575 53.775267)
+        (xy 28.829 53.775267)
+        (xy 28.833188 53.788157)
+        (xy 28.837377 53.7912)
+        (xy 29.291659 53.7912)
+        (xy 29.297687 53.790836)
+        (xy 29.414947 53.776647)
+        (xy 29.426639 53.773775)
+        (xy 29.574515 53.717898)
+        (xy 29.585177 53.712324)
+        (xy 29.715454 53.622785)
+        (xy 29.724483 53.614825)
+        (xy 29.829638 53.496803)
+        (xy 29.836511 53.486914)
+        (xy 29.910479 53.347212)
+        (xy 29.914793 53.335974)
+        (xy 29.941297 53.230454)
+        (xy 29.941166 53.22853)
+        (xy 31.642521 53.22853)
+        (xy 31.666644 53.329011)
+        (xy 31.670846 53.34031)
+        (xy 31.743345 53.480774)
+        (xy 31.750108 53.490726)
+        (xy 31.854024 53.609848)
+        (xy 31.862975 53.617907)
+        (xy 31.992299 53.708797)
+        (xy 32.002914 53.714489)
+        (xy 32.150181 53.771905)
+        (xy 32.161856 53.774902)
+        (xy 32.282385 53.790771)
+        (xy 32.288935 53.7912)
+        (xy 32.739067 53.7912)
+        (xy 32.751957 53.787012)
+        (xy 32.755 53.782823)
+        (xy 32.755 53.775267)
+        (xy 33.009 53.775267)
+        (xy 33.013188 53.788157)
+        (xy 33.017377 53.7912)
+        (xy 33.471659 53.7912)
+        (xy 33.477687 53.790836)
+        (xy 33.594947 53.776647)
+        (xy 33.606639 53.773775)
+        (xy 33.754515 53.717898)
+        (xy 33.765177 53.712324)
+        (xy 33.895454 53.622785)
+        (xy 33.904483 53.614825)
+        (xy 34.009638 53.496803)
+        (xy 34.016511 53.486914)
+        (xy 34.090479 53.347212)
+        (xy 34.094793 53.335974)
+        (xy 34.121297 53.230454)
+        (xy 34.120429 53.217714)
+        (xy 34.110996 53.215)
+        (xy 33.024933 53.215)
+        (xy 33.012043 53.219188)
+        (xy 33.009 53.223377)
+        (xy 33.009 53.775267)
+        (xy 32.755 53.775267)
+        (xy 32.755 53.230933)
+        (xy 32.750812 53.218043)
+        (xy 32.746623 53.215)
+        (xy 31.655206 53.215)
+        (xy 31.642896 53.219)
+        (xy 31.642521 53.22853)
+        (xy 29.941166 53.22853)
+        (xy 29.940429 53.217714)
+        (xy 29.930996 53.215)
+        (xy 28.844933 53.215)
+        (xy 28.832043 53.219188)
+        (xy 28.829 53.223377)
+        (xy 28.829 53.775267)
+        (xy 28.575 53.775267)
+        (xy 28.575 53.230933)
+        (xy 28.570812 53.218043)
+        (xy 28.566623 53.215)
+        (xy 27.475206 53.215)
+        (xy 27.462896 53.219)
+        (xy 27.462521 53.22853)
+        (xy 27.1277 53.22853)
+        (xy 27.1277 52.945546)
+        (xy 27.462703 52.945546)
+        (xy 27.463571 52.958286)
+        (xy 27.473004 52.961)
+        (xy 28.559067 52.961)
+        (xy 28.571957 52.956812)
+        (xy 28.575 52.952623)
+        (xy 28.575 52.945067)
+        (xy 28.829 52.945067)
+        (xy 28.833188 52.957957)
+        (xy 28.837377 52.961)
+        (xy 29.928794 52.961)
+        (xy 29.941104 52.957)
+        (xy 29.941479 52.94747)
+        (xy 29.917356 52.846989)
+        (xy 29.913154 52.83569)
+        (xy 29.840655 52.695226)
+        (xy 29.833892 52.685274)
+        (xy 29.729976 52.566152)
+        (xy 29.721025 52.558093)
+        (xy 29.591701 52.467203)
+        (xy 29.581086 52.461511)
+        (xy 29.433819 52.404095)
+        (xy 29.422144 52.401098)
+        (xy 29.301615 52.385229)
+        (xy 29.295065 52.3848)
+        (xy 28.844933 52.3848)
+        (xy 28.832043 52.388988)
+        (xy 28.829 52.393177)
+        (xy 28.829 52.945067)
+        (xy 28.575 52.945067)
+        (xy 28.575 52.400733)
+        (xy 28.570812 52.387843)
+        (xy 28.566623 52.3848)
+        (xy 28.112341 52.3848)
+        (xy 28.106313 52.385164)
+        (xy 27.989053 52.399353)
+        (xy 27.977361 52.402225)
+        (xy 27.829485 52.458102)
+        (xy 27.818823 52.463676)
+        (xy 27.688546 52.553215)
+        (xy 27.679517 52.561175)
+        (xy 27.574362 52.679197)
+        (xy 27.567489 52.689086)
+        (xy 27.493521 52.828788)
+        (xy 27.489207 52.840026)
+        (xy 27.462703 52.945546)
+        (xy 27.1277 52.945546)
+        (xy 27.1277 44.58853)
+        (xy 27.462521 44.58853)
+        (xy 27.486644 44.689011)
+        (xy 27.490846 44.70031)
+        (xy 27.563345 44.840774)
+        (xy 27.570108 44.850726)
+        (xy 27.674024 44.969848)
+        (xy 27.682975 44.977907)
+        (xy 27.812299 45.068797)
+        (xy 27.822914 45.074489)
+        (xy 27.970181 45.131905)
+        (xy 27.981856 45.134902)
+        (xy 28.102385 45.150771)
+        (xy 28.108935 45.1512)
+        (xy 28.559067 45.1512)
+        (xy 28.571957 45.147012)
+        (xy 28.575 45.142823)
+        (xy 28.575 45.135267)
+        (xy 28.829 45.135267)
+        (xy 28.833188 45.148157)
+        (xy 28.837377 45.1512)
+        (xy 29.291659 45.1512)
+        (xy 29.297687 45.150836)
+        (xy 29.414947 45.136647)
+        (xy 29.426639 45.133775)
+        (xy 29.574515 45.077898)
+        (xy 29.585177 45.072324)
+        (xy 29.715454 44.982785)
+        (xy 29.724483 44.974825)
+        (xy 29.829638 44.856803)
+        (xy 29.836511 44.846914)
+        (xy 29.910479 44.707212)
+        (xy 29.914793 44.695974)
+        (xy 29.941297 44.590454)
+        (xy 29.940429 44.577714)
+        (xy 29.930996 44.575)
+        (xy 28.844933 44.575)
+        (xy 28.832043 44.579188)
+        (xy 28.829 44.583377)
+        (xy 28.829 45.135267)
+        (xy 28.575 45.135267)
+        (xy 28.575 44.590933)
+        (xy 28.570812 44.578043)
+        (xy 28.566623 44.575)
+        (xy 27.475206 44.575)
+        (xy 27.462896 44.579)
+        (xy 27.462521 44.58853)
+        (xy 27.1277 44.58853)
+        (xy 27.1277 44.305546)
+        (xy 27.462703 44.305546)
+        (xy 27.463571 44.318286)
+        (xy 27.473004 44.321)
+        (xy 28.559067 44.321)
+        (xy 28.571957 44.316812)
+        (xy 28.575 44.312623)
+        (xy 28.575 44.305067)
+        (xy 28.829 44.305067)
+        (xy 28.833188 44.317957)
+        (xy 28.837377 44.321)
+        (xy 29.928794 44.321)
+        (xy 29.941104 44.317)
+        (xy 29.941479 44.30747)
+        (xy 29.941017 44.305546)
+        (xy 31.642703 44.305546)
+        (xy 31.643571 44.318286)
+        (xy 31.653004 44.321)
+        (xy 32.739067 44.321)
+        (xy 32.751957 44.316812)
+        (xy 32.755 44.312623)
+        (xy 32.755 44.305067)
+        (xy 33.009 44.305067)
+        (xy 33.013188 44.317957)
+        (xy 33.017377 44.321)
+        (xy 34.108794 44.321)
+        (xy 34.121104 44.317)
+        (xy 34.121479 44.30747)
+        (xy 34.097356 44.206989)
+        (xy 34.093154 44.19569)
+        (xy 34.020655 44.055226)
+        (xy 34.013892 44.045274)
+        (xy 33.909976 43.926152)
+        (xy 33.901025 43.918093)
+        (xy 33.771701 43.827203)
+        (xy 33.761086 43.821511)
+        (xy 33.613819 43.764095)
+        (xy 33.602144 43.761098)
+        (xy 33.481615 43.745229)
+        (xy 33.475065 43.7448)
+        (xy 33.024933 43.7448)
+        (xy 33.012043 43.748988)
+        (xy 33.009 43.753177)
+        (xy 33.009 44.305067)
+        (xy 32.755 44.305067)
+        (xy 32.755 43.760733)
+        (xy 32.750812 43.747843)
+        (xy 32.746623 43.7448)
+        (xy 32.292341 43.7448)
+        (xy 32.286313 43.745164)
+        (xy 32.169053 43.759353)
+        (xy 32.157361 43.762225)
+        (xy 32.009485 43.818102)
+        (xy 31.998823 43.823676)
+        (xy 31.868546 43.913215)
+        (xy 31.859517 43.921175)
+        (xy 31.754362 44.039197)
+        (xy 31.747489 44.049086)
+        (xy 31.673521 44.188788)
+        (xy 31.669207 44.200026)
+        (xy 31.642703 44.305546)
+        (xy 29.941017 44.305546)
+        (xy 29.917356 44.206989)
+        (xy 29.913154 44.19569)
+        (xy 29.840655 44.055226)
+        (xy 29.833892 44.045274)
+        (xy 29.729976 43.926152)
+        (xy 29.721025 43.918093)
+        (xy 29.591701 43.827203)
+        (xy 29.581086 43.821511)
+        (xy 29.433819 43.764095)
+        (xy 29.422144 43.761098)
+        (xy 29.301615 43.745229)
+        (xy 29.295065 43.7448)
+        (xy 28.844933 43.7448)
+        (xy 28.832043 43.748988)
+        (xy 28.829 43.753177)
+        (xy 28.829 44.305067)
+        (xy 28.575 44.305067)
+        (xy 28.575 43.760733)
+        (xy 28.570812 43.747843)
+        (xy 28.566623 43.7448)
+        (xy 28.112341 43.7448)
+        (xy 28.106313 43.745164)
+        (xy 27.989053 43.759353)
+        (xy 27.977361 43.762225)
+        (xy 27.829485 43.818102)
+        (xy 27.818823 43.823676)
+        (xy 27.688546 43.913215)
+        (xy 27.679517 43.921175)
+        (xy 27.574362 44.039197)
+        (xy 27.567489 44.049086)
+        (xy 27.493521 44.188788)
+        (xy 27.489207 44.200026)
+        (xy 27.462703 44.305546)
+        (xy 27.1277 44.305546)
+        (xy 27.1277 43.6113)
+        (xy 27.146913 43.552169)
+        (xy 27.197213 43.515624)
+        (xy 27.2283 43.5107)
+        (xy 35.21332 43.5107)
+      )
+    )
+    (filled_polygon
+      (layer "F.Cu")
+      (pts
+        (xy 36.872451 43.529913)
+        (xy 36.908996 43.580213)
+        (xy 36.908996 43.642387)
+        (xy 36.872451 43.692687)
+        (xy 36.858991 43.700935)
+        (xy 36.768875 43.746851)
+        (xy 36.672851 43.842875)
+        (xy 36.669256 43.849931)
+        (xy 36.614795 43.956816)
+        (xy 36.614794 43.95682)
+        (xy 36.6112 43.963873)
+        (xy 36.609961 43.971694)
+        (xy 36.609961 43.971695)
+        (xy 36.596586 44.056143)
+        (xy 36.5953 44.06426)
+        (xy 36.5953 44.58174)
+        (xy 36.595919 44.585645)
+        (xy 36.595919 44.585651)
+        (xy 36.609961 44.674305)
+        (xy 36.6112 44.682127)
+        (xy 36.614794 44.68918)
+        (xy 36.614795 44.689184)
+        (xy 36.658023 44.774022)
+        (xy 36.672851 44.803125)
+        (xy 36.768875 44.899149)
+        (xy 36.775931 44.902744)
+        (xy 36.882816 44.957205)
+        (xy 36.88282 44.957206)
+        (xy 36.889873 44.9608)
+        (xy 36.897694 44.962039)
+        (xy 36.897695 44.962039)
+        (xy 36.986349 44.976081)
+        (xy 36.986355 44.976081)
+        (xy 36.99026 44.9767)
+        (xy 37.50774 44.9767)
+        (xy 37.511645 44.976081)
+        (xy 37.511651 44.976081)
+        (xy 37.600305 44.962039)
+        (xy 37.600306 44.962039)
+        (xy 37.608127 44.9608)
+        (xy 37.61518 44.957206)
+        (xy 37.615184 44.957205)
+        (xy 37.722069 44.902744)
+        (xy 37.729125 44.899149)
+        (xy 37.825149 44.803125)
+        (xy 37.873297 44.708629)
+        (xy 37.91726 44.664665)
+        (xy 37.962932 44.6537)
+        (xy 38.110068 44.6537)
+        (xy 38.169199 44.672913)
+        (xy 38.199703 44.708629)
+        (xy 38.247851 44.803125)
+        (xy 38.326758 44.882032)
+        (xy 38.354984 44.93743)
+        (xy 38.345258 44.998838)
+        (xy 38.301294 45.042802)
+        (xy 38.268754 45.052906)
+        (xy 38.217847 45.059608)
+        (xy 38.217845 45.059608)
+        (xy 38.211309 45.060469)
+        (xy 38.078342 45.115545)
+        (xy 38.035841 45.148157)
+        (xy 37.977224 45.193136)
+        (xy 37.96416 45.20316)
+        (xy 37.876545 45.317342)
+        (xy 37.821469 45.450309)
+        (xy 37.820608 45.456845)
+        (xy 37.820608 45.456847)
+        (xy 37.804989 45.575487)
+        (xy 37.802683 45.593)
+        (xy 37.805938 45.617722)
+        (xy 37.794606 45.678855)
+        (xy 37.777333 45.701986)
+        (xy 37.770878 45.708441)
+        (xy 37.71548 45.736667)
+        (xy 37.654072 45.726941)
+        (xy 37.650352 45.724684)
+        (xy 37.647841 45.722177)
+        (xy 37.531583 45.665349)
+        (xy 37.501312 45.660933)
+        (xy 37.459453 45.654826)
+        (xy 37.459446 45.654826)
+        (xy 37.455844 45.6543)
+        (xy 35.352156 45.6543)
+        (xy 35.320309 45.658988)
+        (xy 35.283494 45.664407)
+        (xy 35.283493 45.664407)
+        (xy 35.275758 45.665546)
+        (xy 35.268742 45.668991)
+        (xy 35.268741 45.668991)
+        (xy 35.167064 45.718912)
+        (xy 35.167062 45.718913)
+        (xy 35.1596 45.722577)
+        (xy 35.153726 45.728461)
+        (xy 35.153725 45.728462)
+        (xy 35.074049 45.808276)
+        (xy 35.074047 45.808279)
+        (xy 35.068177 45.814159)
+        (xy 35.064528 45.821624)
+        (xy 35.064526 45.821627)
+        (xy 35.053905 45.843356)
+        (xy 35.011349 45.930417)
+        (xy 35.010222 45.938144)
+        (xy 35.002207 45.993086)
+        (xy 35.0003 46.006156)
+        (xy 35.0003 46.449844)
+        (xy 35.011546 46.526242)
+        (xy 35.014991 46.533258)
+        (xy 35.014991 46.533259)
+        (xy 35.06402 46.633118)
+        (xy 35.068577 46.6424)
+        (xy 35.074461 46.648274)
+        (xy 35.074462 46.648275)
+        (xy 35.154276 46.727951)
+        (xy 35.154279 46.727953)
+        (xy 35.160159 46.733823)
+        (xy 35.167626 46.737473)
+        (xy 35.167629 46.737475)
+        (xy 35.23948 46.772596)
+        (xy 35.284167 46.815824)
+        (xy 35.294911 46.877063)
+        (xy 35.267607 46.932921)
+        (xy 35.239639 46.953279)
+        (xy 35.182854 46.98116)
+        (xy 35.1596 46.992577)
+        (xy 35.153726 46.998461)
+        (xy 35.153725 46.998462)
+        (xy 35.074049 47.078276)
+        (xy 35.074047 47.078279)
+        (xy 35.068177 47.084159)
+        (xy 35.064528 47.091624)
+        (xy 35.064526 47.091627)
+        (xy 35.041537 47.138658)
+        (xy 35.011349 47.200417)
+        (xy 35.010222 47.208144)
+        (xy 35.000831 47.272517)
+        (xy 35.0003 47.276156)
+        (xy 35.0003 47.58694)
+        (xy 34.981087 47.646071)
+        (xy 34.930787 47.682616)
+        (xy 34.888802 47.683719)
+        (xy 34.888557 47.686521)
+        (xy 34.879791 47.685754)
+        (xy 34.871289 47.683476)
+        (xy 34.862521 47.684243)
+        (xy 34.853753 47.683476)
+        (xy 34.854092 47.679597)
+        (xy 34.810357 47.669431)
+        (xy 34.769638 47.622446)
+        (xy 34.7617 47.583278)
+        (xy 34.7617 47.347936)
+        (xy 34.749881 47.28852)
+        (xy 34.753762 47.287748)
+        (xy 34.750599 47.247623)
+        (xy 34.749881 47.24748)
+        (xy 34.750387 47.244935)
+        (xy 34.7617 47.188064)
+        (xy 34.7617 46.847936)
+        (xy 34.749881 46.78852)
+        (xy 34.744839 46.780974)
+        (xy 34.740003 46.719515)
+        (xy 34.744588 46.705402)
+        (xy 34.749881 46.69748)
+        (xy 34.7617 46.638064)
+        (xy 34.7617 45.997936)
+        (xy 34.749881 45.93852)
+        (xy 34.753542 45.937792)
+        (xy 34.750363 45.897475)
+        (xy 34.74941 45.897285)
+        (xy 34.750082 45.893908)
+        (xy 34.750078 45.893862)
+        (xy 34.750111 45.89376)
+        (xy 34.760235 45.842864)
+        (xy 34.7612 45.833068)
+        (xy 34.7612 45.660933)
+        (xy 34.757012 45.648043)
+        (xy 34.752823 45.645)
+        (xy 33.8066 45.645)
+        (xy 33.747469 45.625787)
+        (xy 33.710924 45.575487)
+        (xy 33.706 45.5444)
+        (xy 33.706 45.4916)
+        (xy 33.725213 45.432469)
+        (xy 33.775513 45.395924)
+        (xy 33.8066 45.391)
+        (xy 34.745267 45.391)
+        (xy 34.758157 45.386812)
+        (xy 34.7612 45.382623)
+        (xy 34.7612 45.202932)
+        (xy 34.760235 45.193136)
+        (xy 34.751343 45.148435)
+        (xy 34.743555 45.129633)
+        (xy 34.738676 45.06765)
+        (xy 34.771161 45.014637)
+        (xy 34.828602 44.990843)
+        (xy 34.849628 44.991394)
+        (xy 34.91846 45.000456)
+        (xy 34.925 45.001317)
+        (xy 34.93154 45.000456)
+        (xy 35.061153 44.983392)
+        (xy 35.061155 44.983392)
+        (xy 35.067691 44.982531)
+        (xy 35.082976 44.9762)
+        (xy 35.170923 44.939772)
+        (xy 35.232906 44.934894)
+        (xy 35.255093 44.943079)
+        (xy 35.282818 44.957206)
+        (xy 35.282821 44.957207)
+        (xy 35.289873 44.9608)
+        (xy 35.297691 44.962038)
+        (xy 35.297693 44.962039)
+        (xy 35.386349 44.976081)
+        (xy 35.386355 44.976081)
+        (xy 35.39026 44.9767)
+        (xy 35.90774 44.9767)
+        (xy 35.911645 44.976081)
+        (xy 35.911651 44.976081)
+        (xy 36.000305 44.962039)
+        (xy 36.000306 44.962039)
+        (xy 36.008127 44.9608)
+        (xy 36.01518 44.957206)
+        (xy 36.015184 44.957205)
+        (xy 36.122069 44.902744)
+        (xy 36.129125 44.899149)
+        (xy 36.225149 44.803125)
+        (xy 36.239977 44.774022)
+        (xy 36.283205 44.689184)
+        (xy 36.283206 44.68918)
+        (xy 36.2868 44.682127)
+        (xy 36.288039 44.674305)
+        (xy 36.302081 44.585651)
+        (xy 36.302081 44.585645)
+        (xy 36.3027 44.58174)
+        (xy 36.3027 44.06426)
+        (xy 36.301415 44.056143)
+        (xy 36.288039 43.971695)
+        (xy 36.288039 43.971694)
+        (xy 36.2868 43.963873)
+        (xy 36.283206 43.95682)
+        (xy 36.283205 43.956816)
+        (xy 36.228744 43.849931)
+        (xy 36.225149 43.842875)
+        (xy 36.129125 43.746851)
+        (xy 36.039009 43.700935)
+        (xy 35.995045 43.656972)
+        (xy 35.985318 43.595563)
+        (xy 36.013545 43.540165)
+        (xy 36.068942 43.511939)
+        (xy 36.08468 43.5107)
+        (xy 36.81332 43.5107)
+      )
+    )
+  )
+  (zone (net 11) (net_name "GND") (layer "B.Cu") (tstamp 7c289ea3-a8eb-4bf9-bc4d-6cc10ec3f1c3) (hatch edge 0.508)
+    (connect_pads (clearance 0.2032))
+    (min_thickness 0.2032) (filled_areas_thickness no)
+    (fill yes (thermal_gap 0.2032) (thermal_bridge_width 0.254))
+    (polygon
+      (pts
+        (xy 42.164 54.229)
+        (xy 26.924 54.229)
+        (xy 26.924 43.307)
+        (xy 42.164 43.307)
+      )
+    )
+    (filled_polygon
+      (layer "B.Cu")
+      (pts
+        (xy 41.893431 43.529913)
+        (xy 41.929976 43.580213)
+        (xy 41.9349 43.6113)
+        (xy 41.9349 53.9247)
+        (xy 41.915687 53.983831)
+        (xy 41.865387 54.020376)
+        (xy 41.8343 54.0253)
+        (xy 41.004462 54.0253)
+        (xy 40.945331 54.006087)
+        (xy 40.908786 53.955787)
+        (xy 40.908786 53.893613)
+        (xy 40.942674 53.846968)
+        (xy 40.942106 53.846337)
+        (xy 40.945073 53.843665)
+        (xy 40.945327 53.843316)
+        (xy 40.946021 53.842812)
+        (xy 40.946025 53.842809)
+        (xy 40.950291 53.839709)
+        (xy 41.05997 53.717898)
+        (xy 41.064728 53.712614)
+        (xy 41.064729 53.712612)
+        (xy 41.06826 53.708691)
+        (xy 41.156411 53.556009)
+        (xy 41.210891 53.388336)
+        (xy 41.215214 53.347212)
+        (xy 41.228769 53.218242)
+        (xy 41.22932 53.213)
+        (xy 41.210891 53.037664)
+        (xy 41.209262 53.03265)
+        (xy 41.182936 52.951626)
+        (xy 41.182936 52.889451)
+        (xy 41.219481 52.839152)
+        (xy 41.263964 52.821011)
+        (xy 41.268716 52.820312)
+        (xy 41.280309 52.818606)
+        (xy 41.280311 52.818605)
+        (xy 41.288045 52.817467)
+        (xy 41.365529 52.779424)
+        (xy 41.38628 52.769236)
+        (xy 41.386281 52.769235)
+        (xy 41.393744 52.765571)
+        (xy 41.476934 52.682235)
+        (xy 41.528646 52.576445)
+        (xy 41.538169 52.511167)
+        (xy 41.538174 52.511136)
+        (xy 41.538174 52.511129)
+        (xy 41.5387 52.507527)
+        (xy 41.538699 52.140474)
+        (xy 41.528467 52.070955)
+        (xy 41.476571 51.965256)
+        (xy 41.469901 51.958597)
+        (xy 41.41838 51.907167)
+        (xy 41.393235 51.882066)
+        (xy 41.287445 51.830354)
+        (xy 41.260779 51.826464)
+        (xy 41.222136 51.820826)
+        (xy 41.222129 51.820826)
+        (xy 41.218527 51.8203)
+        (xy 40.449692 51.8203)
+        (xy 39.673474 51.820301)
+        (xy 39.603955 51.830533)
+        (xy 39.556159 51.854)
+        (xy 39.50572 51.878764)
+        (xy 39.505719 51.878765)
+        (xy 39.498256 51.882429)
+        (xy 39.415066 51.965765)
+        (xy 39.363354 52.071555)
+        (xy 39.362227 52.079282)
+        (xy 39.353831 52.136835)
+        (xy 39.3533 52.140473)
+        (xy 39.353301 52.507526)
+        (xy 39.363533 52.577045)
+        (xy 39.366979 52.584063)
+        (xy 39.402009 52.65541)
+        (xy 39.415429 52.682744)
+        (xy 39.498765 52.765934)
+        (xy 39.506231 52.769583)
+        (xy 39.506233 52.769585)
+        (xy 39.550257 52.791104)
+        (xy 39.594944 52.834333)
+        (xy 39.605687 52.895572)
+        (xy 39.601754 52.912571)
+        (xy 39.586019 52.961)
+        (xy 39.561109 53.037664)
+        (xy 39.54268 53.213)
+        (xy 39.543231 53.218242)
+        (xy 39.556787 53.347212)
+        (xy 39.561109 53.388336)
+        (xy 39.615589 53.556009)
+        (xy 39.70374 53.708691)
+        (xy 39.707271 53.712612)
+        (xy 39.707272 53.712614)
+        (xy 39.71203 53.717898)
+        (xy 39.821709 53.839709)
+        (xy 39.825975 53.842809)
+        (xy 39.825979 53.842812)
+        (xy 39.826673 53.843316)
+        (xy 39.826927 53.843665)
+        (xy 39.829894 53.846337)
+        (xy 39.829326 53.846968)
+        (xy 39.863216 53.893617)
+        (xy 39.863213 53.955792)
+        (xy 39.826665 54.00609)
+        (xy 39.767538 54.0253)
+        (xy 38.464462 54.0253)
+        (xy 38.405331 54.006087)
+        (xy 38.368786 53.955787)
+        (xy 38.368786 53.893613)
+        (xy 38.402674 53.846968)
+        (xy 38.402106 53.846337)
+        (xy 38.405073 53.843665)
+        (xy 38.405327 53.843316)
+        (xy 38.406021 53.842812)
+        (xy 38.406025 53.842809)
+        (xy 38.410291 53.839709)
+        (xy 38.51997 53.717898)
+        (xy 38.524728 53.712614)
+        (xy 38.524729 53.712612)
+        (xy 38.52826 53.708691)
+        (xy 38.616411 53.556009)
+        (xy 38.670891 53.388336)
+        (xy 38.675214 53.347212)
+        (xy 38.688769 53.218242)
+        (xy 38.68932 53.213)
+        (xy 38.670891 53.037664)
+        (xy 38.616411 52.869991)
+        (xy 38.52826 52.717309)
+        (xy 38.517101 52.704915)
+        (xy 38.453428 52.6342)
+        (xy 38.410291 52.586291)
+        (xy 38.371267 52.557938)
+        (xy 38.334722 52.50764)
+        (xy 38.334721 52.445466)
+        (xy 38.359263 52.405417)
+        (xy 39.312582 51.452098)
+        (xy 39.36798 51.423872)
+        (xy 39.429388 51.433598)
+        (xy 39.45479 51.452036)
+        (xy 39.498765 51.495934)
+        (xy 39.506234 51.499585)
+        (xy 39.595638 51.543287)
+        (xy 39.604555 51.547646)
+        (xy 39.631221 51.551536)
+        (xy 39.669864 51.557174)
+        (xy 39.669871 51.557174)
+        (xy 39.673473 51.5577)
+        (xy 40.442308 51.5577)
+        (xy 41.218526 51.557699)
+        (xy 41.288045 51.547467)
+        (xy 41.367963 51.508229)
+        (xy 41.38628 51.499236)
+        (xy 41.386281 51.499235)
+        (xy 41.393744 51.495571)
+        (xy 41.406019 51.483275)
+        (xy 41.438304 51.450933)
+        (xy 41.476934 51.412235)
+        (xy 41.508687 51.347276)
+        (xy 41.525217 51.31346)
+        (xy 41.528646 51.306445)
+        (xy 41.533088 51.275997)
+        (xy 41.538174 51.241136)
+        (xy 41.538174 51.241129)
+        (xy 41.5387 51.237527)
+        (xy 41.538699 50.870474)
+        (xy 41.528467 50.800955)
+        (xy 41.494761 50.732305)
+        (xy 41.480236 50.70272)
+        (xy 41.480235 50.702719)
+        (xy 41.476571 50.695256)
+        (xy 41.463132 50.68184)
+        (xy 41.424875 50.643651)
+        (xy 41.393235 50.612066)
+        (xy 41.370922 50.601159)
+        (xy 41.29446 50.563783)
+        (xy 41.287445 50.560354)
+        (xy 41.260779 50.556464)
+        (xy 41.222136 50.550826)
+        (xy 41.222129 50.550826)
+        (xy 41.218527 50.5503)
+        (xy 40.449692 50.5503)
+        (xy 39.673474 50.550301)
+        (xy 39.603955 50.560533)
+        (xy 39.554996 50.584571)
+        (xy 39.50572 50.608764)
+        (xy 39.505719 50.608765)
+        (xy 39.498256 50.612429)
+        (xy 39.492379 50.618316)
+        (xy 39.492378 50.618317)
+        (xy 39.417055 50.693772)
+        (xy 39.361683 50.722048)
+        (xy 39.345858 50.7233)
+        (xy 39.261825 50.7233)
+        (xy 39.253058 50.722917)
+        (xy 39.250177 50.722665)
+        (xy 39.213733 50.719477)
+        (xy 39.179441 50.728665)
+        (xy 39.175604 50.729693)
+        (xy 39.167037 50.731592)
+        (xy 39.136814 50.736921)
+        (xy 39.136813 50.736921)
+        (xy 39.128149 50.738449)
+        (xy 39.12053 50.742848)
+        (xy 39.114957 50.744876)
+        (xy 39.109581 50.747383)
+        (xy 39.101083 50.74966)
+        (xy 39.068736 50.77231)
+        (xy 39.061336 50.777024)
+        (xy 39.054322 50.781073)
+        (xy 38.993506 50.793996)
+        (xy 38.936708 50.768705)
+        (xy 38.905624 50.714858)
+        (xy 38.904496 50.686131)
+        (xy 38.904456 50.686131)
+        (xy 38.904456 50.685122)
+        (xy 38.904287 50.680822)
+        (xy 38.905317 50.673)
+        (xy 38.902062 50.648279)
+        (xy 38.913391 50.587149)
+        (xy 38.930666 50.564014)
+        (xy 39.312582 50.182098)
+        (xy 39.36798 50.153872)
+        (xy 39.429388 50.163598)
+        (xy 39.45479 50.182036)
+        (xy 39.498765 50.225934)
+        (xy 39.604555 50.277646)
+        (xy 39.631221 50.281536)
+        (xy 39.669864 50.287174)
+        (xy 39.669871 50.287174)
+        (xy 39.673473 50.2877)
+        (xy 40.442308 50.2877)
+        (xy 41.218526 50.287699)
+        (xy 41.288045 50.277467)
+        (xy 41.339011 50.252444)
+        (xy 41.38628 50.229236)
+        (xy 41.386281 50.229235)
+        (xy 41.393744 50.225571)
+        (xy 41.419707 50.199563)
+        (xy 41.455608 50.163598)
+        (xy 41.476934 50.142235)
+        (xy 41.528646 50.036445)
+        (xy 41.53285 50.007627)
+        (xy 41.538174 49.971136)
+        (xy 41.538174 49.971129)
+        (xy 41.5387 49.967527)
+        (xy 41.538699 49.600474)
+        (xy 41.528467 49.530955)
+        (xy 41.490152 49.452917)
+        (xy 41.480236 49.43272)
+        (xy 41.480235 49.432719)
+        (xy 41.476571 49.425256)
+        (xy 41.460828 49.40954)
+        (xy 41.426026 49.3748)
+        (xy 41.393235 49.342066)
+        (xy 41.381951 49.33655)
+        (xy 41.29446 49.293783)
+        (xy 41.287445 49.290354)
+        (xy 41.260779 49.286464)
+        (xy 41.222136 49.280826)
+        (xy 41.222129 49.280826)
+        (xy 41.218527 49.2803)
+        (xy 40.449692 49.2803)
+        (xy 39.673474 49.280301)
+        (xy 39.603955 49.290533)
+        (xy 39.552989 49.315556)
+        (xy 39.50572 49.338764)
+        (xy 39.505719 49.338765)
+        (xy 39.498256 49.342429)
+        (xy 39.492379 49.348316)
+        (xy 39.492378 49.348317)
+        (xy 39.417055 49.423772)
+        (xy 39.361683 49.452048)
+        (xy 39.345858 49.4533)
+        (xy 39.261833 49.4533)
+        (xy 39.253065 49.452917)
+        (xy 39.222501 49.450243)
+        (xy 39.213733 49.449476)
+        (xy 39.205231 49.451754)
+        (xy 39.175608 49.459691)
+        (xy 39.167042 49.461591)
+        (xy 39.136813 49.466921)
+        (xy 39.136811 49.466922)
+        (xy 39.128149 49.468449)
+        (xy 39.120531 49.472847)
+        (xy 39.114957 49.474876)
+        (xy 39.109582 49.477383)
+        (xy 39.101084 49.47966)
+        (xy 39.093874 49.484709)
+        (xy 39.093873 49.484709)
+        (xy 39.068742 49.502305)
+        (xy 39.061345 49.507018)
+        (xy 39.054331 49.511068)
+        (xy 38.993516 49.523997)
+        (xy 38.936716 49.498712)
+        (xy 38.905626 49.444869)
+        (xy 38.904496 49.416131)
+        (xy 38.904456 49.416131)
+        (xy 38.904456 49.415117)
+        (xy 38.904287 49.410822)
+        (xy 38.905317 49.403)
+        (xy 38.902062 49.378279)
+        (xy 38.913391 49.317149)
+        (xy 38.930666 49.294014)
+        (xy 39.312582 48.912098)
+        (xy 39.36798 48.883872)
+        (xy 39.429388 48.893598)
+        (xy 39.45479 48.912036)
+        (xy 39.498765 48.955934)
+        (xy 39.506234 48.959585)
+        (xy 39.566842 48.989211)
+        (xy 39.604555 49.007646)
+        (xy 39.631221 49.011536)
+        (xy 39.669864 49.017174)
+        (xy 39.669871 49.017174)
+        (xy 39.673473 49.0177)
+        (xy 40.442308 49.0177)
+        (xy 41.218526 49.017699)
+        (xy 41.288045 49.007467)
+        (xy 41.339011 48.982444)
+        (xy 41.38628 48.959236)
+        (xy 41.386281 48.959235)
+        (xy 41.393744 48.955571)
+        (xy 41.403845 48.945453)
+        (xy 41.445342 48.903882)
+        (xy 41.476934 48.872235)
+        (xy 41.528646 48.766445)
+        (xy 41.532536 48.739779)
+        (xy 41.538174 48.701136)
+        (xy 41.538174 48.701129)
+        (xy 41.5387 48.697527)
+        (xy 41.538699 48.330474)
+        (xy 41.528467 48.260955)
+        (xy 41.490152 48.182917)
+        (xy 41.480236 48.16272)
+        (xy 41.480235 48.162719)
+        (xy 41.476571 48.155256)
+        (xy 41.460828 48.13954)
+        (xy 41.403099 48.081913)
+        (xy 41.393235 48.072066)
+        (xy 41.385766 48.068415)
+        (xy 41.29446 48.023783)
+        (xy 41.287445 48.020354)
+        (xy 41.260779 48.016464)
+        (xy 41.222136 48.010826)
+        (xy 41.222129 48.010826)
+        (xy 41.218527 48.0103)
+        (xy 40.449692 48.0103)
+        (xy 39.673474 48.010301)
+        (xy 39.603955 48.020533)
+        (xy 39.557778 48.043205)
+        (xy 39.50572 48.068764)
+        (xy 39.505719 48.068765)
+        (xy 39.498256 48.072429)
+        (xy 39.492379 48.078316)
+        (xy 39.492378 48.078317)
+        (xy 39.417055 48.153772)
+        (xy 39.361683 48.182048)
+        (xy 39.345858 48.1833)
+        (xy 39.261833 48.1833)
+        (xy 39.253065 48.182917)
+        (xy 39.222501 48.180243)
+        (xy 39.213733 48.179476)
+        (xy 39.205231 48.181754)
+        (xy 39.175608 48.189691)
+        (xy 39.167042 48.191591)
+        (xy 39.136813 48.196921)
+        (xy 39.136811 48.196922)
+        (xy 39.128149 48.198449)
+        (xy 39.120531 48.202847)
+        (xy 39.114957 48.204876)
+        (xy 39.109582 48.207383)
+        (xy 39.101084 48.20966)
+        (xy 39.093874 48.214709)
+        (xy 39.093873 48.214709)
+        (xy 39.068742 48.232305)
+        (xy 39.061345 48.237018)
+        (xy 39.054331 48.241068)
+        (xy 38.993516 48.253997)
+        (xy 38.936716 48.228712)
+        (xy 38.905626 48.174869)
+        (xy 38.904496 48.146131)
+        (xy 38.904456 48.146131)
+        (xy 38.904456 48.145117)
+        (xy 38.904287 48.140822)
+        (xy 38.905317 48.133)
+        (xy 38.902062 48.108279)
+        (xy 38.913391 48.047149)
+        (xy 38.930666 48.024014)
+        (xy 39.312582 47.642098)
+        (xy 39.36798 47.613872)
+        (xy 39.429388 47.623598)
+        (xy 39.45479 47.642036)
+        (xy 39.498765 47.685934)
+        (xy 39.604555 47.737646)
+        (xy 39.631221 47.741536)
+        (xy 39.669864 47.747174)
+        (xy 39.669871 47.747174)
+        (xy 39.673473 47.7477)
+        (xy 40.442308 47.7477)
+        (xy 41.218526 47.747699)
+        (xy 41.288045 47.737467)
+        (xy 41.365757 47.699312)
+        (xy 41.38628 47.689236)
+        (xy 41.386281 47.689235)
+        (xy 41.393744 47.685571)
+        (xy 41.419707 47.659563)
+        (xy 41.471061 47.608118)
+        (xy 41.476934 47.602235)
+        (xy 41.516656 47.520974)
+        (xy 41.525217 47.50346)
+        (xy 41.528646 47.496445)
+        (xy 41.5387 47.427527)
+        (xy 41.538699 47.060474)
+        (xy 41.528467 46.990955)
+        (xy 41.490152 46.912917)
+        (xy 41.480236 46.89272)
+        (xy 41.480235 46.892719)
+        (xy 41.476571 46.885256)
+        (xy 41.460828 46.86954)
+        (xy 41.399118 46.807939)
+        (xy 41.393235 46.802066)
+        (xy 41.385766 46.798415)
+        (xy 41.29446 46.753783)
+        (xy 41.287445 46.750354)
+        (xy 41.260779 46.746464)
+        (xy 41.222136 46.740826)
+        (xy 41.222129 46.740826)
+        (xy 41.218527 46.7403)
+        (xy 40.449692 46.7403)
+        (xy 39.673474 46.740301)
+        (xy 39.603955 46.750533)
+        (xy 39.595468 46.7547)
+        (xy 39.50572 46.798764)
+        (xy 39.505719 46.798765)
+        (xy 39.498256 46.802429)
+        (xy 39.492379 46.808316)
+        (xy 39.492378 46.808317)
+        (xy 39.417055 46.883772)
+        (xy 39.361683 46.912048)
+        (xy 39.345858 46.9133)
+        (xy 39.261833 46.9133)
+        (xy 39.253065 46.912917)
+        (xy 39.222501 46.910243)
+        (xy 39.213733 46.909476)
+        (xy 39.205231 46.911754)
+        (xy 39.175608 46.919691)
+        (xy 39.167042 46.921591)
+        (xy 39.136813 46.926921)
+        (xy 39.136811 46.926922)
+        (xy 39.128149 46.928449)
+        (xy 39.120531 46.932847)
+        (xy 39.114957 46.934876)
+        (xy 39.109582 46.937383)
+        (xy 39.101084 46.93966)
+        (xy 39.093874 46.944709)
+        (xy 39.093873 46.944709)
+        (xy 39.068742 46.962305)
+        (xy 39.061345 46.967018)
+        (xy 39.054331 46.971068)
+        (xy 38.993516 46.983997)
+        (xy 38.936716 46.958712)
+        (xy 38.905626 46.904869)
+        (xy 38.904496 46.876131)
+        (xy 38.904456 46.876131)
+        (xy 38.904456 46.875117)
+        (xy 38.904287 46.870822)
+        (xy 38.905317 46.863)
+        (xy 38.902062 46.838279)
+        (xy 38.913391 46.777149)
+        (xy 38.930666 46.754014)
+        (xy 39.312582 46.372098)
+        (xy 39.36798 46.343872)
+        (xy 39.429388 46.353598)
+        (xy 39.45479 46.372036)
+        (xy 39.498765 46.415934)
+        (xy 39.604555 46.467646)
+        (xy 39.631221 46.471536)
+        (xy 39.669864 46.477174)
+        (xy 39.669871 46.477174)
+        (xy 39.673473 46.4777)
+        (xy 40.442308 46.4777)
+        (xy 41.218526 46.477699)
+        (xy 41.288045 46.467467)
+        (xy 41.339011 46.442444)
+        (xy 41.38628 46.419236)
+        (xy 41.386281 46.419235)
+        (xy 41.393744 46.415571)
+        (xy 41.419707 46.389563)
+        (xy 41.471061 46.338118)
+        (xy 41.476934 46.332235)
+        (xy 41.528646 46.226445)
+        (xy 41.538053 46.161963)
+        (xy 41.538174 46.161136)
+        (xy 41.538174 46.161129)
+        (xy 41.5387 46.157527)
+        (xy 41.538699 45.790474)
+        (xy 41.528467 45.720955)
+        (xy 41.490152 45.642917)
+        (xy 41.480236 45.62272)
+        (xy 41.480235 45.622719)
+        (xy 41.476571 45.615256)
+        (xy 41.460828 45.59954)
+        (xy 41.424338 45.563115)
+        (xy 41.393235 45.532066)
+        (xy 41.37112 45.521256)
+        (xy 41.29446 45.483783)
+        (xy 41.287445 45.480354)
+        (xy 41.260779 45.476464)
+        (xy 41.222136 45.470826)
+        (xy 41.222129 45.470826)
+        (xy 41.218527 45.4703)
+        (xy 40.449692 45.4703)
+        (xy 39.673474 45.470301)
+        (xy 39.603955 45.480533)
+        (xy 39.572459 45.495997)
+        (xy 39.50572 45.528764)
+        (xy 39.505719 45.528765)
+        (xy 39.498256 45.532429)
+        (xy 39.492379 45.538316)
+        (xy 39.492378 45.538317)
+        (xy 39.417055 45.613772)
+        (xy 39.361683 45.642048)
+        (xy 39.345858 45.6433)
+        (xy 39.261833 45.6433)
+        (xy 39.253065 45.642917)
+        (xy 39.222501 45.640243)
+        (xy 39.213733 45.639476)
+        (xy 39.205231 45.641754)
+        (xy 39.175608 45.649691)
+        (xy 39.167042 45.651591)
+        (xy 39.136813 45.656921)
+        (xy 39.136811 45.656922)
+        (xy 39.128149 45.658449)
+        (xy 39.120531 45.662847)
+        (xy 39.114957 45.664876)
+        (xy 39.109582 45.667383)
+        (xy 39.101084 45.66966)
+        (xy 39.093874 45.674709)
+        (xy 39.093873 45.674709)
+        (xy 39.068742 45.692305)
+        (xy 39.061345 45.697018)
+        (xy 39.054331 45.701068)
+        (xy 38.993516 45.713997)
+        (xy 38.936716 45.688712)
+        (xy 38.905626 45.634869)
+        (xy 38.904496 45.606131)
+        (xy 38.904456 45.606131)
+        (xy 38.904456 45.605117)
+        (xy 38.904287 45.600822)
+        (xy 38.905317 45.593)
+        (xy 38.902062 45.568279)
+        (xy 38.913391 45.507149)
+        (xy 38.930666 45.484014)
+        (xy 39.312582 45.102098)
+        (xy 39.36798 45.073872)
+        (xy 39.429388 45.083598)
+        (xy 39.45479 45.102036)
+        (xy 39.498765 45.145934)
+        (xy 39.506234 45.149585)
+        (xy 39.558794 45.175277)
+        (xy 39.604555 45.197646)
+        (xy 39.631221 45.201536)
+        (xy 39.669864 45.207174)
+        (xy 39.669871 45.207174)
+        (xy 39.673473 45.2077)
+        (xy 40.442308 45.2077)
+        (xy 41.218526 45.207699)
+        (xy 41.288045 45.197467)
+        (xy 41.343088 45.170442)
+        (xy 41.38628 45.149236)
+        (xy 41.386281 45.149235)
+        (xy 41.393744 45.145571)
+        (xy 41.402653 45.136647)
+        (xy 41.465317 45.073872)
+        (xy 41.476934 45.062235)
+        (xy 41.528646 44.956445)
+        (xy 41.532536 44.929779)
+        (xy 41.538174 44.891136)
+        (xy 41.538174 44.891129)
+        (xy 41.5387 44.887527)
+        (xy 41.538699 44.520474)
+        (xy 41.528467 44.450955)
+        (xy 41.490152 44.372917)
+        (xy 41.480236 44.35272)
+        (xy 41.480235 44.352719)
+        (xy 41.476571 44.345256)
+        (xy 41.452273 44.321)
+        (xy 41.399118 44.267939)
+        (xy 41.393235 44.262066)
+        (xy 41.287445 44.210354)
+        (xy 41.257942 44.20605)
+        (xy 41.222136 44.200826)
+        (xy 41.222129 44.200826)
+        (xy 41.218527 44.2003)
+        (xy 40.449692 44.2003)
+        (xy 39.673474 44.200301)
+        (xy 39.603955 44.210533)
+        (xy 39.552989 44.235556)
+        (xy 39.50572 44.258764)
+        (xy 39.505719 44.258765)
+        (xy 39.498256 44.262429)
+        (xy 39.492379 44.268316)
+        (xy 39.492378 44.268317)
+        (xy 39.417055 44.343772)
+        (xy 39.361683 44.372048)
+        (xy 39.345858 44.3733)
+        (xy 39.261833 44.3733)
+        (xy 39.253065 44.372917)
+        (xy 39.222501 44.370243)
+        (xy 39.213733 44.369476)
+        (xy 39.205231 44.371754)
+        (xy 39.175608 44.379691)
+        (xy 39.167042 44.381591)
+        (xy 39.136813 44.386921)
+        (xy 39.136811 44.386922)
+        (xy 39.128149 44.388449)
+        (xy 39.120531 44.392847)
+        (xy 39.114957 44.394876)
+        (xy 39.109582 44.397383)
+        (xy 39.101084 44.39966)
+        (xy 39.093874 44.404709)
+        (xy 39.093873 44.404709)
+        (xy 39.068742 44.422305)
+        (xy 39.061343 44.427019)
+        (xy 39.034775 44.442359)
+        (xy 39.027151 44.446761)
+        (xy 39.021494 44.453503)
+        (xy 39.001768 44.477011)
+        (xy 38.995839 44.483481)
+        (xy 38.462986 45.016334)
+        (xy 38.407588 45.04456)
+        (xy 38.378724 45.044938)
+        (xy 38.354 45.041683)
+        (xy 38.34746 45.042544)
+        (xy 38.217847 45.059608)
+        (xy 38.217845 45.059608)
+        (xy 38.211309 45.060469)
+        (xy 38.078342 45.115545)
+        (xy 37.96416 45.20316)
+        (xy 37.876545 45.317342)
+        (xy 37.821469 45.450309)
+        (xy 37.820608 45.456845)
+        (xy 37.820608 45.456847)
+        (xy 37.805937 45.568282)
+        (xy 37.802683 45.593)
+        (xy 37.803544 45.59954)
+        (xy 37.816378 45.697018)
+        (xy 37.821469 45.735691)
+        (xy 37.876545 45.868658)
+        (xy 37.96416 45.98284)
+        (xy 37.969391 45.986854)
+        (xy 37.969392 45.986855)
+        (xy 38.071963 46.065561)
+        (xy 38.078341 46.070455)
+        (xy 38.211309 46.125531)
+        (xy 38.217845 46.126392)
+        (xy 38.217847 46.126392)
+        (xy 38.232045 46.128261)
+        (xy 38.288163 46.155028)
+        (xy 38.317829 46.209667)
+        (xy 38.309714 46.27131)
+        (xy 38.266916 46.316409)
+        (xy 38.232045 46.327739)
+        (xy 38.217847 46.329608)
+        (xy 38.217845 46.329608)
+        (xy 38.211309 46.330469)
+        (xy 38.078342 46.385545)
+        (xy 37.96416 46.47316)
+        (xy 37.876545 46.587342)
+        (xy 37.821469 46.720309)
+        (xy 37.820608 46.726845)
+        (xy 37.820608 46.726847)
+        (xy 37.81114 46.798764)
+        (xy 37.802683 46.863)
+        (xy 37.803544 46.86954)
+        (xy 37.816378 46.967018)
+        (xy 37.821469 47.005691)
+        (xy 37.876545 47.138658)
+        (xy 37.96416 47.25284)
+        (xy 38.078341 47.340455)
+        (xy 38.211309 47.395531)
+        (xy 38.217845 47.396392)
+        (xy 38.217847 47.396392)
+        (xy 38.232045 47.398261)
+        (xy 38.288163 47.425028)
+        (xy 38.317829 47.479667)
+        (xy 38.309714 47.54131)
+        (xy 38.266916 47.586409)
+        (xy 38.232045 47.597739)
+        (xy 38.217847 47.599608)
+        (xy 38.217845 47.599608)
+        (xy 38.211309 47.600469)
+        (xy 38.078342 47.655545)
+        (xy 37.96416 47.74316)
+        (xy 37.876545 47.857342)
+        (xy 37.821469 47.990309)
+        (xy 37.820608 47.996845)
+        (xy 37.820608 47.996847)
+        (xy 37.812413 48.059093)
+        (xy 37.802683 48.133)
+        (xy 37.803544 48.13954)
+        (xy 37.820567 48.268836)
+        (xy 37.821469 48.275691)
+        (xy 37.876545 48.408658)
+        (xy 37.96416 48.52284)
+        (xy 37.969391 48.526854)
+        (xy 37.969392 48.526855)
+        (xy 37.971462 48.528443)
+        (xy 38.078341 48.610455)
+        (xy 38.211309 48.665531)
+        (xy 38.217845 48.666392)
+        (xy 38.217847 48.666392)
+        (xy 38.232045 48.668261)
+        (xy 38.288163 48.695028)
+        (xy 38.317829 48.749667)
+        (xy 38.309714 48.81131)
+        (xy 38.266916 48.856409)
+        (xy 38.232045 48.867739)
+        (xy 38.217847 48.869608)
+        (xy 38.217845 48.869608)
+        (xy 38.211309 48.870469)
+        (xy 38.078342 48.925545)
+        (xy 37.96416 49.01316)
+        (xy 37.876545 49.127342)
+        (xy 37.821469 49.260309)
+        (xy 37.820608 49.266845)
+        (xy 37.820608 49.266847)
+        (xy 37.815396 49.306439)
+        (xy 37.802683 49.403)
+        (xy 37.803544 49.40954)
+        (xy 37.816378 49.507018)
+        (xy 37.821469 49.545691)
+        (xy 37.876545 49.678658)
+        (xy 37.96416 49.79284)
+        (xy 37.969391 49.796854)
+        (xy 37.969392 49.796855)
+        (xy 38.061816 49.867775)
+        (xy 38.078341 49.880455)
+        (xy 38.211309 49.935531)
+        (xy 38.217845 49.936392)
+        (xy 38.217847 49.936392)
+        (xy 38.232045 49.938261)
+        (xy 38.288163 49.965028)
+        (xy 38.317829 50.019667)
+        (xy 38.309714 50.08131)
+        (xy 38.266916 50.126409)
+        (xy 38.232045 50.137739)
+        (xy 38.217847 50.139608)
+        (xy 38.217845 50.139608)
+        (xy 38.211309 50.140469)
+        (xy 38.078342 50.195545)
+        (xy 37.96416 50.28316)
+        (xy 37.876545 50.397342)
+        (xy 37.821469 50.530309)
+        (xy 37.820608 50.536845)
+        (xy 37.820608 50.536847)
+        (xy 37.805937 50.648282)
+        (xy 37.802683 50.673)
+        (xy 37.803544 50.67954)
+        (xy 37.816558 50.778386)
+        (xy 37.821469 50.815691)
+        (xy 37.876545 50.948658)
+        (xy 37.96416 51.06284)
+        (xy 37.969391 51.066854)
+        (xy 37.969392 51.066855)
+        (xy 38.073111 51.146442)
+        (xy 38.078341 51.150455)
+        (xy 38.211309 51.205531)
+        (xy 38.217845 51.206392)
+        (xy 38.217847 51.206392)
+        (xy 38.34746 51.223456)
+        (xy 38.354 51.224317)
+        (xy 38.36054 51.223456)
+        (xy 38.362994 51.223456)
+        (xy 38.422125 51.242669)
+        (xy 38.45867 51.292969)
+        (xy 38.45867 51.355143)
+        (xy 38.434129 51.395191)
+        (xy 37.625481 52.203839)
+        (xy 37.619011 52.209768)
+        (xy 37.588761 52.235151)
+        (xy 37.58436 52.242774)
+        (xy 37.584359 52.242775)
+        (xy 37.569019 52.269343)
+        (xy 37.564305 52.276742)
+        (xy 37.546709 52.301873)
+        (xy 37.54166 52.309084)
+        (xy 37.539383 52.317582)
+        (xy 37.536876 52.322957)
+        (xy 37.534847 52.328531)
+        (xy 37.530449 52.336149)
+        (xy 37.528922 52.344811)
+        (xy 37.528921 52.344813)
+        (xy 37.523591 52.375042)
+        (xy 37.521694 52.383597)
+        (xy 37.517161 52.400517)
+        (xy 37.483301 52.452659)
+        (xy 37.460907 52.466383)
+        (xy 37.42434 52.482663)
+        (xy 37.385111 52.511165)
+        (xy 37.297758 52.574631)
+        (xy 37.281709 52.586291)
+        (xy 37.238572 52.6342)
+        (xy 37.1749 52.704915)
+        (xy 37.16374 52.717309)
+        (xy 37.075589 52.869991)
+        (xy 37.021109 53.037664)
+        (xy 37.00268 53.213)
+        (xy 37.003231 53.218242)
+        (xy 37.016787 53.347212)
+        (xy 37.021109 53.388336)
+        (xy 37.075589 53.556009)
+        (xy 37.16374 53.708691)
+        (xy 37.167271 53.712612)
+        (xy 37.167272 53.712614)
+        (xy 37.17203 53.717898)
+        (xy 37.281709 53.839709)
+        (xy 37.285975 53.842809)
+        (xy 37.285979 53.842812)
+        (xy 37.286673 53.843316)
+        (xy 37.286927 53.843665)
+        (xy 37.289894 53.846337)
+        (xy 37.289326 53.846968)
+        (xy 37.323216 53.893617)
+        (xy 37.323213 53.955792)
+        (xy 37.286665 54.00609)
+        (xy 37.227538 54.0253)
+        (xy 35.924462 54.0253)
+        (xy 35.865331 54.006087)
+        (xy 35.828786 53.955787)
+        (xy 35.828786 53.893613)
+        (xy 35.862674 53.846968)
+        (xy 35.862106 53.846337)
+        (xy 35.865073 53.843665)
+        (xy 35.865327 53.843316)
+        (xy 35.866021 53.842812)
+        (xy 35.866025 53.842809)
+        (xy 35.870291 53.839709)
+        (xy 35.97997 53.717898)
+        (xy 35.984728 53.712614)
+        (xy 35.984729 53.712612)
+        (xy 35.98826 53.708691)
+        (xy 36.076411 53.556009)
+        (xy 36.130891 53.388336)
+        (xy 36.135214 53.347212)
+        (xy 36.148769 53.218242)
+        (xy 36.14932 53.213)
+        (xy 36.130891 53.037664)
+        (xy 36.129262 53.03265)
+        (xy 36.090246 52.91257)
+        (xy 36.090246 52.850396)
+        (xy 36.126791 52.800096)
+        (xy 36.141585 52.79118)
+        (xy 36.18628 52.769236)
+        (xy 36.186281 52.769235)
+        (xy 36.193744 52.765571)
+        (xy 36.276934 52.682235)
+        (xy 36.328646 52.576445)
+        (xy 36.338169 52.511167)
+        (xy 36.338174 52.511136)
+        (xy 36.338174 52.511129)
+        (xy 36.3387 52.507527)
+        (xy 36.338699 52.140474)
+        (xy 36.328467 52.070955)
+        (xy 36.276571 51.965256)
+        (xy 36.269901 51.958597)
+        (xy 36.21838 51.907167)
+        (xy 36.193235 51.882066)
+        (xy 36.087445 51.830354)
+        (xy 36.060779 51.826464)
+        (xy 36.022136 51.820826)
+        (xy 36.022129 51.820826)
+        (xy 36.018527 51.8203)
+        (xy 35.249692 51.8203)
+        (xy 34.473474 51.820301)
+        (xy 34.403955 51.830533)
+        (xy 34.356159 51.854)
+        (xy 34.30572 51.878764)
+        (xy 34.305719 51.878765)
+        (xy 34.298256 51.882429)
+        (xy 34.215066 51.965765)
+        (xy 34.163354 52.071555)
+        (xy 34.162227 52.079282)
+        (xy 34.153831 52.136835)
+        (xy 34.1533 52.140473)
+        (xy 34.153301 52.507526)
+        (xy 34.153837 52.511165)
+        (xy 34.153837 52.511167)
+        (xy 34.163177 52.574631)
+        (xy 34.152779 52.63593)
+        (xy 34.108336 52.679409)
+        (xy 34.046824 52.688462)
+        (xy 33.98784 52.65541)
+        (xy 33.909979 52.566155)
+        (xy 33.901025 52.558093)
+        (xy 33.771701 52.467203)
+        (xy 33.761086 52.461511)
+        (xy 33.613819 52.404095)
+        (xy 33.602144 52.401098)
+        (xy 33.481615 52.385229)
+        (xy 33.475065 52.3848)
+        (xy 33.024933 52.3848)
+        (xy 33.012043 52.388988)
+        (xy 33.009 52.393177)
+        (xy 33.009 52.945067)
+        (xy 33.013188 52.957957)
+        (xy 33.017377 52.961)
+        (xy 34.108794 52.961)
+        (xy 34.121104 52.957)
+        (xy 34.121479 52.94747)
+        (xy 34.097356 52.846989)
+        (xy 34.091041 52.830008)
+        (xy 34.093862 52.828959)
+        (xy 34.085802 52.779424)
+        (xy 34.113795 52.723908)
+        (xy 34.169073 52.695448)
+        (xy 34.230522 52.704915)
+        (xy 34.256301 52.723544)
+        (xy 34.269531 52.736752)
+        (xy 34.292882 52.760062)
+        (xy 34.292884 52.760064)
+        (xy 34.298765 52.765934)
+        (xy 34.404555 52.817646)
+        (xy 34.427893 52.821051)
+        (xy 34.483629 52.848596)
+        (xy 34.512531 52.903644)
+        (xy 34.509046 52.951682)
+        (xy 34.481109 53.037664)
+        (xy 34.46268 53.213)
+        (xy 34.463231 53.218242)
+        (xy 34.476787 53.347212)
+        (xy 34.481109 53.388336)
+        (xy 34.535589 53.556009)
+        (xy 34.62374 53.708691)
+        (xy 34.627271 53.712612)
+        (xy 34.627272 53.712614)
+        (xy 34.63203 53.717898)
+        (xy 34.741709 53.839709)
+        (xy 34.745975 53.842809)
+        (xy 34.745979 53.842812)
+        (xy 34.746673 53.843316)
+        (xy 34.746927 53.843665)
+        (xy 34.749894 53.846337)
+        (xy 34.749326 53.846968)
+        (xy 34.783216 53.893617)
+        (xy 34.783213 53.955792)
+        (xy 34.746665 54.00609)
+        (xy 34.687538 54.0253)
+        (xy 27.2283 54.0253)
+        (xy 27.169169 54.006087)
+        (xy 27.132624 53.955787)
+        (xy 27.1277 53.9247)
+        (xy 27.1277 53.22853)
+        (xy 27.462521 53.22853)
+        (xy 27.486644 53.329011)
+        (xy 27.490846 53.34031)
+        (xy 27.563345 53.480774)
+        (xy 27.570108 53.490726)
+        (xy 27.674024 53.609848)
+        (xy 27.682975 53.617907)
+        (xy 27.812299 53.708797)
+        (xy 27.822914 53.714489)
+        (xy 27.970181 53.771905)
+        (xy 27.981856 53.774902)
+        (xy 28.102385 53.790771)
+        (xy 28.108935 53.7912)
+        (xy 28.559067 53.7912)
+        (xy 28.571957 53.787012)
+        (xy 28.575 53.782823)
+        (xy 28.575 53.775267)
+        (xy 28.829 53.775267)
+        (xy 28.833188 53.788157)
+        (xy 28.837377 53.7912)
+        (xy 29.291659 53.7912)
+        (xy 29.297687 53.790836)
+        (xy 29.414947 53.776647)
+        (xy 29.426639 53.773775)
+        (xy 29.574515 53.717898)
+        (xy 29.585177 53.712324)
+        (xy 29.715454 53.622785)
+        (xy 29.724483 53.614825)
+        (xy 29.829638 53.496803)
+        (xy 29.836511 53.486914)
+        (xy 29.910479 53.347212)
+        (xy 29.914793 53.335974)
+        (xy 29.941297 53.230454)
+        (xy 29.941166 53.22853)
+        (xy 31.642521 53.22853)
+        (xy 31.666644 53.329011)
+        (xy 31.670846 53.34031)
+        (xy 31.743345 53.480774)
+        (xy 31.750108 53.490726)
+        (xy 31.854024 53.609848)
+        (xy 31.862975 53.617907)
+        (xy 31.992299 53.708797)
+        (xy 32.002914 53.714489)
+        (xy 32.150181 53.771905)
+        (xy 32.161856 53.774902)
+        (xy 32.282385 53.790771)
+        (xy 32.288935 53.7912)
+        (xy 32.739067 53.7912)
+        (xy 32.751957 53.787012)
+        (xy 32.755 53.782823)
+        (xy 32.755 53.775267)
+        (xy 33.009 53.775267)
+        (xy 33.013188 53.788157)
+        (xy 33.017377 53.7912)
+        (xy 33.471659 53.7912)
+        (xy 33.477687 53.790836)
+        (xy 33.594947 53.776647)
+        (xy 33.606639 53.773775)
+        (xy 33.754515 53.717898)
+        (xy 33.765177 53.712324)
+        (xy 33.895454 53.622785)
+        (xy 33.904483 53.614825)
+        (xy 34.009638 53.496803)
+        (xy 34.016511 53.486914)
+        (xy 34.090479 53.347212)
+        (xy 34.094793 53.335974)
+        (xy 34.121297 53.230454)
+        (xy 34.120429 53.217714)
+        (xy 34.110996 53.215)
+        (xy 33.024933 53.215)
+        (xy 33.012043 53.219188)
+        (xy 33.009 53.223377)
+        (xy 33.009 53.775267)
+        (xy 32.755 53.775267)
+        (xy 32.755 53.230933)
+        (xy 32.750812 53.218043)
+        (xy 32.746623 53.215)
+        (xy 31.655206 53.215)
+        (xy 31.642896 53.219)
+        (xy 31.642521 53.22853)
+        (xy 29.941166 53.22853)
+        (xy 29.940429 53.217714)
+        (xy 29.930996 53.215)
+        (xy 28.844933 53.215)
+        (xy 28.832043 53.219188)
+        (xy 28.829 53.223377)
+        (xy 28.829 53.775267)
+        (xy 28.575 53.775267)
+        (xy 28.575 53.230933)
+        (xy 28.570812 53.218043)
+        (xy 28.566623 53.215)
+        (xy 27.475206 53.215)
+        (xy 27.462896 53.219)
+        (xy 27.462521 53.22853)
+        (xy 27.1277 53.22853)
+        (xy 27.1277 52.945546)
+        (xy 27.462703 52.945546)
+        (xy 27.463571 52.958286)
+        (xy 27.473004 52.961)
+        (xy 28.559067 52.961)
+        (xy 28.571957 52.956812)
+        (xy 28.575 52.952623)
+        (xy 28.575 52.945067)
+        (xy 28.829 52.945067)
+        (xy 28.833188 52.957957)
+        (xy 28.837377 52.961)
+        (xy 29.928794 52.961)
+        (xy 29.941104 52.957)
+        (xy 29.941479 52.94747)
+        (xy 29.941017 52.945546)
+        (xy 31.642703 52.945546)
+        (xy 31.643571 52.958286)
+        (xy 31.653004 52.961)
+        (xy 32.739067 52.961)
+        (xy 32.751957 52.956812)
+        (xy 32.755 52.952623)
+        (xy 32.755 52.400733)
+        (xy 32.750812 52.387843)
+        (xy 32.746623 52.3848)
+        (xy 32.561516 52.3848)
+        (xy 32.502385 52.365587)
+        (xy 32.46584 52.315287)
+        (xy 32.46584 52.253113)
+        (xy 32.502385 52.202813)
+        (xy 32.529995 52.189466)
+        (xy 32.530374 52.189414)
+        (xy 32.667816 52.129938)
+        (xy 32.7842 52.035691)
+        (xy 32.870953 51.913618)
+        (xy 32.880269 51.887744)
+        (xy 32.896317 51.843166)
+        (xy 32.921682 51.772713)
+        (xy 32.93265 51.623356)
+        (xy 32.921234 51.56674)
+        (xy 32.904405 51.483275)
+        (xy 32.904405 51.483274)
+        (xy 32.903049 51.476551)
+        (xy 32.83506 51.343115)
+        (xy 32.771983 51.274519)
+        (xy 32.738336 51.237928)
+        (xy 32.738335 51.237927)
+        (xy 32.733692 51.232878)
+        (xy 32.606412 51.153961)
+        (xy 32.599829 51.152049)
+        (xy 32.599828 51.152048)
+        (xy 32.565675 51.142126)
+        (xy 32.4626 51.11218)
+        (xy 32.457347 51.111794)
+        (xy 32.457346 51.111794)
+        (xy 32.456133 51.111705)
+        (xy 32.451979 51.1114)
+        (xy 32.344485 51.1114)
+        (xy 32.341093 51.111865)
+        (xy 32.341088 51.111865)
+        (xy 32.240421 51.125655)
+        (xy 32.24042 51.125655)
+        (xy 32.233626 51.126586)
+        (xy 32.096184 51.186062)
+        (xy 31.9798 51.280309)
+        (xy 31.893047 51.402382)
+        (xy 31.890726 51.40883)
+        (xy 31.890724 51.408833)
+        (xy 31.87517 51.452036)
+        (xy 31.842318 51.543287)
+        (xy 31.833799 51.659305)
+        (xy 31.833305 51.666027)
+        (xy 31.820817 51.696629)
+        (xy 31.823186 51.69835)
+        (xy 31.840414 51.737597)
+        (xy 31.84918 51.781069)
+        (xy 31.860951 51.839449)
+        (xy 31.864065 51.84556)
+        (xy 31.864065 51.845561)
+        (xy 31.885658 51.887939)
+        (xy 31.92894 51.972885)
+        (xy 31.933583 51.977934)
+        (xy 32.019672 52.071555)
+        (xy 32.030308 52.083122)
+        (xy 32.157588 52.162039)
+        (xy 32.164171 52.163951)
+        (xy 32.164172 52.163952)
+        (xy 32.26489 52.193213)
+        (xy 32.316314 52.22816)
+        (xy 32.337374 52.286659)
+        (xy 32.320028 52.346365)
+        (xy 32.270901 52.384472)
+        (xy 32.248909 52.38969)
+        (xy 32.169053 52.399353)
+        (xy 32.157361 52.402225)
+        (xy 32.009485 52.458102)
+        (xy 31.998823 52.463676)
+        (xy 31.868546 52.553215)
+        (xy 31.859517 52.561175)
+        (xy 31.754362 52.679197)
+        (xy 31.747489 52.689086)
+        (xy 31.673521 52.828788)
+        (xy 31.669207 52.840026)
+        (xy 31.642703 52.945546)
+        (xy 29.941017 52.945546)
+        (xy 29.917356 52.846989)
+        (xy 29.913154 52.83569)
+        (xy 29.840655 52.695226)
+        (xy 29.833892 52.685274)
+        (xy 29.729976 52.566152)
+        (xy 29.721025 52.558093)
+        (xy 29.591701 52.467203)
+        (xy 29.581086 52.461511)
+        (xy 29.433819 52.404095)
+        (xy 29.422144 52.401098)
+        (xy 29.301615 52.385229)
+        (xy 29.295065 52.3848)
+        (xy 28.844933 52.3848)
+        (xy 28.832043 52.388988)
+        (xy 28.829 52.393177)
+        (xy 28.829 52.945067)
+        (xy 28.575 52.945067)
+        (xy 28.575 52.400733)
+        (xy 28.570812 52.387843)
+        (xy 28.566623 52.3848)
+        (xy 28.112341 52.3848)
+        (xy 28.106313 52.385164)
+        (xy 27.989053 52.399353)
+        (xy 27.977361 52.402225)
+        (xy 27.829485 52.458102)
+        (xy 27.818823 52.463676)
+        (xy 27.688546 52.553215)
+        (xy 27.679517 52.561175)
+        (xy 27.574362 52.679197)
+        (xy 27.567489 52.689086)
+        (xy 27.493521 52.828788)
+        (xy 27.489207 52.840026)
+        (xy 27.462703 52.945546)
+        (xy 27.1277 52.945546)
+        (xy 27.1277 52.235752)
+        (xy 30.334801 52.235752)
+        (xy 30.335418 52.243601)
+        (xy 30.349442 52.33215)
+        (xy 30.354277 52.347029)
+        (xy 30.408665 52.453771)
+        (xy 30.417859 52.466426)
+        (xy 30.502574 52.551141)
+        (xy 30.515229 52.560335)
+        (xy 30.621974 52.614724)
+        (xy 30.63685 52.619558)
+        (xy 30.725384 52.63358)
+        (xy 30.733256 52.6342)
+        (xy 30.845067 52.6342)
+        (xy 30.857957 52.630012)
+        (xy 30.861 52.625823)
+        (xy 30.861 52.618266)
+        (xy 31.115 52.618266)
+        (xy 31.119188 52.631156)
+        (xy 31.123377 52.634199)
+        (xy 31.242752 52.634199)
+        (xy 31.250601 52.633582)
+        (xy 31.33915 52.619558)
+        (xy 31.354029 52.614723)
+        (xy 31.460771 52.560335)
+        (xy 31.473426 52.551141)
+        (xy 31.558141 52.466426)
+        (xy 31.567335 52.453771)
+        (xy 31.621724 52.347026)
+        (xy 31.626558 52.33215)
+        (xy 31.64058 52.243616)
+        (xy 31.6412 52.235744)
+        (xy 31.6412 52.123933)
+        (xy 31.637012 52.111043)
+        (xy 31.632823 52.108)
+        (xy 31.130933 52.108)
+        (xy 31.118043 52.112188)
+        (xy 31.115 52.116377)
+        (xy 31.115 52.618266)
+        (xy 30.861 52.618266)
+        (xy 30.861 52.123933)
+        (xy 30.856812 52.111043)
+        (xy 30.852623 52.108)
+        (xy 30.350734 52.108)
+        (xy 30.337844 52.112188)
+        (xy 30.334801 52.116377)
+        (xy 30.334801 52.235752)
+        (xy 27.1277 52.235752)
+        (xy 27.1277 51.958597)
+        (xy 27.146913 51.899466)
+        (xy 27.197213 51.862921)
+        (xy 27.259387 51.862921)
+        (xy 27.28743 51.877209)
+        (xy 27.289276 51.87855)
+        (xy 27.294875 51.884149)
+        (xy 27.323978 51.898977)
+        (xy 27.408816 51.942205)
+        (xy 27.40882 51.942206)
+        (xy 27.415873 51.9458)
+        (xy 27.423694 51.947039)
+        (xy 27.423695 51.947039)
+        (xy 27.512349 51.961081)
+        (xy 27.512355 51.961081)
+        (xy 27.51626 51.9617)
+        (xy 28.03374 51.9617)
+        (xy 28.037645 51.961081)
+        (xy 28.037651 51.961081)
+        (xy 28.126305 51.947039)
+        (xy 28.126306 51.947039)
+        (xy 28.134127 51.9458)
+        (xy 28.14118 51.942206)
+        (xy 28.141184 51.942205)
+        (xy 28.226022 51.898977)
+        (xy 28.255125 51.884149)
+        (xy 28.351149 51.788125)
+        (xy 28.382673 51.726256)
+        (xy 28.409205 51.674184)
+        (xy 28.409206 51.67418)
+        (xy 28.4128 51.667127)
+        (xy 28.414039 51.659305)
+        (xy 28.428081 51.570651)
+        (xy 28.428081 51.570645)
+        (xy 28.4287 51.56674)
+        (xy 28.4287 51.562752)
+        (xy 28.721801 51.562752)
+        (xy 28.722418 51.570601)
+        (xy 28.736442 51.65915)
+        (xy 28.741277 51.674029)
+        (xy 28.795665 51.780771)
+        (xy 28.804859 51.793426)
+        (xy 28.889574 51.878141)
+        (xy 28.902229 51.887335)
+        (xy 29.008974 51.941724)
+        (xy 29.02385 51.946558)
+        (xy 29.112384 51.96058)
+        (xy 29.120256 51.9612)
+        (xy 29.232067 51.9612)
+        (xy 29.244957 51.957012)
+        (xy 29.248 51.952823)
+        (xy 29.248 51.945266)
+        (xy 29.502 51.945266)
+        (xy 29.506188 51.958156)
+        (xy 29.510377 51.961199)
+        (xy 29.629752 51.961199)
+        (xy 29.637601 51.960582)
+        (xy 29.72615 51.946558)
+        (xy 29.741029 51.941723)
+        (xy 29.847771 51.887335)
+        (xy 29.860426 51.878141)
+        (xy 29.9005 51.838067)
+        (xy 30.3348 51.838067)
+        (xy 30.338988 51.850957)
+        (xy 30.343177 51.854)
+        (xy 30.845067 51.854)
+        (xy 30.857957 51.849812)
+        (xy 30.861 51.845623)
+        (xy 30.861 51.838067)
+        (xy 31.115 51.838067)
+        (xy 31.119188 51.850957)
+        (xy 31.123377 51.854)
+        (xy 31.625266 51.854)
+        (xy 31.638156 51.849812)
+        (xy 31.641199 51.845623)
+        (xy 31.641199 51.757481)
+        (xy 31.654229 51.717379)
+        (xy 31.647476 51.711672)
+        (xy 31.633614 51.674397)
+        (xy 31.626559 51.629856)
+        (xy 31.621723 51.614971)
+        (xy 31.567335 51.508229)
+        (xy 31.558141 51.495574)
+        (xy 31.473426 51.410859)
+        (xy 31.460771 51.401665)
+        (xy 31.354026 51.347276)
+        (xy 31.33915 51.342442)
+        (xy 31.250616 51.32842)
+        (xy 31.242744 51.3278)
+        (xy 31.130933 51.3278)
+        (xy 31.118043 51.331988)
+        (xy 31.115 51.336177)
+        (xy 31.115 51.838067)
+        (xy 30.861 51.838067)
+        (xy 30.861 51.343734)
+        (xy 30.856812 51.330844)
+        (xy 30.852623 51.327801)
+        (xy 30.733248 51.327801)
+        (xy 30.725399 51.328418)
+        (xy 30.63685 51.342442)
+        (xy 30.621971 51.347277)
+        (xy 30.515229 51.401665)
+        (xy 30.502574 51.410859)
+        (xy 30.417859 51.495574)
+        (xy 30.408665 51.508229)
+        (xy 30.354276 51.614974)
+        (xy 30.349442 51.62985)
+        (xy 30.33542 51.718384)
+        (xy 30.3348 51.726256)
+        (xy 30.3348 51.838067)
+        (xy 29.9005 51.838067)
+        (xy 29.945141 51.793426)
+        (xy 29.954335 51.780771)
+        (xy 30.008724 51.674026)
+        (xy 30.013558 51.65915)
+        (xy 30.02758 51.570616)
+        (xy 30.0282 51.562744)
+        (xy 30.0282 51.450933)
+        (xy 30.024012 51.438043)
+        (xy 30.019823 51.435)
+        (xy 29.517933 51.435)
+        (xy 29.505043 51.439188)
+        (xy 29.502 51.443377)
+        (xy 29.502 51.945266)
+        (xy 29.248 51.945266)
+        (xy 29.248 51.450933)
+        (xy 29.243812 51.438043)
+        (xy 29.239623 51.435)
+        (xy 28.737734 51.435)
+        (xy 28.724844 51.439188)
+        (xy 28.721801 51.443377)
+        (xy 28.721801 51.562752)
+        (xy 28.4287 51.562752)
+        (xy 28.4287 51.04926)
+        (xy 28.414064 50.95685)
+        (xy 28.414039 50.956695)
+        (xy 28.414039 50.956694)
+        (xy 28.4128 50.948873)
+        (xy 28.409206 50.94182)
+        (xy 28.409205 50.941816)
+        (xy 28.354744 50.834931)
+        (xy 28.351149 50.827875)
+        (xy 28.341708 50.818434)
+        (xy 28.313483 50.763037)
+        (xy 28.323209 50.701629)
+        (xy 28.367173 50.657665)
+        (xy 28.412844 50.6467)
+        (xy 28.578095 50.646699)
+        (xy 28.737864 50.646699)
+        (xy 28.796995 50.665912)
+        (xy 28.83354 50.716212)
+        (xy 28.83354 50.778386)
+        (xy 28.808999 50.818434)
+        (xy 28.804859 50.822574)
+        (xy 28.795665 50.835229)
+        (xy 28.741276 50.941974)
+        (xy 28.736442 50.95685)
+        (xy 28.72242 51.045384)
+        (xy 28.7218 51.053256)
+        (xy 28.7218 51.165067)
+        (xy 28.725988 51.177957)
+        (xy 28.730177 51.181)
+        (xy 29.232067 51.181)
+        (xy 29.244957 51.176812)
+        (xy 29.248 51.172623)
+        (xy 29.248 51.165067)
+        (xy 29.502 51.165067)
+        (xy 29.506188 51.177957)
+        (xy 29.510377 51.181)
+        (xy 30.012266 51.181)
+        (xy 30.025156 51.176812)
+        (xy 30.028199 51.172623)
+        (xy 30.028199 51.053248)
+        (xy 30.027582 51.045399)
+        (xy 30.013558 50.95685)
+        (xy 30.008723 50.941971)
+        (xy 29.954335 50.835229)
+        (xy 29.945141 50.822574)
+        (xy 29.860426 50.737859)
+        (xy 29.847771 50.728665)
+        (xy 29.741026 50.674276)
+        (xy 29.72615 50.669442)
+        (xy 29.637616 50.65542)
+        (xy 29.629744 50.6548)
+        (xy 29.517933 50.6548)
+        (xy 29.505043 50.658988)
+        (xy 29.502 50.663177)
+        (xy 29.502 51.165067)
+        (xy 29.248 51.165067)
+        (xy 29.248 50.670734)
+        (xy 29.243812 50.657844)
+        (xy 29.239623 50.654801)
+        (xy 29.120248 50.654801)
+        (xy 29.108452 50.655729)
+        (xy 29.108291 50.65368)
+        (xy 29.054419 50.645134)
+        (xy 29.010466 50.601159)
+        (xy 29.000755 50.539748)
+        (xy 29.016225 50.501945)
+        (xy 29.016934 50.501235)
+        (xy 29.068646 50.395445)
+        (xy 29.0787 50.326527)
+        (xy 29.0787 50.15687)
+        (xy 29.097913 50.097739)
+        (xy 29.148213 50.061194)
+        (xy 29.210387 50.061194)
+        (xy 29.240541 50.077059)
+        (xy 29.315341 50.134455)
+        (xy 29.448309 50.189531)
+        (xy 29.454845 50.190392)
+        (xy 29.454847 50.190392)
+        (xy 29.58446 50.207456)
+        (xy 29.591 50.208317)
+        (xy 29.59754 50.207456)
+        (xy 29.727153 50.190392)
+        (xy 29.727155 50.190392)
+        (xy 29.733691 50.189531)
+        (xy 29.866659 50.134455)
+        (xy 29.907731 50.102939)
+        (xy 29.975608 50.050855)
+        (xy 29.975609 50.050854)
+        (xy 29.98084 50.04684)
+        (xy 30.068455 49.932658)
+        (xy 30.123531 49.799691)
+        (xy 30.128818 49.759538)
+        (xy 30.141456 49.66354)
+        (xy 30.142317 49.657)
+        (xy 30.125723 49.530955)
+        (xy 30.124392 49.520847)
+        (xy 30.124392 49.520845)
+        (xy 30.123531 49.514309)
+        (xy 30.068455 49.381342)
+        (xy 29.98084 49.26716)
+        (xy 29.963972 49.254216)
+        (xy 29.871889 49.183558)
+        (xy 29.871888 49.183558)
+        (xy 29.866659 49.179545)
+        (xy 29.733691 49.124469)
+        (xy 29.727155 49.123608)
+        (xy 29.727153 49.123608)
+        (xy 29.59754 49.106544)
+        (xy 29.591 49.105683)
+        (xy 29.58446 49.106544)
+        (xy 29.454847 49.123608)
+        (xy 29.454845 49.123608)
+        (xy 29.448309 49.124469)
+        (xy 29.315342 49.179545)
+        (xy 29.240538 49.236944)
+        (xy 29.181933 49.257698)
+        (xy 29.122319 49.240039)
+        (xy 29.084469 49.190713)
+        (xy 29.078699 49.157132)
+        (xy 29.078699 49.084474)
+        (xy 29.068467 49.014955)
+        (xy 29.043444 48.963989)
+        (xy 29.020236 48.91672)
+        (xy 29.020235 48.916719)
+        (xy 29.016571 48.909256)
+        (xy 28.991143 48.883872)
+        (xy 28.939118 48.831939)
+        (xy 28.933235 48.826066)
+        (xy 28.827445 48.774354)
+        (xy 28.800779 48.770464)
+        (xy 28.762136 48.764826)
+        (xy 28.762129 48.764826)
+        (xy 28.758527 48.7643)
+        (xy 28.575903 48.7643)
+        (xy 28.391474 48.764301)
+        (xy 28.321955 48.774533)
+        (xy 28.304698 48.783006)
+        (xy 28.22372 48.822764)
+        (xy 28.223719 48.822765)
+        (xy 28.216256 48.826429)
+        (xy 28.210382 48.832313)
+        (xy 28.210381 48.832314)
+        (xy 28.182072 48.860673)
+        (xy 28.133066 48.909765)
+        (xy 28.129415 48.917234)
+        (xy 28.108915 48.959173)
+        (xy 28.081354 49.015555)
+        (xy 28.080227 49.023282)
+        (xy 28.071831 49.080835)
+        (xy 28.0713 49.084473)
+        (xy 28.0713 49.30718)
+        (xy 28.052087 49.366311)
+        (xy 28.013216 49.398354)
+        (xy 28.012082 49.398883)
+        (xy 28.003584 49.40116)
+        (xy 27.996376 49.406207)
+        (xy 27.996374 49.406208)
+        (xy 27.971242 49.423805)
+        (xy 27.963843 49.428519)
+        (xy 27.937275 49.443859)
+        (xy 27.929651 49.448261)
+        (xy 27.923994 49.455003)
+        (xy 27.904268 49.478511)
+        (xy 27.898339 49.484981)
+        (xy 27.554481 49.828839)
+        (xy 27.548011 49.834768)
+        (xy 27.517761 49.860151)
+        (xy 27.51336 49.867774)
+        (xy 27.513359 49.867775)
+        (xy 27.498019 49.894343)
+        (xy 27.493305 49.901742)
+        (xy 27.475927 49.926562)
+        (xy 27.47066 49.934084)
+        (xy 27.468383 49.942582)
+        (xy 27.465876 49.947957)
+        (xy 27.463847 49.953531)
+        (xy 27.459449 49.961149)
+        (xy 27.457922 49.969811)
+        (xy 27.457921 49.969813)
+        (xy 27.452591 50.000042)
+        (xy 27.450691 50.008608)
+        (xy 27.443298 50.0362)
+        (xy 27.440476 50.046733)
+        (xy 27.441243 50.055501)
+        (xy 27.443917 50.086065)
+        (xy 27.4443 50.094833)
+        (xy 27.4443 50.594068)
+        (xy 27.425087 50.653199)
+        (xy 27.389371 50.683703)
+        (xy 27.352048 50.70272)
+        (xy 27.294875 50.731851)
+        (xy 27.289276 50.73745)
+        (xy 27.28743 50.738791)
+        (xy 27.228298 50.758003)
+        (xy 27.169167 50.738789)
+        (xy 27.132623 50.688488)
+        (xy 27.1277 50.657403)
+        (xy 27.1277 48.802551)
+        (xy 27.146913 48.74342)
+        (xy 27.197213 48.706875)
+        (xy 27.259387 48.706875)
+        (xy 27.272479 48.712171)
+        (xy 27.365685 48.757731)
+        (xy 27.380427 48.762287)
+        (xy 27.437913 48.770674)
+        (xy 27.445166 48.7712)
+        (xy 27.482067 48.7712)
+        (xy 27.494957 48.767012)
+        (xy 27.498 48.762823)
+        (xy 27.498 48.755266)
+        (xy 27.752 48.755266)
+        (xy 27.756188 48.768156)
+        (xy 27.760377 48.771199)
+        (xy 27.804798 48.771199)
+        (xy 27.812116 48.770663)
+        (xy 27.870164 48.76212)
+        (xy 27.884917 48.757535)
+        (xy 27.975985 48.712823)
+        (xy 27.989324 48.703273)
+        (xy 28.06065 48.631823)
+        (xy 28.070173 48.618472)
+        (xy 28.114731 48.527315)
+        (xy 28.119287 48.512573)
+        (xy 28.127674 48.455087)
+        (xy 28.1282 48.447834)
+        (xy 28.1282 47.973433)
+        (xy 28.124012 47.960543)
+        (xy 28.119823 47.9575)
+        (xy 27.767933 47.9575)
+        (xy 27.755043 47.961688)
+        (xy 27.752 47.965877)
+        (xy 27.752 48.755266)
+        (xy 27.498 48.755266)
+        (xy 27.498 47.8041)
+        (xy 27.517213 47.744969)
+        (xy 27.567513 47.708424)
+        (xy 27.5986 47.7035)
+        (xy 28.112266 47.7035)
+        (xy 28.125156 47.699312)
+        (xy 28.128199 47.695123)
+        (xy 28.128199 47.213202)
+        (xy 28.127663 47.205884)
+        (xy 28.11912 47.147836)
+        (xy 28.114535 47.133083)
+        (xy 28.069823 47.042015)
+        (xy 28.060273 47.028676)
+        (xy 27.988823 46.95735)
+        (xy 27.975473 46.947829)
+        (xy 27.970053 46.945179)
+        (xy 27.925367 46.901949)
+        (xy 27.914624 46.84071)
+        (xy 27.941929 46.784853)
+        (xy 27.996851 46.755712)
+        (xy 28.014233 46.754199)
+        (xy 28.029752 46.754199)
+        (xy 28.037601 46.753582)
+        (xy 28.12615 46.739558)
+        (xy 28.141029 46.734723)
+        (xy 28.247771 46.680335)
+        (xy 28.260426 46.671141)
+        (xy 28.345141 46.586426)
+        (xy 28.354335 46.573771)
+        (xy 28.408724 46.467026)
+        (xy 28.413558 46.45215)
+        (xy 28.42758 46.363616)
+        (xy 28.427885 46.35974)
+        (xy 28.7213 46.35974)
+        (xy 28.721919 46.363645)
+        (xy 28.721919 46.363651)
+        (xy 28.735961 46.452305)
+        (xy 28.7372 46.460127)
+        (xy 28.740794 46.46718)
+        (xy 28.740795 46.467184)
+        (xy 28.784023 46.552022)
+        (xy 28.798851 46.581125)
+        (xy 28.894875 46.677149)
+        (xy 28.901931 46.680744)
+        (xy 29.008816 46.735205)
+        (xy 29.00882 46.735206)
+        (xy 29.015873 46.7388)
+        (xy 29.023694 46.740039)
+        (xy 29.023695 46.740039)
+        (xy 29.043324 46.743148)
+        (xy 29.109438 46.753619)
+        (xy 29.164835 46.781845)
+        (xy 29.193061 46.837242)
+        (xy 29.1943 46.85298)
+        (xy 29.1943 46.881717)
+        (xy 29.175087 46.940848)
+        (xy 29.164897 46.952789)
+        (xy 29.088941 47.028879)
+        (xy 29.088939 47.028881)
+        (xy 29.083066 47.034765)
+        (xy 29.031354 47.140555)
+        (xy 29.030227 47.148282)
+        (xy 29.024198 47.18961)
+        (xy 29.0213 47.209473)
+        (xy 29.021301 48.451526)
+        (xy 29.031533 48.521045)
+        (xy 29.037321 48.532833)
+        (xy 29.079368 48.618472)
+        (xy 29.083429 48.626744)
+        (xy 29.166765 48.709934)
+        (xy 29.272555 48.761646)
+        (xy 29.294429 48.764837)
+        (xy 29.337864 48.771174)
+        (xy 29.337871 48.771174)
+        (xy 29.341473 48.7717)
+        (xy 29.524097 48.7717)
+        (xy 29.708526 48.771699)
+        (xy 29.778045 48.761467)
+        (xy 29.829011 48.736444)
+        (xy 29.87628 48.713236)
+        (xy 29.876281 48.713235)
+        (xy 29.883744 48.709571)
+        (xy 29.892165 48.701136)
+        (xy 29.93629 48.656933)
+        (xy 29.966934 48.626235)
+        (xy 30.018646 48.520445)
+        (xy 30.025096 48.476231)
+        (xy 30.028174 48.455136)
+        (xy 30.028174 48.455129)
+        (xy 30.0287 48.451527)
+        (xy 30.028699 47.209474)
+        (xy 30.028163 47.20583)
+        (xy 30.025776 47.18961)
+        (xy 30.036175 47.128312)
+        (xy 30.067603 47.092556)
+        (xy 30.080258 47.083695)
+        (xy 30.087657 47.078981)
+        (xy 30.114225 47.063641)
+        (xy 30.114226 47.06364)
+        (xy 30.121849 47.059239)
+        (xy 30.147232 47.028989)
+        (xy 30.153161 47.022519)
+        (xy 30.173498 47.002182)
+        (xy 30.228896 46.973956)
+        (xy 30.290304 46.983682)
+        (xy 30.334268 47.027646)
+        (xy 30.343994 47.089054)
+        (xy 30.342998 47.095342)
+        (xy 30.3343 47.15026)
+        (xy 30.3343 47.66774)
+        (xy 30.334919 47.671645)
+        (xy 30.334919 47.671651)
+        (xy 30.347075 47.748395)
+        (xy 30.3502 47.768127)
+        (xy 30.353794 47.77518)
+        (xy 30.353795 47.775184)
+        (xy 30.392215 47.850586)
+        (xy 30.411851 47.889125)
+        (xy 30.507875 47.985149)
+        (xy 30.514931 47.988744)
+        (xy 30.621816 48.043205)
+        (xy 30.62182 48.043206)
+        (xy 30.628873 48.0468)
+        (xy 30.636694 48.048039)
+        (xy 30.636695 48.048039)
+        (xy 30.725349 48.062081)
+        (xy 30.725355 48.062081)
+        (xy 30.72926 48.0627)
+        (xy 31.10975 48.0627)
+        (xy 31.168881 48.081913)
+        (xy 31.205426 48.132213)
+        (xy 31.205426 48.194387)
+        (xy 31.180885 48.234435)
+        (xy 31.148481 48.266839)
+        (xy 31.142011 48.272768)
+        (xy 31.111761 48.298151)
+        (xy 31.10736 48.305774)
+        (xy 31.107359 48.305775)
+        (xy 31.092019 48.332343)
+        (xy 31.087305 48.339742)
+        (xy 31.069709 48.364873)
+        (xy 31.06466 48.372084)
+        (xy 31.062383 48.380582)
+        (xy 31.059876 48.385957)
+        (xy 31.057847 48.391531)
+        (xy 31.053449 48.399149)
+        (xy 31.051922 48.407811)
+        (xy 31.051921 48.407813)
+        (xy 31.046591 48.438042)
+        (xy 31.044691 48.446608)
+        (xy 31.043373 48.451527)
+        (xy 31.034476 48.484733)
+        (xy 31.035243 48.493501)
+        (xy 31.037917 48.524065)
+        (xy 31.0383 48.532833)
+        (xy 31.0383 48.91817)
+        (xy 31.019087 48.977301)
+        (xy 30.998943 48.99798)
+        (xy 30.97916 49.01316)
+        (xy 30.891545 49.127342)
+        (xy 30.836469 49.260309)
+        (xy 30.835608 49.266845)
+        (xy 30.835608 49.266847)
+        (xy 30.830396 49.306439)
+        (xy 30.817683 49.403)
+        (xy 30.818544 49.40954)
+        (xy 30.831378 49.507018)
+        (xy 30.836469 49.545691)
+        (xy 30.851513 49.58201)
+        (xy 30.854078 49.588203)
+        (xy 30.858955 49.650186)
+        (xy 30.826469 49.703198)
+        (xy 30.769027 49.72699)
+        (xy 30.761135 49.7273)
+        (xy 30.72926 49.7273)
+        (xy 30.725355 49.727919)
+        (xy 30.725349 49.727919)
+        (xy 30.636695 49.741961)
+        (xy 30.636694 49.741961)
+        (xy 30.628873 49.7432)
+        (xy 30.62182 49.746794)
+        (xy 30.621816 49.746795)
+        (xy 30.536978 49.790023)
+        (xy 30.507875 49.804851)
+        (xy 30.411851 49.900875)
+        (xy 30.397023 49.929978)
+        (xy 30.353795 50.014816)
+        (xy 30.353794 50.01482)
+        (xy 30.3502 50.021873)
+        (xy 30.348961 50.029694)
+        (xy 30.348961 50.029695)
+        (xy 30.337314 50.103233)
+        (xy 30.3343 50.12226)
+        (xy 30.3343 50.63974)
+        (xy 30.334919 50.643645)
+        (xy 30.334919 50.643651)
+        (xy 30.348547 50.729693)
+        (xy 30.3502 50.740127)
+        (xy 30.353794 50.74718)
+        (xy 30.353795 50.747184)
+        (xy 30.391806 50.821784)
+        (xy 30.411851 50.861125)
+        (xy 30.507875 50.957149)
+        (xy 30.514931 50.960744)
+        (xy 30.621816 51.015205)
+        (xy 30.62182 51.015206)
+        (xy 30.628873 51.0188)
+        (xy 30.636694 51.020039)
+        (xy 30.636695 51.020039)
+        (xy 30.725349 51.034081)
+        (xy 30.725355 51.034081)
+        (xy 30.72926 51.0347)
+        (xy 31.24674 51.0347)
+        (xy 31.250645 51.034081)
+        (xy 31.250651 51.034081)
+        (xy 31.339305 51.020039)
+        (xy 31.339306 51.020039)
+        (xy 31.347127 51.0188)
+        (xy 31.35418 51.015206)
+        (xy 31.354184 51.015205)
+        (xy 31.461069 50.960744)
+        (xy 31.468125 50.957149)
+        (xy 31.564149 50.861125)
+        (xy 31.612297 50.766629)
+        (xy 31.65626 50.722665)
+        (xy 31.701932 50.7117)
+        (xy 31.999924 50.7117)
+        (xy 32.061165 50.732489)
+        (xy 32.104107 50.76544)
+        (xy 32.104113 50.765444)
+        (xy 32.109341 50.769455)
+        (xy 32.242309 50.824531)
+        (xy 32.248845 50.825392)
+        (xy 32.248847 50.825392)
+        (xy 32.37846 50.842456)
+        (xy 32.385 50.843317)
+        (xy 32.39154 50.842456)
+        (xy 32.521153 50.825392)
+        (xy 32.521155 50.825392)
+        (xy 32.527691 50.824531)
+        (xy 32.660659 50.769455)
+        (xy 32.665889 50.765442)
+        (xy 32.769608 50.685855)
+        (xy 32.769609 50.685854)
+        (xy 32.77484 50.68184)
+        (xy 32.862455 50.567658)
+        (xy 32.917531 50.434691)
+        (xy 32.924116 50.384674)
+        (xy 32.950883 50.328556)
+        (xy 33.005522 50.29889)
+        (xy 33.067165 50.307005)
+        (xy 33.09499 50.32667)
+        (xy 34.042839 51.274519)
+        (xy 34.048768 51.280989)
+        (xy 34.074151 51.311239)
+        (xy 34.081774 51.31564)
+        (xy 34.081775 51.315641)
+        (xy 34.108343 51.330981)
+        (xy 34.115742 51.335695)
+        (xy 34.132284 51.347277)
+        (xy 34.148084 51.35834)
+        (xy 34.156583 51.360618)
+        (xy 34.164561 51.364338)
+        (xy 34.164323 51.364847)
+        (xy 34.173796 51.368771)
+        (xy 34.175122 51.369536)
+        (xy 34.173159 51.372939)
+        (xy 34.206339 51.398938)
+        (xy 34.206924 51.398519)
+        (xy 34.208356 51.400519)
+        (xy 34.208425 51.400573)
+        (xy 34.208553 51.400794)
+        (xy 34.211764 51.405279)
+        (xy 34.215429 51.412744)
+        (xy 34.221313 51.418618)
+        (xy 34.221314 51.418619)
+        (xy 34.237724 51.435)
+        (xy 34.298765 51.495934)
+        (xy 34.306234 51.499585)
+        (xy 34.395638 51.543287)
+        (xy 34.404555 51.547646)
+        (xy 34.431221 51.551536)
+        (xy 34.469864 51.557174)
+        (xy 34.469871 51.557174)
+        (xy 34.473473 51.5577)
+        (xy 35.242308 51.5577)
+        (xy 36.018526 51.557699)
+        (xy 36.088045 51.547467)
+        (xy 36.167963 51.508229)
+        (xy 36.18628 51.499236)
+        (xy 36.186281 51.499235)
+        (xy 36.193744 51.495571)
+        (xy 36.206019 51.483275)
+        (xy 36.238304 51.450933)
+        (xy 36.276934 51.412235)
+        (xy 36.308687 51.347276)
+        (xy 36.325217 51.31346)
+        (xy 36.328646 51.306445)
+        (xy 36.333088 51.275997)
+        (xy 36.338174 51.241136)
+        (xy 36.338174 51.241129)
+        (xy 36.3387 51.237527)
+        (xy 36.338699 50.870474)
+        (xy 36.328467 50.800955)
+        (xy 36.294761 50.732305)
+        (xy 36.280236 50.70272)
+        (xy 36.280235 50.702719)
+        (xy 36.276571 50.695256)
+        (xy 36.263132 50.68184)
+        (xy 36.224875 50.643651)
+        (xy 36.193235 50.612066)
+        (xy 36.170922 50.601159)
+        (xy 36.09446 50.563783)
+        (xy 36.087445 50.560354)
+        (xy 36.060779 50.556464)
+        (xy 36.022136 50.550826)
+        (xy 36.022129 50.550826)
+        (xy 36.018527 50.5503)
+        (xy 35.249692 50.5503)
+        (xy 34.473474 50.550301)
+        (xy 34.403955 50.560533)
+        (xy 34.396935 50.56398)
+        (xy 34.396934 50.56398)
+        (xy 34.37482 50.574837)
+        (xy 34.313274 50.583651)
+        (xy 34.259349 50.555669)
+        (xy 32.692891 48.989211)
+        (xy 32.664665 48.933813)
+        (xy 32.664287 48.904948)
+        (xy 32.670116 48.860673)
+        (xy 32.696883 48.804556)
+        (xy 32.751523 48.774889)
+        (xy 32.813166 48.783006)
+        (xy 32.84099 48.80267)
+        (xy 34.042839 50.004519)
+        (xy 34.048768 50.010989)
+        (xy 34.074151 50.041239)
+        (xy 34.081774 50.04564)
+        (xy 34.081775 50.045641)
+        (xy 34.108343 50.060981)
+        (xy 34.115742 50.065695)
+        (xy 34.138044 50.08131)
+        (xy 34.148084 50.08834)
+        (xy 34.156583 50.090618)
+        (xy 34.164561 50.094338)
+        (xy 34.164323 50.094847)
+        (xy 34.173796 50.098771)
+        (xy 34.175122 50.099536)
+        (xy 34.173159 50.102939)
+        (xy 34.206339 50.128938)
+        (xy 34.206924 50.128519)
+        (xy 34.208356 50.130519)
+        (xy 34.208425 50.130573)
+        (xy 34.208553 50.130794)
+        (xy 34.211764 50.135279)
+        (xy 34.215429 50.142744)
+        (xy 34.221313 50.148618)
+        (xy 34.221314 50.148619)
+        (xy 34.25479 50.182036)
+        (xy 34.298765 50.225934)
+        (xy 34.404555 50.277646)
+        (xy 34.431221 50.281536)
+        (xy 34.469864 50.287174)
+        (xy 34.469871 50.287174)
+        (xy 34.473473 50.2877)
+        (xy 35.242308 50.2877)
+        (xy 36.018526 50.287699)
+        (xy 36.088045 50.277467)
+        (xy 36.139011 50.252444)
+        (xy 36.18628 50.229236)
+        (xy 36.186281 50.229235)
+        (xy 36.193744 50.225571)
+        (xy 36.219707 50.199563)
+        (xy 36.255608 50.163598)
+        (xy 36.276934 50.142235)
+        (xy 36.328646 50.036445)
+        (xy 36.33285 50.007627)
+        (xy 36.338174 49.971136)
+        (xy 36.338174 49.971129)
+        (xy 36.3387 49.967527)
+        (xy 36.338699 49.600474)
+        (xy 36.328467 49.530955)
+        (xy 36.290152 49.452917)
+        (xy 36.280236 49.43272)
+        (xy 36.280235 49.432719)
+        (xy 36.276571 49.425256)
+        (xy 36.260828 49.40954)
+        (xy 36.226026 49.3748)
+        (xy 36.193235 49.342066)
+        (xy 36.181951 49.33655)
+        (xy 36.09446 49.293783)
+        (xy 36.087445 49.290354)
+        (xy 36.060779 49.286464)
+        (xy 36.022136 49.280826)
+        (xy 36.022129 49.280826)
+        (xy 36.018527 49.2803)
+        (xy 35.249692 49.2803)
+        (xy 34.473474 49.280301)
+        (xy 34.403955 49.290533)
+        (xy 34.396935 49.29398)
+        (xy 34.396934 49.29398)
+        (xy 34.37482 49.304837)
+        (xy 34.313274 49.313651)
+        (xy 34.259349 49.285669)
+        (xy 33.667478 48.693798)
+        (xy 34.153801 48.693798)
+        (xy 34.154337 48.701116)
+        (xy 34.16288 48.759164)
+        (xy 34.167465 48.773917)
+        (xy 34.212177 48.864985)
+        (xy 34.221727 48.878324)
+        (xy 34.293177 48.94965)
+        (xy 34.306528 48.959173)
+        (xy 34.397685 49.003731)
+        (xy 34.412427 49.008287)
+        (xy 34.469913 49.016674)
+        (xy 34.477166 49.0172)
+        (xy 35.103067 49.0172)
+        (xy 35.115957 49.013012)
+        (xy 35.119 49.008823)
+        (xy 35.119 49.001266)
+        (xy 35.373 49.001266)
+        (xy 35.377188 49.014156)
+        (xy 35.381377 49.017199)
+        (xy 36.014798 49.017199)
+        (xy 36.022116 49.016663)
+        (xy 36.080164 49.00812)
+        (xy 36.094917 49.003535)
+        (xy 36.185985 48.958823)
+        (xy 36.199324 48.949273)
+        (xy 36.27065 48.877823)
+        (xy 36.280173 48.864472)
+        (xy 36.324731 48.773315)
+        (xy 36.329287 48.758573)
+        (xy 36.337674 48.701087)
+        (xy 36.3382 48.693834)
+        (xy 36.3382 48.656933)
+        (xy 36.334012 48.644043)
+        (xy 36.329823 48.641)
+        (xy 35.388933 48.641)
+        (xy 35.376043 48.645188)
+        (xy 35.373 48.649377)
+        (xy 35.373 49.001266)
+        (xy 35.119 49.001266)
+        (xy 35.119 48.656933)
+        (xy 35.114812 48.644043)
+        (xy 35.110623 48.641)
+        (xy 34.169734 48.641)
+        (xy 34.156844 48.645188)
+        (xy 34.153801 48.649377)
+        (xy 34.153801 48.693798)
+        (xy 33.667478 48.693798)
+        (xy 33.344747 48.371067)
+        (xy 34.1538 48.371067)
+        (xy 34.157988 48.383957)
+        (xy 34.162177 48.387)
+        (xy 35.103067 48.387)
+        (xy 35.115957 48.382812)
+        (xy 35.119 48.378623)
+        (xy 35.119 48.371067)
+        (xy 35.373 48.371067)
+        (xy 35.377188 48.383957)
+        (xy 35.381377 48.387)
+        (xy 36.322266 48.387)
+        (xy 36.335156 48.382812)
+        (xy 36.338199 48.378623)
+        (xy 36.338199 48.334202)
+        (xy 36.337663 48.326884)
+        (xy 36.32912 48.268836)
+        (xy 36.324535 48.254083)
+        (xy 36.279823 48.163015)
+        (xy 36.270273 48.149676)
+        (xy 36.198823 48.07835)
+        (xy 36.185472 48.068827)
+        (xy 36.094315 48.024269)
+        (xy 36.079573 48.019713)
+        (xy 36.022087 48.011326)
+        (xy 36.014834 48.0108)
+        (xy 35.388933 48.0108)
+        (xy 35.376043 48.014988)
+        (xy 35.373 48.019177)
+        (xy 35.373 48.371067)
+        (xy 35.119 48.371067)
+        (xy 35.119 48.026734)
+        (xy 35.114812 48.013844)
+        (xy 35.110623 48.010801)
+        (xy 34.477202 48.010801)
+        (xy 34.469884 48.011337)
+        (xy 34.411836 48.01988)
+        (xy 34.397083 48.024465)
+        (xy 34.306015 48.069177)
+        (xy 34.292676 48.078727)
+        (xy 34.22135 48.150177)
+        (xy 34.211827 48.163528)
+        (xy 34.167269 48.254685)
+        (xy 34.162713 48.269427)
+        (xy 34.154326 48.326913)
+        (xy 34.1538 48.334166)
+        (xy 34.1538 48.371067)
+        (xy 33.344747 48.371067)
+        (xy 32.86125 47.88757)
+        (xy 32.855321 47.8811)
+        (xy 32.850896 47.875826)
+        (xy 32.829938 47.85085)
+        (xy 32.825985 47.848568)
+        (xy 32.794299 47.797859)
+        (xy 32.798637 47.735836)
+        (xy 32.812096 47.712287)
+        (xy 32.862455 47.646658)
+        (xy 32.917531 47.513691)
+        (xy 32.919171 47.501239)
+        (xy 32.935456 47.37754)
+        (xy 32.936317 47.371)
+        (xy 32.917531 47.228309)
+        (xy 32.89862 47.182652)
+        (xy 32.864978 47.101432)
+        (xy 32.864976 47.101429)
+        (xy 32.862455 47.095342)
+        (xy 32.858688 47.090433)
+        (xy 32.845796 47.029786)
+        (xy 32.871084 46.972987)
+        (xy 32.924928 46.941899)
+        (xy 32.945845 46.9397)
+        (xy 33.34935 46.9397)
+        (xy 33.408481 46.958913)
+        (xy 33.420485 46.969165)
+        (xy 33.673535 47.222216)
+        (xy 33.915844 47.464525)
+        (xy 33.921773 47.470995)
+        (xy 33.936645 47.488718)
+        (xy 33.947151 47.501239)
+        (xy 33.954772 47.505639)
+        (xy 33.981333 47.520974)
+        (xy 33.988735 47.525689)
+        (xy 34.021084 47.54834)
+        (xy 34.029581 47.550617)
+        (xy 34.034957 47.553124)
+        (xy 34.040531 47.555153)
+        (xy 34.048149 47.559551)
+        (xy 34.056811 47.561078)
+        (xy 34.056813 47.561079)
+        (xy 34.087042 47.566409)
+        (xy 34.095608 47.568309)
+        (xy 34.119461 47.5747)
+        (xy 34.133733 47.578524)
+        (xy 34.142501 47.577757)
+        (xy 34.151269 47.578524)
+        (xy 34.151089 47.58058)
+        (xy 34.200441 47.591974)
+        (xy 34.219699 47.607006)
+        (xy 34.226577 47.613872)
+        (xy 34.292882 47.680062)
+        (xy 34.292884 47.680064)
+        (xy 34.298765 47.685934)
+        (xy 34.404555 47.737646)
+        (xy 34.431221 47.741536)
+        (xy 34.469864 47.747174)
+        (xy 34.469871 47.747174)
+        (xy 34.473473 47.7477)
+        (xy 35.242308 47.7477)
+        (xy 36.018526 47.747699)
+        (xy 36.088045 47.737467)
+        (xy 36.165757 47.699312)
+        (xy 36.18628 47.689236)
+        (xy 36.186281 47.689235)
+        (xy 36.193744 47.685571)
+        (xy 36.219707 47.659563)
+        (xy 36.271061 47.608118)
+        (xy 36.276934 47.602235)
+        (xy 36.316656 47.520974)
+        (xy 36.325217 47.50346)
+        (xy 36.328646 47.496445)
+        (xy 36.3387 47.427527)
+        (xy 36.338699 47.060474)
+        (xy 36.328467 46.990955)
+        (xy 36.290152 46.912917)
+        (xy 36.280236 46.89272)
+        (xy 36.280235 46.892719)
+        (xy 36.276571 46.885256)
+        (xy 36.260828 46.86954)
+        (xy 36.199118 46.807939)
+        (xy 36.193235 46.802066)
+        (xy 36.185766 46.798415)
+        (xy 36.09446 46.753783)
+        (xy 36.087445 46.750354)
+        (xy 36.060779 46.746464)
+        (xy 36.022136 46.740826)
+        (xy 36.022129 46.740826)
+        (xy 36.018527 46.7403)
+        (xy 35.249692 46.7403)
+        (xy 34.473474 46.740301)
+        (xy 34.403955 46.750533)
+        (xy 34.304064 46.799577)
+        (xy 34.304062 46.799578)
+        (xy 34.298256 46.802429)
+        (xy 34.297827 46.801556)
+        (xy 34.245733 46.818082)
+        (xy 34.186737 46.798456)
+        (xy 34.1753 46.788619)
+        (xy 33.775161 46.388481)
+        (xy 33.769232 46.382011)
+        (xy 33.753826 46.363651)
+        (xy 33.743849 46.351761)
+        (xy 33.736225 46.347359)
+        (xy 33.709657 46.332019)
+        (xy 33.702258 46.327305)
+        (xy 33.677127 46.309709)
+        (xy 33.677126 46.309709)
+        (xy 33.669916 46.30466)
+        (xy 33.661418 46.302383)
+        (xy 33.656043 46.299876)
+        (xy 33.650469 46.297847)
+        (xy 33.642851 46.293449)
+        (xy 33.634189 46.291922)
+        (xy 33.634187 46.291921)
+        (xy 33.603958 46.286591)
+        (xy 33.595392 46.284691)
+        (xy 33.565769 46.276754)
+        (xy 33.557267 46.274476)
+        (xy 33.548499 46.275243)
+        (xy 33.517935 46.277917)
+        (xy 33.509167 46.2783)
+        (xy 32.960375 46.2783)
+        (xy 32.901244 46.259087)
+        (xy 32.864699 46.208787)
+        (xy 32.864699 46.146613)
+        (xy 32.869016 46.136343)
+        (xy 32.870953 46.133618)
+        (xy 32.921682 45.992713)
+        (xy 32.93265 45.843356)
+        (xy 32.921987 45.790473)
+        (xy 34.1533 45.790473)
+        (xy 34.153301 46.157526)
+        (xy 34.163533 46.227045)
+        (xy 34.177598 46.255691)
+        (xy 34.209866 46.321413)
+        (xy 34.215429 46.332744)
+        (xy 34.221313 46.338618)
+        (xy 34.221314 46.338619)
+        (xy 34.238469 46.355744)
+        (xy 34.298765 46.415934)
+        (xy 34.404555 46.467646)
+        (xy 34.431221 46.471536)
+        (xy 34.469864 46.477174)
+        (xy 34.469871 46.477174)
+        (xy 34.473473 46.4777)
+        (xy 35.242308 46.4777)
+        (xy 36.018526 46.477699)
+        (xy 36.088045 46.467467)
+        (xy 36.139011 46.442444)
+        (xy 36.18628 46.419236)
+        (xy 36.186281 46.419235)
+        (xy 36.193744 46.415571)
+        (xy 36.219707 46.389563)
+        (xy 36.271061 46.338118)
+        (xy 36.276934 46.332235)
+        (xy 36.328646 46.226445)
+        (xy 36.338053 46.161963)
+        (xy 36.338174 46.161136)
+        (xy 36.338174 46.161129)
+        (xy 36.3387 46.157527)
+        (xy 36.338699 45.790474)
+        (xy 36.328467 45.720955)
+        (xy 36.290152 45.642917)
+        (xy 36.280236 45.62272)
+        (xy 36.280235 45.622719)
+        (xy 36.276571 45.615256)
+        (xy 36.260828 45.59954)
+        (xy 36.224338 45.563115)
+        (xy 36.193235 45.532066)
+        (xy 36.17112 45.521256)
+        (xy 36.09446 45.483783)
+        (xy 36.087445 45.480354)
+        (xy 36.060779 45.476464)
+        (xy 36.022136 45.470826)
+        (xy 36.022129 45.470826)
+        (xy 36.018527 45.4703)
+        (xy 35.249692 45.4703)
+        (xy 34.473474 45.470301)
+        (xy 34.403955 45.480533)
+        (xy 34.372459 45.495997)
+        (xy 34.30572 45.528764)
+        (xy 34.305719 45.528765)
+        (xy 34.298256 45.532429)
+        (xy 34.292382 45.538313)
+        (xy 34.292381 45.538314)
+        (xy 34.276475 45.554248)
+        (xy 34.215066 45.615765)
+        (xy 34.211415 45.623234)
+        (xy 34.190478 45.666067)
+        (xy 34.163354 45.721555)
+        (xy 34.161397 45.734971)
+        (xy 34.153831 45.786835)
+        (xy 34.1533 45.790473)
+        (xy 32.921987 45.790473)
+        (xy 32.921259 45.786864)
+        (xy 32.904405 45.703275)
+        (xy 32.904405 45.703274)
+        (xy 32.903049 45.696551)
+        (xy 32.894085 45.678957)
+        (xy 32.838174 45.569227)
+        (xy 32.83506 45.563115)
+        (xy 32.759122 45.480533)
+        (xy 32.738336 45.457928)
+        (xy 32.738335 45.457927)
+        (xy 32.733692 45.452878)
+        (xy 32.606412 45.373961)
+        (xy 32.599829 45.372049)
+        (xy 32.599828 45.372048)
+        (xy 32.518451 45.348406)
+        (xy 32.467027 45.313458)
+        (xy 32.445967 45.25496)
+        (xy 32.463313 45.195254)
+        (xy 32.51244 45.157147)
+        (xy 32.546517 45.1512)
+        (xy 32.739067 45.1512)
+        (xy 32.751957 45.147012)
+        (xy 32.755 45.142823)
+        (xy 32.755 45.135267)
+        (xy 33.009 45.135267)
+        (xy 33.013188 45.148157)
+        (xy 33.017377 45.1512)
+        (xy 33.471659 45.1512)
+        (xy 33.477687 45.150836)
+        (xy 33.594947 45.136647)
+        (xy 33.606639 45.133775)
+        (xy 33.754515 45.077898)
+        (xy 33.765177 45.072324)
+        (xy 33.895454 44.982785)
+        (xy 33.904483 44.974825)
+        (xy 33.985775 44.883586)
+        (xy 34.039456 44.852217)
+        (xy 34.101323 44.858392)
+        (xy 34.147745 44.899753)
+        (xy 34.160415 44.93586)
+        (xy 34.162394 44.94931)
+        (xy 34.162395 44.949313)
+        (xy 34.163533 44.957045)
+        (xy 34.166979 44.964063)
+        (xy 34.209866 45.051413)
+        (xy 34.215429 45.062744)
+        (xy 34.221313 45.068618)
+        (xy 34.221314 45.068619)
+        (xy 34.25479 45.102036)
+        (xy 34.298765 45.145934)
+        (xy 34.306234 45.149585)
+        (xy 34.358794 45.175277)
+        (xy 34.404555 45.197646)
+        (xy 34.431221 45.201536)
+        (xy 34.469864 45.207174)
+        (xy 34.469871 45.207174)
+        (xy 34.473473 45.2077)
+        (xy 35.242308 45.2077)
+        (xy 36.018526 45.207699)
+        (xy 36.088045 45.197467)
+        (xy 36.143088 45.170442)
+        (xy 36.18628 45.149236)
+        (xy 36.186281 45.149235)
+        (xy 36.193744 45.145571)
+        (xy 36.202653 45.136647)
+        (xy 36.265317 45.073872)
+        (xy 36.276934 45.062235)
+        (xy 36.328646 44.956445)
+        (xy 36.332536 44.929779)
+        (xy 36.338174 44.891136)
+        (xy 36.338174 44.891129)
+        (xy 36.3387 44.887527)
+        (xy 36.338699 44.520474)
+        (xy 36.328467 44.450955)
+        (xy 36.290152 44.372917)
+        (xy 36.280236 44.35272)
+        (xy 36.280235 44.352719)
+        (xy 36.276571 44.345256)
+        (xy 36.252273 44.321)
+        (xy 36.199118 44.267939)
+        (xy 36.193235 44.262066)
+        (xy 36.087445 44.210354)
+        (xy 36.057942 44.20605)
+        (xy 36.022136 44.200826)
+        (xy 36.022129 44.200826)
+        (xy 36.018527 44.2003)
+        (xy 35.471983 44.2003)
+        (xy 35.412852 44.181087)
+        (xy 35.392172 44.160941)
+        (xy 35.318856 44.065394)
+        (xy 35.31484 44.06016)
+        (xy 35.300409 44.049086)
+        (xy 35.205889 43.976558)
+        (xy 35.205888 43.976558)
+        (xy 35.200659 43.972545)
+        (xy 35.067691 43.917469)
+        (xy 35.061155 43.916608)
+        (xy 35.061153 43.916608)
+        (xy 34.93154 43.899544)
+        (xy 34.925 43.898683)
+        (xy 34.91846 43.899544)
+        (xy 34.788847 43.916608)
+        (xy 34.788845 43.916608)
+        (xy 34.782309 43.917469)
+        (xy 34.649342 43.972545)
+        (xy 34.53516 44.06016)
+        (xy 34.447545 44.174342)
+        (xy 34.446548 44.173577)
+        (xy 34.405809 44.21026)
+        (xy 34.403955 44.210533)
+        (xy 34.350294 44.23688)
+        (xy 34.30572 44.258764)
+        (xy 34.305719 44.258765)
+        (xy 34.298256 44.262429)
+        (xy 34.292382 44.268313)
+        (xy 34.292381 44.268314)
+        (xy 34.274074 44.286653)
+        (xy 34.218701 44.314928)
+        (xy 34.157283 44.305255)
+        (xy 34.113281 44.261329)
+        (xy 34.105056 44.239064)
+        (xy 34.097353 44.206976)
+        (xy 34.093158 44.195698)
+        (xy 34.020655 44.055226)
+        (xy 34.013892 44.045274)
+        (xy 33.909976 43.926152)
+        (xy 33.901025 43.918093)
+        (xy 33.771701 43.827203)
+        (xy 33.761086 43.821511)
+        (xy 33.613819 43.764095)
+        (xy 33.602144 43.761098)
+        (xy 33.481615 43.745229)
+        (xy 33.475065 43.7448)
+        (xy 33.024933 43.7448)
+        (xy 33.012043 43.748988)
+        (xy 33.009 43.753177)
+        (xy 33.009 45.135267)
+        (xy 32.755 45.135267)
+        (xy 32.755 44.590933)
+        (xy 32.750812 44.578043)
+        (xy 32.746623 44.575)
+        (xy 31.655206 44.575)
+        (xy 31.642896 44.579)
+        (xy 31.642521 44.58853)
+        (xy 31.666644 44.689011)
+        (xy 31.670846 44.70031)
+        (xy 31.743345 44.840774)
+        (xy 31.750108 44.850726)
+        (xy 31.854024 44.969848)
+        (xy 31.862975 44.977907)
+        (xy 31.992299 45.068797)
+        (xy 32.002914 45.074489)
+        (xy 32.150181 45.131905)
+        (xy 32.161855 45.134902)
+        (xy 32.243883 45.145702)
+        (xy 32.3 45.172469)
+        (xy 32.329667 45.227109)
+        (xy 32.321551 45.288751)
+        (xy 32.278753 45.33385)
+        (xy 32.244405 45.345109)
+        (xy 32.233626 45.346586)
+        (xy 32.096184 45.406062)
+        (xy 31.9798 45.500309)
+        (xy 31.893047 45.622382)
+        (xy 31.890726 45.62883)
+        (xy 31.890724 45.628833)
+        (xy 31.877319 45.666067)
+        (xy 31.842318 45.763287)
+        (xy 31.835028 45.862562)
+        (xy 31.831497 45.910643)
+        (xy 31.825862 45.92445)
+        (xy 31.840415 45.957602)
+        (xy 31.846314 45.986855)
+        (xy 31.860951 46.059449)
+        (xy 31.864065 46.06556)
+        (xy 31.864065 46.065561)
+        (xy 31.897932 46.132029)
+        (xy 31.907658 46.193438)
+        (xy 31.879432 46.248835)
+        (xy 31.824034 46.277062)
+        (xy 31.808297 46.2783)
+        (xy 31.725632 46.2783)
+        (xy 31.666501 46.259087)
+        (xy 31.629956 46.208787)
+        (xy 31.626271 46.161963)
+        (xy 31.64058 46.071616)
+        (xy 31.6412 46.063744)
+        (xy 31.6412 45.977486)
+        (xy 31.647567 45.957892)
+        (xy 31.645668 45.956287)
+        (xy 31.637995 45.939758)
+        (xy 31.632823 45.936)
+        (xy 30.350734 45.936)
+        (xy 30.337844 45.940188)
+        (xy 30.334801 45.944377)
+        (xy 30.334801 46.063752)
+        (xy 30.335418 46.071599)
+        (xy 30.34973 46.161963)
+        (xy 30.340003 46.223372)
+        (xy 30.296039 46.267336)
+        (xy 30.250368 46.2783)
+        (xy 30.1293 46.2783)
+        (xy 30.070169 46.259087)
+        (xy 30.033624 46.208787)
+        (xy 30.0287 46.1777)
+        (xy 30.0287 45.84226)
+        (xy 30.02781 45.836635)
+        (xy 30.014039 45.749695)
+        (xy 30.014039 45.749694)
+        (xy 30.0128 45.741873)
+        (xy 30.009206 45.73482)
+        (xy 30.009205 45.734816)
+        (xy 29.974175 45.666067)
+        (xy 30.3348 45.666067)
+        (xy 30.338988 45.678957)
+        (xy 30.343177 45.682)
+        (xy 30.845067 45.682)
+        (xy 30.857957 45.677812)
+        (xy 30.861 45.673623)
+        (xy 30.861 45.666067)
+        (xy 31.115 45.666067)
+        (xy 31.119188 45.678957)
+        (xy 31.123377 45.682)
+        (xy 31.625266 45.682)
+        (xy 31.638156 45.677812)
+        (xy 31.641199 45.673623)
+        (xy 31.641199 45.554248)
+        (xy 31.640582 45.546399)
+        (xy 31.626558 45.45785)
+        (xy 31.621723 45.442971)
+        (xy 31.567335 45.336229)
+        (xy 31.558141 45.323574)
+        (xy 31.473426 45.238859)
+        (xy 31.460771 45.229665)
+        (xy 31.354026 45.175276)
+        (xy 31.33915 45.170442)
+        (xy 31.250616 45.15642)
+        (xy 31.242744 45.1558)
+        (xy 31.130933 45.1558)
+        (xy 31.118043 45.159988)
+        (xy 31.115 45.164177)
+        (xy 31.115 45.666067)
+        (xy 30.861 45.666067)
+        (xy 30.861 45.171734)
+        (xy 30.856812 45.158844)
+        (xy 30.852623 45.155801)
+        (xy 30.733248 45.155801)
+        (xy 30.725399 45.156418)
+        (xy 30.63685 45.170442)
+        (xy 30.621971 45.175277)
+        (xy 30.515229 45.229665)
+        (xy 30.502574 45.238859)
+        (xy 30.417859 45.323574)
+        (xy 30.408665 45.336229)
+        (xy 30.354276 45.442974)
+        (xy 30.349442 45.45785)
+        (xy 30.33542 45.546384)
+        (xy 30.3348 45.554256)
+        (xy 30.3348 45.666067)
+        (xy 29.974175 45.666067)
+        (xy 29.954744 45.627931)
+        (xy 29.951149 45.620875)
+        (xy 29.855125 45.524851)
+        (xy 29.820383 45.507149)
+        (xy 29.741184 45.466795)
+        (xy 29.74118 45.466794)
+        (xy 29.734127 45.4632)
+        (xy 29.726306 45.461961)
+        (xy 29.726305 45.461961)
+        (xy 29.637651 45.447919)
+        (xy 29.637645 45.447919)
+        (xy 29.63374 45.4473)
+        (xy 29.11626 45.4473)
+        (xy 29.112355 45.447919)
+        (xy 29.112349 45.447919)
+        (xy 29.023695 45.461961)
+        (xy 29.023694 45.461961)
+        (xy 29.015873 45.4632)
+        (xy 29.00882 45.466794)
+        (xy 29.008816 45.466795)
+        (xy 28.929617 45.507149)
+        (xy 28.894875 45.524851)
+        (xy 28.798851 45.620875)
+        (xy 28.795256 45.627931)
+        (xy 28.740795 45.734816)
+        (xy 28.740794 45.73482)
+        (xy 28.7372 45.741873)
+        (xy 28.735961 45.749694)
+        (xy 28.735961 45.749695)
+        (xy 28.722191 45.836635)
+        (xy 28.7213 45.84226)
+        (xy 28.7213 46.35974)
+        (xy 28.427885 46.35974)
+        (xy 28.4282 46.355744)
+        (xy 28.4282 46.243933)
+        (xy 28.424012 46.231043)
+        (xy 28.419823 46.228)
+        (xy 27.7486 46.228)
+        (xy 27.689469 46.208787)
+        (xy 27.652924 46.158487)
+        (xy 27.648 46.1274)
+        (xy 27.648 45.958067)
+        (xy 27.902 45.958067)
+        (xy 27.906188 45.970957)
+        (xy 27.910377 45.974)
+        (xy 28.412266 45.974)
+        (xy 28.425156 45.969812)
+        (xy 28.428199 45.965623)
+        (xy 28.428199 45.846248)
+        (xy 28.427582 45.838399)
+        (xy 28.413558 45.74985)
+        (xy 28.408723 45.734971)
+        (xy 28.354335 45.628229)
+        (xy 28.345141 45.615574)
+        (xy 28.260426 45.530859)
+        (xy 28.247771 45.521665)
+        (xy 28.141026 45.467276)
+        (xy 28.12615 45.462442)
+        (xy 28.037616 45.44842)
+        (xy 28.029744 45.4478)
+        (xy 27.917933 45.4478)
+        (xy 27.905043 45.451988)
+        (xy 27.902 45.456177)
+        (xy 27.902 45.958067)
+        (xy 27.648 45.958067)
+        (xy 27.648 45.463734)
+        (xy 27.643812 45.450844)
+        (xy 27.639623 45.447801)
+        (xy 27.520248 45.447801)
+        (xy 27.512399 45.448418)
+        (xy 27.42385 45.462442)
+        (xy 27.408971 45.467277)
+        (xy 27.302229 45.521665)
+        (xy 27.287431 45.532416)
+        (xy 27.2283 45.551629)
+        (xy 27.169168 45.532416)
+        (xy 27.132624 45.482116)
+        (xy 27.1277 45.451029)
+        (xy 27.1277 44.58853)
+        (xy 27.462521 44.58853)
+        (xy 27.486644 44.689011)
+        (xy 27.490846 44.70031)
+        (xy 27.563345 44.840774)
+        (xy 27.570108 44.850726)
+        (xy 27.674024 44.969848)
+        (xy 27.682975 44.977907)
+        (xy 27.812299 45.068797)
+        (xy 27.822914 45.074489)
+        (xy 27.970181 45.131905)
+        (xy 27.981856 45.134902)
+        (xy 28.102385 45.150771)
+        (xy 28.108935 45.1512)
+        (xy 28.559067 45.1512)
+        (xy 28.571957 45.147012)
+        (xy 28.575 45.142823)
+        (xy 28.575 45.135267)
+        (xy 28.829 45.135267)
+        (xy 28.833188 45.148157)
+        (xy 28.837377 45.1512)
+        (xy 29.291659 45.1512)
+        (xy 29.297687 45.150836)
+        (xy 29.414947 45.136647)
+        (xy 29.426639 45.133775)
+        (xy 29.574515 45.077898)
+        (xy 29.585177 45.072324)
+        (xy 29.715454 44.982785)
+        (xy 29.724483 44.974825)
+        (xy 29.829638 44.856803)
+        (xy 29.836511 44.846914)
+        (xy 29.910479 44.707212)
+        (xy 29.914793 44.695974)
+        (xy 29.941297 44.590454)
+        (xy 29.940429 44.577714)
+        (xy 29.930996 44.575)
+        (xy 28.844933 44.575)
+        (xy 28.832043 44.579188)
+        (xy 28.829 44.583377)
+        (xy 28.829 45.135267)
+        (xy 28.575 45.135267)
+        (xy 28.575 44.590933)
+        (xy 28.570812 44.578043)
+        (xy 28.566623 44.575)
+        (xy 27.475206 44.575)
+        (xy 27.462896 44.579)
+        (xy 27.462521 44.58853)
+        (xy 27.1277 44.58853)
+        (xy 27.1277 44.305546)
+        (xy 27.462703 44.305546)
+        (xy 27.463571 44.318286)
+        (xy 27.473004 44.321)
+        (xy 28.559067 44.321)
+        (xy 28.571957 44.316812)
+        (xy 28.575 44.312623)
+        (xy 28.575 44.305067)
+        (xy 28.829 44.305067)
+        (xy 28.833188 44.317957)
+        (xy 28.837377 44.321)
+        (xy 29.928794 44.321)
+        (xy 29.941104 44.317)
+        (xy 29.941479 44.30747)
+        (xy 29.941017 44.305546)
+        (xy 31.642703 44.305546)
+        (xy 31.643571 44.318286)
+        (xy 31.653004 44.321)
+        (xy 32.739067 44.321)
+        (xy 32.751957 44.316812)
+        (xy 32.755 44.312623)
+        (xy 32.755 43.760733)
+        (xy 32.750812 43.747843)
+        (xy 32.746623 43.7448)
+        (xy 32.292341 43.7448)
+        (xy 32.286313 43.745164)
+        (xy 32.169053 43.759353)
+        (xy 32.157361 43.762225)
+        (xy 32.009485 43.818102)
+        (xy 31.998823 43.823676)
+        (xy 31.868546 43.913215)
+        (xy 31.859517 43.921175)
+        (xy 31.754362 44.039197)
+        (xy 31.747489 44.049086)
+        (xy 31.673521 44.188788)
+        (xy 31.669207 44.200026)
+        (xy 31.642703 44.305546)
+        (xy 29.941017 44.305546)
+        (xy 29.917356 44.206989)
+        (xy 29.913154 44.19569)
+        (xy 29.840655 44.055226)
+        (xy 29.833892 44.045274)
+        (xy 29.729976 43.926152)
+        (xy 29.721025 43.918093)
+        (xy 29.591701 43.827203)
+        (xy 29.581086 43.821511)
+        (xy 29.433819 43.764095)
+        (xy 29.422144 43.761098)
+        (xy 29.301615 43.745229)
+        (xy 29.295065 43.7448)
+        (xy 28.844933 43.7448)
+        (xy 28.832043 43.748988)
+        (xy 28.829 43.753177)
+        (xy 28.829 44.305067)
+        (xy 28.575 44.305067)
+        (xy 28.575 43.760733)
+        (xy 28.570812 43.747843)
+        (xy 28.566623 43.7448)
+        (xy 28.112341 43.7448)
+        (xy 28.106313 43.745164)
+        (xy 27.989053 43.759353)
+        (xy 27.977361 43.762225)
+        (xy 27.829485 43.818102)
+        (xy 27.818823 43.823676)
+        (xy 27.688546 43.913215)
+        (xy 27.679517 43.921175)
+        (xy 27.574362 44.039197)
+        (xy 27.567489 44.049086)
+        (xy 27.493521 44.188788)
+        (xy 27.489207 44.200026)
+        (xy 27.462703 44.305546)
+        (xy 27.1277 44.305546)
+        (xy 27.1277 43.6113)
+        (xy 27.146913 43.552169)
+        (xy 27.197213 43.515624)
+        (xy 27.2283 43.5107)
+        (xy 41.8343 43.5107)
+      )
+    )
+  )
+)

+ 75 - 0
dap_link/lib/free-dap/hardware/d11-nano-dbg/d11-nano-dbg.kicad_prl

@@ -0,0 +1,75 @@
+{
+  "board": {
+    "active_layer": 31,
+    "active_layer_preset": "",
+    "auto_track_width": true,
+    "hidden_nets": [],
+    "high_contrast_mode": 0,
+    "net_color_mode": 1,
+    "opacity": {
+      "pads": 1.0,
+      "tracks": 1.0,
+      "vias": 1.0,
+      "zones": 0.3100000023841858
+    },
+    "ratsnest_display_mode": 0,
+    "selection_filter": {
+      "dimensions": true,
+      "footprints": true,
+      "graphics": true,
+      "keepouts": true,
+      "lockedItems": true,
+      "otherItems": true,
+      "pads": true,
+      "text": true,
+      "tracks": true,
+      "vias": true,
+      "zones": true
+    },
+    "visible_items": [
+      0,
+      1,
+      2,
+      3,
+      4,
+      5,
+      8,
+      9,
+      10,
+      11,
+      12,
+      13,
+      14,
+      15,
+      16,
+      17,
+      18,
+      19,
+      20,
+      21,
+      22,
+      23,
+      24,
+      25,
+      26,
+      27,
+      28,
+      29,
+      30,
+      32,
+      33,
+      34,
+      35,
+      36
+    ],
+    "visible_layers": "7fcffff_80000001",
+    "zone_display_mode": 0
+  },
+  "meta": {
+    "filename": "d11-nano-dbg.kicad_prl",
+    "version": 3
+  },
+  "project": {
+    "files": []
+  }
+}

+ 435 - 0
dap_link/lib/free-dap/hardware/d11-nano-dbg/d11-nano-dbg.kicad_pro

@@ -0,0 +1,435 @@
+{
+  "board": {
+    "design_settings": {
+      "defaults": {
+        "board_outline_line_width": 0.09999999999999999,
+        "copper_line_width": 0.19999999999999998,
+        "copper_text_italic": false,
+        "copper_text_size_h": 1.5,
+        "copper_text_size_v": 1.5,
+        "copper_text_thickness": 0.3,
+        "copper_text_upright": false,
+        "courtyard_line_width": 0.049999999999999996,
+        "dimension_precision": 4,
+        "dimension_units": 3,
+        "dimensions": {
+          "arrow_length": 1270000,
+          "extension_offset": 500000,
+          "keep_text_aligned": true,
+          "suppress_zeroes": false,
+          "text_position": 0,
+          "units_format": 1
+        },
+        "fab_line_width": 0.09999999999999999,
+        "fab_text_italic": false,
+        "fab_text_size_h": 1.0,
+        "fab_text_size_v": 1.0,
+        "fab_text_thickness": 0.15,
+        "fab_text_upright": false,
+        "other_line_width": 0.15,
+        "other_text_italic": false,
+        "other_text_size_h": 1.0,
+        "other_text_size_v": 1.0,
+        "other_text_thickness": 0.15,
+        "other_text_upright": false,
+        "pads": {
+          "drill": 0.762,
+          "height": 1.524,
+          "width": 1.524
+        },
+        "silk_line_width": 0.15,
+        "silk_text_italic": false,
+        "silk_text_size_h": 1.0,
+        "silk_text_size_v": 1.0,
+        "silk_text_thickness": 0.15,
+        "silk_text_upright": false,
+        "zones": {
+          "45_degree_only": false,
+          "min_clearance": 0.2032
+        }
+      },
+      "diff_pair_dimensions": [
+        {
+          "gap": 0.0,
+          "via_gap": 0.0,
+          "width": 0.0
+        }
+      ],
+      "drc_exclusions": [],
+      "meta": {
+        "version": 2
+      },
+      "rule_severities": {
+        "annular_width": "error",
+        "clearance": "error",
+        "copper_edge_clearance": "error",
+        "courtyards_overlap": "error",
+        "diff_pair_gap_out_of_range": "error",
+        "diff_pair_uncoupled_length_too_long": "error",
+        "drill_out_of_range": "error",
+        "duplicate_footprints": "warning",
+        "extra_footprint": "warning",
+        "footprint_type_mismatch": "error",
+        "hole_clearance": "error",
+        "hole_near_hole": "error",
+        "invalid_outline": "error",
+        "item_on_disabled_layer": "error",
+        "items_not_allowed": "error",
+        "length_out_of_range": "error",
+        "malformed_courtyard": "error",
+        "microvia_drill_out_of_range": "error",
+        "missing_courtyard": "ignore",
+        "missing_footprint": "warning",
+        "net_conflict": "warning",
+        "npth_inside_courtyard": "ignore",
+        "padstack": "error",
+        "pth_inside_courtyard": "ignore",
+        "shorting_items": "error",
+        "silk_over_copper": "ignore",
+        "silk_overlap": "ignore",
+        "skew_out_of_range": "error",
+        "through_hole_pad_without_hole": "error",
+        "too_many_vias": "error",
+        "track_dangling": "warning",
+        "track_width": "error",
+        "tracks_crossing": "error",
+        "unconnected_items": "error",
+        "unresolved_variable": "error",
+        "via_dangling": "warning",
+        "zone_has_empty_net": "error",
+        "zones_intersect": "error"
+      },
+      "rules": {
+        "allow_blind_buried_vias": false,
+        "allow_microvias": false,
+        "max_error": 0.0050799999999999994,
+        "min_clearance": 0.0,
+        "min_copper_edge_clearance": 0.0,
+        "min_hole_clearance": 0.0,
+        "min_hole_to_hole": 0.254,
+        "min_microvia_diameter": 0.127,
+        "min_microvia_drill": 0.1016,
+        "min_silk_clearance": 0.0,
+        "min_through_hole_diameter": 0.3302,
+        "min_track_width": 0.254,
+        "min_via_annular_width": 0.17779999999999999,
+        "min_via_diameter": 0.3302,
+        "solder_mask_clearance": 0.0,
+        "solder_mask_min_width": 0.0,
+        "use_height_for_length_calcs": true
+      },
+      "track_widths": [
+        0.0,
+        0.2032,
+        0.254
+      ],
+      "via_dimensions": [
+        {
+          "diameter": 0.0,
+          "drill": 0.0
+        }
+      ],
+      "zones_allow_external_fillets": false,
+      "zones_use_no_outline": true
+    },
+    "layer_presets": []
+  },
+  "boards": [],
+  "cvpcb": {
+    "equivalence_files": []
+  },
+  "erc": {
+    "erc_exclusions": [],
+    "meta": {
+      "version": 0
+    },
+    "pin_map": [
+      [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        1,
+        0,
+        0,
+        0,
+        0,
+        2
+      ],
+      [
+        0,
+        2,
+        0,
+        1,
+        0,
+        0,
+        1,
+        0,
+        2,
+        2,
+        2,
+        2
+      ],
+      [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        1,
+        0,
+        1,
+        0,
+        1,
+        2
+      ],
+      [
+        0,
+        1,
+        0,
+        0,
+        0,
+        0,
+        1,
+        1,
+        2,
+        1,
+        1,
+        2
+      ],
+      [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        1,
+        0,
+        0,
+        0,
+        0,
+        2
+      ],
+      [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        2
+      ],
+      [
+        1,
+        1,
+        1,
+        1,
+        1,
+        0,
+        1,
+        1,
+        1,
+        1,
+        1,
+        2
+      ],
+      [
+        0,
+        0,
+        0,
+        1,
+        0,
+        0,
+        1,
+        0,
+        0,
+        0,
+        0,
+        2
+      ],
+      [
+        0,
+        2,
+        1,
+        2,
+        0,
+        0,
+        1,
+        0,
+        2,
+        2,
+        2,
+        2
+      ],
+      [
+        0,
+        2,
+        0,
+        1,
+        0,
+        0,
+        1,
+        0,
+        2,
+        0,
+        0,
+        2
+      ],
+      [
+        0,
+        2,
+        1,
+        1,
+        0,
+        0,
+        1,
+        0,
+        2,
+        0,
+        0,
+        2
+      ],
+      [
+        2,
+        2,
+        2,
+        2,
+        2,
+        2,
+        2,
+        2,
+        2,
+        2,
+        2,
+        2
+      ]
+    ],
+    "rule_severities": {
+      "bus_definition_conflict": "error",
+      "bus_entry_needed": "error",
+      "bus_label_syntax": "error",
+      "bus_to_bus_conflict": "error",
+      "bus_to_net_conflict": "error",
+      "different_unit_footprint": "error",
+      "different_unit_net": "error",
+      "duplicate_reference": "error",
+      "duplicate_sheet_names": "error",
+      "extra_units": "error",
+      "global_label_dangling": "warning",
+      "hier_label_mismatch": "error",
+      "label_dangling": "error",
+      "lib_symbol_issues": "warning",
+      "multiple_net_names": "warning",
+      "net_not_bus_member": "warning",
+      "no_connect_connected": "warning",
+      "no_connect_dangling": "warning",
+      "pin_not_connected": "ignore",
+      "pin_not_driven": "error",
+      "pin_to_pin": "error",
+      "power_pin_not_driven": "error",
+      "similar_labels": "warning",
+      "unannotated": "error",
+      "unit_value_mismatch": "error",
+      "unresolved_variable": "error",
+      "wire_dangling": "error"
+    }
+  },
+  "libraries": {
+    "pinned_footprint_libs": [],
+    "pinned_symbol_libs": []
+  },
+  "meta": {
+    "filename": "saml11-debug.kicad_pro",
+    "version": 1
+  },
+  "net_settings": {
+    "classes": [
+      {
+        "bus_width": 12.0,
+        "clearance": 0.1905,
+        "diff_pair_gap": 0.254,
+        "diff_pair_via_gap": 0.25,
+        "diff_pair_width": 0.254,
+        "line_style": 0,
+        "microvia_diameter": 0.254,
+        "microvia_drill": 0.1016,
+        "name": "Default",
+        "pcb_color": "rgba(0, 0, 0, 0.000)",
+        "schematic_color": "rgba(0, 0, 0, 0.000)",
+        "track_width": 0.254,
+        "via_diameter": 0.6858,
+        "via_drill": 0.3302,
+        "wire_width": 6.0
+      }
+    ],
+    "meta": {
+      "version": 2
+    },
+    "net_colors": null
+  },
+  "pcbnew": {
+    "last_paths": {
+      "gencad": "",
+      "idf": "",
+      "netlist": "",
+      "specctra_dsn": "",
+      "step": "",
+      "vrml": ""
+    },
+    "page_layout_descr_file": "pcb.kicad_wks"
+  },
+  "schematic": {
+    "annotate_start_num": 0,
+    "drawing": {
+      "default_line_thickness": 6.0,
+      "default_text_size": 50.0,
+      "field_names": [],
+      "intersheets_ref_own_page": false,
+      "intersheets_ref_prefix": "",
+      "intersheets_ref_short": false,
+      "intersheets_ref_show": true,
+      "intersheets_ref_suffix": "",
+      "junction_size_choice": 3,
+      "label_size_ratio": 0.375,
+      "pin_symbol_size": 25.0,
+      "text_offset_ratio": 0.15
+    },
+    "legacy_lib_dir": "",
+    "legacy_lib_list": [],
+    "meta": {
+      "version": 1
+    },
+    "net_format_name": "",
+    "ngspice": {
+      "fix_include_paths": true,
+      "fix_passive_vals": false,
+      "meta": {
+        "version": 0
+      },
+      "model_mode": 0,
+      "workbook_filename": ""
+    },
+    "page_layout_descr_file": "sch.kicad_wks",
+    "plot_directory": "output/",
+    "spice_adjust_passive_values": false,
+    "spice_external_command": "spice \"%I\"",
+    "subpart_first_id": 65,
+    "subpart_id_separator": 0
+  },
+  "sheets": [
+    [
+      "9538e4ed-27e6-4c37-b989-9859dc0d49e8",
+      ""
+    ]
+  ],
+  "text_variables": {}
+}

+ 1673 - 0
dap_link/lib/free-dap/hardware/d11-nano-dbg/d11-nano-dbg.kicad_sch

@@ -0,0 +1,1673 @@
+(kicad_sch (version 20211123) (generator eeschema)
+
+  (uuid 9538e4ed-27e6-4c37-b989-9859dc0d49e8)
+
+  (paper "USLetter")
+
+  (title_block
+    (date "2022-04-07")
+    (rev "1")
+  )
+
+  (lib_symbols
+    (symbol "ataradov_conn:Conn-5x2" (pin_names (offset 0.635)) (in_bom yes) (on_board yes)
+      (property "Reference" "J?" (id 0) (at 0 7.62 0)
+        (effects (font (size 1.27 1.27)))
+      )
+      (property "Value" "Conn-5x2" (id 1) (at 0 -7.62 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Footprint" "ataradov_conn:Header-5x2-2.54mm" (id 2) (at 0 -10.16 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Datasheet" "" (id 3) (at 29.21 13.97 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (symbol "Conn-5x2_0_1"
+        (rectangle (start -3.81 6.35) (end 3.81 -6.35)
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type background))
+        )
+      )
+      (symbol "Conn-5x2_1_1"
+        (pin passive line (at -6.35 5.08 0) (length 2.54)
+          (name "1" (effects (font (size 1.27 1.27))))
+          (number "1" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at 6.35 -5.08 180) (length 2.54)
+          (name "10" (effects (font (size 1.27 1.27))))
+          (number "10" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at 6.35 5.08 180) (length 2.54)
+          (name "2" (effects (font (size 1.27 1.27))))
+          (number "2" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at -6.35 2.54 0) (length 2.54)
+          (name "3" (effects (font (size 1.27 1.27))))
+          (number "3" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at 6.35 2.54 180) (length 2.54)
+          (name "4" (effects (font (size 1.27 1.27))))
+          (number "4" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at -6.35 0 0) (length 2.54)
+          (name "5" (effects (font (size 1.27 1.27))))
+          (number "5" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at 6.35 0 180) (length 2.54)
+          (name "6" (effects (font (size 1.27 1.27))))
+          (number "6" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at -6.35 -2.54 0) (length 2.54)
+          (name "7" (effects (font (size 1.27 1.27))))
+          (number "7" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at 6.35 -2.54 180) (length 2.54)
+          (name "8" (effects (font (size 1.27 1.27))))
+          (number "8" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at -6.35 -5.08 0) (length 2.54)
+          (name "9" (effects (font (size 1.27 1.27))))
+          (number "9" (effects (font (size 1.27 1.27))))
+        )
+      )
+    )
+    (symbol "ataradov_conn:USB-C" (pin_numbers hide) (in_bom yes) (on_board yes)
+      (property "Reference" "J?" (id 0) (at 0 12.7 0)
+        (effects (font (size 1.27 1.27)))
+      )
+      (property "Value" "USB-C" (id 1) (at 0 -15.24 0)
+        (effects (font (size 1.27 1.27)))
+      )
+      (property "Footprint" "ataradov_conn:USB-C" (id 2) (at 0 -17.78 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Datasheet" "" (id 3) (at 3.81 -5.08 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (symbol "USB-C_0_1"
+        (rectangle (start -5.08 11.43) (end 5.08 -13.97)
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type background))
+        )
+      )
+      (symbol "USB-C_1_1"
+        (pin bidirectional line (at 7.62 -2.54 180) (length 2.54)
+          (name "CC1" (effects (font (size 1.27 1.27))))
+          (number "CC1" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at 7.62 -5.08 180) (length 2.54)
+          (name "CC2" (effects (font (size 1.27 1.27))))
+          (number "CC2" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at 7.62 5.08 180) (length 2.54)
+          (name "D+" (effects (font (size 1.27 1.27))))
+          (number "D+1" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at 7.62 2.54 180) (length 2.54)
+          (name "D+" (effects (font (size 1.27 1.27))))
+          (number "D+2" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at 7.62 10.16 180) (length 2.54)
+          (name "D-" (effects (font (size 1.27 1.27))))
+          (number "D-1" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at 7.62 7.62 180) (length 2.54)
+          (name "D-" (effects (font (size 1.27 1.27))))
+          (number "D-2" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at -7.62 -10.16 0) (length 2.54)
+          (name "GND" (effects (font (size 1.27 1.27))))
+          (number "GND1" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at -7.62 -12.7 0) (length 2.54)
+          (name "GND" (effects (font (size 1.27 1.27))))
+          (number "GND2" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at -7.62 2.54 0) (length 2.54)
+          (name "S1" (effects (font (size 1.27 1.27))))
+          (number "S1" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at -7.62 0 0) (length 2.54)
+          (name "S2" (effects (font (size 1.27 1.27))))
+          (number "S2" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at -7.62 -2.54 0) (length 2.54)
+          (name "S3" (effects (font (size 1.27 1.27))))
+          (number "S3" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at -7.62 -5.08 0) (length 2.54)
+          (name "S4" (effects (font (size 1.27 1.27))))
+          (number "S4" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at 7.62 -10.16 180) (length 2.54)
+          (name "SBU1" (effects (font (size 1.27 1.27))))
+          (number "SBU1" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at 7.62 -12.7 180) (length 2.54)
+          (name "SBU2" (effects (font (size 1.27 1.27))))
+          (number "SBU2" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at -7.62 10.16 0) (length 2.54)
+          (name "VBUS" (effects (font (size 1.27 1.27))))
+          (number "VBUS1" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at -7.62 7.62 0) (length 2.54)
+          (name "VBUS" (effects (font (size 1.27 1.27))))
+          (number "VBUS2" (effects (font (size 1.27 1.27))))
+        )
+      )
+    )
+    (symbol "ataradov_led:LED" (pin_numbers hide) (pin_names (offset 1.016) hide) (in_bom yes) (on_board yes)
+      (property "Reference" "LED?" (id 0) (at 0 2.54 0)
+        (effects (font (size 1.27 1.27)))
+      )
+      (property "Value" "LED" (id 1) (at 0 -2.54 0)
+        (effects (font (size 1.27 1.27)))
+      )
+      (property "Footprint" "ataradov_smd:0603" (id 2) (at 0 -4.2164 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Datasheet" "" (id 3) (at 4.699 -4.191 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (symbol "LED_0_1"
+        (polyline
+          (pts
+            (xy 1.27 1.27)
+            (xy 1.27 -1.27)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+        (polyline
+          (pts
+            (xy 2.1336 1.2192)
+            (xy 2.4892 0.8636)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+        (polyline
+          (pts
+            (xy 2.794 1.524)
+            (xy 2.2352 1.1684)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+        (polyline
+          (pts
+            (xy 2.794 1.524)
+            (xy 2.4384 0.9652)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+        (polyline
+          (pts
+            (xy 3.2004 1.2192)
+            (xy 3.556 0.8636)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+        (polyline
+          (pts
+            (xy 3.8608 1.524)
+            (xy 3.302 1.1684)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+        (polyline
+          (pts
+            (xy 3.8608 1.524)
+            (xy 3.4544 0.9652)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+        (polyline
+          (pts
+            (xy -1.27 1.27)
+            (xy -1.27 -1.27)
+            (xy 1.27 0)
+            (xy -1.27 1.27)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+        (polyline
+          (pts
+            (xy 1.6256 0.3556)
+            (xy 2.794 1.524)
+            (xy 2.1336 1.2192)
+            (xy 2.794 1.524)
+            (xy 2.4892 0.8636)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+        (polyline
+          (pts
+            (xy 2.6924 0.3556)
+            (xy 3.8608 1.524)
+            (xy 3.2004 1.2192)
+            (xy 3.8608 1.524)
+            (xy 3.556 0.8636)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+      )
+      (symbol "LED_1_1"
+        (pin passive line (at -3.81 0 0) (length 2.54)
+          (name "A" (effects (font (size 1.27 1.27))))
+          (number "1" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at 3.81 0 180) (length 2.54)
+          (name "K" (effects (font (size 1.27 1.27))))
+          (number "2" (effects (font (size 1.27 1.27))))
+        )
+      )
+    )
+    (symbol "ataradov_mcu:ATSAMD11C" (in_bom yes) (on_board yes)
+      (property "Reference" "IC?" (id 0) (at 0 11.43 0)
+        (effects (font (size 1.27 1.27)))
+      )
+      (property "Value" "ATSAMD11C" (id 1) (at 0 -11.43 0)
+        (effects (font (size 1.27 1.27)))
+      )
+      (property "Footprint" "ataradov_ic:SOIC-14" (id 2) (at 0 -13.97 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Datasheet" "" (id 3) (at 0 0 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (symbol "ATSAMD11C_0_1"
+        (rectangle (start -10.16 10.16) (end 10.16 -10.16)
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type background))
+        )
+      )
+      (symbol "ATSAMD11C_1_1"
+        (pin bidirectional line (at -12.7 2.54 0) (length 2.54)
+          (name "PA5" (effects (font (size 1.27 1.27))))
+          (number "1" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at -12.7 -7.62 0) (length 2.54)
+          (name "PA25/DP" (effects (font (size 1.27 1.27))))
+          (number "10" (effects (font (size 1.27 1.27))))
+        )
+        (pin power_in line (at 12.7 -7.62 180) (length 2.54)
+          (name "GND" (effects (font (size 1.27 1.27))))
+          (number "11" (effects (font (size 1.27 1.27))))
+        )
+        (pin power_in line (at 12.7 7.62 180) (length 2.54)
+          (name "VDD" (effects (font (size 1.27 1.27))))
+          (number "12" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at -12.7 7.62 0) (length 2.54)
+          (name "PA2" (effects (font (size 1.27 1.27))))
+          (number "13" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at -12.7 5.08 0) (length 2.54)
+          (name "PA4" (effects (font (size 1.27 1.27))))
+          (number "14" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at -12.7 0 0) (length 2.54)
+          (name "PA8" (effects (font (size 1.27 1.27))))
+          (number "2" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at -12.7 -2.54 0) (length 2.54)
+          (name "PA9" (effects (font (size 1.27 1.27))))
+          (number "3" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at 12.7 5.08 180) (length 2.54)
+          (name "PA14" (effects (font (size 1.27 1.27))))
+          (number "4" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at 12.7 2.54 180) (length 2.54)
+          (name "PA15" (effects (font (size 1.27 1.27))))
+          (number "5" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at 12.7 0 180) (length 2.54)
+          (name "PA28/RST" (effects (font (size 1.27 1.27))))
+          (number "6" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at 12.7 -2.54 180) (length 2.54)
+          (name "PA30/SCK" (effects (font (size 1.27 1.27))))
+          (number "7" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at 12.7 -5.08 180) (length 2.54)
+          (name "PA31/SIO" (effects (font (size 1.27 1.27))))
+          (number "8" (effects (font (size 1.27 1.27))))
+        )
+        (pin bidirectional line (at -12.7 -5.08 0) (length 2.54)
+          (name "PA24/DM" (effects (font (size 1.27 1.27))))
+          (number "9" (effects (font (size 1.27 1.27))))
+        )
+      )
+    )
+    (symbol "ataradov_misc:TestPoint" (pin_numbers hide) (pin_names hide) (in_bom yes) (on_board yes)
+      (property "Reference" "TP?" (id 0) (at 2.54 0 0)
+        (effects (font (size 1.27 1.27)) (justify left))
+      )
+      (property "Value" "TestPoint" (id 1) (at 7.62 0 0)
+        (effects (font (size 1.27 1.27)) (justify left))
+      )
+      (property "Footprint" "ataradov_misc:TestPoint-1.27mm" (id 2) (at 0 -2.54 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Datasheet" "" (id 3) (at 0 0 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (symbol "TestPoint_0_1"
+        (circle (center 1.778 0) (radius 0.508)
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type outline))
+        )
+      )
+      (symbol "TestPoint_1_1"
+        (pin passive line (at 0 0 0) (length 1.78)
+          (name "1" (effects (font (size 1.27 1.27))))
+          (number "1" (effects (font (size 1.27 1.27))))
+        )
+      )
+    )
+    (symbol "ataradov_pwr:+3V3" (power) (pin_names (offset 0)) (in_bom yes) (on_board yes)
+      (property "Reference" "#PWR" (id 0) (at 0 4.445 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Value" "+3V3" (id 1) (at 0 2.286 0)
+        (effects (font (size 1.27 1.27)))
+      )
+      (property "Footprint" "" (id 2) (at 0 0 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Datasheet" "" (id 3) (at 0 0 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (symbol "+3V3_0_1"
+        (polyline
+          (pts
+            (xy -1.905 1.27)
+            (xy 0 1.27)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+        (polyline
+          (pts
+            (xy 0 0)
+            (xy 0 1.27)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+        (polyline
+          (pts
+            (xy 0 1.27)
+            (xy 1.905 1.27)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+      )
+      (symbol "+3V3_1_1"
+        (pin power_in line (at 0 0 90) (length 0) hide
+          (name "+3V3" (effects (font (size 1.27 1.27))))
+          (number "1" (effects (font (size 1.27 1.27))))
+        )
+      )
+    )
+    (symbol "ataradov_pwr:GND" (power) (pin_names (offset 0)) (in_bom yes) (on_board yes)
+      (property "Reference" "#PWR" (id 0) (at 0 -4.445 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Value" "GND" (id 1) (at 0 -2.54 0)
+        (effects (font (size 1.27 1.27)))
+      )
+      (property "Footprint" "" (id 2) (at 0 0 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Datasheet" "" (id 3) (at 0 0 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (symbol "GND_0_1"
+        (polyline
+          (pts
+            (xy -1.905 -1.27)
+            (xy 1.905 -1.27)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+        (polyline
+          (pts
+            (xy 0 0)
+            (xy 0 -1.27)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+      )
+      (symbol "GND_1_1"
+        (pin power_in line (at 0 0 270) (length 0) hide
+          (name "GND" (effects (font (size 1.27 1.27))))
+          (number "1" (effects (font (size 1.27 1.27))))
+        )
+      )
+    )
+    (symbol "ataradov_pwr:VBUS" (power) (pin_names (offset 0)) (in_bom yes) (on_board yes)
+      (property "Reference" "#PWR" (id 0) (at 0 4.445 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Value" "VBUS" (id 1) (at 0 2.286 0)
+        (effects (font (size 1.27 1.27)))
+      )
+      (property "Footprint" "" (id 2) (at 0 0 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Datasheet" "" (id 3) (at 0 0 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (symbol "VBUS_0_1"
+        (polyline
+          (pts
+            (xy -1.905 1.27)
+            (xy 0 1.27)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+        (polyline
+          (pts
+            (xy 0 0)
+            (xy 0 1.27)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+        (polyline
+          (pts
+            (xy 0 1.27)
+            (xy 1.905 1.27)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+      )
+      (symbol "VBUS_1_1"
+        (pin power_in line (at 0 0 90) (length 0) hide
+          (name "VBUS" (effects (font (size 1.27 1.27))))
+          (number "1" (effects (font (size 1.27 1.27))))
+        )
+      )
+    )
+    (symbol "ataradov_rlc:C" (pin_numbers hide) (pin_names hide) (in_bom yes) (on_board yes)
+      (property "Reference" "C?" (id 0) (at 0.635 1.905 0)
+        (effects (font (size 1.27 1.27)) (justify left))
+      )
+      (property "Value" "C" (id 1) (at 0.635 -2.032 0)
+        (effects (font (size 1.27 1.27)) (justify left))
+      )
+      (property "Footprint" "ataradov_smd:0603" (id 2) (at 3.81 0 90)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Datasheet" "" (id 3) (at 0 0 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (symbol "C_0_1"
+        (polyline
+          (pts
+            (xy -1.905 -0.508)
+            (xy 1.905 -0.508)
+          )
+          (stroke (width 0.5) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+        (polyline
+          (pts
+            (xy -1.905 0.508)
+            (xy 1.905 0.508)
+          )
+          (stroke (width 0.5) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+      )
+      (symbol "C_1_1"
+        (pin passive line (at 0 -2.54 90) (length 1.905)
+          (name "1" (effects (font (size 1.27 1.27))))
+          (number "1" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at 0 2.54 270) (length 1.905)
+          (name "2" (effects (font (size 1.27 1.27))))
+          (number "2" (effects (font (size 1.27 1.27))))
+        )
+      )
+    )
+    (symbol "ataradov_rlc:R" (pin_numbers hide) (pin_names hide) (in_bom yes) (on_board yes)
+      (property "Reference" "R?" (id 0) (at 0 2.032 0)
+        (effects (font (size 1.27 1.27)))
+      )
+      (property "Value" "R" (id 1) (at 0 0 0)
+        (effects (font (size 1.016 1.016)))
+      )
+      (property "Footprint" "ataradov_smd:0603" (id 2) (at -0.508 -2.54 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Datasheet" "" (id 3) (at 0 0 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (symbol "R_0_1"
+        (rectangle (start -2.54 1.016) (end 2.54 -1.016)
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+      )
+      (symbol "R_1_1"
+        (pin passive line (at -3.81 0 0) (length 1.27)
+          (name "1" (effects (font (size 1.27 1.27))))
+          (number "1" (effects (font (size 1.27 1.27))))
+        )
+        (pin passive line (at 3.81 0 180) (length 1.27)
+          (name "2" (effects (font (size 1.27 1.27))))
+          (number "2" (effects (font (size 1.27 1.27))))
+        )
+      )
+    )
+    (symbol "ataradov_vreg:SC662K" (in_bom yes) (on_board yes)
+      (property "Reference" "IC?" (id 0) (at 0 6.35 0)
+        (effects (font (size 1.27 1.27)))
+      )
+      (property "Value" "SC662K" (id 1) (at 0 -3.81 0)
+        (effects (font (size 1.27 1.27)))
+      )
+      (property "Footprint" "ataradov_ic:SOT-23" (id 2) (at 0 -6.35 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Datasheet" "" (id 3) (at 0 0 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (symbol "SC662K_0_1"
+        (rectangle (start -5.08 5.08) (end 5.08 -2.54)
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type background))
+        )
+      )
+      (symbol "SC662K_1_1"
+        (pin power_in line (at -7.62 0 0) (length 2.54)
+          (name "GND" (effects (font (size 1.27 1.27))))
+          (number "1" (effects (font (size 1.27 1.27))))
+        )
+        (pin power_out line (at 7.62 2.54 180) (length 2.54)
+          (name "OUT" (effects (font (size 1.27 1.27))))
+          (number "2" (effects (font (size 1.27 1.27))))
+        )
+        (pin power_in line (at -7.62 2.54 0) (length 2.54)
+          (name "IN" (effects (font (size 1.27 1.27))))
+          (number "3" (effects (font (size 1.27 1.27))))
+        )
+      )
+    )
+    (symbol "power:PWR_FLAG" (power) (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes)
+      (property "Reference" "#FLG" (id 0) (at 0 1.905 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Value" "PWR_FLAG" (id 1) (at 0 3.81 0)
+        (effects (font (size 1.27 1.27)))
+      )
+      (property "Footprint" "" (id 2) (at 0 0 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "Datasheet" "~" (id 3) (at 0 0 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "ki_keywords" "power-flag" (id 4) (at 0 0 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (property "ki_description" "Special symbol for telling ERC where power comes from" (id 5) (at 0 0 0)
+        (effects (font (size 1.27 1.27)) hide)
+      )
+      (symbol "PWR_FLAG_0_0"
+        (pin power_out line (at 0 0 90) (length 0)
+          (name "pwr" (effects (font (size 1.27 1.27))))
+          (number "1" (effects (font (size 1.27 1.27))))
+        )
+      )
+      (symbol "PWR_FLAG_0_1"
+        (polyline
+          (pts
+            (xy 0 0)
+            (xy 0 1.27)
+            (xy -1.016 1.905)
+            (xy 0 2.54)
+            (xy 1.016 1.905)
+            (xy 0 1.27)
+          )
+          (stroke (width 0) (type default) (color 0 0 0 0))
+          (fill (type none))
+        )
+      )
+    )
+  )
+
+  (junction (at 72.39 71.12) (diameter 0) (color 0 0 0 0)
+    (uuid 13d14e22-7292-41c0-9503-e5c838361880)
+  )
+  (junction (at 72.39 68.58) (diameter 0) (color 0 0 0 0)
+    (uuid 3c41d82b-8405-4bfa-a9b5-f504becca4d7)
+  )
+  (junction (at 73.66 140.97) (diameter 0) (color 0 0 0 0)
+    (uuid 3f840ba8-88b8-4fc1-9c5c-292bbf94852b)
+  )
+  (junction (at 72.39 66.04) (diameter 0) (color 0 0 0 0)
+    (uuid 76d2fb0a-3949-4e96-a961-14367f8572ee)
+  )
+  (junction (at 72.39 55.88) (diameter 0) (color 0 0 0 0)
+    (uuid 7fa06e3f-644b-4b8a-acdd-46e2d6710ad7)
+  )
+  (junction (at 72.39 76.2) (diameter 0) (color 0 0 0 0)
+    (uuid 8d2d06c3-f3f9-4ba0-a25d-ef3f4dad3b9c)
+  )
+  (junction (at 147.32 55.88) (diameter 0) (color 0 0 0 0)
+    (uuid a6b0c3e4-0579-450a-9127-c31fb00c6692)
+  )
+  (junction (at 123.19 55.88) (diameter 0) (color 0 0 0 0)
+    (uuid a9696e43-3f81-4aa9-901f-150c6a0da3d7)
+  )
+  (junction (at 72.39 78.74) (diameter 0) (color 0 0 0 0)
+    (uuid b9f44169-38d2-4c75-8abc-ce01699774bb)
+  )
+  (junction (at 73.66 146.05) (diameter 0) (color 0 0 0 0)
+    (uuid c685073c-060b-41bd-aef7-91581b60c04b)
+  )
+  (junction (at 91.44 55.88) (diameter 0) (color 0 0 0 0)
+    (uuid d921ac40-acc6-423b-bfd8-c4851f3883ca)
+  )
+  (junction (at 91.44 60.96) (diameter 0) (color 0 0 0 0)
+    (uuid d957b265-4dfb-490e-8451-4fc54cc0fe94)
+  )
+
+  (wire (pts (xy 123.19 57.15) (xy 123.19 55.88))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 00633d47-9cbf-492d-bed4-85a8385cc5e4)
+  )
+  (wire (pts (xy 73.66 140.97) (xy 73.66 146.05))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 02ffca82-9430-4918-93a4-4370ded5af16)
+  )
+  (wire (pts (xy 88.9 71.12) (xy 93.98 71.12))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 080225d7-b073-4739-bf27-52f996e870be)
+  )
+  (wire (pts (xy 157.48 107.95) (xy 157.48 109.22))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 0bd27bb8-242f-4f0c-b5bf-1666e2009b71)
+  )
+  (wire (pts (xy 72.39 66.04) (xy 72.39 68.58))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 0cf40dd7-5817-483f-9d11-57a41b4ec132)
+  )
+  (wire (pts (xy 73.66 76.2) (xy 72.39 76.2))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 149525fb-328d-4bc6-83a1-83ed50c576b9)
+  )
+  (wire (pts (xy 99.06 68.58) (xy 99.06 72.39))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 1e63d159-a08a-443a-9fec-75c3c939d0b8)
+  )
+  (wire (pts (xy 157.48 114.3) (xy 160.02 114.3))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 2053487d-8135-4150-8098-928878d79142)
+  )
+  (wire (pts (xy 88.9 60.96) (xy 91.44 60.96))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 27cb0520-7d2d-45d1-943f-75311e6ac411)
+  )
+  (wire (pts (xy 199.39 110.49) (xy 201.93 110.49))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 2b8e51a2-b877-4660-a06f-e208ecf2ebac)
+  )
+  (wire (pts (xy 123.19 55.88) (xy 129.54 55.88))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 2f4d43f0-2c6f-40e4-b01b-d9f5f61213cf)
+  )
+  (wire (pts (xy 72.39 78.74) (xy 72.39 80.01))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 3c398f38-0d9a-4978-b0a3-bd2faaea9705)
+  )
+  (wire (pts (xy 73.66 138.43) (xy 76.2 138.43))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 3e9ef03e-9ff3-480b-993f-f00dcbda371b)
+  )
+  (wire (pts (xy 129.54 58.42) (xy 129.54 62.23))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 405e3491-1bb6-428b-81af-a8e410c94587)
+  )
+  (wire (pts (xy 157.48 116.84) (xy 160.02 116.84))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 4b8f23bc-3221-466e-8944-5461659b33a2)
+  )
+  (wire (pts (xy 132.08 111.76) (xy 129.54 111.76))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 4c340a85-603d-40bd-aa7a-a206f8627a35)
+  )
+  (wire (pts (xy 144.78 55.88) (xy 147.32 55.88))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 57de946c-8327-4e29-98fc-79d1179075c8)
+  )
+  (wire (pts (xy 88.9 68.58) (xy 99.06 68.58))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 5c40247e-5f02-469b-86e7-d7bb4f416cca)
+  )
+  (wire (pts (xy 129.54 114.3) (xy 132.08 114.3))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 5e43ff9e-afd4-4018-850d-662e08fd363b)
+  )
+  (wire (pts (xy 72.39 54.61) (xy 72.39 55.88))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 6699bb4c-e4d5-435e-9693-9c0516d322ad)
+  )
+  (wire (pts (xy 91.44 55.88) (xy 91.44 58.42))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 676dea48-0023-4cd1-a945-6994803a4f1b)
+  )
+  (wire (pts (xy 129.54 119.38) (xy 132.08 119.38))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 6a22192a-ff02-4d29-8aef-02d4d06ce5e1)
+  )
+  (wire (pts (xy 72.39 68.58) (xy 72.39 71.12))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 6b66a4fe-82c2-484e-b2b0-47e7ab549c52)
+  )
+  (wire (pts (xy 73.66 111.76) (xy 74.93 111.76))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 716cacd2-b62a-4296-9422-65b195c5029c)
+  )
+  (wire (pts (xy 147.32 57.15) (xy 147.32 55.88))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 731a378f-d234-4844-a1f0-f3e544bd6f27)
+  )
+  (wire (pts (xy 72.39 58.42) (xy 73.66 58.42))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 7b88745f-7df0-4577-b301-892773fe28e9)
+  )
+  (wire (pts (xy 72.39 78.74) (xy 73.66 78.74))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 7ceb1d65-5421-484d-87aa-13924aaae756)
+  )
+  (wire (pts (xy 157.48 121.92) (xy 160.02 121.92))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 7e16e382-e5f2-42f1-85f5-065b6d074030)
+  )
+  (wire (pts (xy 199.39 115.57) (xy 201.93 115.57))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 834b4e0b-e168-46bc-bb3f-e06dabfaa33c)
+  )
+  (wire (pts (xy 88.9 138.43) (xy 91.44 138.43))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 89261ac5-0564-4b1d-b017-242319b5fdb2)
+  )
+  (wire (pts (xy 88.9 58.42) (xy 91.44 58.42))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 906dec88-c6ae-4ac4-8821-e17d38435018)
+  )
+  (wire (pts (xy 129.54 116.84) (xy 132.08 116.84))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 934a13c2-54f2-4a76-824a-c770d27d3511)
+  )
+  (wire (pts (xy 88.9 135.89) (xy 91.44 135.89))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 974ddbc9-f8ee-4dc4-b05a-e1877f699b31)
+  )
+  (wire (pts (xy 91.44 55.88) (xy 93.98 55.88))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 9e66e55e-a977-46a0-89e3-16e50d413452)
+  )
+  (wire (pts (xy 72.39 71.12) (xy 72.39 76.2))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 9eafe17c-038c-473c-8052-312ba858c39c)
+  )
+  (wire (pts (xy 72.39 55.88) (xy 73.66 55.88))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid 9f32c03c-5ae6-4101-8e07-770072f65cc0)
+  )
+  (wire (pts (xy 157.48 124.46) (xy 157.48 125.73))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid a26e6b1b-0a07-473f-831c-21c2c3b390b9)
+  )
+  (wire (pts (xy 93.98 72.39) (xy 93.98 71.12))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid a3feaa53-0740-4255-8bbb-e470492ffb35)
+  )
+  (wire (pts (xy 88.9 55.88) (xy 91.44 55.88))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid a7dee156-9cb7-4378-88c2-445b299bdb4b)
+  )
+  (wire (pts (xy 73.66 113.03) (xy 73.66 111.76))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid a8ecb82a-a930-4b75-a49f-6cfed974c3b2)
+  )
+  (wire (pts (xy 123.19 54.61) (xy 123.19 55.88))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid a9cc9122-0c5d-492f-a732-d8fe9ef5c243)
+  )
+  (wire (pts (xy 72.39 76.2) (xy 72.39 78.74))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid b06665ba-7a4d-414f-b0a4-f93d2cb82c1e)
+  )
+  (wire (pts (xy 72.39 68.58) (xy 73.66 68.58))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid b18669f1-8123-45cb-b648-5a45107310c2)
+  )
+  (wire (pts (xy 73.66 146.05) (xy 76.2 146.05))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid b2f1d7d4-9f26-4775-98bf-e2d379b9aa15)
+  )
+  (wire (pts (xy 72.39 55.88) (xy 72.39 58.42))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid b3fd1879-6f20-4ba4-bd92-ac5be440ec16)
+  )
+  (wire (pts (xy 72.39 71.12) (xy 73.66 71.12))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid b76bd2c4-f6ae-4bb6-96d7-d909c747e724)
+  )
+  (wire (pts (xy 129.54 121.92) (xy 132.08 121.92))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid b8a5dc52-7eab-44b5-89c7-1bcb7bf04bc5)
+  )
+  (wire (pts (xy 88.9 63.5) (xy 91.44 63.5))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid bda5bd79-46d0-470f-978e-3a8f830bb866)
+  )
+  (wire (pts (xy 157.48 111.76) (xy 160.02 111.76))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid c02296bb-8160-4717-8315-3d29dace2c7f)
+  )
+  (wire (pts (xy 91.44 60.96) (xy 93.98 60.96))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid c31da7ac-0e84-49c9-a671-1085a8d3b053)
+  )
+  (wire (pts (xy 90.17 111.76) (xy 92.71 111.76))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid cc0dc745-9b61-4cd3-81f7-5853b83d005b)
+  )
+  (wire (pts (xy 73.66 138.43) (xy 73.66 140.97))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid d1aec2ed-ddb3-4d19-acc4-fb896cfbc372)
+  )
+  (wire (pts (xy 73.66 140.97) (xy 76.2 140.97))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid d3ba23cf-b750-40ae-a9d8-5fe48da4ee2d)
+  )
+  (wire (pts (xy 72.39 66.04) (xy 73.66 66.04))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid d48a1f87-90e2-4ea0-aae2-d1ddc0abc032)
+  )
+  (wire (pts (xy 157.48 119.38) (xy 160.02 119.38))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid dbf868ea-9434-48d0-aa76-bef7f902a821)
+  )
+  (wire (pts (xy 88.9 140.97) (xy 91.44 140.97))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid de79fa3b-5a21-4aa0-b062-88deb8e9dcc0)
+  )
+  (wire (pts (xy 147.32 54.61) (xy 147.32 55.88))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid dee29706-d442-4ee4-95b9-3db6d1df4fb2)
+  )
+  (wire (pts (xy 91.44 60.96) (xy 91.44 63.5))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid e1e8ab93-53e2-49b4-80f5-4568cb3bae24)
+  )
+  (wire (pts (xy 73.66 146.05) (xy 73.66 147.32))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid e340fb45-4e18-4168-a6d4-82c73c910a23)
+  )
+  (wire (pts (xy 72.39 63.5) (xy 72.39 66.04))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid ec35aedc-0227-4426-b6e5-73130c121b8b)
+  )
+  (wire (pts (xy 73.66 63.5) (xy 72.39 63.5))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid ef34c09e-65f0-4b13-841b-8f0b0585a46d)
+  )
+  (wire (pts (xy 88.9 146.05) (xy 91.44 146.05))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid f150141e-fd7a-4d6e-86b3-aac3c5be0358)
+  )
+  (wire (pts (xy 88.9 143.51) (xy 91.44 143.51))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid f59a2f9e-8c80-4895-ba5f-24a5623e1940)
+  )
+  (wire (pts (xy 199.39 113.03) (xy 201.93 113.03))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid fa2a1528-acb3-48a1-9e97-b7cad95e8f50)
+  )
+  (wire (pts (xy 129.54 124.46) (xy 132.08 124.46))
+    (stroke (width 0) (type default) (color 0 0 0 0))
+    (uuid fdb404c9-5607-4f4e-961f-aaa1814b16ca)
+  )
+
+  (text "Copyright (c) 2022, Alex Taradov <alex@taradov.com>\nFirmware source code is available at https://github.com/ataradov"
+    (at 13.97 201.93 0)
+    (effects (font (size 2 2)) (justify left bottom))
+    (uuid 50d092a1-cb48-4b36-9419-53ddb3f8fa14)
+  )
+
+  (label "RESET" (at 91.44 146.05 0)
+    (effects (font (size 1.27 1.27)) (justify left bottom))
+    (uuid 0225db91-a163-4a58-be52-eeb95876d0a2)
+  )
+  (label "RESET" (at 129.54 114.3 180)
+    (effects (font (size 1.27 1.27)) (justify right bottom))
+    (uuid 0f09a254-c97e-4a49-8d13-aa6e8a474a8c)
+  )
+  (label "SWDIO{slash}TMS" (at 91.44 135.89 0)
+    (effects (font (size 1.27 1.27)) (justify left bottom))
+    (uuid 0fb39ecb-bdaa-4a44-932c-00ba235f9106)
+  )
+  (label "SWCLK{slash}TCK" (at 91.44 138.43 0)
+    (effects (font (size 1.27 1.27)) (justify left bottom))
+    (uuid 267bc4c9-4a57-49fb-9a86-3c3394033036)
+  )
+  (label "TDO" (at 129.54 119.38 180)
+    (effects (font (size 1.27 1.27)) (justify right bottom))
+    (uuid 3fa02667-3249-405c-b9cf-e27e456460f6)
+  )
+  (label "USB_DP" (at 93.98 60.96 0)
+    (effects (font (size 1.27 1.27)) (justify left bottom))
+    (uuid 406284fa-6bb4-4270-a795-ab760f09e09f)
+  )
+  (label "DBG_RESET" (at 199.39 113.03 180)
+    (effects (font (size 1.27 1.27)) (justify right bottom))
+    (uuid 41b12ede-4402-4c73-8d6f-022bcfc153d3)
+  )
+  (label "USB_DP" (at 129.54 124.46 180)
+    (effects (font (size 1.27 1.27)) (justify right bottom))
+    (uuid 5759d820-3866-4228-8b37-97f569241e89)
+  )
+  (label "USB_DM" (at 93.98 55.88 0)
+    (effects (font (size 1.27 1.27)) (justify left bottom))
+    (uuid 6928b21e-2cf1-44b8-b5c8-be68c3e55645)
+  )
+  (label "DBG_RESET" (at 160.02 116.84 0)
+    (effects (font (size 1.27 1.27)) (justify left bottom))
+    (uuid 697d909a-e6fc-428c-aba5-823fe93fa5a6)
+  )
+  (label "DBG_SWCLK" (at 160.02 119.38 0)
+    (effects (font (size 1.27 1.27)) (justify left bottom))
+    (uuid 6e1db7e3-4b71-4806-8c9e-112e2d4ec47d)
+  )
+  (label "DBG_SWDIO" (at 160.02 121.92 0)
+    (effects (font (size 1.27 1.27)) (justify left bottom))
+    (uuid 7374600e-6b12-40c9-bddb-81c2c0dd958f)
+  )
+  (label "SWDIO{slash}TMS" (at 160.02 114.3 0)
+    (effects (font (size 1.27 1.27)) (justify left bottom))
+    (uuid 84fc0eb0-584a-4153-8a28-03bf18d72fe9)
+  )
+  (label "DBG_SWCLK" (at 199.39 110.49 180)
+    (effects (font (size 1.27 1.27)) (justify right bottom))
+    (uuid 88655a05-ccea-498e-9be2-fd3ccdea92e2)
+  )
+  (label "TDO" (at 91.44 140.97 0)
+    (effects (font (size 1.27 1.27)) (justify left bottom))
+    (uuid 8b64048c-7fa8-4958-981f-2eaeeac8f9af)
+  )
+  (label "SWCLK{slash}TCK" (at 160.02 111.76 0)
+    (effects (font (size 1.27 1.27)) (justify left bottom))
+    (uuid 9d4a9182-5300-48aa-a5a4-edf55896fc62)
+  )
+  (label "TDI" (at 129.54 116.84 180)
+    (effects (font (size 1.27 1.27)) (justify right bottom))
+    (uuid adbb91e5-fc98-4c11-b5cc-41655d290c8d)
+  )
+  (label "DBG_SWDIO" (at 199.39 115.57 180)
+    (effects (font (size 1.27 1.27)) (justify right bottom))
+    (uuid ae2f6ccf-5df0-4d19-b53c-1c652197c3af)
+  )
+  (label "DAP_STATUS" (at 92.71 111.76 0)
+    (effects (font (size 1.27 1.27)) (justify left bottom))
+    (uuid b733bd6d-60a4-4819-949f-403e8cd0b45d)
+  )
+  (label "TDI" (at 91.44 143.51 0)
+    (effects (font (size 1.27 1.27)) (justify left bottom))
+    (uuid bf012cd6-b906-4e5b-af0c-c074a0c1d6a0)
+  )
+  (label "DAP_STATUS" (at 129.54 111.76 180)
+    (effects (font (size 1.27 1.27)) (justify right bottom))
+    (uuid e8217ef5-eef7-4a47-ad84-fb66c9b3469f)
+  )
+  (label "USB_DM" (at 129.54 121.92 180)
+    (effects (font (size 1.27 1.27)) (justify right bottom))
+    (uuid e83de5ae-0187-4a90-9f8d-b8a5bfc8d184)
+  )
+
+  (symbol (lib_id "ataradov_rlc:C") (at 147.32 59.69 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 03c058db-b9f4-404f-9c24-1f1dab858e28)
+    (property "Reference" "C2" (id 0) (at 147.955 57.785 0)
+      (effects (font (size 1.27 1.27)) (justify left))
+    )
+    (property "Value" "1uF" (id 1) (at 147.955 61.722 0)
+      (effects (font (size 1.27 1.27)) (justify left))
+    )
+    (property "Footprint" "ataradov_smd:0603" (id 2) (at 151.13 59.69 90)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 147.32 59.69 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid 0a7d999d-c76d-4114-8820-795cba286d73))
+    (pin "2" (uuid c3d6d463-954a-4c29-9ddb-4bb57be684cb))
+  )
+
+  (symbol (lib_id "ataradov_pwr:GND") (at 93.98 80.01 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 05e9ef89-9155-44fd-8508-5e0c3fb064ae)
+    (property "Reference" "#PWR010" (id 0) (at 93.98 84.455 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "GND" (id 1) (at 93.98 82.55 0))
+    (property "Footprint" "" (id 2) (at 93.98 80.01 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 93.98 80.01 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid af33b692-45d2-4586-8e95-e4c4b30ce752))
+  )
+
+  (symbol (lib_id "ataradov_pwr:GND") (at 73.66 113.03 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 0757abbd-54c6-4c08-a50f-6bd1d1a846df)
+    (property "Reference" "#PWR013" (id 0) (at 73.66 117.475 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "GND" (id 1) (at 73.66 115.57 0))
+    (property "Footprint" "" (id 2) (at 73.66 113.03 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 73.66 113.03 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid 372dddc1-cb4f-4294-9fc4-ca7f615d3d36))
+  )
+
+  (symbol (lib_id "ataradov_pwr:GND") (at 147.32 62.23 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 26820f5c-8822-4371-879b-2c5fdeb709c6)
+    (property "Reference" "#PWR08" (id 0) (at 147.32 66.675 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "GND" (id 1) (at 147.32 64.77 0))
+    (property "Footprint" "" (id 2) (at 147.32 62.23 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 147.32 62.23 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid 3bef0362-242d-46c4-b651-9d41a3c29516))
+  )
+
+  (symbol (lib_id "ataradov_rlc:R") (at 93.98 76.2 90) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 35477d2d-d398-4f18-becb-e7baa5331236)
+    (property "Reference" "R1" (id 0) (at 91.948 76.2 0))
+    (property "Value" "" (id 1) (at 93.98 76.2 0)
+      (effects (font (size 1.016 1.016)))
+    )
+    (property "Footprint" "ataradov_smd:0603" (id 2) (at 96.52 76.708 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 93.98 76.2 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid aef499ec-a824-4421-9454-07582d251979))
+    (pin "2" (uuid c6669998-ea80-4d30-b026-ce57aa91ad9f))
+  )
+
+  (symbol (lib_id "ataradov_misc:TestPoint") (at 201.93 113.03 0) (mirror x) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 6173c660-2127-4241-96b1-bfeb7449ff5f)
+    (property "Reference" "TP2" (id 0) (at 204.47 113.03 0)
+      (effects (font (size 1.27 1.27)) (justify left))
+    )
+    (property "Value" "RST" (id 1) (at 209.55 113.03 0)
+      (effects (font (size 1.27 1.27)) (justify left))
+    )
+    (property "Footprint" "ataradov_misc:TestPoint-1.27mm-SMD" (id 2) (at 201.93 110.49 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 201.93 113.03 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid f3c120bd-69cb-4894-8bb2-219d2612edf6))
+  )
+
+  (symbol (lib_id "power:PWR_FLAG") (at 175.26 54.61 180) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 65803744-5fc3-48eb-aeb5-74da1b7d8a05)
+    (property "Reference" "#FLG01" (id 0) (at 175.26 56.515 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "PWR_FLAG" (id 1) (at 175.26 58.42 0))
+    (property "Footprint" "" (id 2) (at 175.26 54.61 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "~" (id 3) (at 175.26 54.61 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid a25e7a0e-3568-41c7-8781-638712835b6d))
+  )
+
+  (symbol (lib_id "ataradov_pwr:+3V3") (at 147.32 54.61 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 6b77c6b8-330f-44c5-82f1-264745164425)
+    (property "Reference" "#PWR03" (id 0) (at 147.32 50.165 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "+3V3" (id 1) (at 147.32 52.324 0))
+    (property "Footprint" "" (id 2) (at 147.32 54.61 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 147.32 54.61 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid 544f0905-f177-4c0c-b536-d1ae7c0db5ae))
+  )
+
+  (symbol (lib_id "ataradov_led:LED") (at 86.36 111.76 0) (mirror y) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 6bc6f722-72ae-42d6-be95-2b8bf65cd61e)
+    (property "Reference" "LED1" (id 0) (at 86.36 109.22 0))
+    (property "Value" "Orange" (id 1) (at 86.36 114.3 0))
+    (property "Footprint" "ataradov_smd:0603" (id 2) (at 86.36 115.9764 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 81.661 115.951 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid 1caee53e-2f65-44a1-b0a6-628f6771d0f3))
+    (pin "2" (uuid d54c882f-01a3-47ff-b805-a1cce42998db))
+  )
+
+  (symbol (lib_id "ataradov_rlc:R") (at 99.06 76.2 90) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 6e18622d-ab16-46d3-8547-8e9d6c8c3481)
+    (property "Reference" "R2" (id 0) (at 97.028 76.2 0))
+    (property "Value" "" (id 1) (at 99.06 76.2 0)
+      (effects (font (size 1.016 1.016)))
+    )
+    (property "Footprint" "ataradov_smd:0603" (id 2) (at 101.6 76.708 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 99.06 76.2 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid a2d8cec1-70fc-41aa-8ef4-4a25f56b53e0))
+    (pin "2" (uuid 5fbb5b31-843e-4091-87eb-d5903ebdb358))
+  )
+
+  (symbol (lib_id "ataradov_pwr:GND") (at 157.48 125.73 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 7374bcb7-15af-4d0f-999a-8281ae765e32)
+    (property "Reference" "#PWR015" (id 0) (at 157.48 130.175 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "GND" (id 1) (at 157.48 128.27 0))
+    (property "Footprint" "" (id 2) (at 157.48 125.73 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 157.48 125.73 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid bb245c7e-ec50-452a-a17f-bf93af815a5a))
+  )
+
+  (symbol (lib_id "ataradov_pwr:GND") (at 123.19 62.23 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 739b591f-ee89-4e4b-a089-6321966edc77)
+    (property "Reference" "#PWR06" (id 0) (at 123.19 66.675 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "GND" (id 1) (at 123.19 64.77 0))
+    (property "Footprint" "" (id 2) (at 123.19 62.23 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 123.19 62.23 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid 0ddd913a-01fd-481e-b154-5f1b5423e9cd))
+  )
+
+  (symbol (lib_id "ataradov_pwr:VBUS") (at 175.26 54.61 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 795c085a-5839-4b20-9612-e1f68b728c60)
+    (property "Reference" "#PWR04" (id 0) (at 175.26 50.165 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "VBUS" (id 1) (at 175.26 52.324 0))
+    (property "Footprint" "" (id 2) (at 175.26 54.61 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 175.26 54.61 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid 951cf345-da87-4fdd-b04a-95e684d5e266))
+  )
+
+  (symbol (lib_id "ataradov_pwr:+3V3") (at 157.48 107.95 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 7e3716c6-bd4b-4b73-bf20-cfdce2a449e5)
+    (property "Reference" "#PWR012" (id 0) (at 157.48 103.505 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "+3V3" (id 1) (at 157.48 105.664 0))
+    (property "Footprint" "" (id 2) (at 157.48 107.95 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 157.48 107.95 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid d611e538-085f-4765-90b4-94ca28ea34f0))
+  )
+
+  (symbol (lib_id "ataradov_misc:TestPoint") (at 201.93 115.57 0) (mirror x) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 87a0447f-dae7-4542-8125-f968e31d4a91)
+    (property "Reference" "TP3" (id 0) (at 204.47 115.57 0)
+      (effects (font (size 1.27 1.27)) (justify left))
+    )
+    (property "Value" "SIO" (id 1) (at 209.55 115.57 0)
+      (effects (font (size 1.27 1.27)) (justify left))
+    )
+    (property "Footprint" "ataradov_misc:TestPoint-1.27mm-SMD" (id 2) (at 201.93 113.03 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 201.93 115.57 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid b81c865d-107f-4ae5-bc0f-296174c9d79b))
+  )
+
+  (symbol (lib_id "ataradov_conn:Conn-5x2") (at 82.55 140.97 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 906df0a0-5839-47c0-b332-cec00bfc8d50)
+    (property "Reference" "J2" (id 0) (at 82.55 133.35 0))
+    (property "Value" "" (id 1) (at 82.55 148.59 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Footprint" "" (id 2) (at 82.55 151.13 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 111.76 127 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid de759948-161e-4bbe-93f4-670a576de500))
+    (pin "10" (uuid caa4298d-02d5-4f80-9b9d-47f1bd739f15))
+    (pin "2" (uuid eea8afc9-500b-4e96-9580-ce3dbde5cd58))
+    (pin "3" (uuid 0a742bb2-0657-47bc-9dea-e70308e1113a))
+    (pin "4" (uuid 9a87bfc4-c304-4037-8ceb-f6545574a9e8))
+    (pin "5" (uuid 8b398452-7864-4ae1-87b2-f3c31f993db8))
+    (pin "6" (uuid bea25862-abba-489f-bceb-f737bbb678c5))
+    (pin "7" (uuid 4ce03590-e0e1-4703-b46c-7b385c2aeba2))
+    (pin "8" (uuid f294a229-6752-4bf0-afcf-4e666738928a))
+    (pin "9" (uuid 5b9a3805-90b0-44a6-a86e-5b6c07ff9037))
+  )
+
+  (symbol (lib_id "ataradov_conn:USB-C") (at 81.28 66.04 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid 9b533e2a-a396-4b85-abf3-b4e562338c74)
+    (property "Reference" "J1" (id 0) (at 81.28 53.34 0))
+    (property "Value" "" (id 1) (at 81.28 81.28 0))
+    (property "Footprint" "" (id 2) (at 81.28 83.82 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 85.09 71.12 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "CC1" (uuid 7f9b3afe-36aa-4100-8eb1-fe067dbbac71))
+    (pin "CC2" (uuid da17c545-f7d6-4b7a-b32a-9980c1fdd5ea))
+    (pin "D+1" (uuid ceeaa25e-5dd0-4b0b-abeb-d03824759358))
+    (pin "D+2" (uuid a7f9e962-df3d-48ec-bb65-e4cd721b1fdb))
+    (pin "D-1" (uuid ae41ddc8-040a-4a4c-a52c-c9a78e4e42c9))
+    (pin "D-2" (uuid 4d3f805b-53d2-4562-81c5-c956db5aea1d))
+    (pin "GND1" (uuid 3abc7d0d-7f0b-4ca9-ad83-e4dc3d16650e))
+    (pin "GND2" (uuid eee0e712-9905-455b-9345-42af9d32ddf8))
+    (pin "S1" (uuid 6995d692-6799-4a4b-8ee5-526e62999268))
+    (pin "S2" (uuid 3407777c-d948-490d-a2f0-b3ad3390e217))
+    (pin "S3" (uuid f4ad0534-361a-4967-ab71-475e6d58c79b))
+    (pin "S4" (uuid 765e88c2-7918-4daa-8f5e-e11a684828f1))
+    (pin "SBU1" (uuid 7c289ea3-a8eb-4bf9-bc4d-6cc10ec3f1c3))
+    (pin "SBU2" (uuid 0fa66da5-0371-4282-aa61-1dab22b21bd0))
+    (pin "VBUS1" (uuid c417a097-3716-42e2-a277-85bd091132c6))
+    (pin "VBUS2" (uuid d9f9cd76-2103-4a02-8698-c124fe624175))
+  )
+
+  (symbol (lib_id "ataradov_pwr:GND") (at 184.15 55.88 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid a4dc6caf-b167-4179-b6fc-f87da0aed1f2)
+    (property "Reference" "#PWR05" (id 0) (at 184.15 60.325 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "GND" (id 1) (at 184.15 58.42 0))
+    (property "Footprint" "" (id 2) (at 184.15 55.88 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 184.15 55.88 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid 9fef8c21-7687-44b2-9ae5-c73b7fddcb3d))
+  )
+
+  (symbol (lib_id "ataradov_misc:TestPoint") (at 201.93 110.49 0) (mirror x) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid bc214495-6305-49a3-bba3-3efe658c8dd7)
+    (property "Reference" "TP1" (id 0) (at 204.47 110.49 0)
+      (effects (font (size 1.27 1.27)) (justify left))
+    )
+    (property "Value" "SCK" (id 1) (at 209.55 110.49 0)
+      (effects (font (size 1.27 1.27)) (justify left))
+    )
+    (property "Footprint" "ataradov_misc:TestPoint-1.27mm-SMD" (id 2) (at 201.93 107.95 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 201.93 110.49 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid 7f901230-db95-48f1-ae4e-c62dd2ac69be))
+  )
+
+  (symbol (lib_id "ataradov_rlc:R") (at 78.74 111.76 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid c594dcf2-f562-4ebf-9380-711463f31929)
+    (property "Reference" "R3" (id 0) (at 78.74 109.728 0))
+    (property "Value" "20K" (id 1) (at 78.74 111.76 0)
+      (effects (font (size 1.016 1.016)))
+    )
+    (property "Footprint" "ataradov_smd:0603" (id 2) (at 78.232 114.3 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 78.74 111.76 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid 23443ffc-e38c-4bb1-83e7-faaa59cc3785))
+    (pin "2" (uuid e75e898f-9689-4e61-8182-ec9e9a207da3))
+  )
+
+  (symbol (lib_id "ataradov_pwr:GND") (at 129.54 62.23 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid c860c4e9-3ddd-4065-857c-b9aedc01e6ad)
+    (property "Reference" "#PWR07" (id 0) (at 129.54 66.675 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "GND" (id 1) (at 129.54 64.77 0))
+    (property "Footprint" "" (id 2) (at 129.54 62.23 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 129.54 62.23 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid ed1f5df2-cfb6-4083-a9e5-5d196546ef9b))
+  )
+
+  (symbol (lib_id "ataradov_pwr:GND") (at 72.39 80.01 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid d2299eed-477d-40aa-a7fd-92b8ce1c4acf)
+    (property "Reference" "#PWR09" (id 0) (at 72.39 84.455 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "GND" (id 1) (at 72.39 82.55 0))
+    (property "Footprint" "" (id 2) (at 72.39 80.01 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 72.39 80.01 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid 201d29c8-a0c2-462d-859b-6663f4546f75))
+  )
+
+  (symbol (lib_id "ataradov_pwr:GND") (at 99.06 80.01 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid dd61e408-7346-40a4-9cb9-99cd36090419)
+    (property "Reference" "#PWR011" (id 0) (at 99.06 84.455 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "GND" (id 1) (at 99.06 82.55 0))
+    (property "Footprint" "" (id 2) (at 99.06 80.01 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 99.06 80.01 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid 6a2c7e89-94bb-4d4b-9a3d-5734b3add4f2))
+  )
+
+  (symbol (lib_id "ataradov_rlc:C") (at 123.19 59.69 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid e06501c8-2845-4054-9787-05ce88080176)
+    (property "Reference" "C1" (id 0) (at 123.825 57.785 0)
+      (effects (font (size 1.27 1.27)) (justify left))
+    )
+    (property "Value" "1uF" (id 1) (at 123.825 61.722 0)
+      (effects (font (size 1.27 1.27)) (justify left))
+    )
+    (property "Footprint" "ataradov_smd:0603" (id 2) (at 127 59.69 90)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 123.19 59.69 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid b1505178-62d2-4d69-88ca-4f0742d8c5a2))
+    (pin "2" (uuid 61f79dbe-baa7-4106-9905-30750859d682))
+  )
+
+  (symbol (lib_id "ataradov_vreg:SC662K") (at 137.16 58.42 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid e254f06c-00a2-4056-b804-b955996fa3d5)
+    (property "Reference" "IC1" (id 0) (at 137.16 52.07 0))
+    (property "Value" "SC662K-3.3" (id 1) (at 137.16 62.23 0))
+    (property "Footprint" "ataradov_ic:SOT-23" (id 2) (at 137.16 64.77 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 137.16 58.42 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid 907de315-5217-430d-b87e-7673d46e929e))
+    (pin "2" (uuid fa214dfc-a5ff-4252-a326-6f007fc38fde))
+    (pin "3" (uuid 44e9d130-6d17-4ee2-b86d-7a2ffde0c0ff))
+  )
+
+  (symbol (lib_id "ataradov_pwr:VBUS") (at 72.39 54.61 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid e92fc636-6f09-4bcf-996b-40649153e556)
+    (property "Reference" "#PWR01" (id 0) (at 72.39 50.165 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "VBUS" (id 1) (at 72.39 52.324 0))
+    (property "Footprint" "" (id 2) (at 72.39 54.61 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 72.39 54.61 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid fd6083ca-e8b1-4b71-9edd-8b06964fad29))
+  )
+
+  (symbol (lib_id "ataradov_mcu:ATSAMD11C") (at 144.78 116.84 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid e9485002-0b5c-4f78-8d49-67004f0e4d8e)
+    (property "Reference" "IC2" (id 0) (at 144.78 105.41 0))
+    (property "Value" "ATSAMD11C" (id 1) (at 144.78 128.27 0))
+    (property "Footprint" "ataradov_ic:SOIC-14" (id 2) (at 144.78 130.81 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 144.78 116.84 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid 9d78b31d-4604-41f8-bd2f-6bf3c6f87fcd))
+    (pin "10" (uuid 0f59edd7-091a-4b03-9db4-f89c4aa2ce4b))
+    (pin "11" (uuid 6efc737d-5135-429a-aae1-4335391c7bac))
+    (pin "12" (uuid 0e04b0ed-ca5f-42bc-97c7-7b04bb57f514))
+    (pin "13" (uuid 12fefc7a-f21a-476e-82ac-997696b2b60a))
+    (pin "14" (uuid 4f528367-4751-43d7-ba58-d03bc3b75f4a))
+    (pin "2" (uuid 74d14a6f-b874-4afa-ad65-39b56f4a32f6))
+    (pin "3" (uuid f98fc2f0-80e4-4d83-a86d-fdfc8aa394a0))
+    (pin "4" (uuid 5594bf53-47e6-4576-b174-45ab94b82260))
+    (pin "5" (uuid 3eb4c8a6-373f-4727-aee6-c561980ec54b))
+    (pin "6" (uuid 954cd08a-048f-483e-958c-dbe0db840f6b))
+    (pin "7" (uuid 07709db1-af60-4425-ba05-9c0d19a65145))
+    (pin "8" (uuid 8967ff6c-b2ae-4efc-90ef-0dbcc74e6b71))
+    (pin "9" (uuid 81d84ff2-5e6b-4ed1-9a8f-e1c4aa71e796))
+  )
+
+  (symbol (lib_id "ataradov_pwr:GND") (at 73.66 147.32 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid ec2382c6-f67b-4899-959e-d04de4aba0e2)
+    (property "Reference" "#PWR016" (id 0) (at 73.66 151.765 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "GND" (id 1) (at 73.66 149.86 0))
+    (property "Footprint" "" (id 2) (at 73.66 147.32 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 73.66 147.32 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid f602f74b-e606-42d0-aab7-713f25f1f15d))
+  )
+
+  (symbol (lib_id "power:PWR_FLAG") (at 184.15 55.88 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid f43c2fc6-cae3-4670-bdc3-d8ccd28d5859)
+    (property "Reference" "#FLG02" (id 0) (at 184.15 53.975 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "PWR_FLAG" (id 1) (at 184.15 52.07 0))
+    (property "Footprint" "" (id 2) (at 184.15 55.88 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "~" (id 3) (at 184.15 55.88 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid 09274162-ac4a-4d4a-a141-bf8c133f61f6))
+  )
+
+  (symbol (lib_id "ataradov_pwr:VBUS") (at 123.19 54.61 0) (unit 1)
+    (in_bom yes) (on_board yes)
+    (uuid fdfdc927-8119-42ff-858e-0c98d51b2e84)
+    (property "Reference" "#PWR02" (id 0) (at 123.19 50.165 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Value" "VBUS" (id 1) (at 123.19 52.324 0))
+    (property "Footprint" "" (id 2) (at 123.19 54.61 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (property "Datasheet" "" (id 3) (at 123.19 54.61 0)
+      (effects (font (size 1.27 1.27)) hide)
+    )
+    (pin "1" (uuid d245a507-8a19-481d-a05d-417eb2477646))
+  )
+
+  (sheet_instances
+    (path "/" (page "1"))
+  )
+
+  (symbol_instances
+    (path "/65803744-5fc3-48eb-aeb5-74da1b7d8a05"
+      (reference "#FLG01") (unit 1) (value "PWR_FLAG") (footprint "")
+    )
+    (path "/f43c2fc6-cae3-4670-bdc3-d8ccd28d5859"
+      (reference "#FLG02") (unit 1) (value "PWR_FLAG") (footprint "")
+    )
+    (path "/e92fc636-6f09-4bcf-996b-40649153e556"
+      (reference "#PWR01") (unit 1) (value "VBUS") (footprint "")
+    )
+    (path "/fdfdc927-8119-42ff-858e-0c98d51b2e84"
+      (reference "#PWR02") (unit 1) (value "VBUS") (footprint "")
+    )
+    (path "/6b77c6b8-330f-44c5-82f1-264745164425"
+      (reference "#PWR03") (unit 1) (value "+3V3") (footprint "")
+    )
+    (path "/795c085a-5839-4b20-9612-e1f68b728c60"
+      (reference "#PWR04") (unit 1) (value "VBUS") (footprint "")
+    )
+    (path "/a4dc6caf-b167-4179-b6fc-f87da0aed1f2"
+      (reference "#PWR05") (unit 1) (value "GND") (footprint "")
+    )
+    (path "/739b591f-ee89-4e4b-a089-6321966edc77"
+      (reference "#PWR06") (unit 1) (value "GND") (footprint "")
+    )
+    (path "/c860c4e9-3ddd-4065-857c-b9aedc01e6ad"
+      (reference "#PWR07") (unit 1) (value "GND") (footprint "")
+    )
+    (path "/26820f5c-8822-4371-879b-2c5fdeb709c6"
+      (reference "#PWR08") (unit 1) (value "GND") (footprint "")
+    )
+    (path "/d2299eed-477d-40aa-a7fd-92b8ce1c4acf"
+      (reference "#PWR09") (unit 1) (value "GND") (footprint "")
+    )
+    (path "/05e9ef89-9155-44fd-8508-5e0c3fb064ae"
+      (reference "#PWR010") (unit 1) (value "GND") (footprint "")
+    )
+    (path "/dd61e408-7346-40a4-9cb9-99cd36090419"
+      (reference "#PWR011") (unit 1) (value "GND") (footprint "")
+    )
+    (path "/7e3716c6-bd4b-4b73-bf20-cfdce2a449e5"
+      (reference "#PWR012") (unit 1) (value "+3V3") (footprint "")
+    )
+    (path "/0757abbd-54c6-4c08-a50f-6bd1d1a846df"
+      (reference "#PWR013") (unit 1) (value "GND") (footprint "")
+    )
+    (path "/7374bcb7-15af-4d0f-999a-8281ae765e32"
+      (reference "#PWR015") (unit 1) (value "GND") (footprint "")
+    )
+    (path "/ec2382c6-f67b-4899-959e-d04de4aba0e2"
+      (reference "#PWR016") (unit 1) (value "GND") (footprint "")
+    )
+    (path "/e06501c8-2845-4054-9787-05ce88080176"
+      (reference "C1") (unit 1) (value "1uF") (footprint "ataradov_smd:0603")
+    )
+    (path "/03c058db-b9f4-404f-9c24-1f1dab858e28"
+      (reference "C2") (unit 1) (value "1uF") (footprint "ataradov_smd:0603")
+    )
+    (path "/e254f06c-00a2-4056-b804-b955996fa3d5"
+      (reference "IC1") (unit 1) (value "SC662K-3.3") (footprint "ataradov_ic:SOT-23")
+    )
+    (path "/e9485002-0b5c-4f78-8d49-67004f0e4d8e"
+      (reference "IC2") (unit 1) (value "ATSAMD11C") (footprint "ataradov_ic:SOIC-14")
+    )
+    (path "/9b533e2a-a396-4b85-abf3-b4e562338c74"
+      (reference "J1") (unit 1) (value "USB-C") (footprint "ataradov_conn:USB-C")
+    )
+    (path "/906df0a0-5839-47c0-b332-cec00bfc8d50"
+      (reference "J2") (unit 1) (value "Conn-5x2") (footprint "ataradov_conn:Header-5x2-1.27mm-SMD")
+    )
+    (path "/6bc6f722-72ae-42d6-be95-2b8bf65cd61e"
+      (reference "LED1") (unit 1) (value "Orange") (footprint "ataradov_smd:0603")
+    )
+    (path "/35477d2d-d398-4f18-becb-e7baa5331236"
+      (reference "R1") (unit 1) (value "5.1K") (footprint "ataradov_smd:0603")
+    )
+    (path "/6e18622d-ab16-46d3-8547-8e9d6c8c3481"
+      (reference "R2") (unit 1) (value "5.1K") (footprint "ataradov_smd:0603")
+    )
+    (path "/c594dcf2-f562-4ebf-9380-711463f31929"
+      (reference "R3") (unit 1) (value "20K") (footprint "ataradov_smd:0603")
+    )
+    (path "/bc214495-6305-49a3-bba3-3efe658c8dd7"
+      (reference "TP1") (unit 1) (value "SCK") (footprint "ataradov_misc:TestPoint-1.27mm-SMD")
+    )
+    (path "/6173c660-2127-4241-96b1-bfeb7449ff5f"
+      (reference "TP2") (unit 1) (value "RST") (footprint "ataradov_misc:TestPoint-1.27mm-SMD")
+    )
+    (path "/87a0447f-dae7-4542-8125-f968e31d4a91"
+      (reference "TP3") (unit 1) (value "SIO") (footprint "ataradov_misc:TestPoint-1.27mm-SMD")
+    )
+  )
+)

BIN
dap_link/lib/free-dap/hardware/d11-nano-dbg/d11-nano-dbg.pdf


+ 5 - 0
dap_link/lib/free-dap/hardware/d11-nano-dbg/pcb.kicad_wks

@@ -0,0 +1,5 @@
+(kicad_wks (version 20210606) (generator pl_editor)
+  (setup (textsize 1.5 1.5)(linewidth 0.15)(textlinewidth 0.15)
+  (left_margin 10)(right_margin 10)(top_margin 10)(bottom_margin 10))
+  (line (name "segm1:Line") (start 0 0) (end 0 0))
+)

+ 15 - 0
dap_link/lib/free-dap/hardware/d11-nano-dbg/sch.kicad_wks

@@ -0,0 +1,15 @@
+(kicad_wks (version 20210606) (generator pl_editor)
+  (setup (textsize 1.5 1.5)(linewidth 0.15)(textlinewidth 0.15)
+  (left_margin 10)(right_margin 10)(top_margin 10)(bottom_margin 10))
+  (rect (name "") (start 0 0 ltcorner) (end 0 0) (repeat 2) (incrx 2) (incry 2))
+  (line (name "") (start 50 2 ltcorner) (end 50 0 ltcorner) (repeat 30) (incrx 50))
+  (tbtext "1" (name "") (pos 25 1 ltcorner) (font (size 1.3 1.3)) (repeat 100) (incrx 50))
+  (line (name "") (start 50 2 lbcorner) (end 50 0 lbcorner) (repeat 30) (incrx 50))
+  (tbtext "1" (name "") (pos 25 1 lbcorner) (font (size 1.3 1.3)) (repeat 100) (incrx 50))
+  (line (name "") (start 0 50 ltcorner) (end 2 50 ltcorner) (repeat 30) (incry 50))
+  (tbtext "A" (name "") (pos 1 25 ltcorner) (font (size 1.3 1.3)) (justify center) (repeat 100) (incry 50))
+  (line (name "") (start 0 50 rtcorner) (end 2 50 rtcorner) (repeat 30) (incry 50))
+  (tbtext "A" (name "") (pos 1 25 rtcorner) (font (size 1.3 1.3)) (justify center) (repeat 100) (incry 50))
+  (tbtext "${TITLE}${SHEETNAME} ${FILENAME}, rev ${REVISION} (${ISSUE_DATE}), page ${#} of ${##}" (name "") (pos 3 4) (justify right) (comment "Sheet id")
+)
+)

+ 700 - 0
dap_link/lib/free-dap/hardware/d11_micro_std_vcp/d11_micro_std_vcp.brd

@@ -0,0 +1,700 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE eagle SYSTEM "eagle.dtd">
+<eagle version="7.3.0">
+<drawing>
+<settings>
+<setting alwaysvectorfont="no"/>
+<setting verticaltext="up"/>
+</settings>
+<grid distance="0.01" unitdist="inch" unit="inch" style="lines" multiple="1" display="no" altdistance="0.025" altunitdist="inch" altunit="inch"/>
+<layers>
+<layer number="1" name="Top" color="4" fill="1" visible="yes" active="yes"/>
+<layer number="16" name="Bottom" color="1" fill="1" visible="yes" active="yes"/>
+<layer number="17" name="Pads" color="2" fill="1" visible="yes" active="yes"/>
+<layer number="18" name="Vias" color="2" fill="1" visible="yes" active="yes"/>
+<layer number="19" name="Unrouted" color="6" fill="1" visible="yes" active="yes"/>
+<layer number="20" name="Dimension" color="15" fill="1" visible="yes" active="yes"/>
+<layer number="21" name="tPlace" color="7" fill="1" visible="yes" active="yes"/>
+<layer number="22" name="bPlace" color="7" fill="1" visible="yes" active="yes"/>
+<layer number="23" name="tOrigins" color="15" fill="1" visible="yes" active="yes"/>
+<layer number="24" name="bOrigins" color="15" fill="1" visible="yes" active="yes"/>
+<layer number="25" name="tNames" color="7" fill="1" visible="no" active="yes"/>
+<layer number="26" name="bNames" color="7" fill="1" visible="no" active="yes"/>
+<layer number="27" name="tValues" color="7" fill="1" visible="yes" active="yes"/>
+<layer number="28" name="bValues" color="7" fill="1" visible="yes" active="yes"/>
+<layer number="29" name="tStop" color="7" fill="3" visible="no" active="yes"/>
+<layer number="30" name="bStop" color="7" fill="6" visible="no" active="yes"/>
+<layer number="31" name="tCream" color="7" fill="4" visible="no" active="yes"/>
+<layer number="32" name="bCream" color="7" fill="5" visible="no" active="yes"/>
+<layer number="33" name="tFinish" color="6" fill="3" visible="no" active="yes"/>
+<layer number="34" name="bFinish" color="6" fill="6" visible="no" active="yes"/>
+<layer number="35" name="tGlue" color="7" fill="4" visible="no" active="yes"/>
+<layer number="36" name="bGlue" color="7" fill="5" visible="no" active="yes"/>
+<layer number="37" name="tTest" color="7" fill="1" visible="no" active="yes"/>
+<layer number="38" name="bTest" color="7" fill="1" visible="no" active="yes"/>
+<layer number="39" name="tKeepout" color="4" fill="11" visible="yes" active="yes"/>
+<layer number="40" name="bKeepout" color="1" fill="11" visible="yes" active="yes"/>
+<layer number="41" name="tRestrict" color="4" fill="10" visible="yes" active="yes"/>
+<layer number="42" name="bRestrict" color="1" fill="10" visible="yes" active="yes"/>
+<layer number="43" name="vRestrict" color="2" fill="10" visible="yes" active="yes"/>
+<layer number="44" name="Drills" color="7" fill="1" visible="no" active="yes"/>
+<layer number="45" name="Holes" color="7" fill="1" visible="no" active="yes"/>
+<layer number="46" name="Milling" color="3" fill="1" visible="no" active="yes"/>
+<layer number="47" name="Measures" color="7" fill="1" visible="no" active="yes"/>
+<layer number="48" name="Document" color="7" fill="1" visible="yes" active="yes"/>
+<layer number="49" name="Reference" color="7" fill="1" visible="yes" active="yes"/>
+<layer number="51" name="tDocu" color="7" fill="1" visible="no" active="yes"/>
+<layer number="52" name="bDocu" color="7" fill="1" visible="no" active="yes"/>
+<layer number="90" name="Modules" color="5" fill="1" visible="no" active="no"/>
+<layer number="91" name="Nets" color="2" fill="1" visible="no" active="no"/>
+<layer number="92" name="Busses" color="1" fill="1" visible="no" active="no"/>
+<layer number="93" name="Pins" color="2" fill="1" visible="no" active="no"/>
+<layer number="94" name="Symbols" color="4" fill="1" visible="no" active="no"/>
+<layer number="95" name="Names" color="7" fill="1" visible="no" active="no"/>
+<layer number="96" name="Values" color="7" fill="1" visible="no" active="no"/>
+<layer number="97" name="Info" color="7" fill="1" visible="no" active="no"/>
+<layer number="98" name="Guide" color="6" fill="1" visible="no" active="no"/>
+</layers>
+<board>
+<plain>
+<wire x1="0" y1="0" x2="26.086" y2="0" width="0.1524" layer="20"/>
+<wire x1="26.086" y1="0" x2="26.086" y2="11.166" width="0.1524" layer="20"/>
+<wire x1="26.086" y1="11.166" x2="0" y2="11.166" width="0.1524" layer="20"/>
+<wire x1="0" y1="11.166" x2="0" y2="0" width="0.1524" layer="20"/>
+<text x="19.05" y="10.414" size="0.762" layer="28" font="vector" rot="MR180" align="bottom-center">4/13/19</text>
+<text x="20.574" y="1.27" size="1.27" layer="27" font="vector" rot="R90" align="bottom-center">1</text>
+<text x="16.51" y="3.302" size="1.27" layer="28" font="vector" rot="MR270" align="bottom-center">AT</text>
+<circle x="21.336" y="1.27" radius="0.254" width="0.508" layer="27"/>
+<circle x="21.336" y="1.27" radius="0.254" width="0.508" layer="28"/>
+</plain>
+<libraries>
+<library name="ataradov_mcu">
+<description>Alex Taradov Library (MCUs)</description>
+<packages>
+<package name="SO-14">
+<description>SO-14</description>
+<wire x1="4.305" y1="-1.9" x2="-4.305" y2="-1.9" width="0.2032" layer="51"/>
+<wire x1="-4.305" y1="-1.9" x2="-4.305" y2="-1.4" width="0.2032" layer="51"/>
+<wire x1="-4.305" y1="-1.4" x2="-4.305" y2="1.9" width="0.2032" layer="51"/>
+<wire x1="4.305" y1="-1.4" x2="-4.305" y2="-1.4" width="0.2032" layer="51"/>
+<wire x1="4.305" y1="1.9" x2="4.305" y2="-1.4" width="0.2032" layer="51"/>
+<wire x1="4.305" y1="-1.4" x2="4.305" y2="-1.9" width="0.2032" layer="51"/>
+<wire x1="-4.305" y1="1.9" x2="4.305" y2="1.9" width="0.2032" layer="51"/>
+<smd name="2" x="-2.54" y="-2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="13" x="-2.54" y="2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="1" x="-3.81" y="-2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="3" x="-1.27" y="-2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="4" x="0" y="-2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="14" x="-3.81" y="2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="12" x="-1.27" y="2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="11" x="0" y="2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="6" x="2.54" y="-2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="9" x="2.54" y="2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="5" x="1.27" y="-2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="7" x="3.81" y="-2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="10" x="1.27" y="2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="8" x="3.81" y="2.6" dx="0.6" dy="2.2" layer="1"/>
+<text x="-4.826" y="0" size="1.27" layer="25" font="vector" rot="R90" align="bottom-center">&gt;NAME</text>
+<text x="6.096" y="0" size="1.27" layer="27" font="vector" rot="R90" align="bottom-center">&gt;VALUE</text>
+<rectangle x1="-4.0551" y1="-3.1001" x2="-3.5649" y2="-2" layer="51"/>
+<rectangle x1="-2.7851" y1="-3.1001" x2="-2.2949" y2="-2" layer="51"/>
+<rectangle x1="-1.5151" y1="-3.1001" x2="-1.0249" y2="-2" layer="51"/>
+<rectangle x1="-0.2451" y1="-3.1001" x2="0.2451" y2="-2" layer="51"/>
+<rectangle x1="-0.2451" y1="2" x2="0.2451" y2="3.1001" layer="51"/>
+<rectangle x1="-1.5151" y1="2" x2="-1.0249" y2="3.1001" layer="51"/>
+<rectangle x1="-2.7851" y1="2" x2="-2.2949" y2="3.1001" layer="51"/>
+<rectangle x1="-4.0551" y1="2" x2="-3.5649" y2="3.1001" layer="51"/>
+<rectangle x1="1.0249" y1="-3.1001" x2="1.5151" y2="-2" layer="51"/>
+<rectangle x1="2.2949" y1="-3.1001" x2="2.7851" y2="-2" layer="51"/>
+<rectangle x1="3.5649" y1="-3.1001" x2="4.0551" y2="-2" layer="51"/>
+<rectangle x1="3.5649" y1="2" x2="4.0551" y2="3.1001" layer="51"/>
+<rectangle x1="2.2949" y1="2" x2="2.7851" y2="3.1001" layer="51"/>
+<rectangle x1="1.0249" y1="2" x2="1.5151" y2="3.1001" layer="51"/>
+</package>
+</packages>
+</library>
+<library name="ataradov_conn">
+<description>Alex Taradov Library (Connectors)</description>
+<packages>
+<package name="HEADER-5X2-1.27MM">
+<wire x1="-3.81" y1="1.905" x2="3.81" y2="1.905" width="0.127" layer="21"/>
+<wire x1="3.81" y1="1.905" x2="3.81" y2="-1.905" width="0.127" layer="21"/>
+<wire x1="3.81" y1="-1.905" x2="-3.175" y2="-1.905" width="0.127" layer="21"/>
+<wire x1="-3.175" y1="-1.905" x2="-3.81" y2="-1.27" width="0.127" layer="21"/>
+<wire x1="-3.81" y1="-1.27" x2="-3.81" y2="1.905" width="0.127" layer="21"/>
+<pad name="1" x="-2.54" y="-0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="2" x="-2.54" y="0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="3" x="-1.27" y="-0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="4" x="-1.27" y="0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="5" x="0" y="-0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="6" x="0" y="0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="7" x="1.27" y="-0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="8" x="1.27" y="0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="9" x="2.54" y="-0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="10" x="2.54" y="0.635" drill="0.6604" diameter="1.0668"/>
+<text x="0" y="2.54" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+<package name="USB-B-MICRO-SMT-SHELL-TH">
+<pad name="M1" x="2.15" y="-3.6" drill="1.397"/>
+<pad name="M2" x="2.15" y="3.6" drill="1.397"/>
+<smd name="1" x="4.825" y="1.3" dx="1.35" dy="0.4" layer="1" stop="no"/>
+<smd name="2" x="4.825" y="0.65" dx="1.35" dy="0.4" layer="1" stop="no"/>
+<smd name="3" x="4.825" y="0" dx="1.35" dy="0.4" layer="1" stop="no"/>
+<smd name="4" x="4.825" y="-0.65" dx="1.35" dy="0.4" layer="1" stop="no"/>
+<smd name="5" x="4.825" y="-1.3" dx="1.35" dy="0.4" layer="1" stop="no"/>
+<text x="3.175" y="0" size="1.27" layer="25" font="vector" rot="R90" align="bottom-center">&gt;NAME</text>
+<rectangle x1="4.1" y1="1.05" x2="5.55" y2="1.55" layer="29"/>
+<pad name="M3" x="5.05" y="2.425" drill="0.7" shape="long"/>
+<pad name="M4" x="5.05" y="-2.425" drill="0.7" shape="long"/>
+<rectangle x1="4.1" y1="0.4" x2="5.55" y2="0.9" layer="29"/>
+<rectangle x1="4.1" y1="-0.25" x2="5.55" y2="0.25" layer="29"/>
+<rectangle x1="4.1" y1="-0.9" x2="5.55" y2="-0.4" layer="29"/>
+<rectangle x1="4.1" y1="-1.55" x2="5.55" y2="-1.05" layer="29"/>
+<wire x1="-0.5" y1="4" x2="-0.6" y2="3.8" width="0.1524" layer="21"/>
+<wire x1="-0.6" y1="3.8" x2="0" y2="3.5" width="0.1524" layer="21"/>
+<wire x1="0" y1="3.5" x2="0" y2="3.1" width="0.1524" layer="21"/>
+<wire x1="0" y1="3.1" x2="-0.6" y2="3.1" width="0.1524" layer="21"/>
+<wire x1="-0.6" y1="3.1" x2="-0.6" y2="-3.1" width="0.1524" layer="21"/>
+<wire x1="-0.6" y1="-3.1" x2="0" y2="-3.1" width="0.1524" layer="21"/>
+<wire x1="0" y1="-3.1" x2="0" y2="-3.5" width="0.1524" layer="21"/>
+<wire x1="0" y1="-3.5" x2="-0.6" y2="-3.8" width="0.1524" layer="21"/>
+<wire x1="-0.6" y1="-3.8" x2="-0.5" y2="-4" width="0.1524" layer="21"/>
+<wire x1="-0.5" y1="-4" x2="0" y2="-3.75" width="0.1524" layer="21"/>
+<wire x1="0" y1="-3.75" x2="5" y2="-3.75" width="0.1524" layer="21"/>
+<wire x1="5" y1="-3.75" x2="5" y2="-3.16" width="0.1524" layer="21"/>
+<wire x1="-0.5" y1="4" x2="0" y2="3.75" width="0.1524" layer="21"/>
+<wire x1="0" y1="3.75" x2="5" y2="3.75" width="0.1524" layer="21"/>
+<wire x1="5" y1="3.75" x2="5" y2="3.16" width="0.1524" layer="21"/>
+</package>
+<package name="PIN-TH">
+<wire x1="-0.635" y1="1.27" x2="0.635" y2="1.27" width="0.1524" layer="21"/>
+<wire x1="0.635" y1="1.27" x2="1.27" y2="0.635" width="0.1524" layer="21"/>
+<wire x1="1.27" y1="0.635" x2="1.27" y2="-0.635" width="0.1524" layer="21"/>
+<wire x1="1.27" y1="-0.635" x2="0.635" y2="-1.27" width="0.1524" layer="21"/>
+<wire x1="-1.27" y1="0.635" x2="-1.27" y2="-0.635" width="0.1524" layer="21"/>
+<wire x1="-0.635" y1="1.27" x2="-1.27" y2="0.635" width="0.1524" layer="21"/>
+<wire x1="-1.27" y1="-0.635" x2="-0.635" y2="-1.27" width="0.1524" layer="21"/>
+<wire x1="0.635" y1="-1.27" x2="-0.635" y2="-1.27" width="0.1524" layer="21"/>
+<rectangle x1="-0.254" y1="-0.254" x2="0.254" y2="0.254" layer="51"/>
+<pad name="1" x="0" y="0" drill="1.016" shape="octagon"/>
+<text x="0" y="1.524" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+<text x="0" y="-2.794" size="1.27" layer="27" font="vector" align="bottom-center">&gt;VALUE</text>
+</package>
+</packages>
+</library>
+<library name="ataradov_rlc">
+<description>Alex Taradov Library (R, L and C)</description>
+<packages>
+<package name="SMD0603">
+<wire x1="-1.5" y1="0.75" x2="1.5" y2="0.75" width="0.1" layer="21"/>
+<wire x1="1.5" y1="0.75" x2="1.5" y2="-0.75" width="0.1" layer="21"/>
+<wire x1="1.5" y1="-0.75" x2="-1.5" y2="-0.75" width="0.1" layer="21"/>
+<wire x1="-1.5" y1="-0.75" x2="-1.5" y2="0.75" width="0.1" layer="21"/>
+<smd name="1" x="-0.8" y="0" dx="0.9" dy="0.9" layer="1"/>
+<smd name="2" x="0.8" y="0" dx="0.9" dy="0.9" layer="1"/>
+<text x="0" y="1.016" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+<package name="SMD0603-X4">
+<smd name="1" x="-1.2" y="-0.625" dx="0.5" dy="0.65" layer="1"/>
+<smd name="2" x="-0.4" y="-0.625" dx="0.5" dy="0.65" layer="1"/>
+<smd name="3" x="0.4" y="-0.625" dx="0.5" dy="0.65" layer="1"/>
+<smd name="4" x="1.2" y="-0.625" dx="0.5" dy="0.65" layer="1"/>
+<smd name="5" x="1.2" y="0.625" dx="0.5" dy="0.65" layer="1"/>
+<smd name="6" x="0.4" y="0.625" dx="0.5" dy="0.65" layer="1"/>
+<smd name="7" x="-0.4" y="0.625" dx="0.5" dy="0.65" layer="1"/>
+<smd name="8" x="-1.2" y="0.625" dx="0.5" dy="0.65" layer="1"/>
+<text x="0" y="1.524" size="1.27" layer="25" font="vector" ratio="10" align="bottom-center">&gt;NAME</text>
+<wire x1="1.778" y1="1.258" x2="1.778" y2="-1.258" width="0.1016" layer="21"/>
+<wire x1="-1.778" y1="1.258" x2="-1.778" y2="-1.258" width="0.1016" layer="21"/>
+<wire x1="-1.766" y1="1.27" x2="1.766" y2="1.27" width="0.1016" layer="21"/>
+<wire x1="-1.766" y1="-1.27" x2="1.766" y2="-1.27" width="0.1016" layer="21"/>
+</package>
+</packages>
+</library>
+<library name="ataradov_vreg">
+<description>Alex Taradov Library (Voltage Regulators)</description>
+<packages>
+<package name="SOT23-5">
+<description>SOT23-5</description>
+<wire x1="1.422" y1="0.81" x2="1.422" y2="-0.81" width="0.1524" layer="21"/>
+<wire x1="1.422" y1="-0.81" x2="-1.422" y2="-0.81" width="0.1524" layer="51"/>
+<wire x1="-1.422" y1="-0.81" x2="-1.422" y2="0.81" width="0.1524" layer="21"/>
+<wire x1="-1.422" y1="0.81" x2="1.422" y2="0.81" width="0.1524" layer="51"/>
+<wire x1="-0.522" y1="0.81" x2="0.522" y2="0.81" width="0.1524" layer="21"/>
+<wire x1="-0.428" y1="-0.81" x2="-0.522" y2="-0.81" width="0.1524" layer="21"/>
+<wire x1="0.522" y1="-0.81" x2="0.428" y2="-0.81" width="0.1524" layer="21"/>
+<wire x1="-1.328" y1="-0.81" x2="-1.422" y2="-0.81" width="0.1524" layer="21"/>
+<wire x1="1.422" y1="-0.81" x2="1.328" y2="-0.81" width="0.1524" layer="21"/>
+<wire x1="1.328" y1="0.81" x2="1.422" y2="0.81" width="0.1524" layer="21"/>
+<wire x1="-1.422" y1="0.81" x2="-1.328" y2="0.81" width="0.1524" layer="21"/>
+<smd name="1" x="-0.95" y="-1.3" dx="0.55" dy="1.2" layer="1"/>
+<smd name="2" x="0" y="-1.3" dx="0.55" dy="1.2" layer="1"/>
+<smd name="3" x="0.95" y="-1.3" dx="0.55" dy="1.2" layer="1"/>
+<smd name="4" x="0.95" y="1.3" dx="0.55" dy="1.2" layer="1"/>
+<smd name="5" x="-0.95" y="1.3" dx="0.55" dy="1.2" layer="1"/>
+<text x="0" y="2.286" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+<text x="0" y="-3.556" size="1.27" layer="27" font="vector" align="bottom-center">&gt;VALUE</text>
+<rectangle x1="-1.2" y1="-1.5" x2="-0.7" y2="-0.85" layer="51"/>
+<rectangle x1="-0.25" y1="-1.5" x2="0.25" y2="-0.85" layer="51"/>
+<rectangle x1="0.7" y1="-1.5" x2="1.2" y2="-0.85" layer="51"/>
+<rectangle x1="0.7" y1="0.85" x2="1.2" y2="1.5" layer="51"/>
+<rectangle x1="-1.2" y1="0.85" x2="-0.7" y2="1.5" layer="51"/>
+</package>
+</packages>
+</library>
+<library name="ataradov_misc">
+<description>Alex Taradov Library (Miscellaneous stuff)</description>
+<packages>
+<package name="TP-1.27MM">
+<smd name="1" x="0" y="0" dx="1.27" dy="1.27" layer="1" roundness="100" cream="no"/>
+<text x="0" y="1.016" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+</packages>
+</library>
+<library name="ataradov_led">
+<description>Alex Taradov Library (LEDs and other indication devices)</description>
+<packages>
+<package name="SMD0603">
+<wire x1="-1.5" y1="0.75" x2="1.5" y2="0.75" width="0.1" layer="21"/>
+<wire x1="1.5" y1="0.75" x2="1.5" y2="-0.75" width="0.1" layer="21"/>
+<wire x1="1.5" y1="-0.75" x2="-1.5" y2="-0.75" width="0.1" layer="21"/>
+<wire x1="-1.5" y1="-0.75" x2="-1.5" y2="0.75" width="0.1" layer="21"/>
+<smd name="1" x="-0.8" y="0" dx="0.9" dy="0.9" layer="1"/>
+<smd name="2" x="0.8" y="0" dx="0.9" dy="0.9" layer="1"/>
+<text x="0" y="1.016" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+</packages>
+</library>
+</libraries>
+<attributes>
+</attributes>
+<variantdefs>
+</variantdefs>
+<classes>
+<class number="0" name="default" width="0" drill="0">
+</class>
+</classes>
+<designrules name="OSHPark *">
+<description language="de">&lt;b&gt;EAGLE Design Rules&lt;/b&gt;
+&lt;p&gt;
+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.</description>
+<description language="en">&lt;b&gt;Laen's PCB Order Design Rules&lt;/b&gt;
+&lt;p&gt;
+Please make sure your boards conform to these design rules.</description>
+<param name="layerSetup" value="(1*16)"/>
+<param name="mtCopper" value="0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm"/>
+<param name="mtIsolate" value="1.5011mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm"/>
+<param name="mdWireWire" value="6mil"/>
+<param name="mdWirePad" value="6mil"/>
+<param name="mdWireVia" value="6mil"/>
+<param name="mdPadPad" value="6mil"/>
+<param name="mdPadVia" value="6mil"/>
+<param name="mdViaVia" value="6mil"/>
+<param name="mdSmdPad" value="6mil"/>
+<param name="mdSmdVia" value="6mil"/>
+<param name="mdSmdSmd" value="6mil"/>
+<param name="mdViaViaSameLayer" value="8mil"/>
+<param name="mnLayersViaInSmd" value="2"/>
+<param name="mdCopperDimension" value="15mil"/>
+<param name="mdDrill" value="6mil"/>
+<param name="mdSmdStop" value="0mil"/>
+<param name="msWidth" value="6mil"/>
+<param name="msDrill" value="13mil"/>
+<param name="msMicroVia" value="13mil"/>
+<param name="msBlindViaRatio" value="0.5"/>
+<param name="rvPadTop" value="0.25"/>
+<param name="rvPadInner" value="0.25"/>
+<param name="rvPadBottom" value="0.25"/>
+<param name="rvViaOuter" value="0.25"/>
+<param name="rvViaInner" value="0.25"/>
+<param name="rvMicroViaOuter" value="0.25"/>
+<param name="rvMicroViaInner" value="0.25"/>
+<param name="rlMinPadTop" value="7mil"/>
+<param name="rlMaxPadTop" value="20mil"/>
+<param name="rlMinPadInner" value="7mil"/>
+<param name="rlMaxPadInner" value="20mil"/>
+<param name="rlMinPadBottom" value="7mil"/>
+<param name="rlMaxPadBottom" value="20mil"/>
+<param name="rlMinViaOuter" value="7mil"/>
+<param name="rlMaxViaOuter" value="20mil"/>
+<param name="rlMinViaInner" value="7mil"/>
+<param name="rlMaxViaInner" value="20mil"/>
+<param name="rlMinMicroViaOuter" value="4mil"/>
+<param name="rlMaxMicroViaOuter" value="20mil"/>
+<param name="rlMinMicroViaInner" value="4mil"/>
+<param name="rlMaxMicroViaInner" value="20mil"/>
+<param name="psTop" value="-1"/>
+<param name="psBottom" value="-1"/>
+<param name="psFirst" value="-1"/>
+<param name="psElongationLong" value="100"/>
+<param name="psElongationOffset" value="100"/>
+<param name="mvStopFrame" value="1"/>
+<param name="mvCreamFrame" value="0"/>
+<param name="mlMinStopFrame" value="3mil"/>
+<param name="mlMaxStopFrame" value="3mil"/>
+<param name="mlMinCreamFrame" value="0mil"/>
+<param name="mlMaxCreamFrame" value="0mil"/>
+<param name="mlViaStopLimit" value="100mil"/>
+<param name="srRoundness" value="0"/>
+<param name="srMinRoundness" value="0mil"/>
+<param name="srMaxRoundness" value="0mil"/>
+<param name="slThermalIsolate" value="10mil"/>
+<param name="slThermalsForVias" value="0"/>
+<param name="dpMaxLengthDifference" value="10mm"/>
+<param name="dpGapFactor" value="2.5"/>
+<param name="checkGrid" value="0"/>
+<param name="checkAngle" value="0"/>
+<param name="checkFont" value="1"/>
+<param name="checkRestrict" value="1"/>
+<param name="useDiameter" value="13"/>
+<param name="maxErrors" value="50"/>
+</designrules>
+<autorouter>
+<pass name="Default">
+<param name="RoutingGrid" value="50mil"/>
+<param name="AutoGrid" value="1"/>
+<param name="Efforts" value="0"/>
+<param name="TopRouterVariant" value="1"/>
+<param name="tpViaShape" value="round"/>
+<param name="PrefDir.1" value="a"/>
+<param name="PrefDir.2" value="0"/>
+<param name="PrefDir.3" value="0"/>
+<param name="PrefDir.4" value="0"/>
+<param name="PrefDir.5" value="0"/>
+<param name="PrefDir.6" value="0"/>
+<param name="PrefDir.7" value="0"/>
+<param name="PrefDir.8" value="0"/>
+<param name="PrefDir.9" value="0"/>
+<param name="PrefDir.10" value="0"/>
+<param name="PrefDir.11" value="0"/>
+<param name="PrefDir.12" value="0"/>
+<param name="PrefDir.13" value="0"/>
+<param name="PrefDir.14" value="0"/>
+<param name="PrefDir.15" value="0"/>
+<param name="PrefDir.16" value="a"/>
+<param name="cfVia" value="8"/>
+<param name="cfNonPref" value="5"/>
+<param name="cfChangeDir" value="2"/>
+<param name="cfOrthStep" value="2"/>
+<param name="cfDiagStep" value="3"/>
+<param name="cfExtdStep" value="0"/>
+<param name="cfBonusStep" value="1"/>
+<param name="cfMalusStep" value="1"/>
+<param name="cfPadImpact" value="4"/>
+<param name="cfSmdImpact" value="4"/>
+<param name="cfBusImpact" value="0"/>
+<param name="cfHugging" value="3"/>
+<param name="cfAvoid" value="4"/>
+<param name="cfPolygon" value="10"/>
+<param name="cfBase.1" value="0"/>
+<param name="cfBase.2" value="1"/>
+<param name="cfBase.3" value="1"/>
+<param name="cfBase.4" value="1"/>
+<param name="cfBase.5" value="1"/>
+<param name="cfBase.6" value="1"/>
+<param name="cfBase.7" value="1"/>
+<param name="cfBase.8" value="1"/>
+<param name="cfBase.9" value="1"/>
+<param name="cfBase.10" value="1"/>
+<param name="cfBase.11" value="1"/>
+<param name="cfBase.12" value="1"/>
+<param name="cfBase.13" value="1"/>
+<param name="cfBase.14" value="1"/>
+<param name="cfBase.15" value="1"/>
+<param name="cfBase.16" value="0"/>
+<param name="mnVias" value="20"/>
+<param name="mnSegments" value="9999"/>
+<param name="mnExtdSteps" value="9999"/>
+<param name="mnRipupLevel" value="10"/>
+<param name="mnRipupSteps" value="100"/>
+<param name="mnRipupTotal" value="100"/>
+</pass>
+<pass name="Follow-me" refer="Default" active="yes">
+</pass>
+<pass name="Busses" refer="Default" active="yes">
+<param name="cfNonPref" value="4"/>
+<param name="cfBusImpact" value="4"/>
+<param name="cfHugging" value="0"/>
+<param name="mnVias" value="0"/>
+</pass>
+<pass name="Route" refer="Default" active="yes">
+</pass>
+<pass name="Optimize1" refer="Default" active="yes">
+<param name="cfVia" value="99"/>
+<param name="cfExtdStep" value="10"/>
+<param name="cfHugging" value="1"/>
+<param name="mnExtdSteps" value="1"/>
+<param name="mnRipupLevel" value="0"/>
+</pass>
+<pass name="Optimize2" refer="Optimize1" active="yes">
+<param name="cfNonPref" value="0"/>
+<param name="cfChangeDir" value="6"/>
+<param name="cfExtdStep" value="0"/>
+<param name="cfBonusStep" value="2"/>
+<param name="cfMalusStep" value="2"/>
+<param name="cfPadImpact" value="2"/>
+<param name="cfSmdImpact" value="2"/>
+<param name="cfHugging" value="0"/>
+</pass>
+<pass name="Optimize3" refer="Optimize2" active="yes">
+<param name="cfChangeDir" value="8"/>
+<param name="cfPadImpact" value="0"/>
+<param name="cfSmdImpact" value="0"/>
+</pass>
+<pass name="Optimize4" refer="Optimize3" active="yes">
+<param name="cfChangeDir" value="25"/>
+</pass>
+</autorouter>
+<elements>
+<element name="IC2" library="ataradov_mcu" package="SO-14" value="ATSAMD11C" x="10.414" y="6.35" smashed="yes" rot="MR270">
+<attribute name="NAME" x="10.414" y="11.176" size="1.27" layer="26" font="vector" rot="MR0" align="bottom-center"/>
+</element>
+<element name="C1" library="ataradov_rlc" package="SMD0603" value="1uF" x="15.494" y="8.636" rot="R90"/>
+<element name="C2" library="ataradov_rlc" package="SMD0603" value="1uF" x="8.128" y="8.636" smashed="yes" rot="R270">
+<attribute name="NAME" x="9.144" y="8.636" size="1.27" layer="25" font="vector" rot="R270" align="bottom-center"/>
+</element>
+<element name="IC1" library="ataradov_vreg" package="SOT23-5" value="MIC5504-3.3" x="11.938" y="8.636" smashed="yes" rot="R90">
+<attribute name="NAME" x="9.652" y="8.636" size="1.27" layer="25" font="vector" rot="R90" align="bottom-center"/>
+</element>
+<element name="TP1" library="ataradov_misc" package="TP-1.27MM" value="SIO" x="7.874" y="1.524" rot="MR0"/>
+<element name="TP2" library="ataradov_misc" package="TP-1.27MM" value="" x="12.954" y="1.524" rot="MR0"/>
+<element name="TP3" library="ataradov_misc" package="TP-1.27MM" value="" x="10.414" y="1.524" rot="MR0"/>
+<element name="TP4" library="ataradov_misc" package="TP-1.27MM" value="" x="5.334" y="1.524" rot="MR0"/>
+<element name="J1" library="ataradov_conn" package="HEADER-5X2-1.27MM" value="HEADER-5X2-TH-1.27" x="19.304" y="5.588" rot="R90"/>
+<element name="J2" library="ataradov_conn" package="USB-B-MICRO-SMT-SHELL-TH" value="" x="0" y="5.588"/>
+<element name="R1" library="ataradov_rlc" package="SMD0603" value="470" x="9.398" y="3.048" rot="R270"/>
+<element name="LED1" library="ataradov_led" package="SMD0603" value="" x="7.366" y="3.048" rot="R90"/>
+<element name="R2" library="ataradov_rlc" package="SMD0603" value="470" x="11.43" y="3.048" rot="R270"/>
+<element name="LED2" library="ataradov_led" package="SMD0603" value="" x="13.462" y="3.048" rot="R90"/>
+<element name="J3" library="ataradov_conn" package="PIN-TH" value="RX" x="22.606" y="8.128" smashed="yes" rot="R90">
+<attribute name="NAME" x="21.082" y="8.128" size="1.27" layer="25" font="vector" rot="R90" align="bottom-center"/>
+<attribute name="VALUE" x="25.654" y="8.89" size="1.27" layer="27" font="vector" rot="R90" align="bottom-center"/>
+</element>
+<element name="J4" library="ataradov_conn" package="PIN-TH" value="TX" x="22.606" y="5.588" smashed="yes" rot="R90">
+<attribute name="NAME" x="21.082" y="5.588" size="1.27" layer="25" font="vector" rot="R90" align="bottom-center"/>
+<attribute name="VALUE" x="25.654" y="5.588" size="1.27" layer="27" font="vector" rot="R90" align="bottom-center"/>
+</element>
+<element name="J5" library="ataradov_conn" package="PIN-TH" value="GND" x="22.606" y="3.048" smashed="yes" rot="R90">
+<attribute name="NAME" x="21.082" y="3.048" size="1.27" layer="25" font="vector" rot="R90" align="bottom-center"/>
+<attribute name="VALUE" x="25.654" y="2.286" size="1.27" layer="27" font="vector" rot="R90" align="bottom-center"/>
+</element>
+<element name="RN1" library="ataradov_rlc" package="SMD0603-X4" value="100" x="15.748" y="6.858" rot="MR90"/>
+</elements>
+<signals>
+<signal name="GND">
+<contactref element="IC1" pad="2"/>
+<contactref element="C1" pad="1"/>
+<contactref element="C2" pad="1"/>
+<contactref element="IC2" pad="11"/>
+<contactref element="TP4" pad="1"/>
+<contactref element="J1" pad="3"/>
+<contactref element="J1" pad="5"/>
+<contactref element="J2" pad="5"/>
+<polygon width="0.254" layer="16" isolate="0.254">
+<vertex x="0" y="11.176"/>
+<vertex x="26.162" y="11.176"/>
+<vertex x="26.162" y="0"/>
+<vertex x="0" y="0"/>
+</polygon>
+<polygon width="0.254" layer="1" isolate="0.254">
+<vertex x="0" y="11.176"/>
+<vertex x="26.162" y="11.176"/>
+<vertex x="26.162" y="0"/>
+<vertex x="0" y="0"/>
+</polygon>
+<via x="1.524" y="7.366" extent="1-16" drill="0.508" diameter="0.254"/>
+<via x="11.684" y="1.016" extent="1-16" drill="0.508" diameter="0.254"/>
+<via x="22.606" y="10.16" extent="1-16" drill="0.508" diameter="0.254"/>
+<via x="1.524" y="3.81" extent="1-16" drill="0.508" diameter="0.254"/>
+<contactref element="LED2" pad="2"/>
+<contactref element="LED1" pad="2"/>
+<contactref element="J1" pad="9"/>
+<contactref element="J5" pad="1"/>
+<via x="9.144" y="1.016" extent="1-16" drill="0.508" diameter="0.254"/>
+<via x="3.81" y="10.16" extent="1-16" drill="0.508" diameter="0.254"/>
+<via x="3.81" y="1.016" extent="1-16" drill="0.508" diameter="0.254"/>
+<via x="22.606" y="1.016" extent="1-16" drill="0.508" diameter="0.254"/>
+<via x="6.604" y="1.016" extent="1-16" drill="0.508" diameter="0.254"/>
+<via x="14.224" y="1.016" extent="1-16" drill="0.508" diameter="0.254"/>
+<via x="9.652" y="6.096" extent="1-16" drill="0.508" diameter="0.254"/>
+</signal>
+<signal name="N$1">
+<contactref element="IC2" pad="9"/>
+<contactref element="J2" pad="2"/>
+<via x="2.032" y="5.588" extent="1-16" drill="0.508" diameter="0.254"/>
+<wire x1="7.814" y1="3.81" x2="6.604" y2="3.81" width="0.254" layer="16"/>
+<wire x1="6.604" y1="3.81" x2="6.096" y2="4.318" width="0.254" layer="16"/>
+<wire x1="6.096" y1="4.318" x2="2.54" y2="4.318" width="0.254" layer="16"/>
+<wire x1="2.032" y1="5.588" x2="2.682" y2="6.238" width="0.254" layer="1"/>
+<wire x1="2.682" y1="6.238" x2="4.825" y2="6.238" width="0.254" layer="1"/>
+<wire x1="2.54" y1="4.318" x2="2.032" y2="4.826" width="0.254" layer="16"/>
+<wire x1="2.032" y1="4.826" x2="2.032" y2="5.588" width="0.254" layer="16"/>
+</signal>
+<signal name="N$2">
+<contactref element="IC2" pad="10"/>
+<contactref element="J2" pad="3"/>
+<via x="3.302" y="5.334" extent="1-16" drill="0.508" diameter="0.254"/>
+<wire x1="7.814" y1="5.08" x2="3.556" y2="5.08" width="0.254" layer="16"/>
+<wire x1="3.556" y1="5.08" x2="3.302" y2="5.334" width="0.254" layer="16"/>
+<wire x1="4.825" y1="5.588" x2="3.556" y2="5.588" width="0.254" layer="1"/>
+<wire x1="3.556" y1="5.588" x2="3.302" y2="5.334" width="0.254" layer="1"/>
+</signal>
+<signal name="V_USB">
+<contactref element="IC1" pad="3"/>
+<contactref element="IC1" pad="1"/>
+<contactref element="C1" pad="2"/>
+<contactref element="J2" pad="1"/>
+<wire x1="4.825" y1="6.888" x2="11.968" y2="6.888" width="0.254" layer="1"/>
+<wire x1="11.968" y1="6.888" x2="12.192" y2="7.112" width="0.254" layer="1"/>
+<wire x1="12.192" y1="7.112" x2="12.192" y2="7.62" width="0.254" layer="1"/>
+<wire x1="12.192" y1="7.62" x2="12.192" y2="9.398" width="0.254" layer="1"/>
+<wire x1="12.192" y1="9.398" x2="12.38" y2="9.586" width="0.254" layer="1"/>
+<wire x1="12.38" y1="9.586" x2="13.238" y2="9.586" width="0.254" layer="1"/>
+<wire x1="13.238" y1="7.686" x2="13.172" y2="7.62" width="0.254" layer="1"/>
+<wire x1="13.172" y1="7.62" x2="12.192" y2="7.62" width="0.254" layer="1"/>
+<wire x1="13.238" y1="9.586" x2="15.344" y2="9.586" width="0.254" layer="1"/>
+<wire x1="15.344" y1="9.586" x2="15.494" y2="9.436" width="0.254" layer="1"/>
+</signal>
+<signal name="+3V3">
+<contactref element="IC1" pad="5"/>
+<contactref element="C2" pad="2"/>
+<contactref element="IC2" pad="12"/>
+<via x="9.398" y="7.874" extent="1-16" drill="0.508" diameter="0.254"/>
+<wire x1="7.814" y1="7.62" x2="9.144" y2="7.62" width="0.254" layer="16"/>
+<wire x1="9.144" y1="7.62" x2="9.398" y2="7.874" width="0.254" layer="16"/>
+<wire x1="10.638" y1="7.686" x2="9.586" y2="7.686" width="0.254" layer="1"/>
+<wire x1="9.586" y1="7.686" x2="9.398" y2="7.874" width="0.254" layer="1"/>
+<wire x1="8.128" y1="7.836" x2="9.36" y2="7.836" width="0.254" layer="1"/>
+<wire x1="9.36" y1="7.836" x2="9.398" y2="7.874" width="0.254" layer="1"/>
+</signal>
+<signal name="SWDIO">
+<contactref element="IC2" pad="8"/>
+<contactref element="TP1" pad="1"/>
+<wire x1="7.814" y1="2.54" x2="7.874" y2="2.48" width="0.254" layer="16"/>
+<wire x1="7.874" y1="2.48" x2="7.874" y2="1.524" width="0.254" layer="16"/>
+</signal>
+<signal name="PA02">
+<contactref element="IC2" pad="13"/>
+<contactref element="R1" pad="1"/>
+<via x="10.16" y="4.826" extent="1-16" drill="0.508" diameter="0.508"/>
+<wire x1="10.16" y1="4.826" x2="10.414" y2="5.08" width="0.254" layer="16"/>
+<wire x1="7.814" y1="8.89" x2="10.16" y2="8.89" width="0.254" layer="16"/>
+<wire x1="10.16" y1="8.89" x2="10.414" y2="8.636" width="0.254" layer="16"/>
+<wire x1="10.414" y1="8.636" x2="10.414" y2="5.08" width="0.254" layer="16"/>
+<wire x1="9.398" y1="3.848" x2="9.398" y2="4.572" width="0.254" layer="1"/>
+<wire x1="9.398" y1="4.572" x2="9.652" y2="4.826" width="0.254" layer="1"/>
+<wire x1="9.652" y1="4.826" x2="10.16" y2="4.826" width="0.254" layer="1"/>
+</signal>
+<signal name="PA04">
+<contactref element="IC2" pad="14"/>
+<contactref element="R2" pad="1"/>
+<via x="11.176" y="5.334" extent="1-16" drill="0.508" diameter="0.508"/>
+<wire x1="11.176" y1="5.334" x2="11.176" y2="9.906" width="0.254" layer="16"/>
+<wire x1="7.814" y1="10.16" x2="10.922" y2="10.16" width="0.254" layer="16"/>
+<wire x1="10.922" y1="10.16" x2="11.176" y2="9.906" width="0.254" layer="16"/>
+<wire x1="11.43" y1="3.848" x2="11.43" y2="5.08" width="0.254" layer="1"/>
+<wire x1="11.43" y1="5.08" x2="11.176" y2="5.334" width="0.254" layer="1"/>
+</signal>
+<signal name="SWCLK">
+<contactref element="IC2" pad="7"/>
+<contactref element="TP2" pad="1"/>
+<wire x1="13.014" y1="2.54" x2="12.954" y2="2.48" width="0.254" layer="16"/>
+<wire x1="12.954" y1="2.48" x2="12.954" y2="1.524" width="0.254" layer="16"/>
+</signal>
+<signal name="RESET">
+<contactref element="IC2" pad="6"/>
+<contactref element="TP3" pad="1"/>
+<wire x1="13.014" y1="3.81" x2="11.684" y2="3.81" width="0.254" layer="16"/>
+<wire x1="11.684" y1="3.81" x2="10.414" y2="2.54" width="0.254" layer="16"/>
+<wire x1="10.414" y1="2.54" x2="10.414" y2="1.524" width="0.254" layer="16"/>
+</signal>
+<signal name="N$8">
+</signal>
+<signal name="T_SWDIO">
+<contactref element="J1" pad="2"/>
+<contactref element="RN1" pad="8"/>
+<wire x1="18.669" y1="3.048" x2="17.272" y2="3.048" width="0.254" layer="16"/>
+<wire x1="17.272" y1="3.048" x2="16.373" y2="3.947" width="0.254" layer="16"/>
+<wire x1="16.373" y1="3.947" x2="16.373" y2="5.658" width="0.254" layer="16"/>
+</signal>
+<signal name="T_SWCLK">
+<contactref element="J1" pad="4"/>
+<contactref element="RN1" pad="7"/>
+<wire x1="18.669" y1="4.318" x2="18.034" y2="4.318" width="0.254" layer="16"/>
+<wire x1="18.034" y1="4.318" x2="17.526" y2="4.826" width="0.254" layer="16"/>
+<wire x1="17.526" y1="4.826" x2="17.526" y2="6.096" width="0.254" layer="16"/>
+<wire x1="17.526" y1="6.096" x2="17.164" y2="6.458" width="0.254" layer="16"/>
+<wire x1="17.164" y1="6.458" x2="16.373" y2="6.458" width="0.254" layer="16"/>
+</signal>
+<signal name="T_RESET">
+<contactref element="J1" pad="10"/>
+<contactref element="RN1" pad="6"/>
+<wire x1="18.669" y1="8.128" x2="17.78" y2="8.128" width="0.254" layer="16"/>
+<wire x1="17.78" y1="8.128" x2="16.91" y2="7.258" width="0.254" layer="16"/>
+<wire x1="16.91" y1="7.258" x2="16.373" y2="7.258" width="0.254" layer="16"/>
+</signal>
+<signal name="PA14">
+<contactref element="IC2" pad="4"/>
+<contactref element="RN1" pad="2"/>
+<wire x1="13.014" y1="6.35" x2="13.122" y2="6.458" width="0.254" layer="16"/>
+<wire x1="13.122" y1="6.458" x2="15.123" y2="6.458" width="0.254" layer="16"/>
+</signal>
+<signal name="PA15">
+<contactref element="IC2" pad="5"/>
+<contactref element="RN1" pad="1"/>
+<wire x1="13.014" y1="5.08" x2="14.986" y2="5.08" width="0.254" layer="16"/>
+<wire x1="14.986" y1="5.08" x2="15.123" y2="5.217" width="0.254" layer="16"/>
+<wire x1="15.123" y1="5.217" x2="15.123" y2="5.658" width="0.254" layer="16"/>
+</signal>
+<signal name="PA09">
+<contactref element="IC2" pad="3"/>
+<contactref element="RN1" pad="3"/>
+<wire x1="13.014" y1="7.62" x2="14.224" y2="7.62" width="0.254" layer="16"/>
+<wire x1="14.224" y1="7.62" x2="14.586" y2="7.258" width="0.254" layer="16"/>
+<wire x1="14.586" y1="7.258" x2="15.123" y2="7.258" width="0.254" layer="16"/>
+</signal>
+<signal name="PA08">
+<contactref element="IC2" pad="2"/>
+<contactref element="RN1" pad="4"/>
+<wire x1="13.014" y1="8.89" x2="14.732" y2="8.89" width="0.254" layer="16"/>
+<wire x1="14.732" y1="8.89" x2="15.123" y2="8.499" width="0.254" layer="16"/>
+<wire x1="15.123" y1="8.499" x2="15.123" y2="8.058" width="0.254" layer="16"/>
+</signal>
+<signal name="N$4">
+<contactref element="R1" pad="2"/>
+<contactref element="LED1" pad="1"/>
+<wire x1="7.366" y1="2.248" x2="9.398" y2="2.248" width="0.254" layer="1"/>
+</signal>
+<signal name="N$6">
+<contactref element="R2" pad="2"/>
+<contactref element="LED2" pad="1"/>
+<wire x1="11.43" y1="2.248" x2="13.462" y2="2.248" width="0.254" layer="1"/>
+</signal>
+<signal name="UART_TX">
+<contactref element="J4" pad="1"/>
+<contactref element="RN1" pad="5"/>
+<wire x1="22.606" y1="5.588" x2="21.336" y2="6.858" width="0.254" layer="16"/>
+<wire x1="21.336" y1="6.858" x2="21.336" y2="9.144" width="0.254" layer="16"/>
+<wire x1="21.336" y1="9.144" x2="20.828" y2="9.652" width="0.254" layer="16"/>
+<wire x1="20.828" y1="9.652" x2="17.018" y2="9.652" width="0.254" layer="16"/>
+<wire x1="17.018" y1="9.652" x2="16.51" y2="9.144" width="0.254" layer="16"/>
+<wire x1="16.51" y1="9.144" x2="16.51" y2="8.195" width="0.254" layer="16"/>
+<wire x1="16.51" y1="8.195" x2="16.373" y2="8.058" width="0.254" layer="16"/>
+</signal>
+<signal name="N$11">
+</signal>
+<signal name="UART_RX">
+<contactref element="J3" pad="1"/>
+<contactref element="IC2" pad="1"/>
+<wire x1="13.014" y1="10.16" x2="21.082" y2="10.16" width="0.254" layer="16"/>
+<wire x1="21.082" y1="10.16" x2="22.606" y2="8.636" width="0.254" layer="16"/>
+<wire x1="22.606" y1="8.636" x2="22.606" y2="8.128" width="0.254" layer="16"/>
+</signal>
+</signals>
+</board>
+</drawing>
+</eagle>

BIN
dap_link/lib/free-dap/hardware/d11_micro_std_vcp/d11_micro_std_vcp.pdf


+ 1314 - 0
dap_link/lib/free-dap/hardware/d11_micro_std_vcp/d11_micro_std_vcp.sch

@@ -0,0 +1,1314 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE eagle SYSTEM "eagle.dtd">
+<eagle version="7.3.0">
+<drawing>
+<settings>
+<setting alwaysvectorfont="no"/>
+<setting verticaltext="up"/>
+</settings>
+<grid distance="0.1" unitdist="inch" unit="inch" style="lines" multiple="1" display="no" altdistance="0.01" altunitdist="inch" altunit="inch"/>
+<layers>
+<layer number="1" name="Top" color="4" fill="1" visible="no" active="no"/>
+<layer number="16" name="Bottom" color="1" fill="1" visible="no" active="no"/>
+<layer number="17" name="Pads" color="2" fill="1" visible="no" active="no"/>
+<layer number="18" name="Vias" color="2" fill="1" visible="no" active="no"/>
+<layer number="19" name="Unrouted" color="6" fill="1" visible="no" active="no"/>
+<layer number="20" name="Dimension" color="15" fill="1" visible="no" active="no"/>
+<layer number="21" name="tPlace" color="7" fill="1" visible="no" active="no"/>
+<layer number="22" name="bPlace" color="7" fill="1" visible="no" active="no"/>
+<layer number="23" name="tOrigins" color="15" fill="1" visible="no" active="no"/>
+<layer number="24" name="bOrigins" color="15" fill="1" visible="no" active="no"/>
+<layer number="25" name="tNames" color="7" fill="1" visible="no" active="no"/>
+<layer number="26" name="bNames" color="7" fill="1" visible="no" active="no"/>
+<layer number="27" name="tValues" color="7" fill="1" visible="no" active="no"/>
+<layer number="28" name="bValues" color="7" fill="1" visible="no" active="no"/>
+<layer number="29" name="tStop" color="7" fill="3" visible="no" active="no"/>
+<layer number="30" name="bStop" color="7" fill="6" visible="no" active="no"/>
+<layer number="31" name="tCream" color="7" fill="4" visible="no" active="no"/>
+<layer number="32" name="bCream" color="7" fill="5" visible="no" active="no"/>
+<layer number="33" name="tFinish" color="6" fill="3" visible="no" active="no"/>
+<layer number="34" name="bFinish" color="6" fill="6" visible="no" active="no"/>
+<layer number="35" name="tGlue" color="7" fill="4" visible="no" active="no"/>
+<layer number="36" name="bGlue" color="7" fill="5" visible="no" active="no"/>
+<layer number="37" name="tTest" color="7" fill="1" visible="no" active="no"/>
+<layer number="38" name="bTest" color="7" fill="1" visible="no" active="no"/>
+<layer number="39" name="tKeepout" color="4" fill="11" visible="no" active="no"/>
+<layer number="40" name="bKeepout" color="1" fill="11" visible="no" active="no"/>
+<layer number="41" name="tRestrict" color="4" fill="10" visible="no" active="no"/>
+<layer number="42" name="bRestrict" color="1" fill="10" visible="no" active="no"/>
+<layer number="43" name="vRestrict" color="2" fill="10" visible="no" active="no"/>
+<layer number="44" name="Drills" color="7" fill="1" visible="no" active="no"/>
+<layer number="45" name="Holes" color="7" fill="1" visible="no" active="no"/>
+<layer number="46" name="Milling" color="3" fill="1" visible="no" active="no"/>
+<layer number="47" name="Measures" color="7" fill="1" visible="no" active="no"/>
+<layer number="48" name="Document" color="7" fill="1" visible="no" active="no"/>
+<layer number="49" name="Reference" color="7" fill="1" visible="no" active="no"/>
+<layer number="51" name="tDocu" color="6" fill="1" visible="no" active="no"/>
+<layer number="52" name="bDocu" color="7" fill="1" visible="no" active="no"/>
+<layer number="90" name="Modules" color="5" fill="1" visible="yes" active="yes"/>
+<layer number="91" name="Nets" color="2" fill="1" visible="yes" active="yes"/>
+<layer number="92" name="Busses" color="1" fill="1" visible="yes" active="yes"/>
+<layer number="93" name="Pins" color="2" fill="1" visible="no" active="yes"/>
+<layer number="94" name="Symbols" color="4" fill="1" visible="yes" active="yes"/>
+<layer number="95" name="Names" color="7" fill="1" visible="yes" active="yes"/>
+<layer number="96" name="Values" color="7" fill="1" visible="yes" active="yes"/>
+<layer number="97" name="Info" color="7" fill="1" visible="yes" active="yes"/>
+<layer number="98" name="Guide" color="6" fill="1" visible="yes" active="yes"/>
+</layers>
+<schematic xreflabel="%F%N/%S.%C%R" xrefpart="/%S.%C%R">
+<libraries>
+<library name="ataradov_mcu">
+<description>Alex Taradov Library (MCUs)</description>
+<packages>
+<package name="SO-14">
+<description>SO-14</description>
+<wire x1="4.305" y1="-1.9" x2="-4.305" y2="-1.9" width="0.2032" layer="51"/>
+<wire x1="-4.305" y1="-1.9" x2="-4.305" y2="-1.4" width="0.2032" layer="51"/>
+<wire x1="-4.305" y1="-1.4" x2="-4.305" y2="1.9" width="0.2032" layer="51"/>
+<wire x1="4.305" y1="-1.4" x2="-4.305" y2="-1.4" width="0.2032" layer="51"/>
+<wire x1="4.305" y1="1.9" x2="4.305" y2="-1.4" width="0.2032" layer="51"/>
+<wire x1="4.305" y1="-1.4" x2="4.305" y2="-1.9" width="0.2032" layer="51"/>
+<wire x1="-4.305" y1="1.9" x2="4.305" y2="1.9" width="0.2032" layer="51"/>
+<smd name="2" x="-2.54" y="-2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="13" x="-2.54" y="2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="1" x="-3.81" y="-2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="3" x="-1.27" y="-2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="4" x="0" y="-2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="14" x="-3.81" y="2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="12" x="-1.27" y="2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="11" x="0" y="2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="6" x="2.54" y="-2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="9" x="2.54" y="2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="5" x="1.27" y="-2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="7" x="3.81" y="-2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="10" x="1.27" y="2.6" dx="0.6" dy="2.2" layer="1"/>
+<smd name="8" x="3.81" y="2.6" dx="0.6" dy="2.2" layer="1"/>
+<text x="-4.826" y="0" size="1.27" layer="25" font="vector" rot="R90" align="bottom-center">&gt;NAME</text>
+<text x="6.096" y="0" size="1.27" layer="27" font="vector" rot="R90" align="bottom-center">&gt;VALUE</text>
+<rectangle x1="-4.0551" y1="-3.1001" x2="-3.5649" y2="-2" layer="51"/>
+<rectangle x1="-2.7851" y1="-3.1001" x2="-2.2949" y2="-2" layer="51"/>
+<rectangle x1="-1.5151" y1="-3.1001" x2="-1.0249" y2="-2" layer="51"/>
+<rectangle x1="-0.2451" y1="-3.1001" x2="0.2451" y2="-2" layer="51"/>
+<rectangle x1="-0.2451" y1="2" x2="0.2451" y2="3.1001" layer="51"/>
+<rectangle x1="-1.5151" y1="2" x2="-1.0249" y2="3.1001" layer="51"/>
+<rectangle x1="-2.7851" y1="2" x2="-2.2949" y2="3.1001" layer="51"/>
+<rectangle x1="-4.0551" y1="2" x2="-3.5649" y2="3.1001" layer="51"/>
+<rectangle x1="1.0249" y1="-3.1001" x2="1.5151" y2="-2" layer="51"/>
+<rectangle x1="2.2949" y1="-3.1001" x2="2.7851" y2="-2" layer="51"/>
+<rectangle x1="3.5649" y1="-3.1001" x2="4.0551" y2="-2" layer="51"/>
+<rectangle x1="3.5649" y1="2" x2="4.0551" y2="3.1001" layer="51"/>
+<rectangle x1="2.2949" y1="2" x2="2.7851" y2="3.1001" layer="51"/>
+<rectangle x1="1.0249" y1="2" x2="1.5151" y2="3.1001" layer="51"/>
+</package>
+</packages>
+<symbols>
+<symbol name="ATSAMDXXC">
+<description>Atmel SAM D09C/D10C/D11C Cortex-M0+ microcontroller</description>
+<wire x1="-12.7" y1="10.16" x2="12.7" y2="10.16" width="0.254" layer="94"/>
+<wire x1="12.7" y1="10.16" x2="12.7" y2="-10.16" width="0.254" layer="94"/>
+<wire x1="12.7" y1="-10.16" x2="-12.7" y2="-10.16" width="0.254" layer="94"/>
+<wire x1="-12.7" y1="-10.16" x2="-12.7" y2="10.16" width="0.254" layer="94"/>
+<pin name="PA28/RST" x="-17.78" y="-5.08" length="middle"/>
+<pin name="PA8" x="-17.78" y="5.08" length="middle"/>
+<pin name="PA9" x="-17.78" y="2.54" length="middle"/>
+<pin name="PA14" x="-17.78" y="0" length="middle"/>
+<pin name="PA15" x="-17.78" y="-2.54" length="middle"/>
+<pin name="PA5" x="-17.78" y="7.62" length="middle"/>
+<pin name="PA04" x="17.78" y="7.62" length="middle" rot="R180"/>
+<pin name="PA02" x="17.78" y="5.08" length="middle" rot="R180"/>
+<text x="0" y="10.922" size="1.27" layer="95" align="bottom-center">&gt;NAME</text>
+<text x="0" y="-12.192" size="1.27" layer="96" align="bottom-center">&gt;VALUE</text>
+<pin name="PA30/SCK" x="-17.78" y="-7.62" length="middle"/>
+<pin name="VDD" x="17.78" y="2.54" length="middle" rot="R180"/>
+<pin name="GND" x="17.78" y="0" length="middle" rot="R180"/>
+<pin name="PA25" x="17.78" y="-2.54" length="middle" rot="R180"/>
+<pin name="PA24" x="17.78" y="-5.08" length="middle" rot="R180"/>
+<pin name="PA31/SIO" x="17.78" y="-7.62" length="middle" rot="R180"/>
+</symbol>
+</symbols>
+<devicesets>
+<deviceset name="ATSAMD11C" prefix="IC">
+<gates>
+<gate name="G$1" symbol="ATSAMDXXC" x="0" y="0"/>
+</gates>
+<devices>
+<device name="" package="SO-14">
+<connects>
+<connect gate="G$1" pin="GND" pad="11"/>
+<connect gate="G$1" pin="PA02" pad="13"/>
+<connect gate="G$1" pin="PA04" pad="14"/>
+<connect gate="G$1" pin="PA14" pad="4"/>
+<connect gate="G$1" pin="PA15" pad="5"/>
+<connect gate="G$1" pin="PA24" pad="9"/>
+<connect gate="G$1" pin="PA25" pad="10"/>
+<connect gate="G$1" pin="PA28/RST" pad="6"/>
+<connect gate="G$1" pin="PA30/SCK" pad="7"/>
+<connect gate="G$1" pin="PA31/SIO" pad="8"/>
+<connect gate="G$1" pin="PA5" pad="1"/>
+<connect gate="G$1" pin="PA8" pad="2"/>
+<connect gate="G$1" pin="PA9" pad="3"/>
+<connect gate="G$1" pin="VDD" pad="12"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+</devices>
+</deviceset>
+</devicesets>
+</library>
+<library name="ataradov_pwr">
+<description>Alex Taradov Library (Power Symbols)</description>
+<packages>
+</packages>
+<symbols>
+<symbol name="+3V3">
+<wire x1="-1.905" y1="0" x2="1.905" y2="0" width="0.254" layer="94"/>
+<text x="0" y="0.762" size="1.27" layer="96" align="bottom-center">&gt;VALUE</text>
+<pin name="+3V3" x="0" y="-2.54" visible="off" length="short" direction="sup" rot="R90"/>
+</symbol>
+<symbol name="GND">
+<wire x1="-1.905" y1="0" x2="1.905" y2="0" width="0.254" layer="94"/>
+<text x="0" y="-2.032" size="1.27" layer="96" align="bottom-center">&gt;VALUE</text>
+<pin name="GND" x="0" y="2.54" visible="off" length="short" direction="sup" rot="R270"/>
+</symbol>
+<symbol name="V_USB">
+<wire x1="-1.905" y1="0" x2="1.905" y2="0" width="0.254" layer="94"/>
+<text x="0" y="0.762" size="1.27" layer="96" align="bottom-center">&gt;VALUE</text>
+<pin name="V_USB" x="0" y="-2.54" visible="off" length="short" direction="sup" rot="R90"/>
+</symbol>
+</symbols>
+<devicesets>
+<deviceset name="+3V3" prefix="P_">
+<gates>
+<gate name="1" symbol="+3V3" x="0" y="0"/>
+</gates>
+<devices>
+<device name="">
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+</devices>
+</deviceset>
+<deviceset name="GND" prefix="P_">
+<gates>
+<gate name="1" symbol="GND" x="0" y="0"/>
+</gates>
+<devices>
+<device name="">
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+</devices>
+</deviceset>
+<deviceset name="V_USB" prefix="P_">
+<gates>
+<gate name="1" symbol="V_USB" x="0" y="0"/>
+</gates>
+<devices>
+<device name="">
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+</devices>
+</deviceset>
+</devicesets>
+</library>
+<library name="ataradov_conn">
+<description>Alex Taradov Library (Connectors)</description>
+<packages>
+<package name="HEADER-5X2-1.27MM">
+<wire x1="-3.81" y1="1.905" x2="3.81" y2="1.905" width="0.127" layer="21"/>
+<wire x1="3.81" y1="1.905" x2="3.81" y2="-1.905" width="0.127" layer="21"/>
+<wire x1="3.81" y1="-1.905" x2="-3.175" y2="-1.905" width="0.127" layer="21"/>
+<wire x1="-3.175" y1="-1.905" x2="-3.81" y2="-1.27" width="0.127" layer="21"/>
+<wire x1="-3.81" y1="-1.27" x2="-3.81" y2="1.905" width="0.127" layer="21"/>
+<pad name="1" x="-2.54" y="-0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="2" x="-2.54" y="0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="3" x="-1.27" y="-0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="4" x="-1.27" y="0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="5" x="0" y="-0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="6" x="0" y="0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="7" x="1.27" y="-0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="8" x="1.27" y="0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="9" x="2.54" y="-0.635" drill="0.6604" diameter="1.0668"/>
+<pad name="10" x="2.54" y="0.635" drill="0.6604" diameter="1.0668"/>
+<text x="0" y="2.54" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+<package name="HEADER-5X2-2.54MM">
+<wire x1="-6.35" y1="0" x2="-3.81" y2="0" width="0.127" layer="21"/>
+<wire x1="-3.81" y1="0" x2="-3.81" y2="-2.54" width="0.127" layer="21"/>
+<wire x1="-6.35" y1="2.54" x2="6.35" y2="2.54" width="0.127" layer="21"/>
+<wire x1="6.35" y1="2.54" x2="6.35" y2="-2.54" width="0.127" layer="21"/>
+<wire x1="6.35" y1="-2.54" x2="-6.35" y2="-2.54" width="0.127" layer="21"/>
+<wire x1="-6.35" y1="-2.54" x2="-6.35" y2="2.54" width="0.127" layer="21"/>
+<pad name="1" x="-5.08" y="-1.27" drill="1.016" shape="square"/>
+<pad name="2" x="-5.08" y="1.27" drill="1.016"/>
+<pad name="3" x="-2.54" y="-1.27" drill="1.016"/>
+<pad name="4" x="-2.54" y="1.27" drill="1.016"/>
+<pad name="5" x="0" y="-1.27" drill="1.016"/>
+<pad name="6" x="0" y="1.27" drill="1.016"/>
+<pad name="7" x="2.54" y="-1.27" drill="1.016"/>
+<pad name="8" x="2.54" y="1.27" drill="1.016"/>
+<pad name="9" x="5.08" y="-1.27" drill="1.016"/>
+<pad name="10" x="5.08" y="1.27" drill="1.016"/>
+<text x="0" y="3.175" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+<package name="USB-B-MICRO-SMT-SHELL-TH">
+<pad name="M1" x="2.15" y="-3.6" drill="1.397"/>
+<pad name="M2" x="2.15" y="3.6" drill="1.397"/>
+<smd name="1" x="4.825" y="1.3" dx="1.35" dy="0.4" layer="1" stop="no"/>
+<smd name="2" x="4.825" y="0.65" dx="1.35" dy="0.4" layer="1" stop="no"/>
+<smd name="3" x="4.825" y="0" dx="1.35" dy="0.4" layer="1" stop="no"/>
+<smd name="4" x="4.825" y="-0.65" dx="1.35" dy="0.4" layer="1" stop="no"/>
+<smd name="5" x="4.825" y="-1.3" dx="1.35" dy="0.4" layer="1" stop="no"/>
+<text x="3.175" y="0" size="1.27" layer="25" font="vector" rot="R90" align="bottom-center">&gt;NAME</text>
+<rectangle x1="4.1" y1="1.05" x2="5.55" y2="1.55" layer="29"/>
+<pad name="M3" x="5.05" y="2.425" drill="0.7" shape="long"/>
+<pad name="M4" x="5.05" y="-2.425" drill="0.7" shape="long"/>
+<rectangle x1="4.1" y1="0.4" x2="5.55" y2="0.9" layer="29"/>
+<rectangle x1="4.1" y1="-0.25" x2="5.55" y2="0.25" layer="29"/>
+<rectangle x1="4.1" y1="-0.9" x2="5.55" y2="-0.4" layer="29"/>
+<rectangle x1="4.1" y1="-1.55" x2="5.55" y2="-1.05" layer="29"/>
+<wire x1="-0.5" y1="4" x2="-0.6" y2="3.8" width="0.1524" layer="21"/>
+<wire x1="-0.6" y1="3.8" x2="0" y2="3.5" width="0.1524" layer="21"/>
+<wire x1="0" y1="3.5" x2="0" y2="3.1" width="0.1524" layer="21"/>
+<wire x1="0" y1="3.1" x2="-0.6" y2="3.1" width="0.1524" layer="21"/>
+<wire x1="-0.6" y1="3.1" x2="-0.6" y2="-3.1" width="0.1524" layer="21"/>
+<wire x1="-0.6" y1="-3.1" x2="0" y2="-3.1" width="0.1524" layer="21"/>
+<wire x1="0" y1="-3.1" x2="0" y2="-3.5" width="0.1524" layer="21"/>
+<wire x1="0" y1="-3.5" x2="-0.6" y2="-3.8" width="0.1524" layer="21"/>
+<wire x1="-0.6" y1="-3.8" x2="-0.5" y2="-4" width="0.1524" layer="21"/>
+<wire x1="-0.5" y1="-4" x2="0" y2="-3.75" width="0.1524" layer="21"/>
+<wire x1="0" y1="-3.75" x2="5" y2="-3.75" width="0.1524" layer="21"/>
+<wire x1="5" y1="-3.75" x2="5" y2="-3.16" width="0.1524" layer="21"/>
+<wire x1="-0.5" y1="4" x2="0" y2="3.75" width="0.1524" layer="21"/>
+<wire x1="0" y1="3.75" x2="5" y2="3.75" width="0.1524" layer="21"/>
+<wire x1="5" y1="3.75" x2="5" y2="3.16" width="0.1524" layer="21"/>
+</package>
+<package name="PIN-TH">
+<wire x1="-0.635" y1="1.27" x2="0.635" y2="1.27" width="0.1524" layer="21"/>
+<wire x1="0.635" y1="1.27" x2="1.27" y2="0.635" width="0.1524" layer="21"/>
+<wire x1="1.27" y1="0.635" x2="1.27" y2="-0.635" width="0.1524" layer="21"/>
+<wire x1="1.27" y1="-0.635" x2="0.635" y2="-1.27" width="0.1524" layer="21"/>
+<wire x1="-1.27" y1="0.635" x2="-1.27" y2="-0.635" width="0.1524" layer="21"/>
+<wire x1="-0.635" y1="1.27" x2="-1.27" y2="0.635" width="0.1524" layer="21"/>
+<wire x1="-1.27" y1="-0.635" x2="-0.635" y2="-1.27" width="0.1524" layer="21"/>
+<wire x1="0.635" y1="-1.27" x2="-0.635" y2="-1.27" width="0.1524" layer="21"/>
+<rectangle x1="-0.254" y1="-0.254" x2="0.254" y2="0.254" layer="51"/>
+<pad name="1" x="0" y="0" drill="1.016" shape="octagon"/>
+<text x="0" y="1.524" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+<text x="0" y="-2.794" size="1.27" layer="27" font="vector" align="bottom-center">&gt;VALUE</text>
+</package>
+</packages>
+<symbols>
+<symbol name="HEADER-5X2">
+<wire x1="-5.08" y1="7.62" x2="-5.08" y2="-7.62" width="0.254" layer="94"/>
+<wire x1="-5.08" y1="-7.62" x2="5.08" y2="-7.62" width="0.254" layer="94"/>
+<wire x1="5.08" y1="-7.62" x2="5.08" y2="7.62" width="0.254" layer="94"/>
+<wire x1="5.08" y1="7.62" x2="-5.08" y2="7.62" width="0.254" layer="94"/>
+<pin name="1" x="-7.62" y="5.08" length="short" direction="pas"/>
+<pin name="2" x="7.62" y="5.08" length="short" direction="pas" rot="R180"/>
+<pin name="3" x="-7.62" y="2.54" length="short" direction="pas"/>
+<pin name="4" x="7.62" y="2.54" length="short" direction="pas" rot="R180"/>
+<pin name="5" x="-7.62" y="0" length="short" direction="pas"/>
+<pin name="6" x="7.62" y="0" length="short" direction="pas" rot="R180"/>
+<pin name="7" x="-7.62" y="-2.54" length="short" direction="pas"/>
+<pin name="8" x="7.62" y="-2.54" length="short" direction="pas" rot="R180"/>
+<pin name="9" x="-7.62" y="-5.08" length="short" direction="pas"/>
+<pin name="10" x="7.62" y="-5.08" length="short" direction="pas" rot="R180"/>
+<text x="0" y="8.382" size="1.27" layer="95" align="bottom-center">&gt;NAME</text>
+</symbol>
+<symbol name="MICRO-USB-5">
+<wire x1="-5.08" y1="7.62" x2="-5.08" y2="-10.16" width="0.254" layer="94"/>
+<text x="0.762" y="8.382" size="1.27" layer="95" align="bottom-center">&gt;NAME</text>
+<pin name="VBUS" x="-7.62" y="5.08" visible="pin" length="short" direction="pas"/>
+<pin name="DM" x="-7.62" y="2.54" visible="pin" length="short" direction="pas"/>
+<pin name="DP" x="-7.62" y="0" visible="pin" length="short" direction="pas"/>
+<pin name="ID" x="-7.62" y="-2.54" visible="pin" length="short" direction="pas"/>
+<pin name="GND" x="-7.62" y="-5.08" visible="pin" length="short" direction="pas"/>
+<wire x1="7.62" y1="7.62" x2="7.62" y2="-10.16" width="0.254" layer="94"/>
+<wire x1="-5.08" y1="7.62" x2="7.62" y2="7.62" width="0.254" layer="94"/>
+<wire x1="-5.08" y1="-10.16" x2="7.62" y2="-10.16" width="0.254" layer="94"/>
+<pin name="SHIELD" x="-7.62" y="-7.62" visible="pin" length="short" direction="pas"/>
+<text x="0.762" y="-12.192" size="1.27" layer="95" align="bottom-center">&gt;VALUE</text>
+</symbol>
+<symbol name="CONN-SINGLE">
+<wire x1="-2.54" y1="0.762" x2="0.127" y2="0" width="0.254" layer="94"/>
+<wire x1="0.127" y1="0" x2="-2.4765" y2="-0.762" width="0.254" layer="94"/>
+<pin name="1" x="-2.54" y="0" visible="off" length="short" direction="pas" swaplevel="1"/>
+<text x="1.27" y="-0.508" size="1.27" layer="95">&gt;NAME</text>
+<text x="6.096" y="-0.508" size="1.27" layer="96">&gt;VALUE</text>
+</symbol>
+</symbols>
+<devicesets>
+<deviceset name="HEADER-5X2" prefix="J">
+<gates>
+<gate name="G$1" symbol="HEADER-5X2" x="0" y="0"/>
+</gates>
+<devices>
+<device name="-TH-1.27" package="HEADER-5X2-1.27MM">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="10" pad="10"/>
+<connect gate="G$1" pin="2" pad="2"/>
+<connect gate="G$1" pin="3" pad="3"/>
+<connect gate="G$1" pin="4" pad="4"/>
+<connect gate="G$1" pin="5" pad="5"/>
+<connect gate="G$1" pin="6" pad="6"/>
+<connect gate="G$1" pin="7" pad="7"/>
+<connect gate="G$1" pin="8" pad="8"/>
+<connect gate="G$1" pin="9" pad="9"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+<device name="-TH-2.54" package="HEADER-5X2-2.54MM">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="10" pad="10"/>
+<connect gate="G$1" pin="2" pad="2"/>
+<connect gate="G$1" pin="3" pad="3"/>
+<connect gate="G$1" pin="4" pad="4"/>
+<connect gate="G$1" pin="5" pad="5"/>
+<connect gate="G$1" pin="6" pad="6"/>
+<connect gate="G$1" pin="7" pad="7"/>
+<connect gate="G$1" pin="8" pad="8"/>
+<connect gate="G$1" pin="9" pad="9"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+</devices>
+</deviceset>
+<deviceset name="USB-B-MICRO" prefix="J" uservalue="yes">
+<gates>
+<gate name="G$1" symbol="MICRO-USB-5" x="0" y="0"/>
+</gates>
+<devices>
+<device name="-SMT" package="USB-B-MICRO-SMT-SHELL-TH">
+<connects>
+<connect gate="G$1" pin="DM" pad="2"/>
+<connect gate="G$1" pin="DP" pad="3"/>
+<connect gate="G$1" pin="GND" pad="5"/>
+<connect gate="G$1" pin="ID" pad="4"/>
+<connect gate="G$1" pin="SHIELD" pad="M1 M2 M3 M4" route="any"/>
+<connect gate="G$1" pin="VBUS" pad="1"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+</devices>
+</deviceset>
+<deviceset name="CONN-SINGLE" prefix="J" uservalue="yes">
+<gates>
+<gate name="G$1" symbol="CONN-SINGLE" x="0" y="0"/>
+</gates>
+<devices>
+<device name="-TH" package="PIN-TH">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+</devices>
+</deviceset>
+</devicesets>
+</library>
+<library name="ataradov_rlc">
+<description>Alex Taradov Library (R, L and C)</description>
+<packages>
+<package name="SMD0402">
+<wire x1="-1" y1="0.5" x2="1" y2="0.5" width="0.1" layer="21"/>
+<wire x1="1" y1="0.5" x2="1" y2="-0.5" width="0.1" layer="21"/>
+<wire x1="1" y1="-0.5" x2="-1" y2="-0.5" width="0.1" layer="21"/>
+<wire x1="-1" y1="-0.5" x2="-1" y2="0.5" width="0.1" layer="21"/>
+<smd name="1" x="-0.5" y="0" dx="0.6" dy="0.6" layer="1"/>
+<smd name="2" x="0.5" y="0" dx="0.6" dy="0.6" layer="1"/>
+<text x="0" y="0.762" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+<package name="SMD0508">
+<wire x1="-1" y1="1.25" x2="1" y2="1.25" width="0.1" layer="21"/>
+<wire x1="1" y1="1.25" x2="1" y2="-1.25" width="0.1" layer="21"/>
+<wire x1="1" y1="-1.25" x2="-1" y2="-1.25" width="0.1" layer="21"/>
+<wire x1="-1" y1="-1.25" x2="-1" y2="1.25" width="0.1" layer="21"/>
+<smd name="1" x="-0.5" y="0" dx="2" dy="0.5" layer="1" rot="R90"/>
+<smd name="2" x="0.5" y="0" dx="2" dy="0.5" layer="1" rot="R90"/>
+<text x="0" y="1.524" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+<package name="SMD0603">
+<wire x1="-1.5" y1="0.75" x2="1.5" y2="0.75" width="0.1" layer="21"/>
+<wire x1="1.5" y1="0.75" x2="1.5" y2="-0.75" width="0.1" layer="21"/>
+<wire x1="1.5" y1="-0.75" x2="-1.5" y2="-0.75" width="0.1" layer="21"/>
+<wire x1="-1.5" y1="-0.75" x2="-1.5" y2="0.75" width="0.1" layer="21"/>
+<smd name="1" x="-0.8" y="0" dx="0.9" dy="0.9" layer="1"/>
+<smd name="2" x="0.8" y="0" dx="0.9" dy="0.9" layer="1"/>
+<text x="0" y="1.016" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+<package name="SMD0612">
+<wire x1="-1.8" y1="1.4" x2="1.8" y2="1.4" width="0.1" layer="21"/>
+<wire x1="1.8" y1="1.4" x2="1.8" y2="-1.4" width="0.1" layer="21"/>
+<wire x1="1.8" y1="-1.4" x2="-1.8" y2="-1.4" width="0.1" layer="21"/>
+<wire x1="-1.8" y1="-1.4" x2="-1.8" y2="1.4" width="0.1" layer="21"/>
+<smd name="1" x="0" y="0.8" dx="3.2" dy="0.8" layer="1"/>
+<smd name="2" x="0" y="-0.8" dx="3.2" dy="0.8" layer="1"/>
+<text x="0" y="1.778" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+<package name="SMD0805">
+<wire x1="-2" y1="1" x2="2" y2="1" width="0.1" layer="21"/>
+<wire x1="2" y1="1" x2="2" y2="-1" width="0.1" layer="21"/>
+<wire x1="2" y1="-1" x2="-2" y2="-1" width="0.1" layer="21"/>
+<wire x1="-2" y1="-1" x2="-2" y2="1" width="0.1" layer="21"/>
+<smd name="1" x="-0.95" y="0" dx="1.3" dy="1.5" layer="1"/>
+<smd name="2" x="0.95" y="0" dx="1.3" dy="1.5" layer="1"/>
+<text x="0" y="1.27" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+<package name="SMD1206">
+<wire x1="-2.5" y1="1.5" x2="2.5" y2="1.5" width="0.1" layer="21"/>
+<wire x1="2.5" y1="1.5" x2="2.5" y2="-1.5" width="0.1" layer="21"/>
+<wire x1="2.5" y1="-1.5" x2="-2.5" y2="-1.5" width="0.1" layer="21"/>
+<wire x1="-2.5" y1="-1.5" x2="-2.5" y2="1.5" width="0.1" layer="21"/>
+<smd name="1" x="-1.4" y="0" dx="1.6" dy="2" layer="1"/>
+<smd name="2" x="1.4" y="0" dx="1.6" dy="2" layer="1"/>
+<text x="0" y="1.778" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+<package name="SMD2512">
+<wire x1="-5.5" y1="2.5" x2="5.5" y2="2.5" width="0.1" layer="21"/>
+<wire x1="5.5" y1="2.5" x2="5.5" y2="-2.5" width="0.1" layer="21"/>
+<wire x1="5.5" y1="-2.5" x2="-5.5" y2="-2.5" width="0.1" layer="21"/>
+<wire x1="-5.5" y1="-2.5" x2="-5.5" y2="2.5" width="0.1" layer="21"/>
+<smd name="1" x="-3.25" y="0" dx="3.5" dy="3" layer="1" rot="R90"/>
+<smd name="2" x="3.25" y="0" dx="3.5" dy="3" layer="1" rot="R90"/>
+<text x="0" y="2.794" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+<package name="SMD0603-X4">
+<smd name="1" x="-1.2" y="-0.625" dx="0.5" dy="0.65" layer="1"/>
+<smd name="2" x="-0.4" y="-0.625" dx="0.5" dy="0.65" layer="1"/>
+<smd name="3" x="0.4" y="-0.625" dx="0.5" dy="0.65" layer="1"/>
+<smd name="4" x="1.2" y="-0.625" dx="0.5" dy="0.65" layer="1"/>
+<smd name="5" x="1.2" y="0.625" dx="0.5" dy="0.65" layer="1"/>
+<smd name="6" x="0.4" y="0.625" dx="0.5" dy="0.65" layer="1"/>
+<smd name="7" x="-0.4" y="0.625" dx="0.5" dy="0.65" layer="1"/>
+<smd name="8" x="-1.2" y="0.625" dx="0.5" dy="0.65" layer="1"/>
+<text x="0" y="1.524" size="1.27" layer="25" font="vector" ratio="10" align="bottom-center">&gt;NAME</text>
+<wire x1="1.778" y1="1.258" x2="1.778" y2="-1.258" width="0.1016" layer="21"/>
+<wire x1="-1.778" y1="1.258" x2="-1.778" y2="-1.258" width="0.1016" layer="21"/>
+<wire x1="-1.766" y1="1.27" x2="1.766" y2="1.27" width="0.1016" layer="21"/>
+<wire x1="-1.766" y1="-1.27" x2="1.766" y2="-1.27" width="0.1016" layer="21"/>
+</package>
+</packages>
+<symbols>
+<symbol name="C">
+<rectangle x1="-1.524" y1="-0.254" x2="2.54" y2="0.254" layer="94" rot="R90"/>
+<rectangle x1="-2.54" y1="-0.254" x2="1.524" y2="0.254" layer="94" rot="R90"/>
+<wire x1="-2.54" y1="0" x2="-0.762" y2="0" width="0.1524" layer="94"/>
+<wire x1="2.54" y1="0" x2="0.762" y2="0" width="0.1524" layer="94"/>
+<pin name="1" x="-2.54" y="0" visible="off" length="point" direction="pas" swaplevel="1"/>
+<pin name="2" x="2.54" y="0" visible="off" length="point" direction="pas" swaplevel="1" rot="R180"/>
+<text x="0" y="2.413" size="1.27" layer="95" align="bottom-center">&gt;NAME</text>
+<text x="0" y="-3.683" size="1.27" layer="96" align="bottom-center">&gt;VALUE</text>
+</symbol>
+<symbol name="R">
+<wire x1="-2.54" y1="-1.016" x2="-2.54" y2="1.016" width="0.254" layer="94"/>
+<pin name="1" x="-5.08" y="0" visible="off" length="short" direction="pas" swaplevel="1"/>
+<pin name="2" x="5.08" y="0" visible="off" length="short" direction="pas" swaplevel="1" rot="R180"/>
+<text x="0" y="1.524" size="1.27" layer="95" align="bottom-center">&gt;NAME</text>
+<text x="0" y="0" size="1.016" layer="96" align="center">&gt;VALUE</text>
+<wire x1="2.54" y1="-1.016" x2="2.54" y2="1.016" width="0.254" layer="94"/>
+<wire x1="-2.54" y1="1.016" x2="2.54" y2="1.016" width="0.254" layer="94"/>
+<wire x1="-2.54" y1="-1.016" x2="2.54" y2="-1.016" width="0.254" layer="94"/>
+</symbol>
+<symbol name="RN-4">
+<wire x1="-2.54" y1="1.524" x2="-2.54" y2="3.556" width="0.254" layer="94"/>
+<pin name="1" x="-5.08" y="2.54" visible="off" length="short" direction="pas"/>
+<pin name="8" x="5.08" y="2.54" visible="off" length="short" direction="pas" rot="R180"/>
+<text x="0" y="4.572" size="1.27" layer="95" align="bottom-center">&gt;NAME</text>
+<wire x1="2.54" y1="1.524" x2="2.54" y2="3.556" width="0.254" layer="94"/>
+<wire x1="-2.54" y1="3.556" x2="2.54" y2="3.556" width="0.254" layer="94"/>
+<wire x1="-2.54" y1="1.524" x2="2.54" y2="1.524" width="0.254" layer="94"/>
+<wire x1="-2.54" y1="-1.016" x2="-2.54" y2="1.016" width="0.254" layer="94"/>
+<pin name="2" x="-5.08" y="0" visible="off" length="short" direction="pas"/>
+<pin name="7" x="5.08" y="0" visible="off" length="short" direction="pas" rot="R180"/>
+<wire x1="2.54" y1="-1.016" x2="2.54" y2="1.016" width="0.254" layer="94"/>
+<wire x1="-2.54" y1="1.016" x2="2.54" y2="1.016" width="0.254" layer="94"/>
+<wire x1="-2.54" y1="-1.016" x2="2.54" y2="-1.016" width="0.254" layer="94"/>
+<wire x1="-2.54" y1="-3.556" x2="-2.54" y2="-1.524" width="0.254" layer="94"/>
+<pin name="3" x="-5.08" y="-2.54" visible="off" length="short" direction="pas"/>
+<pin name="6" x="5.08" y="-2.54" visible="off" length="short" direction="pas" rot="R180"/>
+<wire x1="2.54" y1="-3.556" x2="2.54" y2="-1.524" width="0.254" layer="94"/>
+<wire x1="-2.54" y1="-1.524" x2="2.54" y2="-1.524" width="0.254" layer="94"/>
+<wire x1="-2.54" y1="-3.556" x2="2.54" y2="-3.556" width="0.254" layer="94"/>
+<wire x1="-2.54" y1="-6.096" x2="-2.54" y2="-4.064" width="0.254" layer="94"/>
+<pin name="4" x="-5.08" y="-5.08" visible="off" length="short" direction="pas"/>
+<pin name="5" x="5.08" y="-5.08" visible="off" length="short" direction="pas" rot="R180"/>
+<text x="0" y="2.54" size="1.016" layer="96" align="center">&gt;VALUE</text>
+<wire x1="2.54" y1="-6.096" x2="2.54" y2="-4.064" width="0.254" layer="94"/>
+<wire x1="-2.54" y1="-4.064" x2="2.54" y2="-4.064" width="0.254" layer="94"/>
+<wire x1="-2.54" y1="-6.096" x2="2.54" y2="-6.096" width="0.254" layer="94"/>
+<wire x1="-3.048" y1="-6.604" x2="-3.048" y2="4.064" width="0.127" layer="94" style="shortdash"/>
+<wire x1="3.048" y1="-6.604" x2="3.048" y2="4.064" width="0.127" layer="94" style="shortdash"/>
+<wire x1="3.048" y1="-6.604" x2="-3.048" y2="-6.604" width="0.127" layer="94" style="shortdash"/>
+<wire x1="3.048" y1="4.064" x2="-3.048" y2="4.064" width="0.127" layer="94" style="shortdash"/>
+</symbol>
+</symbols>
+<devicesets>
+<deviceset name="C" prefix="C" uservalue="yes">
+<gates>
+<gate name="G$1" symbol="C" x="0" y="0"/>
+</gates>
+<devices>
+<device name="-0402" package="SMD0402">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="2" pad="2"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+<device name="-0508" package="SMD0508">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="2" pad="2"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+<device name="-0603" package="SMD0603">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="2" pad="2"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+<device name="-0612" package="SMD0612">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="2" pad="2"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+<device name="-0805" package="SMD0805">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="2" pad="2"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+<device name="-1206" package="SMD1206">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="2" pad="2"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+<device name="-2512" package="SMD2512">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="2" pad="2"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+</devices>
+</deviceset>
+<deviceset name="R" prefix="R" uservalue="yes">
+<gates>
+<gate name="G$1" symbol="R" x="0" y="0"/>
+</gates>
+<devices>
+<device name="-0402" package="SMD0402">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="2" pad="2"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+<device name="-0508" package="SMD0508">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="2" pad="2"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+<device name="-0603" package="SMD0603">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="2" pad="2"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+<device name="-0612" package="SMD0612">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="2" pad="2"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+<device name="-0805" package="SMD0805">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="2" pad="2"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+<device name="-1206" package="SMD1206">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="2" pad="2"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+<device name="-2512" package="SMD2512">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="2" pad="2"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+</devices>
+</deviceset>
+<deviceset name="RN-4" prefix="RN" uservalue="yes">
+<gates>
+<gate name="G$1" symbol="RN-4" x="0" y="0"/>
+</gates>
+<devices>
+<device name="-0603-X4" package="SMD0603-X4">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+<connect gate="G$1" pin="2" pad="2"/>
+<connect gate="G$1" pin="3" pad="3"/>
+<connect gate="G$1" pin="4" pad="4"/>
+<connect gate="G$1" pin="5" pad="5"/>
+<connect gate="G$1" pin="6" pad="6"/>
+<connect gate="G$1" pin="7" pad="7"/>
+<connect gate="G$1" pin="8" pad="8"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+</devices>
+</deviceset>
+</devicesets>
+</library>
+<library name="ataradov_vreg">
+<description>Alex Taradov Library (Voltage Regulators)</description>
+<packages>
+<package name="SOT23-5">
+<description>SOT23-5</description>
+<wire x1="1.422" y1="0.81" x2="1.422" y2="-0.81" width="0.1524" layer="21"/>
+<wire x1="1.422" y1="-0.81" x2="-1.422" y2="-0.81" width="0.1524" layer="51"/>
+<wire x1="-1.422" y1="-0.81" x2="-1.422" y2="0.81" width="0.1524" layer="21"/>
+<wire x1="-1.422" y1="0.81" x2="1.422" y2="0.81" width="0.1524" layer="51"/>
+<wire x1="-0.522" y1="0.81" x2="0.522" y2="0.81" width="0.1524" layer="21"/>
+<wire x1="-0.428" y1="-0.81" x2="-0.522" y2="-0.81" width="0.1524" layer="21"/>
+<wire x1="0.522" y1="-0.81" x2="0.428" y2="-0.81" width="0.1524" layer="21"/>
+<wire x1="-1.328" y1="-0.81" x2="-1.422" y2="-0.81" width="0.1524" layer="21"/>
+<wire x1="1.422" y1="-0.81" x2="1.328" y2="-0.81" width="0.1524" layer="21"/>
+<wire x1="1.328" y1="0.81" x2="1.422" y2="0.81" width="0.1524" layer="21"/>
+<wire x1="-1.422" y1="0.81" x2="-1.328" y2="0.81" width="0.1524" layer="21"/>
+<smd name="1" x="-0.95" y="-1.3" dx="0.55" dy="1.2" layer="1"/>
+<smd name="2" x="0" y="-1.3" dx="0.55" dy="1.2" layer="1"/>
+<smd name="3" x="0.95" y="-1.3" dx="0.55" dy="1.2" layer="1"/>
+<smd name="4" x="0.95" y="1.3" dx="0.55" dy="1.2" layer="1"/>
+<smd name="5" x="-0.95" y="1.3" dx="0.55" dy="1.2" layer="1"/>
+<text x="0" y="2.286" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+<text x="0" y="-3.556" size="1.27" layer="27" font="vector" align="bottom-center">&gt;VALUE</text>
+<rectangle x1="-1.2" y1="-1.5" x2="-0.7" y2="-0.85" layer="51"/>
+<rectangle x1="-0.25" y1="-1.5" x2="0.25" y2="-0.85" layer="51"/>
+<rectangle x1="0.7" y1="-1.5" x2="1.2" y2="-0.85" layer="51"/>
+<rectangle x1="0.7" y1="0.85" x2="1.2" y2="1.5" layer="51"/>
+<rectangle x1="-1.2" y1="0.85" x2="-0.7" y2="1.5" layer="51"/>
+</package>
+</packages>
+<symbols>
+<symbol name="VREG-3-EN">
+<wire x1="-7.62" y1="5.08" x2="7.62" y2="5.08" width="0.254" layer="94"/>
+<wire x1="7.62" y1="5.08" x2="7.62" y2="-2.54" width="0.254" layer="94"/>
+<wire x1="7.62" y1="-2.54" x2="-7.62" y2="-2.54" width="0.254" layer="94"/>
+<wire x1="-7.62" y1="-2.54" x2="-7.62" y2="5.08" width="0.254" layer="94"/>
+<text x="-2.032" y="-1.524" size="1.524" layer="95">GND</text>
+<text x="0" y="5.842" size="1.27" layer="95" align="bottom-center">&gt;NAME</text>
+<text x="1.524" y="-4.318" size="1.27" layer="96">&gt;VALUE</text>
+<pin name="IN" x="-10.16" y="2.54" length="short" direction="sup"/>
+<pin name="OUT" x="10.16" y="2.54" length="short" direction="sup" rot="R180"/>
+<pin name="GND" x="0" y="-5.08" visible="pad" length="short" direction="pwr" rot="R90"/>
+<pin name="EN" x="-10.16" y="0" length="short" direction="in"/>
+</symbol>
+</symbols>
+<devicesets>
+<deviceset name="MIC5504" prefix="IC" uservalue="yes">
+<description>LM1117 voltage regulator</description>
+<gates>
+<gate name="G$1" symbol="VREG-3-EN" x="0" y="0"/>
+</gates>
+<devices>
+<device name="-SOT23-5" package="SOT23-5">
+<connects>
+<connect gate="G$1" pin="EN" pad="3"/>
+<connect gate="G$1" pin="GND" pad="2"/>
+<connect gate="G$1" pin="IN" pad="1"/>
+<connect gate="G$1" pin="OUT" pad="5"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+</devices>
+</deviceset>
+</devicesets>
+</library>
+<library name="ataradov_misc">
+<description>Alex Taradov Library (Miscellaneous stuff)</description>
+<packages>
+<package name="TP-1.27MM">
+<smd name="1" x="0" y="0" dx="1.27" dy="1.27" layer="1" roundness="100" cream="no"/>
+<text x="0" y="1.016" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+<package name="TP-2.54MM">
+<smd name="1" x="0" y="0" dx="2.54" dy="2.54" layer="1" roundness="100" cream="no"/>
+<text x="0" y="1.778" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+</packages>
+<symbols>
+<symbol name="TP">
+<text x="4.064" y="-0.508" size="1.27" layer="95">&gt;NAME</text>
+<pin name="1" x="0" y="0" visible="off" length="short" direction="pas"/>
+<circle x="3.048" y="0" radius="0.508" width="0" layer="94"/>
+</symbol>
+</symbols>
+<devicesets>
+<deviceset name="TEST-POINT" prefix="TP" uservalue="yes">
+<description>Test Point</description>
+<gates>
+<gate name="G$1" symbol="TP" x="0" y="0"/>
+</gates>
+<devices>
+<device name="-1.27MM" package="TP-1.27MM">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+<device name="-2.54MM" package="TP-2.54MM">
+<connects>
+<connect gate="G$1" pin="1" pad="1"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+</devices>
+</deviceset>
+</devicesets>
+</library>
+<library name="ataradov_led">
+<description>Alex Taradov Library (LEDs and other indication devices)</description>
+<packages>
+<package name="SMD0603">
+<wire x1="-1.5" y1="0.75" x2="1.5" y2="0.75" width="0.1" layer="21"/>
+<wire x1="1.5" y1="0.75" x2="1.5" y2="-0.75" width="0.1" layer="21"/>
+<wire x1="1.5" y1="-0.75" x2="-1.5" y2="-0.75" width="0.1" layer="21"/>
+<wire x1="-1.5" y1="-0.75" x2="-1.5" y2="0.75" width="0.1" layer="21"/>
+<smd name="1" x="-0.8" y="0" dx="0.9" dy="0.9" layer="1"/>
+<smd name="2" x="0.8" y="0" dx="0.9" dy="0.9" layer="1"/>
+<text x="0" y="1.016" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+<package name="SMD0805">
+<wire x1="-2" y1="1" x2="2" y2="1" width="0.1" layer="21"/>
+<wire x1="2" y1="1" x2="2" y2="-1" width="0.1" layer="21"/>
+<wire x1="2" y1="-1" x2="-2" y2="-1" width="0.1" layer="21"/>
+<wire x1="-2" y1="-1" x2="-2" y2="1" width="0.1" layer="21"/>
+<smd name="1" x="-0.95" y="0" dx="1.3" dy="1.5" layer="1"/>
+<smd name="2" x="0.95" y="0" dx="1.3" dy="1.5" layer="1"/>
+<text x="0" y="1.27" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+</packages>
+<symbols>
+<symbol name="LED">
+<wire x1="1.27" y1="0" x2="0" y2="-2.54" width="0.254" layer="94"/>
+<wire x1="0" y1="-2.54" x2="-1.27" y2="0" width="0.254" layer="94"/>
+<wire x1="1.27" y1="-2.54" x2="0" y2="-2.54" width="0.254" layer="94"/>
+<wire x1="0" y1="-2.54" x2="-1.27" y2="-2.54" width="0.254" layer="94"/>
+<wire x1="1.27" y1="0" x2="0" y2="0" width="0.254" layer="94"/>
+<wire x1="0" y1="0" x2="-1.27" y2="0" width="0.254" layer="94"/>
+<wire x1="-2.032" y1="-0.762" x2="-3.429" y2="-2.159" width="0.1524" layer="94"/>
+<wire x1="-1.905" y1="-1.905" x2="-3.302" y2="-3.302" width="0.1524" layer="94"/>
+<text x="3.556" y="-2.032" size="1.27" layer="95" rot="R90" align="bottom-center">&gt;NAME</text>
+<text x="5.715" y="-2.032" size="1.27" layer="96" rot="R90" align="bottom-center">&gt;VALUE</text>
+<pin name="C" x="0" y="-5.08" visible="off" length="short" direction="pas" rot="R90"/>
+<pin name="A" x="0" y="2.54" visible="off" length="short" direction="pas" rot="R270"/>
+<polygon width="0.1524" layer="94">
+<vertex x="-3.429" y="-2.159"/>
+<vertex x="-3.048" y="-1.27"/>
+<vertex x="-2.54" y="-1.778"/>
+</polygon>
+<polygon width="0.1524" layer="94">
+<vertex x="-3.302" y="-3.302"/>
+<vertex x="-2.921" y="-2.413"/>
+<vertex x="-2.413" y="-2.921"/>
+</polygon>
+</symbol>
+</symbols>
+<devicesets>
+<deviceset name="LED_SMD" prefix="LED" uservalue="yes">
+<description>SMD_LED</description>
+<gates>
+<gate name="G$1" symbol="LED" x="0" y="0"/>
+</gates>
+<devices>
+<device name="LED_0603" package="SMD0603">
+<connects>
+<connect gate="G$1" pin="A" pad="1"/>
+<connect gate="G$1" pin="C" pad="2"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+<device name="LED_0805" package="SMD0805">
+<connects>
+<connect gate="G$1" pin="A" pad="1"/>
+<connect gate="G$1" pin="C" pad="2"/>
+</connects>
+<technologies>
+<technology name=""/>
+</technologies>
+</device>
+</devices>
+</deviceset>
+</devicesets>
+</library>
+</libraries>
+<attributes>
+</attributes>
+<variantdefs>
+</variantdefs>
+<classes>
+<class number="0" name="default" width="0" drill="0">
+</class>
+</classes>
+<parts>
+<part name="IC2" library="ataradov_mcu" deviceset="ATSAMD11C" device=""/>
+<part name="P_5" library="ataradov_pwr" deviceset="+3V3" device=""/>
+<part name="P_8" library="ataradov_pwr" deviceset="+3V3" device=""/>
+<part name="P_11" library="ataradov_pwr" deviceset="GND" device=""/>
+<part name="P_9" library="ataradov_pwr" deviceset="GND" device=""/>
+<part name="P_10" library="ataradov_pwr" deviceset="V_USB" device=""/>
+<part name="P_3" library="ataradov_pwr" deviceset="V_USB" device=""/>
+<part name="C1" library="ataradov_rlc" deviceset="C" device="-0603" value="1uF"/>
+<part name="C2" library="ataradov_rlc" deviceset="C" device="-0603" value="1uF"/>
+<part name="IC1" library="ataradov_vreg" deviceset="MIC5504" device="-SOT23-5" value="MIC5504-3.3"/>
+<part name="P_4" library="ataradov_pwr" deviceset="GND" device=""/>
+<part name="P_6" library="ataradov_pwr" deviceset="GND" device=""/>
+<part name="P_1" library="ataradov_pwr" deviceset="GND" device=""/>
+<part name="P_2" library="ataradov_pwr" deviceset="GND" device=""/>
+<part name="TP1" library="ataradov_misc" deviceset="TEST-POINT" device="-1.27MM" value="SIO"/>
+<part name="TP2" library="ataradov_misc" deviceset="TEST-POINT" device="-1.27MM"/>
+<part name="TP3" library="ataradov_misc" deviceset="TEST-POINT" device="-1.27MM"/>
+<part name="TP4" library="ataradov_misc" deviceset="TEST-POINT" device="-1.27MM"/>
+<part name="J1" library="ataradov_conn" deviceset="HEADER-5X2" device="-TH-1.27"/>
+<part name="P_7" library="ataradov_pwr" deviceset="GND" device=""/>
+<part name="J2" library="ataradov_conn" deviceset="USB-B-MICRO" device="-SMT"/>
+<part name="R1" library="ataradov_rlc" deviceset="R" device="-0603" value="470"/>
+<part name="LED1" library="ataradov_led" deviceset="LED_SMD" device="LED_0603"/>
+<part name="R2" library="ataradov_rlc" deviceset="R" device="-0603" value="470"/>
+<part name="LED2" library="ataradov_led" deviceset="LED_SMD" device="LED_0603"/>
+<part name="P_13" library="ataradov_pwr" deviceset="GND" device=""/>
+<part name="J3" library="ataradov_conn" deviceset="CONN-SINGLE" device="-TH" value="RX"/>
+<part name="J4" library="ataradov_conn" deviceset="CONN-SINGLE" device="-TH" value="TX"/>
+<part name="J5" library="ataradov_conn" deviceset="CONN-SINGLE" device="-TH" value="GND"/>
+<part name="P_12" library="ataradov_pwr" deviceset="GND" device=""/>
+<part name="RN1" library="ataradov_rlc" deviceset="RN-4" device="-0603-X4" value="100"/>
+</parts>
+<sheets>
+<sheet>
+<plain>
+<frame x1="0" y1="0" x2="152.4" y2="119.38" columns="8" rows="5" layer="97"/>
+<text x="27.94" y="106.68" size="1.778" layer="97" align="bottom-center">Program</text>
+<text x="76.2" y="106.68" size="1.778" layer="97" align="bottom-center">Target</text>
+<text x="60.96" y="15.24" size="1.778" layer="97">Copyright (c) 2016-2019, Alex Taradov &lt;alex@taradov.com&gt;
+
+MCU firmware source code is available at https://github.com/ataradov/free-dap</text>
+<text x="124.46" y="106.68" size="1.778" layer="97" align="bottom-center">UART</text>
+</plain>
+<instances>
+<instance part="IC2" gate="G$1" x="40.64" y="53.34"/>
+<instance part="P_5" gate="1" x="53.34" y="27.94"/>
+<instance part="P_8" gate="1" x="60.96" y="66.04"/>
+<instance part="P_11" gate="1" x="76.2" y="40.64"/>
+<instance part="P_9" gate="1" x="60.96" y="40.64"/>
+<instance part="P_10" gate="1" x="76.2" y="60.96"/>
+<instance part="P_3" gate="1" x="25.4" y="27.94"/>
+<instance part="C1" gate="G$1" x="20.32" y="17.78" rot="R90"/>
+<instance part="C2" gate="G$1" x="53.34" y="17.78" rot="R90"/>
+<instance part="IC1" gate="G$1" x="38.1" y="20.32"/>
+<instance part="P_4" gate="1" x="38.1" y="12.7"/>
+<instance part="P_6" gate="1" x="53.34" y="12.7"/>
+<instance part="P_1" gate="1" x="20.32" y="12.7"/>
+<instance part="P_2" gate="1" x="25.4" y="86.36"/>
+<instance part="TP1" gate="G$1" x="27.94" y="96.52"/>
+<instance part="TP2" gate="G$1" x="27.94" y="93.98"/>
+<instance part="TP3" gate="G$1" x="27.94" y="91.44"/>
+<instance part="TP4" gate="G$1" x="27.94" y="88.9"/>
+<instance part="J1" gate="G$1" x="71.12" y="91.44"/>
+<instance part="P_7" gate="1" x="60.96" y="81.28"/>
+<instance part="J2" gate="G$1" x="86.36" y="50.8"/>
+<instance part="R1" gate="G$1" x="119.38" y="53.34"/>
+<instance part="LED1" gate="G$1" x="129.54" y="53.34" rot="MR270"/>
+<instance part="R2" gate="G$1" x="119.38" y="45.72"/>
+<instance part="LED2" gate="G$1" x="129.54" y="45.72" rot="MR270"/>
+<instance part="P_13" gate="1" x="137.16" y="40.64"/>
+<instance part="J3" gate="G$1" x="127" y="96.52"/>
+<instance part="J4" gate="G$1" x="127" y="93.98"/>
+<instance part="J5" gate="G$1" x="127" y="91.44"/>
+<instance part="P_12" gate="1" x="121.92" y="86.36"/>
+<instance part="RN1" gate="G$1" x="121.92" y="71.12"/>
+</instances>
+<busses>
+</busses>
+<nets>
+<net name="N$1" class="0">
+<segment>
+<pinref part="IC2" gate="G$1" pin="PA24"/>
+<wire x1="58.42" y1="48.26" x2="76.2" y2="48.26" width="0.1524" layer="91"/>
+<wire x1="76.2" y1="48.26" x2="76.2" y2="53.34" width="0.1524" layer="91"/>
+<wire x1="76.2" y1="53.34" x2="78.74" y2="53.34" width="0.1524" layer="91"/>
+<pinref part="J2" gate="G$1" pin="DM"/>
+</segment>
+</net>
+<net name="N$2" class="0">
+<segment>
+<pinref part="IC2" gate="G$1" pin="PA25"/>
+<wire x1="58.42" y1="50.8" x2="78.74" y2="50.8" width="0.1524" layer="91"/>
+<pinref part="J2" gate="G$1" pin="DP"/>
+</segment>
+</net>
+<net name="GND" class="0">
+<segment>
+<pinref part="P_11" gate="1" pin="GND"/>
+<wire x1="76.2" y1="43.18" x2="76.2" y2="45.72" width="0.1524" layer="91"/>
+<wire x1="76.2" y1="45.72" x2="78.74" y2="45.72" width="0.1524" layer="91"/>
+<pinref part="J2" gate="G$1" pin="GND"/>
+</segment>
+<segment>
+<pinref part="IC1" gate="G$1" pin="GND"/>
+<pinref part="P_4" gate="1" pin="GND"/>
+</segment>
+<segment>
+<pinref part="C1" gate="G$1" pin="1"/>
+<pinref part="P_1" gate="1" pin="GND"/>
+</segment>
+<segment>
+<pinref part="C2" gate="G$1" pin="1"/>
+<pinref part="P_6" gate="1" pin="GND"/>
+</segment>
+<segment>
+<pinref part="IC2" gate="G$1" pin="GND"/>
+<pinref part="P_9" gate="1" pin="GND"/>
+<wire x1="58.42" y1="53.34" x2="60.96" y2="53.34" width="0.1524" layer="91"/>
+<wire x1="60.96" y1="53.34" x2="60.96" y2="43.18" width="0.1524" layer="91"/>
+</segment>
+<segment>
+<pinref part="P_2" gate="1" pin="GND"/>
+<wire x1="25.4" y1="88.9" x2="27.94" y2="88.9" width="0.1524" layer="91"/>
+<pinref part="TP4" gate="G$1" pin="1"/>
+</segment>
+<segment>
+<pinref part="J1" gate="G$1" pin="3"/>
+<wire x1="63.5" y1="93.98" x2="60.96" y2="93.98" width="0.1524" layer="91"/>
+<pinref part="P_7" gate="1" pin="GND"/>
+<wire x1="60.96" y1="93.98" x2="60.96" y2="91.44" width="0.1524" layer="91"/>
+<pinref part="J1" gate="G$1" pin="5"/>
+<wire x1="60.96" y1="91.44" x2="60.96" y2="86.36" width="0.1524" layer="91"/>
+<wire x1="60.96" y1="86.36" x2="60.96" y2="83.82" width="0.1524" layer="91"/>
+<wire x1="63.5" y1="91.44" x2="60.96" y2="91.44" width="0.1524" layer="91"/>
+<junction x="60.96" y="91.44"/>
+<pinref part="J1" gate="G$1" pin="9"/>
+<wire x1="63.5" y1="86.36" x2="60.96" y2="86.36" width="0.1524" layer="91"/>
+<junction x="60.96" y="86.36"/>
+</segment>
+<segment>
+<pinref part="P_13" gate="1" pin="GND"/>
+<wire x1="137.16" y1="43.18" x2="137.16" y2="45.72" width="0.1524" layer="91"/>
+<wire x1="137.16" y1="45.72" x2="134.62" y2="45.72" width="0.1524" layer="91"/>
+<pinref part="LED2" gate="G$1" pin="C"/>
+<pinref part="LED1" gate="G$1" pin="C"/>
+<wire x1="137.16" y1="53.34" x2="137.16" y2="45.72" width="0.1524" layer="91"/>
+<wire x1="134.62" y1="53.34" x2="137.16" y2="53.34" width="0.1524" layer="91"/>
+<junction x="137.16" y="45.72"/>
+</segment>
+<segment>
+<pinref part="J5" gate="G$1" pin="1"/>
+<pinref part="P_12" gate="1" pin="GND"/>
+<wire x1="121.92" y1="88.9" x2="121.92" y2="91.44" width="0.1524" layer="91"/>
+<wire x1="121.92" y1="91.44" x2="124.46" y2="91.44" width="0.1524" layer="91"/>
+</segment>
+</net>
+<net name="V_USB" class="0">
+<segment>
+<pinref part="P_10" gate="1" pin="V_USB"/>
+<wire x1="76.2" y1="58.42" x2="76.2" y2="55.88" width="0.1524" layer="91"/>
+<wire x1="76.2" y1="55.88" x2="78.74" y2="55.88" width="0.1524" layer="91"/>
+<pinref part="J2" gate="G$1" pin="VBUS"/>
+</segment>
+<segment>
+<pinref part="IC1" gate="G$1" pin="EN"/>
+<pinref part="P_3" gate="1" pin="V_USB"/>
+<wire x1="27.94" y1="20.32" x2="25.4" y2="20.32" width="0.1524" layer="91"/>
+<wire x1="25.4" y1="20.32" x2="25.4" y2="22.86" width="0.1524" layer="91"/>
+<pinref part="IC1" gate="G$1" pin="IN"/>
+<wire x1="25.4" y1="22.86" x2="25.4" y2="25.4" width="0.1524" layer="91"/>
+<wire x1="27.94" y1="22.86" x2="25.4" y2="22.86" width="0.1524" layer="91"/>
+<junction x="25.4" y="22.86"/>
+<pinref part="C1" gate="G$1" pin="2"/>
+<wire x1="25.4" y1="22.86" x2="20.32" y2="22.86" width="0.1524" layer="91"/>
+<wire x1="20.32" y1="22.86" x2="20.32" y2="20.32" width="0.1524" layer="91"/>
+</segment>
+</net>
+<net name="+3V3" class="0">
+<segment>
+<pinref part="IC1" gate="G$1" pin="OUT"/>
+<wire x1="48.26" y1="22.86" x2="53.34" y2="22.86" width="0.1524" layer="91"/>
+<pinref part="C2" gate="G$1" pin="2"/>
+<wire x1="53.34" y1="20.32" x2="53.34" y2="22.86" width="0.1524" layer="91"/>
+<junction x="53.34" y="22.86"/>
+<pinref part="P_5" gate="1" pin="+3V3"/>
+<wire x1="53.34" y1="25.4" x2="53.34" y2="22.86" width="0.1524" layer="91"/>
+</segment>
+<segment>
+<pinref part="IC2" gate="G$1" pin="VDD"/>
+<pinref part="P_8" gate="1" pin="+3V3"/>
+<wire x1="58.42" y1="55.88" x2="60.96" y2="55.88" width="0.1524" layer="91"/>
+<wire x1="60.96" y1="55.88" x2="60.96" y2="63.5" width="0.1524" layer="91"/>
+</segment>
+</net>
+<net name="SWDIO" class="0">
+<segment>
+<pinref part="IC2" gate="G$1" pin="PA31/SIO"/>
+<wire x1="58.42" y1="45.72" x2="63.5" y2="45.72" width="0.1524" layer="91"/>
+<label x="63.5" y="45.72" size="1.27" layer="95"/>
+</segment>
+<segment>
+<wire x1="27.94" y1="96.52" x2="25.4" y2="96.52" width="0.1524" layer="91"/>
+<label x="25.4" y="96.52" size="1.27" layer="95" rot="MR0"/>
+<pinref part="TP1" gate="G$1" pin="1"/>
+</segment>
+</net>
+<net name="PA02" class="0">
+<segment>
+<pinref part="IC2" gate="G$1" pin="PA02"/>
+<wire x1="58.42" y1="58.42" x2="63.5" y2="58.42" width="0.1524" layer="91"/>
+<label x="63.5" y="58.42" size="1.27" layer="95"/>
+</segment>
+<segment>
+<pinref part="R1" gate="G$1" pin="1"/>
+<wire x1="114.3" y1="53.34" x2="111.76" y2="53.34" width="0.1524" layer="91"/>
+<label x="111.76" y="53.34" size="1.27" layer="95" rot="MR0"/>
+</segment>
+</net>
+<net name="PA04" class="0">
+<segment>
+<pinref part="IC2" gate="G$1" pin="PA04"/>
+<wire x1="58.42" y1="60.96" x2="63.5" y2="60.96" width="0.1524" layer="91"/>
+<label x="63.5" y="60.96" size="1.27" layer="95"/>
+</segment>
+<segment>
+<pinref part="R2" gate="G$1" pin="1"/>
+<wire x1="114.3" y1="45.72" x2="111.76" y2="45.72" width="0.1524" layer="91"/>
+<label x="111.76" y="45.72" size="1.27" layer="95" rot="MR0"/>
+</segment>
+</net>
+<net name="SWCLK" class="0">
+<segment>
+<pinref part="IC2" gate="G$1" pin="PA30/SCK"/>
+<wire x1="22.86" y1="45.72" x2="20.32" y2="45.72" width="0.1524" layer="91"/>
+<label x="20.32" y="45.72" size="1.27" layer="95" rot="MR0"/>
+</segment>
+<segment>
+<label x="25.4" y="93.98" size="1.27" layer="95" rot="MR0"/>
+<wire x1="27.94" y1="93.98" x2="25.4" y2="93.98" width="0.1524" layer="91"/>
+<pinref part="TP2" gate="G$1" pin="1"/>
+</segment>
+</net>
+<net name="RESET" class="0">
+<segment>
+<pinref part="IC2" gate="G$1" pin="PA28/RST"/>
+<wire x1="22.86" y1="48.26" x2="20.32" y2="48.26" width="0.1524" layer="91"/>
+<label x="20.32" y="48.26" size="1.27" layer="95" rot="MR0"/>
+</segment>
+<segment>
+<label x="25.4" y="91.44" size="1.27" layer="95" rot="MR0"/>
+<wire x1="27.94" y1="91.44" x2="25.4" y2="91.44" width="0.1524" layer="91"/>
+<pinref part="TP3" gate="G$1" pin="1"/>
+</segment>
+</net>
+<net name="T_SWDIO" class="0">
+<segment>
+<pinref part="J1" gate="G$1" pin="2"/>
+<wire x1="78.74" y1="96.52" x2="81.28" y2="96.52" width="0.1524" layer="91"/>
+<label x="81.28" y="96.52" size="1.27" layer="95"/>
+</segment>
+<segment>
+<pinref part="RN1" gate="G$1" pin="8"/>
+<wire x1="127" y1="73.66" x2="129.54" y2="73.66" width="0.1524" layer="91"/>
+<label x="129.54" y="73.66" size="1.27" layer="95"/>
+</segment>
+</net>
+<net name="T_SWCLK" class="0">
+<segment>
+<pinref part="J1" gate="G$1" pin="4"/>
+<wire x1="81.28" y1="93.98" x2="78.74" y2="93.98" width="0.1524" layer="91"/>
+<label x="81.28" y="93.98" size="1.27" layer="95"/>
+</segment>
+<segment>
+<pinref part="RN1" gate="G$1" pin="7"/>
+<wire x1="127" y1="71.12" x2="129.54" y2="71.12" width="0.1524" layer="91"/>
+<label x="129.54" y="71.12" size="1.27" layer="95"/>
+</segment>
+</net>
+<net name="T_RESET" class="0">
+<segment>
+<pinref part="J1" gate="G$1" pin="10"/>
+<wire x1="78.74" y1="86.36" x2="81.28" y2="86.36" width="0.1524" layer="91"/>
+<label x="81.28" y="86.36" size="1.27" layer="95"/>
+</segment>
+<segment>
+<pinref part="RN1" gate="G$1" pin="6"/>
+<wire x1="127" y1="68.58" x2="129.54" y2="68.58" width="0.1524" layer="91"/>
+<label x="129.54" y="68.58" size="1.27" layer="95"/>
+</segment>
+</net>
+<net name="PA14" class="0">
+<segment>
+<pinref part="IC2" gate="G$1" pin="PA14"/>
+<wire x1="20.32" y1="53.34" x2="22.86" y2="53.34" width="0.1524" layer="91"/>
+<label x="20.32" y="53.34" size="1.27" layer="95" rot="MR0"/>
+</segment>
+<segment>
+<pinref part="RN1" gate="G$1" pin="2"/>
+<wire x1="116.84" y1="71.12" x2="114.3" y2="71.12" width="0.1524" layer="91"/>
+<label x="114.3" y="71.12" size="1.27" layer="95" rot="MR0"/>
+</segment>
+</net>
+<net name="PA15" class="0">
+<segment>
+<pinref part="IC2" gate="G$1" pin="PA15"/>
+<wire x1="22.86" y1="50.8" x2="20.32" y2="50.8" width="0.1524" layer="91"/>
+<label x="20.32" y="50.8" size="1.27" layer="95" rot="MR0"/>
+</segment>
+<segment>
+<pinref part="RN1" gate="G$1" pin="1"/>
+<wire x1="116.84" y1="73.66" x2="114.3" y2="73.66" width="0.1524" layer="91"/>
+<label x="114.3" y="73.66" size="1.27" layer="95" rot="MR0"/>
+</segment>
+</net>
+<net name="PA09" class="0">
+<segment>
+<pinref part="IC2" gate="G$1" pin="PA9"/>
+<wire x1="22.86" y1="55.88" x2="20.32" y2="55.88" width="0.1524" layer="91"/>
+<label x="20.32" y="55.88" size="1.27" layer="95" rot="MR0"/>
+</segment>
+<segment>
+<pinref part="RN1" gate="G$1" pin="3"/>
+<wire x1="116.84" y1="68.58" x2="114.3" y2="68.58" width="0.1524" layer="91"/>
+<label x="114.3" y="68.58" size="1.27" layer="95" rot="MR0"/>
+</segment>
+</net>
+<net name="PA08" class="0">
+<segment>
+<pinref part="IC2" gate="G$1" pin="PA8"/>
+<wire x1="22.86" y1="58.42" x2="20.32" y2="58.42" width="0.1524" layer="91"/>
+<label x="20.32" y="58.42" size="1.27" layer="95" rot="MR0"/>
+</segment>
+<segment>
+<pinref part="RN1" gate="G$1" pin="4"/>
+<wire x1="116.84" y1="66.04" x2="114.3" y2="66.04" width="0.1524" layer="91"/>
+<label x="114.3" y="66.04" size="1.27" layer="95" rot="MR0"/>
+</segment>
+</net>
+<net name="N$4" class="0">
+<segment>
+<pinref part="R1" gate="G$1" pin="2"/>
+<pinref part="LED1" gate="G$1" pin="A"/>
+<wire x1="124.46" y1="53.34" x2="127" y2="53.34" width="0.1524" layer="91"/>
+</segment>
+</net>
+<net name="N$6" class="0">
+<segment>
+<pinref part="R2" gate="G$1" pin="2"/>
+<pinref part="LED2" gate="G$1" pin="A"/>
+<wire x1="127" y1="45.72" x2="124.46" y2="45.72" width="0.1524" layer="91"/>
+</segment>
+</net>
+<net name="UART_TX" class="0">
+<segment>
+<pinref part="J4" gate="G$1" pin="1"/>
+<wire x1="124.46" y1="93.98" x2="119.38" y2="93.98" width="0.1524" layer="91"/>
+<label x="119.38" y="93.98" size="1.27" layer="95" rot="MR0"/>
+</segment>
+<segment>
+<pinref part="RN1" gate="G$1" pin="5"/>
+<wire x1="129.54" y1="66.04" x2="127" y2="66.04" width="0.1524" layer="91"/>
+<label x="129.54" y="66.04" size="1.27" layer="95"/>
+</segment>
+</net>
+<net name="UART_RX" class="0">
+<segment>
+<pinref part="J3" gate="G$1" pin="1"/>
+<wire x1="124.46" y1="96.52" x2="119.38" y2="96.52" width="0.1524" layer="91"/>
+<label x="119.38" y="96.52" size="1.27" layer="95" rot="MR0"/>
+</segment>
+<segment>
+<pinref part="IC2" gate="G$1" pin="PA5"/>
+<wire x1="22.86" y1="60.96" x2="20.32" y2="60.96" width="0.1524" layer="91"/>
+<label x="20.32" y="60.96" size="1.27" layer="95" rot="MR0"/>
+</segment>
+</net>
+</nets>
+</sheet>
+</sheets>
+</schematic>
+</drawing>
+<compatibility>
+<note version="6.3" minversion="6.2.2" severity="warning">
+Since Version 6.2.2 text objects can contain more than one line,
+which will not be processed correctly with this version.
+</note>
+</compatibility>
+</eagle>

BIN
dap_link/lib/free-dap/hardware/d11_micro_std_vcp/d11_micro_std_vcp_gerber.zip


BIN
dap_link/lib/free-dap/hardware/d11_micro_std_vcp_v2/d11_micro_std_vcp_v2-gerbers.zip


+ 798 - 0
dap_link/lib/free-dap/hardware/d11_micro_std_vcp_v2/d11_micro_std_vcp_v2.brd

@@ -0,0 +1,798 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE eagle SYSTEM "eagle.dtd">
+<eagle version="7.3.0">
+<drawing>
+<settings>
+<setting alwaysvectorfont="no"/>
+<setting verticaltext="up"/>
+</settings>
+<grid distance="0.01" unitdist="inch" unit="inch" style="lines" multiple="1" display="no" altdistance="0.025" altunitdist="inch" altunit="inch"/>
+<layers>
+<layer number="1" name="Top" color="4" fill="1" visible="yes" active="yes"/>
+<layer number="16" name="Bottom" color="1" fill="1" visible="yes" active="yes"/>
+<layer number="17" name="Pads" color="2" fill="1" visible="yes" active="yes"/>
+<layer number="18" name="Vias" color="2" fill="1" visible="yes" active="yes"/>
+<layer number="19" name="Unrouted" color="6" fill="1" visible="yes" active="yes"/>
+<layer number="20" name="Dimension" color="15" fill="1" visible="yes" active="yes"/>
+<layer number="21" name="tPlace" color="7" fill="1" visible="yes" active="yes"/>
+<layer number="22" name="bPlace" color="7" fill="1" visible="yes" active="yes"/>
+<layer number="23" name="tOrigins" color="15" fill="1" visible="yes" active="yes"/>
+<layer number="24" name="bOrigins" color="15" fill="1" visible="yes" active="yes"/>
+<layer number="25" name="tNames" color="7" fill="1" visible="no" active="yes"/>
+<layer number="26" name="bNames" color="7" fill="1" visible="no" active="yes"/>
+<layer number="27" name="tValues" color="7" fill="1" visible="yes" active="yes"/>
+<layer number="28" name="bValues" color="7" fill="1" visible="yes" active="yes"/>
+<layer number="29" name="tStop" color="7" fill="3" visible="no" active="yes"/>
+<layer number="30" name="bStop" color="7" fill="6" visible="no" active="yes"/>
+<layer number="31" name="tCream" color="7" fill="4" visible="no" active="yes"/>
+<layer number="32" name="bCream" color="7" fill="5" visible="no" active="yes"/>
+<layer number="33" name="tFinish" color="6" fill="3" visible="no" active="yes"/>
+<layer number="34" name="bFinish" color="6" fill="6" visible="no" active="yes"/>
+<layer number="35" name="tGlue" color="7" fill="4" visible="no" active="yes"/>
+<layer number="36" name="bGlue" color="7" fill="5" visible="no" active="yes"/>
+<layer number="37" name="tTest" color="7" fill="1" visible="no" active="yes"/>
+<layer number="38" name="bTest" color="7" fill="1" visible="no" active="yes"/>
+<layer number="39" name="tKeepout" color="4" fill="11" visible="yes" active="yes"/>
+<layer number="40" name="bKeepout" color="1" fill="11" visible="yes" active="yes"/>
+<layer number="41" name="tRestrict" color="4" fill="10" visible="yes" active="yes"/>
+<layer number="42" name="bRestrict" color="1" fill="10" visible="yes" active="yes"/>
+<layer number="43" name="vRestrict" color="2" fill="10" visible="yes" active="yes"/>
+<layer number="44" name="Drills" color="7" fill="1" visible="no" active="yes"/>
+<layer number="45" name="Holes" color="7" fill="1" visible="no" active="yes"/>
+<layer number="46" name="Milling" color="3" fill="1" visible="no" active="yes"/>
+<layer number="47" name="Measures" color="7" fill="1" visible="no" active="yes"/>
+<layer number="48" name="Document" color="7" fill="1" visible="yes" active="yes"/>
+<layer number="49" name="Reference" color="7" fill="1" visible="yes" active="yes"/>
+<layer number="51" name="tDocu" color="7" fill="1" visible="no" active="yes"/>
+<layer number="52" name="bDocu" color="7" fill="1" visible="no" active="yes"/>
+<layer number="90" name="Modules" color="5" fill="1" visible="no" active="no"/>
+<layer number="91" name="Nets" color="2" fill="1" visible="no" active="no"/>
+<layer number="92" name="Busses" color="1" fill="1" visible="no" active="no"/>
+<layer number="93" name="Pins" color="2" fill="1" visible="no" active="no"/>
+<layer number="94" name="Symbols" color="4" fill="1" visible="no" active="no"/>
+<layer number="95" name="Names" color="7" fill="1" visible="no" active="no"/>
+<layer number="96" name="Values" color="7" fill="1" visible="no" active="no"/>
+<layer number="97" name="Info" color="7" fill="1" visible="no" active="no"/>
+<layer number="98" name="Guide" color="6" fill="1" visible="no" active="no"/>
+</layers>
+<board>
+<plain>
+<wire x1="0" y1="0" x2="23.368" y2="0" width="0.1524" layer="20"/>
+<wire x1="23.368" y1="0" x2="23.368" y2="11.176" width="0.1524" layer="20"/>
+<wire x1="23.368" y1="11.176" x2="0" y2="11.176" width="0.1524" layer="20"/>
+<wire x1="0" y1="11.176" x2="0" y2="0" width="0.1524" layer="20"/>
+<text x="18.034" y="9.906" size="0.762" layer="21" font="vector" align="bottom-center">01/24/21</text>
+<text x="17.78" y="1.27" size="1.27" layer="21" font="vector" rot="R90" align="bottom-center">1</text>
+<text x="6.35" y="0.762" size="1.27" layer="21" font="vector" align="bottom-center">AT</text>
+<circle x="18.796" y="1.016" radius="0.254" width="0.508" layer="21"/>
+<circle x="18.796" y="1.016" radius="0.254" width="0.508" layer="22"/>
+<text x="13.462" y="5.588" size="0.762" layer="22" font="vector" rot="MR90" align="bottom-center">www.taradov.com</text>
+</plain>
+<libraries>
+<library name="ataradov_mcu">
+<description>Alex Taradov Library (MCUs)</description>
+<packages>
+<package name="QFN24">
+<wire x1="2.196" y1="1.492" x2="2.196" y2="2.196" width="0.127" layer="21"/>
+<wire x1="2.196" y1="2.196" x2="1.492" y2="2.196" width="0.127" layer="21"/>
+<wire x1="1.492" y1="2.196" x2="-1.492" y2="2.196" width="0.127" layer="51"/>
+<wire x1="-1.492" y1="2.196" x2="-2.196" y2="1.492" width="0.127" layer="21"/>
+<wire x1="-2.196" y1="1.492" x2="-2.196" y2="-1.492" width="0.127" layer="51"/>
+<wire x1="-2.196" y1="-1.492" x2="-2.196" y2="-2.196" width="0.127" layer="21"/>
+<wire x1="-2.196" y1="-2.196" x2="-1.492" y2="-2.196" width="0.127" layer="21"/>
+<wire x1="-1.492" y1="-2.196" x2="1.492" y2="-2.196" width="0.127" layer="51"/>
+<wire x1="1.492" y1="-2.196" x2="2.196" y2="-2.196" width="0.127" layer="21"/>
+<wire x1="2.196" y1="-2.196" x2="2.196" y2="-1.492" width="0.127" layer="21"/>
+<wire x1="2.196" y1="-1.492" x2="2.196" y2="1.492" width="0.127" layer="51"/>
+<smd name="1" x="-1.85" y="1.25" dx="0.7" dy="0.28" layer="1" roundness="50" stop="no"/>
+<smd name="2" x="-1.85" y="0.75" dx="0.7" dy="0.28" layer="1" stop="no"/>
+<smd name="3" x="-1.85" y="0.25" dx="0.7" dy="0.28" layer="1" stop="no"/>
+<smd name="4" x="-1.85" y="-0.25" dx="0.7" dy="0.28" layer="1" stop="no"/>
+<smd name="5" x="-1.85" y="-0.75" dx="0.7" dy="0.28" layer="1" stop="no"/>
+<smd name="6" x="-1.85" y="-1.25" dx="0.7" dy="0.28" layer="1" roundness="50" stop="no"/>
+<smd name="7" x="-1.25" y="-1.85" dx="0.28" dy="0.7" layer="1" roundness="50" stop="no"/>
+<smd name="8" x="-0.75" y="-1.85" dx="0.28" dy="0.7" layer="1" stop="no"/>
+<smd name="9" x="-0.25" y="-1.85" dx="0.28" dy="0.7" layer="1" stop="no"/>
+<smd name="10" x="0.25" y="-1.85" dx="0.28" dy="0.7" layer="1" stop="no"/>
+<smd name="11" x="0.75" y="-1.85" dx="0.28" dy="0.7" layer="1" stop="no"/>
+<smd name="12" x="1.25" y="-1.85" dx="0.28" dy="0.7" layer="1" roundness="50" stop="no"/>
+<smd name="13" x="1.85" y="-1.25" dx="0.7" dy="0.28" layer="1" roundness="50" stop="no"/>
+<smd name="14" x="1.85" y="-0.75" dx="0.7" dy="0.28" layer="1" stop="no"/>
+<smd name="15" x="1.85" y="-0.25" dx="0.7" dy="0.28" layer="1" stop="no"/>
+<smd name="16" x="1.85" y="0.25" dx="0.7" dy="0.28" layer="1" stop="no"/>
+<smd name="17" x="1.85" y="0.75" dx="0.7" dy="0.28" layer="1" stop="no"/>
+<smd name="18" x="1.85" y="1.25" dx="0.7" dy="0.28" layer="1" roundness="50" stop="no"/>
+<smd name="19" x="1.25" y="1.85" dx="0.28" dy="0.7" layer="1" roundness="50" stop="no"/>
+<smd name="20" x="0.75" y="1.85" dx="0.28" dy="0.7" layer="1" stop="no"/>
+<smd name="21" x="0.25" y="1.85" dx="0.28" dy="0.7" layer="1" stop="no"/>
+<smd name="22" x="-0.25" y="1.85" dx="0.28" dy="0.7" layer="1" stop="no"/>
+<smd name="23" x="-0.75" y="1.85" dx="0.28" dy="0.7" layer="1" stop="no"/>
+<smd name="24" x="-1.25" y="1.85" dx="0.28" dy="0.7" layer="1" roundness="50" stop="no"/>
+<smd name="PAD" x="0" y="0" dx="2" dy="2" layer="1" stop="no"/>
+<text x="0" y="2.54" size="1.27" layer="25" font="vector" ratio="10" align="bottom-center">&gt;NAME</text>
+<rectangle x1="-1.024" y1="-1.024" x2="1.024" y2="1.024" layer="29"/>
+<rectangle x1="-2.225" y1="1.075" x2="-1.475" y2="1.425" layer="29"/>
+<rectangle x1="-2.225" y1="0.575" x2="-1.475" y2="0.925" layer="29"/>
+<rectangle x1="-2.225" y1="0.075" x2="-1.475" y2="0.425" layer="29"/>
+<rectangle x1="-2.225" y1="-0.425" x2="-1.475" y2="-0.075" layer="29"/>
+<rectangle x1="-2.225" y1="-0.925" x2="-1.475" y2="-0.575" layer="29"/>
+<rectangle x1="-2.225" y1="-1.425" x2="-1.475" y2="-1.075" layer="29"/>
+<rectangle x1="-1.625" y1="-2.025" x2="-0.875" y2="-1.675" layer="29" rot="R90"/>
+<rectangle x1="-1.125" y1="-2.025" x2="-0.375" y2="-1.675" layer="29" rot="R90"/>
+<rectangle x1="-0.625" y1="-2.025" x2="0.125" y2="-1.675" layer="29" rot="R90"/>
+<rectangle x1="-0.125" y1="-2.025" x2="0.625" y2="-1.675" layer="29" rot="R90"/>
+<rectangle x1="0.375" y1="-2.025" x2="1.125" y2="-1.675" layer="29" rot="R90"/>
+<rectangle x1="0.875" y1="-2.025" x2="1.625" y2="-1.675" layer="29" rot="R90"/>
+<rectangle x1="1.475" y1="-1.425" x2="2.225" y2="-1.075" layer="29" rot="R180"/>
+<rectangle x1="1.475" y1="-0.925" x2="2.225" y2="-0.575" layer="29" rot="R180"/>
+<rectangle x1="1.475" y1="-0.425" x2="2.225" y2="-0.075" layer="29" rot="R180"/>
+<rectangle x1="1.475" y1="0.075" x2="2.225" y2="0.425" layer="29" rot="R180"/>
+<rectangle x1="1.475" y1="0.575" x2="2.225" y2="0.925" layer="29" rot="R180"/>
+<rectangle x1="1.475" y1="1.075" x2="2.225" y2="1.425" layer="29" rot="R180"/>
+<rectangle x1="0.875" y1="1.675" x2="1.625" y2="2.025" layer="29" rot="R270"/>
+<rectangle x1="0.375" y1="1.675" x2="1.125" y2="2.025" layer="29" rot="R270"/>
+<rectangle x1="-0.125" y1="1.675" x2="0.625" y2="2.025" layer="29" rot="R270"/>
+<rectangle x1="-0.625" y1="1.675" x2="0.125" y2="2.025" layer="29" rot="R270"/>
+<rectangle x1="-1.125" y1="1.675" x2="-0.375" y2="2.025" layer="29" rot="R270"/>
+<rectangle x1="-1.625" y1="1.675" x2="-0.875" y2="2.025" layer="29" rot="R270"/>
+</package>
+</packages>
+</library>
+<library name="ataradov_conn">
+<description>Alex Taradov Library (Connectors)</description>
+<packages>
+<package name="HEADER-5X2-1.27MM">
+<wire x1="-3.81" y1="1.905" x2="3.81" y2="1.905" width="0.127" layer="21"/>
+<wire x1="3.81" y1="1.905" x2="3.81" y2="-1.905" width="0.127" layer="21"/>
+<wire x1="3.81" y1="-1.905" x2="-3.175" y2="-1.905" width="0.127" layer="21"/>
+<wire x1="-3.175" y1="-1.905" x2="-3.81" y2="-1.27" width="0.127" layer="21"/>
+<wire x1="-3.81" y1="-1.27" x2="-3.81" y2="1.905" width="0.127" layer="21"/>
+<pad name="1" x="-2.54" y="-0.635" drill="0.6096" diameter="1.016"/>
+<pad name="2" x="-2.54" y="0.635" drill="0.6096" diameter="1.016"/>
+<pad name="3" x="-1.27" y="-0.635" drill="0.6096" diameter="1.016"/>
+<pad name="4" x="-1.27" y="0.635" drill="0.6096" diameter="1.016"/>
+<pad name="5" x="0" y="-0.635" drill="0.6096" diameter="1.016"/>
+<pad name="6" x="0" y="0.635" drill="0.6096" diameter="1.016"/>
+<pad name="7" x="1.27" y="-0.635" drill="0.6096" diameter="1.016"/>
+<pad name="8" x="1.27" y="0.635" drill="0.6096" diameter="1.016"/>
+<pad name="9" x="2.54" y="-0.635" drill="0.6096" diameter="1.016"/>
+<pad name="10" x="2.54" y="0.635" drill="0.6096" diameter="1.016"/>
+<text x="0" y="2.54" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+<package name="USB-B-MICRO-SMT-SHELL-TH">
+<pad name="M1" x="2.15" y="-3.6" drill="1.143"/>
+<pad name="M2" x="2.15" y="3.6" drill="1.143"/>
+<smd name="1" x="4.825" y="1.3" dx="1.35" dy="0.4" layer="1" stop="no"/>
+<smd name="2" x="4.825" y="0.65" dx="1.35" dy="0.4" layer="1" stop="no"/>
+<smd name="3" x="4.825" y="0" dx="1.35" dy="0.4" layer="1" stop="no"/>
+<smd name="4" x="4.825" y="-0.65" dx="1.35" dy="0.4" layer="1" stop="no"/>
+<smd name="5" x="4.825" y="-1.3" dx="1.35" dy="0.4" layer="1" stop="no"/>
+<text x="3.175" y="0" size="1.27" layer="25" font="vector" rot="R90" align="bottom-center">&gt;NAME</text>
+<rectangle x1="4.1" y1="1.05" x2="5.55" y2="1.55" layer="29"/>
+<pad name="M3" x="5.05" y="2.425" drill="0.635" shape="long"/>
+<pad name="M4" x="5.05" y="-2.425" drill="0.635" shape="long"/>
+<rectangle x1="4.1" y1="0.4" x2="5.55" y2="0.9" layer="29"/>
+<rectangle x1="4.1" y1="-0.25" x2="5.55" y2="0.25" layer="29"/>
+<rectangle x1="4.1" y1="-0.9" x2="5.55" y2="-0.4" layer="29"/>
+<rectangle x1="4.1" y1="-1.55" x2="5.55" y2="-1.05" layer="29"/>
+<wire x1="-0.5" y1="4" x2="-0.6" y2="3.8" width="0.1524" layer="21"/>
+<wire x1="-0.6" y1="3.8" x2="0" y2="3.5" width="0.1524" layer="21"/>
+<wire x1="0" y1="3.5" x2="0" y2="3.1" width="0.1524" layer="21"/>
+<wire x1="0" y1="3.1" x2="-0.6" y2="3.1" width="0.1524" layer="21"/>
+<wire x1="-0.6" y1="3.1" x2="-0.6" y2="-3.1" width="0.1524" layer="21"/>
+<wire x1="-0.6" y1="-3.1" x2="0" y2="-3.1" width="0.1524" layer="21"/>
+<wire x1="0" y1="-3.1" x2="0" y2="-3.5" width="0.1524" layer="21"/>
+<wire x1="0" y1="-3.5" x2="-0.6" y2="-3.8" width="0.1524" layer="21"/>
+<wire x1="-0.6" y1="-3.8" x2="-0.5" y2="-4" width="0.1524" layer="21"/>
+<wire x1="-0.5" y1="-4" x2="0" y2="-3.75" width="0.1524" layer="21"/>
+<wire x1="0" y1="-3.75" x2="5" y2="-3.75" width="0.1524" layer="21"/>
+<wire x1="5" y1="-3.75" x2="5" y2="-3.16" width="0.1524" layer="21"/>
+<wire x1="-0.5" y1="4" x2="0" y2="3.75" width="0.1524" layer="21"/>
+<wire x1="0" y1="3.75" x2="5" y2="3.75" width="0.1524" layer="21"/>
+<wire x1="5" y1="3.75" x2="5" y2="3.16" width="0.1524" layer="21"/>
+</package>
+<package name="PIN-TH">
+<wire x1="-0.635" y1="1.27" x2="0.635" y2="1.27" width="0.1524" layer="21"/>
+<wire x1="0.635" y1="1.27" x2="1.27" y2="0.635" width="0.1524" layer="21"/>
+<wire x1="1.27" y1="0.635" x2="1.27" y2="-0.635" width="0.1524" layer="21"/>
+<wire x1="1.27" y1="-0.635" x2="0.635" y2="-1.27" width="0.1524" layer="21"/>
+<wire x1="-1.27" y1="0.635" x2="-1.27" y2="-0.635" width="0.1524" layer="21"/>
+<wire x1="-0.635" y1="1.27" x2="-1.27" y2="0.635" width="0.1524" layer="21"/>
+<wire x1="-1.27" y1="-0.635" x2="-0.635" y2="-1.27" width="0.1524" layer="21"/>
+<wire x1="0.635" y1="-1.27" x2="-0.635" y2="-1.27" width="0.1524" layer="21"/>
+<pad name="1" x="0" y="0" drill="1.016"/>
+<text x="0" y="1.524" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+<text x="0" y="-2.794" size="1.27" layer="21" font="vector" align="bottom-center">&gt;VALUE</text>
+</package>
+</packages>
+</library>
+<library name="ataradov_rlc">
+<description>Alex Taradov Library (R, L and C)</description>
+<packages>
+<package name="SMD0603">
+<wire x1="-1.5" y1="0.75" x2="1.5" y2="0.75" width="0.1" layer="21"/>
+<wire x1="1.5" y1="0.75" x2="1.5" y2="-0.75" width="0.1" layer="21"/>
+<wire x1="1.5" y1="-0.75" x2="-1.5" y2="-0.75" width="0.1" layer="21"/>
+<wire x1="-1.5" y1="-0.75" x2="-1.5" y2="0.75" width="0.1" layer="21"/>
+<smd name="1" x="-0.8" y="0" dx="0.9" dy="0.9" layer="1"/>
+<smd name="2" x="0.8" y="0" dx="0.9" dy="0.9" layer="1"/>
+<text x="0" y="1.016" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+<text x="0" y="-0.254" size="0.508" layer="27" font="vector" align="bottom-center">&gt;VALUE</text>
+</package>
+<package name="SMD0603-X4">
+<smd name="1" x="-1.2" y="-0.752" dx="0.5" dy="0.889" layer="1"/>
+<smd name="2" x="-0.4" y="-0.752" dx="0.5" dy="0.889" layer="1"/>
+<smd name="3" x="0.4" y="-0.752" dx="0.5" dy="0.889" layer="1"/>
+<smd name="4" x="1.2" y="-0.752" dx="0.5" dy="0.889" layer="1"/>
+<smd name="5" x="1.2" y="0.752" dx="0.5" dy="0.889" layer="1"/>
+<smd name="6" x="0.4" y="0.752" dx="0.5" dy="0.889" layer="1"/>
+<smd name="7" x="-0.4" y="0.752" dx="0.5" dy="0.889" layer="1"/>
+<smd name="8" x="-1.2" y="0.752" dx="0.5" dy="0.889" layer="1"/>
+<text x="0" y="1.778" size="1.27" layer="25" font="vector" ratio="10" align="bottom-center">&gt;NAME</text>
+<wire x1="1.778" y1="1.4986" x2="1.778" y2="-1.524" width="0.1016" layer="21"/>
+<wire x1="-1.778" y1="1.4986" x2="-1.778" y2="-1.524" width="0.1016" layer="21"/>
+<wire x1="-1.778" y1="1.4986" x2="1.778" y2="1.4986" width="0.1016" layer="21"/>
+<wire x1="-1.778" y1="-1.524" x2="1.778" y2="-1.524" width="0.1016" layer="21"/>
+<text x="0" y="-0.254" size="0.508" layer="27" font="vector" ratio="10" align="bottom-center">&gt;VALUE</text>
+</package>
+</packages>
+</library>
+<library name="ataradov_vreg">
+<description>Alex Taradov Library (Voltage Regulators)</description>
+<packages>
+<package name="SOT23-5">
+<description>SOT23-5</description>
+<wire x1="1.422" y1="0.81" x2="1.422" y2="-0.81" width="0.1524" layer="21"/>
+<wire x1="1.422" y1="-0.81" x2="-1.422" y2="-0.81" width="0.1524" layer="51"/>
+<wire x1="-1.422" y1="-0.81" x2="-1.422" y2="0.81" width="0.1524" layer="21"/>
+<wire x1="-1.422" y1="0.81" x2="1.422" y2="0.81" width="0.1524" layer="51"/>
+<wire x1="-0.522" y1="0.81" x2="0.522" y2="0.81" width="0.1524" layer="21"/>
+<wire x1="-0.428" y1="-0.81" x2="-0.522" y2="-0.81" width="0.1524" layer="21"/>
+<wire x1="0.522" y1="-0.81" x2="0.428" y2="-0.81" width="0.1524" layer="21"/>
+<wire x1="-1.328" y1="-0.81" x2="-1.422" y2="-0.81" width="0.1524" layer="21"/>
+<wire x1="1.422" y1="-0.81" x2="1.328" y2="-0.81" width="0.1524" layer="21"/>
+<wire x1="1.328" y1="0.81" x2="1.422" y2="0.81" width="0.1524" layer="21"/>
+<wire x1="-1.422" y1="0.81" x2="-1.328" y2="0.81" width="0.1524" layer="21"/>
+<smd name="1" x="-0.95" y="-1.3" dx="0.55" dy="1.2" layer="1"/>
+<smd name="2" x="0" y="-1.3" dx="0.55" dy="1.2" layer="1"/>
+<smd name="3" x="0.95" y="-1.3" dx="0.55" dy="1.2" layer="1"/>
+<smd name="4" x="0.95" y="1.3" dx="0.55" dy="1.2" layer="1"/>
+<smd name="5" x="-0.95" y="1.3" dx="0.55" dy="1.2" layer="1"/>
+<text x="0" y="2.286" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+</packages>
+</library>
+<library name="ataradov_misc">
+<description>Alex Taradov Library (Miscellaneous stuff)</description>
+<packages>
+<package name="TP-1.27MM">
+<smd name="1" x="0" y="0" dx="1.27" dy="1.27" layer="1" roundness="100" cream="no"/>
+<text x="0" y="1.016" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+</package>
+<package name="SB-1.27MM-NO">
+<smd name="1" x="-0.508" y="0" dx="0.762" dy="1.27" layer="1" cream="no"/>
+<text x="0" y="1.016" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+<text x="0" y="-2.286" size="1.27" layer="27" font="vector" align="bottom-center">&gt;VALUE</text>
+<smd name="2" x="0.508" y="0" dx="0.762" dy="1.27" layer="1" cream="no"/>
+<rectangle x1="-1.016" y1="-0.762" x2="1.016" y2="0.762" layer="29"/>
+</package>
+</packages>
+</library>
+<library name="ataradov_led">
+<description>Alex Taradov Library (LEDs and other indication devices)</description>
+<packages>
+<package name="SMD0603">
+<wire x1="-1.5" y1="0.75" x2="1.5" y2="0.75" width="0.1" layer="21"/>
+<wire x1="1.5" y1="0.75" x2="1.5" y2="-0.75" width="0.1" layer="21"/>
+<wire x1="1.5" y1="-0.75" x2="-1.5" y2="-0.75" width="0.1" layer="21"/>
+<wire x1="-1.5" y1="-0.75" x2="-1.5" y2="0.75" width="0.1" layer="21"/>
+<smd name="1" x="-0.8" y="0" dx="0.9" dy="0.9" layer="1"/>
+<smd name="2" x="0.8" y="0" dx="0.9" dy="0.9" layer="1"/>
+<text x="0" y="1.016" size="1.27" layer="25" font="vector" align="bottom-center">&gt;NAME</text>
+<text x="0" y="-0.254" size="0.508" layer="27" font="vector" align="bottom-center">&gt;VALUE</text>
+</package>
+</packages>
+</library>
+</libraries>
+<attributes>
+</attributes>
+<variantdefs>
+</variantdefs>
+<classes>
+<class number="0" name="default" width="0" drill="0">
+</class>
+</classes>
+<designrules name="std-tented-new">
+<description language="de">&lt;b&gt;EAGLE Design Rules&lt;/b&gt;
+&lt;p&gt;
+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.</description>
+<description language="en">&lt;b&gt;Laen's PCB Order Design Rules&lt;/b&gt;
+&lt;p&gt;
+Please make sure your boards conform to these design rules.</description>
+<param name="layerSetup" value="(1*16)"/>
+<param name="mtCopper" value="0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm"/>
+<param name="mtIsolate" value="1.5011mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm"/>
+<param name="mdWireWire" value="6mil"/>
+<param name="mdWirePad" value="6mil"/>
+<param name="mdWireVia" value="6mil"/>
+<param name="mdPadPad" value="6mil"/>
+<param name="mdPadVia" value="6mil"/>
+<param name="mdViaVia" value="6mil"/>
+<param name="mdSmdPad" value="0mil"/>
+<param name="mdSmdVia" value="0mil"/>
+<param name="mdSmdSmd" value="0mil"/>
+<param name="mdViaViaSameLayer" value="8mil"/>
+<param name="mnLayersViaInSmd" value="2"/>
+<param name="mdCopperDimension" value="10mil"/>
+<param name="mdDrill" value="6mil"/>
+<param name="mdSmdStop" value="0mil"/>
+<param name="msWidth" value="8mil"/>
+<param name="msDrill" value="13mil"/>
+<param name="msMicroVia" value="13mil"/>
+<param name="msBlindViaRatio" value="0.5"/>
+<param name="rvPadTop" value="0.25"/>
+<param name="rvPadInner" value="0.25"/>
+<param name="rvPadBottom" value="0.25"/>
+<param name="rvViaOuter" value="0.25"/>
+<param name="rvViaInner" value="0.25"/>
+<param name="rvMicroViaOuter" value="0.25"/>
+<param name="rvMicroViaInner" value="0.25"/>
+<param name="rlMinPadTop" value="7mil"/>
+<param name="rlMaxPadTop" value="20mil"/>
+<param name="rlMinPadInner" value="7mil"/>
+<param name="rlMaxPadInner" value="20mil"/>
+<param name="rlMinPadBottom" value="7mil"/>
+<param name="rlMaxPadBottom" value="20mil"/>
+<param name="rlMinViaOuter" value="7mil"/>
+<param name="rlMaxViaOuter" value="20mil"/>
+<param name="rlMinViaInner" value="7mil"/>
+<param name="rlMaxViaInner" value="20mil"/>
+<param name="rlMinMicroViaOuter" value="4mil"/>
+<param name="rlMaxMicroViaOuter" value="20mil"/>
+<param name="rlMinMicroViaInner" value="4mil"/>
+<param name="rlMaxMicroViaInner" value="20mil"/>
+<param name="psTop" value="-1"/>
+<param name="psBottom" value="-1"/>
+<param name="psFirst" value="-1"/>
+<param name="psElongationLong" value="100"/>
+<param name="psElongationOffset" value="100"/>
+<param name="mvStopFrame" value="1"/>
+<param name="mvCreamFrame" value="0"/>
+<param name="mlMinStopFrame" value="3mil"/>
+<param name="mlMaxStopFrame" value="3mil"/>
+<param name="mlMinCreamFrame" value="0mil"/>
+<param name="mlMaxCreamFrame" value="0mil"/>
+<param name="mlViaStopLimit" value="25mil"/>
+<param name="srRoundness" value="0"/>
+<param name="srMinRoundness" value="0mil"/>
+<param name="srMaxRoundness" value="0mil"/>
+<param name="slThermalIsolate" value="6mil"/>
+<param name="slThermalsForVias" value="0"/>
+<param name="dpMaxLengthDifference" value="10mm"/>
+<param name="dpGapFactor" value="2.5"/>
+<param name="checkGrid" value="0"/>
+<param name="checkAngle" value="0"/>
+<param name="checkFont" value="1"/>
+<param name="checkRestrict" value="1"/>
+<param name="useDiameter" value="13"/>
+<param name="maxErrors" value="50"/>
+</designrules>
+<autorouter>
+<pass name="Default">
+<param name="RoutingGrid" value="50mil"/>
+<param name="AutoGrid" value="1"/>
+<param name="Efforts" value="0"/>
+<param name="TopRouterVariant" value="1"/>
+<param name="tpViaShape" value="round"/>
+<param name="PrefDir.1" value="a"/>
+<param name="PrefDir.2" value="0"/>
+<param name="PrefDir.3" value="0"/>
+<param name="PrefDir.4" value="0"/>
+<param name="PrefDir.5" value="0"/>
+<param name="PrefDir.6" value="0"/>
+<param name="PrefDir.7" value="0"/>
+<param name="PrefDir.8" value="0"/>
+<param name="PrefDir.9" value="0"/>
+<param name="PrefDir.10" value="0"/>
+<param name="PrefDir.11" value="0"/>
+<param name="PrefDir.12" value="0"/>
+<param name="PrefDir.13" value="0"/>
+<param name="PrefDir.14" value="0"/>
+<param name="PrefDir.15" value="0"/>
+<param name="PrefDir.16" value="a"/>
+<param name="cfVia" value="8"/>
+<param name="cfNonPref" value="5"/>
+<param name="cfChangeDir" value="2"/>
+<param name="cfOrthStep" value="2"/>
+<param name="cfDiagStep" value="3"/>
+<param name="cfExtdStep" value="0"/>
+<param name="cfBonusStep" value="1"/>
+<param name="cfMalusStep" value="1"/>
+<param name="cfPadImpact" value="4"/>
+<param name="cfSmdImpact" value="4"/>
+<param name="cfBusImpact" value="0"/>
+<param name="cfHugging" value="3"/>
+<param name="cfAvoid" value="4"/>
+<param name="cfPolygon" value="10"/>
+<param name="cfBase.1" value="0"/>
+<param name="cfBase.2" value="1"/>
+<param name="cfBase.3" value="1"/>
+<param name="cfBase.4" value="1"/>
+<param name="cfBase.5" value="1"/>
+<param name="cfBase.6" value="1"/>
+<param name="cfBase.7" value="1"/>
+<param name="cfBase.8" value="1"/>
+<param name="cfBase.9" value="1"/>
+<param name="cfBase.10" value="1"/>
+<param name="cfBase.11" value="1"/>
+<param name="cfBase.12" value="1"/>
+<param name="cfBase.13" value="1"/>
+<param name="cfBase.14" value="1"/>
+<param name="cfBase.15" value="1"/>
+<param name="cfBase.16" value="0"/>
+<param name="mnVias" value="20"/>
+<param name="mnSegments" value="9999"/>
+<param name="mnExtdSteps" value="9999"/>
+<param name="mnRipupLevel" value="10"/>
+<param name="mnRipupSteps" value="100"/>
+<param name="mnRipupTotal" value="100"/>
+</pass>
+<pass name="Follow-me" refer="Default" active="yes">
+</pass>
+<pass name="Busses" refer="Default" active="yes">
+<param name="cfNonPref" value="4"/>
+<param name="cfBusImpact" value="4"/>
+<param name="cfHugging" value="0"/>
+<param name="mnVias" value="0"/>
+</pass>
+<pass name="Route" refer="Default" active="yes">
+</pass>
+<pass name="Optimize1" refer="Default" active="yes">
+<param name="cfVia" value="99"/>
+<param name="cfExtdStep" value="10"/>
+<param name="cfHugging" value="1"/>
+<param name="mnExtdSteps" value="1"/>
+<param name="mnRipupLevel" value="0"/>
+</pass>
+<pass name="Optimize2" refer="Optimize1" active="yes">
+<param name="cfNonPref" value="0"/>
+<param name="cfChangeDir" value="6"/>
+<param name="cfExtdStep" value="0"/>
+<param name="cfBonusStep" value="2"/>
+<param name="cfMalusStep" value="2"/>
+<param name="cfPadImpact" value="2"/>
+<param name="cfSmdImpact" value="2"/>
+<param name="cfHugging" value="0"/>
+</pass>
+<pass name="Optimize3" refer="Optimize2" active="yes">
+<param name="cfChangeDir" value="8"/>
+<param name="cfPadImpact" value="0"/>
+<param name="cfSmdImpact" value="0"/>
+</pass>
+<pass name="Optimize4" refer="Optimize3" active="yes">
+<param name="cfChangeDir" value="25"/>
+</pass>
+</autorouter>
+<elements>
+<element name="C1" library="ataradov_rlc" package="SMD0603" value="1uF" x="1.27" y="5.588" rot="MR270"/>
+<element name="C2" library="ataradov_rlc" package="SMD0603" value="1uF" x="6.858" y="5.588" smashed="yes" rot="MR270">
+<attribute name="NAME" x="5.842" y="5.588" size="1.27" layer="26" font="vector" rot="MR270" align="bottom-center"/>
+</element>
+<element name="IC2" library="ataradov_vreg" package="SOT23-5" value="MIC5504-3.3" x="4.064" y="5.588" smashed="yes" rot="MR90">
+<attribute name="NAME" x="6.35" y="5.588" size="1.27" layer="26" font="vector" rot="MR90" align="bottom-center"/>
+</element>
+<element name="TP1" library="ataradov_misc" package="TP-1.27MM" value="SIO" x="6.604" y="9.652" rot="MR0"/>
+<element name="TP2" library="ataradov_misc" package="TP-1.27MM" value="" x="11.684" y="9.652" rot="MR0"/>
+<element name="TP3" library="ataradov_misc" package="TP-1.27MM" value="" x="9.144" y="9.652" rot="MR0"/>
+<element name="TP4" library="ataradov_misc" package="TP-1.27MM" value="" x="4.064" y="9.652" rot="MR0"/>
+<element name="J2" library="ataradov_conn" package="HEADER-5X2-1.27MM" value="HEADER-5X2-TH-1.27" x="17.018" y="5.588" rot="R90"/>
+<element name="J1" library="ataradov_conn" package="USB-B-MICRO-SMT-SHELL-TH" value="" x="0" y="5.588"/>
+<element name="R1" library="ataradov_rlc" package="SMD0603" value="10K" x="8.382" y="2.286" rot="MR90"/>
+<element name="LED1" library="ataradov_led" package="SMD0603" value="ORANGE" x="8.382" y="2.286" rot="R270"/>
+<element name="R2" library="ataradov_rlc" package="SMD0603" value="10K" x="9.906" y="2.286" rot="MR90"/>
+<element name="LED2" library="ataradov_led" package="SMD0603" value="GREEN" x="9.906" y="2.286" rot="R270"/>
+<element name="J3" library="ataradov_conn" package="PIN-TH" value="RX" x="19.812" y="8.128" smashed="yes" rot="R90">
+<attribute name="NAME" x="18.288" y="8.128" size="1.27" layer="25" font="vector" rot="R90" align="bottom-center"/>
+<attribute name="VALUE" x="22.606" y="8.89" size="1.27" layer="22" font="vector" rot="MR270" align="bottom-center"/>
+</element>
+<element name="J4" library="ataradov_conn" package="PIN-TH" value="TX" x="19.812" y="5.588" smashed="yes" rot="R90">
+<attribute name="NAME" x="18.288" y="5.588" size="1.27" layer="25" font="vector" rot="R90" align="bottom-center"/>
+<attribute name="VALUE" x="22.606" y="5.842" size="1.27" layer="22" font="vector" rot="MR270" align="bottom-center"/>
+</element>
+<element name="J5" library="ataradov_conn" package="PIN-TH" value="GND" x="19.812" y="3.048" smashed="yes" rot="R90">
+<attribute name="NAME" x="18.288" y="3.048" size="1.27" layer="25" font="vector" rot="R90" align="bottom-center"/>
+<attribute name="VALUE" x="22.606" y="2.54" size="1.27" layer="22" font="vector" rot="MR270" align="bottom-center"/>
+</element>
+<element name="RN1" library="ataradov_rlc" package="SMD0603-X4" value="100" x="13.462" y="8.128" rot="R90"/>
+<element name="SB1" library="ataradov_misc" package="SB-1.27MM-NO" value="" x="12.7" y="1.524"/>
+<element name="IC1" library="ataradov_mcu" package="QFN24" value="ATSAMD11D" x="9.144" y="6.35" rot="R90"/>
+<element name="RN2" library="ataradov_rlc" package="SMD0603-X4" value="100" x="13.462" y="4.572" rot="R90"/>
+</elements>
+<signals>
+<signal name="GND">
+<contactref element="IC2" pad="2"/>
+<contactref element="C1" pad="1"/>
+<contactref element="C2" pad="1"/>
+<contactref element="TP4" pad="1"/>
+<contactref element="J2" pad="3"/>
+<contactref element="J2" pad="5"/>
+<contactref element="J1" pad="5"/>
+<polygon width="0.254" layer="16" isolate="0.2032">
+<vertex x="0" y="11.176"/>
+<vertex x="23.368" y="11.176"/>
+<vertex x="23.368" y="0"/>
+<vertex x="0" y="0"/>
+</polygon>
+<polygon width="0.254" layer="1" isolate="0.2032">
+<vertex x="0" y="11.176"/>
+<vertex x="23.368" y="11.176"/>
+<vertex x="23.368" y="0"/>
+<vertex x="0" y="0"/>
+</polygon>
+<via x="19.812" y="9.652" extent="1-16" drill="0.3302" diameter="0.254"/>
+<contactref element="J2" pad="9"/>
+<contactref element="J5" pad="1"/>
+<via x="19.812" y="1.524" extent="1-16" drill="0.3302" diameter="0.254"/>
+<contactref element="IC1" pad="PAD"/>
+<contactref element="IC1" pad="23"/>
+<via x="1.27" y="7.62" extent="1-16" drill="0.3302" diameter="0.254"/>
+<via x="1.27" y="3.556" extent="1-16" drill="0.3302" diameter="0.254"/>
+<via x="3.302" y="8.128" extent="1-16" drill="0.3302" diameter="0.254"/>
+<via x="3.556" y="3.81" extent="1-16" drill="0.3302" diameter="0.254"/>
+<via x="8.636" y="6.858" extent="1-16" drill="0.3302" diameter="0.254"/>
+<via x="9.652" y="6.858" extent="1-16" drill="0.3302" diameter="0.254"/>
+<via x="9.652" y="5.842" extent="1-16" drill="0.3302" diameter="0.254"/>
+<via x="8.636" y="5.842" extent="1-16" drill="0.3302" diameter="0.254"/>
+<wire x1="9.144" y1="6.35" x2="8.636" y2="5.842" width="0.254" layer="1"/>
+<via x="5.334" y="9.652" extent="1-16" drill="0.3302" diameter="0.254"/>
+<via x="20.574" y="4.318" extent="1-16" drill="0.3302" diameter="0.254"/>
+<via x="12.954" y="10.414" extent="1-16" drill="0.3302" diameter="0.254"/>
+<contactref element="R1" pad="2"/>
+<contactref element="R2" pad="2"/>
+<via x="15.24" y="2.54" extent="1-16" drill="0.3302" diameter="0.254"/>
+<via x="20.574" y="6.858" extent="1-16" drill="0.3302" diameter="0.254"/>
+<via x="7.112" y="2.794" extent="1-16" drill="0.3302" diameter="0.254"/>
+</signal>
+<signal name="USB_DM">
+<contactref element="J1" pad="2"/>
+<contactref element="IC1" pad="21"/>
+<wire x1="7.294" y1="6.6" x2="6.1" y2="6.6" width="0.254" layer="1"/>
+<wire x1="4.825" y1="6.238" x2="5.7" y2="6.238" width="0.254" layer="1"/>
+<wire x1="5.7" y1="6.238" x2="6.1" y2="6.6" width="0.254" layer="1"/>
+</signal>
+<signal name="USB_DP">
+<contactref element="J1" pad="3"/>
+<contactref element="IC1" pad="22"/>
+<wire x1="4.829" y1="5.592" x2="4.825" y2="5.588" width="0.254" layer="1"/>
+<wire x1="4.829" y1="5.592" x2="5.846" y2="5.592" width="0.254" layer="1"/>
+<wire x1="5.846" y1="5.592" x2="6.354" y2="6.1" width="0.254" layer="1"/>
+<wire x1="6.354" y1="6.1" x2="7.294" y2="6.1" width="0.254" layer="1"/>
+</signal>
+<signal name="V_USB">
+<contactref element="IC2" pad="3"/>
+<contactref element="IC2" pad="1"/>
+<contactref element="C1" pad="2"/>
+<contactref element="J1" pad="1"/>
+<wire x1="4.825" y1="6.888" x2="3.272" y2="6.888" width="0.254" layer="1"/>
+<via x="3.048" y="7.112" extent="1-16" drill="0.3302"/>
+<wire x1="2.764" y1="6.538" x2="3.622" y2="6.538" width="0.254" layer="16"/>
+<wire x1="3.622" y1="6.538" x2="3.81" y2="6.35" width="0.254" layer="16"/>
+<wire x1="3.81" y1="6.35" x2="3.81" y2="4.826" width="0.254" layer="16"/>
+<wire x1="3.81" y1="4.826" x2="3.622" y2="4.638" width="0.254" layer="16"/>
+<wire x1="3.622" y1="4.638" x2="2.764" y2="4.638" width="0.254" layer="16"/>
+<wire x1="2.764" y1="4.638" x2="2.794" y2="4.608" width="0.254" layer="16"/>
+<wire x1="1.27" y1="4.788" x2="1.42" y2="4.638" width="0.254" layer="16"/>
+<wire x1="1.42" y1="4.638" x2="2.764" y2="4.638" width="0.254" layer="16"/>
+<wire x1="3.048" y1="7.112" x2="2.764" y2="6.828" width="0.254" layer="16"/>
+<wire x1="2.764" y1="6.828" x2="2.764" y2="6.538" width="0.254" layer="16"/>
+<wire x1="3.272" y1="6.888" x2="3.048" y2="7.112" width="0.254" layer="1"/>
+</signal>
+<signal name="+3V3">
+<contactref element="IC2" pad="5"/>
+<contactref element="C2" pad="2"/>
+<contactref element="IC1" pad="24"/>
+<wire x1="5.364" y1="4.638" x2="6.708" y2="4.638" width="0.254" layer="16"/>
+<wire x1="6.708" y1="4.638" x2="6.858" y2="4.788" width="0.254" layer="16"/>
+<via x="7.112" y="3.81" extent="1-16" drill="0.3302"/>
+<wire x1="7.294" y1="5.1" x2="7.294" y2="3.992" width="0.254" layer="1"/>
+<wire x1="7.294" y1="3.992" x2="7.112" y2="3.81" width="0.254" layer="1"/>
+<contactref element="SB1" pad="1"/>
+<wire x1="6.858" y1="4.788" x2="6.858" y2="4.064" width="0.254" layer="16"/>
+<wire x1="6.858" y1="4.064" x2="7.112" y2="3.81" width="0.254" layer="16"/>
+<via x="11.43" y="3.048" extent="1-16" drill="0.3302"/>
+<wire x1="11.43" y1="3.048" x2="11.43" y2="3.81" width="0.254" layer="16"/>
+<wire x1="11.43" y1="3.81" x2="10.602" y2="4.638" width="0.254" layer="16"/>
+<wire x1="10.602" y1="4.638" x2="6.708" y2="4.638" width="0.254" layer="16"/>
+<wire x1="11.43" y1="3.048" x2="11.43" y2="1.778" width="0.254" layer="1"/>
+<wire x1="11.43" y1="1.778" x2="11.684" y2="1.524" width="0.254" layer="1"/>
+<wire x1="11.684" y1="1.524" x2="12.192" y2="1.524" width="0.254" layer="1"/>
+</signal>
+<signal name="SWDIO">
+<contactref element="TP1" pad="1"/>
+<contactref element="IC1" pad="20"/>
+<wire x1="7.294" y1="7.1" x2="6.87" y2="7.1" width="0.254" layer="1"/>
+<wire x1="6.87" y1="7.1" x2="6.604" y2="7.366" width="0.254" layer="1"/>
+<wire x1="6.604" y1="7.366" x2="6.604" y2="8.636" width="0.254" layer="1"/>
+<via x="6.604" y="8.636" extent="1-16" drill="0.3302"/>
+<wire x1="6.604" y1="8.636" x2="6.604" y2="9.652" width="0.254" layer="16"/>
+</signal>
+<signal name="SWCLK">
+<contactref element="TP2" pad="1"/>
+<contactref element="IC1" pad="19"/>
+<wire x1="7.294" y1="7.6" x2="7.294" y2="9.326" width="0.254" layer="1"/>
+<wire x1="7.294" y1="9.326" x2="7.874" y2="9.906" width="0.254" layer="1"/>
+<via x="10.414" y="9.906" extent="1-16" drill="0.3302"/>
+<wire x1="7.874" y1="9.906" x2="10.414" y2="9.906" width="0.254" layer="1"/>
+<wire x1="10.414" y1="9.906" x2="10.668" y2="9.652" width="0.254" layer="16"/>
+<wire x1="10.668" y1="9.652" x2="11.684" y2="9.652" width="0.254" layer="16"/>
+</signal>
+<signal name="RESET">
+<contactref element="TP3" pad="1"/>
+<contactref element="IC1" pad="18"/>
+<via x="8.128" y="9.144" extent="1-16" drill="0.3302"/>
+<wire x1="7.894" y1="8.2" x2="7.894" y2="8.91" width="0.254" layer="1"/>
+<wire x1="7.894" y1="8.91" x2="8.128" y2="9.144" width="0.254" layer="1"/>
+<wire x1="8.128" y1="9.144" x2="8.636" y2="9.144" width="0.254" layer="16"/>
+<wire x1="8.636" y1="9.144" x2="9.144" y2="9.652" width="0.254" layer="16"/>
+</signal>
+<signal name="N$8">
+</signal>
+<signal name="T_SWDIO_TMS">
+<contactref element="J2" pad="2"/>
+<contactref element="RN2" pad="2"/>
+<wire x1="14.214" y1="4.172" x2="15.259" y2="4.172" width="0.254" layer="1"/>
+<wire x1="15.259" y1="4.172" x2="16.383" y2="3.048" width="0.254" layer="1"/>
+</signal>
+<signal name="T_SWCLK_TCK">
+<contactref element="J2" pad="4"/>
+<contactref element="RN2" pad="3"/>
+<wire x1="14.214" y1="4.972" x2="15.729" y2="4.972" width="0.254" layer="1"/>
+<wire x1="15.729" y1="4.972" x2="16.383" y2="4.318" width="0.254" layer="1"/>
+</signal>
+<signal name="T_RESET">
+<contactref element="J2" pad="10"/>
+<contactref element="RN1" pad="2"/>
+<wire x1="14.214" y1="7.728" x2="15.983" y2="7.728" width="0.254" layer="1"/>
+<wire x1="15.983" y1="7.728" x2="16.383" y2="8.128" width="0.254" layer="1"/>
+</signal>
+<signal name="UART_TX">
+<contactref element="J4" pad="1"/>
+<contactref element="RN1" pad="3"/>
+<wire x1="14.214" y1="8.528" x2="15.386" y2="8.528" width="0.254" layer="1"/>
+<wire x1="15.386" y1="8.528" x2="16.002" y2="9.144" width="0.254" layer="1"/>
+<wire x1="16.002" y1="9.144" x2="18.034" y2="9.144" width="0.254" layer="1"/>
+<wire x1="18.034" y1="9.144" x2="18.542" y2="8.636" width="0.254" layer="1"/>
+<wire x1="18.542" y1="8.636" x2="18.542" y2="6.858" width="0.254" layer="1"/>
+<wire x1="18.542" y1="6.858" x2="19.812" y2="5.588" width="0.254" layer="1"/>
+</signal>
+<signal name="N$11">
+</signal>
+<signal name="UART_RX">
+<contactref element="J3" pad="1"/>
+<contactref element="RN1" pad="4"/>
+<wire x1="14.214" y1="9.328" x2="15.424" y2="9.328" width="0.254" layer="1"/>
+<wire x1="15.424" y1="9.328" x2="15.748" y2="9.652" width="0.254" layer="1"/>
+<wire x1="15.748" y1="9.652" x2="18.288" y2="9.652" width="0.254" layer="1"/>
+<wire x1="18.288" y1="9.652" x2="19.812" y2="8.128" width="0.254" layer="1"/>
+</signal>
+<signal name="T_TDO">
+<contactref element="J2" pad="6"/>
+<contactref element="RN2" pad="4"/>
+<wire x1="14.214" y1="5.772" x2="16.199" y2="5.772" width="0.254" layer="1"/>
+<wire x1="16.199" y1="5.772" x2="16.383" y2="5.588" width="0.254" layer="1"/>
+</signal>
+<signal name="T_TDI">
+<contactref element="J2" pad="8"/>
+<contactref element="RN1" pad="1"/>
+<wire x1="14.214" y1="6.928" x2="16.313" y2="6.928" width="0.254" layer="1"/>
+<wire x1="16.313" y1="6.928" x2="16.383" y2="6.858" width="0.254" layer="1"/>
+</signal>
+<signal name="N$2">
+<contactref element="R1" pad="1"/>
+<contactref element="LED1" pad="2"/>
+<via x="7.62" y="1.524" extent="1-16" drill="0.3302"/>
+<wire x1="8.382" y1="1.486" x2="7.658" y2="1.486" width="0.254" layer="1"/>
+<wire x1="7.658" y1="1.486" x2="7.62" y2="1.524" width="0.254" layer="1"/>
+<wire x1="8.382" y1="1.486" x2="7.658" y2="1.486" width="0.254" layer="16"/>
+<wire x1="7.658" y1="1.486" x2="7.62" y2="1.524" width="0.254" layer="16"/>
+</signal>
+<signal name="N$3">
+<contactref element="R2" pad="1"/>
+<contactref element="LED2" pad="2"/>
+<via x="10.668" y="1.524" extent="1-16" drill="0.3302"/>
+<wire x1="9.906" y1="1.486" x2="10.63" y2="1.486" width="0.254" layer="16"/>
+<wire x1="10.63" y1="1.486" x2="10.668" y2="1.524" width="0.254" layer="16"/>
+<wire x1="9.906" y1="1.486" x2="10.63" y2="1.486" width="0.254" layer="1"/>
+<wire x1="10.63" y1="1.486" x2="10.668" y2="1.524" width="0.254" layer="1"/>
+</signal>
+<signal name="LED_A">
+<contactref element="LED1" pad="1"/>
+<contactref element="IC1" pad="2"/>
+<wire x1="8.394" y1="4.5" x2="8.394" y2="3.098" width="0.254" layer="1"/>
+<wire x1="8.394" y1="3.098" x2="8.382" y2="3.086" width="0.254" layer="1"/>
+</signal>
+<signal name="LED_B">
+<contactref element="LED2" pad="1"/>
+<contactref element="IC1" pad="5"/>
+<wire x1="9.894" y1="4.5" x2="9.894" y2="3.098" width="0.254" layer="1"/>
+<wire x1="9.894" y1="3.098" x2="9.906" y2="3.086" width="0.254" layer="1"/>
+</signal>
+<signal name="I_TX">
+<contactref element="IC1" pad="13"/>
+<contactref element="RN1" pad="6"/>
+<wire x1="12.71" y1="8.528" x2="12.084" y2="8.528" width="0.254" layer="1"/>
+<wire x1="12.084" y1="8.528" x2="11.756" y2="8.2" width="0.254" layer="1"/>
+<wire x1="11.756" y1="8.2" x2="10.394" y2="8.2" width="0.254" layer="1"/>
+</signal>
+<signal name="I_RX">
+<contactref element="IC1" pad="14"/>
+<contactref element="RN1" pad="5"/>
+<wire x1="12.71" y1="9.328" x2="11.868" y2="9.328" width="0.254" layer="1"/>
+<wire x1="11.868" y1="9.328" x2="11.684" y2="9.144" width="0.254" layer="1"/>
+<wire x1="11.684" y1="9.144" x2="10.16" y2="9.144" width="0.254" layer="1"/>
+<wire x1="10.16" y1="9.144" x2="9.894" y2="8.878" width="0.254" layer="1"/>
+<wire x1="9.894" y1="8.878" x2="9.894" y2="8.2" width="0.254" layer="1"/>
+</signal>
+<signal name="T_VREF">
+<contactref element="J2" pad="1"/>
+<contactref element="SB1" pad="2"/>
+<contactref element="RN2" pad="1"/>
+<wire x1="16.764" y1="1.524" x2="14.224" y2="1.524" width="0.254" layer="1"/>
+<wire x1="14.224" y1="1.524" x2="13.208" y2="1.524" width="0.254" layer="1"/>
+<wire x1="16.764" y1="1.524" x2="17.653" y2="2.413" width="0.254" layer="1"/>
+<wire x1="17.653" y1="2.413" x2="17.653" y2="3.048" width="0.254" layer="1"/>
+<wire x1="14.214" y1="3.372" x2="14.224" y2="3.362" width="0.254" layer="1"/>
+<wire x1="14.224" y1="3.362" x2="14.224" y2="1.524" width="0.254" layer="1"/>
+</signal>
+<signal name="I_TDI">
+<contactref element="RN1" pad="8"/>
+<contactref element="IC1" pad="11"/>
+<wire x1="10.994" y1="7.1" x2="11.95" y2="7.1" width="0.254" layer="1"/>
+<wire x1="11.95" y1="7.1" x2="12.122" y2="6.928" width="0.254" layer="1"/>
+<wire x1="12.122" y1="6.928" x2="12.71" y2="6.928" width="0.254" layer="1"/>
+</signal>
+<signal name="I_RESET">
+<contactref element="RN1" pad="7"/>
+<contactref element="IC1" pad="12"/>
+<wire x1="10.994" y1="7.6" x2="11.918" y2="7.6" width="0.254" layer="1"/>
+<wire x1="11.918" y1="7.6" x2="12.046" y2="7.728" width="0.254" layer="1"/>
+<wire x1="12.046" y1="7.728" x2="12.71" y2="7.728" width="0.254" layer="1"/>
+</signal>
+<signal name="I_VREF">
+<contactref element="RN2" pad="8"/>
+<contactref element="IC1" pad="6"/>
+<wire x1="12.122" y1="3.372" x2="10.994" y2="4.5" width="0.254" layer="1"/>
+<wire x1="10.994" y1="4.5" x2="10.394" y2="4.5" width="0.254" layer="1"/>
+<wire x1="12.122" y1="3.372" x2="12.71" y2="3.372" width="0.254" layer="1"/>
+</signal>
+<signal name="I_SWDIO_TMS">
+<contactref element="RN2" pad="7"/>
+<contactref element="IC1" pad="7"/>
+<wire x1="10.994" y1="5.1" x2="11.41" y2="5.1" width="0.254" layer="1"/>
+<wire x1="11.41" y1="5.1" x2="11.684" y2="4.826" width="0.254" layer="1"/>
+<wire x1="11.684" y1="4.826" x2="11.684" y2="4.572" width="0.254" layer="1"/>
+<wire x1="11.684" y1="4.572" x2="12.084" y2="4.172" width="0.254" layer="1"/>
+<wire x1="12.084" y1="4.172" x2="12.71" y2="4.172" width="0.254" layer="1"/>
+</signal>
+<signal name="I_SWCLK_TCK">
+<contactref element="RN2" pad="6"/>
+<contactref element="IC1" pad="8"/>
+<wire x1="10.994" y1="5.6" x2="11.672" y2="5.6" width="0.254" layer="1"/>
+<wire x1="11.672" y1="5.6" x2="12.3" y2="4.972" width="0.254" layer="1"/>
+<wire x1="12.3" y1="4.972" x2="12.71" y2="4.972" width="0.254" layer="1"/>
+</signal>
+<signal name="I_TDO">
+<contactref element="RN2" pad="5"/>
+<contactref element="IC1" pad="9"/>
+<wire x1="10.994" y1="6.1" x2="11.874" y2="6.1" width="0.254" layer="1"/>
+<wire x1="11.874" y1="6.1" x2="12.202" y2="5.772" width="0.254" layer="1"/>
+<wire x1="12.202" y1="5.772" x2="12.71" y2="5.772" width="0.254" layer="1"/>
+</signal>
+</signals>
+</board>
+</drawing>
+</eagle>

BIN
dap_link/lib/free-dap/hardware/d11_micro_std_vcp_v2/d11_micro_std_vcp_v2.pdf


Некоторые файлы не были показаны из-за большого количества измененных файлов